PCI9054入门1:硬件引脚定义、时序、FPGA端驱动源码

文章目录

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总线和本地总线之间的数据传输和控制进行了逻辑化和管理,从而实现了稳定的数据交换。

具体代码:

verilog 复制代码
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

思久欲知 , 知繁渴思 , 唯圣祂奇 , 毋为所困 思久欲知,知繁渴思,唯圣祂奇,毋为所困 思久欲知,知繁渴思,唯圣祂奇,毋为所困

$$
思久欲知,知繁渴思,唯圣祂奇,毋为所困
$$
相关推荐
北城笑笑3 小时前
FPGA 14 ,硬件开发板分类详解,FPGA开发板与普通开发板烧录的区别
fpga开发·fpga
2202_754421543 小时前
一个计算频率的模块
驱动开发·fpga开发
小灰灰的FPGA5 小时前
低速接口项目之串口Uart开发(七)——如何在FPGA项目中实现自适应波特率串口功能
fpga开发
fei_sun1 天前
【Verilog】第一章作业
fpga开发·verilog
深圳市雷龙发展有限公司longsto1 天前
基于FPGA(现场可编程门阵列)的SD NAND图片显示系统是一个复杂的项目,它涉及硬件设计、FPGA编程、SD卡接口、NAND闪存控制以及图像显示等多个方面
fpga开发
9527华安1 天前
FPGA实现PCIE3.0视频采集转10G万兆UDP网络输出,基于XDMA+GTH架构,提供工程源码和技术支持
网络·fpga开发·udp·音视频·xdma·pcie3.0·万兆网
able陈1 天前
为什么verilog中递归函数需要定义为automatic?
fpga开发
fei_sun1 天前
【Verilog】第二章作业
fpga开发·verilog
碎碎思1 天前
如何使用 Vivado 从源码构建 Infinite-ISP FPGA 项目
fpga开发·接口隔离原则
江山如画,佳人北望1 天前
fpga-状态机的设计及应用
fpga开发