Причина предполагаемых защелок (не иначе или по умолчанию) в Verilog - PullRequest
0 голосов
/ 04 августа 2020

Quartus сообщает мне, что я предположил защелки для input_val, ii, output_val, delayed и addr_to_rom. Я просмотрел предыдущие сообщения и внес изменения, чтобы все мои операторы if имели компонент else, а мой оператор case имел параметр по умолчанию.

Что еще может вызывать все эти предполагаемые защелки? (обновленный код ниже)

   module   simple_fir(clk, reset_n, output_val); 
    
    parameter               data_width = 8; 
    parameter               size = 1024;    

    
    input   wire                clk;
    input   wire                reset_n;
    //input     reg [(data_width):0]    input_val;
    reg [(data_width):0]    input_val;
    output  reg [data_width:0]      output_val;

    reg     [(data_width):0]    delayed;
    reg     [data_width:0]      to_avg;     
    reg         [9:0]           ii ;
    reg         [9:0]           i ;
    reg     [data_width:0]      val;
    reg     [data_width:0]      output_arr [(size-1):0];

    
    logic [(data_width):0] data_from_rom; //precalculated 1 Hz sine wave
    logic [9:0] addr_to_rom;

    initial delayed = 0;
    initial i = 0;
    initial ii = 0;
    
    
    //port map to ROM
    rom_data input_data(
    .clk(clk),
    .addr(addr_to_rom), //text file?
    .data(data_from_rom)
    );
        
    //Moore FSM
    localparam [3:0]
    s0=0, s1 = 1, s2 = 2, s3 = 3, s4 = 4, s5 = 5, s6 = 6;
    
    reg [3:0] state_reg, state_next;
    initial state_next = 0;
    always @(posedge clk, negedge reset_n) begin //posedge clk, reset_n
        if (reset_n == 'b0) begin //reset is active low
        state_reg <= s0;
        end else begin
        state_reg <= state_next;
        end
    end
            
    always @* begin 
        state_next = state_reg; // default state_next
        case (state_reg)
            s0 : begin //initial state, reset state
                    if (!reset_n) begin
            output_val = 0;
            delayed = 0; 
            to_avg= 0; 
            i = 0;
            ii = 0;
            end else begin
            state_next = s1;
            end
            end
            s1 : begin
                if (ii>(size-2)) begin
                ii = 0;
                end else begin
                addr_to_rom = ii;
                end
                input_val = input_val;
                delayed = delayed; 
                state_next = s2;
            end
            s2 : begin
                input_val = data_from_rom;
                ii = ii+1;
                delayed = delayed; 
                state_next = s3;
            end
            s3 : begin
                delayed = input_val;
                state_next = s4;
            end
            s4 : begin
                addr_to_rom = ii;
                input_val = input_val;
                delayed = delayed; 
                state_next = s5;
            end
            s5 : begin
                input_val = data_from_rom;
                delayed = delayed;
                //i=i+1;
                //ii <= ii+1;
                state_next = s6;
            end
           s6 : begin
                to_avg = input_val + delayed; //summing two values
                val = (to_avg >> 1);    //taking the average
                output_arr[ii-1] = val; //indexing starts on [2]
                output_val = val; 
                state_next = s0;
                input_val = input_val;
            end
            default: begin
                addr_to_rom = addr_to_rom;
                data_from_rom = data_from_rom;
                delayed = delayed;
                input_val = input_val;
                to_avg = to_avg;
                val = val;
                output_val = output_val;
                ii = ii;
                end
        endcase
    end 

endmodule

Ответы [ 3 ]

1 голос
/ 04 августа 2020

У вас 6 состояний в комбинированном блоке always, но вы назначаете delayed только 3 из них. Это означает, что вы хотите сохранить состояние, которое подразумевает защелки. Вы должны убедиться, что delayed присвоено какое-то значение во всех состояниях (и во всех ветвях if/else, если применимо.

Кроме того, у вас есть неполный список чувствительности. Вероятно, вы захотите изменить:

always @(state_reg) begin 

to:

always @* begin 

@* - это список неявной чувствительности, который запускает блок always всякий раз, когда происходит изменение любого сигнала на правой стороне присвоения.

0 голосов
/ 05 августа 2020

вы должны посмотреть на способы программирования конечных автоматов. Обычно состояния вычисляются с использованием flop, а окончательное присвоение является комбинаторным. У вас наоборот. Поэтому у вас есть проблемы. У вас должно сработать что-то вроде следующего. Извините, я не тестировал. Код должен использовать неблокирующие назначения, за исключением того места, где вы вычисляете промежуточное значение.

    always @* 
        state_reg = state_next;

    always @(posedge clk, negedge reset_n) begin //posedge clk, reset_n
        if (reset_n == 'b0) begin //reset is active low
            state_next <= s0;
        end 
        else begin
          case (state_reg)
            S0: begin
              output_val <= 0;
              delayed <= 0; 
              i <= 0;
              ii <= 0;
            end
            s1 : begin
                if (ii>(size-2)) begin
                   ii <= 0;
                end else begin
                   addr_to_rom <= ii;
                end
                input_val <= input_val;
                delayed <= delayed; 
                state_next <= s2;
            end
            s2 : begin
                input_val <= data_from_rom;
                ii <= ii+1;
                state_next <= s3;
            end
            s3 : begin
                delayed <= input_val;
                state_next <= s4;
            end
            s4 : begin
                addr_to_rom <= ii;
                state_next <= s5;
            end
            s5 : begin
                input_val <= data_from_rom;
                state_next <= s6;
            end
            s6 : begin
                // calculating intermediate value, need blocking assignments here
                to_avg = input_val + delayed; //need blocking here
                val = (to_avg >> 1);    //need blocking here

                output_arr[ii-1] <= val; //indexing starts on [2]
                output_val <= val; 
                state_next <= s0; 
            end
        endcase
      end // else
    end // always
0 голосов
/ 05 августа 2020

Я заметил, что вы использовали стиль кодирования, при котором назначение по умолчанию state_next = state_reg размещается в самом верху блока always. Это означает, что state_next всегда имеет допустимый драйвер, если он явно не назначен. Это также требуется для других комбинационных сигналов. В противном случае предполагается фиксация. Кроме того, сигнал data_from_rom, который, как я предполагаю, является выходом модуля rom_data, имеет несколько драйверов.

...