Блокирующие и неблокирующие присваивания в Verilog. Часть Вторая, внезапная.

Постигая ужасы метастабильности и присваиваний, иногда не можешь сделать самого простого - правильно сосчитать какие-нибудь простенькие входящие данные из UART. Особенность моего нынешнего проекта в том, что я точно знаю в каком месте входящего потока какие данные лежат, и мне надо эти самые данные перераспределить.

Итак имеем состояние, в котором считаем входящие байты по фронту стоп-бита UART, и в зависимости от номера - делаем с ним что-то. Повторяем операцию каждые четыре байта. Всё просто, пишем:
после чего пишем обработчик каждого из четырёх входящих битов, case (oneWrd) но получаем смещение на один байт в самом начале передачи. Обратимся к осциллограмме:

И правда, видим, что до четырёх мы досчитали уже на стоп-бите третьего байта. Меняем:

Теперь, предполагаем, что присваивание выполнится "параллельно", и смотрим в осциллограф:

Ай, да мы, ай, да молодцы.

Итак, почему-же  это происходит? Всё дело в тактовом сигнале. На момент наступления условия, прописанного в скобках строки always@(...) begin будь то фронт или срез тактового сигнала, ПЛИС помнит все значения, содержащиеся внутри этого блока. И в один момент присваивает всем левым частям все правые части. Так происходит с неблокирующими (<=) присваиваниями. Блокирующие-же выполняются в том порядке, в каком стоят в коде. То есть, в моём случае, описанном выше, ПЛИС сначала присвоила переменной oneWrd значение содержащееся в тернарной операции, а потом, пошла пересчитывать значения в обработчике. с уже новым oneWrd. Это может и создаёт путаницу у начинающих заниматься цифровой схемотехникой и описанием цифровых схем, поэтому от блокирующих присваиваний на первых порах лучше отказаться, как бы "похожи на обычное программирование" они не были.