|
Счетчик не справляется, или генератор адреса... |
|
|
|
Apr 15 2008, 06:50
|

Гуру
     
Группа: Свой
Сообщений: 2 113
Регистрация: 1-11-05
Пользователь №: 10 359

|
quartus7.2, циклон 2, скорость 7... Мне необходимо состряпать счетчик адреса, для чтения данных из памяти. Частота - 133МГц. Предварительно на симуляторе проверяю, для чего пишем такой код: Код input ddr_sdram_phy_clk_out;
output [23:0] address_0_r; output [22:0] address_0_r_x;
input read_n; input waitrequest; input HC_VD;
assign address_0_r[23:1] = address_0_r_x;
count_adr c1 ( .clock(ddr_sdram_phy_clk_out), .cnt_en((~read_n)&(~waitrequest)), .data(24'd0), .sload(~HC_VD), .q(address_0_r_x) ); address_0_r просто для того чтобы считать по +2. count_adr - это обычный lpm_count из мегавизарда. Так вот, когда частота ddr_sdram_phy_clk_out до 100 МГц - все кое-как работает. Это на первом рисунке видать. А вот если ставим частоту 133МГц - уже, судя по всему не справляется - рисунок 2. Что делать, как по-другому, "правильно", сделать генератор адреса? Да и почему счетчику такая частота не дается?
Эскизы прикрепленных изображений
--------------------
Быть. torizin-liteha@yandex.ru
|
|
|
|
|
Apr 15 2008, 07:21
|
Знающий
   
Группа: Свой
Сообщений: 709
Регистрация: 3-05-05
Пользователь №: 4 693

|
Может чего не понял, но постарайтесь быть проще Код module d22(inclock,ena,outdat);
input inclock,ena; output reg [21:0] outdat;
always @(posedge inclock or posedge ena) if (ena==1) outdat<=outdat; else outdat<=outdat+1`b1;
endmodule для Ц2 -8 работает на 7нС цлоцке в симуляторе. Квартус для него пишет "Info: Clock "inclock" has Internal fmax of 219.88 MHz between source register "outdat[0]~reg0" and destination register "outdat[21]~reg0" (period= 4.548 ns)" Ежли проблему не так понял, извиняйте. ;О)
|
|
|
|
|
Apr 15 2008, 09:15
|

Гуру
     
Группа: Свой
Сообщений: 2 113
Регистрация: 1-11-05
Пользователь №: 10 359

|
Да, этот LPM я попробовал потому что уже ничего не получалось. Вот сделал все так как сказано в предыдущих двух постах и... Та же ситуевина, картинки не поменялись. Я сперва так и делал с той разницей, что не оформлял в виде отдельного модуля, теперь оформил. Может я какие-то назначения не делаю, или что еще? У меня даже строки навроде Цитата "Info: Clock "inclock" has Internal fmax of 219.88 MHz between source register "outdat[0]~reg0" and destination register "outdat[21]~reg0" (period= 4.548 ns)" не имеется Извиняйте, был невнимателен - строка такая имеется...
--------------------
Быть. torizin-liteha@yandex.ru
|
|
|
|
|
Apr 15 2008, 10:09
|
Знающий
   
Группа: Свой
Сообщений: 709
Регистрация: 3-05-05
Пользователь №: 4 693

|
Не понял хохмы, но вроде всё пучком... Квартус(71) заявил, что до 245МГц могло бы работать.
Эскизы прикрепленных изображений
|
|
|
|
|
Apr 15 2008, 10:57
|
Знающий
   
Группа: Свой
Сообщений: 709
Регистрация: 3-05-05
Пользователь №: 4 693

|
Цитата(torik @ Apr 15 2008, 14:42)  Ну во-первых смотрим - почему первый фронт пропускает? ... Дык, РТЛвьювер кажет, что на ЕНА триггеров, с выхода сумматора идёт через логику. А это время. Вот первый цлоцк и таво... Сдвиньте назад сигналы readn и waitrequest на одну-пару нан и счоччик чудесно сработает от "первого" фронта. Ну и время на распространение. ;О) Тут, есчо, надо понимать, что Квартус показывает состояние именно пинов. Физических. Т.е. ещё сколько-то нан плюсом ко всем времянкам.
|
|
|
|
|
Apr 15 2008, 11:32
|

Гуру
     
Группа: Свой
Сообщений: 2 113
Регистрация: 1-11-05
Пользователь №: 10 359

|
Хм... сейчас осмыслю все, попробую в железе - скажу что-нибудь))) Вообще в железе просто инкремент счетчика адреса на 2 работает нормально. А задача стоит несколько более сложная - надо адрес формировать следующего образца: 0,2...8, 30,32...38, 10,12...18... Вот, это навроде деинтерлейсера. И тут у меня и возникли проблемы, вопросы и прочее. Да, в железе output/input заменяются на wire Вот, отдельно разглядим wire и output в симуляторе: Код output [23:0] address_0_r; wire [23:0] address_0_rx;
assign address_0_r = address_0_rx; sdfgsdfg dddd1 ( .iclk(ddr_sdram_phy_clk_out), .irst_n(HC_VD), .ena((~read_n)&(~waitrequest)), .iadr_add(/*adr_add*/2'd2), .oadr(address_0_rx) ); На картинке получаем задержку для wire намного меньше, все начинает проясняться но... какого там появляются некие X? Как это понимать?
Эскизы прикрепленных изображений
--------------------
Быть. torizin-liteha@yandex.ru
|
|
|
|
|
Apr 15 2008, 11:36
|
Гуру
     
Группа: Свой
Сообщений: 2 435
Регистрация: 6-10-04
Из: Петербург
Пользователь №: 804

|
Цитата(torik @ Apr 15 2008, 13:45)  Блин, выкладываю сам этот простейший проект. Если не лениво гляньте на диаграмки... А с чего Вы взяли, что он простейший. На простейшем столько предупреждений не получишь. Ваш счетчик Квартусу не нравиться. Опмсание на lach смахивает. На таких частотах Вы не можете себе позволить асинхронной загрузки. Она тоже в такт должна уложиться. И счетчик для инкремента 2 можно на разряд меньше сделать. Это уже 275 мгц. А моделирование не корректное. grid size надо коррекетно выставлять в пол периода клока и галочку setup выставлять для правильного анализа временного моделирования. input iclk; input irst_n; input ena; output [23:0] oadr_out; reg [22:0] oadr; assign oadr_out = {oadr, 1'b0}; always @(posedge iclk) begin if (!irst_n) oadr <= 23'd0; else begin if (ena) oadr <= oadr + 1'd1; end end
|
|
|
|
|
Apr 15 2008, 12:11
|
Гуру
     
Группа: Свой
Сообщений: 2 435
Регистрация: 6-10-04
Из: Петербург
Пользователь №: 804

|
Цитата(torik @ Apr 15 2008, 15:44)  Грид поправил, но это же не принципиально. О какой галке "setup" идет речь не понял...
По-моему без разницы делать +1 и на 1 разряд меньше или +2 и на один разряд больше - результат будет один.
Вы мне главное поясните - откуда ХХХ беруться в симуляторе при наблюдении wire?))) Если Вам без разницы, на какой частоте счетчик работает, моделируйте функционально. И XXX тоже не будет. Нет смысла рассматривать диаграмму с некорректным grid size. В среде временного моделирования есть опция setup and hold time ........ для анализа времени установления и удержания данных относительно клока. Если времена не корректны, будут xxxxxx. В вашем частном случает, если входные управляющие сигналы через регистры пропустить, xxxx пропадут. Или корректно входные воздействия рисуйте. Если в основном проекте при временном моделировании получаете xxxx, а при функциональном все хорошо, значит с проектом облом. (При наличии галочки и реально выставленном периоде клока)
|
|
|
|
|
Apr 17 2008, 09:19
|

Гуру
     
Группа: Свой
Сообщений: 2 113
Регистрация: 1-11-05
Пользователь №: 10 359

|
Цитата Если Вам без разницы, на какой частоте счетчик работает, моделируйте функционально. И XXX тоже не будет. Нет смысла рассматривать диаграмму с некорректным grid size. В среде временного моделирования есть опция setup and hold time ........ для анализа времени установления и удержания данных относительно клока. Если времена не корректны, будут xxxxxx. В вашем частном случает, если входные управляющие сигналы через регистры пропустить, xxxx пропадут. Или корректно входные воздействия рисуйте. Если в основном проекте при временном моделировании получаете xxxx, а при функциональном все хорошо, значит с проектом облом. (При наличии галочки и реально выставленном периоде клока) Итак, на счет некорректного grid size - результат симуляции от него не зависит, но согласен - должен быть порядок, откорректировал... Промоделировал функционально - все нормально. Теперь временной анализ. Тоже все впорядке! На самом деле "ХХХ" появились не из-за проблем с частотами, а из-за того что при синтезе и оптимизаци компилятор упростил схему и часть выходов регистра была заменена на "провода". "ХХХ" я убрал, т.к. стал прибавлять на 1, а не на 2... Но все равно получаю облом. Задача в целом такая: - все сделано на основе отладки "Nios II Embedded Evaluation Kit, Cyclone III Edition" - с камеры картинка пишется в DDR память. Общее разрешение 576*800, по 16 бит на цвет (565). Т.к. развертка черезстрочная, в памяти получаем поле1 по адресам 0...(288*800*2-2), поле2 по адресам 288*800*2...(576*800*2-2). Запись происходит нормально, это точно. - контроллер DDR памяти в SOPS Builder, для чтения/записи использую простейший мастер (выводы шины авалон на верхний уровень, уже обсуждал здесь на форуме, применяется успешно) - для вывода на экран просто генерируем адрес чтения 0...(576*800*2-2). При этом на экране наблюдаем поле1 и поле2 раздельно, как бы два сжатых по вертикали кадра. Все стабильно работает, никаких сбоев... - остается сделать деинтерлейсер. Для этого по идее надо читать в следующем порядке: Код (0*800*2)...(1*800*2-2), (288*800*2)...(289*800*2-2), (1*800*2)...(2*800*2-2)... Вот тут-то и начинаются проблемы - второе поле вообще куда-то теряется, если два раза повторять каждую строчку одного поля - видим словно пропадание строк. Такое впечатление, что адрес некорректно задается, но на симуляторе (естественно при меньших цифрах) смотрел - все в норме вроде. Кроме того если вывод на монитор выполнять с помощью SGDMA и других приблкд в сопсбилдере, тоже все идет нормально (но этот вариант не подходит). Поглядите, может я где-то принципиально, в алгоритме или коде делаю ошибку? Код wire [23:0] address_0_r; wire [22:0] address_0_rx; assign address_0_r[23:0] = {address_0_rx,1'b0}; sdfgsdfg dddd1 ( .iclk(ddr_sdram_phy_clk_out), .irst_n(HC_VD), .ena((~read_n)&(~waitrequest)), .iadr_add(adr_add), .oadr(address_0_rx) ); wire [22:0] adr_add; adr_add dddd2 ( .iclk(ddr_sdram_phy_clk_out), .irst_n(HC_VD), .ena((~read_n)&(~waitrequest)), .oadr_add(adr_add) );
module sdfgsdfg ( iclk, irst_n, ena, iadr_add, oadr );
input iclk; input irst_n; input ena; input [22:0] iadr_add; output [22:0] oadr; reg [22:0] oadrx;
assign oadr = oadrx; always @(posedge iclk or negedge irst_n) begin if (!irst_n) begin oadrx <= 23'd0; end else begin if (ena == 1'b0) oadrx <= oadrx; else oadrx <= oadrx + iadr_add; end end
endmodule
module adr_add ( iclk, irst_n, ena, oadr_add ); input iclk; input irst_n; input ena; output reg [22:0] oadr_add;
reg [22:0] sta_dop; always @(posedge iclk or negedge irst_n) begin if (!irst_n) begin sta_dop <= 23'd0; end else begin if (sta_dop < /*23'd9*/23'd1599) begin if (ena == 1'b1) //4*pix-2 (4*800-2 = 3198) sta_dop <= sta_dop + 23'd1; else sta_dop <= sta_dop; end else sta_dop <= 0; end
end always @(posedge iclk or negedge irst_n) begin if (!irst_n) oadr_add <= 23'd1; else begin oadr_add <= (sta_dop == 23'd798) ? 23'd229601 : ((sta_dop == 23'd1598) ? 23'h7c7c01 : 23'd1); end end
endmodule А то что-то застопорился на этом. Можно конечно сделать отдельные мастеры на чтение первого и второго поля и переключать строки уже после фифо, но это как-то коряво получается...
--------------------
Быть. torizin-liteha@yandex.ru
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|