Skip to content

Commit 4bfdc62

Browse files
authored
Merge pull request #5472 from Anhijkt/arst-fsm-handling
fsm_detect: add adff detection
2 parents abc78f0 + b08195a commit 4bfdc62

File tree

2 files changed

+130
-2
lines changed

2 files changed

+130
-2
lines changed

passes/fsm/fsm_detect.cc

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,8 +199,15 @@ static void detect_fsm(RTLIL::Wire *wire, bool ignore_self_reset=false)
199199
}
200200

201201
SigSpec sig_y = sig_d, sig_undef;
202-
if (!ignore_self_reset && ce.eval(sig_y, sig_undef))
203-
is_self_resetting = true;
202+
if (!ignore_self_reset) {
203+
if (cellport.first->type == ID($adff)) {
204+
SigSpec sig_arst = assign_map(cellport.first->getPort(ID::ARST));
205+
if (ce.eval(sig_arst, sig_undef))
206+
is_self_resetting = true;
207+
}
208+
else if (ce.eval(sig_y, sig_undef))
209+
is_self_resetting = true;
210+
}
204211
}
205212

206213
if (has_fsm_encoding_attr)

tests/various/fsm-arst.ys

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
read_verilog << EOT
2+
module non_self_rs_fsm (
3+
input wire clk,
4+
input wire reset,
5+
output wire s1
6+
);
7+
localparam [7:0] RST = 8'b10010010;
8+
localparam [7:0] S1 = 8'b01001000;
9+
localparam [7:0] S2 = 8'b11000111;
10+
11+
reg [7:0] current_state, next_state;
12+
always @(posedge clk or posedge reset) begin
13+
if (reset) begin
14+
current_state <= RST;
15+
end else begin
16+
current_state <= next_state;
17+
end
18+
end
19+
20+
always @(*) begin
21+
next_state = current_state;
22+
23+
case (current_state)
24+
RST: next_state = S1;
25+
S1: next_state = S2;
26+
S2: next_state = S1;
27+
default: next_state = RST;
28+
endcase
29+
end
30+
31+
assign s1 = next_state == S1;
32+
endmodule
33+
34+
module semi_self_rs_fsm (
35+
input wire clk,
36+
input wire test,
37+
output wire s1
38+
);
39+
localparam [7:0] RST = 8'b10010010;
40+
localparam [7:0] S1 = 8'b01001000;
41+
localparam [7:0] S2 = 8'b11000111;
42+
43+
reg [7:0] current_state, next_state;
44+
reg [1:0] reset_test;
45+
46+
wire reset = (test || (reset_test == 2));
47+
48+
always @(posedge clk or posedge reset) begin
49+
if (reset) begin
50+
current_state <= RST;
51+
reset_test <= 0;
52+
end else begin
53+
current_state <= next_state;
54+
if (current_state == S2)
55+
reset_test = reset_test + 1;
56+
end
57+
end
58+
59+
60+
always @(*) begin
61+
next_state = current_state;
62+
63+
case (current_state)
64+
RST: next_state = S1;
65+
S2: next_state = S1;
66+
S1: next_state = S2;
67+
68+
default: next_state = RST;
69+
endcase
70+
end
71+
72+
assign s1 = next_state == S1;
73+
endmodule
74+
75+
module self_rs_fsm (
76+
input wire clk,
77+
output wire s1
78+
);
79+
localparam [7:0] RST = 8'b10010010;
80+
localparam [7:0] S1 = 8'b01001000;
81+
localparam [7:0] S2 = 8'b11000111;
82+
83+
reg [7:0] next_state;
84+
wire reset = next_state == S1;
85+
86+
always @(posedge clk or posedge reset) begin
87+
if (reset) begin
88+
next_state <= RST;
89+
end else begin
90+
case (next_state)
91+
RST: next_state = S1;
92+
S1: next_state = S2;
93+
S2: next_state = S1;
94+
default: next_state = RST;
95+
endcase
96+
end
97+
end
98+
99+
100+
assign s1 = next_state == S1;
101+
endmodule
102+
103+
EOT
104+
105+
proc
106+
opt_expr
107+
opt_clean
108+
check
109+
opt -nodffe -nosdff
110+
111+
fsm_detect
112+
fsm_extract
113+
114+
cd non_self_rs_fsm
115+
select -assert-count 1 t:$fsm
116+
117+
cd semi_self_rs_fsm
118+
select -assert-count 1 t:$fsm
119+
120+
cd self_rs_fsm
121+
select -assert-none t:$fsm

0 commit comments

Comments
 (0)