реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Xilinx ROM 72x512, XST глючит или я?
sallador
сообщение Oct 7 2015, 08:10
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 50
Регистрация: 10-05-11
Пользователь №: 64 903



Есть вот такой кусочек кода:

Код
type std_logic_array_64xNN is array (511 downto 0) of std_logic_vector(63 downto 0);

-- Инициализирую массив 512х64 функцией read_ini_file.
constant const_init : std_logic_array_64xNN:=read_ini_file(stage_num);

attribute RAM_STYLE : string;
attribute RAM_STYLE of d_out : signal is "block";

begin    
    -- адрес = выход обычного счетчика
    addr <= cnt(stage_num-2 downto 0);    
    -- здесь я пытаюсь сделать ROM 512х64 на BRAM:
    d_out <= const_init(conv_integer(addr)) when rising_edge(clk);

Хочу: чтобы синтезатор сделал Simple dual-port ROM на одном примитиве RAMB36E1.
Из даташита на 7 серию: Each 36 Kb block RAM can be configured as a ... 512 x 72 in simple dual-port mode.

То есть теоретически это реально, но синтезатор ни в какую не хочет задействовать примитив и делает на рассыпухе.
Причем, атрибуты он игнорирует. XST пишет следующее:

Цитата
The RAM <...> will be implemented on LUTs either because you have described an asynchronous read or because of currently unsupported block RAM features. If you have described an asynchronous read, making it synchronous would allow you to take advantage of available block RAM resources, for optimized device usage and improved timings. Please refer to your documentation for coding guidelines.

Но асинхронного чтения нет, все по клоку. Да и возможности BRAM из 7 серии позволяют использовать режим SDP 512x72.
Пробовал расширять разрядность до 72 - безрезультатно!

Использовать coregenerator не хочу, вставлять напрямую библиотеку unisim/unimacro - тоже. Как быть? Почему XST тупит?
Go to the top of the page
 
+Quote Post
Vascom
сообщение Oct 7 2015, 08:13
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 232
Регистрация: 2-08-07
Из: Москва
Пользователь №: 29 534



А почему не хочешь генератор использовать? Он точно всё как надо сделает и сразу покажет сколько блоков памяти будет использовать.
Только что попробовал - элементарно делает и 1 блок RAMB36E1 использует.

Сообщение отредактировал Vascom - Oct 7 2015, 08:16
Go to the top of the page
 
+Quote Post
sallador
сообщение Oct 7 2015, 08:33
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 50
Регистрация: 10-05-11
Пользователь №: 64 903



Цитата(Vascom @ Oct 7 2015, 12:13) *
А почему не хочешь генератор использовать? Он точно всё как надо сделает и сразу покажет сколько блоков памяти будет использовать.
Только что попробовал - элементарно делает и 1 блок RAMB36E1 использует.

Потому что я хочу сделать параметризируемый блок ROM разной глубины.
В зависимости от условий, он может быть 64х1к, 64х8к или, например 64х128к...

Делать кучу корок - не хочется совсем. Хочется понять, как заставить XST не умничать.

P.S. примечательно то, что если я делаю разрядность данных не 64, а например 44, то он делает на 1 RAMB36 и 1 RAMB18. В FPGA Editore - вижу, что сделал на RAMB, но режимы выставил им TDP, а не SDP. Зачем ему лишний RAMB18 понадобился, не пойму.

Но это не решает проблему для разрядности данных = 64.
Go to the top of the page
 
+Quote Post
Maverick
сообщение Oct 7 2015, 08:34
Сообщение #4


я только учусь...
******

Группа: Модераторы
Сообщений: 3 447
Регистрация: 29-01-07
Из: Украина
Пользователь №: 24 839



Код
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(2**ADDR_WIDTH-1 downto 0) of word_t;

    -- Declare the RAM
    shared variable ram : memory_t;

begin


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

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

end rtl;


в генерике надо задать параметры для памяти

PS В template language в среде разработки XST есть все примеры описаний стандартных цифровых устройств


--------------------
If it doesn't work in simulation, it won't work on the board.

"Ты живешь в своих поступках, а не в теле. Ты — это твои действия, и нет другого тебя" Антуан де Сент-Экзюпери повесть "Маленький принц"
Go to the top of the page
 
+Quote Post
sallador
сообщение Oct 7 2015, 08:39
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 50
Регистрация: 10-05-11
Пользователь №: 64 903



Цитата(Maverick @ Oct 7 2015, 12:34) *
в генерике надо задать параметры для памяти

У вас dual-port, а мне нужен single-port.

Например, в Aldec Active-HDL из Language Assistance для single port RAM предлагается такой код:
Код
process (clk)
    variable ram : ram_t;
