⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mult.v

📁 日立SH-2 CPU核的VERLOG源码
💻 V
📖 第 1 页 / 共 2 页
字号:
//======================================================
// Aquarius Project
//    SuperH-2 ISA Compatible RISC CPU
//------------------------------------------------------
// Module      : Multiplier Unit
//------------------------------------------------------
// File        : mult.v
// Library     : none
// Description : Multiplier Unit in CPU.
// Simulator   : Icarus Verilog (Cygwin)
// Synthesizer : Xilinx XST (Windows XP)
// Author      : Thorn Aitch
//------------------------------------------------------
// Revision Number : 1
// Date of Change  : 19th August 2002
// Creator         : Thorn Aitch
// Description     : Initial Design				  
//------------------------------------------------------
// Revision Number : 2
// Date of Change  : 30th April 2003
// Modifier        : Thorn Aitch
// Description     : Release Version 1.0
//======================================================
// Copyright (C) 2002-2003, Thorn Aitch
//
// Designs can be altered while keeping list of
// modifications "the same as in GNU" No money can
// be earned by selling the designs themselves, but
// anyone can get money by selling the implementation
// of the design, such as ICs based on some cores, 
// boards based on some schematics or Layouts, and
// even GUI interfaces to text mode drivers.
// "The same as GPL SW" Any update to the design
// should be documented and returned to the design. 
// Any derivative work based on the IP should be free
// under OpenIP License. Derivative work means any
// update, change or improvement on the design. 
// Any work based on the design can be either made
// free under OpenIP license or protected by any other
// license. Work based on the design means any work uses
// the OpenIP Licensed core as a building black without
// changing anything on it with any other blocks to
// produce larger design.  There is NO WARRANTY on the
// functionality or performance of the design on the
// real hardware implementation.
// On the other hand, the SuperH-2 ISA (Instruction Set
// Architecture) executed by Aquarius is rigidly
// the property of Renesas Corp. Then you have all 
// responsibility to judge if there are not any 
// infringements to Renesas's rights regarding your 
// Aquarius adoption into your design. 
// By adopting Aquarius, the user assumes all 
// responsibility for its use.
// This project may cause any damages around you, for 
// example, loss of properties, data, money, profits,
// life, or business etc. By adopting this source, 
// the user assumes all responsibility for its use.
//======================================================

`include "timescale.v"
`include "defines.v"

//****************************
// Multiply Unit Specification
//****************************
// This unit handles following multiplier related operations. 
//   DMULS.L
//   DMULU.L
//   MAC.L
//   MAC.W
//   MUL.L
//   MULS.W
//   MULU.W
// Physical multiplier size is 32bit*16bit->48bit.
// Then, 32x32 operations are executed in 2 cycles.

//*************************************************
// Module Definition
//*************************************************
module mult(
    // system signal
    CLK, RST,
    // command
    SLOT, MULCOM1, MULCOM2, MAC_S, WRMACH, WRMACL,
    // input data
    MACIN1, MACIN2,
    // output data
    MACH, MACL,
    // busy signal
    MAC_BUSY
    );

//-------------------
// Module I/O Signals
//-------------------
    input  CLK;           // clock
    input  RST;           // reset
    input  SLOT;          // cpu pipe slot
    input  MULCOM1;       // M1 latch command
    input  [7:0] MULCOM2; // M2 latch and mult engage command
                          // NOP      0 0000000 00
                          // DMULS.L  1 0111101 BD
                          // DMULU.L  1 0110101 B5
                          // MAC.L    1 0001111 8F
                          // MAC.W    1 1001111 CF
                          // MUL.L    1 0000111 87
                          // MULS.W   1 0101111 AF
                          // MULU.W   1 0101110 AE
    input  MAC_S;         // S-bit in SR
    input  WRMACH, WRMACL;// write MACH and MACL directly from data path
    input  [31:0] MACIN1; // input data 1
    input  [31:0] MACIN2; // input data 2
    output [31:0] MACH;   // output MACH
    output [31:0] MACL;   // output MACL
    output MAC_BUSY;      // busy signal (negate at final operation state)

