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

GAYVER

Свой
  • Постов

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

  • Посещение

Весь контент GAYVER


  1. все что нужно обконстрейнено, вылетов за пределы нету. да и какая связь? оно ж "раскладывается" в кристалл в одни и те же места для обеих плисин. значит убегать на разные дистанции для разных случаев не может
  2. платы не друг с другом скрещиваются, а со стендом. платы одинаковые. вынули одну, вставили другую - точно такую же, с такой же прошивкой. результат разный
  3. День добрый. Ситуация такая - плата с плисиной, в которой надо проверить входной каскад (прием от АЦП) и отладочный стенд. АЦП работает по принципу запрос-ответ с заданной периодичностью. С частотой 40КГц плис выдает сигнал "начать преобразование" и выставляет тактовые импульсы. АЦП ловит сигнал "начать преобразование", ловит тактовые импульсы и в определенный момент начинает выставлять биты данных. Проблема в том, что перед началом проектирования меня никто не поставил в известность о том, что стенду пофигу на мои запросы-ответы. По нажатию кнопки "старт" в оболочке он считает что начался обмен и от этой точки сам начинает развертывать диаграмму - сам имитирует "начать преобразование", выставление тактовых импульсов и битов данных в нужных местах. Начало всего этого действа сопровождается стробом У0. К моменту когда это выяснилось - проект уже был собран. Вся внутренняя логика функционирования продумана и отлажена. И она не позволяет асинхронно стартовать с места в карьер и тут же начинать развертывать диаграмму. Сначала должна запуститься управляющая "обвязка". На это нужно пару тактов. А стенд уже плюет мне данные в соответствии с диаграммой. Получился этакий "рассинхрон" по фазе - диаграмма работы плис соответствовала диаграмме работы стенда, но отставала от нее по времени на несколько миллисекунд. Т.к. оказалось что на выставление управляющих сигналов в целом можно было забить, было принято решение просто скомпенсировать эти пару тактов задержки, совместив диаграммы выдачи-приема данных. Рабочая частота приемного блока 1М. И передача данных стендом (выставление строба У0) может начаться в произвольный момент времени в течение периода этой частоты. Эта неопределенность в 1000 нан была сведена к приемлимому лагу в 125 нан. Для этого У0 принимается на частоте 8М и путем нехитрых "вычислений" через стробы "частот" 4М-2М-1М определяется положение фронта У0 в пределах периода 1М частоты (с лагом частоты 8М - 125 нан). Зная это положение я вычитаю нужное количество тактов 8М частоты из своего внутреннего сигнала запуска защелкивания данных, стартующего, в целом, от У0. А дальше все по стандартной диаграмме с нужным периодом. Т.е. подгоняется первое обращение, а дальше стандартная работа. Это помогло. Но до тех пор, пока проект не был прошит в другую плату. Начались лаги в один такт (один бит данных). Лаги в обе стороны - я могу начать защелкивать данные на 1 такт раньше (рабочей частоты приемного блока) чем нужно и на 1 такт позже чем нужно. В 5-10% включений схема отрабатывает как и задумывалось. Собственно вопрос - куда смотреть и чего делать? Все прочие условия остаются неизменными - та же прошивка, тот же стенд, те же кабеля, те же переходники. Показания кварцев на платах отличаются на 0.0003 единицы. В плисине от опороной частоты 56М от кварца получаются все прочие нужные частоты УПД вот, что еще торкнуло. на второй плате 90% косячных срабатываний. с разбежкой шаг влево, шаг вправо. это значит что все время "компенсируется" одна и та же (две одних и тех же) неправильная константа. всего их 8 штук. это значит что в 90% случаев фронт У0 приходит в одно и то же место (в 2 места :)). при том что оператор запускает обмен в произвольный момент времени. но этого же не может быть чтобы стабильно из 100 опытов в 90 было 2 значения из 8. собранная статистика прошлых запусков это подтверждает - распределение довольно случайное. какие мысли могут быть по этому поводу?
  4. так там и так стоят 3 триггера. на шине данных один. но по идее и этот один там не нужен - во-первых данные идут сразу в регистр, а во-вторых три штуки на "валидности" данных компенсируют любые косяки по данным
  5. вот, это уже другое дело - хотя бы направление поиска задано. будем посмотреть в эту сторону. спасибо. хотя как может влиять времянка на логику всеравно не понимаю - ну уехал триггер дальше от пина, и что? он всеравно укладывается во временные ограничения дизайна и никак на конечный результат, защелкнутый в триггере не влияет. ну разве что только метастабильность может вносить свои коррективы. но метастабильность штука не постоянная и проявляется рандомно. триггер в СДС-ке работает на 56МГц upd старшие товарищи сообщили что лет 10 назад уже сталкивались с такой же проблемой - при передаче первой команды ФТДИ выдавала не полную команду. тогда расковыряли все - и свой контроллер и оболочку и драйвера и кабель. но так ни до чего и не докопались. списали на китайскую ФДТАЙку и поставили костыль в виде таймера - для сброса контроллера после первой передачи код и часть диаграммы (раньше был кодбокс, как сейчас сократить простыню кода - не могу найти) library IEEE; use IEEE.STD_LOGIC_1164.ALL; USE ieee.numeric_std.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.std_logic_unsigned.all; use IEEE.math_real.all; entity contr_FTDI is generic (TC: time:=17.85 ns); -- Port ( C56M : in STD_LOGIC; C1M : in STD_LOGIC; C2M : in STD_LOGIC; RST : in STD_LOGIC; ------------------- WR : out STD_LOGIC; nTXE : in STD_LOGIC; D_OUT : out STD_LOGIC_VECTOR (7 downto 0); nRD : out STD_LOGIC; nRXF : in STD_LOGIC; D_IN : in STD_LOGIC_VECTOR (7 downto 0); U_BUF : out STD_LOGIC; --- DUS : INOUT STD_LOGIC_VECTOR (7 DOWNTO 0); --- ------------------- AWADDR : out STD_LOGIC_VECTOR (31 downto 0); AWVALID : out STD_LOGIC; AWREADY : in STD_LOGIC; --- WDATA : out STD_LOGIC_VECTOR (31 downto 0); WVALID : out STD_LOGIC; WREADY : in STD_LOGIC; --- ARADDR : out STD_LOGIC_VECTOR (31 downto 0); ARVALID : out STD_LOGIC; ARREADY : in STD_LOGIC; --- RDATA : in STD_LOGIC_VECTOR (31 downto 0); RVALID : in STD_LOGIC; RREADY : out STD_LOGIC); end contr_FTDI; architecture Behavioral of contr_FTDI is function max(L, R: INTEGER) return INTEGER is begin if L > R then return L; else return R; end if; end; ---------------------------------- constant BPW1_2 :time:=50 ns; --ns constant BPW2_3 :time:=50 ns; --ns constant BPW3_4 :time:=80 ns; --ns -- constant BPR1_2 :time:=50 ns; --ns constant BPR2_3 :time:=105 ns; --ns ---------------------------------- constant prTPW1_2 :integer:=integer(ceil(real(BPW1_2/TC))); constant prTPW2_3 :integer:=integer(ceil(real(BPW2_3/TC))); constant prTPW3_4 :integer:=integer(ceil(real(BPW3_4/TC))); constant TPW1_2 :integer:=prTPW1_2+1; constant TPW2_3 :integer:=prTPW2_3+1; constant TPW3_4 :integer:=prTPW3_4+1; --- constant prTPR1_2 :integer:=integer(ceil(real(BPR1_2/TC))); constant prTPR2_3 :integer:=integer(ceil(real(BPR2_3/TC))); constant TPR1_2 :integer:=prTPR1_2+1; constant TPR2_3 :integer:=prTPR2_3+1; ---------------------------------- constant KOL_TW :integer:=TPW1_2+TPW2_3+TPW3_4; --- constant KOL_TR :integer:=TPR1_2+TPR2_3; --- constant KOL_MAX :integer:=max(KOL_TW, KOL_TR); ---------------------------------- constant BT :integer:=integer(CEIL(LOG2(real(KOL_MAX)))); ---------------------------------- constant BTW_int :integer:=KOL_TW-1-1;--(первая "-1" это сдвиг диапазона в векторе, вторая - это компенсация одного такта на сброс) constant BTW_bit :std_logic_vector(BT-1 downto 0):=CONV_STD_LOGIC_VECTOR(BTW_int, BT); --- constant BTR_int :integer:=KOL_TR-1; constant BTR_bit :std_logic_vector(BT-1 downto 0):=CONV_STD_LOGIC_VECTOR(BTR_int, BT); ---------------------------------- constant PW2 :integer:=KOL_TW-TPW1_2+1;-- constant PW3 :integer:=PW2-TPW2_3; --- constant PR2 :integer:=KOL_TR-TPR1_2; ---------------------------------- constant PW2_bit :std_logic_vector(BT-1 downto 0):=CONV_STD_LOGIC_VECTOR(PW2, BT); constant PW3_bit :std_logic_vector(BT-1 downto 0):=CONV_STD_LOGIC_VECTOR(PW3, BT); --- constant PR2_bit :std_logic_vector(BT-1 downto 0):=CONV_STD_LOGIC_VECTOR(PR2, BT); --- constant C2_bit :std_logic_vector(BT-1 downto 0):=CONV_STD_LOGIC_VECTOR(2, BT); constant C1_bit :std_logic_vector(BT-1 downto 0):=CONV_STD_LOGIC_VECTOR(1, BT); constant C0_bit :std_logic_vector(BT-1 downto 0):=CONV_STD_LOGIC_VECTOR(0, BT); ---------------------------------- ---------------------------------- ---------------------------------- ---------------------------------- signal WRs, nRDs, U_BUFs :std_logic; signal D_OUTs :std_logic_vector(7 downto 0):=(others=>'0'); signal res_ct_usb, ce_ct_usb :std_logic; signal ct_usb_v0, ct_usb_v0_d, ct_usb_v1, ct_usb_v0_2d, ct_usb_v0_3d, ct_usb_v0_4d, ct_usb_v0_5d :std_logic:='1'; signal ct_usb :std_logic_vector(BT-1 downto 0):=(others=>'0'); signal res_ct_byte, ce_ct_byte :std_logic; signal ct_byte_v0, ct_byte_v0_d, ct_byte_v1 :std_logic:='1'; signal ct_byte :std_logic_vector(2 downto 0):=(others=>'0'); signal res_rg_head, ce_rg_head :std_logic; signal rg_head :std_logic_vector(63 downto 0):=(others=>'0'); signal res_ct_ak, ce_ct_ak, ct_ak_v1, ct_ak_v0 :std_logic; signal ct_addr, ct_kol :std_logic_vector(23 downto 0):=(others=>'0'); signal ce_rgd, ce_rgd_d :std_logic; signal rgd :std_logic_vector(31 downto 0); signal ce_rgcom, rg_kol_v1 :std_logic; signal rg_com, rg_id :std_logic; signal rg_ustr :std_logic_vector(1 downto 0); signal rg_addr :std_logic_vector(23 downto 0); signal rg_kol :std_logic_vector(23 downto 0); signal work, work_d :std_logic; signal AWVALIDs, WVALIDs, ARVALIDs, RREADYs :std_logic:='0'; signal AWADDRs, WDATAs, ARADDRs :std_logic_vector(31 downto 0); signal num_ustr :std_logic_vector(5 downto 0); signal ce_timer, res_timer, end_timer, end_timer_d :std_logic:='0'; signal timer :std_logic_vector(6 downto 0):="1111111"; signal nrxf_d, nrxf_2d, nrxf_3d, nrxf_4d, ntxe_d, ntxe_2d, ntxe_3d, res_ftdi :std_logic; -- constant rg_id: STD_LOGIC_VECTOR (31 DOWNTO 0):=X"7531F590"; begin res_ftdi<=RST; pr_usb: process(C56M) begin if C56M'event and C56M='1' then --USB nrxf_d<=nRXf after 100 ps; nrxf_2d<=nrxf_d after 100 ps; nrxf_3d<=nrxf_2d after 100 ps; nrxf_4d<=nrxf_3d after 100 ps; ntxe_d<=nTXE after 100 ps; ntxe_2d<=ntxe_d after 100 ps; ntxe_3d<=ntxe_2d after 100 ps; if res_ftdi='1' or ct_usb=PW3_bit then nRDs<='1' after 100 ps; elsif ct_usb=PW2_bit then nRDs<='0' after 100 ps; else nRDs<=nRDs after 100 ps; end if; if res_ftdi='1' or ct_usb=PR2_bit then WRs<='0' after 100 ps; elsif res_ct_usb='1' and rg_com='0' and work='1' then WRs<='1' after 100 ps; else WRs<=WRs after 100 ps; end if; if res_ftdi='1' then D_OUTs<=(others=>'0') after 100 ps; elsif res_ct_usb='1' then D_OUTs<=rgd(7 downto 0) after 100 ps; else D_OUTs<=D_OUTs after 100 ps; end if; if res_ftdi='1' or (work='0' and work_d='1') then U_BUFs<='0' after 100 ps; elsif work='1' and rg_com='0' then U_BUFs<='1' after 100 ps; else U_BUFs<=U_BUFs after 100 ps; end if; end if; end process; pr_ct_usb: process(C56M) begin if C56M'event and C56M='1' then --res if res_ftdi='1' or res_ct_usb='1' then res_ct_usb<='0' after 100 ps; elsif nRXF_3d='0' and ct_usb_v0='1' and work='0' then res_ct_usb<='1' after 100 ps; elsif nRXF_3d='0' and ct_usb_v0='1' and (work='1' and rg_com='1' and ((WVALIDs='1' and WREADY='1' and ct_byte_v0='1') or (ct_byte_v0='0'))) then res_ct_usb<='1' after 100 ps; elsif nTXE_3d='0' and ct_usb_v0='1' and work='1' and ((RREADYs='1' and RVALID='1') or (rg_com='0' and ct_byte_v0='0')) then res_ct_usb<='1' after 100 ps; else res_ct_usb<=res_ct_usb after 100 ps; end if; --ce if res_ftdi='1' or (ce_ct_usb='1' and ct_usb_v1='1') then ce_ct_usb<='0' after 100 ps; elsif res_ct_usb='1' then ce_ct_usb<='1' after 100 ps; else ce_ct_usb<=ce_ct_usb after 100 ps; end if; --ct if res_ftdi='1' then ct_usb<=(others=>'0') after 100 ps; elsif res_ct_usb='1' and (work='0' or rg_com='1') then ct_usb<=BTW_bit after 100 ps; elsif res_ct_usb='1' and work='1' and rg_com='0' then ct_usb<=BTR_bit after 100 ps; elsif ce_ct_usb='1' then ct_usb<=ct_usb-1 after 100 ps; else ct_usb<=ct_usb after 100 ps; end if; --- if res_ftdi='1' or (ce_ct_usb='1' and ct_usb_v1='1') then ct_usb_v1<='0' after 100 ps; elsif ce_ct_usb='1' and ct_usb=C2_bit then ct_usb_v1<='1' after 100 ps; else ct_usb_v1<=ct_usb_v1 after 100 ps; end if; if res_ct_usb='1' then ct_usb_v0<='0' after 100 ps; elsif res_ftdi='1' or (ce_ct_usb='1' and ct_usb=C1_bit) then ct_usb_v0<='1' after 100 ps; else ct_usb_v0<=ct_usb_v0 after 100 ps; end if; ct_usb_v0_d<=ct_usb_v0 after 100 ps; ct_usb_v0_2d<=ct_usb_v0_d after 100 ps; ct_usb_v0_3d<=ct_usb_v0_2d after 100 ps; ct_usb_v0_4d<=ct_usb_v0_3d after 100 ps; ct_usb_v0_5d<=ct_usb_v0_4d after 100 ps; end if;--clk end process;--pr_ct_usb pr_ct_byte: process(C56M) begin if C56M'event and C56M='1' then --res_ftdi if res_ftdi='1' or res_ct_byte='1' then res_ct_byte<='0' after 100 ps; elsif res_ct_usb='1' and ct_byte_v0='1' then res_ct_byte<='1' after 100 ps; else res_ct_byte<=res_ct_byte after 100 ps; end if; --ce if res_ftdi='1' or ce_ct_byte='1' then ce_ct_byte<='0' after 100 ps; elsif res_ct_usb='1' and ct_byte_v0='0' then ce_ct_byte<='1' after 100 ps; else ce_ct_byte<=ce_ct_byte after 100 ps; end if; --ct if res_ftdi='1' then ct_byte<=(others=>'0') after 100 ps; elsif res_ct_byte='1' and work='0' then ct_byte<="111" after 100 ps; elsif res_ct_byte='1' and work='1' then ct_byte<="011" after 100 ps; elsif ce_ct_byte='1' then ct_byte<=ct_byte-1 after 100 ps; else ct_byte<=ct_byte after 100 ps; end if; --- if res_ftdi='1' or (ce_ct_byte='1' and ct_byte_v1='1') then ct_byte_v1<='0' after 100 ps; elsif ce_ct_byte='1' and ct_byte="010" then ct_byte_v1<='1' after 100 ps; else ct_byte_v1<=ct_byte_v1 after 100 ps; end if; if res_ct_byte='1' then ct_byte_v0<='0' after 100 ps; elsif res_ftdi='1' or (ce_ct_byte='1' and ct_byte="001") then ct_byte_v0<='1' after 100 ps; else ct_byte_v0<=ct_byte_v0 after 100 ps; end if; ct_byte_v0_d<=ct_byte_v0 after 100 ps; end if;--clk end process;--pr_ct_byte pr_ct_ak: process(C56M) begin if C56M'event and C56M='1' then --res_ftdi if res_ftdi='1' or res_ct_ak='1' then res_ct_ak<='0' after 100 ps; elsif work='1' and work_d='0' then res_ct_ak<='1' after 100 ps; else res_ct_ak<=res_ct_ak after 100 ps; end if; --ce if res_ftdi='1' or ce_ct_ak='1' then ce_ct_ak<='0' after 100 ps; elsif (rg_com='1' and res_ct_usb='1' and ct_byte_v0='1') or (rg_com='0' and work='1' and ct_byte_v0='1' and ct_byte_v0_d='0') then ce_ct_ak<='1' after 100 ps; else ce_ct_ak<=ce_ct_ak after 100 ps; end if; --ct if res_ftdi='1' or (res_ct_ak='1' and rg_id='0') then ct_kol<=rg_kol after 100 ps; elsif res_ct_ak='1' and rg_id='1' then ct_kol<="000000000000000000000001" after 100 ps; elsif ce_ct_ak='1' then ct_kol<=ct_kol-1 after 100 ps; else ct_kol<=ct_kol after 100 ps; end if; if res_ftdi='1' or (res_ct_ak='1' and rg_id='0') then ct_addr<=rg_addr after 100 ps; elsif res_ct_ak='1' and rg_id='1' then ct_addr<=(others=>'1') after 100 ps; elsif ce_ct_ak='1' then ct_addr<=ct_addr+1 after 100 ps; else ct_addr<=ct_addr after 100 ps; end if; --- if res_ftdi='1' or (ce_ct_ak='1' and ct_ak_v1='1') or (work='0' and work_d='1') then ct_ak_v1<='0' after 100 ps; elsif (ce_ct_ak='1' and ct_kol="000000000000000000000010") or (res_ct_ak='1' and rg_kol_v1='1') then ct_ak_v1<='1' after 100 ps; else ct_ak_v1<=ct_ak_v1 after 100 ps; end if; if res_ftdi='1' or res_ct_ak='1' or (work='0' and work_d='1') then ct_ak_v0<='0' after 100 ps; elsif ce_ct_ak='1' and ct_kol="000000000000000000000001" then ct_ak_v0<='1' after 100 ps; else ct_ak_v0<=ct_ak_v0 after 100 ps; end if; end if;--clk end process;--pr_ct_ak pr_work:process(C56M) begin if C56M'event and C56M='1' then ---------------------------- --ce if res_ftdi='1' or ce_rg_head='1' then ce_rg_head<='0' after 100 ps; elsif work='0' and ct_usb=PW3_bit then ce_rg_head<='1' after 100 ps; else ce_rg_head<=ce_rg_head after 100 ps; end if; --rg_head if res_ftdi='1' or (work='0' and work_d='1') then rg_head<=(others=>'0') after 100 ps; elsif ce_rg_head='1' then rg_head<=rg_head(55 downto 0) & D_IN after 100 ps; else rg_head<=rg_head after 100 ps; end if; ---------------------------- ---------------------------- --ce if res_ftdi='1' or ce_rgd='1' then ce_rgd<='0' after 100 ps; elsif work='1' and ((ct_usb=PW3_bit and rg_com='1') or (res_ct_usb='1' and rg_com='0')) then ce_rgd<='1' after 100 ps; else ce_rgd<=ce_rgd after 100 ps; end if; ce_rgd_d<=ce_rgd after 100 ps; --rgd if res_ftdi='1' then rgd<=(others=>'0') after 100 ps; elsif RVALID='1' and RREADYs='1' then rgd<=RDATA after 100 ps; elsif rg_com='1' and ce_rgd='1' then rgd<=rgd(23 downto 0) & D_IN after 100 ps; elsif rg_com='0' and ce_rgd='1' then rgd<="00000000" & rgd(31 downto 8) after 100 ps; else rgd<=rgd after 100 ps; end if; ---------------------------- if res_ftdi='1' or (work='0' and work_d='1') then rg_kol_v1<='0' after 100 ps; elsif rg_kol="000000000000000000000001" then rg_kol_v1<='1' after 100 ps; else rg_kol_v1<=rg_kol_v1 after 100 ps; end if; --work if res_ftdi='1' or (ct_byte_v0='1' and ct_ak_v1='1' and ct_usb_v0='1' and rg_com='1' and WVALIDs='1' and WREADY='1') or (ct_byte_v0='1' and ct_ak_v0='1' and rg_com='0' and ct_usb_v0_d='1') then work<='0' after 100 ps; elsif ct_byte_v0='1' and ct_usb_v0='1' and ct_usb_v0_d='0' and work='0' then work<='1' after 100 ps; else work<=work after 100 ps; end if; work_d<=work after 100 ps; --AXI -- после переделки поля выбор устройства в оболочке - поменять условия. после изменения запись удалить!!! if res_ftdi='1' or (work='0' and work_d='1') then num_ustr<=(others=>'0') after 100 ps; elsif rg_ustr="11" or rg_id='1' then num_ustr<="000010" after 100 ps; --- elsif rg_ustr="01" then num_ustr<="000100" after 100 ps; -- в старой оболочке не будет работать!!! --- elsif rg_ustr="00" then num_ustr<="000001" after 100 ps; --RAM IN else num_ustr<=num_ustr after 100 ps; end if; ----------------- if res_ftdi='1' then AWADDRs<=(others=>'0') after 100 ps; elsif (ct_usb_v0='1' and ct_usb_v0_d='0') and ct_byte_v0='1' then AWADDRs<=num_ustr & ct_addr & "00" after 100 ps; else AWADDRs<=AWADDRs after 100 ps; end if; if res_ftdi='1' or (AWVALIDs='1' and AWREADY='1') then AWVALIDs<='0' after 100 ps; elsif (ct_usb_v0='1' and ct_usb_v0_d='0') and ct_byte_v0='1' and work='1' and rg_com='1' then AWVALIDs<='1' after 100 ps; else AWVALIDs<=AWVALIDs after 100 ps; end if; ----------------- if res_ftdi='1' then WDATAs<=(others=>'0') after 100 ps; elsif (ct_usb_v0='1' and ct_usb_v0_d='0') and ct_byte_v0='1' then WDATAs<=rgd after 100 ps; else WDATAs<=WDATAs after 100 ps; end if; if res_ftdi='1' or (WVALIDs='1' and WREADY='1') then WVALIDs<='0' after 100 ps; elsif (ct_usb_v0='1' and ct_usb_v0_d='0') and ct_byte_v0='1' and work='1' and rg_com='1' then WVALIDs<='1' after 100 ps; else WVALIDs<=WVALIDs after 100 ps; end if; ----------------- ----------------- ----------------- if res_ftdi='1' or (ARVALIDs='1' and ARREADY='1') then ARADDRs<=(others=>'0') after 100 ps; elsif rg_com='0' and ct_usb_v0_4d='1' and ct_usb_v0_5d='0' then ARADDRs<=num_ustr & ct_addr & "00" after 100 ps; else ARADDRs<=ARADDRs after 100 ps; end if; if res_ftdi='1' or (ARVALIDs='1' and ARREADY='1') then ARVALIDs<='0' after 100 ps; elsif rg_com='0' and ct_usb_v0_4d='1' and ct_usb_v0_5d='0' and work='1' and ct_byte_v0='1' and ct_usb_v0='1' then ARVALIDs<='1' after 100 ps; else ARVALIDs<=ARVALIDs after 100 ps; end if; --- if res_ftdi='1' or (RVALID='1' and RREADYs='1') then RREADYs<='0' after 100 ps; elsif rg_com='0' and ct_usb_v0_4d='1' and ct_usb_v0_5d='0' and work='1' and ct_byte_v0='1' and ct_usb_v0='1' then RREADYs<='1' after 100 ps; else RREADYs<=RREADYs after 100 ps; end if; ----------------- end if;--clk end process;--work WR<=WRs; nRD<=nRDs; D_OUT<=D_OUTs; U_BUF<=not(U_BUFs); rg_com<=rg_head(63); rg_id<=rg_head(55); rg_ustr<=rg_head(49 downto 48); rg_addr<=rg_head(47 downto 24); rg_kol<=rg_head(23 downto 0); ARADDR<=ARADDRs; ARVALID<=ARVALIDs; RREADY<=RREADYs; AWADDR<=AWADDRs; AWVALID<=AWVALIDs; WDATA<=WDATAs; WVALID<=WVALIDs; end Behavioral;
  6. ок. ваши предположения - какие могут быть косяки в коде в данной ситуации (код не менялся, плисина полупустая, период рабочей частоты большой, входы-выходы сидят на одних и тех же пинах, но результат разный)? линия взаимодействия с ФТДИ - 4 сигнала управления (2 из которых выставляет ФТДИ) и 8 линий данных.
  7. спартан6. утверждение смелое от того, что до этого работали на частотах 250-350. а тут с этими 17 нанами периода - хоть конем гуляй )). да и проект ещ только рыба - без основного вычислителя, который отожрет минимум пол плисины зы и это ж чего надо навротить в проекте, чтобы только 20МГц выдало )))? при том что там границы 5-300
  8. тактовая там одна - 56МГц. т.е. требований к временам и логике практически нет. да и логика там только на управлении триггеров. и таки да - при чем тут дизайн, если ФТДАЙка не выставляет управляющие сигналы, на которые внутренний контроллер должен только ответить? и на те сигналы что приходят - контроллер отвечает ровно по диаграмме, т.е. нету лишних срабатываний в ненужных местах, которые ФТДАЙка могла бы воспринять как лишний прием плавающих ошибок, накладывающихся друг на друга я уже две ликвидировал - непропай по линии ТХЕ на кабеле и сопля на РХФ.
  9. да, асинхронное фифо, но логикой там и не пахнет :). временные ограничения чего?
  10. имеется плата с плисиной, самодельный кабель с FT2232D на борту (УСБ-ФИФО245), программная оболочка. при коннекте с платой оболочка первым делом вычитывает ИД подключенного устройства. отладка началась именно с этого момента - вычитывание ИД. в ЦДЦ-к накидались нужные сигналы, разводка, прошивка - есть коннект. прошивка осталась в архиве прошивок, в проект добавился следующий функционал - чтение внутренней памяти через ФТДИ-контроллер, в ЦДЦ-к докинулись новые сигналы, разводка, прошивка и... ИД-к уже не читается. диаграмма показывает что от ФТДИ в плисину приходит не 8 байт команды, а 4-7. в разных случаях по-разному. но никогда не все 8. прошиваю вчерашнюю прошивку - ИД вычитвается нормально. накатываю новую прошивку - от ФТДИ нет полной команды. при этом фтди-контроллер в плисине вообще никак не менялся, после первоначального сброса он находится в правильном состоянии, на сигналы от ФТДИ отвечает четко по диаграмме, выдерживая все тайминги. уцф никак не менялся. все внешние факторы тоже неизменны - тот же кабель с той же прошивкой, та же оболочка с тем же функционалом. где связь между прошивкой плисины и количеством выдаваемых ФТДИ-контроллером байт?
  11. ну ветка форума называетя "языки проектирования на ПЛИС", так что сильно сомневаюсь что сюда заглянут люди, имеющие дело со схематиками в пикаде :). ISE 14.7, *.vhd? => *.sch
  12. на схематике дженерики можно добавлять через параметры символа. а как протащить параметр в схематик из вхдл-го топ-лвл-а?
  13. тайна раскрыта :). в недрах дизайна обнаружен буфер, на вход которого заведена синхра (которая идет и на память), а выход - на логику. выход буфера законстрэйнен через CLOCK_DEDICATED_ROUTE. после ЭНДки полученный сигнал сразу вытаскивался на пин плисины и нигде внутри больше не использовался. но выход буфера был воспринят как клок и растащен дальше на память... пересмотреть не получится - есть заданный кристалл и заданные алгоритмы, под которые нужно определенное количество памяти. кто-то несколько лет назад посчитал что памяти хватает. теперь приходится изворачиваться и архитектурно и алгоритмически - чтобы впихнуть невпихуемое... ну 2-3 часа это он какраз пытается впихнуть невпихуемое. алгоритм же 3 или 4 раза стартует с нуля, в случае неудачи предыдущего шага. а если все в порядке, то разводка с учетом УЦФа минут за 10-15 проходит :)
  14. вот я и смотрел что там с клоками не так... пока ничего не насмотрел - все берется с ДСМа, раскидывается через буфг. взять блочку не получится ввиду ее нехватки. сегодня еще попробую однопортовую сделать вместо двушки. самокритично, потомучто кроме расплывчатого направления "смотри клоки" ничего не понятно - куда именно смотреть и почему вообще какие то проблемы с клоком возникли. а с подобным в своей практике ранее не сталкивался, чтобы хоть как то сократить область поисков. потому как каждая неудачная разводка до момента выкидывания репортов крутится часа 2-3... и выкинуть часть проекта не получится - это и так тестовая рыба без основного вычислителя зы вспоминается случай с ИСЕ, когда в процессе разводки неправильно собиралась шина :). допустим, есть шина NAME(7:0) и несколько сигналов NAME_1, NAME_5. после разводки шина имела вид: NAME(7:0)= NAME(7) & NAME(6) & NAME_5 & NAME(4) & NAME(3) & NAME(2) & NAME_1 & NAME(0) пока я это нашел... пол кристалла облазил )) вот чую сейчас будет что то подобное...
  15. блок двухпортовой распределенки с синхронной записью и асинхронным чтением. описан по шаблону из хелпа. по объему - четверть от максимально доступной. на мапе выдает: The following instances are the last set of instances that failed to place: 0. B_IN_ADC/B_RAMD_IN_test/Mram_RAM_RE_STR11_RAMD_O (size: 8) LUTM B_IN_ADC/B_RAMD_IN_test/Mram_RAM_RE_STR11_RAMD_O LUTM B_IN_ADC/B_RAMD_IN_test/Mram_RAM_RE_STR11_RAMD LUTM B_IN_ADC/B_RAMD_IN_test/Mram_RAM_RE_STR11_RAMD_O LUTM B_IN_ADC/B_RAMD_IN_test/Mram_RAM_RE_STR11_RAMC LUTM B_IN_ADC/B_RAMD_IN_test/Mram_RAM_RE_STR11_RAMD_O LUTM B_IN_ADC/B_RAMD_IN_test/Mram_RAM_RE_STR11_RAMB LUTM B_IN_ADC/B_RAMD_IN_test/Mram_RAM_RE_STR11_RAMD_O LUTM B_IN_ADC/B_RAMD_IN_test/Mram_RAM_RE_STR11_RAMA ............................................. These instances could be impacted by the following constraints (the line IDs below correspond with the instances above): Clock Region restrictions 0. LUTM B_IN_ADC/B_RAMD_IN_test/Mram_RAM_RE_STR11_RAMD_O driver: DCM B_PLL/DCM_inst1 @ DCM_X0Y3 LUTM B_IN_ADC/B_RAMD_IN_test/Mram_RAM_RE_STR11_RAMD_O driver: DCM B_PLL/DCM_inst1 @ DCM_X0Y3 LUTM B_IN_ADC/B_RAMD_IN_test/Mram_RAM_RE_STR11_RAMD_O driver: DCM B_PLL/DCM_inst1 @ DCM_X0Y3 LUTM B_IN_ADC/B_RAMD_IN_test/Mram_RAM_RE_STR11_RAMD_O driver: DCM B_PLL/DCM_inst1 @ DCM_X0Y3 LUTM B_IN_ADC/B_RAMD_IN_test/Mram_RAM_RE_STR11_RAMD_O driver: DCM B_PLL/DCM_inst1 @ DCM_X0Y3 LUTM B_IN_ADC/B_RAMD_IN_test/Mram_RAM_RE_STR11_RAMD_O driver: DCM B_PLL/DCM_inst1 @ DCM_X0Y3 LUTM B_IN_ADC/B_RAMD_IN_test/Mram_RAM_RE_STR11_RAMD_O driver: DCM B_PLL/DCM_inst1 @ DCM_X0Y3 LUTM B_IN_ADC/B_RAMD_IN_test/Mram_RAM_RE_STR11_RAMD_O driver: DCM B_PLL/DCM_inst1 @ DCM_X0Y3 CLOCKREGION_X0Y2, CLOCKREGION_X1Y2 ............................................................... для меня тут никакой смысловой нагрузки... куда смотреть, чего делать?
  16. если вопрос стоит в том чтобы самому что то городить, то мне будет проще переписать входной блок под одинаковую частоту :). это если нет решения на пару строк кода или использование чего-то стандартного...
  17. фифо, конечно, круто, но в 6 спартане его нет... или я что то путаю ))
  18. в голове уже каша, поэтому обращаюсь к коллективному бессознательному. имеется 2 связанных сигнала (данные-строб). их надо перевести с бОльшей частоты на мЕньшую (кратность примерно 2,6). сначала взял старую проверенную заготовку и вкорячил ее на обе линии. а потом задумался - из-за того что переход в точке 0 затиган - рано или поздно вылезет ситуация, когда произойдет рассинхрон фронтов данных и строба, и на меньшей частоте по стробу защелкнется не то данное. и, собствено, вопрос - как этого избежать? зы я мог не точно выразиться - под стробом понимается сигнал валидности данных. грубо говоря WDATA+WVALID с акси
  19. в последние дни голова забита другим, поэтому допустил грубейшую логическую ошибку. плюс, похоже, накосячил с монтажом. на каникулах перепроверю
  20. ээээ... ну пин как бы инверсный. "рабочее" значение - LOW
  21. сброс подтянут к питанию. на этом пине триггера всегда логический 0. сигнал ЛОСТ прыгает 0-1. вот вам и комбинация 00
  22. откровенно говоря первый раз с таким сталкиваюсь. обычно сброс в приоритете. и что с этим делать? добавлять цепь управления сбросом, которая будет блокировать это состояние?
  23. наконец то дошли руки до сборки. и столкнулся с таким непонятно-неприятным моментом - периодически прямой и обратный выходы второго триггера стоят в единицах. оба. втф?
×
×
  • Создать...