2016-05-24 30 views
0

Ich bin sehr neu auf Verilog. Also das ist meine Frage:Art stecken auf dem Ausgang, wenn die Ausgabe überlappen

Implementieren Sie 16 Bits ALU mit 16-Bit-Register. Dieses Projekt sollte die folgende Anforderung erfüllen.
1. Entwerfen Sie eine 16-Bit-ALU: Entwerfen Sie eine 16-Bit-ALU, die X als Eingabe (z. B. A, B ..) und erzeugt ein 16-Bit-Ergebnis.Die ALU sollte die folgenden Funktionen ausführen. Mindestens 5 Operationen für ALU und LOGIC.
2. Entwerfen Sie eine 16x16-Bit-Registerdatei.
3. Entwerfen Sie eine Steuereinheit.

Also ist mein Plan, eine Reihe von Modulen zu machen, die Operationen in jedem Modul haben. Dann sammle ich es auf dem Prüfstand. Aber das Problem ist gerade jetzt. Die Ausgabe scheint sich zu überlappen und wird rot und x.

Dies ist mein Add-Modul.

module Add(A,B,Y,S,clk,enb); 
    parameter BITS=8; 
    input clk,enb; 
    input [BITS - 5:0] S; 
    input [BITS - 1:0] A ,B; 
    output [BITS - 1:0] Y; 
    reg [BITS - 1:0] Y; 

    always @(posedge clk) 
    begin 
    if 
    ((enb==1) || (S == 000)) 
    begin 
    assign Y = A + B; 

    end 
    end 

endmodule 

Tolak Modul (Minus-Modul)

module Tolak(A,B,Y,S,clk,enb); 
    parameter BITS=8; 
    input clk,enb; 
    input [BITS - 5:0] S; 
    input [BITS - 1:0] A ,B; 
    output [BITS - 1:0] Y; 
    reg [BITS - 1:0] Y; 

    always @(posedge clk) 
begin 
    if 
    ((enb==1) || (S == 010)) 
    begin 
    assign Y = A - B; 

    end 
    end 
endmodule 

Darab Modul (Multiplikationsmodul)

module Darab(A,B,Y,S,clk,enb); 
    parameter BITS=8; 
    input clk,enb; 
    input [BITS - 5:0] S; 
    input [BITS - 1:0] A ,B; 
    output [BITS - 1:0] Y; 
    reg [BITS - 1:0] Y; 

    always @(posedge clk) 
    begin 
    if 
    ((enb==1) || (S == 011)) 
begin 
    assign Y = A * B; 
    end 
    end 

endmodule 

GateOr Modul

module GateOr(A,B,Y,S,clk,enb); 
    parameter BITS=16; 
    input clk,enb; 
    input [BITS - 14:0] S; 
    input [BITS - 1:0] A ,B; 
    output [BITS - 1:0] Y; 
    reg [BITS - 1:0] Y; 

    always @(posedge clk) 
    begin 
    if 
    ((enb==1) || (S == 011)) 
    begin 
    assign Y = A | B ; 

    end 
    end 

endmodule 

gateand Modul

module GateAnd(A,B,Y,S,clk,enb); 
    parameter BITS=16; 
    input clk,enb; 
    input [BITS - 14:0] S; 
    input [BITS - 1:0] A ,B; 
    output [BITS - 1:0] Y; 
    reg [BITS - 1:0] Y; 

    always @(posedge clk) 
begin 
    if 
    ((enb==1) || (S == 100)) 
    begin 
    assign Y = A & B; 

    end 
end 

endmodule 

und dies ist mein PRüFSTAND

module Maintb(); 
parameter SIZE=8; 
reg clk, enb ; 
reg [SIZE-6:0] S; 
reg[SIZE-1:0] A,B; 
wire[SIZE-1:0] Y; 

initial 
begin 
    clk = 1'b0; enb = 1'b0; 
end 
// generate clock 
always 
begin 
    #(10) clk = !clk; 
end 
    always begin 
    //#(10); 
    #10; enb = 1'b1; A=00000001; B=00000000; S=000; //add 
    #(10); enb = 1'b0; 
    #10; enb = 1'b1; A=00000001; B=00000000; S=001; //tolak 
    #(10); enb = 1'b0; 
    #10; enb = 1'b1; A=00000001; B=00000000; S=010; //darab 
    #(10); enb = 1'b0; 
    #10; enb = 1'b1; A=00000001; B=00000000; S=011; //or 
    #(10); enb = 1'b0; 
    #10; enb = 1'b1; A=00000001; B=00000000; S=100; //and 
    //#(10); 
    end 

