dakies/OSS_Verilog huggingface dataset:
module fc2_ctrl(/*autoport*/
//output
			f6_raddr,
			w6_raddr,
			f7_wr_en,
			fc2_done,
			fc2_clr,
//input
			clk,
			rst_n,
			fc2_start);
	input clk;
	input rst_n;

	//Input Weight and Feature Read Addr
	output [6:0]f6_raddr;
	output [6:0]w6_raddr;
	//Output Feature Write Enable
	output      f7_wr_en;
	//Control Signal
	input fc2_start;
	output fc2_done;
	output fc2_clr;

	localparam	IDLE=3'b001;
	localparam  RUN =3'b010;
	localparam  DONE=3'b100;
	reg[2:0] current_state;
	reg[2:0] next_state;

	reg[6:0] cnt0;

	wire add_cnt0,end_cnt0;
	wire IDLE2RUN_start,RUN2DONE_start;

	always@(posedge clk or negedge rst_n)begin
		if(!rst_n)
			current_state <= IDLE;
		else
			current_state <= next_state;
	end

	always@(*) begin
		case(current_state)
			IDLE:begin
				if(IDLE2RUN_start)
					next_state = RUN;
				else
					next_state = IDLE;
			end
			RUN:begin
				if(RUN2DONE_start)
					next_state = DONE;
				else begin
					next_state = current_state;
				end
			end
			DONE:begin
				next_state = IDLE;
			end
			default: next_state = IDLE;	
		endcase
	end

	assign IDLE2RUN_start = current_state==IDLE && fc2_start == 1'b1;
	assign RUN2DONE_start = current_state==RUN  && end_cnt0;

	always @(posedge clk or negedge  rst_n) begin
		if (!rst_n) begin
			// reset
			cnt0 <= 0;
		end
		else if (add_cnt0) begin
			if(end_cnt0)begin
				cnt0 <= 0;
			end
			else begin
				cnt0 <= cnt0 + 1'b1;
			end
		end
	end

	assign add_cnt0 = current_state==RUN;
	assign end_cnt0 = add_cnt0 && cnt0 == 120-1;

	assign f6_raddr = cnt0;
	assign w6_raddr = cnt0;


	wire f7_wr_en_temp,fc2_clr_temp,fc2_done_temp;
	assign f7_wr_en_temp = end_cnt0;
	assign fc2_clr_temp = cnt0==0 ;
	assign fc2_done_temp = current_state==DONE;
	//add delay
	reg fc2_clr_temp_r1,fc2_clr_temp_r2;
	(* max_fanout = 50 *)reg fc2_clr_temp_r3;
	reg f7_wr_en_temp_r1,f7_wr_en_temp_r2,f7_wr_en_temp_r3,
			f7_wr_en_temp_r4,f7_wr_en_temp_r5,f7_wr_en_temp_r6;
	(* max_fanout = 50 *)reg f7_wr_en_temp_r7;
	reg fc2_done_temp_r1,fc2_done_temp_r2,fc2_done_temp_r3,
			fc2_done_temp_r4,fc2_done_temp_r5,fc2_done_temp_r6,fc2_done_temp_r7;
	//addr2data 2; mac 3;bias 1;relu 1;
	always@(posedge clk)begin

    	f7_wr_en_temp_r1 <= f7_wr_en_temp ;
    	f7_wr_en_temp_r2 <= f7_wr_en_temp_r1 ;
    	f7_wr_en_temp_r3 <= f7_wr_en_temp_r2 ;
    	f7_wr_en_temp_r4 <= f7_wr_en_temp_r3 ;
    	f7_wr_en_temp_r5 <= f7_wr_en_temp_r4 ;
    	f7_wr_en_temp_r6 <= f7_wr_en_temp_r5 ;
    	f7_wr_en_temp_r7 <= f7_wr_en_temp_r6 ;

   		fc2_done_temp_r1 <= fc2_done_temp;
    	fc2_done_temp_r2 <= fc2_done_temp_r1;
    	fc2_done_temp_r3 <= fc2_done_temp_r2;
    	fc2_done_temp_r4 <= fc2_done_temp_r3;
    	fc2_done_temp_r5 <= fc2_done_temp_r4;
    	fc2_done_temp_r6 <= fc2_done_temp_r5;
    	fc2_done_temp_r7 <= fc2_done_temp_r6;
//fc_clr should assert at 2nd cycle of mac,DSP include 1, so here is 2 + 2 -1
    	fc2_clr_temp_r1 <= fc2_clr_temp ;    
    	fc2_clr_temp_r2 <= fc2_clr_temp_r1 ;
    	fc2_clr_temp_r3 <= fc2_clr_temp_r2 ;

	end

	assign f7_wr_en = f7_wr_en_temp_r7;
	assign fc2_clr = fc2_clr_temp_r3;
	assign fc2_done = fc2_done_temp_r7;


endmodule
module fc_unit(/*autoport*/
//output
			d_out,
//input
			clk,
			rst_n,
			d_in,
			b_in,
			wr_en);
	input clk;
	input rst_n;

	input [22:0] 	d_in;
	input [15:0]  	b_in;
	input			wr_en;
	output [15:0] 	d_out;



//--------------------------------
//---stage1: bias add-------------
//-------------------------------- 
wire[22:0] temp1;  
adder_23_16 adder (
  .A(d_in),      // input wire [18 : 0] A
  .B(b_in),      // input wire [15 : 0] B
  .CLK(clk),  // input wire CLK
  .S(temp1)      // output wire [18 : 0] S
);

//--------------------------------
//---stage2: ReLU-----------------
//--------------------------------
wire[15:0] temp2;
assign temp2 = temp1[22]? 0:temp1[22:7];



reg [15:0] temp2_r;
always @(posedge clk or negedge  rst_n) begin
	if (!rst_n) begin
		// reset
		temp2_r <= 0;
	end
	else  begin
		temp2_r <= temp2;
	end
end

//--------------------------------
//--stage3: Write reg-------------
//--------------------------------
reg [15:0] temp3_r;
always@(posedge clk or negedge rst_n)begin
	if(!rst_n)begin
		temp3_r <= 0;
	end
	else if (wr_en) begin
		temp3_r <= temp2_r;
	end
end
assign d_out = temp3_r;

endmodule
module fc3_exec(/*autoport*/
//output
			class0,
			class1,
			class2,
			class3,
			class4,
			class5,
			class6,
			class7,
			class8,
			class9,
//input
			clk,
			rst_n,
			f8_wr_en,
			mac_5);

input clk;
input rst_n;

input f8_wr_en;
input [229:0]	mac_5;	//mac result. mac5_1 ~ mac5_10


output [15:0]  class0;
output [15:0]  class1;
output [15:0]  class2;
output [15:0]  class3;
output [15:0]  class4;
output [15:0]  class5;
output [15:0]  class6;
output [15:0]  class7;
output [15:0]  class8;
output [15:0]  class9;



parameter b_1 = 16'b0000011001000101;
parameter b_2 = 16'b1111100101111001;
parameter b_3 = 16'b0000000001101010;
parameter b_4 = 16'b1111100111010010;
parameter b_5 = 16'b1111110001110001;
parameter b_6 = 16'b1111110100100000;
parameter b_7 = 16'b1111011010010100;
parameter b_8 = 16'b1111100001110001;
parameter b_9 = 16'b0000101110000110;
parameter b_10 = 16'b0000000101111101;






wire [15:0] fc3_d_out[9:0];
wire [15:0] fc3_b_in[9:0];
wire [22:0] fc3_d_in[9:0];
generate
	genvar i;
	for(i=0;i<10;i=i+1)begin:fc3_unit_gen
		fc_unit fc_unit(/*autoinst*/
			.d_out(fc3_d_out[i]),
			.clk(clk),
			.rst_n(rst_n),
			.d_in(fc3_d_in[i]),
			.b_in(fc3_b_in[i]),
			.wr_en(f8_wr_en));
		assign fc3_d_in[i] = mac_5[i*23+22:i*23];
	end
endgenerate


//Bias initial

assign fc3_b_in[0] = b_1;
assign fc3_b_in[1] = b_2;
assign fc3_b_in[2] = b_3;
assign fc3_b_in[3] = b_4;
assign fc3_b_in[4] = b_5;
assign fc3_b_in[5] = b_6;
assign fc3_b_in[6] = b_7;
assign fc3_b_in[7] = b_8;
assign fc3_b_in[8] = b_9;
assign fc3_b_in[9] = b_10;

