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

Subversion Repositories pci_mini

[/] [pci_mini/] [trunk/] [pci-40.vhd] - Blame information for rev 9

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 9 buenos
-- *************************************************************** //
2
--                                                                                                                                 //
3
--                      PCI_TARGET-Wishbone_MASTER INTERFACE MODULE     (PCI-mini) //
4
--                                                                                      v4.0                           //
5
--                                                                                                                             //
6
--   The original PCI module is from:   Ben Jackson.               //
7
--                              http://www.ben.com/minipci/verilog.php             //
8
--                                                                                                                         //
9
--        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
-- V4.0 is completely re-written from scratch in VHDL. It has some features removed,
82
--  like address remapping or user reset control.
83
--
84
-- Device Compatibility:
85
--  Until v3.3 the code was tested on Xilinx FPGAs (sp2, sp3) with ISE 4.7-9.1 and VIA/AMD chipsets.
86
--  Version 3.4 has modifications to work on Actel/Microsemi ProASIC3 with Sinplify and Intel Atom chipset.
87
--  (v3.4 was not tested on Xilinx FPGAs) To make sure that it runs on the Actel FPGA, we have to use the
88
--  timing constraint SDC file, AND ALSO set the P&R to Timing optimized and "effort"=high.
89
--
90
-- *************************************************************** //
91
 
92
 
93
library IEEE;
94
use IEEE.STD_LOGIC_1164.ALL;
95
use IEEE.STD_LOGIC_ARITH.ALL;
96
use IEEE.STD_LOGIC_UNSIGNED.ALL;
97
 
98
 
99
--entity header  ----------------------------------------------------------------
100
entity pci is
101
    Port ( --ports:
102
            reset : in std_logic;
103
            pciclk : in std_logic;
104
            frame : in std_logic;
105
            irdy : in std_logic;
106
            trdy : out std_logic;
107
            devsel : out std_logic;
108
            idsel : in std_logic;
109
            ad : inout std_logic_vector(31 downto 0);
110
            cbe : in std_logic_vector(3 downto 0);
111
            par : inout std_logic;
112
            stop : out std_logic;
113
            inta : out std_logic;
114
            serr : out std_logic;
115
            perr : out std_logic;
116
            led_out : out std_logic_vector(3 downto 0);
117
            wb_address : out std_logic_vector(31 downto 0);
118
            wb_dat_o : out std_logic_vector(31 downto 0);
119
            wb_dat_i : in std_logic_vector(31 downto 0);
120
            wb_sel_o : out std_logic_vector(3 downto 0);
121
            wb_cyc_o : out std_logic;
122
            wb_stb_o : out std_logic;
123
            wb_wr_o : out std_logic;
124
            wb_reset_o : out std_logic;
125
            wb_clk_o : out std_logic;
126
            wb_ack_i : in std_logic;
127
            wb_irq : in std_logic;
128
            wb_req : out std_logic;
129
            wb_gnt : in std_logic;
130
            wb_req_other : in std_logic;
131
            contr_o : out std_logic_vector(7 downto 0)
132
           );
133
end pci;
134
 
135
 
136
 
137
 
138
 
139
 
140
--architecture start ------------------------------------------------------------
141
architecture Behavioral of pci is
142
 
143
 
144
 
145
 
146
-- SOME CONSTANTS ---------------------------------------------------------------
147
CONSTANT DEVICE_ID : std_logic_vector := X"9500";
148
CONSTANT VENDOR_ID : std_logic_vector := X"11AA"; --    160X11AA : std_logic_vector := actel, 
149
CONSTANT DEVICE_CLASS : std_logic_vector := X"118000";  -- some examples: 068000=bridge/other, 078000=simple_comm_contr/other, 118000=data_acquisition/other
150
CONSTANT DEVICE_REV : std_logic_vector := X"01";
151
CONSTANT SUBSYSTEM_ID : std_logic_vector := X"0001";    -- Card identifier
152
CONSTANT SUBSYSTEM_VENDOR_ID : std_logic_vector := X"13C7"; -- 13C7 : std_logic_vector := bluechip technology
153
CONSTANT DEVSEL_TIMING : std_logic_vector := "00";      -- Fast!
154
CONSTANT ST_IDLE : std_logic_vector := "000";
155
CONSTANT ST_BUSY : std_logic_vector := "010";
156
CONSTANT ST_MEMREAD : std_logic_vector := "100";
157
CONSTANT ST_MEMWRITE : std_logic_vector := "101";
158
CONSTANT ST_CFGREAD : std_logic_vector := "110";
159
CONSTANT ST_CFGWRITE : std_logic_vector := "111";
160
CONSTANT ST_HOLD : std_logic_vector := "001";
161
CONSTANT MEMREAD : std_logic_vector := "0110"; --cbe
162
CONSTANT MEMWRITE : std_logic_vector := "0111"; --cbe
163
CONSTANT CFGREAD : std_logic_vector := "1010"; --cbe
164
CONSTANT CFGWRITE : std_logic_vector := "1011"; --cbe
165
CONSTANT WB_BASEADDRESS : std_logic_vector := "00000000000000000000000000000000";
166
CONSTANT INT_PIN_INFO : std_logic_vector := "00000001"; --which interrupt signal is connected on the PCB? 0=none, 1=INTA, 2=INTB, 3=INTC, 4=INTD
167
 
