summaryrefslogtreecommitdiffstats
path: root/scripts/smtbmc/tracecmp3.v
blob: a1bb63be6ff5d4a4ce5e95fee75c47e38d145104 (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
127
128
129
130
131
132
133
134
135
// Based on the benchmark from 2016 Yosys-SMTBMC presentation, which in turn is
// based on the tracecmp2 test from this directory.

module testbench (
	input clk,
	input [31:0] mem_rdata_in,

	input             pcpi_wr,
	input      [31:0] pcpi_rd,
	input             pcpi_wait,
	input             pcpi_ready
);
	reg resetn = 0;

	always @(posedge clk)
		resetn <= 1;

	wire        cpu0_trap;
	wire        cpu0_mem_valid;
	wire        cpu0_mem_instr;
	wire        cpu0_mem_ready;
	wire [31:0] cpu0_mem_addr;
	wire [31:0] cpu0_mem_wdata;
	wire [3:0]  cpu0_mem_wstrb;
	wire [31:0] cpu0_mem_rdata;
	wire        cpu0_trace_valid;
	wire [35:0] cpu0_trace_data;

	wire        cpu1_trap;
	wire        cpu1_mem_valid;
	wire        cpu1_mem_instr;
	wire        cpu1_mem_ready;
	wire [31:0] cpu1_mem_addr;
	wire [31:0] cpu1_mem_wdata;
	wire [3:0]  cpu1_mem_wstrb;
	wire [31:0] cpu1_mem_rdata;
	wire        cpu1_trace_valid;
	wire [35:0] cpu1_trace_data;

	wire        mem_ready;
	wire [31:0] mem_rdata;

	assign mem_ready = cpu0_mem_valid && cpu1_mem_valid;
	assign mem_rdata = mem_rdata_in;

	assign cpu0_mem_ready = mem_ready;
	assign cpu0_mem_rdata = mem_rdata;

	assign cpu1_mem_ready = mem_ready;
	assign cpu1_mem_rdata = mem_rdata;

	reg [ 2:0] trace_balance = 3'b010;
	reg [35:0] trace_buffer_cpu0 = 0, trace_buffer_cpu1 = 0;

	always @(posedge clk) begin
		if (resetn) begin
			if (cpu0_trace_valid)
				trace_buffer_cpu0 <= cpu0_trace_data;

			if (cpu1_trace_valid)
				trace_buffer_cpu1 <= cpu1_trace_data;

			if (cpu0_trace_valid && !cpu1_trace_valid)
				trace_balance <= trace_balance << 1;

			if (!cpu0_trace_valid && cpu1_trace_valid)
				trace_balance <= trace_balance >> 1;
		end
	end

	always @* begin
		if (resetn && cpu0_mem_ready) begin
			assert(cpu0_mem_addr == cpu1_mem_addr);
			assert(cpu0_mem_wstrb == cpu1_mem_wstrb);
			if (cpu0_mem_wstrb[3]) assert(cpu0_mem_wdata[31:24] == cpu1_mem_wdata[31:24]);
			if (cpu0_mem_wstrb[2]) assert(cpu0_mem_wdata[23:16] == cpu1_mem_wdata[23:16]);
			if (cpu0_mem_wstrb[1]) assert(cpu0_mem_wdata[15: 8] == cpu1_mem_wdata[15: 8]);
			if (cpu0_mem_wstrb[0]) assert(cpu0_mem_wdata[ 7: 0] == cpu1_mem_wdata[ 7: 0]);
		end
		if (trace_balance == 3'b010) begin
			assert(trace_buffer_cpu0 == trace_buffer_cpu1);
		end
	end

	picorv32 #(
		.ENABLE_COUNTERS(0),
		.REGS_INIT_ZERO(1),
		.COMPRESSED_ISA(1),
		.ENABLE_TRACE(1),

		.TWO_STAGE_SHIFT(0),
		.ENABLE_PCPI(1)
	) cpu0 (
		.clk         (clk             ),
		.resetn      (resetn          ),
		.trap        (cpu0_trap       ),
		.mem_valid   (cpu0_mem_valid  ),
		.mem_instr   (cpu0_mem_instr  ),
		.mem_ready   (cpu0_mem_ready  ),
		.mem_addr    (cpu0_mem_addr   ),
		.mem_wdata   (cpu0_mem_wdata  ),
		.mem_wstrb   (cpu0_mem_wstrb  ),
		.mem_rdata   (cpu0_mem_rdata  ),
		.pcpi_wr     (pcpi_wr         ),
		.pcpi_rd     (pcpi_rd         ),
		.pcpi_wait   (pcpi_wait       ),
		.pcpi_ready  (pcpi_ready      ),
		.trace_valid (cpu0_trace_valid),
		.trace_data  (cpu0_trace_data )
	);

	picorv32 #(
		.ENABLE_COUNTERS(0),
		.REGS_INIT_ZERO(1),
		.COMPRESSED_ISA(1),
		.ENABLE_TRACE(1),

		.TWO_STAGE_SHIFT(1),
		.TWO_CYCLE_COMPARE(1),
		.TWO_CYCLE_ALU(1)
	) cpu1 (
		.clk         (clk             ),
		.resetn      (resetn          ),
		.trap        (cpu1_trap       ),
		.mem_valid   (cpu1_mem_valid  ),
		.mem_instr   (cpu1_mem_instr  ),
		.mem_ready   (cpu1_mem_ready  ),
		.mem_addr    (cpu1_mem_addr   ),
		.mem_wdata   (cpu1_mem_wdata  ),
		.mem_wstrb   (cpu1_mem_wstrb  ),
		.mem_rdata   (cpu1_mem_rdata  ),
		.trace_valid (cpu1_trace_valid),
		.trace_data  (cpu1_trace_data )
	);
endmodule