assign class0 = fc3_d_out[0];
assign class1 = fc3_d_out[1];
assign class2 = fc3_d_out[2];
assign class3 = fc3_d_out[3];
assign class4 = fc3_d_out[4];
assign class5 = fc3_d_out[5];
assign class6 = fc3_d_out[6];
assign class7 = fc3_d_out[7];
assign class8 = fc3_d_out[8];
assign class9 = fc3_d_out[9];
endmodule
module dut (clk, rst, cmd, data, dout );
	parameter N=8;
	input clk;
	input rst; 
	input cmd;
	input [N-1:0] data;
	output [N-1:0] dout;

  reg [N-1:0] count;

  always @(posedge clk or negedge rst)
    if (!rst) begin
 		count <= 0;
    end else begin
		if (cmd == 1'b0) begin 
			count <= data;
		end else begin
			count <= count + 1;
		end
		//$display("DUT count is %0d, %0d, %0d",count, data, cmd);
    end

  assign dout = count;
	
endmodule
module mudi64_tb ();

parameter full = 63;
parameter half = 31;
reg [half:0] opera1;
reg [full:0] opera2;
reg muordi, clock, reset, start;
wire [full:0] result;
wire valid;

mudi64 U1 (result, opera1, opera2, muordi, clock, reset, start, valid);

initial begin
	$dumpfile("mudi64.vcd");
	$dumpvars(0, mudi64_tb);
end

initial muordi = 0;	//0 for multiplication; 1 for divition

initial begin
	clock = 0;
	forever
	#10 clock = ~clock;
end

initial begin
	reset = 0;
	#1 reset = ~reset;
	#1 reset = ~reset;
end

initial begin
	start = 1;
	#100	start = 0;
		opera1 = 32'h15555555;
		opera2 = 32'h55555555;		//Q=4, R=1
	#100 start = ~start;
	#1000	start = ~start;
		opera1 = -32'h15555555;
		opera2 = 32'h55555555;		//Q=fc, R=1
	#100 start = ~start;
	#1000	start = ~start;
		opera1 = 32'h15555555;
		opera2 = -32'h55555555;		//Q=fc, R=ff
	#100 start = ~start;
	#1000	start = ~start;
		opera1 = -32'h15555555;
		opera2 = -32'h55555555;		//Q=4, R=ff
	#100 start = ~start;
	#1000	start = ~start;
		opera1 = 0;
		opera2 = 0;
end

initial begin
	#20000;
	$finish;
end

endmodule
module add32 (sum, cout, a, b, cin);
output [31:0] sum;
output cout;
input [31:0] a, b;
input cin;
wire cin4, cin8, cin12, cin16, cin20, cin24, cin28;
add_4 U1 (sum[3:0], cin4, a[3:0], b[3:0], cin);
add_4 U2 (sum[7:4], cin8, a[7:4], b[7:4], cin4);
add_4 U3 (sum[11:8], cin12, a[11:8], b[11:8], cin8);
add_4 U4 (sum[15:12], cin16, a[15:12], b[15:12], cin12);
add_4 U5 (sum[19:16], cin20, a[19:16], b[19:16], cin16);
add_4 U6 (sum[23:20], cin24, a[23:20], b[23:20], cin20);
add_4 U7 (sum[27:24], cin28, a[27:24], b[27:24], cin24);
add_4 U8 (sum[31:28], cout, a[31:28], b[31:28], cin28);
endmodule
module add_half (sum, cout, a, b);
input a, b;
output cout, sum;
xor (sum, a, b);
and (cout, a, b);
endmodule
module add_full (sum, cout, a, b, cin);
input a, b, cin;
output cout, sum;
wire w1, w2, w3;
add_half U1 (w1, w2, a, b);
add_half U2 (sum, w3, cin, w1);
or (cout, w2, w3);
endmodule
module add_4 (sum, cout, a, b, cin);
output [3:0] sum;
output cout;
input [3:0] a, b;
input cin;
wire cin1, cin2, cin3;
add_full U1 (sum[0], cin1, a[0], b[0], cin);
add_full U2 (sum[1], cin2, a[1], b[1], cin1);
add_full U3 (sum[2], cin3, a[2], b[2], cin2);
add_full U4 (sum[3], cout, a[3], b[3], cin3);
endmodule
module Booth_Multiplier_1xA #(
    parameter N = 16            // Width = N: multiplicand & multiplier
)(
    input   Rst,                // Reset
    input   Clk,                // Clock
    
    input   Ld,                 // Load Registers and Start Multiplier
    input   [(N - 1):0] M,      // Multiplicand
    input   [(N - 1):0] R,      // Multiplier
    output  reg Valid,          // Product Valid
    output  reg [(2*N - 1):0] P // Product <= M * R
);

///////////////////////////////////////////////////////////////////////////////
//
//  Local Parameters
//

///////////////////////////////////////////////////////////////////////////////
//
//  Declarations
//

reg     [4:0] Cntr;             // Operation Counter
reg     [1:0] Booth;            // Booth Recoding Field
reg     Guard;                  // Shift bit for Booth Recoding
reg     [N:0] A;                // Multiplicand w/ sign guard bit
reg     [N:0] B;                // Input Operand to Adder w/ sign guard bit
reg     Ci;                     // Carry input to Adder
reg     [N:0] S;                // Adder w/ sign guard bit
wire    [N:0] Hi;               // Upper half of Product w/ sign guard

reg     [2*N:0] Prod;           // Double length product w/ sign guard bit

///////////////////////////////////////////////////////////////////////////////
//
//  Implementation
//

always @(posedge Clk)
begin
    if(Rst)
        Cntr <= #1 0;
    else if(Ld)
        Cntr <= #1 N;
    else if(|Cntr)
        Cntr <= #1 (Cntr - 1);
end

//  Multiplicand Register
//      includes an additional bit to guard sign bit in the event the
//      most negative value is provided as the multiplicand.

always @(posedge Clk)
begin
    if(Rst)
        A <= #1 0;
    else if(Ld)
        A <= #1 {M[N - 1], M};  
end

//  Compute Upper Partial Product: (N + 1) bits in width

always @(*) Booth <= {Prod[0], Guard};  // Booth's Multiplier Recoding field

assign Hi = Prod[2*N:N];                // Upper Half of the Product Register

always @(*)
begin
    case(Booth)
        2'b01   : {Ci, B} <= {1'b0,  A};
        2'b10   : {Ci, B} <= {1'b1, ~A};
        default : {Ci, B} <= 0;
    endcase
end

always @(*) S <= Hi + B + Ci;

//  Register Partial products and shift right arithmetically.
//      Product register has a sign extension guard bit.

always @(posedge Clk)
begin
    if(Rst)
        Prod <= #1 0;
    else if(Ld)
        Prod <= #1 R;
    else if(|Cntr)  // Arithmetic right shift 1 bit
        Prod <= #1 {S[N], S, Prod[(N - 1):1]};
end

always @(posedge Clk)
begin
    if(Rst)
        Guard <= #1 0;
    else if(Ld)
        Guard <= #1 0;
    else if(|Cntr)
        Guard <= #1 Prod[0];
end

//  Assign the product less the sign extension guard bit to the output port

always @(posedge Clk)
begin
    if(Rst)
        P <= #1 0;
    else if(Cntr == 1)
        P <= #1 {S, Prod[(N - 1):1]};
end

//  Count the number of shifts
//      This implementation does not use any optimizations to perform multiple
//      bit shifts to skip over runs of 1s or 0s.

always @(posedge Clk)
begin
    if(Rst)
        Valid <= #1 0;
    else
        Valid <= #1 (Cntr == 1);
end

endmodule
module Booth_Multiplier #(
    parameter pN = 4                // Width = 2**pN: multiplicand & multiplier
)(
    input   Rst,                    // Reset
    input   Clk,                    // Clock
    
    input   Ld,                     // Load Registers and Start Multiplier
    input   [(2**pN - 1):0] M,      // Multiplicand
    input   [(2**pN - 1):0] R,      // Multiplier
    output  reg Valid,              // Product Valid
    output  reg [(2**(pN+1) - 1):0] P   // Product <= M * R
);

///////////////////////////////////////////////////////////////////////////////
//
//  Local Parameters
//

///////////////////////////////////////////////////////////////////////////////
//
//  Declarations
//

reg     [2**pN:0] A;      // Multiplicand w/ sign guard bit
reg     [   pN:0] Cntr;   // Operation Counter
reg     [2**pN:0] S;      // Adder w/ sign guard bit

reg     [(2**(pN+1) + 1):0] Prod;   // Double length product w/ guard bits

///////////////////////////////////////////////////////////////////////////////
//
//  Implementation
//

always @(posedge Clk)
begin
    if(Rst)
        Cntr <= #1 0;
    else if(Ld)
        Cntr <= #1 2**pN;
    else if(|Cntr)
        Cntr <= #1 (Cntr - 1);
end

//  Multiplicand Register
//      includes an additional bit to guard sign bit in the event the
//      most negative value is provided as the multiplicand.

always @(posedge Clk)
begin
    if(Rst)
        A <= #1 0;
    else if(Ld)
        A <= #1 {M[2**pN - 1], M};  
