Jump to content

    
Sign in to follow this  
_ANDREW

как написать на vhdl память

Recommended Posts

здравствуйте.

искал,но не нашёл как на vhdlнаписать модуль памяти с разной разрядностью входной и выходной шины данных. не понятно каким образом объявлять сигнал, если писать в него данные одной разрядности(допустим 8), а читать из него данные другой разрядности(допустим 1). знаю что можно сгенерировать такой модуль в coregenerator, но меня это не устраивает. надо на языке написать. зараннее спасибо.

Share this post


Link to post
Share on other sites

память должна быть двухпортовой, в первом порту шина 8 бит, во втором - 1. соответственно, шина адреса во втором порту на 3 разряда шире.

пример двухпортовой памяти(шаблон из квартуса):

library ieee;
use ieee.std_logic_1164.all;

entity true_dual_port_ram_single_clock is

    generic 
    (
        DATA_WIDTH : natural := 8;
        ADDR_WIDTH : natural := 6
    );

    port 
    (
        clk        : in std_logic;
        addr_a    : in natural range 0 to 2**ADDR_WIDTH - 1;
        addr_b    : in natural range 0 to 2**ADDR_WIDTH - 1;
        data_a    : in std_logic_vector((DATA_WIDTH-1) downto 0);
        data_b    : in std_logic_vector((DATA_WIDTH-1) downto 0);
        we_a    : in std_logic := '1';
        we_b    : in std_logic := '1';
        q_a        : out std_logic_vector((DATA_WIDTH -1) downto 0);
        q_b        : out std_logic_vector((DATA_WIDTH -1) downto 0)
    );

end true_dual_port_ram_single_clock;

architecture rtl of true_dual_port_ram_single_clock is

    -- Build a 2-D array type for the RAM
    subtype word_t is std_logic_vector((DATA_WIDTH-1) downto 0);
    type memory_t is array(addr_a'high downto 0) of word_t;

    -- Declare the RAM signal.    
    signal ram : memory_t;

begin

    -- Port A
    process(clk)
    begin
    if(rising_edge(clk)) then 
        if(we_a = '1') then
            ram(addr_a) <= data_a;

            -- Read-during-write on the same port returns NEW data
            q_a <= data_a;
        else 
            -- Read-during-write on the mixed port returns OLD data
            q_a <= ram(addr_a);
        end if;
    end if;
    end process;

    -- Port B 
    process(clk)
    begin
    if(rising_edge(clk)) then 
        if(we_b = '1') then
            ram(addr_b) <= data_b;

            -- Read-during-write on the same port returns NEW data
            q_b <= data_b;
        else 
            -- Read-during-write on the mixed port returns OLD data
            q_b <= ram(addr_b);
        end if;
    end if;
    end process;

end rtl;

надо только на разные разрядности порты переделать.

Share this post


Link to post
Share on other sites
искал,но не нашёл как на vhdlнаписать модуль памяти с разной разрядностью входной и выходной шины данных. не понятно каким образом объявлять сигнал, если писать в него данные одной разрядности(допустим 8), а читать из него данные другой разрядности(допустим 1).

 

для моделирования легко, для синтеза никак. используйте различные генераторы памяти.

 

надо только на разные разрядности порты переделать.

 

попробуйте сами для начала ;)

Share this post


Link to post
Share on other sites
так о синтезе речи и не шло

 

я конечно не телепат, но с вероятностью 99% следующий вопрос будет, почему при синтезе описанного модуля он занимает не 1 блок памяти, а N %)

Share this post


Link to post
Share on other sites
я конечно не телепат, но с вероятностью 99% следующий вопрос будет, почему при синтезе описанного модуля он занимает не 1 блок памяти, а N %)

я тоже не телепат :laughing: но этот вопрос достаточно разжеван в разделах coding-style в справочниках по средам разработки, там же говорится и про генераторы памяти.

Share this post


Link to post
Share on other sites
я тоже не телепат :laughing: но этот вопрос достаточно разжеван в разделах coding-style в справочниках по средам разработки, там же говорится и про генераторы памяти.

 

ткните носом в Quartus II Handbook Version 9.0 где описано coding-style на DWC память ? В Section II. Design Guidelines -> 6. Recommended HDL Coding Styles -> Inferring Memory Functions from HDL Code ни слова о DWC памяти. Может быть я что то упустил ? :)

Share this post


Link to post
Share on other sites
ткните носом в Quartus II Handbook Version 9.0 где описано coding-style на DWC память ? В Section II. Design Guidelines -> 6. Recommended HDL Coding Styles -> Inferring Memory Functions from HDL Code ни слова о DWC памяти. Может быть я что то упустил ? :)

