2015-04-16 2 views
1

Мне нужно написать в VHDL программу, которая инициализирует регистры датчиков с помощью i2c. Моя проблема заключается в том, чтобы написать эффективную программу, которая не растрачивает все пространство FPGA. Количество регистров, которые мне нужны для хранения, - это 400 регистров, состоящих из 8-битного адреса и 8-битных данных.Как правильно хранить регистры в FPGA

Программа я пишу:

entity i2cReg is 
    port (
      RegSel : in std_logic; 
      Address : out std_logic_vector (15 downto 0); 
      Data : out std_logic_vector (7 downto 0); 
      RegStop : out std_logic; 
      ModuleEN : in std_logic 
    ); 
end i2cReg; 

architecture i2cReg_archi of i2cReg is 
    signal counter :integer := 0; 

    begin 
     process(RegSel, ModuleEN) 
     begin 
      if ModuleEN = '0' then 
        Address <= x"10"; 
        Data <= x"10"; 
        RegStop <= '0'; 
        counter <= 0; 
      elsif rising_edge(RegSel) then 
       counter <= counter + 1; 
       case counter is 
        when 0 => 
        Address <= x"10"; 
        Data <= x"10"; 
        when 1 => 
        Address <= x"10"; 
        Data <= x"10"; 
        when 2 => 
        Address <= x"10"; 
        Data <= x"10"; 
        when 3 => 
        Address <= x"10"; 
        Data <= x"10"; 
        when 4 => 
        Address <= x"10"; 
        Data <= x"10"; 
        when 5 => 
        Address <= x"10"; 
        Data <= x"10"; 
        when 400 => 
         RegStop <= '1'; 
        when others => 
       end case; 
      end if; 
     end process; 

end i2cReg_archi; 

Существует способ, чтобы оптимизировать этот код? Или вы советуете мне использовать внешний eeprom?

+0

Если FPGA - это тип с примитивом BlockRam, то да, есть способ оптимизировать этот код. –

+0

FPGA имеют тысячи регистров, поэтому использование 400 не является числом ... НО вы правы, чтобы попросить более дешевое решение. Большинство FPGA имеют встроенные оперативные запоминающие устройства в несколько килобайт. Некоторые другие ПЛИС могут использовать там LUT в качестве ОЗУ, которые хороши для хранения данных <1 КБайт. Каков ваш целевой архитектурник? – Paebbels

+0

Я видел, как вы сказали, некоторые FPGA имеют встроенную оперативную память. Но мне нужно хранить эти данные в устройстве и не записывать ОЗУ при включении устройства. Возможно ли использовать это пространство памяти в качестве постоянного хранилища и записать его при программировании устройства? – Yaro

ответ

1

Yaro - вы не упомянули поставщика FPGA или устройство, но ответ: Да, вы можете инициализировать ПЗУ в FPGA, чтобы нужные вам значения присутствовали после настройки. Как Altera, так и Xilinx позволяют вам предоставить файл с начальными значениями во время синтеза.

Kevin.

+0

Просто чтобы прокомментировать (или добавить) на этот ответ (потому что я думаю, что это правильный вариант), если регистры на FPGA необходимо редактировать (или изменять во время выполнения), я бы рекомендовал использовать блок RAM. Это позволит вам значительно упростить ваш дизайн и уменьшить логику, используемую для создания этой карты регистров. – NKamrath

0

Инициализированный BlockRAM в целом является правильным решением, если вы находитесь на Xilinx или Altera.

Но есть исключения, в которых также может работать логическая реализация: Например, если содержимое ваших 400 регистров имеет повторяющиеся шаблоны или множество регистров с одинаковым значением (например, в вашем примере кода). В этом случае, если вы реализуете его как логику, ваш инструмент синтеза оптимизирует его. На самом деле вы можете получить очень небольшое количество логики, если содержимое регистра очень повторяется. Иногда также возможно улучшить оптимизацию путем умного переупорядочения регистров.

100-200 логических ячеек часто считают «дешевле», чем BlockRAM. Но в основном это зависит от того, какой ресурс наиболее ограничен в вашем конкретном приложении.

Независимо от того, если вы идете для инициализации BlockRAM или логики, я бы предложил, чтобы вы моделировали его как массив std_logic_vector вместо использования case/when. Подход «массив std_logic_vector» независим от платформы и может быть синтезирован как для BlockRAM, так и для логики. Ваш инструмент синтеза обычно пытается автоматически выбрать наилучшую реализацию. Но вы также можете заставить инструмент sythesis использовать либо логику, либо BlockRAM, используя атрибуты конкретного поставщика. (Я не могу сказать вам, какие атрибуты использовать, так как я не знаю, какую платформу вы используете)

Пример:

type REG_TYPE is array (0 to 3) of std_logic_vector(15 downto 0); 
constant REGISTERS : REG_TYPE := 
    (x"0000", 
    x"0001", 
    x"0010", 
    x"0100"); 

И в вашем процессе, что-то вроде:

if rising_edge(RegSel) then 
    Address <= REGISTERS(counter)(15 downto 8); 
    Data <= REGISTERS(counter)(7 downto 0); 
end if; 
Смежные вопросы