当前位置: 首页 > news >正文

【计算机组成与设计】Chisel取指和指令译码设计

本次试验分为三个部分:

目录

设计译码电路

设计寄存器文件

实现一个32个字的指令存储器


设计译码电路

输入位32bit的一个机器字,按照课本MIPS 指令格式,完成add、sub、lw、sw指令译码,其他指令一律译码成nop指令。输入信号名为Instr_word,对上述四条指令义译码输出信号名为add_op、sub_op、lw_op和sw_op,其余指令一律译码为nop;

给出Chisel设计代码和仿真测试波形,观察输入Instr_word为add R1,R2,R3; sub R0,R5,R6,lw R5,100(R2), sw R5,104(R2)、JAL RA,100(R2)时,对应的输出波形

Decode.scala

import chisel3._class Decoder extends Module {val io = IO(new Bundle {val Instr_word = Input(UInt(32.W))val add_op = Output(Bool())val sub_op = Output(Bool())val lw_op = Output(Bool())val sw_op = Output(Bool())val nop_op = Output(Bool())})// 定义操作码val OPCODE_ADD = "b000000".Uval OPCODE_SUB = "b000000".Uval OPCODE_LW = "b100011".Uval OPCODE_SW = "b101011".U//定义功能码val FUNCT_ADD = "b100000".Uval FUNCT_SUB = "b100010".U// 提取MIPS指令的操作码val opcode = io.Instr_word(31, 26)//提取MIPS指令的功能码val funct = io.Instr_word(5, 0)// 译码io.add_op := opcode === OPCODE_ADD && funct === FUNCT_ADDio.sub_op := opcode === OPCODE_SUB && funct === FUNCT_SUBio.lw_op := opcode === OPCODE_LWio.sw_op := opcode === OPCODE_SWio.nop_op := !(io.add_op || io.sub_op || io.lw_op || io.sw_op)
}object Decoder extends App {(new chisel3.stage.ChiselStage).emitVerilog(new Decoder())
}

 DecoderTest.scala

