杭电计算机组成原理课程设计-实验十一-实现R型指令的CPU设计实验
R-CPU 设计实验
实验内容
选以下4种系统结构之一,设计一个MIPS单周期R-CPU
(1)不带状态寄存器,8条指令
(2)带状态寄存器,8条指令
(3)不带状态寄存器,9条指令(多了sll)
(4)带状态寄存器,9条指令(多了sll)
本文选取第4种结构进行设计
具体步骤
- 修改寄存器堆模块,以使$0 内容恒置全零,只读。
- 根据所选指令系统,修改ALU模块
- 编写测试的汇编程序,准备验收文档(汇编、机器代码、结果)
- 设计取指令模块 用IP核重新设计(建议)
- 设计R-CPU主模块,完成各部件连接和指令译码控制单元的实现。
- 编写仿真测试代码,仿真验收
实验原理
实验流程图
R型指令的控制信号
汇编指令与.coe文件
地址 | 机器代码 | 汇编指令 | 执行结果 |
---|---|---|---|
[0x00400000] | 0x00004827 | nor $9, $0, $0 | R9 (t1) = ffffffff |
[0x00400004] | 0x0009502b | sltu $10, $0, $9 | R10 (t2) = 00000001 |
[0x00400008] | 0x012a5822 | sub $11, $9, $10 | R11 (t3) = fffffffe |
[0x0040000c] | 0x012b6022 | sub $12, $9, $11 | R12 (t4) = 00000001 |
[0x00400010] | 0x014c6820 | add $13, $10, $12 | R13 (t5) = 00000002 |
[0x00400014] | 0x01a97004 | sllv $14, $9, $13 | R14 (t6) = fffffffc |
[0x00400018] | 0x01ad7804 | sllv $15, $13, $13 | R15 (t7) = 00000008 |
[0x0040001c] | 0x01eac020 | add $24, $15, $10 | R24 (t8) = 00000009 |
[0x00400020] | 0x030bc825 | or $25, $24, $11 | R25 (t9) = ffffffff |
[0x00400024] | 0x01798826 | xor $17, $11, $25 | R17 (s1) = 00000001 |
[0x00400028] | 0x01d89024 | and $18, $14, $24 | R18 (s2) = 00000008 |
[0x0040002c] | 0x02299820 | add $19, $17, $9 | R19 (s3) = 00000000 |
[0x00400030] | 0x0253a025 | or $20, $18, $19 | R20 (s4) = 00000008 |
[0x00400034] | 0x01b1a804 | sllv $21, $17, $13 | R21 (s5) = 00000004 |
[0x00400038] | 0x02b1b004 | sllv $22, $17, $21 | R22 (s6) = 00000010 |
[0x0040003c] | 0x016eb820 | add $23, $11, $14 | R23 (s7) = fffffffa |
[0x00400040] | 0x0009f880 | sll $31, $9, 2 | R31 (ra) = fffffffc |
.coe文件内容
memory_initialization_radix=16; memory_initialization_vector=00004827,0009502b,012a5822,012b6022,014c6820,01a97004,01ad7804,01eac020,030bc825,01798826,01d89024,02299820,0253a025,01b1a804,02b1b004,016eb820,0009f880,00000820,00010fff,20006789,ffff0000,0000ffff,88888888,99999999,aaaaaaaa,bbbbbbbb,12345678,23456789,3456789a,456789ab,56789abc,6789abcd,00000820,00632020,00010fff,20006789,ffff0000,0000ffff,88888888,99999999,aaaaaaaa,bbbbbbbb,12345678,23456789,3456789a,456789ab,56789abc,6789abcd,00000820,00632020,00010fff,20006789,ffff0000,0000ffff,88888888,99999999,aaaaaaaa,bbbbbbbb,12345678,23456789,3456789a,456789ab,56789abc,6789abcd;
.coe文件内容由汇编语言翻译而来,详情见 MIPS汇编器与模拟器实验
根据.coe文件创建IP核,IP核的创建详情见 ISE IP核创建教程
功能模块说明
module R_CPU( clk,rst, Inst_code,PC, opcode,rs,rt,rd,shamt,func, ALU_F,FR_ZF,FR_OF,ALU_OP, rs_shamt,ALU_A ); input clk;//时钟 input rst;//清零 output reg [31:0]PC;//PC地址 output [31:0]Inst_code;//取出的指令 output [5:0]opcode,func;//指令分段 output [4:0]rs,rt,rd,shamt;//指令分段 output [31:0] ALU_F;//ALU结果 output reg [2:0] ALU_OP;//ALU运算的OP output reg FR_ZF; //ZF储存结果 output reg FR_OF;//OF储存结果 output [31:0]ALU_A; //ALU运算时A的数据 output reg rs_shamt; //控制ALU的A输入数据的信号
module REGS(R_Data_A,R_Data_B,W_Data,R_Addr_A,R_Addr_B,W_Addr,Write_Reg,rst,clk); input clk;//写入时钟信号 input rst;//清零信号 input Write_Reg;//写控制信号 input [4:0]R_Addr_A;//A端口读寄存器地址 input [4:0]R_Addr_B;//B端口读寄存器地址 input [4:0]W_Addr;//写寄存器地址 input [31:0]W_Data;//写入数据 output [31:0]R_Data_A;//A端口读出数据 output [31:0]R_Data_B;//B端口读出数据
module ALU(ALU_OP,A,B,F,ZF,OF); input [2:0] ALU_OP;//控制ALU运算类型的OP input [31:0] A; //ALU运算数据A input [31:0] B; //ALU运算数据B output [31:0] F; //ALU运算结果F output ZF; //零标志位 output OF; //溢出标志位
逻辑引脚图
仿真时序波形图
Inst_code表示当前OP地址中的指令
PC表示当前OP地址
Opcode,rs,rt,rd,shamt,func皆为指令分段
ALU_F为ALU运算结果
FR_ZF,FR_OF储存ALU运算得出的ZF,OF
ALU_OP为当前ALU运算的操作码
Rs_shamt控制当前是否使用shamt进行移位
ALU_A为当前ALU的A口输入数据
Clk为时钟信号,rst为复位信号
R-I CPU 完整代码
module R_CPU( clk,rst, Inst_code,PC, opcode,rs,rt,rd,shamt,func, ALU_F,FR_ZF,FR_OF,ALU_OP, rs_shamt,ALU_A ); input clk;//时钟 input rst;//清零 output reg [31:0]PC;//地址 wire [31:0]PC_new; output [31:0]Inst_code;//取出的指令 output [5:0]opcode,func;//指令分段 output [4:0]rs,rt,rd,shamt;//指令分段 wire [15:0]imm,offset;//指令分段 wire [25:0]address;//指令分段 output [31:0] ALU_F;//ALU结果 output reg [2:0] ALU_OP;//ALU结果 output reg FR_ZF; output reg FR_OF; wire ZF,OF; output [31:0]ALU_A; reg Write_Reg; wire [31:0]R_Data_A; wire [31:0]R_Data_B; reg Set_ZF; reg Set_OF; wire [31:0]shamt_kz; output reg rs_shamt; assign shamt_kz={{16{1'b0}},shamt}; initial PC = 32'h00000000; assign PC_new = PC + 4; Inst_Rom ROM2 ( .clka(clk), // input clka .addra(PC[7:2]), // input [5 : 0] addra .douta(Inst_code) // output [31 : 0] douta ); always @(negedge clk or posedge rst) begin if (rst) PC = 32'h00000000; //PC复位; else PC = PC_new; //PC更新为PC+4; end; assign opcode = Inst_code[31:26]; assign rs = Inst_code[25:21]; assign rt = Inst_code[20:16]; assign rd= Inst_code[15:11]; assign shamt = Inst_code[10:6]; assign func = Inst_code[5:0]; always @(*) begin ALU_OP = 3'b000; Write_Reg = 1'b0; rs_shamt=1'b0; if (opcode==6'b000000) //R指令 begin Write_Reg = 1'b1; //结果送寄存器 case (func) 6'b100000:begin ALU_OP=3'b100;Set_ZF=1;Set_OF=1; end 6'b100010:begin ALU_OP=3'b101;Set_ZF=1;Set_OF=1; end 6'b100100:begin ALU_OP=3'b000;Set_ZF=1;Set_OF=0; end 6'b100101:begin ALU_OP=3'b001;Set_ZF=1;Set_OF=0; end 6'b100110:begin ALU_OP=3'b010;Set_ZF=1;Set_OF=0; end 6'b100111:begin ALU_OP=3'b011;Set_ZF=1;Set_OF=0; end 6'b101011:begin ALU_OP=3'b110;Set_ZF=1;Set_OF=0; end 6'b000100:begin ALU_OP=3'b111;Set_ZF=1;Set_OF=0; end 6'b000000:begin ALU_OP=3'b111;Set_ZF=1;Set_OF=0;rs_shamt=1'b1; end endcase end end; REGS REGS_1(R_Data_A,R_Data_B,ALU_F,rs,rt,rd,Write_Reg,rst,~clk); assign ALU_A = (rs_shamt)?shamt_kz:R_Data_A; ALU ALU_1(ALU_OP,ALU_A,R_Data_B,ALU_F,ZF,OF); always @(negedge clk or posedge rst) if (rst) begin FR_OF <= 1'b0; FR_ZF <= 1'b0; end else begin if (Set_ZF) FR_ZF <= ZF; if (Set_OF) FR_OF <= OF; end endmodule module REGS(R_Data_A,R_Data_B,W_Data,R_Addr_A,R_Addr_B,W_Addr,Write_Reg,rst,clk); input clk;//写入时钟信号 input rst;//清零信号 input Write_Reg;//写控制信号 input [4:0]R_Addr_A;//A端口读寄存器地址 input [4:0]R_Addr_B;//B端口读寄存器地址 input [4:0]W_Addr;//写寄存器地址 input [31:0]W_Data;//写入数据 output [31:0]R_Data_A;//A端口读出数据 output [31:0]R_Data_B;//B端口读出数据 integer i; reg [31:0] REG_Files[0:31]; initial for(i=0;i<32;i=i+1) REG_Files[i]<=0; always@(posedge clk or posedge rst) begin if(rst) for(i=0;i<32;i=i+1) REG_Files[i]<=0; else if(Write_Reg&&W_Addr!=32'd0) REG_Files[W_Addr]<=W_Data; end assign R_Data_A=REG_Files[R_Addr_A]; assign R_Data_B=REG_Files[R_Addr_B]; endmodule module ALU(ALU_OP,A,B,F,ZF,OF); input [2:0] ALU_OP; input [31:0] A; input [31:0] B; output [31:0] F; output ZF; output OF; reg [31:0] F; reg C,ZF; always@(*) begin C=0; case(ALU_OP) 3'b000:begin F=A&B; end 3'b001:begin F=A|B; end 3'b010:begin F=A^B; end 3'b011:begin F=~(A|B); end 3'b100:begin {C,F}=A+B; end 3'b101:begin {C,F}=A-B; end 3'b110:begin F=A<B; end 3'b111:begin F=B<<A; end endcase ZF = F==0; end assign OF = ((ALU_OP==3'b100)||(ALU_OP==3'b101))&&(A[31] ^ B[31] ^ F[31] ^ C); endmodule
测试用例代码
always #50 clk=~clk; initial begin // Initialize Inputs clk=0; rst=1; #5; rst = 0; end endmodule
探索与思考(非标准答案)
-
sll rd, rt, shamt 指令将 rt 寄存器的数据进行逻辑左移,左移的位数则是由字段shamt 指定。试着实现该指令,谈谈你的实现方法。
答:加入rs_shamt信号,控制位移量是rs地址数据还是shamt。
assign ALU_A = (rs_shamt)?shamt_kz:R_Data_A;
ALU ALU_1(ALU_OP,ALU_A,R_Data_B,ALU_F,ZF,OF);
在case(func)中加入:
6’b000000:begin ALU_OP=3’b111;Set_ZF=1;Set_OF=0;rs_shamt=1’b1; end -
本实验实现的 sltu 指令是对无符号数的比较置位指令,如果需要实现有符号数的比较置位指令——slt 指令,请问应该如何实现?
答:若想实现有符号数的比较置位指令,可以先根据有符号数的最高位进行分类:
若两正,则和无符号数比较置位无异,若一正一负,则可轻易得出结论。若两负,则将余下位数进行比较置位,再将结果取反即可。 -
srav 是对(有符号)数据的算术右移指令,考虑如何实现它?
答:读取数据符号位,设右移位数为n,从数据最右边开始,将其每一位覆盖为其左边n位的数的数值,当其左边n位数不存在时,改为复制符号位即可。 -
在所设计的CPU基础上,添加一个输入设备(逻辑开关)和一个输出设备(LED 灯),假如直接用指令来实现输入输出功能,输入指令 in 和输出指令 out 的格式也是 R 型指令,
请画出修改后的系统结构图,并写出这两条指令对应令对应的控制信号。
设IN和OUT的func分别为110000,110001
输入输出对应的设备号由rs的低2位控制
IO_R=1时,执行输入指令
IO_W=1时,执行输出指令
增加信号alu_IO_s,控制寄存器W_Data的写入数据。
alu_IO_s=1时,数据由输入设备输入,为0时,数据由ALU运算结果输入。
- 杭电计算机组成原理课程设计-实验十三-实现R-I-J型指令的CPU设计实验
- 杭电计算机组成原理课程设计-实验十二-实现R-I型指令的CPU设计实验
- [置顶] [计算机组成原理][R-I-J型指令CPU设计实验总结]
- [计算机组成原理][实验十.R-I-J型指令CPU设计实验总结]
- 计算机组成原理实验 单总线CPU设计(定长指令周期3级时序)(HUST)思路总结
- 计算机组成原理实验 单总线CPU设计(变长指令周期3级时序)(HUST)思路总结
- 计算机组成原理课程设计 Dais CMX16 模型机指令及微指令设计
- 计算机组成原理课程设计 Dais CMX16 模型机指令及微指令设计
- 计算机组成原理课程设计(vhdl语言实现)
- 计算机组成实验-第5章_R指令设计实现
- 计算机组成原理课程设计实验一:验证74LS181运算和逻辑功能
- 计算机组成原理课程设计-基本模型机的设计与实现
- 山东大学计算机组成原理实验课程设计-模型机
- 计算机组成原理运算器设计实验之CLA182四位先行进位电路设计
- 重学计算机组成原理(五)- "旋转跳跃"的指令实现
- 计算机组成原理运算器设计实验之8位可控加减法电路设计
- 中山大学计算机组成原理多周期CPU实验
- Atitit 计算机系统结构 计算机系统结构 Cpu 存储 cache 指令系统 目录 Line 56: 第2章指令系统设计 指令格式 寻址方式 1 Line 64: 第3章CPU及其实现
- 计算机组成原理课程设计基于cop2000
- 计算机组成原理——cpu的简单模型实验报告