Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Двухпортовая память в режиме записи-чтения
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Языки проектирования на ПЛИС (FPGA)
Acvarif
Имеется двухпортовая память типа
Код
entity ramdata is

    generic
    (
        DATA_WIDTH : natural;
        ADDR_WIDTH : natural
    );

    port
    (
        rclk    : in std_logic;
        wclk    : in std_logic;
        raddr    : in std_logic_vector (0 to ADDR_WIDTH - 1);
        waddr    : in std_logic_vector (0 to ADDR_WIDTH - 1);
        data    : in std_logic_vector((DATA_WIDTH-1) downto 0);
        we        : in std_logic;
        q        : out std_logic_vector((DATA_WIDTH -1) downto 0)
    );

end ramdata;

architecture behavioural of ramdata is

    subtype byte is std_logic_vector((DATA_WIDTH-1) downto 0);
    type memory is array(2**ADDR_WIDTH-1 downto 0) of byte;

    signal ram : memory;
    attribute ramstyle : string;
--    attribute ramstyle of ram : signal is "M512, no_rw_check";
    attribute ramstyle of ram : signal is "M9K, no_rw_check";
--    attribute ramstyle of ram : signal is "M-RAM";
--    attribute ramstyle of ram : signal is "MLAB, no_rw_check";

begin

    process(wclk)
    begin
    if(rising_edge(wclk)) then
        if(we = '0') then
            ram(conv_integer(waddr)) <= data;
        end if;
    end if;
    end process;

    process(rclk)
    begin
    if(rising_edge(rclk)) then
        if(we = '0') then
            q <= ram(conv_integer(raddr));
        else
            q <= (others => 'Z');
        end if;
    end if;
    end process;
    
end behavioural;


Предполагается использовать ее для записи 128 бит информации одним импульсом записи, а считывать четырьмя импульсами чтения по 32 бита.
Похоже на глупость, но все-же...
Скажите пожалуйста возможно-ли в принципе организовать такой режим записи-чтения? Если да то как это примерно будет выглядеть на VHDL?
Golikov A.
немного смущает что
if(we = '0') then
ram(conv_integer(waddr)) <= data;
это очевидно запись по 0 уровню, при этом
if(we = '0') then
q <= ram(conv_integer(raddr));
это чтение, при том же нулевом уровне, а без него шина в 3 состояние, зачем - то...

потом обычно выход памяти делают комбинаторным по регистру адреса, а адрес защелкивают. Это более классическое описание и в примерах альтеры такое описание (если я правильно помню).

ну и описание у вас как я вижу вход и выход одинаковой ширины. Вы планируете набрать память из 4 блоков?.

тогда все просто данные на вход всех 4 блоков, и врайт енайбл на них на всех сразу. Выходные данные с памяти на мультиплексор, младшие 2 адреса бита выбирают какой из банков вы читаете, при записи 2 младших бита игнорируются. Будет словная запись во все банки, и чтение из каждого банка отдельно. Можно сделать автомат чтения, который будет читать из 4 банков разом, а потом выдавливать наружу по 32

Maverick
посмотрите по этой ссылке
там организовано чтение по 16 бит, думаю сделать 32 бита не будет сложным...
Acvarif
Цитата(Golikov A. @ Oct 6 2017, 15:01) *
тогда все просто данные на вход всех 4 блоков, и врайт енайбл на них на всех сразу. Выходные данные с памяти на мультиплексор, младшие 2 адреса бита выбирают какой из банков вы читаете, при записи 2 младших бита игнорируются. Будет словная запись во все банки, и чтение из каждого банка отдельно. Можно сделать автомат чтения, который будет читать из 4 банков разом, а потом выдавливать наружу по 32

Спасибо. Смысл понятен.
По ходу появилась похожая задачка, только немного наоборот. Записываются данные в память побайтно, а читать нужно по 32 бита сразу.
Я так понимаю в этом случае шина данных должна быть 32 бита, а данные при записи сдвигать на 8 бит 3 раза..? Или можно как-то проще?
Цитата
посмотрите по этой ссылке

