¿Por qué aparece una advertencia "[Synth 8-5413] Mezcla de control síncrono y asíncrono para el registro" en Vivado?

2

El código siguiente es tomar el recíproco de un número de punto fijo utilizando el método de Newton. Cuando se afirma start , la máquina de estado entra en el estado de estimación . Para obtener un punto de partida, comienzo en 1/2 ^ N, donde N es el índice del bit más significativo. Parece que funciona bien en la simulación, pero cuando lo sintetizo aparece la siguiente advertencia:

  

[Synth 8-5413] Mezcla de control síncrono y asíncrono para el registro abs_n_reg en el módulo qinv. ["/home/chase/vivado-workspace/FixedMath/FixedMath.srcs/sources_1/new/qinv.v":45]

No estoy realmente seguro de por qué recibo esto o cómo solucionarlo. abs_n_reg es el valor absoluto de n . Solo estoy configurando su valor a partir de uno de mis bloques siempre.

  module qinv(output reg signed [63:0] inv,
                output reg ready = 1'b1,
                input signed [63:0] n,
                input start,
                input clk);

        reg sign;
        reg [63:0] abs_n;

        reg [63:0] cur_inv;
        reg [63:0] next_inv;


        localparam READY = 2'b00,
                   COMPUTE = 2'b01,
                   ESTIMATE = 2'b10;


        reg [1:0] state = READY;
        reg [1:0] next_state = READY;

        wire [5:0] mb;
        msb m(abs_n, mb);

        always @(posedge clk or posedge start) begin
            if(start && state == READY) begin

                if(n[63] == 1'b1) begin
                    abs_n <= -n;
                    sign <= 1'b1;
                end else begin
                    abs_n <= n;
                    sign <= 1'b0;
                end

                ready <= 1'b0;
                cur_inv <= 64'b0;
                state <= ESTIMATE;

            end else begin
                state <= next_state;
                cur_inv <= next_inv;

                if(state == COMPUTE && next_state == READY) begin
                    ready <= 1'b1;
                    if(sign) inv <= -next_inv;
                    else inv <= next_inv;
                end
            end
        end

        wire [63:0] p1, p2;
        qmul m1(p1, abs_n, cur_inv);

        reg [63:0] diff;
        qmul m2(p2, diff, cur_inv);

        always @* begin
            next_inv = 0;
            next_state = READY;
            diff = 0;

            if(state == ESTIMATE) begin
                next_inv = {1'b1, 63'b0} >> mb;
                next_state = COMPUTE;
            end else if(state == COMPUTE) begin
                diff = {30'b0, 2'b10, 32'b0} - p1;
                next_inv = p2;
                if(next_inv[63:1] == cur_inv[63:1])
                    next_state = READY;
                else
                    next_state = COMPUTE;
            end
        end

    endmodule

    module msb(input [63:0] n, output reg [5:0] m);
        integer i;
        always @* begin
            m = 0;
            for(i = 0; i <= 63; i = i + 1)
                if(n[i] == 1'b1) m = i; 
        end

    endmodule

    module div_test();

        reg clk = 0;
        always #5 clk = ~clk;

        wire ready;
        wire [63:0] out;
        reg start = 0;
        reg [63:0] in = {8'd207, 24'b0};
        qinv d(out, ready, in, start, clk); 

        initial begin
            #5 start = 1;
            #10 start = 0;
            #1000 $finish;
        end 
    endmodule
    
pregunta chasep255

1 respuesta

3

Es exactamente como dice la advertencia, estás mezclando lógica síncrona con lógica asíncrona.

No puedes usar ... or posedge start ... .

    
respondido por el Paebbels

Lea otras preguntas en las etiquetas