verilog的15个经典设计实例
Verilog设计练习十例及答案

设计练习进阶前言:在前面九章学习的基础上,通过本章的练习,一定能逐步掌握Verilog HDL设计的要点。
我们可以先理解样板模块中每一条语句的作用,然后对样板模块进行综合前和综合后仿真,再独立完成每一阶段规定的练习。
当十个阶段的练习做完后,便可以开始设计一些简单的逻辑电路和系统。
很快我们就能过渡到设计相当复杂的数字逻辑系统。
当然,复杂的数字逻辑系统的设计和验证,不但需要系统结构的知识和经验的积累,还需要了解更多的语法现象和掌握高级的Verilog HDL系统任务,以及与C语言模块接口的方法(即PLI),这些已超出的本书的范围。
有兴趣的同学可以阅读Verilog语法参考资料和有关文献,自己学习,我们将在下一本书中介绍Verilog较高级的用法。
练习一.简单的组合逻辑设计目的: 掌握基本组合逻辑电路的实现方法。
这是一个可综合的数据比较器,很容易看出它的功能是比较数据a与数据b,如果两个数据相同,则给出结果1,否则给出结果0。
在Verilog HDL中,描述组合逻辑时常使用assign 结构。
注意equal=(a==b)1:0,这是一种在组合逻辑实现分支判断时常使用的格式。
模块源代码:" qual(equal),.a(a),.b(b)); 简单时序逻辑电路的设计目的:掌握基本时序逻辑电路的实现。
在Verilog HDL中,相对于组合逻辑电路,时序逻辑电路也有规定的表述方式。
在可综合的Verilog HDL模型,我们通常使用always块和@(posedge clk)或@(negedge clk)的结构来表述时序逻辑。
下面是一个1/2分频器的可综合模型。
eset(reset),.clk_in(clk),.clk_out(clk_out));endmodule仿真波形:练习:依然作clk_in的二分频clk_out,要求输出与上例的输出正好反相。
编写测试模块,给出仿真波形。
练习三. 利用条件语句实现较复杂的时序逻辑电路目的:掌握条件语句在Verilog HDL中的使用。
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_FPGA实例