//-----------------
// Internal Signals
//-----------------
    reg  [31:0] M1;   // input data1 latch
    reg  [31:0] M2;   // input data2 latch
    reg  [31:0] MB;   // input data 2 buffer to implement continuous MAC.L instruction
    reg  SELA;        // 0:A=M1, 1:A=MB
    reg  [31:0] A;    // A=M1 or A=MB (selected by SELA)
    reg  [31:0] B;    // B=M2
    reg  SHIFT;       // use lower(0)/upper(1) 16bit of B; use unshifted(0)/16bit-shifted(1) PM
    reg  SIGN;        // 0:unsigned, 1:signed (multipier operation)
    reg  SIZE;        // if 32*32 then 1, 16*16 then 0
    reg  [30:0] AH;   // lower 31bit of A
    reg  [15:0] BH;   // upper 16bit of B(0) or lower 16bit of B(1)
    reg  [46:0] ABH;  // output of Multiplier(31x16) (=A * BH) (calculated as unsigned)
    reg  [32:0] ABH2; // modified ABH
    reg  [31:0] P2;   // if signed32*32, ~SHIFT&A[31]&B[31:0], if signed16*16, ~SHIFT&A[31]&{B[15:0]:16'h0000}
    reg  [31:0] P3;   // if signed32*32, ~SHIFT&B[31]&A[31:0], if signed16*16, ~SHIFT&B[15]&A[31:0]
    reg  [31:0] P23;  // P2 + P3
    reg  [32:0] P23S; // if SIGN, ~P23, else P23
    reg  [47:0] PM;   // multiplier output (partial result) with sign
    reg  [63:0] C;    // one of the adder inputs
    reg  ZH;          // if final result is 16bit, adder input from MACH is forced to zero 
    reg  [1:0] ADD;   // 00:ADD, 10:ADDS48, 11:ADDS32 (adder functions regarding saturation)
    reg  [63:0] ADDRESULT;  // pure adder result
    reg  [63:0] ADDRESULT2; // saturated result
    reg  SAT;         // whether saturation has occured or not (to or 0001 to MACH)
    reg  LATMACH;     // latch signal of MACH by state machine
    reg  LATMACL;     // latch signal of MACL by state machine
    reg  [31:0] MACH; // actual MACH
    reg  [31:0] MACL; // actual MACL
    reg  MAC_BUSY;    // busy signal (negate at final operation state)
    reg  [3:0] STATE;     // control state
    reg  [3:0] NEXTSTATE; // next state
    reg  MAC_DISPATCH;    // mult can accept next new operation

//-------------------
// Main State Machine
//-------------------
    // state machine F/F
    always @(posedge CLK or posedge RST)
    begin
        if (RST == 1'b1)
            STATE <= `NOP;
        else if (MAC_DISPATCH & SLOT)
            begin                
                case(MULCOM2)
                    8'h00   : STATE <= `NOP;
                    8'hBD   : STATE <= `DMULSL;
                    8'hB5   : STATE <= `DMULUL;
                    8'h8F   : if (MAC_S == 1'b0)
                                  STATE <= `MACL0;
                              else
                                  STATE <= `MACLS;
                    8'hCF   : if (MAC_S == 1'b0)
                                  STATE <= `MACW;
                              else
                                  STATE <= `MACWS;
                    8'h87   : STATE <= `MULL;
                    8'hAF   : STATE <= `MULSW;
                    8'hAE   : STATE <= `MULUW;
                    default : STATE <= `NOP;
                endcase
            end
        else if (MAC_DISPATCH & ~SLOT)
            STATE <= `NOP;
        else if (~MAC_DISPATCH)
            STATE <= NEXTSTATE;
    end