end

//  Compute Upper Partial Product: (2**pN + 1) bits in width

always @(*)
begin
    case(Prod[1:0])
        2'b01   : S <= Prod[(2**(pN+1) + 1):(2**pN + 1)] + A;
        2'b10   : S <= Prod[(2**(pN+1) + 1):(2**pN + 1)] - A;
        default : S <= Prod[(2**(pN+1) + 1):(2**pN + 1)];
    endcase
end

//  Register Partial products and shift rigth arithmetically.
//      Product register has guard bits on both ends.

always @(posedge Clk)
begin
    if(Rst)
        Prod <= #1 0;
    else if(Ld)
        Prod <= #1 {R, 1'b0};
    else if(|Cntr)
        Prod <= #1 {S[2**pN], S, Prod[2**pN:1]};    // Arithmetic Shift Right
end

//  Assign the product less the two guard bits to the output port

always @(posedge Clk)
begin
    if(Rst)
        P <= #1 0;
    else if(Cntr == 1)
        P <= #1 {S[2**pN], S, Prod[2**pN:2]};
end

//  Count the number of shifts
//      This implementation does not use any optimizations to perform multiple
//      bit shifts to skip over runs of 1s or 0s.

always @(posedge Clk)
begin
    if(Rst)
        Valid <= #1 0;
    else
        Valid <= #1 (Cntr == 1);
end

endmodule
module uart_tx_V2(
    input wire clk,
    input wire [7:0] din,
    input wire wr_en,
    output wire tx_busy,

    output reg tx_p    
);

initial begin
    tx_p = 1'b1;
end

parameter clk_freq = 27000000;
parameter uart_freq = 115200;

localparam STATE_IDLE	= 2'b00;
localparam STATE_START	= 2'b01;
localparam STATE_DATA	= 2'b10;
localparam STATE_STOP	= 2'b11;

reg[7:0] localdin;
reg localwr_en;

//always@(posedge clk)begin
always@(*)begin	
    localdin<=din;
    localwr_en<=wr_en;
end

reg [7:0] data= 8'h00;
reg [2:0] bitpos= 3'h0;
reg [1:0] state= STATE_IDLE;

wire tx_clk;

localparam TX_CLK_MAX = (clk_freq / uart_freq)-1;

reg[$clog2(TX_CLK_MAX+1)+1:0] tx_clkcnt;

assign tx_clk = (tx_clkcnt == 0);

initial tx_clkcnt=0;

always @(posedge clk) begin
	if (tx_clkcnt >= TX_CLK_MAX)
		tx_clkcnt <= 0;
	else
		tx_clkcnt <= tx_clkcnt + 1;
end
	

always @(posedge clk) begin
	case (state)
	STATE_IDLE: begin
		if (localwr_en) begin
			state <= STATE_START;
			data <= localdin;
			bitpos <= 3'h0;
		end
	end
	STATE_START: begin
		if (tx_clk) begin
			tx_p <= 1'b0;
			state <= STATE_DATA;
		end
	end
	STATE_DATA: begin
		if (tx_clk) begin
			if (bitpos == 3'h7)
				state <= STATE_STOP;
			else
				bitpos <= bitpos + 3'h1;
			tx_p <= data[bitpos];
		end
	end
	STATE_STOP: begin
		if (tx_clk) begin
			tx_p <= 1'b1;
			state <= STATE_IDLE;
		end
	end
	default: begin
		tx_p <= 1'b1;
		state <= STATE_IDLE;
	end
	endcase
end

assign tx_busy = (state != STATE_IDLE);

endmodule
module Gowin_rPLL (clkout, clkoutp, lock, clkoutd, clkin);

output clkout;
output clkoutp;
output lock;
output clkoutd;
input clkin;

wire clkoutd3_o;
wire gw_gnd;

assign gw_gnd = 1'b0;

rPLL rpll_inst (
    .CLKOUT(clkout),
    .LOCK(lock),
    .CLKOUTP(clkoutp),
    .CLKOUTD(clkoutd),
    .CLKOUTD3(clkoutd3_o),
    .RESET(gw_gnd),
    .RESET_P(gw_gnd),
    .CLKIN(clkin),
    .CLKFB(gw_gnd),
    .FBDSEL({gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd}),
    .IDSEL({gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd}),
    .ODSEL({gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd}),
    .PSDA({gw_gnd,gw_gnd,gw_gnd,gw_gnd}),
    .DUTYDA({gw_gnd,gw_gnd,gw_gnd,gw_gnd}),
    .FDLY({gw_gnd,gw_gnd,gw_gnd,gw_gnd})
);

// clkout @ 499.5 Mhz
//defparam rpll_inst.FBDIV_SEL = 36;
//defparam rpll_inst.IDIV_SEL = 1;
//defparam rpll_inst.ODIV_SEL = 2;

// clkout @ 398.25 Mhz
defparam rpll_inst.FBDIV_SEL = 58;
defparam rpll_inst.IDIV_SEL = 3;
defparam rpll_inst.ODIV_SEL = 2;

// clkoutd @ 1/4 * clkout
defparam rpll_inst.DYN_SDIV_SEL = 4;

defparam rpll_inst.FCLKIN = "27";
defparam rpll_inst.DYN_IDIV_SEL = "false";
defparam rpll_inst.DYN_FBDIV_SEL = "false";
defparam rpll_inst.DYN_ODIV_SEL = "false";
defparam rpll_inst.PSDA_SEL = "0100";
defparam rpll_inst.DYN_DA_EN = "false";
defparam rpll_inst.DUTYDA_SEL = "1000";
defparam rpll_inst.CLKOUT_FT_DIR = 1'b1;
defparam rpll_inst.CLKOUTP_FT_DIR = 1'b1;
defparam rpll_inst.CLKOUT_DLY_STEP = 0;
defparam rpll_inst.CLKOUTP_DLY_STEP = 0;
defparam rpll_inst.CLKFB_SEL = "internal";
defparam rpll_inst.CLKOUT_BYPASS = "false";
defparam rpll_inst.CLKOUTP_BYPASS = "false";
defparam rpll_inst.CLKOUTD_BYPASS = "false";
defparam rpll_inst.CLKOUTD_SRC = "CLKOUT";
defparam rpll_inst.CLKOUTD3_SRC = "CLKOUT";
defparam rpll_inst.DEVICE = "GW2A-18C";

endmodule //Gowin_rPLL
module xfcp_mod_drp #
(
    parameter XFCP_ID_TYPE = 16'h0001,
    parameter XFCP_ID_STR = "DRP",
    parameter XFCP_EXT_ID = 0,
    parameter XFCP_EXT_ID_STR = "",
    parameter ADDR_WIDTH = 10
)
(
    input  wire                    clk,
    input  wire                    rst,

    /*
     * XFCP upstream interface
     */
    input  wire [7:0]              up_xfcp_in_tdata,
    input  wire                    up_xfcp_in_tvalid,
    output wire                    up_xfcp_in_tready,
    input  wire                    up_xfcp_in_tlast,
    input  wire                    up_xfcp_in_tuser,

    output wire [7:0]              up_xfcp_out_tdata,
    output wire                    up_xfcp_out_tvalid,
    input  wire                    up_xfcp_out_tready,
    output wire                    up_xfcp_out_tlast,
    output wire                    up_xfcp_out_tuser,

    /*
     * DRP interface
     */
    output wire [ADDR_WIDTH-1:0]   drp_addr,
    output wire [15:0]             drp_do,
    input  wire [15:0]             drp_di,
    output wire                    drp_en,
    output wire                    drp_we,
    input  wire                    drp_rdy
);

wire [ADDR_WIDTH-1:0] wb_adr;
wire [15:0] wb_dat_m;
wire [15:0] wb_dat_drp;
wire wb_we;
wire wb_stb;
wire wb_ack_drp;
wire wb_cyc;

xfcp_mod_wb #(
    .XFCP_ID_TYPE(XFCP_ID_TYPE),
    .XFCP_ID_STR(XFCP_ID_STR),
    .XFCP_EXT_ID(XFCP_EXT_ID),
    .XFCP_EXT_ID_STR(XFCP_EXT_ID_STR),
    .COUNT_SIZE(16),
    .WB_DATA_WIDTH(16),
    .WB_ADDR_WIDTH(ADDR_WIDTH),
    .WB_SELECT_WIDTH(1)
)
xfcp_mod_wb_inst (
    .clk(clk),
    .rst(rst),
    .up_xfcp_in_tdata(up_xfcp_in_tdata),
    .up_xfcp_in_tvalid(up_xfcp_in_tvalid),
    .up_xfcp_in_tready(up_xfcp_in_tready),
    .up_xfcp_in_tlast(up_xfcp_in_tlast),
    .up_xfcp_in_tuser(up_xfcp_in_tuser),
    .up_xfcp_out_tdata(up_xfcp_out_tdata),
    .up_xfcp_out_tvalid(up_xfcp_out_tvalid),
    .up_xfcp_out_tready(up_xfcp_out_tready),
    .up_xfcp_out_tlast(up_xfcp_out_tlast),
    .up_xfcp_out_tuser(up_xfcp_out_tuser),
    .wb_adr_o(wb_adr),
    .wb_dat_i(wb_dat_drp),
    .wb_dat_o(wb_dat_m),
    .wb_we_o(wb_we),
    .wb_sel_o(),
    .wb_stb_o(wb_stb),
    .wb_ack_i(wb_ack_drp),
    .wb_err_i(1'b0),
    .wb_cyc_o(wb_cyc)
);

wb_drp #(
    .ADDR_WIDTH(ADDR_WIDTH)
)
wb_drp_inst (
    .clk(clk),
    .rst(rst),
    .wb_adr_i(wb_adr[ADDR_WIDTH-1:0]),
    .wb_dat_i(wb_dat_m),
    .wb_dat_o(wb_dat_drp),
    .wb_we_i(wb_we),
    .wb_stb_i(wb_stb),
    .wb_ack_o(wb_ack_drp),
    .wb_cyc_i(wb_cyc),
    .drp_addr(drp_addr),
    .drp_do(drp_do),
    .drp_di(drp_di),
    .drp_en(drp_en),
    .drp_we(drp_we),
    .drp_rdy(drp_rdy)
);

