首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

单周期CPU电路设计

  • 25-03-07 11:02
  • 4691
  • 9322
blog.csdn.net

1.实验目的

本实验旨在让学生通过设计一个简单的单周期 CPU 电路,深入理解 RISC-V 指令集的子集功能实现,掌握数字电路设计与实现的基本流程,包括指令解析、部件组合、电路设计以及功能仿真等环节,同时培养verilog HDL编程能力和对课程知识的理解。

2.实验内容及操作环境

  • 指令实现

    1.该CPU需要完成的指令有以下9个(附加beq),每条指令长度都为32bits。

    add,sub,or,slt,addi,ori,slti,sw,lw,beq(附加)

    2.该CPU的部件资源包括:1)X0-X31共32通用寄存器;2)特殊寄存器PC(program counter)和指令暂存寄存器IR(instruction Register)。以上寄存器都是32bits字长。

    3.存储器包括256bytes的memory(地址为0~255,采用little endian方式存储数据或者指令)。其中地址0~127存放程序指令(最多32条指令),地址128~255存放数据。也可以使用两块128byte的独立存储器。

    4.最后的波形仿真应当采用功能仿真,且所有存储器件中的数据都应当被显示。

    指令功能:

    • 算术逻辑运算指令(add、sub、or、slt、addi、ori、slti):根据指令规定对寄存器进行相应运算,并将结果存回目的寄存器。

    • 存数指令(sw):将指定寄存器的值存入内存特定地址。

    • 取数指令(lw):从内存特定地址读取数据存入指定寄存器。

    • 条件跳转指令 (beq):改变程序的执行顺序,实现分支结构。

  • 操作环境 使用vivado2019.2设计实验电路;使用Verilog HDL语言进行代码编写及仿真验证;操作系统为Windows 11。

3.实验设计

主要代码cpu.v:

