Verilog 语言,关于状态机的困惑

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Verilog 语言,关于状态机的困惑相关的知识,希望对你有一定的参考价值。

想在状态机加一个计数器,即处于某个状态超过50个clk就设置一个标志位:
always @(posedge clk or posedge grst)
begin
if(grst)
begin state[3:0] = 4'd0; idle_count[5:0] = 6'd0;falg = 0;end
else
begin
case(state[3:0])
4'd0:begin if(idle_count[5:0] == 6'd50) flag = 1;
else idle_count[5:0] = idle_count[5:0] + 6'd1;
state[3:0] = 4'd1; end
4'd1: begin if(falg = 1) falg = 0;……state[3:0] = 4'd2; end
4'd2: begin ……state[3:0] = 4'd0; end
endcase
end
end
我编写就向上面程序所写模式一样,但flag无变化,不知道哪里错了?
请高手指点下,谢谢!
程序:
always @(posedge clk or posedge grst)
begin
if(grst)
begin
state[3:0] = 4'd0;
idle_count[5:0] = 6'd0;
falg = 0;
end
else
begin
case(state[3:0])
4'd0:begin
if(rxdata == 1)
begin
state[3:0] = 4'd0;
if(idle_count[5:0] == 6'd50)
flag = 1;
else
idle_count[5:0] = idle_count[5:0] + 6'd1;
end
else
state[3:0] = 4'd1;
end
4'd1: begin if(falg = 1) falg = 0;……state[3:0] = 4'd2; end
4'd2: begin ……state[3:0] = 4'd0; end
endcase
end
end

参考技术A 我的一点想法,仅供参考
状态机时序中赋值一般用“<="比较多吧,如果不是有特别需要不用“=”的
4'd0:begin if(idle_count[5:0] == 6'd50) flag = 1;
else idle_count[5:0] = idle_count[5:0] + 6'd1;
state[3:0] = 4'd1; end
4'd1: begin if(falg = 1) falg = 0;……state[3:0] = 4'd2; end
4'd2: begin ……state[3:0] = 4'd0; end

case 语句中4'd0满足后state[3:0] = 4'd1,这个赋值是立即执行的,那么 4'd1又被满足了,然后一直下去,虽然你的flag在50的时候是被置为1了,但是紧接着下面又被置回0了,所以时序上看不出来,会不会是这个问题,建议改为阻塞赋值。
不知道自己理解的对不对,大家一起看看追问

补充问题里是格式正确的程序,
不存在你说的那个问题,关键的问题应该不在这里

参考技术B 1 . idle_count[5:0] == 6'd50 的时候,flag 从0变为1,并没有进入状态1;
2 . idle_count[5:0] !== 6'd50 的时候,flag还是0,没有变化,进入状态1,然后,判断 if(falg ==1) ,falg=0 不能满足条件,就卡在这一步了;
3. 从你下面补充的来看,状态0进入状态1的条件是 rxdata !== 1;而rxdata == 1的时候,flag 会从0变为1;
参考技术C 你的idle_count初始值是000000,state初始也是0000
这样你的状态机卡在第一步了
4'd0:begin if(idle_count[5:0] == 6'd50) flag = 1;
你需要在这个if里添加state的变化,否则状态机动不了追问

gg,下面有呀,state[3:0] = 4'd1;

参考技术D 从 4'd0跳到 4'd1有 idle_count[5:0] = 6'd0;5:0] = 6'd0;这句,就是又回到0了,要flag有变化就要 idle_count能到 6'd50,如果你的省略号里内容与此无关的话那么 idle_count变化不了,flag也就不会有变化追问

看来是写的格式不好,我再重发一个重写一遍

第5个回答  2011-08-05 时序逻辑不要用=,使用<=应该就可以了本回答被提问者采纳

一个关于verilog 状态机的问题程序,综合的时候出了点错误,希望各位可以帮忙解决下问题

module Status_Machine(
Clk_In,Reaset,
Effect_0,Effect_1,
Status,Clk_Out
);

input Clk_In,Reaset;output Status,Effect_0,Effect_1,Clk_Out;
reg [1:0] status;
reg [1:0] Effect_0;
reg [7:0] Effect_1;
reg [3:0] Cunt;
reg Clk_Out;

parameter LED = 2'b01, Digital_tube = 2'b10;
always @ (posedge Clk_In)
begin
Cunt <=Cunt+1;
if (Cunt<4'b1001)
Clk_Out <= 1'b0;
else
begin
Clk_Out <=1'b1;
Cunt <=4'b0000;
end
end
always @ (posedge Clk_Out)
if (!Reaset)
begin
Status <= LED;
end
else
begin
case(Status)
LED :
begin
Status <=Digital_tube;
Effect_0 <= 2'b11;
end
Digital_tube:
begin
Status <= LED;
Effect_1 <= 8'b01111111;
end
default :
begin
Effect_0 <= 2'b11;
Effect_1 <=8'b01111111;
end
endcase
end
endmodule

个人觉得在分频程序和状态机状态调用程序上无错误,倒是一到赋值就有错了
Error (10137): Verilog HDL Procedural Assignment error at Status_Machine.v(34): object "Status" on left-hand side of assignment must have a variable data type

状态机使用的是Status跟你定义的reg [1:0] status第一个字母大小写不一样~~ 参考技术A reg [1:0] status; 大小写错误,应该是 reg [1:0] Status; 参考技术B 早知道先看下楼上的了,先看了一分钟... 参考技术C case(Status)改成case(status)

以上是关于Verilog 语言,关于状态机的困惑的主要内容,如果未能解决你的问题,请参考以下文章

怎么定义Verilog状态机每个状态执行啥动作?

verilog之状态机

是关于verilog状态机的问题 在always 时钟块的一个状态中,系统如何运行阻塞赋值? 代码如下:

verilog中的隐式状态机和显示状态机?

Verilog学习笔记设计和验证篇...............同步有限状态机的指导原则

在用verilog编写三段式状态机的时候,我看网上很多地方都是提到格式如下:always @ (posedge clk or negedg