begin
    if clk'event and clk = '1' then
        if wr_en = '1' then
            ram(conv_integer(addr)) := data_in;
        end if;
        data_out <= ram(conv_integer(addr));
    end if;
end process;

Что совпадает с моими желаниями, за исключением того, что мне не нужна запись, т.к. я делаю ROM.

Добавлено: для Template language из ISE - код практически идентичный.

Сообщение отредактировал sallador - Oct 7 2015, 08:45
Go to the top of the page
 
+Quote Post
Maverick
сообщение Oct 7 2015, 08:48
Сообщение #6


я только учусь...
******

Группа: Модераторы
Сообщений: 3 447
Регистрация: 29-01-07
Из: Украина
Пользователь №: 24 839



Цитата(sallador @ Oct 7 2015, 11:39) *
У вас dual-port, а мне нужен single-port.

Например, в Aldec Active-HDL из Language Assistance для single port RAM предлагается такой код:
Код
process (clk)
    variable ram : ram_t;
begin
    if clk'event and clk = '1' then
        if wr_en = '1' then
            ram(conv_integer(addr)) := data_in;
        end if;
        data_out <= ram(conv_integer(addr));
    end if;
end process;

Что совпадает с моими желаниями, за исключением того, что мне не нужна запись, т.к. я делаю ROM.

Добавлено: для Template language из ISE - код практически идентичный.


так в чем проблема
Код
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity single_port_rom is

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

    port
    (
        clk        : in std_logic;
        addr    : in natural range 0 to 2**ADDR_WIDTH - 1;
        q        : out std_logic_vector((DATA_WIDTH -1) downto 0)
    );

end entity;

architecture rtl of single_port_rom is

    -- Build a 2-D array type for the RoM
    subtype word_t is std_logic_vector((DATA_WIDTH-1) downto 0);
    type memory_t is array(2**ADDR_WIDTH-1 downto 0) of word_t;

    function init_rom
        return memory_t is
        variable tmp : memory_t := (others => (others => '0'));
    begin
        for addr_pos in 0 to 2**ADDR_WIDTH - 1 loop
            -- Initialize each address with the address itself
            tmp(addr_pos) := std_logic_vector(to_unsigned(addr_pos, DATA_WIDTH));
        end loop;
        return tmp;
    end init_rom;    

    -- Declare the ROM signal and specify a default value.    Quartus II
    -- will create a memory initialization file (.mif) based on the
    -- default value.
    signal rom : memory_t := init_rom;

begin

    process(clk)
    begin
    if(rising_edge(clk)) then
        q <= rom(addr);
    end if;
    end process;

end rtl;


добавлено
Если индентично, тогда совет работайте дальше и не обращайте пока на это внимание...


--------------------
If it doesn't work in simulation, it won't work on the board.

"Ты живешь в своих поступках, а не в теле. Ты — это твои действия, и нет другого тебя" Антуан де Сент-Экзюпери повесть "Маленький принц"
Go to the top of the page
 
+Quote Post
sallador
сообщение Oct 7 2015, 09:00
Сообщение #7


Участник
*

Группа: Участник
Сообщений: 50
Регистрация: 10-05-11
Пользователь №: 64 903



Цитата(Maverick @ Oct 7 2015, 12:48) *
добавлено
Если индентично, тогда совет работайте дальше и не обращайте пока на это внимание...

В том то и дело, что работать дальше могу, но и с этим хотелось бы решить вопрос.

Похоже, что остается подключать unimacro и тащить оттуда большой примитив.

Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Oct 7 2015, 09:11
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



сделайте регистр и в него явно по клоку защелкните данные из массива. Такое описание рождает РОМ, никаких доп регистров не появиться... С ксалинксом в свое время мне удалось договориться без проблем...

но через RAMB36E1 делать правильнее, самостоятельно посчитав сколько их надо и описав мультиплексоры. Сами блоки так же параметризуются и имеют возможность инициализации
Go to the top of the page
 
+Quote Post
TRILLER
сообщение Oct 7 2015, 09:28
Сообщение #9


Частый гость
**

Группа: Свой
Сообщений: 180
Регистрация: 17-02-09
Из: Санкт-Петербург
Пользователь №: 45 001



В Симплифае один раз так накололся, написав атрибут syn_ramstyle вместо syn_romstyle.
Посомтрите в XST, возможно в этом проблема - мне лень.
Go to the top of the page
 
+Quote Post
sallador
сообщение Oct 7 2015, 10:30
Сообщение #10


Участник
*

Группа: Участник
Сообщений: 50
Регистрация: 10-05-11
Пользователь №: 64 903



Цитата(TRILLER @ Oct 7 2015, 13:28) *
В Симплифае один раз так накололся, написав атрибут syn_ramstyle вместо syn_romstyle.
Посомтрите в XST, возможно в этом проблема - мне лень.


