Перейти к содержанию
    

BSACPLD

Свой
  • Постов

    906
  • Зарегистрирован

  • Посещение

  • Победитель дней

    5

Сообщения, опубликованные BSACPLD


  1. Насчёт синтеза в Synplify.

    Для того чтобы использовать отладчик, на интересующие сигналы нужно было добавить директиву /* synthesis PAP_MARK_DEBUG="true" */.

    В PDS_2022.2-SP4.2-CentOS7.3-x64 это работает, а в PDS_2023.2-SP1-CentOS7.3-x64 начинает выкидывать сигналы.

    В более новых версиях поменялись директивы для отладчика или это просто баг?

  2. 2 hours ago, makc said:

    А управлять с триггера, инициализированного единицей в прошивке (начальное значение после конфигурации), не получается? Если так, то непонятно чем инициализация инвертора и его коммутации отличается от инициализации начального состояния триггера, это ведь по сути одна и та же SRAM. Или вы так не пробовали?

    Не пробовал, т.к. в Synplify с начальной инициализацией всегда были приколы.

    На мой взгляд с инвертором более предсказуемый вариант с точки зрения синтеза в Synplify.

    2 hours ago, makc said:

    У вас инженерные образцы Logos2 в 324 корпусе? Если да, то у них ещё была проблема с ресетом (точнее, установкой в '1' по ресету) триггеров в ячейках ВВ: единица не появлялась, только ноль. Если запретить размещение триггера в ячейке, то всё работает штатно.

    324

    Вроде уже серийные должны быть...

  3. 1 hour ago, makc said:

    Я думаю, что это скорее сигнал управления внутренним мультиплексором тактового сигнала конфигурационной флешки. Поэтому слабая подтяжка не повредит, но и не поможет в вашем случае.

    Походу нужен.

    CFG_CLK.thumb.png.9a0260d7a9c2ac2d21a198f50feebc04.png

    Для Xilinx данный резистор не требуется.

    Получается, что Logos2 в версии без трансиверов хоть и pin-to-pin, но по схемотехнике немного отличается.

    1 hour ago, makc said:

    Думается, что эту логику нужно привязать к отдельному триггеру с известным начальным состоянием, равным единице. Что там творится с PLL в момент старта - одному Панго известно.

    Привязал к триггеру, который изначально в 0 (все триггеры у PangoMicro по включению питания 0), проинвертировал сигнал, а условие установки триггера поставил на первое обращение к регистру адреса контроллера QSPI.

    Заработало.

    Костыли, костыли, костыли...

  4. 24 minutes ago, makc said:

    Попробуйте подать на вход CE_N GTP_CFGCLK не ноль, как у вас, а единицу.

    Идея проста: вам нужно включить управление выходом тактирования только после успешного завершения конфигурирования. А вы, возможно, его гробите где-то на раннем этапе.

    Если CE_N это tristate, тогда ещё и внешний pull-up на qspi_sck придётся добавить.

    В принципе не страшно - можно 0805 припаять между 6 и 8 выводом FLASH.

    Благо она у меня в SOIC и сделать это совсем несложно.

    UPD.

    Если чисто 1 подать, то грузится.

    А вот если от логики, то не грузится.

    Пробовал ~locked от PLL подавать.

  5. Кажется я нашёл проблемное место...

    Если убрать из проекта доступ к 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.

  6. 35 minutes ago, makc said:

    Как будто бы в его конце нет команд, аналогичных START+DESYNC у Xilinx.

    Как всё однако интересно...

    Чтобы долго не ждать сборки проекта сделал простейший проект со светодиодом - успешный старт из FLASH.

  7. 4 hours ago, makc said:

    Может всё-таки идёт попытка конфигурации в режиме Quad, но флешка к этому не готова (нет QE)?

    Пока не смотрел, но успел сделать другую проверку.

    Зашил FLASH, выключил/включил питание, подцепился по JTAG и сделал верификацию загруженного в RAM битстрима - Verify OK.

    И после окончания верификации прошивка внезапно стартовала.

    Т.е. походу битстрим попадает в RAM, но почему-то не стартует.

    Как будто ждёт какую-то команду на старт...

  8. Коллеги, подскажите, пожалуйста, как правильно сформировать файл для прошивки 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.

  9. В итоге получилось вот в таком виде:

    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.

  10. 35 minutes ago, makc said:

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

    PG2L50H-6IMBG324

    P.S.

    Уже нашёл в чём дело было.

    FIFO_RST делался из многомерного массива и был указан индекс за границей массива.

    Vivado и Quartus туда 0 подставляли и получался "рабочий" код, а PDS синтезировал какую-то ерунду.

    Заметил уже когда все возможные варианты перебрал...

    P.P.S.

    Теперь осталось тайминги на входе SERDES победить...

  11. Я разобрался где проблема.

    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 входовое ИЛИ.

  12. Коллеги, как заставить 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 выкидывает триггер.

  13. Добрый день, коллеги!

    Мне наконец пришли платы на PangoMicro.

    Сейчас пытаюсь разобраться какие примитивы на что подменять при переводе проекта с Xilinx.

    Возник ряд вопросов, подскажите, пожалуйста, кто в курсе.

    1. IBUFDS подменяем на GTP_INBUFDS?

    2. BUFR для того чтобы сделать байтовый клок из битового клока SERDES подменяем на GTP_IOCLKDIV_E2?

    3. BUFIO для SERDES подменяем на ????? Может я невнимательно смотрел, но не нашёл аналога данного примитива...

    Я сейчас пытаюсь переписать следующий кусок кода на Logos2:

    IBUFDS				#(
    					.DIFF_TERM             (DIFF_TERM),
    					.IBUF_LOW_PWR          ("FALSE"),
    					.IOSTANDARD            (IOSTANDARD)
    					)
    					
    					cam_ck_ibufds (
    					.I                     (cam_ck_p),
    					.IB                    (cam_ck_n),
    					.O                     (cam_ck_)
    					) ;
    
    
    BUFIO				cam_ck_bufio (
    					.I                     (cam_ck_),		// 1-bit input: Clock input (connect to an IBUF or BUFMR).
    					.O                     (cam_ck_hs)		// 1-bit output: Clock output (connect to I/O clock loads).
    					) ;
    
    
    BUFR				#(
    					.BUFR_DIVIDE           ("2"),			// Values: "BYPASS, 1, 2, 3, 4, 5, 6, 7, 8" 
    					.SIM_DEVICE            ("7SERIES")		// Must be set to "7SERIES" 
    					)
    					
    					cam_ck_bufr (
    					.I                     (cam_ck_),		// 1-bit input: Clock buffer input driven by an IBUF, MMCM or local interconnect
    					.CLR                   (1'b0),			// 1-bit input: Active high, asynchronous clear (Divided modes only)
    					.CE                    (1'b1),			// 1-bit input: Active high, clock enable (Divided modes only)
    					.O                     (cam_ck)			// 1-bit output: Clock output port
    					) ;

    Пока не до конца получается подобрать замену для примитивов Xilinx:

    GTP_INBUFDS			#(
    					.TERM_DIFF             (DIFF_TERM),
    					.IOSTANDARD            (IOSTANDARD)
    					)
    					
    					cam_ck_ibufds (
    					.I                     (cam_ck_p),
    					.IB                    (cam_ck_n),
    					.O                     (cam_ck_)
    					) ;
    
    // ??????????????????????????????????
    BUFIO				cam_ck_bufio (
    					.I                     (cam_ck_),		// 1-bit input: Clock input (connect to an IBUF or BUFMR).
    					.O                     (cam_ck_hs)		// 1-bit output: Clock output (connect to I/O clock loads).
    					) ;
    
    
    GTP_IOCLKDIV_E2		#(
    					.DIV_FACTOR            ("2")			// Values: "BYPASS, 1, 2, 3, 4, 5, 6, 7, 8" 
    					)
    					
    					cam_ck_bufr (
    					.CLKIN                 (cam_ck_),		// 1-bit input: Clock buffer input driven by an IBUF, MMCM or local interconnect
    					.RST_N                 (1'b0),			// 1-bit input: Active high, asynchronous clear (Divided modes only)
    					.CE                    (1'b1),			// 1-bit input: Active high, clock enable (Divided modes only)
    					.CLKDIVOUT             (cam_ck)			// 1-bit output: Clock output port
    					) ;

    4. IDELAYE2 подменяем на GTP_IODELAY_E2?

    5. ISERDESE2 подменяем на GTP_ISERDES_E2?

  14. 2 hours ago, Ivanii said:

    И даже если у вас "все работает" это не значит что вся сеть работает ШТАТНО и сети это не вредит. Для своего эксперимента в "своей" изолированной сети(или VLAN) можно творить любую дичь, для чужих сетей лучше придерживаться стандартов.

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

  15. 4 hours ago, fguy said:

    Проход пакетов от одного девайса до другого по такой сетке обеспечивает админ, а не навороченность (в плане поддержки кучи протоколов) ядра в плис. Мне реализации обычного udp c возможностью выставить нужные МАС, IP адрес и порт всегда хватало что бы пакеты дошли хоть по радиомостам, хоть по много-км территории предприятия с хз какой структурой сети.

    И все админы, с которыми мне приходилось сталкиваться, использовали именно ping для проверки работы сети 🙂

  16. 6 hours ago, Arlleex said:

    ICMP не обязательно.

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

    В случае чего, как связь с железкой проверять будете?

    У меня вот один раз очень интересный случай был.

    Железка это камера со встроенным маршрутизатором на ПЛИС.

    Связь с железкой по своему протоколу есть.

    Пинги на железку и комп подключенный к общей сети через железку проходят, а интернета на компе нет.

    Что в результате оказалось - битый кабель.

    На коротких пакетах всё ОК, на длинных пакетах данные бились так, что выставлялся RX_ERR на выходе PHY.

    Выяснил экспериментально меняя длину ICMP запроса.

    Поменял кабель и всё заработало.

  17. 2 hours ago, Aleksey25 said:

    Да, хочу попробовать именно HW.

    Чисто HW это лишнее усложнение и трата ресурсов.

    Вам как минимум нужно: ARP, ICMP, UDP.

    Я когда свою видеокамеру делал, реализовал комбинированный вариант - фильтр MAC HW, маршрутизация UDP HW, всё что прошло фильтр, но не прошло в UDP HW обрабатывалось на встроенном софт-процессоре RISC-V (PicoRV32).

    И то даже в таком комбинированном виде это занимало довольно прилично как Slice, так и BRAM.

    Чисто HW это монстр будет с точки зрения потребления ресурсов.

    Не говоря уже про сложности с отладкой.

  18. 2 hours ago, korotaev said:

    Не обижайте таких специалистов. Специфичность в общении - защита от халявщиков и менагеров, которых развелось немерянно.

    Так я и не обижаю, ибо сам такой, 5 в 1, схемотехник, тополог, программист ПЛИС и МК, программист C/C++, паяю платы не хуже хорошего монтажника, своя лаборатория, свой инструмент - заменяю собой целый отдел по разработке электроники.

    И я сам понимаю, что специфичен в общении - ненавижу тупых манагеров и всячески их троллю, когда начинают мешать делать мою работу. И "мордой об стол" люблю провезти некомпетентных неучей, когда они начинают что-то из себя строить 🙂 А уж любителей считать жопочасы вместо реальной работы просто напросто шлю открытым текстом 🙂

×
×
  • Создать...