Merge branch 'new_trng'

This commit is contained in:
Joachim Strömbergson 2022-10-11 13:00:13 +02:00
commit af36a40f3e

View File

@ -31,24 +31,68 @@ module figaro(
//----------------------------------------------------------------
// Internal constant and parameter definitions.
//----------------------------------------------------------------
// API
localparam ADDR_STATUS = 8'h09;
localparam STATUS_READY_BIT = 0;
localparam ADDR_SAMPLE_RATE = 8'h10;
localparam ADDR_ENTROPY = 8'h20;
// Total number of ROSCs will be 2 x NUM_ROSC.
localparam SAMPLE_RATE = 16'h1000;
localparam NUM_ROSC = 16;
localparam CTRL_SAMPLE1 = 0;
localparam CTRL_SAMPLE2 = 1;
localparam CTRL_DATA_READY = 2;
//----------------------------------------------------------------
// Registers with associated wires.
//----------------------------------------------------------------
reg [16 : 0] cycle_ctr_reg;
reg [16 : 0] cycle_ctr_new;
reg cycle_ctr_done;
reg cycle_ctr_rst;
reg [4 : 0] bit_ctr_reg;
reg [4 : 0] bit_ctr_new;
reg bit_ctr_we;
reg [31 : 0] entropy_reg;
reg [31 : 0] entropy_new;
reg entropy_we;
reg [1 : 0] sample1_reg;
reg [1 : 0] sample1_new;
reg sample1_we;
reg [1 : 0] sample2_reg;
reg [1 : 0] sample2_new;
reg sample2_we;
reg data_ready_reg;
reg data_ready_new;
reg data_ready_we;
reg data_ready_set;
reg data_ready_rst;
reg [1 : 0] rosc_ctrl_reg;
reg [1 : 0] rosc_ctrl_new;
reg rosc_ctrl_we;
//----------------------------------------------------------------
// Wires.
//----------------------------------------------------------------
reg core_read_entropy;
reg core_set_sample_rate;
wire [31 : 0] core_entropy;
wire core_ready;
reg [31 : 0] tmp_read_data;
reg tmp_ready;
/* verilator lint_off UNOPTFLAT */
wire [(NUM_ROSC - 1) : 0] f;
/* verilator lint_on UNOPTFLAT */
/* verilator lint_off UNOPTFLAT */
wire [(NUM_ROSC - 1) : 0] g;
/* verilator lint_on UNOPTFLAT */
//----------------------------------------------------------------
// Concurrent connectivity for ports etc.
@ -58,17 +102,66 @@ module figaro(
//----------------------------------------------------------------
// core instantiation.
// oscillators.
//
// 32 single inverters, each connect to itself.
//----------------------------------------------------------------
figaro_core core(
.clk(clk),
.reset_n(reset_n),
.read_entropy(core_read_entropy),
.set_sample_rate(core_set_sample_rate),
.sample_rate(write_data[23 : 0]),
.entropy(core_entropy),
.ready(core_ready)
);
genvar i;
generate
for(i = 0 ; i < NUM_ROSC ; i = i + 1)
begin: oscillators
/* verilator lint_off PINMISSING */
(* keep *) SB_LUT4 #(.LUT_INIT(16'h1)) osc_inv_f (.I0(f[i]), .O(f[i]));
(* keep *) SB_LUT4 #(.LUT_INIT(16'h1)) osc_inv_g (.I0(g[i]), .O(g[i]));
/* verilator lint_off PINMISSING */
end
endgenerate
//---------------------------------------------------------------
// reg_update
//---------------------------------------------------------------
always @(posedge clk)
begin : reg_update
if (!reset_n) begin
cycle_ctr_reg <= 16'h0;
bit_ctr_reg <= 5'h0;
sample1_reg <= 2'h0;
sample2_reg <= 2'h0;
entropy_reg <= 32'h0;
data_ready_reg <= 1'h0;
rosc_ctrl_reg <= CTRL_SAMPLE1;
end
else begin
cycle_ctr_reg <= cycle_ctr_new;
if (bit_ctr_we) begin
bit_ctr_reg <= bit_ctr_new;
end
if (sample1_we) begin
sample1_reg <= sample1_new;
end
if (sample2_we) begin
sample2_reg <= sample2_new;
end
if (entropy_we) begin
entropy_reg <= entropy_new;
end
if (data_ready_we) begin
data_ready_reg <= data_ready_new;
end
if (rosc_ctrl_we) begin
rosc_ctrl_reg <= rosc_ctrl_new;
end
end
end
//----------------------------------------------------------------
@ -78,32 +171,133 @@ module figaro(
//----------------------------------------------------------------
always @*
begin : api
core_read_entropy = 1'h0;
core_set_sample_rate = 1'h0;
tmp_read_data = 32'h0;
tmp_ready = 1'h0;
data_ready_rst = 1'h0;
tmp_read_data = 32'h0;
tmp_ready = 1'h0;
if (cs) begin
tmp_ready = 1'h1;
if (we) begin
if (address == ADDR_SAMPLE_RATE) begin
core_set_sample_rate = 1'h1;
end
end
else begin
if (!we) begin
if (address == ADDR_STATUS) begin
tmp_read_data = {31'h0, core_ready};
tmp_read_data = {31'h0, data_ready_reg};
end
if (address == ADDR_ENTROPY) begin
tmp_read_data = core_entropy;
core_read_entropy = 1'h1;
tmp_read_data = entropy_reg;
data_ready_rst = 1'h1;
end
end
end
end // api
//----------------------------------------------------------------
// data_ready_logic
//----------------------------------------------------------------
always @*
begin : data_ready_logic
data_ready_new = 1'h0;
data_ready_we = 1'h0;
if (data_ready_set) begin
data_ready_new = 1'h1;
data_ready_we = 1'h1;
end else if (data_ready_rst) begin
data_ready_new = 1'h0;
data_ready_we = 1'h1;
end
end
//----------------------------------------------------------------
// cycle_ctr_logic
//----------------------------------------------------------------
always @*
begin : cycle_ctr_logic
cycle_ctr_done = 1'h0;
cycle_ctr_new = cycle_ctr_reg + 1'h1;
if (cycle_ctr_rst) begin
cycle_ctr_new = 24'h0;
end
if (cycle_ctr_reg == SAMPLE_RATE) begin
cycle_ctr_done = 1'h1;
end
end
//----------------------------------------------------------------
// rosc_ctrl_logic
//----------------------------------------------------------------
always @*
begin : rosc_ctrl_logic
reg xor_f;
reg xor_g;
reg xor_sample1;
reg xor_sample2;
sample1_we = 1'h0;
sample2_we = 1'h0;
cycle_ctr_rst = 1'h0;
data_ready_set = 1'h0;
entropy_we = 1'h0;
bit_ctr_new = 6'h0;
bit_ctr_we = 1'h0;
rosc_ctrl_new = CTRL_SAMPLE1;
rosc_ctrl_we = 1'h0;
xor_f = ^f;
xor_g = ^g;
xor_sample1 = ^sample1_reg;
xor_sample2 = ^sample2_reg;
sample1_new = {sample1_reg[0], xor_f};
sample2_new = {sample2_reg[0], xor_g};
entropy_new = {entropy_reg[30 : 0], xor_sample2};
if (bit_ctr_reg == 31) begin
data_ready_set = 1'h1;
end
case (rosc_ctrl_reg)
CTRL_SAMPLE1: begin
if (cycle_ctr_done) begin
cycle_ctr_rst = 1'h1;
sample1_we = 1'h1;
sample2_we = 1'h1;
rosc_ctrl_new = CTRL_SAMPLE2;
rosc_ctrl_we = 1'h1;
end
end
CTRL_SAMPLE2: begin
if (cycle_ctr_done) begin
cycle_ctr_rst = 1'h1;
sample1_we = 1'h1;
sample2_we = 1'h1;
rosc_ctrl_new = CTRL_DATA_READY;
rosc_ctrl_we = 1'h1;
end
end
CTRL_DATA_READY: begin
if (xor_sample1 ^ xor_sample2) begin
entropy_we = 1'h1;
bit_ctr_new = bit_ctr_reg + 1'h1;
bit_ctr_we = 1'h1;
end
rosc_ctrl_new = CTRL_SAMPLE1;
rosc_ctrl_we = 1'h1;
end
default: begin
end
endcase // case (rosc_ctrl_reg)
end
endmodule // figaro
//======================================================================