资源描述
电子科技大学计算机科学和工程学院
标 准 实 验 报 告
(试验)课程名称: 计算机组成原理试验
电子科技大学教务处制表
电 子 科 技 大 学
实 验 报 告
学生姓名: 郫县尼克杨 学 号: 指导老师:陈虹
试验地点: 主楼A2-411 试验时间:12周-15周
一、 试验室名称:
主楼A2-411
二、 试验项目名称:
单周期CPU设计和实现。
三、 试验课时:
8课时
四、 试验原理:
(一) 概述
指令0
指令1
指令5
指令2
指令4
1个时钟周期
Clock
单周期(Single Cycle)CPU是指CPU从取出1条指令到实施完该指令只需1个时钟周期。
一条指令实施过程包含:取指令→分析指令→取操作数→实施指令→保留结果。对于单周期CPU来说,这些实施步骤均在一个时钟周期内完成。
(二) 单周期cpu总体电路
本试验所设计单周期CPU总体电路结构以下。
(三) MIPS指令格式化
MIPS指令系统结构有MIPS-32和MIPS-64两种。本试验MIPS指令选择MIPS-32。以下所说MIPS指令均指MIPS-32。
MIPS指令格式为32位。下图给出MIPS指令3种格式。
26
31
25
21
20
16
15
11
10
6
5
0
op
rs
rt
rd
sa
func
R型指令
26
31
25
21
20
16
15
0
op
rs
rt
immediate
I型指令
26
31
25
0
op
address
J型指令
本试验只选择了9条经典MIPS指令来描述CPU逻辑电路设计方法。下图列出了本试验所包含到9条MIPS指令。
五、 试验目标
1、掌握单周期CPU工作原理、实现方法及其组成部件原理和设计方法,如控制器、运算器等。
2、认识和掌握指令和CPU关系、指令实施过程。
3、熟练使用硬件描述语言Verilog、EDA工具软件进行软件设计和仿真,以培养学生分析和设计CPU能力。
六、 试验内容
(一)确定本试验指令系统,指令应包含R型指令、I型指令和J型指令,指令数为9条。
(二)CPU各功效模块设计和实现。
(三)对设计各个模块仿真测试。
(四)整个CPU封装和测试。
七、 试验器材(设备、元器件):
(一)安装了Xilinx ISE Design Suite 13.4PC机一台
(二)FPGA开发板:Anvyl Spartan6/XC6SLX45
(三)计算机和FPGA开发板经过JTAG(Joint Test Action Group)接口连接,其连接方法图所表示。
八、 试验步骤
一个CPU关键由ALU(运算器)、控制器、寄存器堆、取指部件及其它基础功效部件等组成。
在本试验中基础功效部件关键有:32位2选1多路选择器、5位2选1多路选择器、32位寄存器堆、ALU等。
(一)新建工程(New Project)
开启ISE Design Suite 13.4软件,然后选择菜单File→New Project,弹出New Project Wizard对话框,在对话框中输入工程名CPU,并指定工作路径D:\Single_Cycle_CPU。
(二)基础功效器件设计和实现
(1)多路选择器设计和实现
a.5位2选1多路选择器(MUX5_2_1)设计和实现
在ISE集成开发环境中,在工程管理区任意位置单击鼠标右键,在弹出菜单中选择New Source命令,创建一个Verilog Module模块,名称为:MUX5_2_1,然后输入其实现代码:
module MUX5_2_1(
input [4:0] A,
input [4:0] B,
input Sel,
output [4:0] O
);
assign O = Sel ? B : A;
endmodule
在ISE集成开发环境中,对模块MUX5_2_1进行综合(Synthesize),综合结果图所表示:
在ISE集成开发环境中,对模块MUX5_2_1进行仿真(Simulation)。输入以下测式代码:
module MUX5_2_1_T;
// Inputs
reg [4:0] A;
reg [4:0] B;
reg sel;
// Outputs
wire [4:0] C;
// Instantiate the Unit Under Test (UUT)
MUX5_2_1 uut (
.A(A),
.B(B),
.sel(sel),
.C(C)
);
initial begin
// Initialize Inputs
A = 0;
B = 0;
sel = 0;
// Wait 100 ns for global reset to finish
#100;
A = 5'b10100;
B = 0;
sel = 1;
// Wait 100 ns for global reset to finish
#100;
A = 1;
B = 5'b10000;
sel = 0;
// Wait 100 ns for global reset to finish
#100;
A = 5'b00000;
B = 5'b11000;
sel = 1;
// Add stimulus here
end
endmodule
然后进行仿真,仿真结果图所表示:
b.32位2选1多路选择器设计和实现
在ISE集成开发环境中,在工程管理区任意位置单击鼠标右键,在弹出菜单中选择New Source命令,创建一个Verilog Module模块,名称为:MUX32_2_1,然后输入其实现代码:
module MUX32_2_1(
input [31:0]A ,
input [31:0]B,
input sel,
output [31:0] O
);
assign O= sel?B:A;
endmodule
在ISE集成开发环境中,对模块MUX32_2_1进行综合(Synthesize),综合结果图所表示:
在ISE集成开发环境中,对模块MUX32_2_1进行仿真(Simulation)。首先输入以下测式代码:
module MUX32_2_1_T;
// Inputs
reg [31:0] A;
reg [31:0] B;
reg sel;
// Outputs
wire [31:0] O;
// Instantiate the Unit Under Test (UUT)
MUX32_2_1 uut (
.A(A),
.B(B),
.sel(sel),
.O(O)
);
initial begin
A=0;
B=0;
sel=0;
// Wait 100 ns for global reset to finish
#100;
A=32'h00000001;
B=32'h00000000;
sel=1;
#100;
A=32'h00000101;
B=32'h00000010;
sel =0;
// Add stimulus here
end
endmodule
然后进行仿真,仿真结果图所表示:
(2)符号扩展(Sign_Extender)设计和实现
在ISE集成开发环境中,在工程管理区任意位置单击鼠标右键,在弹出菜单中选择New Source命令,创建一个Verilog Module模块,名称为:Sign_Extender,然后输入其实现代码:
module Sign_Extender(
input [15:0] d,
output [31:0] o
);
assign o = (d[15:15] == 1'b0) ? {16'b0, d[15:0]} : {16'b1, d[15:0]};
endmodule
在ISE集成开发环境中,对模块Sign_Extender进行综合(Synthesize),综合结果图所表示。
在ISE集成开发环境中,对模块MUX32_2_1进行仿真(Simulation)。首先输入以下测式代码:
module Sign_Extender_t;
// Inputs
reg [15:0] d;
// Outputs
wire [31:0] o;
// Instantiate the Unit Under Test (UUT)
Sign_Extender uut (
.d(d),
.o(o)
);
initial begin
// Initialize Inputs
d = 0;
// Wait 100 ns for global reset to finish
#100;
// Add stimulus here
d = 16'h0011;
#100;
d = 16'h1011;
end
endmodule
然后进行仿真,仿真结果图所表示:
(3)32位寄存器堆(RegFile)设计和实现
在ISE集成开发环境中,在工程管理区任意位置单击鼠标右键,在弹出菜单中选择New Source命令,创建一个Verilog Module模块,名称为:RegFile,然后输入其实现代码:
module RegFile(
input [4:0] Rn1, Rn2, Wn,
input Write,
input [31:0] Wd,
output [31:0] A, B,
input Clock
);
reg [31:0] Register[1:31];
assign A = (Rn1 == 0) ? 0 : Register[Rn1];
assign B = (Rn2 == 0) ? 0 : Register[Rn2];
always @ (posedge Clock) begin
if (Write && Wn != 0)
Register[Wn] <= Wd;
end
endmodule
在ISE集成开发环境中,对模块RegFile进行综合(Synthesize),综合结果图所表示。
在ISE集成开发环境中,对模块RegFile进行仿真(Simulation)。输入以下测式代码:
module Regfile_t;
// Inputs
reg [4:0] Rn1;
reg [4:0] Rn2;
reg [4:0] Wn;
reg Write;
reg [31:0] Wd;
reg Clock;
// Outputs
wire [31:0] A;
wire [31:0] B;
// Instantiate the Unit Under Test (UUT)
RegFile uut (
.Rn1(Rn1),
.Rn2(Rn2),
.Wn(Wn),
.Write(Write),
.Wd(Wd),
.A(A),
.B(B),
.Clock(Clock)
);
initial begin
// Initialize Inputs
Rn1 = 0;
Rn2 = 0;
Wn = 0;
Write = 0;
Wd = 0;
Clock = 0;
// Wait 100 ns for global reset to finish
#100;
Rn1 = 5'b00001;
Rn2 = 5'b00001;
Wn = 5'b00001;
Write = 1;
Wd = 0;
Clock = 0;
#100;
Clock = 1;
#50;
Wd = 32'hBBBBBBBB;
#50;
Clock = 0;
#100;
Clock = 1;
#100
Clock = 0;
// Add stimulus here
end
endmodule
然后进行仿真,仿真结果图所表示:
(4)运算器(ALU)设计和实现
在ISE集成开发环境中,在工程管理区任意位置单击鼠标右键,在弹出菜单中选择New Source命令,创建一个Verilog Module模块,名称为:ALU,然后输入其实现代码:
module ALU(
input [31:0] A, B,
input [2:0] ALU_operation,
output [31:0] Result,
output Zero
);
assign Result = (ALU_operation == 3'b000) ? A + B :
(ALU_operation == 3'b100) ? A - B :
(ALU_operation == 3'b001) ? A & B :
(ALU_operation == 3'b101) ? A | B :
(ALU_operation == 3'b010) ? A ^ B :
(ALU_operation == 3'b110) ? {B[15:0], 16'h0} :
32'hxxxxxxxx;
assign Zero = ~|Result;
endmodule
在ISE集成开发环境中,对模块ALU进行综合(Synthesize),综合结果图所表示:
在ISE集成开发环境中,对模块ALU进行仿真(Simulation)。输入以下测式代码:
module ALU_tb;
// Inputs
reg [31:0] A;
reg [31:0] B;
reg [2:0] ALU_operation;
// Outputs
wire [31:0] Result;
wire Zero;
// Instantiate the Unit Under Test (UUT)
ALU uut (
.A(A),
.B(B),
.ALU_operation(ALU_operation),
.Result(Result),
.Zero(Zero)
);
initial begin
// Initialize Inputs
A = 0;
B = 0;
ALU_operation = 0;
// Wait 100 ns for global reset to finish
#100;
A = 1;
B = 1;
ALU_operation = 0;
// Add stimulus here
#100
A = 2;
B = 2;
ALU_operation = 4;
#100
A = 1;
B = 1;
ALU_operation = 1;
#100
A = 1;
B = 1;
ALU_operation = 5;
#100
A = 1;
B = 1;
ALU_operation = 2;
end
endmodule
然后进行仿真,仿真结果图所表示:
(5)控制器(Controller)设计和实现
为了简化设计,控制器由控制单元Control和控制单元ALUop组成,控制器结构以下所表示。
a. Control设计和实现
在ISE集成开发环境中,在工程管理区任意位置单击鼠标右键,在弹出菜单中选择New Source命令,创建一个Verilog Module模块,名称为:Control,然后输入其实现代码:
module Control(
input [5:0] op,
output RegDst,
output RegWrite,
output ALUSrc,
output MemWrite,
output MemRead,
output MemtoReg,
output Branch,
output [1:0] ALUctr
);
wire i_Rt=~|op;
wire i_Lw=op[5] & ~op[3];
wire i_Sw=op[5] & op[3];
wire i_Beq =op[2] & ~op[1];
wire i_Lui=op[3] & op[2];
assign RegDst = i_Rt;
assign RegWrite=i_Rt|i_Lw|i_Lui;
assign ALUSrc =i_Lw|i_Sw |i_Lui;
assign MemWrite =i_Sw;
assign MemRead=i_Lw;
assign MemtoReg= i_Lw;
assign Branch=i_Beq;
assign ALUctr[1]= i_Rt|i_Lui;
assign ALUctr[0]=i_Beq|i_Lui;
endmodule
在ISE集成开发环境中,对模块Control进行综合(Synthesize), 综合结果图:
在ISE集成开发环境中,对模块Control进行仿真(Simulation)。首先输入以下测式代码:
module Control_tb;
// Inputs
reg [5:0] op;
// Outputs
wire RegDst;
wire RegWrite;
wire ALUSrc;
wire MemWrite;
wire MemRead;
wire MemtoReg;
wire Branch;
wire [1:0] ALUctr;
// Instantiate the Unit Under Test (UUT)
Control uut (
.op(op),
.RegDst(RegDst),
.RegWrite(RegWrite),
.ALUSrc(ALUSrc),
.MemWrite(MemWrite),
.MemRead(MemRead),
.MemtoReg(MemtoReg),
.Branch(Branch),
.ALUctr(ALUctr)
);
initial begin
// Initialize Inputs
op = 0;
// Wait 100 ns for global reset to finish
#100;
op = 6'b000000;
#100;
op = 6'b100011;
#100;
op = 6'b101011;
#100;
op = 6'b000100;
#100;
op = 6'b001111;
end
endmodule
然后进行仿真,仿真结果图所表示:
b. ALUop设计和实现
在ISE集成开发环境中,在工程管理区任意位置单击鼠标右键,在弹出菜单中选择New Source命令,创建一个Verilog Module模块,名称为:ALUop,然后输入其实现代码:
module ALUop(
input [5:0] func,
input [1:0] ALUctr,
output [2:0] ALU_op
);
wire i_Rt = ALUctr[1] & ~ALUctr[0];
assign ALU_op[2]=(i_Rt&((~func[2]&func[1])|(func[2] &func[0]))) | ALUctr[0];
assign ALU_op[1]=(i_Rt &func[2] &func[1])| (ALUctr[1]& ALUctr[0]);
assign ALU_op[0]=(i_Rt &func[2] &~func[1]);
endmodule
在ISE集成开发环境中,对模块ALUop进行综合(Synthesize), 综合结果图:
在ISE集成开发环境中,对模块ALUop进行仿真(Simulation)。首先输入以下测式代码:
module ALU_tb;
// Inputs
reg [31:0] A;
reg [31:0] B;
reg [2:0] ALU_operation;
// Outputs
wire [31:0] Result;
wire Zero;
// Instantiate the Unit Under Test (UUT)
ALU uut (
.A(A),
.B(B),
.ALU_operation(ALU_operation),
.Result(Result),
.Zero(Zero)
);
initial begin
// Initialize Inputs
A = 0;
B = 0;
ALU_operation = 0;
// Wait 100 ns for global reset to finish
#100;
A = 1;
B = 1;
ALU_operation = 0;
// Add stimulus here
#100
A = 2;
B = 2;
ALU_operation = 4;
#100
A = 1;
B = 1;
ALU_operation = 1;
#100
A = 1;
B = 1;
ALU_operation = 5;
#100
A = 1;
B = 1;
ALU_operation = 2;
end
endmodule
然后进行仿真,仿真结果图所:
c. 将Control和ALUop封装成Controller
在ISE集成开发环境中,在工程管理区任意位置单击鼠标右键,在弹出菜单中选择New Source命令,创建一个Verilog Module模块,名称为:Controller,然后输入其实现代码:
module Controller(
input [5:0] op,
input [5:0] func,
output RegDst,
output RegWrite,
output ALUSrc,
output MemWrite,
output MemRead,
output MemtoReg,
output Branch,
output [2:0] ALU_op
);
wire [1:0] ALUctr;
Control U0 (op, RegDst, RegWrite, ALUSrc, MemWrite, MemRead, MemtoReg, Branch, ALUctr);
ALUop U1 (func, ALUctr, ALU_op);
endmodule
在ISE集成开发环境中,对模块Controller进行综合(Synthesize),综合结果图:
在ISE集成开发环境中,对模块Controller进行仿真(Simulation)。首先输入以下测式代码:
module Controller_tb;
// Inputs
reg [5:0] op;
reg [5:0] func;
// Outputs
wire RegDst;
wire RegWrite;
wire ALUSrc;
wire MemWrite;
wire MemRead;
wire MemtoReg;
wire Branch;
wire [2:0] ALU_op;
// Instantiate the Unit Under Test (UUT)
Controller uut (
.op(op),
.func(func),
.RegDst(RegDst),
.RegWrite(RegWrite),
.ALUSrc(ALUSrc),
.MemWrite(MemWrite),
.MemRead(MemRead),
.MemtoReg(MemtoReg),
.Branch(Branch),
.ALU_op(ALU_op)
);
initial begin
// Initialize Inputs
op = 0;
func = 0;
// Wait 100 ns for global reset to finish
#100;
op =6'b100011;
#100
op=6'b101011;
#100
op=6'b000100;
#100
op=6'b001111;
end
endmodule
然后进行仿真,仿真结果图所表示:
(6)取指电路设计和实现
取指电路需完成ADD32、PC寄存器、多路选择器和左移两位模块,从而实现该取指电路。
a.ADD32设计和实现
在ISE集成开发环境中,在工程管理区任意位置单击鼠标右键,在弹出菜单中选择New Source命令,创建一个Verilog Module模块,名称为:ADD32,然后输入其实现代码:
module ADD32(
input [31:0] A, B,
output [31:0] C
);
assign C = A + B;
endmodule
在ISE集成开发环境中,对模块Controller进行综合(Synthesize),综合结果图:
b.左移两位模块(Left_2_Shifter)设计和实现
在ISE集成开发环境中,在工程管理区任意位置单击鼠标右键,在弹出菜单中选择New Source命令,创建一个Verilog Module模块,名称为:Left_2_Shifter,然后输入其实现代码:
module Left_2_Shifter(
input [31:0] d,
output [31:0] o
);
assign o = {d[29:0], 2'b00};
endmodule
在ISE集成开发环境中,对模块Controller进行综合(Synthesize),综合结果图:
c.综合取指电路(Fetch)设计和实现
在ISE集成开发环境中,在工程管理区任意位置单击鼠标右键,在弹出菜单中选择New Source命令,创建一个Verilog Module模块,名称为:Fetch,然后输入其实现代码:
module Fetch(
input Reset,
input Clock,
input [31:0] B_addr,
input Z, B,
output [31:0] addr
);
reg [31:0] PC;
wire [31:0] U0_o;
wire [31:0] U1_C;
wire [31:0] U2_C;
wire [31:0] Next_PC;
wire sel = Z & B;
Left_2_Shifter U0 (B_addr, U0_o);
ADD32 U1 (PC, 4, U1_C);
ADD32 U2 (U1_C, U0_o, U2_C);
MUX32_2_1 M1 (U1_C, U2_C, sel, Next_PC);
assign addr = PC;
always @ (posedge Clock or negedge Reset) begin
if (Reset == 0)
PC = 0;
else
PC = Next_PC;
end
endmodule
在ISE集成开发环境中,对模块Fetch进行综合(Synthesize),综合结果图:
在ISE集成开发环境中,对模块Fetch进行仿真(Simulation)。首先输入以下测式代码:
module FETCH_T;
// Inputs
reg clock;
reg reset;
reg [31:0] b_addr;
reg B;
reg Z;
// Outputs
wire [31:0] inst;
wire [31:0] o_addr;
wire [31:0] o_sum;
wire [31:0] o_sum1;
// Instantiate the Unit Under Test (UUT)
FETCH uut (
.clock(clock),
.reset(reset),
.b_addr(b_addr),
.B(B),
.Z(Z),
.inst(inst),
.o_addr(o_addr),
.o_sum(o_sum),
.o_sum1(o_sum1)
);
initial begin
// Initialize Inputs
clock = 0;
reset = 0;
b_addr = 0;
B = 0;
Z = 0;
// Wait 100 ns for global reset to finish
#100;
clock=1;
#100;
clock=0;
#100;
clock=1;
#100;
clock=0;
#100;
clock=1;
#100;
clock=0;
#100;
clock=1;
#100;
Z=1;
B=1;
b_addr=32'h4;
clock=0;
#100;
clock=1;
#100;
clock=0;
B=0;
Z=0;
#100;
clock=1;
#100;
clock=0;
#100;
clock=1;
b_addr=32'b0;
#100;
clock=0;
#100;
reset=1;
clock=1;
#100;
clock=0;
#100;
clock=1;
#100;
clock=0;
// Add stimulus here
// Add stimulus here
end
endmodule
然后进行仿真,仿真结果图所表示:
(7)数据通路Data_Flow设计和实现
除去指令存放器Instruction ROM、数据存放器DATA MEM,将剩下电路封装成一个单周期CPU数据通路(Data_Flow)模块。
在ISE集成开发环境中,在工程管理区任意位置单击鼠标右键,在弹出菜单中选择New Source命令,创建一个Verilog Module模块,名称为:Data_Flow,然后输入其实现代码:
module Data_Flow(
input Reset,
input Clock,
input [31:0] Inst,
input [31:0] Data,
output MemWrite,
output MemRead,
output [31:0] Result,
output [31:0] B_data,
output [31:0] NextPC
);
wire [31:0] B_addr;
wire Z, B;
wire RegDst;
wire RegWrite;
wire ALUSrc;
wire MemtoReg;
wire [2:0] ALU_op;
wire [31:0] ALU_A, ALU_B;
wire [4:0] Wn;
wire [31:0] Wd;
Fetch U0 (Reset, Clock, B_addr, Z, B, NextPC);
Controller U1 (Inst[31:26], Inst[5:0], RegDst, RegWrite, ALUSrc,
MemWrite, MemRead, MemtoReg, B, ALU_op);
ALU U2 (ALU_A, ALU_B, ALU_op, Result, Z);
RegFile U3 (Inst[25:21], Inst[20:16], Wn, RegWrite, Wd, ALU_A, B_data, Clock);
MUX5_2_1 U4 (Inst[20:16], Inst[15:11], RegDst, Wn);
MUX32_2_1 U5 (B_data, B_addr, ALUSrc, ALU_B);
Sign_Extender U6 (Inst[15:0], B_addr);
MUX32_2_1 U7 (NextPC, Data, MemtoReg, Wd);
endmodule
在ISE集成开发环境中,对模块Controller进行综合(Synthesize),综合结果图:
在IS
展开阅读全文