]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/lx-dad.git/blob - hw/lx_dad_top.vhd
fixed FPGA buggs, added support for single shot measurement (fpga does 2 measurements...
[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                 -- signals to image sensor
42                 phi1        : out std_logic;
43                 phi2        : out std_logic;
44                 phi_rst     : out std_logic;
45                 LED_1       : out std_logic;
46                 sck_o           : out std_logic;
47                 cnv_o           : out std_logic;
48                 phist           : out std_logic;
49                 sck_i           : in std_logic;
50                 SDI             : in std_logic
51                 
52         );
53 end lx_dad_top;
54
55 architecture Behavioral of lx_dad_top is
56
57         -- Reset signal
58         signal reset_s                  : std_logic;
59         signal init_s                   : std_logic;
60         -- Peripherals on the memory buses
61         -- Example memory
62         signal example_out_s            : std_logic_vector(31 downto 0);
63         signal example_ce_s             : std_logic;
64         -- Measurement (Master)
65         signal meas_out_s               : std_logic_vector(31 downto 0);
66         signal meas_ce_s                : std_logic;
67         -- Sensor timing
68         signal sensor_ce_s                              : std_logic;
69         signal sensor_out_s                     : std_logic_vector(31 downto 0);
70         -- sensor memory if
71         signal sens_mem_ce_s                    : std_logic;
72         signal sens_mem_out_s                   : std_logic_vector(31 downto 0);
73         
74         signal sens_adr_s                       : std_logic_vector(10 downto 0);
75         signal sens_data_s                      : std_logic_vector(31 downto 0);
76         signal sens_i_bls_s                     : std_logic_vector(3 downto 0);
77         signal sens_mem_int_ce_s        : std_logic;
78         
79         -- Signals for external bus transmission
80         signal data_i_s                 : std_logic_vector(31 downto 0);
81         signal data_o_s                 : std_logic_vector(31 downto 0);
82         -- Signals for internal transaction
83         signal last_address_s           : std_logic_vector(15 downto 0);
84         signal next_last_address_s              : std_logic_vector(15 downto 0);
85         signal next_address_hold_s              : std_logic;
86         signal address_hold_s           : std_logic;
87         signal last_rd_s                : std_logic;
88         signal next_last_rd_s           : std_logic;
89         signal last_bls_s               : std_logic_vector(3 downto 0); -- prev bls_f_s (active 1)
90         signal next_last_bls_s          : std_logic_vector(3 downto 0);
91
92         -- Reading logic for Master CPU:
93         -- Broadcast rd only till ta (transaction acknowledge)
94         -- is received, then latch the data till the state of
95         -- rd or address changes
96         --
97         -- Data latching is synchronous - it's purpose is to
98         -- provide stable data for CPU on the bus
99         signal cs0_xc_f_s          : std_logic;
100         signal rd_f_s              : std_logic; -- Filtered RD
101         signal i_rd_s              : std_logic; -- Internal bus RD (active 1)
102         signal next_last_i_rd_s    : std_logic;
103         signal last_i_rd_s         : std_logic; -- Delayed RD bus, used for latching
104         --
105         signal address_f_s         : std_logic_vector(15 downto 0); -- Filtered address
106         --
107         signal data_f_s            : std_logic_vector(31 downto 0); -- Filterred input data
108         --
109         signal data_read_s         : std_logic_vector(31 downto 0); -- Latched read data
110         signal next_data_read_s    : std_logic_vector(31 downto 0);
111
112         -- Writing logic:
113         signal bls_f_s             : std_logic_vector(3 downto 0); -- Filtered BLS (active 1)
114         signal i_bls_s             : std_logic_vector(3 downto 0); -- Internal BLS (active 1)
115         signal next_i_bls_s        : std_logic_vector(3 downto 0);
116         --
117         signal data_write_s        : std_logic_vector(31 downto 0); -- Data broadcasted to write
118         signal next_data_write_s   : std_logic_vector(31 downto 0);
119
120         -- signal s0   : std_logic;
121         -- signal s1   : std_logic;
122         -- signal s2   : std_logic;
123
124         -- XST attributes
125         attribute REGISTER_DUPLICATION : string;
126         attribute REGISTER_DUPLICATION of rd : signal is "NO";
127         attribute REGISTER_DUPLICATION of rd_f_s : signal is "NO";
128         attribute REGISTER_DUPLICATION of bls : signal is "NO";
129         attribute REGISTER_DUPLICATION of bls_f_s : signal is "NO";
130         attribute REGISTER_DUPLICATION of address : signal is "NO";
131         attribute REGISTER_DUPLICATION of address_f_s : signal is "NO";
132         attribute REGISTER_DUPLICATION of cs0_xc : signal is "NO";
133         attribute REGISTER_DUPLICATION of cs0_xc_f_s : signal is "NO";
134
135 begin
136
137 -- Example connection
138 memory_bus_example: bus_example
139         port map
140         (
141                 clk_i          => clk_50m,
142                 reset_i        => reset_s,
143                 ce_i           => example_ce_s,
144                 bls_i          => i_bls_s,
145                 address_i      => address_f_s(11 downto 0),
146                 data_i         => data_i_s,
147                 data_o         => example_out_s
148                 --
149                 --
150                 -- additional externally connected signals goes there
151         );
152
153
154 --Sensor clock generator
155 mytest: clockgen
156         port map
157         (
158                 clk_i   => clk_50m,
159                 reset_i => reset_s,
160                 sck_i   => sck_i,
161                 SDI     => SDI,
162                 phi_st  => phist,
163                 phi_1   => phi1,
164                 phi_2   => phi2,
165                 ph_rst  => phi_rst,
166                 --LED   => LED_1,
167                 sck_o   => sck_o,
168                 cnv_o   => cnv_o,
169                 mem_o   => sens_data_s,
170                 addr_o  => sens_adr_s,
171                 bls_o   => sens_i_bls_s,
172                 ce_o    => sens_mem_int_ce_s,
173                 addr_i  => address_f_s(3 downto 0),
174                 data_i  => data_i_s,
175                 ce_i    => sensor_ce_s,
176                 bls_i   => i_bls_s,
177                 data_o  => sensor_out_s
178                 
179         );
180         
181 --sensor memory connection
182 memory_bus_sensormem: bus_sensor
183         port map
184         (
185                 clk_i           => clk_50m,
186                 ce_i            => sens_mem_ce_s,
187                 reset_i         => reset_s,
188                 --led           => LED_1,
189                 bls_i           => i_bls_s,
190                 address_i       => address_f_s(10 downto 0),
191                 data_i          => data_i_s,
192                 data_o          => sens_mem_out_s,
193                 ce_a_i          => sens_mem_int_ce_s,
194                 adr_a_i         => sens_adr_s,
195                 bls_a_i         => sens_i_bls_s,
196                 dat_a_i         => sens_data_s
197                 );
198
199 -- Measurement
200 memory_bus_measurement: bus_measurement
201         port map
202         (
203                 clk_i     => clk_50m,
204                 reset_i   => reset_s,
205                 ce_i      => meas_ce_s,
206                 address_i => address_f_s(1 downto 0),
207                 bls_i     => i_bls_s,
208                 data_i    => data_i_s,
209                 data_o    => meas_out_s
210         );
211
212 -- Reset
213 dff_reset: dff2
214         port map
215         (
216                 clk_i   => clk_50m,
217                 d_i     => init_s,
218                 q_o     => reset_s
219         );
220
221         -- Reset
222         init_s          <= not init;
223
224         -- Signalling
225         data_i_s        <= data_write_s;
226
227
228         event_jk_j <= '0';
229
230 -- Bus update
231 memory_bus_logic:
232         process(cs0_xc_f_s, rd_f_s, last_rd_s, last_i_rd_s,
233                 bls_f_s, last_bls_s, data_f_s, data_write_s,
234                 data_o_s, data_read_s, last_address_s, address_f_s)
235         begin
236                 -- Defaults
237                 next_address_hold_s <= '0';
238
239                 -- Check if we have chip select
240                 if cs0_xc_f_s = '1' then
241
242                         -- Reading
243                         if rd_f_s = '1' then
244                                 -- Internal read
245                                 if last_rd_s = '0' or (last_address_s /= address_f_s) then
246                                         i_rd_s <= '1';
247                                         next_last_i_rd_s  <= '1';
248                                 else
249                                         i_rd_s <= '0';
250                                         next_last_i_rd_s  <= '0';
251                                 end if;
252
253                                 if last_i_rd_s = '1' then
254                                         -- Latch data we just read - they are valid in this cycle
255                                         next_data_read_s <= data_o_s;
256                                 else
257                                         next_data_read_s <= data_read_s;
258                                 end if;
259                         else
260                         --      -- Not reading, anything goes
261                         --      data_read_s       <= (others => 'X');
262                                 next_data_read_s  <= data_read_s;
263                                 i_rd_s            <= '0';
264                                 next_last_i_rd_s  <= '0';
265                         end if;
266
267                         next_last_rd_s            <= rd_f_s;
268
269                         -- Data for write are captured only when BLS signals are stable
270                         if bls_f_s /= "0000" then
271                                 next_data_write_s <= data_f_s;
272                                 next_address_hold_s <= '1';
273                         else
274                                 next_data_write_s <= data_write_s;
275                         end if;
276
277                         if (bls_f_s /= "0000") or (rd_f_s = '1') then
278                                 next_last_address_s <= address_f_s;
279                         else
280                                 next_last_address_s <= last_address_s;
281                         end if;
282                 else
283                         next_last_rd_s <= '0';
284                         i_rd_s <= '0';
285                         next_last_i_rd_s <= '0';
286
287                         next_i_bls_s <= "0000";
288                         next_data_write_s <= data_write_s;
289                         next_data_read_s  <= data_read_s;
290                         next_last_address_s <= last_address_s;
291                 end if;
292
293                 -- Data for write are captured at/before BLS signals are negated
294                 -- and actual write cycle takes place exacly after BLS negation
295                 if ((last_bls_s and not bls_f_s) /= "0000") or
296                     ((last_bls_s /= "0000") and (cs0_xc_f_s = '0')) then
297                         next_i_bls_s <= last_bls_s;
298                         next_last_bls_s   <= "0000";
299                         next_address_hold_s <= '1';
300                 else
301                         next_i_bls_s <= "0000";
302                         if cs0_xc_f_s = '1' then
303                                 next_last_bls_s <= bls_f_s;
304                         else
305                                 next_last_bls_s <= "0000" ;
306                         end if;
307                 end if;
308
309         end process;
310
311 -- Bus update
312 memory_bus_update:
313         process
314         begin
315
316                 wait until clk_50m = '1' and clk_50m'event;
317
318                 address_hold_s <= next_address_hold_s;
319
320                 -- Synchronized external signals with main clock domain
321                 cs0_xc_f_s     <= not cs0_xc;
322                 bls_f_s        <= not bls;
323                 rd_f_s         <= not rd;
324                 data_f_s       <= data;
325                 if address_hold_s = '0' then
326                         address_f_s <= address;
327                 else
328                         address_f_s <= next_last_address_s;
329                 end if;
330
331                 -- Synchronoust state andvance to next period
332                 last_bls_s     <= next_last_bls_s;
333                 last_rd_s      <= next_last_rd_s;
334                 i_bls_s        <= next_i_bls_s;
335                 last_i_rd_s    <= next_last_i_rd_s;
336                 data_write_s   <= next_data_write_s;
337                 last_address_s <= next_last_address_s;
338                 data_read_s    <= next_data_read_s;
339
340         end process;
341
342 -- Do the actual wiring here
343 memory_bus_wiring:
344         process(cs0_xc_f_s, i_bls_s, address_f_s, example_out_s, meas_out_s, sensor_out_s, sens_mem_out_s, i_rd_s, last_i_rd_s)
345         begin
346
347                 -- Inactive by default
348                 example_ce_s           <= '0';
349                 meas_ce_s              <= '0';
350                 sensor_ce_s            <= '0';
351                 sens_mem_ce_s           <= '0';
352                 data_o_s               <= (others => '0');
353
354                 if i_rd_s = '1' or i_bls_s /= "0000" then
355
356                         -- Memory Map (16-bit address @ 32-bit each)
357
358                         -- Each address is seen as 32-bit entry now
359                         -- 0x0000 - 0x0FFF: Example memory
360                         -- 0x1000 - 0x100F: Sensor timing
361                         -- 0x1FFC - 0x1FFF: Measurement
362                         -- 0x2000 - 0x3FFF: sensor memory
363                         -- 0x4000 - 0x8FFF: Free space
364
365                         if address_f_s < "0001000000000000" then                  -- Tumbl
366                                 example_ce_s           <= '1';
367                         elsif address_f_s(15 downto 4) = "000100000000" then   -- Sensor timing
368                                 sensor_ce_s            <= '1';
369                         elsif address_f_s(15 downto 2) = "00011111111111" then    -- Measurement
370                                 meas_ce_s              <= '1';
371                         elsif address_f_s > "0001111111111111" and address_f_s < "0100000000000000" then  -- sensor data
372                                 sens_mem_ce_s                           <= '1';
373                         end if;
374
375                 end if;
376
377                 if last_i_rd_s = '1' then
378                         if address_f_s < "0001000000000000" then                  -- Tumbl
379                                 data_o_s               <= example_out_s;
380                         elsif address_f_s(15 downto 2) = "00011111111111" then    -- Measurement
381                                 data_o_s               <= meas_out_s;
382                         elsif address_f_s(15 downto 4) = "000100000000" then   -- Sensor timing
383                                 data_o_s                   <= sensor_out_s;
384                         elsif address_f_s > "0001111111111111" and address_f_s < "0100000000000000" then  -- sensor data
385                                 data_o_s                       <= sens_mem_out_s;
386                         end if;
387                 end if;
388
389         end process;
390
391 -- If RD and BLS is not high, we must keep DATA at high impedance
392 -- or the FPGA collides with SDRAM (damaging each other)
393 memory_bus_out:
394         process(cs0_xc, rd, data_read_s)
395         begin
396
397                 -- CS0 / RD / BLS are active LOW
398                 if cs0_xc = '0' and rd = '0' then
399                         -- Don't risk flipping (between data_o_s and latched data_read_s, it's better to wait)
400                         -- Maybe check this later.
401                         -- if last_i_rd_s = '1' then
402                         --   data <= data_o_s;
403                         -- else
404                         data <= data_read_s;
405                         -- end if;
406                 else
407                         -- IMPORTANT!!!
408                         data <= (others => 'Z');
409                 end if;
410
411         end process;
412
413 end Behavioral;
414