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;
|
||||
// User configurable values
|
||||
parameter [7:0] NN = 64; // Output hash byte length
|
||||
|
||||
// Initial values
|
||||
|
||||
// Initial values
|
||||
parameter [7:0][63:0] IV = {
|
||||
64'h5be0cd19137e2179,
|
||||
64'h1f83d9abfb41bd6b,
|
||||
|
@ -12,39 +15,38 @@ package blake2_pkg;
|
|||
64'h6a09e667f3bcc908
|
||||
};
|
||||
|
||||
parameter [15*10-1:0][31:0] SIGMA = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3,
|
||||
11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4,
|
||||
7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8,
|
||||
9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13,
|
||||
2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9,
|
||||
12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11,
|
||||
13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10,
|
||||
6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5,
|
||||
10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0
|
||||
};
|
||||
parameter [16*10-1:0][31:0] SIGMA = {
|
||||
0, 13, 12, 3, 14, 9, 11, 15, 5, 1, 6, 7, 4, 8, 2, 10,
|
||||
5, 10, 4, 1, 7, 13, 2, 12, 8, 0, 3, 11, 9, 14, 15, 6,
|
||||
10, 2, 6, 8, 4, 15, 0, 5, 9, 3, 1, 12, 14, 7, 11, 13,
|
||||
11, 8, 2, 9, 3, 6, 7, 0, 10, 4, 13, 14, 15, 1, 5, 12,
|
||||
9, 1, 14, 15, 5, 7, 13, 4, 3, 8, 11, 0, 10, 6, 12, 2,
|
||||
13, 3, 8, 6, 12, 11, 1, 14, 15, 10, 4, 2, 7, 5, 0, 9,
|
||||
8, 15, 0, 4, 10, 5, 6, 2, 14, 11, 12, 13, 1, 3, 9, 7,
|
||||
4, 9, 1, 7, 6, 3, 14, 10, 13, 15, 2, 5, 0, 12, 8, 11,
|
||||
3, 5, 7, 11, 2, 0, 12, 1, 6, 13, 15, 9, 8, 4, 10, 14,
|
||||
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 = {
|
||||
14, 9, 4, 3,
|
||||
13, 8, 7, 2,
|
||||
12, 11, 6, 1,
|
||||
15, 10, 5, 0,
|
||||
15, 11, 7, 3,
|
||||
14, 10, 6, 2,
|
||||
13, 9, 5, 1,
|
||||
12, 8, 4, 0
|
||||
};
|
||||
|
||||
// Top 4 bits per entry is the nth G-function unit
|
||||
// lower 4 bits is the ith output of the G-function
|
||||
parameter [15:0][5:0] G_FINAL_MAPPING = {
|
||||
{3'd4,3'd3}, {3'd7,3'd3}, {3'd6,3'd3}, {3'd5,3'd3},
|
||||
{3'd5,3'd2}, {3'd4,3'd2}, {3'd7,3'd2}, {3'd6,3'd2},
|
||||
{3'd6,3'd1}, {3'd5,3'd1}, {3'd4,3'd1}, {3'd7,3'd1},
|
||||
{3'd7,3'd0}, {3'd6,3'd0}, {3'd5,3'd0}, {3'd4, 3'd0}
|
||||
};
|
||||
|
||||
parameter [4*8-1:0][31:0] G_MAPPING = {
|
||||
14, 9, 4, 3,
|
||||
13, 8, 7, 2,
|
||||
12, 11, 6, 1,
|
||||
15, 10, 5, 0,
|
||||
15, 11, 7, 3,
|
||||
14, 10, 6, 2,
|
||||
13, 9, 5, 1,
|
||||
12, 8, 4, 0
|
||||
};
|
||||
|
||||
// This is so we can get the correct mapping back from the diagonal
|
||||
// operation
|
||||
parameter [4*4-1:0][31:0] G_MAPPING_DIAG = {
|
||||
3, 15, 11,7,
|
||||
6, 2, 14, 10,
|
||||
9, 5, 1, 13,
|
||||
12, 8 , 4, 0
|
||||
};
|
||||
|
||||
endpackage
|
|
@ -3,7 +3,6 @@
|
|||
module blake2_top
|
||||
import blake2_pkg::*;
|
||||
#(
|
||||
|
||||
)
|
||||
(
|
||||
input i_clk, i_rst,
|
||||
|
@ -20,9 +19,9 @@ module blake2_top
|
|||
output logic[64*8-1:0] o_digest,
|
||||
output logic o_rdy,
|
||||
output logic o_val,
|
||||
output logic o_err
|
||||
|
||||
|
||||
output logic o_err,
|
||||
|
||||
if_axi_stream o_hash
|
||||
);
|
||||
|
||||
enum {STATE_IDLE = 0,
|
||||
|
@ -31,24 +30,27 @@ enum {STATE_IDLE = 0,
|
|||
|
||||
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 [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 [127:0] t; // Counter - TODO make this smaller - related to param
|
||||
logic [$clog2(ROUNDS)-1:0] round_cntr;
|
||||
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 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
|
||||
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
|
||||
block_r <= i_block;
|
||||
final_block_r <= i_final_block;
|
||||
parameters_r <= parameters;
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -60,26 +62,30 @@ always_ff @(posedge i_clk) begin
|
|||
o_rdy <= 0;
|
||||
h <= 0;
|
||||
v <= 0;
|
||||
t <= 0;
|
||||
g_row_col <= 0;
|
||||
t <= 128;
|
||||
g_col <= 0;
|
||||
round_cntr <= 0;
|
||||
o_err <= 0;
|
||||
o_digest <= 0;
|
||||
cnt <= 0;
|
||||
|
||||
o_hash.reset();
|
||||
|
||||
end else begin
|
||||
cnt <= cnt + 1;
|
||||
case (blake2_state)
|
||||
STATE_IDLE: begin
|
||||
o_val <= 0;
|
||||
init_state_vector();
|
||||
t <= 0;
|
||||
t <= 128;
|
||||
o_err <= 0;
|
||||
o_rdy <= 1;
|
||||
v <= 0;
|
||||
g_row_col <= 0;
|
||||
o_hash.val = 0;
|
||||
g_col <= 0;
|
||||
round_cntr <= 0;
|
||||
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;
|
||||
o_rdy <= 0;
|
||||
end
|
||||
|
@ -89,19 +95,19 @@ always_ff @(posedge i_clk) begin
|
|||
STATE_ROUNDS: begin
|
||||
// Update local work vector with output of G function blocks
|
||||
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;
|
||||
g_row_col <= ~g_row_col;
|
||||
g_col <= ~g_col;
|
||||
|
||||
// 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] ^
|
||||
g_out[G_FINAL_MAPPING[i][5:3]][G_FINAL_MAPPING[i][2:0]] ^
|
||||
g_out[G_FINAL_MAPPING[i+8][5:3]][G_FINAL_MAPPING[i][2:0]];
|
||||
g_out[16 + blake2_pkg::G_MAPPING_DIAG[i]] ^
|
||||
g_out[16 + blake2_pkg::G_MAPPING_DIAG[i+8]];
|
||||
|
||||
blake2_state <= STATE_NEXT_BLOCK;
|
||||
if (~final_block_r)
|
||||
|
@ -111,13 +117,23 @@ always_ff @(posedge i_clk) begin
|
|||
end
|
||||
STATE_NEXT_BLOCK: begin
|
||||
if (final_block_r) begin
|
||||
blake2_state <= STATE_IDLE;
|
||||
|
||||
o_val <= 1;
|
||||
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
|
||||
round_cntr <= 0;
|
||||
init_local_work_vector();
|
||||
t <= (t+1) * 128;
|
||||
init_local_work_vector(t);
|
||||
t <= t + 128;
|
||||
blake2_state <= STATE_ROUNDS;
|
||||
end
|
||||
end
|
||||
|
@ -133,12 +149,12 @@ generate begin
|
|||
#(.PIPELINES(0))
|
||||
blake2_g (
|
||||
.i_clk(i_clk),
|
||||
.i_a(v[(gv_g*4 + 0) % 16]),
|
||||
.i_b(v[(gv_g*4 + 1) % 16]),
|
||||
.i_c(v[(gv_g*4 + 2) % 16]),
|
||||
.i_d(v[(gv_g*4 + 3) % 16]),
|
||||
.i_m0(block_r[blake2_pkg::SIGMA[(round_cntr % 10) + (gv_g*16)]]),
|
||||
.i_m1(block_r[blake2_pkg::SIGMA[(round_cntr % 10) + ((gv_g+1))*16]]),
|
||||
.i_a(v[blake2_pkg::G_MAPPING[(gv_g*4 + 0)]]),
|
||||
.i_b(v[blake2_pkg::G_MAPPING[(gv_g*4 + 1)]]),
|
||||
.i_c(v[blake2_pkg::G_MAPPING[(gv_g*4 + 2)]]),
|
||||
.i_d(v[blake2_pkg::G_MAPPING[(gv_g*4 + 3)]]),
|
||||
.i_m0(block_r[blake2_pkg::SIGMA[16*(round_cntr % 10) + (gv_g*2)]]),
|
||||
.i_m1(block_r[blake2_pkg::SIGMA[16*(round_cntr % 10) + (gv_g*2 + 1)]]),
|
||||
.o_a(g_out[gv_g*4 + 0]),
|
||||
.o_b(g_out[gv_g*4 + 1]),
|
||||
.o_c(g_out[gv_g*4 + 2]),
|
||||
|
@ -160,14 +176,14 @@ end
|
|||
endtask
|
||||
|
||||
// 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
|
||||
for (int i = 0; i < 16; i++)
|
||||
case (i) inside
|
||||
0,1,2,3,4,5,6,7: v[i] <= h[i];
|
||||
8,9,10,11: v[i] <= blake2_pkg::IV[i%8];
|
||||
12: v[i] <= blake2_pkg::IV[i%8] ^ t[63:0];
|
||||
13: v[i] <= blake2_pkg::IV[i%8] ^ t[64 +: 64];
|
||||
12: v[i] <= blake2_pkg::IV[i%8] ^ cntr[63:0];
|
||||
13: v[i] <= blake2_pkg::IV[i%8] ^ cntr[64 +: 64];
|
||||
14: v[i] <= blake2_pkg::IV[i%8] ^ {64{i_final_block}};
|
||||
15: v[i] <= blake2_pkg::IV[i%8];
|
||||
endcase
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
module blake2_top_tb();
|
||||
|
||||
import blake2_pkg::*;
|
||||
|
||||
logic clk, rst;
|
||||
logic [7:0] digest_byte_len, key_byte_len;
|
||||
logic [128*8-1:0] i_block;
|
||||
|
@ -11,6 +13,8 @@ logic o_rdy;
|
|||
logic o_val;
|
||||
logic o_err;
|
||||
|
||||
if_axi_stream #(.DAT_BYTS(blake2_pkg::NN)) out_hash(clk);
|
||||
|
||||
initial begin
|
||||
rst = 0;
|
||||
#100ns rst = 1;
|
||||
|
@ -35,7 +39,9 @@ blake2_top DUT (
|
|||
.o_digest(o_digest),
|
||||
.o_rdy(o_rdy),
|
||||
.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"
|
||||
|
@ -49,19 +55,18 @@ begin
|
|||
i_val = 1;
|
||||
i_final_block = 1;
|
||||
i_new_block = 1;
|
||||
digest_byte_len = 3;
|
||||
key_byte_len = 0;
|
||||
i_block = 'h636261;
|
||||
|
||||
@(negedge clk);
|
||||
i_val = 0;
|
||||
|
||||
// TODO check rdy goes low
|
||||
while (!out_hash.val) @(posedge clk);
|
||||
|
||||
while (!o_val) @(posedge clk);
|
||||
|
||||
@(posedge clk);
|
||||
@(posedge clk);
|
||||
|
||||
// TODO verify result
|
||||
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);
|
||||
assert (out_hash.eop == 1) else $fatal(0, "%m %t:ERROR, out_hash.sop was not high", $time);
|
||||
|
||||
$display("rfc_test PASSED");
|
||||
end
|
||||
|
@ -70,11 +75,13 @@ endtask
|
|||
// Main testbench calls
|
||||
initial begin
|
||||
key_byte_len = 0;
|
||||
digest_byte_len = 64;
|
||||
digest_byte_len = 3;
|
||||
i_block = '0;
|
||||
i_new_block = '0;
|
||||
i_final_block = '0;
|
||||
i_val = '0;
|
||||
out_hash.rdy = 1;
|
||||
|
||||
|
||||
#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