операция приращения в Systemverilog Vivado не работает должным образом

Сумма: часть с конечным автоматом с именем «WaitS2» увеличивает значение «count» только один раз.

Я пытаюсь управлять ультразвуковыми датчиками HC-SR04 в systemverilog. Как я видел в таблице данных, этот датчик создает сигнал «триггер», который создает звук, и после генерации звукового датчика создает логическое «эхо», мне нужно подсчитать время, поэтому я создаю конечный автомат, который вы можете видеть в коде, но проблема в том, что count ++ не работает так хорошо, как ожидалось, он только увеличивает переменную count один раз, независимо от того, как долго длится эхо-сигнал

Я использовал другой модуль под названием 32-битный сумматор из интернета, который ничего не менял. Я изменил все операторы на неблокирующие операторы, это не сработало. Я даже пробовал поменять count++ на count = count + 1 не получилось

module sensorFSM(
    input logic echo , clk ,reset, 
    output logic trig,
    output logic[31:0] distance,
    output logic[1:0] presentState
    );
    /*typedef enum logic[1:0] {BeginS , WaitS , ReturnS } states;
    states presentState , nextState;
    */
    logic[31:0] count , count1; 
    logic[1:0] BeginS , WaitS, WaitS2 , ReturnS  , nextState;
    assign BeginS = 2'b00;
    assign WaitS = 2'b01; 
    assign WaitS2 = 2'b10;
    assign ReturnS = 2'b11; 

    // clk and state change
    always_ff @( posedge clk )
        begin
            if ( reset == 1'b1 )
            presentState <= BeginS;
            else
            presentState <= nextState;
        end

    // real state changes    
    always_comb 
        begin            
            case(presentState)           
            BeginS:
                begin
                    trig = 1'b1;
                    count = 32'b0;
                    nextState = WaitS;
                end
            WaitS:
                begin
                    trig = 1'b0;
                    distance = 32'b0;
                    //#5000;
                    nextState = WaitS2;
                end
            WaitS2:
                begin
                    if( echo  == 1 )
                      begin
                        if ( count < 24'b101100111000000100100000 )
                            begin 
                            // here is the problem count is only incrementing 
                            //once
                                count++;                               
                                nextState = WaitS2; 
                            end 
                         else 
                            begin
                                distance = count;
                                nextState = BeginS;
                            end 
                      end
                    else // echo == 0   
                        begin
                            nextState = ReturnS;
                        end
                   end 
            ReturnS:
                begin
                    //count =  count / 1470;
                    distance = count;
                    nextState = BeginS;
                end
            default:
                nextState = BeginS;
            endcase
         end  
endmodule

Я ожидаю, что симуляция будет насчитывать около 1 мили, но всегда выводит 1, но я вижу, что состояние с именем «WaitS2» присутствует в течение длительного времени, когда также активно эхо.


person Batuhan Tosyalı    schedule 18.07.2019    source источник


Ответы (1)


Вы создали асинхронный цикл обратной связи с count++; внутри always_comb. Вам нужно сделать count реестр.

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

always_ff @( posedge clk )
    begin
      if ( reset == 1'b1 ) begin
        presentState <= BeginS;
        trig <= 0; // <-- reset
        distance <= 0; // <-- reset
        count <= 0; // <-- reset
      end else begin
        presentState <= nextState;
        trig <= next_trig; // <-- flop trig
        distance <= next_distance; // <-- flop distance
        count <= next_count; // <-- flop count
      end
    end

// real state changes    
always_comb 
    begin
      next_trig = trig; // <-- default value is flopped value
      next_distance = distance; // <-- default value is flopped value
      next_count = count; // <-- default value is flopped value
        case(presentState)           
        BeginS:
            begin
                //trig = 1'b1; // <-- is now a flop assigned in always_ff
                //count = 32'b0; // <-- is now a flop assigned in always_ff
                next_trig = 1'b1; // <-- update value
                next_count = 32'b0; // <-- update value
                nextState = WaitS;
            end
        WaitS:
            // ... replace trig/distance with next_trig/next_distance in here ...
        WaitS2:
            begin
              // ...
              //count++;  // <-- NOPE would be asynchronous feedback
              next_count = count + 1; // <-- synchronous increment
              // ...
            end
        ReturnS:
            //  ... replace distance with next_distance in here ...
        default:
            nextState = BeginS;
        endcase
     end  
person Greg    schedule 18.07.2019