模块功能的描述方法
目录
行为描述方法
语句块
过程赋值语句
高级程序语句
循环语句
数据流描述
结构描述
混合描述方法
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
相关文章:

模块功能的描述方法
目录 行为描述方法 语句块 过程赋值语句 高级程序语句 循环语句 数据流描述 结构描述 混合描述方法 module 模块名(端口列表); // 模块声明// 端口定义input [数据类型] [位宽] 输入端口列表; output [数据类型] [位宽] 输出端口列表; inout [数据类…...

【WPF】MatrixTransform类
【WPF】MatrixTransform类 主要特性使用场景示例 在WPF(Windows Presentation Foundation)中,MatrixTransform 类是用于表示一个仿射变换的类,它允许开发者通过一个矩阵来定义一个二维空间中的线性变换。这种变换可以包括平移&…...

【C++】继承的理解
1.继承的概念和定义 1.1继承的概念 继承 (inheritance) 机制是面向对象程序设计 使代码可以复用 的最重要的手段,它允许程序员在 保 持原有类特性的基础上进行扩展 ,增加功能,这样产生新的类,称派生类。继承 呈现了面向对象 程序…...

day50 图论章节刷题Part02(99.岛屿数量 深搜、99.岛屿数量 广搜、100.岛屿的最大面积)
前言:前段时间论文开题落下了很多进度,今天开始会尽快赶上 99.岛屿数量 深搜 思路:对地图进行遍历遇到一个没有遍历过的陆地节点,计数器就1,并把该节点所能遍历到的陆地都标记上;遇到标记过的陆地节点和海…...

超详细从基准将VMware ESXi 升级到 vSphere 6.7U1教程
哈喽大家好,欢迎来到虚拟化时代君(XNHCYL),收不到通知请将我点击星标! “ 大家好,我是虚拟化时代君,一位潜心于互联网的技术宅男。这里每天为你分享各种你感兴趣的技术、教程、软件、资源、福…...

华为OD机试 - 打印机队列 - 优先队列(Java 2024 E卷 200分)
华为OD机试 2024E卷题库疯狂收录中,刷题点这里 专栏导读 本专栏收录于《华为OD机试(JAVA)真题(E卷D卷A卷B卷C卷)》。 刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加…...

MatrixOne 助力西安天能替换MySQL+MongoDB+ES打造一体化物联网平台
物联网(IoT)时代,企业正以前所未有的速度加快数字化转型。西安天能软件科技有限责任公司(Skyable)作为工业物联网领域的领先企业,携手MatrixOne,共同构建新一代一体化物联网平台,实现…...

