2017-10-18 4 views
0

Je tente d'implémenter 4 signaux d'horloge activés les uns après les autres dans Verilog. J'ai écrit un module, mais je ne suis pas sûr de savoir comment faire un banc d'essai pour elle parce que Im obtenir l'erreur:Création d'une horloge à 4 étapes

error: clk_pc Unable to assign to unresolved wires. 

Je me attends à un résultat comme celui-ci:

1000 
0100 
0010 
0001 
1000 
0100 
... 

C'est le module:

module clock_divisor(input clk0, 
        input clk1, 
        input clk2, 
        input clk3, 
        output clk0_out, 
        output clk1_out, 
        output clk2_out, 
        output clk3_out); 

    reg clk0_out,clk1_out,clk2_out,clk3_out; 
    always @(posedge clk0 or posedge clk1 or posedge clk2 or posedge clk3) begin 
     if(clk0 == 1)begin 
      assign clk0_out = 0; 
      assign clk1_out = 1; 
      assign clk2_out = 0; 
      assign clk3_out = 0; 
     end 
     else if(clk1 == 1)begin 
      assign clk0_out = 0; 
      assign clk1_out = 0; 
      assign clk2_out = 1; 
      assign clk3_out = 0; 
     end 
     else if(clk2 == 1)begin 
      assign clk0_out = 0; 
      assign clk1_out = 0; 
      assign clk2_out = 0; 
      assign clk3_out = 1; 
     end 
     else if(clk3 == 1)begin 
      assign clk0_out = 1; 
      assign clk1_out = 0; 
      assign clk2_out = 0; 
      assign clk3_out = 0; 
     end 
    end 

endmodule 

Et mon banc d'essai:

module testbench(); 
    reg clk_pc, clk_instruction_memory, clk_alu, clk_registers, reset; 
    // Clock Management 
    clock_divisor clock_divisor (clk_pc, 
           clk_instruction_memory, 
           clk_alu, 
           clk_registers, 
           clk_pc, 
           clk_instruction_memory, 
           clk_alu, 
           clk_registers); 
    initial begin 
     clk_pc = 1; 
    end 

    initial 
    #500 $finish; 


    initial begin 
    //$display (" Pc\tCLK\treset\tCurrent-inst"); 
    //$monitor(" %d\t%b\t%b\t%h", pc, clk_pc, reset, current_instruction); 

    //Monitor Clocks 
    $display (" CLK0\tCLK1\tCLK2\tCLK3"); 
    $monitor(" %b\t%b\t%b\t%b", clk_pc, clk_instruction_memory, clk_alu, clk_registers); 
    end 

endmodule 

Quelqu'un peut-il me dire pourquoi je reçois cette erreur et comment puis-je faire fonctionner mon module comme prévu?

+1

quel genre d'erreur? Aussi. arrêtez d'utiliser les 'affectations procédurales', ce sont les instructions avec' assign' dans le bloc 'always'. Dans votre banc d'essai, vous devez modifier les entrées de votre module. Vous n'avez pas, donc rien ne change. – Serge

+0

Merci pour le commentaire: Im getting: 'error: clk_pc Impossible d'attribuer aux fils non résolus.'Qu'est-ce que je devrais utiliser à la place des affectations procédurales? –

+0

vous devez utiliser des affectations normales non bloquantes dans ce cas. c'est-à-dire 'clk1_out <= 1;' – Serge

Répondre

1

(désolé, ma réputation est trop faible pour commenter)

Comme d'autres ont dit, ne pas utiliser les affectations de procédure dans des blocs toujours. Les éléments séquentiels ne doivent avoir que des affectations non bloquantes (< =) et des éléments combinatoires bloquant uniquement les affectations (=). Ne les mélangez pas dans un bloc de code. En outre, votre conception ne synthétisera pas en raison de plusieurs signaux dans la liste de blocage de bloc.

Si vous voulez synchroniser vos signaux d'horloge, utilisez-en un et synchronisez-en d'autres. Ceci est très simple si vous utilisez un registre à décalage rotatif de 4 bits et assignez des sorties d'horloge à un bit correspondant dans le registre à décalage.

registre à décalage:

module clock_divisor(input clk0, 
       input rst_i, 
       output clk0_out, 
       output clk1_out, 
       output clk2_out, 
       output clk3_out); 

reg [3:0] shift_reg; 

always @ (posedge clk0 or negedge rst_i) begin 
    if(rst_i) begin 
     shift_reg <= 4'd1; 
    end 
    else begin 
     shift_reg <= {shift_reg[2:0], shift_reg[3]}; 
    end 
end 

assign clk0_out = shift_reg[0]; 
assign clk1_out = shift_reg[1]; 
assign clk2_out = shift_reg[2]; 
assign clk3_out = shift_reg[3]; 

endmodule 

enter image description here

Fréquence de toutes les sorties d'horloge est le même que CLK0! Ils ont juste un déphasage de 180 °.

Mais si vous voulez vraiment faire un diviseur d'horloge, il suffit d'utiliser un simple compteur:

module clock_divisor(input clk0, 
       input rst_i, 
       output clk0_out, 
       output clk1_out, 
       output clk2_out, 
       output clk3_out); 

reg [3:0] counter; 

always @ (posedge clk0 or negedge rst_i) begin 
    if(rst_i) begin 
     counter <= 4'd0; 
    end 
    else begin 
     counter <= counter + 1'd1; 
    end 
end 

assign clk0_out = counter[0]; 
assign clk1_out = counter[1]; 
assign clk2_out = counter[2]; 
assign clk3_out = counter[3]; 

endmodule 

enter image description here

Maintenant, la fréquence des clk_out de sont:

  • clk0_out = 2 * clk0
  • clk1_out = 4 * clk0
  • clk2_out = 8 * clk0
  • clk3_out = 16 * CLK0

Hope this vous aide!

P.S. N'oubliez pas d'ajouter un signal de réinitialisation pour les registres! Ceci est crucial, donc votre conception peut commencer à partir d'un état connu.