diff --git a/hdl/src/primatives/vr_fifo.sv b/hdl/src/primatives/fifo_vr.sv similarity index 99% rename from hdl/src/primatives/vr_fifo.sv rename to hdl/src/primatives/fifo_vr.sv index 87b4a11895a93f5aa0ab294bcae398b6e7a19302..81910e4b5c513da1575ab98f1d4d330cfeaeca89 100644 --- a/hdl/src/primatives/vr_fifo.sv +++ b/hdl/src/primatives/fifo_vr.sv @@ -8,7 +8,7 @@ // // Copyright 2022, SoC Labs (www.soclabs.org) //----------------------------------------------------------------------------- -module vr_fifo #( +module fifo_vr #( parameter DEPTH = 4, // FIFO Row Depth parameter DATA_W = 32, // FIFO Row Width parameter PTR_W = $clog2(DEPTH) + 1 // Read/Write Pointer Width diff --git a/hdl/src/sha256_engine.sv b/hdl/src/sha256_engine.sv new file mode 100644 index 0000000000000000000000000000000000000000..ec2e079ecc6375548f803940c454848d49ca0dd4 --- /dev/null +++ b/hdl/src/sha256_engine.sv @@ -0,0 +1,151 @@ +//----------------------------------------------------------------------------- +// SoC Labs Basic SHA-256 Engine Top-level +// 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) +//----------------------------------------------------------------------------- + +module sha256_engine ( + // 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 [511:0] message_block; + logic message_block_last; + logic message_block_valid; + logic message_block_ready; + + logic [255:0] hash; + logic hash_last; + logic hash_valid; + logic hash_ready; + + // Data-in FIFO + fifo_vr #( DEPTH = 16, + DATA_W = 512 + ) data_in_buffer ( + .clk (clk), + .nrst (nrst), + .en (en), + .sync_rst (sync_rst), + .in (data_in), + .in_valid (data_in_valid), + .in_ready (data_in_ready), + .in_last (data_in_last), + .out (data_in_buffered), + .out_last (data_in_last_buffered;), + .out_valid (data_in_valid_buffered), + .out_ready (data_in_ready_buffered) + ); + + // Configuration FIFO + fifo_vr #( DEPTH = 8, // Should be recieving less configuration words than data words + DATA_W = 66 + ) cfg_buffer ( + .clk (clk), + .nrst (nrst), + .en (en), + .sync_rst (sync_rst), + .in ({cfg_size, cfg_scheme}), + .in_valid (cfg_in_valid), + .in_ready (cfg_in_ready), + .in_last (cfg_in_last), + .out ({cfg_size_buffered,cfg_scheme_buffered}), + .out_last (cfg_last_buffered;), + .out_valid (cfg_valid_buffered), + .out_ready (cfg_ready_buffered) + ); + + // Message Build (Construct Message Blocks) + message_build message_block_builder ( + .clk (clk), + .nrst (nrst), + .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), + .data_out (message_block), + .data_out_last (message_block_last), + .data_out_valid (message_block_valid), + .data_out_ready (message_block_ready) + ); + + // Hash Compression (Peform Hash Calculation) + hash_compression hash_calculator ( + .clk (clk), + .nrst (nrst), + .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 (hash), + .data_out_last (hash_last), + .data_out_valid (hash_valid), + .data_out_ready (hash_ready) + ); + + // Data-out FIFO + fifo_vr #( DEPTH = 4, + DATA_W = 256 + ) data_out_buffer ( + .clk (clk), + .nrst (nrst), + .en (en), + .sync_rst (sync_rst), + .in (hash), + .in_valid (hash_valid), + .in_ready (hash_ready), + .in_last (hash_last), + .out (data_out), + .out_last (data_out_last), + .out_valid (data_out_valid), + .out_ready (data_out_ready) + ); + +endmodule \ No newline at end of file diff --git a/hdl/src/sha_2_engine.sv b/hdl/src/sha_2_engine.sv deleted file mode 100644 index 5820d35bab3fa32a2b420187dbc1e335240c9ab3..0000000000000000000000000000000000000000 --- a/hdl/src/sha_2_engine.sv +++ /dev/null @@ -1,214 +0,0 @@ -//----------------------------------------------------------------------------- -// SoC Labs Basic SHA-2 Engine Top-level -// 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) -//----------------------------------------------------------------------------- - -module sha_2_engine ( - // Clocking Signals - input logic clk, - input logic nrst, - - // Data In data and Handshaking - input logic [511:0] data_in, - 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_valid, - output logic cfg_ready, - - // Data Out data and Handshaking - output logic [511:0] data_out, - output logic data_out_valid, - input logic data_out_ready -); - - // Stage 1: Input Data Registering - - // Data In FIFO Signals - logic [511:0] data_in_fifo [3:0]; - logic [2:0] data_in_fifo_write_ptr; - logic [2:0] data_in_fifo_read_ptr; - logic [2:0] data_in_fifo_ptr_dif; - wire [1:0] data_in_fifo_write_ptr_val, data_in_fifo_read_ptr_val; - - // Data In FIFO Pointer Derived Signal Assignments - assign data_in_fifo_ptr_dif = data_in_fifo_write_ptr - data_in_fifo_read_ptr; - assign data_in_fifo_write_ptr_val = data_in_fifo_write_ptr [1:0]; - assign data_in_fifo_read_ptr_val = data_in_fifo_read_ptr [1:0]; - - // Config FIFO Signals - logic [63:0] cfg_size_fifo [3:0]; - logic [1:0] cfg_scheme_fifo [3:0]; - logic [2:0] cfg_fifo_write_ptr; - logic [2:0] cfg_fifo_read_ptr; - logic [2:0] cfg_fifo_ptr_dif; - logic [1:0] cfg_fifo_write_ptr_val, cfg_fifo_read_ptr_val; - - // Config FIFO Pointer Derived Signal Assignments - assign cfg_fifo_ptr_dif = cfg_fifo_write_ptr - cfg_fifo_read_ptr; - assign cfg_fifo_write_ptr_val = cfg_fifo_write_ptr [1:0]; - assign cfg_fifo_read_ptr_val = cfg_fifo_read_ptr [1:0]; - - // Conditions to write and read from FIFO's - // Write Ptr | Read Ptr | Result | Valid Write | Valid Read - // 000 - 000 = 000 | Y | N - // 001 - 000 = 001 | Y | Y - // 010 - 000 = 010 | Y | Y - // 011 - 000 = 011 | Y | Y - // 100 - 000 = 100 | N | Y - // 101 - 000 = 101 | N | N - // 110 - 000 = 110 | N | N - // 111 - 000 = 111 | N | N - // WriteValid: WritePtr - ReadPtr < 3'd4 - // ReadValid: WritePtr - ReadPtr - 1 < 3'd4 - - always_ff @(posedge clk, negedge nrst) begin: data_in_registering - if (!nrst) begin - data_in_fifo_write_ptr <= 3'b0; - data_in_ready <= 1'b1; - end else if (data_in_fifo_ptr_dif < 3'd4) begin // Space in FIFO - if ((data_in_valid == 1'b1) && (data_in_ready == 1'b1)) begin // Successful Handshake - data_in_fifo [data_in_fifo_write_ptr[1:0]] <= data_in; - data_in_fifo_write_ptr <= data_in_fifo_write_ptr + 3'b1; - if (data_in_fifo_ptr_dif + 3'b1 >= 3'd4) begin // FIFO full with new data written - data_in_ready <= 1'b0; - end else begin // Still space in FIFO after latest write - data_in_ready <= 1'b1; - end - end else begin // Unsuccessful handshake but space in FIFO - data_in_ready <= 1'b1; - end - end else begin // FIFO Full - data_in_ready <= 1'b0; - end - end - - always_ff @(posedge clk, negedge nrst) begin: cfg_registering - if (!nrst) begin - cfg_fifo_write_ptr <= 3'b0; - cfg_ready <= 1'b1; - end else if (cfg_fifo_ptr_dif < 3'd4) begin // Space in FIFO - if ((cfg_valid == 1'b1) && (cfg_ready == 1'b1)) begin // Successful Handshake - cfg_size_fifo [cfg_fifo_write_ptr[1:0]] <= cfg_size; - cfg_scheme_fifo [cfg_fifo_write_ptr[1:0]] <= cfg_scheme; - cfg_fifo_write_ptr <= cfg_fifo_write_ptr + 3'b1; - if (cfg_fifo_ptr_dif + 3'b1 >= 3'd4) begin // FIFO full with new data written - cfg_ready <= 1'b0; - end else begin // Still space in FIFO after latest write - cfg_ready <= 1'b1; - end - end else begin // Unsuccessful handshake but space in FIFO - cfg_ready <= 1'b1; - end - end else begin // FIFO Full - cfg_ready <= 1'b0; - end - end - - // Stage 2: Functional Logic - - // SHA-2 State Machine - logic [1:0] state; - logic [53:0] data_word_count; - logic cfg_word_avail; - logic data_in_word_avail; - - assign cfg_word_avail = ((cfg_fifo_ptr_dif - 3'b1) < 3'd4); // Is there a Config word in the FIFO to read? - assign data_in_word_avail = ((data_in_fifo_ptr_dif - 3'b1) < 3'd4); // Is there a Data In word in the FIFO to read? - - logic [63:0] size_read, size_read_reg; - logic [8:0] size_word_rem, size_word_rem_reg; - logic [53:0] words_to_read, words_to_read_reg; // Number of 512 bit words to read in - logic round_up; - logic extra_word_needed; - logic [511:0] extra_word, extra_word_reg; - - assign size_read = cfg_size_fifo[cfg_fifo_read_ptr_val]; // Extract Size from FIFO - assign size_word_rem = size_read[8:0]; // Remainder of 512 Word Division - assign round_up = |size_word_rem; // Is there a remainder after a 512 division? - assign words_to_read = (size_read >> 9) + round_up; // Total Number of 512 bit words to Read in - assign extra_word_needed = (size_word_rem - 1) > 446; // Extra word needed as not enough space in last word size - - // If extra word needed, extra word is sets the value of the extra word to the value of size and determines - // if message end 1 needs to be put at the beginning of word or not - // If not needed, set to 0 as invalid word (as size can't be 0) - can be detected later - assign extra_word = extra_word_needed ? {~round_up, 447'd0, size_read} : 512'd0; - - logic [511:0] working_data; - logic [511:0] data_in_word_read; - - assign data_in_word_read = data_in_fifo[data_in_fifo_read_ptr_val]; // Extract Data In Word from FIFO - - logic [511:0] last_word_mask; - logic [511:0] end_marker; - logic [511:0] last_data_word; - - assign last_word_mask = |size_word_rem_reg ? ((512'd1 << 512) - 1) << (512 - size_word_rem_reg) : ((512'd1 << 512) - 1); // Create mask to get data from last word - assign end_marker = 1 << (512 - size_word_rem_reg - 1); // "1" to signify end of message - // Combine Last Data with end marker and size - assign last_data_word = (data_in_word_read & last_word_mask) | (|size_word_rem_reg ? end_marker : 512'd0) | (~|extra_word_reg ? size_read_reg : 512'd0); - - always_ff @(posedge clk, negedge nrst) begin: sha_2_next_state - if (!nrst) begin - state <= 2'd0; - data_in_fifo_read_ptr <= 3'b0; - cfg_fifo_read_ptr <= 3'b0; - words_to_read_reg <= 54'd0; - extra_word_reg <= 512'd0; - working_data <= 512'd0; - data_word_count <= 54'd0; - size_read_reg <= 64'd0; - size_word_rem_reg <= 9'd0; - end else begin - case(state) - 2'd0: begin // Initial Config Read - if (cfg_word_avail == 1'b1) begin - size_read_reg <= size_read; - size_word_rem_reg <= size_word_rem; - words_to_read_reg <= words_to_read; - extra_word_reg <= extra_word; - data_word_count <= 54'd0; - cfg_fifo_read_ptr <= cfg_fifo_read_ptr + 3'b1; - state <= state + 2'b1; - end - end - 2'd1: begin // Data Processing Step - if (data_in_word_avail == 1'b1) begin - data_in_fifo_read_ptr <= data_in_fifo_read_ptr + 3'b1; - data_word_count <= data_word_count + 54'd1; - if (data_word_count < (words_to_read_reg - 1)) begin // Not the last word to read - working_data <= data_in_word_read; - end else begin // Last Data In Word to Process - working_data <= last_data_word; - if (|extra_word_reg == 1'b1) begin - state <= state + 2'd1; - end else begin - state <= state + 2'd2; - end - end - end - end - 2'd2: begin // Process Extra Word If Needed - working_data <= extra_word_reg; - state <= state + 2'd1; - end - 2'd3: begin // Write Out Result to Output - state <= 2'd0; - end - default: begin - state <= 2'd0; - end - endcase - end - end - -endmodule \ No newline at end of file diff --git a/hdl/verif/tb_hash_compression.sv b/hdl/verif/tb_hash_compression.sv index 62bcc099cb36b6dbbb233251353bac3746a6d2ae..c89a9ea37591b5d9c8dc05a1bb2467ee7870c7a0 100644 --- a/hdl/verif/tb_hash_compression.sv +++ b/hdl/verif/tb_hash_compression.sv @@ -15,6 +15,7 @@ module tb_hash_compression; logic clk; logic nrst; + logic sync_rst; // Data In data and Handshaking logic [511:0] data_in; logic data_in_last; @@ -37,6 +38,7 @@ module tb_hash_compression; hash_compression uut ( .clk (clk), .nrst(nrst), + .sync_rst(sync_rst), .data_in(data_in), .data_in_valid(data_in_valid), .data_in_ready(data_in_ready), @@ -187,6 +189,9 @@ module tb_hash_compression; data_out_check = data_out_queue.pop_front(); data_out_last_check = data_out_last_queue.pop_front(); + // Defaultly set Sync Reset Low + sync_rst = 0; + #20 nrst = 1; #20 nrst = 0; #20 nrst = 1; diff --git a/hdl/verif/tb_message_build.sv b/hdl/verif/tb_message_build.sv index 0ec9b7c20eadc1cdc042d2563b5d176ab6328532..e7615509224a77eed914dd61dd1dac305ae8f504 100644 --- a/hdl/verif/tb_message_build.sv +++ b/hdl/verif/tb_message_build.sv @@ -15,6 +15,7 @@ module tb_message_build; logic clk; logic nrst; + logic sync_rst; // Data In data and Handshaking logic [511:0] data_in; logic data_in_last; @@ -37,6 +38,7 @@ module tb_message_build; message_build uut ( .clk (clk), .nrst(nrst), + .sync_rst(sync_rst), .data_in(data_in), .data_in_valid(data_in_valid), .data_in_ready(data_in_ready), @@ -218,6 +220,9 @@ module tb_message_build; data_out_check = data_out_queue.pop_front(); data_out_last_check = data_out_last_queue.pop_front(); + // Defaultly set Sync Reset Low + sync_rst = 0; + #20 nrst = 1; #20 nrst = 0; #20 nrst = 1;