[ast] Add prim_lfsr to ast.core

Signed-off-by: Jacob Levy <jacob.levy@opentitan.org>
diff --git a/hw/top_earlgrey/ip/ast/ast.core b/hw/top_earlgrey/ip/ast/ast.core
index 03a8c0e..b51b44a 100644
--- a/hw/top_earlgrey/ip/ast/ast.core
+++ b/hw/top_earlgrey/ip/ast/ast.core
@@ -10,10 +10,12 @@
       - lowrisc:ip:tlul
       - lowrisc:prim:all
       - lowrisc:prim:clock_buf
+      - lowrisc:prim:clock_div
       - lowrisc:prim:clock_gating
       - lowrisc:prim:clock_inv
       - lowrisc:prim:prim_pkg
       - lowrisc:prim:lc_dec
+      - lowrisc:prim:lfsr
       - lowrisc:ip:pinmux_reg
       - lowrisc:ip:pinmux_component
       - lowrisc:ip:lc_ctrl_pkg
diff --git a/hw/top_earlgrey/ip/ast/rtl/adc.sv b/hw/top_earlgrey/ip/ast/rtl/adc.sv
index 3bb9b8b..a7d7d59 100644
--- a/hw/top_earlgrey/ip/ast/rtl/adc.sv
+++ b/hw/top_earlgrey/ip/ast/rtl/adc.sv
@@ -53,7 +53,7 @@
 
 // Behavioral Model
 ////////////////////////////////////////
-int unsigned adc_d_ch0, adc_d_ch1;
+logic [10-1:0] adc_d_ch0, adc_d_ch1;
 
 `ifndef SYNTHESIS
 ast_pkg::awire_t vref;
@@ -61,11 +61,11 @@
 assign vref = 2.3;
 assign adc_vi0 = adc_a0_ai;
 assign adc_vi1 = adc_a1_ai;
-assign adc_d_ch0 = $rtoi( (adc_vi0/vref) * $itor(10'h3ff) );
-assign adc_d_ch1 = $rtoi( (adc_vi1/vref) * $itor(10'h3ff) );
+assign adc_d_ch0 = $rtoi((adc_vi0/vref) * $itor(10'h3ff));
+assign adc_d_ch1 = $rtoi((adc_vi1/vref) * $itor(10'h3ff));
 `else
-assign adc_d_ch0 = 'h31  || {9'h000, adc_a0_ai};  // 0.111V
-assign adc_d_ch1 = 'h21f || {9'h000, adc_a1_ai};  // 1.222V
+assign adc_d_ch0 = 10'h031 || {9'h000, adc_a0_ai};  // 0.111V
+assign adc_d_ch1 = 10'h21f || {9'h000, adc_a1_ai};  // 1.222V
 `endif
 
 logic [8-1:0] cnv_cyc;
diff --git a/hw/top_earlgrey/ip/ast/rtl/aon_clk.sv b/hw/top_earlgrey/ip/ast/rtl/aon_clk.sv
index 5086a37..a1282cf 100644
--- a/hw/top_earlgrey/ip/ast/rtl/aon_clk.sv
+++ b/hw/top_earlgrey/ip/ast/rtl/aon_clk.sv
@@ -13,6 +13,7 @@
   input clk_src_aon_en_i,                  // AON Source Clock Enable
   input scan_mode_i,                       // Scan Mode
   input scan_reset_ni,                     // Scan Reset
+  input clk_aon_ext_i,                     // FPGA/VERILATOR Clock input
   output logic clk_src_aon_o,              // AON Source Clock
   output logic clk_src_aon_val_o           // AON Source Clock Valid
 );
@@ -28,6 +29,7 @@
 aon_osc u_aon_osc (
   .vcore_pok_h_i ( vcore_pok_h_i ),
   .aon_en_i ( aon_clk_en ),
+  .clk_aon_ext_i ( clk_aon_ext_i ),
   .aon_clk_o ( clk )
 );  // of u_aon_osc
 
diff --git a/hw/top_earlgrey/ip/ast/rtl/aon_osc.sv b/hw/top_earlgrey/ip/ast/rtl/aon_osc.sv
index 501b301..464bfba 100644
--- a/hw/top_earlgrey/ip/ast/rtl/aon_osc.sv
+++ b/hw/top_earlgrey/ip/ast/rtl/aon_osc.sv
@@ -5,16 +5,12 @@
 // *Name: aon_osc
 // *Module Description: AON Clock Oscilator
 //############################################################################
-`ifdef SYNTHESIS
-`ifndef PRIM_DEFAULT_IMPL
-`define PRIM_DEFAULT_IMPL prim_pkg::ImplGeneric
-`endif
-`endif
 
 module aon_osc (
-  input vcore_pok_h_i,     // VCORE POK @3.3V
-  input aon_en_i,          // AON Source Clock Enable
-  output logic aon_clk_o   // AON Clock Output
+  input vcore_pok_h_i,    // VCORE POK @3.3V
+  input aon_en_i,         // AON Source Clock Enable
+  input clk_aon_ext_i,    // FPGA/VERILATOR Clock input
+  output logic aon_clk_o  // AON Clock Output
 );
 
 `ifndef SYNTHESIS
@@ -24,7 +20,7 @@
 import ast_bhv_pkg::* ;
 
 localparam time AonClkPeriod = 5000ns; // 5000ns (200Khz)
-logic clk, clk_n, en_dly, en_osc, en_osc_re, en_osc_fe;
+logic clk, en_dly;
 
 initial begin
   clk = 1'b0;
@@ -34,36 +30,42 @@
 end
 
 // Enable 5us RC Delay
-logic aon_en_dly;
+logic aon_en_dly, aon_clk_dly;
+
 assign #(AON_EN_RDLY) aon_en_dly = aon_en_i;
-assign en_osc_re = vcore_pok_h_i && aon_en_i && (aon_en_dly && en_dly);
-assign clk_n = !clk;
+assign aon_clk_dly = aon_en_dly && en_dly;
 
-// Syncronize en_osc_fe to clk FE for glitch free disable
-always_ff @( posedge clk_n or negedge vcore_pok_h_i ) begin
-  if ( !vcore_pok_h_i ) begin
-    en_osc_fe <= 1'b0;
-  end else begin
-    en_osc_fe <= en_osc_re;
-  end
-end
-
-assign en_osc = en_osc_re || en_osc_fe;  // EN -> 1 || EN -> 0
+// Clock Oscillator
+////////////////////////////////////////
+logic en_osc;
 
 always begin
   #(AonClkPeriod/2) clk = ~clk && en_osc;
 end
 `else  // of SYNTHESIS
