PCI内核源代码说明
Linux系统中列出PCI设备和USB设备的命令详解

Linux系统中列出PCI设备和USB设备的命令详解lspciNAMElspci - 列出所有PCI设备 [[ ]]总览 SYNOPSISlspci [ options ] [[ ]]描述 DESCRIPTIONlspci 是⼀个⽤来显⽰系统中所有PCI总线设备或连接到该总线上的所有设备的⼯具。
为了能使⽤这个命令所有功能,你需要有 linux 2.1.82 或以上版本,⽀持 /proc/bus/pci 接⼝的内核。
在旧版本内核中,PCI⼯具必须使⽤只有root才能执⾏的直接硬件访问,⽽且总是出现竞争状况以及其他问题。
如果你要报告 PCI 设备驱动中,或者是 lspci ⾃⾝的 bugs,请在报告中包含 "lspci -vvx" 的输出。
[[ ]]选项 OPTIONS-v使得 lspci 以冗余模式显⽰所有设备的详细信息。
-vv使得 lspci 以过冗余模式显⽰更详细的信息 (事实上是 PCI 设备能给出的所有东西)。
这些数据的确切意义没有在此⼿册页中解释,如果你想知道更多,请参照 /usr/include/linux/pci.h 或者 PCI 规范。
-n以数字形式显⽰ PCI ⽣产⼚商和设备号,⽽不是在 PCI ID 数据库中查找它们。
-x以⼗六进制显⽰ PCI 配置空间 (configuration space) 的前64个字节映象 (标准头部信息)。
此参数对调试驱动和 lspci 本⾝很有⽤。
-xxx以⼗六进制显⽰所有 PCI 配置空间的映象。
此选项只有 root 可⽤,并且很多 PCI 设备在你试图读取配置空间的未定义部分时会崩溃 (此操作可能不违反PCI标准,但是它⾄少⾮常愚蠢)。
-b以总线为中⼼进⾏查看。
显⽰所有 IRQ 号和内存地址,就象 PCI 总线上的卡看到的⼀样,⽽不是内核看到的内容。
-t以树形⽅式显⽰包含所有总线、桥、设备和它们的连接的图表。
-s [[<bus>]:][<slot>][.[<func>]]仅显⽰指定总线、插槽上的设备或设备上的功能块信息。
一、如何编写LinuxPCI驱动程序

⼀、如何编写LinuxPCI驱动程序PCI的世界是⼴阔的,充满了(⼤部分令⼈不快的)惊喜。
由于每个CPU体系结构实现不同的芯⽚集,并且PCI设备有不同的需求(“特性”),因此Linux内核中的PCI⽀持并不像⼈们希望的那么简单。
这篇简短的⽂章介绍⽤于PCI设备驱动程序的Linux APIs。
1.1 PCI驱动程序结构PCI驱动程序通过pci_register_driver()在系统中"发现"PCI设备。
事实上,恰恰相反。
当PCI通⽤代码发现⼀个新设备时,具有匹配“描述”的驱动程序将被通知。
详情如下。
pci_register_driver()将设备的⼤部分探测留给PCI层,并⽀持在线插⼊/删除设备[因此在单个驱动程序中⽀持热插拔PCI、CardBus和Express-Card]。
pci_register_driver()调⽤需要传⼊⼀个函数指针表,从⽽指⽰驱动程序的更⾼⼀级结构体。
⼀旦驱动程序知道了⼀个PCI设备并获得了所有权,驱动程序通常需要执⾏以下初始化:启⽤设备请求MMIO / IOP资源设置DMA掩码⼤⼩(⽤于⼀致性DMA和流式DMA)分配和初始化共享控制数据(pci_allocate_coherent())访问设备配置空间(如果需要)注册IRQ处理程序(request_irq())初始化non-PCI(即LAN/SCSI/等芯⽚部分)启⽤DMA /处理引擎当使⽤设备完成时,可能需要卸载模块,驱动程序需要采取以下步骤:禁⽌设备产⽣irq释放IRQ (free_irq())停⽌所有DMA活动释放DMA缓冲区(包括流式DMA和⼀致性DMA)从其他⼦系统注销(例如scsi或netdev)释放MMIO / IOP资源禁⽤该设备下⾯⼏节将介绍这些主题中的⼤部分。
其余部分请查看LDD3或<linux/pci.h>。
如果PCI⼦系统没有配置(没有设置CONFIG_PCI),下⾯描述的⼤多数PCI函数都被定义为内联函数,要么完全空,要么只是返回⼀个适当的错误代码,以避免在驱动程序中出现⼤量ifdefs。
PIC单片机的C语言编程指南

