Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Обращение к SRAM, нет данных на выходе.
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Работаем с ПЛИС, области применения, выбор
A-10
Доброго времени суток

Доделываю этот проект: http://electronix.ru/forum/index.php?showt...126809&st=0

Суть в следующем, есть частота 40МГц (разрешение 800/600 60Гц), вертикальные и горизонтальные синхроимпульсы от AD9984А. Использую эту частоту для записи в SRAM, т.е. открываю буфер, OE, CE, LB и UB подтянуты к земле.
Регистрирую нажатие кнопки, определяющей будет ли производится запись в буфер или чтение. Записываю состояние во время смены кадра, когда Vsync = 0.
Далее, если кнопка отпущена, в следующем цикле поднимаю OE в 1, закрываю буфер (режим чтения). В каждом такте меняю адрес.
Но по факту данные то ли не пишутся или же не читаются из памяти, экран просто черный.

Память 100Мгц (IS61WV51216EDBLL), пробовал меньшее разрешение, все то же самое.

p.s. Есть некоторое непонимание по поводу валидности данных на выходе AD9984. Судя по таймингу, валидные данные появляются через 6 циклов после регенерированного HSOUT:
Нажмите для просмотра прикрепленного файла

В таком случае непонятно, куда делся передний порог в N пикселей:
Нажмите для просмотра прикрепленного файла

Однако это не объясняет проблем с памятью. Пересмотрел тайминги по 10 раз, чувствую, будто на поверхности ответ. Буду рад любому совету.

Код на verilog:
Код
module Capture_Logic
    (
        input   wire            pclk,
        input   wire            rst,
        input   wire            hsync,
        input   wire            vsync,
        input   wire            pb_state,                       // '1' as long as PB is down
        output  wire    [18:0]  sram_addr,
        output  wire            sram2_nWE,
        output  wire            sram2_nOE,
        output  wire            buffer2_nOE
    );

//

localparam  TOTAL_PXL_IN_A_ROW  = 800;

reg         pb_saved;
reg [9:0]   row_pxl_cntr;
reg [18:0]  address;
reg         vback_dis;
reg         pixel_cntr_en;

wire        sram2_rw;

//

assign      sram2_rw            = pb_saved      ? 1        : pclk;
assign      sram2_nWE           = pixel_cntr_en ? sram2_rw : 1;
assign      sram2_nOE           = pb_saved      ?        0 : 1;
assign      buffer2_nOE         = pb_saved      ?        1 : 0;
assign      sram_addr           = address;

// latch pushbutton state during vertical sync period

    always @ (negedge pclk or posedge rst) begin

        if (rst) begin
            pb_saved <= 1;
        end
        else if (vsync == 0) begin
            pb_saved <= !pb_state;
        end

    end

//  framebuffer address counter

    always @ (negedge pclk or posedge rst) begin
        
        if (rst) begin
            address <= 0;
        end else begin
            if (vsync == 0) begin
                address <= 0;
            end else if (pixel_cntr_en) begin
                address <= address + 1;
            end
        end
    
    end

// enable pixel counter

    always @ (negedge pclk or posedge rst) begin
        
    if (rst) begin
            pixel_cntr_en <= 0;
        end else if (hsync == 0) begin
            pixel_cntr_en <= 0;
        end else begin
            if ((row_pxl_cntr > 3'b110) && (row_pxl_cntr < 10'h320)) begin
                pixel_cntr_en <= 1;
            end else begin
                pixel_cntr_en <= 0;
            end
        end

    end

// input data delay counter

    always @ (negedge pclk or posedge rst) begin
        
        if (rst) begin
            row_pxl_cntr <= 0;
        end else begin
            if (hsync == 0) begin
                row_pxl_cntr <= 0;
            end else begin
                if (vback_dis == 0) begin
                    row_pxl_cntr <= row_pxl_cntr + 1;
                end else begin
                    row_pxl_cntr <= 0;
                end
            end
        end

    end

// vsync bakc porch data disable check

always @ (negedge pclk or posedge rst) begin
    
    if (rst) begin
        vback_dis <= 1;    
    end else begin
        if (vsync == 0) begin
            vback_dis <= 1;
        end else if (hsync == 0) begin
            vback_dis <= 0;
        end
    end
end

