blob: 46d2b285f991d63ef485b6395882d801e97f6e17 [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
//
// -------- W A R N I N G: A U T O - G E N E R A T E D C O D E !! -------- //
// PLEASE DO NOT HAND-EDIT THIS FILE. IT HAS BEEN AUTO-GENERATED.
//
//############################################################################
// *Name: dev_entropy
// *Module Description: Device Entropy
//############################################################################
module dev_entropy #(
parameter int EntropyRateWidth = 4
) (
input clk_i, // Entropy Clock
input rst_ni, // Entropy Reset
input clk_dev_i, // Device Clock
input rst_dev_ni, // Device Reset
input dev_en_i, // Device Enable
input [EntropyRateWidth-1:0] dev_rate_i, // Entropy Rate
input dev_ack_i, // Write Valid (EDN_ACK)
input [32-1:0] dev_data_i, // Write Data (EDN_BUS)
output logic dev_wready_o, // Write Ready (EDN_REQ)
output logic dev_data_o // Entropy Data
);
////////////////////////////////////
// Device Enable Sync
////////////////////////////////////
logic dev_en_dev;
// Sync dev_en to Dev clock
prim_flop_2sync #(
.Width ( 1 ),
.ResetValue ( 1'b0 )
) u_dev_en_dev_sync (
.clk_i ( clk_dev_i ),
.rst_ni ( rst_dev_ni ),
.d_i ( dev_en_i ),
.q_o ( dev_en_dev )
);
////////////////////////////////////
// Entropy Rate
///////////////////////////////////////
logic fast_start, rate_pulse, rready;
logic [7-1:0] fast_cnt;
logic [(1<<EntropyRateWidth)-1:0] erate_cnt, dev_rate;
// Sync dev_rate_i to Device clock
// A simplified synchrnization is used instead of a pulse synchronize.
// The rate might go through a different value for one clk_dev_i cycle.
// In most cases the rate will be set ahead of the dev_en_i
logic [EntropyRateWidth-1:0] dev_rate_sync;
prim_flop_2sync #(
.Width ( EntropyRateWidth ),
.ResetValue ( {EntropyRateWidth{1'b0}} )
) u_erate_sync (
.clk_i ( clk_dev_i ) ,
.rst_ni ( rst_dev_ni ),
.d_i ( dev_rate_i[EntropyRateWidth-1:0] ),
.q_o ( dev_rate_sync[EntropyRateWidth-1:0] )
);
// Fastest rate to init the LFSR
always_ff @( posedge clk_dev_i, negedge rst_dev_ni ) begin
if ( !rst_dev_ni ) begin
fast_start <= 1'b1;
fast_cnt <= 7'h00;
end else if ( fast_cnt == 7'h40 ) begin
fast_start <= 1'b0;
end else if ( fast_start && rready ) begin
fast_cnt <= fast_cnt + 1'b1;
end
end
assign dev_rate = fast_start ? '0 : ((1<<EntropyRateWidth)'(1'b1) << dev_rate_sync) - 1;
always_ff @( posedge clk_dev_i, negedge rst_dev_ni ) begin
if ( !rst_dev_ni ) begin
erate_cnt <= '0;
end else if ( rate_pulse ) begin
erate_cnt <= dev_rate;
end else if ( erate_cnt != '0 ) begin
erate_cnt <= erate_cnt - 1'b1;
end
end
assign rate_pulse = (erate_cnt == '0) && dev_en_dev;
////////////////////////////////////////
// Entropy Data Buffer at ES Clock
////////////////////////////////////////
// Entropy Clock
///////////////////////////////////////
logic [32-1:0] wdata;
always_ff @( posedge clk_i, negedge rst_ni ) begin
if ( !rst_ni ) begin
wdata <= 32'h0000_0000;
end else if ( dev_ack_i ) begin
wdata <= dev_data_i;
end
end
// Sync wvalid to ES clock
logic wready_dev, wready_es;
prim_flop_2sync #(
.Width ( 1 ),
.ResetValue ( 1'b0 )
) u_wvalid_es_sync (
.clk_i,
.rst_ni,
.d_i ( wready_dev ),
.q_o ( wready_es )
);
logic wready_es_d;
always_ff @( posedge clk_i, negedge rst_ni ) begin
if ( !rst_ni ) begin
wready_es_d <= 1'b0;
end else begin
wready_es_d <= wready_es;
end
end
logic wdata_val, set_wdata_val, clr_wdata_val, wready_es_fe;
assign wready_es_fe = !wready_es && wready_es_d;
assign set_wdata_val = !wdata_val && dev_ack_i;
assign clr_wdata_val = wdata_val && wready_es_fe;
always_ff @( posedge clk_i, negedge rst_ni ) begin
if ( !rst_ni ) begin
wdata_val <= 1'b0;
end else if ( set_wdata_val ) begin
wdata_val <= 1'b1;
end else if ( clr_wdata_val ) begin
wdata_val <= 1'b0;
end
end
assign dev_wready_o = !wdata_val;
// Device Clock
///////////////////////////////////////
// Reset de-assert of rst_ni to Device clock
logic rst_es_dev_in_n, rst_es_dev_da_n, rst_es_dev_n;
assign rst_es_dev_in_n = rst_ni && rst_dev_ni;
prim_flop_2sync #(
.Width ( 1 ),
.ResetValue ( 1'b0 )
) u_rst_es_n_da (
.clk_i ( clk_dev_i ),
.rst_ni ( rst_es_dev_in_n ),
.d_i ( 1'b1 ),
.q_o ( rst_es_dev_da_n )
);
assign rst_es_dev_n = rst_es_dev_da_n;
// Sync wready_es to Device clock
logic wready, wready_es_dev;
prim_flop_2sync #(
.Width ( 1 ),
.ResetValue ( 1'b0 )
) u_wready_es_dev_sync (
.clk_i ( clk_dev_i ),
.rst_ni ( rst_es_dev_n ),
.d_i ( wready_es ),
.q_o ( wready_es_dev )
);
logic set_wready_dev, clr_wready_dev;
assign set_wready_dev = !wready_dev && wready;
assign clr_wready_dev = wready_dev && !wready && wready_es_dev;
always_ff @( posedge clk_dev_i, negedge rst_es_dev_n ) begin
if ( !rst_es_dev_n ) begin
wready_dev <= 1'b0;
end else if ( set_wready_dev ) begin
wready_dev <= 1'b1;
end else if ( clr_wready_dev ) begin
wready_dev <= 1'b0;
end
end
// Sync wdata_val to Device clock
logic wdata_val_dev;
prim_flop_2sync #(
.Width ( 1 ),
.ResetValue ( 1'b0 )
) u_wvalid_dev_sync (
.clk_i ( clk_dev_i ),
.rst_ni ( rst_es_dev_n ),
.d_i ( wdata_val ),
.q_o ( wdata_val_dev )
);
logic wvalid, set_wvalid, clr_wvalid;
assign set_wvalid = !wvalid && wready && wdata_val_dev;
assign clr_wvalid = wvalid;
always_ff @( posedge clk_dev_i, negedge rst_es_dev_n ) begin
if ( !rst_es_dev_n ) begin
wvalid <= 1'b0;
end else if ( set_wvalid ) begin
wvalid <= 1'b1;
end else if ( clr_wvalid ) begin
wvalid <= 1'b0;
end
end
////////////////////////////////////////
// Packer FIFO (32to1 bit)
////////////////////////////////////////
logic rdata, rvalid;
logic [6-1:0] depth;
prim_packer_fifo #(
.InW ( 32 ),
.OutW ( 1 )
) u_dev_fifo (
.clk_i ( clk_dev_i ),
.rst_ni ( rst_dev_ni ),
.clr_i ( 1'b0 ), // !dev_en_dev ), // Clear (sync)
.wvalid_i ( wvalid ), // Write Valid
.wdata_i ( wdata ), // Write Data (32-bit)
.wready_o ( wready ), // Write Ready
//
.rvalid_o ( rvalid ), // Read Valid
.rdata_o ( rdata ), // Read Data
.rready_i ( rready ), // Read Ready (done)
.depth_o ( depth[6-1:0] ) // empty when (depth_o == `0)
);
assign rready = rvalid && rate_pulse;
assign dev_data_o = rdata && rate_pulse;
///////////////////////
// Unused Signals
///////////////////////
logic unused_sigs;
assign unused_sigs = ^{ depth[6-1:0] };
endmodule : dev_entropy