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

Subversion Repositories pci

[/] [pci/] [tags/] [rel_7/] [bench/] [verilog/] [wb_master32.v] - Blame information for rev 154

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 15 mihad
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  File name "wb_master32.v"                                   ////
4
////                                                              ////
5
////  This file is part of the "PCI bridge" project               ////
6
////  http://www.opencores.org/cores/pci/                         ////
7
////                                                              ////
8
////  Author(s):                                                  ////
9
////      - Miha Dolenc (mihad@opencores.org)                     ////
10
////                                                              ////
11
////  All additional information is avaliable in the README.pdf   ////
12
////  file.                                                       ////
13
////                                                              ////
14
////                                                              ////
15
//////////////////////////////////////////////////////////////////////
16
////                                                              ////
17
//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org          ////
18
////                                                              ////
19
//// This source file may be used and distributed without         ////
20
//// restriction provided that this copyright statement is not    ////
21
//// removed from the file and that any derivative work contains  ////
22
//// the original copyright notice and the associated disclaimer. ////
23
////                                                              ////
24
//// This source file is free software; you can redistribute it   ////
25
//// and/or modify it under the terms of the GNU Lesser General   ////
26
//// Public License as published by the Free Software Foundation; ////
27
//// either version 2.1 of the License, or (at your option) any   ////
28
//// later version.                                               ////
29
////                                                              ////
30
//// This source is distributed in the hope that it will be       ////
31
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
32
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
33
//// PURPOSE.  See the GNU Lesser General Public License for more ////
34
//// details.                                                     ////
35
////                                                              ////
36
//// You should have received a copy of the GNU Lesser General    ////
37
//// Public License along with this source; if not, download it   ////
38
//// from http://www.opencores.org/lgpl.shtml                     ////
39
////                                                              ////
40
//////////////////////////////////////////////////////////////////////
41
//
42
// CVS Revision History
43
//
44
// $Log: not supported by cvs2svn $
45 106 mihad
// Revision 1.3  2003/07/29 08:19:47  mihad
46
// Found and simulated the problem in the synchronization logic.
47
// Repaired the synchronization logic in the FIFOs.
48
//
49 104 mihad
// Revision 1.2  2003/06/12 02:30:39  mihad
50
// Update!
51
//
52 92 mihad
// Revision 1.1  2002/02/01 13:39:43  mihad
53
// Initial testbench import. Still under development
54 15 mihad
//
55 92 mihad
//
56 15 mihad
 
57
`include "pci_testbench_defines.v"
58
`include "timescale.v"
59
module WB_MASTER32
60
(
61
    CLK_I,
62
    RST_I,
63
    TAG_I,
64
    TAG_O,
65
    ACK_I,
66
    ADR_O,
67
    CYC_O,
68
    DAT_I,
69
    DAT_O,
70
    ERR_I,
71
    RTY_I,
72
    SEL_O,
73
    STB_O,
74
    WE_O,
75
    CAB_O
76
);
77
 
78
    input                    CLK_I;
79
    input                    RST_I;
80
    input    `WB_TAG_TYPE    TAG_I;
81
    output   `WB_TAG_TYPE    TAG_O;
82
    input                    ACK_I;
83
    output   `WB_ADDR_TYPE   ADR_O;
84
    output                   CYC_O;
85
    input    `WB_DATA_TYPE   DAT_I;
86
    output   `WB_DATA_TYPE   DAT_O;
87
    input                    ERR_I;
88
    input                    RTY_I;
89
    output   `WB_SEL_TYPE    SEL_O;
90
    output                   STB_O;
91
    output                   WE_O;
92
    output                   CAB_O ;
93
 
94
    // period length
95
    real Tp ;
96
 
97
    reg    `WB_ADDR_TYPE   ADR_O;
98
    reg    `WB_SEL_TYPE    SEL_O;
99
    reg    `WB_TAG_TYPE    TAG_O;
100
    reg                    CYC_O;
101
    reg                    WE_O;
102
    reg    `WB_DATA_TYPE   DAT_O;
103
    reg                    CAB_O ;
104
    reg                    STB_O ;
105
 
106
    // variable used for indication on whether cycle was already started
107
    reg in_use ;
108
 
109
    // because of non-blocking assignments CYC_O is not sufficient indicator for cycle starting - this var is used in its place
110
    reg cycle_in_progress ;
111
 
112
    // same goes for CAB_O signal
113
    reg cab ;
114
 
115
    reg we ;
116
 
117
    task start_cycle ;
118 92 mihad
        input is_cab  ;
119
        input write   ;
120
        input fastb2b ;
121 15 mihad
        output ok ;      // ok indicates to the caller that cycle was started succesfully - if not, caller must take appropriate action
122
    begin:main
123
 
124
        ok  = 1 ;
125
 
126
        // just check if valid value is provided for CAB_O signal (no x's or z's allowed)
127
        if ( (is_cab !== 1'b0) && (is_cab !== 1'b1) )
128
        begin
129
            $display("*E, invalid CAB value for cycle! Requested CAB_O value = %b, Time %t ", is_cab, $time) ;
130
            ok = 0 ;
131
            disable main ;
132
        end
133
 
134
        if ( (cycle_in_progress === 1) || (CYC_O === 1))
135
        begin
136
            // cycle was previously started - allow cycle to continue if CAB and WE values match
137 92 mihad
            if (fastb2b !== 1'b1)
138
                $display("*W, cycle already in progress when start_cycle routine was called! Time %t ", $time) ;
139
 
140 15 mihad
            if ((CAB_O !== is_cab) || (WE_O !== write) )
141
            begin
142
                ok = 0 ;
143
                if ( is_cab === 1 )
144
                    $display("*E, cab cycle start attempted when non-cab cycle was in progress! Time %t", $time) ;
145
                else
146
                    $display("*E, non-cab cycle start attempted when cab cycle was in progress! Time %t", $time) ;
147
 
148
                if ( we === 1 )
149
                    $display("*E, write cycle start attempted when read cycle was in progress! Time %t", $time) ;
150
                else
151
                    $display("*E, read cycle start attempted when write cycle was in progress! Time %t", $time) ;
152
 
153
                disable main ;
154
            end
155
        end
156
 
157
        CYC_O <= #(Tp - `Tsetup) 1'b1 ;
158
        CAB_O <= #(Tp - `Tsetup) is_cab ;
159
        WE_O  <= #(Tp - `Tsetup) write ;
160
 
161
        // this non-blocking assignments are made to internal variables, so read and write tasks can be called immediately after cycle start task
162
        cycle_in_progress = 1'b1 ;
163
        cab               = is_cab ;
164
        we                = write ;
165
    end
166
    endtask //start_cycle
167
 
168
    task end_cycle ;
169
    begin
170
        if ( CYC_O !== 1'b1 )
171
            $display("*W, end_cycle routine called when CYC_O value was %b! Time %t ", CYC_O, $time) ;
172
 
173
        CYC_O <= #`Thold 1'b0 ;
174
        CAB_O <= #`Thold 1'b0 ;
175
        cycle_in_progress = 1'b0 ;
176
    end
177
    endtask //end_cycle
178
 
179
    task modify_cycle ;
180
    begin
181
        if ( CYC_O !== 1'b1 )
182
            $display("*W, modify_cycle routine called when CYC_O value was %b! Time %t ", CYC_O, $time) ;
183
 
184
        we = ~we ;
185
        WE_O <= #(Tp - `Tsetup) we ;
186
    end
187
    endtask //modify_cycle
188
 
189
    task wbm_read ;
190
        input  `READ_STIM_TYPE input_data ;
191
        inout `READ_RETURN_TYPE   output_data ;
192
        reg    `WB_ADDR_TYPE           address ;
193
        reg    `WB_DATA_TYPE           data ;
194
        reg    `WB_SEL_TYPE            sel ;
195
        reg    `WB_TAG_TYPE            tag ;
196
        integer                        num_of_cyc ;
197
    begin:main
198
        output_data`TB_ERROR_BIT = 1'b0 ;
199
 
200
        // check if task was called before previous call to read or write finished
201
        if ( in_use === 1 )
202
        begin
203
            $display("*E, wbm_read routine re-entered or called concurently with write routine! Time %t ", $time) ;
204
            output_data`TB_ERROR_BIT = 1'b1 ;
205
            disable main ;
206
        end
207
 
208
        if ( cycle_in_progress !== 1 )
209
        begin
210
            $display("*E, wbm_read routine called without start_cycle routine being called first! Time %t ", $time) ;
211
            output_data`TB_ERROR_BIT = 1'b1 ;
212
            disable main ;
213
        end
214
 
215
        if ( we !== 0 )
216
        begin
217
            $display("*E, wbm_read routine called after write cycle was started! Time %t ", $time) ;
218
            output_data`TB_ERROR_BIT = 1'b1 ;
219
            disable main ;
220
        end
221
 
222
        // this branch contains timing controls - claim the use of WISHBONE
223
        in_use = 1 ;
224
 
225
        num_of_cyc = `WAIT_FOR_RESPONSE ;
226
 
227
        // assign data outputs
228
        ADR_O      <= #(Tp - `Tsetup) input_data`READ_ADDRESS ;
229
        SEL_O      <= #(Tp - `Tsetup) input_data`READ_SEL ;
230
        TAG_O      <= #(Tp - `Tsetup) input_data`READ_TAG_STIM ;
231
 
232
        // assign control output
233
        STB_O      <= #(Tp - `Tsetup) 1'b1 ;