//------------------
// State Transistion
//------------------
// NOP     : A=M1, BH=LowerB, unsign MULT, C=PM,                > NOP
//
// DMULSL  : A=M1, BH=LowerB, signed MULT, C=PM,       MAC<=ADD > DMULSL2
// DMULSL2 : A=M1, BH=upperB, signed MULT, C=(PM<<16), MAC<=ADD > NOP
//
// DMULUL  : A=M1, BH=LowerB, unsign MULT, C=PM,       MAC<=ADD > DMULUL2
// DMULUL2 : A=M1, BH=upperB, unsign MULT, C=(PM<<16), MAC<=ADD > NOP
//
// MACL0   : A=MB, BH=LowerB, signed MULT, C=PM,       MAC<=ADD > MACL2
// MACL2   : A=MB, BH=upperB, signed MULT, C=(PM<<16), MAC<=ADD > NOP

// MACLS   : A=MB, BH=LowerB, signed MULT, C=PM,       MAC<=ADDS48 > MACL2
// MACLS2  : A=MB, BH=upperB, signed MULT, C=(PM<<16), MAC<=ADDS48 > NOP

// MACW    : A=M1, BH=LowerB, signed MULT, C=PM,       MAC<=ADD > NOP

// MACWS   : A=M1, BH=LowerB, signed MULT, C=PM,       MACL<=ADDS32 > NOP
//                                                               if saturate, MACH|=0001

// MULL    : A=M1, BH=LowerB, signed MULT, C=PM,       MACL<=ADD > MULL2
// MULL2   : A=M1, BH=upperB, signed MULT, C=(PM<<16), MACL<=ADD > NOP

// MULSW   : A=M1, BH=LowerB, signed MULT, C=PM,       MACL<=ADD > NOP