PIC单片机的C语言编程指南PIC单片机是一种常用的嵌入式系统开发平台,其具有低功耗、成本低廉、易于编程等优点,在工业自动化、电子设备控制等领域有着广泛应用。
本文将为读者提供一份PIC单片机的C语言编程指南,帮助初学者快速入门并掌握基本的编程技巧。
首先,我们需要了解一些PIC单片机的基本概念。
PIC单片机采用哈佛结构,具有多种型号和系列,每个系列有多个型号可供选择。
不同的型号和系列有不同的特性和功能,因此在编程时需要根据具体的芯片型号进行适配。
PIC单片机的编程语言常用的是C语言,其语法简洁,易于理解和学习,并且具有较高的可移植性。
在编写PIC单片机的C语言程序时,我们需要按照以下步骤进行:1. 引入头文件:使用#include指令引入所需的头文件,头文件包含了定义和声明所需的函数和变量。
3.初始化:在程序开始时对所需的资源进行初始化,包括引脚配置、中断设置、定时器初始化等。
4.主循环:编写主循环代码,其中包括需要重复执行的功能,例如读取传感器数据、处理输入输出等。
5.中断处理:根据需要,编写中断处理函数,处理外部中断、定时器中断等。
6.清理工作:在程序结束时,进行一些清理工作,例如释放资源、关闭设备等。
下面是一个PIC单片机的C语言编程示例:```c#include <xc.h> // 引入XC8编译器的头文件#define LED_PIN RC0 // 定义LED连接的引脚void iniTRISC0=0;//配置RC0引脚为输出模式void maiinit(; // 初始化while(1)LED_PIN=1;//点亮LED__delay_ms(500); // 延时500毫秒LED_PIN=0;//关闭LED__delay_ms(500); // 延时500毫秒}```上述代码实现了一个简单的功能,即使LED灯以500毫秒的间隔交替点亮和关闭。
在程序中,我们首先引入了`<xc.h>`头文件,然后定义了一个宏`LED_PIN`来表示连接LED的RC0引脚。
kernel hacker修炼之道之PCI subsystem(六)

k ernel hacker 修炼之道——李万鹏男儿立志出乡关, 学不成名死不还。
埋骨何须桑梓地, 人生无处不青山。
——西乡隆盛诗k ernel hacker修炼之道之PCI subsystem(六)分类: linux内核编程PCI-e/PCI 2012-02-26 18:39 1072人阅读 评论(3) 收藏举报kernel hacker修炼之道之PCI subsystem(六)作者 李万鹏第二步分析PCI core对PCI device resource的分配,包括:I/O,Memory,在pcibios_init函数中,遍历完PCI tree之后会调用pcibios_resource_survey函数来分配资源:1450void __init pcibios_resource_survey(void)1451{1452 struct pci_bus *b;14531454 /* Allocate and assign resources. If we re-assign everything, then1455 * we skip the allocate phase1456 */1457 list_for_each_entry(b, &pci_root_buses, node)1458 pcibios_allocate_bus_resources(b);14591460 if (!pci_has_flag(PCI_REASSIGN_ALL_RSRC)) {1461 pcibios_allocate_resources(0);1462 pcibios_allocate_resources(1);1463 }14641465 /* Before we start assigning unassigned resource, we try to reserve1466 * the low IO area and the VGA memory area if they intersect the1467 * bus available resources to avoid allocating things on top of them1468 */1469 if (!pci_has_flag(PCI_PROBE_ONLY)) {1470 list_for_each_entry(b, &pci_root_buses, node)1471 pcibios_reserve_legacy_regions(b);1472 }14731474 /* Now, if the platform didn't decide to blindly trust the firmware,1475 * we proceed to assigning things that were left unassigned1476 */1477 if (!pci_has_flag(PCI_PROBE_ONLY)) {1478 pr_debug("PCI: Assigning unassigned resources...\n");1479 pci_assign_unassigned_resources();1480 }14811482 /* Call machine dependent fixup */1483 if (ppc_md.pcibios_fixup)1484 ppc_md.pcibios_fixup();1485}首先给各个bus分配resource,然后再给挂在bus上的各个device分配resource,然后对未成功分配到resource的device进行重新分配。
pci热插拔内核原理

