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