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

Subversion Repositories pci

[/] [pci/] [tags/] [rel_7/] [bench/] [verilog/] [wb_slave_behavioral.v] - Blame information for rev 154

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

powered by: WebSVN 2.1.0

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