HDLBits-Verilog 学習記録 | Verilog 言語モジュール (1)

20.モジュール

練習: ポート名またはポートの位置によって信号をモジュールに接続できます。さらに練習するために、両方の方法を試してください。二方法
ここに画像の説明を挿入します

1、ポート名で信号をモジュールに接続できます。

module top_module ( input a, input b, output out );
    mod_a instance1 (a, b, out);
endmodule

注: mod_a のポートは、top_module の入力ポートおよび出力ポートと同じ順序であり、位置に応じて左から右に適応されます。

2、ポート位置

module top_module ( input a, input b, output out );
    mod_a instance2 (.out(out), .in1(a), .in2(b));
endmodule

注: この 2 つはここで直接バインドされています。

21.位置ごとのポートの接続 | モジュールの位置

練習問題:
この問題は前の問題(モジュール)と似ています。2 つの出力と 4 つの入力をこの順序で持つ mod_a という名前のモジュールが与えられます。6 つのポートを位置に応じて、トップレベル モジュールのポート out1、out2、a、b、c、d にこの順序で接続する必要があります。

次のモジュールが与えられます。

モジュール mod_a (出力、出力、入力、入力、入力、入力);

ここに画像の説明を挿入します

module top_module ( 
    input a, 
    input b, 
    input c,
    input d,
    output out1,
    output out2
);
    mod_a instance1 ( out1, out2, a, b, c, d );
endmodule

注: これは位置に対応する単純な演習ですが、質問内の mod_a の順序を注意深く調べて、どのポートが最初に記述されているかを確認する必要があります。

22.名前によるポートの接続 | モジュール名

練習:
この問題はモジュールに似ています。2 つの出力と 4 つの入力を順に持つ mod_a という名前のモジュールが与えられます。6 つのポートを名前で最上位モジュールのポートに接続する必要があります。

mod_a のポート top_module のポート
出力 out1 out1
出力 out2 out2
入力 in1 a
入力 in2 b
入力 in3 c
入力 in4 d
次のモジュールが与えられます。

モジュール mod_a (出力 out1、出力 out2、入力 in1、入力 in2、入力 in3、入力 in4);
ここに画像の説明を挿入します

module top_module ( 
    input a, 
    input b, 
    input c,
    input d,
    output out1,
    output out2
);
    mod_a ins_mod_a ( .out1(out1), .out2(out2), .in1(a), .in2(b), .in3(c), .in4(d) );
endmodule


名前を押した場合は位置を気にせず直接綴じることができ、中の順番は自由に変更できます。
括弧内の形式: .port 名 (外部信号)。
忘れずにクリックしてください。

23.3つのモジュール | モジュールシフト

練習: 2 つの入力と 1 つの出力 (D フリップフロップを実装する) を持つモジュール my_dff が与えられます。そのうち 3 つをインスタンス化し、それらをチェーンして長さ 3 のシフト レジスタを作成します。 clk ポートはすべてのインスタンスに接続する必要があります。

提供されるモジュールは次のとおりです。 module my_dff ( input clk, input d, Output q );

内部接続を作成するには、いくつかのワイヤを宣言する必要があることに注意してください。ワイヤとモジュール インスタンスの名前付けには注意してください: 名前は一意である必要があります。ネットワーク変換: 2 つの入力と 1 つの出力を持つモジュール my_dff が得られます
( D フリップフロップ)。そのうち 3 つをインスタンス化し、それらをチェーンして長さ 3 のシフト レジスタを形成します。clk ポートはすべてのインスタンスに接続する必要があります。
提供されるモジュールは次のとおりです。 module my_dff (入力 clk、入力 d、出力 q);

ここに画像の説明を挿入します
1. 名前でインスタンス化する

module top_module ( input clk, input d, output q );
    wire out_q1, out_q2;
    my_dff ins_dff1 ( .clk(clk), .d(d), .q(out_q1));
    my_dff ins_dff2 ( .clk(clk), .d(out_q1), .q(out_q2));
    my_dff ins_dff3 ( .clk(clk), .d(out_q2), .q(q));
endmodule

注: これは基本的に、(送信プロセス中に) 使用されるプロセス値を宣言し、後でサンプル モジュールのロジックに従ってそれらをペアにすることです。当初から、モジュールを名前に基づいて整理する方が便利だと感じていましたが、位置に基づいてモジュールを整理するのは現実的ではないとも感じていました。

2. 位置に基づくインスタンス化は
機能しないはずですが、私の能力が十分ではない可能性があります。

24.モジュールとベクター | モジュールシフト8

