时序模块之always语句
module PAOBIAO(a,b,c,d);input a,b,c;output d;reg d;
always@(posedge a or negedge b)if(b) d<=0;
else if(c)d<=1;endmodule
先看这么⼀段简单的程序,编译:提⽰错误。错在哪⾥?经过⼀晚上才终于琢磨透彻。这是错误提⽰:Error (10200): VerilogHDL Conditional Statement error at PAOBIAO.v(75): cannot match operand(s) in the condition to the corresponding edges inthe enclosing event control of the always construct
⼤概意思就是不能匹配操作条件中的边沿事件和always语句中的控制事件。错误指⽰在红⾊⼀⾏。仔细分析语法吧,看起来真的没有错啊。不断地修改再编译,⽆意中去掉了negedge b
这句,即酱红⾊部分改为always@(posedge clk),编译后没错了。⽹上搜也有⼈遇见过这种情况可是⼏乎没⼀⼈解释到正点上。最后答案还是在⾃⼰觉得编写的很垃圾的课本上找到了(因为刚上来我总觉得这本书⼀⼤堆屁话,看不懂把浅显的问题说的那么复杂,呵呵,看来该改变下⾃⼰的态度了)。
加上我的理解分析⼀下吧:⾸先这很明确要描述的是⼀个时序模块电路(这⾥仅讨论带posedge or negedge 的时序模块),敏感信号列表⾥有a和b两个信号,但是边沿敏感时钟信号只能有⼀个,如何区分哪个是时钟信号?规定是这样的,如果把a定义为时钟信号,那么在always过程结构中不能再出现a信号了,如上⾯例⼦就可以看出a是作为时钟信号的。这也满⾜要求似乎不应该编译出错啊,还有⼀点就是剩余的b了,这个b在这⾥是⼀个异步控制信号(或者是异步输⼊信号),这个b除了在敏感信号表中给出对应的表述外(即always后的negedge b)在always过程语句中必须给予说明(经实践是always结构中带if语句的,不带if语句也可不说明),简单的说就是在always语句中加⼊有if语句则必须把b放在if的()中作为判定条件。看上⾯例⼦,b也组为了判定条件可是为什么还会报错?还有⼀点经过实践,假如在敏感信号⾥表中描述的是negedge b,则必须是if(!b),如果是posedge b则必须是if(b)。所以这⾥想要改正错误有两种⽅法:⼀、如上所述,去掉红⾊部分的negedge b,但是这样改已经改变了程序的功能;⼆、将if(b)改为if(!b),可以想想把if(b)作为判断条件没有实际意义的。
最后还有⼀点就是把else if(c)中的c换为!b即else if(!b),由此看来假如把b作为敏感控制信号,并且always语句中出现if语句的话,则b必须在第⼀条if语句中判断,若放在后⾯的else if语句中就会编译出错。
2012.05.04
(wzt笔记)
LZ,这地⽅理解的不够,有点浅,
本质应该是在FPGA的底层FF中没有你描述的单元与之对应:
always中⽤的是negedge b 即此处b信号对应与底层FF异步复位端且低电平有较,⽽在下⾯if 中⽤的是⾼电平有较对d复位。综合⼯具⽆法将这⽭盾的描述转化成实际电路,所以报错。
1,改1 if ( !b ) 即低电平有较,d 复位,与negedge b描述正确。
2,改2 去了negedge b,原因是你改⽤了同步复位⽅式。在always列表是没有对对沿的触发⽅式作表述,不存在⽭盾。