Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Оптимизация регистров в Quartus
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Системы на ПЛИС - System on a Programmable Chip (SoPC)
margosh
Всем добрый день! smile.gif Подскажите плиз, какими способами можно решить проблему. Написала на VHDL собственный компонент Авалон слейв, в который встроила мегафункцию FIFO; некоторые сигналы FIFO типа wrreq выствляю внутрипрограммно, наружу их не вывожу. При симуляции выяснилось, что мегафункция работает неадекватно по той причине, что Квартус все эти внутренние сигналы выкинул. Пыталась найти какие-нить настройки, чтобы сохранить данные сигналы, но пока безуспешно. Выводить их наружу и подвешивать в воздухе пока не хочется, может кто знает, есть ли способ сохранить внутренние сигналы иначе или выборочно настроить оптимизацию?
DmitryR
Если он сигналы выкинул - значит, они не нужны smile.gif То есть схема построена неправильно, и сигналы упростились. Читайте warnings синтеза - от того, что вы как-то заставите синтезатор сохранить эти сигналы схема работать правильно не начет.
Kuzmi4
2 margosh - в верилоге - атрибут syn_keep, в VHDL тоже должен быть.
margosh
DmitryR - В том то и дело - в варнингах этих сигналов нет... Пробовала создавать проект содержащий исключительно эту мегафункцию без моих сигналов, результат тот же - работает корректно только если ее сигналы указаны среди портов ввода-вывода.

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

Кроме того обнаружила следующее: в данной мегафункции есть параметр add_ram_output_register, который оптимизирует скорость фифо. При значении этого параметра "OFF" счетчик слов фифо продолжает увеличиваться, в то время как запись закончилась, а считывание давно началось... Если же занчение этого параметра "ON" - все работает нормально(при условии что все сигналы вевыдены наружу)

add_ram_output_register = "ON"
Нажмите для просмотра прикрепленного файла

add_ram_output_register = "OFF"
Нажмите для просмотра прикрепленного файла

Ребят, если есть догадки, почему так происходит, поделитесь пожалуста.
Kuzmi4
Цитата
Покопалась в книжке по VHDL, подобных атрибутов нет

blink.gif
СцылкО!!!
Страница 20
Цитата
The keep attribute is used for a wire or net node. For example:
In Verilog:
wire my_wire /* synthesis keep = 1 */:
In VHDL:
signal my_signal: bit;
attribute syn_keep : boolean;
attribute syn_keep of my_signal: signal is true;
The preserve attribute is used for a register. For example:
In Verilog:
reg my_reg /* synthesis preserve = 1 */:
In VHDL:
signal my_reg: stdlogic;
attribute preserve : boolean;
attribute preserve of my_signal: signal is true;

laughing.gif
Касательно варнингов - бывает полезно и Info читать - он там тоже много чего интересного пишет wink.gif
Но почему то мне кажется что трабл у вас в HDL (квартус просто так ничего не выкидывает).
Egor_N
Цитата(margosh @ Oct 26 2009, 13:45) *
Всем добрый день! smile.gif Подскажите плиз, какими способами можно решить проблему. Написала на VHDL собственный компонент Авалон слейв, в который встроила мегафункцию FIFO; некоторые сигналы FIFO типа wrreq выствляю внутрипрограммно, наружу их не вывожу. При симуляции выяснилось, что мегафункция работает неадекватно по той причине, что Квартус все эти внутренние сигналы выкинул. Пыталась найти какие-нить настройки, чтобы сохранить данные сигналы, но пока безуспешно. Выводить их наружу и подвешивать в воздухе пока не хочется, может кто знает, есть ли способ сохранить внутренние сигналы иначе или выборочно настроить оптимизацию?


