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

Subversion Repositories ethmac

[/] [ethmac/] [trunk/] [bench/] [verilog/] [wb_slave_behavioral.v] - Blame information for rev 346

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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