library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.numeric_std.all; use work.mbl_pkg.all; use work.util_pkg.all; use work.lx_rocon_pkg.all; -- Main unit in the IRC cooprocessor -- This could be written as generic (n IRC axes) -- >100 MHz entity irc_proc_main is generic ( num_irc_g : positive := 4 ); port ( -- Basic input clk_i : in std_logic; reset_i : in std_logic; -- Signals from IRC irc_i : in IRC_COUNT_OUTPUT_Array_Type((num_irc_g-1) downto 0); -- Index resetting irc_index_reset_o : out std_logic_vector((num_irc_g-1) downto 0); -- BRAM access mem_clk_i : in std_logic; mem_en_i : in std_logic; mem_we_i : in std_logic_vector(3 downto 0); mem_addr_i : in std_logic_vector(ceil_log2(num_irc_g) downto 0); mem_data_i : in std_logic_vector(31 downto 0); mem_data_o : out std_logic_vector(31 downto 0) ); end irc_proc_main; architecture Behavioral of irc_proc_main is signal op_s : std_logic_vector(1 downto 0); signal axis_s : std_logic_vector((ceil_log2(num_irc_g)-1) downto 0); -- signal op_r : std_logic_vector(1 downto 0); signal axis_r : std_logic_vector((ceil_log2(num_irc_g)-1) downto 0); -- signal ram_en_s : std_logic; signal ram_addr_s : std_logic_vector((mem_addr_i'length-1) downto 0); signal ram_write_s : std_logic_vector(3 downto 0); signal ram_data_i_s : std_logic_vector(31 downto 0); signal ram_data_o_s : std_logic_vector(31 downto 0); -- signal irc_reg_s : std_logic_vector(31 downto 0); signal irc_reg_r : std_logic_vector(31 downto 0); begin incr: irc_proc_inc generic map (num_irc_g) port map ( clk_i => clk_i, reset_i => reset_i, op_o => op_s, axis_o => axis_s ); -- FIXME: Template needs to support 1-bit WE enabling, getting KEEP conflicts on wea here ram: xilinx_dualport_bram generic map ( we_width => 4, byte_width => 8, address_width => ram_addr_s'length, port_a_type => READ_FIRST, port_b_type => READ_FIRST ) port map ( -- Internal clka => clk_i, rsta => reset_i, ena => ram_en_s, wea => ram_write_s, addra => ram_addr_s, dina => ram_data_i_s, douta => ram_data_o_s, -- External clkb => mem_clk_i, rstb => '0', enb => mem_en_i, web => mem_we_i, addrb => mem_addr_i, dinb => mem_data_i, doutb => mem_data_o ); -- RAM address ram_addr_s <= axis_s & op_s(1); update: process (irc_i, irc_reg_r, op_r, axis_r, ram_data_o_s, reset_i) variable skip_v : std_logic; variable irc_v : IRC_COUNT_OUTPUT_Type; variable res_v : std_logic_vector(31 downto 0); variable count_v : std_logic_vector(31 downto 0); variable src_v : std_logic_vector(31 downto 0); begin -- Init (reset the index reset events) irc_index_reset_o <= (others => '0'); ram_en_s <= '0'; ram_write_s <= "0000"; ram_data_i_s <= (others => '0'); irc_reg_s <= irc_reg_r; -- count_v := (others => '0'); skip_v := '1'; src_v := (others => '0'); -- No reset if reset_i = '0' then -- Caluclating step if op_r(1) = '0' then -- get source irc_v := irc_i(to_integer(unsigned(axis_r))); if op_r(0) = '0' then count_v(7 downto 0) := irc_v.qcount; skip_v := '0'; src_v := ram_data_o_s; irc_reg_s <= ram_data_o_s; elsif irc_v.index_event = '1' then irc_index_reset_o(to_integer(unsigned(axis_r))) <= '1'; count_v(7 downto 0) := irc_v.index; skip_v := '0'; src_v := irc_reg_r; end if; if skip_v = '0' then -- signed extension if count_v(7) = '1' then count_v(31 downto 8) := (others => '1'); else count_v(31 downto 8) := (others => '0'); end if; -- calculate qs8 ep_add32nc(count_v, not src_v, '1', res_v); -- extend it count_v(7 downto 0) := res_v(7 downto 0); if res_v(7) = '1' then count_v(31 downto 8) := (others => '1'); else count_v(31 downto 8) := (others => '0'); end if; -- add it back ep_add32nc(src_v, count_v, '0', res_v); -- store it ram_en_s <= '1'; ram_write_s <= "1111"; ram_data_i_s <= res_v; end if; end if; -- Read next stored IRC if op_r = "11" then ram_en_s <= '1'; end if; end if; end process; seq: process begin wait until clk_i'event and clk_i = '1'; op_r <= op_s; axis_r <= axis_s; if reset_i = '1' then irc_reg_r <= (others => '0'); else irc_reg_r <= irc_reg_s; end if; end process; end Behavioral;