]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/lx-rocon.git/commitdiff
LX Master extended to allow send only each n-th receive done event.
authorPavel Pisa <ppisa@pikron.com>
Sun, 23 Nov 2014 15:14:58 +0000 (16:14 +0100)
committerPavel Pisa <ppisa@pikron.com>
Sun, 23 Nov 2014 15:14:58 +0000 (16:14 +0100)
Signed-off-by: Pavel Pisa <ppisa@pikron.com>
hw/bus_lxmaster.vhd
hw/cnt_div.vhd [new file with mode: 0644]
hw/lx_rocon_pkg.vhd
hw/lx_rocon_top.prj

index 931282cbc2f2ccc02b1ce69107de73249b910853..41a360635f0c7e26fe2c605e3d58a0ed6b310ace 100644 (file)
@@ -33,6 +33,8 @@ end bus_lxmaster;
 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);
@@ -70,7 +72,11 @@ architecture Behavioral of bus_lxmaster is
        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
@@ -116,7 +122,7 @@ master_receiver: lxmaster_receiver
                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,
@@ -130,11 +136,26 @@ master_receiver: lxmaster_receiver
                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';
@@ -156,6 +177,7 @@ wire_in:
                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
@@ -212,7 +234,7 @@ wire_in:
                                                        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';
@@ -228,6 +250,18 @@ wire_in:
                                                        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;
@@ -270,6 +304,18 @@ update:
                        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;
diff --git a/hw/cnt_div.vhd b/hw/cnt_div.vhd
new file mode 100644 (file)
index 0000000..79c4cce
--- /dev/null
@@ -0,0 +1,60 @@
+--
+-- * 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;
index 64821145b655875e15a33df7f9b611cf6518f8bc..3251cd66baf1495ff52e0c3d1e582273d0860596 100644 (file)
@@ -157,6 +157,21 @@ package lx_rocon_pkg is
   );
        end component;
 
+       -- Counter - divider
+       component cnt_div
+       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 component;
+
        -- LX Master transmitter
        component lxmaster_transmitter
        generic (
index ab24c6bb9c0cf7814ba7c039e4bc9ba8de87db63..3ae7f9dba8ca701fb973a8a651ea8acae0b8ffa3 100644 (file)
@@ -14,6 +14,7 @@ vhdl work "lx-rocon_tumbl/lx_rocon_gprf_abd.vhd"
 vhdl work "lx-rocon_tumbl/lx_rocon_dmem.vhd"
 vhdl work "irc_proc_inc.vhd"
 vhdl work "crc.vhd"
+vhdl work "cnt_div.vhd"
 vhdl work "measurement_register.vhd"
 vhdl work "lxmaster_transmitter.vhd"
 vhdl work "lxmaster_receiver.vhd"