From 2069d92f9ec67bdcba8715d18c1b64b84289fc19 Mon Sep 17 00:00:00 2001 From: Kevin Kim Date: Sat, 18 Feb 2023 22:12:55 -0800 Subject: [PATCH] B DONE (for now) - datapath passes along comparator flag to alu - controllers and zbb handle min/max instructions --- src/ieu/alu.sv | 3 ++- src/ieu/bmu/bmuctrl.sv | 4 ++++ src/ieu/bmu/zbb.sv | 11 +++++++++++ src/ieu/controller.sv | 13 ++++++++++++- src/ieu/datapath.sv | 2 +- 5 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/ieu/alu.sv b/src/ieu/alu.sv index 97400f44..0e7487eb 100644 --- a/src/ieu/alu.sv +++ b/src/ieu/alu.sv @@ -36,6 +36,7 @@ module alu #(parameter WIDTH=32) ( input logic [3:0] BSelect, // One-Hot 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 output logic [WIDTH-1:0] Result, // ALU result output logic [WIDTH-1:0] Sum); // Sum of operands @@ -145,7 +146,7 @@ module alu #(parameter WIDTH=32) ( end else assign ZBCResult = 0; if (`ZBB_SUPPORTED) begin: zbb - zbb #(WIDTH) ZBB(.A(A), .B(B), .ALUResult(ALUResult), .W64(W64), .ZBBSelect(ZBBSelect), .ZBBResult(ZBBResult)); + zbb #(WIDTH) ZBB(.A(A), .B(B), .ALUResult(ALUResult), .W64(W64), .lt(CompFlags[0]), .ZBBSelect(ZBBSelect), .ZBBResult(ZBBResult)); end else assign ZBBResult = 0; // Final Result B instruction select mux diff --git a/src/ieu/bmu/bmuctrl.sv b/src/ieu/bmu/bmuctrl.sv index ab275047..097ee27e 100644 --- a/src/ieu/bmu/bmuctrl.sv +++ b/src/ieu/bmu/bmuctrl.sv @@ -141,6 +141,10 @@ module bmuctrl( else BMUControlsD = `BMUCTRLW'b000_0000_000; // illegal instruction 17'b0010011_0010100_101: BMUControlsD = `BMUCTRLW'b000_0100_011; // orc.b + 17'b0110011_0000101_110: BMUControlsD = `BMUCTRLW'b000_0100_101; // max + 17'b0110011_0000101_111: BMUControlsD = `BMUCTRLW'b000_0100_101; // maxu + 17'b0110011_0000101_100: BMUControlsD = `BMUCTRLW'b000_0100_110; // min + 17'b0110011_0000101_101: BMUControlsD = `BMUCTRLW'b000_0100_110; // minu 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 2342fe0c..3289d13a 100644 --- a/src/ieu/bmu/zbb.sv +++ b/src/ieu/bmu/zbb.sv @@ -34,6 +34,7 @@ module zbb #(parameter WIDTH=32) ( input logic [WIDTH-1:0] A, B, // Operands input logic [WIDTH-1:0] ALUResult, // ALU Result input logic W64, // Indicates word operation + input logic lt, // lt flag input logic [2:0] ZBBSelect, // Indicates word operation output logic [WIDTH-1:0] ZBBResult); // ZBB result @@ -41,6 +42,10 @@ module zbb #(parameter WIDTH=32) ( // count result logic [WIDTH-1:0] CntResult; + + // min,max result + logic [WIDTH-1:0] MaxResult; + logic [WIDTH-1:0] MinResult; // byte results logic [WIDTH-1:0] ByteResult; @@ -52,6 +57,10 @@ module zbb #(parameter WIDTH=32) ( byteUnit #(WIDTH) bu(.A(A), .B(B), .ByteResult(ByteResult)); ext #(WIDTH) ext(.A(A), .B(B), .ExtResult(ExtResult)); + + assign MaxResult = (lt) ? B : A; + assign MinResult = (lt) ? A : B; + //can replace with structural mux by looking at bit 4 in rs2 field always_comb begin case (ZBBSelect) @@ -59,6 +68,8 @@ module zbb #(parameter WIDTH=32) ( 3'b000: ZBBResult = CntResult; // count 3'b100: ZBBResult = ExtResult; // sign/zero extend 3'b011: ZBBResult = ByteResult; // byte instructions + 3'b110: ZBBResult = MinResult; // min, minu + 3'b101: ZBBResult = MaxResult; // max, maxu /*15'b0010100_101_00111: ZBBResult = OrcBResult; 15'b0110100_101_11000: ZBBResult = Rev8Result; 15'b0110101_101_11000: ZBBResult = Rev8Result; diff --git a/src/ieu/controller.sv b/src/ieu/controller.sv index 74d0e4f1..d6e0c191 100644 --- a/src/ieu/controller.sv +++ b/src/ieu/controller.sv @@ -108,6 +108,7 @@ module controller( 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 maxE, maxuE, minE, minuE; // Indicates if is one of these instructions in Execute Stage logic BranchTakenE; // Branch is taken logic eqE, ltE; // Comparator outputs logic unused; @@ -216,10 +217,19 @@ module controller( assign andnD = (ALUSelectD == 3'b111 & BSelectD[2]); assign ornD = (ALUSelectD == 3'b110 & BSelectD[2]); assign xnorD = (ALUSelectD == 3'b100 & BSelectD[2]); + // we only need these signals if we want to calculate a signedD flag in decode stage to pass to the comparator. + assign maxE = (Funct3E[1:0] == 2'b10 & BSelectE[2]); + assign maxuE = (Funct3E[1:0] == 2'b11 & BSelectE[2]); + assign minE = (Funct3E[1:0] == 2'b00 & BSelectE[2]); + assign minuE = (Funct3E[1:0] == 2'b01 & BSelectE[2]); end else begin assign andnD = 0; assign ornD = 0; assign xnorD = 0; + assign maxE = 0; + assign maxuE = 0; + assign minE = 0; + assign minuE = 0; end // ALU Decoding is lazy, only using func7[5] to distinguish add/sub and srl/sra @@ -263,7 +273,8 @@ module controller( // Branch Logic // The comparator handles both signed and unsigned branches using BranchSignedE // Hence, only eq and lt flags are needed - assign BranchSignedE = ~(Funct3E[2:1] == 2'b11); + assign BranchSignedE = (~(Funct3E[2:1] == 2'b11) & ~BSelectE[2]) | (`ZBB_SUPPORTED & (maxE | minE)) ; + //assign BranchSignedE = ~(Funct3E[2:1] == 2'b11); assign {eqE, ltE} = FlagsE; mux2 #(1) branchflagmux(eqE, ltE, Funct3E[2], BranchFlagE); assign BranchTakenE = BranchFlagE ^ Funct3E[0]; diff --git a/src/ieu/datapath.sv b/src/ieu/datapath.sv index ff25309f..d0f6f039 100644 --- a/src/ieu/datapath.sv +++ b/src/ieu/datapath.sv @@ -83,7 +83,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, ALUSelectE, BSelectE, ZBBSelectE, Funct3E, ALUResultE, IEUAdrE); + alu #(`XLEN) alu(SrcAE, SrcBE, ALUControlE, ALUSelectE, BSelectE, ZBBSelectE, Funct3E, FlagsE, ALUResultE, IEUAdrE); mux2 #(`XLEN) altresultmux(ImmExtE, PCLinkE, JumpE, AltResultE); mux2 #(`XLEN) ieuresultmux(ALUResultE, AltResultE, ALUResultSrcE, IEUResultE);