![](https://electronix.ru/forum/uploads/set_resources_23/84c1e40ea0e759e3f1505eb1788ddf3c_pattern.png)
![](https://electronix.ru/forum/uploads/set_resources_23/84c1e40ea0e759e3f1505eb1788ddf3c_default_photo.png)
BSACPLD
Свой-
Постов
912 -
Зарегистрирован
-
Посещение
-
Победитель дней
5
Весь контент BSACPLD
-
-
Как, например, насчёт MAX V (у которого нет регистров в IOB)? Так у Cyclone II, IV E тоже нет входных DDR регистров. Но есть статическая задержка. И метод с задержкой там прекрасно работал на 125 МГц, только я задерживал клок, а не данные. Хотя в случае MAX V и входной задержки нет.
-
Не совсем согласен. Метод с входной задержкой был успешно применён на Altera (Cyclone II, IV E, Stratix III), Xilinx (Artix-7, Kintex-7), Lattice (ECP5), Fudan (JFMK50T4) и PangoMicro (Logos2). Единственное, где не прокатило, это Gowin, но там всё уперлось в максимальную частоту проекта (больше 80МГц не удалось вытянуть), а не в задержки. При этом единственное различие, это примитивы и конкретные значения задержки. Я просто оборачивал все примитивы во враппер - см. MAC что я выкладывал в этой теме. А с PLL могут быть проблемы, т.к. при изменении скорости падает частота клока - не факт, что PLL будет корректно работать на частоте отличной от указанной при генерации IP блока. На 2.5МГц точно не будет работать, но с другой стороны кто сейчас применяет 10 Мбит/с?...
-
Вот ещё MDIO до кучи. P.S. Для MAC я обычно ставил IDELAY_VALUE = 10. На Artix-7 этого было достаточно чтобы setup был порядка -1.0 нс. Констрейны при этом были: create_clock -period 7.200 -name {RXC_VIRTUAL} create_clock -period 7.200 -name {RXC} [get_ports {eth_rxc}] set_false_path -rise_from [get_clocks {RXC_VIRTUAL}] -rise_to [get_clocks {RXC}] set_false_path -fall_from [get_clocks {RXC_VIRTUAL}] -fall_to [get_clocks {RXC}] set_input_delay -clock [get_clocks {RXC_VIRTUAL}] -max 0.500 [get_ports {eth_rx_ctl}] set_input_delay -clock [get_clocks {RXC_VIRTUAL}] -min -0.500 [get_ports {eth_rx_ctl}] set_input_delay -clock [get_clocks {RXC_VIRTUAL}] -clock_fall -max -add_delay 0.500 [get_ports {eth_rx_ctl}] set_input_delay -clock [get_clocks {RXC_VIRTUAL}] -clock_fall -min -add_delay -0.500 [get_ports {eth_rx_ctl}] set_input_delay -clock [get_clocks {RXC_VIRTUAL}] -max 0.500 [get_ports {eth_rd[0]}] set_input_delay -clock [get_clocks {RXC_VIRTUAL}] -min -0.500 [get_ports {eth_rd[0]}] set_input_delay -clock [get_clocks {RXC_VIRTUAL}] -clock_fall -max -add_delay 0.500 [get_ports {eth_rd[0]}] set_input_delay -clock [get_clocks {RXC_VIRTUAL}] -clock_fall -min -add_delay -0.500 [get_ports {eth_rd[0]}] set_input_delay -clock [get_clocks {RXC_VIRTUAL}] -max 0.500 [get_ports {eth_rd[1]}] set_input_delay -clock [get_clocks {RXC_VIRTUAL}] -min -0.500 [get_ports {eth_rd[1]}] set_input_delay -clock [get_clocks {RXC_VIRTUAL}] -clock_fall -max -add_delay 0.500 [get_ports {eth_rd[1]}] set_input_delay -clock [get_clocks {RXC_VIRTUAL}] -clock_fall -min -add_delay -0.500 [get_ports {eth_rd[1]}] set_input_delay -clock [get_clocks {RXC_VIRTUAL}] -max 0.500 [get_ports {eth_rd[2]}] set_input_delay -clock [get_clocks {RXC_VIRTUAL}] -min -0.500 [get_ports {eth_rd[2]}] set_input_delay -clock [get_clocks {RXC_VIRTUAL}] -clock_fall -max -add_delay 0.500 [get_ports {eth_rd[2]}] set_input_delay -clock [get_clocks {RXC_VIRTUAL}] -clock_fall -min -add_delay -0.500 [get_ports {eth_rd[2]}] set_input_delay -clock [get_clocks {RXC_VIRTUAL}] -max 0.500 [get_ports {eth_rd[3]}] set_input_delay -clock [get_clocks {RXC_VIRTUAL}] -min -0.500 [get_ports {eth_rd[3]}] set_input_delay -clock [get_clocks {RXC_VIRTUAL}] -clock_fall -max -add_delay 0.500 [get_ports {eth_rd[3]}] set_input_delay -clock [get_clocks {RXC_VIRTUAL}] -clock_fall -min -add_delay -0.500 [get_ports {eth_rd[3]}] 7.2 нс это период клока от PHY с учётом возможного гуляния фронтов при восстановлении клока - ставим самый худший случай. eth_mdio.7z
-
Я использовал AXI, AXI-Stream и I2C. Ethernet и PCIe мне показали немного "недоделанными", поэтому писал сам, точнее у меня уже была своя реализация под RGMII. Собственно вот моя кроссплатформенная реализация MAC для RGMII. eth_mac_rgmii.7z lib.7z
-
Статические, расчетные. Я уже разобрался. Надо было делать клок с помощью GTP_INBUFGDS вместо GTP_INBUFDS. После этого все тайминги сошлись.
-
Ведущий инженер, ООО "ГЛОСАВ", Москва
BSACPLD ответил BSACPLD тема в Предлагаю работу
UP. Всё ещё актуально. -
Насчёт синтеза в Synplify. Для того чтобы использовать отладчик, на интересующие сигналы нужно было добавить директиву /* synthesis PAP_MARK_DEBUG="true" */. В PDS_2022.2-SP4.2-CentOS7.3-x64 это работает, а в PDS_2023.2-SP1-CentOS7.3-x64 начинает выкидывать сигналы. В более новых версиях поменялись директивы для отладчика или это просто баг?
-
Т.е. то что сейчас предлагают поставщики со складов, это опытные образцы?
-
Не пробовал, т.к. в Synplify с начальной инициализацией всегда были приколы. На мой взгляд с инвертором более предсказуемый вариант с точки зрения синтеза в Synplify. 324 Вроде уже серийные должны быть...
-
Походу нужен. Для Xilinx данный резистор не требуется. Получается, что Logos2 в версии без трансиверов хоть и pin-to-pin, но по схемотехнике немного отличается. Привязал к триггеру, который изначально в 0 (все триггеры у PangoMicro по включению питания 0), проинвертировал сигнал, а условие установки триггера поставил на первое обращение к регистру адреса контроллера QSPI. Заработало. Костыли, костыли, костыли...
-
Если CE_N это tristate, тогда ещё и внешний pull-up на qspi_sck придётся добавить. В принципе не страшно - можно 0805 припаять между 6 и 8 выводом FLASH. Благо она у меня в SOIC и сделать это совсем несложно. UPD. Если чисто 1 подать, то грузится. А вот если от логики, то не грузится. Пробовал ~locked от PLL подавать.
-
Вот у меня тот же вопрос...
-
Кажется я нашёл проблемное место... Если убрать из проекта доступ к FLASH, то проект успешно грузится из FLASH. generate if (FPGA_VENDOR == "PANGO") begin GTP_CFGCLK GTP_CFGCLK_inst ( .CE_N (1'b0), .CLKIN (qspi_sck_) ) ; end // if (FPGA_VENDOR == "PANGO") else if (FPGA_VENDOR == "XILINX") begin STARTUPE2 #( .PROG_USR ("FALSE"), // Activate program event security feature. Requires encrypted bitstreams. .SIM_CCLK_FREQ (0.0) // Set the Configuration Clock Frequency(ns) for simulation. ) STARTUPE2_inst ( .CFGCLK (), // 1-bit output: Configuration main clock output .CFGMCLK (), // 1-bit output: Configuration internal oscillator clock output .EOS (), // 1-bit output: Active high output signal indicating the End Of Startup. .PREQ (), // 1-bit output: PROGRAM request to fabric output .CLK (1'b0), // 1-bit input: User start-up clock input .GSR (1'b0), // 1-bit input: Global Set/Reset input (GSR cannot be used for the port name) .GTS (1'b0), // 1-bit input: Global 3-state input (GTS cannot be used for the port name) .KEYCLEARB (1'b0), // 1-bit input: Clear AES Decrypter Key input from Battery-Backed RAM (BBRAM) .PACK (1'b1), // 1-bit input: PROGRAM acknowledge input .USRCCLKO (qspi_sck_), // 1-bit input: User CCLK input // For Zynq-7000 devices, this input must be tied to GND .USRCCLKTS (1'b0), // 1-bit input: User CCLK 3-state enable input // For Zynq-7000 devices, this input must be tied to VCC .USRDONEO (1'b1), // 1-bit input: User DONE pin output control .USRDONETS (1'b1) // 1-bit input: User DONE 3-state enable output ) ; end // if (FPGA_VENDOR == "XILINX") endgenerate Если добавить, то перестаёт грузиться из FLASH.
-
Самая низкая стоит - 2.99M. Пробовал варианты 2.99, 11.76, 25.
-
Как всё однако интересно... Чтобы долго не ждать сборки проекта сделал простейший проект со светодиодом - успешный старт из FLASH.
-
Пока не смотрел, но успел сделать другую проверку. Зашил FLASH, выключил/включил питание, подцепился по JTAG и сделал верификацию загруженного в RAM битстрима - Verify OK. И после окончания верификации прошивка внезапно стартовала. Т.е. походу битстрим попадает в RAM, но почему-то не стартует. Как будто ждёт какую-то команду на старт...
-
Пробовал поменять Micron на Winbond - не помогло 😞
-
Коллеги, подскажите, пожалуйста, как правильно сформировать файл для прошивки FLASH для PG2L50H-6IMBG324. FLASH Micron MT25QL128ABA1ESE-0SIT. Режим x1. Знаю, что лучше было ставить рекомендованную W25Q128, но тут вышла путаница на производстве - Winbond запаяли на платы с Xilinx, а Micron на платы с PangoMicro... При создании файла в меню Operations->Convert File я выбрал FLASH с точно таким же ID - N25Q128. Прошивка и верификация без ошибок, но ПЛИС не хочет загружаться из FLASH. По JTAG ПЛИС грузится и стартует нормально. Пробовал даже своей прошивкой вычитывать FLASH - совпадает с исходным файлом. Посмотрел осциллографом. В начале загрузки падает CS, идёт битовый поток порядка 150 мс, потом CS не поднимается и светодиод CFG_DONE не загорается, CS так и висит в 0. Схема рабочая, т.к. точно такая же плата, где был запаян Xilinx, грузится без проблем, а PG2L50H-6IMBG324 и XC7A100T-2CSG324I pin-to-pin.
-
В итоге получилось вот в таком виде: else if (FPGA_VENDOR == "PANGO") begin GTP_INBUFDS #( .TERM_DIFF (DIFF_TERM), .IOSTANDARD (IOSTANDARD) ) cam_ck_ibufds ( .I (cam_ck_p), .IB (cam_ck_n), .O (cam_ck_hs) ) ; GTP_IOCLKDIV_E2 #( .DIV_FACTOR ("2") // Values: "BYPASS, 1, 2, 3, 4, 5, 6, 7, 8" ) cam_ck_bufr ( .CLKIN (cam_ck_hs), .RST_N (1'b1), .CE (1'b1), .CLKDIVOUT (cam_ck) ) ; for (i=0 ; i<NUM_LVDS ; i=i+1) begin:loop_cam_d GTP_INBUFDS #( .TERM_DIFF (DIFF_TERM), .IOSTANDARD (IOSTANDARD) ) cam_d_ibufds ( .I (cam_d_p[i]), .IB (cam_d_n[i]), .O (cam_d[i]) ) ; GTP_IODELAY_E2 #( .DELAY_STEP_VALUE (IDELAY_VALUE), .DELAY_STEP_SEL ("PARAMETER"), .TDELAY_EN ("FALSE") ) cam_d_idelaye2 ( .DELAY_SEL (1'b1), // INPUT .DELAY_STEP (8'd0), // INPUT[7:0] .EN_N (1'b0), // INPUT .DI (cam_d[i]), // INPUT .DO (cam_d_[i]) // OUTPUT ) ; GTP_ISERDES_E2 #( .ISERDES_MODE ("DDR1TO4"), .CASCADE_MODE ("MASTER"), .BITSLIP_EN ("FALSE"), .GRS_EN ("TRUE"), .NUM_ICE (1'b0), .GRS_TYPE_Q0 ("RESET"), .GRS_TYPE_Q1 ("RESET"), .GRS_TYPE_Q2 ("RESET"), .GRS_TYPE_Q3 ("RESET"), .LRS_TYPE_Q0 ("ASYNC_RESET"), .LRS_TYPE_Q1 ("ASYNC_RESET"), .LRS_TYPE_Q2 ("ASYNC_RESET"), .LRS_TYPE_Q3 ("ASYNC_RESET") ) cam_d_iserdese2 ( .RST (reset), .ICE0 (1'b1), .ICE1 (1'b1), .DESCLK (1'b0), .ICLK (cam_ck_hs), .ICLKB (~cam_ck_hs), .OCLK (1'b0), .ICLKDIV (cam_ck), .DI (cam_d_[i]), .BITSLIP (1'b0), .ISHIFTIN0 (1'b0), .ISHIFTIN1 (1'b0), .DO (cam_d_des_[i]), .ISHIFTOUT0 (), .ISHIFTOUT1 () ) ; always @(posedge cam_ck) begin cam_d_des[i] <= ((INV_LVDS >> i) & 1)? ~cam_d_des_[i] : cam_d_des_[i] ; end end // for (i=0 ; i<NUM_LVDS ; i=i+1) begin:loop_cam_d end // if (FPGA_VENDOR == "PANGO") Проект собирается, но никак не получается правильно прописать тайминги для данного SERDES. Пробовал как в Vivado: set_false_path -rise_from [get_clocks {CAM_CK_VIRTUAL}] -rise_to [get_clocks {CAM_CK}] set_false_path -fall_from [get_clocks {CAM_CK_VIRTUAL}] -fall_to [get_clocks {CAM_CK}] set_input_delay -clock [get_clocks {CAM_CK_VIRTUAL}] -max 0.500 [get_ports {lvds_io_p[0]}] set_input_delay -clock [get_clocks {CAM_CK_VIRTUAL}] -min -0.500 [get_ports {lvds_io_p[0]}] set_input_delay -clock [get_clocks {CAM_CK_VIRTUAL}] -clock_fall -max -add_delay 0.500 [get_ports {lvds_io_p[0]}] set_input_delay -clock [get_clocks {CAM_CK_VIRTUAL}] -clock_fall -min -add_delay -0.500 [get_ports {lvds_io_p[0]}] set_input_delay -clock [get_clocks {CAM_CK_VIRTUAL}] -max 0.500 [get_ports {lvds_io_p[1]}] set_input_delay -clock [get_clocks {CAM_CK_VIRTUAL}] -min -0.500 [get_ports {lvds_io_p[1]}] set_input_delay -clock [get_clocks {CAM_CK_VIRTUAL}] -clock_fall -max -add_delay 0.500 [get_ports {lvds_io_p[1]}] set_input_delay -clock [get_clocks {CAM_CK_VIRTUAL}] -clock_fall -min -add_delay -0.500 [get_ports {lvds_io_p[1]}] set_input_delay -clock [get_clocks {CAM_CK_VIRTUAL}] -max 0.500 [get_ports {lvds_io_p[2]}] set_input_delay -clock [get_clocks {CAM_CK_VIRTUAL}] -min -0.500 [get_ports {lvds_io_p[2]}] set_input_delay -clock [get_clocks {CAM_CK_VIRTUAL}] -clock_fall -max -add_delay 0.500 [get_ports {lvds_io_p[2]}] set_input_delay -clock [get_clocks {CAM_CK_VIRTUAL}] -clock_fall -min -add_delay -0.500 [get_ports {lvds_io_p[2]}] set_input_delay -clock [get_clocks {CAM_CK_VIRTUAL}] -max 0.500 [get_ports {lvds_io_p[3]}] set_input_delay -clock [get_clocks {CAM_CK_VIRTUAL}] -min -0.500 [get_ports {lvds_io_p[3]}] set_input_delay -clock [get_clocks {CAM_CK_VIRTUAL}] -clock_fall -max -add_delay 0.500 [get_ports {lvds_io_p[3]}] set_input_delay -clock [get_clocks {CAM_CK_VIRTUAL}] -clock_fall -min -add_delay -0.500 [get_ports {lvds_io_p[3]}] Но в итоге для lvds_io_p[1] тайминги сходятся, а для lvds_io_p[0], lvds_io_p[2], lvds_io_p[3] вылезает slack по hold почти -1.24 ns.
-
PG2L50H-6IMBG324 P.S. Уже нашёл в чём дело было. FIFO_RST делался из многомерного массива и был указан индекс за границей массива. Vivado и Quartus туда 0 подставляли и получался "рабочий" код, а PDS синтезировал какую-то ерунду. Заметил уже когда все возможные варианты перебрал... P.P.S. Теперь осталось тайминги на входе SERDES победить...
-
Я разобрался где проблема. PDS неправильно синтезирует сигнал сброса. Сделал следующий тест выведя сигналы на светодиоды: assign u_debug_led[0] = (axil_aresetn == 1'b0) | UART_RST | FIFO_RST ; assign u_debug_led[1] = (axil_aresetn == 1'b0) ; assign u_debug_led[2] = UART_RST ; assign u_debug_led[3] = FIFO_RST ; В итоге u_debug_led[3], u_debug_led[2], u_debug_led[1] показывают 0, а u_debug_led[0] показывает 1. PDS неправильно синтезирует 3 входовое ИЛИ.
-
Коллеги, как заставить PDS2023.2.SP1 не оптимизировать следующий кусок кода? always @(posedge wrclk) begin if (~reset_n_wrclk[1]) init_done_wrclk <= 1'b0 ; else init_done_wrclk <= 1'b1 ; end Должна быть задержка на 1 такт после снятия сброса, а PDS выкидывает триггер.
-
Можете положить в закрома?