Multifile Templates¶
Sometimes you need to generate multiple related files from a single template group. embgen supports multifile templates for these cases.
Use Cases¶
- Header and Source — Generate both
.hand.cfiles together - Multiple Modules — Generate several related SystemVerilog files
- Split Output — Separate definitions from implementations
Naming Convention¶
Multifile templates use the _multi suffix:
Different Extensions (Same Group)¶
Generate files with different extensions:
CLI usage: --c-multi generates both files
Same Extension (With Suffix)¶
Generate multiple files with the same extension:
CLI usage: --sv-multi generates both files
Examples¶
C Header and Source¶
Create two templates for header and implementation:
template.c_multi.h.j2:
// {{ name }}.h - Generated by embgen
#ifndef {{ name | upper }}_H
#define {{ name | upper }}_H
{% for item in config.items %}
void {{ item.name }}(void);
{% endfor %}
#endif
template.c_multi.c.j2:
// {{ name }}.c - Generated by embgen
#include "{{ name }}.h"
{% for item in config.items %}
void {{ item.name }}(void) {
// Implementation for {{ item.name }}
}
{% endfor %}
CLI usage:
Output:
SystemVerilog Modules¶
Generate multiple related Verilog files:
templates/
├── template.sv_multi.sv.1.j2 # Top module
├── template.sv_multi.sv.2.j2 # Controller
└── template.sv_multi.sv.3.j2 # Datapath
template.sv_multi.sv.1.j2:
// {{ name }}_top.sv
module {{ name }}_top (
input clk,
input rst_n
);
{{ name }}_ctrl ctrl_inst (...);
{{ name }}_dp dp_inst (...);
endmodule
template.sv_multi.sv.2.j2:
template.sv_multi.sv.3.j2:
CLI usage:
Output:
Mixing Single and Multifile¶
You can have both single-file and multifile templates in the same domain:
templates/
├── template.h.j2 # Single: --h
├── template.md.j2 # Single: --md
├── template.c_multi.h.j2 # Multifile: --c-multi
└── template.c_multi.c.j2 # Multifile: --c-multi
CLI usage:
# Generate just the header
embgen mydomain config.yml -o output/ --h
# Generate header + source pair
embgen mydomain config.yml -o output/ --c-multi
# Generate everything
embgen mydomain config.yml -o output/ --h --md --c-multi
Output Filename Patterns¶
| Template | Config Name | Output File |
|---|---|---|
template.h.j2 |
MyConfig |
myconfig.h |
template.c_multi.h.j2 |
MyConfig |
myconfig.h |
template.c_multi.c.j2 |
MyConfig |
myconfig.c |
template.sv_multi.sv.1.j2 |
MyConfig |
myconfig_1.sv |
template.sv_multi.sv.2.j2 |
MyConfig |
myconfig_2.sv |
The base filename comes from config.output_filename (which defaults to the lowercase name or can be overridden with the file field).
Python API¶
When using the Python API, multifile groups are discovered separately:
from embgen.templates import discover_templates
single_templates, multifile_groups = discover_templates(templates_path)
# single_templates: {"h": ("C Header", "template.h.j2"), ...}
# multifile_groups: {"c": MultifileGroup(...), "sv": MultifileGroup(...)}
# Access multifile group info
c_group = multifile_groups["c"]
print(c_group.description) # "C Source"
print(c_group.templates) # [TemplateInfo(...), TemplateInfo(...)]
Generating multifile output:
from embgen.generator import CodeGenerator
code_gen = CodeGenerator(generator, output_path)
# Generate a multifile group
for template_info in multifile_groups["c"].templates:
code_gen.render_to_file(
config,
template_info.filename,
template_info.output_ext,
template_info.suffix,
)
Template Discovery Rules¶
- Templates must end in
.j2or.jinja - Files starting with
_are ignored (use for includes) - Single templates:
template.<ext>.j2 - Multifile templates:
template.<group>_multi.<ext>[.<suffix>].j2
The group name becomes the CLI flag: --<group>-multi