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

📄 mult.v

📁 日立SH-2 CPU核的VERLOG源码
💻 V
📖 第 1 页 / 共 2 页
字号:
    end

//---------------------------------------
// lower 31bit of A	(input to Multiplier)
//---------------------------------------
    always @(A or SIZE)
    begin
	   if (SIZE == 1'b0)
	       AH <= {16'h0000,A[14:0]};
	   else
	       AH <= A[30:0];
    end

//---------------------------------------
// upper/lower of B (input to Multiplier)
//---------------------------------------
    always @(B or SHIFT or SIZE)
    begin
        if (SIZE == 1'b0)
		  BH <= {1'b0,B[14:0]};
        else if (SHIFT == 1'b0)
            BH <= B[15:0];
        else
            BH <= {1'b0,B[30:16]};
    end

//-----------
// Multiplier
//----------
    always @(AH or BH)
    begin
        ABH[46:0] <= AH[30:0] * BH[15:0]; // 31bit * 16bit -> 47bit
    end

//---
// PM
//---
    always @(SHIFT or SIZE or A or B)
    begin
        if (SHIFT)
	       begin
			 P2 <= {1'b0, (A[31])? B[30:0]:31'h00000000};
			 P3 <= {1'b0, (B[31])? A[30:0]:31'h00000000};
		  end
	   else if(~SIZE)
	       begin
			 P2 <= {17'h00000, (A[15])? B[14:0]:15'h0000};
			 P3 <= {17'h00000, (B[15])? A[14:0]:15'h0000};
		  end
	   else
	       begin
			 P2 <= 32'h00000000;
			 P3 <= 32'h00000000;
		  end
    end

    always @(P2 or P3)
    begin
        P23 <= P2 + P3;
    end

    always @(ABH or SHIFT or SIZE or A or B)
    begin
        if (SIZE == 1'b0)
	       ABH2 <= {17'h00000,(A[15] & B[15]),ABH[29:15]};
        else if (SHIFT == 1'b0)
            ABH2 <= {1'b0, ABH[46:15]};
	   else
	       ABH2 <= {1'b0,(A[31] & B[31]),ABH[45:15]};
    end

    always @(P23 or SIGN)
    begin
        if (SIGN == 1'b0)
	       P23S <= {1'b0, P23};
	   else
	       P23S <= {1'b1,~P23};
    end

    always @(P23S or ABH or ABH2 or SIGN)
    begin
	   PM[47:15] <= ABH2[32:0] + P23S + SIGN;
	   PM[14: 0] <= ABH[14: 0];
    end

//---------
// Select C
//---------
    always @(PM or SHIFT or SIZE)
    begin
        if (SHIFT == 1'b0)
            if (~SIZE & PM[47])
                C <= {16'hffff, PM};
            else 
                C <= {16'h0000, PM};
        else
            C <= {PM, 16'h0000};
    end

//-------------------------------------
// 64bit ADDER with Satulating function
//-------------------------------------
//
// Essential of Saturate Operation [ MAC[64] + C[64] ]
//
//   +S     |             Left plane shows value of MAC.
//     \    |             "+S" is + side saturate value (ex.00007FFF).
//      \  <P>            "-S" is - side saturate value (ex.FFFF8000).
//  <P'> \  |             Addition of plus C rotates MAC value counterclockwise.
//        \ |             Addition of minus C rotates MAC value clockwise.                                                     
// 7F..    \|     00..
// -------------------    Region<M'> : MAC=80000000~FFFF7FFF
// 80..    /|     FF..    Region<M > : MAC=FFFF8000~FFFFFFFF
//        / |             Region<P > : MAC=00000000~00007FFF
//  <M'> /  |             Region<P'> : MAC=00008000~7FFFFFFF
//      /  <M>  
//     /    |             Note that initial MAC value may be in any region.
//   -S     |             And value C may also be 00000000~FFFFFFFF.
//                                            
// ===========================================
// Initial_MAC  Rotation(C)  MAC+C  Result_MAC
// ===========================================
//     P            +          P     OK      
//     P            +          P'    00007FFF
//     P            +          M'    00007FFF
//     P            +          M     00007FFF 
// -------------------------------------------
//     P'           +          P     00007FFF Impossible      
//     P'           +          P'    00007FFF
//     P'           +          M'    00007FFF
//     P'           +          M     00007FFF 
// -------------------------------------------
//     M'           +          P     OK      
//     M'           +          P'    00007FFF Imposible
//     M'           +          M'    FFFF8000
//     M'           +          M     OK       
// -------------------------------------------
//     M            +          P     OK      
//     M            +          P'    00007FFF
//     M            +          M'    00007FFF Impossible
//     M            +          M     OK       
// ===========================================
//     P            -          P     OK      
//     P            -          P'    FFFF8000 Impossible
//     P            -          M'    FFFF8000
//     P            -          M     OK 
// -------------------------------------------
//     P'           -          P     OK      
//     P'           -          P'    00007FFF
//     P'           -          M'    FFFF8000 Impossible
//     P'           -          M     OK 
// -------------------------------------------
//     M'           -          P     FFFF8000      
//     M'           -          P'    FFFF8000
//     M'           -          M'    FFFF8000
//     M'           -          M     FFFF8000 Impossible       
// -------------------------------------------
//     M            -          P     FFFF8000      
//     M            -          P'    FFFF8000
//     M            -          M'    FFFF8000
//     M            -          M     OK       
// ===========================================

// Again, Compactly...                               
// ===========================================
// Initial_MAC  Rotation(C)  MAC+C  Result_MAC
// ===========================================
//     P /M        +/-        P /M  OK      
//     P /M        +/-        P'/M' 00007FFF/FFFF8000
//     P /M        +/-        M'/P' 00007FFF/FFFF8000
//     P /M        +/-        M /P  00007FFF/FFFF8000
// -------------------------------------------
//     P'/M'       +/-        P /M  Impossible = Don't care      
//     P'/M'       +/-        P'/M' 00007FFF/FFFF8000
//     P'/M'       +/-        M'/P' 00007FFF/FFFF8000
//     P'/M'       +/-        M /P  00007FFF/FFFF8000
// -------------------------------------------
//     M'/P'       +/-        P /M  OK      
//     M'/P'       +/-        P'/M' Impossible = Don't care
//     M'/P'       +/-        M'/P' FFFF8000/00007FFF <--caution !
//     M'/P'       +/-        M /P  OK       
// -------------------------------------------
//     M /P        +/-        P /M  OK      
//     M /P        +/-        P'/M' 00007FFF/FFFF8000
//     M /P        +/-        M'/P' Impossible = Don't care
//     M /P        +/-        M /P  OK       
// ===========================================

// Again, Much Compactly...                                  
// ===========================================
// Initial_MAC  Rotation(C)  MAC+C  Result_MAC
// ===========================================
//     P /M        +/-        P /M  OK      
//     P /M        +/-        P'/M' 00007FFF/FFFF8000
//     P /M        +/-        - /+  00007FFF/FFFF8000
// -------------------------------------------
//     P'/M'       +/-        P /M  Impossible = Don't care      
//     P'/M'       +/-        P'/M' 00007FFF/FFFF8000
//     P'/M'       +/-        - /+  00007FFF/FFFF8000
// -------------------------------------------
//     M'/P'       +/-        P /M  OK 
//     - /+        +/-        M'/P' FFFF8000/00007FFF <--caution !
//     M'/P'       +/-        M /P  OK       
// -------------------------------------------
//     M /P        +/-        P /M  OK      
//     - /+        +/-        P'/M' 00007FFF/FFFF8000
//     M /P        +/-        M /P  OK       
// ===========================================

// Again, Much Compactly...                                  
// ===========================================
// Initial_MAC  Rotation(C)  MAC+C  Result_MAC
// ===========================================
//     + /-        +/-        P /M  OK      
//     + /-        +/-        P'/M' 00007FFF/FFFF8000
//     + /-        +/-        - /+  00007FFF/FFFF8000
// -------------------------------------------
//     - /+        +/-        P /M  OK 
//     - /+        +/-        M'/P' FFFF8000/00007FFF <--caution !
//     - /+        +/-        M /P  OK       
//     - /+        +/-        P'/M' 00007FFF/FFFF8000
// ===========================================

// Again, Much Compactly...                                  
// ===========================================
// Initial_MAC  Rotation(C)  MAC+C  Result_MAC
// ===========================================
//     * /*        +/-        P /M  OK      
//     * /*        +/-        P'/M' 00007FFF/FFFF8000
//     + /-        +/-        - /+  00007FFF/FFFF8000
//     - /+        +/-        M'/P' FFFF8000/00007FFF <--caution !
//     - /+        +/-        M /P  OK       
// ===========================================

    always @(C or MACH or MACL or ZH)
    begin
        ADDRESULT <= C + {((ZH == 1'b0) ? MACH : 32'h00000000), MACL};
    end

    reg [1:0] RESULT_REGION48; //00:P, 01:P', 10:M, 11:M'
    reg       RESULT_REGION32; //0:P, 1:M, No P'/M' region in case of 32bit saturation.
    always @(ADDRESULT)
    begin
        RESULT_REGION48[1] <=  ADDRESULT[63];
        RESULT_REGION32    <=  ADDRESULT[31];
        if (ADDRESULT[63] == 1'b0)
          //RESULT_REGION48[0] <= (ADDRESULT[63:47] >= 17'h00001);
		  RESULT_REGION48[0] <= (ADDRESULT[63:47] != 17'h00000);
        else
          //RESULT_REGION48[0] <= (ADDRESULT[63:47] <= 17'hFFFFE);
		  RESULT_REGION48[0] <= (ADDRESULT[63:47] != 17'hFFFFF);
    end

    always @(ADDRESULT or C or MACH or MACL or ADD or RESULT_REGION48 or RESULT_REGION32)
    begin
        case(ADD)
            2'b00   : begin // ADD
                          ADDRESULT2 <= ADDRESULT;
                          SAT <= 1'b0;
                      end
            2'b10   : begin // ADDS48
                          if (~C[63]) // + rotation
                              case ({MACH[31], RESULT_REGION48})
                                  3'b000 : {ADDRESULT2,SAT} <= {ADDRESULT,1'b0};            //+,P
                                  3'b001 : {ADDRESULT2,SAT} <= {64'h00007FFFFFFFFFFF,1'b1}; //+,P'
                                  3'b010 : {ADDRESULT2,SAT} <= {64'h00007FFFFFFFFFFF,1'b1}; //+,M
                                  3'b011 : {ADDRESULT2,SAT} <= {64'h00007FFFFFFFFFFF,1'b1}; //+,M'
                                  3'b100 : {ADDRESULT2,SAT} <= {ADDRESULT,1'b0};            //-,P
                                  3'b101 : {ADDRESULT2,SAT} <= {64'h00007FFFFFFFFFFF,1'b1}; //-,P'
                                  3'b110 : {ADDRESULT2,SAT} <= {ADDRESULT,1'b0};            //-,M
                                  3'b111 : {ADDRESULT2,SAT} <= {64'hFFFF800000000000,1'b1}; //-,M'
                                  default: {ADDRESULT2,SAT} <= {64'hxxxxxxxxxxxxxxxx,1'bx};
                              endcase
                          else        // - rotation
                              case ({MACH[31], RESULT_REGION48})
                                  3'b000 : {ADDRESULT2,SAT} <= {ADDRESULT,1'b0};            //+,P
                                  3'b001 : {ADDRESULT2,SAT} <= {64'h00007FFFFFFFFFFF,1'b1}; //+,P'
                                  3'b010 : {ADDRESULT2,SAT} <= {ADDRESULT,1'b0};            //+,M
                                  3'b011 : {ADDRESULT2,SAT} <= {64'hFFFF800000000000,1'b1}; //+,M'
                                  3'b100 : {ADDRESULT2,SAT} <= {64'hFFFF800000000000,1'b1}; //-,P
                                  3'b101 : {ADDRESULT2,SAT} <= {64'hFFFF800000000000,1'b1}; //-,P'
                                  3'b110 : {ADDRESULT2,SAT} <= {ADDRESULT,1'b0};            //-,M
                                  3'b111 : {ADDRESULT2,SAT} <= {64'hFFFF800000000000,1'b1}; //-,M'
                                  default: {ADDRESULT2,SAT} <= {64'hxxxxxxxxxxxxxxxx,1'bx};
                              endcase
                      end
            2'b11   : begin // ADDS32
                          if (~C[31]) // + rotation
                              case ({MACL[31], RESULT_REGION32})
                                  2'b00  : {ADDRESULT2,SAT} <= {ADDRESULT,1'b0};            //+,P
                                  2'b01  : {ADDRESULT2,SAT} <= {64'h000000007FFFFFFF,1'b1}; //+,M
                                  2'b10  : {ADDRESULT2,SAT} <= {ADDRESULT,1'b0};            //-,P
                                  2'b11  : {ADDRESULT2,SAT} <= {ADDRESULT,1'b0};            //-,M
                                  default: {ADDRESULT2,SAT} <= {64'hxxxxxxxxxxxxxxxx,1'bx};
                              endcase
                          else        // - rotation
                              case ({MACL[31], RESULT_REGION32})
                                  2'b00  : {ADDRESULT2,SAT} <= {ADDRESULT,1'b0};            //+,P
                                  2'b01  : {ADDRESULT2,SAT} <= {ADDRESULT,1'b0};            //+,M
                                  2'b10  : {ADDRESULT2,SAT} <= {64'hFFFFFFFF80000000,1'b1}; //-,P
                                  2'b11  : {ADDRESULT2,SAT} <= {ADDRESULT,1'b0};            //-,M
                                  default: {ADDRESULT2,SAT} <= {64'hxxxxxxxxxxxxxxxx,1'bx};
                              endcase
                      end
            default : begin 
                          ADDRESULT2 <= 64'hxxxxxxxxxxxxxxxx;
                          SAT <= 1'b0;
                      end
        endcase
    end

//-----
// MACH
//-----
// Clear condition of MACH: following command do not clear MACH
                          // 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
// Should do saturating operation 
    always @(posedge CLK)
    begin
        if (SLOT & WRMACH)
            MACH <= MACIN1;
        else if (SLOT & MULCOM2[7] 
                 & (MULCOM2[5:0] != 6'b001111) 
                 & (MULCOM2[6:0] != 7'b0000111)
                 & (MULCOM2[6:0] != 7'b0101111) 
                 & (MULCOM2[6:0] != 7'b0101110)
           )
            begin
                MACH <= 32'h00000000;
            end
        else if ((STATE == `MACWS) && (SAT == 1'b1))
            begin
                MACH <= MACH | 32'h00000001;
            end
        else if (LATMACH == 1'b1)
            begin
                MACH <= ADDRESULT2[63:32];
            end
    end

//-----
// MACL
//-----
// Clear condition of MACL: following command do not clear MACL
                          // MAC.L    1 0001111 8F
                          // MAC.W    1 1001111 CF
    always @(posedge CLK)
    begin
        if (SLOT & WRMACL)
            MACL <= MACIN2;
        else if (SLOT & MULCOM2[7] & (MULCOM2[5:0] != 6'b001111))
            begin
                MACL <= 32'h00000000;
            end
        else if (LATMACL == 1'b1)
            begin
                MACL <= ADDRESULT2[31:0];
            end
    end

//======================================================
  endmodule
//======================================================

⌨️ 快捷键说明

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