endmodule
Golikov A.
Цитата
Есть некоторое непонимание по поводу валидности данных на выходе AD9984. Судя по таймингу, валидные данные появляются через 6 циклов после регенерированного HSOUT:

Цитата
В таком случае непонятно, куда делся передний порог в N пикселей:

Валидные данные шире видимых, или вопрос про другое?
A-10
Цитата(Golikov A. @ Aug 12 2015, 12:17) *
Валидные данные шире видимых, или вопрос про другое?
Я думал, что валидные = видимые.
Получается, из валидных данных вычитаются n пикслей под задний и передний порог и остаются видимые? Т.е. следует отсчитать N(порог) + delay валидных пикселей и после начинать вывод видимого кадра, верно?
Golikov A.
обычно так...
по описанию у этой микрухи какой-то конвейер на выходе, и его надо очистить прежде чем получите что хотите, это как раз 6 слов данных надо пропустить, а дальше начинается ваша строчка, вроде так, строчка полная с началом и концом.
KPiter
Цитата
есть частота 40МГц

Цитата
Память 100Мгц

Как так?


Цитата(Golikov A. @ Aug 12 2015, 14:03) *
по описанию у этой микрухи какой-то конвейер на выходе, и его надо очистить прежде чем получите что хотите, это как раз 6 слов данных надо пропустить, а дальше начинается ваша строчка, вроде так, строчка полная с началом и концом.

не уверен на счет наличия конвеера (было бы не плохо выдержку из описания привести). Это обычный АЦП. H,V out регенирируются на основании H, V in (в самом простом случае). Начало и длительность H,V out задаются регистрами AD9984.
Golikov A.
http://www.analog.com/media/en/technical-d...ets/AD9984A.pdf

Цитата
TIMING DIAGRAMS
The timing diagrams in Figure 14 to Figure 17 show the operation of the AD9984A. The output data clock signal is created so that its
rising edge always occurs between data transitions and can be used to latch the output data externally. There is a pipeline in the AD9984A
that must be flushed before valid data becomes available
. This means six data sets are present before valid data is available.


можно конечно читать что в AD9984A есть трубопровод - нефтепровод. Но мне уместнее кажется называть эту штуку конвейером wink.gif
A-10
Цитата(KPiter @ Aug 13 2015, 10:13) *
Как так?
Время доступа памяти 10нс, частота данных 40МГц (25нс) на таком разрешении.

А кто-то может авторитетно заявить =) - нужно ли использовать CE или UB/LB для стробирования данных? Ибо на диаграммах либо то, либо другое используется. А у меня CE, UB и LB подтянуты к нулю.
zombi
Цитата(A-10 @ Aug 16 2015, 17:03) *
А кто-то может авторитетно заявить =) - нужно ли использовать CE или UB/LB для стробирования данных? Ибо на диаграммах либо то, либо другое используется. А у меня CE, UB и LB подтянуты к нулю.

Использую IS61WV102416BLL на 3,3V.
Ноги /CE,/OE,/LB,/UB все подключены к GND.
Ничего не стробирую, просто выставляю адрес и через 8 нс читаю состояние на ШД.

Пишу так как на стр.15 WRITE CYCLE NO. 3(WE Controlled. OE is LOW During Write Cycle) в DS рекомендуют.

PS. кстати мс выпуска до 2015 года устойчиво работали даже на 6,25 нс. А теперь только 8 нс.
A-10
Цитата(zombi @ Aug 17 2015, 12:29) *
Использую IS61WV102416BLL на 3,3V.
Ноги /CE,/OE,/LB,/UB все подключены к GND.
Ничего не стробирую, просто выставляю адрес и через 8 нс читаю состояние на ШД.

Пишу так как на стр.15 WRITE CYCLE NO. 3(WE Controlled. OE is LOW During Write Cycle) в DS рекомендуют.

PS. кстати мс выпуска до 2015 года устойчиво работали даже на 6,25 нс. А теперь только 8 нс.
Под стробом я имел ввиду установку WE в 0, а после в 1 в режиме записи. Да, все проверил, именно так и делаю, разве что CE высокое во режиме записи. Но, судя по таймингам, там нет отличий. В моем случае нужно Thzwe+Tsd (11ns) до поднятия WE в 1 (записи).
Видимо ошибка где-то еще, потыкаюсь осциллом более тщательно.
zombi
Цитата(A-10 @ Aug 17 2015, 13:19) *
разве что CE высокое во режиме записи.

