Verilog学习笔记
Verilog中的一些语法和技巧

Verilog中的⼀些语法和技巧1、.2、.3、Reg型的数据类型默认初始值为X。
reg型数据可以赋正值也可以赋负值,但是当⼀个reg型数据是⼀个表达式的操作数的时候,他的值被当做⽆符号数及正值。
4、在数据类型中?和Z均表⽰⾼阻态。
5、Reg型只表⽰被定义的信号将⽤在“always”模块内,并不是说reg型⼀定是寄存器或触发器的输出。
虽然reg型信号常常是寄存器或触发器的输出但是并不⼀定总是这样。
6、Verilog语⾔中没有多维数组的存在。
Memory型数据类型是通过扩展reg型数据的弟⼦和范围来⽣成的。
其格式如下reg[n-1:0]存储器名[m-1:0];7、在除法和取余的运算中结果的符号和第⼀个操作数的符号位是相同的。
8、不同长度的数据进⾏运算:两个长度不同的数据进⾏位运算时,系统会⾃动地将两者按有端对齐,位数少的操作数会在相应的⾼位⽤0填满以便连个操作数安慰进⾏操作。
9、= = =与!= = =和= =与!= =的区别:后者称为逻辑等是运算符,其结果是2个操作数的值决定的。
由于操作书中某些位可能不定值x和⾼阻态z结果可能是不定值x。
⽽ = = =和!= = =运算符对操作数的⽐较时对某些位的⾼阻态z和不定值x也进⾏⽐较,两个操作数必须完全⼀致,其结果才是1,否则是0.10、⾮阻塞和阻塞赋值⽅式:⾮阻塞赋值⽅式(如a<=b)上⾯语句所赋得变量值不能⽴即被下⾯语句所⽤,(2)快结束后才能完成这次赋值操作 3在编写克综合的时序逻辑模块时这是最常⽤的赋值⽅法。
阻塞赋值(如a=b)赋值语句执⾏完后,块才结束 2 b的值在赋值语句完成后⽴即执⾏ 3在时序逻辑使⽤中,可能产⽣意想不到的结果。
11、模块的描述⽅式:(RTL为寄存器传输级描述)“(1)数据流描述⽅式:数据流⾏描述主要⽤来描述组合功能,具体⽤“assign”连续赋值语句来实现。
分为两种a、显式连续赋值语句;连线型变量类型[连线型变量为快]连线型变量名Assign #(延时量)连线型变量名=赋值表达式;显式连续赋值语句包含了两条语句;第⼀条是对连线型变量的进⾏类型说明的说明语句;第⼆句是对这个已得到声明的连线型变量进⾏连续赋值语句。
Verilog HDL 学习笔记(二)数据类型及其常量、变量

Verilog HDL 学习笔记(二)数据类型及其常量、变量Verilog HDL中总共有19种数据类型。
数据类型是用来表示数字电路硬件中的数据储存和传送元素的。
常量类型:一、数字1.整数(1)二进制整数(b或B)(2)十进制整数(d或D)(3)十六进制整数(h或H)(4)八进制整数(o或O)。
数字表达方式有以下3种:(1)<位宽><进制><数字>,这是一种全面的描述方式。
(2)<进制><数字> 这种描述方式中,数字的位采用缺少位宽(这由具体的机器系统决定,但至少是32位)。
(3)在<数字> 这种描述方式中,采用十进制作为转为。
在表达式中,位宽指明了数字的精确位数,例如:一个4位二进制数的位宽为4,一个4位十六进制数的位宽为16(因为每个十六进制数就要用4位二进制数来表示)。
如:8'b101011008'ha22.x和z在数字电路中,x代表不定值,z代表高阻值(z可用?代替)。
比如:8'b101011x0表示,从右数第二位为不定值。
8'ha?表示从右数前四位二进制位(一位十六进制位)为高阻值。
还有一个我不太懂的也写出来:12‘d?表示,位宽为12的十进制整数。
(有些不十分明白,但也大致可以理解)3.负数-8'ha3 //正确用法(负号必须在最前面)8'h-a3 //错误用法4.下划线正确的加适当下划线可以增加程序的可读性,不影响程序的运行:16'b1101_1111_0011_1101 //正确(下划线只能在数字中加,不能在其它位置)16'b_1101_1111_0011_1101 //错误二、参数型常量parameter e=22,f=e+1;(个人感觉:挺像C语言中的宏定义的最基础用法)需要改变参数型常量的值时,用defparam语句变量:后面的越来越不懂……。
自己整理的:学习verilogDHL问题笔记——Quartus常见错误

