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

Subversion Repositories firewire

[/] [firewire/] [trunk/] [bench/] [verilog/] [fw_link_tb.v] - Blame information for rev 21

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 21 johnsonw10
// $Id: fw_link_tb.v,v 1.2 2003-04-27 04:30:51 johnsonw10 Exp $
2 11 johnsonw10
//////////////////////////////////////////////////////////////////////
3
////                                                              ////
4
//// FIREWIRE IP Core                                             ////
5
////                                                              ////
6
//// This file is part of the firewire project                    ////
7
//// http://www.opencores.org/cores/firewire/                     ////
8
////                                                              ////
9
//// Description                                                  ////
10
//// Implementation of firewire IP core according to              ////
11
//// firewire IP core specification document.                     ////
12
////                                                              ////
13
//// To Do:                                                       ////
14
//// -                                                            ////
15
////                                                              ////
16
//// Author(s):                                                   ////
17
//// - johnsonw10@opencores.org                                   ////
18
////                                                              ////
19
//////////////////////////////////////////////////////////////////////
20
////                                                              ////
21
//// Copyright (C) 2001 Authors and OPENCORES.ORG                 ////
22
////                                                              ////
23
//// This source file may be used and distributed without         ////
24
//// restriction provided that this copyright statement is not    ////
25
//// removed from the file and that any derivative work contains  ////
26
//// the original copyright notice and the associated disclaimer. ////
27
////                                                              ////
28
//// This source file is free software; you can redistribute it   ////
29
//// and/or modify it under the terms of the GNU Lesser General   ////
30
//// Public License as published by the Free Software Foundation; ////
31
//// either version 2.1 of the License, or (at your option) any   ////
32
//// later version.                                               ////
33
////                                                              ////
34
//// This source is distributed in the hope that it will be       ////
35
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
36
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
37
//// PURPOSE. See the GNU Lesser General Public License for more  ////
38
//// details.                                                     ////
39
////                                                              ////
40
//// You should have received a copy of the GNU Lesser General    ////
41
//// Public License along with this source; if not, download it   ////
42
//// from http://www.opencores.org/lgpl.shtml                     ////
43
////                                                              ////
44
//////////////////////////////////////////////////////////////////////
45
//
46
// CVS Revision History
47
//
48
// $Log: not supported by cvs2svn $
49 21 johnsonw10
// Revision 1.1  2002/03/10 17:17:36  johnsonw10
50
// Initail revision. Top level test bench.
51 11 johnsonw10
//
52
//
53 21 johnsonw10
//
54 11 johnsonw10
 
55
/**********************************************************************
56
  Design Notes:
57
  1. Startup sequence:
58
     * hard reset
59
     * set all enable signals
60
     * PHY receives self ID packet
61
     * PHY status receiving of self ID packet (PHYID write)
62
     *
63
     *
64
     *
65
***********************************************************************/
66
 
67
// synopsys translate_off
68
`include "timescale.v"
69
// synopsys translate_on
70
 
71 21 johnsonw10
`include "fw_link_defines.vh"
72
 
73 11 johnsonw10
module fw_link_tb;
74
 
75 21 johnsonw10
parameter BUF_SIZE = 64;
76 11 johnsonw10
reg reset_n;
77
reg sclk;
78
 
79
wire [0:7] d;
80
wire [0:1] ctl;
81
 
82
wire [0:3] phy_reg_addr;
83
wire [0:7] phy_reg_data;
84
 
85
wire [0:31] grxf_data, atxf_data, itxf_data;
86
 
87 21 johnsonw10
integer pkt_type;
88
 
89 11 johnsonw10
reg [0:31] selfid_data;
90 21 johnsonw10
reg [0:3] ack_code;
91 11 johnsonw10
 
92
// host interface
93
reg [0:7]  host_addr;
94
wire [0:31] host_data;
95
reg  [0:31] host_data_out;  // driven by the host
96
 
97
reg        host_cs_n, host_wr_n;
98 21 johnsonw10
reg [0:31] send_buf[0:BUF_SIZE-1];
99
reg [0:31] exp_buf[0:BUF_SIZE-1];
100 11 johnsonw10
 
101 21 johnsonw10
wire [0:7]  phy_d;
102
wire [0:1]  phy_ctl;
103 11 johnsonw10
 
104 21 johnsonw10
reg [0:15] status, exp_status, rcvd_status;
105 11 johnsonw10
 
106 21 johnsonw10
integer rcvd_ql_num, exp_ql_num;
107 11 johnsonw10
 
108
reg [0:31] atxf_din;
109
reg        atxf_wr;
110
 
111
reg [0:31] itxf_din;
112
reg        itxf_wr;
113
 
