Problema al agregar dos contadores en serie en un FPGA

2

Estoy usando Verilog en Lattice Diamond IDE con una placa de separación MachXO2 7000HE de celosía.

Construí un contador básico con una entrada límite que genera una salida de reloj de período variable. Funciona bien solo, sin embargo, cuando agrego dos instancias de este módulo y las conecto en serie (para escalar la frecuencia dos veces), obtengo un resultado extraño en el FPGA. La simulación, sin embargo, parece mostrar lo que esperaba del código.

Aquí está el módulo superior:

 module clock_generator (fpga_clock, cnt1_clock, cnt2_clock, cnt2_counter);
    output  wire            fpga_clock;
    output  wire            cnt1_clock;
    output  wire            cnt2_clock;
    output  wire    [7:0]   cnt2_counter;

    reg     [7:0]   default_period_1    = 8'b00000011;
    reg     [7:0]   default_period_2    = 8'b00000011;

    defparam OSCH_inst.NOM_FREQ = "2.08";
    OSCH OSCH_inst(.STDBY(1'b0), .OSC(fpga_clock));

    counter Counter_1_inst(.clk_in(fpga_clock), .limit_in(default_period_1), .clk_out(cnt1_clock), .cnt_out());
    counter Counter_2_inst(.clk_in(cnt1_clock), .limit_in(default_period_1), .clk_out(cnt2_clock), .cnt_out(cnt2_counter)); 
endmodule

module counter (clk_in, limit_in, clk_out, cnt_out);
    input   wire            clk_in;
    input   wire    [7:0]   limit_in;
    output  reg             clk_out     = 1'b1;
    output  reg     [7:0]   cnt_out     = 8'b00000000;

    always @(posedge clk_in) begin
        cnt_out <= cnt_out + 1'b1;
        if (cnt_out == limit_in) begin
            clk_out <= !clk_out;
            cnt_out <= 0;
        end
    end 
endmodule

Y aquí está el banco de pruebas para mi simulación:

'timescale 1 ns / 1 ns

module testbench;
    wire            fpga_clock;
    wire            cnt1_clock;
    wire            cnt2_clock;
    wire    [7:0]   cnt2_counter;

    clock_generator dut(.fpga_clock(fpga_clock), .cnt1_clock(cnt1_clock), .cnt2_clock(cnt2_clock), .cnt2_counter(cnt2_counter));

    initial begin
        #1400000000
        $finish;
    end
endmodule

Aquí está la salida de la simulación:

Yelalcancedelresultado:

ch1-fpga_clock

ch2-cnt1_clock

ch3-cnt2_clock

ch4-cnt2_counter[1◆

Elcanal3(cnt2_clock)debetenereldobledelperíododecnt2_counter[1],yaqueestáenlasalidadelasimulación.Ensulugar,comopuedever,esunaráfagadebordesdemayorfrecuenciadondedeberíaestarelbordeúnico.Heestadoenestoporuntiempoahora.¿Quémeestoyperdiendo?

Permítemetambiénagregarelshematic:

¡Gracias!

    
pregunta amfast

2 respuestas

0

¿Cómo debería funcionar?

always @(posedge clk_in) begin
    cnt_out <= cnt_out + 1'b1;
    if (cnt_out == limit_in) begin
        clk_out <= !clk_out;
        cnt_out <= 0;
    end
end 

Tal vez te refieres a:

always @(posedge clk_in) begin
    cnt_out <= (cnt_out == limit_in) ? 0 : cnt_out + 1;
    clk_out <= (cnt_out == limit_in) ? ~clk_out : clk_out;
end 
    
respondido por el strannyi
0

Estás usando un reloj generado. Esto generalmente no es aconsejable en un FPGA ya que se debe hacer con mucho cuidado para evitar fallos y para asegurar que sea posible el cierre de tiempo. Parece que podrías tener algunos fallos en cnt1_clock que están arruinando la segunda instancia. Intente usar el reloj habilitado y vea qué sucede.

Además, fpga_clock debería ser una entrada y no una salida en su módulo superior.

    
respondido por el alex.forencich

Lea otras preguntas en las etiquetas