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 63

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

powered by: WebSVN 2.1.0

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