2016-04-11 7 views
0

Ich prüfe die Funktionalität eines 8-Bit Ripple Carry Adders mit einer Testbench, die jede einzelne Kombination ausprobiert. Aus irgendeinem Grund wird die Summe der aktuellen Werte von A und B im nächsten Taktzyklus berechnet. Ich bin nicht sicher, warum das passiert. Anfangs nahm ich an, dass es wegen der Verzögerungen war, aber der Fehler tritt immer noch auf, wenn ich die Verzögerungen ändere. Hier ist mein Code:Volladdierer Summe um einen Taktzyklus

//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 

Hier ist ein Beispiel für die Ausgabe:

enter image description here

+0

Ich bekomme eine Kompilierung Warnung: 'Der folgende 1-Bit-Ausdruck ist mit 8-Bit-Port" Carry "des Moduls" Eight_adder ", Instanz" FA "verbunden." – toolic

+0

Warum bist du die gesamte Durchführung Ihres FA übergeben? Warum verwenden Sie den gleichen Übertragswert für Ihr cin und cout? Warum machst du sowohl 'und (w1, b, cin);' und 'und (w2, cin, b);'? – wilcroft

+0

@wilcroft 1Q), Nicht sicher, warum ich das tue. 2Q) Weil der Übertrag der Carryin für alle Ein-Bit-Addierer wird, wenn ich dann in Reihe einen 8-Bit-Addierer mache. 3Q) Das hätte sein sollen "und (w1, a, cin)" und "und (w2, b, cin);" Ich habe den Code bearbeitet –

Antwort

1

Sie die Berechnung der Summe in der richtigen Zyklus, aber Sie anzeigen es zu einem anderen Zeitpunkt. Bewegen Sie die $display auf einen $monitor wie folgt:

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

Ich bin überrascht, dass Sie sich nicht immer nur Xs für Ihren Summenausgang. Sie haben das Übertragsbit-Feedback zurück zum Carry-In desselben Addierers. Es sollte einen Offset geben, so dass der Übertrag eines Addierers der Übertrag eines anderen Addierers ist.

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])); 

Wie für Ihre Display-Meldung, Ihre {co,sum} wird in der gleichen Zeit-Stempel als A und B aktualisiert. Der Verilog-Scheduler bewertet die , bevor es eine Möglichkeit gibt, etwas zu berechnen. Sie können entweder eine Verzögerung vor dem $display hinzufügen (wie bei Ihrer Fehlerprüfung), $display durch $strobe ersetzen oder vor dem Schleifen $monitor verwenden. (Sie können lesen display vs strobe vs monitor in verilog?)