Перейти к содержанию

    

Двухпортовая память в режиме записи-чтения

Имеется двухпортовая память типа

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?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

немного смущает что

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

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

посмотрите по этой ссылке

там организовано чтение по 16 бит, думаю сделать 32 бита не будет сложным...

Поделиться сообщением


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

Спасибо. Смысл понятен.

По ходу появилась похожая задачка, только немного наоборот. Записываются данные в память побайтно, а читать нужно по 32 бита сразу.

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

посмотрите по этой ссылке

Спасибо. Какраз по теме.

Изменено пользователем Acvarif

Поделиться сообщением


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

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

 

Найдите 32 битную память с побайтовым доступом, и поставьте 4 банка в параллель, объединив байт енайблы по битно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Имеется двухпортовая память типа

entity ramdata is

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

 

Предполагается использовать ее для записи 128 бит информации одним импульсом записи, а считывать четырьмя импульсами чтения по 32 бита.

Похоже на глупость, но все-же...

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

 

https://www.xilinx.com/support/documentatio..._4/xst_v6s6.pdf

Страница 244

Изменено пользователем Burenkov Sergey

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Найдите 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 для чтения и записи нужно будет разделить.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
Авторизация