`timescale 1ns / 1ps
module CPU(
    input clk,
    input reset
);
    //信号线
    reg [31:0] PC;//指令暂存器IR,指令地址PC
    wire [31:0] IR;
    wire [4:0] rs1, rs2, rd;//命令解析片段
    
    wire ALUASrc,MemToReg,MemWr,RegWr,Zero;
    wire [1:0]ALUctr,ALUBSrc,ExtOp;
    
    //数据线
    wire alu_src1, alu_src2;
    
    wire [31:0] alu_out;//ALU输入输出寄存器
    wire [31:0] reg_data1, reg_data2;//寄存器堆读出
    wire [31:0] mem_out;//内存读出,数据线都用wire,和模块内output类型无关
    
    assign rs2 = IR[24:20];
    assign rs1 = IR[19:15];
    assign rd = IR[11:7];
    assign funct3 =IR[14:12];
    assign funct7=IR[31:25];
    assign opc=IR[6:0];
    //最后做接线
    reg [31:0]MUX_out0;
    reg [31:0]ext_out;
    always@(*)begin
        case(ALUBSrc)
            2'b00:MUX_out0=reg_data2;
            2'b01:MUX_out0=4;
            2'b10:MUX_out0=ext_out;//imm扩展器待实现
        endcase
    end
    
    //MUX_reg or PC
    reg [31:0]MUX_out1;//接入ALU
    always@(*)begin
        if(ALUASrc) MUX_out1=PC;
        else MUX_out1=reg_data1;
    end
    
    //MUX_MemToReg or ALUtoReg
    reg [31:0]MUX_out2;
    always@(*)begin
        if(MemToReg) MUX_out2=mem_out;
        else MUX_out2=alu_out;
    end
    
    //MUX_PC_jump
    reg [31:0]adder_out;
    always@(*) begin
        if(Branch&&Zero) adder_out=PC+ext_out;
        else adder_out=PC+4;
    end
    
    // PC
    always @(posedge clk or posedge reset) begin
        if (reset) PC=0;//异步复位
        else PC=adder_out;//每次读4bytes
    end
    
    ALU Alu(
        .opt(ALUctr),//选择算法
        .ASrc(MUX_out1),//src1可能是立即数,也可能是寄存器
        .BSrc(MUX_out0),
        .res(alu_out),
        .Zero(Zero)
    );
     // Control Unit
     ControlUnit CU(
         .instr(IR),
         .ExtOp(ExtOp),
         .ALUASrc(ALUASrc),
         .ALUBSrc(ALUBSrc),
         .ALUctr(ALUctr),
         .MemToReg(MemToReg),
         .RegWr(RegWr),
         .MemWr(MemWr),
         .Branch(Branch)
     );
​
    // Register File 寄存器堆,传入调用编号,获得数据
    RegisterFile RF(
        .read1(rs1),//读取的寄存器地址
        .read2(rs2),
        .write_data(MUX_out2),//待写入数据
        .write_addr(rd),//写地址
        .write_en(RegWr),//使能,写
        .clk(clk),
        .read_data1(reg_data1),//读取的数据
        .read_data2(reg_data2)
    );
​
    // Memory
    P_Memory PM(
        .clk(clk),
        .addr(PC[6:0]),//根据PC获取指令
        .rd(IR)//读到指令通过IR输出
    );
    //读写
    Memory DM(
        .clk(clk),
        .addr(alu_out[6:0]),//获取数据
        .we(MemWr),
        .wd(reg_data2),//写入数据
        .rd(mem_out)
    );
​
    //imm扩展器
    always@(*)begin
        case(ExtOp) 
            2'b00:ext_out={{20{IR[31]}},IR[31:20]};//I型
            2'b01:ext_out={{20{IR[31]}}, IR[31:25], IR[11:7]};//s型
            2'b10:ext_out={{20{IR[31]}}, IR[7], IR[30:25], IR[11:8], 1'b0}; // B型偏移量
        endcase
    end
endmodule

这个代码是一个简单的CPU设计,主要实现了CPU的基本功能模块,包括指令获取、指令解码、ALU运算、数据存储、内存访问等。整体结构为:指令从内存中读取,经过控制单元控制各种操作,ALU计算结果与数据内存操作相结合,最后将结果写回寄存器或输出。

1. 模块说明:

  1. PC(程序计数器):

    • 用于存储当前正在执行的指令的地址。

    • 每执行完一条指令,PC 会加 4(即指向下一条指令)。

    • 支持异步复位。

  2. IR(指令寄存器):

    • 存储从内存中读取的指令。

  3. 寄存器堆(RegisterFile):

    • 该模块用于存储CPU的寄存器数据,支持两个寄存器读操作(rs1 和 rs2)和一个寄存器写操作。

  4. ALU(算术逻辑单元):

    • 实现基础的算术和逻辑操作。

    • 根据控制信号 ALUctr 来选择操作。

    • 其中,Zero 信号表示计算结果是否为零。

  5. Memory(内存):

    • P_Memory 用于从内存中读取指令,Memory 用于数据访问(读写)。

  6. 控制单元(ControlUnit):

    • 根据指令 IR 生成相应的控制信号,包括 ALU 控制信号、寄存器写使能信号、内存读写使能信号等。

  7. MUX(多路选择器):

    • 多个 MUX 用于选择输入信号的路径。例如:决定 ALU 输入的数据来源,选择寄存器文件的输出或内存的输出等。

  8. 扩展器(Imm_Ext):

    • 用于生成立即数的扩展。支持多种操作模式,如 I 型、S 型、B 型等。


2. 各模块及实现:

  1. 指令提取 (IF) 阶段:

    • 每个时钟周期,PC 递增(PC = PC + 4),并从 P_Memory 中读取指令存入 IR。

    • 通过IR 获取操作码 opcode、功能码 funct3、funct7 等信息。

  2. 指令解码 (ID) 阶段:

    • 从 IR 中解析出寄存器地址(rs1, rs2, rd),并通过寄存器堆 RegisterFile 读取寄存器数据(reg_data1 和 reg_data2)。

    • 控制信号由 ControlUnit 生成,包括 ALU 操作类型、是否使用立即数、是否进行内存操作、是否写回寄存器等。

  3. 执行 (EX) 阶段:

    • 在 ALU 中执行运算,使用 ALU 控制信号(ALUctr)和输入(MUX_out1, MUX_out2)计算。

    • ALU 根据输入数据选择是否计算寄存器值或立即数。

    • 如果是条件跳转,ALU 会计算跳转地址,跳转时 PC 会设置为新的地址。

  4. 访存 (MEM) 阶段:

    • 根据 MemWr 信号决定是否写入内存。

    • 从内存 Memory 读取数据,写入 mem_out。

  5. 写回 (WB) 阶段:

    • 根据 MemToReg 信号选择写回的数据来源,可以是 ALU 的输出或内存的输出。

CPU设计

(一)电路图示例

(二)CPU 功能实现

  1. 指令提取(IF)阶段

    • 每个时钟周期,PC 递增(PC = PC + 4),指向下一条指令地址。

    • 从 P_Memory 中读取当前 PC 指向的指令,并将其存入 IR。

  2. 指令解码(ID)阶段

    • 从 IR 中解析出操作码(opcode)、功能码(funct3、funct7)以及寄存器地址(rs1、rs2、rd)。

    • 根据寄存器地址从 RegisterFile 中读取两个源操作数(reg_data1 和 reg_data2)。

    • 控制单元根据指令生成控制信号,如确定 ALU 操作类型(ALUctr)、是否使用立即数(ALUBSrc)、是否进行内存操作(MemWr、MemToReg)以及是否写回寄存器(RegWr)等。

  3. 执行(EX)阶段

    • ALU 根据控制信号 ALUctr 对输入数据进行运算,输入数据来源由多路选择器(MUX)根据 ALUASrc 和 ALUBSrc 选择,可以是寄存器值或立即数。

    • 对于条件跳转指令(beq),ALU 计算两个操作数是否相等(Zero 信号),如果相等且满足跳转条件(Branch 信号为真),则计算跳转地址(PC + ext_out),并更新 PC 的值。

  4. 访存(MEM)阶段

    • 根据 MemWr 信号判断是否进行内存写操作,如果为真,则将数据(reg_data2)写入内存(Memory)中指定地址(alu_out [6:0])。

    • 从内存中读取数据,存入 mem_out,准备后续写回阶段使用。

  5. 写回(WB)阶段

    • 根据 MemToReg 信号选择写回的数据来源,如果为真,则将内存读取的数据(mem_out)写回寄存器堆;否则将 ALU 的运算结果(alu_out)写回寄存器堆。

(三)性能改进点

  1. 优化电路结构

    • 减少不必要的逻辑层次和延迟路径,例如优化多路选择器(MUX)的设计,减少信号传输的延迟。

    • 合理安排部件之间的连接,使数据传输更加高效,避免信号冲突和竞争。

  2. 采用流水线技术

    • 将 CPU 的指令执行过程分为多个阶段,如取指(IF)、译码(ID)、执行(EX)、访存(MEM)、写回(WB),每个阶段由专门的硬件电路处理,不同指令的不同阶段可以并行执行,提高 CPU 的吞吐量。

    • 在流水线设计中,需要解决数据相关、控制相关等问题,如采用数据前推、分支预测等技术,减少流水线的停顿,提高执行效率。

4.仿真结果

仿真代码test.v: 可以在仿真过程中观察到 PC、IR 和寄存器 X1 到 X8 的值,并且能够正常控制时钟和复位信号。

`timescale 1ns / 1ps
module test;
    reg CLK;
    reg reset;
    
    CPU demo(
        .clk(CLK),
        .reset(reset)
    );
     initial begin
        CLK = 0;//初始化
        reset = 1;
        #10 reset = 0;//复位
        #100 $stop;
    end
    always #5 CLK = ~CLK;// 生成时钟信号
    initial begin
        $monitor("At time %t, PC=%h,IR=%h,X1=%d,X2=%d,X3=%d,X4=%d,X5=%d,X6=%d,X7=%d,X8=%d", $time, demo.PC,demo.IR,demo.RF.registers[1],demo.RF.registers[2],demo.RF.registers[3],demo.RF.registers[4],demo.RF.registers[5],demo.RF.registers[6],demo.RF.registers[7],demo.RF.registers[8]);
    end
