AND Gate and posedge CLK? Pregunta simple

1

Estoy tratando de hacer el sistema de secuencias como la imagen, estoy seguro de que es simple pero no recuerdo la "puerta" de esto.

EsterelojcondseusaráparaenviarbitsenUART.

regcond;always@(posedgeclkornegedgeclk)beginif(enable==1)beginif(clk==1)cond=1;//############ERRORthislineelseif(clk==0)cond=0;endend

Estecódigofuncionaensimulación,perorecibíunerroralintentarsintetizarlo:Thelogicfor<cond>doesnotmatchaknownFForLatchtemplate.Thedescriptionstyleyouareusingtodescribearegisterorlatchisnotsupportedinthecurrentsoftwarerelease.

condsoloseusaparaestojustodebajodelcódigoanterior:

always@(posedgecondornegedgeenable)begin***

SoyunprincipianteenVerilog,porfavorayúdame.

Gracias.

Editar:

Tengocada100usdatosdeunADC.QuieroconvertiraBCDyenviarASCIIconUART/comunicaciónserial.

Lafrecuenciadelosdatosylafrecuenciadelavelocidaddetransmisiónsondiferentes.Tengoalgunosproblemasporque,porejemplo,paraelsegundoenvío,nodetectaráDsinoC,luegoenviaráCynoD.Yaqueesmiprimerproyectodeverilog/FPGA,intentéhacerlocomosolíahacermicerebro..Significaconevento,inicio,habilitación,señalesdefinalización,etc.CreoqueesmáscómofuncionaunuC/uPqueunFPGA.Peroestoyaprendiendo.

Estoysegurodequeessimpleperollevo2semanas...

    
pregunta Alexis_FR_JP

1 respuesta

1

Esto no daría lo que Alexis quiere.

module and_clk (
                input wire clk,
                input wire rst_n,
                input wire enable,
                output reg cond
              );

   always @(posedge clk or negedge rst_n) 
   begin
     if(~rst_n) begin
       cond <= 1'b0;
     end else begin
       cond <= enable & clk;
     end
   end

endmodule

A medida que el FF captura datos solo en la posición del reloj, cond <= enable & clk siempre pondrá 1'b1 en cond (cuando la habilitación es alta por cierto).

Puedo ver dos soluciones para hacer lo que quieres:

  1. Agregue lógica en el reloj (lo que puede dar como resultado problemas graves en la síntesis)

    module and_clk (
                input wire clk,
                input wire rst_n,
                input wire enable,
                output wire cond
              );
    
    reg enable_q;
    
    always @(posedge clk or negedge rst_n) 
    begin
     if(~rst_n) begin
       enable_q <= 1'b0;
     end else begin
       enable_q <= enable;//stores enable value in a FF
     end
    end
    
    assign cond = enable_q & clk; //it is not safe to add combinatorial cells on the clock path. It will complicate the generation of the clock tree
    endmodule
    
  2. Utilice un FF desencadenado por negedge, un poco más complicado pero mucho más seguro para la síntesis

    module and_clk (
                input wire clk,
                input wire rst_n,
                input wire enable,
                output wire cond
              );
    
    reg enable_q;
    
    always @(posedge clk or negedge rst_n) 
    begin
     if(~rst_n) begin
       enable_q <= 1'b0;
     end else begin
       enable_q <= enable & ~enable_qn;//stores enable value in a FF
       //set to 0 when enable_qn is high to generate the cycles you want
     end
    end
    
    always @(negedge clk or negedge rst_n) 
    begin
     if(~rst_n) begin
       enable_qn <= 1'b0;
     end else begin
       enable_qn <= enable_q;
       //will take the value of enable_q half a cycle later
     end
    end
    
    assign cond = enable_q ^ enable_qn; 
    //xoring the output will give you what you want
    
    endmodule
    

    Finalmente, no es una pregunta tan simple :)

EDIT:

Problemas sobre la adición de lógica en la ruta del reloj:
Agregar lógica en la ruta del reloj agrega dos cosas:

  1. Retraso a la salida de la lógica: lo que puede crear metastabilidad ya que la señal resultante cambiará en una ventana cercana de los bordes del reloj. ( Este sitio explica claramente el problema de la metastabilidad)
  2. Capacitancia a la entrada: Esto provoca un desequilibrio en el árbol del reloj, es decir, arruina el trabajo que realizó la herramienta de síntesis para garantizar que todos los FF, con el mismo reloj, se activen al mismo tiempo. ( explica cómo se genera un árbol de reloj)

Este interesante pdf agrupa un montón de cosas que deben evitarse para diseñar circuitos confiables.

Problemas al agregar enable en la ruta de salida:
(Para entender lo que trataré de explicar en las siguientes líneas, debe leer y entender cuidadosamente, mi primera referencia )

No sé de dónde viene su señal enable , pero como se dibuja, parece ser asíncrono. El problema con las señales asíncronas en los diseños síncronos es que pueden violar las restricciones de configuración / retención del FF y luego crear una metastabilidad que dará como resultado un valor impredecible del FF de salida que se violaron las restricciones.

Si entendió el artículo sobre metastabilidad, debería haber imaginado que incluso poner enable en enable_q puede crear metastabilidad. Para estar (más) cubierto sobre eso, una solución es agregar un FF activado por negedge "entre" enable y enable_q .

Como es una cuestión de probabilidad, la metastabilidad puede ocurrir en todas partes. Una versión más segura de tu diseño sería:

    module and_clk (
                input wire clk,
                input wire rst_n,
                input wire enable,
                output wire cond
              );

    reg enable_q, enable_meta;

    //This FF store on negedge the value of enable
    always @(negedge clk or negedge rst_n) 
    begin
     if(~rst_n) begin
       enable_meta <= 1'b0;
     end else begin
       enable_meta <= enable;//stores enable value in a FF
     end
    end

    //By doubling this FF the risk of metastability is greatly reduced
    always @(posedge clk or negedge rst_n) 
    begin
     if(~rst_n) begin
       enable_q <= 1'b0;
     end else begin
       enable_q <= enable_meta & ~enable_qn;//stores enable value in a FF
       //set to 0 when enable_qn is high to generate the cycles you want
     end
    end

    always @(negedge clk or negedge rst_n) 
    begin
     if(~rst_n) begin
       enable_qn <= 1'b0;
     end else begin
       enable_qn <= enable_q;
       //will take the value of enable_q half a cycle later
     end
    end

    assign cond = (enable_q ^ enable_qn) & enable_meta; 
    //adding "& enable_meta" can replace "enable"
    //This should be safe as the result of the xor will have a very low probability of metastability
    endmodule

Esta solución será más segura, pero también más grande y bastante más complicada. También habrá configuraciones de eventos que conducirán a un ciclo adicional en cond o un retraso de 1 reloj dependiendo de la llegada de subida / caída de enable .

Espero que esto ayude.

    
respondido por el Krouitch

Lea otras preguntas en las etiquetas