diff --git a/Changes b/Changes
index 70834a094..d9ebb1599 100644
--- a/Changes
+++ b/Changes
@@ -5,6 +5,8 @@ The contributors that suggested a given feature are shown in []. Thanks!
 
 * Verilator 4.109 devel
 
+****  Fix TIMESCALE warnings on primitives (#2763). [Xuanqi]
+
 
 * Verilator 4.108 2021-01-10
 
diff --git a/src/V3LinkLevel.cpp b/src/V3LinkLevel.cpp
index 8572a25e9..b8f2aa104 100644
--- a/src/V3LinkLevel.cpp
+++ b/src/V3LinkLevel.cpp
@@ -103,10 +103,12 @@ void V3LinkLevel::timescaling(const ModVec& mods) {
     for (AstNodeModule* nodep : mods) {
         if (nodep->timeunit().isNone()) {
             if (modTimedp && !VN_IS(nodep, Iface)
+                && !VN_IS(nodep, Primitive)
                 && !(VN_IS(nodep, Package) && VN_CAST(nodep, Package)->isDollarUnit())) {
                 nodep->v3warn(TIMESCALEMOD,
                               "Timescale missing on this module as other modules have "
                               "it (IEEE 1800-2017 3.14.2.2)\n"
+                                  << nodep->warnContextPrimary() << '\n'
                                   << modTimedp->warnOther()
                                   << "... Location of module with timescale\n"
                                   << modTimedp->warnContextSecondary());
diff --git a/test_regress/t/t_flag_timescale.out b/test_regress/t/t_flag_timescale.out
index b82ab0b9a..72dfb1fc5 100644
--- a/test_regress/t/t_flag_timescale.out
+++ b/test_regress/t/t_flag_timescale.out
@@ -1,2 +1,3 @@
-Time scale of t is 1ms / 1us
+t: Time scale of t is 1ms / 1us
+sub: Time scale of sub is 1s / 1us
 *-* All Finished *-*
diff --git a/test_regress/t/t_flag_timescale.v b/test_regress/t/t_flag_timescale.v
index ed019c442..ce1d0aee8 100644
--- a/test_regress/t/t_flag_timescale.v
+++ b/test_regress/t/t_flag_timescale.v
@@ -5,9 +5,20 @@
 // SPDX-License-Identifier: CC0-1.0
 
 module t;
+   sub sub();
    initial begin
+      $write("t: ");
       $printtimescale;
+      sub.pts();
       $write("*-* All Finished *-*\n");
       $finish;
    end
 endmodule
+
+`timescale 1s/1s
+module sub;
+   task pts;
+      $write("sub: ");
+      $printtimescale;
+   endtask
+endmodule
diff --git a/test_regress/t/t_timescale_lint_bad.out b/test_regress/t/t_timescale_lint_bad.out
index e397440d8..fece9ec2e 100644
--- a/test_regress/t/t_timescale_lint_bad.out
+++ b/test_regress/t/t_timescale_lint_bad.out
@@ -1,4 +1,6 @@
 %Error-TIMESCALEMOD: t/t_timescale_lint_bad.v:7:8: Timescale missing on this module as other modules have it (IEEE 1800-2017 3.14.2.2)
+    7 | module pre_no_ts;
+      |        ^~~~~~~~~
                      t/t_timescale_lint_bad.v:12:8: ... Location of module with timescale
    12 | module t;
       |        ^
diff --git a/test_regress/t/t_timescale_udp.pl b/test_regress/t/t_timescale_udp.pl
new file mode 100755
index 000000000..4e42b8db0
--- /dev/null
+++ b/test_regress/t/t_timescale_udp.pl
@@ -0,0 +1,22 @@
+#!/usr/bin/env perl
+if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
+# DESCRIPTION: Verilator: Verilog Test driver/expect definition
+#
+# Copyright 2003 by Wilson Snyder. This program is free software; you
+# can redistribute it and/or modify it under the terms of either the GNU
+# Lesser General Public License Version 3 or the Perl Artistic License
+# Version 2.0.
+# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
+
+scenarios(simulator => 1);
+
+compile(
+    );
+
+execute(
+    check_finished => 1,
+    );
+
+ok(1);
+
+1;
diff --git a/test_regress/t/t_timescale_udp.v b/test_regress/t/t_timescale_udp.v
new file mode 100644
index 000000000..4b30c71ef
--- /dev/null
+++ b/test_regress/t/t_timescale_udp.v
@@ -0,0 +1,43 @@
+// DESCRIPTION: Verilator: Verilog Test module
+//
+// This file ONLY is placed under The Creative Commons Public Domain, for
+// any use, without warranty, 2021 by Wilson Snyder.
+// SPDX-License-Identifier: CC0-1.0
+
+`timescale 1ns/1ns
+module t;
+   p p ();
+   initial begin
+      $write("*-* All Finished *-*\n");
+      $finish;
+   end
+endmodule
+
+`timescale 1ns/1ns
+program p;
+endprogram
+
+`celldefine
+`timescale 1ns/1ns
+
+primitive a_udp(out, in);
+output out;
+input in;
+reg out;
+
+table
+0       :   1;
+1       :   0;
+?       :   ?;
+x       :   x;
+endtable
+endprimitive
+`endcelldefine
+
+`celldefine
+module c_not(in, out);
+input in;
+output out;
+assign out = !in1;
+endmodule
+`endcelldefine