正则表达式---元字符
简介 正则表达式分为两种语法:POSIX标准的语法,Perl语法。 正则表达式的POSIX规范,分为基本型正则表达式(Basic Regular Expression, BRE),扩展型正则表达式(Extended Regular Expression&…...

数据库Redis篇
系列文章目录 第一章 C/C语言篇第二章 计算机网络篇第三章 操作系统篇第四章 数据库MySQL篇第五章 数据库Redis篇第六章 场景题/算法题第七篇 常见HR问题篇 本系列专栏:点击进入 后端开发面经 关注走一波 秋招阶段,面过很多大中小厂,积攒了…...

在区块链技术中,什么是权益证明(PoS)?
权益证明(Proof of Stake, PoS)是一种与工作量证明(Proof of Work, PoW)类似的共识机制,但它通过不同的方式来确保区块链网络的安全性和一致性。PoS的主要目标是解决PoW中存在的高能耗问题,并提高网络的扩展…...

Spring Boot——日志介绍和配置
1. 日志的介绍 在前面的学习中,控制台上打印出来的一大堆内容就是日志,可以帮助我们发现问题,分析问题,定位问题,除此之外,日志还可以进行系统的监控,数据采集等 2. 日志的使用 在程序中获取日…...

Python实现全国岗位招聘信息可视化分析(源码+论文+部署讲解)
项目源码&数据源获取 利用Python实现全国岗位招聘信息可视化分析 项目背景: 1.为企业招聘决策提供科学的依据和参考,可以帮助人力资源部门、招聘机构和求职者了解当前的就业形势、行业趋势和人才需求,从而做出更明智的招聘和求职决策。…...

【真题笔记】16年系统架构设计师要点总结
【真题笔记】16年系统架构设计师要点总结 存储部件接口嵌入式处理器产品配置配置管理用户文档系统文档CMM(能力成熟度模型)螺旋模型敏捷软件开发的方法学软件工具面向对象的分析模型设计模型COP(面向构件的编程)构件原子构件模块S…...

2024 CSS保姆级教程二 - BFC详解
前言 - CSS中的文档流 在介绍BFC之前,需要先给大家介绍一下文档流。 我们常说的文档流其实分为定位流、浮动流、普通流三种。 1. 绝对定位(Absolute positioning) 如果元素的属性 position 为 absolute 或 fixed,它就是一个绝对定位元素。 在…...

Knowledge-refined Denoising Network for Robust Recommendation
Knowledge-refined Denoising Network for Robust Recommendation(Sigir23) 摘要 知识图(KG)包含丰富的边信息,是提高推荐性能和可解释性的重要组成部分。然而,现有的知识感知推荐方法直接在KG和用户-项目…...

轴流风机和后倾式风机的安装要求
后向离心风机风压大,风量足,安装方便。因为不需要蜗壳,所以风道往往需要自行设计,而风道的合理与否,大大影响了后向离心风机的效率。那么后向离心风机的安装技巧有哪些?怎样达到风机的最佳使用效果呢&#…...

代码笔录1
10-16 出入栈序列是否合法 // // Created by 86184 on 2024/10/16. // #include <stdio.h>//IIOOOIO int jude(char s[]) {int count 0, i 0;while (s[i] ! \0) {if (s[i] I) count;else if (s[i] O) count--;else return 0;if (count < 0) return 0;i;}if (cou…...

强网杯2024 Web WP
强网杯2024 参考链接:https://mp.weixin.qq.com/s/Mfmg7UsL4i9xbm3V3e5HMA https://mp.weixin.qq.com/s/vV_II8TpyaGL4HUlUS57RQ PyBlockly 源码: from flask import Flask, request, jsonify import re import unidecode import string import ast …...

《双指针篇》---盛最多水的容器_Java(中等但简单)
题目传送门 1.首先计算出暂时的盛水体积 2.求暂时体积和最大体积max的最大值 3.更新right和left。如果height[left] > height[right] 那么right--否则left; class Solution {public int maxArea(int[] height) {int left 0,right height.length-1; int ret 0;while (lef…...

Linux: network: 环境:网络burst的一个原因,虚拟机感染病毒导致,外部网络设备太忙
最近碰到一个问题,测试人员在测试一周内的产品稳定性,带有的业务非常大。 总是不能满足需要的时长,总是在一段时间内出现丢包,业务出现错误的现象。从tshark/tcpdump的抓包看,确实在某个时间段,有一次十几秒…...

idea使用Translation插件实现翻译
1.打开idea,settings,选择plugins,搜索插件Translation,安装 2.选择翻译引擎 3.配置引擎,以有道词典为例 3.1 获取应用ID,应用秘钥 3.1.1 创建应用 点击进入有道智云控制台 3.1.2 复制ID和秘钥 3.2 idea设…...

[OS] sys_mmap() 函数+
流程图分析 1. 调用 sys_mmap() 步骤:当用户程序调用 mmap() 时,操作系统会进入 sys_mmap() 函数。作用:这是整个 mmap() 操作的入口。系统调用的实现从这里开始。 2. 提取参数(Fetch Argument) 步骤:从…...

轧钢机辊道多电动机传动控制系统
轧钢机辊道多电动机传动控制系统是一种复杂的工业自动化系统,主要用于控制轧钢车间中多个电动机驱动的辊道,以实现轧件的高效、稳定输送和加工。以下是对该系统的详细介绍: 系统组成 轧线辊道TDC控制器:作为系统的核心控制单元&a…...

使用 Nginx 部署 Python 项目
今天的目标是完成一个 Python Web 项目的线上部署,我们使用最新的 Django 项目搭建一个简易的 Web 工程,然后基于 Nginx 服务部署该 Python Web 项目。 1. 前期准备 1.1 安装虚拟环境pyenv 使用虚拟环境逐渐成了 python 项目开发中的一种主流方式。py…...

[笔记] SQL 优化
一. 数据库设计优化 1. 选择合适的字段类型 设计表时,尽量选择存储空间小的字段类型: 整型字段:从TINYINT、SMALLINT、INT到BIGINT。小数类型:对于金额等需精确计算的数值使用DECIMAL,避免使用FLOAT和DOUBLE。字符串…...

【InfluxDB】InfluxDB 2.x基础概念及原理
InfluxDB简介 什么是时序数据库 时序数据库,全称时间序列数据库(Time Series Database,TSDB),用于存储大量基于时间的数据。时序数据库支持时序数据的快速写入、持久化,多维度查询、聚合等操作࿰…...

.net Core 使用Panda.DynamicWebApi动态构造路由
我们以前是通过创建controller来创建API,通过controller来显示的生成路由,这里我们讲解下如何不通过controller,构造API路由 安装 Panda.DynamicWebApi 1.2.2 1.2.2 Swashbuckle.AspNetCore 6.2.3 6.2.3添加ServiceAction…...

Spring框架和Spring Boot框架都使用注解来简化配置和提高开发效率,但它们之间存在一些区别
Spring框架和Spring Boot框架都使用注解来简化配置和提高开发效率,但它们之间存在一些区别: Spring框架注解: Autowired:自动导入对象到类中,被注入的类需要被Spring容器管理。Component、Repository、Service、Contro…...

从数据提取到管理:TextIn平台的全面解析与产品体验
一、引言 在现代信息时代,文档解析和管理已经成为企业和开发者不可或缺的工具。TextIn是合合信息旗下的一款智能文档处理平台,为开发者和企业提供高效、精准的文档解析工具,帮助用户轻松应对各种复杂的文档处理需求。本文将深入探讨TextIn的…...

2024 Rust现代实用教程 Error错误处理
文章目录 一、错误处理之:Result、Option以及panic!宏1.Result2.Option3.panic! 二、错误处理之:unwrap()与?1.unwrap()2.?运算符 三、自定义一个Error类型参考 一、错误处理之:Result、Option以及panic!宏 Rust中的错误可以分为…...