dakies/OSS_Verilog huggingface dataset:
module FAST9_Top (clock, nReset, refAddr, outPixel);
	input clock;
	input nReset;
	output [14:0] refAddr;
	output [7:0] outPixel;
	
	wire isCorner; // 코너 확인
	wire [31:0] compare; // DARK, BRIGHT, SIMILAR 값
	wire [14:0] refAddr; // 기준점 주소
	wire [7:0] refPixel; // 기준점 데이터
	wire [127:0] adjPixel; // 인접한 16개의 점 데이터
	wire [7:0] thres; // 임계값
	wire [14:0] outAddr; // 최종 코너 주소
	wire [7:0] outPixel; // 최종 코너 데이터
	wire [14:0] scoreAddr; // Score Memory 주소
	wire [7:0] scoreValue; // Score Memory에 저장할 값
	wire [7:0] scoreData; // Score Memory에서 Read한 값
	wire wren; // Score Memeory 쓰기 신호
	
	// Feature Detection
	FD_Top fd(
		.clock(clock), 
		.nReset(nReset),
		.isCorner(isCorner),
		.refAddr(refAddr),
		.refPixel(refPixel),
		.adjPixel(adjPixel),
		.thres(thres),
		.compare(compare)
	);
	
	// Feature Score
	FS_Top fs(
		.isCorner(isCorner),
		.compare(compare),
		.refAddr(refAddr),
		.refPixel(refPixel),
		.adjPixel(adjPixel),
		.thres(thres),
		.scoreValue(scoreValue),
		.wren(wren)
	);
	
	// Non-Maximal Suppression
	NMS_Top nms(
		.clock(clock),
		.nReset(nReset),
		.refAddr(refAddr),
		.refPixel(refPixel),
		.scoreData(scoreData),
		.scoreAddr(scoreAddr),
		.outAddr(outAddr),
		.outPixel(outPixel)
	);
	
	// Score Memory
	FS_ScoreMem scoreMem(
		.clock(clock),
		.address(scoreAddr),
		.data(scoreValue),
		.wren(wren),
		.q(scoreData)
	);
endmodule
module Buffer (
	address,
	clock,
	data,
	wren,
	q);

	input	[14:0]  address;
	input	  clock;
	input	[7:0]  data;
	input	  wren;
	output	[7:0]  q;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_off
`endif
	tri1	  clock;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_on
`endif

endmodule
module Testbench_SramTest;
	reg clock;
	reg wren;
	reg [14:0] address;
	reg [7:0] data;
	wire [7:0] read;
	
	always begin
		#50 clock = ~clock;
		$display($time, "%d : %b : %h", read, read, read);
	end
		
	always @ (posedge clock)
		address <= address + 1;
		
	SRAM sram(
		.clock(clock), 
		.address(address), 
		.data(data),
		.wren(wren),
		.q(read)
	);
	
	initial begin
		wren = 1'b0;
		clock = 1'b0;
		address = 15'b0;
		data = 8'b00110000;
		
		#21600 $finish;
	end
endmodule
module Accelerator_Top (clock, nReset, position, isMatching);
	input clock;
	input nReset;
	output [239:0] position;
	output isMatching;
	
	wire [14:0] outAddr;
	wire [7:0] outPixel;

	FAST9_Top fast9(
		.clock(clock),
		.nReset(nReset),
		.refAddr(outAddr),
		.outPixel(outPixel)
	);
	
	Mat_Top matching(
		.clock(clock),
		.nReset(nReset),
		.refAddr(outAddr),
		.isFeature(outPixel),
		.position(position),
		.isMatching(isMatching)
	);
