Commit 0a65f5dd authored by Wesley W. Terpstra's avatar Wesley W. Terpstra

eca: datatype fattening patch

This patch does five things:
  - Increase param from 32 to 64 bits (CCT wanted more space)
  - Added a timing extension field (tef) to include fine delay & future proof
  - Rework the register layout to accomodate these changes
  - Flatten all channels into a single register bank
  - Sort old+new tuple elements alphabetically
parent 2fb2f907
This diff is collapsed.
......@@ -46,13 +46,13 @@
-- There are c_scanners* parallel Scan processes, which partition the table vertically.
-- A timestamp = "fff..." indicates that the entry is invalid/free.
--
-- /=============================\
-- | time | time tag param event |
-- | time | time tag param event |
-- |------| |
-- | time | time tag param event |
-- | time | time tag param event |
-- \=============================/
-- /=================================\
-- | time | event param tag tef time |
-- | time | event param tag tef time |
-- |------| |
-- | time | event param tag tef time |
-- | time | event param tag tef time |
-- \=================================/
-- ^--- Data component of table (td)
-- ^---- scan components (ts0, ts1); used by scanner0 and scanner1
......@@ -160,16 +160,18 @@ architecture rtl of eca_channel is
signal td_manage_write : std_logic;
signal td_manage_index : t_table_index;
signal td_manage_valid : std_logic;
signal td_manage_time : t_time;
signal td_manage_tag : t_tag;
signal td_manage_param : t_param;
signal td_manage_event : t_event;
signal td_manage_param : t_param;
signal td_manage_tag : t_tag;
signal td_manage_tef : t_tef;
signal td_manage_time : t_time;
signal td_dispatch_index : t_table_index;
signal td_dispatch_valid : std_logic;
signal td_dispatch_time : t_time;
signal td_dispatch_tag : t_tag;
signal td_dispatch_param : t_param;
signal td_dispatch_event : t_event;
signal td_dispatch_param : t_param;
signal td_dispatch_tag : t_tag;
signal td_dispatch_tef : t_tef;
signal td_dispatch_time : t_time;
-- Free signals
signal fw_manage_free : std_logic;
......@@ -222,18 +224,20 @@ architecture rtl of eca_channel is
signal manage_write : std_logic;
signal manage_valid : std_logic;
signal manage_index : t_table_index;
signal manage_time : t_time;
signal manage_tag : t_tag;
signal manage_param : t_param;
signal manage_event : t_event;
signal manage_param : t_param;
signal manage_tag : t_tag;
signal manage_tef : t_tef;
signal manage_time : t_time;
constant cd_valid_offset : natural := 0;
subtype cd_time_range is natural range c_time_bits +cd_valid_offset downto cd_valid_offset +1;
subtype cd_tag_range is natural range c_tag_bits +cd_time_range'left downto cd_time_range'left +1;
subtype cd_param_range is natural range c_param_bits+cd_tag_range'left downto cd_tag_range'left +1;
subtype cd_event_range is natural range c_event_bits+cd_param_range'left downto cd_param_range'left +1;
subtype cd_data_type is std_logic_vector(cd_event_range);
subtype cd_event_range is natural range c_event_bits+cd_valid_offset downto cd_valid_offset +1;
subtype cd_param_range is natural range c_param_bits+cd_event_range'left downto cd_event_range'left +1;
subtype cd_tag_range is natural range c_tag_bits +cd_param_range'left downto cd_param_range'left +1;
subtype cd_tef_range is natural range c_tef_bits +cd_tag_range'left downto cd_tag_range'left +1;
subtype cd_time_range is natural range c_time_bits +cd_tef_range'left downto cd_tef_range'left +1;
subtype cd_data_type is std_logic_vector(cd_time_range);
constant cd_data_bits : natural := cd_data_type'left + 1; --'
begin
......@@ -288,17 +292,19 @@ begin
w_en_i => td_manage_write,
w_addr_i => td_manage_index,
w_data_i(cd_valid_offset)=> td_manage_valid,
w_data_i(cd_time_range) => td_manage_time,
w_data_i(cd_tag_range) => td_manage_tag,
w_data_i(cd_param_range) => td_manage_param,
w_data_i(cd_event_range) => td_manage_event,
w_data_i(cd_param_range) => td_manage_param,
w_data_i(cd_tag_range) => td_manage_tag,
w_data_i(cd_tef_range) => td_manage_tef,
w_data_i(cd_time_range) => td_manage_time,
r_clk_i => clk_i,
r_addr_i => td_dispatch_index,
r_data_o(cd_valid_offset)=> td_dispatch_valid,
r_data_o(cd_time_range) => td_dispatch_time,
r_data_o(cd_tag_range) => td_dispatch_tag,
r_data_o(cd_event_range) => td_dispatch_event,
r_data_o(cd_param_range) => td_dispatch_param,
r_data_o(cd_event_range) => td_dispatch_event);
r_data_o(cd_tag_range) => td_dispatch_tag,
r_data_o(cd_tef_range) => td_dispatch_tef,
r_data_o(cd_time_range) => td_dispatch_time);
-- The free queue
F : eca_sdp
......@@ -368,16 +374,18 @@ begin
td_dispatch_index <= addr_i when freeze_i='1' else dispatch_mux_record.index;
channel_o.valid <= dispatch_valid1;
channel_o.time <= td_dispatch_time;
channel_o.tag <= td_dispatch_tag;
channel_o.param <= td_dispatch_param;
channel_o.event <= td_dispatch_event;
channel_o.param <= td_dispatch_param;
channel_o.tag <= td_dispatch_tag;
channel_o.tef <= td_dispatch_tef;
channel_o.time <= td_dispatch_time;
inspect_o.valid <= td_dispatch_valid;
inspect_o.time <= td_dispatch_time;
inspect_o.tag <= td_dispatch_tag;
inspect_o.param <= td_dispatch_param;
inspect_o.event <= td_dispatch_event;
inspect_o.param <= td_dispatch_param;
inspect_o.tag <= td_dispatch_tag;
inspect_o.tef <= td_dispatch_tef;
inspect_o.time <= td_dispatch_time;
dispatch_manage_kill <= dispatch_valid1;
dispatch_manage_index <= dispatch_index1;
......@@ -505,10 +513,11 @@ begin
end if;
manage_valid <= not drain_i and channel_i.valid;
manage_time <= channel_i.time;
manage_tag <= channel_i.tag;
manage_param <= channel_i.param;
manage_event <= channel_i.event;
manage_param <= channel_i.param;
manage_tag <= channel_i.tag;
manage_tef <= channel_i.tef;
manage_time <= channel_i.time;
end if;
end process;
......@@ -532,9 +541,10 @@ begin
td_manage_write <= manage_write;
td_manage_index <= manage_index;
td_manage_valid <= manage_valid;
td_manage_time <= manage_time;
td_manage_tag <= manage_tag;
td_manage_param <= manage_param;
td_manage_event <= manage_event;
td_manage_param <= manage_param;
td_manage_tag <= manage_tag;
td_manage_tef <= manage_tef;
td_manage_time <= manage_time;
end rtl;
......@@ -32,13 +32,13 @@ package eca_pkg is
constant c_eca_sdb : t_sdb_device := (
abi_class => x"0000", -- undocumented device
abi_ver_major => x"01",
abi_ver_major => x"02",
abi_ver_minor => x"00",
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"00000000000003ff",
addr_last => x"000000000000007f",
product => (
vendor_id => x"0000000000000651",
device_id => x"8752bf44",
......@@ -46,9 +46,9 @@ package eca_pkg is
date => x"20130204",
name => "ECA_UNIT:CONTROL ")));
constant c_eca_evt_sdb : t_sdb_device := (
constant c_eca_event_sdb : t_sdb_device := (
abi_class => x"0000", -- undocumented device
abi_ver_major => x"01",
abi_ver_major => x"02",
abi_ver_minor => x"00",
wbd_endian => c_sdb_endian_big,
wbd_width => x"4", -- 32-bit port granularity
......@@ -62,32 +62,53 @@ package eca_pkg is
date => x"20130204",
name => "ECA_UNIT:EVENTS_IN ")));
constant c_time_bits : natural := 64;
constant c_eca_queue_sdb : t_sdb_device := (
abi_class => x"0000", -- undocumented device
abi_ver_major => x"01",
abi_ver_minor => x"00",
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"000000000000003f",
product => (
vendor_id => x"0000000000000651",
device_id => x"9bfa4560",
version => x"00000001",
date => x"20131107",
name => "ECA_UNIT:ACTION_QUE")));
constant c_event_bits : natural := 64;
constant c_param_bits : natural := 32;
constant c_param_bits : natural := 64;
constant c_tag_bits : natural := 32;
constant c_tef_bits : natural := 32;
constant c_time_bits : natural := 64;
subtype t_ascii is std_logic_vector(6 downto 0);
subtype t_time is std_logic_vector(c_time_bits-1 downto 0);
subtype t_event is std_logic_vector(c_event_bits-1 downto 0);
subtype t_param is std_logic_vector(c_param_bits-1 downto 0);
subtype t_tag is std_logic_vector(c_tag_bits-1 downto 0);
subtype t_tef is std_logic_vector(c_tef_bits-1 downto 0);
subtype t_time is std_logic_vector(c_time_bits-1 downto 0);
type t_channel is record
valid : std_logic;
time : t_time;
tag : t_tag;
param : t_param;
event : t_event;
param : t_param;
tag : t_tag;
tef : t_tef;
time : t_time; -- high bit set if late
end record t_channel;
type t_name is array(63 downto 0) of t_ascii;
type t_name_array is array(natural range <>) of t_name;
type t_channel_array is array(natural range <>) of t_channel;
type t_time_array is array(natural range <>) of t_time;
type t_tag_array is array(natural range <>) of t_tag;
type t_param_array is array(natural range <>) of t_param;
type t_event_array is array(natural range <>) of t_event;
type t_param_array is array(natural range <>) of t_param;
type t_tag_array is array(natural range <>) of t_tag;
type t_tef_array is array(natural range <>) of t_tef;
type t_time_array is array(natural range <>) of t_time;
-- Convert a string into a name (aka, pad it)
function f_name(name : string) return t_name;
......@@ -141,8 +162,9 @@ package eca_pkg is
e_stb_i : in std_logic;
e_stall_o : out std_logic;
e_event_i : in t_event;
e_time_i : in t_time;
e_param_i : in t_param;
e_tef_i : in t_tef;
e_time_i : in t_time;
e_index_o : out std_logic_vector(7 downto 0);
-- ECA control registers
c_clk_i : in std_logic;
......@@ -156,7 +178,23 @@ package eca_pkg is
a_channel_o : out t_channel_array(g_num_channels-1 downto 0));
end component;
-- Execute a WB write to address "tag" with data "param"
-- Put the action into a queue and fire an interrupt to 'tag'
component eca_queue_channel is
port(
a_clk_i : in std_logic;
a_rst_n_i : in std_logic;
a_channel_i : in t_channel;
q_clk_i : in std_logic;
q_rst_n_i : in std_logic;
q_slave_i : in t_wishbone_slave_in;
q_slave_o : out t_wishbone_slave_out;
i_clk_i : in std_logic;
i_rst_n_i : in std_logic;
i_master_o : out t_wishbone_master_out;
i_master_i : in t_wishbone_master_in);
end component;
-- Put low bits of param to address tag
component eca_wb_channel is
port(
clk_i : in std_logic;
......@@ -166,7 +204,7 @@ package eca_pkg is
master_i : in t_wishbone_master_in);
end component;
-- Set bits selected by "tag" to value in "param"
-- Set gpio bits on/off as specified in channel_i.tag
component eca_gpio_channel is
port(
clk_i : in std_logic;
......@@ -276,8 +314,9 @@ package eca_pkg is
e_stb_o : out std_logic;
e_stall_i : in std_logic;
e_event_o : out t_event;
e_time_o : out t_time;
e_param_o : out t_param;
e_tef_o : out t_tef;
e_time_o : out t_time;
e_index_i : in std_logic_vector(7 downto 0));
end component;
......@@ -292,16 +331,18 @@ package eca_pkg is
e_stall_o : out std_logic;
e_page_i : in std_logic;
e_event_i : in t_event;
e_time_i : in t_time;
e_param_i : in t_param;
e_tef_i : in t_tef;
e_time_i : in t_time;
-- Feed located event rules to the walker
w_stb_o : out std_logic;
w_stall_i : in std_logic;
w_page_o : out std_logic;
w_first_o : out std_logic_vector(g_log_table_size-1 downto 0);
w1_event_o : out t_event;
w1_time_o : out t_time;
w1_param_o : out t_param;
w1_tef_o : out t_tef;
w1_time_o : out t_time;
-- Access the search table
t_clk_i : in std_logic;
t_page_i : in std_logic;
......@@ -328,8 +369,9 @@ package eca_pkg is
b_page_i : in std_logic;
b_first_i : in std_logic_vector(g_log_table_size-1 downto 0);
b1_event_i : in t_event;
b1_time_i : in t_time;
b1_param_i : in t_param;
b1_tef_i : in t_tef;
b1_time_i : in t_time;
-- Outputs for the channel queue
q_channel_o : out t_channel_array (g_num_channels-1 downto 0);
q_full_i : in std_logic_vector(g_num_channels-1 downto 0);
......
......@@ -44,16 +44,18 @@ entity eca_search is
e_stall_o : out std_logic;
e_page_i : in std_logic;
e_event_i : in t_event;
e_time_i : in t_time;
e_param_i : in t_param;
e_tef_i : in t_tef;
e_time_i : in t_time;
-- Feed located event rules to the walker
w_stb_o : out std_logic;
w_stall_i : in std_logic;
w_page_o : out std_logic;
w_first_o : out std_logic_vector(g_log_table_size-1 downto 0);
w1_event_o : out t_event;
w1_time_o : out t_time;
w1_param_o : out t_param;
w1_tef_o : out t_tef;
w1_time_o : out t_time;
-- Access the search table
t_clk_i : in std_logic;
t_page_i : in std_logic;
......@@ -84,8 +86,9 @@ architecture rtl of eca_search is
-- Stage 0 registers+signals
signal r0_page : std_logic;
signal r0_event : t_event;
signal r0_time : t_time;
signal r0_param : t_param;
signal r0_tef : t_tef;
signal r0_time : t_time;
signal r0_known : t_table_ptr;
signal r0_try : t_table_ptr := (others => '0');
signal r0_state : t_state := input;
......@@ -97,8 +100,9 @@ architecture rtl of eca_search is
-- Stage 1 registers+signals
signal r1_page : std_logic;
signal r1_event : t_event;
signal r1_time : t_time;
signal r1_param : t_param;
signal r1_tef : t_tef;
signal r1_time : t_time;
signal r1_known : t_table_ptr;
signal r1_try : t_table_ptr := (others => '0');
signal r1_state : t_state := input;
......@@ -113,8 +117,9 @@ architecture rtl of eca_search is
-- Stage 2 registers+signals
signal r2_page : std_logic;
signal r2_event : t_event;
signal r2_time : t_time;
signal r2_param : t_param;
signal r2_tef : t_tef;
signal r2_time : t_time;
signal r2_known : t_table_ptr;
signal r2_try : t_table_ptr := (others => '0');
signal r2_state : t_state := input;
......@@ -126,8 +131,9 @@ architecture rtl of eca_search is
-- Stage 3 registers+signals
signal r3_page : std_logic;
signal r3_event : t_event;
signal r3_time : t_time;
signal r3_param : t_param;
signal r3_tef : t_tef;
signal r3_time : t_time;
signal r3_known : t_table_ptr;
signal r3_try : t_table_ptr := (others => '0');
signal r3_state : t_state := input;
......@@ -229,23 +235,25 @@ begin
-- 0: probe => output
-- 1: compare first w_stb_o
-- 2: ... e_stall_o => input
-- 3: less page/event/time/param => search
-- 3: less page/event/param/tef/time => search
main : process(clk_i) is
begin
if rising_edge(clk_i) then
r0_page <= r3_page;
r0_event <= r3_event;
r0_time <= r3_time;
r0_param <= r3_param;
r0_tef <= r3_tef;
r0_time <= r3_time;
r0_known <= s3_known;
r0_try <= s3_try;
r0_state <= s3_state;
r1_page <= r0_page;
r1_event <= r0_event;
r1_time <= r0_time;
r1_param <= r0_param;
r1_tef <= r0_tef;
r1_time <= r0_time;
r1_known <= r0_known;
-- A boring pipeline-stage: a good place to feed in the reset
if rst_n_i = '0' then
......@@ -263,8 +271,9 @@ begin
r2_page <= r1_page;
r2_event <= r1_event;
r2_time <= r1_time;
r2_param <= r1_param;
r2_tef <= r1_tef;
r2_time <= r1_time;
r2_known <= r1_known;
r2_try <= r1_try;
r2_state <= s1_state;
......@@ -274,8 +283,9 @@ begin
if e_stb_i = '1' and r2_stall = '0' then
r3_page <= e_page_i;
r3_event <= e_event_i;
r3_time <= e_time_i;
r3_param <= e_param_i;
r3_tef <= e_tef_i;
r3_time <= e_time_i;
r3_known <= (others => '0');
r3_try <= r2_try;
r3_state <= search;
......@@ -285,8 +295,9 @@ begin
else
r3_page <= r2_page;
r3_event <= r2_event;
r3_time <= r2_time;
r3_param <= r2_param;
r3_tef <= r2_tef;
r3_time <= r2_time;
r3_known <= r2_known;
r3_try <= r2_try;
r3_state <= r2_state;
......@@ -310,7 +321,8 @@ begin
w_page_o <= r1_page;
w_first_o <= r1_first;
w1_event_o <= r2_event;
w1_time_o <= r2_time;
w1_param_o <= r2_param;
w1_tef_o <= r2_tef;
w1_time_o <= r2_time;
end rtl;
......@@ -44,8 +44,9 @@ entity eca_walker is
b_page_i : in std_logic;
b_first_i : in std_logic_vector(g_log_table_size-1 downto 0);
b1_event_i : in t_event; -- all one cycle AFTER the b_stb_i
b1_time_i : in t_time;
b1_param_i : in t_param;
b1_tef_i : in t_tef;
b1_time_i : in t_time;
-- Outputs for the channel queue
q_channel_o : out t_channel_array (g_num_channels-1 downto 0);
q_full_i : in std_logic_vector(g_num_channels-1 downto 0);
......@@ -96,8 +97,9 @@ architecture rtl of eca_walker is
signal r_w_page : std_logic;
signal r_w_addr : t_table_ptr;
signal r_w_event : t_event;
signal r_w_time : t_time;
signal r_w_param : t_param;
signal r_w_tef : t_tef;
signal r_w_time : t_time;
-- Walking signals
signal s_w_active : std_logic;
......@@ -109,6 +111,7 @@ architecture rtl of eca_walker is
signal r3_a_event : t_event;
signal r3_a_param : t_param;
signal r3_a_tag : t_tag;
signal r3_a_tef : t_tef;
signal r3_a_channel : t_channel_id;
signal r3_a_valid : std_logic;
......@@ -118,12 +121,14 @@ architecture rtl of eca_walker is
signal r2_a_event : t_event;
signal r2_a_param : t_param;
signal r2_a_tag : t_tag;
signal r2_a_tef : t_tef;
signal r2_a_channel : t_channel_id;
signal r2_a_valid : std_logic;
signal r1_a_event : t_event;
signal r1_a_param : t_param;
signal r1_a_tag : t_tag;
signal r1_a_tef : t_tef;
signal r1_a_channel : t_channel_id;
signal r1_a_validv : std_logic_vector(g_num_channels-1 downto 0);
......@@ -231,8 +236,9 @@ begin
r_w_latch <= b_stb_i and not s_w_active and not r_stall;
if r_w_latch = '1' then
r_w_event <= b1_event_i;
r_w_time <= b1_time_i;
r_w_param <= b1_param_i;
r_w_tef <= b1_tef_i;
r_w_time <= b1_time_i;
end if;
end if;
end process;
......@@ -249,9 +255,9 @@ begin
b_stall_o <= s_w_active or r_stall;
-- Adjust the timestamp and push out the channels; pipelined:
-- t3: event(3) param(3) tag(3) event_time offset_time valid(3)
-- t2: event(2) param(2) tag(2) ... pipeline ... valid(2)
-- t1: event(1) param(1) tag(1) ... pipeline ... valid1(*) stall
-- t3: event(3) param(3) tag(3) tef(3) event_time offset_time valid(3)
-- t2: event(2) param(2) tag(2) tef(2) ... pipeline ... valid(2)
-- t1: event(1) param(1) tag(1) tef(1) ... pipeline ... valid1(*) stall
-- t0: channel_i.* latched by eca_channel
adjust : process(clk_i) is
begin
......@@ -263,10 +269,12 @@ begin
if r_w_latch = '1' then
r3_a_event <= b1_event_i;
r3_a_param <= b1_param_i;
r3_a_tef <= b1_tef_i;
r3_a_event_time <= b1_time_i;
else
r3_a_event <= r_w_event;
r3_a_param <= r_w_param;
r3_a_tef <= r_w_tef;
r3_a_event_time <= r_w_time;
end if;
......@@ -279,12 +287,14 @@ begin
r2_a_event <= r3_a_event;
r2_a_param <= r3_a_param;
r2_a_tag <= r3_a_tag;
r2_a_tef <= r3_a_tef;
r2_a_channel <= r3_a_channel;
r2_a_valid <= r3_a_valid;
r1_a_event <= r2_a_event;
r1_a_param <= r2_a_param;
r1_a_tag <= r2_a_tag;
r1_a_tef <= r2_a_tef;
r1_a_channel <= r2_a_channel;
for i in 0 to g_num_channels-1 loop
......@@ -313,10 +323,11 @@ begin
channels : for i in 0 to g_num_channels-1 generate
q_channel_o(i).valid <= r1_a_validv(i) and not r_stall;
q_channel_o(i).time <= s1_a_action_time;
q_channel_o(i).tag <= r1_a_tag;
q_channel_o(i).param <= r1_a_param;
q_channel_o(i).event <= r1_a_event;
q_channel_o(i).param <= r1_a_param;
q_channel_o(i).tag <= r1_a_tag;
q_channel_o(i).tef <= r1_a_tef;
q_channel_o(i).time <= s1_a_action_time;
end generate;
end rtl;
......@@ -88,7 +88,7 @@ begin
r_cyc <= '1';
r_stb <= '1';
master_o.adr <= channel_i.tag;
master_o.dat <= channel_i.param;
master_o.dat <= channel_i.param(31 downto 0);
end if;
end if;
end if;
......
......@@ -4,9 +4,9 @@
--!
--! Copyright (C) 2013 GSI Helmholtz Centre for Heavy Ion Research GmbH
--!
--! Feed chunks of 5 words in from the Wishbone clock domain.
--! If the queue cannot fit 5 words, spit out errors until cycle end.
--! If a cycle terminates without writing 5 words, discard partial write.
--! Feed chunks of 8 words in from the Wishbone clock domain.
--! If the queue cannot fit 8 words, spit out errors until cycle end.
--! If a cycle terminates without writing 8 words, discard partial write.
--!
--------------------------------------------------------------------------------
--! This library is free software; you can redistribute it and/or
......@@ -41,8 +41,9 @@ entity eca_wb_event is
e_stb_o : out std_logic;
e_stall_i : in std_logic;
e_event_o : out t_event;
e_time_o : out t_time;
e_param_o : out t_param;
e_tef_o : out t_tef;
e_time_o : out t_time;
e_index_i : in std_logic_vector(7 downto 0));
end eca_wb_event;
......@@ -52,13 +53,13 @@ architecture rtl of eca_wb_event is
attribute altera_attribute of rtl : architecture is "-name AUTO_SHIFT_REGISTER_RECOGNITION OFF";
-- We track two kinds of pointers:
-- Event pointers count completed writes of 5 words
-- Event pointers count completed writes of 8 words
-- Word pointers are indexes into the FIFO
--
-- At any point in time, these event pointer relationships hold:
-- re_sent <= re_ready <= rw_ready <= rw_limit <= rw_sent+4
-- re_sent <= re_ready <= rw_ready <= rw_limit <= rw_sent+7
-- where re_ready is an old value of rw_ready; behind only by clock-crossing delay
-- and rw_limit is an old value of rw_sent+4; behind by 1 clock cycle
-- and rw_limit is an old value of rw_sent+7; behind by 1 clock cycle
-- and rw_sent is an old value of re_sent; behind only by clock-crossing delay
constant c_addr1_bits : natural := 5;
......@@ -67,7 +68,7 @@ architecture rtl of eca_wb_event is
subtype t_addr1 is unsigned(c_addr1_bits-1 downto 0);
subtype t_addr5 is unsigned(c_addr5_bits-1 downto 0);
type t_state is (S0, S1, S2, S3, S4, SERR);
type t_state is (S0, S1, S2, S3, S4, S5, S6, S7, SERR);
-- Registers in clock domain w_clk_i
signal rw_ready_gray : t_addr5;
......@@ -130,7 +131,7 @@ begin
rw0_sent_gray <= rw1_sent_gray;
rw_sent <= unsigned(f_eca_gray_decode(std_logic_vector(rw0_sent_gray), 1));
rw_limit <= rw_sent + 4;
rw_limit <= rw_sent + 7;
vw_addr1 := rw_addr + 1;
w_slave_o.ACK <= '0';
......@@ -179,6 +180,21 @@ begin
rw_addr <= vw_addr1;
when S4 =>
rw_state <= S5;
w_slave_o.ACK <= '1';
rw_addr <= vw_addr1;
when S5 =>
rw_state <= S6;
w_slave_o.ACK <= '1';
rw_addr <= vw_addr1;
when S6 =>
rw_state <= S7;
w_slave_o.ACK <= '1';
rw_addr <= vw_addr1;
when S7 =>
rw_state <= S0;
w_slave_o.ACK <= '1';
rw_addr <= vw_addr1;
......@@ -215,8 +231,9 @@ begin
if e_rst_n_i = '0' then
e_event_o <= (others => '0');
e_time_o <= (others => '0');
e_param_o <= (others => '0');
e_tef_o <= (others => '0');
e_time_o <= (others => '0');
re_sent <= (others => '0');
re_state <= S0;
......@@ -242,17 +259,29 @@ begin
when S1 =>
e_event_o(31 downto 0) <= se_data;
re_state <= S2;
when S2 =>
e_time_o(63 downto 32) <= se_data;
e_param_o(63 downto 32) <= se_data;
re_state <= S3;
when S3 =>
e_time_o(31 downto 0) <= se_data;
e_param_o(31 downto 0) <= se_data;
re_state <= S4;
when S4 =>
e_param_o(31 downto 0) <= se_data;
-- reserved bits against future changes
re_state <= S5;
when S5 =>
e_tef_o(31 downto 0) <= se_data;
re_state <= S6;
when S6 =>
e_time_o(63 downto 32) <= se_data;
re_state <= S7;
when S7 =>
e_time_o(31 downto 0) <= se_data;
re_state <= S0;
re_stb <= '1';
......
......@@ -68,14 +68,16 @@ architecture rtl of wr_eca is
signal sa_stb : std_logic_vector(g_num_streams-1 downto 0);
signal sa_event : t_event_array (g_num_streams-1 downto 0);
signal sa_time : t_time_array (g_num_streams-1 downto 0);
signal sa_param : t_param_array (g_num_streams-1 downto 0);
signal sa_tef : t_tef_array (g_num_streams-1 downto 0);
signal sa_time : t_time_array (g_num_streams-1 downto 0);
signal sa_full_stb : std_logic_vector(g_num_streams downto 0);
signal sa_full_stall : std_logic_vector(g_num_streams downto 0);
signal sa_full_event : t_event_array (g_num_streams downto 0);
signal sa_full_time : t_time_array (g_num_streams downto 0);
signal sa_full_param : t_param_array (g_num_streams downto 0);
signal sa_full_tef : t_tef_array (g_num_streams downto 0);
signal sa_full_time : t_time_array (g_num_streams downto 0);
begin
......@@ -96,8 +98,9 @@ begin
e_stb_i => sa_full_stb (0),
e_stall_o => sa_full_stall(0),
e_event_i => sa_full_event(0),
e_time_i => sa_full_time (0),
e_param_i => sa_full_param(0),
e_tef_i => sa_full_tef (0),
e_time_i => sa_full_time (0),
e_index_o => sa_index,
c_clk_i => c_clk_i,
c_rst_n_i => c_rst_n_i,
......@@ -117,8 +120,9 @@ begin
sa_full_stb (g_num_streams) <= '0';
sa_full_event(g_num_streams) <= (others => '-');
sa_full_time (g_num_streams) <= (others => '-');
sa_full_param(g_num_streams) <= (others => '-');
sa_full_tef (g_num_streams) <= (others => '-');
sa_full_time (g_num_streams) <= (others => '-');
-- Priority access goes to #0
Sx : for stream in 0 to g_num_streams-1 generate
......@@ -134,15 +138,17 @@ begin
e_stb_o => sa_stb (stream),
e_stall_i => sa_full_stall(stream),
e_event_o => sa_event(stream),
e_time_o => sa_time (stream),
e_param_o => sa_param(stream),
e_tef_o => sa_tef (stream),
e_time_o => sa_time (stream),
e_index_i => sa_index);
sa_full_stall(stream+1) <= sa_stb (stream) or sa_full_stall(stream);
sa_full_stb (stream) <= sa_stb (stream) or sa_full_stb (stream+1);
sa_full_event(stream) <= sa_event(stream) when sa_stb(stream)='1' else sa_full_event(stream+1);
sa_full_time (stream) <= sa_time (stream) when sa_stb(stream)='1' else sa_full_time (stream+1);
sa_full_param(stream) <= sa_param(stream) when sa_stb(stream)='1' else sa_full_param(stream+1);
sa_full_tef (stream) <= sa_tef (stream) when sa_stb(stream)='1' else sa_full_tef (stream+1);
sa_full_time (stream) <= sa_time (stream) when sa_stb(stream)='1' else sa_full_time (stream+1);
end generate;
end rtl;
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