From 27581f8d28d1ac2e1d2a86ff2b45dfda63c9b594 Mon Sep 17 00:00:00 2001
From: Kevin Kim <kevindkim723@gmail.com>
Date: Sat, 18 Feb 2023 20:57:07 -0800
Subject: [PATCH] alu and controllers handle andn, orn, xnor

---
 src/ieu/alu.sv         |  4 ++--
 src/ieu/bmu/bmuctrl.sv |  3 +++
 src/ieu/bmu/zbb.sv     |  2 +-
 src/ieu/controller.sv  | 14 +++++++++++++-
 4 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/src/ieu/alu.sv b/src/ieu/alu.sv
index 164a2810a..97400f447 100644
--- a/src/ieu/alu.sv
+++ b/src/ieu/alu.sv
@@ -113,8 +113,8 @@ module alu #(parameter WIDTH=32) (
         3'b001: FullResult = Shift;                         // sll, sra, or srl
         3'b010: FullResult = SLT;                           // slt
         3'b011: FullResult = SLTU;                          // sltu
-        3'b100: FullResult = A ^ CondMaskB;                 // xor, binv
-        3'b110: FullResult = A | CondMaskB;                 // or, bset
+        3'b100: FullResult = A ^ CondInvB;                  // xor, xnor, binv
+        3'b110: FullResult = A | CondInvB;                  // or, orn, bset
         3'b111: FullResult = A & CondInvB;                  // and, bclr
         3'b101: FullResult = {{(WIDTH-1){1'b0}},{|(A & CondMaskB)}};// bext
       endcase
diff --git a/src/ieu/bmu/bmuctrl.sv b/src/ieu/bmu/bmuctrl.sv
index ef021db0e..abaf36558 100644
--- a/src/ieu/bmu/bmuctrl.sv
+++ b/src/ieu/bmu/bmuctrl.sv
@@ -129,6 +129,9 @@ module bmuctrl(
                                  BMUControlsD = `BMUCTRLW'b000_0100_100;  // zexth (rv32)
                                else 
                                  BMUControlsD = `BMUCTRLW'b000_0000_000;  // illegal instruction
+      17'b0110011_0100000_111:   BMUControlsD = `BMUCTRLW'b111_0100_111;  // andn
+      17'b0110011_0100000_110:   BMUControlsD = `BMUCTRLW'b110_0100_111;  // orn
+      17'b0110011_0100000_100:   BMUControlsD = `BMUCTRLW'b100_0100_111;  // xnor
                                  
       default:                   BMUControlsD = {Funct3D, {7'b0}};        // not B instruction or shift
     endcase
diff --git a/src/ieu/bmu/zbb.sv b/src/ieu/bmu/zbb.sv
index d5198d484..bacbef817 100644
--- a/src/ieu/bmu/zbb.sv
+++ b/src/ieu/bmu/zbb.sv
@@ -56,7 +56,7 @@ module zbb #(parameter WIDTH=32) (
   //can replace with structural mux by looking at bit 4 in rs2 field
   always_comb begin 
       case (ZBBSelect)
-      3'b111: ZBBResult = ALUResult;  // rotate
+      3'b111: ZBBResult = ALUResult;  // rotates, andn, xnor, orn
       3'b000: ZBBResult = CntResult;  // count
       3'b100: ZBBResult = ExtResult;  // sign/zero extend
       /*15'b0010100_101_00111: ZBBResult = OrcBResult;
diff --git a/src/ieu/controller.sv b/src/ieu/controller.sv
index 70d5f5987..74d0e4f1e 100644
--- a/src/ieu/controller.sv
+++ b/src/ieu/controller.sv
@@ -107,6 +107,7 @@ module controller(
   logic        SubArithD;                      // TRUE for R-type subtracts and sra, slt, sltu
   logic        subD, sraD, sltD, sltuD;        // Indicates if is one of these instructions
   logic        bclrD, bextD;                   // Indicates if is one of these instructions
+  logic        andnD, ornD, xnorD;             // Indicates if is one of these instructions
   logic        BranchTakenE;                   // Branch is taken
   logic        eqE, ltE;                       // Comparator outputs
   logic        unused; 
@@ -210,11 +211,22 @@ module controller(
     assign bclrD = 1'b0;
     assign bextD = 1'b0;
   end
+
+  if (`ZBB_SUPPORTED) begin
+    assign andnD = (ALUSelectD == 3'b111 & BSelectD[2]);
+    assign ornD = (ALUSelectD == 3'b110 & BSelectD[2]);
+    assign xnorD = (ALUSelectD == 3'b100 & BSelectD[2]);
+  end else begin
+    assign andnD = 0;
+    assign ornD = 0;
+    assign xnorD = 0;
+  end
+
   // ALU Decoding is lazy, only using func7[5] to distinguish add/sub and srl/sra
   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 | (`ZBS_SUPPORTED & (bextD | bclrD))); // TRUE for R-type subtracts and sra, slt, sltu
+  assign SubArithD = ALUOpD & (subD | sraD | sltD | sltuD | (`ZBS_SUPPORTED & (bextD | bclrD)) | (`ZBB_SUPPORTED & (andnD | ornD | xnorD))); // TRUE for R-type subtracts and sra, slt, sltu, and any B instruction that requires inverted operand
   assign ALUControlD = {W64D, SubArithD, ALUOpD};
 
   if (`ZBS_SUPPORTED) begin: bitmanipi //change the conditional expression to OR any Z supported flags