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

Subversion Repositories pci

[/] [pci/] [tags/] [rel_9/] [bench/] [verilog/] [wb_slave_behavioral.v] - Blame information for rev 92

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 15 mihad
//////////////////////////////////////////////////////////////////////
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 92 mihad
// Revision 1.3  2002/10/11 10:08:58  mihad
46
// Added additional testcase and changed rst name in BIST to trst
47
//
48 63 mihad
// Revision 1.2  2002/03/06 09:10:56  mihad
49
// Added missing include statements
50
//
51 34 mihad
// Revision 1.1  2002/02/01 13:39:43  mihad
52
// Initial testbench import. Still under development
53 15 mihad
//
54 34 mihad
//
55 15 mihad
 
56
`include "pci_testbench_defines.v"
57
`include "timescale.v"
58 34 mihad
`include "pci_constants.v"
59 63 mihad
 
60 15 mihad
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 63 mihad
/*------------------------------------------------------------------------------------------------------
78 15 mihad
WISHBONE signals
79 63 mihad
------------------------------------------------------------------------------------------------------*/
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 15 mihad
 
94 63 mihad
reg     `WB_DATA_TYPE   DAT_O;
95 15 mihad
 
96 63 mihad
/*------------------------------------------------------------------------------------------------------
97 15 mihad
Asynchronous dual-port RAM signals for storing and fetching the data
98 63 mihad
------------------------------------------------------------------------------------------------------*/
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 15 mihad
 
104 63 mihad
/*------------------------------------------------------------------------------------------------------
105 15 mihad
Maximum values for WAIT and RETRY counters and which response !!!
106 63 mihad
------------------------------------------------------------------------------------------------------*/
107
reg     [2:0]  a_e_r_resp; // tells with which cycle_termination_signal must wb_slave respond !
108
reg     [3:0]  wait_cyc;
109
reg     [7:0]  max_retry;
110 15 mihad
 
111
// assign registers to default state while in reset
112
always@(RST_I)
113
begin
114 63 mihad
  if (RST_I)
115
  begin
116
    a_e_r_resp <= 3'b000; // do not respond
117
    wait_cyc   <= 4'b0; // no wait cycles
118
    max_retry  <= 8'h0; // no retries
119
  end
120 15 mihad
end //reset
121
 
122 63 mihad
task cycle_response;
123
  input [2:0]  ack_err_rty_resp; // acknowledge, error or retry response input flags
124
  input [3:0]  wait_cycles; // if wait cycles before each data termination cycle (ack, err or rty)
125
  input [7:0]  retry_cycles; // noumber of retry cycles before acknowledge cycle
126 15 mihad
begin
127 63 mihad
  // assign values
128
  a_e_r_resp <= #1 ack_err_rty_resp;
129
  wait_cyc   <= #1 wait_cycles;
130
  max_retry  <= #1 retry_cycles;
131 15 mihad
end
132
endtask // cycle_response
133
 
134 63 mihad
/*------------------------------------------------------------------------------------------------------
135
Tasks for writing and reading to and from memory !!!
136
------------------------------------------------------------------------------------------------------*/
137
reg    `WB_ADDR_TYPE task_wr_adr_i;
138
reg    `WB_ADDR_TYPE task_rd_adr_i;
139
reg    `WB_DATA_TYPE task_dat_i;
140
reg    `WB_DATA_TYPE task_dat_o;
141
reg    `WB_SEL_TYPE  task_sel_i;
142
reg                  task_wr_data;
143
reg                  task_data_written;
144
reg    `WB_DATA_TYPE task_mem_wr_data;
145 15 mihad
 
146 63 mihad
// write to memory
147
task wr_mem;
148
    input   `WB_ADDR_TYPE adr_i;
149
    input   `WB_DATA_TYPE dat_i;