-// SYNTHESUS/VERILATOR/LINTER/FPGA
+// SYNTHESIS/VERILATOR/LINTER/FPGA
 ///////////////////////////////////////
-localparam prim_pkg::impl_e Impl = `PRIM_DEFAULT_IMPL;
-logic clk, clk_n, en_osc, en_osc_re, en_osc_fe;
+logic aon_clk_dly;
+assign aon_clk_dly = 1'b1;
 
-assign en_osc_re = vcore_pok_h_i && aon_en_i;
-assign clk_n = !clk;
+// Clock Oscillator
+////////////////////////////////////////
+logic clk, en_osc;
+
+prim_clock_gating u_clk_ckgt (
+  .clk_i ( clk_aon_ext_i ),
+  .en_i ( en_osc ),
+  .test_en_i ( 1'b0 ),
+  .clk_o ( clk )
+);
+`endif
+
+logic en_osc_re, en_osc_fe;
+
+assign en_osc_re = vcore_pok_h_i && aon_en_i && aon_clk_dly;
 
 // Syncronize en_osc to clk FE for glitch free disable
-always_ff @( posedge clk_n or negedge vcore_pok_h_i ) begin
+always_ff @( negedge clk, negedge vcore_pok_h_i ) begin
   if ( !vcore_pok_h_i ) begin
     en_osc_fe <= 1'b0;
   end else begin
@@ -73,15 +75,8 @@
 
 assign en_osc = en_osc_re || en_osc_fe;  // EN -> 1 || EN -> 0
 
