CPU 指令执行系统 FPGA 设计 Verilog Vivado VHDL

名称:CPU 指令执行系统 FPGA 设计 Verilog Vivado VHDL

软件:Vivado

语言:VHDL

功能介绍

本项目实现了一个面向 FPGA 的 CPU 指令执行系统,核心功能围绕取指、程序计数、指令译码、立即数扩展、寄存器读写、ALU 运算、访存控制以及结果输出展开。设计中以 CPU 模块作为核心顶层单元,对外提供时钟、复位、指令输入、数据读入、PC 输出、ALU 结果输出、寄存器读数据输出和存储器写使能等接口,便于结合程序 ROM、数据存储器和外设显示模块组成完整运行工程。 CPU 内部包含 PC 程序计数器、NPC 下一条指令地址生成、CTRL 控制器、SEXT 立即数扩展、RF 寄存器文件和 ALU 运算相关逻辑。控制器根据 opcode、func3、func7 等指令字段生成 PC 选择、寄存器写回选择、存储器写使能、分支控制、ALU 控制、操作数选择和立即数扩展类型等控制信号,使数据通路能够完成不同类型指令的执行流程。 工程还配套了程序存储和数据存储相关 IP,以及开关、LED、结果显示等 IO 连接模块,可用于观察 CPU 运行状态和计算结果。对于学习简化处理器结构、指令控制信号生成、数据通路连线以及 Vivado 工程集成,本设计具有较直接的参考价值。

运行环境

开发环境:Vivado。 设计语言:Verilog。 工程包含 Vivado 工程文件、Verilog 用户源码、仿真 testbench、时钟 IP、程序 ROM/数据存储相关 IP、存储初始化文件以及管脚约束文件。主要源码包括 CPU、CTRL、SEXT、PC、TOP、DRAM、result_display、io_bridge、io_switch、io_led 等模块。

设计思路

整体设计采用典型 CPU 数据通路与控制通路分离的思路。CPU 核心通过 PC 模块保存当前指令地址,NPC 模块根据顺序执行、分支跳转、立即数和基地址等信息生成下一条指令地址。指令输入后,CTRL 模块根据指令字段输出控制信号,驱动寄存器写回选择、ALU 操作类型、操作数来源、存储器写控制和分支控制等关键路径。 立即数处理由 SEXT 模块完成,按照控制器给出的 sext_op 选择不同格式的立即数扩展结果。寄存器文件 RF 根据指令中的读寄存器地址输出两个源操作数,并在写使能有效时将写回数据写入目标寄存器。写回数据通过多路选择逻辑在 ALU 结果、PC+4、数据存储器读数和立即数之间选择,覆盖了运算、跳转返回、访存加载和立即数写入等常见写回来源。 分支跳转由 ALU 分支判断结果与控制器分支信号共同决定,形成 jump 信号后交给 NPC 参与下一 PC 计算。操作数 B 通过 op_B_sel 在立即数和寄存器读数据之间切换,使同一 ALU 通路能够支持寄存器型和立即数型运算。顶层工程再结合程序 ROM、DRAM、IO 桥接和显示模块,将 CPU 核心运行结果输出到外设显示链路中。

模块结构

主要模块结构如下: CPU:核心处理器模块,连接 PC、NPC、CTRL、SEXT、RF、ALU 等数据通路和控制通路。 PC:程序计数器模块,在时钟和复位控制下更新当前 PC。 NPC:下一条 PC 生成模块,根据跳转、PC 选择信号、立即数和基地址生成 npc,同时输出 pc4。 CTRL:指令控制模块,根据 func3、func7、opcode 生成寄存器写回、存储器写、分支、ALU 控制、操作数选择和立即数扩展控制信号。 SEXT:立即数扩展模块,根据指令内容和扩展类型输出 32 位立即数。 RF:寄存器文件模块,提供双读单写寄存器访问能力。 DRAM / prgrom:数据存储和程序存储相关模块/IP。 io_bridge、io_switch、io_led、result_display:用于外设输入输出和结果显示。

开发板验证

工程包含管脚约束文件 pin.xdc,可用于 FPGA 开发板引脚分配与上板实现。设计同时包含 IO 开关、LED、结果显示和时钟相关模块,便于在开发板环境中连接外设信号并观察 CPU 运行结果。

演示视频

包含演示视频,可用于查看工程运行效果和显示现象。

仿真图/仿真说明/设计文档图片

包含 testbench 仿真文件以及设计文档图片内容,可辅助理解模块连接、运行流程和工程结构。文档图片共 7 张,适合配合源码阅读 CPU 数据通路、控制信号和外设显示部分。

CPU 指令执行系统 FPGA 设计 Verilog Vivado VHDL 设计文档图片 image7.png

CPU 指令执行系统 FPGA 设计 Verilog Vivado VHDL 设计文档图片 image6.png

