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