Verilog Dataflow Modeling with HDL Import
Use HDL import to import synthesizable HDL code into the
Simulink® modeling environment. To import the HDL code, use the importhdl
function. Make sure that the constructs used in the HDL code are supported by HDL
import.
These tables list the supported Verilog® HDL dataflow patterns that you can use when importing the HDL code. If your code
uses an unsupported dataflow model such as code that infers a latch,
importhdl
generates an error message with a link to the file name and
line number. You can then update the code as illustrated in the preceding examples.
Supported Verilog Dataflow Patterns
Verilog Dataflow Model | Example Verilog Code |
---|---|
Blocking assignments in sequential always blocks and nonblocking assignments in combinational always blocks. | For example, this Verilog code uses a sequential assignment for the variable
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 |
Multiple assignments to the same signal. You can use partial and complete assignments to that signal. | This example shows the Verilog code that performs both partial assignment and complete assignment
to the variable 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 |
Multiple assignments to the same variable in the true or false path of a Switch block that gets inferred. | For example, this Verilog code performs multiple assignments to the variable
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 |
Bit select, part select, and array indexing operations with signals. A Multiport Switch is inferred when array indexing is performed at the RHS. An array indexing operation on the LHS is inferred as an Assign block. | For example, this Verilog code uses multiple assignments to the variable
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 |
Unsupported Verilog Dataflow Patterns
These dataflow constructs are unsupported when you import the Verilog code. The Description and Example Scenarios column describes each scenario with an example and illustrates how you can avoid this scenario.
Verilog Dataflow Model | Description and Example Scenarios |
---|---|
Latch detection from the Verilog code. | Presence of latches in the HDL code can result in algebraic loops in the generated Simulink model and result in model compilation failures. To avoid latch inference, specify all branches in if-else conditions and in case statements. For example, when you import this Verilog code, the if-condition is inferred as a Switch block. The block has a true path that is specified in the code. The output of the Switch block is fed back directly as input to the false path which results Fin an algebraic loop. 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 |
Performing operations on clock, reset, or clock enable signals in the Verilog code. | When you define signals using names such as For
example, this Verilog code uses an explicit assignment with the clock signal
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 Make sure that your Verilog code does not perform
operations on any of the signals in the clock
bundle. In addition, for signals that you use for performing computations in your
code, make sure that the signal names do not match
any of the names that are inferred as clock, reset,
or enable signals. See the |
Sensitivity of clock or reset signal to different clock edges or different reset edges inside the same module. | You cannot have one For example, this Verilog code uses the positive and negative edges of the same clock, which is not supported. 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 Make sure that your Verilog code does not use both edges
of the clock or reset signal in the same module. Use either
|
Realization of synchronous and asynchronous circuits inside the same module. | You cannot use Verilog code realizes both circuits in the same module as shown in the code below. Use different modules for realization of asynchronous and synchronous circuits. 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 |
Initialization of multiple RAMs that are inferred in the same module. | For example, this Verilog code infers 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 |
Usage of certain constructs when reading initial values from an
| An For
example, this Verilog code uses an if-else condition to assign a value to the
variable 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 |
All dimensions of signals not referenced at time of usage. | Use all dimensions of a signal in the input Verilog code. If you specify an additional dimension, it creates an indexed bit select. For example, this Verilog code creates an
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 |