CPU 指令执行系统 FPGA 设计 Verilog Vivado VHDL 设计文档图片 image5.png

CPU 指令执行系统 FPGA 设计 Verilog Vivado VHDL 设计文档图片 image4.png

CPU 指令执行系统 FPGA 设计 Verilog Vivado VHDL 设计文档图片 image1.png

CPU 指令执行系统 FPGA 设计 Verilog Vivado VHDL 设计文档图片 image2.png

CPU 指令执行系统 FPGA 设计 Verilog Vivado VHDL 设计文档图片 image3.png

部分代码

以下展示顶层模块 CPU 的部分代码,完整源码请下载压缩包查看。

module CPU(
    input clk,//时钟
    input rst_n,//复位,低电平有效

    input wire [31:0] inst,//指令输入
    input wire [31:0] RD,//

    output wire [31:0] pc,//程序计数器
    output wire [31:0] resC,//
    output wire [31:0] rD2,//
    output wire mem_write//
    //output wire [31:0] x19_o    // this is the result of the trace test

//    output        debug_wb_have_inst,  
//    output [31:0] debug_wb_pc,          
//    output        debug_wb_ena,         
//    output [4:0]  debug_wb_reg,         
//    output [31:0] debug_wb_value        
);


// reg [31:0] pc;
wire [31:0] npc;
// wire [31:0] inst;

// ctrl
wire [1:0] pc_sel;
wire [1:0] reg_write;
// wire mem_write;
wire ctrl_branch;
wire [3:0] alu_ctrl;
wire op_B_sel;
wire [2:0] sext_op;

// rf
wire reg_we;
wire [31:0] wD; 
wire [31:0] rD1;
// wire [31:0] rD2;

// alu
wire [31:0] opB;
wire alu_branch;
// wire [31:0] resC;

// npc
wire jump;
wire [31:0] pc4;

// sext
wire [31:0] ext;

// dm
// wire [31:0] RD;  

//程序计数器模块
PC u_pc(
    .clk(clk),//时钟
    .rst_n(rst_n),//复位
    .npc(npc),//计数输入
    .pc(pc)//计数输出
//    .next_iter(debug_wb_have_inst)
);

assign jump = alu_branch & ctrl_branch;//alu_branch 逻辑与 ctrl_branch
//程序计数器计数控制
NPC u_npc(
    .jump(jump),//跳转
    .pc_sel(pc_sel),//程序计数器选择信号
    .pc(pc),//程序计数器
    .imm(ext),//立即数信号
    .base_adr(rD1),//基地址
    .npc(npc),//计数器输出
    .pc4(pc4)//计数器加4
);

CTRL u_ctrl(
    .func3(inst[14:12]),//ALU功能控制
    .func7(inst[31:25]),//功能信号
    .opcode(inst[6:0]),//操作码
    .pc_sel(pc_sel),//程序计数器选择信号
    .reg_write(reg_write),//寄存器写数据选择
    .mem_write(mem_write),//寄存器写数据
    .branch(ctrl_branch),//控制信号
    .alu_ctrl(alu_ctrl),//运算方式
    .op_B_sel(op_B_sel),//操作数B选择
    .sext_op(sext_op),//选择控制信号
    .reg_we(reg_we)// 寄存器文件的写使能
);

//6选1模块
SEXT u_sext(
    .inst(inst),//指令输入
    .sext_op(sext_op),//选择控制信号
    .ext(ext)//输出
);

//
assign wD = (reg_write == 2'b00) ? resC : //reg_write为00时,输出resC
            (reg_write == 2'b01) ? pc4  : //reg_write为01时,输出pc4 
            (reg_write == 2'b10) ? RD   : //reg_write为10时,输出RD
            (reg_write == 2'b11) ? ext  : //reg_write为11时,输出ext
			32'h0000_0000;
			
//寄存器文件
RF u_rf(
    .clk(clk),//时钟
    .WE(reg_we),//写使能
    .rR1(inst[19:15]),//读地址1
    .rR2(inst[24:20]),//读地址2
    .wR(inst[11:7]),//写地址
    .WD(wD),//写数据
    .rD1(rD1),//读数据1
    .rD2(rD2)//读数据2
    //.x19_o(x19_o)  // the result of the trace test
);

//op_B_sel为0时,opB输出ext,否则输出rD2
assign opB = (op_B_sel == 1'b0) ? ext : rD2;

// ... 以下代码略,完整源码请下载压缩包查看

代码文件(付费下载)

📥 付费后此处显示完整工程压缩包下载链接。
1、代码文件需要付费后才可见。
2、支付问题请联系微信公众号客服。
3、优质Verilog/VHDL代码资源,所见即所得。
Verilog/VHDL资源下载 » CPU 指令执行系统 FPGA 设计 Verilog Vivado VHDL

注册为本站会员,充值100得150,详情咨询客服

目前为止共有 *** 位优秀的会员加入! 立刻加入会员