首页 > 其他分享 >Rong晔大佬教程学习(5):ALU单元设计

Rong晔大佬教程学习(5):ALU单元设计

时间:2023-12-14 11:11:20浏览次数:40  
标签:教程 ALU Rong src2 WIDTH input alu CPU

  之前我们提到,alu一共有两个输入,通过前几章的指令部分,我们可以发现有以下四种情况:

   注意:虽然上面有四种情况,但由于本项目的U型指令只实现了lui,也就是立即数左移12位,所以把这一类归为寄存器和立即数,而不是第四种立即数和pc,这个是auipc指令实现的功能。所以下面代码中一共只有三种情况。

1.mux_alu.v

`include "rvseed_defines.v"
//使用一个多路选择器实现alu输入数据源的选择(一共有三种情况)
module mux_alu ( 
    input      [`ALU_SRC_WIDTH-1:0] alu_src_sel,// reg or imm to alu,由ctrl提供

    input      [`CPU_WIDTH-1:0]     reg1_rdata, // register 1 read data
    input      [`CPU_WIDTH-1:0]     reg2_rdata, // register 2 read data
    input      [`CPU_WIDTH-1:0]     imm,        // immediate
    input      [`CPU_WIDTH-1:0]     curr_pc,    // current pc addr

    output reg [`CPU_WIDTH-1:0]     alu_src1,   // alu source 1
    output reg [`CPU_WIDTH-1:0]     alu_src2    // alu source 2
);

always @(*) begin
    alu_src1 = reg1_rdata;     // defalut select reg1 data
    alu_src2 = reg2_rdata;     // default select reg2 data
    case (alu_src_sel)
        `ALU_SRC_REG: 
            alu_src2 = reg2_rdata; // select reg2 data
        `ALU_SRC_IMM: 
            alu_src2 = imm;        // select immediate 
        `ALU_SRC_FOUR_PC: begin
            alu_src1 = `CPU_WIDTH'h4; // pc + 4 
            alu_src2 = curr_pc;       //
        end
    endcase
end
endmodule

  上面的alu_src_sel的case判断只有三种情况,原因上面橙色部分已经给出

 

2.alu.v(运算模块)

   运算模块的设计非常简单,因为只有加法和减法两个运算:

`include "rvseed_defines.v"

module alu(
    input      [`ALU_OP_WIDTH-1:0] alu_op,   // alu opcode
    input      [`CPU_WIDTH-1:0]    alu_src1, // alu source 1
    input      [`CPU_WIDTH-1:0]    alu_src2, // alu source 2
    output reg                     zero,     // alu result is zero
    output reg [`CPU_WIDTH-1:0]    alu_res   // alu result
);

//运算结果设计标志位zero是否为0
//当前运算中只有一个加法运算和一个减法运算,且加法为半加器,不考虑逸出
//且这里不考虑有符号无符号问题,其他指令会涉及,此处不涉及
always @(*) begin
    zero = 1'b0;
    alu_res = `CPU_WIDTH'b0;            //运算结果为32位
    case (alu_op)
        `ALU_ADD: 
            alu_res = alu_src1 + alu_src2;
        `ALU_SUB:begin 
            alu_res = alu_src1 - alu_src2;
            zero = (alu_res == `CPU_WIDTH'b0) ? 1'b1 : 1'b0;//运算结果为0,标志信号会被拉高
        end
    endcase
end
endmodule

  (仔细想了一下,这么看下来这个riscv实现的指令肯定比第一章说的那那五个要多,但肯定也没多多少呵呵呵,比如R型指令应该中实现了一个add和一个sub,J型指令只实现了一个jal,U型指令只实现了一个lui,但其实细细想一下其实其他指令的实现也不难,只是需要考虑的更多,实现的运算也更多)

 

`include "rvseed_defines.v"
module alu(     input      [`ALU_OP_WIDTH-1:0] alu_op,   // alu opcode     input      [`CPU_WIDTH-1:0]    alu_src1, // alu source 1     input      [`CPU_WIDTH-1:0]    alu_src2, // alu source 2     output reg                     zero,     // alu result is zero     output reg [`CPU_WIDTH-1:0]    alu_res   // alu result );
//运算结果设计标志位zero是否为0 //当前运算中只有一个加法运算和一个减法运算,且加法为半加器,不考虑逸出 //且这里不考虑有符号无符号问题,其他指令会涉及,此处不涉及 always @(*) begin     zero = 1'b0;     alu_res = `CPU_WIDTH'b0;            //运算结果为32位     case (alu_op)         `ALU_ADD:             alu_res = alu_src1 + alu_src2;         `ALU_SUB:begin             alu_res = alu_src1 - alu_src2;             zero = (alu_res == `CPU_WIDTH'b0) ? 1'b1 : 1'b0;//运算结果为0,标志信号会被拉高         end     endcase end endmodule

标签:教程,ALU,Rong,src2,WIDTH,input,alu,CPU
From: https://www.cnblogs.com/liwilling/p/17900776.html

相关文章

  • Rong晔大佬教程学习(4):寄存器堆和立即数扩展
    在第一节的设计结构图中,我们可以看到,ctrl.v模块译码后,就可以得到我们实际运算所需要的数据,有两种:1.寄存器值,通过译码后得到的地址在寄存器堆中读出;2.立即数值,在译码后进行扩展得到的完整的立即数值。首先来看寄存器堆,一共有32个寄存器: 接口名称表示每个寄存器的功......
  • 虚拟机安装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共享文件夹。本教程将指......