Skip to content

5. Standard Templates

simicsmp edited this page May 28, 2024 · 14 revisions

This chapter describes the standard templates included the Device Modeling Language (DML) library. The templates can be used for both registers and fields. The templates can be accessed after importing utility.dml.

The most common device register functionality is included in the standard templates.

Note that many standard templates has the same functionality and only differ by name or log-messages printed when writing or reading them. The name of the template help developers to get a quick overview of the device functionality. An example are the undocumented and reserved templates. Both have the same functionality. However, the undocumented template hints that something in the device documentation is unclear or missing, and the reserved template that the register or field should not be used by software.

The sub-sections use object as a combined name for registers and fields. The sub-sections refers to software and hardware reads and writes. Software reads and writes are defined as accesses using the io_memory interface (write/reads to memory/io mapped device). Software reads and writes use the DML built-in read and write methods. Hardware read writes are defined as accesses using Simics configuration attributes, using the DML built-in set and get methods. Device code can still modify a register or device even if hardware modification is prohibited.

Templates for reset

Reset behavior can vary quite a bit between different devices. DML has no built-in support for handling reset, but there are standard templates in utility.dml to cover some common reset mechanisms.

There are three standard reset types:

Power-on reset

The reset that happens when power is first supplied to a device.

Hard reset

Typically triggered by a physical hard reset line that can be controlled from various sources, such as a watchdog timer or a physical button. Often the same as a power-on reset.

Soft reset

This usually refers to a reset induced by software, e.g. by a register write. Not all devices have a soft reset, and some systems may support more than one type of soft reset.

Usually, the effect of a reset is that all registers are restored to some pre-defined value.

In DML, the reset types can be enabled by instantiating the templates poreset, hreset and sreset, respectively. These will define a port with the corresponding upper-case name (POWER, HRESET, SRESET), which implements the signal interface, triggering the corresponding reset type on raising edge. This happens by invoking a corresponding method (power_on_reset, hard_reset and soft_reset, respectively), in all objects implementing a given template (power_on_reset, hard_reset and soft_reset, respectively). The default is that all registers and fields implement these templates, with the default behavior being to restore to the value of the init_val parameter. The methods signal_raise and signal_lower can be overridden to add additional side effects upon device reset. One example would be to track if the reset signal is asserted to prevent interaction with the device during reset.

The default implementation of all reset methods recursively calls the corresponding reset method in all sub-objects. Thus, if a reset method is overridden in an object without calling default(), then reset is effectively suppressed in all sub-objects.

The two most common overrides of reset behavior are:

  • to reset to a different value. In the general case, this can be done with an explicit method override. In the case of soft reset, you can also use the standard template soft_reset_val which allows you to configure the reset value with a parameter soft_reset_val.

  • to suppress reset. This can be done with a standard template: sticky suppresses soft reset only, while no_reset suppresses all resets.

    It is quite common that hard reset and power-on reset behave identically. In this case, we recommend that only a HRESET port is created; this way, the presence of a POWER port is an indication that the device actually provides a distinct behavior on power cycling.

    There are some less common reset use cases:

  • In some devices, the standard reset types may not map well to the hardware, typically because there may be more than one reset type that could be viewed as a soft reset. In this case, we recommend that SRESET is replaced with device-specific port names that map better to the hardware, but that the POWER and HRESET port names are preserved if they are unambiguous.

  • In some cases, it is desirable to accurately simulate how a device acts in a powered-off state. This would typically mean that the device does not react to other stimuli until power is turned on again.

    The recommended way to simulate a powered-off state, is to let the high signal level of the POWER port represent that the device has power, and react as if power is down while the signal is low. Furthermore, the device is reset when the POWER signal is lowered.

    If this scheme is used by a device, then a device will be considered turned off after instantiation, so the POWER signal must be raised explicitly before the device can function normally.

    Thus, there are two rather different ways to handle devices that have a POWER port:

    • POWER can be treated as a pure reset port, which stays low for most of the time and is rapidly raised and lowered to mark a power-on reset. This is the most convenient way to provide a power signal, but it only works if the device only uses POWER for power-on reset. If the device models power supply accurately, then it will not function as expected, because it will consider power to be off.

    • POWER can be accurately treated as a power supply, meaning that the signal is raised before simulation starts, and lowered when power goes down. A reset is triggered by a lower followed by a raise. This approach is less convenient to implement, but more correct: The device will function correctly both if the device does an accurate power supply simulation, and if it only uses POWER for power-on reset.

power_on_reset, hard_reset, soft_reset

Description

Implemented on any object to get a callback on the corresponding reset event. Automatically implemented by registers and fields.

Related Templates

poreset, hreset, sreset

poreset, hreset, sreset

Description

Implemented on the top level to get standard reset behaviour, for power-on reset, hard reset and soft reset, respectively.

Related Templates

power_on_reset, hard_reset, soft_reset

Templates for registers and fields

The following templates can be applied to both registers and fields. Most of them affect either the write or read operation; if applied on a register it will disregard fields. For instance, when applying the read_unimpl template on a register with fields, then the read will ignore any implementations of read or read_field in fields, and return the current register value (through get), ignoring any read overrides in fields. However, writes will still propagate to the fields.

