Skip to content
Snippets Groups Projects
Commit bf05b251 authored by David Mapstone's avatar David Mapstone
Browse files

design: ATO2-24: Created Repository for SHA-2 Acclerator, implemented...

design: ATO2-24: Created Repository for SHA-2 Acclerator, implemented simulation flow and added initial design files
parent 27329d3a
No related branches found
No related tags found
No related merge requests found
*.vcd
*.vvp
\ No newline at end of file
{
"workbench.colorCustomizations": {
"activityBar.background": "#00360F",
"titleBar.activeBackground": "#004C16",
"titleBar.activeForeground": "#EDFFF2"
}
}
\ No newline at end of file
# Sample GitLab Project
# SHA-2 Accelerator
This sample project shows how a project in GitLab looks for demonstration purposes. It contains issues, merge requests and Markdown files in many branches,
named and filled with lorem ipsum.
This project is an example accelerator which can be combined with the SoC Labs SoC infrastructure.
You can look around to get an idea how to structure your project and, when done, you can safely delete this project.
## Repository Structure
The respository is currently broken down into 2 main directories:
- hdl
- simulate
[Learn more about creating GitLab projects.](https://docs.gitlab.com/ee/gitlab-basics/create-project.html)
HDL contains all the verilog files. This is seperated into:
- src
- verif
src contains SystemVerilog design files and verif contains the SystemVerilog testbenches and verification resources.
The simulate directory contains the socsim script, along with a directory called "simulators" which contains simulator-specific scripts and a "sim" directory which contains dumps and logs from simulation runs. The files in this directory should not be commited to the Git.
## Setting Up Environment
To be able to simulate in this repository, you will first need to source the sourceme:
```
% source sourceme
```
This will set up the environment variables and will set the simulator used. Defaultly, this is set to ivlog - Icarus Verilog. This can be overloaded from the command line with the following command:
```
% SIMULATOR=yoursimulator
```
Once this is done, a simulation can be ran using the socsim command:
```
% socsim
```
This will generate simulation dumps in the following directory:
```
% $SHA_2_ACC_DIR/simulate/sim
```
\ No newline at end of file
//-----------------------------------------------------------------------------
// 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
//-----------------------------------------------------------------------------
// SoC Labs Basic SHA-2 Engine function and constants SV Package
// 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)
//-----------------------------------------------------------------------------
package sha_2_pkg;
parameter data_width = 32;
// SHA-2 Functions
function logic [data_width-1:0] ssig0 (
logic [data_width-1:0] x);
logic [data_width-1:0] xrotr7, xrotr18, xshr3;
assign xrotr7 = {x[6:0], x[31:7]};
assign xrotr18 = {x[17:0], x[31:18]};
assign xshr3 = x >> 3;
assign ssig0 = xrotr7 ^ xrotr18 ^ xshr3;
endfunction
function logic [data_width-1:0] ssig1 (
logic [data_width-1:0] x);
logic [data_width-1:0] xrotr17, xrotr19, xshr10;
assign xrotr17 = {x[16:0], x[31:17]};
assign xrotr19 = {x[18:0], x[31:19]};
assign xshr10 = x >> 10;
assign ssig1 = xrotr17 ^ xrotr19 ^ xshr10;
endfunction
function logic [data_width-1:0] bsig0 (
logic [data_width-1:0] x);
logic [data_width-1:0] xrotr2, xrotr13, xrotr22;
assign xrotr2 = {x[1:0], x[31:2]};
assign xrotr13 = {x[12:0], x[31:13]};
assign xrotr22 = {x[21:0], x[31:22]};
assign bsig0 = xrotr2 ^ xrotr13 ^ xrotr22;
endfunction
function logic [data_width-1:0] bsig1 (
logic [data_width-1:0] x);
logic [data_width-1:0] xrotr6, xrotr11, xrotr25;
assign xrotr6 = {x[5:0], x[31:6]};
assign xrotr11 = {x[10:0], x[31:11]};
assign xrotr25 = {x[24:0], x[31:25]};
assign bsig1 = xrotr6 ^ xrotr11 ^ xrotr25;
endfunction
function logic [data_width-1:0] ch (
logic [data_width-1:0] x, y, z);
assign ch = (x & y) ^ ((~x) & z);
endfunction
function logic [data_width-1:0] maj (
logic [data_width-1:0] x, y, z);
assign maj = (x & y) ^ (x & z) ^ (y & z);
endfunction
// SHA-2 Constants
const logic [31:0] K0 = 32'h428a2f98;
const logic [31:0] K1 = 32'h71374491;
const logic [31:0] K2 = 32'hb5c0fbcf;
const logic [31:0] K3 = 32'he9b5dba5;
const logic [31:0] K4 = 32'h3956c25b;
const logic [31:0] K5 = 32'h59f111f1;
const logic [31:0] K6 = 32'h923f82a4;
const logic [31:0] K7 = 32'hab1c5ed5;
const logic [31:0] K8 = 32'hd807aa98;
const logic [31:0] K9 = 32'h12835b01;
const logic [31:0] K10 = 32'h243185be;
const logic [31:0] K11 = 32'h550c7dc3;
const logic [31:0] K12 = 32'h72be5d74;
const logic [31:0] K13 = 32'h80deb1fe;
const logic [31:0] K14 = 32'h9bdc06a7;
const logic [31:0] K15 = 32'hc19bf174;
const logic [31:0] K16 = 32'he49b69c1;
const logic [31:0] K17 = 32'hefbe4786;
const logic [31:0] K18 = 32'h0fc19dc6;
const logic [31:0] K19 = 32'h240ca1cc;
const logic [31:0] K20 = 32'h2de92c6f;
const logic [31:0] K21 = 32'h4a7484aa;
const logic [31:0] K22 = 32'h5cb0a9dc;
const logic [31:0] K23 = 32'h76f988da;
const logic [31:0] K24 = 32'h983e5152;
const logic [31:0] K25 = 32'ha831c66d;
const logic [31:0] K26 = 32'hb00327c8;
const logic [31:0] K27 = 32'hbf597fc7;
const logic [31:0] K28 = 32'hc6e00bf3;
const logic [31:0] K29 = 32'hd5a79147;
const logic [31:0] K30 = 32'h06ca6351;
const logic [31:0] K31 = 32'h14292967;
const logic [31:0] K32 = 32'h27b70a85;
const logic [31:0] K33 = 32'h2e1b2138;
const logic [31:0] K34 = 32'h4d2c6dfc;
const logic [31:0] K35 = 32'h53380d13;
const logic [31:0] K36 = 32'h650a7354;
const logic [31:0] K37 = 32'h766a0abb;
const logic [31:0] K38 = 32'h81c2c92e;
const logic [31:0] K39 = 32'h92722c85;
const logic [31:0] K40 = 32'ha2bfe8a1;
const logic [31:0] K41 = 32'ha81a664b;
const logic [31:0] K42 = 32'hc24b8b70;
const logic [31:0] K43 = 32'hc76c51a3;
const logic [31:0] K44 = 32'hd192e819;
const logic [31:0] K45 = 32'hd6990624;
const logic [31:0] K46 = 32'hf40e3585;
const logic [31:0] K47 = 32'h106aa070;
const logic [31:0] K48 = 32'h19a4c116;
const logic [31:0] K49 = 32'h1e376c08;
const logic [31:0] K50 = 32'h2748774c;
const logic [31:0] K51 = 32'h34b0bcb5;
const logic [31:0] K52 = 32'h391c0cb3;
const logic [31:0] K53 = 32'h4ed8aa4a;
const logic [31:0] K54 = 32'h5b9cca4f;
const logic [31:0] K55 = 32'h682e6ff3;
const logic [31:0] K56 = 32'h748f82ee;
const logic [31:0] K57 = 32'h78a5636f;
const logic [31:0] K58 = 32'h84c87814;
const logic [31:0] K59 = 32'h8cc70208;
const logic [31:0] K60 = 32'h90befffa;
const logic [31:0] K61 = 32'ha4506ceb;
const logic [31:0] K62 = 32'hbef9a3f7;
const logic [31:0] K63 = 32'hc67178f2;
// H_init Constants
const logic [31:0] H0_init = 32'h6a09e667;
const logic [31:0] H1_init = 32'hbb67ae85;
const logic [31:0] H2_init = 32'h3c6ef372;
const logic [31:0] H3_init = 32'ha54ff53a;
const logic [31:0] H4_init = 32'h510e527f;
const logic [31:0] H5_init = 32'h9b05688c;
const logic [31:0] H6_init = 32'h1f83d9ab;
const logic [31:0] H7_init = 32'h5be0cd19;
endpackage
\ No newline at end of file
//-----------------------------------------------------------------------------
// SoC Labs Basic SHA-2 Engine 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 "sha_2_engine.sv"
module tb_engine;
logic clk;
logic nrst;
// Data In data and Handshaking
logic [511:0] data_in;
logic data_in_valid;
logic data_in_ready;
// Config data and Handshaking
logic [63:0] cfg_size;
logic [1:0] cfg_scheme;
logic cfg_valid;
logic cfg_ready;
// Data Out data and Handshaking
logic [511:0] data_out;
logic data_out_valid;
logic data_out_ready;
sha_2_engine uut (
.clk (clk),
.nrst(nrst),
.data_in(data_in),
.data_in_valid(data_in_valid),
.data_in_ready(data_in_ready),
.cfg_size(cfg_size),
.cfg_scheme(cfg_scheme),
.cfg_valid(cfg_valid),
.cfg_ready(cfg_ready),
.data_out(data_out),
.data_out_valid(data_out_valid),
.data_out_ready(data_out_ready));
logic data_in_drive_en;
logic [511:0] data_in_queue [$];
logic data_in_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_wait_queue <= 1'b1;
end else if (data_in_drive_en) begin
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) begin
data_in <= data_in_queue.pop_front();
data_in_valid <= 1'b1;
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
logic [511:0] temp_data ;
initial begin
$dumpfile("engine_sim.vcd");
$dumpvars(0, tb_engine);
for (int idx = 0; idx < 4; idx = idx + 1) begin
$dumpvars(0, uut.data_in_fifo[idx]);
$dumpvars(0, uut.cfg_size_fifo[idx]);
$dumpvars(0, uut.cfg_scheme_fifo[idx]);
end
data_in_drive_en = 0;
for (int idx_1 = 0; idx_1 < 20; idx_1 = idx_1 + 1) begin
for (int idx = 1; idx < 5; idx = idx + 1) begin
data_in_queue.push_back({$urandom(),$urandom(),$urandom(),$urandom(),$urandom(),$urandom(),
$urandom(),$urandom(),$urandom(),$urandom(),$urandom(),$urandom(),
$urandom(),$urandom(),$urandom(),$urandom()});
end
end
cfg_size = 0;
cfg_scheme = 0;
cfg_valid = 0;
data_out_ready = 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_size = 512;
cfg_scheme = 2;
cfg_valid = 1;
#1200
$display("Test Complete");
$finish;
end
initial begin
forever begin
#10 clk = 0;
#10 clk = 1;
end
end
endmodule
\ No newline at end of file
#-----------------------------------------------------------------------------
# SoC Labs icarus verilog simulation script for engine 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)
#-----------------------------------------------------------------------------
#!/usr/bin/env bash
mkdir -p $SHA_2_ACC_DIR/simulate/sim/
iverilog -I $SHA_2_ACC_DIR/hdl/verif/ -I $SHA_2_ACC_DIR/hdl/src/ -g2012 -o $SHA_2_ACC_DIR/simulate/sim/engine_sim.vvp $SHA_2_ACC_DIR/hdl/verif/tb_engine.sv
cd $SHA_2_ACC_DIR/simulate/sim/ && vvp engine_sim.vvp
\ No newline at end of file
#-----------------------------------------------------------------------------
# SoC Labs socsim script to run required simulation
# 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)
#-----------------------------------------------------------------------------
#!/usr/bin/env bash
DEFAULT_SIMULATOR="ivlog"
if [[ -z "${SIMULATOR}" ]]; then
SIMULATOR=$DEFAULT_SIMULATOR
fi
$SHA_2_ACC_DIR"/simulate/simulators/"$SIMULATOR"_sim.sh"
sourceme 0 → 100755
#-----------------------------------------------------------------------------
# SoC Labs Environment Setup Script
# 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)
#-----------------------------------------------------------------------------
#!/usr/bin/env bash
# Set environment Variables for Repository
export SHA_2_ACC_DIR="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"
# Add simulation directory to Path
export PATH=$PATH:$SHA_2_ACC_DIR/simulate
# Set Default Simulator
export SIMULATOR="ivlog"
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment