Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: kintex7+pci-e
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Работаем с ПЛИС, области применения, выбор
exigo
Добрый день. Есть отладочная плата с kintex7 (xc7k160t) Mercury_PE1 c Mercury_KX1. использую и ISE и Vivado
Требуется организовать передачу данных из плис в компьютер по pcie.
Для начала хочу, чтобы устройство хоть как-то обозначилось на компьютере, для этого конфигурирую ядро без изменений, сразу по умолчанию, и компилирую заголовочный xilinx_pcie_2_1_ep_7x.vhd
Но на компьютере тишина, в чипскоп завел тактовые и осцилографом смотрел на плате - нет входной частоты для pcie, и соответсвенно ничего не работает.
Подскажите пожалуйста, что делаю не так, что упустил?
RobFPGA
Приветствую!

Для начала нужно убедится что правильно назначены пины в constrain файле.

Многие материнки если в течении 100 ms после reset не обнаружили PCIe устройство могут отключать ref clk на этот слот для экономии.
Так что смотреть clk осцилографом надо сразу после reset.

Удачи! Rob.
AVR
Цитата(exigo @ Jan 19 2017, 11:39) *
Но на компьютере тишина, в чипскоп завел тактовые и осцилографом смотрел на плате - нет входной частоты для pcie, и соответсвенно ничего не работает.
Подскажите пожалуйста, что делаю не так, что упустил?
Я могу ошибаться, но вроде как есть возможность работы PCI-E без клока от материнской платы, хотя рекомендуют его всё же брать, иначе в режимах с spread spectrum запас может быть предельно мал. Как-то так.
Соответственно, это не причина что не работает, правильно подсказывают - может пины неверно назначены, я бы смотрел как они настроены в примере к плате. Кроме того, так как проект почти пустой, есть вероятность что компилятор просто выкинул всю логику. Вроде есть и прием и передача в таких проектах, но тем не менее, мне попадалось и такое - если нет задействования "внутриплисных" интерфейсов то ядро вычистилось под ноль - тоже советую проверить.
exigo
Мне думалось, что пример должен сразу отрабатывать.
В настройках выбирается внутренний аппаратный блок, генерируется constrain. Как я понимаю, там должны быть уже указаны задействованые пины, и не требуется вносить изменения?

Вот ссылка на мой UCF
https://www.dropbox.com/s/5yv8p8lz4y0uybm/m...x1_top.ucf?dl=0
Inanity
Дело не только в ref clk. Устройство должно быть готово через 100мс, чтобы успешно пройти enumeration, иначе до свидания, даже если ref clk с матери не используется.

ТС, убедитесь, что успеваете сконфигурироваться. Если не успеваете, то можно питать плату отдельно от компа, конфигурировать её, потом выполнить перезагрузку компа. Для первых тестов будет достаточно, а потом разберётесь, почему не успеваете. Скорее всего изменение схемы конфигурации ПЛИС + увеличение частоты решат проблему.
Lixlex
Цитата(exigo @ Jan 19 2017, 13:24) *
Мне думалось, что пример должен сразу отрабатывать.
В настройках выбирается внутренний аппаратный блок, генерируется constrain. Как я понимаю, там должны быть уже указаны задействованые пины, и не требуется вносить изменения?

Нет, пины надо править под вашу плату.
RobFPGA
Приветствую!

Цитата(Inanity @ Jan 19 2017, 13:59) *
Дело не только в ref clk. Устройство должно быть готово через 100мс, чтобы успешно пройти enumeration, иначе до свидания, даже если ref clk с матери не используется.

ТС, убедитесь, что успеваете сконфигурироваться. Если не успеваете, то можно питать плату отдельно от компа, конфигурировать её, потом выполнить перезагрузку компа. Для первых тестов будет достаточно, а потом разберётесь, почему не успеваете. Скорее всего изменение схемы конфигурации ПЛИС + увеличение частоты решат проблему.


На начальном этапе это не столь важно - enumeration происходит при каждом reset материнки. Так что если и не успели после power on то после следующего reset FPGA уже сконфигурированна.

Удачи! Rob.


AVR
Цитата(exigo @ Jan 19 2017, 13:24) *
Мне думалось, что пример должен сразу отрабатывать.
Ого... А Вы компьютер с этой платой перезагружаете перед попытками обнаружить устройство? Я бы под это дело отдельный комп выделил. Книга по теме прочитана? Мне вот такая нравится "PCI Express Technology. Comprehensive Guide to Generations 1.x, 2.x, 3.0", правда она дорогая, но... wink.gif Однако и ее, как ни странно, недостаточно для полного понимания, особенно со стороны хоста, драйвера и BIOS (если есть).
exigo
Цитата(Lixlex @ Jan 19 2017, 18:37) *
Нет, пины надо править под вашу плату.

Кто-нибудь может скинуть название плис, и констрейн файл, чтобы я разобрался как оно было подключено. (лучше конечно когда использовалось ядро 7 серии)
А то в интернете сколько находил, примерно так же стандартно, нет конкретного упоминания той или иной ноги

У меня есть отладочная плата как выше писал, программа на флешке записана, в биосе убрал всякие энергосбережения, попробовал вначале запитать плату, чтобы программа подгрузилась и инициализировалась, после включаю компьютер. Но результата ноль пока, тоже грешу на пины, смущает что не требуется указывать конкретные ноги (как в ддр ядре например), но нет примера чтоб узнать как правильно, по даташитам просто компилируют, и якобы ядро конфигурируется на аппаратный блок pci-e конкретно выбранной плис, и соответственно ноги настроены.
Есть еще конечное устройство(с такой же плис) для которого поднимается pci-e, оно подключено по pci-e кабелю, и там тоже я вначале питание подаю, а потом ПК включаю, но результат пока тот-же.
toshas
Цитата(exigo @ Jan 20 2017, 05:50) *
Но результата ноль пока, тоже грешу на пины, смущает что не требуется указывать конкретные ноги (как в ддр ядре например)


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

Например вместо перечисления ног можно задать положение буфера так:
set_property LOC IBUFDS_GTE2_X0Y0 [get_cells refclk_ibuf]
exigo
Цитата(toshas @ Jan 20 2017, 11:37) *
В файлах ограничений может использоваться привязка к координатам конкретного блока, неявно она же и задает ножки, т.к. конкретный блок имеет конкретное фиксированное подключение.

Например вместо перечисления ног можно задать положение буфера так:
set_property LOC IBUFDS_GTE2_X0Y0 [get_cells refclk_ibuf]


значит ядро норм генерирует
Flood
Цитата(exigo @ Jan 20 2017, 09:49) *
значит ядро норм генерирует

Ядро генерируется корректно, но наверняка не для вашей платы.
Возьмите схемы мезонина и базовой платы и выясните, к каким пинам ПЛИС подсоединены сброс (PERST), клок и лейны PCI-e. Соответственно отредактикуйте ucf / xdc и наступит счастье.

Вот эти строки в вашем ucf на чем основаны? И почему не задан LOC для sys_rst_n?

Код
NET "sys_rst_n" TIG;
NET "sys_rst_n" IOSTANDARD = LVCMOS18 | PULLUP | NODELAY;

INST "refclk_ibuf" LOC = IBUFDS_GTE2_X0Y3;

INST "pcie_7x_vhdl_i/gt_top_i/pipe_wrapper_i/pipe_lane[0].gt_wrapper_i/gtx_channel.gtxe2_channel_i" LOC = GTXE2_CHANNEL_X0Y7;

INST "pcie_7x_vhdl_i/pcie_top_i/pcie_7x_i/pcie_block_i" LOC = PCIE_X0Y0;
exigo
Цитата(Flood @ Jan 20 2017, 16:27) *
Ядро генерируется корректно, но наверняка не для вашей платы.
Возьмите схемы мезонина и базовой платы и выясните, к каким пинам ПЛИС подсоединены сброс (PERST), клок и лейны PCI-e. Соответственно отредактикуйте ucf / xdc и наступит счастье.

Вот эти строки в вашем ucf на чем основаны? И почему не задан LOC для sys_rst_n?

Код
NET "sys_rst_n" TIG;
NET "sys_rst_n" IOSTANDARD = LVCMOS18 | PULLUP | NODELAY;

INST "refclk_ibuf" LOC = IBUFDS_GTE2_X0Y3;

INST "pcie_7x_vhdl_i/gt_top_i/pipe_wrapper_i/pipe_lane[0].gt_wrapper_i/gtx_channel.gtxe2_channel_i" LOC = GTXE2_CHANNEL_X0Y7;

INST "pcie_7x_vhdl_i/pcie_top_i/pcie_7x_i/pcie_block_i" LOC = PCIE_X0Y0;


При конфигурации выбран X0Y0 (ну для х1 вариантов то и нет), и все это из примера, про ресет тоже задумывался, sys_rst_n подключить к PERST ?
Flood
Цитата(exigo @ Jan 20 2017, 12:40) *
При конфигурации выбран X0Y0 (ну для х1 вариантов то и нет), и все это из примера, про ресет тоже задумывался, sys_rst_n подключить к PERST ?

Еще раз: возьмите схемы ваших плат и составьте ucf согласно этим схемам. Авторам примера генерации ядра неизвестно, на какую плату вы генерируете ядро. Если бы это была родная отладочная плата KC705 - тогда да, ее распиновка Xilinx-у известна.
Ну а про вашу откуда он должен узнать, если не от вас?
exigo
Что-то пересмотрел несколько примеров ucf для разных плат, и где как.
Подключил sys_rst к светодиоду и user_rst. При перезагрузке sys_rst мигает, но user_rst постоянно в 1( не горит), а для успешной инициализации как понимаю должен в 0 выставится.
Ниже прилагаю поправленный ucf, добавил пин с разъема sys_rst.
Добавил пины тактирования и закомментировал буфер, пока от всяких махинаций результат один (как написал выше).

Код
NET "sys_rst_n" TIG;
NET "sys_rst_n" LOC = M20 | IOSTANDARD = LVCMOS33 | PULLUP | NODELAY;
#INST "refclk_ibuf" LOC = IBUFDS_GTE2_X0Y3;
# PCIe Lane 0
INST "pcie_7x_v1_11_i/gt_top_i/pipe_wrapper_i/pipe_lane[0].gt_wrapper_i/gtx_channel.gtxe2_channel_i" LOC = GTXE2_CHANNEL_X0Y7;
INST "pcie_7x_v1_11_i/pcie_top_i/pcie_7x_i/pcie_block_i" LOC = PCIE_X0Y0;
#
# BlockRAM placement
#
INST "pcie_7x_v1_11_i/pcie_top_i/pcie_7x_i/pcie_bram_top/pcie_brams_rx/brams[3].ram/use_tdp.ramb36/ramb_bl.ramb36_dp_bl.ram36_bl" LOC = RAMB36_X5Y35;
INST "pcie_7x_v1_11_i/pcie_top_i/pcie_7x_i/pcie_bram_top/pcie_brams_rx/brams[2].ram/use_tdp.ramb36/ramb_bl.ramb36_dp_bl.ram36_bl" LOC = RAMB36_X4Y36;
INST "pcie_7x_v1_11_i/pcie_top_i/pcie_7x_i/pcie_bram_top/pcie_brams_rx/brams[1].ram/use_tdp.ramb36/ramb_bl.ramb36_dp_bl.ram36_bl" LOC = RAMB36_X4Y35;
INST "pcie_7x_v1_11_i/pcie_top_i/pcie_7x_i/pcie_bram_top/pcie_brams_rx/brams[0].ram/use_tdp.ramb36/ramb_bl.ramb36_dp_bl.ram36_bl" LOC = RAMB36_X4Y34;
INST "pcie_7x_v1_11_i/pcie_top_i/pcie_7x_i/pcie_bram_top/pcie_brams_tx/brams[0].ram/use_tdp.ramb36/ramb_bl.ramb36_dp_bl.ram36_bl" LOC = RAMB36_X4Y33;
INST "pcie_7x_v1_11_i/pcie_top_i/pcie_7x_i/pcie_bram_top/pcie_brams_tx/brams[1].ram/use_tdp.ramb36/ramb_bl.ramb36_dp_bl.ram36_bl" LOC = RAMB36_X4Y32;
INST "pcie_7x_v1_11_i/pcie_top_i/pcie_7x_i/pcie_bram_top/pcie_brams_tx/brams[2].ram/use_tdp.ramb36/ramb_bl.ramb36_dp_bl.ram36_bl" LOC = RAMB36_X4Y31;
INST "pcie_7x_v1_11_i/pcie_top_i/pcie_7x_i/pcie_bram_top/pcie_brams_tx/brams[3].ram/use_tdp.ramb36/ramb_bl.ramb36_dp_bl.ram36_bl" LOC = RAMB36_X4Y30;
###############################################################################
# Timing Constraints
###############################################################################
NET "sys_clk" TNM_NET = "SYSCLK";
NET "ext_clk.pipe_clock_i/clk_125mhz" TNM_NET = "CLK_125";
NET "ext_clk.pipe_clock_i/clk_250mhz" TNM_NET = "CLK_250";
NET "ext_clk.pipe_clock_i/userclk1" TNM_NET = "CLK_USERCLK";
NET "ext_clk.pipe_clock_i/userclk2" TNM_NET = "CLK_USERCLK2";
TIMESPEC "TS_SYSCLK"  = PERIOD "SYSCLK" 100 MHz HIGH 50 %;
TIMESPEC "TS_CLK_125"  = PERIOD "CLK_125" TS_SYSCLK*1.25 HIGH 50 % PRIORITY 1;
#TIMESPEC "TS_CLK_250" = PERIOD "CLK_250" TS_SYSCLK*2.5 HIGH 50 % PRIORITY 2;
TIMESPEC "TS_CLK_USERCLK" = PERIOD "CLK_USERCLK" TS_SYSCLK/1.6 HIGH 50 %;
TIMESPEC "TS_CLK_USERCLK2" = PERIOD "CLK_USERCLK2" TS_SYSCLK/1.6 HIGH 50 %;

NET "sys_clk_n"                 LOC =  "D5" | IOSTANDARD = "LVDS"; #| DIFF_TERM = "FALSE";
NET "sys_clk_p"                 LOC =  "D6" | IOSTANDARD = "LVDS";# | DIFF_TERM = "FALSE";

