Оба края Clk в кодировании синтеза VHDL - PullRequest
0 голосов
/ 08 января 2019

Стили кодирования синтеза будут внедряться в будущем? Или стандарт 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 голосов
/ 08 января 2019

Рабочая группа предоставила шаблоны и правила для создания стилей кодирования. Приведенные выше примеры показывают некоторые потенциальные возможности. Конечно, я недавно не видел первый стиль кодирования, хотя, как я прокомментировал, я думаю, что в то время я смог найти такой регистр в библиотеке 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 ;

Вы также можете считать, что стиль кодирования, который требуется некоторым поставщикам ПЛИС, не является языковым. Тип разделяемой переменной должен быть защищенным типом. Совместно используемые переменные с обычными типами были временно разрешены в VHDL-93, но, как отмечено в VHDL-93, это было исправлено в следующей редакции, которая является VHDL-2000/2002.

Если поставщики ПЛИС хотят сделать что-то эффективное и законное на языке, они могут заменить свой нелегальный код на код OSVVM MemoryPkg, чтобы реализовать модели памяти в качестве надлежащего защищенного типа. Причина, по которой я говорю, что это эффективно, заключается в том, что MemoryPkg реализует структуру данных, которая реализует только память, как она используется. Вы можете найти OSVVM на github и osvvm.org.

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, либо - не верьте мне, попробуйте взять код из rise_edge и использовать все это в операторе if для создания триггера.

0 голосов
/ 08 января 2019

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, специфичных для технологии.

...