演習: この演習は module_shift の拡張です。モジュール ポートが単一のピンだけである代わりに、ポートとしてベクトルを持つモジュールが用意されており、これにプレーン ワイヤの代わりにワイヤ ベクトルを接続します。Verilog の他の場所と同様、ベクトルの長さは、ポートはそれに接続するワイヤと一致する必要はありませんが、これによりベクトルのゼロパディングまたは切り捨てが発生します。この演習ではベクトル長が一致しない接続は使用されません。この作業は module_shift の拡張です
単一のピンを持つモジュール ポートの代わりに、ポートとしてベクトルを持つモジュールが用意され、通常のワイヤの代わりにワイヤ ベクトルを接続します。Verilog の他の部分と同様、ポートのベクトルの長さはそれに接続されているワイヤと一致する必要はありませんが、これによりベクトルのゼロ パディングや切り捨てが発生する可能性があります。この演習では、ベクトルの長さが一致しない結合は使用しません。

2 つの入力と 1 つの出力 (8 つの D フリップフロップのセットを実装する) を備えたモジュール my_dff8 が与えられ、そのうちの 3 つをインスタンス化し、それらをチェーンして長さ 3 の 8 ビット幅のシフト レジスタを作成します。 sel[1:0]: 最初、2 番目、または 3 番目の D フリップフロップの後、入力 d の値に応じて出力するものを選択する 4 対 1 マルチプレクサ (提供されていません) を作成します。 (基本的に、sel は入力を遅延させるサイクル数を 0 から 3 クロック サイクルまで選択します。)
2 つの入力と 1 つの出力を持つモジュール my_dff8 が得られます (8 つの D フリップフロップのセットを実装します)。そのうち 3 つをインスタンス化し、それらをチェーンして、長さ 3 の 8 ビット幅のシフト レジスタを形成します。さらに、sel[1:0] に基づいて 4 対 1 マルチプレクサ (提供されません) を作成します: 入力 d の値、最初の d の後、2 番目の後、または 3 番目の後の値 D フリップフロップ後の値。(基本的に、sel は入力を遅延するサイクル数を 0 から 3 クロック サイクルまで選択します。

提供されるモジュールは次のとおりです。 module my_dff8 ( input clk, input [7:0] d, Output [7:0] q );

マルチプレクサは提供されていません。マルチプレクサを記述する方法の 1 つは、always ブロック内で case ステートメントを内部に記述することです
考えられる 1 つの記述方法は、case ステートメントを含む always ブロック内に記述することです。
ここに画像の説明を挿入します

module top_module ( 
    input clk, 
    input [7:0] d, 
    input [1:0] sel, 
    output [7:0] q 
);
    wire [7:0] out_my1, out_my2, out_my3;
    
    my_dff8 ins_my1 ( .clk(clk), .d(d), .q(out_my1));
    my_dff8 ins_my2 ( .clk(clk), .d(out_my1), .q(out_my2));
    my_dff8 ins_my3 ( .clk(clk), .d(out_my2), .q(out_my3));
    
    reg [7:0] q_t;
    always @(*)
        case(sel)
            2'b00:	q_t = d;
            2'b01:	q_t = out_my1;
            2'b10:	q_t = out_my2;
    		2'b11:	q_t = out_my3;
        endcase
    assign q = q_t;
endmodule

注: この質問の思考プロセスについて話します
1. まず、この質問は、出てきた時点で包括的な質問であると思われます。
2. 以前の質問で扱ったことがあり、書きやすいため、最初に 3 つのモジュールをインスタンス化しました。ここでは、最初にいくつかのワイヤーを宣言する必要があります。最初は連続代入を使用し、このように直接書きました

out_my1、out_my2、out_my3 に配線します。

3. 後の質問で、always と case を使用する必要性について言及されました。前の講義を聞いていたときに、この知識ポイントを聞いたのですが、よく理解できませんでした。その後、ネットで調べて本を調べました。この2つを使うことです。
出典: https://www.runoob.com/w3cnote/verilog-process-structural.html
画像出典:https://www.runoob.com/w3cnote/verilog-process-structural.html
しかし、これがよくわからなかったので、
最後にケースを見て、例でたまたまalwaysを使用していましたが、画像出典
ここに画像の説明を挿入します
:https://www.runoob.com/w3cnote/verilog-case.htmlで
、always@の使い方を確認(※)
ここに画像の説明を挿入します
4.それで実行してみましたが、コンパイルは成功したが、結果がすべて正しくなかった場合 00の結果は正しいが、以下の結果はすべて間違っている場合、out_myの幅が定義されていないのではないかと考え、次のように変更しました。

wire [7:0] out_my1,out_my2,out_my3;

5. 質問のまとめ:質問をするのが一番早く学習できることがわかり、授業を聞いている時にはわからなかった部分も、今ならかなり理解できるようになります。質問に基づいて方法を見つけることができ、より効率的ですが、この間、インターネットで回答を見るのに抵抗がありました。

おすすめ

転載: blog.csdn.net/qq_43374681/article/details/132465942