华中科技大学HUST类MIPS单周期微处理器设计实验报告.docx
- 文档编号:26309578
- 上传时间:2023-06-17
- 格式:DOCX
- 页数:29
- 大小:677.38KB
华中科技大学HUST类MIPS单周期微处理器设计实验报告.docx
《华中科技大学HUST类MIPS单周期微处理器设计实验报告.docx》由会员分享,可在线阅读,更多相关《华中科技大学HUST类MIPS单周期微处理器设计实验报告.docx(29页珍藏版)》请在冰豆网上搜索。
华中科技大学HUST类MIPS单周期微处理器设计实验报告
类MIPS单周期微处理器设计
实验报告
专业:
班级:
学号:
姓名:
一、微处理器各模块设计
各模块的框图结构如上图所示。
由图可知,该处理器包含指令存储器、数据存储器、寄存器组、ALU单元、符号数扩张、控制器、ALU控制译码以及多路复用器等。
图中还忽略了一个单元:
时钟信号产生器,而且以上各个部件必须在时钟信号的控制下协调工作。
1.指令存储器的设计
指令寄存器为ROM类型的存储器,为单一输出指令的存储器。
因此其对外的接口为clk、存储器地址输入信号(指令指针)以及数据输出信号(指令)。
(1)在IPwizard中配置ROM,分配128个字的存储空间,字长为32位宽。
(2)选择输入具有地址寄存功能,只有当时钟上升沿有效时,才进行数据的输出。
(3)配置ROM内存空间的初始化COE文件。
最后单击Generate按钮生成IROM模块。
2.数据存储器的设计
数据存储器为RAM类型的存储器,并且需要独立的读写控制信号。
因此其对外的接口输入信号为clk、we、datain、addr;输出信号为dataout。
数据存储器基本建立过程同ROM的建立。
3.寄存器组设计
寄存器组是指令操作的主要对象,MIPS中一共有32个32位寄存器。
在指令的操作过程中需要区分Rs、Rt、Rd的地址和数据,并且Rd的数据只有在寄存器写信号有效时才能写入,因此该模块的输入为clk、RegWriteAddr、RegWriteData、RegWriteEn、RsAddr、RtAddr、reset;输出信号为RsData、RtData。
由于$0一直输出0,因此当RsAddr、RtAddr为0时,RsData以及RtData必须输出0,否则输出相应地址寄存器的值。
另外,当RegWriteEn有效时,数据应该写入RegWriteAddr寄存器。
并且每次复位时所有寄存器都清零。
代码如下:
moduleregFile(
inputclk,
inputreset,
input[31:
0]regWriteData,
input[4:
0]regWriteAddr,
inputregWriteEn,
output[31:
0]RsData,
output[31:
0]RtData,
input[4:
0]RsAddr,
input[4:
0]RtAddr
);
reg[31:
0]regs[0:
31];
assignRsData=(RsAddr==5'b0)?
32'b0:
regs[RsAddr];
assignRtData=(RtAddr==5'b0)?
32'b0:
regs[RtAddr];
integeri;
always@(posedgeclk)
begin
if(!
reset)
begin
if(regWriteEn==1)
begin
regs[regWriteAddr]=regWriteData;
end
end
else
begin
for(i=0;i<31;i=i+1)
regs[i]=0;
regs[31]=32'hffffffff;
end
end
endmodule
4.ALU设计
在这个简单的MIPS指令集中,微处理器支持add、sub、and、or、slt运算指令,需要利用ALU单元实现运算,同时数据存储指令sw、lw也需要ALU单元计算存储器地址,条件跳转指令beq需要ALU来比较两个寄存器是否相等。
所有这些指令包含的操作为加、减、与、或小于设置5种不同的操作。
该模块根据输入控制信号对输入数据进行相应的操作,并获得输出结果以及零标示,由于MIPS处理器ALU单元利用4根输入控制线的译码决定执行何种操作,因此该模块的接口为:
输入:
input1(32bit),input2(32bit),aluCtr(4bit)
输出:
zero(1bit),alluRes(32bit)
代码如下:
moduleALU(
input[31:
0]input1,
input[31:
0]input2,
input[3:
0]aluCtr,
output[31:
0]aluRes,
outputzero
);
regzero;
reg[31:
0]aluRes;
always@(input1orinput2oraluCtr)
begin
case(aluCtr)
4'b0110:
begin
aluRes=input1-input2;
if(aluRes==0)
zero=1;
else
zero=0;
end
4'b0010:
aluRes=input1+input2;
4'b0000:
aluRes=input1&input2;
4'b0001:
aluRes=input1|input2;
4'b1100:
aluRes=~(input1|input2);
4'b0111:
begin
if(input1 aluRes=1; end default: aluRes=0; endcase end endmodule 5.ALU控制设计 ALU单元对应以上5种操作的编码如表所示: 输入信号 操作类型 0000 与 0001 或 0010 加 0110 减 0111 小于设置 通过2位操作类型码以及6位指令功能码就可以产生ALU单元的4位控制信号。 它们之间的对应关系如表所示: 因此该模块的主要功能就是根据译码控制单元产生2位操作码以及6位功能码产生4位ALU控制信号,接口为: 输入: aluop(2bit),funt(6bit) 输出: aluctr(4bit) 代码为: modulealuctr( input[1: 0]ALUOp, input[5: 0]funct, output[3: 0]ALUCtr ); reg[3: 0]ALUCtr; always@(ALUOporfunct) casex({ALUOp,funct}) 8'b00xxxxxx: ALUCtr=4'b0010; 8'b01xxxxxx: ALUCtr=4'b0110; 8'b11xxxxxx: ALUCtr=4'b0000; 8'b10xx0000: ALUCtr=4'b0010; 8'b10xx0010: ALUCtr=4'b0110; 8'b10xx0100: ALUCtr=4'b0000; 8'b10xx0101: ALUCtr=4'b0001; 8'b10xx1010: ALUCtr=4'b0111; endcase endmodule 6.控制器设计 控制器输入为指令的opCode字段,即操作码。 操作码经过主控制单元的译码,给ALUCtr、Data、Memory、Registers、Muxs等部件输出正的控制信号。 微处理器在执行不同指令时,控制信号相对应的状态表如下: 因此该模块的接口为: 输入: opcode(6bit) 输出: alusrc,memtoreg,regwrite,memread,memwrite,branch,,aluop[1: 0],jmp 代码为: modulectr( input[5: 0]opCode, outputregDst, outputaluSrc, outputmemToReg, outputregWrite, outputmemRead, outputmemWrite, outputbranch, output[1: 0]aluop, outputjmp ); regregDst; regaluSrc; regmemToReg; regregWrite; regmemRead; regmemWrite; regbranch; reg[1: 0]aluop; regjmp; always@(opCode) begin case(opCode) 6'b000010: //jmp begin regDst=0; aluSrc=0; memToReg=0; regWrite=0; memRead=0; memWrite=0; branch=0; aluop=2'b00; jmp=1; end 6'b000000: //R begin regDst=1; aluSrc=0; memToReg=0; regWrite=1; memRead=0; memWrite=0; branch=0; aluop=2'b10; jmp=0; end 6'b100011: //lw begin regDst=0; aluSrc=1; memToReg=1; regWrite=1; memRead=1; memWrite=0; branch=0; aluop=2'b00; jmp=0; end 6'b101011: //sw begin regDst=0; aluSrc=1; memToReg=0; regWrite=0; memRead=0; memWrite=1; branch=0; aluop=2'b00; jmp=0; end 6'b000100: //beq begin regDst=0; aluSrc=0; memToReg=0; regWrite=0; memRead=0; memWrite=0; branch=1; aluop=2'b01; jmp=0; end 6'b001100: //andi begin regDst=0; aluSrc=1; memToReg=0; regWrite=1; memRead=0; memWrite=0; branch=0; aluop=2'b11; jmp=0; end default: begin regDst=0; aluSrc=0; memToReg=0; regWrite=0; memRead=0; memWrite=0; branch=0; aluop=2'b00; jmp=0; end endcase end endmodule 7.符号数扩展 将16位有符号扩展为32位有符号数。 带符号扩展只需要在前面补足符号即可。 代码为: modulesignext( input[15: 0]inst, output[31: 0]data ); assigndata=inst[15: 15]? {16'hffff,inst}: {16'h0000,inst}; endmodule 8.顶层模块 顶层模块需要将前面多个模块实例化,通过导线以及多路复用器将各个部件连接起来,并且在时钟的控制下修改PC的值,PC是一个32位的寄存器,每个时钟沿自动增加4。 多路复用器MUX直接通过三目运算符实现: AssignOUT=SEL? INPUT1: INPUT2; 其中,OUT、SEL、INPUT1、INPUT2都是预先定义的信号。 代码如下: moduletop( inputclkin, inputreset ); reg[31: 0]pc,add4; wirechoose4; wire[31: 0]expand2,mux2,mux3,mux4,mux5,address,jmpaddr,inst; wire[4: 0]mux1; //wireforcontroller wirereg_dst,jmp,branch,memread,memwrite,memtoreg; wire[1: 0]aluop; wirealu_src,regwrite; //wireforaluunit wirezero; wire[31: 0]aluRes; //wireforaluctr wire[3: 0]aluCtr; //wireformemory wire[31: 0]memreaddata; //wireforregister wire[31: 0]RsData,RtData; //wireforext wire[31: 0]expand; always@(negedgeclkin) begin if(! reset)begin pc=mux5; add4=pc+4; end elsebegin pc=32'b0; add4=32'h4; end end ctrmainctr( .opCode(inst[31: 26]), .regDst(reg_dst), .aluSrc(alu_scr), .memToReg(memtoreg), .regWrite(regwrite), .memRead(memread), .memWrite(memwrite), .branch(branch), .aluop(aluop), .jmp(jmp)); ALUalu(.input1(RsData), .input2(mux2), .aluCtr(aluCtr), .zero(zero), .aluRes(aluRes)); aluctraluctr1(.ALUOp(aluop), .funct(inst[5: 0]), .ALUCtr(aluCtr)); dramdmem( .a(aluRes[7: 2]), .d(RtData), .clk(! clkin), .we(memwrite), .spo(memreaddata) ); irom_numberimem( .a(pc[8: 2]), .clk(clkin), .spo(inst) ); regFileregfile( .RsAddr(inst[25: 21]), .RtAddr(inst[20: 16]), .clk(! clkin), .reset(reset), .regWriteAddr(mux1), .regWriteData(mux3), .regWriteEn(regwrite), .RsData(RsData), .RtData(RtData) ); signextsignext(.inst(inst[15: 0]),.data(expand)); assignmux1=reg_dst? inst[15: 11]: inst[20: 16]; assignmux2=alu_scr? expand: RtData; assignmux3=memtoreg? memreaddata: aluRes; assignmux4=choose4? address: add4; assignmux5=jmp? jmpaddr: mux4; assignchoose4=branch&zero; assignexpand2=expand<<2; assignjmpaddr={add4[31: 28],inst[25: 0],2'b00}; assignaddress=pc+expand2; endmodule 二、Rom汇编程序设计 下面以将本人学号U201513343的ASCII码存入RAM的连续内存区域编写为汇编程序为例: 编辑MIPS汇编源代码: 采用ultraedit编辑汇编源程序代码,并保存为number.asm文件。 代码如下: main: andi$2,$31,85#U sw$2,0($3) andi$2,$31,50#2 sw$2,4($3) andi$2,$31,48#0 sw$2,8($3) andi$2,$31,49#1 sw$2,12($3) andi$2,$31,53#5 sw$2,16($3) andi$2,$31,49#1 sw$2,20($3) andi$2,$31,51#3 sw$2,24($3) andi$2,$31,51#3 sw$2,28($3) andi$2,$31,52#4 sw$2,32($3) andi$2,$31,51#3 sw$2,36($3) jmain 获取机器代码,并保存为coe文件: 利用QtSpim装载number.asm,并测试功能是否正常。 装载之后的用户代码段在QtSpim中的结构如附图所示: 提取的用户代码对应的机器码,并把jmain指令对应的机器码0x08100009修改为0x08000000。 将上述机器指令保存在ultraedit中新的文件中,添加coe文件头描述语句,完成后的完整coe文件内容如下: MEMORY_INITIALIZATION_RADIX=16; MEMORY_INITIALIZATION_VECTOR= 33e20055, ac620000, 33e20032, ac620004, 33e20030, ac620008, 33e20031, ac62000c, 33e20035, ac620010, 33e20031, ac620014, 33e20033, ac620018, 33e20033, ac62001c, 33e20034, ac620020, 33e20033, ac620024, 08000000, 将该文件保存为coe文件,即number.coe。 至此,coe文件制作完成。 最后,把coe文件导入irom中,如下图所示: 三、模块仿真 1.寄存器组仿真: 建立仿真代码,在自动生成的激励代码基础上加入功能仿真需要的代码: reset测试、写入测试、输出测试等、完整代码如下: moduleregsim; //Inputs regclk; regreset; reg[31: 0]regWriteData; reg[4: 0]regWriteAddr; regregWriteEn; reg[4: 0]RsAddr; reg[4: 0]RtAddr; //Outputs wire[31: 0]RsData; wire[31: 0]RtData; //InstantiatetheUnitUnderTest(UUT) regFileuut( .clk(clk), .reset(reset), .regWriteData(regWriteData), .regWriteAddr(regWriteAddr), .regWriteEn(regWriteEn), .RsData(RsData), .RtData(RtData), .RsAddr(RsAddr), .RtAddr(RtAddr) ); integeri; initialbegin //InitializeInputs clk=0; reset=0; regWriteData=0; regWriteAddr=0; regWriteEn=0; RsAddr=0; RtAddr=0; //Wait100nsforglobalresettofinish #100; //Addstimulushere regWriteData=32'h55aaaa55; regWriteEn=1; reset=1; #100; reset=0; end parameterPERIOD=20; alwaysbegin clk=1'b0; #(PERIOD/2)clk=1'b1; #(PERIOD/2); end alwaysbegin for(i=31;i>=1;i=i-1)begin regWriteAddr=i; RsAddr=i; #PERIOD; end end endmodule 仿真结果如下: 下图可以观察到Reset为高电平状态。 Reset高电平状态下输出数据为0,表示Reset有效地工作了。 Reset信号无效后,正常输入和输出数据。 第一次for循环的地址范围输出数据在时钟低电平时输出0,高电平输出0x55aaaa55,如下图所示,表明数据正确地在时钟上升沿写入的。 之后一直输出的数据与写入的数据相同,表明数据都正确地保存在寄存器组中。 2.控制器仿真: 控制器仿真需要包含所有case的输入,仿真激励文件修改代码后,如下: modulectrsim; //Inputs reg[5: 0]opCode; //Outputs wireregDst; wirealuSrc; wirememToReg; wireregWrite; wirememRead; wirememWrite; wirebranch; wire[1: 0]aluop; wirejmp; //InstantiatetheUnitUnderTest(UUT) ctruut( .opCode(opCode), .regDst(regDst), .aluSrc(aluSrc), .memToReg(memToReg), .regWrite(regWrite), .memRead(memRead), .memWrite(memWrite), .branch(branch), .aluop(aluop), .jmp(jmp) ); initialbegin //InitializeInputs opCode=0; //Wait100nsforglobalresettofinish #100; opCode=6'b000010;//jump #100; opCode=6'b000000;//R #100; opCode=6'b100011;//lw #100; opCode
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 华中科技大学 HUST MIPS 周期 微处理器 设计 实验 报告