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

Subversion Repositories ethmac

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

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

powered by: WebSVN 2.1.0

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