mirror of
				https://github.com/openhwgroup/cvw
				synced 2025-02-11 06:05:49 +00:00 
			
		
		
		
	Merge pull request #158 from kipmacsaigoren/bitmanip-alu
Modularize Bit Manipulation Specific ALU Changes
This commit is contained in:
		
						commit
						9b2c170c03
					
				
							
								
								
									
										130
									
								
								src/ieu/alu.sv
									
									
									
									
									
								
							
							
						
						
									
										130
									
								
								src/ieu/alu.sv
									
									
									
									
									
								
							| @ -33,7 +33,7 @@ module alu #(parameter WIDTH=32) ( | |||||||
|   input  logic [WIDTH-1:0] A, B,        // Operands
 |   input  logic [WIDTH-1:0] A, B,        // Operands
 | ||||||
|   input  logic [2:0]       ALUControl,  // With Funct3, indicates operation to perform
 |   input  logic [2:0]       ALUControl,  // With Funct3, indicates operation to perform
 | ||||||
|   input  logic [2:0]       ALUSelect,   // ALU mux select signal
 |   input  logic [2:0]       ALUSelect,   // ALU mux select signal
 | ||||||
|   input  logic [1:0]       BSelect,     // One-Hot encoding of if it's a ZBA_ZBB_ZBC_ZBS instruction
 |   input  logic [1:0]       BSelect,     // Binary encoding of if it's a ZBA_ZBB_ZBC_ZBS instruction
 | ||||||
|   input  logic [2:0]       ZBBSelect,   // ZBB mux select signal
 |   input  logic [2:0]       ZBBSelect,   // ZBB mux select signal
 | ||||||
|   input  logic [2:0]       Funct3,      // With ALUControl, indicates operation to perform NOTE: Change signal name to ALUSelect
 |   input  logic [2:0]       Funct3,      // With ALUControl, indicates operation to perform NOTE: Change signal name to ALUSelect
 | ||||||
|   input  logic [1:0]       CompFlags,   // Comparator flags
 |   input  logic [1:0]       CompFlags,   // Comparator flags
 | ||||||
| @ -43,43 +43,31 @@ module alu #(parameter WIDTH=32) ( | |||||||
| 
 | 
 | ||||||
|   // CondInvB = ~B when subtracting, B otherwise. Shift = shift result. SLT/U = result of a slt/u instruction.
 |   // CondInvB = ~B when subtracting, B otherwise. Shift = shift result. SLT/U = result of a slt/u instruction.
 | ||||||
|   // FullResult = ALU result before adjusting for a RV64 w-suffix instruction.
 |   // FullResult = ALU result before adjusting for a RV64 w-suffix instruction.
 | ||||||
|   logic [WIDTH-1:0] CondMaskInvB, Shift, FullResult,ALUResult;                   // Intermediate Signals 
 |   logic [WIDTH-1:0] CondMaskInvB, Shift, FullResult, ALUResult;                   // Intermediate Signals 
 | ||||||
|   logic [WIDTH-1:0] ZBCResult, ZBBResult;                                                   // Result of ZBB, ZBC
 |   logic [WIDTH-1:0] CondMaskB;                                                    // Result of B mask select mux
 | ||||||
|   logic [WIDTH-1:0] MaskB;                                                                  // BitMask of B
 |   logic [WIDTH-1:0] CondShiftA;                                                   // Result of A shifted select mux
 | ||||||
|   logic [WIDTH-1:0] CondMaskB;                                                              // Result of B mask select mux
 |   logic [WIDTH-1:0] CondExtA;                                                     // Result of Zero Extend A select mux
 | ||||||
|   logic [WIDTH-1:0] CondShiftA;                                                             // Result of A shifted select mux
 |   logic             Carry, Neg;                                                   // Flags: carry out, negative
 | ||||||
|   logic [WIDTH-1:0] CondExtA;                                                               // Result of Zero Extend A select mux
 |   logic             LT, LTU;                                                      // Less than, Less than unsigned
 | ||||||
|   logic [WIDTH-1:0] RevA;                                                                   // Bit-reversed A
 |   logic             W64;                                                          // RV64 W-type instruction
 | ||||||
