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

Subversion Repositories pci

[/] [pci/] [tags/] [rel_5/] [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
//
46
 
47
`include "pci_testbench_defines.v"
48
`include "timescale.v"
49
module WB_MASTER32
50
(
51
    CLK_I,
52
    RST_I,
53
    TAG_I,
54
    TAG_O,
55
    ACK_I,
56
    ADR_O,
57
    CYC_O,
58
    DAT_I,
59
    DAT_O,
60
    ERR_I,
61
    RTY_I,
62
    SEL_O,
63
    STB_O,
64
    WE_O,
65
    CAB_O
66
);
67
 
68
    input                    CLK_I;
69
    input                    RST_I;
70
    input    `WB_TAG_TYPE    TAG_I;
71
    output   `WB_TAG_TYPE    TAG_O;
72
    input                    ACK_I;
73
    output   `WB_ADDR_TYPE   ADR_O;
74
    output                   CYC_O;
75
    input    `WB_DATA_TYPE   DAT_I;
76
    output   `WB_DATA_TYPE   DAT_O;
77
    input                    ERR_I;
78
    input                    RTY_I;
79
    output   `WB_SEL_TYPE    SEL_O;
80
    output                   STB_O;
81
    output                   WE_O;
82
    output                   CAB_O ;
83
 
84
    // period length
85
    real Tp ;
86
 
87
    reg    `WB_ADDR_TYPE   ADR_O;
88
    reg    `WB_SEL_TYPE    SEL_O;
89
    reg    `WB_TAG_TYPE    TAG_O;
90
    reg                    CYC_O;
91
    reg                    WE_O;
92
    reg    `WB_DATA_TYPE   DAT_O;
93
    reg                    CAB_O ;
94
    reg                    STB_O ;
95
 
96
    // variable used for indication on whether cycle was already started
97
    reg in_use ;
98
 
99
    // because of non-blocking assignments CYC_O is not sufficient indicator for cycle starting - this var is used in its place
100
    reg cycle_in_progress ;
101
 
102
    // same goes for CAB_O signal
103
    reg cab ;
104
 
105
    reg we ;
106
 
107
    task start_cycle ;
108
        input is_cab ;
109
        input write  ;
110
        output ok ;      // ok indicates to the caller that cycle was started succesfully - if not, caller must take appropriate action
111
    begin:main
112
 
113
        ok  = 1 ;
114
 
115
        // just check if valid value is provided for CAB_O signal (no x's or z's allowed)
116
        if ( (is_cab !== 1'b0) && (is_cab !== 1'b1) )
117
        begin
118
            $display("*E, invalid CAB value for cycle! Requested CAB_O value = %b, Time %t ", is_cab, $time) ;
119
            ok = 0 ;
120
            disable main ;
121
        end
122
 
123
        if ( (cycle_in_progress === 1) || (CYC_O === 1))
124
        begin
125
            // cycle was previously started - allow cycle to continue if CAB and WE values match
126
            $display("*W, cycle already in progress when start_cycle routine was called! Time %t ", $time) ;
127
            if ((CAB_O !== is_cab) || (WE_O !== write) )
128
            begin
129
                ok = 0 ;
130
                if ( is_cab === 1 )
131
                    $display("*E, cab cycle start attempted when non-cab cycle was in progress! Time %t", $time) ;
132
                else
133
                    $display("*E, non-cab cycle start attempted when cab cycle was in progress! Time %t", $time) ;
134
 
135
                if ( we === 1 )
136
                    $display("*E, write cycle start attempted when read cycle was in progress! Time %t", $time) ;
137
                else
138
                    $display("*E, read cycle start attempted when write cycle was in progress! Time %t", $time) ;
139
 
140
                disable main ;
141
            end
142
        end
143
 
144
        CYC_O <= #(Tp - `Tsetup) 1'b1 ;
145
        CAB_O <= #(Tp - `Tsetup) is_cab ;
146
        WE_O  <= #(Tp - `Tsetup) write ;
147
 
148
        // this non-blocking assignments are made to internal variables, so read and write tasks can be called immediately after cycle start task
149
        cycle_in_progress = 1'b1 ;
150
        cab               = is_cab ;
151
        we                = write ;
152
    end
153
    endtask //start_cycle
154
 
155
    task end_cycle ;
156
    begin
157
        if ( CYC_O !== 1'b1 )
158
            $display("*W, end_cycle routine called when CYC_O value was %b! Time %t ", CYC_O, $time) ;
159
 
160
        CYC_O <= #`Thold 1'b0 ;
161
        CAB_O <= #`Thold 1'b0 ;
162
        cycle_in_progress = 1'b0 ;
163
    end
164
    endtask //end_cycle
165
 
166
    task modify_cycle ;
167
    begin
168
        if ( CYC_O !== 1'b1 )
169
            $display("*W, modify_cycle routine called when CYC_O value was %b! Time %t ", CYC_O, $time) ;
170
 
171
        we = ~we ;
172
        WE_O <= #(Tp - `Tsetup) we ;
173
    end
174
    endtask //modify_cycle
175
 
176
    task wbm_read ;
177
        input  `READ_STIM_TYPE input_data ;
178
        inout `READ_RETURN_TYPE   output_data ;
179
        reg    `WB_ADDR_TYPE           address ;
180
        reg    `WB_DATA_TYPE           data ;
181
        reg    `WB_SEL_TYPE            sel ;
182
        reg    `WB_TAG_TYPE            tag ;
183
        integer                        num_of_cyc ;
184
    begin:main
185
        output_data`TB_ERROR_BIT = 1'b0 ;
186
 
187
        // check if task was called before previous call to read or write finished
188
        if ( in_use === 1 )
189
        begin
190
            $display("*E, wbm_read routine re-entered or called concurently with write routine! Time %t ", $time) ;
191
            output_data`TB_ERROR_BIT = 1'b1 ;
192
            disable main ;
193
        end
194
 
195
        if ( cycle_in_progress !== 1 )
196
        begin
197
            $display("*E, wbm_read routine called without start_cycle routine being called first! Time %t ", $time) ;
198
            output_data`TB_ERROR_BIT = 1'b1 ;
199
            disable main ;
200
        end
201
 
202
        if ( we !== 0 )
203
        begin
204
            $display("*E, wbm_read routine called after write cycle was started! Time %t ", $time) ;
205
            output_data`TB_ERROR_BIT = 1'b1 ;
206
            disable main ;
207
        end
208
 
209
        // this branch contains timing controls - claim the use of WISHBONE
210
        in_use = 1 ;
211
 
212
        num_of_cyc = `WAIT_FOR_RESPONSE ;
213
 
214
        // assign data outputs
215
        ADR_O      <= #(Tp - `Tsetup) input_data`READ_ADDRESS ;
216
        SEL_O      <= #(Tp - `Tsetup) input_data`READ_SEL ;
217
        TAG_O      <= #(Tp - `Tsetup) input_data`READ_TAG_STIM ;
218
 
219
        // assign control output
220
        STB_O      <= #(Tp - `Tsetup) 1'b1 ;
