Skip to content
Snippets Groups Projects
Commit 4ecde6be authored by Mathias Kreider's avatar Mathias Kreider
Browse files

wb_irq: bug on ack line for irqm_core fixed

	removed auto id from irqm_core
        TODO: fix auto IDs for wb_irq_master
parent c003e0be
Branches
Tags
No related merge requests found
......@@ -10,10 +10,7 @@ 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
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
g_det_edge : boolean := true -- edge detection. true: trigger on rising edge of irq lines, false: trigger on high level
);
port (clk_i : std_logic; -- clock
rst_n_i : std_logic; -- reset, active LO
......@@ -31,7 +28,7 @@ end entity;
architecture behavioral of irqm_core is
type t_state is (st_IDLE, st_SEND);
type t_state is (st_IDLE, st_SEND, st_WAITACK);
signal r_state : t_state;
signal s_msg : t_wishbone_data_array(g_channels-1 downto 0);
......@@ -139,52 +136,46 @@ irq_master_o.we <= '1';
-- send pending MSI IRQs over WB
wb_irq_master : process(clk_i)
variable v_state : t_state;
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;
v_dst := (others => '0');
if(rst_n_i = '0') then
irq_master_o.cyc <= '0';
irq_master_o.stb <= '0';
r_state <= st_IDLE;
else
v_state := r_state;
r_wb_sending <= '0';
v_state := r_state;
r_wb_sending <= '0';
case r_state is
when st_IDLE => if(s_wb_send = '1') then
when st_IDLE => if(s_wb_send = '1') then
v_state := st_SEND;
v_dst(6 downto 2) := std_logic_vector(to_unsigned(idx, 5));
if(g_has_dev_id) then
v_dst(12 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.adr <= s_dst(idx);
irq_master_o.dat <= s_msg(idx);
r_wb_sending <= '1';
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;
end if;
when st_SEND => if(irq_master_i.stall = '0') then
v_state := st_WAITACK;
end if;
when st_WAITACK => if(irq_master_i.ack = '1') then
v_state := st_IDLE;
end if;
when others => v_state := st_IDLE;
end case;
-- flags on state transition
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;
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;
......
......@@ -26,6 +26,9 @@
-- 2013-08-10 1.0 mkreider Created
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
......@@ -39,8 +42,9 @@ entity wb_irq_master 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_has_dev_id : boolean := false; -- if set, dst adr bits 11..7 hold g_dev_id as device identifier
g_dev_id : std_logic_vector(4 downto 0) := (others => '0'); -- device identifier
g_has_ch_id : boolean := false; -- if set, dst adr bits 6..2 hold g_ch_id as 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
......@@ -52,7 +56,6 @@ port (clk_i : std_logic; -- clock
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;
......@@ -61,12 +64,12 @@ architecture behavioral of wb_irq_master is
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);
variable n_val : std_logic_vector(pval'range);
variable result : std_logic_vector(pval'range);
begin
for i in pval'range loop
n_sel(i) := sel(i / 8);
n_val(i) := ival(i);
n_val(i) := ival(i);
end loop;
if(mode = "set") then
......@@ -102,7 +105,8 @@ constant c_RST : natural := 0; --0x00, wo, Reset
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_SW_IRQ : natural := c_MSK_CLR +4; --0x10, wo, software irq
constant c_CHANNEL_INFO : natural := c_SW_IRQ +4; --0x14 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
......@@ -112,11 +116,21 @@ signal r_csl : t_wishbone_data; --
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
signal s_irq, r_swirq : std_logic_vector(g_channels-1 downto 0); --
--v_dst(6 downto 2) := std_logic_vector(to_unsigned(idx, 5));
--if(g_has_dev_id) then
-- v_dst(12 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;
begin
--combine mask register and mask lines
s_msk <= r_msk and mask_i;
s_msk <= r_msk;
s_irq <= irq_i or r_swirq;
--******************************************************************************************
-- WB ctrl interface implementation
......@@ -145,6 +159,7 @@ s_msk <= r_msk and mask_i;
r_rst_n <= '1';
r_csl <= (others => '0'); -- channel select
r_msk <= (others => '0'); -- irq mask
r_swirq <= (others => '0'); -- software irq
--init code for messages
if(g_default_msg) then
......@@ -167,6 +182,7 @@ s_msk <= r_msk and mask_i;
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_SW_IRQ => r_swirq <= f_wb_wr(r_swirq, s_c_dati, s_c_sel, "owr");
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
......@@ -206,7 +222,7 @@ s_msk <= r_msk and mask_i;
msi_msg_array => r_msg,
--irq lines
mask_i => s_msk,
irq_i => irq_i
irq_i => s_irq
);
......
......@@ -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"0000000000000fff",
addr_last => x"00000000000000ff",
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"0000000000000fff",
addr_last => x"00000000000000ff",
product => (
vendor_id => x"0000000000000651", -- GSI
device_id => x"10050082",
......@@ -95,10 +95,7 @@ package wb_irq_pkg is
component wb_irq_master 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
g_det_edge : boolean := true -- edge detection. true: trigger on rising edge of irq lines, false: trigger on high level
);
port (clk_i : std_logic; -- clock
rst_n_i : std_logic; -- reset, active LO
......@@ -109,7 +106,6 @@ port (clk_i : std_logic; -- clock
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;
......@@ -166,12 +162,9 @@ port (clk_i : std_logic; -- clock
end component;
component irqm_core is
generic( g_channels : natural := 32; -- number of interrupt lines
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
g_det_edge : boolean := true -- edge detection. true: trigger on rising edge of irq lines, false: trigger on high level
);
port (clk_i : std_logic; -- clock
rst_n_i : std_logic; -- reset, active LO
......@@ -243,8 +236,8 @@ variable ret : std_logic;
begin
ret := '0';
for I in 0 to slv_in'left loop
ret := ret or slv_in(I);
end loop;
ret := ret or slv_in(I);
end loop;
return ret;
end function or_all;
......
......@@ -140,7 +140,7 @@ signal r_csl : t_wishbone_data_array(g_timers-1 downto 0); --cascade selec
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 : 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);
......@@ -343,9 +343,6 @@ G1: for I in 0 to g_timers-1 generate
end if;
end process comps;
s_comp_edge_masked <= s_comp_edge and s_comp_mask;
irq : irqm_core
generic map(g_channels => g_timers,
g_round_rb => true,
......
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