SM 13 February 4, 2014 Posted February 4, 2014 · Report post Ставится RC цепочка которая выполняет временную задержку? Я к тому что мне интересно как это реализуется в ASIC. Желательно по подробнее. Ставится источник опорного напряжения, компаратор(или несколько), и RC-генератор. Компараторы проверяют, достигли ли напряжения питания достаточных уровней, и когда достигли - разрешают счет счетчику (а точнее, снимают с него его асинхронный сброс), который тактируется от внутреннего генератора. Схема генератора такова, что когда напряжения питаний достигли заданных порогов, то генератор гарантировано генерирует корректные импульсы. Счетчик считает, пока его старший бит равен нулю. Как только он стал единицей - счет останавливается. Выход сброса - активный низкий - старший бит счетчика. Ну, это не догма конечно, а пример реализации (реальный, из реальных микросхем). Quote Share this post Link to post Share on other sites More sharing options...
Jackov 2 February 4, 2014 Posted February 4, 2014 · Report post Ставится источник опорного напряжения, компаратор(или несколько), и RC-генератор. Кажется это и называется супервизор http://radio-hobby.org/modules/news/article.php?storyid=1354 рис. 12 Quote Share this post Link to post Share on other sites More sharing options...
Golikov 0 February 4, 2014 Posted February 4, 2014 · Report post Ну вот не дали испортить человека, наговорили ему всякого заранее... У меня есть некая теория подтвержденная практикой, которую старая школа не приемлет. Касается она именно ПЛИС, в АСИКи я не лезу, ни разу не делал для них ничего, это к SM, он в них мастер. Так вот моя теория гласит что иногда пофиг как оно там реализовано, аргументы не буду приводить, если хотите пишите в личку, а то я слишкмо уважаю SM чтобы доставлять ему такой стресс) пусть у нас есть ПЛИС, и у нее есть входной клок CLK. берем такую конструкцию reg [3:0] Counter = 15; wire RESET; assign RESET = (Counter !=0) ? 1 : 0; always @(posedge CLK) begin if(Counter != 0) Counter <= Counter - 1; end я утверждаю, что совершенно не важно как построена плис, какие там схемы, триггера, и технологии, в какое состояние перейдут и какие триггеры после загрузки. Синтезатор из этого описания сделает схему, которая загрузится, и выдаст сигнал ресет равный 1, отсчитает 16 клоков, и выдаст на ресет равный 0. Значение счетчика можно варьировать, можно считать от 0 до 15. Но как бы то ни было, эта схемка вам создаст 15 клоковый сигнал ресета. Дальше вы можете писать свои конечные автоматы вида always @(posedge CLK) begin if (RESET == 1) State <= IDLE; else case(State) IDLE: State <= ST_1; ST_1: State <= ST_2; ST_2: State <= IDLE; endcase; end подключив его к 1 схеме, ваш автомат ресетнется после старта, придет в начальное состояние, и через 16 клоков пойдет молотить. Если у вас есть какая-то внешняя среда, у меня процессор АРМ, например подключен к ПЛИС. Тогда можно в ПЛИС сделать регистр, изменяемый этой внешней средой, которая выдает ресеты модулям. Но тут надо быть осторожным. Ибо есть такая штука как метастабильность, про нее есть много теории и описания, про сигналы, про триггер в неустойчивом равновесии, но я всегда выступаю за практику, и думаю легче всего понять на примере чем оно грозит, дальше будет не столько про метастабильность, сколько про близкие эффекты по теме. 1. распространение сигнала пусть у вас внешний сигнал ext_reset вы хотите завести его на ресет двух конечных автоматов и пишите always @(posedge CLK) if(ext_reset == 1) ESM_1 <= IDLE; always @(posedge CLK) if(ext_reset == 1) ESM_2 <= IDLE; вы думаете что ваши 2 автомата сбросятся одновременно, как только кто-то нажмет кнопку. Но главная засада ПЛИС, что это не хорошая программа, а плохой и злой кристал:))) и элемент который физически запоминает состояние ESM_2 и ESM_1 могут быть на разном растоянии от входа сигнала ext_reset. И этот сигнал до одного из них будет идти дольше чем до другого. И что может быть? Если сигнал будет очень близко к фронту, может так оказаться, что до одного он дойти успеет, а до другого нет, и вместо одновременного сброса будет сброс с разнице в 1 такт. 2. Восприятие сигнала вот вы допустим решили побороть проблему и делаете такую схему always @(posedge CLK) RESET <= ext_reset; always @(posedge CLK) if(RESET == 1) ESM_1 <= IDLE; always @(posedge CLK) if(RESET == 1) ESM_2 <= IDLE; казалось бы вот он успех. RESET защелкнет состояние, и оно всегда дойдет в одном виде до всех участников (плис умеет следить чтобы сигналы дошли до фронта клока). Но вот тут вторая засада плохого и злого кристала. представьте что вы нажали кнопку прям в момент CLK. И физический элемент который запоминает состояние RESET по CLK, поймал фронт когда на входе у него был фронт кнопки, то есть не 0 либо 1, а что-то среднее 0.5. И поскольку он есть схема из транзисторов, на выход он тоже выдаст что-то невразумительное. В большинстве случаев это невразумительное перейдет в 0 либо 1 уже к следующему такту, но при очень быстром клоке может и не успеть (или еще по каким то причинам SM может объяснить) и на ваши схемы придут RESET равный чему то среднему, не 0 либо 1. И поскольку принимающий элемент тоже какая-то схема, всегда есть шанс что один автомат воспримет это средние как 0, а другой как 1, и опять мы получим не синхронный уход в ресет. 3. И это мое любимое, ибо зная про это все равно наступил на эти грабли. ПЛИС делает все в параллель, но параллель эта условная, части схемы делающие действия могут быть в разных местах. я написал что-то типа always @(posedge CLK) begin if(( ext_reset == 1)&&(MY_OBRABOTALI_RESET == 0)) begin MY_OBRABOTALI_RESET <= 1; Counter <= 15; end end я хотел очень простую вещь, как только мы найдем ресет внешний, мы ставим флаг что мы его заметили и заряжаем счетчик. Флаг ставим чтобы счетчик зарядить 1 раз, по клоку как только мы увидим ресет. Но в этом жестоком и бездушном кристалле схема представлена 2 кусками 1. это установка флага MY_OBRABOTALI_RESET по условию (( ext_reset == 1)&&(MY_OBRABOTALI_RESET == 0)) 2. это зарядка счетчика Counter по условию (( ext_reset == 1)&&(MY_OBRABOTALI_RESET == 0)) и что как вы думаете случилось? Правильно, сигнал попал очень близко к фронту, и так получилось что до 1 куска условие выполнилось до клока, а для второго куска после, то есть фактически на следующем клоке. Но на следующем клоке условие уже не выполнялось, потому что 1 часть поставила флаг запрета условия... Вот тут я правда некоторое время был озадачен, флаг выставился - значит под if мы попали, так почему же не зарядился счетчик?! Вот теперь вы знаете все:) можете спокойно начинать делать взрослые проекты, чтобы SM не писал дальше:)))) но это только про ПЛИС, и если вам не жалко их ресурсов как мне;) теперь я одел кастрюлю на голову и готов слушать где как и почему я не прав от уважаемых гуру%)! желающие могут прям в личку писать:) Quote Share this post Link to post Share on other sites More sharing options...
SM 13 February 4, 2014 Posted February 4, 2014 · Report post Ну описали Вы верилогом схему формирования резета, которую я словами описал чуть выше - там , только заменив обнуление на инициализацию в 15 (что, кстати, не во всех ПЛИС прокатит, и не все синтезаторы съедят), вот так оно корректнее: reg [3:0] Counter = 15 /* synthesis INIT="SSSS" syn_preserve=1 */; upd: поясню - Synplify H-2003.03, например, съест "=15", а чуть более старая версия, скажет, что "не понимаю и игнорую =15", зато поймет аттрибут INIT. Докучи каким-то синтезаторам нужно в аттрибуте не S/R указывать, а 0/1, тоже может быть засада а чтобы на большем кол-ве видов ПЛИС оно работало, надо считать от нуля вверх, инициализировать нулем, так как не везде "power up high" имеется в распоряжении разработчика. но, в общем и целом, именно типа того и делают в ПЛИС. И, это, еще... С таким вот "assign rst = (Counter !=0) ? 1 : 0;" - на rst имеете шансы глитчи получить, это не всегда хорошо, в глобальную цепь сигнал с глитчами пускать, даже если он везде потом синхронно используется. Лучше "always @(posedge clk) rst <= (Counter !=0) ? 1 : 0;" Ну а присвоения одному и тому же регистру из разных always, так это вообще, тупо грубейшая ошибка начинающего, ругаемая синтезатором благими матюками, никакая кастрюля на голове не поможет. :) :) И Вы это еще и советуете... ERROR - CL172 :" ....... Only one always block can assign a given variable Counter[3:0] Quote Share this post Link to post Share on other sites More sharing options...
Pavia 0 February 4, 2014 Posted February 4, 2014 · Report post Вот тут я правда некоторое время был озадачен, флаг выставился - значит под if мы попали, так почему же не зарядился счетчик?! Вот теперь вы знаете все:) можете спокойно начинать делать взрослые проекты, чтобы SM не писал дальше:)))) но это только про ПЛИС, и если вам не жалко их ресурсов как мне;) теперь я одел кастрюлю на голову и готов слушать где как и почему я не прав от уважаемых гуру%)! желающие могут прям в личку писать:) Это называется нестабильностью. Вероятность такого события мола порядка 10^-6 для быстрых устройств применяют установку 2-х тригеров. Что соответственно возводит вероятность в квадрат 10^-12. Насколько понимаю увидеть эти два тригера можно в нетлисте. PS А испортить меня трудно. Я уже испорчен. Quote Share this post Link to post Share on other sites More sharing options...
Golikov 0 February 4, 2014 Posted February 4, 2014 · Report post а чтобы на большем кол-ве видов ПЛИС оно работало, надо считать от нуля вверх, инициализировать нулем, так как не везде "power up high" имеется в распоряжении разработчика. нюансы, придираетесь :), сравнение с нулем жрало меньше лутов, а сравнение на переход в отрицательное даже для огромных регистров еще меньше, потому предпочитают считать вниз. И ISE в котором работаю это поедает, но на случай универсальных модулей запомню спасибо. И, это, еще... С таким вот "assign rst = (Counter !=0) ? 1 : 0;" - на rst имеете шансы глитчи получить, это не всегда хорошо, в глобальную цепь сигнал с глитчами пускать, даже если он везде потом синхронно используется. Лучше "always @(posedge clk) rst <= (Counter !=0) ? 1 : 0;" на переходах разрядов? хм не думал об этом, но я обычно внутри такие сигналы синхронно использую, к фронту клока то всяко устоится, я надеюсь:) Ну а присвоения одному и тому же регистру из разных always, так это вообще, тупо грубейшая ошибка начинающего, ругаемая синтезатором благими матюками, никакая каска не поможет: :) :) ERROR - CL172 :" ....... Only one always block can assign a given variable Counter[3:0] а где я такое сделал? понятно дело что синтезатор на это ругнется. Правда меня это прям нервирует. Мне иногда для удобства восприятия хочется разбить большие always на 2 блока, а мне не дают:((... я тасками обхожусь, надеюсь они мне не испортят ничего. А может я типа НУБ и синтезатору можно как-то сказать что эти 2 блока суть один? на верилоге? Quote Share this post Link to post Share on other sites More sharing options...
SM 13 February 4, 2014 Posted February 4, 2014 · Report post а где я такое сделал? понятно дело что синтезатор на это ругнется. тут (сам Counter то описан был выше): always @(posedge CLK) begin if(( ext_reset == 1)&&(MY_OBRABOTALI_RESET == 0)) begin MY_OBRABOTALI_RESET <= 1; Counter <= 15; end end task это тоже по сути конструкция несинтезируемая, ее если и съест, то только квартус, и то не факт что корректно. По любому и всегда - один регистр (или несколько) должен быть описан полностью внутри одного always, и все тут. Иначе Вы описываете нечто физически непонятное, которое по одному клоку должно записать в регистр два разных значения, и какое из них верное, хрен его знает. Quote Share this post Link to post Share on other sites More sharing options...
Golikov 0 February 4, 2014 Posted February 4, 2014 · Report post Это называется нестабильностью. Вероятность такого события мола порядка 10^-6 ага а в моем случае - событие было чипселект SPI, который работал на 50 МГц, а тактовая плис основная была 100 МГц. Так вот на 2000 передач по SPI получал порядка нескольких сотен таких ошибок. Там были еще нюансы, с разводкой клока на не клоковый вход, так что я прям немного вспотел пока понял что не так) да, 2 триггера не то что уменьшат вероятность, они ее полностью исключат, в оригинальной схеме я перед принятием решения просто делал паузу в 2 клока, фактически тоже самое что сигнал пропустить через 2 триггера, но для читабельности так было лучше, а ЛУТы мне не жмут:) тут (сам Counter то описан был выше): always @(posedge CLK) begin if(( ext_reset == 1)&&(MY_OBRABOTALI_RESET == 0)) begin MY_OBRABOTALI_RESET <= 1; Counter <= 15; end end Все персонажи являются вымышленными, любые совпадения случайны. MY_OBRABOTALI_RESET - тогда вообще нигде не описан, это просто условный блок, для частоты можно считать что это Counter1. task это тоже по сути конструкция несинтезируемая, ее если и съест, то только квартус, и то не факт что корректно. АЙ!!! кастрюлка выручай!!! как так не синтезируемая? А я использую, и схема получается ISE ест спокойно. Вы меня растраиваете%(... как тогда делать такую фигню, допустим есть несколько состояний автомата, и в них надо сделать одно и тоже действие, что его копировать что ли везде, а потом поменять? Я был уверен что таск на то и служит. Переход с заданием флага, оформляем в такс, и нигде не забудем задать флаг. Большой блок текста плохо читаемый в основном always, выносим в таск, и все читабельно... че нельзя? а я делал! ну ёёёё моёёёёёё По любому и всегда - один регистр (или несколько) должен быть описан полностью внутри одного always, и все тут. Иначе Вы описываете нечто физически непонятное, которое по одному клоку должно записать в регистр два разных значения, и какое из них верное, хрен его знает. вот допустим есть куча регистров если условие А, они одному равны если условие В, они другому равны иногда хочется чтобы каждое условие было своей группой описано, ведь там часто ветвления и награмождения физически они могут быть под одним алвисом, но читать неудобно, а мне не разрешают:(... ну и описанные выше случаи. Quote Share this post Link to post Share on other sites More sharing options...
SM 13 February 4, 2014 Posted February 4, 2014 · Report post как тогда делать такую фигню, допустим есть несколько состояний автомата, и в них надо сделать одно и тоже действие, что его копировать что ли везде, а потом поменять? Я был уверен что таск на то и служит. Ну, например, как-то так написать: case () STATE_2, STATE_3, STATE_4, STATE_5: <действие> че нельзя? а я делал! ну ёёёё моёёёёёё Если затачивать весь свой текст под определенный синтезатор, можно, без проблем, только советовать всем это не нужно, вдруг они синтезируют чем-то другим. Хотя... Может тут я отстал от жизни, и сейчас уже и не осталось синтезаторов таких, которые task ругать будут. Такой вариант вполне возможен, потому что это мое высказывание базируется на знаниях о синтезаторах из начала 2000-ных. Под одним always сколько хотите регистров описывайте, нельзя один регистр на два always разбивать! Я тут вот про что, Вы пишете always @(posedge clk) if (a) r <= data; а реально физически это может быть: always @(posedge clk) if (a) r <= data; else r <= r; вот об этом нюансе надо не забывать. Quote Share this post Link to post Share on other sites More sharing options...
o_khavin 0 February 4, 2014 Posted February 4, 2014 · Report post Вторая ветка за последние дни улетела в ресето-флуд. :) Quote Share this post Link to post Share on other sites More sharing options...
Golikov 0 February 4, 2014 Posted February 4, 2014 · Report post карма... ладно я больше не буду;( почему ругается синтезатор понятно, просто хотелось бы от него чтобы он алвысы по одному и тому же сигналу объединял перед анализом, например... Может в будущем... такая конструкция case () STATE_2, STATE_3, STATE_4, STATE_5: <действие> не пойдет, у них есть общая часть, а в остальном они разные, и я общую часть в таск пихал... Quote Share this post Link to post Share on other sites More sharing options...
SM 13 February 4, 2014 Posted February 4, 2014 · Report post не пойдет, у них есть общая часть, а в остальном они разные, и я общую часть в таск пихал... Ну я образно же, можно, например, два case разных, один для общей части, или общую часть под IF, а разные части в другом case после (перед) этим. Варианты зависят от того, что там за схема... Тут ведь вот что еще будет - task по сути при синтезе, если синтезируется, то синтезируется в некую комбинационную схему, куча task-ов, в кучу копий таких схем, и не факт, что синтезатор сможет их потом правильно соптимизировать в части resource sharing (если он вообще в опциях разрешен!!!), чем если сразу описать эту логику более компактным условием каким-то. Кстати, о птичках, вот вам вместо двух always сделайте в одном begin ... end да и пишите там блоки под разными условиями подряд, будет то, что Вы хотите из двух разных always, но по правилам синтезируемости, и читаемость не пострадает никак. always @(posedge clk) begin if (условие_a) begin end if (условие_b) begin end end Quote Share this post Link to post Share on other sites More sharing options...
Pavia 0 February 5, 2014 Posted February 5, 2014 · Report post Так как про ресет никто толком из специалистов не рассказал. Пришлось рыть самому. Из достоверных фактов нашел только для процессора 8086 где сброс происходит на 3 такте после подачи питания. http://portal.tpu.ru/SHARED/a/ALKHIMOV/Tab/ch3.doc Управляет этим микросхема 8284 видимо нечто подобное есть и в современных микропроцессорах. Что касается ПЛИС то там начальное значение регистров можно задать. Quote Share this post Link to post Share on other sites More sharing options...
SM 13 February 5, 2014 Posted February 5, 2014 · Report post Так как про ресет никто толком из специалистов не рассказал. А что Вы хотели-то? Описания словами мало? Надо конкретно топологию и схематику этого блока из какого нибудь ASIC что ли? Так никто не даст, это денег стоит. Quote Share this post Link to post Share on other sites More sharing options...
Golikov 0 February 6, 2014 Posted February 6, 2014 · Report post а че я писал буквы?.... по моему конкретный вариант ресета с задержкой предложил. Quote Share this post Link to post Share on other sites More sharing options...