微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > FPGA,CPLD和ASIC > CPLD双向I/O口问题请教!(重新整理)  

CPLD双向I/O口问题请教!(重新整理)  

时间:10-02 整理:3721RD 点击:
VHDL程序如下:
该程序主要完成将CPU传送过来的8位命令经CPU转换为串行信号经SDATA输出并回读串行接口芯片返回的数据,由SCLK提供50M时钟!其中
gclk:外部100M时钟输入
en_ser :CPU发给CPLD的脉冲信号;第一个上升沿: 锁存CPU并行输出的命令数据,经COM_DATA口所存到COM_CPU。
第二个上升沿: 设置start_ser为高,CPLD启动clk_count计数SCLK开始输出
16个周期50M方波信号,SDATA前8个时钟串行输出COM_CPU命令,
后8个周期回读接口芯片返回的数据并锁存到DATA_RET中。
第三个上升沿:CPLD通过COM_DATA口将接口芯片返回的数据回送给CPU,由CPU对
数据进行处理.
com_dada:CPU与CPLD 8BIT 双向数据接口。
sdata:CPLD与串行接口芯片的双向数据线。
sden:串行接口芯片使能信号。
LIBRARY IEEE;
USEIEEE.Std_logic_1164.ALL;
ENTITY flipchip IS
PORT(
gclk:INStd_Logic;
en_ser:IN Std_Logic:='0';
com_data:INOUTStd_Logic_vector(7 DOWNTO 0);
sdata:INOUTStd_Logic:='0';
sden:OUTStd_Logic:='0';
sclk:OUTStd_Logic:='0');
END flipchip;
ARCHITECTURE behave OF flipchip IS
SIGNALcom_cpu: STD_LOGIC_VECTOR(7 DOWNTO 0); --Buffered Command from CPU
SIGNALdata_cpu: STD_LOGIC_VECTOR(7 DOWNTO 0); --Buffered Set_Data from CPU
SIGNALdata_ret:STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL start_ser:STD_LOGIC :='0';
BEGIN
P_Sclk:
PROCESS(start_ser,gclk)
VARIABLE clk_count:INTEGER RANGE -1 TO 35:=0;
BEGIN
IF(start_ser='0') THEN --Count Gclk
clk_count:=-1;
ELSIF(gclk'EVENT AND gclk='1')THEN
IF(clk_count/=35) THEN
clk_count:=clk_count+1;
END IF;
--Read Mode
CASE clk_count IS
WHEN 0 =>sclk<='0';
sden<='1';
sdata<='0';
WHEN 1 => sclk<='0';
sden<='1';--Enable Serial Communication Signal
sdata<=com_cpu(0);
WHEN 2 =>sclk<='1';--1
WHEN 3=> sclk<='0';
sdata<=com_cpu(1);
WHEN 4=> sclk<='1';--2
WHEN 5 => SCLK<='0';
sdata<=com_cpu(2);
WHEN 6 => sclk<='1';--3
WHEN 7 => sclk<='0';
sdata<=com_cpu(3);
WHEN 8 => sclk<='1';--4
WHEN 9 => sclk<='0';
sdata<=com_cpu(4);
WHEN 10=>sclk<='1';--5
WHEN 11=> SCLK<='0';
sdata<=com_cpu(5);
WHEN 12=> sclk<='1';--6
WHEN 13=> sclk<='0';
sdata<=com_cpu(6);
WHEN 14=> sclk<='1';--7
WHEN 15=> sclk<='0';
sdata<=com_cpu(7);
WHEN 16=> sclk<='1';--8
sdata<=com_cpu(7);
sdata<='Z';
WHEN 17=> sclk<='0';
data_ret(0)<=sdata;
WHEN 18=> sclk<='1';--9
WHEN 19=> sclk<='0';
data_ret(1)<=sdata;
WHEN 20 => sclk<='1';--10
WHEN 21=> sclk<='0';
data_ret(2)<=sdata;
WHEN 22=> sclk<='1';--11
WHEN 23=> sclk<='0';
data_ret(3)<=sdata;
WHEN 24=> sclk<='1';--12
WHEN 25=> sclk<='0';
data_ret(4)<=sdata;
WHEN 26=> sclk<='1';--13
WHEN 27=> sclk<='0';
data_ret(5)<=sdata;
WHEN 28=> sclk<='1';--14
WHEN 29=> sclk<='0';
data_ret(6)<=sdata;
WHEN 30=> sclk<='1';--15
WHEN 31=> sclk<='0';
data_ret(7)<=sdata;
WHEN 32=> sclk<='1';--16
WHEN 33 TO 34=>sclk<='0';
sdata<='0';
WHEN 35=>sclk<='0';
sdata<='0';
sden<='0';
WHEN others=>sclk<='0';
sdata<='0';
END CASE;
END IF;--End gclk
END PROCESS P_Sclk;
latch_up_com:--Latch the Set_Command from CPU
PROCESS(en_ser)
VARIABLE count_en_ser: INTEGER RANGE -1 TO 2 :=-1;
BEGIN
IF(en_ser'EVENT AND en_ser='1') THEN
IF(count_en_ser=2) THEN
count_en_ser:=0;
en_out<='0';
ELSE
count_en_ser:=count_en_ser+1;
en_out<='0';
END IF;
ENDIF;
--Read Input Command_Data TO Buffer
CASE count_en_ser IS
WHEN 0 =>start_ser<='0';
com_data<="ZZZZZZZZ";
com_cpu<=com_data;
WHEN 1 =>start_ser<='1';
WHEN2 =>start_ser<='0';
com_data<=data_ret;
WHEN OTHERS =>start_ser<='0';
com_data<=data_ret;
END CASE;
END PROCESS latch_up_com;
END behave;
因SCLK时钟高达50M,在SCLK及SDATA输出时CPU无法干预SDATA的输入输出状态,只能由CPLD控制
SDATA模式切换,所以即使CPLD有输出使能控制信号OE,CPU也无法控制。
现在主要是该串行通信功能实现,小弟折腾了一个月也没有结果,急啊!
现在时间很紧,不知各位大侠能否指点菜鸟!不胜感激!

CPLD双向I/O口问题请教!(重新整理)  
你也知道时钟高达50M阿
双向口是有三态门来控制的,去看看三态门的资料
由z到0需要一段无信号时间的,所以不能脱离硬件来进行vhdl编程

CPLD双向I/O口问题请教!(重新整理)  
zhoujj同学不要谈虎色变嘛。
50M时钟用三态总线没有问题。
建议你按照这三个en_ser信号脉冲先做一个简单状态机。每种状态下再分别实现自己的功能。

CPLD双向I/O口问题请教!(重新整理)  
工作可靠吗
出现异常,没有连续3个en_ser时怎么办

CPLD双向I/O口问题请教!(重新整理)  
sorry,我是上次被我的那个板子搞怕了,^_^
不过我看到他的问题,我还是好好看了看的

CPLD双向I/O口问题请教!(重新整理)  
现在不管用什么方法,都要实现I/O口模式切换。“ oe可以用内部逻辑产生”这句话是什么意思,是不是用一个SIGNAL 可以用作使能端。能否说详细一点!谢谢!

CPLD双向I/O口问题请教!(重新整理)  
那句话是针对你的上个帖子的,你不是说io管脚不够么,就说也可以内部产生oe。当初我还以为oe是对应你cpu的w/r信号。
现在给你的建议是 case clk_count 17 到 35 里面都加一句 sdata<='Z';
其实这种写法不很正规,但是要你的程序改得最小,估计只能这样了。

CPLD双向I/O口问题请教!(重新整理)  
谢谢你的指教! 但我还有疑问:
case clk_count 17 到 35 里面都加一句 sdata<='Z'
我试过,好像也不对。
我当时把SDATA接一个10K电阻连到VCC,前8个时钟SDATA输出数据正确,但后8个时钟
用示波器看SDATA为低电平,如果SDATA成功切换到输入模式,我想此时SDATA应该为高电平。不知是不是这样。

CPLD双向I/O口问题请教!(重新整理)  
对,如果cpld输出高阻,而你外面上拉的话应该是高电平,但是有一种可能,就是你的后端芯片正在对cpld输出全‘0’的数据。
sdata<='Z'
这句肯定是要的,可能程序的其他部分没有配合好,你有没有试过仿真?或者把内部信号引出来看看?

CPLD双向I/O口问题请教!(重新整理)  
SDATA并没有跟外部芯片连接,也就是SDATA仅仅通过电阻连到VCC.不存在后端芯片输出对SDATA影响的问题。
我现在想知道按照我的程序思路有没有可能实现该功能,如果不能实现的话我只能另外换方案了,有可能实现的话,我再折腾也不会白费功夫。

可以实现,但是你的count_en_set最好每三个有个同步信号。否则一旦出错就很难补救了。

CPLD双向I/O口问题请教!(重新整理)  
谢谢!
那我再折腾一下,count_en_ser同步信号应该不会有太大问题,三个脉冲信号是由
CPU发出来的,我可以控制。经测试没有什么问题,就是有问题解决也不会很困难!
我再自己多试试,可能还会有问题要麻烦您!真的很感激您的帮助!

CPLD双向I/O口问题请教!(重新整理)  
不客气。搞技术嘛,就要多交流。:)

踩踩踩踩踩踩踩踩从踩踩踩踩

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

网站地图

Top