dakies/OSS_Verilog huggingface dataset:
module cmsdk_apb3_eg_slave_interface_led #(
  // parameter for address width
  parameter ADDRWIDTH = 12)
 (
  // IO declaration

  input  wire                    pclk,     // pclk
  input  wire                    presetn,  // reset

  // apb interface inputs
  input  wire                    psel,
  input  wire [ADDRWIDTH-1:0]    paddr,
  input  wire                    penable,
  input  wire                    pwrite,
  input  wire [31:0]             pwdata,

  // apb interface outputs
  output wire [31:0]             prdata,
  output wire                    pready,
  output wire                    pslverr,

  // LED write interface
  output wire [31:0]             ledNumIn
 );

 //------------------------------------------------------------------------------
 // module logic start
 //------------------------------------------------------------------------------

reg  [31:0]     Reg2LED;
wire            write_en;

// APB interface
assign   prdata  = 32'b0;
assign   pready  = 1'b1; //always ready. Can be customized to support waitstate if required.
assign   pslverr = 1'b0; //alwyas OKAY. Can be customized to support error response if required.


// LED write signal
//assign  write_en = psel & (~penable) & pwrite; // assert for 1st cycle of write transfer
        // It is also possible to change the design to perform the write in the 2nd
        // APB cycle.   E.g.
        //   assign write_en = psel & penable & pwrite;
        // However, if the design generate waitstate, this expression will result
        // in write_en being asserted for multiple cycles.
assign write_en = psel & penable & pwrite;

