OpenCores
URL https://opencores.org/ocsvn/ftdi_wb_bridge/ftdi_wb_bridge/trunk

Subversion Repositories ftdi_wb_bridge

[/] [ftdi_wb_bridge/] [trunk/] [testbench/] [top_tb.sv] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 ultra_embe
`timescale 100ps/100ps
2
 
3
//-----------------------------------------------------------------
4
// Module
5
//-----------------------------------------------------------------
6
module top_tb ;
7
 
8
//-----------------------------------------------------------------
9
// Params
10
//-----------------------------------------------------------------
11
parameter MAX_DELAY      = 0;
12
 
13
//-----------------------------------------------------------------
14
// Simulation
15
//-----------------------------------------------------------------
16
`include "simulation.svh"
17
 
18
`CLOCK_GEN(clk, 100)
19
`RESET_GEN(rst, 100)
20
 
21
`ifdef TRACE
22
    `TB_VCD(top_tb, "waveform.vcd")
23
`endif
24
 
25
`TB_RUN_FOR(10ms)
26
 
27
//-----------------------------------------------------------------
28
// Registers / Wires
29
//-----------------------------------------------------------------
30
wire [31:0]         mem_addr;
31
wire [31:0]         mem_data_w;
32
wire [31:0]         mem_data_r;
33
wire [3:0]          mem_sel;
34
wire                mem_stb;
35
wire                mem_cyc;
36
wire                mem_we;
37
wire                mem_stall;
38
wire                mem_ack;
39
 
40
reg                 ftdi_rxf;
41
reg                 ftdi_txe;
42
wire                ftdi_rd;
43
wire                ftdi_wr;
44
reg [7:0]           ftdi_data;
45
 
46
wire [7:0]          ftdi_data_io_w;
47
 
48
reg [7:0]           mem[*];
49
 
50
reg [7:0]           gpio_in;
51
wire [7:0]          gpio_out;
52
 
53
//-----------------------------------------------------------------
54
// mem_write
55
//-----------------------------------------------------------------
56
task automatic mem_write(input [31:0] addr, input [7:0] data);
57
begin
58
    mem[addr] = data;
59
end
60
endtask
61
 
62
//-----------------------------------------------------------------
63
// mem_read
64
//-----------------------------------------------------------------
65
task automatic mem_read(input [31:0] addr, output [7:0] data);
66
begin
67
    if (mem.exists(addr))
68
        data = mem[addr];
69
    else
70
        data = 8'bx;
71
end
72
endtask
73
//-----------------------------------------------------------------
74
// write_to_ftdi
75
//-----------------------------------------------------------------
76
task automatic write_to_ftdi(input [31:0] addr, input [11:0] len);
77
begin
78
    integer i;
79
    reg [7:0] data;
80
    reg [31:0] addr_tmp;
81
 
82
    repeat ($urandom_range(MAX_DELAY,0)) @(posedge clk);
83
 
84
    ftdi_rxf        <= 1'b0;
