-- LX Master (Transmitter)
entity lxmaster_transmitter is
+ generic (
+ cycle_cnt_width_g : natural := 12
+ );
port
(
clk_i : in std_logic;
register_i : in std_logic;
register_o : out std_logic_vector(1 downto 0);
register_we_i : in std_logic;
+ -- Cycle period
+ cycle_reg_i : in std_logic_vector(cycle_cnt_width_g-1 downto 0);
+ cycle_reg_o : out std_logic_vector(cycle_cnt_width_g-1 downto 0);
+ cycle_reg_we_i : in std_logic;
-- Watchdog
wdog_i : in std_logic;
wdog_we_i : in std_logic;
signal lxmaster_sync_last_bit_r : std_logic;
-- Counters
signal lxmaster_wdog_counter_s : natural range 0 to (wdog_length_c-1);
- signal lxmaster_frame_counter_s : natural range 0 to (frame_length_c-1);
+ signal lxmaster_frame_counter_s : natural range 0 to (2**cycle_cnt_width_g - 1);
+ signal lxmaster_cycle_limit_r : std_logic_vector(cycle_cnt_width_g-1 downto 0);
signal lxmaster_msg_counter_s : natural range 0 to (msg_max_count_c-1);
signal lxmaster_msg_counter_r : natural range 0 to (msg_max_count_c-1);
-- CRC
-- Bit 1: Watchdog not kicked (O)
signal lxmaster_register_in_s : std_logic;
signal lxmaster_register_out_s : std_logic_vector(1 downto 0);
+ -- Output buffers
+ signal sync_s : std_logic;
+ signal sync_r : std_logic;
+ signal mosi_s : std_logic;
+ signal mosi_r : std_logic;
begin
-- Directly route out some signals
clock_o <= clk_i; -- Cannot mix with logic
- sync_o <= not lxmaster_sync_r; -- Active in log. 0
- mosi_o <= '1' when lxmaster_sync_r = '0' and lxmaster_sync_last_bit_r = '0'
+ sync_s <= not lxmaster_sync_r; -- Active in log. 0
+ mosi_s <= '1' when lxmaster_sync_r = '0' and lxmaster_sync_last_bit_r = '0'
else lxmaster_crc_reg_r(0) when lxmaster_state_r = ST_CRC
else lxmaster_loaded_data_r(0);
+ sync_o <= sync_r;
+ mosi_o <= mosi_r;
+
-- CRC
lxmaster_crc_reg_s <= '0' & lxmaster_crc_reg_r(7 downto 1) when lxmaster_state_r = ST_CRC else lxmaster_crc_out_s;
lxmaster_crc_data_s <= '1' when lxmaster_state_r = ST_CRC else lxmaster_loaded_data_r(0);
lxmaster_crc_reset_s <= '1' when lxmaster_state_r /= ST_XFER or reset_i = '1' else '0';
- -- Register
+ -- Registers output
register_o <= lxmaster_register_out_s;
+ cycle_reg_o <= lxmaster_cycle_limit_r;
ram: xilinx_dualport_bram
generic map
end if;
when ST_END =>
- if lxmaster_frame_counter_s = (frame_length_c - 1) then
+ if lxmaster_frame_counter_s < 2 then
-- Initialize first step
lxmaster_state_s <= ST_INIT;
ram_addr_s <= lxmaster_register_in_s & x"00";
-- Increment counter
if reset_i = '1' then
- lxmaster_frame_counter_s <= (frame_length_c - 1);
+ lxmaster_frame_counter_s <= 1;
lxmaster_wdog_counter_s <= 0;
lxmaster_register_in_s <= '0';
lxmaster_register_out_s <= (others => '0');
lxmaster_last_word_r <= '1';
+ lxmaster_cycle_limit_r <= std_logic_vector(to_unsigned(frame_length_c,
+ lxmaster_cycle_limit_r'length));
else
lxmaster_register_in_s <= register_i;
end if;
- if lxmaster_frame_counter_s = (frame_length_c - 1) then
+ if lxmaster_frame_counter_s < 2 then
lxmaster_register_out_s(0) <= lxmaster_register_in_s;
- lxmaster_frame_counter_s <= 0;
+ lxmaster_frame_counter_s <= to_integer(unsigned(lxmaster_cycle_limit_r));
else
- lxmaster_frame_counter_s <= lxmaster_frame_counter_s + 1;
+ lxmaster_frame_counter_s <= lxmaster_frame_counter_s - 1;
end if;
if wdog_we_i = '1' and wdog_i = '1' then
lxmaster_register_out_s(1) <= '1';
end if;
+ if cycle_reg_we_i = '1' then
+ lxmaster_cycle_limit_r <= cycle_reg_i;
+ end if;
+
end if;
lxmaster_sync_r <= lxmaster_sync_s;
end process;
+update_outputs:
+ process
+ begin
+ wait until clk_i'event and clk_i = '0';
+
+ sync_r <= sync_s;
+ mosi_r <= mosi_s;
+ end process;
+
end Behavioral;