Skip to content

Commit

Permalink
[i2c,rtl] Count number of NACKs sent
Browse files Browse the repository at this point in the history
This is useful for software to know how many NACKs have happened since
the ACQ FIFO ended up being full. Otherwise there is no way for software
to know whether it was on time with emptying the FIFO or whether it just
missed the one byte or whether it missed multiple transactions.

Signed-off-by: Marno van der Maas <[email protected]>
  • Loading branch information
marnovandermaas committed Mar 19, 2024
1 parent 7ce3a44 commit 3fd4b0c
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 0 deletions.
5 changes: 5 additions & 0 deletions hw/ip/i2c/rtl/i2c_core.sv
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ module i2c_core import i2c_pkg::*;
logic event_stretch_timeout;
logic event_sda_unstable;
logic event_cmd_complete;
logic event_target_nack;
logic event_tx_stretch;
logic event_unexp_stop;
logic event_host_timeout;
Expand Down Expand Up @@ -187,6 +188,9 @@ module i2c_core import i2c_pkg::*;
assign hw2reg.target_fifo_status.acqlvl.d = MaxFifoDepthW'(acq_fifo_depth);
assign hw2reg.acqdata.abyte.d = acq_fifo_rdata[7:0];
assign hw2reg.acqdata.signal.d = acq_fifo_rdata[AcqFifoWidth-1:8];
// Add one to the target NACK count if this target has sent a NACK.
assign hw2reg.target_nack_count.de = event_target_nack;
assign hw2reg.target_nack_count.d = reg2hw.target_nack_count.q + 1;

assign override = reg2hw.ovrd.txovrden;

Expand Down Expand Up @@ -469,6 +473,7 @@ module i2c_core import i2c_pkg::*;
.target_mask0_i (target_mask0),
.target_address1_i (target_address1),
.target_mask1_i (target_mask1),
.event_target_nack_o (event_target_nack),
.event_nak_o (event_nak),
.event_scl_interference_o(event_scl_interference),
.event_sda_interference_o(event_sda_interference),
Expand Down
4 changes: 4 additions & 0 deletions hw/ip/i2c/rtl/i2c_fsm.sv
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ module i2c_fsm import i2c_pkg::*;
input logic [6:0] target_address1_i,
input logic [6:0] target_mask1_i,

output logic event_target_nack_o, // this target sent a NACK (this is used to keep count)
output logic event_nak_o, // target didn't Ack when expected
output logic event_scl_interference_o, // other device forcing SCL low
output logic event_sda_interference_o, // other device forcing SDA low
Expand Down Expand Up @@ -518,6 +519,7 @@ module i2c_fsm import i2c_pkg::*;
event_scl_interference_o = 1'b0;
event_sda_unstable_o = 1'b0;
event_cmd_complete_o = 1'b0;
event_target_nack_o = 1'b0;
rw_bit = rw_bit_q;
stretch_en = 1'b0;
expect_stop = 1'b0;
Expand Down Expand Up @@ -832,6 +834,7 @@ module i2c_fsm import i2c_pkg::*;
// complete notification from a restart or a stop. We must notify
// software that it needs to start processing the ACQ FIFO.
event_cmd_complete_o = 1'b1;
event_target_nack_o = 1'b1;
end
end
// StretchAddr: target stretches the clock if matching address cannot be
Expand Down Expand Up @@ -881,6 +884,7 @@ module i2c_fsm import i2c_pkg::*;
event_scl_interference_o = 1'b0;
event_sda_unstable_o = 1'b0;
event_cmd_complete_o = 1'b0;
event_target_nack_o = 1'b0;
actively_stretching = 1'b0;
end
endcase // unique case (state_q)
Expand Down

0 comments on commit 3fd4b0c

Please sign in to comment.