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

Subversion Repositories sd_card_controller

[/] [sd_card_controller/] [trunk/] [bench/] [verilog/] [wb_master32.v] - Blame information for rev 3

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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