当前位置:文档之家› 硬件描述语言范例

硬件描述语言范例

硬件描述语言语言设计实例1、8-3编码器module encode_verilog ( a ,b );input [7:0] a ; //编码器输入wire [7:0] a ;output [2:0] b ; //编码器输出reg [2:0] b;always @ ( a )begincase ( a ) //编码器某一输入端口为高电平输出相应的3位二进制数8'b0000_0001 : b<=3'b000; //08'b0000_0010 : b<=3'b001; //18'b0000_0100 : b<=3'b010; //28'b0000_1000 : b<=3'b011; //38'b0001_0000 : b<=3'b100; //48'b0010_0000 : b<=3'b101; //58'b0100_0000 : b<=3'b110; //68'b1000_0000 : b<=3'b111; //7default : b<= 3'b000; //其他情况编码器输出3’b000endcaseendendmodule2、8-3优先编码器module p_encode_verilog ( A ,I ,GS ,EO ,EI ); //编码器以低为有效input [7:0] I ; //编码器输入wire [7:0] I ;input EI ; //输入使能,EI=0时,编码器正常工作wire EI ;output [2:0] A ; //编码器输出reg [2:0] A ;output GS ; //优先编码器工作状态标志,编码器的八个输入端有信号输入时,GS=0 reg GS ;output EO ; //输出使能,reg EO ;always @ ( I or EI )if ( EI ) //使用if、else if表明条件的优先级顺序beginA <= 3'b111;GS <= 1;EO <= 1;endelse if ( I[7] == 0 )beginA <= 3'b000;GS <= 0;EO <= 1;endelse if ( I[6] == 0 )beginA <= 3'b001;GS <= 0;EO <= 1;endelse if ( I[5] == 0 )beginA <= 3'b010;GS <= 0;EO <= 1;endelse if ( I[4] == 0 )beginA <= 3'b011;GS <= 0;EO <= 1;endelse if ( I[3] == 0 )beginA <= 3'b100;GS <= 0;EO <= 1;endelse if ( I[2] == 0 )beginA <= 3'b101;GS <= 0;EO <= 1;endelse if ( I[1] == 0 )beginA <= 3'b110;GS <= 0;EO <= 1;endelse if ( I[0] == 0 )beginA <= 3'b111;GS <= 0;EO <= 1;endelse if ( I == 8'b11111111)beginA <= 3'b111;GS <= 1;EO <= 0;endendmodule3、3-8译码器module decoder_verilog ( G1 ,Y ,G2 ,A ,G3 ); input G1 ; //使能输入,高有效wire G1 ;input G2 ; //使能输入,低有效wire G2 ;input [2:0] A ; //3位译码器输入,为高有效wire [2:0] A ;input G3 ; //使能输入wire G3 ; //使能输入,低有效output [7:0] Y ; //8位译码器输出,为低有效reg [7:0] Y ;reg s;always @ ( A ,G1, G2, G3)begins <= G2 | G3 ;if ( G1 == 0) //G1为低有效Y <= 8'b1111_1111;else if ( s)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;endcaseendendmodule4、数据选择器module mux8_1_verilog ( Y ,A ,D0, D1,D2, D3, D4, D5, D6, D7 ,G );input [2:0] A ; //地址输入端wire [2:0] A ;input D0 ; //数据输入端input D1 ; //数据输入端input D2 ; //数据输入端input D3 ; //数据输入端input D4 ; //数据输入端input D5 ; //数据输入端input D6 ; //数据输入端input D7 ; //数据输入端input G ; //使能端,当G=1时Y=0,当G=0时数据选择器正常工作wire G ;output Y ; //数据输出端reg Y ;always @(G or A or D0 or D1 or D2 or D3or D4 or D5 or D6 or D7 )beginif (G == 1) //使能端的优先级高Y <= 0;elsecase (A ) //根据输入的地址A确定数据选择器输出哪路输入数据3'b000 : Y = D0 ;3'b001 : Y = D1 ;3'b010 : Y = D2 ;3'b011 : Y = D3 ;3'b100 : Y = D4 ;3'b101 : Y = D5;3'b110 : Y = D6 ;3'b111 : Y = D7 ;default : Y = 0;endcaseendendmodule5、多位数值比较器module compare_verilog ( Y ,A ,B );input [3:0] A ; //4位二进制数Awire [3:0] A ;input [3:0] B ; //4位二进制数Bwire [3:0] B ;output [2:0] Y ; //A与B大小的比较结果reg [2:0] Y ;always @ ( A or B )beginif ( A > B )Y <= 3'b001; //A > B时Y输出3'b001 else if ( A == B)Y <= 3'b010; //A = B时Y输出3'b010 elseY <= 3'b100; //A < B时Y输出3'b100 endendmodule6、全加器module sum_verilog ( A ,Co ,B ,S ,Ci );input A ; //输入加数Awire A ;input B ; //输入加数Bwire B ;input Ci ; //相邻低位的进位输入信号wire Ci ;output Co ; //向相邻高位的进位输出信号reg Co ;output S ; //相加和数输出reg S ;always @ ( A or B or Ci)beginif ( A== 0 && B == 0 && Ci == 0 )beginS <= 0;Co <= 0;endelse if ( A== 1 && B == 0 && Ci == 0 )beginS <= 1;Co <= 0;endelse if ( A== 0 && B == 1 && Ci == 0 )beginS <= 1;Co <= 0;endelse if ( A==1 && B == 1 && Ci == 0 )beginS <= 0;Co <= 1;endelse if ( A== 0 && B == 0 && Ci == 1 )beginS <= 1;Co <= 0;endelse if ( A== 1 && B == 0 && Ci == 1 )beginS <= 0;Co <= 1;endelse if ( A== 0 && B == 1 && Ci == 1 )beginS <= 0;Co <= 1;endelsebeginS <= 1;Co <= 1;endendendmodule7、D触发器module Dflipflop ( Q ,CLK ,RESET ,SET ,D ,Qn );input CLK ; //D触发器输入时钟wire CLK ;input RESET ; //D触发器清零输入wire RESET ;input SET ; //D触发器预置数输入wire SET ;input D ; //D触发器输入wire D ;output Q ; //D触发器输出reg Q ;output Qn ;wire Qn ;assign Qn = ~Q ; //将D触发器输出取反always @ ( posedge CLK or negedge SET or negedge RESET ) beginif ( !RESET) //RESET下降沿将D触发器输出清零Q <= 0 ;else if ( ! SET) //SER下降沿将D触发器输出置1 Q <= 1;else Q <= D; //CLK上升沿D触发器输出等于输入endendmodule8、寄存器module reg8 ( clr ,clk ,DOUT ,D );input clr ; //异步清零信号,高有效wire clr ;input clk ; //时钟输入wire clk ;input [7:0] D ; //寄存器数据输入wire [7:0] D ;output [7:0] DOUT ; //寄存器数据输出reg [7:0] DOUT ;always @ ( posedge clk or posedge clr)beginif ( clr == 1'b1)DOUT <= 0;else DOUT <= D ;endendmodule9、双向移位寄存器module shiftdata ( left_right ,load ,clr ,clk ,DIN ,DOUT );input left_right ; // 左移右移控制信号wire left_right ;input load ; //异步置数信号,有效时将DIN输入wire load ;input clr ; //异步清零信号,高有效wire clr ;input clk ; //时钟输入wire clk ;input [3:0] DIN ; //并行输入wire [3:0] DIN ;output [3:0] DOUT ; //并行输出wire [3:0] DOUT ; // DOUT是一个wire型变量,不能在always块中被赋值reg [3:0] data_r; //所以定义一个寄存器型变量data_r作为中间变量assign DOUT = data_r ;always @ ( posedge clk or posedge clror posedge load )beginif ( clr == 1) //异步清零data_r <= 0;else if (load ) //异步置数data_r <= DIN;else beginif ( left_right) //left_right=1,信号左移begindata_r <= (data_r<<1);data_r[0] <= 0; //移出位补0endelse begin //left_right=0,信号右移data_r <= (data_r>>1);data_r[3] <= 0; //移出位补0endendendendmodule10、4位二进制加减法计数器module counter4 ( load ,clr ,c ,DOUT ,clk, up_down ,DIN);input load ; //异步预置数input clk; //输入时钟wire load ;input clr ; //异步清零wire clr ;input up_down ; //加减计数,up_dpwn=1加计数,up_down=0减计数wire up_down ;input [3:0] DIN ; //预置数输入wire [3:0] DIN ;output c ; //进位/借位输出,可以用于计数器的级联reg c ;output [3:0] DOUT ; //计数输出wire [3:0] DOUT ;reg [3:0] data_r;assign DOUT = data_r;always @ ( posedge clk or posedge clror posedge load)beginif ( clr == 1) //异步清零data_r <= 0;else if ( load == 1) //异步预置data_r <= DIN;else begin if ( up_down ==1) //加计数beginif ( data_r == 4'b1111) begindata_r <= 4'b0000;c = 1;endelse begindata_r <= data_r +1;c = 0 ;endendelse //减计数beginif ( data_r == 4'b0000) begindata_r <= 4'b1111;c = 1;endelse begindata_r <= data_r -1;c = 0 ;endendendendendmodule11、十进制加减法计数器module counter10 ( load ,clr ,c ,DOUT ,clk,up_down ,DIN ,seven_seg);input load ; //异步预置数input clk; //输入时钟wire load ;input clr ; //异步清零wire clr ;input up_down ; //加减计数,up_dpwn=1加计数,up_down=0减计数wire up_down ;input [3:0] DIN ; //预置数输入wire [3:0] DIN ;output c ; //进位/借位输出,可以用于计数器的级联reg c ;output [3:0] DOUT ; //计数输出output [7:0] seven_seg; //7段数码管wire [3:0] DOUT ;reg [3:0] data_r;assign DOUT = data_r;always @ ( posedge clk or posedge clror posedge load)beginif ( clr == 1) //异步清零data_r <= 0;else if ( load == 1) //异步预置data_r <= DIN;else if ( up_down ==1 & data_r == 9) //加进位beginc = 1;data_r <= 4'b0000;endelse if ( up_down ==0 & data_r == 0) //减借位beginc = 1;data_r <= 9;endelsebeginif (up_down ==1) begin //加计数data_r <= data_r +1;c = 0 ;endelse begin //减计数data_r <= data_r -1 ;c = 0 ;endendend/************数码管***************/assign seven_seg =Y_r;reg [7:0] Y_r;always @(data_r ) //用7段数码管显示计数输出beginY_r =8'b11111111;case (data_r )4'b0000: Y_r = 8'b00000011; //显示04'b0001: Y_r = 8'b10011111; //显示14'b0010: Y_r = 8'b00100101; //显示24'b0011: Y_r = 8'b00001101; //显示34'b0100: Y_r = 8'b10011001; //显示44'b0101: Y_r = 8'b01001001; //显示54'b0110: Y_r = 8'b01000001; //显示64'b0111: Y_r = 8'b00011111; //显示74'b1000: Y_r = 8'b00000001; //显示84'b1001: Y_r = 8'b00001001; //显示9default: Y_r = 8'b11111111; //默认数码管不发光endcaseendendmodule12、顺序脉冲发生器module pulsegen ( Q ,clr ,clk);input clr ; //异步预置数wire clr ;input clk ; //时钟输入wire clk ;output [7:0] Q ;//顺序脉冲输出wire [7:0] Q ;reg [7:0] temp ;reg x;assign Q =temp;always @ ( posedge clk or posedge clr )beginif ( clr==1)begintemp <= 8'b00000001; //temp寄存预定的序列x= 0 ;endelsebeginx<= temp[7] ; //序列最高位输出temp <= temp<<1 ; //temp左移一位temp[0] <=x; //将输出的结果赋给序列最低位,实现序列的循环输出endendendmodule13、序列信号发生器module xlgen ( Q ,clk ,res);input clk ; //时钟输入wire clk ;input res ; //异步预置数wire res ;output Q ; //序列信号输出reg Q ;reg [7:0] Q_r ;always @( posedge clk or posedge res)beginif (res ==1)beginQ <= 1'b0;Q_r <= 8'b11100100 ;//Q_r寄存预定的序列endelsebeginQ <= Q_r[7]; //序列最高位输出Q_r <= Q_r<<1; //Q_r左移一位Q_r[0] <=Q; //将输出的结果赋给序列最低位,实现序列的循环输出endend endmodule14、分频器module clockdiv ( Q ,rst ,sysclk ,sel );input rst ; //系统复位wire rst ;input sysclk ; //系统时钟输入wire sysclk ;input [1:0] sel ; //分频倍数选择wire [1:0] sel ;output Q ; //分频器输出wire Q ;reg [2:0] q;reg [31:0] cnt ;reg clk ;//时钟分频模块always @( posedge sysclk or negedge rst)beginif ( !rst ) begincnt <= 0 ;clk <= 1'b1 ;endelse begincnt <= cnt + 1'b1 ;if (cnt >= 32'd2500000 ) begin /clk时钟周期是系统时钟周期的5000000倍clk <= ~clk;cnt <= 0 ;endendend//分频器模块always @ ( posedge clk or negedge rst )if ( !rst ) q[0] <= 0;else q[0] <= ~q[0] ; // q[0]是clk的2分频always @ ( posedge q[0] or negedge rst )if ( !rst ) q[1] <= 0;else q[1] <= ~q[1] ; // q[1]是clk的4分频always @ ( posedge q[1] or negedge rst )if ( !rst ) q[2] <= 0;else q[2] <= ~q[2] ; // q[2]是clk的8分频assign Q = (sel== 2'd0) ? clk : //分频器输出clk(sel== 2'd1) ? q[0] : //分频器输出clk的二分频(sel== 2'd2) ? q[1] : //分频器输出clk的四分频(sel== 2'd3) ? q[2] : 0; //分频器输出clk的八分频endmodule。

相关主题