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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
//-----------------------------------------------------------------------------
// SoC Labs Basic SHA-2 ID Buffer 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_id_buf.sv"
module tb_sha256_id_buf;
logic clk;
logic nrst;
logic en;
logic sync_rst;
// ID Buffer IN
logic [5:0] id_in;
logic id_in_last;
logic id_in_valid;
logic id_in_ready;
// ID Out
logic [5:0] id_out;
logic id_out_last;
logic id_out_valid;
logic id_out_ready;
// Status Out - Gets updated after every hash
logic [5:0] status_id;
sha256_id_buf uut (
.clk (clk),
.nrst (nrst),
.en (en),
.sync_rst (sync_rst),
// ID IN
.id_in (id_in),
.id_in_last (id_in_last),
.id_in_valid (id_in_valid),
.id_in_ready (id_in_ready),
// ID Out
.id_out (id_out),
.id_out_last (id_out_last),
.id_out_valid (id_out_valid),
.id_out_ready (id_out_ready),
// Status Out - Gets updated on every output Handshake
.status_id (status_id)
);
logic id_in_drive_en;
logic id_out_drive_ready;
logic [5:0] id_in_queue [$];
logic id_in_last_queue [$];
int id_in_gap_queue [$];
logic id_in_wait_queue;
logic [5:0] id_out_queue [$];
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
logic id_out_last_queue [$];
int id_out_stall_queue [$];
logic id_out_wait_queue;
// TODO: Handle Status Checking
// Handle Valid and Data for id_in
always_ff @(posedge clk, negedge nrst) begin: id_in_valid_drive
if (!nrst) begin
id_in <= 6'd0;
id_in_valid <= 1'b0;
id_in_last <= 1'b0;
id_in_gap <= 0;
id_in_wait_queue <= 1'b1;
end else if (id_in_drive_en) begin
if (id_in_gap > 1) begin
id_in_gap <= id_in_gap - 1;
id_in_valid <= 1'b0;
end else begin
id_in_valid <= 1'b1;
end
if (((id_in_valid == 1'b1) && (id_in_ready == 1'b1)) ||
(id_in_wait_queue == 1'b1)) begin
// Data transfer just completed or transfers already up to date
if ((id_in_queue.size() > 0) && (id_in_last_queue.size() > 0) && (id_in_gap_queue.size() > 0)) begin
id_in <= id_in_queue.pop_front();
id_in_last <= id_in_last_queue.pop_front();
if (id_in_gap_queue[0] == 0) begin
id_in_valid <= 1'b1;
end else begin
id_in_valid <= 1'b0;
end
id_in_gap <= id_in_gap_queue.pop_front();
id_in_wait_queue <= 1'b0;
end else begin
// No data currently avaiable in queue to write but transfers up to date
id_in_wait_queue <= 1'b1;
id_in_valid <= 1'b0;
end
end
end
end
logic [5:0] id_out_check;
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
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
160
161
162
163
164
165
166
167
168
logic id_out_last_check;
int id_in_gap;
int id_out_stall;
int packet_num;
// Handle Output Ready Signal Verification
always @(posedge clk) begin
// Check Override Control on Ready
if (id_out_drive_ready) begin
// Count down to zero before enabling Ready
if (id_out_stall > 1) begin
id_out_stall <= id_out_stall - 1;
id_out_ready <= 1'b0;
end else begin
// Wait for handshake before updating stall value
if ((id_out_valid == 1'b1) && (id_out_ready == 1'b1)) begin
if (id_out_stall_queue.size() > 0) begin
if (id_out_stall_queue[0] == 0) begin
id_out_ready <= 1'b1;
end else begin
id_out_ready <= 1'b0;
end
id_out_stall <= id_out_stall_queue.pop_front();
end
// Keep Ready Asserted until handshake seen
end else begin
id_out_ready <= 1'b1;
end
end
end else begin
id_out_ready <= 1'b0;
end
end
// Handle Output Data Verification
always @(posedge clk) begin
// Check Data on Handshake
if ((id_out_valid == 1'b1) && (id_out_ready == 1'b1)) begin
// Check Size
assert (id_out == id_out_check) else begin
$error("id_out missmatch! packet %d | recieve: %x != check: %x", packet_num, id_out, id_out_check);
$finish;
end
if ($test$plusargs ("DEBUG")) $display("id_out match! packet %d | recieve: %x == check: %x", packet_num, id_out, id_out_check);
// Check Last Flag
assert (id_out_last == id_out_last_check) else begin
$error("id_out_last missmatch! packet %d | recieve: %x != check: %x", packet_num, id_out_last, id_out_last_check);
$finish;
end
if ($test$plusargs ("DEBUG")) $display("id_out_last match! packet %d | recieve: %x == check: %x", packet_num, id_out_last, id_out_last_check);
// Check Status Value
assert (status_id == status_id_out_check) else begin
$error("id_out_last missmatch! packet %d | recieve: %x != check: %x", packet_num, status_id, status_id_out_check);
$finish;
end
if ($test$plusargs ("DEBUG")) $display("status_id match! packet %d | recieve: %x == check: %x", packet_num, status_id, status_id_out_check);
if ((id_out_queue.size() > 0) && (status_id_out_queue.size() > 0) && (id_out_last_queue.size() > 0)) begin
id_out_check <= id_out_queue.pop_front();
status_id_out_check <= status_id_out_queue.pop_front();
id_out_last_check <= id_out_last_queue.pop_front();
if (id_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 [5:0] temp_id_in; // Temporary Input Data Storage
logic temp_id_in_last; // Temporary Input Data Last
int temp_id_in_gap; // Temporary Input Gap
logic [5:0] temp_id_out; // Temporary ID Value
logic [5:0] temp_status_id_out; // Temporary Status ID Value
logic temp_id_out_last; // Temporary ID last;
int temp_id_out_stall; // Temporary ID stall;
initial begin
$dumpfile("sha256_id_buf.vcd");
$dumpvars(0, tb_sha256_id_buf);
id_in_drive_en = 0;
id_out_drive_ready = 0;
// Read input data into Queue in
fd = $fopen("../stimulus/testbench/input_buf_id_stim.csv", "r");
while ($fscanf (fd, "%d,%b,%d", temp_id_in, temp_id_in_last, temp_id_in_gap) == 3) begin
id_in_queue.push_back(temp_id_in);
id_in_last_queue.push_back(temp_id_in_last);
id_in_gap_queue.push_back(temp_id_in_gap);
end
$fclose(fd);
// Read output data into Queue
fd = $fopen("../stimulus/testbench/output_buf_id_ref.csv", "r");
while ($fscanf (fd, "%d,%b,%d,%d", temp_id_out, temp_id_out_last, temp_status_id_out, temp_id_out_stall) == 4) begin
id_out_queue.push_back(temp_id_out);
id_out_last_queue.push_back(temp_id_out_last);
status_id_out_queue.push_back(temp_status_id_out);
id_out_stall_queue.push_back(temp_id_out_stall);
end
$fclose(fd);
// Initialise First Checking Values
id_out_check = id_out_queue.pop_front();
status_id_out_check = status_id_out_queue.pop_front();
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
id_out_last_check = id_out_last_queue.pop_front();
id_out_stall = id_out_stall_queue.pop_front();
// Defaultly enable Message Builder
en = 1;
// Defaultly set Sync Reset Low
sync_rst = 0;
#20 nrst = 1;
#20 nrst = 0;
#20 nrst = 1;
// Write some data into the config register
# 30 id_in_drive_en = 1;
# 30 id_out_drive_ready = 1;
end
initial begin
forever begin
#10 clk = 0;
#10 clk = 1;
end
end
endmodule