168
 
169
 
170
 
171
 
172
-- INTERNAL SIGNALS -------------------------------------------------------------
173
    SIGNAL wb0_state  :  std_logic_VECTOR(7 DOWNTO 0);
174
    SIGNAL wb_transaction_complete :  std_logic;
175
    SIGNAL start_read_wb0 :  std_logic;
176
    SIGNAL start_write_wb0 :  std_logic;
177
    SIGNAL wb_address_feed  :  std_logic_VECTOR(31 DOWNTO 0);
178
    SIGNAL wb_dat_o_feed  :  std_logic_VECTOR(31 DOWNTO 0);
179
    SIGNAL wb_dat_i_latched  :  std_logic_VECTOR(31 DOWNTO 0);
180
    SIGNAL wb_sel_o_feed :  std_logic_VECTOR(3 DOWNTO 0);
181
 
182
    SIGNAL pci_state  :  std_logic_VECTOR(2 DOWNTO 0);
183
    SIGNAL second_clock_pci :  std_logic;
184
    SIGNAL assert_stop :  std_logic;
185
    SIGNAL data  :  std_logic_VECTOR(31 DOWNTO 0);
186
    SIGNAL wr_data_pci  :  std_logic_VECTOR(31 DOWNTO 0);
187
    SIGNAL ad_latched   :  std_logic_VECTOR(31 DOWNTO 0);
188
    SIGNAL cbe_latched   :  std_logic_VECTOR(3 DOWNTO 0);
189
    SIGNAL frame_latched  :  std_logic;
190
    SIGNAL irdy_latched  :  std_logic;
191
    SIGNAL idsel_latched  :  std_logic;
192
    SIGNAL cbe_latched2  :  std_logic_VECTOR(3 DOWNTO 0);
193
    SIGNAL frame_latched2 :  std_logic;
194
 
195
    SIGNAL pci_address   :  std_logic_VECTOR(31 DOWNTO 0);
196
    SIGNAL pci_address_previous  :  std_logic_VECTOR(31 DOWNTO 0);
197
    SIGNAL pci_address_readonly  :  std_logic_VECTOR(31 DOWNTO 0);
198
    SIGNAL hit :  std_logic;
199
    SIGNAL int_stat :  std_logic;
200
    SIGNAL addr_hit :  std_logic;
201
    SIGNAL cfg_hit :  std_logic;
202
    SIGNAL baseaddr   :  std_logic_VECTOR(7 DOWNTO 0);
203
    SIGNAL int_line   :  std_logic_VECTOR(7 DOWNTO 0);
204
    SIGNAL int_dis :  std_logic;
205
    SIGNAL data_par :  std_logic;
206
    SIGNAL memen :  std_logic;
207
    SIGNAL dummyreg32  :  std_logic_VECTOR(31 DOWNTO 0);
208
 
209
 
210
 
211
 
212
 
213
--------- COMPONENT DECLARATIONS (introducing the IPs) --------------------------
214
--none
215
 
216
 
217
--architecture body start -------------------------------------------------------
218
begin
219
 
220
 
221
 
222
--------- COMPONENT INSTALLATIONS (connecting the IPs to local signals) ---------
223
--none
224
 
225
 
226
-- local Logic ------------------------------------------------------------------
227
 
228
    led_out <= "0000";
229
    contr_o <= "00000000";
