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

Subversion Repositories ethmac

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

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

powered by: WebSVN 2.1.0

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