Тишинуша Гамимеря (spamsink) wrote,
Тишинуша Гамимеря
spamsink

Особенности национальной работы

Или "гладко было на бумаге, да забыли про овраги".



Языки описания логических схем, например, Verilog или VHDL, основаны на возможности записывать асинхронные процессы, активирующиеся по изменению значений переменных.
Например, если нужно, чтобы что-то происходило по переднему фронту сигнала clock, так и пишем: always @(posedge clock) begin ... end. Если нужно, чтобы значение переменной перевычислялось каждый раз, когда изменяется любая из переменных, входящая в выражение, пишем, например, так: assign var = expression; или так: always @* begin ... end. Здесь @* означает "если какая-нибудь из переменных, упомянутых внутри блока c целью прочитать ее значение, изменится, выполнить блок".

Теперь, допустим, у нас есть элемент асинхронной памяти, активной не по фронту, а по уровню разрешения на запись, т.е. всегда, когда сигнал разрешения на запись равен 1, реализованный как
always @*
    if (write_enable) mem[address] = data;
Что произойдет, если в какой-то момент write_enable равно единице, а переменная address изменится? Активируется этот процесс, и запишет текущее значение data в ячейку памяти по адресу, соответствующему новому значению переменной address. С точки зрения софтверного симулятора языка Verilog или VHDL - ровно в одну ячейку.

Подумаем, как бы эта память была реализована в хардвере. Слегка упрощая, у каждой ячейки будет свой блок логических элементов, побитно сравнивающих входящий адрес с ее собственным и делающих логическое И результата сравнения c сигналом write_enable, чтобы понять, надо записывать в себя входящие данные или нет.
И если address меняется, скажем, с 1 (...001) на 2 (...010), а проводочки для разных бит чуть-чуть разной длины, то может случиться краткий миг, когда сочетание значений бит будет или ...000, или ...011, и ячейка с адресом 0 или 3 решит в себя что-нибудь записать, совершив тем самым неприемлемое самоуправство.
Бороться с этим в хардвере очень просто - достаточно перед изменением значения переменной address установить сигнал write_enable в 0, а после изменения адреса выждать время, достаточное для нивелировки разницы времени распространения сигнала по отдельным битам адреса, после чего установить write_enable в 1.
А вот бороться с непониманием этого отличия софтверной симуляции от хардвера в головах отдельных инженеров гораздо труднее. Я уже второй день мучаюсь.
Subscribe

  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 30 comments