data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v
None: at end of input
1: b'%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:8: Cannot find include file: spio_uart_common.h\n`include "spio_uart_common.h" \n         ^~~~~~~~~~~~~~~~~~~~\n        ... Looked in:\n             data/full_repos/permissive/19591557/modules/uart,data/full_repos/permissive/19591557/spio_uart_common.h\n             data/full_repos/permissive/19591557/modules/uart,data/full_repos/permissive/19591557/spio_uart_common.h.v\n             data/full_repos/permissive/19591557/modules/uart,data/full_repos/permissive/19591557/spio_uart_common.h.sv\n             spio_uart_common.h\n             spio_uart_common.h.v\n             spio_uart_common.h.sv\n             obj_dir/spio_uart_common.h\n             obj_dir/spio_uart_common.h.v\n             obj_dir/spio_uart_common.h.sv\n%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:23: Define or directive not defined: \'`PKT_LEN\'\nwire [`PKT_LEN-1:0] tx_data_i [1:0];\n      ^~~~~~~~\n%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:28: Define or directive not defined: \'`PKT_LEN\'\nwire [`PKT_LEN-1:0] rx_data_expected_i [1:0];\n      ^~~~~~~~\n%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:29: Define or directive not defined: \'`PKT_LEN\'\nwire [`PKT_LEN-1:0] rx_data_i [1:0];\n      ^~~~~~~~\n%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:141: syntax error, unexpected \'@\'\n @(negedge reset_i[1]);\n ^\n%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:142: syntax error, unexpected \'@\'\n #(WAIT_TIME) @(posedge clk_i[0]);\n              ^\n%Warning-STMTDLY: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:142: Unsupported: Ignoring delay on this delayed statement.\n #(WAIT_TIME) @(posedge clk_i[0]);\n ^\n                  ... Use "/* verilator lint_off STMTDLY */" and lint_on around source to disable this message.\n%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:146: syntax error, unexpected \'@\'\n #(WAIT_TIME) @(posedge clk_i[0]);\n              ^\n%Warning-STMTDLY: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:146: Unsupported: Ignoring delay on this delayed statement.\n #(WAIT_TIME) @(posedge clk_i[0]);\n ^\n%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:148: syntax error, unexpected \'@\'\n @(posedge clk_i[0]);\n ^\n%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:153: syntax error, unexpected \'@\'\n #(WAIT_TIME) @(posedge clk_i[0]);\n              ^\n%Warning-STMTDLY: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:153: Unsupported: Ignoring delay on this delayed statement.\n #(WAIT_TIME) @(posedge clk_i[0]);\n ^\n%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:161: syntax error, unexpected \'@\'\n  #(WAIT_TIME) @(posedge clk_i[0]);\n               ^\n%Warning-STMTDLY: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:161: Unsupported: Ignoring delay on this delayed statement.\n  #(WAIT_TIME) @(posedge clk_i[0]);\n  ^\n%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:164: syntax error, unexpected \'@\'\n  @(posedge clk_i[1]);\n  ^\n%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:167: syntax error, unexpected \'@\'\n  #(WAIT_TIME) @(posedge clk_i[0]);\n               ^\n%Warning-STMTDLY: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:167: Unsupported: Ignoring delay on this delayed statement.\n  #(WAIT_TIME) @(posedge clk_i[0]);\n  ^\n%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:170: syntax error, unexpected \'@\'\n  @(posedge clk_i[1]);\n  ^\n%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:173: syntax error, unexpected \'@\'\n  #(WAIT_TIME) @(posedge clk_i[0]);\n               ^\n%Warning-STMTDLY: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:173: Unsupported: Ignoring delay on this delayed statement.\n  #(WAIT_TIME) @(posedge clk_i[0]);\n  ^\n%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:176: syntax error, unexpected \'@\'\n  @(posedge clk_i[1]);\n  ^\n%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:181: syntax error, unexpected \'@\'\n  #(WAIT_TIME) @(posedge clk_i[0]);\n               ^\n%Warning-STMTDLY: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:181: Unsupported: Ignoring delay on this delayed statement.\n  #(WAIT_TIME) @(posedge clk_i[0]);\n  ^\n%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:184: syntax error, unexpected \'@\'\n  @(posedge clk_i[1]);\n  ^\n%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:187: syntax error, unexpected \'@\'\n  #(WAIT_TIME) @(posedge clk_i[0]);\n               ^\n%Warning-STMTDLY: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:187: Unsupported: Ignoring delay on this delayed statement.\n  #(WAIT_TIME) @(posedge clk_i[0]);\n  ^\n%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:190: syntax error, unexpected \'@\'\n  @(posedge clk_i[1]);\n  ^\n%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:193: syntax error, unexpected \'@\'\n  #(WAIT_TIME) @(posedge clk_i[0]);\n               ^\n%Warning-STMTDLY: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:193: Unsupported: Ignoring delay on this delayed statement.\n  #(WAIT_TIME) @(posedge clk_i[0]);\n  ^\n%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:196: syntax error, unexpected \'@\'\n  @(posedge clk_i[1]);\n  ^\n%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:199: syntax error, unexpected \'@\'\n  #(WAIT_TIME) @(posedge clk_i[0]);\n               ^\n%Warning-STMTDLY: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:199: Unsupported: Ignoring delay on this delayed statement.\n  #(WAIT_TIME) @(posedge clk_i[0]);\n  ^\n%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:202: syntax error, unexpected \'@\'\n  @(posedge clk_i[1]);\n  ^\n%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:205: syntax error, unexpected \'@\'\n  #(WAIT_TIME) @(posedge clk_i[0]);\n               ^\n%Warning-STMTDLY: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:205: Unsupported: Ignoring delay on this delayed statement.\n  #(WAIT_TIME) @(posedge clk_i[0]);\n  ^\n%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:208: syntax error, unexpected \'@\'\n  @(posedge clk_i[1]);\n  ^\n%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:213: syntax error, unexpected \'@\'\n  #(WAIT_TIME) @(posedge clk_i[0]);\n               ^\n%Warning-STMTDLY: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:213: Unsupported: Ignoring delay on this delayed statement.\n  #(WAIT_TIME) @(posedge clk_i[0]);\n  ^\n%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:216: syntax error, unexpected \'@\'\n  @(posedge clk_i[1]);\n  ^\n%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:219: syntax error, unexpected \'@\'\n  #(WAIT_TIME) @(posedge clk_i[0]);\n               ^\n%Warning-STMTDLY: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:219: Unsupported: Ignoring delay on this delayed statement.\n  #(WAIT_TIME) @(posedge clk_i[0]);\n  ^\n%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:222: syntax error, unexpected \'@\'\n  @(posedge clk_i[1]);\n  ^\n%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:225: syntax error, unexpected \'@\'\n  #(WAIT_TIME) @(posedge clk_i[0]);\n               ^\n%Warning-STMTDLY: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:225: Unsupported: Ignoring delay on this delayed statement.\n  #(WAIT_TIME) @(posedge clk_i[0]);\n  ^\n%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:228: syntax error, unexpected \'@\'\n  @(posedge clk_i[1]);\n  ^\n%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:231: syntax error, unexpected \'@\'\n  #(WAIT_TIME) @(posedge clk_i[0]);\n               ^\n%Warning-STMTDLY: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:231: Unsupported: Ignoring delay on this delayed statement.\n  #(WAIT_TIME) @(posedge clk_i[0]);\n  ^\n%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:234: syntax error, unexpected \'@\'\n  @(posedge clk_i[1]);\n  ^\n%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:239: syntax error, unexpected \'@\'\n #(WAIT_TIME) @(posedge clk_i[0]);\n              ^\n%Warning-STMTDLY: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:239: Unsupported: Ignoring delay on this delayed statement.\n #(WAIT_TIME) @(posedge clk_i[0]);\n ^\n%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:241: syntax error, unexpected \'@\'\n @(posedge clk_i[0]);\n ^\n%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:243: syntax error, unexpected \'@\'\n #(WAIT_TIME) @(posedge clk_i[1]);\n              ^\n%Warning-STMTDLY: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:243: Unsupported: Ignoring delay on this delayed statement.\n #(WAIT_TIME) @(posedge clk_i[1]);\n ^\n%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:245: syntax error, unexpected \'@\'\n @(posedge clk_i[1]);\n ^\n%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:250: syntax error, unexpected \'@\'\n  #(WAIT_TIME) @(posedge clk_i[0]);\n               ^\n%Warning-STMTDLY: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:250: Unsupported: Ignoring delay on this delayed statement.\n  #(WAIT_TIME) @(posedge clk_i[0]);\n  ^\n%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:253: syntax error, unexpected \'@\'\n  @(posedge clk_i[1]);\n  ^\n%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:256: syntax error, unexpected \'@\'\n  #(WAIT_TIME) @(posedge clk_i[0]);\n               ^\n%Warning-STMTDLY: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:256: Unsupported: Ignoring delay on this delayed statement.\n  #(WAIT_TIME) @(posedge clk_i[0]);\n  ^\n%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:259: syntax error, unexpected \'@\'\n  @(posedge clk_i[0]);\n  ^\n%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:261: syntax error, unexpected \'@\'\n  #(WAIT_TIME) @(posedge clk_i[1]);\n               ^\n%Warning-STMTDLY: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:261: Unsupported: Ignoring delay on this delayed statement.\n  #(WAIT_TIME) @(posedge clk_i[1]);\n  ^\n%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:263: syntax error, unexpected \'@\'\n  @(posedge clk_i[1]);\n  ^\n%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:266: syntax error, unexpected \'@\'\n  #(WAIT_TIME) @(posedge clk_i[0]);\n               ^\n%Warning-STMTDLY: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:266: Unsupported: Ignoring delay on this delayed statement.\n  #(WAIT_TIME) @(posedge clk_i[0]);\n  ^\n%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:269: syntax error, unexpected \'@\'\n  @(posedge clk_i[1]);\n  ^\n%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:272: syntax error, unexpected \'@\'\n  #(WAIT_TIME) @(posedge clk_i[0]);\n               ^\n%Warning-STMTDLY: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:272: Unsupported: Ignoring delay on this delayed statement.\n  #(WAIT_TIME) @(posedge clk_i[0]);\n  ^\n%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:275: syntax error, unexpected \'@\'\n  @(posedge clk_i[1]);\n  ^\n%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:280: syntax error, unexpected \'@\'\n  #(WAIT_TIME) @(posedge clk_i[0]);\n               ^\n%Warning-STMTDLY: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:280: Unsupported: Ignoring delay on this delayed statement.\n  #(WAIT_TIME) @(posedge clk_i[0]);\n  ^\n%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:283: syntax error, unexpected \'@\'\n  @(posedge clk_i[1]);\n  ^\n%Error: data/full_repos/permissive/19591557/modules/uart/spio_uart_tb.v:286: syntax error, unexpected \'@\'\n  #(WAIT_TIME) @(posedge clk_i[0]);\n               ^\n%Error: Exiting due to too many errors encountered; --error-limit=50\n'
module spio_uart_tb();

