前言

与大多数编程语言一样,我们应该尝试使尽可能多的代码可重用。

这使我们可以减少将来项目的开发时间,因为我们可以更轻松地将代码从一种设计移植到另一种设计。

我们在verilog中有两个可用的构造,它们可以帮助我们编写可重用的代码-parameter和generate语句。

这两种构造都允许我们创建更多的通用代码,我们在实例化组件时可以轻松地对其进行修改以满足自己的需求。

文章首发:https://www.ebaina.com/articles/140000010031

Verilog参数

在verilog中,参数是常量的局部形式,当我们实例化模块时,可以为其分配一个值。

由于参数的范围有限,因此我们可以多次调用同一个verilog模块,并为该参数分配不同的值。这使我们可以动态配置模块的行为。

我们都知道编写模块时必须定义模块的接口。然后,我们可以使用该接口互连FPGA设计中的许多不同模块。

作为此接口的一部分,我们可以声明参数以及模块的输入和输出。

下面的Verilog代码片段显示了我们用于在模块中声明参数的方法。当在这样的verilog模块中声明参数时,我们称其为参数化模块。

module <module_name> #(parameter <parameter_name> = <default_value> )(// Port declarations);

上面的Verilog代码中的<parameter_name>字段用于为我们的参数提供标识符。

具体示例:

模块计数器有两个参数N和DOWN,声明其默认值分别为2和0。N控制输出的位数,有效控制计数器的宽度。默认情况下,它是一个2位的计数器。参数DOWN控制计数器是递增还是递减。默认情况下,计数器将递减,因为该参数被设置为0。

module counter#(     parameter N = 2,parameter DOWN = 0)( input                            clk,input                           rstn,input                          en,output   reg [N-1:0] out);always @ (posedge clk) beginif (!rstn) beginout <= 0;end else beginif (en)if (DOWN)out <= out - 1;elseout <= out + 1;elseout <= out;endend
endmodule

我们使用该标识符来调用代码中的参数值,就像使用普通变量一样。

在上面的示例中,我们还可以使用<default_value>字段将默认值分配给我们的参数。

这很有用,因为它允许我们实例化组件,而不必专门为参数分配值。

例如,我们对上述实际示例的例化:

module design_top (    input clk,input rstn,input en,output [1:0] out);counter #(.N(2)) u0 ( .clk(clk),.rstn(rstn),.en(en));
endmodule

我们对一个参数分配了参数值,另一个参数没有分配,则编译工具对于另一个参数的处理是使用默认值。也就是0.

当我们在Verilog设计单元中实例化模块时,可以使用named关联或positional关联为参数分配一个值。这与将信号分配给模块上的输入或输出完全相同。

但是,当我们编写使用verilog 1995标准的代码时,只能使用位置关联将值分配给参数。

下面的Verilog代码片段显示了在实例化模块时用于为参数分配值的方法。

// Example of named association
<module_name> # (// If the module uses parameters they are connected here.<parameter_name> (<parameter_value>))<instance_name> (// port connections);// Example of positional association<module_name> # (<parameter_values>)<instance_name> (// port connections);

Verilog参数化模块示例

为了更好地理解我们如何在verilog中使用参数,让我们考虑一个基本示例。

对于此示例,让我们考虑一个需要两个同步计数器的设计 。这些计数器之一为8位宽,而另一个为12位宽。

为了实现该电路,我们可以编写两个不同的计数器组件,它们具有不同的宽度。但是,这是对我们的电路进行编码的低效率方式。

相反,我们将编写一个计数器电路,并使用一个参数来更改输出中的位数。

由于理解我们如何使用参数化模块并不重要,因此在此示例中将排除功能代码。

相反,我们将仅研究如何在verilog中声明和实例化参数化模块。

下面的Verilog代码片段显示了我们如何编写参数化计数器模块的接口。

module counter #(parameter BITS = 8)
(input wire clock,input wire reset,output reg [BITS-1 : 0] count);endmodule

在此示例中,我们看到了如何使用参数来调整Verilog中信号的大小。

而不是使用固定的数字声明端口宽度,我们将参数值替换为端口声明。

这是Verilog中参数最常见的用例之一。

在上面的verilog代码中,我们将BITS参数的默认值定义为8。

因此,仅当我们想要非8位的输出时,才需要为参数分配一个值。

下面的代码片段显示了当我们需要12位输出时如何实例化此模块。

在这种情况下,我们在实例化verilog模块时必须超越参数的默认值。

counter # (.BITS (12)) count_12 (.clock  (clock),.reset  (reset),.count  (count_out));

尽管在上面的示例中使用了命名关联,但是我们也可以使用位置关联为verilog中的参数分配值。

下面的代码段显示了如何使用位置关联将值12分配给BITS参数。

counter # (12) count_12 (.clock  (clock),.reset  (reset),.count  (count_out));

localparam

参数的声明方式不仅有parameter这种方式,还有一种localparam的语法,不过它当然与parameter有所区别:

localparam模块内有效的定义,是局部变量,不可用于参数传递,也不能被重定义。

它用来生成循环,生成维数可扩展的模块,localparam是局部参数,但它不能被重定义,也就是说在实例化的时候不能通过层次引用进行重定义,例如parameter可以通过#(参数)来进行重新定义,但是localparam不可以,只能通过源代码来改变。

什么时候?什么场合用这种参数比较好呢?

例如我们可以在设置状态变量的时候使用它,因为状态变量属于模块专属,我们不需要对其进行传递,也不需要对其进行更改,我们也可以对CPU的总线地址等使用它,总之,一切不需要进行参数传递的地方均可以使用。

