blob: 64edbf71fc274ec9375862cbaeb032e023ac392c [file] [log] [blame]
//-----------------------------------------------------------------------------
// @file trng_wb_wrapper.vhd
//
// @brief This block is a wishbone wrapper for TRNG macro
//
// @details This wrapper gets signal from master if it is selected
// and convey to the TRNG module and vice versa.
//
// @author Sukru Uzun <sukru.uzun@procenne.com>
// @date 19.03.2022
//
// @todo TRNG buffer size can be changed.
// @warning Wrapper should not convey data unless buffer is full.
//
// @project https://github.com/Procenne-Digital-Design/secure-memory.git
//
// @revision :
// 0.1 - 19 March 2022, Sukru Uzun
// initial version
//-----------------------------------------------------------------------------
module trng_wb_wrapper #(
parameter BUFFER_SIZE = 32
) (
`ifdef USE_POWER_PINS
input wire vccd1,
input wire vssd1,
`endif
input wire rst_i,
// Wishbone Interface
input wire wb_clk_i,
input wire wb_cyc_i,
input wire wb_stb_i,
input wire [8:0] wb_adr_i,
input wire wb_we_i,
input wire [31:0] wb_dat_i,
// input wire [3:0] wb_sel_i,
output wire [31:0] wb_dat_o,
output reg wb_ack_o,
output reg trng_valid_o,
output reg [BUFFER_SIZE-1:0] trng_buffer_o
);
wire read_trng;
wire trim_select;
wire trim_write_en;
reg [25:0] trim_fast, trim_slow;
reg [5:0] trng_counter;
wire trng_o;
// Wishbone to TRNG signalization and vice versa.
assign read_trng = (wb_stb_i == 1'b1 && wb_we_i == 1'b0 && wb_cyc_i == 1'b1) ? 1'b1 : 1'b0;
assign wb_dat_o = (trng_valid_o == 1'b1 && read_trng == 1'b1) ? trng_buffer_o : 'h0;
ringosc_macro #(.TRIM_BITS(26))
ringosc_macro_dut (
`ifdef USE_POWER_PINS
.vccd1 (vccd1),
.vssd1 (vssd1),
`endif
.rst_i (rst_i),
.trim_fast (trim_fast),
.trim_slow (trim_slow),
.trng_o (trng_o)
);
assign trim_select = wb_dat_i[5];
assign trim_write_en = (wb_stb_i == 1'b1 && wb_we_i == 1'b1 && wb_cyc_i == 1'b1) ? 1'b1 : 1'b0;
always @(posedge wb_clk_i)
begin
if (rst_i == 1'b1) begin
trim_slow <= 26'b11111111111111111111111111;
trim_fast <= 26'b00000000000000000000000000;
end
else begin
if (trim_write_en) begin
if(trim_select)
case(wb_dat_i[4:0])
5'b00000: trim_fast = 26'b00000000000000000000000000;
5'b00001: trim_fast = 26'b00000000000000000000000001;
5'b00010: trim_fast = 26'b00000000000000000000000011;
5'b00011: trim_fast = 26'b00000000000000000000000111;
5'b00100: trim_fast = 26'b00000000000000000000001111;
5'b00101: trim_fast = 26'b00000000000000000000011111;
5'b00110: trim_fast = 26'b00000000000000000000111111;
5'b00111: trim_fast = 26'b00000000000000000001111111;
5'b01000: trim_fast = 26'b00000000000000000011111111;
5'b01001: trim_fast = 26'b00000000000000000111111111;
5'b01010: trim_fast = 26'b00000000000000001111111111;
5'b01011: trim_fast = 26'b00000000000000011111111111;
5'b01100: trim_fast = 26'b00000000000000111111111111;
5'b01101: trim_fast = 26'b00000000000001111111111111;
5'b01110: trim_fast = 26'b00000000000011111111111111;
5'b01111: trim_fast = 26'b00000000000111111111111111;
5'b10000: trim_fast = 26'b00000000001111111111111111;
5'b10001: trim_fast = 26'b00000000011111111111111111;
5'b10010: trim_fast = 26'b00000000111111111111111111;
5'b10011: trim_fast = 26'b00000001111111111111111111;
5'b10100: trim_fast = 26'b00000011111111111111111111;
5'b10101: trim_fast = 26'b00000111111111111111111111;
5'b10110: trim_fast = 26'b00001111111111111111111111;
5'b10111: trim_fast = 26'b00011111111111111111111111;
5'b11000: trim_fast = 26'b00111111111111111111111111;
5'b11001: trim_fast = 26'b01111111111111111111111111;
5'b11010: trim_fast = 26'b11111111111111111111111111;
default: trim_fast = 26'b11111111111111111111111111;
endcase
else begin
case(wb_adr_i[4:0])
5'b00000: trim_slow = 26'b00000000000000000000000000;
5'b00001: trim_slow = 26'b00000000000000000000000001;
5'b00010: trim_slow = 26'b00000000000000000000000011;
5'b00011: trim_slow = 26'b00000000000000000000000111;
5'b00100: trim_slow = 26'b00000000000000000000001111;
5'b00101: trim_slow = 26'b00000000000000000000011111;
5'b00110: trim_slow = 26'b00000000000000000000111111;
5'b00111: trim_slow = 26'b00000000000000000001111111;
5'b01000: trim_slow = 26'b00000000000000000011111111;
5'b01001: trim_slow = 26'b00000000000000000111111111;
5'b01010: trim_slow = 26'b00000000000000001111111111;
5'b01011: trim_slow = 26'b00000000000000011111111111;
5'b01100: trim_slow = 26'b00000000000000111111111111;
5'b01101: trim_slow = 26'b00000000000001111111111111;
5'b01110: trim_slow = 26'b00000000000011111111111111;
5'b01111: trim_slow = 26'b00000000000111111111111111;
5'b10000: trim_slow = 26'b00000000001111111111111111;
5'b10001: trim_slow = 26'b00000000011111111111111111;
5'b10010: trim_slow = 26'b00000000111111111111111111;
5'b10011: trim_slow = 26'b00000001111111111111111111;
5'b10100: trim_slow = 26'b00000011111111111111111111;
5'b10101: trim_slow = 26'b00000111111111111111111111;
5'b10110: trim_slow = 26'b00001111111111111111111111;
5'b10111: trim_slow = 26'b00011111111111111111111111;
5'b11000: trim_slow = 26'b00111111111111111111111111;
5'b11001: trim_slow = 26'b01111111111111111111111111;
5'b11010: trim_slow = 26'b11111111111111111111111111;
default: trim_slow = 26'b00000000000000000000000000;
endcase
end
end
end
end
always @(posedge wb_clk_i)
begin
if (rst_i == 1'b1) begin
wb_ack_o <= 1'b0;
trng_valid_o <= 1'b0;
trng_counter <= 'h0;
trng_buffer_o <= 'h0;
end
else begin
// TRNG signalization
wb_ack_o <= 1'b0;
trng_counter <= trng_counter + 1;
trng_valid_o <= trng_valid_o;
if(trim_write_en == 1'b1 && wb_ack_o == 1'b0) begin
wb_ack_o <= 1'b1;
end
if(trng_counter == 6'b100000) begin
trng_counter <= 'h0;
trng_valid_o <= 1'b1;
end
if(read_trng == 1'b1 && trng_valid_o == 1'b1) begin
wb_ack_o <= 1'b1;
trng_counter <= 'h0;
trng_valid_o <= 1'b0;
end
trng_buffer_o <= {trng_buffer_o[30:0],trng_o};
end
end
endmodule