-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathtb.sv
More file actions
121 lines (91 loc) · 2.42 KB
/
Copy pathtb.sv
File metadata and controls
121 lines (91 loc) · 2.42 KB
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
module tb;
parameter N = 32;
logic [N-1:0] a, b, result;
logic [3:0] opcode;
logic carry_in;
logic cout;
logic [32:0] expected;
alu dut (a, b, opcode, carry_in, result, cout);
class txn;
rand bit [31:0] a, b;
randc bit [3:0] opcode;
rand bit carry_in;
constraint valid_op {
opcode <= 4'b1100;
}
endclass
txn t;
function automatic [32:0] alu_ref(
input [31:0] a, b,
input [3:0] opcode,
input carry_in
);
logic [32:0] tmp;
case (opcode)
// ADD
4'b0000: tmp = a + b;
// SUB (a - b)
4'b0001: begin
tmp[31:0] = a - b;
tmp[32] = (a >= b);
end
// ADC
4'b0010: tmp = a + b + carry_in;
// AND
4'b0011: tmp = {1'b0, (a & b)};
// ORR
4'b0100: tmp = {1'b0, (a | b)};
// EOR
4'b0101: tmp = {1'b0, (a ^ b)};
// MOV
4'b0110: tmp = {1'b0, a};
// MVN
4'b0111: tmp = {1'b0, ~a};
// CMP (a - b, only cout matters)
4'b1000: begin
tmp[31:0] = a - b;
tmp[32] = (a >= b);
end
// CMN (a + b)
4'b1001: tmp = a + b;
// BIC (a & ~b)
4'b1010: tmp = {1'b0, (a & ~b)};
// RSB (b - a)
4'b1011: begin
tmp[31:0] = b - a;
tmp[32] = (b >= a);
end
// SBC (IMPORTANT)
4'b1100: begin
tmp[31:0] = a - b - (1 - carry_in);
tmp[32] = (a >= (b + (1 - carry_in)));
end
default: tmp = a + b;
endcase
return tmp;
endfunction
initial begin
t = new();
repeat (3000) begin
assert(t.randomize());
a = t.a;
b = t.b;
opcode = t.opcode;
carry_in = t.carry_in;
#1;
expected = alu_ref(a, b, opcode, carry_in);
if (opcode == 4'b1000 || opcode == 4'b1001) begin
if (cout !== expected[32]) begin
$error("Flag mismatch: opcode=%0d a=%h b=%h", opcode, a, b);
end
end
else begin
if ({cout, result} !== expected) begin
$error("Mismatch: opcode=%0d a=%h b=%h", opcode, a, b);
end
end
end
$display("TEST COMPLETED");
$finish;
end
endmodule