SystemVerilog микширование неблокирующих и блокирующих назначений для арбитра

Я не могу обернуться вокруг примера 10-3 в книге Стюарта Сазерленда (и соавторов) SystemVerilog For Design.

Смотрите строку 232 из:

https://code.google.com/p/vak-opensource/source/browse/trunk/hardware/systemverilog/utopia-example/squat.sv?r=185

Вот фрагмент кода. Мой вопрос будет следовать.

  bit [0:NumRx-1] RoundRobin;

  always_ff @(posedge clk, posedge reset) begin: FSM
    bit breakVar;
    if (reset) begin: reset_logic
      Rxready <= '1;
      Txvalid <= '0;
      Txsel_out <= '0;
      SquatState <= wait_rx_valid;
      forward <= 0;
      RoundRobin = 1;
    end: reset_logic
    else begin: FSM_sequencer
      unique case (SquatState)

        wait_rx_valid: begin: rx_valid_state
          Rxready <= '1;
          breakVar = 1;
          for (int j=0; j<NumRx; j+=1) begin: loop1
            for (int i=0; i<NumRx; i+=1) begin: loop2
              if (Rxvalid[i] && RoundRobin[i] && breakVar)
                begin: match
                  ATMcell <= RxATMcell[i];
                  Rxready[i] <= 0;
                  SquatState <= wait_rx_not_valid;
                  breakVar = 0;
                end: match
            end: loop2
            if (breakVar)
              RoundRobin={RoundRobin[1:$bits(RoundRobin)-1],
                          RoundRobin[0]};
          end: loop1
        end: rx_valid_state

В частности, мой вопрос о назначении блокировки для breakVar и RoundRobin. Я где-то читал, что переменные оцениваются локально, но я не могу представить в терминах Гейтса, как синтезируется логика. Входит ли RoundRobin в государственный реестр?

В большинстве руководств говорится, что никогда нельзя смешивать блокирующие и неблокирующие назначения. Есть ли лучший способ представить что-то вроде этого. Можно ли теперь в SV-Design смешивать оба типа присвоений, учитывая, что это блок Always_ff?

2 ответа

Никогда не следует смешивать блокирующие и неблокирующие назначения для одной и той же переменной. breakVar является временной переменной, которая будет синтезирована в комбинаторную логику, потому что она всегда записывается сначала, а затем читается. Нет состояния для сохранения. RoundRobin является локальной переменной, которая используется как промежуточная переменная и переменная состояния. Но поскольку доступ к нему осуществляется только из блока Always_ff, опасность возникновения гонки отсутствует.

В старые добрые времена было плохо смешивать блокирующие и неблокирующие назначения в одном и том же блоке процесса, потому что разные инструменты были несовместимы в том, как они планировали эти операции.

Новая спецификация SystemVerilog гораздо точнее о том, как упорядочить обработку этих событий, поэтому теперь можно смешивать блокирующие и неблокирующие назначения, поскольку инструменты теперь будут согласованными. Тем не мение:

  1. Вы будете писать непонятный и сложный в обслуживании код, который заставит людей, которые смотрят на него, задавать вопросы по stackru.

  2. Вы разозлите каждого разработчика RTL с более чем 10-летним опытом. После того, как вы были сожжены несоответствием симулятора / синтезатора, вы развиваете компульсивное отвращение к оскорбительному стилю кодирования.

Мое эмпирическое правило таково: если логика не тривиальна, выполняйте всю сложную работу в блоке always_comb, используя только блокирующие назначения. Все знают, как читать последовательный код, его можно обслуживать, и никто не будет смущен этим. Используйте отдельный процесс always_ff, чтобы ничего не делать, кроме как фиксировать переменные следующего состояния в переменные текущего состояния.

Полностью согласен с ответом Jonathan Mayer.

Вы всегда должны разделять свои логические элементы на блок always_comb и последовательные элементы в блок always_ff.

  • Если вы пишете код, который так тесно сшит вместе (как комбинированные, так и последовательные элементы в одном блоке), даже если он правильный и соответствует спецификации system verilog, некоторые старые версии симулятора или новые разрабатываемые имитаторы могут сделать вывод о нем неверно.

  • Ваш код не будет чистым и понятным для других.

  • Также, написав в стиле выше, вы просто уплотняете строки кода, хотя логика остается той же. Нет смысла писать компактный код, если он мешает читаемости кода.

Что касается использования блокирующих и неблокирующих операторов, я думаю, что дискуссия закрыта. Теперь использование блокирующих операторов в блоке always_comb и неблокирующих операторов в блоке always_ff является больше правилом, чем рекомендацией.

Однако ответы на все ваши вопросы объясняются в этой превосходной статье Клиффорда Э. Каммингса. Неблокирующие присваивания в Verilog Synthesis, Coding Styles That Kill!

И если вы новичок в дизайне verilog/system verilog, я предлагаю вам прочитать все их статьи. Они очень полезны и создают хорошую основу для инженера-проектировщика RTL.

Также может быть слишком много рассказывать здесь, но если вы ищете, как разделить свой код на комбинированный и последовательный блок, вы можете взглянуть на код, сгенерированный bluespec.

Названия сигналов трудно понять за один раз, но если вы внимательно посмотрите, код очень логичен и не оставляет ничего на прихоти инструментов моделирования и синтеза.

Другие вопросы по тегам