endmodule
module wb_drp #
(
    parameter ADDR_WIDTH = 16
)
(
    input  wire                    clk,
    input  wire                    rst,

    /*
     * Wishbone interface
     */
    input  wire [ADDR_WIDTH-1:0]   wb_adr_i,   // ADR_I() address
    input  wire [15:0]             wb_dat_i,   // DAT_I() data in
    output wire [15:0]             wb_dat_o,   // DAT_O() data out
    input  wire                    wb_we_i,    // WE_I write enable input
    input  wire                    wb_stb_i,   // STB_I strobe input
    output wire                    wb_ack_o,   // ACK_O acknowledge output
    input  wire                    wb_cyc_i,   // CYC_I cycle input

    /*
     * DRP interface
     */
    output wire [ADDR_WIDTH-1:0]   drp_addr,
    output wire [15:0]             drp_do,
    input  wire [15:0]             drp_di,
    output wire                    drp_en,
    output wire                    drp_we,
    input  wire                    drp_rdy
);

reg cycle = 1'b0;

assign drp_addr = wb_adr_i;
assign drp_do = wb_dat_i;
assign wb_dat_o = drp_di;
assign drp_en = wb_cyc_i & wb_stb_i & ~cycle;
assign drp_we = wb_cyc_i & wb_stb_i & wb_we_i & ~cycle;
assign wb_ack_o = drp_rdy;

always @(posedge clk) begin
    cycle <= wb_cyc_i & wb_stb_i & ~drp_rdy;

    if (rst) begin
        cycle <= 1'b0;
    end
end

endmodule
module test_xfcp_interface_udp;

// Parameters

// Inputs
reg clk = 0;
reg rst = 0;
reg [7:0] current_test = 0;

reg [7:0] s_eth_axis_tdata = 0;
reg s_eth_axis_tvalid = 0;
reg s_eth_axis_tlast = 0;
reg s_eth_axis_tuser = 0;
reg m_eth_axis_tready = 0;
reg [7:0] down_xfcp_in_tdata = 0;
reg down_xfcp_in_tvalid = 0;
reg down_xfcp_in_tlast = 0;
reg down_xfcp_in_tuser = 0;
reg down_xfcp_out_tready = 0;
reg [47:0] local_mac = 0;
reg [31:0] local_ip = 0;
reg [15:0] local_port = 0;
reg [31:0] gateway_ip = 0;
reg [31:0] subnet_mask = 0;

// Outputs
wire s_eth_axis_tready;
wire [7:0] m_eth_axis_tdata;
wire m_eth_axis_tvalid;
wire m_eth_axis_tlast;
wire m_eth_axis_tuser;
wire down_xfcp_in_tready;
wire [7:0] down_xfcp_out_tdata;
wire down_xfcp_out_tvalid;
wire down_xfcp_out_tlast;
wire down_xfcp_out_tuser;

initial begin
    // myhdl integration
    $from_myhdl(
        clk,
        rst,
        current_test,
        s_eth_axis_tdata,
        s_eth_axis_tvalid,
        s_eth_axis_tlast,
        s_eth_axis_tuser,
        m_eth_axis_tready,
        down_xfcp_in_tdata,
        down_xfcp_in_tvalid,
        down_xfcp_in_tlast,
        down_xfcp_in_tuser,
        down_xfcp_out_tready,
        local_mac,
        local_ip,
        local_port,
        gateway_ip,
        subnet_mask
    );
    $to_myhdl(
        s_eth_axis_tready,
        m_eth_axis_tdata,
        m_eth_axis_tvalid,
        m_eth_axis_tlast,
        m_eth_axis_tuser,
        down_xfcp_in_tready,
        down_xfcp_out_tdata,
        down_xfcp_out_tvalid,
        down_xfcp_out_tlast,
        down_xfcp_out_tuser
    );

    // dump file
    $dumpfile("test_xfcp_interface_udp.lxt");
    $dumpvars(0, test_xfcp_interface_udp);
end

xfcp_interface_udp
UUT (
    .clk(clk),
    .rst(rst),
    .s_eth_axis_tdata(s_eth_axis_tdata),
    .s_eth_axis_tvalid(s_eth_axis_tvalid),
    .s_eth_axis_tready(s_eth_axis_tready),
    .s_eth_axis_tlast(s_eth_axis_tlast),
    .s_eth_axis_tuser(s_eth_axis_tuser),
    .m_eth_axis_tdata(m_eth_axis_tdata),
    .m_eth_axis_tvalid(m_eth_axis_tvalid),
    .m_eth_axis_tready(m_eth_axis_tready),
    .m_eth_axis_tlast(m_eth_axis_tlast),
    .m_eth_axis_tuser(m_eth_axis_tuser),
    .down_xfcp_in_tdata(down_xfcp_in_tdata),
    .down_xfcp_in_tvalid(down_xfcp_in_tvalid),
    .down_xfcp_in_tready(down_xfcp_in_tready),
    .down_xfcp_in_tlast(down_xfcp_in_tlast),
    .down_xfcp_in_tuser(down_xfcp_in_tuser),
    .down_xfcp_out_tdata(down_xfcp_out_tdata),
    .down_xfcp_out_tvalid(down_xfcp_out_tvalid),
    .down_xfcp_out_tready(down_xfcp_out_tready),
    .down_xfcp_out_tlast(down_xfcp_out_tlast),
    .down_xfcp_out_tuser(down_xfcp_out_tuser),
    .local_mac(local_mac),
    .local_ip(local_ip),
    .local_port(local_port),
    .gateway_ip(gateway_ip),
    .subnet_mask(subnet_mask)
);

endmodule
module test_xfcp_mod_i2c_master;

// Parameters
parameter XFCP_ID_TYPE = 16'h2C00;
parameter XFCP_ID_STR = "I2C Master";
parameter XFCP_EXT_ID = 0;
parameter XFCP_EXT_ID_STR = "";
parameter DEFAULT_PRESCALE = 1;

// Inputs
reg clk = 0;
reg rst = 0;
reg [7:0] current_test = 0;

reg [7:0] up_xfcp_in_tdata = 0;
reg up_xfcp_in_tvalid = 0;
reg up_xfcp_in_tlast = 0;
reg up_xfcp_in_tuser = 0;
reg up_xfcp_out_tready = 0;
reg i2c_scl_i = 1;
reg i2c_sda_i = 1;

// Outputs
wire up_xfcp_in_tready;
wire [7:0] up_xfcp_out_tdata;
wire up_xfcp_out_tvalid;
wire up_xfcp_out_tlast;
wire up_xfcp_out_tuser;
wire i2c_scl_o;
wire i2c_scl_t;
wire i2c_sda_o;
wire i2c_sda_t;

initial begin
    // myhdl integration
    $from_myhdl(
        clk,
        rst,
        current_test,
        up_xfcp_in_tdata,
        up_xfcp_in_tvalid,
        up_xfcp_in_tlast,
        up_xfcp_in_tuser,
        up_xfcp_out_tready,
        i2c_scl_i,
        i2c_sda_i
    );
    $to_myhdl(
        up_xfcp_in_tready,
        up_xfcp_out_tdata,
        up_xfcp_out_tvalid,
        up_xfcp_out_tlast,
        up_xfcp_out_tuser,
        i2c_scl_o,
        i2c_scl_t,
        i2c_sda_o,
        i2c_sda_t
    );

    // dump file
    $dumpfile("test_xfcp_mod_i2c_master.lxt");
    $dumpvars(0, test_xfcp_mod_i2c_master);
