VHDL & Verilog HDL 语言编程的经验之谈

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/evolone/article/details/76218381

1.最近debug代码,发现一个RAM的读有问题。
波形大意是:
首先一共给RAM写了16个数据,然后再去依次读取数据,这个时候问题就来了,前面十五个数据都能正确读出,最后一个数据非但不能正确读出,而且还显示是红色未知不确定的值(XXXXXX)。

这是怎么回事?

首先怀疑是没有正确写入。
去查看写入的代码及波形,并无异常。
其次,怀疑是没有正确读取,或许是读取地址有问题,读到未写值的地址栏。
去查看读取的代码及波形,代码没有问题,波形中的使能信号及地址也完全正确,并无异常。

那是什么原因?

后面偶然查看波形发现,在写入阶段完成后,又进行了对第16个地址的写操作,而且一直持续。
反复查看分析代码及波形发现,因为tb代码没有写完备,if else语句,只写了if阶段的控制,没有写else阶段的控制,所以在超出控制条件后,会生成不想要的锁存器,使得使能/地址等信号会一直保持最后一次的有效值。
于是,因为一直在写第十六个地址的值,自然无法正常读取。
代码示例:

//示例1
always @ (posedge clk)begin
  if(a == 1) begin
    b <= 1;
  end
end

示例1,只有if语句,没有对应的else语句。
那么在条件a从1变成0时,b的输出值会一直保持为最后一次有效值,这里是1.
如果只看b的波形,那么就会发现,在a从1->0后,b的值一直保持1,没有变化。

//示例2
always @ (posedge clk)begin
  if(a == 1) begin
    b <= 1;
  end
  else begin
    b <= 0;
  end
end

示例2,if语句有对应的else语句。
那么在条件a从1变成0时,b的输出值会跳变并保持为0.

Verilog语言存在两种赋值方式:阻塞赋值(=,串行)与非阻塞赋值(<=,并行)。

掌握可综合风格的Verilog模块编程的八个原则会有很大的帮助。在编写时牢记这八个要点可以为绝大多数的Verilog用户解决在综合后仿真中出现的90-100% 的冒险竞争问题。

1) 时序电路建模时,用非阻塞赋值。

2) 锁存器电路建模时,用非阻塞赋值。

扫描二维码关注公众号,回复: 3045340 查看本文章

3) 用always块建立组合逻辑模型时,用阻塞赋值。

4) 在同一个always块中建立时序和组合逻辑电路时,用非阻塞赋值。

5) 在同一个always块中不要既用非阻塞赋值又用阻塞赋值。

6) 不要在一个以上的always块中为同一个变量赋值。

7) 用$strobe系统任务来显示用非阻塞赋值的变量值

8) 在赋值时不要使用 #0 延迟

猜你喜欢

转载自blog.csdn.net/evolone/article/details/76218381
今日推荐