Commit 49485d4f authored by Wesley W. Terpstra's avatar Wesley W. Terpstra

eca: boilerplate to include a conflict counter

parent 25e16479
......@@ -118,7 +118,8 @@ struct ActionChannel {
bool frozen; /* Queue is frozen; nothing enters/exits */
uint16_t fill; /* Current number of entries in the queue */
uint16_t max_fill; /* Maximum entries in the queue since reset */
uint32_t valid; /* How many valid actions have been sent */
uint32_t valid; /* How many valid actions have been sent (includes late+conflict) */
uint32_t conflict; /* How many conflicting actions have been sent */
uint32_t late; /* How many late actions have been sent */
/* ------------------------------------------------------------------- */
......
This diff is collapsed.
......@@ -377,21 +377,23 @@ begin
td_dispatch_index <= addr_i when freeze_i='1' else dispatch_mux_record.index;
channel_o.valid <= dispatch_valid1;
channel_o.late <= td_dispatch_late;
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.late <= td_dispatch_late;
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;
channel_o.valid <= dispatch_valid1;
channel_o.conflict <= '0'; -- !!!;
channel_o.late <= td_dispatch_late;
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.conflict <= '0';
inspect_o.late <= td_dispatch_late;
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;
......
......@@ -92,13 +92,14 @@ package eca_pkg is
subtype t_time is std_logic_vector(c_time_bits-1 downto 0);
type t_channel is record
valid : std_logic;
late : std_logic;
event : t_event;
param : t_param;
tag : t_tag;
tef : t_tef;
time : t_time; -- high bit set if late
valid : std_logic;
conflict : std_logic;
late : std_logic;
event : t_event;
param : t_param;
tag : t_tag;
tef : t_tef;
time : t_time;
end record t_channel;
type t_name is array(63 downto 0) of t_ascii;
......
......@@ -18,7 +18,7 @@
--! 0x10 R : Queued actions
--! 0x14 RW : Dropped actions
--! 0x18 -- reserved --
--! 0x1C -- reserved --
--! 0x1C R : flags (0x1=late, 0x2=conflict)
--! 0x20 R : Event1
--! 0x24 R : Event0
--! 0x28 R : Param1
......@@ -87,7 +87,9 @@ architecture rtl of eca_queue_channel is
return (x and not v_sel) or (v_dat and v_sel);
end function;
subtype c_event_range is natural range c_event_bits-1 downto 0;
constant c_conflict_bit : natural := 0;
constant c_late_bit : natural := c_conflict_bit+1;
subtype c_event_range is natural range c_event_bits+c_late_bit downto c_late_bit+1;
subtype c_param_range is natural range c_param_bits+c_event_range'left downto c_event_range'left+1;
subtype c_tag_range is natural range c_tag_bits +c_param_range'left downto c_param_range'left+1;
subtype c_tef_range is natural range c_tef_bits +c_tag_range'left downto c_tag_range'left +1;
......@@ -165,6 +167,8 @@ architecture rtl of eca_queue_channel is
signal rq_stall_n : unsigned(g_log_clock_factor downto 0);
signal sq_data : t_data;
signal sq_conflict : std_logic;
signal sq_late : std_logic;
signal sq_event : t_event;
signal sq_param : t_param;
signal sq_tag : t_tag;
......@@ -217,11 +221,13 @@ begin
sa_wen <= a_channel_i.valid and not ra_full;
sa_widx_next <= f_eca_add(ra_widx, 1) when sa_wen='1' else ra_widx;
sa_data(c_event_range) <= a_channel_i.event;
sa_data(c_param_range) <= a_channel_i.param;
sa_data(c_tag_range) <= a_channel_i.tag;
sa_data(c_tef_range) <= a_channel_i.tef;
sa_data(c_time_range) <= a_channel_i.time;
sa_data(c_conflict_bit) <= a_channel_i.conflict;
sa_data(c_late_bit) <= a_channel_i.late;
sa_data(c_event_range) <= a_channel_i.event;
sa_data(c_param_range) <= a_channel_i.param;
sa_data(c_tag_range) <= a_channel_i.tag;
sa_data(c_tef_range) <= a_channel_i.tef;
sa_data(c_time_range) <= a_channel_i.time;
a_fifo : process(a_clk_i, a_rst_n_i) is
begin
......@@ -353,11 +359,13 @@ begin
end if;
end process;
sq_event <= sq_data(c_event_range);
sq_param <= sq_data(c_param_range);
sq_tag <= sq_data(c_tag_range);
sq_tef <= sq_data(c_tef_range);
sq_time <= sq_data(c_time_range);
sq_conflict <= sq_data(c_conflict_bit);
sq_late <= sq_data(c_late_bit);
sq_event <= sq_data(c_event_range);
sq_param <= sq_data(c_param_range);
sq_tag <= sq_data(c_tag_range);
sq_tef <= sq_data(c_tef_range);
sq_time <= sq_data(c_time_range);
q_slave_o.stall <= rq_stall;
q_slave_o.err <= '0';
......@@ -405,7 +413,8 @@ begin
when 4 => q_slave_o.dat(rq_queued'range) <= std_logic_vector(rq_queued);
when 5 => q_slave_o.dat(rq_dropped'range) <= std_logic_vector(rq_dropped);
when 6 => null; -- reserved
when 7 => null; -- reserved
when 7 => q_slave_o.dat(0) <= sq_late;
q_slave_o.dat(1) <= sq_conflict;
-- Protect clock crossing (rq_widx updates well after memory written)
when 8 => q_slave_o.dat <= sq_event(63 downto 32);
when 9 => q_slave_o.dat <= sq_event(31 downto 0);
......@@ -438,7 +447,7 @@ begin
when 4 => null; -- queued (RO)
when 5 => rq_dropped <= f_update(rq_dropped);
when 6 => null; -- reserved
when 7 => null; -- reserved
when 7 => null; -- Flags (RO)
when 8 => null; -- Event1 (RO)
when 9 => null; -- Event0 (RO)
when 10 => null; -- Param1 (RO)
......
......@@ -376,13 +376,14 @@ begin
c2_o => open);
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).late <= s1_a_late;
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;
q_channel_o(i).valid <= r1_a_validv(i) and not r_stall;
q_channel_o(i).conflict <= '0'; -- conflicts only happen after sorting in channel
q_channel_o(i).late <= s1_a_late;
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;
......@@ -41,6 +41,7 @@ status_t ActionChannel::refresh() {
eb_data_t ctl;
eb_data_t d_fill;
eb_data_t d_valid;
eb_data_t d_conflict;
eb_data_t d_late;
if ((status = cycle.open(eca->device)) != EB_OK)
......@@ -48,10 +49,11 @@ status_t ActionChannel::refresh() {
address = eca->address;
cycle.write(address + ECAQ_SELECT, EB_DATA32, index << 16);
cycle.read(address + ECAQ_CTL, EB_DATA32, &ctl);
cycle.read(address + ECAQ_FILL, EB_DATA32, &d_fill);
cycle.read(address + ECAQ_VALID, EB_DATA32, &d_valid);
cycle.read(address + ECAQ_LATE, EB_DATA32, &d_late);
cycle.read(address + ECAQ_CTL, EB_DATA32, &ctl);
cycle.read(address + ECAQ_FILL, EB_DATA32, &d_fill);
cycle.read(address + ECAQ_VALID, EB_DATA32, &d_valid);
cycle.read(address + ECAQ_CONFLICT, EB_DATA32, &d_conflict);
cycle.read(address + ECAQ_LATE, EB_DATA32, &d_late);
if ((status = cycle.close()) != EB_OK)
return status;
......@@ -60,8 +62,9 @@ status_t ActionChannel::refresh() {
frozen = ((ctl >> 24) & 0x02) != 0;
fill = (d_fill >> 16) & 0xFFFF;
max_fill = (d_fill >> 0) & 0xFFFF;
valid = d_valid & 0xFFFFFFFF;
late = d_late & 0xFFFFFFFF;
valid = d_valid & 0xFFFFFFFF;
conflict = d_conflict & 0xFFFFFFFF;
late = d_late & 0xFFFFFFFF;
return EB_OK;
}
......
......@@ -56,14 +56,15 @@
#define ECA_FREQ_2S 0x3D
#define ECA_FREQ_DIV 0x3E
#define ECAQ_SELECT 0x4C
#define ECAQ_CHANNEL 0x4C
#define ECAQ_INDEX 0x4E
#define ECAQ_CTL 0x50
#define ECAQ_NAME 0x51
#define ECAQ_FILL 0x54
#define ECAQ_MAX_FILL 0x56
#define ECAQ_VALID 0x58
#define ECAQ_SELECT 0x48
#define ECAQ_CHANNEL 0x48
#define ECAQ_INDEX 0x4A
#define ECAQ_CTL 0x4C
#define ECAQ_NAME 0x4D
#define ECAQ_FILL 0x50
#define ECAQ_MAX_FILL 0x52
#define ECAQ_VALID 0x54
#define ECAQ_CONFLICT 0x58
#define ECAQ_LATE 0x5C
#define ECAQ_EVENT1 0x60
......
......@@ -148,6 +148,7 @@ status_t ECA::probe(Device device, std::vector<ECA>& ecas) {
eb_data_t freq1, freq0;
eb_data_t fill;
eb_data_t valid;
eb_data_t conflict;
eb_data_t late;
eb_data_t id;
......@@ -206,9 +207,10 @@ status_t ECA::probe(Device device, std::vector<ECA>& ecas) {
cycle.write(eca.address + ECAQ_SELECT, EB_DATA32, c << 16);
for (unsigned j = 0; j < 64; ++j)
cycle.read(eca.address + ECAQ_CTL, EB_DATA32, &name[j]);
cycle.read(eca.address + ECAQ_FILL, EB_DATA32, &fill);
cycle.read(eca.address + ECAQ_VALID, EB_DATA32, &valid);
cycle.read(eca.address + ECAQ_LATE, EB_DATA32, &late);
cycle.read(eca.address + ECAQ_FILL, EB_DATA32, &fill);
cycle.read(eca.address + ECAQ_VALID, EB_DATA32, &valid);
cycle.read(eca.address + ECAQ_CONFLICT, EB_DATA32, &conflict);
cycle.read(eca.address + ECAQ_LATE, EB_DATA32, &late);
if ((status = cycle.close()) != EB_OK)
return status;
......@@ -218,8 +220,9 @@ status_t ECA::probe(Device device, std::vector<ECA>& ecas) {
ac.frozen = ((name[0] >> 24) & 0x02) != 0;
ac.fill = (fill >> 16) & 0xFFFF;
ac.max_fill = (fill >> 0) & 0xFFFF;
ac.valid = valid & 0xFFFFFFFF;
ac.late = late & 0xFFFFFFFF;
ac.valid = valid & 0xFFFFFFFF;
ac.conflict = conflict & 0xFFFFFFFF;
ac.late = late & 0xFFFFFFFF;
eca.channels.push_back(ac);
}
......
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