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

Subversion Repositories ethmac

[/] [ethmac/] [trunk/] [bench/] [verilog/] [wb_master32.v] - Blame information for rev 359

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

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

powered by: WebSVN 2.1.0

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