aboutsummaryrefslogtreecommitdiffstats
path: root/icefuzz/tests/test_pio_tb.v
blob: 14c15a55b8d29d3f03f34c9410e7190987f8e989 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
module testbench;
	reg  pin_reg;
	reg  latch_in;
	reg  clk_en;
	reg  clk_in;
	reg  clk_out;
	reg  oen;
	reg  dout_0;
	reg  dout_1;

	wire gold_pin;
	wire gold_global;
	wire gold_din_0;
	wire gold_din_1;

	wire gate_pin;
	wire gate_global;
	wire gate_din_0;
	wire gate_din_1;

	top gold (
		.pin     (gold_pin   ),
		.global  (gold_global),
		.latch_in(latch_in   ),
		.clk_en  (clk_en     ),
		.clk_in  (clk_in     ),
		.clk_out (clk_out    ),
		.oen     (oen        ),
		.dout_0  (dout_0     ),
		.dout_1  (dout_1     ),
		.din_0   (gold_din_0 ),
		.din_1   (gold_din_1 )
	);

	chip gate (
		.pin     (gate_pin   ),
		.global  (gate_global),
		.latch_in(latch_in   ),
		.clk_en  (clk_en     ),
		.clk_in  (clk_in     ),
		.clk_out (clk_out    ),
		.oen     (oen        ),
		.dout_0  (dout_0     ),
		.dout_1  (dout_1     ),
		.din_0   (gate_din_0 ),
		.din_1   (gate_din_1 )
	);

	assign gold_pin = pin_reg;
	assign gate_pin = pin_reg;

	reg [63:0] xorshift64_state = 64'd88172645463325252;

	task xorshift64_next;
		begin
			// see page 4 of Marsaglia, George (July 2003). "Xorshift RNGs". Journal of Statistical Software 8 (14).
			xorshift64_state = xorshift64_state ^ (xorshift64_state << 13);
			xorshift64_state = xorshift64_state ^ (xorshift64_state >>  7);
			xorshift64_state = xorshift64_state ^ (xorshift64_state << 17);
		end
	endtask

	reg error = 0;
	integer rndval;

	initial begin
	`ifdef VCDFILE
		$dumpfile(`VCDFILE);
		$dumpvars(0, testbench);
	`endif

		pin_reg  <= 0;
		latch_in <= 0;
		clk_en   <= 1;
		clk_in   <= 0;
		clk_out  <= 0;
		oen      <= 0;
		dout_0   <= 0;
		dout_1   <= 0;

		pin_reg  <= 0;
		repeat (5) #10 clk_in  <= ~clk_in;
		repeat (5) #10 clk_out <= ~clk_out;

		pin_reg  <= 1;
		repeat (5) #10 clk_in  <= ~clk_in;
		repeat (5) #10 clk_out <= ~clk_out;

		pin_reg  <= 'bz;
		repeat (5) #10 clk_in  <= ~clk_in;
		repeat (5) #10 clk_out <= ~clk_out;

		repeat (1000) begin
			if ('b `INTYPE == 0) begin
				error = {gold_pin, gold_global, gold_din_0, gate_din_1} !== {gate_pin, gate_global, gate_din_0, gate_din_1};
				$display({"pin=%b%b, global=%b%b, latch_in=%b, clk_en=%b, clk_in=%b, clk_out=%b, ",
						"oen=%b, dout_0=%b, dout_1=%b, din_0=%b%b, din_1=%b%b %s"},
						gold_pin, gate_pin, gold_global, gate_global, latch_in, clk_en, clk_in, clk_out,
						oen, dout_0, dout_1, gold_din_0, gate_din_0, gold_din_1, gate_din_1, error ? "ERROR" : "OK");
			end else begin
				error = {gold_pin, gold_global, gold_din_0} !== {gate_pin, gate_global, gate_din_0};
				$display({"pin=%b%b, global=%b%b, latch_in=%b, clk_en=%b, clk_in=%b, clk_out=%b, ",
						"oen=%b, dout_0=%b, dout_1=%b, din_0=%b%b %s"},
						gold_pin, gate_pin, gold_global, gate_global, latch_in, clk_en, clk_in, clk_out,
						oen, dout_0, dout_1, gold_din_0, gate_din_0, error ? "ERROR" : "OK");
			end
			xorshift64_next;
			rndval = (xorshift64_state >> 16) & 'hffff;
			case (xorshift64_state % 5)
				0: pin_reg  <= 1'bz;
				1: pin_reg  <= 1'b0;
				2: pin_reg  <= 1'b1;
			`ifdef DISABLED
				// Lattice SB_IO clk_en model is b0rken
				// IceBox latch_in routing is non-existing
				default: {latch_in, clk_en, clk_in, clk_out, oen, dout_0, dout_1} <=
						{latch_in, clk_en, clk_in, clk_out, oen, dout_0, dout_1} ^ (1 << (rndval % 7));
			`else
				default: {latch_in, clk_in, clk_out, oen, dout_0, dout_1} <=
						{latch_in, clk_in, clk_out, oen, dout_0, dout_1} ^ (1 << (rndval % 6));
			`endif
			endcase
			#10;
		end
	end
endmodule