Skip to content

Commit

Permalink
Add target reset detection
Browse files Browse the repository at this point in the history
Signed-off-by: Krzysztof Boronski <[email protected]>
  • Loading branch information
kboronski-ant authored and tmichalak committed Nov 15, 2024
1 parent 2f3de09 commit b820d1b
Show file tree
Hide file tree
Showing 8 changed files with 188 additions and 10 deletions.
18 changes: 16 additions & 2 deletions src/ctrl/bus_monitor.sv
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ module bus_monitor
output logic start_detect_o, // Module detected START or REPEATED START condition
output logic stop_detect_o, // Module detected STOP condition

input is_in_hdr_mode_i, // Module is in HDR mode
output hdr_exit_detect_o // Detected HDR exit condition (see: 5.2.1.1.1 of the base spec)
input logic is_in_hdr_mode_i, // Module is in HDR mode
output logic hdr_exit_detect_o, // Detected HDR exit condition (see: 5.2.1.1.1 of the base spec)
output logic target_reset_detect_o // Deteced Target Reset condtition
);
logic enable, enable_q;

Expand Down Expand Up @@ -228,4 +229,17 @@ module bus_monitor
assign stop_detect_o = stop_det;
assign hdr_exit_detect_o = hdr_exit_det;

target_reset_detector target_reset_detector(
.clk_i,
.rst_ni,
.enable_i,
.scl_high(scl_stable_high),
.scl_low(scl_stable_low),
.scl_negedge,
.sda_posedge,
.sda_negedge,
.start_detected_i(start_det),
.stop_detected_i(stop_det),
.target_reset_detect_o
);
endmodule
4 changes: 3 additions & 1 deletion src/ctrl/controller_standby_i3c.sv
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ module controller_standby_i3c

logic start_detect;
logic stop_detect;
logic target_reset_detect;

logic is_in_hdr_mode;
logic hdr_exit_detect;
Expand Down Expand Up @@ -260,7 +261,8 @@ module controller_standby_i3c
.start_detect_o(start_detect),
.stop_detect_o(stop_detect),
.is_in_hdr_mode_i(is_in_hdr_mode),
.hdr_exit_detect_o(hdr_exit_detect)
.hdr_exit_detect_o(hdr_exit_detect),
.target_reset_detect_o(target_reset_detect)
);

bus_timers xbus_timers (
Expand Down
118 changes: 118 additions & 0 deletions src/ctrl/target_reset_detector.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
typedef enum logic [1:0] {
AwaitPattern = 2'h0,
AwaitSr = 2'h1,
AwaitP = 2'h2,
ResetDetected = 2'h3
} target_reset_detector_state_e;

module target_reset_detector
import controller_pkg::*;
(
input logic clk_i,
input logic rst_ni,

input logic enable_i, // Enable

input logic scl_low,
input logic scl_high,
input logic scl_negedge,
input logic sda_posedge,
input logic sda_negedge,

input start_detected_i, stop_detected_i,

output logic target_reset_detect_o
);
logic count_sda_transition;

logic [3:0] transition_count_q;
logic [3:0] transition_count_d;
logic [1:0] suspicious_transition_count_q;
logic [1:0] suspicious_transition_count_d;
logic invalidate_sr;

target_reset_detector_state_e state_q, state_d;

always_comb begin
if (scl_high)
transition_count_d = 4'h0;
else
transition_count_d =
count_sda_transition ? transition_count_q + 4'h1 : transition_count_q;

if ((state_q inside {AwaitP, AwaitSr}) & (sda_posedge | sda_negedge)) begin
suspicious_transition_count_d = suspicious_transition_count_q + 2'h1;
end else if (state_q == AwaitPattern) begin
suspicious_transition_count_d = 2'h0;
end

count_sda_transition = 0;
if ((state_q == AwaitPattern) & (transition_count_q < 4'he))
count_sda_transition = (sda_posedge & (transition_count_q != 0)) | sda_negedge;

invalidate_sr = suspicious_transition_count_d > 1;
end

always_ff @(posedge clk_i or negedge rst_ni) begin : target_reset_transition_counter
if (!rst_ni) begin
transition_count_q <= 4'h0;
end else if (clk_i) begin
transition_count_q <= transition_count_d;
end
end : target_reset_transition_counter

// If suspicious_transition_count == 1, it's either start or stop signal,
// but if it's more then it means something weird has happened or start/stop timing
// requirements were not met
always_ff @(posedge clk_i or negedge rst_ni) begin : suspicious_transition_counter
if (!rst_ni) begin
suspicious_transition_count_q <= 2'h0;
end else if (clk_i) begin
if (state_d == state_q)
suspicious_transition_count_q <= suspicious_transition_count_d;
else
suspicious_transition_count_q <= 2'h0; // Reset on state transition
end
end: suspicious_transition_counter

always_ff @(posedge clk_i or negedge rst_ni) begin : target_reset_detection_state
if (!rst_ni) begin
state_q <= AwaitPattern;
end else if (clk_i) begin
state_q <= state_d;
end
end : target_reset_detection_state

always_comb begin : target_reset_detection_fsm
case (state_q)
AwaitPattern: begin
state_d = (transition_count_q == 4'he) ? AwaitSr : AwaitPattern;
end
AwaitSr: begin
state_d = AwaitSr;
if (start_detected_i & scl_high) begin
state_d = AwaitP;
end else if (scl_low | suspicious_transition_count_q > 1) begin
state_d = AwaitPattern;
end
end
AwaitP: begin
state_d = AwaitP;
if (stop_detected_i & scl_high) begin
state_d = ResetDetected;
end else begin
if (invalidate_sr)
state_d = AwaitPattern;
end
end
ResetDetected: begin
state_d = AwaitPattern;
end
default: begin
state_d = AwaitPattern;
end // Unreachable
endcase
end : target_reset_detection_fsm

assign target_reset_detect_o = state_d == ResetDetected;
endmodule
1 change: 1 addition & 0 deletions src/i3c.f
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
${I3C_ROOT_DIR}/src/recovery/recovery_executor.sv
${I3C_ROOT_DIR}/src/recovery/recovery_handler.sv
${I3C_ROOT_DIR}/src/ctrl/bus_timers.sv
${I3C_ROOT_DIR}/src/ctrl/target_reset_detector.sv
${I3C_ROOT_DIR}/src/ctrl/bus_monitor.sv
${I3C_ROOT_DIR}/src/ctrl/ccc.sv
${I3C_ROOT_DIR}/src/ctrl/daa.sv
Expand Down
1 change: 1 addition & 0 deletions verification/cocotb/block/ctrl_bus_monitor/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ VERILOG_SOURCES = \
$(SRC_DIR)/ctrl/controller_pkg.sv \
$(SRC_DIR)/ctrl/edge_detector.sv \
$(SRC_DIR)/ctrl/stable_high_detector.sv \
$(SRC_DIR)/ctrl/target_reset_detector.sv \
$(SRC_DIR)/ctrl/bus_monitor.sv \

include $(TEST_DIR)/../block_common.mk
54 changes: 47 additions & 7 deletions verification/cocotb/block/ctrl_bus_monitor/test_bus_monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,15 @@ async def count_high_cycles(clk, sig, e_terminate):
await RisingEdge(clk)
return num_det

def create_default_controller(dut: SimHandleBase) -> I3cController:
return I3cController(
sda_i=None,
sda_o=dut.sda_i,
scl_i=None,
scl_o=dut.scl_i,
speed=12.5e6,
)


@cocotb.test()
async def test_bus_monitor(dut: SimHandleBase):
Expand All @@ -49,13 +58,7 @@ async def test_bus_monitor(dut: SimHandleBase):
clk = dut.clk_i
rst_n = dut.rst_ni

i3c_controller = I3cController(
sda_i=None,
sda_o=dut.sda_i,
scl_i=None,
scl_o=dut.scl_i,
speed=12.5e6,
)
i3c_controller = create_default_controller(dut)

clock = Clock(clk, 2, units="ns")
cocotb.start_soon(clock.start())
Expand Down Expand Up @@ -140,3 +143,40 @@ async def test_bus_monitor_hdr_exit(dut: SimHandleBase):
cocotb.log.info(f"HDR exits detected {num_detects}")
assert num_detects == 1
e_terminate.clear()


@cocotb.test()
async def test_target_reset_detection(dut: SimHandleBase):
cocotb.log.setLevel("INFO")

i3c_controller = create_default_controller(dut)
clock = Clock(dut.clk_i, 2, units="ns")
cocotb.start_soon(clock.start())

await setup(dut)
await reset_n(dut.clk_i, dut.rst_ni, cycles=5)

dut.enable_i.value = 1

# Basic target reset
cocotb.log.info("Performing basic target reset test with no configuration")

e_terminate = cocotb.triggers.Event()
t_detect_target_reset = cocotb.start_soon(count_high_cycles(
dut.clk_i,
dut.target_reset_detect_o,
e_terminate
))
await i3c_controller.target_reset()

await ClockCycles(dut.clk_i, 32)
e_terminate.set()
await RisingEdge(dut.clk_i)

num_resets = t_detect_target_reset.result()
cocotb.log.info(f"Resets detected: {num_resets}")
assert num_resets == 1

e_terminate.clear()

await ClockCycles(dut.clk_i, 10)
1 change: 1 addition & 0 deletions verification/cocotb/block/i2c/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ VERILOG_SOURCES = \
$(SRC_DIR)/ctrl/i2c_controller_fsm.sv \
$(SRC_DIR)/ctrl/i2c_target_fsm.sv \
$(SRC_DIR)/ctrl/i3c_controller_fsm.sv \
$(SRC_DIR)/ctrl/target_reset_detector.sv \
$(SRC_DIR)/ctrl/bus_monitor.sv \
$(SRC_DIR)/ctrl/i3c_target_fsm.sv \
$(SRC_DIR)/ctrl/flow_active.sv \
Expand Down
1 change: 1 addition & 0 deletions verification/cocotb/block/i2c_standby_controller/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ VERILOG_SOURCES = \
$(SRC_DIR)/ctrl/i2c_controller_fsm.sv \
$(SRC_DIR)/ctrl/i2c_target_fsm.sv \
$(SRC_DIR)/ctrl/i3c_controller_fsm.sv \
$(SRC_DIR)/ctrl/target_reset_detector.sv \
$(SRC_DIR)/ctrl/bus_monitor.sv \
$(SRC_DIR)/ctrl/i3c_target_fsm.sv \
$(SRC_DIR)/ctrl/flow_active.sv \
Expand Down

0 comments on commit b820d1b

Please sign in to comment.