]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/lx-dad.git/blob - hw/lx_dad_top.vhd
36a3eb3e5b46182cc7b4272c8707a3b62b6e347e
[fpga/lx-cpu1/lx-dad.git] / hw / lx_dad_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 -- Disable next libraries for simulation in GHDL
8 --library unisim;
9 --use unisim.vcomponents.all;
10
11 use work.lx_dad_pkg.all;
12
13 -- lx_dad_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_dad_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                 init        : in std_logic;
41                 -- signal connected to external JK FF
42                 event_jk_j  : out std_logic
43         );
44 end lx_dad_top;
45
46 architecture Behavioral of lx_dad_top is
47
48         -- Reset signal
49         signal reset_s                  : std_logic;
50         signal init_s                   : std_logic;
51         -- Peripherals on the memory buses
52         -- Example memory
53         signal example_out_s            : std_logic_vector(31 downto 0);
54         signal example_ce_s             : std_logic;
55         -- Measurement (Master)
56         signal meas_out_s               : std_logic_vector(31 downto 0);
57         signal meas_ce_s                : std_logic;
58         -- Signals for external bus transmission
59         signal data_i_s                 : std_logic_vector(31 downto 0);
60         signal data_o_s                 : std_logic_vector(31 downto 0);
61         -- Signals for internal transaction
62         signal last_address_s           : std_logic_vector(15 downto 0);
63         signal next_last_address_s      : std_logic_vector(15 downto 0);
64         signal next_address_hold_s      : std_logic;
65         signal address_hold_s           : std_logic;
66         signal last_rd_s                : std_logic;
67         signal next_last_rd_s           : std_logic;
68         signal last_bls_s               : std_logic_vector(3 downto 0); -- prev bls_f_s (active 1)
69         signal next_last_bls_s          : std_logic_vector(3 downto 0);
70
71         -- Reading logic for Master CPU:
72         -- Broadcast rd only till ta (transaction acknowledge)
73         -- is received, then latch the data till the state of
74         -- rd or address changes
75         --
76         -- Data latching is synchronous - it's purpose is to
77         -- provide stable data for CPU on the bus
78         signal cs0_xc_f_s          : std_logic;
79         signal rd_f_s              : std_logic; -- Filtered RD
80         signal i_rd_s              : std_logic; -- Internal bus RD (active 1)
81         -- signal next_i_rd_s         : std_logic;
82         signal last_i_rd_s         : std_logic; -- Delayed RD bus, used for latching
83         signal next_last_i_rd_s    : std_logic;
84         signal i_rd_cycle2_s       : std_logic; -- Some internal subsystems provide
85         signal next_i_rd_cycle2_s  : std_logic; -- data only after 2 cycles
86         --
87         signal address_f_s         : std_logic_vector(15 downto 0); -- Filtered address
88         --
89         signal data_f_s            : std_logic_vector(31 downto 0); -- Filterred input data
90         --
91         signal data_read_s         : std_logic_vector(31 downto 0); -- Latched read data
92         signal next_data_read_s    : std_logic_vector(31 downto 0);
93
94         -- Writing logic:
95         signal bls_f_s             : std_logic_vector(3 downto 0); -- Filtered BLS (active 1)
96         signal i_bls_s             : std_logic_vector(3 downto 0); -- Internal BLS (active 1)
97         signal next_i_bls_s        : std_logic_vector(3 downto 0);
98         --
99         signal data_write_s        : std_logic_vector(31 downto 0); -- Data broadcasted to write
100         signal next_data_write_s   : std_logic_vector(31 downto 0);
101
102         -- signal s0   : std_logic;
103         -- signal s1   : std_logic;
104         -- signal s2   : std_logic;
105
106         -- XST attributes
107         attribute REGISTER_DUPLICATION : string;
108         attribute REGISTER_DUPLICATION of rd : signal is "NO";
109         attribute REGISTER_DUPLICATION of rd_f_s : signal is "NO";
110         attribute REGISTER_DUPLICATION of bls : signal is "NO";
111         attribute REGISTER_DUPLICATION of bls_f_s : signal is "NO";
112         attribute REGISTER_DUPLICATION of address : signal is "NO";
113         attribute REGISTER_DUPLICATION of address_f_s : signal is "NO";
114         attribute REGISTER_DUPLICATION of cs0_xc : signal is "NO";
115         attribute REGISTER_DUPLICATION of cs0_xc_f_s : signal is "NO";
116
117 begin
118
119 -- Example connection
120 memory_bus_example: bus_example
121         port map
122         (
123                 clk_i          => clk_50m,
124                 reset_i        => reset_s,
125                 ce_i           => example_ce_s,
126                 bls_i          => i_bls_s,
127                 address_i      => address_f_s(11 downto 0),
128                 data_i         => data_i_s,
129                 data_o         => example_out_s
130                 --
131                 --
132                 -- additional externally connected signals goes there
133         );
134
135 -- Measurement
136 memory_bus_measurement: bus_measurement
137         port map
138         (
139                 clk_i     => clk_50m,
140                 reset_i   => reset_s,
141                 ce_i      => meas_ce_s,
142                 address_i => address_f_s(1 downto 0),
143                 bls_i     => i_bls_s,
144                 data_i    => data_i_s,
145                 data_o    => meas_out_s
146         );
147
148 -- Reset
149 dff_reset: dff2
150         port map
151         (
152                 clk_i   => clk_50m,
153                 d_i     => init_s,
154                 q_o     => reset_s
155         );
156
157         -- Reset
158         init_s          <= not init;
159
160         -- Signalling
161         data_i_s        <= data_write_s;
162
163
164         event_jk_j <= '0';
165
166 -- Bus update
167 memory_bus_logic:
168         process(cs0_xc_f_s, rd_f_s, last_rd_s, i_rd_cycle2_s, last_i_rd_s,
169                 bls_f_s, last_bls_s, data_f_s, data_write_s,
170                 data_o_s, data_read_s, last_address_s, address_f_s)
171         begin
172                 -- Defaults
173                 next_i_rd_cycle2_s <= '0';
174                 next_address_hold_s <= '0';
175
176                 -- Check if we have chip select
177                 if cs0_xc_f_s = '1' then
178
179                         -- Reading
180                         if rd_f_s = '1' then
181                                 -- Internal read
182                                 if last_rd_s = '0' or (last_address_s /= address_f_s) then
183                                         i_rd_s <= '1';
184                                         next_i_rd_cycle2_s <= '1';
185                                         next_last_i_rd_s  <= '1';
186                                 elsif i_rd_cycle2_s = '1' then    -- FIXME it seems that some internal
187                                         i_rd_s <= '1';            -- peripherals demands 2 cycles to read
188                                         next_last_i_rd_s  <= '1';
189                                 else
190                                         i_rd_s            <= '0';
191                                         next_last_i_rd_s  <= '0';
192                                 end if;
193
194                                 if last_i_rd_s = '1' then
195                                         -- Latch data we just read - they are valid in this cycle
196                                         next_data_read_s <= data_o_s;
197                                 else
198                                         next_data_read_s <= data_read_s;
199                                 end if;
200                         else
201                         --      -- Not reading, anything goes
202                         --      data_read_s       <= (others => 'X');
203                                 next_data_read_s  <= data_read_s;
204                                 i_rd_s            <= '0';
205                                 next_last_i_rd_s  <= '0';
206                         end if;
207
208                         next_last_rd_s            <= rd_f_s;
209
210                         -- Data for write are captured only when BLS signals are stable
211                         if bls_f_s /= "0000" then
212                                 next_data_write_s <= data_f_s;
213                                 next_address_hold_s <= '1';
214                         else
215                                 next_data_write_s <= data_write_s;
216                         end if;
217
218                         if (bls_f_s /= "0000") or (rd_f_s = '1') then
219                                 next_last_address_s <= address_f_s;
220                         else
221                                 next_last_address_s <= last_address_s;
222                         end if;
223                 else
224                         next_last_rd_s <= '0';
225                         i_rd_s <= '0';
226                         next_last_i_rd_s <= '0';
227
228                         next_i_bls_s <= "0000";
229                         next_data_write_s <= data_write_s;
230                         next_data_read_s  <= data_read_s;
231                         next_last_address_s <= last_address_s;
232                 end if;
233
234                 -- Data for write are captured at/before BLS signals are negated
235                 -- and actual write cycle takes place exacly after BLS negation
236                 if ((last_bls_s and not bls_f_s) /= "0000") or
237                     ((last_bls_s /= "0000") and (cs0_xc_f_s = '0')) then
238                         next_i_bls_s <= last_bls_s;
239                         next_last_bls_s   <= "0000";
240                         next_address_hold_s <= '1';
241                 else
242                         next_i_bls_s <= "0000";
243                         if cs0_xc_f_s = '1' then
244                                 next_last_bls_s <= bls_f_s;
245                         else
246                                 next_last_bls_s <= "0000" ;
247                         end if;
248                 end if;
249
250         end process;
251
252 -- Bus update
253 memory_bus_update:
254         process
255         begin
256
257                 wait until clk_50m = '1' and clk_50m'event;
258
259                 address_hold_s <= next_address_hold_s;
260
261                 -- Synchronized external signals with main clock domain
262                 cs0_xc_f_s     <= not cs0_xc;
263                 bls_f_s        <= not bls;
264                 rd_f_s         <= not rd;
265                 data_f_s       <= data;
266                 if address_hold_s = '0' then
267                         address_f_s <= address;
268                 else
269                         address_f_s <= next_last_address_s;
270                 end if;
271
272                 -- Synchronoust state andvance to next period
273                 last_bls_s     <= next_last_bls_s;
274                 last_rd_s      <= next_last_rd_s;
275                 i_bls_s        <= next_i_bls_s;
276                 -- i_rd_s         <= next_i_rd_s;
277                 i_rd_cycle2_s  <= next_i_rd_cycle2_s;
278                 last_i_rd_s    <= next_last_i_rd_s;
279                 data_write_s   <= next_data_write_s;
280                 last_address_s <= next_last_address_s;
281                 data_read_s    <= next_data_read_s;
282
283         end process;
284
285 -- Do the actual wiring here
286 memory_bus_wiring:
287         process(cs0_xc_f_s, i_bls_s, address_f_s, example_out_s, meas_out_s)
288         begin
289
290                 -- Inactive by default
291                 example_ce_s           <= '0';
292                 meas_ce_s              <= '0';
293                 data_o_s               <= (others => '0');
294
295                 if cs0_xc_f_s = '1' or i_bls_s /= "0000" then
296
297                         -- Memory Map (16-bit address @ 32-bit each)
298
299                         -- Each address is seen as 32-bit entry now
300                         -- 0x0000 - 0x0FFF: Example memory
301                         -- 0x1FFC - 0x1FFF: Measurement
302                         -- 0x2000 - 0x8FFF: Free space
303
304                         if address_f_s < "0001000000000000" then                  -- Tumbl
305                                 example_ce_s           <= '1';
306                                 data_o_s               <= example_out_s;
307                         elsif address_f_s(15 downto 2) = "00011111111111" then    -- Measurement
308                                 meas_ce_s              <= '1';
309                                 data_o_s               <= meas_out_s;
310                         end if;
311
312                 end if;
313
314         end process;
315
316 -- If RD and BLS is not high, we must keep DATA at high impedance
317 -- or the FPGA collides with SDRAM (damaging each other)
318 memory_bus_out:
319         process(cs0_xc, rd, data_read_s)
320         begin
321
322                 -- CS0 / RD / BLS are active LOW
323                 if cs0_xc = '0' and rd = '0' then
324                         -- Don't risk flipping (between data_o_s and latched data_read_s, it's better to wait)
325                         -- Maybe check this later.
326                         -- if last_i_rd_s = '1' then
327                         --   data <= data_o_s;
328                         -- else
329                         data <= data_read_s;
330                         -- end if;
331                 else
332                         -- IMPORTANT!!!
333                         data <= (others => 'Z');
334                 end if;
335
336         end process;
337
338 end Behavioral;
339