architecture Behavioral of bus_lxmaster is
+ constant cycle_cnt_width_c : natural := 12; -- number of bits
+
signal mem_trans_en_s : std_logic;
signal mem_trans_bls_s : std_logic_vector(1 downto 0);
signal mem_trans_addr_s : std_logic_vector(8 downto 0);
signal mem_recv_out_s : std_logic;
signal mem_recv_out_r : std_logic;
--
- signal state_o_s : std_logic_vector(1 downto 0);
- signal state_o_r : std_logic_vector(1 downto 0);
+ signal state_o_s : std_logic_vector(15 downto 0);
+ signal state_o_r : std_logic_vector(15 downto 0);
--
signal reset_reg_s : std_logic;
signal reset_reg_r : std_logic;
signal register_trans_in_s : std_logic;
signal register_trans_out_s : std_logic_vector(1 downto 0);
signal register_trans_wr_s : std_logic;
+ signal register_cycle_in_s : std_logic_vector(cycle_cnt_width_c-1 downto 0);
+ signal register_cycle_out_s : std_logic_vector(cycle_cnt_width_c-1 downto 0);
+ signal register_cycle_wr_s : std_logic;
signal wdog_trans_in_s : std_logic;
signal wdog_trans_wr_s : std_logic;
--
begin
master_transmitter: lxmaster_transmitter
+ generic map
+ (
+ cycle_cnt_width_g => cycle_cnt_width_c
+ )
port map
(
clk_i => clk_i,
register_i => register_trans_in_s,
register_o => register_trans_out_s,
register_we_i => register_trans_wr_s,
+ -- Cycle period
+ cycle_reg_i => register_cycle_in_s,
+ cycle_reg_o => register_cycle_out_s,
+ cycle_reg_we_i => register_cycle_wr_s,
-- Watchdog
wdog_i => wdog_trans_in_s,
wdog_we_i => wdog_trans_wr_s,
wire_in:
process(next_ce_i, ce_s, reset_reg_r, bls_i, address_i, mem_trans_data_s,
- mem_recv_data_s, data_i, register_trans_out_s, register_recv_out_s)
+ mem_recv_data_s, data_i, register_trans_out_s, register_recv_out_s, register_cycle_out_s)
begin
mem_trans_en_s <= '0';
reset_reg_wr_s <= '0';
register_trans_in_s <= '0';
register_trans_wr_s <= '0';
+ register_cycle_in_s <= (others => '0');
+ register_cycle_wr_s <= '0';
register_recv_in_s <= '0';
register_recv_wr_s <= '0';
wdog_trans_in_s <= '0';
-- Ugh, hack :-)
state_o_s(0) <= reset_reg_r;
state_o_s(1) <= '0';
+ state_o_s(15 downto 2) <= (others => '0');
end if;
elsif address_i(2 downto 0) = "001" then
-- LX Master register
register_trans_in_s <= data_i(0);
register_trans_wr_s <= '1';
else
- state_o_s <= register_trans_out_s;
+ state_o_s(1 downto 0) <= register_trans_out_s;
+ state_o_s(15 downto 2) <= (others => '0');
end if;
elsif address_i(2 downto 0) = "010" then
if bls_i(0) = '1' then
wdog_trans_in_s <= data_i(0);
wdog_trans_wr_s <= '1';
end if;
+ elsif address_i(2 downto 0) = "011" then
+ -- LX Master register
+ if bls_i(0) = '1' then
+ register_cycle_in_s <= data_i(cycle_cnt_width_c-1 downto 0);
+ register_cycle_wr_s <= '1';
+ else
+ state_o_s <= (15 downto cycle_cnt_width_c => '0') &
+ register_cycle_out_s;
+ end if;
elsif address_i(2 downto 0) = "100" then
if bls_i(0) = '1' then
register_recv_in_s <= data_i(0);
register_recv_wr_s <= '1';
else
- state_o_s <= register_recv_out_s;
+ state_o_s(1 downto 0) <= register_recv_out_s;
+ state_o_s(15 downto 2) <= (others => '0');
end if;
end if;
elsif mem_recv_out_r = '1' then
data_o <= mem_recv_data_s;
else
- data_o(1 downto 0) <= state_o_r;
+ data_o <= state_o_r;
end if;
end if;
-- 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
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;