longt 发表于 2010-6-26 01:27:48

三段式状态机的代码问题

本帖最后由 fpgaw 于 2010-11-18 16:14 编辑

关于三段式状态机的一段是这么写的
//3rd always block, the sequential FSM output
always @ (posedge clk or negedge nrst)
if (!nrst)
{o1,o2,err} <= 3'b000;
else
begin
{o1,o2,err} <= 3'b000;
case (NS)
IDLE: {o1,o2,err}<=3'b000;
S1: {o1,o2,err}<=3'b100;
S2: {o1,o2,err}<=3'b010;
ERROR: {o1,o2,err}<=3'b111;
endcase
end

我的疑问是{o1,o2,err} <= 3'b000;这条语句,用的是非阻塞赋值,会不会和下面的语句冲突?

另外,在Samir Palnitkar著,夏宇闻译的《Verilog HDL数字设计与综合》中,也有关于状态机的例子,P108关于交通信号灯的例子,也是三段式的,不过他的输出逻辑是组合逻辑,always@(state)这样的,里面也是先给输出阻塞式赋值,赋默认值,然后case(state)再给输出赋值,这样做会不会有毛刺产生?

数字电路学的不好,还请大家多多指教

HANG 发表于 2010-6-26 03:09:56

没关系的,只要别阻塞和非阻塞混用,<br>
或是不同always块里对同一个寄存器赋值就好。<br>
毕竟还只是硬件描述,而不是真正的硬件,<br>
仿真器对同一个always块内对同一个寄存器两次<br>
同样类型的赋值语句的处理是<br>
只有后面那个起作用,呵呵。<br>
<br>
你看他的三段式里面第2段开始就对nextstate赋值,<br>
后面case里又对其赋值,跟这个原理是一样的。<br>
<br>
他们这样些一方面是代码简洁,<br>
一方面是减少在case下的某个状态漏写输出的情况。<br>
<br>
而我说的nextstate=3'bx;是为了检验逻辑正确。<br>
<br>
[ 本帖最后由 yljusting 于 2006-11-10 11:48 编辑 ]

AAT 发表于 2010-6-26 03:45:16

我也是正好看到这方面的资料。<br>
资料里是这么说的:<br>
<br>
Note: some misinformed engineers fear that making multiple assignments to the same variable, in the<br>
same always block, using nonblocking assignments, is undefined and can cause race conditions. This<br>
is not true. Making multiple nonblocking assignments to the same variable in the same always block <br>
is defined by the Verilog Standard. The last nonblocking assignment to the same variable wins!

usd 发表于 2010-6-26 04:35:10

谢谢yljusting的解释,有点明白了<br>
<br>
不过你贴的这段e文里说的是非阻塞赋值,阻塞赋值也适用吗

encounter 发表于 2010-6-26 04:42:51

这个我只能说我看到很多代码这么用,<br>
应该是适用的,不然你也可以自己写份代码<br>
仿真验证一下。<br>
当然最权威的还是去查verilog标准。。

HANG 发表于 2010-6-26 06:29:29

恩,应该自己仿真试试看

CCIE 发表于 2010-6-26 07:16:35

没有问题,可以用

tim 发表于 2010-6-26 08:21:11

always @(state)是电平触发,产生组合逻辑嘛,那时序怎么产生呀

interi 发表于 2010-6-26 08:36:57

不知道楼主说的和下面语句冲突是和哪句冲突?

CTT 发表于 2010-6-26 10:04:36

//3rd always block, the sequential FSM output<br>
always @ (posedge clk or negedge nrst)<br>
if (!nrst)<br>
{o1,o2,err} &lt;= 3'b000;<br>
else<br>
begin<br>
{o1,o2,err} &lt;= 3'b000;<br>
case (NS)<br>
IDLE: {o1,o2,err}&lt;=3'b000;<br>
S1: {o1,o2,err}&lt;=3'b100;<br>
S2: {o1,o2,err}&lt;=3'b010;<br>
ERROR: {o1,o2,err}&lt;=3'b111;<br>
endcase<br>
end<br>
<br>
个人认为,一个成熟的逻辑设计人员,是不应该写出这样的代码的。代码中不应该存在冗余代码,也不应该出现同一时刻多次赋值的情况,因为不利于理解。一个好的代码还要讲究缩进。我更改后的代码:<br>
always @ (posedge clk or negedge nrst)<br>
if (!nrst)<br>
&nbsp; &nbsp; {o1,o2,err} &lt;= 3'b000;<br>
else<br>
&nbsp; &nbsp; case (NS)<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;IDLE&nbsp; &nbsp;&nbsp; &nbsp;: {o1,o2,err} &lt;= 3'b000;<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;S1&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;: {o1,o2,err} &lt;= 3'b100;<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;S2&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;: {o1,o2,err} &lt;= 3'b010;<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;ERROR : {o1,o2,err} &lt;= 3'b111;<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;default : {o1,o2,err} &lt;= 3'b000;<br>
&nbsp; &nbsp; endcase<br>
<br>
<br>
另外,这种写法也不推荐。因为从代码背后的机制看,err这个比特只跟error这个状态相关,但是这种写法就和idle,s1,s2等其他状态相关了,好的综合工具可能会综合成不相关,不好的综合工具可能会综合成相关,从而浪费资源,如果资源紧张的话,会加重资源的紧张度。<br>
<br>
[ 本帖最后由 caesar000 于 2006-11-22 10:22 编辑 ]
页: [1] 2
查看完整版本: 三段式状态机的代码问题