// enable write transfer without wait signal
always @ (posedge pclk or negedge presetn)
begin
    if(~presetn)
      Reg2LED <= 0;
    else if(write_en == 1'b1)
      Reg2LED <= pwdata;
    else
      Reg2LED <= Reg2LED;
end

assign ledNumIn = Reg2LED;



`ifdef ARM_APB_ASSERT_ON

 `include "std_ovl_defines.h"
  // ------------------------------------------------------------
  // Assertions
  // ------------------------------------------------------------

  // Check error response should not be generated if not selected
    assert_never
     #(`OVL_ERROR,
       `OVL_ASSERT,
       "Error! Should not generate error response if not selected")
     u_ovl_apb3_eg_slave_response_illegal
     (.clk        (pclk),
      .reset_n    (presetn),
      .test_expr  (pslverr & pready & (~psel))
      );

`endif

 //------------------------------------------------------------------------------
 // module logic end
 //------------------------------------------------------------------------------

endmodule
module custom_apb_led(
    //led core ports
    input  wire        clk,
    input  wire        rst,
    input  wire [31:0] ledNumIn,
    output reg  [3:0]  ledNumOut    // When high, the LED on board turns off
);

always @ (posedge clk or negedge rst)
begin
    if(~rst)
        ledNumOut <= 4'b1111;
    else if(ledNumIn >= 4'b1111)
        ledNumOut <= 4'b0000;
    else
        ledNumOut <= ~ledNumIn;
end

endmodule
module igniter #(
	parameter ADDRWIDTH = 12)
	(
	
	//SYSTEM
	input wire                       pclk,
	input wire                       presetn,
	
	output reg					     				 ignite_acc,
  input                            ignite_ready,
	output reg 						 					 ignite_cam,
	input							 							 ignite_cam_ready,
  output reg                       write_addr_index,
  output reg                       read_addr_index,
	//APB
	input  wire                      psel,
	input  wire [ADDRWIDTH-1:0]      paddr,
	input  wire                      penable,
	input  wire                      pwrite,
	input  wire [31:0]               pwdata,
	output reg  [31:0]               prdata,
	output wire                      pready,
	output wire                      pslverr	
	);

  	assign	pready  = 1'b1;	//always ready. Can be customized to support waitstate if required.
  	assign	pslverr = 1'b0;	//alwyas OKAY. Can be customized to support error response if required.

	assign	write_en = psel & penable & pwrite;
	assign	read_en  = psel & penable & (~pwrite);

	// Camera Igniter
	always @ (posedge pclk or negedge presetn) begin
		if(~presetn)begin
			ignite_cam <= 1'b0;
    end 
    else begin
			if(ignite_cam_ready == 1'b1) begin
				ignite_cam <= 1'b0; 
			end
			else if((write_en == 1'b1) && (pwdata == 32'hca)) begin
				ignite_cam <= 1'b1;
			end
    end
	end

	// Accelerator Igniter
	always @ (posedge pclk or negedge presetn) begin
		if(~presetn)begin
			ignite_acc <= 1'b0;
        end 
        else begin
		    if(ignite_ready == 1'b1) begin
		    	ignite_acc <= 1'b0; 
		    end
		    else if((write_en == 1'b1) && (pwdata == 32'd1514)) begin
				ignite_acc <= 1'b1;
		    end
        end
	end

  // pixel address index
  always @ (posedge pclk or negedge presetn) begin
    if(~presetn)begin
      prdata <= 32'd0;
    end
		else if(read_en == 1'b1) begin
			prdata <= {31'b0, write_addr_index};
		end
  end

  // draw kuangkuang
  always @ (posedge pclk or negedge presetn) begin
    if(~presetn)begin
      write_addr_index  <= 1'd0;
      read_addr_index   <= 1'd1;
    end
		else begin
      if((write_en == 1'b1) && (pwdata == 32'hda)) begin
        read_addr_index   = write_addr_index;
        write_addr_index  = write_addr_index + 1'd1;
      end
		end
  end

endmodule
module custom_apb_timer #(
	parameter ADDRWIDTH = 12,
  parameter CLK_FREQ  = 32'd50000000
  )
	(
	
	//SYSTEM
	input wire                       pclk,
	input wire                       presetn,
	
	output reg	[31:0]				       cp_timerCnt, // ckp
  input                            ui_clk,
  output reg  [31:0]               ui_cnt,
	//APB
	input  wire                      psel,
	input  wire [ADDRWIDTH-1:0]      paddr,
	input  wire                      penable,
	input  wire                      pwrite,
	input  wire [31:0]               pwdata,
	output reg  [31:0]               prdata,
	output wire                      pready,
	output wire                      pslverr	
	);

  	assign	pready  = 1'b1;	//always ready. Can be customized to support waitstate if required.
  	assign	pslverr = 1'b0;	//alwyas OKAY. Can be customized to support error response if required.

	assign	write_en = psel & penable & pwrite;
	assign	read_en  = psel & penable & (~pwrite);

	reg [31:0]	cnt;
	always @ (posedge pclk or negedge presetn) begin
		if(~presetn) begin
			cnt <= 32'd0;
		end
		else if(cnt >= CLK_FREQ/1000 - 1) begin // reset to zero every 1ms
			cnt <= 32'd0;
		end
		else begin
			cnt <= cnt + 32'd1;
		end
	end

	reg [31:0] ms_cnt;
	always @ (posedge pclk or negedge presetn) begin
		if(~presetn)begin
			ms_cnt <= 32'd0;
		end
		else if((write_en == 1'b1) && (pwdata == 32'd1514)) begin
			ms_cnt <= 32'd0;
		end
		else if(cnt == 32'd1) begin
			ms_cnt <= ms_cnt + 32'd1;
		end
	end

	always @ (posedge pclk or negedge presetn) begin
		if(~presetn)begin
			prdata <= 32'd0;
		end
		else begin
			prdata <= ms_cnt;
		end		
	end

	always @ (posedge pclk or negedge presetn) begin
		if(~presetn)begin
			cp_timerCnt <= 32'd0;
		end
		else if(read_en == 1'b1) begin
			cp_timerCnt <= ms_cnt;
		end
	end

  reg [31:0]    ui_reg;
  always @ (posedge ui_clk or negedge presetn) begin
    if(~presetn)begin
      ui_reg      <= 32'd0;
    end
    else begin
      if(cnt == 32'd1)begin
        ui_cnt <= ui_reg;
        ui_reg <= 32'd0; 
      end
      else begin
        ui_reg <= ui_reg + 32'd1;
      end
    end
  end


endmodule
module video_timing_data
#(
	parameter DATA_WIDTH = 16                       // Video data one clock data width
)
(
	input                       video_clk,          // Video pixel clock
	input                       rst,
	output reg                  read_req,           // Start reading a frame of data     
	input                       read_req_ack,       // Read request response
	output                      read_en,            // Read data enable
	input[DATA_WIDTH - 1:0]     read_data,          // Read data
	output                      hs,                 // horizontal synchronization
	output                      vs,                 // vertical synchronization
	output                      de,                 // video valid
	output[DATA_WIDTH - 1:0]    vout_data           // video data
);
wire                   video_hs;
wire                   video_vs;
wire                   video_de;
//delay video_hs video_vs  video_de 2 clock cycles
reg                    video_hs_d0;
reg                    video_vs_d0;
reg                    video_de_d0;
reg                    video_hs_d1;
reg                    video_vs_d1;
reg                    video_de_d1;

reg[DATA_WIDTH - 1:0]  vout_data_r;
assign read_en = video_de;
assign hs = video_hs_d1;
assign vs = video_vs_d1;
assign de = video_de_d1;
assign vout_data = vout_data_r;
always@(posedge video_clk or posedge rst)
begin
	if(rst == 1'b1)
	begin
		video_hs_d0 <= 1'b0;
		video_vs_d0 <= 1'b0;
		video_de_d0 <= 1'b0;
	end
	else
	begin
		//delay video_hs video_vs  video_de 2 clock cycles
		video_hs_d0 <= video_hs;
		video_vs_d0 <= video_vs;
		video_de_d0 <= video_de;
		video_hs_d1 <= video_hs_d0;
		video_vs_d1 <= video_vs_d0;
		video_de_d1 <= video_de_d0;		
	end
end

always@(posedge video_clk or posedge rst)
begin
	if(rst == 1'b1)
		vout_data_r <= {DATA_WIDTH{1'b0}};
	else if(video_de_d0)
		vout_data_r <= read_data;
	else
		vout_data_r <= {DATA_WIDTH{1'b0}};
end

always@(posedge video_clk or posedge rst)
begin
	if(rst == 1'b1)
		read_req <= 1'b0;
	else if(video_vs_d0 & ~video_vs) //vertical synchronization edge (the rising or falling edges are OK)
		read_req <= 1'b1;
	else if(read_req_ack)
		read_req <= 1'b0;
end

color_bar color_bar_m0(
	.clk(video_clk),
	.rst(rst),
	.hs(video_hs),
	.vs(video_vs),
	.de(video_de),
	.rgb_r(),
	.rgb_g(),
	.rgb_b()
);
endmodule
module cmos_8_16bit(
	input              rst,
	input              pclk,
	input [7:0]        pdata_i,
	input              de_i,
	output reg[15:0]   pdata_o,
	output reg         hblank,
	output reg         de_o
);
reg[7:0] pdata_i_d0;
reg[11:0] x_cnt;
always@(posedge pclk)
begin
	pdata_i_d0 <= pdata_i;
end

always@(posedge pclk or posedge rst)
begin
	if(rst)
		x_cnt <= 12'd0;
	else if(de_i)
		x_cnt <= x_cnt + 12'd1;
	else
		x_cnt <= 12'd0;
end

always@(posedge pclk or posedge rst)
begin
	if(rst)
		de_o <= 1'b0;
	else if(de_i && x_cnt[0])
		de_o <= 1'b1;
	else
		de_o <= 1'b0;
end

always@(posedge pclk or posedge rst)
begin
	if(rst)
		hblank <= 1'b0;
	else
		hblank <= de_i;
end

always@(posedge pclk or posedge rst)
begin
	if(rst)
		pdata_o <= 16'd0;
	else if(de_i && x_cnt[0])
		pdata_o <= {pdata_i_d0,pdata_i};
	else
		pdata_o <= 16'd0;
end

endmodule
module dvi_encoder
(
input           pixelclk,       // system clock
input           pixelclk5x,     // system clock x5
input           rstin,          // reset
input[7:0]      blue_din,       // Blue data in
input[7:0]      green_din,      // Green data in
input[7:0]      red_din,        // Red data in
input           hsync,          // hsync data
input           vsync,          // vsync data
input           de,             // data enable
output          tmds_clk_p,
output          tmds_clk_n,
output[2:0]     tmds_data_p,    //rgb
output[2:0]     tmds_data_n     //rgb
);

wire    [9:0]   red ;
wire    [9:0]   green ;
wire    [9:0]   blue ;

encode encb (
.clkin      (pixelclk),
.rstin      (rstin),
.din        (blue_din),
.c0         (hsync),
.c1         (vsync),
.de         (de),
.dout       (blue)) ;

encode encr (
.clkin      (pixelclk),
.rstin      (rstin),
.din        (green_din),
.c0         (1'b0),
.c1         (1'b0),
.de         (de),
.dout       (green)) ;

encode encg (
.clkin      (pixelclk),
.rstin      (rstin),
.din        (red_din),
.c0         (1'b0),
.c1         (1'b0),
.de         (de),
.dout       (red)) ;
serdes_4b_10to1 serdes_4b_10to1_m0(
.clk           (pixelclk        ),// clock input
.clkx5         (pixelclk5x      ),// 5x clock input
.datain_0      (blue            ),// input data for serialisation
.datain_1      (green         ),// input data for serialisation
.datain_2      (red             ),// input data for serialisation
.datain_3      (10'b1111100000  ),// input data for serialisation
.dataout_0_p   (tmds_data_p[0]  ),// out DDR data
.dataout_0_n   (tmds_data_n[0]  ),// out DDR data
.dataout_1_p   (tmds_data_p[1]  ),// out DDR data
.dataout_1_n   (tmds_data_n[1]  ),// out DDR data
.dataout_2_p   (tmds_data_p[2]  ),// out DDR data
.dataout_2_n   (tmds_data_n[2]  ),// out DDR data
.dataout_3_p   (tmds_clk_p      ),// out DDR data
.dataout_3_n   (tmds_clk_n      ) // out DDR data
) ; 

endmodule
module cmos_write_req_gen(
	input              rst,
	input              pclk,
	input              cmos_vsync,
	output reg         write_req,
	// output reg  	     write_addr_index,
	// output reg  	     read_addr_index,
	input              write_req_ack     
);
reg cmos_vsync_d0;
reg cmos_vsync_d1;
always@(posedge pclk or posedge rst)
begin
	if(rst == 1'b1)
	begin
		cmos_vsync_d0 <= 1'b0;
		cmos_vsync_d1 <= 1'b0;
	end
	else
	begin
		cmos_vsync_d0 <= cmos_vsync;
		cmos_vsync_d1 <= cmos_vsync_d0;
	end
end

always@(posedge pclk or posedge rst)
begin
	if(rst == 1'b1)
	begin
		write_req <= 1'b0;
	end
	else if(cmos_vsync_d0 == 1'b1 && cmos_vsync_d1 == 1'b0)
	begin
		write_req <= 1'b1;
	end
	else if(write_req_ack == 1'b1)
		write_req <= 1'b0;
end

// always@(posedge pclk or posedge rst)
// begin
// 	if(rst == 1'b1)
// 		write_addr_index <= 1'b0;
// 	else if(cmos_vsync_d0 == 1'b1 && cmos_vsync_d1 == 1'b0)
// 		write_addr_index <= write_addr_index + 1'd1;
// end

// always@(posedge pclk or posedge rst)
// begin
// 	if(rst == 1'b1)
// 		read_addr_index <= 1'b0;
// 	else if(cmos_vsync_d0 == 1'b1 && cmos_vsync_d1 == 1'b0)
// 		read_addr_index <= write_addr_index;
// end

endmodule
module i2c_config(
	input              rst,
	input              clk,
	input[15:0]        clk_div_cnt,
	input              i2c_addr_2byte,
	output reg[9:0]    lut_index,
	input[7:0]         lut_dev_addr,
	input[15:0]        lut_reg_addr,
	input[7:0]         lut_reg_data,
	output reg         error,
	output             done,
	inout              i2c_scl,
	inout              i2c_sda
);
wire scl_pad_i;
wire scl_pad_o;
wire scl_padoen_o;

wire sda_pad_i;
wire sda_pad_o;
wire sda_padoen_o;

assign sda_pad_i = i2c_sda;
assign i2c_sda = ~sda_padoen_o ? sda_pad_o : 1'bz;
assign scl_pad_i = i2c_scl;
assign i2c_scl = ~scl_padoen_o ? scl_pad_o : 1'bz;

reg i2c_read_req;
wire i2c_read_req_ack;
reg i2c_write_req;
wire i2c_write_req_ack;
wire[7:0] i2c_slave_dev_addr;
wire[15:0] i2c_slave_reg_addr;
wire[7:0] i2c_write_data;
wire[7:0] i2c_read_data;

wire err;
reg[2:0] state;

localparam S_IDLE                =  0;
localparam S_WR_I2C_CHECK        =  1;
localparam S_WR_I2C              =  2;
localparam S_WR_I2C_DONE         =  3;


assign done = (state == S_WR_I2C_DONE);
assign i2c_slave_dev_addr  = lut_dev_addr;
assign i2c_slave_reg_addr = lut_reg_addr;
assign i2c_write_data  = lut_reg_data;


always@(posedge clk or posedge rst)
begin
	if(rst)
	begin
		state <= S_IDLE;
		error <= 1'b0;
		lut_index <= 8'd0;
	end
	else 
		case(state)
			S_IDLE:
			begin
				state <= S_WR_I2C_CHECK;
				error <= 1'b0;
				lut_index <= 8'd0;
			end
			S_WR_I2C_CHECK:
			begin
				if(i2c_slave_dev_addr != 8'hff)
				begin
					i2c_write_req <= 1'b1;
					state <= S_WR_I2C;
				end
				else
				begin
					state <= S_WR_I2C_DONE;
				end
			end
			S_WR_I2C:
			begin
				if(i2c_write_req_ack)
				begin
					error <= err ? 1'b1 : error; 
					lut_index <= lut_index + 8'd1;
					i2c_write_req <= 1'b0;
					state <= S_WR_I2C_CHECK;
				end
			end
			S_WR_I2C_DONE:
			begin
				state <= S_WR_I2C_DONE;
			end
			default:
				state <= S_IDLE;
		endcase
end



i2c_master_top i2c_master_top_m0
(
	.rst(rst),
	.clk(clk),
	.clk_div_cnt(clk_div_cnt),
	
	// I2C signals
	// i2c clock line
	.scl_pad_i(scl_pad_i),       // SCL-line input
	.scl_pad_o(scl_pad_o),       // SCL-line output (always 1'b0)
	.scl_padoen_o(scl_padoen_o),    // SCL-line output enable (active low)

	// i2c data line
	.sda_pad_i(sda_pad_i),       // SDA-line input
	.sda_pad_o(sda_pad_o),       // SDA-line output (always 1'b0)
	.sda_padoen_o(sda_padoen_o),    // SDA-line output enable (active low)
	
	.i2c_read_req(i2c_read_req),
	.i2c_addr_2byte(i2c_addr_2byte),
	.i2c_read_req_ack(i2c_read_req_ack),
	.i2c_write_req(i2c_write_req),
	.i2c_write_req_ack(i2c_write_req_ack),
	.i2c_slave_dev_addr(i2c_slave_dev_addr),
	.i2c_slave_reg_addr(i2c_slave_reg_addr),
	.i2c_write_data(i2c_write_data),
	.i2c_read_data(i2c_read_data),
	.error(err)
);
endmodule
module nt_packet_counter (
  // clock and resets
  input wire clk,
  input wire rstn,
  input wire rst_sw,

  // AXI4-Stream signals
  input wire axis_tvalid,
  input wire axis_tready,
  input wire axis_tlast,

  output reg [31:0]    cntr_o
);

  always @(posedge clk) begin
    if (~rstn | rst_sw) begin
      cntr_o <= 32'b0;
    end else begin
      if (axis_tvalid & axis_tready & axis_tlast) begin
        // packet transfer completed, increment counter
        cntr_o <= cntr_o + 1;
      end else begin
        cntr_o <= cntr_o;
      end
    end
  end

endmodule
module nt_recv_capture_rx_fifo_merge_test
(
  // clock and resets
  input wire          clk,
  input wire          rstn,
  input wire          rst_sw,

  // AXI-S slave interface
  input wire [63:0]   s_axis_tdata,
  input wire          s_axis_tvalid,
  input wire          s_axis_tlast,
  input wire [7:0]    s_axis_tkeep,
  input wire [52:0]   s_axis_tuser,
  output wire         s_axis_tready,

  // activation signals
  input wire          active_i,
  input wire [15:0]   max_len_capture_i,

  // fifo output
  output wire [63:0]  fifo_din_o,
  output wire         fifo_wr_en_o,
  input wire          fifo_full_i,

  // activation status output
  output wire         active_o,

  // packet counter output
  output wire [31:0]  pkt_cnt_o,

  // fifo full error output
  output wire         err_meta_fifo_full_o,
  output wire         err_data_fifo_full_o
);

  wire [74:0] fifo_meta_din, fifo_meta_dout;
  wire [63:0] fifo_data_din, fifo_data_dout;
  wire fifo_meta_rd_en, fifo_meta_empty, fifo_meta_wr_en, fifo_meta_full;
  wire fifo_data_rd_en, fifo_data_empty, fifo_data_wr_en, fifo_data_full;

  // instantiate nt_recv_capture_rx module
  nt_recv_capture_rx nt_recv_capture_rx_inst (
    .clk(clk),
    .rstn(rstn),
    .rst_sw(rst_sw),
    .s_axis_tdata(s_axis_tdata),
    .s_axis_tvalid(s_axis_tvalid),
    .s_axis_tlast(s_axis_tlast),
    .s_axis_tkeep(s_axis_tkeep),
    .s_axis_tuser(s_axis_tuser),
    .s_axis_tready(s_axis_tready),
    .active_i(active_i),
    .max_len_capture_i(max_len_capture_i),
    .fifo_meta_din_o(fifo_meta_din),
    .fifo_meta_wr_en_o(fifo_meta_wr_en),
    .fifo_meta_full_i(fifo_meta_full),
    .fifo_data_din_o(fifo_data_din),
    .fifo_data_wr_en_o(fifo_data_wr_en),
    .fifo_data_full_i(fifo_data_full),
    .active_o(active_o),
    .pkt_cnt_o(pkt_cnt_o),
    .err_meta_fifo_full_o(err_meta_fifo_full_o),
    .err_data_fifo_full_o(err_data_fifo_full_o)
  );

  // instantiate nt_recv_capture_fifo_merge module
  nt_recv_capture_fifo_merge nt_recv_capture_fifo_merge_inst (
    .clk(clk),
    .rstn(rstn),
    .rst_sw(rst_sw),
    .fifo_meta_dout_i(fifo_meta_dout),
    .fifo_meta_empty_i(fifo_meta_empty),
    .fifo_meta_rd_en_o(fifo_meta_rd_en),
    .fifo_data_dout_i(fifo_data_dout),
    .fifo_data_empty_i(fifo_data_empty),
    .fifo_data_rd_en_o(fifo_data_rd_en),
    .fifo_din_o(fifo_din_o),
    .fifo_wr_en_o(fifo_wr_en_o),
    .fifo_full_i(fifo_full_i)
  );

  // instantiate meta fifo
  nt_recv_capture_meta_fifo nt_recv_capture_meta_fifo_inst (
    .clk(clk),
    .srst(~rstn | rst_sw),
    .din(fifo_meta_din),
    .wr_en(fifo_meta_wr_en),
    .rd_en(fifo_meta_rd_en),
    .dout(fifo_meta_dout),
    .full(fifo_meta_full),
    .empty(fifo_meta_empty)
  );

  // instantiate data fifo
  nt_recv_capture_data_fifo nt_recv_capture_data_fifo_inst (
    .clk(clk),
    .srst(~rstn | rst_sw),
    .din(fifo_data_din),
    .wr_en(fifo_data_wr_en),
    .rd_en(fifo_data_rd_en),
    .dout(fifo_data_dout),
    .full(fifo_data_full),
    .empty(fifo_data_empty)
  );

endmodule
module nt_recv_capture_fifo_merge_test
(
  // clock and resets
  input wire          clk,
  input wire          rstn,
  input wire          rst_sw,

  // meta data fifo input
  input wire [74:0]   fifo_meta_din_i,
  input wire          fifo_meta_wr_en_i,
  output wire         fifo_meta_full_o,

  // packet data fifo input
  input wire [63:0]   fifo_data_din_i,
  input wire          fifo_data_wr_en_i,
  output wire         fifo_data_full_o,

  // merged fifo output
  output wire [63:0]  fifo_din_o,
  output wire         fifo_wr_en_o,
  input wire          fifo_full_i
);

  wire [74:0] fifo_meta_dout;
  wire [63:0] fifo_data_dout;
  wire fifo_meta_rd_en, fifo_meta_empty;
  wire fifo_data_rd_en, fifo_data_empty;

  // instantiate module to be tested
  nt_recv_capture_fifo_merge nt_recv_capture_fifo_merge_inst (
    .clk(clk),
    .rstn(rstn),
    .rst_sw(rst_sw),
    .fifo_meta_dout_i(fifo_meta_dout),
    .fifo_meta_empty_i(fifo_meta_empty),
    .fifo_meta_rd_en_o(fifo_meta_rd_en),
    .fifo_data_dout_i(fifo_data_dout),
    .fifo_data_empty_i(fifo_data_empty),
    .fifo_data_rd_en_o(fifo_data_rd_en),
    .fifo_din_o(fifo_din_o),
    .fifo_wr_en_o(fifo_wr_en_o),
    .fifo_full_i(fifo_full_i)
  );

  // instantiate meta fifo
  nt_recv_capture_meta_fifo nt_recv_capture_meta_fifo_inst (
    .clk(clk),
    .srst(~rstn | rst_sw),
    .din(fifo_meta_din_i),
    .wr_en(fifo_meta_wr_en_i),
    .rd_en(fifo_meta_rd_en),
    .dout(fifo_meta_dout),
    .full(fifo_meta_full_o),
    .empty(fifo_meta_empty)
  );

  // instantiate data fifo
  nt_recv_capture_data_fifo nt_recv_capture_data_fifo_inst (
    .clk(clk),
    .srst(~rstn | rst_sw),
    .din(fifo_data_din_i),
    .wr_en(fifo_data_wr_en_i),
    .rd_en(fifo_data_rd_en),
    .dout(fifo_data_dout),
    .full(fifo_data_full_o),
    .empty(fifo_data_empty)
  );

endmodule
module nt_timestamp (
  // clock and reset
  input wire        clk,
  input wire        rstn,

  // number of clock cycles between two counter increments
  input wire [7:0]  cycles_per_tick_i,

  // timestamp counter output
  output reg [23:0] timestamp_o
);

  reg [7:0] tick_cntr;

  // process increments output timestamp_o counter every cycles_per_tick_i
  // cycles. when maximum value is reached, counter is reset to zero
  always @(posedge clk) begin
    if (~rstn) begin
      timestamp_o <= 24'b0;
    end else begin
      if (tick_cntr == (cycles_per_tick_i - 1)) begin
        if (timestamp_o == 24'hFFFFFF) begin
          timestamp_o <= 24'b0;
        end else begin
          timestamp_o <= timestamp_o + 24'b1;
        end
      end else begin
        timestamp_o <= timestamp_o;
      end
    end
  end

  // process increments tick_cntr every clock cycle. When cycles_per_tick_i is
  // reached, counter is reset
  always @(posedge clk) begin
    if (~rstn) begin
      tick_cntr <= 8'b0;
    end else begin
      if (tick_cntr >= (cycles_per_tick_i - 1)) begin
        tick_cntr <= 8'b0;
      end else begin
        tick_cntr <= tick_cntr + 8'b1;
      end
    end
  end

endmodule
module nt_timestamp_top # (
  parameter C_AXI_BASE_ADDRESS = 32'h00000000
)
(
  // clock and reset
  input wire clk156,
  input wire rstn156,

  input wire [31:0]    s_axi_ctrl_awaddr,
  input wire [2:0]     s_axi_ctrl_awprot,
  input wire           s_axi_ctrl_awvalid,
  output wire          s_axi_ctrl_awready,
  input wire [31:0]    s_axi_ctrl_wdata,
  input wire [3:0]     s_axi_ctrl_wstrb,
  input wire           s_axi_ctrl_wvalid,
  output wire          s_axi_ctrl_wready,
  output wire [1:0]    s_axi_ctrl_bresp,
  output wire          s_axi_ctrl_bvalid,
  input wire           s_axi_ctrl_bready,
  input wire [31:0]    s_axi_ctrl_araddr,
  input wire [2:0]     s_axi_ctrl_arprot,
  output wire          s_axi_ctrl_arready,
  input wire           s_axi_ctrl_arvalid,
  output wire [31:0]   s_axi_ctrl_rdata,
  output wire [1:0]    s_axi_ctrl_rresp,
  output wire          s_axi_ctrl_rvalid,
  input wire           s_axi_ctrl_rready,

  // timestamp output
  output wire [23:0]   timestamp_o,
  output wire [1:0]    mode_o,
  output wire [10:0]   pos_o,
  output wire          width_o
);

  // cpu registers
  wire [`CPUREG_CTRL_CYCLES_PER_TICK_BITS] cpureg_ctrl_cycles_per_tick;

  nt_timestamp_cpuregs # (
    .C_AXI_BASE_ADDRESS(C_AXI_BASE_ADDRESS)
  ) nt_timestamp_cpuregs_inst (
    .clk(clk156),
    .rstn(rstn156),

    .s_axi_awaddr(s_axi_ctrl_awaddr),
    .s_axi_awport(s_axi_ctrl_awprot),
    .s_axi_awvalid(s_axi_ctrl_awvalid),
    .s_axi_awready(s_axi_ctrl_awready),
    .s_axi_wdata(s_axi_ctrl_wdata),
    .s_axi_wstrb(s_axi_ctrl_wstrb),
    .s_axi_wvalid(s_axi_ctrl_wvalid),
    .s_axi_wready(s_axi_ctrl_wready),
    .s_axi_bresp(s_axi_ctrl_bresp),
    .s_axi_bvalid(s_axi_ctrl_bvalid),
    .s_axi_bready(s_axi_ctrl_bready),
    .s_axi_araddr(s_axi_ctrl_araddr),
    .s_axi_arprot(s_axi_ctrl_arprot),
    .s_axi_arready(s_axi_ctrl_arready),
    .s_axi_arvalid(s_axi_ctrl_arvalid),
    .s_axi_rdata(s_axi_ctrl_rdata),
    .s_axi_rresp(s_axi_ctrl_rresp),
    .s_axi_rvalid(s_axi_ctrl_rvalid),
    .s_axi_rready(s_axi_ctrl_rready),

    .cpureg_ctrl_cycles_per_tick_o(cpureg_ctrl_cycles_per_tick),
    .cpureg_ctrl_mode_o(mode_o),
    .cpureg_ctrl_pos_o(pos_o),
    .cpureg_ctrl_width_o(width_o)
  );

  nt_timestamp nt_timestamp_inst (
    .clk(clk156),
    .rstn(rstn156),
    .cycles_per_tick_i(cpureg_ctrl_cycles_per_tick),
    .timestamp_o(timestamp_o)
  );

endmodule
module nt_ctrl_top # (
  parameter C_AXI_BASE_ADDRESS = 32'h00000000
)
(
  input wire clk,
  input wire rstn,

  input wire clk156,
  input wire rstn156,

  input wire [31:0]    s_axi_awaddr,
  input wire [2:0]     s_axi_awprot,
  input wire           s_axi_awvalid,
  output wire          s_axi_awready,
  input wire [31:0]    s_axi_wdata,
  input wire [3:0]     s_axi_wstrb,
  input wire           s_axi_wvalid,
  output wire          s_axi_wready,
  output wire [1:0]    s_axi_bresp,
  output wire          s_axi_bvalid,
  input wire           s_axi_bready,
  input wire [31:0]    s_axi_araddr,
  input wire [2:0]     s_axi_arprot,
  output wire          s_axi_arready,
  input wire           s_axi_arvalid,
  output wire [31:0]   s_axi_rdata,
  output wire [1:0]    s_axi_rresp,
  output wire          s_axi_rvalid,
  input wire           s_axi_rready,

  output reg [3:0] rate_ctrl_active_o,
  output reg       rst_sw,
  output reg       rstn_sw,
  output reg       rst_sw156,
  output reg       rstn_sw156
);

  // cpu register wires
  wire [`CPUREG_CTRL_RATE_CTRL_ACTIVE_BITS] cpureg_ctrl_rate_ctrl_active;
  wire [`CPUREG_RST_BITS]                   cpureg_rst;

  nt_ctrl_cpuregs # (
    .C_AXI_BASE_ADDRESS(C_AXI_BASE_ADDRESS)
  ) nt_ctrl_cpuregs_inst (
    .clk(clk156),
    .rstn(rstn156),

    .s_axi_awaddr(s_axi_awaddr),
    .s_axi_awport(s_axi_awprot),
    .s_axi_awvalid(s_axi_awvalid),
    .s_axi_awready(s_axi_awready),
    .s_axi_wdata(s_axi_wdata),
    .s_axi_wstrb(s_axi_wstrb),
    .s_axi_wvalid(s_axi_wvalid),
    .s_axi_wready(s_axi_wready),
    .s_axi_bresp(s_axi_bresp),
    .s_axi_bvalid(s_axi_bvalid),
    .s_axi_bready(s_axi_bready),
    .s_axi_araddr(s_axi_araddr),
    .s_axi_arprot(s_axi_arprot),
    .s_axi_arready(s_axi_arready),
    .s_axi_arvalid(s_axi_arvalid),
    .s_axi_rdata(s_axi_rdata),
    .s_axi_rresp(s_axi_rresp),
    .s_axi_rvalid(s_axi_rvalid),
    .s_axi_rready(s_axi_rready),

    .cpureg_ctrl_rate_ctrl_active_o(cpureg_ctrl_rate_ctrl_active),
    .cpureg_rst_o(cpureg_rst)
  );

  // TX rate control active signal
  always @(posedge clk156) begin
    if (~rstn156 | cpureg_rst[0:0]) begin
      rate_ctrl_active_o <= 4'b0;
    end else begin
      rate_ctrl_active_o <= cpureg_ctrl_rate_ctrl_active;
    end
  end

  // software reset signal in 200 MHz clock domain
  always @(posedge clk) begin
    if (~rstn) begin
      rst_sw <= 1'b0;
      rstn_sw <= 1'b1;
    end else begin
      rst_sw <= cpureg_rst[0:0];
      rstn_sw <= ~cpureg_rst[0:0];
    end
  end

  // software reset signal in 156.25 MHz clock domain
  always @(posedge clk156) begin
    if (~rstn156) begin
      rst_sw156 <= 1'b0;
      rstn_sw156 <= 1'b1;
    end else begin
      rst_sw156 <= cpureg_rst[0:0];
      rstn_sw156 <= ~cpureg_rst[0:0];
    end
  end

endmodule
module nt_datarate (
  // clock and resets
  input wire clk,
  input wire rstn,
  input wire rst_sw,

  // AXI4-Stream signals
  input wire        axis_tvalid,
  input wire        axis_tready,
  input wire        axis_tlast,
  input wire [7:0]  axis_tkeep,

  // sample interval length in clock cycles
  input wire [31:0] sample_interval_i,

  // number of bytes received/transmitted in last sample interval
  output reg [31:0] n_bytes_o,

  // number of bytes received/transmitted in last sample interval (including
  // FCS, preample and gap)
  output reg [31:0] n_bytes_raw_o
);

  // clock cycle counter
  reg [31:0] clk_cntr;

  // number of bytes that have been transferred so far in the current interval
  reg [31:0] n_bytes, n_bytes_raw;


  // number of bytes that are transferred in this clock cycle
  reg [3:0] n_bytes_cycle;
  reg [5:0] n_bytes_raw_cycle;

  // determine how many bytes are transferred in this clock cycle
  always @(axis_tvalid, axis_tready, axis_tlast, axis_tkeep) begin
    if (axis_tvalid & axis_tready) begin
      if (axis_tlast) begin
        // this is the last word of the axi stream transaction. evaluate tkeep
        // to see how many bytes are transferred
        case (axis_tkeep)
          8'b00000001: n_bytes_cycle = 4'd1;
          8'b00000011: n_bytes_cycle = 4'd2;
          8'b00000111: n_bytes_cycle = 4'd3;
          8'b00001111: n_bytes_cycle = 4'd4;
          8'b00011111: n_bytes_cycle = 4'd5;
          8'b00111111: n_bytes_cycle = 4'd6;
          8'b01111111: n_bytes_cycle = 4'd7;
          8'b11111111: n_bytes_cycle = 4'd8;
          default: n_bytes_cycle = 4'd0;
        endcase

        // we do not see preamble, SOD, FCS and inter-frame gap. add 24 byte to
        // account for the raw data rate
        n_bytes_raw_cycle = n_bytes_cycle + 6'd24;
      end else begin
        // not the last word, so always transferring 8 byte
        n_bytes_cycle = 4'd8;
        n_bytes_raw_cycle = 4'd8;
      end
    end else begin
      n_bytes_cycle = 4'd0;
      n_bytes_raw_cycle = 4'd0;
    end
  end

  always @(posedge clk) begin
    if (~rstn | rst_sw) begin
      clk_cntr <= 32'b0;
      n_bytes_o <= 32'b0;
      n_bytes_raw_o <= 32'b0;
      n_bytes <= 32'b0;
      n_bytes_raw <= 32'b0;
    end else begin
      if (clk_cntr == (sample_interval_i - 32'b1)) begin
        // end of sample interval has been reached. write counters to output
        // registers. reset counters for a fresh sample interval
        clk_cntr <= 32'b0;
        n_bytes_o <= n_bytes + n_bytes_cycle;
        n_bytes_raw_o <= n_bytes_raw + n_bytes_raw_cycle;
        n_bytes <= 32'b0;
        n_bytes_raw <= 32'b0;
      end else begin
        // end of sample interval has not been reached. leave output registers
        // as they are and increment byte counters for the current interval
        clk_cntr <= clk_cntr + 32'b1;
        n_bytes_o <= n_bytes_o;
        n_bytes_raw_o <= n_bytes_raw_o;
        n_bytes <= n_bytes + n_bytes_cycle;
        n_bytes_raw <= n_bytes_raw + n_bytes_raw_cycle;
      end
    end
  end

endmodule
module nt_10g_if_shared (
  input wire [63:0]    s_axis_tdata,
  input wire           s_axis_tvalid,
  input wire           s_axis_tlast,
  input wire [7:0]     s_axis_tkeep,
  output wire          s_axis_tready,

  output wire [63:0]   m_axis_tdata,
  output wire          m_axis_tvalid,
  output wire          m_axis_tlast,
  output wire [7:0]    m_axis_tkeep,
  input wire           m_axis_tready,

  input wire           refclk_n,
  input wire           refclk_p,
  input wire           reset,
  input wire           tx_fault,
  input wire           tx_abs,
  output wire          tx_disable,
  input wire           rxn,
  input wire           rxp,
  output wire          txn,
  output wire          txp,
  output wire          areset_clk156_out,
  output wire          clk156_out,
  output wire          gtrxreset_out,
  output wire          gttxreset_out,
  output wire          qplllock_out,
  output wire          qplloutclk_out,
  output wire          qplloutrefclk_out,
  output wire          txuserrdy_out,
  output wire          txusrclk_out,
  output wire          txusrclk2_out,
  output wire          reset_counter_done_out,
  output wire          resetdone
);

  wire signal_detect;
  assign signal_detect = ~tx_abs;

  axi_10g_ethernet_shared axi_10g_ethernet_shared_inst (
    .tx_axis_aresetn(~areset_clk156_out),
    .rx_axis_aresetn(~areset_clk156_out),
    .tx_ifg_delay(8'b0),
    .dclk(clk156_out),
    .txp(txp),
    .txn(txn),
    .rxp(rxp),
    .rxn(rxn),
    .signal_detect(signal_detect),
    .tx_fault(tx_fault),
    .tx_disable(tx_disable),
    .pcspma_status(),
    .sim_speedup_control(1'b0),
    .mac_tx_configuration_vector('h402), // 0x402 => tx enable, deficit idle
    .mac_rx_configuration_vector('h2), // 0x2 -> rx enable
    .mac_status_vector(),
    .pcs_pma_configuration_vector(536'b0),
    .pcs_pma_status_vector(),
    .txusrclk_out(txusrclk_out),
    .txusrclk2_out(txusrclk2_out),
    .gttxreset_out(gttxreset_out),
    .gtrxreset_out(gtrxreset_out),
    .txuserrdy_out(txuserrdy_out),
    .coreclk_out(clk156_out),
    .areset_datapathclk_out(areset_clk156_out),
    .resetdone_out(resetdone),
    .reset_counter_done_out(reset_counter_done_out),
    .qplllock_out(qplllock_out),
    .qplloutclk_out(qplloutclk_out),
    .qplloutrefclk_out(qplloutrefclk_out),
    .refclk_p(refclk_p),
    .refclk_n(refclk_n),
    .reset(reset),
    .s_axis_tx_tdata(s_axis_tdata),
    .s_axis_tx_tkeep(s_axis_tkeep),
    .s_axis_tx_tlast(s_axis_tlast),
    .s_axis_tx_tready(s_axis_tready),
    .s_axis_tx_tvalid(s_axis_tvalid),
    .s_axis_tx_tuser(1'b0),
    .s_axis_pause_tdata(16'b0),
    .s_axis_pause_tvalid(1'b0),
    .m_axis_rx_tdata(m_axis_tdata),
    .m_axis_rx_tkeep(m_axis_tkeep),
    .m_axis_rx_tlast(m_axis_tlast),
    .m_axis_rx_tuser(),
    .m_axis_rx_tvalid(m_axis_tvalid),
    .tx_statistics_valid(),
    .tx_statistics_vector(),
    .rx_statistics_valid(),
    .rx_statistics_vector(),
    .rxrecclk_out()
  );

endmodule
module nt_recv_interpackettime (
  // clock and reset
  input wire clk156,
  input wire rstn156,
  input wire rst_sw156,

  // AXI-S slave interface
  input wire [63:0]    s_axis_tdata,
  input wire [7:0]     s_axis_tkeep,
  input wire           s_axis_tvalid,
  input wire           s_axis_tlast,
  output wire          s_axis_tready,
  input wire [24:0]    s_axis_tuser,

  // AXI-S master interface
  output reg [63:0]    m_axis_tdata,
  output reg [7:0]     m_axis_tkeep,
  output reg           m_axis_tvalid,
  output reg           m_axis_tlast,
  input wire           m_axis_tready,
  output reg [52:0]    m_axis_tuser
);

  // pass through AXI-Stream tready singal
  assign s_axis_tready = m_axis_tready;

  // inter-packet cycles counter
  reg [27:0] cntr_inter_packet_cycles;

  // inter-packet cycles
  reg [27:0] inter_packet_cycles;

  // flag determining whether there is currently a packet transfer active on
  // the AXI-Stream interface
  reg axis_active;

  always @(posedge clk156) begin
    if (~rstn156 | rst_sw156) begin
      m_axis_tdata <= 64'b0;
      m_axis_tkeep <= 8'b0;
      m_axis_tvalid <= 1'b0;
      m_axis_tlast <= 1'b0;
      m_axis_tuser <= 53'b0;

      cntr_inter_packet_cycles <= 28'b0;
      inter_packet_cycles <= 28'b0;
      axis_active <= 1'b0;
    end else begin
      if (m_axis_tready) begin
        // AXI4-Stream slave is ready to receive data
        m_axis_tdata <= s_axis_tdata;
        m_axis_tkeep <= s_axis_tkeep;
        m_axis_tvalid <= s_axis_tvalid;
        m_axis_tlast <= s_axis_tlast;

        if (s_axis_tvalid & ~axis_active) begin
          // this transfer starts a new packet. record inter-packet arrival
          // time
          inter_packet_cycles <= cntr_inter_packet_cycles + 28'b1;
          cntr_inter_packet_cycles <= 28'b0;

          // output inter-packet time in TUSER, if this is the last word of
          // the packet
          if (s_axis_tlast) begin
            m_axis_tuser <= {cntr_inter_packet_cycles + 28'b1, s_axis_tuser};
          end else begin
            m_axis_tuser <= 53'b0;
          end
        end else begin
          // this transfer does not start a new packet, keep inter-packet
          // arrival time
          inter_packet_cycles <= inter_packet_cycles;
          cntr_inter_packet_cycles <= cntr_inter_packet_cycles + 28'b1;

          // output inter-packet time in tuser, if this is the last word of
          // the packet
          if (s_axis_tlast) begin
            m_axis_tuser <= {inter_packet_cycles, s_axis_tuser};
          end else begin
            m_axis_tuser <= 53'b0;
          end
        end

        // does this word end the current transfer?
        axis_active <= s_axis_tvalid ? ~s_axis_tlast : axis_active;
      end else begin
        // AXI4-Stream slave currently not ready to receive data
        m_axis_tdata <= m_axis_tdata;
        m_axis_tkeep <= m_axis_tkeep;
        m_axis_tvalid <= m_axis_tvalid;
        m_axis_tlast <= m_axis_tlast;
        m_axis_tuser <= m_axis_tuser;

        inter_packet_cycles <= inter_packet_cycles;
        cntr_inter_packet_cycles <= cntr_inter_packet_cycles + 28'b1;
      end
    end
  end

endmodule
module nt_10g_if (
  input wire [63:0]    s_axis_tdata,
  input wire           s_axis_tvalid,
  input wire           s_axis_tlast,
  input wire [7:0]     s_axis_tkeep,
  output wire          s_axis_tready,

  output wire [63:0]   m_axis_tdata,
  output wire          m_axis_tvalid,
  output wire          m_axis_tlast,
  output wire [7:0]    m_axis_tkeep,
  input wire           m_axis_tready,

  input wire           tx_fault,
  input wire           tx_abs,
  output wire          tx_disable,
  input wire           rxn,
  input wire           rxp,
  output wire          txn,
  output wire          txp,
  input wire           areset_clk156,
  input wire           clk156,
  input wire           gtrxreset,
  input wire           gttxreset,
  input wire           qplllock,
  input wire           qplloutclk,
  input wire           qplloutrefclk,
  input wire           txuserrdy,
  input wire           txusrclk,
  input wire           txusrclk2,
  input wire           reset_counter_done,
  output wire          tx_resetdone,
  output wire          rx_resetdone
);

  wire signal_detect;
  assign signal_detect = ~tx_abs;

  axi_10g_ethernet axi_10g_ethernet_inst (
    .tx_axis_aresetn(~areset_clk156),
    .rx_axis_aresetn(~areset_clk156),
    .tx_ifg_delay(8'b0),
    .dclk(clk156),
    .txp(txp),
    .txn(txn),
    .rxp(rxp),
    .rxn(rxn),
    .signal_detect(signal_detect),
    .tx_fault(tx_fault),
    .tx_disable(tx_disable),
    .pcspma_status(),
    .sim_speedup_control(1'b0),
    .mac_tx_configuration_vector('h402), // 0x402 => tx enable, deficit idle
    .mac_rx_configuration_vector('h2), // 0x2 -> rx enable
    .mac_status_vector(),
    .pcs_pma_configuration_vector(536'b0),
    .pcs_pma_status_vector(),
    .txusrclk(txusrclk),
    .txusrclk2(txusrclk2),
    .gttxreset(gttxreset),
    .gtrxreset(gtrxreset),
    .txuserrdy(txuserrdy),
    .coreclk(clk156),
    .areset_coreclk(areset_clk156),
    .areset(areset_clk156),
    .tx_resetdone(tx_resetdone),
    .rx_resetdone(rx_resetdone),
    .reset_counter_done(reset_counter_done),
    .qplllock(qplllock),
    .qplloutclk(qplloutclk),
    .qplloutrefclk(qplloutrefclk),
    .txoutclk(),
    .s_axis_tx_tdata(s_axis_tdata),
    .s_axis_tx_tkeep(s_axis_tkeep),
    .s_axis_tx_tlast(s_axis_tlast),
    .s_axis_tx_tready(s_axis_tready),
    .s_axis_tx_tvalid(s_axis_tvalid),
    .s_axis_tx_tuser(1'b0),
    .s_axis_pause_tdata(16'b0),
    .s_axis_pause_tvalid(1'b0),
    .m_axis_rx_tdata(m_axis_tdata),
    .m_axis_rx_tkeep(m_axis_tkeep),
    .m_axis_rx_tlast(m_axis_tlast),
    .m_axis_rx_tuser(),
    .m_axis_rx_tvalid(m_axis_tvalid),
    .tx_statistics_valid(),
    .tx_statistics_vector(),
    .rx_statistics_valid(),
    .rx_statistics_vector(),
    .rxrecclk_out()
  );

endmodule
module lspuf_tb;

	// Inputs
	reg clk;
	reg tigSignal;
	reg [15:0] c;

	// Outputs
	wire respReady;
	wire [9:0] respBitA;
	wire [8:0] respBits;

	// Instantiate the Unit Under Test (UUT)
	lspuf uut (
		.clk(clk), 
		.tigSignal(tigSignal), 
		.c(c), 
		.respReady(respReady), 
		.respBitA(respBitA), 
		.respBits(respBits)
	);

	initial begin
		// Initialize Inputs
		clk = 0;
		tigSignal = 0;
		c = 64'hafbaafbaafbaafb;

		// Wait 100 ns for global reset to finish
		#500;
		tigSignal = 1;
        
		// Add stimulus here

	end
   
	always #50 clk = ~clk;
	
endmodule
module sw_dolut_tb;

	// Inputs
	reg iT;
	reg iB;
	reg c;
	reg vcc;

	// Outputs
	wire oT;
	wire oB;

	// Instantiate the Unit Under Test (UUT)
	sw_dolut uut (
		.iT(iT), 
		.iB(iB), 
		.c(c), 
		.vcc(vcc), 
		.oT(oT), 
		.oB(oB)
	);

	initial begin
		// Initialize Inputs
		iT = 0;
		iB = 0;
		c = 0;
		vcc = 1'b1;

		// Wait 100 ns for global reset to finish
		#100;
		iT = 1;
		iB = 0;
		c = 0;
		
		#100;
		iT = 1;
		iB = 0;
		c = 1;
		
		#100;
		iT = 0;
		iB = 1;
		c = 0;
		
		#100;
		iT = 0;
		iB = 1;
		c = 1;
		
		#100;
		iT = 0;
		iB = 1;
		c = 1;
		
		#100;
		iT = 1;
		iB = 1;
		c = 1;
      

		
	end
      
endmodule
module outputNetwrok_tb;

	// Inputs
	reg [9:0] in;

	// Outputs
	wire [8:0] out;

	// Instantiate the Unit Under Test (UUT)
	outputNetwork uut (
		.in(in), 
		.out(out)
	);

	initial begin
		// Initialize Inputs
		in = 10'b01010101110;

		// Wait 100 ns for global reset to finish
		#100;
        
		// Add stimulus here

	end
      
endmodule
module apuClassic_tb3;

	// Inputs
	reg clk;
	reg tigSignal;
	reg vcc;
	reg [63:0] c;

	// Outputs
	wire respReady;
	wire respBit;

	// Instantiate the Unit Under Test (UUT)
	apufClassic uut (
		.clk(clk), 
		.tigSignal(tigSignal), 
		.vcc(vcc), 
		.c(c), 
		.respReady(respReady), 
		.respBit(respBit)
	);

	initial begin
		// Initialize Inputs
		clk = 0;
		tigSignal = 0;
		vcc = 0;
		c = 0;

		// Wait 100 ns for global reset to finish
		#100;
		vcc = 1;
        
		#100;
		tigSignal = 1;

	end
	
	always #50 clk = ~clk;
      
endmodule
module inputNetwork_tb;

	// Inputs
	reg [7:0] x;

	// Outputs
	wire [7:0] y;
	wire [7:0] z;

	// Instantiate the Unit Under Test (UUT)
	inputNetwork uut (
		.x(x), 
		.y(y),
		.z(z)
	);

	initial begin
		// Initialize Inputs
		x = 8'b01101110;

		// Wait 100 ns for global reset to finish
		#100;
        
		// Add stimulus here

	end
      
endmodule
module inputNetwork_tb_1;

	// Inputs
	reg [63:0] x;

	// Outputs
	wire [63:0] y;

	// Instantiate the Unit Under Test (UUT)
	inputNetwork uut (
		.x(x), 
		.y(y)
	);

	initial begin
		// Initialize Inputs
		x = 64'b1101000011100111001000001110100110100001000110000100011110001100;

		// Wait 100 ns for global reset to finish
		#100;
        
		// Add stimulus here

	end
      
endmodule
module apufClassic_tb;

	// Inputs
	reg clk;
	reg tigSignal;
	reg vcc;
	reg [63:0] c;

	// Outputs
	wire respReady;
	wire respBit;
	wire pathT, pathB,tigReg;

	// Instantiate the Unit Under Test (UUT)
	apufClassic uut (
		.clk(clk), 
		.tigSignal(tigSignal), 
		.vcc(vcc), 
		.c(c), 
		.respReady(respReady), 
		.respBit(respBit),
		.pathT(pathT),
		.pathB(pathB),
		.tigReg(tigReg)
	);

	initial begin
		// Initialize Inputs
		clk = 0;
		tigSignal = 0;
		vcc = 0;
		c = 0;

		#100;
		vcc = 1;
		
		#100;
		tigSignal = 0;
		
		
	end
	
	always #100 clk = ~clk;
      
endmodule
module apufClassic_tb1;

	// Inputs
	reg clk;
	reg tigSignal;
	reg vcc;
	reg [63:0] c;

	// Outputs
	wire respReady;
	wire respBit;
	wire pathT;
	wire pathB;
	wire tigOut;

	// Instantiate the Unit Under Test (UUT)
	apufClassic uut (
		.clk(clk), 
		.tigSignal(tigSignal), 
		.vcc(vcc), 
		.c(c), 
		.respReady(respReady), 
		.respBit(respBit), 
		.pathT(pathT), 
		.pathB(pathB), 
		.tigOut(tigOut)
	);

	initial begin
		// Initialize Inputs
		clk = 0;
		tigSignal = 0;
		vcc = 0;
		c = 0;

		// Wait 100 ns for global reset to finish
		#100;
		
		vcc = 1;
		
		#100;
		tigSignal = 1;
        
		// Add stimulus here

	end
	
	always #50 clk = ~clk;
      
endmodule
module swChain_tb;

	// Inputs
	reg inT;
	reg inB;
	reg [15:0] c;

	// Outputs
	wire outT;
	wire outB;

	// Instantiate the Unit Under Test (UUT)
	switchChain uut (
		.inT(inT), 
		.inB(inB), 
		.c(c), 
		.outT(outT), 
		.outB(outB)
	);

	initial begin
		// Initialize Inputs
		inT = 0;
		inB = 0;
		c = 0;

		// Wait 100 ns for global reset to finish
		#100;
		inT = 1;
		inB = 1;
        
		// Add stimulus here

	end
      
endmodule
module outputNetwork  #(parameter K=10,X=K-1,M=K-1,S=0) (in,out);

	input [K-1:0] in;
	output [M-1:0] out;
	
	genvar i;
	generate
		for(i=0; i<M; i=i+1) begin: OUT
		
			if( (i+S+X-1) < K ) begin
			
				(*KEEP_HIERARCHY="TRUE"*)
				xor_vec #(.X(X)) XG(
					.x(in[(i+S+X-1)%K:i]), 
					.y(out[i])
				);
				
				initial 
			  $display ("<in[%d:%d]>", (i+S+X-1)%K, i);
				
			end else begin
			
				(*KEEP_HIERARCHY="TRUE"*)
				xor_vec #(.X(X)) XG(
					.x({in[K-1:i],in[(i+S+X-1)%K:0]}), 
					.y(out[i])
				);
				
			  initial 
			  $display ("<in[%d:%d] in[%d:0]>",K-1,i,(i+S+X-1)%K);
			end
			
		end
	endgenerate


endmodule
module xor_apuf #(parameter N=16,K=8)(clk,tigSignal,c,respReady,respBitA,respBit);

	input clk;
	input tigSignal;
	input [N-1:0] c;
	output respReady;
	output [K-1:0] respBitA;
	output respBit;

	wire [K-1:0] respReadyA;
	
	assign respReady = &respReadyA;    // When response is ready for sampling
	assign respBit = ^respBitA;        // XOR-ed response

	// APUF 
	genvar i;
	generate
		for(i=0; i<K; i=i+1) begin: PUFList
		
			(* KEEP_HIERARCHY = "TRUE" *)
			apufClassic #(.nStage(N)) APUF(
				.clk(clk), 
				.tigSignal(tigSignal), 
				.vcc(1'b1),
				.c(c),
				.respReady(respReadyA[i]), 
				.respBit(respBitA[i])
			);
			
		end
	endgenerate
		
endmodule
module inputNetwork #(parameter N = 64, nSHIFT = 0)(x,y);

    input  [N-1:0] x;
    output [N-1:0] y;
    
	 wire [N-1:0] z;
	 
    assign z =  (nSHIFT ==0)? x : {x[N-nSHIFT-1:0],x[N-1: N-nSHIFT]};
	 
	 genvar i;
	 generate 
	 for(i=0; i< N-1; i=i+1) begin:net

		if(i==0) begin
			xor(y[N/2],z[i],1'b0);
	   end
		
		if((i%2)==0) begin 
			xor(y[i/2],z[i],z[i+1]);
	   end else begin 
		   xor(y[(N+i+1)/2],z[i],z[i+1]); 
	   end
		
	 end
	 endgenerate

endmodule
module xor_vec #(parameter X=2) (x,y);

	input [X-1:0] x;
	output y;
	
	assign y = ^x;
	
endmodule
module ixor_apuf #(parameter N1=16, N2=N1+1, K1=2, K2=2, POS=N1/2)(
	clk,
	tigSig_t,
	tigSig_b,
	c,
	respReady_t,
	respReady,
	respBitA,
	respBit
	);

	input clk;                        // Clock
	input tigSig_t;                   // Trigger signal for upper XOR APUF
	input tigSig_b;                   // Trigger signal for lower XOR APUF
	input [N1-1:0] c;                 // Challenge
	output respReady_t;               // Response ready status signal for upper XOR APUF
	output respReady;                 // Response ready status signal of iXOR APUF 
	output [K1+K2-1:0] respBitA;          // Response bits of all APUFs
	output respBit;                   // Response of iXOR APUF

	
	wire [N2-1:0] c_b;                   // Challenge for lower xor PUF
	wire [K1-1:0] respBitA_t;         // Responses of APUFs in uppuer XOR PUF
	wire [K2-1:0] respBitA_b;         // Responses of APUFs in lower XOR PUF
	
	wire respBit_t;                   // Response of uppuer XOR PUF
	   
	assign respBitA = {respBitA_t,respBitA_b}; 
	assign c_b = {c[N1-1:POS+1], respBit_t, c[POS:0]}; 	
	
    // UPPER XOR APUF
	(*KEEP_HIERARCHY="TRUE"*)
	xor_apuf #(.N(N1),.K(K1)) XAPUF_T(
	   .clk(clk),
		.tigSignal(tigSig_t),
		.c(c),
		.respReady(respReady_t),
		.respBitA(respBitA_t),
		.respBit(respBit_t)
	);
	
	// LOWER XOR APUF
	(*KEEP_HIERARCHY="TRUE"*)
	xor_apuf #(.N(N2),.K(K2)) XAPUF_B(
		.clk(clk),
		.tigSignal(tigSig_b),
		.c(c_b),
		.respReady(respReady),
		.respBitA(respBitA_b),
		.respBit(respBit)
	);
	
		
endmodule
module sw_dolut(iT,iB,c,vcc,oT,oB);

	input iT,iB;      // Input signals
	input vcc;
	input c;          // Challenge bit
	output oT,oB;     // Output signals
	
	LUT6_2 #( 
		.INIT(64'hccccaaaaaaaacccc) // Specify LUT Contents
	) SW(
		.O6(oT), 
		.O5(oB), 
		.I0(iT), 
		.I1(iB), 
		.I2(vcc), 
		.I3(vcc), 
		.I4(c), 
		.I5(vcc)                //(fast MUX select only available to O6 output)
	);


endmodule
module mux_n21 #(parameter nCTRL = 8)(ins,ctrls,out);

	localparam nIN = 2**nCTRL;
	
	input [nIN-1:0] ins;
	input [nCTRL-1:0] ctrls;
	output out;

	assign out = ins[ctrls];

endmodule