defparam dut.BITS = SIZE; 
defparam dut1.BITS = SIZE; 
defparam dut2.BITS = SIZE; 
defparam gate.BITS = SIZE; 
defparam gate1.BITS = SIZE; 
Add dut (A,B,Y,S,clk,enb); //000 
Tolak dut1 (A,B,Y,S,clk,enb); //001 
Darab dut2 (A,B,Y,S,clk,enb); //010 
GateOr gate (A,B,Y,S,clk,enb); //011 
GateAnd gate1 (A,B,Y,S,clk,enb);//100 
Endmodule 
+0

Ihr S hat konstante Bitbreite von 3 Bits? –

+0

Was ist das Verhalten Ihres Enb-Signals? Ändert es sich am Rand des clk-Zyklus oder an irgendeiner Kante oder unabhängig vom clk-Zyklus? –

Antwort

1

Achten Sie darauf, Punkten zu folgen, während HDL-Codierung:

  1. Verwenden <= für sequentielle Hardware und = für kombinatorische Hardware
  2. niemals in alway s oder umgekehrt
  3. Instanziieren Modul in der richtigen Art und Weise, das heißt

<module name> #(parameter <paramters_list>) <instant_name >

  1. angeben Eingangsübergang WRT zu Taktflanken verwenden zuweisen, Verwendung von expliziter Verwendung von # vermeiden

hierarchische Topologie von Blöcken verzögern:

enter image description here

Sie können in Bild sehen, ALU ist Top-Level-Einheit und enthalten Untermodule, die miteinander verbunden sind oder gemeinsame Signale im oberen Bereich.

Testbench hat höchste Ebene oben wo Instanz DUT (Designed Top ist getestet werden) -Design im Test.

Die im Grunde Signal in das DUT stimulieren und Antwort von demselben erhalten.

Stellen Sie sicher, dass Sie nicht das gleiche Signal von mehreren Modulen übertragen, wie in Ihrem Fall ist es Y, die von Add, Sub, Mul, AND und OR-Modul der ALU, die separat sein muss, angetrieben wird.

Entfernt clk Signal, da kombinatorische Schaltung clk überhaupt nicht benötigt.

Ihren sauberen Code mit tb, es ändern, wie oben erwähnt:

