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_slave_behavioral.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_slave_behavioral.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
////      - Tadej Markovic, tadej@opencores.org                   ////
10
////                                                              ////
11
////  All additional information is available in the README.txt   ////
12
////  file.                                                       ////
13
////                                                              ////
14
////                                                              ////
15
//////////////////////////////////////////////////////////////////////
16
////                                                              ////
17
//// Copyright (C) 2002 Tadej Markovic, tadej@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.2  2002/09/13 12:29:14  mohor
46
// Headers changed.
47
//
48
// Revision 1.1  2002/09/13 11:57:21  mohor
49
// New testbench. Thanks to Tadej M - "The Spammer".
50
//
51
// Revision 1.2  2002/03/06 09:10:56  mihad
52
// Added missing include statements
53
//
54
// Revision 1.1  2002/02/01 13:39:43  mihad
55
// Initial testbench import. Still under development
56
//
57
//
58
 
59
`include "wb_model_defines.h"
60
module WB_SLAVE_BEHAVIORAL
61
(
62
        CLK_I,
63
        RST_I,
64
        ACK_O,
65
        ADR_I,
66
        CYC_I,
67
        DAT_O,
68
        DAT_I,
69
        ERR_O,
70
        RTY_O,
71
        SEL_I,
72
        STB_I,
73
        WE_I,
74
        CAB_I
75
);
76
 
77
/*------------------------------------------------------------------------------------------------------
78
WISHBONE signals
79
------------------------------------------------------------------------------------------------------*/
80
input                   CLK_I;
81
input                   RST_I;
82
output                  ACK_O;
83
input   `WB_ADDR_TYPE   ADR_I;
84
input                   CYC_I;
85
output  `WB_DATA_TYPE   DAT_O;
86
input   `WB_DATA_TYPE   DAT_I;
87
output                  ERR_O;
88
output                  RTY_O;
89
input   `WB_SEL_TYPE    SEL_I;
90
input                   STB_I;
91
input                   WE_I;
92
input                   CAB_I;
93
 
94
reg     `WB_DATA_TYPE   DAT_O;
95
 
96
/*------------------------------------------------------------------------------------------------------
97
Asynchronous dual-port RAM signals for storing and fetching the data
98
------------------------------------------------------------------------------------------------------*/
99
//reg     `WB_DATA_TYPE wb_memory [0:16777215]; // WB memory - 24 addresses connected - 2 LSB not used
100
reg     `WB_DATA_TYPE wb_memory [0:1048575]; // WB memory - 20 addresses connected - 2 LSB not used
101
reg     `WB_DATA_TYPE mem_wr_data_out;
102
reg     `WB_DATA_TYPE mem_rd_data_in;
103
 
104
initial $readmemh("../bin/wb_memory.txt",wb_memory);
105
 
106
integer k;
107
initial begin
108
        $display("Contents of Mem after reading data file:");
109
        for (k=0; k<10; k=k+1) $display("%d:%h",k,wb_memory[k]);
110
end
111
 
112
 
113
 
114
/*------------------------------------------------------------------------------------------------------
115
Maximum values for WAIT and RETRY counters and which response !!!
116
------------------------------------------------------------------------------------------------------*/
117
reg     [2:0]  a_e_r_resp; // tells with which cycle_termination_signal must wb_slave respond !
118
reg     [3:0]  wait_cyc;
119
reg     [7:0]  max_retry;
120
 
121
// assign registers to default state while in reset
122
always@(RST_I)
123
begin
124
  if (RST_I)
125
  begin
126
    a_e_r_resp <= 3'b100; // do not respond
127
    wait_cyc   <= 4'b0; // no wait cycles
128
    max_retry  <= 8'h0; // no retries
129
  end
130
end //reset
131
 
132
task cycle_response;
133
  input [2:0]  ack_err_rty_resp; // acknowledge, error or retry response input flags
134
  input [3:0]  wait_cycles; // if wait cycles before each data termination cycle (ack, err or rty)
135
  input [7:0]  retry_cycles; // noumber of retry cycles before acknowledge cycle
136
begin
137
  // assign values
138
  a_e_r_resp <= #1 ack_err_rty_resp;
139
  wait_cyc   <= #1 wait_cycles;
140
  max_retry  <= #1 retry_cycles;
141
end
142
endtask // cycle_response
143
 
144
/*------------------------------------------------------------------------------------------------------
145
Tasks for writing and reading to and from memory !!!
146
------------------------------------------------------------------------------------------------------*/
147
reg    `WB_ADDR_TYPE task_wr_adr_i;
148
reg    `WB_ADDR_TYPE task_rd_adr_i;
149
reg    `WB_DATA_TYPE task_dat_i;
150
reg    `WB_DATA_TYPE task_dat_o;
151
reg    `WB_SEL_TYPE  task_sel_i;
152
reg                  task_wr_data;
153
reg                  task_data_written;
154
reg    `WB_DATA_TYPE task_mem_wr_data;
155
 
156
// write to memory
157
task wr_mem;
158
  input  `WB_ADDR_TYPE adr_i;
