verilog语法实例学习(1)
本文档中通过verilog实例来学习verilog语法。Verilog是一种硬件描述语言,它具有并发性和时序性。并发性是指不同硬件模块的同时操作,时序性是指信号的赋值或操作在时钟的边沿进行。由于作者本身也是一个初学者,所以尽量用简单明了的例子介绍Verilog语法。
Verilog中的注释
Verilog代码中的注释和c++语言相同,分为短注释(//)和长注释(/* … */)。短注释通常放在每行代码的后面或上面,用来注释这行代码的功能。长注释一般在module的开始处,用来说明模块的功能。比如下面四位全加器代码中的注释。
/*
通过实例化全加器模块实现四位加法的功能。
输入:cin,进位
x, y 被加数和加数
s 和
cout 进位
*/
module adder4(cin, x, y,s,cout); input cin;
input [3:0] x;
input [3:0] y; output [3:0] s;
output cout;
wire [3:1] c; //内部线网类型信号c,用来存储串行进位 fulladd stage0(.cin(cin),.x(x[0]),.y(y[0]),.s(s[0]),.cout(c[1]));
fulladd stage1(.cin(c[1]),.x(x[1]),.y(y[1]),.s(s[1]),.cout(c[2]));
fulladd stage2(.cin(c[2]),.x(x[2]),.y(y[2]),.s(s[2]),.cout(c[3]));
fulladd stage3(.cin(c[3]),.x(x[3]),.y(y[3]),.s(s[3]),.cout(cout)); endmodule
Verilog中的信号
Verilog中,电路里面的一个信号就代表一个特定类型的线网(net)或变量。这里线网指的两个或更多电路结点的相互连接。
一个线网或变量的声明格式如下:
type [range] signal_name{,signal_name};
方括号中range(范围)是可选的,如果没有指定范围,默认情况下表示该信号是标量,是只有一位的单位信号。大括号中表示允许加入的条目,也就是说一个在一行里面可以声明多个线网或变量。
范围表示为[Ra:Rb]的形式,它定义了矢量信号的范围。范围[Ra:Rb]可以增大或减小。在任何情况下,Ra都表示一个矢量信号的最高有效位(最左边),Rb表示一个矢量信号的最低有效位(最右边)。Ra和Rb可以是正整数和负整数。
比如:
wire [7:0] x1,x2;
wire [3:1] Array;
reg y1,y2; //y1和y2没有指定范围,只有一位。
标识符
在verilog中,线网或变量名字是通过标识符来表示的。标识符是由一些字母,数字,下划线或美元符号组成。但必须注意两点:标识符不能以数字开头,也不能使用verilog中的关键字。Verilog标识符中也可以出现转义字符,比如 \abc,如果用转义字符,则可以用特殊字符,比如\*cd,但是通常写代码过程中,不要用转义字符来定义变量,这种转义字符通常是其它语言用工具翻译成verilog语言时自动插入的。另外注意的一点就是verilog是区分大小写的,m和M是两个不同的变量。
合法的标识符:
f, x, x1, x_y, Byte
非法的标识符:
1x, 100, x*y,default(verilog关键字)
Verilog中一些系统任务或函数以$开头,比如$display, $fopen, $monitor等等。Verilog中还定义一些编译指示,以`开头,比如:`timescale 1ns/1ns,定义时间单位和时间精度。
信号的值
Verilog支持单位信号表示的标量(一位信号)或者矢量(多位信号),每个单位信号有四种可能的值:0,1,z(或者Z),x(或者X)。
0, 逻辑值0
1, 逻辑值1,
在正逻辑系统中,逻辑值0表示低电平,逻辑值1表示高电平。负逻辑系统中正好相反。在教程中,我们总是用正逻辑系统。
我们用阈值电压来表示电平的逻辑值。 在上图中,最低电压为 Vss,表示接地。VDD表示最高电压,表示接电源,通常电源在5v到1v之间。VDD~V1,min之间的范围对应逻辑值1,V0,max~Vss之间的范围对应逻辑值0。典型的V1,min 是60%Vdd,V0,max是40%Vdd
X, 通常表示多驱动值的冲突,为未初始化的值或者两个反相信号(如0和1)的短接。Verilog中线网和变量的初始值都为X。
Z, 通常表示未驱动的高阻值,此时在电源和地之间没有电流流动。比如在三态门中,E=0,则输出为Z。

Verilog中的数字
信号值如果为标量,则为一位的0,1,x或z。例如:
a = 1’b0; b = 1’b1;
c = x; d = z;
对于矢量,通常表示为:[size]’[radix]constant, 标量也可以当作size=1的矢量。其中size表示常数的位数,radix为常数的基数。如果没有指定基数,则默认为十进制。Verilog支持的基数有:d(十进制),b(二进制),h(十六进制),o(八进制)。如果定义的位数大于所需要的位数时,通常在前面补0,但是如果最高位是x或z时候,就用x和z来填充。在常量表示中间,可以任意插入下划线,把数字隔开,以方便阅读。可以在基数前面加s(或者S)以表示这是一个有符号数,若未指定一个整数的进制类型,则默认是有符号数,若指定了进制类型,仅当基数前有s,则其为有符号数,否则为无符号数。对于有符号数,如果定义的位数大于所需要的位数时,前面补最高有效位(MSB),如下表中的8’sha9。
下面是一些实例:
|
数字表示 |
二进制 |
注释 |
|
reg [31:0] a = 8'sha9 |
‘11111111111111111111111110101001 |
8位有符号数,所以进行MSB位扩展, |
|
reg [31:0] b = 4'd5 |
’00000000000000000000000000000101 |
4位无符号数,高位补0 |
|
reg [31:0] c = 12'h5b_3 |
‘00000000000000000000010110110011 |
忽略下划线,12位的无符号数,高位补0 |
|
reg [31:0] d = -8'b101 |
’11111111111111111111111111111011 |
负数转为补码表示,MSB位扩展到32位 |
|
reg [31:0] e= 10'o752 |
‘00000000000000000000000111101010 |
8进制无符号数,高位补0 |
|
reg [31:0] f = 8'hf |
’00000000000000000000000000001111 |
16进制无符号数,高位补0 |
|
reg [31:0] g = 12'hxa |
‘00000000000000000000xxxxxxxx1010 |
左边补x直到12位,然后高位补0 |
|
reg [31:0] h = -8'sha9 |
’00000000000000000000000001010111 |
补码表示负数,扩展MSB位, |
|
reg [31:0] i = 8'ha9 |
‘00000000000000000000000010101001 |
无符号数,高位补0 |
|
reg [31:0] j = -4'sha |
’00000000000000000000000000000110 |
补码表示负数,扩展MSB位。 |
实现这些实例的verilog代码为:
`timescale 1ns/1ns
module verilogdisnum;
reg [31:0] a = 8'sha9;
initial $displayb("a=",a);
reg [31:0] b = 4'd5;
initial $displayb("b=",b);
reg [31:0] c = 4'h5b_3;
initial $displayb("c=",c);
reg [31:0] d = -8'b101;
initial $displayb("d=",d);
reg [31:0] e= 10'o752;
initial $displayb("e=",e);
reg [31:0] f = 8'hf;
initial $displayb("f=",f);
reg [31:0] g = 12'hxa;
initial $displayb("g=",g);
reg [31:0] h = -8'sha9;
initial $displayb("h=",h);
reg [31:0] i = 8'ha9;
initial $displayb("i=",i);
reg [31:0] j = -4'sha;
initial $displayb("j=",j);
endmodule
Verilog中的参数
参数由一个标识符和一个常数组成。比如:
parameter n=4;
parameter S0=2’b00; S1=2’b01;S2=2’b10;S3=2’b11;
标识符n可以在代码中替换表示数字4的地方,S0则可以替换数值2’b00。参数的主要作用是指定参数化的子电路。比如下面的代码中,可以看到代码通过parameter定义了一个常量n,实例化时候通过addern #(.n(32)) addern_0(…)的形式把32传入到参数n中,从而实现32位的加法操作。另外一种调用参数的方法是用defparam,比如下面的例子:
addern addern_0(…)
defparam addern_0.n=32;
但这种方法是不可综合的,通常只是用在testbench当中。
module addern(x, y, s, cout);
parameter n=8;
input [n-1:0] x;
input [n-1:0] y;
output reg[n-1:0] s;
output reg cout;
reg [n:0] c;
integer k;
always @(x,y) begin
c[0] = 1'b0;
for(k = 0; k < n; k = k + 1) begin
s[k] = x[k]^y[k]^c[k];
c[k+1] = (x[k]&y[k])|(x[k]&c[k])|(y[k]&c[k]);
end
cout = c[n];
end
endmodule
`timescale 1ns/1ns
`define clock_period 20
module addern_tb;
reg [7:0] x,y;
wire cout;
wire [7:0] s;
reg clk;
addern #(.n(32)) addern_0(
.x(x),
.y(y),
.s(s),
.cout(cout)
);
initial clk = 0;
always #(`clock_period/2) clk = ~clk;
initial begin
x = 0;
repeat(20)
#(`clock_period) x = $random;
end
initial begin
y = 0;
repeat(20)
#(`clock_period) y = $random;
end
initial begin
#(`clock_period*20)
$stop;
end
endmodule
verilog语法实例学习(1)的更多相关文章
- verilog语法实例学习(4)
Verilog模块 Verilog中代码描述的电路叫模块,模块具有以下的结构: module module_name[ (portname {, portname})]; //端口列表 [parame ...
- verilog语法实例学习(12)
verilog中的综合和不可综合总结 Verilog中综合的概念 综合就是EDA工具或者说综合工具把我们编写的verilog代码转化成具体电路的过程.Verilog中有很多语法,结构,过程,语句,有些 ...
- verilog语法实例学习(6)
函数和任务 函数 https://wenku.baidu.com/view/d31d1ba8dd3383c4bb4cd283.html verilog中函数的目的是允许代码写成模块的方式而不是定义独立 ...
- verilog语法实例学习(5)
子电路模块 子电路模块的使用 一个verilog模块能够作为一个子电路包含在另一个模块中.采用这种方式,所有的模块都必须定义在一个文件中,那么verilog编译器就必须被告知每个模块的所属.模块例化的 ...
- verilog语法实例学习(2)
Verilog中的信号类型 线网类型 线网类型表示一个或多个门或者其它类型的信号源驱动的硬件连线.如果没有驱动源,则线网的默认值为z.verilog中定义的线网类型有以下几种: wire,tr ...
- verilog语法实例学习(13)
verilog代码编写指南 变量及信号命名规范 1. 系统级信号的命名. 系统级信号指复位信号,置位信号,时钟信号等需要输送到各个模块的全局信号:系统信号以字符串Sys开头. 2. 低电平有效的 ...
- verilog语法实例学习(11)
同步时序电路的一般形式 时序电路由组合逻辑以及一个或多个触发器实现.一般的架构如下图所示:W为输入,Z为输出,触发器中存储的状态为Q.在时钟信号的控制下,触发器通过加在其输入端的组合逻辑输入,使得电路 ...
- verilog语法实例学习(10)
常用的时序电路介绍 T触发器和JK触发器 在D触发器输入端添加一些简单的逻辑电路,可以生成另一种类型的存储元件.比如下图所示的T触发器.该电路有一个上升沿触发的触发器和两个与门,一个或门,以及一个反相 ...
- verilog语法实例学习(9)
常用的时序电路介绍 寄存器 一个触发器可以存储一位数据,由n个触发器组成的电路可以存储n位数据,我们把这一组触发器叫做寄存器.寄存器中每个触发器共用同一个时钟. 下面是n位寄存器的代码,我们通过一个参 ...
随机推荐
- 高能天气——团队Scrum冲刺阶段-Day 7 总结
高能天气--团队Scrum冲刺阶段-Day 7 总结 今日完成任务 于欣月:修改项目说明书,帮助修改应用 余坤澎:进行应用整合的收尾工作 康皓越:进行应用整合的收尾工作 范雯琪:修改项目说明书,完成项 ...
- 2019 B类
警察 非警察
- 正睿OI 提高 Day1T3 ZYB玩字符串(DP)
题目链接 设可能的答案串为p,长为len.p一定是s的一个子串且len|n. 虽然一些p在s中可能被断成若干段,但删掉其中的若干段后,这段区间一定会被全部消掉. 于是枚举p后,可以用f[i][j]表示 ...
- Codeforces 749E Gosha is hunting 二分+DP
很神奇的一题 看完题解不由惊叹 题意:$n$个神奇宝贝 $a$个普通球 $b$个高级球 普通球抓住$i$神奇宝贝的概率为$u[i]$ 高级球为$p[i]$ 一起用为$u[i]+p[i]-u[i]*p[ ...
- WEB应用从服务器主动推送Data到客户端有那些方式?
1) html5 websocket 2) WebSocket 通过 Flash 3) XHR长时间连接 4) XHR Multipart Streaming 5) 不可见的Iframe 6 ...
- 喵哈哈村的魔法考试 Round #3 (Div.2) 题解
A 题解:保证一个三角形的话,得两边之和大于第三边才行,所以都拿来判一判就好了. #include <iostream> using namespace std; int main(){ ...
- 使用 Python 登录网站(转)
对于大部分论坛,我们想要抓取其中的帖子分析,首先需要登录,否则无法查看. 这是因为 HTTP 协议是一个无状态(Stateless)的协议,服务器如何知道当前请求连接的用户是否已经登录了呢?有两种方式 ...
- 使用p3p跨域设置Cookie
有些时候不能将url上的参数传来传去,比如与调用某开放平台上的接口,这时候可能需要借助Cookie来进行处理了,但这里可能又涉及到跨域的问题. 如果浏览器开启了对Cookie的支持,按照Cookie ...
- Flex+blazeds实现与mySQL数据库的连接(已成功实现此文的例子)
http://bdk82924.iteye.com/blog/1067285 几个下载地址 blazeds_turnkey_3-0-0-544.zip 下载地址:http://download.mac ...
- Unity3D实践系列02,查看Scene窗口物体
删除"Hierarchy"窗口中的"Directional Light". 把鼠标放在"Scene"窗口,滑动鼠标滚轮,可以对"S ...