数字模块实例-Verilog.doc
- 文档编号:750498
- 上传时间:2023-04-30
- 格式:DOC
- 页数:61
- 大小:4.78MB
数字模块实例-Verilog.doc
《数字模块实例-Verilog.doc》由会员分享,可在线阅读,更多相关《数字模块实例-Verilog.doc(61页珍藏版)》请在冰点文库上搜索。
一、加、减法器 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,就可以构成多位加法器。
//二进制行波进位加法器
moduleripple_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;
regq[N:
0];
always@(xoryorcin)begin:
ADDER
integeri;
q[0]=cin;
for(i=0;i<=N-1;i=i+1)begin
q[i+1]=(x[i]&y[i])|(x[i]&q[i])|(y[i]&q[i]);
sum[i]=x[i]^y[i]^q[i];
end
cout=q[N];
end
endmodule
4、超前进位加法器(先行进位加法器)
产生进位输出的情况是AB=1、A+B=1且CI=1,则得:
即
高位的进位输入不用等到低位计算完后就可得到,提高了计算速度,其电路结构如下:
其电路符号
Verilog描述:
GP生成器:
使用两个一位加法器与一个GP生成器设计两位的超前进位加法器
同样可以进行继续扩展
5、进位链加法器、跳跃进位加法器
modulecarry_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@(xoryorcin)begin:
ADDER
integeri;
q[0]=cin;
for(i=0;i p[i]=x[i]^y[i]; g[i]=y[i]; q[i+1]=(p[i])? q[i]: g[i]; sum[i]=p[i]^q[i]; end cout=q[DSIZE]; end endmodule //二进制跳跃进位加法器 modulecarry_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; integeri,j; reg[DSIZE: 0]q; always@(x_inory_inorc_in)begin q[0]=c_in; begin carry_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]; end c_out=q[DSIZE]; end //S比特分组进位链 taskcarry_skip_add_cell; input[S-1: 0]x,y; inputcin; output[S: 1]cout; reg q[S: 0],p[S-1: 0],g[S-1: 0],accumulator,generalized_p; integeri; begin q[0]=cin; for(i=0;i<=S-1;i=i+1)begin p[i]=x[i]^y[i]; g[i]=y[i]; q[i+1]=(p[i])? q[i]: g[i]; end accumulator=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]; end endtask endmodule 6、进位旁路加法器、线性进位选择加法器等 7、减法器 Verilog模型如下: 二、乘法器 1、定点原码乘法器 乘数与被乘数分别载入两个寄存器R1与R2中。 此外,还有一个寄存器A,A的初始值为0。 运算时,控制逻辑每次读乘数的一位。 若R1的最低位为1,则被乘数与A寄存器相加,并将结果存于A寄存器。 然后,A、R1这两个寄存器整体右移一位,A的最高位变成0,且A0进入R1的最高位,而R1的最低位丢弃。 若R1的最低位是0,则只需进行移位,不进行加法。 产生的2n位乘积存于A与R1寄存器中。 32位定点原码一位乘法流程图如下: Verilog参考代码: modulemult(start,resten,x,y,z,); input resten; input start; regbusy; input [2: 0] x; input [2: 0] y; output[5: 0]z; reg[5: 0] z; reg [2: 0]reg_x; reg [2: 0] reg_y; reg [3: 0] A; reg [2: 0] temp_x; integer i; always@(xoryorrestenorstart) begin if(! resten) begin A =4'b0; reg_x=3'b0; reg_y=3'b0; temp_x=3'b0; z =6'b0; busy =0; end elseif(start)begin reg_x=x; reg_y=y; busy =1; A =4'b0; end elsebegin if(busy) for(i=0;i<3;i=i+1)begin if(y[i])temp_x=x; else temp_x=3'b000; A = A+{1'b0,temp_x}; reg_y = {A[0],reg_y[2: 1]}; A = A>>1; end z={A,reg_y};busy=0; end end endmodule 2、加法树乘法器 moduleadd_tree_mult(out,a,b,clk); output[15: 0]out; input[7: 0]a,b; inputclk; wire[15: 0]out; wire[14: 0]out1,c1; wire[12: 0]out2; wire[10: 0]out3,c2; wire[8: 0]out4; reg[14: 0]temp0; reg[13: 0]temp1; reg[12: 0]temp2; reg[11: 0]temp3; reg[10: 0]temp4; reg[9: 0]temp5; reg[8: 0]temp6; reg[7: 0]temp7; function[7: 0]mux8_1; input[7: 0]operand; inputsel; begin mux8_1=(sel)? (operand): 8'b00000000; end endfunction always@(posedgeclk) begin temp7<=mux8_1(a,b[0]); temp6<=((mux8_1(a,b[1]))<<1); temp5<=((mux8_1(a,b[2]))<<2); temp4<=((mux8_1(a,b[3]))<<3); temp3<=((mux8_1(a,b[4]))<<4); temp2<=((mux8_1(a,b[5]))<<5); temp1<=((mux8_1(a,b[6]))<<6); temp0<=((mux8_1(a,b[7]))<<7); end assign out1=temp0+temp1; assign out2=temp2+temp3; assign out3=temp4+temp5; assign out4=temp6+temp7; assign c1=out1+out2; assign c2=out3+out4; assign out=c1+c2; endmodule 3、查找表乘法器 查找表乘法器是将乘积直接存放在存储器中,将操作数作为地址访问存储器,得到的输出数据就是乘法器的结果。 查找表乘法器的速度只局限于所使用存储器的存取速度。 modulelookup_mult(out,a,b,clk); output[7: 0]out; input[3: 0]a,b; inputclk; reg[7: 0]out; reg[1: 0]firsta,firstb; reg[1: 0]seconda,secondb; wire[3: 0]outa,outb,outc,outd; always@(posedgeclk) begin firsta=a[3: 2];seconda=a[1: 0]; firstb=b[3: 2];secondb=b[1: 0]; end lookup m1(outa,firsta,firstb,clk), m2(outb,firsta,secondb,clk), m3(outc,seconda,firstb,clk), m4(outd,seconda,secondb,clk); always@(posedgeclk) begin out=(outa<<4)+(outb<<2)+(outc<<2)+outd; end endmodule modulelookup(out,a,b,clk); output[3: 0]out; input[1: 0]a,b; inputclk; reg[3: 0]out; reg[3: 0]address; always@(posedgeclk) begin address={a,b}; case(address) 4'h0: out=4'b0000; 4'h1: out=4'b0000; 4'h2: out=4'b0000; 4'h3: out=4'b0000; 4'h4: out=4'b0000; 4'h5: out=4'b0001; 4'h6: out=4'b0010; 4'h7: out=4'b0011; 4'h8: out=4'b0000; 4'h9: out=4'b0010; 4'ha: out=4'b0100; 4'hb: out=4'b0110; 4'hc: out=4'b0000; 4'hd: out=4'b0011; 4'he: out=4'b0110; 4'hf: out=4'b1001; default: out='bx; endcase end endmodule 4、布尔乘法器 Booth算法通过以移位代替某些运算来提高乘法的运算速度。 Booth算法是补码乘法的算法,基本公式为: [X*Y]补=[X]补*[Yn-1Yn-2…..Y0]-[X]补*Yn。 公式说明如果乘数为正,则将乘数的尾数与被乘数相乘即可,如果乘数为负,那么在乘法运算之后,还要再减去被乘数才能得到最后的乘积。 公式变形为[X*Y]补=[X]补*[2^n(Yn-1-Yn)+2^n-1(Yn-2-Yn-1)+……+2^0(0-Y0)]。 从变形公式中可以看出,如果在乘数Y的末位Y0之后再增设一个附加位Y-1,其初始值为0,对乘数Y的值并无影响,则{(Yi-1,Yi)[X]补}就是每一次的部分积,该部分的位权就是2^i。 这种方法即为补码一位乘,即每次只处理一位乘数。 运算流程: 乘数与被乘数分别载入Q和M寄存器内,同时,还有一个1位寄存器,位于Q寄存器最低位Q0的右边,成为Q’。 乘法的结果出现在A和Q寄存器中。 A与Q’初始值为0。 控制逻辑也是每次扫描乘数的一位,但同时它也要检查右边的一位。 若两位相同,则A、Q和Q’寄存器的所有位向右移一位。 若两位不同,则根据两位是1-0还是0-1,决定被乘数加到A寄存器,还是有A寄存器减去被乘数,加减之后再右移一位。 也就是说,右移总是要进行的。 右移是{A,Q,Q’}的右移且是算术右移(算术移位: 算术左移时,右端(低位)补0,左端(高位)部分舍去;右移保证符号位不改变)。 设计流程图为: 示例: Verilog示例代码: modulebooth_mult(product,ready,word1,word2,start,clock,reset); parameterL_word=4; parameterL_brc=2; parameterAll_Ones=4'b1111; parameterAll_Zeros=4'b0000; output[2*L_word-1: 0]product; outputready; input[L_word-1: 0]word1,word2; inputstart,clock,reset; wireload_words,shift,add,sub,ready; wire[L_brc-1: 0]brc; Datapath_Boothm1(product,m0,word1,word2,load_words,shift,add,sub,clock,reset); Controller_Boothm2(load_words,shift,add,sub,read,m0,start,clock,reset); endmodule //控制模块 moduleController_Booth(load_words,shift,add,sub,ready,m0,start,clock,reset); parameterL_word=4; parameterL_state=4; parameterL_brc=2; outputload_words,shift,add,sub,ready; inputstart,clock,reset; inputm0; reg[L_state-1: 0]state,nextstate; parameterS_idle=0,S_1=1,S_2=2,S_3=3,S_4=4,S_5=5,S_6=6,S_7=7,S_8=8; regload_words,shift,add,sub; wireready=((state==S_idle)&&! reset)||(state==S_8); regm0_del; wire[L_brc-1: 0]brc={m0,m0_del}; always@(posedgeclockorposedgereset) if(reset)state<=S_idle;elsestate<=nextstate; always@(posedgeclockorposedgereset) if(reset)m0_del<=0;elseif(load_words)m0_del<=0;elsem0_del<=m0; always@(stateorstartorbrc)begin load_words=0;shift=0;add=0;sub=0; case(state) S_idle: if(start)beginload_words<=1;nextstate<=S_1;end elsenextstate<=S_idle; S_1: if((brc==0)||(brc==3))beginshift=1;nextstate<=S_3;end elseif(brc==1)beginadd=1;nextstate<=S_2;end elseif(brc==2)beginsub=1;nextstate<=S_2;end S_3: if((brc==0)||(brc==3))beginshift=1;nextstate<=S_5;end elseif(brc==1)beginadd=1;nextstate<=S_4;end elseif(brc==2)beginsub=1;nextstate<=S_4;end S_5: if((brc==0)||(brc==3))beginshift=1;nextstate<=S_7;end elseif(brc==1)beginadd=1;nextstate<=S_6;end elseif(brc==2)beginsub=1;nextstate<=S_6;end S_7: if((brc==0)||(brc==3))beginshift=1;nextstate<=S_8;end elseif(brc==1)beginadd=1;nextstate<=S_8;end elseif(brc==2)beginsub=1;nextstate<=S_8;end S_2: beginshift=1;nextstate=S_3;end S_4: beginshift=1;nextstate=S_5;end S_6: beginshift=1;nextstate=S_7;end S_8: if(start)beginload_words=1;nextstate=S_1;end elsenextstate=S_8; default: nextstate=S_idle; endcase end endmodule //数据路径模块 moduleDatapath_Booth(product,m0,word1,word2,load_words,shift,add,sub,clock,reset); parameterL_word=4; output[2*L_word-1: 0]product; outputm0; input[L_word-1: 0]word1,word2; inputload_words,shift,add,sub,clock,reset; reg[2*L_word-1: 0]product,multiplicand; reg[L_word-1: 0]mult; wirem0=mult[0]; parameterAll_Ones=4'b1111; parameterAll_Zeros=4'b0000; always@(posedgeclockorposedgereset)begin if(reset)beginmult<=0;multiplicand<=0;product<=0;end elseif(load_words)begin if(word1[L_word-1]==0)multiplicand<=w
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数字 模块 实例 Verilog