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
|