|   logic             Carry, Neg;                                                             // Flags: carry out, negative
 |   logic             SubArith;                                                     // Performing subtraction or arithmetic right shift
 | ||||||
|   logic             LT, LTU;                                                                // Less than, Less than unsigned
 |   logic             ALUOp;                                                        // 0 for address generation addition or 1 for regular ALU ops
 | ||||||
|   logic             W64;                                                                    // RV64 W-type instruction
 |   logic             Asign, Bsign;                                                 // Sign bits of A, B
 | ||||||
|   logic             SubArith;                                                               // Performing subtraction or arithmetic right shift
 |  | ||||||
|   logic             ALUOp;                                                                  // 0 for address generation addition or 1 for regular ALU ops
 |  | ||||||
|   logic             Asign, Bsign;                                                           // Sign bits of A, B
 |  | ||||||
|   logic             shSignA; |   logic             shSignA; | ||||||
|   logic [WIDTH-1:0] rotA;                                                                   // XLEN bit input source to shifter
 |   logic [WIDTH-1:0] rotA;                                                         // XLEN bit input source to shifter
 | ||||||
|   logic [1:0]       shASelect;                                                              // select signal for shifter source generation mux 
 |   logic [1:0]       shASelect;                                                    // select signal for shifter source generation mux 
 | ||||||
|   logic             Rotate;                                                                 // Indicates if it is Rotate instruction
 |   logic             Rotate;                                                       // Indicates if it is Rotate instruction
 | ||||||
|   logic             Mask;                                                                   // Indicates if it is ZBS instruction
 |  | ||||||
|   logic             PreShift;                                                               // Inidicates if it is sh1add, sh2add, sh3add instruction
 |  | ||||||
|   logic [1:0]       PreShiftAmt;                                                            // Amount to Pre-Shift A 
 |  | ||||||
| 
 | 
 | ||||||
|   // Extract control signals from ALUControl.
 |   // Extract control signals from ALUControl.
 | ||||||
|   assign {W64, SubArith, ALUOp} = ALUControl; |   assign {W64, SubArith, ALUOp} = ALUControl; | ||||||
| 
 | 
 | ||||||
|   // Extract control signals from bitmanip ALUControl.
 |   // Extract rotate signal from BALUControl.
 | ||||||
|   assign {Rotate, Mask, PreShift} = BALUControl; |   assign Rotate = BALUControl[2]; | ||||||
| 
 | 
 | ||||||
|   // Pack control signals into shifter select
 |   // Pack control signals into shifter select signal.
 | ||||||
|   assign shASelect = {W64,SubArith}; |   assign shASelect = {W64, SubArith}; | ||||||
| 
 |  | ||||||
|   assign PreShiftAmt = Funct3[2:1] & {2{PreShift}}; |  | ||||||
| 
 |  | ||||||
