dakies/OSS_Verilog huggingface dataset:
module c3aibadapt_fsr_in 
 #(
    parameter NUM_OF_PCS_CHAIN   = 16, 
    parameter NUM_OF_HIP_CHAIN   = 16,
    parameter NUM_OF_PARITY_BIT_FSRIN = 1 
  )
(
input wire [(NUM_OF_PCS_CHAIN + NUM_OF_HIP_CHAIN - 1):0] sr_parallel_in,
//input wire [(NUM_OF_PCS_CHAIN + NUM_OF_HIP_CHAIN - 1):0] r_sr_bit,
input wire                    sr_load,
input wire                    clk,
input wire                    rst_n,
input wire                    r_sr_hip_en,
input wire                    r_sr_parity_en,
output wire                   sr_serial_out
);

wire [(NUM_OF_PCS_CHAIN + NUM_OF_HIP_CHAIN - 1):0]  sr_datain_int;
wire [(NUM_OF_PCS_CHAIN + NUM_OF_HIP_CHAIN - 1):0]  sr_dataout_int;

assign sr_datain_int[0] = sr_dataout_int[0];

generate
  genvar i;
  for (i=0; i < (NUM_OF_PCS_CHAIN + NUM_OF_HIP_CHAIN) ; i=i+1) begin: c3adapt_sr_in_bit
       c3aibadapt_sr_in_bit
       #(
           .RESET_VAL (0)
        ) c3adapt_sr_in_bit
         (
           // input
           .sr_load_in   (sr_parallel_in[i]),
           .sr_shift_in  (sr_datain_int[i]),
           .sr_load      (sr_load),
           .clk          (clk),
           .rst_n        (rst_n),
           // output
           .sr_dataout   (sr_dataout_int[i])
         );
  end
endgenerate

generate
  genvar j;
  for (j=1; j < (NUM_OF_PCS_CHAIN + NUM_OF_HIP_CHAIN); j=j+1)
  begin: fsr_in_chain_connection
    assign sr_datain_int[j] = sr_dataout_int[j-1];
  end
endgenerate

assign sr_serial_out = r_sr_hip_en ? sr_dataout_int[NUM_OF_PCS_CHAIN + NUM_OF_HIP_CHAIN - 1] : 
                                     !r_sr_parity_en ? sr_dataout_int[NUM_OF_PCS_CHAIN - 1] : sr_dataout_int[NUM_OF_PCS_CHAIN+NUM_OF_PARITY_BIT_FSRIN-1];

endmodule
module c3aibadapt_ssr_out 
 #(
    parameter NUM_OF_PCS_CHAIN   = 16, 
    parameter NUM_OF_HIP_CHAIN   = 16,
    parameter NUM_OF_RESERVED_CHAIN_SSROUT  = 5,
    parameter NUM_OF_PARITY_BIT_SSROUT = 6
  )
(
input wire                    sr_serial_in,
input wire                    sr_load,
input wire                    clk,
input wire                    rst_n,
input wire                    r_sr_hip_en,
input wire                    r_sr_parity_en,
input wire                    r_sr_reserbits_out_en,
output wire [(NUM_OF_PCS_CHAIN + NUM_OF_HIP_CHAIN + NUM_OF_RESERVED_CHAIN_SSROUT - 1):0] sr_parallel_out
);

localparam NUM_OF_UNUSED_HIP_CHAIN = NUM_OF_HIP_CHAIN - NUM_OF_PARITY_BIT_SSROUT;

wire [(NUM_OF_PCS_CHAIN + NUM_OF_HIP_CHAIN + NUM_OF_RESERVED_CHAIN_SSROUT - 1):0]  sr_datain_int;
wire [(NUM_OF_PCS_CHAIN + NUM_OF_HIP_CHAIN + NUM_OF_RESERVED_CHAIN_SSROUT - 1):0]  sr_dataout_int;

assign sr_datain_int[0] = sr_serial_in;

generate
  genvar i; 
  for (i=0; i < (NUM_OF_PCS_CHAIN + NUM_OF_HIP_CHAIN + NUM_OF_RESERVED_CHAIN_SSROUT); i=i+1) begin: c3adapt_sr_out_bit 
       c3aibadapt_sr_out_bit
       #(
           .RESET_VAL (0)
        ) c3adapt_sr_out_bit
         (
           // input
           .sr_shift_in  (sr_datain_int[i]),
           .sr_load      (sr_load),
           .clk          (clk),
           .rst_n        (rst_n),
           // output
           .sr_dataout   (sr_dataout_int[i])
         );
  end
endgenerate

generate
  genvar j;
  for (j=1; j < (NUM_OF_PCS_CHAIN + NUM_OF_HIP_CHAIN + NUM_OF_RESERVED_CHAIN_SSROUT); j=j+1)
  begin: ssr_out_chain_connection
    if (j == (NUM_OF_PCS_CHAIN + NUM_OF_RESERVED_CHAIN_SSROUT)) begin
         assign sr_datain_int[j] = r_sr_reserbits_out_en ? sr_dataout_int[j-1] : sr_dataout_int[NUM_OF_PCS_CHAIN-1];
    end
    else begin
         assign sr_datain_int[j] = sr_dataout_int[j-1];
    end
  end
endgenerate

