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

Golikov

Свой
  • Постов

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

  • Посещение

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


  1. не ну не настолько близко... 67 и 100 МГц. мне кажется что если поставить защелки на выходе сигналов, которые бы по поднятому сигналу и основному клоку пропускали, в противном случае хранили то все проблемы были бы решены... как мне кажется... все изменения могут быть только по фронту основного клока, и для дальнейшей схемы все будет синхронно... Единственное волнует переходной процесс открывающейся latch, но можно открывать ее по падающему фронту и тогда к восходящему все будет ок! Или так не делают?
  2. а вот я подумал... если я поставлю D триггер, на данные ему подам ADC_DRDY а на клок - основной клок схемы, получится что у меня все заcсинхронизируется на основной клок схемы... или не получится? signal a:std_logic_vector(3 downto 0) :="0000"; signal b:std_logic_vector(3 downto 0) :="0000"; process(ADC_DRDY_D_TRIG_OUT) begin if ADC_DRDY_D_TRIG_OUT ='1' and ADC_DRDY_D_TRIG_OUT'event then a<= ADC_IN; end if; end process process(GLB_CLK) begin if GLB_CLK='1' and GLB_CLK'event then b<= a; end if; end process по идее рассинхрона не будет, так?... то есть нет шанса что в b защелкнется переходной процесс из a? И кстати вот еще что. Если последовательно соединить несколько D триггеров, с общим клоком, то на каждый фронт будет происходит сдвиг данных как в сдвиговом регистре? А не может так получится, что в какой-то из защелок будет сохранен переходной процесс с прошлой? Как-то раньше этот вопрос у меня не возникал, а теперь я не понимаю как это работает:)...
  3. библиотеку нумерик я добавил уже от отчаяния... этот проект у меня не симулится хоть умри.... и как вы говорите тоже не симулится... может надо среду менять.. у меня ксалинский проек навигатор 7.1.04i вроде бы из последних... а проблемы наверное правда могут быть. Половину данных я защелкну по специальному сигналу PHASE_DRDY, а вот про ADC_VAL я что-то забыл... но это моно поправить, и для него тоже вывести ADC_DRDY… хотя это уже перебор… Другими словами имеет смысл ввести в схему глобальный сигнал синхронизации... что-то типа process (CLK, ADC_DRDY) begin if CLK='1' and CLK'event then if ADC_DRDY ='1' then ADC_OUT <=ADC_IN; end if; end if; end process кстати хотел узнать, можно ли делать так process (CLK, ADC_DRDY) begin if CLK='1' and CLK'event then if ADC_DRDY'event then -- имея ввиду первый подъем ADC_DRDY после фронта CLK? ADC_OUT <=ADC_IN; end if; end if; end process; или это надо реализовывать через флаг? чтобы не считывать данные каждый клок, а только один раз.. и вообще как по уму делается синхронизация, про которую вы говорили?...Просто у меня может быть проблема с тем, что фронт основного клока может не попасть в сигнал ADC_DRDY и пропустить данные, чего бы не хотелось… частоты близки и не кратны...
  4. Боролся долго с SIGNED UNSIGNED, пришел к выводу что смысл это все имеет очень сомнительный, и кажущаяся удобность просто на корню убивается, что я делаю не так.... вот два примера. ibrary IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; --use IEEE.STD_LOGIC_SIGNED.ALL; use IEEE.NUMERIC_STD.ALL; ---- Uncomment the following library declaration if instantiating ---- any Xilinx primitives in this code. --library UNISIM; --use UNISIM.VComponents.all; entity ADCProcess is Port ( ADC_IN : in SIGNED (13 downto 0); ADC_DRDY : in std_logic; SYNC : in std_logic; ADC_AMPLITUDE : out UNSIGNED(13 downto 0); ADC_RAW_PHASE : out SIGNED(14 downto 0); ADC_VALUE : out SIGNED(13 downto 0); PHASE_DRDY : out std_logic); end ADCProcess; architecture Behavioral of ADCProcess is signal ADC_MIN : SIGNED (13 downto 0) :=CONV_SIGNED(8191,14); signal ADC_MAX : SIGNED (13 downto 0) :=CONV_SIGNED(-8192,14); signal StoreClear : UNSIGNED (1 downto 0) := "00"; begin process (ADC_DRDY) begin if ADC_DRDY='1' and ADC_DRDY'event then ADC_VALUE <= ADC_IN; if StoreClear /= CONV_UNSIGNED(1,2) then --collect min and max value if ADC_MIN > ADC_IN then ADC_MIN <= ADC_IN; end if; if ADC_MAX < ADC_IN then ADC_MAX <= ADC_IN; end if; end if; if StoreClear = CONV_UNSIGNED(0,2) AND SYNC ='1' then -- store phase and amplitude data StoreClear <= StoreClear+1; ADC_AMPLITUDE <= CONV_UNSIGNED(ADC_MAX-ADC_MIN,14); -- add 13'th bit for store true MIN, MAX sign -- not devide max+min on 2, instead it we mult ADC val on 2 -- and have multed on 2 raw_phase val -- from out max(sin)/ampletude(sin) = 0.5 we want 1, and -- already have it, because raw_phase was multiplied -- from out we need only divide raw_phase on amplitude -- to take real phase val ADC_RAW_PHASE <= ADC_IN&'0' - (ADC_MAX(13)&ADC_MAX)+(ADC_MIN(13)&ADC_MIN); end if; if StoreClear = CONV_UNSIGNED(1,2) then -- clear colect min max data StoreClear <= StoreClear+1; ADC_MIN <=CONV_SIGNED(8191,14); ADC_MAX <=CONV_SIGNED(-8192,14); PHASE_DRDY <='1'; -- set phase data ready signal end if; if SYNC= '0' then -- set scheme to sync sygnal wating state StoreClear <= "00"; PHASE_DRDY <='0'; end if; end if; end process; end Behavioral; этот пример синтезируется, но не симулируется как я с ним не бился... ModelSim ругается на конструкцию To_INTEGER, хотя я уже, кажется, перепробовал все библиотеки, а встроенный ругается на невозможность вызова функции write, в той же строке где TO_INTEGER Вот реализация той же логике моим способом library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; ---- Uncomment the following library declaration if instantiating ---- any Xilinx primitives in this code. --library UNISIM; --use UNISIM.VComponents.all; entity ADCProcessSigned is Port ( ADC_IN : in std_logic_vector(13 downto 0); ADC_DRDY : in std_logic; SYNC : in std_logic; ADC_AMPLITUDE : out std_logic_vector(13 downto 0); ADC_RAW_PHASE : out std_logic_vector(14 downto 0); ADC_VALUE : out std_logic_vector(13 downto 0); PHASE_DRDY : out std_logic); end ADCProcessSigned; architecture Behavioral of ADCProcessSigned is signal ADC_MIN : std_logic_vector (13 downto 0) :="11111111111111"; signal ADC_MAX : std_logic_vector (13 downto 0) :="00000000000000"; signal StoreClear : std_Logic_Vector (1 downto 0) := "00"; begin process (ADC_DRDY, SYNC) begin if ADC_DRDY='1' and ADC_DRDY'event then ADC_VALUE <= ADC_IN; if StoreClear = "01" then --clear min max data PHASE_DRDY <='1'; --set data ready signal ADC_MIN <="11111111111111"; --unsigned max possible val ADC_MAX <="00000000000000"; --unsigned min possible val StoreClear <= StoreClear+1; else --if StoreClear /= "01" --if not clear flag, collect data if ADC_MIN > (ADC_IN + "10000000000000") then -- convert -n..n to 0..2n ADC_MIN <= ADC_IN + "10000000000000"; end if; if ADC_MAX < (ADC_IN + "10000000000000") then -- convert -n..n to 0..2n ADC_MAX <= ADC_IN + "10000000000000"; end if; end if; if StoreClear = "00" AND SYNC ='1' then --store phase and amplitude data ADC_AMPLITUDE <= ADC_MAX-ADC_MIN; -- add 13 bit to store true sign -- not divide max+min on 2, instead it we mult ADC val on 2 -- and have mult on 2 phase val -- to convert unsigned 0..2n to -n to n, 14 bit adc min max -- widen on '0' and '1' it's equal adding of '100000000000000' -- in out, we need divide raw_phase on amplitude, and don't need -- multiply it on 2 , because raw_phase already doubled -- multiply need because (max(sin)/ampl(sin) = 0.5, we want 1) ADC_RAW_PHASE <= ADC_IN&'0' - (('1'&ADC_MAX)+('0'&ADC_MIN)); StoreClear <= StoreClear+1; end if; if SYNC= '0' then -- set sync signal waiting state StoreClear <= "00"; PHASE_DRDY <='0'; end if; end if; end process; end Behavioral; этот пример синтезируется и симулируется, и вроде даже работает как мне хочется... первый дает макс частоту ADC_DRDY 130 МГц, второй 127. и во втором тратится на одну лук ап таблицу больше. Это все сравнительные характеристики а не абсолютные естественно... ВАШ ОТВЕТ МЕНЯ ОЗАДАЧИЛ я как раз думал что если ввести один общий синхронизирующий сигнал в моем случае ADC_DRDY, то наоборот схема будет наиболее надежной. я хотел чтобы каждый раз как появятся данные на АЦП, чему свидетельствует восходящий фронт ADC_DRDY у меня это значение защелкивалось на ADC_VALUE, и сохранялось в регистрах MIN, MAX, если меньше минимума или больше максимума... каждый раз когда генерится сигнал SYNC (этот сигнал генерится когда аналоговый сигнал переходит ноль из минуса в плюс. запускается автомат из 4 состояний. Причем синхронизированный по ADC_DRDY, что гарантирует как я думаю отсуствие гонок сигналов... состояние 0 сбор данных, MIN MAX, ожидание сигнала SYNC, если SYNC -> состояние 1 состояние 1 расчет амплитуды из MIN,MAX, и фазы по последнему ADC_IN... -> состояние 2 состояние 2 обнуление MIN, MAX, выставление наличие данных фазы и амлитуды -> состояние 3 состояние 3 сбор новых данных, MIN MAX, ожидание сброса как SYNC уйдет в 0, автомат переходит в состояние 0 сбрасывает сигнал наличия данных... мне казалось что такая логика наиболее безопасна и детерминирована... очень хочется услышать ваши комментарии по возможным ошибкам...
  5. 1. Подключено было.... 2. Да это как бы и есть результат экспериментов, я решил оставить вариант с преобразованием знакового формата в безнаковый, это требует 1 лишнего сумматора, и убирает 2 мультиплексора и константные сигналы... в скорости проигрываю 2-3 МГц что на фоне 127 для меня несущественно... 3. ошибки?... ой.. ну я по памяти писал. На самом деле все просто, когда убирается ресет, каждое входное значение с АЦП по сигналу D_RDY выводится наружу в ADC_OUT, а также сравнивается на минимальное и максимальное. Тем самым через период будем иметь амплитуду и каждый такт текущее значение АЦП. Раз в период поднимается сигнал RESET и в этот момент минимуму присваивается самое большое число, максимуму самое маленькое, а амплитуда высчитывается как макс - мин. ошибку я вижу только в MIN <+ ADC_VAL+"10000000000000"; надо читать MIN <= ADC_VAL+"10000000000000"; эта схема работает, за одним исключением если с АЦП идут сигналы 0 1 2 3 4 5 6 то каждый клок на ADC_OUT 0 1 2 3 4 5 6 а на MIN или MAX z 0 1 2 3 4 5 то есть запаздывание на 1 такт, лично я не понял почему... 4. Да вот это я и не попробовал:)... спасибо, но это уже на будущее я думаю... в данной схеме это ситуацию сильно не изменит как мне кажется, 1 лишний сумматор ничтожно мало от имеющегося количества...
  6. использование Signed генерит быструю, но странную схему... Причем мне так и не удалось ее просимулировать. Симуляторы хором писали кучу ошибок, одной из которых было неизвестная конструкция TO_INTEGER, а подключение библиотеки NUMERIC сразу выносит файл из синтезируемых... Причем в решении когда диапазон -n..n перевел в 0..2n чтобы правильно учитывался знак в сравнении, ненамного медленнее, но не требует мультиплексоров для сброса мин и макс значения, так как в этом случае они ровны "1111…" и "0000…" а не "1000…" и "0111…" ( вектора по 14 бит естественно). Вот такие вот дела... так что всех тонкостей использования SIGNED я не осознал. А вот вопрос возник такой: process (D_RDY) begin if D_RDY='1' and D_RDY'event then if RESET='1' then AMPLETUDE <= MAX - MIN; MIN <="11111111111111"; MAX <="00000000000000"; else if (MIN > ADC_VAL+"10000000000000") MIN <+ ADC_VAL+"10000000000000"; if (MAX < ADC_VAL+"10000000000000") MAX <= ADC_VAL+"10000000000000"; ADC_OUT <= ADC_VAL; end if; end if; end process; Почему то MIN и MAX имеют задержку по присвоению значения в 1 так по сравнению с ADC_OUT. По схеме она появляется перед компараторами, можно ли как-то ее насильно убрать? и второе когда AMPLETUDE была UNSIGNED а MAX и MIN были SIGNED, AMPLETUDE <= MAX - MIN; вот такое присвоение так и не получилось, какие преобразования я не делал... В большинстве случаев мне писали про то что сумма должна иметь 2 типа или как-то так, или что неправильные подтипы... Как правильно делается такое преобразование?
  7. ну чтож в понедельник попробую, погляжу что скажет ModelSim
  8. я бы рад не обращать внимания но невозможно симулировать... in1 : in integer range -16 to 16 он пишет in1[-16..16] и когда предлагает ввести число, хочет чтобы было введено 32 битное число, а не 5 битное как должно бы было быть. И поэтому в моей записе in1 : integer range -8192 to 8191 он хочет 16000 битные вектора, он жутко тормозит при каждом действии, и соответственно неправильно представляет введенные числа... вот в чем проблема. Ну в общем понятно, надо бороть ModelSim, запись для VHDL я так понимаю правильная... а есть форма задания переменной интежер но с указанием диапазона в битах а не в числах?
  9. спасибо еще раз. Беспокоит только 2 момента 1. я писал пример in ineteger range -10 to 10; ModelSimе это представляется 20 битным вектором в реальной программе, так как АЦП 14 бит, было in1: in ineteger range -8192 to 8191; и МоделCим представил входные данные вектором из 8192+8191=16383 битов, хотя если смотреть RTL то там честные 14 бит складываются, сравниваются, на выход подаются... если я напишу in1: in signed range -8192 to 8191; это поможет? или это неисправимый косяк ModelSimа? 2. я сделал примеры с := и с <=. И из них я понял что первый работает только с переменными, второй только с сигналами. И применение <= равносильно физическому соединению сигналов, как бы проводками, а := соответствует как бы описанию того что чему равно, и соответственно объединяется в случае если а:=b, b:=c, в итоге за один такт получаем и a и b оба ровны c нюансы применения <= понятны a <= c and b and d сделает общее присвоение a1 <= c and b a2<= a1 and d последовательное, с промежуточной защелкой результата в a2 (я имею ввиду если повесить на event клока, иначе разница будет только на время распространения сигнала и работы логики) в случае := a1 := c and b a2 := a1 and d получаем равносильную запись с сигналами a <= c and b and d а как сделать последовательную, такую как a1 <= c and b a2<= a1 and d или с переменными это невозможно? И последние что пришло мне на ум. Всегда ли записи вида If clk=’1’ and clk’event then a1 <= in1 a2<= a1 a3<= a2 … end if; будут работать как FIFO, и последовательно продвигать значения in1 по списку? Или может быть гонка сигналов, и потери некоторых значений… если будут потери, как детерминировать этот процесс? очень понравилось - http://www.eng.auburn.edu/department/ee/mgc/vhdl.html, позволит быстро доделать проект спасибо
  10. 1. Спасибо, именно так я и понял. И если я правильно понял varibal integer и unsigned iteger - синтезируемые и в принципе локальный аналог сигнала. А какие еще типы синтезируемые?... 2. Получается это эквивалентные записи просто для разных типов? Я читал про последовательное блокирующие присвоение, и вроде как = - было блокирующие. Я так понял что <= просто привязать одно к другому сигналом... тут у меня пока путаница, пример и разницу в конструкции я видел, можно ли примеры когда целесообразно это применять... и если это просто эквивалентные записи как тогда с помощью <= реализовать signal a_out: std_logic_vector(1 downto 0) :="00"; signal b_out: std_logic_vector(1 downto 0) :="00"; process (clk) begin if clk='1' and clk'event then a_out<=b and c; b_out<=a_out and d; end if; end process; в этой конструкции как я понимаю с каждым клоком на б_оут будет защелкиваться то что было на a_out and d, a на a_out защелкиваться b and c. то есть аналоги FIFO 3, 6. АЦП выдает в стандартном знаковом формате, просто 14 бит. У меня стояла задача сравнения и вычитания и я присваивал эти значения сигналам, чтобы логика сравнения работала верно перевел данные в без знаковый формат с нулем по середине... Использование integer я думаю такое как я описал в пункте 6. Но там у меня возникает следующая проблема в описании входов стоит, например, in1 :in ineteger range -10 to 10; почему то в ModelSimе это представляется 20 битным вектором, не представляю как бороться... 4. понятно 5.понятно, а зачем используются не синтезируемые конструкции на практике? в исследовательских целях и удобства симуляции? или есть какой-то еще смысл? большое спасибо за литературу, я сейчас читаю VHDL - язык описания электронной аппаратуры, Яицкого и Шабанова, и подозревал что это не очень хорошая книга, теперь понимаю что так оно и есть... почитаю предложенные вами.
  11. Начинаю работу с ПЛИС и VHDL. Имею несколько непонятностей. Часть вопросов будет совсем детской, но очень хочется разобраться. 1. Имеет ли смысл в VHDL типы variable и записи на подобии after 10 ns для синтезируемых прошивок ПЛИС, или это общие расширения языка? Может всегда надо использовать сигналы? потому что как применять переменны типа файл и флоат я вообще не представляю. А задержки присвоений сигналов были проигнорированы синтезатором если я правильно его понял. 2. Мне VHDL не дает применять знаки := ни с чем кроме переменных, имеет ли смысл применять := в законченных устройствах, или при грамотном написании все можно сделать и с помощью <=. Если можно приведите пример где грамотней было бы использовать := а не <= если такие есть. 3. Первый проект это фазовый дискриминатор, и ПЛИС считывает данные с 14 битной полярной АЦП, я сразу добавлением 0x2000 перевел числа из диапазона -8192..8191 в диапазон 0..16383, для простоты сложения и вычитания... стоит ли это делать или лучше было бы как-то рассказать VHDLу что это знаковые числа? Как? 4. Имеет ли смысл реализовывать деление на ПЛИС или лучше отдать это внешнему ДСП, я имею в виду, сколько тратят тактов уже написанные модули деления, и будет ли выигрыш их применения, если необходимо делать всего 2 редких деления. 5. generic – что это с точки зрения уже законченного устройства? Набор управляющих констант, или набор ограничений для последующего использования данного модуля? Если можно примеры как вы используете generic 6. Теперь вопрос уже по среде. ПЛИС xilinx spartan 3. среда разработки ихняя ISE 7.1. Пытался реализовать второй вариант со знаковым считыванием данных АЦП, написал entity int_test is Port ( clk : in std_logic; rst :in std_logic; in1 : in integer range -8192 to 8191; in2 : in integer range -8192 to 8191; out1 : out integer range -16384 to 16383; max1 : out integer range -8192 to 8191); end int_test; architecture Behavioral of int_test is signal MaxValue : integer range -8192 to 8191 :=-8192; begin process (clk) begin if clk='1' and clk'event then out1<=in1+in2; if rst='0' then if MaxValue<in1 then MaxValue<=in1; end if; else MaxValue<=-8192; end if; end if; end process; max1<=MaxValue; end Behavioral; Синтезированная схема меня удовлетворила по виду. Но когда я попробовал промоделить, ModelSim сделал все входные сигналы по 16К бит, как будто это логические вектора с таким диапазоном индексов... это мой косяк или ModelSimа. Как вы решаете эту проблему, пока я не представляю себе возможность описать серьезное устройство без проверок в симуляторе. Еще раз извиняюсь за детские вопросы, буду рад услышать на них ответы...
×
×
  • Создать...