114 21 johnsonw10
// packet fields
115
reg [0:1] spd;
116
reg [0:5] tl;
117
reg [0:1] rt;
118
reg [0:3] tc;
119
reg [0:3] pri;
120
reg [0:15] dest_id;
121
reg [0:47] dest_offset;
122
 
123
reg err_count;
124
 
125
 
126 11 johnsonw10
initial begin
127 21 johnsonw10
    // set time format
128
    $timeformat(-9, 1, " ns", 5);
129
    err_count = 0;
130 11 johnsonw10
    reset_n = 1;
131
    host_cs_n = 1;
132
    host_wr_n = 1;
133
 
134 21 johnsonw10
    rcvd_ql_num = 0;
135 11 johnsonw10
    atxf_wr = 0;
136
 
137
    #25 reset_n = 0;
138
    #100 reset_n = 1;
139
 
140
 
141
    // enable link_op (set bits 5, 6, 7, 8 @ 0x08)
142
    host_write_reg (16'h08, 32'h0780_0000);
143
 
144
    #100;
145
 
146
    // phy receive selfid packet #0
147 21 johnsonw10
    spd = 2'b00;
148
    pkt_type = `SELF_ID_PKT;
149 11 johnsonw10
    selfid_data[0:1]   = 2'b01;          //selfid packet identifier
150
    selfid_data[2:7]   = 6'b00_0011;     //sender's phy_ID
151
    selfid_data[8]     = 1'b0;           //always 0
152
    selfid_data[9]     = 1'b1;           //link_active = 1
153
    selfid_data[10:15] = 6'b01_0000;     //gap_count = 10h
154
    selfid_data[16:17] = 2'b00;          //phy_speed = 100Mbit/s
155
    selfid_data[18:19] = 2'b00;          //phy_delay <= 144ns
156
    selfid_data[20]    = 1'b0;           //contender = 0
157
    selfid_data[21:23] = 3'b000;         //power_class = 0;
158
    selfid_data[24:25] = 2'b11;          //p0;
159
    selfid_data[26:27] = 2'b11;          //p1
160
    selfid_data[28:29] = 2'b11;          //p2
161
    selfid_data[30]    = 1'b0;           //initiated_reset = 0
162
    selfid_data[31]    = 1'b0;           //more_packets = 0
163
 
164 21 johnsonw10
    phy_ctrl.rcv_buf[0] = selfid_data;
165
    phy_ctrl.rcv_buf[1] = ~selfid_data;
166
 
167
    set_exp_buf (2);
168 11 johnsonw10
 
169 21 johnsonw10
    phy_ctrl.phy_rcv_pkt (spd, pkt_type);     //receive 2 32-bit word at 100Mbit/s
170 11 johnsonw10
 
171
    #100;
172
 
173 21 johnsonw10
    //phy status
174
    status[0]    = 1'b1;     // reset_gap = 1
175
    status[1]    = 1'b0;     // sub_gap = 0
176
    status[2]    = 1'b0;     // bus_reset = 0;
177
    status[3]    = 1'b0;     // bus_time_out = 0;
178
    status[4:7]  = 4'h0;     // physical_id addr
179
    status[8:15] = 8'b0010_1000;  // id = a, r = 0, ps = 0
180 11 johnsonw10
 
181 21 johnsonw10
    exp_status = status;
182
    phy_ctrl.phy_status (status);
183 11 johnsonw10
 
184 21 johnsonw10
    // read request for data quadlet at 400Mbit/s
185
    phy_ctrl.arb_won = 1;  //tells phy to grant the bus control
186
    spd = 2'b10;
187
    tl = 6'b010101;
188
    rt = 2'b01;
189
    tc = 4'h4;
190
    pri = 4'h0;
191
    dest_id = 16'haaaa;
192
    dest_offset = 48'h1234_5678_9abc;
193 11 johnsonw10
 
194 21 johnsonw10
    phy_ctrl.send_ack = 1; //tells phy to send back ack pakcet
195
    set_send_buf (3);
196 11 johnsonw10
 
197 21 johnsonw10
    $display ("STATUS @%t: %m: sending read request for data for quadlet",
198
              $time);
199 11 johnsonw10
    host_write_atxf (3);
200
 
201 21 johnsonw10
    // dest sends back ack packet
202
    wait (phy_ctrl.pkt_sent);
203
    spd = 2'b10;
204
    pkt_type = `ACK_PKT;
