2 use ieee.std_logic_1164.all;
3 use ieee.std_logic_arith.all;
4 use ieee.std_logic_unsigned.all;
5 use ieee.numeric_std.all;
7 -- lx_rocon_top - wires the modules with outside world
9 -- ======================================================
10 -- INTERNAL MEMORY BUS
11 -- ======================================================
13 -- Internal memory bus has the following wires:
15 -- - address[15..0] The address
16 -- - data_in[31..0] The data coming to bus
17 -- - data_out[31..0] The data coming from bus, multiplexed
18 -- - rd Read enable, active LOW
19 -- - bls[3..0] Write enable for respective bytes, active LOW
20 -- In some cases, only WR is used
21 -- - ta Transaction acknowledge (latches data out), active LOW, multiplexed
23 entity lx_rocon_top is
29 cs0_xc : in std_logic;
32 bls : in std_logic_vector(3 downto 0);
33 address : in std_logic_vector(15 downto 0);
34 data : inout std_logic_vector(31 downto 0);
36 irc1_a : in std_logic;
37 irc1_b : in std_logic;
38 irc1_index : in std_logic;
39 irc1_mark : in std_logic;
41 irc2_a : in std_logic;
42 irc2_b : in std_logic;
43 irc2_index : in std_logic;
44 irc2_mark : in std_logic;
46 irc3_a : in std_logic;
47 irc3_b : in std_logic;
48 irc3_index : in std_logic;
49 irc3_mark : in std_logic;
51 irc4_a : in std_logic;
52 irc4_b : in std_logic;
53 irc4_index : in std_logic;
54 irc4_mark : in std_logic;
60 architecture Behavioral of lx_rocon_top is
63 signal reset : std_logic;
65 -- Peripherals on the memory bus
66 signal bram_out : std_logic_vector(31 downto 0);
67 signal bram_ta : std_logic;
68 signal bram_ce : std_logic;
70 signal irc_reg_out : std_logic_vector(31 downto 0);
71 signal irc_reg_ta : std_logic;
72 signal irc_reg_ce : std_logic;
74 -- Signals for external bus transmission
75 signal data_in_bus : std_logic_vector(31 downto 0);
76 signal data_out_bus : std_logic_vector(31 downto 0);
78 -- Signals for internal transaction
79 signal last_address : std_logic_vector(15 downto 0);
80 signal last_rd : std_logic;
83 -- Broadcast rd only till ta (transaction acknowledge)
84 -- is received, then latch the data till the state of
85 -- rd or address changes
86 signal i_ta : std_logic;
87 signal i_rd : std_logic;
88 signal data_latched : std_logic_vector(31 downto 0);
89 signal acked : std_logic;
97 address : in std_logic_vector(3 downto 0);
100 data_in : in std_logic;
101 data_out : out std_logic_vector(31 downto 0);
107 irc1_a : in std_logic;
108 irc1_b : in std_logic;
109 irc1_index : in std_logic;
110 irc1_mark : in std_logic;
112 irc2_a : in std_logic;
113 irc2_b : in std_logic;
114 irc2_index : in std_logic;
115 irc2_mark : in std_logic;
117 irc3_a : in std_logic;
118 irc3_b : in std_logic;
119 irc3_index : in std_logic;
120 irc3_mark : in std_logic;
122 irc4_a : in std_logic;
123 irc4_b : in std_logic;
124 irc4_index : in std_logic;
125 irc4_mark : in std_logic
129 component bus_control_bram
135 wea : in std_logic_vector(3 downto 0);
136 addra : in std_logic_vector(9 downto 0);
137 dina : in std_logic_vector(31 downto 0);
138 douta : out std_logic_vector(31 downto 0);
142 web : in std_logic_vector(3 downto 0);
143 addrb : in std_logic_vector(9 downto 0);
144 dinb : in std_logic_vector(31 downto 0);
145 doutb : out std_logic_vector(31 downto 0)
152 memory_bus_irc: bus_irc
157 address => address(3 downto 0),
159 data_in => data_in_bus(0),
160 data_out => irc_reg_out,
167 irc1_index => irc1_index,
168 irc1_mark => irc1_mark,
172 irc2_index => irc2_index,
173 irc2_mark => irc2_mark,
177 irc3_index => irc3_index,
178 irc3_mark => irc3_mark,
182 irc4_index => irc4_index,
183 irc4_mark => irc4_mark
186 -- Control BRAM interconnect (9 kiB)
187 memory_bus_control_bram: bus_control_bram
194 addra => address(9 downto 0),
199 web => (others => '0'),
200 addrb => (others => '0'),
201 dinb => (others => '0'),
206 memory_bus_update: process(clk)
209 if clk = '1' and clk'event then
211 -- Set every signal to inactive state here
216 -- TODO: Make sure our CPU actually follows the convention
219 -- Memory Map (16-bit address @ 32-bit each)
221 -- 0x0000 - 0x0900: Control dual-port BRAM
222 -- 0x8000 - 0x800F: IRC registers
224 if address < "0000100100000000" then -- Control BRAM
227 data_out_bus <= bram_out;
228 elsif address(15 downto 4) = "100000000000" then -- IRC
231 data_out_bus <= irc_reg_out;
235 if last_rd = '1' or last_address /= address then
236 -- Getting something new
237 -- Set internal RD to active and reset ack and latched data
240 -- Latching must be performed synchronously, otherwise poor timing performance
241 -- caused by significant routing delay
242 data_latched <= (others => 'X');
243 elsif i_rd = '0' and acked = '0' and i_ta = '0' then
244 -- Got acknowledge, latch data
246 data_latched <= data_out_bus;
247 elsif acked = '0' then
248 -- Ongoing read, keep the signal low
250 data_latched <= (others => 'X');
253 last_address <= address;
255 -- Not reading, anything goes
256 data_latched <= (others => 'X');
266 -- If RD and BLS is not high, we must keep DATA at high impedance
267 -- or the FPGA collides with SDRAM (burning each other)
269 memory_bus_out: process(cs0_xc, rd, data, data_latched)
272 -- CS0 / RD / BLS are active LOW
273 if cs0_xc = '0' and rd = '0' then
274 data <= data_latched;
277 data <= (others => 'Z');
285 initialization: process(init)