INST "ext_clk.pipe_clock_i/mmcm_i"  LOC = MMCME2_ADV_X0Y2;
PIN "pcie_7x_v1_11_i/pcie_top_i/pcie_7x_i/pcie_block_i.PLPHYLNKUPN" TIG;
PIN "pcie_7x_v1_11_i/pcie_top_i/pcie_7x_i/pcie_block_i.PLRECEIVEDHOTRST" TIG;
PIN "ext_clk.pipe_clock_i/mmcm_i.RST" TIG;
NET "pcie_7x_v1_11_i/gt_top_i/pipe_wrapper_i/user_resetdone*" TIG;
NET "ext_clk.pipe_clock_i/pclk_sel" TIG;
NET "pcie_7x_v1_11_i/gt_top_i/pipe_wrapper_i/pipe_lane[0].pipe_rate.pipe_rate_i/*" TNM_NET = FFS "MC_PIPE";
TIMESPEC "TS_PIPE_RATE" = FROM "MC_PIPE" TS_CLK_USERCLK*0.5;
#NET "pcie_7x_v1_11_i/gt_top_i/pipe_wrapper_i/pipe_reset.pipe_reset_i/cpllreset" TIG;

И еще подскажите, пожалуйста, программу для отслеживания pci-e устройства (win7 x64)
Flood
Выложите схемы обеих плат, без них нет никакого смысла гадать по ucf.
exigo
Цитата(Flood @ Jan 25 2017, 03:12) *
Выложите схемы обеих плат, без них нет никакого смысла гадать по ucf.

Вот схема конечного устройства, а на отладочной плате enclustra pe-1 + kx-1, не отследил линию сброса, только трансиверы
exigo
Что-то так и не пойму, если подключаем к sys_reset PERST, Нормальное состояние сигнала 1, а сброс по 0?
Flood
Цитата(exigo @ Jan 27 2017, 12:15) *
Что-то так и не пойму, если подключаем к sys_reset PERST, Нормальное состояние сигнала 1, а сброс по 0?


На слоте PERST# - активный 0.
Насчет выложенных картинок - это не схема, а какие-то обрывки. Вы снова предлагаете гадать по неполной информации.
Могу предположить, что:
Код
INST "pcie_7x_v1_11_i/gt_top_i/pipe_wrapper_i/pipe_lane[0].gt_wrapper_i/gtx_channel.gtxe2_channel_i" LOC = GTXE2_CHANNEL_X0Y4;

Но не уверен, что это правильно. Схемы-то толком нет.

Обратитесь в саппорт изготовителя отладочной платы с вопросом: дайте ucf на PCI Express для вашей платы.
exigo
Судя по этому, правильно X0Y7
Заметил, что должна быть выставлена PRSNT в '1', может еще какие сигналы забыл, почему-то об этом нигде не увидел.
upd: хотя если выставляю '1', то ресет на 0 зависает
Flood
Если есть ощущение, что пинаут правильный (что не факт), возможно, что конфигурирование ПЛИС занимает слишком много времени и плата успевает отключить клок.
Об этой проблеме достаточно подробно написано в документации на ядро. Но скорее проблема в пинауте.
exigo
На плате таковую осциллографом увидел, копаю дальше
exigo
Устройство увиделось в системе.
И тактовую и трансиверы потребовалось напрямую задавать.
exigo
Здравствуйте, взялся за реализацию обмена по pcie. Плата с Kintex7. Пк Win7, смотрю память программой RW-Everything, ну и собственная есть для чтения из БАРов и памяти.
Подключил пример с ядром 7 Series FPGAs Integrated Block for PCI Express v1.7. Чтение и запись, работа с БАРами получилась, теперь стоит задача, чтобы железо писало по заданному адресу.
В корке по запросу чтения из БАРа реализована запись сл. образом:
Код
s_axis_tx_tdata <= (
                                    rd_data &
                                    req_rid &
                                    req_tag &
                                    '0' &
                                    lower_addr &
                                    completer_id &
                                    "000" &
                                    '0' &
                                    byte_count &
                                    '0' &
                                    PIO_CPLD_FMT_TYPE & --"1001010"
                                    '0' &
                                    req_tc &
                                    "0000" &
                                    req_td &
                                    req_ep &
                                    req_attr &
                                    "00" &
                                    req_len
                                    ) after TCQ;

Начал городить запись в память по заданному адресу, решил попробовать написать в ту же область (в моем случае под БАР выделяется память с адреса 0xF610000), изменил пакет сл образом.
Код
s_axis_tx_tdata <= (
                                    rd_data &
                                    X"F6100000" &
                                    req_rid &
                                    req_tag &
                                    req_lb & --здесь значение "1111" --не совсем понял назначение этих двух переменных, но в примерах дма такие значения.
                                    req_fb & -- здесь значение "1111"
                                    "01000000" & --запись в память
                                    '0' &
                                    req_tc &
                                    "0000" &
                                    req_td &
                                    req_ep &
                                    req_attr &
                                    "00" &
                                    req_len
                                    ) after TCQ;

После попытки чтения, комп подвисает немного, но данных нет, пробовал по другому адресу, тоже ничего.
Подскажите, пожалуйста, может служебные переменные "вырванные" из запроса на чтение БАР(шины m_axis_rx_tdata) не подходят в данном случае.
Хотелось бы пример команды с чистой записью из железки в ПК по заданному адресу, возможно однократная.
AVR
Цитата(exigo @ Nov 22 2017, 14:05) *
Хотелось бы пример команды с чистой записью из железки в ПК по заданному адресу, возможно однократная.