localparam的语法:

module <module_name> (// Port declarations);localparam <parameter_name> = <default_value> ;endmodule

或对于多个局部参数的定义:

module <module_name> (// Port declarations);localparam <parameter_name1> = <default_value1> ,<parameter_name2> = <default_value2> ,<parameter_name3> = <default_value3> ,            ;endmodule

FPGA的设计艺术(12)使用parameter构建可重用的逻辑设计相关推荐

  1. FPGA的设计艺术(13)使用generate语句构建可重用的逻辑设计

    前言 本文首发:https://www.ebaina.com/articles/140000010059 我们在verilog中使用generate语句在我们的设计中有条件地或迭代地生成代码块. 这使 ...

  2. 【Verilog零基础入门-边看边练】学习笔记——第三讲 组合逻辑代码设计和仿真(补码转换和七段译码逻辑设计)(二)

    二.七段译码逻辑设计 所需软件 Verilog编程软件:Lattice Diamond(3.11.0.396.4_Diamond_x64) Verilog仿真软件:ModelSim SE-64 10. ...

  3. FPGA逻辑设计回顾(12)RAM以及ROM的RTL设计及其验证

    前言 本文首发:FPGA逻辑设计回顾(12)RAM以及ROM的RTL设计及其验证 RAM以及ROM在FPGA中的实现大体有两种方式,一种是使用IP核定制,一种是RTL设计. 也许有人会反驳,那原语呢? ...

  4. 移动平台动画设计的12个原则

    移动端动画设计的12个原则 在移动设备用户体验设计领域,微妙精致的动画已成为非常重要的设计元素.为任何对象添加动画并不简单,需要观察研究在真实世界中物体是如何在时空中运动的,需要设计者关注细节,并且具 ...

  5. 很多字段的数据要插入另一张表_一文看懂数据库设计之逻辑设计,值得收藏

    概述 数据库逻辑设计是从事数据库应用设计.开发.运行维护等各方面工作的一个重要的基础性工作.根据不同业务和应用需求,确定并遵循数据库逻辑设计原则,例如按照第三范式开展逻辑设计,不仅能满足减少数据冗余. ...

  6. project开发的程序设计与逻辑设计

    非常多时候我们要做庞大project, 就像一棵大树, 方方面面都有自己的细枝末节,而作为开发员的我们,无法时时刻刻去保持对程序的全面认知,所以我们要把程序设计与逻辑设计区分开来. 那么什么是程序设计 ...

  7. 数字电路逻辑设计笔记(2):逻辑代数基础

    数字电路逻辑设计笔记(2):逻辑代数基础 参考教材:<数字电路逻辑设计>欧阳星明 人民邮电出版社 参考教程: 中国大学MOOC 西安工业大学<数字电子技术基础> 文章目录 数字 ...

  8. mysql逻辑设计_一文看懂数据库设计之逻辑设计,值得收藏

    概述 数据库逻辑设计是从事数据库应用设计.开发.运行维护等各方面工作的一个重要的基础性工作.根据不同业务和应用需求,确定并遵循数据库逻辑设计原则,例如按照第三范式开展逻辑设计,不仅能满足减少数据冗余. ...

  9. FPGA的设计艺术(11)FPGA的构建过程

    前言 本文讨论FPGA的构建过程,由于FPGA的过程太多了,恐怕会有歧义,这个过程,不是开发过程,不是开发流程,而是实实在在的FPGA编译的过程,使用编译恐怕不是太合适,但是大家都叫习惯了,也知道FP ...

最新文章

  1. USEARCH11发布,新功能简介
  2. PC登录Citrix WI时报CPS license acquisition error(500)错误 截图及解决
  3. Qt实践| HTTP知识点-接入某图片验证码系统查询余额
  4. unique-substrings-in-wraparound-string(好)
  5. DataContractJsonSerializer 没有using 类库找不到
  6. github因网络问题无法git clone解决办法
  7. 通俗易懂!视觉slam第三部分——slam数学表示
  8. Windows下Apache架站务实
  9. 打开计算机管理时,提示找不到Apphelp.dll
  10. java基础之集合:List Set Map的概述以及使用场景
  11. Qt中添加静态库.lb,.a和动态库.dll,.so,头文件和.cpp文件
  12. Anima Toon:体素角色动画软件
  13. 彩色图像加密matlab算法,彩色图像混沌加密算法
  14. python常用写法
  15. 提示猜数字范围python_Python 猜数字游戏
  16. win10 如何快速显示桌面
  17. 统一vscode和hbuildX开发工具格式化规则
  18. 离散数学:聚会上的名人
  19. 拆解报告:爱否开物1A2C 65W PD氮化镓充电器智融SW3516十分表现抢眼
  20. 打造IBM 的F11一键恢复系统

热门文章

  1. freemarker 读取字符串模板,(非文件)
  2. mac下没有设置 SVN_EDITOR....错误解决方法
  3. python下使用qrcode方法
  4. Android中下载进度条格式,Android开发如何实现文件下载进度条
  5. linux改变该进程优先级,linux – 是nice()用于更改线程优先级或进程优先级吗?
  6. python include函数_python 库函数
  7. 计算机教育的发展,计算机教育发展方向研究
  8. 39 n 39 是不是c语言常量,自考“高级语言程序设计”习题答案详解(39)
  9. 智能车竞赛技术报告 | 智能车视觉 - 青岛工学院 - 青工战斗
  10. 5月15日直播预告:英飞凌AURIX™培训—图像处理、实车演示等热点问题