Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Spartan 2 объединение блочной и распределенной памяти
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Работаем с ПЛИС, области применения, выбор
putio
На отладочной плате нужен блок паралельной RAM чуть большей чем возможное кол-во блочной.
Можно ли соединить в одно ресурсы блочной и распределенной памяти?
Был бы очень благодарен за какие-то примеры.
Поиском не нашел.
Boris_TS
Цитата(putio @ Oct 16 2011, 21:59) *
На отладочной плате нужен блок паралельной RAM чуть большей чем возможное кол-во блочной.
Можно ли соединить в одно ресурсы блочной и распределенной памяти?

Можно, тут на выбор: либо городить кучу мультиплексоров (можно на логике быстрого переноса) - если частота большая; или можно воспользоваться BUFT, которые, пока еще есть в Spartan-2.

Для более точных ответов необходимо знать:
1. какой именно кристалл Вы используете.
2. какой надо сделать массив ОЗУ (сколько на сколько).
3. частота, на которой это всё должно работать.
ivanoffer
Цитата(Boris_TS @ Oct 16 2011, 21:58) *
Можно, тут на выбор: либо городить кучу мультиплексоров (можно на логике быстрого переноса) - если частота большая; или можно воспользоваться BUFT, которые, пока еще есть в Spartan-2.


Скорее склеить "в одно" из двух типов памяти на BRAM и распределенной памяти. По упрощенному пути - из корегена
получить два модуля памяти (на BRAM и на распределенной) и обернуть их своей надстройкой. Подобное проделывал.
О потенциальной скорости стоит забыть, да и исходной информации малова-то на что Boris_TS указал.
putio
Сейчас возникло целые две задачи, где нужно было бы это провернуть -
чипы
XC2S200 есть 56K блочных, нужно сделать 70
XC3S400 есть 288K блочных, нужно сделать 344 и то этого маловато

Сколько на сколько - уточняю. Утром скажут.

Я с такими вопросами раньше не сталкивался, но хороший друг попросил
в 2-х паралельных проектах кбайты с кбитами попутал. Ориентировался, что памяти с запасом. Теперь горит.

Сейчас постараюсь найти инфу о том, что вы написали. Спасибо за наводки.


Цитата(Boris_TS @ Oct 16 2011, 21:58) *
Можно, тут на выбор: либо городить кучу мультиплексоров (можно на логике быстрого переноса) - если частота большая; или можно воспользоваться BUFT, которые, пока еще есть в Spartan-2.

Для более точных ответов необходимо знать:
1. какой именно кристалл Вы используете.
2. какой надо сделать массив ОЗУ (сколько на сколько).
3. частота, на которой это всё должно работать.



Boris_TS
Цитата(putio @ Oct 16 2011, 23:56) *
XC2S200 есть 56K блочных, нужно сделать 70
Хреново дело, может почти вся ПЛИС уйти на организацию ОЗУ...

Цитата(putio @ Oct 16 2011, 23:56) *
XC3S400 есть 288K блочных, нужно сделать 344 и то этого маловато
Очень хреново дело, т.к. 288K - это если все 9 бит задействовать в каждом блоке - а получается такое далеко не во всех случаях... в добавок, в Spartan-3 нет BUFT, которые могли бы неплохо помочь в этой ситуации...

Цитата(putio @ Oct 16 2011, 23:56) *
Сколько на сколько - уточняю. Утром скажут.
От «Сколько на сколько», очень много зависит - без этой информации я не смогу что-либо более конкретное посоветовать.
imperman
Цитата(Boris_TS @ Oct 17 2011, 13:31) *
Хреново дело, может почти вся ПЛИС уйти на организацию ОЗУ...

Очень хреново дело, т.к. 288K - это если все 9 бит задействовать в каждом блоке - а получается такое далеко не во всех случаях... в добавок, в Spartan-3 нет BUFT, которые могли бы неплохо помочь в этой ситуации...

От «Сколько на сколько», очень много зависит - без этой информации я не смогу что-либо более конкретное посоветовать.


Да, я уже тоже прихожу к мысли, что плохо дело из того, что успел почитать.
Spartan 2 - почти гвоздями прибили к плате дополнительную память.
Spartan 3 - получилось довесить I2C SROM, но нужна паралельная... не знаю реально ли сделать обертку в ПЛИС для паралельности. Потом данные идут в PCI-E.
Идеально было бы сделать 530Килобит, но это значит - точно использовать SPROM
Или же нужно как-то просто выжать по максимуму 3s400.
Нужно Xx32 (PCI-E 32 bit)

