]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/lx-rocon.git/blob - hw/lx_rocon_top.vhd
Merge branch 'master' of rtime.felk.cvut.cz:/fpga/lx-cpu1/lx-rocon
[fpga/lx-cpu1/lx-rocon.git] / hw / lx_rocon_top.vhd
1 library ieee;
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;
6
7 library unisim;
8 use unisim.vcomponents.all;
9
10 use work.mbl_pkg.all;
11 use work.lx_rocon_pkg.all;
12
13 -- lx_rocon_top - wires the modules with the outside world
14
15 -- ======================================================
16 --  MASTER CPU EXTERNAL MEMORY BUS
17 -- ======================================================
18 --
19 -- Master cpu memory bus has the following wires:
20 --
21 -- - address[15..0]          The address, used to mark chip enable
22 -- - data_in[31..0]          The data coming to bus
23 -- - data_out[31..0]         The data coming from bus, multiplexed
24 -- - bls[3..0]               Write enable for respective bytes
25
26 entity lx_rocon_top is
27         port
28         (
29                 -- External
30                 --clk_cpu     : in std_logic;
31                 clk_50m     : in std_logic;
32                 --
33                 cs0_xc      : in std_logic;
34                 --
35                 rd          : in std_logic;
36                 bls         : in std_logic_vector(3 downto 0);
37                 address     : in std_logic_vector(15 downto 0);
38                 data        : inout std_logic_vector(31 downto 0);
39                 --
40                 irc0_a      : in std_logic;
41                 irc0_b      : in std_logic;
42                 irc0_index  : in std_logic;
43                 irc0_mark   : in std_logic;
44                 --
45                 irc1_a      : in std_logic;
46                 irc1_b      : in std_logic;
47                 irc1_index  : in std_logic;
48                 irc1_mark   : in std_logic;
49                 --
50                 irc2_a      : in std_logic;
51                 irc2_b      : in std_logic;
52                 irc2_index  : in std_logic;
53                 irc2_mark   : in std_logic;
54                 --
55                 irc3_a      : in std_logic;
56                 irc3_b      : in std_logic;
57                 irc3_index  : in std_logic;
58                 irc3_mark   : in std_logic;
59                 --
60                 irc4_a      : in std_logic;
61                 irc4_b      : in std_logic;
62                 irc4_index  : in std_logic;
63                 irc4_mark   : in std_logic;
64                 --
65                 irc5_a      : in std_logic;
66                 irc5_b      : in std_logic;
67                 irc5_index  : in std_logic;
68                 irc5_mark   : in std_logic;
69                 --
70                 irc6_a      : in std_logic;
71                 irc6_b      : in std_logic;
72                 irc6_index  : in std_logic;
73                 irc6_mark   : in std_logic;
74                 --
75                 irc7_a      : in std_logic;
76                 irc7_b      : in std_logic;
77                 irc7_index  : in std_logic;
78                 irc7_mark   : in std_logic;
79                 --
80                 init        : in std_logic;
81                 --
82                 s1_clk_in   : in std_logic;
83                 s1_miso     : in std_logic;
84                 s1_sync_in  : in std_logic;
85                 --
86                 s1_clk_out  : out std_logic;
87                 s1_mosi     : out std_logic;
88                 s1_sync_out : out std_logic
89         );
90 end lx_rocon_top;
91
92 architecture Behavioral of lx_rocon_top is
93
94         -- Reset signal
95         signal reset_s                  : std_logic;
96         signal init_s                   : std_logic;
97         -- Peripherals on the memory buses
98         -- Master to Tumbl DMEM / IMEM (Master)
99         signal tumbl_out_s              : std_logic_vector(31 downto 0);
100         signal tumbl_ce_s               : std_logic;
101         -- Measurement (Master)
102         signal meas_out_s               : std_logic_vector(31 downto 0);
103         signal meas_ce_s                : std_logic;
104         -- Master to Tumbl XMEM
105         signal master_tumbl_xmem_out_s  : std_logic_vector(31 downto 0);
106         signal master_tumbl_xmem_ce_s   : std_logic;
107         signal master_tumbl_xmem_lock_s : std_logic;
108         -- IRC (Tumbl)
109         signal irc_proc_out_s            : std_logic_vector(31 downto 0);
110         signal irc_proc_ce_s             : std_logic;
111         signal irc_proc_next_ce_s        : std_logic;
112         -- LX Master (Tumbl)
113         signal lxmaster_out_s           : std_logic_vector(15 downto 0);
114         signal lxmaster_ce_s            : std_logic;
115         signal lxmaster_next_ce_s       : std_logic;
116         -- Signals for external bus transmission
117         signal data_i_s                 : std_logic_vector(31 downto 0);
118         signal data_o_s                 : std_logic_vector(31 downto 0);
119         -- Signals for internal transaction
120         signal last_address_s           : std_logic_vector(15 downto 0);
121         signal last_rd_s                : std_logic;
122         signal last_bls_s               : std_logic_vector(3 downto 0);
123
124         -- Reading logic for Master CPU:
125         -- Broadcast rd only till ta (transaction acknowledge)
126         -- is received, then latch the data till the state of
127         -- rd or address changes
128         --
129         -- Data latching is synchronous - it's purpose is to
130         -- provide stable data for CPU on the bus
131         signal rd_f_s              : std_logic; -- Filtered RD
132         signal rd_d_s              : std_logic; -- D over RD
133         signal i_rd_s              : std_logic; -- Internal bus RD (active 1)
134         signal last_i_rd_s         : std_logic; -- Delayed RD bus, used for latching
135         --
136         signal address_f_s         : std_logic_vector(15 downto 0); -- Filtered address
137         signal address_d_s         : std_logic_vector(15 downto 0); -- D over address
138         --
139         signal data_read_s         : std_logic_vector(31 downto 0); -- Latched read data
140
141         -- Writing logic:
142         signal bls_f_s             : std_logic_vector(3 downto 0); -- Filtered BLS
143         signal bls_d_s             : std_logic_vector(3 downto 0); -- D over BLS
144         signal i_bls_s             : std_logic_vector(3 downto 0); -- Internal BLS (active 1)
145         --
146         signal data_write_s        : std_logic_vector(31 downto 0); -- Data broadcasted to write
147
148         -- Tumbl:
149         signal tumbl_bls_s         : std_logic_vector(3 downto 0);
150         signal tumbl_address_s     : std_logic_vector(14 downto 0);
151         signal tumbl_data_i_s      : std_logic_vector(31 downto 0);
152         --
153         signal tumbl_xmemb_o_s     : CORE2DMEMB_Type;
154         signal tumbl_xmemb_i_s     : DMEMB2CORE_Type;
155         signal tumbl_xmemb_sel_s   : std_logic;
156
157 begin
158
159 -- Tumbl coprocessor
160 memory_bus_tumbl: bus_tumbl
161         port map
162         (
163                 clk_i          => clk_50m,
164                 reset_i        => reset_s,
165                 ce_i           => tumbl_ce_s,
166                 bls_i          => i_bls_s,
167                 address_i      => address_f_s(11 downto 0),
168                 data_i         => data_i_s,
169                 data_o         => tumbl_out_s,
170                 --
171                 xmemb_o        => tumbl_xmemb_o_s,
172                 xmemb_i        => tumbl_xmemb_i_s,
173                 xmemb_sel_o    => tumbl_xmemb_sel_s
174         );
175
176 -- Measurement
177 memory_bus_measurement: bus_measurement
178         port map
179         (
180                 clk_i     => clk_50m,
181                 reset_i   => reset_s,
182                 ce_i      => meas_ce_s,
183                 address_i => address_f_s(1 downto 0),
184                 bls_i     => i_bls_s,
185                 data_i    => data_i_s,
186                 data_o    => meas_out_s
187         );
188
189 -- IRC interconnect
190 memory_bus_irc: bus_irc
191         port map
192         (
193                 reset_i        => reset_s,
194                 --
195                 clk_i          => clk_50m,
196                 address_i      => tumbl_address_s(4 downto 0),
197                 next_ce_i      => irc_proc_next_ce_s,
198                 data_i         => tumbl_data_i_s,
199                 data_o         => irc_proc_out_s,
200                 bls_i          => tumbl_bls_s,
201                 --
202                 irc_i(0).a     => irc0_a,
203                 irc_i(0).b     => irc0_b,
204                 irc_i(0).index => irc0_index,
205                 irc_i(0).mark  => irc0_mark,
206                 --
207                 irc_i(1).a     => irc1_a,
208                 irc_i(1).b     => irc1_b,
209                 irc_i(1).index => irc1_index,
210                 irc_i(1).mark  => irc1_mark,
211                 --
212                 irc_i(2).a     => irc2_a,
213                 irc_i(2).b     => irc2_b,
214                 irc_i(2).index => irc2_index,
215                 irc_i(2).mark  => irc2_mark,
216                 --
217                 irc_i(3).a     => irc3_a,
218                 irc_i(3).b     => irc3_b,
219                 irc_i(3).index => irc3_index,
220                 irc_i(3).mark  => irc3_mark,
221                 --
222                 irc_i(4).a     => irc4_a,
223                 irc_i(4).b     => irc4_b,
224                 irc_i(4).index => irc4_index,
225                 irc_i(4).mark  => irc4_mark,
226                 --
227                 irc_i(5).a     => irc5_a,
228                 irc_i(5).b     => irc5_b,
229                 irc_i(5).index => irc5_index,
230                 irc_i(5).mark  => irc5_mark,
231                 --
232                 irc_i(6).a     => irc6_a,
233                 irc_i(6).b     => irc6_b,
234                 irc_i(6).index => irc6_index,
235                 irc_i(6).mark  => irc6_mark,
236                 --
237                 irc_i(7).a     => irc7_a,
238                 irc_i(7).b     => irc7_b,
239                 irc_i(7).index => irc7_index,
240                 irc_i(7).mark  => irc7_mark
241         );
242
243 -- LX Master
244 memory_bus_lxmaster: bus_lxmaster
245         port map
246         (
247                 reset_i        => reset_s,
248                 --
249                 clk_i          => clk_50m,
250                 address_i      => tumbl_address_s(10 downto 0),
251                 next_ce_i      => lxmaster_next_ce_s,
252                 data_i         => tumbl_data_i_s(15 downto 0),
253                 data_o         => lxmaster_out_s,
254                 bls_i          => tumbl_bls_s(1 downto 0),
255                 --
256                 clock_i        => s1_clk_in,
257                 miso_i         => s1_miso,
258                 sync_i         => s1_sync_in,
259                 --
260                 clock_o        => s1_clk_out,
261                 mosi_o         => s1_mosi,
262                 sync_o         => s1_sync_out
263         );
264
265 -- Reset
266 dff_reset: dff2
267         port map
268         (
269                 clk_i   => clk_50m,
270                 reset_i => '0',
271                 d_i     => init_s,
272                 q_o     => reset_s
273         );
274
275         -- Reset
276         init_s          <= not init;
277
278         -- Filters
279         bls_f_s         <= bls when bls = bls_d_s else "1111";
280         rd_f_s          <= rd when rd = rd_d_s else '1';
281         address_f_s     <= address when address = address_d_s else last_address_s; -- Use last address on mismatch!
282
283         -- Signalling
284         data_i_s        <= data_write_s when i_bls_s /= "0000" else (others => '0');
285
286         -- Tumbl
287         tumbl_bls_s     <= i_bls_s when (master_tumbl_xmem_lock_s = '1')
288                            else tumbl_xmemb_o_s.bls when (tumbl_xmemb_sel_s = '1')
289                            else "0000";
290         tumbl_address_s <= address_f_s(14 downto 0) when (master_tumbl_xmem_lock_s = '1')
291                            else tumbl_xmemb_o_s.addr when (tumbl_xmemb_sel_s = '1')
292                            else (others => '0');
293         tumbl_data_i_s  <= data_i_s when (master_tumbl_xmem_lock_s = '1')
294                            else tumbl_xmemb_o_s.data when (tumbl_xmemb_sel_s = '1')
295                            else (others => '0');
296         --
297         tumbl_xmemb_i_s.int <= '0'; -- No interrupt
298         -- Enable clken only when available for Tumbl
299         tumbl_xmemb_i_s.clken <= not master_tumbl_xmem_lock_s;
300
301 -- Bus update
302 memory_bus_update:
303         process
304         begin
305
306                 wait until clk_50m = '1' and clk_50m'event;
307
308                 -- Defaults
309                 i_bls_s <= "0000";
310                 i_rd_s  <= '0';
311
312                 -- Check if we have chip select
313                 if cs0_xc = '0' then
314
315                         -- Reading
316                         if rd_f_s = '0' then
317
318                                 -- Internal read
319                                 if (last_rd_s = '1' or last_address_s /= address_f_s) then
320                                         i_rd_s <= '1';
321                                 end if;
322
323                                 if i_rd_s = '0' and last_i_rd_s = '1' then
324                                         -- Latch data we just read - they are valid in this cycle
325                                         data_read_s  <= data_o_s;
326                                 end if;
327
328                                 last_address_s <= address_f_s;
329                         else
330                                 -- Not reading, anything goes
331                                 data_read_s    <= (others => 'X');
332                         end if;
333
334                         last_rd_s        <= rd_f_s;
335
336                         -- Writing
337                         if bls_f_s /= "1111" then
338
339                                 -- Internal write
340                                 if (last_bls_s /= bls_f_s or last_address_s /= address_f_s) then
341                                         i_bls_s      <= not bls_f_s;
342                                 end if;
343
344                                 last_address_s <= address_f_s;
345                         end if;
346
347                         last_bls_s       <= bls_f_s;
348
349                 else
350
351                         -- Set last read / bls to '1' if CS0 is not asserted
352                         last_rd_s        <= '1';
353                         last_bls_s       <= (others => '1');
354                         last_address_s   <= address_d_s;
355
356                 end if;
357
358                 -- Filters
359                 bls_d_s     <= bls;
360                 rd_d_s      <= rd;
361                 address_d_s <= address;
362                 --
363                 last_i_rd_s <= i_rd_s;
364
365                 -- ======================================================
366                 --  TUMBL BUS
367                 -- ======================================================
368
369                 -- Just copy these to their desired next state
370                 irc_proc_ce_s <= irc_proc_next_ce_s;
371                 lxmaster_ce_s <= lxmaster_next_ce_s;
372
373         end process;
374
375 -- Do the actual wiring here
376 memory_bus_wiring:
377         process(cs0_xc, address_f_s, tumbl_out_s, meas_out_s, master_tumbl_xmem_out_s)
378         begin
379
380                 -- Inactive by default
381                 tumbl_ce_s             <= '0';
382                 meas_ce_s              <= '0';
383                 master_tumbl_xmem_ce_s <= '0';
384                 data_o_s               <= (others => '0');
385
386                 if cs0_xc = '0' then
387
388                         -- Memory Map (16-bit address @ 32-bit each)
389
390                         -- Each address is seen as 32-bit entry now
391                         -- 0x0000 - 0x0FFF: Tumbl IMEM / DMEM
392                         -- 0x1FFC - 0x1FFF: Measurement
393                         -- 0x8000 - 0x8FFF: Tumbl BUS
394
395                         if address_f_s < "0001000000000000" then                  -- Tumbl
396                                 tumbl_ce_s             <= '1';
397                                 data_o_s               <= tumbl_out_s;
398                         elsif address_f_s(15 downto 2) = "00011111111111" then    -- Measurement
399                                 meas_ce_s              <= '1';
400                                 data_o_s               <= meas_out_s;
401                         elsif address_f_s(15) = '1' then                          -- Tumbl External BUS
402                                 master_tumbl_xmem_ce_s <= '1';
403                                 data_o_s               <= master_tumbl_xmem_out_s;
404                         end if;
405
406                 end if;
407
408         end process;
409
410 -- If RD and BLS is not high, we must keep DATA at high impedance
411 -- or the FPGA collides with SDRAM (damaging each other)
412 memory_bus_out:
413         process(cs0_xc, rd, data, data_read_s)
414         begin
415
416                 -- CS0 / RD / BLS are active LOW
417                 if cs0_xc = '0' and rd = '0' then
418                         -- Don't risk flipping (between data_o_s and latched data_read_s, it's better to wait)
419                         -- Maybe check this later.
420                         -- if last_i_rd_s = '1' then
421                         --   data <= data_o_s;
422                         -- else
423                         data <= data_read_s;
424                         -- end if;
425                 else
426                         -- IMPORTANT!!!
427                         data <= (others => 'Z');
428                 end if;
429
430                 data_write_s <= data;
431
432         end process;
433
434 -- Outputs from Tumbl (enabling and address muxing) and Master CPU
435 tumbl_bus_o:
436         process(tumbl_xmemb_sel_s, tumbl_xmemb_o_s, master_tumbl_xmem_ce_s, address_f_s, i_rd_s, i_bls_s)
437                 variable addr_v : std_logic_vector(14 downto 0); -- This space is visible by both (32-bit)
438                 variable sel_v  : std_logic;
439         begin
440
441                 -- Defaults
442                 irc_proc_next_ce_s        <= '0';
443                 lxmaster_next_ce_s        <= '0';
444                 master_tumbl_xmem_lock_s  <= '0';
445                 --
446                 addr_v                    := (others => '0');
447                 sel_v                     := '0';
448
449                 -- Check who is accessing
450                 if master_tumbl_xmem_ce_s = '1' and (i_rd_s = '1' or i_bls_s /= "0000") then
451                         -- Master blocks Tumbl
452                         master_tumbl_xmem_lock_s <= '1';
453                         addr_v                   := address_f_s(14 downto 0);
454                         sel_v                    := '1';
455                 else
456                         addr_v                   := tumbl_xmemb_o_s.addr;
457                         sel_v                    := '1';
458                 end if;
459
460                 if sel_v = '1' then
461                         -- IRC:       0x0800 - 0x081F (32-bit address)
462                         -- LX MASTER: 0x1000 - 0x17FF (32-bit address)
463                         if addr_v(14 downto 5) = "0001000000" then
464                                 irc_proc_next_ce_s     <= '1';
465                         elsif addr_v(14 downto 11) = "0010" then
466                                 lxmaster_next_ce_s     <= '1';
467                         end if;
468                 end if;
469
470         end process;
471
472 -- Inputs to Tumbl (enabling and address muxing)
473 tumbl_bus_i:
474         process(irc_proc_ce_s, irc_proc_out_s, lxmaster_ce_s, lxmaster_out_s, tumbl_xmemb_i_s)
475         begin
476
477                 tumbl_xmemb_i_s.data  <= (others => 'X');
478
479                 -- NOTE: This is input to Tumbl EXEQ - with MUL instruction for input > 18-bit,
480                 -- (i.e. more DSPs in a sequence), this already has tough timing constraints
481                 -- and SmartXplorer has to be used with XiSE or use Synplify.
482                 if irc_proc_ce_s = '1' then
483                         tumbl_xmemb_i_s.data <= irc_proc_out_s;
484                 elsif lxmaster_ce_s = '1' then
485                         tumbl_xmemb_i_s.data(15 downto 0)  <= lxmaster_out_s;
486                         tumbl_xmemb_i_s.data(31 downto 16) <= (others => '0');
487                 end if;
488
489                 master_tumbl_xmem_out_s <= tumbl_xmemb_i_s.data;
490
491         end process;
492
493 end Behavioral;
494