微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > FPGA和CPLD > 基于CPLD的单片机PCI接口设计

基于CPLD的单片机PCI接口设计

时间:09-14 来源:互联网 点击:
2 PCI设计接口实现

2.1 CPLD ABEL HDL程序设计

我们针对8位单片机控制PCI以太网卡进行了程序设计,CPLD器件选用ALTERA的MAX7000系列。针对以太网卡的特点在逻辑上进行了再次简化,最张程序将适配进EPM7128芯片中,并在实践中检验通过。

以太网卡仅支持对配置空间和I/O空间的读写操作,而且这两个空间的地址都可以设置在0xFF以内,所以可以只用一个pci_address0寄存器,其它地址都直接设为“0”;如果再限制,每次只往网卡写入一个字节数据,则可以只用一个pci_datas0寄存器,其它数值在具体操作时设成与pci_datas0寄存器的一样即可。

以下是ABEL HDL主要源码。其中16dmux是4~16位译码器,用于地址译码,选通CPLD内的寄存器;8dffe是8位的DFFE;abelcounter是8位移位计数器;mylatch8与mylatch1分别为8位与1位锁存器,而mylatchc是带清零1位锁存器;其它以“my”开始的变量都是三态缓冲器,以“out”开始的变量是三态节点,以“e”开始的变量是普通节点。这此在程序中不再声明。

SUBDESIGN abelpci



P2[7..3] : INPUT;

READ0 : INPUT

WRITE0 : INPUT;

P0[7..0] : BIDIR;

CLK : INPUT;

TRDY0 : INPUT;

AD[31..] : BIDIR;

CBE[3..0] : BIDIR;

IRDY0 : OUTPUT;

FRAME0 : OUTPUT;

)

VARIABLE

decoder : 16dmux;

mycounter : abelcounter;

pci_c
be : 8DFFE;

PCI_address0 : 8DFFE;

pci_datas0 : 8DFFE;

pci_request[6..0] : mylatch1;

pci_request7 : mylatchc;

pci_data0 : mylatch8;

pci_data1 : mylatch8;

pci_data2 : mylatch8;

pci_data3 : mylatch8;

ss : MACHINE OF BITS (FRAME0,IRDY0)

WITH STATES(s0 = B"11",

s1=B"01");

s2=B"10";

S3=B"11");

BEGIN

decoder.(d,c,b,a)=P2[6..3];

enareg[]=decoder.q[];

pci_che.ena=enareg[0]&p2;

pci_cbe.d[]=p0[];

pci_cbe.clk=!WRITE0;

pci_address0.ena=enareg&p2l

pci_address0.d[]=P0[];

pci_datas0.ena=enareg&P2;

pci_datas0.d[]=P0[];

pci_datas0.clk=!WRITE0;

pci_data0.gate=!TRDY0;

pci_data0.data[]=AD[7..0];

pci_data1.gate=!TRDY0;

pci_data1.data[]=AD[15..8];

pci_data2.gate=!TRDY0;

pci_data2.data[]=AD[23..16];

pci_data3.gate=!TRDY0;

pci_data3.data[]=AD[31..24];

pci_request[3..0].gate=!TRDY0;

pci_request7.gate=!TRDY0;

pci_request7.aclr=P2&!WRITE0;

pci_request[3..0].data=CBE[];

pci_request.data=IRDY0;

pci_request.data=FRAME0;

pci_request.data=Vcc;

pci_request7.data=Vcc;

eread=P2&!READ0 & WRITE0;

my_P0_data0[].in=pci_data0.q[];

my_P0_data0[].oe=enareg&eread;

my_P0_data1[].in=pci_data1.q[];

my_P0_data1[].oe=enareg&eread;

my_P0_data2[].in=pci_data2.q[];

my_P0_data2[].oe=enareg&eread;

my_P0_data3[].in=pci_data3.q[];

my_P0_data3[].oe=enareg&eread;

my_P0_request[6..0].in=pci_request[6..0].q;

my_P0_request.in=pci_request7.q;

my_P0_request[].oe=enareg[13]&eread;

out_P0[]=my_P0_data0[];

out_P0[]=my_P0_data1[];

out_P0[]=my_P0_data2[];

out_P0[]=my_P0_data3[];

out_P0[]=my_P0_request[];

P0[]=out_P0[];

enclr=enareg[0]&P2&!WRITE0;

mycounter.clock=CLK;

mycounter.cnt_en=!IRDY0;

mycounter.aclr=!FRAME0;

mycounter.sset=!TRDY0;

ss.clk=!CLK;

ss.reset=enclr;

ss.ena=Vcc;

CASE ss IS

WHEN s0 => ss="s1";

WHEN s1 => ss="s2";

WHEN s2 => IF mycounter.cout THEN ss =s3;ELSE ss="s2";

END IF;

WHENf s3 => ss="s3";

END CASE;

my_AD_address[7..0].in=in=pci_
address0;

my_AD_address[31..8].in=GND;

my_AD_address[31..0].oe=!FRAME0;

my_CBE_c[].in=PCI_cbe.d[3..0];

my_CBE_c[].oe=!FRAME0;

my_AD_data[31..0].in=pci_datas0.q[8..1];

my_AD_data[31..0].oe=pci_cbe_[0]&FRAME0;

my_CBE_be[].in=pci_cbe.d[7..4];

my_CBE_be[].oe=FRAME0;

out_AD[]=my_AD_address[];

out_AD[]=my_AD_data[];

AD[]=out_AD[];

out_CBE[]=my_CBE_c[];

out_CBE[]=my_CBE_be[];

CBE[]=out_CBE[];

END;

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top