状态机中某条语句貌似没有执行是怎么回事??
本帖最后由 fpgaw 于 2010-11-18 16:20 编辑我的状态机碰到一个奇怪的问题,现在不清楚是不是状态机的问题
大虾们帮我看看
。。。
parameter Idle= 2'b00,
Wt_L= 2'b01,
Wt_S= 2'b10,
Svda= 2'b11;
always@(posedge clk)
if(!reset)begin
state <= Idle;
wr <= 0
end
else
case(state)
Idle: begin
if(!save_flag)
state <= Wt_L;
else
state <= Idle;
end
Wt_L: begin
if(!L) begin
state <= Wt_S;
wr <= ~wr;
end
elsestate <= Wt_L;
end
Wt_S: begin
if(save_flag)
state<= Svda;
else
state <= Wt_S;
end
Svda: begin
if(!save_flag)
state <= Wt_L;
else
state <= Svda;
end
endcase
end
。。。
其中save_flag 与wr 有关,只有在wr信号翻转后由外围电路产生。
状态机一开始正确,在循环了 n 次(n为不确定值)之后,就停在了状态 Wt_S,经查发现当L 由高电平变为低电平,状态 由Wt_L变为Wt_S ( state <= Wt_S )
但是示波器中观测到 wr 却没有翻转 ( wr <= ~wr ), 好像 wr <= ~wr 这句没有执行一样, 但是状态却是变了 state <= Wt_S
请教大家,是什么原因. 大虾们在哪呢<br>
<br>
帮我看看呐~~~~~~ Wt_L: begin<br>
if(!L) begin<br>
state <= Wt_S;<br>
wr <= ~wr; <br>
end<br>
else state <= Wt_L;<br>
end问题应该是: 在L由低变高之前,有没有时钟上升沿<br>
如果没有 wr <= ~wr; 就不会被执行。 明白你的意思是:L 低电平刚好处在时钟相邻两个上升沿之间<br>
<br>
但问题是 从示波器上可以看到 L 由高电平变为了低电平后一直保持着低电平(需要由状态SvDa 才能使 L回复高电平),而且更奇怪的是 状态已经由 Wt_L 变成了 Wt_S , 也就是说语句 state <= Wt_S 被执行了, 而 wr <= ~wr 没有被执行 !!! 状态机里就是从一个状态变到另一个状态,可是里面是怎么运行的啊?<br>
感觉没什么内容啊,和不用状态机的写法来说。 你把状态机的相关输入信号都先用时钟锁一拍<br>
很有可能是异步信号输入导致状态机不正常 从逻辑上来说,这样应该不会有问题.<br>
但楼主这样写状态机,感觉有点不太合适,换一种状态机写法试一下吧. 用两段式或三段式状态机会更好些,即::一个always 模块采用同步时序描述状态转移;另一个模块采用组合逻辑判断状态转移条件,描述状态转移规律 问题得到了解决: 我看了 CROSSTALK 的帖子 “急,状态机求助” , 用D触发器 “过滤“了一下芯片外输入信号,状态机就正常了。 亦如 gucheng82 所写<br>
“ 你把状态机的相关输入信号都先用时钟锁一拍<br>
很有可能是异步信号输入导致状态机不正常 “<br>
但还是不太明白为何状态机不正常会出现这样的现象。 应该是异步信号的原因,你最好把always那条语句的监控改成和状态信号同步的
页:
[1]
2