OpenCores
URL https://opencores.org/ocsvn/aemb/aemb/trunk

Subversion Repositories aemb

[/] [aemb/] [branches/] [DEV_SYBREON/] [rtl/] [verilog/] [aeMB2_bpcu.v] - Diff between revs 78 and 80

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 78 Rev 80
Line 1... Line 1...
/* $Id: aeMB2_bpcu.v,v 1.1 2007-12-11 00:43:17 sybreon Exp $
/* $Id: aeMB2_bpcu.v,v 1.2 2007-12-12 19:16:59 sybreon Exp $
**
**
** AEMB2 BRANCH/PROGRAMME COUNTER
** AEMB2 BRANCH/PROGRAMME COUNTER
**
**
** Copyright (C) 2004-2007 Shawn Tan Ser Ngiap <shawn.tan@aeste.net>
** Copyright (C) 2004-2007 Shawn Tan Ser Ngiap <shawn.tan@aeste.net>
**
**
Line 20... Line 20...
** License along with AEMB. If not, see <http://www.gnu.org/licenses/>.
** License along with AEMB. If not, see <http://www.gnu.org/licenses/>.
*/
*/
 
 
module aeMB2_bpcu (/*AUTOARG*/
module aeMB2_bpcu (/*AUTOARG*/
   // Outputs
   // Outputs
   iwb_adr_o, rPC_OF, rPC_MA, rPC_IF, rIMM_IF, rALT_IF, rOPC_IF,
   iwb_adr_o, rPC_MA, rPC_IF, rIMM_IF, rALT_IF, rOPC_IF, rRD_IF,
   rRD_IF, rRA_IF, rRB_IF, rBRA,
   rRA_IF, rRB_IF, rBRA,
   // Inputs
   // Inputs
   iwb_dat_i, iwb_ack_i, rOPX_OF, rOPC_OF, rRA_OF, rRD_OF, rRES_EX,
   iwb_dat_i, iwb_ack_i, rOPX_OF, rOPC_OF, rRA_OF, rRD_OF, rRES_EX,
   rRD_EX, rOPD_EX, clk_i, rst_i, ena_i, pha_i
   rRD_EX, rOPD_EX, rMSR_TXE, clk_i, rst_i, ena_i, pha_i
   );
   );
   parameter IWB = 32;
   parameter IWB = 32;
   parameter TXE = 1;
   parameter TXE = 1;
   parameter LUT = 1;
 
 
 
   // IWB
   // IWB
   output [IWB-1:2] iwb_adr_o;
   output [IWB-1:2] iwb_adr_o;
   input [31:0]     iwb_dat_i;
   input [31:0]     iwb_dat_i;
   input            iwb_ack_i;
   input            iwb_ack_i;
 
 
   // PIPELINE
   // PIPELINE
   output [31:2]    rPC_OF,
   output [31:2]    //rPC_OF,
                    rPC_MA,
                    rPC_MA,
                    rPC_IF;
                    rPC_IF;
   output [15:0]    rIMM_IF;
   output [15:0]    rIMM_IF;
   output [10:0]    rALT_IF;
   output [10:0]    rALT_IF;
   output [5:0]     rOPC_IF;
   output [5:0]     rOPC_IF;
   output [4:0]     rRD_IF,
   output [4:0]     rRD_IF,
                    rRA_IF,
                    rRA_IF,
                    rRB_IF;
                    rRB_IF;
 
 
   // BRANCH DETECTION
   // BRANCH DETECTION
   output [1:0]     rBRA; ///< {branch, delay}
   output [1:0]     rBRA; // {branch, delay}
   input [31:0]     rOPX_OF; // BCC op test   
   input [31:0]     rOPX_OF; // BCC op test   
   input [5:0]       rOPC_OF;
   input [5:0]       rOPC_OF;
   input [4:0]       rRA_OF,
   input [4:0]       rRA_OF,
                    rRD_OF;
                    rRD_OF;
   input [31:0]     rRES_EX;
   input [31:0]     rRES_EX;
Line 59... Line 58...
   // MEMORY HAZARD DETECTION
   // MEMORY HAZARD DETECTION
   input [4:0]       rRD_EX; ///< RD
   input [4:0]       rRD_EX; ///< RD
   input [2:0]       rOPD_EX; ///< data register source (ALU, MEM/FSL, PC)
   input [2:0]       rOPD_EX; ///< data register source (ALU, MEM/FSL, PC)
 
 
   // SYSTEM
   // SYSTEM
 
   input            rMSR_TXE;
   input            clk_i,
   input            clk_i,
                    rst_i,
                    rst_i,
                    ena_i,
                    ena_i,
                    pha_i;
                    pha_i;
 
 
