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#等。
2:PCI9054的C模式下的读写时序
MODE[1:0]都接地为0,设为C模式。
C模式是一种类似于单片机的工作方式。在这种模式下,PCI9054通过片内逻辑控制,将PCI的地址线和数据线分开,很方便的为本地工作时序提供各种工作方式,设计者只要严格控制Local端和PCI端的各种时序控制线,就可以很好的应用PCI9054芯片。C模式下可以进行配置寄存器、主模式、从模式及 DMA模式等操作。
3:FPGA代码部分
通过parameter来定义各个不同状态的参数。每一个状态的位宽为7位,接下来还需要定义两个7位的寄存器,一个用来表示当前状态,另一个用来表示下一个状态,如下所示:
这段Verilog代码是一个PCI Local Bus接口的模块定义。该模块用于连接PCI 9054芯片与其他组件之间的通信,通过一系列输入和输出信号来实现数据的读写和控制。以下是该代码的一些重要部分解释:
参数部分
信号部分
接下来的代码部分描述了一个状态机,用于管理数据传输过程。不同的状态表示不同的传输阶段,如IDLE、TRANSFER、SINGLE_WAIT和SINGLE_END。
代码中使用的触发器和逻辑门用于控制状态转移和输出信号的生成,以实现稳定的数据传输和寄存器读写操作。
这段代码实现了一个复杂的功能模块,将PCI总线和本地总线之间的数据传输和控制进行了逻辑化和管理,从而实现了稳定的数据交换。
具体代码:
//第一段采用同步时序描述状态转移
//-------------------------------------------------------------------------------------------------------------------------------
// IP Lib index : IP Library index
// IP Core Name : Capital name of top entity.
//
// File Name : pci_local_bus.v
// Entity Name : pci_local_bus
// Description : PCI local bus protocol parser for PCI Bridge of PLX9054.
//
// Release Version :
//
// Revision History:
//-------------------------------------------------------------------------------------------------------------------------------
`timescale 1ns / 1ps
module pci_local_bus #(
parameter integer REG_ADDR_WIDTH = 8,
parameter integer REG_DATA_WIDTH = 32
)(
// global system clock, fixed single-ended 40MHz
input wire clk ,
// Global Reset from PCI 9054
input wire areset_n ,
// Local Bus Interface
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 ,
// Register R/W interface
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
);
/*---------------------------------------------------------------------------------------*/
// generate ready state-machine
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;
// synchronous logic
always@(posedge clk or negedge areset_n)
begin
if(~areset_n)
current_state <= SM_IDLE;
else
current_state <= next_state;
end
// combinational logic
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
// output logic
assign o_ready_n = (current_state == SM_SINGLE_WAIT)?1'b0 : 1'b1;
/*---------------------------------------------------------------------------------------*/
// asserts acknowledge reponsing to HOLD
always@(posedge clk or negedge areset_n)
if(~areset_n) o_holda <= 0;
else o_holda <= i_hold;
/*---------------------------------------------------------------------------------------*/
// internal register write/read logic
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}};
/*---------------------------------------------------------------------------------------*/
// tri-state control
assign ld_oen = ~ren;
assign o_ld = rdata;
endmodule
思久欲知 , 知繁渴思 , 唯圣祂奇 , 毋为所困 思久欲知,知繁渴思,唯圣祂奇,毋为所困 思久欲知,知繁渴思,唯圣祂奇,毋为所困