如何设计可综合的Verilog代码和应该遵循什么原则

嵌入式技术

1368人已加入

描述

编写可综合的FPGA代码

在接触Verilog 语法参考手册的时候,我们发现其提供了一组非常丰富的功能来描述硬件。所以大家往往会疑惑那些Verilog语句是可综合的,那些是只能用于写Testbench的,其实,参考手册中只有一小部分语句是可综合的,但是这一小部分可综合的语法确是我们应用最为频繁的,可综合的意思就是可以通过物理工具进行编译、综合、布局布线,最终在FPGA上实现。

参考下面的例子。

reg [7:0] memory[1:2**22];

Initial begin

memory[1]=8’h1;

memory[2]=8’h2;

end

该示例虽然可以正常的仿真,但是用FPGA工具编译综合,最终在FPGA上实现。代码中定义了一个4M Byte的存储器,其实在FPGA中时没有这样的物理资源可以与其对应的,另外,FPGA编译综合工具在编译的时候也将忽略Initial块语句。

本文重点介绍如何设计可综合的Verilog代码。在设计可综合的Verilog代码的时候,我们应该遵循怎样的原则。

1. 坚持FPGA的同步设计原则

包括以下几个方面:

使用同步复位电路。

避免使用锁存器; 尽可能使用同步寄存器。

避免使用门控,派生或分频时钟。

使用时钟使能,而不是多个时钟。

实现所有异步信号的正确同步。

2. 理解综合工具的能力和局限性

充分了解综合工具的能力和局限性将有助于提高FPGA设计的性能、逻辑性、以及资源利用率和可生产性。熟悉特定FPGA系列的内部构造,以及综合工具所忽略或不支持的语言以及建议的寄存器,状态机,三态和其他推荐的编码风格非常重要。

3. 忽略语言结构

FPGA综合工具会忽略延迟值和时间标度编译器指令。设计人员经常利用延迟来使分析仿真波形变得更容易,如下例所示。

`define DLY 1

always @(posedge clk) begin

Data_out

end

因为潜在的综合和仿真失配,所以不鼓励使用这样的结构。例如,如果上例中的“DLY超过时钟周期,则综合电路可能在功能上不正确,因为它不会匹配仿真结果。绝大多数FPGA综合工具都忽略编译器指令,例如celldefine和endcelldefine。

FPGA综合工具忽略initial块描述。

综合工具为Verilog门级原语(如nmos,pmos,cmos,pullup,pulldown,

tranif0,tranif1,tran等)提供各种级别的支持。例如,XST不支持Verilog tranif原语,而Synplify则支持。 尽管Xilinx FPGA体系结构不具有门级原语的直接等价物,但一些综合工具将其转换为功能等效的门级开关。 以下是nmos转换的一个例子。

module nmos_switch(output out,intput data,control);

Assign out =control?Data :1’bz ;

endmoudle

4. 不支持的语句结构

不支持的语句结构包括有:用户自定义的原语(UDP),repeat,wait,

fork/join,deassign ,event,force/release 语句。也不支持模块内寄存器和网络的分层引用,如:

module mymodule1;

assign my_net =top.my_mudule2.my_net ;

endmoudle

相等和不相等运算符(===和!==)的支持级别取决于综合工具。有些综合工具在遇到一个等式和不等式运算符时会产生一个错误,而另一些则会将运算符转换为逻辑等式(==和!=)。

5. 2种状态和4种状态的比较

4态值(‘0’,‘1’,‘x’,‘z’)本质上是不可综合的。 FPGA架构仅支持2态值(逻辑“0”和“1”),综合工具将应用不同的规则来优化“z”和“x”综合的过程。这将导致综合和仿真结果之间的不匹配和其他错误。 在实现三态IO缓冲区的时候只使用‘z’值。

6. translate_on/translate_off

translate_off和translate_on表示让综合工具忽略Verilog代码的一部分。这些指令通常用于忽略IP核模型中的行为代码部分。以下是使用这些指令的示例。

module bram_2k_9 ( input clka, input [0 : 0] wea,

input [10 : 0] addra,

output [8 : 0] douta,

input [8 : 0] dina);

// synthesis translate_off

// behavioral description of bram_2k_9

// synthesis translate_on

endmodule // bram_2k_9

7. 特殊的编译指令也无法被综合

syn_keep指令可防止综合工具删除指定的信号。它适用于网络和组合逻辑。 该指令通常用于禁用不需要的优化,并保留手动创建的复制。综合工具不同syn_keep的作用可能会不同。例如,XST不会将约束传播到综合网表,这并不妨碍物理实现工具的优化。syn_preserve防止寄存器优化。XST还支持“Equivalent Register Removal”选项,相当于syn_preserve。syn_noprune确保如果未使用实例化原型的输出,则原型未被优化。XST也支持“Optimize Instantiated Primittives”选项,相当于syn_noprune。

8. parallel_case和full_case

如果在case,casex或casez语句中指定了full_case指令,则会阻止综合工具创建其他逻辑以涵盖未描述的条件。使用full_case指令可能会有更紧凑的效果。parallel_case指令强制将case语句综合成为并行复用器而不是优先级编码结构。使用parallel_case指令可能会提高电路的时序性能。

full_case和parallel_case指令的确切作用取决于综合工具。而且,使用这些指令也会导致综合和仿真不匹配。出于这些原因,不建议在FPGA设计中使用full_case和parallel_case指令。相反,设计师可以通过一个case语句的实现来达到同样的效果。例如,删除重叠的大小写条件会导致不必要的parallel_case指令。

9. 编译器指令 `default_nettype

Verilog-2001标准定义了一个`default_nettype编译器指令。 如果该指令被分配为“无”,则必须声明所有的1bit 信号网络。

// no `default_nettype

wire sum; // declaration is not required

assign sum = a + b;

`default_nettype none

wire sum; // must be declared

assign sum = a + b;

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分