From 25c0811d3d778fbb6f42f5af3db770779a5c2366 Mon Sep 17 00:00:00 2001
From: Kevin Kim <kevindkim723@gmail.com>
Date: Fri, 17 Feb 2023 07:50:45 -0800
Subject: [PATCH] Added ALUSelect signal into datapath, ieu, controller

---
 src/ieu/controller.sv | 18 +++++++++++++-----
 src/ieu/datapath.sv   |  3 ++-
 src/ieu/ieu.sv        |  5 +++--
 3 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/src/ieu/controller.sv b/src/ieu/controller.sv
index 51f27ef7..7e054b5d 100644
--- a/src/ieu/controller.sv
+++ b/src/ieu/controller.sv
@@ -46,6 +46,7 @@ module controller(
   output logic [2:0]  ALUControlE,             // ALU operation to perform
   output logic 	      ALUSrcAE, ALUSrcBE,      // ALU operands
   output logic        ALUResultSrcE,           // Selects result to pass on to Memory stage
+  output logic [2:0]  ALUSelectE,              // ALU mux select signal
   output logic        MemReadE, CSRReadE,      // Instruction reads memory, reads a CSR (needed for Hazard unit)
   output logic [2:0]  Funct3E,                 // Instruction's funct3 field
   output logic [6:0]  Funct7E,                 // Instruction's funct7 field
@@ -90,6 +91,7 @@ module controller(
   logic		     BranchD, BranchE;               // Branch instruction
   logic	       ALUOpD;                         // 0 for address generation, 1 for all other operations (must use Funct3)
   logic [2:0]  ALUControlD;                    // Determines ALU operation
+  logic [2:0]  ALUSelectD;                     // ALU mux select signal
   logic 	     ALUSrcAD, ALUSrcBD;             // ALU inputs
   logic        ALUResultSrcD, W64D, MDUD;      // ALU result, is RV64 W-type, is multiply/divide instruction
   logic        CSRZeroSrcD;                    // Ignore setting and clearing zeros to CSR
@@ -102,7 +104,7 @@ module controller(
   logic        InvalidateICacheE, FlushDCacheE;// Invalidate I$, flush D$
   logic [`CTRLW-1:0] ControlsD;                // Main Instruction Decoder control signals
   logic        SubArithD;                      // TRUE for R-type subtracts and sra, slt, sltu
-  logic        subD, sraD, sltD, sltuD;        // Indicates if is one of these instructions
+  logic        subD, sraD, sltD, sltuD, bextD; // Indicates if is one of these instructions
   logic        BranchTakenE;                   // Branch is taken
   logic        eqE, ltE;                       // Comparator outputs
   logic        unused; 
@@ -195,9 +197,18 @@ module controller(
   assign sltuD = (Funct3D == 3'b011);
   assign subD = (Funct3D == 3'b000 & Funct7D[5] & OpD[5]);  // OpD[5] needed to distinguish sub from addi
   assign sraD = (Funct3D == 3'b101 & Funct7D[5]);
-  assign SubArithD = ALUOpD & (subD | sraD | sltD | sltuD); // TRUE for R-type subtracts and sra, slt, sltu
+  assign SubArithD = ALUOpD & (subD | sraD | sltD | sltuD | (`ZBS_SUPPORTED & bextD)); // TRUE for R-type subtracts and sra, slt, sltu
   assign ALUControlD = {W64D, SubArithD, ALUOpD};
 
+  if (`ZBS_SUPPORTED) begin: bitmanipi //change the conditional expression to OR any Z supported flags
+    bmuctrl bmuctrl(.clk, .reset, .StallD, .FlushD, .InstrD, .ALUSelectD, .bextD, .StallE, .FlushE, .Funct7E, .ALUSelectE);
+  end else begin: bitmanipi
+    assign ALUSelectD = Funct3D;
+    assign ALUSelectE = Funct3E;
+    assign bextD = 1'b0;
+    assign Funct7E = 7'b0;
+  end
+
   // Fences
   // Ordinary fence is presently a nop
   // fence.i flushes the D$ and invalidates the I$ if Zifencei is supported and I$ is implemented
@@ -239,9 +250,6 @@ module controller(
                          {RegWriteE, ResultSrcE, MemRWE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, FWriteIntE, AtomicE, InvalidateICacheE, FlushDCacheE, FenceE, InstrValidE, IntDivE},
                          {RegWriteM, ResultSrcM, MemRWM, CSRReadM, CSRWriteM, PrivilegedM, Funct3M, FWriteIntM, AtomicM, InvalidateICacheM, FlushDCacheM, FenceM, InstrValidM, IntDivM});
   
-  // BMU control register
-  flopenrc#(7) controlregBMU(clk, reset, FlushM, ~StallM, {Funct7D}, {Funct7E});
-
   // Writeback stage pipeline control register
   flopenrc #(5) controlregW(clk, reset, FlushW, ~StallW,
                          {RegWriteM, ResultSrcM, IntDivM},
diff --git a/src/ieu/datapath.sv b/src/ieu/datapath.sv
index f715a5d5..3cf12b37 100644
--- a/src/ieu/datapath.sv
+++ b/src/ieu/datapath.sv
@@ -15,6 +15,7 @@ module datapath (
   input  logic [2:0]       ALUControlE,             // Indicate operation ALU performs
   input  logic             ALUSrcAE, ALUSrcBE,      // ALU operands
   input  logic             ALUResultSrcE,           // Selects result to pass on to Memory stage
+  input  logic [2:0]       ALUSelectE,              // ALU mux select signal
   input  logic             JumpE,                   // Is a jump (j) instruction
   input  logic             BranchSignedE,           // Branch comparison operands are signed (if it's a branch)
   output logic [1:0]       FlagsE,                  // Comparison flags ({eq, lt})
@@ -81,7 +82,7 @@ module datapath (
   comparator #(`XLEN) comp(ForwardedSrcAE, ForwardedSrcBE, BranchSignedE, FlagsE);
   mux2  #(`XLEN)  srcamux(ForwardedSrcAE, PCE, ALUSrcAE, SrcAE);
   mux2  #(`XLEN)  srcbmux(ForwardedSrcBE, ImmExtE, ALUSrcBE, SrcBE);
-  alu   #(`XLEN)  alu(SrcAE, SrcBE, ALUControlE, Funct7E, Funct3E, ALUResultE, IEUAdrE);
+  alu   #(`XLEN)  alu(SrcAE, SrcBE, ALUControlE, ALUSelectE, Funct7E, Funct3E, ALUResultE, IEUAdrE);
   mux2 #(`XLEN)   altresultmux(ImmExtE, PCLinkE, JumpE, AltResultE);
   mux2 #(`XLEN)   ieuresultmux(ALUResultE, AltResultE, ALUResultSrcE, IEUResultE);
 
diff --git a/src/ieu/ieu.sv b/src/ieu/ieu.sv
index f7a20152..b8ee90d0 100644
--- a/src/ieu/ieu.sv
+++ b/src/ieu/ieu.sv
@@ -79,6 +79,7 @@ module ieu (
   logic       ALUSrcAE, ALUSrcBE;                            // ALU source operands
   logic [2:0] ResultSrcW;                                    // Selects result in Writeback stage
   logic       ALUResultSrcE;                                 // Selects ALU result to pass on to Memory stage
+  logic [2:0] ALUSelectE;                                    // ALU select mux signal
   logic       SCE;                                           // Store Conditional instruction
   logic       FWriteIntM;                                    // FPU writing to integer register file
   logic       IntDivW;                                       // Integer divide instruction
@@ -95,7 +96,7 @@ module ieu (
   controller c(
     .clk, .reset, .StallD, .FlushD, .InstrD, .ImmSrcD,
     .IllegalIEUInstrFaultD, .IllegalBaseInstrFaultD, .StallE, .FlushE, .FlagsE, .FWriteIntE,
-    .PCSrcE, .ALUControlE, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .MemReadE, .CSRReadE, 
+    .PCSrcE, .ALUControlE, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .ALUSelectE, .MemReadE, .CSRReadE, 
     .Funct3E, .Funct7E, .IntDivE, .MDUE, .W64E, .JumpE, .SCE, .BranchSignedE, .StallM, .FlushM, .MemRWM,
     .CSRReadM, .CSRWriteM, .PrivilegedM, .AtomicM, .Funct3M,
     .RegWriteM, .InvalidateICacheM, .FlushDCacheM, .InstrValidM, .InstrValidE, .InstrValidD, .FWriteIntM,
@@ -103,7 +104,7 @@ module ieu (
 
   datapath   dp(
     .clk, .reset, .ImmSrcD, .InstrD, .StallE, .FlushE, .ForwardAE, .ForwardBE,
-    .ALUControlE, .Funct3E, .Funct7E, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .JumpE, .BranchSignedE, 
+    .ALUControlE, .Funct3E, .Funct7E, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .ALUSelectE, .JumpE, .BranchSignedE, 
     .PCE, .PCLinkE, .FlagsE, .IEUAdrE, .ForwardedSrcAE, .ForwardedSrcBE,
     .StallM, .FlushM, .FWriteIntM, .FIntResM, .SrcAM, .WriteDataM, .FCvtIntW,
     .StallW, .FlushW, .RegWriteW, .IntDivW, .SquashSCW, .ResultSrcW, .ReadDataW, .FCvtIntResW,