-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapb_tb.v
More file actions
227 lines (198 loc) · 7.22 KB
/
apb_tb.v
File metadata and controls
227 lines (198 loc) · 7.22 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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
// Testbench for APB System
`timescale 1ns / 1ps
module apb_tb;
parameter ADDR_WIDTH = 32;
parameter DATA_WIDTH = 32;
parameter NUM_SLAVES = 4;
// Clock and reset
reg PCLK;
reg PRESETn;
// Master interface
reg req;
reg [ADDR_WIDTH-1:0] addr;
reg write;
reg [DATA_WIDTH-1:0] wdata;
wire [DATA_WIDTH-1:0] rdata;
wire ready;
wire error;
// Slave register interfaces
wire [DATA_WIDTH-1:0] slave0_reg [0:15];
wire [DATA_WIDTH-1:0] slave1_reg [0:15];
wire [DATA_WIDTH-1:0] slave2_reg [0:15];
wire [DATA_WIDTH-1:0] slave3_reg [0:15];
// Instantiate APB Top
apb_top #(
.ADDR_WIDTH(ADDR_WIDTH),
.DATA_WIDTH(DATA_WIDTH),
.NUM_SLAVES(NUM_SLAVES)
) dut (
.PCLK(PCLK),
.PRESETn(PRESETn),
.req(req),
.addr(addr),
.write(write),
.wdata(wdata),
.rdata(rdata),
.ready(ready),
.error(error),
.slave0_reg(slave0_reg),
.slave1_reg(slave1_reg),
.slave2_reg(slave2_reg),
.slave3_reg(slave3_reg)
);
// Clock generation
initial begin
PCLK = 0;
forever #5 PCLK = ~PCLK; // 100MHz clock (10ns period)
end
// Task for APB write
task apb_write;
input [ADDR_WIDTH-1:0] address;
input [DATA_WIDTH-1:0] data;
begin
@(posedge PCLK);
req = 1;
addr = address;
write = 1;
wdata = data;
@(posedge PCLK);
wait(ready);
@(posedge PCLK);
req = 0;
write = 0;
#10;
end
endtask
// Task for APB read
task apb_read;
input [ADDR_WIDTH-1:0] address;
output [DATA_WIDTH-1:0] data;
begin
@(posedge PCLK);
req = 1;
addr = address;
write = 0;
@(posedge PCLK);
wait(ready);
data = rdata;
@(posedge PCLK);
req = 0;
#10;
end
endtask
// Test stimulus
initial begin
// Initialize signals
PRESETn = 0;
req = 0;
addr = 0;
write = 0;
wdata = 0;
// Reset
#20;
PRESETn = 1;
#20;
$display("=== APB Testbench Started ===\n");
// Test 1: Write to Slave 0
$display("Test 1: Writing to Slave 0");
apb_write(32'h0000_0000, 32'hDEAD_BEEF);
$display(" Write: Address=0x%08h, Data=0x%08h", 32'h0000_0000, 32'hDEAD_BEEF);
#10;
apb_write(32'h0000_0004, 32'hCAFE_BABE);
$display(" Write: Address=0x%08h, Data=0x%08h", 32'h0000_0004, 32'hCAFE_BABE);
#10;
// Test 2: Read from Slave 0
$display("\nTest 2: Reading from Slave 0");
begin
reg [DATA_WIDTH-1:0] read_data;
apb_read(32'h0000_0000, read_data);
$display(" Read: Address=0x%08h, Data=0x%08h", 32'h0000_0000, read_data);
if (read_data == 32'hDEAD_BEEF)
$display(" PASS: Data matches!");
else
$display(" FAIL: Expected 0xDEAD_BEEF, got 0x%08h", read_data);
end
begin
reg [DATA_WIDTH-1:0] read_data;
apb_read(32'h0000_0004, read_data);
$display(" Read: Address=0x%08h, Data=0x%08h", 32'h0000_0004, read_data);
if (read_data == 32'hCAFE_BABE)
$display(" PASS: Data matches!");
else
$display(" FAIL: Expected 0xCAFE_BABE, got 0x%08h", read_data);
end
// Test 3: Write to Slave 1
$display("\nTest 3: Writing to Slave 1");
apb_write(32'h0000_1000, 32'h1234_5678);
$display(" Write: Address=0x%08h, Data=0x%08h", 32'h0000_1000, 32'h1234_5678);
#10;
// Test 4: Read from Slave 1
$display("\nTest 4: Reading from Slave 1");
begin
reg [DATA_WIDTH-1:0] read_data;
apb_read(32'h0000_1000, read_data);
$display(" Read: Address=0x%08h, Data=0x%08h", 32'h0000_1000, read_data);
if (read_data == 32'h1234_5678)
$display(" PASS: Data matches!");
else
$display(" FAIL: Expected 0x1234_5678, got 0x%08h", read_data);
end
// Test 5: Write to Slave 2
$display("\nTest 5: Writing to Slave 2");
apb_write(32'h0000_2000, 32'hABCD_EF00);
$display(" Write: Address=0x%08h, Data=0x%08h", 32'h0000_2000, 32'hABCD_EF00);
#10;
// Test 6: Read from Slave 2
$display("\nTest 6: Reading from Slave 2");
begin
reg [DATA_WIDTH-1:0] read_data;
apb_read(32'h0000_2000, read_data);
$display(" Read: Address=0x%08h, Data=0x%08h", 32'h0000_2000, read_data);
if (read_data == 32'hABCD_EF00)
$display(" PASS: Data matches!");
else
$display(" FAIL: Expected 0xABCD_EF00, got 0x%08h", read_data);
end
// Test 7: Write to Slave 3
$display("\nTest 7: Writing to Slave 3");
apb_write(32'h0000_3000, 32'hFEDC_BA98);
$display(" Write: Address=0x%08h, Data=0x%08h", 32'h0000_3000, 32'hFEDC_BA98);
#10;
// Test 8: Read from Slave 3
$display("\nTest 8: Reading from Slave 3");
begin
reg [DATA_WIDTH-1:0] read_data;
apb_read(32'h0000_3000, read_data);
$display(" Read: Address=0x%08h, Data=0x%08h", 32'h0000_3000, read_data);
if (read_data == 32'hFEDC_BA98)
$display(" PASS: Data matches!");
else
$display(" FAIL: Expected 0xFEDC_BA98, got 0x%08h", read_data);
end
// Test 9: Multiple writes to different registers
$display("\nTest 9: Multiple writes to different registers in Slave 0");
for (integer i = 0; i < 8; i = i + 1) begin
apb_write(32'h0000_0000 + (i * 4), 32'h1000 + i);
$display(" Write: Reg[%0d] = 0x%08h", i, 32'h1000 + i);
end
// Test 10: Verify multiple reads
$display("\nTest 10: Reading back all registers from Slave 0");
for (integer i = 0; i < 8; i = i + 1) begin
reg [DATA_WIDTH-1:0] read_data;
apb_read(32'h0000_0000 + (i * 4), read_data);
$display(" Read: Reg[%0d] = 0x%08h", i, read_data);
if (read_data == (32'h1000 + i))
$display(" PASS");
else
$display(" FAIL: Expected 0x%08h", 32'h1000 + i);
end
$display("\n=== APB Testbench Completed ===");
#100;
$finish;
end
// Monitor APB signals
initial begin
$monitor("Time: %0t | Req: %b | Addr: 0x%08h | Write: %b | WData: 0x%08h | RData: 0x%08h | Ready: %b | Error: %b",
$time, req, addr, write, wdata, rdata, ready, error);
end
endmodule