end

xfcp_mod_i2c_master #(
    .XFCP_ID_TYPE(XFCP_ID_TYPE),
    .XFCP_ID_STR(XFCP_ID_STR),
    .XFCP_EXT_ID(XFCP_EXT_ID),
    .XFCP_EXT_ID_STR(XFCP_EXT_ID_STR),
    .DEFAULT_PRESCALE(DEFAULT_PRESCALE)
)
UUT (
    .clk(clk),
    .rst(rst),
    .up_xfcp_in_tdata(up_xfcp_in_tdata),
    .up_xfcp_in_tvalid(up_xfcp_in_tvalid),
    .up_xfcp_in_tready(up_xfcp_in_tready),
    .up_xfcp_in_tlast(up_xfcp_in_tlast),
    .up_xfcp_in_tuser(up_xfcp_in_tuser),
    .up_xfcp_out_tdata(up_xfcp_out_tdata),
    .up_xfcp_out_tvalid(up_xfcp_out_tvalid),
    .up_xfcp_out_tready(up_xfcp_out_tready),
    .up_xfcp_out_tlast(up_xfcp_out_tlast),
    .up_xfcp_out_tuser(up_xfcp_out_tuser),
    .i2c_scl_i(i2c_scl_i),
    .i2c_scl_o(i2c_scl_o),
    .i2c_scl_t(i2c_scl_t),
    .i2c_sda_i(i2c_sda_i),
    .i2c_sda_o(i2c_sda_o),
    .i2c_sda_t(i2c_sda_t)
);

endmodule
module test_wb_drp;

// Parameters
parameter ADDR_WIDTH = 16;

// Inputs
reg clk = 0;
reg rst = 0;
reg [7:0] current_test = 0;

reg [ADDR_WIDTH-1:0] wb_adr_i = 0;
reg [15:0] wb_dat_i = 0;
reg wb_we_i = 0;
reg wb_stb_i = 0;
reg wb_cyc_i = 0;
reg [15:0] drp_di = 0;
reg drp_rdy = 0;

// Outputs
wire [15:0] wb_dat_o;
wire wb_ack_o;
wire [ADDR_WIDTH-1:0] drp_addr;
wire [15:0] drp_do;
wire drp_en;
wire drp_we;

initial begin
    // myhdl integration
    $from_myhdl(
        clk,
        rst,
        current_test,
        wb_adr_i,
        wb_dat_i,
        wb_we_i,
        wb_stb_i,
        wb_cyc_i,
        drp_di,
        drp_rdy
    );
    $to_myhdl(
        wb_dat_o,
        wb_ack_o,
        drp_addr,
        drp_do,
        drp_en,
        drp_we
    );

    // dump file
    $dumpfile("test_wb_drp.lxt");
    $dumpvars(0, test_wb_drp);
end

wb_drp #(
    .ADDR_WIDTH(ADDR_WIDTH)
)
UUT (
    .clk(clk),
    .rst(rst),
    .wb_adr_i(wb_adr_i),
    .wb_dat_i(wb_dat_i),
    .wb_dat_o(wb_dat_o),
    .wb_we_i(wb_we_i),
    .wb_stb_i(wb_stb_i),
    .wb_ack_o(wb_ack_o),
    .wb_cyc_i(wb_cyc_i),
    .drp_addr(drp_addr),
    .drp_do(drp_do),
    .drp_di(drp_di),
    .drp_en(drp_en),
    .drp_we(drp_we),
    .drp_rdy(drp_rdy)
);

endmodule
module test_xfcp_arb_2;

// Parameters
parameter PORTS = 2;

// Inputs
reg clk = 0;
reg rst = 0;
reg [7:0] current_test = 0;

reg [PORTS*8-1:0] up_xfcp_in_tdata = 0;
reg [PORTS-1:0] up_xfcp_in_tvalid = 0;
reg [PORTS-1:0] up_xfcp_in_tlast = 0;
reg [PORTS-1:0] up_xfcp_in_tuser = 0;
reg [PORTS-1:0] up_xfcp_out_tready = 0;
reg [7:0] down_xfcp_in_tdata = 0;
reg down_xfcp_in_tvalid = 0;
reg down_xfcp_in_tlast = 0;
reg down_xfcp_in_tuser = 0;
reg down_xfcp_out_tready = 0;

// Outputs
wire [PORTS-1:0] up_xfcp_in_tready;
wire [PORTS*8-1:0] up_xfcp_out_tdata;
wire [PORTS-1:0] up_xfcp_out_tvalid;
wire [PORTS-1:0] up_xfcp_out_tlast;
wire [PORTS-1:0] up_xfcp_out_tuser;
wire down_xfcp_in_tready;
wire [7:0] down_xfcp_out_tdata;
wire down_xfcp_out_tvalid;
wire down_xfcp_out_tlast;
wire down_xfcp_out_tuser;

initial begin
    // myhdl integration
    $from_myhdl(
        clk,
        rst,
        current_test,
        up_xfcp_in_tdata,
        up_xfcp_in_tvalid,
        up_xfcp_in_tlast,
        up_xfcp_in_tuser,
        up_xfcp_out_tready,
        down_xfcp_in_tdata,
        down_xfcp_in_tvalid,
        down_xfcp_in_tlast,
        down_xfcp_in_tuser,
        down_xfcp_out_tready
    );
    $to_myhdl(
        up_xfcp_in_tready,
        up_xfcp_out_tdata,
        up_xfcp_out_tvalid,
        up_xfcp_out_tlast,
        up_xfcp_out_tuser,
        down_xfcp_in_tready,
        down_xfcp_out_tdata,
        down_xfcp_out_tvalid,
        down_xfcp_out_tlast,
        down_xfcp_out_tuser
    );

    // dump file
    $dumpfile("test_xfcp_arb_2.lxt");
    $dumpvars(0, test_xfcp_arb_2);
end

xfcp_arb #(
    .PORTS(PORTS)
)
UUT (
    .clk(clk),
    .rst(rst),
    .up_xfcp_in_tdata(up_xfcp_in_tdata),
    .up_xfcp_in_tvalid(up_xfcp_in_tvalid),
    .up_xfcp_in_tready(up_xfcp_in_tready),
    .up_xfcp_in_tlast(up_xfcp_in_tlast),
    .up_xfcp_in_tuser(up_xfcp_in_tuser),
    .up_xfcp_out_tdata(up_xfcp_out_tdata),
    .up_xfcp_out_tvalid(up_xfcp_out_tvalid),
    .up_xfcp_out_tready(up_xfcp_out_tready),
    .up_xfcp_out_tlast(up_xfcp_out_tlast),
    .up_xfcp_out_tuser(up_xfcp_out_tuser),
    .down_xfcp_in_tdata(down_xfcp_in_tdata),
    .down_xfcp_in_tvalid(down_xfcp_in_tvalid),
    .down_xfcp_in_tready(down_xfcp_in_tready),
    .down_xfcp_in_tlast(down_xfcp_in_tlast),
    .down_xfcp_in_tuser(down_xfcp_in_tuser),
    .down_xfcp_out_tdata(down_xfcp_out_tdata),
    .down_xfcp_out_tvalid(down_xfcp_out_tvalid),
    .down_xfcp_out_tready(down_xfcp_out_tready),
    .down_xfcp_out_tlast(down_xfcp_out_tlast),
    .down_xfcp_out_tuser(down_xfcp_out_tuser)
);

endmodule
module test_xfcp_interface_uart;

// Parameters

// Inputs
reg clk = 0;
reg rst = 0;
reg [7:0] current_test = 0;

reg uart_rxd = 1;
reg [7:0] down_xfcp_in_tdata = 0;
reg down_xfcp_in_tvalid = 0;
reg down_xfcp_in_tlast = 0;
reg down_xfcp_in_tuser = 0;
reg down_xfcp_out_tready = 0;
reg [15:0] prescale = 0;

// Outputs
wire uart_txd;
wire down_xfcp_in_tready;
wire [7:0] down_xfcp_out_tdata;
wire down_xfcp_out_tvalid;
wire down_xfcp_out_tlast;
wire down_xfcp_out_tuser;

initial begin
    // myhdl integration
    $from_myhdl(
        clk,
        rst,
        current_test,
        uart_rxd,
        down_xfcp_in_tdata,
        down_xfcp_in_tvalid,
        down_xfcp_in_tlast,
        down_xfcp_in_tuser,
        down_xfcp_out_tready,
        prescale
    );
    $to_myhdl(
        uart_txd,
        down_xfcp_in_tready,
        down_xfcp_out_tdata,
        down_xfcp_out_tvalid,
        down_xfcp_out_tlast,
        down_xfcp_out_tuser
    );

    // dump file
    $dumpfile("test_xfcp_interface_uart.lxt");
    $dumpvars(0, test_xfcp_interface_uart);
