计算机组成与系统结构实验报告
CPU设计与实现
院(系):
专业班级: 计算机科学与技术 组 员: 指导教师:
实验目得:
设计实现CPU部件。
实验仪器:
PC机(安装Altebra 公司得开发软件 QuartusII,Modelsim)两台
TEC—CA计算机组成原理试验箱
实验过程:
一、理论设计 1、1、设计指令集
设计CPU第一步,就就是根据需求,确定功能,并且设计出指令集。指令集包括每一条指令得编码方式,操作码以及每一条指令实现得功能。考虑到第一次设计CPU,在指令集设计过程中难免会出现考虑不周全或者指令集设计不科学
得问题,我们借鉴了经典得31条MIPS指令集。在对指令集每一条指令进行解读、分析后,我们确定:31条MIPS指令可以满足我们得CPU得基本功能。下面将31条MIPS指令得编码格式、对应得操作类型以表格得形式列举出来:
MIPS 指令集(共31条) 2B2011031、、55、、 it 、、5、、、、0 26 、、# 16 11 6 21 shfR-ty op rs rt rd ampe unc t 0 rd <- rs + rr $1=$2+ad add t ;其中rs=0000rt rd d s $1,$2,$3 $3 $2,rt=$3, rd=$1 0 a rd 〈- rs + rt ; $1=$2+000r addu 其中rs=$2,rt=$3, ddrt rd 000 s $1,$2,$3 $3 u rd=$1,无符号数 00 rd <— rs — rt ;r sub $1, $1=$2— 其中rs=$2,rt=sub 000rt rd s $2,$3 $3 0 $3, rd=$1 rd <- rs - rt ;其s0000 subu $1=$2—rs rt rd 中rs=$2,rt=$3, $1,$2,$3 $3 ubu 00 rd=$1,无符号数 and rd <— rs & rt ;其an0000 $1= $1,$2,中rs=$2,rt=$3, rs rt rd $2 & $3 d 00 $3 rd=$1 rd <- rs | r or $1,$2, $1=0000 t ;其中rs=$2,rt=or rs rt rd 00 $3 $2 | $3 $3, rd=$1 rd <- rs xor $1=xo0000 xor $1,rt ;其中rs=$2, $2 ^ $rs rt rd r 00 $2,$3 rt=$3, rd=$13 (异或) 00 $1=~ rd 〈- not(rs | r nor $1,nor 000rs rt rd ($2 | $3t) ;其中rs=$2,rt$2,$3 0 ) =$3, rd=$1(或非) if($2< if (rs < rt) rd=00 slt $3) sr1 else rd=0 ;其00rs rt $1,$2, $1=1 elt d 中rs=$2,rt=00 $3 l$3, rd=$1 seﻫ $1
slt0000rs rt u 00 sll rt srl rt sra rt 0sl000rs rt lv 00 0sr000rs rt lv 00 00srav rs rt 0000 j0000rs r 00 I—typop rs rt immediate e if (rs < rt) rd=1 else rd=0 ;其中rs=$2,rt=$3, rd rd=$1 (无符号数) rd <- rt << shamt ;shamt存0 sll $1, $1=$2放移位得位数, shard 0000mt $2,10 〈<10 也就就是指令中得0 立即数,其中rt=$2, rd=$1 sh000 rd <- rt 〉〉 s srl $1, $1=hamt ;(logical) ,其中rd a01$2,10 $2>〉10 rt=$2, rd=$1 mt 0 rd 〈- rt >> shamt ;(arith00sh sra $1, $1=$2>metic) 注意符号rd a001$2,10 >10 位保留 mt 1 其中rt=$2, rd=$1 sllv rd <— rt << rs ;r $1=$2< $1,$2,其中rs=$3,rt=$2, d 〈$3 $3 rd=$1 rd 〈— rt 〉> rs ; srlv $1, $1=$2>(logical)其中rsrd $2,$3 >$3 =$3,rt=$2, rd=$1 rd 〈— rt 〉〉 rs ;(arithmetic) 注意符 srav $1, $1=rd $2,$3 $2>>$3 号位保留ﻫ 其中rs=$3,rt=$2, rd=$1 goto $3000001 jr $31 PC 〈- rs 1 0 000 =0 if($2<$3) ﻫ sltu $1, $1=$2,$3 1 else $1=0 rt <— rs + (sign- addi $1, $1=extend)immediaad0010rs rt immediate di 00 $2,100 $2+100 te ;其中rt=$1,rs=$2 〈- rs + (zeradd001addi $1=$2+10 rt rs rt immediate i001 u $1,0 o—extend)imm
u 0an0110rs di 0 o0011rs ri 01 00xo1rs ri 110 lui lw 1000rs 11 sw 1010rs 11 beq 00r0100 s 0bn0010rs e 1 0slt0101rs i 0 slt0010rs iu 11
ediate ;其中rt=$1,rs=$2 rt <— rs & (zer and $1=$2 o-extend)immediatrt immediate i $1,e ;其中rt=$1,rs& 10 $2,10 =$2 rt <- rs | (zer a $1=o-extend)immert immediate ndi $1,$2 | 10 diate ;其中rt=$1,$2,10 rs=$2 rt <— rs xor and $1=$2 (zero—extend)rt immediate i $1,^ 10 immediate ;其中$2,10 rt=$1,rs=$2 rt <- immediate*65536 ;将16immediat lui $1, $1=100位立即数放到目标寄rt *65536 存器高16ﻫ 位,e 100 目标寄存器得 低16位填0 $1=me rt 〈— memory[rs lmo+ (sign—extenrt immediate w $1,10ry[$2d)immediate] ;rt($2) ﻫ +10] =$1,rs=$2 me memory[rs + (s sw $1,1mory[$2ign-extend)immrt immediate 0($2) +10] ediate] <- rt ; =$1 rt=$1,rs=$2 if($1 if (rs == rt) beq $1,==$2) PC <— PC+4 + rt immediate $2,10 goto P(sign-extend)imC+4+40 mediate<<2 if($1!= if (rs != rt) PC 〈— bn$2)PC+4 + rt immediate e $1,$2,ﻫ goto P(sign-extend)immed10 C+4+40 iate<<2 if (rs <(s if($2ign-extend) slti $1,〈10) rt immediate immediate) rt=$2,10 $1=1 else1 else rt=0 ; ﻫ $1=0 其中rs=$2,rt=$1 sltiu if($2〈1 if (rs 〈(zero—ert immediate $1,$2,0) xtend)immediate) $2,100
10 $1=rt=1 else rt=0 ;1 else ﻫ 其中rs=$2,rt= $1=0 $1 J-tyop pe 00j 0010 address address 0000jal 11 address PC 〈— (PC+4)[3 goto 101、、28],address, j 10000 000 0,0 ;address=10000/4 $31<—PC+4;PC $31<-<- (PC+4)[31、、 jal 100PC+4;ﻫ go28],address,00 to 10000 0,0ﻫ ;address=10000/4 经典得MIPS指令有三种格式:R—TYPE、I—TYPE、J—TYPE。其编码格式各不相同,分别代表寄存器操作指令、立即数操作指令、跳转指令。
寄存器操作主要就是将寄存器中得树取出进行运算并存回寄存器;立即数操作为一个寄存器数与指令中得扩展后得立即数进行运算得到结果再存回寄存器;跳转
我们后面得设计都就是对这31条指令进行具体实现,所有得内容紧密围绕这31条指令。
1、2、画数据通路图
在设计完指令后,要做得就就是根据指令描述得功能确定CPU有哪些部件,
并且确定各部件之间得连线方式。首先,一个CPU最重要得部件一定就是控制器。控制器就像人得大脑,控制其她各个部件得工作.其次,由于就是基于MIPS指令集得CPU,大多数操作基于寄存器,因此必须设计一个寄存器堆.此外,ALU运算部件对于CPU来说也就是必不可少得.由于有六条指令涉及比较操作,并且给有效位置位。考虑到本CPU设计初衷就是四级流水控制,若一条指令多个节拍使用ALU部件会造成部件冲突,后期控制会比较复杂。因此,在本CPU中额外设计了一个比较部件。此外,还有其她部件,如PC部件、立即数扩展部件、数据寄存器、地址寄存器等。再根据31条指令,画出数据通路图。
这只就是一个初步得数据通路图,却奠定了CPU得基本构架。可能在后续得详细设计过程中,会对这个数据通路有所改动,但一定就是以现有得图为基础.可以说,这就就是我们将要设计得CPU得一个初步蓝图。
二、详细设计
2、1、控制信号得提取与分析
这一部分可以说就是整个CPU设计过程里最重要、最复杂得过程之一了.在这一部分,我们将依据数据通路图,分析数据通路中所有控制信号得组成与赋值。第一步,我们将31条指令都划分为四个节拍执行完成:取指与译码、取数与ALU操作、主存取数、写回寄存器.我们需要对每一条指令得每一个控制信号进行分析,判断它应该在第几节拍给出.
经分析,我们在CPU工作过程中共需要控制信号38个(其中包括4位ALUCtr),分别就是:0,1,ALU_AR,PC_1,RT_DR,PC_AB,DB_IR,DB_DR,RS_ALU,RT_ALU,DE_ALU,PC_ALU,ZERO_ALU,HEX_ALU,SHAMT_ALU,DR_REG,REG_W,REG_R,ALUCtr0,ALUCtr1,ALUCtr2,ALUCtr3,ADDR_PC,DR_DB,ALU_DR,AR_AB,DR_PC,DR_REG31,PC_W,PC_R,J_PC,IMM_DE,DE_U,RD_REG,RS_REG,RT_REG,RS_,RT_,DE_,_NVST,ZERO_REG,PC_JIE。具体得信号表在附件得Excel中。列出所有控制信号后,对每一条指令需要哪些控制信号,在第几节拍需要这些控制信号都要标识清楚.如对于一号指令有符号数加:在第一节拍(取指与译码),要给出控制信号PC_1,PC_AB,DB_IR,将PC地址传入地址总线并取出相应得指令送入指令寄存器,PC再完成自加一得操作;第二节拍(取数与ALU操作)需要得控制信号就
是RS_ALU,RT_ALU,REG_R,ALU_DR,RS_REG,RT_REG(ALUCtr为0,四个控制信号都不给出),将指令中rs,rt地址传给寄存器,寄存器将对应寄存器中得数取出送到ALU,ALU根据给出得ALUCtr进行不同得操作。第三节拍就是写回寄存器,给出控制信号DR_REG,REG_W,RD_REG,将DR中得数、rd地址送至寄存器,并打开寄存器写开关。用这种方式分析所有指令。
在分析完控制信号后,我们就可以对控制器进行具体设计了。
2、2、各部件具体设计
2、2、1、ALU部件
ALU就是基于指令集来设计得,可完成二进制信息得算术运算、逻辑运算与移位操作,共包含31条MIPS指令。我们将其总结为13种ALU操作类型,用四位二进制数进行编码,如下图所示。这些二进制编码作为ALU控制信号,即aluctr。
编号 操作类型 二进制编码 1 2 3 4 有符号加 无符号加 有符号减 无符号减 0000 0001 0010 0011 5 6 7 8 9 10 11 逻辑左移 1010 与 或 异或 非或 有符号比较 无符号比较 0100 0101 0110 0111 1000 1001
12 13 逻辑右移 1011 数字右移 1100 在ALU中,为符合它得双操作数功能,我们设计了两个寄存器r1与r2,作为ALU得两个输入。经过对指令集得分析,将进入ALU数据来源分为rt、rs,shamt,imm,PC几种类型,为了避免数据操作时发生冲突,将其分别放在两个寄存器中,其中rt、imm放在r1中,rs、shamt与PC放在r2中。除了两个寄存器输入外,还有ALU控制信号输入端口aluctr。一个输出端口out。在ALU运行过程中,从r1、r2中取出数据,根据aluctr给出得控制信号进行相应得运算,从out端口输出.
ALU部件得代码见附录。
2、2、2、PC部件
PC部件就是用来计算下一条指令得,在一般情况下,指令都就是顺序执行下去得,即PC+1,而在遇到跳转指令时,则需要进行其她复杂得操作,所以我们制作得PC部件主要分了这两种操作方法。
在编写得PC部件代码中,共有四个输入端口,分别就是从当前执行得指令中取来得地址address,用于下一条PC得拼接,既然有PC拼接与PC+1得两种操作,我们就分别给出了两个输入得PC操作信号:pc_ctr与pc_pj,另外还有从ALU来得运算结果alu_pc作为第四个输入端口。输出端口有pc_out与pc_alu。当接收到pc_ctr信号时,进行PC+1得操作,而当接收到pc_pj信号时,进行PC得拼接操作。
PC部件得代码见附录。
2、2、3、寄存器组
寄存器就是计算机得一个重要部件,用于暂存数据与指令等。由于考虑到存储空间得大小,我们将原有得32个32位得寄存器组修改为4个32位得寄存器组.
在寄存器组中,存在两个控制信号,分别为读与写,当收到读信号时,我们
接收到得地址所对应得寄存器得数据取出,若接收到得就是写信号,我们就将接收到得数据写回之前发过来得地址所指示得寄存器中。其中,地址得来源有指令中得rs_add,rrt_addr与rd_addr,数据来源为rd_data,共有两个输出端口,分别为rt_out,rs_out。
寄存器组得代码见附录。
2、2、4、立即数扩展部件
立即数扩展部件得主要工作就是将指令中得16位得立即数扩展成为32位得数,并且有有符号扩展与无符号扩展两种。因此,对于一个立即数扩展部件来说,有两个输入一个输出。输入分别就是16位得立即数与控制扩展方式得控制信号,输出就是扩展之后得32位得数。立即数扩展部件具体代码见附录。
2、2、5、比较部件
比较部件就是我们在本次设计中得一个创新点。考虑到每一次比较操作都要经过ALU,而涉及到比较操作得指令除了比较操作本身还会用一次ALU操作,这在流水设计中无疑会带来部件冲突。尽管在发生冲突时,我们可以采用检测冲突、加入阻塞得方法进行排除,但这无疑给控制得设计带来了很大得困难。我们考虑:能否为比较操作专门设置一个比较部件,用来判断两个操作数大小并依据指令类型为标志位赋值。为后面得操作提供依据。
我们设计得比较部件,可以完成如下四种操作:判等置1,判不等置1,判大于置1,判小于置1。因此比较部件有四个输入:比较控制信号1,比较控制信号2(两个信号组合起来表示现在在做哪一种判断),比较数1以及比较数2,一个输出对标志位置位。具体代码见附录。
2、2、6、信号发生器
信号发生器就是根据脉冲信号循环给出节拍控制信号得部件。学过熟悉逻辑得都应该就得不难。首先将clk进行分频,将分频后得信号与clk组合起来,表示四个节拍,从一到四分别为:00,01,10,11。在仿真后出现了下面得情况
(图2、6、1):
图2、6、1
仔细观察可以发现,途中输出信号w1,w2,w3,w4出现了毛刺(如4600ns处w1信号)。在查阅相关资料并向教员请教后我们意识到,这就就是数电中说到得“毛刺”。由于从“01”到“10”,两个输入信号同时发生了变化,所以在变化得一瞬间出现了不想要得“毛刺”。我们又查阅数电书,发现解决毛刺得方法就就是采用“格雷码”编码方式,即每次信号变化时只有一个信号发生变化。因此我们又添加了一个分频信号在clk得时钟下降沿翻转,与原先始终上升沿翻转得信号一起,组成了新得控制信号,从一到四分别为:00,01,11,10.这样产生得信号就符合“格雷码\"编码方式,也不会产生“毛刺”。(如图2、6、2)
图2、6、2
信号发生器源码见附录。
2、2、7、硬布线控制器
在设计CPU之初,我们就决定了使用硬布线方式设计控制器.在IDE工具得帮助下设计硬布线控制器比真实得大规模集成电路设计硬布线要简单得多。运用一些固定得格式,IDE会自动生成硬布线电路.之前在2、1得部分,我们就已经完成了控制信号得提取与分析,这时候只需要细心地将Excel表格中得内容转换成代码.
控制器得输入有六个:6位得OP,6位得FUNC,节拍信号w1,w2,w3,w4,输出为所有控制信号.如在某条指令中,需要在第几节拍给出哪个信号,就将该信号等于对应得节拍输入即可,IDE会自动生成硬布线电路。源码见附录.
实验感悟
唐玲芳得实验感悟
经过几个星期得努力,虽然没能把CPU制作出来,却收获了不少。在这次实验中,我最大得收获就是对计算机组成原理这门课程得理解更加深刻了。在制作得过程中,我们不懂就问,自己动脑去理解,因为我们知道,如果不理解,实验就是无法进行下去得,在教员得悉心帮助下,我们也取得了一些成果。在实验得前期,我们一步一个脚印:确定CPU得功能、能执行指令集,制定通路路线图,分析出所有得控制信号等等。在这个过程中,我们也充分理解到“结构决定功能”这句话,在没能全面考虑到所有得功能时,在通路图上总会少几个部件,只有将所有功能走通了,都能实现了,我们得通路才真得制定完整了.在实验得过程中,我主要参与了ALU部件、寄存器组、PC部件得制作.在编写程序得过程中,也遇到了不少麻烦。比如说部件得中心思想、主要结构没有弄清楚,导致程序出错,而无法进行下去。在之前我们一直以为控制器所给得控制信号就是在ALU内部得,控制信号一来,才知道数据就是从哪来ALU得,然后再从ALU中得寄存器中取出来进行相应得运算,但就是后来才发现,控制器得控制信号并不归ALU管,它就是各部件连接得通路上得,在ALU中我们只需要从寄存器中取数,根据ALU控制信号进行相应得运算就可以了。明白了这一点后,我们得ALU才基本完成了正确得实现。另外就就是我对所用得Verilog语言不够熟悉,很多语法都没有完全掌握,在写程序时,断断续续,影响进度。
总得来说,在这次实验中,我得收获还就是很大得。无论就是对课程得理解还就是对编程、动手能力得提高,都有一定程度得帮助.
戚洪源得实验感悟
在回到信大之前,心里就是非常向往这次实验得.在科大学习了一学期计算机原理,第一次如此深入地接触计算机,当时教员说会在暑期学期用整整两周时间来做这个实验。原本以为自己没有这样得机会,但很幸运还就是解除了这个实验。整体感觉就是:很难.设计CPU不就是纸上谈兵,就是要实实在在写代码烧板子得,一个小小得错误可能就导致了最后得失败。我在试验中最大得感受有以下几点:
一、 万事开头难
做这个实验摆在面前得第一个问题就就是:现在干嘛?这就是一个很实际得问题,如果没有教员指导,应该怎么开始?在实验开始前我就着手资料准备,与许多研究生学长交流之后确定了从指令集到通路图得方案。浴室我着手开始搜关于设计指令集得资料,并且确定以31条MIPS指令集为基础。事后回想起来,真就是万事开头难。当一个复杂得任务来临不知道从何入手时,一定要注意,千万不能自己搞自己那一套,很可能一开始就走到了一个错误得道路上。既然不知道从何入手,就去查资料,请教别人,这就是本次实验得收获之一。
二、 模块化设计思想与黑盒设计思想
CPU这几工作量很大,而且各部分之间紧密联系.首先时间紧,一个人去完成不太可能实现,而合作得话,如何将一个联系非常紧密得东西分开去做呢?这就要用到模块化设计思想与黑盒设计思想。将这个数据通路图中得元器件按照功能进行最小化划分。一个元器件有什么输入什么输出,实现什么样得功能,这与总体连线就是没有太大关联得。确定出来大致有哪几个元器件,分别就是什么输入输出,比如ALU部件,就两个操作数输入,一个控制信号输入,一个结果输出,至于怎么与寄存器堆相连,输出到哪里之类得问题,不需要AlU设计者去考虑。最终,在所有元器件确认没有问题之后进行顶层连线。讲一个个元件瞧成黑盒,元件设计者不需要知道外界怎么连接它,顶层设计者不需要知道内部如何运行。这样,就可以把CPU这个有机得整体合理划分成几小块,交给不同人去分别实现。这种思想还就是令我感触十分深得。在以后得大项目、大问题出现得时候,也可以考虑这种方式进行分工合作。
三、 对于中央处理器有了更深一步得认识
实践就是检验真理得唯一标准。经过这一次得实验,我对于CPU得理解又深了一层。在科大得时候做过一个简单得,七条指令得单周期CPU得元器件连线图,连控制信号都就是教员给出来得,也可以跑指令,当时觉得非常激动。这一次,我自己动手设计31条指领得流水CPU。从设计指令集开始,一步一步地提取控制信号,这个过程得收获非常大。这一次实验让我彻底理解了设计CPU得控
制器应该遵循一个什么样得流程,绝不就是简单复制某本书上得真值表.在走遍31条指令后,整个CPU得数据通路图已经深深刻在我得脑海里。还有太多太多,整个过程得确让我受益匪浅。
四、 对于硬件设计有了更深得了解
原先也学习过数字设计课程,不过几乎没有接触实验。以至于学完之后许多逻辑上得问题根本无法理解.这一次做了实验,再回过头来想想,许多东西就可以理解了.特别就是一些问题得处理,必须用到数电得知识。如:设计信号发生器得时候遇到得“毛刺\"问题,一开始一头雾水,根本不懂为什么会出现这个东西。后来经教员点拨,一下子想起来这就是数电中学习过得“格雷码\"编码问题.这时运用数电知识问题迎刃而解。
五、 总结
总结起来,这一次实验即使最终没有完整地拿出结果来,但就是已经有了许多收获了。今年暑假得时候与科大得教员交流,说到CPU实验得问题时,她说作为一个计算机专业得学生,没有去自己尝试过做一个CPU,还就是有点遗憾得。做过一次,不管结果如何,都会有所收获.现在这学期得实验也告一段落,收获肯定远比上面说得要多。真得不虚此行,后面有机会,一定要把这个CPU再拿出来,把它做完.不知道这个可不可以算一个毕业设计。如果做出来,能算信大CPU第一人吗?哈哈,开玩笑了.
附录
ALU部件源码
module ALU(alucrt,r1,r2,out); input [3:0]alucrt; input [31:0]r1,r2; output reg[31:0]out; always(*) begin
case(alucrt) 0000: begin
if(r2[31]==r1[31]) begin
out[31]=r2[31];
out[30:0]=r2[30:0]+r1[30:0]; end else begin
if(r2[30:0]>r1[30:0]) begin
out[31]=r2[31];
out[30:0]=r2[30:0]-r1[30:0]; end else begin
out[31]=r1[31];
out[30:0]=r1[30:0]-r2[30:0]; end end end 0001: begin
out=r2+r1; end 0010: begin
if(r2[31]==r1[31]) begin
if(r2[30:0]>r1[30:0]) begin
out[31]=r2[31];
out[30:0]=r2[30:0]-r1[30:0];
end else begin
out[31]=r1[31];
out[30:0]=r1[30:0]—r2[30:0]; end end else begin
out[31]=r2[31];
out[30:0]=r2[30:0]+r1[30:0] end end 0011: begin
out=r2-r1; end 0100: begin
out=r2&r1; end 0101: begin
out=r2|r1; end 0110: begin
out=r2^r1; end 0111: begin
out=r2~^r1; end 1000:
;
begin
if(r2[31]==r1[31]) begin
if(r2[31]==1) begin
if(r2[30:0]>r1[30:0]) begin
out=1; end else begin out=0; end end else begin
if(r2[30:0]〈r1[30:0 begin
out=1; end else begin out=0; end end end else begin
if(r1[31]==1) begin out=1; end else begin
])
out=0; end end end 1001: begin
if(r2〈r1) begin out=1; end else begin out=0; end end 1010: begin
out=(r2<<r1); end 1011: begin
out=(r2>>r1); end 1100: begin
out=(r2>>>r1); end endcase end
endmodule
PC部件源码
module PC(address,alu_pc,pc_alu,pc_ctr,pc_pj,pc_out); input [25:0]address;
input [31:0]alu_pc,pc_ctr,pc_pj; output [31:0]pc_out,pc_alu; reg [31:0]r; always(*) begin
if(pc_ctr) begin r=r+4; end
if(pc_pj) begin
r=r+4;
r[27:2]=address; r[1:0]=0; end end endmodule
寄存器组源码
module Register(rs_addr,rt_addr,rd_addr,rd_data,read,write,rt_out,rs_out);
input [4:0]rs_addr,rt_addr,rd_addr; input [31:0]rd_data; input read,write;
output [31:0]rt_out,rs_out; reg [31:0]rt_out,rs_out; reg [31:0]r[0:3]; always(*) begin
if(read) begin
if(rs_addr) begin
case(rs_addr)
00000: begin
rs_out=r[0]; end 00001: begin
rs_out=r[1]; end 00010: begin
rs_out=r[2]; end 00011: begin
rs_out=r[3]; end endcase end
if(rt_addr) begin case(rt_addr) 00000: begin
rt_out=r[0]; end 00001: begin
rt_out=r[1]; end 00010: begin
rt_out=r[2]; end 00011:
begin
rt_out=r[3]; end endcase end end else begin
case(rd_addr) 00000: begin
r[0]=rd_data; end 00001: begin
r[1]=rd_data; end 00010: begin
r[2]=rd_data; end
00011: begin
r[3]=rd_data; end endcase end end endmodule
立即数扩展部件源码
module DE(DE_U,IMM,DE_OUT); input DE_U; input [15:0]IMM;
output [31:0] DE_OUT; reg [31:0] DE_OUT; always(*) begin
ﻩDE_OUT[15:0]=IMM; ﻩif(DE_U=0) ﻩbegin
ﻩDE_OUT[31]=IMM[15]; ﻩDE_OUT[30]=IMM[15]; ﻩﻩDE_OUT[29]=IMM[15];
DE_OUT[28]=IMM[15]; DE_OUT[27]=IMM[15]; DE_OUT[26]=IMM[15];
ﻩDE_OUT[25]=IMM[15]; ﻩﻩDE_OUT[24]=IMM[15];
DE_OUT[23]=IMM[15];
ﻩﻩDE_OUT[22]=IMM[15]; ﻩDE_OUT[21]=IMM[15]; ﻩDE_OUT[20]=IMM[15]; ﻩ DE_OUT[19]=IMM[15]; ﻩﻩDE_OUT[18]=IMM[15]; ﻩ DE_OUT[17]=IMM[15];
DE_OUT[16]=IMM[15];ﻩ
end ﻩelse ﻩbegin
ﻩ DE_OUT[31]=0;
DE_OUT[30]=0;
ﻩ DE_OUT[29]=0; ﻩﻩDE_OUT[28]=0; ﻩDE_OUT[27]=0; ﻩﻩDE_OUT[26]=0; ﻩDE_OUT[25]=0;
DE_OUT[24]=0;
ﻩﻩDE_OUT[23]=0; ﻩﻩDE_OUT[22]=0; ﻩ DE_OUT[21]=0; ﻩDE_OUT[20]=0;
DE_OUT[19]=0;
ﻩDE_OUT[18]=0; ﻩﻩDE_OUT[17]=0; ﻩend end endmodule
DE_OUT[16]=0;
比较部件源码
module (R1,R2,NVST,0,1); input 0,1;
input [31:0] R1,R2; output NVST; reg NVST; reg num; num=0+1*2; always(*) begin ﻩcase(num) ﻩ0: ﻩbegin
if(R1==R2)
ﻩNVST=1; ﻩ else ﻩﻩNVST=0; ﻩend 1: begin ﻩif(R1==R2)
NVST=0;
else NVST=1;
end ﻩ2:
begin ﻩﻩif(R1<R2) ﻩ NVST=1; else
ﻩﻩNVST=0;
ﻩend 3: begin ﻩ if(R1〉R2) ﻩ NVST=1; ﻩelse ﻩ NVST=0; ﻩend endcase end endmodule
信号发生器源码
module signal(clk,w1,w2,winput clk;
output w1,w2,w3,w4; reg w1,w2,w3,w4; reg clk2,clk3; always(posedge clk) begin
ﻩclk2<=~clk2; end
always(negedge clk) begin
clk3〈=~clk3; end
always(clk or clk2) begin
3,w4);
ﻩw1=~clk&~clk2; ﻩw2=~clk2&clk; w3=~clk&clk2; ﻩw4=clk&clk2; end
endmodule
硬布线控制器源码
module control(OP,FUNC,W1,W2,W3,W4,RT_DR,0,1,PC_1,PC_AB,DB_IR,DB_DR,RS_ALU,RT_ALU,DE_ALU,PC_ALU,ZERO_ALU,HEX_ALU,SHAMT_ALU,DR_REG,REG_W,REG_R,ALUCtr0,ALUCtr1,ALUCtr2,ALUCtr3,ADDR_PC,DR_DB,ALU_DR,ALU_AR,AR_AB,DR_PC,DR_REG31,PC_W,PC_R,J_PC,IMM_DE,DE_U,RD_REG,RS_REG,RT_REG,RS_,RT_,DE_,_NVST,ZERO_REG,PC_JIE);
input W1,W2,W3,W4; input [5:0] OP,FUNC;
output 0,1,ALU_AR,PC_1,RT_DR,PC_AB,DB_IR,DB_DR,RS_ALU,RT_ALU,DE_ALU,PC_ALU,ZERO_ALU,HEX_ALU,SHAMT_ALU,DR_REG,REG_W,REG_R,ALUCtr0,ALUCtr1,ALUCtr2,ALUCtr3,ADDR_PC,DR_DB,ALU_DR,AR_AB,DR_PC,DR_REG31,PC_W,PC_R,J_PC,IMM_DE,DE_U,RD_REG,RS_REG,RT_REG,RS_,RT_,DE_,_NVST,ZERO_REG,PC_JIE;
reg 0,1,ALU_AR,PC_1,RT_DR,PC_AB,DB_IR,DB_DR,RS_ALU,RT_ALU,DE_ALU,PC_ALU,ZERO_ALU,HEX_ALU,SHAMT_ALU,DR_REG,REG_W,REG_R,ALUCtr0,ALUCtr1,ALUCtr2,ALUCtr3,ADDR_PC,DR_DB,ALU_DR,AR_AB,DR_PC,DR_REG31,PC_W,PC_R,J_PC,IMM_DE,DE_U,RD_REG,RS_REG,RT_REG,RS_,RT_,DE_,_NVST,ZERO_REG,PC_JIE;
always(W1 or W2 or W3 or W4) begin PC_1=0; PC_AB=0; ﻩDB_IR=0; ﻩDB_DR=0; RS_ALU=0; RT_ALU=0; DE_ALU=0; PC_ALU=0;
ZERO_ALU=0; HEX_ALU=0; SHAMT_ALU=0; ﻩDR_REG=0; REG_W=0; REG_R=0; ALUCtr0=0; ﻩALUCtr1=0; ﻩALUCtr2=0; ﻩALUCtr3=0; ADDR_PC=0; DR_DB=0; ALU_DR=0; ﻩAR_AB=0; ﻩDR_PC=0; DR_REG31=0; PC_W=0; ﻩPC_R=0; ﻩJ_PC=0; ﻩIMM_DE=0; ﻩDE_U=0; RD_REG=0; ﻩRS_REG=0; RT_REG=0; RS_=0; ﻩRT_=0; ﻩDE_=0; ﻩ_NVST=0; ZERO_REG=0; ﻩPC_JIE=0; case(OP) ﻩ 000000:
begin
ﻩcase(FUNC)
ﻩ ﻩ100000: ﻩ
begin
ﻩ ﻩﻩPC_1=W1; ﻩ ﻩPC_AB=W1; ﻩﻩ DB_IR=W1; ﻩﻩﻩ
RS_ALU=W2; ﻩﻩRT_ALU=W2;
DR_REG=W3; REG_W=W3;
ﻩ ﻩﻩﻩ
ﻩ ﻩﻩREG_R=W2;
ﻩﻩALU_DR=W2; ﻩﻩRD_REG=W3;
RS_REG=W2;
RT_REG=W2;
ﻩﻩﻩend ﻩﻩ 100001:
ﻩbegin
PC_1=W1;
ﻩ
ﻩ ﻩPC_AB=W1; ﻩﻩﻩDB_IR=W1; ﻩﻩﻩRS_ALU=W2; ﻩ ﻩ RT_ALU=W2; ﻩﻩ ﻩDR_REG=W3; ﻩ ﻩ
ﻩREG_W=W3; ﻩALU_DR=W2;
ﻩﻩﻩﻩREG_R=W2; ﻩﻩﻩﻩRD_REG=W3; ﻩ ﻩ RS_REG=W2; ﻩ ﻩ ﻩend ﻩﻩ 100010: ﻩ ﻩbegin ﻩ ﻩ PC_1=W1;
RT_REG=W2;
ﻩﻩ ALUCtr0=W2;
ﻩﻩ PC_AB=W1; ﻩﻩﻩﻩDB_IR=W1; ﻩ
ﻩRS_ALU=W2;
ﻩﻩﻩﻩRT_ALU=W2; ﻩﻩ DR_REG=W3; ﻩ ﻩ
ﻩREG_W=W3; ﻩREG_R=W2;
ﻩ ﻩALU_DR=W2; ﻩ ﻩﻩRD_REG=W3; ﻩ ﻩ RS_REG=W2; ﻩﻩﻩﻩRT_REG=W2; ﻩ
ALUCtr1=W2;
ﻩﻩ end
ﻩ100011: ﻩbegin
ﻩPC_1=W1; PC_AB=W1;
ﻩ
ﻩﻩ ﻩDB_IR=W1; ﻩﻩﻩﻩRS_ALU=W2; ﻩ ﻩﻩRT_ALU=W2; ﻩﻩ
DR_REG=W3;
ﻩ ﻩREG_W=W3; ﻩﻩﻩREG_R=W2;
ﻩALU_DR=W2;
ﻩ ﻩRD_REG=W3; ﻩ ﻩRS_REG=W2; ﻩﻩ ﻩRT_REG=W2; ﻩ ﻩﻩﻩ ﻩ ﻩend ﻩﻩ 100100: ﻩ begin ﻩﻩ ﻩPC_1=W1; ﻩ
PC_AB=W1; ALUCtr0=W2; ALUCtr1=W2;
ﻩ ﻩﻩ
ﻩDB_IR=W1; RS_ALU=W2;
ﻩﻩﻩRT_ALU=W2; ﻩ ﻩ DR_REG=W3;
ﻩ REG_W=W3;
ﻩﻩﻩﻩREG_R=W2; ﻩﻩﻩﻩALU_DR=W2; ﻩ
RD_REG=W3;
ﻩﻩ RS_REG=W2;
ﻩﻩRT_REG=W2;
ﻩﻩ ALUCtr2=W2; ﻩ ﻩend ﻩﻩﻩ100101:
ﻩbegin
ﻩﻩﻩﻩPC_1=W1; ﻩ ﻩﻩPC_AB=W1; ﻩﻩ ﻩDB_IR=W1; ﻩ
ﻩRS_ALU=W2; ﻩ DR_REG=W3;
ﻩﻩ RT_ALU=W2; ﻩﻩﻩﻩREG_W=W3; ﻩ ﻩ REG_R=W2; ﻩ ﻩ ALU_DR=W2; ﻩﻩﻩﻩRD_REG=W3; ﻩ ﻩ ﻩ ﻩﻩﻩ ﻩﻩﻩ ﻩ
ﻩRS_REG=W2; ﻩRT_REG=W2; ﻩALUCtr2=W2; ALUCtr0=W2; ﻩend
100110:
ﻩ ﻩbegin
PC_1=W1; ﻩPC_AB=W1;
DB_IR=W1;
ﻩﻩﻩRS_ALU=W2; ﻩﻩ ﻩRT_ALU=W2; ﻩﻩﻩ ﻩﻩ ﻩ
DR_REG=W3; REG_W=W3; ﻩREG_R=W2;
ﻩALU_DR=W2; ﻩﻩRD_REG=W3; ﻩ RT_REG=W2;
ﻩﻩﻩRS_REG=W2; ﻩﻩﻩﻩALUCtr2=W2; ﻩ ﻩ ALUCtr1=W2; ﻩﻩ
ﻩend
100111: begin
ﻩﻩPC_1=W1; DB_IR=W1;
ﻩﻩﻩPC_AB=W1; ﻩﻩ ﻩRS_ALU=W2; ﻩ ﻩ RT_ALU=W2;
ﻩDR_REG=W3;
ﻩ ﻩREG_W=W3; ﻩﻩ REG_R=W2; ﻩﻩ ﻩALU_DR=W2;
ﻩRD_REG=W3;
ﻩ ﻩﻩRS_REG=W2; ﻩ ﻩRT_REG=W2; ﻩﻩ ﻩﻩﻩ
ALUCtr2=W2;
ALUCtr1=W2;
ALUCtr0=W2;
ﻩ end
ﻩ 101010: ﻩ begin ﻩﻩﻩend ﻩﻩ 101011:
ﻩﻩﻩbegin ﻩﻩﻩend ﻩ
000000:
ﻩﻩ begin
ﻩ ﻩPC_1=W1; ﻩﻩ ﻩPC_AB=W1; ﻩ ﻩDB_IR=W1; ﻩﻩﻩ ﻩ
SHAMT_ALU=W2; ﻩRT_ALU=W2; ﻩﻩDR_REG=W3;
REG_R=W2; RD_REG=W3;
ﻩ ﻩ REG_W=W3; ﻩ ﻩ
ﻩ ALU_DR=W2;
ﻩ ﻩ RT_REG=W2; ﻩﻩﻩALUCtr3=W2; ﻩ
ALUCtr1=W2;
ﻩﻩ end ﻩ ﻩ000010: ﻩﻩbegin ﻩﻩ ﻩPC_1=W1; ﻩ ﻩ PC_AB=W1; ﻩ ﻩ DB_IR=W1; ﻩﻩ SHAMT_ALU=W2; ﻩ ﻩﻩ ﻩﻩﻩ ﻩﻩﻩ
RT_ALU=W2;
ﻩﻩﻩDR_REG=W3;
REG_W=W3; ﻩ REG_R=W2; ALU_DR=W2; ﻩﻩRD_REG=W3; RT_REG=W2; ﻩﻩALUCtr3=W2; ﻩﻩALUCtr0=W2;
ﻩﻩﻩﻩALUCtr1=W2;
ﻩ ﻩ ﻩﻩﻩ ﻩ ﻩ ﻩﻩ ﻩ ﻩﻩ
ﻩend 000011: begin PC_AB=W1;
ﻩﻩSHAMT_ALU=W2;
DR_REG=W3; REG_R=W2;
ﻩ ﻩ PC_1=W1; ﻩ ﻩDB_IR=W1; ﻩﻩﻩRT_ALU=W2; ﻩ ﻩ REG_W=W3; ﻩﻩ ﻩALU_DR=W2;
RD_REG=W3; ﻩ RT_REG=W2;
ALUCtr3=W2; ALUCtr2=W2;
ﻩﻩend ﻩﻩ 000100: ﻩﻩ begin ﻩﻩ ﻩPC_1=W1; ﻩ ﻩ PC_AB=W1; ﻩ
ﻩDB_IR=W1;
ﻩﻩ ﻩRS_ALU=W2; ﻩ ﻩﻩRT_ALU=W2; ﻩ
DR_REG=W3;
ﻩﻩ ﻩREG_W=W3; ﻩﻩ REG_R=W2; ﻩﻩﻩ ﻩ
ALU_DR=W2;
RS_REG=W2;
ﻩﻩ RD_REG=W3;
RT_REG=W2; ALUCtr1=W2;
ﻩ ﻩ ALUCtr3=W2; ﻩ
ﻩend
ﻩﻩﻩ000110: ﻩﻩ begin
ﻩ ﻩﻩPC_1=W1; ﻩﻩﻩ
ﻩﻩPC_AB=W1; DB_IR=W1;
ﻩﻩﻩﻩRS_ALU=W2; ﻩ ﻩﻩRT_ALU=W2; ﻩﻩﻩDR_REG=W3; ﻩ ﻩﻩ
ﻩREG_W=W3; REG_R=W2;
ﻩﻩﻩALU_DR=W2; ﻩ ﻩﻩRD_REG=W3; ﻩ ﻩRS_REG=W2; ﻩ ﻩRT_REG=W2; ﻩ
ALUCtr3=W2; ALUCtr1=W2;
ﻩ ﻩﻩend
ﻩ 000111:
ﻩbegin
PC_AB=W1; ﻩDB_IR=W1;
ﻩﻩﻩPC_1=W1; ﻩ ﻩ
ﻩﻩ ALUCtr0=W2;
ﻩﻩ RS_ALU=W2;
ﻩ RT_ALU=W2;
ﻩDR_REG=W3;
ﻩﻩ ﻩREG_W=W3;
ﻩREG_R=W2;
ﻩﻩﻩALU_DR=W2; ﻩﻩ RD_REG=W3; ﻩ ﻩﻩ
ﻩRS_REG=W2; ALUCtr3=W2;
ﻩ ﻩﻩRT_REG=W2; ﻩﻩﻩﻩALUCtr2=W2;
ﻩ end ﻩ 001000: ﻩﻩbegin ﻩ
ﻩPC_1=W1; ﻩPC_AB=W1; ﻩ RS_ALU=W2;
ﻩ ﻩ DB_IR=W1; ﻩ ﻩ ZERO_ALU=W2; ﻩ ﻩREG_R=W2; ﻩﻩ ALU_DR=W2; ﻩﻩ RS_REG=W2; ﻩ ﻩ DR_PC=W3; ﻩﻩﻩﻩPC_W=W3; ﻩ ﻩend ﻩ ﻩ ﻩ
endcase end begin ﻩPC_1=W1; PC_AB=W1; RS_ALU=W2; IMM_DE=W2;
ﻩ001000:
ﻩﻩﻩDB_IR=W1; ﻩ DE_ALU=W2; ﻩﻩ DR_REG=W3; ﻩﻩﻩREG_W=W3;
ﻩREG_R=W2; ﻩRS_REG=W2;
RT_REG=W3; end begin
ﻩﻩﻩALU_DR=W2;
ﻩ 001001: ﻩﻩ PC_1=W1;
PC_AB=W1;
ﻩﻩDB_IR=W1; ﻩﻩRS_ALU=W2; ﻩ ﻩDE_ALU=W2; ﻩﻩ IMM_DE=W2; ﻩ DR_REG=W3; ﻩ
REG_W=W3;
ﻩﻩREG_R=W2; ﻩ ALU_DR=W2; ﻩ
RS_REG=W2;
ﻩﻩRT_REG=W3; ﻩﻩ ALUCtr0=W2;
ﻩDE_U=W2;
ﻩ end ﻩ 001100: ﻩbegin ﻩﻩﻩPC_1=W1;
ﻩPC_AB=W1; ﻩDB_IR=W1;
RS_ALU=W2;
ﻩﻩDE_ALU=W2; ﻩﻩﻩIMM_DE=W2; ﻩ ﻩ
DR_REG=W3; ﻩREG_W=W3; REG_R=W2;
ALU_DR=W2;
ﻩ ﻩRS_REG=W2;
RT_REG=W3;
ﻩ ﻩALUCtr2=W2; ﻩ DE_U=W2; ﻩ end ﻩﻩ001101: ﻩﻩbegin ﻩﻩﻩPC_1=W1;
ﻩﻩﻩPC_AB=W1; ﻩ
DB_IR=W1;
ﻩ ﻩRS_ALU=W2; ﻩﻩﻩDE_ALU=W2; ﻩﻩﻩIMM_DE=W2; ﻩ ﻩDR_REG=W3; ﻩﻩREG_W=W3; ﻩ
REG_R=W2;
ﻩﻩALU_DR=W2;
ﻩRS_REG=W2; ALUCtr2=W2;
ALUCtr0=W2;
ﻩﻩ RT_REG=W3;
ﻩﻩﻩDE_U=W2; ﻩ end
001110: begin
ﻩﻩ PC_1=W1; ﻩ ﻩPC_AB=W1; ﻩﻩﻩDB_IR=W1;
ﻩRS_ALU=W2;
ﻩ ﻩDE_ALU=W2; ﻩﻩ IMM_DE=W2; ﻩﻩ DR_REG=W3; ﻩ REG_W=W3;
ﻩREG_R=W2;
ﻩﻩALU_DR=W2; ﻩ ﻩRS_REG=W2; ﻩ ﻩRT_REG=W3; ﻩﻩALUCtr1=W2; ﻩ
ALUCtr2=W2; DE_U=W2; end 001111:
ﻩ begin ﻩ ﻩ
PC_1=W1;
DB_IR=W1;
ﻩﻩPC_AB=W1; ﻩﻩﻩHEX_ALU=W2;
ﻩDE_ALU=W2; IMM_DE=W2;
ﻩ ﻩDR_REG=W3; ﻩﻩ REG_W=W3; ﻩﻩﻩALU_DR=W2; ﻩﻩﻩRT_REG=W3;
ALUCtr1=W2;
ﻩ ALUCtr3=W2; ﻩ DE_U=W2; ﻩ end ﻩ 100011: ﻩﻩbegin
PC_1=W1;
ﻩ ﻩPC_AB=W1; ﻩ DB_IR=W1; ﻩ DB_DR=W3; ﻩ ﻩRS_ALU=W2; ﻩﻩﻩDE_ALU=W2; ﻩ ﻩIMM_DE=W2; ﻩ ﻩDR_REG=W4; ﻩ ﻩREG_W=W4; ﻩ ﻩREG_R=W2; ﻩﻩALU_AR=W2; ﻩ
AR_AB=W3;
ﻩ ﻩRS_REG=W2; ﻩﻩﻩRT_REG=W4; ﻩ ALUCtr0=W2;
end
ﻩ101011:
ﻩﻩbegin ﻩ PC_1=W1; ﻩ PC_AB=W1; ﻩ
DB_IR=W1; ﻩDR_DB=W3;
ﻩ ﻩRS_ALU=W2; ﻩﻩ DE_ALU=W2; ﻩ ﻩIMM_DE=W2; ﻩ ﻩREG_R=W2; ﻩﻩ ALU_AR=W2; ﻩﻩAR_AB=W3; ﻩ RS_REG=W2;
RT_DR=W2;
ﻩ ﻩALUCtr0=W2; ﻩend ﻩ000100:
begin
ﻩﻩPC_1=W1; ﻩ PC_AB=W1; ﻩﻩDB_IR=W1; ﻩ DE_ALU=W2; ﻩ ﻩ
PC_ALU=W2; REG_R=W2;
ﻩﻩALUCtr0=W2; ﻩﻩALU_DR=W2;
ﻩDR_PC=W3; ﻩPC_R=W2;
ﻩ PC_W=W3; ﻩ IMM_DE=W2; ﻩﻩ RS_REG=W2; ﻩﻩ RT_REG=W2; ﻩﻩ RS_=W2;
RT_=W2;
ﻩ ﻩ_NVST=W2;
end 000101:
ﻩ begin ﻩﻩﻩPC_1=W1;
ﻩPC_AB=W1; ﻩDB_IR=W1;
PC_ALU=W2;
ﻩﻩﻩDE_ALU=W2;
ﻩREG_R=W2;
ﻩﻩ ALUCtr0=W2; ﻩﻩ ALU_DR=W2; ﻩ
DR_PC=W3;
ﻩﻩﻩPC_W=W3; ﻩﻩﻩPC_R=W2; ﻩﻩIMM_DE=W2; ﻩﻩRS_REG=W2; ﻩﻩRT_REG=W2; ﻩ RS_=W2;
RT_=W2;
ﻩﻩ_NVST=W2; ﻩﻩ 0=W2; ﻩ end ﻩﻩ001010: ﻩ begin
PC_1=W1;
ﻩﻩPC_AB=W1; ﻩﻩﻩDB_IR=W1; ﻩﻩﻩREG_W=W3; ﻩ ﻩ ﻩ
REG_R=W2;
IMM_DE=W2; RT_REG=W3; RS_REG=W2;
ﻩﻩ RS_=W2;
DE_=W2;
ﻩ_NVST=W2;
1=W2;
ﻩ end ﻩ001011: ﻩbegin ﻩﻩPC_1=W1; ﻩ ﻩ ﻩ
PC_AB=W1; REG_W=W3; REG_R=W2;
ﻩﻩﻩDB_IR=W1;
ﻩﻩ IMM_DE=W2; ﻩﻩ RS_REG=W2; ﻩﻩRT_REG=W3;
ﻩRS_=W2;
ﻩﻩ DE_=W2; ﻩﻩ _NVST=W2;
1=W2; 0=W2;
ﻩ DE_U=W2; ﻩ end
000010:
ﻩ begin ﻩ ﻩPC_1=W1; ﻩ ﻩPC_AB=W1; ﻩﻩﻩDB_IR=W1; ﻩ
PC_JIE=W2; 000011: ﻩPC_1=W1;
DB_IR=W1;
ﻩﻩend ﻩﻩbegin ﻩﻩPC_AB=W1;
ﻩPC_ALU=W2; ﻩZERO_ALU=W2;
ﻩ ﻩDR_REG=W3;
ﻩALUCtr0=W2;
ﻩﻩ ALU_DR=W2; ﻩ PC_W=W3; ﻩﻩﻩPC_JIE=W3; ﻩﻩend ﻩendcaseﻩ end endmodule
因篇幅问题不能全部显示,请点此查看更多更全内容