您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 信息化管理 > 用verilog编写16位加法器-乘法器-自动售货机
Verilog课程实验报告实验1十六位超前进位加法器1.1系统设计要求用超前进位加法器实现一个有符号位的16位加法器,并且考虑溢出的情况2.1详细设计根据超前进位加法器的原理Co=G|(P&Ci)S=P^Ci设计出4位加法器的子模块,然后通过4个4位加法器的相连来得到十六位的加法器。原理如下图所示。溢出用flag=0表示。3.1程序//-------------16位超前进位加法器-----------------modulecla16(a,b,s,flag);//含有a,b,输出s,进位flag的模块input[15:0]a,b;//输入a,boutput[16:0]s;//输出soutputregflag;//进位FAFAFAFAP0G1P0G1P2G2P3G3Co,3Co,2Co,1Co,0Ci,0FAFAFAFAP0G1P0G1P2G2P3G3Co,2Co,1Co,0Ci,0Co,3MultiplexerBP=PoP1P2P3Idea:If(P0andP1andP2andP3=1)thenCo3=C0,else“kill”or“generate”.wirepp4,pp3,pp2,pp1;wiregg4,gg3,gg2,gg1;wire[15:0]Cp;wire[15:0]p,g;pgi0(a[15:0],b[15:0],p[15:0],g[15:0]);addi1(p[3],p[2],p[1],p[0],g[3],g[2],g[1],g[0],pp1,gg1);addi2(p[7],p[6],p[5],p[4],g[7],g[6],g[5],g[4],pp2,gg2);addi3(p[11],p[10],p[9],p[8],g[11],g[10],g[9],g[8],pp3,gg3);addi4(p[15],p[14],p[13],p[12],g[15],g[14],g[13],g[12],pp4,gg4);addi5(pp4,pp3,pp2,pp1,gg4,gg3,gg2,gg1,pp5,gg5);//调用四位加法器模块add4l0(p[3],p[2],p[1],p[0],g[3],g[2],g[1],g[0],1'b0,Cp[3],Cp[2],Cp[1],Cp[0]);add4l1(p[7],p[6],p[5],p[4],g[7],g[6],g[5],g[4],Cp[3],Cp[7],Cp[6],Cp[5],Cp[4]);add4l2(p[11],p[10],p[9],p[8],g[11],g[10],g[9],g[8],Cp[7],Cp[11],Cp[10],Cp[9],Cp[8]);add4l3(p[15],p[14],p[13],p[12],g[15],g[14],g[13],g[12],Cp[11],Cp[15],Cp[14],Cp[13],Cp[12]);assigns[0]=p[0]^1'b0;//保留位assigns[1]=p[1]^Cp[0];assigns[2]=p[2]^Cp[1];assigns[3]=p[3]^Cp[2];assigns[4]=p[4]^Cp[3];assigns[5]=p[5]^Cp[4];assigns[6]=p[6]^Cp[5];assigns[7]=p[7]^Cp[6];assigns[8]=p[8]^Cp[7];assigns[9]=p[9]^Cp[8];assigns[10]=p[10]^Cp[9];assigns[11]=p[11]^Cp[10];assigns[12]=p[12]^Cp[11];assigns[13]=p[13]^Cp[12];assigns[14]=p[14]^Cp[13];assigns[15]=p[15]^Cp[14];assigns[16]=pp5|gg5;//溢出判断模块always@(a,b,s)beginif((a[15]==1&&b[15]==1&&s[15]==0)||(a[15]==0&&b[15]==0&&s[15]==1))flag=1'b1;elseflag=1'b0;endendmodule//4位加法器模块moduleadd4(p[3],p[2],p[1],p[0],g[3],g[2],g[1],g[0],Co,Cp[3],Cp[2],Cp[1],Cp[0]);input[3:0]p,g;inputCo;output[3:0]Cp;assignCp[0]=g[0]|p[0]&Co;assignCp[1]=g[1]|p[1]&Cp[0];assignCp[2]=g[2]|p[2]&Cp[1];assignCp[3]=g[3]|p[3]&Cp[2];endmodule//模块间的进位moduleadd(p[3],p[2],p[1],p[0],g[3],g[2],g[1],g[0],pp,gg);input[3:0]p,g;outputpp,gg;assignpp=p[3]&p[2]&p[1]&p[0];assigngg=g[3]|(p[3]&(g[2]|p[2]&(g[1]|p[1]&g[0])));endmodule//进位信号的产生modulepg(a,b,p,g);input[15:0]a,b;output[15:0]p,g;assignp=a^b;assigng=a&b;endmodule4.1测试程序通过产生一个随机输入a和b,来验证c=a+b。//16位加法器的测试文件`timescale1ns/1ns`include./sixteenadder.vmodulesixteenaddertest;wire[15:0]s;reg[15:0]a,b;wireflag;parametertimes=5;//随机产生一个数,总共产生6次initialbegina={$random}%65536;b={$random}%65536;repeat(times)begin#100a={$random}%65536;b={$random}%65536;end#100$stop;endcla16cal161(a,b,s,flag);endmodule5.1仿真波形用mudelsim10.0仿真得到的波形如下所示:如图a=13604,b=24193s=-27739.s为负数,产生溢出,溢出标位sto=1.当a=-10743,,b=22115.s=11372没有溢出,sto=0.通过这个实验验证了s=a+b,实现了带符号位的加法器。实验二十六位加减法器1.1系统设计要求将加法器和减法器结合到一起,实现带符号位的16位加减法运算,并考虑溢出。2.1详细设计在16位加法器的基础上,加上一条判断语句,如果出现减的操作,被减数取反加一,这样就实现了减的运算,用add_sub来表示加减运算符,当add_sub=0时候实现的是减运算,add_sub=1的时候实现的是加运算。3.1程序//--------------------16位加减法器------------------------modulecla16(a,b,s);//定义模块包括a,b,sinput[15:0]a,b;//输入a,boutput[16:0]s;//输出swirepp4,pp3,pp2,pp1;wiregg4,gg3,gg2,gg1;wire[15:0]Cp;wire[15:0]p,g;pgi0(a[15:0],b[15:0],p[15:0],g[15:0]);addi1(p[3],p[2],p[1],p[0],g[3],g[2],g[1],g[0],pp1,gg1);addi2(p[7],p[6],p[5],p[4],g[7],g[6],g[5],g[4],pp2,gg2);addi3(p[11],p[10],p[9],p[8],g[11],g[10],g[9],g[8],pp3,gg3);addi4(p[15],p[14],p[13],p[12],g[15],g[14],g[13],g[12],pp4,gg4);addi5(pp4,pp3,pp2,pp1,gg4,gg3,gg2,gg1,pp5,gg5);add4l0(p[3],p[2],p[1],p[0],g[3],g[2],g[1],g[0],1'b0,Cp[3],Cp[2],Cp[1],Cp[0]);add4l1(p[7],p[6],p[5],p[4],g[7],g[6],g[5],g[4],Cp[3],Cp[7],Cp[6],Cp[5],Cp[4]);add4l2(p[11],p[10],p[9],p[8],g[11],g[10],g[9],g[8],Cp[7],Cp[11],Cp[10],Cp[9],Cp[8]);add4l3(p[15],p[14],p[13],p[12],g[15],g[14],g[13],g[12],Cp[11],Cp[15],Cp[14],Cp[13],Cp[12]);assigns[0]=p[0]^1'b0;assigns[1]=p[1]^Cp[0];assigns[2]=p[2]^Cp[1];assigns[3]=p[3]^Cp[2];assigns[4]=p[4]^Cp[3];assigns[5]=p[5]^Cp[4];assigns[6]=p[6]^Cp[5];assigns[7]=p[7]^Cp[6];assigns[8]=p[8]^Cp[7];assigns[9]=p[9]^Cp[8];assigns[10]=p[10]^Cp[9];assigns[11]=p[11]^Cp[10];assigns[12]=p[12]^Cp[11];assigns[13]=p[13]^Cp[12];assigns[14]=p[14]^Cp[13];assigns[15]=p[15]^Cp[14];assigns[16]=pp5|gg5;endmodulemoduleadd4(p[3],p[2],p[1],p[0],g[3],g[2],g[1],g[0],Co,Cp[3],Cp[2],Cp[1],Cp[0]);input[3:0]p,g;inputCo;output[3:0]Cp;assignCp[0]=g[0]|p[0]&Co;assignCp[1]=g[1]|p[1]&Cp[0];assignCp[2]=g[2]|p[2]&Cp[1];assignCp[3]=g[3]|p[3]&Cp[2];endmodulemoduleadd(p[3],p[2],p[1],p[0],g[3],g[2],g[1],g[0],pp,gg);input[3:0]p,g;outputpp,gg;assignpp=p[3]&p[2]&p[1]&p[0];assigngg=g[3]|(p[3]&(g[2]|p[2]&(g[1]|p[1]&g[0])));endmodulemodulepg(a,b,p,g);input[15:0]a,b;output[15:0]p,g;assignp=a^b;assigng=a&b;endmodule//定义加减法器的模块moduleaddsub(a,b,s,flag,add_sub);input[15:0]a,b;inputadd_sub;output[15:0]s;outputregflag;wire[15:0]b1;cla16cla1(a,b1,s);/*always@(posedgeclk)beginif(~add_sub)beginb1=~b;b1=b1+1;endelseb1=b;end*/assignb1=(add_sub)?b:(~b+1'b1);//判断是否为减操作,为减操作的话是取反加一的运算always@(a,b,s)//判断是否溢出beginif((a[15]==1&&b[15]==1&&add_sub==1&&s[15]==0)||(a[15]==0&&b[15]==0&&add_sub==1&&s[15]==1))flag=1'b1;e
本文标题:用verilog编写16位加法器-乘法器-自动售货机
链接地址:https://www.777doc.com/doc-6940621 .html