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 -- Main unit in the IRC cooprocessor
9 -- This could be written as generic (n IRC axes)
11 entity irc_proc_main is
14 num_irc_g : positive := 4
20 reset_i : in std_logic;
22 irc_i : in IRC_COUNT_OUTPUT_Array_Type((num_irc_g-1) downto 0);
24 irc_index_reset_o : out std_logic_vector((num_irc_g-1) downto 0);
26 mem_clk_i : in std_logic;
27 mem_en_i : in std_logic;
28 mem_we_i : in std_logic_vector(3 downto 0);
29 mem_addr_i : in std_logic_vector(ceil_log2(num_irc_g) downto 0);
30 mem_data_i : in std_logic_vector(31 downto 0);
31 mem_data_o : out std_logic_vector(31 downto 0)
35 architecture Behavioral of irc_proc_main is
37 signal op_s : std_logic_vector(1 downto 0);
38 signal axis_s : std_logic_vector((ceil_log2(num_irc_g)-1) downto 0);
40 signal op_r : std_logic_vector(1 downto 0);
41 signal axis_r : std_logic_vector((ceil_log2(num_irc_g)-1) downto 0);
43 signal ram_en_s : std_logic;
44 signal ram_addr_s : std_logic_vector((mem_addr_i'length-1) downto 0);
45 signal ram_write_s : std_logic_vector(3 downto 0);
46 signal ram_data_i_s : std_logic_vector(31 downto 0);
47 signal ram_data_o_s : std_logic_vector(31 downto 0);
49 signal irc_reg_s : std_logic_vector(31 downto 0);
50 signal irc_reg_r : std_logic_vector(31 downto 0);
55 generic map (num_irc_g)
64 -- FIXME: Template needs to support 1-bit WE enabling, getting KEEP conflicts on wea here
65 ram: xilinx_dualport_bram
70 address_width => ram_addr_s'length,
71 port_a_type => READ_FIRST,
72 port_b_type => READ_FIRST
83 douta => ram_data_o_s,
95 ram_addr_s <= axis_s & op_s(1);
98 process (irc_i, irc_reg_r, op_r, axis_r, ram_data_o_s, reset_i)
99 variable skip_v : std_logic;
100 variable irc_v : IRC_COUNT_OUTPUT_Type;
101 variable res_v : std_logic_vector(31 downto 0);
102 variable count_v : std_logic_vector(31 downto 0);
103 variable src_v : std_logic_vector(31 downto 0);
106 -- Init (reset the index reset events)
107 irc_index_reset_o <= (others => '0');
109 ram_write_s <= "0000";
110 ram_data_i_s <= (others => '0');
111 irc_reg_s <= irc_reg_r;
113 count_v := (others => '0');
115 src_v := (others => '0');
118 if reset_i = '0' then
121 if op_r(1) = '0' then
123 irc_v := irc_i(to_integer(unsigned(axis_r)));
125 if op_r(0) = '0' then
126 count_v(7 downto 0) := irc_v.qcount;
128 src_v := ram_data_o_s;
129 irc_reg_s <= ram_data_o_s;
130 elsif irc_v.index_event = '1' then
131 irc_index_reset_o(to_integer(unsigned(axis_r))) <= '1';
132 count_v(7 downto 0) := irc_v.index;
140 res_v(7 downto 0) := std_logic_vector(unsigned(count_v(7 downto 0)) -
141 unsigned(src_v(7 downto 0)));
144 count_v(7 downto 0) := res_v(7 downto 0);
146 if res_v(7) = '1' then
147 count_v(31 downto 8) := (others => '1');
149 count_v(31 downto 8) := (others => '0');
153 res_v := std_logic_vector(unsigned(src_v) + unsigned(count_v));
157 ram_write_s <= "1111";
158 ram_data_i_s <= res_v;
163 -- Read next stored IRC
175 wait until clk_i'event and clk_i = '1';
179 if reset_i = '1' then
180 irc_reg_r <= (others => '0');
182 irc_reg_r <= irc_reg_s;