驱动输入时钟输出

时间:2015-04-18 15:30:06

标签: vhdl clock fpga

我有一个具有8位输入和串行输出的模块,我想序列化输入数据并将其与时钟同步。

我想在下降沿时设置数据然后在时钟上升时等待,当时钟再次下降时我设置另一个数据。我不想将直接参考时钟连接到输出,因为当我不使用该模块时,我想要一个时钟输出状态。

我已尝试过此代码:

process(Clock, ModuleReset)
    begin
        if ModuleReset = '0' then
            OutData <= '0';
            OutCK <= '0';
            counter <= 7;
        elsif falling_edge(Clock) then
                OutCK <= '0';
                OutData <= Data(counter);
        elsif rising_edge(Clock) then
                OutCK <= '1';
        end if;
end process;

合成器给了我这个错误:

  

&#34;不支持SCK的非常量数据的异步加载&#34;

当我将代码分成两个块时,如下所示:

process(Clock, ModuleReset)
    begin
        if ModuleReset = '0' then
            OutData <= '0';
            OutCK <= '0';
            counter <= 7;
        elsif falling_edge(Clock) then
                OutCK <= '0';
                OutData <= Data(counter);
end process;

process(Clock)
        if rising_edge(Clock) then
                OutCK <= '1';
        end if;
end process;

我有这两个错误:

  

&#34;用于净SCK的多个非三态驱动程序&#34;
  &#34;网络SCK&#34;未解决的三态驱动因素

我尝试过的另一个代码是:

process(Clock, ModuleReset)
    if ModuleEN = '1' then
       OutCK <= Clock;
    end if;
    begin
        if ModuleReset = '0' then
            OutData <= '0';
            OutCK <= '0';
            counter <= 7;
        elsif falling_edge(Clock) then
                OutCK <= '0';
                OutData <= Data(counter);
        end if;
end process;

但输出时钟看起来很奇怪,频率不同。

2 个答案:

答案 0 :(得分:1)

我理解的最后一个想法最终为你效劳,是次优的。如果你的时钟很慢,那应该没问题,但我建议你解决它。

if ModuleEN = '1' then
    OutCK <= Clock;
else
    OutCK <= '1';
end if;

产生具有输出时钟信号的组合逻辑。永远不建议将时钟用作逻辑信号,因为时钟使用的时钟路径不能很好地路由到一般的路由资源。输出信号将有潜在的毛刺(输出接口非常糟糕!)和大延迟/偏斜。

使用DDR寄存器转发时钟的第一种方法确实是正确且最好的方法。使用这种方案,您的时钟仅使用时钟路径,如果输出时钟和数据的寄存器都位于IO块中,它们将具有相同的输出延迟且具有非常小的偏斜。

您没有指定您正在使用的技术,但我建议您查找如何编写映射到合成器的DDR寄存器的代码。或者,您可以手动实例化DDR输出寄存器原语,可能是Xilinx的ODDR或altera的ALTDDIO_OUT。

答案 1 :(得分:0)

您尝试的问题确实是您有相同信号的多个驱动程序,或者您在时钟的上升沿和下降沿分配信号。这是不可综合的。

试试这个:

process(Clock, ModuleReset, ModuleEN)
begin
    if ModuleEN = '1' then
        OutCK <= Clock;
    else
        OutCK <= '1';
    end if;

    if ModuleReset = '0' then
        OutData <= '0';
        counter <= 7;
    elsif falling_edge(Clock) then
        OutData <= Data(counter);
    end if;
end process;