localparam CLK_FREQ  = 37_500_000;
localparam BAUD_RATE =    115_200;
localparam RX_BUFFER_ADDR_BITS = 2;

genvar i;


reg clk_i   [1:0];
reg reset_i [1:0];


wire [`PKT_LEN-1:0] tx_data_i [1:0];
reg                 tx_vld_i  [1:0];
wire                tx_rdy_i  [1:0];


wire [`PKT_LEN-1:0] rx_data_expected_i [1:0];
wire [`PKT_LEN-1:0] rx_data_i [1:0];
wire                rx_vld_i  [1:0];
reg                 rx_rdy_i  [1:0];



wire uart_data_i        [1:0];
wire uart_data_synced_i [1:0];



wire cts_i        [1:0];
wire cts_synced_i [1:0];


reg sync_trigger_i [1:0];


wire synchronising_i [1:0];


wire tx_packet_dropped_i [1:0];
wire rx_packet_dropped_i [1:0];





generate for (i = 0; i < 2; i = i + 1)
	begin : instances

		spio_uart_sync         #( .NUM_BITS      (1)
		                        , .NUM_STAGES    (2)
		                        , .INITIAL_VALUE (1'b1)
		                        )
		spio_uart_sync_tx_data_i( .CLK_IN   (clk_i[i])
		                        , .RESET_IN (reset_i[i])
		                        , .DATA_IN  (uart_data_i[i])
		                        , .DATA_OUT (uart_data_synced_i[i])
		                        );
		

		spio_uart_sync     #( .NUM_BITS      (1)
		                    , .NUM_STAGES    (2)
		                    , .INITIAL_VALUE (1'b0)
		                    )
		spio_uart_sync_cts_i( .CLK_IN   (clk_i[i])
		                    , .RESET_IN (reset_i[i])
		                    , .DATA_IN  (cts_i[i])
		                    , .DATA_OUT (cts_synced_i[i])
		                    );
		

		spio_uart #( .IS_MASTER             (i==0)
		           , .BAUD_PERIOD           (CLK_FREQ/BAUD_RATE)
		           , .BAUD_NUM_BITS         ($clog2(CLK_FREQ/BAUD_RATE))
		           , .RX_BUFFER_ADDR_BITS   (RX_BUFFER_ADDR_BITS)
		           , .RX_HIGH_WATER_MARK    ((1<<RX_BUFFER_ADDR_BITS)/2)
		           )
		spio_uart_i( .CLK_IN                (clk_i[i])
		           , .RESET_IN              (reset_i[i])

		           , .RX_IN                 (uart_data_synced_i[(i+1)%2])
		           , .CTS_IN                (cts_synced_i[(i+1)%2])
		           , .TX_OUT                (uart_data_i[i])
		           , .CTS_OUT               (cts_i[i])

		           , .RX_DATA_OUT           (rx_data_i[i])
		           , .RX_VLD_OUT            (rx_vld_i[i])
		           , .RX_RDY_IN             (rx_rdy_i[i])
		           , .RX_PACKET_DROPPED_OUT (rx_packet_dropped_i[i])

		           , .TX_DATA_IN            (tx_data_i[i])
		           , .TX_VLD_IN             (tx_vld_i[i])
		           , .TX_RDY_OUT            (tx_rdy_i[i])
		           , .TX_PACKET_DROPPED_OUT (tx_packet_dropped_i[i])

		           , .SYNC_TRIGGER_IN       (sync_trigger_i[i])
		           , .SYNCHRONISING_OUT     (synchronising_i[i])
		           );
	end
endgenerate





localparam WAIT_TIME = (1000000000/CLK_FREQ)*(CLK_FREQ/BAUD_RATE)*1000;

`define  MTICK              @(posedge clk_i[0])
`define MMTICK #(WAIT_TIME) @(posedge clk_i[0])

`define  STICK              @(posedge clk_i[1])
`define MSTICK #(WAIT_TIME) @(posedge clk_i[1])

`define MTXV tx_vld_i[0]
`define STXV tx_vld_i[1]

`define MRXR rx_rdy_i[0]
`define SRXR rx_rdy_i[1]

`define MST sync_trigger_i[0]
`define SST sync_trigger_i[1]

integer sim_phase;

initial
	begin
	sim_phase = 0;
	

	`MTXV<=1'b0; `MRXR<=1'b0; `STXV<=1'b0; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b0;
	@(negedge reset_i[1]);
	`MMTICK;
	
	sim_phase = sim_phase + 1;
	$display("Trigger synchronisation via the master");
	`MMTICK;
	`MTXV<=1'b0; `MRXR<=1'b0; `STXV<=1'b0; `SRXR<=1'b0; `MST<=1'b1; `SST<=1'b0;
	`MTICK;
	`MTXV<=1'b0; `MRXR<=1'b0; `STXV<=1'b0; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b0;
	
	sim_phase = sim_phase + 1;
	$display("Should now be in sync");
	`MMTICK;
	if (synchronising_i[0])
		$display("Time %d: ERROR: Master should be synchronised.", $time);
	if (synchronising_i[1])
		$display("Time %d: ERROR: Slave should be synchronised.", $time);
	
	sim_phase = sim_phase + 1;
	$display("Should be able to send to eachother without backpressure");
		`MMTICK;

		`MTXV<=1'b1; `MRXR<=1'b1; `STXV<=1'b0; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b0;
		`STICK;
		`MTXV<=1'b1; `MRXR<=1'b1; `STXV<=1'b1; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
		
		`MMTICK;

		`MTXV<=1'b0; `MRXR<=1'b1; `STXV<=1'b0; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
		`STICK;
		`MTXV<=1'b0; `MRXR<=1'b1; `STXV<=1'b0; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
		
		`MMTICK;

		`MTXV<=1'b0; `MRXR<=1'b0; `STXV<=1'b0; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
		`STICK;
		`MTXV<=1'b0; `MRXR<=1'b0; `STXV<=1'b0; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b0;
	
	sim_phase = sim_phase + 1;
	$display("Should be able to block, unblock and drain");
		`MMTICK;

		`MTXV<=1'b1; `MRXR<=1'b1; `STXV<=1'b0; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b0;
		`STICK;
		`MTXV<=1'b1; `MRXR<=1'b1; `STXV<=1'b1; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
		
		`MMTICK;

		`MTXV<=1'b1; `MRXR<=1'b0; `STXV<=1'b1; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
		`STICK;
		`MTXV<=1'b1; `MRXR<=1'b0; `STXV<=1'b1; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b0;
		
		`MMTICK;

		`MTXV<=1'b1; `MRXR<=1'b1; `STXV<=1'b1; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b0;
		`STICK;
		`MTXV<=1'b1; `MRXR<=1'b1; `STXV<=1'b1; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
		
		`MMTICK;

		`MTXV<=1'b0; `MRXR<=1'b1; `STXV<=1'b0; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
		`STICK;
		`MTXV<=1'b0; `MRXR<=1'b1; `STXV<=1'b0; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
		
		`MMTICK;

		`MTXV<=1'b0; `MRXR<=1'b0; `STXV<=1'b0; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
		`STICK;
		`MTXV<=1'b0; `MRXR<=1'b0; `STXV<=1'b0; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b0;
	
	sim_phase = sim_phase + 1;
	$display("Should be able to block and drain immediately");
		`MMTICK;

		`MTXV<=1'b1; `MRXR<=1'b1; `STXV<=1'b0; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b0;
		`STICK;
		`MTXV<=1'b1; `MRXR<=1'b1; `STXV<=1'b1; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
		
		`MMTICK;

		`MTXV<=1'b1; `MRXR<=1'b0; `STXV<=1'b1; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
		`STICK;
		`MTXV<=1'b1; `MRXR<=1'b0; `STXV<=1'b1; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b0;
		
		`MMTICK;

		`MTXV<=1'b0; `MRXR<=1'b0; `STXV<=1'b1; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b0;
		`STICK;
		`MTXV<=1'b0; `MRXR<=1'b0; `STXV<=1'b0; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b0;
		
		`MMTICK;

		`MTXV<=1'b0; `MRXR<=1'b1; `STXV<=1'b0; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b0;
		`STICK;
		`MTXV<=1'b0; `MRXR<=1'b1; `STXV<=1'b0; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
	
	sim_phase = sim_phase + 1;
	$display("Should be able to resync both ends while idle");
	`MMTICK;
	`MTXV<=1'b0; `MRXR<=1'b0; `STXV<=1'b0; `SRXR<=1'b0; `MST<=1'b1; `SST<=1'b0;
	`MTICK;
	`MTXV<=1'b0; `MRXR<=1'b0; `STXV<=1'b0; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b0;
	`MSTICK;
	`MTXV<=1'b0; `MRXR<=1'b0; `STXV<=1'b0; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b1;
	`STICK;
	`MTXV<=1'b0; `MRXR<=1'b0; `STXV<=1'b0; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b0;
	
	sim_phase = sim_phase + 1;
	$display("Should be able to resync both ends while transmitting");
		`MMTICK;

		`MTXV<=1'b1; `MRXR<=1'b1; `STXV<=1'b0; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b0;
		`STICK;
		`MTXV<=1'b1; `MRXR<=1'b1; `STXV<=1'b1; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
		
		`MMTICK;

		`MTXV<=1'b1; `MRXR<=1'b1; `STXV<=1'b1; `SRXR<=1'b1; `MST<=1'b1; `SST<=1'b0;
		`MTICK;
		`MTXV<=1'b1; `MRXR<=1'b1; `STXV<=1'b1; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
		`MSTICK;
		`MTXV<=1'b1; `MRXR<=1'b1; `STXV<=1'b1; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b1;
		`STICK;
		`MTXV<=1'b1; `MRXR<=1'b1; `STXV<=1'b1; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
		
		`MMTICK;

		`MTXV<=1'b0; `MRXR<=1'b1; `STXV<=1'b0; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
		`STICK;
		`MTXV<=1'b0; `MRXR<=1'b1; `STXV<=1'b0; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
		
		`MMTICK;

		`MTXV<=1'b0; `MRXR<=1'b0; `STXV<=1'b0; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
		`STICK;
		`MTXV<=1'b0; `MRXR<=1'b0; `STXV<=1'b0; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b0;
	
	sim_phase = sim_phase + 1;
	$display("Should be able to resync while blocked");
		`MMTICK;

		`MTXV<=1'b1; `MRXR<=1'b1; `STXV<=1'b0; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b0;
		`STICK;
		`MTXV<=1'b1; `MRXR<=1'b1; `STXV<=1'b1; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
		
		`MMTICK;

		`MTXV<=1'b1; `MRXR<=1'b0; `STXV<=1'b1; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
		`STICK;
		`MTXV<=1'b1; `MRXR<=1'b0; `STXV<=1'b1; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b0;
		
		`MMTICK;

		`MTXV<=1'b1; `MRXR<=1'b0; `STXV<=1'b1; `SRXR<=1'b0; `MST<=1'b1; `SST<=1'b0;
		`MTICK;
		`MTXV<=1'b1; `MRXR<=1'b0; `STXV<=1'b1; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b0;
		`MSTICK;
		`MTXV<=1'b1; `MRXR<=1'b0; `STXV<=1'b1; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b1;
		`STICK;
		`MTXV<=1'b1; `MRXR<=1'b0; `STXV<=1'b1; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b0;
		
		`MMTICK;

		`MTXV<=1'b1; `MRXR<=1'b1; `STXV<=1'b1; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b0;
		`STICK;
		`MTXV<=1'b1; `MRXR<=1'b1; `STXV<=1'b1; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
		
		`MMTICK;

		`MTXV<=1'b0; `MRXR<=1'b1; `STXV<=1'b0; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
		`STICK;
		`MTXV<=1'b0; `MRXR<=1'b1; `STXV<=1'b0; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
		
		`MMTICK;

		`MTXV<=1'b0; `MRXR<=1'b0; `STXV<=1'b0; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
		`STICK;
		`MTXV<=1'b0; `MRXR<=1'b0; `STXV<=1'b0; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b0;
	
	
	`MSTICK;

	if (tx_counter_i[0] != rx_counter_i[1])
		$display( "Time %d: ERROR: Some values from the master never arrived: last ID sent = %x, last ID arrived = %x."
		        , $time
		        , tx_counter_i[0]-1
		        , rx_counter_i[1]-1
		        );
	if (tx_counter_i[1] != rx_counter_i[0])
		$display( "Time %d: ERROR: Some values from the slave never arrived: last ID sent = %x, last ID arrived = %x."
		        , $time
		        , tx_counter_i[1]-1
		        , rx_counter_i[0]-1
		        );
	#0
	$finish;
	end


reg [31:0] tx_counter_i [1:0];


generate for (i = 0; i < 2; i = i + 1)
	begin : packet_generation
		always @ (posedge clk_i[i], posedge reset_i[i])
			if (reset_i[i])
				tx_counter_i[i] <= 32'd0;
			else
				if (tx_vld_i[i] && tx_rdy_i[i])
					tx_counter_i[i] <= tx_counter_i[i] + 1;
		
		assign tx_data_i[i] = (tx_counter_i[i][0] == 1'b0)
		                    ? {32'bX          , tx_counter_i[i], 7'h00, !(^tx_counter_i[i])}
		                    : {tx_counter_i[i], tx_counter_i[i], 8'h02}
		                    ;
	end
endgenerate






reg [31:0] rx_counter_i [1:0];


generate for (i = 0; i < 2; i = i + 1)
	begin : packet_consumption
		assign rx_data_expected_i[i] = (rx_counter_i[i][0] == 1'b0)
		                             ? {32'bX          , rx_counter_i[i], 7'h00, ~^rx_counter_i[i]}
		                             : {rx_counter_i[i], rx_counter_i[i], 8'h02}
		                             ;
		
		always @ (posedge clk_i[i], posedge reset_i[i])
			if (reset_i[i])
				rx_counter_i[i] <= 32'b0;
			else
				if (rx_vld_i[i] && rx_rdy_i[i])
					begin
						if (rx_data_i[i] != rx_data_expected_i[i])
							$display( "Time %d: ERROR: Value out of sequence for %d: got %x, expected %x."
							        , $time
							        , i
							        , rx_data_i[i]
							        , rx_data_expected_i[i]
							        );
						rx_counter_i[i] <= rx_data_i[i][8+:32] + 1;
					end
	end
endgenerate






generate for (i = 0; i < 2; i = i + 1)
	begin : testbench_signals

		initial
			begin
				clk_i[i] = 1'b0;
				forever
					#((1_000_000_000/CLK_FREQ)/2) clk_i[i] = ~clk_i[i];
			end
		

		initial
			begin
				reset_i[i] = 1'b1;
				#(100 + i*05) reset_i[i] = 1'b0;
			end
	end
endgenerate


endmodule
module spio_uart_tb();


localparam CLK_FREQ  = 37_500_000;
localparam BAUD_RATE =    115_200;
localparam RX_BUFFER_ADDR_BITS = 2;

genvar i;


reg clk_i   [1:0];
reg reset_i [1:0];


wire [`PKT_LEN-1:0] tx_data_i [1:0];
reg                 tx_vld_i  [1:0];
wire                tx_rdy_i  [1:0];


wire [`PKT_LEN-1:0] rx_data_expected_i [1:0];
wire [`PKT_LEN-1:0] rx_data_i [1:0];
wire                rx_vld_i  [1:0];
reg                 rx_rdy_i  [1:0];



wire uart_data_i        [1:0];
wire uart_data_synced_i [1:0];



wire cts_i        [1:0];
wire cts_synced_i [1:0];


reg sync_trigger_i [1:0];


wire synchronising_i [1:0];


wire tx_packet_dropped_i [1:0];
wire rx_packet_dropped_i [1:0];





generate for (i = 0; i < 2; i = i + 1)
	begin : instances

		spio_uart_sync         #( .NUM_BITS      (1)
		                        , .NUM_STAGES    (2)
		                        , .INITIAL_VALUE (1'b1)
		                        )
		spio_uart_sync_tx_data_i( .CLK_IN   (clk_i[i])
		                        , .RESET_IN (reset_i[i])
		                        , .DATA_IN  (uart_data_i[i])
		                        , .DATA_OUT (uart_data_synced_i[i])
		                        );
		

		spio_uart_sync     #( .NUM_BITS      (1)
		                    , .NUM_STAGES    (2)
		                    , .INITIAL_VALUE (1'b0)
		                    )
		spio_uart_sync_cts_i( .CLK_IN   (clk_i[i])
		                    , .RESET_IN (reset_i[i])
		                    , .DATA_IN  (cts_i[i])
		                    , .DATA_OUT (cts_synced_i[i])
		                    );
		

		spio_uart #( .IS_MASTER             (i==0)
		           , .BAUD_PERIOD           (CLK_FREQ/BAUD_RATE)
		           , .BAUD_NUM_BITS         ($clog2(CLK_FREQ/BAUD_RATE))
		           , .RX_BUFFER_ADDR_BITS   (RX_BUFFER_ADDR_BITS)
		           , .RX_HIGH_WATER_MARK    ((1<<RX_BUFFER_ADDR_BITS)/2)
		           )
		spio_uart_i( .CLK_IN                (clk_i[i])
		           , .RESET_IN              (reset_i[i])

		           , .RX_IN                 (uart_data_synced_i[(i+1)%2])
		           , .CTS_IN                (cts_synced_i[(i+1)%2])
		           , .TX_OUT                (uart_data_i[i])
		           , .CTS_OUT               (cts_i[i])

		           , .RX_DATA_OUT           (rx_data_i[i])
		           , .RX_VLD_OUT            (rx_vld_i[i])
		           , .RX_RDY_IN             (rx_rdy_i[i])
		           , .RX_PACKET_DROPPED_OUT (rx_packet_dropped_i[i])

		           , .TX_DATA_IN            (tx_data_i[i])
		           , .TX_VLD_IN             (tx_vld_i[i])
		           , .TX_RDY_OUT            (tx_rdy_i[i])
		           , .TX_PACKET_DROPPED_OUT (tx_packet_dropped_i[i])

		           , .SYNC_TRIGGER_IN       (sync_trigger_i[i])
		           , .SYNCHRONISING_OUT     (synchronising_i[i])
		           );
	end
endgenerate





localparam WAIT_TIME = (1000000000/CLK_FREQ)*(CLK_FREQ/BAUD_RATE)*1000;

`define  MTICK              @(posedge clk_i[0])
`define MMTICK #(WAIT_TIME) @(posedge clk_i[0])

`define  STICK              @(posedge clk_i[1])
`define MSTICK #(WAIT_TIME) @(posedge clk_i[1])

`define MTXV tx_vld_i[0]
`define STXV tx_vld_i[1]

`define MRXR rx_rdy_i[0]
`define SRXR rx_rdy_i[1]

`define MST sync_trigger_i[0]
`define SST sync_trigger_i[1]

integer sim_phase;

initial
	begin
	sim_phase = 0;
	

	`MTXV<=1'b0; `MRXR<=1'b0; `STXV<=1'b0; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b0;
	@(negedge reset_i[1]);
	`MMTICK;
	
	sim_phase = sim_phase + 1;
	$display("Trigger synchronisation via the master");
	`MMTICK;
	`MTXV<=1'b0; `MRXR<=1'b0; `STXV<=1'b0; `SRXR<=1'b0; `MST<=1'b1; `SST<=1'b0;
	`MTICK;
	`MTXV<=1'b0; `MRXR<=1'b0; `STXV<=1'b0; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b0;
	
	sim_phase = sim_phase + 1;
	$display("Should now be in sync");
	`MMTICK;
	if (synchronising_i[0])
		$display("Time %d: ERROR: Master should be synchronised.", $time);
	if (synchronising_i[1])
		$display("Time %d: ERROR: Slave should be synchronised.", $time);
	
	sim_phase = sim_phase + 1;
	$display("Should be able to send to eachother without backpressure");
		`MMTICK;

		`MTXV<=1'b1; `MRXR<=1'b1; `STXV<=1'b0; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b0;
		`STICK;
		`MTXV<=1'b1; `MRXR<=1'b1; `STXV<=1'b1; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
		
		`MMTICK;

		`MTXV<=1'b0; `MRXR<=1'b1; `STXV<=1'b0; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
		`STICK;
		`MTXV<=1'b0; `MRXR<=1'b1; `STXV<=1'b0; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
		
		`MMTICK;

		`MTXV<=1'b0; `MRXR<=1'b0; `STXV<=1'b0; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
		`STICK;
		`MTXV<=1'b0; `MRXR<=1'b0; `STXV<=1'b0; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b0;
	
	sim_phase = sim_phase + 1;
	$display("Should be able to block, unblock and drain");
		`MMTICK;

		`MTXV<=1'b1; `MRXR<=1'b1; `STXV<=1'b0; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b0;
		`STICK;
		`MTXV<=1'b1; `MRXR<=1'b1; `STXV<=1'b1; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
		
		`MMTICK;

		`MTXV<=1'b1; `MRXR<=1'b0; `STXV<=1'b1; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
		`STICK;
		`MTXV<=1'b1; `MRXR<=1'b0; `STXV<=1'b1; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b0;
		
		`MMTICK;

		`MTXV<=1'b1; `MRXR<=1'b1; `STXV<=1'b1; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b0;
		`STICK;
		`MTXV<=1'b1; `MRXR<=1'b1; `STXV<=1'b1; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
		
		`MMTICK;

		`MTXV<=1'b0; `MRXR<=1'b1; `STXV<=1'b0; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
		`STICK;
		`MTXV<=1'b0; `MRXR<=1'b1; `STXV<=1'b0; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
		
		`MMTICK;

		`MTXV<=1'b0; `MRXR<=1'b0; `STXV<=1'b0; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
		`STICK;
		`MTXV<=1'b0; `MRXR<=1'b0; `STXV<=1'b0; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b0;
	
	sim_phase = sim_phase + 1;
	$display("Should be able to block and drain immediately");
		`MMTICK;

		`MTXV<=1'b1; `MRXR<=1'b1; `STXV<=1'b0; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b0;
		`STICK;
		`MTXV<=1'b1; `MRXR<=1'b1; `STXV<=1'b1; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
		
		`MMTICK;

		`MTXV<=1'b1; `MRXR<=1'b0; `STXV<=1'b1; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
		`STICK;
		`MTXV<=1'b1; `MRXR<=1'b0; `STXV<=1'b1; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b0;
		
		`MMTICK;

		`MTXV<=1'b0; `MRXR<=1'b0; `STXV<=1'b1; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b0;
		`STICK;
		`MTXV<=1'b0; `MRXR<=1'b0; `STXV<=1'b0; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b0;
		
		`MMTICK;

		`MTXV<=1'b0; `MRXR<=1'b1; `STXV<=1'b0; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b0;
		`STICK;
		`MTXV<=1'b0; `MRXR<=1'b1; `STXV<=1'b0; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
	
	sim_phase = sim_phase + 1;
	$display("Should be able to resync both ends while idle");
	`MMTICK;
	`MTXV<=1'b0; `MRXR<=1'b0; `STXV<=1'b0; `SRXR<=1'b0; `MST<=1'b1; `SST<=1'b0;
	`MTICK;
	`MTXV<=1'b0; `MRXR<=1'b0; `STXV<=1'b0; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b0;
	`MSTICK;
	`MTXV<=1'b0; `MRXR<=1'b0; `STXV<=1'b0; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b1;
	`STICK;
	`MTXV<=1'b0; `MRXR<=1'b0; `STXV<=1'b0; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b0;
	
	sim_phase = sim_phase + 1;
	$display("Should be able to resync both ends while transmitting");
		`MMTICK;

		`MTXV<=1'b1; `MRXR<=1'b1; `STXV<=1'b0; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b0;
		`STICK;
		`MTXV<=1'b1; `MRXR<=1'b1; `STXV<=1'b1; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
		
		`MMTICK;

		`MTXV<=1'b1; `MRXR<=1'b1; `STXV<=1'b1; `SRXR<=1'b1; `MST<=1'b1; `SST<=1'b0;
		`MTICK;
		`MTXV<=1'b1; `MRXR<=1'b1; `STXV<=1'b1; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
		`MSTICK;
		`MTXV<=1'b1; `MRXR<=1'b1; `STXV<=1'b1; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b1;
		`STICK;
		`MTXV<=1'b1; `MRXR<=1'b1; `STXV<=1'b1; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
		
		`MMTICK;

		`MTXV<=1'b0; `MRXR<=1'b1; `STXV<=1'b0; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
		`STICK;
		`MTXV<=1'b0; `MRXR<=1'b1; `STXV<=1'b0; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
		
		`MMTICK;

		`MTXV<=1'b0; `MRXR<=1'b0; `STXV<=1'b0; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
		`STICK;
		`MTXV<=1'b0; `MRXR<=1'b0; `STXV<=1'b0; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b0;
	
	sim_phase = sim_phase + 1;
	$display("Should be able to resync while blocked");
		`MMTICK;

		`MTXV<=1'b1; `MRXR<=1'b1; `STXV<=1'b0; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b0;
		`STICK;
		`MTXV<=1'b1; `MRXR<=1'b1; `STXV<=1'b1; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
		
		`MMTICK;

		`MTXV<=1'b1; `MRXR<=1'b0; `STXV<=1'b1; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
		`STICK;
		`MTXV<=1'b1; `MRXR<=1'b0; `STXV<=1'b1; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b0;
		
		`MMTICK;

		`MTXV<=1'b1; `MRXR<=1'b0; `STXV<=1'b1; `SRXR<=1'b0; `MST<=1'b1; `SST<=1'b0;
		`MTICK;
		`MTXV<=1'b1; `MRXR<=1'b0; `STXV<=1'b1; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b0;
		`MSTICK;
		`MTXV<=1'b1; `MRXR<=1'b0; `STXV<=1'b1; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b1;
		`STICK;
		`MTXV<=1'b1; `MRXR<=1'b0; `STXV<=1'b1; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b0;
		
		`MMTICK;

		`MTXV<=1'b1; `MRXR<=1'b1; `STXV<=1'b1; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b0;
		`STICK;
		`MTXV<=1'b1; `MRXR<=1'b1; `STXV<=1'b1; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
		
		`MMTICK;

		`MTXV<=1'b0; `MRXR<=1'b1; `STXV<=1'b0; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
		`STICK;
		`MTXV<=1'b0; `MRXR<=1'b1; `STXV<=1'b0; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
		
		`MMTICK;

		`MTXV<=1'b0; `MRXR<=1'b0; `STXV<=1'b0; `SRXR<=1'b1; `MST<=1'b0; `SST<=1'b0;
		`STICK;
		`MTXV<=1'b0; `MRXR<=1'b0; `STXV<=1'b0; `SRXR<=1'b0; `MST<=1'b0; `SST<=1'b0;
	
	
	`MSTICK;

	if (tx_counter_i[0] != rx_counter_i[1])
		$display( "Time %d: ERROR: Some values from the master never arrived: last ID sent = %x, last ID arrived = %x."
		        , $time
		        , tx_counter_i[0]-1
		        , rx_counter_i[1]-1
		        );
	if (tx_counter_i[1] != rx_counter_i[0])
		$display( "Time %d: ERROR: Some values from the slave never arrived: last ID sent = %x, last ID arrived = %x."
		        , $time
		        , tx_counter_i[1]-1
		        , rx_counter_i[0]-1
		        );
	#0
	$finish;
	end


reg [31:0] tx_counter_i [1:0];


generate for (i = 0; i < 2; i = i + 1)
	begin : packet_generation
		always @ (posedge clk_i[i], posedge reset_i[i])
			if (reset_i[i])
				tx_counter_i[i] <= 32'd0;
			else
				if (tx_vld_i[i] && tx_rdy_i[i])
					tx_counter_i[i] <= tx_counter_i[i] + 1;
		
		assign tx_data_i[i] = (tx_counter_i[i][0] == 1'b0)
		                    ? {32'bX          , tx_counter_i[i], 7'h00, !(^tx_counter_i[i])}
		                    : {tx_counter_i[i], tx_counter_i[i], 8'h02}
		                    ;
	end
endgenerate






reg [31:0] rx_counter_i [1:0];


generate for (i = 0; i < 2; i = i + 1)
	begin : packet_consumption
		assign rx_data_expected_i[i] = (rx_counter_i[i][0] == 1'b0)
		                             ? {32'bX          , rx_counter_i[i], 7'h00, ~^rx_counter_i[i]}
		                             : {rx_counter_i[i], rx_counter_i[i], 8'h02}
		                             ;
		
		always @ (posedge clk_i[i], posedge reset_i[i])
			if (reset_i[i])
				rx_counter_i[i] <= 32'b0;
			else
				if (rx_vld_i[i] && rx_rdy_i[i])
					begin
						if (rx_data_i[i] != rx_data_expected_i[i])
							$display( "Time %d: ERROR: Value out of sequence for %d: got %x, expected %x."
							        , $time
							        , i
							        , rx_data_i[i]
							        , rx_data_expected_i[i]
							        );
						rx_counter_i[i] <= rx_data_i[i][8+:32] + 1;
					end
	end
endgenerate






generate for (i = 0; i < 2; i = i + 1)
	begin : testbench_signals

		initial
			begin
				clk_i[i] = 1'b0;
				forever
					#((1_000_000_000/CLK_FREQ)/2) clk_i[i] = ~clk_i[i];
			end
		

		initial
			begin
				reset_i[i] = 1'b1;
				#(100 + i*05) reset_i[i] = 1'b0;
			end
	end
endgenerate


endmodule