使用 Verilog 的 FSM 建模显示 X
Modelling of a FSM using Verilog shows X
给定以下 FSM:
我正在尝试使用 Verilog 对其进行建模,这是我的试验:
module fsm (u,d,clr,clk,inc,dec,c);
input u,d, clr,clk;
output reg inc,dec,c ;
// the state variables
reg y,Y; // y is the present state and Y is the next state
reg S0,S1;
// next state and output specifications
always @ (y,u,d) begin
case (y)
S0 : if (u==1) begin
Y= S1;
inc=1;
dec=0;
c=1;
end
else if (u==0) begin
c=0;
end
S1 : if (d==1) begin
Y= S0;
inc=0;
dec=1;
c=0;
end
else if (d==0) begin
c=1;
end
endcase
end
// state update
always @(posedge clk,clr) begin
if (clr)
y=S0;
else
y=Y;
end
endmodule
如果我的代码正确描述了这个 FSM,请告诉我,如果代码有任何改进,请告诉我。
这是一个初始测试平台代码:
module tb();
reg u,d, clr,clk;
reg inc,dec,c,y ;
fsm ttb (.u(u),.d(d),.clk(clk),.clr(clr),.inc(inc),.dec(dec),.c(c));
initial begin
$dumpfile("dump.vcd");
$dumpvars;
end
initial begin //{
clk=0 ; clr=0; #10
clk=1; u=0 ; clr=0 ; d=0; #10
clk = 0;#10
u=1; clk=1; #10
$finish;
end //}
endmodule
测试台代码显示有问题。当前状态变量 y
显示未定义的值 'X'。我不知道为什么。输出变量 inc
和 dec
.
相同
造成 X
的原因有多种。
在设计中,您将 S0
和 S1
声明为 reg
,但您从未为它们赋值。 Verilog reg
被初始化为 X
。 FSM 通常使用常量 parameter
值进行编码。例如,更改:
reg S0,S1;
至:
parameter S0=0, S1=1;
你的下一个状态逻辑需要在所有情况下给Y
赋值(参考<---
):
always @ (y,u,d) begin
case (y)
S0 : if (u==1) begin
Y= S1;
inc=1;
dec=0;
c=1;
end
else if (u==0) begin
c=0;
Y= S0; // <-----
end
S1 : if (d==1) begin
Y= S0;
inc=0;
dec=1;
c=0;
end
else if (d==0) begin
c=1;
Y= S1; // <-----
end
endcase
end
在您的测试台中,您需要断言重置 (clr
=1):
initial begin
u=0; d=0;
clk=0 ; clr=1; #10
clk=1; u=0 ; d=0; #10
clk = 0;#10
u=1; clk=1; clr=0; #10
$finish;
end
针对您关于异步清除的问题的评论,您应该更改:
always @(posedge clk,clr) begin
至:
always @(posedge clk, posegde clr) begin
给定以下 FSM:
我正在尝试使用 Verilog 对其进行建模,这是我的试验:
module fsm (u,d,clr,clk,inc,dec,c);
input u,d, clr,clk;
output reg inc,dec,c ;
// the state variables
reg y,Y; // y is the present state and Y is the next state
reg S0,S1;
// next state and output specifications
always @ (y,u,d) begin
case (y)
S0 : if (u==1) begin
Y= S1;
inc=1;
dec=0;
c=1;
end
else if (u==0) begin
c=0;
end
S1 : if (d==1) begin
Y= S0;
inc=0;
dec=1;
c=0;
end
else if (d==0) begin
c=1;
end
endcase
end
// state update
always @(posedge clk,clr) begin
if (clr)
y=S0;
else
y=Y;
end
endmodule
如果我的代码正确描述了这个 FSM,请告诉我,如果代码有任何改进,请告诉我。
这是一个初始测试平台代码:
module tb();
reg u,d, clr,clk;
reg inc,dec,c,y ;
fsm ttb (.u(u),.d(d),.clk(clk),.clr(clr),.inc(inc),.dec(dec),.c(c));
initial begin
$dumpfile("dump.vcd");
$dumpvars;
end
initial begin //{
clk=0 ; clr=0; #10
clk=1; u=0 ; clr=0 ; d=0; #10
clk = 0;#10
u=1; clk=1; #10
$finish;
end //}
endmodule
测试台代码显示有问题。当前状态变量 y
显示未定义的值 'X'。我不知道为什么。输出变量 inc
和 dec
.
造成 X
的原因有多种。
在设计中,您将 S0
和 S1
声明为 reg
,但您从未为它们赋值。 Verilog reg
被初始化为 X
。 FSM 通常使用常量 parameter
值进行编码。例如,更改:
reg S0,S1;
至:
parameter S0=0, S1=1;
你的下一个状态逻辑需要在所有情况下给Y
赋值(参考<---
):
always @ (y,u,d) begin
case (y)
S0 : if (u==1) begin
Y= S1;
inc=1;
dec=0;
c=1;
end
else if (u==0) begin
c=0;
Y= S0; // <-----
end
S1 : if (d==1) begin
Y= S0;
inc=0;
dec=1;
c=0;
end
else if (d==0) begin
c=1;
Y= S1; // <-----
end
endcase
end
在您的测试台中,您需要断言重置 (clr
=1):
initial begin
u=0; d=0;
clk=0 ; clr=1; #10
clk=1; u=0 ; d=0; #10
clk = 0;#10
u=1; clk=1; clr=0; #10
$finish;
end
针对您关于异步清除的问题的评论,您应该更改:
always @(posedge clk,clr) begin
至:
always @(posedge clk, posegde clr) begin