diff --git a/modules/wishbone/wb_irq/Manifest.py b/modules/wishbone/wb_irq/Manifest.py index b15bda403dadb78960400fb7854ed03b518a487d..894c10ac7d75d957fae46203b6ef823f1f0fff18 100644 --- a/modules/wishbone/wb_irq/Manifest.py +++ b/modules/wishbone/wb_irq/Manifest.py @@ -1,4 +1,6 @@ -files = ["wb_irq_lm32.vhd", +files = ["wb_irq_timer.vhd", + "irqm_core.vhd", + "wb_irq_lm32.vhd", "wb_irq_slave.vhd", "wb_irq_master.vhd", "wb_irq_pkg.vhd"] diff --git a/modules/wishbone/wb_irq/irqm_core.vhd b/modules/wishbone/wb_irq/irqm_core.vhd index 221db3043d570c1ee7276e5f252627713e007487..e706eb62382a5201675a2a38f0130d80020d7915 100644 --- a/modules/wishbone/wb_irq/irqm_core.vhd +++ b/modules/wishbone/wb_irq/irqm_core.vhd @@ -8,9 +8,12 @@ use work.genram_pkg.all; use work.wb_irq_pkg.all; entity irqm_core is -generic( g_channels : natural := 32; -- number of interrupt lines - g_round_rb : boolean := true; -- scheduler true: round robin, false: prioritised - g_det_edge : boolean := true -- edge detection. true: trigger on rising edge of irq lines, false: trigger on high level +generic( g_channels : natural := 32; -- number of interrupt lines + g_round_rb : boolean := true; -- scheduler true: round robin, false: prioritised + g_det_edge : boolean := true; -- edge detection. true: trigger on rising edge of irq lines, false: trigger on high level + g_has_dev_id : boolean := false; -- if set, dst adr bits 15..8 hold g_dev_id as device identifier + g_dev_id : std_logic_vector(4 downto 0) := (others => '0'); -- device identifier + g_default_msg : boolean := true -- initialises msgs to a default value in order to detect uninitialised irq master ); port (clk_i : std_logic; -- clock rst_n_i : std_logic; -- reset, active LO @@ -140,22 +143,33 @@ irq_master_o.we <= '1'; -- send pending MSI IRQs over WB wb_irq_master : process(clk_i) variable v_state : t_state; - variable v_ID : std_logic_vector(6 downto 0); + variable v_dst : std_logic_vector(31 downto 0); begin + if rising_edge(clk_i) then if(rst_n_i = '0') then irq_master_o.cyc <= '0'; irq_master_o.stb <= '0'; r_state <= st_IDLE; - else + v_dst := (others => '0'); + else v_state := r_state; r_wb_sending <= '0'; - case r_state is + + case r_state is when st_IDLE => if(s_wb_send = '1') then v_state := st_SEND; - v_ID := std_logic_vector(to_unsigned(idx, 5)) & "00"; - irq_master_o.adr <= s_dst(idx)(31 downto 7) & v_ID; + + v_dst(6 downto 2) := std_logic_vector(to_unsigned(idx, 5)); + if(g_has_dev_id) then + v_dst(15 downto 8) := g_dev_id; + v_dst(31 downto 16) := s_dst(idx)(31 downto 16); + else + v_dst(31 downto 7) := s_dst(idx)(31 downto 7); + end if; + + irq_master_o.adr <= v_dst; irq_master_o.dat <= s_msg(idx); r_wb_sending <= '1'; end if; diff --git a/modules/wishbone/wb_irq/wb_irq_master.vhd b/modules/wishbone/wb_irq/wb_irq_master.vhd index 168240b747276465266767c59b147bd25da437bd..90eb2f4ed4ea9c64fd1e03cbbfede5d2e3df67da 100644 --- a/modules/wishbone/wb_irq/wb_irq_master.vhd +++ b/modules/wishbone/wb_irq/wb_irq_master.vhd @@ -1,3 +1,31 @@ +------------------------------------------------------------------------------ +-- Title : WB Timer Interrupt +-- Project : Wishbone +------------------------------------------------------------------------------ +-- File : wb_irq_timer.vhd +-- Author : Mathias Kreider +-- Company : GSI +-- Created : 2013-08-10 +-- Last update: 2013-08-10 +-- Platform : FPGA-generic +-- Standard : VHDL'93 +------------------------------------------------------------------------------- +-- Description: Programmable Timer interrupt module (MSI) +------------------------------------------------------------------------------- +-- Copyright (c) 2013 GSI +------------------------------------------------------------------------------- +-- +-- +-- +-- 31 16 6 0 +-- Dst.............SrcID....ChID... +-- ************************* +-- +-- Revisions : +-- Date Version Author Description +-- 2013-08-10 1.0 mkreider Created +------------------------------------------------------------------------------- + library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; @@ -8,116 +36,178 @@ use work.genram_pkg.all; use work.wb_irq_pkg.all; entity wb_irq_master is - port (clk_i : std_logic; - rst_n_i : std_logic; - - master_o : out t_wishbone_master_out; - master_i : in t_wishbone_master_in; - - irq_i : std_logic; - adr_i : t_wishbone_address; - msg_i : t_wishbone_data +generic( g_channels : natural := 32; -- number of interrupt lines + g_round_rb : boolean := true; -- scheduler true: round robin, false: prioritised + g_det_edge : boolean := true; -- edge detection. true: trigger on rising edge of irq lines, false: trigger on high level + g_has_dev_id : boolean := false; -- if set, dst adr bits 15..8 hold g_dev_id as device identifier + g_dev_id : std_logic_vector(4 downto 0) := (others => '0'); -- device identifier + g_default_msg : boolean := true -- initialises msgs to a default value in order to detect uninitialised irq master +); +port (clk_i : std_logic; -- clock + rst_n_i : std_logic; -- reset, active LO + --msi if + irq_master_o : out t_wishbone_master_out; -- Wishbone msi irq interface + irq_master_i : in t_wishbone_master_in; + -- ctrl interface + ctrl_slave_o : out t_wishbone_slave_out; + ctrl_slave_i : in t_wishbone_slave_in; + --irq lines + mask_i : std_logic_vector(g_channels-1 downto 0); -- irq mask. to use mask register only, tie all bits to HI + irq_i : std_logic_vector(g_channels-1 downto 0) -- irq lines ); end entity; architecture behavioral of wb_irq_master is -signal r_ffs_q : std_logic; -signal r_ffs_r : std_logic; -signal s_ffs_s : std_logic; - -type t_state is (s_IDLE, s_LOOKUP, s_SEND, s_DONE); -signal r_state : t_state; -signal s_master_o : t_wishbone_master_out; - +function f_wb_wr(pval : std_logic_vector; ival : std_logic_vector; sel : std_logic_vector; mode : string := "owr") return std_logic_vector is + variable n_sel : std_logic_vector(pval'range); + variable n_val : std_logic_vector(pval'range); + variable result : std_logic_vector(pval'range); begin - - -------------------------------------------------------------------------- ---input rs flipflops -------------------------------------------------------------------------- -process(clk_i) - begin - if rising_edge(clk_i) then - if(rst_n_i = '0') then - r_ffs_q <= '0'; - else - if(s_ffs_s = '0' and r_ffs_r = '1') then - r_ffs_q <= '0'; - elsif(s_ffs_s = '1' and r_ffs_r = '0') then - r_ffs_q <= '1'; - else - r_ffs_q <= r_ffs_q; - end if; - end if; + for i in pval'range loop + n_sel(i) := sel(i / 8); + n_val(i) := ival(i); + end loop; + + if(mode = "set") then + result := pval or (n_val and n_sel); + elsif (mode = "clr") then + result := pval and not (n_val and n_sel); + else + result := (pval and not n_sel) or (n_val and n_sel); + end if; + + return result; +end f_wb_wr; + +function f_oob(a : std_logic_vector; limit : natural) return boolean is +begin + if(to_integer(unsigned(a)) > limit-1) then + return true; + else + return false; end if; - end process; +end f_oob; + +--****************************************************************************************** +-- WB ctrl interface definitions and constants +-------------------------------------------------------------------------------------------- +signal s_c_en, s_c_we, r_c_ack, r_c_err : std_logic; +signal s_c_adr : natural range 255 downto 0; +signal s_c_dati, r_c_dato : t_wishbone_data; +signal s_c_sel : t_wishbone_byte_select; +signal r_rst_n : std_logic; + +constant c_RST : natural := 0; --0x00, wo, Reset Active Low +constant c_MSK_GET : natural := c_RST +4; --0x04, ro, get irq mask. to only use irq mask vector (mask_i), set all bits to HI +constant c_MSK_SET : natural := c_MSK_GET +4; --0x08, wo, set irq mask bits. +constant c_MSK_CLR : natural := c_MSK_SET +4; --0x0C, wo, clr irq mask bits, +constant c_CHANNEL_INFO : natural := c_MSK_CLR +4; --0x10 ro number of channels in this device + +constant c_CHANNEL_SEL : natural := 16#20#; --0x20, rw, channel select. !!!CAUTION!!! content of all c_CH_... regs depends on this +constant c_CH_MSG : natural := c_CHANNEL_SEL +4; --0x24, rw, MSI msg to be sent on MSI when deadline is hit +constant c_CH_DST : natural := c_CH_MSG +4; --0x28, rw, MSI adr to send the msg to when deadline is hit + +signal r_csl : t_wishbone_data; -- channel select +signal r_msk, s_msk : std_logic_vector(g_channels-1 downto 0); -- mask +signal r_msg : t_wishbone_data_array(g_channels-1 downto 0); -- messages +signal r_dst : t_wishbone_address_array(g_channels-1 downto 0); -- destinations - - -s_ffs_s <= irq_i; -s_master_o.sel <= (others => '1'); -s_master_o.we <= '1'; - -master_o <= s_master_o; -------------------------------------------------------------------------- - -------------------------------------------------------------------------- --- WB master generating IRQ msgs -------------------------------------------------------------------------- -wb_irq_master : process(clk_i, rst_n_i) +begin - variable v_state : t_state; - variable v_irq : natural; +--combine mask register and mask lines +s_msk <= r_msk and mask_i; +--****************************************************************************************** +-- WB ctrl interface implementation +-------------------------------------------------------------------------------------------- + + s_c_en <= ctrL_slave_i.cyc and ctrl_slave_i.stb; + s_c_adr <= to_integer(unsigned(ctrl_slave_i.adr(7 downto 2)) & "00"); + s_c_we <= ctrl_slave_i.we; + s_c_dati <= ctrl_slave_i.dat; + s_c_sel <= ctrl_slave_i.sel; + + ctrl_slave_o.int <= '0'; + ctrl_slave_o.rty <= '0'; + ctrl_slave_o.stall <= '0'; + ctrl_slave_o.ack <= r_c_ack; + ctrl_slave_o.err <= r_c_err; + ctrl_slave_o.dat <= r_c_dato; + + process(clk_i) + variable v_ch_sl : natural range g_channels-1 downto 0; begin - if(rst_n_i = '0') then - - s_master_o.cyc <= '0'; - s_master_o.stb <= '0'; - s_master_o.adr <= (others => '0'); - s_master_o.dat <= (others => '0'); - r_state <= s_IDLE; - - elsif rising_edge(clk_i) then - - v_state := r_state; - - case r_state is - when s_IDLE => if(r_ffs_q = '1') then - s_master_o.adr <= adr_i; - s_master_o.dat <= msg_i; - v_state := s_SEND; - end if; - - when s_SEND => if(master_i.stall = '0') then - v_state := s_DONE; - end if; - - when s_DONE => v_state := s_IDLE; - when others => v_state := s_IDLE; - end case; - - -- flags on state transition - if(v_state = s_DONE) then - r_ffs_r <= '1'; - else - r_ffs_r <= '0'; - end if; - - if(v_state = s_SEND) then - s_master_o.cyc <= '1'; - s_master_o.stb <= '1'; - else - s_master_o.cyc <= '0'; - s_master_o.stb <= '0'; - end if; - - r_state <= v_state; - - end if; - - end process; + if rising_edge(clk_i) then + if(rst_n_i = '0' or r_rst_n <= '0') then + r_c_ack <= '0'; + r_c_err <= '0'; + r_rst_n <= '1'; + r_csl <= (others => '0'); -- channel select + r_msk <= (others => '0'); -- irq mask + + --init code for messages + if(g_default_msg) then + for i in irq_i'range loop + r_dst(i) <= x"CAFEBABE"; + end loop; + end if; + else + -- Fire and Forget Registers + + r_c_ack <= '0'; + r_c_err <= '0'; + r_c_dato <= (others => '0'); + + if(s_c_en = '1') then + v_ch_sl := to_integer(unsigned(r_csl)); + r_c_ack <= '1'; + if(s_c_we = '1') then + case s_c_adr is + when c_RST => r_rst_n <= '0'; + when c_MSK_SET => r_msk <= f_wb_wr(r_msk, s_c_dati, s_c_sel, "set"); + when c_MSK_CLR => r_msk <= f_wb_wr(r_msk, s_c_dati, s_c_sel, "clr"); + when c_CHANNEL_SEL => if(f_oob(s_c_dati, g_channels)) then -- owr with limit check + r_c_ack <= '0'; r_c_err <= '1'; + else + r_csl <= f_wb_wr(r_csl, s_c_dati, s_c_sel, "owr"); + end if; + when c_CH_MSG => r_msg(v_ch_sl) <= f_wb_wr(r_msg(v_ch_sl), s_c_dati, s_c_sel, "owr"); + when c_CH_DST => r_dst(v_ch_sl) <= f_wb_wr(r_dst(v_ch_sl), s_c_dati, s_c_sel, "owr"); + when others => r_c_ack <= '0'; r_c_err <= '1'; + end case; + else + case s_c_adr is + when c_MSK_GET => r_c_dato(r_msk'range) <= r_msk; + when c_CHANNEL_INFO => r_c_dato <= std_logic_vector(to_unsigned(g_channels,32)); + when c_CHANNEL_SEL => r_c_dato(r_csl'range) <= r_csl; + when c_CH_MSG => r_c_dato(r_msg(v_ch_sl)'range) <= r_msg(v_ch_sl); + when c_CH_DST => r_c_dato(r_dst(v_ch_sl)'range) <= r_dst(v_ch_sl); + when others => r_c_ack <= '0'; r_c_err <= '1'; + end case; + end if; -- s_c_we + end if; -- s_c_en + end if; -- rst + end if; -- clk edge + end process; + + msi : irqm_core + generic map(g_channels => g_channels, + g_round_rb => g_round_rb, + g_det_edge => g_det_edge + ) + port map( clk_i => clk_i, + rst_n_i => rst_n_i, + --msi if + irq_master_o => irq_master_o, + irq_master_i => irq_master_i, + --config + msi_dst_array => r_dst, + msi_msg_array => r_msg, + --irq lines + mask_i => s_msk, + irq_i => irq_i + ); diff --git a/modules/wishbone/wb_irq/wb_irq_pkg.vhd b/modules/wishbone/wb_irq/wb_irq_pkg.vhd index abd5ec2fcbc151a420da5e6bfafee1af9f0ebdbd..1445206f4c31fb007eb35364c500d713db3ea2b9 100644 --- a/modules/wishbone/wb_irq/wb_irq_pkg.vhd +++ b/modules/wishbone/wb_irq/wb_irq_pkg.vhd @@ -52,7 +52,7 @@ package wb_irq_pkg is wbd_width => x"7", -- 8/16/32-bit port granularity sdb_component => ( addr_first => x"0000000000000000", - addr_last => x"00000000000000ff", + addr_last => x"0000000000000fff", product => ( vendor_id => x"0000000000000651", -- GSI device_id => x"10050081", @@ -68,7 +68,7 @@ package wb_irq_pkg is wbd_width => x"7", -- 8/16/32-bit port granularity sdb_component => ( addr_first => x"0000000000000000", - addr_last => x"00000000000000ff", + addr_last => x"0000000000000fff", product => ( vendor_id => x"0000000000000651", -- GSI device_id => x"10050082", @@ -93,15 +93,24 @@ package wb_irq_pkg is name => "IRQ_CTRL "))); component wb_irq_master is - port (clk_i : std_logic; - rst_n_i : std_logic; - - master_o : out t_wishbone_master_out; - master_i : in t_wishbone_master_in; - - irq_i : std_logic; - adr_i : t_wishbone_address; - msg_i : t_wishbone_data + generic( g_channels : natural := 32; -- number of interrupt lines + g_round_rb : boolean := true; -- scheduler true: round robin, false: prioritised + g_det_edge : boolean := true; -- edge detection. true: trigger on rising edge of irq lines, false: trigger on high level + g_has_dev_id : boolean := false; -- if set, dst adr bits 15..8 hold g_dev_id as device identifier + g_dev_id : std_logic_vector(4 downto 0) := (others => '0'); -- device identifier + g_default_msg : boolean := true -- initialises msgs to a default value in order to detect uninitialised irq master +); +port (clk_i : std_logic; -- clock + rst_n_i : std_logic; -- reset, active LO + --msi if + irq_master_o : out t_wishbone_master_out; -- Wishbone msi irq interface + irq_master_i : in t_wishbone_master_in; + -- ctrl interface + ctrl_slave_o : out t_wishbone_slave_out; + ctrl_slave_i : in t_wishbone_slave_in; + --irq lines + mask_i : std_logic_vector(g_channels-1 downto 0); -- irq mask. to use mask register only, tie all bits to HI + irq_i : std_logic_vector(g_channels-1 downto 0) -- irq lines ); end component; @@ -156,6 +165,27 @@ package wb_irq_pkg is ); end component; + component irqm_core is + generic( g_channels : natural := 32; -- number of interrupt lines + g_round_rb : boolean := true; -- scheduler true: round robin, false: prioritised + g_det_edge : boolean := true; -- edge detection. true: trigger on rising edge of irq lines, false: trigger on high level + g_has_dev_id : boolean := false; -- if set, dst adr bits 15..8 hold g_dev_id as device identifier + g_dev_id : std_logic_vector(4 downto 0) := (others => '0'); -- device identifier + g_default_msg : boolean := true -- initialises msgs to a default value in order to detect uninitialised irq master +); +port (clk_i : std_logic; -- clock + rst_n_i : std_logic; -- reset, active LO + --msi if + irq_master_o : out t_wishbone_master_out; -- Wishbone msi irq interface + irq_master_i : in t_wishbone_master_in; + --config + msi_dst_array : in t_wishbone_address_array(g_channels-1 downto 0); -- MSI Destination address for each channel + msi_msg_array : in t_wishbone_data_array(g_channels-1 downto 0); -- MSI Message for each channel + --irq lines + mask_i : std_logic_vector(g_channels-1 downto 0); -- interrupt mask + irq_i : std_logic_vector(g_channels-1 downto 0) -- interrupt lines +); + end component; component wb_irq_lm32 is generic(g_msi_queues: natural := 3; diff --git a/modules/wishbone/wb_irq/wb_irq_timer.vhd b/modules/wishbone/wb_irq/wb_irq_timer.vhd index 04eacde08a99619943929125e0f1ce8e1802d934..dbf4752d19933a418a9342f2769d24bc1e086e9a 100644 --- a/modules/wishbone/wb_irq/wb_irq_timer.vhd +++ b/modules/wishbone/wb_irq/wb_irq_timer.vhd @@ -135,12 +135,12 @@ signal r_src : std_logic_vector(g_timers-1 downto 0); --comps sources signal r_mod : std_logic_vector(g_timers-1 downto 0); --counters mode signal r_csc : std_logic_vector(g_timers-1 downto 0); --cascade starts signal r_msg : t_wishbone_data_array(g_timers-1 downto 0); -signal r_dst : t_wishbone_data_array(g_timers-1 downto 0); +signal r_dst : t_wishbone_address_array(g_timers-1 downto 0); signal r_csl : t_wishbone_data_array(g_timers-1 downto 0); --cascade selects signal r_ddl_hi : t_wishbone_data_array(g_timers-1 downto 0); signal r_ddl_lo : t_wishbone_data_array(g_timers-1 downto 0); -signal s_comp_mask, s_comp_edge_masked : std_logic_vector(g_timers-1 downto 0); +signal s_comp_mask, s_comp_edge_masked : std_logic_vector(g_timers-1 downto 0); signal r_msk_cnt : t_msk_cnt_array(g_timers-1 downto 0); signal r_time : t_time; signal s_deadline : t_time_array(g_timers-1 downto 0); @@ -149,22 +149,10 @@ signal r_deadline_offs : t_time_array(g_timers-1 downto 0); signal s_x, s_y, s_sy : t_time_array(g_timers-1 downto 0); signal s_ovf1, s_ovf2 : std_logic_vector(g_timers-1 downto 0); - - - signal s_csc_arm, s_csc_arm_edge : std_logic_vector(g_timers-1 downto 0); --cascade starts - - -------------------------------------------------------------------------------------------- ---****************************************************************************************** --- WB irq interface definitions and constants --------------------------------------------------------------------------------------------- -signal r_comp_1st, comp, s_comp_edge, r_comp, r_pending : std_logic_vector(g_timers-1 downto 0); -signal r_wb_sending, s_wb_send : std_logic; -signal s_idx, r_idx : natural range g_timers-1 downto 0; -signal r_state : t_state; -signal s_set_pending : std_logic_vector(r_pending'length-1 downto 0); +signal r_comp_1st, comp, s_comp_edge, r_comp : std_logic_vector(g_timers-1 downto 0); begin @@ -317,7 +305,7 @@ G1: for I in 0 to g_timers-1 generate end process deadline_offs; - --create comparators + --create comparators -- carry-save s_x(I) <= s_deadline_abs(I) xor r_deadline_offs(I) xor not r_time; @@ -329,8 +317,6 @@ G1: for I in 0 to g_timers-1 generate s_sy(I)(63 downto 1) <= s_y(I)(62 downto 0); s_sy(I)(0) <= '0'; - - ea : eca_adder port map( clk_i => clk_sys_i, @@ -342,14 +328,8 @@ G1: for I in 0 to g_timers-1 generate x2_o => open, c2_o => open); - - - - end generate; - - comps : process(clk_sys_i) begin if rising_edge(clk_sys_i) then @@ -365,87 +345,24 @@ G1: for I in 0 to g_timers-1 generate s_comp_edge_masked <= s_comp_edge and s_comp_mask; ---****************************************************************************************** --- WB IRQ Interface Arbitration --------------------------------------------------------------------------------------------- - with f_hot_to_bin(r_pending) select - s_idx <= 0 when 0, - f_hot_to_bin(r_pending)-1 when others; - - s_wb_send <= f_or_vec(r_pending); - - -- keep track of what needs sending - queue_mux : process(clk_sys_i, rst_sys_n_i) - variable v_set_pending, v_clr_pending : std_logic_vector(r_pending'length-1 downto 0); - begin - if rising_edge(clk_sys_i) then - if((rst_sys_n_i and r_rst_n) = '0') then - r_pending <= (others => '0'); - else - v_clr_pending := (others => '1'); - v_clr_pending(r_idx) := not r_wb_sending; - v_set_pending := s_comp_edge_masked; - - r_pending <= (r_pending or v_set_pending) and v_clr_pending; - end if; - end if; - end process queue_mux; - ---****************************************************************************************** --- WB IRQ Interface --------------------------------------------------------------------------------------------- - --- send pending MSI IRQs over WB - wb_irq_master : process(clk_sys_i) - variable v_state : t_state; - begin - - if rising_edge(clk_sys_i) then - if(rst_sys_n_i = '0') then - irq_master_o.cyc <= '0'; - irq_master_o.stb <= '0'; - irq_master_o.we <= '1'; - irq_master_o.sel <= (others => '1'); - r_state <= st_IDLE; - r_idx <= 0; - else - v_state := r_state; - - case r_state is - when st_IDLE => if(s_wb_send = '1') then - v_state := st_SEND; - irq_master_o.adr <= r_dst(s_idx)(31 downto 8) & std_logic_vector(to_unsigned(s_idx, 6)) & "00"; - irq_master_o.dat <= r_msg(s_idx); - r_idx <= s_idx; - end if; - when st_SEND => if(irq_master_i.stall = '0') then - v_state := st_IDLE; - end if; - when others => v_state := st_IDLE; - end case; - -- flags on state transition - if(v_state = st_IDLE) then - r_wb_sending <= '0'; - - else - r_wb_sending <= '1'; - end if; - - if(v_state = st_SEND) then - irq_master_o.cyc <= '1'; - irq_master_o.stb <= '1'; - - - else - irq_master_o.cyc <= '0'; - irq_master_o.stb <= '0'; - end if; - - r_state <= v_state; - end if; - end if; - end process; + irq : irqm_core + generic map(g_channels => g_timers, + g_round_rb => true, + g_det_edge => false + ) + port map( clk_i => clk_sys_i, + rst_n_i => rst_sys_n_i, + --msi if + irq_master_o => irq_master_o, + irq_master_i => irq_master_i, + --config + msi_dst_array => r_dst, + msi_msg_array => r_msg, + mask_i => s_comp_mask, + --irq lines + irq_i => s_comp_edge + ); end architecture behavioral;