标签归档:HDL

Verilog一段错误代码分析

reg [3:0] Count_EN;
localparam PWen=4'd12;
always@(posedge CLK or negedge RST)
begin
  if(!RST)
    Count_EN<=0;
  else if(Count_EN==PWen)
    Count_EN<=0;
  else
    Count_EN<=Count_EN+1'b1;
end

此电路存在一个问题即:

Count_EN没有初始化值。

也就是说:当RST从一开始的时候就是1的话,即不满足条件一,Count_EN<=0不执行。那么Count_EN将一直处于不定态。于是else语句的加1操作相当于在一个不定态加1,得出的结果自然还是不定态。所以电路最终不能实现计数功能!

从仿真结果看:

counter_en_x

继续阅读

学习笔记之:HDL的优缺点

HDL具有通用性并且允许对电路的实现进项各种各样的控制。但即是优点也是缺点。

优点是:开发者可以针对硬件进行针对性的优化设计。但这也带来了缺点,即是:开发者必须深入到每一个细节进行精细的控制,包括数据和流程控制。因此对于复杂算法的编程相当困难。

为了解决上面的缺点,于是对高级语言,尤其是C语言进行硬件综合方面进行了相当多的研究。但硬件本身是并行的,每一步或者每一个运算都有独立的硬件执行。相比之下,软件通过重复使用CPU进行运算,使之本质上是串行的。这也是HDL描述电路时,与编程思维不同的原因。

所以时刻牢记FPGA开发属于硬件设计工作是十分重要的。进行硬件设计与进行软件设计需要不同的能力。即使是基于C语言的来描述设计,时刻牢记正在构建或者算法本身所暗指的结构也是非常重要的。并不是所有的软件算法都可以很好的映射到硬件上。例如,除非很好的保持上下文内容并将之调用,否则递归就不能被很好的映射到硬件上。因此这项工作需要面向硬件的思维模式。

Verilog学习笔记——之重点

verilog原本被设计成一种仿真语言,而不是一种综合语言,所以verilog HDL中很多逻辑描述没有相应的硬件可以对应。因此如果程序只用于仿真,那么verilog中的所有语句和语法都可以使用。但如果用于硬件电路的实现,则许多的语句和描述方式都是不可综合的。

  • 只有寄存器类型的信号才可以在always和initial 语句中进行赋值,类型定义通过reg语句实现。
  • always 语句是一直重复执行,由敏感表(always 语句括号内的变量)中的变量触发。
  • always 语句从0 时刻开始。
  • 在begin 和end 之间的语句是顺序执行,属于串行语句。书写规范
  • 用有意义的有效的名字如 Sum 、CPU_addr等。
  • 用下划线区分词。
  • 采用一些前缀或后缀,如时钟采用Clk 前缀:Clk_50,Clk_CPU;低电平采用_n 后缀:Enable_n;
  • 统一一定的缩写 如全局复位信号 Rst。
  • 同一信号在不同层次保持一致性,如同一时钟信号必须在各模块保持一致。
  • 自定义的标识符不能与保留字同名。
  • 参数采用大写,如SIZE 。

继续阅读

为什么是“硬件描述语言”而不是“硬件设计语言”

“描述”一词说明电路不是凭空设计出来的,而是在能够实现的基础之上通过某种语言来描述他们的互联关系。早期的数字电路设计采用原理图设计方法,其本质上也是对电路的一种描述。它用原理图的形式将各种逻辑电路互联在一起。但随着电路的发展,采用原理图来设计数字电路已经显得力不从心了,因此便采用所谓的硬件描述语言来描述电路的互联关系。

由此也可以看出,硬件描述语言和计算机编程语言有着本质的差别。HDL必须基于硬件的实现基础之上,也就是说硬件描述语言所描述的电路必须是能够实现的。而计算机编程语言则不在乎电路的实现。因此当编写或阅读硬件描述语言的时候,从硬件结构的角度而不是从顺序算法的角度来考虑的话,将更容易理解。

也因为这个缘故,在编写代码的时候,应以导出电路为目的,而不是描述一个顺序的C语言算法。如果不能做到这一点,则会经常导致代码的不可综合,实现复杂,或仿真和综合之间存在差异。例如,同一个变量在多个always块中被赋值。在verilog语法中是允许这种情况,并且可以仿真。但是却无法综合。

🙂