Попробуйте доступные варианты настроек в Assignment -> Settings -> Category: Fitter Setting -> Physical Syntesis Optimazations -> Physical Syntesis for Registers ... А вообще-то, если квартус что-то считает лишним, значит надо как-то по-другому переписывать код.
des333
Выложите репорт Квартуса, а еще лучше код проекта или хотя бы мегафункции.
margosh
Kuzmi4, спасибо за ссылку, вообщето искала этот атрибут в книжке по VHDL, без Вас точно не нашла бы laughing.gif
Теперь касательно варнингов. Ребят, очень извиняюсь, проблема видимо действительно не в сигналах. Сбило с толку меня следующее: в варнингах полной компиляции и в инфо тоже никаких записей касательно неработающих у меня сигналов нет(хотя другого предостаточно и до временного анализа еще не добралась),
Нажмите для просмотра прикрепленного файла
а в варнингах симуляции они есть:
Нажмите для просмотра прикрепленного файла,
потому я и решила, что квартус сигналы эти оптимизировал и мегафункция не работает 05.gif , а теперь создается ощущение, что внутренние счетчики слов мегафункции криво работают когда параметр add_ram_output_register отключен (диаграмма в предыдущем сообщении). Может кто-то знает, почему так?
Разумеется не исключаю, что где-то сама накосячила, так как знакома с Квартусом недолго. Присоединяю код проекта
CODE
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
use IEEE.std_logic_arith.all;
LIBRARY altera_mf;
USE altera_mf.altera_mf_components.all;

entity fifo_tr is
port (
--inputs
signal clk : in std_logic;
signal clk_tr : in std_logic;
signal address : in std_logic;
signal chipselect : in std_logic;
signal write_n,read_n : in std_logic;
signal writedata : in std_logic_vector(8 downto 1);

--outputs

--signal tr_read : out std_logic_vector(7 downto 0); --data for transmiter
signal ff_out: out std_logic_vector(7 downto 0);
signal irq : out std_logic;
signal readdata : out std_logic_vector(8 downto 1);
-- buffer
signal rdusedw_d : buffer std_logic_vector(11 downto 0);
signal wrusedw_d : buffer std_logic_vector(11 downto 0)

);
end fifo_tr;

architecture cosmos of fifo_tr is

signal data_d : std_logic_vector(7 downto 0);
signal wrfull_d : std_logic;
signal rdfull_d : std_logic;
signal wrempty_d : std_logic;
signal rdempty_d : std_logic;
signal rdreq_d : std_logic;
signal wrreq_d : std_logic;
signal flag_rd_end : std_logic;
signal schetchik : std_logic_vector(11 downto 0) := "000000000000";
signal schetchik_2 : std_logic_vector(11 downto 0) := "000000000000";
signal dlina_kadra : std_logic_vector(11 downto 0) := "000000000000";
signal stat_reg : std_logic_vector(7 downto 0);
-- статусный регистр: (0:2)бит - поле дынных содержит режим, устанавливающий размер видеостроки(размер пакета)
-- 3 - фифо пустой
-- 4 - фифо полный
-- 5 - ошибка: превышение заданных размеров контейнера
-- 6 - контейнер заполнен
-- 7 - контейнер отправлен
component dcfifo
generic (
add_ram_output_register : string := "OFF";
add_usedw_msb_bit : string := "OFF";
clocks_are_synchronized : string := "FALSE";
delay_rdusedw : natural := 1;
delay_wrusedw : natural := 1;
intended_device_family : string := "unused";
lpm_numwords : natural;
lpm_showahead : string := "OFF";
lpm_width : natural;
lpm_widthu : natural := 1;
overflow_checking : string := "ON";
rdsync_delaypipe : natural := 3;
underflow_checking : string := "ON";
use_eab : string := "ON";
write_aclr_synch : string := "ON";
wrsync_delaypipe : natural := 3;
lpm_hint : string := "USE_EAB=ON";
lpm_type : string := "dcfifo"
);
port(
aclr : in std_logic := '0';
data : in std_logic_vector(lpm_width-1 downto 0);
q : out std_logic_vector(lpm_width-1 downto 0);
rdclk : in std_logic;
rdempty : out std_logic;
rdfull : out std_logic;
rdreq : in std_logic;
rdusedw : out std_logic_vector(lpm_widthu - 1 downto 0);
wrclk : in std_logic;
wrempty : out std_logic;
wrfull : out std_logic;
wrreq : in std_logic;
wrusedw : out std_logic_vector(lpm_widthu - 1 downto 0)
);
end component;


begin

ff_tr1: dcfifo
generic map(lpm_numwords => 4096,
lpm_showahead => "ON",
add_ram_output_register => "ON",
delay_rdusedw => 0,
delay_wrusedw => 0,
rdsync_delaypipe => 3,
wrsync_delaypipe => 3,
lpm_width => 8,
lpm_widthu => 12)

port map( aclr => open,
data => data_d,
q => ff_out,
rdclk => clk_tr,
rdempty => rdempty_d,
rdfull => rdfull_d,
rdreq => rdreq_d,
rdusedw => rdusedw_d,
wrclk => clk,
wrempty => wrempty_d,
wrfull => wrfull_d,
wrreq => wrreq_d,
wrusedw => wrusedw_d);

