verilog数字系统设计教程第四版例题源码
- 格式:docx
- 大小:36.87 KB
- 文档页数:4
verilog 数字系统设计教程习题答案第二章HDL 既是一种行为描述语言,也是一种结构描述语言。
如果按照一定的规则和风格编写代码,就可以将功能行为模块通过工具自动转化为门级互联的结构模块。
这意味着利用Verilog 语言所提供的功能,就可以构造一个模块间的清晰结构来描述复杂的大型设计,并对所需的逻辑电路进行严格的设计。
2.模块的基本结构由关键词module和endmodule构成。
3.一个复杂电路系统的完整Verilog HDL 模型是由若干个VerilogHDL模块构成的,每一个模块又可以由若干个子模块构成。
其中有些模块需要综合成具体电路,而有些模块只是与用户所设计的模块交互的现存电路或激励信号源。
利用Verilog HDL语言结构所提供的这种功能就可以构造一个模块间的清晰层次结构来描述极其复杂的大型设计,并对所作设计的逻辑电路进行严格的验证。
HDL和VHDL乍为描述硬件电路设计的语言,其共同的特点在于:能形式化地抽象表示电路的结构和行为、支持逻辑设计中层次与领域的描述、可借用高级语言的精巧结构来简化电路的描述、具有电路仿真与验证机制以保证设计的正确性、支持电路描述由高层到低层的综合转换、硬件描述与实现工艺无关(有关工艺参数可通过语言提供的属性包括进去)、便于文档管理、易于理解和设计重用。
5.不是6.将用行为和功能层次表达的电子系统转换为低层次的便于具体实现的模块组合装配的过程。
7.综合工具可以把HDL变成门级网表。
这方面Synopsys工具占有较大的优势,它的Design Compile 是作为一个综合的工业标准,它还有另外一个产品叫Behavior Compiler ,可以提供更高级的综合。
另外最近美国又出了一个软件叫Ambit ,据说比Synopsys 的软件更有效,可以综合50万门的电路,速度更快。
今年初Ambit 被Cadence 公司收购,为此Cade nee放弃了它原来的综合软件Syn ergy。
数字系统设计与veriloghdl课后答案【篇一:数字逻辑与数字系统设计习题参考答案】>第1章习题解答1.3 (1)86(2)219(3)106.25(4)0.6875 (4)0.1011.4 (1)101111(2)1001000(3)100001l.111.5 (1)(117)10=(165)8=(1110101)2=(75)16(2)(3452)10=(6574)8=(110101111100)2=(d7c)16(3)(23768.6875)10=(56330.54)8=(101110011011000.1011)2=(5cd 8.b)16 (4)(0.625)10=(0.5)8=(0.101)2=(0.a)16 1.6(1)(117)8=(1001111)2=(79)10(2)(7456)8=(111100101110)2=(3886)10(3)(23765.64)8=(10 0111 1111 0101.1101)2=(10229.8125)10(4)(0.746)8=(0.11111)2=(0.96875)10 1.7 (1)(9a)16=(10011010)2=(154)10(2) (3cf6)16=(11110011110110)2=(15606)10(3) (7ffe.6)16=(111111*********.011)2=(32766.375)10 (4)(0.c4)16=(0.110001)2=(0.765625)10 1-8(1)(125)10=(000100100101)8421bcd(2)(7342)10=(0111001101000010)8421bcd(3)(2018.49)10=(0010000000011000.01001001)8421bcd(4)(0.785)10=(0.011110000101)8421bcd1.9(1)(106)10=(1101010)2 原码=反码=补码=01101010 (2)(-98)10=(-1100010)2原码=11100010反码=10011101 补码=11100011(3)(-123)10=(-1111011)2 原码=11111011反码=10000101 补码=11111011(4)(-0.8125)10=(-0.1101)2 原码=1.1101000反码=1.0010111 补码=1.00110001.10(1)(104)10=(1101000)2 [1101000]补=01101000(-97)10=(-1100001)2 [-1100001]补=1001111101101000 + 10011111 0000011110000011 + 01001111 11010010[104-97]补=01101000+10011111=00000111, 104-97=(00000111)2=7 (2) (-125)10=(-1111101)2(79)10=(01001111)2[-1111101]补=10000011 [01001111]补=0100111101111000 [-125+79]补=10000011+01001111=11010010,-125+79=(-0101110)2=-46 (3) (120)10=(1111000)2[01111000]补=01111000(-67)10=(-1000011)2[-1000011]补=10111101[120-67]补=10000011+01001111=00110101,-125+79=(00110101)2=53 (4) (-87)10=(-1010111)2[-1010111]补=10101001(12)10=(1100)2[1100]补=00001100[-87+12]补=10101001+00001100=10110101,-125+79=(-1001011)2=-75+ 10111101 0011010110101001+ 00001100 10110101第2章习题解答2.3 解:根据逻辑图可直接写出逻辑表达式:(a) f=ab?bc;(b)f=abbcac解:设3个输入变量分别为a、b、c,输出为f,按题意,其中有奇数个为1,则输出f=1,因此可写出其逻辑表达式为f=abc?abc?abc?abc。
《Verilog数字系统设计教程》夏宇闻第四版思考题答案(第2章)1.Verilog语⾔有什么作⽤?可描述顺序执⾏和并⾏执⾏的程序结构;⽤延迟表达式或事件表达式来明确的控制过程的启动时间;通过命名的事件来触发其它过程⾥的激活⾏为或停⽌⾏为;提供了条件如if-else,case等循环程序结构;提供了可带参数且⾮零延续时间的任务程序结构;提供了可定义新的操作符的函数结构;提供了⽤于建⽴表达式的算术运算符,逻辑运算符,位运算符;Verilog HDL语⾔作为⼀种结构化的语⾔⾮常适⽤于门级和开关级的模型设计;提供了⼀套完整的表⽰组合逻辑的基本元件的原话;提供了双向通路和电阻器件的原话;可建⽴MOS器件的电荷分享和电荷衰减动态模型;Verilog HDL的构造性语句可以精确地建⽴信号的模型;2.构成模块的关键词是什么?module,endmodule。
3.为什么说可以⽤Verilog构成⾮常复杂的电路结构?因为Verilog可描述顺序执⾏和并⾏执⾏的程序结构;⽤延迟表达式或事件表达式来明确的控制过程的启动时间;通过命名的事件来触发其它过程⾥的激活⾏为或停⽌⾏为;提供了条件如if-else,case等循环程序结构;提供了可带参数且⾮零延续时间的任务程序结构;提供了可定义新的操作符的函数结构;提供了⽤于建⽴表达式的算术运算符,逻辑运算符,位运算符;Verilog HDL语⾔作为⼀种结构化的语⾔⾮常适⽤于门级和开关级的模型设计;提供了⼀套完整的表⽰组合逻辑的基本元件的原话;提供了双向通路和电阻器件的原话;可建⽴MOS器件的电荷分享和电荷衰减动态模型Verilog HDL的构造性语句可以精确地建⽴信号的模型;4.为什么可以⽤⽐较抽象的描述来设计具体的电路结构?因为有可以⽤⽐较抽象描述设计电路结构的语⾔,⽽这种语⾔是适合数字系统设计的语⾔。
5.是否任意抽象的符合语法的Verilog模块都可以通过综合⼯具转变为电路结构?不能。
Verilog 数字系统设计90例verilog数字系统设计90例verilog数字系统设计代码90基准合肥工业大学宣城校区微电子科学与工程verilog数字系统设计contents1、二选一多路选择器............................................................................ ..............................12、多路器模块的编写测试平台............................................................................ ..............13、三位加法器............................................................................ ..........................................24、比较器............................................................................ ..................................................25、实例调用―三态门选择器............................................................................ ..................26、同步置位/清零的计数器............................................................................ .....................37、异步清零............................................................................ ..............................................38、case语句实现3-8译码器的部分代码 (3)9、for语句来实现8位数据中低4位左移到高4位........................................................410、for语句计算出13路脉冲信号为高电平的个数........................................................411、生成语句对两个n 位的总线用门级原语进行按位异或...........................................512、用条件生成语句实现参数化乘法器............................................................................ 513、使用case生成语句实现n位加法器.. (61)4、四选一多路器............................................................................ ....................................715、四位计数器............................................................................ ........................................716、使用任务控制交通灯............................................................................ ........................817、cpu总线控制的任务............................................................................ .......................918、自动任务示例............................................................................ ....................................919、用函数实现乘累加器............................................................................ .......................1020、计算32位地址值的偶校验位............................................................................ .........1121、左/右移位寄存器............................................................................ ..............................1222、用函数的递归调用定义阶乘计算............................................................................ ...1223、常量函数............................................................................ ...........................................1324、带符号函数............................................................................ .......................................1325、显示任务............................................................................ ...........................................1426、文件写入操作的例子............................................................................ .......................1427、读取文件的示例1............................................................................. ...........................1528、读取文件的示例2............................................................................. ...........................1529、使用$random生成随机数............................................................................ ................1630、宏定义语句`define....................................................................... .................................1631、带有宏定义的8位加法器............................................................................ ...............1732、用`include语句设计的16位加法器 (1)733、结构化描述方式对四选一多路选择器.......................................................................1834、结构化描述方式实现一位全加器...............................................................................1835、结构化描述方式实例化四个一位全加器实现四位串行进位全加器.......................1836、用户定义原语............................................................................ ...................................1937、四选一的多路选择器的自定义原语设计...................................................................2038、用户定义原语的方式设计电平敏感锁存器...............................................................2039、用户定义原语的方式设计d触发器(时钟下降沿触发)......................................2040、采用实例化前面用定义原语设计的四选一多路选择器(mux)的方法实现十六合肥工业大学宣城校区微电子科学与工程verilog数字系统设计选一的多路选择器............................................................................ (21)41、数据流建模叙述方式:一位全加器............................................................................ ..2242、犯罪行为建模方式设计一位加法器............................................................................ .......2243、混合设计方式设计一位全加器............................................................................ .......2244、数据流叙述方式对四挑选一多路选择器建模...............................................................2345、犯罪行为建模方式设计四挑选一多路选择器.......................................................................2346、用rtl级建模方式设计此电路............................................................................ ......2447、四位全加器............................................................................ .......................................2448、女团逻辑电路............................................................................ ...................................2449、单向三态端口............................................................................ ...................................2550、单向总线缓冲器............................................................................ ...............................2551、双向三态端口............................................................................ ...................................2552、双向总线缓冲器............................................................................ ...............................2653、2挑选1多路选择器............................................................................ ............................2654、多路比较器............................................................................ .......................................2755、拎CX600X端的3-8译码器............................................................................ .................2856、4十一位二进制至格雷码点的转换器............................................................................ ........2957、时序逻辑电路............................................................................ ...................................3058、jk触发器............................................................................ ..........................................3159、d触发器............................................................................ ............................................3260、拎异步登位端的d触发器............................................................................ ...................3261、拎异步置位端的d触发器............................................................................ ...................3262、具有异步置位和登位的d触发器............................................................................ ...3363、具有同步登位的d触发器............................................................................ ...............3364、拎同步置位端的下降沿触发器............................................................................ ........3365、拎异步登位端的和输入CX600X端的下降沿触发器............................................................3466、门锁存器:电平引爆的存储器单元,基本sr门锁存器.................................................3467、透明化门锁存器............................................................................ ........................................3568、基本n十一位同步计数器............................................................................ .......................3569、具有异步登位、同步计数CX600X和可以预置的十进制计数器........................................3570、格雷码计数器............................................................................ ....................................3671、四位移位寄存器............................................................................ ................................3772、8位撬装谢朗特移位寄存器.............................................................................................3773、利用移位寄存器产生顺序脉冲............................................................................ ........3874、可以输入输出信号的2分频信号、4分频信号和8分频信号的分频器.....................3875、分频系数为12的分频器............................................................................ ..................3976、分频系数为6,充电电流为1:5的偶数分频器..............................................................3977、3分频充电电流为1:1的奇数分频器............................................................................ ..4078、分频系数为5、充电电流为1:1的奇数分频器..............................................................4179、分频系数为7、充电电流为1:6的奇数分频器..............................................................4280、带使能端和登位端的时钟同步8十一位寄存器组逻辑....................................................4281、自引爆always 块............................................................................ ...............................4282、1001序列信号检测器............................................................................ .......................4383、米利型非常有限状态机............................................................................ . (47)合肥工业大学宣城校区微电子科学与工程verilog数字系统设计84、自动购饮料机的设计............................................................................ ........................4985、循序数据流切换为一种特定以太网数据流模块的设计................................................5386、设计对数字收集芯片ad0809的掌控USB电路的verilog代码...............................5787、面积优化――设计乘法选择器............................................................................ .........6188、串行化――叙述一个乘法累加器,其位宽位16十一位对8个16位数据进行乘法和加法运算.......................................................................6389、流水线设计――流水线计数使用实例:8位加法器..................................................6490、流水线设计――设计一个为8位全加器(一个就是轻易同时实现,一个使用4级流水线同时实现) (65)合肥工业大学宣城校区微电子科学与工程verilog数字系统设计1、二挑选一多路选择器行为描述:modulemuxtwo(out,a,b,sl);inputa,b,sl;outputout;regout;always@(aorborsl)if(!sl)out=a;elseout=b;endmodule逻辑叙述:modulemuxtwo(out,a,b,sl);inputa,b,sl;outputout;不必写下寄存器wirensl,sela,selb;assignnsl=~sl;assignsela=a&nsl;assignselb=b&sl;assignout=sel a|selb;endmodule门级叙述:modulemuxtwo(out,a,b,sl);inputa,b,sl;outputout;不用写寄存器notu1(nsl,sl);andu2(sela,a,nsl);andu3(selb,b,sl);oru4(out,sela,selb);endmodule2、多路器模块的编写测试平台`include“muxtwo.v”1。
王金明:《Verilog HDL程序设计教程》- 1 -【例3.1】4 位全加器module adder4(cout,sum,ina,inb,cin);output[3:0] sum;output cout;input[3:0] ina,inb;input cin;assign {cout,sum}=ina+inb+cin;endmodule【例3.2】4 位计数器module count4(out,reset,clk);output[3:0] out;input reset,clk;reg[3:0] out;always @(posedge clk)beginif (reset) out<=0; //同步复位else out<=out+1; //计数endendmodule【例3.3】4 位全加器的仿真程序`timescale 1ns/1ns`include "adder4.v"module adder_tp; //测试模块的名字reg[3:0] a,b; //测试输入信号定义为reg型reg cin;wire[3:0] sum; //测试输出信号定义为wire型wire cout;integer i,j;adder4 adder(sum,cout,a,b,cin); //调用测试对象always #5 cin=~cin; //设定cin的取值initialbegina=0;b=0;cin=0;for(i=1;i<16;i=i+1)#10 a=i; //设定a的取值end 程序文本- 2 -initialbeginfor(j=1;j<16;j=j+1)#10 b=j; //设定b的取值endinitial //定义结果显示格式begin$monitor($time,,,"%d + %d + %b={%b,%d}",a,b,cin,cout,sum);#160 $finish;endendmodule【例3.4】4 位计数器的仿真程序`timescale 1ns/1ns`include "count4.v"module coun4_tp;reg clk,reset; //测试输入信号定义为reg型wire[3:0] out; //测试输出信号定义为wire型parameter DELY=100;count4 mycount(out,reset,clk); //调用测试对象always #(DEL Y/2) clk = ~clk; //产生时钟波形initialbegin //激励信号定义clk =0; reset=0;#DELY reset=1;#DELY reset=0;#(DELY*20) $finish;end//定义结果显示格式initial $monitor($time,,,"clk=%d reset=%d out=%d", clk, reset,out);endmodule【例3.5】“与-或-非”门电路module AOI(A,B,C,D,F); //模块名为AOI(端口列表A,B,C,D,F)input A,B,C,D; //模块的输入端口为A,B,C,Doutput F; //模块的输出端口为F 王金明:《Verilog HDL程序设计教程》- 3 -wire A,B,C,D,F; //定义信号的数据类型assign F= ~((A&B)|(C&D)); //逻辑功能描述endmodule【例5.1】用case语句描述的4 选1 数据选择器module mux4_1(out,in0,in1,in2,in3,sel);output out;input in0,in1,in2,in3;input[1:0] sel;reg out;always @(in0 or in1 or in2 or in3 or sel) //敏感信号列表case(sel)2'b00: out=in0;2'b01: out=in1;2'b10: out=in2;2'b11: out=in3;default: out=2'bx;endcaseendmodule【例5.2】同步置数、同步清零的计数器module count(out,data,load,reset,clk);output[7:0] out;input[7:0] data;input load,clk,reset;reg[7:0] out;always @(posedge clk) //clk上升沿触发beginif (!reset) out = 8'h00; //同步清0,低电平有效else if (load) out = data; //同步预置else out = out + 1; //计数endendmodule【例5.3】用always 过程语句描述的简单算术逻辑单元`define add 3'd0`define minus 3'd1`define band 3'd2`define bor 3'd3`define bnot 3'd4 程序文本- 4 -module alu(out,opcode,a,b);output[7:0] out;reg[7:0] out;input[2:0] opcode; //操作码input[7:0] a,b; //操作数always@(opcode or a or b) //电平敏感的always块begincase(opcode)`add: out = a+b; //加操作`minus: out = a-b; //减操作`band: out = a&b; //求与`bor: out = a|b; //求或`bnot: out=~a; //求反default: out=8'hx; //未收到指令时,输出任意态endcaseendendmodule【例5.4】用initial过程语句对测试变量A、B、C 赋值`timescale 1ns/1nsmodule test;reg A,B,C;initialbeginA = 0;B = 1;C = 0;#50 A = 1; B = 0;#50 A = 0; C = 1;#50 B = 1;#50 B = 0; C = 0;#50 $finish ;endendmodule【例5.5】用begin-end 串行块产生信号波形`timescale 10ns/1nsmodule wave1;reg wave;parameter cycle=10;initialbegin 王金明:《Verilog HDL程序设计教程》- 5 -wave=0;#(cycle/2) wave=1;#(cycle/2) wave=0;#(cycle/2) wave=1;#(cycle/2) wave=0;#(cycle/2) wave=1;#(cycle/2) $finish ;endinitial $monitor($time,,,"wave=%b",wave);endmodule【例5.6】用fork-join 并行块产生信号波形`timescale 10ns/1nsmodule wave2;reg wave;parameter cycle=5;initialforkwave=0;#(cycle) wave=1;#(2*cycle) wave=0;#(3*cycle) wave=1;#(4*cycle) wave=0;#(5*cycle) wave=1;#(6*cycle) $finish;joininitial $monitor($time,,,"wave=%b",wave);endmodule【例5.7】持续赋值方式定义的2 选 1 多路选择器module MUX21_1(out,a,b,sel);input a,b,sel;output out;assign out=(sel==0)?a:b;//持续赋值,如果sel为0,则out=a ;否则out=b endmodule【例5.8】阻塞赋值方式定义的2 选 1 多路选择器module MUX21_2(out,a,b,sel);input a,b,sel; 程序文本- 6 -output out;reg out;always@(a or b or sel)beginif(sel==0) out=a; //阻塞赋值else out=b;endendmodule【例5.9】非阻塞赋值module non_block(c,b,a,clk);output c,b;input clk,a;reg c,b;always @(posedge clk)beginb<=a;c<=b;endendmodule【例5.10】阻塞赋值module block(c,b,a,clk);output c,b;input clk,a;reg c,b;always @(posedge clk)beginb=a;c=b;endendmodule【例5.11】模为60 的BCD码加法计数器module count60(qout,cout,data,load,cin,reset,clk);output[7:0] qout;output cout;input[7:0] data;input load,cin,clk,reset;reg[7:0] qout;always @(posedge clk) //clk上升沿时刻计数王金明:《Verilog HDL程序设计教程》- 7 -beginif (reset) qout<=0; //同步复位else if(load) qout<=data; //同步置数else if(cin)beginif(qout[3:0]==9) //低位是否为9,是则beginqout[3:0]<=0; //回0,并判断高位是否为5if (qout[7:4]==5) qout[7:4]<=0;elseqout[7:4]<=qout[7:4]+1; //高位不为5,则加1endelse //低位不为9,则加1qout[3:0]<=qout[3:0]+1;endendassign cout=((qout==8'h59)&cin)?1:0; //产生进位输出信号endmodule【例5.12】BCD码—七段数码管显示译码器module decode4_7(decodeout,indec);output[6:0] decodeout;input[3:0] indec;reg[6:0] decodeout;always @(indec)begincase(indec) //用case语句进行译码4'd0:decodeout=7'b1111110;4'd1:decodeout=7'b0110000;4'd2:decodeout=7'b1101101;4'd3:decodeout=7'b1111001;4'd4:decodeout=7'b0110011;4'd5:decodeout=7'b1011011;4'd6:decodeout=7'b1011111;4'd7:decodeout=7'b1110000;4'd8:decodeout=7'b1111111;4'd9:decodeout=7'b1111011;default: decodeout=7'bx;endcaseend 程序文本- 8 -endmodule【例5.13】用casez 描述的数据选择器module mux_casez(out,a,b,c,d,select);output out;input a,b,c,d;input[3:0] select;reg out;always @(select or a or b or c or d)begincasez(select)4'b???1: out = a;4'b??1?: out = b;4'b?1??: out = c;4'b1???: out = d;endcaseendendmodule【例5.14】隐含锁存器举例module buried_ff(c,b,a);output c;input b,a;reg c;always @(a or b)beginif((b==1)&&(a==1)) c=a&b;endendmodule【例5.15】用for 语句描述的七人投票表决器module voter7(pass,vote);output pass;input[6:0] vote;reg[2:0] sum;integer i;reg pass;always @(vote)beginsum=0; 王金明:《Verilog HDL程序设计教程》- 9 -for(i=0;i<=6;i=i+1) //for语句if(vote[i]) sum=sum+1;if(sum[2]) pass=1; //若超过4人赞成,则pass=1 else pass=0;endendmodule【例5.16】用for 语句实现2 个8 位数相乘module mult_for(outcome,a,b);parameter size=8;input[size:1] a,b; //两个操作数output[2*size:1] outcome; //结果reg[2*size:1] outcome;integer i;always @(a or b)beginoutcome=0;for(i=1; i<=size; i=i+1) //for语句if(b[i]) outcome=outcome +(a << (i-1));endendmodule【例5.17】用repeat 实现8 位二进制数的乘法module mult_repeat(outcome,a,b);parameter size=8;input[size:1] a,b;output[2*size:1] outcome;reg[2*size:1] temp_a,outcome;reg[size:1] temp_b;always @(a or b)beginoutcome=0;temp_a=a;temp_b=b;repeat(size) //repeat语句,size为循环次数beginif(temp_b[1]) //如果temp_b的最低位为1,就执行下面的加法outcome=outcome+temp_a;temp_a=temp_a<<1; //操作数a左移一位程序文本- 10 -temp_b=temp_b>>1; //操作数b右移一位endendendmodule【例5.18】同一循环的不同实现方式module loop1; //方式1integer i;initialfor(i=0;i<4;i=i+1) //for语句begin$display(“i=%h”,i);endendmodulemodule loop2; //方式2integer i;initial begini=0;while(i<4) //while语句begin$display ("i=%h",i);i=i+1;endendendmodulemodule loop3; //方式3integer i;initial begini=0;repeat(4) //repeat语句begin$display ("i=%h",i);i=i+1;endendendmodule【例5.19】使用了`include 语句的16 位加法器王金明:《Verilog HDL程序设计教程》- 11 -`include "adder.v"module adder16(cout,sum,a,b,cin);output cout;parameter my_size=16;output[my_size-1:0] sum;input[my_size-1:0] a,b;input cin;adder my_adder(cout,sum,a,b,cin); //调用adder模块endmodule//下面是adder模块代码module adder(cout,sum,a,b,cin);parameter size=16;output cout;output[size-1:0] sum;input cin;input[size-1:0] a,b;assign {cout,sum}=a+b+cin;endmodule【例5.20】条件编译举例module compile(out,A,B);output out;input A,B;`ifdef add //宏名为addassign out=A+B;`elseassign out=A-B;`endifendmodule【例6.1】加法计数器中的进程module count(data,clk,reset,load,cout,qout);output cout;output[3:0] qout;reg[3:0] qout;input[3:0] data;input clk,reset,load;程序文本- 12 -always @(posedge clk) //进程1,always过程块beginif (!reset) qout= 4'h00; //同步清0,低电平有效else if (load) qout= data; //同步预置else qout=qout + 1; //加法计数endassign cout=(qout==4'hf)?1:0; //进程2,用持续赋值产生进位信号endmodule【例6.2】任务举例module alutask(code,a,b,c);input[1:0] code;input[3:0] a,b;output[4:0] c;reg[4:0] c;task my_and; //任务定义,注意无端口列表input[3:0] a,b; //a,b,out名称的作用域范围为task任务内部output[4:0] out;integer i;beginfor(i=3;i>=0;i=i-1)out[i]=a[i]&b[i]; //按位与endendtaskalways@(code or a or b)begincase(code)2'b00: my_and(a,b,c);/* 调用任务my_and,需注意端口列表的顺序应与任务定义中的一致,这里的a,b,c分别对应任务定义中的a,b,out */2'b01: c=a|b; //或2'b10: c=a-b; //相减2'b11: c=a+b; //相加endcaseendendmodule王金明:《Verilog HDL程序设计教程》- 13 -【例6.3】测试程序`include "alutask.v"module alu_tp;reg[3:0] a,b;reg[1:0] code;wire[4:0] c;parameter DELY = 100;alutask ADD(code,a,b,c); //调用被测试模块initial begincode=4'd0; a= 4'b0000; b= 4'b1111;#DELY code=4'd0; a= 4'b0111; b= 4'b1101;#DELY code=4'd1; a= 4'b0001; b= 4'b0011;#DELY code=4'd2; a= 4'b1001; b= 4'b0011;#DELY code=4'd3; a= 4'b0011; b= 4'b0001;#DELY code=4'd3; a= 4'b0111; b= 4'b1001;#DELY $finish;endinitial $monitor($time,,,"code=%b a=%b b=%b c=%b", code,a,b,c);endmodule【例6.4】函数function[7:0] get0;input[7:0] x;reg[7:0] count;integer i;begincount=0;for (i=0;i<=7;i=i+1)if (x[i]=1'b0) count=count+1;get0=count;endfunction【例6.5】用函数和case语句描述的编码器(不含优先顺序)module code_83(din,dout);input[7:0] din;output[2:0] dout;程序文本- 14 -function[2:0] code; //函数定义input[7:0] din; //函数只有输入,输出为函数名本身casex (din)8'b1xxx_xxxx : code = 3'h7;8'b01xx_xxxx : code = 3'h6;8'b001x_xxxx : code = 3'h5;8'b0001_xxxx : code = 3'h4;8'b0000_1xxx : code = 3'h3;8'b0000_01xx : code = 3'h2;8'b0000_001x : code = 3'h1;8'b0000_000x : code = 3'h0;default: code = 3'hx;endcaseendfunctionassign dout = code(din) ; //函数调用endmodule【例6.6】阶乘运算函数module funct(clk,n,result,reset);output[31:0] result;input[3:0] n;input reset,clk;reg[31:0] result;always @(posedge clk) //在clk的上升沿时执行运算beginif(!reset) result<=0; //复位else beginresult <= 2 * factorial(n); //调用factorial函数endendfunction[31:0] factorial; //阶乘运算函数定义(注意无端口列表)input[3:0] opa; //函数只能定义输入端,输出端口为函数名本身reg[3:0] i;factorial = opa ? 1 : 0;for(i= 2; i <= opa; i = i+1) //该句若要综合通过,opa应赋具体的数值factorial = i* factorial; //阶乘运算end 王金明:《Verilog HDL程序设计教程》- 15 -endfunctionendmodule【例6.7】测试程序`define clk_cycle 50`include "funct.v"module funct_tp;reg[3:0] n;reg reset,clk;wire[31:0] result;initial //定义激励向量beginn=0; reset=1; clk=0;for(n=0;n<=15;n=n+1)#100 n=n;endinitial $monitor($time,,,"n=%d result=%d",n,result);//定义输出显示格式always # `clk_cycle clk=~clk; //产生时钟信号funct funct_try(.clk(clk),.n(n),.result(result),.reset(reset));//调用被测试模块endmodule【例6.8】顺序执行模块1module serial1(q,a,clk);output q,a;input clk;reg q,a;always @(posedge clk)beginq=~q;a=~q;endendmodule【例6.9】顺序执行模块2module serial2(q,a,clk);output q,a; 程序文本- 16 -input clk;reg q,a;always @(posedge clk)begina=~q;q=~q;endendmodule【例6.10】并行执行模块1module paral1(q,a,clk);output q,a;input clk;reg q,a;always @(posedge clk)beginq=~q;endalways @(posedge clk)begina=~q;endendmodule【例6.11】并行执行模块2module paral2(q,a,clk);output q,a;input clk;reg q,a;always @(posedge clk)begina=~q;endalways @(posedge clk)beginq=~q;endendmodule【例7.1】调用门元件实现的 4 选1 MUX 王金明:《Verilog HDL程序设计教程》- 17 -module mux4_1a(out,in1,in2,in3,in4,cntrl1,cntrl2); output out;input in1,in2,in3,in4,cntrl1,cntrl2;wire notcntrl1,notcntrl2,w,x,y,z;not (notcntrl1,cntrl2),(notcntrl2,cntrl2);and (w,in1,notcntrl1,notcntrl2),(x,in2,notcntrl1,cntrl2),(y,in3,cntrl1,notcntrl2),(z,in4,cntrl1,cntrl2);or (out,w,x,y,z);endmodule【例7.2】用case语句描述的 4 选1 MUX module mux4_1b(out,in1,in2,in3,in4,cntrl1,cntrl2); output out;input in1,in2,in3,in4,cntrl1,cntrl2;reg out;always@(in1 or in2 or in3 or in4 or cntrl1 or cntrl2) case({cntrl1,cntrl2})2'b00:out=in1;2'b01:out=in2;2'b10:out=in3;2'b11:out=in4;default:out=2'bx;endcaseendmodule【例7.3】行为描述方式实现的4 位计数器module count4(clk,clr,out);input clk,clr;output[3:0] out;reg[3:0] out;always @(posedge clk or posedge clr)beginif (clr) out<=0;else out<=out+1;endendmodule程序文本- 18 -【例7.4】数据流方式描述的 4 选1 MUX module mux4_1c(out,in1,in2,in3,in4,cntrl1,cntrl2); output out;input in1,in2,in3,in4,cntrl1,cntrl2;assign out=(in1 & ~cntrl1 & ~cntrl2)|(in2 & ~cntrl1 & cntrl2)| (in3 & cntrl1 & ~cntrl2)|(in4 & cntrl1 & cntrl2); endmodule【例7.5】用条件运算符描述的4 选 1 MUXmodule mux4_1d(out,in1,in2,in3,in4,cntrl1,cntrl2);output out;input in1,in2,in3,in4,cntrl1,cntrl2;assign out=cntrl1 ? (cntrl2 ? in4:in3):(cntrl2 ? in2:in1); endmodule【例7.6】门级结构描述的 2 选1MUXmodule mux2_1a(out,a,b,sel);output out;input a,b,sel;not (sel_,sel);and (a1,a,sel_),(a2,b,sel);or (out,a1,a2);endmodule【例7.7】行为描述的 2 选1MUXmodule mux2_1b(out,a,b,sel);output out;input a,b,sel;reg out;always @(a or b or sel)beginif(sel) out = b;else out = a;endendmodule【例7.8】数据流描述的2 选1MUXmodule MUX2_1c(out,a,b,sel);output out; 王金明:《Verilog HDL程序设计教程》- 19 -input a,b,sel;assign out = sel ? b : a;endmodule【例7.9】调用门元件实现的 1 位半加器module half_add1(a,b,sum,cout);input a,b;output sum,cout;and (cout,a,b);xor (sum,a,b);endmodule【例7.10】数据流方式描述的 1 位半加器module half_add2(a,b,sum,cout);input a,b;output sum,cout;assign sum=a^b;assign cout=a&b;endmodule【例7.11】采用行为描述的 1 位半加器module half_add3(a,b,sum,cout);input a,b;output sum,cout;reg sum,cout;always @(a or b)begincase ({a,b}) //真值表描述2'b00: begin sum=0; cout=0; end2'b01: begin sum=1; cout=0; end2'b10: begin sum=1; cout=0; end2'b11: begin sum=0; cout=1; endendcaseendendmodule【例7.12】采用行为描述的 1 位半加器module half_add4(a,b,sum,cout);input a,b;output sum,cout; 程序文本- 20 -reg sum,cout;always @(a or b)beginsum= a^b;cout=a&b;endendmodule【例7.13】调用门元件实现的 1 位全加器module full_add1(a,b,cin,sum,cout);input a,b,cin;output sum,cout;wire s1,m1,m2,m3;and (m1,a,b),(m2,b,cin),(m3,a,cin);xor (s1,a,b),(sum,s1,cin);or (cout,m1,m2,m3);endmodule【例7.14】数据流描述的1 位全加器module full_add2(a,b,cin,sum,cout);input a,b,cin;output sum,cout;assign sum = a ^ b ^ cin;assign cout = (a & b)|(b & cin)|(cin & a);endmodule【例7.15】1 位全加器module full_add3(a,b,cin,sum,cout);input a,b,cin;output sum,cout;assign {cout,sum}=a+b+cin;endmodule【例7.16】行为描述的1 位全加器module full_add4(a,b,cin,sum,cout);input a,b,cin;output sum,cout; 王金明:《Verilog HDL程序设计教程》- 21 -reg sum,cout; //在always块中被赋值的变量应定义为reg型reg m1,m2,m3;always @(a or b or cin)beginsum = (a ^ b) ^ cin;m1 = a & b;m2 = b & cin;m3 = a & cin;cout = (m1|m2)|m3;endendmodule【例7.17】混合描述的1 位全加器module full_add5(a,b,cin,sum,cout);input a,b,cin;output sum,cout;reg cout,m1,m2,m3; //在always块中被赋值的变量应定义为reg型wire s1;xor x1(s1,a,b); //调用门元件always @(a or b or cin) //always块语句beginm1 = a & b;m2 = b & cin;m3 = a & cin;cout = (m1| m2) | m3;endassign sum = s1 ^ cin; //assign持续赋值语句endmodule【例7.18】结构描述的4 位级连全加器`include "full_add1.v"module add4_1(sum,cout,a,b,cin);output[3:0] sum;output cout;input[3:0] a,b;input cin;full_add1 f0(a[0],b[0],cin,sum[0],cin1); //级连描述full_add1 f1(a[1],b[1],cin1,sum[1],cin2);full_add1 f2(a[2],b[2],cin2,sum[2],cin3); 程序文本- 22 -full_add1 f3(a[3],b[3],cin3,sum[3],cout);endmodule【例7.19】数据流描述的4 位全加器module add4_2(cout,sum,a,b,cin);output[3:0] sum;output cout;input[3:0] a,b;input cin;assign {cout,sum}=a+b+cin;endmodule【例7.20】行为描述的4 位全加器module add4_3(cout,sum,a,b,cin);output[3:0] sum;output cout;input[3:0] a,b;input cin;reg[3:0] sum;reg cout;always @(a or b or cin)begin{cout,sum}=a+b+cin;endendmodule【例8.1】$time 与$real time 的区别`timescale 10ns/1nsmodule time_dif;reg ts;parameter delay=2.6;initialbegin#delay ts=1;#delay ts=0;#delay ts=1;#delay ts=0;endinitial $monitor($time,,,"ts=%b",ts); //使用函数$time 王金明:《Verilog HDL程序设计教程》- 23 -endmodule【例8.2】$random 函数的使用`timescale 10ns/1nsmodule random_tp;integer data;integer i;parameter delay=10;initial $monitor($time,,,"data=%b",data);initial beginfor(i=0; i<=100; i=i+1)#delay data=$random; //每次产生一个随机数endendmodule【例8.3】1 位全加器进位输出UDP 元件primitive carry_udp(cout,cin,a,b);input cin,a,b;output cout;table//cin a b : cout //真值表0 0 0 : 0;0 1 0 : 0;0 0 1 : 0;0 1 1 : 1;1 0 0 : 0;1 0 1 : 1;1 1 0 : 1;1 1 1 : 1;endtableendprimitive【例8.4】包含x 态输入的1 位全加器进位输出UDP 元件primitive carry_udpx1(cout,cin,a,b);input cin,a,b;output cout;table// cin a b : cout //真值表0 0 0 : 0; 程序文本- 24 -0 1 0 : 0;0 0 1 : 0;0 1 1 : 1;1 0 0 : 0;1 0 1 : 1;1 1 0 : 1;1 1 1 : 1;0 0 x : 0; //只要有两个输入为0,则进位输出肯定为0 0 x 0 : 0;x 0 0 : 0;1 1 x : 1; //只要有两个输入为1,则进位输出肯定为1 1 x 1 : 1;x 1 1 : 1;endtableendprimitive【例8.5】用简缩符“?”表述的1 位全加器进位输出UDP 元件primitive carry_udpx2(cout,cin,a,b);input cin,a,b;output cout;table// cin a b : cout //真值表? 0 0 : 0; //只要有两个输入为0,则进位输出肯定为00 ? 0 : 0;0 0 ? : 0;? 1 1 : 1; //只要有两个输入为1,则进位输出肯定为11 ? 1 : 1;1 1 ? : 1;endtableendprimitive【例8.6】3 选1 多路选择器UDP 元件primitive mux31(Y,in0,in1,in2,s2,s1);input in0,in1,in2,s2,s1;output Y;table//in0 in1 in2 s2 s1 : Y0 ? ? 0 0 : 0; //当s2s1=00时,Y=in01 ? ? 0 0 : 1;? 0 ? 0 1 : 0; //当s2s1=01时,Y=in1 王金明:《Verilog HDL程序设计教程》- 25 -? 1 ? 0 1 : 1;? ? 0 1 ? : 0; //当s2s1=1?时,Y=in2? ? 1 1 ? : 1;0 0 ? 0 ? : 0;1 1 ? 0 ? : 1;0 ? 0 ? 0 : 0;1 ? 1 ? 0 : 1;? 0 0 ? 1 : 0;? 1 1 ? 1 : 1;endtableendprimitive【例8.7】电平敏感的 1 位数据锁存器UDP 元件primitive latch(Q,clk,reset,D);input clk,reset,D;output Q;reg Q;initial Q = 1'b1; //初始化table// clk reset D : state : Q? 1 ? : ? : 0 ; //reset=1,则不管其他端口为什么值,输出都为00 0 0 : ? : 0 ; //clk=0,锁存器把D端的输入值输出0 0 1 : ? : 1 ;1 0 ? : ? : - ; //clk=1,锁存器的输出保持原值,用符号“-”表示endtableendprimitive【例8.8】上升沿触发的D 触发器UDP 元件primitive DFF(Q,D,clk);output Q;input D,clk;reg Q;table//clk D : state : Q(01) 0 : ? : 0; //上升沿到来,输出Q=D(01) 1 : ? : 1;(0x) 1 : 1 : 1;(0x) 0 : 0 : 0;(?0) ? : ? : -; //没有上升沿到来,输出Q保持原值? (??) : ? : - ; //时钟不变,输出也不变程序文本- 26 -endtableendprimitive【例8.9】带异步置1 和异步清零的上升沿触发的D 触发器UDP 元件primitive DFF_UDP(Q,D,clk,clr,set);output Q;input D,clk,clr,set;reg Q;table// clk D clr set : state : Q(01) 1 0 0 : ? : 0;(01) 1 0 x : ? : 0;? ? 0 x : 0 : 0;(01) 0 0 0 : ? : 1;(01) 0 x 0 : ? : 1;? ? x 0 : 1 : 1;(x1) 1 0 0 : 0 : 0;(x1) 0 0 0 : 1 : 1;(0x) 1 0 0 : 0 : 0;(0x) 0 0 0 : 1 : 1;? ? 1 ? : ? : 1; //异步复位? ? 0 1 : ? : 0; //异步置1n ? 0 0 : ? : -;? * ? ? : ? : -;? ? (?0) ? : ? : -;? ? ? (?0): ? : -;? ? ? ? : ? : x;endtableendprimitive【例8.12】延迟定义块举例module delay(out,a,b,c);output out;input a,b,c;and a1(n1,a,b);or o1(out,c,n1);specify(a=>out)=2;(b=>out)=3;(c=>out)=1; 王金明:《Verilog HDL程序设计教程》- 27 -endspecifyendmodule【例8.13】激励波形的描述'timescale 1ns/1nsmodule test1;reg A,B,C;initialbegin //激励波形描述A = 0;B = 1;C = 0;#100 C = 1;#100 A = 1; B = 0;#100 A = 0;#100 C = 0;#100 $finish;endinitial $monitor($time,,,"A=%d B=%d C=%d",A,B,C); //显示endmodule【例8.15】用always 过程块产生两个时钟信号module test2;reg clk1,clk2;parameter CYCLE = 100;alwaysbegin{clk1,clk2} = 2'b10;#(CYCLE/4) {clk1,clk2} = 2'b01;#(CYCLE/4) {clk1,clk2} = 2'b11;#(CYCLE/4) {clk1,clk2} = 2'b00;#(CYCLE/4) {clk1,clk2} = 2'b10;endinitial $monitor($time,,,"clk1=%b clk2=%b",clk1,clk2); endmodule【例8.17】存储器在仿真程序中的应用module ROM(addr,data,oe);output[7:0] data; //数据信号input[14:0] addr; //地址信号input oe; //读使能信号,低电平有效程序文本- 28 -reg[7:0] mem[0:255]; //存储器定义parameter DELAY = 100;assign #DELAY data=(oe==0) ? mem[addr] : 8'hzz;initial $readmemh("rom.hex",mem); //从文件中读入数据endmodule【例8.18】8 位乘法器的仿真程序`timescale 10ns/1nsmodule mult_tp; //测试模块的名字reg[7:0] a,b; //测试输入信号定义为reg型wire [15:0] out; //测试输出信号定义为wire型integer i,j;mult8 m1(out,a,b); //调用测试对象//激励波形设定initialbegina=0;b=0;for(i=1;i<255;i=i+1)#10 a=i;endinitialbeginfor(j=1;j<255;j=j+1)#10 b=j;endinitial //定义结果显示格式begin$monitor($time,,,"%d * %d= %d",a,b,out);#2560 $finish;endendmodulemodule mult8(out, a, b); //8位乘法器源代码parameter size=8;input[size:1] a,b; //两个操作数output[2*size:1] out; //结果assign out=a*b; //乘法运算符王金明:《Verilog HDL程序设计教程》- 29 -endmodule【例8.19】8 位加法器的仿真程序`timescale 1ns/1nsmodule add8_tp; //仿真模块无端口列表reg[7:0] A,B; //输入激励信号定义为reg型reg cin;wire[7:0] SUM; //输出信号定义为wire型wire cout;parameter DELY = 100;add8 AD1(SUM,cout,A,B,cin); //调用测试对象initial begin //激励波形设定A= 8'd0; B= 8'd0; cin=1'b0;#DELY A= 8'd100; B= 8'd200; cin=1'b1;#DELY A= 8'd200; B= 8'd88;#DELY A= 8'd210; B= 8'd18; cin=1'b0;#DELY A= 8'd12; B= 8'd12;#DELY A= 8'd100; B= 8'd154;#DELY A= 8'd255; B= 8'd255; cin=1'b1;#DELY $finish;end//输出格式定义initial $monitor($time,,,"%d + %d + %b = {%b, %d}",A,B,cin,cout,SUM);endmodulemodule add8(SUM,cout,A,B,cin); //待测试的8位加法器模块output[7:0] SUM;output cout;input[7:0] A,B;input cin;assign {cout,SUM}=A+B+cin;endmodule【例8.20】2 选 1 多路选择器的仿真`timescale 1ns/1nsmodule mux_tp;reg a,b,sel;wire out; 程序文本- 30 -MUX2_1 m1(out,a,b,sel); //调用待测试模块initialbegina=1'b0; b=1'b0; sel=1'b0;#5 sel=1'b1;#5 a=1'b1; sel=1'b0;#5 sel=1'b1;#5 a=1'b0; b=1'b1; sel=1'b0;#5 sel=1'b1;#5 a=1'b1; b=1'b1; sel=1'b0;#5 sel=1'b1;endinitial $monitor($time,,,"a=%b b=%b sel=%b out=%b",a,b,sel,out); endmodulemodule MUX2_1(out,a,b,sel); //待测试的2选1MUX模块input a,b,sel;output out;not #(0.4,0.3) (sel_,sel); //#(0.4,0.3)为门延时and #(0.7,0.6) (a1,a,sel_);and #(0.7,0.6) (a2,b,sel);or #(0.7,0.6) (out,a1,a2);endmodule【例8.21】8 位计数器的仿真`timescale 10ns/1nsmodule count8_tp;reg clk,reset; //输入激励信号定义为reg型wire[7:0] qout; //输出信号定义为wire型parameter DELY=100;counter C1(qout,reset,clk); //调用测试对象always #(DEL Y/2) clk = ~clk; //产生时钟波形initialbegin //激励波形定义clk =0; reset=0; 王金明:《Verilog HDL程序设计教程》- 31 -#DEL Y reset=1;#DELY reset=0;#(DELY*300) $finish;end//结果显示initial $monitor($time,,,"clk=%d reset=%d qout=%d",clk,reset,qout); endmodulemodule counter(qout,reset,clk); //待测试的8位计数器模块output[7:0] qout;input clk,reset;reg[7:0] qout;always @(posedge clk)begin if (reset) qout<=0;else qout<=qout+1;endendmodule【例9.1】基本门电路的几种描述方法(1)门级结构描述module gate1(F,A,B,C,D);input A,B,C,D;output F;nand(F1,A,B); //调用门元件and(F2,B,C,D);or(F,F1,F2);endmodule(2)数据流描述module gate2(F,A,B,C,D);input A,B,C,D;output F;assign F=(A&B)|(B&C&D); //assign持续赋值endmodule(3)行为描述module gate3(F,A,B,C,D);input A,B,C,D;output F; 程序文本- 32 -reg F;always @(A or B or C or D) //过程赋值beginF=(A&B)|(B&C&D);endendmodule【例9.2】用bufif1 关键字描述的三态门module tri_1(in,en,out);input in,en;output out;tri out;bufif1 b1(out,in,en); //注意三态门端口的排列顺序endmodule【例9.3】用assign 语句描述的三态门module tri_2(out,in,en);output out;input in,en;assign out = en ? in : 'bz;//若en=1,则out=in;若en=0,则out为高阻态endmodule【例9.4】三态双向驱动器module bidir(tri_inout,out,in,en,b);inout tri_inout;output out;input in,en,b;assign tri_inout = en ? in : 'bz;assign out = tri_inout ^ b;endmodule【例9.5】三态双向驱动器module bidir2(bidir,en,clk);inout[7:0] bidir;input en,clk;reg[7:0] temp;assign bidir= en ? temp : 8'bz;always @(posedge clk)begin 王金明:《Verilog HDL程序设计教程》- 33 -if(en) temp=bidir;else temp=temp+1;endendmodule【例9.6】3-8 译码器module decoder_38(out,in);output[7:0] out;input[2:0] in;reg[7:0] out;always @(in)begincase(in)3'd0: out=8'b11111110;3'd1: out=8'b11111101;3'd2: out=8'b11111011;3'd3: out=8'b11110111;3'd4: out=8'b11101111;3'd5: out=8'b11011111;3'd6: out=8'b10111111;3'd7: out=8'b01111111;endcaseendendmodule【例9.7】8-3 优先编码器module encoder8_3(none_on,outcode,a,b,c,d,e,f,g,h); output none_on;output[2:0] outcode;input a,b,c,d,e,f,g,h;reg[3:0] outtemp;assign {none_on,outcode}=outtemp;always @(a or b or c or d or e or f or g or h)beginif(h) outtemp=4'b0111;else if(g) outtemp=4'b0110;else if(f) outtemp=4'b0101;else if(e) outtemp=4'b0100;else if(d) outtemp=4'b0011;else if(c) outtemp=4'b0010; 程序文本- 34 -else if(b) outtemp=4'b0001;else if(a) outtemp=4'b0000;else outtemp=4'b1000;endendmodule【例9.8】用函数定义的8-3 优先编码器module code_83(din, dout);input[7:0] din;output[2:0] dout;function[2:0] code; //函数定义input[7:0] din; //函数只有输入端口,输出为函数名本身if (din[7]) code = 3'd7;else if (din[6]) code = 3'd6;else if (din[5]) code = 3'd5;else if (din[4]) code = 3'd4;else if (din[3]) code = 3'd3;else if (din[2]) code = 3'd2;else if (din[1]) code = 3'd1;else code = 3'd0;endfunctionassign dout = code(din); //函数调用endmodule【例9.9】七段数码管译码器module decode47(a,b,c,d,e,f,g,D3,D2,D1,D0);output a,b,c,d,e,f,g;input D3,D2,D1,D0; //输入的4位BCD码reg a,b,c,d,e,f,g;always @(D3 or D2 or D1 or D0)begincase({D3,D2,D1,D0}) //用case语句进行译码4'd0: {a,b,c,d,e,f,g}=7'b1111110;4'd1: {a,b,c,d,e,f,g}=7'b0110000;4'd2: {a,b,c,d,e,f,g}=7'b1101101;4'd3: {a,b,c,d,e,f,g}=7'b1111001;4'd4: {a,b,c,d,e,f,g}=7'b0110011;4'd5: {a,b,c,d,e,f,g}=7'b1011011; 王金明:《Verilog HDL程序设计教程》- 35 -4'd6: {a,b,c,d,e,f,g}=7'b1011111;4'd7: {a,b,c,d,e,f,g}=7'b1110000;4'd8: {a,b,c,d,e,f,g}=7'b1111111;4'd9: {a,b,c,d,e,f,g}=7'b1111011;default: {a,b,c,d,e,f,g}=7'bx;endcaseendendmodule【例9.10】奇偶校验位产生器module parity(even_bit,odd_bit,input_bus);output even_bit,odd_bit;。
第四章例题例:if(A==1’bx) $display(“AisX”); (当A等于X时,这个语句不执行)if(A===1’bx) $display(“AisX”); (当A等于X时,这个语句执行)例:module shift;reg [3:0] start, result;initialbeginstart = 1; //start在初始时刻设为值0001result = (start<<2);//移位后,start的值0100,然后赋给result。
endendmodule例:4’b1001<<1 = 5’b10010; 4’b1001<<2 = 6’b100100;1<<6 = 32’b1000000; 4’b1001>>1 = 4’b0100;4’b1001>>4 = 4’b0000;例:reg [3:0] B;reg C;C = &B;//相当于:C =( (B[0]&B[1]) & B[2] ) & B[3];由于缩减运算的与、或运算规则类似于位运算符与、或运算规则,这里不再详细讲述,请参照位运算符的运算规则介绍。
[例1]:always @( posedge clk )beginb<=a;c<=b;end[例2]:always @(posedge clk)beginb=a;c=b;end[例1]:beginareg = breg;creg = areg; //creg的值为breg的值。
end/* 从该例可以看出,第一条赋值语句先执行,areg的值更新为breg的值,然后程序流程控制转到第二条赋值语句,creg的值更新为areg的值。
因为这两条赋值语句之间没有任何延迟时间,creg的值实为breg的值。
当然可以在顺序块里延迟控制时间来分开两个赋值语句的执行时间,见[例2]:*/[例2]:beginareg = breg;#10 creg = areg;//在两条赋值语句间延迟10个时间单位。
第五章例题例如:if(a>b)out1 = int1;elseout1 = int2;例如:always @( some_event) //虚的字体表示块语句beginif(a>b) out1 = int1;else if (a==b) out1 = int2;else out1 = int3;endif(a>b)beginout1<=int1;out2<=int2;endelsebeginout1<=int2;out2<=int1;end//有时begin_end块语句的不慎使用会改变逻辑行为。
见下例:if(index>0)for(scani=0;scani<index;scani=scani+1)if(memory[scani]>0)begin$display("...");memory[scani]=0;endelse /*WRONG*/$display("error-indexiszero");尽管程序设计者把else写在与第一个if(外层if)同一列上,希望与第一个if对应,但实际上else是与第二个if对应,因为它们相距最近。
正确的写法应当是这样的:if(index>0)beginfor(scani=0;scani<index;scani=scani+1)if(memory[scani]>0)begin$display("...");memory[scani]=0;endendelse /*WRONG*/$display("error-indexiszero");//定义寄存器和参数。
reg [31:0] instruction, segment_area[255:0];reg [7:0] index;reg [5:0] modify_seg1, modify_seg2, modify_seg3; parametersegment1=0, inc_seg1=1,segment2=20, inc_seg2=2,segment3=64, inc_seg3=4,data=128;//检测寄存器index的值if(index<segment2)begininstruction = segment_area[index + modify_seg1];index = index + inc_seg1;endelse if(index<segment3)begininstruction = segment_area[index + modify_seg2];index = index + inc_seg2;endelse if (index<data)begininstruction = segment_area[index + modify_seg3];index = index + inc_seg3;endelseinstruction = segment_area[index];reg [15:0] rega;reg [9:0] result;case(rega)16 'd0: result = 10 'b0111111111;16 'd1: result = 10 'b1011111111;16 'd2: result = 10 'b1101111111;16 'd3: result = 10 'b1110111111;16 'd4: result = 10 'b1111011111;16 'd5: result = 10 'b1111101111;16 'd6: result = 10 'b1111110111;16 'd7: result = 10 'b1111111011;16 'd8: result = 10 'b1111111101;16 'd9: result = 10 'b1111111110;default: result =10 'bx;endcase[例1]:case ( select[1:2] )2 'b00: result = 0;2 'b01: result = flaga;2 'b0x,2 'b0z: result = flaga? 'bx : 0;2 'b10: result = flagb;2 'bx0,2 'bz0: result = flagb? 'bx : 0;default: result = 'bx;endcase[例2]:case(sig)1 'bz: $display("signal is floating");1 'bx: $display("signal is unknown");default: $display("signal is %b", sig);endcase[例3]: reg[7:0] ir;casez(ir)8 'b1???????: instruction1(ir);8 'b01??????: instruction2(ir);8 'b00010???: instruction3(ir);8 'b000001??: instruction4(ir);endcase[例4]: reg[7:0] r, mask;mask = 8'bx0x0x0x0;casex(r^mask)8 'b001100xx: stat1;8 'b1100xx00: stat2;8 'b00xx0011: stat3;8 'bxx001100: stat4;endcase例:always @ (al or d ) // 有锁存器beginif ( al ) q = d;endalways @ (al or d ) // 无锁存器beginif ( al ) q = d;else q = 0;end[例5]:条件语句举例//第一类条件语句if ( !lock ) buffer = data ;if ( enable ) out = in ;//第二类条件语句if (number_queued < MAX_Q_DEPTH)begindata_queue = data ;number_queued = number_queued + 1 ;endelse$display ( " Queue Full. Try again " ) ;//第三类条件语句//根据不同的算术逻辑单元的控制信号alu_control 执行不同的算术运算操作if ( alu_control = = 0 )y = x + z ;else if ( alu_control = = 1 )y = x - z ;else if ( alu_control = = 2 )y = x * z ;else$ display ( " Invalid ALU control signal ");reg [ 1: 0] alu_control ;......case (alu_control)2 'd 0 : y = x + z ;2 'd 1 : y = x - z ;2 'd 2 : y = x * z ;default : $display ( "Invalid ALU control signal ") ;endcase[例6]:使用case语句实现四选一多路选择器module mux4_to_1 (out, i0, i1, i2, i3, s1, s0);// 根据输入/输出图的端口声明output out;input i0, i1, i2, i3;input s1, s0;//把输出变量声明为寄存器类型reg out;//任何输入信号改变,都会引起输出信号的重新计算//使输出out 重新计算的所有输入信号必须写入always @(...)的变量列表中always @(s1 or s0 or i0 or i1 or i2 or i3)begincase ({s1, s0})2'b00: out = i0;2'b01: out = i1;2'b10: out = i2;2'b11: out = i3;default: out = 1'bx;endcaseendendmoduleparameter size=8,longsize=16;reg [size:1] opa, opb;reg [longsize:1] result;begin: multreg [longsize:1] shift_opa, shift_opb;shift_opa = opa;shift_opb = opb;result = 0;repeat(size)beginif(shift_opb[1])result = result + shift_opa;shift_opa = shift_opa <<1;shift_opb = shift_opb >>1;endendbegin: count1sreg[7:0] tempreg;count=0;tempreg = rega;while(tempreg)beginif(tempreg[0]) count = count + 1;tempreg = tempreg>>1;endend[例7]:begin: init_memreg[7:0] tempi;for(tempi=0;tempi<memsize;tempi=tempi+1)memory[tempi]=0;end[例8]:parameter size = 8, longsize = 16;reg[size:1] opa, opb;reg[longsize:1] result;begin:multinteger bindex;result=0;for( bindex=1; bindex<=size; bindex=bindex+1 )if(opb[bindex])result = result + (opa<<(bindex-1));end/*在for语句中,循环变量增值表达式可以不必是一般的常规加法或减法表达式。
EDA课程设计多功能数字钟设计程序清单数字系统设计与verilog HDL(第四版)王金明/*引脚锁定基于DE2一70,芯片为EP2C70F896,信号定义如下: Clk50m: 50MHz 时钟输,mode:模式选择0:计时模式1:设置闹钟模式mcheck:手动调整时间turn:手动调整时间,在时、分之间选择change:对选中的数据调整led hourl,led_hour0,led_minul,led_minu0,led_secl,led sec0;alert: 闹钟输出ld_alert: 是否设置了闹钟ld_hour,id_min,ld_sec:在调整时,指示选中了时,分还是秒*/moduleclock(clk50m,mode,turn,change,mreset,led_hour1,led_hour0,led_minu1,led_minu0, led_sec1,led_sec0, alert,ld_alert,ld_check,ld_hour,ld_min,ld_sec);input clk50m;input mode; // key0键input turn; //keyl键input change; // key2 键input mreset; //switch0复位,低电平有效output alert; //gpioO->IOAOoutput ld_alert; //ledgO-led19output ld_check; //ledgl-led22output ld_hour; //ledr3-led13output ld_min; //ledr9-led9output ld_sec; //ledr7-led7output[6:0] led_hour1;output[6:0] led_hour0;output[6:0] led_minu1;output[6:0] led_minu0;output[6:0]led_sec1;output[6:0]led_sec0;reg [1:0] modestate;//00: 计时模式10:闹钟模式; 01:手动调整模式;11:非法模式wire nowmode;//记录当前模式,0:计时模式;1: 设置闹钟模式wire ischecking; //是否在手动调整时间assign {nowmode, ischecking}=modestate;always@(negedge mode)//两个按钮都是低电平有效begincase (modestate)2'b00 : modestate<=2'b10; //设置闹钟模式优先2'b10: modestate<=2'b01; //手动调整模式2'b01: modestate<=2'b00;default :modestate<=2'b00;endcaseendwire reset, clk_1hz;switch #(8) rmjitter(clk50m,mresetr,reset);clk50mtol genlhz (clk50m, clk_1hz) ; //生成1Hz的时钟wire [2 : 0] selcode; //对turn信号在不同模式bitsel seldecoder (nowmode, ischecking, turn, selcode, reset);wire [3:0] clocktime0,clocktimel,clocktime2,clocktime3,clocktime4,clockthre5;//计时输出的时钟数值wire clockalarmon; //整点报时的闹钟输出wire [2 : 0] counterselcode;assign counterselcode=(modestate==2'b01)?selcode:3'b000;counter_time clock_time (clk_1hz,counterselcode,~change,clocktime5,clocktime4,clocktime3,clocktime2,clock time1,clocktime0,clockalarmon,reset);wire[3:0] alarmtime0,alarmtime1,alarmtime2,alarmtime3;wire alarmon;alarm_time alarm_time ( clk_1hz , nowmode , selcode [ 2 : 1] , change ,{clocktime5, clocktime4, clocktime3, clocktime2, clocktime1},{alarmtime3, alarmtime2, alarmtime1, alarmtime0} , alarmon, reset) ;wire voiceout ;alarm alarmvoice (clk50m,{clockalarmon, alarmon} ,voiceout, raset) ;//显示输出部分assign {ld_hour,ld_min,ld_sec}=(ischecking||nowmode)?selcode:3'b000; assign alert=voiceout;reg[3:0] showout2,showout3,showout4,showout5;led led5 (showout5,led_hour1) ; //led译码显示led led4 (showout4,led_hour0) ;led led3 (showout3,led_minu1) ;led led2 (showout2,led_minu0) ;led led1 (clocktime1,led_sec1) ;led led0 (clocktime0,led_sec0) ;alwaysbegin if ( nowmode)begin showout5=alarmtime3 ; showout4=alarmtime2 ;showout3=alarmtime1; showout2=alarmtime0 ; end else beginshowout5=clocktime5; showout4=clocktime4 ;showout3=clocktime3 ; showout2=clocktime2 ; end endassign ld_alert=nowmode; assign ld_check=ischecking;endmodule/*alarm.V:闹铃模块Clk50m: 50MHz输入时钟alarmon:闹铃是否打开,2'b00:不打开:2'b01:闹钟;2'b10:整点报时ala rmoUt:闹铃声音输出*/module alarm(clk50m,alarmon,alarmout,reset);input[1:0] alarmon;input clk50m,reset;output reg alarmout;reg[15:0] counter_1k;wire clk_1k;assign clk_1k=counter_1k[4];always@(posedge clk50m)begin if (counter_1k==20) counter_1k<=0;else counter_1k<=counter_1k+1'b1; endwire ddd_du_out,ddd_out;sound_ddd_du ddd_du (clk_1k,alarmon[1] ,ddd_du_out) ;sound_ddd ddd(clk_1k,alarmon[0],ddd_out);alwaysbegin if (!reset)begin if (alarmon [0]==1'b1) //ddd,闹钟的响铃优先级更高alarmout=ddd_out ;else if (alarmon==2'b10) alarmout=ddd_du_out;else alarmout=0 ;end else alarmout=0 ;endendmodule/*alarm_time.V:闹钟时间设定模块enable:使能信号Sel:在时、分之间切换选择10:时;01:分inc:对选中的信号自增basetime:基准时钟*/module alarm_time (clk_1hz , enable, sel, inc, basetime, alarmouttime, alarm_on, reset) ;input clk_1hz,enable, inc,reset;input[1:0] sel;input[4*5-1:0] basetime;output reg alarm_on;output [4*4-1: 0] alarmouttime;reg [ 3 : 0] hour1, hour0 , minu1, minu0 ; //存储的设定时间always@ (posedge inc or posedge reset)begin if (reset) //reset=1时复位begin { hour1, hour0,minu1, minu0 } <=16'h0 ; endelse beginif (enable) beginif (sel==2'b10) //设置时begin if({hour1,hour0}==8'h23) {hour1,hour0}<=8'h00;else if (hour0==9)begin hour0<=0;hour1<=hour1+1'b1; endelse hour0<=hour0+1'b1;endelse if(sel===2'b01)//设置分begin if({minu1,minu0}==8'h59) {minu1,minu0}<=8'h00;else if (minu0==4'h9)begin minu0<=4'h0;minu1<=minu1+4'h1;endelse minu0<=minu0+4'h1; endelse {hour1,hour0,minu1,minu0}<=16'h0;end endendalways //闹钟开始条件beginif(({hour1,hour0,minu1,minu0}==basetime[ (4*5-1) :4]) && (basetime[3:0]<2)) alarm_on=1'b1;else alarm_on=1'b0; endassign alarmouttime={ hour1,hour0,minu1,minu0};endmodule/*counter time,v:计时模块,并留有调整接;check:调整信号,3位,分别调整时、分、秒,调整方法:将计数输出给加法器,把调整信息转换成异步置数信息,将加法器的输出作为置数值;hour1,hour0,minul, minu0, sec1,sec0:输出的计时时钟;alarmout:整点报时输出*/modulecounter_time(clk_1hz,check,inc,hour1,hour0,minu1,minu0,sec1,sec0,alarmout,reset); input clk_1hz,inc,reset;input[2:0] check;output[3:0] hour1,hour0,minu1,minu0,sec1,sec0;output reg alarmout;reg clk_1hz_md;wire [6: 0] carryclk;reg[5:0] incplus;//自增脉冲wire [5 : 0] carry; //进位时钟wire [3 : 0] adderout0,adderout1,adderout2,adderout3,adderout4,adderout5;wire [3 : 0] timerout0,timerout1,timerout2,timerout3,timerout4,timerout5; hexcounter counter_sec0(carryclk[0],reset,4'd9,4'b0,timerout0,carry[0]); hexcounter counter_sec1(carryclk[1],reset,4'd5,4'b0,timerout1,carry[1]); hexcounter counter_minu0(carryclk[2],reset,4'd9,4'b0,timerout2,carry[2]); hexcounter counter_minu1(carryclk[3],reset,4'd5,4'b0,timerout3,carry[3]);wire [3:0] hour0max;assign hour0max=(timerout5==4'h2)?(4'h3) : (4'h9);hexcounter counter_hour0(carryclk[4],reset,hour0max,4'b0,timerout4,carry[4]); hexcounter counter_hour1(carryclk[5],reset,4'd2,4'b0,timerout5,carry[5]);//每个计时器的时钟,由前级进位和自堦脉冲相加得到assign carryclk[0]=(check==4'h0) ? clk_1hz_md:incplus[0];assign carryclk[1]=carry[0]|incplus[1];assign carryclk[2]=(check==4'h0) ? carry[1]:incplus[2];assign carryclk[3]=carry[2]|incplus[3];assign carryclk[4]=(check==4'h0) ? carry[3]:incplus[4];assign carryclk[5]=carry[4]|incplus[5];always //对异步置位信号进行解码begin case (check)3 'b001: begin clk_1hz_md=0;incplus={5 'b00000, inc} ;end3 'b010 : begin clk_1hz_md=0;incplus={3'b000,inc,2'b00};end3 'b100 : begin //在正常的调节状态中clk_1hz_md=0;incplus={1'b0, inc, 4'b000};enddefault:begin incplus=6'b000000;clk_1hz_md=clk_1hz ;endendcaseendalways begin if (((reset|check)==0)&&(timerout3==0) && (timerout2==0) && (timerout1<2)) alarmout=1;//时间小于20秒的时间内else alarmout=0;endassign hour1=timerout5;assign hour0=timerout4;assign minu1=timerout3;assign minu0=timerout2;assign sec1=timerout1;assign sec0=timerout0;endmodule/*Clk50mtol.v: 50mhz 时钟分频到lhz */module clk50mtol(clk50m,clk1hz);input clk50m;output clk1hz;reg [25:0]counter_1hz;//从50mhz 分频到lhz 的计数器assign clk1hz=counter_1hz[14];//assign clk1hz=counter_1hz[25];always@ (posedge clk50m)beginif(counter_1hz==20000) counter_1hz<=0;else counter_1hz<=counter_1hz+1'b1;endendmodule/*led.v:7段数码管(led)译码显示模块datain:4位,10进制数输入ledout:7位,数码管的7段*/module led(datain,ledout);parameter INWIDTH=4;parameter OUTWIDTH=7;input[INWIDTH-1: 0] datain;output [OUTWIDTH-1:0] ledout;reg[OUTWIDTH-1:0] dataout;assign ledout=dataout;always begincase (datain)0 : dataout<=7'b1000000;1 : dataout<=7'b1111001;2 : dataout<=7'b0100100;3 : dataout<=7'b0110000;4 : dataout<=7'b0011001;5 : dataout<=7'b0010010;6 : dataout<=7'b0000010;7 : dataout<=7'b1111000;8 : dataout<=7'b0000000;9 : dataout<=7'b0010000;default : dataout<=7'b1000000;endcaseendendmodule/*switch-v:对按键开关的消抖电路,采用一个频率较低的时钟,对输入进行采样,消除抖动*/module switch(clk,keyin,keyout);parameter COUNTWIDTH=8;input clk, keyin;output reg keyout;reg [COUNTWIDTH-1: 0] counter;wire clk_use; //频率较低的时钟assign clk_use=counter [COUNTWIDTH-1];always@ (posedge clk)counter<=counter+1'b1;always@ (posedge clk_use)keyout<=keyin;endmodule/*bitsel-v:将输出解码成对时、分、秒的选择(并且分闹钟设置模式还是计时模式)Alarmmode:是否是在设置闹钟模式checkmode:是否是在调整时间模式*/module bitsel(alarmmode, checkmode, sel, selcode, reset) ;input alarmmode, checkmode, sel, reset;output reg [2:0] selcode;reg [2:0] check_code ;reg [1:0] alarm_code ;always@ (negedge sel or posedge reset)begin if (reset) check_code<=3'b000; //reset=1 复位else begincase (check_code)3 'b000: check_code<=3 'b001;3 'b001: check_code<=3 'b010;3 'b010: check_code<=3 'b100;3 'b100: check_code<=3 'b001;default: check_code<=3 'b000;endcaseendendalways@ (negedge sel or posedge reset)begin if (reset) alarm_code<=2 'b00; //低电平复位else begincase (alarm_code)2'b00 : alarm_code<=2'b01;2 'b01 : alarm_code<=2 'b10 ;2 'b10 : alarm_code<=2 'b01;default : alarm_code<=2 'b00;endcaseendendalwaysbegin if (alarmmode^checkmode) //两个当中只有1个为1 begin if (checkmode) selcode=check_code;else selcode={alarm_code,1'b0}; endelse selcode=3 'b000 ;endendmodule/*adder.v:加法器*/module adder(in1, in2, out);parameter in1width=8;parameter in2width=8;parameter outwidth=8;input [in1width-1: 0] in1;input [in2width-1: 0] in2;output[outwidth-1: 0] out;assign out=in1+in2;endmodule/*excounter-v:16进制计数的一个计数器*/module hexcounter (clk, set, max, setdata, dataout, carryout) ; input clk,set;input[3:0] max,setdata;output carryout;output[3:0] dataout;reg[3:0] counter;reg carrybit;assign carryout=carrybit;assign dataout=counter;always@ (posedge clk or posedge set)begin if (set) //set是高电平有效begin counter<=setdata;carrybit<=0 ;endelse begin if( (counter==max)||(counter>max) )begin counter<=0 ;carrybit<=1;endelse begin counter<=counter+1'b1;carrybit<=0 ;endendendendmodule/*sound_ddd.V:发出嘀嘀嘀闹铃声模块*/module sound_ddd(clk_1k, on, out);parameter soundspace=30;parameter shotstopspace=20; //20ms,两个嘀声的时间距离parameter longstopspace=50;//50ms,连续三个嘀后的时间距离input clk_1k,on;output reg out;reg sound;always@ (posedge clk_1k)begin sound<=~sound; endreg[10:0] mscount;always@ (posedge clk_1k)begin if (mscount== (soundspace*3+shotstopspace*2+longstopspace-1) )mscount<=0;else mscount<=mscount+1'b1;endalways@ (negedge clk_1k)begin if (on)begin if ( (mscount>=0) && (mscount<soundspace) ) out<=sound;else if ( (mscount>=soundspace) && (mscount< (soundspace+shotstopspace) ) )out<=0;else if ( (mscount>= (soundspace+shotstopspace) ) && (mscount< (soundspace+shotstopspace) +soundspace) )out<=sound;else if ( (mscount>= (soundspace+shotstopspace) +soundspace) && (mscount< (soundspace+shotstopspace) *2) )out<=0;else if ( (mscount>= (soundspace+shotstopspace) *2)&&(mscount< ((soundspace+shotstopspace) *2+soundspace) ) )out<=sound;else out<=0;endelse out<=0 ;endendmodule/* sound ddd du,v:发出声音嘀嘀嘀一嘟声音模块*/module sound_ddd_du (clk_1k, on, out) ;parameter SOUNDSPACE=30;parameter shotstopspace=20;//20ms,两个嘀声的时间距离parameter longsoundspace=60; //嘟的长度input clk_1k, on;output reg out;reg sound_di, sound_du;always@ (posedge clk_1k) sound_di<=~sound_di;always@ (posedge sound_di) sound_du<=~sound_du;reg [ 11 : 0 ] mscount ;always@ (posedge clk_1k)begin if (on)begin if (mscount< (SOUNDSPACE+shotstopspace) *3+longsoundspace+10)mscount<=mscount+1'b1;endelse mscount<=0 ;endalways@ (negedge clk_1k)begin if (on)begin if ( (mscount>=0) && (mscount<SOUNDSPACE) ) out<=sound_di;else if ( (mscount>=SOUNDSPACE) && (mscount< (SOUNDSPACE+shotstopspace) ) )out<=0 ;else if ( (mscount>= (SOUNDSPACE+shotstopspace) ) && (mscount< (SOUNDSPACE+shotstopspace) +SOUNDSPACE) )out<=sound_di ;else if ( (mscount>= (SOUNDSPACE+shotstopspace) +SOUNDSPACE) && (mscount< (SOUNDSPACE+shotstopspace) *2) )out<=0;else if ( (mscount>= (SOUNDSPACE+shotstopspace) *2) && (mscount< ( (SOUNDSPACE+shotstopspace) *2+SOUNDSPACE) ) )out<=sound_di;else if ( (mscount>= (SOUNDSPACE+shotstopspace) *2+SOUNDSPACE) && (mscount< (SOUNDSPACE+shotstopspace) *3) )out<=0;else if ( (mscount>= (SOUNDSPACE+shotstopspace) *3) && (mscount< ( (SOUNDSPACE+shotstopspace) *3+longsoundspace) ) )out<=sound_du;else out<=0;endendendmodule。
数字系统设计与VerilogHDL第四版课程设计1. 概述数字系统设计与VerilogHDL第四版是数字系统设计方面的经典教材,本课程设计以此为指导,通过对数字系统的设计和VerilogHDL的学习,加深学生对数字系统的认知和理解,掌握一定的数字系统设计和VerilogHDL的编程能力。
2. 课程设计内容课程设计的主要内容是数字系统设计和VerilogHDL,其中包括以下几个方面:2.1 数字系统设计数字系统设计是计算机科学和电气工程领域中的核心课程,其原理、方法和技术在广泛的领域中得到了应用。
本次课程设计主要针对数字系统的设计理论进行研究和应用,包括数字系统的基本概念、数字系统的设计方法、数字系统的实现等。
2.2 VerilogHDLVerilogHDL是一种硬件描述语言,常用于数字电路的设计和验证。
本次课程设计的另一个重点是学习VerilogHDL的语法和规则,掌握VerilogHDL的基本编程能力,能够使用VerilogHDL设计并实现数字电路的各种功能。
2.3 课程设计任务针对课程设计的内容,我们将学生分为若干个小组,每个小组设计一个数字电路,并使用VerilogHDL对其进行描述和实现。
课程设计具体包括以下任务:•确定数字电路设计的主题和功能•设计数字电路的逻辑模型和信号流图•使用VerilogHDL实现数字电路的各个部分•对设计的数字电路进行仿真和测试•优化数字电路的性能和可靠性3. 课程设计评价本次课程设计的评价主要考虑以下几个方面:3.1 设计方案的创新性和实用性设计方案的创新性和实用性是评价设计方案的重要指标。
学生们要根据实际需求和现有技术,提出有价值的设计方案,并且能够实现。
3.2 VerilogHDL的使用情况VerilogHDL的使用情况是评价学生的编程能力的主要指标。
学生们需要掌握VerilogHDL的基本语法和规则,熟练地运用VerilogHDL进行编程实现。
3.3 数字电路的性能和可靠性数字电路的性能和可靠性是评价设计方案的另一个重要指标。
数字系统设计与verilog_HDL_王金明_第四版__EDA期末知识点复习(宁波工程学院电科版)1、采用硬件描述语言(HDL)进行电路设计的优势。
1)更适合用于描述规模大、功能复杂的数字系统2)语言标准化、便于设计的复用、交流、保存和修改3)设计与工艺的无关性,宽范围的描述能力,便于组织大规模、模块化的设计2、Verilog模块的结构模块声明:包括模块名字、模块输入、输出端口列表,结束关键字为endmodule端口定义:格式为:input: 端口名1,端口名2…端口名n;output: 端口名1,端口名2…端口名n;inout: 端口名1,端口名2…端口名n;3、标识符是用户在编程时给verilog对象起的名字,模块、端口和实例的名字都是标识符。
标识符可以是任意一组字母、数字以及符号“$”和“_”的组合,但标识符的第一个字符必须是字母(a-z,A-Z)或者是下划线“_”,标识符最长可包含1023个字符,此外,标识符区分大小写。
4、整数写法:+/-’1、在较长的数之间可用下划线分开2、当数字不说明位宽时,默认值为32位3、 X或(z)在二进制中代表1位x(或z),在八进制中代表3位,在16进制中代表4位4、如果没有定义一个整数的位宽,其宽度为相应值中定义的位数。
5、如果定义的位宽比实际的位数长,通常在左边填0补位,但如果最左边一位为x或z,就相应的用x或z左边补位。
6、“?”是高阻态z的另一种表示符号,在数字的表示中,字符“?”和z 是完全等价的,可相互代替。
7、整数可以带符号,并且正负号应写在最左边,负数通常表示为二进制补码的形式。
8、当位宽与进制缺省时表示的是10进制数9、在位宽和‘之间,以及进制和数值之间允许出现空格,但’和进制之间以及数值之间是不能出现空格的。
要求掌握整数正确的书写方式。
5、向量:宽度大于1位的变量;标量:宽度为1位的变量。
定义2个8位reg型矢量:reg [7:0] ra, rb;6、运算符(1)注意:逻辑运算符,例如逻辑与&&、逻辑或||、逻辑非!,运算结果是1位的。
Verilog数字系统设计代码90例Contents1、二选一多路选择器 (1)2、多路器模块的编写测试平台 (1)3、三位加法器 (2)4、比较器 (2)5、实例调用—三态门选择器 (2)6、同步置位/清零的计数器 (3)7、异步清零 (3)8、case语句实现3-8译码器的部分代码 (3)9、for语句来实现8位数据中低4位左移到高4位 (4)10、for语句计算出13路脉冲信号为高电平的个数 (4)11、生成语句对两个N位的总线用门级原语进行按位异或 (5)12、用条件生成语句实现参数化乘法器 (5)13、使用case生成语句实现N位加法器 (6)14、四选一多路器 (7)15、四位计数器 (7)16、使用任务控制交通灯 (8)17、CPU总线控制的任务 (9)18、自动任务示例 (9)19、用函数实现乘累加器 (10)20、计算32位地址值的偶校验位 (11)21、左/右移位寄存器 (12)22、用函数的递归调用定义阶乘计算 (12)23、常量函数 (13)24、带符号函数 (13)25、显示任务 (14)26、文件写入操作的例子 (14)27、读取文件的示例1 (15)28、读取文件的示例2 (15)29、使用$random生成随机数 (16)30、宏定义语句`define (16)31、带有宏定义的8位加法器 (17)32、用`include语句设计的16位加法器 (17)33、结构化描述方式对四选一多路选择器 (18)34、结构化描述方式实现一位全加器 (18)35、结构化描述方式实例化四个一位全加器实现四位串行进位全加器 (18)36、用户定义原语 (19)37、四选一的多路选择器的自定义原语设计 (20)38、用户定义原语的方式设计电平敏感锁存器 (20)39、用户定义原语的方式设计D触发器(时钟下降沿触发) (20)40、采用实例化前面用定义原语设计的四选一多路选择器(MUX)的方法实现十六41、数据流建模描述方式:一位全加器 (22)42、行为建模方式设计一位加法器 (22)43、混合设计方式设计一位全加器 (22)44、数据流描述方式对四选一多路选择器建模 (23)45、行为建模方式设计四选一多路选择器 (23)46、用RTL级建模方式设计此电路 (24)47、四位全加器 (24)48、组合逻辑电路 (24)49、单向三态端口 (25)50、单向总线缓冲器 (25)51、双向三态端口 (25)52、双向总线缓冲器 (26)53、2选1多路选择器 (26)54、多路比较器 (27)55、带使能端的3-8译码器 (28)56、4位二进制到格雷码的转换器 (29)57、时序逻辑电路 (30)58、JK触发器 (31)59、D触发器 (32)60、带异步复位端D触发器 (32)61、带异步置位端D触发器 (32)62、带有异步置位和复位的D触发器 (33)63、带有同步复位的D触发器 (33)64、带同步置位端的上升沿触发器 (33)65、带异步复位端和输出使能端的上升沿触发器 (34)66、锁存器:电平触发的存储器单元,基本SR锁存器 (34)67、透明锁存器 (35)68、基本N位同步计数器 (35)69、带有异步复位、同步计数使能和可预置的十进制计数器 (35)70、格雷码计数器 (36)71、四位移位寄存器 (37)72、8位串入串出移位寄存器 (37)73、利用移位寄存器产生顺序脉冲 (38)74、可输出输入信号的2分频信号、4分频信号和8分频信号的分频器 (38)75、分频系数为12的分频器 (39)76、分频系数为6,占空比为1:5的偶数分频器 (39)77、3分频占空比为1:1的奇数分频器 (40)78、分频系数为5、占空比为1:1的奇数分频器 (41)79、分频系数为7、占空比为1:6的奇数分频器 (42)80、带使能端和复位端的时钟同步8位寄存器组逻辑 (42)81、自触发always块 (42)82、1001序列信号检测器 (43)83、米利型有限状态机 (47)85、并行数据流转换为一种特殊串行数据流模块的设计 (53)86、设计对数字采集芯片AD0809的控制接口电路的Verilog代码 (57)87、面积优化——设计乘法选择器 (61)88、串行化——描述一个乘法累加器,其位宽位16位对8个16位数据进行乘法和加法运算 (63)89、流水线设计——流水线计数使用实例:8位加法器 (64)90、流水线设计——设计一个为8位全加器(一个是直接实现,一个采用4级流水线实现) (65)1、二选一多路选择器行为描述:module muxtwo(out,a,b,sl);input a,b,sl;output out;reg out;always@(a or b or sl)if(!sl) out = a;else out = b; endmodule逻辑描述:module muxtwo(out,a,b,sl);input a,b,sl;output out;不用写寄存器wire nsl,sela,selb;assign nsl = ~sl;assign sela = a&nsl;assign selb = b&sl;assign out = sela|selb; endmodule门级描述:module muxtwo(out,a,b,sl);input a,b,sl;output out;不用写寄存器not u1(nsl,sl);and u2(sela,a,nsl);and u3(selb,b,sl);or u4(out,sela,selb); endmodule2、多路器模块的编写测试平台`include “muxtwo.v”module t;reg ain,bin,select;reg clock;wire outw;initialbeginain=0; bin=0;select=0; clock=0;endalways #50 clock =~clock;always@(posedge clock)begin#1 ain = {$random}%2;#3 bin = {$random}%2;endmuxtwo m(.out(outw),.a(ain),.b(bin),.sl(select));endmodule3、三位加法器module adder ( count,sum,a,b,cin );input [2:0] a,b;input cin;output count;output [2:0] sum;assign {count,sum}=a+b+cin;endmodule4、比较器:module compare ( equal,a,b );output equal; //声明输出信号equalinput [1:0] a,b; //声明输入信号a,bassign equal=(a==b)?1:0;//如果两个输入信号相等,输出为1。
第八章语法概念总复习练习1)以下给出了一个填空练习,请将所给各个选项根据电路图,填入程序中的适当位置。
a s s i g n m o d u l e;~| &i n p u t o u t p u ti n p u t s o u t p u t s e n d m o d u l eA ,B ,C , DAOI ( A, B, C, D, F )input A,B,C,D;output F;assign F = ((A&B)&(C&D));endmodule2〕 在这一题中,我们将作有关层次电路的练习,通过这个练习,你将加深对模块间调用时,管脚间连接的理解。
假设已有全加器模块FullAdder,若有一个顶层模块调用此全加器,连接线分别为W4,W5,W3,W1和W2。
请在调用时正确地填入I/O 的对应信号。
module FullAdder(A,B,Cin,Sum,Cout); input A, B, Cin;output Sum, Cout;endmodule3)initial begin endinitialSEL=0; A=0; B=0;#10 A=1;#10 SEL=1; #10 B=1;$monitor (SEL , A ,B , ,F) ; reg A, B , SEL;wire F;A Sum W1 W2 W3 W4 W5B Cin Countendmodule标准答案:module TestFixturereg A,B,SEL;wire F;MUX2M(SEL,A,B,F);initialbeginSEL=0; A=0; B=0;#10 A=1;#10 SEL=1; #10 B=1;endinitial$monitor(SEL,A,B,,F);endmodule4)指出下面几个信号的最高位和最低位。
reg [1:0] SEL; input [0:2] IP; wire [16:23] A;标准答案:MSB:SEL[1] MSB:IP[0] MSB:A[16]LSB:SEL[0] LSB:IP[2] LSB:A[23]5)P,Q,R都是4bit的输入矢量,下面哪一种表达形式是正确的。
verilog数字系统设计教程第四版例题源码verilog数字系统设计教程第四版是一本深入浅出的数字系统设计教材,其中包括了丰富的例题与对应的源码。
以下是该书第四版例题的源码综述:
1. `add` 模块源码:
```verilog
module add (
input [3:0] a,
input [3:0] b,
output [3:0] sum,
output carry
);
wire [3:0] intermediate_sum;
wire intermediate_carry;
assign intermediate_sum = a + b;
assign carry = intermediate_sum[4];
assign sum = intermediate_sum[3:0];
endmodule
```
`add` 模块实现了将两个四位数相加的功能。
本例子还演示了 verilog 的
基本语法、数据类型、变量的使用、运算符的使用、模块的定义与实例化等基本概念。
2. `d_flip_flop` 模块源码:
```verilog
module d_flip_flop (
input clk,
input d,
output reg q
);
always @(posedge clk) begin
q <= d;
end
endmodule
```
`d_flip_flop` 模块实现了一个 D 触发器的功能。
本例子还演示了时序逻辑的基本概念,包括时钟信号的使用和寄存器的使用。
3. `counter` 模块源码:
```verilog
module counter (
input clk,
input reset,
output reg [7:0] count
);
always @(posedge clk or posedge reset) begin
if (reset) begin
count <= 0;
end else begin
count <= count + 1;
end
end
endmodule
```
`counter` 模块实现了一个八位计数器的功能。
本例子还演示了时钟的使用和一种常见的状态机设计模式。
4. `mux` 模块源码:
```verilog
module mux (
input [1:0] select,
input [3:0] a,
input [3:0] b,
output [3:0] out
);
assign out = (select) ? b : a;
endmodule
```
`mux` 模块实现了一个两路四重复用器的功能。
本例子还演示了一种简
单的条件语句和三元运算符的使用。
总体而言,以上例题的源码主要演示了verilog 的基础语法、数据类型、运算符和模块机制等概念,这对于数字系统设计的初学者非常有帮助,并且也对于那些希望巩固自己的基础知识的学生非常有用。