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

Roberto_Tolas

Участник
  • Публикаций

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

  • Посещение

Репутация

0 Обычный

Информация о Roberto_Tolas

  • Звание
    Участник
  1. Благодарю пользователя BackEnd за развернутый ответ. Сейчас борюсь с временными констрейнами для гигабитного Ethernet. Очень уж они "жесткие" получаются. Создал маленький проект, в котором используются только сигналы RxD, TxD, RxCLK, TxCLK с PHY микросхемы. В качестве эксперимента завернул данные с приема на передачу через внутренние сигналы. Примерно так: КодIBUFG_000: IBUFG port map (O => eth_rx_clk, I => rx_clk); rx_proc : process(eth_rx_clk) begin     if (rising_edge(eth_rx_clk)) then         data <= rx_data_delayed;     end if; end process; BUFG_000: BUFG port map(I => eth_rx_clk, O => eth_tx_clk); tx_proc : process(eth_tx_clk) begin     if (rising_edge(eth_tx_clk)) then         tx_data <= data;     end if; end process; tx_clk <= eth_tx_clk; Задал следующие констрейны: КодNET "rx_clk" TNM_NET = "rx_clk"; TIMESPEC "TS_rx_clk" = PERIOD "rx_clk" 7500 ps HIGH 50 %; OFFSET = IN  2500 ps VALID 3000 ps BEFORE "rx_clk"; В таком виде избежать проблем с констрейнами не удалось. Но, используя IODELAY2 на сигналы RxD удалось удовлетворить констрейнам. Но в основном проекте уже так не прокатило, так как там проект большой, задержки больше и уже не удалось найти такой параметр IDELAY_VALUE чтобы все констрейны были удовлетворены. Вопросы, которые у меня появились в процессе этих манипуляций: 1) Что можно еще предпринять для удовлетворения констрейнам? 2) Когда создавал маленький проект, сначала в ucf файле указал только констрейны, без Location для выводов. Он раскидал все выводы так, как считает нужным. И, в принципе, проект удовлетворил констрейнам даже без IODELAY2. Может быть тогда следует сначала писать проект для FPGA, задавая все констрейны, потом смотреть куда ISE раскидает выводы и потом разводить плату?
  2. Цитата(Timmy @ Jan 29 2015, 12:45) Разброс между выходным клоком и данными в ISE нельзя по-нормальному обконстрейнить. В данном случае можно объединить в группу сигналы GTX_CLK, TDX*, и задать для неё пустой(Analize only) OFFSET OUT с REFERENCE_PIN "GTX_CLK". Всё это делается, при желании, с помощью визарда. Тогда в отчёте будет максимальный разброс между данными и клоком, и можно глазами проверить, что он маленький. Если при этом восходящий фронт клока выровнен по середине данных(в этом можно убедиться в симуляции, или просто анализом дизайна), то всё в порядке. Для RXD* можно задать OFFSET 2.5 ns VALID 3ns в соответствии с другим рисунком из даташита(если не учитывать PCB skew). Для этого тоже подойдёт визард, он ещё соотвествующую картинку показывает. Скажите, пожалуйста, а нельзя ли задать в моем случае констрейны для выходных сигналов TXD используя входную тактовую RX_CLK? Напоминаю код: КодRX_CLKG <= RX_CLK; TX_CLKG <= RX_CLK;
  3. Итак, пока я переписываю проект и упрощаю его чтобы легче было искать ошибки, у меня возникают общие вопросы. 1) Получается, что все тактовые сигналы, которые идут из вне на ПЛИС и синхронизируют логику процессов обмена данными должны быть заведены на GCLK пины ПЛИС. А в проекте на VHDL они должны приниматься во внутренний сигнал через IBUFG. Дополнительно должны быть обконстрейнены данные на выход и на вход (с помощью OFFSET IN и OFFSET OUT), которые зависят от этих тактовых. Возникает следующий вопрос: "Как быть, если входных тактовых слишком много, ведь ресурсы ПЛИС ограничены в плане глобальных тактовых буферов?" 2) ЦитатаК тактовым всегда нужно относиться правильно. Про кустарные делители частоты в промышленных решениях забудьте сразу, для этого есть DCM и PLL. ЦитатаМожно попробовать работать через clock enable, если экономите PLL У меня стоит задача разделить частоту 32.768 МГц на 16 и получить частоту 2.048 МГц. Чем же плох делитель частоты с помощью счетчика? Попробовал поработать через clock enable и переписал код вот так: КодIBUFG_001: IBUFG port map (O => tclk, I => clk_32768); clock_enable_32768KHz : process (tclk) is         variable cnt : integer range 0 to 7; begin     if (rising_edge(tclk)) then         if (rstn = '0') then                     cnt := 0;             CLKOUT_E1_EN <= '0';         else             if cnt=7 then                 CLKOUT_E1_EN <= '1';                 cnt:=0;             else                 CLKOUT_E1_EN <= '0';                 cnt:=cnt + 1;             end if;         end if;             end if; end process; out_2048KHz : process (tclk) is begin    if (rising_edge(tclk)) then       if (rstn = '0') then          CLKOUT_E1 <= '0';       else          if (CLKOUT_E1_EN = '1') then             CLKOUT_E1 <= not CLKOUT_E1;          end if;       end if;    end if; end process; Правда пока его не проверял, но я не понимаю разницы с делителем, реализованном на счетчике. Может тыкнете меня носом в информацию где можно понять в чем разница? 3) В п.1 я говорил про входные тактовые сигналы. А как быть с выходными тактовыми сигналами? В п.2 я как раз такой сигнал формирую, он служит для синхронизации выходных данных. Нужно ли его как-то обконстрейнить? И, если данный сигнал участвует в процессах формирования и обработки выходных данных, то нужно ли его вешать на глобальный тактовый буфер: КодBUFG_002: BUFG port map(I => CLKOUT_E1, O => e1_tx_clk);?
  4. Изменил констрейн, добавил слово FALLING в конце, так как данные считываются по заднему фронту сигнала. Вроде прошел Place & Route быстренько.
  5. Цитата(andrew_b @ Aug 24 2016, 11:44) Ставить BUFG на сигналы, которые идут только на выход, смысла нет. Вам надо триггеры CLKOUT_E1 расположить в IOB. Сделал вот так: Кодe1t1_mclk0 <= CLKOUT_E1; e1t1_tclk0 <= CLKOUT_E1; В параметрах Map процесса стоит Pack I/O Registers/Latches into IOBs: For Inputs and Outputs. Этого достаточно чтобы "триггеры CLKOUT_E1 расположить в IOB"? Или следует написать констрейн вида КодINST "CLKOUT_E1" IOB =TRUE; Я так понимаю что после сборки можно посмотреть лежат ли в IOB эти триггеры в FPGA Editor'e. Только вот я не нашел где... После добавления строки КодOFFSET = IN 122070 ps VALID 200 ns BEFORE "e1t1_rclk0"; процесс Place & Route стал очень долгим и выводится следующее сообщение: КодUnusually high hold time violation detected among 24 connections. The top 20 such instances are printed below. The    router will continue and try to fix it     e1t1_rpos0:I -> ethmac/e1_1_rx/TR_FLAG:A6 -165406     e1t1_rpos0:I -> ethmac/e1_1_rx/hdlc_bit_get.byte<6>:B6 -165117     e1t1_rpos0:I -> ethmac/e1_1_rx/hdlc_bit_get.byte<6>:D6 -165030     e1t1_rpos0:I -> ethmac/e1_1_rx/hdlc_bit_get.one_cnt<1>:D2 -165025     e1t1_rpos0:I -> ethmac/e1_1_rx/hdlc_bit_get.byte<6>:C6 -164960     e1t1_rpos0:I -> ethmac/e1_1_rx/hdlc_bit_get.byte<6>:A6 -164895     e1t1_rpos0:I -> ethmac/e1_1_rx/hdlc_bit_get.byte<2>:C6 -164845     ethmac/e1_1_rx/SIZE_TO_READ<10>:C -> ethmac/e1_1_rx/SIZE_TO_READ<10>:CE -164835     e1t1_rpos0:I -> ethmac/e1_1_rx/SIZE_TO_READ<10>:C4 -164835     e1t1_rpos0:I -> ethmac/e1_1_rx/hdlc_bit_get.byte<2>:D6 -164824     e1t1_rpos0:I -> ethmac/e1_1_rx/hdlc_bit_get.byte<7>:A6 -164818     e1t1_rpos0:I -> lut11048_1737:D1 -164809     ethmac/e1_1_rx/hdlc_bit_get.byte<6>:B -> ethmac/e1_1_rx/Mram_REC_DATA:DIA4 -164767     ethmac/e1_1_rx/hdlc_bit_get.byte<6>:D -> ethmac/e1_1_rx/Mram_REC_DATA:DIA6 -164745     e1t1_rpos0:I -> ethmac/e1_1_rx/hdlc_bit_get.byte<2>:A1 -164709     ethmac/e1_1_rx/hdlc_bit_get.byte<2>:AMUX -> ethmac/e1_1_rx/Mram_REC_DATA:DIA0 -164709     e1t1_rpos0:I -> ethmac/e1_1_rx/SYNC_LOCAL:A5 -164704     ethmac/e1_1_rx/hdlc_bit_get.byte<6>:C -> ethmac/e1_1_rx/Mram_REC_DATA:DIA5 -164663     ethmac/e1_1_rx/hdlc_bit_get.byte<2>:C -> ethmac/e1_1_rx/Mram_REC_DATA:DIA1 -164638     ethmac/e1_1_rx/hdlc_bit_get.byte<2>:AMUX -> ethmac/e1_1_rx/hdlc_bit_get.byte<2>:AX -164632 Из-за чего это может происходить?
  6. Цитата(Lutovid @ Aug 23 2016, 23:21) Судя по постановке вопроса я бы сделал вывод, что глобальная линия использована не была Для входной тактовой 32.768 МГц был определен тактовый буфер: КодIBUFG_002: IBUFG port map (O => tclk, I => clk_32768); Делю входную тактовую счетчиком: Кодdiv16_32768KHz : process (tclk, rstn) is     variable cnt : integer range 0 to 7; begin    if rstn = '0' then       cnt := 0;       CLKOUT_E1 <= '0';    else       if tclk'event and tclk='1' then          if cnt=7 then             CLKOUT_E1 <= not CLKOUT_E1;             cnt:=0;          else             cnt:=cnt +1;          end if;       end if;    end if; end process; Сейчас добавил еще строчки для выходных тактовых и входной тактовой принимаемых данных: КодOBUFG_000: BUFG port map (O => e1t1_mclk0, I => CLKOUT_E1); OBUFG_001: BUFG port map (O => e1t1_tclk0, I => CLKOUT_E1); IBUFG_003: IBUFG port map (O => e1t1_rclk0_local, I => e1t1_rclk0); Вот только все эти входы и выходы на ПЛИС подключены к обычным портам ввода/вывода (не GCLK). Это плохо?
  7. Цитата(Alex11 @ Aug 23 2016, 12:05) Для гигабитного интерейса обычно нужно не просто более 125 МГц, а ровно 125 МГц. Может быть в Марвелле есть возможность работать на другой частоте, не знаю, я с ним не работал. В любом случае будут вопросы с синхронизацией, или нестандартная частота передачи. Да, для Marvell нужна частота 125 МГц для работы на скорости 1 Гб/с, а частота 125 МГц или более нужна для МАС уровня, который обрабатывает данные с PHY.
  8. Цитата(BackEnd @ Aug 18 2016, 14:44) К тактовым всегда нужно относиться правильно. Про кустарные делители частоты в промышленных решениях забудьте сразу, для этого есть DCM и PLL. В стандартной xilinx'овской библиотеке я не нашел делителя тактовой на 16, а счетчик Вы говорите лучше не использовать. Неужели даже для деления на 16 входной тактовой нужно использовать целый блок PLL или DCM? И еще вопрос про тактовые: "Как быть с тактовыми, частота которых не очень высока, например тактовая на интерфейсе I2C?". Неужели даже для таких тактовых нужно использовать глобальные буфера (BUFG) и писать констрейны для них? Просто я Е1 причислял к интерфейсам с низкой тактовой, поэтому не задумывался об констрейнах на Е1. Цитата(BackEnd @ Aug 18 2016, 14:44) Работайте с привязками Я попытался обконстрейнить все, что связано с Е1: КодNET "clk_32768"       LOC = "C1" | IOSTANDARD = LVTTL; NET "clk_32768"       TNM_NET = "clk_32768"; TIMESPEC "TS_clk_32768" = PERIOD "clk_32768" 30517 ps HIGH 50.00%; NET "e1t1_rclk0"     TNM_NET = "e1t1_rclk0"; TIMESPEC "TS_e1t1_rclk0" = PERIOD "e1t1_rclk0" 488281 ps HIGH 50.00%; OFFSET = IN 122070 ps VALID 244100 ps BEFORE "e1t1_rclk0"; Это для тактовой 32.768 МГц и для входных данных. А как быть с передаваемыми данными, если тактовую для передаваемых данных вырабатываю я, из 32.768 МГц?
  9. Цитатаповедение похоже на проблемы с времянкой Проблемы с времянками имеются. Для гигабитного интерфейса МАС требуется входная тактовая 125 МГц или более. У меня основная тактовая идет от генератора на 48 МГц. С помощью блока PLL_BASE я формирую частоты 64 МГц (для периферии и процессора, которые выращены на этой ПЛИС) и 128 МГц для данного блока. Вот что после сборки мне говорит Timing Analizer про частоту 64 МГц: КодTiming constraint: TS_CLKOUT1 = PERIOD TIMEGRP "CLKOUT1" TS_clk / 1.33333333 HIGH 50%; For more information, see Period Analysis in the Timing Closure User Guide (UG612). 23378864 paths analyzed, 16675 endpoints analyzed, 63 failing endpoints 63 timing errors detected. (63 setup errors, 0 hold errors, 0 component switching limit errors) Minimum period is  17.606ns. Я так понимаю, что данная проблема возникает из-за того, что много блоков (процессор, SPI, пара UART, контроллер памяти) подключено к этой частоте. Есть ли какие-нибудь способы исправить данную ситуацию?
  10. Здравствуйте! Являюсь начинающим разработчиком на FPGA. Работаю с ПЛИС Xilinx Spartan 6. Среда разработки ISE 14.7. Стоит задача: переброс данных из МАС уровня Ethernet в Е1. Имеется ПЛИС Spartan6 xc6slx150t-2fgg900, PHY Marvell 88E1111, сконфигурированный на работу по оптическому каналу на скорости 1 Gbs, E1 микросхема ds21348, сконфигурированная с NRZE = 1 (не биполярные данные на RPOS и RNEG (TPOS, TNEG), а используются только ноги RPOS и TPOS). Обмен информацией по Е1 организован с помощью HDLC протокола. Алгоритм работы: 1) полностью принимается пакет с МАС уровня (в буфер), убирается флаг готовности приема данных с МАС уровня; 2) этот пакет передается по Е1 удаленному абоненту, в конце передачи выставляется флаг готовности приема данных с МАС уровня; 3) удаленный абонент, принимая данные по Е1 кладет, их в буфер для передачи в МАС уровень; 4) сразу после окончания приема по Е1 удаленный абонент выдает в МАС уровень принятый пакет. Используемом соединение: точка-точка, поэтому количество пакетов не очень большое и время между пакетами не превышает времени передачи одного пакета по Е1, следовательно буфер приема данных с МАС уровня не должен переполняться (пока писал, подумал что не плохо было бы все-таки поставить флаг попытки положить данные из МАС уровня в буфер во время передачи по Е1). Суть вопроса: так как я являюсь начинающим разработчиком на FPGA, я не могу понять почему у меня при разных попытках сборки при малых исправлениях кода (или даже если вовсе код не править) все ведет себя абсолютно непредсказуемо? Пример: собрал проект, загрузил на плату, смотрю в Wireshark пакеты, приходящие от другого устройства - они абсолютно битые, вовсе не похожи на то, что надо. Запускаю SmartXplorer, выбираю один из вариантов сборки, загружаю на плату, получаю пакеты с битым широковещательным МАС адресом (заместо FF:FF:FF:FF:FF:FF принимается FF:7F:FF:FF:FF:FF или FE:FF:FF:FF:FF:FF), выбираю какой-нибудь другой вариант сборки в результатах SmartXplorer, получаю боле-менее стабильный результат, но есть потери пакетов (каждые 5 секунд высылаю пакет, но, примерно каждые 50 секунд 1-3 пакета теряются). Части кода, связанные с HDLC и МАС тестировались отдельно, в том числе создавались testbanches. Может что-то в настройках проекта следует указывать или как-то задавать какие-то параметры и флаги портам? Может как-то надо более правильно относиться к тактовым? (Тактовую 2.048 МГц для Е1 получаю простым счетчиком из 32.768 МГц). В общем, хотелось бы получить какие либо рекомендации по разработке устройств на ПЛИС чтобы не получать непредсказуемого поведения)
  11. Здравствуйте! Имеется следующая задача: нужно организовать обмен данными между двумя устройствами, основанными на ПЛИС Spartan6. В качестве канала связи могут выступать разные интерфейсы, например, RS-485, RS-232 и т.п. Хотелось бы иметь один протокол передачи данных для всех интерфейсов, реализованный на ПЛИС, и обеспечивающий достоверную передачу данных с возможностью перезапросов и т.п. Первая проблема: не могу подобрать такой протокол, вроде V.42 или X.25 близки для решения данной задачи, но может быть есть что-то еще, попроще? Вторая проблема: нужна реализация данного протокола на ПЛИС чтобы можно было разгрузить программную часть, чтобы программно нужно было только "подсовывать" данные в протокол, а ПЛИС сама формировала бы пакеты и подтверждала их передачу и прием. Попадалась на глаза на OpenCores реализация протокола HDLC, но если я правильно понял, там есть только подсчет контрольной суммы и формирование пакета формата HDLC, а хотелось бы еще иметь функции перезапроса и подтверждения пакетов (REJ, SREJ). Может кто сталкивался с данной задачей и может что-нибудь посоветовать?
  12. Всем спасибо, благодаря Вашим подсказкам, получился вполне такой рабочий код: CODE state <= mfcs1; -- IOBUF_1 : IOBUF -- generic map ( DRIVE => 12, IOSTANDARD => "DEFAULT", SLEW => "SLOW") port map ( O => I0, -- Buffer output IO => mfmiso, -- Buffer inout port (connect directly to top-level port) I => spi_mosi_local, -- Buffer input T => not state -- 3-state enable input, high=input, low=output ); IOBUF_2 : IOBUF -- generic map ( DRIVE => 12, IOSTANDARD => "DEFAULT", SLEW => "SLOW") port map ( O => I1, -- Buffer output IO => mfmosi, -- Buffer inout port (connect directly to top-level port) I => spi_mosi_local, -- Buffer input T => state -- 3-state enable input, high=input, low=output ); MUXF7_L_1 : MUXF7_L port map ( LO => spi_miso_local, -- Output of MUX to local routing I0 => I0, -- Input (tie to MUXF6 LO out or LUT6 O6 pin) I1 => I1, -- Input (tie to MUXF6 LO out or LUT6 O6 pin) S => state -- Input select to MUX ); spimctrl1 : if CFG_SPIM_ENABLE = 1 generate spi_mctrl1 : spictrl generic map (pindex => CFG_SPIM_PINDEX, paddr => CFG_SPIM_PADDR, pirq => CFG_SPIM_PIRQ, fdepth => 1, slvselen => 0, slvselsz => 1) port map (rstn, clkm, apbi2, apbo2(CFG_SPIM_PINDEX), spii, spio, open); sckpad : iopad generic map (tech => padtech) port map (mfscl, spio.sck, spio.sckoen, spii.sck); end generate; spii.miso <= spi_miso_local; spi_mosi_local <= spio.mosi;
  13. Цитата(Lerk @ Feb 13 2015, 11:24) А чем собственно обусловлена такая задача? Может проще перепаять пару проводов на макетке, а не городить огород в плисине? Если устройство пойдет в серию, то это на каждом придется проводки накидывать, легче тогда уж плату переразвести. Это не желательно, если есть возможность решить данную проблему с помощью ПЛИС.
  14. Здравствуйте! Возникла проблема следующего вида: На плате есть 2 разные микросхемы, висят на SPI. Нужно в зависимости от выбранной микросхемы (CS1 = 0 или CS2 = 0) менять местами MOSI и MISO. То есть, если выбрана первая микросхема - то MOSI это MOSI, а MISO это MISO. А вот когда выбрана вторая микросхема (CS2 = 0) то MOSI должна стать MISO, а MISO - MOSI на ПЛИС. ПЛИС Xilinx Spartan 6, код SPI взят из библиотеки Gaisler. Получившийся код: CODE entity leon3mp is ... port( ... mfmiso : inout std_logic; mfmosi : inout std_logic; mfscl : inout std_logic; mfcs1 : out std_logic; mfcs2 : out std_logic; ... ); ... signal spi_mosi_local, spi_miso_local: std_logic; signal spii : spi_in_type; signal spio : spi_out_type; spi_change_io: process(clkm, rstn) begin if rstn = '0' then mfmosi <= '0'; mfmiso <= '0'; spi_miso_local <= '0'; spi_mosi_local <= '0'; elsif clk'event and clk = '1' then if (mfcs2 = '0') then mfmiso <= spi_mosi_local; spi_miso_local <= mfmosi; else mfmosi <= spi_mosi_local; spi_miso_local <= mfmiso; end if; end if; end process; spimctrl : if CFG_SPIM_ENABLE = 1 generate spi_mctrl : spictrl generic map (pindex => CFG_SPIM_PINDEX, paddr => CFG_SPIM_PADDR, pirq => CFG_SPIM_PIRQ, fdepth => 1, slvselen => 0, slvselsz => 1) port map (rstn, clkm, apbi2, apbo2(CFG_SPIM_PINDEX), spii, spio, open); misopad : inpad generic map (tech => padtech) port map (spi_miso_local, spii.miso); mosipad : outpad generic map (tech => padtech) port map (spi_mosi_local, spio.mosi); sckpad : iopad generic map (tech => padtech) port map (mfscl, spio.sck, spio.sckoen, spii.sck); end generate; На этапе синтеза выдает ошибку вида: ERROR:Xst:528 - Multi-source in Unit <leon3mp> on signal <N0>; this signal is connected to multiple drivers. и кучу Drivers дальше, в том числе Output signal of OBUF instance <spimctrl.mosipad/xcv.x0/ttl0.slow0.op> Dangling signal <spi_mosi_local> in Unit <leon3mp> is tied to 0 by XST и много Dangling signal <N0> in Unit <iopad> is tied to 0 by XST Dangling signal <N0> in Unit <unisim_iopad> is tied to 0 by XST В чем ошибка данного решения, и как правильно решить данную проблему?
  15. DS21354 Reading

    Абсолютно такая же проблема. Не нашлось ли решение?