Сам ПК успешно считал из BAR через эту программу (rw everything), т.е. проходят запросы CplD?
Итак, попытка записать в ПК из железки - откуда берется адрес? И как он попадает в железку, хардкод что ли?

Цитата(exigo @ Nov 22 2017, 14:05) *
решил попробовать написать в ту же область

т.е. данные будут прилетать без запроса? Кто их там ждет? А кто сказал что адрес для устройства и адрес для ядра ОС один и тот же? Не знаю, возможно ли это, я так никогда не делал, может потому компьютер удивляется.
exigo
Цитата(AVR @ Nov 22 2017, 18:15) *
Сам ПК успешно считал из BAR через эту программу (rw everything), т.е. проходят запросы CplD?
Итак, попытка записать в ПК из железки - откуда берется адрес? И как он попадает в железку, хардкод что ли?


т.е. данные будут прилетать без запроса? Кто их там ждет? А кто сказал что адрес для устройства и адрес для ядра ОС один и тот же? Не знаю, возможно ли это, я так никогда не делал, может потому компьютер удивляется.

Да, исходный пример с ядром по записи-чтению в БАР, работает. Запросы проходят, вот я подумал изменить этот кусок, чтобы он писал не в БАР, а мной заданный адрес (для начала прям в коде железно адрес, пробовал разные, а потом через БАР буду задавать выделенную область). Поэтому вот хочу разобраться просто в команде записи по заданному адресу.

//update
Я похоже адрес неправильно ввожу, т.к. там в конце два бита зарезервированы, а адрес 30 разрядный
AVR
Цитата(exigo @ Nov 23 2017, 06:12) *
Я похоже адрес неправильно ввожу, т.к. там в конце два бита зарезервированы, а адрес 30 разрядный

Для Windows не подскажу, но по аналогии в Linux можно (в качестве самого базового способа) вызвать dma_alloc_coherent и выделить некоторый буфер, например 4096 байт. И получив два адреса, один отдается устройство в которое оно может писать в произвольный момент времени, а ядро ОС может читать что записало устройство по второму адресу.
Отсюда и вопрос - как Вы выделяете память, приведите пример. И какие меры приняты, чтобы оба адреса оставались постоянными, чтоб их можно было чуть ли не зашить в прошивку.

Если пользуетесь сторонней программой, то похоже это тот самый момент, когда надо уже начинать писать свой драйвер.

Цитата(exigo @ Nov 23 2017, 06:12) *
Я похоже адрес неправильно ввожу, т.к. там в конце два бита зарезервированы, а адрес 30 разрядный

Да, там есть такое дело, адрес должен быть с шагом 4 байта, если не ошибаюсь, и действительно 2 младших бита нулевые.
exigo
Цитата(AVR @ Nov 23 2017, 14:36) *
Для Windows не подскажу, но по аналогии в Linux можно (в качестве самого базового способа) вызвать dma_alloc_coherent и выделить некоторый буфер, например 4096 байт. И получив два адреса, один отдается устройство в которое оно может писать в произвольный момент времени, а ядро ОС может читать что записало устройство по второму адресу.
Отсюда и вопрос - как Вы выделяете память, приведите пример. И какие меры приняты, чтобы оба адреса оставались постоянными, чтоб их можно было чуть ли не зашить в прошивку.

Если пользуетесь сторонней программой, то похоже это тот самый момент, когда надо уже начинать писать свой драйвер.

Да, там есть такое дело, адрес должен быть с шагом 4 байта, если не ошибаюсь, и действительно 2 младших бита нулевые.


С выделением памяти есть своя программа, предполагал, пока не передаю выделенный адрес в плис, просто протестировать запись с произвольную ячейку, но видимо так нельзя? (заведомо брал побольше адрес, чтобы он неиспользовался и там нулевые значения были).
AVR
Цитата(exigo @ Nov 24 2017, 13:41) *
С выделением памяти есть своя программа, предполагал, пока не передаю выделенный адрес в плис, просто протестировать запись с произвольную ячейку, но видимо так нельзя? (заведомо брал побольше адрес, чтобы он неиспользовался и там нулевые значения были).

Вот не знаю, мне кажется (кажется!) так нельзя. У меня есть собственные догадки, почему так, не буду их афишировать, дабы не прогневать специалистов sm.gif
Лучше полагаться на API операционной системы, и всё будет работать. Это не микроконтроллер, совсем произвольно так с адресами нельзя поступать, всё (адреса шин) должно штатным образом отображаться одно в другое.

Цитата(exigo @ Nov 24 2017, 13:41) *
А по поводу адреса в ПЛИС, при 32 битной адресации address[31:2], [1,0] - reserv. Получается адрес максимум 30 разрядный? 3FFFFFFF максимальный адрес, или адрес считывается вместе с младшими нулями? и нормально можно адресовать FFFFFFFF.

