Vivado MIPS寄存器堆(含测试代码)

本篇文章使用Verilog语言编写实现带有优先级的83译码器,含有设计代码和测试代码。

一、

寄存器堆regfile模块实现了32个32位通用寄存器。可以同时进行两个寄存器的读操作一个寄存器的写操作。写操作是同步写,写使能信号(we)为1时有效,为0时无效;读操作可以在任意时刻进行读操作。
(1)当复位信号有效(rst为1)时,读数据(rdata1和rdata2)为0
(2)否则当复位信号无效(rst为0)时,当读地址为0,读数据为0
(3)否则当读写地址相等,且读写使能都有效的时候,读数据为写数据
(4)否则当读使能有效时,读数据为寄存器堆中存储数据
(5)其余情况,读数据为0

接口描述表如下:

接口名宽度输入/输出
rst1输入
clk1输入
waddr5输入
wdata32输入
we1输入
raddr15输入
re11输入
rdata232输出
raddr25输入
re21输入
rdata232输出

二、宏定义文件

将宏定义文件(此处为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
五、仿真波形图

仿真波形图_refile

仅供学习交流,如发现错误,欢迎大家指正。

  • 1
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HePingxxb

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值