¿Es bueno borrar el estado en 'posedge habilitar' en verilog

1

Estoy empezando con verilog y quería intentar crear un módulo que calcule si un punto en el conjunto de Mandelbrot difiere o no. Estoy planeando usar el IP de Xilinx para matemáticas de punto flotante de 32 bits. Bellow es el código que tengo hasta ahora, que está lejos de ser completo.

Lo que quiero hacer es cambiar el estado de todos mis registros para que el cálculo pueda comenzar en el próximo ciclo de reloj. Me preguntaba si esto es una buena práctica o no. Estaba pensando que el problema podría ser que cuando se habilitan los cambios en true, pero always @(posedge clk && enable == 1) begin se ejecuta antes de que se realice la inicialización. ¿Hay una mejor manera de hacer esto? Tal vez debería tener un registro de habilitación interno que se modifica cuando se activa el cable de habilitación.

También me pregunto si el intercambio de pila de EE es el mejor lugar para ver las preguntas. He estado publicando en el desbordamiento de pila, pero estas preguntas tienden a no recibir mucha atención.

module mandelbrot(
    input [31:0] x,
    input [31:0] y,
    input clk,
    input enable,

    output reg [7:0] count,
    output done);

    reg [61:0] z;
    reg [61:0] zsq;
    reg [1:0] state;
    parameter SQUARING = 0;
    parameter COMPARING = 1;
    parameter ADDING = 2;

    reg valid_sq;
    reg done_sq;
    reg in_sq;

    reg valid_add;
    reg done_add;
    reg in_add;

    reg valid_lt;
    reg done_lt;
    reg in_lt;

    always @(posedge enable) begin
        z = {x, y};
        valid_sq <= 0;
        done_sq <= 0;
        in_sq <= 0;
        valid_add <= 0;
        done_add <= 0;
        in_add <= 0;
        valid_lt <= 0;
        done_lt <= 0;
        in_lt <= 0;
    end

    always @(posedge clk && enable == 1) begin
        case(state)
            SQUARING:

            COMPARING:
                state <= ADDING;
            ADDING:
                state <= SQUARING;
        endcase
    end

endmodule
    
pregunta chasep255

2 respuestas

4
always @(posedge clk && enable == 1) begin

Esa no es la manera de hacerlo. Ni siquiera estoy seguro de que sea una sintaxis válida. Además, solo puede controlar una variable de tipo reg o integer desde un solo bloque siempre, por lo que tener el primer bloque siempre que sea sensible para habilitar significa que no podría controlar ninguna de esas señales en ningún otro bloque siempre. / p>

Lo que está buscando depende de a qué se conecte la lógica. Por ejemplo, si desea realizar cálculos mientras la habilitación es alta, pero luego no use los valores cuando está baja, simplemente puede usar la señal de habilitación como un reinicio negativo. Si este es el caso, entonces la señal debería llamarse simplemente eso, "restablecer" no "habilitar".

always @ (posedge clock) begin
    if (~enable) begin
        //Reset the values ready for next time
    end else begin
        //Do stuff when enabled

    end
end

Esto puede no ser lo que quieres. Por ejemplo, si necesita que los registros conserven su valor cuando la señal de habilitación es baja, y luego bórrelos justo antes de un cálculo. Esto también se puede hacer, pero solo si no te importa tomar un ciclo de reloj. Este enfoque se puede lograr utilizando un reinicio síncrono y un circuito de detección de bordes.

reg enableDelay;
always @ (posedge clock) begin
    enableDelay <= enable; //Keep track of the previous value
end

wire enableRising = enable && !enableDelay; //enableRising will be high for a single clock cycle at the rising edge of enable

always @ (posedge clock) begin
    if (enableRising) begin
         //Clear stuff on rising edge of enable
         data <= 1'b1; //Maybe we set the register 'data' to 1 or whatever
    end else if (enableDelay) begin
         //While the delayed enable signal is high, do stuff.
         data <= something;
    end
end

El código anterior producirá el siguiente resultado:

  1. Hayunflancoascendentedelaseñalenable.ObservecómolaseñalenableRisingtambiénseelevaalmismotiempo.
  2. LaseñalenableDelayseeleva,yaquesiempreseretrasauncicloderelojdesdelaseñalenable.Enelmismomomento,elsegundobloquealwaysdetectaquelaseñalenableRisingesaltayrealizalaoperaciónde"reinicio". Esto se indica mediante la señal data que va alta.
  3. En el tercer ciclo de reloj, enableRising ahora está nuevamente bajo, por lo que la señal data se establece en el cálculo que haga en la parte else de ese bloque. Seguirá ejecutando la parte else en cada ciclo de reloj hasta que la señal enableDelay vuelva a bajar.

Básicamente, el bloque se despejará en el flanco ascendente y luego realizará los cálculos de n (donde n es el número de ciclos de reloj que la señal enable fue alta) .

El problema con tu pregunta es un problema X-Y clásico . Usted está describiendo Y cuando realmente debería decirnos X. Y es lo que piensa es la forma de hacer algo, X es lo que realmente está tratando de hacer. Por favor aclarar en su pregunta.

Respondiendo directamente el título de la pregunta: "Depende". Es posible que algunas señales desees borrar, tal vez un contador necesite restablecerse a cero, o algo así. Puede haber otros que no importan, digamos la salida de un cálculo que no afecta la entrada.

Las tareas que requieren realizar una secuencia de eventos se organizan mejor en una máquina de estados, de modo que cuando se produce algún disparo (por ejemplo, el flanco ascendente de una señal), su máquina de estados comienza a ejecutar cada estado. Una vez que se completa la tarea, vuelve a un estado inactivo esperando otro desencadenante. De esta manera, no es necesario que reinicie los elementos en el activador, ya que la máquina de estado, si está diseñada correctamente, dejaría todas las señales que controla en un estado predeterminado cuando vuelve al estado inactivo.

    
respondido por el Tom Carpenter
2

Está describiendo un comportamiento RESET, no un comportamiento HABILITAR.

La forma habitual de codificar un flip flop con reinicio asíncrono y habilitar entradas es

reg Q
always @(posedge clk or posedge reset) begin
if reset begin
   Q <= 0
end
else if enable begin
   Q <= <whatever Q gets>
end

Debes tener todo tu código que establece cualquier registro particular en el mismo bloque siempre. Su código como dos bloques siempre, uno para responder a la señal de "habilitación" y otro para responder a la señal de reloj. No está claro qué producirá esto en síntesis o si se puede sintetizar en absoluto.

Además, debe tener en cuenta que los flip-flops en el dispositivo Xilinx tienen ciertas capacidades, como el reinicio y la activación asíncrona. Si intenta codificar algún comportamiento del que no son capaces (como tener una sola señal que primero los reinicia y luego les permite tomar nuevos valores), su código no podrá sintetizar o producirá resultados impredecibles cuando se implemente en la realidad. hardware.

    
respondido por el The Photon

Lea otras preguntas en las etiquetas