硬件描述语言范例.docx
《硬件描述语言范例.docx》由会员分享,可在线阅读,更多相关《硬件描述语言范例.docx(21页珍藏版)》请在冰点文库上搜索。
![硬件描述语言范例.docx](https://file1.bingdoc.com/fileroot1/2023-5/17/af14dcca-7415-4551-b9b4-16705bbcab62/af14dcca-7415-4551-b9b4-16705bbcab621.gif)
硬件描述语言范例
硬件描述语言范例
硬件描述语言语言设计实例
1、8-3编码器
moduleencode_verilog(a,b);
input[7:
0]a;//编码器输入
wire[7:
0]a;
output[2:
0]b;//编码器输出
reg[2:
0]b;
always@(a)
begin
case(a)//编码器某一输入端口为高电平输出相应的3位二进制数
8'b0000_0001:
b<=3'b000;//0
8'b0000_0010:
b<=3'b001;//1
8'b0000_0100:
b<=3'b010;//2
8'b0000_1000:
b<=3'b011;//3
8'b0001_0000:
b<=3'b100;//4
8'b0010_0000:
b<=3'b101;//5
8'b0100_0000:
b<=3'b110;//6
8'b1000_0000:
b<=3'b111;//7
default:
b<=3'b000;//其他情况编码器输出3’b000
endcase
end
endmodule
2、8-3优先编码器
modulep_encode_verilog(A,I,GS,EO,EI);//编码器以低为有效
input[7:
0]I;//编码器输入
wire[7:
0]I;
inputEI;//输入使能,EI=0时,编码器正常工作
wireEI;
output[2:
0]A;//编码器输出
reg[2:
0]A;
outputGS;//优先编码器工作状态标志,编码器的八个输入端有信号输入时,GS=0
regGS;
outputEO;//输出使能,
regEO;
always@(IorEI)
if(EI)//使用if、elseif表明条件的优先级顺序
begin
A<=3'b111;
GS<=1;
EO<=1;
end
elseif(I[7]==0)
begin
A<=3'b000;
GS<=0;
EO<=1;
end
elseif(I[6]==0)
begin
A<=3'b001;
GS<=0;
EO<=1;
end
elseif(I[5]==0)
begin
A<=3'b010;
GS<=0;
EO<=1;
end
elseif(I[4]==0)
begin
A<=3'b011;
GS<=0;
EO<=1;
end
elseif(I[3]==0)
begin
A<=3'b100;
GS<=0;
EO<=1;
end
elseif(I[2]==0)
begin
A<=3'b101;
GS<=0;
EO<=1;
end
elseif(I[1]==0)
begin
A<=3'b110;
GS<=0;
EO<=1;
end
elseif(I[0]==0)
begin
A<=3'b111;
GS<=0;
EO<=1;
end
elseif(I==8'b11111111)
begin
A<=3'b111;
GS<=1;
EO<=0;
end
endmodule
3、3-8译码器
moduledecoder_verilog(G1,Y,G2,A,G3);
inputG1;//使能输入,高有效
wireG1;
inputG2;//使能输入,低有效
wireG2;
input[2:
0]A;//3位译码器输入,为高有效
wire[2:
0]A;
inputG3;//使能输入
wireG3;//使能输入,低有效
output[7:
0]Y;//8位译码器输出,为低有效
reg[7:
0]Y;
regs;
always@(A,G1,G2,G3)
begin
s<=G2|G3;
if(G1==0)//G1为低有效
Y<=8'b1111_1111;
elseif(s)
Y<=8'b1111_1111;
else
case(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;
endcase
end
endmodule
4、数据选择器
modulemux8_1_verilog(Y,A,D0,D1,
D2,D3,D4,D5,D6,D7,G);
input[2:
0]A;//地址输入端
wire[2:
0]A;
inputD0;//数据输入端
inputD1;//数据输入端
inputD2;//数据输入端
inputD3;//数据输入端
inputD4;//数据输入端
inputD5;//数据输入端
inputD6;//数据输入端
inputD7;//数据输入端
inputG;//使能端,当G=1时Y=0,当G=0时数据选择器正常工作
wireG;
outputY;//数据输出端
regY;
always@(GorAorD0orD1orD2orD3
orD4orD5orD6orD7)
begin
if(G==1)//使能端的优先级高
Y<=0;
else
case(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;
endcase
end
endmodule
5、多位数值比较器
modulecompare_verilog(Y,A,B);
input[3:
0]A;//4位二进制数A
wire[3:
0]A;
input[3:
0]B;//4位二进制数B
wire[3:
0]B;
output[2:
0]Y;//A与B大小的比较结果
reg[2:
0]Y;
always@(AorB)
begin
if(A>B)
Y<=3'b001;//A>B时Y输出3'b001
elseif(A==B)
Y<=3'b010;//A=B时Y输出3'b010
else
Y<=3'b100;//A
end
endmodule
6、全加器
modulesum_verilog(A,Co,B,S,Ci);
inputA;//输入加数A
wireA;
inputB;//输入加数B
wireB;
inputCi;//相邻低位的进位输入信号
wireCi;
outputCo;//向相邻高位的进位输出信号
regCo;
outputS;//相加和数输出
regS;
always@(AorBorCi)
begin
if(A==0&&B==0&&Ci==0)
begin
S<=0;
Co<=0;
end
elseif(A==1&&B==0&&Ci==0)
begin
S<=1;
Co<=0;
end
elseif(A==0&&B==1&&Ci==0)
begin
S<=1;
Co<=0;
end
elseif(A==1&&B==1&&Ci==0)
begin
S<=0;
Co<=1;
end
elseif(A==0&&B==0&&Ci==1)
begin
S<=1;
Co<=0;
end
elseif(A==1&&B==0&&Ci==1)
begin
S<=0;
Co<=1;
end
elseif(A==0&&B==1&&Ci==1)
begin
S<=0;
Co<=1;
end
else
begin
S<=1;
Co<=1;
end
end
endmodule
7、D触发器
moduleDflipflop(Q,CLK,
RESET,SET,D,Qn);
inputCLK;//D触发器输入时钟
wireCLK;
inputRESET;//D触发器清零输入
wireRESET;
inputSET;//D触发器预置数输入
wireSET;
inputD;//D触发器输入
wireD;
outputQ;//D触发器输出
regQ;
outputQn;
wireQn;
assignQn=~Q;//将D触发器输出取反
always@(posedgeCLKornegedgeSETornegedgeRESET)
begin
if(!
RESET)//RESET下降沿将D触发器输出清零
Q<=0;
elseif(!
SET)//SER下降沿将D触发器输出置1
Q<=1;
elseQ<=D;//CLK上升沿D触发器输出等于输入
end
endmodule
8、寄存器
modulereg8(clr,clk,DOUT,D);
inputclr;//异步清零信号,高有效
wireclr;
inputclk;//时钟输入
wireclk;
input[7:
0]D;//寄存器数据输入
wire[7:
0]D;
output[7:
0]DOUT;//寄存器数据输出
reg[7:
0]DOUT;
always@(posedgeclkorposedgeclr)
begin
if(clr==1'b1)
DOUT<=0;
elseDOUT<=D;
end
endmodule
9、双向移位寄存器
moduleshiftdata(left_right,load,clr,clk,
DIN,DOUT);
inputleft_right;//左移右移控制信号
wireleft_right;
inputload;//异步置数信号,有效时将DIN输入
wireload;
inputclr;//异步清零信号,高有效
wireclr;
inputclk;//时钟输入
wireclk;
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作为中间变量
assignDOUT=data_r;
always@(posedgeclkorposedgeclr
orposedgeload)
begin
if(clr==1)//异步清零
data_r<=0;
elseif(load)//异步置数
data_r<=DIN;
elsebegin
if(left_right)//left_right=1,信号左移
begin
data_r<=(data_r<<1);
data_r[0]<=0;//移出位补0
end
elsebegin//left_right=0,信号右移
data_r<=(data_r>>1);
data_r[3]<=0;//移出位补0
end
end
end
endmodule
10、4位二进制加减法计数器
modulecounter4(load,clr,c,DOUT,
clk,up_down,DIN);
inputload;//异步预置数
inputclk;//输入时钟
wireload;
inputclr;//异步清零
wireclr;
inputup_down;//加减计数,up_dpwn=1加计数,up_down=0减计数
wireup_down;
input[3:
0]DIN;//预置数输入
wire[3:
0]DIN;
outputc;//进位/借位输出,可以用于计数器的级联
regc;
output[3:
0]DOUT;//计数输出
wire[3:
0]DOUT;
reg[3:
0]data_r;
assignDOUT=data_r;
always@(posedgeclkorposedgeclr
orposedgeload)
begin
if(clr==1)//异步清零
data_r<=0;
elseif(load==1)//异步预置
data_r<=DIN;
elsebeginif(up_down==1)//加计数
begin
if(data_r==4'b1111)begin
data_r<=4'b0000;
c=1;
end
elsebegin
data_r<=data_r+1;
c=0;
end
end
else//减计数
begin
if(data_r==4'b0000)begin
data_r<=4'b1111;
c=1;
end
elsebegin
data_r<=data_r-1;
c=0;
end
end
end
end
endmodule
11、十进制加减法计数器
modulecounter10(load,clr,c,DOUT,clk,
up_down,DIN,seven_seg);
inputload;//异步预置数
inputclk;//输入时钟
wireload;
inputclr;//异步清零
wireclr;
inputup_down;//加减计数,up_dpwn=1加计数,up_down=0减计数
wireup_down;
input[3:
0]DIN;//预置数输入
wire[3:
0]DIN;
outputc;//进位/借位输出,可以用于计数器的级联
regc;
output[3:
0]DOUT;//计数输出
output[7:
0]seven_seg;//7段数码管
wire[3:
0]DOUT;
reg[3:
0]data_r;
assignDOUT=data_r;
always@(posedgeclkorposedgeclr
orposedgeload)
begin
if(clr==1)//异步清零
data_r<=0;
elseif(load==1)//异步预置
data_r<=DIN;
elseif(up_down==1&data_r==9)//加进位
begin
c=1;
data_r<=4'b0000;
end
elseif(up_down==0&data_r==0)//减借位
begin
c=1;
data_r<=9;
end
else
begin
if(up_down==1)begin//加计数
data_r<=data_r+1;
c=0;
end
elsebegin//减计数
data_r<=data_r-1;
c=0;
end
end
end
/************数码管***************/
assignseven_seg=Y_r;
reg[7:
0]Y_r;
always@(data_r)//用7段数码管显示计数输出
begin
Y_r=8'b11111111;
case(data_r)
4'b0000:
Y_r=8'b00000011;//显示0
4'b0001:
Y_r=8'b10011111;//显示1
4'b0010:
Y_r=8'b00100101;//显示2
4'b0011:
Y_r=8'b00001101;//显示3
4'b0100:
Y_r=8'b10011001;//显示4
4'b0101:
Y_r=8'b01001001;//显示5
4'b0110:
Y_r=8'b01000001;//显示6
4'b0111:
Y_r=8'b00011111;//显示7
4'b1000:
Y_r=8'b00000001;//显示8
4'b1001:
Y_r=8'b00001001;//显示9
default:
Y_r=8'b11111111;//默认数码管不发光
endcase
end
endmodule
12、顺序脉冲发生器
modulepulsegen(Q,clr,clk);
inputclr;//异步预置数
wireclr;
inputclk;//时钟输入
wireclk;
output[7:
0]Q;//顺序脉冲输出
wire[7:
0]Q;
reg[7:
0]temp;
regx;
assignQ=temp;
always@(posedgeclkorposedgeclr)
begin
if(clr==1)
begin
temp<=8'b00000001;//temp寄存预定的序列
x=0;
end
else
begin
x<=temp[7];//序列最高位输出
temp<=temp<<1;//temp左移一位
temp[0]<=x;//将输出的结果赋给序列最低位,实现序列的循环输出
end
end
endmodule
13、序列信号发生器
modulexlgen(Q,clk,res);
inputclk;//时钟输入
wireclk;
inputres;//异步预置数
wireres;
outputQ;//序列信号输出
regQ;
reg[7:
0]Q_r;
always@(posedgeclkorposedgeres)
begin
if(res==1)
begin
Q<=1'b0;
Q_r<=8'b11100100;//Q_r寄存预定的序列
end
else
begin
Q<=Q_r[7];//序列最高位输出
Q_r<=Q_r<<1;//Q_r左移一位
Q_r[0]<=Q;//将输出的结果赋给序列最低位,实现序列的循环输出
end
end
endmodule
14、分频器
moduleclockdiv(Q,rst,sysclk,sel);
inputrst;//系统复位
wirerst;
inputsysclk;//系统时钟输入
wiresysclk;
input[1:
0]sel;//分频倍数选择
wire[1:
0]sel;
outputQ;//分频器输出
wireQ;
reg[2:
0]q;
reg[31:
0]cnt;
regclk;
//时钟分频模块
always@(posedgesysclkornegedgerst)
begin
if(!
rst)begin
cnt<=0;
clk<=1'b1;
end
elsebegin
cnt<=cnt+1'b1;
if(cnt>=32'd2500000)begin/clk时钟周期是系统时钟周期的5000000倍
clk