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

Subversion Repositories pci_mini

[/] [pci_mini/] [trunk/] [pci_mini-34.v] - Blame information for rev 7

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 7 ocadmin
// *************************************************************** //
2
//                                                                                                                                 //
3
//                      PCI_TARGET-Wishbone_MASTER INTERFACE MODULE     (PCI-mini) //
4
//                                                                                      v3.4                           //
5
//                                                                                                                             //
6
//   The original PCI module is from:   Ben Jackson                //
7
//                              http://www.ben.com/minipci/verilog.php             //
8
//                                                                                                                         //
9
//        Redesigned for wishbone : Istvan Nagy, buenos@freemail.hu        //
10
//                                                                                                         //
11
//                                                                                                                     //
12
//      DOWNLOADED FROM OPENCORES. (License = GPL)                 //
13
//                                                                 //
14
// *************************************************************** //
15
 
16
// The core implements a 16MB relocable memory image. Relocable on the
17
//   wb bus. the wb address = 4M*wb_baseaddr_reg + PCI_addr[23:2]
18
//   Only Dword aligned Dword accesses allowed on the PCI. This way
19
//   we can access to the 4GB wb-space through a 16MB PCI-window.
20
//   The addressing on the wb-bus, is Dword addressing, while on the
21
//   PCI bus, the addressing is byte addressing. A(pci)=A(wb)*4
22
//   The PCI address is increasing by 4, and we get 4 bytes. The wb
23
//   address is increasing by 1, and we get 1 Dword (= 4 bytes also).
24
//   The wb_baseaddr_reg is the wb image relocation register, can be
25
//   accessed at 50h address in the PCI configuration space.
26
//   Other bridge status and command is at the 54h and 58h addresses.
27
//   if access fails with timeout, then the address will be in the 
28
//   wb address will be stored in the failed_addr_reg at 5Ch address.
29
//
30
// Wishbone compatibility:
31
//  Wishbone signals: wb_address, wb_dat_o, wb_dat_i, wb_sel_o, wb_cyc_o, 
32
//  wb_stb_o, wb_wr_o, wb_reset_o, wb_clk_o, wb_ack_i.
33
//  Not implemented wb signals: error, lock, retry, tag-signals.
34
//  The peripheral has to response with ack in 16 clk cycles.
35
//  The core has wishbone clk and reset outputs, just like a Syscon module.
36
//  The core generates single reads/writes. These are made of 4 phases, so
37
//  dont write new data, until internal data movement finishes: about 300...500ns
38
//
39
// PCI compatibility: 
40
// Only single DWORD reads/writes are supported. between them, the software has 
41
//   to wait 300...500nsec, to prevent data corrupting. STOP signaling is not 
42
//   implemented, so target terminations also not. 
43
//   Single Byte access is NOT supported! It may cause corrupt data.
44
//   The core uses INTA interrupt signal. There are some special PCI config
45
//   registers, from 50h...60h config-space addresses.
46
//   PCI-parity: it generates parity, but doesnt check incoming parity.
47
//   Because of the PC chipset, if you read a value and write it back,
48
//   the chipset will not write anything, because it can see the data is not 
49
//   changed. This is important at some peripherals, where you write, to control.
50
// Device specific PCI config header registers:
51
//   name:                                      addr:           function:
52
//   wb_baseaddr_reg;   50h             A(wb)=(A(pci)-BAR0)/4 + wb_baseaddr_reg. RESET TO 0
53
//   user_status_reg;   54h             not used yet
54
//   user_command_reg;  58h             not used yet
55
//   failed_addr_reg;   5Ch             address, when timeout occurs on the wb bus.
56
//
57
// Local bus arbitration: 
58
// This is not really wishbone compatible, but needed for the PCI.
59
//  The method is: "brute force". it means if the PCI interface wants to
60
//  be mastering on the local (wishbone) bus, then it will be mastering,
61
//  so, the other master(s) must stop anything immediately. The req signal
62
//  goes high when there is an Address hit on teh PCI bus. so the other
63
//  master has few clk cycles to finish.
64
// Restrictions: the peripherals have to be fast: If the other master
65
//  starts a transaction before req goes high, the ack has to arrive before 
66
//  the PCI interface starts its own transaction. (max 4clk ACK delay)
67
//  The other master or the bus unit must sense the req, and give bus
68
//  mastering to the PCI-IF immediatelly, not just when the other master
69
//  finished everything, like at normal arbitration schemes.
70
//
71
// Buffering:
72
//  There is a single Dword buffering only.
73
//
74
// The led_out interface: 
75
//  only for system-debug: we can write to the LEDs, at any address. 
76
//  (in the same time there is a wishbone write also)
77
//
78
// Changes since original version: wishbone interface,
79
//  bigger memory-image, parity-generation,
80
//  interrupt handling. Code size is 3x bigger. New registers, 
81
//
82
// Device Compatibility:
83
//  Until v3.3 the code was tested on Xilinx FPGAs (sp2, sp3) with ISE 4.7-9.1 and VIA/AMD chipsets.
84
//  Version 3.4 has modifications to work on Actel/Microsemi ProASIC3 with Sinplify and Intel Atom chipset.
85
//  (v3.4 was not tested on Xilinx FPGAs) To make sure that it runs on the Actel FPGA, we have to use the
86
//  timing constraint SDC file, AND ALSO set the P&R to Timing optimized and "effort"=high.
87
//
88
// *************************************************************** //
89
 
