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

Subversion Repositories aemb

[/] [aemb/] [trunk/] [rtl/] [verilog/] [aeMB2_ctrl.v] - Diff between revs 160 and 191

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 160 Rev 191
/* $Id: aeMB2_ctrl.v,v 1.7 2008-05-11 13:50:50 sybreon Exp $
/* $Id: aeMB2_ctrl.v,v 1.7 2008-05-11 13:50:50 sybreon Exp $
**
**
** AEMB2 EDK 6.2 COMPATIBLE CORE
** AEMB2 EDK 6.2 COMPATIBLE CORE
** Copyright (C) 2004-2008 Shawn Tan <shawn.tan@aeste.net>
** Copyright (C) 2004-2008 Shawn Tan <shawn.tan@aeste.net>
**
**
** This file is part of AEMB.
** This file is part of AEMB.
**
**
** AEMB is free software: you can redistribute it and/or modify it
** AEMB is free software: you can redistribute it and/or modify it
** under the terms of the GNU Lesser General Public License as
** under the terms of the GNU Lesser General Public License as
** published by the Free Software Foundation, either version 3 of the
** published by the Free Software Foundation, either version 3 of the
** License, or (at your option) any later version.
** License, or (at your option) any later version.
**
**
** AEMB is distributed in the hope that it will be useful, but WITHOUT
** AEMB is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
** or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General
** or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General
** Public License for more details.
** Public License for more details.
**
**
** You should have received a copy of the GNU Lesser General Public
** You should have received a copy of the GNU Lesser General Public
** License along with AEMB. If not, see <http:**www.gnu.org/licenses/>.
** License along with AEMB. If not, see <http:**www.gnu.org/licenses/>.
*/
*/
/**
/**
 * Instruction Decode & Control
 * Instruction Decode & Control
 * @file aeMB2_ctrl.v
 * @file aeMB2_ctrl.v
 
 
 * This is the data decoder that will control the command signals and
 * This is the data decoder that will control the command signals and
   operand fetch.
   operand fetch.
 
 
 */
 */
 
 
