Verilog: compruebe si hay dos márgenes en el bloque siempre

4

Intento hacer algo como esto:

always @ (negedge speed_dec or negedge speed_inc)
 begin
  do something
 end

Esto no funciona, ya que la comprobación de 2 aristas negativas es muy exigente y da como resultado solo la comprobación del reloj.

Intenté hacer la comprobación manualmente:

    reg old_key0;
always @ (KEY[0])
begin
    if(KEY[0] == 1  & old_key0 == 0)
            do something
    old_key0 = KEY[0];
    end

Pero ahora deja de funcionar por completo. ¿Alguien puede detectar el error?

    
pregunta Nicolas

2 respuestas

4

El always@ es una lista de sensibilidad y generalmente no una lista de comprobación, es decir, no funciona como un bloque if-else .

En cambio, indica cuándo el registro / latch especificado en el bloque necesita cambiar de estado, generalmente en un borde del reloj (register) o cambio de nivel (latch).

Si está intentando detectar un borde en una entrada, como en el caso de una detección de interrupción, la forma recomendada es sincronizar el borde con un registro de desplazamiento interno.

Podría ser tan simple como esto:

reg [1:0] det_edge;
wire sig_edge;
assign sig_edge = (det_edge == 2'b10);
always @(posedge clk)
  begin
    det_edge <= {det_edge[0], input};
  end

Luego, puede hacer lo que quiera con la señal de borde, posiblemente como una señal de habilitación para una máquina de estado u otro bloque que haga algo con su dispositivo (como marcar la interrupción).

Por lo tanto, para su aplicación, es posible que desee hacer lo anterior dos veces y luego usar las dos señales de detección de borde para controlar algún otro dispositivo / bloque.

El punto punto a recordar con todo el trabajo de HDL es que HDL significa Lenguaje de descripción de hardware. Es un reemplazo para los esquemas, no para el software.

Para empezar, recomendaría comenzar con el hardware y luego traducirlo en código, es decir, dibujar el esquema y luego escribir el HDL que describe el esquema del circuito.

    
respondido por el sybreon
3

Lo que escribiste es perfectamente válido Verilog. Por ejemplo, un caso donde un bloque siempre depende de dos bordes es al describir un flip-flop con reinicio asíncrono:

wire d;
reg q;
always @ (posedge CLOCK or posedge RESET) begin
    if (RESET) 
        q <= 0;
    else
        q <= d;
end

Otro caso en el que un bloque siempre es sensible a múltiples entradas (pero no a sus bordes) es al describir un multiplexor:

wire s, a, b;
reg out;
always @ ( s or a or b ) begin
    case ( s )
        0 : out <= a;
        1 : out <= b;
    endcase
end

Tenga en cuenta que en este caso, aunque out es una variable reg en el Verilog, en realidad se implementará como la salida de la lógica combinatoria, y no se generará ningún flip-flop o latch desde este codigo

Sin embargo, solo porque algo sea Verilog válido, no significa que se pueda sintetizar en su dispositivo (supongo que está intentando sintetizar para un FPGA o CPLD). Si su dispositivo no tiene puertas reales disponibles que puedan realizar la lógica que describe en su Verilog, obtendrá un error de síntesis.

Como dijo Sybreon, a menudo es una buena idea diseñar mentalmente su lógica en términos de los recursos de hardware disponibles en su dispositivo, luego averiguar cómo traducir eso a Verilog, en lugar de simplemente escribir Verilog y luego tratar de averiguar cómo para ajustarlo para que sea sintetizable.

    
respondido por el The Photon

Lea otras preguntas en las etiquetas