Golikov 0 21 февраля, 2006 Опубликовано 21 февраля, 2006 · Жалоба Боролся долго с 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 сбрасывает сигнал наличия данных... мне казалось что такая логика наиболее безопасна и детерминирована... очень хочется услышать ваши комментарии по возможным ошибкам... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
makc 198 21 февраля, 2006 Опубликовано 21 февраля, 2006 · Жалоба Если вы работаете с числами и операциями над ними, то signed и unsigned имеют для Вас смысл. Если нет, то Вам будет достаточно std_logic_vector. В вашем первом примере Вы ошибочно включили numeric_std, тогда как он не может быть включен вместе с std_logic_*. Т.е. если вы поставите только library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; то все будет нормально моделироваться. ВАШ ОТВЕТ МЕНЯ ОЗАДАЧИЛ я как раз думал что если ввести один общий синхронизирующий сигнал в моем случае 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 сбрасывает сигнал наличия данных... Это-то понятно. :) мне казалось что такая логика наиболее безопасна и детерминирована... очень хочется услышать ваши комментарии по возможным ошибкам... Только если один тактовый сигнал. Если несколько или есть основной периодический тактовый сигнал, то лучше использовать другую логику работу (по основному тактовому сигналу). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 22 февраля, 2006 Опубликовано 22 февраля, 2006 (изменено) · Жалоба библиотеку нумерик я добавил уже от отчаяния... этот проект у меня не симулится хоть умри.... и как вы говорите тоже не симулится... может надо среду менять.. у меня ксалинский проек навигатор 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 и пропустить данные, чего бы не хотелось… частоты близки и не кратны... Изменено 22 февраля, 2006 пользователем Golikov A. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 22 февраля, 2006 Опубликовано 22 февраля, 2006 (изменено) · Жалоба а вот я подумал... если я поставлю 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 триггеров, с общим клоком, то на каждый фронт будет происходит сдвиг данных как в сдвиговом регистре? А не может так получится, что в какой-то из защелок будет сохранен переходной процесс с прошлой? Как-то раньше этот вопрос у меня не возникал, а теперь я не понимаю как это работает:)... Изменено 22 февраля, 2006 пользователем Golikov A. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Kyle 0 22 февраля, 2006 Опубликовано 22 февраля, 2006 · Жалоба по идее рассинхрона не будет, так?... то есть нет шанса что в b защелкнется переходной процесс из a? Насколько я понял частоты похожы, но немного оличаются? если да, то b может защелкнутся в переходной процесс a! и ещё, проще использовать конструкцию: If rising_edge(CLK) Then вместо If CLK = '1' and CLK'event Then а если нужен спад, то falling_edge(CLK) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 22 февраля, 2006 Опубликовано 22 февраля, 2006 (изменено) · Жалоба не ну не настолько близко... 67 и 100 МГц. мне кажется что если поставить защелки на выходе сигналов, которые бы по поднятому сигналу и основному клоку пропускали, в противном случае хранили то все проблемы были бы решены... как мне кажется... все изменения могут быть только по фронту основного клока, и для дальнейшей схемы все будет синхронно... Единственное волнует переходной процесс открывающейся latch, но можно открывать ее по падающему фронту и тогда к восходящему все будет ок! Или так не делают? Изменено 22 февраля, 2006 пользователем Golikov A. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться