PCIãã¹ã«ã¯å€ãã®ãã©ã³ã¶ã¯ã·ã§ã³ããããŸããããã®ãããã¯ã§ã¯ä»¥äžã«ã€ããŠã®ã¿èª¬æããŸãã
- æ§æãã©ã³ã¶ã¯ã·ã§ã³
- I / Oãã©ã³ã¶ã¯ã·ã§ã³
- ã¡ã¢ãªã¢ã¯ã»ã¹ãã©ã³ã¶ã¯ã·ã§ã³
ãã©ã³ã¶ã¯ã·ã§ã³ãè¡ãå Žåã2ã€ã®ãªãã·ã§ã³ãå¯èœã§ãã
- ãã¹ã¿ãŒããµãŠã¹ããªããžã®å Žå
- ãã¹ã¿ãŒãPCIãã¹ã«æ¥ç¶ãããŠããããã€ã¹ã®å Žå
ãã§ã«èµ·ãã£ãããã«ãPCIãã¹ãæ€èšããå Žåããã¹ã¿ãŒããã€ã¹ããã¹ã¿ãŒãã¹ã¬ãŒãããã€ã¹ãã¿ãŒã²ããïŒã¿ãŒã²ããïŒãšåŒã³ãŸãã
ãã¹ã¿ãŒãPCIãã¹ã«æ¥ç¶ãããããã€ã¹ã§ããå Žåã®ãã©ã³ã¶ã¯ã·ã§ã³ã¯å¥ã®èšäºã«å€ããããããã®èšäºã§ã¯ãã¹ã¿ãŒããµãŠã¹ããªããžã®å Žåã®ãã©ã³ã¶ã¯ã·ã§ã³ã®ã¿ãæ±ããŸãã
ãããã£ãŠããã¹ã䜿çšããã«ã¯ã次ã®ä¿¡å·ãå¿ èŠã§ãã
entity main is Port ( clk : in std_logic; AD : inout std_logic_vector(31 downto 0); IDSEL : in std_logic; CBE : in std_logic_vector(3 downto 0); FRAME : in std_logic; IRDY : in std_logic; TRDY : inout std_logic; STOP : inout std_logic; PAR : inout std_logic; RST : in std_logic; DEVSEL : inout std_logic ); end main;
clkïŒã¯ããã¯ïŒ-PCIäžã®ãã¹ãŠã®ãã©ã³ã¶ã¯ã·ã§ã³ã®åæãæäŸããåPCIããã€ã¹ã®å ¥åã§ããããŸãã
ADïŒã¢ãã¬ã¹ãšããŒã¿ïŒ-ãã¹ã®ã¢ãã¬ã¹ãšããŒã¿ãå€éåããŸãã
IDSELïŒåæåããã€ã¹éžæïŒ-åæåããã€ã¹ã®éžæãæ§æã®èªã¿åãããã³æžã蟌ã¿ãã©ã³ã¶ã¯ã·ã§ã³äžã«ããããéžæããããã«äœ¿çšãããŸãã
CBEïŒãã¹ã³ãã³ãããã³ãã€ãã€ããŒãã«ïŒ-ãã¹ã³ãã³ãããã³ãã€ã解å床ã
FRAMEïŒãã¬ãŒã ïŒ-ãã©ã³ã¶ã¯ã·ã§ã³ã®éå§æã«ãã¹ã¿ãŒã«ãã£ãŠä¿¡å·ãçºè¡ããããã®æéã決å®ãããŸãã åçžãã©ã³ã¶ã¯ã·ã§ã³ã®å ŽåãFRAMEã¯åžžã«1ã¯ããã¯ãµã€ã¯ã«ç¶ããŸãã ãã«ããã§ãŒãºãã©ã³ã¶ã¯ã·ã§ã³ã§ã¯ããã©ã³ã¶ã¯ã·ã§ã³ãå®äºãã1ãµã€ã¯ã«åã«FRAMEãåé€ãããŸãã
IRDYïŒã€ãã·ãšãŒã¿ãŒæºåå®äºïŒ-ãã¹ã¿ãŒã®æºåå®äºã®ã·ã°ãã«ã ãŠã£ã¶ãŒããçŸåšã®ããŒã¿ãã§ãŒãºãå®äºããææãããããšã瀺ããŸãã
TRDYïŒã¿ãŒã²ããæºåå®äºïŒ-ã¿ãŒã²ããã®æºåå®äºã®ä¿¡å·ãçŸåšã®ããŒã¿ãã§ãŒãºãå®äºããããã®ã¿ãŒã²ããæºåå®äºã瀺ããŸãã
STOPïŒåæ¢ïŒ-ãã®ã·ã°ãã«ã¯ãã¿ãŒã²ãããçŸåšã®ãã©ã³ã¶ã¯ã·ã§ã³ãåæ¢ããå Žåã«çºè¡ãããŸãã
PARïŒããªãã£ïŒ-ADããã³CBEåç·ã®ããªãã£ã
RSTïŒãªã»ããïŒ-ãªã»ããä¿¡å·ã éåæã§ãã
DEVSELïŒããã€ã¹éžæïŒ-ããã€ã¹éžæä¿¡å·ã
ããã€ã¹ãæäœããåã«ãåæåããå¿ èŠããããŸãã ãããã£ãŠãæ§æãã©ã³ã¶ã¯ã·ã§ã³å®è¡ã®æ©èœãæ€èšããŸãã
æ§æãã©ã³ã¶ã¯ã·ã§ã³ äžè¬çãªæ å ±ã
OSããã®æ§æãã©ã³ã¶ã¯ã·ã§ã³ã®ãã¥ãŒ
PCã§PCIæ§æãã©ã³ã¶ã¯ã·ã§ã³ãçæããã«ã¯ãCONFIG_ADDRESSããã³CONFIG_DATAãšããååã®2ã€ã®I / OããŒããåŒã³åºããããããã¢ãã¬ã¹0CF8hããã³0CFChã䜿çšããPCIãã¹ãããã»ããµã«çŽæ¥ãŸãã¯éæ¥çã«æ¥ç¶ãããã¹ã-PCIããªããžã«å«ããŸãã
CONFIG_ADDRESSããŒãã®ãµã€ãºã¯ããã«ã¯ãŒãã§ããããŠããããšããŠã®ã¿äœ¿çšå¯èœã§ãã ããã«å±ããã¢ãã¬ã¹ãžã®ããå°ããåŒã³åºãã¯ãéåžžã®I / Oãã©ã³ã¶ã¯ã·ã§ã³ãšããŠPCIãã¹ã«è»¢éãããŸãã ãã®ããŒãã¯èªã¿åããšæžã蟌ã¿ãå¯èœã§ã次ã®åœ¢åŒããããŸãã
æ§æãã©ã³ã¶ã¯ã·ã§ã³ãå®è¡ããå¿ èŠãããå ŽåãPCIæ§æã¹ããŒã¹ã¬ãžã¹ã¿ã®ã¢ãã¬ã¹ããã®ããŒãã«æžã蟌ãŸãããã¹çªå·ïŒããã23ã16ïŒãããã€ã¹ïŒ15ã11ïŒãæ©èœïŒ10ã8ïŒãããã³ã¬ãžã¹ã¿èªäœïŒ7ã2ïŒã§æ§æãããŸãã ããã1ãš0ã«ã¯åžžã«ãŒããå«ãŸããæäžäœãããã«ã¯1ãå«ãŸããŠããå¿ èŠããããŸããããã«ãããæ§æãã©ã³ã¶ã¯ã·ã§ã³ã®å®è¡ãå¯èœã«ãªããŸãã æ¡30ã24ã¯äºçŽãããŠããããŒããå«ããå¿ èŠããããŸãã
å®éã«ã¯ãæ§æãã©ã³ã¶ã¯ã·ã§ã³ã¯ãCONFIG_DATAããŒãã®èªã¿åããŸãã¯æžã蟌ã¿ããã¹ã-PCIããªããžããŸãã¯ãã®ãã¹ã®äžã«ãããCONFIG_ADDRESSãä»ããŠæ¥ç¶ãããŠããPCIãã¹ã«å¯Ÿå¿ãããã¹ã«å¯Ÿå¿ããèšå®ãããããããšãã¹çªå·ãæã€ã¢ãã¬ã¹ãæžã蟌ãŸãããšãã«çæãããŸã1ã€ãŸãã¯è€æ°ã®PCI â PCIããªããžïŒãã¹çªå·ã®æå¹ç¯å²ã¯ãæ§æäžã«ãã¹ãâ PCIããªããžã«ãã£ãŠæå®ãããŸãïŒã CONFIG_DATAããŒããžã®ã¢ã¯ã»ã¹ã¯ãã¢ãã¬ã¹ãCONFIG_ADDRESSã«ããèªã¿åããŸãã¯æžã蟌ã¿æ§æã¬ãžã¹ã¿ãšåããµã€ãºã§ãªããã°ãªããŸããã
CONFIG_ADDRESSã§æå®ããããã¹çªå·ããã¹ã-PCIããªããžã«çŽæ¥æ¥ç¶ãããŠãããã¹ã®çªå·ãšäžèŽããå Žåãã¿ã€ã0ã®ã¢ãã¬ã¹ãæã€æ§æãã©ã³ã¶ã¯ã·ã§ã³ãçæãããCONFIG_ADDRESSããŒãã®ããã15ã11ã«ããããã€ã¹çªå·ãIDSELä¿¡å·ã®1ã€ãçºè¡ããããã«äœ¿çšãããŸããç¹å®ã®ããã€ã¹ãéžæããããã«äœ¿çšãããŸãã ããã«ãæ§æãã©ã³ã¶ã¯ã·ã§ã³ã®ã¢ãã¬ã¹ãã§ãŒãºã§ãã³ãŒããããããã€ã¹çªå·ïŒ1ãŠããããšæ®ãã®ãŒããããïŒã¯ãã¢ãã¬ã¹ã®ããã31ã11ã§éä¿¡ãããŸãã
CONFIG_ADDRESSã®ã¢ãã¬ã¹ãããã¹ã-PCIããªããžã«çŽæ¥æ¥ç¶ãããŠããééã£ããã¹ã瀺ããŠããå ŽåãåŸè ã¯ã¿ã€ã1ã®ã¢ãã¬ã¹ã§æ§æãã©ã³ã¶ã¯ã·ã§ã³ãçæããŸããã¢ãã¬ã¹ã«å«ãŸãããã¹çªå·ãèªèããPCI-PCIããªããžã«ãã£ãŠåŠçãããŸãã ãã®ããªããžã¯ãã¿ã€ã0ã®ã¢ãã¬ã¹ã§æ§æãã©ã³ã¶ã¯ã·ã§ã³ãå®è¡ããŸãïŒã¢ãã¬ã¹æå®ãããããã€ã¹ããã®ããªããžã«çŽæ¥æ¥ç¶ããããã¹ã«æ¥ç¶ãããŠããå ŽåïŒããŸãã¯ã¿ã€ã1ã®ã¢ãã¬ã¹ã§ãã©ã³ã¶ã¯ã·ã§ã³ãçæããããšã«ããã次ã®ããªããžãééããããã«ããŸã ãã®ãã§ãŒã³ã®é·ãã¯ãçè«çã«ã¯ãã¹çªå·ïŒ8ãããïŒã«å²ãåœãŠããããã£ãŒã«ãã®ããã深床ã«ãã£ãŠã®ã¿å¶éãããŸãã
ãã©ã³ã¶ã¯ã·ã§ã³äžã«æ§æã¬ãžã¹ã¿ã®ã¢ãã¬ã¹ãååšããªãããšãå€æããå ŽåïŒååšããªããã¹ãããã€ã¹ãæ©èœããŸãã¯ã¬ãžã¹ã¿ã®çªå·ã瀺ãããŠããïŒãæžã蟌ã¿æäœã¯äœã®ã¢ã¯ã·ã§ã³ãå®è¡ãããèªã¿åãæäœã¯åã«ããŽãªã®ãŠããããå«ãå€ãããã»ããµã«è¿ããŸã
ãã©ã³ã¶ã¯ã·ã§ã³ã¿ã€ã1ã®ã¢ãã¬ã¹åœ¢åŒã
ãã©ã³ã¶ã¯ã·ã§ã³ã®ã¢ãã¬ã¹åœ¢åŒã¯ã¿ã€ã0ã§ãã
CONFIG_ADDRESSããŒãã®ãµã€ãºã¯ããã«ã¯ãŒãã§ããããŠããããšããŠã®ã¿äœ¿çšå¯èœã§ãã ããã«å±ããã¢ãã¬ã¹ãžã®ããå°ããåŒã³åºãã¯ãéåžžã®I / Oãã©ã³ã¶ã¯ã·ã§ã³ãšããŠPCIãã¹ã«è»¢éãããŸãã ãã®ããŒãã¯èªã¿åããšæžã蟌ã¿ãå¯èœã§ã次ã®åœ¢åŒããããŸãã
æ§æãã©ã³ã¶ã¯ã·ã§ã³ãå®è¡ããå¿ èŠãããå ŽåãPCIæ§æã¹ããŒã¹ã¬ãžã¹ã¿ã®ã¢ãã¬ã¹ããã®ããŒãã«æžã蟌ãŸãããã¹çªå·ïŒããã23ã16ïŒãããã€ã¹ïŒ15ã11ïŒãæ©èœïŒ10ã8ïŒãããã³ã¬ãžã¹ã¿èªäœïŒ7ã2ïŒã§æ§æãããŸãã ããã1ãš0ã«ã¯åžžã«ãŒããå«ãŸããæäžäœãããã«ã¯1ãå«ãŸããŠããå¿ èŠããããŸããããã«ãããæ§æãã©ã³ã¶ã¯ã·ã§ã³ã®å®è¡ãå¯èœã«ãªããŸãã æ¡30ã24ã¯äºçŽãããŠããããŒããå«ããå¿ èŠããããŸãã
å®éã«ã¯ãæ§æãã©ã³ã¶ã¯ã·ã§ã³ã¯ãCONFIG_DATAããŒãã®èªã¿åããŸãã¯æžã蟌ã¿ããã¹ã-PCIããªããžããŸãã¯ãã®ãã¹ã®äžã«ãããCONFIG_ADDRESSãä»ããŠæ¥ç¶ãããŠããPCIãã¹ã«å¯Ÿå¿ãããã¹ã«å¯Ÿå¿ããèšå®ãããããããšãã¹çªå·ãæã€ã¢ãã¬ã¹ãæžã蟌ãŸãããšãã«çæãããŸã1ã€ãŸãã¯è€æ°ã®PCI â PCIããªããžïŒãã¹çªå·ã®æå¹ç¯å²ã¯ãæ§æäžã«ãã¹ãâ PCIããªããžã«ãã£ãŠæå®ãããŸãïŒã CONFIG_DATAããŒããžã®ã¢ã¯ã»ã¹ã¯ãã¢ãã¬ã¹ãCONFIG_ADDRESSã«ããèªã¿åããŸãã¯æžã蟌ã¿æ§æã¬ãžã¹ã¿ãšåããµã€ãºã§ãªããã°ãªããŸããã
CONFIG_ADDRESSã§æå®ããããã¹çªå·ããã¹ã-PCIããªããžã«çŽæ¥æ¥ç¶ãããŠãããã¹ã®çªå·ãšäžèŽããå Žåãã¿ã€ã0ã®ã¢ãã¬ã¹ãæã€æ§æãã©ã³ã¶ã¯ã·ã§ã³ãçæãããCONFIG_ADDRESSããŒãã®ããã15ã11ã«ããããã€ã¹çªå·ãIDSELä¿¡å·ã®1ã€ãçºè¡ããããã«äœ¿çšãããŸããç¹å®ã®ããã€ã¹ãéžæããããã«äœ¿çšãããŸãã ããã«ãæ§æãã©ã³ã¶ã¯ã·ã§ã³ã®ã¢ãã¬ã¹ãã§ãŒãºã§ãã³ãŒããããããã€ã¹çªå·ïŒ1ãŠããããšæ®ãã®ãŒããããïŒã¯ãã¢ãã¬ã¹ã®ããã31ã11ã§éä¿¡ãããŸãã
CONFIG_ADDRESSã®ã¢ãã¬ã¹ãããã¹ã-PCIããªããžã«çŽæ¥æ¥ç¶ãããŠããééã£ããã¹ã瀺ããŠããå ŽåãåŸè ã¯ã¿ã€ã1ã®ã¢ãã¬ã¹ã§æ§æãã©ã³ã¶ã¯ã·ã§ã³ãçæããŸããã¢ãã¬ã¹ã«å«ãŸãããã¹çªå·ãèªèããPCI-PCIããªããžã«ãã£ãŠåŠçãããŸãã ãã®ããªããžã¯ãã¿ã€ã0ã®ã¢ãã¬ã¹ã§æ§æãã©ã³ã¶ã¯ã·ã§ã³ãå®è¡ããŸãïŒã¢ãã¬ã¹æå®ãããããã€ã¹ããã®ããªããžã«çŽæ¥æ¥ç¶ããããã¹ã«æ¥ç¶ãããŠããå ŽåïŒããŸãã¯ã¿ã€ã1ã®ã¢ãã¬ã¹ã§ãã©ã³ã¶ã¯ã·ã§ã³ãçæããããšã«ããã次ã®ããªããžãééããããã«ããŸã ãã®ãã§ãŒã³ã®é·ãã¯ãçè«çã«ã¯ãã¹çªå·ïŒ8ãããïŒã«å²ãåœãŠããããã£ãŒã«ãã®ããã深床ã«ãã£ãŠã®ã¿å¶éãããŸãã
ãã©ã³ã¶ã¯ã·ã§ã³äžã«æ§æã¬ãžã¹ã¿ã®ã¢ãã¬ã¹ãååšããªãããšãå€æããå ŽåïŒååšããªããã¹ãããã€ã¹ãæ©èœããŸãã¯ã¬ãžã¹ã¿ã®çªå·ã瀺ãããŠããïŒãæžã蟌ã¿æäœã¯äœã®ã¢ã¯ã·ã§ã³ãå®è¡ãããèªã¿åãæäœã¯åã«ããŽãªã®ãŠããããå«ãå€ãããã»ããµã«è¿ããŸã
ãã©ã³ã¶ã¯ã·ã§ã³ã¿ã€ã1ã®ã¢ãã¬ã¹åœ¢åŒã
ãã©ã³ã¶ã¯ã·ã§ã³ã®ã¢ãã¬ã¹åœ¢åŒã¯ã¿ã€ã0ã§ãã
æ§æã¬ãžã¹ã¿ã®åœ¢åŒïŒ
ã¬ãžã¹ã¿ã®æå°ã»ããïŒ
- ãã³ããŒID-ãã£ãŒã«ãã¯ããã€ã¹ã®ã¡ãŒã«ãŒãèå¥ããŸãã å€0xFFFFã䜿çšããããšã¯çŠæ¢ãããŠããŸãã
- ããã€ã¹ID-ãã£ãŒã«ãã¯ç¹å®ã®ã¿ã€ãã®ããã€ã¹ãèå¥ããŸãã å€0xFFFFã䜿çšããããšã¯çŠæ¢ãããŠããŸãã
- ãªããžã§ã³ID-ããã€ã¹èå¥åãžã®è¿œå ã ãŒãã«ãªãå ŽåããããŸãã
- ããããŒã¿ã€ã-å€æ©èœããã€ã¹çšã 7çªç®ã®ãããã0ã®å Žåãããã€ã¹ã¯åæ©èœã§ããã以å€ã®å Žåã¯å€æ©èœã§ãã
- ã¯ã©ã¹ã³ãŒã-èªã¿åãå°çš ããã€ã¹ã®äžè¬çãªæ©èœãèå¥ããããã«äœ¿çšãããŸãã äžäœãã€ãïŒã¢ãã¬ã¹0BhïŒã¯åºæ¬ã¯ã©ã¹ãå®çŸ©ããäžå€®ã¯ãµãã¯ã©ã¹ãäžäœã¯ããã°ã©ã ã€ã³ã¿ãŒãã§ã€ã¹ïŒæšæºåãããŠããå ŽåïŒãå®çŸ©ããŸãã
- ãµãã·ã¹ãã IDããµãã·ã¹ãã ãã³ããŒID-ã¡ãŒã«ãŒã«ãã£ãŠèšå®ãããŸãã èªã¿åãå°çš ã«ãŒããšããã€ã¹ã®æ£ç¢ºãªèå¥ãå¯èœã«ããèå¥åãä¿åããŸãïŒã·ã¹ãã ã«ã€ã³ã¹ããŒã«å¯èœïŒ
äžèŽããããã€ã¹ããã³ã¡ãŒã«ãŒIDïŒããã€ã¹IDããã³ãã³ããŒIDïŒãæã€è€æ°ã®ã«ãŒãã - BAR0-BAR5-ã¡ã¢ãªããã³å ¥å/åºåããŒãã«ã€ããŠèª¬æããŸãã
ã¡ã¢ãªé åãšããŒãã®èª¬æã¯ç°ãªããŸãïŒ
- ããã0 = 0ã¯ã¡ã¢ãªã®å åã§ãã ãµã€ãºã2 GB以äž
- ããã0 = 1-ããŒããšãªã¢ã®ãµã€ã³ã æ倧256ãã€ãã®ãµã€ãºã
ãšãªã¢ã®ãµã€ãºã¯æ¬¡ã®ããã«èšç®ãããŸãã 0xFFFFFFFFãBARã«æžã蟌ãŸããŸãã 次ã«ãBARããå€ãèªã¿åããã0xFFFFFFFFããæžç®ãããŸãã çµæã¯ãé åã®ãµã€ãºã§ãã äžäœãããã®åäœã¯èæ ®ãããŸããã
äžè¬çãªååŒã¢ã«ãŽãªãºã
ãã¹ã¿ãŒã¯ãADãã¹äžã®ããã€ã¹ã¢ãã¬ã¹ãCBEãã¹äžã§å®è¡ãããã³ãã³ããå ¬éããFRAMEä¿¡å·ã0ã«èšå®ããIRDYä¿¡å·ã0ã«èšå®ããŸãã次ã«ããã¹ã¿ãŒã¯ã¿ãŒã²ãããTRDYããã³DEVSELä¿¡å·ãèšå®ããã®ãåŸ ã¡ãŸãã ãŸããã¿ãŒã²ããã¯ãèŠæ±ãããããŒã¿ãADãã¹ã«å ¬éããŸãã ããŒã¿ã¯ãIRDYãTRDYãããã³DEVSELãè«çãŒãã®ãšãã«æå¹ãšèŠãªãããŸãã
å®è£
FPGAã®çµè«ã«ã¢ã¯ã»ã¹ããã«ã¯ãç¹å¥ãªã³ã³ããŒãã³ããå¿ èŠã§ããZ-ç¶æ ãæäœããããã®I / Oãããã¡ãŒã
ãããã£ãŠãADãã¹ã®å Žåãæ¥ç¶ã¯æ¬¡ã®ããã«ãªããŸãã
signal AD_I: std_logic_vector (AD'range); signal AD_O: std_logic_vector (AD'range); signal AD_T: std_logic; AD_BUF: for iCount in AD'low to AD'high generate begin IOBUF_AD : IOBUF generic map ( DRIVE => 12, IOSTANDARD => "PCI33_3", SLEW => "SLOW") port map ( O => AD_I(iCount), IO => AD(iCount), I => AD_O(iCount), T => AD_T ); end generate;
ã©ãã§
- O-ãããã¡åºåã
- IO-FPGAãã³ã«çŽæ¥æ¥ç¶ããããããã¡ã®å ¥å/åºåã
- I-ãããã¡åºåã
- T-å ¥åå¶åŸ¡ããŠãããã¬ãã«-å ¥åããŒãã¬ãã«-åºåã
æ®ãã®ä¿¡å·ã«ã€ããŠãåæ§ã«ãèšäºãç ©éã«ããªãããã«åŒçšããŸããã
äžèšã§æžããããã«ããã©ã³ã¶ã¯ã·ã§ã³ã®éå§æã«ãADãã¹ã«ã¢ãã¬ã¹ãèšå®ããããšãFRAMEä¿¡å·ã¯åžžã«ãŒãã«ãªããŸãã 以äžã¯ãAdrPhASEä¿¡å·ãçæããã³ãŒãã§ãããã®éãåŸã®äœæ¥ã®ããã«ã¢ãã¬ã¹ãã¹ãšã³ãã³ããã¹ãã¯ãªãã¯ããå¿ èŠããããŸãã å®éãAdrPhASEä¿¡å·ã¯ããã©ã³ã¶ã¯ã·ã§ã³ã®éå§ãäžæã«èå¥ããFRAMEä¿¡å·ã®ç«ã¡äžãããšããžã«ãããŸããã
signal AdrPhASE: std_logic; signal FRAME_D: std_logic; signal Addres: std_logic_vector(AD_I'range); signal Command: std_logic_vector(CBE'range); signal bCfgTr: boolean; process (clk_i, RST_I) begin if (RST_I = '0') then FRAME_D <= '1' after cTCQ; elsif (rising_edge(clk_I)) then FRAME_D <= FRAME_I after cTCQ; end if; end process; AdrPhASE <= not FRAME_I and FRAME_D; process (clk_I, RST_I) begin if (RST_I = '0') then Address <= (others => '0') after cTCQ; Command <= (others => '0') after cTCQ; bCfgTr <= false after cTCQ; elsif (rising_edge(clk_I)) then if (AdrPhASE = '1') then Address <= AD_I after cTCQ; Command <= CBE_I after cTCQ; bCfgTr <= (IDSEL_I = '1') after cTCQ; end if; end if; end process;
ããã«ãè£ çœ®å šäœã®åäœãæ©æ¢°ã䜿çšããŠèª¬æã§ããŸãã
æ©æ¢°ã³ãŒã
type TSM_PCI_T is (sIDLE, sDECODE, sCFG_READ, sCFG_WRITE, sIO_READ, sIO_WRITE, sMEM_READ, sMEM_WRITE); signal smPCI_T: TSM_PCI_T; process(clk_I, RST_I) begin if (RST_I = '0') then smPCI_T <= sIDLE after cTCQ; elsif (rising_edge(clk_I)) then case (smPCI_T) is when sIDLE => if (AdrPhASE = '1') then smPCI_T <= sDECODE after cTCQ; end if; when sDECODE => if (bCfgTr and Address(10 downto 8) = b"000" and Command(3 downto 1) = b"101") then if (Command(0) = '0') then smPCI_T <= sCFG_READ after cTCQ; else smPCI_T <= sCFG_WRITE after cTCQ; end if; elsif (Command(3 downto 1)= b"001") and (Addres(31 downto 8) = BAR0(31 downto 8))then if (Command(0) = '0') then smPCI_T <= sIO_READ after cTCQ; else smPCI_T <= sIO_WRITE after cTCQ; end if; elsif (Command(3 downto 1) = b"011") and (Addres(31 downto 16) = BAR1(31 downto 16)) then if (Command(0) = '0') then smPCI_T <= sMEM_READ after cTCQ; else smPCI_T <= sMEM_WRITE after cTCQ; end if; else smPCI_T <= sIDLE after cTCQ; end if; when sCFG_READ => if (IRDY_I = '0') then smPCI_T <= sIDLE after cTCQ; end if; when sCFG_WRITE => if (IRDY_I = '0') then smPCI_T <= sIDLE after cTCQ; end if; when sIO_WRITE => if (IRDY_I = '0') then smPCI_T <= sIDLE after cTCQ; end if; when sIO_READ => if (IRDY_I = '0') then smPCI_T <= sIDLE after cTCQ; end if; when sMEM_READ => if (IRDY_I = '0') then smPCI_T <= sIDLE after cTCQ; end if; when sMEM_WRITE => if (IRDY_I = '0') then smPCI_T <= sIDLE after cTCQ; end if; when others => smPCI_T <= sIDLE after cTCQ; end case; end if; end process;
äžèšãç解ããããã«ãCBEãã¹çµç±ã§éä¿¡ãããå¯èœæ§ã®ããã³ãã³ãã瀺ããŸãã
- 0010 I / Oèªã¿åã
- 0011 I / Oæžã蟌ã¿
- 0110ã¡ã¢ãªãŒèªã¿åã
- 0111ã¡ã¢ãªæžã蟌ã¿
- 1010æ§æã®èªã¿åã
- 1011æ§æã®æžã蟌ã¿
åããŒã ã«ã¯ããã·ã³ã®ç¬èªã®ç¶æ ããããŸãã ãããžã®ç§»è¡ã¯ãã¡ã¢ãªããã³I / OããŒãã«ã¢ã¯ã»ã¹ãããã©ã³ã¶ã¯ã·ã§ã³ã®CBEãã¹ãšADãã¹ã®çŸåšã®ç¶æ ã«äŸåããŸãã ãã¹ã¿ãŒããIRDYä¿¡å·ãåä¿¡ãããšãåæç¶æ ãžã®åºå£ãå®è¡ãããŸãã
èšå®ãèªã
åè¿°ã®ããã«ãããã€ã¹ã®åŠçã«ã¯ã¿ã€ã0ã®ãã©ã³ã¶ã¯ã·ã§ã³ã䜿çšãããŸãããããã€ã¹ã¯åæ©èœã§ãããããæ©èœçªå·ã¯000ã§ãããå¶åŸ¡ãã·ã³ã§ãã§ãã¯ãããŸãã ã¬ãžã¹ã¿çªå·ïŒADãã¹ã®ããã7..0ïŒã«å¿ããŠãç®çã®ã¬ãžã¹ã¿ãäžã®å³ã«åŸã£ãŠADãã¹ã«çºè¡ãããŸãã
æ§æèªã¿åãã³ãŒã
signal CfgRData: std_logic_vector(31 downto 0):=x"00000000"; signal CommandReg: std_logic_vector(15 downto 0) := x"0000"; signal StatusReg: std_logic_vector(15 downto 0) := x"0200"; signal LatencyTimer: std_logic_vector(7 downto 0) := x"00"; signal CacheLineSize: std_logic_vector(7 downto 0) := x"00"; signal BAR0: std_logic_vector(31 downto 0) := x"00000001"; signal BAR1: std_logic_vector(31 downto 0) := x"00000000"; signal InterruptLine: std_logic_vector(7 downto 0); process (clk_I) begin if (rising_edge(clk_I)) then case (Address(7 downto 0)) is when x"00" => CfgRData <= x"00017788" ; --Device ID and Vendor ID when x"04" => CfgRData <= StatusReg & CommandReg; --Status Register, Command Register when x"08" => CfgRData <= x"10000001"; -- Class Code and Revision ID when x"0C" => CfgRData <= x"0000" & LatencyTimer & CacheLineSize; -- BIST, Header Type(bit 7 = 0, single, bits 6-0 = 0, type0), Latency Timer(for masters), Cache Line Size (bit 2 in 1) when x"10" => CfgRData <= BAR0; -- Base Adress 0 (Register IO address decoder) when x"14" => CfgRData <= BAR1; -- Base Adress 1 when x"28" => CfgRData <= x"00000000"; -- CarfdBus CIS Pointer when x"2C" => CfgRData <= x"00017788"; -- Subsystem ID, Subsystem Vendor ID when x"30" => CfgRData <= x"00000000"; -- Expanxion Rom Base Address when x"34" => CfgRData <= x"00000000"; -- Reserved, Capabilitis Pointer when x"38" => CfgRData <= x"00000000"; -- Reserved when x"3C" => CfgRData <= x"004001" & InterruptLine; -- Max_Lat(only bus master), Min_Gnt, Interrupt Pin, Interrupt Line when others => CfgRData <= (others => '0'); end case; end if; end process;
ããã¯ãã·ãã¥ã¬ãŒã¿ãŒã§æ§æãèªã¿åãæ¹æ³ã§ãã
æ§æã¬ã³ãŒã
ADãã¹ã§ã¯ããã¹ã¿ãŒãèšé²çšã®ã¬ãžã¹ã¿ã¢ãã¬ã¹ãèšå®ãã次ã®ã¯ããã¯ãµã€ã¯ã«ã§ãæžã蟌ãŸããããŒã¿ãèšå®ãããŸãã BAR0ã§ã¯ãããã7..0ã¯èªã¿åãå°çšã§ãBAR1ã§ã¯ãããã15..0ã¯èªã¿åãå°çšã§ãã ãããã£ãŠãI / Oã¢ãã¬ã¹ã¯256ãã¡ã¢ãªã¢ãã¬ã¹ã¯4,294,967,296ã§ãã
æ§æã¬ã³ãŒãã³ãŒã
process(clk_I, RST_I) begin if(RST_I = '0')then CommandReg <= x"0000" after cTCQ; StatusReg <= x"0200" after cTCQ; LatencyTimer <= x"00" after cTCQ; CacheLineSize <= x"00" after cTCQ; BAR0 <= x"00000001" after cTCQ; BAR1 <= x"00000000" after cTCQ; elsif(rising_edge(clk_I)) then if (smPCI_T = sCFG_WRITE) then case(Address(7 downto 0)) is when x"04" => if (CBE_I(1) = '0') then CommandReg(15 downto 8) <= AD_I(15 downto 8) after cTCQ; end if; if (CBE_I(0) = '0') then CommandReg(7 downto 0) <= AD_I(7 downto 0) after cTCQ; end if; when x"0C" => if (CBE_I(1) = '0') then LatencyTimer <= AD_I(15 downto 8) after cTCQ; end if; if (CBE_I(0) = '0') then CacheLineSize <= AD_I(7 downto 0) after cTCQ; end if; when x"10" => if (CBE_I(3) = '0') then BAR0(31 downto 24) <= AD_I(31 downto 24) after cTCQ; end if; if (CBE_I(2) = '0') then BAR0(23 downto 16) <= AD_I(23 downto 16) after cTCQ; end if; if (CBE_I(1) = '0') then BAR0(15 downto 8) <= AD_I(15 downto 8) after cTCQ; end if; when x"14" => if (CBE_I(3) = '0') then BAR1(31 downto 24) <= AD_I(31 downto 24) after cTCQ; end if; if (CBE_I(2) = '0') then BAR1(23 downto 16) <= AD_I(23 downto 16) after cTCQ; end if; when x"3C" => if (CBE_I(0) = '0') then InterruptLine <= AD_I(7 downto 0) after cTCQ; end if; when others => null; end case; end if; end if; end process;
ããŒããžã®æžã蟌ã¿
ADãã¹ã§ã¯ããã¹ã¿ãŒãèšé²çšã®ã¬ãžã¹ã¿çªå·ãèšå®ãã次ã®ã¯ããã¯ã§æžã蟌ãŸããããŒã¿ãèšå®ãããŸãã
1ã€ã®ã¬ãžã¹ã¿ãæžã蟌ãããã®äŸã瀺ããŸãããæ®ãã¯åãæ¹æ³ã§æžã蟌ãŸããŸãã
signal IOReg0: std_logic_vector (31 downto 0); process(clk_I, RST_I) begin if(RST_I = '0') then IOReg0 <= x"00000000" after cTCQ; elsif (rising_edge(clk_I)) then if (smPCI_T = sIO_WRITE and Address(7 downto 0) = x"00") then if (CBE_I(0) = '0') then IOReg0( 7 downto 0) <= AD_I( 7 downto 0) after cTCQ; end if; if (CBE_I(1) = '0') then IOReg0(15 downto 8) <= AD_I(15 downto 8) after cTCQ; end if; if (CBE_I(2) = '0') then IOReg0(23 downto 16) <= AD_I(23 downto 16) after cTCQ; end if; if (CBE_I(3) = '0') then IOReg0(31 downto 24) <= AD_I(31 downto 24) after cTCQ; end if; end if; end if; end process;
èªã¿åãããŒã
ADãã¹ã§ã¯ããã¹ã¿ãŒãèªã¿åãã¬ãžã¹ã¿çªå·ãèšå®ããŸãã ãã®åŸãããã€ã¹ã¯èŠæ±ãããããŒã¿ãADãã¹ã«çºè¡ããŸãã
ããŒãèªã¿åãã³ãŒã
signal IORDate: std_logic_vector (31 downto 0); process (clk_I, RST_I) begin if (RST_I = '0') then IORDate <= x"00000000"; elsif (rising_edge(clk_I)) then case (Address(7 downto 0)) is when x"00" => IORDate <= IOReg0 after cTCQ; when x"04" => IORDate <= IOReg1 after cTCQ; when x"08" => IORDate <= IOReg2 after cTCQ; when x"0C" => IORDate <= IOReg3 after cTCQ; when x"10" => IORDate <= IOReg4 after cTCQ; when x"14" => IORDate <= IOReg5 after cTCQ; when x"18" => IORDate <= IOReg6 after cTCQ; when x"1C" => IORDate <= IOReg7 after cTCQ; when x"20" => IORDate <= IOReg8 after cTCQ; when x"24" => IORDate <= IOReg9 after cTCQ; when others => IORDate <= (others => '0'); end case; end if; end process;
ããã¯ãå ¥å/åºåããŒãã®æžã蟌ã¿ããã³èªã¿åãã®æ§åã§ãã
ã¡ã¢ãªã®æžã蟌ã¿ãšèªã¿åã
ADãã¹ã§ã¯ããã¹ã¿ãŒã¯ããŒã¿ãæžã蟌ãã¢ãã¬ã¹ãèšå®ãã次ã®ã¯ããã¯ã§ããŒã¿èªäœãèšå®ããŸãã ADãã¹ã§èªã¿åãå Žåããã¹ã¿ãŒã¯èªã¿åãã¢ãã¬ã¹ãèšå®ããããŒã¿èªäœãADãã¹ãã¿ãŒã²ããã«ããŸãã
ããŒã¿ã¯ããŒãAã®RAMã«æžã蟌ãŸããããŒãBããèªã¿åãããŸãã
ã¡ã¢ãªã¢ã¯ã»ã¹ã³ãŒã
signal RamWrEn: std_logic; signal RamOutputDate: std_logic_vector (31 downto 0); signal RamInputDate: std_logic_vector (31 downto 0); signal RamRst: std_logic := '0'; RAMB16_S36_S36_inst : RAMB16_S36_S36 port map ( DOA => open, -- Port A 32-bit Data Output DOB => RamOutputDate, -- Port B 32-bit Data Output DOPA => open, -- Port A 4-bit Parity Output DOPB => open, -- Port B 4-bit Parity Output ADDRA => Address(8 downto 0), -- Port A 9-bit Address Input ADDRB => Address(8 downto 0), -- Port B 9-bit Address Input CLKA => clk_I, -- Port A Clock CLKB => clk_I, -- Port B Clock DIA => RamInputDate, -- Port A 32-bit Data Input DIB => x"00000000", -- Port B 32-bit Data Input DIPA => x"0", -- Port A 4-bit parity Input DIPB => x"0", -- Port-B 4-bit parity Input ENA => '1', -- Port A RAM Enable Input ENB => '1', -- PortB RAM Enable Input SSRA => '0', -- Port A Synchronous Set/Reset Input SSRB => '0', -- Port B Synchronous Set/Reset Input WEA => RamWrEn, -- Port A Write Enable Input WEB => '0' -- Port B Write Enable Input ); process(clk_I) begin if (rising_edge(clk_I)) then if (RST_I = '1') then RamRst <= '0'; else RamRst <= '1'; end if; end if; end process; process(clk_I, RST_I) begin if(RST_I = '0') then RamInputDate <= (others => '0') after cTCQ; RamWrEn <= '0' after cTCQ; elsif (rising_edge(clk_I)) then if (smPCI_T = sMEM_WRITE) then if (CBE_I(0) = '0') then RamInputDate(7 downto 0) <= AD_I( 7 downto 0) after cTCQ; end if; if (CBE_I(1) = '0') then RamInputDate(15 downto 8) <= AD_I(15 downto 8) after cTCQ; end if; if (CBE_I(2) = '0') then RamInputDate(23 downto 16) <= AD_I(23 downto 16) after cTCQ; end if; if (CBE_I(3) = '0') then RamInputDate(31 downto 24) <= AD_I(31 downto 24) after cTCQ; end if; RamWrEn <= '1' after cTCQ; else RamWrEn <= '0' after cTCQ; end if; end if; end process;
ããã¯ãã·ãã¥ã¬ãŒã¿ãŒã§ã®ã¡ã¢ãªãŒã®æžã蟌ã¿ããã³èªã¿åãã®æ§åã§ãã
ADãã¹äžã®ããŒã¿ã¯æ¬¡ã®ããã«åºåãããŸãã ãã·ã³ã®ç¶æ ã«å¿ããŠã察å¿ããã¬ãžã¹ã¿ãåºåãããã¡ã«æ¥ç¶ãããŸãã
process (clk_I, RST_I) begin if (RST_I = '0') then AD_O <= (others => '0') after cTCQ; elsif (rising_edge(clk_I)) then if (smPCI_T = sCFG_READ) then AD_O <= CfgRData after cTCQ; elsif (smPCI_T = sIO_READ) then AD_O <= IORDate after cTCQ; elsif (smPCI_T = sMEM_READ) then AD_O <= RamOutputDate after cTCQ; end if; end if; end process;
ADãã¹ã«ããŒã¿ãçºè¡ããããã®ã€ããŒãã«ä¿¡å·ã¯ã次ã®ããã«çæãããŸãã
process (clk_I, RST_I) begin if (RST_I = '0') then AD_T <= '1' after cTCQ; elsif (rising_edge(clk_I)) then AD_T <= not b2l(smPCI_T = sCFG_READ or smPCI_T = sIO_READ or smPCI_T = sMEM_READ) after cTCQ; end if; end process;
DEVSELä¿¡å·ã®éçºã®äŸãšããŠãSTSã³ã³ããŒãã³ãã«ã€ããŠãè¿œå ããããšæããŸãã
DEVSEL_STS : entity WORK.componentIO(Behavioral) port map (iD => DEVSEL_O, oT => DEVSEL_T, clk => clk_I, rst => RST_I)
å¶åŸ¡ä¿¡å·ã®ã¢ã¯ãã£ãã¬ãã«ã¯ãŒãã«çãããããZ-ç¶æ ã«åãæ¿ããŠåç·ã解æŸããã«ã¯ããŸãè«çãŠãããã®ã¬ãã«ãçºè¡ããŠãããZ-ç¶æ ã«è»¢éããå¿ èŠããããŸãã
ãããã«
çµè«ãšããŠãPCIãã¹ã§ã®ãã©ã³ã¶ã¯ã·ã§ã³ã®å®è¡ã¯èŠãç®ã»ã©é£ãããããŸããã éçºããããã¡ãŒã ãŠã§ã¢ãFPGAã«ã¢ããããŒããããŸããã FPGAãæèŒããããŒããPCIã¹ãããã«æ¿å ¥ãããã³ã³ãã¥ãŒã¿ãŒã®é»æºããªã³ã«ãªããŸããã ã·ã¹ãã ã¯ããŒããæ€åºãããã®ãã©ã€ããŒãèŠæ±ããŸããã
ããŸãããïŒ :)
drive.google.com/file/d/0B-i4aT8Q0ZNxc1VkV3J2b0dTRlU/view?usp=sharingãããžã§ã¯ãèªäœã xilinx ise 14.2ãéããŸãã