end

xfcp_interface_uart
UUT (
    .clk(clk),
    .rst(rst),
    .uart_rxd(uart_rxd),
    .uart_txd(uart_txd),
    .down_xfcp_in_tdata(down_xfcp_in_tdata),
    .down_xfcp_in_tvalid(down_xfcp_in_tvalid),
    .down_xfcp_in_tready(down_xfcp_in_tready),
    .down_xfcp_in_tlast(down_xfcp_in_tlast),
    .down_xfcp_in_tuser(down_xfcp_in_tuser),
    .down_xfcp_out_tdata(down_xfcp_out_tdata),
    .down_xfcp_out_tvalid(down_xfcp_out_tvalid),
    .down_xfcp_out_tready(down_xfcp_out_tready),
    .down_xfcp_out_tlast(down_xfcp_out_tlast),
    .down_xfcp_out_tuser(down_xfcp_out_tuser),
    .prescale(prescale)
);

endmodule
module test_xfcp_switch_4;

// Parameters
parameter PORTS = 4;
parameter XFCP_ID_TYPE = 16'h0100;
parameter XFCP_ID_STR = "XFCP Switch";
parameter XFCP_EXT_ID = 0;
parameter XFCP_EXT_ID_STR = "";

// Inputs
reg clk = 0;
reg rst = 0;
reg [7:0] current_test = 0;

reg [7:0] up_xfcp_in_tdata = 0;
reg up_xfcp_in_tvalid = 0;
reg up_xfcp_in_tlast = 0;
reg up_xfcp_in_tuser = 0;
reg up_xfcp_out_tready = 0;
reg [PORTS*8-1:0] down_xfcp_in_tdata = 0;
reg [PORTS-1:0] down_xfcp_in_tvalid = 0;
reg [PORTS-1:0] down_xfcp_in_tlast = 0;
reg [PORTS-1:0] down_xfcp_in_tuser = 0;
reg [PORTS-1:0] down_xfcp_out_tready = 0;

// Outputs
wire up_xfcp_in_tready;
wire [7:0] up_xfcp_out_tdata;
wire up_xfcp_out_tvalid;
wire up_xfcp_out_tlast;
wire up_xfcp_out_tuser;
wire [PORTS-1:0] down_xfcp_in_tready;
wire [PORTS*8-1:0] down_xfcp_out_tdata;
wire [PORTS-1:0] down_xfcp_out_tvalid;
wire [PORTS-1:0] down_xfcp_out_tlast;
wire [PORTS-1:0] down_xfcp_out_tuser;

initial begin
    // myhdl integration
    $from_myhdl(
        clk,
        rst,
        current_test,
        up_xfcp_in_tdata,
        up_xfcp_in_tvalid,
        up_xfcp_in_tlast,
        up_xfcp_in_tuser,
        up_xfcp_out_tready,
        down_xfcp_in_tdata,
        down_xfcp_in_tvalid,
        down_xfcp_in_tlast,
        down_xfcp_in_tuser,
        down_xfcp_out_tready
    );
    $to_myhdl(
        up_xfcp_in_tready,
        up_xfcp_out_tdata,
        up_xfcp_out_tvalid,
        up_xfcp_out_tlast,
        up_xfcp_out_tuser,
        down_xfcp_in_tready,
        down_xfcp_out_tdata,
        down_xfcp_out_tvalid,
        down_xfcp_out_tlast,
        down_xfcp_out_tuser
    );

    // dump file
    $dumpfile("test_xfcp_switch_4.lxt");
    $dumpvars(0, test_xfcp_switch_4);
end

xfcp_switch #(
    .PORTS(PORTS),
    .XFCP_ID_TYPE(XFCP_ID_TYPE),
    .XFCP_ID_STR(XFCP_ID_STR),
    .XFCP_EXT_ID(XFCP_EXT_ID),
    .XFCP_EXT_ID_STR(XFCP_EXT_ID_STR)
)
UUT (
    .clk(clk),
    .rst(rst),
    .up_xfcp_in_tdata(up_xfcp_in_tdata),
    .up_xfcp_in_tvalid(up_xfcp_in_tvalid),
    .up_xfcp_in_tready(up_xfcp_in_tready),
    .up_xfcp_in_tlast(up_xfcp_in_tlast),
    .up_xfcp_in_tuser(up_xfcp_in_tuser),
    .up_xfcp_out_tdata(up_xfcp_out_tdata),
    .up_xfcp_out_tvalid(up_xfcp_out_tvalid),
    .up_xfcp_out_tready(up_xfcp_out_tready),
    .up_xfcp_out_tlast(up_xfcp_out_tlast),
    .up_xfcp_out_tuser(up_xfcp_out_tuser),
    .down_xfcp_in_tdata(down_xfcp_in_tdata),
    .down_xfcp_in_tvalid(down_xfcp_in_tvalid),
    .down_xfcp_in_tready(down_xfcp_in_tready),
    .down_xfcp_in_tlast(down_xfcp_in_tlast),
    .down_xfcp_in_tuser(down_xfcp_in_tuser),
    .down_xfcp_out_tdata(down_xfcp_out_tdata),
    .down_xfcp_out_tvalid(down_xfcp_out_tvalid),
    .down_xfcp_out_tready(down_xfcp_out_tready),
    .down_xfcp_out_tlast(down_xfcp_out_tlast)
);

endmodule
module test_xfcp_mod_wb_32;

// Parameters
parameter XFCP_ID_TYPE = 16'h0001;
parameter XFCP_ID_STR = "WB Master";
parameter XFCP_EXT_ID = 0;
parameter XFCP_EXT_ID_STR = "";
parameter COUNT_SIZE = 16;
parameter WB_DATA_WIDTH = 32;
parameter WB_ADDR_WIDTH = 32;
parameter WB_SELECT_WIDTH = (WB_DATA_WIDTH/8);

// Inputs
reg clk = 0;
reg rst = 0;
reg [7:0] current_test = 0;

reg [7:0] up_xfcp_in_tdata = 0;
reg up_xfcp_in_tvalid = 0;
reg up_xfcp_in_tlast = 0;
reg up_xfcp_in_tuser = 0;
reg up_xfcp_out_tready = 0;
reg [WB_DATA_WIDTH-1:0] wb_dat_i = 0;
reg wb_ack_i = 0;
reg wb_err_i = 0;

// Outputs
wire up_xfcp_in_tready;
wire [7:0] up_xfcp_out_tdata;
wire up_xfcp_out_tvalid;
wire up_xfcp_out_tlast;
wire up_xfcp_out_tuser;
wire [WB_ADDR_WIDTH-1:0] wb_adr_o;
wire [WB_DATA_WIDTH-1:0] wb_dat_o;
wire wb_we_o;
wire [WB_SELECT_WIDTH-1:0] wb_sel_o;
wire wb_stb_o;
wire wb_cyc_o;

initial begin
    // myhdl integration
    $from_myhdl(
        clk,
        rst,
        current_test,
        up_xfcp_in_tdata,
        up_xfcp_in_tvalid,
        up_xfcp_in_tlast,
        up_xfcp_in_tuser,
        up_xfcp_out_tready,
        wb_dat_i,
        wb_ack_i,
        wb_err_i
    );
    $to_myhdl(
        up_xfcp_in_tready,
        up_xfcp_out_tdata,
        up_xfcp_out_tvalid,
        up_xfcp_out_tlast,
        up_xfcp_out_tuser,
        wb_adr_o,
        wb_dat_o,
        wb_we_o,
        wb_sel_o,
        wb_stb_o,
        wb_cyc_o
    );

    // dump file
    $dumpfile("test_xfcp_mod_wb_32.lxt");
    $dumpvars(0, test_xfcp_mod_wb_32);
end

xfcp_mod_wb #(
    .XFCP_ID_TYPE(XFCP_ID_TYPE),
    .XFCP_ID_STR(XFCP_ID_STR),
    .XFCP_EXT_ID(XFCP_EXT_ID),
    .XFCP_EXT_ID_STR(XFCP_EXT_ID_STR),
    .COUNT_SIZE(COUNT_SIZE),
    .WB_DATA_WIDTH(WB_DATA_WIDTH),
    .WB_ADDR_WIDTH(WB_ADDR_WIDTH),
    .WB_SELECT_WIDTH(WB_SELECT_WIDTH)
)
UUT (
    .clk(clk),
    .rst(rst),
    .up_xfcp_in_tdata(up_xfcp_in_tdata),
    .up_xfcp_in_tvalid(up_xfcp_in_tvalid),
    .up_xfcp_in_tready(up_xfcp_in_tready),
    .up_xfcp_in_tlast(up_xfcp_in_tlast),
    .up_xfcp_in_tuser(up_xfcp_in_tuser),
    .up_xfcp_out_tdata(up_xfcp_out_tdata),
    .up_xfcp_out_tvalid(up_xfcp_out_tvalid),
    .up_xfcp_out_tready(up_xfcp_out_tready),
    .up_xfcp_out_tlast(up_xfcp_out_tlast),
    .up_xfcp_out_tuser(up_xfcp_out_tuser),
    .wb_adr_o(wb_adr_o),
    .wb_dat_i(wb_dat_i),
    .wb_dat_o(wb_dat_o),
    .wb_we_o(wb_we_o),
    .wb_sel_o(wb_sel_o),
    .wb_stb_o(wb_stb_o),
    .wb_ack_i(wb_ack_i),
    .wb_err_i(wb_err_i),
    .wb_cyc_o(wb_cyc_o)
);