soft_reset_val

Description

Implemented on a register or field. Upon soft reset, the reset value is defined by the required soft_reset_val parameter, instead of the default init_val.

Related Templates

soft_reset

ignore_write

Description

Writes are ignored. This template might also be useful for read-only fields inside an otherwise writable register. See the documentation for the read_only template for more information.

read_zero

Description

Reads return 0, regardless of register/field value. Writes are unaffected by this template.

Related Templates

read_constant

read_only

Description

The object value is read-only for software, the object value can be modified by hardware.

Log Output

First software write results in a spec_violation log-message on log-level 1, remaining writes on log-level 2. Fields will only log if the written value is different from the old value.

If the register containing the read-only field also contains writable fields, it may be better to use the ignore_write template instead, since software often do not care about what gets written to a read-only field, causing unnecessary logging.

write_only

Description

The register value can be modified by software but can't be read back, reads return 0. Only for use on registers; use read_zero for write-only fields.

Log Output

The first time the object is read there is a spec_violation log-message on log-level 1, remaining reads on log-level 2.

write_1_clears

Description

Software can only clear bits. This feature is often used when hardware sets bits and software clears them to acknowledge. Software write 1's to clear bits. The new object value is a bitwise AND of the old object value and the bitwise complement of the value written by software.

clear_on_read

Description

Software reads return the object value. The object value is then reset to 0 as a side-effect of the read.

write_1_only

Description

Software can only set bits to 1. The new object value is the bitwise OR of the old object value and the value written by software.

Related Templates

write_0_only

write_0_only

Description

Software can only set bits to 0. The new object value is the bitwise AND of the old object value and the value written by software.

Related Templates

write_1_only

read_constant

Description

Reads return a constant value.

Writes are unaffected by this template. The read value is unaffected by the value of the register or field.

The template is intended for registers or fields that have a stored value that is affected by writes, but where reads disregard the stored value and return a constant value. The attribute for the register will reflect the stored value, not the value that is returned by read operations. For constant registers or fields that do not store a value, use the constant template instead.

Parameters

read_val: the constant value

Related Templates

constant, silent_constant, read_zero

constant

Description

Writes are forbidden and have no effect.

The object still has backing storage, which affects the value being read. Thus, an end-user can modify the constant value by writing to the register's attribute. Such tweaks will survive a reset.

Using the constant template marks that the object is intended to stay constant, so the model should not update the register value, and not override the read method. Use the template read_only if that is desired.

Log Output

First write to register or field (if field value is not equal to write value) results in a spec_violation log-message on log-level 1, remaining writes on log-level 2.

Parameters

init_val: the constant value

Related Templates

read_constant, silent_constant, read_only

silent_constant

Description

The object value will remain constant. Writes are ignored and do not update the object value.

The end-user can tweak the constant value; any tweaks will survive a reset.

By convention, the object value should not be modified by the model; if that behaviour is wanted, use the ignore_write template instead.

Parameters

init_val: the constant value

Related Templates

constant, read_constant

zeros

Description

The object value is constant 0. Software writes are forbidden and do not update the object value.

Log Output

First software write to register or field (if field value is not equal to write value) results in a spec_violation log-message on log-level 1, remaining writes on log-level 2.

ones

Description

The object is constant all 1's. Software writes do not update the object value. The object value is all 1's.

Log Output

First software write to register or field (if field value is not equal to write value) results in a spec_violation log-message on log-level 1, remaining writes on log-level 2.

ignore

Description

The object's functionality is unimportant. Reads return 0. Writes are ignored.

reserved

Description

The object is marked reserved and should not be used by software. Writes update the object value. Reads return the object value.

Log Output

First software write to register or field (if field value is not equal to write value) results in a spec-viol log-message on log-level 2. No logs on subsequent writes.

unimpl

Description

The object functionality is unimplemented. Warn when software is using the object. Writes and reads are implemented as default writes and reads.

Log Output

First read from a register results in an unimplemented log-message on log-level 1, remaining reads on log-level 3. Reads from a field does not result in a log-message. First write to a register results in an unimplemented log-message on log-level 1, remaining writes on log-level 3. First write to a field (if field value is not equal to write value) results in an unimplemented log-message on log-level 1, remaining writes on log-level 3.

Related Templates

read_unimpl, write_unimpl, silent_unimpl, design_limitation

read_unimpl

Description

The object functionality associated to a read access is unimplemented. Write access is using default implementation and can be overridden (for instance by the read_only template).

Log Output

First software read to a register results in an unimplemented log-message on log-level 1, remaining reads on log-level 3. Software reads to fields does not result in a log-message.

Related Templates

unimpl, write_unimpl, silent_unimpl, design_limitation

write_unimpl

Description

The object functionality associated to a write access is unimplemented. Read access is using default implementation and can be overridden (for instance by the write_only template).

Log Output

First software write to registers results in an unimplemented log-message on log-level 1, remaining writes on log-level 3. First write to a field (if field value is not equal to write value) results in an unimplemented log-message on log-level 1, remaining writes on log-level 3.

