]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/lx-rocon.git/blob - hw/lx_rocon_top.vhd
Multiple changes in FPGA, include Tumbl coprocessor
[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 : std_logic;
75         signal neg_init : std_logic;
76
77         -- 100 MHz clock
78         signal clk_100m : std_logic;
79         signal clk_100m_fb : std_logic;
80         signal clk_100m_locked : std_logic;
81
82         -- Peripherals on the memory bus
83         signal tumbl_out : std_logic_vector(31 downto 0);
84         signal tumbl_ta : std_logic;
85         signal tumbl_ce : std_logic;
86
87         signal irc_reg_out : std_logic_vector(31 downto 0);
88         signal irc_reg_ta : std_logic;
89         signal irc_reg_ce : std_logic;
90
91         signal calib_out : std_logic_vector(31 downto 0);
92         signal calib_ta : std_logic;
93         signal calib_ce : std_logic;
94
95         -- Signals for external bus transmission
96         signal data_in_bus : std_logic_vector(31 downto 0);
97         signal data_out_bus : std_logic_vector(31 downto 0);
98
99         -- Signals for internal transaction
100         signal last_address : std_logic_vector(15 downto 0);
101         signal last_rd : std_logic;
102         signal last_bls : std_logic_vector(3 downto 0);
103
104         -- Reading logic:
105         -- Broadcast rd only till ta (transaction acknowledge)
106         -- is received, then latch the data till the state of
107         -- rd or address changes
108         --
109         -- Data latching is synchronous - it's purpose is to
110         -- provide stable data for CPU on the bus on high rise
111         -- of trans. ack signal
112         signal rd_f : std_logic;
113         signal rd_d : std_logic;
114
115         signal data_read : std_logic_vector(31 downto 0);
116
117         signal i_ta : std_logic;
118         signal i_rd : std_logic;
119         signal acked : std_logic;
120
121         -- Writing logic:
122         signal bls_f : std_logic_vector(3 downto 0);
123         signal bls_d : std_logic_vector(3 downto 0);
124
125         signal data_write : std_logic_vector(31 downto 0);
126
127         signal i_bls : std_logic_vector(3 downto 0);
128
129 begin
130
131         -- Clocking
132         clk_100m_dcm_sp : DCM_SP
133         generic map
134         (
135                 clkdv_divide => 2.0,
136                 clkfx_divide => 1,
137                 clkfx_multiply => 2,
138                 clkin_divide_by_2 => false,
139                 clkin_period => 20.0, -- 50 MHz
140                 clkout_phase_shift => "NONE",
141                 clk_feedback => "1X",
142                 deskew_adjust => "SYSTEM_SYNCHRONOUS",
143                 dfs_frequency_mode => "LOW",
144                 dll_frequency_mode => "LOW",
145                 dss_mode => "NONE",
146                 duty_cycle_correction => true,
147                 factory_jf => X"c080",
148                 phase_shift => 0,
149                 startup_wait => false
150         )
151         port map
152         (
153                 clk0 => clk_100m_fb,
154                 clk180 => open,
155                 clk270 => open,
156                 clk2x => clk_100m,
157                 clk2x180 => open,
158                 clk90 => open,
159                 clkdv => open,
160                 clkfx => open,
161                 clkfx180 => open,
162                 locked => clk_100m_locked,
163                 psdone => open,
164                 status => open,
165                 clkfb => clk_100m_fb,
166                 clkin => clk_50m,
167                 dssen => '0',
168                 psclk => '0',
169                 psen => '0',
170                 psincdec => '0',
171                 rst => neg_init
172         );
173
174         -- IRC interconnect
175         memory_bus_irc: bus_irc
176         port map
177         (
178                 clk => clk_100m,
179                 reset => reset,
180                 address => address(3 downto 0),
181                 ce => irc_reg_ce,
182                 data_in => data_in_bus(0),
183                 data_out => irc_reg_out,
184                 rd => i_rd,
185                 wr => i_bls(0),
186                 ta => irc_reg_ta,
187
188                 irc1_a => irc1_a,
189                 irc1_b => irc1_b,
190                 irc1_index => irc1_index,
191                 irc1_mark => irc1_mark,
192
193                 irc2_a => irc2_a,
194                 irc2_b => irc2_b,
195                 irc2_index => irc2_index,
196                 irc2_mark => irc2_mark,
197
198                 irc3_a => irc3_a,
199                 irc3_b => irc3_b,
200                 irc3_index => irc3_index,
201                 irc3_mark => irc3_mark,
202
203                 irc4_a => irc4_a,
204                 irc4_b => irc4_b,
205                 irc4_index => irc4_index,
206                 irc4_mark => irc4_mark
207         );
208
209         -- Tumbl coprocessor
210         memory_bus_tumbl: bus_tumbl
211         port map
212         (
213                 clk_100m => clk_100m,
214                 clk_50m => clk_50m,
215                 reset => reset,
216                 ce => tumbl_ce,
217                 ta => tumbl_ta,
218                 rd => i_rd,
219                 bls => i_bls,
220                 address => address(11 downto 0),
221                 data_in => data_in_bus,
222                 data_out => tumbl_out,
223
224                 XMEMB_o => open,
225                 XMEMB_i.clken => '1',
226                 XMEMB_i.data => (others => '1'),
227                 XMEMB_i.int => '0',
228                 XMEMB_sel_o => open
229         );
230
231         -- Calibration
232         memory_bus_calibration: bus_calibration
233         port map
234         (
235                 clk => clk_100m,
236                 reset => reset,
237                 ce => calib_ce,
238                 address => address(1 downto 0),
239                 rd => i_rd,
240                 bls => i_bls,
241                 ta => calib_ta,
242                 data_in => data_in_bus,
243                 data_out => calib_out
244         );
245
246         -- Filters
247         bls_f <= bls when bls = bls_d else "1111";
248         rd_f <= rd when rd = rd_d else '1';
249
250         -- Bus update
251         memory_bus_update: process(clk_100m)
252         begin
253
254                 if clk_100m = '1' and clk_100m'event then
255
256                         -- Set every signal to inactive state here
257                         irc_reg_ce <= '1';
258                         tumbl_ce <= '1';
259                         calib_ce <= '1';
260                         i_rd <= '1';
261                         i_bls <= (others => '1');
262                         data_in_bus <= (others => 'X');
263
264                         -- Check if we have chip select
265                         if cs0_xc = '0' then
266
267                                 -- Memory Map (16-bit address @ 32-bit each)
268
269                                 -- Each address is seen as 32-bit entry now
270                                 -- 0x0000 - 0x0FFF: Tumbl
271                                 -- 0x8000 - 0x800F: IRC registers
272                                 -- 0xFFFC - 0xFFFF: Calibration
273
274                                 if address < "0001000000000000" then -- Tumbl
275                                         tumbl_ce <= '0';
276                                         i_ta <= tumbl_ta;
277                                         data_out_bus <= tumbl_out;
278                                 elsif address(15 downto 4) = "100000000000" then -- IRC
279                                         irc_reg_ce <= '0';
280                                         i_ta <= irc_reg_ta;
281                                         data_out_bus <= irc_reg_out;
282                                 elsif address(15 downto 2) = "11111111111111" then -- Calibration
283                                         calib_ce <= '0';
284                                         i_ta <= calib_ta;
285                                         data_out_bus <= calib_out;
286                                 end if;
287
288                                 -- Reading
289                                 if rd_f = '0' then
290                                         if last_rd = '1' or last_address /= address then
291                                                 -- Getting something new
292                                                 -- Set internal RD to active and reset ack and latched data
293                                                 acked <= '0';
294                                                 i_rd <= '0';
295                                                 -- Data latching - synchronous
296                                                 data_read <= (others => 'X');
297                                         elsif i_rd = '0' and acked = '0' and i_ta = '0' then
298                                                 -- Got acknowledge, latch data
299                                                 acked <= '1';
300                                                 data_read <= data_out_bus;
301                                         elsif acked = '0' then
302                                                 -- Ongoing read, keep the signal low
303                                                 i_rd <= '0';
304                                                 data_read <= (others => 'X');
305                                         end if;
306
307                                         last_address <= address;
308                                 else
309                                         -- Not reading, anything goes
310                                         data_read <= (others => 'X');
311                                 end if;
312
313                                 last_rd <= rd_f;
314
315                                 -- Writing (BLS is filtered due to bus error otherwise)
316                                 if bls_f /= "1111" then
317
318                                         if last_bls /= bls_f or last_address /= address then
319                                                 -- Broadcast BLS for once cycle to write the data
320                                                 i_bls <= bls_f;
321                                                 data_in_bus <= data_write;
322                                         end if;
323
324                                         last_address <= address;
325                                 end if;
326
327                                 last_bls <= bls_f;
328
329                         else
330
331                                 -- Set last read / bls to '1' if CS0 is not asserted
332                                 last_rd <= '1';
333                                 last_bls <= (others => '1');
334
335                         end if;
336
337                         -- Filters
338                         bls_d <= bls;
339                         rd_d <= rd;
340
341                 end if;
342
343         end process;
344
345         -- If RD and BLS is not high, we must keep DATA at high impedance
346         -- or the FPGA collides with SDRAM (damaging each other)
347         memory_bus_out: process(cs0_xc, rd, data, data_read)
348         begin
349
350                 -- CS0 / RD / BLS are active LOW
351                 if cs0_xc = '0' and rd = '0' then
352                         data <= data_read;
353                 else
354                         -- IMPORTANT!!!
355                         data <= (others => 'Z');
356                 end if;
357
358                 data_write <= data;
359
360         end process;
361
362         -- Reset
363         initialization: process(init, clk_100m_locked)
364         begin
365
366                 neg_init <= not init;
367                 reset <= (not init) or (not clk_100m_locked);
368
369         end process;
370
371 end Behavioral;
372