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

Subversion Repositories sdcard_mass_storage_controller

[/] [sdcard_mass_storage_controller/] [trunk/] [bench/] [sdc_dma/] [verilog/] [wb_slave_behavioral.v] - Blame information for rev 127

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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