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);
61 -- FIXME: Template needs to support 1-bit WE enabling, getting KEEP conflicts on wea here
62 ram: xilinx_dualport_bram_no_change
67 address_width => ram_addr_s'length
78 douta => ram_data_o_s,
90 ram_addr_s <= axis_s & op_s(1);
93 process (irc_i, op_r, axis_r, ram_data_o_s, reset_i)
94 variable skip_v : std_logic;
95 variable irc_v : IRC_COUNT_OUTPUT_Type;
96 variable res_v : std_logic_vector(31 downto 0);
97 variable count_v : std_logic_vector(31 downto 0);
100 -- Init (reset the index reset events)
101 irc_index_reset_o <= (others => '0');
103 ram_write_s <= "0000";
104 ram_data_i_s <= (others => '0');
106 count_v := (others => '0');
110 if reset_i = '0' then
113 if op_r(1) = '0' then
115 irc_v := irc_i(to_integer(unsigned(axis_r)));
117 if op_r(0) = '0' then
118 count_v(7 downto 0) := irc_v.qcount;
121 if irc_v.index_event = '1' then
122 irc_index_reset_o(to_integer(unsigned(axis_r))) <= '1';
123 count_v(7 downto 0) := irc_v.index;
130 if count_v(7) = '1' then
131 count_v(31 downto 8) := (others => '1');
133 count_v(31 downto 8) := (others => '0');
137 ep_add32nc(count_v, not ram_data_o_s, '1', res_v);
140 count_v(7 downto 0) := res_v(7 downto 0);
142 if res_v(7) = '1' then
143 count_v(31 downto 8) := (others => '1');
145 count_v(31 downto 8) := (others => '0');
149 ep_add32nc(ram_data_o_s, count_v, '0', res_v);
153 ram_write_s <= "1111";
154 ram_data_i_s <= res_v;
159 -- Read next stored IRC
171 wait until clk_i'event and clk_i = '1';