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

Subversion Repositories ps2

[/] [ps2/] [tags/] [rel_6/] [bench/] [verilog/] [wb_master32.v] - Blame information for rev 51

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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