|   if (`ZBS_SUPPORTED) begin: zbsdec |  | ||||||
|     decoder #($clog2(WIDTH)) maskgen (B[$clog2(WIDTH)-1:0], MaskB); |  | ||||||
|     mux2 #(WIDTH) maskmux(B, MaskB, Mask, CondMaskB); |  | ||||||
|   end else assign CondMaskB = B; |  | ||||||
| 
 | 
 | ||||||
|  |   // A, A sign bit muxes
 | ||||||
|   if (WIDTH == 64) begin |   if (WIDTH == 64) begin | ||||||
|     mux3 #(1) signmux(A[63], A[31], 1'b0, {~SubArith, W64}, shSignA); |     mux3 #(1) signmux(A[63], A[31], 1'b0, {~SubArith, W64}, shSignA); | ||||||
|     mux3 #(64) extendmux({{32{1'b0}}, A[31:0]},{{32{A[31]}}, A[31:0]}, A,{~W64, SubArith}, CondExtA); |     mux3 #(64) extendmux({{32{1'b0}}, A[31:0]},{{32{A[31]}}, A[31:0]}, A,{~W64, SubArith}, CondExtA); | ||||||
| @ -88,16 +76,6 @@ module alu #(parameter WIDTH=32) ( | |||||||
|     assign CondExtA = A; |     assign CondExtA = A; | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   // shifter rotate source select mux
 |  | ||||||
|   if (`ZBB_SUPPORTED & WIDTH == 64) begin |  | ||||||
|     mux2 #(WIDTH) rotmux(A, {A[31:0], A[31:0]}, W64, rotA); |  | ||||||
|   end else assign rotA = A; |  | ||||||
|      |  | ||||||
|   if (`ZBA_SUPPORTED) begin: zbapreshift |  | ||||||
|     // Pre-Shift
 |  | ||||||
|     assign CondShiftA = CondExtA << (PreShiftAmt); |  | ||||||
|   end else assign CondShiftA = A; |  | ||||||
| 
 |  | ||||||
|   // Addition
 |   // Addition
 | ||||||
|   assign CondMaskInvB = SubArith ? ~CondMaskB : CondMaskB; |   assign CondMaskInvB = SubArith ? ~CondMaskB : CondMaskB; | ||||||
|   assign {Carry, Sum} = CondShiftA + CondMaskInvB + {{(WIDTH-1){1'b0}}, SubArith}; |   assign {Carry, Sum} = CondShiftA + CondMaskInvB + {{(WIDTH-1){1'b0}}, SubArith}; | ||||||
| @ -116,59 +94,33 @@ module alu #(parameter WIDTH=32) ( | |||||||
|   assign LTU = ~Carry; |   assign LTU = ~Carry; | ||||||
|   |   | ||||||
|   // Select appropriate ALU Result
 |   // Select appropriate ALU Result
 | ||||||
|   if (`ZBS_SUPPORTED | `ZBB_SUPPORTED) begin |   always_comb begin | ||||||
|     always_comb |     if (~ALUOp) FullResult = Sum;                         // Always add for ALUOp = 0 (address generation)
 | ||||||
|       if (~ALUOp) FullResult = Sum;                         // Always add for ALUOp = 0 (address generation)
 |     else casez (ALUSelect)                                // Otherwise check Funct3 NOTE: change signal name to ALUSelect
 | ||||||
|       else casez (ALUSelect)                                // Otherwise check Funct3 NOTE: change signal name to ALUSelect
 |       3'b000: FullResult = Sum;                           // add or sub
 | ||||||
|         3'b000: FullResult = Sum;                           // add or sub
 |       3'b001: FullResult = Shift;                         // sll, sra, or srl
 | ||||||
|         3'b001: FullResult = Shift;                         // sll, sra, or srl
 |       3'b010: FullResult = {{(WIDTH-1){1'b0}}, LT};       // slt
 | ||||||
|         3'b010: FullResult = {{(WIDTH-1){1'b0}}, LT};       // slt
 |       3'b011: FullResult = {{(WIDTH-1){1'b0}}, LTU};      // sltu
 | ||||||
|         3'b011: FullResult = {{(WIDTH-1){1'b0}}, LTU};      // sltu
 |       3'b100: FullResult = A ^ CondMaskInvB;              // xor, xnor, binv
 | ||||||
|         3'b100: FullResult = A ^ CondMaskInvB;              // xor, xnor, binv
 |       3'b101: FullResult = (`ZBS_SUPPORTED | `ZBB_SUPPORTED) ? {{(WIDTH-1){1'b0}},{|(A & CondMaskB)}} : Shift;// bext
 | ||||||
|         3'b101: FullResult = {{(WIDTH-1){1'b0}},{|(A & CondMaskB)}};// bext
 |       3'b110: FullResult = A | CondMaskInvB;              // or, orn, bset
 | ||||||
|         3'b110: FullResult = A | CondMaskInvB;              // or, orn, bset
 |       3'b111: FullResult = A & CondMaskInvB;              // and, bclr
 | ||||||
|         3'b111: FullResult = A & CondMaskInvB;              // and, bclr
 |     endcase | ||||||
|       endcase |  | ||||||
|   end |   end | ||||||
|   else begin |  | ||||||
|     always_comb |  | ||||||
|       if (~ALUOp) FullResult = Sum;     // Always add for ALUOp = 0 (address generation)
 |  | ||||||
|       else casez (ALUSelect)            // Otherwise check Funct3 NOTE: change signal name to ALUSelect
 |  | ||||||
|         3'b000: FullResult = Sum;       // add or sub
 |  | ||||||
|         3'b?01: FullResult = Shift;     // sll, sra, or srl
 |  | ||||||
|         3'b010: FullResult = {{(WIDTH-1){1'b0}}, LT};        // slt
 |  | ||||||
|         3'b011: FullResult = {{(WIDTH-1){1'b0}}, LTU};       // sltu
 |  | ||||||
|         3'b100: FullResult = A ^ B;     // xor
 |  | ||||||
|         3'b110: FullResult = A | B;     // or 
 |  | ||||||
|         3'b111: FullResult = A & B;     // and
 |  | ||||||
|       endcase |  | ||||||
|   end |  | ||||||
| 
 |  | ||||||
|   if (`ZBC_SUPPORTED | `ZBB_SUPPORTED) begin: bitreverse |  | ||||||
|     bitreverse #(WIDTH) brA(.A, .RevA); |  | ||||||
|   end |  | ||||||
| 
 |  | ||||||
|   if (`ZBC_SUPPORTED) begin: zbc |  | ||||||
|     zbc #(WIDTH) ZBC(.A, .RevA, .B, .Funct3, .ZBCResult); |  | ||||||
|   end else assign ZBCResult = 0; |  | ||||||
| 
 |  | ||||||
