0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Verilog编码风格

FPGA之家 来源:FPGA之家 作者:FPGA之家 2022-06-26 10:46 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

一、Verilog 编码风格

(本文的语法高亮因为浏览器的缘故,所以不准确)

1.1 使用“`include编译器指令”

文件包含“`include编译器指令”用于在合成过程中将源文件的全部内容插入到另一个文件中。它通常用于包括全局项目定义,而无需在多个文件中重复相同的代码。另一个用例是将代码的一部分插入模块,如以下示例所示:

// file test_bench_top.v
// top-level simulation testbench
module test_bench_top;
`include “test_case.v”
endmodule
// file test_case.v
initialbegin
//…
end
task my_task;
//…
endtask

> include编译器指令的语法定义为:`include

可以是文件名,还可以包含绝对或相对路径名:

`include“test_case.v”
`include“../../includes/test_case.v”
`include“/home/myprojects/test/includes/test_case.v”

建议仅在include中使用文件名,而不要使用绝对或相对路径名。这将使代码位置独立,因此更加可移植。另一个建议是保持包含文件简单而不使用嵌套的include指令。

1.2使用`define编译器指令,parameter和localparam


`define是文本宏替换编译器指令。它定义为:`define

可以包含带有可选参数列表的单行或多行文本。

`define具有全局范围。一旦定义了文本宏名称,就可以在项目中的任何地方使用它。文本宏通常是用于定义状态名称,常量或字符串的简单标识符。

parameter关键字定义模块特定的参数,该参数在特定模块实例的范围生效。参数用于为模块实例提供不同的自定义,例如,输入或输出端口的宽度。以下是使用parameter关键字的示例:

module adder #(parameter WIDTH = 8) (
input[WIDTH-1:0] a,b, output [WIDTH-1:0] sum );
assign sum = a+ b;
endmodule // adder
// aninstance of adder module
adder # (16) adder1 (.a(a[15:0]),.b(b[15:0]),.sum(sum[15:0]));

localparam关键字与parameter相似。它被分配了一个常量表达式,并在特定模块内具有作用域。它定义为:

1.3 使用函数

以下是执行XOR操作的Verilog函数的简单示例:

module function_example( inputa,b, output func_out);
functionfunc_xor;
inputa, b;
begin
func_xor = a^ b;
end
endfunction
assign func_out = func_xor(a,b);
endmodule // function_example

建议使用Verilog函数来实现组合逻辑和其他不需要非阻塞分配的操作,例如同步逻辑。使用函数可以编写更紧凑和模块化的代码。所有综合工具均支持Verilog函数。

1.4使用 generate块

在Verilog-2001中引入了generate块,以使对同一模块,函数,变量,网络和连续分配的多个实例的实例化变得容易。以下是使用generate的两个示例:

// aconditional instantiation of modules
parameter COND1 = 1;
generate
if(COND1) begin : my_module1_inst
my_module1 inst (.clk(clk), .di(di), .do(do));
end
elsebegin : my_module2_inst
my_module2 inst (.clk(clk), .di(di), .do(do));
end
endgenerate

// using forloop in generate block
genvar ii;
generate
for(ii = 0; ii < 32; ii = ii+1) begin: for_loop
my_module1 inst (.clk(clk), .di(di[ii]), .do(do[ii]));
end
end
endgenerate

1.5 开发简单的代码

始终努力开发简单的代码。与每种编程语言一样,Verilog允许编写详细的语句,从功能的角度来看,这些语句很优美,但可读性不高。下面的简单示例说明了这一点:

reg [5:0] sel;
reg [3:0] result1,result2,a,b;
always @(*) begin
result1 = sel[0] ? a + b : sel[1] ? a - b :
sel[2] ? a & b : sel[3] ? a ^ b :
sel[4] ? ~a : ~ b;
if(~|sel)
result1 = 4'b0;
end// always

reg [5:0] sel;
reg [3:0] result1,result2,a,b;
always @(*) begin
casex(sel)
6'bxxxxx1: result2 = a + b;
6'bxxxx10: result2 = a - b;
6'bxxx100: result2 = a & b;
6'bxx1000: result2 = a ^+ b;
6'bx10000: result2 = ~a;
6'b100000: result2 = ~b;
default: result2 = 4'b0;
endcase
end // always

实现result1和result2的逻辑在功能上是等效的。但是,在result1中使用嵌套三元运算符和两个赋值语句不太透明,并且与result2逻辑的更清晰的case语句相比,需要花更多的精力来理解。

通常,代码清晰度高容易实现高效率。同一段代码能在其生命周期内被多个开发人员读取。编写更清晰的代码更容易调试,并且一般不容易包含错误。

二、为FPGA编写可综合的代码

2.1考虑资源

Verilog语言参考手册(LRM)提供了丰富的功能来描述硬件。但是,只有一部分语言可以为FPGA综和。即使有些特定的语言结构是可综合的,也不能保证该代码能在特定FPGA上实现物理电路。考虑以下示例:

reg [7:0] memory[1:2**22];
initial begin
memory[1] = 8’h1;
memory[2] = 8’h2;
end

该示例能正确模拟出来,但会导致FPGA物理实现失败。该代码需要4 MB的内存,这是一些FPGA所没有的。此外,综合工具将忽略初始块,该块将初始化内存的最低两个字节。

该技巧提供了一些指导方针和建议,以帮助编写用于FPGA的可综合代码。

2.2 遵循同步设计原则

建议开发人员遵守FPGA同步设计的原则,其中包括以下内容:

1、使用同步复位。后续会详细讨论,同步,异步复位的问题

2、避免使用锁存

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

4、使用时钟使能而不是多个时钟

5、对所有异步信号实行正确同步

审核编辑 :李倩

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

    关注

    1663

    文章

    22493

    浏览量

    638939
  • Verilog
    +关注

    关注

    30

    文章

    1374

    浏览量

    114709

原文标题:学习FPGA的小Tips(一)

文章出处:【微信号:zhuyandz,微信公众号:FPGA之家】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    磁铁在编码器中的作用与应用

    编码器中,磁铁的作用不可小觑,常用的磁性材料主要是钕铁硼和铁氧体,今天这篇文章主要介绍下磁铁用于哪些编码器类型,以及其具体作用。磁铁在编码器中的作用(功能)是什么?在编码器中,磁铁主
    的头像 发表于 03-19 14:42 333次阅读
    磁铁在<b class='flag-5'>编码</b>器中的作用与应用

    Verilog HDL语法学习笔记

    Verilog HDL 语 言 最 初 是 作为 Gateway Design Automation 公 司 ( Gateway DesignAutomation 公司后来被著名的 Cadence Design Systems 公司收购)模拟器产品开发的硬件建模语言。
    的头像 发表于 03-04 15:04 5732次阅读
    <b class='flag-5'>Verilog</b> HDL语法学习笔记

    hcs301 编码跳变编码器应用手册

    电子发烧友网站提供《hcs301 编码跳变编码器应用手册.pdf》资料免费下载
    发表于 02-09 16:35 0次下载

    Linux内核编码风格权威总结:从缩进到底层设计,让你的代码更“内核味”

    作为全球最庞大的开源项目之一,Linux 内核的代码量早已突破千万行。要让来自世界各地的开发者高效协作,一套统一、严谨的编码风格必不可少 —— 这不仅是 “代码颜值” 的要求,更是可读性、可维护性的核心保障。
    的头像 发表于 02-09 16:29 266次阅读
    Linux内核<b class='flag-5'>编码</b><b class='flag-5'>风格</b>权威总结:从缩进到底层设计,让你的代码更“内核味”

    Vishay USB编码器接口技术解析与应用指南

    Vishay/MCB Industrie RAMK/RAME USB编码器接口是一款设计用于Vishay MCB编码器(AMK和RAME系列,包括霍尔效应)的电子板。该接口板只需使用随附的USB
    的头像 发表于 11-12 11:51 1112次阅读

    请问verilog文件开头部分的@00080000是什么意思?

    请问verilog文件开头部分的@00080000是什么意思??
    发表于 11-06 08:10

    使用NucleiStudio生成tb仿真需要的.verilog文件

    打开仿真顶层文件tb_top.v,存放在ITCM模块里面的指令是通过readmemh函数读入.verilog文件实现的: 下面通过对NucleiStudio IDE进行设置,实现将c
    发表于 11-05 07:07

    NucleiStudio如何生成.verilog文件和.dasm文件,以及对.dasm文件中自定义指令反汇编结果分析

    硬件设计需要.verilog文件来运行加NICE后的tb仿真、软件组需要.dasm来确定自定义指令有无被正确编译。今天,我们来分享一下NucleiStudio如何生成.verilog文件和.dasm
    发表于 10-24 06:33

    Verilog实现使用Booth编码和Wallace树的定点补码乘法器原理

    对于有符号整数乘法操作,E203使用常用的Booth编码产生部分积,然后使用迭代的方法,每个周期使用加法器对部分积进行累加,经过多个周期的迭代之后得到最终的乘积。其基本硬件原理图如图所示,从而实现多
    发表于 10-23 08:01

    Bourns发布全新增量式微型编码

    Bourns 推出 PEC04 系列 4 mm 增量式微型编码器、PEC05 PEC05 系列 5 mm 增量式微型编码器,以及 PEC06 型号 6 mm 增量式微型编码器。Bourns 全新微型
    的头像 发表于 09-22 16:05 1438次阅读

    绝对值编码器与增量式编码器相比有哪些优势?

    绝对值编码器与增量式编码器相比有哪些优势?核心功能:断电后位置信息不丢失,绝对值编码器:通过机械结构或电子存储(如电池备份),能实时输出当前位置的唯一绝对值编码(如二进制、格雷码)。无
    的头像 发表于 08-11 13:57 2007次阅读
    绝对值<b class='flag-5'>编码</b>器与增量式<b class='flag-5'>编码</b>器相比有哪些优势?

    增量型编码器与绝对值型编码器怎么选择?

    在选择增量型编码器与绝对值型编码器时,需要考虑多个因素,包括应用需求、成本、精度、可靠性以及环境适应性等。以下是对两种编码器的详细比较及选择建议: 一、增量型编码器 1. 优点:  
    的头像 发表于 07-10 10:34 1768次阅读

    RTL级机器人电机控制器的FPGA设计

    借助Verilog,在FPGA中实现了带编码器的两台电机的电机控制系统的RTL级设计。
    的头像 发表于 07-07 14:01 3066次阅读
    RTL级机器人电机控制器的FPGA设计

    verilog模块的调用、任务和函数

    在做模块划分时,通常会出现这种情形,某个大的模块中包含了一个或多个功能子模块,verilog是通过模块调用或称为模块实例化的方式来实现这些子模块与高层模块的连接的.
    的头像 发表于 05-03 10:29 1724次阅读
    <b class='flag-5'>verilog</b>模块的调用、任务和函数

    一文读懂什么是磁性编码

    磁性编码器是一种用于测量角度和线性位置的传感器。它使用磁性信号来监测旋转或线性位置的变化,并把这些变化转换成数字信号。磁性编码器可用于各种应用中,比如机器人、汽车、数控机床等领域
    的头像 发表于 04-27 17:18 1229次阅读