2016-05-24 8 views
0

私はVerilogで非常に新しいです。 これは私の質問です:出力がオーバーラップしたときに出力に固執する種類

16ビットレジスタを持つ16ビットALUを実装します。このプロジェクトは、次の要件を満たす必要があります。
1. 16 bitALUを設計してください。 Xを入力として(例えばA、B ..)16ビットの結果を生成する16ビットALUを設計します.ALUは以下の機能を実行する必要があります。 ALUとLOGICの両方で5回以上の操作。
2. 16x16ビットのレジスタファイルを設計します。
3.コントロールユニットを設計します。

私の計画では、各モジュールに操作があるモジュールを作ります。それから私はテストベンチでそれを集める。しかし問題は今です。出力が重なり、赤とxになるようです。

これは私のAddモジュールです。

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モジュール(マイナスモジュール)

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モジュール(乗算モジュール)

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モジュール

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モジュール

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 

、これは私のテストベンチ

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

あなたのSは3ビットの一定のビット幅を持っていますか? –

+0

あなたのenb信号の動作は何ですか? clkサイクルのエッジで変化するか、または任意のエッジで変化するか、またはclkサイクルとは独立しているか? –

答えて

1

は、HDLコーディングしながら、ポイントを次の世話をされています組み合わせたハードウェアのためのシーケンシャルなハードウェアと=ため

  1. 使用<=
  2. はすなわち

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

、適切な方法でなかれ
Sまたはその逆
  • インスタンス化モジュール内割り当てる使用しないでください
  • クロックエッジに入力遷移WRTを指定

    01:
    は、ブロックの
  • 階層トポロジを遅らせる#を明示的に使用の使用を避けます

    enter image description here

    ALUは、トップレベルのエンティティであり、お互いに接続されている、または共有信号が一番上にあるサブモジュールを含んでいます。

    Testbenchは、DUT(Designed Topはテスト対象)のインスタンスの最上位レベルを持っています - テスト中の設計。

    基本的に信号をDUTに刺激し、同じ信号から応答を得る。

    複数のモジュールから同じ信号をドライブしていないことを確認してください。例えば、Yは、ALUのadd、sub、mul、AND、ORモジュールによって駆動されます。

    組み合わせ回路が「clk」をまったく必要としないため、clk信号が削除されました。

    上向きに述べたように、それを修正し、結核であなたのきれいなコードを参照してください:

    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 
    

    シミュレーション:手始めに

    enter image description here

    +0

    すみません。私はなぜ波のためにY1などを持っている必要があるのか​​分かりますか?その機能は何ですか? – diniebee

    +0

    Yのみをすべてのモジュールに接続し、たとえばS = 011とすると、ORモジュールはYを駆動するだけでなく、他のすべてのモジュールも駆動します。他のすべてのモジュールが8'b0000_0000にドライブし、ORモジュールが8 ' b0000_0011ならばYは8'b0000_00XXになります。単線はマルチ駆動できないため、別々の信号を渡す必要があります。 –

    +0

    私は今、その明確な希望ですか? –

    0

    は、GateOrとGateAndが自分のS信号に違法な範囲を持っていますモジュール...

    input [BITS - 14:0] S; 
    

    with BITS = 8 makesそれは...まあ、[-6:0]。それとは別に、すべての出力をYに一度に駆動しています。そして、あなたのモジュールではANDではなく論理ORを実行しているので、それらはすべて同時にアクティブになります。

    あなたのデザインは完全に間違っています。各サブブロックをクロックに依存しないようにする必要があります(クロック駆動のブロックではなくalways @(*)ブロックを使用します)。次に、上位モジュールですべてをインスタンス化し、それぞれの出力をY_AddY_TolakY_DarabY_GateOrおよびY_GateAndシグナル。

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

    そしてYreg、ないwireであることを確認してください:最後に、トップレベルであなたのような何かを言うクロックドブロックを持つことができます。基本的には、マルチプレクサから駆動される値でレジスタを実装します。

    +0

    申し訳ありませんが、私はまだこれで新しいです。私はもっと学びます。ありがとう – diniebee

    +0

    いいです。 VerilogとRTLは一般的に頭がおかしくなるまで頭がおかしくなります。 – eSedano

    関連する問題