// MULUW   : A=M1, BH=LowerB, unsign MULT, C=PM,       MACL<=ADD > NOP

    always @(STATE or SLOT or MULCOM2 or MAC_S)
    begin 
        case (STATE)
            `NOP    :begin
                      {SELA,SHIFT,SIGN,SIZE,ADD,LATMACH,LATMACL,ZH}<=9'b0_000_00_000;
                      MAC_BUSY <= 1'b0;
                      MAC_DISPATCH <= 1'b1;
                      NEXTSTATE <= `NOP;
                     end
            `DMULSL :begin
                      {SELA,SHIFT,SIGN,SIZE,ADD,LATMACH,LATMACL,ZH}<=9'b0_011_00_110;
                      MAC_BUSY <= 1'b1;
                      MAC_DISPATCH <= 1'b0;
                      NEXTSTATE <= `DMULSL2;
                     end
            `DMULSL2:begin
                      {SELA,SHIFT,SIGN,SIZE,ADD,LATMACH,LATMACL,ZH}<=9'b0_111_00_110;
                      MAC_BUSY <= 1'b0;
                      MAC_DISPATCH <= 1'b1;
                      NEXTSTATE <= `NOP;
                     end
            `DMULUL :begin
                      {SELA,SHIFT,SIGN,SIZE,ADD,LATMACH,LATMACL,ZH}<=9'b0_001_00_110;
                      MAC_BUSY <= 1'b1;
                      MAC_DISPATCH <= 1'b0;
                      NEXTSTATE <= `DMULUL2;
                     end
            `DMULUL2:begin
                      {SELA,SHIFT,SIGN,SIZE,ADD,LATMACH,LATMACL,ZH}<=9'b0_101_00_110;
                      MAC_BUSY <= 1'b0;    
                      MAC_DISPATCH <= 1'b1;
                      NEXTSTATE <= `NOP;
                     end
            `MACL0  :begin
                      {SELA,SHIFT,SIGN,SIZE,ADD,LATMACH,LATMACL,ZH}<=9'b1_011_00_110;
                      MAC_BUSY <= 1'b1;     
                      MAC_DISPATCH <= 1'b0;
                      NEXTSTATE <= `MACL2;
                     end
            `MACL2  :begin
                      {SELA,SHIFT,SIGN,SIZE,ADD,LATMACH,LATMACL,ZH}<=9'b1_111_00_110;
                      MAC_BUSY <= 1'b0;    
                      MAC_DISPATCH <= 1'b1;
                      NEXTSTATE <= `NOP;
                     end
            `MACLS  :begin
                      {SELA,SHIFT,SIGN,SIZE,ADD,LATMACH,LATMACL,ZH}<=9'b1_011_10_110;
                      MAC_BUSY <= 1'b1;     
                      MAC_DISPATCH <= 1'b0;
                      NEXTSTATE <= `MACLS2;
                     end
            `MACLS2 :begin
                      {SELA,SHIFT,SIGN,SIZE,ADD,LATMACH,LATMACL,ZH}<=9'b1_111_10_110;
                      MAC_BUSY <= 1'b0;    
                      MAC_DISPATCH <= 1'b1;
                      NEXTSTATE <= `NOP;
                     end
            `MACW   :begin
                      {SELA,SHIFT,SIGN,SIZE,ADD,LATMACH,LATMACL,ZH}<=9'b0_010_00_110;
                      MAC_BUSY <= 1'b1;    
                      MAC_DISPATCH <= 1'b1;
                      NEXTSTATE <= `NOP;
                     end
            `MACWS  :begin
                      {SELA,SHIFT,SIGN,SIZE,ADD,LATMACH,LATMACL,ZH}<=9'b0_010_11_011;
                      MAC_BUSY <= 1'b0;     
                      MAC_DISPATCH <= 1'b1;
                      NEXTSTATE <= `NOP;
                     end
            `MULL   :begin
                      {SELA,SHIFT,SIGN,SIZE,ADD,LATMACH,LATMACL,ZH}<=9'b0_011_00_011;
                      MAC_BUSY <= 1'b1;     
                      MAC_DISPATCH <= 1'b0;
                      NEXTSTATE <= `MULL2;
                     end
            `MULL2  :begin
                      {SELA,SHIFT,SIGN,SIZE,ADD,LATMACH,LATMACL,ZH}<=9'b0_111_00_011;
                      MAC_BUSY <= 1'b0;    
                      MAC_DISPATCH <= 1'b1;
                      NEXTSTATE <= `NOP;
                     end
            `MULSW  :begin
                      {SELA,SHIFT,SIGN,SIZE,ADD,LATMACH,LATMACL,ZH}<=9'b0_010_00_011;
                      MAC_BUSY <= 1'b0;     
                      MAC_DISPATCH <= 1'b1;
                      NEXTSTATE <= `NOP;
                     end
            `MULUW  :begin
                      {SELA,SHIFT,SIGN,SIZE,ADD,LATMACH,LATMACL,ZH}<=9'b0_000_00_011;
                      MAC_BUSY <= 1'b0;     
                      MAC_DISPATCH <= 1'b1;
                      NEXTSTATE <= `NOP;
                     end
            default : begin
                      {SELA,SHIFT,SIGN,SIZE,ADD,LATMACH,LATMACL,ZH}<=9'b0_000_00_000;
                      MAC_BUSY <= 1'b0;     
                      MAC_DISPATCH <= 1'b1;
                      NEXTSTATE <= `NOP;
                     end
        endcase
    end

//-----------------------------------------
// Data Path
//-----------------------------------------

//---
// M1
//---
    always @(posedge CLK)
    begin
        if (SLOT & MULCOM1)
	   begin
            M1 <= MACIN1;
        end
    end

//-------
// M2
// B (=M2)
//-------
    always @(posedge CLK)
    begin
        if (SLOT & MULCOM2[7])
	   begin
            M2 <= MACIN2;
        end
    end

    always @(M2) B <= M2;

//---
// MB
//---
// if SLOT and MULCOM2=MACL, do latch M1.
    always @(posedge CLK)
    begin
        if (SLOT & MULCOM2[7] & (MULCOM2[5:0] == 6'b001111))
	   begin
            MB <= M1;
        end
    end

//--------
//Select A
//--------
    always @(SELA or M1 or MB)
    begin
        if (SELA)
            A <= MB;
         else
            A <= M1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -