From 7d10a724903749001d6ecb3e4b723d7f2bbd4a2e Mon Sep 17 00:00:00 2001 From: Anhijkt Date: Thu, 6 Nov 2025 23:29:47 +0200 Subject: [PATCH 1/3] fsm_detect: add adff detection --- passes/fsm/fsm_detect.cc | 11 +++- tests/various/fsm-arst.ys | 133 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 142 insertions(+), 2 deletions(-) create mode 100644 tests/various/fsm-arst.ys diff --git a/passes/fsm/fsm_detect.cc b/passes/fsm/fsm_detect.cc index 9cffbf95a..5f491a16c 100644 --- a/passes/fsm/fsm_detect.cc +++ b/passes/fsm/fsm_detect.cc @@ -199,8 +199,15 @@ static void detect_fsm(RTLIL::Wire *wire, bool ignore_self_reset=false) } SigSpec sig_y = sig_d, sig_undef; - if (!ignore_self_reset && ce.eval(sig_y, sig_undef)) - is_self_resetting = true; + if (!ignore_self_reset) { + if (cellport.first->type == ID($adff)) { + SigSpec sig_arst = assign_map(cellport.first->getPort(ID::ARST)); + if (ce.eval(sig_arst, sig_undef)) + is_self_resetting = true; + } + else if (ce.eval(sig_y, sig_undef)) + is_self_resetting = true; + } } if (has_fsm_encoding_attr) diff --git a/tests/various/fsm-arst.ys b/tests/various/fsm-arst.ys new file mode 100644 index 000000000..2cfca1d57 --- /dev/null +++ b/tests/various/fsm-arst.ys @@ -0,0 +1,133 @@ +read_verilog << EOT +module non_self_rs_fsm ( + input wire clk, + input wire reset, + output wire s1 +); + localparam [7:0] RST = 8'b10010010; + localparam [7:0] S1 = 8'b01001000; + localparam [7:0] S2 = 8'b11000111; + + reg [7:0] current_state, next_state; + always @(posedge clk or posedge reset) begin + if (reset) begin + current_state <= RST; + end else begin + current_state <= next_state; + end + end + + always @(*) begin + next_state = current_state; + + case (current_state) + RST: next_state = S1; + S1: next_state = S2; + S2: next_state = S1; + default: next_state = RST; + endcase + end + + assign s1 = next_state == S1; +endmodule + +module semi_self_rs_fsm ( + input wire clk, + inout wire reset, + input wire test, + output wire s1 +); + localparam [7:0] RST = 8'b10010010; + localparam [7:0] S1 = 8'b01001000; + localparam [7:0] S2 = 8'b11000111; + + reg [7:0] current_state, next_state; + reg [1:0] reset_test; + + assign reset = (test || (reset_test == 2)); + + always @(posedge clk or posedge reset) begin + if (reset) begin + current_state <= RST; + reset_test <= 0; + end else begin + current_state <= next_state; + if (current_state == S2) + reset_test = reset_test + 1; + end + end + + + always @(*) begin + next_state = current_state; + + case (current_state) + RST: next_state = S1; + S2: next_state = S1; + S1: next_state = S2; + + default: next_state = RST; + endcase + end + + assign s1 = next_state == S1; +endmodule + +module self_rs_fsm ( + input wire clk, + inout wire reset, + output wire s1 +); + localparam [7:0] RST = 8'b10010010; + localparam [7:0] S1 = 8'b01001000; + localparam [7:0] S2 = 8'b11000111; + + reg [7:0] current_state, next_state; + reg reset_reg; + + wire reset = (reset_reg || next_state == S1); + always @(posedge clk or posedge reset) begin + if (reset) begin + current_state <= RST; + reset_reg = 0; + end else begin + current_state <= next_state; + end + end + + always @(*) begin + next_state = current_state; + + case (current_state) + RST: next_state = S1; + S1: next_state = S2; + S2: next_state = S1; + default: begin + reset_reg = 1; + next_state = RST; + end + endcase + end + + assign s1 = next_state == S1; +endmodule + +EOT + +proc +opt_expr +opt_clean +check +opt -nodffe -nosdff + +fsm_detect +fsm_extract + +cd non_self_rs_fsm +select -assert-count 1 t:$fsm + +cd semi_self_rs_fsm +select -assert-count 1 t:$fsm + +cd self_rs_fsm +select -assert-none t:$fsm From a75b999f133b90c35f366e6b170ad03b3fda796a Mon Sep 17 00:00:00 2001 From: Anhijkt Date: Fri, 14 Nov 2025 13:25:51 +0200 Subject: [PATCH 2/3] fsm_detect: fix test --- tests/various/fsm-arst.ys | 32 ++++++++++---------------------- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/tests/various/fsm-arst.ys b/tests/various/fsm-arst.ys index 2cfca1d57..d3c40444b 100644 --- a/tests/various/fsm-arst.ys +++ b/tests/various/fsm-arst.ys @@ -33,7 +33,6 @@ endmodule module semi_self_rs_fsm ( input wire clk, - inout wire reset, input wire test, output wire s1 ); @@ -44,7 +43,7 @@ module semi_self_rs_fsm ( reg [7:0] current_state, next_state; reg [1:0] reset_test; - assign reset = (test || (reset_test == 2)); + wire reset = (test || (reset_test == 2)); always @(posedge clk or posedge reset) begin if (reset) begin @@ -75,39 +74,28 @@ endmodule module self_rs_fsm ( input wire clk, - inout wire reset, output wire s1 ); localparam [7:0] RST = 8'b10010010; localparam [7:0] S1 = 8'b01001000; localparam [7:0] S2 = 8'b11000111; - reg [7:0] current_state, next_state; - reg reset_reg; - + reg [7:0] next_state; wire reset = (reset_reg || next_state == S1); + always @(posedge clk or posedge reset) begin if (reset) begin - current_state <= RST; - reset_reg = 0; + next_state <= RST; end else begin - current_state <= next_state; + case (next_state) + RST: next_state = S1; + S1: next_state = S2; + S2: next_state = S1; + default: next_state = RST; + endcase end end - always @(*) begin - next_state = current_state; - - case (current_state) - RST: next_state = S1; - S1: next_state = S2; - S2: next_state = S1; - default: begin - reset_reg = 1; - next_state = RST; - end - endcase - end assign s1 = next_state == S1; endmodule From b08195a9cffdeff14fc93047745033952d20f914 Mon Sep 17 00:00:00 2001 From: Anhijkt Date: Fri, 14 Nov 2025 13:34:58 +0200 Subject: [PATCH 3/3] typo --- tests/various/fsm-arst.ys | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/various/fsm-arst.ys b/tests/various/fsm-arst.ys index d3c40444b..4b2c9c66a 100644 --- a/tests/various/fsm-arst.ys +++ b/tests/various/fsm-arst.ys @@ -81,7 +81,7 @@ module self_rs_fsm ( localparam [7:0] S2 = 8'b11000111; reg [7:0] next_state; - wire reset = (reset_reg || next_state == S1); + wire reset = next_state == S1; always @(posedge clk or posedge reset) begin if (reset) begin