architecture Behavioral of bus_lxmaster is
constant cycle_cnt_width_c : natural := 12; -- number of bits
+ constant rx_done_div_width_c : natural := 5; -- number of bits
+ constant rx_done_cnt_width_c : natural := 5; -- number of bits
signal mem_trans_en_s : std_logic;
signal mem_trans_bls_s : std_logic_vector(1 downto 0);
signal register_recv_in_s : std_logic;
signal register_recv_out_s : std_logic_vector(1 downto 0);
signal register_recv_wr_s : std_logic;
-
+ signal rx_done_s : std_logic;
+ signal rx_done_ratio_s : std_logic_vector(rx_done_div_width_c-1 downto 0);
+ signal rx_done_ratio_r : std_logic_vector(rx_done_div_width_c-1 downto 0);
+ signal rx_done_ratio_wr_s : std_logic;
+ signal rx_done_cnt_r : natural range 0 to (2**rx_done_cnt_width_c - 1);
begin
master_transmitter: lxmaster_transmitter
miso_i => miso_i,
sync_i => sync_i,
-- Receive done pulse
- rx_done_o => rx_done_o,
+ rx_done_o => rx_done_s,
-- Register
register_i => register_recv_in_s,
register_o => register_recv_out_s,
mem_data_o => mem_recv_data_s
);
+rx_done_divider : cnt_div
+ generic map (
+ cnt_width_g => rx_done_div_width_c
+ )
+ port map
+ (
+ clk_i => clk_i,
+ en_i => rx_done_s,
+ reset_i => reset_s,
+ ratio_i => rx_done_ratio_r,
+ q_out_o => rx_done_o
+ );
+
reset_s <= reset_reg_r or reset_i;
+
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, register_cycle_out_s)
+ mem_recv_data_s, data_i, register_trans_out_s, register_recv_out_s,
+ register_cycle_out_s, rx_done_ratio_r, rx_done_cnt_r)
begin
mem_trans_en_s <= '0';
register_recv_wr_s <= '0';
wdog_trans_in_s <= '0';
wdog_trans_wr_s <= '0';
+ rx_done_ratio_wr_s <= '0';
-- Incoming bus request
if next_ce_i = '1' then
wdog_trans_wr_s <= '1';
end if;
elsif address_i(2 downto 0) = "011" then
- -- LX Master register
+ -- LX Master period 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';
state_o_s(1 downto 0) <= register_recv_out_s;
state_o_s(15 downto 2) <= (others => '0');
end if;
+ elsif address_i(2 downto 0) = "101" then
+ -- LX Master receiver done divisor
+ if bls_i(0) = '1' then
+ rx_done_ratio_s <= data_i(rx_done_div_width_c + 8 - 1 downto 8);
+ rx_done_ratio_wr_s <= '1';
+ else
+ state_o_s(rx_done_cnt_width_c - 1 downto 0) <=
+ std_logic_vector(to_unsigned(rx_done_cnt_r, rx_done_cnt_width_c));
+ state_o_s(7 downto rx_done_cnt_width_c) <= (others => '0');
+ state_o_s(rx_done_div_width_c + 8 - 1 downto 8) <= rx_done_ratio_r;
+ state_o_s(15 downto rx_done_div_width_c + 8) <= (others => '0');
+ end if;
end if;
end if;
reset_reg_r <= reset_reg_s;
end if;
+ if reset_i = '1' then
+ rx_done_ratio_r <= ( 0 => '1', others => '0');
+ elsif rx_done_ratio_wr_s = '1' then
+ rx_done_ratio_r <= rx_done_ratio_s;
+ end if;
+
+ if reset_i = '1' then
+ rx_done_cnt_r <= 0;
+ elsif rx_done_s = '1' then
+ rx_done_cnt_r <= rx_done_cnt_r + 1;
+ end if;
+
end process;
end Behavioral;
--- /dev/null
+--
+-- * Counter - divider *
+--
+-- part of LXPWR motion control board (c) PiKRON Ltd
+-- idea by Pavel Pisa PiKRON Ltd <ppisa@pikron.com>
+--
+-- license: BSD
+--
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+entity cnt_div is
+ generic (
+ cnt_width_g : natural := 8
+ );
+ port
+ (
+ clk_i : in std_logic;
+ en_i : in std_logic;
+ reset_i : in std_logic;
+ ratio_i : in std_logic_vector(cnt_width_g-1 downto 0);
+ q_out_o : out std_logic
+ );
+end cnt_div;
+
+architecture behavioral of cnt_div is
+ signal cnt_val_s : natural range 0 to (2**cnt_width_g - 1);
+ signal cnt_val_r : natural range 0 to (2**cnt_width_g - 1);
+begin
+
+comb: process (reset_i, en_i, ratio_i, cnt_val_r)
+ begin
+ if reset_i = '1' then
+ cnt_val_s <= to_integer(unsigned(ratio_i));
+ q_out_o <= '0';
+ else
+ if en_i = '0' then
+ cnt_val_s <= cnt_val_r;
+ q_out_o <= '0';
+ else
+ if cnt_val_r <= 1 then
+ cnt_val_s <= to_integer(unsigned(ratio_i));
+ q_out_o <= '1';
+ else
+ cnt_val_s <= cnt_val_r - 1;
+ q_out_o <= '0';
+ end if;
+ end if;
+ end if;
+ end process;
+
+seq: process
+ begin
+ wait until clk_i'event and clk_i = '1';
+ cnt_val_r <= cnt_val_s;
+ end process;
+
+end behavioral;