3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-11-21 21:26:42 +00:00

fsm_detect: add adff detection

This commit is contained in:
Anhijkt 2025-11-06 23:29:47 +02:00
parent a16fc9b4f3
commit 7d10a72490
2 changed files with 142 additions and 2 deletions

View file

@ -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)

133
tests/various/fsm-arst.ys Normal file
View file

@ -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