⾃⼰整理的:学习verilogDHL问题笔记——Quartus常见错误我初学verilog语⾔,很多细节都没注意,按着⾃⼰的思想就写了,编译的时候才发现各种问题。
这些都是我在学习中遇到的问题,还是很常见的。
1.Error (10028): Can't resolve multiple constant drivers for net ……解析:不能在两个以上always内对同⼀变量赋值,这个细节⼀般看书看资料会看到,但是编程时,就是没想到。
2.Error (10158): Verilog HDL Module Declaration error at clkseg.v(1): port "XXXX" is not declared as port解析:⼤意了,端⼝类型还没定义啊!3.Error (10110): variable "en" has mixed blocking and nonblocking Procedural Assignments -- must be all blocking or all nonblocking assignments解析:en在程序中有时⽤⾮阻塞赋值,有时⽤阻塞赋值,这是禁⽌的。
在初学的时候,可能分得不是很清楚,所以在检查时,⼀定要⼀步步观察慢慢来。
4.Error (10161): Verilog HDL error at clkseg.v(36): object "count" is not declared解析:这个错误应该很明显啦,只要能读得懂。
5.Error (10170): Verilog HDL syntax error at clkseg.v(37) near text "***"; expecting ";"解析:意思应该也很简单,就是检查的时候要细⼼点。
学习verilog DHL问题笔记——Quartus常见错误

学习verilog DHL问题笔记——Quartus常见错误我初学verilog语言,很多细节都没注意,按着自己的思想就写了,编译的时候才发现各种问题。
这些都是我在学习中遇到的问题,还是很常见的。
1.Error (10028): Can't resolve multiple constant drivers for net ……解析:不能在两个以上always内对同一变量赋值,这个细节一般看书看资料会看到,但是编程时,就是没想到。
2.Error (10158): Verilog HDL Module Declaration error at clkseg.v(1): port "XXXX" is not declared as port解析:大意了,端口类型还没定义啊!3.Error (10110): variable "en" has mixed blocking and nonblocking Procedural Assignments -- must be all blocking or all nonblocking assignments解析:en在程序中有时用非阻塞赋值,有时用阻塞赋值,这是禁止的。
在初学的时候,可能分得不是很清楚,所以在检查时,一定要一步步观察慢慢来。
4.Error (10161): Verilog HDL error at clkseg.v(36): object "count" is not declared解析:这个错误应该很明显啦,只要能读得懂。
5.Error (10170): Verilog HDL syntax error at clkseg.v(37) near text "***"; expecting ";"解析:意思应该也很简单,就是检查的时候要细心点。
最新FPGA状态机学习笔记(verilog)资料