|   if (`ZBB_SUPPORTED) begin: zbb |  | ||||||
|     zbb #(WIDTH) ZBB(.A, .RevA, .B, .ALUResult, .W64, .lt(CompFlags[0]), .ZBBSelect, .ZBBResult); |  | ||||||
|   end else assign ZBBResult = 0; |  | ||||||
| 
 | 
 | ||||||
|   // Support RV64I W-type addw/subw/addiw/shifts that discard upper 32 bits and sign-extend 32-bit result to 64 bits
 |   // Support RV64I W-type addw/subw/addiw/shifts that discard upper 32 bits and sign-extend 32-bit result to 64 bits
 | ||||||
|   if (WIDTH == 64)  assign ALUResult = W64 ? {{32{FullResult[31]}}, FullResult[31:0]} : FullResult; |   if (WIDTH == 64)  assign ALUResult = W64 ? {{32{FullResult[31]}}, FullResult[31:0]} : FullResult; | ||||||
|   else              assign ALUResult = FullResult; |   else              assign ALUResult = FullResult; | ||||||
| 
 | 
 | ||||||
|   // Final Result B instruction select mux
 |   // Final Result B instruction select mux
 | ||||||
|   if (`ZBC_SUPPORTED | `ZBS_SUPPORTED | `ZBA_SUPPORTED | `ZBB_SUPPORTED) begin : zbdecoder |   if (`ZBC_SUPPORTED | `ZBS_SUPPORTED | `ZBA_SUPPORTED | `ZBB_SUPPORTED) begin : bitmanipalu | ||||||
|     always_comb |     bitmanipalu #(WIDTH) balu(.A, .B, .ALUControl, .ALUSelect, .BSelect, .ZBBSelect,  | ||||||
|       case (BSelect) |        .Funct3, .CompFlags, .BALUControl, .CondExtA, .ALUResult, .FullResult, | ||||||
|         // 00: ALU, 01: ZBA/ZBS, 10: ZBB, 11: ZBC
 |       .CondMaskB, .CondShiftA, .rotA, .Result); | ||||||
|         2'b00: Result = ALUResult;  |   end else begin | ||||||
|         2'b01: Result = FullResult;         // NOTE: We don't use ALUResult because ZBA/ZBS instructions don't sign extend the MSB of the right-hand word.
 |     assign Result = ALUResult; | ||||||
|         2'b10: Result = ZBBResult;  |     assign CondMaskB = B; | ||||||
|         2'b11: Result = ZBCResult; |     assign CondShiftA = A; | ||||||
|       endcase |     assign rotA = A; | ||||||
|   end else assign Result = ALUResult; |   end | ||||||
| endmodule | endmodule | ||||||
							
								
								
									
										109
									
								
								src/ieu/bmu/bitmanipalu.sv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								src/ieu/bmu/bitmanipalu.sv
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,109 @@ | |||||||
|  | ///////////////////////////////////////////
 | ||||||
|  | // bitmanipalu.sv
 | ||||||
|  | //
 | ||||||
|  | // Written: Kevin Kim <kekim@hmc.edu>
 | ||||||
|  | // Created: 23 March 2023
 | ||||||
|  | // Modified: 23 March 2023
 | ||||||
|  | //
 | ||||||
|  | // Purpose: RISC-V Arithmetic/Logic Unit Bit-Manipulation Extension
 | ||||||
|  | //
 | ||||||
|  | // Documentation: RISC-V System on Chip Design Chapter 15
 | ||||||
|  | // 
 | ||||||
|  | // A component of the CORE-V-WALLY configurable RISC-V project.
 | ||||||
|  | // 
 | ||||||
|  | // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
 | ||||||
|  | //
 | ||||||
|  | // SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
 | ||||||
|  | //
 | ||||||
|  | // Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file 
 | ||||||
|  | // except in compliance with the License, or, at your option, the Apache License version 2.0. You 
 | ||||||
|  | // may obtain a copy of the License at
 | ||||||
|  | //
 | ||||||
|  | // https://solderpad.org/licenses/SHL-2.1/
 | ||||||
|  | //
 | ||||||
|  | // Unless required by applicable law or agreed to in writing, any work distributed under the 
 | ||||||
|  | // License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
 | ||||||
|  | // either express or implied. See the License for the specific language governing permissions 
 | ||||||
|  | // and limitations under the License.
 | ||||||
|  | ////////////////////////////////////////////////////////////////////////////////////////////////
 | ||||||
|  | 
 | ||||||
|  | `include "wally-config.vh" | ||||||
|  | 
 | ||||||
|  | module bitmanipalu #(parameter WIDTH=32) ( | ||||||
|  |   input  logic [WIDTH-1:0] A, B,                    // Operands
 | ||||||
|  |   input  logic [2:0]       ALUControl,              // With Funct3, indicates operation to perform
 | ||||||
|  |   input  logic [2:0]       ALUSelect,               // ALU mux select signal
 | ||||||
|  |   input  logic [1:0]       BSelect,                 // Binary encoding of if it's a ZBA_ZBB_ZBC_ZBS instruction
 | ||||||
|  |   input  logic [2:0]       ZBBSelect,               // ZBB mux select signal
 | ||||||
|  |   input  logic [2:0]       Funct3,                  // With ALUControl, indicates operation to perform NOTE: Change signal name to ALUSelect
 | ||||||
|  |   input  logic [1:0]       CompFlags,               // Comparator flags
 | ||||||
|  |   input  logic [2:0]       BALUControl,             // ALU Control signals for B instructions in Execute Stage
 | ||||||
|  |   input  logic [WIDTH-1:0] CondExtA,                // A Conditional Extend Intermediary Signal
 | ||||||
|  |   input  logic [WIDTH-1:0] ALUResult, FullResult,   // ALUResult, FullResult signals
 | ||||||
|  |   output logic [WIDTH-1:0] CondMaskB,               // B is conditionally masked for ZBS instructions
 | ||||||
|  |   output logic [WIDTH-1:0] CondShiftA,              // A is conditionally shifted for ShAdd instructions
 | ||||||
|  |   output logic [WIDTH-1:0] rotA,                    // Rotate source signal
 | ||||||
|  |   output logic [WIDTH-1:0] Result);                 // Result
 | ||||||
