单周期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,指令地址PCwire [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@(*)begincase(ALUBSrc)2'b00:MUX_out0=reg_data2;2'b01:MUX_out0=4;2'b10:MUX_out0=ext_out;//imm扩展器待实现endcaseend//MUX_reg or PCreg [31:0]MUX_out1;//接入ALUalways@(*)beginif(ALUASrc) MUX_out1=PC;else MUX_out1=reg_data1;end//MUX_MemToReg or ALUtoRegreg [31:0]MUX_out2;always@(*)beginif(MemToReg) MUX_out2=mem_out;else MUX_out2=alu_out;end//MUX_PC_jumpreg [31:0]adder_out;always@(*) beginif(Branch&&Zero) adder_out=PC+ext_out;else adder_out=PC+4;end// PCalways @(posedge clk or posedge reset) beginif (reset) PC=0;//异步复位else PC=adder_out;//每次读4bytesendALU Alu(.opt(ALUctr),//选择算法.ASrc(MUX_out1),//src1可能是立即数,也可能是寄存器.BSrc(MUX_out0),.res(alu_out),.Zero(Zero));// Control UnitControlUnit 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)); // MemoryP_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@(*)begincase(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型偏移量endcaseend endmodule
这个代码是一个简单的CPU设计,主要实现了CPU的基本功能模块,包括指令获取、指令解码、ALU运算、数据存储、内存访问等。整体结构为:指令从内存中读取,经过控制单元控制各种操作,ALU计算结果与数据内存操作相结合,最后将结果写回寄存器或输出。
1. 模块说明:
-
PC(程序计数器):
-
用于存储当前正在执行的指令的地址。
-
每执行完一条指令,
PC
会加 4(即指向下一条指令)。 -
支持异步复位。
-
-
IR(指令寄存器):
-
存储从内存中读取的指令。
-
-
寄存器堆(
RegisterFile
):-
该模块用于存储CPU的寄存器数据,支持两个寄存器读操作(rs1 和 rs2)和一个寄存器写操作。
-
-
ALU(算术逻辑单元):
-
实现基础的算术和逻辑操作。
-
根据控制信号
ALUctr
来选择操作。 -
其中,
Zero
信号表示计算结果是否为零。
-
-
Memory(内存):
-
P_Memory
用于从内存中读取指令,Memory
用于数据访问(读写)。
-
-
控制单元(
ControlUnit
):-
根据指令
IR
生成相应的控制信号,包括 ALU 控制信号、寄存器写使能信号、内存读写使能信号等。
-
-
MUX(多路选择器):
-
多个 MUX 用于选择输入信号的路径。例如:决定 ALU 输入的数据来源,选择寄存器文件的输出或内存的输出等。
-
-
扩展器(Imm_Ext):
-
用于生成立即数的扩展。支持多种操作模式,如 I 型、S 型、B 型等。
-
2. 各模块及实现:
-
指令提取 (IF) 阶段:
-
每个时钟周期,
PC
递增(PC = PC + 4
),并从P_Memory
中读取指令存入IR
。 -
通过
IR
获取操作码opcode
、功能码funct3
、funct7
等信息。
-
-
指令解码 (ID) 阶段:
-
从
IR
中解析出寄存器地址(rs1
,rs2
,rd
),并通过寄存器堆RegisterFile
读取寄存器数据(reg_data1
和reg_data2
)。 -
控制信号由
ControlUnit
生成,包括 ALU 操作类型、是否使用立即数、是否进行内存操作、是否写回寄存器等。
-
-
执行 (EX) 阶段:
-
在
ALU
中执行运算,使用 ALU 控制信号(ALUctr
)和输入(MUX_out1
,MUX_out2
)计算。 -
ALU
根据输入数据选择是否计算寄存器值或立即数。 -
如果是条件跳转,ALU 会计算跳转地址,跳转时
PC
会设置为新的地址。
-
-
访存 (MEM) 阶段:
-
根据
MemWr
信号决定是否写入内存。 -
从内存
Memory
读取数据,写入mem_out
。
-
-
写回 (WB) 阶段:
-
根据
MemToReg
信号选择写回的数据来源,可以是ALU
的输出或内存的输出。
-
CPU设计
(一)电路图示例
(二)CPU 功能实现
-
指令提取(IF)阶段
-
每个时钟周期,PC 递增(PC = PC + 4),指向下一条指令地址。
-
从 P_Memory 中读取当前 PC 指向的指令,并将其存入 IR。
-
-
指令解码(ID)阶段
-
从 IR 中解析出操作码(opcode)、功能码(funct3、funct7)以及寄存器地址(rs1、rs2、rd)。
-
根据寄存器地址从 RegisterFile 中读取两个源操作数(reg_data1 和 reg_data2)。
-
控制单元根据指令生成控制信号,如确定 ALU 操作类型(ALUctr)、是否使用立即数(ALUBSrc)、是否进行内存操作(MemWr、MemToReg)以及是否写回寄存器(RegWr)等。
-
-
执行(EX)阶段
-
ALU 根据控制信号 ALUctr 对输入数据进行运算,输入数据来源由多路选择器(MUX)根据 ALUASrc 和 ALUBSrc 选择,可以是寄存器值或立即数。
-
对于条件跳转指令(beq),ALU 计算两个操作数是否相等(Zero 信号),如果相等且满足跳转条件(Branch 信号为真),则计算跳转地址(PC + ext_out),并更新 PC 的值。
-
-
访存(MEM)阶段
-
根据 MemWr 信号判断是否进行内存写操作,如果为真,则将数据(reg_data2)写入内存(Memory)中指定地址(alu_out [6:0])。
-
从内存中读取数据,存入 mem_out,准备后续写回阶段使用。
-
-
写回(WB)阶段
-
根据 MemToReg 信号选择写回的数据来源,如果为真,则将内存读取的数据(mem_out)写回寄存器堆;否则将 ALU 的运算结果(alu_out)写回寄存器堆。
-
(三)性能改进点
-
优化电路结构
-
减少不必要的逻辑层次和延迟路径,例如优化多路选择器(MUX)的设计,减少信号传输的延迟。
-
合理安排部件之间的连接,使数据传输更加高效,避免信号冲突和竞争。
-
-
采用流水线技术
-
将 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 beginCLK = 0;//初始化reset = 1;#10 reset = 0;//复位#100 $stop;endalways #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 性能的分析,再到对实验中遇到问题的反思,这一系列的工作让我对计算机硬件设计有了更系统的认识。
总的来说,本次实验不仅提升了我的专业技能,还培养了我的创新思维。同时,我也意识到自己在硬件设计方面还有很多不足,如电路优化能力、对复杂硬件系统的理解能力等,未来还需要不断学习和实践来提高自己的能力水平。
相关文章:

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

从零开始采用命令行创建uniapp vue3 ts springboot项目
文章目录 1,通过命令行创建uniapp vue3 ts项目2, 创建springboot后台项目3, 联调测试 1,通过命令行创建uniapp vue3 ts项目 官方通过命令行创建项目的地址:https://zh.uniapp.dcloud.io/quickstart-cli.html 在执行下面操…...

跟着逻辑先生学习FPGA-实战篇第一课 6-1 LED灯闪烁实验
硬件平台:征战Pro开发板 软件平台:Vivado2018.3 仿真软件:Modelsim10.6d 文本编译器:Notepad 征战Pro开发板资料 链接:https://pan.baidu.com/s/1AIcnaGBpNLgFT8GG1yC-cA?pwdx3u8 提取码:x3u8 1 知识背景 LED,又名…...
springboot 跨域配置
方案一 Configuration public class GlobalCorsConfig {Beanpublic CorsFilter corsFilter() {//1. 添加 CORS配置信息CorsConfiguration config new CorsConfiguration();//放行哪些原始域config.addAllowedOrigin("*");//是否发送 Cookieconfig.setAllowCredenti…...
C语言宏和结构体的使用代码
先看代码: #include <stdio.h> #include <string.h>// 定义一个宏,用于定义结构体 #define DEFINE_STRUCT(name, type1, name1, type2, name2, size, cf) \typedef struct { \type1 name1; …...
微信小程序 覆盖组件cover-view
wxml 覆盖组件 <video src"../image/1.mp4" controls"{{false}}" event-model"bubble"> <cover-view class"controls"> <cover-view class"play" bind:tap"play"> <cover-image class"…...
【Redis知识】Redis进阶-redis还有哪些高级特性?
文章目录 概览1. 持久化2. 复制与高可用3. 事务和脚本4. 发布/订阅 Redis事务示例事务中的错误处理使用 WATCH 进行乐观锁总结 Redis管道一、管道的原理二、管道的特点三、管道的使用场景四、管道的实现示例五、管道的注意事项 发布订阅模式一、Redis发布订阅模式介绍二、Redis…...
【Pytorch实用教程】深入了解 torchvision.models.resnet18 新旧版本的区别
深入了解 torchvision.models.resnet18 新旧版本的区别 在深度学习模型开发中,PyTorch 和 torchvision 一直是我们不可或缺的工具。近期,torchvision 对其模型加载 API 进行了更新,将旧版的 pretrained 参数替换为新的 weights 参数。本文将介绍这一变化的背景、具体区别,…...

攻防世界 - Web - Level 3 | very_easy_sql
关注这个靶场的其它相关笔记:攻防世界(XCTF) —— 靶场笔记合集-CSDN博客 0x01:考点速览 本关考察的是 SSRF 漏洞,需要我们结合 Gopher 协议利用服务端进行越权 SQL 注入。考点不少,总结一下主要有以下几点…...
使用Java Selenium修改打开页面窗口大小
在自动化测试过程中,有时需要模拟不同屏幕尺寸的用户行为,以确保网页在不同设备上的显示效果和用户体验。Selenium是一个强大的自动化测试工具,支持多种编程语言和浏览器,可以帮助我们实现这一需求。本文将详细介绍如何使用Java S…...

基于BiLSTM和随机森林回归模型的序列数据预测
本文以新冠疫情相关数据集为案例,进行新冠数量预测。(源码请留言或评论) 首先介绍相关理论概念: 序列数据特点 序列数据是人工智能和机器学习领域的重要研究对象,在多个应用领域展现出独特的特征。这种数据类型的核心特点是 元素之间的顺序至关重要 ,反映了数据内在的时…...
【Vim Masterclass 笔记04】S03L12:Vim 文本删除同步练习课 + S03L13:练习课点评
文章目录 L12 Exercise 03 - Deleting Text1 训练目标2 训练指引2.1 打开文件 practicedeleting.txt2.2 练习删除单个字符2.3 练习 motion:删除(Practice deleting motions)2.4 文本行的删除练习(Practice deleting lines…...

[AI] 深度学习的“黑箱”探索:从解释性到透明性
目录 1. 深度学习的“黑箱”问题:何为不可解释? 1.1 为什么“黑箱”问题存在? 2. 可解释性研究的现状 2.1 模型解释的方法 2.1.1 后置可解释性方法(Post-hoc Explanations) 2.1.2 内在可解释性方法(I…...
网络安全技能试题总结参考
对网络安全技能测试相关的试题进行了总结,供大家参考。 一、单选题 1.(单选题)以下属于汇聚层功能的是 A.拥有大量的接口,用于与最终用户计算机相连 B.接入安全控制 C.高速的包交换 D.复杂的路由策略 答案:D 2.(单选题)VLAN划分的方法,选择一个错误选项 A.基于端口…...
【翻译】优化加速像素着色器执行的方法
中文翻译 在回复我的 Twitter 私信时,我遇到了一个关于如何提高像素/片段着色器执行速度的问题。这是一个相当广泛的问题,具体取决于每个 GPU/平台和游戏内容的特性,但我在本帖中扩展了我“头脑风暴”式的回答,以便其他人也觉得有用。这不是一份详尽的清单,更像是一个高层…...

赛博周刊·2024年度工具精选(图片资源类)
1、EmojiSpark emoji表情包查找工具。 2、fluentui-emoji 微软开源的Fluent Emoji表情包。 3、开源Emoji库 一个开源的emoji库,目前拥有4000个emoji表情。 4、中国表情包大合集博物馆 一个专门收集中国表情包的项目,已收录5712张表情包,并…...
【深度学习基础之多尺度特征提取】多尺度图像增强(Multi-Scale Image Augmentation)是如何在深度学习网络中提取多尺度特征的?附代码
【深度学习基础之多尺度特征提取】多尺度图像增强(Multi-Scale Image Augmentation)是如何在深度学习网络中提取多尺度特征的?附代码 【深度学习基础之多尺度特征提取】多尺度图像增强(Multi-Scale Image Augmentation࿰…...
Spring Boot项目启动时显示MySQL连接数已满的错误
当Spring Boot项目启动时显示MySQL连接数已满的错误,这通常意味着应用程序尝试创建的数据库连接数超过了MySQL服务器配置的最大连接数限制。以下是一些解决此问题的步骤: 1. 检查MySQL服务器的最大连接数设置 首先,你需要检查MySQL服务器的…...

小程序多入口对应指定客服的实现方案:小程序如何实现接入指定客服人员?
小程序多入口对应指定客服的实现方案:小程序如何实现接入指定客服人员? 背景 小程序是否能接入指定客服? 近年来,小程序已经成为众多企业与用户交互的高效工具。无论是电商、服务预约还是在线咨询,客服功能的引入显…...

网页单机版五子棋小游戏项目练习-初学前端可用于练习~
今天给大家分享一个 前端练习的项目,技术使用的是 html css 和javascrpit 。希望能对于 刚刚学习前端的小伙伴一些帮助。 先看一下 实现的效果图 1. HTML(HyperText Markup Language) HTML 是构建网页的基础语言,它的主要作用是定…...

手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误
HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误,它们的含义、原因和解决方法都有显著区别。以下是详细对比: 1. HTTP 406 (Not Acceptable) 含义: 客户端请求的内容类型与服务器支持的内容类型不匹…...

2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...

技术栈RabbitMq的介绍和使用
目录 1. 什么是消息队列?2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...

使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...

STM32HAL库USART源代码解析及应用
STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...
Web中间件--tomcat学习
Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机,它可以执行Java字节码。Java虚拟机是Java平台的一部分,Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...
MinIO Docker 部署:仅开放一个端口
MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...