Boris_TS
Цитата(imperman @ Oct 17 2011, 17:53) *
Spartan 3 - получилось довесить I2C SROM, но нужна параллельная... не знаю реально ли сделать обертку в ПЛИС для параллельности. Потом данные идут в PCI-E.
Что-то как-то непонятно... PCI-E оно очень быстрое, а I2C SROM - очень медленное, да еще и с ограниченным количеством перезаписей. Соответственно, пока PCI-E успеет прокачать несколько пакетов, байт эдак по 128, I2C SROM вряд ли даже успеет один такой блок в себя записать... - так что его применимость для меня - загадка... однако, и проект не мой.
Может проще сделать PCI-E Master, который будет худо-бедно (зато примитивно и ресурсоэкономично) наталкивать данные в ОЗУ машины ?

Цитата(imperman @ Oct 17 2011, 17:53) *
Или же нужно как-то просто выжать по максимуму 3s400.
Нужно Xx32 (PCI-E 32 bit)
Yx32 что-то хреново получается в Spartan-3.
А вот 2048x64 можно реализовать на 7 RAM и 466 LUT (210 - на логику и 256 - на саму память) - итого: 6.5% LUT (7.1% SliceM) + 43.7% RAMB (осталось 9 RAMB)..

2048x128 можно реализовать на 14 RAM и 792 LUT (280 - на логику и 512 - на саму память) - итого: 11.0% LUT (14.2% SliceM) + 87.5% RAMB (осталось 2 RAMB).

В обоих случаях прийдётся немного потратить логики на схему, которая будет производить запись в ОЗУ (собирать 2/4 группы по 32 в единую порцию 64/128 бит) и аналогично добавить дополнительный выходной мультиплексор.

Оставшиеся RAMB и SliceM можно использовать в каких-либо более мелких местах - сдаётся мне они тоже должны быть.

Для тех, кто хочет сам что-то ручками повертеть, прикинуть так и эдак:
Код
library IEEE;
use IEEE.Std_Logic_1164.all;
use IEEE.Std_Logic_unsigned.all;

entity qwe is generic (
    constant cnRAM_W:    positive := 11
); port (
    WR_A:    in    std_logic_vector(cnRAM_W-1 downto 0);
--    WR_D:    in    std_logic_vector(31 downto 0);
--    WR_D:    in    std_logic_vector(63 downto 0);
    WR_D:    in    std_logic_vector(127 downto 0);
    WR_C:    in    std_logic;
    RD_A:    in    std_logic_vector(cnRAM_W-1 downto 0);
--    RD_D:    out    std_logic_vector(31 downto 0);
--    RD_D:    out    std_logic_vector(63 downto 0);
    RD_D:    out    std_logic_vector(127 downto 0);
    RD_C:    in    std_logic
);
end entity;

architecture Tushka of qwe is
    constant cnRAM_D:    positive := 2**cnRAM_W;
    
--    alias    RAMB_WR_D:    std_logic_vector(26 downto  0) is WR_D(26 downto  0);
--    alias    RAMD_WR_D:    std_logic_vector(31 downto 27) is WR_D(31 downto 27);

