]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/lx-rocon.git/blob - hw/lx_rocon_top.vhd
FPGA: Improvements & Fixes
[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 -- lx_rocon_top - wires the modules with outside world
8
9 -- ======================================================
10 --  INTERNAL MEMORY BUS
11 -- ======================================================
12 --
13 -- Internal memory bus has the following wires:
14 --
15 -- - address[15..0]          The address
16 -- - data_in[31..0]          The data coming to bus
17 -- - data_out[31..0]         The data coming from bus, multiplexed
18 -- - rd                      Read enable, active LOW
19 -- - bls[3..0]               Write enable for respective bytes, active LOW
20 --                           In some cases, only WR is used
21 -- - ta                      Transaction acknowledge (latches data out), active LOW, multiplexed
22
23 entity lx_rocon_top is
24         port
25         (
26                 -- External
27                 clk_cpu   : in std_logic;
28
29                 cs0_xc   : in std_logic;
30
31                 rd       : in std_logic;
32                 bls      : in std_logic_vector(3 downto 0);
33                 address  : in std_logic_vector(15 downto 0);
34                 data     : inout std_logic_vector(31 downto 0);
35
36                 irc1_a     : in std_logic;
37                 irc1_b     : in std_logic;
38                 irc1_index : in std_logic;
39                 irc1_mark  : in std_logic;
40
41                 irc2_a     : in std_logic;
42                 irc2_b     : in std_logic;
43                 irc2_index : in std_logic;
44                 irc2_mark  : in std_logic;
45
46                 irc3_a     : in std_logic;
47                 irc3_b     : in std_logic;
48                 irc3_index : in std_logic;
49                 irc3_mark  : in std_logic;
50
51                 irc4_a     : in std_logic;
52                 irc4_b     : in std_logic;
53                 irc4_index : in std_logic;
54                 irc4_mark  : in std_logic;
55
56                 init       : in std_logic
57         );
58 end lx_rocon_top;
59
60 architecture Behavioral of lx_rocon_top is
61
62         -- Reset signal
63         signal reset : std_logic;
64
65         -- Peripherals on the memory bus
66         signal bram_out : std_logic_vector(31 downto 0);
67         signal bram_ta : std_logic;
68         signal bram_ce : std_logic;
69
70         signal irc_reg_out : std_logic_vector(31 downto 0);
71         signal irc_reg_ta : std_logic;
72         signal irc_reg_ce : std_logic;
73
74         signal bcd_out : std_logic_vector(31 downto 0);
75         signal bcd_ta : std_logic;
76         signal bcd_ce : std_logic;
77
78         signal calib_out : std_logic_vector(31 downto 0);
79         signal calib_ta : std_logic;
80         signal calib_ce : std_logic;
81
82         -- Signals for external bus transmission
83         signal data_in_bus : std_logic_vector(31 downto 0);
84         signal data_out_bus : std_logic_vector(31 downto 0);
85
86         -- Signals for internal transaction
87         signal last_address : std_logic_vector(15 downto 0);
88         signal last_rd : std_logic;
89         signal last_bls : std_logic_vector(3 downto 0);
90
91         -- Reading logic:
92         -- Broadcast rd only till ta (transaction acknowledge)
93         -- is received, then latch the data till the state of
94         -- rd or address changes
95         --
96         -- Data latching is synchronous - it's purpose is to
97         -- provide stable data for CPU on the bus on high rise
98         -- of trans. ack signal
99         signal i_ta : std_logic;
100         signal i_rd : std_logic;
101         signal data_read : std_logic_vector(31 downto 0);
102         signal acked : std_logic;
103
104         -- Writing logic:
105         signal i_bls : std_logic_vector(3 downto 0);
106         signal data_write : std_logic_vector(31 downto 0);
107
108         component bus_irc
109         port
110         (
111                 clk         : in std_logic;
112                 reset       : in std_logic;
113
114                 address     : in std_logic_vector(3 downto 0);
115                 ce          : in std_logic;
116
117                 data_in     : in std_logic;
118                 data_out    : out std_logic_vector(31 downto 0);
119
120                 rd          : in std_logic;
121                 wr          : in std_logic;
122                 ta          : out std_logic;
123
124                 irc1_a      : in std_logic;
125                 irc1_b      : in std_logic;
126                 irc1_index  : in std_logic;
127                 irc1_mark   : in std_logic;
128
129                 irc2_a      : in std_logic;
130                 irc2_b      : in std_logic;
131                 irc2_index  : in std_logic;
132                 irc2_mark   : in std_logic;
133
134                 irc3_a      : in std_logic;
135                 irc3_b      : in std_logic;
136                 irc3_index  : in std_logic;
137                 irc3_mark   : in std_logic;
138
139                 irc4_a      : in std_logic;
140                 irc4_b      : in std_logic;
141                 irc4_index  : in std_logic;
142                 irc4_mark   : in std_logic
143         );
144         end component;
145
146         component bus_control_bram
147         port
148         (
149                 clk : in std_logic;
150
151     ena : in std_logic;
152     wea : in std_logic_vector(3 downto 0);
153     addra : in std_logic_vector(8 downto 0);
154     dina : in std_logic_vector(31 downto 0);
155     douta : out std_logic_vector(31 downto 0);
156                 taa : out std_logic;
157
158     enb : in std_logic;
159     web : in std_logic_vector(3 downto 0);
160     addrb : in std_logic_vector(8 downto 0);
161     dinb : in std_logic_vector(31 downto 0);
162     doutb : out std_logic_vector(31 downto 0)
163   );
164         end component;
165
166         component bus_bcd
167         port
168         (
169                 reset      : in std_logic;
170                 en         : in std_logic;
171                 clk        : in std_logic;
172                 ce         : in std_logic;
173                 data_out   : out std_logic_vector(31 downto 0);
174                 rd         : in std_logic;
175                 ta         : out std_logic
176         );
177         end component;
178
179         component bus_calibration
180         port
181         (
182                 clk         : in std_logic;
183                 reset       : in std_logic;
184                 ce          : in std_logic;
185                 address     : in std_logic_vector(1 downto 0);
186                 data_in     : in std_logic_vector(31 downto 0);
187                 data_out    : out std_logic_vector(31 downto 0);
188                 rd          : in std_logic;
189                 bls         : in std_logic_vector(3 downto 0);
190                 ta          : out std_logic
191         );
192         end component;
193
194 begin
195
196         -- IRC interconnect
197         memory_bus_irc: bus_irc
198         port map
199         (
200                 clk => clk_cpu,
201                 reset => reset,
202                 address => address(3 downto 0),
203                 ce => irc_reg_ce,
204                 data_in => data_in_bus(0),
205                 data_out => irc_reg_out,
206                 rd => i_rd,
207                 wr => bls(0),
208                 ta => irc_reg_ta,
209
210                 irc1_a => irc1_a,
211                 irc1_b => irc1_b,
212                 irc1_index => irc1_index,
213                 irc1_mark => irc1_mark,
214
215                 irc2_a => irc2_a,
216                 irc2_b => irc2_b,
217                 irc2_index => irc2_index,
218                 irc2_mark => irc2_mark,
219
220                 irc3_a => irc3_a,
221                 irc3_b => irc3_b,
222                 irc3_index => irc3_index,
223                 irc3_mark => irc3_mark,
224
225                 irc4_a => irc4_a,
226                 irc4_b => irc4_b,
227                 irc4_index => irc4_index,
228                 irc4_mark => irc4_mark
229         );
230
231         -- Control BRAM interconnect (9 kib)
232         memory_bus_control_bram: bus_control_bram
233         port map
234         (
235                 clk => clk_cpu,
236                 ena => bram_ce,
237                 taa => bram_ta,
238                 wea => i_bls,
239                 addra => address(8 downto 0),
240                 dina => data_in_bus,
241                 douta => bram_out,
242
243                 enb => '0',
244                 web => (others => '0'),
245                 addrb => (others => '0'),
246                 dinb => (others => '0'),
247                 doutb => open
248         );
249
250         -- BCD
251         memory_bus_bcd: bus_bcd
252         port map
253         (
254                 clk => clk_cpu,
255                 reset => reset,
256                 en => '1',
257                 ce => bcd_ce,
258                 rd => i_rd,
259                 ta => bcd_ta,
260                 data_out => bcd_out
261         );
262
263         -- Calibration
264         memory_bus_calibration: bus_calibration
265         port map
266         (
267                 clk => clk_cpu,
268                 reset => reset,
269                 ce => calib_ce,
270                 address => address(1 downto 0),
271                 rd => i_rd,
272                 bls => i_bls,
273                 ta => calib_ta,
274                 data_in => data_in_bus,
275                 data_out => calib_out
276         );
277
278         -- Bus update
279         memory_bus_update: process(clk_cpu)
280         begin
281
282                 if clk_cpu = '1' and clk_cpu'event then
283
284                         -- Set every signal to inactive state here
285                         irc_reg_ce <= '1';
286                         bram_ce <= '1';
287                         bcd_ce <= '1';
288                         calib_ce <= '1';
289                         i_rd <= '1';
290                         i_bls <= (others => '1');
291                         data_in_bus <= (others => 'X');
292
293                         -- Check if we have chip select
294                         if cs0_xc = '0' then
295
296                                 -- Memory Map (16-bit address @ 32-bit each)
297
298                                 -- Each address is seen as 32-bit entry now
299                                 -- 0x0000 - 0x011F: Control dual-port BRAM
300                                 -- 0x8000 - 0x800F: IRC registers
301                                 -- 0xFFFB:          32-bit BCD
302                                 -- 0xFFFC - 0xFFFF: Calibration
303
304                                 if address < "0000000100100000" then -- Control BRAM
305                                         bram_ce <= '0';
306                                         i_ta <= bram_ta;
307                                         data_out_bus <= bram_out;
308                                 elsif address(15 downto 4) = "100000000000" then -- IRC
309                                         irc_reg_ce <= '0';
310                                         i_ta <= irc_reg_ta;
311                                         data_out_bus <= irc_reg_out;
312                                 elsif address = "1111111111111011" then -- BCD
313                                         bcd_ce <= '0';
314                                         i_ta <= bcd_ta;
315                                         data_out_bus <= bcd_out;
316                                 elsif address(15 downto 2) = "11111111111111" then -- Calibration
317                                         calib_ce <= '0';
318                                         i_ta <= calib_ta;
319                                         data_out_bus <= calib_out;
320                                 end if;
321
322                                 -- Reading
323                                 if rd = '0' then
324                                         if last_rd = '1' or last_address /= address then
325                                                 -- Getting something new
326                                                 -- Set internal RD to active and reset ack and latched data
327                                                 acked <= '0';
328                                                 i_rd <= '0';
329                                                 -- Data latching - synchronous
330                                                 data_read <= (others => 'X');
331                                         elsif i_rd = '0' and acked = '0' and i_ta = '0' then
332                                                 -- Got acknowledge, latch data
333                                                 acked <= '1';
334                                                 data_read <= data_out_bus;
335                                         elsif acked = '0' then
336                                                 -- Ongoing read, keep the signal low
337                                                 i_rd <= '0';
338                                                 data_read <= (others => 'X');
339                                         end if;
340
341                                         last_address <= address;
342                                 else
343                                         -- Not reading, anything goes
344                                         data_read <= (others => 'X');
345                                 end if;
346
347                                 last_rd <= rd;
348
349                                 -- Writing
350                                 if bls /= "1111" then
351                                         if last_bls /= bls or last_address /= address then
352                                                 -- Data are valid when BLS is active, broadcast it for one cycle
353                                                 i_bls <= bls;
354                                                 data_in_bus <= data_write;
355                                         end if;
356
357                                         last_address <= address;
358                                 end if;
359
360                                 last_bls <= bls;
361
362                         else
363
364                                 -- Set last read / bls to '1' if CS0 is not asserted
365                                 last_rd <= '1';
366                                 last_bls <= (others => '1');
367
368                         end if;
369
370                 end if;
371
372         end process;
373
374         -- If RD and BLS is not high, we must keep DATA at high impedance
375         -- or the FPGA collides with SDRAM (damaging each other)
376         memory_bus_out: process(cs0_xc, rd, data, data_read)
377         begin
378
379                 -- CS0 / RD / BLS are active LOW
380                 if cs0_xc = '0' and rd = '0' then
381                         data <= data_read;
382                 else
383                         -- IMPORTANT!!!
384                         data <= (others => 'Z');
385                 end if;
386
387                 data_write <= data;
388
389         end process;
390
391         -- Reset
392         initialization: process(init)
393         begin
394
395                 reset <= not init;
396
397         end process;
398
399 end Behavioral;
400