assign sr_parallel_out = (!r_sr_reserbits_out_en) ?
                             (r_sr_hip_en ? {sr_dataout_int[(NUM_OF_RESERVED_CHAIN_SSROUT+NUM_OF_PCS_CHAIN+NUM_OF_HIP_CHAIN-1):(NUM_OF_RESERVED_CHAIN_SSROUT+NUM_OF_PCS_CHAIN)],
                                             {NUM_OF_RESERVED_CHAIN_SSROUT{1'b0}}, sr_dataout_int[NUM_OF_PCS_CHAIN-1:0]} :
                                            (!r_sr_parity_en ? {{NUM_OF_HIP_CHAIN{1'b0}}, {NUM_OF_RESERVED_CHAIN_SSROUT{1'b0}}, sr_dataout_int[NUM_OF_PCS_CHAIN-1:0]} : 
                                                               {{NUM_OF_UNUSED_HIP_CHAIN{1'b0}}, sr_dataout_int[(NUM_OF_PARITY_BIT_SSROUT + NUM_OF_RESERVED_CHAIN_SSROUT + NUM_OF_PCS_CHAIN - 1): (NUM_OF_RESERVED_CHAIN_SSROUT+ NUM_OF_PCS_CHAIN)], {NUM_OF_RESERVED_CHAIN_SSROUT{1'b0}}, sr_dataout_int[NUM_OF_PCS_CHAIN-1:0]}) ) :
                             (r_sr_hip_en ? sr_dataout_int : 
                                            !r_sr_parity_en ? {{NUM_OF_HIP_CHAIN{1'b0}}, sr_dataout_int[NUM_OF_RESERVED_CHAIN_SSROUT+NUM_OF_PCS_CHAIN-1:0]} : 
                                                             {{NUM_OF_UNUSED_HIP_CHAIN{1'b0}}, sr_dataout_int[NUM_OF_PARITY_BIT_SSROUT+NUM_OF_RESERVED_CHAIN_SSROUT+NUM_OF_PCS_CHAIN-1:0]});


endmodule
module c3aibadapt_sr_out_bit
 #(
    parameter RESET_VAL = 0     // Reset value
  )
(
input wire  sr_shift_in,
input wire  sr_load,
input wire  clk,
input wire  rst_n,

output reg  sr_dataout
);

localparam reset_value = (RESET_VAL == 1) ? 1'b1 : 1'b0;

always @(negedge rst_n or posedge clk)
  if (rst_n == 1'b0)
    begin
      sr_dataout <= reset_value;
    end
  else
    begin
      sr_dataout <= (!sr_load) ? sr_shift_in : sr_dataout;
    end


endmodule
module c3aibadapt_sr_async_capture_bit 
   #(
      parameter RESET_VAL     = 0  // 1: Active high; 0: Active low
    )
   (
   // Inputs
   input  wire               clk,      	  // clock
   input  wire               rst_n,       // async reset
   input  wire  	     data_in,     // data in
   input  wire		     unload,      // unload data out
   // Outputs
   output reg   	     data_out     // data out
   );

//******************************************************************************
// Define regs
//******************************************************************************
reg  				data_in_sync_d0;
wire  				data_in_sync;
reg				sample;

localparam reset_value = (RESET_VAL == 1) ? 1'b1 : 1'b0;  // To eliminate truncating warning


// hd_dpcmn_bitsync2
c3lib_bitsync
  #(
    .SRC_DATA_FREQ_MHZ    (500),      // Source data freq
    .DST_CLK_FREQ_MHZ     (1000),      // Dest clock freq
    .DWIDTH               (1), // Sync Data input 
    .RESET_VAL            (reset_value)    	 // Reset Value 
    )
  bitsync2
   (
   .clk      (clk),
   .rst_n    (rst_n),
   .data_in  (data_in),
   .data_out (data_in_sync)
   );
      
      
always @(negedge rst_n or posedge clk) begin
   if (rst_n == 1'b0) begin
     begin
       sample 		<= 1'b0;
       data_out 	<= reset_value;
     end
  end
  else begin
  // No sample during unload
      if (unload) begin
        sample <= 1'b0;
      end
  // Sample on the first data change after unload      
      else if (sample == 1'b0 && data_in_sync != data_out) begin
        sample   <= 1'b1;
        data_out 		<= data_in_sync;
      end  
  end
end

endmodule
module c3aibadapt_srrst_ctl
(
	input   wire            csr_rdy_dly_in,
	input	wire		sr_clock_tx_sr_clk_in,
	input	wire		sr_clock_reset_rx_osc_clk,
	input	wire		sr_clock_reset_tx_osc_clk,
	input	wire		r_sr_free_run_div_clk,
	input	wire		dft_adpt_rst,
	input	wire		adapter_scan_rst_n,
	input	wire		adapter_scan_mode_n,
	output	wire		sr_reset_tx_sr_clk_in_rst_n,
	output	wire		sr_reset_rx_osc_clk_rst_n,
	output	wire		sr_reset_tx_osc_clk_rst_n
);

	wire		int_sr_hrd_rst_n;
	wire            int_div_clk_rst_n_bypass;
        wire            int_div_clk_scan_mode_n;
	//wire	sr_reset_tx_sr_clk_in_rst_n_int;

assign int_sr_hrd_rst_n = (adapter_scan_mode_n & ~dft_adpt_rst & csr_rdy_dly_in) | (~adapter_scan_mode_n & adapter_scan_rst_n);

// hd_dpcmn_rst_n_sync hd_dpcmn_rst_n_sync_rx_osc_clk
c3lib_rstsync #(.RESET_VAL(0), .DST_CLK_FREQ_MHZ(1000))
  rst_sync_rx_osc_clk 
  (
  .rst_n(int_sr_hrd_rst_n),
  .rst_n_bypass(adapter_scan_rst_n),
  .clk (sr_clock_reset_rx_osc_clk),
  .scan_mode_n(adapter_scan_mode_n),
  .rst_n_sync(sr_reset_rx_osc_clk_rst_n)
  );

// hd_dpcmn_rst_n_sync hd_dpcmn_rst_n_sync_tx_osc_clk
c3lib_rstsync #(.RESET_VAL(0), .DST_CLK_FREQ_MHZ(1000))
  rst_sync_tx_osc_clk 
  (
  .rst_n(int_sr_hrd_rst_n),
  .rst_n_bypass(adapter_scan_rst_n),
  .clk (sr_clock_reset_tx_osc_clk),
  .scan_mode_n(adapter_scan_mode_n),
  .rst_n_sync(sr_reset_tx_osc_clk_rst_n)
  );

        assign int_div_clk_rst_n_bypass = (adapter_scan_mode_n | adapter_scan_rst_n);
        assign int_div_clk_scan_mode_n = (adapter_scan_mode_n & ~r_sr_free_run_div_clk);

// hd_dpcmn_rst_n_sync hd_dpcmn_rst_n_sync_tx_sr_clk_in
c3lib_rstsync #(.RESET_VAL(0), .DST_CLK_FREQ_MHZ(1000))
  rst_sync_tx_sr_clk_in 
  (
  .rst_n(int_sr_hrd_rst_n),
  .rst_n_bypass(int_div_clk_rst_n_bypass),
  .clk (sr_clock_tx_sr_clk_in),
  .scan_mode_n(int_div_clk_scan_mode_n),
  .rst_n_sync(sr_reset_tx_sr_clk_in_rst_n)
  );

 //assign sr_reset_tx_sr_clk_in_rst_n = (r_sr_free_run_div_clk) ? 1'b1 : sr_reset_tx_sr_clk_in_rst_n_int;

endmodule // c3aibadapt_srrst_ctl
module c3aibadapt_sr_sm 
 #(
    parameter NUM_OF_PCS_CHAIN   = 7'd16,
    parameter NUM_OF_HIP_CHAIN   = 7'd16,
    parameter NUM_OF_PARITY_IN   = 7'd1,
    parameter NUM_OF_RESERVED_CHAIN_SSRIN = 7'd5
  )
(
input wire  clk,
input wire  rst_n,
input wire  r_sr_hip_en,
input wire  r_sr_parity_en,
input wire  r_sr_reserbits_in_en,
input wire  avmm_hrdrst_hssi_osc_transfer_en_sync,

output wire [3:0] sr_testbus,
output reg  sr_loadout
);


localparam SR_LOAD  = 1'b1;
localparam SR_SHIFT = 1'b0; 

reg sr_ns;
reg sr_cs;
reg sr_loadout_comb;

reg sr_counter_expired;
reg sr_count_start_comb;
reg sr_count_start;
reg  [6:0] sr_counter;
wire [6:0] sr_counter_target;

assign sr_testbus = {sr_cs, sr_counter_expired, sr_count_start, sr_loadout};

assign sr_counter_target = (!r_sr_reserbits_in_en) ? (r_sr_hip_en ? (NUM_OF_PCS_CHAIN + NUM_OF_HIP_CHAIN - 1) : !r_sr_parity_en ? (NUM_OF_PCS_CHAIN - 1) : (NUM_OF_PARITY_IN + NUM_OF_PCS_CHAIN - 1)) :
                                                     (r_sr_hip_en ? (NUM_OF_PCS_CHAIN + NUM_OF_HIP_CHAIN + NUM_OF_RESERVED_CHAIN_SSRIN - 1) : 
                                                                    !r_sr_parity_en ? (NUM_OF_PCS_CHAIN + NUM_OF_RESERVED_CHAIN_SSRIN - 1) : (NUM_OF_PARITY_IN + NUM_OF_PCS_CHAIN + NUM_OF_RESERVED_CHAIN_SSRIN - 1));


always @(*) begin
  sr_ns = sr_cs;
  sr_loadout_comb = 1'b0;
  sr_count_start_comb = 1'b0;
 
  case (sr_cs)
    SR_LOAD: 
      begin
         sr_loadout_comb      = 1'b1;
         sr_count_start_comb  = 1'b0;
         sr_ns                = SR_SHIFT;
      end
    SR_SHIFT:
      begin
         sr_loadout_comb      = 1'b0;
         sr_count_start_comb  = 1'b1;
         if (sr_counter_expired == 1'b1) 
         begin 
             sr_ns      = SR_LOAD;
         end
      end
    default: 
      begin
         sr_loadout_comb     = 1'b1;
         sr_count_start_comb = 1'b0;
         sr_ns               = SR_LOAD;
      end
  endcase
end


always @(negedge rst_n or posedge clk)
  if (rst_n == 1'b0)
    begin
       sr_loadout <= 1'b1;
       sr_cs      <= SR_LOAD;
    end
  else if (avmm_hrdrst_hssi_osc_transfer_en_sync == 1'b0)
    begin
       sr_loadout <= 1'b1;
       sr_cs      <= SR_LOAD;
    end
  else
    begin
       sr_loadout <= sr_loadout_comb;
       sr_cs      <= sr_ns;
    end

    
always @(negedge rst_n or posedge clk)
  if (rst_n == 1'b0)
    begin
      sr_counter <= 7'b000_0000;
      sr_counter_expired <= 1'b0;
      sr_count_start <= 1'b0; 
    end
  else
    begin
       sr_count_start <= sr_count_start_comb;
       if (sr_count_start_comb == 1'b1) begin
           sr_counter <= sr_counter + 7'b000_0001;
           sr_counter_expired <= (sr_counter[6:0] == (sr_counter_target[6:0]-1))? 1'b1: 1'b0;
       end
       else begin
           sr_counter <= 7'b000_0000;
           sr_counter_expired <= 1'b0;
       end
    end

endmodule
module c3aibadapt_rxclk_gate
(
	input	wire		cp,
	input	wire		e,
	input	wire		te,
	output	wire		q
);

	wire	clk;
	wire	clk_n;
	wire	clken;
	reg	latch_clken;

	assign clk = cp;
	assign clk_n = ~cp;
	assign clken = e || te;

        always @(clk_n or clken)
        begin
		if (clk_n)
                begin
                        latch_clken <= clken;
                end
        end

	assign q = clk & latch_clken;

endmodule // c3aibadapt_rxclk_gate
module c3aibadapt_rxasync_rsvd_capture (
input   wire   [1:0]    pld_rx_ssr_reserved_in,

// SR
input   wire            rx_async_hssi_fabric_ssr_load,

// RXCLK_CTL
input   wire            rx_clock_async_tx_osc_clk, 

// RXRST_CTL
input   wire            rx_reset_async_tx_osc_clk_rst_n, 

// SR
output  wire   [1:0]    rx_async_hssi_fabric_ssr_reserved 
);

wire [1:0] nc_0;

// SLOW SR:
generate
  genvar i;
    for (i=0; i < 2; i=i+1) begin: c3adapt_cmn_async_capture_bit
    c3aibadapt_cmn_async_capture_bit
     #(
       .SYNC_STAGE  (3),
       .RESET_VAL   (0)
       )
       async_rx_reserved_ssr_in
      (
          .clk         (rx_clock_async_tx_osc_clk),
          .rst_n       (rx_reset_async_tx_osc_clk_rst_n),
          .data_in     (pld_rx_ssr_reserved_in[i]),
          .unload      (rx_async_hssi_fabric_ssr_load),
          .data_in_sync_out (nc_0[i]),
          .data_out    (rx_async_hssi_fabric_ssr_reserved[i])
      );
   end
endgenerate

endmodule
module c3aibadapt_rx_dprio(
// rx_datapath
        output   wire    [15:0]  avmm_rx_datapath_user_datain,
        output   wire            r_10g_mode    ,
        output   wire            r_bonding_dft_in_en,
        output   wire            r_bonding_dft_in_value,
        output   wire    [7:0]   r_comp_cnt,
        output   wire    [1:0]   r_compin_sel,
        output   wire            r_double_write,
        output   wire            r_ds_bypass_pipeln,
        output   wire            r_ds_master,
        output   wire    [3:0]   r_empty,
        output   wire            r_empty_type  ,
        output   wire    [2:0]   r_fifo_mode,
        output   wire    [3:0]   r_full,
        output   wire            r_full_type   ,
        output   wire            r_indv,
        output   wire    [3:0]   r_pempty,
        output   wire            r_pempty_type ,
        output   wire    [3:0]   r_pfull,
        output   wire            r_pfull_type  ,
        output   wire    [2:0]   r_phcomp_rd_delay,
        output   wire            r_stop_read   ,
        output   wire            r_stop_write  ,
        output   wire            r_us_bypass_pipeln,
        output   wire            r_us_master,
        output   wire            r_write_ctrl,
// rx_async
        output   wire    [23:0]  avmm_rx_async_user_datain,
// rxclk_ctrl
        output   wire    [15:0]  rx_user_clk_config
// rxrst_ctrl
);




endmodule
module c3aibadapt_rxdp_fifo_ram
  #(
    parameter DWIDTH = 'd40,             // FIFO Input data width 
    parameter DEPTH  = 'd16              // FIFO Depth 
    )
(
    input  wire              r_double_write,	// Write to 2 consecutive locations
    input  wire		     r_stop_write, // Disable/enable writing when FIFO is full    
    input  wire		     wr_full,
    input  wire              wr_clk,     // Write Domain Clock
    input  wire		     wr_rst_n,   // Write Domain Reset 
    input  wire              wr_en,      // Write Data Enable
    input  wire [DEPTH-1:0] wr_ptr,     // Write Pointer
    input  wire [DWIDTH-1:0] wr_data,    // Write Data In
    input  wire [DWIDTH-1:0] wr_data2,    // Write Data In
    input  wire [DEPTH-1:0] rd_ptr,     // Read Pointer
    output reg  [DWIDTH-1:0] rd_data   // Read Data

);

   //********************************************************************
   // Infer Memory or use Dual Port Memory from Quartus/ASIC Memory
   //********************************************************************
   
   integer		m;
   integer		i;
//   reg [DWIDTH-1:0]          fifo_mem [((1<<AWIDTH)-1):0];
   reg [DWIDTH-1:0]          fifo_mem [DEPTH-1:0];
   
   always @(negedge wr_rst_n or posedge wr_clk) begin
      if (~wr_rst_n) begin
         for (m='d0; m<=(DEPTH-1'b1); m=m+1'b1)
            fifo_mem[m] <= 'd0;	
      end 
      else if (wr_en && (~wr_full||~r_stop_write)) begin
         for (m='d0; m<=(DEPTH-1'b1); m=m+1'b1) begin
           if (wr_ptr[m]) begin
             fifo_mem[m] <= wr_data;
             if (r_double_write & m < DEPTH-1) // In double write mode, wr_ptr always increments by 2
               fifo_mem[m+1] <= wr_data2;
             end  
         end   
      end
   end
   
// assign rd_data = fifo_mem[rd_ptr];
// Read ptr must be one-hot
always @ *
begin: data_out 
  rd_data = fifo_mem[0];
  for (i='d0; i<=(DEPTH-1'b1); i=i+1'b1) begin
    if (rd_ptr[i]) begin
      rd_data = fifo_mem[i];
    end       
  end   
end 

endmodule
module c3aibadapt_rxasync_rsvd_update (
// RXCLK_CTL
input   wire            rx_clock_async_rx_osc_clk,

// RXRST_CTL
input   wire            rx_reset_async_rx_osc_clk_rst_n,

// SR
input   wire            rx_async_fabric_hssi_ssr_load, 
input   wire [1:0]      rx_async_fabric_hssi_ssr_reserved,

output  wire [1:0]      pld_rx_ssr_reserved_out 
);


// SLOW SR:
c3aibadapt_async_update
    #( .AWIDTH       (1),
       .RESET_VAL    (1)
     ) async_rx_pld_rx_ssr_reserved_out0
     ( .clk             (rx_clock_async_rx_osc_clk),
       .rst_n           (rx_reset_async_rx_osc_clk_rst_n),
       .sr_load         (rx_async_fabric_hssi_ssr_load),
       .async_data_in   (rx_async_fabric_hssi_ssr_reserved[0]),
       .async_data_out  (pld_rx_ssr_reserved_out[0])
     );

c3aibadapt_async_update
    #( .AWIDTH       (1),
       .RESET_VAL    (0)
     ) async_rx_pld_rx_ssr_reserved_out1
     ( .clk             (rx_clock_async_rx_osc_clk),
       .rst_n           (rx_reset_async_rx_osc_clk_rst_n),
       .sr_load         (rx_async_fabric_hssi_ssr_load),
       .async_data_in   (rx_async_fabric_hssi_ssr_reserved[1]),
       .async_data_out  (pld_rx_ssr_reserved_out[1])
     );


endmodule
module c3aibadapt_rxasync_direct (
// PCS IF
input   wire            pld_8g_rxelecidle,
input   wire            pld_pma_rxpll_lock,
input   wire            hip_aib_async_out,
input   wire            r_rx_async_hip_en,
input   wire  [1:0]     r_rx_parity_sel,
input   wire            pld_pma_pfdmode_lock,
input   wire  [5:0]     sr_parity_error_flag,
input	wire		avmm_transfer_error,
input	wire		rx_direct_transfer_testbus,
input	wire		r_rx_usertest_sel,

// AIB_IF
output  wire            aib_hssi_pld_pma_pfdmode_lock,
output  wire            aib_hssi_pld_8g_rxelecidle,
output  wire            aib_hssi_pld_pma_rxpll_lock
);



assign aib_hssi_pld_8g_rxelecidle  = r_rx_async_hip_en ? hip_aib_async_out : r_rx_usertest_sel ? (r_rx_parity_sel == 2'b00 ? pld_8g_rxelecidle : (r_rx_parity_sel == 2'b01 ? |sr_parity_error_flag[2:0] : (r_rx_parity_sel == 2'b10 ? |sr_parity_error_flag[5:3] : avmm_transfer_error) ) ) : rx_direct_transfer_testbus;
assign aib_hssi_pld_pma_rxpll_lock = pld_pma_rxpll_lock;
assign aib_hssi_pld_pma_pfdmode_lock = pld_pma_pfdmode_lock;
endmodule
module c3aibadapt_cmn_occ_clkgate
(
	input	wire		clk,
	input	wire		clk_enable_i,
	output	wire		clk_o
);

c3aibadapt_cmn_clkgate adapt_cmn_clkgate
    (
        .cp(clk),
        .e(clk_enable_i),
        .te(1'b0),
        .q(clk_o)
    );

endmodule // c3aibadapt_cmn_occ_clkgate
module c3aibadapt_cmn_dft_clk_ctlr (
  user_clk,                               //User clock
  test_clk,                               //Test clock      
  rst_n,				  //Reset (active low)
  clk_sel_n,                              //Mux sel between user or test clock, Active low
  scan_enable,                            //Scan enable control signal, Active high in IP, Active low in top level
  occ_enable,                             //Control signal to enable OCC, Active high in IP, Active low in top level
  atpg_mode,                              //Control signal for test mode, Active high in IP, Active low in top level
  out_clk                                 //Output clock 
);

parameter CONTROL_REGISTER_PRESENT = 0;

input user_clk;
input test_clk;
input rst_n;
input clk_sel_n;
input scan_enable;
input atpg_mode;
input occ_enable;
output out_clk;

wire int_test_clk;
wire int_user_clk; 
wire [1:0] burst_cnt;                     //may required more bus width if more pulse needed. Current is 2 pulses
wire clk_sel;
wire occ_enable_nand;
wire occ_user_clken;
wire occ_rst_n;

//Inversion for the clock selection  control signal
assign clk_sel = ~clk_sel_n;

// Reset logic
assign occ_rst_n = (atpg_mode == 1'b1)? 1'b1 : rst_n;


// clock mux (between user and test clock) - use clock MUX
// c3adapt_cmn_clkmux2 altr_ckmux21_inst(
c3lib_mux2_ctn altr_ckmux21_inst(
  .ck_out  (out_clk),
  .ck0     (int_user_clk),
  .ck1     (int_test_clk),
  .s0      (clk_sel)
);

// scan control registers
c3aibadapt_cmn_occ_test_ctlregs ctl_reg (
  .clk   (test_clk),
  .rst_n (occ_rst_n),
  .ctrl  (burst_cnt)
//  .clken (test_clk_en)
);

//test clock enable
generate
if(CONTROL_REGISTER_PRESENT == 1) begin : CONTROL_REG
  reg test_clken /* synopsys preserve_sequential */;
  always @(posedge test_clk)
    test_clken <= test_clken;

  // c3adapt_cmn_occ_clkgate altr_clkgate_test_inst (
  //    .clk          (test_clk),
  //    .clk_enable_i (test_clken),
  //    .clk_o        (int_test_clk)
  // );
  c3lib_ckg_posedge_ctn altr_clkgate_test_inst (
    .gated_clk    (int_test_clk),
    .clk          (test_clk),
    .clk_en       (test_clken),
    .tst_en       (1'b0)
  );
end
else begin
  assign int_test_clk = test_clk;
end

endgenerate

// user clock enable
// c3adapt_cmn_occ_clkgate altr_clkgate_user_inst(
//    .clk          (user_clk),
//    .clk_enable_i (occ_user_clken),
//    .clk_o        (int_user_clk)
// );
c3lib_ckg_posedge_ctn altr_clkgate_user_inst(
  .gated_clk    (int_user_clk),
  .clk          (user_clk),
  .clk_en       (occ_user_clken),
  .tst_en       (int_user_clk)
);

c3aibadapt_cmn_occ_enable_logic occ_enable_logic_inst(

    .user_clk (user_clk),
    .scan_enable (scan_enable),
    .occ_enable (occ_enable),
    .atpg_mode (atpg_mode),
    .burst_cnt (burst_cnt),
    .occ_user_clken (occ_user_clken)
);

endmodule
module c3aibadapt_cmn_parity_gen
    #(
	parameter WIDTH = 'd0   
    )   
    (
        output  wire			parity,
        input   wire [WIDTH-1:0]    	data
    );

	assign parity = ^data[WIDTH-1:0];

endmodule // c3aibadapt_cmn_parity_gen
module c3aibadapt_cmn_pulse_stretch 
  #(
    parameter RESET_VAL = 'd0   // reset value
    )
  (
    input  wire         clk,         // clock
    input  wire         rst_n,       // async reset
    input  wire [2:0]   num_stages,  // number of stages required
    input  wire         data_in,     // data in
    output  reg         data_out     // stretched data out             
   );

   reg                  data_d1, data_d2, data_d3, data_d4;
   reg                  data_d5, data_d6, data_d7;
   reg                  data_out_comb;

   localparam reset_value = (RESET_VAL == 1) ? 1'b1 : 1'b0;  // To eliminate truncating warning
      
   always @* begin
      data_out_comb = data_in;
      
      case (num_stages)
        3'b000: data_out_comb = data_in;
        3'b001: data_out_comb = data_d1 | data_in;
        3'b010: data_out_comb = data_d2 | data_d1 | data_in;
        3'b011: data_out_comb = data_d3 | data_d2 | data_d1 | data_in;
        3'b100: data_out_comb = data_d4 | data_d3 | data_d2 | data_d1 | data_in;
        3'b101: data_out_comb = data_d5 | data_d4 | data_d3 | data_d2 | data_d1 | data_in;
        3'b110: data_out_comb = data_d6 | data_d5 | data_d4 | data_d3 | data_d2 | data_d1 | data_in;
        3'b111: data_out_comb = data_d7 | data_d6 | data_d5 | data_d4 | data_d3 | data_d2 | data_d1 | data_in;
        default: data_out_comb = data_in;
      endcase // case(num_stages)
   end // always @ *

   always @(negedge rst_n or posedge clk) begin
      if (~rst_n) begin
         data_d1 <= reset_value;
         data_d2 <= reset_value;
         data_d3 <= reset_value;
         data_d4 <= reset_value;
         data_d5 <= reset_value;
         data_d6 <= reset_value;
         data_d7 <= reset_value;
         data_out <= reset_value;
      end
      else begin
         data_d1 <= data_in;
         data_d2 <= data_d1;
         data_d3 <= data_d2;
         data_d4 <= data_d3;
         data_d5 <= data_d4;
         data_d6 <= data_d5;
         data_d7 <= data_d6;
         data_out <= data_out_comb;
      end
   end // always @ (negedge rst_n or posedge clk)
      
endmodule // c3aibadapt_cmn_pulse_stretch
module c3aibadapt_cmn_latency_measure 
   (
   // Inputs
   input  wire              s_clk,      	  // clock
   input  wire              s_rst_n,       // async reset
   input  wire [1:0]	    r_fifo_power_mode,
   input  wire              wr_addr_msb, 	// Write address MSB
   input  wire              rd_addr_msb, 	// Read address MSB
   input  wire              ps_wr_addr_msb, 	// Write address MSB
   input  wire              ps_rd_addr_msb, 	// Read address MSB

   // Outputs
   output reg  		    latency_pulse       // Latency pulse
   );


wire			    rd_addr_msb_sync;
wire			    wr_addr_msb_sync;

wire			    ps_rd_addr_msb_sync;
wire			    ps_wr_addr_msb_sync;


// hd_dpcmn_bitsync2 
c3lib_bitsync 
  #(
    .SRC_DATA_FREQ_MHZ (100), // Source data freq 
    .DST_CLK_FREQ_MHZ  (300), // Destination clock freq
    .DWIDTH            (1),   // Sync Data input 
    .RESET_VAL         (0)    // Reset Value 
   )
 bitsync2_wr (
   .clk      (s_clk),
   .rst_n    (s_rst_n),
   .data_in  (wr_addr_msb),
   .data_out (wr_addr_msb_sync)
   );

// hd_dpcmn_bitsync2 
c3lib_bitsync 
  #(
    .SRC_DATA_FREQ_MHZ (100), // Source data freq 
    .DST_CLK_FREQ_MHZ  (300), // Destination clock freq
    .DWIDTH            (1),   // Sync Data input 
    .RESET_VAL         (0)    // Reset Value 
  )
  bitsync2_rd
  (
   .clk       (s_clk),
   .rst_n     (s_rst_n),
   .data_in  (rd_addr_msb),
   .data_out (rd_addr_msb_sync)
   );

// hd_dpcmn_bitsync2 
c3lib_bitsync 
  #(
    .SRC_DATA_FREQ_MHZ (100), // Source data freq 
    .DST_CLK_FREQ_MHZ  (300), // Destination clock freq
    .DWIDTH            (1),   // Sync Data input 
    .RESET_VAL         (0)    // Reset Value 
  )
  bitsync2_ps_wr_msb
    (
     .clk       (s_clk),
     .rst_n     (s_rst_n),
     .data_in  (ps_wr_addr_msb),
     .data_out (ps_wr_addr_msb_sync)
    );

// hd_dpcmn_bitsync2 
c3lib_bitsync 
  #(
    .SRC_DATA_FREQ_MHZ (100), // Source data freq 
    .DST_CLK_FREQ_MHZ  (300), // Destination clock freq
    .DWIDTH            (1),   // Sync Data input 
    .RESET_VAL         (0)    // Reset Value 
  )
  bitsync2_ps_rd_msb
      (
       .clk       (s_clk),
       .rst_n     (s_rst_n),
       .data_in  (ps_rd_addr_msb),
       .data_out (ps_rd_addr_msb_sync)
       );
   
always @(negedge s_rst_n or posedge s_clk) begin
   if (~s_rst_n) begin
      latency_pulse      <= 1'b0;
   end
   else begin
      latency_pulse      <= r_fifo_power_mode[1] ? wr_addr_msb_sync ^ rd_addr_msb_sync : ps_wr_addr_msb_sync ^ ps_rd_addr_msb_sync;
   end
end

endmodule
module c3aibadapt_cmn_occ_enable_logic(

     user_clk,
     scan_enable,
     occ_enable,
     atpg_mode,
     burst_cnt,
     occ_user_clken
);

input user_clk;
input scan_enable;
input atpg_mode;
input occ_enable;
input [1:0] burst_cnt;
output occ_user_clken;

wire [1:0] gc_counter;
wire cmp;
wire reset;
reg occ_user_clk_en_reg;
wire occ_user_clk_en_buf;
wire sync_out;
wire scan_enable;
wire atpg_mode;
wire occ_enable;
wire occ_clken;
wire gc_counter_en;
reg  enable_reg;

//Inversion for all the control signal
//assign scan_enable = ~scan_enable_n;
//assign atpg_mode = ~atpg_mode_n;
//assign occ_enable = ~occ_enable_n;

assign reset = ~scan_enable;                
assign cmp = |(gc_counter ^ burst_cnt);     //comparison of the gc counter versus the burst cnt
assign gc_counter_en = sync_out & cmp;      //enabling the gc counter
assign occ_user_clken = (atpg_mode == 1'b1)?  occ_user_clk_en_reg : 1'b1;



always @(posedge occ_enable or negedge reset)
begin
  if(~reset)
    enable_reg <= 1'b0;
  else
    enable_reg <= 1'b1;
end


always @(posedge user_clk or negedge reset )
begin
  if(~reset)
    occ_user_clk_en_reg <= 1'b0;
  else
    occ_user_clk_en_reg <= gc_counter_en;
end


//sycnronization register
// hd_dpcmn_bitsync3 altr_bitsync3_inst(
c3lib_sync3_ulvt_bitsync altr_bitsync3_inst(
  .clk      (user_clk),
  .rst_n    (reset),
  .data_in  (enable_reg),
  .data_out (sync_out)
);

//gray code counter
c3aibadapt_cmn_occ_gray_cntr counter_inst (
  .clk   (user_clk),
  .rst_n (reset),
  .en    (gc_counter_en),
  .cout   (gc_counter)
);

endmodule
module c3aibadapt_cmn_async_capture_bus 
   #(
      parameter RESET_VAL     = 1, // 1: Active high; 0: Active low
      parameter DWIDTH           = 2,  // Sync Data input 
      parameter SYNC_STAGE    = 2
    )
   (
   // Inputs
   input  wire               clk,      	  // clock
   input  wire               rst_n,       // async reset
   input  wire [DWIDTH-1:0]  data_in,     // data in
   input  wire		     unload,      // unload data out
   input  wire		     r_capt_mode,      // capture mode
   // Outputs
   output reg  [DWIDTH-1:0]  data_out     // data out
   );

//******************************************************************************
// Define regs
//******************************************************************************
reg  [DWIDTH-1:0]		data_in_sync_d0;
reg  [DWIDTH-1:0]		data_in_sync_d1;
wire [DWIDTH-1:0] 		data_in_sync;
reg				sample;

   localparam reset_value = (RESET_VAL == 1) ? 1'b1 : 1'b0;  // To eliminate truncating warning


generate
if (SYNC_STAGE == 3) begin
   c3lib_sync3_ulvt_bitsync
   #(
   .DWIDTH             (DWIDTH),                 // Sync Data input
   .RESET_VAL          (reset_value)             //  Reset value
   )
   ulvt_bitsync3
     (
     .clk      (clk),
     .rst_n    (rst_n),
     .data_in  (data_in),
     .data_out (data_in_sync)
     );
end
else begin
   c3lib_bitsync
   #(
   .SRC_DATA_FREQ_MHZ  (500),         // Source clock frequency
   .DST_CLK_FREQ_MHZ   (1000),        // Destination clock frequency
   .DWIDTH             (DWIDTH),      // Sync Data input
   .RESET_VAL          (reset_value)  //  Reset value
   )
   lvt_bitsync2
     (
     .clk      (clk),
     .rst_n    (rst_n),
     .data_in  (data_in),
     .data_out (data_in_sync)
     );
end
endgenerate


   always @(negedge rst_n or posedge clk) begin
      if (rst_n == 1'b0) begin
        begin
          data_in_sync_d0 	<= {DWIDTH{reset_value}};
          data_in_sync_d1 	<= {DWIDTH{reset_value}};
        end
     end
     else begin
          data_in_sync_d0 	<= data_in_sync;
          data_in_sync_d1 	<= data_in_sync_d0;
        end
   end        
     
     
     
   always @(negedge rst_n or posedge clk) begin
      if (rst_n == 1'b0) begin
        begin
          sample 		<= 1'b0;
          data_out 		<= {DWIDTH{reset_value}};
        end
     end
     else begin
     // No sample during unload
         if (unload) begin
           sample <= 1'b0;
         end
     // Sample on the first data change after unload      
         else begin  
           if (r_capt_mode) begin
             if (~sample)   
               sample   <= 1'b1;
               data_out <= data_in_sync;
           end
           else begin
             if  (~sample && data_in_sync == data_in_sync_d0 && data_in_sync_d0 == data_in_sync_d1) begin
               sample   <= 1'b1;
               data_out <= data_in_sync_d1;
             end
           end
           
         end  
     end
   end

endmodule
module c3aibadapt_cmn_occ_test_ctlregs (
  clk,
  rst_n,
  ctrl
//  clken
);

input clk;
input rst_n;
output [1:0] ctrl;
//output clken;

// test clock enable
//reg clken /* synopsys preserve_sequential */;

//always @(posedge clk)
//begin
//  clken <= clken;
//end

// counter logic
reg [1:0] ctrl /* synopsys preserve_sequential */;

always @(posedge clk or negedge rst_n)
begin
  if(rst_n == 1'b0)
    ctrl <= 2'b00;
  else
    ctrl <= ctrl;
end

endmodule
module c3aibadapt_cmn_cp_dist
  #(
    parameter ASYNC_RESET_VAL = 'd0,   // Asynchronous reset value
    parameter WIDTH           = 'd1    // Control width
    )
    (
    input  wire                clk,                      // clock
    input  wire                rst_n,                    // async reset
    input  wire                srst_n,                   // sync reset
    input wire                 data_enable,              // data enable / data valid
    input  wire [WIDTH-1:0]    master_in,                // master control signal
    input  wire [WIDTH-1:0]    dist_in,                  // CP distributed signal in 
    input  wire                r_dist_master,            // CRAM to control master or distributed
    input  wire                r_dist_bypass_pipeln,     // CRAM combo or registered
    output  wire [WIDTH-1:0]   dist_out,                 // CP distributed signal out
    output  wire [WIDTH-1:0]   dist_tap                  // CP output for this channel
     );

   reg [WIDTH-1:0]          dist_1;
   reg [WIDTH-1:0]          dist_2;

   reg [WIDTH-1:0]         dist_1_in;
   reg [WIDTH-1:0]          dist_2_in;
   reg [WIDTH-1:0]          dist_1_out;
   reg [WIDTH-1:0]          dist_2_out;


   // module outputs
   assign  dist_tap = dist_1_out;
   assign  dist_out = dist_2_out;
   
   
   always @*
     begin
        // default FF inputs to FF outputs
        dist_1_in = dist_1;
        dist_2_in = dist_2;

        // default stage outputs to FF outputs
        dist_1_out = dist_1;
        dist_2_out = dist_2;

        // set FF inputs
        if (data_enable)
          begin
             dist_1_in = dist_in;
             if (r_dist_master)
               begin
                  dist_2_in = master_in;
               end
             else
               begin
                  dist_2_in = dist_1_out;
               end
          end // if (data_enable)
        
        // set stage outputs
        if (r_dist_bypass_pipeln)
          begin
             dist_1_out = dist_in;
             if (r_dist_master)
               begin
                  dist_2_out = master_in;
               end
             else
               begin
                  dist_2_out = dist_1_out;
               end
          end // if (r_dist_bypass_pipeln)
        else
          begin
             dist_1_out = dist_1;
             dist_2_out = dist_2;
          end

     end // always @ *
      
   
   always @(negedge rst_n or posedge clk)
     begin
        if (~rst_n)
          begin
             dist_1 <= {WIDTH{ASYNC_RESET_VAL}};
             dist_2 <= {WIDTH{ASYNC_RESET_VAL}};
          end
        else if (~srst_n)
          begin
             dist_1 <= {WIDTH{ASYNC_RESET_VAL}};
             dist_2 <= {WIDTH{ASYNC_RESET_VAL}};
          end
        else 
          begin
             dist_1 <= dist_1_in;
             dist_2 <= dist_2_in;
          end
     end // always @ (negedge rst_n or posedge clk)

   
endmodule // c3aibadapt_cmn_cp_dist
module c3aibadapt_cmn_cp_comp_cntr
  #(
    parameter CNTWIDTH         = 'd8
    )
    (
    input  wire                clk,             // clock
    input  wire                rst_n,           // async reset
    input  wire                srst_n,          // async reset
    input  wire                data_enable,     // data enable / data valid
    input  wire                master_in_en,    
    input  wire                us_tap_en,   
    input  wire                ds_tap_en,  
    input  wire [1:0]          r_compin_sel,    // CRAM input select
    input  wire [CNTWIDTH-1:0] r_comp_cnt,      // CRAM timeout value
    output  reg                comp_cnt_match,   // output signal for match
    output wire		       compin_sel	 
     );

   localparam                  MASTER	         = 2'd0;
   localparam                  SLAVE_ABOVE		 = 2'd1;
   localparam                  SLAVE_BELOW		 = 2'd2;
   
   reg [CNTWIDTH-1:0] cnt, cnt_ns;
   reg                cnt_co;
   reg                cnt_enable;
//   reg		      cnt_enable_reg;
//   wire		      cnt_enable_neg_edge;

   always @*
     begin
        cnt_enable = master_in_en;
        cnt_ns = cnt;
        cnt_co = 1'b0;
        comp_cnt_match = 1'b0;
                        
        case (r_compin_sel)
          MASTER: begin
             cnt_enable = master_in_en;
          end
          SLAVE_ABOVE: begin
             cnt_enable = us_tap_en;
          end
          SLAVE_BELOW: begin
             cnt_enable = ds_tap_en;
          end
          default: begin
             cnt_enable = master_in_en;
          end
        endcase // case(r_compin_sel)

        
        if (cnt == r_comp_cnt && cnt_enable)
          begin
             comp_cnt_match = 1'b1;
          end
        else if (data_enable && cnt_enable && cnt != r_comp_cnt)
          begin
             {cnt_co,cnt_ns} = cnt + 1'b1;
          end
        
     end // always @ *

assign compin_sel = cnt_enable;

//   always @(negedge rst_n or posedge clk)
//     begin
//        if (~rst_n)
//          begin
//             cnt_enable_reg <= 1'b0;
//          end
//        else if (~srst_n)
//          begin
//             cnt_enable_reg <= 1'b0;
//          end
//        else 
//          begin
//             cnt_enable_reg <= cnt_enable;
//          end
//     end // always @ (negedge rst_n or posedge clk)               
// 
//   assign cnt_enable_neg_edge = ~cnt_enable && cnt_enable_reg;

   always @(negedge rst_n or posedge clk)
     begin
        if (~rst_n)
          begin
             cnt <= {CNTWIDTH{1'b0}};
          end
//        else if (~srst_n || cnt_enable_neg_edge)
        else if (~srst_n)
          begin
             cnt <= {CNTWIDTH{1'b0}};
          end
        else 
          begin
             cnt <= cnt_ns;
          end
     end // always @ (negedge rst_n or posedge clk)               
   
endmodule // c3aibadapt_cmn_cp_comp_cntr
module c3aibadapt_cmn_cp_dist_pair_dw
  #(
    parameter ASYNC_RESET_VAL = 'd0,   // Asynchronous reset value
    parameter WIDTH         = 'd1   // Control width
    )
    (
    input  wire                clk,                        // clock 
    input  wire                rst_n,                      // async reset
    input  wire                srst_n,                     // sync reset
    input wire                 data_enable,                // data enable / data valid
    input  wire [WIDTH-1:0]    master_in,                  // master control signal
    input  wire [WIDTH-1:0]    us_in,                  // CP distributed signal in up
    input  wire [WIDTH-1:0]    ds_in,                 // CP distributed signal in dwn
    input  wire                r_us_master,            // CRAM to control master or distributed up
    input  wire                r_ds_master,           // CRAM to control master or distributed dwn
    input  wire                r_us_bypass_pipeln,     // CRAM combo or registered up
    input  wire                r_ds_bypass_pipeln,    // CRAM combo or registered dwn
    input  wire                r_double_en,              // CRAM double mode enable
    output  wire [WIDTH-1:0]   us_out,                 // CP distributed signal out up
    output  wire [WIDTH-1:0]   ds_out,                // CP distributed signal out dwn
    output  wire [WIDTH-1:0]   ds_tap,                // CP output for this channel dwn 
    output  wire [WIDTH-1:0]   us_tap                  // CP output for this channel up
     );

   c3aibadapt_cmn_cp_dist_dw
     #(
       .ASYNC_RESET_VAL (ASYNC_RESET_VAL),
       .WIDTH         (WIDTH)
       )
       adapt_cmn_cp_dist_dw_dwn
         (
          .clk                  (clk),
          .rst_n                (rst_n), 
          .srst_n               (srst_n), 
          .data_enable          (data_enable),
          .master_in            (master_in),
          .dist_in              (us_in),
          .r_dist_master        (r_ds_master),
          .r_dist_bypass_pipeln (r_ds_bypass_pipeln),
          .r_double_en		(r_double_en),
          .dist_out             (ds_out),
          .dist_tap             (ds_tap)
          );

   c3aibadapt_cmn_cp_dist_dw
     #(
       .ASYNC_RESET_VAL (ASYNC_RESET_VAL),
       .WIDTH         (WIDTH)
       )
       adapt_cmn_cp_dist_dw_up
         (
          .clk                  (clk),
          .rst_n                (rst_n),
          .srst_n               (srst_n), 
          .data_enable          (data_enable),
          .master_in            (master_in),
          .dist_in              (ds_in),
          .r_dist_master        (r_us_master),
          .r_dist_bypass_pipeln (r_us_bypass_pipeln),
          .r_double_en		(r_double_en),
          .dist_out             (us_out),
          .dist_tap             (us_tap)
          );
   
   
endmodule // c3aibadapt_cmn_cp_dist_pair
module c3aibadapt_cmn_clkand2
(
        output  wire    Z,
        input   wire    A1,
        input   wire    A2
);

	assign Z = A1 & A2;

endmodule // c3adapt_cmn_clkand2
module c3aibadapt_cmn_dprio_status_sync_regs 
#(
   parameter DATA_WIDTH         = 16,  // Data width
   parameter BYPASS_STAT_SYNC   = 0    // Parameter to bypass the Synchronization SM in case of individual status bits
 )
(
input  wire                                 rst_n,         // reset
input  wire                                 clk,           // clock
input  wire [DATA_WIDTH-1:0]                stat_data_in,  // status data input
input  wire                                 write_en_ack,  // write data acknowlege from user logic

output reg                                  write_en,      // write data enable to user logic
output reg  [DATA_WIDTH-1:0]                stat_data_out  // status data output

);

//********************************************************************
// Define Parameters 
//********************************************************************
 localparam  WE_LOCAL        = 2'b00;
 localparam  CDC_WE_ACK      = 2'b01;
 localparam  CDC_WE_N_ACK    = 2'b10;

wire       write_en_ack_sync;
reg  [1:0] cdc_cs;
reg  [1:0] cdc_ns;
reg        write_en_comb;
reg        write_en_local_comb;
reg        write_en_local;

// Bit sync for write_en_ack
// hd_dpcmn_bitsync2 
c3lib_bitsync #( .DWIDTH (1), .RESET_VAL (0), .DST_CLK_FREQ_MHZ (400), .SRC_DATA_FREQ_MHZ (200))
   write_en_ack_sync_1 (
    .clk  (clk),                  // read clock
    .rst_n(rst_n),                // async reset for read clock domain
    .data_in (write_en_ack),      // data in
    .data_out(write_en_ack_sync)  // data out
   );

// Registering data_in with write_en
always @(negedge rst_n or posedge clk)
  if (rst_n == 1'b0)
    begin
      stat_data_out   <= {DATA_WIDTH{1'b0}};
    end
  else if (write_en_local == 1'b1)
    begin      
      stat_data_out <= stat_data_in;
    end

// CDC SM
// Output
always @(negedge rst_n or posedge clk)
  if (rst_n == 1'b0)
    begin
      write_en       <= 1'b0;
      write_en_local <= 1'b0;
      cdc_cs         <= WE_LOCAL;
    end
  else if (BYPASS_STAT_SYNC == 1'b1)
    begin
      write_en       <= 1'b1;
      write_en_local <= 1'b1;
      cdc_cs         <= WE_LOCAL;
    end  
  else
    begin      
      write_en       <= write_en_comb;
      write_en_local <= write_en_local_comb;
      cdc_cs         <= cdc_ns;      
    end

// SM
always @ (*)
  begin
    cdc_ns              = cdc_cs;
    write_en_comb       = 1'b0;
    write_en_local_comb = 1'b0;
    
    case (cdc_cs)
      WE_LOCAL:
        begin
          write_en_local_comb = 1'b1;
          cdc_ns              = CDC_WE_ACK;
        end

      CDC_WE_ACK:
        begin
          write_en_comb       = 1'b1;
          if (write_en_ack_sync == 1'b1)
            begin
              cdc_ns          = CDC_WE_N_ACK;
            end
        end

      CDC_WE_N_ACK:
        begin
          if (write_en_ack_sync == 1'b0)
            begin
              cdc_ns          = WE_LOCAL;
            end
        end
        
      default:
        begin
          cdc_ns          = WE_LOCAL;
          write_en_comb       = 1'b0;
          write_en_local_comb = 1'b0;          
        end
      endcase        
  end

endmodule
module c3aibadapt_cmn_async_capture_bit 
   #(
      parameter RESET_VAL     = 0,  // 1: Active high; 0: Active low
      parameter SYNC_STAGE    = 2
    )
   (
   // Inputs
   input  wire               clk,      	  // clock
   input  wire               rst_n,       // async reset
   input  wire  	     data_in,     // data in
   input  wire		     unload,      // unload data out
   // Outputs
   output wire   	     data_in_sync_out, // data out
   output reg   	     data_out     // data out
   );

//******************************************************************************
// Define regs
//******************************************************************************
wire  				data_in_sync;
reg				sample;

localparam reset_value = (RESET_VAL == 1) ? 1'b1 : 1'b0;  // To eliminate truncating warning

generate
if (SYNC_STAGE == 3) begin
// hd_dpcmn_bitsync3
c3lib_sync3_ulvt_bitsync
  #(
  .DWIDTH      (1'b1),         // Sync Data input
  .RESET_VAL   (reset_value)   // Reset value
  )
  ulvt_bitsync3
    (
    .clk      (clk),
    .rst_n    (rst_n),
    .data_in  (data_in),
    .data_out (data_in_sync)
    );
end
else begin
// hd_dpcmn_bitsync2
c3lib_bitsync
  #(
  .SRC_DATA_FREQ_MHZ  (500),         // Source clock frequency
  .DST_CLK_FREQ_MHZ   (1000),        // Destination clock frequency
  .DWIDTH             (1'b1),      // Sync Data input
  .RESET_VAL          (reset_value)  //  Reset value
  )
  lvt_bitsync2
    (
    .clk      (clk),
    .rst_n    (rst_n),
    .data_in  (data_in),
    .data_out (data_in_sync)
    );
end
endgenerate

assign data_in_sync_out = data_in_sync;

always @(negedge rst_n or posedge clk) begin
   if (rst_n == 1'b0) begin
     begin
       sample 		<= 1'b0;
       data_out 	<= reset_value;
     end
  end
  else begin
  // No sample during unload
      if (unload) begin
        sample <= 1'b0;
      end
  // Sample on the first data change after unload      
      else if (sample == 1'b0 && data_in_sync != data_out) begin
        sample   <= 1'b1;
        data_out 		<= data_in_sync;
      end  
  end
end

endmodule
module c3aibadapt_cmn_clkmux2
(
        output  wire    clk_o,
        input   wire    clk_0,
        input   wire    clk_1,
        input   wire    clk_sel
);

c3aibadapt_cmn_clkmux2_cell adapt_cmn_clkmux2_cell
    (
        .S(clk_sel),
        .I0(clk_0),
        .I1(clk_1),
        .Z(clk_o)
    );

endmodule // c3aibadapt_cmn_clkmux2
module c3aibadapt_cmn_clkmux2_cell
(
        output  wire    Z,
        input   wire    I0,
        input   wire    I1,
        input   wire    S
);

      assign Z = S ? I1 : I0;

endmodule // c3aibadapt_cmn_clkmux2_cell
module c3aibadapt_cmn_occ_gray_cntr (
  clk,
  rst_n,
  en,
  cout
);


input clk;
input rst_n;
input en;
output [1:0] cout;

reg [1:0] counter_reg;

always @(posedge clk or negedge rst_n)
begin
  if(rst_n == 1'b0)
    counter_reg <= 2'b00;
  else
  begin
    if(en == 1'b1)
      counter_reg <= counter_reg + 1;
    else
      counter_reg <= counter_reg;
  end
end

// need auto-code generator for different WIDTH
assign cout = {counter_reg[1],counter_reg[1]^counter_reg[0]};

endmodule
module c3aibadapt_cmn_clkgate_high
(
	input	wire		cpn,
	input	wire		e,
	input	wire		te,
	output	wire		q
);

	wire	clk;
	wire	clken;
	reg	latch_clken;

	assign clk = cpn;
	assign clken = e || te;

        always @(clk or clken)
        begin
		if (clk)
                begin
                        latch_clken <= clken;
                end
        end

	assign q = clk | ~latch_clken;

endmodule // c3aibadapt_cmn_clkgate_high