[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 ),