221
 
222
        output_data`CYC_ACK = 0 ;
223
        output_data`CYC_RTY = 0 ;
224
        output_data`CYC_ERR = 0 ;
225
 
226
        @(posedge CLK_I) ;
227
        output_data`CYC_ACK = ACK_I ;
228
        output_data`CYC_RTY = RTY_I ;
229
        output_data`CYC_ERR = ERR_I ;
230
 
231
        while ( (num_of_cyc > 0) && (output_data`CYC_RESPONSE === 0) )
232
        begin
233
            @(posedge CLK_I) ;
234
            output_data`CYC_ACK = ACK_I ;
235
            output_data`CYC_RTY = RTY_I ;
236
            output_data`CYC_ERR = ERR_I ;
237
            num_of_cyc = num_of_cyc - 1 ;
238
        end
239
 
240
        output_data`READ_DATA    = DAT_I ;
241
        output_data`READ_TAG_RET = TAG_I ;
242
 
243
        if ( output_data`CYC_RESPONSE === 0 )
244
        begin
245
 
246
            $display("*W, Terminating read cycle because no response was received in %d cycles! Time %t ", `WAIT_FOR_RESPONSE, $time) ;
247
        end
248
 
249
        if ( output_data`CYC_ACK === 1 && output_data`CYC_RTY === 0 && output_data`CYC_ERR === 0 )
250
            output_data`CYC_ACTUAL_TRANSFER = output_data`CYC_ACTUAL_TRANSFER + 1 ;
251
 
252
        STB_O <= #`Thold 1'b0 ;
253
        ADR_O <= #`Thold {`WB_ADDR_WIDTH{1'bx}} ;
254
        SEL_O <= #`Thold {`WB_SEL_WIDTH{1'bx}} ;
255
        TAG_O <= #`Thold {`WB_TAG_WIDTH{1'bx}} ;
256
 
257
        in_use = 0 ;
258
    end
259
    endtask // wbm_read
260
 
261
    task wbm_write ;
262
        input  `WRITE_STIM_TYPE input_data ;
263
        inout  `WRITE_RETURN_TYPE   output_data ;
264
        reg    `WB_ADDR_TYPE        address ;
265
        reg    `WB_DATA_TYPE        data ;
266
        reg    `WB_SEL_TYPE         sel ;
267
        reg    `WB_TAG_TYPE         tag ;
268
        integer                     num_of_cyc ;
269
    begin:main
270
        output_data`TB_ERROR_BIT = 1'b0 ;
271
 
272
        // check if task was called before previous call to read or write finished
273
        if ( in_use === 1 )
274
        begin
275
            $display("*E, wbm_write routine re-entered or called concurently with read routine! Time %t ", $time) ;
276
            output_data`TB_ERROR_BIT = 1'b1 ;
277
            disable main ;
278
        end
279
 
280
        if ( cycle_in_progress !== 1 )
281
        begin
282
            $display("*E, wbm_write routine called without start_cycle routine being called first! Time %t ", $time) ;
283
            output_data`TB_ERROR_BIT = 1'b1 ;
284
            disable main ;
285
        end
286
 
287
        if ( we !== 1 )
288
        begin
289
            $display("*E, wbm_write routine after read cycle was started! Time %t ", $time) ;
290
            output_data`TB_ERROR_BIT = 1'b1 ;
291
            disable main ;
292
        end
293
 
294
        // this branch contains timing controls - claim the use of WISHBONE
295
        in_use = 1 ;
296
 
297
        num_of_cyc = `WAIT_FOR_RESPONSE ;
298
 
299
        ADR_O      <= #(Tp - `Tsetup) input_data`WRITE_ADDRESS ;
300
        DAT_O      <= #(Tp - `Tsetup) input_data`WRITE_DATA ;
301
        SEL_O      <= #(Tp - `Tsetup) input_data`WRITE_SEL ;
302
        TAG_O      <= #(Tp - `Tsetup) input_data`WRITE_TAG_STIM ;
303
 
304
        STB_O      <= #(Tp - `Tsetup) 1'b1 ;