endmodule
module test_i2c_init;

// Parameters

// Inputs
reg clk = 0;
reg rst = 0;
reg [7:0] current_test = 0;

reg m_axis_cmd_ready = 0;
reg m_axis_data_tready = 0;
reg start = 0;

// Outputs
wire [6:0] m_axis_cmd_address;
wire m_axis_cmd_start;
wire m_axis_cmd_read;
wire m_axis_cmd_write;
wire m_axis_cmd_write_multiple;
wire m_axis_cmd_stop;
wire m_axis_cmd_valid;
wire [7:0] m_axis_data_tdata;
wire m_axis_data_tvalid;
wire m_axis_data_tlast;
wire busy;

initial begin
    // myhdl integration
    $from_myhdl(
        clk,
        rst,
        current_test,
        m_axis_cmd_ready,
        m_axis_data_tready,
        start);
    $to_myhdl(
        m_axis_cmd_address,
        m_axis_cmd_start,
        m_axis_cmd_read,
        m_axis_cmd_write,
        m_axis_cmd_write_multiple,
        m_axis_cmd_stop,
        m_axis_cmd_valid,
        m_axis_data_tdata,
        m_axis_data_tvalid,
        m_axis_data_tlast,
        busy
    );

    // dump file
    $dumpfile("test_i2c_init.lxt");
    $dumpvars(0, test_i2c_init);
end

i2c_init
UUT (
    .clk(clk),
    .rst(rst),
    .m_axis_cmd_address(m_axis_cmd_address),
    .m_axis_cmd_start(m_axis_cmd_start),
    .m_axis_cmd_read(m_axis_cmd_read),
    .m_axis_cmd_write(m_axis_cmd_write),
    .m_axis_cmd_write_multiple(m_axis_cmd_write_multiple),
    .m_axis_cmd_stop(m_axis_cmd_stop),
    .m_axis_cmd_valid(m_axis_cmd_valid),
    .m_axis_cmd_ready(m_axis_cmd_ready),
    .m_axis_data_tdata(m_axis_data_tdata),
    .m_axis_data_tvalid(m_axis_data_tvalid),
    .m_axis_data_tready(m_axis_data_tready),
    .m_axis_data_tlast(m_axis_data_tlast),
    .busy(busy),
    .start(start)
);

endmodule
module test_i2c_master_wbs_16;

// Parameters
parameter DEFAULT_PRESCALE = 1;
parameter FIXED_PRESCALE = 0;
parameter CMD_FIFO = 1;
parameter CMD_FIFO_ADDR_WIDTH = 5;
parameter WRITE_FIFO = 1;
parameter WRITE_FIFO_ADDR_WIDTH = 5;
parameter READ_FIFO = 1;
parameter READ_FIFO_ADDR_WIDTH = 5;

// Inputs
reg clk = 0;
reg rst = 0;
reg [7:0] current_test = 0;

reg [2:0] wbs_adr_i = 0;
reg [15:0] wbs_dat_i = 0;
reg wbs_we_i = 0;
reg [1:0] wbs_sel_i = 0;
reg wbs_stb_i = 0;
reg wbs_cyc_i = 0;
reg i2c_scl_i = 1;
reg i2c_sda_i = 1;

// Outputs
wire [15:0] wbs_dat_o;
wire wbs_ack_o;
wire i2c_scl_o;
wire i2c_scl_t;
wire i2c_sda_o;
wire i2c_sda_t;

initial begin
    // myhdl integration
    $from_myhdl(
        clk,
        rst,
        current_test,
        wbs_adr_i,
        wbs_dat_i,
        wbs_we_i,
        wbs_sel_i,
        wbs_stb_i,
        wbs_cyc_i,
        i2c_scl_i,
        i2c_sda_i
    );
    $to_myhdl(
        wbs_dat_o,
        wbs_ack_o,
        i2c_scl_o,
        i2c_scl_t,
        i2c_sda_o,
        i2c_sda_t
    );

    // dump file
    $dumpfile("test_i2c_master_wbs_16.lxt");
    $dumpvars(0, test_i2c_master_wbs_16);
end

i2c_master_wbs_16 #(
    .DEFAULT_PRESCALE(DEFAULT_PRESCALE),
    .FIXED_PRESCALE(FIXED_PRESCALE),
    .CMD_FIFO(CMD_FIFO),
    .CMD_FIFO_ADDR_WIDTH(CMD_FIFO_ADDR_WIDTH),
    .WRITE_FIFO(WRITE_FIFO),
    .WRITE_FIFO_ADDR_WIDTH(WRITE_FIFO_ADDR_WIDTH),
    .READ_FIFO(READ_FIFO),
    .READ_FIFO_ADDR_WIDTH(READ_FIFO_ADDR_WIDTH)
)
UUT (
    .clk(clk),
    .rst(rst),
    .wbs_adr_i(wbs_adr_i),
    .wbs_dat_i(wbs_dat_i),
    .wbs_dat_o(wbs_dat_o),
    .wbs_we_i(wbs_we_i),
    .wbs_sel_i(wbs_sel_i),
    .wbs_stb_i(wbs_stb_i),
    .wbs_ack_o(wbs_ack_o),
    .wbs_cyc_i(wbs_cyc_i),
    .i2c_scl_i(i2c_scl_i),
    .i2c_scl_o(i2c_scl_o),
    .i2c_scl_t(i2c_scl_t),
    .i2c_sda_i(i2c_sda_i),
    .i2c_sda_o(i2c_sda_o),
    .i2c_sda_t(i2c_sda_t)
);

endmodule
module test_i2c_master;

// Parameters

// Inputs
reg clk = 0;
reg rst = 0;
reg [7:0] current_test = 0;

reg [6:0] s_axis_cmd_address = 0;
reg s_axis_cmd_start = 0;
reg s_axis_cmd_read = 0;
reg s_axis_cmd_write = 0;
reg s_axis_cmd_write_multiple = 0;
reg s_axis_cmd_stop = 0;
reg s_axis_cmd_valid = 0;
reg [7:0] s_axis_data_tdata = 0;
reg s_axis_data_tvalid = 0;
reg s_axis_data_tlast = 0;
reg m_axis_data_tready = 0;
reg scl_i = 1;
reg sda_i = 1;
reg [15:0] prescale = 0;
reg stop_on_idle = 0;

// Outputs
wire s_axis_cmd_ready;
wire s_axis_data_tready;
wire [7:0] m_axis_data_tdata;
wire m_axis_data_tvalid;
wire m_axis_data_tlast;
wire scl_o;
wire scl_t;
wire sda_o;
wire sda_t;
wire busy;
wire bus_control;
wire bus_active;
wire missed_ack;

initial begin
    // myhdl integration
    $from_myhdl(
        clk,
        rst,
        current_test,
        s_axis_cmd_address,
        s_axis_cmd_start,
        s_axis_cmd_read,
        s_axis_cmd_write,
        s_axis_cmd_write_multiple,
        s_axis_cmd_stop,
        s_axis_cmd_valid,
        s_axis_data_tdata,
        s_axis_data_tvalid,
        s_axis_data_tlast,
        m_axis_data_tready,
        scl_i,
        sda_i,
        prescale,
        stop_on_idle
    );
    $to_myhdl(
        s_axis_cmd_ready,
        s_axis_data_tready,
        m_axis_data_tdata,
        m_axis_data_tvalid,
        m_axis_data_tlast,
        scl_o,
        scl_t,
        sda_o,
        sda_t,
        busy,
        bus_control,
        bus_active,
        missed_ack
    );

    // dump file
    $dumpfile("test_i2c_master.lxt");
    $dumpvars(0, test_i2c_master);
end

