沧州网站设计哪家好,个人网站能干嘛,电子购物网站建设目的,网站建设创业项目简介1.实验目的
本实验旨在让学生通过设计一个简单的单周期 CPU 电路#xff0c;深入理解 RISC-V 指令集的子集功能实现#xff0c;掌握数字电路设计与实现的基本流程#xff0c;包括指令解析、部件组合、电路设计以及功能仿真等环节#xff0c;同时培养verilog HDL编程能力和…1.实验目的
本实验旨在让学生通过设计一个简单的单周期 CPU 电路深入理解 RISC-V 指令集的子集功能实现掌握数字电路设计与实现的基本流程包括指令解析、部件组合、电路设计以及功能仿真等环节同时培养verilog HDL编程能力和对课程知识的理解。
2.实验内容及操作环境 指令实现 1.该CPU需要完成的指令有以下9个附加beq每条指令长度都为32bits。 addsuborsltaddiorisltiswlwbeq(附加) 2.该CPU的部件资源包括1X0-X31共32通用寄存器2特殊寄存器PCprogram counter和指令暂存寄存器IRinstruction 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 funct7IR[31:25];assign opcIR[6:0];//最后做接线reg [31:0]MUX_out0;reg [31:0]ext_out;always(*)begincase(ALUBSrc)2b00:MUX_out0reg_data2;2b01:MUX_out04;2b10:MUX_out0ext_out;//imm扩展器待实现endcaseend//MUX_reg or PCreg [31:0]MUX_out1;//接入ALUalways(*)beginif(ALUASrc) MUX_out1PC;else MUX_out1reg_data1;end//MUX_MemToReg or ALUtoRegreg [31:0]MUX_out2;always(*)beginif(MemToReg) MUX_out2mem_out;else MUX_out2alu_out;end//MUX_PC_jumpreg [31:0]adder_out;always(*) beginif(BranchZero) adder_outPCext_out;else adder_outPC4;end// PCalways (posedge clk or posedge reset) beginif (reset) PC0;//异步复位else PCadder_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) 2b00:ext_out{{20{IR[31]}},IR[31:20]};//I型2b01:ext_out{{20{IR[31]}}, IR[31:25], IR[11:7]};//s型2b10:ext_out{{20{IR[31]}}, IR[7], IR[30:25], IR[11:8], 1b0}; // 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 选择可以是寄存器值或立即数。 对于条件跳转指令beqALU 计算两个操作数是否相等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 性能的分析再到对实验中遇到问题的反思这一系列的工作让我对计算机硬件设计有了更系统的认识。
总的来说本次实验不仅提升了我的专业技能还培养了我的创新思维。同时我也意识到自己在硬件设计方面还有很多不足如电路优化能力、对复杂硬件系统的理解能力等未来还需要不断学习和实践来提高自己的能力水平。