2 use ieee.std_logic_1164.all;
3 use ieee.std_logic_unsigned.all;
4 use ieee.numeric_std.all;
6 use work.lx_rocon_pkg.all;
8 -- LX Master (Transmitter)
9 entity lxmaster_receiver is
13 reset_i : in std_logic;
15 clock_i : in std_logic;
16 miso_i : in std_logic;
17 sync_i : in std_logic;
19 rx_done_o : out std_logic;
20 rx_crc_error_o : out std_logic;
22 register_i : in std_logic;
23 register_o : out std_logic_vector(1 downto 0);
24 register_we_i : in std_logic;
26 mem_clk_i : in std_logic;
27 mem_en_i : in std_logic;
28 mem_we_i : in std_logic_vector(1 downto 0);
29 mem_addr_i : in std_logic_vector(8 downto 0);
30 mem_data_i : in std_logic_vector(15 downto 0);
31 mem_data_o : out std_logic_vector(15 downto 0)
33 end lxmaster_receiver;
35 architecture Behavioral of lxmaster_receiver is
38 type state_t is (ST_INIT, ST_READY, ST_XFER, ST_CRC, ST_END);
39 constant msg_max_count_c : positive := 8;
41 signal ram_en_s : std_logic;
42 signal ram_we_s : std_logic_vector(1 downto 0);
43 signal ram_rst_s : std_logic;
44 signal ram_addr_s : std_logic_vector(8 downto 0);
45 signal ram_addr_r : std_logic_vector(8 downto 0);
46 signal ram_data_o_s : std_logic_vector(15 downto 0);
47 signal ram_data_i_s : std_logic_vector(15 downto 0);
48 signal inc_ram_addr_s : std_logic;
49 signal inc_ram_addr_r : std_logic;
51 signal lxmaster_state_s : state_t;
52 signal lxmaster_state_r : state_t;
53 signal lxmaster_last_word_s : std_logic;
54 signal lxmaster_last_word_r : std_logic;
56 signal lxmaster_num_data_s : std_logic_vector(7 downto 0); -- If 0 then the peripheral is not active this cycle
57 signal lxmaster_num_data_r : std_logic_vector(7 downto 0);
58 signal lxmaster_data_counter_s : natural range 0 to 15;
59 signal lxmaster_data_counter_r : natural range 0 to 15;
61 signal lxmaster_frame_start_s : std_logic;
62 signal miso_s : std_logic;
63 signal sync_s : std_logic;
64 signal prev_sync_s : std_logic;
65 signal prev_sync_r : std_logic;
66 signal data_ready_s : std_logic;
67 signal received_data_s : std_logic_vector(15 downto 0);
68 signal received_data_r : std_logic_vector(15 downto 0);
70 signal lxmaster_msg_counter_s : natural range 0 to (msg_max_count_c-1);
71 signal lxmaster_msg_counter_r : natural range 0 to (msg_max_count_c-1);
73 signal lxmaster_crc_data_s : std_logic;
74 signal lxmaster_crc_reset_s : std_logic;
75 signal lxmaster_crc_out_s : std_logic_vector(7 downto 0);
76 signal lxmaster_crc_reg_s : std_logic_vector(7 downto 0);
77 signal lxmaster_crc_reg_r : std_logic_vector(7 downto 0);
79 signal lxmaster_crc_error_int_s : std_logic;
80 signal lxmaster_crc_error_int_r : std_logic;
81 signal lxmaster_crc_error_s : std_logic;
82 signal lxmaster_crc_error_r : std_logic;
84 signal rx_done_s : std_logic;
87 signal lxmaster_ram_reset_s : std_logic;
89 -- Bit 0: Transmitter - use first or second buffer (I/O)
90 signal lxmaster_register_in_s : std_logic;
91 signal lxmaster_register_out_s : std_logic_vector(1 downto 0);
95 -- Directly route out some signals
96 lxmaster_frame_start_s <= '1' when (sync_s = '1') and (prev_sync_r = '0') else '0';
99 lxmaster_crc_reg_s <= '0' & lxmaster_crc_reg_r(7 downto 1) when lxmaster_state_r = ST_CRC else lxmaster_crc_out_s;
100 lxmaster_crc_data_s <= received_data_r(received_data_r'length - 1);
101 lxmaster_crc_reset_s <= '1' when lxmaster_state_r /= ST_XFER or reset_i = '1' else '0';
102 rx_crc_error_o <= lxmaster_crc_error_r;
105 register_o <= lxmaster_register_out_s;
107 ram: xilinx_dualport_bram
113 port_a_type => WRITE_FIRST,
114 port_b_type => READ_FIRST
124 dina => ram_data_i_s,
125 douta => ram_data_o_s,
140 reset_i => lxmaster_crc_reset_s,
141 input_i => lxmaster_crc_data_s,
142 crc_o => lxmaster_crc_out_s
145 ram_rst_s <= reset_i or lxmaster_ram_reset_s;
147 crosdom_ser_fifo: lx_crosdom_ser_fifo
154 -- Asynchronous clock domain interface
155 acd_clock_i => clock_i,
156 acd_miso_i => miso_i,
157 acd_sync_i => sync_i,
161 -- Output synchronous with clk_i
164 data_ready_o => data_ready_s -- Not used for now
168 -- TODO: Maybe some exception handling (overflows etc.)
170 process (ram_data_o_s, ram_addr_r, inc_ram_addr_r, lxmaster_state_r, lxmaster_num_data_r, lxmaster_msg_counter_r,
171 lxmaster_last_word_r, lxmaster_data_counter_r, reset_i, lxmaster_frame_start_s, lxmaster_register_in_s,
172 sync_s, miso_s, prev_sync_r, received_data_r, lxmaster_crc_reg_r, lxmaster_crc_error_int_r,
173 lxmaster_crc_error_r)
174 variable ram_addr_v : std_logic_vector(8 downto 0);
175 variable crc_bit_mismatch_v : std_logic;
179 lxmaster_ram_reset_s <= '0';
181 -- Defaults of state variables (no change)
182 ram_addr_s <= ram_addr_r;
183 inc_ram_addr_s <= '0';
184 lxmaster_state_s <= lxmaster_state_r;
185 lxmaster_data_counter_s <= lxmaster_data_counter_r;
186 lxmaster_num_data_s <= lxmaster_num_data_r;
187 lxmaster_msg_counter_s <= lxmaster_msg_counter_r;
188 lxmaster_last_word_s <= lxmaster_last_word_r;
189 lxmaster_crc_error_int_s <= lxmaster_crc_error_int_r;
190 lxmaster_crc_error_s <= lxmaster_crc_error_r;
192 prev_sync_s <= sync_s;
195 ram_data_i_s <= received_data_r;
196 received_data_s <= miso_s & received_data_r(received_data_r'length - 1 downto 1);
198 if reset_i = '1' then
199 lxmaster_num_data_s <= x"00";
200 lxmaster_state_s <= ST_END;
201 lxmaster_last_word_s <= '0';
203 ram_addr_s <= '0' & x"00";
206 lxmaster_ram_reset_s <= '1';
207 lxmaster_crc_error_s <= '0';
211 -- OK, we are enabled, default values
212 ram_en_s <= '0'; -- Not reading
214 case lxmaster_state_r is
217 -- We just read number of commands
218 if ram_data_o_s(7 downto 0) = x"00" then
219 lxmaster_state_s <= ST_END; --Nothing
222 lxmaster_state_s <= ST_READY; -- Make next read init the transfer
223 ram_addr_v := ram_addr_r(8) & ram_data_o_s(15 downto 8); -- Update address
224 ram_addr_s <= ram_addr_v;
225 lxmaster_num_data_s <= std_logic_vector(unsigned(ram_addr_v(7 downto 0)) + unsigned(ram_data_o_s(7 downto 0)));
226 ram_en_s <= '1'; -- Read
229 -- Prepare message counter
230 lxmaster_msg_counter_s <= 0;
232 lxmaster_crc_error_int_s <= '0';
235 -- We are ready to begin transferring
236 lxmaster_data_counter_s <= 0; -- Reset counter
237 lxmaster_state_s <= ST_XFER; --Go to transfer loop
241 if inc_ram_addr_r = '1' then
242 -- Update address if second and other loop
243 ram_addr_s <= ram_addr_r(8) & (ram_addr_r(7 downto 0) + 1);
246 if lxmaster_data_counter_r = 14 then
247 lxmaster_data_counter_s <= lxmaster_data_counter_r + 1; -- Increment
249 if (ram_addr_r(7 downto 0) + 1) /= lxmaster_num_data_r then
250 lxmaster_last_word_s <= '0';
252 lxmaster_last_word_s <= '1';
255 elsif lxmaster_data_counter_r = 15 then
256 -- At 15th bit, we either stop if ram_addr_r equals lxmaster_num_data_r
257 if lxmaster_last_word_r = '1' then
258 lxmaster_state_s <= ST_CRC;
259 lxmaster_data_counter_s <= 0;
261 lxmaster_data_counter_s <= 0;
266 inc_ram_addr_s <= '1';
269 lxmaster_data_counter_s <= lxmaster_data_counter_r + 1;
274 if received_data_r(received_data_r'length - 1) /= lxmaster_crc_reg_r(0) then
275 crc_bit_mismatch_v := '1';
277 crc_bit_mismatch_v := '0';
280 if crc_bit_mismatch_v = '1' then
281 lxmaster_crc_error_int_s <= '1';
284 -- Check if this is last command, first read one more
285 if lxmaster_data_counter_r = 0 then
286 if lxmaster_msg_counter_r = (msg_max_count_c - 1) then
287 lxmaster_ram_reset_s <= '1'; -- Make sure we read 0 if we are on the last message
289 lxmaster_msg_counter_s <= lxmaster_msg_counter_r + 1;
292 ram_addr_s <= ram_addr_r(8) & std_logic_vector(to_unsigned(lxmaster_msg_counter_r + 1, ram_addr_r'length - 1)); -- Update address
293 ram_en_s <= '1'; -- Read
295 elsif lxmaster_data_counter_r = 1 then
297 if ram_data_o_s(15 downto 8) >= msg_max_count_c then -- Need to read first command, make sure it's valid
298 ram_addr_v := ram_addr_r(8) & ram_data_o_s(15 downto 8); -- Update address
299 ram_addr_s <= ram_addr_v;
300 lxmaster_num_data_s <= std_logic_vector(unsigned(ram_addr_v(7 downto 0)) + unsigned(ram_data_o_s(7 downto 0)));
301 ram_en_s <= '1'; -- Read
303 lxmaster_num_data_s <= x"00"; -- Signalize termination
308 if lxmaster_data_counter_r = 7 then -- Ending
309 lxmaster_data_counter_s <= 0;
311 if lxmaster_num_data_r = x"00" then
312 lxmaster_state_s <= ST_END; -- Last command
314 lxmaster_crc_error_s <= lxmaster_crc_error_int_r or crc_bit_mismatch_v;
316 -- Begin transmission of next data
317 lxmaster_data_counter_s <= 0; -- Reset counter
318 lxmaster_state_s <= ST_XFER; --Go to transfer loop
322 lxmaster_data_counter_s <= lxmaster_data_counter_r + 1; -- Increment
326 if lxmaster_frame_start_s = '1' then
327 -- Initialize first step
328 lxmaster_state_s <= ST_INIT;
329 ram_addr_s <= lxmaster_register_in_s & x"00";
339 -- This function toggles outputs directly, make sure the outputs
340 -- are updated with clock to minimize phase.
345 wait until clk_i'event and clk_i = '1';
348 ram_addr_r <= ram_addr_s;
349 inc_ram_addr_r <= inc_ram_addr_s;
350 lxmaster_state_r <= lxmaster_state_s;
351 lxmaster_data_counter_r <= lxmaster_data_counter_s;
352 lxmaster_num_data_r <= lxmaster_num_data_s;
353 lxmaster_crc_reg_r <= lxmaster_crc_reg_s;
354 lxmaster_msg_counter_r <= lxmaster_msg_counter_s;
355 lxmaster_last_word_r <= lxmaster_last_word_s;
356 lxmaster_crc_error_int_r <= lxmaster_crc_error_int_s;
357 lxmaster_crc_error_r <= lxmaster_crc_error_s;
359 rx_done_o <= rx_done_s;
362 if reset_i = '1' then
364 lxmaster_register_in_s <= '0';
365 lxmaster_register_out_s <= (others => '0');
366 lxmaster_last_word_r <= '1';
370 if register_we_i = '1' then
371 lxmaster_register_in_s <= register_i;
374 if lxmaster_frame_start_s = '1' then
375 lxmaster_register_out_s(0) <= lxmaster_register_in_s;
378 if lxmaster_state_s = ST_END then
379 lxmaster_register_out_s(1) <= '0';
381 lxmaster_register_out_s(1) <= '1';
385 prev_sync_r <= prev_sync_s;
386 received_data_r <= received_data_s;