HDL インポートを使用した Verilog データフロー モデリング
"HDL インポート" を使用して、合成可能な HDL コードを Simulink® モデリング環境にインポートします。HDL コードをインポートするには、関数 importhdl
を使用します。HDL コードで使用されている構造が HDL インポートでサポートされていることを確認します。
以下の表に、HDL コードをインポートするときに使用可能な、サポートされる Verilog® HDL データフロー パターンを示します。コードで、ラッチを推定するコードなどのサポートされていないデータフロー モデルを使用している場合、importhdl
はファイル名と行番号へのリンクを含むエラー メッセージを生成します。次に、前述の例に示すようにコードを更新できます。
サポートされる Verilog データフロー パターン
Verilog データフロー モデル | Verilog コード例 |
---|---|
連続的な always ブロックのブロッキング代入と組み合わせた always ブロックのノンブロッキング代入。 | たとえば、次の Verilog コードでは組み合わせた module dataconv(clk,a,b,c); input clk; integer i; input wire [7:0] a, b; output wire [7:0] c; reg [1:0] temp [0:7]; always @(*) begin for (i=0;i<=7;i=i+1) begin temp[i] <= a[i] + b[i]; end end assign c = temp; endmodule |
同じ信号への複数代入。その信号への部分的な代入および完全な代入を使用できます。 | 次の例は、変数 module testPartialAndCompleteAssign (input [2:0] in1, in2, input cond, clk, output [2:0] out1); reg [2:0] out1_reg; always@(posedge clk) begin if(cond) begin out1_reg[0] = 1'b0; out1_reg[1] = 1'b0; out1_reg[2] = 1'b0; end else begin out_reg = in1 & in2; end end assign out1 = out1_reg; endmodule |
推定される Switch ブロックの true パスまたは false パスの同じ変数に対する複数回代入。 | たとえば、この Verilog コードは always ブロックの if 条件と else 条件の両方の変数 module testSwitchMuxing (input [2:0] in1, input cond, output reg [2:0] out1); always@(*) begin if (cond) begin out1 = in1; end else begin out1 = 3'd2; out1 = 3'd1; end end endmodule |
信号でのビット選択、部分選択、および配列インデックス付け操作。RHS で配列インデックス演算が実行されると、Multiport Switch が推測されます。LHS での配列インデックス演算は Assign ブロックとして推測されます。 | たとえば、この Verilog コードは false 分岐で変数 module ArrayIndexing (In1, In2, In3, In4, Sel1, Sel2, Out1, Out2, Out3); parameter w = 7; input [w:0] In1, In2, In3, In4; input [1:0] Sel1, Sel2; output [w:0] Out1; output [1:0] Out2; output Out3; wire [w:0] v[3:0]; assign v[0] = In1; assign v[1] = In2; assign v[2] = In3; assign v[3] = In4; //Array indexing with signal Sel1 assign Out1 = v[Sel1]; //Part select on array index with signal Sel2 assign Out2 = v[Sel2][7:2]; //Bit select on array index with signal Sel assign Out3 = v[Sel2][4]; endmodule |
サポートされない Verilog データフロー パターン
Verilog コードをインポートする場合、これらのデータフロー構造はサポートされません。"説明とシナリオ例" 列に、各シナリオの説明と例、およびこのシナリオの回避方法を示します。
Verilog データフロー モデル | 説明とシナリオ例 |
---|---|
Verilog コードからのラッチ検出。 | HDL コード内にラッチが存在すると、生成された Simulink モデルで代数ループが発生したり、モデルのコンパイルに失敗する可能性があります。ラッチの干渉を防ぐには、if-else 条件および case ステートメントですべての分岐を指定します。 たとえば、次の Verilog コードをインポートするときに、if 条件は Switch ブロックとして推定されます。ブロックには、コード内で指定された true パスがあります。Switch ブロックの出力は false パスに入力として直接フィードバックされ、結果的に代数ループが発生します。 module testAlgebraicLoop(input cond, input [2:0] in1, output reg [2:0] out1); // causes latch inference - unsupported always@(*) begin if (cond) begin out1 = in1; end end // Specify else branch to avoid latch inference // always@(*) begin // if (cond) begin // out1 = in1; // end // else begin // out1 = in1 + 1; // end // end endmodule |
Verilog コード内のクロック、リセット、クロック イネーブル信号に対する演算の実行。 |
たとえば、次の Verilog コードは、クロック信号 module testOperationOnClkBundle (input [2:0] in1, input clk, output reg [2:0] out1, output out2); reg [2:0] out1_reg; always@(posedge clk) begin out1_reg <= in1; end assign out2 = clk && 1'b1; endmodule Verilog コードのクロック バンドルでいずれの信号に対する演算も実行していないことを確認します。さらに、コードで計算の実行に使用する信号について、それらの信号名がクロック信号、リセット信号、またはイネーブル信号と推定されるいずれの名前とも一致しないことを確認してください。クロック バンドルで信号と推定される可能性がある信号名については、関数 |
同じモジュール内の異なるクロック エッジまたは異なるリセット エッジに対するクロック信号またはリセット信号の感度。 | 正のエッジの影響を受けるクロック信号をもつ たとえば、次の Verilog コードでは同じクロックの正のエッジと負のエッジを使用していますが、これはサポートされていません。 module testMultipleClockEdges (input [2:0] in1, in2, input clk, output [2:0] out1, out2); reg [2:0] out1_reg, out2_reg; /* clk sensitivity to posedge */ always@(posedge clk) begin out1_reg <= in1 && in2; end /* clk sensitivity to neegedge */ always@(negedge clk) begin out2_reg <= in1 || in2; end assign out1 = out1_reg; assign out2 = out2_reg; endmodule Verilog コードの同じモジュールでクロック信号またはリセット信号の両方のエッジを使用していないことを確認します。クロックの |
同じモジュール内での同期回路および非同期回路の実現。 | 以下のコードに示されているように、Verilog コードを使用して同じモジュールで両方の回路を実現することはできません。非同期回路と同期回路を実現するには異なるモジュールを使用します。 module testSynchronousAsynchronous (input [2:0] in1, in2, input clk, reset, output [2:0] out1, out2); reg [2:0] out1_reg, out2_reg; /* synchronous always block */ always@(posedge clk) begin out1_reg <= in1 && in2; end /* asynchronous always block */ always@(posedge clk or posedge reset) begin out2_reg <= in1 || in2; end assign out1 = out1_reg; assign out2 = out2_reg; endmodule |
同じモジュールで推定される複数の RAM の初期化。 | たとえば、この Verilog コードは module testMultipleRAMs (input [2:0] in1, in2, input clk, reset, output reg [2:0] read_data0, read_data1); reg [2:0] out1_reg, out2_reg; /* Inference of RAM sample_store0 */ always@(posedge clk) begin if (write_enable) begin sample_store0[write_address] <= write_data; end read_data0 = sample_store0[read_address0] end /* Inference of RAM sample_store1 */ always@(posedge clk) begin if (write_enable) begin sample_store1[write_address] <= write_data; end read_data1 = sample_store0[read_address1] end endmodule |
|
たとえば、次の Verilog コードでは if-else 条件を使用して変数 module testInitial (input cond, input [3:0] write_data output reg [3:0] dout_a, dout_b, doutc); parameter AddrWidth = 3; integer i; reg [3:0] ram [7:0]; initial begin for (i=0; i<=2**AddrWidth - 1; i=i+1) begin ram[i] = 0; end dout_b = 0; // if-else condition - not supported if (cond) begin dout_a = 0; end else begin dout_a = 4; end end // Variable assignment to RHS - not supported dout_a = write_data; // Use assignment statements instead for // dout_a and dout_c // dout_a = 4; // dout_c = 32; // end // end endmodule |
使用時にすべての次元が参照されていない信号。 | 入力 Verilog コードにおける信号のすべての次元を使用します。追加の次元を指定する場合は、インデックス付きのビット選択が作成されます。 たとえば、次の Verilog コードでは module dataconv(clk,a,b,c); input clk; input wire [1:0] a, b; output wire [1:0] c; reg [7:0] temp_reg [1:0][1:0]; // temp_reg is not indexed // with both dimensions - not supported always @(posedge clk) begin temp_reg [0] <= a[0] + b[0]; temp_reg [1] <= a[1] + b[1]; end // Use both dimensions when indexing a variable // always @(posedge clk) begin // temp_reg [0][0] <= a[0] + b[0]; // temp_reg [0][1] <= a[0] + b[1]; // temp_reg [1][0] <= a[1] + b[0]; // temp_reg [1][1] <= a[1] + b[1]; // You can also perform indexed bit select // temp_reg [1][0][1] = 1'b0; // end assign c = temp_reg; endmodule |