我是硬件的初学者。
在学习Verilog HDL时,由于缺乏系统学习,我在学习期间很容易迷失。
我正在尝试编写下面状态图中指定的机器的Verilog HDL行为描述。
我在case语句中使用了if-else语句,这给了我关于这些行的语法错误。
与Java或C ++不同,Verilog几乎没有关于错误的来源。
你看到问题是什么吗?
我的代码附在下面:
module foo(y_out, state, x_in, clk, reset);
input x_in, clk, reset;
output reg y_out;
parameter s0 = 3'b000, s1 = 3'b001, s2 = 3'b010, s3 = 3'b011, s4 = 3'b100;
output reg[2:0] state;
reg[2:0] next_state;
always @(posedge clk) begin
if(reset == 1'b0) state <= s0;
else state <= next_state;
end
always @(state, x_in) begin
y_out = 0;
next_state = s0;
case(state, x_in)
s0:
if (!x_in) begin
next_state = s3;
y_out = 1'b0;
end
else begin
next_state = s4;
y_out =1'b1;
end
s1:
if (!x_in) begin
next_state = s1;
y_out = 1'b0;
end
else begin
next_state = s4;
y_out =1'b1;
end
s2: if (!x_in) begin
next_state = s2;
y_out = 1'b0;
end
else begin
next_state = s0;
y_out =1'b1;
end
s3: if (!x_in) begin
next_state = s1;
y_out = 1'b0;
end
else begin
next_state = s2;
y_out =1'b1;
end
s4: if (!x_in) begin
next_state = s2;
y_out = 1'b0;
end
else begin
next_state = s3;
y_out =1'b0;
end
default begin
next_state = s0;
y_out = 1'b0;
end
endcase
end
endmodule
module t_foo;
wire t_y_out, t_state;
reg t_x_in, t_clock, t_reset;
foo M1(t_y_out, t_state, t_x_in, t_clock, t_reset);
initial #200 $finish;
initial begin
t_reset = 0;
t_clock = 0;
#5 t_reset = 1;
repeat (16)
#5 t_clock = ~t_clock;
end
initial begin
t_x_in = 0;
#15 t_x_in = 1;
repeat (8)
#10 t_x_in = ~t_x_in;
end
initial begin
$monitor("ABC: %d, x_in: %d, Clock: %d, Reset: %d", state, t_x_in, t_clock, t_reset);
$dumpfile("5_41_wv.vcd");
$dumpvars;
end
endmodule
答案 0 :(得分:6)
case
语句需要单个项目,如果这是基于多个wire / regs,那么它们需要使用{}
进行连接。
我会避免使用像always @(state, x_in) begin
这样的内容而只是写always @* begin
。 @ *将处理敏感度列表。
使用连接运算符可以删除if语句:
always @* begin
y_out = 0;
next_state = s0;
case({state, x_in}) //Added {}
{s0, 1'b0}:
begin
next_state = s3;
y_out = 1'b0;
end
{s0, 1'b1}:
begin
next_state = s4;
y_out = 1'b1;
end
{s1, 1'b0}:
begin
next_state = s1;
y_out = 1'b0;
end
{s1, 1'b1}:
begin
next_state = s4;
y_out = 1'b1;
end
使用casez
将允许您添加不关心next_state逻辑:
always @* begin
y_out = 0;
next_state = s0;
casez({state, x_in}) //Added {}
{s0, 1'bx}: //Do not care about the state of x_in
begin
next_state = s3;
y_out = 1'b0;
end
{s1, 1'b0}:
begin
next_state = s1;
y_out = 1'b0;
end
{s1, 1'b1}:
begin
next_state = s4;
y_out = 1'b1;
end
答案 1 :(得分:3)
变化:
case(state, x_in)
为:
case(state)
这为我修复了一个编译错误。代码中的案例项仅取决于您的州参数,而不是x_in
。
我的testbench模块中也出现了编译错误。要修复它,请更改:
$monitor("ABC: %d, x_in: %d, Clock: %d, Reset: %d", state, t_x_in, t_clock, t_reset);
为:
$monitor("ABC: %d, x_in: %d, Clock: %d, Reset: %d", t_state, t_x_in, t_clock, t_reset);
通过更改:
来修正警告wire t_y_out, t_state;
为:
wire t_y_out;
wire [2:0] t_state;
答案 2 :(得分:-1)
在case表达式中使用状态,在条件良好的情况下使用xin。请找到以下工作代码。
module fsm_state(
input clk,
input rst_n,
input xin,
output reg yout
);
reg [2:0] state;
reg [2:0] next_state;
parameter s0 = 3'b000,
s1 = 3'b001,
s2 = 3'b010,
s3 = 3'b011,
s4 = 3'b100;
always @ (posedge clk) begin
if (!rst_n)
state = s0;
else
state = next_state;
end
always @*
begin
yout = 1'b0;
case (state)
s0: begin
if (xin) begin
yout = 1'b1;
next_state = s4;
end
else
next_state = s3;
end
s1: begin
if (xin) begin
yout = 1'b1;
next_state = s4;
end
else
next_state = s1;
end
s2: begin
if (xin) begin
yout = 1'b1;
next_state = s0;
end
else
next_state = s2;
end
s3: begin
if (xin) begin
yout = 1'b1;
next_state = s2;
end
else
next_state = s1;
end
s4: begin
if (xin)
next_state = s3;
else
next_state = s2;
end
endcase
end
endmodule
谢谢