目录
一、实验目的
1.掌握Xilinx ISE集成开发环境和ModelSim仿真工具的使用方法
2.掌握VERILOG语言
3.掌握FPGA编程方法及硬件调试手段
4.深刻理解处理器结构和计算机系统的整体工作原理
二、实验环境(实验设备、开发环境)
- Windows10
- ISE14.7
- NEXYS3开发板
三、设计思想
1.指令格式设计



2.处理器结构设计框图及功能描述

上图是一个简单的基本上能够在单周期CPU上完成所要求设计的指令功能的数据通路和必要的控制线路图。其中指令和数据各存储在不同存储器中,即有指令存储器和数据存储器。访问存储器时,先给出内存地址,然后指令存储器以组合逻辑的方式来实现,而数据存储器以时序逻辑的方式来实现,在写时需要将对应的使能信号置为有效状态。对于寄存器组,先给出寄存器地址,读操作时不需要时钟信号,输出端就直接输出相应数据;而在写操作时,在 写使能信号为1时,在时钟边沿触发将数据写入寄存器。CU是整个CPU的控制器,随着节拍的改变而调整各个使能信号、MUX的选择输入端。
3.各功能模块结构的功能描述
PC,用于存放下一条要执行的指令的地址。
IMEM,指令存储器,用于存放所有要执行的指令。
IR,用于存放正要执行的指令。
NPC,用于暂存pc+4的值。
ADD,用于执行加法运算。
PC_select,用于在pc+4和跳转指令中地址进行选择。
Registers,寄存器组文件,这里实现了32个32位的通用寄存器。
Data_holder,用来暂存数据,A、B、IMM都是这个模块的实例化。
Extender,进行位扩展,如果是无条件跳转J指令,则将后26位符号扩展为32位,否则将后16位符号扩展为32位。
MUX,数据选择器。
ALU,算数运算单元,执行和指令相关的一些计算。
ALU_output,暂存ALU的结果。
DMEM,数据存储器。
LMD,用于暂存DMEM的数据。
CU,CPU的控制器,随着时钟节拍的改变而相应的变化控制信号。
4.各模块输入输出接口信号定义
模块名称及功能:PC,用于存放下一条要执行的指令的地址。

模块名称及功能:IMEM,指令存储器,用于存放所有要执行的指令。

模块名称及功能:IR,用于存放正要执行的指令。

模块名称及功能:NPC,用于暂存pc+4的值。

模块名称及功能:ADD,用于执行加法运算。

模块名称及功能:PC_select,用于在pc+4和跳转指令中地址进行选择。

模块名称及功能:Registers,寄存器组文件,这里实现了32个32位的通用寄存器。

模块名称及功能:Data_holder,用来暂存数据,A、B、IMM都是这个模块的实例化。

模块名称及功能:Extender,进行位扩展,如果是无条件跳转J指令,则将后26位符号扩展为32位,否则将后16位符号扩展为32位。

模块名称及功能:MUX,数据选择器。

模块名称及功能:ALU,算数运算单元,执行和指令相关的一些计算。

模块名称及功能:ALU_output,暂存ALU的结果。

模块名称及功能:DMEM,数据存储器。

模块名称及功能:LMD,用于暂存DMEM的数据。

模块名称及功能:CU,CPU的控制器,随着时钟节拍的改变而相应的变化控制信号。

四、实验设计及测试
用Verilog语言实现处理器设计与实现
① 各模块的详细设计
(1)PC:
module PC(
input [31:0] new_address, // 下一个地址
input clk,
input reset,
input pc_enable, // 是否可以更改PC
output reg [31:0] output_address // 当前PC内容
);
always@(posedge clk) begin
if(reset == 1'b1)
output_address <= 0 - 4;
else
output_address <= (pc_enable == 1)? new_address : output_address;
end
endmodule
(2)ADD:
module ADD(
input [31:0] data1,
input [31:0] data2,
output [31:0] result
);
assign result = data1 + data2;
endmodule
(3)PC_select:
module PC_select(
input [31:0] JMP_address, // 执行跳转类指令时PC值
input [31:0] PC_address, // 向下执行时的PC值
input pc_select, // 是否跳转
output [31:0] next_address
);
assign next_address = (pc_select == 1)? JMP_address : PC_address;
endmodule
(4)NPC:
module NPC(
input [31:0] input_address, // 下一个PC值
input clk,
input reset,
input npc_enable, // 是否可以更改NPC
output reg [31:0] output_address // NPC当前的值
);
always@(negedge clk) begin
if(reset == 1'b1) begin
output_address <= 0;
end
else begin
output_address <= (npc_enable==1)? input_address : output_address;
end
end
endmodule
(5)IMEM:
`include "./cpu.vh"
module IMEM(
input [31:0] address, // 指令的地址
output [31:0] output_instruction // 指令
);
reg [31:0] data [255:0]; // 32*256大小的指令存储缓冲器
initial begin
$readmemh(`INST_FILE_PATH, data); // 读取文件内容并进行初始化
end
assign output_instruction = data[address / 4];
endmodule
(6)IR:
module IR(
input [31:0] input_instruction, // IR要修改为的值,即取出的指令
input ir_enable, // IR是否可以被修改
input clk,
input reset,
output reg [31:0] output_instruction // 指令
);
always@(negedge clk) begin
if (reset == 1) begin
output_instruction <= 32'h00000000;
end
else begin
output_instruction <= (ir_enable == 1)? input_instruction : output_instruction;
end
end
endmodule
(7)Registers:
`include "./cpu.vh"
module Registers(
input [4:0] RS_1, // 指令中的寄存器部分
input [4:0] RS_2, // 指令中的寄存器部分
input [4:0] writeback_address, // 要写的寄存器的地址
input [31:0] writeback_data, // 要写入的内容
input clk,
input write_enable, // 是否可以写
input reset,
output [31:0] output_data_1, // 读到的值
output [31:0] output_data_2 // 读到的值
);
reg [31:0] memory [31:0]; // 32个32位寄存器
assign output_data_1 = memory[RS_1];
assign output_data_2 = memory[RS_2];
// 使用本地文件初始化寄存器组
initial begin
$readmemb(`GPRS_FILE_PATH , memory);
end
always@(posedge clk) begin
if(reset == 1) begin
//output_data_1 = 32'h00000000;
//output_data_2 = 32'h00000000;
end
else begin
if(write_enable == 1) begin
memory[writeback_address

本文详细介绍了如何使用Xilinx ISE和ModelSim进行实验,通过VERILOG实现一个基本CPU的指令处理器,包括指令格式设计、处理器结构、模块功能描述、设计及测试,涵盖了寄存器组、数据存储、CPU控制器等关键组件。
最低0.47元/天 解锁文章
2万+

被折叠的 条评论
为什么被折叠?



