Implementación de lógica de contador Verilog Down

0

Estoy tratando de escribir lógica para almacenar datos de activación. Por ejemplo, estoy usando un contador de 3 bits como generador de direcciones para almacenar muestras de datos. Cuando tengo un evento desencadenante, quiero almacenar las 4 muestras de datos justo antes de que ocurriera el evento desencadenante y las 4 después de las salas. Así que uso un contador descendente de 2 bits cuando se produce el disparo y detiene el contador cuando cuenta hasta 0, por lo que me da 4 muestras de datos anteriores al disparo y 4 muestras de datos después del disparo. Sin embargo, estoy teniendo problemas para implementar esto y obtengo solo 3 direcciones una vez que comienzo el contador hacia abajo y el conteo regresivo es de 0

//=== 8-bit wide loadable up-counter =============================
'timescale 1 ns / 1 ps

module fw_up_counter_3 (tc, count, d, ld, en, clk, rst);

output          tc;
output  [2:0]   count;
input   [2:0]   d;
input           ld, en, clk, rst;
reg     [2:0]   l_count;
wire            tc;

assign  tc      = &count[2:0];
assign  count   = l_count ;

always @(posedge clk)
 begin
        if(rst)
                l_count <=      3'b0;
        else if(ld)
                l_count <=      d;
        else if (en & ~ld)
                l_count <=      l_count + 1;
        else
                l_count <=      l_count;
 end
endmodule

//====2-bit wide loadable down-counter=====================
module fw_dn_counter_1(tc, count, en, ld, clk, rst);
  output tc;
  output [1:0] count;
  input en, clk, rst, ld;
  reg [1:0] l_count;
  reg [1:0] d = 2'b11;
  wire tc;

  assign tc = ~|count[1:0];
  assign count = l_count;

  always@(posedge clk)
  begin
    if (rst)
      l_count <= 2'b11;
    else if (ld)
      l_count <= d;
    else if(en & ~ld & ~tc)
      l_count <= l_count - 1;
    else if (l_count == 2'b00)
      l_count <= 2'b00;
    else
      l_count <= l_count;
    end
  endmodule


module trig_test(clk, tc1, tc2, en1, en2, count1, count2, rst, ld, trig, trig_loc);
  input clk, rst, en1, en2, ld;
  output [2:0] count1;
  output [1:0] count2;
  output tc1, tc2;
  input trig;
  output reg [2:0]trig_loc;

  fw_up_counter_3 counter1(.tc(tc1), .count(count1), .d(3'b000), .ld(ld), .en(~tc2), .clk(clk), .rst(rst));

  fw_dn_counter_1 counter2(.tc(tc2), .count(count2), .en(trig) , .ld(ld), .clk(clk), .rst(rst));

  always@(posedge trig)
  begin
      trig_loc <= count1;
  end

endmodule

¿Alguien tiene alguna idea sobre dónde me voy mal?

    
pregunta GamingX

1 respuesta

1

counter2 se restablece al estado 11. Cuando se produce el borde ascendente de trig , comienza la cuenta regresiva.

Su código no muestra ninguna manera de garantizar que el trig edge esté sincronizado con su señal clk . En su simulación, trig va alto muy poco antes de un clk al alza. Entonces, en ese borde, counter2 comienza la cuenta regresiva --- yendo al estado 10. Pero entre el borde trig y el borde clk , tuvo un breve período en el que counter2 estaba en el estado 11. Entonces, de hecho, tenías counter2 en 4 estados diferentes después del borde de activación.

Si desea asegurarse de mantener el contador en el estado 11 durante al menos un ciclo clk completo después del disparo, puede sincronizar trig a clk , o retrasar la entrada al contador en de entrada para un ciclo después de que se vea el disparador (esencialmente lo mismo, pero haciendo una nueva señal sincronizada).

    
respondido por el The Photon

Lea otras preguntas en las etiquetas