Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: использование двух портовой памяти
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Языки проектирования на ПЛИС (FPGA)
Maverick
Мне один человек утверждает, что при работе с блочной памятью в 7 серией xilinx (в частности Zynq),
нужно работать следующим образом при чтении
Цитата
выставил адрес - пропустил такт - прочитал данные с памяти. Получается чтение за 2 такта.

Иначе можно прочитать предыдущие данные.
При работе с альтерой я не замечал такой "особенности" работы с памятью.
Читал данные следующим образом:
Цитата
выставил адрес, на следующем такте прочитал данные из памяти

Пример описаниия памяти я привел ниже

Код
--пример описания памяти
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use IEEE.NUMERIC_STD.ALL;

entity bram_tdp is
generic (
    DATA    : integer := 32;
    ADDR    : integer := 8
);
port (
    -- Port A
    a_clk   : in  std_logic;
    a_wr    : in  std_logic;
    a_addr  : in  std_logic_vector(ADDR-1 downto 0);
    a_din   : in  std_logic_vector(DATA-1 downto 0);
    a_dout  : out std_logic_vector(DATA-1 downto 0);

    -- Port B
    b_clk   : in  std_logic;
    b_wr    : in  std_logic;
    b_addr  : in  std_logic_vector(ADDR-1 downto 0);
    b_din   : in  std_logic_vector(DATA-1 downto 0);
    b_dout  : out std_logic_vector(DATA-1 downto 0)
);
end bram_tdp;

architecture rtl of bram_tdp is
    -- Shared memory
    type mem_type is array ( (2**ADDR)-1 downto 0 ) of std_logic_vector(DATA-1 downto 0);
    
   -- FUNCTION initialize_ram  return mem_type is variable result : mem_type;
   -- BEGIN
        -- FOR i IN ((2**ADDR)-1) DOWNTO 0 LOOP
            -- result(i) := std_logic_vector( to_unsigned(natural(i), natural'(DATA)));
        -- END LOOP;
   -- RETURN result;
   -- END initialize_ram;
    
    shared variable mem : mem_type; -- := initialize_ram; --mem_type

    begin

-- Port A
process(a_clk)
begin
    if(a_clk'event and a_clk='1') then
        if(a_wr='1') then
            mem(conv_integer(a_addr)) := a_din;
        end if;
        a_dout <= mem(conv_integer(a_addr));
    end if;
end process;

-- Port B
process(b_clk)
begin
    if(b_clk'event and b_clk='1') then
        if(b_wr='1') then
            mem(conv_integer(b_addr)) := b_din;
        end if;
        b_dout <= mem(conv_integer(b_addr));
    end if;
end process;

end rtl;


Прошу подтвердить/опровергнуть данное утверждение и/или поделиться опытом...
Спасибо
RobFPGA
Приветствую!

Цитата(Maverick @ Jan 23 2018, 23:48) *
Мне один человек утверждает, что при работе с блочной памятью в 7 серией xilinx (в частности Zynq),
...

А мне одна бабка говорила что полезно читать соответствующие доки (ug437) для снятия сомнений.

Блочная память в Xilinx и в 7 семействе в частности может иметь 1 или 2 такта latency на чтение в зависимости от того как Вы ее скофигурировали.
Соответственно и читать надо на нужном такте.

Удачи! Rob.



Maverick
Цитата(RobFPGA @ Jan 23 2018, 23:51) *
Приветствую!


А мне одна бабка говорила что полезно читать соответствующие доки (ug437) для снятия сомнений.

Блочная память в Xilinx и в 7 семействе в частности может иметь 1 или 2 такта latency на чтение в зависимости от того как Вы ее скофигурировали.
Соответственно и читать надо на нужном такте.

Удачи! Rob.

Да, вы правы этот документ ug437 давно не читал (virtexll)...
Читал
7 Series FPGAs Memory Resources
User Guide UG473 (v1.12) September 27, 2016

Пример описания я привел, чтение там за один такт(латентность равна1).
Человек ссылается на большой практический опыт...
Мой опыт не совпадает с опытом человека,.
Из-за этого спор и возник
просто мне интересно опыт других.

Bad0512
Цитата(Maverick @ Jan 24 2018, 05:22) *
Пример описания я привел, чтение там за один такт(латентность равна1).
Человек ссылается на большой практический опыт...
Мой опыт не совпадает с опытом человека,.
Из-за этого спор и возник
просто мне интересно опыт других.

А проверка в банальном симуляторе не поможет уважаемым специалистам установить истину?
Как уже говорили - возможны оба варианта. При задержке в 2 такта задействуются (если синтезатор не затупил) регистры внутри примитива памяти и
существенно улучшается времянка по выходу порта данных (см. например ds181 p22.).

Maverick
Цитата(Bad0512 @ Jan 24 2018, 04:02) *
А проверка в банальном симуляторе не поможет уважаемым специалистам установить истину?

не поверите, но оказывается есть еще люди, которые не верят симуляции, верят только осцилографу.
Соответствено в их проектах есть vhdl/verilog для синтеза и С/С++ для процессора.
lembrix
Так у Альтеры тоже два такта на чтение. По фронту 1 выставил адрес, по фронту 2 адрес защелкивается в обязательном входном регистре блока памяти, по фронту 3 можно забирать данные с выхода. А можно включить регистр выходных данных и тогда будет еще 1 такт задержки.

Хотя в тех семействах с которыми я работаю используется только M9K память. В MLAB, кажется, можно отключать регистр по входу адреса и тогда действительно чтение будет в 1 такт.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.