本篇文章使用Verilog语言编写实现带有优先级的83译码器,含有设计代码和测试代码。
一、
寄存器堆regfile模块实现了32个32位通用寄存器。可以同时进行两个寄存器的读操作和一个寄存器的写操作。写操作是同步写,写使能信号(we)为1时有效,为0时无效;读操作可以在任意时刻进行读操作。
(1)当复位信号有效(rst为1)时,读数据(rdata1和rdata2)为0
(2)否则当复位信号无效(rst为0)时,当读地址为0,读数据为0
(3)否则当读写地址相等,且读写使能都有效的时候,读数据为写数据
(4)否则当读使能有效时,读数据为寄存器堆中存储数据
(5)其余情况,读数据为0
接口描述表如下:
接口名 | 宽度 | 输入/输出 |
---|---|---|
rst | 1 | 输入 |
clk | 1 | 输入 |
waddr | 5 | 输入 |
wdata | 32 | 输入 |
we | 1 | 输入 |
raddr1 | 5 | 输入 |
re1 | 1 | 输入 |
rdata2 | 32 | 输出 |
raddr2 | 5 | 输入 |
re2 | 1 | 输入 |
rdata2 | 32 | 输出 |
二、宏定义文件
将宏定义文件(此处为define.v)右键设置为global include文件,即可在其他文件中进行引用。
`define RegAddrBus 4:0
`define RegDataBus 31:0
`define RegNum 31:0
`define RstEnable 1
`define RstDisable 0
`define ZeroWord 0
`define ReadEnable 1
`define WriteEnable 1
三、设计代码
`timescale 1ns / 1ps
`include "define.v"
module regfile(
input wire clk,
input wire rst,
input wire [`RegAddrBus] waddr,
input wire [`RegDataBus] wdata,
input wire we,
input wire [`RegAddrBus] raddr1,
input wire re1,
output reg [`RegDataBus] rdata1,
input wire [`RegAddrBus] raddr2,
input wire re2,
output reg [`RegDataBus] rdata2
);
reg [`RegDataBus] reg1[`RegNum];
always@(*)begin
//复位信号为0,写信号为1,当前地址不为0时,数据写入寄存器
if(rst==`RstDisable)begin
if((we==`WriteEnable)&&(waddr!=0))begin
reg1[waddr]<=wdata;
end
end
end
//读rdata1
always@(*)begin
if(rst==`RstEnable)begin
//复位信号有效时,读数据为0
rdata1<=`ZeroWord;
end
//复位信号无效时
//读信号为1,读地址为0时,读数据为0
else if((re1==`ReadEnable)&&(raddr1==0))begin
rdata1<=`ZeroWord;
end
//读信号为1,写信号为1,读地址=写地址
else if((re1==`ReadEnable)&&(we==`WriteEnable)&&(raddr1==waddr))begin
rdata1<=wdata;
end
else if(re1==`ReadEnable) begin
rdata1<=reg1[raddr1];
end
//其余情况下,读数据为0
else begin
rdata1<=`ZeroWord;
end
end
//读rdata2
always@(*)begin
if(rst==`RstEnable)begin
rdata2<=`ZeroWord;
end
else if((re2==`ReadEnable)&&(raddr2==0))begin
rdata2<=`ZeroWord;
end
else if((re2==`ReadEnable)&&(we==`WriteEnable)&&(raddr2==waddr))begin
rdata2<=wdata;
end
else if(re2==`ReadEnable) begin
rdata2<=reg1[raddr2];
end
else begin
rdata2<=`ZeroWord;
end
end
endmodule
四、测试代码
`timescale 1ns / 1ps
module regfile_tb();
reg clk;
reg rst;
reg [`RegAddrBus] waddr;
reg [`RegDataBus] wdata;
reg we;
reg [`RegAddrBus] raddr1;
reg re1;
wire [`RegDataBus] rdata1;
reg [`RegAddrBus] raddr2;
reg re2;
wire [`RegDataBus] rdata2;
regfile regfile0(rst,clk,waddr,wdata,we,raddr1,re1,rdata1,raddr2,re2,rdata2);
integer i;
initial begin
clk=1;
forever begin
#10 clk=~clk;
end
end
//若把写和读放在两个initial中,存在并列的问题
initial begin
rst=0;
#10
rst=1;
#30
rst=0;
#30
//写使能有效,写数据有效
we=1;
wdata=32'h1234;
for(i=0;i<=31;i=i+1)begin
waddr=i;
wdata=wdata+32'h1111;
#30;
end
//写无效,读有效
we=0;
re1=1;
re2=1;
for(i=0;i<=31;i=i+1)begin
raddr1=i;
raddr2=31-i;
#30;
end
//读写地址相等
we=1;
wdata=32'h5678;
for(i=0;i<=31;i=i+1)begin
waddr=i;
raddr1=i;
raddr2=i;
#30;
wdata=wdata+32'h0101;
end
//恢复0
re1=0;
re2=0;
we=0;
#100 $finish;
end
endmodule
五、仿真波形图
文章来源:https://www.toymoban.com/news/detail-475002.html
仅供学习交流,如发现错误,欢迎大家指正。文章来源地址https://www.toymoban.com/news/detail-475002.html
到了这里,关于Vivado MIPS寄存器堆(含测试代码)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!