Verilog HDL学习笔记
- 格式:doc
- 大小:618.50 KB
- 文档页数:30
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语句变量:后面的越来越不懂……。
学习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之有限状态机学习笔记有限状态机(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块中语句是顺序执行的,因此在需要延时的时候,按相对时间延时。
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 HDL是在哪一年首次被IEEE标准化的?回答:1983年首次提出,1995年被IEEE标准化。
问题二:Verilog HDL支持哪三种基本描述方式?回答:行为描述方式(过程化结构建模),数据流方式(连续赋值语句方式),结构化方式(使用门和模块实例语句描述建模)。
问题三:Verilog HDL中的两类主要数据类型是什么?回答:线网数据类型wire型和寄存器数据类型reg型。
问题四:UDP代表什么?回答:用户定义原语,既可以是组合逻辑原语,也可以是时序逻辑原语。
问题五:开关级基本门和基本逻辑门?回答:pmos和nmos等为开关级基本门,and、or和nand等为基本逻辑门。
问题六:系统任务和系统函数的第一个字符标识符是什么?回答:$是系统任务和系统函数的字符标识符;问题七:Verilog HDL中是否有布尔类型?回答:有等效于布尔类型的,例如wire BIT;而且还有按位与,按位或等运算符;问题八:文本替换编译指令?`define BIT 32`undef BIT问题九:线网类型变量说明后未赋值,其缺省值为多少?回答:线网类型缺省值为z,寄存器类型缺省值为x;问题十:Verilog HDL允许没有显式说明的线网类型,此时怎样决定线网类型?回答:没有显式说明的线网类型取缺省为1位线网;问题十一:integer [0:3] Ripple;该说明错在哪里?回答:可以改成integer Ripple;或integer Ripple [0:3];前者定义一个整数型寄存器,后者定义一组4个整数型寄存器;问题十二:编写系统任务从数据文件”MEMA.DATA”加载32X64字存储器?reg [0:63] Mem [0:31];$readmemh (“MEMA.DATA”,Mem);问题十三:在编译时覆盖参数值的两种方法?回答:使用参数定义语句parameter或者在模块初始化语句中定义参数;问题十四:用移位操作符给2X4解码器建模?`timescale 1ns/1nsmodule Decoder(A,B,DecodeOut);input A,B;output [0:3]DecodeOut;assign DecodeOut=4’b1<<{A,B};endmodule问题十五:为什么有了if语句还要?:语句呢?回答:if语句只能用于always模块中,在assign中就用?:语句,而且某些时候后者更简洁灵活。
问题十六:如果case条件表达式和分支项表达式的长度不同会怎样?回答:在这种情况下,在进行任何比较前,所有的case表达式都统一为这些表达式的最长长度;而且case语句中x表示不确定值,z和?表示无关值;问题十七:顺序语句块和并行语句块的区别,顺序语句块能否出现在并行语句块中?回答:顺序语句块中的语句按顺序执行,并行语句块中语句按并行执行,这两者可以混合使用,可以相互出现在对方的语句块中;问题十八:语句块在什么时候需要标识符?回答:语句块的标识符是可选的,如果有标识符,寄存器变量可以在语句块内部声明,带标识符的语句块可被引用,语句块标识符提供唯一标识寄存器的一种方式,寄存器是静态的,它们的值在整个模拟运行中不变;问题十九:用一个initial语句和一个forever语句替代下面的always语句?always @(Expected or Observed)if(Expected !==Observed) begin$display (“MISMATCH:Expected = %b,Observed =%b”,Expected,Observed);$stop;end解答:initialbeginif(Observed!==Expected)forecer$display (“MISMATCH:Expected = %b,Observed =%b”,Expected,Observed);$stop;end问题二十:模块实例语句和门实例语句的区别?解答:门实例语句的端口定义不同的门对应有专门格式,如与门的第一个端口为输出,其他的端口为输入,模块实例语句的端口相对灵活,端口位置没有限制;模块实例语句有内部端口和外部端口之分,门实例语句没有;模块实例语句可以引用其他模块,门实例语句不能引用;问题二十一:函数和任务的区别?解答:函数,如同任务一样,也可以在模块不同位置执行共同代码。
函数与任务的不同之处是函数只能返回一个值,它不能包含任何时延或时序控制(必须立即执行),并且它不能调用其它的任务。
此外,函数必须带有至少一个输入,在函数中允许没有输出或输入输出说明。
函数可以调用其它的函数。
函数和任务定义中声明的局部寄存器都是静态的,在多个调用之间保持它们的值;模块是Verilog HDL的基本描述单位,用于描述某个设计的功能或结构及其与其他模块通信的外部端口。
连续赋值(即阻塞赋值)语句的语法为:assign [delay] LHS_net=RHS_expression;右边表达式使用的操作数无论何时发生变化,右边表达式都重新计算,并且在指定的时延后变化值被赋予左边表达式的线网变量,时延定义了右边表达式操作数变化与赋值给左边表达式之间的持续时间,如果没有定义时延值,缺省为0。
实例一:2X4解码器。
实例一是数据流描述方式,即采用连续赋值语句。
`timescale 1ns/1nsmodule Decoder2x4 (A,B,EN,Z);input A,B,EN;output [0:3] Z;wire Abar,Bbar;assign #1 Abar=~A;assign #1 Bbar=~B;assign #2 Z[0]=~(Abar&Bbar&EN);assign #2 Z[1]=~(Abar&B&EN);assign #2 Z[2]=~(A&Bbar&EN);assign #2 Z[3]=~(A&B&EN);endmodule注释:以反引号`开始的第一条语句是编译器指令,编译器指令`timescale将模块中所有时延的单位设置为1ns,时间精度为1ns,模块Decoder2x4有三个输入端口和一个4位输出端口,线网类型说明了两个连线型变量Abar和Bbar,模块包含6个连续赋值语句。
参见图2 - 3中的波形图。
当E N在第5 ns变化时,语句3、4、5和6执行。
这是因为E N是这些连续赋值语句中右边表达式的操作数。
Z[ 0 ]在第7 ns时被赋予新值0。
当A在第15 ns 变化时, 语句1、5和6执行。
执行语句5和6不影响Z[ 0 ]和Z[ 1 ]的取值。
执行语句5导致Z[ 2 ]值在第17 ns变为0。
执行语句1导致A b a r在第16 ns被重新赋值。
由于A b a r的改变,反过来又导致Z[ 0 ]值在第18 n s变为1。
请注意连续赋值语句是如何对电路的数据流行为建模的;这种建模方式是隐式而非显式的建模方式。
此外,连续赋值语句是并发执行的,也就是说各语句的执行顺序与其在描述中出现的顺序无关。
实例二:1位全加器。
实例二是行为描述方式,即采用过程语句结构描述,always语句总是循环重复执行。
module FA_Seq (A,B,Cin,Sum,Cout);input A,B,Cin;output Sum,Cout;reg Sum,Cout;reg T1,T2,T3;always@(A or B or Cin)beginSum=(A^B)^Cin;T1=A&Cin;T2=B&Cin;T3=A&B;Cout=(T1|T2)|T3;endendmodule注释:模块FA_Seq有三个输入和两个输出,由于Sum和Cout和T1和T2和T3在always语句中被赋值,他们被说明为reg类型,always语句中有一个与事件控制(跟在@后面的表达式)相关联的顺序过程(begin-end对),只要A、B或Cin之一的值发生变化,顺序过程就执行,顺序过程中的语句顺序执行,顺序过程执行结束之后被挂起,always语句再次等待触发事件。
实例三:initial语句。
实例三也是行为描述方式,采用initial语句,只执行一次。
`timescale 1ns/1nsmodule Test (Pop, Pid) ;output Pop, Pid;reg Pop, Pid;initialbeginPop=0;Pid=0;Pop=#5 1;Pid=#3 1;Pop=#6 0;Pid=#2 0;endendmodule注释:initial语句包含一个顺序过程,这一顺序过程在0ns时开始执行,所有语句全部执行完毕后,initial语句永远挂起,顺序过程中包含定义语句内时延的分组过程赋值的实例,只有寄存器类型数据reg型能够在这两种语句(initial语句和always语句)中被赋值,所有初始化语句和always语句在0时刻并发执行。
实例四:用内置门原语描述1位全加器,即结构化描述方式。
在Verilog HDL中可用如下方式描述结构:内置门原语,开关级原语,用户定义原语,模块实例;通过使用线网来相互连接。
module FA_Str (A,B,Cin,Sum,Cout);input A,B,Cin;output Sum,Cout;wire S1,T1,T2,T3;xorX1 (S1,A,B);X2(Sum,S1,Cin);andA1 (T3,A,B);A2(T2,B,Cin);A3 (T1,A,Cin);orO1 (Cout,T1,T2,T3);endmodule注释:在该实例中,模块包含门的实例语句,也就是说包含内置门xor、and、or的实例语句(在这种表达方式中,将内置门看成是已经存在的实例),门实例由线网类型变量S1,T1,T2,T3互连,由于没有指定的顺序,门实例语句可以以任何顺序出现,xor、and、or是内置门原语,X1,X2,A1,A2,A3,O1是实例名称,紧跟在每个门后的信号列表是它的互连,列表中第一个是门输出,余下的是输入。
实例五:由4个1位全加器构成一个4位全加器,采用结构描述形式。
module FourBitFA(FA,FB,FCin,FSum,FCout);parameter SIZE=4;input [SIZE:1] FA,FB;output [SIZE:1] FSum;input FCin;output FCout;wire [1:SIZE-1] FTemp;FA_StrFA1( .A(FA[1]), .B(FB[1]), .Cin(FCin), .Sum(FSum[1]), .Cout(FTemp[1])),FA2( .A(FA[2]), .B(FB[2]), .Cin(FTemp[1]), .Sum(FSum[2]), .Cout(FTemp[2])),FA3(FA[3],FB[3],FTemp[2],FSum[3],FTemp[3]),FA4(FA[4],FB[4],FTemp[3],FSum[4],FCout);endmodule注释:在这一实例中,模块实例用于建模4位全加器,在模块实例语句中,端口可以与名称或位置关联;前两个实例FA1,FA2使用名称关联方式,也就是说,端口的名称和它连接的线网被显式描述(每一个的形式都为.port_name(net_name));后两个实例语句,实例FA3,FA4使用位置关联方式将端口与线网关联,关联顺序很重要(FA[4]与FA_Str端口A连接,FB[4]与FA_Str的端口B连接,余下的由此类推),临时变量FTemp定义成wire类型。