230
 
231
 
232
 
233
 
234
    -- ************** WISBONE BACK-end INTERFACE ****************************
235
    -- **********************************************************************
236
 
237
    --main state machine: set states, capture inputs, set addr/data outputs
238
         --minimum 2 clock cycles / transaction. writes are posted, reads have wait states.
239
    process (reset, pciclk, wb0_state, start_read_wb0, start_write_wb0,
240
                                wb_address_feed, wb_dat_o_feed, wb_sel_o_feed)
241
    begin
242
    if (reset='0') then
243
       wb0_state <= "00000000";
244
       wb_transaction_complete <= '0';
245
                 wb_address <= "00000000000000000000000000000000";
246
                 wb_sel_o <= "0000";
247
                 wb_dat_o <=   "00000000000000000000000000000000";
248
                 wb_transaction_complete <='0';
249
         wb_dat_i_latched <= "00000000000000000000000000000000";
250
    else
251
      if (pciclk'event and pciclk = '1') then
252
                case ( wb0_state ) is
253
 
254
                --********** IDLE STATE  **********
255
                when "00000000" =>   --state 0        
256
                    wb_transaction_complete <='0';
257
                                                  wb_sel_o <= wb_sel_o_feed;
258
                                                  wb_address <= wb_address_feed;
259
                                                  if (start_read_wb0 ='1') then --go to read
260
                                                    wb0_state <= "00000001";
261
                                                  elsif (start_write_wb0 ='1') then --go to write
262
                                                    wb0_state <= "00000010";
263
                                                        wb_dat_o <= wb_dat_o_feed;
264
                                                  end if;
265
 
266
                --********** READ STATE ********** 
267
                                         --set the outputs, 
268
                                         --if ACK asserted, sample the data input
269
                                         --The hold requirements are oversatisfyed by going back to idle, and by the fact that the slave uses the cyc/stb/wr strobes synchronously.
270
                when "00000001" =>   --state 1
271
                    if (wb_ack_i='1') then
272
                                                     wb_dat_i_latched <= wb_dat_i; --sample the incoming data                                           
273
                                                         wb_transaction_complete <='1'; --signalling ready, but only for one clock cycle
274
                                                         wb0_state <= "00000000"; --go to state 0
275
                                                  else
276
                                                         wb_transaction_complete <='0';
277
                                                  end if;
278
 
279
                --********** WRITE STATE **********     
280
                                         --if ACK asserted, go back to idle
281
                                         --The hold requirements are oversatisfyed by waiting for ACK to remove write data                                       
282
                when "00000010" =>   --state 2
283
                    if (wb_ack_i='1') then
284
                                                         wb0_state <= "00000000"; --go to state 0
285
                                                         wb_transaction_complete <='1';
286
                                                  else
287
                                                     wb_transaction_complete <='0';
288
                                                  end if;
289
 
290
                when others => --error
291
                      wb0_state <= "00000000"; --go to state 0
292
                end case;
293
       end if;
294
    end if;
295
    end process;
296
    --sync control on wb-control signals:
297
    process (reset, wb0_state)
298
    begin
299
    if (reset='0') then
300
                wb_cyc_o  <= '0';
301
                wb_stb_o  <= '0';
302
                wb_wr_o  <= '0';
303
    else
304
      if (wb0_state = "00000000") then --idle
305
                        wb_cyc_o  <= '0';
306
                        wb_stb_o  <= '0';
307
                        wb_wr_o  <= '0';
308
      elsif (wb0_state = "00000001") then --read 
309
                        wb_cyc_o  <= '1';
310
                        wb_stb_o  <= '1';
311
                        wb_wr_o  <= '0';
312
      elsif (wb0_state = "00000010") then --write 
313
                        wb_cyc_o  <= '1';
314
                        wb_stb_o  <= '1';
315
                        wb_wr_o  <= '1';
316
                else
317
                        wb_cyc_o  <= '0';
318
                        wb_stb_o  <= '0';
319
                        wb_wr_o  <= '0';
320
                end if;
321
    end if;
322
    end process;
323
 
324
    wb_reset_o <= not reset;
325
    wb_clk_o <= pciclk;
326
    wb_sel_o_feed <= "1111"; --only 32bit accesses are supported
327
 
328
 
329
 
330
    -- wishbone arbitration:
331
    --not supported at the moment:
332
    wb_req <= '1';
333
    -- xx <- wb_req_other, wb_gnt
334
 
335
 
336
 
337
 
338
 
339
 
340
 
341
 
342
 
343
 
344
 
345
 
346
    -- ************** THE PCI I/O STATEMACHINE ******************************
347
    -- **********************************************************************
348
    process (reset, pciclk)
349
    begin
350
    if (reset='0') then
351
        trdy  <= 'Z';
352
        devsel  <= 'Z';
353
        ad  <= "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ";
354
        par  <= 'Z';
355
        stop  <= 'Z';
356
        start_read_wb0 <= '0';
357
        start_write_wb0  <= '0';
358
        wb_address_feed  <= "11111111111111111111111111111111";
359
        wb_dat_o_feed  <= "11111111111111111111111111111111";
360
        pci_state <= ST_IDLE;
361
        ad_latched <= (others => '0');
362
        cbe_latched <= "0000";
363
        frame_latched <= '1';
364
        irdy_latched <= '1';
365
        idsel_latched <= '0';
366
        second_clock_pci <= '0';
367
        wr_data_pci <=  (others => '0');
368
        assert_stop  <= '0';
369
        dummyreg32 <=   (others => '0');
370
        baseaddr  <=   (others => '0');
371
        int_line   <=   (others => '0');
372
        int_dis  <= '0';
373
        memen  <= '0';
374
        pci_address    <=   (others => '0');
375
        pci_address_previous   <=   (others => '1');
376
        pci_address_readonly <=   (others => '0');
377
        data   <=   (others => '0');
378
        cbe_latched2 <= "0000";
379
        frame_latched2 <= '1';
380
    else
381
      if (pciclk'event and pciclk = '1') then
382
 
383
              --latching some signals to break timing path:
384
              ad_latched <= ad;
385
              cbe_latched <= cbe;
386
              frame_latched <= frame;
387
              irdy_latched <= irdy;
388
              idsel_latched <= idsel;
389
              --again::
390
              cbe_latched2 <= cbe_latched;
391
              frame_latched2 <= frame_latched;
392
 
393
              case ( pci_state ) is
394
 
395
                --********** idle STATE  **********
396
                when ST_IDLE =>   --state 000        
397
                    --pci signals:
398
                    trdy  <= 'Z';
399
                    ad  <= "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ";
400
                    par  <= 'Z';
401
                    stop  <= 'Z';
402
                    --logic:
403
                    --address handling/latching:
404
                    if (frame_latched = '0') then
405
                      pci_address <= ad_latched;
406
                    end if;
407
                    if (frame_latched2='0' and hit='1') then
408
                      --next state without decoding:
409
                      --pci_state(2) <= '1';
410
                      --pci_state(1) <=  cbe_latched(3);
411
                      --pci_state(0) <= cbe_latched(0);
412
                      if (cbe_latched2 = MEMREAD) then
413
                        pci_state <=  ST_MEMREAD ;
414
                        pci_address_readonly <= pci_address;
415
                        pci_address_previous <= pci_address_readonly;
416
                      elsif (cbe_latched2 = MEMWRITE) then
417
                        pci_state <=  ST_MEMWRITE ;
418
                      elsif (cbe_latched2 = CFGREAD) then
419
                        pci_state <=  ST_CFGREAD ;
420
                      elsif (cbe_latched2 = CFGWRITE) then
421
                        pci_state <=  ST_CFGWRITE  ;
422
                      end if;
423
                      devsel  <= '0';
424
                    else
425
                      devsel  <= 'Z';
426
                    end if;
427
                    start_read_wb0 <= '0';
428
                    start_write_wb0 <= '0';
429
                    assert_stop  <= '0';
430
                    second_clock_pci <= '0';
431
 
432
                --********** CFG Read STATE ********** 
433
                when ST_CFGREAD =>   --state 110
434
                    second_clock_pci <= '1';
435
                    case (pci_address(7 downto 2)) is
436
                      when "000000" => --0
437
                         data (31 downto 16) <=  DEVICE_ID;
438
                         data (15 downto 0) <=  VENDOR_ID;
439
                      when "000001" => --1
440
                         data (31 downto 27) <=  "00000";
441
                         data (26 downto 25 ) <=  DEVSEL_TIMING;
442
                         data (24 downto 20) <=  "00000";
443
                         data ( 19 ) <=  int_stat;
444
                         data (18 downto 11) <=  "00000000";
445
                         data ( 10 ) <=  int_dis;
446
                         data (9 downto 2) <=  "00000000";
447
                         data ( 1 ) <=  memen;
448
                         data ( 0 ) <=  '0';
449
                      when "000010" => --2
450
                         data (31 downto 8) <=  DEVICE_CLASS;
451
                         data (7 downto 0) <=  DEVICE_REV;
452
                      when "000100" => --4 (BAR0)
453
                         data (31 downto 24) <=  baseaddr;
454
                         data (23 downto 0) <=  (others => '0');
455
                      when "001011" => --11
456
                         data (31 downto 16) <=  SUBSYSTEM_ID;
457
                         data (15 downto 0) <=  SUBSYSTEM_VENDOR_ID;
458
                      when "001111" => --15
459
                         data (31 downto 16) <=  (others => '0');
460
                         data (15 downto 8) <=  INT_PIN_INFO;
461
                         data (7 downto 0) <=  int_line;
462
                      --when "010000" => --16
463
                         --data ( downto ) <=  ;
464
                      when others => --0
465
                         data <= "00000000000000000000000000000000";
466
                    end case;
467
                    --finishing off:
468
                    if (second_clock_pci='1' and irdy_latched='0') then
469
                        --pci signals:
470
                        trdy  <= '0';
471
                        ad  <= data;
472
                        par  <= data_par;
473
                        pci_state <= ST_HOLD;
474
                    end if;
475
 
476
                --********** CFG Write STATE **********                                  
477
                when ST_CFGWRITE =>   --state 111
478
                    if (second_clock_pci='0' and irdy_latched='0') then
479
                        wr_data_pci <= ad;
480
                        second_clock_pci <= '1';
481
                    end if;
482
                    --finishing off:
483
                    if (second_clock_pci='1') then
484
                        --pci signals:
485
                        devsel  <= '1';
486
                        trdy  <= '1';
487
                        stop  <= '1';
488
                        pci_state <= ST_HOLD;
489
                        --set the appropriate register
490
                        case (pci_address(7 downto 2)) is
491
                          when "000001" => --1
492
                             int_dis <= wr_data_pci(10);
493
                             memen <= wr_data_pci(1);
494
                          when "000100" => --4 (BAR0)
495
                             baseaddr <= wr_data_pci(31 downto 24);
496
                          when "001111" => --15
497
                             int_line  <= wr_data_pci(7 downto 0);
498
                          --when "010000" => --16
499
                             --data ( downto ) <=  ;
500
                          when others => --0
501
                             dummyreg32 <= wr_data_pci;
502
                        end case;
503
                    elsif (irdy_latched='0') then --second_clock_pci='0'
504
                      trdy  <= '0';
505
                    end if;
506
 
507
                --********** Mem Read STATE ********** 
508
                when ST_MEMREAD =>   --state 100
509
                   second_clock_pci <= '1';
510
                   --initialize wishbone read:
511
                   if (second_clock_pci='0' ) then
512
                        wb_address_feed(21 downto 0) <= pci_address (23 downto 2);
513
                        wb_address_feed(31 downto 22) <= (others => '0');
514
                        start_read_wb0 <= '1';
515
                        data <= wb_dat_i_latched;
516
                   else
517
                        start_read_wb0 <= '0';
518
                   end if;
519
                   if (pci_address_previous = pci_address_readonly) then
520
                       assert_stop  <= '0';
521
                   else
522
                       assert_stop  <= '1';
523
                   end if;
524
                   if (second_clock_pci='1' and irdy_latched='0') then
525
                        --pci signals:
526
                        ad  <= data;
527
                        par  <= data_par;
528
                        pci_state <= ST_HOLD;
529
                        if (assert_stop = '1') then --terminate with retry
530
                          stop  <= '0';
531
                          trdy  <= 'Z';
532
                        else                        --terminate with data
533
                          stop  <= 'Z';
534
                          trdy  <= '0';
535
                          pci_address_readonly <=   (others => '1'); --so next time it will reqest a retry again
536
                        end if;
537
                   end if;
538
 
539
                --********** Mem Write STATE **********                                  
540
                when ST_MEMWRITE =>   --state 101
541
                    if (second_clock_pci='0' and irdy_latched='0') then
542
                        wr_data_pci <= ad;
543
                        second_clock_pci <= '1';
544
                    end if;
545
                    --finishing off:
546
                    if (second_clock_pci='1') then
547
                        --pci signals:
548
                        devsel  <= '1';
549
                        trdy  <= '1';
550
                        stop  <= '1';
551
                        pci_state <= ST_HOLD;
552
                        --set the awishbone bus to go
553
                        start_write_wb0 <= '1';
554
                        wb_address_feed(21 downto 0) <= pci_address (23 downto 2);
555
                        wb_address_feed(31 downto 22) <= (others => '0');
556
                        wb_dat_o_feed <= wr_data_pci;
557
                    elsif (irdy_latched='0') then --second_clock_pci='0'
558
                      trdy  <= '0';
559
                    end if;
560
 
561
                --********** busy STATE **********
562
                --this is left over from the original PCI core
563
                when ST_BUSY =>   --state 010
564
                    pci_state <= ST_IDLE; --go to state 0
565
 
566
                --********** HOLD STATE **********                               
567
                when ST_HOLD =>   --state 001
568
                    pci_state <= ST_IDLE; --go to state 0
569
                    trdy  <= '1';
570
                    devsel  <= '1';
571
                    stop  <= '1';
572
                    start_write_wb0 <= '0';
573
 
574
                when others => --error
575
                      pci_state <= ST_IDLE; --go to state 0
576
              end case;
577
       end if;
578
    end if;
579
    end process; --pci statemachine ends here
580
 
581
 
582
 
583
 
584
 
585
 
586
 
587
 
588
 
589
 
590
 
591
-- some PCI glue logic: -------------------------------------------------
592
 
593
    --parity:
594
    data_par <= (data(31) xor data(30) xor data(29) xor data(28)) xor
595
                    (data(27) xor data(26) xor data(25) xor data(24)) xor
596
                    (data(23) xor data(22) xor data(21) xor data(20)) xor
597
                    (data(19) xor data(18) xor data(17) xor data(16)) xor
598
                    (data(15) xor data(14) xor data(13) xor data(12)) xor
599
                    (data(11) xor data(10) xor data(9)  xor data(8))  xor
600
                    (data(7)  xor data(6)  xor data(5)  xor data(4))  xor
601
                                (cbe(3)  xor cbe(2)  xor cbe(1)  xor cbe(0))  xor
602
                    (data(3)  xor data(2)  xor data(1)  xor data(0)) ;
603
 
604
 
605
 
606
 
607
  --these are not used:
608
   serr  <= 'Z';
609
   perr <= 'Z';
610
 
611
 
612
 
613
    --interrupt:
614
        process ( reset, pciclk)
615
    begin
616
       if (reset='0') then
617
           inta <= 'Z';
618
           int_stat <= '0';
619
       elsif (pciclk'event and pciclk='1') then
620
             if (wb_irq = '1' and int_dis='0') then
621
               inta <= '0';
622
             else
623
               inta <= 'Z';
624
             end if;
625
             int_stat <= wb_irq;
626
       end if;
627
    end process;
628
 
629
 
630
 
631
         --address match detection logic:
632
        process ( reset, pciclk )
633
    begin
634
       if (reset='0') then
635
           cfg_hit <= '0';
636
           addr_hit <= '0';
637
       elsif (pciclk'event and pciclk='1') then
638
             --config access:
639
             if ((cbe_latched = CFGREAD or cbe_latched = CFGWRITE)
640
                 and idsel_latched='1'
641
                 and ad_latched(10 downto 8) = "000"
642
                 and ad_latched(1 downto 0) = "00") then
643
                  cfg_hit <= '1';
644
             else
645
                  cfg_hit <= '0';
646
             end if;
647
             --memory access:
648
             if ((cbe_latched = MEMREAD or cbe_latched = MEMWRITE)
649
                 and memen = '1'
650
                 and ad_latched(31 downto 24) = baseaddr) then
651
                  addr_hit <= '1';
652
             else
653
                  addr_hit <= '0';
654
             end if;
655
       end if;
656
    end process;
657
    hit <= cfg_hit or addr_hit;
658
 
659
 
660
 
661
 
662
 
663
 
664
--end file ----------------------------------------------------------------------
665
end Behavioral;
666
 
667
 

powered by: WebSVN 2.1.0

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