首页 > 其他分享 >Rong晔大佬教程学习(4):寄存器堆和立即数扩展

Rong晔大佬教程学习(4):寄存器堆和立即数扩展

时间:2023-12-14 10:35:17浏览次数:29  
标签:教程 20 imm Rong WIDTH inst 寄存器 reg

  在第一节的设计结构图中,我们可以看到,ctrl.v模块译码后,就可以得到我们实际运算所需要的数据,有两种:1.寄存器值,通过译码后得到的地址在寄存器堆中读出;2.立即数值,在译码后进行扩展得到的完整的立即数值。

  首先来看寄存器堆,一共有32个寄存器:

   接口名称表示每个寄存器的功能,本章暂不涉及。特别的,x0寄存器始终为0(只读存储器,这在之后的代码中可以看出)

1.reg_file.v(寄存器堆)

`include "rvseed_defines.v"
//主要功能是定义了一个32*32的寄存器堆,实现了寄存器堆的读和写逻辑
module reg_file (
    input                            clk,
    input                            rst_n,

    input                            reg_wen,    // register write enable
    input      [`REG_ADDR_WIDTH-1:0] reg_waddr,  // register write address
    input      [`CPU_WIDTH-1:0]      reg_wdata,  // register write data
    
    input      [`REG_ADDR_WIDTH-1:0] reg1_raddr, // register 1 read address
    input      [`REG_ADDR_WIDTH-1:0] reg2_raddr, // register 2 read address
    output reg [`CPU_WIDTH-1:0]      reg1_rdata, // register 1 read data
    output reg [`CPU_WIDTH-1:0]      reg2_rdata  // register 2 read data
);

reg [`CPU_WIDTH-1:0] reg_f [0:`REG_DATA_DEPTH-1]; //深度固定为32,因为一共有32个寄存器,每一个寄存器为32位宽

// register write,寄存器写逻辑
always @(posedge clk or negedge rst_n) begin
    if (rst_n && reg_wen && (reg_waddr != `REG_ADDR_WIDTH'b0)) // x0 read only,不能是复位状态,写使能有效,写地址不能为0(反向说明x0寄存器只读)
        reg_f[reg_waddr] <= reg_wdata;  //将数据写入寄存器
end

// register 1 read,寄存器读逻辑
always @(*) begin
    if(reg1_raddr == `REG_ADDR_WIDTH'b0)
        reg1_rdata = `CPU_WIDTH'b0;
    else
        reg1_rdata = reg_f[reg1_raddr]; //只要给一个读地址,那么就会把数据读出,没有“开关”控制
end

// register 2 read,寄存器读逻辑
always @(*) begin
    if(reg2_raddr == `REG_ADDR_WIDTH'b0)
        reg2_rdata = `CPU_WIDTH'b0;
    else
        reg2_rdata = reg_f[reg2_raddr];
end

endmodule

  相应的解释说明以在注释中给出,这部分主要就是定义了一个寄存器堆,然后通过输入地址信号和控制信号可以实现寄存器值的读出,特别注意的是,输入的控制信号和地址信号均由上一章ctrl.v模块给出,也就是译码的结果。

 

  立即数扩展模块主要实现立即数的补全(将立即数扩展为32位),这里我们直接上代码:

2.imm_gen.v(立即数扩展模块)

`include "rvseed_defines.v"
//立即数扩展模块
module imm_gen (
    input      [`CPU_WIDTH-1:0]        inst,       // instruction input,输入为我们的指令(有一个报错是inst的最低7位没有用到,那个是opcode,和这个程序没有关系)
    input      [`IMM_GEN_OP_WIDTH-1:0] imm_gen_op, // immediate extend opcode,输入立即数扩展操作码,决定立即数扩展为什么样子(由上一章的ctrl.v模块提供)

    output reg [`CPU_WIDTH-1:0]        imm         // immediate  
);

//扩展思路:将指令中的立即数摆在正确的位置上,拼接后进行高位符号位扩展,低位0扩展
always @(*) begin
    imm = `CPU_WIDTH'b0;
    case (imm_gen_op)
        `IMM_GEN_I: 
             imm = {{20{inst[31]}},inst[31:20]};
        `IMM_GEN_S: 
             imm = {{20{inst[31]}},inst[31:25],inst[11:7]};
        `IMM_GEN_B: 
             imm = {{20{inst[31]}},inst[7],inst[30:25],inst[11:8], 1'b0};
        `IMM_GEN_J: 
             imm = {{12{inst[31]}},inst[19:12],inst[20],inst[30:21], 1'b0};
        `IMM_GEN_U: 
             imm = {inst[31:12],12'b0};
    endcase
end

endmodule

  我们以I型指令为例:I型指令的立即数在指令的31-20位,同时也是立即数的最低12位,因此在扩展中截取inst[31:20]作为立即数的低12位,高20位则将inst[31]复制20次,这也就是高位符号位扩展的意思。

   至于低位0扩展,可以参考U型指令,U型指令的立即数在指令的高20位,同时也是立即数的高20位,所以低12位就全部补0即可。

 

P.S:本章的测试中up主定义了一个顶层模块rvseed.v,因为我没有做仿真所以我暂时不考虑了

标签:教程,20,imm,Rong,WIDTH,inst,寄存器,reg
From: https://www.cnblogs.com/liwilling/p/17900609.html

相关文章

  • 虚拟机安装Windows7 X64位教程以及解决VMTOOLS无法安装问题
    相关镜像文件的下载首先我们需要下载一个Windows7的镜像文件这里推荐迅雷下载,速度更快一点ed2k://|file|cn_windows_7_professional_x64_dvd_x15-65791.iso|3341268992|3474800521d169fbf3f5e527cd835156|h=TIYH37L3PBVMNCLT2EX5CSSEGXY6M47W|/虚拟机安装首页->新建虚拟机以上就是......
  • 无涯教程-Java - max()函数
    此方法给出两个参数中的最大值。参数可以是int,float,long,double。max()-语法此方法具有以下变体-doublemax(doublearg1,doublearg2)floatmax(floatarg1,floatarg2)intmax(intarg1,intarg2)longmax(longarg1,longarg2)max()-返回值此方法返回两个参数......
  • PS AI 创成式填充无限试用!畅快使用Adobe全套软件功能Win&MAC(保姆级教程)
    Adobe彻底放弃中国市场,如果是中国的IP访问Adobe官网,则看不到各款软件的详情介绍了,PS的最新更新时间停留在了2023年10月版本。今天就给大家带来AI创成式填充稳定可用的使用方法,并且是可以无限循环使用,还有全套Adobe软件等各种限制级功能全部解锁。本次给大家带来的是......
  • 无涯教程-Java - min()函数
    该方法给出两个参数中较小的一个。参数可以是int,float,long,double。min()-语法此方法具有以下变体-doublemin(doublearg1,doublearg2)floatmin(floatarg1,floatarg2)intmin(intarg1,intarg2)longmin(longarg1,longarg2)min()-返回值此方法返回两个参......
  • Rong晔大佬教程学习(3):取译码
    在讲解指令译码之前,我们首先需要了解指令,如下图所示,ARM、MIPS、RISCV-v指令集同属于RISC指令集(精简指令集),特别注意的是,相同的一条指令在不同的ISA中译码得到的结果是不同的,这也很好理解,比如“nihao”在拼音中可以翻译为“你好”,就是打招呼的意思,但在英文中这甚至不是一个单词......
  • 【案例教程】LoadRunner订票系统WebTours部署
    题目:使用LoadRunner自带的测试项目--航班订票管理系统WebTours,网站地址为:http://127.0.0.1:1080/WebTours/(用户名为jojo,密码为bean),完成性能测试,要求:1、虚拟用户为10;2、每隔15s启动2个Vusers;3、运行时间为5min;4、每隔15s停止2个Vusers;5、在分析工具中自定......
  • 无涯教程-Java - rint()函数
    rint方法返回值最接近参数的整数。rint()-语法doublerint(doubled)这是参数的详细信息-d  - 它接受双精度值作为参数。rint()-返回值此方法返回值最接近参数的整数。rint()-示例publicclassTest{publicstaticvoidmain(Stringargs[]){do......
  • 无涯教程-Java - toString()函数
    该方法用于获取表示Number对象值的String对象。toString()-语法以下是此方法的所有变体-StringtoString()staticStringtoString(inti)这是参数的详细信息-i   - 将为其返回字符串表示形式的int。toString()-返回值toString()     - 这将返......
  • 保姆级教程利用免费内网穿透工具快速实现远程访问SMB文件共享
    当你需要在远程网络中访问SMB(ServerMessageBlock)共享资源时,你可以使用Solopace.Gem来建立安全且便捷的连接。Solopace.Gem是一款专为远程访问和网络连接而设计的工具,它能够轻松地穿越NAT(网络地址转换)和防火墙,如果运营商的防火墙让你能够安全地远程访问SMB共享文件夹。本教程将指......
  • 无涯教程-Java - valueOf()函数
    valueOf方法返回相关的Number对象,其中包含传递的参数的值,参数可以是原始数据类型,字符串等。此方法是静态方法。该方法可以使用两个参数,其中一个是字符串,另一个是基数。valueOf()-语法以下是此方法的所有变体-staticIntegervalueOf(inti)staticIntegervalueOf(String......