data/full_repos/permissive/497870922/testbench/tb_i2c.v
1: b'%Warning-STMTDLY: data/full_repos/permissive/497870922/testbench/tb_i2c.v:121: Unsupported: Ignoring delay on this delayed statement.\n     # HALF_CLOCK_PERIOD_50M;\n     ^\n                  ... Use "/* verilator lint_off STMTDLY */" and lint_on around source to disable this message.\n%Warning-STMTDLY: data/full_repos/permissive/497870922/testbench/tb_i2c.v:123: Unsupported: Ignoring delay on this delayed statement.\n     # HALF_CLOCK_PERIOD_50M;\n     ^\n%Error: data/full_repos/permissive/497870922/testbench/tb_i2c.v:129: syntax error, unexpected \'@\'\n   @(posedge clk);\n   ^\n%Warning-STMTDLY: data/full_repos/permissive/497870922/testbench/tb_i2c.v:130: Unsupported: Ignoring delay on this delayed statement.\n   #PERIOD;\n   ^\n%Error: data/full_repos/permissive/497870922/testbench/tb_i2c.v:146: syntax error, unexpected \'@\'\n   @(posedge clk);\n   ^\n%Error: data/full_repos/permissive/497870922/testbench/tb_i2c.v:149: syntax error, unexpected \'@\'\n   @(posedge clk);\n   ^\n%Warning-STMTDLY: data/full_repos/permissive/497870922/testbench/tb_i2c.v:180: Unsupported: Ignoring delay on this delayed statement.\n   while(TiP) #1;\n              ^\n%Warning-STMTDLY: data/full_repos/permissive/497870922/testbench/tb_i2c.v:196: Unsupported: Ignoring delay on this delayed statement.\n   while(TiP) #1;\n              ^\n%Warning-STMTDLY: data/full_repos/permissive/497870922/testbench/tb_i2c.v:211: Unsupported: Ignoring delay on this delayed statement.\n #10;\n ^\n%Warning-STMTDLY: data/full_repos/permissive/497870922/testbench/tb_i2c.v:213: Unsupported: Ignoring delay on this delayed statement.\n #100;\n ^\n%Warning-STMTDLY: data/full_repos/permissive/497870922/testbench/tb_i2c.v:216: Unsupported: Ignoring delay on this delayed statement.\n #5;\n ^\n%Error: data/full_repos/permissive/497870922/testbench/tb_i2c.v:218: syntax error, unexpected \'@\'\n repeat(1) @(posedge clk);\n           ^\n%Warning-STMTDLY: data/full_repos/permissive/497870922/testbench/tb_i2c.v:277: Unsupported: Ignoring delay on this delayed statement.\n #50000;\n ^\n%Warning-STMTDLY: data/full_repos/permissive/497870922/testbench/tb_i2c.v:302: Unsupported: Ignoring delay on this delayed statement.\n  while (i2c_busy) #1;\n                   ^\n%Warning-STMTDLY: data/full_repos/permissive/497870922/testbench/tb_i2c.v:305: Unsupported: Ignoring delay on this delayed statement.\n  #5000;\n  ^\n%Warning-STMTDLY: data/full_repos/permissive/497870922/testbench/tb_i2c.v:310: Unsupported: Ignoring delay on this delayed statement.\n #5000;\n ^\n%Error: Exiting due to 4 error(s), 12 warning(s)\n        ... See the manual and https://verilator.org for more assistance.\n'
module tb_i2c ();


	reg clk;
	reg resetn;
	reg i2c_slave_rst;
	reg [7:0] mem [0:3];


	parameter HALF_CLOCK_PERIOD_50M 	= 10;
	parameter HALF_CLOCK_PERIOD_10M 	= 50;
	parameter HALF_CLOCK_PERIOD_1M 		= 500;
	parameter HALF_CLOCK_PERIOD_100K 	= 5000;
	parameter PERIOD = 100;
	parameter SADR = 7'b001_0000;


	tri1 scl, sda;

	wire scl_padoen_oe, sda_padoen_oe;
	wire scl_pad_o, sda_pad_o;
	wire scl_pad_i, sda_pad_i;

	assign scl = scl_padoen_oe ? 1'bz : scl_pad_o;
	assign sda = sda_padoen_oe ? 1'bz : sda_pad_o;
	assign scl_pad_i = scl;
	assign sda_pad_i = sda;


	wire [7:0] rx_byte;
	wire [7:0] status;
	reg [7:0] data_input = 0;
	reg [4:0] enable = 0;

	parameter EN_PRER_LO = 5'b0_0001;
	parameter EN_PRER_HI = 5'b0_0010;
	parameter EN_CTR 	 = 5'b0_0100;
	parameter EN_TXR 	 = 5'b0_1000;
	parameter EN_CR 	 = 5'b1_0000;

	integer i;


	i2c_master_top i2c_master (
		.clk_i(clk),
		.arst_i(resetn),
	

		.reg_i(data_input),
		.en_prer_lo_i(enable[0]),
		.en_prer_hi_i(enable[1]),
		.en_ctr_i(enable[2]),
		.en_txr_i(enable[3]),
		.en_cr_i(enable[4]),
	
		.rxr_o(rx_byte),
		.sr_o(status),
	


		.scl_pad_i(scl_pad_i),
		.scl_pad_o(scl_pad_o),
		.scl_padoen_o(scl_padoen_oe),
	

		.sda_pad_i(sda_pad_i),
		.sda_pad_o(sda_pad_o),
		.sda_padoen_o(sda_padoen_oe)
	);


	i2cSlaveTop i2c_slave_full (
		.clk(clk),
  		.rst(i2c_slave_rst),
  		.sda(sda),
  		.scl(scl)
	);


	wire irq_flag;
	wire TiP;
	wire al;
	wire i2c_busy;
	wire RxACK;

	assign irq_flag = status[0];
	assign TiP 		= status[1];
	assign al 		= status[5];
	assign i2c_busy = status[6];
	assign RxACK 	= status[7];


	parameter CORE_ENABLE 	   = 8'b1000_0000;
	parameter CORE_DISABLE	   = 8'b0000_0000;
	parameter CORE_IRQ_ENABLE  = 8'b0100_0000;
	parameter CORE_IRQ_DISABLE = 8'b0000_0000;


	parameter READ_TO_SLAVE	   = 1'b1;
	parameter WRITE_TO_SLAVE   = 1'b0;


	parameter START_BIT = 8'b1000_0000;
	parameter STOP_BIT	= 8'b0100_0000;
	parameter READ		= 8'b0010_0000;
	parameter WRITE		= 8'b0001_0000;
	parameter NACK		= 8'b0000_1000;
	parameter IRQ_ACK	= 8'b0000_0001;


	always begin		
    	clk   = 1;
    	# HALF_CLOCK_PERIOD_50M;
    	clk   = 0;
    	# HALF_CLOCK_PERIOD_50M;
	end


	task WaitClock;
		begin
			@(posedge clk);
			#PERIOD;
		end
	endtask

	task send_stop;
		begin
			WaitClock;
			write_reg(EN_CR, STOP_BIT | NACK);
			WaitClock;
		end
	endtask

	task write_reg; 
		input [4:0] sel_enable;
		input [7:0] data_w_r;
		begin
			@(posedge clk);
			enable = sel_enable;
			data_input = data_w_r;
			@(posedge clk);
			enable = 5'b0_0000;
		end
		
	endtask

	task read_slave;
		input [4:0] sel_enable;
		input [7:0] data_w_r;
		begin
			write_reg(sel_enable, data_w_r);

		end
	endtask

	task send_byte;
		input [7:0] byte_to_send;
		begin
			WaitClock;

			if (!RxACK) begin
		    	WaitClock;
		   		write_reg(EN_TXR, byte_to_send);
		   		WaitClock;
		   		write_reg(EN_CR, WRITE);
		   		WaitClock;
			end else begin

		    	$stop;
			end

			while(TiP) #1;

		end
	endtask

	task send_adr_dir;
		input [6:0] adr_to_send;
		input dir;
		begin
			WaitClock;
			write_reg(EN_TXR, {adr_to_send,dir});
			WaitClock;
			write_reg(EN_CR, START_BIT | WRITE);
			WaitClock;


			while(TiP) #1;

		end
	endtask

