单周期CPU电路设计

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、功能码 funct3funct7 等信息。

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

    • IR 中解析出寄存器地址(rs1, rs2, rd),并通过寄存器堆 RegisterFile 读取寄存器数据(reg_data1reg_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: 可以在仿真过程中观察到 PCIR 和寄存器 X1X8 的值,并且能够正常控制时钟和复位信号。

`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 性能的分析,再到对实验中遇到问题的反思,这一系列的工作让我对计算机硬件设计有了更系统的认识。

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/946671.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【文献精读笔记】Explainability for Large Language Models: A Survey (大语言模型的可解释性综述)(五)

****非斜体正文为原文献内容(也包含笔者的补充),灰色块中是对文章细节的进一步详细解释! 五、 解释评估(Explanation Evaluation) 在前面的章节中,我们介绍了不同的解释技术和它们的用途&#…

UE5材质节点Camera Vector/Reflection Vector

Camera Vector相机向量,输出像素到相机的方向,结果归一化 会随着相机移动而改变 Reflection Vector 反射向量,物体表面法线反射到相机的方向,x和y和camera vector相反 配合hdr使用

使用Qt中的模型视图框架

本篇文章让你能够在阅读完之后,掌握Qt的模型视图框架的大致使用方法。 问题引入 在我们开发较小的软件的时候,我们可能不会注意到模型视图框架的作用。 因为我们的同一份的数据可能只会在同一个窗口中显示,不会存在数据在一个窗口中更新&a…

跟着逻辑先生学习FPGA-实战篇第一课 6-1 LED灯闪烁实验

硬件平台:征战Pro开发板 软件平台:Vivado2018.3 仿真软件:Modelsim10.6d 文本编译器:Notepad 征战Pro开发板资料 链接:https://pan.baidu.com/s/1AIcnaGBpNLgFT8GG1yC-cA?pwdx3u8 提取码:x3u8 1 知识背景 LED,又名…

2024国城杯 Web

这四道题目Jasper大佬都做了镜像可以直接拉取进行复现 https://jaspersec.top/2024/12/16/0x12%20%E5%9B%BD%E5%9F%8E%E6%9D%AF2024%20writeup%20with%20docker/ n0ob_un4er 这道题没有复现成功, 不知道为啥上传了文件, 也在 /tmp目录下生成了sess_PHPSESSID的文件, 但是就是…

【ArcGISPro/GeoScenePro】检查多光谱影像的属性并优化其外观

数据 https://arcgis.com/sharing/rest/content/items/535efce0e3a04c8790ed7cc7ea96d02d/data 操作 其他数据 检查影像的属性 熟悉检查您正在使用的栅格属性非常重要。

基于Docker基础与操作实战

6.1 Docker容器简介 Docker是一个开源的应用容器引擎,它基于Go语言并遵从Apache2.0 协议开源。 Docker是一个用于开发,交付和运行应用程序的开放平台。Docker能将应用程序与基础架构分开,从而可以快速交付软件。借助Docker,您可…

使用exe4j将jar转成exe、java打包exe

1、maven打包 需要配置以下插件&#xff0c;注意skip为false 插件配置中设置 <skip>true</skip> 时&#xff0c;实际上是告诉 Maven 在构建过程中跳过 spring-boot-maven-plugin 插件的执行。也就是说&#xff0c;Maven 在打包时不会将项目打包成可执行的 JAR 文…

MySQL 的事务与多版本并发控制(MVCC)的那些事

什么是事务原子性:一致性隔离性 问题1: 为什么MySQL要使用mvcc实现隔离性而不使用 锁 解决并发问题?持久性 问题2: MySQL 不是磁盘数据库吗,持久化为什么是 redo log 保证的?问题 3: redo log 储存了什么东西,持久化(崩溃恢复是怎么做的?)问题 4 : MySQL 的 bing log (二进制…

【单片机通讯协议】—— 常用的UART/I2C/SPI等通讯协议的基本原理与时序分析

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、通信基本知识1.1 MCU的参见外设1.2 通信的分类按基本的类型从传输方向上来分 二、UART&#xff08;串口通讯&#xff09;2.1 简介2.2 时序图分析2.3 UART的…

Ceph 手动部署(CentOS9)

#Ceph手动部署、CentOS9、squid版本、数字版本19.2.0 #部署服务:块、对象、文件 一、部署前规划 1、兼容性确认 2、资源规划 节点类型节点名称操作系统CPU/内存硬盘网络组件安装集群节点CephAdm01CentOS94U/8GOS:40G,OSD:2*100GIP1:192.169.0.9(管理&集群),IP2:…

CentOS7 解决ping:www.baidu.com 未知的名称或服务

CentOS7 解决ping&#xff1a;www.baidu.com“未知的名称或服务 在VM查看网络配置 查看虚拟网络编辑器 编辑网络配置文件 vi /etc/sysconfig/network-scripts/ifcfg-ens33注意&#xff1a;不同机器的配置文件名可能不相同&#xff0c;通过 ip addr 命令查看 将 ONBOOT 从 no 改…

GPU 进阶笔记(二):华为昇腾 910B GPU

大家读完觉得有意义记得关注和点赞&#xff01;&#xff01;&#xff01; 1 术语 1.1 与 NVIDIA 术语对应关系1.2 缩写2 产品与机器 2.1 GPU 产品2.2 训练机器 底座 CPU功耗操作系统2.3 性能3 实探&#xff1a;鲲鹏底座 8*910B GPU 主机 3.1 CPU3.2 网卡和网络3.3 GPU 信息 3.3…

[ICCD 2022]Towards Sparsification of Graph Neural Networks

论文网址&#xff1a;[2209.04766] Towards Sparsification of Graph Neural Networks 论文代码&#xff1a;github.com 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&#xff0c;若有发现欢迎评论指正&#…

人工智能与传统编程的主要区别是什么?

传统编程&#xff1a;开发者预先编写软件行为规则&#xff0c;代码基于程序员定义逻辑处理输入并产生确定输出&#xff0c;具有确定性、手动编写规则和结构化逻辑特点&#xff0c;如垃圾邮件分类程序基于预设关键词等规则。AI 编程&#xff1a;从数据中学习而非手动编写规则&am…

Mac电脑python多版本环境安装与切换

我当前是python3.9.6环境&#xff0c;需要使用3.9.8环境&#xff0c;通过brew安装3.9.8版本&#xff0c;然后通过pyenv切换环境 步骤 1: 安装 pyenv brew install pyenv brew install pyenv-virtualenv 步骤 2: 安装 Python 3.9.8&#xff08;使用 pyenv 安装指定版本的 Pyth…

UE5通过蓝图节点控制材质参数

通过蓝图节点控制材质的参数 蓝图节点 在材质上设置标量值 和 在材质上设置向量参数值 Set Scalar Parameter Value on Materials Set Vector Parameter Value on Materials 这两个蓝图节点都可以在蓝图中&#xff0c;控制材质的参数值和向量值

人工智能(AI)简史:推动新时代的科技力量

一、人工智能简介 人工智能&#xff08;AI&#xff0c;Artificial Intelligence&#xff09;是计算机科学的一个分支&#xff0c;旨在研究和开发可以模拟、扩展或增强人类智能的系统。它涉及多种技术和方法&#xff0c;包括机器学习、深度学习、自然语言处理&#xff08;NLP&a…

Github优质项目推荐(第十期)

文章目录 Github优质项目推荐&#xff08;第十期&#xff09;一、【postiz-app】&#xff0c;14.6k stars - 您的终极 AI 社交媒体调度工具二、【lobe-chat】&#xff0c;50.1k stars - AI 聊天框架三、【cobalt】&#xff0c;22.1k stars - 媒体下载器四、【build-your-own-x】…

DeepSeek V3“报错家门”:我是ChatGPT

搜 &#xff1a;海讯无双Ai 要说这两天大模型圈的顶流话题&#xff0c;那绝对是非DeepSeek V3莫属了。 不过在网友们纷纷测试之际&#xff0c;有个bug也成了热议的焦点—— 只是少了一个问号&#xff0c;DeepSeek V3竟然称自己是ChatGPT。 甚至让它讲个笑话&#xff0c;生成…