205
    ack_code = `ACK_COMPLETE;
206
    phy_ctrl.rcv_buf[0] = {ack_code, ~ack_code, 24'h00_0000};
207
    phy_ctrl.phy_rcv_pkt(spd, pkt_type);
208
 
209 11 johnsonw10
end
210
 
211
initial sclk = 0;
212
always #10 sclk = ~sclk;   // 50MHz sclk
213
 
214
// atx FIFO
215
fifo_beh atxf (
216
               // Outputs
217
               .dout                    (atxf_data[0:31]),
218
               .empty                   (atxf_ef),
219
               .full                    (atxf_ff),
220
               // Inputs
221
               .reset_n                 (reset_n),
222
               .clk                     (sclk),
223
               .wr                      (atxf_wr),
224
               .din                     (atxf_din[0:31]),
225
               .rd                      (atxf_rd));
226
 
227
// itx FIFO
228
fifo_beh itxf (
229
               // Outputs
230
               .dout                    (itxf_data[0:31]),
231
               .empty                   (itxf_ef),
232
               .full                    (itxf_ff),
233
               // Inputs
234
               .reset_n                 (reset_n),
235
               .clk                     (sclk),
236
               .wr                      (itxf_wr),
237
               .din                     (itxf_din[0:31]),
238
               .rd                      (itxf_rd));
239
 
240
wire [0:15] src_id;
241
wire hard_rst = ~reset_n;
242
 
243 21 johnsonw10
// bi-directional d and ctl buses
244
tran tran_d0 (d[0], phy_d[0]);
245
tran tran_d1 (d[1], phy_d[1]);
246
tran tran_d2 (d[2], phy_d[2]);
247
tran tran_d3 (d[3], phy_d[3]);
248
tran tran_d4 (d[4], phy_d[4]);
249
tran tran_d5 (d[5], phy_d[5]);
250
tran tran_d6 (d[6], phy_d[6]);
251
tran tran_d7 (d[7], phy_d[7]);
252
 
253
tran tran_ctl0(ctl[0], phy_ctl[0]);
254
tran tran_ctl1(ctl[1], phy_ctl[1]);
255
 
256 11 johnsonw10
assign host_data = host_data_out;
257
 
258
fw_link_host_if link_host_if (/*AUTOINST*/
259
                              // Outputs
260
                              .src_id   (src_id[0:15]),
261
                              .tx_asy_en(tx_asy_en),
262
                              .rx_asy_en(rx_asy_en),
263
                              .tx_iso_en(tx_iso_en),
264
                              .rx_iso_en(rx_iso_en),
265
                              .soft_rst (soft_rst),
266
                              // Inouts
267
                              .host_data(host_data[0:31]),
268
                              // Inputs
269
                              .hard_rst (hard_rst),
270
                              .sclk     (sclk),
271
                              .host_cs_n(host_cs_n),
272
                              .host_wr_n(host_wr_n),
273
                              .host_addr(host_addr[0:7]));
274
 
275
fw_link_ctrl link_ctrl (/*AUTOINST*/
276
                        // Outputs
277
                        .lreq           (lreq),
278
                        .status_rcvd    (status_rcvd),
279
                        .arb_reset_gap  (arb_reset_gap),
280
                        .sub_gap        (sub_gap),
281
                        .bus_reset      (bus_reset),
282
                        .state_time_out (state_time_out),
283
                        .phy_reg_addr   (phy_reg_addr[0:3]),
284
                        .phy_reg_data   (phy_reg_data[0:7]),
285
                        .atxf_rd        (atxf_rd),
286
                        .itxf_rd        (itxf_rd),
287
                        .grxf_we        (grxf_we),
288
                        .grxf_data      (grxf_data[0:31]),
289
                        // Inouts
290
                        .d              (d[0:7]),
291
                        .ctl            (ctl[0:1]),
292
                        // Inputs
293
                        .hard_rst       (hard_rst),
294
                        .sclk           (sclk),
295
                        .src_id         (src_id[0:15]),
296
                        .soft_rst       (soft_rst),
297
                        .tx_asy_en      (tx_asy_en),
298
                        .rx_asy_en      (rx_asy_en),
299
                        .tx_iso_en      (tx_iso_en),
300
                        .rx_iso_en      (rx_iso_en),
301
                        .atxf_ef        (atxf_ef),
302
                        .atxf_data      (atxf_data[0:31]),
303
                        .itxf_ef        (itxf_ef),
304
                        .itxf_data      (itxf_data[0:31]),
305
                        .grxf_ff        (grxf_ff));
306
 
307
wire lreq_sent;
308
 
309 21 johnsonw10
assign phy_ctrl.lreq_rcvd = link_ctrl.link_req.req_sent;
310 11 johnsonw10
 
311 21 johnsonw10
defparam phy_ctrl.BUF_SIZE = BUF_SIZE;
312
fw_phy_ctrl phy_ctrl (/*AUTOINST*/
313
                      // Inouts
314
                      .phy_ctl          (phy_ctl[0:1]),
315
                      .phy_d            (phy_d[0:7]),
316
                      // Inputs
317
                      .sclk             (sclk));
318 11 johnsonw10
 
319
// grxf monitor
320
always @ (posedge sclk) begin : grxf_monitor
321
    if (grxf_we) begin
322 21 johnsonw10
        $display ("STATUS @%t: %m: received quadlet %0d = %x",
323
                  $time, rcvd_ql_num, grxf_data);
324
        if (grxf_data != exp_buf[rcvd_ql_num]) begin
325
            $display ("ERROR @%t: %m: incorrect quadlet %0d received:",
326
                      $time, rcvd_ql_num);
327
            $display ("        expected: %x", exp_buf[rcvd_ql_num]);
328
            $display ("        received: %x", grxf_data);
329
 
330
            err_count = err_count + 1;
331
        end
332
 
333
        rcvd_ql_num = (rcvd_ql_num == exp_ql_num) ? 0 : (rcvd_ql_num + 1);
334 11 johnsonw10
    end
335
end
336
 
337
// status monitor
338
always @ (posedge sclk) begin : status_monitor
339
    if (status_rcvd) begin
340 21 johnsonw10
        rcvd_status = {arb_reset_gap, sub_gap, bus_reset, state_time_out,
341
                       phy_reg_addr, phy_reg_data};
342
        $display ("STATUS @%t: %m: received phy status = %x",
343
                  $time, rcvd_status);
344 11 johnsonw10
        $display ("    arb_reset_gap = %h", arb_reset_gap);
345
        $display ("    sub_gap = %h", sub_gap);
346
        $display ("    bus_reset = %h", bus_reset);
347
        $display ("    state_time_out = %h", state_time_out);
348
        $display ("    phy_reg_addr = %h", phy_reg_addr);
349
        $display ("    phy_reg_data = %h", phy_reg_data);
350 21 johnsonw10
 
351
        if (exp_status != rcvd_status) begin
352
            $display ("ERROR @%t: %m: incorrect phy status received:", $time);
353
            $display ("        expected: %x", exp_status);
354
            $display ("        received: %x", rcvd_status);
355
 
356
            err_count = err_count + 1;
357
        end
358 11 johnsonw10
    end
359
end
360
 
361
`include "fw_host_tasks.v"
362
 
