Перейти к содержанию
    

SIMPLE PCI CONTROLLER ПОМОГИТЕ ПОДОГНАТЬ под MAX+

-- SIMPLE PCI CONTROLLER VERSION 2.1 --

-- Designed for xc95144xl --

-- --

-- **************************** Resource Summary **************************** --

-- Macrocells Product Terms Registers Pins Function Block --

-- Used Used Used Used Inputs Used --

-- 100/144 ( 69%) 524 /720 ( 72%) 76 /144 ( 52%) 57 /81 ( 70%) 262/432 ( 60%) --

-- --

-- Copyright © 2001, 2002 by Shustanov Viktor. All rights reserved. --

-- --

-- This source file may be used and distributed without restriction --

-- provided that this copyright statement is not removed from the file --

-- and that any derivative work contains this copyright notice. --

-- --

-- Disclaimer: These designs are provided "AS IS" with no warranty --

-- whatsoever and auther specfically disclaims any --

-- implied waarenties of merchantability, fitness for --

-- a particular purpose, or agaist infringement. --

-- NOTES: VendorId and DeviceID are arbitrary numbers and have no relation with --

-- potential producer --

-- mailto: [email protected] --

--================================================================================

====

 

library IEEE;

use IEEE.std_logic_1164.all;

use IEEE.std_logic_unsigned.all;

use IEEE.std_logic_arith.all;

 

entity pci_controller is

port (

-- PCI side signals

clk : IN STD_LOGIC;

frame : IN STD_LOGIC;

ad : INOUT STD_LOGIC_VECTOR (31 DOWNTO 0);

cbe : IN STD_LOGIC_VECTOR (3 DOWNTO 0);

irdy : IN STD_LOGIC;

idsel : IN STD_LOGIC;

devsel : OUT STD_LOGIC;

trdy : OUT STD_LOGIC;

stop : OUT STD_LOGIC;

reset : IN STD_LOGIC;

inta : OUT STD_LOGIC;

 

-- Local side signals

d : INOUT STD_LOGIC_VECTOR (7 DOWNTO 0);

iord : OUT STD_LOGIC;

iowr : OUT STD_LOGIC;

iocs : OUT STD_LOGIC;

interrupt : IN STD_LOGIC);

end pci_controller;

 

ARCHITECTURE rtl OF pci_controller IS

 

------------------- PCI configuration space registers

signal command_io : STD_LOGIC;

signal bar0 : STD_LOGIC_VECTOR (7 DOWNTO 0);

signal int_line_reg : STD_LOGIC_VECTOR (7 downto 0);

signal late_grant_reg : STD_LOGIC_VECTOR (15 downto 0);

 

------------------- PCI configuration space constants

constant ADDRESS_00H : STD_LOGIC_VECTOR (5 DOWNTO 0) := "000000";

constant ADDRESS_04H : STD_LOGIC_VECTOR (5 DOWNTO 0) := "000001";

constant ADDRESS_08H : STD_LOGIC_VECTOR (5 DOWNTO 0) := "000010";

constant ADDRESS_0CH : STD_LOGIC_VECTOR (5 DOWNTO 0) := "000011";

constant ADDRESS_10H : STD_LOGIC_VECTOR (5 DOWNTO 0) := "000100";

constant ADDRESS_3CH : STD_LOGIC_VECTOR (5 DOWNTO 0) := "001111";

constant IO_WRITE : STD_LOGIC_VECTOR (3 DOWNTO 0) := "0011";

constant IO_READ : STD_LOGIC_VECTOR (3 DOWNTO 0) := "0010";

constant CONFIG_WRITE : STD_LOGIC_VECTOR (3 DOWNTO 0) := "1011";

constant CONFIG_READ : STD_LOGIC_VECTOR (3 DOWNTO 0) := "1010";

constant INT_PIN : STD_LOGIC_VECTOR (7 DOWNTO 0) := "00000001";

constant DEVICE_VENDOR_ID : STD_LOGIC_VECTOR (31 DOWNTO 0) := "01010101010101010101010101010101";

constant CLASS_CODE : STD_LOGIC_VECTOR (31 DOWNTO 0) := "00000010100000000000000000000000";

 

 

signal access_address : STD_LOGIC_VECTOR (15 DOWNTO 0);

signal pci_state_mashine : integer range 0 to 8;

signal ws_cntr : integer range 0 to 10;

 

ATTRIBUTE INIT : string;

ATTRIBUTE INIT OF command_io : signal is "R";

ATTRIBUTE INIT OF devsel : signal is "S";

ATTRIBUTE INIT OF trdy : signal is "S";

ATTRIBUTE INIT OF stop : signal is "S";

ATTRIBUTE INIT OF iord : signal is "S";

ATTRIBUTE INIT OF iowr : signal is "S";

ATTRIBUTE INIT OF iocs : signal is "S";

ATTRIBUTE INIT OF d : signal is "ZZZZZZZZ";

 

BEGIN

 

inta <= interrupt;

 

--================================================================================

====

-- MAIN PROCESS

--================================================================================

====

process

begin

wait until clk'event and clk='1';

 

--================================================================================

====

-- IO wait states count

--================================================================================

====

case ws_cntr is

when 10 => NULL;

when others => ws_cntr <= ws_cntr+1;

end case;

--if ws_cntr /= 10 then

-- ws_cntr <= ws_cntr+1;

--end if;

--================================================================================

====

-- init on RESET

--================================================================================

====

if reset='0' then

pci_state_mashine <= 0;

command_io <= '0';

bar0 <= "00000000";

devsel <= 'Z';

trdy <= 'Z';

stop <= 'Z';

ad <= (others =>'Z');