一、组合逻辑实验 (2)实验13X8译码器程序 (2)实验2二-十进制译码器 (2)实验3BCD码—七段数码管显示译码器 (3)实验48-3编码器 (4)实验58-3优先编码器 (4)实验6十—二进制编码器 (5)实验7三选一数据选择器 (5)实验8半加器 (6)实验9全加器 (7)实验10半减器 (8)实验11全减器 (8)实验12多位数值比较器 (9)实验13奇偶校验 (9)实验14补码生成 (10)实验158位硬件加法器的设计 (10)实验164位并行乘法器 (10)实验17七人表决器 (10)实验18格雷码变换 (11)二、时序逻辑实验 (11)实验1D触发器 (11)实验2JK触发器 (12)实验3四位移位寄存器 (12)实验4异步计数器 (13)实验5同步计数器 (14)实验6可逆计数器 (15)实验7步长可变的加减计数器 (16)实验8含异步清0和同步时钟使能的4位加法计数器 (17)实验9顺序脉冲发生器 (18)实验10序列信号发生器 (18)实验11用状态机实现串行数据检测器 (19)实验12分频器 (20)实验13Moore状态机 (21)实验14Mealy状态机 (23)实验15三层电梯 (24)实验16性线反馈移位寄存器(LFSR)设计 (32)实验17正负脉宽数控调制信号发生器 (32)三、存储器设计 (34)实验1只读存储器(ROM) (34)实验2SRAM (34)实验3FIFO (35)四、扩展接口实验 (39)实验1流水灯 (39)实验2VGA彩色信号显示控制器设计 (40)实验3PS/2键盘接口实验 (48)实验4PS/2鼠标接口实验 (49)五、综合实验 (58)实验1函数发生器 (58)实验2自动售货机 (61)实验3移位相加4位硬件乘法器电路设计 (63)一、组合逻辑实验实验13X8译码器程序//Decoder:3-to8decoder 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实验3BCD码—七段数码管显示译码器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实验48-3编码器//a8-3codermodule 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实验58-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@(d0or d1or d2or d3or d4or d5or d6or 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//1bit full adder1位全加器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 I1or I2or 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实验158位硬件加法器的设计//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实验164位并行乘法器//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,DATA_OUT);input EN;input[3:0]DATA_IN;output[3:0]DATA_OUT;assign DATA_OUT[0]=(DATA_IN[0]^DATA_IN[1])&&EN; assign DATA_OUT[1]=(DATA_IN[1]^DATA_IN[2])&&EN; assign DATA_OUT[2]=(DATA_IN[2]^DATA_IN[3])&&EN; assign DATA_OUT[3]=DATA_IN[3]&&EN;endmodule二、时序逻辑实验实验1D触发器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实验2JK触发器//带异步清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,//state0s1=8'b1100_0001,//state1s2=8'b1110_0000,//state2s3=8'b0001_0000,s4=8'b1111_1000,s5=8'b0000_0011,s6=8'b1111_0011,s7=8'b0000_0001;//state7always@(posedge clk)beginif(clr)yt<=s0;//clear to state0elsebegincase(yt)s0:yt<=s1;//change from state0to state1s1:yt<=s2;//s2:yt<=s3;//state2-->3s3:yt<=s4;s4:yt<=s5;s5:yt<=s6;s6:yt<=s7;s7:yt<=s0;//state7to state0default:yt<=s0;//default state7to 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;//8statesalways@(posedge clk)//定义起始状态begincstate<=nextstate;endalways@(cstate or instr)//定义状态转换begincase(cstate)s0:begin got<=0;if(instr)nextstate<=s1;//detected the1st bit of1110010,i.e.,1,to s1else nextstate<=s0;//if not,stay hereends1:begin got<=0;if(instr)nextstate<=s2;//detected the2nd bit of1110010,i.e.,1,to s2else nextstate<=s0;//notends2:begin got<=0;if(instr)nextstate<=s3;//detected the3rd bit of1110010,i.e.,1else nextstate<=s0;//notends3:begin got<=0;if(!instr)nextstate<=s4;//detected the4th bit of1110010,i.e.,0else nextstate<=s2;//not,stayends4:begin got<=0;if(!instr)nextstate<=s5;//detected the5th bit of1110010,i.e.,0else nextstate<=s1;//notends5:begin got<=0;f(instr)nextstate<=s6;//detected the6th bit of1110010,i.e.,1else nextstate<=s0;//notends6:begin got<=0;if(!instr)nextstate<=s7;//detected the7th bit of1110010,i.e.,0else nextstate<=s2;//notends7:begin got<=1;//got the sequenceif(instr)nextstate<=s1;//detected the1st bit of1110010,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实验13Moore状态机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实验14Mealy状态机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;//from1st floor to upstairsinput f2upbutton;//from2nd floor to upstairsinput f2dnbutton;//from2nd floor to downstairsinput f3dnbutton;//from3rd floor to downstairsinput stop1button;//signal to stop the lift on floor1input stop2button;//stop on floor2input stop3button;//stop on floor3output[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:floor1clearup=1'b0;//clear upcleardn=1'b0;//clear downendelsebegincase(mylift)//FSMstopon1:///stop on floor1begindoorlight=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://after4seconds,close the doorbegindoorlight=1'b0;if(udsig==1'b0)//going upbeginif(position==3)//on floor3beginif(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 floor2beginif(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 floor1beginif(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)//控制按键信号灯beginif(reset==1'b1)//asyn resetbeginstoplight=3'b000;fuplight=2'b00;fdnlight=2'b00;endelse//posedge buttonclkbeginif(clearup==1'b1)//begin//内部停靠信号灯和外部上升请求信号灯灭stoplight[position]=1'b0;fuplight[position]=1'b0;endelse//beginif(f1upbutton==1'b1)beginfuplight[1]=1'b1;endelse if(f2upbutton==1'b1)beginfuplight[2]=1'b1;endendif(cleardn==1'b1)beginstoplight[position]=1'b0;fdnlight[position]=1'b0;endelsebeginif(f2dnbutton==1'b1)beginfdnlight[2]=1'b1;endelse if(f3dnbutton==1'b1)beginfdnlight[3]=1'b1;endendif(stop1button==1'b1)beginstoplight[1]=1'b1;endelse if(stop2button==1'b1)beginstoplight[2]=1'b1;endelse if(stop3button==1'b1)beginstoplight[3]=1'b1;endendendendmodule//分频器部分,获得电梯运行(慢)和扫描按键请求的时钟(快)module clk_div(clk_10hz,clk_1hz,clk_in);input clk_in;output clk_1hz,clk_10hz;reg clk_1hz,clk_10hz;reg[25:0]counter1;//50_000_000=1011_1110_1011_1100_0010_0000_00 reg[22:0]counter2;//5,000,000=1001_1000_1001_0110_1000_000parameter cnt1=50_000_000;///50MHz is the sys clk,50_000_000=2FAF080,1HZ parameter cnt2=5_000_000;//to10HZalways@(posedge clk_in)begincounter1<=counter1+1;if(counter1==cnt1/2-1)beginclk_1hz<=!clk_1hz;counter1<=0;endend///clk_10hz,10HZalways@(posedge clk_in)begincounter2<=counter2+1;if(counter2==cnt2/2-1)beginclk_10hz<=!clk_10hz;counter2<=0;endendendmodule。
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-a写的一些电路模块的例子