FPGA之有限状态机学习笔记有限状态机(FSM)是由寄存器组合组合逻辑构成的硬件时序电路。
FSM 的状态只可能在同一时钟跳变沿的情况下才能从一个状态转向另一个状态。
Mealy型FSM的下一个状态不仅取决于当前所在状态,还取决于各个输入值。
Moore型FSM的下一个状态只取决于当前状态。
Verilog HDL可以用很多方法描述FSM,最常用的是用always语句和case 语句。
FSM常用模型有Gray和独热码两种,对于用FPGA实现的FSM建议采用独热码。
因为采用独热码可省下许多组合电路的使用,提高电路的速度和可靠性,且总的单元数并无显著增加。
用Verilog语言描述FSM,可以充分发挥硬件描述语言的抽象建模能力。
有限状态机设计的一般步骤:(1)、逻辑抽象,得出状态转换图(2)、状态化简(3)、状态分配(4)、选定触发器的类型并求出状态方程、驱动方程和输出方程(5)、按照方程得出逻辑图以下就是分别用独热码和Gray码实现上述状态的源程序:采用独热码源程序:module fsm(Clock,Reset,A,B,C,D,E,Multi,Contig,Single);input Clock;input Reset;input A,B,C,D,E;output Multi,Contig,Single;reg Multi;reg Contig;reg Single;parameter [6:0]S1=7'b0000001,S2=7'b0000010,S3=7'b0000100,S4=7'b0001000,S5=7'b0010000,S6=7'b0100000,S7=7'b1000000;parameter U_DL Y=1;reg [6:0] curr_st;reg [6:0] next_st;always @(posedge Clock or posedge Reset) beginif(!Reset)curr_st=S1;elsecurr_st= #U_DL Y next_st;endalways @(curr_st or A or B or C or D or E) begincase(curr_st)S1:beginMulti =1'b0;Contig =1'b0;Single =1'b0;if(A&~B&C)next_st =S2;else if(A&B&~C)next_st =S4;elsenext_st =S1;endS2:beginMulti =1'b1;Contig =1'b0;Single =1'b0;if(!D)next_st =S3;elsenext_st =S4;endS3:beginMulti =1'b0;Contig =1'b1;Single =1'b0;if(A|D)next_st =S4;elsenext_st =S3;endS4:beginMulti =1'b1;Contig =1'b1;Single =1'b0;if(A&B&~C)next_st =S5;elsenext_st =S4;endS5:beginMulti =1'b1;Contig =1'b0;Single =1'b0;next_st =S6;endS6:beginMulti =1'b0;Contig =1'b1;Single =1'b1;if(!E)next_st =S7;elsenext_st =S6;endS7:beginMulti =1'b0;Contig =1'b1;Single =1'b0;if(E)next_st =S1;elsenext_st =S7;enddefault:next_st =S1;endcaseendendmoduleModelsim仿真激励文件程序如下:`timescale 1 ns/ 1 psmodule fsm_vlg_tst();// constants// general purpose registersreg eachvec;// test vector input registersreg A;reg B;reg C;reg Clock;reg D;reg E;reg Reset;// wireswire Contig;wire Multi;wire Single;// assign statements (if any)fsm i1 (// port map - connection between master ports and signals/registers .A(A),.B(B),.C(C),.Clock(Clock),.Contig(Contig),.D(D),.E(E),.Multi(Multi),.Reset(Reset),.Single(Single));initialbeginClock=0;forever #10Clock=~Clock;endinitialbeginReset=0;#100Reset=1;endinitialbegin//{A,B,C,D,E}=5'b10101;//# 10// {A,B,C,D,E}=5'b11000;{A,B,C,D,E}=5'b10111;//A=1;//B=0;//C=1;#100//{A,B,C,D,E}=5'b10101;D=0;#50//{A,B,C,D,E}=5'b10111;A=1;D=1;#50//{A,B,C,D,E}=5'b11011;A=1;B=1;C=0;#100//{A,B,C,D,E}=5'b11010;E=0;#50//{A,B,C,D,E}=5'b11011;E=1;endendmodule注:initial块中语句是顺序执行的,因此在需要延时的时候,按相对时间延时。
16位乘法器学习笔记(Verilog语言源程序+仿真程序)

LCD1602显示源程序如下:module lcd1602(input clk, //60Minput rst_n,output lcd_p, //Backlight Source + lcd屏幕背光output lcd_n, //Backlight Source -output reg lcd_rs, //0:write order; 1:write dataoutput lcd_rw, //0:write data; 1:read dataoutput reg lcd_en, //negedge 在lcd_en下降沿需保证数据有效output reg [7:0] lcd_data);mux16mul(.rst_n(rst_n),.clk(clk),.start(start),.ain(data0),.bin(data1),.yout(data2),.done(done));//端口名称关联//--------------------lcd1602 order----------------------------parameter Mode_Set = 8'h31, //功能设置,Cursor_Set = 8'h0c, //光标设置Address_Set = 8'h06, //输入模式设置Clear_Set = 8'h01; //清屏设置/****************************LCD1602 Display Data****************************/ wire [7:0] data_r0,data_r1,data_r2; //乘数、被乘数wire [15:0]data0,data1; //结果显示wire [31:0]data2;wire [7:0] addr; //write addresswire start,done;assign data_r0 = 8'h30 + data0[7:0] ; // 8'h30在LCD1602上显示值为0。
Verilog语言基础知识

在Verilog HDL中,用parameter来定义常量,即用parameter来定义一个标志符,代表一个常量,称为符号常量。其定义格式如下:
parameter 参数名1=表达式,参数名2=表达式,参数名3=表达式……;
例如:
parameter sel=8,code=8'ha3;
//分别定义参数sel为常数8(十进制),参数code为常数a3(十六进制)
Verilog HDL中共有19种数据类型。数据类型是用来表示数字电路中的数据存储和传送单元的。在此介绍4个最基本的数据类型:integer型、parameter型、reg型和wire型。
Verilog HDL中也有常量和变量之分,他们分属以上这些类型。
6.2.1 常量
在程序运行过程中,其值不能被改变的量称为常量。
assign {cout,sum}=ina+inb+cin;//全加
endmodule
【例6.2】一个8位计数器的Verilog HDL源代码
module counter8(out,cout,data,load,cin,clk);
output[7:0]out;
output cout;
input[7:0] data;
6.1.2 Verilog HDL模块的结构
Verilog HDL的基本设计单元是"模块(block)"。一个模块是由两部分组成的,一部分描述接口;另一部分描述逻辑功能,即定义输入是如何影响输出的。下面举例说明,图6.1示出了一个"与-或-非"门电路。
图6.1"与-或-非"电路
该电路表示的逻辑函数可以写为:
6.2.2 变量
Verilog学习笔记--运算符与阻塞非阻塞语句

verilog中的位运算符,缩位运算符和逻辑运算符的说明
1,位运算符
按位运算的运算符是位运算符,原来的操作数有几位,结果就有几位,若两个操作数位数不同,则位数短的操作数左端会自动补0(两个数右端对齐,位数少的操作数会在相应的高位补0)。
(1),按位取反:~
(2),按位与:&
(3),按位或:|
(4),按位异或:^
(5),按位同或:^~或~^
2,缩位运算符(又称归约运算符)
缩位运算符是单目运算符,按位进行逻辑运算,结果是一位值!
(1),与缩位运算符:&
(2),或缩位运算符:|
(3),异或缩位运算符:^
(4),与,或,异或运算符和非运算符组成的复合运算符:~&,~|,~^
3,逻辑运算符(逻辑关系运算)
(1),逻辑与:&&
(2),逻辑或:||
(3),逻辑非:!
其中,逻辑与和逻辑或是双目运算符,逻辑非是单目运算符。
如果操作数是多位的,则将操作数看做整体,若操作数中每一位都是0值则为逻辑0值,若操作数当中有1,则做位逻辑1值。
4,相等与全等运算符
(1),==
(2),!=
(3),===
(4),!==
== 、!= 、===、!== 符号之间不能有空格。
“==”和“!=”称作逻辑等式运算符,其结果由两个操作数的值决定。
由于操作数可能是x或z,其结果可能为x;
“===”和“!==”常用于case表达式的判别,又称作cae等式运算符。
其结果只为0和1.如果操作数中存在x和z,那么操作数必须完全相同结果才为1,否则为0.
逻辑等式运算符和case等式运算符的区别:。
FPGA笔记之verilog语言(基础语法篇)

FPGA笔记之verilog语言(基础语法篇)笔记之verilog语言(基础语法篇)写在前面:verilogHDL语言是面对硬件的语言,换句话说,就是用语言的形式来描述硬件线路。
因此与等软件语言不同,假如想要在实际的中实现,那么在举行verilog语言编写时,就需要提前有个硬件电路的构思和主意,同时,在编写verilog语言时,应当采纳可综合的语句和结构。
1. verilog 的基础结构1.1 verilog设计的基本单元——module在数字电路中,我们经常把一些复杂的电路或者具有特定功能的电路封装起来作为一个模块用法。
以后在运用这种模块化的封装时,我们只需要知道:1.模块的输入是什么;2.模块的输出是什么;3.什么样的输入对应什么样的输出。
而中间输入是经过什么样的电路转化为输出就不是我们在用法时需要特殊重视的问题。
当无数个这样的模块互相组合,就能构成一个系统,解决一些复杂的问题。
verilog语言的基础结构就是基于这种思想。
verilog中最基本的模块是module,就可以看做是一个封装好的模块,我们用verilog来写无数个基本模块,然后再用verilog描述多个模块之间的接线方式等,将多个模块组合得到一个系统。
那么一个module应当具有哪些要素呢?首先对于一个module,我们应当设计好其各个I/O,以及每个I/O的性质,用于与模块外部的信号相联系,让用法者知道如何连线。
第二,作为开发者,我们需要自己设计模块内部的线路来实现所需要的功能。
因此需要对模块内部浮现的变量举行声明,同时通过语句、代码块等实现模块的功能。
综上所述,我们把一个module分成以下五个部分:模块名端口定义I/O解释第1页共9页。
学习笔记-verilog控制12864显示汉字 - 副本

学习笔记-verilog控制12864显示汉字设计心得:1,在一个这样的非阻塞赋值的块里:Write_Ram : beginLCD_DATA <= data_disp;cnt <= cnt+1'b1;Read_addr <= {ref_data,cnt[4:0]}+1;if(CN_cnt <32)if(cnt <= 31)if(cnt[0]==1'b1)State <= Disp0;elseState <= Write_Ram;else;elseState <=Stop;end左值总保持在上一个时钟进来的值状态中,判断语句同样如此,不要认为是顺序赋值,值就改变。
2,设计中的时序仿真图,更能说明问题一:使用内置ROM块1,对所取字形取模(根据特点)如:汉字:张,取出点阵如下:{0x01,0x00,0xF9,0x08,0x09,0x08,0x09,0x10,0x09,0x20,0x79,0x40,0x41,0x00,0x47,0xFE},{0x41,0x40,0x79,0x20,0x09,0x20,0x09,0x10,0x09,0x08,0x09,0x44,0x51,0x82,0x21,0x00},/*"张2,生成hex文件(在keil中生成hex)3,创建ROM(利用内置的IP)本次设置:1024个word即2^10,可以存储16*16编码共32个(一个16*16编码占用8*2*2=32=2^5,2^10/2^5 =2^5 =32)选择生成的hex文件二:一个汉字的写表示此处写汉字所用的液晶模式为GDRAM形式,该形式下:绘图RAM的空间结构如下图所示:这些都是点阵,绘图RAM就是给这些点阵置1或置0,可以看到其实它本来是32行×256列的,但是分成了上下两屏显示,每个点对应了屏幕上的一个点。
要使用绘图功能需要开启扩展指令。
Verilog入门教程笔记

将编码后的信号还原成原始信号,常用于数据解压缩和控制信号生成。例如, 将3个输入信号译码成8个输出信号的3-8译码器。
多路选择器设计实例
多路选择器(Multiplexer)
根据选择信号从多个输入信号中选择一个输出,常用于数据选择和路由。例如,2选1 多路选择器、4选1多路选择器等。
明确CPU需要实现哪些指令集,具备哪些功能,以及达到什么样的性 能指标。
选择合适的架构
根据需求和性能指标,选择适合的CPU架构,如RISC或CISC。
设计指令集
根据所选架构,设计相应的指令集,包括指令格式、操作码、寻址方 式等。
规划寄存器组
设计寄存器组,包括通用寄存器、特殊功能寄存器等,以满足指令执 行和数据存储的需求。
03
组合逻辑电路设计
基本门电路实现方法
01
02
03
04
05
与门(AND Gate)或门(OR Gate) 非门(NOT Gate)与非门(NAND 或非门(NOR
Ga…
Gat…
实现逻辑与操作,当所有输 入为高电平时输出高电平。
实现逻辑或操作,当任一输 入为高电平时输出高电平。
实现逻辑非操作,将输入信 号取反后输出。
实现二进制数的减法运算,可 以通过加法器和取反器来实现。
实现二进制数的乘法运算,通 常采用逐位相乘再相加的方式 实现。
实现二进制数的除法运算,通 常采用逐位相除再减去的方式 实现,也可以使用更高效的算 法如SRT除法算法等。
04
时序逻辑电路设计
触发器类型及特点介绍
RS触发器
具有置0、置1和保持功能,是基 本存储单元。
数字电路的设计。
发展历程
Verilog学习笔记基本语法篇(十二)········编译预处理

Verilog学习笔记基本语法篇(⼗⼆)········编译预处理hVerilog HDL语⾔和C语⾔⼀样也提供编译预处理的功能。
在Verilog中为了和⼀般的语句相区别,这些预处理语句以符号"`"开头,注意,这个字符位于主键盘的左上⾓,其对应的上键盘字符为"~",这个符号并不是单引号"'".这⾥简单介绍最常⽤的`define `include `timescale.1)宏定义`define⽤⼀个指定的标识符(名字)来代表⼀个字符串,其的⼀般形式为: `define 标识符(宏名)字符串(宏内容)如:`define SIGNAL string其作⽤是在后⾯程序中⽤SIGNAL替代所有的string字符串,在编译预处理时,将程序中该命令后⾯所有的SIGNAL替换为string。
这种替代过程称作宏展开。
说明:a)宏名可以是⼤写字母,也可以是⼩写字母。
⼀般⽤⼤写字母,防⽌与后⾯的变量名重复。
b)`define可以出现在模块定义⾥⾯,也可以出现在外边。
其有效范围是从该命令⾏开始⾄源⽂件结束。
c)在引⽤已定义的宏名时,必须在宏名的前⾯加上符号`,表⽰该名字是⼀个经过宏定义的名字。
d)宏定义是⽤宏名代替⼀个字符串,只做简单替换不检查语法。
e)宏定义不是Verilog HDL语句,不必在后⾯加分号。
f)在进⾏宏定义时,可以引⽤已经定义的宏名,可以层层替换。
g)宏名和宏内容必须在同⼀⾏进⾏声明。
如果在宏内容中包含有注释⾏,注释⾏不会作为被置换的内容。
注意:组成宏内容的字符串不能够被以下的语句记号分隔开。
注释⾏+数字+字符串+确认符+关键词+双⽬或三⽬运算符如下⾯的宏定义声明和引⽤就是⾮法的:`define first_half "start of string$display(`first_half end of string")2)⽂件包含处理`include所谓⽂件包含是指处理⼀个源⽂件可以将另⼀个源⽂件的全部内容包含进来,即将另外⽂件包含到本⽂件之中。
Verilog学习笔记基本语法篇(九)········任务和函数