i2c_master
UUT (
    .clk(clk),
    .rst(rst),
    .s_axis_cmd_address(s_axis_cmd_address),
    .s_axis_cmd_start(s_axis_cmd_start),
    .s_axis_cmd_read(s_axis_cmd_read),
    .s_axis_cmd_write(s_axis_cmd_write),
    .s_axis_cmd_write_multiple(s_axis_cmd_write_multiple),
    .s_axis_cmd_stop(s_axis_cmd_stop),
    .s_axis_cmd_valid(s_axis_cmd_valid),
    .s_axis_cmd_ready(s_axis_cmd_ready),
    .s_axis_data_tdata(s_axis_data_tdata),
    .s_axis_data_tvalid(s_axis_data_tvalid),
    .s_axis_data_tready(s_axis_data_tready),
    .s_axis_data_tlast(s_axis_data_tlast),
    .m_axis_data_tdata(m_axis_data_tdata),
    .m_axis_data_tvalid(m_axis_data_tvalid),
    .m_axis_data_tready(m_axis_data_tready),
    .m_axis_data_tlast(m_axis_data_tlast),
    .scl_i(scl_i),
    .scl_o(scl_o),
    .scl_t(scl_t),
    .sda_i(sda_i),
    .sda_o(sda_o),
    .sda_t(sda_t),
    .busy(busy),
    .bus_control(bus_control),
    .bus_active(bus_active),
    .missed_ack(missed_ack),
    .prescale(prescale),
    .stop_on_idle(stop_on_idle)
);

endmodule
module test_i2c_master_axil;

// Parameters
parameter DEFAULT_PRESCALE = 1;
parameter FIXED_PRESCALE = 0;
parameter CMD_FIFO = 1;
parameter CMD_FIFO_ADDR_WIDTH = 5;
parameter WRITE_FIFO = 1;
parameter WRITE_FIFO_ADDR_WIDTH = 5;
parameter READ_FIFO = 1;
parameter READ_FIFO_ADDR_WIDTH = 5;

// Inputs
reg clk = 0;
reg rst = 0;
reg [7:0] current_test = 0;

reg [3:0] s_axil_awaddr = 0;
reg [2:0] s_axil_awprot = 0;
reg s_axil_awvalid = 0;
reg [31:0] s_axil_wdata = 0;
reg [3:0] s_axil_wstrb = 0;
reg s_axil_wvalid = 0;
reg s_axil_bready = 0;
reg [3:0] s_axil_araddr = 0;
reg [2:0] s_axil_arprot = 0;
reg s_axil_arvalid = 0;
reg s_axil_rready = 0;
reg i2c_scl_i = 1;
reg i2c_sda_i = 1;

// Outputs
wire s_axil_awready;
wire s_axil_wready;
wire [1:0] s_axil_bresp;
wire s_axil_bvalid;
wire s_axil_arready;
wire [31:0] s_axil_rdata;
wire [1:0] s_axil_rresp;
wire s_axil_rvalid;
wire i2c_scl_o;
wire i2c_scl_t;
wire i2c_sda_o;
wire i2c_sda_t;

initial begin
    // myhdl integration
    $from_myhdl(
        clk,
        rst,
        current_test,
        s_axil_awaddr,
        s_axil_awprot,
        s_axil_awvalid,
        s_axil_wdata,
        s_axil_wstrb,
        s_axil_wvalid,
        s_axil_bready,
        s_axil_araddr,
        s_axil_arprot,
        s_axil_arvalid,
        s_axil_rready,
        i2c_scl_i,
        i2c_sda_i
    );
    $to_myhdl(
        s_axil_awready,
        s_axil_wready,
        s_axil_bresp,
        s_axil_bvalid,
        s_axil_arready,
        s_axil_rdata,
        s_axil_rresp,
        s_axil_rvalid,
        i2c_scl_o,
        i2c_scl_t,
        i2c_sda_o,
        i2c_sda_t
    );

    // dump file
    $dumpfile("test_i2c_master_axil.lxt");
    $dumpvars(0, test_i2c_master_axil);
end

i2c_master_axil #(
    .DEFAULT_PRESCALE(DEFAULT_PRESCALE),
    .FIXED_PRESCALE(FIXED_PRESCALE),
    .CMD_FIFO(CMD_FIFO),
    .CMD_FIFO_ADDR_WIDTH(CMD_FIFO_ADDR_WIDTH),
    .WRITE_FIFO(WRITE_FIFO),
    .WRITE_FIFO_ADDR_WIDTH(WRITE_FIFO_ADDR_WIDTH),
    .READ_FIFO(READ_FIFO),
    .READ_FIFO_ADDR_WIDTH(READ_FIFO_ADDR_WIDTH)
)
UUT (
    .clk(clk),
    .rst(rst),
    .s_axil_awaddr(s_axil_awaddr),
    .s_axil_awprot(s_axil_awprot),
    .s_axil_awvalid(s_axil_awvalid),
    .s_axil_awready(s_axil_awready),
    .s_axil_wdata(s_axil_wdata),
    .s_axil_wstrb(s_axil_wstrb),
    .s_axil_wvalid(s_axil_wvalid),
    .s_axil_wready(s_axil_wready),
    .s_axil_bresp(s_axil_bresp),
    .s_axil_bvalid(s_axil_bvalid),
    .s_axil_bready(s_axil_bready),
    .s_axil_araddr(s_axil_araddr),
    .s_axil_arprot(s_axil_arprot),
    .s_axil_arvalid(s_axil_arvalid),
    .s_axil_arready(s_axil_arready),
    .s_axil_rdata(s_axil_rdata),
    .s_axil_rresp(s_axil_rresp),
    .s_axil_rvalid(s_axil_rvalid),
    .s_axil_rready(s_axil_rready),
    .i2c_scl_i(i2c_scl_i),
    .i2c_scl_o(i2c_scl_o),
    .i2c_scl_t(i2c_scl_t),
    .i2c_sda_i(i2c_sda_i),
    .i2c_sda_o(i2c_sda_o),
    .i2c_sda_t(i2c_sda_t)
);

endmodule
module test_i2c_slave_wbm;

// Parameters
parameter FILTER_LEN = 4;
parameter WB_DATA_WIDTH = 32;
parameter WB_ADDR_WIDTH = 16;
parameter WB_SELECT_WIDTH = WB_DATA_WIDTH/8;

// Inputs
reg clk = 0;
reg rst = 0;
reg [7:0] current_test = 0;

reg i2c_scl_i = 1;
reg i2c_sda_i = 1;
reg [WB_DATA_WIDTH-1:0] wb_dat_i = 0;
reg wb_ack_i = 0;
reg wb_err_i = 0;
reg enable = 0;
reg [6:0] device_address = 0;

// Outputs
wire i2c_scl_o;
wire i2c_scl_t;
wire i2c_sda_o;
wire i2c_sda_t;
wire [WB_ADDR_WIDTH-1:0] wb_adr_o;
wire [WB_DATA_WIDTH-1:0] wb_dat_o;
wire wb_we_o;
wire [WB_SELECT_WIDTH-1:0] wb_sel_o;
wire wb_stb_o;
wire wb_cyc_o;
wire busy;
wire bus_addressed;
wire bus_active;

initial begin
    // myhdl integration
    $from_myhdl(
        clk,
        rst,
        current_test,
        i2c_scl_i,
        i2c_sda_i,
        wb_dat_i,
        wb_ack_i,
        wb_err_i,
        enable,
        device_address
    );
    $to_myhdl(
        i2c_scl_o,
        i2c_scl_t,
        i2c_sda_o,
        i2c_sda_t,
        wb_adr_o,
        wb_dat_o,
        wb_we_o,
        wb_sel_o,
        wb_stb_o,
        wb_cyc_o,
        busy,
        bus_addressed,
        bus_active
    );

    // dump file
    $dumpfile("test_i2c_slave_wbm.lxt");
    $dumpvars(0, test_i2c_slave_wbm);
end

i2c_slave_wbm #(
    .FILTER_LEN(FILTER_LEN),
    .WB_DATA_WIDTH(WB_DATA_WIDTH),
    .WB_ADDR_WIDTH(WB_ADDR_WIDTH),
    .WB_SELECT_WIDTH(WB_SELECT_WIDTH)
)
UUT (
    .clk(clk),
    .rst(rst),
    .i2c_scl_i(i2c_scl_i),
    .i2c_scl_o(i2c_scl_o),
    .i2c_scl_t(i2c_scl_t),
    .i2c_sda_i(i2c_sda_i),
    .i2c_sda_o(i2c_sda_o),
    .i2c_sda_t(i2c_sda_t),
    .wb_adr_o(wb_adr_o),
    .wb_dat_i(wb_dat_i),
    .wb_dat_o(wb_dat_o),
    .wb_we_o(wb_we_o),
    .wb_sel_o(wb_sel_o),
    .wb_stb_o(wb_stb_o),
    .wb_ack_i(wb_ack_i),
    .wb_err_i(wb_err_i),
    .wb_cyc_o(wb_cyc_o),
    .busy(busy),
    .bus_addressed(bus_addressed),
    .bus_active(bus_active),
    .enable(enable),
    .device_address(device_address)
);

endmodule