这是我的VHDL代码:
entity Operation is
port (
clk16: in std_logic; // 16 MHz input clock
start_cmd: inout std_logic; // open drain line. When CPLD sees it is pulled low, it keeps pulling it low till the operation is finished
clk_out: buffer std_logic; // output clock derived from clk16
);
end Operation;
architecture a of Operation is
type T_STATE is (STOPPED, STARTING, ....another states....);
signal state: T_STATE := STOPPED;
begin
process (clk16, clk_out)
begin
if rising_edge(clk16) then
clk_out <= not clk_out; -- create clk_out clock
end if;
if rising_edge(clk_out) then
case state is
when STOPPED =>
if start_cmd = '0' then
state <= STARTING;
start_cmd <= '0' -- sometimes this doesn't happen
end if;
when STARTING =>
-- code continues here.... after the operation is finished, start_cmd <= 'Z' is "executed"
我已将start_cmd信号连接到我的CPLD。带上拉的开漏信号也连接到另一个设备。当另一个设备希望CPLD开始某些操作时,它将start_cmd拉低。当CPLD看到start_cmd为低电平时,它还将线拉低。稍后,另一台设备释放了该线路。 CPLD的操作完成后,CPLD释放该行。由于现在没有人将线拉低,因此线变高。然后另一台设备知道CPLD的操作已完成。
问题在于有时(10%)start_cmd <='0'未被“执行”,因此一旦另一台设备停止将start_cmd拉低,start_cmd信号将返回高电平。然后另一台设备检测到错误的“操作已完成”。
您能看到为什么有时未“执行” start_cmd <='0'的任何问题吗?
我使用示波器调试了设备,可以看到这种情况发生在另一台设备恰好在clk_out的上升沿将start_cmd拉至低电平时。
此VHDL使用Quartus Prime在MAX V CPLD上实现。
答案 0 :(得分:0)
首先-我认为您应该在启动时始终使用'Z'初始化inout
将新状态INIT添加到T_STATE
type T_STATE is (INIT,STOPPED, STARTING, ....another states....);
并将状态初始化为INIT
signal state: T_STATE := INIT;
case state is
when INIT =>
start_cmd <= 'Z';
state <= STOPPED;
when STOPPED =>
:
第二,我不确定clk_out缓冲区的要求。除非有特定原因,否则我认为这不是必需的。看来您只需要
if falling_edge(clk16) then
case state is
: