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

powered by: WebSVN 2.1.0

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