--    alias    RAMB_WR_D:    std_logic_vector(62 downto  0) is WR_D(62 downto  0);
--    alias    RAMD_WR_D:    std_logic_vector(63 downto 63) is WR_D(63 downto 63);
    
    alias    RAMB_WR_D:    std_logic_vector(125 downto   0) is WR_D(125 downto   0);
    alias    RAMD_WR_D:    std_logic_vector(127 downto 126) is WR_D(127 downto 126);
    
    alias    RAMB_RD_D:    std_logic_vector(RAMB_WR_D'Range) is RD_D(RAMB_WR_D'Range);
    alias    RAMD_RD_D:    std_logic_vector(RAMD_WR_D'Range) is RD_D(RAMD_WR_D'Range);
    
    type    taRAMB is array (0 to cnRAM_D-1) of std_logic_vector(RAMB_WR_D'Range);
    type    taRAMD is array (0 to cnRAM_D-1) of std_logic_vector(RAMD_WR_D'Range);
    
    signal    aRAMB:    taRAMB;
    signal    aRAMD:    taRAMD;
    
    attribute RAM_Style:  string;
    attribute RAM_Style of aRAMD: signal is "distributed";
begin
    process(WR_C) begin
        if rising_edge(WR_C) then
            aRAMB(conv_integer(WR_A)) <= RAMB_WR_D;
            aRAMD(conv_integer(WR_A)) <= RAMD_WR_D;
        end if;
    end process;
    
    process(RD_C) begin
        if rising_edge(RD_C) then
            RAMB_RD_D <= aRAMB(conv_integer(RD_A));
            RAMD_RD_D <= aRAMD(conv_integer(RD_A));
        end if;
    end process;
    
end architecture;

P.S. компилировал на ISE 10.1 SP3.
imperman
>Что-то как-то непонятно... PCI-E оно очень быстрое, а I2C SROM - очень медленное, да еще и с ограниченным количеством перезаписей.
В том-то и дело sm.gif А довесить получилось только I2C шину.
Огромное спасибо за ответ, сейчас буду разбираться с новой информацией.


Цитата(Boris_TS @ Oct 19 2011, 19:55) *
Что-то как-то непонятно... PCI-E оно очень быстрое, а I2C SROM - очень медленное, да еще и с ограниченным количеством перезаписей. Соответственно, пока PCI-E успеет прокачать несколько пакетов, байт эдак по 128, I2C SROM вряд ли даже успеет один такой блок в себя записать... - так что его применимость для меня - загадка... однако, и проект не мой.
Может проще сделать PCI-E Master, который будет худо-бедно (зато примитивно и ресурсоэкономично) наталкивать данные в ОЗУ машины ?

Yx32 что-то хреново получается в Spartan-3.
А вот 2048x64 можно реализовать на 7 RAM и 466 LUT (210 - на логику и 256 - на саму память) - итого: 6.5% LUT (7.1% SliceM) + 43.7% RAMB (осталось 9 RAMB)..

2048x128 можно реализовать на 14 RAM и 792 LUT (280 - на логику и 512 - на саму память) - итого: 11.0% LUT (14.2% SliceM) + 87.5% RAMB (осталось 2 RAMB).

В обоих случаях прийдётся немного потратить логики на схему, которая будет производить запись в ОЗУ (собирать 2/4 группы по 32 в единую порцию 64/128 бит) и аналогично добавить дополнительный выходной мультиплексор.

Оставшиеся RAMB и SliceM можно использовать в каких-либо более мелких местах - сдаётся мне они тоже должны быть.

Для тех, кто хочет сам что-то ручками повертеть, прикинуть так и эдак:
Код
library IEEE;
use IEEE.Std_Logic_1164.all;
use IEEE.Std_Logic_unsigned.all;

entity qwe is generic (
    constant cnRAM_W:    positive := 11
); port (
    WR_A:    in    std_logic_vector(cnRAM_W-1 downto 0);
--    WR_D:    in    std_logic_vector(31 downto 0);
--    WR_D:    in    std_logic_vector(63 downto 0);
    WR_D:    in    std_logic_vector(127 downto 0);
    WR_C:    in    std_logic;
    RD_A:    in    std_logic_vector(cnRAM_W-1 downto 0);
--    RD_D:    out    std_logic_vector(31 downto 0);
--    RD_D:    out    std_logic_vector(63 downto 0);
    RD_D:    out    std_logic_vector(127 downto 0);
    RD_C:    in    std_logic
);
end entity;

architecture Tushka of qwe is
    constant cnRAM_D:    positive := 2**cnRAM_W;
    
--    alias    RAMB_WR_D:    std_logic_vector(26 downto  0) is WR_D(26 downto  0);
--    alias    RAMD_WR_D:    std_logic_vector(31 downto 27) is WR_D(31 downto 27);

--    alias    RAMB_WR_D:    std_logic_vector(62 downto  0) is WR_D(62 downto  0);
--    alias    RAMD_WR_D:    std_logic_vector(63 downto 63) is WR_D(63 downto 63);
    
    alias    RAMB_WR_D:    std_logic_vector(125 downto   0) is WR_D(125 downto   0);
    alias    RAMD_WR_D:    std_logic_vector(127 downto 126) is WR_D(127 downto 126);
    
    alias    RAMB_RD_D:    std_logic_vector(RAMB_WR_D'Range) is RD_D(RAMB_WR_D'Range);
    alias    RAMD_RD_D:    std_logic_vector(RAMD_WR_D'Range) is RD_D(RAMD_WR_D'Range);
    
    type    taRAMB is array (0 to cnRAM_D-1) of std_logic_vector(RAMB_WR_D'Range);
    type    taRAMD is array (0 to cnRAM_D-1) of std_logic_vector(RAMD_WR_D'Range);
    
    signal    aRAMB:    taRAMB;
    signal    aRAMD:    taRAMD;
    
    attribute RAM_Style:  string;
    attribute RAM_Style of aRAMD: signal is "distributed";
begin
    process(WR_C) begin
        if rising_edge(WR_C) then
            aRAMB(conv_integer(WR_A)) <= RAMB_WR_D;
            aRAMD(conv_integer(WR_A)) <= RAMD_WR_D;
        end if;
    end process;
    
    process(RD_C) begin
        if rising_edge(RD_C) then
            RAMB_RD_D <= aRAMB(conv_integer(RD_A));
            RAMD_RD_D <= aRAMD(conv_integer(RD_A));
        end if;
    end process;
    
end architecture;

P.S. компилировал на ISE 10.1 SP3.

ynt
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.