3 use ieee.std_logic_1164.all;
4 use ieee.std_logic_arith.all;
5 use ieee.std_logic_unsigned.all;
6 use ieee.numeric_std.all;
8 use work.lx_rocon_pkg.all;
10 -- Connects tumbl to the Master CPU
16 clk_100m_i : in std_logic;
17 clk_50m_i : in std_logic;
19 ce_100m_i : in std_logic;
21 reset_100m_i : in std_logic;
22 -- Master CPU bus for the memory
23 rd_100m_i : in std_logic;
24 bls_100m_i : in std_logic_vector(3 downto 0);
25 address_100m_i : in std_logic_vector(11 downto 0);
26 data_100m_i : in std_logic_vector(31 downto 0);
27 data_100m_o : out std_logic_vector(31 downto 0);
28 ta_100m_o : out std_logic;
29 -- Tumbl extrenal memory bus
30 xmemb_sel_100m_o : out std_logic;
31 xmemb_100m_i : in DMEMB2CORE_Type;
32 xmemb_100m_o : out CORE2DMEMB_Type
36 architecture Behavioral of bus_tumbl is
39 -- The following signals are driven by 100M clock
40 signal tumbl_reset_100m_s : std_logic;
41 signal tumbl_halt_100m_s : std_logic;
42 signal tumbl_int_100m_s : std_logic;
43 signal tumbl_trace_100m_s : std_logic;
45 -- The following signals kick in at 50M clock
46 signal tumbl_reset_50m_s : std_logic;
47 signal tumbl_halt_50m_s : std_logic;
48 signal tumbl_int_50m_s : std_logic;
49 signal tumbl_trace_50m_s : std_logic;
51 -- Trace kick (since this is "one cycle command", it needs req / ack)
52 signal tumbl_trace_kick_50m_s : std_logic;
53 signal tumbl_trace_kick_ack_50m_s : std_logic;
54 signal tumbl_trace_kick_req_100m_s : std_logic;
56 -- Tumbl PC (copy it with cpu clock and then wire further)
57 signal tumbl_pc_50m_s : std_logic_vector(31 downto 0);
59 -- Halting using halt instruction
60 -- Driven by 50M clock
61 signal tumbl_halted_50m_s : std_logic;
62 signal tumbl_halt_code_50m_s : std_logic_vector(4 downto 0);
64 -- Tumbl signals under 100M domain
65 -- Driven by 100M clock
66 signal tumbl_pc_100m_s : std_logic_vector(31 downto 0);
67 signal tumbl_halted_100m_s : std_logic;
68 signal tumbl_halt_code_100m_s : std_logic_vector(4 downto 0);
70 -- Internal memory signals
71 -- Driven by 100M clock
72 signal imem_en_100m_s : std_logic;
73 signal dmem_en_100m_s : std_logic;
75 signal imem_we_100m_s : std_logic_vector(3 downto 0);
76 signal dmem_we_100m_s : std_logic_vector(3 downto 0);
78 signal imem_data_o_100m_s : std_logic_vector(31 downto 0);
79 signal dmem_data_o_100m_s : std_logic_vector(31 downto 0);
81 -- Tumbl external memory
82 -- Driven by 50M clock
83 signal xmemb_sel_50m_s : std_logic;
84 signal xmemb_50m_i_s : DMEMB2CORE_Type;
85 signal xmemb_50m_o_s : CORE2DMEMB_Type;
87 -- Internal bus structure
88 -- 12 address bits: 2 bits for selection, 10 bits for address
100 -- Bit 1: RW - Interrupt
106 -- Bit 0: W - Write 1 for trace kick
109 -- Tumbl program counter (R)
116 -- Wire it to the tumbl
117 I_TUMBL: lx_rocon_tumbl
123 USE_HW_MUL_g => true,
124 USE_BARREL_g => true,
125 COMPATIBILITY_MODE_g => false
130 rst_i => tumbl_reset_50m_s,
131 halt_i => tumbl_halt_50m_s,
132 int_i => tumbl_int_50m_s,
133 trace_i => tumbl_trace_50m_s,
134 trace_kick_i => tumbl_trace_kick_50m_s,
136 pc_o => tumbl_pc_50m_s,
137 halted_o => tumbl_halted_50m_s,
138 halt_code_o => tumbl_halt_code_50m_s,
140 -- Internal memory (instruction)
141 imem_clk_i => clk_100m_i,
142 imem_en_i => imem_en_100m_s,
143 imem_we_i => imem_we_100m_s,
144 imem_addr_i => address_100m_i(8 downto 0),
145 imem_data_i => data_100m_i,
146 imem_data_o => imem_data_o_100m_s,
148 -- Internal memory (data)
149 dmem_clk_i => clk_100m_i,
150 dmem_en_i => dmem_en_100m_s,
151 dmem_we_i => dmem_we_100m_s,
152 dmem_addr_i => address_100m_i(9 downto 0),
153 dmem_data_i => data_100m_i,
154 dmem_data_o => dmem_data_o_100m_s,
156 -- External memory bus
157 xmemb_sel_o => xmemb_sel_50m_s,
158 xmemb_i => xmemb_50m_i_s,
159 xmemb_o => xmemb_50m_o_s
163 enabling: process(ce_100m_i, address_100m_i)
166 if ce_100m_i = '1' and address_100m_i(11 downto 10) = "00" then
167 imem_en_100m_s <= '1';
169 imem_en_100m_s <= '0';
172 if ce_100m_i = '1' and address_100m_i(11 downto 10) = "01" then
173 dmem_en_100m_s <= '1';
175 dmem_en_100m_s <= '0';
181 -- NOTE: This is only modifying signals inside 100m domain
182 wiring: process(ce_100m_i, rd_100m_i, bls_100m_i, address_100m_i, imem_en_100m_s, imem_data_o_100m_s, dmem_en_100m_s,
183 dmem_data_o_100m_s, tumbl_reset_100m_s, tumbl_int_100m_s, tumbl_halt_100m_s, tumbl_trace_100m_s,
184 tumbl_halted_100m_s, tumbl_halt_code_100m_s, tumbl_pc_100m_s)
187 if imem_en_100m_s = '1' then
188 imem_we_100m_s <= bls_100m_i;
190 imem_we_100m_s <= "0000";
193 if dmem_en_100m_s = '1' then
194 dmem_we_100m_s <= bls_100m_i;
196 dmem_we_100m_s <= "0000";
199 if imem_en_100m_s = '1' then
200 data_100m_o <= imem_data_o_100m_s;
201 elsif dmem_en_100m_s = '1' then
202 data_100m_o <= dmem_data_o_100m_s;
203 elsif ce_100m_i = '1' and rd_100m_i = '1' and address_100m_i(11 downto 10) = "11" then
204 if address_100m_i(9 downto 0) = "0000000000" then
205 data_100m_o(0) <= tumbl_reset_100m_s;
206 data_100m_o(1) <= tumbl_int_100m_s;
207 data_100m_o(2) <= tumbl_halt_100m_s;
208 data_100m_o(3) <= tumbl_trace_100m_s;
209 data_100m_o(4) <= tumbl_halted_100m_s;
210 data_100m_o(31 downto 5) <= (others => '0');
211 elsif address_100m_i(9 downto 0) = "0000000010" then
212 data_100m_o <= tumbl_pc_100m_s;
213 elsif address_100m_i(9 downto 0) = "0000000011" then
214 data_100m_o(4 downto 0) <= tumbl_halt_code_100m_s;
215 data_100m_o(31 downto 5) <= (others => '0');
217 data_100m_o <= (others => 'X');
220 data_100m_o <= (others => 'X');
225 -- Transaction acknowledge and writing to registers
226 -- The clocks are synchronous!
227 update: process(clk_100m_i)
230 -- Update on the 100 MHz clock
231 if clk_100m_i = '1' and clk_100m_i'event then
234 -- Copy the 50M driven signals to 100M domain
235 tumbl_pc_100m_s <= tumbl_pc_50m_s;
236 tumbl_halted_100m_s <= tumbl_halted_50m_s;
237 tumbl_halt_code_100m_s <= tumbl_halt_code_50m_s;
239 xmemb_sel_100m_o <= xmemb_sel_50m_s;
240 xmemb_100m_o <= xmemb_50m_o_s;
242 if imem_en_100m_s = '1' or dmem_en_100m_s = '1' then
246 if reset_100m_i = '1' then
247 tumbl_reset_100m_s <= '1';
248 tumbl_int_100m_s <= '0';
249 tumbl_halt_100m_s <= '0';
250 tumbl_trace_100m_s <= '0';
251 tumbl_trace_kick_req_100m_s <= '0';
253 if tumbl_trace_kick_ack_50m_s = '1' then
254 tumbl_trace_kick_req_100m_s <= '0';
257 if ce_100m_i = '1' and address_100m_i(11 downto 10) = "11" then
258 if bls_100m_i(0) = '1' then
259 if address_100m_i(9 downto 0) = "0000000000" then
260 tumbl_reset_100m_s <= data_100m_i(0);
261 tumbl_int_100m_s <= data_100m_i(1);
262 tumbl_halt_100m_s <= data_100m_i(2);
263 tumbl_trace_100m_s <= data_100m_i(3);
264 elsif address_100m_i(9 downto 0) = "0000000001" then
265 if data_100m_i(0) = '1' then
266 tumbl_trace_kick_req_100m_s <= '1';
271 if rd_100m_i = '1' then
281 tumbl: process(clk_50m_i)
284 -- Update on the 50 MHz clock
285 if clk_50m_i = '1' and clk_50m_i'event then
287 -- Copy the 100M driven signals to their 50M domain
288 -- and then route them further
289 tumbl_reset_50m_s <= tumbl_reset_100m_s;
290 tumbl_int_50m_s <= tumbl_int_100m_s;
291 tumbl_halt_50m_s <= tumbl_halt_100m_s;
292 tumbl_trace_50m_s <= tumbl_trace_100m_s;
294 xmemb_50m_i_s <= xmemb_100m_i;
296 if reset_100m_i = '1' then
297 tumbl_trace_kick_50m_s <= '0';
298 tumbl_trace_kick_ack_50m_s <= '0';
300 if tumbl_trace_kick_50m_s = '0' and tumbl_trace_kick_req_100m_s = '1' then
301 tumbl_trace_kick_50m_s <= '1';
302 tumbl_trace_kick_ack_50m_s <= '1';
304 tumbl_trace_kick_50m_s <= '0';
308 if tumbl_trace_kick_req_100m_s = '0' then
309 tumbl_trace_kick_ack_50m_s <= '0';