2pyrtl logo2pyrtl

Writing RTL

Project settings

Every design is built against a set of settings: which language to write out, what a clock is called, whether reset is active low, how the output is indented. They live in one file in your workspace, src/ProjectConfig.py, which arrives with every setting written out at its default. Changing one is editing a line.

Nothing here is required reading to start. The defaults produce sensible Verilog, and most designers change two or three lines at most - usually the language, and the clock and reset names to match their house style.

What gets generated, and where

general_settings

The language your design is written out in, and the housekeeping around the files it produces.

SettingAcceptsDefaultWhat it does
hdl'systemverilog' or 'vhdl''systemverilog'The language your RTL is written out in. Everything else about your design stays the same; only the generated files differ.
output_files_directorya path to a directory that already exists'.'Where generated files are written. In the 2pyrtl workspace this is managed for you and is best left alone.
autogen_wire_max_name_sizea whole number below 50050A cap on the length of the wire names 2pyrtl invents for you. Raise it if generated names are being cut short in a way that makes the output hard to follow; lower it if they are simply too long to scan.
module_type_name_max_sizea whole number from 16 to 49964The longest a module type keeps its whole name. A type is a module with its parameter values, Arbiter_fixed_priority_NUM_REQUESTERS_3, and that name names its architecture file and its saved layout. A longer one is shortened as the next two settings say and ends with a CRC of the full name, so two parameter sets never share a name. Changing any of the three renames those files, and a layout saved under the old name is no longer found.
module_type_name_letters_per_worda whole number from 1 to 201In a shortened type name, how many letters of each word of a parameter name are kept: NUM_REQUESTERS becomes NR with 1, NURE with 2.
module_type_name_digits_per_valuea whole number from 0 to 200In a shortened type name, how many digits of each parameter value are kept; 0 keeps the whole value. A cut value misleads - 16 cut to one digit reads as 1 - which is why 0 is the default.

Verilog timescale

timescale_for_verilog

Written into the generated Verilog. Ignored entirely when you are generating VHDL.

SettingAcceptsDefaultWhat it does
time_unita number and a unit - fs, ps, ns, us or ms. For example '1ns' or '100ps''1ns'The unit that a delay of 1 means in your simulation.
time_precisionthe same form as above'1ps'The smallest slice of time your simulator will resolve. It should be finer than the unit above, not coarser.

Both are written as text rather than a number, because the unit is part of the value. Anything that is not a number followed by one of those five units stops the build.

House style

coding_guidelines

How the generated code is shaped and named. None of this changes what the hardware does - it changes what the file looks like to whoever reviews it.

SettingAcceptsDefaultWhat it does
indentationwhatever one level of nesting should add - spaces or a tabthree spacesThe whitespace one level of nesting adds in the generated file.
clock_edge_sync'posedge' or 'negedge''posedge'Which clock edge your sequential logic is written against.
reset_active_level0 or 10The level at which reset counts as asserted. 0 means active low. Write the number, not True or False - those are refused.
default_reset_type'async' or 'sync''async'Whether reset reaches a flip-flop asynchronously, or is clocked in.
default_clock_nameany name'clk'What your clock is called in the generated code.
default_reset_nameany name'resetn'What your reset is called in the generated code.

The default reset is called resetn because a trailing n is the usual way of writing active low, which is what the default polarity is. If you change the polarity to active high, rename it as well - otherwise the name tells a reviewer the opposite of the truth, and nothing in the tool will correct it for you.

Performance monitor

perfmon_settings

Counters 2pyrtl can build into a design so you can see what it is doing while it runs.

SettingAcceptsDefaultWhat it does
perfmon_enabledTrue or FalseTrueWhether the performance-monitoring hardware is built at all. Turning it off removes the counters and the logic that feeds them.
counter_widtha whole number from 1 to 99916How many bits each counter has, which is what decides how far it can count before wrapping back to zero.

Worth knowing

A value that is not allowed stops the build

Give a setting a value outside its list or its range and the build stops immediately, printing what it expected instead. It does not quietly fall back to the default and carry on, so you will never end up with output that ignored what you asked for.

A misspelled setting name does not stop the build

Setting a name 2pyrtl does not recognise is allowed on purpose, so that a project can carry settings of its own. It prints a single line saying it is adding a new setting, and then nothing ever reads it. So a typo does not fail - it is simply ignored, and your design is built with the default you believed you had changed. If a setting seems to have no effect, check its spelling against this page first.

One configuration serves one design

Build the configuration once in your top-level file and pass it to everything beneath it; every library component takes it as its first argument. Creating a second one part-way through gives you two separate designs that cannot see each other, which is rarely what anyone intended.

Your own copy lives in your workspace

Your workspace has its own src/ProjectConfig.py. That is the file your designs import and the one you are free to edit. It arrives with every setting written out at its default, so changing one is a matter of editing a line rather than remembering a name.

Two further groups exist inside the tool but are not offered yet: safety_settings, for functional-safety infrastructure, and timing_settings, for static timing analysis. They are named here so that meeting one in an error message is not a mystery.