endmodule
module FD_Top (clock, nReset, isCorner, refAddr, refPixel, adjPixel, thres, compare);
	input clock;
	input nReset;
	output isCorner; // Corner 확인
	output [14:0] refAddr; // 기준점 주소
	output [7:0] refPixel; // 기준점 데이터
	output [127:0] adjPixel; // 인접한 16개의 점 데이터
	output [7:0] thres; // 임계값
	output [31:0] compare;
	
	wire [4:0] adjNumber; // 1~16개의 인접한 점
	wire [4:0] regAddr; // 레지스터 주소
	wire [14:0] sramAddr; // SRAM 주소
	wire [7:0] sramData; // SRAM Output 데이터
	
	// Controller, 기준점과 인접한 16개의 주소를 얻어, 레지스터에 저장하는 과정을 제어
	FD_Controller controller(
		.clock(clock),
		.nReset(nReset),
		.refAddr(refAddr), 
		.adjNumber(adjNumber),
		.regAddr(regAddr),
		.readen(readen)
	);
	
	// 기준점으로 부터 인접한 16개의 점을 계산
	FD_AddrCal addrCal(
		.refAddr(refAddr),
		.adjNumber(adjNumber),
		.sramAddr(sramAddr)
	);

	// 이미지 데이터가 저장된 SRAM
	SRAM sram(
		.clock(clock),
		.address(sramAddr),
		.data(8'bx),
		.wren(1'b0),
		.q(sramData)
	);

	// 기준점과 인접한 16개의 점을 저장할 레지스터 파일
	FD_Reg fd_reg(
		.clock(clock),
		.nReset(nReset),
		.readen(readen),
		.regAddr(regAddr),
		.sramData(sramData),
		.refPixel(refPixel),
		.adjPixel(adjPixel),
		.thres(thres)
	);
	
	// 레지스터에 저장된 기준점과 인접한 16개의 점의 데이터를 이용하여 코너 확인
	FD_Datapath datapath(
		.refPixel(refPixel),
		.adjPixel(adjPixel),
		.thres(thres),
		.isCorner(isCorner),
		.compare(compare)
	);
endmodule
module spi_slave
#(
  parameter DEPTH = 64
)
(
  // sys connect
  input              clk,
  input              rst,

  // spi slave port
  input              ss,
  input              mosi,
  output             miso,
  input              sck,

  // parallel data io port
  output             parallel_stb,
  input [DEPTH-1:0]  parallel_din,
  output [DEPTH-1:0] parallel_dout
);
  reg mosi_d, mosi_q;
  reg ss_d, ss_q;
  reg sck_d, sck_q;
  reg sck_old_d, sck_old_q;
  reg miso_d, miso_q;

  reg [DEPTH-1:0] data_d, data_q;
  reg             parallel_stb_d, parallel_stb_q;
  reg [`LOG2(DEPTH)-1:0] bit_ct_d, bit_ct_q;
  reg [DEPTH-1:0] parallel_dout_d, parallel_dout_q;

  assign miso = miso_q;
  assign parallel_stb = parallel_stb_q;
  assign parallel_dout = parallel_dout_q;

  always @(*) begin
    ss_d            = ss;
    mosi_d          = mosi;
    miso_d          = miso_q;
    sck_d           = sck;
    sck_old_d       = sck_q;
    data_d          = data_q;
    parallel_stb_d  = 1'b0;
    bit_ct_d        = bit_ct_q;
    parallel_dout_d = parallel_dout_q;

    if (ss_q) begin
      bit_ct_d = 'h0;
      data_d   = parallel_din;
      miso_d   = data_q[DEPTH-1];
    end
    else begin
      if (!sck_old_q && sck_q) begin // rising edge
        data_d   = {data_q[DEPTH-1-1:0], mosi_q};
        bit_ct_d = bit_ct_q + 1'b1;
        if (bit_ct_q == (DEPTH - 1)) begin
          parallel_dout_d = {data_q[DEPTH-1-1:0], mosi_q};
          parallel_stb_d          = 1'b1;
          data_d          = parallel_din;
        end
      end
      else if (sck_old_q && !sck_q) begin // falling edge
        miso_d = data_q[DEPTH-1];
      end
    end
  end

  always @(posedge clk) begin
    if (rst) begin
      parallel_stb_q          <= 1'b0;
      bit_ct_q        <= 'h0;
      parallel_dout_q <= 'h0;
      miso_q          <= 1'b1;
    end else begin
      parallel_stb_q  <= parallel_stb_d;
      bit_ct_q        <= bit_ct_d;
      parallel_dout_q <= parallel_dout_d;
      miso_q          <= miso_d;
    end

    sck_q     <= sck_d;
    mosi_q    <= mosi_d;
    ss_q      <= ss_d;
    data_q    <= data_d;
    sck_old_q <= sck_old_d;
  end

endmodule
module S6CLK2PIN
(
    input I,
    output O
);

    ODDR2 #(
           .DDR_ALIGNMENT("NONE"), // to "NONE", "C0" or "C1"
           .INIT(1'b0),            // output to 1'b0 or 1'b1
           .SRTYPE("ASYNC"))        // set/reset "SYNC" or "ASYNC"

         ODDR2_S6CLK2PIN
           (
        .Q(O),  // 1-bit DDR output data
        .C0(I), // 1-bit clock input
        .C1(~I), // 1-bit clock input
        .CE(1'b1), // 1-bit clock enable input
        .D0(1'b1), // 1-bit data input (associated with C0)
        .D1(1'b0), // 1-bit data input (associated with C1)
        .R(1'b0),  // 1-bit reset input
        .S(1'b0) );// 1-bit set input

endmodule //S6CLK2PIN
module b205_clk_gen
 (// Clock in ports
  input         CLK_IN1_40,
  // Clock out ports
  output        CLK_OUT1_40_int,
  output        CLK_OUT2_100_bus,
  output        CLK_OUT3_200_ref_pll,
  // Status and control signals
  input         RESET,
  output        LOCKED
 );

  // Input buffering
  //------------------------------------
  IBUFG clkin1_buf
   (.O (clkin1),
    .I (CLK_IN1_40));


  // Clocking primitive
  //------------------------------------
  // Instantiation of the PLL primitive
  //    * Unused inputs are tied off
  //    * Unused outputs are labeled unused
  wire [15:0] do_unused;
  wire        drdy_unused;
  wire        clkfbout;
  wire        clkfbout_buf;
  wire        clkout3_unused;
  wire        clkout4_unused;
  wire        clkout5_unused;

  PLL_BASE
  #(.BANDWIDTH              ("OPTIMIZED"),
    .CLK_FEEDBACK           ("CLKFBOUT"),
    .COMPENSATION           ("SYSTEM_SYNCHRONOUS"),
    .DIVCLK_DIVIDE          (1),
    .CLKFBOUT_MULT          (10),
    .CLKFBOUT_PHASE         (0.000),
    .CLKOUT0_DIVIDE         (10),
    .CLKOUT0_PHASE          (0.000),
    .CLKOUT0_DUTY_CYCLE     (0.500),
    .CLKOUT1_DIVIDE         (4),
    .CLKOUT1_PHASE          (0.000),
    .CLKOUT1_DUTY_CYCLE     (0.500),
    .CLKOUT2_DIVIDE         (2),
    .CLKOUT2_PHASE          (0.000),
    .CLKOUT2_DUTY_CYCLE     (0.500),
    .CLKIN_PERIOD           (25.0),
    .REF_JITTER             (0.010))
  pll_base_inst
    // Output clocks
   (.CLKFBOUT              (clkfbout),
    .CLKOUT0               (clkout0),
    .CLKOUT1               (clkout1),
    .CLKOUT2               (clkout2),
    .CLKOUT3               (clkout3_unused),
    .CLKOUT4               (clkout4_unused),
    .CLKOUT5               (clkout5_unused),
    // Status and control signals
    .LOCKED                (LOCKED),
    .RST                   (RESET),
     // Input clock control
    .CLKFBIN               (clkfbout_buf),
    .CLKIN                 (clkin1));


  // Output buffering
  //-----------------------------------
  BUFG clkf_buf
   (.O (clkfbout_buf),
    .I (clkfbout));

  BUFG clkout1_buf
   (.O   (CLK_OUT1_40_int),
    .I   (clkout0));


  BUFG clkout2_buf
   (.O   (CLK_OUT2_100_bus),
    .I   (clkout1));

  BUFG clkout3_buf
   (.O   (CLK_OUT3_200_ref_pll),
    .I   (clkout2));



endmodule
module chipscope_icon(
    CONTROL0) /* synthesis syn_black_box syn_noprune=1 */;


inout [35 : 0] CONTROL0;

endmodule
module chipscope_ila(
    CONTROL,
    CLK,
    TRIG0) /* synthesis syn_black_box syn_noprune=1 */;


inout [35 : 0] CONTROL;
input CLK;
input [127 : 0] TRIG0;

endmodule
module b205_clk_gen_tb ();

  // Clock to Q delay of 100ps
  localparam  TCQ              = 100;


  // timescale is 1ps/1ps
  localparam  ONE_NS      = 1000;
  localparam  PHASE_ERR_MARGIN   = 100; // 100ps
  // how many cycles to run
  localparam  COUNT_PHASE = 1024;
  // we'll be using the period in many locations
  localparam time PER1    = 25.0*ONE_NS;
  localparam time PER1_1  = PER1/2;
  localparam time PER1_2  = PER1 - PER1/2;

  // Declare the input clock signals
  reg         CLK_IN1     = 1;

  // The high bits of the sampling counters
  wire [3:1]  COUNT;
  // Status and control signals
  reg         RESET      = 0;
  wire        LOCKED;
  reg         COUNTER_RESET = 0;
wire [3:1] CLK_OUT;
//Freq Check using the M & D values setting and actual Frequency generated


  // Input clock generation
  //------------------------------------
  always begin
    CLK_IN1 = #PER1_1 ~CLK_IN1;
    CLK_IN1 = #PER1_2 ~CLK_IN1;
  end

  // Test sequence
  reg [15*8-1:0] test_phase = "";
  initial begin
    // Set up any display statements using time to be readable
    $timeformat(-12, 2, "ps", 10);
    COUNTER_RESET = 0;
    test_phase = "reset";
    RESET = 1;
    #(PER1*6);
    RESET = 0;
    test_phase = "wait lock";
    `wait_lock;
    #(PER1*6);
    COUNTER_RESET = 1;
    #(PER1*20)
    COUNTER_RESET = 0;

    test_phase = "counting";
    #(PER1*COUNT_PHASE);

    $display("SIMULATION PASSED");
    $display("SYSTEM_CLOCK_COUNTER : %0d\n",$time/PER1);
    $finish;
  end

  // Instantiation of the example design containing the clock
  //    network and sampling counters
  //---------------------------------------------------------
  b205_clk_gen_exdes 
  #(
    .TCQ (TCQ)
   ) dut
   (// Clock in ports
    .CLK_IN1            (CLK_IN1),
    // Reset for logic in example design
    .COUNTER_RESET      (COUNTER_RESET),
    .CLK_OUT            (CLK_OUT),
    // High bits of the counters
    .COUNT              (COUNT),
    // Status and control signals
    .RESET              (RESET),
    .LOCKED             (LOCKED));

// Freq Check 

endmodule
module b205_clk_gen_tb ();

  // Clock to Q delay of 100ps
  localparam  TCQ              = 100;


  // timescale is 1ps/1ps
  localparam  ONE_NS      = 1000;
  localparam  PHASE_ERR_MARGIN   = 100; // 100ps
  // how many cycles to run
  localparam  COUNT_PHASE = 1024;
  // we'll be using the period in many locations
  localparam time PER1    = 25.0*ONE_NS;
  localparam time PER1_1  = PER1/2;
  localparam time PER1_2  = PER1 - PER1/2;

  // Declare the input clock signals
  reg         CLK_IN1     = 1;

  // The high bits of the sampling counters
  wire [3:1]  COUNT;
  // Status and control signals
  reg         RESET      = 0;
  wire        LOCKED;
  reg         COUNTER_RESET = 0;
wire [3:1] CLK_OUT;
//Freq Check using the M & D values setting and actual Frequency generated 

  reg [13:0]  timeout_counter = 14'b00000000000000;

  // Input clock generation
  //------------------------------------
  always begin
    CLK_IN1 = #PER1_1 ~CLK_IN1;
    CLK_IN1 = #PER1_2 ~CLK_IN1;
  end

  // Test sequence
  reg [15*8-1:0] test_phase = "";
  initial begin
    // Set up any display statements using time to be readable
    $timeformat(-12, 2, "ps", 10);
    $display ("Timing checks are not valid");
    COUNTER_RESET = 0;
    test_phase = "reset";
    RESET = 1;
    #(PER1*6);
    RESET = 0;
    test_phase = "wait lock";
    `wait_lock;
    #(PER1*6);
    COUNTER_RESET = 1;
    #(PER1*19.5)
    COUNTER_RESET = 0;
    #(PER1*1)
    $display ("Timing checks are valid");
    test_phase = "counting";
    #(PER1*COUNT_PHASE);

    $display("SIMULATION PASSED");
    $display("SYSTEM_CLOCK_COUNTER : %0d\n",$time/PER1);
    $finish;
  end


   always@(posedge CLK_IN1) begin
      timeout_counter <= timeout_counter + 1'b1;
      if (timeout_counter == 14'b10000000000000) begin
         if (LOCKED != 1'b1) begin
            $display("ERROR : NO LOCK signal");
            $display("SYSTEM_CLOCK_COUNTER : %0d\n",$time/PER1);
            $finish;
         end
      end
   end

  // Instantiation of the example design containing the clock
  //    network and sampling counters
  //---------------------------------------------------------
  b205_clk_gen_exdes 
    dut
   (// Clock in ports
    .CLK_IN1            (CLK_IN1),
    // Reset for logic in example design
    .COUNTER_RESET      (COUNTER_RESET),
    .CLK_OUT            (CLK_OUT),
    // High bits of the counters
    .COUNT              (COUNT),
    // Status and control signals
    .RESET              (RESET),
    .LOCKED             (LOCKED));


// Freq Check 

endmodule
module ten_gige_phy_clk_gen 
(
   input  areset,
   input  refclk_p,
   input  refclk_n,

   output refclk,
   output clk156,
   output dclk
);

   wire clk156_buf;
   wire dclk_buf;
   wire clkfbout;
   
   IBUFDS_GTE2 ibufds_inst (
      .O     (refclk),
      .ODIV2 (),
      .CEB   (1'b0),
      .I     (refclk_p),
      .IB    (refclk_n)
   );

   BUFG clk156_bufg_inst (
      .I (refclk),
      .O (clk156) 
   );

   // Divding independent clock by 2 as source for DRP clock
   BUFR # (
      .BUFR_DIVIDE ("2")
   ) dclk_divide_by_2_buf (
      .I   (clk156),
      .O   (dclk_buf),
      .CE  (1'b1),
      .CLR (1'b0)
   );

   BUFG dclk_bufg_i (
      .I (dclk_buf),
      .O (dclk)
   );

endmodule
module one_gige_phy_clk_gen 
(
   input  refclk_p,
   input  refclk_n,
   output refclk,
   output refclk_bufg
);

   IBUFDS_GTE2 ibufds_inst (
      .O     (refclk),
      .ODIV2 (),
      .CEB   (1'b0),
      .I     (refclk_p),
      .IB    (refclk_n)
   );

   BUFG bufg_gtrefclk_inst (
      .I(refclk),
      .O(refclk_bufg)
   );

endmodule
module aurora_phy_clk_gen 
(
   input  areset,
   input  refclk_p,
   input  refclk_n,

   output refclk,
   output clk156,
   output init_clk
);

   wire clk156_buf;
   wire init_clk_buf;
   wire clkfbout;
   
   IBUFDS_GTE2 ibufds_inst (
      .O     (refclk),
      .ODIV2 (),
      .CEB   (1'b0),
      .I     (refclk_p),
      .IB    (refclk_n)
   );

   BUFG clk156_bufg_inst (
      .I (refclk),
      .O (clk156) 
   );

   // Divding independent clock by 2 as source for DRP clock
   BUFR # (
      .BUFR_DIVIDE ("2")
   ) dclk_divide_by_2_buf (
      .I   (clk156),
      .O   (init_clk_buf),
      .CE  (1'b1),
      .CLR (1'b0)
   );

   BUFG dclk_bufg_i (
      .I (init_clk_buf),
      .O (init_clk)
   );

endmodule
module ten_gige_phy_clk_gen
(
   input refclk_ibuf,
   output clk156,
   output dclk
);

   wire dclk_buf;

   BUFG clk156_bufg_inst (
      .I (refclk_ibuf),
      .O (clk156)
   );

   // Dividing independent clock by 2 as source for DRP clock
   BUFR # (
      .BUFR_DIVIDE ("2")
   ) dclk_divide_by_2_buf (
      .I   (clk156),
      .O   (dclk_buf),
      .CE  (1'b1),
      .CLR (1'b0)
   );

   BUFG dclk_bufg_i (
      .I (dclk_buf),
      .O (dclk)
   );

endmodule
module multi_stream_add
  #(parameter WIDTH = 40,
    parameter NUM_INPUTS = 16,
    parameter LOG_INPUTS = $clog2(NUM_INPUTS))(
  input clk, input rst, input drop,
  input [NUM_INPUTS*WIDTH-1:0] i_tdata, input [NUM_INPUTS-1:0] i_tlast,
  input [NUM_INPUTS-1:0] i_tvalid, output [NUM_INPUTS-1:0] i_tready,
  output [LOG_INPUTS+WIDTH-1:0] sum_tdata,  output sum_tlast,
  output sum_tvalid,  input sum_tready
  );

  reg [LOG_INPUTS+WIDTH:0] full_sum;
  wire [NUM_INPUTS-1:0] i_tready_int;
  wire [NUM_INPUTS-1:0] i_tvalid_int;
  reg [NUM_INPUTS-1:0] drop_reg;

  assign sum_tdata = full_sum;

  genvar s;
  generate
    for (s = 0; s < (NUM_INPUTS); s = s + 1) begin
      always @(posedge clk)
        if (rst)
          drop_reg[s] <= 1'b0;
        else if (i_tvalid[s] & i_tlast[s] & i_tready[s] & drop)
          drop_reg[s] <= 1'b1;
        else if (drop_reg[s])
          drop_reg[s] <= drop;
        else
          drop_reg[s] <= 1'b0;

  // Drop incoming bad packets
  // Start Dropping : After tlast is asserted
  // Stop Dropping  : Immediately
    assign i_tready[s]     = (drop & drop_reg[s]) ? {NUM_INPUTS{1'b1}} : i_tready_int[s];
    assign i_tvalid_int[s] = (drop & drop_reg[s]) ? {NUM_INPUTS{1'b0}} : i_tvalid[s];
    end
  endgenerate

  axi_join #(.INPUTS(NUM_INPUTS)) aj_inst (
    .i_tlast(i_tlast), .i_tvalid(i_tvalid_int), .i_tready(i_tready_int),
    .o_tlast(sum_tlast), .o_tvalid(sum_tvalid), .o_tready(sum_tready));

  integer i;
  reg [LOG_INPUTS+WIDTH:0] temp_data;
  always @* begin
    temp_data = 0;
    for (i = 0; i < NUM_INPUTS; i = i + 1) begin
      temp_data = temp_data + {{LOG_INPUTS{i_tdata[i*WIDTH+WIDTH-1]}}, i_tdata[i*WIDTH +: WIDTH]};

      end
    full_sum = temp_data;
    end

endmodule
module rhodium_lo_gain #(
  parameter TABLE_NUM = 2'b01
) (
  input  wire       ctrl_sck,
  input  wire       ctrl_csb,
  input  wire       ctrl_mosi,
  output reg        ctrl_miso,
  output wire [4:0] dsa,
  output reg        dsa1_le,
  output reg        dsa2_le
);

localparam CNT_GAIN1_DRIVE = 10,
           CNT_DSA1_LE_RISE = 11,
           CNT_DSA1_LE_FALL = 14,
           CNT_GAIN1_RELEASE = 17;
localparam CNT_GAIN2_DRIVE = 17,
           CNT_DSA2_LE_RISE = 18,
           CNT_DSA2_LE_FALL = 21,
           CNT_GAIN2_RELEASE = 24;

reg  [4:0]  ctrl_bit_cnt;
reg  [1:0]  ctrl_tbl;
reg  [5:0]  ctrl_index;
reg  [5:0]  gain1, gain2;
reg gain1_t;
reg gain2_t;

assign dsa = (!gain1_t | !gain2_t) ? ctrl_index[4:0] : 5'b11111;

// Cycle counter for where we are in protocol and shift register for input
// Also controls timing of DSAs' latch enable signals
always @ (posedge ctrl_sck or posedge ctrl_csb)
begin
  if (ctrl_csb) begin
    ctrl_bit_cnt <= 5'd0;
    dsa1_le      <= 1'b0;
    dsa2_le      <= 1'b0;
    gain1_t      <= 1'b1;
    gain2_t      <= 1'b1;
  end else if (!ctrl_csb) begin
    if (ctrl_bit_cnt < 23) begin
      ctrl_bit_cnt <= ctrl_bit_cnt + 5'd1;
    end

    if (ctrl_bit_cnt < 8) begin
      {ctrl_tbl, ctrl_index} <= {ctrl_tbl[0], ctrl_index, ctrl_mosi};
    end

    if (ctrl_tbl == TABLE_NUM) begin
      if ((ctrl_bit_cnt == CNT_GAIN1_DRIVE) && (ctrl_mosi)) begin
        gain1   <= ctrl_index;
        gain1_t <= 1'b0;
      end else if ((gain1_t == 1'b0) && (ctrl_bit_cnt == CNT_DSA1_LE_RISE)) begin
        dsa1_le <= 1'b1;
      end else if ((gain1_t == 1'b0) && (ctrl_bit_cnt == CNT_DSA1_LE_FALL)) begin
        dsa1_le <= 1'b0;
      end else if ((gain1_t == 1'b0) && (ctrl_bit_cnt == CNT_GAIN1_RELEASE)) begin
        gain1_t <= 1'b1;
      end

      if ((ctrl_bit_cnt == CNT_GAIN2_DRIVE) && (ctrl_mosi)) begin
        gain2   <= ctrl_index;
        gain2_t <= 1'b0;
      end else if ((gain2_t == 1'b0) && (ctrl_bit_cnt == CNT_DSA2_LE_RISE)) begin
        dsa2_le <= 1'b1;
      end else if ((gain2_t == 1'b0) && (ctrl_bit_cnt == CNT_DSA2_LE_FALL)) begin
        dsa2_le <= 1'b0;
      end else if ((gain2_t == 1'b0) && (ctrl_bit_cnt == CNT_GAIN2_RELEASE)) begin
        gain2_t <= 1'b1;
      end
    end
  end
end

// SPI readback for ctrl bus, based on current bit count
always @ (negedge ctrl_sck)
begin
  case (ctrl_bit_cnt) // Shift out on neg edge
  11:      ctrl_miso <= gain1[5];
  12:      ctrl_miso <= gain1[4];
  13:      ctrl_miso <= gain1[3];
  14:      ctrl_miso <= gain1[2];
  15:      ctrl_miso <= gain1[1];
  16:      ctrl_miso <= gain1[0];
  18:      ctrl_miso <= gain2[5];
  19:      ctrl_miso <= gain2[4];
  20:      ctrl_miso <= gain2[3];
  21:      ctrl_miso <= gain2[2];
  22:      ctrl_miso <= gain2[1];
  23:      ctrl_miso <= gain2[0];
  default: ctrl_miso <= 1'b0;
  endcase
end


endmodule // rhodium_lo_gain
module rhodium_gain_table
(
  input wire        wr_clk,
  input wire        wr_en,
  input wire  [6:0] wr_addr,
  input wire  [9:0] wr_data,

  // Read data for wr_addr (read-first/read-before-write): One cycle latency
  output wire [9:0] wr_data_prev,

  input wire        rd_clk,
  input wire  [6:0] rd_addr,
  output wire [9:0] rd_data // Read data for rd_addr: One cycle latency
);

reg [15:0] gain_table[127:0];
reg [15:0] wr_data_prev_r;
reg [15:0] rd_data_r;

assign wr_data_prev = wr_data_prev_r[15:6];
assign rd_data      = rd_data_r[15:6];

always @ (posedge wr_clk)
begin
  if (wr_en)
    gain_table[wr_addr] <= {wr_data, 6'b0};
  wr_data_prev_r <= gain_table[wr_addr];
end

always @ (posedge rd_clk)
begin
  rd_data_r <= gain_table[rd_addr];
end


endmodule // rhodium_gain_table
module aurora_phy_mmcm 
(
   input  aurora_tx_clk_unbuf,
   input  mmcm_reset,
   output user_clk,
   output sync_clk,
   output mmcm_locked
);

  wire mmcm_fb_clk;
  wire user_clk_i;
  wire sync_clk_i;
  wire aurora_tx_clk;

  BUFG txout_clock_net_i (
    .I(aurora_tx_clk_unbuf),
    .O(aurora_tx_clk)
  );

  localparam MULT        = 10;
  localparam DIVIDE      = 5;
  localparam CLK_PERIOD  = 3.103;
  localparam OUT0_DIVIDE = 4;
  localparam OUT1_DIVIDE = 2;
  localparam OUT2_DIVIDE = 6;
  localparam OUT3_DIVIDE = 8;

  MMCME2_ADV #(
    .BANDWIDTH            ("OPTIMIZED"),
    .CLKOUT4_CASCADE      ("FALSE"),
    .COMPENSATION         ("ZHOLD"),
    .STARTUP_WAIT         ("FALSE"),
    .DIVCLK_DIVIDE        (DIVIDE),
    .CLKFBOUT_MULT_F      (MULT),
    .CLKFBOUT_PHASE       (0.000),
    .CLKFBOUT_USE_FINE_PS ("FALSE"),
    .CLKOUT0_DIVIDE_F     (OUT0_DIVIDE),
    .CLKOUT0_PHASE        (0.000),
    .CLKOUT0_DUTY_CYCLE   (0.500),
    .CLKOUT0_USE_FINE_PS  ("FALSE"),
    .CLKIN1_PERIOD        (CLK_PERIOD),
    .CLKOUT1_DIVIDE       (OUT1_DIVIDE),
    .CLKOUT1_PHASE        (0.000),
    .CLKOUT1_DUTY_CYCLE   (0.500),
    .CLKOUT1_USE_FINE_PS  ("FALSE"),
    .CLKOUT2_DIVIDE       (OUT2_DIVIDE),
    .CLKOUT2_PHASE        (0.000),
    .CLKOUT2_DUTY_CYCLE   (0.500),
    .CLKOUT2_USE_FINE_PS  ("FALSE"),
    .CLKOUT3_DIVIDE       (OUT3_DIVIDE),
    .CLKOUT3_PHASE        (0.000),
    .CLKOUT3_DUTY_CYCLE   (0.500),
    .CLKOUT3_USE_FINE_PS  ("FALSE"),
    .REF_JITTER1          (0.010)
  ) mmcm_adv_inst (
    .CLKFBOUT            (mmcm_fb_clk),
    .CLKFBOUTB           (),
    .CLKOUT0             (user_clk_i),
    .CLKOUT0B            (),
    .CLKOUT1             (sync_clk_i),
    .CLKOUT1B            (),
    .CLKOUT2             (),
    .CLKOUT2B            (),
    .CLKOUT3             (),
    .CLKOUT3B            (),
    .CLKOUT4             (),
    .CLKOUT5             (),
    .CLKOUT6             (),
     // Input clock control
    .CLKFBIN             (mmcm_fb_clk),
    .CLKIN1              (aurora_tx_clk),
    .CLKIN2              (1'b0),
     // Tied to always select the primary input clock
    .CLKINSEL            (1'b1),
    // Ports for dynamic reconfiguration
    .DADDR               (7'h0),
    .DCLK                (1'b0),
    .DEN                 (1'b0),
    .DI                  (16'h0),
    .DO                  (),
    .DRDY                (),
    .DWE                 (1'b0),
    // Ports for dynamic phase shift
    .PSCLK               (1'b0),
    .PSEN                (1'b0),
    .PSINCDEC            (1'b0),
    .PSDONE              (),
    // Other control and status signals
    .LOCKED              (mmcm_locked),
    .CLKINSTOPPED        (),
    .CLKFBSTOPPED        (),
    .PWRDWN              (1'b0),
    .RST                 (mmcm_reset)
  );

  BUFG user_clk_net_i (
     .I(user_clk_i),
     .O(user_clk)
  );
  BUFG sync_clock_net_i (
     .I(sync_clk_i),
     .O(sync_clk)
  );
endmodule
module aurora_phy_clk_gen 
(
   input refclk_ibuf,
   output clk156,
   output init_clk
);

   wire init_clk_buf;

   BUFG clk156_bufg_inst (
      .I (refclk_ibuf),
      .O (clk156) 
   );

   // Divding independent clock by 2 as source for DRP clock
   BUFR # (
      .BUFR_DIVIDE ("2")
   ) dclk_divide_by_2_buf (
      .I   (clk156),
      .O   (init_clk_buf),
      .CE  (1'b1),
      .CLR (1'b0)
   );

   BUFG dclk_bufg_i (
      .I (init_clk_buf),
      .O (init_clk)
   );

endmodule
module b200_chipscope_ila(
    CONTROL,
    CLK,
    DATA,
    TRIG0) /* synthesis syn_black_box syn_noprune=1 */;


inout [35 : 0] CONTROL;
input CLK;
input [63 : 0] DATA;
input [7 : 0] TRIG0;

endmodule
module chipscope_ila_32(
    CONTROL,
    CLK,
    TRIG0) /* synthesis syn_black_box syn_noprune=1 */;


inout [35 : 0] CONTROL;
input CLK;
input [31 : 0] TRIG0;

endmodule
module chipscope_ila_256(
    CONTROL,
    CLK,
    TRIG0) /* synthesis syn_black_box syn_noprune=1 */;


inout [35 : 0] CONTROL;
input CLK;
input [255 : 0] TRIG0;

endmodule
module chipscope_ila_128(
    CONTROL,
    CLK,
    TRIG0) /* synthesis syn_black_box syn_noprune=1 */;


inout [35 : 0] CONTROL;
input CLK;
input [127 : 0] TRIG0;

endmodule
module b200_chipscope_icon(
    CONTROL0) /* synthesis syn_black_box syn_noprune=1 */;


inout [35 : 0] CONTROL0;

endmodule
module b200_clk_gen
 (// Clock in ports
  input         CLK_IN1_40_P,
  input         CLK_IN1_40_N,
  // Clock out ports
  output        CLK_OUT1_40_int,
  output        CLK_OUT2_100_gpif,
  output        CLK_OUT3_100_bus,
  // Status and control signals
  input         RESET,
  output        LOCKED
 );

  // Input buffering
  //------------------------------------
  IBUFGDS clkin1_buf
   (.O  (clkin1),
    .I  (CLK_IN1_40_P),
    .IB (CLK_IN1_40_N));


  // Clocking primitive
  //------------------------------------

  // Instantiation of the DCM primitive
  //    * Unused inputs are tied off
  //    * Unused outputs are labeled unused
  wire        psdone_unused;
  wire        locked_int;
  wire [7:0]  status_int;
  wire clkfb;
  wire clk0;
  wire clkfx;

  DCM_SP
  #(.CLKDV_DIVIDE          (2.000),
    .CLKFX_DIVIDE          (2),
    .CLKFX_MULTIPLY        (5),
    .CLKIN_DIVIDE_BY_2     ("FALSE"),
    .CLKIN_PERIOD          (25.0),
    .CLKOUT_PHASE_SHIFT    ("NONE"),
    .CLK_FEEDBACK          ("1X"),
    .DESKEW_ADJUST         ("SYSTEM_SYNCHRONOUS"),
    .PHASE_SHIFT           (0),
    .STARTUP_WAIT          ("FALSE"))
  dcm_sp_inst
    // Input clock
   (.CLKIN                 (clkin1),
    .CLKFB                 (clkfb),
    // Output clocks
    .CLK0                  (clk0),
    .CLK90                 (),
    .CLK180                (),
    .CLK270                (),
    .CLK2X                 (),
    .CLK2X180              (),
    .CLKFX                 (clkfx),
    .CLKFX180              (),
    .CLKDV                 (),
    // Ports for dynamic phase shift
    .PSCLK                 (1'b0),
    .PSEN                  (1'b0),
    .PSINCDEC              (1'b0),
    .PSDONE                (),
    // Other control and status signals
    .LOCKED                (locked_int),
    .STATUS                (status_int),
 
    .RST                   (RESET),
    // Unused pin- tie low
    .DSSEN                 (1'b0));

    assign LOCKED = locked_int;

  // Output buffering
  //-----------------------------------
  assign clkfb = CLK_OUT1_40_int;

  BUFG clkout1_buf
   (.O   (CLK_OUT1_40_int),
    .I   (clk0));


  BUFG clkout2_buf
   (.O   (CLK_OUT2_100_gpif),
    .I   (clkfx));

  BUFG clkout3_buf
   (.O   (CLK_OUT3_100_bus),
    .I   (clkfx));



endmodule
module b200_clk_gen_tb ();

  // Clock to Q delay of 100ps
  localparam  TCQ              = 100;


  // timescale is 1ps/1ps
  localparam  ONE_NS      = 1000;
  localparam  PHASE_ERR_MARGIN   = 100; // 100ps
  // how many cycles to run
  localparam  COUNT_PHASE = 1024;
  // we'll be using the period in many locations
  localparam time PER1    = 25.0*ONE_NS;
  localparam time PER1_1  = PER1/2;
  localparam time PER1_2  = PER1 - PER1/2;

  // Declare the input clock signals
  reg         CLK_IN1     = 1;
  wire        CLK_IN1_P   =  CLK_IN1;
  wire        CLK_IN1_N   = ~CLK_IN1;

  // The high bits of the sampling counters
  wire [3:1]  COUNT;
  // Status and control signals
  reg         RESET      = 0;
  wire        LOCKED;
  reg         COUNTER_RESET = 0;
wire [3:1] CLK_OUT;
//Freq Check using the M & D values setting and actual Frequency generated


  // Input clock generation
  //------------------------------------
  always begin
    CLK_IN1 = #PER1_1 ~CLK_IN1;
    CLK_IN1 = #PER1_2 ~CLK_IN1;
  end

  // Test sequence
  reg [15*8-1:0] test_phase = "";
  initial begin
    // Set up any display statements using time to be readable
    $timeformat(-12, 2, "ps", 10);
    COUNTER_RESET = 0;
    test_phase = "reset";
    RESET = 1;
    #(PER1*6);
    RESET = 0;
    test_phase = "wait lock";
    `wait_lock;
    #(PER1*6);
    COUNTER_RESET = 1;
    #(PER1*20)
    COUNTER_RESET = 0;

    test_phase = "counting";
    #(PER1*COUNT_PHASE);

    $display("SIMULATION PASSED");
    $display("SYSTEM_CLOCK_COUNTER : %0d\n",$time/PER1);
    $finish;
  end

  // Instantiation of the example design containing the clock
  //    network and sampling counters
  //---------------------------------------------------------
  b200_clk_gen_exdes 
  #(
    .TCQ (TCQ)
   ) dut
   (// Clock in ports
    .CLK_IN1_P          (CLK_IN1_P),
    .CLK_IN1_N          (CLK_IN1_N),
    // Reset for logic in example design
    .COUNTER_RESET      (COUNTER_RESET),
    .CLK_OUT            (CLK_OUT),
    // High bits of the counters
    .COUNT              (COUNT),
    // Status and control signals
    .RESET              (RESET),
    .LOCKED             (LOCKED));

