Commit ed4ba6aa authored by Cesar Prados's avatar Cesar Prados

msi_interrupts: add support to the core to handle msi interrupts

   the VME_Wb interface has an additional register for controlling
   the msi interrupts. The rest of the changes in the VME bus and top
   file are for backwards compatibility. Now the user can synthesize
   for legacy interrupts or msi.
parent 20906542
......@@ -96,6 +96,7 @@ entity VME_Wb_Interface is
funct_sel : in std_logic_vector (7 downto 0);
RW_o : out std_logic;
-- MSI
msi_reset_i : in std_logic;
msi_slave_o : out t_wishbone_slave_out;
msi_slave_i : in t_wishbone_slave_in := cc_dummy_slave_in;
msi_irq_o : out std_logic
......@@ -104,21 +105,21 @@ end VME_Wb_interface;
--===========================================================================
-- Architecture declaration
--===========================================================================
architecture Behavioral of VME_Wb_master is
--==========================================================================
architecture Behavioral of VME_Wb_interface is
signal s_shift_dx : std_logic;
signal s_funct_sel : std_logic_vector (7 downto 0);
signal s_cyc : std_logic;
signal s_AckWithError : std_logic;
signal s_ack_ctrl : std_logic;
signal s_ack_ctrl : std_logic;
signal s_wbData_i : std_logic_vector(63 downto 0);
signal s_select : std_logic_vector(8 downto 0);
signal s_data_ctrl : std_logic_vector(g_wb_data_width - 1 downto 0);
signal s_DATi_sample : std_logic_vector(g_wb_data_width - 1 downto 0);
signal s_funct_sel : integer := 0;
-- Ctrl
signal s_error_ctrl : std_logic_vector(31 downto 0);
-- MSI register
signal s_msi_cyc : std_logic;
signal s_msi_cyc : std_logic := '0';
signal s_msi_fifo_full: std_logic;
signal s_msi_fifo_full_r : std_logic;
......@@ -133,32 +134,37 @@ begin
s_select <= cardSel_i & sel_i;
s_wbData_i <= std_logic_vector(resize(unsigned(s_DATi_sample),s_wbData_i'length));
s_funct_sel <= to_integer(unsigned(funct_sel));
cyc_o <= s_cyc;
MSI_IRQ_FIFO : xwb_clock_crossing port map(
slave_clk_i => clk_i,
slave_rst_n_i => reset_i,
slave_rst_n_i => msi_reset_i,
slave_i => msi_slave_i,
slave_o => msi_slave_o,
master_clk_i => clk_i,
master_rst_n_i => reset_i,
master_rst_n_i => msi_reset_i,
master_i => msi_int_master_i,
master_o => msi_int_master_o);
msi_int_master_i.rty <= '0';
s_msi_fifo_full <= int_master_o.cyc and int_master_o.stb;
s_msi_fifo_full <= msi_int_master_o.cyc and msi_int_master_o.stb;
msi_irq_o <= s_msi_fifo_full and not s_msi_fifo_full_r;
process(clk_i)
begin
if rising_edge(clk_i) then
s_msi_fifo_full_r <= s_msi_fifo_full;
s_funct_sel <= funct_sel;
msi_int_master_i.stall <= '1';
msi_int_master_i.ack <= '0';
msi_int_master_i.err <= '0';
-- WB WINDOW
if funct_sel(0) = '1' or (funct_sel(0) = '0' and funct_sel(1) = '0') then
if s_funct_sel(0) = '1' or (s_funct_sel(0) = '0' and s_funct_sel(1) = '0') then
-- strobe hadler
if reset_i = '1' or (stall_i = '0' and s_cyc = '1') then
stb_o <= '0';
......@@ -176,7 +182,7 @@ begin
s_AckWithError <=(memReq_i and cardSel_i and BERRcondition_i);
s_ack_ctrl <= '0';
elsif funct_sel(1) = '1' and -- CONTROL WINDOW
elsif s_funct_sel(1) = '1' and -- CONTROL WINDOW
(memReq_i = '1' and cardSel_i = '1' and BERRcondition_i = '0') then
s_ack_ctrl <= '1';
......@@ -187,8 +193,8 @@ begin
when "001000" => -- SDWD
s_data_ctrl <= g_sdb_addr;
when "010000" => -- CTRL
s_data_ctrl(31) <= s_msi_cyc;
s_data_ctrl(30 downto 0) <= '0';
s_data_ctrl(31) <= s_cyc;
s_data_ctrl(30 downto 0) <= (others => '0');
when "011000" => -- MASTER MSI STATUS
s_data_ctrl(31) <= s_msi_fifo_full;
s_data_ctrl(30) <= msi_int_master_o.we;
......@@ -201,31 +207,27 @@ begin
when others =>
s_data_ctrl <= (others => '0');
end case;
msi_int_master_i.stall <= '1';
msi_int_master_i.ack <= '0';
msi_int_master_i.err <= '0';
if RW_i = '1' then
if RW_i = '0' and memReq_i = '1' and cardSel_i = '1' then
case rel_locAddr_i(5 downto 0) is
when "010000" => -- CTRL
if sel_i(3) = '1' then
if locDataInSwap_i(30) = '1' then -- write
s_msi_cyc <= locDataInSwap_i(31);
s_cyc <= locDataInSwap_i(31);
end if;
when "011000" => -- MASTER MSI STATUS
if sel_i(0) = '1' then
case locDataInSwap_i(1 downto 0) is
when "00" => null;
when "01" => msi_int_master_i.stall <= '0';
when "10" => msi_int_master_i.ack <= '1';
when "11" => msi_int_master_i.err <= '1';
end case;
end if;
when "101000" => -- MASTER MSI DATA
msi_int_master_i.dat <= locDataInSwap_i(31 downto 0);
when others =>
end case;
end if;
end if;
end if
-- Shift in the error register
if err_i = '1' or rty_i = '1' or s_ack_ctrl = '1' then
......@@ -233,6 +235,8 @@ begin
(err_i or rty_i );
end if;
end if;
end process;
-- shift data and address for WB data bus 32 bits
......
......@@ -130,7 +130,7 @@ entity VME_bus is
stall_i : in std_logic;
-- MSI WB slave
slave_o : out t_wishbone_slave_out;
slave_i : out t_wishbone_slave_in;
slave_i : in t_wishbone_slave_in;
msi_irq_o : out std_logic;
--CR/CSR space signals:
CRAMaddr_o : out std_logic_vector(f_log2_size(g_cram_size)-1 downto 0);
......@@ -274,9 +274,6 @@ architecture RTL of VME_bus is
signal s_BEG_CRAM : std_logic_vector(23 downto 0);
signal s_END_CRAM : std_logic_vector(23 downto 0);
-- MSI IRQ
signal s_msi_irq : std_logic;
-- Error signals
signal s_BERRcondition : std_logic; -- Condition for asserting BERR
signal s_wberr1 : std_logic;
......@@ -1225,11 +1222,12 @@ with s_addressingType select
funct_sel => s_func_sel,
RW_o => RW_o,
-- MSI WB bus
slave_o => slave_o,
slave_i => slave_i,
msi_irq_o => s_msi_irq
msi_reset_i => VME_RST_n_i,
msi_slave_o => slave_o,
msi_slave_i => slave_i,
msi_irq_o => msi_irq_o
);
--------------------------DECODER-------------------------------------|
-- DECODER: This component check if the board is addressed; if the CR/CSR
-- space is addressed the Confaccess signal is asserted
......
......@@ -182,7 +182,7 @@
signal s_bytes : std_logic_vector(12 downto 0);
signal s_IRQ : std_logic;
signal s_IRQ_i : std_logic;
signal s_msi_irq : std_logic;
-- Oversampled input signals
signal VME_RST_n_oversampled : std_logic;
......@@ -320,9 +320,9 @@ begin
rty_i => master_i.RTY,
stall_i => master_i.STALL,
-- MSI WB slave
slave_o => slave_o;
slave_i => slave_i;
msi_irq_o => s_msi_irq;
slave_o => slave_o,
slave_i => slave_i,
msi_irq_o => s_msi_irq,
-- CR/CSR signals
CRAMaddr_o => s_CRAMaddr,
CRAMdata_o => s_CRAMdataIn,
......
......@@ -91,6 +91,22 @@ package xvme64x_pack is
--_______________________________________________________________________________
-- Constants:
constant c_vme_msi_sdb : t_sdb_device := (
abi_class => x"0000", -- undocumented device
abi_ver_major => x"01",
abi_ver_minor => x"01",
wbd_endian => c_sdb_endian_big,
wbd_width => x"7", -- 8/16/32-bit port granularity
sdb_component => (
addr_first => x"0000000000000000",
addr_last => x"00000000000000ff",
product => (
vendor_id => x"0000000000000651", -- GSI
device_id => x"9326AA75",
version => x"00000001",
date => x"20120308",
name => "IRQ_VME ")));
--SDB address
constant c_sdb_address : t_wishbone_address := x"00300000";
--WB data width:
......@@ -277,7 +293,7 @@ package xvme64x_pack is
s_DTACK => '1',
s_enableIRQ => '0',
s_resetIRQ => '1',
s_DSlatch => '0',
s_DSlatch => '0'
);
-- CSR address:
......@@ -678,8 +694,7 @@ function f_latchDS (clk_period : integer) return integer;
g_ManufacturerID : integer := c_CERN_ID;
g_RevisionID : integer := c_RevisionID;
g_ProgramID : integer := 96;
g_base_addr : base_addr:= GEOGRAPHICAL_ADDR;
g_irq_addr : integer := LEGACY
g_base_addr : base_addr:= GEOGRAPHICAL_ADDR
);
port(
......@@ -786,8 +801,9 @@ function f_latchDS (clk_period : integer) return integer;
WbSel_o : out std_logic_vector(f_div8(g_wb_data_width) - 1 downto 0);
funct_sel : in std_logic_vector (7 downto 0);
RW_o : out std_logic;
slave_o : out t_wishbone_slave_out;
slave_i : in t_wishbone_slave_in;
msi_reset_i : in std_logic;
msi_slave_o : out t_wishbone_slave_out;
msi_slave_i : in t_wishbone_slave_in;
msi_irq_o : out std_logic
);
end component VME_Wb_Interface;
......@@ -1047,5 +1063,6 @@ function f_log2_size (A : natural) return natural is
end loop;
return(4); -- works for up to 200 MHz
end function f_latchDS;
end xvme64x_pack;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment