综合编码样式将在将来实现吗? 还是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;
答案 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语句中使用所有代码来制作触发器。