模块功能的描述方法

目录

行为描述方法

语句块

过程赋值语句

高级程序语句

循环语句

数据流描述

结构描述

混合描述方法


module 模块名(端口列表);    // 模块声明// 端口定义input   [数据类型] [位宽]  输入端口列表;           output [数据类型] [位宽]  输出端口列表; inout   [数据类型] [位宽]  双向端口列表; // 数据类型定义wire  [位宽] 线网名,线网名,…;     reg  [位宽] 变量名,变量名,…;//函数与任务声明function [位宽] 函数名; ...; endfuctiontask 任务名; ...; endtask// 功能描述 assign 线网名=函数表达式;            // 数据流描述方式always/initial过程语句;                // 行为描述方式例化模块名 实例名(端口关联列表);    // 结构描述方式endmodule

行为描述方法

  行为描述(Behavioral Modeling)以过程语句为基本单位,在过程体内部应用高级语句和操作符描述模块的行为特性,不考虑具体的实现方法。过程语句有initial语句和always语句两种形式。

   initial过程语句称为初始化语句,无触发条件,从0时刻开始只执行一次。initial语句用在testbench文件中,用于对变量进行初始化或者产生特定的信号波形。

initial语句的语法格式为:
initial begin块内变量说明;[延时控制1] 语句1; ...end 
initial beginclk = 0;#10 clk = 1;#20 clk = 0; 
end

  当模块中存在多个的initial语句时,则所有initial语句同时从0时刻开始执行。

always 语句

  always语句有两种过程状态:等待状态和执行状态。当事件列表中无事件发生时,always语句处于等待状态;当事件列表中有事件发生时,always语句进入执行状态,执行完毕后自动返回等待状态。

  always语句应用的语法格式为:always @(事件列表)begin [:语句块名]块内变量说明;[延时控制1] 语句1; …… [延时控制n] 语句n; end

  事件列表示触发启动always过程语句执行的条件,分为电平敏感事件和边沿触发事件两种类型。

电平敏感事件是指线网/变量的电平发生变化时,触发过程语句进入执行状态。 其语法格式为: @(电平敏感量1 or … or 电平敏感量n) 语句块;

always @ (*) begin……end

  边沿触发事件是指线网/变量发生边沿跳变时执行语句块,分为上升沿触发和下降沿触发两种,分别用关键词posedge和negedge表示。

边沿触发事件的语法格式为:      @(边沿触发事件1 or … or 边沿触发事件n) 语句块;

D触发器的描述。module d_ff(clk,d,q);input clk,d;output reg q;always @( posedge clk )   // 上升沿锁存数据q <= d;endmodule
4位二进制计数器的描述。module cnt4b(clk,q);parameter Nbits = 4;input clk;output reg [Nbits-1:0] q;// 下降沿计数always @( negedge clk )  q <= q + 1'b1;endmodule

  always过程语句也可以没有触发条件,表示永远反复执行,用来产生周期性的波形,但不可综合,只能用于测试平台文件中。

  需要强调的是:在always语句的事件列表中,电平敏感事件和边沿触发事件不能混合使用。一旦事件列表中含有由posedge或者negedge引导的边沿触发事件,则不能再出现电平敏感事件,即下述形式是错误的: always @( posedge clk or rst_n)

 always @( posedge clk or negedge rst_n)if ( !rst_n )  ...else ...
过程语句应用示例。module clk_gen(clk1,clk2);output clk1,clk2;reg clk1,clk2;initial            // 定义初值beginclk1 = 0;clk2 = 0;endalways      // 产生周期性波形#50 clk1 = ~clk1;always#100 clk2 = ~clk2;endmodule

语句块

   语句块(block)是将两条或者两条以上的语句组合在一起,使其在形式上如同一条语句,其作用与C语言中的大括号“{}”相同。  语句块有顺序语句块和并行语句块两种类型。

  顺序语句块(sequential block)由关键词begin和end定义,按语句的书写顺序执行块中的语句,即前一条语句执行完后才能执行后一条语句。若使用延迟,则每条语句的延迟时间均相对于上一条语句的执行时刻而言。

顺序语句块定义的语法格式为:begin [:块名]语句1;...语句n;end
其中块名可以省略。
reg a,b,c,d;
initial begina = 1'b0;           // 仿真时刻0时执行#5  b = 1'b1;     // 仿真时刻5时执行#10 c = 1'b0;     // 仿真时刻15(=10+5)时执行#15 d = 1'b1;     // 仿真时刻30(=15+10+5)时执行end

  并行语句块(parallel block)由关键词fork和join定义,块中的所有语句从块被调用的时刻同时开始执行。若使用延迟,则每条语句的延迟时间均相对于块调用的开始时刻而言,与语句的具体书写顺序无关。