363 21 johnsonw10
task set_send_buf;
364
input ql_num;
365
integer ql_num;
366
 
367
begin
368
    send_buf[0] = {14'h0000, spd, tl, rt, tc, pri};
369
    send_buf[1] = {dest_id, dest_offset[0:15]};
370
    send_buf[2] = dest_offset[16:47];
371
 
372
    // set exp_buf for the checker
373
    phy_ctrl.tx_spd     = spd;
374
    phy_ctrl.exp_ql_num = ql_num + 1;
375
    phy_ctrl.exp_buf[0] = {dest_id, tl, rt, tc, pri};
376
    phy_ctrl.exp_buf[1] = {src_id, dest_offset[0:15]};
377
    phy_ctrl.exp_buf[2] = dest_offset[16:47];
378
    phy_ctrl.exp_buf[3] = gen_crc(ql_num);
379
end
380
endtask // set_send_buf
381
 
382
task set_exp_buf;
383
input ql_num;
384
integer ql_num;
385
begin
386
    exp_ql_num = 2;
387
    exp_buf[0] = phy_ctrl.rcv_buf[0];
388
    exp_buf[1] = phy_ctrl.rcv_buf[1];
389
end
390
endtask // set_exp_buf
391
 
392
// CRC32 generation function
393
parameter MSB32       = 32'h8000_0000;
394
parameter CRC_COMPUTE = 32'h04c1_1db7;
395
parameter CRC_RESULTs = 32'hc704_dd7b;
396
 
397
function [0:31] gen_crc;
398
input ql_num;
399
integer ql_num;
400
 
401
reg [0:31] crc_sum;
402
reg [0:31] mask;
403
reg        new_bit, old_bit, sum_bit;
404
 
405
integer i;
406
integer in_ql;
407
begin
408
    crc_sum = 32'hffff_ffff;
409
    for (i = 0; i < ql_num; i = i + 1) begin
410
        in_ql = phy_ctrl.exp_buf[i];
411
        for (mask = MSB32; mask != 0; mask = mask >> 1) begin
412
            new_bit = ((in_ql & mask) != 32'h0000_0000);
413
            old_bit = ((crc_sum & MSB32) != 32'h0000_0000);
414
            sum_bit = old_bit ^ new_bit;
415
 
416
            // update crc_sum
417
            crc_sum = (crc_sum << 1) ^ (sum_bit ? CRC_COMPUTE : 0);
418
        end // (mask = MSB32; mask != 0; mask = mask >> 1)
419
    end //for (i = 0; i < ql_num, i = i + 1)
420
 
421
    gen_crc = crc_sum;
422
end
423
endfunction
424
 
425 11 johnsonw10
endmodule // fw_link_tb
426
 
427
// Local Variables:
428
// verilog-library-directories:("." "../../rtl/verilog")
429
// End:

powered by: WebSVN 2.1.0

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