PCI内核源代码说明
一、如何编写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活动
PCI内核源代码说明
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)
PIC32MX795F512L代码示例及说明
基于PIC32MX795F512L的Ethernet Starter Kit简单应用手册
一、单片机基本概念
1.1 单片机学习三要素
单片机学习包括三部分,其一单片机开发板,其二,PC机上的开发环境,即MPLAB,其三,两者的连接器,即USB连接的DEBUG调试器。三者关系如图1-1所示。
图1-1 单片机开发三要素
单片机这里所用的单片机型号为PIC32MX795F512L型号单片机,此单片机所拥有的主要资源有:
1、80MHz的主频,1.56DMIPS/MHz,总线32位;
2、USB 2.0 接口;
3、2个带1024缓存的CAN 2.0接口;
4、8通道DMA通道;
5、5级流水线,哈佛架构;
6、1个以太网接口;
7、512K的Flash,外加12k的启动Flash;
8、128K的RAM;
9、可编程中断向量控制器;
10、16个10位AD转换器;
11、UART/SPI/IIC等串行通信方式;
12、带JTAG调试口,具有休眠功能,节省能耗。
更具体资源可以参考PIC32MX795F512L.pdf。
MPLAB的介绍详见第二章。
USB连接器,本质上是从单片机内部的JTAG线通过一块芯片把JTAG转为USB通信方式,然后直接连到PC机上,与MPLAB间接通信。更多情况,一般都会独立做一个仿真器,功能如上所述。
更为详细的单片机知识可以参考:
1、《PIC单片机实用教程——基础篇》;
2、《PIC单片机实用教程——提高篇》;
3、上相应目录下的资料;
4、PIC论坛或MPLAB开发工具下的help等。
1.2 单片机最小系统
linux设备驱动之pci设备的IO和内存
linux设备驱动之pci设备的I/O和内存
------------------------------------------
Pci设备的I/O和内存是一个比较复杂的问题.如下的总线结构:
在上图的总线结构中,ethernet设备和pci-pci bridge的同类型资源空间必须要是pci bus0的一个子集
例如,pci bus 0的I/O端口资源是0x00CC~0x01CC. Ethernet设备的I/O范围的是
0x00CC~0x0xE0.那么pci-pci bridge的I/O端口范围就必须要在0x0xE0~0x01CC之间. 同样,SCSI和VIDEO同类型资源必须要是pci_bus1的子集.pci bus1上有一个pci桥,对应的资源也就是它所连桥上的资源.即pci_bus->self.
也就是说,下层总线的资源是它上层总线资源的子集。上层总线资源是下层总线资源的父集。其实,每个PCI设备的资源地始地址都是由操作系统设置的.在x86上,都由bios设置好了.假若没有bios的时候,我们应该怎么去设置设备的资源起始范围呢?
可能在pci枚举完成之后:
1:从根总线开始,设置根总线的资源范围是从0开始,到0xFFFF或者0xFFFFFFFF的最大范围. 2:对其它的设备,可往其资源寄存器全部写入1,就可以求得该资源项的类型和长度.
3:设备从根总线的资源那里分得对应长度的资源.
4:如果设备是pci-pci bridge,则递归配置它.
可能有人会有这样迷惑,对应于上图,如果pci-pci bridge的资源大小是N.而SCSI和video资源范围超过了N怎么办呢?
pci_alloc_consistent函数
pci_alloc_consistent函数
PCI(Peripheral Component Interconnect)总线是一种连接主
板和外部设备的标准接口。在PCI总线上,每个设备都被分配到一个
唯一的设备编号(Device ID),并且可以进行数据传输。
当一个驱动需要向设备进行DMA(Direct Memory Access)数据
传输时,需要申请系统内存作为缓冲区,这个申请过程可以通过
pci_alloc_consistent函数来完成。在本文中,我们将围绕这个函数
展开讨论。
一、函数定义
pci_alloc_consistent函数的定义如下:
```C
void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle);
```
其中,pci_dev *hwdev代表要进行DMA传输的设备对象,size
代表所需内存空间的大小,dma_addr_t *dma_handle代表分配的内存
空间的虚实映射地址。
二、函数调用过程
1. 准备传输数据的设备
在进行DMA传输前,需要引入所需传输数据的设备并进行初始化
设置,以便进行顺利的数据传输。在这里,我们可以使用Linux内核
提供的pci_driver进行设备管理。具体代码如下:
```C
#include <linux/pci.h>
static struct pci_driver my_driver = {
.name = "mydriver",
PCI信号 定 义
PCI信号定义说明(中文版)
1. AD[31:0] (PCI ADDRESS / DATA BUS)地址与数据总线讯号,在FRAME#启动后地址才有效,在 PCLK第一个CLOCK 动作初始化时,FRAME#动作后,输出为地址与数据,写入周期,输入为数据,读取周期 TRDY# 与 IRDY#会动作,高阻抗时,为数据转换周期或RESET#动作
2. C/BE[3:0]# (PCI COMMAND /BYTE ENABLES) FRAME#启动后,CLOCK第一个CLOCK,周期为PCI命令, 再下一个周期为允许命令,命令在FRAME#后有效,数据在TRDY#与IRDY#后有效
3. DEVSEL# (PCI DEVSEL SELECT)确定外部外围连结之响应讯号,高阻抗时,为停止周期或RESET#动作时
4. FRAME# (PCI CYCLE FRAME) PCI 总线起始讯号
5. GNT[4:0]# (PCI BUS GRANT) PCI 总线控制认可讯号
6. IRDY# (INITIATOR READY) 数据读取写入讯号
7. LOCK# (PCI BUS LOCK) 总线锁住讯号
8. PAR (PCI BUS PARITY) 地址与位传送之同位检错讯号
9. PCLK (PCI CLOCK) PCI 时脉讯号
10.PGNT# (PCI GRANT TO PERIPHERAL BUS CONTROLLER)
PCI 总线对外部外围装置之需求同意认可讯号
11. PERQ# (PCI REQUEST FROM PERIPHERAL BUS CONTROLLER)
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.
PCIE详细设计说明
PCI Express 详细设计
目录
1PCI EXPRESS介绍1
2PCI EXPRESS参数与接口1
3实现框图与接口时序错误!未定义书签。
4PCI EXPRESS中模块〔功能的原理与实现2
4.1应用层模块2
4.1.1 模块介绍2
结构、算法〔或原理和实现2
4.1.3 参数和接口3
4.2配置信号采样模块4
4.2.1 模块介绍4
4.2.2 结构、算法〔或原理和实现错误!未定义书签。
4.2.3 参数和接口4
4.3PCIE硬核模块4
4.3.1 模块介绍4
4.3.2 结构、算法〔或原理和实现错误!未定义书签。
4.3.3 参数和接口4
4.4LMI配置模块4
4.4.1 模块介绍4
4.4.2 结构、算法〔或原理和实现4
4.4.3 参数和接口5
4.5重新配置时钟模块5
4.5.1 模块介绍5
4.5.2 结构、算法〔或原理和实现错误!未定义书签。
4.5.3 参数和接口5
4.6兼容性测试模块5
4.6.1 模块介绍5
PCI Express详细设计
1PCI Express介绍
PCIE设备按照一定的拓扑连接构成总线结构,设备与设备通过协议规定的事务包〔TLP进行通信。PCIE垂直方向可分为应用层、事务层、数据链路层和物理层,协议规定每层实现的功能,每层功能配合实现设备的PCIE数据传输功能。
PCIE硬核的结构图如下图1.1所示:
●应用层模块〔altpcierd_example_app_chaining:主要实现PCIE应用层的
功能
●配置信号采样模块〔altpcierd_tl_cfg_sample:将PCIE IP核配置空间的
PCI侦测诊断卡代码大全
代码说明
00已显示系统的配置;即将控制INI19引导装入。
01处理器测试1,处理器状态核实,如果测试失败,循环是无限的。处理器寄存器的测试即将开始,不可屏蔽中断即将停用。CPU寄存器测试正在进行或者失败。
02确定诊断的类型(正常或者制造)。如果键盘缓冲器含有数据就会失效。停用不可屏蔽中断;通过延迟开始。CMOS写入/读出正在进行或者失灵。
03清除8042键盘控制器,发出TESTKBRD命令(AAH)通电延迟已完成。ROM BIOS检查部件正在进行或失灵。
04使8042键盘控制器复位,核实TESTKBRD。键盘控制器软复位/通电测试。可编程间隔计时器的测试正在进行或失灵。
05如果不断重复制造测试1至5,可获得8042控制状态。已确定软复位/通电;即将启动ROM。DMA初如准备正在进行或者失灵。
06使电路片作初始准备,停用视频、奇偶性、DMA电路片,以及清除DMA电路片,所有页面寄存器和CMOS停机字节。已启动ROM计算ROM BIOS检查总和,以及检查键盘缓冲器是否清除。DMA初始页面寄存器读/写测试正在进行或失灵。
07处理器测试2,核实CPU寄存器的工作。ROM BIOS检查总和正常,键盘缓冲器已清除,向键盘发出BAT(基本保证测试)命令。
08使CMOS计时器作初始准备,正常的更新计时器的循环。已向键盘发出BAT命令,即将写入BAT命令。RAM更新检验正在进行或失灵。
09 EPROM检查总和且必须等于零才通过。核实键盘的基本保证测试,接着核实键盘命令字节。第一个64K RAM测试正在进行。
PCI
第5章PCI
P C I 的英文全称为Periheral Component Interconnect 。正如它的名称一样,P C I 局部总线是微型计算机系统上处理器/存储器与外围控制部件、外围附加板之间的互连机构。“P C I 局部总线规范3”规定了互连机构的协议、电气、机械以及配置空间规范。本章主要介绍L i n u x 的内核如何初始化系统的P C I 总线和设备。
图1 -5-1是一个基于P C I 局部总线的系统逻
辑示意图。P C I 局部总线和P C I -P C I 桥是将系统
的部件连接起来的连接器。C P U 连接到P C I 局
部总线0 ,这条总线主要用于连接视频设备。
被称为P C I -P C I 桥的特别P C I 设备将P C I 局部总
线0与从P C I 局部总线连接起来。这种“从P C I
总线”被称为P C I 局部总线1。按照P C I 规范的
术语来讲,P C I 局部总线1被称作位于P C I -P C I
桥的下游( d o w n s t r e a m ),而P C I 局部总线0被称
为桥的上游( u p -s t r e a m )。从P C I 局部总线主要
连接系统的S C S I 设备和以太网设备。桥、从
P C I 局部总线以及上面的两种设备都可以物理
地集成在同一个P C I 集成卡中。系统中的P C I -
I S A 桥支持老式、遗留下来的I S A 设备。在图1 -5-1中画出了一个超级I /O 控制器芯片,它可以
控制键盘、鼠标和软盘驱动器。5.1 PCI 的地址空间
PCie驱动综述分析
PCie 驱动
Pcie设备上有三种地址空间:PCI的I/O空间、PCI的存储空间和PCI的配置空间。
Pce的配置空间:
PCI有三个相互独立的物理地址空间:设备存储器地址空间、I/O地址空间和配置空间。配置空间是PCI所特有的一个物理空间。由于PCI支持设备即插即用,所以PCI设备不占用固定的内存地址空间或I/O地址空间,而是由操作系统决定其映射的基址。
系统加电时,BIOS检测PCI总线,确定所有连接在PCI总线上的设备以及它们的配置要求,并进行系统配置。所以,所有的PCI设备必须实现配置空间,从而能够实现参数的自动配置,实现真正的即插即用。
PCI总线规范定义的配置空间总长度为256个字节,配置信息按一定的顺序和大小依次存放。前64个字节的配置空间称为配置头,对于所有的设备都一样,配置头的主要功能是用来识别设备、定义主机访问PCI卡的方式(I/O访问或者存储器访问,还有中断信息)。其余的192个字节称为本地配置空间,主要定义卡上局部总线的特性、本地空间基地址及范围等。
•
一般来说,基于pcie总线的驱动,需要涉及到pci_driver pci_dev pci_device_id .
pci_device_id : 用于标识pcie设备,通过上图的厂商Id 设备Id 功能号等唯一确定一个pcie 设备,内核通过这个结构体确认驱动与设备是否匹配。
pci_dev : 一般pcie 设备都具有热拔插功能,当内核检测到有pcie设备插入时,会与相应的Pci_driver : 当有相应的设备匹配会调用驱动的相关方法,驱动中通常要做的是读出Base Adrress Register1-6 的值,这是pcies设备6个内存空间的基地址,然后通过ioremap方法映射成虚拟地址,至于6个内存空间的具体含义需要依赖于设备。
linux下pci的数据读写流程
linux下pci的数据读写流程
Linux下PCI的数据读写流程
一、引言
PCI(Peripheral Component Interconnect,外设互联)是一种计算机总线标准,用于连接计算机的主板与外部硬件设备。在Linux系统下,PCI设备的数据读写是通过访问设备的寄存器来实现的。本文将介绍Linux下PCI的数据读写流程。
二、PCI设备的识别和配置
在Linux系统启动时,会进行PCI总线的枚举和设备的识别与配置。Linux内核会扫描PCI总线上的设备,并为每个设备分配唯一的设备标识符,称为PCI设备号。系统将会为每个PCI设备分配资源,并将设备驱动程序与设备进行匹配。
三、设备驱动程序的加载与初始化
在设备识别和配置完成后,系统会加载与该设备匹配的驱动程序。设备驱动程序是对设备进行管理和控制的软件模块。当驱动程序被加载时,会进行初始化操作,包括分配内存空间、注册中断处理程序等。
四、设备寄存器的映射
设备驱动程序在初始化过程中需要访问设备的寄存器来进行数据的读写。为了实现对设备寄存器的访问,驱动程序需要将设备寄存器
映射到内核空间。在Linux中,可以通过ioremap函数将设备寄存器的物理地址映射到内核虚拟地址空间。
五、数据读写操作
一旦设备寄存器映射完成,驱动程序就可以通过读写内核虚拟地址来实现对设备寄存器的读写操作。通常,设备寄存器是以字节为单位进行读写的。驱动程序可以使用readb、readw、readl函数来读取设备寄存器的值,使用writeb、writew、writel函数来向设备寄存器写入数据。
PCI详解
Award BIOS 7166
• CLKGEN_X_PCI0_CLK • • • • • • • • • CLKGEN_X_PCI1_CLK CLKGEN_X_PCI2_CLK CLKGEN_X_PCI3_CLK CLKGEN_X_PCI4_CLK CLKGEN_X_PCI5_CLK CLKGEN_X_PCI6_CLK CLKGEN_X_PCI7_CLK CLKGEN_X_PCI8_CLK CLKGEN_X_PCI9_CLK EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU 0 ;internal LAN CLKGEN_PIN_4 CLKGEN_PIN_55;bobi 2005-7-14 CLKGEN_PIN_2 ;bobi 2005-7-19 CLKGEN_PIN_3 ;bobi 2005-7-9 0 0 0; 0; 0; 0;
• • • • • • •
位元0 = 1 致能裝置的ROM位址解碼器. 位元[10:1]保留. 位元[31:11]用來指定ROM的起始位址. 假設FFFFFFFFh被寫入到ROM的基底位址暫存器裡(位元0,既擴充ROM致 能位元被清除,所以ROM位址解碼器不會被致能,直到指定起始記憶體位 址之後),隨後再讀取此暫存器,所得的值為FFFE0000h,這表示: 位元0 = 0 ,表示ROM位址解碼器目前被關閉. 位元[10:1]保留. 在基底位址欄位(位元[31:11])裡,位元17為程式執行裝置可以設定為1的最 低有效位元,其二進位權值為128K,表示ROM解碼器需要128K的記憶體位 址,然後,程式執行裝置寫入一個32位元的起始位址到此暫存器中,指定 128KB的位址邊界當作ROM的起始位址.
linunx pcie发送数据调用的函数
linunx pcie发送数据调用的函数
【Linux PCIE发送数据调用的函数】
当在Linux系统中使用PCIe总线发送数据时,可以使用一些特定的函数来实现这一功能。PCIE发送数据的关键是通过驱动程序对PCIE设备进行访问和控制。在编写驱动程序时,我们可以使用以下函数来进行数据发送操作:
1. pci_request_regions:
这个函数用于向操作系统请求PCI设备的资源,包括IO端口和内存地址。将该函数与之后的pci_iomap函数结合使用,可以分配并映射PCI 设备的内存资源,为数据传输做准备。
2. pci_iomap:
该函数用于将分配的内存资源映射到用户空间的内存地址空间,以便用户可以直接访问PCI设备的内存区域。用户程序可以通过访问这些内存地址来发送数据到PCI设备。
3. memcpy_toio:
这个函数用于将数据从内核空间复制到IO内存空间。调用该函数可以将用户空间的数据复制到PCI设备的内存地址,实现数据发送的功能。
4. writel:
该函数用于向PCI设备的寄存器中写入数据。通过调用该函数,可以向PCI设备的控制寄存器中写入特定的命令和参数,控制设备的操作。
综合上述函数,我们可以编写一个函数,将数据从用户空间发送到PCIe 设备。以下是一个示例:
#include <linux/pci.h>
#include <asm/io.h>
void send_data_to_pcie(struct pci_dev *pdev, void *data, size_t size) {
PIC编程说明
PIC编程说明
在编程过程中由于一个端口可能有多个功能,所以在初始化时应该详细设置所以的端口的功能,当使用一种功能时应该将其他功能关闭,否则端口的功能将不能正常工作。
汇编:
C语言:-------picc
1、在用C语言编程之前,得确定用户用的是哪个辅助C编译器(因为MPLAB IDE 不提供C编译器,不过在8.33版本有捆绑了PICC的C编译器用户可以直接选用)。注意设置连接编译器的路径。
2 在程序的最前面用#include 预处理指令引用包含头文件,其中必须包含一个编译器
提供的“pic.h”文件(在picc18里为:pic18.h),实现单片机内特殊寄存器和其它特殊符号的声明;
3 用“__CONFIG”预处理指令定义芯片的配置位;
4 声明本模块内被调用的所有函数的类型,PICC 将对所调用的函数进行严格的类型
匹配检查;
5 定义全局变量或符号替换;
6 实现函数(子程序),特别注意main 函数必须是一个没有返回的死循环。
现提供个C 原程序的范例:
#include <pic.h> //包含单片机内部资源预定义
#include “pc68.h” //包含自定义头文件
//定义芯片工作时的配置位
__CONFIG (HS & PROTECT & PWRTEN & BOREN & WDTDIS);
//声明本模块中所调用的函数类型
void SetSFR(void);
void Clock(void);
void KeyScan(void);
void Measure(void);
void LCD_Test(void);
xilinx PCIE的Linux驱动程序源代码
//--------------------------------------------------------------------------------
//-- Filename: xbmd.h
//--
//-- Description: Main header file for kernel driver
//--
//-- XBMD is an example Red Hat device driver which exercises XBMD design //-- Device driver has been tested on Red Hat Fedora FC9 2.6.15.
//--------------------------------------------------------------------------------
// Define Result values
#define SUCCESS 0
#define CRIT_ERR -1
// Debug - define will output more info
#define Verbose 1
// Max DMA Buffer Size
#define BUF_SIZE (4096 * 1024)
enum {
INITCARD,
INITRST,
DISPREGS,
RDDCSR,
RDDDMACR,
RDWDMATLPA,
RDWDMATLPS,
RDWDMATLPC,
RDWDMATLPP,
RDRDMATLPP,
- 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;
begin
con_st : process(clk,rst)
begin //PCI目标命令及地址锁存
if rst='0' then add<=(others=>'0');cmd<=(others=>'0');
elsif rising_edge(clk) then
if (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) then
if (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;