【计算机组成与设计】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()}}
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于Matlab的yolo算法行人检测系统

欢迎大家点赞、收藏、关注、评论啦 ,由于篇幅有限,只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 # 基于Matlab编写的Yolo算法行人检测系统介绍 基于Matlab编写的Yolo算法行人检测系统是一种用于自动检测图像或视频…

了解web3,什么是web3

Web3是指下一代互联网,它基于区块链技术,将各种在线活动更加安全、透明和去中心化。Web3是一个广义的概念,它包括了很多方面,如数字货币、去中心化应用、智能合约等等。听不懂且大多数人听到这个东西,直觉感觉就像骗子…

HR如何应用人才测评系统来开展招聘?

企业招聘:名额少,应聘者多,这是必然现象!如果提高招聘效率,成为企业最为关心的问题。 问题可能有 1、简历多筛选难 每次收到一堆的简历,如何从中筛选出有效的人才,是一件头疼的事&#xff0c…

【Orangepi Zero2 全志H616】驱动舵机控制 / Linux定时器(signal、setitimer)

一、SG90舵机开发 舵机基本介绍 二、Linux定时器 signal 函数setitimer 函数原型signal、setitimer函数API调用 三、舵机 软件PWM实现 一、SG90舵机开发 舵机基本介绍 如下图所示,最便宜的舵机sg90,常用三根或者四根接线,黄色为PWM信号控…

requests库编写的爬虫程序没有那么难!

下文是用requests库编写的爬虫程序,用于爬取toutiao上的图片。程序使用了代理服务器,代理服务器的地址为duoip,端口号为8000。 import requests from bs4 import BeautifulSoup# 设置代理服务器 proxy_host duoip proxy_port 8000 proxy {…

modesim verilog仿真验证基本流程(新建工程方式)

文章目录 环境搭建一、在modelsim里创建一个新的工程二、新建verilog设计文件及仿真激励文件三、仿真结果本文演示如何使用modelsim新建工程进行功能仿真。 环境搭建 本文中采用的modelsim版本如下: modelsim altera 10.3d一、在modelsim里创建一个新的工程 打开modelsim软…

Python自定义函数练习(持续更新中~)

1.计算矩阵的面积和周长: class Rectangle:def __init__(self, width, height):self.width widthself.height heightdef area(self):return self.width * self.heightdef perimeter(self):return 2 * (self.width self.height)if __name__ "__main__"…

JAVA电商平台免费搭建 B2B2C商城系统 多用户商城系统 直播带货 新零售商城 o2o商城 电子商务 拼团商城 分销商城

1. 涉及平台 平台管理、商家端(PC端、手机端)、买家平台(H5/公众号、小程序、APP端(IOS/Android)、微服务平台(业务服务) 2. 核心架构 Spring Cloud、Spring Boot、Mybatis、Redis 3. 前端框架…

最速下降法

目录 前言 一、梯度下降相关数学概念 二、最速下降法实战 2.1、例图1 2.2、Matlab代码实现 2.3、例题2 三、小结 前言 最速下降法,在SLAM中,作为一种很重要求解位姿最优值的方法,缺点很明显:迭代次数太多&#xff0c…

YOLO v2(2016.12)

文章目录 AbstractIntroduction当前存在的困境基于此,我们给出了方法 BetterBatch NormalizationHigh Resolution ClassifierConvolutional With Anchor BoxesDimension ClustersDirect location predictionFine-Grained FeaturesMulti-Scale TrainingFurther Exper…

海洋专用cmocean颜色包_共22种--全平台可用

海洋专用cmocean颜色包_共22种–全平台可用 往期推荐: Python语言_matplotlib包_共80种–全平台可用 Python语言_single_color_共140种–全平台可用 R语言_RColorBrewer包–全平台可用 R语言gplots包的颜色索引表–全平台可用 R语言中的自带的调色板–五种–全平台…

(后续补充)vue+express、gitee pm2部署轻量服务器

首先 防火墙全部关闭算了 首先 防火墙全部关闭算了 首先 防火墙全部关闭算了 首先 防火墙全部关闭算了 首先 防火墙全部关闭算了 首先 防火墙全部关闭算了 关闭防火墙 systemctl stop firewalld 重新载入防火墙使设置生效 firewall-cmd --reload 后端的 pm2.config.cjs …

Centralized Feature Pyramid for Object Detection解读

Centralized Feature Pyramid for Object Detection 问题 主流的特征金字塔集中于层间特征交互,而忽略了层内特征规则。尽管一些方法试图在注意力机制或视觉变换器的帮助下学习紧凑的层内特征表示,但它们忽略了对密集预测任务非常重要的被忽略的角点区…

云智慧联合北航提出智能运维(AIOps)大语言模型及评测基准

随着各行业数字化转型需求的不断提高,人工智能、云计算、大数据等新技术的应用已不仅仅是一个趋势。各行业企业和组织纷纷投入大量资源,以满足日益挑剔的市场需求,追求可持续性和竞争力,这也让运维行业迎来了前所未有的挑战和机遇…

文举论金:黄金原油全面走势分析策略独家指导

市场没有绝对,涨跌没有定势,所以,对市场行情的涨跌平衡判断就是你的制胜法宝。欲望!有句意大利谚语:让金钱成为我们忠心耿耿的仆人,否则,它就会成为一个专横跋扈的主人。空头,多头都…

GitLab CI/CD使用经验,来自于莫纳什大学的考试任务解析

CI/CD简介 CI/CD的作用在于自动化和加速软件开发、测试和交付流程,通过持续集成确保代码协同工作和质量,通过持续交付降低风险,使每次代码变更都能够快速、高质量地交付到生产环境,从而提高软件开发效率、质量和协作。 作业要求…

openGauss学习笔记-115 openGauss 数据库管理-设置安全策略-设置密码安全策略

文章目录 openGauss学习笔记-115 openGauss 数据库管理-设置安全策略-设置密码安全策略115.1 操作步骤 openGauss学习笔记-115 openGauss 数据库管理-设置安全策略-设置密码安全策略 115.1 操作步骤 用户密码存储在系统表pg_authid中,为防止用户密码泄露&#xff…

ffmpeg mp3截取命令,视频与mp3合成带音频视频命令

从00:00:03.500开始截取往后长度到结尾的mp3音频(这个更有用,测试好用) ffmpeg -i d:/c.mp3 -ss 00:00:03.500 d:/output.mp3 将两个音频合并成一个音频(测试好用) ffmpeg -i "concat:d:/c.mp3|d:/output.mp3&…

前端框架Vue学习 ——(四)Axios

文章目录 Axios 介绍Axios 入门Vue项目中使用 Axios Axios 介绍 介绍: Axios 对原生的 Ajax 进行了封装,简化书写,快速开发。(异步请求) 官网: https://www.axios-http.cn/ 官网介绍:Axios 是一个基于 promise 网络请…

20.5 OpenSSL 套接字RSA加密传输

RSA算法同样可以用于加密传输,但此类加密算法虽然非常安全,但通常不会用于大量的数据传输,这是因为RSA算法加解密过程涉及大量的数学运算,尤其是模幂运算(即计算大数的幂模运算),这些运算对于计…