¿Cómo controlar una bandera en dos bloques de procedimiento diferentes en verilog?

0

Quiero subir una bandera una vez que entro en el bloque de procedimiento # 1, y quiero restablecerlo a cero en otro bloque de procedimiento. Por supuesto, recibo un error que dice que la bandera está controlada por demasiados controladores. ¿Cómo puedo superar este problema?

Bloque 1, sensible a sw (conmutadores de placa FPGA):

always @ (sw)
flag =1;
begin 
case (sw)   
8'bxxxxxx01: x2= 13'd1249;
8'bxxxxxx10: x2= 13'd2499;
8'bxxxxxx11: x2= 13'd3749;

endcase

end

Bloque 2, sensible a CLK:

always @ (posedge CLK)

        begin

        if (counter2 == x2)
        begin
        counter2 <=0;
        flag=0;
        end

        else
        counter2 <= counter2 +1;

        end

Suponiendo que toda la inicialización esté a cargo.

    
pregunta HaneenSu

3 respuestas

1

Obviamente, necesitas pasar una señal de un proceso a otro (en cualquier dirección) para que todas las actualizaciones de flag puedan ocurrir en un proceso.

¿Pero qué estaría mal con el muestreo de los interruptores dentro del proceso cronometrado? ¿Es tan lento el reloj que se perderían los cambios en las entradas del interruptor? Yo escribiría algo como esto:

reg [7:0] sw_prev;

always @ (posedge CLK)
begin

  /* Note that flag will be overridden if counter overflows on the
   * same clock cycle that the switches change. To avoid that, put
   * these two statements inside the 'else' clause below.
   */
  sw_prev <= sw;
  if (sw != sw_prev) flag <= 1;

  case (sw)   
  8'bxxxxxx01: x2 <= 13'd1249;
  8'bxxxxxx10: x2 <= 13'd2499;
  8'bxxxxxx11: x2 <= 13'd3749;
  endcase

  if (counter2 == x2) begin
    counter2 <= 0;
    flag <= 0;
  end else begin
    counter2 <= counter2 + 1;
  end
end

Siempre tenga en cuenta que Verilog es un lenguaje de descripción de hardware , no un lenguaje de programación secuencial. ¿Qué hardware crees que podría usarse para implementar flag como lo has escrito? Cuando se trata de partes asíncronas de su diseño, necesita pensar en un nivel muy bajo y luego escribir un código que explique más o menos explícitamente esa lógica.

    
respondido por el Dave Tweed
1
always @ (sw) ...

Esta es la lógica combinacional , lo que significa que si establece flag=1 aquí, siempre será 1. Básicamente, no es diferente de hacer assign flag = 1; .

¿Por qué? Porque sw siempre será, no importa lo que sea, siempre será algo, por lo que always @ (sw) siempre se hará, no es un proceso cronometrado.

Los registros y los cables deben manejarse desde solo una fuente , nunca más de una (es decir, no puede conducir una señal desde dos bloques siempre).

Ahora, lo que podrías hacer es lo siguiente:

reg [7:0] sw_delay;
wire sw_edge;

always @ (posedge CLK) begin
   sw_delay <= sw;
end

assign sw_edge = |(sw_delay ^ sw); //If any edge on any switch is detected

always @ (posedge CLK) begin
    if (sw_edge) begin
        //Do something in the clock cycle when an edge is detected
    end else begin
        //Otherwise do something else
    end
end

En lugar de solo hacer una pregunta de cómo hago que Y funcione para hacer X, también debe proporcionar información sobre qué es X y nos pueden ayudar a asesorar si Y es realmente el camino a seguir.

    
respondido por el Tom Carpenter
0

Le está pidiendo al software que resuelva un problema ambiguo, en este momento, flag está intentando actuar como algún tipo de bus compartido (lo más probable, depende de la cadena de herramientas de síntesis)

No estoy seguro de qué tipo de bandera es, pero parece que quieres que actúe como una variable global. En ese caso, necesita memoria asignada, y es mejor que lo defina como un flip-flop (síncrono) o RS latch (asíncrono "flip-flop") explícitamente. Dependiendo de la lógica exacta que desee, las dos operaciones también pueden dividirse como entradas a una "puerta lógica" / operador lógico. Por favor, reconsidere la lógica cuidadosamente, luego elija la solución más adecuada.

    

Lea otras preguntas en las etiquetas