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

Subversion Repositories ethmac

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

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

powered by: WebSVN 2.1.0

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