¿Este código implica un bloqueo y no es seguro (verilog)?

1

Estoy empezando con verilog y escribí este código aquí para probar si un número es primo. Sé que podría ser mucho más eficiente, pero es solo para la práctica. La forma en que se realiza la prueba de primado es cuando se envía la señal de reinicio. Inicializo el registro div a 2. Luego lo incremento en 1 en cada ciclo de reloj mientras no es divisible por el número que estoy probando. Una vez que se vuelve divisible (en este caso es un factor donde el número no es primo o el número en el cual es primo) quiero mantener el registro en el mismo valor. Este es el problema. Estoy implicando un cierre aquí. Sé que estoy asignando un valor a div en cada rama de la declaración if, pero no estoy seguro de si debería asignárselo a sí mismo.

module prime(
    input [31:0] n,
    input clk,
    input reset,
    output done,
    output is_prime);

    reg [32:0] div;
    assign is_prime = div == n;
    assign done = n % div == 0;

    always @(posedge clk) begin
        if(reset) begin
            div <= 2;
        end     
        else if(n % div == 0) begin
            div <= div; //does this cause a latch
        end
        else begin
            div <= div + 1;
        end
    end


endmodule
    
pregunta chasep255

1 respuesta

4

No hay ningún cierre inferido en absoluto. Es simplemente un flip-flop (bien varios) con un reloj habilitado, o un multiplexor de su propia salida y alguna otra entrada.

Se inferiría un latch si fuera una lógica asíncrona, es decir, no tenía reloj. En esa situación, puede tener un pestillo, ya que la lógica asíncrona tendría que mantener su valor (en este caso, si fuera asíncrono, creo que habría habido).

Si está utilizando herramientas de síntesis como Altera Quartus o Xilinx ISE, generalmente incluyen visualizadores de netlist RTL que le dan una idea aproximada de lo que está inferiendo. A continuación se muestra lo que produce su código. Tenga en cuenta el mux (se llama div ~ [32..0] por la herramienta de síntesis) en el que una de las entradas es el valor actual del registro.

Como nota aparte, y si bien soy consciente de que su ejemplo solo está practicando, vale la pena señalar que la división y el módulo requieren una gran cantidad de lógica para su implementación y, como tal, son muy lentos o necesitan mucha coordinación. No son operaciones bien adaptadas a FPGAs. Hay formas de realizar pruebas de primalidad que no requieren la operación de módulo que puede ser más adecuada para el FPGA.

En caso de que tenga curiosidad, y solo por diversión, compilé el código que apunta a un dispositivo Stratix V (que es uno de los Altera para acabar con los FPGA), y las herramientas informan que el diseño solo podría funcionar a 21MHz. - Sin el módulo, probablemente podría funcionar a más de 300MHz :).

    
respondido por el Tom Carpenter

Lea otras preguntas en las etiquetas