90
 
91
 
92
module pci(reset, pciclk, frame, irdy, trdy, devsel, idsel, ad, cbe, par, stop, inta, serr, perr, led_out, wb_address, wb_dat_o, wb_dat_i, wb_sel_o, wb_cyc_o, wb_stb_o, wb_wr_o, wb_reset_o, wb_clk_o, wb_ack_i, wb_irq, wb_req, wb_gnt, wb_req_other, contr_o);
93
    input reset;
94
    input pciclk;
95
    input frame;
96
    input irdy;
97
    output trdy;
98
    output devsel;
99
    input idsel;
100
    inout [31:0] ad;
101
    input [3:0] cbe;
102
    inout par;
103
    output stop;
104
    output inta;
105
    output serr;
106
    output perr;
107
    output [3:0] led_out;
108
                output [31:0] wb_address;
109
                output [31:0] wb_dat_o;
110
                input [31:0] wb_dat_i;
111
                output [3:0] wb_sel_o;
112
                output wb_cyc_o;
113
                output wb_stb_o;
114
                output wb_wr_o;
115
                output wb_reset_o;
116
                output wb_clk_o;
117
                input wb_ack_i;
118
                input wb_irq;
119
                output wb_req;
120
                input wb_gnt;
121
                input wb_req_other;
122
        output [7:0] contr_o;
123
 
124
 
125
 
126
parameter DEVICE_ID = 16'h9500;
127
parameter VENDOR_ID = 16'h11AA; //      16'h11AA = actel, 
128
parameter DEVICE_CLASS = 24'h118000;    // some examples: 068000=bridge/other, 078000=simple_comm_contr/other, 118000=data_acquisition/other
129
parameter DEVICE_REV = 8'h01;
130
parameter SUBSYSTEM_ID = 16'h0001;      // Card identifier
131
parameter SUBSYSTEM_VENDOR_ID = 16'h13C7; //  13C7 = bluechip technology
132
parameter DEVSEL_TIMING = 2'b00;        // Fast!
133
 
134
reg [2:0] state;
135
reg [31:0] data;
136
 
137
reg [1:0] enable;
138
parameter EN_NONE = 2'b00;
139
parameter EN_RD = 2'b01;
140
parameter EN_WR = 2'b10;
141
parameter EN_TR = 2'b11;
142
 
143
reg memen; // respond to baseaddr?
144
reg [7:0] baseaddr;
145
reg [5:0] address;
146
 
147
reg [9:0] wb_baseaddr_reg; //remap the image on the wishbone bus
148
reg [31:0] wb_address_1;
149
reg [31:0] user_status_reg;
150
reg [31:0] user_command_reg;
151
reg [31:0] failed_addr_reg;
152
reg [31:0] dummy_reg;
153
reg [31:0] pci_read_reg;
154
reg [31:0] pci_write_reg;
155
reg [31:0] wb_read_reg;
156
reg [31:0] wb_write_reg;
157
reg [3:0] pci_read_sel_reg;
158
reg [3:0] pci_write_sel_reg;
159
reg [3:0] wb_read_sel_reg;
160
reg [3:0] wb_write_sel_reg;
161
 
