2016-10-06 16 views
0

これは初めてのVerilog HDLプログラミングであり、私のコードに何が問題なのかわかりません。私はビヘイビアコードで単純なALUを設計する必要があります。Verilog HDLビヘイビアコーディングモジュール(ALU用)

これまでは、減算器と加算器モジュールを作成しました(他のモジュールを追加する必要がありますが、他のモジュールを追加する前に、これらのモジュールをALUモジュールで使用したいと思います)。

私は、同じプロジェクト(かなり確信して、これは行動ある?)で別々.Vファイルで以下のモジュールがあります。私はこれらをテストし、彼らが働いていることがわかり

module adder3bit(sum, co, a, b); 
parameter n = 2; 
output reg [n:0] sum; 
output reg co; 
input [n:0] a; 
input [n:0] b; 

always @(a, b) 
{co, sum} = a + b; 

endmodule 


module subtract3bit(diff, bo, a, b); 
parameter n = 2; 
output reg [n:0] diff; 
output reg bo; 
input [n:0] a; 
input [n:0] b; 

always @(a, b) 
{bo, diff} = a - b; 

endmodule 

を。

は今、私はメインALUモジュールにそれらを呼び出すしようとしています:

module alu(out, overflow, a, b,sel); 
input [2:0] a, b; 
input sel; 
output [2:0] out; 
output overflow; 
always @(a,b,sel) 
begin 
if(sel=='b0) 
    adder3bit A1(out,overflow,a,b); 
if(sel=='b1) 
    subtract3bit S1(out, overflow, a, b); 
end 
endmodule 

私の構文が間違っているかもしれないが、それはエラーを示しています。私はVerilogにはまったく慣れていません。私は最初にC.を学ぶことでどのように感じたかを感じます。

モジュールが正しく呼び出されていることはわかっていますが、if文と何か関係があると思います。

ありがとう、私は何か新しいことを学ぶことを望みます!

答えて

2

のようになります。モジュールは、呼び出せない関数やタスクではありません。モジュールでできることとできることは、別のモジュール(この場合はALUモジュール)でインスタンス化します。手続き型ブロック内でモジュールをインスタンス化することはできません(e.xは常にあなたのコード内にあります)。加算器と減算器の両方が入力の変更ごとに新しい結果を生成しますので、このモジュールの入力と出力の読み取りを適切に駆動するだけです。

私は、読みやすいように、モジュールのポートを宣言するためにあなたをアドバイス:ALUで

module adder3bit #(
    parameter N = 2 
) ( 
    output reg [N:0] sum, 
    output reg co, 
    input [N:0] a, 
    input [N:0] b 
); 
    always @(a, b) 
     {co, sum} = a + b; 

endmodule 

をあなたはこのようadder3bitをインスタンス化することができます

module alu (
    input [2:0] a, 
    input [2:0] b, 
    input sel, 
    output [2:0] out, 
    output overflow 
) 
    localparam SIZE = 3; 
    wire [SIZE - 1 : 0] diff; 
    wire [SIZE - 1 : 0] sum; 
    wire co; 
    wire bo; 

    adder3bit #( 
     .N(SIZE) 
    ) adder (
     .a(a), 
     .b(b), 
     .sum(sum), 
     .co(co) 
    ); 

    subtract3bit #( 
     .N(SIZE) 
    ) subtractor (
     .a(a), 
     .b(b), 
     .diff(diff), 
     .bo(bo) 
    ); 

    always @(*) 
    begin 
     if(sel=='b0) 
      {out,overflow) = {sum, co}; 
     if(sel=='b1) 
      {out,overflow) = {diff, bo}; 
    end 
endmodule 

そしてもう一つ、あなたのモジュールは、どのパラメータがありますそれは入力と出力のサイズを定義しますが、それは3つに固定されていることを示唆しており、混乱する可能性があります。

+1

'n'と' N'を使って違法な同じパラメータを指定します。 1つまたは別のものを選ぶ。業界といくつかのプログラミング言語の一般的な実践であるため、大文字を使用してパラメータを識別することをお勧めします。 – Greg

+0

もちろん、ありがとうございます! –

+0

ありがとうございました。したがって、モジュールは事前に初期化する必要があります。つまり、alwaysブロック内のモジュールの出力が読み取られるたびに、aとbに応じて新しい入力が読み込まれます。また、sumとdiffの2本の線を宣言する代わりに、単一のout線を使用することもできますか? – Darklink9110

0

モジュールをverilogのalwaysブロック内でインスタンス化することはできません。代わりに、モジュールadder3bitとsubtract3bitをタスクに変更することができます。あなたは今書いたようにコードを使用することができます。 ソリューションは、主な問題は、モジュールを呼び出したいということです。この

task adder3bit; 
parameter n = 2; 
input [n:0] a; 
input [n:0] b; 
output reg [n:0] sum; 
output reg co; 
begin 
always @(*) {co, sum} = a + b; 
endtask 


task subtract3bit; 
parameter n = 2; 
input [n:0] a; 
input [n:0] b; 
output reg [n:0] diff; 
output reg bo; 
begin 
always @(*) {bo, diff} = a - b; 
endtask 

module alu(out, overflow, a, b,sel); 
input [2:0] a, b; 
input sel; 
output [2:0] out; 
output overflow; 
always @(a,b,sel) 
begin 
if(sel=='b0) 
    adder3bit (a,b,out,overflow); 
if(sel=='b1) 
    subtract3bit (a,b,out,overflow); 
end 
endmodule 
+1

タスクは 'always'ブロックを含むことはできず、' parameter'sを宣言することはできません。 – Greg

+0

alwaysブロックは宣言できませんが、パラメータは... –

+0

私は構文木を十分に掘り下げずに、そのパラメータがblock_item_declarationのサブセットであることを確認しました。これ自体はタスクによって使用されるtf_item_declarationのサブセットです。しかし、LRMを再検討すると、_pure_ Verilog(IEEE 1364)がモジュールの外で定義されたタスク/機能をサポートしていないことがわかりました。 SystemVerilog(IEEE 1800)では合法です。現代のVerilogシミュレータはすべてSystemVerilogシミュレータですが、コンパイラフラグが厳密なVerilogに設定されている場合、モジュール外で定義されたタスクはコンパイルエラーになります。 – Greg

関連する問題