Естественно, не вообще 1е, а после долгого перерыва. Фирма aeronautics-sys, точнее, их хеврат-бат. Явне - надо будет переезжать. Должность - FPGA Engineer - не знаком. Есть сивуг битхони, а у меня отец в России. Короче, все не знакомо, шансов очень мало, придется поднапрячься, но профукать не жалко - идеально для тренировочного интервью :) Дальше - сплошная
электроника.
Разминаемся красненьким:
Есть ADC с параллельным выходом. Но 1 бит (MSB) все время = 0. На входе синусоида. Что на выходе графически (если, например, выход подсоединен ко входу DAC)?
Спрашиваю, нет ли пост. составляющей? Предположим, что нет. Тогда MSB это sign bit. Мучительно вспоминаю, как выглядят 2's compliment. Для простоты предполагаю, что у нас есть 2 рабочих бита (не считая sign bit). Тогда верхняя половина синусоиды идет по порядку возрастания 000,001,010,011; а нижняя по порядку убывания - 000,111,110,101. Если 1й бит всегда =0, то верхняя половина синусоиды останется неизменной, а нижняя поднимется так, что макушкой дотронется до 0 (при достаточно большом числе битов).
ОК, чтобы жизнь медом не казалась - синусоида сдвинута так, что проходит через числа от 0 до максимума. Т.е. "ось" приходится примерно на 1/2 максимума.
Аналогично получаем, что верхняя половинка синусоиды опустится так, что макушкой коснется оси.
Имплементируй каунтер на 3 бита. Ну, 3 D-flipflops, adder, и обратно на вход. Сделай эддер. Сделал ripple-carry, рассказал про carry look-ahead. В чем недостатки ripple-carry? Обьяснил. Сделай carry look-ahead. Изобразил упрощенный, с учетом того, что инкремент = 1. Так и не понял, удовлетворился он или нет.
Следующая позиция. Как работает UART? (Блин, мужик, ты бы еще про телефон Белла спросил :)
К сожалению, мне не приходилось с ним сталкиваться ни по работе, ни по жизни. Вероятно, это некий сериальный протокол? Да. Как там происходит синхронизация клоков передатчика и приемника? Не знаю, но это можно сделать, например, с помощью управляющих сигналов: read, write и т.д. А нэту! Как нету - в обычном компе коннектор UART, кажется, имеет 9 пинов? что, сплошная земля??? А вот нету и все! ОК, тогда синхронизацию можно осуществить так, как это делается в USB: 1 - пост. уровень напр-я, 0 - изменение. И передавать группами, напрмер, по 8бит и к ним добавлять 0 для синхронизации. Хорошо, но у тебя нет опции играться с уровнем сигнала: 0 - это 0, 1 - это Vcc. Tri-state? Тоже нету. (Мужик, ты за меня или за медведя? :) Тогда ничего не поделаешь, надо периодически передавать некую последовательность битов, которая не встречается в данных. Все последовательности встречаются. Нет, не все: если, например, данные передаются по 8 бит, то последовательность из 9 или более не встретится. Правда, это означает, что эффективная передача данных будет занимать < 1/2 времени работы баса. Передавать можно, например, 000000001 и по переходу 0-1 синхронизировать. Да, так он и работает, только последовательность 111111110. (Ура, я изобрел велосипед!)
Продолжаем. Ну есть у тебя этот переход. Как ты клок-то синхронизировать будешь? С помощью PLL. А нэту! (№*!*!) ОК, если это реальный дизайн, то там наверняка есть быстрый клок, с помощью которого можно просто подсчитать разницу фаз, ну и сделать новый клок, сдвинутый. Во сколько раз быстрее д.б. клок? Получилось, что в 3 достаточно. Оказалось, что в реальном UARTе - в 5.
ОК, теперь реальный вопрос, из жизни. Есть передатчик и приемник RF. Передаются пакеты по 1000 бит, серийно. Как можно синхронизировать начало пакета?
Ну, в сотовой телефонии используются бакены - сигналы синхронизации на дополнительной частоте. Нету дополнительной. Методами RF можно передать некий сигнал в дополнение к обычным на почти той же частоте. Нету RF, все, что есть - 1 дигитальная линия. Допустимо ли, как в UARTе, сделать сигналы синхронизации длиннее пакета? Нет. Есть ли такие последовательности битов, которые не встречаются в данных? Нет. Ладно, Чапай думать будет.
Можно сделать так: передается к.-то хеадер перед началом пакета и тейлор в конце. Тогда синхронизация происходит так: распознаем хеадер и ждем время, соответствующее длине пакета (данные при этом пишутся в память - в shift register 1000+ бит длины). Если через 1000 битов мы получили тейлор, то у нас есть в регистре весь пакет. Если нет, то мы приняли за хедер соответсвующую последовательность битов в теле пакета. Продолжаем ждать, пока хедер не появится снова. При этом существует вероятность того, что внутри пакетов встретится и хедер, и тейлор ровно через 1000 битов после него, но вероятность этого исчезающе мала. И некоторые пакеты окажутся выброшенными, но с этим можно справится (передать еще раз).
Да, я примерно так и сделал (Уррррряяаа!)
Следующий вопрос. Данные передаются с ошибками - помехи, то-се... Как теперь распознать хеадер?
Начинаю судорожно вспоминать error-detection and error-correction codes. Честно признаюсь, что не касался этого с курса Маарахот Сифратиет, который слушал в 1997г. Даю интуитивные примеры bit redundancy. ОК, у тебя есть хеадер длиной 32 бита. Допустимо, чтобы N битов пришли с искажениями. Как определить оптимальное N? Вот тебе, мужик, питарон мааси: поднимаю телефон и звоню приятелю с PhD, мумхе в хекер бицуим. Он как раз этим занимается, а я, уж извини, электроникой. Но формулу для такой вероятности я изобразил, хотя и со скрипом.
Ладно. Имплементируй систему распознования хедера, который пришел с <=N ошибками.
И тут меня переклинило. Блин, 3+ часа тут сижу, уже голова ни хера не варит! Предложил даже look-up table, но потом сообразил, что 4Г памяти - это перебор :) В общем, выдал, но со скрипом. Очень просто оказалось: есть эталонное число в регистре, есть шифт регистр, в котором все время ползут данные, и между ними - 32 ксора (побитно). И считаем кол-во единиц на выходе ксоров. Если <=N - поймали хеадер, а нет, так продолжаем.
Правильно. Теперь напиши это на VHDL. Синтаксис меня не волнует
Я выдал примерно следующее:
if (clk'event and clk = 1)
sum=0;
for (i=0, i<32, i++)
inc = sh_r(i) xor good(i); --- bitwise; should be completed within 1 clk
sum = sum+inc;
if sum <= N
out <= '1'; -- header recognised. Start waiting 1000 clks for tailer
else
out <= '0'; -- not header
sh_r(31 downto 0) <= sh_r(30 downto 0) & in; -- next bit comes to shift reg
end
(Мужик, ты сам сказал, что синтаксис тебя не волнует!)
Он начал распрашивать про типы переменных и я откровенно поплыл. Он сказал, что видит, что я давно не писал на VHDL. Пришлось подтвердить :)
Тахлес: хорошее интервью, интересные вопросы. Но мы оба затрахались по самое немогу: началось все в 16.00, закончилось ок. 19.30. В конце он откровенно скучал, а я мог бы выдать больше, если бы не так устал.
Кроме того, если сначала я держался вполне уверенно, то потом, по мере "плаванья", эту уверенность подрастерял. Не хорошо: совершенно нормально, что на интервью человека доводят до пределов его возможностей и уводят за них. Это не повод для неуверенности в себе.
В любом случае, неплохое начало. Если бы еще приглашали почаще :)