Verilog HDL非预测问题分析
0赞Verilog HDL非预测问题分析
总是在不停的前进,总是在不停的徘徊,总是在不停的寻找,总是在不停的修复……只有不停的探索,才有可能突破极限,毕竟:Perfect has no limitation!
问题1:
去年遇到过一个蛋疼的问题,也许是因为基础不扎实,当让也不排除粗心的可能性,在移位的时候差点想崩溃……
mY <= Y<<9 + Y<<6 + Y<<4 + Y<<2;
如上以为代码所示:当时调试摄像头,将YUV色度空间转换到RGB,途中将乘除法巧妙转换位了移位算法,但是实际调试中百思不得其解。。。最后被人一板砖,原来是优先级的问题,废话不多说,直接改下下面就OK:
mY <= (Y<<9)+(Y<<6)+(Y<<4)+(Y<<2);
问题2:
(1)ACK <= ACK1 | ACK2 | ACK3; (2)ACK <= (~ACK1 & ~ACK2 & ~ACK3); (3)ACK <= ((ACK1 == 1'b0) && (ACK2 == 1'b0) && (ACK3 == 1'b0)) ? 1'b1 : 1'b0;
如上三种ACK的表达式,描述的电路为了达到ACK1,ACK2,ACK3同时为0的时候,输出1,然而(1)可行,(2)不可行,(3)竟然也不可行。。。
参照问题1,很好解释(2)不行,可是(3)为什么不行,死也无法给自己一个交代。。。。。。
问题3:
阻塞赋值和非阻塞赋值,很多人都茫茫然的。。。
看过有些人的代码,相当然的这样描述电路,说是综合之后都一样,无所谓:
always@(posedge clk or negedge) begin if(!rst_n) dout = 0; else dout = dout + 1'b1; end
当然实际RTL图看起来的确没啥问题。。。
然则,勿以恶小而为之,当"<="和"="出现在同一个模块中时,一山不容二虎,意想不到的问题发生了,请看下面一段代码:
reg i2c_transfer_en; //send i2c data before, make sure that sdat is steady always@(posedge clk or negedge rst_n) begin if(!rst_n) begin clk_cnt <= 0; i2c_transfer_en <= 0; end else if(delay_done) begin if(clk_cnt < (CLK_FREQ/I2C_FREQ) - 1'b1) clk_cnt <= clk_cnt + 1'd1; else clk_cnt <= 0; i2c_transfer_en = (clk_cnt == 16'd0) ? 1'b1 : 1'b0; end else begin clk_cnt <= 0; i2c_transfer_en <= 0; end end
有问题吗?。。。好像没问题,那就没问题吧。。。。继续写下面一段,状态转移,行云流水滔滔不绝,唰~~~
//Write I2C: {ID_Address, REG_Address, W_REG_Data} I2C_WR_START: begin if(i2c_transfer_en) next_state = I2C_WR_IDADDR; else next_state = I2C_WR_START; end
准备完毕。习惯性用modelsim前仿,通不过modelsim的面试,死也不会用Quartus II综合。仿真图如下,一切尽在不言中……
然则:
出现了一个状态1跳转到状态,以及状态2跳转到状态2,这未免太神奇了,无限倍的方法1-1或者2-2之间的状态,也没有出现异常的心情,干干净净的1或2,百思不得其解吗,想撞墙,崩溃了一个下午……
手贱打开Quartus II编译一下,惊奇的发现了傻瓜式的错误如下:
Warning (10268): Verilog HDL information at i2c_timing_ctrl.v(75): always construct contains both blocking and non-blocking assignments
回归到代码中,我竟然:
i2c_transfer_en = (clk_cnt == 16'd0) ? 1'b1 : 1'b0;
所谓一山不容二虎,而我却……这个看起没问题的问题,在状态上的后续操作造成了不可磨灭的bug。。。。
i2c_transfer_en <= (clk_cnt == 16'd0) ? 1'b1 : 1'b0;
不知道是自己敲太快了还是怎么,反正就是手贱了。。。重新修改i2c_transfer_en电路,如上所示。。。再次modelsim编译,干得漂亮。。。。
有些FPGA初学者,甚至从来不看Quartus II Waiming,认为警告不是错误,一撸而过。。。。而太多的时候,警告其实也是错误。。。比如:“警告处分”。。。。
Verilog HDL代码规范,风格,太重要,太重要。。。组合、时序、同步、异步。。。好的代码,可以避免时序违规,可以达到速度和面积的性价比,甚至可以省略时序约束。。。。
十年磨一剑,跌跌撞撞4年了,还是觉得自己是个菜鸟。。。。。