Спасибо. Какраз по теме.
Golikov A.
Цитата
Я так понимаю в этом случае шина данных должна быть 32 бита, а данные при записи сдвигать на 8 бит 3 раза..? Или можно как-то проще?

это стандартный режим памяти, обычно шину туда и сюда делают полной 128, при чтении читают все сразу, а при записи добавляют еще 4 сигнала, каждый из который выбирает какие 32 битные слова пишутся. Поставили все 4 единички, пишется 128, поставили 2 единички пишутся 64, поставили одну пишется 32. Сами данные в шине обычно не двигают, то есть если надо записать во 2 банк, ставят 2 единичку и данные на месте второго банка.

Найдите 32 битную память с побайтовым доступом, и поставьте 4 банка в параллель, объединив байт енайблы по битно.
Burenkov Sergey
Цитата(Acvarif @ Oct 6 2017, 14:31) *
Имеется двухпортовая память типа
Код
entity ramdata is

    generic
    (
        DATA_WIDTH : natural;
        ADDR_WIDTH : natural
    );
...


Предполагается использовать ее для записи 128 бит информации одним импульсом записи, а считывать четырьмя импульсами чтения по 32 бита.
Похоже на глупость, но все-же...
Скажите пожалуйста возможно-ли в принципе организовать такой режим записи-чтения? Если да то как это примерно будет выглядеть на VHDL?


https://www.xilinx.com/support/documentatio..._4/xst_v6s6.pdf
Страница 244
Acvarif
Цитата(Golikov A. @ Oct 6 2017, 16:47) *
Найдите 32 битную память с побайтовым доступом, и поставьте 4 банка в параллель, объединив байт енайблы по битно.

Спасибо. Похоже что это
Код
entity byte_enabled_simple_dual_port_ram is

    generic (
        ADDR_WIDTH : natural := 6;
        BYTE_WIDTH : natural := 8;
        BYTES : natural := 4);
  
    port (
        we, clk : in  std_logic;
        be      : in  std_logic_vector (BYTES - 1 downto 0);
        wdata   : in  std_logic_vector(BYTE_WIDTH - 1 downto 0);
        waddr   : in  integer range 0 to 2 ** ADDR_WIDTH -1;
        raddr   : in  integer range 0 to 2 ** ADDR_WIDTH - 1;
        q       : out std_logic_vector(BYTES*BYTE_WIDTH-1 downto 0));
end byte_enabled_simple_dual_port_ram;

architecture rtl of byte_enabled_simple_dual_port_ram is
    --  build up 2D array to hold the memory
    type word_t is array (0 to BYTES-1) of std_logic_vector(BYTE_WIDTH-1 downto 0);
    type ram_t is array (0 to 2 ** ADDR_WIDTH - 1) of word_t;
    -- delcare the RAM
    signal ram : ram_t;
    signal q_local : word_t;

begin  -- rtl
    -- Re-organize the read data from the RAM to match the output
    unpack: for i in 0 to BYTES - 1 generate    
        q(BYTE_WIDTH*(i+1) - 1 downto BYTE_WIDTH*i) <= q_local(i);
    end generate unpack;
        
    process(clk)
    begin
        if(rising_edge(clk)) then
            if(we = '1') then
                -- edit this code if using other than four bytes per word
                if(be(0) = '1') then
                    ram(waddr)(0) <= wdata;
                end if;
                if be(1) = '1' then
                    ram(waddr)(1) <= wdata;
                end if;
                if be(2) = '1' then
                    ram(waddr)(2) <= wdata;
                end if;
                if be(3) = '1' then
                    ram(waddr)(3) <= wdata;
                end if;
            end if;
            q_local <= ram(raddr);
        end if;
    end process;  
end rtl;

Только clk для чтения и записи нужно будет разделить.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.