¿Cómo puedo configurar un retraso en Verilog usando un reloj?

0

Estoy tratando de escribir un bloque siempre que abra una válvula y luego la mantenga abierta durante unos segundos y luego la cierre si es necesario. La válvula se abre cuando la entrada es 1 y se cierra cuando es cero. ¿Cómo puedo hacer que el código espere unos segundos después de que la válvula se abra para que no se cierre justo después de que se abra?

Aquí está mi código:

input in, alteraclock;
output reg out;
reg clock;

clock myclock(.clkin(alteraclock), .clkout(clock));

always@(in)
begin

if(in==1)

begin
out=1;  //open valve

end

else
begin
out=0;  //close valve
end

end

PS: Estoy usando un Altera DE2-115, si eso ayuda.

    
pregunta ninesalt

2 respuestas

1

Use una máquina de estados y un contador grande. En un estado, espere a que la entrada cambie. Cuando cambie la entrada, configure el contador en un número grande, actualice la salida y cambie al estado de retardo. En el estado de retraso, decrementar el contador. Cuando llegue a cero, vuelva a la espera del estado de entrada.

Editar: no voy a escribir tu código por ti, pero aquí hay una plantilla para una máquina de estado con la que puedes jugar:

localparam [1:0]
    STATE_IDLE = 2'd0,
    STATE_1 = 2'd1,
    STATE_2 = 2'd2;

reg [1:0] state_reg = STATE_IDLE, state_next;

reg [16:0] count_reg = 0, count_next;

always @* begin
    state_next = STATE_IDLE;

    count_next = count_reg;

    case (state_reg)
        STATE_IDLE: begin
            // idle state
            if (condition) begin
                count_next = some_value;
                state_next = STATE_1;
            end else begin
                state_next = STATE_IDLE;
            end
        end
        STATE_1: begin
            // some state
            count_next = count_reg - 1;

            if (count_reg == 0) begin
                state_next = STATE_2;
            end else begin
                state_next = STATE_1;
            end
        end
        STATE_2: begin
            // another state
            if (some_condition) begin
                state_next = STATE_IDLE;
            end else begin
                state_next = STATE_2;
            end
        end
    endcase
end

always @(posedge clk) begin
    if (rst) begin
        state_reg <= STATE_IDLE;
        count_reg <= 0;
    end else begin
        state_reg <= state_next;
        count_reg <= count_next;
    end
end

Aquí hay una manera de hacer esto sin una máquina de estados explícita:

reg [32:0] counter = 0;

always @(posedge clk) begin
    if (rst) begin
        counter <= 0;
        out <= 0;
    end else if (counter > 0) begin
        counter <= counter - 1;
    end else begin
        out <= in;
        if (out != in) begin
            counter <= some_delay_value;
        end
    end
end
    
respondido por el alex.forencich
0

La idea básica es usar un contador.

Lo más probable es que tenga un reloj de 50Mhz, lo que significa que si cuenta hasta 50 millones a partir de 0 en su contador, tomará ese reloj alrededor de 1 s. Así que puedes generar 1'b1 desde el módulo de tu contador, una vez que haya terminado de contar. Por lo tanto, la salida del módulo de este contador puede darte un clk más lento.

Implementarlo como se explicó anteriormente.

    
respondido por el Abdul Muqeet

Lea otras preguntas en las etiquetas