|  | 
 | ||||||
|  |   logic [WIDTH-1:0] ZBBResult, ZBCResult;           // ZBB, ZBC Result
 | ||||||
|  |   logic [WIDTH-1:0] MaskB;                          // BitMask of B
 | ||||||
|  |   logic [WIDTH-1:0] RevA;                           // Bit-reversed A
 | ||||||
|  |   logic             W64;                            // RV64 W-type instruction
 | ||||||
|  |   logic             SubArith;                       // Performing subtraction or arithmetic right shift
 | ||||||
|  |   logic             ALUOp;                          // 0 for address generation addition or 1 for regular ALU ops
 | ||||||
|  |   logic             Rotate;                         // Indicates if it is Rotate instruction
 | ||||||
|  |   logic             Mask;                           // Indicates if it is ZBS instruction
 | ||||||
|  |   logic             PreShift;                       // Inidicates if it is sh1add, sh2add, sh3add instruction
 | ||||||
|  |   logic [1:0]       PreShiftAmt;                    // Amount to Pre-Shift A 
 | ||||||
|  | 
 | ||||||
|  |   // Extract control signals from ALUControl.
 | ||||||
|  |   assign {W64, SubArith, ALUOp} = ALUControl; | ||||||
|  | 
 | ||||||
|  |   // Extract control signals from bitmanip ALUControl.
 | ||||||