234
 
235
        output_data`CYC_ACK = 0 ;
236
        output_data`CYC_RTY = 0 ;
237
        output_data`CYC_ERR = 0 ;
238
 
239
        @(posedge CLK_I) ;
240
        output_data`CYC_ACK = ACK_I ;
241
        output_data`CYC_RTY = RTY_I ;
242
        output_data`CYC_ERR = ERR_I ;
243
 
244
        while ( (num_of_cyc > 0) && (output_data`CYC_RESPONSE === 0) )
245
        begin
246
            @(posedge CLK_I) ;
247
            output_data`CYC_ACK = ACK_I ;
248
            output_data`CYC_RTY = RTY_I ;
249
            output_data`CYC_ERR = ERR_I ;
250
            num_of_cyc = num_of_cyc - 1 ;
251
        end
252
 
253
        output_data`READ_DATA    = DAT_I ;
254
        output_data`READ_TAG_RET = TAG_I ;
255
 
256
        if ( output_data`CYC_RESPONSE === 0 )
257
        begin
258
 
259
            $display("*W, Terminating read cycle because no response was received in %d cycles! Time %t ", `WAIT_FOR_RESPONSE, $time) ;
260
        end
261
 
262
        if ( output_data`CYC_ACK === 1 && output_data`CYC_RTY === 0 && output_data`CYC_ERR === 0 )
263
            output_data`CYC_ACTUAL_TRANSFER = output_data`CYC_ACTUAL_TRANSFER + 1 ;
264
 
265
        STB_O <= #`Thold 1'b0 ;
266
        ADR_O <= #`Thold {`WB_ADDR_WIDTH{1'bx}} ;
267
        SEL_O <= #`Thold {`WB_SEL_WIDTH{1'bx}} ;
268
        TAG_O <= #`Thold {`WB_TAG_WIDTH{1'bx}} ;
269
 
270
        in_use = 0 ;
271
    end
272
    endtask // wbm_read
273
 
274
    task wbm_write ;
275
        input  `WRITE_STIM_TYPE input_data ;
276
        inout  `WRITE_RETURN_TYPE   output_data ;
277
        reg    `WB_ADDR_TYPE        address ;
278
        reg    `WB_DATA_TYPE        data ;
279
        reg    `WB_SEL_TYPE         sel ;
280
        reg    `WB_TAG_TYPE         tag ;
281
        integer                     num_of_cyc ;
282
    begin:main
283
        output_data`TB_ERROR_BIT = 1'b0 ;
284
 
285
        // check if task was called before previous call to read or write finished
286
        if ( in_use === 1 )
287
        begin
288
            $display("*E, wbm_write routine re-entered or called concurently with read routine! Time %t ", $time) ;
289
            output_data`TB_ERROR_BIT = 1'b1 ;
290
            disable main ;
291
        end
292
 
293
        if ( cycle_in_progress !== 1 )
294
        begin
295
            $display("*E, wbm_write routine called without start_cycle routine being called first! Time %t ", $time) ;
296
            output_data`TB_ERROR_BIT = 1'b1 ;
297
            disable main ;
298
        end
299
 
300
        if ( we !== 1 )
301
        begin
302
            $display("*E, wbm_write routine after read cycle was started! Time %t ", $time) ;
303
            output_data`TB_ERROR_BIT = 1'b1 ;
304
            disable main ;
305
        end
306
 
307
        // this branch contains timing controls - claim the use of WISHBONE
308
        in_use = 1 ;
309
 
310
        num_of_cyc = `WAIT_FOR_RESPONSE ;
311
 
312
        ADR_O      <= #(Tp - `Tsetup) input_data`WRITE_ADDRESS ;
313 106 mihad
 
314
        begin:dat_o_assign_blk
315
            reg [`WB_SEL_WIDTH - 1:0] cur_sel ;
316
            reg [`WB_DATA_WIDTH - 1:0] cur_dat ;
317
            reg [`WB_DATA_WIDTH - 1:0] rnd_dat ;
318
            integer cur_bit ;
319
 
320
            cur_dat = input_data`WRITE_DATA ;
321
            cur_sel = input_data`WRITE_SEL  ;
322
            rnd_dat = $random ;
323
 
324
            for(cur_bit = 0 ; cur_bit < `WB_DATA_WIDTH ; cur_bit = cur_bit + 1)
325
            begin
326
                if (cur_sel[cur_bit/8] === 1'b1)
327
                    DAT_O[cur_bit] <= #(Tp - `Tsetup) cur_dat[cur_bit] ;
328
                else
329
                    DAT_O[cur_bit] <= #(Tp - `Tsetup) rnd_dat[cur_bit] ;
330
            end
331
        end
332
 
333 15 mihad
        SEL_O      <= #(Tp - `Tsetup) input_data`WRITE_SEL ;
334
        TAG_O      <= #(Tp - `Tsetup) input_data`WRITE_TAG_STIM ;
335
 
336
        STB_O      <= #(Tp - `Tsetup) 1'b1 ;
337
 
338
        output_data`CYC_ACK = 0 ;
339
        output_data`CYC_RTY = 0 ;
340
        output_data`CYC_ERR = 0 ;
341
 
342
        @(posedge CLK_I) ;
343
        output_data`CYC_ACK = ACK_I ;
344
        output_data`CYC_RTY = RTY_I ;
345
        output_data`CYC_ERR = ERR_I ;
346
 
347
        while ( (num_of_cyc > 0) && (output_data`CYC_RESPONSE === 0) )
348
        begin
349
            @(posedge CLK_I) ;
350
            output_data`CYC_ACK = ACK_I ;
351
            output_data`CYC_RTY = RTY_I ;
352
            output_data`CYC_ERR = ERR_I ;
353
            num_of_cyc = num_of_cyc - 1 ;
354
        end
355
 
356
        output_data`WRITE_TAG_RET = TAG_I ;
357
        if ( output_data`CYC_RESPONSE === 0 )
358
        begin
359
            $display("*W, Terminating write cycle because no response was received in %d cycles! Time %t ", `WAIT_FOR_RESPONSE, $time) ;
360
        end
361
 
362
        if ( output_data`CYC_ACK === 1 && output_data`CYC_RTY === 0 && output_data`CYC_ERR === 0 )
363
            output_data`CYC_ACTUAL_TRANSFER = output_data`CYC_ACTUAL_TRANSFER + 1 ;
364
 
365
        ADR_O <= #`Thold {`WB_ADDR_WIDTH{1'bx}} ;
366
        DAT_O <= #`Thold {`WB_DATA_WIDTH{1'bx}} ;
367
        SEL_O <= #`Thold {`WB_SEL_WIDTH{1'bx}} ;
368
        TAG_O <= #`Thold {`WB_TAG_WIDTH{1'bx}} ;
369
 
370
        STB_O <= #`Thold 1'b0 ;
371
 
372
        in_use = 0 ;
373
    end
374
    endtask //wbm_write
375
 
376
    initial
377
    begin
378 104 mihad
        Tp = `WB_PERIOD ;
379 15 mihad
        in_use = 0 ;
380
        cycle_in_progress = 0 ;
381
        cab = 0 ;
382
        ADR_O <= {`WB_ADDR_WIDTH{1'bx}} ;
383
        DAT_O <= {`WB_DATA_WIDTH{1'bx}} ;
384
        SEL_O <= {`WB_SEL_WIDTH{1'bx}} ;
385
        TAG_O <= {`WB_TAG_WIDTH{1'bx}} ;
386
        CYC_O <= 1'b0 ;
387
        STB_O <= 1'b0 ;
388
        CAB_O <= 1'b0 ;
389
        WE_O  <= 1'b0 ;
390
        if ( `Tsetup > Tp || `Thold >= Tp )
391
        begin
392
            $display("Either Tsetup or Thold values for WISHBONE BFMs are too large!") ;
393
            $stop ;
394
        end
395
    end
396
 
397
endmodule

powered by: WebSVN 2.1.0

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