Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
//-----------------------------------------------------------------------------
// SoC Labs Basic SHA-256 Configuration Synchroniser
// A joint work commissioned on behalf of SoC Labs, under Arm Academic Access license.
//
// Contributors
//
// David Mapstone (d.a.mapstone@soton.ac.uk)
//
// Copyright 2023, SoC Labs (www.soclabs.org)
//-----------------------------------------------------------------------------
module sha256_config_sync (
input logic clk,
input logic nrst,
input logic en,
// Synchronous, localised reset
input logic sync_rst,
// ID In and Handshaking
input logic [5:0] id_in,
input logic id_in_last,
input logic id_in_valid,
output logic id_in_ready,
// Config data and Handshaking
input logic [63:0] cfg_in_size,
input logic [1:0] cfg_in_scheme,
input logic cfg_in_last,
input logic cfg_in_valid,
output logic cfg_in_ready,
// Data Out data and Handshaking
output logic [63:0] cfg_out_size,
output logic [1:0] cfg_out_scheme,
output logic [5:0] cfg_out_id,
output logic cfg_out_last,
output logic cfg_out_valid,
input logic cfg_out_ready,
// Status Out - Gets updated after every hash
// - outputs size and then clears size to 0
// - status regs are looking for non-zero size
output logic [63:0] status_size,
input logic status_clear
);
logic [1:0] state, next_state;
logic next_cfg_in_ready;
logic next_id_in_ready;
logic [63:0] next_cfg_out_size;
logic [1:0] next_cfg_out_scheme;
logic [5:0] next_cfg_out_id;
logic next_cfg_out_last;
logic next_cfg_out_valid;
logic [63:0] next_status_size;
// State Machine Sequential Logic
always_ff @(posedge clk, negedge nrst) begin
if ((!nrst) | sync_rst) begin
state <= 2'd0;
cfg_out_size <= 64'd0;
cfg_out_scheme <= 2'd0;
cfg_out_id <= 6'd0;
cfg_out_last <= 1'b0;
cfg_out_valid <= 1'b0;
cfg_in_ready <= 1'b0;
id_in_ready <= 1'b0;
status_size <= 64'd0;
end else if (en == 1'b1) begin
state <= next_state;
cfg_out_size <= next_cfg_out_size;
cfg_out_scheme <= next_cfg_out_scheme;
cfg_out_id <= next_cfg_out_id;
cfg_out_last <= next_cfg_out_last;
cfg_out_valid <= next_cfg_out_valid;
cfg_in_ready <= next_cfg_in_ready;
id_in_ready <= next_id_in_ready;
status_size <= next_status_size;
end else begin
cfg_out_valid <= 1'b0;
cfg_in_ready <= 1'b0;
id_in_ready <= 1'b0;
status_size <= 64'd0;
end
end
always_comb begin
// Default
next_state = state;
next_cfg_out_size = cfg_out_size;
next_cfg_out_scheme = cfg_out_scheme;
next_cfg_out_id = cfg_out_id;
next_cfg_out_last = cfg_out_last;
next_cfg_out_valid = cfg_out_valid;
next_cfg_in_ready = cfg_in_ready;
next_id_in_ready = id_in_ready;
next_status_size = status_size;
// Override
case (state)
2'd0: begin
next_cfg_in_ready = 1'b1;
next_id_in_ready = 1'b1;
next_state = 2'd1;
end
2'd1: begin
// Handle Status Signals
if (status_clear) begin
next_status_size = 64'd0;
end
// Check outputs can be written to
if (cfg_out_valid && !cfg_out_ready) begin
// If data out is valid and ready is low, there is already data waiting to be transferred
next_cfg_in_ready = 1'b0;
next_id_in_ready = 1'b0;
// If there is no Valid data at the output or there is a valid transfer happening on this clock cycle
end else begin
// These can be overloaded later if data is written to the outputs
next_cfg_out_valid = 1'b0;
next_cfg_in_ready = 1'b1;
next_id_in_ready = 1'b1;
next_cfg_out_last = 1'b0;
// Check cfg input
if (cfg_in_ready && cfg_in_valid) begin
next_cfg_out_last = cfg_in_last;
next_cfg_out_scheme = cfg_in_scheme;
next_cfg_out_size = cfg_in_size;
next_status_size = cfg_in_size;
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
next_cfg_in_ready = 1'b0;
next_state = 2'd2;
end
// Check Id input
if (id_in_ready && id_in_valid) begin
next_cfg_out_id = id_in;
next_id_in_ready = 1'b0;
next_state = 2'd3;
end
// Check if both inputs handshaked
if ((id_in_ready && id_in_valid) && (cfg_in_ready && cfg_in_valid)) begin
next_cfg_out_valid = 1'b1;
if (!cfg_out_valid && cfg_out_ready) begin
// In case where no valid data and ready is waiting for valid data
// - (will be asserted next cc), guaranteed handshake next cycle
next_cfg_in_ready = 1'b1;
next_cfg_in_ready = 1'b1;
end else begin
next_cfg_in_ready = 1'b0;
next_id_in_ready = 1'b0;
end
next_state = 2'd1;
end
end
end
2'd2: begin // Cfg already handshaked - wait for ID handshake
// Handle Status Signals
if (status_clear) begin
next_status_size = 64'd0;
end
// These can be overloaded later if data is written to the outputs
next_cfg_out_valid = 1'b0;
next_cfg_in_ready = 1'b0;
next_id_in_ready = 1'b1;
// Check Id input
if (id_in_ready && id_in_valid) begin
next_cfg_out_id = id_in;
next_cfg_out_valid = 1'b1;
if (cfg_out_ready) begin // Guaranteeded Handshake next clock cycle
next_cfg_in_ready = 1'b1;
next_id_in_ready = 1'b1;
end else begin
next_cfg_in_ready = 1'b0;
next_id_in_ready = 1'b0;
end
next_state = 2'd1;
end
end
2'd3: begin // ID already handshaked - wait for config handshake
// Handle Status Signals
if (status_clear) begin
next_status_size = 64'd0;
end
// These can be overloaded later if data is written to the outputs
next_cfg_out_valid = 1'b0;
next_cfg_in_ready = 1'b1;
next_id_in_ready = 1'b0;
// Check config input
if (cfg_in_ready && cfg_in_valid) begin
next_cfg_out_last = cfg_in_last;
next_cfg_out_scheme = cfg_in_scheme;
next_cfg_out_size = cfg_in_size;
next_cfg_out_valid = 1'b1;
next_status_size = cfg_in_size;
if (cfg_out_ready) begin // Guaranteeded Handshake next clock cycle
next_cfg_in_ready = 1'b1;
next_id_in_ready = 1'b1;
end else begin
next_cfg_in_ready = 1'b0;
next_id_in_ready = 1'b0;
end
next_state = 2'd1;
end
end
endcase
end
endmodule