Line 75... Line 75...
   reg [31:2]           rPC_MA;
   reg [31:2]           rPC_MA;
   reg [4:0]             rRA_IF;
   reg [4:0]             rRA_IF;
   reg [4:0]             rRD_IF;
   reg [4:0]             rRD_IF;
   // End of automatics
   // End of automatics
 
 
 
 
   /* Partial decoding */
   /* Partial decoding */
   wire [5:0]            rOPC = rOPC_IF;
   wire [5:0]            rOPC = rOPC_IF;
   wire [4:0]            rRA = rRA_IF;
   wire [4:0]            rRA = rRA_IF;
   wire [4:0]            rRB = rRB_IF;
   wire [4:0]            rRB = rRB_IF;
   wire                 fSFT = (rOPC == 6'o44);
   wire                 fSFT = (rOPC == 6'o44);
Line 101... Line 100...
 
 
   /* Select the PC. */
   /* Select the PC. */
 
 
   reg [31:2]           rPC, // PC
   reg [31:2]           rPC, // PC
                        rPC0, rPC1, // register based 
                        rPC0, rPC1, // register based 
                        rPCL[0:TXE]; // LUT based
                        rPCL[0:1]; // LUT based
 
 
   wire [31:2]          wPCSEL = (pha_i) ? rPC0 : (TXE) ? rPC1 : 30'hX;
   wire [31:2]          wPCNXT = (pha_i) ? rPC0 : (TXE) ? rPC1 : 30'hX;
   wire [31:2]          wPCNXT = (LUT) ? rPCL[!pha_i] : wPCSEL;
 
   wire [31:2]          wPCINC = (rPC + 1);
   wire [31:2]          wPCINC = (rPC + 1);
 
 
   /* Check for RW data hazard */
   /* Check for RW data hazard */
   // TODO: Optimise
   // TODO: Optimise
 
 
Line 116... Line 114...
   wire                 fMULT = (rOPD_EX == 3'o3);
   wire                 fMULT = (rOPD_EX == 3'o3);
   wire                 fWRE = |rRD_EX;
   wire                 fWRE = |rRD_EX;
   wire                 fOPBHZD = (rRB_IF == rRD_EX) & (fLOAD | fMULT) & !fMOV & !rOPC_IF[3] & fWRE;
   wire                 fOPBHZD = (rRB_IF == rRD_EX) & (fLOAD | fMULT) & !fMOV & !rOPC_IF[3] & fWRE;
   wire                 fOPAHZD = (rRA_IF == rRD_EX) & (fLOAD | fMULT) & !fBRU & fWRE;
   wire                 fOPAHZD = (rRA_IF == rRD_EX) & (fLOAD | fMULT) & !fBRU & fWRE;
   wire                 fOPDHZD = (rRD_IF == rRD_EX) & (fLOAD | fMULT) & fSTR & fWRE;
   wire                 fOPDHZD = (rRD_IF == rRD_EX) & (fLOAD | fMULT) & fSTR & fWRE;
   wire                 fHAZARD = fOPBHZD | fOPAHZD | fOPDHZD;
   wire                 fHZD = fOPBHZD | fOPAHZD | fOPDHZD;
 
 
 
   /*
 
    IWB PC OUTPUT
 
 
   /* Output the new PC for IWB */
    This is part of the address generation stage. It pre-selects the
 
    next PC to fetch depending on whether it's a branch, retry or
 
    normal. A retry happens during a special hazard */
 
 
   wire [1:0]            wIPCMX = {fHAZARD, rBRA[1]};
   wire [1:0]            wIPCMX = {fHZD, rBRA[1]};
   assign               iwb_adr_o = rPC[IWB-1:2];
   assign               iwb_adr_o = rPC[IWB-1:2];
 
 
   always @ (posedge clk_i)
   always @ (posedge clk_i)
     if (rst_i) begin
     if (rst_i) begin
        rPC <= {(30){1'b1}};
        rPC <= {(30){1'b1}};
Line 136... Line 139...
          2'o2 : rPC <= #1 rPC_IF[IWB-1:2]; // retry/stall
          2'o2 : rPC <= #1 rPC_IF[IWB-1:2]; // retry/stall
          default: rPC <= {(IWB-2){1'bX}}; // undefined
          default: rPC <= {(IWB-2){1'bX}}; // undefined
        endcase // case (wIPCMX)
        endcase // case (wIPCMX)
     end
     end
 
 
   /* Inbcrement the PC */
   /*
 
    PC INCREMENT
 
 
 
    This will store the next PC in a holding register until it is
 
    needed during the next AG stage. */
 
 
   always @(posedge clk_i)
   always @(posedge clk_i)
     if (rst_i) begin
     if (rst_i) begin
        /*AUTORESET*/
        /*AUTORESET*/
        // Beginning of autoreset for uninitialized flops
        // Beginning of autoreset for uninitialized flops
        rPC0 <= 30'h0;
        rPC0 <= 30'h0;
        rPC1 <= 30'h0;
        rPC1 <= 30'h0;
        // End of automatics
        // End of automatics
     end else if (ena_i) begin
     end else begin
        if (pha_i)
        if (pha_i & ena_i & rMSR_TXE) rPC1 <= #1 wPCINC;
          rPC1 <= #1 wPCINC;
        if (!pha_i & ena_i) rPC0 <= #1 wPCINC;
        else
 
          rPC0 <= #1 wPCINC;
 
     end
     end
 
 
   always @(posedge clk_i)
   /*
     if (ena_i | rst_i) begin
    INSTRUCTION LATCH
        rPCL[pha_i] <= #1 wPCINC;
 
     end
 
 
 
   /* Latch onto instruction word */
    This latches onto the instruction. It may not work correctly if
 
    there is a pipeline stall. */
 
 
   reg [31:2]           rPC_OF, rPC_EX;
   reg [31:2]           rPC_OF, rPC_EX;
   assign               {rRB_IF, rALT_IF} = rIMM_IF;
   assign               {rRB_IF, rALT_IF} = rIMM_IF;
 
 
   always @(posedge clk_i)
   always @(posedge clk_i)
Line 174... Line 179...
        // End of automatics
        // End of automatics
     end else if (ena_i & iwb_ack_i) begin
     end else if (ena_i & iwb_ack_i) begin
        {rOPC_IF, rRD_IF, rRA_IF, rIMM_IF} <= #1 iwb_dat_i;
        {rOPC_IF, rRD_IF, rRA_IF, rIMM_IF} <= #1 iwb_dat_i;
     end
     end
 
 
   always @(posedge clk_i)
   /*
     if (rst_i) begin
    PC PIPELINE
 
 
 
    This merely passes the PC down so that it is available during
 
    branch instructions. This may be modified to use a shift register.
 
    */
 
 
 
   always @(posedge clk_i) if (rst_i) begin
        /*AUTORESET*/
        /*AUTORESET*/
        // Beginning of autoreset for uninitialized flops
        // Beginning of autoreset for uninitialized flops
        rPC_EX <= 30'h0;
        rPC_EX <= 30'h0;
        rPC_IF <= 30'h0;
        rPC_IF <= 30'h0;
        rPC_MA <= 30'h0;
        rPC_MA <= 30'h0;
Line 189... Line 200...
        // TODO: Stuff inside a small LUT FIFO
        // TODO: Stuff inside a small LUT FIFO
        {rPC_MA, rPC_EX, rPC_OF, rPC_IF} <= #1 {rPC_EX, rPC_OF, rPC_IF, rPC};
        {rPC_MA, rPC_EX, rPC_OF, rPC_IF} <= #1 {rPC_EX, rPC_OF, rPC_IF, rPC};
     end
     end
 
 
   /* Branch Control */
   /* Branch Control */
 
 
   wire                 wRTD = (rOPC_OF == 6'o55);
   wire                 wRTD = (rOPC_OF == 6'o55);
   wire                 wBCC = (rOPC_OF == 6'o47) | (rOPC_OF == 6'o57);
   wire                 wBCC = (rOPC_OF == 6'o47) | (rOPC_OF == 6'o57);
   wire                 wBRU = (rOPC_OF == 6'o46) | (rOPC_OF == 6'o56);
   wire                 wBRU = (rOPC_OF == 6'o46) | (rOPC_OF == 6'o56);
 
 
   wire                 wBEQ = (rOPX_OF == 32'd0);
   wire                 wBEQ = (rOPX_OF == 32'd0);
Line 201... Line 213...
   wire                 wBLE = wBLT | wBEQ;
   wire                 wBLE = wBLT | wBEQ;
   wire                 wBGE = ~wBLT;
   wire                 wBGE = ~wBLT;
   wire                 wBGT = ~wBLE;
   wire                 wBGT = ~wBLE;
 
 
   reg                  xXCC;
   reg                  xXCC;
 
 
   always @(/*AUTOSENSE*/rRD_OF or wBEQ or wBGE or wBGT or wBLE
   always @(/*AUTOSENSE*/rRD_OF or wBEQ or wBGE or wBGT or wBLE
            or wBLT or wBNE)
            or wBLT or wBNE)
     case (rRD_OF[2:0])
     case (rRD_OF[2:0])
       3'o0: xXCC <= wBEQ;
       3'o0: xXCC <= wBEQ;
       3'o1: xXCC <= wBNE;
       3'o1: xXCC <= wBNE;
Line 224... Line 237...
     end else if(ena_i) begin
     end else if(ena_i) begin
        rBRA[1] <= #1 wRTD | wBRU | (wBCC & xXCC);
        rBRA[1] <= #1 wRTD | wBRU | (wBCC & xXCC);
        rBRA[0] <= #1 (wBRU & rRA_OF[4]) | (wBCC & rRD_OF[4]) | wRTD;
        rBRA[0] <= #1 (wBRU & rRA_OF[4]) | (wBCC & rRD_OF[4]) | wRTD;
     end
     end
 
 
   // synopsys translate_off
 
   integer r;
 
   initial begin
 
      for (r=0; r<TXE; r=r+1) begin
 
         rPCL[r] <= $random;
 
      end
 
   end
 
 
 
   // synopsys translate_on
 
 
 
endmodule // aeMB2_bpcu
endmodule // aeMB2_bpcu
 
 
/* $Log: not supported by cvs2svn $ */
 
 No newline at end of file
 No newline at end of file
 
/* $Log: not supported by cvs2svn $
 
/* Revision 1.1  2007/12/11 00:43:17  sybreon
 
/* initial import
 
/* */
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.