|  |   assign {Mask, PreShift} = BALUControl[1:0]; | ||||||
|  | 
 | ||||||
|  |   // Mask Generation Mux
 | ||||||
|  |   if (`ZBS_SUPPORTED) begin: zbsdec | ||||||
|  |     decoder #($clog2(WIDTH)) maskgen (B[$clog2(WIDTH)-1:0], MaskB); | ||||||
|  |     mux2 #(WIDTH) maskmux(B, MaskB, Mask, CondMaskB); | ||||||
|  |   end else assign CondMaskB = B; | ||||||
|  |   | ||||||
|  |   // shifter rotate source select mux
 | ||||||
|  |   if (`ZBB_SUPPORTED & WIDTH == 64) begin | ||||||
|  |     mux2 #(WIDTH) rotmux(A, {A[31:0], A[31:0]}, W64, rotA); | ||||||
|  |   end else assign rotA = A; | ||||||
|  |      | ||||||
|  |   // Pre-Shift Mux
 | ||||||
|  |   if (`ZBA_SUPPORTED) begin: zbapreshift | ||||||
|  |     assign PreShiftAmt = Funct3[2:1] & {2{PreShift}}; | ||||||
|  |     assign CondShiftA = CondExtA << (PreShiftAmt); | ||||||
|  |   end else begin | ||||||
|  |     assign PreShiftAmt = 2'b0; | ||||||
|  |     assign CondShiftA = A; | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   // Bit reverse needed for some ZBB, ZBC instructions
 | ||||||
|  |   if (`ZBC_SUPPORTED | `ZBB_SUPPORTED) begin: bitreverse | ||||||
|  |     bitreverse #(WIDTH) brA(.A, .RevA); | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   // ZBC Unit
 | ||||||
|  |   if (`ZBC_SUPPORTED) begin: zbc | ||||||
|  |     zbc #(WIDTH) ZBC(.A, .RevA, .B, .Funct3, .ZBCResult); | ||||||
|  |   end else assign ZBCResult = 0; | ||||||
|  | 
 | ||||||
|  |   // ZBB Unit
 | ||||||
|  |   if (`ZBB_SUPPORTED) begin: zbb | ||||||
|  |     zbb #(WIDTH) ZBB(.A, .RevA, .B, .ALUResult, .W64, .lt(CompFlags[0]), .ZBBSelect, .ZBBResult); | ||||||
|  |   end else assign ZBBResult = 0; | ||||||
|  | 
 | ||||||
|  |   // Result Select Mux
 | ||||||
|  |   always_comb | ||||||
|  |     case (BSelect) | ||||||
|  |       // 00: ALU, 01: ZBA/ZBS, 10: ZBB, 11: ZBC
 | ||||||
|  |       2'b00: Result = ALUResult;  | ||||||
|  |       2'b01: Result = FullResult;         // NOTE: We don't use ALUResult because ZBA/ZBS instructions don't sign extend the MSB of the right-hand word.
 | ||||||
|  |       2'b10: Result = ZBBResult;  | ||||||
|  |       2'b11: Result = ZBCResult; | ||||||
|  |     endcase | ||||||
|  | endmodule | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user