是这样的,我写的三段式状态机,3个always块大致如下:
//状态转换
always @(posedge clk or negedge rst)
begin
if (!rst)
current_state <= s1;
else
current_state <= next_state;
end
//next_state
always @(current_state or in)
begin
case (current_state)
s1:
if (…)
next_state = s3;
s2:
if (…)
next_state = s5;
…
default:
next_state <= s1;
endcase
end
//输出信号
always @(current_state or in)
begin
case (current_state)
s1:
if (…)
out = 1'b1;
s2:
if (…)
out = 1'b0;
…
default:
out = 1'b0;
endcase
end
但是在rst下降沿的时候想要给将out设为0.
在modelsim仿真的时候,如果把第一个always块改写成如下:
always @(posedge clk or negedge rst)
begin
if (!rst)
begin
current_state <= s1;
out <= 1'b0;
end
else
current_state <= next_state;
end
我把你的优化一下如下吧,你看着合适就用,不合适就自己取舍吧。
/*
always @(posedge clk or negedge rst)
begin
if (!rst)
current_state <= s1;
else
current_state <= next_state;
end
*/
reg[3:0] flag_cnt;
wire flag_en;
always @(posedge clk or negedge rst)
begin
if (!rst)
flag_cnt <= 4'b0000;
else
flag_cnt <= flag_cnt + 1'b1;
assign flag_en = flag_cnt = 4'b1111 ? 1: 0;
always @(posedge clk or negedge rst)
begin
if (!rst)
current_state <= s1;
else if(flag_en) //这里做一个延迟处理,具体打几个时钟看你需要。
current_state <= next_state;
end
//next_state 这段代码是组合逻辑啊,我给你改正下,注意=,<=的用法哈
always @(*)
begin
case (current_state)
s1:
if (…)
next_state = s3;
s2:
if (…)
next_state = s5;
…
default:
next_state = s1;
endcase
end
/*
//输出信号
always @(current_state or in)
begin
case (current_state)
s1:
if (…)
out = 1'b1;
s2:
if (…)
out = 1'b0;
…
default:
out = 1'b0;
endcase
end
*/
//以下这段代码改动比较大,自己体会哈
always @(posedge clk or negedge rst)
begin
if (!rst) begin
current_state <= s1;
out <= 1'b0;
end
else begin
case (next_state)
s1:
if (…)
out <= 1'b1;
s2:
if (…)
out <= 1'b0;
…
always @(posedge clk or negedge rst)
begin
if (!rst)
current_state <= s1;
else if(flag_en) //这里做一个延迟处理,具体打几个时钟看你需要。
current_state <= next_state;
end
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
上面这个状态转换的模块,为什么要做延迟处理?我觉得应该没有必要吧。。
------------------------------------------------------------------------------------------------------------------------------
always @(*)
begin
case (current_state)
s1:
if (…)
next_state = s3;
s2:
if (…)
next_state = s5;
…
default:
next_state = s1;
endcase
end
------------------------------------------------------------------------------------------------------------------------------
原先这个next_state模块case的default语句的非阻塞赋值,是我笔误了,不好意思,很感谢你指出。但是我想问为什么把我的敏感列表always@(current_state or in)改成了always@(*)。按照我的理解always@(*)的意思是把所有输入作为敏感列表,但是我的状态机里current_state变化了应该也是要对next_state进行赋值的,还是说我的理解有问题?
------------------------------------------------------------------------------------------------------------------------------
always @(posedge clk or negedge rst)
begin
if (!rst) begin
current_state <= s1;
out <= 1'b0;
end
else begin
case (next_state)
s1:
if (…)
out <= 1'b1;
s2:
if (…)
out <= 1'b0;
…
我这个问题是问非阻塞赋值。麻烦看一下以下两段代码和波形图。
1.
always @(posedge clk or negedge rst)
begin
if (!rst)
hint <= 1'b0;
else if ((current_state == 1'b1) &&
(bitstream == 2‘d60))
hint <= 1'b1;
else
hint <= hint;
end