2013-07-01 3 views
0

Я хотел бы создать простой код Verilog, который содержит два всегда блока, исполняемых в качестве альтернативы, например, рукопожатие. Я хочу использовать два флага do_A и do_B для управления двумя блоками block_A и block_B. Ожидаемый результат должен быть ABABAB ... Есть ли способ исправить следующий код? Спасибо за помощь.Как чередовать два всегда блока?

module tb; 
    reg clock, reset, do_A, do_B; 

    initial begin clock = 0; reset = 0; #50; reset = 150; #50; reset = 0; end 
    always #50 clock = ~clock; 

    always @(posedge clock) begin: block_A 
     if (reset) do_B <= 0; 
     else if (do_A) begin 
      do_B <= 0; 
      $display("A"); 
     end 
    end 

    always @(posedge clock) begin:block_B 
     if (reset) do_A <= 1; 
     else if (do_B) begin 
      do_A <= 0; 
      $display("B"); 
     end 
    end 
endmodule 

Спасибо Vesiliy, следующие коды хорошо подходят для желаемых результатов.

always @(posedge clock) begin: Block_A 
     if (reset) do_B = 0; 
     else if (do_A) begin 
      do_B = 0; 
      $display("A"); 
     end 
     else do_B <= 1; 
    end 

    always @(posedge clock) begin:Block_B 
     if (reset) do_A = 1; 
     else if (do_B) begin 
      do_A = 1; 
      $display("B"); 
     end 
     else do_A <= 0; 

Это кажется странным, но хорошо работает.

ответ

2

Прежде всего reset = 150; выглядит странно (опечатка?). Однако он работает в этом контексте.

Вы еще опечатка в первом последовательном always - то, что вы (казалось бы) хотел написать это:

else if (do_A) begin 
    do_B <= 1; 
    $display("A"); 
end 

Однако, я считаю, что ваш главный вопрос здесь в том, что вы не имеете else (по умолчанию) в ваших последовательных блоках always.

Посмотрите на этом блоке (например):

always @(posedge clock) begin:block_B 
    if (reset) do_A <= 1; 
    else if (do_B) begin 
     do_A <= 0; 
     $display("B"); 
    end 
end 

После сброса сбрасывается do_A = 1; то, предположив, что вы исправили предыдущую опечатку, do_B станет 1, что приведет к do_A, ставшему 0. После достижения этого состояния do_A застрянет в 0, пока вы не сбросите все.

Следующее дополнение это исправить (то же самое для первого always блока):

always @(posedge clock) begin:block_B 
    if (reset) do_A <= 1; 
    else if (do_B) begin 
     do_A <= 0; 
     $display("B"); 
    end 
    else do_A <= 1; 
end 

Я считаю, что ваш код с вышеперечисленными исправлениями будет работать, однако, правильный способ описать эту функцию, чтобы реализовать (простое) состояние-машина с двумя состояниями. Погугли это.

+0

Спасибо Vasiliy. Следуя вашему предложению, я изменил код и протестировал, получив последовательность ABAB .... – gnoejh

+0

Нет проблем. Вы должны принять ответ. – Vasiliy