系列文章目录
【计算机组织与体系结构】实验一:算术逻辑单元的实现
【计算机组织与体系结构】实验二:给定指令系统的处理器设计
【计算机组织与体系结构】实验三:流水线处理器
【计算机组织与体系结构】实验四:指令 CACHE 的设计与实现
文章目录
一、实验目的
- 掌握 Vivado 集成开发环境
- 掌握 Verilog 语言
- 掌握 FPGA 编程方法及硬件调试手段
- 深刻理解处理器结构和计算机系统的整体工作原理
二、实验环境
Vivado 集成开发环境和龙芯 Artix-7 实验平台
三、实验内容
根据课程第五章 MIPS 指令集的基本实现,设计并实现一个符合实验指令的非流水处理器,包括 Verilog语言的实现和 FPGA 芯片的编程实现,要求该处理器可以通过所提供的自动测试环境。
1、处理器功能
本实验的任务是设计一个简单的 RISC 处理器,该处理器是在给定的指令集(与 MIPS32 类似)下构建的,支持 11 条指令。假定存储器分为数据缓冲存储器
和指令缓冲存储器
,且都可以在一个时钟周期内完成一次同步存取操作,时钟信号和 CPU 相同。处理器的指令字长为 32 位,包含 32 个 32 位通用寄存器 R0~R31
, 1 个32 位的指令寄存器 IR
和 1 个 32 位的程序计数器 PC
, 1 个 256×32 位指令缓冲存储器
, 1 个 256×32 位的数据缓冲存储器
。
2、指令系统定义
处理器所支持的指令包括 LW, SW, ADD, SUB, AND, OR, XOR, SLT, MOVZ, BEQ, J
。
其中仅有 LW
和 SW
是字访存指令,所有的存储器访问都通过这两条指令完成; ADD、 SUB、 AND、 OR、 XOR、SLT、 MOVZ
是运算指令,他们都在处理器内部完成;BEQ
是分支跳转指令,根据寄存器的内容进行相对跳转;J
是无条件转移指令
1)指令说明
关于汇编指令的说明:
• rs 意味着 source register, rd 意味着 destination register;
• rt 有时(如运算指令)意味着第二个 source register,有时(如访存指令)意味着 target (source/destination)
register;
• 我们使用 [rs] 表示寄存器 rs 的内容;
另外,所有算数运算指令都执行有符号运算。
2)运算指令
(1)加法指令 ADD rd, rs, rt
该指令将两个源寄存器内容相加,结果送回目的寄存器的操作。
具体为: [rd] <- [rs] + [rt]
(2)减法指令 SUB rd, rs, rt
该指令将两个源寄存器内容相减,结果送回目的寄存器的操作。
具体为: [rd] <- [rs] - [rt]
(3)与运算指令 AND rd, rs, rt
该指令将两个源寄存器内容相与,结果送回目的寄存器的操作。
具体为: [rd] <- [rs] & [rt]
(4)或运算指令 OR rd, rs, rt
该指令将两个源寄存器内容相或,结果送回目的寄存器的操作。
具体为: [rd] <- [rs] | [rt]
(5)异或指令 XOR rd, rs, rt
该指令将两个源寄存器内容相异或,结果送回目的寄存器的操作。
具体为: [rd] <- [rs] ⊕ [rt]
(6)小于指令 SLT rd, rs, rt
该指令将两个源寄存器内容相比较,结果决定目的寄存器的值。
具体为: [rd] <- [rs] < [rt] ? 1 : 0
(7)条件移动指令 MOVZ rd, rs, rt
该指令根据其中一个源寄存器内容,决定另一个源寄存器的值是否写回目的寄存器。
具体为: if ([rt] == 0) then [rd] <- [rs]
Note
: 注意:当 [rt] != 0 时,不对寄存器 rd 进行任何写回操作。
3)访存指令
Warning
: 使用访存指令时,计算后的目标地址必须是访问数据单元大小的整数倍。对于 LW 和 SW 指令, ([base] + offset) % 4 == 0
(1)存数指令 SW rt, offset(base)
该指令将寄存器 rt 的内容存于主存单元中,对应的地址由 16 位偏移地址 offset 经符号拓展加上 base的内容生成。
具体操作为: Mem[[base] + offset] <- [rt]
(2)取数指令 LW rt, offset(base)
该指令将主存单元中的内容存于寄存器 rt,对应的地址由 16 位偏移地址 offset 经符号拓展加上 base
内容生成。
具体操作为: [rt] <- Mem[[base] + offset]
3)转移类指令
Warning
:
• 和 MIPS32 指令集不同,我们给出的跳转指令没有延迟槽。
• 跳转指令使用 NPC(也就是 PC+4)参与跳转地址运算。
(1)条件转移(相等跳转)指令 BEQ rs, rt, offset
该指令根据寄存器 rs 和 rt 的内容决定下一条指令的地址,若两个寄存器内容相等,则 16 位偏移 offset扩充为 32 位,左移 2 位后与 NPC 相加,作为下一条指令的地址,否则程序按原顺序执行。
具体操作为: PC <- ([rs] == [rt]) ? [sign_extend(offset) << 2 + NPC] : NPC
(2)无条件转移指令 J target
该指令改变下一条指令的地址,地址由指令中的 26 位形式地址 instr_index 左移 2 位作为低 28 位,和NPC 的高 4 位拼接而成。
具体操作为: PC <- (NPC[31:28]) ## (instr_index << 2)
四、实验要求
要求根据以上给定的指令系统设计处理器,包括指令格式设计、操作的定义、 Verilog 语言的实现及 FPGA 编程实现。处理器设计实验要求按指定阶段进行。
五、设计思想
(一)CPU接口信号定义
(二)处理器的设计方案
1、指令格式设计
处理器所支持的指令包括 LW, SW, ADD, SUB, AND, OR, XOR, SLT, MOVZ, BEQ, J。其中仅有 LW 和 SW 是字访存指令,所有的存储器访问都通过这两条指令完成; ADD、 SUB、 AND、 OR、 XOR、SLT、 MOVZ 是运算指令,他们都在处理器内部完成; BEQ 是分支跳转指令,根据寄存器的内容进行相对跳转;J 是无条件转移指令。
2、处理器结构设计框图及功能描述
该处理器可以实现11种指令,具体见上面表格
3、各功能模块结构设计框图及功能描述
(1)模块名称及功能:pc;指令寄存器,用来给出指令在指令存储器中的地址。
(2)模块名称及功能:npc;暂存PC输出的结果。
(3)模块名称及功能:符号位扩展signextension;将26位数据符号扩展为32位或者取出16位扩展为32位
(4)模块名称及功能:指令缓冲存储器imem;根据输入的地址来找到相应的指令
(5)模块名称及功能:算术逻辑单元alu;根据不同指令进行不同运算操作。
(6)模块名称及功能:数据存储器dmem;大小为256*32位,用来存储数据,在时钟上升沿,判断是否复位,若复位,则将数据缓冲存储器初始化,如果不复位,则根据写使能信号进行写操作。读操作不需要时钟信号。
(7)模块名称及功能:控制单元cu;根据输入的opcode、func、equal、radata、resetn, 来输出各种控制信号。
(8)模块名称及功能:32个32位寄存器堆regfile;可以进行两个寄存器的数据读出和一个寄存器的写回。
(9)模块名称及功能:二选一mux;对输入的两个32位数据进行选择,如果选择控制信号为1,则选择data1;如果为0,则选择data0。
(10)模块名称及功能:datatempstore;暂存数据imm、a、b、ir、aluoutput、lmd
(11)模块名称及功能:equal;比较数据是否相等,0表示不相等;1表示相等。
(12)模块名称及功能:writebackaddrmux;进行写回寄存器的选择
4、各模块输入输出接口信号定义
(1)模块名称及功能:pc;指令寄存器,用来给出指令在指令存储器中的地址。
(2)模块名称及功能:npc;暂存PC输出的结果。
(3)模块名称及功能:符号位扩展signextension;将26位数据符号扩展为32位或者取出16位扩展为32位
(4)模块名称及功能:指令缓冲存储器imem;根据输入的地址来找到相应的指令
(5)模块名称及功能:算术逻辑单元alu;根据不同指令进行不同运算操作。
(6)模块名称及功能:数据存储器dmem;大小为256*32位,用来存储数据,在时钟上升沿,判断是否复位,若复位,则将数据缓冲存储器初始化,如果不复位,则根据写使能信号进行写操作。读操作不需要时钟信号。
(7)模块名称及功能:控制单元cu;根据输入的opcode、func、equal、radata、resetn,
来输出各种控制信号。
(8)模块名称及功能:32个32位寄存器堆regfile;可以进行两个寄存器的数据读出和一个寄存器的写回。
(9)模块名称及功能:二选一mux;对输入的两个32位数据进行选择,如果选择控制信号为1,则选择data1;如果为0,则选择data0。
(10)模块名称及功能:datatempstore;暂存数据,包括imm、a、b、ir、aluoutput、lmd
(11)模块名称及功能:equal;比较数据是否相等,0表示不相等;1表示相等。
(12)模块名称及功能:writebackaddrmux;进行写回寄存器的选择
六、实验设计及测试
1、各模块的详细设计
(包括各模块功能详述,设计方法,Verilog语言实现等)
(1)模块名称及功能:pc;指令寄存器,用来给出指令在指令存储器中的地址。
module pc(
input clk,
input resetn,
input[31:0] nextpc,
output reg[31:0] currentpc
);
initial begin
currentpc <= 0;
end
always@(posedge clk)begin
if(!resetn) currentpc <= 0;
else currentpc <= nextpc;
end
endmodule
(2)模块名称及功能:npc;暂存PC输出的结果。
module npc(
input[31:0] pc,
output[31:0] pcadd4
);
assign pcadd4 = pc + 4;
endmodule
(3)模块名称及功能:符号位扩展signextension;将26位数据符号扩展为32位或者取出16位扩展为32位
module signextension(
input is_J,//控制信号,如果为0,表示为sw/lw/beq(16->32),如果为1,表示为J(26->32)
input [25:0]data,//待扩展的数据
output [31:0]extendresult//扩展结果
);
assign extendresult = (is_J)?{
{
6{
data[25]}},data}:{
{
16{
data[15]}},data[15:0]};//如果是J指令,则将26位扩展为32位
endmodule
(4)模块名称及功能:指令缓冲存储器imem;根据输入的地址来找到相应的指令
module imem(
input[31:0] pc,
output[31:0] instruction
);
reg [31:0] instmemory[255:0];
initial begin
$readmemh("D:/Users/Administrator/VivadoProjects/lab2/lab2.data/inst_data.txt",instmemory);//读取指令文件到inst_data
end
assign instruction = instmemory[pc>>2];
endmodule
(5)模块名称及功能:算术逻辑单元alu;根据不同指令进行不同运算操作。
module alu(
input[31:0] data0,
input[31:0] data1,
input[5:0] operation,
output[31:0] result
);
//存储不同指令的计算结果
wire [31:0] result1;//add lw sw
wire [31:0] result2;//sub
wire [31:0] result3;//and
wire [31:0] result4;//or
wire [31:0] result5;//xor
wire [31:0] result6;//slt
wire [31:0] result7;//movz
wire [31:0] result8;//beq
wire [31:0] result9;//j
wire [31:0] temp;
//计算不同指令的结果
assign result1 = data0 + data1;//add sw lw
assign result2 = data0 - data1;
assign result3 = data0 & data1;
assign result4 = data0 | data1;
assign result5 = data0 ^ data1;
assign result6 = (data0