module streebog_wrapper
(
input wire clk,
input wire rst,
input wire cs,
input wire we,
input wire [ 7: 0] address,
input wire [31: 0] write_data,
output wire [31: 0] read_data
);
//----------------------------------------------------------------
// Internal constant and parameter definitions.
//----------------------------------------------------------------
localparam ADDR_NAME0 = 8'h00;
localparam ADDR_NAME1 = 8'h01;
localparam ADDR_VERSION = 8'h02;
localparam ADDR_CTRL = 8'h08; // {short, final, update, init}
localparam ADDR_STATUS = 8'h09; // {valid, ready}
localparam ADDR_BLOCK_BITS = 8'h0a; // block length in bits
localparam ADDR_MODE = 8'h0b; // 0=long (512-bit) mode, 1=short (256-bit) mode
localparam ADDR_BLOCK0 = 8'h10;
localparam ADDR_BLOCK1 = 8'h11;
localparam ADDR_BLOCK2 = 8'h12;
localparam ADDR_BLOCK3 = 8'h13;
localparam ADDR_BLOCK4 = 8'h14;
localparam ADDR_BLOCK5 = 8'h15;
localparam ADDR_BLOCK6 = 8'h16;
localparam ADDR_BLOCK7 = 8'h17;
localparam ADDR_BLOCK8 = 8'h18;
localparam ADDR_BLOCK9 = 8'h19;
localparam ADDR_BLOCK10 = 8'h1a;
localparam ADDR_BLOCK11 = 8'h1b;
localparam ADDR_BLOCK12 = 8'h1c;
localparam ADDR_BLOCK13 = 8'h1d;
localparam ADDR_BLOCK14 = 8'h1e;
localparam ADDR_BLOCK15 = 8'h1f;
localparam ADDR_DIGEST0 = 8'h20;
localparam ADDR_DIGEST1 = 8'h21;
localparam ADDR_DIGEST2 = 8'h22;
localparam ADDR_DIGEST3 = 8'h23;
localparam ADDR_DIGEST4 = 8'h24;
localparam ADDR_DIGEST5 = 8'h25;
localparam ADDR_DIGEST6 = 8'h26;
localparam ADDR_DIGEST7 = 8'h27;
localparam ADDR_DIGEST8 = 8'h28;
localparam ADDR_DIGEST9 = 8'h29;
localparam ADDR_DIGEST10 = 8'h2a;
localparam ADDR_DIGEST11 = 8'h2b;
localparam ADDR_DIGEST12 = 8'h2c;
localparam ADDR_DIGEST13 = 8'h2d;
localparam ADDR_DIGEST14 = 8'h2e;
localparam ADDR_DIGEST15 = 8'h2f;
localparam CTRL_INIT_BIT = 0;
localparam CTRL_UPDATE_BIT = 1;
localparam CTRL_FINAL_BIT = 2;
localparam STATUS_READY_BIT = 0;
localparam STATUS_VALID_BIT = 1;
localparam CORE_NAME0 = 32'h73747265; // "stre"
localparam CORE_NAME1 = 32'h65626F67; // "ebog"
localparam CORE_VERSION = 32'h302E3130; // "0.10"
//----------------------------------------------------------------
// Control register
//----------------------------------------------------------------
reg [2:0] reg_ctrl; // core input
reg [9:0] reg_block_bits; // input block length in bits
reg reg_mode; // long/short mode
//----------------------------------------------------------------
// Init, Update and Final 1-Cycle Pulses
//----------------------------------------------------------------
reg [2:0] reg_ctrl_dly;
always @(posedge clk) reg_ctrl_dly <= reg_ctrl;
wire core_init_pulse = (reg_ctrl[CTRL_INIT_BIT] == 1'b1) && (reg_ctrl_dly[CTRL_INIT_BIT] == 1'b0);
wire core_update_pulse = (reg_ctrl[CTRL_UPDATE_BIT] == 1'b1) && (reg_ctrl_dly[CTRL_UPDATE_BIT] == 1'b0);
wire core_final_pulse = (reg_ctrl[CTRL_FINAL_BIT] == 1'b1) && (reg_ctrl_dly[CTRL_FINAL_BIT] == 1'b0);
//----------------------------------------------------------------
// Status register
//----------------------------------------------------------------
wire core_ready; // core output
wire digest_valid; // core output
wire [1:0] reg_status = {digest_valid, core_ready};
//----------------------------------------------------------------
// Block and Digest
//----------------------------------------------------------------
reg [511 : 0] core_block; // core input
wire [511 : 0] core_digest; // core output
//----------------------------------------------------------------
// core instantiation.
//----------------------------------------------------------------
streebog_hash_top streebog
(
.clock (clk),
.block (core_block),
.block_length (reg_block_bits),
.init (core_init_pulse),
.update (core_update_pulse),
.final (core_final_pulse),
.short_mode (reg_mode),
.digest (core_digest),
.digest_valid (digest_valid),
.ready (core_ready)
);
//----------------------------------------------------------------
// Read Latch
//----------------------------------------------------------------
reg [31: 0] tmp_read_data;
assign read_data = tmp_read_data;
//----------------------------------------------------------------
// Read/Write Interface
//----------------------------------------------------------------
always @(posedge clk)
//
if (rst) begin
//
reg_ctrl <= 3'b000;
reg_block_bits <= 10'd0;
reg_mode <= 1'b0;
core_block <= {512{1'b0}};
tmp_read_data <= 32'h00000000;
//
end else if (cs) begin
//
if (we) begin
//
// Write Handler
//
case (address)
ADDR_CTRL: reg_ctrl <= write_data[2:0];
ADDR_BLOCK_BITS: reg_block_bits <= write_data[9:0];
ADDR_MODE: reg_mode <= write_data[0];
ADDR_BLOCK0: core_block[511:480] <= write_data;
ADDR_BLOCK1: core_block[479:448] <= write_data;
ADDR_BLOCK2: core_block[447:416] <= write_data;
ADDR_BLOCK3: core_block[415:384] <= write_data;
ADDR_BLOCK4: core_block[383:352] <= write_data;
ADDR_BLOCK5: core_block[351:320] <= write_data;
ADDR_BLOCK6: core_block[319:288] <= write_data;
ADDR_BLOCK7: core_block[287:256] <= write_data;
ADDR_BLOCK8: core_block[255:224] <= write_data;
ADDR_BLOCK9: core_block[223:192] <= write_data;
ADDR_BLOCK10: core_block[191:160] <= write_data;
ADDR_BLOCK11: core_block[159:128] <= write_data;
ADDR_BLOCK12: core_block[127: 96] <= write_data;
ADDR_BLOCK13: core_block[ 95: 64] <= write_data;
ADDR_BLOCK14: core_block[ 63: 32] <= write_data;
ADDR_BLOCK15: core_block[ 31: 0] <= write_data;
endcase
//
end else begin
//
// Read Handler
//
case (address)
//
ADDR_NAME0: tmp_read_data <= CORE_NAME0;
ADDR_NAME1: tmp_read_data <= CORE_NAME1;
ADDR_VERSION: tmp_read_data <= CORE_VERSION;
ADDR_CTRL: tmp_read_data <= {{28{1'b0}}, reg_ctrl};
ADDR_STATUS: tmp_read_data <= {{30{1'b0}}, reg_status};
ADDR_BLOCK_BITS: tmp_read_data <= {{22{1'b0}}, reg_block_bits};
ADDR_MODE: tmp_read_data <= {{31{1'b0}}, reg_mode};
//
ADDR_BLOCK0: tmp_read_data <= core_block[511:480];
ADDR_BLOCK1: tmp_read_data <= core_block[479:448];
ADDR_BLOCK2: tmp_read_data <= core_block[447:416];
ADDR_BLOCK3: tmp_read_data <= core_block[415:384];
ADDR_BLOCK4: tmp_read_data <= core_block[383:352];
ADDR_BLOCK5: tmp_read_data <= core_block[351:320];
ADDR_BLOCK6: tmp_read_data <= core_block[319:288];
ADDR_BLOCK7: tmp_read_data <= core_block[287:256];
ADDR_BLOCK8: tmp_read_data <= core_block[255:224];
ADDR_BLOCK9: tmp_read_data <= core_block[223:192];
ADDR_BLOCK10: tmp_read_data <= core_block[191:160];
ADDR_BLOCK11: tmp_read_data <= core_block[159:128];
ADDR_BLOCK12: tmp_read_data <= core_block[127: 96];
ADDR_BLOCK13: tmp_read_data <= core_block[ 95: 64];
ADDR_BLOCK14: tmp_read_data <= core_block[ 63: 32];
ADDR_BLOCK15: tmp_read_data <= core_block[ 31: 0];
//
ADDR_DIGEST0: tmp_read_data <= core_digest[511:480];
ADDR_DIGEST1: tmp_read_data <= core_digest[479:448];
ADDR_DIGEST2: tmp_read_data <= core_digest[447:416];
ADDR_DIGEST3: tmp_read_data <= core_digest[415:384];
ADDR_DIGEST4: tmp_read_data <= core_digest[383:352];
ADDR_DIGEST5: tmp_read_data <= core_digest[351:320];
ADDR_DIGEST6: tmp_read_data <= core_digest[319:288];
ADDR_DIGEST7: tmp_read_data <= core_digest[287:256];
ADDR_DIGEST8: tmp_read_data <= core_digest[255:224];
ADDR_DIGEST9: tmp_read_data <= core_digest[223:192];
ADDR_DIGEST10: tmp_read_data <= core_digest[191:160];
ADDR_DIGEST11: tmp_read_data <= core_digest[159:128];
ADDR_DIGEST12: tmp_read_data <= core_digest[127: 96];
ADDR_DIGEST13: tmp_read_data <= core_digest[ 95: 64];
ADDR_DIGEST14: tmp_read_data <= core_digest[ 63: 32];
ADDR_DIGEST15: tmp_read_data <= core_digest[ 31: 0];
//
default: tmp_read_data <= 32'h00000000;
//
endcase
//
end
//
end
endmodule // streebog_wrapper
//======================================================================
// EOF streebog_wrapper.v
//======================================================================