9/08/2026

Verilog to SystemVerilog Transition : `timescale to timeunit & timeprecision | Episode- 01

 


In this article, we have explored important concepts related to Verilog and SystemVerilog, particularly focusing on their time-related constructs. Verilog, which is a Hardware Description Language (HDL), was widely used in digital design but lacked the advanced capabilities required to verify complex digital blocks in ASIC and SoC designs. To address these limitations, experts in the VLSI industry developed SystemVerilog, which extends Verilog beyond just a description language into a more comprehensive Hardware Description and Verification Language (HDVL). We will analyze SystemVerilog’s new features by drawing comparisons between Verilog and SystemVerilog, as well as their counterparts in traditional programming languages. Specifically, we will discuss the `timescale directive with an example, introduce the concepts of `timeunit` and `timeprecision` with practical illustrations, and explain why these were introduced over `timescale, emphasizing their benefits such as improved readability and maintainability, granular control over time precision, avoidance of redefinition conflicts, and enhanced support for mixed-time-scale designs.


What is timescale ?

`timescale : Example











In this code snippet, the timescale directive is used to set a time unit and time precision globally for all modules in the same compilation unit. While this might seem convenient at first, it introduImagine you’re designing a system with multiple modules, each representing different parts of a larger hardware design. One module, Module1, might need to operate at a high level of precision, such as nanoseconds to picoseconds (1ns/1ps), while another module, Module2, could work with less precision, such as microseconds to nanoseconds (1us/10ns).

With the timescale directive applied globally, every module in the compilation unit is forced to adhere to the same timing settings, in this case, 1ns/1ps. 


What are  timeunit and timeprecision :

timeunit and timeprecision : Example










In this code snippet, each module is granted its own control over time settings through the use of timeunit and timeprecision. This approach introduces a level of modularity and flexibility that was absent in the previous example where timescale was applied globally.

Imagine you are building a sophisticated digital system where different components operate at vastly different speeds and require varying levels of timing precision. One module, Module1, might be handling high-speed signals requiring nanosecond-level timing, while another, Module2, might be working with slower operations measured in microseconds. With this new code, each module can define its own time settings to align with its specific requirements, ensuring that simulations are both accurate and efficient.

For instance, Module1 can operate at 1ns granularity with 1ps precision, capturing fine details essential for high-speed operations. Meanwhile, Module2 uses a broader time scale of 1us with 1ns precision, which is more suited to its slower operations. This targeted approach not only reduces simulation overhead for the slower module but also avoids overloading the simulator with unnecessary precision.

By decoupling the time settings of each module, this method makes the design more adaptable. You can now develop and refine modules independently, tailoring their timing behavior to their specific roles. This modular flexibility also improves the maintainability of the code, as changes to one module’s timing settings won’t inadvertently impact others. In short, this design empowers you with greater control, precision, and efficiency in handling complex systems with diverse timing needs.

Why timeunit and timeprecision introduced over `timescale :

The timescale directive applies globally to all modules in the same compilation unit, forcing them to share the same time unit and precision. This can lead to inefficiencies when modules have different timing needs, as slower modules may use unnecessarily fine precision, and faster modules may lose required detail. It also risks unexpected behavior and makes debugging harder in mixed-timing designs.

`timeunit` and `timeprecision` are scoped declarations. They allow the user to set time units and precision per module, interface, or program, enabling better modularity and flexibility in multi-module designs. This makes it easier to design and simulate systems where different parts work at different speeds, like combining fast and slow components in one project.

Improved Readability and Maintainability:








timeunit and timeprecision are easier to read and understand because they’re written directly in the module’s syntax, making the timing settings explicit and self-contained, unlike the less intuitive timescale directive.


Granular Control of Time Precision:

`timeprecision` allows defining the precision at which time values are rounded, independently of the time unit. This avoids mismatches and issues arising from `timescale` where unit and precision are coupled.

  - Example:

    - With `timeunit 1ns; timeprecision 1ps;`, a module can express simulation times in nanoseconds but with picosecond-level precision.

    - This separation provides finer control, especially for high-precision simulations.








High precision in SystemVerilog is essential for accurately simulating and designing modern digital systems, especially those operating at high frequencies or involving fine-grain timing requirements. Consider the example of timeunit set to 1ns and timeprecision to 1ps. This allows the simulation to handle delays as small as one picosecond, ensuring no critical timing detail is lost.

Imagine designing a high-speed communication interface, like a PCIe or DDR memory controller, where timing margins are tight, and delays of just a few picoseconds can significantly affect performance. Without high precision, such subtle delays might be ignored or rounded off, leading to incorrect results or failure to capture critical timing violations. By using time-precision 1ps, the simulation ensures that these small but crucial timing differences are accounted for, resulting in a more reliable and accurate design.

Avoiding Redefinition Conflicts:

Conflict Scenario:

In this scenario, Mod1 and Mod2 are tied to conflicting timing settings. Since timescale is applied globally during compilation, it’s unclear which definition the simulator should follow. This inconsistency can cause unpredictable behavior, such as incorrect time calculations or mismatched delays between modules. It also makes debugging harder because timing dependencies may not align with the designer's intent.

Using timescale in a design can lead to conflicts when it is redefined within the same compilation unit. 

This conflict highlights why scoped declarations like timeunit and timeprecision are preferred for handling diverse timing requirements, as they allow each module to independently define its own settings without interfering with others.

Now let us see how to remove the conflicts 


In the provided code, the timeunit and timeprecision directives are modular and scoped locally within each module, ensuring there is no direct conflict when Mod1 and Mod2 are simulated together. Each module operates using its own time unit and precision—Mod1 with 1ns and 1ps and Mod2 with 1us and 1ns—allowing the $time system task to correctly display time values relative to the module's settings. The simulator resolves potential conflicts by respecting these local declarations, ensuring accurate and consistent time handling within each module's scope while allowing them to coexist harmoniously in the same simulation environment.


Better Support for Mixed-Time-Scale Designs:

In complex designs, different modules may require different time units or precision. For instance:

  - Analog/mixed-signal modules may need finer precision (e.g., 1ps).

  - Digital modules might work at coarser precision (e.g., 1ns).

- `timeunit` and `timeprecision` allow these to coexist without affecting unrelated modules.












Final conclusion:

In complex designs where modules like analog and digital components require different time units and precisions, the use of timeunit and timeprecision ensures modular flexibility and consistency. For example, the analog module uses fine precision (1ps and 1fs) for high-accuracy modeling, while the digital module operates at coarser precision (10ns and 1ns) suited for event-driven simulation. By scoping these directives locally within each module, the simulator allows them to coexist without interference, maintaining accurate timing behavior within their respective domains and enabling seamless integration in the overall design.


Watch the video lecture here: