PCI总线仲裁器的设计与实现
ELSE
PCIgntN0 = GND;
parb_sm = PARB_SLT0D;
END IF;
WHEN PARB_SLT0D =>
PCIgntN0 = GND;
IF ( frameN & irdyN ) THEN
parb_sm = PARB_SLT0;
ELSE
Parb_sm = PARB_SLT0D;
END IF;
为了避免AD线上和PAR线上出现时序竞争,一个设备的PCIgntN信号有效和另一个设备的PCIgntN的撤销,如果不是在总线空闲状态,则两者之间至少要有一个时钟的延迟。设计中,将每个设备占用总线的状态分为两部分,PARB_SLTx(总线空闲)和PARB_SLTxD(总线忙);状态机不能从一个设备的PARB_SLTxD状态直接转到另一个设备的PARB_SLTyD状态,中间必须经过至少一个时钟的PARB_SLTx状态的衔接,这样就避免了总线上竞争的出现。
代码中,PARBtout为一5位计数器,对PCI时钟个数进行计数,用来判别设备发出请求信号后是否在规定时间内(16个时钟,即PARBtout[4..0] = 10000)占据了总线,启动了数据的传输;如果超时,则撤销该设备的请求信号,并按预设的优先级顺序,对其余设备总线使用权进行新一轮的裁定。计数器的编程实现:
IF ( PARBtout4 # PCIreqN0 & PCIreqN1 & PCIreqN2 & PCIreqN3 ) THEN
PARBtout [ ] = 0;
ELSIF ( frameN & irdyN ) THEN
PARBtout [ ] = PARBtout [ ] + 1;
ELSE
PARBtout [ ] = 0;
END IF;
四、仿真分析
1. 单一设备总线请求情况
系统初始化后自动将总线停靠于设备0上,总线处于空闲状态,frameN、irdyN均为高电平。需要强调的一点是,仲裁所用的PCI控制信号均在PCI时钟信号的上升沿采样而得。如图3所示,设备2发出总线占用信号,仲裁器在时钟上升沿A处采样到该信号,并开始启动PARBtout计数,此时的frameN、irdyN为高电平,设备0仍然拥有总线使用权;随后设备2驱动使得frameN和irdyN有效,在时钟上升沿B处,仲裁器采样到frameN和irdyN,计数器清零,使设备2的PCIgntN2信号有效,从而占用总线,设备把地址、数据驱动到总线上,总线处于忙状态。
《PCI总线仲裁器的设计与实现(第3页)》