]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/lx-rocon.git/blob - hw/lx_rocon_top.vhd
Major refactorization in hw
[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
22 -- - data_in[31..0]          The data coming to bus
23 -- - data_out[31..0]         The data coming from bus, multiplexed
24 -- - rd                      Read enable, active LOW
25 -- - bls[3..0]               Write enable for respective bytes, active LOW
26 --                           In some cases, only WR is used
27 -- - ta                      Transaction acknowledge (latches data out), active LOW, multiplexed
28 --
29 -- ======================================================
30 --  TUMBL EXTERNAL MEMORY BUS
31 -- ======================================================
32
33 entity lx_rocon_top is
34         port
35         (
36                 -- External
37                 --clk_cpu    : in std_logic;
38                 clk_50m    : in std_logic;
39
40                 cs0_xc     : in std_logic;
41
42                 rd         : in std_logic;
43                 bls        : in std_logic_vector(3 downto 0);
44                 address    : in std_logic_vector(15 downto 0);
45                 data       : inout std_logic_vector(31 downto 0);
46
47                 irc1_a     : in std_logic;
48                 irc1_b     : in std_logic;
49                 irc1_index : in std_logic;
50                 irc1_mark  : in std_logic;
51
52                 irc2_a     : in std_logic;
53                 irc2_b     : in std_logic;
54                 irc2_index : in std_logic;
55                 irc2_mark  : in std_logic;
56
57                 irc3_a     : in std_logic;
58                 irc3_b     : in std_logic;
59                 irc3_index : in std_logic;
60                 irc3_mark  : in std_logic;
61
62                 irc4_a     : in std_logic;
63                 irc4_b     : in std_logic;
64                 irc4_index : in std_logic;
65                 irc4_mark  : in std_logic;
66
67                 init       : in std_logic
68         );
69 end lx_rocon_top;
70
71 architecture Behavioral of lx_rocon_top is
72
73         -- Reset signal
74         signal reset_s           : std_logic;
75         signal neg_init_s        : std_logic;
76         -- 100 MHz clock
77         signal clk_100m_s        : std_logic;
78         signal clk_100m_fb_s     : std_logic;
79         signal clk_100m_locked_s : std_logic;
80         -- Peripherals on the memory bus
81         signal tumbl_out_s       : std_logic_vector(31 downto 0);
82         signal tumbl_ta_s        : std_logic;
83         signal tumbl_ce_s        : std_logic;
84         --
85         signal irc_reg_out_s     : std_logic_vector(31 downto 0);
86         signal irc_reg_ta_s      : std_logic;
87         signal irc_reg_ce_s      : std_logic;
88         --
89         signal calib_out_s       : std_logic_vector(31 downto 0);
90         signal calib_ta_s        : std_logic;
91         signal calib_ce_s        : std_logic;
92         -- Signals for external bus transmission
93         signal data_i_s          : std_logic_vector(31 downto 0);
94         signal data_o_s          : std_logic_vector(31 downto 0);
95         -- Signals for internal transaction
96         signal last_address_s    : std_logic_vector(15 downto 0);
97         signal last_rd_s         : std_logic;
98         signal last_bls_s        : std_logic_vector(3 downto 0);
99
100         -- Reading logic:
101         -- Broadcast rd only till ta (transaction acknowledge)
102         -- is received, then latch the data till the state of
103         -- rd or address changes
104         --
105         -- Data latching is synchronous - it's purpose is to
106         -- provide stable data for CPU on the bus on high rise
107         -- of trans. ack signal
108         signal rd_f_s            : std_logic; -- Filtered RD
109         signal rd_d_s            : std_logic; -- D over RD
110         signal i_ta_s            : std_logic; -- Internal bus TA (active 1)
111         signal i_rd_s            : std_logic; -- Internal bus RD (active 1)
112         --
113         signal data_read_s       : std_logic_vector(31 downto 0); -- Latched read data
114         --
115         signal acked_s           : std_logic;
116
117         -- Writing logic:
118         signal bls_f_s : std_logic_vector(3 downto 0); -- Filtered BLS
119         signal bls_d_s : std_logic_vector(3 downto 0); -- D over BLS
120         signal i_bls_s : std_logic_vector(3 downto 0); -- Internal BLS (active 1)
121         --
122         signal data_write_s : std_logic_vector(31 downto 0); -- Data broadcasted to write
123
124 begin
125
126         -- Clocking
127         clk_100m_dcm_sp : DCM_SP
128         generic map
129         (
130                 clkdv_divide          => 2.0,
131                 clkfx_divide          => 1,
132                 clkfx_multiply        => 2,
133                 clkin_divide_by_2     => false,
134                 clkin_period          => 20.0, -- 50 MHz
135                 clkout_phase_shift    => "NONE",
136                 clk_feedback          => "1X",
137                 deskew_adjust         => "SYSTEM_SYNCHRONOUS",
138                 dfs_frequency_mode    => "LOW",
139                 dll_frequency_mode    => "LOW",
140                 dss_mode              => "NONE",
141                 duty_cycle_correction => true,
142                 factory_jf            => X"c080",
143                 phase_shift           => 0,
144                 startup_wait          => false
145         )
146         port map
147         (
148                 clk0                  => clk_100m_fb_s,
149                 clk180                => open,
150                 clk270                => open,
151                 clk2x                 => clk_100m_s,
152                 clk2x180              => open,
153                 clk90                 => open,
154                 clkdv                 => open,
155                 clkfx                 => open,
156                 clkfx180              => open,
157                 locked                => clk_100m_locked_s,
158                 psdone                => open,
159                 status                => open,
160                 clkfb                 => clk_100m_fb_s,
161                 clkin                 => clk_50m,
162                 dssen                 => '0',
163                 psclk                 => '0',
164                 psen                  => '0',
165                 psincdec              => '0',
166                 rst                   => neg_init_s
167         );
168
169         -- IRC interconnect
170         memory_bus_irc: bus_irc
171         port map
172         (
173                 clk_i        => clk_100m_s,
174                 reset_i      => reset_s,
175                 address_i    => address(3 downto 0),
176                 ce_i         => irc_reg_ce_s,
177                 data_i       => data_i_s(0),
178                 data_o       => irc_reg_out_s,
179                 rd_i         => i_rd_s,
180                 wr_i         => i_bls_s(0),
181                 ta_o         => irc_reg_ta_s,
182                 --
183                 irc1_a_i     => irc1_a,
184                 irc1_b_i     => irc1_b,
185                 irc1_index_i => irc1_index,
186                 irc1_mark_i  => irc1_mark,
187                 --
188                 irc2_a_i     => irc2_a,
189                 irc2_b_i     => irc2_b,
190                 irc2_index_i => irc2_index,
191                 irc2_mark_i  => irc2_mark,
192                 --
193                 irc3_a_i     => irc3_a,
194                 irc3_b_i     => irc3_b,
195                 irc3_index_i => irc3_index,
196                 irc3_mark_i  => irc3_mark,
197                 --
198                 irc4_a_i     => irc4_a,
199                 irc4_b_i     => irc4_b,
200                 irc4_index_i => irc4_index,
201                 irc4_mark_i  => irc4_mark
202         );
203
204         -- Tumbl coprocessor
205         memory_bus_tumbl: bus_tumbl
206         port map
207         (
208                 clk_100m_i        => clk_100m_s,
209                 clk_50m_i         => clk_50m,
210                 reset_100m_i      => reset_s,
211                 ce_100m_i         => tumbl_ce_s,
212                 ta_100m_o         => tumbl_ta_s,
213                 rd_100m_i         => i_rd_s,
214                 bls_100m_i        => i_bls_s,
215                 address_100m_i    => address(11 downto 0),
216                 data_100m_i       => data_i_s,
217                 data_100m_o       => tumbl_out_s,
218                 --
219                 XMEMB_50m_o       => open,
220                 XMEMB_50m_i.clken => '1',
221                 XMEMB_50m_i.data  => (others => '1'),
222                 XMEMB_50m_i.int   => '0',
223                 XMEMB_sel_50m_o   => open
224         );
225
226         -- Calibration
227         memory_bus_calibration: bus_calibration
228         port map
229         (
230                 clk_i     => clk_100m_s,
231                 reset_i   => reset_s,
232                 ce_i      => calib_ce_s,
233                 address_i => address(1 downto 0),
234                 rd_i      => i_rd_s,
235                 bls_i     => i_bls_s,
236                 ta_o      => calib_ta_s,
237                 data_i    => data_i_s,
238                 data_o    => calib_out_s
239         );
240
241         -- Filters
242         --bls_f <= bls when bls = bls_d else "1111";
243         bls_f_s(0) <= bls(0) when bls(0) = bls_d_s(0) else '1';
244         bls_f_s(1) <= bls(2) when bls(2) = bls_d_s(2) else '1';
245         bls_f_s(2) <= bls(2) when bls(2) = bls_d_s(2) else '1';
246         bls_f_s(3) <= bls(3) when bls(3) = bls_d_s(3) else '1';
247         rd_f_s     <= rd when rd = rd_d_s else '1';
248
249         -- Bus update
250 memory_bus_update:
251         process(clk_100m_s)
252         begin
253
254                 if clk_100m_s = '1' and clk_100m_s'event then
255
256                         -- Set every signal to inactive state here
257                         irc_reg_ce_s  <= '0';
258                         tumbl_ce_s    <= '0';
259                         calib_ce_s    <= '0';
260                         i_rd_s        <= '0';
261                         i_bls_s       <= (others => '0');
262                         data_i_s      <= (others => 'X');
263
264                         -- Check if we have chip select
265                         if reset_s = '1' then
266                                 acked_s     <= '1';
267                                 i_ta_s      <= '0';
268                                 data_read_s <= (others => '0');
269                         elsif cs0_xc = '0' then
270
271                                 -- Memory Map (16-bit address @ 32-bit each)
272
273                                 -- Each address is seen as 32-bit entry now
274                                 -- 0x0000 - 0x0FFF: Tumbl
275                                 -- 0x8000 - 0x800F: IRC registers
276                                 -- 0xFFFC - 0xFFFF: Calibration
277
278                                 if address < "0001000000000000" then               -- Tumbl
279                                         tumbl_ce_s   <= '1';
280                                         i_ta_s       <= tumbl_ta_s;
281                                         data_o_s     <= tumbl_out_s;
282                                 elsif address(15 downto 4) = "100000000000" then   -- IRC
283                                         irc_reg_ce_s <= '1';
284                                         i_ta_s       <= irc_reg_ta_s;
285                                         data_o_s     <= irc_reg_out_s;
286                                 elsif address(15 downto 2) = "11111111111111" then -- Calibration
287                                         calib_ce_s   <= '1';
288                                         i_ta_s       <= calib_ta_s;
289                                         data_o_s     <= calib_out_s;
290                                 end if;
291
292                                 -- Reading
293                                 if rd_f_s = '0' then
294                                         if last_rd_s = '1' or last_address_s /= address then
295                                                 -- Getting something new
296                                                 -- Set internal RD to active and reset ack and latched data
297                                                 acked_s      <= '0';
298                                                 i_rd_s       <= '1';
299                                                 -- Data latching - synchronous
300                                                 data_read_s  <= (others => 'X');
301                                         elsif i_rd_s = '1' and acked_s = '0' and i_ta_s = '1' then
302                                                 -- Got acknowledge, latch data
303                                                 acked_s      <= '1';
304                                                 data_read_s  <= data_o_s;
305                                         elsif acked_s = '0' then
306                                                 -- Ongoing read, keep the signal active
307                                                 i_rd_s       <= '1';
308                                                 data_read_s  <= (others => 'X');
309                                         end if;
310
311                                         last_address_s <= address;
312                                 else
313                                         -- Not reading, anything goes
314                                         data_read_s    <= (others => 'X');
315                                 end if;
316
317                                 last_rd_s        <= rd_f_s;
318
319                                 -- Writing
320                                 if bls_f_s /= "1111" then
321
322                                         if last_bls_s /= bls_f_s or last_address_s /= address then
323                                                 -- Broadcast BLS for once cycle to write the data
324                                                 i_bls_s      <= not bls_f_s;
325                                                 data_i_s     <= data_write_s;
326                                         end if;
327
328                                         last_address_s <= address;
329                                 end if;
330
331                                 last_bls_s       <= bls_f_s;
332
333                         else
334
335                                 -- Set last read / bls to '1' if CS0 is not asserted
336                                 last_rd_s        <= '1';
337                                 last_bls_s       <= (others => '1');
338
339                         end if;
340
341                         -- Filters
342                         bls_d_s <= bls;
343                         rd_d_s  <= rd;
344
345                 end if;
346
347         end process;
348
349         -- If RD and BLS is not high, we must keep DATA at high impedance
350         -- or the FPGA collides with SDRAM (damaging each other)
351 memory_bus_out:
352         process(cs0_xc, rd, data, data_read_s)
353         begin
354
355                 -- CS0 / RD / BLS are active LOW
356                 if cs0_xc = '0' and rd = '0' then
357                         data <= data_read_s;
358                 else
359                         -- IMPORTANT!!!
360                         data <= (others => 'Z');
361                 end if;
362
363                 data_write_s <= data;
364
365         end process;
366
367         -- Reset
368 initialization:
369         process(init, clk_100m_locked_s)
370         begin
371
372                 -- TODO: Proper reset (lacks filter and propagation with ack as we use PLL)
373                 neg_init_s <= not init;
374                 reset_s <= (not init) or (not clk_100m_locked_s);
375
376         end process;
377
378 end Behavioral;
379