iowr <= '1';

iord <= '1';

iocs <= '1';

d <= "ZZZZZZZZ";

ws_cntr <= 10;

end if;

 

--================================================================================

====

-- PCI STATE MASHINE

--================================================================================

====

 

----- ADDRESS PHASE

if frame='0' and pci_state_mashine=0

then access_address <= ad(15 downto 0);

 

----------- configuration space access

if idsel='1'

then case cbe is

when CONFIG_READ => pci_state_mashine <= 1;

--devsel <= transport '0' after 6 ns;

devsel <= '0' after 6 ns;

when CONFIG_WRITE => pci_state_mashine <= 2;

--devsel <= transport '0' after 6 ns;

devsel <= '0' after 6 ns;

when others => NULL;

end case;

 

----------- i/o space access

else case cbe is

when IO_READ => if command_io='1'

then pci_state_mashine <= 3;

iocs <= '0';

end if;

when IO_WRITE => if command_io='1'

then pci_state_mashine <= 4;

iocs <= '0';

end if;

when others => NULL;

end case;

end if;

end if;

 

---- DATA PHASE

case pci_state_mashine is

 

----------- configuration read

when 1 => --trdy <= transport '0' after 6 ns;

--stop <= transport '0' after 6 ns;

trdy <= '0' after 6 ns;

stop <= '0' after 6 ns;

pci_state_mashine <= 5;

case access_address(7 downto 2) is

when ADDRESS_00H => ad <= DEVICE_VENDOR_ID;

when ADDRESS_04H => ad(0) <= command_io;

--ad(31 downto 1)<= (31 downto 1 => '0');

ad(31 downto 1)<="0000000000000000000000000000000";

--ad<=("0000000000000000000000000000000"&command_io);

when ADDRESS_08H => ad <= CLASS_CODE;

when ADDRESS_0CH => ad <= (others => '0');

when ADDRESS_10H => ad(7 downto 0) <= "00000001";

ad(15 downto 8) <= bar0;

--ad(31 downto 16) <= (31 downto 16 => '0');

ad(31 downto 16) <= "0000000000000000";

when ADDRESS_3CH => ad(7 downto 0) <= int_line_reg;

ad(15 downto 8) <= INT_PIN;

--ad(31 downto 16) <= (31 downto 16 => '0');

ad(31 downto 16) <= "0000000000000000";

when others => ad <= (others => '0');

end case;

 

----------- configuration write

when 2 => --trdy <= transport '0' after 6 ns;

--stop <= transport '0' after 6 ns;

trdy <= '0' after 6 ns;

stop <= '0' after 6 ns;

pci_state_mashine <= 6;

case access_address(7 downto 2) is

when ADDRESS_04H => command_io <= ad(0);

when ADDRESS_10H => bar0 <= ad(15 downto 8);

when ADDRESS_3CH => int_line_reg <= ad(7 downto 0);

when others => NULL;

end case;

 

----------- i/o read

when 3 => if access_address(15 downto 8)=bar0

then --devsel <= transport '0' after 6 ns;

devsel <= '0' after 6 ns;

case access_address(3 downto 2) is

when "00" => pci_state_mashine <= 8;

ad(7 downto 0) <= d;

iord <= '0';

ws_cntr <= 0;

when "01" => NULL;

when "10" => NULL;

when others=> NULL;

end case;

end if;

when 8 => ad(7 downto 0) <= d;

case ws_cntr is

when 6 => --trdy <= transport '0' after 6 ns;

--stop <= transport '0' after 6 ns;

trdy <= '0' after 6 ns;

stop <= '0' after 6 ns;

when 7 => --trdy <= transport '1' after 6 ns;

--stop <= transport '1' after 6 ns;

--devsel <= transport '1' after 6 ns;

trdy <= '1' after 6 ns;

stop <= '1' after 6 ns;

devsel <= '1' after 6 ns;

if irdy='0'

then pci_state_mashine <= 7;

end if;

when others => NULL;

end case;

 

----------- i/o write

when 4 => if access_address(15 downto 8)=bar0

then --devsel <= transport '0' after 6 ns;

--trdy <= transport '0' after 6 ns;

--stop <= transport '0' after 6 ns;

devsel <= '0' after 6 ns;

trdy <= '0' after 6 ns;

stop <= '0' after 6 ns;

pci_state_mashine <= 6;

case access_address(3 downto 2) is

when "00" => d <= ad(7 downto 0);

iowr <= '0';

ws_cntr <= 0;

when "01" => NULL;

when "10" => NULL;

when others => NULL;

end case;

end if;

 

---- DEASSERT ALL SIGNALS

when 5|6 => --devsel <= transport '1' after 6 ns;

-- trdy <= transport '1' after 6 ns;

-- stop <= transport '1' after 6 ns;

devsel <= '1' after 6 ns;

trdy <= '1' after 6 ns;

stop <= '1' after 6 ns;

if irdy <= '0'

then pci_state_mashine <= 7;

end if;

iord <= '1';

 

---- TRISTATE ALL SIGNALS

when 7 => pci_state_mashine <= 0;

ad <= (others =>'Z');

devsel <= 'Z';

trdy <= 'Z';

stop <= 'Z';

iord <= '1';

 

when others => NULL;

end case;

 

---- end of the i/o write operation

case ws_cntr is

when 8 => iowr <= '1';

when 9 => iocs <= '1';

d <= "ZZZZZZZZ";

when others => NULL;

end case;

 

end process;

 

END rtl;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не грузите пожалуйста длинный код, используйте вставку файла. Воспользуйтесь кнопкой EDIT и сами отредактируйте сообщение. Пожалуйста!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...