endmodule

打印输出结果如下:

5.遇到问题及解决方法

  • 理解和准确实现CPU不同指令功能具有一定难度。例如,对于不同类型指令中立即数的处理方式(如 I 型指令中的符号扩展)以及各指令对寄存器和内存的操作细节需要深入理解。

    方法:仔细研读 RISC-V 指令集文档,结合实验提供的指令规范和示例,逐一对每条指令进行分析,明确其操作码、操作数的含义及功能实现方式。对于立即数处理,按照指令集规定编写代码实现符号扩展或零扩展等操作进行。

  • 如何合理连接寄存器、ALU、存储器等部件,以及设计控制器来生成正确的控制信号以协调各部件工作较难处理。

    方法:参考附录中提供的单周期 CPU 简介及相关电路原理图,理解各部件之间的数据流向和控制关系。根据指令功能需求,设计各部件之间的连接线路,并依据指令与控制信号的逻辑关系,不断优化和调试电路结构,确保各部件协同工作正确执行指令。

  • 在功能仿真过程中,可能会遇到仿真结果与预期不符的情况,如指令执行结果错误、数据存储或读取异常等,且难以快速定位问题所在。

    方法:仔细检查输出结果,分析程序执行流程,找出错误原因并进行修正。

6.实验感想

通过本次单周期 CPU 电路设计实验,我对硬件的底层实现有了更深入的理解。从最初对 RISC-V 指令集的迷茫,到逐步理解并实现各条指令功能,再到设计出完整的 CPU 电路,这个过程充满挑战但也收获颇丰。在实验过程中,我深刻体会到了理论与实践相结合的重要性,但真正动手设计电路时,才发现实际情况远比想象中复杂。这不仅需要扎实的理论基础,更需要具备解决实际问题的能力,如在遇到指令实现错误或电路设计问题时,通过不断调试和优化代码来解决问题,极大地锻炼了我的耐心和细心。此外,实验还让我认识到团队协作和资源利用的重要性。在遇到困难时,与同学讨论交流、参考相关资料以及借鉴附录中的示例,都为我提供了新的思路和方法。同时,实验报告的撰写过程也促使我对整个实验进行全面总结和深入思考,从对实验过程的描述到对 CPU 性能的分析,再到对实验中遇到问题的反思,这一系列的工作让我对计算机硬件设计有了更系统的认识。

总的来说,本次实验不仅提升了我的专业技能,还培养了我的创新思维。同时,我也意识到自己在硬件设计方面还有很多不足,如电路优化能力、对复杂硬件系统的理解能力等,未来还需要不断学习和实践来提高自己的能力水平。

注:本文转载自blog.csdn.net的是害羞的感觉的文章"https://blog.csdn.net/2401_84974736/article/details/144810270"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

123
硬件开发
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top