-- процесс записи данных в фифо
process(clk, chipselect, address, write_n)
begin
if clk = '1' and clk'event then
if chipselect = '1' and write_n = '0' then
if address = '0'then
if (schetchik(11 downto 0) <= dlina_kadra(11 downto 0)) then
data_d(7 downto 0) <= writedata(8 downto 1); -- запись данных
wrreq_d <= '1';
schetchik <= schetchik + '1';
--aclr_d <= '1';
else --если количество байт превысило допустимые рзмеры кадра
wrreq_d <= '0';
stat_reg(5) <= '1'; -- выставляем статус ошибка
end if;
elsif address = '1' then
stat_reg(7 downto 0) <= writedata(8 downto 1); -- записываем в статусный регистр признак
case writedata(3 downto 1) is
when "001" => dlina_kadra(11 downto 0) <= "001100100000";
when "010" => dlina_kadra(11 downto 0) <= "010000000000";
when "011" => dlina_kadra(11 downto 0) <= "010000011010";
when "100" => dlina_kadra(11 downto 0) <= "010100000000";
when "101" => dlina_kadra(11 downto 0) <= "010101111000";
when "110" => dlina_kadra(11 downto 0) <= "011010010000";
when "111" => dlina_kadra(11 downto 0) <= "100000000000";
when others => dlina_kadra(11 downto 0) <= "000000001010";
end case;
wrreq_d <= '0';
end if;
elsif chipselect = '1' and read_n = '0' then
if address = '0' then
readdata(8 downto 1) <= data_d(7 downto 0);
wrreq_d <= '0';
elsif address = '1' then
readdata(8 downto 1) <= stat_reg(7 downto 0);
wrreq_d <= '0';
end if;
else
wrreq_d <= '0';
end if;
if chipselect = '0' and (schetchik(11 downto 0) <= dlina_kadra(11 downto 0)) and (schetchik(11 downto 0) > "000000000000") then
stat_reg(6) <= '1';
--aclr_d <= '0';
elsif chipselect = '0'and (schetchik(11 downto 0) = "000000000000") then
irq <= '1';
elsif chipselect = '1' then
irq <= '0';
end if;
if (flag_rd_end = '1') then
schetchik(11 downto 0) <= "000000000000";
stat_reg(6) <= '0';
stat_reg(7) <= '1';
wrreq_d <= '0';
end if;
stat_reg(3) <= rdempty_d;
stat_reg(4) <= wrfull_d;
end if;


end process;

process(clk_tr, chipselect, stat_reg)
begin
if clk_tr = '0' and clk_tr'event then
if chipselect = '0' and stat_reg(6) = '1' then
if (schetchik_2(11 downto 0) <= schetchik(11 downto 0)) then
rdreq_d <= '1';
schetchik_2 <= schetchik_2 + '1';
flag_rd_end <= '0';
else
flag_rd_end <= '1';
schetchik_2 <= "000000000000";
rdreq_d <= '0';
end if;
else
rdreq_d <= '0';
end if;
end if;
end process;

end architecture cosmos;
Kuzmi4
Сдаётся мне что дело тут не в add_ram_output_register, да и если б
Цитата
внутренние счетчики слов мегафункции криво работают когда параметр add_ram_output_register отключен
- обязательно на альтереб об этом написали, правда ??

