FPGA 实现PCI转localbus

把PCI转localbus调通了,取代了以前使用的PCI芯片PCI9030,PCI9054等芯片.全部用FPGA实现。

使用P1020主板可以识别到FPGA PCI卡,DEVICE_ID和VENDOR_ID的参数在config_mux.v里面设置。以及后面的class/rev参数设置如下

FPGA 实现PCI转localbus_第1张图片

 

 

 

2、接下来要做的工作是将PCI总线转成类似localbus总线去访问读写FPGA片内寄存器,主弄清PCI读写命令的原理,以及相关的地址划分,现在要读写FPGA片内寄存器,应该怎么使用地址。

3、PCI设备中有三种地址空间,分别是内存空间、IO空间和配置空间。

 

PCI总体设计方案:

FPGA 实现PCI转localbus_第2张图片

一、配置模块

在PCI Agent设备的配置空间中包含了许多寄存器,这些寄存器决定了该设备在PCI总线中的使用方法,本节不会全部介绍这些寄存器,因为系统软件只对部分配置寄存器感兴趣。PCI Agent设备使用的配置空间如图2‑9所示。

FPGA 实现PCI转localbus_第3张图片

 

以下记录几个主要的配置进行说明:

1、定义设备的DEVICE_ID和VENDOR_ID,如下代码:

FPGA 实现PCI转localbus_第4张图片

 

 6'b0000_00: cfg_dat_out <= #1 {DEVICE_ID,VENDOR_ID};// reg 00h (DevID/VendorID)

2、主要的配置代码:

FPGA 实现PCI转localbus_第5张图片

 

3、对部分配置空间寄存器进行写操作

FPGA 实现PCI转localbus_第6张图片

 

4、数据输出通道,pci_dat_out驱动pci_ad的数据周期输出;

FPGA 实现PCI转localbus_第7张图片

 

二、锁存模块

锁存负责在PCI操作的地址周期将PCI的地址信号AD[31:0]、命令信号CBE#[3:0]、和主设备选择信号IDSEL锁存到相应的寄存器供其他模块调用。

PCI总线复用地址和数据信号,在FRAME#有效(低电平)的第1个时钟,AD[31:00]上传送的是32位地址,称为地址期。地址在这里锁存。

FPGA 实现PCI转localbus_第8张图片

四、重计数模块

协议中规定有限状态机通知后端设备进行I/O操作或存储器操作后,后端设备需要在最多16个时钟周期内响应,发出ready信号,否则有限状态机将对其重试连接。在这里我们采用计数器,如果后端设备10个时钟周期内没有发出ready信号,模块就会输出重试信号通知状态机。代码如下:

 

 

五、基地址译码模块

  assign ba0_rw_reg = {ba0, 4'b0000};

  assign ba1_rw_reg = {ba1, 4'b0000};

  always @ (posedge pci_clk or negedge pci_rst_l)

    begin

      if (pci_rst_l == 1'b0) begin

  ba0 <= 28'h0;

  ba1 <= 28'h0;

end

      else if (ba0_en == 1'b1) begin

            if (!pci_cbe_l[3])  ba0[31:24] <= pci_ad[31:24];

  if (!pci_cbe_l[2]) ba0[23:16] <= pci_ad[23:16];

             if (!pci_cbe_l[1]) ba0[15:8]   <= pci_ad[15:8];

  if (!pci_cbe_l[0])ba0[7:4]      <= pci_ad[7:4];    

     end

      else if (ba1_en == 1'b1) begin

 

 

六、主状态机模块

七、后端设备处理模块

 

进过测试 能正确进行存储器读写和IO读写

FPGA 实现PCI转localbus_第9张图片

////////可以提供全套测试OK的PCI转localbus总线 verilog代码,QQ:296880551

你可能感兴趣的:(FPGA 实现PCI转localbus)