blob: aa1e21678518865e00cd58ef37443bae41e5c907 [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
//############################################################################
// *Name: rng_osc
// *Module Description: RNG Clock Oscilator
//############################################################################
`ifdef SYNTHESIS
`ifndef PRIM_DEFAULT_IMPL
`define PRIM_DEFAULT_IMPL prim_pkg::ImplGeneric
`endif
`endif
module rng_osc (
input vcaon_pok_i, // VCAON POK @1.1V
input rng_en_i, // RNG Source Clock Enable
output logic rng_clk_o // RNG Clock Output
);
`ifndef SYNTHESIS
timeunit 1ns / 1ps;
import ast_bhv_pkg::* ;
// Behavioral Model
///////////////////////////////////////
integer CLK_PERIOD;
logic clk, en_dly, en_osc, en_osc_re, en_osc_fe;
initial begin
clk = 1'b0;
// Seed is set from the vcs run command
CLK_PERIOD = 10**9/$urandom_range(70000, 50000); // ns (50Khz-70Khz)
$display( "\nRNG Internal Clock Period: %0dns", CLK_PERIOD);
en_dly = 1'b0; // to block init X
#(RNG_EN_RDLY+1) en_dly = 1'b1;
end
// Enable 5us RC Delay
logic rng_en_dly;
assign #(RNG_EN_RDLY) rng_en_dly = rng_en_i;
assign en_osc_re = vcaon_pok_i && rng_en_i && (rng_en_dly && en_dly);
// Syncronize en_osc to clk FE for glitch free disable
always_ff @( negedge clk or negedge vcaon_pok_i ) begin
if ( !vcaon_pok_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
always begin
#(CLK_PERIOD/2) clk = ~clk && en_osc;
end
assign rng_clk_o = clk;
`else // of SYNTHESIS
localparam prim_pkg::impl_e Impl = `PRIM_DEFAULT_IMPL;
// SYNTHESUS/VERILATOR/LINTER/FPGA
///////////////////////////////////////
logic clk, en_osc, en_osc_re, en_osc_fe;
assign en_osc_re = vcaon_pok_i && rng_en_i;
// Syncronize en_osc to clk FE for glitch free disable
always_ff @( negedge clk or negedge vcaon_pok_i ) begin
if ( !vcaon_pok_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
if (Impl == prim_pkg::ImplXilinx) begin : gen_xilinx
// FPGA Model (place holder)
///////////////////////////////////////
assign clk = (/*TODO*/ 1'b1) && en_osc;
assign rng_clk_o = clk;
end else begin : gen_generic
assign clk = (/*TODO*/ 1'b1) && en_osc;
assign rng_clk_o = clk;
end
`endif
endmodule : rng_osc