Verilog学习笔记基本语法篇(九)········任务和函数task 和 function 说明语句分别⽤来定义任务和函数,利⽤任务和函数可以把函数模块分成许多⼩的任务和函数便于理解和调试。
任务和函数往往还是⼤的程序模块在不同地点多次⽤到的相同的程序段。
输⼊、输出和总线信号的数据可以传⼊、传出任务和函数。
task 和 function 的不同:1)函数只能与主模块共⽤同⼀个仿真的时间单位,⽽任务可以⾃⼰定义⾃⼰的仿真时间单位。
2)函数不能启动任务,但是可以调⽤其它函数,但是任务可以调⽤其他函数和任务;3)函数⾄少要有⼀个输⼊变量,⽽任务可以没有或者有多个任何类型的变量。
4)函数返回⼀个值,⽽任务不返回任何值。
函数的⽬的值通过⼀个返回值对输⼊的信号进⾏响应。
⽽任务可以⽀持多种⽬的,能计算多个结果值,这些值只能通过任务的输出端⼝或者总线端⼝输出。
A) task说明语句如果传给任务的变量和任务完成后接受结果的变量已经定义,就可以⽤⼀条语句启动任务,任务完成以后控制就传回启动过程。
如果任务内部有定时设置,则启动的时间可以与控制返回的时间不同。
1)任务的定义;task <任务名>;<端⼝及数据类型声明语句><语句1>...<语句n>endtask2)任务的调⽤以及变量的传递:任务定义;task my_task;input a,b;inout c;output d,e;.... //执⾏任务的相应语句c=foo1; //对任务的变量赋初始值b=foo2;e=foo3;endtask任务的调⽤: my_task(v,w,x,y,z)任务调⽤变量(v,w,x,y,z)和任务定义的I/O变量(a,b,c,d,e)是⼀⼀对应的。
任务启动时,v,w和x的值给了a b c,结束时c,d,e的值返回给x,y,z。
学习笔记一:I2C协议学习和Verilog实现

