把PCI转localbus调通了,取代了以前使用的PCI芯片PCI9030,PCI9054等芯片.全部用FPGA实现。
使用P1020主板可以识别到FPGA PCI卡,DEVICE_ID和VENDOR_ID的参数在config_mux.v里面设置。以及后面的class/rev参数设置如下
2、接下来要做的工作是将PCI总线转成类似localbus总线去访问读写FPGA片内寄存器,主弄清PCI读写命令的原理,以及相关的地址划分,现在要读写FPGA片内寄存器,应该怎么使用地址。
3、PCI设备中有三种地址空间,分别是内存空间、IO空间和配置空间。
PCI总体设计方案:
一、配置模块
在PCI Agent设备的配置空间中包含了许多寄存器,这些寄存器决定了该设备在PCI总线中的使用方法,本节不会全部介绍这些寄存器,因为系统软件只对部分配置寄存器感兴趣。PCI Agent设备使用的配置空间如图2‑9所示。
以下记录几个主要的配置进行说明:
1、定义设备的DEVICE_ID和VENDOR_ID,如下代码:
6'b0000_00: cfg_dat_out <= #1 {DEVICE_ID,VENDOR_ID};// reg 00h (DevID/VendorID)
2、主要的配置代码:
3、对部分配置空间寄存器进行写操作
4、数据输出通道,pci_dat_out驱动pci_ad的数据周期输出;
二、锁存模块
锁存负责在PCI操作的地址周期将PCI的地址信号AD[31:0]、命令信号CBE#[3:0]、和主设备选择信号IDSEL锁存到相应的寄存器供其他模块调用。
PCI总线复用地址和数据信号,在FRAME#有效(低电平)的第1个时钟,AD[31:00]上传送的是32位地址,称为地址期。地址在这里锁存。
四、重计数模块
协议中规定有限状态机通知后端设备进行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读写
////////可以提供全套测试OK的PCI转localbus总线 verilog代码,QQ:296880551