2 use ieee.std_logic_1164.all;
3 use ieee.std_logic_unsigned.all;
4 use ieee.numeric_std.all;
7 use work.lx_rocon_pkg.all;
9 -- Main unit in the IRC cooprocessor
10 -- This could be written as generic (n IRC axes)
12 entity irc_proc_main is
15 num_irc_g : positive := 4
21 reset_i : in std_logic;
23 irc_i : in IRC_COUNT_OUTPUT_Array_Type((num_irc_g-1) downto 0);
25 irc_index_reset_o : out std_logic_vector((num_irc_g-1) downto 0);
27 mem_clk_i : in std_logic;
28 mem_en_i : in std_logic;
29 mem_we_i : in std_logic_vector(3 downto 0);
30 mem_addr_i : in std_logic_vector(ceil_log2(num_irc_g) downto 0);
31 mem_data_i : in std_logic_vector(31 downto 0);
32 mem_data_o : out std_logic_vector(31 downto 0)
36 architecture Behavioral of irc_proc_main is
38 signal op_s : std_logic_vector(1 downto 0);
39 signal axis_s : std_logic_vector((ceil_log2(num_irc_g)-1) downto 0);
41 signal op_r : std_logic_vector(1 downto 0);
42 signal axis_r : std_logic_vector((ceil_log2(num_irc_g)-1) downto 0);
44 signal ram_en_s : std_logic;
45 signal ram_addr_s : std_logic_vector((mem_addr_i'length-1) downto 0);
46 signal ram_write_s : std_logic_vector(3 downto 0);
47 signal ram_data_i_s : std_logic_vector(31 downto 0);
48 signal ram_data_o_s : std_logic_vector(31 downto 0);
50 signal irc_reg_s : std_logic_vector(31 downto 0);
51 signal irc_reg_r : std_logic_vector(31 downto 0);
56 generic map (num_irc_g)
65 -- FIXME: Template needs to support 1-bit WE enabling, getting KEEP conflicts on wea here
66 ram: xilinx_dualport_bram
71 address_width => ram_addr_s'length,
72 port_a_type => READ_FIRST,
73 port_b_type => READ_FIRST
84 douta => ram_data_o_s,
96 ram_addr_s <= axis_s & op_s(1);
99 process (irc_i, irc_reg_r, op_r, axis_r, ram_data_o_s, reset_i)
100 variable skip_v : std_logic;
101 variable irc_v : IRC_COUNT_OUTPUT_Type;
102 variable res_v : std_logic_vector(31 downto 0);
103 variable count_v : std_logic_vector(31 downto 0);
104 variable src_v : std_logic_vector(31 downto 0);
107 -- Init (reset the index reset events)
108 irc_index_reset_o <= (others => '0');
110 ram_write_s <= "0000";
111 ram_data_i_s <= (others => '0');
112 irc_reg_s <= irc_reg_r;
114 count_v := (others => '0');
116 src_v := (others => '0');
119 if reset_i = '0' then
122 if op_r(1) = '0' then
124 irc_v := irc_i(to_integer(unsigned(axis_r)));
126 if op_r(0) = '0' then
127 count_v(7 downto 0) := irc_v.qcount;
129 src_v := ram_data_o_s;
130 irc_reg_s <= ram_data_o_s;
131 elsif irc_v.index_event = '1' then
132 irc_index_reset_o(to_integer(unsigned(axis_r))) <= '1';
133 count_v(7 downto 0) := irc_v.index;
140 if count_v(7) = '1' then
141 count_v(31 downto 8) := (others => '1');
143 count_v(31 downto 8) := (others => '0');
147 ep_add32nc(count_v, not src_v, '1', res_v);
150 count_v(7 downto 0) := res_v(7 downto 0);
152 if res_v(7) = '1' then
153 count_v(31 downto 8) := (others => '1');
155 count_v(31 downto 8) := (others => '0');
159 ep_add32nc(src_v, count_v, '0', res_v);
163 ram_write_s <= "1111";
164 ram_data_i_s <= res_v;
169 -- Read next stored IRC
181 wait until clk_i'event and clk_i = '1';
185 if reset_i = '1' then
186 irc_reg_r <= (others => '0');
188 irc_reg_r <= irc_reg_s;