Модуль Verilog не вызывается

#verilog #icarus

Вопрос:

Я работаю над программой, которая будет принимать значение в BCD, преобразовывать его в двоичный код и вести обратный отсчет для данного значения до 0. Модуль преобразования BCD работает отлично, но, похоже, мой «микроволновый» модуль не вызывается.

Мой результат этой программы таков:

 time = xxxxxxxx bcdtime = 0001 0010

time = 00001100 bcdtime = 0001 0010
 

Я вижу преобразование, но обратный отсчет не происходит. Может ли кто-нибудь объяснить, где я могу ошибаться, или указать мне направление ресурсов, которые могли бы помочь мне ответить на этот вопрос? Мой код приведен ниже:

 module bcd_to_bin(bintime,bcdtime1,bcdtime0);
  input [3:0] bcdtime1,bcdtime0;
  output [7:0] bintime;

  assign bintime = (bcdtime1 * 4'b1010)   {3'b0, bcdtime0};
endmodule

module microwave(bintimeout, Clk, Start, Stop, bintime, status);
    input [7:0] bintime;
    input Clk, Start, Stop;
    output reg [7:0] bintimeout;
    output reg status;
    
    
 always @ (posedge Start)
    begin
        assign bintimeout = bintime;
    end 
    
 always @ (posedge Clk)

  begin 
    bintimeout = bintimeout - 1;
  end
endmodule


module t_microwave;

    wire status;
    wire [7:0] bintimeout;
    reg Clk=1; reg Start, Stop;
    reg [3:0] bcdtime1, bcdtime0;
    wire [7:0] bintime;
    
    microwave M2 (bintimeout, Clk, Start, Stop, bintime, status);
    bcd_to_bin M3 (bintime,bcdtime1,bcdtime0);
    
    
    
     always #10 Clk = ~Clk;
    initial
      begin
        
        Start = 0; Stop = 0; bcdtime1 = 4'b0001; bcdtime0 = 4'b0010;
        #10 Start = 1; #10 Start = 0;

        
      end       

    initial #10000 $finish;

    initial
      begin
        $monitor ("time = %b, bcdtime = %b %b ", bintimeout, bcdtime1, bcdtime0);
      end
endmodule
 

Ответ №1:

С вашим кодом есть несколько проблем.

Если вы хотите гарантировать, что ваш дизайн фиксирует Start импульс, вы должны убедиться, что он высок в течение одного тактового периода (20). Изменить:

     #10 Start = 1; #10 Start = 0;
 

Для:

     #10 Start = 1; #20 Start = 0;
 

В microwave модуле вы должны назначить bintimeout в одном always блоке, а не в двух, и нет необходимости использовать assign ключевое слово внутри always блока. Кроме того, хорошие методы кодирования рекомендуют использовать неблокирующие назначения ( <= ) для последовательной логики. Это лучший способ кодирования модуля:

 module microwave(bintimeout, Clk, Start, Stop, bintime, status);
    input [7:0] bintime;
    input Clk, Start, Stop;
    output reg [7:0] bintimeout;
    output reg status;
    
    always @ (posedge Clk) begin
        if (Start) begin
            bintimeout <= bintime;
        end else begin
            bintimeout <= bintimeout - 1;
        end
    end
endmodule
 

Это вывод сейчас, который показывает обратный отсчет:

 time = xxxxxxxx, bcdtime = 0001 0010 
time = 00001100, bcdtime = 0001 0010 
time = 00001011, bcdtime = 0001 0010 
time = 00001010, bcdtime = 0001 0010 
time = 00001001, bcdtime = 0001 0010 
time = 00001000, bcdtime = 0001 0010 
time = 00000111, bcdtime = 0001 0010 
time = 00000110, bcdtime = 0001 0010 
time = 00000101, bcdtime = 0001 0010 
time = 00000100, bcdtime = 0001 0010 
time = 00000011, bcdtime = 0001 0010 
time = 00000010, bcdtime = 0001 0010 
time = 00000001, bcdtime = 0001 0010 
time = 00000000, bcdtime = 0001 0010 
time = 11111111, bcdtime = 0001 0010 
time = 11111110, bcdtime = 0001 0010