162
assign contr_o = user_command_reg [7:0];
163
 
164
parameter ST_IDLE = 3'b000;
165
parameter ST_BUSY = 3'b010;
166
parameter ST_MEMREAD = 3'b100;
167
parameter ST_MEMWRITE = 3'b101;
168
parameter ST_CFGREAD = 3'b110;
169
parameter ST_CFGWRITE = 3'b111;
170
 
171
parameter MEMREAD = 4'b0110;
172
parameter MEMWRITE = 4'b0111;
173
parameter CFGREAD = 4'b1010;
174
parameter CFGWRITE = 4'b1011;
175
 
176
`define LED
177
`ifdef LED
178
reg [3:0] led;
179
`endif
180
 
181
`undef STATE_DEBUG_LED
182
`ifdef STATE_DEBUG_LED
183
assign led_out = ~state;
184
`else
185
`ifdef LED
186
assign led_out = ~led;
187
`endif
188
`endif
189
 
190
assign ad = (enable == EN_RD) ? data : 32'bZ;
191
 
192
reg [1:0] enable_delayed;
193
  always @(posedge pciclk)
194
    begin enable_delayed <= enable; end
195
 
196
 
197
// TRDY# Generation --------------------------------------------------
198
reg [31:0] wb_address_previous;
199
reg [31:0] wb_address_readonly;
200
reg trdy;
201
//assign trdy = (enable_delayed == EN_NONE) ? 'bZ : (enable == EN_TR ? 1 : 0);
202
   always @(posedge pciclk) //delaying of trdy
203
                        if (enable_delayed == EN_NONE)
204
              trdy <= 'bZ;
205
            else if (enable == EN_TR)
206
              trdy <= 'b1;
207
            else if ((wb_address_previous != wb_address_readonly) && (state == ST_MEMREAD))
208
              trdy <= 'b1;
209
            else
210
              trdy <= 'b0;
211
 
212
//assign trdylocal = (enable_delayed == EN_NONE) ? 'b1 : (enable == EN_TR ? 1 : 0);
213
reg trdylocal;
214
   always @(posedge pciclk) //delaying of trdy
215
                        if (enable_delayed == EN_NONE)
216
              trdylocal <= 'b1;
217
            else if (enable == EN_TR)
218
              trdylocal <= 'b1;
219
            else if ((wb_address_previous != wb_address_readonly) && (state == ST_MEMREAD))
220
              trdylocal <= 'b1;
221
            else
222
              trdylocal <= 'b0;
223
 
224
 
225
// STOP# Generation --------------------------------------------------
226
//auto-generate Retry for read completion transactions, by using STOP# and target-abort:
227
reg stop;
228
   always @(posedge pciclk) //delaying of trdy
229
                        if (enable_delayed == EN_NONE)
230
              stop <= 'bZ;
231
            else if (enable == EN_TR)
232
              stop <= 'b1;
233
            else if ((wb_address_previous != wb_address_readonly) && (state == ST_MEMREAD))
234
              stop <= 'b0;
235
            else
236
              stop <= 'bZ;
237
reg stoplocal;
238
   always @(posedge pciclk) //delaying of trdy
239
                        if (enable_delayed == EN_NONE)
240
              stoplocal <= 'b1;
241
            else if (enable == EN_TR)
242
              stoplocal <= 'b1;
243
            else if ((wb_address_previous != wb_address_readonly) && (state == ST_MEMREAD))
244
              stoplocal <= 'b0;
245
            else
246
              stoplocal <= 'b1;
247
//assign stop = 1'bZ; //if not used
248
 
249
 
250
 
251
 
252
reg devsel;
253
 
254
assign serr = 1'bZ;
255
assign perr = 1'bZ;
256
 
257
 
258
wire cfg_hit = ((cbe == CFGREAD || cbe == CFGWRITE) && idsel && ad[10:8] == 3'b000 && ad[1:0] == 2'b00);
259
wire addr_hit = ((cbe == MEMREAD || cbe == MEMWRITE) && memen && ad[31:24] == {baseaddr});
260
wire hit = cfg_hit | addr_hit;
261
 
262
//count hit for debug purposes. also trigger on it in the logic analyzer:
263
reg [7:0] hitcounter;
264
  always @(posedge pciclk)
265
      if (~reset) begin
266
         hitcounter <= 4'b00000000;
267
      end
268
      else begin
269
         if ((hit=='b1) & (frame == 'b0))  hitcounter <= hitcounter +1;
270
          end
271
 
272
 
273
 
274
 
275
 
276
// Wishbone SYSCON: output signals------------------------------------
277
assign wb_reset_o = ~reset;
278
assign wb_clk_o = pciclk;
279
//reg wb_clk_o;
280
   //always @(posedge clk)
281
                //wb_clk_o = wb_clk_o+ 1;
282
 
283
 
284
// PCI parity generation:---------------------------------------------
285
// during read, the parity on AD, and delayen by one clk.
286
reg par_en;
287
reg par_latched;
288
reg EN_RDd;
289
reg addr_increment;
290
wire data_par = (data[31] ^ data[30] ^ data[29] ^ data[28]) ^
291
                (data[27] ^ data[26] ^ data[25] ^ data[24]) ^
292
                (data[23] ^ data[22] ^ data[21] ^ data[20]) ^
293
                (data[19] ^ data[18] ^ data[17] ^ data[16]) ^
294
                (data[15] ^ data[14] ^ data[13] ^ data[12]) ^
295
                (data[11] ^ data[10] ^ data[9]  ^ data[8])  ^
296
                (data[7]  ^ data[6]  ^ data[5]  ^ data[4])  ^
297
                                          (cbe[3]  ^ cbe[2]  ^ cbe[1]  ^ cbe[0])  ^
298
                (data[3]  ^ data[2]  ^ data[1]  ^ data[0]) ;
299
 
300
   always @(posedge pciclk) //delaying of parity
301
      if ((enable == EN_RD)|(enable == EN_TR)) begin
302
         par_latched = data_par; end
303
      else
304
         begin par_latched = 0; end
305
 
306
   always @(posedge pciclk) //delaying of EN_RD
307
                        EN_RDd = EN_RD;
308
 
309
        //assign par = (enable == EN_RD) ? 0 : 'bZ;
310
        assign par = ((enable == EN_RD)|(enable == EN_RDd)) ? par_latched : 'bZ; //output control
311
 
312
 
313
 
314
// Interrupt handling:--------------------------------------------------------------------
315
reg int_dis;
316
wire int_stat;
317
reg [7:0] int_line;
318
assign inta = ((wb_irq == 1) && (int_dis == 0)) ? 1'b0 : 1'bZ;
319
assign int_stat = wb_irq;
320
 
321
 
322
 
323
// WB bus arbitration:--------------------------------------------------------------------
324
//assign wb_req = mastering;
325
reg arb_start;
326
reg arb_stop;
327
reg wb_req;
328
 
329
   parameter arb_state1 = 2'b00;
330
   parameter arb_state2 = 2'b01;
331
   reg  arb_state = arb_state1;
332
   always@(posedge pciclk) begin
333
      if (wb_reset_o) begin
334
         arb_state <= arb_state1;
335
         wb_req <= 0;
336
      end
337
      else
338
         case (arb_state)
339
            arb_state1 : begin //arbitration is not needed: IDLE
340
               wb_req <= 0;
341
               if (arb_start == 1)
342
                  arb_state <= arb_state2;
343
            end
344
            arb_state2 : begin //arbitration is needed
345
               wb_req <= 1;
346
               if (arb_stop == 1)
347
                  arb_state <= arb_state1;
348
            end
349
            default : begin  // Fault Recovery
350
               arb_state <= arb_state1;
351
               wb_req <= 0;
352
            end
353
         endcase
354
                end
355
 
356
 
357
 
358
// -------------- wishbone state machine --------------------------------------------------
359
//write FIFO buffer:
360
reg [31:0] wb_wr_buf [5:0]; //64 Dwords wb write buffer: wb_wr_buf[index] <= value;
361
reg [3:0] wb_wr_sel_buf [5:0]; //select lines, write buffer: wb_wr_buf[index] <= value;
362
reg [31:0] fifo_start_wb_addr;
363
reg [31:0] fifo_act_wb_addr;
364
reg [5:0] fifo_max_count;
365
reg [5:0] fifo_wb_counter;
366
reg [5:0] fifo_wb_counter_o;
367
reg fifo_flush; //wb output mux control
368
reg fifo_flush_start; //start pulse
369
reg fifo_fill; //disable wb during filling fifo
370
reg [3:0] wbw_timeout_count_new;
371
reg [1:0] wbw_phase;
372
//read FIFO buffer:
373
reg [31:0] wb_rd_buf [5:0]; //64 Dwords wb read buffer: wb_rd_buf[index] <= value;
374
reg [3:0] wb_rd_sel_buf [5:0]; //select lines, write buffer: wb_wr_buf[index] <= value;
375
reg [31:0] fifo_start_wb_addr_rd;
376
reg [31:0] fifo_act_wb_addr_rd;
377
reg [5:0] fifo_max_count_rd;
378
reg [5:0] fifo_wb_counter_rd;
379
reg [5:0] fifo_wb_counter_o_rd;
380
reg fifo_flush_rd; //wb output mux control
381
reg fifo_fill_start_rd; //start pulse
382
reg fifo_fill_rd; //disable wb during filling fifo
383
reg [3:0] wbr_timeout_count_new;
384
reg [1:0] wbr_phase;
385
//
386
reg wb_cyc_o;
387
reg wb_stb_o;
388
reg wb_wr_o;
389
reg [31:0] wb_address;
390
reg [3:0] wb_sel_o;
391
reg [31:0] wb_dat_o;
392
reg machinereset;
393
reg mastering;
394
//assign wb_req = mastering;
395
 
396
 
397
   parameter machine_waiting = 2'b00;
398
   parameter machine_flushing = 2'b01;
399
   parameter machine_read_filling = 2'b11;
400
   reg [1:0] wbwf_state = machine_waiting;
401
 
402
   always@(posedge wb_clk_o)
403
      if (wb_reset_o) begin
404
         wbwf_state <= machine_waiting;
405
                         wbw_phase <= 0;
406
                        wbw_timeout_count_new <= 0;
407
                        fifo_wb_counter_o<=0;
408
                        fifo_flush <= 0;
409
                        wb_cyc_o <= 0;
410
                        wb_stb_o <= 0;
411
                        wb_wr_o <= 0;
412
                         wbr_phase <= 0;
413
                        wbr_timeout_count_new <= 0;
414
                        fifo_wb_counter_o_rd<=0;
415
                        fifo_fill_rd <= 0;
416
                        wb_address[31:0] = 32'b0;
417
                        wb_sel_o = 4'b0;
418
                        wb_dat_o = 32'b0;
419
                        pci_read_reg <= 0;
420
                        mastering <= 0;
421
                        arb_stop <= 0;
422
                        failed_addr_reg <= 0;
423
      end
424
      else
425
         case (wbwf_state)
426
 
427
            machine_waiting : begin //no operation on Wishbone bus **************
428
                                        wbw_phase <= 0;
429
                                        wbw_timeout_count_new <= 0;
430
                                        wbr_phase <= 0;
431
                                        wbr_timeout_count_new <= 0;
432
                                        wb_address[31:0] = 32'b0;
433
                                        wb_cyc_o <= 0;
434
                                        wb_stb_o <= 0;
435
                                        wb_wr_o <= 0;
436
                                        wb_sel_o = 4'b0;
437
                                        wb_dat_o = 32'b0;
438
                                        arb_stop <= 0;
439
               if (fifo_flush_start  == 1)
440
                  begin fifo_flush <= 1; wbwf_state <= machine_flushing; fifo_wb_counter_o<=0; mastering <= 1; end
441
               else if (fifo_fill_start_rd == 1)
442
                  begin fifo_fill_rd <= 1; wbwf_state <= machine_read_filling; fifo_wb_counter_o_rd<=0; mastering <= 1; end
443
            end
444
 
445
            machine_flushing : begin //wr-FIFO flushing: wb write***********************
446
                                        wb_sel_o = pci_write_sel_reg;
447
                                        wb_dat_o  = pci_write_reg; //wb_wr_buf[fifo_wb_counter_o];
448
                                        wb_address[31:0]  = fifo_start_wb_addr; //[31:0]+fifo_wb_counter_o ;
449
               if ( wbw_phase== 0 ) begin //phase 0: setup
450
                  wb_cyc_o <= 0;
451
                                                wb_stb_o <= 0;
452
                                                wb_wr_o <= 0;
453
                                                wbw_phase <= wbw_phase + 1;
454
                                                //address and data also changes now, from FIFO
455
                                        end
456
                                        else if ( wbw_phase== 1 ) begin //phase 1: access
457
                  wb_cyc_o <= 1;
458
                                                wb_stb_o <= 1;
459
                                                wb_wr_o <= 1;
460
                                                wbw_phase <= wbw_phase + 1;
461
                                        end
462
                                        else if ( wbw_phase== 2 ) begin //phase 2: wait for ack
463
                                                wbw_timeout_count_new <= wbw_timeout_count_new +1;
464
                                                if ((wb_ack_i==1) | (wbw_timeout_count_new==15)) begin
465
                                                        wbw_phase <= wbw_phase + 1;
466
                                                        wb_cyc_o <= 0;
467
                                                        wb_stb_o <= 0;
468
                                                        wb_wr_o <= 0;
469
                                                        if (wbw_timeout_count_new==15) begin failed_addr_reg <= wb_address; end
470
                                                        end
471
                                                else begin wb_cyc_o <= 1;       wb_stb_o <= 1;  wb_wr_o <= 1; end
472
                                        end
473
                                        else  if ( wbw_phase== 3 ) begin //phase 3: hold (finish)
474
                                           wb_cyc_o <= 0;
475
                                                wb_stb_o <= 0;
476
                                                wb_wr_o <= 0;
477
                                                wbw_phase <= wbw_phase + 1;
478
                                                wbw_timeout_count_new <=0;
479
                                                fifo_wb_counter_o <= fifo_wb_counter_o + 1; //for next word
480
                                                //if ((fifo_wb_counter_o == fifo_max_count-1)|(machinereset == 1)) begin 
481
                                                        fifo_flush <= 0;
482
                                                        wbwf_state <= machine_waiting;
483
                                                        fifo_wb_counter_o<=0;
484
                                                        mastering <= 0;
485
                                                        arb_stop <= 1;
486
                                                //end
487
                                        end
488
            end
489
 
490
            machine_read_filling : begin //rd-FIFO filling: wb read********************
491
                                   wb_sel_o = pci_read_sel_reg;
492
                                        wb_dat_o = 32'b0;
493
                                        wb_address[31:0]  = fifo_start_wb_addr_rd; //[31:0]+fifo_wb_counter_o_rd ;
494
               if ( wbr_phase== 0 ) begin //phase 0: setup
495
                  wb_cyc_o <= 0;
496
                                                wb_stb_o <= 0;
497
                                                wb_wr_o <= 0;
498
                                                wbr_phase <= wbr_phase + 1;
499
                                                //address and data also changes now, from FIFO
500
                                        end
501
                                        else if ( wbr_phase== 1 ) begin //phase 1: access
502
                  wb_cyc_o <= 1;
503
                                                wb_stb_o <= 1;
504
                                                wb_wr_o <= 0;
505
                                                wbr_phase <= wbr_phase + 1;
506
                                        end
507
                                        else if ( wbr_phase== 2 ) begin //phase 2: wait for ack
508
                                                wbr_timeout_count_new <= wbr_timeout_count_new +1;
509
                                                if ((wb_ack_i==1) | (wbr_timeout_count_new==15)) begin
510
                                                        //wb_rd_buf[fifo_wb_counter_o_rd] <= wb_dat_i; //sampling
511
                                                        pci_read_reg <= wb_dat_i; //sampling
512
                                                        wbr_phase <= wbr_phase + 1;
513
                                                        wb_cyc_o <= 0;
514
                                                        wb_stb_o <= 0;
515
                                                        wb_wr_o <= 0;
516
                                                        if (wbw_timeout_count_new==15) begin failed_addr_reg <= wb_address; end
517
                                                        end
518
                                                else begin wb_cyc_o <= 1;       wb_stb_o <= 1;  wb_wr_o <= 0; end
519
                                        end
520
                                        else  if ( wbr_phase== 3 ) begin //phase 3: hold (finish)
521
                                           wb_cyc_o <= 0;
522
                                                wb_stb_o <= 0;
523
                                                wb_wr_o <= 0;
524
                                                wbr_phase <= wbw_phase + 1;
525
                                                wbr_timeout_count_new <=0;
526
                                                fifo_wb_counter_o_rd <= fifo_wb_counter_o_rd + 1; //for next word
527
                                                //if ((fifo_wb_counter_o_rd == fifo_max_count_rd-1)|(machinereset == 1)) begin 
528
                                                        fifo_fill_rd <= 0;
529
                                                        wbwf_state <= machine_waiting;
530
                                                        fifo_wb_counter_o_rd<=0;
531
                                                        mastering <= 0;
532
                                                        arb_stop <= 1;
533
                                                //end
534
                                        end
535
            end
536
 
537
            default : begin  // Fault Recovery
538
               wbwf_state <= machine_waiting;
539
            end
540
 
541
 
542
         endcase
543
 
544
 
545
 
546
 
547
 
548
 
549
 
550
// main PCI state machine: ---------------------------------------------------------------
551
always @(posedge pciclk)
552
begin
553
    if (~reset) begin
554
        state <= ST_IDLE;
555
        enable <= EN_NONE;
556
        baseaddr <= 0;
557
        devsel <= 'bZ;
558
        memen <= 0;
559
                  int_line <= 8'b0;
560
                  int_dis <= 0;
561
                  wb_baseaddr_reg <= 0;
562
                  wb_address_1[31:0] <= 0;
563
                  user_status_reg <= 0;
564
                  user_command_reg <= 0;
565
                  fifo_flush_start <= 0;
566
                  fifo_fill_start_rd <= 0;
567
                  fifo_wb_counter <= 0;
568
                  fifo_wb_counter_rd <= 0;
569
                        dummy_reg  <= 0;
570
                        pci_write_reg <= 0;
571
                        machinereset   <= 0;
572
        led <= 0;
573
                  arb_start <= 0;
574
          addr_increment <= 0;
575
          wb_address_readonly  <= 0;
576
          wb_address_previous <= 5;
577
 
578
    end
579
    else    begin
580
 
581
    case (state)
582
        ST_IDLE: begin
583
            //enable <= EN_NONE;
584
            //devsel <= 'bZ;
585
                                fifo_flush_start <= 0;
586
                                fifo_fill_start_rd <= 0;
587
                                fifo_wb_counter <= 0;
588
                                fifo_wb_counter_rd <= 0;
589
                                machinereset   <= 0;
590
                addr_increment <= 0;
591
            if (~frame) begin
592
                address <= ad[7:2];
593
                if (hit) begin
594
                    devsel <= 0;
595
                    state <= {1'b1, cbe[3], cbe[0]};
596
                                                  if (addr_hit) begin  arb_start <= 1; end
597
                    //devsel <= 0;
598
                                                  wb_address_1[31:0] <= {wb_baseaddr_reg, ad[23:2]};
599
                                                  //if (wbwf_state == machine_waiting) begin //sample address, if FIFO is not busy
600
                                                                fifo_start_wb_addr <= {wb_baseaddr_reg, ad[23:2]};
601
                                                                fifo_start_wb_addr_rd <= {wb_baseaddr_reg, ad[23:2]};
602
                                                  //end         
603
                    // pipeline the write enable
604
                    if (cbe[0]) begin //its one?
605
                       enable <= EN_WR;
606
                    end
607
                    else begin
608
                       enable <= EN_RD;
609
                    end
610
                    if (cbe==4'b0110) begin //latch previous address if its going to be a memory read
611
                      wb_address_previous[31:0] <= wb_address_readonly[31:0];
612
                      wb_address_readonly[31:0] <= {wb_baseaddr_reg, ad[23:2]};
613
                    end
614
                end
615
                else begin
616
                    devsel <= 'bZ;
617
                    state <= ST_BUSY;
618
                    enable <= EN_NONE;
619
                end
620
            end
621
        end
622
 
623
        ST_BUSY: begin
624
            devsel <= 'bZ;
625
            enable <= EN_NONE;
626
                                arb_start <= 0;
627
            if (frame)
628
                state <= ST_IDLE;
629
        end
630
 
631
        ST_CFGREAD: begin
632
            //enable <= EN_RD;
633
            if (~irdy || trdylocal) begin
634
                case (address)
635
                    0: data <= { DEVICE_ID, VENDOR_ID };
636
                    1: data <= { 5'b0, DEVSEL_TIMING,  5'b0, int_stat, 8'b0, int_dis, 8'b0, memen, 1'b0};
637
                    2: data <= { DEVICE_CLASS, DEVICE_REV };
638
                    4: data <= { baseaddr, 12'b0, 8'b0, 4'b0000 }; // baseaddr + request mem < 1Mbyte
639
                    11: data <= {SUBSYSTEM_ID, SUBSYSTEM_VENDOR_ID };
640
                                                  15: data <= {16'b0, 7'b0, 1'b1, int_line}; //irq pin and line
641
                    16: data <= { 24'b0, baseaddr };
642
                                                  20: data <= { wb_baseaddr_reg, 22'b0}; //wb base address: for wb-local relocation
643
                                                  21: data <= user_status_reg;
644
                                                  22: data <= user_command_reg;
645
                                                  23: data <= failed_addr_reg; //actual addr, at a timeout
646
                    default: data <= 'h00000000;
647
                endcase
648
                //address <= address + 1;
649
                                         arb_start <= 0;
650
                     addr_increment <= 1;
651
                     if (addr_increment) begin address <= address + 1; end
652
            end
653
            if (frame && ~irdy && ~trdylocal) begin
654
                devsel <= 1;
655
                state <= ST_IDLE;
656
                enable <= EN_TR;
657
            end
658
            else begin
659
                enable <= EN_RD;
660
            end
661
        end
662
 
663
        ST_CFGWRITE: begin
664
            //enable <= EN_WR;
665
            if (~irdy) begin
666
                case (address)
667
                    4: baseaddr <= ad[31:24];  // XXX examine cbe
668
                    1: begin memen <= ad[1]; int_dis <= ad[10]; end
669
                                                  15: int_line <= ad[7:0];
670
                                                  20: wb_baseaddr_reg <= ad[31:22];
671
                                                  22: user_command_reg  <= ad[31:0];
672
                                                  24: machinereset   <= 1;      //resetting the wb state machine (60h)
673
                    default: ;
674
                endcase
675
                //address <= address + 1;
676
                                         arb_start <= 0;
677
                     addr_increment <= 1;
678
                     if (addr_increment) begin address <= address + 1; end
679
                if (frame && ~trdylocal) begin
680
                    devsel <= 1;
681
                    state <= ST_IDLE;
682
                    enable <= EN_TR;
683
                end
684
                else begin
685
                    enable <= EN_WR;
686
                end
687
            end
688
        end
689
 
690
        ST_MEMREAD: begin
691
            //enable <= EN_RD;
692
                                arb_start <= 0;
693
            if (~irdy || trdylocal) begin
694
                //address <= address + 1;
695
                                         data <= pci_read_reg;
696
                                         pci_read_sel_reg  <= ~cbe;
697
            end
698
            if (frame && ~irdy && (~trdylocal || ~stoplocal)) begin
699
                devsel <= 1;
700
                state <= ST_IDLE;
701
                enable <= EN_TR;
702
                                                  //fifo_fill_rd<=0;
703
                                                  //if (wbwf_state == machine_waiting) begin 
704
                                                                fifo_fill_start_rd <= 1;
705
                                                  //end                                          
706
            end
707
            else begin
708
                enable <= EN_RD;
709
            end
710
        end
711
 
712
        ST_MEMWRITE: begin
713
            //enable <= EN_WR;
714
                                arb_start <= 0;
715
            if (~irdy) begin
716
                                         led <= ad[3:0];
717
                                         pci_write_reg  <= ad[31:0];
718
                                         pci_write_sel_reg <= ~cbe;
719
                //address <= address + 1;
720
                if (frame & ~trdylocal) begin
721
                    devsel <= 1;
722
                    state <= ST_IDLE;
723
                    enable <= EN_TR;
724
                                                  fifo_fill<=0;
725
                                                  //if (wbwf_state == machine_waiting) begin 
726
                                                                fifo_flush_start <= 1;
727
                                                  //end         
728
               end
729
               else begin
730
                    enable <= EN_WR;
731
               end
732
            end
733
 
734
        end
735
 
736
    endcase
737
    end
738
end
739
endmodule

powered by: WebSVN 2.1.0

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