159
  input  `WB_DATA_TYPE dat_i;
160
  input  `WB_SEL_TYPE  sel_i;
161
begin
162
  task_data_written = 0;
163
  task_wr_adr_i = adr_i;
164
  task_dat_i = dat_i;
165
  task_sel_i = sel_i;
166
  task_wr_data = 1;
167
  wait(task_data_written);
168
  task_wr_data = 0;
169
end
170
endtask
171
 
172
// read from memory
173
task rd_mem;
174
  input  `WB_ADDR_TYPE adr_i;
175
  output `WB_DATA_TYPE dat_o;
176
  input  `WB_SEL_TYPE  sel_i;
177
begin
178
  task_rd_adr_i = adr_i;
179
  task_sel_i = sel_i;
180
  #1;
181
  dat_o = task_dat_o;
182
end
183
endtask
184
 
185
/*------------------------------------------------------------------------------------------------------
186
Internal signals and logic
187
------------------------------------------------------------------------------------------------------*/
188
reg            calc_ack;
189
reg            calc_err;
190
reg            calc_rty;
191
 
192
reg     [7:0]  retry_cnt;
193
reg     [7:0]  retry_num;
194
reg            retry_expired;
195
 
196
// Retry counter
197
always@(posedge RST_I or posedge CLK_I)
198
begin
199
  if (RST_I)
200
    retry_cnt <= #1 8'h00;
201
  else
202
  begin
203
    if (calc_ack || calc_err)
204
      retry_cnt <= #1 8'h00;
205
    else if (calc_rty)
206
      retry_cnt <= #1 retry_num;
207
  end
208
end
209
 
210
always@(retry_cnt or max_retry)
211
begin
212
  if (retry_cnt < max_retry)
213
  begin
214
    retry_num = retry_cnt + 1'b1;
215
    retry_expired = 1'b0;
216
  end
217
  else
218
  begin
219
    retry_num = retry_cnt;
220
    retry_expired = 1'b1;
221
  end
222
end
223
 
224
reg     [3:0]  wait_cnt;
225
reg     [3:0]  wait_num;
226
reg            wait_expired;
227
 
228
// Wait counter
229
always@(posedge RST_I or posedge CLK_I)
230
begin
231
  if (RST_I)
232
    wait_cnt <= #1 4'h0;
233
  else
234
  begin
235
    if (wait_expired || ~STB_I)
236
      wait_cnt <= #1 4'h0;
237
    else
238
      wait_cnt <= #1 wait_num;
239
  end
240
end
241
 
242
always@(wait_cnt or wait_cyc or STB_I or a_e_r_resp or retry_expired)
243
begin
244
  if ((wait_cyc > 0) && (STB_I))
245
  begin
246
    if (wait_cnt < wait_cyc) // 4'h2)
247
    begin
248
      wait_num = wait_cnt + 1'b1;
249
      wait_expired = 1'b0;
250
      calc_ack = 1'b0;
251
      calc_err = 1'b0;
252
      calc_rty = 1'b0;
253
    end
254
    else
255
    begin
256
      wait_num = wait_cnt;
257
      wait_expired = 1'b1;
258
      if (a_e_r_resp == 3'b100)
259
      begin
260
        calc_ack = 1'b1;
261
        calc_err = 1'b0;
262
        calc_rty = 1'b0;
263
      end
264
      else
265
      if (a_e_r_resp == 3'b010)
266
      begin
267
        calc_ack = 1'b0;
268
        calc_err = 1'b1;
269
        calc_rty = 1'b0;
270
      end
271
      else
272
      if (a_e_r_resp == 3'b001)
273
      begin
274
        calc_err = 1'b0;
275
        if (retry_expired)
276
        begin
277
          calc_ack = 1'b1;
278
          calc_rty = 1'b0;
279
        end
280
        else
281
        begin
282
          calc_ack = 1'b0;
283
          calc_rty = 1'b1;
284
        end
285
      end
286
      else
287
      begin
288
        calc_ack = 1'b0;
289
        calc_err = 1'b0;
290
        calc_rty = 1'b0;
291
      end
292
    end
293
  end
294
  else
295
  if ((wait_cyc == 0) && (STB_I))
296
  begin
297
    wait_num = 2'h0;
298
    wait_expired = 1'b1;
299
    if (a_e_r_resp == 3'b100)
300
    begin
301
      calc_ack = 1'b1;
302
      calc_err = 1'b0;
303
      calc_rty = 1'b0;
304
    end
305
    else if (a_e_r_resp == 3'b010)
306
    begin
307
      calc_ack = 1'b0;
308
      calc_err = 1'b1;
309
      calc_rty = 1'b0;
310
    end
311
    else if (a_e_r_resp == 3'b001)
312
    begin
313
      calc_err = 1'b0;
314
      if (retry_expired)
315
      begin
316
        calc_ack = 1'b1;
317
        calc_rty = 1'b0;
318
      end
319
      else
320
      begin
321
        calc_ack = 1'b0;
322
        calc_rty = 1'b1;
323
      end
324
    end
325
    else
326
    begin
327
      calc_ack = 1'b0;
328
      calc_err = 1'b0;
329
      calc_rty = 1'b0;
330
    end
331
  end
332
  else
333
  begin
334
    wait_num = 2'h0;
335
    wait_expired = 1'b0;
336
    calc_ack = 1'b0;
337
    calc_err = 1'b0;
338
    calc_rty = 1'b0;
339
  end
340
end
341
 
342
wire rd_sel = (CYC_I && STB_I && ~WE_I);
343
wire wr_sel = (CYC_I && STB_I && WE_I);
344
 
345
// Generate cycle termination signals
346
assign ACK_O = calc_ack && STB_I;
347
assign ERR_O = calc_err && STB_I;
348
assign RTY_O = calc_rty && STB_I;
349
 
350
// Assign address to asynchronous memory
351
always@(RST_I or ADR_I)
352
begin
353
  if (RST_I) // this is added because at start of test bench we need address change in order to get data!
354
  begin
355
    #1 mem_rd_data_in = `WB_DATA_WIDTH'hxxxx_xxxx;