pci热插拔内核原理PCI hot-plug is a technology that allows users to add or remove PCI cards from a computer while it is running. This is useful for servers and other high-availability systems because it allows for maintenance and upgrades without having to shut down the entire system.PCI热拔插是一种技术,允许用户在计算机运行时添加或删除PCI卡。
这对服务器和其他高可用性系统非常有用,因为它允许进行维护和升级,而无需关闭整个系统。
From a kernel perspective, the hot-plug feature is supported by the Linux kernel through the use of the PCI hot-plug driver. This driver handles the communication between the hardware and the kernel, allowing for the seamless addition or removal of PCI cards. When a new card is added, the driver detects it and initializes it so that the system can start using it without any interruption. Similarly, when a card is removed, the driver ensures that the system can continue to function properly without it.从内核的角度来看,热插拔功能是通过Linux内核通过PCI热插拔驱动程序支持的。
linux pci枚举流程

linux pci枚举流程摘要:1.Linux PCI枚举流程简介2.内核空间与用户空间的PCI配置空间3.PCI设备初始化流程4.驱动程序加载与卸载5.实战应用:Linux内核模块开发正文:Linux作为一种开源的操作系统,具有强大的硬件兼容性和丰富的设备驱动支持。
在Linux系统中,PCI(Peripheral Component Interconnect,外围组件互连)设备的枚举和驱动开发是至关重要的。
本文将详细介绍Linux PCI枚举流程,以及与之相关的内核空间与用户空间的PCI配置空间、设备初始化流程、驱动程序加载与卸载等知识点,最后通过实战应用案例,帮助读者更好地理解和掌握Linux内核模块开发。
1.Linux PCI枚举流程简介在Linux系统中,PCI设备的枚举过程主要分为以下几个阶段:(1)PCI配置空间的读取(2)设备驱动程序的加载与初始化(3)设备驱动程序与硬件设备的交互(4)设备驱动程序的卸载2.内核空间与用户空间的PCI配置空间Linux系统中,PCI配置空间分为内核空间和用户空间两部分。
内核空间主要用于操作系统内核对PCI设备的访问和管理,用户空间则用于设备驱动程序对PCI设备的配置和控制。
内核空间的PCI配置空间包括:(1)PCI设备的基本配置寄存器(2)PCI设备的扩展配置寄存器用户空间的PCI配置空间包括:(1)PCI设备的寄存器映射(2)PCI设备的I/O空间映射3.PCI设备初始化流程PCI设备初始化流程主要包括以下几个步骤:(1)设备枚举:操作系统内核通过读取PCI配置空间,获取设备信息。
(2)设备驱动程序加载:根据设备类型和接口,加载相应的设备驱动程序。
(3)设备初始化:设备驱动程序对硬件设备进行初始化,如配置寄存器、中断号等。
(4)设备启动:设备驱动程序发送命令,启动硬件设备。
4.驱动程序加载与卸载在Linux系统中,设备驱动程序的加载与卸载是通过动态链接库实现的。
PIC 单片机的C 语言编程

PIC单片机C语言编程讲义奥科电子工作室(内部资料)2006年元月第一版第1章 PIC 单片机的C 语言编程1.1 PIC 单片机C 语言编程简介用C 语言来开发单片机系统软件最大的好处是编写代码效率高、软件调试直观、维护升级方便、代码的重复利用率高、便于跨平台的代码移植等等,因此C 语言编程在单片机系统设计中已得到越来越广泛的运用。
针对PIC 单片机的软件开发,同样可以用C 语言实现。
但在单片机上用C 语言写程序和在PC 机上写程序绝对不能简单等同。
现在的PC 机资源十分丰富,运算能力强大,因此程序员在写PC 机的应用程序时几乎不用关心编译后的可执行代码在运行过程中需要占用多少系统资源,也基本不用担心运行效率有多高。
写单片机的C 程序最关键的一点是单片机内的资源非常有限,控制的实时性要求又很高,因此,如果没有对单片机体系结构和硬件资源作详尽的了解,以笔者的愚见认为是无法写出高质量实用的C 语言程序。
这就是为什么前面所有章节中的的示范代码全部用基础的汇编指令实现的原因,希望籍此能使读者对PIC 单片机的指令体系和硬件资源有深入了解,在这基础之上再来讨论C 语言编程,就有水到渠成的感觉。
本讲稿围绕中档系列PIC 单片机来展开讨论,Microchip 公司自己没有针对中低档系列PIC单片机的C 语言编译器,但很多专业的第三方公司有众多支持PIC 单片机的C 语言编译器提供,常见的有Hitech、CCS、IAR、Bytecraft 等公司。
其中笔者最常用的是Hitech 公司的PICC 编译器,它稳定可靠,编译生成的代码效率高,在用PIC 单片机进行系统设计和开发的工程师群体中得到广泛认可。
其正式完全版软件需要购置,但在其网站上有限时的试用版供用户评估。
另外,Hitech 公司针对广大PIC 的业余爱好者和初学者还提供了完全免费的学习版PICC-Lite 编译器套件,它的使用方式和完全版相同,只是支持的PIC 单片机型号限制在PIC16F84、PIC16F877 和PIC16F628 等几款。
PCI驱动开发手册