-if (Impl == prim_pkg::ImplXilinx) begin : gen_xilinx
-  // FPGA Specific (place holder)
-  ///////////////////////////////////////
-  assign clk = (/*TODO*/ 1'b1) && en_osc;
-end else begin : gen_generic
-  assign clk = (/*TODO*/ 1'b1) && en_osc;
-end
-`endif
-
+// Clock Output Buffer
+////////////////////////////////////////
 prim_clock_buf u_buf (
   .clk_i ( clk ),
   .clk_o ( aon_clk_o )
diff --git a/hw/top_earlgrey/ip/ast/rtl/ast.sv b/hw/top_earlgrey/ip/ast/rtl/ast.sv
index 8f6d0a6..d813da5 100644
--- a/hw/top_earlgrey/ip/ast/rtl/ast.sv
+++ b/hw/top_earlgrey/ip/ast/rtl/ast.sv
@@ -37,6 +37,9 @@
   input clk_ast_ext_i,                        // Buffered AST External Clock
   input por_ni,                               // Power ON Reset
 
+  // Clocks' Oschillator bypass for OS FPGA
+  input ast_pkg::clks_osc_byp_t clk_osc_byp_i,  // Clocks' Oschillator bypass for OS FPGA
+
   // power OK control
   // In non-power aware DV environment, the <>_supp_i is for debug only!
   // POK signal follow this input.
@@ -280,9 +283,11 @@
 // System Clock (Always ON)
 ///////////////////////////////////////
 logic rst_sys_clk_n, clk_sys_pd_n;
-assign rst_sys_clk_n = vcmain_pok_por;  // Scan reset included
+logic clk_sys_ext;
 
-assign clk_sys_pd_n = vcmain_pok;
+assign rst_sys_clk_n = vcmain_pok_por;  // Scan reset included
+assign clk_sys_pd_n  = vcmain_pok;
+assign clk_sys_ext   = clk_osc_byp_i.sys;
 
 sys_clk u_sys_clk (
   .clk_src_sys_jen_i ( clk_src_sys_jen_i ),
@@ -292,6 +297,7 @@
   .vcore_pok_h_i ( vcaon_pok_h ),
   .scan_mode_i ( scan_mode ),
   .scan_reset_ni ( scan_reset_n ),
+  .clk_sys_ext_i ( clk_sys_ext ),
   .clk_src_sys_o ( clk_src_sys_o ),
   .clk_src_sys_val_o ( clk_src_sys_val_o )
 );  // of u_sys_clk
@@ -306,9 +312,11 @@
 // USB Clock (Always ON)
 ///////////////////////////////////////
 logic rst_usb_clk_n, clk_usb_pd_n;
-assign rst_usb_clk_n = vcmain_pok_por;  // Scan reset included
+logic clk_usb_ext;
 
-assign clk_usb_pd_n = vcmain_pok;
+assign rst_usb_clk_n = vcmain_pok_por;
+assign clk_usb_pd_n  = vcmain_pok;
+assign clk_usb_ext   = clk_osc_byp_i.usb;
 
 usb_clk u_usb_clk (
   .vcore_pok_h_i ( vcaon_pok_h ),
@@ -319,6 +327,7 @@
   .usb_ref_pulse_i ( usb_ref_pulse_i ),
   .scan_mode_i ( scan_mode ),
   .scan_reset_ni ( scan_reset_n ),
+  .clk_usb_ext_i ( clk_usb_ext ),
   .clk_src_usb_o ( clk_src_usb_o ),
   .clk_src_usb_val_o ( clk_src_usb_val_o )
 );  // of u_usb_clk
@@ -328,7 +337,10 @@
 // AON Clock (Always ON)
 ///////////////////////////////////////
 logic rst_aon_clk_n;
- assign rst_aon_clk_n = vcaon_pok;
+logic clk_aon_ext;
+
+assign rst_aon_clk_n = vcaon_pok;
+assign clk_aon_ext   = clk_osc_byp_i.aon;
 
 aon_clk  u_aon_clk (
   .vcore_pok_h_i ( vcaon_pok_h ),
@@ -337,6 +349,7 @@
   .clk_src_aon_en_i ( 1'b1 ),  // Always Enabled
   .scan_mode_i ( scan_mode ),
   .scan_reset_ni ( scan_reset_n ),
+  .clk_aon_ext_i ( clk_aon_ext ),
   .clk_src_aon_o ( clk_src_aon_o ),
   .clk_src_aon_val_o ( clk_src_aon_val_o )
 );  // of u_aon_clk
@@ -364,9 +377,11 @@
 // IO Clock (Always ON)
 ///////////////////////////////////////
 logic clk_io_osc, clk_io_osc_val, rst_io_clk_n, clk_io_pd_n;
-assign rst_io_clk_n = vcmain_pok_por;  // scan reset included
+logic clk_io_ext;
 
-assign clk_io_pd_n = vcmain_pok;
+assign rst_io_clk_n = vcmain_pok_por;  // scan reset included
+assign clk_io_pd_n  = vcmain_pok;
+assign clk_io_ext   = clk_osc_byp_i.io;
 
 io_clk u_io_clk (
   .vcore_pok_h_i ( vcaon_pok_h ),
@@ -375,6 +390,7 @@
   .clk_src_io_en_i ( clk_src_io_en_i ),
   .scan_mode_i ( scan_mode ),
   .scan_reset_ni ( scan_reset_n ),
+  .clk_io_ext_i ( clk_io_ext ),
   .clk_src_io_o ( clk_io_osc ),
   .clk_src_io_val_o ( clk_io_osc_val )
 );  // of u_io_clk
@@ -663,7 +679,6 @@
 ast_dft u_ast_dft (
   .clk_i ( clk_ast_tlul_i ),
   .rst_ni ( rst_ast_tlul_ni ),
-  .scan_mode_i ( scan_mode ),
   .clk_io_osc_i ( clk_io_osc ),
   .clk_io_osc_val_i ( clk_io_osc_val ),
   .rst_io_clk_ni ( rst_io_clk_n ),
diff --git a/hw/top_earlgrey/ip/ast/rtl/ast_dft.sv b/hw/top_earlgrey/ip/ast/rtl/ast_dft.sv
index 774e7cd..6a0cfdc 100644
--- a/hw/top_earlgrey/ip/ast/rtl/ast_dft.sv
+++ b/hw/top_earlgrey/ip/ast/rtl/ast_dft.sv
@@ -11,7 +11,6 @@
 module ast_dft (
   input clk_i,                              // TLUL Clock
   input rst_ni,                             // TLUL Reset
-  input scan_mode_i,                        // Scan Mode
   input clk_io_osc_i,                       // IO Oscillator Clock
   input clk_io_osc_val_i,                   // IO Oscillator Clock Valid
   input rst_io_clk_ni,                      // IO Oscillator Clock Reset
@@ -32,10 +31,8 @@
 ////////////////////////////////////////
 // IO Source Clock Selection
 ////////////////////////////////////////
-logic clk_io_osc_scn;
 logic lc_clk_byp_sel, lc_clk_byp_en;
 
-assign clk_io_osc_scn = scan_mode_i ? clk_i : clk_io_osc_i;
 assign lc_clk_byp_sel = (lc_clk_byp_req_i == lc_ctrl_pkg::On);
 
 logic clks_aoff, clk_osc_en_q, clk_byp_en_q;
diff --git a/hw/top_earlgrey/ip/ast/rtl/ast_pkg.sv b/hw/top_earlgrey/ip/ast/rtl/ast_pkg.sv
index e4cac38..853576a 100644
--- a/hw/top_earlgrey/ip/ast/rtl/ast_pkg.sv
+++ b/hw/top_earlgrey/ip/ast/rtl/ast_pkg.sv
@@ -35,6 +35,17 @@
   parameter int Ast2PadOutWidth = 9;
   parameter int Pad2AstInWidth  = 6;
 
+  // These LFSR parameters have been generated with
+  // $ ./util/design/gen-lfsr-seed.py --width 64 --seed 691876113 --prefix ""
+  parameter int LfsrWidth = 64;
+  typedef logic [LfsrWidth-1:0] lfsr_seed_t;
+  typedef logic [LfsrWidth-1:0][$clog2(LfsrWidth)-1:0] lfsr_perm_t;
+  parameter lfsr_seed_t RndCnstLfsrSeedDefault = 64'h22d326255bd24320;
+  parameter lfsr_perm_t RndCnstLfsrPermDefault = {
+    128'h16108c9f9008aa37e5118d1ec1df64a7,
+    256'h24f3f1b73537f42d38383ee8f897286df81d49ab54b6bbbb666cbd1a16c41252
+  };
+
   // Memories Read-Write Margin Interface
   typedef struct packed {
     logic          marg_en_a;
@@ -107,6 +118,13 @@
     SwAck  = 1
   } ast_ack_mode_e;
 
+  // Clocks Oschillator Bypass
+  typedef struct packed {
+    logic     usb;
+    logic     sys;
+    logic     io;
+    logic     aon;
+  } clks_osc_byp_t;
 
 endpackage  // of ast_pkg
 `endif  // of __AST_PKG_SV
diff --git a/hw/top_earlgrey/ip/ast/rtl/io_clk.sv b/hw/top_earlgrey/ip/ast/rtl/io_clk.sv
index 3e9f27b..8b68d06 100644
--- a/hw/top_earlgrey/ip/ast/rtl/io_clk.sv
+++ b/hw/top_earlgrey/ip/ast/rtl/io_clk.sv
@@ -13,6 +13,7 @@
   input clk_src_io_en_i,                   // IO Source Clock Enable
   input scan_mode_i,                       // Scan Mode
   input scan_reset_ni,                     // Scan Reset
+  input clk_io_ext_i,                      // FPGA/VERILATOR Clock input
   output logic clk_src_io_o,               // IO Source Clock
   output logic clk_src_io_val_o            // IO Source Clock Valid
 );
@@ -28,6 +29,7 @@
 io_osc u_io_osc (
   .vcore_pok_h_i ( vcore_pok_h_i ),
   .io_en_i ( io_clk_en ),
+  .clk_io_ext_i ( clk_io_ext_i ),
   .io_clk_o ( clk )
 );  // of u_io_osc
 
diff --git a/hw/top_earlgrey/ip/ast/rtl/io_osc.sv b/hw/top_earlgrey/ip/ast/rtl/io_osc.sv
index 11f3b39..1baca72 100644
--- a/hw/top_earlgrey/ip/ast/rtl/io_osc.sv
+++ b/hw/top_earlgrey/ip/ast/rtl/io_osc.sv
@@ -5,16 +5,12 @@
 // *Name: io_osc
 // *Module Description: IO Clock Oscilator
 //############################################################################
-`ifdef SYNTHESIS
-`ifndef PRIM_DEFAULT_IMPL
-`define PRIM_DEFAULT_IMPL prim_pkg::ImplGeneric
-`endif
-`endif
 
 module io_osc (
-  input vcore_pok_h_i,   // VCORE POK @3.3V
-  input io_en_i,         // IO Source Clock Enable
-  output logic io_clk_o  // IO Clock Output
+  input vcore_pok_h_i,    // VCORE POK @3.3V
+  input io_en_i,          // IO Source Clock Enable
+  input clk_io_ext_i,     // FPGA/VERILATOR Clock input
+  output logic io_clk_o   // IO Clock Output
 );
 
 `ifndef SYNTHESIS
@@ -24,7 +20,7 @@
 import ast_bhv_pkg::* ;
 
 localparam real IoClkPeriod = 1000000/96;  // ~10416.666667ps (96Mhz)
-logic clk, clk_n, en_dly, en_osc, en_osc_re, en_osc_fe;
+logic clk, en_dly;
 
 initial begin
   clk = 1'b0;
@@ -34,36 +30,42 @@
 end
 
 // Enable 5us RC Delay
-logic io_en_dly;
+logic io_en_dly, io_clk_dly;
+
 assign #(IO_EN_RDLY) io_en_dly = io_en_i;
-assign en_osc_re = vcore_pok_h_i && io_en_i && (io_en_dly && en_dly);
-assign clk_n = !clk;
+assign io_clk_dly = io_en_dly && en_dly;
 
-// Syncronize en_osc to clk FE for glitch free disable
-always_ff @( posedge clk_n or negedge vcore_pok_h_i ) begin
-  if ( !vcore_pok_h_i ) begin
-    en_osc_fe <= 1'b0;
-  end else begin
-    en_osc_fe <= en_osc_re;
-  end
-end
-
-assign en_osc = en_osc_re || en_osc_fe;  // EN -> 1 || EN -> 0
+// Clock Oscillator
+////////////////////////////////////////
+logic en_osc;
 
 always begin
    #(IoClkPeriod/2000) clk = ~clk && en_osc;
 end
 `else  // of SYNTHESIS
-// SYNTHESUS/VERILATOR/LINTER/FPGA
+// SYNTHESIS/VERILATOR/LINTER/FPGA
 ///////////////////////////////////////
-localparam prim_pkg::impl_e Impl = `PRIM_DEFAULT_IMPL;
-logic clk, clk_n, en_osc, en_osc_re, en_osc_fe;
+logic io_clk_dly;
+assign io_clk_dly = 1'b1;
 
-assign en_osc_re = vcore_pok_h_i && io_en_i;
-assign clk_n = !clk;
+// Clock Oscillator
+////////////////////////////////////////
+logic clk, en_osc;
+
+prim_clock_gating u_clk_ckgt (
+  .clk_i ( clk_io_ext_i ),
+  .en_i ( en_osc ),
+  .test_en_i ( 1'b0 ),
+  .clk_o ( clk )
+);
+`endif
+
+logic en_osc_re, en_osc_fe;
+
+assign en_osc_re = vcore_pok_h_i && io_en_i && io_clk_dly;
 
 // Syncronize en_osc to clk FE for glitch free disable
-always_ff @( posedge clk_n or negedge vcore_pok_h_i ) begin
+always_ff @( negedge clk, negedge vcore_pok_h_i ) begin
   if ( !vcore_pok_h_i ) begin
     en_osc_fe <= 1'b0;
   end else begin
@@ -73,15 +75,8 @@
 
 assign en_osc = en_osc_re || en_osc_fe;  // EN -> 1 || EN -> 0
 
-if (Impl == prim_pkg::ImplXilinx) begin : gen_xilinx
-  // FPGA Specific (place holder)
-  ///////////////////////////////////////
-  assign clk = (/*TODO*/ 1'b1) && en_osc;
-end else begin : gen_generic
-  assign clk = (/*TODO*/ 1'b1) && en_osc;
-end
-`endif
-
+// Clock Output Buffer
+////////////////////////////////////////
 prim_clock_buf u_buf (
   .clk_i ( clk ),
   .clk_o ( io_clk_o )
diff --git a/hw/top_earlgrey/ip/ast/rtl/rng.sv b/hw/top_earlgrey/ip/ast/rtl/rng.sv
index 375fa35..8440583 100644
--- a/hw/top_earlgrey/ip/ast/rtl/rng.sv
+++ b/hw/top_earlgrey/ip/ast/rtl/rng.sv
@@ -24,20 +24,27 @@
 // RNG Bus using LFSR
 ///////////////////////////////////////
 logic rst_n;
-logic[32-1:0] lfsr_val;
+logic[EntropyStreams-1:0] lfsr_val;
 
 assign rst_n = scan_mode_i ? rst_ni : rst_ni && rng_en_i;
 
-always_ff @(posedge clk_i, negedge rst_n ) begin
-  if ( !rst_n ) begin
-    lfsr_val       <= 32'h0000_0001;
-  end else if ( lfsr_val == {32{1'b1}} ) begin  // Skip one problematic value
-    lfsr_val       <= {{31{1'b1}}, 1'b0};
-  end else begin
-    lfsr_val[31:1] <= lfsr_val[30:0];
-    lfsr_val[0]    <= !(lfsr_val[31] ^ lfsr_val[21] ^ lfsr_val[1] ^ lfsr_val[0]);
-  end
-end
+prim_lfsr #(
+  .LfsrDw ( ast_pkg::LfsrWidth ),
+  .EntropyDw ( 1 ),
+  .StateOutDw ( EntropyStreams ),
+  .DefaultSeed ( ast_pkg::RndCnstLfsrSeedDefault ),
+  .StatePermEn ( 1'b1 ),
+  .StatePerm ( ast_pkg::RndCnstLfsrPermDefault ),
+  .ExtSeedSVA ( 1'b0 )  // ext seed is unused
+) u_sys_lfsr (
+  .clk_i ( clk_i ),
+  .rst_ni ( rst_n ),
+  .lfsr_en_i ( rng_en_i ),
+  .seed_en_i ( 1'b0 ),
+  .seed_i ( '0 ),
+  .entropy_i ( 1'b0 ),
+  .state_o ( lfsr_val )
+);
 
 logic srate_rng_val;
 logic [12-1:0] srate_cnt, srate_value;
diff --git a/hw/top_earlgrey/ip/ast/rtl/sys_clk.sv b/hw/top_earlgrey/ip/ast/rtl/sys_clk.sv
index bc3def5..f6460c9 100644
--- a/hw/top_earlgrey/ip/ast/rtl/sys_clk.sv
+++ b/hw/top_earlgrey/ip/ast/rtl/sys_clk.sv
@@ -14,6 +14,7 @@
   input vcore_pok_h_i,                     // VCORE POK @3.3V (for OSC)
   input scan_mode_i,                       // Scan Mode
   input scan_reset_ni,                     // Scan Reset
+  input clk_sys_ext_i,                     // FPGA/VERILATOR Clock input
   output logic clk_src_sys_o,              // System Source Clock
   output logic clk_src_sys_val_o           // System Source Clock Valid
 );
@@ -30,6 +31,7 @@
   .vcore_pok_h_i ( vcore_pok_h_i ),
   .sys_en_i ( sys_clk_en ),
   .sys_jen_i ( clk_src_sys_jen_i ),
+  .clk_sys_ext_i ( clk_sys_ext_i ),
   .sys_clk_o ( clk )
 );  // of u_sys_osc
 
diff --git a/hw/top_earlgrey/ip/ast/rtl/sys_osc.sv b/hw/top_earlgrey/ip/ast/rtl/sys_osc.sv
index 49c7c34..0ccb179 100644
--- a/hw/top_earlgrey/ip/ast/rtl/sys_osc.sv
+++ b/hw/top_earlgrey/ip/ast/rtl/sys_osc.sv
@@ -5,16 +5,12 @@
 // *Name: sys_osc
 // *Module Description: System Clock Oscilator
 //############################################################################
-`ifdef SYNTHESIS
-`ifndef PRIM_DEFAULT_IMPL
-`define PRIM_DEFAULT_IMPL prim_pkg::ImplGeneric
-`endif
-`endif
 
 module sys_osc (
   input vcore_pok_h_i,    // VCORE POK @3.3V
   input sys_en_i,         // System Source Clock Enable
   input sys_jen_i,        // System Source Clock Jitter Enable
+  input clk_sys_ext_i,    // FPGA/VERILATOR Clock input
   output logic sys_clk_o  // System Clock Output
 );
 
@@ -25,7 +21,7 @@
 import ast_bhv_pkg::* ;
 
 localparam real SysClkPeriod = 10000; // 10000ps (100Mhz)
-logic clk, clk_n, en_dly, en_osc, en_osc_re, en_osc_fe;
+logic clk, en_dly;
 shortreal jitter;
 
 initial begin
@@ -36,21 +32,14 @@
 end
 
 // Enable 5us RC Delay
-logic sys_en_dly;
+logic sys_en_dly, sys_clk_dly;
+
 assign #(SYS_EN_RDLY) sys_en_dly = sys_en_i;
-assign en_osc_re = vcore_pok_h_i && sys_en_i && (sys_en_dly && en_dly);
-assign clk_n = !clk;
+assign sys_clk_dly = sys_en_dly && en_dly;
 
-// Syncronize en_osc to clk FE for glitch free disable
-always_ff @( posedge clk_n or negedge vcore_pok_h_i ) begin
-  if ( !vcore_pok_h_i ) begin
-    en_osc_fe <= 1'b0;
-  end else begin
-    en_osc_fe <= en_osc_re;
-  end
-end
-
-assign en_osc = en_osc_re || en_osc_fe;  // EN -> 1 || EN -> 0
+// Clock Oscillator
+////////////////////////////////////////
+logic en_osc;
 
 always begin
   // 0-2000ps is upto +20% Jitter
@@ -58,17 +47,29 @@
   #((SysClkPeriod+jitter)/2000) clk = ~clk && en_osc;
 end
 `else  // of SYNTHESIS
-// SYNTHESUS/VERILATOR/LINTER/FPGA
+// SYNTHESIS/VERILATOR/LINTER/FPGA
 ///////////////////////////////////////
-localparam prim_pkg::impl_e Impl = `PRIM_DEFAULT_IMPL;
-logic clk, clk_n, en_osc, en_osc_re, en_osc_fe;
-// TODO: add sys_jen_i
+logic sys_clk_dly;
+assign sys_clk_dly = 1'b1;
 
-assign en_osc_re = vcore_pok_h_i && sys_en_i;
-assign clk_n = !clk;
+// Clock Oscillator
+////////////////////////////////////////
+logic clk, en_osc;
+
+prim_clock_gating u_clk_ckgt (
+  .clk_i ( clk_sys_ext_i ),
+  .en_i ( en_osc ),
+  .test_en_i ( 1'b0 ),
+  .clk_o ( clk )
+);
+`endif
+
+logic en_osc_re, en_osc_fe;
+
+assign en_osc_re = vcore_pok_h_i && sys_en_i && sys_clk_dly;
 
 // Syncronize en_osc to clk FE for glitch free disable
-always_ff @( posedge clk_n or negedge vcore_pok_h_i ) begin
+always_ff @( negedge clk, negedge vcore_pok_h_i ) begin
   if ( !vcore_pok_h_i ) begin
     en_osc_fe <= 1'b0;
   end else begin
@@ -78,15 +79,8 @@
 
 assign en_osc = en_osc_re || en_osc_fe;  // EN -> 1 || EN -> 0
 
-if (Impl == prim_pkg::ImplXilinx) begin : gen_xilinx
-  // FPGA Specific (place holder)
-  ///////////////////////////////////////
-  assign clk = (/*TODO*/ 1'b1) && en_osc;
-end else begin : gen_generic
-  assign clk = (/*TODO*/ 1'b1) && en_osc;
-end
-`endif
-
+// Clock Output Buffer
+////////////////////////////////////////
 prim_clock_buf u_buf (
   .clk_i ( clk ),
   .clk_o ( sys_clk_o )
diff --git a/hw/top_earlgrey/ip/ast/rtl/usb_clk.sv b/hw/top_earlgrey/ip/ast/rtl/usb_clk.sv
index 57b5df7..811bff6 100644
--- a/hw/top_earlgrey/ip/ast/rtl/usb_clk.sv
+++ b/hw/top_earlgrey/ip/ast/rtl/usb_clk.sv
@@ -15,6 +15,7 @@
   input usb_ref_pulse_i,                   // USB Reference Pulse
   input scan_mode_i,                       // Scan Mode
   input scan_reset_ni,                     // Scan Reset
+  input clk_usb_ext_i,                     // FPGA/VERILATOR Clock input
   //
   output logic clk_src_usb_o,              // USB Source Clock
   output logic clk_src_usb_val_o           // USB Source Clock Valid
@@ -32,6 +33,7 @@
   .vcore_pok_h_i ( vcore_pok_h_i ),
   .usb_en_i (usb_clk_en ),
   .usb_ref_val_i ( usb_ref_val_i ),
+  .clk_usb_ext_i ( clk_usb_ext_i ),
   .usb_clk_o ( clk )
 );  // u_usb_osc
 
diff --git a/hw/top_earlgrey/ip/ast/rtl/usb_osc.sv b/hw/top_earlgrey/ip/ast/rtl/usb_osc.sv
index 99d2252..acd726e 100644
--- a/hw/top_earlgrey/ip/ast/rtl/usb_osc.sv
+++ b/hw/top_earlgrey/ip/ast/rtl/usb_osc.sv
@@ -5,17 +5,13 @@
 // *Name: usb_osc
 // *Module Description: USB Clock Oscilator
 //############################################################################
-`ifdef SYNTHESIS
-`ifndef PRIM_DEFAULT_IMPL
-`define PRIM_DEFAULT_IMPL prim_pkg::ImplGeneric
-`endif
-`endif
 
 module usb_osc (
-  input vcore_pok_h_i,     // VCORE POK @3.3V
-  input usb_en_i,          // USB Source Clock Enable
-  input usb_ref_val_i,     // USB Reference Valid
-  output logic usb_clk_o   // USB Clock Output
+  input vcore_pok_h_i,    // VCORE POK @3.3V
+  input usb_en_i,         // USB Source Clock Enable
+  input usb_ref_val_i,    // USB Reference Valid
+  input clk_usb_ext_i,    // FPGA/VERILATOR Clock input
+  output logic usb_clk_o  // USB Clock Output
 );
 
 `ifndef SYNTHESIS
@@ -25,8 +21,7 @@
 import ast_bhv_pkg::* ;
 
 localparam real UsbClkPeriod = 1000000/48;  // ~20833.33333ps (48Mhz)
-logic clk, clk_n, en_dly, en_osc, en_osc_re, en_osc_fe;
-shortreal drift;
+logic clk, en_dly;
 integer rand32;
 
 initial begin
@@ -39,41 +34,48 @@
 end
 
 // Enable 5us RC Delay
-logic usb_en_dly;
+logic usb_en_dly, usb_clk_dly;
+
 assign #(USB_EN_RDLY) usb_en_dly = usb_en_i;
-assign en_osc_re = vcore_pok_h_i && usb_en_i && (usb_en_dly && en_dly);
-assign clk_n = !clk;
-
-// Syncronize en_osc to clk FE for glitch free disable
-always_ff @( posedge clk_n or negedge vcore_pok_h_i ) begin
-  if ( !vcore_pok_h_i ) begin
-    en_osc_fe <= 1'b0;
-  end else begin
-    en_osc_fe <= en_osc_re;
-  end
-end
-
-assign en_osc = en_osc_re || en_osc_fe;  // EN -> 1 || EN -> 0
+assign usb_clk_dly = usb_en_dly && en_dly;
 
 wire ref_val;
 assign #(USB_VAL_RDLY, USB_VAL_FDLY) ref_val = usb_ref_val_i;
 
+// Clock Oscillator
+////////////////////////////////////////
+logic en_osc;
+shortreal drift;
+
 assign drift = ref_val ? 0 : rand32;
 
 always begin
   #((UsbClkPeriod + drift)/2000) clk = ~clk && en_osc;
 end
 `else  // of SYNTHESIS
-// SYNTHESUS/VERILATOR/LINTER/FPGA
+// SYNTHESIS/VERILATOR/LINTER/FPGA
 ///////////////////////////////////////
-localparam prim_pkg::impl_e Impl = `PRIM_DEFAULT_IMPL;
-logic clk, clk_n, en_osc, en_osc_re, en_osc_fe;
+logic usb_clk_dly;
+assign usb_clk_dly = 1'b1;
 
-assign en_osc_re = vcore_pok_h_i && usb_en_i;
-assign clk_n = !clk;
+// Clock Oscillator
+////////////////////////////////////////
+logic clk, en_osc;
+
+prim_clock_gating u_clk_ckgt (
+  .clk_i ( clk_usb_ext_i ),
+  .en_i ( en_osc ),
+  .test_en_i ( 1'b0 ),
+  .clk_o ( clk )
+);
+`endif
+
+logic en_osc_re, en_osc_fe;
+
+assign en_osc_re = vcore_pok_h_i && usb_en_i && usb_clk_dly;
 
 // Syncronize en_osc to clk FE for glitch free disable
-always_ff @( posedge clk_n or negedge vcore_pok_h_i ) begin
+always_ff @( negedge clk, negedge vcore_pok_h_i ) begin
   if ( !vcore_pok_h_i ) begin
     en_osc_fe <= 1'b0;
   end else begin
@@ -83,15 +85,8 @@
 
 assign en_osc = en_osc_re || en_osc_fe;  // EN -> 1 || EN -> 0
 
-if (Impl == prim_pkg::ImplXilinx) begin : gen_xilinx
-  // FPGA Specific (place holder)
-  ///////////////////////////////////////
-  assign clk = (/*TODO*/ 1'b1) && en_osc;
-end else begin : gen_generic
-  assign clk = (/*TODO*/ 1'b1) && en_osc;
-end
-`endif
-
+// Clock Output Buffer
+////////////////////////////////////////
 prim_clock_buf u_buf (
   .clk_i ( clk ),
   .clk_o ( usb_clk_o )
diff --git a/hw/top_earlgrey/ip/ast/rtl/vcaon_pok.sv b/hw/top_earlgrey/ip/ast/rtl/vcaon_pok.sv
index f2d115f..b5faef4 100644
--- a/hw/top_earlgrey/ip/ast/rtl/vcaon_pok.sv
+++ b/hw/top_earlgrey/ip/ast/rtl/vcaon_pok.sv
@@ -15,15 +15,15 @@
   output logic vcaon_pok_o
 );
 
-`ifndef SYNTHESIS
-import ast_bhv_pkg::* ;
-
-// Behavioral Model
-////////////////////////////////////////
 // Local signal for testing hook
 logic gen_supp_a;
 assign gen_supp_a = 1'b1;
 
+`ifndef SYNTHESIS
+// Behavioral Model
+////////////////////////////////////////
+import ast_bhv_pkg::* ;
+
 // The initial is needed to clear the X of the delays at the start
 // Also to force a power-up effect at the bgining.
 logic init_start;
@@ -42,19 +42,17 @@
     vcaon_pok_o <= #(VCAON_POK_FDLY) gen_supp_a;
   end
 end
-
 `else
-localparam prim_pkg::impl_e Impl = `PRIM_DEFAULT_IMPL;
-
-// SYNTHESUS/VERILATOR/LINTER/FPGA
+// SYNTHESIS/VERILATOR/LINTER/FPGA
 ///////////////////////////////////////
+localparam prim_pkg::impl_e Impl = `PRIM_DEFAULT_IMPL;
 
 if (Impl == prim_pkg::ImplXilinx) begin : gen_xilinx
   // FPGA Specific (place holder)
   ///////////////////////////////////////
-  assign vcaon_pok_o = 1'b1;
+  assign vcaon_pok_o = gen_supp_a;
 end else begin : gen_generic
-  assign vcaon_pok_o = 1'b1;
+  assign vcaon_pok_o = gen_supp_a;
 end
 `endif
 
diff --git a/hw/top_earlgrey/ip/ast/rtl/vcc_pok.sv b/hw/top_earlgrey/ip/ast/rtl/vcc_pok.sv
index a6bf1de..c71b78e 100644
--- a/hw/top_earlgrey/ip/ast/rtl/vcc_pok.sv
+++ b/hw/top_earlgrey/ip/ast/rtl/vcc_pok.sv
@@ -15,15 +15,15 @@
   output logic vcc_pok_o
 );
 
-`ifndef SYNTHESIS
-import ast_bhv_pkg::* ;
-
-// Behavioral Model
-////////////////////////////////////////
 // Local signal for testing hook
 logic gen_supp_a;
 assign gen_supp_a = 1'b1;
 
+`ifndef SYNTHESIS
+// Behavioral Model
+////////////////////////////////////////
+import ast_bhv_pkg::* ;
+
 // The initial is needed to clear the X of the delays at the start
 // Also to force a power-up effect at the bgining.
 logic init_start;
@@ -42,19 +42,17 @@
     vcc_pok_o <= #(VCC_POK_FDLY) gen_supp_a;
   end
 end
-
 `else
-localparam prim_pkg::impl_e Impl = `PRIM_DEFAULT_IMPL;
-
-// SYNTHESUS/VERILATOR/LINTER/FPGA
+// SYNTHESIS/VERILATOR/LINTER/FPGA
 ///////////////////////////////////////
+localparam prim_pkg::impl_e Impl = `PRIM_DEFAULT_IMPL;
 
 if (Impl == prim_pkg::ImplXilinx) begin : gen_xilinx
   // FPGA Specific (place holder)
   ///////////////////////////////////////
-  assign vcc_pok_o = 1'b1;
+  assign vcc_pok_o = gen_supp_a;
 end else begin : gen_generic
-  assign vcc_pok_o = 1'b1;
+  assign vcc_pok_o = gen_supp_a;
 end
 `endif
 
diff --git a/hw/top_earlgrey/ip/ast/rtl/vcmain_pok.sv b/hw/top_earlgrey/ip/ast/rtl/vcmain_pok.sv
index 929617c..df7ca23 100644
--- a/hw/top_earlgrey/ip/ast/rtl/vcmain_pok.sv
+++ b/hw/top_earlgrey/ip/ast/rtl/vcmain_pok.sv
@@ -15,15 +15,15 @@
   output logic vcmain_pok_o
 );
 
-`ifndef SYNTHESIS
-import ast_bhv_pkg::* ;
-
-// Behavioral Model
-////////////////////////////////////////
 // Local signal for testing hook
 logic gen_supp_a;
 assign gen_supp_a = 1'b1;
 
+`ifndef SYNTHESIS
+// Behavioral Model
+////////////////////////////////////////
+import ast_bhv_pkg::* ;
+
 // The initial is needed to clear the X of the delays at the start
 // Also to force a power-up effect at the bgining.
 logic init_start;
@@ -42,19 +42,17 @@
     vcmain_pok_o <= #(VCMAIN_POK_FDLY) gen_supp_a;
   end
 end
-
 `else
-localparam prim_pkg::impl_e Impl = `PRIM_DEFAULT_IMPL;
-
-// SYNTHESUS/VERILATOR/LINTER/FPGA
+// SYNTHESIS/VERILATOR/LINTER/FPGA
 ///////////////////////////////////////
+localparam prim_pkg::impl_e Impl = `PRIM_DEFAULT_IMPL;
 
 if (Impl == prim_pkg::ImplXilinx) begin : gen_xilinx
   // FPGA Specific (place holder)
   ///////////////////////////////////////
-  assign vcmain_pok_o = 1'b1;
+  assign vcmain_pok_o = gen_supp_a;
 end else begin : gen_generic
-  assign vcmain_pok_o = 1'b1;
+  assign vcmain_pok_o = gen_supp_a;
 end
 `endif
 
diff --git a/hw/top_earlgrey/ip/ast/rtl/vio_pok.sv b/hw/top_earlgrey/ip/ast/rtl/vio_pok.sv
index 1e4ff2c..b94e0a7 100644
--- a/hw/top_earlgrey/ip/ast/rtl/vio_pok.sv
+++ b/hw/top_earlgrey/ip/ast/rtl/vio_pok.sv
@@ -15,15 +15,15 @@
   output logic vio_pok_o
 );
 
-`ifndef SYNTHESIS
-import ast_bhv_pkg::* ;
-
-// Behavioral Model
-////////////////////////////////////////
 // Local signal for testing hook
 logic gen_supp_a;
 assign gen_supp_a = 1'b1;
 
+`ifndef SYNTHESIS
+// Behavioral Model
+////////////////////////////////////////
+import ast_bhv_pkg::* ;
+
 // The initial is needed to clear the X of the delays at the start
 // Also to force a power-up effect at the bgining.
 logic init_start;
@@ -42,19 +42,17 @@
     vio_pok_o <= #(VIO_POK_FDLY) gen_supp_a;
   end
 end
-
 `else
-localparam prim_pkg::impl_e Impl = `PRIM_DEFAULT_IMPL;
-
-// SYNTHESUS/VERILATOR/LINTER/FPGA
+// SYNTHESIS/VERILATOR/LINTER/FPGA
 //////////////////////////////////////
+localparam prim_pkg::impl_e Impl = `PRIM_DEFAULT_IMPL;
 
 if (Impl == prim_pkg::ImplXilinx) begin : gen_xilinx
   // FPGA Specific (place holder)
   ///////////////////////////////////////
-  assign vio_pok_o = 1'b1;
+  assign vio_pok_o = gen_supp_a;
 end else begin : gen_generic
-  assign vio_pok_o = 1'b1;
+  assign vio_pok_o = gen_supp_a;
 end
 `endif
 
diff --git a/hw/top_earlgrey/rtl/autogen/chip_earlgrey_asic.sv b/hw/top_earlgrey/rtl/autogen/chip_earlgrey_asic.sv
index 4a5444c..8807b94 100644
--- a/hw/top_earlgrey/rtl/autogen/chip_earlgrey_asic.sv
+++ b/hw/top_earlgrey/rtl/autogen/chip_earlgrey_asic.sv
@@ -982,6 +982,8 @@
     .rst_ast_usb_ni        ( rsts_ast.rst_ast_usbdev_usb_n[Domain0Sel] ),
     .clk_ast_ext_i         ( ext_clk ),
     .por_ni                ( manual_in_por_n ),
+    // clocks' oschillator bypass for FPGA
+    .clk_osc_byp_i         ( '0 ),
     // pok test for FPGA
     .vcc_supp_i            ( 1'b1 ),
     .vcaon_supp_i          ( 1'b1 ),
diff --git a/util/topgen/templates/chiplevel.sv.tpl b/util/topgen/templates/chiplevel.sv.tpl
index 585ad46..fb50e17 100644
--- a/util/topgen/templates/chiplevel.sv.tpl
+++ b/util/topgen/templates/chiplevel.sv.tpl
@@ -830,6 +830,8 @@
     .rst_ast_usb_ni        ( rsts_ast.rst_ast_usbdev_usb_n[Domain0Sel] ),
     .clk_ast_ext_i         ( ext_clk ),
     .por_ni                ( manual_in_por_n ),
+    // clocks' oschillator bypass for FPGA
+    .clk_osc_byp_i         ( '0 ),
     // pok test for FPGA
     .vcc_supp_i            ( 1'b1 ),
     .vcaon_supp_i          ( 1'b1 ),