// ***************************************************************************/
//Microsemi Corporation Proprietary and Confidential
//Copyright 2011 Microsemi Corporation. All rights reserved.
//
//ANY USE OR REDISTRIBUTION IN PART OR IN WHOLE MUST BE HANDLED IN
//ACCORDANCE WITH THE MICROSEMI LICENSE AGREEMENT AND MUST BE APPROVED
//IN ADVANCE IN WRITING.
//
//Description:  CoreFFT
//              Hard MAC component wrapper
//
//Revision Information:
//Date         Description
//01Aug2011    Initial Release
//
//SVN Revision Information:
//SVN $Revision: $
//SVN $Data: $
//
//Resolved SARs
//SAR     Date    Who         Description
//
//Notes:
//
// 10/7/2011  Static unused register are tight to 1'b1 when possible

`timescale 1 ns/100 ps


// MAC 18x18 for wide and cmplx mult:
//  -optional mcand and P registers
//  -common reset; no accumulator - just adder
//  -add/sub input
//  -mcands get sign extended
//  -unused cin/cdin are grounded
module fft_inpl_mac18x18mx(nGrst, rstn, clk, en_a, en_b, en_p,
                mcand_a, mcand_b,
                carryin,
                cdsel,
                cdout, pout,
                shftsel, sub);
  parameter WIDTH_A      = 18;
  parameter WIDTH_B      = 18;
  parameter BYPASS_REG_A = 0;
  parameter BYPASS_REG_B = 0;
  parameter BYPASS_REG_P = 0;
  parameter FPGA_FAMILY  = 12;

  localparam [1:0] BY_REGA = BYPASS_REG_A ? 2'b11 : 2'b00;
  localparam [1:0] BY_REGB = BYPASS_REG_B ? 2'b11 : 2'b00;
  localparam [1:0] BY_REGP = BYPASS_REG_P ? 2'b11 : 2'b00;

  localparam P_WIDTH = (FPGA_FAMILY == 12)? 41 : 44;

  input nGrst, rstn, clk, en_a, en_b, en_p;
  input [WIDTH_A-1:0] mcand_a;
  input [WIDTH_B-1:0] mcand_b;
  input [P_WIDTH-1:0] carryin;
  input cdsel;        // Constant; 0-carryin=cin; 1-carryin=cdin;
  input shftsel;      // Constant; 0-no shift; 1-carryin>>>17;
  input sub;          // Constant; 0-add; 1-sub;
  output[P_WIDTH-1:0] cdout, pout;

  wire [1:0] ea_w, eb_w, ep_w;
  wire [1:0] rstn_a_w, rstn_b_w, rstn_p_w;
  wire [17:0] hw_mcand_a, hw_mcand_b;
  wire [1:0] arstn_a, arstn_b, arstn_p;
  wire[P_WIDTH-1:0] hw_cdin, hw_cin;

  always @ (nGrst)
    if((WIDTH_A>18) || (WIDTH_B>18))
      $display("Error: Multiplicand bitwidth cannot exceed 18\n");

  assign ea_w = BYPASS_REG_A ? 2'b11 : {en_a,en_a};
  assign eb_w = BYPASS_REG_B ? 2'b11 : {en_b,en_b};
  assign ep_w = BYPASS_REG_P ? 2'b11 : {en_p,en_p};

  assign rstn_a_w = BYPASS_REG_A ? 2'b11 : {rstn,rstn};
  assign rstn_b_w = BYPASS_REG_B ? 2'b11 : {rstn,rstn};
  assign rstn_p_w = BYPASS_REG_P ? 2'b11 : {rstn,rstn};
  assign arstn_a  = BYPASS_REG_A ? 2'b11 : {nGrst,nGrst};   // tool
  assign arstn_b  = BYPASS_REG_B ? 2'b11 : {nGrst,nGrst};   // tool
  assign arstn_p  = BYPASS_REG_P ? 2'b11 : {nGrst,nGrst};   // tool

  // At first tap carryin goes to cin, otherwise to cdin
  assign hw_cin  = cdsel ? 'b0 : carryin;
  assign hw_cdin = cdsel ? carryin : 'b0; // the case for a column bottom only

  fft_inpl_signExt # ( .INWIDTH(WIDTH_A), .OUTWIDTH(18), .UNSIGNED(0)) signExt_a (
    .inp(mcand_a), .outp(hw_mcand_a)  );
  fft_inpl_signExt # ( .INWIDTH(WIDTH_B), .OUTWIDTH(18), .UNSIGNED(0)) signExt_b (
    .inp(mcand_b), .outp(hw_mcand_b)  );

  generate
    if(FPGA_FAMILY == 12) begin: rtax_d
      MATH18X18 mac_0 (
        .CLK({clk,clk}),
        .A(hw_mcand_a),
        .EA(ea_w),
        .ARSTA(arstn_a),      // async rst
        .SRSTA(rstn_a_w),     // sync rst
        .ALAT(BY_REGA),       // latch

        .B    (hw_mcand_b),
        .EB   (eb_w),
        .ARSTB(arstn_b),      // async rs
        .SRSTB(rstn_b_w),     // sync rst
        .BLAT (BY_REGB),      // latch

        .P    (pout),
        .CDOUT(cdout),
        .OVFL (),
        .EP   (ep_w),
        .ARSTP(arstn_p),      // async rs
        .SRSTP(rstn_p_w),     // sync rst
        .PLAT (BY_REGP),      // latch

        .CIN  (hw_cin),
        .CDIN (hw_cdin),

        .SUB        (sub),
        .ESUB       (1'b1),           // en
        .SUBAD      (1'b0),           // async data bit
        .ALSUB      (1'b1),           // async load the data bit
        .SUBSD      (1'b1),           // sync data bit
        .SLSUB      (1'b1),           // sync load the data bit
        .SUBLAT     (1'b1),           // latch

        .SHFTSEL    (shftsel),
        .ESHFTSEL   (1'b1),           // en
        .SHFTSELAD  (1'b0),           // async data bit
        .ALSHFTSEL  (1'b1),           // async load the data bit
        .SHFTSELSD  (1'b1),           // sync data bit
        .SLSHFTSEL  (1'b1),           // sync load the data bit
        .SHFTSELLAT (1'b1),           // latch

        .CDSEL      (cdsel),
        .ECDSEL     (1'b1),           // en
        .CDSELAD    (1'b0),           // async data bit
        .ALCDSEL    (1'b1),           // async load the data bit
        .CDSELSD    (1'b1),           // sync data bit
        .SLCDSEL    (1'b1),           // sync load the data bit
        .CDSELLAT   (1'b1),           // latch

        .FDBKSEL    (1'b0),
        .EFDBKSEL   (1'b1),           // en
        .FDBKSELAD  (1'b0),           // async data bit
        .ALFDBKSEL  (1'b1),           // async load the data bit
        .FDBKSELSD  (1'b1),           // sync data bit
        .SLFDBKSEL  (1'b1),           // sync load the data bit
        .FDBKSELLAT (1'b1),           // latch

        .SIMD(1'b0)             );
    end

    else begin: g4_macc
      // Cdin input of a MAC by design is connected ONLY to cdout of an adjacent
      // MAC
      // 1.Set fdbksel mux (sel0) to let zero thru it.
      // 2.Set cdsel mux to disconnect cdin and let the fdbk mux output, i.e.
      //   zero thru it.
      MACC macc_0 (
        .CLK  ({clk,clk}),

        .A        (hw_mcand_a),
        .A_EN     (ea_w),
        .A_ARST_N (arstn_a),
        .A_SRST_N (rstn_a_w),
        .A_BYPASS (BY_REGA),      // latch

        .B        (hw_mcand_b),
        .B_EN     (eb_w),
        .B_ARST_N (arstn_b),
        .B_SRST_N (rstn_b_w),
        .B_BYPASS (BY_REGB),      // latch

        // Permanent 44'b0 generator
        .C        (44'hFFFFFFFFFFF),
        .C_EN     (2'b11),
        .C_ARST_N (2'b00),
        .C_SRST_N (2'b11),
        .C_BYPASS (2'b00),        // latch    //Library
        .CARRYIN  (1'b1),

        .P        (pout),
        .CDOUT    (cdout),
        .P_EN     (ep_w),
        .P_ARST_N (arstn_p),
        .P_SRST_N (rstn_p_w),
        .P_BYPASS (BY_REGP),      //latch

        .OVFL_CARRYOUT  (),

        .CDIN (hw_cdin),

        // Transparent reg as sub is static
        .SUB        (sub),
        .SUB_EN     (1'b1),           // en
        .SUB_AD     (1'b0),           // async data bit
        .SUB_AL_N   (1'b1),           // async load the data bit
        .SUB_SD_N   (1'b1),           // sync data bit
        .SUB_SL_N   (1'b1),           // sync load the data bit
        .SUB_BYPASS (1'b1),           // latch

        // Transparent reg as shftsel is static
        .ARSHFT17         (shftsel),
        .ARSHFT17_EN      (1'b1),           // en
        .ARSHFT17_AD      (1'b0),           // async data bit
        .ARSHFT17_AL_N    (1'b1),           // async load the data bit
        .ARSHFT17_SD_N    (1'b1),           // sync data bit
        .ARSHFT17_SL_N    (1'b1),           // sync load the data bit
        .ARSHFT17_BYPASS  (1'b1),           // latch

        // Let zero thru fdbksel mux so, that when cdsel==0 adder 'd' input = 0
        // Reg is a permanent 0 generator to keep fdbk control signal = 0
        .FDBKSEL        (1'b0),   // cannot tight it to high !!! SAR 34520
        .FDBKSEL_EN     (1'b1),           // en
        .FDBKSEL_AD     (1'b0),           // async data bit
        .FDBKSEL_AL_N   (1'b0),           // async load the data bit
        .FDBKSEL_SD_N   (1'b1),           // sync data bit
        .FDBKSEL_SL_N   (1'b1),           // sync load the data bit
        .FDBKSEL_BYPASS (1'b1),           // latch

        // Transparent reg as cdsel is static
        .CDSEL        (cdsel),
        .CDSEL_EN     (1'b1),           // en
        .CDSEL_AD     (1'b0),           // async data bit
        .CDSEL_AL_N   (1'b1),           // async load the data bit
        .CDSEL_SD_N   (1'b1),           // sync data bit
        .CDSEL_SL_N   (1'b1),           // sync load the data bit
        .CDSEL_BYPASS (1'b1),           // latch

        .OVFL_CARRYOUT_SEL  (1'b1),     // Select carryout 1 ???

        .SIMD(1'b0),
        .DOTP(1'b0)    );
    end
  endgenerate
endmodule



































