356
  end
357
  else
358
  begin
359
//    #1 mem_rd_data_in = wb_memory[ADR_I[25:2]];
360
    #1 mem_rd_data_in = wb_memory[ADR_I[21:2]];
361
  end
362
end
363
 
364
// Data input/output interface
365
always@(rd_sel or mem_rd_data_in or RST_I)
366
begin
367
  if (RST_I)
368
    DAT_O <=#1 `WB_DATA_WIDTH'hxxxx_xxxx;       // assign outputs to unknown state while in reset
369
  else if (rd_sel)
370
    DAT_O <=#1 mem_rd_data_in;
371
  else
372
    DAT_O <=#1 `WB_DATA_WIDTH'hxxxx_xxxx;
373
end
374
 
375
 
376
always@(RST_I or task_rd_adr_i)
377
begin
378
  if (RST_I)
379
    task_dat_o = `WB_DATA_WIDTH'hxxxx_xxxx;
380
  else
381
    task_dat_o = wb_memory[task_rd_adr_i[21:2]];
382
end
383
always@(CLK_I or wr_sel or task_wr_data or ADR_I or task_wr_adr_i or
384
        mem_wr_data_out or DAT_I or task_mem_wr_data or task_dat_i or
385
        SEL_I or task_sel_i)
386
begin
387
  if (task_wr_data)
388
  begin
389
    task_mem_wr_data = wb_memory[task_wr_adr_i[21:2]];
390
 
391
    if (task_sel_i[3])
392
      task_mem_wr_data[31:24] = task_dat_i[31:24];
393
    if (task_sel_i[2])
394
      task_mem_wr_data[23:16] = task_dat_i[23:16];
395
    if (task_sel_i[1])
396
      task_mem_wr_data[15: 8] = task_dat_i[15: 8];
397
    if (task_sel_i[0])
398
      task_mem_wr_data[ 7: 0] = task_dat_i[ 7: 0];
399
 
400
    wb_memory[task_wr_adr_i[21:2]] = task_mem_wr_data; // write data
401
    task_data_written = 1;
402
  end
403
  else if (wr_sel && ~CLK_I)
404
  begin
405
//    mem_wr_data_out = wb_memory[ADR_I[25:2]]; // if no SEL_I is active, old value will be written
406
    mem_wr_data_out = wb_memory[ADR_I[21:2]]; // if no SEL_I is active, old value will be written
407
 
408
    if (SEL_I[3])
409
      mem_wr_data_out[31:24] = DAT_I[31:24];
410
    if (SEL_I[2])
411
      mem_wr_data_out[23:16] = DAT_I[23:16];
412
    if (SEL_I[1])
413
      mem_wr_data_out[15: 8] = DAT_I[15: 8];
414
    if (SEL_I[0])
415
      mem_wr_data_out[ 7: 0] = DAT_I[ 7: 0];
416
 
417
//    wb_memory[ADR_I[25:2]]  <= mem_wr_data_out; // write data
418
    wb_memory[ADR_I[21:2]]  = mem_wr_data_out; // write data
419
  end
420
end
421
 
422
endmodule

powered by: WebSVN 2.1.0

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