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级. 但是,我们还没有从宏 ...
随机推荐
- Vue 新建项目+基本语法
新建项目: 导入依赖: <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"> ...
- Spectre.Console-实现自己的CLI
引言 最近发现自己喜欢用的 Todo 软件总是差点意思,毕竟每个人的习惯和工作流不太一样,我就想着自己写一个小的Todo 项目,核心的功能是自动记录 Todo 执行过程中消耗的时间(尤其面向程序员), ...
- JavaSE线程基础
1.线程概念 2.线程创建方式 1.继承thread 2.实现runnable runnable使用最多 3.线程的生命周期及线程的状态 新建状态 就绪状态的线程(已获得所有资源,栈堆内存空间),即s ...
- hosts文件妙用,提升网站访问速度!
一.背景 在讲解hosts文件之前,我们先了解下IP地址与域名的关系. 1.IP地址与域名的关系 IP(Internet Protocol)是一种规定互联网中数据传输的协议,每台连接到互联网中的计算机 ...
- HttpURLConnection调用webservice,c#、java、python等HTTP调用webservice,简单的webservice调用
以前调用webservice一般使用axis.axis2先生成java类后,直接引用,多方便.但是有的webservice接口非常的函数,生成的java类非常多,有没有一种非常简化的方法. axis2 ...
- 全面解析PCIDSS中的设备访问控制和网络访问控制
目录 1. 引言 2. 技术原理及概念 3. 实现步骤与流程 4. 应用示例与代码实现讲解 1. 引言 PCI DSS是PCI设备安全标准(PCI DSS)的缩写,是由PCI设备制造商和PCI服务提供 ...
- Codeforces Round #771 (Div. 2) A-E
A 代码 #include <bits/stdc++.h> using namespace std; using ll = long long; int p[507]; bool solv ...
- kubernetes(k8s):解决不在同一网段加入集群失败问题
执行下面命令,将内外网进行映射. iptables -t nat -A OUTPUT -d 10.140.128.121 -j DNAT --to-destination 10.170.129.153 ...
- 分享一个Java功能小案例(代码已开源哦)
工程合集 工程列表 地址预览 B站 抖音
- 在VS Code 中调试远程服务器的PHP代码
背景 对于PHP的调试,一般来说我们用 echo 和 var_dump 就够用了. 有时会碰到要解决复杂的逻辑或需要确认代码的运行顺序,这里用var_dump效率就比较低了,这时建议用断点的方式进行代 ...