学习笔记⼀:I2C协议学习和Verilog实现1//////////////////////////////////////////////////2//clk = 20 MHz ,⼀个周期50ns3//sck = 100 kHz (scl) ,⼀个周期 1000ns4//I2C在sck下降沿更新数据,上升沿读取(采样)数据5///////////////////////////////////////////////////6module demo_I2C #(parameter F100K = 9'd200)(clk,rstn,start_sig,word_addr,wr_data,rd_data,done_sig,scl,sda,sq_i);78input clk ;9input rstn ;1011input [1:0] start_sig ; //12input [7:0] word_addr ; //word address13input [7:0] wr_data ; //Data14output [7:0] rd_data ; //Data from EEPROM15output done_sig ;1617output scl ; //sda和scl其实是⽤来作为仿真信号添加在这⾥的,寄存器信号都⽤rscl和rsda表⽰了,最后⽤assign将rscl和rsda赋值给sda和scl,连到模块外部仿真⽤ 18inout sda ; //sda表⽰当前sda的in或out的值1920output [4:0] sq_i ;21/************************************22在这⾥,iic_func_module.v 的步骤i已经被引出来了。
读者要知道步骤i在⽆论是在设计上还是仿真上都有许多的好处。
23步骤i在仿真中可以充当“调试跟踪”的作⽤,因为只要模块的那个部分出问题,步骤i就会指向它。
Verilog学习笔记基本语法篇(六)········循环语句

