2016-04-11 1 views
0

Je teste la fonctionnalité d'un 8 bits Ripple Adder de transport avec un banc d'essai qui essaie toutes les combinaisons unique. Pour une raison quelconque, la somme des valeurs actuelles de A et B est calculée dans le cycle d'horloge suivant. Je ne sais pas pourquoi c'est happening.Initially, je suppose que ce fut à cause des retards, mais l'erreur persiste lorsque je change les retards. Voici mon code:pleine Adder Somme Off par une horloge Cycle

//one_adder.v 

module One_adder(a,b,cin,sum,carry); 
    output carry,sum; 
    input a,b,cin; 
    wire w0,w1,w2; 

     xor(sum,a,b,cin); 
     and(w0,a,b); 
     and(w1,a,cin); 
     and(w2,cin,b); 
     or(carry,w0,w1,w2); 

endmodule; 


//Eight_adder.v 

module Eight_adder(A,B,S,Carry); 
    output [7:0]S, Carry; 
    input [7:0]A, B; 
    //wire [7:0]w; 
    wire overflow; 

    One_adder add0(.carry(Carry[0]), .sum(S[0]), .a(A[0]), .b(B[0]), .cin(Carry[0])); 
    One_adder add1(.carry(Carry[1]), .sum(S[1]), .a(A[1]), .b(B[1]), .cin(Carry[1])); 
    One_adder add2(.carry(Carry[2]), .sum(S[2]), .a(A[2]), .b(B[2]), .cin(Carry[2])); 
    One_adder add3(.carry(Carry[3]), .sum(S[3]), .a(A[3]), .b(B[3]), .cin(Carry[3])); 
    One_adder add4(.carry(Carry[4]), .sum(S[4]), .a(A[4]), .b(B[4]), .cin(Carry[4])); 
    One_adder add5(.carry(Carry[5]), .sum(S[5]), .a(A[5]), .b(B[5]), .cin(Carry[5])); 
    One_adder add6(.carry(Carry[6]), .sum(S[6]), .a(A[6]), .b(B[6]), .cin(Carry[6])); 
    One_adder add7(.carry(Carry[7]), .sum(S[7]), .a(A[7]), .b(B[7]), .cin(Carry[7])); 
    assign overflow= (A[7]&B[7]&~Carry[7]) | (~A[7]&~B[7]&Carry[7]); 

endmodule 


//tBench.v 
//`timescale 1 ns/ 1 ns 

module tBench; 
    wire [7:0]sum; 
    wire cin, co; 
    reg[7:0] A, B;  // the different combinations 
//module Eight_adder(A,B,Cin,S,Cout); 
Eight_adder FA(A,B,sum,co); 

initial begin 
    for(A =0; A<255; A=A+1) 
    begin 
     #10 // the period in ModelSim: 10ns 
     for(B=0; B<255; B=B+1) 
     begin 
      $display("A=%b,, B=%b,, Sum=%b,,", A,B,{co,sum}); 
     #10 
      if({co,sum} != (A+B)) 
       $display("Error: A=%b b=%b sum=%b cout=%b\n", A, B, sum, co); 
     end 
    end 
    $finish; 
end 
endmodule 

Voici un exemple de sortie:

enter image description here

+0

Je reçois un avertissement de compilation: 'L'expression suivante 1 bit est connecté au port 8 bits "Carry" du module "Eight_adder", par exemple "FA" .' – toolic

+0

Pourquoi êtes-vous passer la totalité de votre FA? Pourquoi utilisez-vous la même valeur pour votre cin et cout? Pourquoi faites-vous à la fois 'et (w1, b, cin),' et 'et (w2, cin, b);'? – wilcroft

+0

@wilcroft 1Q), Je ne sais pas pourquoi je fais ça. 2Q) Parce que le carryout devient le carryin pour l'ensemble des additionneurs un bit quand j'ai alors en série pour faire un additionneur 8 bits. 3Q) Cela aurait dû être 'et (w1, a, cin);' et 'et (w2, b, cin); ' J'ai modifié la réponse du code –

Répondre

1

Vous êtes en calculer la somme dans le cycle correct, mais vous l'afficher à un autre moment. Déplacez le $display à un $monitor comme suit:

initial begin 
    $monitor("A=%b,, B=%b,, Sum=%b,,", A,B,{co,sum}); 
    for(A =0; A<255; A=A+1) 
    begin 
     #10 // the period in ModelSim: 10ns 
     for(B=0; B<255; B=B+1) 
     begin 
     #10 
      if({co,sum} != (A+B)) 
       $display("Error: A=%b b=%b sum=%b cout=%b\n", A, B, sum, co); 
     end 
    end 
    $finish; 
end 
1

Je suis surpris que vous ne recevez pas seulement Xs pour votre sortie de somme. Vous avez le retour de bits de carry-out retour le report du même additionneur. Il devrait y avoir un décalage de sorte que l'exécution d'un additionneur soit le report d'un autre additionneur.

One_adder add0(.carry(Carry[0]), .sum(S[0]), .a(A[0]), .b(B[0]), .cin(1'b0)); 
... 
One_adder add7(.carry(carryout), .sum(S[7]), .a(A[7]), .b(B[7]), .cin(Carry[7])); 

Comme pour votre message d'affichage, votre {co,sum} est mis à jour dans le même horodater que A et B. Le planificateur Verilog évalue la $display avant qu'il y ait l'occasion de calculer quoi que ce soit. Vous pouvez ajouter un délai avant la $display (comme vous l'avez fait avec votre vérification d'erreur), remplacer $display avec $strobe, ou utiliser $monitor avant la mise en boucle. (Vous pouvez lire display vs strobe vs monitor in verilog?)