Verilog Timescale Scope

本文详细介绍了Verilog中的时标(timescale)概念,包括默认时标、标准时标作用域以及不同Verilog文件之间的时标影响。通过实例展示了时标如何在模块和文件中生效,以及文件包含顺序对时标定义的影响。强调了在每个文件顶部定义时标的必要性,以确保所有模块采用正确的时标,同时指出了编译器可能提供的默认时标覆盖选项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文地址:https://www.chipverify.com/verilog/verilog-timescale-scope

Default timescale

Although Verilog modules are expected to have a timescale defined before the module, simulators may insert a default timescale. The actual timescale that gets applied at any scope in a Verilog elaborated hierarchy can be printed using the system task $printtimescale which accepts the scope as an argument.

module tb;
	initial begin
		// Print timescale of this module
		$printtimescale(tb);
		// $printtimescale($root);
	end
endmodule

See that even though a timescale directive was not placed before this module, simulator ended up applying a 1ns/1ns timescale value.

Simulation Log

Simulation Log xcelium> run
Time scale of (tb) is  1ns /  1ns
xmsim: *W,RNQUIE: Simulation is complete.

Standard timescale scope

By default a timescale directive placed in a file is applied to all modules that follow the directive until the definition of another timescale directive.

`timescale 1ns/1ps

module tb;
  des m_des();
  alu m_alu();

  initial begin
    $printtimescale(tb);
    $printtimescale(tb.m_alu);
	$printtimescale(tb.m_des);
  end
endmodule

module alu;

endmodule

`timescale 1ns/10ps

module des;

endmodule

In the above example, tb and alu end up with a timescale of 1ns/1ns while des gets a timescale of 1ns/10ps because of the placement of directive before module definition of des

Simulation Log

xcelium> run
Time scale of (tb) is  1ns /  1ps
Time scale of (tb.m_alu) is  1ns /  1ps
Time scale of (tb.m_des) is  1ns /  10ps
xmsim: *W,RNQUIE: Simulation is complete.

Scope between Verilog files

Other files can be included into the current file using a include directive which is a pre-processor directive and makes the compiler place contents of the included file before compilation. So, this is equivalent to simply pasting the entire contents of the other file in this main file.

// main.v
`timescale 1ns/1ps

module tb;
  des m_des();
  alu m_alu();

  initial begin
    $printtimescale(tb);
    $printtimescale(tb.m_alu);
	$printtimescale(tb.m_des);
  end
endmodule

`include "file_alu.v"
`include "file_des.v"

// file_alu.v
module alu;
endmodule

// file_des.v
`timescale 1ns/10ps

module des;

endmodule

See that results are exactly the same as in previous example. alu gets a timescale of 1ns/1ps because it was last directive that stayed valid until the compiler found alu definition inspite of placing it in a different file. des gets a timescale of 1ns/10ps because the directive was replaced before its definition.

Simulation Log

xcelium> run
Time scale of (tb) is  1ns /  1ps
Time scale of (tb.m_alu) is  1ns /  1ps
Time scale of (tb.m_des) is  1ns /  10ps
xmsim: *W,RNQUIE: Simulation is complete.

Swapping files can change timescale
Order of inclusion of files play an important role in redefinition of timescale directives, which is evident in the example below.

// main.v
`timescale 1ns/1ps

module tb;
  des m_des();
  alu m_alu();

  initial begin
    $printtimescale(tb);
    $printtimescale(tb.m_alu);
	$printtimescale(tb.m_des);
  end
endmodule

// NOTE! Swapped order of inclusion
`include "file_des.v"
`include "file_alu.v"

// file_alu.v
module alu;
endmodule

// file_des.v
`timescale 1ns/10ps

module des;

endmodule

See that the module alu now gets a timescale of 1ns/10ps.

Simulation Log

xcelium> run
Time scale of (tb) is  1ns /  1ps
Time scale of (tb.m_alu) is  1ns /  10ps
Time scale of (tb.m_des) is  1ns /  10ps
xmsim: *W,RNQUIE: Simulation is complete.

This is one of the reasons for having a timescale directive at the top of files so that all modules in that file assume the correct timescale irrespective of file inclusion.

However this approach may make it difficult to compile with a different timescale precision (value following the oblique) without altering each file. Many compilers and simulators also provide an option to override default timescale values which will be applied to all modules.

### Verilog Top-Level Code Example and Guidelines In designing a top-level module in Verilog, several best practices should be followed to ensure that the design is robust, maintainable, and adheres to industry standards. The following sections provide guidance on structuring such modules. #### Module Declaration and Interface Definition A well-defined interface enhances modularity and reusability of components within larger designs. For instance: ```verilog module top_level_module ( input wire clk, input wire rst_n, input wire [7:0] data_in, output reg [7:0] data_out ); ``` This snippet declares `top_level_module` with clock (`clk`), reset (`rst_n`), and data ports defined clearly[^1]. #### Instantiation of Submodules Submodules can be instantiated within the body of the top-level module as follows: ```verilog // Instantiate submodule A submodule_A u_submodule_A ( .clk(clk), .rst_n(rst_n), .data(data_in) ); // Instantiate submodule B submodule_B u_submodule_B ( .clk(clk), .rst_n(rst_n), .input_data(u_submodule_A.output_data), .output_data(data_out) ); ``` Each instantiation uses named port connections which improve readability compared to positional mapping[^2]. #### Timescale Directive Usage At the beginning of any Verilog file containing simulation models or testbenches, it's common practice to specify time units and precision through the `timescale` directive: ```verilog `timescale 1ns / 1ps ``` Setting appropriate values ensures consistent timing behavior during simulations across different tools and platforms[^3]. #### Non-Blocking Assignments Within Always Blocks For sequential logic operations like state machines or flip-flops, non-blocking assignments are preferred over blocking ones because they better model hardware concurrency characteristics: ```verilog always @(posedge clk or negedge rst_n) begin : proc_state_register if (!rst_n) begin current_state <= IDLE; end else begin case (current_state) ... endcase end end ``` Non-blocking assignments allow all updates to occur simultaneously at the end of the process block rather than sequentially when encountered while executing lines one by one[^4]. --related questions-- 1. How does hierarchical naming facilitate debugging complex digital systems? 2. Can unnamed blocks contain local parameters accessible from outside their scope? 3. What considerations must be taken into account regarding signal widths between interconnected modules? 4. Is there any difference between synthesizing combinational versus sequential circuits concerning assignment types used inside always blocks? 5. Why might specifying too fine-grained time precisions impact synthesis results negatively?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值