Fixes for blake2 engine and testbench passing rfc_test now
This commit is contained in:
parent
7c0d5dab5b
commit
a07b4a7cc6
|
@ -1,6 +1,9 @@
|
||||||
package blake2_pkg;
|
package blake2_pkg;
|
||||||
|
// User configurable values
|
||||||
|
parameter [7:0] NN = 64; // Output hash byte length
|
||||||
|
|
||||||
// Initial values
|
|
||||||
|
// Initial values
|
||||||
parameter [7:0][63:0] IV = {
|
parameter [7:0][63:0] IV = {
|
||||||
64'h5be0cd19137e2179,
|
64'h5be0cd19137e2179,
|
||||||
64'h1f83d9abfb41bd6b,
|
64'h1f83d9abfb41bd6b,
|
||||||
|
@ -12,39 +15,38 @@ package blake2_pkg;
|
||||||
64'h6a09e667f3bcc908
|
64'h6a09e667f3bcc908
|
||||||
};
|
};
|
||||||
|
|
||||||
parameter [15*10-1:0][31:0] SIGMA = {
|
parameter [16*10-1:0][31:0] SIGMA = {
|
||||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
0, 13, 12, 3, 14, 9, 11, 15, 5, 1, 6, 7, 4, 8, 2, 10,
|
||||||
14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3,
|
5, 10, 4, 1, 7, 13, 2, 12, 8, 0, 3, 11, 9, 14, 15, 6,
|
||||||
11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4,
|
10, 2, 6, 8, 4, 15, 0, 5, 9, 3, 1, 12, 14, 7, 11, 13,
|
||||||
7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8,
|
11, 8, 2, 9, 3, 6, 7, 0, 10, 4, 13, 14, 15, 1, 5, 12,
|
||||||
9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13,
|
9, 1, 14, 15, 5, 7, 13, 4, 3, 8, 11, 0, 10, 6, 12, 2,
|
||||||
2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9,
|
13, 3, 8, 6, 12, 11, 1, 14, 15, 10, 4, 2, 7, 5, 0, 9,
|
||||||
12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11,
|
8, 15, 0, 4, 10, 5, 6, 2, 14, 11, 12, 13, 1, 3, 9, 7,
|
||||||
13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10,
|
4, 9, 1, 7, 6, 3, 14, 10, 13, 15, 2, 5, 0, 12, 8, 11,
|
||||||
6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5,
|
3, 5, 7, 11, 2, 0, 12, 1, 6, 13, 15, 9, 8, 4, 10, 14,
|
||||||
10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0
|
15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
parameter [4*8-1:0][31:0] G_MAPPING = {
|
parameter [4*8-1:0][31:0] G_MAPPING = {
|
||||||
14, 9, 4, 3,
|
14, 9, 4, 3,
|
||||||
13, 8, 7, 2,
|
13, 8, 7, 2,
|
||||||
12, 11, 6, 1,
|
12, 11, 6, 1,
|
||||||
15, 10, 5, 0,
|
15, 10, 5, 0,
|
||||||
15, 11, 7, 3,
|
15, 11, 7, 3,
|
||||||
14, 10, 6, 2,
|
14, 10, 6, 2,
|
||||||
13, 9, 5, 1,
|
13, 9, 5, 1,
|
||||||
12, 8, 4, 0
|
12, 8, 4, 0
|
||||||
};
|
};
|
||||||
|
|
||||||
// Top 4 bits per entry is the nth G-function unit
|
// This is so we can get the correct mapping back from the diagonal
|
||||||
// lower 4 bits is the ith output of the G-function
|
// operation
|
||||||
parameter [15:0][5:0] G_FINAL_MAPPING = {
|
parameter [4*4-1:0][31:0] G_MAPPING_DIAG = {
|
||||||
{3'd4,3'd3}, {3'd7,3'd3}, {3'd6,3'd3}, {3'd5,3'd3},
|
3, 15, 11,7,
|
||||||
{3'd5,3'd2}, {3'd4,3'd2}, {3'd7,3'd2}, {3'd6,3'd2},
|
6, 2, 14, 10,
|
||||||
{3'd6,3'd1}, {3'd5,3'd1}, {3'd4,3'd1}, {3'd7,3'd1},
|
9, 5, 1, 13,
|
||||||
{3'd7,3'd0}, {3'd6,3'd0}, {3'd5,3'd0}, {3'd4, 3'd0}
|
12, 8 , 4, 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
endpackage
|
endpackage
|
|
@ -3,7 +3,6 @@
|
||||||
module blake2_top
|
module blake2_top
|
||||||
import blake2_pkg::*;
|
import blake2_pkg::*;
|
||||||
#(
|
#(
|
||||||
|
|
||||||
)
|
)
|
||||||
(
|
(
|
||||||
input i_clk, i_rst,
|
input i_clk, i_rst,
|
||||||
|
@ -20,9 +19,9 @@ module blake2_top
|
||||||
output logic[64*8-1:0] o_digest,
|
output logic[64*8-1:0] o_digest,
|
||||||
output logic o_rdy,
|
output logic o_rdy,
|
||||||
output logic o_val,
|
output logic o_val,
|
||||||
output logic o_err
|
output logic o_err,
|
||||||
|
|
||||||
|
if_axi_stream o_hash
|
||||||
);
|
);
|
||||||
|
|
||||||
enum {STATE_IDLE = 0,
|
enum {STATE_IDLE = 0,
|
||||||
|
@ -31,24 +30,27 @@ enum {STATE_IDLE = 0,
|
||||||
|
|
||||||
localparam ROUNDS = 12;
|
localparam ROUNDS = 12;
|
||||||
|
|
||||||
logic [64*8-1:0] parameters;
|
logic [64*8-1:0] parameters, parameters_r;
|
||||||
logic [7:0][63:0] h; // The state vector
|
logic [7:0][63:0] h; // The state vector
|
||||||
logic [15:0][63:0] v; // The local work vector
|
logic [15:0][63:0] v; // The local work vector
|
||||||
logic [31:0][63:0] g_out; // Outputs of the G mixing function - use 8 here to save on timing
|
logic [31:0][63:0] g_out; // Outputs of the G mixing function - use 8 here to save on timing
|
||||||
logic [127:0] t; // Counter - TODO make this smaller - related to param
|
logic [127:0] t; // Counter - TODO make this smaller - related to param
|
||||||
logic [$clog2(ROUNDS)-1:0] round_cntr;
|
logic [$clog2(ROUNDS)-1:0] round_cntr;
|
||||||
logic cnt;
|
logic cnt;
|
||||||
logic g_row_col;
|
logic g_col;
|
||||||
logic [15:0][63:0] block_r; // The message block registered and converted to a 2d array
|
logic [15:0][63:0] block_r; // The message block registered and converted to a 2d array
|
||||||
logic final_block_r;
|
logic final_block_r;
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
parameters = {32'd0, 8'd1, 8'd1, i_key_byte_len, blake2_pkg::NN};
|
||||||
|
end
|
||||||
|
|
||||||
// Logic that is for pipelining
|
// Logic that is for pipelining
|
||||||
always_ff @(posedge i_clk) begin
|
always_ff @(posedge i_clk) begin
|
||||||
parameters <= {32'd0, 8'd1, 8'd1, i_key_byte_len, i_digest_byte_len};
|
|
||||||
if (i_val && o_rdy) begin
|
if (i_val && o_rdy) begin
|
||||||
block_r <= i_block;
|
block_r <= i_block;
|
||||||
final_block_r <= i_final_block;
|
final_block_r <= i_final_block;
|
||||||
|
parameters_r <= parameters;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -60,26 +62,30 @@ always_ff @(posedge i_clk) begin
|
||||||
o_rdy <= 0;
|
o_rdy <= 0;
|
||||||
h <= 0;
|
h <= 0;
|
||||||
v <= 0;
|
v <= 0;
|
||||||
t <= 0;
|
t <= 128;
|
||||||
g_row_col <= 0;
|
g_col <= 0;
|
||||||
round_cntr <= 0;
|
round_cntr <= 0;
|
||||||
o_err <= 0;
|
o_err <= 0;
|
||||||
o_digest <= 0;
|
o_digest <= 0;
|
||||||
cnt <= 0;
|
cnt <= 0;
|
||||||
|
|
||||||
|
o_hash.reset();
|
||||||
|
|
||||||
end else begin
|
end else begin
|
||||||
cnt <= cnt + 1;
|
cnt <= cnt + 1;
|
||||||
case (blake2_state)
|
case (blake2_state)
|
||||||
STATE_IDLE: begin
|
STATE_IDLE: begin
|
||||||
o_val <= 0;
|
o_val <= 0;
|
||||||
init_state_vector();
|
init_state_vector();
|
||||||
t <= 0;
|
t <= 128;
|
||||||
o_err <= 0;
|
o_err <= 0;
|
||||||
o_rdy <= 1;
|
o_rdy <= 1;
|
||||||
v <= 0;
|
v <= 0;
|
||||||
g_row_col <= 0;
|
o_hash.val = 0;
|
||||||
|
g_col <= 0;
|
||||||
round_cntr <= 0;
|
round_cntr <= 0;
|
||||||
if (o_rdy && i_val && i_new_block) begin
|
if (o_rdy && i_val && i_new_block) begin
|
||||||
init_local_work_vector();
|
init_local_work_vector(i_final_block ? i_digest_byte_len : t);
|
||||||
blake2_state <= STATE_ROUNDS;
|
blake2_state <= STATE_ROUNDS;
|
||||||
o_rdy <= 0;
|
o_rdy <= 0;
|
||||||
end
|
end
|
||||||
|
@ -89,19 +95,19 @@ always_ff @(posedge i_clk) begin
|
||||||
STATE_ROUNDS: begin
|
STATE_ROUNDS: begin
|
||||||
// Update local work vector with output of G function blocks
|
// Update local work vector with output of G function blocks
|
||||||
for (int i = 0; i < 16; i++)
|
for (int i = 0; i < 16; i++)
|
||||||
v[i] <= g_out[G_MAPPING[g_row_col*16 + i]];
|
v[i] <= g_col == 0 ? g_out[blake2_pkg::G_MAPPING[i]] : g_out[16 + blake2_pkg::G_MAPPING_DIAG[i]];
|
||||||
|
|
||||||
if (g_row_col)
|
if (g_col)
|
||||||
round_cntr <= round_cntr + 1;
|
round_cntr <= round_cntr + 1;
|
||||||
g_row_col <= ~g_row_col;
|
g_col <= ~g_col;
|
||||||
|
|
||||||
// Update state vector on the final round
|
// Update state vector on the final round
|
||||||
if (round_cntr == ROUNDS-1) begin
|
if (round_cntr == ROUNDS-1 && g_col) begin
|
||||||
|
|
||||||
for (int i = 0; i < 7; i++)
|
for (int i = 0; i < 8; i++)
|
||||||
h[i] <= h[i] ^
|
h[i] <= h[i] ^
|
||||||
g_out[G_FINAL_MAPPING[i][5:3]][G_FINAL_MAPPING[i][2:0]] ^
|
g_out[16 + blake2_pkg::G_MAPPING_DIAG[i]] ^
|
||||||
g_out[G_FINAL_MAPPING[i+8][5:3]][G_FINAL_MAPPING[i][2:0]];
|
g_out[16 + blake2_pkg::G_MAPPING_DIAG[i+8]];
|
||||||
|
|
||||||
blake2_state <= STATE_NEXT_BLOCK;
|
blake2_state <= STATE_NEXT_BLOCK;
|
||||||
if (~final_block_r)
|
if (~final_block_r)
|
||||||
|
@ -111,13 +117,23 @@ always_ff @(posedge i_clk) begin
|
||||||
end
|
end
|
||||||
STATE_NEXT_BLOCK: begin
|
STATE_NEXT_BLOCK: begin
|
||||||
if (final_block_r) begin
|
if (final_block_r) begin
|
||||||
blake2_state <= STATE_IDLE;
|
|
||||||
o_val <= 1;
|
o_val <= 1;
|
||||||
o_digest <= h;
|
o_digest <= h;
|
||||||
|
t <= 128;
|
||||||
|
if (~o_hash.val) begin
|
||||||
|
o_hash.dat <= h;
|
||||||
|
o_hash.val <= 1;
|
||||||
|
o_hash.sop <= 1;
|
||||||
|
o_hash.eop <= 1;
|
||||||
|
end
|
||||||
|
if (o_hash.rdy)
|
||||||
|
blake2_state <= STATE_IDLE;
|
||||||
|
|
||||||
end else if (o_rdy && i_val) begin
|
end else if (o_rdy && i_val) begin
|
||||||
round_cntr <= 0;
|
round_cntr <= 0;
|
||||||
init_local_work_vector();
|
init_local_work_vector(t);
|
||||||
t <= (t+1) * 128;
|
t <= t + 128;
|
||||||
blake2_state <= STATE_ROUNDS;
|
blake2_state <= STATE_ROUNDS;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -133,12 +149,12 @@ generate begin
|
||||||
#(.PIPELINES(0))
|
#(.PIPELINES(0))
|
||||||
blake2_g (
|
blake2_g (
|
||||||
.i_clk(i_clk),
|
.i_clk(i_clk),
|
||||||
.i_a(v[(gv_g*4 + 0) % 16]),
|
.i_a(v[blake2_pkg::G_MAPPING[(gv_g*4 + 0)]]),
|
||||||
.i_b(v[(gv_g*4 + 1) % 16]),
|
.i_b(v[blake2_pkg::G_MAPPING[(gv_g*4 + 1)]]),
|
||||||
.i_c(v[(gv_g*4 + 2) % 16]),
|
.i_c(v[blake2_pkg::G_MAPPING[(gv_g*4 + 2)]]),
|
||||||
.i_d(v[(gv_g*4 + 3) % 16]),
|
.i_d(v[blake2_pkg::G_MAPPING[(gv_g*4 + 3)]]),
|
||||||
.i_m0(block_r[blake2_pkg::SIGMA[(round_cntr % 10) + (gv_g*16)]]),
|
.i_m0(block_r[blake2_pkg::SIGMA[16*(round_cntr % 10) + (gv_g*2)]]),
|
||||||
.i_m1(block_r[blake2_pkg::SIGMA[(round_cntr % 10) + ((gv_g+1))*16]]),
|
.i_m1(block_r[blake2_pkg::SIGMA[16*(round_cntr % 10) + (gv_g*2 + 1)]]),
|
||||||
.o_a(g_out[gv_g*4 + 0]),
|
.o_a(g_out[gv_g*4 + 0]),
|
||||||
.o_b(g_out[gv_g*4 + 1]),
|
.o_b(g_out[gv_g*4 + 1]),
|
||||||
.o_c(g_out[gv_g*4 + 2]),
|
.o_c(g_out[gv_g*4 + 2]),
|
||||||
|
@ -160,14 +176,14 @@ end
|
||||||
endtask
|
endtask
|
||||||
|
|
||||||
// Task to initialize local work vector for the compression function
|
// Task to initialize local work vector for the compression function
|
||||||
task init_local_work_vector();
|
task init_local_work_vector(input [127:0] cntr);
|
||||||
begin
|
begin
|
||||||
for (int i = 0; i < 16; i++)
|
for (int i = 0; i < 16; i++)
|
||||||
case (i) inside
|
case (i) inside
|
||||||
0,1,2,3,4,5,6,7: v[i] <= h[i];
|
0,1,2,3,4,5,6,7: v[i] <= h[i];
|
||||||
8,9,10,11: v[i] <= blake2_pkg::IV[i%8];
|
8,9,10,11: v[i] <= blake2_pkg::IV[i%8];
|
||||||
12: v[i] <= blake2_pkg::IV[i%8] ^ t[63:0];
|
12: v[i] <= blake2_pkg::IV[i%8] ^ cntr[63:0];
|
||||||
13: v[i] <= blake2_pkg::IV[i%8] ^ t[64 +: 64];
|
13: v[i] <= blake2_pkg::IV[i%8] ^ cntr[64 +: 64];
|
||||||
14: v[i] <= blake2_pkg::IV[i%8] ^ {64{i_final_block}};
|
14: v[i] <= blake2_pkg::IV[i%8] ^ {64{i_final_block}};
|
||||||
15: v[i] <= blake2_pkg::IV[i%8];
|
15: v[i] <= blake2_pkg::IV[i%8];
|
||||||
endcase
|
endcase
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
module blake2_top_tb();
|
module blake2_top_tb();
|
||||||
|
|
||||||
|
import blake2_pkg::*;
|
||||||
|
|
||||||
logic clk, rst;
|
logic clk, rst;
|
||||||
logic [7:0] digest_byte_len, key_byte_len;
|
logic [7:0] digest_byte_len, key_byte_len;
|
||||||
logic [128*8-1:0] i_block;
|
logic [128*8-1:0] i_block;
|
||||||
|
@ -11,6 +13,8 @@ logic o_rdy;
|
||||||
logic o_val;
|
logic o_val;
|
||||||
logic o_err;
|
logic o_err;
|
||||||
|
|
||||||
|
if_axi_stream #(.DAT_BYTS(blake2_pkg::NN)) out_hash(clk);
|
||||||
|
|
||||||
initial begin
|
initial begin
|
||||||
rst = 0;
|
rst = 0;
|
||||||
#100ns rst = 1;
|
#100ns rst = 1;
|
||||||
|
@ -35,7 +39,9 @@ blake2_top DUT (
|
||||||
.o_digest(o_digest),
|
.o_digest(o_digest),
|
||||||
.o_rdy(o_rdy),
|
.o_rdy(o_rdy),
|
||||||
.o_val(o_val),
|
.o_val(o_val),
|
||||||
.o_err(o_err)
|
.o_err(o_err),
|
||||||
|
|
||||||
|
.o_hash(out_hash)
|
||||||
);
|
);
|
||||||
|
|
||||||
// This test runs the hash which is shown in the RFC, for "abc"
|
// This test runs the hash which is shown in the RFC, for "abc"
|
||||||
|
@ -49,19 +55,18 @@ begin
|
||||||
i_val = 1;
|
i_val = 1;
|
||||||
i_final_block = 1;
|
i_final_block = 1;
|
||||||
i_new_block = 1;
|
i_new_block = 1;
|
||||||
|
digest_byte_len = 3;
|
||||||
|
key_byte_len = 0;
|
||||||
i_block = 'h636261;
|
i_block = 'h636261;
|
||||||
|
|
||||||
@(negedge clk);
|
@(negedge clk);
|
||||||
i_val = 0;
|
i_val = 0;
|
||||||
|
|
||||||
// TODO check rdy goes low
|
while (!out_hash.val) @(posedge clk);
|
||||||
|
|
||||||
while (!o_val) @(posedge clk);
|
assert (out_hash.dat == 'h239900d4ed8623b95a92f1dba88ad31895cc3345ded552c22d79ab2a39c5877dd1a2ffdb6fbb124bb7c45a68142f214ce9f6129fb697276a0d4d1c983fa580ba) else $fatal(0, "%m %t:ERROR, out_hash.dat did not match, was:\n0x%h", $time, out_hash.dat);
|
||||||
|
assert (out_hash.sop == 1) else $fatal(0, "%m %t:ERROR, out_hash.sop was not high", $time);
|
||||||
@(posedge clk);
|
assert (out_hash.eop == 1) else $fatal(0, "%m %t:ERROR, out_hash.sop was not high", $time);
|
||||||
@(posedge clk);
|
|
||||||
|
|
||||||
// TODO verify result
|
|
||||||
|
|
||||||
$display("rfc_test PASSED");
|
$display("rfc_test PASSED");
|
||||||
end
|
end
|
||||||
|
@ -70,11 +75,13 @@ endtask
|
||||||
// Main testbench calls
|
// Main testbench calls
|
||||||
initial begin
|
initial begin
|
||||||
key_byte_len = 0;
|
key_byte_len = 0;
|
||||||
digest_byte_len = 64;
|
digest_byte_len = 3;
|
||||||
i_block = '0;
|
i_block = '0;
|
||||||
i_new_block = '0;
|
i_new_block = '0;
|
||||||
i_final_block = '0;
|
i_final_block = '0;
|
||||||
i_val = '0;
|
i_val = '0;
|
||||||
|
out_hash.rdy = 1;
|
||||||
|
|
||||||
|
|
||||||
#200ns;
|
#200ns;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
|
||||||
|
// Interface for a AXI stream
|
||||||
|
interface if_axi_stream # (
|
||||||
|
parameter DAT_BYTS = 8,
|
||||||
|
parameter CTL_BYTS = 8
|
||||||
|
)(
|
||||||
|
input i_clk
|
||||||
|
);
|
||||||
|
|
||||||
|
localparam DAT_BITS = DAT_BYTS*8;
|
||||||
|
localparam CTL_BITS = CTL_BYTS*8;
|
||||||
|
|
||||||
|
logic rdy;
|
||||||
|
logic val;
|
||||||
|
logic err;
|
||||||
|
logic sop;
|
||||||
|
logic eop;
|
||||||
|
logic [CTL_BITS-1:0] ctl;
|
||||||
|
logic [DAT_BITS-1:0] dat;
|
||||||
|
logic [$clog2(DAT_BYTS)-1:0] mod;
|
||||||
|
|
||||||
|
task reset();
|
||||||
|
val <= 0;
|
||||||
|
err <= 0;
|
||||||
|
sop <= 0;
|
||||||
|
eop <= 0;
|
||||||
|
dat <= 0;
|
||||||
|
ctl <= 0;
|
||||||
|
mod <= 0;
|
||||||
|
endtask
|
||||||
|
|
||||||
|
endinterface
|
Loading…
Reference in New Issue