Verilog 2.9
Generate Constructs Can Do More Than Repeat Hardware
In the previous Unit, we learned about:
generate 'for'
A generate 'for' loop allows us to create repeated structural elements during elaboration.
For example:
genvar i;
generate
for (i = 0; i < WIDTH; i = i + 1) begin : GATES
and_gate U1(...);
end
endgenerate
Conceptually:
One structural pattern
↓
Generate 'for'
↓
Multiple structural instances are elaborated
However, sometimes we do not want to REPEAT a structure.
Instead, we want to CHOOSE which structure should exist.
For this purpose, Verilog provides conditional generate constructs such as:
generate 'if'
and:
generate 'case'
Therefore:
Generate 'for'
↓
Controls HOW MANY repeated structural elements are created
Generate 'if' / Generate 'case'
↓
Control WHICH structural alternative is elaborated
First Remember the Ordinary Procedural 'if'
We have previously used procedural conditional statements such as:
always@(*) begin
if (enable)
out = a + b;
else
out = a - b;
end
Here:
enable
is an ordinary runtime signal.
The value of enable can change while the hardware is operating.
Conceptually:
Hardware is operating
↓
enable changes
↓
Required output behavior changes
If:
enable = 1
the output follows:
a + b
If:
enable = 0
the output follows:
a - b
What Does Procedural 'if' Describe?
A procedural 'if' describes conditional BEHAVIOR.
For example:
if (enable)
out = a + b;
else
out = a - b;
means that the hardware must provide the required output according to the runtime value of:
enable
Conceptually:
a and b
↓
Required arithmetic behavior
↓
Selection according to enable
↓
out
The exact physical hardware is determined by synthesis and optimization.
Therefore, we should NOT automatically claim:
"Verilog must physically create one adder, one subtractor, and exactly one mux."
That is one useful conceptual implementation, but synthesis may optimize or restructure the logic.
The important point is:
The resulting hardware must support the required RUNTIME alternatives.
Runtime Condition
A RUNTIME CONDITION depends on a signal whose value can change while the implemented hardware is operating.
Example:
input wire enable;
Then:
if (enable)
depends on the current value of that input.
Conceptually:
enable = 0
↓
one behavior
enable changes to 1
↓
different behavior
No redesign or re-synthesis is required simply because enable changes.
The existing hardware was designed to respond to the runtime signal.
Generate 'if' Introduces a Different Idea
Now consider something like:
parameter USE_ADDER = 1;
generate
if (USE_ADDER) begin : ADD_MODE
assign out = a + b;
end
else begin : SUB_MODE
assign out = a - b;
end
endgenerate
This may LOOK similar to a procedural 'if'.
However, its purpose is fundamentally different.
Here:
USE_ADDER
is a parameter whose value is known during elaboration.
Therefore, the condition is evaluated while the design structure is being determined.
What Does Generate 'if' Do?
A generate 'if' conditionally elaborates structure according to an elaboration-time constant expression.
Conceptually:
Parameter value is resolved
↓
Generate condition is evaluated
↓
One structural alternative is selected
↓
Selected branch becomes part of the elaborated design
For example:
USE_ADDER = 1
↓
ADD_MODE is elaborated
USE_ADDER = 0
↓
SUB_MODE is elaborated
The unselected generate branch is not part of that particular elaborated configuration.
Generate 'if' Does NOT Make a Runtime Decision
This is one of the most important distinctions in the entire handwritten set.
DO NOT imagine:
FPGA is operating
↓
Check USE_ADDER
↓
Switch between generated adder and subtractor whenever USE_ADDER changes
USE_ADDER is not being used here as an ordinary runtime control signal.
Instead:
USE_ADDER
↓
Known during elaboration
↓
Determines which structural branch exists in that configured instance
Therefore:
GENERATE 'if'
≠
Runtime switching
GENERATE 'if'
=
Elaboration-time structural selection
Procedural 'if' vs Generate 'if'
PROCEDURAL 'if'
Example:
if (enable)
Condition:
Runtime signal
Purpose:
Describe conditional procedural behavior
When decision matters:
During hardware operation
Conceptually:
Existing hardware responds to the current value of enable
GENERATE 'if'
Example:
if (USE_ADDER)
Condition:
Elaboration-time constant expression, commonly based on a parameter
Purpose:
Choose which structural branch is elaborated
When decision matters:
During elaboration
Conceptually:
The selected hardware structure becomes part of that configured design
The Most Important Question to Ask
Whenever you see:
if (...)
ask:
WHAT KIND OF CONDITION IS THIS?
If the condition depends on a runtime signal such as:
enable
sel
valid
button
then you are generally dealing with runtime behavior in procedural logic.
If the condition belongs to a generate construct and depends on an elaboration-time parameter or constant expression such as:
USE_ADDER
WIDTH
MODE
then it can determine what structure is elaborated.
Therefore, the word:
if
by itself does NOT tell you whether the choice occurs at runtime or elaboration time.
Context matters.
Example: Configurable Arithmetic Module
Consider:
module arithmetic #(
parameter USE_ADDER = 1
)(
input wire [7:0] a,
input wire [7:0] b,
output wire [7:0] out
);
generate
if (USE_ADDER) begin : ADD_MODE
assign out = a + b;
end
else begin : SUB_MODE
assign out = a - b;
end
endgenerate
endmodule
This one module description can represent two different elaborated configurations.
Configuration 1: USE_ADDER = 1
Suppose the module is configured with:
USE_ADDER = 1
During elaboration:
USE_ADDER is resolved
↓
Condition is true
↓
ADD_MODE is selected
↓
Adder relationship becomes part of the elaborated design
Conceptually:
a + b
↓
out
The SUB_MODE generate branch is not part of this elaborated configuration.
Configuration 2: USE_ADDER = 0
Suppose:
USE_ADDER = 0
During elaboration:
USE_ADDER is resolved
↓
Condition is false
↓
SUB_MODE is selected
↓
Subtractor relationship becomes part of the elaborated design
Conceptually:
a - b
↓
out
The ADD_MODE generate branch is not part of this elaborated configuration.
Same Source Module, Different Hardware Configurations
This is one of the major benefits of parameter-controlled generation.
We can write one general module:
arithmetic
and configure different instances differently.
Conceptually:
Same module source
│
├── USE_ADDER = 1
│
└── Adder configuration
│
└── USE_ADDER = 0
└── Subtractor configuration
Therefore, parameterization can affect more than:
vector width
or:
number of generated copies
It can also determine which structural alternative exists.
Configuring an Instance
A parameter can be overridden when a module is instantiated.
For example:
arithmetic #(
.USE_ADDER(1)
) U_ADD (
.a(a1),
.b(b1),
.out(result1)
);
Another instance could use:
arithmetic #(
.USE_ADDER(0)
) U_SUB (
.a(a2),
.b(b2),
.out(result2)
);
Conceptually:
U_ADD
↓
elaborated with USE_ADDER = 1
↓
adder configuration
U_SUB
↓
elaborated with USE_ADDER = 0
↓
subtractor configuration
Both instances come from the same module definition but can elaborate differently.
Two Instances Can Have Different Generate Results
Suppose the same module is instantiated twice.
Instance A:
USE_ADDER = 1
Instance B:
USE_ADDER = 0
The generate condition is evaluated separately for each configured module instance.
Therefore:
Instance A
↓
ADD_MODE exists
Instance B
↓
SUB_MODE exists
This demonstrates an important idea:
Parameters configure MODULE INSTANCES.
Different instances of the same module can therefore have different elaborated structures.
Generate 'if' Is Static with Respect to Runtime
Once the design has been elaborated, synthesized, implemented, and loaded onto the FPGA, the generate choice is not something that normally changes because an input signal changes.
Suppose:
USE_ADDER = 1
Then that configuration was used to construct the design.
Changing:
a
b
enable
button
switch
during runtime does not suddenly cause:
SUB_MODE
to appear.
To obtain the other generated structure, the design must use the other elaboration-time configuration and then be synthesized/implemented accordingly.
Static Configuration vs Dynamic Selection
STATIC CONFIGURATION
Example:
parameter USE_ADDER = 1;
generate
if (USE_ADDER)
...
endgenerate
The design structure is selected before runtime.
DYNAMIC SELECTION
Example:
always@(*) begin
if (enable)
out = a + b;
else
out = a - b;
end
The hardware responds while operating according to enable.
Therefore:
Generate 'if'
↓
Static structural configuration
Procedural 'if'
↓
Dynamic runtime behavior
Why Use Generate 'if'?
Generate 'if' is useful when some hardware should exist only for certain configurations.
Examples include:
- Optional hardware features
- Different arithmetic implementations
- Different widths requiring different structures
- Debug logic enabled only in some configurations
- Optional pipeline stages
- Alternative module implementations
Conceptually:
Configuration parameter
↓
Generate condition
↓
Include appropriate structure
Generate 'if' Can Select Module Instances
A generate branch does not have to contain only:
assign
It can contain structural constructs such as module instances.
For example:
generate
if (USE_FAST_VERSION) begin : FAST
fast_module U1(...);
end
else begin : SMALL
small_module U1(...);
end
endgenerate
Conceptually:
USE_FAST_VERSION = 1
↓
fast_module instance exists
USE_FAST_VERSION = 0
↓
small_module instance exists
This is a very powerful use of conditional generation.
Named Conditional Generate Blocks
Just as with generate 'for', conditional generate blocks can be named.
For example:
if (USE_ADDER) begin : ADD_MODE
and:
else begin : SUB_MODE
The names:
ADD_MODE
and:
SUB_MODE
identify the corresponding generated scopes.
Only the selected branch exists in the elaborated hierarchy for that configuration.
This makes the hierarchy easier to understand and inspect.
Generate 'case'
Sometimes there are more than two possible structural configurations.
For example, suppose:
parameter MODE = 0;
and we want:
MODE = 0
↓
Structure A
MODE = 1
↓
Structure B
MODE = 2
↓
Structure C
Using many nested generate 'if' statements could become inconvenient.
For this situation, we can use:
generate 'case'
Basic Generate 'case' Structure
A traditional explicit form can look like:
generate
case (MODE)
0: begin : MODE_0
// structure for mode 0
end
1: begin : MODE_1
// structure for mode 1
end
2: begin : MODE_2
// structure for mode 2
end
default: begin : DEFAULT_MODE
// default structure
end
endcase
endgenerate
Here:
MODE
must be resolvable as an elaboration-time constant expression for the generate selection.
What Does Generate 'case' Do?
Conceptually:
MODE is resolved
↓
Generate 'case' examines its value
↓
Matching structural branch is selected
↓
That branch is elaborated into the configured design
For example:
MODE = 0
↓
MODE_0 exists
MODE = 1
↓
MODE_1 exists
MODE = 2
↓
MODE_2 exists
Again, this is not a runtime switching mechanism.
Generate 'if' vs Generate 'case'
GENERATE 'if'
Useful when the structural decision is naturally expressed as a condition.
Example:
if (USE_ADDER)
GENERATE 'case'
Useful when one elaboration-time value selects among several structural alternatives.
Example:
case (MODE)
0: ...
1: ...
2: ...
endcase
Conceptually:
Generate 'if'
↓
Conditional structural choice
Generate 'case'
↓
Multi-option structural choice
Procedural 'case' vs Generate 'case'
Just as there is a difference between procedural 'if' and generate 'if', there is also a difference between procedural 'case' and generate 'case'.
A PROCEDURAL 'case' can select behavior according to runtime signals.
For example:
always@(*) begin
case (sel)
2'b00: out = a;
2'b01: out = b;
2'b10: out = c;
default: out = d;
endcase
end
Here:
sel
can change while the hardware operates.
A GENERATE 'case' selects structural alternatives using an elaboration-time constant expression.
Therefore:
Procedural 'case'
↓
Runtime behavioral selection
Generate 'case'
↓
Elaboration-time structural selection
Runtime Multiplexer vs Generate Selection
Consider:
always@(*) begin
case (sel)
0: out = a;
1: out = b;
endcase
end
This describes hardware that must respond to:
sel
while operating.
Conceptually, selection logic such as a multiplexer may result.
Now consider:
generate
case (MODE)
0: begin
assign out = a;
end
1: begin
assign out = b;
end
endcase
endgenerate
MODE is resolved before runtime.
Therefore, the generated design contains the selected structural alternative.
There is no requirement for runtime selection merely because the source contains a generate 'case'.
Generate Conditions Must Be Known During Elaboration
This is a fundamental rule.
A generate condition cannot depend on an arbitrary runtime signal whose value will only be known after the hardware begins operating.
For example, conceptually:
input wire button;
generate
if (button)
...
endgenerate
is not the correct way to make hardware appear and disappear when a physical button is pressed.
Why?
Because:
button
↓
Runtime value
but:
generate 'if'
↓
Must determine structure during elaboration
If a button should control behavior during runtime, procedural or other runtime logic should be used instead.
Parameters Are Especially Useful with Generate Constructs
We have now seen three major ways parameters can influence a design.
FIRST:
Vector size
parameter WIDTH = 8;
↓
[WIDTH-1:0]
SECOND:
Amount of repeated structure
for (i = 0; i < WIDTH; i = i + 1)
THIRD:
Which structure exists
if (USE_ADDER)
or:
case (MODE)
Therefore:
PARAMETERS
↓
Can configure both the SIZE and STRUCTURE of a module
Generate 'for', Generate 'if', and Generate 'case'
We now know three major generate patterns.
GENERATE 'for'
Purpose:
Repeat structural elements.
Question answered:
"How many copies of this structural pattern should exist?"
GENERATE 'if'
Purpose:
Conditionally include one structural alternative.
Question answered:
"Should this structural branch exist?"
GENERATE 'case'
Purpose:
Choose among several structural alternatives.
Question answered:
"Which one of several structural configurations should exist?"
Generate Constructs Do Not Dynamically Reconfigure the FPGA
This is an important limitation of the mental model.
Generate constructs are HDL elaboration mechanisms.
They do NOT mean:
"The running FPGA can dynamically create and destroy arbitrary logic whenever a parameter changes."
Parameters are resolved as part of the design configuration.
Generate constructs determine the elaborated structure.
The design is then synthesized and implemented.
Therefore:
GENERATE CONSTRUCTS
≠
Runtime dynamic hardware creation
They describe STATIC structural configuration in the HDL design flow.
Generate Selection vs Synthesis Optimization
Suppose a generate 'if' excludes a branch during elaboration.
That is different from writing runtime logic and hoping synthesis notices that one path is unnecessary.
Generate selection says, conceptually:
For this configuration, elaborate this structural branch.
Then synthesis operates on the resulting elaborated design.
Conceptually:
Parameter
↓
Generate selection
↓
Elaborated structure
↓
Synthesis
↓
Optimization
↓
Implementation
Generate elaboration and synthesis optimization are related parts of the design flow, but they are not the same mechanism.
The Actual Hardware May Still Be Optimized
Suppose:
USE_ADDER = 1
and the generated configuration contains:
assign out = a + b;
That does not mean the FPGA must contain a physical object literally named:
ADD_MODE
with an implementation that exactly mirrors the source.
After elaboration:
Selected generated structure
↓
Synthesis
↓
Optimization
↓
Technology mapping
↓
Implementation
The actual FPGA resources are determined by the implementation tools.
Therefore:
GENERATED HDL STRUCTURE
≠
GUARANTEED EXACT PHYSICAL LAYOUT
Procedural Control Flow
We can now group the procedural constructs from this handwritten set.
Procedural constructs include:
for
while
repeat
if
case
These are used inside procedural contexts to describe behavior.
Examples:
always@(*) begin
if (sel)
...
end
or:
always@(*) begin
for (...)
...
end
Conceptually:
PROCEDURAL CONTROL FLOW
↓
Describes how procedural statements determine behavior
Generate Control
Generate constructs include:
generate 'for'
generate 'if'
generate 'case'
These determine structural elaboration.
Conceptually:
GENERATE CONTROL
↓
Determines repeated or conditional structure
↓
during elaboration
Therefore, although procedural and generate constructs can share keywords such as:
for
if
case
their purposes are different.
The Same Keyword Can Have Different Roles
The keywords:
for
if
case
can appear in different HDL contexts.
Therefore, do not memorize:
"if always means runtime"
or:
"for always means procedural"
Instead, examine the context.
For example:
always@(*) begin
if (enable)
...
end
↓
Procedural 'if'
generate
if (USE_FEATURE) begin
...
end
endgenerate
↓
Generate 'if'
Likewise:
for inside procedural block
↓
Procedural 'for'
for using genvar in generate context
↓
Generate 'for'
Master Comparison: Procedural 'for' vs Generate 'for'
PROCEDURAL 'for'
Typical variable:
integer i;
Typical context:
always@(*)
Purpose:
Describe repeated procedural operations.
Example:
for (i = 0; i < 8; i = i + 1)
out[i] = in[7-i];
GENERATE 'for'
Typical variable:
genvar i;
Purpose:
Create repeated structural constructs during elaboration.
Example:
for (i = 0; i < WIDTH; i = i + 1)
my_module U1(...);
Master Comparison: Procedural 'if' vs Generate 'if'
PROCEDURAL 'if'
Condition:
Runtime signal
Example:
if (enable)
Purpose:
Hardware responds conditionally while operating.
GENERATE 'if'
Condition:
Elaboration-time constant expression
Example:
if (USE_ADDER)
Purpose:
Determine which structural branch is elaborated.
Master Comparison: Procedural 'case' vs Generate 'case'
PROCEDURAL 'case'
Selector:
Runtime signal
Example:
case (sel)
Purpose:
Select runtime behavior.
GENERATE 'case'
Selector:
Elaboration-time constant expression
Example:
case (MODE)
Purpose:
Select among structural configurations during elaboration.
Runtime Behavior vs Elaborated Structure
This is the deepest distinction in this entire set.
RUNTIME BEHAVIOR asks:
"What should the already-created hardware do when its signals change?"
Examples:
if (enable)
case (sel)
always@(posedge clk)
ELABORATED STRUCTURE asks:
"What hardware structure should this configured module instance contain?"
Examples:
generate for
generate if
generate case
Therefore:
PROCEDURAL CONTROL
↓
Primarily describes behavior
GENERATE CONTROL
↓
Determines elaborated structure
A Useful Two-Question Test
When you are unsure whether something is procedural or generate-based, ask:
QUESTION 1:
Does the condition/index depend on something that changes while the hardware operates?
If YES:
Think RUNTIME behavior.
QUESTION 2:
Does the condition/index depend on a parameter or constant that is resolved while the design is being elaborated?
If YES:
Think ELABORATION-TIME structure.
This is not a replacement for checking the actual Verilog syntax, but it is a very useful conceptual test.
What Happens Before and After Elaboration?
A useful overall design-flow mental model is:
Verilog source
↓
Parameter values are determined for module instances
↓
ELABORATION
↓
Generate loops expanded
Generate conditions selected
Module hierarchy resolved
↓
Specific elaborated design
↓
SYNTHESIS
↓
Logic inference and optimization
↓
Technology mapping / implementation
↓
FPGA configuration
↓
RUNTIME OPERATION
This explains why a generate parameter is fundamentally different from a runtime input.
Common Mistake: Using Generate 'if' for a Runtime Input
Incorrect mental model:
input wire enable;
generate
if (enable)
...
endgenerate
with the expectation:
enable changes
↓
different hardware appears
That is not what generate 'if' is for.
If enable should change behavior while the hardware operates, use runtime logic appropriate for that behavior.
Generate 'if' is for elaboration-time structural selection.
Common Mistake: Assuming Both Generate Branches Exist
Suppose:
generate
if (USE_ADDER) begin : ADD_MODE
...
end
else begin : SUB_MODE
...
end
endgenerate
Do NOT think:
Both generated branches always exist and a runtime mux simply chooses between them.
For a particular elaborated configuration, the generate condition determines which branch is elaborated.
That is the key difference from runtime selection.
Common Mistake: Assuming Generate Parameters Change at Runtime
A parameter such as:
parameter MODE = 0;
is not an ordinary register.
It does not behave like:
MODE changes from 0 to 1
↓
hardware instantly transforms into another generated architecture
Instead:
MODE
↓
Used to configure/elaborate the design instance
A different MODE value represents a different configured elaboration.
Common Mistake: Thinking Procedural 'if' Guarantees a Specific Physical Mux
Consider:
if (enable)
out = a + b;
else
out = a - b;
It is reasonable to use selection logic as a conceptual model.
But do not conclude that the final FPGA must contain:
exactly one adder
+
exactly one subtractor
+
exactly one mux
Synthesis may optimize or restructure the implementation.
The correct statement is:
The resulting hardware must implement the required runtime behavior.
When Should I Use Procedural Conditional Logic?
Think of procedural 'if' or procedural 'case' when:
- A runtime signal determines behavior
- A selector changes while the hardware operates
- Combinational outputs depend on runtime conditions
- Clocked behavior depends on runtime conditions
Examples:
if (enable)
if (reset)
case (sel)
These conditions describe behavior of hardware that already exists.
When Should I Use Generate Conditional Logic?
Think of generate 'if' or generate 'case' when:
- A parameter determines which hardware feature exists
- One configuration needs a module that another configuration does not
- Several hardware architectures are available
- The structural decision is known during elaboration
Examples:
if (USE_PIPELINE)
if (ENABLE_DEBUG)
case (ARCHITECTURE)
These configure the structure before normal runtime operation.
The Entire Handwritten Set in One Picture
We started with:
PROCEDURAL 'for'
↓
Repeated procedural operations
Then:
PARAMETERS
↓
Configurable module properties
Then:
INDEXED PART-SELECTS
↓
Calculated fixed-width vector regions
Then:
ACCUMULATION
↓
Repeatedly update one result
Then:
'while'
↓
Condition-controlled procedural repetition
Then:
'repeat'
↓
Count-controlled procedural repetition
Then we changed mental models:
GENERATE 'for'
↓
Repeated structural generation during elaboration
Then:
GENERATE 'if'
↓
Conditional structural generation
Then:
GENERATE 'case'
↓
Multi-option structural generation
Final Comparison
PROCEDURAL 'for'
↓
Repeated procedural operations
'while'
↓
Procedural repetition while a condition remains true
'repeat'
↓
Procedural repetition a specified number of times
PROCEDURAL 'if'
↓
Conditional runtime procedural behavior
PROCEDURAL 'case'
↓
Multi-option runtime procedural behavior
GENERATE 'for'
↓
Repeated structural generation
GENERATE 'if'
↓
Conditional structural generation
GENERATE 'case'
↓
Multi-option structural generation
PARAMETER
↓
Elaboration-time module configuration
RUNTIME SIGNAL
↓
Value that can change while implemented hardware operates
Final Mental Model
There are two fundamentally different questions we can ask when writing Verilog.
QUESTION 1:
"What should the hardware DO while it is operating?"
This leads us toward:
PROCEDURAL BEHAVIOR
Examples:
for
while
repeat
if
case
inside appropriate procedural contexts.
QUESTION 2:
"What STRUCTURE should this configured hardware design contain?"
This leads us toward:
GENERATE CONSTRUCTS
Examples:
generate 'for'
generate 'if'
generate 'case'
For conditional selection:
Procedural 'if'
↓
Runtime signal
↓
Existing hardware responds to the signal
Generate 'if'
↓
Elaboration-time constant
↓
Determines which structural branch is elaborated
For multiple alternatives:
Procedural 'case'
↓
Runtime selector
↓
Existing hardware selects behavior
Generate 'case'
↓
Elaboration-time selector
↓
Determines which structural configuration is elaborated
The most important ideas are:
GENERATE 'if' SELECTS STRUCTURE USING AN ELABORATION-TIME CONSTANT CONDITION.
GENERATE 'case' SELECTS AMONG MULTIPLE STRUCTURAL ALTERNATIVES DURING ELABORATION.
THE UNSELECTED GENERATE BRANCH IS NOT PART OF THAT PARTICULAR ELABORATED CONFIGURATION.
A PARAMETER IS NOT AN ORDINARY RUNTIME SIGNAL.
DIFFERENT INSTANCES OF THE SAME MODULE CAN USE DIFFERENT PARAMETER VALUES AND THEREFORE ELABORATE DIFFERENT STRUCTURES.
PROCEDURAL 'if' DESCRIBES RUNTIME CONDITIONAL BEHAVIOR.
GENERATE 'if' DESCRIBES ELABORATION-TIME STRUCTURAL SELECTION.
PROCEDURAL 'case' DESCRIBES RUNTIME MULTI-WAY BEHAVIOR.
GENERATE 'case' DESCRIBES ELABORATION-TIME MULTI-WAY STRUCTURAL SELECTION.
GENERATE CONSTRUCTS DO NOT DYNAMICALLY CREATE OR DESTROY FPGA HARDWARE DURING NORMAL OPERATION.
GENERATED STRUCTURE CAN STILL BE OPTIMIZED DURING SYNTHESIS.
THE KEY DISTINCTION IS:
PROCEDURAL CONTROL FLOW
=
DESCRIBE WHAT THE HARDWARE DOES
GENERATE CONTROL
=
DETERMINE WHAT STRUCTURE THE CONFIGURED DESIGN CONTAINS