150
    input   `WB_SEL_TYPE  sel_i;
151
    integer current_byte ;
152
    integer current_bit ;
153
begin
154
    /*
155
    task_data_written = 0;
156
    task_wr_adr_i = adr_i;
157
    task_dat_i = dat_i;
158
    task_sel_i = sel_i;
159
    task_wr_data = 1;
160
    wait(task_data_written);
161
    task_wr_data = 0;
162
    */
163
 
164
    task_mem_wr_data = wb_memory[adr_i[21:2]];
165 15 mihad
 
166 63 mihad
    for (current_byte = 0 ; current_byte < `WB_DATA_WIDTH / 8 ; current_byte = current_byte + 1'b1)
167
    begin
168
        // check sel_i for every byte
169
        if (sel_i[current_byte])
170
        begin
171
            // have to write a bit at a time, because dynamic range bouds are not allowed
172
            for (current_bit = 0 ; current_bit < 8 ; current_bit = current_bit + 1'b1)
173
                task_mem_wr_data[current_byte * 8 + current_bit] = dat_i[current_byte * 8 + current_bit] ;
174
        end
175
    end
176
    /*if (sel_i[3])
177
      task_mem_wr_data[31:24] = dat_i[31:24];
178
    if (sel_i[2])
179
      task_mem_wr_data[23:16] = dat_i[23:16];
180
    if (sel_i[1])
181
      task_mem_wr_data[15: 8] = dat_i[15: 8];
182
    if (sel_i[0])
183
      task_mem_wr_data[ 7: 0] = dat_i[ 7: 0];
184
    */
185
    wb_memory[adr_i[21:2]] = task_mem_wr_data; // write data
186
end
187
endtask
188
 
189
// read from memory
190
task rd_mem;
191
  input  `WB_ADDR_TYPE adr_i;
192
  output `WB_DATA_TYPE dat_o;
193
  input  `WB_SEL_TYPE  sel_i;
194 15 mihad
begin
195 63 mihad
  task_rd_adr_i = adr_i;
196
  task_sel_i = sel_i;
197
  #1;
198
  dat_o = task_dat_o;
199 15 mihad
end
200 63 mihad
endtask
201 15 mihad
 
202 63 mihad
/*------------------------------------------------------------------------------------------------------
203
Internal signals and logic
204
------------------------------------------------------------------------------------------------------*/
205
reg            calc_ack;
206
reg            calc_err;
207
reg            calc_rty;
208
 
209
reg     [7:0]  retry_cnt;
210
reg     [7:0]  retry_num;
211
reg            retry_expired;
212
 
213 15 mihad
// Retry counter
214 63 mihad
always@(posedge RST_I or posedge CLK_I)
215 15 mihad
begin
216 63 mihad
  if (RST_I)
217
    retry_cnt <= #1 8'h00;
218
  else
219
  begin
220
    if (calc_ack || calc_err)
221
      retry_cnt <= #1 8'h00;
222
    else if (calc_rty)
223
      retry_cnt <= #1 retry_num;
224
  end
225 15 mihad
end
226 63 mihad
 
227 15 mihad
always@(retry_cnt or max_retry)
228
begin
229 63 mihad
  if (retry_cnt < max_retry)
230
  begin
231
    retry_num = retry_cnt + 1'b1;
232
    retry_expired = 1'b0;
233
  end
234
  else
235
  begin
236
    retry_num = retry_cnt;
237 92 mihad
    if (max_retry != 8'h0)
238
        retry_expired = 1'b1;
239 63 mihad
  end
240 15 mihad
end
241
 
242 63 mihad
reg     [3:0]  wait_cnt;
243
reg     [3:0]  wait_num;
244
reg            wait_expired;
245 15 mihad
 
246 63 mihad
// Wait counter
247 15 mihad
always@(posedge RST_I or posedge CLK_I)
248
begin
249 63 mihad
  if (RST_I)
250
    wait_cnt <= #1 4'h0;
251
  else
252
  begin
253
    if (wait_expired || ~STB_I)
254
      wait_cnt <= #1 4'h0;
255
    else
256
      wait_cnt <= #1 wait_num;
257
  end
258 15 mihad
end
259
 
260
always@(wait_cnt or wait_cyc or STB_I or a_e_r_resp or retry_expired)
261
begin
262 63 mihad
  if ((wait_cyc > 0) && (STB_I))
263
  begin
264
    if (wait_cnt < wait_cyc) // 4'h2)
265
    begin
266
      wait_num = wait_cnt + 1'b1;
267
      wait_expired = 1'b0;
268
      calc_ack = 1'b0;
269
      calc_err = 1'b0;
270
      calc_rty = 1'b0;
271
    end
272
    else
273
    begin
274
      wait_num = wait_cnt;
275
      wait_expired = 1'b1;
276
      if (a_e_r_resp == 3'b100)
277
      begin
278
        calc_ack = 1'b1;
279
        calc_err = 1'b0;
280
        calc_rty = 1'b0;
281
      end
282
      else
283
      if (a_e_r_resp == 3'b010)
284
      begin
285
        calc_ack = 1'b0;
286
        calc_err = 1'b1;
287
        calc_rty = 1'b0;
288
      end
289
      else
290
      if (a_e_r_resp == 3'b001)
291
      begin
292
        calc_err = 1'b0;
293
        if (retry_expired)
294
        begin
295
          calc_ack = 1'b1;
296
          calc_rty = 1'b0;
297
        end
298
        else
299
        begin
300
          calc_ack = 1'b0;
301
          calc_rty = 1'b1;
302
        end
303
      end
304
      else
305
      begin
306
        calc_ack = 1'b0;
307
        calc_err = 1'b0;
308
        calc_rty = 1'b0;
309
      end
310
    end
311
  end
312
  else
313
  if ((wait_cyc == 0) && (STB_I))
314
  begin
315
    wait_num = 2'h0;
316
    wait_expired = 1'b1;
317
    if (a_e_r_resp == 3'b100)
318
    begin
319
      calc_ack = 1'b1;
320
      calc_err = 1'b0;
321
      calc_rty = 1'b0;
322
    end
323
    else if (a_e_r_resp == 3'b010)
324
    begin
325
      calc_ack = 1'b0;
326
      calc_err = 1'b1;
327
      calc_rty = 1'b0;
328
    end
329
    else if (a_e_r_resp == 3'b001)
330
    begin
331
      calc_err = 1'b0;
332
      if (retry_expired)
333
      begin
334
        calc_ack = 1'b1;
335
        calc_rty = 1'b0;
336
      end
337
      else
338
      begin
339
        calc_ack = 1'b0;
340
        calc_rty = 1'b1;
341
      end
342
    end
343
    else
344
    begin
345
      calc_ack = 1'b0;
346
      calc_err = 1'b0;
347
      calc_rty = 1'b0;
348
    end
349
  end
350
  else
351
  begin
352
    wait_num = 2'h0;
353
    wait_expired = 1'b0;
354
    calc_ack = 1'b0;
355
    calc_err = 1'b0;
356
    calc_rty = 1'b0;
357
  end
358 15 mihad
end
359
 
360 63 mihad
wire rd_sel = (CYC_I && STB_I && ~WE_I);
361
wire wr_sel = (CYC_I && STB_I && WE_I);
362 15 mihad
 
363
// Generate cycle termination signals
364 63 mihad
assign ACK_O = calc_ack && STB_I && CYC_I;
365
assign ERR_O = calc_err && STB_I && CYC_I;
366
assign RTY_O = calc_rty && STB_I && CYC_I;
367 15 mihad
 
368
// Assign address to asynchronous memory
369 63 mihad
always@(RST_I or ADR_I)
370 15 mihad
begin
371 63 mihad
  if (RST_I) // this is added because at start of test bench we need address change in order to get data!
372
  begin
373
    #1 mem_rd_data_in = `WB_DATA_WIDTH'hxxxx_xxxx;
374
  end
375
  else
376
  begin
377
//    #1 mem_rd_data_in = wb_memory[ADR_I[25:2]];
378
    #1 mem_rd_data_in = wb_memory[ADR_I[21:2]];
379
  end
380 15 mihad
end
381
 
382 63 mihad
/*// Data input/output interface
383
always@(rd_sel or mem_rd_data_in or RST_I)
384 15 mihad
begin
385 63 mihad
  if (RST_I)
386
    DAT_O <=#1 `WB_DATA_WIDTH'hxxxx_xxxx;       // assign outputs to unknown state while in reset
387
  else if (rd_sel)
388
    DAT_O <=#1 mem_rd_data_in;
389
  else
390
    DAT_O <=#1 `WB_DATA_WIDTH'hxxxx_xxxx;
391
end
392
*/
393 92 mihad
 
394
wire `WB_DATA_TYPE current_memory_location = wb_memory[ADR_I[21:2]] ;
395 63 mihad
always@
396
(
397
    RST_I or
398
    ACK_O or
399
    WE_I  or
400 92 mihad
    current_memory_location
401 63 mihad
)
402
begin
403
    if ((ACK_O === 1'b1) && (RST_I === 1'b0) && (WE_I === 1'b0))
404 92 mihad
        DAT_O <= #1 current_memory_location ;
405 63 mihad
    else
406
        DAT_O <= #1 {`WB_DATA_WIDTH{1'bx}} ;
407
end
408 15 mihad
 
409 63 mihad
always@(RST_I or task_rd_adr_i)
410 15 mihad
begin
411 63 mihad
  if (RST_I)
412
    task_dat_o = `WB_DATA_WIDTH'hxxxx_xxxx;
413
  else
414
    task_dat_o = wb_memory[task_rd_adr_i[21:2]];
415 15 mihad
end
416 63 mihad
 
417
/*always@(CLK_I or wr_sel or task_wr_data or ADR_I or task_wr_adr_i or
418
        mem_wr_data_out or DAT_I or task_dat_i or
419
        SEL_I or task_sel_i)
420 15 mihad
begin
421 63 mihad
  if (task_wr_data)
422
  begin
423
    task_mem_wr_data = wb_memory[task_wr_adr_i[21:2]];
424 15 mihad
 
425 63 mihad
    if (task_sel_i[3])
426
      task_mem_wr_data[31:24] = task_dat_i[31:24];
427
    if (task_sel_i[2])
428
      task_mem_wr_data[23:16] = task_dat_i[23:16];
429
    if (task_sel_i[1])
430
      task_mem_wr_data[15: 8] = task_dat_i[15: 8];
431
    if (task_sel_i[0])
432
      task_mem_wr_data[ 7: 0] = task_dat_i[ 7: 0];
433 15 mihad
 
434 63 mihad
    wb_memory[task_wr_adr_i[21:2]] = task_mem_wr_data; // write data
435
    task_data_written = 1;
436
  end
437
  else if (wr_sel && CLK_I)
438
  begin
439
//    mem_wr_data_out = wb_memory[ADR_I[25:2]]; // if no SEL_I is active, old value will be written
440
    mem_wr_data_out = wb_memory[ADR_I[21:2]]; // if no SEL_I is active, old value will be written
441 15 mihad
 
442 63 mihad
    if (SEL_I[3])
443
      mem_wr_data_out[31:24] = DAT_I[31:24];
444
    if (SEL_I[2])
445
      mem_wr_data_out[23:16] = DAT_I[23:16];
446
    if (SEL_I[1])
447
      mem_wr_data_out[15: 8] = DAT_I[15: 8];
448
    if (SEL_I[0])
449
      mem_wr_data_out[ 7: 0] = DAT_I[ 7: 0];
450 15 mihad
 
451 63 mihad
//    wb_memory[ADR_I[25:2]]  <= mem_wr_data_out; // write data
452
    wb_memory[ADR_I[21:2]]      = mem_wr_data_out; // write data
453
  end
454 15 mihad
end
455 63 mihad
*/
456
always@(posedge CLK_I)
457
begin
458
    if (CYC_I && STB_I && WE_I && ACK_O)
459
            wr_mem(ADR_I, DAT_I, SEL_I) ;
460
end
461 15 mihad
 
462
endmodule

powered by: WebSVN 2.1.0

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