Просмотрел одним глазом ваше творение - стало страшно 07.gif а словами можно описать что вы там хотели реализовать ? (квартуса под рукой счас нет, но мне почему то кажется что он там много чего интересного насинтезирует laughing.gif , да и вопрос тут не в квартусе даже)
margosh
Kuzmi4, что такого страшного Вы там усмотрели? smile.gif Реализовать хотела следующее: авалон слейв FIFO c внутренним статусным регистром, в котором малдшие 3 бита содержат режим работы, соответствующий пакетам различной длины(предполагается, что данные биты статусного регистра выставляет ниосовская прошивка), остальные биты - статусные. При обращении по адресу 1 FIFO происходит считывание либо запись статусного регистра, при обращении по адресу 0 - запись данных. Выходные данные с фифо подаются на выходной пин ff_out (в последующем на вход передатчика).
Kuzmi4
так тоже в своё время писал и мучали те же вопросы laughing.gif
margosh
Вы какую-то конкретно ошибку нашли? Или просто коряво? Я пока учусь, мне любая информация на пользу - не томите wink.gif
Kuzmi4
Просто запутанно у вас как то всё описывается - видимо квартус и распутывает как может, если опишите словами что именно нужно может и помогём чем смогём.
margosh
Kuzmi4, ответила на Ваш вопрос в сообщении 10, нужно подробнее?
Kuzmi4
НУ пока есть время и "натхнення" smile.gif - имеем :авалон слейв интерфейс, он содержит 2 адреса 0 - статус/контрол (статус с фифо лап? контрол что именно задаёт - длинну и всё?), адрес 1 - сосбно фифо. Пишем в фифо стандартными авалоновскими трансферами (бурстить будем/нет ?), по достижению нужного количества слов в фифо - что происходит ?(выдача автоматом всего содержимомого фифо через ff_out? стробы какие нибудь вообсче предусматриваются чтоб сообсчать кому нибудь с наружи что данные валидные?) .
Вроде всё ??
margosh
В моем случае по адресу 1 - FIFO, по адресу 0 - статусный регистр(взяла аналогично описанию корки DCFIFO), только статусный регистр я создаю сама(не с лап), и при обращении по адресу 1 запроса считывания выдаю его на readdata. Биты статусного регистра:
(0:2)бит - поле дынных содержит режим, устанавливающий размер пакета
3 - фифо пустой
4 - фифо полный
5 - ошибка: превышение заданных размеров контейнера
6 - контейнер заполнен
7 - контейнер отправлен
Передача не пакетная пока что, планирую и это реализовать, но хочу сначала с азами разобраться.
По достижению нужного количества слов (данный момент как раз устанавливается 3 битами статусного регистра, обьем всего FIFO выставлен для возможности хранения максимально длинного пакета): проц прекращает обращение к FIFO(Chipselect = 0) и FIFO начинает передавать накопленный пакет. Передача без подтверждения, стробирующих сигналов пока нет, просто слив пакета через ff_out. Как только FIFO опустел, он выставляет прерывание процу, тот снова толкает пакет и снимает обращение.
Kuzmi4
в Опсчем ясно, есть уже, и даже с каментами wink.gif , там осталось строб корректно передать в другой произвольный клоковый домен, как будет свободное время сегодня допишу и выложу...
margosh
Если честно, расчитывала только на то, что носом ткнете в ошибки... Большое спасибо! Очень хочется узнать, что конкретно делаю не так...
Kuzmi4
Вот как то так
Нажмите для просмотра прикрепленного файла
Там есчё нужно ессно дорабатывать, на идеал не претендую, но идею я думаю что донёс laughing.gif каменты есть wink.gif
Если чего не ясно спрашивайте. В обсчем там ключевые моменты:
- работа автоматов в 2 клоковых доменах: один загружает данные с авалона, второй по стробу выгружает фифошным интерфейсом с флагом валидности.
- передача одноклокового строба так, чтоб он был одноклоковый для принимающего.
И я там писал с рассчёта на 32-х битные дата-трансферы по шине (но использовал только нижные 8 байт), этот момент тоже проработайте для удобства в дальнейшем использования.
Если что, думаю товарисчи исправят или дополнят если что-то заФтыкал.

А на счёт
Цитата
Очень хочется узнать, что конкретно делаю не так

сравните ваш вариант и мой - сразу станет всё понятно biggrin.gif
margosh
угу, с учетом того, что я пока писала проекты только на VHDL - "сразу станет все понятно" biggrin.gif ... сижу, разбираюсь, чуствую вопросов будет много)
Kuzmi4
2 margosh - мог написать на вхдл , но с учётом моего рабочего графика заняло бы дней 5 laughing.gif
margosh
Принцип контроля за заполнением кадра для меня пока не ясен... Kuzmi4, прерывания Вы не используете, в таком случае Вы создаете какой-то аналог сигнала waitrequest? если не сложно, обьясните плиз, что происходит, когда заполнился первый кадр? С этого момента я суть программы перестаю улавливать...
Kuzmi4
Слона то я и не заметил... rolleyes.gif
Вот с прерыванием длинной 1 клок на мастер
Нажмите для просмотра прикрепленного файла

Далее
Цитата
прерывания Вы не используете, в таком случае Вы создаете какой-то аналог сигнала waitrequest?
расшифруйте, что вы имели ввиду? Потому как мне кажется, что у вас неправильное понимание назначения waitrequest.