А как же 64-битная адресация у PCI-E? Тут http://xillybus.com/tutorials/pci-express-...utorial-guide-1 пишут, что такое редко когда надо.
В принципе, ясно, что ширина адреса это не катастрофа, всегда можно обойти окошечками.
AVR
Еще одна деталь, насчет "нормально адресовать" FFFFFFFF.
http://www.compbegin.ru/articles/view/_76
Цитата
Как мы уже знаем, чисто теоретически 32-х разрядной системе без каких-либо дополнительных ухищрений доступны до 4 гигабайт оперативной памяти (232), но Windows не может использовать весь этот объем, так как часть его отводится под устройства компьютера.
Так что, я полагаю, что ширина ворот для адресации устройств составляет лишь 1 Гбайт. Не могу уверенно утверждать, там далеко я еще не забирался. Возможно для AMD64/x86_64 эта ситуация несколько иначе.
exigo
Проверенными методами выделяю память, и передаю начальный адрес в ПЛИС через БАР0, на стороне плис успешно его считываю, там же в БАР0 записываю бит разрешающий писать по данному адресу. В ПЛИС по этому флагу собственно вот такой механизм записи в ПК, в нем очень не уверен, думаю из-за него и проблема. Так же прочитал, что должен быть в конфигурации выставлен бит мастер шины, по 0x4 адресу = 0x0006, т.е. 2 бит выставлен верно.
Код
            if (write_en_f = '1') then                        
                        if ((s_axis_tx_tready) = '1') then
                         s_axis_tx_tlast <= '1' after TCQ;
                         s_axis_tx_tvalid <= '1' after TCQ;
                         s_axis_tx_tdata <= (
                                                    X"11111111" & --data
                                                    st_addr & --addr
                                                    "0000000000000000" &
                                                    "00000000" &
                                                    "0000" &
                                                    "1111" &
                                                    "01000000" &
                                                    '0' &
                                                    "000" &
                                                    "0000" &
                                                    '0' &
                                                    '0' &
                                                    "00" &
                                                    "00" &
                                                    req_len
                                                    ) after TCQ;

                            s_axis_tx_tkeep <= x"FFFF" after TCQ;
                        end if;
                
                    else         
                      s_axis_tx_tlast  <= '0' after TCQ;
                      s_axis_tx_tvalid <= '0' after TCQ;
                      s_axis_tx_tdata  <= (others => '0') after TCQ;
                      s_axis_tx_tkeep  <= (others => '1') after TCQ;
                  end if; --write_en_f

Не уверен, что этого достаточно, или параметры не верны, хочу по начальному адресу для начала хотя бы записать один пакет. На ПК тишина и в области памяти нули. Синего экрана даже нет, как будто ничего и не происходит.
exigo
Скажите, пожалуйста, кто знает, похоже на правду или я кардинально неправильно делаю sm.gif А то всё капаю капаю, а вдруг, где 1 бит не так. Буду благодарен конечно, если скините кусок рабочего кода.
AVR
Цитата(exigo @ Jan 15 2018, 07:31) *
Скажите, пожалуйста, кто знает, похоже на правду или я кардинально неправильно делаю sm.gif А то всё капаю капаю, а вдруг, где 1 бит не так. Буду благодарен конечно, если скините кусок рабочего кода.

А как же "его величество светодиод"? Делая проект на PCI-E нужно не забывать об удобной инфраструктуре отладки, а не гадать в слепую. Надо иметь возможность четко знать "вот тут не так", а "тут как надо".

Могу лишь посоветовать или даже скинуть код отладки. Я отлаживаю так: есть некий буфер из полей единого формата, куда я кидаю события или значения каких-то регистров + временная метка в микросекундах например. Когда событий накопилось допустим 1000, я сбрасываю это в UART. Так можно получить ясную картину что где когда происходило и отладить проблему, сверить с моделью. Сам UART на передачу чудовищно прост: просто делитель и {1'b0, data[7:0], 1'b1} всё.

Еще один мой подход - PCI-E пользовательскую логику можно вынести в отдельный модуль, и его то уже моделировать, ведь интерфейс PCI-E ядер на мой взгляд примитивен, так что его легко имитировать, и таким образом отлаживать саму логику свой части в Modelsim или ином симуляторе, используя обильный принтинг ($display или $fprintf и т.д.). А уже в top-модуле просто слепить свою логику и PCI-E ядро.
exigo
Да и светодиоды использую для проверки и chipscope, в том то и дело, что на основе моей логике и пакеты формируются и все что надо выставляется, но по заданным адресам на пк так и тишина, вот и грешу на служебные слова в заголовке пакета, что выше скидывал, хотя судя по мануалам везде нули.

Функция запаси или автомат формирования запроса и данных, очень меня бы спас

А на счет бита, это я про бит мастер шины, мало ли, где что-то подобное упустил. (кстати через светодиод и проверил)
AVR
Цитата(exigo @ Jan 15 2018, 11:26) *
Да и светодиоды использую для проверки и chipscope, в том то и дело, что на основе моей логике и пакеты формируются и все что надо выставляется, но по заданным адресам на пк так и тишина, вот и грешу на служебные слова в заголовке пакета, что выше скидывал, хотя судя по мануалам везде нули.
Функция запаси или автомат формирования запроса и данных, очень меня бы спас
А на счет бита, это я про бит мастер шины, мало ли, где что-то подобное упустил. (кстати через светодиод и проверил)