/CE (Chip Enable) должен быть низким во всех режимах.
Может Вы /OE (Output Enable) поднимаете во время записи, а не /CE? biggrin.gif
A-10
Цитата(zombi @ Aug 17 2015, 13:33) *
/CE (Chip Enable) должен быть низким во всех режимах.
Да, речь шла об OE )) CE подтянут(ы) к 0.
Нажмите для просмотра прикрепленного файла
Цитата(zombi @ Aug 17 2015, 13:33) *
Может Вы /OE (Output Enable) поднимаете во время записи, а не /CE? biggrin.gif
То есть наоборот, вы хотели сказать )) Но я понял biggrin.gif
zombi
Цитата(A-10 @ Aug 17 2015, 14:53) *
CE подтянут(ы) к 0.

У меня /CE,/OE,/LB,/UB прямо на GND без всяких резисторов.
хотя это без разницы.
A-10
В итоге, проблема оказалась из серии "сам дурак" - Vsync регенерированный оказался active High, вместо low, как у Hsync. Вроде в начале самом проверял, оба сигнала были low.

Дальше начались некоторые непонятности - напомню, использую режим 800x600 @ 60 / @ 75
Штатная частота при 60 кадрах 40МГц.

Параметры такие:

hsync
передний бордюр - 40 (пкс)
задний бордюр - 88 (пкс)

vsync
передний бордюр - 1 (линия)
задний бордюр - 23 (линии)

Соот-но у меня активный сигнал (записи и чтения) включался по следующим условиям:

(счетчик линий > 23) AND (счетчик линий < 623) AND (счетчик пикселей > 46) AND (счетчик пикселей < 846)

+6 - это задержка конвейера.

В итоге, правая часть экрана - обрезана, черная. Примерно 50 пикселей. Изображение раз в несколько секунд обновляется с артефактами (что-то проскакивает) и есть вертикальные серые полосы на общем фоне.

Пробовал сначала немного смещать активную зону вправо, но это приводило, напротив, к совсем убитой картинке. При смещении влево, наоборот, картинка оставась такой же (что вроде не логично).

Методом тыка подобрал такие параметры:
(счетчик линий > 23) AND (счетчик линий < 623) AND (счетчик пикселей > 150) AND (счетчик пикселей < 1056)

Может кто-то объяснить, почему это работает при таких параметрах?

Дрожание исчезло, картинка не обрезана, но все равно не очень качественная:
Нажмите для просмотра прикрепленного файла
Видно не очень, но на ней есть желтые полосы и в демке с двигающимся объектом фон неравномерный, как будто размазан кистью.

Причем картинка, в режиме вывода (когда кнопка зажата и данные просто вываливаются насквозь) четче и без желтизны:
Нажмите для просмотра прикрепленного файла

Я грешу на несколько вариантов:
а) частоты WE и PCLK не в фазе, так как первый проходит с задержкой
Нажмите для просмотра прикрепленного файла
б) R2R ОУ имеет нелинейность, у меня к тому же на этом канале резисторы натыканы с большим допуском, т.к. выбрал неправильные номиналы изначально и впаял что есть.
в) PCLK брошен не на global clock вход CPLD. изначально завел туда только основую частоту (которую использую для I2C и периферии). Не знаю, насколько это влияет.

p.s. Снимал осциллогамму вывода данных с VGA напрямую, выводил просто белый квадрат. Строб WE идет не там, но я это исправил. Непонятно, почему во время переднего бордюра выводятся какие-то данные.
Нажмите для просмотра прикрепленного файла
Barktail
А что служит сигналом к сбросу счетчика?
A-10
@ Barktail
счетчик пикселей в линии сбрасывается сигналом гор. синхронизации, линий - вертикальной.
Barktail
Цитата(A-10 @ Aug 27 2015, 21:11) *
hsync
передний бордюр - 40 (пкс)
задний бордюр - 88 (пкс)

vsync
передний бордюр - 1 (линия)
задний бордюр - 23 (линии)

(счетчик линий > 23) AND (счетчик линий < 623) AND (счетчик пикселей > 46) AND (счетчик пикселей < 846)


