Commit c8a6d3c3 authored by Federico Vaga's avatar Federico Vaga

Merge remote-tracking branch 'origin/proposed_master'

Tested by Dimitris who used the proposed_master branch  as reference in
external projects.

This has been tester with the trigger distribution which seems to work.
So I believe that these changes work. In order to keep things
parents a637eeaf 5c0ef2d1
general-cores @ a50772ea
Subproject commit 1d8a2e8a31c0e5f7c6bd14a42f2251e4d4c3ecc0
Subproject commit a50772ea3d4687226fbb6339bd951137946c7ad5
......@@ -39,6 +39,7 @@ entity mt_cpu_cb is
generic (
g_CPU_ID : integer;
g_CPU_CONFIG : t_mt_cpu_config;
g_CPU_IRAM_INIT : string;
g_SYSTEM_CLOCK_FREQ : integer;
g_WITH_WHITE_RABBIT : boolean);
port (
......@@ -307,6 +308,7 @@ begin -- arch
U_TheCoreCPU : entity work.mt_urv_wrapper
generic map (
g_IRAM_SIZE => g_CPU_CONFIG.memsize,
g_IRAM_INIT => g_CPU_IRAM_INIT,
g_CPU_ID => g_CPU_ID)
port map (
clk_sys_i => clk_sys_i,
......
......@@ -34,6 +34,7 @@ use work.mt_per_cpu_csr_pkg.all;
entity mt_urv_wrapper is
generic(
g_IRAM_SIZE : integer;
g_IRAM_INIT : string;
g_CPU_ID : integer);
port(
clk_sys_i : in std_logic;
......@@ -155,7 +156,8 @@ begin
g_SIZE => g_IRAM_SIZE,
g_WITH_BYTE_ENABLE => TRUE,
g_ADDR_CONFLICT_RESOLUTION => "dont_care",
g_INIT_FILE => "",
g_INIT_FILE => g_IRAM_INIT,
g_FAIL_IF_FILE_NOT_FOUND => FALSE,
g_DUAL_CLOCK => FALSE)
port map (
rst_n_i => rst_n_i,
......
......@@ -47,21 +47,12 @@ package mt_endpoint_pkg is
dst_ip : std_logic_vector(31 downto 0);
dst_port : std_logic_vector(15 downto 0);
ethertype : std_logic_vector(15 downto 0);
type0 : std_logic_vector(31 downto 0);
type1 : std_logic_vector(31 downto 0);
type2 : std_logic_vector(31 downto 0);
type3 : std_logic_vector(31 downto 0);
store_header : std_logic;
is_tlv : std_logic;
filter_dst_mac : std_logic;
filter_dst_ip : std_logic;
filter_dst_port : std_logic;
filter_ethertype : std_logic;
filter_udp : std_logic;
filter_type0 : std_logic;
filter_type1 : std_logic;
filter_type2 : std_logic;
filter_type3 : std_logic;
filter_raw : std_logic;
enable : std_logic; -- discard all packets if 0
end record;
......@@ -69,7 +60,6 @@ package mt_endpoint_pkg is
type t_rmq_ep_rx_header is record
is_udp : std_logic;
is_raw : std_logic;
is_tlv : std_logic;
src_mac : std_logic_vector(47 downto 0);
dst_mac : std_logic_vector(47 downto 0);
ethertype : std_logic_vector(15 downto 0);
......@@ -78,8 +68,6 @@ package mt_endpoint_pkg is
src_ip : std_logic_vector(31 downto 0);
dst_ip : std_logic_vector(31 downto 0);
udp_length : std_logic_vector(15 downto 0);
tlv_type : std_logic_vector(31 downto 0);
tlv_size : std_logic_vector(15 downto 0);
end record;
type t_rmq_ep_tx_slot_config_array is
......
......@@ -58,15 +58,13 @@ architecture arch of mt_rmq_endpoint_rx is
constant c_addr_ethertype : integer := 3;
constant c_addr_dst_ip : integer := 4;
constant c_addr_dst_port : integer := 5;
constant c_addr_dst_type0 : integer := 6;
constant c_addr_dst_type1 : integer := 7;
constant c_addr_dst_type2 : integer := 8;
constant c_addr_dst_type3 : integer := 9;
constant c_BROADCAST_IP : std_logic_vector(31 downto 0) := (others => '1');
constant c_BROADCAST_MAC : std_logic_vector(47 downto 0) := (others => '1');
signal config : t_rmq_ep_rx_config;
signal match_dst_mac, match_dst_ip, match_udp, match_ethertype : std_logic;
signal match_type0, match_type1, match_type2, match_type3 : std_logic;
signal match_dst_port, match_raw, match : std_logic;
signal drop : std_logic;
......@@ -84,16 +82,11 @@ begin -- arch
case to_integer(unsigned(snk_config_i.adr(9 downto 2))) is
when c_addr_config =>
config.filter_udp <= snk_config_i.dat(0);
-- config.filter_tlv <= snk_config_i.dat(1);
config.filter_raw <= snk_config_i.dat(2);
config.filter_dst_mac <= snk_config_i.dat(3);
config.filter_ethertype <= snk_config_i.dat(4);
config.filter_dst_port <= snk_config_i.dat(5);
config.filter_dst_ip <= snk_config_i.dat(6);
config.filter_type0 <= snk_config_i.dat(7);
config.filter_type1 <= snk_config_i.dat(8);
config.filter_type2 <= snk_config_i.dat(9);
config.filter_type3 <= snk_config_i.dat(10);
config.store_header <= snk_config_i.dat(11);
config.enable <= snk_config_i.dat(31);
when c_addr_dst_mac_hi =>
......@@ -106,14 +99,6 @@ begin -- arch
config.dst_port <= snk_config_i.dat(15 downto 0);
when c_addr_ethertype =>
config.ethertype <= snk_config_i.dat(15 downto 0);
when c_addr_dst_type0 =>
config.type0 <= snk_config_i.dat(31 downto 0);
when c_addr_dst_type1 =>
config.type1 <= snk_config_i.dat(31 downto 0);
when c_addr_dst_type2 =>
config.type2 <= snk_config_i.dat(31 downto 0);
when c_addr_dst_type3 =>
config.type3 <= snk_config_i.dat(31 downto 0);
when others => null;
end case;
end if;
......@@ -133,10 +118,6 @@ begin -- arch
snk_config_o.dat(4) <= config.filter_ethertype;
snk_config_o.dat(5) <= config.filter_dst_port;
snk_config_o.dat(6) <= config.filter_dst_ip;
snk_config_o.dat(7) <= config.filter_type0;
snk_config_o.dat(8) <= config.filter_type1;
snk_config_o.dat(9) <= config.filter_type2;
snk_config_o.dat(10) <= config.filter_type3;
snk_config_o.dat(11) <= config.store_header;
snk_config_o.dat(30 downto 12) <= (others => '0');
snk_config_o.dat(31) <= config.enable;
......@@ -153,14 +134,6 @@ begin -- arch
when c_addr_ethertype =>
snk_config_o.dat(15 downto 0) <= config.ethertype;
snk_config_o.dat(31 downto 16) <= (others => '0');
when c_addr_dst_type0 =>
snk_config_o.dat <= config.type0;
when c_addr_dst_type1 =>
snk_config_o.dat <= config.type1;
when c_addr_dst_type2 =>
snk_config_o.dat <= config.type2;
when c_addr_dst_type3 =>
snk_config_o.dat <= config.type3;
when others => null;
end case;
end process p_read_config_regs;
......@@ -171,90 +144,53 @@ begin -- arch
if rst_n_i = '0' then
match <= '0';
else
match_dst_port <= '1';
match_dst_ip <= '1';
match_ethertype <= '1';
match_dst_mac <= '1';
match_udp <= '1';
match_raw <= '1';
match_ethertype <= '1';
match_dst_mac <= '1';
match_dst_ip <= '1';
match_dst_port <= '1';
match_type0 <= '1';
match_type1 <= '1';
match_type2 <= '1';
match_type3 <= '1';
if(config.filter_udp = '1') then
if config.filter_udp = '1' then
match_udp <= header_i.is_udp;
end if;
if(header_i.ethertype /= x"0800") then
match_ethertype <= '0';
end if;
if config.filter_raw = '1' then
match_raw <= header_i.is_raw;
end if;
if (config.filter_dst_port = '1') then
if (config.dst_port /= header_i.dst_port) then
match_dst_port <= '0';
end if;
if config.filter_ethertype = '1' then
if (header_i.is_udp = '1' and header_i.ethertype /= x"0800") or
(header_i.is_raw = '1' and header_i.ethertype /= config.ethertype) then
match_ethertype <= '0';
end if;
end if;
if (config.filter_dst_ip = '1') then
if (config.dst_ip /= header_i.dst_ip) then
match_dst_ip <= '0';
end if;
if config.filter_dst_mac = '1' then
if header_i.dst_mac /= c_BROADCAST_MAC and header_i.dst_mac /= config.dst_mac then
match_dst_mac <= '0';
end if;
--if (config.filter_type0 = '1') then
-- if (config.type0 /= header_i.tlv_type) then
-- match_type0 <= '0';
-- end if;
--end if;
--if (config.filter_type1 = '1') then
-- if (config.type1 /= header_i.tlv_type) then
-- match_type1 <= '0';
-- end if;
--end if;
--if (config.filter_type2 = '1') then
-- if (config.type2 /= header_i.tlv_type) then
-- match_type2 <= '0';
-- end if;
--end if;
--if (config.filter_type3 = '1') then
-- if (config.type3 /= header_i.tlv_type) then
-- match_type3 <= '0';
-- end if;
--end if;
end if;
if(config.filter_raw = '1') then
match_raw <= header_i.is_raw;
if(header_i.ethertype /= config.ethertype) then
match_ethertype <= '0';
if config.filter_dst_ip = '1' then
if header_i.dst_ip /= c_BROADCAST_IP and config.dst_ip /= header_i.dst_ip then
match_dst_ip <= '0';
end if;
end if;
if config.filter_dst_mac = '1' then
if (header_i.dst_mac /= config.dst_mac) then
match_dst_mac <= '0';
end if;
if config.filter_dst_port = '1' then
if config.dst_port /= header_i.dst_port then
match_dst_port <= '0';
end if;
end if;
match <= match_type0 and match_type1 and match_type2 and match_type3 and
match_dst_mac and match_dst_ip and match_ethertype and
match <= match_dst_mac and match_dst_ip and match_ethertype and
match_dst_port and match_udp and match_raw and config.enable;
end if;
end if;
end process;
end process p_filter_packets;
drop <= header_valid_i and not match and framer_snk_i.last;
......
......@@ -89,7 +89,7 @@ begin -- arch
end if;
end process p_write_config_regs;
p_read_config_regs : process(snk_config_i)
p_read_config_regs : process(config, snk_config_i)
begin
case to_integer(unsigned(snk_config_i.adr(9 downto 2))) is
when c_ADDR_CONFIG =>
......
......@@ -40,7 +40,6 @@ entity mt_rmq_rx_deframer is
p_header_valid_o : out std_logic;
p_is_udp_o : out std_logic;
p_is_raw_o : out std_logic;
p_is_tlv_o : out std_logic;
p_src_mac_o : out std_logic_vector(47 downto 0);
p_dst_mac_o : out std_logic_vector(47 downto 0);
p_ethertype_o : out std_logic_vector(15 downto 0);
......@@ -48,9 +47,7 @@ entity mt_rmq_rx_deframer is
p_dst_port_o : out std_logic_vector(15 downto 0);
p_src_ip_o : out std_logic_vector(31 downto 0);
p_dst_ip_o : out std_logic_vector(31 downto 0);
p_udp_length_o : out std_logic_vector(15 downto 0);
p_tlv_type_o : out std_logic_vector(31 downto 0);
p_tlv_size_o : out std_logic_vector(15 downto 0));
p_udp_length_o : out std_logic_vector(15 downto 0));
end mt_rmq_rx_deframer;
architecture arch of mt_rmq_rx_deframer is
......@@ -83,7 +80,7 @@ architecture arch of mt_rmq_rx_deframer is
return if_false;
end if;
end f_pick;
signal dummy : std_logic_vector(15 downto 0);
signal state : t_state;
......@@ -208,9 +205,5 @@ begin
end if;
end if;
end process p_fsm;
p_is_tlv_o <= '0';
end arch;
......@@ -44,11 +44,8 @@ end entity mt_rmq_rx_path;
architecture arch of mt_rmq_rx_path is
type t_mt_stream_source_out_array is array(integer range<>) of t_mt_stream_source_out;
type t_mt_stream_source_in_array is array(integer range<>) of t_mt_stream_source_in;
signal fwd_pipe : t_mt_stream_source_out_array(0 to 2);
signal rev_pipe : t_mt_stream_source_in_array(0 to 2);
signal fwd_pipe : t_mt_stream_source_out;
signal rev_pipe : t_mt_stream_source_in;
begin
......@@ -58,12 +55,11 @@ begin
rst_n_i => rst_n_i,
snk_i => snk_i,
snk_o => snk_o,
src_i => rev_pipe(0),
src_o => fwd_pipe(0),
src_i => rev_pipe,
src_o => fwd_pipe,
p_header_valid_o => p_header_valid_o,
p_is_udp_o => p_header_o.is_udp,
p_is_raw_o => p_header_o.is_raw,
p_is_tlv_o => p_header_o.is_tlv,
p_src_mac_o => p_header_o.src_mac,
p_dst_mac_o => p_header_o.dst_mac,
p_ethertype_o => p_header_o.ethertype,
......@@ -71,16 +67,14 @@ begin
p_dst_port_o => p_header_o.dst_port,
p_src_ip_o => p_header_o.src_ip,
p_dst_ip_o => p_header_o.dst_ip,
p_udp_length_o => p_header_o.udp_length,
p_tlv_type_o => p_header_o.tlv_type,
p_tlv_size_o => p_header_o.tlv_size);
p_udp_length_o => p_header_o.udp_length);
U_stream_register : entity work.mt_rmq_stream_register
port map (
clk_i => clk_i,
rst_n_i => rst_n_i,
snk_i => fwd_pipe(0),
snk_o => rev_pipe(0),
snk_i => fwd_pipe,
snk_o => rev_pipe,
src_i => src_i,
src_o => src_o);
......
......@@ -39,9 +39,20 @@ entity mock_turtle_core is
generic (
-- Message Queue and CPU configuration
g_CONFIG : t_mt_config := c_DEFAULT_MT_CONFIG;
g_CONFIG : t_mt_config := c_DEFAULT_MT_CONFIG;
-- Frequency of clk_i, in Hz
g_SYSTEM_CLOCK_FREQ : integer := 62500000;
g_SYSTEM_CLOCK_FREQ : integer := 62500000;
-- Optional instruction memory init files. Unfortunately prior to VHDL2008,
-- strings are not allowed within records, otherwise these could be embedded
-- in g_CONFIG.cpu_config.
g_CPU0_IRAM_INITF : string := "none";
g_CPU1_IRAM_INITF : string := "none";
g_CPU2_IRAM_INITF : string := "none";
g_CPU3_IRAM_INITF : string := "none";
g_CPU4_IRAM_INITF : string := "none";
g_CPU5_IRAM_INITF : string := "none";
g_CPU6_IRAM_INITF : string := "none";
g_CPU7_IRAM_INITF : string := "none";
-- Enables/disables WR support
g_WITH_WHITE_RABBIT : boolean := FALSE);
port (
......@@ -73,9 +84,23 @@ end mock_turtle_core;
architecture arch of mock_turtle_core is
------------------------------------------
-- CONSTANTS DECLARATION
------------------------------------------
-- Not elegant at all. Unfortunately, prior to VHDL2008, strings are not allowed
-- within records, otherwise these could be embedded in g_CONFIG.cpu_config.
function f_mt_cpu_iram_init_pick(idx : integer)
return string is
begin
case idx is
when 0 => return g_CPU0_IRAM_INITF;
when 1 => return g_CPU1_IRAM_INITF;
when 2 => return g_CPU2_IRAM_INITF;
when 3 => return g_CPU3_IRAM_INITF;
when 4 => return g_CPU4_IRAM_INITF;
when 5 => return g_CPU5_IRAM_INITF;
when 6 => return g_CPU6_IRAM_INITF;
when 7 => return g_CPU7_IRAM_INITF;
when others => return "none";
end case;
end function f_mt_cpu_iram_init_pick;
constant c_SMEM_REMAP_BASE_IN : t_wishbone_address_array(0 to 2) := (
0 => x"00000000",
......@@ -369,6 +394,7 @@ begin -- arch
generic map (
g_CPU_ID => i,
g_CPU_CONFIG => c_CFG,
g_CPU_IRAM_INIT => f_mt_cpu_iram_init_pick(i),
g_WITH_WHITE_RABBIT => g_WITH_WHITE_RABBIT,
g_SYSTEM_CLOCK_FREQ => g_SYSTEM_CLOCK_FREQ)
port map (
......
......@@ -144,6 +144,14 @@ package mock_turtle_pkg is
generic (
g_CONFIG : t_mt_config := c_DEFAULT_MT_CONFIG;
g_SYSTEM_CLOCK_FREQ : integer := 62500000;
g_CPU0_IRAM_INITF : string := "none";
g_CPU1_IRAM_INITF : string := "none";
g_CPU2_IRAM_INITF : string := "none";
g_CPU3_IRAM_INITF : string := "none";
g_CPU4_IRAM_INITF : string := "none";
g_CPU5_IRAM_INITF : string := "none";
g_CPU6_IRAM_INITF : string := "none";
g_CPU7_IRAM_INITF : string := "none";
g_WITH_WHITE_RABBIT : boolean := FALSE);
port (
clk_i : in std_logic;
......
......@@ -35,7 +35,6 @@ package mt_mqueue_pkg is
constant c_MT_STREAM_TAG_PAYLOAD : std_logic_vector(1 downto 0) := "01";
type t_mt_stream_sink_in is record
req : std_logic;
data : std_logic_vector(31 downto 0);
hdr : std_logic;
valid : std_logic;
......@@ -66,7 +65,7 @@ package mt_mqueue_pkg is
constant c_MT_DUMMY_SOURCE_IN : t_mt_stream_sink_out :=
('0', '0');
constant c_MT_DUMMY_SINK_IN : t_mt_stream_sink_in :=
('0', x"00000000", '0', '0', '0', '0');
(x"00000000", '0', '0', '0', '0');
constant c_MT_DUMMY_EP_CONFIG_OUT : t_mt_stream_config_out :=
("00000000000", x"00000000", '0');
......
......@@ -94,8 +94,7 @@ begin
addr => unsigned(c_mqueue_addr_header) + 8,
is_even => '1',
payload_size => (others => '0'),
is_hdr_d => 'X'
);
is_hdr_d => 'X');
else
-- Wait until a slot is ready.
snk_o <= (pkt_ready => '0',
......@@ -118,17 +117,15 @@ begin
-- Data available, store it.
outb_o <= (sel => '1',
adr => std_logic_vector(state.addr),
dat => (snk_i.data(7 downto 0)
& snk_i.data(15 downto 8)
& snk_i.data(7 downto 0)
& snk_i.data(15 downto 8)),
dat => (snk_i.data(15 downto 0)
& snk_i.data(15 downto 0)),
we => '1',
wmask => "0000");
if state.is_even = '1' then
outb_o.wmask <= "0011";
else
outb_o.wmask <= "1100";
else
outb_o.wmask <= "0011";
end if;
if snk_i.error = '1' then
......@@ -142,7 +139,7 @@ begin
if (state.is_hdr_d = '1' and snk_i.hdr = '0') then
-- end of header
outb_o.adr <= c_mqueue_addr_payload;
outb_o.wmask <= "0011";
outb_o.wmask <= "1100";
n_state.addr <= unsigned(c_mqueue_addr_payload);
n_state.state <= CLAIM;
n_state.is_even <= '0';
......
......@@ -76,8 +76,7 @@ begin
dat => (others => 'X'),
we => 'X',
wmask => "XXXX");
src_o <= (req => not inb_stat_i.empty,
data => (others => 'X'),
src_o <= (data => (others => 'X'),
hdr => 'X',
valid => '0',
last => 'X',
......@@ -87,8 +86,7 @@ begin
pkt_last_addr => (others => 'X'));
else
n_state <= state;
src_o <= (req => not inb_stat_i.empty,
data => (others => 'X'),
src_o <= (data => (others => 'X'),
hdr => 'X',
valid => '0',
last => 'X',
......@@ -134,8 +132,7 @@ begin
unsigned("1" & inb_i.dat(10 downto 0) & "00" ) - 4;
end if;
src_o <= (req => not inb_stat_i.empty,
data => inb_i.dat,
src_o <= (data => inb_i.dat,
hdr => '1',
valid => '1',
last => '0',
......@@ -174,8 +171,7 @@ begin
wmask => "XXXX");
-- Send payload word
src_o <= (req => not inb_stat_i.empty,
data => x"0000" & inb_i.dat(31 downto 16),
src_o <= (data => x"0000" & inb_i.dat(31 downto 16),
hdr => '0',
valid => '1',
last => '0',
......@@ -197,8 +193,7 @@ begin
wmask => "XXXX");
-- Send payload word
src_o <= (req => not inb_stat_i.empty,
data => x"0000" & inb_i.dat(15 downto 0) ,
src_o <= (data => x"0000" & inb_i.dat(15 downto 0) ,
hdr => '0',
valid => '1',
last => payload_last,
......
......@@ -78,9 +78,9 @@ class MockTurtleDriver;
task mdisplay ( string str );
string tmp;
if (this.name == "")
tmp = str;
tmp = $sformatf("<%t> %s", $realtime, str);
else
tmp = $sformatf("[%s] %s", this.name, str);
tmp = $sformatf("[%s] <%t> %s", this.name, $realtime, str);
$display (tmp);
endtask // mdisplay
......@@ -157,9 +157,6 @@ class MockTurtleDriver;
csr.notify_queue[core] = {};
endtask // get_cpu_notifications
task handle_hmq_in_irq ();
endtask // handle_hmq_in_irq
task hmq_receive_message (ref MQueueMsg msg);
msg = hmq[msg.core].receive_message (msg.slot);
endtask // hmq_receive_message
......@@ -169,7 +166,6 @@ class MockTurtleDriver;
endtask // hmq_send_message
task hmq_purge (int core, int slot);
hmq[core].purge (slot);
endtask // hmq_purge
......
......@@ -59,9 +59,9 @@ class MTCPUControl;
task mdisplay ( string str );
string tmp;
if (this.name == "")
tmp = str;
tmp = $sformatf("<%t> %s", $realtime, str);
else
tmp = $sformatf("[%s] %s", this.name, str);
tmp = $sformatf("[%s] <%t> %s", this.name, $realtime, str);
$display (tmp);
endtask // mdisplay
......
......@@ -129,16 +129,20 @@ class MQueueHost;
MQueueMsg msg;
u32_queue hdr;
csr.hmq_select ( core, slot );
msg = slots_out[slot].pop_back();
hdr = msg.hdr_pack ();
outgoing_write (`MQUEUE_SLOT_COMMAND, `MQUEUE_CMD_CLAIM);
for (int i = 0; i < msg.header.size(); i++)
for (int i = 0; i < hdr.size(); i++)
begin
outgoing_write (`MQUEUE_SLOT_HEADER + i * 4, msg.header[i]);
outgoing_write (`MQUEUE_SLOT_HEADER + i * 4, hdr[i]);
end
for (int i = 0; i < msg.data.size(); i++)
for (int i = 0; i < msg.header.len; i++)
begin
outgoing_write (`MQUEUE_SLOT_DATA + i * 4, msg.data[i]);
end
......@@ -152,18 +156,23 @@ class MQueueHost;
uint32_t val;
uint32_t hdr[$];
csr.hmq_select ( core, slot );
msg = new (core, slot);
msg = new ( core, slot );
hdr = {};
incoming_read (`MQUEUE_SLOT_HEADER + 0, val );
msg.header[0] = val;
hdr[0] = val;
incoming_read (`MQUEUE_SLOT_HEADER + 4, val );
msg.header[1] = val;
hdr[1] = val;
incoming_read (`MQUEUE_SLOT_HEADER + 8, val );
msg.header[2] = val;
hdr[2] = val;
msg.set_header ( hdr );
for (int i = 0; i < msg.header[1] & 32'h0000ffff; i++)
for (int i = 0; i < msg.header.len; i++)
begin
incoming_read (`MQUEUE_SLOT_DATA + 4*i, val);
msg.data.push_back(val);
......
......@@ -26,40 +26,78 @@
`ifndef __MT_MQUEUE_MSG_INCLUDED
`define __MT_MQUEUE_MSG_INCLUDED
typedef uint32_t u32_queue[$];
typedef struct {
uint32_t app_id;
uint32_t flags;
uint32_t msg_id;
uint32_t len;
uint32_t sync_id;
uint32_t seq;
} mqueue_msg_header;
class MQueueMsg;
int core;
int slot;
uint32_t header[$];
uint32_t data[$];
mqueue_msg_header header;
u32_queue data;
function new (int core = 0, int slot = 0);
function new ( int core = 0, int slot = 0,
u32_queue header = {},
u32_queue data = {});
this.core = core;
this.slot = slot;
this.header = {};
this.data = {};
if ( header.size() )
this.header = hdr_unpack ( header );
else
this.header = '{0, 0, 0, 0, 0, 0};
this.data = data;
endfunction // new
function mqueue_msg_header hdr_unpack (u32_queue header );
mqueue_msg_header hdr;
if ( header.size() > 2 )
begin
hdr.app_id = header[0] & 32'h0000ffff;
hdr.flags = (header[0] & 32'h00ff0000) >> 16;
hdr.msg_id = (header[0] & 32'hff000000) >> 24;
hdr.len = header[1] & 32'h0000ffff;
hdr.sync_id = (header[1] & 32'hffff0000) >> 16;
hdr.seq = header[2];
end
else
hdr = '{0, 0, 0, 0, 0, 0};
if ( header.size() != 3 )
$warning ( "incorrect message header size %0d", header.size() );
return hdr;
endfunction // hdr_unpack
task set_header ( u32_queue header );