уели :) читать надо не только в справочнике:

http://www.alteraforum.com/forum/showthread.php?t=5695

там есть пример, написано почему может работать, а может и не работать(если ширины портов не согласованы). понравилась вот эта фраза

As a point of note: Xilinx, synopsis and Mentor tools cant do it either.

Share this post


Link to post
Share on other sites
уели :) читать надо не только в справочнике:

http://www.alteraforum.com/forum/showthread.php?t=5695

там есть пример, написано почему может работать, а может и не работать(если ширины портов не согласованы). понравилась вот эта фраза

 

я может быть не понимаю по английски, но

 

пример приведен Tricky который отмечен как Altera Guru. И если я правильно понимаю его то

 

1.

(this infers dual port ram fine when addr_a/b and data_a/q_b sizes match) :
Код прекрасно инферит рам, кода параметры портов А/В совпадают, т.е. момент DWC тут опущен

 

2.

This is the point, you cannot currently infer a memory with missmatched in/out port sizes. The code was one suggested way it "might" be done. The synthesiser would have to look at the behaviour around the code rather than the declarations, to infer the memory correctly.
Еще одно подтверждение что этот DWC поведенческий код не может инферить DWC память при синтезе.

 

3. Когда martin.xrm приводит код не DWC памяти, как это сделали в своем посте вы, Tricky пишет

That will never work - the mem_type stores 8 bit values, while data in is 64 bits wide.

Насколько я могу судить, синтезируемого поведенческого кода который инферит память с использованием ее DWC возможностей, нет. О чем и говорит и Altera Guru и хендбук на софт от альтеры. И что является дальнейшим предметом обсуждения данной темы %)

Share this post


Link to post
Share on other sites
пример приведен Tricky который отмечен как Altera Guru. И если я правильно понимаю его то 

 

Offtop:

 

Когда-то, увидев на форуме Альтеры ответ на интересующий меня вопрос от человека, отмеченного как "Altera Teacher", я очень обрадовался - мол, представитель Альтеры, наконец-то я узнаю ответ.

 

К сожалению, оказалось, что точного ответа он не знал, а лишь высказывал свои предположения, а надписи типа "Altera Teacher" оказались лишь форумными подписями.  :biggrin:

Edited by des333

Share this post


Link to post
Share on other sites
Насколько я могу судить, синтезируемого поведенческого кода который инферит память с использованием ее DWC возможностей, нет.

таки да. и в том примере, что в конце 2-й страницы, хотя и инферится в двухпортовую память, но с одинаковой разрядностью + еще и мультиплексоры.

вот еще момент:

The synthesiser would have to look at the behaviour around the code rather than the declarations, to infer the memory correctly.

т.е. синтезатор в код даже не глядит, только на декларации?

Share this post


Link to post
Share on other sites
т.е. синтезатор в код даже не глядит, только на декларации?

 

в контексте той темы, я бы перевел эту фразу так "синтезатору потребовалось бы больше смотреть на окружение, а не на декларацию памяти для ее инферирования". Ну или по колхозному не умеет синтезатор оценивать такие ситуации. Все что может это простые чтения/записи, а такие выверты нет.

Share this post


Link to post
Share on other sites

entity ramNxM is
    generic(    AddrWidht : integer := 4;
        DataWidht : integer := 2);
    port (
                clk        : in    std_logic;
                we        : in    std_logic;
                AddrA        : in    std_logic_vector(AddrWidht-1  downto 0);
                DataIn        : in    std_logic_vector(DataWidht-1 downto 0);
                AddrB        : in    std_logic_vector(AddrWidht-1  downto 0);
                DataOutA    : out    std_logic_vector(DataWidht-1 downto 0);
                DataOutB    : out    std_logic_vector(DataWidht-1 downto 0)
             );
end ramNxM;

architecture Behavioral of ramNxM is

    type ram_type is array ((2**AddrWidht - 1) downto 0) of std_logic_vector (DataWidht-1 downto 0);
    signal    RAM    :    ram_type;

begin

process (clk)
begin
    if rising_edge(Clk) then
        if we = '1' then
            RAM(conv_integer(AddrA)) <= DataIn;
        end if;
    end if;
end process;

DataOutA <= RAM(conv_integer(AddrA));
DataOutB <= RAM(conv_integer(AddrB));

end Behavioral;

 

У меня такой код синтезируется в ISE'е. Память правда распределенная, но мне такую и надо.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this