用verilog-a写的一些电路模块的例子以下是几个用Verilog-A 语言编写的电路模块的例子:1. 增益电路模块````include "disciplines.vams"module gain_circuit(va, vb, vout, g);input va, vb;output vout;parameter real g=10.0;analog beginvout = g * (va - vb);endendmodule```这个例子展示了一个简单的增益电路模块,其中输入是两个电压va、vb,输出是vout,增益系数为g。
在模块中使用了Verilog-A 的`analog begin` 语句来定义电路的行为。
2. RC 低通滤波器模块````include "disciplines.vams"module rc_lowpass_filter(vin, vout, r, c);input vin;output vout;parameter real r=1.0, c=1e-6;real v1;analog begini(vin, v1) <+ (vin - v1)/(r*c);vout <+ v1;endendmodule```这个例子展示了一个基于RC 电路的低通滤波器模块,其中输入为vin,输出为vout,RC 电路的参数由r 和c 决定。
在模块中使用了Verilog-A 的`i()` 语句来定义电路的行为。
3. 三角波发生器模块````include "disciplines.vams"module triangle_wave_generator(vout, freq, amp, dc);output vout;parameter real freq=1e3, amp=1.0, dc=0.0;real t;analog begint = $abstime;vout <+ amp * (2 * (t * freq - floor(t * freq + 0.5)) - 1) + dc;endendmodule```这个例子展示了一个简单的三角波发生器模块,其中输出为vout,频率由freq 决定,幅值由amp 决定,直流分量由dc 决定。
Verilog建模示例

奇数分频电路
• 错位异或法:对占空比为50%的N倍奇数分频 • 首先进行上升沿出发的模N奇数,到某选定值时输出翻转,然后经 (N-1)/2再次翻转,得到一奇数N分频时钟; • 其次进行下降沿出发的模N记数,到某选定值时输出翻转,然后经 (N-1)/2再次翻转,也得到一奇数N分频时钟; • 将两个信号进行或运算
e a b y
3-8译码器
module decode3to8(din,reset,dout); input [2:0] din; input reset_n; output [7:0] dout; reg [7:0] dout; always @(din or reset) begin if (!reset_n) dout = 8’b0000_0000; else case (din) 1’b000: dout = 8’b0000_0001; 1’b001: dout = 8’b0000_0010; 1’b010: dout = 8’b0000_0100; 1’b011: dout = 8’b0000_1000; 1’b100: dout = 8’b0001_0000; 1’b101: dout = 8’b0010_0000; 1’b110: dout = 8’b0100_0000; 1’b111: dout = 8’b1000_0000; endcase end endmodule
二always块状态机
A/Z=0/1 A/Z=0/0
S0
A/Z=1/0
S3
A/Z=1/1
A/Z=0/0
A/Z=1/1
A/Z=0/0
S1
A/Z=1/1
S2
二always块状态机
module mealy_fsm(z,a, clk, rst_n); parameter S0 = 0,S1 = 1,S2 = 2,S3 = 3; output z; input a,clk,rst_n; reg z; reg [1:0] state,new_state; always @(posedge clk or negedge rst_n) if (~rst_n) state <= S0; else state <= new_state; end always @(state or a) case (state) s0: if (a) begin z = 1; new_state = S2; end else z = 0;
verilog基本电路设计(包括:时钟域同步、无缝切换、异步fifo、去抖滤波))

Verilog基本电路设计(包括:时钟域同步、无缝切换、异步FIFO、去抖滤波))Verilog基本电路设计共包括四部分:单bit跨时钟域同步时钟无缝切换异步FIFO去抖滤波Verilog基本电路设计之一: 单bit跨时钟域同步(帖子链接:/thread-605419-1-1.html)看到坛子里不少朋友,对于基本数字电路存在这样那样的疑惑,本人决定开贴,介绍数字电路最常见的模块单元,希望给初学者带来帮助,也欢迎大佬们前来拍砖。
如果想要做数字设计,下面这些电路是一定会碰到的,也是所有大型IP,SOC设计必不可少的基础,主要包括异步信号的同步处理,同步FIFO,异步FIFO,时钟无缝切换,信号滤波debounce等等,后面会根据大家反馈情况再介绍新电路。
首先介绍异步信号的跨时钟域同步问题。
一般分为单bit的控制信号同步,以及多bit的数据信号同步。
多bit的信号同步会使用异步FIFO完成,而单bit的信号同步,又是时钟无缝切换电路以及异步FIFO电路的设计基础,这里先介绍单bit信号同步处理。
clka域下的信号signal_a,向异步的clkb域传递时,会产生亚稳态问题。
所有的亚稳态,归根结底就是setup/hold时间不满足导致。
在同一个时钟域下的信号,综合以及布线工具可以在data路径或者clock路径上插入buffer使得每一个DFF的setup/hold时间都满足;但是当signal_a在clkb域下使用时,由于clka与clkb异步,它们的相位关系不确定,那么在clkb的时钟沿到来时,无法确定signal_a此时是否处于稳定无变化状态,也即setup/hold时间无法确定,从而产生亚稳态。
这种异步信号在前后端流程里面是无法做时序分析的,也就是静态时序分析里常说的false_path。
消除亚稳态,就是采用多级DFF来采样来自另一个时钟域的信号,级数越多,同步过来的信号越稳定。
对于频率很高的设计,建议至少用三级DFF,而两级DFF同步则是所有异步信号处理的最基本要求。
verilog多模块编程实例

Verilog多模块编程实例1. 介绍Verilog是一种硬件描述语言,被广泛应用于数字电路设计。
Verilog具有模块化设计的特点,可以将一个大型的电路设计分解成多个小模块,然后逐个实现和调试。
本文将介绍Verilog多模块编程的实例,以帮助读者了解如何使用Verilog进行模块化设计。
2. 模块化设计的优势模块化设计是一种将大型系统分解成多个小模块的设计方法。
在Verilog中,模块化设计有以下几个优势:- 提高代码可读性:通过将大型系统分解成多个小模块,可以提高代码的可读性和可维护性。
- 便于调试:每个小模块相对独立,可以单独调试和测试,提高了系统的可靠性和稳定性。
- 提高复用性:将功能相似的代码封装成模块,可以提高代码的复用性,减少代码冗余。
3. 多模块编程实例接下来,我们将通过一个简单的数字电路设计来演示Verilog多模块编程的实例。
假设我们要设计一个4位全加器电路,首先我们需要实现一个单位全加器模块,然后将四个单元全加器模块连接成一个4位全加器模块。
3.1 单位全加器模块我们定义一个单位全加器模块,代码如下:```verilogmodule Adder_unit (input a, b, cin,output sum, cout);assign {cout, sum} = a + b + cin;endmodule```在单位全加器模块中,我们定义了三个输入信号a、b、cin和两个输出信号sum、cout。
其中,sum表示相加的结果,cout表示进位。
在模块内部,我们通过assign语句实现了全加器的功能。
3.2 4位全加器模块接下来,我们将四个单位全加器模块连接成一个4位全加器模块,代码如下:```verilogmodule Adder_4bit (input [3:0] a, b,input cin,output [3:0] sum,output cout);Adder_unit U0(.a(a[0]), .b(b[0]), .cin(cin), .sum(sum[0]), .cout(cout0));Adder_unit U1(.a(a[1]), .b(b[1]), .cin(cout0), .sum(sum[1]), .cout(cout1)); Adder_unit U2(.a(a[2]), .b(b[2]), .cin(cout1), .sum(sum[2]), .cout(cout2)); Adder_unit U3(.a(a[3]), .b(b[3]), .cin(cout2), .sum(sum[3]), .cout(cout));endmodule```在4位全加器模块中,我们首先定义了四个输入信号a、b和一个输入信号cin,以及四个输出信号sum和一个输出信号cout。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
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;
reg[7:0] qout; always @(posedge clk)
//clk 上升沿时刻计数
-6-
王金明:《Verilog HDL 程序设计教程》
begin if (reset) else if(load)
//设定 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);
//敏感信号列表
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,则加 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);
end //定义结果显示格式
initial $monitor($time,,,"clk=%d reset=%d out=%d", clk, reset,out);
endmodule
【例 3.5】“与-或-非”门电路
module AOI(A,B,C,D,F); input A,B,C,D; output F; -2-
begin A = 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 ; end endmodule
【例 5.5】用 begin-end 串行块产生信号波形
`timescale 10ns/1ns module wave1; reg wave; parameter cycle=10; initபைடு நூலகம்al
王金明:《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;
count4 mycount(out,reset,clk);
//调用测试对象
always #(DELY/2) clk = ~clk;
//产生时钟波形
initial begin
//激励信号定义
clk =0; reset=0;
#DELY reset=1;
#DELY reset=0;
#(DELY*20) $finish;
【例 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
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;
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;
output[6:0] decodeout;
input[3:0] indec;
reg[6:0] decodeout;
always @(indec)
begin case(indec)
//用 case 语句进行译码
4'd0:decodeout=7'b1111110;
4'd1:decodeout=7'b0110000;
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)
-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
#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 型
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】阻塞赋值
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