Нет, это не влияет.

Цитата(Golikov A. @ Oct 7 2015, 13:11) *
сделайте регистр и в него явно по клоку защелкните данные из массива. Такое описание рождает РОМ, никаких доп регистров не появиться... С ксалинксом в свое время мне удалось договориться без проблем...

Ура. Удалось сделать не на рассыпухе, а на 2 блоках RAMB36. Причем, без атрибутов ram_style.
Но все равно он не хочет в 1 блок упихивать.

Код такой:
Код
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity rams_21b is
    generic (
        Data_w    : integer:=64;
        Data_d    : integer:=512
        );
    
    port (
        CLK     : in  std_logic;
        EN         : in  std_logic;
        ADDR     : in  std_logic_vector(8 downto 0);
        DATA     : out std_logic_vector(Data_w-1 downto 0)
    );
end rams_21b;

architecture syn of rams_21b is
    type rom_type is array (Data_d-1 downto 0) of std_logic_vector (Data_w-1 downto 0);                
    signal ROM : rom_type:= ( ТУТ 512 ОТСЧЕТОВ  );                        

signal rdata : std_logic_vector(Data_w-1 downto 0);    

begin

rdata <= ROM(conv_integer(ADDR));

process (CLK)
begin
    if (CLK'event and CLK = '1') then
        if (EN = '1') then
            DATA <= rdata;
        end if;
    end if;
end process;

end syn;
Go to the top of the page
 
+Quote Post
andrew_b
сообщение Oct 7 2015, 10:33
Сообщение #11


Профессионал
*****

Группа: Свой
Сообщений: 1 975
Регистрация: 30-12-04
Из: Воронеж
Пользователь №: 1 757



Цитата(sallador @ Oct 7 2015, 12:10) *
Код
     d_out <= const_init(conv_integer(addr)) when rising_edge(clk);

Почему XST тупит?
Вы бы не выделывались, а написали бы нормальный процесс. Глядишь, и xst тупить бы перестал. Это первое.
А второе, xst не умел использовать двухпортовую память для двух идентичных блоков ROM. Видать, так и не научили ещё.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Oct 7 2015, 10:37
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Цитата
Ура. Удалось сделать не на рассыпухе, а на 2 блоках RAMB36. Причем, без атрибутов ram_style.
Но все равно он не хочет в 1 блок упихивать.


может не мочь на 1 блоке. там есть ограничения, надо доки читать...
Go to the top of the page
 
+Quote Post
sallador
сообщение Oct 7 2015, 10:57
Сообщение #13


Участник
*

Группа: Участник
Сообщений: 50
Регистрация: 10-05-11
Пользователь №: 64 903



Цитата(andrew_b @ Oct 7 2015, 14:33) *
Вы бы не выделывались, а написали бы нормальный процесс. Глядишь, и xst тупить бы перестал. Это первое.
А второе, xst не умел использовать двухпортовую память для двух идентичных блоков ROM. Видать, так и не научили ещё.

Для уменьшения кода я написал без процесса. С процессом тоже пробовал, суть та же. Результаты одинаковые.

Ладно, попробую через примитив из unimacro, где можно определенным образом задать INIT векторы.

Цитата(Golikov A. @ Oct 7 2015, 14:37) *
может не мочь на 1 блоке. там есть ограничения, надо доки читать...

Хм. Ничего не понимаю. ROM не хочет делать, а RAM влегкую. Такие дела, переписал код: удалил инициализацию, добавил порт для записи в память. Итого, RAM 512x64 он сделал без проблем на 1 RAMB36. Пруф из FPGA_Editor:
Прикрепленное изображение

Чудеса.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Oct 7 2015, 17:46
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Кстати вы надеюсь смотрите technologic view а не rtl view? В ртл он отсебятину несет, эта схема не соответствует действительности.... надо технологик смотреть
Go to the top of the page
 
+Quote Post
sallador
сообщение Oct 8 2015, 08:19
Сообщение #15


Участник
*

Группа: Участник
Сообщений: 50
Регистрация: 10-05-11
Пользователь №: 64 903



Цитата(Golikov A. @ Oct 7 2015, 21:46) *
Кстати вы надеюсь смотрите technologic view а не rtl view? В ртл он отсебятину несет, эта схема не соответствует действительности.... надо технологик смотреть

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

Вчера очень долго читал даташиты. Похоже, что нельзя инициализировать RAMB36E как ROM 72x512 таким способом.
Остается вариант - либо делать через CoreGEN, либо unimacro подключать.
Первое не устраивает, второе еще терпимо.
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 4th July 2025 - 20:47
Рейтинг@Mail.ru


Страница сгенерированна за 0.01569 секунд с 7
ELECTRONIX ©2004-2016