Linux2.6内核PCI驱动程序开发一,PCI相关数据结构说明1.1struct pci_driver这个数据结构在文件/linux/pci.h里,这是Linux内核版本2.4之后为新型的PCI设备驱动程序所添加的,其中最主要的是用于识别设备的id_table结构,以及用于检测设备的函数probe( )和卸载设备的函数remove( )。
struct pci_driver {struct list_head node;char *name;const struct pci_device_id *id_table;int (*probe) (struct pci_dev *dev, const struct pci_device_id *id);void (*remove) (struct pci_dev *dev);int (*save_state) (struct pci_dev *dev, u32 state);int (*suspend)(struct pci_dev *dev, u32 state);int (*resume) (struct pci_dev *dev);int (*enable_wake) (struct pci_dev *dev, u32 state, int enable);};为创建一个正确的struct pci_driver 结构, 只有4个字段需要被初始化:name,id_table,probe和remove。
其中id_table初始化可以用到宏PCI_DEVICE(VENDOR_ID,DEVICE_ID),VENDOR_ID 和DEVICE_ID分别为设备和厂商编号,由板卡生产厂家指定。
Static const struct pci_device_id mypci[] ={{PCI_DEVICE(VENDOR_ID,DEVICE_ID)},{}};1.2pci_dev这个数据结构也在文件include/linux/pci.h里,它详细描述了一个PCI设备几乎所有的硬件信息,包括厂商ID、设备ID、各种资源等。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
PCI从设备代码说明:library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity pcislave is port( //PCI接口说明//CLK:33M PCI 时钟;//RST : PCI 复位,低有效;// IDSEL : PCI 配置空间选择,高有效;// FRAME :PCI 祯周期开始,低有效;// IRDY : PCI主设备准备好,低有效;clk,rst,idsel,frame,irdy : in std_logic;// TRDY : PCI目标设备准备好,低有效;// DEVSEL :PCI目标设备选择,低有效;// STOP : PCI目标设备停止,低有效;trdy,devsel,stop : inout std_logic;// PCI 效验输出使能,高有效;paren1 : out std_logic;// DATA RD OUT :局部总线读输出信号,高有效;// DATA WR :局部总线写输出信号,高有效;// DMASEL :DMA允许,高有效;data_rd_out,data_wr,dmasel : out std_logic;// IOSEL : IO空间选择输出,高有效;// MEMSEL :内存空间选择输出,高有效;iosel,memsel : buffer std_logic;// EXT ADD :局部总线地址译码输出,IO空间只用(7 到0)ext_add : out std_logic_vector(21 downto 0);// CBE :PCI命令及字节输入cbe : in std_logic_vector(3 downto 0);// AD : PCI地址及数据复用信号ad : inout std_logic_vector(31 downto 0));end pcislave;architecture beha of pcislave is// 目标读状态机type slaverdst is (idle1,dev_st1,rdst1,rdst2,rdst3,rdst4,rdstopst,ctst1);//目标写状态机type slavewrst is (idle2,dev_st2,wrst1,wrst2,wrst3,wrst4,wrstopst,ctst2);signal pre_state1,nxt_state1 : slaverdst;signal pre_state2,nxt_state2 : slavewrst;// PCI配置空间定义:// PCI ID号定义constant id : std_logic_vector(31 downto 0) :="01000010010110000001000100000000"; // PCI 设备类型定义constant clss : std_logic_vector(31 downto 0) :="00000100000000000000000000000000";//PCI 编程接口类型定义:constant ht : std_logic_vector(31 downto 0) :="00000000000000000010000000000000";//PCI 保留空间定义,全‘0’constant res : std_logic_vector(31 downto 0) :="00000000000000000000000000000000";//PCI 保留地址译码,全‘0’constant base : std_logic_vector(31 downto 0) :="00000000000000000000000000000000"; signal add,basereg1,basereg0,wrreg,intreg,stc,dqreg : std_logic_vector(31 downto 0);signal cmd : std_logic_vector(3 downto 0);signal st_clr,st_clr1,io_sel,iordsel,iowrsel,memrdsel,memwrsel,membase0_sel : std_logic; signal iobase0_sel,ioen,memen,io_rd_sel,io_wr_sel,mem_rd_sel,mem_wr_sel,cfg_sel : std_logic; signal rdsel,wrsel,dev_sel,cfg_rd_sel,cfg_wr_sel,devid,statecmd,classcd,hdtp : std_logic;signal base0,base1,base2,base3,base4,base5,res1,res2,res3,res4,res5,int_sel : std_logic;signal cfgwr,cfgwr1,data_out,data_out1,spar_en : std_logic;begincon_st : process(clk,rst)begin //PCI目标命令及地址锁存if rst='0' then add<=(others=>'0');cmd<=(others=>'0');elsif rising_edge(clk) thenif (frame='0' and irdy='1' and trdy='1' and devsel='1' and stop='1')then cmd<=cbe;add<=ad;end if;end if;// PCI IO及内存空间访问锁存if (rst='0' or st_clr='1') then io_sel<='0';elsif rising_edge(clk) thenif (frame='0' and irdy='1' and trdy='1' and devsel='1' and stop='1')then io_sel<='1';else io_sel<='0';end if;end if;// PCI IO命令译码if cmd="0010" then iordsel<='1';else iordsel<='0';end if;if cmd="0011" then iowrsel<='1';else iowrsel<='0';end if;//PCI内存命令译码if cmd="0110" then memrdsel<='1';else memrdsel<='0';end if;if cmd="0111" then memwrsel<='1';else memwrsel<='0';end if;//PCI内存空间访问地址选中if (add(31 downto 22)=basereg1(31 downto 22)) then membase0_sel<='1';else membase0_sel<='0';end if;//PCI IO空间访问地址选中if add(15 downto 8)=basereg0(15 downto 8) then iobase0_sel<='1';else iobase0_sel<='0';end if;// PCI IO访问及内存访问地址选中if io_sel='1' and iordsel='1' and iobase0_sel='1' and ioen='1' then io_rd_sel<='1';else io_rd_sel<='0';end if;if io_sel='1' and iowrsel='1' and iobase0_sel='1' and ioen='1' then io_wr_sel<='1';else io_wr_sel<='0';end if;if io_sel='1' and memrdsel='1' and membase0_sel='1' and memen='1' then mem_rd_sel<='1';else mem_rd_sel<='0';end if;if io_sel='1' and memwrsel='1' and membase0_sel='1' and memen='1' then mem_wr_sel<='1';else mem_wr_sel<='0';end if;//PCI配置空间访问选中if (rst='0' or st_clr='1') then cfg_sel<='0';elsif rising_edge(clk) thenif (idsel='1' and frame='0' and irdy='1' and trdy='1' and devsel='1' and stop='1') then cfg_sel<='1';else cfg_sel<='0';end if;end if;//PCI配置访问译码输出if cmd="1010" then rdsel<='1';else rdsel<='0';end if;if cmd="1011" then wrsel<='1';else wrsel<='0';end if;//PCI配置空间访问译码if (add(10 downto 6)="00000" and add(1 downto 0)="00") then dev_sel<='1';else dev_sel<='0';end if;if cfg_sel='1' and dev_sel='1' and rdsel='1' then cfg_rd_sel<='1';else cfg_rd_sel<='0';end if;if cfg_sel='1' and dev_sel='1' and wrsel='1' then cfg_wr_sel<='1';else cfg_wr_sel<='0';end if;//PCI空间访问地址译码if rising_edge(clk) thenif add(5 downto 2)="0000" then devid<='1';else devid<='0';end if;if add(5 downto 2)="0001" then statecmd<='1';else statecmd<='0';end if; if add(5 downto 2)="0010" then classcd<='1';else classcd<='0';end if;if add(5 downto 2)="0011" then hdtp<='1';else hdtp<='0';end if;if add(5 downto 2)="0100" then base0<='1';else base0<='0';end if;if add(5 downto 2)="010 1" then base1<='1';else base1<='0';end if;if add(5 downto 2)="0110" then base2<='1';else base2<='0';end if;if add(5 downto 2)="0111" then base3<='1';else base3<='0';end if;if add(5 downto 2)="1000" then base4<='1';else base4<='0';end if;if add(5 downto 2)="1001" then base5<='1';else base5<='0';end if;if add(5 downto 2)="1010" then res1<='1';else res1<='0';end if;if add(5 downto 2)="1011" then res2<='1';else res2<='0';end if;if add(5 downto 2)="1100" then res3<='1';else res3<='0';end if;if add(5 downto 2)="1101" then res4<='1';else res4<='0';end if;if add(5 downto 2)="1110" then res5<='1';else res5<='0';end if;if add(5 downto 2)="1111" then int_sel<='1';else int_sel<='0';end if;end if;//PCI从读状态机case pre_state1 iswhen idle1 => if (cfg_rd_sel='1' or io_rd_sel='1' or mem_rd_sel='1')then nxt_state1<=dev_st1;else nxt_state1<=idle1;end if;when dev_st1 => if irdy='0' then nxt_state1<=rdst1;else nxt_state1<=dev_st1;end if;when rdst1 => if irdy='0' then nxt_state1<=rdst2;else nxt_state1<=rdst1;end if;when rdst2 => if irdy='0' then nxt_state1<=rdst3;else nxt_state1<=rdst2;end if;when rdst3 => if irdy='0' then nxt_state1<=rdst4;else nxt_state1<=rdst3;end if;when rdst4 => if frame='0' then nxt_state1<=rdstopst;else nxt_state1<=ctst1;end if;when rdstopst => if frame='0' or irdy='0' then nxt_state1<=rdstopst;else nxt_state1<=ctst1;end if;when ctst1 => nxt_state1<=idle1;when others=> nxt_state1<=idle1;end case;//PCI从写状态机case pre_state2 iswhen idle2=> if (cfg_wr_sel='1' or io_wr_sel='1' or mem_wr_sel='1')then nxt_state2<=dev_st2;else nxt_state2<=idle2;end if;when dev_st2=> if irdy='0' then nxt_state2<=wrst1;else nxt_state2<=dev_st2;end if;when wrst1=> if irdy='0' then nxt_state2<=wrst2;else nxt_state2<=wrst1;end if;when wrst2=> if irdy='0' then nxt_state2<=wrst3;else nxt_state2<=wrst2;end if;when wrst3=> if irdy='0' then nxt_state2<=wrst4;else nxt_state2<=wrst3;end if;when wrst4=> if frame='0' then nxt_state2<=wrstopst;else nxt_state2<=ctst2;end if;when wrstopst => if frame='0' or irdy='0' then nxt_state2<=wrstopst;else nxt_state2<=ctst2;end if;when ctst2 => nxt_state2<=idle2;when others=> nxt_state2<=idle2;end case;if rst='0' then wrreg<=(others=>'0');elsif rising_edge(clk) then wrreg<=ad;end if;//配置空间0地址寄存器if rst='0' then basereg0<="11111111111111111111111100000001";elsif rising_edge(clk) thenif (cfgwr='1' and base0='1' and wrsel='1') thenbasereg0(31 downto 8)<=wrreg(31 downto 8);basereg0(7 downto 0)<="00000001";end if;end if;//配置空间1地址寄存器if rst='0' then basereg1<="11111111110000000000000000000000";elsif rising_edge(clk) thenif (cfgwr='1' and base1='1' and wrsel='1') thenbasereg1(31 downto 22)<=wrreg(31 downto 22);basereg1(21 downto 0)<="0000000000000000000000";end if;end if;//配置空间中断寄存器if rst='0' then intreg<="00000000000000000000000111111111";elsif rising_edge(clk) thenif (cfgwr='1' and int_sel='1' and wrsel='1') thenintreg(31 downto 8)<="000000000000000000000001";intreg(7 downto 0)<=wrreg(7 downto 0);end if;end if;//配置空间状态及命令寄存器if rst='0' then stc<="00000100000000000000000000000000";elsif rising_edge(clk) thenif (cfgwr='1' and statecmd='1' and wrsel='1') thenstc(31 downto 3)<="00000100000000000000000000000";stc(2 downto 0)<=wrreg(2 downto 0);end if;end if;ioen<=stc(0);memen<=stc(1);dmasel<=stc(2);PCI读效验产生if rst='0' then paren1<='0';cfgwr<='0';st_clr<='0';data_out<='0';elsif rising_edge(clk) thenparen1<=spar_en;cfgwr<=cfgwr1;st_clr<=st_clr1;data_out<=data_out1;end if;if rising_edge(clk) thenif devid='1' then dqreg<=id;elsif statecmd='1' then dqreg<=stc;elsif classcd='1' then dqreg<=clss;elsif hdtp='1' then dqreg<=ht;elsif res1='1' or res2='1' or res3='1' or res4='1' or res5='1'or base2='1' or base3='1' or base4='1' or base5='1' then dqreg<=base; elsif base0='1' then dqreg<=basereg0;elsif base1='1' then dqreg<=basereg1;elsif int_sel='1' then dqreg<=intreg;else dqreg<=(others=>'0');end if;end if;end process;//PCI数据输出ad<=dqreg when data_out='1' and rdsel='1'else "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ";state1_pro : process(clk,rst)begin if rst='0' then pre_state1<=idle1;elsif rising_edge(clk) then pre_state1<=nxt_state1;end if;end process;state2_pro : process(clk,rst)begin if rst='0' then pre_state2<=idle2;elsif rising_edge(clk) then pre_state2<=nxt_state2;end if;end process;//PCI效验信号产生spar_en<='1' when pre_state1=rdst4else '0';//局部总线写信号产生cfgwr1<='1' when pre_state2=wrst2 or pre_state2=wrst3 else '0';st_clr1<='1' when pre_state1=dev_st1 or pre_state2=dev_st2 else '0';//局部总线读信号产生data_out1<='1' when pre_state1=rdst1 or pre_state1=rdst2or pre_state1=rdst3 or pre_state1=rdst4else '0';//PCI目标选择信号输出devsel<='0' when pre_state1=dev_st1 or pre_state1=rdst1 or pre_state1=rdst2or pre_state1=rdst3 or pre_state1=rdst4 or pre_state1=rdstopstor pre_state2=dev_st2 or pre_state2=wrst1 or pre_state2=wrst2or pre_state2=wrst3 or pre_state2=wrst4 or pre_state2=wrstopst else '1' when pre_state1=ctst1 or pre_state2=ctst2else 'Z';//PCI目标准备好信号输出trdy<='0' when pre_state1=rdst4 or pre_state2=wrst4else '1' when pre_state1=dev_st1 or pre_state1=rdst1 or pre_state1=rdst2or pre_state1=rdst3 or pre_state1=rdstopstor pre_state2=dev_st2 or pre_state2=wrst1 or pre_state2=wrst2or pre_state2=wrst3 or pre_state2=wrstopstor pre_state1=ctst1 or pre_state2=ctst2else 'Z';//PCI目标停止信号输出stop<='0' when pre_state1=rdstopst or pre_state2=wrstopstelse '1' when pre_state1=dev_st1 or pre_state1=rdst1 or pre_state1=rdst2or pre_state1=rdst3 or pre_state1=rdst4or pre_state2=dev_st2 or pre_state2=wrst1 or pre_state2=wrst2or pre_state2=wrst3 or pre_state2=wrst4or pre_state1=ctst1 or pre_state2=ctst2else 'Z';// 局部总线读信号输出data_rd_out<=data_out and ((iordsel and iobase0_sel)or (memrdsel and membase0_sel));//局部总线io译码输出iosel<=(iordsel or iowrsel) and iobase0_sel;//局部总线内存译码输出memsel<=(memrdsel or memwrsel) and membase0_sel;//局部总线写信号输出data_wr<=cfgwr and ((iowrsel and iobase0_sel) or(memwrsel and membase0_sel));//局部总线地址输出ext_add<=add(21 downto 0);end beha;。