305
 
306
        output_data`CYC_ACK = 0 ;
307
        output_data`CYC_RTY = 0 ;
308
        output_data`CYC_ERR = 0 ;
309
 
310
        @(posedge CLK_I) ;
311
        output_data`CYC_ACK = ACK_I ;
312
        output_data`CYC_RTY = RTY_I ;
313
        output_data`CYC_ERR = ERR_I ;
314
 
315
        while ( (num_of_cyc > 0) && (output_data`CYC_RESPONSE === 0) )
316
        begin
317
            @(posedge CLK_I) ;
318
            output_data`CYC_ACK = ACK_I ;
319
            output_data`CYC_RTY = RTY_I ;
320
            output_data`CYC_ERR = ERR_I ;
321
            num_of_cyc = num_of_cyc - 1 ;
322
        end
323
 
324
        output_data`WRITE_TAG_RET = TAG_I ;
325
        if ( output_data`CYC_RESPONSE === 0 )
326
        begin
327
            $display("*W, Terminating write cycle because no response was received in %d cycles! Time %t ", `WAIT_FOR_RESPONSE, $time) ;
328
        end
329
 
330
        if ( output_data`CYC_ACK === 1 && output_data`CYC_RTY === 0 && output_data`CYC_ERR === 0 )
331
            output_data`CYC_ACTUAL_TRANSFER = output_data`CYC_ACTUAL_TRANSFER + 1 ;
332
 
333
        ADR_O <= #`Thold {`WB_ADDR_WIDTH{1'bx}} ;
334
        DAT_O <= #`Thold {`WB_DATA_WIDTH{1'bx}} ;
335
        SEL_O <= #`Thold {`WB_SEL_WIDTH{1'bx}} ;
336
        TAG_O <= #`Thold {`WB_TAG_WIDTH{1'bx}} ;
337
 
338
        STB_O <= #`Thold 1'b0 ;
339
 
340
        in_use = 0 ;
341
    end
342
    endtask //wbm_write
343
 
344
    initial
345
    begin
346
        Tp = 1 / `WB_FREQ ;
347
        in_use = 0 ;
348
        cycle_in_progress = 0 ;
349
        cab = 0 ;
350
        ADR_O <= {`WB_ADDR_WIDTH{1'bx}} ;
351
        DAT_O <= {`WB_DATA_WIDTH{1'bx}} ;
352
        SEL_O <= {`WB_SEL_WIDTH{1'bx}} ;
353
        TAG_O <= {`WB_TAG_WIDTH{1'bx}} ;
354
        CYC_O <= 1'b0 ;
355
        STB_O <= 1'b0 ;
356
        CAB_O <= 1'b0 ;
357
        WE_O  <= 1'b0 ;
358
        if ( `Tsetup > Tp || `Thold >= Tp )
359
        begin
360
            $display("Either Tsetup or Thold values for WISHBONE BFMs are too large!") ;
361
            $stop ;
362
        end
363
    end
364
 
365
endmodule

powered by: WebSVN 2.1.0

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