import chiseltest._
import org.scalatest.flatspec.AnyFlatSpec
import chisel3._class DecoderTest extends AnyFlatSpec with ChiselScalatestTester {behavior of "Decoder"it should "correctly decode instructions" in {test(new Decoder).withAnnotations(Seq(WriteVcdAnnotation)) { c =>// Test instructionsval addInstruction = "b000000_00010_00011_00001_00000_100000".Uval subInstruction = "b000000_00101_00110_00000_00000_100010".Uval lwInstruction = "b100011_00010_00101_0000000001100100".Uval swInstruction = "b101011_00010_00101_0000000001101000".Uval jalInstruction = "b000011_00000_00000000000000000000".U// Set the input instruction and evaluate the decoderc.io.Instr_word.poke(addInstruction)c.clock.step()c.io.add_op.expect(true)c.io.sub_op.expect(false)c.io.lw_op.expect(false)c.io.sw_op.expect(false)c.io.nop_op.expect(false)c.io.Instr_word.poke(subInstruction)c.clock.step()c.io.add_op.expect(false)c.io.sub_op.expect(true)c.io.lw_op.expect(false)c.io.sw_op.expect(false)c.io.nop_op.expect(false)c.io.Instr_word.poke(lwInstruction)c.clock.step()c.io.add_op.expect(false)c.io.sub_op.expect(false)c.io.lw_op.expect(true)c.io.sw_op.expect(false)c.io.nop_op.expect(false)c.io.Instr_word.poke(swInstruction)c.clock.step()c.io.add_op.expect(false)c.io.sub_op.expect(false)c.io.lw_op.expect(false)c.io.sw_op.expect(true)c.io.nop_op.expect(false)c.io.Instr_word.poke(jalInstruction)c.clock.step()c.io.add_op.expect(false)c.io.sub_op.expect(false)c.io.lw_op.expect(false)c.io.sw_op.expect(false)c.io.nop_op.expect(true)}}
}

设计寄存器文件

共32个32bit寄存器,允许两读一写,且0号寄存器固定读出位0。四个输入信号为RS1、RS2、WB_data、Reg_WB,寄存器输出RS1_out和RS2_out;寄存器内部保存的初始数值等同于寄存器编号

给出Chisel设计代码和仿真测试波形,观察RS1=5,RS2=8,WB_data=0x1234,Reg_WB=1的输出波形和受影响寄存器的值。

Register.scala

import chisel3._
import chisel3.util._class RegisterFile extends Module {val io = IO(new Bundle {val RS1 = Input(UInt(5.W)) // RS1输入信号,用于选择要读取的寄存器val RS2 = Input(UInt(5.W)) // RS2输入信号,用于选择要读取的寄存器val WB_data = Input(UInt(32.W)) // 写入数据信号,用于写入寄存器val Reg_WB = Input(UInt(5.W)) // 选择写入数据的寄存器val RS1_out = Output(UInt(32.W)) // RS1输出数据val RS2_out = Output(UInt(32.W)) // RS2输出数据})val registers = RegInit(VecInit((0 until 32).map(_.U(32.W)))) // 32个32位寄存器,初始值等于寄存器编号registers(io.Reg_WB) := io.WB_data // 写入数据到寄存器io.RS1_out := Mux(io.RS1 === 0.U, 0.U, registers(io.RS1)) // RS1输出数据,0号寄存器固定读出位0io.RS2_out := Mux(io.RS2 === 0.U, 0.U, registers(io.RS2)) // RS2输出数据,0号寄存器固定读出位0
}object RegisterFile extends App {(new chisel3.stage.ChiselStage).emitVerilog(new RegisterFile())
}

RegisterTest.scala

import chisel3._
import chiseltest._
import org.scalatest.flatspec.AnyFlatSpec
import chisel3.util._class RegisterFileTest extends AnyFlatSpec with ChiselScalatestTester {behavior of "RegisterFile"it should "correctly update and read registers" in {test(new RegisterFile).withAnnotations(Seq(WriteVcdAnnotation)) { c =>// 设置输入信号c.io.RS1.poke(5.U)c.io.RS2.poke(8.U)c.io.WB_data.poke(0x1234.U)c.io.Reg_WB.poke(1.U)c.clock.step()c.io.RS1_out.expect(5.U)c.io.RS2_out.expect(8.U)}}
}

实现一个32个字的指令存储器

从0地址分别存储4条指令add R1,R2,R3; sub R0,R5,R6,lw R5,100(R2), sw R5,104(R2)。然后组合指令存储器、寄存器文件、译码电路,并结合PC更新电路(PC初值为0)、WB_data和Reg_WB信号产生电路,最终让电路能逐条指令取出、译码(不需要完成指令执行)。

给出Chisel设计代码和仿真测试波形,观察四条指令的执行过程波形,记录并解释其含义。

InstructionMemory.scala

import chisel3._class InstructionMemory extends Module {val io = IO(new Bundle {val address = Input(UInt(5.W)) // 32个字,需要5位地址val instruction = Output(UInt(32.W))})// 创建一个32个字的指令存储器val mem = Mem(32, UInt(32.W))// 初始化存储器,存储MIPS指令mem.write(0.U, "b000000_00010_00011_00001_00000_100000".U) // add R1, R2, R3mem.write(1.U, "b000000_00101_00110_00000_00000_100010".U) // sub R0, R5, R6mem.write(2.U, "b100011_00010_00101_0000000001100100".U) // lw R5, 100(R2)mem.write(3.U, "b101011_00010_00101_0000000001101000".U) // sw R5, 104(R2)// 从存储器中读取指令io.instruction := mem.read(io.address)
}

Circuit.scala

import chisel3._
import chisel3.util._class Circuit extends Module {val io = IO(new Bundle {// 寄存器的输入输出val WB_data = Input(UInt(32.W)) // 写入数据信号,用于写入寄存器val Reg_WB = Input(UInt(5.W)) // 选择写入数据的寄存器val RS1_out = Output(UInt(32.W))val RS2_out = Output(UInt(32.W))// 译码val add_op = Output(Bool())val sub_op = Output(Bool())val lw_op = Output(Bool())val sw_op = Output(Bool())val nop_op = Output(Bool())})val instructionMemory = Module(new InstructionMemory)val registerFile = Module(new RegisterFile)val decoder = Module(new Decoder)val pc = RegInit(0.U(5.W))// 根据pc的值取出指令寄存器相应指令instructionMemory.io.address := pcdecoder.io.Instr_word := instructionMemory.io.instructionregisterFile.io.RS1 := instructionMemory.io.instruction(25, 21)registerFile.io.RS2 := instructionMemory.io.instruction(20, 16)registerFile.io.WB_data := (0.U(32.W))registerFile.io.Reg_WB := (0.U(5.W))// 更新输出io.RS1_out := registerFile.io.RS1_outio.RS2_out := registerFile.io.RS2_outio.add_op := decoder.io.add_opio.sub_op := decoder.io.sub_opio.lw_op := decoder.io.lw_opio.sw_op := decoder.io.sw_opio.nop_op := decoder.io.nop_op// 更新PCpc := pc + 1.U
}object Circuit extends App {(new chisel3.stage.ChiselStage).emitVerilog(new Circuit())
}

Circuit.scala

import chiseltest._
import org.scalatest.flatspec.AnyFlatSpec
import chisel3._class CircuitTest extends AnyFlatSpec with ChiselScalatestTester {behavior of "Circuit"it should "correct circuit" in {test(new Circuit).withAnnotations(Seq(WriteVcdAnnotation)) { c =>c.clock.step()c.clock.step()c.clock.step()c.clock.step()}}
}

相关文章:

【计算机组成与设计】Chisel取指和指令译码设计

本次试验分为三个部分: 目录 设计译码电路 设计寄存器文件 实现一个32个字的指令存储器 设计译码电路 输入位32bit的一个机器字,按照课本MIPS 指令格式,完成add、sub、lw、sw指令译码,其他指令一律译码成nop指令。输入信号名…...

「Verilog学习笔记」位拆分与运算

专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点,刷题网站用的是牛客网 1、寄存器的位是可以分开单独运算的,并不是一个输入就一定是一个数据,在很多情况下,一个输入既包括数据又包括地址等其他有效信息 2、需…...

protobufjs实现protobuf序列化与反序列化

系列文章目录 websocket训练地址:https://www.qiulianmao.com,正在搭建中 基础-websocket逆向基础-http拦截基础-websocket拦截基础-base64编码与解码基础-python实现protobuf序列化与反序列化基础-前端js实现protobuf序列化与反序列化基础-protobufjs实现protobuf序列化与反…...

el-select多选以tag展示时,超过显示长度以...省略号显示,且在一行展示

效果&#xff1a; 代码&#xff1a; <span>系统词典维度&#xff1a;</span><el-selectv-model"dNum"placeholder"请选择"multiplecollapse-tags //设置collapse-tags属性将它们合并为一段文字size"small"style"width:160p…...

计算机网络第4章-通用转发和SDN

引子&#xff1a; 在前面&#xff0c;我们将基于目的地转发的特征总结为两个步骤&#xff1a; 查找目的IP地址&#xff08;匹配&#xff09;&#xff0c;然后将分组发送到有特定输出端口的交换结构&#xff08;“动作”&#xff09;。 但是这种转发特征会带来许多问题&#…...

DDD技术方案落地实践 | 京东云技术团队

1. 引言 从接触领域驱动设计的初学阶段&#xff0c;到实现一个旧系统改造到DDD模型&#xff0c;再到按DDD规范落地的3个的项目。对于领域驱动模型设计研发&#xff0c;从开始的各种疑惑到吸收各种先进的理念&#xff0c;目前在技术实施这一块已经基本比较成熟。在既往经验中总…...

MySQL 案例:update set 和 and 的坑

问题描述 最近碰到到一个奇怪的问题&#xff0c;update 语句执行没有报错&#xff0c;但是没有更新数据&#xff0c;具体有问题的语句类似于如下形式&#xff1a; update test.stu set cname 0 and math 90 and his 80 where id 100; 复制 原因分析 直观上看&#xff…...

VSCode remote-ssh 连接远端服务器失败

系统 Mac os Intel处理器 描述 该问题在上午时还没有&#xff0c;下午突然毫无征兆的发生&#xff0c;当时没有更新vscode&#xff0c;没有更新插件。 分析 网上对于该问题的答案多是说磁盘空间不够vscode不能下载相应插件&#xff0c;我所遇到的并不是这种情况。报的错误多是…...

通达信动量线MTM指标原理详解及MTM底背离选股公式

MTM指标&#xff08;动量线指标&#xff09;用于衡量价格的动量和趋势&#xff0c;以判断未来价格的变化。计算方法很简单&#xff0c;用当前价格减去一段时间&#xff08;通常为12日&#xff09;前的价格&#xff0c;计算得到的差值的正负和大小&#xff0c;可以判断可能的趋势…...

汇编-DUP操作符

DUP操作符使用整数表达式作为计数器&#xff0c; 为多个数据项分配存储空间。 在为字符串或数组分配存储空间时&#xff0c;这个操作符尤其有用&#xff0c;并且可以使用初始化或非初始化数据&#xff1a; .data BYTE 20 DUP(0) ;20个字节&#xff0c;都等于0 BYTE 20 …...

2311C++抽象工厂

1,为啥需要工厂设计模式?工厂设计模式可解决什么问题? 先看一下示例,多态示例. #include <iostream> using namespace std; class Shape { public:Shape() { }virtual void drawShape(){cout << "base draw shape" << endl;} }; class Rectang…...

Lavarel定时任务的使用

系统为window 执行命令(执行一次命令只会根据当前时间运行一次定时任务) php artisan schedule:run创建一个任务类(在Jobs文件夹下面) <?phpnamespace App\Jobs;use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldBeUnique; use Illuminate\Contract…...

Java开发者的网络安全指南(二)

目录 一、加密和数据保护 二、身份验证和授权 三、Web应用程序安全 四、安全编码实践 五、网络防火墙和入侵检测系统 六、日志和监视 七、漏洞管理 八、安全教育和培训 九、结论 介绍&#xff1a; 简要说明网络安全的重要性和为什么Java开发者需要关注它。 一、加密…...

Python基础学习016__UnitTest

# UnitTest是python自带的一个单元测试框架,不需要额外安装 # 也是自动化脚本执行框架,使用UnitTest来管理,运行多个框架 # 为什么使用:能够组织多个用例去执行.提供了丰富的断言方法,能够生成测试报告 # 核心要素: # Testcase:测试用例:这个测试用例是UnitTest的组成部分,不是…...

一物一码需求,标签制作功能轻松解决

许多行业存在为人员、物品、设备等做一物一码标签的需求&#xff0c;可使用草料标签制作功能。直接选择标签样式&#xff0c;填入数据&#xff0c;即可批量生成标签&#xff0c;还可批量排版&#xff0c;更易落地。还可保存标签样式&#xff0c;后续多次复用样式&#xff0c;批…...

【Linux】七、基础IO

预备知识 文件 属性&#xff08;本质上也是数据&#xff09;内容&#xff1b; 文件的所有操作大致有两种&#xff0c;对内容的操作&#xff0c;和对属性的操作&#xff1b; 文件在磁盘中放置&#xff0c;磁盘是硬件&#xff0c;只有操作系统可以真正的访问磁盘&#xff1b;C\C…...

Elasticsearch语法之Term query不区分大小写

设置关键词是否区分大小写 说明&#xff1a;case_insensitive是term的可选参数&#xff0c;默认为false&#xff0c;表示关键词区分大小写&#xff0c;设置为true表示关键词不区分大小写。该参数在7.10.0开始有效 需求&#xff1a;分别使用关键词"iphone"和"I…...

远程管理SSH服务

一、搭建SSH服务 1、关闭防火墙与SELinux # 关闭firewalld防火墙 # 临时关闭 systemctl stop firewalld # 关闭开机自启动 systemctl disable firewalld ​ # 关闭selinux # 临时关闭 setenforce 0 # 修改配置文件 永久关闭 vim /etc/selinux/config SELINUXdisabled 2、配置…...

Linux 实现原理 — NUMA 多核架构中的多线程调度开销与性能优化

前言 NOTE&#xff1a;本文中所指 “线程” 均为可执行调度单元 Kernel Thread。 NUMA 体系结构 NUMA&#xff08;Non-Uniform Memory Access&#xff0c;非一致性存储器访问&#xff09;的设计理念是将 CPU 和 Main Memory 进行分区自治&#xff08;Local NUMA node&#x…...

Oracle锁处理

背景&#xff1a; 随着数据库版本不断迭代更新&#xff0c; v$session 视图的内容越来越丰富&#xff0c;可以直接使用blocking_session、blocking_instance、final_blocking_instance和final_blocking_session字段进行定位。对于锁层次的排查可以重复查询v$session来确定&am…...

反向工程与模型迁移:打造未来商品详情API的可持续创新体系

在电商行业蓬勃发展的当下&#xff0c;商品详情API作为连接电商平台与开发者、商家及用户的关键纽带&#xff0c;其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息&#xff08;如名称、价格、库存等&#xff09;的获取与展示&#xff0c;已难以满足市场对个性化、智能…...

VB.net复制Ntag213卡写入UID

本示例使用的发卡器&#xff1a;https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...

三维GIS开发cesium智慧地铁教程(5)Cesium相机控制

一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点&#xff1a; 路径验证&#xff1a;确保相对路径.…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习

禁止商业或二改转载&#xff0c;仅供自学使用&#xff0c;侵权必究&#xff0c;如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...

Web中间件--tomcat学习

Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机&#xff0c;它可以执行Java字节码。Java虚拟机是Java平台的一部分&#xff0c;Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...

【安全篇】金刚不坏之身:整合 Spring Security + JWT 实现无状态认证与授权

摘要 本文是《Spring Boot 实战派》系列的第四篇。我们将直面所有 Web 应用都无法回避的核心问题&#xff1a;安全。文章将详细阐述认证&#xff08;Authentication) 与授权&#xff08;Authorization的核心概念&#xff0c;对比传统 Session-Cookie 与现代 JWT&#xff08;JS…...

鸿蒙HarmonyOS 5军旗小游戏实现指南

1. 项目概述 本军旗小游戏基于鸿蒙HarmonyOS 5开发&#xff0c;采用DevEco Studio实现&#xff0c;包含完整的游戏逻辑和UI界面。 2. 项目结构 /src/main/java/com/example/militarychess/├── MainAbilitySlice.java // 主界面├── GameView.java // 游戏核…...

C++--string的模拟实现

一,引言 string的模拟实现是只对string对象中给的主要功能经行模拟实现&#xff0c;其目的是加强对string的底层了解&#xff0c;以便于在以后的学习或者工作中更加熟练的使用string。本文中的代码仅供参考并不唯一。 二,默认成员函数 string主要有三个成员变量&#xff0c;…...

跨平台商品数据接口的标准化与规范化发展路径:淘宝京东拼多多的最新实践

在电商行业蓬勃发展的当下&#xff0c;多平台运营已成为众多商家的必然选择。然而&#xff0c;不同电商平台在商品数据接口方面存在差异&#xff0c;导致商家在跨平台运营时面临诸多挑战&#xff0c;如数据对接困难、运营效率低下、用户体验不一致等。跨平台商品数据接口的标准…...

UE5 音效系统

一.音效管理 音乐一般都是WAV,创建一个背景音乐类SoudClass,一个音效类SoundClass。所有的音乐都分为这两个类。再创建一个总音乐类&#xff0c;将上述两个作为它的子类。 接着我们创建一个音乐混合类SoundMix&#xff0c;将上述三个类翻入其中&#xff0c;通过它管理每个音乐…...