RISC-V学习1.0

发布时间 2023-08-30 13:22:44作者: 有翅膀的大象

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模块支持各种算术和逻辑操作,并根据控制信号和操作数提供比较结果和结果。

ridecore/ridecore: RIDECORE (RIsc-v Dynamic Execution CORE) is an Out-of-Order RISC-V processor written in Verilog HDL. (github.com)

Dmitriy0111/nanoFOX: A small RISC-V core (SystemVerilog) (github.com)

T-head-Semi/wujian100_open: IC design and development should be faster,simpler and more reliable (github.com)

picorio / picorio-doc · GitLab