Skip to content

Commit 916b9de

Browse files
committed
synth: keep mocked memories by default
Signed-off-by: Øyvind Harboe <[email protected]>
1 parent e511371 commit 916b9de

File tree

4 files changed

+45
-14
lines changed

4 files changed

+45
-14
lines changed

docs/user/FlowVariables.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,10 +242,11 @@ configuration file.
242242
| <a name="SYNTH_HDL_FRONTEND"></a>SYNTH_HDL_FRONTEND| Select an alternative language frontend to ingest the design. Available option is "slang". If the variable is empty, design is read with the Yosys read_verilog command.| |
243243
| <a name="SYNTH_HIERARCHICAL"></a>SYNTH_HIERARCHICAL| Enable to Synthesis hierarchically, otherwise considered flat synthesis.| 0|
244244
| <a name="SYNTH_HIER_SEPARATOR"></a>SYNTH_HIER_SEPARATOR| Separator used for the synthesis flatten stage.| .|
245+
| <a name="SYNTH_KEEP_MOCKED_MEMORIES"></a>SYNTH_KEEP_MOCKED_MEMORIES| Keeping the mocked memories(not flattening them), preserves some of the access logic complexity and avoids optimizations outside of the mocked memory.| 1|
245246
| <a name="SYNTH_KEEP_MODULES"></a>SYNTH_KEEP_MODULES| Mark modules to keep from getting removed in flattening.| |
246247
| <a name="SYNTH_MEMORY_MAX_BITS"></a>SYNTH_MEMORY_MAX_BITS| Maximum number of bits for memory synthesis. Ideally, real RAM or realistic fakeram should be used for RAMs much larger than 1024 bits. To temporarily ignore the RAM concerns and investigate other aspects of the design, consider setting `SYNTH_MOCK_LARGE_MEMORIES=1`, or adjusting `SYNTH_MEMORY_MAX_BITS`.| 4096|
247248
| <a name="SYNTH_MINIMUM_KEEP_SIZE"></a>SYNTH_MINIMUM_KEEP_SIZE| For hierarchical synthesis, we keep modules of larger area than given by this variable and flatten smaller modules. The area unit used is the size of a basic nand2 gate from the platform's standard cell library. The default value is platform specific.| 0|
248-
| <a name="SYNTH_MOCK_LARGE_MEMORIES"></a>SYNTH_MOCK_LARGE_MEMORIES| Reduce memories larger than SYNTH_MEMORY_MAX_BITS to 1 row. This is useful and convenient to separate the concern of instantiating and placing memories from investigating other issues with a design, though it comes at the expense of the increased accuracy that using realistic fakemem would provide. Memories with a single 1 row will of course have unrealistically good timing and area characteristics, but timing will still correctly terminate in a register. Large port memories, typically register files, will still have the retain a lot of the port logic that can be useful to investigate issues. Consider using SYNTH_KEEP_MODULES to keep the modules of the mocked memories so that code outside the mocked memories is not optimized as a consequence of mocking a memory, yielding better insight into issues running the rest of the design through the ORFS flow.| 0|
249+
| <a name="SYNTH_MOCK_LARGE_MEMORIES"></a>SYNTH_MOCK_LARGE_MEMORIES| Reduce Yosys inferred memories larger than SYNTH_MEMORY_MAX_BITS to 1 row. Yosys will generally infer memories from behavioral Verilog code, whether the memories are in standalone modules or instantiated within some larger module. fakeram and empty Verilog memories(blackboxes) of memories will not be inferred memories by Yosys and are therefore not affected by this variable. This is useful and convenient to separate the concern of instantiating and placing memories from investigating other issues with a design, though it comes at the expense of the increased accuracy that using realistic fakemem would provide. Memories with a single 1 row will of course have unrealistically good timing and area characteristics, but timing will still correctly terminate in a register. Large port memories, typically register files, will still have the retain a lot of the port logic that can be useful to investigate issues. This can be especially useful during development of designs where the behavioral model comes first and suitable memories are matched up when the design RTL is stable. A typical use case would be Chisel which will generate a behavioral model for a memories with the required clocks, ports, etc. in addition to a computer readable file with the specification of the memories that is used to [automatically](https://chipyard.readthedocs.io/en/stable/Tools/Barstools.html/) match up suitable memory macros later in the flow. During an architectural screening study, a large range of memory configurations can be investigated quickly with this option, without getting bogged down in the concern of how to realize the memories in silicon for emphemral RTL configurations that exist only long enough to run through the ORFS flow to create a table of some characteristics of a design configuration.| 0|
249250
| <a name="SYNTH_NETLIST_FILES"></a>SYNTH_NETLIST_FILES| Skips synthesis and uses the supplied netlist files. If the netlist files contains duplicate modules, which can happen when using hierarchical synthesis on indvidual netlist files and combining here, subsequent modules are silently ignored and only the first module is used.| |
250251
| <a name="SYNTH_OPT_HIER"></a>SYNTH_OPT_HIER| Optimize constants across hierarchical boundaries.| |
251252
| <a name="SYNTH_RETIME_MODULES"></a>SYNTH_RETIME_MODULES| *This is an experimental option and may cause adverse effects.* *No effort has been made to check if the retimed RTL is logically equivalent to the non-retimed RTL.* List of modules to apply automatic retiming to. These modules must not get dissolved and as such they should either be the top module or be included in SYNTH_KEEP_MODULES. The main use case is to quickly identify if performance can be improved by manually retiming the input RTL. Retiming will treat module ports like register endpoints/startpoints. The objective function of retiming isn't informed by SDC, even the clock period is ignored. As such, retiming will optimize for best delay at potentially high register number cost. Automatic retiming can produce suboptimal results as its timing model is crude and it doesn't find the optimal distribution of registers on long pipelines. See OR discussion #8080.| |
@@ -282,6 +283,7 @@ configuration file.
282283
- [SYNTH_GUT](#SYNTH_GUT)
283284
- [SYNTH_HDL_FRONTEND](#SYNTH_HDL_FRONTEND)
284285
- [SYNTH_HIERARCHICAL](#SYNTH_HIERARCHICAL)
286+
- [SYNTH_KEEP_MOCKED_MEMORIES](#SYNTH_KEEP_MOCKED_MEMORIES)
285287
- [SYNTH_KEEP_MODULES](#SYNTH_KEEP_MODULES)
286288
- [SYNTH_MEMORY_MAX_BITS](#SYNTH_MEMORY_MAX_BITS)
287289
- [SYNTH_MINIMUM_KEEP_SIZE](#SYNTH_MINIMUM_KEEP_SIZE)

flow/designs/sky130hd/microwatt/config.mk

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,6 @@ ifeq ($(SYNTH_MOCK_LARGE_MEMORIES),1)
4242
# These module names comes from the error report when setting SYNTH_MEMORY_MAX_BITS=2048
4343
# and SYNTH_MOCK_LARGE_MEMORIES=0
4444
#
45-
# Keeping them avoids mocking them away, which would lead to further optimizations
46-
# that would obscure what is going on in the rest of the design.
47-
export SYNTH_KEEP_MODULES=decode1_0_bf8b4530d8d246dd74ac53a13471bba17941dff7 \
48-
decode1_0_bf8b4530d8d246dd74ac53a13471bba17941dff7 \
49-
fpu \
50-
decode1_0_bf8b4530d8d246dd74ac53a13471bba17941dff7 \
51-
decode1_0_bf8b4530d8d246dd74ac53a13471bba17941dff7 \
52-
decode1_0_bf8b4530d8d246dd74ac53a13471bba17941dff7
5345
# The goal is to run through the flow quickly to learn what we can
5446
# about the design without getting bogged down in memory issues.
5547
export SYNTH_MEMORY_MAX_BITS ?= 1024

flow/scripts/synth.tcl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ if { !$::env(SYNTH_HIERARCHICAL) } {
5959
if { $::env(SYNTH_MOCK_LARGE_MEMORIES) } {
6060
memory_collect
6161
set select [tee -q -s result.string select -list t:\$mem_v2]
62+
set report_file [open $::env(REPORTS_DIR)/synth_mocked_memories.txt "w"]
6263
foreach path [split [string trim $select] "\n"] {
6364
set index [string first "/" $path]
6465
set module [string range $path 0 [expr { $index - 1 }]]
@@ -71,8 +72,15 @@ if { $::env(SYNTH_MOCK_LARGE_MEMORIES) } {
7172
if { $nbits > $::env(SYNTH_MEMORY_MAX_BITS) } {
7273
rtlil::set_param -uint $module $instance SIZE 1
7374
puts "Shrunk memory $path from $size rows to 1"
75+
puts -nonewline $report_file "$module:\n width: $width\n size: $size\n"
76+
if { $::env(SYNTH_KEEP_MOCKED_MEMORIES) } {
77+
select -module $module
78+
setattr -mod -set keep_hierarchy 1
79+
select -clear
80+
}
7481
}
7582
}
83+
close $report_file
7684
}
7785

7886
json -o $::env(RESULTS_DIR)/mem.json

flow/scripts/variables.yaml

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,15 @@ SYNTH_MEMORY_MAX_BITS:
186186
- synth
187187
SYNTH_MOCK_LARGE_MEMORIES:
188188
description: >
189-
Reduce memories larger than SYNTH_MEMORY_MAX_BITS to 1 row.
189+
Reduce Yosys inferred memories larger than SYNTH_MEMORY_MAX_BITS to 1 row.
190+
191+
Yosys will generally infer memories from behavioral Verilog code, whether
192+
the memories are in standalone modules or instantiated within some
193+
larger module.
194+
195+
fakeram and empty Verilog memories(blackboxes) of memories will not
196+
be inferred memories by Yosys and are therefore not affected by
197+
this variable.
190198
191199
This is useful and convenient to separate the concern of instantiating
192200
and placing memories from investigating other issues with a design,
@@ -200,13 +208,34 @@ SYNTH_MOCK_LARGE_MEMORIES:
200208
Large port memories, typically register files, will still have the
201209
retain a lot of the port logic that can be useful to investigate issues.
202210
203-
Consider using SYNTH_KEEP_MODULES to keep the modules of the mocked
204-
memories so that code outside the mocked memories is not
205-
optimized as a consequence of mocking a memory, yielding better insight
206-
into issues running the rest of the design through the ORFS flow.
211+
This can be especially useful during development of designs where the
212+
behavioral model comes first and suitable memories are matched up
213+
when the design RTL is stable.
214+
215+
A typical use case would be Chisel which will generate a behavioral model
216+
for a memories with the required clocks, ports, etc. in addition to a
217+
computer readable file with the specification of the memories that
218+
is used to
219+
[automatically](https://chipyard.readthedocs.io/en/stable/Tools/Barstools.html/)
220+
match up suitable memory macros later in the flow.
221+
222+
During an architectural screening study, a large range of memory
223+
configurations can be investigated quickly with this option,
224+
without getting bogged down in the concern of how to realize the
225+
memories in silicon for emphemral RTL configurations that exist
226+
only long enough to run through the ORFS flow to create a table
227+
of some characteristics of a design configuration.
207228
default: 0
208229
stages:
209230
- synth
231+
SYNTH_KEEP_MOCKED_MEMORIES:
232+
description: >
233+
Keeping the mocked memories(not flattening them), preserves some of
234+
the access logic complexity and avoids optimizations outside
235+
of the mocked memory.
236+
default: 1
237+
stages:
238+
- synth
210239
SYNTH_HDL_FRONTEND:
211240
description: >
212241
Select an alternative language frontend to ingest the design. Available option

0 commit comments

Comments
 (0)