SystemVerilog相对于Verilog添加了很多新特性,比如使用起来非常方便的累加++或递减--操作符。有这么好的变化,再也不用傻傻的写cnt <= cnt + 1了。在一个新项目中毫不犹豫的用了起来。
always_ff @ (posedge clk) begin
if( rst ) cnt <= 4'h0;
else if( wr_trans_bus.wr_i ) begin
if( cnt == WR_NUM-1 ) cnt <= 4'h0;
else cnt++;
end
if( wr_trans_bus.wr_i && (cnt == WR_NUM-1) ) wr_trans_bus.wr_o <= 1'b1;
else wr_trans_bus.wr_o <= 1'b0;
if( rst ) wr_trans_bus.wr_addr_o <= 'h0;
else if( wr_trans_bus.wr_o ) wr_trans_bus.wr_addr_o++;
end
上面的程序看起来毫无问题,每当wr_trans_bus.wr_i为1时,如果cnt == WR_NUM-1条件不满足,cnt累加。当wr_trans_bus.wr_i && (cnt == WR_NUM-1)条件满足时,wr_trans_bus.wr_o输出1。在上述时序逻辑中,cnt == WR_NUM-1的下一个周期,wr_trans_bus.wr_o才会输出1。
下面是仿真结果,wr_trans_bus.wr_o非常诡异的表现出了组合逻辑的特性。注意图中蓝色部分,当下方的cnt等于2时,wr_trans_bus.wr_o立即为高了。
只能祭出法宝,翻IEEE标准。在SystemVerilog中,++是一个阻塞赋值!!!
所以在使用新特性时,最好看看标准,先掌握其使用方法再实践。使用++确实写起来快一些,整个程序算下来省了好几分钟,但是调试这个问题花了两个小时......
老老实实改代码,把cnt++修改为cnt <= cnt+1后,仿真结果正确了。