Skip to content
Snippets Groups Projects
Commit 83b5bd89 authored by dam1n19's avatar dam1n19
Browse files

Created Hashing Stream Module

parent ec5487e9
Branches
No related tags found
No related merge requests found
...@@ -51,11 +51,6 @@ module fifo_vr #( ...@@ -51,11 +51,6 @@ module fifo_vr #(
assign status_ptr_dif = ptr_dif; assign status_ptr_dif = ptr_dif;
logic [PTR_W-1:0] still_read_ptr;
assign still_read_ptr = ((ptr_dif - 1) + {{(PTR_W-1){1'b0}},data_in_shake}) - 1;
logic dinshake_min1;
assign dinshake_min1 = (data_in_shake - 1'b1);
// EXAMPLE: Conditions to write and read from FIFO's // EXAMPLE: Conditions to write and read from FIFO's
// Write Ptr | Read Ptr | Ptr_Dif | Valid Write | Valid Read // Write Ptr | Read Ptr | Ptr_Dif | Valid Write | Valid Read
// 000 - 000 = 000 | Y | N // 000 - 000 = 000 | Y | N
......
//-----------------------------------------------------------------------------
// SoC Labs Basic SHA-256 Hashing Stream
// A joint work commissioned on behalf of SoC Labs, under Arm Academic Access license.
//
// Contributors
//
// David Mapstone (d.a.mapstone@soton.ac.uk)
//
// Copyright 2022, SoC Labs (www.soclabs.org)
//-----------------------------------------------------------------------------
`include "sha256_hash_compression.sv"
`include "sha256_message_build.sv"
`include "sha256_id_issue.sv"
`include "fifo_vr.sv"
module sha256_hashing_stream (
// Clocking Signals
input logic clk,
input logic nrst,
input logic en,
// Synchronous, localised reset
input logic sync_rst,
// Data In data and Handshaking
input logic [511:0] data_in,
input logic data_in_last,
input logic data_in_valid,
output logic data_in_ready,
// Config data and Handshaking
input logic [63:0] cfg_size,
input logic [1:0] cfg_scheme,
input logic cfg_last,
input logic cfg_valid,
output logic cfg_ready,
// Data Out data and Handshaking
output logic [255:0] data_out,
output logic data_out_last,
output logic data_out_valid,
input logic data_out_ready
);
logic [511:0] data_in_buffered;
logic data_in_last_buffered;
logic data_in_valid_buffered;
logic data_in_ready_buffered;
logic [63:0] cfg_size_buffered;
logic [1:0] cfg_scheme_buffered;
logic cfg_last_buffered;
logic cfg_valid_buffered;
logic cfg_ready_buffered;
logic [5:0] id_val;
logic [511:0] message_block;
logic message_block_last;
logic message_block_valid;
logic message_block_ready;
logic [511:0] message_block_buffered;
logic message_block_last_buffered;
logic message_block_valid_buffered;
logic message_block_ready_buffered;
logic [255:0] hash;
logic hash_last;
logic hash_valid;
logic hash_ready;
// Data-in FIFO
fifo_vr #(16, // Depth
512 // Data Width
) data_in_buffer (
.clk (clk),
.nrst (nrst),
.en (en),
.sync_rst (sync_rst),
.data_in (data_in),
.data_in_valid (data_in_valid),
.data_in_ready (data_in_ready),
.data_in_last (data_in_last),
.data_out (data_in_buffered),
.data_out_last (data_in_last_buffered),
.data_out_valid (data_in_valid_buffered),
.data_out_ready (data_in_ready_buffered),
.status_ptr_dif ()
);
// Configuration FIFO
fifo_vr #(8, // Depth
66 // Data Width
) cfg_buffer (
.clk (clk),
.nrst (nrst),
.en (en),
.sync_rst (sync_rst),
.data_in ({cfg_size, cfg_scheme}),
.data_in_valid (cfg_valid),
.data_in_ready (cfg_ready),
.data_in_last (cfg_last),
.data_out ({cfg_size_buffered,cfg_scheme_buffered}),
.data_out_last (cfg_last_buffered),
.data_out_valid (cfg_valid_buffered),
.data_out_ready (cfg_ready_buffered),
.status_ptr_dif ()
);
// Message Build (Construct Message Blocks)
sha256_message_build message_block_builder (
.clk (clk),
.nrst (nrst),
.en (en),
.sync_rst (sync_rst),
.data_in (data_in_buffered),
.data_in_valid (data_in_valid_buffered),
.data_in_ready (data_in_ready_buffered),
.data_in_last (data_in_last_buffered),
.cfg_size (cfg_size_buffered),
.cfg_scheme (cfg_scheme_buffered),
.cfg_last (cfg_last_buffered),
.cfg_valid (cfg_valid_buffered),
.cfg_ready (cfg_ready_buffered),
.cfg_id (),
.data_out (message_block),
.data_out_last (message_block_last),
.data_out_valid (message_block_valid),
.data_out_ready (message_block_ready),
.data_out_id ()
);
// Intermediate FIFO
fifo_vr #(16, // Depth
512 // Data Width
) message_block_buffer (
.clk (clk),
.nrst (nrst),
.en (en),
.sync_rst (sync_rst),
.data_in (message_block),
.data_in_valid (message_block_valid),
.data_in_ready (message_block_ready),
.data_in_last (message_block_last),
.data_out (message_block_buffered),
.data_out_last (message_block_last_buffered),
.data_out_valid (message_block_valid_buffered),
.data_out_ready (message_block_ready_buffered),
.status_ptr_dif ()
);
// Hash Compression (Peform Hash Calculation)
sha256_hash_compression hash_calculator (
.clk (clk),
.nrst (nrst),
.en (en),
.sync_rst (sync_rst),
.data_in (message_block_buffered),
.data_in_valid (message_block_valid_buffered),
.data_in_ready (message_block_ready_buffered),
.data_in_last (message_block_last_buffered),
.data_in_id (),
.data_out (hash),
.data_out_last (hash_last),
.data_out_valid (hash_valid),
.data_out_ready (hash_ready),
.data_out_id ()
);
// Data-out FIFO
fifo_vr #(4, // Depth
256 // Data Width
) data_out_buffer (
.clk (clk),
.nrst (nrst),
.en (en),
.sync_rst (sync_rst),
.data_in (hash),
.data_in_valid (hash_valid),
.data_in_ready (hash_ready),
.data_in_last (hash_last),
.data_out (data_out),
.data_out_last (data_out_last),
.data_out_valid (data_out_valid),
.data_out_ready (data_out_ready),
.status_ptr_dif ()
);
endmodule
\ No newline at end of file
//-----------------------------------------------------------------------------
// SoC Labs Basic SHA-2 Hashing Stream Testbench
// A joint work commissioned on behalf of SoC Labs, under Arm Academic Access license.
//
// Contributors
//
// David Mapstone (d.a.mapstone@soton.ac.uk)
//
// Copyright 2022, SoC Labs (www.soclabs.org)
//-----------------------------------------------------------------------------
`timescale 1ns/1ns
`include "sha256_hashing_stream.sv"
module tb_sha256_hashing_stream;
logic clk;
logic nrst;
logic en;
logic sync_rst;
// Data In data and Handshaking
logic [511:0] data_in;
logic data_in_last;
logic data_in_valid;
logic data_in_ready;
// Config data and Handshaking
logic [63:0] cfg_size;
logic [1:0] cfg_scheme;
logic cfg_last;
logic cfg_valid;
logic cfg_ready;
// Data Out data and Handshaking
logic [255:0] data_out;
logic data_out_valid;
logic data_out_ready;
logic data_out_last;
sha256_hashing_stream uut (
.clk (clk),
.nrst (nrst),
.en (en),
.sync_rst (sync_rst),
.data_in (data_in),
.data_in_valid (data_in_valid),
.data_in_ready (data_in_ready),
.data_in_last (data_in_last),
.cfg_size (cfg_size),
.cfg_scheme (cfg_scheme),
.cfg_last (cfg_last),
.cfg_valid (cfg_valid),
.cfg_ready (cfg_ready),
.data_out (data_out),
.data_out_last (data_out_last),
.data_out_valid (data_out_valid),
.data_out_ready (data_out_ready)
);
logic data_in_drive_en;
logic cfg_drive_en;
logic data_out_drive_ready;
logic [511:0] data_in_queue [$];
logic data_in_last_queue [$];
int data_in_gap_queue [$];
logic data_in_wait_queue;
logic [63:0] cfg_size_queue [$];
logic [1:0] cfg_scheme_queue [$];
logic cfg_last_queue [$];
int cfg_gap_queue [$];
logic cfg_wait_queue;
logic [511:0] message_block_queue [$];
logic message_block_last_queue [$];
logic message_block_wait_queue;
logic [255:0] data_out_queue [$];
logic data_out_last_queue [$];
int data_out_stall_queue [$];
logic data_out_wait_queue;
// Handle Valid and Data for data_in
always_ff @(posedge clk, negedge nrst) begin: data_in_valid_drive
if (!nrst) begin
data_in <= 512'd0;
data_in_valid <= 1'b0;
data_in_last <= 1'b0;
data_in_gap <= 0;
data_in_wait_queue <= 1'b1;
end else if (data_in_drive_en) begin
if (data_in_gap > 1) begin
data_in_gap <= data_in_gap -1;
data_in_valid <= 1'b0;
end else begin
data_in_valid <= 1'b1;
end
if (((data_in_valid == 1'b1) && (data_in_ready == 1'b1)) ||
(data_in_wait_queue == 1'b1)) begin
// Data transfer just completed or transfers already up to date
if ((data_in_queue.size() > 0) && (data_in_last_queue.size() > 0) && (data_in_gap_queue.size() > 0)) begin
data_in <= data_in_queue.pop_front();
data_in_last <= data_in_last_queue.pop_front();
if (data_in_gap_queue[0] == 0) begin
data_in_valid <= 1'b1;
end else begin
data_in_valid <= 1'b0;
end
data_in_gap <= data_in_gap_queue.pop_front();
data_in_wait_queue <= 1'b0;
end else begin
// No data currently avaiable in queue to write but transfers up to date
data_in_wait_queue <= 1'b1;
data_in_valid <= 1'b0;
end
end
end
end
// Handle Valid and Data for cfg
always_ff @(posedge clk, negedge nrst) begin: cfg_valid_drive
if (!nrst) begin
cfg_size <= 64'd0;
cfg_scheme <= 2'd0;
cfg_valid <= 1'b0;
cfg_last <= 1'b0;
cfg_gap <= 0;
cfg_wait_queue <= 1'b1;
end else if (cfg_drive_en) begin
if (cfg_gap > 1) begin
cfg_gap <= cfg_gap -1;
cfg_valid <= 1'b0;
end else begin
cfg_valid <= 1'b1;
end
if (((cfg_valid == 1'b1) && (cfg_ready == 1'b1)) ||
(cfg_wait_queue == 1'b1)) begin
// cfg transfer just completed or transfers already up to date
if ((cfg_size_queue.size() > 0) && (cfg_scheme_queue.size() > 0 ) && (cfg_last_queue.size() > 0) && (cfg_gap_queue.size() > 0)) begin
cfg_size <= cfg_size_queue.pop_front();
cfg_scheme <= cfg_scheme_queue.pop_front();
cfg_last <= cfg_last_queue.pop_front();
if (cfg_gap_queue[0] == 0) begin
cfg_valid <= 1'b1;
end else begin
cfg_valid <= 1'b0;
end
cfg_gap <= cfg_gap_queue.pop_front();
cfg_wait_queue <= 1'b0;
end else begin
// No data currently avaiable in queue to write but transfers up to date
cfg_wait_queue <= 1'b1;
cfg_valid <= 1'b0;
end
end
end
end
logic [511:0] message_block_data_out_check;
logic message_block_data_out_last_check;
int message_block_packet_num;
logic [255:0] data_out_check;
logic data_out_last_check;
int data_in_gap;
int cfg_gap;
int data_out_stall;
int packet_num;
// Handle Output Ready Signal Verification
always @(posedge clk) begin
// Check Override Control on Ready
if (data_out_drive_ready) begin
// Count down to zero before enabling Ready
if (data_out_stall > 1) begin
data_out_stall <= data_out_stall - 1;
data_out_ready <= 1'b0;
end else begin
// Wait for handshake before updating stall value
if ((data_out_valid == 1'b1) && (data_out_ready == 1'b1)) begin
if (data_out_stall_queue.size() > 0) begin
if (data_out_stall_queue[0] == 0) begin
data_out_ready <= 1'b1;
end else begin
data_out_ready <= 1'b0;
end
data_out_stall <= data_out_stall_queue.pop_front();
end
// Keep Ready Asserted until handshake seen
end else begin
data_out_ready <= 1'b1;
end
end
end else begin
data_out_ready <= 1'b0;
end
end
// Handle Output Data Verification
always @(posedge clk) begin
// Check Data In Handshake
if ((data_out_valid == 1'b1) && (data_out_ready == 1'b1)) begin
assert (data_out == data_out_check) else begin
$error("data_out missmatch! packet %d | recieve: %x != check: %x", packet_num, data_out, data_out_check);
$finish;
end
if ($test$plusargs ("DEBUG")) $display("data_out match! packet %d | recieve: %x == check: %x", packet_num, data_out, data_out_check);
assert (data_out_last == data_out_last_check) else begin
$error("data_out_last missmatch! packet %d | recieve: %x != check: %x", packet_num, data_out_last, data_out_last_check);
$finish;
end
if ($test$plusargs ("DEBUG")) $display("data_out_last match! packet %d | recieve: %x == check: %x", packet_num, data_out_last, data_out_last_check);
if ((data_out_queue.size() > 0) && (data_out_last_queue.size() > 0)) begin
data_out_check <= data_out_queue.pop_front();
data_out_last_check <= data_out_last_queue.pop_front();
if (data_out_last_check == 1'b1) begin
packet_num <= packet_num + 1;
end
end else begin
$display("Test Passes");
$finish;
end
end
end
// File Reading Variables
int fd; // File descriptor Handle
logic [511:0] input_data; // Temporary Input Data Storage
logic input_data_last; // Temporary Input Data Last
int input_data_gap; // Temporary Input Gap
logic [63:0] input_cfg_size; // Temporary cfg size
logic [1:0] input_cfg_scheme; // Temporary cfg scheme
logic input_cfg_last; // Temporary cfg last;
int input_cfg_gap; // Temporary cfg gap;
logic [255:0] output_data; // Temporary Output Data Storage
logic [4:0] output_data_id; // Temporary Output Data ID
logic output_data_last; // Temporary Output Data Last
int output_data_stall; // Temporary Output Stall
logic [511:0] message_block_data; // Temporary Message Block Data Storage
logic message_block_data_last; // Temporary Message Block Data Last
int message_block_stall; // Dummy Variable to Read Stall Values into (goes unused other than file parsing)
logic [511:0] message_builder_out_data;
logic message_builder_out_data_last;
initial begin
$dumpfile("sha256_hashing_stream.vcd");
$dumpvars(0, tb_sha256_hashing_stream);
if ($test$plusargs ("DEBUG")) begin
for (int i = 0; i < 16; i++) begin
$dumpvars(0, tb_sha256_hashing_stream.uut.hash_calculator.M[i]);
end
for (int i = 0; i < 8; i++) begin
$dumpvars(0, tb_sha256_hashing_stream.uut.hash_calculator.H[i]);
$dumpvars(0, tb_sha256_hashing_stream.uut.hash_calculator.next_H[i]);
end
for (int i = 0; i < 64; i++) begin
$dumpvars(0, tb_sha256_hashing_stream.uut.hash_calculator.W[i]);
$dumpvars(0, tb_sha256_hashing_stream.uut.hash_calculator.next_W[i]);
$dumpvars(0, tb_sha256_hashing_stream.uut.hash_calculator.ssig1_next_W[i]);
end
end
data_in_drive_en = 0;
cfg_drive_en = 0;
data_out_drive_ready = 0;
// Read input data into Queue
fd = $fopen("../stimulus/unit/input_data_stim.csv", "r");
while ($fscanf (fd, "%x,%b,%d", input_data, input_data_last, input_data_gap) == 3) begin
data_in_queue.push_back(input_data);
data_in_last_queue.push_back(input_data_last);
data_in_gap_queue.push_back(input_data_gap);
end
$fclose(fd);
// Read input cfg into Queue
fd = $fopen("../stimulus/unit/input_cfg_stim.csv", "r");
while ($fscanf (fd, "%x,%x,%b,%d", input_cfg_size, input_cfg_scheme, input_cfg_last, input_cfg_gap) == 4) begin
cfg_size_queue.push_back(input_cfg_size);
cfg_scheme_queue.push_back(input_cfg_scheme);
cfg_last_queue.push_back(input_cfg_last);
cfg_gap_queue.push_back(input_cfg_gap);
end
$fclose(fd);
// Read output data into Queue
fd = $fopen("../stimulus/unit/output_hash_ref.csv", "r");
while ($fscanf (fd, "%x, %d, %b, %d", output_data, output_data_id, output_data_last, output_data_stall) == 4) begin
data_out_queue.push_back(output_data);
data_out_last_queue.push_back(output_data_last);
data_out_stall_queue.push_back(output_data_stall);
end
$fclose(fd);
// Initialise First Checking Values
data_out_check = data_out_queue.pop_front();
data_out_last_check = data_out_last_queue.pop_front();
data_out_stall = data_out_stall_queue.pop_front();
// Enable Hash Compression
en = 1;
// Defaultly set Sync Reset Low
sync_rst = 0;
#20 nrst = 1;
#20 nrst = 0;
#20 nrst = 1;
#20 data_in_drive_en = 1;
// Write some data into the config register
# 30 cfg_drive_en = 1;
# 30 data_out_drive_ready = 1;
end
initial begin
forever begin
#10 clk = 0;
#10 clk = 1;
end
end
endmodule
\ No newline at end of file
...@@ -24,7 +24,7 @@ module tb_sha256_id_issue; ...@@ -24,7 +24,7 @@ module tb_sha256_id_issue;
// Concatenator Handshake // Concatenator Handshake
logic id_out_cfg_valid; logic id_out_cfg_valid;
logic id_out_cfg_ready; logic id_out_cfg_ready;
// ID Buffer Handshake // ID Buffer Handshake
logic id_out_buf_valid; logic id_out_buf_valid;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment