-
-
Notifications
You must be signed in to change notification settings - Fork 29
/
Copy pathram.vhd
125 lines (110 loc) · 4.69 KB
/
ram.vhd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
-------------------------------------------------------------------------------
--| @file ram.vhd
--| @brief Bus Interface to Nexys3 on board memory devices
--| @author Richard James Howe
--| @copyright Copyright 2017 Richard James Howe.
--| @license MIT
--| @email [email protected]
--|
--| This component is for interfacing with the two memory devices available
--| on the Nexys3 board.
--|
--| The devices are:
--| - PC28F128P33BF60 (Non-Volatile Flash with a CSI Interface)
--| - MT45W1MW16BDGB (SRAM)
--|
--| They both share the same data, address lines, output enable, and write
--| enable signals. They are selected with a Chip Select (ram_cs = SRAM,
--| flash_cs = Flash device). The Flash has an addition reset line (flash_rp).
--|
--| This interface is very simple, it does not bother with timing and
--| only has minimal logic and state, it is up to the consumer of this
--| module to implement the bus timing - which in this case is a Soft CPU
--| Core.
--|
--| Many improvements could be made, we could do a lot more in the hardware,
--| even going as far as to implement most of the Common Flash Interface (but
--| that would be better placed in a controlling module), but it is not
--| necessary. We will Keep It Simple.
--|
-------------------------------------------------------------------------------
library ieee, work;
use ieee.std_logic_1164.all;
use work.util.common_generics;
entity ram_interface is
generic (g: common_generics);
port(
clk: in std_ulogic;
rst: in std_ulogic;
mem_addr_16_1: in std_ulogic_vector(16 downto 2);
mem_addr_16_1_we: in std_ulogic;
mem_addr_26_17: in std_ulogic_vector(26 downto 17);
mem_addr_26_17_we: in std_ulogic;
mem_control_i: in std_ulogic_vector(5 downto 0);
mem_control_we: in std_ulogic;
mem_data_i: in std_ulogic_vector(15 downto 0);
mem_data_i_we: in std_ulogic;
mem_data_o: out std_ulogic_vector(15 downto 0);
ram_cs: out std_ulogic := '1';
mem_oe: out std_ulogic := '0'; -- negative logic
mem_wr: out std_ulogic := '0'; -- negative logic
mem_adv: out std_ulogic := '0'; -- negative logic
mem_wait: out std_ulogic := '0'; -- positive!
flash_cs: out std_ulogic := '0';
flash_rp: out std_ulogic := '1';
mem_addr: out std_ulogic_vector(26 downto 1) := (others => '0');
mem_data: inout std_logic_vector(15 downto 0) := (others => 'Z'));
end entity;
architecture rtl of ram_interface is
signal mem_data_buf_i: std_ulogic_vector(mem_data_i'range) := (others => '0');
signal mem_control_o: std_ulogic_vector(mem_control_i'range) := (others => '0');
signal mem_we: std_ulogic := '0';
signal mem_oe_internal: std_ulogic := '0';
signal mem_addr_low: std_ulogic_vector(mem_addr_16_1'range) := (others => '0');
signal mem_addr_high: std_ulogic_vector(mem_addr_26_17'range) := (others => '0');
begin
mem_addr <= '0' & mem_addr_high & mem_addr_low;
mem_addr_16_1_reg: entity work.reg
generic map(g => g, N => mem_addr_16_1'length)
port map(
clk => clk,
rst => rst,
we => mem_addr_16_1_we,
di => mem_addr_16_1,
do => mem_addr_low);
mem_addr_26_17_reg: entity work.reg
generic map(g => g, N => mem_addr_26_17'length)
port map(
clk => clk,
rst => rst,
we => mem_addr_26_17_we,
di => mem_addr_26_17,
do => mem_addr_high);
mem_control_reg: entity work.reg
generic map(g => g, N => mem_control_i'length)
port map(
clk => clk,
rst => rst,
we => mem_control_we,
di => mem_control_i,
do => mem_control_o);
mem_data_i_reg: entity work.reg
generic map(g => g, N => mem_data_i'length)
port map(
clk => clk,
rst => rst,
we => mem_data_i_we,
di => mem_data_i,
do => mem_data_buf_i);
flash_cs <= '0' when mem_control_o(5 downto 4) /= "00" and mem_control_o(0) = '1' else '1' after g.delay;
ram_cs <= '0' when mem_control_o(5 downto 4) /= "00" and mem_control_o(1) = '1' else '1' after g.delay;
mem_wait <= mem_control_o(2);
flash_rp <= '0' when mem_control_o(3) = '1' else '1' after g.delay;
mem_adv <= '0' when mem_oe_internal = '1' or mem_we = '1' else '1' after g.delay;
mem_oe_internal <= '1' when mem_control_o(5 downto 4) = "01" else '0' after g.delay;
mem_we <= '1' when mem_control_o(5 downto 4) = "10" else '0' after g.delay;
mem_oe <= not mem_oe_internal after g.delay;
mem_wr <= not mem_we after g.delay;
mem_data_o <= std_ulogic_vector(mem_data) when mem_oe_internal = '1' else (others => '0') after g.delay;
mem_data <= std_logic_vector(mem_data_buf_i) when mem_we = '1' else (others => 'Z') after g.delay;
end architecture;