module aeMB2_ctrl (/*AUTOARG*/
module aeMB2_ctrl (/*AUTOARG*/
   // Outputs
   // Outputs
   opa_of, opb_of, opd_of, opc_of, ra_of, rd_of, imm_of, rd_ex,
   opa_of, opb_of, opd_of, opc_of, ra_of, rd_of, imm_of, rd_ex,
   mux_of, mux_ex, hzd_bpc, hzd_fwd,
   mux_of, mux_ex, hzd_bpc, hzd_fwd,
   // Inputs
   // Inputs
   opa_if, opb_if, opd_if, brk_if, bra_ex, rpc_if, alu_ex, ich_dat,
   opa_if, opb_if, opd_if, brk_if, bra_ex, rpc_if, alu_ex, ich_dat,
   gclk, grst, dena, iena, gpha
   gclk, grst, dena, iena, gpha
   );
   );
   parameter AEMB_HTX = 1;
   parameter AEMB_HTX = 1;
 
 
   // EX CONTROL
   // EX CONTROL
   output [31:0] opa_of;
   output [31:0] opa_of;
   output [31:0] opb_of;
   output [31:0] opb_of;
   output [31:0] opd_of;
   output [31:0] opd_of;
   output [5:0]  opc_of;
   output [5:0]  opc_of;
   output [4:0]  ra_of,
   output [4:0]  ra_of,
                 //rb_of,
                 //rb_of,
                 rd_of;
                 rd_of;
   output [15:0] imm_of;
   output [15:0] imm_of;
   output [4:0]   rd_ex;
   output [4:0]   rd_ex;
 
 
   // REGS
   // REGS
   input [31:0]  opa_if,
   input [31:0]  opa_if,
                 opb_if,
                 opb_if,
                 opd_if;
                 opd_if;
 
 
   // WB CONTROL
   // WB CONTROL
   output [2:0]  mux_of,
   output [2:0]  mux_of,
                 mux_ex;
                 mux_ex;
 
 
   // INTERNAL
   // INTERNAL
   input [1:0]    brk_if;
   input [1:0]    brk_if;
   input [1:0]    bra_ex;
   input [1:0]    bra_ex;
   input [31:2]  rpc_if;
   input [31:2]  rpc_if;
   input [31:0]  alu_ex;
   input [31:0]  alu_ex;
   input [31:0]  ich_dat;
   input [31:0]  ich_dat;
 
 
   output        hzd_bpc;
   output        hzd_bpc;
   output        hzd_fwd;
   output        hzd_fwd;
 
 
   // SYSTEM
   // SYSTEM
   input         gclk,
   input         gclk,
                 grst,
                 grst,
                 dena,
                 dena,
                 iena,
                 iena,
                 gpha;
                 gpha;
 
 
   /*AUTOREG*/
   /*AUTOREG*/
   // Beginning of automatic regs (for this module's undeclared outputs)
   // Beginning of automatic regs (for this module's undeclared outputs)
   reg [15:0]            imm_of;
   reg [15:0]            imm_of;
   reg [2:0]             mux_ex;
   reg [2:0]             mux_ex;
   reg [2:0]             mux_of;
   reg [2:0]             mux_of;
   reg [31:0]            opa_of;
   reg [31:0]            opa_of;
   reg [31:0]            opb_of;
   reg [31:0]            opb_of;
   reg [5:0]             opc_of;
   reg [5:0]             opc_of;
   reg [31:0]            opd_of;
   reg [31:0]            opd_of;
   reg [4:0]             ra_of;
   reg [4:0]             ra_of;
   reg [4:0]             rd_ex;
   reg [4:0]             rd_ex;
   reg [4:0]             rd_of;
   reg [4:0]             rd_of;
   // End of automatics
   // End of automatics
 
 
   wire                 fINT;
   wire                 fINT;
   //wire [31:0]                wXCEOP = 32'hBA2D0020; // Vector 0x20
   //wire [31:0]                wXCEOP = 32'hBA2D0020; // Vector 0x20
   wire [31:0]           wINTOP = 32'hB9CD0010; // Vector 0x10   
   wire [31:0]           wINTOP = 32'hB9CD0010; // Vector 0x10   
   //wire [31:0]                wNOPOP = 32'h88000000; // branch-no-delay/stall
   //wire [31:0]                wNOPOP = 32'h88000000; // branch-no-delay/stall
 
 
   wire [1:0]            mux_opa, mux_opb, mux_opd;
   wire [1:0]            mux_opa, mux_opb, mux_opd;
 
 
   // translate signals
   // translate signals
   wire [4:0]            wRD, wRA, wRB;
   wire [4:0]            wRD, wRA, wRB;
   wire [5:0]            wOPC;
   wire [5:0]            wOPC;
   wire [15:0]           wIMM;
   wire [15:0]           wIMM;
   wire [31:0]           imm_if;
   wire [31:0]           imm_if;
 
 
   assign               {wOPC, wRD, wRA, wIMM} = (fINT) ? wINTOP : ich_dat;
   assign               {wOPC, wRD, wRA, wIMM} = (fINT) ? wINTOP : ich_dat;
   assign               wRB = wIMM[15:11];
   assign               wRB = wIMM[15:11];
 
 
   // decode main opgroups
   // decode main opgroups
 
 
   //wire               fSFT = (wOPC == 6'o44);
   //wire               fSFT = (wOPC == 6'o44);
   //wire               fLOG = ({wOPC[5:4],wOPC[2]} == 3'o4);      
   //wire               fLOG = ({wOPC[5:4],wOPC[2]} == 3'o4);      
   wire                 fMUL = (wOPC == 6'o20) | (wOPC == 6'o30);
   wire                 fMUL = (wOPC == 6'o20) | (wOPC == 6'o30);
   wire                 fBSF = (wOPC == 6'o21) | (wOPC == 6'o31);
   wire                 fBSF = (wOPC == 6'o21) | (wOPC == 6'o31);
   //wire               fDIV = (wOPC == 6'o22);   
   //wire               fDIV = (wOPC == 6'o22);   
   wire                 fRTD = (wOPC == 6'o55);
   wire                 fRTD = (wOPC == 6'o55);
   wire                 fBCC = (wOPC == 6'o47) | (wOPC == 6'o57);
   wire                 fBCC = (wOPC == 6'o47) | (wOPC == 6'o57);
   wire                 fBRU = (wOPC == 6'o46) | (wOPC == 6'o56);
   wire                 fBRU = (wOPC == 6'o46) | (wOPC == 6'o56);
   //wire               fBRA = fBRU & wRA[3];      
   //wire               fBRA = fBRU & wRA[3];      
   wire                 fIMM = (wOPC == 6'o54);
   wire                 fIMM = (wOPC == 6'o54);
   wire                 fMOV = (wOPC == 6'o45);
   wire                 fMOV = (wOPC == 6'o45);
   wire                 fLOD = ({wOPC[5:4],wOPC[2]} == 3'o6);
   wire                 fLOD = ({wOPC[5:4],wOPC[2]} == 3'o6);
   wire                 fSTR = ({wOPC[5:4],wOPC[2]} == 3'o7);
   wire                 fSTR = ({wOPC[5:4],wOPC[2]} == 3'o7);
   //wire               fLDST = (wOPC[5:4] == 2'o3);   
   //wire               fLDST = (wOPC[5:4] == 2'o3);   
   //wire               fPUT = (wOPC == 6'o33) & wRB[4];
   //wire               fPUT = (wOPC == 6'o33) & wRB[4];
   wire                 fGET = (wOPC == 6'o33) & !wRB[4];
   wire                 fGET = (wOPC == 6'o33) & !wRB[4];
 
 
 
 
   // control signals
   // control signals
   localparam [2:0]      MUX_SFR = 3'o7,
   localparam [2:0]      MUX_SFR = 3'o7,
                        MUX_BSF = 3'o6,
                        MUX_BSF = 3'o6,
                        MUX_MUL = 3'o5,
                        MUX_MUL = 3'o5,
                        MUX_MEM = 3'o4,
                        MUX_MEM = 3'o4,
 
 
                        MUX_RPC = 3'o2,
                        MUX_RPC = 3'o2,
                        MUX_ALU = 3'o1,
                        MUX_ALU = 3'o1,
                        MUX_NOP = 3'o0;
                        MUX_NOP = 3'o0;
 
 
   always @(posedge gclk)
   always @(posedge gclk)
     if (grst) begin
     if (grst) begin
        /*AUTORESET*/
        /*AUTORESET*/
        // Beginning of autoreset for uninitialized flops
        // Beginning of autoreset for uninitialized flops
        imm_of <= 16'h0;
        imm_of <= 16'h0;
        mux_of <= 3'h0;
        mux_of <= 3'h0;
        opc_of <= 6'h0;
        opc_of <= 6'h0;
        ra_of <= 5'h0;
        ra_of <= 5'h0;
        rd_of <= 5'h0;
        rd_of <= 5'h0;
        // End of automatics
        // End of automatics
     end else if (dena) begin
     end else if (dena) begin
 
 
        mux_of <= #1
        mux_of <= #1
                  (hzd_bpc | hzd_fwd | fSTR | fRTD | fBCC) ? MUX_NOP :
                  (hzd_bpc | hzd_fwd | fSTR | fRTD | fBCC) ? MUX_NOP :
                  (fLOD | fGET) ? MUX_MEM :
                  (fLOD | fGET) ? MUX_MEM :
                  (fMOV) ? MUX_SFR :
                  (fMOV) ? MUX_SFR :
                  (fMUL) ? MUX_MUL :
                  (fMUL) ? MUX_MUL :
                  (fBSF) ? MUX_BSF :
                  (fBSF) ? MUX_BSF :
                  (fBRU) ? MUX_RPC :
                  (fBRU) ? MUX_RPC :
                  MUX_ALU;
                  MUX_ALU;
 
 
        opc_of <= #1
        opc_of <= #1
                  (hzd_bpc | hzd_fwd) ? 6'o42 : // XOR (SKIP) 
                  (hzd_bpc | hzd_fwd) ? 6'o42 : // XOR (SKIP) 
                  wOPC;
                  wOPC;
 
 
        rd_of <= #1 wRD;
        rd_of <= #1 wRD;
        ra_of <= #1 wRA;
        ra_of <= #1 wRA;
        imm_of <= #1 wIMM;
        imm_of <= #1 wIMM;
 
 
     end // if (dena)
     end // if (dena)
 
 
   // immediate implementation
   // immediate implementation
   reg [15:0]            rIMM0, rIMM1;
   reg [15:0]            rIMM0, rIMM1;
   reg                  rFIM0, rFIM1;
   reg                  rFIM0, rFIM1;
   //wire               wFIMH = (gpha & AEMB_HTX[0]) ? rFIM1 : rFIM0;   
   //wire               wFIMH = (gpha & AEMB_HTX[0]) ? rFIM1 : rFIM0;   
   //wire [15:0]                wIMMH = (gpha & AEMB_HTX[0]) ? rIMM1 : rIMM0;
   //wire [15:0]                wIMMH = (gpha & AEMB_HTX[0]) ? rIMM1 : rIMM0;
 
 
   assign               imm_if[15:0] = wIMM;
   assign               imm_if[15:0] = wIMM;
   assign               imm_if[31:16] = (rFIM1) ? rIMM1 :
   assign               imm_if[31:16] = (rFIM1) ? rIMM1 :
                                        {(16){wIMM[15]}};
                                        {(16){wIMM[15]}};
 
 
   // BARREL IMM
   // BARREL IMM
   always @(posedge gclk)
   always @(posedge gclk)
     if (grst) begin
     if (grst) begin
        /*AUTORESET*/
        /*AUTORESET*/
        // Beginning of autoreset for uninitialized flops
        // Beginning of autoreset for uninitialized flops
        rFIM0 <= 1'h0;
        rFIM0 <= 1'h0;
        rFIM1 <= 1'h0;
        rFIM1 <= 1'h0;
        rIMM0 <= 16'h0;
        rIMM0 <= 16'h0;
        rIMM1 <= 16'h0;
        rIMM1 <= 16'h0;
        // End of automatics
        // End of automatics
     end else if (dena) begin
     end else if (dena) begin
        rFIM1 <= #1 rFIM0;
        rFIM1 <= #1 rFIM0;
        rFIM0 <= #1 fIMM & !hzd_bpc;
        rFIM0 <= #1 fIMM & !hzd_bpc;
 
 
        rIMM1 <= #1 rIMM0;
        rIMM1 <= #1 rIMM0;
        rIMM0 <= #1 wIMM;
        rIMM0 <= #1 wIMM;
     end
     end
 
 
   assign fINT = brk_if[0] & gpha & !rFIM1;
   assign fINT = brk_if[0] & gpha & !rFIM1;
 
 
   // operand latch   
   // operand latch   
   reg                  wrb_ex;
   reg                  wrb_ex;
   reg                  fwd_ex;
   reg                  fwd_ex;
   reg [2:0]             mux_mx;
   reg [2:0]             mux_mx;
 
 
   wire                 opb_fwd, opa_fwd, opd_fwd;
   wire                 opb_fwd, opa_fwd, opd_fwd;
 
 
   assign               mux_opb = {wOPC[3], opb_fwd};
   assign               mux_opb = {wOPC[3], opb_fwd};
   assign               opb_fwd = ((wRB ^ rd_ex) == 5'd0) & // RB forwarding needed
   assign               opb_fwd = ((wRB ^ rd_ex) == 5'd0) & // RB forwarding needed
                                  fwd_ex & wrb_ex;
                                  fwd_ex & wrb_ex;
 
 
   assign               mux_opa = {(fBRU|fBCC), opa_fwd};
   assign               mux_opa = {(fBRU|fBCC), opa_fwd};
   assign               opa_fwd = ((wRA ^ rd_ex) == 5'd0) & // RA forwarding needed
   assign               opa_fwd = ((wRA ^ rd_ex) == 5'd0) & // RA forwarding needed
                                  fwd_ex & wrb_ex;
                                  fwd_ex & wrb_ex;
 
 
   assign               mux_opd = {fBCC, opd_fwd};
   assign               mux_opd = {fBCC, opd_fwd};
   assign               opd_fwd = (( ((wRA ^ rd_ex) == 5'd0) & fBCC) | // RA forwarding
   assign               opd_fwd = (( ((wRA ^ rd_ex) == 5'd0) & fBCC) | // RA forwarding
                                   ( ((wRD ^ rd_ex) == 5'd0) & fSTR)) & // RD forwarding
                                   ( ((wRD ^ rd_ex) == 5'd0) & fSTR)) & // RD forwarding
                                  fwd_ex & wrb_ex;
                                  fwd_ex & wrb_ex;
 
 
   always @(posedge gclk)
   always @(posedge gclk)
     if (grst) begin
     if (grst) begin
        /*AUTORESET*/
        /*AUTORESET*/
        // Beginning of autoreset for uninitialized flops
        // Beginning of autoreset for uninitialized flops
        fwd_ex <= 1'h0;
        fwd_ex <= 1'h0;
        mux_ex <= 3'h0;
        mux_ex <= 3'h0;
        mux_mx <= 3'h0;
        mux_mx <= 3'h0;
        rd_ex <= 5'h0;
        rd_ex <= 5'h0;
        wrb_ex <= 1'h0;
        wrb_ex <= 1'h0;
        // End of automatics
        // End of automatics
     end else if (dena) begin
     end else if (dena) begin
        wrb_ex <= #1 |rd_of & |mux_of; // FIXME: check mux      
        wrb_ex <= #1 |rd_of & |mux_of; // FIXME: check mux      
        fwd_ex <= #1 |mux_of; // FIXME: check mux
        fwd_ex <= #1 |mux_of; // FIXME: check mux
 
 
        mux_mx <= #1 mux_ex;
        mux_mx <= #1 mux_ex;
        mux_ex <= #1 mux_of;
        mux_ex <= #1 mux_of;
        rd_ex <= #1 rd_of;
        rd_ex <= #1 rd_of;
     end
     end
 
 
   always @(posedge gclk)
   always @(posedge gclk)
     if (grst) begin
     if (grst) begin
        /*AUTORESET*/
        /*AUTORESET*/
        // Beginning of autoreset for uninitialized flops
        // Beginning of autoreset for uninitialized flops
        opa_of <= 32'h0;
        opa_of <= 32'h0;
        opb_of <= 32'h0;
        opb_of <= 32'h0;
        opd_of <= 32'h0;
        opd_of <= 32'h0;
        // End of automatics
        // End of automatics
 
 
     end else if (dena) begin
     end else if (dena) begin
 
 
        case (mux_opd)
        case (mux_opd)
          2'o2: opd_of <= #1 opa_if; // BCC
          2'o2: opd_of <= #1 opa_if; // BCC
          2'o1: opd_of <= #1 alu_ex; // FWD
          2'o1: opd_of <= #1 alu_ex; // FWD
          2'o0: opd_of <= #1 opd_if; // SXX
          2'o0: opd_of <= #1 opd_if; // SXX
          2'o3: opd_of <= #1 alu_ex; // FWD               
          2'o3: opd_of <= #1 alu_ex; // FWD               
        endcase // case (mux_opd)
        endcase // case (mux_opd)
 
 
        case (mux_opb)
        case (mux_opb)
          2'o0: opb_of <= #1 opb_if;
          2'o0: opb_of <= #1 opb_if;
          2'o1: opb_of <= #1 alu_ex;
          2'o1: opb_of <= #1 alu_ex;
          2'o2: opb_of <= #1 imm_if;
          2'o2: opb_of <= #1 imm_if;
          2'o3: opb_of <= #1 imm_if;
          2'o3: opb_of <= #1 imm_if;
        endcase // case (mux_opb)
        endcase // case (mux_opb)
 
 
        case (mux_opa)
        case (mux_opa)
          2'o0: opa_of <= #1 opa_if;
          2'o0: opa_of <= #1 opa_if;
          2'o1: opa_of <= #1 alu_ex;
          2'o1: opa_of <= #1 alu_ex;
          2'o2: opa_of <= #1 {rpc_if, 2'o0};
          2'o2: opa_of <= #1 {rpc_if, 2'o0};
          2'o3: opa_of <= #1 {rpc_if, 2'o0};
          2'o3: opa_of <= #1 {rpc_if, 2'o0};
        endcase // case (mux_opa)
        endcase // case (mux_opa)
 
 
     end // if (dena)
     end // if (dena)
 
 
   // Hazard Detection
   // Hazard Detection
   //wire               wFMUL = (mux_ex == MUX_MUL);
   //wire               wFMUL = (mux_ex == MUX_MUL);
   //wire               wFBSF = (mux_ex == MUX_BSF);
   //wire               wFBSF = (mux_ex == MUX_BSF);
   //wire               wFMEM = (mux_ex == MUX_MEM);
   //wire               wFMEM = (mux_ex == MUX_MEM);
   //wire               wFMOV = (mux_ex == MUX_SFR);   
   //wire               wFMOV = (mux_ex == MUX_SFR);   
 
 
   assign               hzd_fwd = (opd_fwd | opa_fwd | opb_fwd) & mux_ex[2];
   assign               hzd_fwd = (opd_fwd | opa_fwd | opb_fwd) & mux_ex[2];
                                  //(wFMUL | wFBSF | wFMEM | wFMOV);
                                  //(wFMUL | wFBSF | wFMEM | wFMOV);
   assign               hzd_bpc = (bra_ex[1] & !bra_ex[0]);
   assign               hzd_bpc = (bra_ex[1] & !bra_ex[0]);
 
 
endmodule // aeMB2_ctrl
endmodule // aeMB2_ctrl
 
 
/*
/*
 $Log: not supported by cvs2svn $
 $Log: not supported by cvs2svn $
 Revision 1.6  2008/05/01 08:32:58  sybreon
 Revision 1.6  2008/05/01 08:32:58  sybreon
 Added interrupt capability.
 Added interrupt capability.
 
 
 Revision 1.5  2008/04/28 08:15:25  sybreon
 Revision 1.5  2008/04/28 08:15:25  sybreon
 Optimisations.
 Optimisations.
 
 
 Revision 1.4  2008/04/26 17:57:43  sybreon
 Revision 1.4  2008/04/26 17:57:43  sybreon
 Minor performance improvements.
 Minor performance improvements.
 
 
 Revision 1.3  2008/04/26 01:09:05  sybreon
 Revision 1.3  2008/04/26 01:09:05  sybreon
 Passes basic tests. Minor documentation changes to make it compatible with iverilog pre-processor.
 Passes basic tests. Minor documentation changes to make it compatible with iverilog pre-processor.
 
 
 Revision 1.2  2008/04/20 16:34:32  sybreon
 Revision 1.2  2008/04/20 16:34:32  sybreon
 Basic version with some features left out.
 Basic version with some features left out.
 
 
 Revision 1.1  2008/04/18 00:21:52  sybreon
 Revision 1.1  2008/04/18 00:21:52  sybreon
 Initial import.
 Initial import.
 
 

powered by: WebSVN 2.1.0

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