Я предлагаю сделать свой отладочный модуль вместо chipscope, некий 9-битный FIFO, где 8 бит данные на каждый байт, а 9-й бит означает начало пакета. Вот это потом вывалить в UART при этом начало пакета предварять символами 0x0D 0x0A. Тогда будет видно - вот такие пакеты зашли, такие вышли. Я так и отлаживал, имея легкочитаемые пакеты перед глазами, в которых легко найти ошибку, неверный битик.
Понятно что PCI-E это скорость света, а UART улитка, но всё равно, накопив немного пакетов на огромной скорости, их потом можно неспешно выдавить в UART и скушать терминалом.

И да, я не вижу кода драйвера - может настройка неверна в части ПО? Добро пожаловать на paste.org.ru и ссылки сюда, можно просто приложить исходник сюда к сообщениям - этот форум имеет такую функцию.
exigo
Снова приветствую, запись завелась, теперь новый затык.
Пишу сл. образом: шина 128 бит, Первый TLP пакет(128 бит), и следом 8 пакетов данных. Все чудесно пишется, но только некоторое время. Ниже прилагаю скрин чипскопа. Каждый эксперимент прокачивает +- одинаковое количество данных. Пробовал кольцевой буфер и 1мб и 1кб, результат примерно один. Подскажите пожалуйста, почему падает tx_ready.
AVR
Цитата(exigo @ Mar 6 2018, 13:12) *
Снова приветствую, запись завелась, теперь новый затык.

Стоп стоп стоп, прошу прощения, так дело не пойдет. Это не форум техподдержки, это по сути публичная база знаний.
Что было конкретно сделано чтобы решить проблему? Прошу дать краткое описание решения.

Цитата(exigo @ Mar 6 2018, 13:12) *
Пишу сл. образом: шина 128 бит, Первый TLP пакет(128 бит), и следом 8 пакетов данных. Все чудесно пишется, но только некоторое время. Ниже прилагаю скрин чипскопа. Каждый эксперимент прокачивает +- одинаковое количество данных. Пробовал кольцевой буфер и 1мб и 1кб, результат примерно один. Подскажите пожалуйста, почему падает tx_ready.

Используемое IP-ядро само автоматически проверяет доступность "кредитов"?
Какое время пишется - надо четко указать. И что происходит когда прокачка данных завершается - она завершается досрочно с зависанием, или аварийно. Или просто пакеты перестают идти?
exigo
Дада, вчера не успел на работе)
Поставил вивадо и запустил корку дма бета. Изучил формирование пакета и автомат управления сигналами. Собственно, чего и не хватало. До конца помогло разобраться в конфигурации ТЛП запроса, ну и организовал автомат управляющий ногами как на скрине выше.
Вот как формируется ТЛП запрос
Код
                                    s_axis_tx_tdata <= (
                                                        dma_addr & --lo addr
                                                        X"00000000" & --hi addr
                                                        X"0600" & --RID
                                                        "10000000"&--tx_tag
                                                        "1111" &
                                                        "1111" &
                                                        "01100000" & --write
                                                        '0' &
                                                        "000" &
                                                        "0000" &
                                                        '0' &
                                                        '0' &
                                                        "00" &
                                                        "00" &
                                                        "0000100000"    --32 DW                                            
                                                        ) after TCQ;

Передача как на скрине выше, организована циклическая запись, запись по сигнала Tx_ready. Валится Tx_ready от ядра и все встает(комп не зависает). По времени пересылает 125-130 пачек (TLP+8пакетов данных).
Может в ядре что-то сбрасывать надо периодически? Или в конфиге бит какой важный

update:
через BAR могу управлять dma_en своим сигналом, т.е. pcie устройство не отваливается, но запись более не происходит, т.к. tx_ready от ядра нет
upd2:
добавил после пачек не 1 такт нулевой а 3, и поток пишется, есть такие же застои иногда, но не сдыхает. По расчетам 1.3 ГБ поток, буду еще экспериментировать с размером посылок, но паузы мне эти не нравятся sm.gif На двух тактах работает несколько секунд и сдыхал.
AVR
Цитата(exigo @ Mar 7 2018, 06:54) *
добавил после пачек не 1 такт нулевой а 3, и поток пишется, есть такие же застои иногда, но не сдыхает. По расчетам 1.3 ГБ поток, буду еще экспериментировать с размером посылок, но паузы мне эти не нравятся sm.gif На двух тактах работает несколько секунд и сдыхал.

