Use Bus Signals to Improve Readability of Model and Generate HDL Code
You can follow these guidelines to learn about bus signals, how to model your design by using these signals, and generate HDL code. Each guideline has a severity level that indicates the level of compliance requirements. To learn more, see HDL Modeling Guidelines Severity Levels.
When to Use Buses?
If your DUT or other blocks in your model have many input or output signals, you can create bus signals to improve the readability of your model. A bus signal or bus is a composite signal that consists of other signals that are called elements. The bus signal can have a structure of different data types or a vector signal with the same data types. If all signals have the same data type, you generally use a Mux block. The constituent signals or elements of a bus can be:
Mixed data type signals such as double, integer, and fixed-point
Mixed scalar and vector elements
Mixed real and complex signals
Other buses nested to any level
HDL Coder Support for Buses
You can generate HDL code for designs that have:
DUT subsystem ports connected to buses.
Simulink® and Stateflow® blocks supported for HDL code generation.
HDL Coder™ supports code generation for bus-capable blocks in the HDL Coder block library. Bus-capable blocks are blocks that can accept bus signals as input and produce bus signals as outputs. For a list of bus-capable blocks that Simulink supports, see Bus-Capable Blocks.
See Signal and Data Type Support for blocks that support HDL code generation with buses.
Create Bus Signals
You can create bus signals by using Bus Creator blocks. A Bus Creator block assigns a name to each signal that it creates. You can then refer to signals by name when you search for their sources.
For an example that illustrates how to model with buses, open
hdlcoder_bus_nested.slx. Double-click the
open_system('hdlcoder_bus_nested') set_param('hdlcoder_bus_nested','SimulationCommand','Update') open_system('hdlcoder_bus_nested/HDL_DUT')
In this model, the Bus Creator blocks create two bus signals. One bus signal contains
CounterForParam signals. The other bus signal contains
sin signals. By default, each signal on the bus inherits the name of the signal connected to the bus. This figure shows the Elements in the bus block parameter for the Bus Creator block that takes inputs
You see another Bus Creator block that combines these two bus signals. When one or more inputs to a Bus Creator block is a bus, the output is a nested bus.
The Bus Creator block generates names for bus signals whose corresponding inputs do not have names. The names are in the form
signaln, where n is the number of the port the input signal connects to. For example, if you open the Block Parameters dialog box for the second Bus Creator block, you see Elements in the bus as
Assign Signal Values to Bus
To change bus element values, use a Bus Assignment block. Use a Bus Assignment block to change bus element values without adding Bus Selector and Bus Creator blocks that select bus elements and reassemble them into a bus.
For example, open the model
open_system('hdlcoder_bus_nested_assignment') set_param('hdlcoder_bus_nested_assignment','SimulationCommand','Update') open_system('hdlcoder_bus_nested_assignment/HDL_DUT')
In the model, you see a Bus Assignment block that assigns the value
5 to the
data1_En signal in the bus.
Select Bus Outputs
To extract the signals from a bus that includes nested buses, use Bus Selector blocks. By default, the block outputs the specified bus elements as separate signals. You can also output the signals as another bus. You can use the
OutputSignals block property to see the Elements in the bus that the block outputs. By using this property, you can track which signals are entering a Bus Selector block deep within your model hierarchy.
get_param('hdlcoder_bus_nested/HDL_DUT/Bus Selector5', 'OutputSignals')
ans = 'signal1.data1_En,signal1.CounterForParam,Param_sin.Param,Param_sin.sin'
Generate HDL Code
To generate HDL code for this model, run this command:
You see that the code generator expands the bus signals to scalar signals in the generated code. For example, if you open the generated Verilog file for the
HDL_DUT Subsystem, for the Delay block that takes the two nested bus signals
Param_sin, you see four always blocks created for each signal in the bus. For example, you see an always block for the
data1_En signal that is part of
signal1. This figure displays the scalar signals created for each bus signal in the module definition.
Simplify Subsystem Bus Interfaces
You can simplify the Subsystem bus interfaces by using Bus Element blocks. The In Bus Element and Out Bus Element blocks provide a simplified and flexible way to use bus signals as inputs and outputs to subsystems. The In Bus Element block is equivalent to an Inport block combined with a Bus Selector block. The Out Bus Element block is equivalent to an Outport block combined with a Bus Creator block. To refactor an existing model that uses Inport, Bus Selector, Bus Creator, and Outport blocks to use In Bus Element and Out Bus Element blocks, you can use Simulink Editor action bars.
For example, open the model
hdlcoder_bus_nested_simplified. This model is functionally equivalent to the
hdlcoder_bus_nested model but is a more simplified version.
open_system('hdlcoder_bus_nested_simplified') set_param('hdlcoder_bus_nested_simplified','SimulationCommand','Update') open_system('hdlcoder_bus_nested_simplified/HDL_DUT')
The model has two Subsystems that perform bus creation and bus selection by using Bus Element blocks. The
Bus_Creator_Subsystem combines the Outport blocks with the Bus Creator blocks to create Out Bus Element blocks.
Bus_Selection_Subsystem combines the Inport blocks with the Bus Selector blocks to create In Bus Element blocks.
To learn more, see Simplify Subsystem and Model Interfaces with Bus Element Ports.
Virtual and Nonvirtual Buses
The bus signals in the model
hdlcoder_bus_nested created earlier by using Bus Creator and Bus Selector blocks are virtual buses. Each bus element signal is stored in memory, but the bus signal is not stored. The bus simplifies the graph but has no functional effect. In the generated HDL code, you see the constituent signals but not the bus signal.
To more easily track the correspondence between a bus signal in the model and the generated HDL code, use nonvirtual buses. Nonvirtual buses generate clean HDL code because it uses a structure to hold the bus signals. To convert a virtual bus to a nonvirtual bus, in the Block Parameters of the Bus Creator blocks, you specify the Output data type as
Bus: object_name by replacing
object_name with the name of the bus object and then select Output as nonvirtual bus.
See Convert Virtual Bus to Nonvirtual Bus.
Array of Buses
An array of buses is an array whose elements are buses. Each element in an array of buses must be nonvirtual and must have the same data type.
To learn more about modeling with array of buses, see Generating HDL Code for Subsystems with Array of Buses.