вот тут (счетчик пикселей > 46) AND (счетчик пикселей < 846) Вроде как должно быть (счетчик пикселей > 94) AND (счетчик пикселей < 894), т.к. учитывается задний бордюр. А вообще, уж извините если скажу очевидную вещь, строчные синхроимпульсы точно идут стабильно, без большого джиттера? И как то странно на фотографиях черная полоса справа на экране. По идее такой быть не должно.

Я когда то делал простенький вывод на VGA, там было всего 8 цветов, и не графика, а знакогенератор. Но именно 800 на 600, 60 герц, и весь экран заполняло. Для него сделал вот такой генератор синхроимпульсов, потом еще пару раз его использовал, вроде все отлично было. Вдруг поможет?
A-10
@ Barktail

да, вы правы, back porch = 88+6. я еще раз проверю все, я пытался подстроиться под референсный сигнал, возможно напутал.
джиттера нет, регенерированный сигнал весьма четкий.

полосы там и справа и слева (ракурс неудачный), просто видимое изображение сжато )
кстати, на 75Гц каритнка четче, чем на 60.

спасибо! посмотрю, попробую найти возможные проблемы. а потом возьмусь за исправление в железе, попробую ЦАП отдельный поставить и посмотреть как с ним будет.
A-10
Попробовал с параметрами 94 < pxl_cntr < 894, вылезла та самая полоса сбоку, экран начал дрожать и весь приобрел желтый оттенок ) мистика
Maverick
Цитата(A-10 @ Aug 28 2015, 21:03) *
Попробовал с параметрами 94 < pxl_cntr < 894, вылезла та самая полоса сбоку, экран начал дрожать и весь приобрел желтый оттенок ) мистика


Времянка под конкретное разрешение VGA точно соблюдена? (проверьте еще раз математику расчетов констант для счетчиков (строк и столбцов) исходя из Вашей тактовой частоты ПЛИС на которой они формируются)
Если убрать бордюры (равные нулю) по строкам и столбцам изображение правильное?
далее я бы на Вашем месте проверил данные то что Вы читаете из памяти и выдаете на экран

Попробуйте загрузить заранее известные данные например цветные полосы, узоры и т.д.
Эти данные можно генерировать ПЛИС, далее производите запись во внешнюю память и выдаете на экран.
Таким образом, можно попробовать проверить не сбивается ли синхронизация и запись/чтение в/из памяти и вывод на экран работает ли корректно.
Можно сделать упрощения использовать только блочную память ПЛИС для проверки вывода на экран.

Можно сделать схему сравнения данных чтения из памяти и данных для вывода на экран...


попробуйте определить номера пикселей столбца (который не правильный) и чипскопом/сигналтапом посмотреть что при этом пишется и разобраться почему это пишется не правильно, т.е. отследить
всю цепочку... Выведете максимум сигналов в логический анализатор, сделайте максиальный буфер в анализаторе...

Переходы между клоковыми доменами соблюдены?
A-10
Maverick
Проверил, по VESA Generalized Timing Formula - там другие значения =) 150 для back porch. Поменял, но полоса справа вылазит опять.

Убрать бордюры - как это?

Просто у меня аппартаная часть такова, что данные, которые идут на DAC, висят на входе SRAM. То есть та же картинка, что идет на ЦАП (условно хорошая) идет и на память.

Я как раз загружаю изображение с ноута, запускаю TFT-тест. Использовал белую заливку для поиска бордюров и тест с движущимся объектом. По сути так и делаю, держу кнопку - данные проходят на ЦАП (и одновременно записывается последний кадр), отпускаю - происходит чтение из памяти на ЦАП (входной буфер данных закрыт).

Но ПЛИС хорошая идея, спасибо. Можно будет попробовать нестандарное разрешение (мне по ТЗ нужно 800x480, отлаживаюсь на 800x600).

Данные идут напрямую на все SRAM, ПЛИС управляет только адресами и сигналами управления.
То есть шину я могу проверить только осциллографом/лог. анализатором. Можно, конечно, попробовать подпаяться и кинуть шину на отладку с ПЛИС, сделать сравнение и выдать куда-нить в терминал.

Клоковых доменов 2, но они не связаны - от основной частоты тактируется I2C и логика сброса, антидребезг кнопок. А VGA часть тактируется частотой пикселей от AD9984.

Еще по global clock почитал, пишут, что если в этой таблице есть наименование клока, то он пущен через глобальную линию (то есть можно не перепаивать ко входу gclk?)
Нажмите для просмотра прикрепленного файла
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.