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

Как сгенерировать несколько модулей памяти (больше 20)

мне кажется, даже если упростить задачу сделать настоящую двупортовую память, но с одним клоком - все равно не получиться

Т.к. 2 процесса/always

 

Вообще-то это стандартный шаблон квартуса. Тут у синтезатора крышу сносит, как я понимаю, на предмет многомерности массива.

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


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

мне кажется, даже если упростить задачу сделать настоящую двупортовую память, но с одним клоком - все равно не получиться

Т.к. 2 процесса/always

Не, ну тут можно и в одном always написать. В parallel_case, например... Или двумя if один за другим. Только вопрос, поймет ли синтезатор, что от него хотят. Precision понимает true dual port, а вот synplify - нет (в ISPLever 7.0 был пример, из-за чего его и снесли оттуда уже в 7.2).

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


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

А так ли принципиально делать это всё одним модулем? Двумя всё отлично описывается и синтезируется, как я написал в своём предыдущем сообщении.

SM

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

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


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

Приветствую!

 

Ой опоздал :)

 

Synplify нормально понимает tru-dualport во всяком случае для Xilinx.

 

module n_dpram #(parameter
    WHD = 8, 
    WHA = 8, 
    N   = 8  
) (
    input                         clk_a , 
    input        [WHA-1:0] addr_a  [0:N-1],
    input        [WHD-1:0] din_a   [0:N-1],
    input        [  N-1:0] wr_a  ,
    output logic [WHD-1:0] dou_a   [0:N-1],

    input                         clk_b , 
    input        [WHA-1:0] addr_b  [0:N-1],
    input        [WHD-1:0] din_b   [0:N-1],
    input        [  N-1:0] wr_b  ,
    output logic [WHD-1:0] dou_b   [0:N-1]
);

generate
genvar ii;
    for (ii=0; ii<N; ii++) begin  
        logic [WHD-1:0]  mem [0:(1<<WHA)-1];

        always_ff @(posedge clk_a) begin :port_a
            if (wr_a[ii])
                mem[addr_a[ii]]<=din_b[ii];

                dou_a[ii]<=mem[addr_a[ii]];
        end

        always_ff @(posedge clk_b) begin :port_b
            if (wr_b[ii])
                mem[addr_b[ii]]<=din_b[ii];

                dou_b[ii]<=mem[addr_b[ii]];
        end

    end
endgenerate
endmodule

 

Успехов! Rob.

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


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

Приветствую!

 

Ой опоздал :)

 

Synplify нормально понимает tru-dualport во всяком случае для Xilinx.

 

module n_dpram #(parameter
    WHD = 8, 
    WHA = 8, 
    N   = 8  
) (
    input                         clk_a , 
    input        [WHA-1:0] addr_a  [0:N-1],
    input        [WHD-1:0] din_a   [0:N-1],
    input        [  N-1:0] wr_a  ,
    output logic [WHD-1:0] dou_a   [0:N-1],

    input                         clk_b , 
    input        [WHA-1:0] addr_b  [0:N-1],
    input        [WHD-1:0] din_b   [0:N-1],
    input        [  N-1:0] wr_b  ,
    output logic [WHD-1:0] dou_b   [0:N-1]
);

generate
genvar ii;
    for (ii=0; ii<N; ii++) begin  
        logic [WHD-1:0]  mem [0:(1<<WHA)-1];

        always_ff @(posedge clk_a) begin :port_a
            if (wr_a[ii])
                mem[addr_a[ii]]<=din_b[ii];

                dou_a[ii]<=mem[addr_a[ii]];
        end

        always_ff @(posedge clk_b) begin :port_b
            if (wr_b[ii])
                mem[addr_b[ii]]<=din_b[ii];

                dou_b[ii]<=mem[addr_b[ii]];
        end

    end
endgenerate
endmodule

 

Успехов! Rob.

спасибо, буду знать...

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


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

Категорически нельзя в разных always заносить в одну переменную какие либо значения. Именно поэтому нельзя описать dual clock память на HDL.

А я вот даже не знаю, можно ли вообще двухклоковую память самому создать. Имеется в виду на логике, на обычных триггерах. Скорее всего там используются специальные двухклоковые триггеры. Я прав?

 

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


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

Synplify нормально понимает tru-dualport во всяком случае для Xilinx.

 

У меня с этим кодом те же "can't resolve multiple drivers", как и для любого из вариантов, которые я только пытался придумать, когда в двух always заношу данные в одну и ту же переменную (массив).

 

а precision без вопросов!

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


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

Скорее всего там используются специальные двухклоковые триггеры. Я прав?

у каждого входа - свой клок, не 2 разных одновременно для каждого из 2 входов, потому двухклоковые триггеры наверное не нужны...

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


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

там используются специальные двухклоковые триггеры. Я прав?

 

Нет. Там, вообще, используются защелки - LATCH - из слабых транзисторов. А из клоков и WE формируется логикой импульс разрешения записи, который прямо на выход подает сильный уровень, который перебрасывает защелку в новое состояние.

 

post-2881-1427394779_thumb.png

 

Построение памяти на триггерах - это голимое расточительство.

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


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

Нет. Там, вообще, используются защелки - LATCH - из слабых транзисторов. А из клоков и WE формируется логикой импульс разрешения записи, который прямо на выход подает сильный уровень, который перебрасывает защелку в новое состояние.
Тогда этот импульс совсем тонкий. Проводил когда-то эксперимент, даже на совсем незначительном расхождении фронтов на клоках всё нормально отрабатывалось.

 

Построение памяти на триггерах - это голимое расточительство.
А мне как-то раз пришлось. В первом Сыклоне вся хардовая память кончилась, пришлось слов на 50 16-разрядных делать, но это был обычный регистровый файл.

 

Кстати, ради интересу, пытался создать полноценную двухпортовую память на триггерах. Уже не помню чем кончилось, но помню что почти работало.

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


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

Тогда этот импульс совсем тонкий.

По-разному. Обычно, в пол-клока. Тоньше делать нет смысла. То есть, на входе по шине данных стоит триггер, который защелкивает данное по фронту клока, а затем, управление защелкой, которая открывается, пропуская данное, в момент защелкивания данных триггером, и закрывается, защелкивая данное, через пол-периода клока. Поэтому данное оказывается "как бы защелкнутым" сразу после фронта. А с целью предотвращения конфликта двух усилителей записи (сквозного тока), сигнал разрешения первого сбрасывается сигналом разрешения последующего, если импульсы записи пересеклись по времени на одной линии записи.

 

А мне как-то раз пришлось.

Я не про ПЛИС, а про разработку, собственно, самой блочной памяти.

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


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

Присоединяйтесь к обсуждению

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...