initial begin
	
	clk   = 0;
	resetn = 1;

	mem[0] = 0;
	mem[1] = 0;
	mem[2] = 0;
	mem[3] = 0;

	#10;
	i2c_slave_rst = 1;
	#100;
	i2c_slave_rst = 0;

	#5;
	resetn = 1'b0;
	repeat(1) @(posedge clk);
	resetn = 1'b1;

	$display("");










	write_reg(EN_PRER_LO, 8'h13);
	WaitClock;
	write_reg(EN_PRER_HI, 8'h00);
	WaitClock;
	write_reg(EN_CTR, CORE_ENABLE);
	WaitClock;

	$display("---------------------------------------------------");
	$display("WRITE TO A SLAVE");
	$display("---------------------------------------------------");


	send_adr_dir(SADR,WRITE_TO_SLAVE);


	send_byte(8'h00);
	

	send_byte(8'hAA);


	send_byte(8'hBB);


	send_byte(8'hCC);


	send_byte(8'hDD);


	send_stop;


   	if (i2c_slave_full.u_i2cSlave.myReg0 == 8'hAA) $display("PASS first  transmission");
   	else $display("FAIL first  transmission");
	if (i2c_slave_full.u_i2cSlave.myReg1 == 8'hBB) $display("PASS second transmission");
   	else $display("FAIL second transmission");
   	if (i2c_slave_full.u_i2cSlave.myReg2 == 8'hCC) $display("PASS third  transmission");
   	else $display("FAIL third  transmission");
   	if (i2c_slave_full.u_i2cSlave.myReg3 == 8'hDD) $display("PASS fourth transmission");
   	else $display("FAIL fourth transmission");

   	$display("---------------------------------------------------");	
	$display("READ FROM A SLAVE");
	$display("---------------------------------------------------");
	#50000;
	
	mem[0] = i2c_slave_full.u_i2cSlave.myReg0;
	mem[1] = i2c_slave_full.u_i2cSlave.myReg1;
	mem[2] = i2c_slave_full.u_i2cSlave.myReg2;
	mem[3] = i2c_slave_full.u_i2cSlave.myReg3;



	for(i=0;i<=3;i=i+1) begin

		send_adr_dir(SADR,WRITE_TO_SLAVE);


		send_byte(i);


		send_adr_dir(SADR,READ_TO_SLAVE);


		read_slave(EN_CR, READ);


		send_stop;

		while (i2c_busy) #1;
		if (rx_byte == mem[i]) $display("PASS: Expected: %H, Received: %H", mem[i], rx_byte);
		else $display("FAIL: Expected: %H, Received: %H", mem[i], rx_byte);
		#5000;
	end

	$display("");

	#5000;
	$stop;

end

endmodule
module tb_i2c ();



	reg clk;
	reg resetn;
	reg i2c_slave_rst;
	reg [7:0] mem [0:3];


	parameter HALF_CLOCK_PERIOD_50M 	= 10;
	parameter HALF_CLOCK_PERIOD_10M 	= 50;
	parameter HALF_CLOCK_PERIOD_1M 		= 500;
	parameter HALF_CLOCK_PERIOD_100K 	= 5000;
	parameter PERIOD = 100;
	parameter SADR = 7'b001_0000;


	tri1 scl, sda;

	wire scl_padoen_oe, sda_padoen_oe;
	wire scl_pad_o, sda_pad_o;
	wire scl_pad_i, sda_pad_i;

	assign scl = scl_padoen_oe ? 1'bz : scl_pad_o;
	assign sda = sda_padoen_oe ? 1'bz : sda_pad_o;
	assign scl_pad_i = scl;
	assign sda_pad_i = sda;


	wire [7:0] rx_byte;
	wire [7:0] status;
	reg [7:0] data_input = 0;
	reg [4:0] enable = 0;

	parameter EN_PRER_LO = 5'b0_0001;
	parameter EN_PRER_HI = 5'b0_0010;
	parameter EN_CTR 	 = 5'b0_0100;
	parameter EN_TXR 	 = 5'b0_1000;
	parameter EN_CR 	 = 5'b1_0000;

	integer i;


	i2c_master_top i2c_master (
		.clk_i(clk),
		.arst_i(resetn),
	

		.reg_i(data_input),
		.en_prer_lo_i(enable[0]),
		.en_prer_hi_i(enable[1]),
		.en_ctr_i(enable[2]),
		.en_txr_i(enable[3]),
		.en_cr_i(enable[4]),
	
		.rxr_o(rx_byte),
		.sr_o(status),
	


		.scl_pad_i(scl_pad_i),
		.scl_pad_o(scl_pad_o),
		.scl_padoen_o(scl_padoen_oe),
	

		.sda_pad_i(sda_pad_i),
		.sda_pad_o(sda_pad_o),
		.sda_padoen_o(sda_padoen_oe)
	);


	i2cSlaveTop i2c_slave_full (
		.clk(clk),
  		.rst(i2c_slave_rst),
  		.sda(sda),
  		.scl(scl)
	);


	wire irq_flag;
	wire TiP;
	wire al;
	wire i2c_busy;
	wire RxACK;

	assign irq_flag = status[0];
	assign TiP 		= status[1];
	assign al 		= status[5];
	assign i2c_busy = status[6];
	assign RxACK 	= status[7];


	parameter CORE_ENABLE 	   = 8'b1000_0000;
	parameter CORE_DISABLE	   = 8'b0000_0000;
	parameter CORE_IRQ_ENABLE  = 8'b0100_0000;
	parameter CORE_IRQ_DISABLE = 8'b0000_0000;


	parameter READ_TO_SLAVE	   = 1'b1;
	parameter WRITE_TO_SLAVE   = 1'b0;


	parameter START_BIT = 8'b1000_0000;
	parameter STOP_BIT	= 8'b0100_0000;
	parameter READ		= 8'b0010_0000;
	parameter WRITE		= 8'b0001_0000;
	parameter NACK		= 8'b0000_1000;
	parameter IRQ_ACK	= 8'b0000_0001;


	always begin		
    	clk   = 1;
    	# HALF_CLOCK_PERIOD_50M;
    	clk   = 0;
    	# HALF_CLOCK_PERIOD_50M;
	end


	task WaitClock;
		begin
			@(posedge clk);
			#PERIOD;
		end
	endtask

	task send_stop;
		begin
			WaitClock;
			write_reg(EN_CR, STOP_BIT | NACK);
			WaitClock;
		end
	endtask

	task write_reg; 
		input [4:0] sel_enable;
		input [7:0] data_w_r;
		begin
			@(posedge clk);
			enable = sel_enable;
			data_input = data_w_r;
			@(posedge clk);
			enable = 5'b0_0000;
		end
		
	endtask

	task read_slave;
		input [4:0] sel_enable;
		input [7:0] data_w_r;
		begin
			write_reg(sel_enable, data_w_r);

		end
	endtask

	task send_byte;
		input [7:0] byte_to_send;
		begin
			WaitClock;

			if (!RxACK) begin
		    	WaitClock;
		   		write_reg(EN_TXR, byte_to_send);
		   		WaitClock;
		   		write_reg(EN_CR, WRITE);
		   		WaitClock;
			end else begin

		    	$stop;
			end

			while(TiP) #1;

		end
	endtask

	task send_adr_dir;
		input [6:0] adr_to_send;
		input dir;
		begin
			WaitClock;
			write_reg(EN_TXR, {adr_to_send,dir});
			WaitClock;
			write_reg(EN_CR, START_BIT | WRITE);
			WaitClock;


			while(TiP) #1;

		end
	endtask

initial begin
	
	clk   = 0;
	resetn = 1;

	mem[0] = 0;
	mem[1] = 0;
	mem[2] = 0;
	mem[3] = 0;

	#10;
	i2c_slave_rst = 1;
	#100;
	i2c_slave_rst = 0;

	#5;
	resetn = 1'b0;
	repeat(1) @(posedge clk);
	resetn = 1'b1;

	$display("");










	write_reg(EN_PRER_LO, 8'h13);
	WaitClock;
	write_reg(EN_PRER_HI, 8'h00);
	WaitClock;
	write_reg(EN_CTR, CORE_ENABLE);
	WaitClock;

	$display("---------------------------------------------------");
	$display("WRITE TO A SLAVE");
	$display("---------------------------------------------------");


	send_adr_dir(SADR,WRITE_TO_SLAVE);


	send_byte(8'h00);
	

	send_byte(8'hAA);


	send_byte(8'hBB);


	send_byte(8'hCC);


	send_byte(8'hDD);


	send_stop;


   	if (i2c_slave_full.u_i2cSlave.myReg0 == 8'hAA) $display("PASS first  transmission");
   	else $display("FAIL first  transmission");
	if (i2c_slave_full.u_i2cSlave.myReg1 == 8'hBB) $display("PASS second transmission");
   	else $display("FAIL second transmission");
   	if (i2c_slave_full.u_i2cSlave.myReg2 == 8'hCC) $display("PASS third  transmission");
   	else $display("FAIL third  transmission");
   	if (i2c_slave_full.u_i2cSlave.myReg3 == 8'hDD) $display("PASS fourth transmission");
   	else $display("FAIL fourth transmission");

   	$display("---------------------------------------------------");	
	$display("READ FROM A SLAVE");
	$display("---------------------------------------------------");
	#50000;
	
	mem[0] = i2c_slave_full.u_i2cSlave.myReg0;
	mem[1] = i2c_slave_full.u_i2cSlave.myReg1;
	mem[2] = i2c_slave_full.u_i2cSlave.myReg2;
	mem[3] = i2c_slave_full.u_i2cSlave.myReg3;



	for(i=0;i<=3;i=i+1) begin

		send_adr_dir(SADR,WRITE_TO_SLAVE);


		send_byte(i);


		send_adr_dir(SADR,READ_TO_SLAVE);


		read_slave(EN_CR, READ);


		send_stop;

		while (i2c_busy) #1;
		if (rx_byte == mem[i]) $display("PASS: Expected: %H, Received: %H", mem[i], rx_byte);
		else $display("FAIL: Expected: %H, Received: %H", mem[i], rx_byte);
		#5000;
	end

	$display("");

	#5000;
	$stop;

end

endmodule