VHDL综合编码中Clk的两个边缘

时间:2019-01-08 11:43:12

标签: vhdl xilinx synthesis

综合编码样式将在将来实现吗? 还是IEEE-1076.6-200X标准现在允许简化和增强VHDL综合编码能力?

--Multiple Edge Registers
--Copyright © 2004 SynthWorks Design Inc. All Rights Reserved.
DualEdgeFF : process( nReset, Clk1, Clk2)
begin
  if (nReset = '0') then
    Q <= '0' ;
  elsif rising_edge(Clk1) then -- Functional Clock
    Q <= D ;
  elsif rising_edge(Clk2) then -- Scan Clock
    Q <= SD ;
  end if ;
  -- RTL_SYNTHESIS OFF
  if rising_edge(Clk1) and rising_edge(Clk2) then
    report "Warning: . . ." severity warning ;
    Q <= 'X' ;
  end if ;
-- RTL_SYNTHESIS ON
end process;

--Register Using Both Edges of Clk
DualEdge_Proc: process (Clk, Reset) is
begin
  if Reset = '1' then
    Q <= (others => '0');
  elsif rising_edge(Clk) then
    Q <= D4Rise;
  elsif falling_edge(Clk) then
    Q <= D4Fall;
  end if;
end process DualEdge_Proc;

2 个答案:

答案 0 :(得分:0)

if (nReset = '0') then Q <= '0' ; elsif rising_edge(Clk1) then -- Functional Clock Q <= D ; elsif rising_edge(Clk2) then -- Scan Clock Q <= SD ; end if ;

这永远无法映射到现实世界中任何明智的事物。这是无效的综合设计。

if Reset = '1' then Q <= (others => '0'); elsif rising_edge(Clk) then Q <= D4Rise; elsif falling_edge(Clk) then Q <= D4Fall; end if;

这可以映射到DDR IO输出寄存器。 FPGA具有此功能,但目前这些工具无法合成此代码。他们将来可能会支持这样的事情。 还有一些问题,例如D4Fall必须从上升沿域恢复时钟。

当前,您必须显式实例化特定于技术的DDR单元。

答案 1 :(得分:0)

工作组提供了用于创建编码样式的模板和规则。上面的示例显示了一些潜在的用法。当然,我最近还没有见过第一种编码风格,尽管正如我评论过的那样,我认为当时我能够在用于扫描逻辑的ASIC库中找到这种寄存器。

但是,今天,如果我们稍微修改所示的代码模板(但仍与1076.6-2004兼容),我们就会发现有用的东西。请注意,我将“ elsif”替换为“ end if”,并将单独的“ if”替换为我的首选编码方式。

MemProc : process (ClkA, ClkB)
  type MemType is array (0 to 1023) of std_logic_vector(7 downto 0) ;
  variable Mem : MemType ;
begin
  if rising_edge(ClkA) then
    DataOutA <= Mem(to_integer(unsigned(AddrA))) ;
    if WriteA = '1' then
      Mem(to_integer(unsigned(AddrA))) := DataInA ;
    end if ;
  end if ;
  if rising_edge(ClkB) then
    DataOutB <= Mem(to_integer(unsigned(AddrB))) ;
    if WriteB = '1' then
      Mem(to_integer(unsigned(AddrB))) := DataInB ;
    end if ;
  end if ;
end process ;

您可能还认为某些FPGA供应商要求的编码风格不合法。共享变量的类型必须是受​​保护的类型。在VHDL-93中,与普通类型的共享变量暂时合法,但是如VHDL-93中所述,此问题在下一修订版VHDL-2000 / 2002中已得到解决。

如果FPGA供应商想要做一些高效且语言合法的事情,则可以用OSVVM MemoryPkg代码替换其非法代码,以将内存模型实现为适当的保护类型。我之所以说这很有效,是因为MemoryPkg实现的数据结构仅在使用时才实现内存。您可以在github和osvvm.org上找到OSVVM。

library OSVVM;
use OSVVM.MemoryPkg.all;

architecture ...
  shared variable ptRam : MemoryPType ;
begin
  ptRam.MemInit(
AddrWidth => Address'length, DataWidth => Data'length
) ;

MemAProc : process (ClkA)
begin
  if rising_edge(ClkA) then
    DataOutA <= ptRam.MemRead(AddrA) ; ;
    if WriteA = '1' then
      ptRam.MemWrite(AddrA, DataInA) ;
    end if ;
  end if ;
end process ;

MemBProc : process (ClkB)
begin
  if rising_edge(ClkB) then
    DataOutB <= ptRam.MemRead(AddrB) ; ;
    if WriteB = '1' then
      ptRam.MemWrite(AddrB, DataInB) ;
    end if ;
  end if ;
end process ;

您可能会说,不,很难综合保护类型。简单的答案是,您不必这样做。您也无法在std_logic_1164或numeric_std中合成大多数代码-不相信我,请尝试从riseing_edge获取代码,并在if语句中使用所有代码来制作触发器。