Related Templates

unimpl, read_unimpl, silent_unimpl, design_limitation

silent_unimpl

Description

The object functionality is unimplemented, but do not print a lot of log-messages when reading or writing. Writes and reads are implemented as default writes and reads.

Log Output

First software read to a register results in an unimplemented log-message on log-level 2, remaining reads on log-level 3. Software reads to fields does not result in a log-message. First software write to a register results in an unimplemented log-message on log-level 2, remaining writes on log-level 3. First write to a field (if field value is not equal to write value) results in an unimplemented log-message on log-level 2, remaining writes on log-level 3.

Related Templates

unimpl, design_limitation

undocumented

Description

The object functionality is undocumented or poorly documented. Writes and reads are implemented as default writes and reads.

Log Output

First software write and read result in a spec_violation log-message on log-level 1, remaining on log-level 2.

unmapped

Description

The register is excluded from the address space of the containing bank.

sticky

Description

Do not reset object value on soft-reset, keep current value.

design_limitation

Description

The object's functionality is not in the model's scope and has been left unimplemented as a design decision. Software and hardware writes and reads are implemented as default writes and reads. Debug registers are a prime example of when to use this template. This is different from unimplemented which is intended to be implement (if required) but is a limitation in the current model.

Related Templates

unimpl, silent_unimpl

no_reset

Description

The register's or field's value will not be changed on a hard or soft reset.

Bank related templates

function_mapped_bank

Description

Only valid in bank objects. The bank is recognized as a function mapped bank by the function_io_memory template, and is mapped to a specified function by whoever instantiates that template.

Parameters

function: the function number, an integer

Related Templates

function_io_memory

function_io_memory

Description

Only valid in implement objects named io_memory. Implements the io_memory interface by function mapping: An incoming memory transaction is handled by finding a bank that instantiates the function_mapped_bank template inside the same (sub)device as implement, and has a function number that matches the memory transaction's. If such a bank exists, the transaction is handled by that bank. If no such bank exists, an error message is logged and a miss is reported for the access.

Mapping banks by function number is a deprecated practice, still used by PCI devices for legacy reasons. It is usually easier to map a bank directly into a memory space, than using a function number as an indirection.

Note also that function numbers as defined by the PCI standard are unrelated to the function numbers of banks. They can sometimes coincide, though.

Parameters

function: the function number, an integer

Related Templates

function_mapped_bank

miss_pattern_bank

Description

Only valid in bank objects. Handles unmapped accesses by ignoring write accesses, and returning a given value for each unmapped byte. If you want to customize this behaviour, overriding unmapped_get is sufficient to also customize unmapped_read.

Parameters

miss_pattern: each missed byte in a miss read is set to this value

Connect related templates

map_target

A connect object can instantiate the template map_target. The template provides an easy way to send memory transactions to objects that can be mapped into Simics memory maps. It defines a default implementation of set which assigns the session variable map_target of type map_target_t *, which can be used to issue transactions to the connected object. It also defines a default implementation of validate which verifies that the object can be used to create a map target, i.e. the Simics API SIM_new_map_target returns a valid pointer.

The template defines the following methods:

  • read(uint64 addr, uint64 size) -> (uint64) throws

    Reads size bytes starting at addr in the connected object. Size must be 8 or less. Byte order is little-endian. Throws an exception if the read fails.

  • read_bytes(uint64 addr, uint64 size, uint8 *bytes) throws

    Reads size bytes into bytes, starting at addr in the connected object. Throws an exception if the read fails.

  • write(uint64 addr, uint64 size, uint64 value) throws

    Writes value of size bytes, starting at addr in the connected object. Size must be 8 or less. Byte order is little-endian. Throws an exception if the write fails.

  • write_bytes(uint64 addr, uint64 size, const uint8 *bytes) throws

    Writes size bytes from bytes, starting at addr in the connected object. Throws an exception if the write fails.

  • issue(transaction_t *t, uint64 addr) -> (exception_type_t)

    Provides a shorthand to the API function SIM_issue_transaction. This method is called by the read/write methods in this template. It can be overridden, e.g. to add additional atoms to the transactions, while still allowing the ease-of-use from the simpler methods.

Signal related templates

signal_port

Implements a signal interface with saved state. The current state of the signal is stored in the saved boolean high, and a spec-violation message is logged on level 2 if the signal is raised or lowered when already high or low. The methods signal_raise and signal_lower can be overridden to add additional side effects.

signal_connect

Implements a connect with a signal interface, with saved state. The current state of the signal is stored in the saved boolean signal.high. If the connect is changed while signal.high is true and the device is configured, the signal_lower method will be called on the old object, and the signal_raise method will be called on the new object. Similarly, if the device is created with signal.high set to true, the signal_raise method will be called on the connected object in the finalize phase. This behaviour can be changed by overriding the set method and/or the post_init method. The template defines the following method:

  • set_level(uint1 high): Sets the level of the signal, by calling signal_raise or signal_lower, as required. Also sets signal.high to high.

Related Templates

signal_port

Clone this wiki locally