Verilog的135个经典设计实例
verilog实例
verilog实例Verilog是一种硬件描述语言,用于设计和建模数字电路。
下面是一个Verilog实例,用于实现一个简单的4位加法器。
verilog.module adder4bit(。
input [3:0] A,。
input [3:0] B,。
input Cin,。
output [3:0] Sum,。
output Cout.);wire [3:0] S;wire C1, C2, C3;// 4个全加器实例。
full_adderFA0(.A(A[0]), .B(B[0]), .Cin(Cin), .Sum(S[0]), .Cout(C1));full_adderFA1(.A(A[1]), .B(B[1]), .Cin(C1), .Sum(S[1]), .Cout(C2));full_adderFA2(.A(A[2]), .B(B[2]), .Cin(C2), .Sum(S[2]), .Cout(C3));full_adderFA3(.A(A[3]), .B(B[3]), .Cin(C3), .Sum(S[3]), .Cout(Cout)); assign Sum = S;endmodule.module full_adder(。
input A,。
input B,。
input Cin,。
output Sum,。
output Cout.);assign Sum = A ^ B ^ Cin;assign Cout = (A & B) | (Cin & (A ^ B));endmodule.在这个例子中,我们定义了一个4位加法器模块`adder4bit`,它有两个4位输入A和B,一个输入Cin表示进位,以及一个4位输出Sum和一个输出Cout表示进位。
在`adder4bit`模块中,我们实例化了4个全加器模块`full_adder`,并将它们连接起来形成一个级联的加法器。
最后,我们使用`assign`语句将全加器的输出连接到`Sum`和`Cout`输出。
ASIC设计实例(verilog)
ASIC设计实例 ASIC设计实例
设计一个交通灯信号控制电路。 要求输入为1KHz的时钟和复位信号,输出为 红、绿、黄三个信号(高电平为亮)。 具体描述:复位信号(低电平)有效,红、 绿、黄灯灭;接着进行如下循环:绿灯亮60 秒,黄灯闪烁10秒(闪烁周期是1秒),红 灯亮60秒。
设计端口及需求: 设计端口及需求:
always @(posedge clk) //??(50MHz->1KHz) begin if(~reset) begin count<=0; clk_scan<=0; end else begin if(count==25000) begin count<=0; clk_scan<=~clk_scan; end else count<=count+1; end end
always @(posedge clk_scan,negedge reset) //第5位 begin if (~reset) five<=0; else begin if (one==9 && two==9 && three==9 && four==9 && five==9) five<= 0; else begin if (one==9 && two==9 && three==9 && four==9) five<=five+1; end end end
always @(posedge clk_scan,negedge reset) //第4位 begin if (~reset) four<=0; else begin if (one==9 && two==9 && three==9 && four==9) four<= 0; else begin if (one==9 && two==9 && three==9) four<=four+1; end end end
Verilog的135个经典设计实例
Verilog的135个经典设计实例1、立即数放大器:立即数放大器是一种用于将输入电平放大到更高电平的电路,它可以实现任意输入到输出的映射,并且可以在Verilog中使用。
立即数放大器的Verilog实现如下:module immedamp(in, out);input in;output out;reg [3:0] immed;assign out = immed[3];begincase (in)4'b0000: immed = 4'b1000;4'b0001: immed = 4'b1001;4'b0010: immed = 4'b1010;4'b0011: immed = 4'b1011;4'b0100: immed = 4'b1100;4'b0101: immed = 4'b1101;4'b0110: immed = 4'b1110;4'b0111: immed = 4'b1111;4'b1000: immed = 4'b1000;4'b1001: immed = 4'b1001;4'b1010: immed = 4'b1010;4'b1011: immed = 4'b1011;4'b1100: immed = 4'b1100;4'b1101: immed = 4'b1101;4'b1110: immed = 4'b1110;4'b1111: immed = 4'b1111;endcaseendendmodule2、多路复用器:多路复用器是一种用于将多个输入选择转换为单个输出的电路,它可以实现由多种方式选择的输出,并可以使用Verilog实现。
verilog hdl语言100例详解
verilog hdl语言100例详解Verilog HDL语言是一种硬件描述语言,用于描述数字电路和系统的行为和结构。
它是硬件设计工程师在数字电路设计中的重要工具。
本文将介绍100个例子,详细解释Verilog HDL语言的应用。
1. 基本门电路:Verilog HDL可以用于描述基本门电路,如与门、或门、非门等。
例如,下面是一个描述与门电路的Verilog HDL代码:```verilogmodule and_gate(input a, input b, output y);assign y = a & b;endmodule```2. 多路选择器:Verilog HDL也可以用于描述多路选择器。
例如,下面是一个描述2:1多路选择器的Verilog HDL代码:```verilogmodule mux_2to1(input a, input b, input sel, output y);assign y = sel ? b : a;endmodule```3. 寄存器:Verilog HDL可以用于描述寄存器。
例如,下面是一个描述8位寄存器的Verilog HDL代码:```verilogmodule register_8bit(input [7:0] d, input clk, input reset, output reg [7:0] q);always @(posedge clk or posedge reset)if (reset)q <= 0;elseq <= d;endmodule```4. 计数器:Verilog HDL可以用于描述计数器。
例如,下面是一个描述8位计数器的Verilog HDL代码:```verilogmodule counter_8bit(input clk, input reset, output reg [7:0] count);always @(posedge clk or posedge reset)if (reset)count <= 0;elsecount <= count + 1;endmodule```5. 加法器:Verilog HDL可以用于描述加法器。
verilog的15个经典设计实例
begin b=a; c=b; end endmodule
【例 5.11】模为 60 的 BCD 码加法计数器
module count60(qout,cout,data,load,cin,reset,clk);
【例 5.6】用 fork-join 并行块产生信号波形
`timescale 10ns/1ns module wave2; reg wave; parameter cycle=5; initial
fork wave=0;
#(cycle) wave=1; #(2*cycle) wave=0; #(3*cycle) wave=1; #(4*cycle) wave=0; #(5*cycle) wave=1; #(6*cycle) $finish; join initial $monitor($time,,,"wave=%b",wave); endmodule
else
out<=out+1;
end
endmodule
//同步复位 //计数
【例 3.3】4 位全加器的仿真程序
`timescale 1ns/1ns `include "adder4.v" module adder_tp; reg[3:0] a,b; reg cin; wire[3:0] sum; wire cout; integer i,j;
output[7:0] qout;
output cout;
input[7:0] data;
input load,cin,clk,reset;
Verilog 数字系统设计90例
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实例
一、组合逻辑实验 (2)实验1 3X8 译码器程序 (2)实验 2 二-十进制译码器 (2)实验3 BCD 码—七段数码管显示译码器 (3)实验4 8-3编码器 (4)实验 5 8-3优先编码器 (4)实验6 十—二进制编码器 (5)实验7 三选一数据选择器 (5)实验8 半加器 (6)实验9 全加器 (7)实验10 半减器 (8)实验11 全减器 (8)实验12 多位数值比较器 (9)实验13 奇偶校验 (9)实验14 补码生成 (10)实验15 8位硬件加法器的设计 (10)实验16 4 位并行乘法器 (10)实验17 七人表决器 (10)实验18 格雷码变换 (11)二、时序逻辑实验 (11)实验 1 D 触发器 (11)实验 2 JK 触发器 (12)实验 3 四位移位寄存器 (12)实验 4 异步计数器 (13)实验 5 同步计数器 (14)实验 6 可逆计数器 (15)实验7 步长可变的加减计数器 (16)实验8 含异步清0和同步时钟使能的4位加法计数器 (17)实验9 顺序脉冲发生器 (18)实验10 序列信号发生器 (18)实验11 用状态机实现串行数据检测器 (19)实验12 分频器 (20)实验13 Moore状态机 (21)实验14 Mealy 状态机 (23)实验15 三层电梯 (24)实验16 性线反馈移位寄存器(LFSR)设计 (32)实验17 正负脉宽数控调制信号发生器 (32)三、存储器设计 (34)实验 1 只读存储器(ROM) (34)实验 2 SRAM (34)实验 3 FIFO (35)四、扩展接口实验 (39)实验 1 流水灯 (39)实验 2 VGA彩色信号显示控制器设计 (40)实验 3 PS/2键盘接口实验 (48)实验 4 PS/2鼠标接口实验 (49)五、综合实验 (58)实验 1 函数发生器 (58)实验 2 自动售货机 (61)实验 3 移位相加4位硬件乘法器电路设计 (63)一、组合逻辑实验实验1 3X8 译码器程序//Decoder: 3-to 8 decoder with an enable contmodule decoder(y,en,a) ;output [7:0] y ;input en ;input [2:0] a;reg[7:0] y ;always @ (en or a) // EN 和A 是敏感信号if(!en) // 如果使能信号为低,无效y = 8'b1111_1111 ;elsecase(a)3'b000 : y = 8'b1111_1110 ; // 最低位为低3'b001 : y = 8'b1111_1101 ;3'b010 : y = 8'b1111_1011 ;3'b011 : y = 8'b1111_0111 ;3'b100 : y = 8'b1110_1111 ;3'b101 : y = 8'b1101_1111 ;3'b110 : y = 8'b1011_1111 ;3'b111 : y = 8'b0111_1111 ;default : y = 8'bx ; // 否则为不确定信号endcaseendmodule实验 2 二-十进制译码器//Decoder: binary-to decimal decoder with an enable controlmodule b2d(y,en,a) ;output [7:0] y ;input en ;input [3:0] a;reg[7:0] y ;always @ (en or a) // EN 和A 是敏感信号if(!en) // 如果使能信号为低,无效y = 8'b1111_1111;elsebeginif(a>9)y<=a+6; //这里完成了二进制到十进制的译码,elsey<=a;end//为了方便在平台上进行观察验证///这里把数据的个位和十位分别用4 个LED 进行显示,均为二进制Endmodule实验3 BCD 码—七段数码管显示译码器module decode4_7(decodeout,a);output[6:0] decodeout;input[3:0] a;reg[6:0] decodeout;always @(a)begincase(a) //用case 语句进行译码abcdefg4'h0:decodeout=7'b1111110;4'h1:decodeout=7'b0110000;4'h2:decodeout=7'b1101101;4'h3:decodeout=7'b1111001;4'h4:decodeout=7'b0110011;4'h5:decodeout=7'b1011011;4'h6:decodeout=7'b1011111;4'h7:decodeout=7'b1110000;4'h8:decodeout=7'b1111111;4'h9:decodeout=7'b1111011;4'ha:decodeout=7'b1110111;4'hb:decodeout=7'b0011111;4'hc:decodeout=7'b1001110;4'hd:decodeout=7'b0111101;4'he:decodeout=7'b1001111;4'hf:decodeout=7'b1000111;default: decodeout=7'bx;endcaseendendmodule实验4 8-3编码器//a 8-3 codermodule coder(dout,din);output[2:0] dout;input [7:0] din;reg [2:0] dout;always @(din)case(din)8'b1111_1110 : dout<=3'b000;8'b1111_1101 : dout<=3'b001;8'b1111_1011 : dout<=3'b010;8'b1111_0111 : dout<=3'b011;8'b1110_1111 : dout<=3'b100;8'b1101_1111 : dout<=3'b101;8'b1011_1111 : dout<=3'b110;8'b0111_1111 : dout<=3'b111;default: dout<=3'bx;endcaseendmodule实验 5 8-3优先编码器module encoder(d0,d1,d2,d3,d4,d5,d6,d7,x,y,v); output x,y,v;input d0,d1,d2,d3,d4,d5,d6,d7;reg x,y,v;always @ (d0 or d1 or d2 or d3 or d4 or d5 or d6 or d7) if (d7 == 0){x,y,v} = 3'b111 ;else if (d6 == 0){x,y,v} = 3'b110 ;else if (d5 == 0){x,y,v} = 3'b101 ;else if (d4 == 0){x,y,v} = 3'b100 ;else if (d3 == 0){x,y,v} = 3'b011 ;else if (d2 == 0){x,y,v} = 3'b010 ;else if (d1 == 0){x,y,v} = 3'b001 ;else if (d0 == 0){x,y,v} = 3'b000 ;else{x,y,v} = 3'bxxx ;endmodule实验6 十—二进制编码器// decimal to binary encodermodule encoder(y,a);output [4:0] y;input [4:0] a; // input [4] 为十位,[3:0]为个位?reg [4:0] y;always @ (a) // A 是敏感信号beginif(a>9)y<=a-6; //这里完成了十进制到二进制的编码,elsey<=a;end//为了方便在平台上进行观察验证///这里把数据的个位用4 个2 进制数据表示,十位用1bit 进行显示;endmodule实验7 三选一数据选择器module mux3to1(dout,a,b,c,sel);output[1:0] dout;input [1:0] a,b,c;input[1:0] sel;reg [1:0] dout;// RTL modelingalways @(a or b or c or sel)case(sel)2'b00 : dout<=a;2'b01 : dout<=b;2'b10 : dout<=c;default :dout<=2'bx;endcaseendmodule//数据流方式描述的1 位半加器module halfadder (sum,cout,a,b); input a,b;output sum,cout;assign sum=a^b;assign cout=a&b;// carry out; endmodule附录:各种不同的描述方式:1,调用门元件实现的1 位半加器module half_add1(a,b,sum,cout); input a,b;output sum,cout;and (cout,a,b);xor (sum,a,b);endmodule2,采用行为描述的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; end endcaseendendmodule3,采用行为描述的1 位半加器module half_add4(a,b,sum,cout); input a,b;output sum,cout;reg sum,cout;always @(a or b)beginsum= a^b;cout=a&b;endendmodule// 1 bit full adder 1 位全加器module full_add(a,b,cin,sum,cout);input a,b,cin;output sum,cout;assign {cout,sum}=a+b+cin;endmodule附录:各种不同的描述方式实现的1位全加器1,调用门元件实现的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);endmodule2 数据流描述的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);endmodule3 行为描述的1 位全加器module full_add4(a,b,cin,sum,cout);input a,b,cin;output sum,cout;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;endendmodule4 混合描述的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实验10 半减器module half_sub(diff,sub_out,x,y);output diff,sub_out;input x,y;reg diff,sub_out;//行为描述always@(x or y)case ({x,y})2'b00 : begin diff= 0; sub_out = 0;end2'b01 : begin diff= 1; sub_out = 1;end2'b10 : begin diff= 1; sub_out = 0;end2'b11 : begin diff= 0; sub_out = 0;enddefault: begin diff= x; sub_out =x;endendcaseendmodule实验11 全减器module full_sub(diff,sub_out,x,y,sub_in);output diff,sub_out;input x,y,sub_in;reg diff,sub_out;//行为描述always@(x or y or sub_in)case ({x,y,sub_in})3'b000 : begin diff= 0; sub_out = 0;end3'b001 : begin diff= 1; sub_out = 1;end3'b010 : begin diff= 1; sub_out = 1;end3'b011 : begin diff= 0; sub_out = 1;end3'b100 : begin diff= 1; sub_out = 0;end3'b101 : begin diff= 0; sub_out = 0;end3'b110 : begin diff= 0; sub_out = 0;end3'b111 : begin diff= 1; sub_out = 1;enddefault: begin diff= x; sub_out =x;endendcaseendmodule实验12 多位数值比较器module comp(ABB,AEB,ASB,A,B,I1,I2,I3);output ABB,AEB,ASB; // ABB 表示A>B AEB 表示A=B, ASB 表示A<B;input [1:0] A,B;input I1,I2,I3; // I1表示上一级的A>B I2 表示上一级的A=B, I3 表示上一级的A<B; reg ABB,AEB,ASB;//行为描述always@(A or B or I1 or I2 or I3)if(A>B){ABB,AEB,ASB}=3'b100;else if(A<B){ABB,AEB,ASB}=3'b001;else // A=B,但是考虑到前一级的情况begin if(I1) //I1 表示上一级的A>B{ABB,AEB,ASB}=3'b100;else if(I3){ABB,AEB,ASB}=3'b001;//I3 表示上一级的A<B;else{ABB,AEB,ASB}=3'b010;endendmodule实验13 奇偶校验//奇偶校验位产生器module parity(even_bit,odd_bit,input_bus);output even_bit,odd_bit;input[7:0] input_bus;assign odd_bit = ^ input_bus; //产生奇校验位assign even_bit = ~odd_bit; //产生偶校验位endmodule实验14 补码生成module compo(d_out,d_in);output [7:0] d_out;input [7:0]d_in;reg [7:0] d_out;always @(d_in)if (d_in[7]==1'b0) // 正数,最高位为符号位,0说明是正数,正数补码是其本身d_out=d_in;else // 负数d_out={d_in[7],~d_in[6:0]+1'b1}; //最高位符号位不变,数据位加一构成其补码endmodule实验15 8位硬件加法器的设计//8 位硬件加法器module add8b(cout,sum,a,b,cin);output[7:0] sum;output cout;input[7:0] a,b;input cin;assign {cout,sum}=a+b+cin;endmodule实验16 4 位并行乘法器//4 位并行乘法器module mult(outcome,a,b);parameter size=4;input[size:1] a,b; //两个操作数output[2*size:1] outcome; //结果assign outcome=a*b; //乘法运算符endmodule实验17 七人表决器// for 语句描述的七人投票表决器module voter7(pass,vote);output pass; // 通过为高电平,否则为低电平input[6:0] vote; // 7个投票输入#通过为高,否定为低reg[2:0] sum;integer i;reg pass;always @(vote)beginsum=0;for(i=0;i<=6;i=i+1) //for 语句if(vote[i]) sum=sum+1;if(sum[2]) pass=1; //若超过4 人赞成,则pass=1else pass=0;endendmodule实验18 格雷码变换module BIN2GARY (EN ,DATA_IN ,DA TA_OUT );input EN ;input [3:0] DATA_IN ;output [3:0] DATA_OUT ;assign DATA_OUT [0] = (DA TA_IN [0] ^ DA TA_IN [1] ) && EN ; assign DATA_OUT [1] = (DA TA_IN [1] ^ DATA_IN [2] ) && EN ; assign DATA_OUT [2] = (DA TA_IN [2] ^ DATA_IN [3] ) && EN ; assign DATA_OUT [3] = DATA_IN [3] && EN ;endmodule二、时序逻辑实验实验 1 D 触发器module myDFF(q,qn,d,clk,set,reset);input d,clk,set,reset;output q,qn;reg q,qn;always @(posedge clk)beginif (reset) beginq <= 0; qn <= 1; //同步清0,高电平有效endelse if (set) beginq <=1; qn <=0; //同步置1,高电平有效else beginq <= d; qn <= ~d;endendendmodule实验 2 JK 触发器//带异步清0、异步置1 的JK 触发器module JK_FF(CLK,J,K,Q,RS,SET);input CLK,J,K,SET,RS;output Q;reg Q;always @(posedge CLK or negedge RS or negedge SET) beginif(!RS) Q <= 1'b0;else if(!SET) Q <= 1'b1;else case({J,K})2'b00 : Q <= Q;2'b01 : Q <= 1'b0;2'b10 : Q <= 1'b1;2'b11 : Q <= ~Q;default: Q<= 1'bx;endcaseendendmodule实验 3 四位移位寄存器//4 位移位寄存器module shifter(din,clk,clr,dout);input din,clk,clr;output[3:0] dout;reg[3:0] dout;always @(posedge clk)beginif (clr) dout<= 4'b0; //同步清0,高电平有效elsebegindout <= dout << 1; //输出信号左移一位dout[0] <= din; //输入信号补充到输出信号的最低位endendmodule// 分频器部分,获得便于试验观察的时钟信号module clk_div(clk_out,clk_in);input clk_in;output clk_out;reg clk_out;reg[25:0] counter; //50_000_000=1011_1110_1011_1100_0010_0000_00parameter cnt=50_000_000; /// 50MHz is the sys clk,50_000_000=2FAF080 always @(posedge clk_in)begincounter<=counter+1;if(counter==cnt/2-1)beginclk_out<=!clk_out;counter<=0;endendendmodule实验 4 异步计数器//行为描述方式实现的4 位异步计数器module counter(clk,clr,q0,q1,q2,q3);input clk,clr;output q0,q1,q2,q3;reg q0,q1,q2,q3;//reg q0_t,q1_t,q2_t,q3_t;reg q0_r,q1_r,q2_r,q3_r;always @(posedge clk or negedge clr)if(!clr) q0_r<=0;elseq0_r<=!q0_r;always @(posedge q0_r or negedge clr)if(!clr) q1_r<=0;elseq1_r<=!q1_r;always @(posedge q1_r or negedge clr)if(!clr) q2_r<=0;elseq2_r<=!q2_r;always @(posedge q2_r or negedge clr)if(!clr) q3_r<=0;elseq3_r<=!q3_r;assign {q0,q1,q2,q3}={q0_r,q1_r,q2_r,q3_r};endmodule// 分频器部分,获得便于试验观察的时钟信号module clk_div(clk_out,clk_in);input clk_in;output clk_out;reg clk_out;reg[25:0] counter; //50_000_000=1011_1110_1011_1100_0010_0000_00 parameter cnt=50_000_000; /// 50MHz is the sys clk,50_000_000=2FAF080 always @(posedge clk_in)begincounter<=counter+1;if(counter==cnt/2-1)beginclk_out<=!clk_out;counter<=0;endendendmodule实验 5 同步计数器Verilog HDL 程序//带异步清0的同步计数器module counter(Q,CR,CLK);input CLK,CR;output[3:0] Q;reg [3:0]Q;always @(posedge CLK or negedge CR)beginif(!CR) Q <= 4'b0000;elsebeginif (Q==15)Q<=0;else Q<=Q+1;endendendmodule// 分频器部分,获得便于试验观察的时钟信号module clk_div(clk_out,clk_in);input clk_in;output clk_out;reg clk_out;reg[25:0] counter; //50_000_000=1011_1110_1011_1100_0010_0000_00 parameter cnt=50_000_000; /// 50MHz is the sys clk,50_000_000=2FAF080 always @(posedge clk_in)begincounter<=counter+1;if(counter==cnt/2-1)beginclk_out<=!clk_out;counter<=0;endendendmodule实验 6 可逆计数器//同步清零的可逆计数器module counter(Q,CLK,CR,UD);input CLK,CR,UD;output[3:0] Q;reg [3:0]cnt;initialbegincnt<=4'b0000;endassign Q = cnt;always @(posedge CLK )beginif(!CR) cnt <= 4'b0000; //同步清0,低电平有效else beginif (UD) cnt = cnt + 1; //加法计数else cnt = cnt - 1; //减法计数endendendmodule// 分频器部分,获得便于试验观察的时钟信号module clk_div(clk_out,clk_in);input clk_in;output clk_out;reg clk_out;reg[25:0] counter; //50_000_000=1011_1110_1011_1100_0010_0000_00parameter cnt=50_000_000; /// 50MHz is the sys clk,50_000_000=2FAF080 always @(posedge clk_in)begincounter<=counter+1;if(counter==cnt/2-1)beginclk_out<=!clk_out;counter<=0;endendendmodule实验7 步长可变的加减计数器//同步清零的步长可变加减计数器module counter(Q,CLK,CR,UD,STEP);input CLK,CR,UD;input [1:0] STEP;output[3:0] Q;reg [3:0]cnt;initialbegincnt<=4'b0000;endassign Q = cnt;always @(posedge CLK)beginif(!CR) cnt <= 4'b0000; //同步清0,低电平有效else beginif (UD) cnt = cnt + STEP; //加法计数else cnt = cnt - STEP; //减法计数endendendmodule// 分频器部分,获得便于试验观察的时钟信号module clk_div(clk_out,clk_in);input clk_in;output clk_out;reg clk_out;reg[25:0] counter; //50_000_000=1011_1110_1011_1100_0010_0000_00 parameter cnt=50_000_000; /// 50MHz is the sys clk,50_000_000=2FAF080 always @(posedge clk_in)begincounter<=counter+1;if(counter==cnt/2-1)beginclk_out<=!clk_out;counter<=0;endendendmodule实验8 含异步清0和同步时钟使能的4位加法计数器//实验八含异步清0 和同步时钟使能的4 位加法计数器module counter(clk,clear,en,qd);input clk,clear,en;output[3:0] qd;reg[3:0] cnt;always @(posedge clk or negedge clear)beginif (!clear) cnt <= 4'h0; //异步清0,低电平有效else if (en) //同步使能cnt<= cnt + 1; //加法计数endassign qd = cnt;endmodule// 分频器部分,获得便于试验观察的时钟信号module clk_div(clk_out,clk_in);input clk_in;output clk_out;reg clk_out;reg[25:0] counter; //50_000_000=1011_1110_1011_1100_0010_0000_00parameter cnt=50_000_000; /// 50MHz is the sys clk,50_000_000=2FAF080 always @(posedge clk_in)begincounter<=counter+1;if(counter==cnt/2-1)beginclk_out<=!clk_out;counter<=0;endendendmodule实验9 顺序脉冲发生器module pulsegen(q0,q1,q2,clk,rd);input clk, rd;output q0,q1,q2;reg q0,q1,q2;reg [2:0] x,y;always @(posedge clk)if(rd)beginy<=0;x<=3'b001; // give a initial valueendelsebeginy<=x;x<={x[1:0],x[2]};endassign {q0,q1,q2}=y;endmodule// 分频器部分,获得便于试验观察的时钟信号module clk_div(clk_out,clk_in);input clk_in;output clk_out;reg clk_out;reg[25:0] counter; //50_000_000=1011_1110_1011_1100_0010_0000_00 parameter cnt=50_000_000; /// 50MHz is the sys clk,50_000_000=2FAF080 always @(posedge clk_in)begincounter<=counter+1;if(counter==cnt/2-1)beginclk_out<=!clk_out;counter<=0;endendendmodule实验10 序列信号发生器module sequencer(y,clk,clr);input clk,clr;reg [7:0] yt;parameter s0=8'b1000_0000, // state 0s1=8'b1100_0001, // state 1s2=8'b1110_0000, // state 2s3=8'b0001_0000,s4=8'b1111_1000,s5=8'b0000_0011,s6=8'b1111_0011,s7=8'b0000_0001; //state 7always @(posedge clk)beginif(clr)yt<=s0; // clear to state 0elsebegincase(yt)s0: yt<=s1; //change from state 0 to state 1s1 : yt<=s2; //s2 : yt<=s3; // state 2-->3s3 : yt<=s4;s4 : yt<=s5;s5 : yt<=s6;s6 : yt<=s7;s7 : yt<=s0; //state 7 to state 0default: yt<=s0; //default state 7 to s0endcaseendendassign y=yt;endmodule实验11 用状态机实现串行数据检测器module detector(got,instr,clk);output got;input instr,clk;reg [2:0] cstate,nextstate;reg got;parameter s0=0,s1=1,s2=2,s3=3,s4=4,s5=5,s6=6,s7=7; // 8 statesalways @(posedge clk) // 定义起始状态begincstate<=nextstate;endalways @(cstate or instr) // 定义状态转换begincase(cstate)s0 : begin got<=0;if(instr) nextstate<=s1; //detected the 1st bit of 1110010,i.e.,1,to s1else nextstate<=s0; // if not ,stay hereends1 : begin got<=0;if(instr) nextstate<=s2; //detected the 2nd bit of 1110010,i.e.,1,to s2else nextstate<=s0; // notends2 : begin got<=0;if(instr) nextstate<=s3; //detected the 3rd bit of 1110010,i.e.,1else nextstate<=s0; // notends3 : begin got<=0;if(!instr) nextstate<=s4; //detected the 4th bit of 1110010,i.e.,0else nextstate<=s2; // not ,stayends4 : begin got<=0;if(!instr) nextstate<=s5; //detected the 5th bit of 1110010,i.e.,0else nextstate<=s1; // notends5 : begin got<=0;f(instr) nextstate<=s6; //detected the 6th bit of 1110010,i.e.,1else nextstate<=s0; // notends6 : begin got<=0;if(!instr) nextstate<=s7; //detected the 7th bit of 1110010,i.e.,0else nextstate<=s2; // notends7 : begin got<=1; // got the sequenceif(instr) nextstate<=s1; //detected the 1st bit of 1110010,i.e.,1,chagne to s1 else nextstate<=s0; // not ,change to s0endendcaseendendmodule实验12 分频器// 分频器部分,获得便于试验观察的时钟信号,在实验台上进行观察module clk_div(clk_out,clk_in);input clk_in;output clk_out;reg clk_out;reg[25:0] counter; //50_000_000=1011_1110_1011_1100_0010_0000_00 parameter cnt=50_000_000; /// 50MHz is the sys clk,50_000_000=2FAF080 always @(posedge clk_in)begincounter<=counter+1;if(counter==cnt/2-1)beginclk_out<=!clk_out;counter<=0;endendendmodule// 分频器部分用于设计仿真,10 分频module clk_diver(clk_out,clk_in);input clk_in;output clk_out;reg clk_out;reg[4:0] counter; //parameter cnt=10; /// 10分频always @(posedge clk_in)begincounter<=counter+1;if(counter==cnt/2-1)beginclk_out<=!clk_out;counter<=0;endendendmodule实验13 Moore状态机module moore(dataout,clk,datain,reset);output[3:0] dataout;input [1:0] datain;input clk,reset;parameter s0=2'b00, //采用格雷码编码s1=2'b01,s2=2'b11,s3=2'b10;reg [1:0]cstate,nstate;reg [3:0] dataout;always @(posedge clk or posedge reset)//时序逻辑进程if(reset) //异步复位cstate<=s0;else //--当检测到时钟上升沿时执行CASE 语句begincstate<=nstate;endalways @(cstate or datain)begincase(cstate)s0:begin if(datain==0) nstate<=s1;else nstate<=s0;ends1:begin if(datain==1) nstate<=s2;else nstate<=s1;ends2:begin if(datain==2) nstate<=s3;else nstate<=s2; ends3:begin if(datain==3) nstate<=s0;else nstate<=s3; end//由信号state 将当前状态值带出此进程,进入组合逻辑进程endcaseendalways @(cstate) //组合逻辑进程begincase(cstate)// -- 确定当前状态值s0:dataout<=4'b0001; //对应状态s0的数据输出为"0001"s1:dataout<=4'b0010;s2:dataout<=4'b0100;s3:dataout<=4'b1000;endcaseendendmodule// 分频器部分,获得便于试验观察的时钟信号module clk_div(clk_out,clk_in);input clk_in;output clk_out;reg clk_out;reg[25:0] counter; //50_000_000=1011_1110_1011_1100_0010_0000_00parameter cnt=50_000_000; /// 50MHz is the sys clk,50_000_000=2FAF080 always @(posedge clk_in)begincounter<=counter+1;if(counter==cnt/2-1)beginclk_out<=!clk_out;counter<=0;endendendmodule实验14 Mealy 状态机module mealy(dataout,clk,datain,reset);output[3:0] dataout;input [1:0] datain;input clk,reset;parameter s0=2'b00, //采用格雷码编码s1=2'b01,s2=2'b11,s3=2'b10;reg [1:0]cstate,nstate;reg [3:0] dataout;always @(posedge clk or posedge reset)//时序逻辑进程if(reset) //异步复位cstate<=s0;else //--当检测到时钟上升沿时执行CASE 语句begincstate<=nstate;endalways @(cstate or datain)begincase(cstate)s0:begin if(datain==0) nstate<=s1;else nstate<=s0;ends1:begin if(datain==1) nstate<=s2;else nstate<=s1;ends2:begin if(datain==2) nstate<=s3;else nstate<=s2; ends3:begin if(datain==3) nstate<=s0;else nstate<=s3; end//由信号state 将当前状态值带出此进程,进入组合逻辑进程endcaseendalways @(cstate or datain) //组合逻辑进程begincase(cstate)// -- 确定当前状态值s0:begin if (datain==0)dataout<=4'b0001;else dataout<=4'b0000;end//对应状态s0,输入datain 为0 时,数据输出为"0001",即输出由当前状态和输入同时控制;s1:begin if (datain==1)dataout<=4'b0010;else dataout<=4'b0101;ends2:begin if (datain==2)dataout<=4'b0100;else dataout<=4'b0011;ends3:begin if (datain==3)dataout<=4'b1000; else dataout<=4'b0110;endendcaseendendmodule实验15 三层电梯module lift_3 (buttonclk, liftclk, reset, f1upbutton, f2upbutton, f2dnbutton, f3dnbutton,stop1button, stop2button, stop3button,position, doorlight,udsig,fdnlight,fuplight);input buttonclk; //input liftclk; //电梯运行时钟input reset; // resetinput f1upbutton; //from 1st floor to upstairsinput f2upbutton; //from 2nd floor to upstairsinput f2dnbutton; //from 2nd floor to downstairsinput f3dnbutton; //from 3rd floor to downstairsinput stop1button; // signal to stop the lift on floor 1input stop2button; // stop on floor 2input stop3button; // stop on floor 3output [2:1] fuplight;reg[2:1] fuplight; //regoutput [3:2] fdnlight;reg[3:2] fdnlight;reg[3:1] stoplight;reg[1:0] position;output doorlight; // close or open 开关指示灯reg doorlight;output udsig; // up or down signalreg udsig;parameter[3:0] stopon1 = 0; /// state machineparameter[3:0] dooropen = 1;parameter[3:0] doorclose = 2;parameter[3:0] doorwait1 = 3;parameter[3:0] doorwait2 = 4;parameter[3:0] doorwait3 = 5;parameter[3:0] doorwait4 = 6;parameter[3:0] up = 7;parameter[3:0] down = 8;parameter[3:0] stop = 9;reg[3:0] mylift; //reg clearup;reg cleardn;reg[1:0] pos;always @(posedge reset or posedge liftclk)beginif (reset == 1'b1) ///asyn resetbeginmylift = stopon1 ; // defalut positon :floor 1clearup = 1'b0 ; // clear upcleardn = 1'b0 ; //clear downendelsebegincase (mylift) // FSMstopon1 : /// stop on floor 1begindoorlight = 1'b1 ;position = 1 ; //the lift positon flagpos = 1; //mylift = doorwait1 ;enddoorwait1 :beginmylift = doorwait2 ; // 2nd secondsenddoorwait2 :beginclearup = 1'b0 ; //cleardn = 1'b0 ;mylift = doorwait3 ; // 3rd sec.senddoorwait3 :beginmylift = doorwait4 ; //4th secondenddoorwait4 :beginmylift = doorclose ; //enddoorclose : // after 4 seconds ,close the doorbegindoorlight = 1'b0 ;if (udsig == 1'b0) // going upbeginif (position == 3) // on floor 3beginif (stoplight == 3'b000 & fuplight == 2'b00 & fdnlight == 2'b00) //no requestsbeginudsig = 1'b1 ; ///mylift = doorclose ;endelsebeginudsig = 1'b1 ;mylift = down ; // if not ,must be going downendendelse if (position == 2) // on floor 2beginif (stoplight == 3'b000 & fuplight == 2'b00 & fdnlight == 2'b00) //no requestsbeginudsig = 1'b0 ; //still going upmylift = doorclose ; //closingendelse if ((stoplight[3]) == 1'b1 | ((stoplight[3])== 1'b0 & (fdnlight[3]) == 1'b1))begin //inside req to stop onf.3 ,or req. to go down from f.3udsig = 1'b0 ; //still going upmylift = up ;endelsebegin // must be going down whatever happensudsig = 1'b1 ;mylift = down ;endendelse if (position == 1) // on floor 1beginif (stoplight == 3'b000 & fuplight == 2'b00 & fdnlight == 2'b00) //no req.beginudsig = 1'b0 ;mylift = doorclose ; // waiting for the going up reqendelsebeginudsig = 1'b0 ; // must be going upmylift = up ;endendendelse if (udsig == 1'b1) // if going downbeginif (position == 1) //beginif (stoplight == 3'b000 & fuplight == 2'b00 & fdnlight == 2'b00)beginudsig = 1'b0 ; // no reqmylift = doorclose ;//waiting for the req to go upendelsebeginudsig = 1'b0 ; // going up at any casemylift = up ;endendelse if (position == 2)beginif (stoplight == 3'b000 & fuplight == 2'b00 & fdnlight == 2'b00)beginudsig = 1'b1 ;mylift = doorclose ;endelse if ((stoplight[1]) == 1'b1 | ((stoplight[1]) == 1'b0 & (fuplight[1]) == 1'b1))beginudsig = 1'b1 ; //downmylift = down ;endelsebeginudsig = 1'b0 ; //mylift = up ;endendelse if (position == 3)///beginif (stoplight == 3'b000 & fuplight == 2'b00 & fdnlight == 2'b00)beginudsig = 1'b1 ;mylift = doorclose ;endelsebeginudsig = 1'b1 ;mylift = down ;endendendendup : ///going up stairsbeginposition = position + 1 ; // under the lift clockpos = pos + 1; //if (pos < 3 & ((stoplight[pos]) == 1'b1 | (fuplight[pos]) == 1'b1))begin//destination isn't the top,to stop there or going up from theremylift = stop ; // stop the liftendelse if (pos == 3 & ((stoplight[pos]) == 1'b1 | (fdnlight[pos]) == 1'b1))begin// has been on f.3, and stop here request or go dowm reqmylift = stop ; //next state : stopendelsebeginmylift = doorclose ; //endenddown : // go downbeginposition = position - 1 ;pos = pos - 1;if (pos > 1 & ((stoplight[pos]) == 1'b1 | (fdnlight[pos]) == 1'b1))beginmylift = stop ; // stop hereendelse if (pos == 1 & ((stoplight[pos]) == 1'b1 | (fuplight[pos]) == 1'b1))beginmylift = stop ;endelsebeginmylift = doorclose ; // no req to stop or go up,closedendendstop : //beginmylift = dooropen ; //next state to openenddooropen :begindoorlight = 1'b1 ;if (udsig == 1'b0) //going upbeginif (position <= 2 & ((stoplight[position]) == 1'b1 | (fuplight[position]) == 1'b1))beginclearup = 1'b1 ;endelsebeginclearup = 1'b1 ;cleardn = 1'b1 ;endendelse if (udsig == 1'b1)beginif (position >= 2 & ((stoplight[position]) == 1'b1 | (fdnlight[position]) == 1'b1))begincleardn = 1'b1 ;endelsebeginclearup = 1'b1;cleardn = 1'b1 ;endendmylift = doorwait1 ;endendcaseendendalways @(posedge reset or posedge buttonclk) // 控制按键信号灯。
Verilog的135个经典设计实例
王金明《Verilog HDL程序设计教程》【例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- 1 - 程序文本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 #(DELY/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- 2 -王金明《Verilog HDL程序设计教程》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- 3 - 程序文本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- 4 -王金明《Verilog HDL程序设计教程》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;- 5 - 程序文本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上升沿时刻计数- 6 -王金明《Verilog HDL程序设计教程》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- 7 - 程序文本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;- 8 -王金明《Verilog HDL程序设计教程》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左移一位- 9 - 程序文本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位加法器- 10 -王金明《Verilog HDL程序设计教程》`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;- 11 - 程序文本always @(posedge clk) //进程1always过程块beginif (!reset) qout= 4'h00; //同步清0低电平有效else if (load) qout= data; //同步预置else qout=qout + 1; //加法计数endassign cout=(qout==4'hf)?1:0; //进程2用持续赋值产生进位信号【例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; //相加endcaseend- 12 -王金明《Verilog HDL程序设计教程》【例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;endendfunction【例6.5】用函数和case语句描述的编码器不含优先顺序module code_83(din,dout);input[7:0] din;output[2:0] dout;- 13 - 程序文本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;beginfactorial = opa ? 1 : 0;for(i= 2; i <= opa; i = i+1) //该句若要综合通过opa应赋具体的数值 factorial = i* factorial; //阶乘运算end- 14 -王金明《Verilog HDL程序设计教程》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】顺序执行模块2 module serial2(q,a,clk); output q,a;- 15 - 程序文本input clk;reg q,a;always @(posedge clk)begina=~q;q=~q;endendmodule【例6.10】并行执行模块1 module 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- 16 -王金明《Verilog HDL程序设计教程》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 MUXmodule 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- 17 - 程序文本【例7.4】数据流方式描述的4选1 MUXmodule 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;- 18 -王金明《Verilog HDL程序设计教程》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;- 19 - 程序文本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;- 20 -王金明《Verilog HDL程序设计教程》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);- 21 - 程序文本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与$realtime的区别`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- 22 -王金明《Verilog HDL程序设计教程》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;- 23 - 程序文本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则进位输出肯定为0 0 ? 0 : 0;0 0 ? : 0;? 1 1 : 1; //只要有两个输入为1则进位输出肯定为1 1 ? 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- 24 -王金明《Verilog HDL程序设计教程》? 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则不管其他端口为什么值输出都为0 0 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保持原值? (??) : ? : - ; //时钟不变输出也不变- 25 - 程序文本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 et 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;- 26 -王金明《Verilog HDL程序设计教程》 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; //读使能信号低电平有效- 27 - 程序文本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; //乘法运算符- 28 -王金明《Verilog HDL程序设计教程》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);endmodule module 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;- 29 - 程序文本MUX2_1 m1(out,a,b,sel); //调用待测试模块initialbegina=1'b0; b=1'b0; sel=1'b0;#5 sel=1'b1;#5 a=1'b1; el=1'b0;#5 sel=1'b1;#5 a=1'b0; b=1'b1; el=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 #(DELY/2) clk = ~clk; //产生时钟波形initialbegin //激励波形定义clk =0; reset=0;- 30 -王金明《Verilog HDL程序设计教程》#DELY reset=1;#DELY reset=0;#(DELY*300) $finish;end//结果显示initial $monitor($time,,,"clk=%d reset=%d qout=%d",clk,reset,qout);endmodule module 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);endmodule2数据流描述module gate2(F,A,B,C,D);input A,B,C,D;output F;assign F=(A&B)|(B&C&D); //assign持续赋值endmodule3行为描述module gate3(F,A,B,C,D);input A,B,C,D;output F;- 31 - 程序文本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- 32 -王金明《Verilog HDL程序设计教程》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;- 33 - 程序文本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;- 34 -王金明《Verilog HDL程序设计教程》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;。
Verilog建模实例
• 信号边沿检测器
– 要求检测输入信号的上升沿,检测到上升沿时,输 出一个有效脉冲(脉冲宽度为一个时钟周期)。 module edge_detector(in,clk,out) output out; input in, clk; reg in1, in2;
n1<=in; in2<=in1; end assign endmodule out=!in2&in1;
• 上述的信号边沿检测器对应的硬件结构 是什么? • 如果要检测的是下降沿,上面的代码怎 么修改?
[课后练习] 1. 设计一个模为N的计数器。(用 parameter来定义)
Verilog模块的部件
Verilog中的端口连接规则
• 思考:如果将上例case语句中default语句不写, 改写成如下所示的三选一数据选择器,那么它对 应的硬件结构又是什么? always @(C, D, E, s) begin case(s) 2’b00:MUX_OUT=C; 2’b01:MUX_OUT=D; 2’b10:MUX_OUT=E; endcase end
assign C=& Q & ET; assign ena=ET & EP; always @(negedge Rd_n or posedge clk) begin if (!Rd_n) Q<=0; else if (!Ld_n) Q<=D; else if (ena) Q<=Q+1; end endmodule
• 用case构造的四选一选择器 always @(C, D, E, F, s) begin case(s) 2’b00:MUX_OUT=C; 2’b01:MUX_OUT=D; 2’b10:MUX_OUT=E; default:MUX_OUT=F; endcase end 这段代码对应的硬件结构是什么?
Verilog实例讲解
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`includemodule//测试模块的名字reg[3:0] a,b; //测试输入信号定义为reg型reg cin;wire[3:0] sum; //测试输出信号定义为wire型wire cout;integer//调用测试对象always #5 cin=~cin; //设定cin的取值initialbegina=0;b=0;cin=0;for(i=1;i<16;i=i+1)#10 a=i; //设定a的取值endinitialbeginfor(j=1;j<16;j=j+1)#10 b=j; //设定b的取值endinitial//定义结果显示格式begin#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;//调用测试对象always//产生时钟波形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; //模块的输出端口为Fwire 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敏感信号列表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'd4module 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`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 endmodule5.8】阻塞赋值方式定义的2选1多路选择器module MUX21_2(out,a,b,sel);input a,b,sel;output out;reg out;always@(a or b or sel)beginif(sel==0) out=a; //阻塞赋值else out=b;endendmodule【例5.9】非阻塞赋值moduleoutput 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上升沿时刻计数if (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【例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】隐含锁存器举例moduleoutput 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;for(i=0;i<=6;i=i+1) //for语句if(vote[i]) sum=sum+1;if(sum[2]) pass=1; //若超过4人赞成,则pass=1else 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左移一位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程序设计教程》`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;程序文本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程序设计教程》【例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;endendfunction【例6.5】用函数和case语句描述的编码器(不含优先顺序)module code_83(din,dout);input[7:0] din;output[2:0] dout;程序文本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;beginfactorial = opa ? 1 : 0;for(i= 2; i <= opa; i = i+1) //该句若要综合通过,opa应赋具体的数值factorial = i* factorial; //阶乘运算王金明:《Verilog HDL程序设计教程》#DELY 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;程序文本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;assignassign 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)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(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'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;input[7:0] input_bus;assign odd_bit = ^ input_bus; //产生奇校验位assign even_bit = ~odd_bit; //产生偶校验位endmodule【例9.11】用if-else语句描述的4选1 MUXmodule mux_if(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)beginif(sel==2'b00) out=in0;else if(sel==2'b01) out=in1;else if(sel==2'b10) out=in2;else out=in3;endendmodule【例9.12】用case语句描述的4选1 MUXmodule mux_case(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)input d,clk,set,reset;assign q = reset ? 0 : (set ? 1 : (clk ? d : q));endmodule【例9.20】8位数据锁存器module latch_8(qout,data,clk);output[7:0] qout;input[7:0] data;input clk;reg[7:0] qout;always @(clk or data)beginif (clk) qout<=data;endendmodule【例9.21】8位数据寄存器module reg8(out_data,in_data,clk,clr);output[7:0] out_data;input[7:0] in_data;input clk,clr;reg[7:0] out_data;always @(posedge clk or posedge clr)beginif(clr) out_data <=0;else out_data <=in_data;endendmodule【例9.22】8位移位寄存器module shifter(din,clk,clr,dout);input din,clk,clr;output[7:0] dout;reg[7:0] dout;always @(posedge clk)beginif (clr) dout<= 8'b0; //同步清0,高电平有效elsebeginbeginif(counter==255) counter=0;else counter=counter+1;endalways@(posedge clk)beginstrb=temp; //引入一个触发器endalways@(counter)beginif(counter<=(delay-1)) temp=1;else temp=0;endendmodule【例11.1】数字跑表/*信号定义:CLK:CLK为时钟信号;CLR:为异步复位信号;PAUSE:为暂停信号;MSH,MSL:百分秒的高位和低位;SH,SL:秒信号的高位和低位;MH,ML:分钟信号的高位和低位。
第六章 Verilog HDL高级程序设计举例
10/7/2013
Microelectronics School Xidian University
7
6.2典型电路设计
• 6.2.1加法器树乘法器
加法器树乘法器的设计思想是“移位后加”,并且加法运算采用加法器 树的形式。乘法运算的过程是,被乘数与乘数的每一位相乘并且乘以 相应的权值,最后将所得的结果相加,便得到了最终的乘法结果。 例:下图是一个4位的乘法器结构,用Verilog HDL设计一个加法器树 4位乘法器
module mult_addtree_tb; reg [3:0]mult_a; reg [3:0]mult_b; wire [7:0]mult_out; // module instance mul_addtree U1(.mul_a(mult_a),.mul_b(mult_b),.mul_out(mult_out)); initial //Stimuli signal begin mult_a=0; mult_b=0; repeat(9) begin #20 mult_a=mult_a+1; mult_b=mult_b+1; end end endmodule
10/7/2013
Xidian University
11
module mult_addtree_2_stag_tb; reg clk, clr; reg [3:0]mult_a, mult_b; wire [7:0]mult_out; mul_addtree_2_stage U1(.mul_a(mult_a),.mul_b(mult_b), .mul_out(mult_out),.clk(clk),.clr(clr)); initial begin clk=0; clr=0; mult_a=1; mult_b=1; #5 clr=1; end always #10 clk=~clk; initial begin repeat(5) begin #20 mult_a=mult_a+1; mult_b=mult_b+1; end end endmodule
Verilog逻辑设计实例系列.ppt
简化的状态机的例子(续)
实际上,这个状态机就是你自己。你可能处于下 列三个状态之一:睡眠中,醒了但还在床上,或起床。 你接受两个输入:唤你醒来的闹钟和当天是否是工作日, 后者决定你对闹钟的反映态度。在这个例子中,唯一的 输出就是关掉闹钟。(这里假设你不弄坏闹钟;如果弄 坏闹钟,这个例子就需要一个“弄坏闹钟”的输出)
历史视角:有限状态机和微处理器
微处理器有三个主要部分:寄存器,算术逻 辑单元和控制单元。控制单元输入将被执行的指 令和其他的信息,如标志寄存器的值。控制单元 输出控制信号以便加载和修改寄存器的内容,执 行算术逻辑功能,存取存储器和输入/输出设备。 它按照适当的顺序输出这些信号,以便微处理器 正确读取,译码和执行每条指令。
收费站控制器(续)
收费站有两个输出灯和一个输出警铃。当车 开进收费站,红灯(R)亮,直到司机投入至少 35分为止,此时红灯灭并且绿(G)灯亮。当 汽车离开收费站的时候,绿灯灭,红灯又亮。如 果汽车没有交足费用就离开收费站,则红的一直 亮并且警铃响。直到另一辆车进入收费站时,警 铃才关闭。
该系统需要几个状态来对应已经列出的条件。 另外它还要几个额外的状态来跟踪已投入了多少 钱。下面列表描述有限状态机的状态以及它们的 输出。
收费站控制器状态
状态
SNOCAR S0 S5 S10 S15 S20 S25 S30 SPAID SCHEAT
条件 站中无车 站中有车,已付费0分 站中有车,已付费5分 站中有车,已付费10分 站中有车,已付费15分 站中有车,已付费20分 站中有车,已付费25分 站中有车,已付费30分 站中有车,已付费35分 未付满过站费车就离开收费站
微处理器的控制单元本质上是一个有限状态 机。指令和标志值是状态机的输入,控制信号是 状态机的输出。
Verilog 数字系统设计90例
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。
Verilog逻辑设计实例系列一
or
M3 (c_out,w2,w3);
endmodule
Add_half_0_delay的完整描述如下所示:
module Add_half_0_delay (sum,c_out,a,b);
output input
sum, c_out; a,b;
xor
M1 (sum,a,b);
and
M2 (c_out,a,b);
第三部分 实践篇
设计实例系列(一) Verilog 逻辑设计介绍
1. 半加器的原理图及其Verilog描述
module Add_half_0_delay (sum,c_out,a,b);
input
a,b;
output
c_out,sum;
xor
(sum,a,b);
and
(c_out,a,b);
endmodule
w1,w2,w3;
Add_half_0_delay M1 (w1,w2,a,b);
Add_half_0_delay M2 (sum,w3,c_in,w1);
or
(c_out,w2,w3);
endmodule
模块可以嵌套在其他模块内,但不能以循环 方式嵌套。当一个模块被其他模块引用时,结构 化层次就形成了嵌套和被嵌套的设计结果,这种 层次形成了一种划分,并且表示了引用嵌套和被 嵌套之间的关系。引用模块称为父模块,被引用 的模块称为子模块,即包含子模块的模块是父模 块。
endmodule
Add_rca_16 Add_rca_4 Add_rca_4 Add_rca_4 Add_rca_4
Add_full Add_full
Add_full Add_full
Verilog模块实例
一、组合逻辑电路设计实例1、8位带进位端的加法器module adder_8(cout,sum,a,b,cin);output cout;output [7:0] sum;input [7:0] a,b;input cin;assign {cout,sum}=a+b+cin;endmodule2、指令译码电路设计实例//操作码的宏定义`define plus 3'd0;`define minus 3'd1;`define band 3'd2;`define bor 3'd3;`define unegate 3'd4;module alu(out,opcode,a,b);output [7:0] out;input [2:0] opcode;input [7:0] a,b;reg [7:0] out;//用电平敏感的always块描述组合逻辑always @(opcode or a or b)begin //always后只跟一条语句,若为多句,必须用begin end块case(opcode)`plus: out=a+b;`minus: out=a-b;`band: out=a&b;`bor: out=a|b;`unegate: out=~a;default: out=8'hx;endcaseendendmodule3、3-8译码器设计实例module decoder(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;endcaseendendmodule4、利用task和电平敏感的always块设计经比较后重组信号的组合逻辑module sort4(ra,rb,rc,rd,a,b,c,d);parameter t=3;output [t:0] ra,rb,rc,rd;input [t:0] a,b,c,d;reg [t:0] ra,rb,rc,rd;always @(a or b or c or d)begin:local //此处必须加模块名local,因为该模块中定义了局部变量va,vb,vc,vdreg [t:0] va,vb,vc,vd;{va,vb,vc,vd}={a,b,c,d};sort2(va,vb);sort2(va,vc);sort2(va,vd);sort2(vb,vc);sort2(vb,vc);sort2(vc,vd);{ra,rb,rc,rd}={va,vb,vc,vd};endtask sort2;input [t:0] x,y;reg [t:0] temp;if(x>y)begintemp=x;x=y;y=temp;endendtaskendmodule5、比较器的设计实例module compare(equle,a,b);output equal;parameter size=3;input [size:0] a,b;assign equal=(a==b)?1:0;endmodule6、8-3优先编码器设计实例module encoder8_3(out,in);output [2:0] out;input [7:0] in;reg [2:0] out;always @(in or out)//这里必须包含所有下面要用到的信号beginif(in[7]) out=3'b111;else if(in[6]) out=3'b110;else if(in[5]) out=3'b101;else if(in[4]) out=3'b100;else if(in[3]) out=3'b011;else if(in[2]) out=3'b010;else if(in[1]) out=3'b001;else out=3'b000;endendmodule7、多路器设计实例module mux2(out,a,b,sel);output out;input a,b,sel;reg out;always @(a or b or sel)begincase(sel)1'b1: out=a;1'b0: out=b;defult: out='bx;endcaseendendmodule8、奇偶校验位生成器设计实例校验方法奇校验:就是让原有数据序列中(包括你要加上的一位)1的个数为奇数1000110(0)你必须添0这样原来有3个1已经是奇数了所以你添上0之后1的个数还是奇数个。
verilog经典三段式状态机设计实例
Moore型verilog源代码:FSM实现10010串的检测Moore状态转移图module moorefsm(clk,rst,a,z);input clk,rst;input a;output z;reg z;reg [3:0] currentstate,nextstate;parameter S0 = 4'b0000;parameter S1 = 4'b0001;parameter S2 = 4'b0010;parameter S3 = 4'b0011;parameter S4 = 4'b0100;parameter S5 = 4'b0101;always@(posedge clk or negedge rst)beginif(!rst)currentstate <= S0;elsecurrentstate <= nextstate;endalways@(currentstate or a or rst)beginif(!rst)nextstate = S0;elsecase(currentstate)S0: nextstate = (a==1)?S1:S0;S1: nextstate = (a==0)?S2:S1;S2: nextstate = (a==0)?S3:S1;S3: nextstate = (a==1)?S4:S0;S4: nextstate = (a==0)?S5:S1;S5: nextstate = (a==0)?S3:S1;default: nextstate = S0;endcaseendalways@(rst or currentstate)beginif(!rst)z = 0;elsecase(currentstate)S0: z = 0;S1: z = 0;S2: z = 0;S3: z = 0;S4: z = 0;S5: z = 1;default: z = 0;endcaseendendmodulemoorefsm测试模块testbench module tb_fsm;reg clk,rst;reg a;wire z;moorefsmfsm(.clk(clk),.rst(rst),.a(a),.z(z)); initialbeginclk = 0;rst = 1;#5 rst = 0;#3 rst = 1;#20 a = 1;#100 a = 1;#100 a = 0;#100 a = 0;#100 a = 1;#100 a = 0;#100 a = 0;#100 a = 1;#100 a = 0;#100 a = 0;#100 a = 0;#100 a = 0;#100 a = 1;#100 a = 0;#100 a = 0;#100 a = 1;#100 a = 0;#100 a = 1;#100 a = 0;endalways #50 clk = ~clk;endmoduleMealy型verilog源代码:FSM实现10010串的检测Mealy状态转移图module mealyfsm(clk,rst,a,z);input clk;input rst;input a;output z;reg z;reg [3:0] temp_z;reg [3:0] currentstate,nextstate;parameter S0 = 4'b0000;parameter S1 = 4'b0001;parameter S2 = 4'b0010;parameter S3 = 4'b0011;parameter S4 = 4'b0100;always@(posedge clk or negedge rst) if(!rst)currentstate <= S0;elsecurrentstate <= nextstate;always@(currentstate or a or rst)if(!rst)nextstate = S0;elsecase(currentstate)S0: nextstate = (a == 1)? S1 : S0;S1: nextstate = (a == 0)? S2 : S1;S2: nextstate = (a == 0)? S3 : S1;S3: nextstate = (a == 1)? S4 : S0;S4: nextstate = (a == 0)? S2 : S0;default:nextstate = S0;endcasealways@(rst or currentstate or a)if(!rst)temp_z = 0;elsecase(currentstate)S0: temp_z = 0;S1: temp_z = 0;S2: temp_z = 0;S3: temp_z = 0;S4: temp_z = (a == 0)? 1 : 0;default:temp_z = 0;always@(posedge clk or negedge rst)if(!rst)z <= 0;elsebeginif((temp_z == 1)&&(nextstate == S2))z <= 1;elsez <= 0;endendmodulemealyfsm测试模块testbenchmodule tb_fsm;reg clk,rst;reg a;wire z;mealyfsmfsm(.clk(clk),.rst(rst),.a(a),.z(z));initialbeginclk = 0;rst = 1;#5 rst = 0;#3 rst = 1;#20 a = 1;#100 a = 1;#100 a = 0;#100 a = 0;#100 a = 1;#100 a = 0;#100 a = 1;#100 a = 0;#100 a = 0;#100 a = 0;#100 a = 0;#100 a = 1;#100 a = 0;#100 a = 0;#100 a = 1;#100 a = 0;#100 a = 1;#100 a = 0;endalways #50 clk = ~clk; endmodule。
Verilog实例讲解
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`includemodule//测试模块的名字reg[3:0] a,b; //测试输入信号定义为reg型reg cin;wire[3:0] sum; //测试输出信号定义为wire型wire cout;integer//调用测试对象always #5 cin=~cin; //设定cin的取值initialbegina=0;b=0;cin=0;for(i=1;i<16;i=i+1)#10 a=i; //设定a的取值endinitialbeginfor(j=1;j<16;j=j+1)#10 b=j; //设定b的取值endinitial//定义结果显示格式begin#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;//调用测试对象always//产生时钟波形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; //模块的输出端口为Fwire 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敏感信号列表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'd4module 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`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 endmodule5.8】阻塞赋值方式定义的2选1多路选择器module MUX21_2(out,a,b,sel);input a,b,sel;output out;reg out;always@(a or b or sel)beginif(sel==0) out=a; //阻塞赋值else out=b;endendmodule【例5.9】非阻塞赋值moduleoutput 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上升沿时刻计数if (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【例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】隐含锁存器举例moduleoutput 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;for(i=0;i<=6;i=i+1) //for语句if(vote[i]) sum=sum+1;if(sum[2]) pass=1; //若超过4人赞成,则pass=1else 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左移一位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程序设计教程》`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;程序文本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程序设计教程》【例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;endendfunction【例6.5】用函数和case语句描述的编码器(不含优先顺序)module code_83(din,dout);input[7:0] din;output[2:0] dout;程序文本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;beginfactorial = opa ? 1 : 0;for(i= 2; i <= opa; i = i+1) //该句若要综合通过,opa应赋具体的数值factorial = i* factorial; //阶乘运算王金明:《Verilog HDL程序设计教程》#DELY 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;程序文本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;assignassign 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)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(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'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;input[7:0] input_bus;assign odd_bit = ^ input_bus; //产生奇校验位assign even_bit = ~odd_bit; //产生偶校验位endmodule【例9.11】用if-else语句描述的4选1 MUXmodule mux_if(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)beginif(sel==2'b00) out=in0;else if(sel==2'b01) out=in1;else if(sel==2'b10) out=in2;else out=in3;endendmodule【例9.12】用case语句描述的4选1 MUXmodule mux_case(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)input d,clk,set,reset;assign q = reset ? 0 : (set ? 1 : (clk ? d : q));endmodule【例9.20】8位数据锁存器module latch_8(qout,data,clk);output[7:0] qout;input[7:0] data;input clk;reg[7:0] qout;always @(clk or data)beginif (clk) qout<=data;endendmodule【例9.21】8位数据寄存器module reg8(out_data,in_data,clk,clr);output[7:0] out_data;input[7:0] in_data;input clk,clr;reg[7:0] out_data;always @(posedge clk or posedge clr)beginif(clr) out_data <=0;else out_data <=in_data;endendmodule【例9.22】8位移位寄存器module shifter(din,clk,clr,dout);input din,clk,clr;output[7:0] dout;reg[7:0] dout;always @(posedge clk)beginif (clr) dout<= 8'b0; //同步清0,高电平有效elsebeginbeginif(counter==255) counter=0;else counter=counter+1;endalways@(posedge clk)beginstrb=temp; //引入一个触发器endalways@(counter)beginif(counter<=(delay-1)) temp=1;else temp=0;endendmodule【例11.1】数字跑表/*信号定义:CLK:CLK为时钟信号;CLR:为异步复位信号;PAUSE:为暂停信号;MSH,MSL:百分秒的高位和低位;SH,SL:秒信号的高位和低位;MH,ML:分钟信号的高位和低位。
数字模块实例-Verilog
一、加、减法器 (2)1、半加器 (2)2、全加器 (2)3、串行进位加法器(行波进位加法器) (4)4、超前进位加法器(先行进位加法器) (4)5、进位链加法器、跳跃进位加法器 (7)6、进位旁路加法器、线性进位选择加法器等 (9)7、减法器 (9)二、乘法器 (10)1、定点原码乘法器 (10)2、加法树乘法器 (12)3、查找表乘法器 (13)4、布尔乘法器 (14)三、CORDIC数字计算机 (18)四、Johnson计数器 (21)五、移位寄存器 (22)1、串并转换模块 (22)2生成伪随机数及伪随机序列应用设计 (24)3桶形移位寄存器(循环移位寄存器) (27)六、编码译码器 (29)1、差错控制编码 (29)2、HDB3编码与译码 (37)3曼彻斯特编译码器 (39)RS(204,188)译码器 (46)4、Gray码与二进制码的转换 (46)5、NRZI编码 (46)七、加密解密模块 (48)1、DES加密模块 (48)一、加、减法器1、半加器半加器:输入为两个二进制数,输出产生两个二进制数,一个和位、一个进位,不包括来自低位的进位。
逻辑表达式为:,其电路符号为:2、全加器在将两个多位二进制数相加时,除了最低位以外,每一位都应该考虑来自低位的进位,这种运算为全加,其电路为全加器。
逻辑表达式为:电路图:由半加器组成的结构如下:Verilog模型或3、串行进位加法器(行波进位加法器)依次将低位全加器的进位输出端CO接到高位全加器的进位输入端CI,就可以构成多位加法器。
// 二进制行波进位加法器module ripple_carry_adder(x, y, cin, sum, cout);parameter N = 8;input cin;input [N-1:0] x, y;output [N-1:0] sum;output cout;reg cout;reg [N-1:0] sum;reg q[N:0];always @(x or y or cin)begin:ADDERinteger i;q[0] = cin;for(i=0; i<=N-1; i=i+1)beginq[i+1] = (x[i]&y[i]) | (x[i]&q[i]) | (y[i]&q[i]);sum[i] = x[i] ^ y[i] ^ q[i];endcout = q[N];endendmodule4、超前进位加法器(先行进位加法器)产生进位输出的情况是AB=1、A+B=1且CI=1,则得:即高位的进位输入不用等到低位计算完后就可得到,提高了计算速度,其电路结构如下:其电路符号Verilog描述:GP生成器:使用两个一位加法器与一个GP生成器设计两位的超前进位加法器同样可以进行继续扩展5、进位链加法器、跳跃进位加法器module carry_chain_adder(x, y, cin, sum, cout);parameter DSIZE = 8;input cin;input [DSIZE-1:0] x, y;output [DSIZE-1:0] sum;output cout;reg cout, q[DSIZE:0], p[DSIZE-1:0], g[DSIZE-1:0];reg [DSIZE-1:0] sum;always @(x or y or cin)begin:ADDERinteger i;q[0] = cin;for(i=0; i<DSIZE; i=i+1)beginp[i] = x[i]^y[i];g[i] = y[i];q[i+1] = (p[i])?q[i]:g[i];sum[i] = p[i]^q[i];endcout = q[DSIZE];endendmodule// 二进制跳跃进位加法器module carry_skip_adder(x_in, y_in, c_in, sum, c_out);parameter DSIZE = 12;parameter S = 4;input c_in;input [DSIZE-1:0] x_in, y_in;output [DSIZE-1:0] sum;reg [DSIZE-1:0] sum;output c_out;reg c_out;integer i, j;reg [DSIZE:0] q;always @(x_in or y_in or c_in)beginq[0] = c_in;begincarry_skip_add_cell(x_in[S-1:0], y_in[S-1:0],q[0], q[S:1]);for(j=0; j<=S-1; j=j+1)sum[j] = x_in[j] ^ y_in[j] ^ q[j];carry_skip_add_cell(x_in[2*S-1:S], y_in[2*S-1:S],q[S], q[2*S:S+1]);for(j=0; j<=S-1; j=j+1)sum[S+j] = x_in[S+j] ^ y_in[S+j] ^ q[S+j];carry_skip_add_cell(x_in[3*S-1:2*S], y_in[3*S-1:2*S],q[2*S], q[3*S:2*S+1]);for(j=0; j<=S-1; j=j+1)sum[2*S+j] = x_in[2*S+j] ^ y_in[2*S+j] ^ q[2*S+j];endc_out = q[DSIZE];end// S比特分组进位链task carry_skip_add_cell;input [S-1:0] x, y;input cin;output [S:1] cout;reg q[S:0], p[S-1:0], g[S-1:0], accumulator, generalized_p;integer i;beginq[0] = cin;for(i=0; i<=S-1; i=i+1)beginp[i] = x[i]^y[i];g[i] = y[i];q[i+1] = (p[i])?q[i]:g[i];endaccumulator = p[0];for(i=1; i<=S-1; i=i+1)accumulator = accumulator & p[i];generalized_p = accumulator;cout[S] = (generalized_p) ? c_in : q[S];for(i=1; i<=S-1; i=i+1)cout[i] = q[i];endendtaskendmodule6、进位旁路加法器、线性进位选择加法器等7、减法器Verilog模型如下:二、乘法器1、定点原码乘法器乘数与被乘数分别载入两个寄存器R1与R2中。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
//操作码 //操作数 //电平敏感的 always 块
//加操作 //减操作 //求与 //求或 //求反 //未收到指令时,输出任意态
【例 5.4】用 initial 过程语句对测试变量 A、B、C 赋值
`timescale 1ns/1ns module test; reg A,B,C; initial
【例 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)
王金明:《Verilog HDL 程序设计教程》
【例 3.2】4 位计数器
module count4(out,reset,clk);
output[3:0] out;
input reset,clk;
reg[3:0] out;
always @(posedge clk)
begin
if (reset) out<=0;
end
endmodule
//clk 上升沿触发
//同步清 0,低电平有效 //同步预置 //计数
【例 5.3】用 always 过程语句描述的简单算术逻辑单元
`define add 3'd0 `define minus 3'd1 `define band 3'd2 `define bor 3'd3 `define bnot 3'd4
//模块名为 AOI(端口列表 A,B,C,D,F) //模块的输入端口为 A,B,C,D //模块的输出端口为 F
wire A,B,C,D,F; assign F= ~((A&B)|(C&D));
endmodule
王金明:《Verilog HDL 程序设计教程》 //定义信号的数据类型 //逻辑功能描述
output[7:0] qout;
output cout;
input[7:0] data;
input load,cin,clk,reset;
reg[7:0] qout; always @(posedge clk)
//clk 上升沿时刻计数
-6-
王金明:《Verilog HDL 程序设计教程》
begin if (reset) else if(load)
【例 5.8】阻塞赋值方式定义的 2 选 1 多路选择器
module MUX21_2(out,a,b,sel); input a,b,sel;
-5-
程序文本
output out; reg out;
always@(a or b or sel)
begin
if(sel==0) out=a;
else end
4'd8:decodeout=7'b1111111;
4'd9:decodeout=7'b1111011;
default: decodeout=7'bx;
endcase
end
-7-
程序文本 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)
output[7:0] out;
input[7:0] data;
input load,clk,reset;
reg[7:0] out;
always @(posedge clk)
begin
if (!reset)
out = 8'h00;
else if (load) out = data;
else
out = out + 1;
//设定 a 的取值
end
-1-
程序文本
initial begin for(j=1;j<16;j=j+1) #10 b=j; end
//设定 b 的取值
initial
//定义结果显示格式
begin
$monitor($time,,,"%d + %d + %b={%b,%d}",a,b,cin,cout,sum);
-3-
程序文本 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) begin case(opcode) `add: out = a+b; `minus: out = a-b; `band: out = a&b; `bor: out = a|b; `bnot: out=~a; default: out=8'hx; endcase end endmodule
qout<=0; qout<=data;
//同步复位 //同步置数
else if(cin)
begin if(qout[3:0]==9)
//低位是否为 9,是则
begin qout[3:0]<=0;
//回 0,并判断高位是否为 5
if (qout[7:4]==5) qout[7:4]<=0;
else qout[7:4]<=qout[7:4]+1;
else
out<=out+1;
end
endmodule
//同步复位 //计数
【例 3.3】4 位全加器的仿真程序
`timescale 1ns/1ns `include "adder4.v" module adder_tp; reg[3:0] a,b; reg cin; wire[3:0] sum; wire cout; integer i,j;
out=b;
endmodule
【例 5.9】非阻塞赋值
module non_block(c,b,a,clk);
output c,b; input clk,a;
reg c,b;
always @(posedge clk)
begin
b<=a; c<=b; end
endmodule
//阻塞赋值
【例 5.10】阻塞赋值
#160 $finish; end
endmodule
【例 3.4】4 位计数器的仿真程序
`timescale 1ns/1ns `include "count4.v" module coun4_tp; reg clk,reset; wire[3:0] out; parameter DELY=100;
//测试输入信号定义为 reg 型 //测试输出信号定义为 wire 型
【例 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
//敏感信号列表
case(sel)
2'b00: out=in0;
2'b01: out=in1;
2'b10: out=in2;
2'b11: out=in3;
default: out=2'bx;
endcase
endmodule
【例 5.2】同步置数、同步清零的计数器
module count(out,data,load,reset,clk);
【例 5.6】用 fork-join 并行块产生信号波形
`timescale 10ns/1ns module wave2; reg wave; parameter cycle=5; initial
fork wave=0;
#(cycle) wave=1; #(2*cycle) wave=0; #(3*cycle) wave=1; #(4*cycle) wave=0; #(5*cycle) wave=1; #(6*cycle) $finish; join initial $monitor($time,,,"wave=%b",wave); endmodule
begin -4-
王金明:《Verilog HDL 程序设计教程》 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 ; end initial $monitor($time,,,"wave=%b",wave); endmodule
//高位不为 5,则加 1
end else
//低位不为 9,则加 1
qout[3:0]<=qout[3:0]+1;
end
end assign cout=((qout==8'h59)&cin)?1:0;
//产生进位输出信号
endmodule
【例 5.12】BCD 码—七段数码管显示译码器
module decode4_7(decodeout,indec);