From e24ee033554613d0e19c401781f5dcc42a17ec0a Mon Sep 17 00:00:00 2001 From: Kevin Kim Date: Mon, 6 Feb 2023 17:55:37 +0000 Subject: [PATCH] modified shifter to configure for Zbb and handle rotates - alu handles rotates --- pipelined/src/ieu/alu.sv | 13 +++++- pipelined/src/ieu/shifter.sv | 79 ++++++++++++++++++++++++++++++++---- 2 files changed, 82 insertions(+), 10 deletions(-) diff --git a/pipelined/src/ieu/alu.sv b/pipelined/src/ieu/alu.sv index 1d472268..e10591c1 100644 --- a/pipelined/src/ieu/alu.sv +++ b/pipelined/src/ieu/alu.sv @@ -48,6 +48,7 @@ module alu #(parameter WIDTH=32) ( logic ALUOp; // 0 for address generation addition or 1 for regular ALU ops logic Asign, Bsign; // Sign bits of A, B logic InvB; // Is Inverted Operand Instruction (ZBB) + logic Rotate; // Is rotate operation // Extract control signals from ALUControl. assign {W64, SubArith, ALUOp} = ALUControl; @@ -74,6 +75,16 @@ module alu #(parameter WIDTH=32) ( default: InvB = 1'b0; endcase + casez ({Funct7, Funct3}) + 10'b0110000_101: Rotate = 1'b1; + 10'b011000?_101: Rotate = 1'b1; + 10'b000010?_001: Rotate = 1'b0; + 10'b0110000_001: Rotate = 1'b1; + 10'b0110000_101: Rotate = 1'b1; + 10'b0110000_001: Rotate = 1'b1; + 10'b0110000_101: Rotate = 1'b1; + default: Rotate = 1'b0; + endcase end else begin assign CondShiftA = A; @@ -85,7 +96,7 @@ module alu #(parameter WIDTH=32) ( assign {Carry, Sum} = CondShiftA + CondInvB + {{(WIDTH-1){1'b0}}, SubArith}; // Shifts - shifter sh(.A, .Amt(B[`LOG_XLEN-1:0]), .Right(Funct3[2]), .Arith(SubArith), .W64, .Y(Shift)); + shifter sh(.A, .Amt(B[`LOG_XLEN-1:0]), .Right(Funct3[2]), .Arith(SubArith), .W64, .Rotate(Rotate), .Y(Shift)); // Condition code flags are based on subtraction output Sum = A-B. // Overflow occurs when the numbers being subtracted have the opposite sign diff --git a/pipelined/src/ieu/shifter.sv b/pipelined/src/ieu/shifter.sv index 77e4dab3..15c7b411 100644 --- a/pipelined/src/ieu/shifter.sv +++ b/pipelined/src/ieu/shifter.sv @@ -1,9 +1,9 @@ /////////////////////////////////////////// // shifter.sv // -// Written: David_Harris@hmc.edu, Sarah.Harris@unlv.edu +// Written: David_Harris@hmc.edu, Sarah.Harris@unlv.edu, kekim@hmc.edu // Created: 9 January 2021 -// Modified: +// Modified: 6 February 2023 // // Purpose: RISC-V 32/64 bit shifter // @@ -30,18 +30,18 @@ `include "wally-config.vh" module shifter ( - input logic [`XLEN-1:0] A, // Source - input logic [`LOG_XLEN-1:0] Amt, // Shift amount - input logic Right, Arith, W64, // Shift right, arithmetic, RV64 W-type shift - output logic [`XLEN-1:0] Y); // Shifted result + input logic [`XLEN-1:0] A, // Source + input logic [`LOG_XLEN-1:0] Amt, // Shift amount + input logic Right, Arith, W64, Rotate, // Shift right, arithmetic, RV64 W-type shift + output logic [`XLEN-1:0] Y); // Shifted result - logic [2*`XLEN-2:0] z, zshift; // Input to funnel shifter, shifted amount before truncated to 32 or 64 bits - logic [`LOG_XLEN-1:0] amttrunc, offset; // Shift amount adjusted for RV64, right-shift amount + logic [2*`XLEN-2:0] z, zshift; // Input to funnel shifter, shifted amount before truncated to 32 or 64 bits + logic [`LOG_XLEN-1:0] amttrunc, offset; // Shift amount adjusted for RV64, right-shift amount // Handle left and right shifts with a funnel shifter. // For RV32, only 32-bit shifts are needed. // For RV64, 32- and 64-bit shifts are needed, with sign extension. - + /* // Funnel shifter input (see CMOS VLSI Design 4e Section 11.8.1, note Table 11.11 shift types wrong) if (`XLEN==32) begin:shifter // RV32 always_comb // funnel mux @@ -65,6 +65,67 @@ module shifter ( end assign amttrunc = W64 ? {1'b0, Amt[4:0]} : Amt; // 32- or 64-bit shift end + */ + + if (`ZBB_SUPPORTED) begin: rotFunnel // HANDLES ROTATE + if (`XLEN==32) begin:shifter // RV32 + always_comb // funnel mux + if (Right) + if (Rotate) z = {A[30:0], A[31:0]}; //ror (rv32) + else + if (Arith) z = {{31{A[31]}}, A}; + else z = {31'b0, A}; + else + if (Rotate) z = {A[31:0], A[31:1]}; //rol (rv32) + else z = {A, 31'b0}; + assign amttrunc = Amt; // shift amount + end else begin:shifter // RV64 + always_comb // funnel mux + if (W64) begin // 32-bit shifts + if (Right) + if (Rotate) z = {{64'b0},A[30:0],A[31:0]}; //rorw + else + if (Arith) z = {64'b0, {31{A[31]}}, A[31:0]}; + else z = {95'b0, A[31:0]}; + else + if (Rotate) z = {{64'b0},A[31:0],A[31:1]}; //rolw + else z = {32'b0, A[31:0], 63'b0}; + end else begin + if (Right) + if (Rotate) z = {A[62:0], A[63:0]}; //ror + else + if (Arith) z = {{63{A[63]}}, A}; + else z = {63'b0, A}; + else + if (Rotate) z = {A[63:0], A[63:1]}; //rol + else z = {A, 63'b0}; + end + assign amttrunc = W64 ? {1'b0, Amt[4:0]} : Amt; // 32- or 64-bit shift + end + end else begin: norotFunnel + if (`XLEN==32) begin:shifter // RV32 + always_comb // funnel mux + if (Right) + if (Arith) z = {{31{A[31]}}, A}; + else z = {31'b0, A}; + else z = {A, 31'b0}; + assign amttrunc = Amt; // shift amount + end else begin:shifter // RV64 + always_comb // funnel mux + if (W64) begin // 32-bit shifts + if (Right) + if (Arith) z = {64'b0, {31{A[31]}}, A[31:0]}; + else z = {95'b0, A[31:0]}; + else z = {32'b0, A[31:0], 63'b0}; + end else begin + if (Right) + if (Arith) z = {{63{A[63]}}, A}; + else z = {63'b0, A}; + else z = {A, 63'b0}; + end + assign amttrunc = W64 ? {1'b0, Amt[4:0]} : Amt; // 32- or 64-bit shift + end + end // Opposite offset for right shifts assign offset = Right ? amttrunc : ~amttrunc;