2017-07-04 5 views
0

Ce que j'essaie de faire: Je souhaite compter les nombres de 0 à hexadécimal F et les afficher sur ma carte FPGA à différentes fréquences - mon L'horloge de la carte (CLOCK_50) est à 50 MHz et je souhaite modifier la fréquence/vitesse du comptage en fonction de deux commutateurs d'entrée sur ma carte (SW [1: 0]).Modelsim - Objet non enregistré et pas de données de signal lors de la simulation du code du diviseur d'horloge verilog

code Verilog pour le haut-module & module diviseur d'horloge:

//top level module 

module rate_divider (input CLOCK_50, input [1:0] SW, input [1:0] KEY,output [6:0] HEX0); 

//Declare parameters that define the # of clock cycles needed to generate an enable pulse 
according to the desired frequency. 

    parameter FREQ_5MHz = 4'd9; //To divide to 5 MHz we need (10-1) cycles, 
           //since the pulse needs to start at the 9th cycle. 
    parameter FULL50_MHz = (4'd1); //The CLOCK_50's Frequency. 

//Select the desired parameter based on the input switches 

    reg [3:0] cycles_countdown; 
    wire enable_display_count; 
    wire [3:0] selected_freq; 

    always @(*) 
      case (SW)   
       2'b00: cycles_countdown = FULL50_MHz; 
       2'b01: cycles_countdown = FREQ_5MHz; 
       default : cycles_countdown = FULL50_MHz; 
      endcase 

    assign selected_freq = cycles_countdown;   

//wire that is the output of the display_counter and input to the 7 segment 

    wire [3:0] hex_value; 

// instantiate my other modules 

    clock_divider_enable freq_divider (.d(selected_freq), .clk(CLOCK_50), .reset(KEY[0]), 
                .enable(enable_display_count)); 

    display_counter count_hex (.enable(enable_display_count), .clk(CLOCK_50), .hex_out(hex_value), .reset(KEY[1])); 

    hex_decoder HX0 (.hex_digit(hex_value), .segments(HEX0[6:0])); 

endmodule 

//the clock_divider sub-circuit. 

module clock_divider_enable (input [3:0] d, input clk, reset, 
             output enable); 

    reg [3:0] q; 

    always @(posedge clk) 
     begin 
      if (!reset || !q) 
       q <= d; 
      else 
       q <= q - 4'd1; 
     end 

    assign enable = (q == 4'h0) ? 1'b1 : 1'b0; 

endmodule 

code ModelSim:

vlib work 
vlog rate_divider.v 
vsim rate_divider 
log {/*} 
add wave {/*} 

#initial reset - using KEY[1:0]. Note: active low synchronous reset. 

force {CLOCK_50} 1 
force {KEY[0]} 0 
force {KEY[1]} 0 
run 10ns 

#choose 5 MHz as the desired frequency - turn SW[0] high. 

force {CLOCK_50} 0 0ns, 1 {10ns} -r 20ns 
force {KEY[0]} 1 
force {KEY[1]} 1 
force {SW[0]} 1 
force {SW[1]} 0 
run 600ns 

Problèmes Je suis face à:

est ici la chose - quand je ne le fais pas utilisez le bloc always pour sélectionner un paramètre, et passez un paramètre désiré au fil selected_freq, ma simulation fonctionne bien - je peux voir l'impulsion de validation attendue. CEPENDANT, si j'utilise le bloc always, le paramètre reg cycles_countdown reçoit la valeur correcte, MAIS pour une raison quelconque le signal de validation est juste une ligne rouge. Lorsque je sélectionne mon module clock_divider_enable et que j'ajoute son signal 'q' sur ma forme d'onde, il est également rouge et ne montre aucune donnée, et l'objet q est "non connecté". En tant que tel, je suis incapable de déboguer et de comprendre exactement quel est le problème avec mon code. Ce serait génial si quelqu'un pouvait aider à résoudre le problème de simulation plutôt que de simplement signaler le problème avec mon code Verilog puisque je veux apprendre à utiliser ModelSim de manière efficace pour qu'à l'avenir le débogage soit plus facile pour moi.

Matériel agricole:

FPGA: Altera De-1-SoC, puce Cyclone V

Outils CAD/Simulation: Altera Quartus II Lite 17,0 + ModelSim Starter Edition

+0

Vous devez affecter SW avant de libérer la réinitialisation, avec un delta de temps entre les deux – Greg

+0

Merci, a fonctionné très bien! Pourriez-vous expliquer pourquoi exactement je dois faire cela? Et pourquoi n'était-ce pas un problème lorsque je n'utilisais que le paramètre directement - je suppose que dans ce cas les SW ne conduisaient à aucune logique? –

Répondre

0

SW n » était pas t donné une valeur initiale, donc il est haut-Z (X s'il est connecté à un reg).

Je devine quand vous avez utilisé l'approche de paramètre que vous étiez en train de paramétrer cycles_countdown. Certains simulateurs ne déclenchent pas @* à l'instant-0. Donc, s'il n'y a pas de changement dans la liste de senctivité, alors le bloc peut ne pas s'exécuter; laissant cycles_countdown comme sa valeur initiale (4'hX). Au lieu de conduire votre test avec des commandes TCL, vous pouvez utiliser create verilux avec verilog. Ce banc d'essai ne doit être utilisé qu'en simulation, pas en synthèse.

module rate_devider_tb; 
    reg CLOCK_50; 
    reg [1:0] SW; 
    reg [1:0] KEY; 
    wire [6:0] HEX0; 

    rate_divider dut(.CLOCK_50(CLOCK_50), .SW(SW), .KEY(KEY), .HEX0(HEX0)); 

    always begin 
    CLOCK_50 = 1'b1; 
    #10; 
    CLOCK_50 = 1'b0; 
    #10; 
    end 
    initial begin 
    // init input signals 
    SW <= 2'b01; 
    KEY <= 2'b00; 

    // Log file reporting 
    $monitor("SW:%b KEY:%b HEX0:%h @ %t", SW, KEY, HEX0, $time); 
    // waveform dumping 
    $dumpfile("test.vcd"); 
    $dumpvars(0, rate_devider_tb); 

    wait(CLOCK_50 === 1'b0); // initialization x->1 will trigger an posedge 
    @(posedge CLOCK_50); 
    KEY <= 2'b01; // remove reset after SW was sampled 
    #600; // 600ns assuming timescale is in 1ns steps 
    $finish(); 
    end