Verilog学习笔记基本语法篇(六)········循环语句在Verilog中存在着4种类型的循环语句,⽤来控制执⾏语句的执⾏次数。
1)forever语句:连续执⾏的语句。
2)repeat语句:连续执⾏n次的语句。
3)while语句:执⾏语句,直⾄某个条件不满⾜。
4)for 语句:三个部分,尽量少⽤或者不⽤for循环。
各语句的格式与注意事项:
1)forever格式:
forever 语句;
或:forever begin 多条语句 end
常⽤于产⽣周期性的波形,⽤来作为仿真测试信号。
它与always的不同之处是不能独⽴在程序中,必须写在initial块中。
2)repeat格式:
repeat(表达式)语句;
或:repeat(表达式) begin 多条语句 end
在repeat中,其表达式常为常量表达式。
(可实现乘法器P60)
3)while格式:
while(表达式)语句;
或:while(表达式) begin 多条语句 end
4)for的格式:
for(表达式1;表达式2;表达式3)
语句;
执⾏过程与 c 语⾔中的for循环相同,注意表达式之间要⽤分号分割。
我的FQGA学习笔记。

单芯片可编程系统(SOPC)Verilog中不允许模块声明中嵌套模块。
SOPC:System-on-a-Programmable-Chip,即可编程片上系统。
用可编程逻辑技术把整个系统放到一块硅片上,称作SOPC。
可编程片上系统(SOPC)是一种特殊的嵌入式系统:首先它是片上系统(SOC),即由单个芯片完成整个系统的主要逻辑功能;其次,它是可编程系统,具有灵活的设计方式,可裁减、可扩充、可升级,并具备软硬件在系统可编程的功能。
清零——电子学术语:清零是一种指令。
在电子计算机硬件中,有计算器、累加器、中央存储器、外部存储器、地址存储器等。
使用清零指令,可以将存储器的状态(数据)变成原始的零状态。
即是存储器由高电位(代表逻辑1)翻转成地电位(代表逻辑0)。
同步清零:同步是指与时钟同步,即时钟触发条件满足时检测清零信号是否有效,有效则执行清零,异步清零:异步是清零信号有效即清零。
DFF: D类型触发器,它是在时钟信号作用下,输出结果根据D的状态而改变。
verilog 语言的三种描述方法1 结构型描述是通过实例进行描述的方法将verilog 预定义的基元实例嵌入到语言中监控实例的输入一旦其中任何一个发生变化便重新运算并输出2 数据流型描述(assign)是一种描述组合功能的方法用assign 连续赋值语句来实现连续赋值语句完成如下的组合功能等式右边的所有变量受持续监控每当这些变量中有任何一个发生变化整个表达式被重新赋值并送给等式左端这种描述方法只能用来实现组合功能3 行为型描述(always , initial ,if else , case, while , for , repeat , forever )(行为级上以更抽象的角度来考虑问题,并不关心具体的硬件实现方法,而是对其功能进行说明。
)initial ,always 块构成行为级建模的基础,其他所有行为级语句只能出现在这两块中。
是一种使用高级语言的方法它和用软件编程语言描述没有什么不同具有很强的通用性和有效性它是通过行为实例来实现的关键词是always其含义是一旦赋值给定仿真器便等待变量的下一次变化有无限循环之意。
SystemVerilog断言学习笔记