reg a,b,c,d;
initial forka = 1'b0;           // 仿真时刻0时执行#5  b = 1'b1;      // 仿真时刻5时执行#10 c = 1'b0;      // 仿真时刻10时执行#15 d = 1'b1;      // 仿真时刻15时执行join

时序控制

  时序控制用于定义从开始遇到语句到真正执行该语句时的等待时间。时序控制只用于仿真,综合时所有的延时控制将被忽略。

  时序控制有常规延时和内嵌延时两种书写形式。

应用常规延时的语法格式为:    

[#延时量] 线网/变量 = 表达式;

应用内嵌延时的语法格式为:    

线网/变量 = [#延时量] 表达式;

  在Verilog HDL中,延迟量的单位由预编译指令“`timescale”进行定义。例如,在文件头中添加语句:      `timescale 1ns /1ps 表示仿真时间单位为1ns,仿真精度为1ps。根据该命令,仿真工具才认为 #10 表示延时时间为10ns。

过程赋值语句

过程赋值(procedural assignment)语句是指在initial/always语句内部对变量进行赋值的赋值语句。

过程赋值语句的语法格式为:    <变量> <赋值操作符> <赋值表达式> ;

  赋值操作符分为两类:“=”和“<=”,分别表示阻塞赋值(blocking assignment)和非阻塞赋值(non-blocking assignment)。

  阻塞赋值按照语句的书写顺序进行赋值。也就是说,在前一条赋值语句执行结束之前,后一条语句被阻塞,不能执行。只有前一条赋值语句执行结束后,后一条语句才能被执行。

module eq1b(a,b,eq);input a,b;output reg eq;reg tmp1,tmp2;always @(a,b)begintmp1 = ~a & ~b;tmp2 = a & b;eq = tmp1 | tmp2;end
endmodule

  非阻塞赋值是指多条赋值语句同时赋值,与语句的书写顺序无关,即后面赋值语句的执行不受前面赋值语句的影响。  由于阻塞赋值与非阻塞赋值的赋值方法不同,因此综合出的电路存在差异,所以必须正确地区分和应用这两类赋值语句。

 module blocking(din,clk,reg1,reg2);input din,clk;output reg reg1,reg2;always @(posedge clk)beginreg1 = din;reg2 = reg1;endendmodule

  当模块中既包含组合逻辑又包含时序逻辑时,应该将组合逻辑和时序逻辑分开进行描述。可以用一个always语句描述时序逻辑,用另一个always语句描述组合逻辑,或者改用连续赋值语句描述组合逻辑。

 module blocking(din,clk,reg1,reg2);input din,clk;output reg reg1,reg2;always @(posedge clk)beginreg1 <= din;reg2 <= reg1;endendmodule

高级程序语句

  Verilog HDL中的高级程序语句和C语言一样,用于控制代码的流向,分为条件语句、分支语句和循环语句三种类型。

  条件语句(conditional statement)使用关键词if和else,根据条件表达式的真假确定执行的操作,用于对赋值过程进行控制,分为简单条件语句、分支条件语句和多重语句三种类型。

module d_latch(clk,d,q);  input clk,d;output reg q;always @(clk,d)if (clk) q <= d;endmodule

  由于简单条件语句没有定义条件表达式为假时执行的操作,隐含条件表达式为假时不执行任何操作,所以被赋值的变量应该保持不变,因而会综合出时序电路。

分支条件语句的语法格式为:   if(条件表达式)     条件表达式为真时执行的语句块;   else     条件表达式为假时执行的语句块;

module mux2to1 (y,d0,d1,sel);input d0,d1,sel;output reg y;always @(d0,d1,sel)beginif ( !sel ) y = d0;elsey = d1;endendmodule

如果用下述代码描述双向口:

module BiDir_Port(dir,a,b);input dir;     // 双向控制端inout a,b;     // 两个双向口reg atmp,btmp;assign a=atmp;assign b=btmp;always @ (dir,a,b) if ( dir )  atmp = b;  else btmp = a;  
endmodule

描述双向口正确的Verilog代码参考如下:

module BiDir_Port(dir,a,b);input dir;       // 双向控制端inout a,b;       // 两个双向口reg atmp,btmp;assign a=atmp;assign b=btmp;always @ (dir,a,b) if (dir) begin atmp = b; btmp = 1’bz; endelse begin btmp = a; atmp = 1’bz; end
endmodule

具有异步复位功能的4位二进制计数器的描述

module cnt4b(clk,rst_n,q);input clk,rst_n;output [3:0] q;reg [3:0] q;always @(posedge clk or negedge rst_n)beginif ( !rst_n )  // 低电平有效q <= 4'b0000;elseq <= q + 1'b1;end
endmodule

多重条件语句常用于多路选择, 其语法格式为:

if(条件表达式1) 条件表达式1为真时执行的语句块;  

else if(条件表达式2)   条件表达式2为真时执行的语句块;    ……    

else if(条件表达式n)      条件表达式n为真时执行的语句块;    

else      条件表达式1~n均为假时执行的语句块;

  多重条件语句对条件表达式的判断有先后次序,隐含有优先级的关系,先判断的条件表达式优先级高,后判断的条件表达式优先级低。因此,多重条件语句通常用于描述有优先级的逻辑电路。

4线-2线优先编码器的描述。module prior_encoder(d,c,b,a,y);input d,c,b,a;output reg [1:0] y;always @ (d,c,b,a)beginif (d) y = 2'b11;else if (c) y = 2'b10;else if (b) y = 2'b01;else  y = 2'b00;endendmodule 

分支语句使用关键词case...endcase引导,功能相当于C语言中的switch语句,用于实现多路选择。

 用分支语句描述2选一数据选择器。
module mux2to1(d0,d1,sel,y);input d0,d1,sel;output y;reg y;always @ (d0,d1,sel) case ( sel )1'b0:  y = d0;1'b1:  y = d1;default: y= d0;endcaseendmodule

  在Verilog HDL中,通常用字符“?”代替字符x和z,表示无关位。

  always @ (d,c,b,a)begincasez({d,c,b,a})4'b1???: y = 2'b11;4'b01??: y = 2'b10;4'b001?: y = 2'b01;4'b0001: y = 2'b00;default: y = 2'b00;endcaseendendmodule

循环语句

  循环语句的作用与C语言相同。Verilog HDL支持4类循环语句:for、while、repeat和forever语句,其中for语句、while语句的用法与C语言相同。

用移位累加方法描述乘法器。module multi(result,op_a,op_b);parameter Nbits=8;          // 参数定义input [Nbits:1] op_a,op_b;  // 被乘数与乘数output [2*Nbits:1] result;   // 乘法结果reg [2*Nbits:1] result;integer i;                      // 循环变量always @(op_a, op_b)begin  result = 0;for(i=1;i<=Nbits;i=i+1)if(op_b[i]) result = result+(op_a<<(i-1));  endendmodule

需要注意的是,Verilog不支持i++和i--这种循环增量的书写方式,递加和递减只能写成i=i+1和i=i-1。

while语句的语法格式为: while(循环条件表达式)   语句块;

  如果while循环中条件表达式的值为x或者z时,则循环次数为0。

parameter Nbits=8;
reg [2*Nbits:1] atmp;   // 定义内部变量
reg [Nbits:1]  btmp;    
integer i;                // 定义循环变量
always @(op_a,op_b)begin  result = 0;atmp = {{Nbits{1'b0}},op_a};  // 拼接扩展btmp = op_b;   i = Nbits;while (i>0)  begin if ( btmp[1] ) result = result + atmp;  i = i-1;               // 循环次数减1atmp = atmp << 1;   // 左移一位 btmp = btmp >> 1;   // 右移一位end       end

repeat语句的语法格式为:   repeat(循环次数表达式)              语句块;

parameter Nbits=8;
reg [2*Nbits:1] atmp;
reg [Nbits:1] btmp;
always @(op_a,op_b)beginresult = 0;atmp = op_a;btmp = op_b;repeat (Nbits)    // 循环次数由Nbits确定begin if ( btmp[1] ) result = result + atmp;atmp = atmp << 1; btmp = btmp >> 1;endend

数据流描述

  数据流描述(Dataflow Modeling)采用连续赋值语句,基于表达式和操作符描述线网的功能,用于组合逻辑电路的描述。连续赋值语句的语法格式为:   assign [#延迟量] 线网名 = 赋值表达式;

用数据流描述2选一数据选择器。module MUX2to1(y,d0,d1,sel);input d0,d1,sel;output y;assign y= ~sel & d0 | sel & d1; endmodule

  需要说明的是:(1)连续赋值语句用于对线网进行赋值,不能对变量进行赋值;(2)连续赋值语句和过程语句为平等关系,不能相互嵌套使用;(3)连续赋值语句的执行顺序与语句书写的顺序无关。

结构描述

  结构描述(Structural Modeling)方法类似于原理图设计,是将电路中的基元、模块和功能IP之间的连接关系由连线转换为文字表达。

  Verilog HDL预定义了26个基本元器件(primitives,简称基元),包括逻辑门和三态门,上拉电阻和下拉电阻,以及MOS开关和双向开关。

 Verilog基元分为以下六种类型: ▪ 多输入门:and, nand, or, nor, xor, xnor ▪ 多输出门:buf, not ▪ 三态门:bufif0, bufif1, notif0, notif1 ▪ 上拉电阻/下拉电阻:pullup, pulldown ▪ MOS开关:cmos, nmos, pmos, rcmos, rnmos, rpmos ▪ 双向开关:tran, tranif0, tranif1, rtran, rtranif0, rtranif1

结构描述的代码参考如下:module mux2to1(y,a,b,sel);output y;input a,b,sel;wire sel_n,a1,b1;not G1 (sel_n,sel);and G2 (a1,a,sel_n);and G3 (b1,b,sel);or G4 (y,a1,b1);endmodule

混合描述方法

  Verilog HDL支持三种描述方式的混合使用,即在同一模块中可以混合使用过程语句、连续赋值语句和例化语句。

全加器的混合描述。module Full_Adder(A,B,Cin,Sum,Co);input A,B,Cin;output Sum,Co;reg Co;wire Wtmp;xor U1(Wtmp,A,B);                    // 结构描述,实现Wtmp=A^Bassign Sum = Wtmp ^ Cin;            // 数据流描述,实现Sum=Wtmp^Cinalways @ ( A or B or Cin )            // 行为描述Co = A & Cin | B & Cin | A & B;    // 过程赋值语句endmodule

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/2662.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

LeetCode 热题100(七)【链表】(1)

7.链表 7.1相交链表&#xff08;简单&#xff09; 题目描述&#xff1a;leetcode链接 160.相交链表 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点&#xff0c;返回 null 。 图示两个链表在节点 c…

OpenAI正在与台积电(TSMC)和博通(Broadcom)合作,打造自己的AI推理芯片

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

小新学习k8s第四天之发布管理

一、金丝雀发布&#xff08;灰度发布&#xff09; Deployment控制器支持自定义控制更新过程中的滚动节奏&#xff0c;如“暂停(pause)”或“继续(resume)”更新操作。 ①比如等待第一批新的Pod资源创建完成后立即暂停更新过程&#xff0c;此时&#xff0c;仅存在一部分新版本的…

大数据安全方案 验证

一、背景 文档用于记录配置 Kerberos 和 Ranger 后&#xff0c;对 HDFS、Hive 认证和鉴权的功能测试。 二、Kerberos 验证 2.1、验证功能 1&#xff0c;HDFS 认证 2.1.1、访问 HDFS Kerberos 验证前&#xff0c;访问 HDFS 失败。 Kerberos 验证后&#xff0c;访问 HDFS 成…

全面解析:云计算技术及其应用

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 全面解析&#xff1a;云计算技术及其应用 全面解析&#xff1a;云计算技术及其应用 全面解析&#xff1a;云计算技术及其应用 云…

规范:项目、目录、文件、样式、事件、变量、方法、url参数、注释、git提交 命名规范及考证

一、规范命名的重要性 易懂、通用、规范、标准、专业性、是经验积累的体现 1.1、常见命名方法 序号命名方法解释1全小写2全大写3驼峰&#xff1a;小驼峰命名法4驼峰&#xff1a;大驼峰命名法5烤串命名法 / 脊柱命名法6下划线分隔法 二、项目名 采用小写字母和中划线&#…

03-Dubbo的负载均衡及高性能RPC调用

03-Dubbo的负载均衡及高性能RPC调用 Dubbo 的负载均衡策略 负载均衡策略就是当某个服务压力比较大的时候&#xff0c;这时候部署多个节点同时提供相同的服务 当服务消费者来消费的时候&#xff0c;可以从这多个节点中选择一个节点进行消费&#xff0c;这个选择的过程&#xff0…

【LVGL-列表部件 lv_list_create】

LVGL-列表部件 lv_list_create ■ LVGL-列表部件-函数■ 修改样式-■ 修改样式- 背景色■ 修改样式- 改变项的颜色-label■ 修改样式- 改变项的颜色-btn ■ 事件(Event)■ 示例0&#xff1a;综合■ 示例1&#xff08;自动出现滚动&#xff09;■ 示例2&#xff08;滚动捕捉&…

【React】初学React

A. react中如何创建元素呢&#xff1f; 说明一点&#xff1a; 属性都改为驼峰形式&#xff08;无障碍属性aria-*除外&#xff09;&#xff0c; class改成className 创建元素 B. 变量或表达式如何表示呢&#xff1f;大括号{ }包起来 变量值用大括号包裹 C. 元素和组件的区别 元素…

设备搜索相关协议使用

一、实现原理 首先&#xff0c;Client -> Gateway : 发送 UDP 广播包&#xff08;含厂商自定义协议)这一步表示客户端开始向网络中发送一个包含厂商自定义协议的 UDP 广播包&#xff0c;目的是寻找本厂商的设备&#xff08;网关&#xff09;。客户端此时处于活动状态activa…

TMDOG的Gin学习笔记_01——初识Gin框架

TMDOG的Gin学习笔记_01——初识Gin框架 博客地址&#xff1a;[TMDOG的博客](https://blog.tmdog114514.icu) 作者自述&#xff1a; 停更太久了&#xff0c;是因为开学了课太多了&#xff0c;并且我一直在准备上篇文章的内容正在coding&#xff0c;就先搁置了更新博客QAQ&…

H7-TOOL的CAN/CANFD助手增加帧发送成功标识支持, 继续加强完善功能细节

2.27版本固件正式携带此功能&#xff0c;包括之前做的负载率检测和错误信息展示也将集成到这个版本固件中。 对于接收&#xff0c;我们可以直接看到效果&#xff0c;而发送不行&#xff0c;所以打算在发送的地方展示下发送成功标识。CAN发送不像串口&#xff0c;需要等待应答后…

Pr 视频效果:超级键

视频效果/键控/超级键 Keying/Ultra Key 超级键 Ultra Key效果是 Premiere Pro 中功能强大的抠像工具&#xff0c;主要用于绿幕/蓝幕抠像。通过选择要抠除的颜色&#xff08;通常是绿幕或蓝幕的颜色&#xff09;&#xff0c;即可以将该颜色的像素设为透明&#xff0c;实现主体与…

善用Git LFS来降低模型文件对磁盘的占用

将讲一个实际的例子&#xff1a;对于模型文件&#xff0c;动辄就是好几个G&#xff0c;而有的仓库更是高达几十G&#xff0c;拉一个仓库到本地&#xff0c;稍不注意直接磁盘拉满都有可能。 比如&#xff1a;meta-llama-3.1-8b-instruct&#xff0c;拉到本地后发现居然占用了60G…

「树链剖分」学习笔记

一、引入 “在一棵树上进行路径的修改、求极值、求和”乍一看只要线段树就能轻松解决&#xff0c;实际上&#xff0c;仅凭线段树是不能搞定它的。我们需要用到一种貌似高级的复杂算法——「树链剖分」。 树链剖分&#xff08;简称树剖&#xff09;&#xff0c;顾名思义&#xf…

Golang--数组、切片、映射

1、数组 1.1 数组类型 var 数组名 [数组大小]数据类型 package main import "fmt"func main(){//1、定义一个数组var arr1 [5]intarr1[0] 100arr1[1] 200fmt.Println(arr1) //[100 200 0 0 0] } 1.2 数组的初始化方式 package main import "fmt" func …

结构体对齐,位段

大家好&#xff0c;今天来给大家分享一些结构体的知识&#xff0c;结构体是我们学习数据结构的基础&#xff0c;只有把它了解清楚才能让我们学习数据结构是得心应手&#xff0c;现在让我们来看看它的一些内容吧。 1.结构体的定义和调用我们就跳过吧 大家如果还不熟悉的话可以去…

ElementUI中el-table双击单元格显示输入框

效果图 实现 <el-table:data"formData.products"row-key"id":show-header"true"style"width: 100%; margin-top: 16px"class"zq-table-theme-info"bordercell-dblclick"handleDbClick"> <el-table-col…

Python OpenCV 图像改变

更改图像数据 通过 改像素点 或者 切片的区域 import cv2 import numpy as np img cv2.imread("image.jpg") print(img[3,5]) # 显示某位置(行3列5)的像素值( 如 [53 34 29] 它是有三通道 B G R 组成) img[3,5] (0,0,255) # 更改该位置的像素…

学习虚幻C++开发日志——定时器

官方文档&#xff1a;虚幻引擎中的Gameplay定时器 | 虚幻引擎 5.5 文档 | Epic Developer Community | Epic Developer Community 定时器 安排在经过一定延迟或一段时间结束后要执行的操作。例如&#xff0c;您可能希望玩家在获取某个能力提升道具后变得无懈可击&#xff0c;…