Что если насыпать туда заведомо лошадиное количество пустых тактов? Что будет? И оставить на час - и понять, будут ли затыки, просадки.
Потом можно будет вернуть до 3-4 пустых.
exigo
Вернул на минимальную паузу в один такт между TLP, добавил в этот такт доп проверку tx_buf (количество свободных буферов ядра), не даю им опуститься ниже 8, если опускается то в отдельном состояние автомата ожидает, пока ядро переварит и продолжает запись. Добился 1.6 ГБ/с.
И еще, материнка определила max payload как 128, хотя в ядре 512, в биосе что-то не нарыл как изменить, так бы еще удалось разогнать
XVR
Цитата(exigo @ Mar 14 2018, 12:00) *
И еще, материнка определила max payload как 128, хотя в ядре 512, в биосе что-то не нарыл как изменить, так бы еще удалось разогнать
Max payload определяется по совокупности всего пути от вашего устройства до root complex. Если там есть хоть один с max payload в 128, то можете у себя хоть 10G поставить - всё равно будет не более 128 sm.gif
toshas
Цитата(exigo @ Mar 14 2018, 12:00) *
Вернул на минимальную паузу в один такт между TLP, добавил в этот такт доп проверку tx_buf (количество свободных буферов ядра), не даю им опуститься ниже 8, если опускается то в отдельном состояние автомата ожидает, пока ядро переварит и продолжает запись. Добился 1.6 ГБ/с.
И еще, материнка определила max payload как 128, хотя в ядре 512, в биосе что-то не нарыл как изменить, так бы еще удалось разогнать



1.6 Гбайт/с это и есть предел. Обычно можно брать за правду правило - 200 Мбайт/с на 1 lane 1 gen, т.е. x4 gen2 это и есть около 200*4*2 = 1600 Мбайт/с.
Вот XAPP1289 где гоняли данные ПЛИС-to-ПЛИС https://www.xilinx.com/support/documentatio...89-dma-pcie.pdf
exigo
Всем привет, благополучно юзал pcie. Но тут мне обновили ПК и на новом железе все перестало работать. Мой проект успешно позволяет записать управляющие адреса и размер буфера в БАР, но после включения ДМА устройство отваливается и в БАР 0xffffffffff все, или и того виснет комп.
Решил проверить на xilinx примерах дма стримера и дма передачи(от которых отталкивался и они работали на старом ПК), после загрузки в железо комп сразу зависает, даже драйвер не дает поставить.
Подскажите пожалуйста, в какую сторону копать?

В устройстве проблем нет, подключил к компу схожим на мой старый, все путем.
AVR
Цитата(exigo @ Aug 24 2018, 12:04) *
Всем привет, благополучно юзал pcie. Но тут мне обновили ПК и на новом железе все перестало работать. Мой проект успешно позволяет записать управляющие адреса и размер буфера в БАР, но после включения ДМА устройство отваливается и в БАР 0xffffffffff все, или и того виснет комп.
Решил проверить на xilinx примерах дма стримера и дма передачи(от которых отталкивался и они работали на старом ПК), после загрузки в железо комп сразу зависает, даже драйвер не дает поставить.
Подскажите пожалуйста, в какую сторону копать?

В устройстве проблем нет, подключил к компу схожим на мой старый, все путем.

Может в теме этот вопрос был отвечен, но я всю тему не помню. Поэтому спрошу - Вы кредиты смотрите? Ждете необходимого минимального значения кредитов прежде чем слать?
У меня была такая проблема - на новом быстром компе проблем не было, на старом висло, потому что не успевало выгребать из буферов. В любом случае, так называемые кредиты - очень важная деталь, и ее нужно обязательно проверять в процессе работы.

Выше увидел, вы опираетесь на tx_ready. Оно может дает возможность слать, если приемные буфера приемной стороны хоть немного свободны, только достаточно ли в них места? Так что просто на tx_ready я бы не полагался, хотя Xilinx PCI-E еще не нюхал, предстоит до НГ освоить PCI на Xilinx.
exigo
В последних версиях еще отслеживаю кредиты (tx_buf)
Но дело в том, что комп быстрее стал, и раньше когда не хватало кредитов он не зависал.
И интересно, что xilinx примеры не запускаются.
exigo
В чипскоп завел проект, tx_buf заканчиваются и встает автомат в ожидание, но самое, что все команды на запись, что идут в ПК, по адресам ноль. Вот не как не пойму на что может повлиять другой комп и материнка. RID какой выставляется?

Самое интересное, что пробники pcie в VIVADO даже не дают зашить прошивку, на 99% комп колом встает, и только хард ресет спасает. А на старом ПК все шикарно работает.

Попробав разные машины, вывод что безупречно работает в портах pcie 2gen, а в gen3 нет, но надо как-то это исправлять.
RobFPGA
Приветствую!
Цитата(exigo @ Sep 7 2018, 11:51) *
Самое интересное, что пробники pcie в VIVADO даже не дают зашить прошивку, на 99% комп колом встает, и только хард ресет спасает. А на старом ПК все шикарно работает.

Попробав разные машины, вывод что безупречно работает в портах pcie 2gen, а в gen3 нет, но надо как-то это исправлять.
Gen3 от Gen2 отличается другой более высокой внутренней частотой работы корки - соответственно в старой мамке Gen3 не включается и все работает пучком, а в новой при попытке переключится вешается из за проблем с времянкой. Усугубление проблем при добавлении пробников CрipScope может быть тому подтверждением.

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