SystemVerilog断⾔学习笔记SystemVerilog断⾔学习笔记1⼀、前⾔随着数字电路规模越来越⼤、设计越来越复杂,使得对设计的功能验证越来越重要。
⾸先,我们要明⽩为什么要对设计进⾏验证?验证有什么作⽤?例如,在⽤FPGA进⾏设计时,我们并不能确保设计出来的东西没有功能上的漏洞,因此在设计后我们都会对其进⾏验证仿真。
换句话说,验证的⽬的是彻底地验证被测设计以确保设计没有功能上的缺陷。
⽽即将介绍的SystemVerilog断⾔便是⼀门重要的验证技术,它可以尽早发现设计的缺陷以及提⾼验证的效率。
⼆、基本概念1、什么是断⾔断⾔是设计属性的描述。
⽽断⾔可以从设计的功能描述中推知,然后转换成断⾔。
那么断⾔是如何表现的呢?当⼀个被检查的属性不像我们期望的那样表现时,则该断⾔失败;当⼀个禁⽌在设计中出现的属性发⽣时,则该断⾔失败。
2、为什么要使⽤SystemVerilog断⾔Verilog HDL也能实现断⾔,但其存在不⾜之处:Verilog HDL是⼀种过程语⾔,不能很好地控制时序;Verilog HDL是⼀种冗长的语⾔,随着断⾔数量的增加,维护代码将变得很困难;语⾔的过程性使得测试同⼀时间段内发⽣的并⾏事件相当困难;Verilog HDL没有提供内嵌的机制来提供功能覆盖的数据。
⽽SystemVerilog断⾔具有如下特征:它是⼀种描述性语⾔,可以完美描述时序的状况;语⾔本⾝⾮常精确且易于维护;语⾔的描述性提供了对时间卓越的控制;它提供了若⼲个内嵌函数来测试特定的设计情况,并且提供了⼀些构造来⾃动收集功能覆盖数据。
可见,使⽤SystemVerilog断⾔具有⾮常⼤的优势。
三、验证平台⼀个包含SystemVerilog断⾔的验证环境如下图所⽰:注:约束随机测试平台可以⽤来产⽣更多真实的验证情景;代码覆盖则是验证完整性的基本衡量标准。
⼀般情况下,测试平台需要做三件事:产⽣激励;⾃检机制;衡量功能覆盖。
verilog学习笔记-verilog基本语法