Потом
Цитата
.wrusedw (av_wr_counter), // wr counter
...
.rdusedw (fifo_rd_counter) // rd counter

Это счётчики заполнения/опустошения, тактируемые своими клоками (могу и ошибаться, что это именно wr/rdusedw, потому как давно с альтерой плотно не работал, но камент специально поставил laughing.gif ). Смотрите где они используются.

Идём дальше
Цитата
Принцип контроля за заполнением кадра для меня пока не ясен

А принцип контроля со сторы хоста простой - так как бурста нет, тогда пишем по одному байту и читаем флаг container_full (хотя это и не обязательно и я думаю избыточно в принципе - можно же вычитать stat/cfg регистр с длинной фифошки и в проге на сях для ниоса это учесть (если не он конфигурил), ну или в своём самописном мастере (опять же если не он конфигурил) - ну и дальше гнать данные по одному трансферу согласно вычитанного кода длинны). Если несколько разных мастеров работают, тогда каждый на начале трансфера должен записывать свой параметр длинны и по окончании записи нужного количества байт ждать прерывания и отдавать слейв другому мастеру, ну а тот повторяет процедуру...

Ну и наконец
Цитата
что происходит, когда заполнился первый кадр
- авалоновская машинка передаёт строб начала работы машинке отгрузки наружу, по опустошению фифо машинка отгрузки наружу переходит в состояние ожидания нового сигнала начала работы. Ну и выставляется интерупт хосту - что фифо готово к новой работе.

Вроде всё.
margosh
Цитата
расшифруйте, что вы имели ввиду? Потому как мне кажется, что у вас неправильное понимание назначения waitrequest.

waitrequest - сигнал, котрый выставляет устройство, если не успевает вовремя выдать данные процессору или считать от процессора. Я не разобралась в другом wacko.gif , - в стробовых сигналах. Не могу понять что делает модуль interck2, Вы не могли бы прояснить? Если только сообщает о завершении считывания из fifo, то у меня это было предусмотрено выставлением соответствующего бита в статусный регистр.
Kuzmi4
И снова добрый день!
Итак, имеем
Цитата
waitrequest - сигнал, котрый выставляет устройство, если не успевает вовремя выдать данные процессору или считать от процессора
так а при чём тут
Цитата(margosh @ Oct 28 2009, 14:32) *
прерывания Вы не используете, в таком случае Вы создаете какой-то аналог сигнала waitrequest
??

Далее,
Цитата
что делает модуль interck2

Как говорил, у нас 2 машинки - одна записывает данные в фифо с авалона на клоке шины, другая считывает данные наружу (в external) по наружному клоку. Клоки могут быть произвольные, потому нужен модуль корректно передающий строб с одного произвольного домена в другой (это и есть interck2). Собсно строб нужен для того чтоб запускать выгрузку сразу по заполнению нужным количеством данных - на сколько я помню
Цитата
По достижению нужного количества слов ... проц прекращает обращение к FIFO(Chipselect = 0) и FIFO начинает передавать накопленный пакет.

Собсно отсюда и с неопределённости использования компонента вытекает избыточность в реализации.
margosh
Здравствуйте smile.gif Овтечу подробнее во избежание повторений. Дело в том, что я сходу не въехала как работает interck2, и, так как у Вас не был использован сигнал прерывания, решила что он выполняет что-то вроде задержки нового сигнала записи от Авалона на тот период, пока кадр из фифо не считался. После более детального изучания поняла функциональное назначение interck2, правда масштабно представить себе этот переход от одного клока к другому не могу - еще с этим не работала, жапуталась laughing.gif
Дико извиняюсь, я не сообщила один важный момент - клоки не произвольные, - с авалона 50 МГц на запись, на чтение - 25 МГц с генератора, причем оба синхронизованны по фазе.

Для того, чтобы запускать выгрузку фифо сразу по достижению нужного количества данных в моей программке использовался бит 6 статусного регистра, теперь правда думаю, что условия его выставления необходимо подкорректировать, так же, как и условие выставления прерывания. Kuzmi4, огромное спасибо за помощь, и мои извинения, если запутала Вас в условиях задачи. Сажусь исправлять smile.gif
Kuzmi4
2 margosh - успехов laughing.gifв раЖпутывании
На счёт клоков - interck2 для произвольных доменов, так что тут можно поставить галочку

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