module Add #(parameter BITS=8)(A,B,Y,S,enb); 
    input wire enb; 
    input wire [2:0] S; 
    input wire [BITS - 1:0] A ,B; 
    output wire [BITS - 1:0] Y; 

    assign Y = (A + B) & {BITS{enb & (S == 3'b000)}}; 

endmodule 


module Tolak #(parameter BITS=8) (A,B,Y,S,enb); 
    input enb; 
    input [2:0] S; 
    input [BITS - 1:0] A ,B; 
    output wire [BITS - 1:0] Y; 

    assign Y = (A - B) & {BITS{enb & (S == 3'b001)}}; 

endmodule 

module Darab #(parameter BITS=8) (A,B,Y,S,enb); 
    input enb; 
    input [2:0] S; 
    input [BITS - 1:0] A ,B; 
    output wire [BITS - 1:0] Y; 

    assign Y = (A * B) & {BITS{enb & (S == 3'b010)}}; // truncated to 8 bit only 

endmodule 

module GateOr #(parameter BITS=8) (A,B,Y,S,enb); 
    input enb; 
    input [2:0] S; 
    input [BITS - 1:0] A ,B; 
    output wire[BITS - 1:0] Y; 

    assign Y = (A | B) & {BITS{enb & (S == 3'b011)}}; // truncated to 8 bit only 

endmodule 

module GateAnd #(parameter BITS=8) (A,B,Y,S,enb); 
    input enb; 
    input [2:0] S; 
    input [BITS - 1:0] A ,B; 
    output wire [BITS - 1:0] Y; 

    assign Y = (A & B) & {BITS{enb & (S == 3'b100)}}; // truncated to 8 bit only 

endmodule 


module Maintb(); 
parameter SIZE=8; 
reg clk, enb ; 
reg [2:0] S; 
reg [SIZE -1:0] A,B; 
wire [SIZE -1:0] Y,Y1,Y2,Y3,Y4,Y5; 

Add #(SIZE) dut (A,B,Y1,S,enb); //000 
Tolak #(SIZE) dut1 (A,B,Y2,S,enb); //001 
Darab #(SIZE) dut2 (A,B,Y3,S,enb); //010 
GateOr #(SIZE) gate (A,B,Y4,S,enb); //011 
GateAnd #(SIZE) gate1 (A,B,Y5,S,enb);//100 

assign Y = Y1 | Y2 | Y3 | Y4 | Y5; 

initial 
begin 
    clk = 1'b0; 
    enb = 1'b0; 
    enb = 1'b0; A=8'b0000_0000; B=8'b0001_0000; S=3'b000; 
end 

// generate clock 
always #10 clk = ~clk; 

initial 
begin 
    @(posedge clk); 
    @(posedge clk); 
    @(posedge clk); 
    @(posedge clk); 
    @(posedge clk); enb = 1'b1; A=8'b0000_0001; B=8'b0000_0010; S=3'b000; //add 
    @(posedge clk); enb = 1'b0; 
    @(posedge clk); enb = 1'b1; A=8'b0000_0011; B=8'b0010_0000; S=3'b001; //tolak 
    @(posedge clk); enb = 1'b0; 
    @(posedge clk); enb = 1'b1; A=8'b0000_1001; B=8'b0000_0000; S=3'b010; //darab 
    @(posedge clk); enb = 1'b0; 
    @(posedge clk); enb = 1'b1; A=8'b0010_0001; B=8'b0100_0000; S=3'b011; //or 
    @(posedge clk); enb = 1'b0; 
    @(posedge clk); enb = 1'b1; A=8'b1000_0001; B=8'b0000_0000; S=3'b100; //and 
    @(posedge clk); enb = 1'b0; 
    @(posedge clk); enb = 1'b0; A=8'b0000_0000; B=8'b0001_0000; S=3'b000; //and 
    #100 $finish; 
end 

initial 
begin 
    $monitor("clk %b A-%b B-%b Y-%b S-%b enb-%b",clk, A, B, Y, S, enb); 
end 

endmodule 

Simulation:

enter image description here

+0

es tut mir leid. aber kann ich wissen, warum wir Y1 und so weiter für die Welle haben müssen? und was ist ihre Funktion? – diniebee

+0

Wenn Sie nur Y an alle Module anschließen, dann ist zum Beispiel S = 011, dann fahren nicht nur OR-Module Ihr Y, sondern alle anderen Module fahren es auch, nehmen Sie an, dass alle anderen es zu 8'b0000_0000 fahren und OR-Modul es zu 8 'fährt b0000_0011 dann wird Y 8'b0000_00XX. Deshalb müssen wir getrennte Signale weitergeben, da eine einzelne Leitung nicht mehrfach angesteuert werden kann. –

+0

ich hoffe es ist jetzt klar? –

0

Für Starter Module GateOr und gateand illegale Bereiche in ihrem S-Signal haben ...

input [BITS - 14:0] S; 

mit BITS = 8 Marken es ... nun, [-6: 0]. Abgesehen davon, treiben Sie alle Ausgänge gleichzeitig auf Y. Und da Sie in Ihren Modulen ein logisches ODER und kein UND ausführen, sind alle gleichzeitig aktiv.

Es tut mir leid zu sagen, Ihr Design ist völlig falsch. Sie sollten jeden Unterblock Taktunabhängig (verwenden Sie einen always @(*) Block anstelle der Uhr eines angetrieben) machen, dann im oberen Modul instantiate alle, jeder von ihnen mit ihrem Ausgang zu Y_Add angetrieben, Y_Tolak, Y_Darab, Y_GateOr und Y_GateAnd Signale. Schließlich wird in der obersten Ebene können Sie einen getakteten Block haben, der etwas sagt wie:

always @(posedge clk) 
begin: 
    if (enb == 1'b1): 
    case (S) 
     3'b000: Y <= Y_Add; 
     3'b001: Y <= Y_Tolak; 
     [...] 
    endcase 
end 

Und stellen Sie sicher Y ist ein reg, kein wire. Im Grunde werden Sie ein Register implementieren, dessen Wert von einem Multiplexer gesteuert wird.

+0

Sorry, ich bin noch neu in diesem. Ich werde mehr erfahren. Danke – diniebee

+0

Es ist in Ordnung. Verilog und RTL im Allgemeinen kann am Anfang ein bisschen schwierig sein, bis Sie sich damit befassen. – eSedano