85
    ftdi_data       <= {len[11:8], 4'h1}; // WRITE
86
 
87
    @(posedge ftdi_rd);
88
    ftdi_rxf        <= 1'b1;
89
 
90
    repeat ($urandom_range(MAX_DELAY,0)) @(posedge clk);
91
 
92
    ftdi_rxf        <= 1'b0;
93
    ftdi_data       <= len[7:0]; // LEN
94
 
95
    @(posedge ftdi_rd);
96
    ftdi_rxf        <= 1'b1;
97
 
98
    repeat ($urandom_range(MAX_DELAY,0)) @(posedge clk);
99
 
100
    // ADDR
101
    addr_tmp = addr;
102
    for (i=0;i<4;i=i+1)
103
    begin
104
        ftdi_rxf   <= 1'b0;
105
 
106
        data = addr_tmp[31:24];
107
        addr_tmp = {addr_tmp[23:0], 8'b0};
108
 
109
        $display("ADDR%d: %x", i, data);
110
        ftdi_data  <= data; // DATA
111
 
112
        @(posedge ftdi_rd);
113
        ftdi_rxf        <= 1'b1;
114
 
115
        repeat ($urandom_range(MAX_DELAY,0)) @(posedge clk);
116
    end
117
 
118
    // DATA
119
    addr_tmp = addr;
120
    for (i=0;i
121
    begin
122
        ftdi_rxf   <= 1'b0;
123
 
124
        data = $urandom;
125
 
126
        $display("BYTE%d: %x", i, data);
127
        ftdi_data  <= data; // DATA
128
 
129
        mem_write(addr_tmp, data);
130
        addr_tmp += 1;
131
 
132
        @(posedge ftdi_rd);
133
        ftdi_rxf    <= 1'b1;
134
 
135
        repeat ($urandom_range(MAX_DELAY,0)) @(posedge clk);
136
    end
137
end
138
endtask
139
//-----------------------------------------------------------------
140
// write_gp
141
//-----------------------------------------------------------------
142
task automatic write_gp(input [7:0] gp);
143
begin
144
    integer i;
145
    reg [7:0] data;
146
    reg [31:0] addr_tmp;
147
 
148
    repeat ($urandom_range(MAX_DELAY,0)) @(posedge clk);
149
 
150
    ftdi_rxf        <= 1'b0;
151
    ftdi_data       <= {4'b0, 4'h3}; // GP_WR
152
 
153
    @(posedge ftdi_rd);
154
    ftdi_rxf        <= 1'b1;
155
 
156
    repeat ($urandom_range(MAX_DELAY,0)) @(posedge clk);
157
 
158
    ftdi_rxf   <= 1'b0;
159
 
160
    data = $urandom;
161
 
162
    ftdi_data  <= data; // DATA
163
 
164
    mem_write(addr_tmp, data);
165
    addr_tmp += 1;
166
 
167
    @(posedge ftdi_rd);
168
    ftdi_rxf    <= 1'b1;
169
 
170
    repeat ($urandom_range(MAX_DELAY,0)) @(posedge clk);
171
 
172
    repeat (2) @(posedge clk);
173
    `ASSERT(gpio_out == data);
174
end
175
endtask
176
//-----------------------------------------------------------------
177
// read_gp
178
//-----------------------------------------------------------------
179
task automatic read_gp(output [7:0] gp);
180
begin
181
    integer i;
182
    reg [7:0] data;
183
    reg [31:0] addr_tmp;
184
 
185
    repeat ($urandom_range(MAX_DELAY,0)) @(posedge clk);
186
 
187
    ftdi_rxf        <= 1'b0;
188
    ftdi_data       <= {4'b0, 4'h4}; // GP_RD
189
 
190
    @(posedge ftdi_rd);
191
    ftdi_rxf        <= 1'b1;
192
 
193
    repeat ($urandom_range(MAX_DELAY,0)) @(posedge clk);
194
 
195
    ftdi_txe   <= 1'b0;
196
 
197
    @(posedge ftdi_wr);
198
 
199
    $display("GPIO_IN: %x", u_dut.u_sync.tx_data_q);
200
 
201
    ftdi_txe    <= 1'b1;
202
 
203
    repeat ($urandom_range(MAX_DELAY,0)) @(posedge clk);
204
end
205
endtask
206
//-----------------------------------------------------------------
207
// check_mem
208
//-----------------------------------------------------------------
209
task automatic check_mem(input [31:0] addr, input [31:0] len);
210
begin
211
    integer   i;
212
    reg [7:0] data;
213
    reg [7:0] actual_data;
214
 
215
    // Compare
216
    for (i=0;i
217
    begin
218
 
219
        mem_read(addr, data);
220
        u_wbs.read8(addr, actual_data);
221
 
222
        if (data !== actual_data)
223
        begin
224
            $display("Error @ %x: %x != %x", addr, data, actual_data);
225
            $finish;
226
        end
227
 
228
        addr += 1;
229
 
230
    end
231
end
232
endtask
233
//-----------------------------------------------------------------
234
// read_from_ftdi
235
//-----------------------------------------------------------------
236
task automatic read_from_ftdi(input [31:0] addr, input [11:0] len);
237
begin
238
    integer i;
239
    reg [7:0] data;
240
    reg [31:0] addr_tmp;
241
 
242
    repeat ($urandom_range(MAX_DELAY,0)) @(posedge clk);
243
 
244
    ftdi_rxf        <= 1'b0;
245
    ftdi_data       <= {len[11:8], 4'h2}; // READ
246
 
247
    @(posedge ftdi_rd);
248
    ftdi_rxf        <= 1'b1;
249
 
250
    repeat ($urandom_range(MAX_DELAY,0)) @(posedge clk);
251
 
252
    ftdi_rxf        <= 1'b0;
253
    ftdi_data       <= len[7:0]; // LEN
254
 
255
    @(posedge ftdi_rd);
256
    ftdi_rxf        <= 1'b1;
257
 
258
    repeat ($urandom_range(MAX_DELAY,0)) @(posedge clk);
259
 
260
    // ADDR
261
    addr_tmp = addr;
262
    for (i=0;i<4;i=i+1)
263
    begin
264
        ftdi_rxf   <= 1'b0;
265
 
266
        data = addr_tmp[31:24];
267
        addr_tmp = {addr_tmp[23:0], 8'b0};
268
 
269
        $display("ADDR%d: %x", i, data);
270
        ftdi_data  <= data; // DATA
271
 
272
        @(posedge ftdi_rd);
273
        ftdi_rxf        <= 1'b1;
274
 
275
        repeat ($urandom_range(MAX_DELAY,0)) @(posedge clk);
276
    end
277
 
278
    // DATA
279
    addr_tmp = addr;
280
    for (i=0;i
281
    begin
282
        ftdi_txe   <= 1'b0;
283
 
284
        @(posedge ftdi_wr);
285
 
286
        data = $urandom;
287
 
288
        $display("READ%d: %x", i, u_dut.u_sync.tx_data_q);
289
        // TODO: COMP
290
        mem_write(addr_tmp, u_dut.u_sync.tx_data_q);
291
        addr_tmp += 1;
292
 
293
        ftdi_txe    <= 1'b1;
294
 
295
        repeat ($urandom_range(MAX_DELAY,0)) @(posedge clk);
296
    end
297
end
298
endtask
299
 
300
//-----------------------------------------------------------------
301
// Testbench
302
//-----------------------------------------------------------------
303
initial
304
begin
305
    reg [7:0] tmp;
306
 
307
    ftdi_rxf        = 1'b1;
308
    ftdi_data       = 8'bz;
309
    ftdi_txe        = 1'b1;
310
 
311
    gpio_in         = 8'h55;
312
 
313
    forever
314
    begin
315
        repeat (10) @(posedge clk);
316
 
317
        write_to_ftdi(32'h00000000, 16);
318
        write_gp(4'ha);
319
        write_to_ftdi(32'h00000010, 16);
320
 
321
        read_gp(tmp);
322
        `ASSERT(tmp == 8'h55);
323
 
324
        repeat (100) @(posedge clk);
325
        check_mem(32'h00000000, 32);
326
 
327
        read_from_ftdi(32'h00000000, 16);
328
 
329
        repeat (100) @(posedge clk);
330
        check_mem(32'h00000000, 16);
331
 
332
        write_to_ftdi(32'h00000100, 15);
333
        repeat (100) @(posedge clk);
334
        check_mem(32'h00000100, 15);
335
 
336
        write_to_ftdi(32'h00000201, 14);
337
        repeat (100) @(posedge clk);
338
        check_mem(32'h00000201, 14);
339
 
340
        write_to_ftdi(32'h00000001, 1);
341
        repeat (100) @(posedge clk);
342
        check_mem(32'h00000001, 1);
343
 
344
        $finish;
345
    end
346
end
347
 
348
//-----------------------------------------------------------------
349
// Instantiation
350
//-----------------------------------------------------------------
351
assign ftdi_data_io_w = !ftdi_rd ? ftdi_data : 8'bz;
352
 
353
ftdi_if
354
u_dut
355
(
356
    .clk_i(clk),
357
    .rst_i(rst),
358
 
359
    // FTDI (async FIFO interface)
360
    .ftdi_rxf_i(ftdi_rxf),
361
    .ftdi_txe_i(ftdi_txe),
362
    .ftdi_siwua_o(),
363
    .ftdi_wr_o(ftdi_wr),
364
    .ftdi_rd_o(ftdi_rd),
365
    .ftdi_d_io(ftdi_data_io_w),
366
 
367
    // General Purpose
368
    .gp_o(gpio_out),
369
    .gp_i(gpio_in),
370
 
371
    // Wishbone Interface
372
    .mem_addr_o(mem_addr),
373
    .mem_data_o(mem_data_w),
374
    .mem_data_i(mem_data_r),
375
    .mem_sel_o(mem_sel),
376
    .mem_we_o(mem_we),
377
    .mem_cyc_o(mem_cyc),
378
    .mem_stb_o(mem_stb),
379
    .mem_stall_i(mem_stall),
380
    .mem_ack_i(mem_ack)
381
);
382
 
383
wb_slave
384
#(
385
    .RANDOM_STALLS(1),
386
    .MAX_RESP_RATE(0)
387
)
388
u_wbs
389
(
390
    .clk_i(clk),
391
    .rst_i(rst),
392
 
393
    .addr_i(mem_addr),
394
    .data_i(mem_data_w),
395
    .data_o(mem_data_r),
396
    .sel_i(mem_sel),
397
    .cyc_i(mem_cyc),
398
    .stb_i(mem_stb),
399
    .cti_i(3'b111),
400
    .we_i(mem_we),
401
    .stall_o(mem_stall),
402
    .ack_o(mem_ack)
403
);
404
 
405
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.