[TOC]
1:PCI9054的FPGA侧(local侧引脚定义) 而PCI9054的本地总线端的主要管脚信号定义如下表所示。这些管脚是连接到本地逻辑控制电路部分的,并由本地逻辑控制电路部分实现接口时序控制。
本组信号引脚主要用于PCI9054与Local端的连接,主要信号包括LA[31:2]、LD[3 1:0]、LHOLD、LHOLDA、ADS#、LCLK、LBE[3:0]#、LW/R#、READY#、WAIT#、BLAST#等。
CCS#:配置寄存器片选。低电平有效时,选中的是PCI9054的内部寄存器,Local端可以通过此方法配置寄存器。
LCLK: Local端的时钟输入,是Local端处理器与PCI9054之间的同步信号,如果没有此信号,PCI插卡将不能启动。
LINT#:本地中断信号。作为输入时可以引起PCI 中断,作为输出时,可以通过改写中断寄存器INTCSR的内容来改变中断状态。
LRESETo#: Local端复位信号。当PC19054复位(RST#有效)时此信号有效,可以用来复位本地处理器。
LA[31:2]:本地地址信号。代表物理地址的高30Bit,突发传输时可以自动增加表明一个连续的数据周期。
LW/R#:Local端的读写复用信号,低电平为读,高电平为写。
READY#:输入/输出准备好信号,表示总线上数据有效或写数据完成,用以连接PCI9054等待状态产生器。
ADS#:地址有效信号。表明LA[31:2]上的地址有效以及一个新的总线交易的开始,在第一个时钟周期内有效。
BLAST#:突发结束。表明总线访问的最后一次传送,由本地总线主设备驱动。
BTERM#:突发中止。用于中止一个突发传输并启动一个新的总线交易。
MODE[1:0]:总线工作模式选择。
<
2:PCI9054的C模式下的读写时序 MODE[1:0]都接地为0,设为C模式。
C模式是一种类似于单片机的工作方式。在这种模式下,PCI9054通过片内逻辑控制,将PCI的地址线和数据线分开,很方便的为本地工作时序提供各种工作方式,设计者只要严格控制Local端和PCI端的各种时序控制线,就可以很好的应用PCI9054芯片。C模式下可以进行配置寄存器、主模式、从模式及 DMA模式等操作。
<
PCI 写发起时序
<
PCI 读发起时序
3:FPGA代码部分 通过parameter来定义各个不同状态的参数。每一个状态的位宽为7位,接下来还需要定义两个7位的寄存器,一个用来表示当前状态,另一个用来表示下一个状态,如下所示:
这段Verilog代码是一个PCI Local Bus接口的模块定义。该模块用于连接PCI 9054芯片与其他组件之间的通信,通过一系列输入和输出信号来实现数据的读写和控制。以下是该代码的一些重要部分解释:
参数部分
序号
代号
含义
1
parameter integer REG_ADDR_WIDTH = 8
:
定义了寄存器地址的位宽,默认为8位
2
parameter integer REG_DATA_WIDTH = 32
:
定义了寄存器数据的位宽,默认为32位
信号部分
序号
代号
含义
1
输入信号 clk
全局系统时钟
2
输入信号 areset_n
来自PCI 9054的全局复位信号,低电平有效
3
输入信号 i_hold
本地总线接口的保持信号
4
输出信号 o_holda
经过逻辑处理后的保持信号
5
输入信号 ads_n
PCI总线地址有效信号,低电平有效
6
输入信号 blast_n
PCI总线传输结束信号,低电平有效
7
输出信号 o_ready_n
: 就绪信号
在特定状态下为低电平,表示数据传输准备就绪
8
输入信号 lw_rn
读写控制信号,高电平表示写操作,低电平表示读操作。
9
输入信号 la
地址信号
10
输入信号 i_ld
输入的数据
11
输出信号 ld_oen
数据输出使能信号
12
输出信号 o_ld
输出的数据
接下来的代码部分描述了一个状态机,用于管理数据传输过程。不同的状态表示不同的传输阶段,如IDLE、TRANSFER、SINGLE_WAIT和SINGLE_END。
代码中使用的触发器和逻辑门用于控制状态转移和输出信号的生成,以实现稳定的数据传输和寄存器读写操作。
这段代码实现了一个复杂的功能模块,将PCI总线和本地总线之间的数据传输和控制进行了逻辑化和管理,从而实现了稳定的数据交换。
具体代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 `timescale 1ns / 1ps module pci_local_bus #( parameter integer REG_ADDR_WIDTH = 8 , parameter integer REG_DATA_WIDTH = 32 )( input wire clk , input wire areset_n , input wire i_hold , output reg o_holda , input wire ads_n , input wire blast_n , output wire o_ready_n , input wire lw_rn , input wire [18 :2 ] la , input wire [REG_DATA_WIDTH-1 :0 ] i_ld , output wire ld_oen , output wire [REG_DATA_WIDTH-1 :0 ] o_ld , output wire wen , output wire [REG_ADDR_WIDTH-1 :0 ] waddr , output wire [REG_DATA_WIDTH-1 :0 ] wdata , output wire ren , output wire [REG_ADDR_WIDTH-1 :0 ] raddr , input wire [REG_DATA_WIDTH-1 :0 ] rdata ); reg [3 :0 ] current_state, next_state; parameter [3 :0 ] SM_IDLE = 4'b0001 ;parameter [3 :0 ] SM_TRANSFER = 4'b0010 ;parameter [3 :0 ] SM_SINGLE_WAIT = 4'b0100 ;parameter [3 :0 ] SM_SINGLE_END = 4'b1000 ;always @(posedge clk or negedge areset_n)begin if (~areset_n) current_state <= SM_IDLE; else current_state <= next_state; end always @(*)case (current_state) SM_IDLE: if (~ads_n) next_state = SM_TRANSFER; else next_state = SM_IDLE; SM_TRANSFER: if (~blast_n) next_state = SM_SINGLE_WAIT; else next_state = SM_TRANSFER; SM_SINGLE_WAIT: next_state = SM_SINGLE_END; SM_SINGLE_END: if (ads_n && blast_n) next_state = SM_IDLE; else if (~ads_n) next_state = SM_TRANSFER; else next_state = SM_SINGLE_END; default : next_state = SM_IDLE; endcase assign o_ready_n = (current_state == SM_SINGLE_WAIT)?1'b0 : 1'b1 ;always @(posedge clk or negedge areset_n)if (~areset_n) o_holda <= 0 ;else o_holda <= i_hold;assign wen = (~o_ready_n & lw_rn)?1'b1 : 1'b0 ;assign waddr = (~o_ready_n & lw_rn)?la[2 +REG_ADDR_WIDTH-1 :2 ] : {REG_ADDR_WIDTH{1'b0 }};assign wdata = (~o_ready_n & lw_rn)?i_ld : {REG_DATA_WIDTH{1'b0 }};assign ren = (~o_ready_n & ~lw_rn)?1'b1 : 1'b0 ;assign raddr = (~o_ready_n & ~lw_rn)?la[2 +REG_ADDR_WIDTH-1 :2 ] : {REG_DATA_WIDTH{1'b0 }};assign ld_oen = ~ren;assign o_ld = rdata;endmodule