verilog学习笔记-verilog基本语法1.verilog中逻辑表⽰ 在verilog中,有4中逻辑: 逻辑0:表⽰低电平 逻辑1:表⽰⾼电平 逻辑X:表⽰未知电平 逻辑Z:表⽰⾼阻态2.Verilog中数字进制 Verilog数字进制格式包括⼆进制、⼋进制、⼗进制和⼗六进制。
⼀般常⽤的为⼆进制、⼗进制和⼗六进制。
d:表⽰⼗进制 b:表⽰⼆进制 o:表⽰⼋进制 h:表⽰⼗六进制 verilog中数字的表⽰⽅法: ⼆进制表⽰如下:4'b0101 表⽰4位⼆进制数字0101 ⼗进制表⽰如下:4'd2 表⽰4位⼗进制数字2(⼆进制0010) ⼗六进制表⽰如下:4'ha 表⽰4位⼗六进制数字a(⼆进制1010) 在verilog中负数的表⽰⽅法:在位宽前⾯加符号 例如: -5'd25:表⽰5位的⼗进制数-25 在veriog中如果位宽缺省则默认位宽是32位宽:'b1001表⽰32位的⼆进制数0000_0000_0000_0000_0000_0000_0000_1001。
在veriog中如果进制缺省则默认⼗进制。
3.标识符 ⽤于定义模块名,端⼝名,信号名等。
标识符可以是任意⼀组字母、数字、$符号和_(下划线)符号的组合。
但是第⼀个必须是字母或者下划线,⽽且标识符区分⼤⼩写。
书写标识符时应该简洁明了清晰,最好能够体现含义,如: clk_50M:表⽰50兆赫兹时钟。
cpu_addr:表⽰CPU的地址线4.数据类型 在verilog⾥有三种数据类型: reg型:寄存器数据类型。
wire型:线⽹型数据类型。
tri型:线⽹型数据类型。
reg型: 寄存器表⽰⼀个抽象的数据存储单元,通过赋值语句可以改变寄存器储存的值,寄存器数据类型的关键字是 reg,reg 类型数据的默认初始值为不定值x reg [7:0] data //表⽰定义了⼀个8位的寄存器类型的数据data. reg cnt_reg //表⽰定义了⼀个⼀位的寄存器类型的数据cnt_reg reg [7:0] data [255:0] //定义了256个8位的寄存器data reg类型的数据只能在 always 语句和 initial 语句中被赋值。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
parameter size = 8,longsize = 16;
reg [size:1] opa,opb;
reg [longsize:1] result;
begin: mult
reg [longsize:1] shift_opa,shift_opb;
begin
repeat(2) //重复两次产生下面的data变化
begin
data=4'b0000;
`stim0001;
/***************************************************************
宏定义stim引用,等同于#100 data=4'b0001;。注意引用时要用 `符号。
clk=0;
#3 reset = 0;
#5 reset = 1;
end
always #5 clk = ~clk;
endmodule
2.Verilog HDL建模在TOP-DOWN设计中的作用和行为建模的可综合性问题
(1)累加器用寄存器(ACCUMULATOR RREGISTER)
2) UDP可以有多个输入端,最多允许有10个输入端。
3) UDP所有端口变量必须是标量,也就是必须是1位的。
4) 在UDP的真值表项中,只允许出现0、1、X三种逻辑值,高阻值状态Z是不允许出现的。
5) 只有输出端才可以被定义为寄存器类型变量。
6) initial语句用于为时序电路内部寄存器赋初值,只允许赋0、1、X三种逻辑值,缺省值为X。
primitive 元件名(输出端口名,输入端口名1,输入端口名2,…)
output 输出端口名;
input 输入端口名1, 输入端口名2,…;
reg 输出端口名;
initial begin
输出端口寄存器或时序逻辑内部寄存器赋初值(0,1,或 X);
end
table
4.2.1仅用于产生仿真测试信号的Verilog HDL行为描述建模
module gen_clk ( clk, reset);
output clk;
output reset;
reg clk, reset;
initial
begin
reset = 1; //initial state
shift_opa = opa;
shift_opb = opb;
reslut = 0;
repeat(size)
begin
if(shift_opb[1])
result = result + shift_opa;
shift_opa = shift_opa << 1;
wire [3:0] qout;
`define stim #100 data=4'b //宏定义stim,可使源程序简洁
event end_first_pass; //定义事件end_first_pass
hardreg reg_4bit (.d(data), .clk(clock), .clrb(clearb), .q(qout));
/*****************************************************
类似于C语言的 printf 语句,可打印不同时刻的信号值
******************************************************/
initial
/**********************************************************************************
把本模块中产生的测试信号data、clock、clearb输入实例reg_4bit以观察输出信号qout.实例
reg_4bit引用了hardreg
f2(d[1],clk,clrb,q[1],),
f3(d[2],clk,clrb,q[2],),
f4(d[3],clk,clrb,q[3],);
endmodule
//在这使用了以上模块
module hardreg_top;
reg clock, clearb;
reg [3:0] data;
always @(negedge clock)
begin
case(opcode)
3'b000: #`ALUdly alu_out=accum; //Pass Accumulator
3'b001: #`ALUdly alu_out=accum; //Pass Accumulator
DFF d2(r[2],,load,data[2],rst);
DFF d1(r[1],,load,data[1],rst);
DFF d0(r[0],,load,data[0],rst);
Endmodule
其中 DFF和and都是Verilog语言中保留的关键字分别表示带复位端的D触发器和与门。
#200 -> end_first_pass;
/***********************************************
延迟200个单位时间,触发事件end_first_pass
************************************************/
end
//一个计数器
always @(a or b or c)
//D触发器
module flop(data,clock,clear,q,qb);
input data,clock,clear;
output q,qb;
nand #10 nd1(a,data,clock,clear),
//输入1 输入2 输入3 …: 输出
逻辑值 逻辑值 逻辑值 …: 逻辑值 ;
逻辑值 逻辑值 逻辑值 …: 逻辑值 ;
逻辑值 逻辑值 逻辑值 …: 逻辑值 ;
… … … …: …;
endtable
endprimitive
注意
1) UDP只能有一个输出端,而且必定是端口说明列表的第一项。
3'b110: #`ALUdly alu_out=accum; //Pass Accumulator
3'b111: #`ALUdly alu_out=accum; //Pass Accumulator
default: begin
$display("Unknown OPcode");
always @(end_first_pass)
clearb = ~rb;
always @(posedge clock)
$display("at time %0d clearb= %b data= %d qout= %d", $time, clearb, data, qout);
(2)RISC算术运算单元(RISC_ALU)
`timescale1ns/100ps
module riscalu ( alu_out, zero, opcode, data, accum, clock );
output [7:0] alu_out;
reg[7:0] alu_out;
DFF d7(r[7],,load,data[7],rst);
DFF d6(r[6],,load,data[6],rst);
DFF d5(r[5],,load,data[5],rst);
DFF d4(r[4],,load,data[4],rst);
DFF d3(r[3],,load,data[3],rst);
iv2(nclock,clock);
endmodule
//在此处使用了以上定义的D触发器
module hardreg(d,clk,clrb,q);
input clk,clrb;
input[3:0] d;
output[3:0] q;
flop f1(d[0],clk,clrb,q[0],),
**********************************************************************************/
initial
begin
clock = 0;
clearb = 1;
end
always #50 clock = ~clock;
$finish; //结束仿真
end
endmodule
//加法器
module adder(sum, cin, count, a, b);
input [2:0] a,b;
output [3:0] sum;
output [3:0] count;
assign {count,sum} = a + b + cin;
endmodule
//三态门
module san_state_gate(out, in, en);
input en,in_a;
output out;
bufif1 mybuf(out, in, en);
endmodule
//user defined primitives
UDP语言格式
shift_opb = shift_opb >> 1;