计算机组成原理实验——寄存器堆实现
程序员文章站
2022-07-06 08:30:09
...
这次要做的是用Verilog代码写一个寄存器堆,此寄存器堆共有32个寄存器,每个寄存器可存储32个二进制位。要求有一个写端口,两个读端口,本次实验设计为异步读同步写的寄存器堆,即读寄存器不需要时钟控制,但写寄存器需时钟控制。
先上寄存器堆模块的代码
`timescale 1ns / 1ps
//*************************************************************************
// > 文件名: regfile.v
// > 描述 :寄存器堆模块,同步写,异步读
// > 作者 : LOONGSON
// > 日期 : 2016-04-14
//*************************************************************************
module regfile(
input clk, //时钟控制信号
input wen, //写使能信号,1有效
input [4 :0] raddr1, //第一个读端口的地址
input [4 :0] raddr2, //第二个读端口的地址
input [4 :0] waddr, //一个写端口
input [31:0] wdata, //需要写入的数据
output [31:0] rdata1, //读出的数据1
output [31:0] rdata2, //读出的数据2
input [4 :0] test_addr, //输入的调试地址
output [31:0] test_data //输出调试数据
);
//总共32个寄存器
integer i = 0;
reg [31:0] REG_Files[31:0];
initial//初始化32个寄存器,全为0
for(i = 0;i < 32;i = i + 1)
REG_Files[i]<=0;
always @ (posedge clk)
begin
if(wen)
REG_Files[waddr] <= wdata;
end
assign rdata1 = REG_Files[raddr1] ;
assign rdata2 = REG_Files[raddr2];
assign test_data = REG_Files[test_addr];
endmodule
其实整个代码的逻辑还是比较简单的。定义一个reg型数组REG_Files来充当寄存器堆,此数组共有32个元素,每一个元素的大小为32个二进制位。在initial块中,用for循环对寄存器堆的内容初始化为0。当时钟信号clk上跳沿时触发always语句的执行,如果写使能信号wen为1,则把数据写入寄存器堆中。因为是异步读,所以只要是输入寄存器的地址,应能够立刻得到寄存器的内容。用assign语句对读数据的输出端口rdata1和rdata2进行赋值,其中,数组的下标相当于寄存器的地址,因此可以写成REG_Files[raddr1] 这种形式。最后一个assign语句是上板验证时用到的,用test_data来向显示屏传送数据。如果仅仅是为了得到仿真图形,可以不用管这行代码,但如果想上板验证,可以查看我的另一篇博客中关于test_data的介绍。点击此处进行跳转
仿真图形
写寄存器阶段
读寄存器阶段
上板验证图
regfile模块结构框图
寄存器堆设计实验的顶层模块大致框图