MIPS寄存器堆
实验目的
- 熟悉并掌握 MIPS 计算机中寄存器堆的原理和设计方法
- 理解源操作数/目的操作数的概念
实验环境
- Vivado 集成开发环境
MIPS寄存器

- 寄存器R0的值恒为0。
模块接口设计
1个写端口和2个读端口

| 名称 | 宽度 | 方向 | 描述 |
|---|---|---|---|
| clk | 1 | IN | 时钟信号 |
| raddr1 | 5 | IN | 寄存器堆读地址1 |
| rdata1 | 32 | OUT | 寄存器堆返回数据1 |
| raddr2 | 5 | IN | 寄存器堆读地址2 |
| rdata2 | 32 | OUT | 寄存器堆返回数据2 |
| we | 1 | IN | 寄存器堆写使能 |
| waddr | 5 | IN | 寄存器堆写地址 |
| wdata | 32 | IN | 寄存器堆写数据 |
寄存器堆(regfile)实现了32个32位通用寄存器。
- 可以同时进行两个寄存器的读操作和一个寄存器的写操作。
- 写:写使能信号(we)为1时写有效,为0时无效。(write enable)
- 读:读操作可以同时读两个寄存器。
- 同时对同一个寄存器进行读写时,读的数据为旧的数据。
- 读写均为同步。
- 0号寄存器恒为0。
设计代码
`define REG_DATA_WIDTH 31:0
`define REG_NUM 31:0
`define REG_ADDR_WIDTH 4:0
`define REG_ADDR_BIT 5 // 地址线宽
`define REG_DATA_BIT 32 // 数据线宽
module regfile(
input clk,
input [`REG_ADDR_WIDTH] raddr1,
input [`REG_ADDR_WIDTH] raddr2,
input we, // 写使能
input [`REG_ADDR_WIDTH] waddr, // 写地址
input [`REG_DATA_WIDTH] wdata, // 写数据
output reg [`REG_DATA_WIDTH] rdata1,
output reg [`REG_DATA_WIDTH] rdata2
);
// 数组表示寄存器堆
reg [`REG_DATA_WIDTH] mips_regfile [`REG_NUM];
// 读1
always @(posedge clk) begin
if (raddr1 == {`REG_ADDR_BIT{1'b0}}) begin
rdata1 <= {`REG_DATA_BIT{1'b0}};
end
else begin
rdata1 <= mips_regfile[raddr1];
end
end
// 读2
always @(posedge clk) begin
if (raddr2 == {`REG_ADDR_BIT{1'b0}}) begin
rdata2 <= {`REG_DATA_BIT{1'b0}};
end
else begin
rdata2 <= mips_regfile[raddr2];
end
end
// 写
always @(posedge clk) begin
if (we == 1'b1 ) begin
if (waddr == {`REG_ADDR_BIT{1'b0}}) begin
mips_regfile[0] <= {`REG_DATA_BIT{1'b0}};
end
else begin
mips_regfile[waddr] <= wdata;
end
end
else begin
mips_regfile[0] <= {`REG_DATA_BIT{1'b0}};
end
end
endmodule
测试
测试代码
`timescale 1ns / 1ps
`define REG_DATA_WIDTH 31:0
`define REG_NUM 31:0
`define REG_ADDR_WIDTH 4:0
`define REG_ADDR_BIT 5
`define REG_DATA_BIT 32
module sim();
reg clk;
reg [`REG_ADDR_WIDTH] raddr1;
reg [`REG_ADDR_WIDTH] raddr2;
reg we; // 写使能
reg [`REG_ADDR_WIDTH] waddr; // 写地址
reg [`REG_DATA_WIDTH] wdata; // 写数据
wire [`REG_DATA_WIDTH] rdata1;
wire [`REG_DATA_WIDTH] rdata2;
integer i;
regfile u0 (
.clk(clk),
.raddr1(raddr1),
.raddr2(raddr2),
.we(we),
.waddr(waddr),
.wdata(wdata),
.rdata1(rdata1),
.rdata2(rdata2)
);
initial begin
clk = 1;
forever begin
#10 clk = ~clk;
end
end
initial begin
raddr1 = `REG_ADDR_BIT'd0;
raddr2 = `REG_ADDR_BIT'd0;
we = 1'b0;
waddr = `REG_ADDR_BIT'd0;
wdata = `REG_DATA_BIT'd0;
// 写数据
#100
we = 1'b1;
wdata = `REG_DATA_BIT'hFF;
for (i = 0; i < `REG_DATA_BIT; i = i + 1) begin
waddr = i;
wdata = wdata + `REG_DATA_BIT'h100;
#20;
end
// 读数据
we = 1'b0;
for (i = 0; i < `REG_DATA_BIT; i = i + 1) begin
raddr1 = i;
raddr2 = `REG_DATA_BIT - raddr1 - 1;
#20;
end
// 读写相同
// 读到的数据是旧数据
we = 1'b1;
wdata = `REG_DATA_BIT'h100;
for (i = 0; i < `REG_DATA_BIT; i = i + 1) begin
raddr1 = i;
raddr2 = i;
waddr = i;
wdata = wdata - `REG_DATA_BIT'h1;
#20;
end
we = 1'b0;
#100 $finish;
end
endmodule
测试波形
写数据:
从 0号寄存器开始到 31号寄存器,分别写入 01ff到 20ff。

读数据:
读地址 1和读地址 2分别读寄存器值,0号寄存器读得值为 0。其余寄存器读值正确。

结果分析
先进行写数据测试,从 0号寄存器开始到 31号寄存器,分别写入 01ff到 20ff。然后进行读数据测试,发现 0号寄存器值为 0,其余寄存器的值符合预期。当同时写和读,即写地址和读地址相同,且写使能时,发现读到的数据为旧数据,而写入的数据不会冲突。
MIPS寄存器堆的更多相关文章
- 自己动手写CPU——寄存器堆、数据存储器(基于FPGA与Verilog)
上一篇写的是基本的设计方案,由于考研复习很忙,不知道下一次什么时候才能打开博客,今天就再写一篇.写一写CPU中涉及到RAM的部件,如寄存器堆.数据存储器等. 大家应该在大一刚接触到计算机的时候就知道R ...
- 【CPU微架构设计】分布式多端口(4写2读)寄存器堆设计
寄存器堆(Register File)是微处理的关键部件之一.寄存器堆往往具有多个读写端口,其中写端口往往与多个处理单元相对应.传统的方法是使用集中式寄存器堆,即一个集中式寄存器堆匹配N个处理单元.随 ...
- 手写一个简易的多周期 MIPS CPU
一点前言 多周期 CPU 相比单周期 CPU 以及流水线 CPU 实现来说其实写起来要麻烦那么一些,但是相对于流水线 CPU 和单周期 CPU 而言,多周期 CPU 除了能提升主频之外似乎并没有什么卵 ...
- MIPS指令 MIPS架构
华中科技大学 - 计算机组成原理 华中科技大学 - 计算机硬件系统设计 Microprocessor without Interlocked Pipleline Stages 无内部互锁流水级的微处理 ...
- MIPS 汇编指令学习
MIPS 寄存器 MIPS comes with 32 general purpose registers named $0. . . $31Registers also have symbolic ...
- uvm_reg_file——寄存器模型(十四)
有了uvm_reg_field, uvm_reg, uvm_block, 也许我们需要跟大的uvm_file,这就是传说中的寄存器堆. // // CLASS: uvm_reg_file // Reg ...
- iot漏洞mips汇编基础
1 基础概念 MIPS(Microprocessor without Interlocked Piped Stages architecture),是一种采取精简指令集(RISC)的处理架构,由MIP ...
- verilog实现16位五级流水线的CPU带Hazard冲突处理
verilog实现16位五级流水线的CPU带Hazard冲突处理 该文是基于博主之前一篇博客http://www.cnblogs.com/wsine/p/4292869.html所增加的Hazard处 ...
- OpenRisc-47-or1200的WB模块分析
引言 “善妖善老,善始善终”,说的是无论什么事情要从有头有尾,别三分钟热度. 对于or1200的流水线来说,MA阶段是最后一个阶段,也是整条流水线的收尾阶段,负责战场的清扫工作.比如,把运算指令的运算 ...
- OpenRisc-44-or1200的pipeline整体分析
引言 我们在前面分析了ORPSoC,or1200_top,和or1200_cpu的整体架构,在最近,我们也分析了or1200的pipeline(流水线)中的两级,EX级和IF级. 但是,我们还没有从宏 ...
随机推荐
- java中接口,抽象类,具体类之间的关系
抽象类实现接口,具体类继承于抽象类
- Python-PyQt5的安装与简单使用
一.安装 1.安装 PyQt5 和 PyQt5-tools pip install PyQt5 -i https://pypi.douban.com/simple pip install PyQt5- ...
- 10.1. Java性能调优
Java性能调优是一个复杂且重要的主题,它涉及到了JVM.垃圾收集器.内存管理.多线程.代码优化等多个方面.在本节中,我们将对Java性能调优的基本概念和方法进行简要介绍. 10.1.1. 理解性能指 ...
- CSS 图片加载提前占位 padding-top、padding-bottom
今天聊一个图片加载提前占位的一个问题 ,内容比较适合初学者. 起因 在响应式页面当中,图片加载之前是不知道图片高度的,加载成功图片完全撑开.如果不做提前占位会把下面的内容挤下去,页面出现抖动,就像下面 ...
- 使用Python实现学生信息管理系统
本文介绍了一个简单的学生信息管理系统,包括管理员登录.重置学生密码.添加.删除和修改学生信息.查询学生信息以及对学生成绩进行排序等功能.该系统使用Python编写,基于控制台交互 实现思路 该系统分为 ...
- Grafana 系列-GaC-2-Grafana Terraform Provider 基础
系列文章 Grafana 系列文章 Terraform 系列文章 概述 前文最后总结了我的工具选型: Grafana Terraform provider Jsonnet 我们今天先简单介绍 Graf ...
- 全球唯一云厂商!华为云高分入选2023Gartner Peer Insights™云数据库管理系统“客户之选”
本文分享自华为云社区<华为云高分入选2023Gartner Peer Insights云数据库管理系统"客户之选">,作者:GaussDB 数据库 . 近日,Gartn ...
- string类型可以作为lock的锁对象吗
lock 关键字介绍 lock 关键字是用于在多线程编程中实现同步和互斥访问的关键字.它的作用是确保共享资源在任意时刻只能被一个线程访问,从而避免出现竞态条件(race condition)和数据不一 ...
- K8S | 容器和Pod组件
对比软件安装和运行: 一.场景 作为研发人员,通常自己电脑的系统环境都是非常复杂,在个人的习惯上,是按照下图的模块管理电脑的系统环境: 对于「基础设施」.「主机操作系统」.「系统软件」来说,通常只做配 ...
- 添加.gitignore不生效问题
1. 解决.gitignore不生效问题 把某些目录或文件加入忽略规则,按照上述方法定义后发现并未生效,原因是.gitignore只能忽略那些原来没有被追踪的文件,如果某些文件已经被纳入了版本管理中, ...