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;