// Freq Check 

endmodule
module b200_clk_gen_tb ();

  // Clock to Q delay of 100ps
  localparam  TCQ              = 100;


  // timescale is 1ps/1ps
  localparam  ONE_NS      = 1000;
  localparam  PHASE_ERR_MARGIN   = 100; // 100ps
  // how many cycles to run
  localparam  COUNT_PHASE = 1024;
  // we'll be using the period in many locations
  localparam time PER1    = 25.0*ONE_NS;
  localparam time PER1_1  = PER1/2;
  localparam time PER1_2  = PER1 - PER1/2;

  // Declare the input clock signals
  reg         CLK_IN1     = 1;
  wire        CLK_IN1_P   =  CLK_IN1;
  wire        CLK_IN1_N   = ~CLK_IN1;

  // The high bits of the sampling counters
  wire [3:1]  COUNT;
  // Status and control signals
  reg         RESET      = 0;
  wire        LOCKED;
  reg         COUNTER_RESET = 0;
wire [3:1] CLK_OUT;
//Freq Check using the M & D values setting and actual Frequency generated 

  reg [13:0]  timeout_counter = 14'b00000000000000;

  // Input clock generation
  //------------------------------------
  always begin
    CLK_IN1 = #PER1_1 ~CLK_IN1;
    CLK_IN1 = #PER1_2 ~CLK_IN1;
  end

  // Test sequence
  reg [15*8-1:0] test_phase = "";
  initial begin
    // Set up any display statements using time to be readable
    $timeformat(-12, 2, "ps", 10);
    $display ("Timing checks are not valid");
    COUNTER_RESET = 0;
    test_phase = "reset";
    RESET = 1;
    #(PER1*6);
    RESET = 0;
    test_phase = "wait lock";
    `wait_lock;
    #(PER1*6);
    COUNTER_RESET = 1;
    #(PER1*19.5)
    COUNTER_RESET = 0;
    #(PER1*1)
    $display ("Timing checks are valid");
    test_phase = "counting";
    #(PER1*COUNT_PHASE);

    $display("SIMULATION PASSED");
    $display("SYSTEM_CLOCK_COUNTER : %0d\n",$time/PER1);
    $finish;
  end


   always@(posedge CLK_IN1) begin
      timeout_counter <= timeout_counter + 1'b1;
      if (timeout_counter == 14'b10000000000000) begin
         if (LOCKED != 1'b1) begin
            $display("ERROR : NO LOCK signal");
            $display("SYSTEM_CLOCK_COUNTER : %0d\n",$time/PER1);
            $finish;
         end
      end
   end

  // Instantiation of the example design containing the clock
  //    network and sampling counters
  //---------------------------------------------------------
  b200_clk_gen_exdes 
    dut
   (// Clock in ports
    .CLK_IN1_P          (CLK_IN1_P),
    .CLK_IN1_N          (CLK_IN1_N),
    // Reset for logic in example design
    .COUNTER_RESET      (COUNTER_RESET),
    .CLK_OUT            (CLK_OUT),
    // High bits of the counters
    .COUNT              (COUNT),
    // Status and control signals
    .RESET              (RESET),
    .LOCKED             (LOCKED));


// Freq Check 

endmodule
module zf_slave_settings
#(
    parameter CONFIG_BASE = 32'h40000000
)
(
    input clk,
    input rst,

    //------------------------------------------------------------------
    //-- control write signals - slave
    //------------------------------------------------------------------
    input [31:0] AXI_AWADDR,
    input AXI_AWVALID,
    output AXI_AWREADY,
    input [31:0] AXI_WDATA,
    input [3:0] AXI_WSTRB,
    input AXI_WVALID,
    output AXI_WREADY,
    output [1:0] AXI_BRESP,
    output AXI_BVALID,
    input AXI_BREADY,

    //------------------------------------------------------------------
    // settings interface
    //------------------------------------------------------------------
    output reg [31:0] addr,
    output reg [31:0] data,
    output strobe,

    output [31:0] debug
);

////////////////////////////////////////////////////////////////////////
///////////////////////////// Begin R T L //////////////////////////////
////////////////////////////////////////////////////////////////////////

    //------------------------------------------------------------------
    // Control write state machine responds to AXI control writes
    // Used for setting the state of the various FIFOs
    //------------------------------------------------------------------
    localparam STATE_ADDR = 0;
    localparam STATE_DATA = 1;
    localparam STATE_WRITE = 2;

    reg [1:0] state;

    always @(posedge clk) begin
        if (rst) begin
            state <= STATE_ADDR;
            addr <= 0;
            data <= 0;
        end
        else case (state)

        STATE_ADDR: begin
            if (AXI_AWVALID && AXI_AWREADY) begin
                addr <= (AXI_AWADDR - CONFIG_BASE);
                state <= STATE_DATA;
            end
        end

        STATE_DATA: begin
            if (AXI_WVALID && AXI_WREADY) begin
                data <= AXI_WDATA;
                state <= STATE_WRITE;
            end
        end

        STATE_WRITE: begin
            state <= STATE_ADDR;
        end

        default: state <= STATE_ADDR;

        endcase //state
    end

    assign strobe = (state == STATE_WRITE);

    //assign to slave write
    assign AXI_AWREADY = (state == STATE_ADDR);
    assign AXI_WREADY = (state == STATE_DATA);
    assign AXI_BRESP = 0;
    assign AXI_BVALID = AXI_BREADY; //FIXME - we can choose not to assert valid

endmodule //zf_slave_settings
module zf_slave_readback
#(
    parameter CONFIG_BASE = 32'h40000000
)
(
    input clk,
    input rst,

    //------------------------------------------------------------------
    //-- control read signals - slave
    //------------------------------------------------------------------
    input [31:0] AXI_ARADDR,
    input AXI_ARVALID,
    output AXI_ARREADY,
    output [31:0] AXI_RDATA,
    output [1:0] AXI_RRESP,
    output AXI_RVALID,
    input AXI_RREADY,

    //------------------------------------------------------------------
    // readback interface
    //------------------------------------------------------------------
    output reg [31:0] addr,
    input [31:0] data,
    output strobe,

    output [31:0] debug
);

////////////////////////////////////////////////////////////////////////
///////////////////////////// Begin R T L //////////////////////////////
////////////////////////////////////////////////////////////////////////

    //------------------------------------------------------------------
    // Control read state machine responds to AXI control reads
    // Used for reading back the state of the various FIFOs
    //------------------------------------------------------------------
    localparam STATE_ADDR = 0;
    localparam STATE_READ = 1;
    localparam STATE_DATA = 2;

    reg [3:0] state;

    always @(posedge clk) begin
        if (rst) begin
            state <= STATE_ADDR;
            addr <= 0;
        end
        else case (state)

        STATE_ADDR: begin
            if (AXI_ARVALID && AXI_ARREADY) begin
                state <= STATE_READ;
                addr <= (AXI_ARADDR - CONFIG_BASE);
            end
        end

        STATE_READ: begin
            state <= STATE_DATA;
        end

        STATE_DATA: begin
            if (AXI_RVALID && AXI_RREADY) begin
                state <= STATE_ADDR;
            end
        end

        default: state <= STATE_ADDR;

        endcase //state
    end

    assign strobe = AXI_RVALID && AXI_RREADY;

    //readback data
    assign AXI_RDATA = data;
    //only acking address reads from the wait state
    assign AXI_ARREADY = (state == STATE_ADDR);
    //when to release outputs from the slave
    assign AXI_RVALID = (state == STATE_DATA);
    assign AXI_RRESP = 0;

endmodule //zf_slave_readback
module cvita_dest_lookup_legacy
#(
    parameter DEST_WIDTH = 4
)
(
    input clk, input rst,
    input set_stb, input [7:0] set_addr, input [DEST_WIDTH-1:0] set_data,
    input [63:0] i_tdata, input i_tlast, input i_tvalid, output i_tready,
    output [63:0] o_tdata, output o_tlast, output o_tvalid, input o_tready,
    output [DEST_WIDTH-1:0] o_tdest
);

    reg [7:0] endpoint;
    ram_2port #(.DWIDTH(DEST_WIDTH), .AWIDTH(8)) dest_lut
    (
        .clka(clk), .ena(1'b1), .wea(set_stb), .addra(set_addr), .dia(set_data), .doa(),
        .clkb(clk), .enb(1'b1), .web(1'b0), .addrb(endpoint), .dib(8'hff), .dob(o_tdest)
    );

    reg forward;
    reg [1:0] count;
    always @(posedge clk) begin
        if (rst) begin
            forward <= 1'b0;
            count <= 2'b0;
        end
        else if (forward == 1'b0 && i_tvalid) begin
            if (count == 2'b11) forward <= 1'b1;
            endpoint <= i_tdata[23:16];
            count <= count + 1'b1;
        end
        else if (forward == 1'b1 && i_tvalid && i_tready && i_tlast) begin
            forward <= 1'b0;
            count <= 2'b0;
        end
    end

    assign o_tdata = i_tdata;
    assign o_tlast = i_tlast;
    assign o_tvalid = i_tvalid && forward;
    assign i_tready = o_tready && forward;

endmodule // cvita_dest_lookup_legacy
module ioport2_msg_decode(
    input  [63:0]   message,
    output          rd_response,
    output          wr_request,
    output          rd_request,
    output          half_word,
    output [19:0]   address,
    output [31:0]   data,
    output [31:0]   control    
);
    assign rd_response  = message[63];
    assign wr_request   = message[62];
    assign rd_request   = message[61];
    assign half_word    = message[60];
    assign address      = message[51:32];
    assign data         = message[31:0];
    assign control      = message[63:32];
endmodule
module ioport2_msg_encode(
    input          rd_response,
    input          wr_request,
    input          rd_request,
    input          half_word,
    input  [19:0]  address,
    input  [31:0]  data,
    output [31:0]  control,
    output [63:0]  message
);
    assign control = rd_response ? {rd_response, 31'h0} : {rd_response, wr_request, rd_request, half_word, 8'h00, address};
    assign message = {control, data};
endmodule
module data_swapper_64 (
   input  wire         clk,
   input  wire [2:0]   swap_lanes,

   input  wire [63:0]  i_tdata,
   input  wire         i_tlast,
   input  wire         i_tvalid,
   output wire         i_tready,
   output wire [63:0]  o_tdata,
   output wire         o_tlast,
   output wire         o_tvalid,
   input  wire         o_tready
);
   localparam SWAP_32B = 3'b100;
   localparam SWAP_16B = 3'b010;
   localparam SWAP_8B  = 3'b001;

   wire [63:0] data_p1, data_p2;

   assign data_p1 = (|(swap_lanes & SWAP_32B)) ? { i_tdata[31:0], i_tdata[63:32] } : i_tdata;
   assign data_p2 = (|(swap_lanes & SWAP_16B)) ? { data_p1[47:32], data_p1[63:48], data_p1[15:0],  data_p1[31:16] } : data_p1;
   assign o_tdata = (|(swap_lanes & SWAP_8B))  ? { data_p2[55:48], data_p2[63:56], data_p2[39:32], data_p2[47:40], 
                                                   data_p2[23:16], data_p2[31:24], data_p2[7:0],   data_p2[15:8]  } : data_p2;

   assign i_tready = o_tready;
   assign o_tvalid = i_tvalid;
   assign o_tlast  = i_tlast;

endmodule // data_swapper_64
module pcie_pkt_route_specifier #(
    parameter BASE_ADDR = 20'h0,
    parameter ADDR_MASK = 20'hFFF00,
    parameter SID_WIDTH = 8,
    parameter DST_WIDTH = 4
) (
    input           clk,
    input           reset,

    input [63:0]    regi_tdata,
    input           regi_tvalid,
    output          regi_tready,

    input  [SID_WIDTH-1:0]  local_sid,
    output [DST_WIDTH-1:0]  fifo_dst
);
    // Routing table
    reg [DST_WIDTH-1:0] routing_table[0:(1<<SID_WIDTH)-1];
    assign fifo_dst = routing_table[local_sid];
    
    wire        reg_wr;
    wire [19:0] reg_addr;
    wire [31:0] reg_data;
    
    // Routing table configuration
    ioport2_msg_decode config_message_decoder (
        .message(regi_tdata), .wr_request(reg_wr), .rd_request(reg_rd), .address(reg_addr), .data(reg_data)
    );

    always @(posedge clk) begin
      if (regi_tvalid && regi_tready && reg_wr && ((reg_addr & ADDR_MASK) == BASE_ADDR)) begin
        routing_table[reg_data[SID_WIDTH+15:16]] <= reg_data[DST_WIDTH-1:0];
      end
    end
    
    assign regi_tready = 1;
    
endmodule
module pcie_lossy_samp_gate
(
   input [63:0]   i_tdata,
   input          i_tvalid,
   output         i_tready,
   
   output [63:0]  o_tdata,
   output         o_tvalid,
   input          o_tready,
   
   input          drop,
   output         dropping
);

   assign o_tdata    = i_tdata;
   assign o_tvalid   = i_tvalid & ~drop;
   assign i_tready   = o_tready | drop;
   
   assign dropping   = drop & i_tvalid;
   
endmodule // pcie_lossy_samp_gate
module xge_handshake
  (
   input clk,
   input reset,
   output reg pkt_rx_ren,
   input pkt_rx_avail,
   input pkt_rx_eop
   );

   localparam IDLE=0;
   localparam RX=1;

   reg 	      state;
   

   always @(posedge clk)
     if (reset) begin
	pkt_rx_ren <= 0;
	state <= IDLE;
     end else begin
	case (state)
	  //
	  // Wait for pkt_rx_avail to be asserted, then assert pkt_rx_ren next cycle
	  //
	  IDLE: begin
	     if (pkt_rx_avail) begin
		pkt_rx_ren <= 1;
		state <= RX;
	     end else begin
		pkt_rx_ren <= 0;
		state <= IDLE;
	     end
	  end
	  //
	  // Keep pkt_rx_ren asserted until EOF received.
	  //
	  RX: begin
	     if (pkt_rx_eop) begin
		pkt_rx_ren <= 0;
		state <= IDLE;
	     end else begin
		pkt_rx_ren <= 1;
		state <= RX;
	     end
	  end   
	     
	endcase // case(state)
     end // else: !if(reset)
endmodule // xge_handshake
module axi64_to_xge64
  (
   input clk,
   input reset,
   input clear,
   input [63:0] s_axis_tdata,
   input [3:0] s_axis_tuser,
   input s_axis_tlast,
   input s_axis_tvalid,
   output s_axis_tready,
   output [63:0] m_axis_tdata,
   output [3:0] m_axis_tuser,
   output m_axis_tlast,
   output m_axis_tvalid,
   input m_axis_tready
   );

   localparam STORE_FIRST = 0;
   localparam FORWARD_FULL = 1;
   localparam RELEASE_LAST = 2;

   reg [1:0] state;
   reg [15:0] saved;
   reg [2:0]  last_occ;
   reg 	      last_sof;

   //on last line when eof and not finishing with 7 or 8 bytes as last word.
   wire       last_line = (s_axis_tlast && !(s_axis_tuser[2:0] == 3'b111 || s_axis_tuser[2:0] == 3'b000));

   always @(posedge clk) begin
      if(reset | clear) begin
         last_sof <= 0;
         last_occ <= 0;
         state <= STORE_FIRST;
      end
      else begin
         if (s_axis_tvalid && s_axis_tready) begin
            saved <= s_axis_tdata[15:0];
            last_occ <= s_axis_tuser[2:0];
            last_sof <= (state == STORE_FIRST) ;
         end

         case(state)

           STORE_FIRST: begin
              if (s_axis_tvalid && s_axis_tready) begin
                 state <= FORWARD_FULL;
              end
           end

           FORWARD_FULL: begin
              if (s_axis_tvalid && s_axis_tready && s_axis_tlast) begin
                 state <= last_line? STORE_FIRST : RELEASE_LAST;
              end
           end

           RELEASE_LAST: begin
              if (m_axis_tvalid && m_axis_tready) begin
                 state <= STORE_FIRST;
              end
           end

         endcase //state
      end
   end

   assign m_axis_tdata[63:0] = {saved, s_axis_tdata[63:16]};
   assign m_axis_tuser[3] = last_sof;
   assign m_axis_tlast = (state == RELEASE_LAST)? 1'b1 : last_line;
   assign m_axis_tuser[2:0] = ((state == RELEASE_LAST)? last_occ : (last_line? s_axis_tuser[2:0] : 3'b110)) + 3'b010;
   assign m_axis_tvalid = (state == STORE_FIRST)? 0 : ((state == RELEASE_LAST)? 1 : s_axis_tvalid);
   assign s_axis_tready = (state == STORE_FIRST)? 1 : ((state == RELEASE_LAST)? 0 : m_axis_tready);

endmodule //fifo69_txrealign
module pulse_generator #(parameter WIDTH = 32) (
  input  wire             clk,          /* clock */
  input  wire             reset,        /* reset */
  input  wire [WIDTH-1:0] period,       /* period, in clk cycles */
  input  wire [WIDTH-1:0] pulse_width,  /* pulse width, in clk cycles */
  output reg              pulse         /* pulse */
);
  reg [WIDTH-1:0] count = 0;

  always @(posedge clk) begin
    if (reset | count <= 1)
      count <= period;
    else
      count <= count - 1;

    pulse <= (count > (period - pulse_width));
  end

endmodule //pulse_generator
module pps_generator #(
   parameter CLK_FREQ   = 32'd10_000_000, //Min:10kHz, Max:4GHz
   parameter DUTY_CYCLE = 25
) (
   input  clk,
   input  reset,
   output pps
);
    reg [31:0] count;

    always @(posedge clk) begin
        if (reset) begin
            count <= 32'd0;
        end else if (count >= CLK_FREQ - 1) begin
            count <= 32'd0;
        end else begin
            count <= count + 32'd1;
        end
    end

    assign pps = (count < ((CLK_FREQ / 100) * DUTY_CYCLE));
endmodule //pps_generator
module pps_synchronizer
(
   input      ref_clk,
   input      timebase_clk,
   input      pps_in,
   output     pps_out,
   output reg pps_count
);
   wire pps_refclk;
   reg  pps_out_del;

   //The input pps is treated an as async signal and is first synchronized
   //to a common reference clock shared between multiple devices. It is then
   //synchronized to the timebase clock which counts up the VITA time.
   //The reference clock frequency must be equal to or smaller than the 
   //timebase clock frequency to remove any time ambiguity.

   //For robust synchronization across FPGA builds, the async delay for pps_in
   //must be constrained along with the clock delay (or meet static timing there).
   //The path length between the two synchronizers must also be constrained
   synchronizer #(.INITIAL_VAL(1'b0), .FALSE_PATH_TO_IN(0)) pps_sync_refclk_inst (
      .clk(ref_clk), .rst(1'b0 /* no reset */), .in(pps_in), .out(pps_refclk));

   synchronizer #(.INITIAL_VAL(1'b0), .FALSE_PATH_TO_IN(0)) pps_sync_tbclk_inst (
      .clk(timebase_clk), .rst(1'b0 /* no reset */), .in(pps_refclk), .out(pps_out));

   //Implement a 1-bit counter to detect PPS edges
   always @(posedge timebase_clk)
      pps_out_del <= pps_out;

   always @(posedge timebase_clk)
      if (~pps_out_del && pps_out)
         pps_count <= ~pps_count;

endmodule //pps_synchronizer