]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/lx-rocon.git/blob - hw/lx_rocon_top.vhd
Implemented initial version of LXPWR receiver FSM based on transmitter.
[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 next_last_address_s      : std_logic_vector(15 downto 0);
122         signal next_address_hold_s      : std_logic;
123         signal address_hold_s           : std_logic;
124         signal last_rd_s                : std_logic;
125         signal next_last_rd_s           : std_logic;
126         signal last_bls_s               : std_logic_vector(3 downto 0); -- prev bls_f_s (active 1)
127         signal next_last_bls_s          : std_logic_vector(3 downto 0);
128
129         -- Reading logic for Master CPU:
130         -- Broadcast rd only till ta (transaction acknowledge)
131         -- is received, then latch the data till the state of
132         -- rd or address changes
133         --
134         -- Data latching is synchronous - it's purpose is to
135         -- provide stable data for CPU on the bus
136         signal cs0_xc_f_s          : std_logic;
137         signal rd_f_s              : std_logic; -- Filtered RD
138         signal i_rd_s              : std_logic; -- Internal bus RD (active 1)
139         -- signal next_i_rd_s         : std_logic;
140         signal last_i_rd_s         : std_logic; -- Delayed RD bus, used for latching
141         signal next_last_i_rd_s    : std_logic;
142         signal i_rd_cycle2_s       : std_logic; -- Some internal subsystems provide
143         signal next_i_rd_cycle2_s  : std_logic; -- data only after 2 cycles
144         --
145         signal address_f_s         : std_logic_vector(15 downto 0); -- Filtered address
146         --
147         signal data_f_s            : std_logic_vector(31 downto 0); -- Filterred input data
148         --
149         signal data_read_s         : std_logic_vector(31 downto 0); -- Latched read data
150         signal next_data_read_s    : std_logic_vector(31 downto 0);
151
152         -- Writing logic:
153         signal bls_f_s             : std_logic_vector(3 downto 0); -- Filtered BLS (active 1)
154         signal i_bls_s             : std_logic_vector(3 downto 0); -- Internal BLS (active 1)
155         signal next_i_bls_s        : std_logic_vector(3 downto 0);
156         --
157         signal data_write_s        : std_logic_vector(31 downto 0); -- Data broadcasted to write
158         signal next_data_write_s   : std_logic_vector(31 downto 0);
159
160         -- Tumbl:
161         signal tumbl_bls_s         : std_logic_vector(3 downto 0);
162         signal tumbl_address_s     : std_logic_vector(14 downto 0);
163         signal tumbl_data_i_s      : std_logic_vector(31 downto 0);
164         --
165         signal tumbl_xmemb_o_s     : CORE2DMEMB_Type;
166         signal tumbl_xmemb_i_s     : DMEMB2CORE_Type;
167         signal tumbl_xmemb_sel_s   : std_logic;
168
169         -- signal s0   : std_logic;
170         -- signal s1   : std_logic;
171         -- signal s2   : std_logic;
172
173         -- XST attributes
174         attribute REGISTER_DUPLICATION : string;
175         attribute REGISTER_DUPLICATION of rd : signal is "NO";
176         attribute REGISTER_DUPLICATION of rd_f_s : signal is "NO";
177         attribute REGISTER_DUPLICATION of bls : signal is "NO";
178         attribute REGISTER_DUPLICATION of bls_f_s : signal is "NO";
179         attribute REGISTER_DUPLICATION of address : signal is "NO";
180         attribute REGISTER_DUPLICATION of address_f_s : signal is "NO";
181         attribute REGISTER_DUPLICATION of cs0_xc : signal is "NO";
182
183 begin
184
185 -- Tumbl coprocessor
186 memory_bus_tumbl: bus_tumbl
187         port map
188         (
189                 clk_i          => clk_50m,
190                 reset_i        => reset_s,
191                 ce_i           => tumbl_ce_s,
192                 bls_i          => i_bls_s,
193                 address_i      => address_f_s(11 downto 0),
194                 data_i         => data_i_s,
195                 data_o         => tumbl_out_s,
196                 --
197                 xmemb_o        => tumbl_xmemb_o_s,
198                 xmemb_i        => tumbl_xmemb_i_s,
199                 xmemb_sel_o    => tumbl_xmemb_sel_s
200         );
201
202 -- Measurement
203 memory_bus_measurement: bus_measurement
204         port map
205         (
206                 clk_i     => clk_50m,
207                 reset_i   => reset_s,
208                 ce_i      => meas_ce_s,
209                 address_i => address_f_s(1 downto 0),
210                 bls_i     => i_bls_s,
211                 data_i    => data_i_s,
212                 data_o    => meas_out_s
213         );
214
215 -- IRC interconnect
216 memory_bus_irc: bus_irc
217         port map
218         (
219                 reset_i        => reset_s,
220                 --
221                 clk_i          => clk_50m,
222                 address_i      => tumbl_address_s(4 downto 0),
223                 next_ce_i      => irc_proc_next_ce_s,
224                 data_i         => tumbl_data_i_s,
225                 data_o         => irc_proc_out_s,
226                 bls_i          => tumbl_bls_s,
227                 --
228                 irc_i(0).a     => irc0_a,
229                 irc_i(0).b     => irc0_b,
230                 irc_i(0).index => irc0_index,
231                 irc_i(0).mark  => irc0_mark,
232                 --
233                 irc_i(1).a     => irc1_a,
234                 irc_i(1).b     => irc1_b,
235                 irc_i(1).index => irc1_index,
236                 irc_i(1).mark  => irc1_mark,
237                 --
238                 irc_i(2).a     => irc2_a,
239                 irc_i(2).b     => irc2_b,
240                 irc_i(2).index => irc2_index,
241                 irc_i(2).mark  => irc2_mark,
242                 --
243                 irc_i(3).a     => irc3_a,
244                 irc_i(3).b     => irc3_b,
245                 irc_i(3).index => irc3_index,
246                 irc_i(3).mark  => irc3_mark,
247                 --
248                 irc_i(4).a     => irc4_a,
249                 irc_i(4).b     => irc4_b,
250                 irc_i(4).index => irc4_index,
251                 irc_i(4).mark  => irc4_mark,
252                 --
253                 irc_i(5).a     => irc5_a,
254                 irc_i(5).b     => irc5_b,
255                 irc_i(5).index => irc5_index,
256                 irc_i(5).mark  => irc5_mark,
257                 --
258                 irc_i(6).a     => irc6_a,
259                 irc_i(6).b     => irc6_b,
260                 irc_i(6).index => irc6_index,
261                 irc_i(6).mark  => irc6_mark,
262                 --
263                 irc_i(7).a     => irc7_a,
264                 irc_i(7).b     => irc7_b,
265                 irc_i(7).index => irc7_index,
266                 irc_i(7).mark  => irc7_mark
267         );
268
269 -- LX Master
270 memory_bus_lxmaster: bus_lxmaster
271         port map
272         (
273                 reset_i        => reset_s,
274                 --
275                 clk_i          => clk_50m,
276                 address_i      => tumbl_address_s(10 downto 0),
277                 next_ce_i      => lxmaster_next_ce_s,
278                 data_i         => tumbl_data_i_s(15 downto 0),
279                 data_o         => lxmaster_out_s,
280                 bls_i          => tumbl_bls_s(1 downto 0),
281                 --
282                 clock_i        => s1_clk_in,
283                 miso_i         => s1_miso,
284                 sync_i         => s1_sync_in,
285                 --
286                 clock_o        => s1_clk_out,
287                 mosi_o         => s1_mosi,
288                 sync_o         => s1_sync_out
289                 --
290                 -- clock_i        => s0,
291                 -- miso_i         => s1,
292                 -- sync_i         => not s2,
293                 --
294                 -- clock_o        => s0,
295                 -- mosi_o         => s1,
296                 -- sync_o         => s2
297         );
298
299         -- s1_clk_out      <= s0;
300         -- s1_mosi         <= s1;
301         -- s1_sync_out     <= s2;
302
303
304 -- Reset
305 dff_reset: dff2
306         port map
307         (
308                 clk_i   => clk_50m,
309                 d_i     => init_s,
310                 q_o     => reset_s
311         );
312
313         -- Reset
314         init_s          <= not init;
315
316         -- Signalling
317         data_i_s        <= data_write_s;
318
319         -- Tumbl
320         tumbl_bls_s     <= i_bls_s when (master_tumbl_xmem_lock_s = '1')
321                            else tumbl_xmemb_o_s.bls when (tumbl_xmemb_sel_s = '1')
322                            else "0000";
323         tumbl_address_s <= address_f_s(14 downto 0) when (master_tumbl_xmem_lock_s = '1')
324                            else tumbl_xmemb_o_s.addr when (tumbl_xmemb_sel_s = '1')
325                            else (others => '0');
326         tumbl_data_i_s  <= data_i_s when (master_tumbl_xmem_lock_s = '1')
327                            else tumbl_xmemb_o_s.data when (tumbl_xmemb_sel_s = '1')
328                            else (others => '0');
329         --
330         tumbl_xmemb_i_s.int <= '0'; -- No interrupt
331         -- Enable clken only when available for Tumbl
332         tumbl_xmemb_i_s.clken <= not master_tumbl_xmem_lock_s;
333
334
335 -- Bus update
336 memory_bus_logic:
337         process(cs0_xc_f_s, rd_f_s, last_rd_s, i_rd_cycle2_s, last_i_rd_s,
338                 bls_f_s, last_bls_s, data_f_s, data_write_s,
339                 data_o_s, data_read_s, last_address_s, address_f_s)
340         begin
341                 -- Defaults
342                 next_i_rd_cycle2_s <= '0';
343                 next_address_hold_s <= '0';
344
345                 -- Check if we have chip select
346                 if cs0_xc_f_s = '1' then
347
348                         -- Reading
349                         if rd_f_s = '1' then
350                                 -- Internal read
351                                 if last_rd_s = '0' or (last_address_s /= address_f_s) then
352                                         i_rd_s <= '1';
353                                         next_i_rd_cycle2_s <= '1';
354                                         next_last_i_rd_s  <= '1';
355                                 elsif i_rd_cycle2_s = '1' then    -- FIXME it seems that some internal
356                                         i_rd_s <= '1';            -- peripherals demands 2 cycles to read
357                                         next_last_i_rd_s  <= '1';
358                                 else
359                                         i_rd_s            <= '0';
360                                         next_last_i_rd_s  <= '0';
361                                 end if;
362
363                                 if last_i_rd_s = '1' then
364                                         -- Latch data we just read - they are valid in this cycle
365                                         next_data_read_s <= data_o_s;
366                                 else
367                                         next_data_read_s <= data_read_s;
368                                 end if;
369                         else
370                         --      -- Not reading, anything goes
371                         --      data_read_s       <= (others => 'X');
372                                 next_data_read_s  <= data_read_s;
373                                 i_rd_s            <= '0';
374                                 next_last_i_rd_s  <= '0';
375                         end if;
376
377                         next_last_rd_s            <= rd_f_s;
378
379                         -- Data for write are captured only when BLS signals are stable
380                         if bls_f_s /= "0000" then
381                                 next_data_write_s <= data_f_s;
382                                 next_address_hold_s <= '1';
383                         else
384                                 next_data_write_s <= data_write_s;
385                         end if;
386
387                         if (bls_f_s /= "0000") or (rd_f_s = '1') then
388                                 next_last_address_s <= address_f_s;
389                         else
390                                 next_last_address_s <= last_address_s;
391                         end if;
392                 else
393                         next_last_rd_s <= '0';
394                         i_rd_s <= '0';
395                         next_last_i_rd_s <= '0';
396
397                         next_i_bls_s <= "0000";
398                         next_data_write_s <= data_write_s;
399                         next_data_read_s  <= data_read_s;
400                         next_last_address_s <= last_address_s;
401                 end if;
402
403                 -- Data for write are captured at/before BLS signals are negated
404                 -- and actual write cycle takes place exacly after BLS negation
405                 if ((last_bls_s and not bls_f_s) /= "0000") or
406                     ((last_bls_s /= "0000") and (cs0_xc_f_s = '0')) then
407                         next_i_bls_s <= last_bls_s;
408                         next_last_bls_s   <= "0000";
409                         next_address_hold_s <= '1';
410                 else
411                         next_i_bls_s <= "0000";
412                         if cs0_xc_f_s = '1' then
413                                 next_last_bls_s <= bls_f_s;
414                         else
415                                 next_last_bls_s <= "0000" ;
416                         end if;
417                 end if;
418
419         end process;
420
421 -- Bus update
422 memory_bus_update:
423         process
424         begin
425
426                 wait until clk_50m = '1' and clk_50m'event;
427
428                 address_hold_s <= next_address_hold_s;
429
430                 -- Synchronized external signals with main clock domain
431                 cs0_xc_f_s     <= not cs0_xc;
432                 bls_f_s        <= not bls;
433                 rd_f_s         <= not rd;
434                 data_f_s       <= data;
435                 if address_hold_s = '0' then
436                         address_f_s <= address;
437                 else
438                         address_f_s <= next_last_address_s;
439                 end if;
440
441                 -- Synchronoust state andvance to next period
442                 last_bls_s     <= next_last_bls_s;
443                 last_rd_s      <= next_last_rd_s;
444                 i_bls_s        <= next_i_bls_s;
445                 -- i_rd_s         <= next_i_rd_s;
446                 i_rd_cycle2_s  <= next_i_rd_cycle2_s;
447                 last_i_rd_s    <= next_last_i_rd_s;
448                 data_write_s   <= next_data_write_s;
449                 last_address_s <= next_last_address_s;
450                 data_read_s    <= next_data_read_s;
451                 --
452                 -- ======================================================
453                 --  TUMBL BUS
454                 -- ======================================================
455
456                 -- Just copy these to their desired next state
457                 irc_proc_ce_s <= irc_proc_next_ce_s;
458                 lxmaster_ce_s <= lxmaster_next_ce_s;
459
460         end process;
461
462 -- Do the actual wiring here
463 memory_bus_wiring:
464         process(cs0_xc_f_s, i_bls_s, address_f_s, tumbl_out_s, meas_out_s, master_tumbl_xmem_out_s)
465         begin
466
467                 -- Inactive by default
468                 tumbl_ce_s             <= '0';
469                 meas_ce_s              <= '0';
470                 master_tumbl_xmem_ce_s <= '0';
471                 data_o_s               <= (others => '0');
472
473                 if cs0_xc_f_s = '1' or i_bls_s /= "0000" then
474
475                         -- Memory Map (16-bit address @ 32-bit each)
476
477                         -- Each address is seen as 32-bit entry now
478                         -- 0x0000 - 0x0FFF: Tumbl IMEM / DMEM
479                         -- 0x1FFC - 0x1FFF: Measurement
480                         -- 0x8000 - 0x8FFF: Tumbl BUS
481
482                         if address_f_s < "0001000000000000" then                  -- Tumbl
483                                 tumbl_ce_s             <= '1';
484                                 data_o_s               <= tumbl_out_s;
485                         elsif address_f_s(15 downto 2) = "00011111111111" then    -- Measurement
486                                 meas_ce_s              <= '1';
487                                 data_o_s               <= meas_out_s;
488                         elsif address_f_s(15) = '1' then                          -- Tumbl External BUS
489                                 master_tumbl_xmem_ce_s <= '1';
490                                 data_o_s               <= master_tumbl_xmem_out_s;
491                         end if;
492
493                 end if;
494
495         end process;
496
497 -- If RD and BLS is not high, we must keep DATA at high impedance
498 -- or the FPGA collides with SDRAM (damaging each other)
499 memory_bus_out:
500         process(cs0_xc, rd, data_read_s)
501         begin
502
503                 -- CS0 / RD / BLS are active LOW
504                 if cs0_xc = '0' and rd = '0' then
505                         -- Don't risk flipping (between data_o_s and latched data_read_s, it's better to wait)
506                         -- Maybe check this later.
507                         -- if last_i_rd_s = '1' then
508                         --   data <= data_o_s;
509                         -- else
510                         data <= data_read_s;
511                         -- end if;
512                 else
513                         -- IMPORTANT!!!
514                         data <= (others => 'Z');
515                 end if;
516
517         end process;
518
519 -- Outputs from Tumbl (enabling and address muxing) and Master CPU
520 tumbl_bus_o:
521         process(tumbl_xmemb_sel_s, tumbl_xmemb_o_s, master_tumbl_xmem_ce_s, address_f_s, i_rd_s, i_bls_s)
522                 variable addr_v : std_logic_vector(14 downto 0); -- This space is visible by both (32-bit)
523                 variable sel_v  : std_logic;
524         begin
525
526                 -- Defaults
527                 irc_proc_next_ce_s        <= '0';
528                 lxmaster_next_ce_s        <= '0';
529                 master_tumbl_xmem_lock_s  <= '0';
530                 --
531                 addr_v                    := (others => '0');
532                 sel_v                     := '0';
533
534                 -- Check who is accessing
535                 if master_tumbl_xmem_ce_s = '1' and (i_rd_s = '1' or i_bls_s /= "0000") then
536                         -- Master blocks Tumbl
537                         master_tumbl_xmem_lock_s <= '1';
538                         addr_v                   := address_f_s(14 downto 0);
539                         sel_v                    := '1';
540                 else
541                         addr_v                   := tumbl_xmemb_o_s.addr;
542                         sel_v                    := '1';
543                 end if;
544
545                 if sel_v = '1' then
546                         -- IRC:       0x0800 - 0x081F (32-bit address)
547                         -- LX MASTER: 0x1000 - 0x17FF (32-bit address)
548                         if addr_v(14 downto 5) = "0001000000" then
549                                 irc_proc_next_ce_s     <= '1';
550                         elsif addr_v(14 downto 11) = "0010" then
551                                 lxmaster_next_ce_s     <= '1';
552                         end if;
553                 end if;
554
555         end process;
556
557 -- Inputs to Tumbl (enabling and address muxing)
558 tumbl_bus_i:
559         process(irc_proc_ce_s, irc_proc_out_s, lxmaster_ce_s, lxmaster_out_s, tumbl_xmemb_i_s)
560         begin
561
562                 tumbl_xmemb_i_s.data  <= (others => 'X');
563
564                 -- NOTE: This is input to Tumbl EXEQ - with MUL instruction for input > 18-bit,
565                 -- (i.e. more DSPs in a sequence), this already has tough timing constraints
566                 -- and SmartXplorer has to be used with XiSE or use Synplify.
567                 if irc_proc_ce_s = '1' then
568                         tumbl_xmemb_i_s.data <= irc_proc_out_s;
569                 elsif lxmaster_ce_s = '1' then
570                         tumbl_xmemb_i_s.data(15 downto 0)  <= lxmaster_out_s;
571                         tumbl_xmemb_i_s.data(31 downto 16) <= (others => '0');
572                 end if;
573
574                 master_tumbl_xmem_out_s <= tumbl_xmemb_i_s.data;
575
576         end process;
577
578 end Behavioral;
579