Membership – RISC-V International (riscv.org)
RISC-V China – RISC-V International (riscv.org)
tommythorn/yarvi: Yet Another RISC-V Implementation (github.com)
alu.v
// ----------------------------------------------------------------------- // // A purely combinatorial RV32I ALU (assumes predecoded steering) // // ISC License // // Copyright (C) 2014 - 2022 Tommy Thorn <tommy-github2@thorn.ws> // // Permission to use, copy, modify, and/or distribute this software for any // purpose with or without fee is hereby granted, provided that the above // copyright notice and this permission notice appear in all copies. // // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. // ----------------------------------------------------------------------- /* The width comparisons in Verilator are completely broken. */ /* verilator lint_off WIDTH */ `define ADDSUB 0 `define SLL 1 `define SLT 2 `define SLTU 3 `define XOR 4 `define SR_ 5 `define OR 6 `define AND 7 /* The function selector of the ALU is kept close to the RISC-V ISA, but it assumes a lot of instructions translate their opcodes into the ALU appropriate ones and feed the ALU with the relevant operands. Further improvement possible: - multi-cycle shifter (eg. migrate shifter out of this ALU) */ `default_nettype none module alu(sub, ashr, funct3, w, op1, op2, result, eq, lt, ltu); parameter XLEN = 64; parameter XMSB = XLEN-1; parameter X2MSB = ($clog2(XLEN)-1); input wire sub; input wire ashr; input wire [ 2:0] funct3; input wire w; input wire [XMSB:0] op1; input wire [XMSB:0] op2; output reg [XMSB:0] result; output wire eq; output wire lt; output wire ltu; // sum = op1 + op2 or op1 - op2 wire [XLEN:0] sum = op1 + ({XLEN{sub}} ^ op2) + sub; wire s = sum[XMSB]; wire c = sum[XLEN]; wire v = op1[XMSB] == !op2[XMSB] && op1[XMSB] != s; assign eq = op1 == op2; assign lt = s ^ v; assign ltu = !c; always @(*) begin case (funct3) `SLT: result = {{XMSB{1'd0}}, lt}; // $signed(op1) < $signed(op2) `SLTU: result = {{XMSB{1'd0}}, ltu}; // op1 < op2 `ifndef NO_SHIFTS `SR_: if (XLEN != 32 && w) result = $signed({op1[31] & ashr, op1[31:0]}) >>> op2[4:0]; else result = $signed({op1[XMSB] & ashr, op1}) >>> op2[X2MSB:0]; `SLL: result = op1 << op2[X2MSB:0]; `endif `AND: result = op1 & op2; `OR: result = op1 | op2; `XOR: result = op1 ^ op2; default: result = 'hX; endcase if (funct3 == `ADDSUB) result = sum[XMSB:0]; if (XLEN != 32 && w) result = {{XLEN/2{result[XLEN/2-1]}}, result[XLEN/2-1:0]}; end endmodule
代码定义了一个Verilog中的算术逻辑单元(ALU)模块。ALU基于控制信号和输入操作数执行各种操作。
ALU模块有以下输入:
- "sub":表示减法操作的控制信号。
- "ashr":表示算术右移操作的控制信号。
- "funct3":表示ALU执行的功能的3位控制信号。
- "w":表示ALU是否应该对32位或64位数字进行操作的控制信号。
- "op1":ALU操作的第一个操作数。
- "op2":ALU操作的第二个操作数。
ALU模块有以下输出:
- "result":ALU操作的结果。
- "eq":指示操作数是否相等的信号。
- "lt":指示第一个操作数是否小于第二个操作数(有符号比较)的信号。
- "ltu":指示第一个操作数是否小于第二个操作数(无符号比较)的信号。
ALU模块根据"funct3"控制信号支持以下操作:
- ADD/SUB("funct3 = 0"):根据"sub"控制信号执行加法或减法。
- SLL("funct3 = 1"):执行逻辑左移操作。
- SLT("funct3 = 2"):执行有符号小于比较。
- SLTU("funct3 = 3"):执行无符号小于比较。
- XOR("funct3 = 4"):执行按位异或操作。
- SR("funct3 = 5"):根据"ashr"控制信号执行逻辑或算术右移操作。
- OR("funct3 = 6"):执行按位或操作。
- AND("funct3 = 7"):执行按位与操作。
在"always @(*)"块中使用case语句显示了每个操作的实现。操作的结果被赋值给"result"输出线。
ALU还执行附加操作,如计算进位("c"),有符号位("s")和溢出("v")。
在模块的结尾,如果"funct3"控制信号设置为"ADDSUB"(0),则根据"sub"控制信号将"result"更新为操作数的和或差。
最后,对字大小"w"进行检查,以确定结果是否应该截断为32位。结果分配给"result"输出线。
该ALU模块支持各种算术和逻辑操作,并根据控制信号和操作数提供比较结果和结果。
Dmitriy0111/nanoFOX: A small RISC-V core (SystemVerilog) (github.com)
picorio / picorio-doc · GitLab
标签:wire,1.0,op1,op2,RISC,学习,funct3,result,ALU From: https://www.cnblogs.com/shiningleo007/p/17666963.html