cpu设计报告

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

试验报告——cpu设计一、概述我所设计的CPU与教员所给的要求存在不同,指令是32位的,寄存器和存储器均是32位的。设计思路是先写出CPU所需要的部件,然后设计指令系统,最后将各个部件按照指令集所生成的控制电路连接在一起。这样做的好处是可以模块化的添加功能,比如:当CPU需要执行除法时,只需要设计除法器以及除法指令即可。缺点是各个功能模块之间的通信需要大量的控制信号,这些控制信号需要严格遵守制定好的指令集真值表,否则会出现大量错误,本人有切身体会,具体问题会在后面章节详细展开。二、多路选择器设计本CPU共用到了32位的二选一多路选择器,四选一多路选择器以及八选一多路选择器。思路大致相同,已四选一多路选择器为例来简单介绍,其他两个多路选择器与其结构差异不大。以下是四选一多路选择器的代码,其中a0,a1,a2,a3是32位的输入信号,y为32位的输出信号。S为两位的选择信号:a)当S=00时,y=a0;b)当S=01时,y=a1;c)当S=10时,y=a2;d)当S=11时,y=a3;modulemux4x32(a0,a1,a2,a3,s,y);input[31:0]a0,a1,a2,a3;input[1:0]s;output[31:0]y;function[31:0]select;input[31:0]a0,a1,a2,a3;input[1:0]s;case(s)2'b00:select=a0;2'b01:select=a1;2'b10:select=a2;2'b11:select=a3;endcaseendfunctionassigny=select(a0,a1,a2,a3,s);endmodule三、位移器设计32位移位器对32为二进制数左移或者右移,移动位数可在0~31之间自由选择,右移时可选择逻辑右移(最高位填0)或者算数右移(高位符号扩展)。以下是32位移位器的代码,d是32位输入信号,sh是32位输出信号,sa是5位移位位数控制信号,right是右移控制信号,arith是算数右移控制引号。moduleshift(d,sa,right,arith,sh);input[31:0]d;input[4:0]sa;inputright,arith;output[31:0]sh;reg[31:0]sh;always@*beginif(!right)beginsh=dsa;endelseif(!arith)beginsh=dsa;endelsebeginsh=$signed(d)sa;endendendmodule四、加法器设计本加法器使用补码运算,所以支持减法操作。因为使用补码时:做加减法运算时与无符号数是相同的。首先考虑一位二进制数的相加,能够完成一位二进制数加法的电路称为半加器,当把低位的进位考虑进来后,就产生了全加器。以下是全加器的真值表,我们可以根据真值表来写出电路的功能描述风格的代码。输入信号输出信号注释ABCiCoS计算式000000+0+0=00001010+0+1=01010010+1+0=01011100+1+1=10100011+0+0=01101101+0+1=10110101+1+0=10111111+1+1=11moduleadd(a,b,ci,s,co);inputa,b,ci;outputs,co;assigns=a^b^ci;assignco=(a&b)|(b&ci)|(a&ci);endmodule可以将许多全加器组合在一起,就组成了32位的加法器。但是这样的加法器速度很慢,因为进位将从输入的ci逐位的传递到最高位的进位输出co,途中需要穿越32个全加器,我们知道,电路是有延迟的,这样的长途旅行是要花时间的。为了加快加法器的运算速度,必须向办法能尽快地产生每位的进位。由于:c[i+1]=a[i]b[i]+a[i]c[i]+b[i]c[i]=a[i]b[i]+(a[i]+b[i])c[i]=g[i]+p[i]c[i]其中g[i]=a[i]b[i]称为进位产生函数,p[i]=a[i]+b[i]称为进位传递函数,则c[i+1]=g[i]+p[i]g[i-1]+p[i]p[i-1]g[i-2]+……+p[i]p[i-1]……p[1]c[0]+p[i]p[i-1]……p[1]p[0]c[0]从理论上来讲,由c[i+1]的表达式可以并行产生所有位的进位输入,但是这样的电路太复杂,难以实现。所以采用了树形结构来分层次产生进位。首先是一位加法器的代码,除了产生一位加法结果s外,还生成进位产生的函数g和进位传递函数p。一位加法器和GP生成器代码如下:moduleadd(a,b,c,g,p,s);inputa,b,c;outputg,p,s;assigns=a^b^c;assigng=a&b;assignp=a|b;endmodulemoduleg_p(g,p,c_in,g_out,p_out,c_out);input[1:0]g,p;inputc_in;outputg_out,p_out,c_out;assigng_out=g[1]|p[1]&g[0];assignp_out=p[1]&p[0];assignc_out=g[0]|p[0]&c_in;endmodule有了以上两个模块,就可以设计一个两位先行加法器了。它使用了两个一位加法器和一个GP生成器。modulecla_2(a,b,c_in,g_out,p_out,s);input[1:0]a,b;inputc_in;outputg_out,p_out;output[1:0]s;wire[1:0]g,p;wirec_out;addadd0(a[0],b[0],c_in,g[0],p[0],s[0]);addadd1(a[1],b[1],c_out,g[1],p[1],s[1]);g_pg_p0(g,p,c_in,g_out,p_out,c_out);endmodule四位,八位,十六位,三十二位先行加法器代码与两位先行加法器类似,在此不再叙述,附件代码中已给出。以下是32位先行加法器的最后代码,除了产生32位加法结果,他也产生最后的进位输出。代码如下:modulecla32(a,b,ci,s,co);input[31:0]a,b;inputci;output[31:0]s;outputco;wireg_out,p_out;cla_32cla(a,b,ci,g_out,p_out,s);assignco=g_out|p_out&ci;endmodule五、乘法器设计此乘法器是两个16位带符号数相乘,两个乘数和结果均使用补码表示。大致原理如下:设有两个补码表示的4位带符号数A4和B4,,计算Z8=A4×B4:A4=a3a2a1a0=-a3×23+∑ai×2i=-a3×23+A3B4=b3b2b1b0=-b3×23+∑bi×2i=-b3×23+B3其中i的范围位0~2,A3和B3是无符号数。由于(a+b)(x+y)=ax+ay+bx+by,则Z8=A4×B4=(-a3×23+A3)×(-b3×23+B3)=a3×b3×26+(-a3×B3×23)+(-b3×A3×23)+A3×B3。其中第一项与第四项与无符号数乘相同,而第二项和第三项为负。如下图所示:写成二进制的形式:(-a3)×B3=00a3b2a3b1a3b0(-b3)×A3=00a2b3a1b3a0b3由于是反码,所以–x=𝑥̅+1,对着两项同时取反加1后再相加,得:7654311a3b2a3b1a3b011a2b3a1b3a0b300001+00001化简后得:7654300a3b2a3b1a3b000a2b3a1b3a0b3+10001只需要把两个红色的1放在合适的位置即可,再把所有乘积项相加,就可得到带符号数的相乘结果。以下是带符号数乘法器的代码,其中前半部分用与非门实现,后半部分经过逻辑综合后得到结果。modulemul_signed(a,b,z);765432101a3b0a2b0a1b0a0b0a3b1a2b1a1b1a0b1a3b2a2b2a1b2a0b21a3b3a2b3a1b3a0b3Z7Z6Z5Z4Z3Z2Z1Z0input[15:0]a,b;output[31:0]z;reg[15:0]a_bi[15:0];integeri,j;always@*beginfor(i=0;i15;i=i+1)for(j=0;j15;j=j+1)a_bi[i][j]=a[i]&b[j];for(i=0;i15;i=i+1)a_bi[i][15]=~(a[i]&b[15]);for(j=0;j15;j=j+1)a_bi[15][j]=~(a[15]&b[j]);a_bi[15][15]=a[15]&b[15];endassignz=(({16'b1,a_bi[0][15],a_bi[0][14:0]}+{15'b0,a_bi[1][15],a_bi[1][14:0],1'b0})+({14'b0,a_bi[2][15],a_bi[2][14:0],2'b0}+{13'b0,a_bi[3][15],a_bi[3][14:0],3'b0}))+(({12'b0,a_bi[4][15],a_bi[4][14:0],4'b0}+{11'b0,a_bi[5][15],a_bi[5][14:0],5'b0})+({10'b0,a_bi[6][15],a_bi[6][14:0],6'b0}+{9'b0,a_bi[7][15],a_bi[7][14:0],7'b0}))+(({8'b0,a_bi[8][15],a_bi[8][14:0],8'b0}+{7'b0,a_bi[9][15],a_bi[9][14:0],9'b0})+({6'b0,a_bi[10][15],a_bi[10][14:0],10'b0}+{5'b0,a_bi[11][15],a_bi[11][14:0],11'b0}))+(({4'b0,a_bi[12][15],a_bi[12][14:0],12'b0}+{3'b0,a_bi[13][15],a_bi[13][14:0],13'b0})+({2'b0,a_bi[14][15],a_bi[14][14:0],14'b0}+{1'b1,a_bi[15][15],a_bi[15][14:0],15'b0}));endmodule六、指令系统本CPU部分指令如下(有一些是我自己用来调试的指令,在此就不列举了):指令32:2625:2120:1615:1110:65:0意义Add000000Rsrtrd00000100000寄存器加Sub000000RsRtRd00000100010寄存器减And000000RsRtRd00000100100寄存器与Or000000RsRtRd00000100101寄存器或Xor000000RsRtRd00000100110寄存器异或mul000000RsRtRd00000100111寄存器乘Sll000000000000RtRdSa000000左移srl000000000000RtRdSa000010逻辑右移Sra000000000000RtRdsa000011算数友谊Addi001000RsRtimmediate立即数加Andi001100RsRtImmediate立即数加Ori001101RsRtImmediate立即数加Xori001110RsRtImmediate立即数加Lw100011RsRtOffset取整数数据字Sw101011RsRtOffset存整数数据字stop111111全0停机指令jar000011address调用七、ALU设计ALU是负责运算的电路。综合指令表可以看出,ALU需要实现以下运算:加法,减法,与运算,或运算,异或运算,左移,逻辑右移,算数右移,乘法运算。ALU设计的基本思想是准备好所有的运算电路,然后用多路选择器进行选择。多路选择器的选择信号就是ALU的操作控制码。以下是ALU的代码,其中a[3

1 / 25
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功