URL
https://opencores.org/ocsvn/sha3/sha3/trunk
Subversion Repositories sha3
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 5 to Rev 6
- ↔ Reverse comparison
Rev 5 → Rev 6
/sha3/trunk/high_speed_core/testbench/test_padder.v
File deleted
/sha3/trunk/high_speed_core/testbench/test_padder1.v
File deleted
/sha3/trunk/high_speed_core/testbench/test_keccak.v
File deleted
/sha3/trunk/high_speed_core/testbench/simulation.do
File deleted
/sha3/trunk/high_speed_core/testbench/Read_Me.txt
File deleted
/sha3/trunk/high_speed_core/rtl/padder.v
File deleted
/sha3/trunk/high_speed_core/rtl/padder1.v
File deleted
/sha3/trunk/high_speed_core/rtl/keccak.v
File deleted
/sha3/trunk/high_speed_core/rtl/round2in1.v
File deleted
/sha3/trunk/high_speed_core/rtl/rconst2in1.v
File deleted
/sha3/trunk/high_speed_core/rtl/f_permutation.v
File deleted
/sha3/trunk/high_throughput_core/testbench/test_f_permutation.v
0,0 → 1,132
/* |
* Copyright 2013, Homer Hsing <homer.hsing@gmail.com> |
* |
* Licensed under the Apache License, Version 2.0 (the "License"); |
* you may not use this file except in compliance with the License. |
* You may obtain a copy of the License at |
* |
* http://www.apache.org/licenses/LICENSE-2.0 |
* |
* Unless required by applicable law or agreed to in writing, software |
* distributed under the License is distributed on an "AS IS" BASIS, |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
* See the License for the specific language governing permissions and |
* limitations under the License. |
*/ |
|
/* test "f permutation". |
* write a block, wait 3 cycles, write another block, do not wait, write the third block */ |
|
`timescale 1ns / 1ps |
`define P 20 |
|
module test_f_permutation; |
|
// Inputs |
reg clk; |
reg reset; |
reg [575:0] in; |
reg in_ready; |
|
// Outputs |
wire ack; |
wire [1599:0] out; |
wire out_ready; |
|
integer i; |
|
// Instantiate the Unit Under Test (UUT) |
f_permutation uut ( |
.clk(clk), |
.reset(reset), |
.in(in), |
.in_ready(in_ready), |
.ack(ack), |
.out(out), |
.out_ready(out_ready) |
); |
|
initial begin |
// Initialize Inputs |
clk = 0; |
reset = 1; |
in = 0; |
in_ready = 0; |
|
// Wait 100 ns for global reset to finish |
#100; |
|
// Add stimulus here |
@ (negedge clk); |
if (out !== 0) error; /* should be 0 */ |
if (ack !== 0) error; /* should be 0 */ |
if (out_ready !== 0) error; /* should be 0 */ |
|
#(`P); |
reset = 0; |
in = 0; |
in_ready = 1; |
#(`P); |
if (out_ready !== 0) error; /* should be 0 */ |
in_ready = 0; |
|
/* check 1~10-th cycles */ |
for(i=0; i<10; i=i+1) |
begin |
if (out === 0) error; /* should not be 0 */ |
if (ack !== 0) error; /* should be 0 */ |
if (out_ready !== 0) error; /* should be 0 */ |
#(`P); |
end |
|
/* check the 11-th cycle */ |
if (out === 0) error; /* should not be 0 */ |
if (ack !== 0) error; /* should be 0 */ |
if (out_ready !== 0) error; /* should be 0 */ |
#(`P); |
|
/* check the 12-th cycle */ |
#(`P); /* wait out */ |
if (out_ready !== 1) error; /* should be 1 */ |
if(out !== 1600'hf1258f7940e1dde784d5ccf933c0478ad598261ea65aa9eebd1547306f80494d8b284e056253d057ff97a42d7f8e6fd490fee5a0a44647c48c5bda0cd6192e76ad30a6f71b19059c30935ab7d08ffc64eb5aa93f2317d635a9a6e6260d71210381a57c16dbcf555f43b831cd0347c82601f22f1a11a5569f05e5635a21d9ae6164befef28cc970f2613670957bc46611b87c5a554fd00ecb8c3ee88a1ccf32c8940c7922ae3a26141841f924a2c509e416f53526e70465c275f644e97f30a13beaf1ff7b5ceca249) error; |
|
#(3*`P); /* wait more cycles */ |
if (out_ready !== 1) error; /* should be 1 */ |
/* "out" should not change */ |
if(out !== 1600'hf1258f7940e1dde784d5ccf933c0478ad598261ea65aa9eebd1547306f80494d8b284e056253d057ff97a42d7f8e6fd490fee5a0a44647c48c5bda0cd6192e76ad30a6f71b19059c30935ab7d08ffc64eb5aa93f2317d635a9a6e6260d71210381a57c16dbcf555f43b831cd0347c82601f22f1a11a5569f05e5635a21d9ae6164befef28cc970f2613670957bc46611b87c5a554fd00ecb8c3ee88a1ccf32c8940c7922ae3a26141841f924a2c509e416f53526e70465c275f644e97f30a13beaf1ff7b5ceca249) error; |
|
in_ready = 1; /* feed in one more block */ |
in = 0; |
#(`P); |
if (out_ready !== 0) error; /* should be 0 */ |
in_ready = 0; |
|
while (out_ready !== 1) |
#(`P); |
if(out !== 1600'h2d5c954df96ecb3c6a332cd07057b56d093d8d1270d76b6c8a20d9b25569d0944f9c4f99e5e7f156f957b9a2da65fb3885773dae1275af0dfaf4f247c3d810f71f1b9ee6f79a8759e4fecc0fee98b42568ce61b6b9ce68a1deea66c4ba8f974f33c43d836eafb1f5e00654042719dbd97cf8a9f009831265fd5449a6bf17474397ddad33d8994b4048ead5fc5d0be774e3b8c8ee55b7b03c91a0226e649e42e9900e3129e7badd7b202a9ec5faa3cce85b3402464e1c3db6609f4e62a44c105920d06cd26a8fbf5c) error; |
|
/* no wait, feed in one more block */ |
in_ready = 1; |
#(`P); |
if (out_ready !== 0) error; /* should be 0 */ |
in_ready = 0; |
|
while (out_ready !== 1) |
#(`P); |
if(out !== 1600'h55eabb80767d364686c354c8d01cbace9452d254b0979b3dde59422be2c66f16c660e4f2d4d8212e78414f691b639bb3cbb20f9f1b22e381cf16da5fac2da63f83c0b76552d95f7c44efc84eaf017e1548d380ff3e532c9592436ec5c5e02f05bde57ca1ee8de7e9240970468a1fd1b012a978439cbb7686d26b59fcceff8b4dd2aa0f472110fff87bd44abf53f72551e15ad2b722d00bb7c56095932c792c459e02d1766ad3a79c312f2da72ada4ec368b9f274a8d7d6b92b7239f7e51eea1eb6947f6894d77aeb) error; |
|
$display("Good!"); |
$finish; |
end |
|
always #(`P/2) clk = ~ clk; |
|
task error; |
begin |
$display("Error!"); |
$finish; |
end |
endtask |
endmodule |
|
`undef P |
/sha3/trunk/high_throughput_core/testbench/test_padder.v
0,0 → 1,196
/* |
* Copyright 2013, Homer Hsing <homer.hsing@gmail.com> |
* |
* Licensed under the Apache License, Version 2.0 (the "License"); |
* you may not use this file except in compliance with the License. |
* You may obtain a copy of the License at |
* |
* http://www.apache.org/licenses/LICENSE-2.0 |
* |
* Unless required by applicable law or agreed to in writing, software |
* distributed under the License is distributed on an "AS IS" BASIS, |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
* See the License for the specific language governing permissions and |
* limitations under the License. |
*/ |
|
`timescale 1ns / 1ps |
`define P 20 |
|
module test_padder; |
|
// Inputs |
reg clk; |
reg reset; |
reg [63:0] in; |
reg in_ready; |
reg is_last; |
reg [2:0] byte_num; |
reg f_ack; |
|
// Outputs |
wire buffer_full; |
wire [575:0] out; |
wire out_ready; |
|
// Var |
integer i; |
|
// Instantiate the Unit Under Test (UUT) |
padder uut ( |
.clk(clk), |
.reset(reset), |
.in(in), |
.in_ready(in_ready), |
.is_last(is_last), |
.byte_num(byte_num), |
.buffer_full(buffer_full), |
.out(out), |
.out_ready(out_ready), |
.f_ack(f_ack) |
); |
|
initial begin |
// Initialize Inputs |
clk = 0; |
reset = 1; |
in = 0; |
in_ready = 0; |
is_last = 0; |
byte_num = 0; |
f_ack = 0; |
|
// Wait 100 ns for global reset to finish |
#100; |
|
// Add stimulus here |
@ (negedge clk); |
|
// pad an empty string, should not eat next input |
reset = 1; #(`P); reset = 0; |
#(7*`P); // wait some cycles |
if (buffer_full !== 0) error; |
in_ready = 1; |
is_last = 1; |
#(`P); |
in_ready = 1; // next input |
is_last = 1; |
#(`P); |
in_ready = 0; |
is_last = 0; |
|
while (out_ready !== 1) |
#(`P); |
check({8'h1, 560'h0, 8'h80}); |
f_ack = 1; #(`P); f_ack = 0; |
for(i=0; i<5; i=i+1) |
begin |
#(`P); |
if (buffer_full !== 0) error; // should be 0 |
end |
|
// pad an (576-8) bit string |
reset = 1; #(`P); reset = 0; |
#(4*`P); // wait some cycles |
in_ready = 1; |
byte_num = 7; /* should have no effect */ |
is_last = 0; |
for (i=0; i<8; i=i+1) |
begin |
in = 64'h1234567890ABCDEF; |
#(`P); |
end |
is_last = 1; |
#(`P); |
in_ready = 0; |
is_last = 0; |
check({ {8{64'h1234567890ABCDEF}}, 64'h1234567890ABCD81 }); |
|
// pad an (576-64) bit string |
reset = 1; #(`P); reset = 0; |
// don't wait any cycle |
in_ready = 1; |
byte_num = 7; /* should have no effect */ |
is_last = 0; |
for (i=0; i<8; i=i+1) |
begin |
in = 64'h1234567890ABCDEF; |
#(`P); |
end |
is_last = 1; |
byte_num = 0; |
#(`P); |
in_ready = 0; |
is_last = 0; |
check({ {8{64'h1234567890ABCDEF}}, 64'h0100000000000080 }); |
|
// pad an (576*2-16) bit string |
reset = 1; #(`P); reset = 0; |
in_ready = 1; |
byte_num = 7; /* should have no effect */ |
is_last = 0; |
for (i=0; i<9; i=i+1) |
begin |
in = 64'h1234567890ABCDEF; |
#(`P); |
end |
if (out_ready !== 1) error; |
check({9{64'h1234567890ABCDEF}}); |
#(`P/2); |
if (buffer_full !== 1) error; // should not eat |
#(`P/2); |
in = 64'h999; // should not eat this |
#(`P/2); |
if (buffer_full !== 1) error; // should not eat |
#(`P/2); |
f_ack = 1; #(`P); f_ack = 0; |
if (out_ready !== 0) error; |
// feed next (576-16) bit |
for (i=0; i<8; i=i+1) |
begin |
in = 64'h1234567890ABCDEF; #(`P); |
end |
byte_num = 6; |
is_last = 1; |
in = 64'h1234567890ABCDEF; #(`P); |
if (out_ready !== 1) error; |
check({ {8{64'h1234567890ABCDEF}}, 64'h1234567890AB0180 }); |
is_last = 0; |
// eat these bits |
f_ack = 1; #(`P); f_ack = 0; |
// should not provide any more bits, if user provides nothing |
in_ready = 0; |
is_last = 0; |
for (i=0; i<10; i=i+1) |
begin |
if (out_ready === 1) error; |
#(`P); |
end |
in_ready = 0; |
|
$display("Good!"); |
$finish; |
end |
|
always #(`P/2) clk = ~ clk; |
|
task error; |
begin |
$display("E"); |
$finish; |
end |
endtask |
|
task check; |
input [575:0] wish; |
begin |
if (out !== wish) |
begin |
$display("out:%h wish:%h", out, wish); |
error; |
end |
end |
endtask |
endmodule |
|
`undef P |
/sha3/trunk/high_throughput_core/testbench/test_padder1.v
0,0 → 1,88
/* |
* Copyright 2013, Homer Hsing <homer.hsing@gmail.com> |
* |
* Licensed under the Apache License, Version 2.0 (the "License"); |
* you may not use this file except in compliance with the License. |
* You may obtain a copy of the License at |
* |
* http://www.apache.org/licenses/LICENSE-2.0 |
* |
* Unless required by applicable law or agreed to in writing, software |
* distributed under the License is distributed on an "AS IS" BASIS, |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
* See the License for the specific language governing permissions and |
* limitations under the License. |
*/ |
|
`timescale 1ns / 1ps |
`define P 20 |
|
module test_padder1; |
|
// Inputs |
reg [63:0] in; |
reg [2:0] byte_num; |
|
// Outputs |
wire [63:0] out; |
|
reg [63:0] wish; |
|
// Instantiate the Unit Under Test (UUT) |
padder1 uut ( |
.in(in), |
.byte_num(byte_num), |
.out(out) |
); |
|
initial begin |
// Initialize Inputs |
in = 0; |
byte_num = 0; |
|
// Wait 100 ns for global reset to finish |
#100; |
|
// Add stimulus here |
in = 64'h1234567890ABCDEF; |
byte_num = 0; |
wish = {8'h01, 56'h0}; |
check; |
byte_num = 1; |
wish = 64'h1201000000000000; |
check; |
byte_num = 2; |
wish = 64'h1234010000000000; |
check; |
byte_num = 3; |
wish = 64'h1234560100000000; |
check; |
byte_num = 4; |
wish = 64'h1234567801000000; |
check; |
byte_num = 5; |
wish = 64'h1234567890010000; |
check; |
byte_num = 6; |
wish = 64'h1234567890AB0100; |
check; |
byte_num = 7; |
wish = 64'h1234567890ABCD01; |
check; |
$display("Good!"); |
$finish; |
end |
|
task check; |
begin |
#(`P); |
if (out !== wish) |
begin |
$display("E"); |
$finish; |
end |
end |
endtask |
endmodule |
|
`undef P |
/sha3/trunk/high_throughput_core/testbench/test_keccak.v
0,0 → 1,242
/* |
* Copyright 2013, Homer Hsing <homer.hsing@gmail.com> |
* |
* Licensed under the Apache License, Version 2.0 (the "License"); |
* you may not use this file except in compliance with the License. |
* You may obtain a copy of the License at |
* |
* http://www.apache.org/licenses/LICENSE-2.0 |
* |
* Unless required by applicable law or agreed to in writing, software |
* distributed under the License is distributed on an "AS IS" BASIS, |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
* See the License for the specific language governing permissions and |
* limitations under the License. |
*/ |
|
`timescale 1ns / 1ps |
`define P 20 |
|
module test_keccak; |
|
// Inputs |
reg clk; |
reg reset; |
reg [63:0] in; |
reg in_ready; |
reg is_last; |
reg [2:0] byte_num; |
|
// Outputs |
wire buffer_full; |
wire [511:0] out; |
wire out_ready; |
|
// Var |
integer i; |
|
// Instantiate the Unit Under Test (UUT) |
keccak uut ( |
.clk(clk), |
.reset(reset), |
.in(in), |
.in_ready(in_ready), |
.is_last(is_last), |
.byte_num(byte_num), |
.buffer_full(buffer_full), |
.out(out), |
.out_ready(out_ready) |
); |
|
initial begin |
// Initialize Inputs |
clk = 0; |
reset = 0; |
in = 0; |
in_ready = 0; |
is_last = 0; |
byte_num = 0; |
|
// Wait 100 ns for global reset to finish |
#100; |
|
// Add stimulus here |
@ (negedge clk); |
|
// SHA3-512("The quick brown fox jumps over the lazy dog") |
reset = 1; #(`P); reset = 0; |
in_ready = 1; is_last = 0; |
in = "The quic"; #(`P); |
in = "k brown "; #(`P); |
in = "fox jump"; #(`P); |
in = "s over t"; #(`P); |
in = "he lazy "; #(`P); |
in = "dog "; byte_num = 3; is_last = 1; #(`P); /* !!! not in = "dog" */ |
in_ready = 0; is_last = 0; |
while (out_ready !== 1) |
#(`P); |
check(512'hd135bb84d0439dbac432247ee573a23ea7d3c9deb2a968eb31d47c4fb45f1ef4422d6c531b5b9bd6f449ebcc449ea94d0a8f05f62130fda612da53c79659f609); |
|
// SHA3-512("The quick brown fox jumps over the lazy dog.") |
reset = 1; #(`P); reset = 0; |
in_ready = 1; is_last = 0; |
in = "The quic"; #(`P); |
in = "k brown "; #(`P); |
in = "fox jump"; #(`P); |
in = "s over t"; #(`P); |
in = "he lazy "; #(`P); |
in = "dog. "; byte_num = 4; is_last = 1; #(`P); /* !!! not in = "dog." */ |
in_ready = 0; is_last = 0; |
while (out_ready !== 1) |
#(`P); |
check(512'hab7192d2b11f51c7dd744e7b3441febf397ca07bf812cceae122ca4ded6387889064f8db9230f173f6d1ab6e24b6e50f065b039f799f5592360a6558eb52d760); |
|
// hash an string "\xA1\xA2\xA3\xA4\xA5", len == 5 |
reset = 1; #(`P); reset = 0; |
#(7*`P); // wait some cycles |
in = 64'hA1A2A3A4A5000000; |
byte_num = 5; |
in_ready = 1; |
is_last = 1; |
#(`P); |
in = 64'h12345678; // next input |
in_ready = 1; |
is_last = 1; |
#(`P/2); |
if (buffer_full === 1) error; // should be 0 |
#(`P/2); |
in_ready = 0; |
is_last = 0; |
|
while (out_ready !== 1) |
#(`P); |
check(512'h12f4a85b68b091e8836219e79dfff7eb9594a42f5566515423b2aa4c67c454de83a62989e44b5303022bfe8c1a9976781b747a596cdab0458e20d8750df6ddfb); |
for(i=0; i<5; i=i+1) |
begin |
#(`P); |
if (buffer_full !== 0) error; // should keep 0 |
end |
|
// hash an empty string, should not eat next input |
reset = 1; #(`P); reset = 0; |
#(7*`P); // wait some cycles |
in = 64'h12345678; // should not be eat |
byte_num = 0; |
in_ready = 1; |
is_last = 1; |
#(`P); |
in = 64'hddddd; // should not be eat |
in_ready = 1; // next input |
is_last = 1; |
#(`P); |
in_ready = 0; |
is_last = 0; |
|
while (out_ready !== 1) |
#(`P); |
check(512'h0eab42de4c3ceb9235fc91acffe746b29c29a8c366b7c60e4e67c466f36a4304c00fa9caf9d87976ba469bcbe06713b435f091ef2769fb160cdab33d3670680e); |
for(i=0; i<5; i=i+1) |
begin |
#(`P); |
if (buffer_full !== 0) error; // should keep 0 |
end |
|
// hash an (576-8) bit string |
reset = 1; #(`P); reset = 0; |
#(4*`P); // wait some cycles |
in_ready = 1; |
byte_num = 7; /* should have no effect */ |
is_last = 0; |
for (i=0; i<8; i=i+1) |
begin |
in = 64'hEFCDAB9078563412; |
#(`P); |
end |
is_last = 1; |
#(`P); |
in_ready = 0; |
is_last = 0; |
while (out_ready !== 1) |
#(`P); |
check(512'hf7f6b44069dba8900b6711ffcbe40523d4bb718cc8ed7f0a0bd28a1b18ee9374359f0ca0c9c1e96fcfca29ee2f282b46d5045eff01f7a7549eaa6b652cbf6270); |
|
// pad an (576-64) bit string |
reset = 1; #(`P); reset = 0; |
// don't wait any cycle |
in_ready = 1; |
byte_num = 7; /* should have no effect */ |
is_last = 0; |
for (i=0; i<8; i=i+1) |
begin |
in = 64'hEFCDAB9078563412; |
#(`P); |
end |
is_last = 1; |
byte_num = 0; |
#(`P); |
in_ready = 0; |
is_last = 0; |
in = 0; |
while (out_ready !== 1) |
#(`P); |
check(512'hccd91653872c106f6eea1b8b68a4c2901c8d9bed9c180201f8a6144e7e6e6c251afcb6f6da44780b2d9aabff254036664719425469671f7e21fb67e5280a27ed); |
|
// pad an (576*2-16) bit string |
reset = 1; #(`P); reset = 0; |
in_ready = 1; |
byte_num = 1; /* should have no effect */ |
is_last = 0; |
for (i=0; i<9; i=i+1) |
begin |
in = 64'hEFCDAB9078563412; #(`P); |
end |
#(`P/2); |
if (buffer_full !== 1) error; // should not eat |
#(`P/2); |
in = 64'h999; // should not eat this |
in_ready = 0; |
#(`P/2); |
if (buffer_full !== 0) error; // should not eat, but buffer should not be full |
#(`P/2); |
#(`P); |
// feed next (576-16) bit |
in_ready = 1; |
for (i=0; i<8; i=i+1) |
begin |
in = 64'hEFCDAB9078563412; #(`P); |
end |
byte_num = 6; |
is_last = 1; |
in = 64'hEFCDAB9078563412; |
#(`P); |
is_last = 0; |
in_ready = 0; |
while (out_ready !== 1) |
#(`P); |
check(512'h0f385323604e279251e80f928cfd9ce9492ba5df775063ea106eebe2a2c7785a3e33b4397fca66e90f67470334c66ea12016cb1f06170b9b033f158a7c01933e); |
|
$display("Good!"); |
$finish; |
end |
|
always #(`P/2) clk = ~ clk; |
|
task error; |
begin |
$display("E"); |
$finish; |
end |
endtask |
|
task check; |
input [511:0] wish; |
begin |
if (out !== wish) |
begin |
$display("%h %h", out, wish); error; |
end |
end |
endtask |
endmodule |
|
`undef P |
/sha3/trunk/high_throughput_core/testbench/test_rconst2in1.v
0,0 → 1,98
/* |
* Copyright 2013, Homer Hsing <homer.hsing@gmail.com> |
* |
* Licensed under the Apache License, Version 2.0 (the "License"); |
* you may not use this file except in compliance with the License. |
* You may obtain a copy of the License at |
* |
* http://www.apache.org/licenses/LICENSE-2.0 |
* |
* Unless required by applicable law or agreed to in writing, software |
* distributed under the License is distributed on an "AS IS" BASIS, |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
* See the License for the specific language governing permissions and |
* limitations under the License. |
*/ |
|
`timescale 1ns / 1ps |
`define P 20 |
|
module test_rconst2in1; |
|
// Inputs |
reg [11:0] i; |
|
// Outputs |
wire [63:0] rc1; |
wire [63:0] rc2; |
|
// Instantiate the Unit Under Test (UUT) |
rconst2in1 uut ( |
.i(i), |
.rc1(rc1), |
.rc2(rc2) |
); |
|
initial begin |
// Initialize Inputs |
i = 0; |
|
// Wait 100 ns for global reset to finish |
#100; |
|
// Add stimulus here |
i=0; i[0] = 1; |
#(`P/2); |
if(rc1 !== 64'h1) begin $display("E"); $finish; end |
if(rc2 !== 64'h8082) begin $display("E"); $finish; end |
i=0; i[1] = 1; |
#(`P/2); |
if(rc1 !== 64'h800000000000808a) begin $display("E"); $finish; end |
if(rc2 !== 64'h8000000080008000) begin $display("E"); $finish; end |
i=0; i[2] = 1; |
#(`P/2); |
if(rc1 !== 64'h808b) begin $display("E"); $finish; end |
if(rc2 !== 64'h80000001) begin $display("E"); $finish; end |
i=0; i[3] = 1; |
#(`P/2); |
if(rc1 !== 64'h8000000080008081) begin $display("E"); $finish; end |
if(rc2 !== 64'h8000000000008009) begin $display("E"); $finish; end |
i=0; i[4] = 1; |
#(`P/2); |
if(rc1 !== 64'h8a) begin $display("E"); $finish; end |
if(rc2 !== 64'h88) begin $display("E"); $finish; end |
i=0; i[5] = 1; |
#(`P/2); |
if(rc1 !== 64'h80008009) begin $display("E"); $finish; end |
if(rc2 !== 64'h8000000a) begin $display("E"); $finish; end |
i=0; i[6] = 1; |
#(`P/2); |
if(rc1 !== 64'h8000808b) begin $display("E"); $finish; end |
if(rc2 !== 64'h800000000000008b) begin $display("E"); $finish; end |
i=0; i[7] = 1; |
#(`P/2); |
if(rc1 !== 64'h8000000000008089) begin $display("E"); $finish; end |
if(rc2 !== 64'h8000000000008003) begin $display("E"); $finish; end |
i=0; i[8] = 1; |
#(`P/2); |
if(rc1 !== 64'h8000000000008002) begin $display("E"); $finish; end |
if(rc2 !== 64'h8000000000000080) begin $display("E"); $finish; end |
i=0; i[9] = 1; |
#(`P/2); |
if(rc1 !== 64'h800a) begin $display("E"); $finish; end |
if(rc2 !== 64'h800000008000000a) begin $display("E"); $finish; end |
i=0; i[10] = 1; |
#(`P/2); |
if(rc1 !== 64'h8000000080008081) begin $display("E"); $finish; end |
if(rc2 !== 64'h8000000000008080) begin $display("E"); $finish; end |
i=0; i[11] = 1; |
#(`P/2); |
if(rc1 !== 64'h80000001) begin $display("E"); $finish; end |
if(rc2 !== 64'h8000000080008008) begin $display("E"); $finish; end |
$display("Good!"); |
$finish; |
end |
|
endmodule |
|
`undef P |
/sha3/trunk/high_throughput_core/testbench/simulation.do
0,0 → 1,16
vlib work |
vlog -lint ../rtl/*.v |
vlog -lint *.v |
vsim -novopt test_keccak |
add wave -noupdate -format Logic -radix unsigned /test_keccak/clk |
add wave -noupdate -format Logic -radix unsigned /test_keccak/reset |
add wave -noupdate -divider input |
add wave -noupdate -format Literal -radix hexadecimal /test_keccak/in |
add wave -noupdate -format Literal -radix unsigned /test_keccak/byte_num |
add wave -noupdate -format Literal -radix unsigned /test_keccak/in_ready |
add wave -noupdate -format Literal -radix unsigned /test_keccak/is_last |
add wave -noupdate -divider output |
add wave -noupdate -format Literal -radix unsigned /test_keccak/ack |
add wave -noupdate -format Literal -radix hexadecimal /test_keccak/out |
add wave -noupdate -format Literal -radix unsigned /test_keccak/out_ready |
run -all |
/sha3/trunk/high_throughput_core/testbench/Read_Me.txt
0,0 → 1,9
How to start the simulation |
|
1. simulation.do |
---------------- |
This file is a batch file for Modelsim to compile the HDL files, setup the wave file, and begin function simulation. The working directory of Modelsim must be the same directory of the batch file. |
|
2. test_keccak.v |
---------------------- |
This file is the main test bench. It is self-checked. It feeds input data to the core and compare the correct result with the output of the core. If the output is wrong, the test bench will display an error message. |
/sha3/trunk/high_throughput_core/rtl/f_permutation.v
0,0 → 1,69
/* |
* Copyright 2013, Homer Hsing <homer.hsing@gmail.com> |
* |
* Licensed under the Apache License, Version 2.0 (the "License"); |
* you may not use this file except in compliance with the License. |
* You may obtain a copy of the License at |
* |
* http://www.apache.org/licenses/LICENSE-2.0 |
* |
* Unless required by applicable law or agreed to in writing, software |
* distributed under the License is distributed on an "AS IS" BASIS, |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
* See the License for the specific language governing permissions and |
* limitations under the License. |
*/ |
|
/* if "ack" is 1, then current input has been used. */ |
|
module f_permutation(clk, reset, in, in_ready, ack, out, out_ready); |
input clk, reset; |
input [575:0] in; |
input in_ready; |
output ack; |
output reg [1599:0] out; |
output reg out_ready; |
|
reg [10:0] i; /* select round constant */ |
wire [1599:0] round_in, round_out; |
wire [63:0] rc1, rc2; |
wire update; |
wire accept; |
reg calc; /* == 1: calculating rounds */ |
|
assign accept = in_ready & (~ calc); // in_ready & (i == 0) |
|
always @ (posedge clk) |
if (reset) i <= 0; |
else i <= {i[9:0], accept}; |
|
always @ (posedge clk) |
if (reset) calc <= 0; |
else calc <= (calc & (~ i[10])) | accept; |
|
assign update = calc | accept; |
|
assign ack = accept; |
|
always @ (posedge clk) |
if (reset) |
out_ready <= 0; |
else if (accept) |
out_ready <= 0; |
else if (i[10]) // only change at the last round |
out_ready <= 1; |
|
assign round_in = accept ? {in ^ out[1599:1599-575], out[1599-576:0]} : out; |
|
rconst2in1 |
rconst_ ({i, accept}, rc1, rc2); |
|
round2in1 |
round_ (round_in, rc1, rc2, round_out); |
|
always @ (posedge clk) |
if (reset) |
out <= 0; |
else if (update) |
out <= round_out; |
endmodule |
/sha3/trunk/high_throughput_core/rtl/padder.v
0,0 → 1,88
/* |
* Copyright 2013, Homer Hsing <homer.hsing@gmail.com> |
* |
* Licensed under the Apache License, Version 2.0 (the "License"); |
* you may not use this file except in compliance with the License. |
* You may obtain a copy of the License at |
* |
* http://www.apache.org/licenses/LICENSE-2.0 |
* |
* Unless required by applicable law or agreed to in writing, software |
* distributed under the License is distributed on an "AS IS" BASIS, |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
* See the License for the specific language governing permissions and |
* limitations under the License. |
*/ |
|
/* "is_last" == 0 means byte number is 8, no matter what value "byte_num" is. */ |
/* if "in_ready" == 0, then "is_last" should be 0. */ |
/* the user switch to next "in" only if "ack" == 1. */ |
|
module padder(clk, reset, in, in_ready, is_last, byte_num, buffer_full, out, out_ready, f_ack); |
input clk, reset; |
input [63:0] in; |
input in_ready, is_last; |
input [2:0] byte_num; |
output buffer_full; /* to "user" module */ |
output reg [575:0] out; /* to "f_permutation" module */ |
output out_ready; /* to "f_permutation" module */ |
input f_ack; /* from "f_permutation" module */ |
|
reg state; /* state == 0: user will send more input data |
* state == 1: user will not send any data */ |
reg done; /* == 1: out_ready should be 0 */ |
reg [8:0] i; /* length of "out" buffer */ |
wire [63:0] v0; /* output of module "padder1" */ |
reg [63:0] v1; /* to be shifted into register "out" */ |
wire accept, /* accept user input? */ |
update; |
|
assign buffer_full = i[8]; |
assign out_ready = buffer_full; |
assign accept = (~ state) & in_ready & (~ buffer_full); // if state == 1, do not eat input |
assign update = (accept | (state & (~ buffer_full))) & (~ done); // don't fill buffer if done |
|
always @ (posedge clk) |
if (reset) |
out <= 0; |
else if (update) |
out <= {out[575-64:0], v1}; |
|
always @ (posedge clk) |
if (reset) |
i <= 0; |
else if (f_ack | update) |
i <= {i[7:0], 1'b1} & {9{~ f_ack}}; |
/* if (f_ack) i <= 0; */ |
/* if (update) i <= {i[7:0], 1'b1}; // increase length */ |
|
always @ (posedge clk) |
if (reset) |
state <= 0; |
else if (is_last) |
state <= 1; |
|
always @ (posedge clk) |
if (reset) |
done <= 0; |
else if (state & out_ready) |
done <= 1; |
|
padder1 p0 (in, byte_num, v0); |
|
always @ (*) |
begin |
if (state) |
begin |
v1 = 0; |
v1[7] = v1[7] | i[7]; /* "v1[7]" is the MSB of its last byte */ |
end |
else if (is_last == 0) |
v1 = in; |
else |
begin |
v1 = v0; |
v1[7] = v1[7] | i[7]; |
end |
end |
endmodule |
/sha3/trunk/high_throughput_core/rtl/padder1.v
0,0 → 1,33
/* |
* Copyright 2013, Homer Hsing <homer.hsing@gmail.com> |
* |
* Licensed under the Apache License, Version 2.0 (the "License"); |
* you may not use this file except in compliance with the License. |
* You may obtain a copy of the License at |
* |
* http://www.apache.org/licenses/LICENSE-2.0 |
* |
* Unless required by applicable law or agreed to in writing, software |
* distributed under the License is distributed on an "AS IS" BASIS, |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
* See the License for the specific language governing permissions and |
* limitations under the License. |
*/ |
|
module padder1(in, byte_num, out); |
input [63:0] in; |
input [2:0] byte_num; |
output reg [63:0] out; |
|
always @ (*) |
case (byte_num) |
0: out = 64'h0100000000000000; |
1: out = {in[63:56], 56'h01000000000000}; |
2: out = {in[63:48], 48'h010000000000}; |
3: out = {in[63:40], 40'h0100000000}; |
4: out = {in[63:32], 32'h01000000}; |
5: out = {in[63:24], 24'h010000}; |
6: out = {in[63:16], 16'h0100}; |
7: out = {in[63:8], 8'h01}; |
endcase |
endmodule |
/sha3/trunk/high_throughput_core/rtl/round2in1.v
0,0 → 1,284
/* |
* Copyright 2013, Homer Hsing <homer.hsing@gmail.com> |
* |
* Licensed under the Apache License, Version 2.0 (the "License"); |
* you may not use this file except in compliance with the License. |
* You may obtain a copy of the License at |
* |
* http://www.apache.org/licenses/LICENSE-2.0 |
* |
* Unless required by applicable law or agreed to in writing, software |
* distributed under the License is distributed on an "AS IS" BASIS, |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
* See the License for the specific language governing permissions and |
* limitations under the License. |
*/ |
|
`define low_pos(x,y) `high_pos(x,y) - 63 |
`define high_pos(x,y) 1599 - 64*(5*y+x) |
`define add_1(x) (x == 4 ? 0 : x + 1) |
`define add_2(x) (x == 3 ? 0 : x == 4 ? 1 : x + 2) |
`define sub_1(x) (x == 0 ? 4 : x - 1) |
`define rot_up(in, n) {in[63-n:0], in[63:63-n+1]} |
`define rot_up_1(in) {in[62:0], in[63]} |
|
module round2in1(in, round_const_1, round_const_2, out); |
input [1599:0] in; |
input [63:0] round_const_1, round_const_2; |
output [1599:0] out; |
|
/* "a ~ g" for round 1 */ |
wire [63:0] a[4:0][4:0]; |
wire [63:0] b[4:0]; |
wire [63:0] c[4:0][4:0], d[4:0][4:0], e[4:0][4:0], f[4:0][4:0], g[4:0][4:0]; |
|
/* "aa ~ gg" for round 2 */ |
wire [63:0] bb[4:0]; |
wire [63:0] cc[4:0][4:0], dd[4:0][4:0], ee[4:0][4:0], ff[4:0][4:0], gg[4:0][4:0]; |
|
genvar x, y; |
|
/* assign "a[x][y][z] == in[w(5y+x)+z]" */ |
generate |
for(y=0; y<5; y=y+1) |
begin : L0 |
for(x=0; x<5; x=x+1) |
begin : L1 |
assign a[x][y] = in[`high_pos(x,y) : `low_pos(x,y)]; |
end |
end |
endgenerate |
|
/* calc "b[x] == a[x][0] ^ a[x][1] ^ ... ^ a[x][4]" */ |
generate |
for(x=0; x<5; x=x+1) |
begin : L2 |
assign b[x] = a[x][0] ^ a[x][1] ^ a[x][2] ^ a[x][3] ^ a[x][4]; |
end |
endgenerate |
|
/* calc "c == theta(a)" */ |
generate |
for(y=0; y<5; y=y+1) |
begin : L3 |
for(x=0; x<5; x=x+1) |
begin : L4 |
assign c[x][y] = a[x][y] ^ b[`sub_1(x)] ^ `rot_up_1(b[`add_1(x)]); |
end |
end |
endgenerate |
|
/* calc "d == rho(c)" */ |
assign d[0][0] = c[0][0]; |
assign d[1][0] = `rot_up_1(c[1][0]); |
assign d[2][0] = `rot_up(c[2][0], 62); |
assign d[3][0] = `rot_up(c[3][0], 28); |
assign d[4][0] = `rot_up(c[4][0], 27); |
assign d[0][1] = `rot_up(c[0][1], 36); |
assign d[1][1] = `rot_up(c[1][1], 44); |
assign d[2][1] = `rot_up(c[2][1], 6); |
assign d[3][1] = `rot_up(c[3][1], 55); |
assign d[4][1] = `rot_up(c[4][1], 20); |
assign d[0][2] = `rot_up(c[0][2], 3); |
assign d[1][2] = `rot_up(c[1][2], 10); |
assign d[2][2] = `rot_up(c[2][2], 43); |
assign d[3][2] = `rot_up(c[3][2], 25); |
assign d[4][2] = `rot_up(c[4][2], 39); |
assign d[0][3] = `rot_up(c[0][3], 41); |
assign d[1][3] = `rot_up(c[1][3], 45); |
assign d[2][3] = `rot_up(c[2][3], 15); |
assign d[3][3] = `rot_up(c[3][3], 21); |
assign d[4][3] = `rot_up(c[4][3], 8); |
assign d[0][4] = `rot_up(c[0][4], 18); |
assign d[1][4] = `rot_up(c[1][4], 2); |
assign d[2][4] = `rot_up(c[2][4], 61); |
assign d[3][4] = `rot_up(c[3][4], 56); |
assign d[4][4] = `rot_up(c[4][4], 14); |
|
/* calc "e == pi(d)" */ |
assign e[0][0] = d[0][0]; |
assign e[0][2] = d[1][0]; |
assign e[0][4] = d[2][0]; |
assign e[0][1] = d[3][0]; |
assign e[0][3] = d[4][0]; |
assign e[1][3] = d[0][1]; |
assign e[1][0] = d[1][1]; |
assign e[1][2] = d[2][1]; |
assign e[1][4] = d[3][1]; |
assign e[1][1] = d[4][1]; |
assign e[2][1] = d[0][2]; |
assign e[2][3] = d[1][2]; |
assign e[2][0] = d[2][2]; |
assign e[2][2] = d[3][2]; |
assign e[2][4] = d[4][2]; |
assign e[3][4] = d[0][3]; |
assign e[3][1] = d[1][3]; |
assign e[3][3] = d[2][3]; |
assign e[3][0] = d[3][3]; |
assign e[3][2] = d[4][3]; |
assign e[4][2] = d[0][4]; |
assign e[4][4] = d[1][4]; |
assign e[4][1] = d[2][4]; |
assign e[4][3] = d[3][4]; |
assign e[4][0] = d[4][4]; |
|
/* calc "f = chi(e)" */ |
generate |
for(y=0; y<5; y=y+1) |
begin : L5 |
for(x=0; x<5; x=x+1) |
begin : L6 |
assign f[x][y] = e[x][y] ^ ((~ e[`add_1(x)][y]) & e[`add_2(x)][y]); |
end |
end |
endgenerate |
|
/* calc "g = iota(f)" */ |
generate |
for(x=0; x<64; x=x+1) |
begin : L60 |
if(x==0 || x==1 || x==3 || x==7 || x==15 || x==31 || x==63) |
assign g[0][0][x] = f[0][0][x] ^ round_const_1[x]; |
else |
assign g[0][0][x] = f[0][0][x]; |
end |
endgenerate |
|
generate |
for(y=0; y<5; y=y+1) |
begin : L7 |
for(x=0; x<5; x=x+1) |
begin : L8 |
if(x!=0 || y!=0) |
assign g[x][y] = f[x][y]; |
end |
end |
endgenerate |
|
/* round 2 */ |
|
/* calc "bb[x] == g[x][0] ^ g[x][1] ^ ... ^ g[x][4]" */ |
generate |
for(x=0; x<5; x=x+1) |
begin : L12 |
assign bb[x] = g[x][0] ^ g[x][1] ^ g[x][2] ^ g[x][3] ^ g[x][4]; |
end |
endgenerate |
|
/* calc "cc == theta(g)" */ |
generate |
for(y=0; y<5; y=y+1) |
begin : L13 |
for(x=0; x<5; x=x+1) |
begin : L14 |
assign cc[x][y] = g[x][y] ^ bb[`sub_1(x)] ^ `rot_up_1(bb[`add_1(x)]); |
end |
end |
endgenerate |
|
/* calc "dd == rho(cc)" */ |
assign dd[0][0] = cc[0][0]; |
assign dd[1][0] = `rot_up_1(cc[1][0]); |
assign dd[2][0] = `rot_up(cc[2][0], 62); |
assign dd[3][0] = `rot_up(cc[3][0], 28); |
assign dd[4][0] = `rot_up(cc[4][0], 27); |
assign dd[0][1] = `rot_up(cc[0][1], 36); |
assign dd[1][1] = `rot_up(cc[1][1], 44); |
assign dd[2][1] = `rot_up(cc[2][1], 6); |
assign dd[3][1] = `rot_up(cc[3][1], 55); |
assign dd[4][1] = `rot_up(cc[4][1], 20); |
assign dd[0][2] = `rot_up(cc[0][2], 3); |
assign dd[1][2] = `rot_up(cc[1][2], 10); |
assign dd[2][2] = `rot_up(cc[2][2], 43); |
assign dd[3][2] = `rot_up(cc[3][2], 25); |
assign dd[4][2] = `rot_up(cc[4][2], 39); |
assign dd[0][3] = `rot_up(cc[0][3], 41); |
assign dd[1][3] = `rot_up(cc[1][3], 45); |
assign dd[2][3] = `rot_up(cc[2][3], 15); |
assign dd[3][3] = `rot_up(cc[3][3], 21); |
assign dd[4][3] = `rot_up(cc[4][3], 8); |
assign dd[0][4] = `rot_up(cc[0][4], 18); |
assign dd[1][4] = `rot_up(cc[1][4], 2); |
assign dd[2][4] = `rot_up(cc[2][4], 61); |
assign dd[3][4] = `rot_up(cc[3][4], 56); |
assign dd[4][4] = `rot_up(cc[4][4], 14); |
|
/* calc "ee == pi(dd)" */ |
assign ee[0][0] = dd[0][0]; |
assign ee[0][2] = dd[1][0]; |
assign ee[0][4] = dd[2][0]; |
assign ee[0][1] = dd[3][0]; |
assign ee[0][3] = dd[4][0]; |
assign ee[1][3] = dd[0][1]; |
assign ee[1][0] = dd[1][1]; |
assign ee[1][2] = dd[2][1]; |
assign ee[1][4] = dd[3][1]; |
assign ee[1][1] = dd[4][1]; |
assign ee[2][1] = dd[0][2]; |
assign ee[2][3] = dd[1][2]; |
assign ee[2][0] = dd[2][2]; |
assign ee[2][2] = dd[3][2]; |
assign ee[2][4] = dd[4][2]; |
assign ee[3][4] = dd[0][3]; |
assign ee[3][1] = dd[1][3]; |
assign ee[3][3] = dd[2][3]; |
assign ee[3][0] = dd[3][3]; |
assign ee[3][2] = dd[4][3]; |
assign ee[4][2] = dd[0][4]; |
assign ee[4][4] = dd[1][4]; |
assign ee[4][1] = dd[2][4]; |
assign ee[4][3] = dd[3][4]; |
assign ee[4][0] = dd[4][4]; |
|
/* calc "ff = chi(ee)" */ |
generate |
for(y=0; y<5; y=y+1) |
begin : L15 |
for(x=0; x<5; x=x+1) |
begin : L16 |
assign ff[x][y] = ee[x][y] ^ ((~ ee[`add_1(x)][y]) & ee[`add_2(x)][y]); |
end |
end |
endgenerate |
|
/* calc "gg = iota(ff)" */ |
generate |
for(x=0; x<64; x=x+1) |
begin : L160 |
if(x==0 || x==1 || x==3 || x==7 || x==15 || x==31 || x==63) |
assign gg[0][0][x] = ff[0][0][x] ^ round_const_2[x]; |
else |
assign gg[0][0][x] = ff[0][0][x]; |
end |
endgenerate |
|
generate |
for(y=0; y<5; y=y+1) |
begin : L17 |
for(x=0; x<5; x=x+1) |
begin : L18 |
if(x!=0 || y!=0) |
assign gg[x][y] = ff[x][y]; |
end |
end |
endgenerate |
|
/* assign "out[w(5y+x)+z] == out_var[x][y][z]" */ |
generate |
for(y=0; y<5; y=y+1) |
begin : L99 |
for(x=0; x<5; x=x+1) |
begin : L100 |
assign out[`high_pos(x,y) : `low_pos(x,y)] = gg[x][y]; |
end |
end |
endgenerate |
endmodule |
|
`undef low_pos |
`undef high_pos |
`undef add_1 |
`undef add_2 |
`undef sub_1 |
`undef rot_up |
`undef rot_up_1 |
/sha3/trunk/high_throughput_core/rtl/keccak.v
0,0 → 1,98
/* |
* Copyright 2013, Homer Hsing <homer.hsing@gmail.com> |
* |
* Licensed under the Apache License, Version 2.0 (the "License"); |
* you may not use this file except in compliance with the License. |
* You may obtain a copy of the License at |
* |
* http://www.apache.org/licenses/LICENSE-2.0 |
* |
* Unless required by applicable law or agreed to in writing, software |
* distributed under the License is distributed on an "AS IS" BASIS, |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
* See the License for the specific language governing permissions and |
* limitations under the License. |
*/ |
|
/* "is_last" == 0 means byte number is 8, no matter what value "byte_num" is. */ |
/* if "in_ready" == 0, then "is_last" should be 0. */ |
/* the user switch to next "in" only if "ack" == 1. */ |
|
`define low_pos(w,b) ((w)*64 + (b)*8) |
`define low_pos2(w,b) `low_pos(w,7-b) |
`define high_pos(w,b) (`low_pos(w,b) + 7) |
`define high_pos2(w,b) (`low_pos2(w,b) + 7) |
|
module keccak(clk, reset, in, in_ready, is_last, byte_num, buffer_full, out, out_ready); |
input clk, reset; |
input [63:0] in; |
input in_ready, is_last; |
input [2:0] byte_num; |
output buffer_full; /* to "user" module */ |
output [511:0] out; |
output reg out_ready; |
|
reg state; /* state == 0: user will send more input data |
* state == 1: user will not send any data */ |
wire [575:0] padder_out, |
padder_out_1; /* before reorder byte */ |
wire padder_out_ready; |
wire f_ack; |
wire [1599:0] f_out; |
wire f_out_ready; |
wire [511:0] out1; /* before reorder byte */ |
reg [10:0] i; /* gen "out_ready" */ |
genvar w, b; |
|
assign out1 = f_out[1599:1599-511]; |
|
always @ (posedge clk) |
if (reset) |
i <= 0; |
else |
i <= {i[9:0], state & f_ack}; |
|
always @ (posedge clk) |
if (reset) |
state <= 0; |
else if (is_last) |
state <= 1; |
|
/* reorder byte ~ ~ */ |
generate |
for(w=0; w<8; w=w+1) |
begin : L0 |
for(b=0; b<8; b=b+1) |
begin : L1 |
assign out[`high_pos(w,b):`low_pos(w,b)] = out1[`high_pos2(w,b):`low_pos2(w,b)]; |
end |
end |
endgenerate |
|
generate |
for(w=0; w<9; w=w+1) |
begin : L2 |
for(b=0; b<8; b=b+1) |
begin : L3 |
assign padder_out[`high_pos(w,b):`low_pos(w,b)] = padder_out_1[`high_pos2(w,b):`low_pos2(w,b)]; |
end |
end |
endgenerate |
|
always @ (posedge clk) |
if (reset) |
out_ready <= 0; |
else if (i[10]) |
out_ready <= 1; |
|
padder |
padder_ (clk, reset, in, in_ready, is_last, byte_num, buffer_full, padder_out_1, padder_out_ready, f_ack); |
|
f_permutation |
f_permutation_ (clk, reset, padder_out, padder_out_ready, f_ack, f_out, f_out_ready); |
endmodule |
|
`undef low_pos |
`undef low_pos2 |
`undef high_pos |
`undef high_pos2 |
/sha3/trunk/high_throughput_core/rtl/rconst2in1.v
0,0 → 1,46
/* |
* Copyright 2013, Homer Hsing <homer.hsing@gmail.com> |
* |
* Licensed under the Apache License, Version 2.0 (the "License"); |
* you may not use this file except in compliance with the License. |
* You may obtain a copy of the License at |
* |
* http://www.apache.org/licenses/LICENSE-2.0 |
* |
* Unless required by applicable law or agreed to in writing, software |
* distributed under the License is distributed on an "AS IS" BASIS, |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
* See the License for the specific language governing permissions and |
* limitations under the License. |
*/ |
|
/* round constant (2 in 1 ~ ~) */ |
module rconst2in1(i, rc1, rc2); |
input [11:0] i; |
output [63:0] rc1, rc2; |
reg [63:0] rc1, rc2; |
|
always @ (i) |
begin |
rc1 = 0; |
rc1[0] = i[0] | i[2] | i[3] | i[5] | i[6] | i[7] | i[10] | i[11]; |
rc1[1] = i[1] | i[2] | i[4] | i[6] | i[8] | i[9]; |
rc1[3] = i[1] | i[2] | i[4] | i[5] | i[6] | i[7] | i[9]; |
rc1[7] = i[1] | i[2] | i[3] | i[4] | i[6] | i[7] | i[10]; |
rc1[15] = i[1] | i[2] | i[3] | i[5] | i[6] | i[7] | i[8] | i[9] | i[10]; |
rc1[31] = i[3] | i[5] | i[6] | i[10] | i[11]; |
rc1[63] = i[1] | i[3] | i[7] | i[8] | i[10]; |
end |
|
always @ (i) |
begin |
rc2 = 0; |
rc2[0] = i[2] | i[3] | i[6] | i[7]; |
rc2[1] = i[0] | i[5] | i[6] | i[7] | i[9]; |
rc2[3] = i[3] | i[4] | i[5] | i[6] | i[9] | i[11]; |
rc2[7] = i[0] | i[4] | i[6] | i[8] | i[10]; |
rc2[15] = i[0] | i[1] | i[3] | i[7] | i[10] | i[11]; |
rc2[31] = i[1] | i[2] | i[5] | i[9] | i[11]; |
rc2[63] = i[1] | i[3] | i[6] | i[7] | i[8] | i[9] | i[10] | i[11]; |
end |
endmodule |
/sha3/trunk/high_throughput_core/for ASIC or expensive FPGA
--- sha3/trunk/low_throughput_core/testbench/test_f_permutation.v (nonexistent)
+++ sha3/trunk/low_throughput_core/testbench/test_f_permutation.v (revision 6)
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2013, Homer Hsing
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* test "f permutation".
+ * write a block, wait 3 cycles, write another block, do not wait, write the third block */
+
+`timescale 1ns / 1ps
+`define P 20
+
+module test_f_permutation;
+
+ // Inputs
+ reg clk;
+ reg reset;
+ reg [575:0] in;
+ reg in_ready;
+
+ // Outputs
+ wire ack;
+ wire [1599:0] out;
+ wire out_ready;
+
+ integer i;
+
+ // Instantiate the Unit Under Test (UUT)
+ f_permutation uut (
+ .clk(clk),
+ .reset(reset),
+ .in(in),
+ .in_ready(in_ready),
+ .ack(ack),
+ .out(out),
+ .out_ready(out_ready)
+ );
+
+ initial begin
+ // Initialize Inputs
+ clk = 0;
+ reset = 1;
+ in = 0;
+ in_ready = 0;
+
+ // Wait 100 ns for global reset to finish
+ #100;
+
+ // Add stimulus here
+ @ (negedge clk);
+ if (out !== 0) error; /* should be 0 */
+ if (ack !== 0) error; /* should be 0 */
+ if (out_ready !== 0) error; /* should be 0 */
+
+ #(`P);
+ reset = 0;
+ in = 0;
+ in_ready = 1;
+ #(`P);
+ if (out_ready !== 0) error; /* should be 0 */
+ in_ready = 0;
+
+ /* check 1~22-th cycles */
+ for(i=0; i<22; i=i+1)
+ begin
+ if (out === 0) error; /* should not be 0 */
+ if (ack !== 0) error; /* should be 0 */
+ if (out_ready !== 0) error; /* should be 0 */
+ #(`P);
+ end
+
+ /* check the 23-th cycle */
+ if (out === 0) error; /* should not be 0 */
+ if (ack !== 0) error; /* should be 0 */
+ if (out_ready !== 0) error; /* should be 0 */
+ #(`P);
+
+ /* check the 24-th cycle */
+ #(`P); /* wait out */
+ if (out_ready !== 1) error; /* should be 1 */
+ if(out !== 1600'hf1258f7940e1dde784d5ccf933c0478ad598261ea65aa9eebd1547306f80494d8b284e056253d057ff97a42d7f8e6fd490fee5a0a44647c48c5bda0cd6192e76ad30a6f71b19059c30935ab7d08ffc64eb5aa93f2317d635a9a6e6260d71210381a57c16dbcf555f43b831cd0347c82601f22f1a11a5569f05e5635a21d9ae6164befef28cc970f2613670957bc46611b87c5a554fd00ecb8c3ee88a1ccf32c8940c7922ae3a26141841f924a2c509e416f53526e70465c275f644e97f30a13beaf1ff7b5ceca249) error;
+
+ #(3*`P); /* wait more cycles */
+ if (out_ready !== 1) error; /* should be 1 */
+ /* "out" should not change */
+ if(out !== 1600'hf1258f7940e1dde784d5ccf933c0478ad598261ea65aa9eebd1547306f80494d8b284e056253d057ff97a42d7f8e6fd490fee5a0a44647c48c5bda0cd6192e76ad30a6f71b19059c30935ab7d08ffc64eb5aa93f2317d635a9a6e6260d71210381a57c16dbcf555f43b831cd0347c82601f22f1a11a5569f05e5635a21d9ae6164befef28cc970f2613670957bc46611b87c5a554fd00ecb8c3ee88a1ccf32c8940c7922ae3a26141841f924a2c509e416f53526e70465c275f644e97f30a13beaf1ff7b5ceca249) error;
+
+ in_ready = 1; /* feed in one more block */
+ in = 0;
+ #(`P);
+ if (out_ready !== 0) error; /* should be 0 */
+ in_ready = 0;
+
+ while (out_ready !== 1)
+ #(`P);
+ if(out !== 1600'h2d5c954df96ecb3c6a332cd07057b56d093d8d1270d76b6c8a20d9b25569d0944f9c4f99e5e7f156f957b9a2da65fb3885773dae1275af0dfaf4f247c3d810f71f1b9ee6f79a8759e4fecc0fee98b42568ce61b6b9ce68a1deea66c4ba8f974f33c43d836eafb1f5e00654042719dbd97cf8a9f009831265fd5449a6bf17474397ddad33d8994b4048ead5fc5d0be774e3b8c8ee55b7b03c91a0226e649e42e9900e3129e7badd7b202a9ec5faa3cce85b3402464e1c3db6609f4e62a44c105920d06cd26a8fbf5c) error;
+
+ /* no wait, feed in one more block */
+ in_ready = 1;
+ #(`P);
+ if (out_ready !== 0) error; /* should be 0 */
+ in_ready = 0;
+
+ while (out_ready !== 1)
+ #(`P);
+ if(out !== 1600'h55eabb80767d364686c354c8d01cbace9452d254b0979b3dde59422be2c66f16c660e4f2d4d8212e78414f691b639bb3cbb20f9f1b22e381cf16da5fac2da63f83c0b76552d95f7c44efc84eaf017e1548d380ff3e532c9592436ec5c5e02f05bde57ca1ee8de7e9240970468a1fd1b012a978439cbb7686d26b59fcceff8b4dd2aa0f472110fff87bd44abf53f72551e15ad2b722d00bb7c56095932c792c459e02d1766ad3a79c312f2da72ada4ec368b9f274a8d7d6b92b7239f7e51eea1eb6947f6894d77aeb) error;
+
+ $display("Good!");
+ $finish;
+ end
+
+ always #(`P/2) clk = ~ clk;
+
+ task error;
+ begin
+ $display("Error!");
+ $finish;
+ end
+ endtask
+endmodule
+
+`undef P
/sha3/trunk/low_throughput_core/testbench/test_padder.v
0,0 → 1,197
/* |
* Copyright 2013, Homer Hsing <homer.hsing@gmail.com> |
* |
* Licensed under the Apache License, Version 2.0 (the "License"); |
* you may not use this file except in compliance with the License. |
* You may obtain a copy of the License at |
* |
* http://www.apache.org/licenses/LICENSE-2.0 |
* |
* Unless required by applicable law or agreed to in writing, software |
* distributed under the License is distributed on an "AS IS" BASIS, |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
* See the License for the specific language governing permissions and |
* limitations under the License. |
*/ |
|
`timescale 1ns / 1ps |
`define P 20 |
|
module test_padder; |
|
// Inputs |
reg clk; |
reg reset; |
reg [31:0] in; |
reg in_ready; |
reg is_last; |
reg [1:0] byte_num; |
reg f_ack; |
|
// Outputs |
wire buffer_full; |
wire [575:0] out; |
wire out_ready; |
|
// Var |
integer i; |
|
// Instantiate the Unit Under Test (UUT) |
padder uut ( |
.clk(clk), |
.reset(reset), |
.in(in), |
.in_ready(in_ready), |
.is_last(is_last), |
.byte_num(byte_num), |
.buffer_full(buffer_full), |
.out(out), |
.out_ready(out_ready), |
.f_ack(f_ack) |
); |
|
initial begin |
// Initialize Inputs |
clk = 0; |
reset = 1; |
in = 0; |
in_ready = 0; |
is_last = 0; |
byte_num = 0; |
f_ack = 0; |
|
// Wait 100 ns for global reset to finish |
#100; |
|
// Add stimulus here |
@ (negedge clk); |
|
// pad an empty string, should not eat next input |
reset = 1; #(`P); reset = 0; |
#(7*`P); // wait some cycles |
if (buffer_full !== 0) error; |
in_ready = 1; |
is_last = 1; |
#(`P); |
in_ready = 1; // next input |
is_last = 1; |
#(`P); |
in_ready = 0; |
is_last = 0; |
|
while (out_ready !== 1) |
#(`P); |
check({8'h1, 560'h0, 8'h80}); |
f_ack = 1; #(`P); f_ack = 0; |
for(i=0; i<5; i=i+1) |
begin |
#(`P); |
if (buffer_full !== 0) error; // should be 0 |
end |
|
// pad an (576-8) bit string |
reset = 1; #(`P); reset = 0; |
#(4*`P); // wait some cycles |
in_ready = 1; is_last = 0; |
byte_num = 3; /* should have no effect */ |
for (i=0; i<8; i=i+1) |
begin |
in = 32'h12345678; #(`P); |
in = 32'h90ABCDEF; #(`P); |
end |
in = 32'h12345678; #(`P); |
in = 32'h90ABCDEF; is_last = 1; #(`P); |
in_ready = 0; |
is_last = 0; |
check({ {8{64'h1234567890ABCDEF}}, 64'h1234567890ABCD81 }); |
|
// pad an (576-64) bit string |
reset = 1; #(`P); reset = 0; |
// don't wait any cycle |
in_ready = 1; is_last = 0; |
byte_num = 1; /* should have no effect */ |
for (i=0; i<8; i=i+1) |
begin |
in = 32'h12345678; #(`P); |
in = 32'h90ABCDEF; #(`P); |
end |
is_last = 1; |
byte_num = 0; |
#(`P); |
in_ready = 0; |
is_last = 0; |
#(`P); |
check({ {8{64'h1234567890ABCDEF}}, 64'h0100000000000080 }); |
|
// pad an (576*2-16) bit string |
reset = 1; #(`P); reset = 0; |
in_ready = 1; |
byte_num = 7; /* should have no effect */ |
is_last = 0; |
for (i=0; i<9; i=i+1) |
begin |
in = 32'h12345678; #(`P); |
in = 32'h90ABCDEF; #(`P); |
end |
if (out_ready !== 1) error; |
check({9{64'h1234567890ABCDEF}}); |
#(`P/2); |
if (buffer_full !== 1) error; // should not eat |
#(`P/2); |
in = 64'h999; // should not eat this |
#(`P/2); |
if (buffer_full !== 1) error; // should not eat |
#(`P/2); |
f_ack = 1; #(`P); f_ack = 0; |
if (out_ready !== 0) error; |
// feed next (576-16) bit |
for (i=0; i<8; i=i+1) |
begin |
in = 32'h12345678; #(`P); |
in = 32'h90ABCDEF; #(`P); |
end |
in = 32'h12345678; #(`P); |
byte_num = 2; |
is_last = 1; |
in = 32'h90ABCDEF; #(`P); |
if (out_ready !== 1) error; |
check({ {8{64'h1234567890ABCDEF}}, 64'h1234567890AB0180 }); |
is_last = 0; |
// eat these bits |
f_ack = 1; #(`P); f_ack = 0; |
// should not provide any more bits, if user provides nothing |
in_ready = 0; |
is_last = 0; |
for (i=0; i<10; i=i+1) |
begin |
if (out_ready === 1) error; |
#(`P); |
end |
in_ready = 0; |
|
$display("Good!"); |
$finish; |
end |
|
always #(`P/2) clk = ~ clk; |
|
task error; |
begin |
$display("E"); |
$finish; |
end |
endtask |
|
task check; |
input [575:0] wish; |
begin |
if (out !== wish) |
begin |
$display("out:%h wish:%h", out, wish); |
error; |
end |
end |
endtask |
endmodule |
|
`undef P |
/sha3/trunk/low_throughput_core/testbench/test_padder1.v
0,0 → 1,76
/* |
* Copyright 2013, Homer Hsing <homer.hsing@gmail.com> |
* |
* Licensed under the Apache License, Version 2.0 (the "License"); |
* you may not use this file except in compliance with the License. |
* You may obtain a copy of the License at |
* |
* http://www.apache.org/licenses/LICENSE-2.0 |
* |
* Unless required by applicable law or agreed to in writing, software |
* distributed under the License is distributed on an "AS IS" BASIS, |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
* See the License for the specific language governing permissions and |
* limitations under the License. |
*/ |
|
`timescale 1ns / 1ps |
`define P 20 |
|
module test_padder1; |
|
// Inputs |
reg [31:0] in; |
reg [1:0] byte_num; |
|
// Outputs |
wire [31:0] out; |
|
reg [31:0] wish; |
|
// Instantiate the Unit Under Test (UUT) |
padder1 uut ( |
.in(in), |
.byte_num(byte_num), |
.out(out) |
); |
|
initial begin |
// Initialize Inputs |
in = 0; |
byte_num = 0; |
|
// Wait 100 ns for global reset to finish |
#100; |
|
// Add stimulus here |
in = 32'h90ABCDEF; |
byte_num = 0; |
wish = 32'h01000000; |
check; |
byte_num = 1; |
wish = 32'h90010000; |
check; |
byte_num = 2; |
wish = 32'h90AB0100; |
check; |
byte_num = 3; |
wish = 32'h90ABCD01; |
check; |
$display("Good!"); |
$finish; |
end |
|
task check; |
begin |
#(`P); |
if (out !== wish) |
begin |
$display("E"); |
$finish; |
end |
end |
endtask |
endmodule |
|
`undef P |
/sha3/trunk/low_throughput_core/testbench/test_keccak.v
0,0 → 1,257
/* |
* Copyright 2013, Homer Hsing <homer.hsing@gmail.com> |
* |
* Licensed under the Apache License, Version 2.0 (the "License"); |
* you may not use this file except in compliance with the License. |
* You may obtain a copy of the License at |
* |
* http://www.apache.org/licenses/LICENSE-2.0 |
* |
* Unless required by applicable law or agreed to in writing, software |
* distributed under the License is distributed on an "AS IS" BASIS, |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
* See the License for the specific language governing permissions and |
* limitations under the License. |
*/ |
|
`timescale 1ns / 1ps |
`define P 20 |
|
module test_keccak; |
|
// Inputs |
reg clk; |
reg reset; |
reg [31:0] in; |
reg in_ready; |
reg is_last; |
reg [1:0] byte_num; |
|
// Outputs |
wire buffer_full; |
wire [511:0] out; |
wire out_ready; |
|
// Var |
integer i; |
|
// Instantiate the Unit Under Test (UUT) |
keccak uut ( |
.clk(clk), |
.reset(reset), |
.in(in), |
.in_ready(in_ready), |
.is_last(is_last), |
.byte_num(byte_num), |
.buffer_full(buffer_full), |
.out(out), |
.out_ready(out_ready) |
); |
|
initial begin |
// Initialize Inputs |
clk = 0; |
reset = 0; |
in = 0; |
in_ready = 0; |
is_last = 0; |
byte_num = 0; |
|
// Wait 100 ns for global reset to finish |
#100; |
|
// Add stimulus here |
@ (negedge clk); |
|
// SHA3-512("The quick brown fox jumps over the lazy dog") |
reset = 1; #(`P); reset = 0; |
in_ready = 1; is_last = 0; |
in = "The "; #(`P); |
in = "quic"; #(`P); |
in = "k br"; #(`P); |
in = "own "; #(`P); |
in = "fox "; #(`P); |
in = "jump"; #(`P); |
in = "s ov"; #(`P); |
in = "er t"; #(`P); |
in = "he l"; #(`P); |
in = "azy "; #(`P); |
in = "dog "; byte_num = 3; is_last = 1; #(`P); /* !!! not in = "dog" */ |
in_ready = 0; is_last = 0; |
while (out_ready !== 1) |
#(`P); |
check(512'hd135bb84d0439dbac432247ee573a23ea7d3c9deb2a968eb31d47c4fb45f1ef4422d6c531b5b9bd6f449ebcc449ea94d0a8f05f62130fda612da53c79659f609); |
|
// SHA3-512("The quick brown fox jumps over the lazy dog.") |
reset = 1; #(`P); reset = 0; |
in_ready = 1; is_last = 0; |
in = "The "; #(`P); |
in = "quic"; #(`P); |
in = "k br"; #(`P); |
in = "own "; #(`P); |
in = "fox "; #(`P); |
in = "jump"; #(`P); |
in = "s ov"; #(`P); |
in = "er t"; #(`P); |
in = "he l"; #(`P); |
in = "azy "; #(`P); |
in = "dog."; #(`P); |
in = 0; byte_num = 0; is_last = 1; #(`P); /* !!! */ |
in_ready = 0; is_last = 0; |
while (out_ready !== 1) |
#(`P); |
check(512'hab7192d2b11f51c7dd744e7b3441febf397ca07bf812cceae122ca4ded6387889064f8db9230f173f6d1ab6e24b6e50f065b039f799f5592360a6558eb52d760); |
|
// hash an string "\xA1\xA2\xA3\xA4\xA5", len == 5 |
reset = 1; #(`P); reset = 0; |
#(7*`P); // wait some cycles |
in_ready = 1; is_last = 0; byte_num = 1; |
in = 32'hA1A2A3A4; |
#(`P); |
is_last = 1; byte_num = 1; |
in = 32'hA5000000; |
#(`P); |
in = 32'h12345678; // next input |
in_ready = 1; |
is_last = 1; |
#(`P/2); |
if (buffer_full === 1) error; // should be 0 |
#(`P/2); |
in_ready = 0; |
is_last = 0; |
|
while (out_ready !== 1) |
#(`P); |
check(512'h12f4a85b68b091e8836219e79dfff7eb9594a42f5566515423b2aa4c67c454de83a62989e44b5303022bfe8c1a9976781b747a596cdab0458e20d8750df6ddfb); |
for(i=0; i<5; i=i+1) |
begin |
#(`P); |
if (buffer_full !== 0) error; // should keep 0 |
end |
|
// hash an empty string, should not eat next input |
reset = 1; #(`P); reset = 0; |
#(7*`P); // wait some cycles |
in = 32'h12345678; // should not be eat |
byte_num = 0; |
in_ready = 1; |
is_last = 1; |
#(`P); |
in = 32'hddddd; // should not be eat |
in_ready = 1; // next input |
is_last = 1; |
#(`P); |
in_ready = 0; |
is_last = 0; |
|
while (out_ready !== 1) |
#(`P); |
check(512'h0eab42de4c3ceb9235fc91acffe746b29c29a8c366b7c60e4e67c466f36a4304c00fa9caf9d87976ba469bcbe06713b435f091ef2769fb160cdab33d3670680e); |
for(i=0; i<5; i=i+1) |
begin |
#(`P); |
if (buffer_full !== 0) error; // should keep 0 |
end |
|
// hash an (576-8) bit string |
reset = 1; #(`P); reset = 0; |
#(4*`P); // wait some cycles |
in_ready = 1; |
byte_num = 3; /* should have no effect */ |
is_last = 0; |
for (i=0; i<8; i=i+1) |
begin |
in = 32'hEFCDAB90; #(`P); |
in = 32'h78563412; #(`P); |
end |
in = 32'hEFCDAB90; #(`P); |
in = 32'h78563412; is_last = 1; #(`P); |
in_ready = 0; |
is_last = 0; |
while (out_ready !== 1) |
#(`P); |
check(512'hf7f6b44069dba8900b6711ffcbe40523d4bb718cc8ed7f0a0bd28a1b18ee9374359f0ca0c9c1e96fcfca29ee2f282b46d5045eff01f7a7549eaa6b652cbf6270); |
|
// pad an (576-64) bit string |
reset = 1; #(`P); reset = 0; |
// don't wait any cycle |
in_ready = 1; |
byte_num = 7; /* should have no effect */ |
is_last = 0; |
for (i=0; i<8; i=i+1) |
begin |
in = 32'hEFCDAB90; #(`P); |
in = 32'h78563412; #(`P); |
end |
is_last = 1; |
byte_num = 0; |
#(`P); |
in_ready = 0; |
is_last = 0; |
in = 0; |
while (out_ready !== 1) |
#(`P); |
check(512'hccd91653872c106f6eea1b8b68a4c2901c8d9bed9c180201f8a6144e7e6e6c251afcb6f6da44780b2d9aabff254036664719425469671f7e21fb67e5280a27ed); |
|
// pad an (576*2-16) bit string |
reset = 1; #(`P); reset = 0; |
in_ready = 1; |
byte_num = 1; /* should have no effect */ |
is_last = 0; |
for (i=0; i<9; i=i+1) |
begin |
in = 32'hEFCDAB90; #(`P); |
in = 32'h78563412; #(`P); |
end |
#(`P/2); |
if (buffer_full !== 1) error; // should not eat |
#(`P/2); |
in = 32'h999; // should not eat this |
in_ready = 0; |
#(`P/2); |
if (buffer_full !== 0) error; // should not eat, but buffer should not be full |
#(`P/2); |
#(`P); |
// feed next (576-16) bit |
in_ready = 1; |
for (i=0; i<8; i=i+1) |
begin |
in = 32'hEFCDAB90; #(`P); |
in = 32'h78563412; #(`P); |
end |
in = 32'hEFCDAB90; #(`P); |
byte_num = 2; |
is_last = 1; |
in = 32'h78563412; |
#(`P); |
is_last = 0; |
in_ready = 0; |
while (out_ready !== 1) |
#(`P); |
check(512'h0f385323604e279251e80f928cfd9ce9492ba5df775063ea106eebe2a2c7785a3e33b4397fca66e90f67470334c66ea12016cb1f06170b9b033f158a7c01933e); |
|
$display("Good!"); |
$finish; |
end |
|
always #(`P/2) clk = ~ clk; |
|
task error; |
begin |
$display("E"); |
$finish; |
end |
endtask |
|
task check; |
input [511:0] wish; |
begin |
if (out !== wish) |
begin |
$display("%h %h", out, wish); error; |
end |
end |
endtask |
endmodule |
|
`undef P |
/sha3/trunk/low_throughput_core/testbench/simulation.do
0,0 → 1,16
vlib work |
vlog -lint ../rtl/*.v |
vlog -lint *.v |
vsim -novopt test_keccak |
add wave -noupdate -format Logic -radix unsigned /test_keccak/clk |
add wave -noupdate -format Logic -radix unsigned /test_keccak/reset |
add wave -noupdate -divider input |
add wave -noupdate -format Literal -radix hexadecimal /test_keccak/in |
add wave -noupdate -format Literal -radix unsigned /test_keccak/byte_num |
add wave -noupdate -format Literal -radix unsigned /test_keccak/in_ready |
add wave -noupdate -format Literal -radix unsigned /test_keccak/is_last |
add wave -noupdate -divider output |
add wave -noupdate -format Literal -radix unsigned /test_keccak/ack |
add wave -noupdate -format Literal -radix hexadecimal /test_keccak/out |
add wave -noupdate -format Literal -radix unsigned /test_keccak/out_ready |
run -all |
/sha3/trunk/low_throughput_core/testbench/Read_Me.txt
0,0 → 1,9
How to start the simulation |
|
1. simulation.do |
---------------- |
This file is a batch file for Modelsim to compile the HDL files, setup the wave file, and begin function simulation. The working directory of Modelsim must be the same directory of the batch file. |
|
2. test_keccak.v |
---------------------- |
This file is the main test bench. It is self-checked. It feeds input data to the core and compare the correct result with the output of the core. If the output is wrong, the test bench will display an error message. |
/sha3/trunk/low_throughput_core/testbench/test_rconst.v
0,0 → 1,121
/* |
* Copyright 2013, Homer Hsing <homer.hsing@gmail.com> |
* |
* Licensed under the Apache License, Version 2.0 (the "License"); |
* you may not use this file except in compliance with the License. |
* You may obtain a copy of the License at |
* |
* http://www.apache.org/licenses/LICENSE-2.0 |
* |
* Unless required by applicable law or agreed to in writing, software |
* distributed under the License is distributed on an "AS IS" BASIS, |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
* See the License for the specific language governing permissions and |
* limitations under the License. |
*/ |
|
`timescale 1ns / 1ps |
`define P 20 |
|
module test_rconst; |
|
// Inputs |
reg [23:0] i; |
|
// Outputs |
wire [63:0] rc; |
|
// Instantiate the Unit Under Test (UUT) |
rconst uut ( |
.i(i), |
.rc(rc) |
); |
|
initial begin |
// Initialize Inputs |
i = 0; |
|
// Wait 100 ns for global reset to finish |
#100; |
|
// Add stimulus here |
i=0; i[0] = 1; |
#(`P); |
if(rc !== 64'h1) begin $display("E"); $finish; end |
i=0; i[1] = 1; |
#(`P); |
if(rc !== 64'h8082) begin $display("E"); $finish; end |
i=0; i[2] = 1; |
#(`P); |
if(rc !== 64'h800000000000808a) begin $display("E"); $finish; end |
i=0; i[3] = 1; |
#(`P); |
if(rc !== 64'h8000000080008000) begin $display("E"); $finish; end |
i=0; i[4] = 1; |
#(`P); |
if(rc !== 64'h808b) begin $display("E"); $finish; end |
i=0; i[5] = 1; |
#(`P); |
if(rc !== 64'h80000001) begin $display("E"); $finish; end |
i=0; i[6] = 1; |
#(`P); |
if(rc !== 64'h8000000080008081) begin $display("E"); $finish; end |
i=0; i[7] = 1; |
#(`P); |
if(rc !== 64'h8000000000008009) begin $display("E"); $finish; end |
i=0; i[8] = 1; |
#(`P); |
if(rc !== 64'h8a) begin $display("E"); $finish; end |
i=0; i[9] = 1; |
#(`P); |
if(rc !== 64'h88) begin $display("E"); $finish; end |
i=0; i[10] = 1; |
#(`P); |
if(rc !== 64'h80008009) begin $display("E"); $finish; end |
i=0; i[11] = 1; |
#(`P); |
if(rc !== 64'h8000000a) begin $display("E"); $finish; end |
i=0; i[12] = 1; |
#(`P); |
if(rc !== 64'h8000808b) begin $display("E"); $finish; end |
i=0; i[13] = 1; |
#(`P); |
if(rc !== 64'h800000000000008b) begin $display("E"); $finish; end |
i=0; i[14] = 1; |
#(`P); |
if(rc !== 64'h8000000000008089) begin $display("E"); $finish; end |
i=0; i[15] = 1; |
#(`P); |
if(rc !== 64'h8000000000008003) begin $display("E"); $finish; end |
i=0; i[16] = 1; |
#(`P); |
if(rc !== 64'h8000000000008002) begin $display("E"); $finish; end |
i=0; i[17] = 1; |
#(`P); |
if(rc !== 64'h8000000000000080) begin $display("E"); $finish; end |
i=0; i[18] = 1; |
#(`P); |
if(rc !== 64'h800a) begin $display("E"); $finish; end |
i=0; i[19] = 1; |
#(`P); |
if(rc !== 64'h800000008000000a) begin $display("E"); $finish; end |
i=0; i[20] = 1; |
#(`P); |
if(rc !== 64'h8000000080008081) begin $display("E"); $finish; end |
i=0; i[21] = 1; |
#(`P); |
if(rc !== 64'h8000000000008080) begin $display("E"); $finish; end |
i=0; i[22] = 1; |
#(`P); |
if(rc !== 64'h80000001) begin $display("E"); $finish; end |
i=0; i[23] = 1; |
#(`P); |
if(rc !== 64'h8000000080008008) begin $display("E"); $finish; end |
|
$display("Good!"); |
$finish; |
end |
|
endmodule |
|
`undef P |
/sha3/trunk/low_throughput_core/rtl/f_permutation.v
0,0 → 1,69
/* |
* Copyright 2013, Homer Hsing <homer.hsing@gmail.com> |
* |
* Licensed under the Apache License, Version 2.0 (the "License"); |
* you may not use this file except in compliance with the License. |
* You may obtain a copy of the License at |
* |
* http://www.apache.org/licenses/LICENSE-2.0 |
* |
* Unless required by applicable law or agreed to in writing, software |
* distributed under the License is distributed on an "AS IS" BASIS, |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
* See the License for the specific language governing permissions and |
* limitations under the License. |
*/ |
|
/* if "ack" is 1, then current input has been used. */ |
|
module f_permutation(clk, reset, in, in_ready, ack, out, out_ready); |
input clk, reset; |
input [575:0] in; |
input in_ready; |
output ack; |
output reg [1599:0] out; |
output reg out_ready; |
|
reg [22:0] i; /* select round constant */ |
wire [1599:0] round_in, round_out; |
wire [63:0] rc; /* round constant */ |
wire update; |
wire accept; |
reg calc; /* == 1: calculating rounds */ |
|
assign accept = in_ready & (~ calc); // in_ready & (i == 0) |
|
always @ (posedge clk) |
if (reset) i <= 0; |
else i <= {i[21:0], accept}; |
|
always @ (posedge clk) |
if (reset) calc <= 0; |
else calc <= (calc & (~ i[22])) | accept; |
|
assign update = calc | accept; |
|
assign ack = accept; |
|
always @ (posedge clk) |
if (reset) |
out_ready <= 0; |
else if (accept) |
out_ready <= 0; |
else if (i[22]) // only change at the last round |
out_ready <= 1; |
|
assign round_in = accept ? {in ^ out[1599:1599-575], out[1599-576:0]} : out; |
|
rconst |
rconst_ ({i, accept}, rc); |
|
round |
round_ (round_in, rc, round_out); |
|
always @ (posedge clk) |
if (reset) |
out <= 0; |
else if (update) |
out <= round_out; |
endmodule |
/sha3/trunk/low_throughput_core/rtl/padder.v
0,0 → 1,88
/* |
* Copyright 2013, Homer Hsing <homer.hsing@gmail.com> |
* |
* Licensed under the Apache License, Version 2.0 (the "License"); |
* you may not use this file except in compliance with the License. |
* You may obtain a copy of the License at |
* |
* http://www.apache.org/licenses/LICENSE-2.0 |
* |
* Unless required by applicable law or agreed to in writing, software |
* distributed under the License is distributed on an "AS IS" BASIS, |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
* See the License for the specific language governing permissions and |
* limitations under the License. |
*/ |
|
/* "is_last" == 0 means byte number is 4, no matter what value "byte_num" is. */ |
/* if "in_ready" == 0, then "is_last" should be 0. */ |
/* the user switch to next "in" only if "ack" == 1. */ |
|
module padder(clk, reset, in, in_ready, is_last, byte_num, buffer_full, out, out_ready, f_ack); |
input clk, reset; |
input [31:0] in; |
input in_ready, is_last; |
input [1:0] byte_num; |
output buffer_full; /* to "user" module */ |
output reg [575:0] out; /* to "f_permutation" module */ |
output out_ready; /* to "f_permutation" module */ |
input f_ack; /* from "f_permutation" module */ |
|
reg state; /* state == 0: user will send more input data |
* state == 1: user will not send any data */ |
reg done; /* == 1: out_ready should be 0 */ |
reg [17:0] i; /* length of "out" buffer */ |
wire [31:0] v0; /* output of module "padder1" */ |
reg [31:0] v1; /* to be shifted into register "out" */ |
wire accept, /* accept user input? */ |
update; |
|
assign buffer_full = i[17]; |
assign out_ready = buffer_full; |
assign accept = (~ state) & in_ready & (~ buffer_full); // if state == 1, do not eat input |
assign update = (accept | (state & (~ buffer_full))) & (~ done); // don't fill buffer if done |
|
always @ (posedge clk) |
if (reset) |
out <= 0; |
else if (update) |
out <= {out[575-32:0], v1}; |
|
always @ (posedge clk) |
if (reset) |
i <= 0; |
else if (f_ack | update) |
i <= {i[16:0], 1'b1} & {18{~ f_ack}}; |
/* if (f_ack) i <= 0; */ |
/* if (update) i <= {i[16:0], 1'b1}; // increase length */ |
|
always @ (posedge clk) |
if (reset) |
state <= 0; |
else if (is_last) |
state <= 1; |
|
always @ (posedge clk) |
if (reset) |
done <= 0; |
else if (state & out_ready) |
done <= 1; |
|
padder1 p0 (in, byte_num, v0); |
|
always @ (*) |
begin |
if (state) |
begin |
v1 = 0; |
v1[7] = v1[7] | i[16]; // "v1[7]" is the MSB of the last byte of "v1" |
end |
else if (is_last == 0) |
v1 = in; |
else |
begin |
v1 = v0; |
v1[7] = v1[7] | i[16]; |
end |
end |
endmodule |
/sha3/trunk/low_throughput_core/rtl/padder1.v
0,0 → 1,37
/* |
* Copyright 2013, Homer Hsing <homer.hsing@gmail.com> |
* |
* Licensed under the Apache License, Version 2.0 (the "License"); |
* you may not use this file except in compliance with the License. |
* You may obtain a copy of the License at |
* |
* http://www.apache.org/licenses/LICENSE-2.0 |
* |
* Unless required by applicable law or agreed to in writing, software |
* distributed under the License is distributed on an "AS IS" BASIS, |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
* See the License for the specific language governing permissions and |
* limitations under the License. |
*/ |
|
/* |
* in byte_num out |
* 0x11223344 0 0x01000000 |
* 0x11223344 1 0x11010000 |
* 0x11223344 2 0x11220100 |
* 0x11223344 3 0x11223301 |
*/ |
|
module padder1(in, byte_num, out); |
input [31:0] in; |
input [1:0] byte_num; |
output reg [31:0] out; |
|
always @ (*) |
case (byte_num) |
0: out = 32'h1000000; |
1: out = {in[31:24], 24'h010000}; |
2: out = {in[31:16], 16'h0100}; |
3: out = {in[31:8], 8'h01}; |
endcase |
endmodule |
/sha3/trunk/low_throughput_core/rtl/keccak.v
0,0 → 1,100
/* |
* Copyright 2013, Homer Hsing <homer.hsing@gmail.com> |
* |
* Licensed under the Apache License, Version 2.0 (the "License"); |
* you may not use this file except in compliance with the License. |
* You may obtain a copy of the License at |
* |
* http://www.apache.org/licenses/LICENSE-2.0 |
* |
* Unless required by applicable law or agreed to in writing, software |
* distributed under the License is distributed on an "AS IS" BASIS, |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
* See the License for the specific language governing permissions and |
* limitations under the License. |
*/ |
|
/* "is_last" == 0 means byte number is 8, no matter what value "byte_num" is. */ |
/* if "in_ready" == 0, then "is_last" should be 0. */ |
/* the user switch to next "in" only if "ack" == 1. */ |
|
`define low_pos(w,b) ((w)*64 + (b)*8) |
`define low_pos2(w,b) `low_pos(w,7-b) |
`define high_pos(w,b) (`low_pos(w,b) + 7) |
`define high_pos2(w,b) (`low_pos2(w,b) + 7) |
|
module keccak(clk, reset, in, in_ready, is_last, byte_num, buffer_full, out, out_ready); |
input clk, reset; |
input [31:0] in; |
input in_ready, is_last; |
input [1:0] byte_num; |
output buffer_full; /* to "user" module */ |
output [511:0] out; |
output reg out_ready; |
|
reg state; /* state == 0: user will send more input data |
* state == 1: user will not send any data */ |
wire [575:0] padder_out, |
padder_out_1; /* before reorder byte */ |
wire padder_out_ready; |
wire f_ack; |
wire [1599:0] f_out; |
wire f_out_ready; |
wire [511:0] out1; /* before reorder byte */ |
reg [22:0] i; /* gen "out_ready" */ |
|
genvar w, b; |
|
assign out1 = f_out[1599:1599-511]; |
|
always @ (posedge clk) |
if (reset) |
i <= 0; |
else |
i <= {i[21:0], state & f_ack}; |
|
always @ (posedge clk) |
if (reset) |
state <= 0; |
else if (is_last) |
state <= 1; |
|
/* reorder byte ~ ~ */ |
generate |
for(w=0; w<8; w=w+1) |
begin : L0 |
for(b=0; b<8; b=b+1) |
begin : L1 |
assign out[`high_pos(w,b):`low_pos(w,b)] = out1[`high_pos2(w,b):`low_pos2(w,b)]; |
end |
end |
endgenerate |
|
/* reorder byte ~ ~ */ |
generate |
for(w=0; w<9; w=w+1) |
begin : L2 |
for(b=0; b<8; b=b+1) |
begin : L3 |
assign padder_out[`high_pos(w,b):`low_pos(w,b)] = padder_out_1[`high_pos2(w,b):`low_pos2(w,b)]; |
end |
end |
endgenerate |
|
always @ (posedge clk) |
if (reset) |
out_ready <= 0; |
else if (i[22]) |
out_ready <= 1; |
|
padder |
padder_ (clk, reset, in, in_ready, is_last, byte_num, buffer_full, padder_out_1, padder_out_ready, f_ack); |
|
f_permutation |
f_permutation_ (clk, reset, padder_out, padder_out_ready, f_ack, f_out, f_out_ready); |
endmodule |
|
`undef low_pos |
`undef low_pos2 |
`undef high_pos |
`undef high_pos2 |
/sha3/trunk/low_throughput_core/rtl/round.v
0,0 → 1,171
/* |
* Copyright 2013, Homer Hsing <homer.hsing@gmail.com> |
* |
* Licensed under the Apache License, Version 2.0 (the "License"); |
* you may not use this file except in compliance with the License. |
* You may obtain a copy of the License at |
* |
* http://www.apache.org/licenses/LICENSE-2.0 |
* |
* Unless required by applicable law or agreed to in writing, software |
* distributed under the License is distributed on an "AS IS" BASIS, |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
* See the License for the specific language governing permissions and |
* limitations under the License. |
*/ |
|
`define low_pos(x,y) `high_pos(x,y) - 63 |
`define high_pos(x,y) 1599 - 64*(5*y+x) |
`define add_1(x) (x == 4 ? 0 : x + 1) |
`define add_2(x) (x == 3 ? 0 : x == 4 ? 1 : x + 2) |
`define sub_1(x) (x == 0 ? 4 : x - 1) |
`define rot_up(in, n) {in[63-n:0], in[63:63-n+1]} |
`define rot_up_1(in) {in[62:0], in[63]} |
|
module round(in, round_const, out); |
input [1599:0] in; |
input [63:0] round_const; |
output [1599:0] out; |
|
wire [63:0] a[4:0][4:0]; |
wire [63:0] b[4:0]; |
wire [63:0] c[4:0][4:0], d[4:0][4:0], e[4:0][4:0], f[4:0][4:0], g[4:0][4:0]; |
|
genvar x, y; |
|
/* assign "a[x][y][z] == in[w(5y+x)+z]" */ |
generate |
for(y=0; y<5; y=y+1) |
begin : L0 |
for(x=0; x<5; x=x+1) |
begin : L1 |
assign a[x][y] = in[`high_pos(x,y) : `low_pos(x,y)]; |
end |
end |
endgenerate |
|
/* calc "b[x] == a[x][0] ^ a[x][1] ^ ... ^ a[x][4]" */ |
generate |
for(x=0; x<5; x=x+1) |
begin : L2 |
assign b[x] = a[x][0] ^ a[x][1] ^ a[x][2] ^ a[x][3] ^ a[x][4]; |
end |
endgenerate |
|
/* calc "c == theta(a)" */ |
generate |
for(y=0; y<5; y=y+1) |
begin : L3 |
for(x=0; x<5; x=x+1) |
begin : L4 |
assign c[x][y] = a[x][y] ^ b[`sub_1(x)] ^ `rot_up_1(b[`add_1(x)]); |
end |
end |
endgenerate |
|
/* calc "d == rho(c)" */ |
assign d[0][0] = c[0][0]; |
assign d[1][0] = `rot_up_1(c[1][0]); |
assign d[2][0] = `rot_up(c[2][0], 62); |
assign d[3][0] = `rot_up(c[3][0], 28); |
assign d[4][0] = `rot_up(c[4][0], 27); |
assign d[0][1] = `rot_up(c[0][1], 36); |
assign d[1][1] = `rot_up(c[1][1], 44); |
assign d[2][1] = `rot_up(c[2][1], 6); |
assign d[3][1] = `rot_up(c[3][1], 55); |
assign d[4][1] = `rot_up(c[4][1], 20); |
assign d[0][2] = `rot_up(c[0][2], 3); |
assign d[1][2] = `rot_up(c[1][2], 10); |
assign d[2][2] = `rot_up(c[2][2], 43); |
assign d[3][2] = `rot_up(c[3][2], 25); |
assign d[4][2] = `rot_up(c[4][2], 39); |
assign d[0][3] = `rot_up(c[0][3], 41); |
assign d[1][3] = `rot_up(c[1][3], 45); |
assign d[2][3] = `rot_up(c[2][3], 15); |
assign d[3][3] = `rot_up(c[3][3], 21); |
assign d[4][3] = `rot_up(c[4][3], 8); |
assign d[0][4] = `rot_up(c[0][4], 18); |
assign d[1][4] = `rot_up(c[1][4], 2); |
assign d[2][4] = `rot_up(c[2][4], 61); |
assign d[3][4] = `rot_up(c[3][4], 56); |
assign d[4][4] = `rot_up(c[4][4], 14); |
|
/* calc "e == pi(d)" */ |
assign e[0][0] = d[0][0]; |
assign e[0][2] = d[1][0]; |
assign e[0][4] = d[2][0]; |
assign e[0][1] = d[3][0]; |
assign e[0][3] = d[4][0]; |
assign e[1][3] = d[0][1]; |
assign e[1][0] = d[1][1]; |
assign e[1][2] = d[2][1]; |
assign e[1][4] = d[3][1]; |
assign e[1][1] = d[4][1]; |
assign e[2][1] = d[0][2]; |
assign e[2][3] = d[1][2]; |
assign e[2][0] = d[2][2]; |
assign e[2][2] = d[3][2]; |
assign e[2][4] = d[4][2]; |
assign e[3][4] = d[0][3]; |
assign e[3][1] = d[1][3]; |
assign e[3][3] = d[2][3]; |
assign e[3][0] = d[3][3]; |
assign e[3][2] = d[4][3]; |
assign e[4][2] = d[0][4]; |
assign e[4][4] = d[1][4]; |
assign e[4][1] = d[2][4]; |
assign e[4][3] = d[3][4]; |
assign e[4][0] = d[4][4]; |
|
/* calc "f = chi(e)" */ |
generate |
for(y=0; y<5; y=y+1) |
begin : L5 |
for(x=0; x<5; x=x+1) |
begin : L6 |
assign f[x][y] = e[x][y] ^ ((~ e[`add_1(x)][y]) & e[`add_2(x)][y]); |
end |
end |
endgenerate |
|
/* calc "g = iota(f)" */ |
generate |
for(x=0; x<64; x=x+1) |
begin : L60 |
if(x==0 || x==1 || x==3 || x==7 || x==15 || x==31 || x==63) |
assign g[0][0][x] = f[0][0][x] ^ round_const[x]; |
else |
assign g[0][0][x] = f[0][0][x]; |
end |
endgenerate |
|
generate |
for(y=0; y<5; y=y+1) |
begin : L7 |
for(x=0; x<5; x=x+1) |
begin : L8 |
if(x!=0 || y!=0) |
assign g[x][y] = f[x][y]; |
end |
end |
endgenerate |
|
/* assign "out[w(5y+x)+z] == out_var[x][y][z]" */ |
generate |
for(y=0; y<5; y=y+1) |
begin : L99 |
for(x=0; x<5; x=x+1) |
begin : L100 |
assign out[`high_pos(x,y) : `low_pos(x,y)] = g[x][y]; |
end |
end |
endgenerate |
endmodule |
|
`undef low_pos |
`undef high_pos |
`undef add_1 |
`undef add_2 |
`undef sub_1 |
`undef rot_up |
`undef rot_up_1 |
/sha3/trunk/low_throughput_core/rtl/rconst.v
0,0 → 1,34
/* |
* Copyright 2013, Homer Hsing <homer.hsing@gmail.com> |
* |
* Licensed under the Apache License, Version 2.0 (the "License"); |
* you may not use this file except in compliance with the License. |
* You may obtain a copy of the License at |
* |
* http://www.apache.org/licenses/LICENSE-2.0 |
* |
* Unless required by applicable law or agreed to in writing, software |
* distributed under the License is distributed on an "AS IS" BASIS, |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
* See the License for the specific language governing permissions and |
* limitations under the License. |
*/ |
|
/* round constant */ |
module rconst(i, rc); |
input [23:0] i; |
output reg [63:0] rc; |
|
always @ (i) |
begin |
rc = 0; |
rc[0] = i[0] | i[4] | i[5] | i[6] | i[7] | i[10] | i[12] | i[13] | i[14] | i[15] | i[20] | i[22]; |
rc[1] = i[1] | i[2] | i[4] | i[8] | i[11] | i[12] | i[13] | i[15] | i[16] | i[18] | i[19]; |
rc[3] = i[2] | i[4] | i[7] | i[8] | i[9] | i[10] | i[11] | i[12] | i[13] | i[14] | i[18] | i[19] | i[23]; |
rc[7] = i[1] | i[2] | i[4] | i[6] | i[8] | i[9] | i[12] | i[13] | i[14] | i[17] | i[20] | i[21]; |
rc[15] = i[1] | i[2] | i[3] | i[4] | i[6] | i[7] | i[10] | i[12] | i[14] | i[15] | i[16] | i[18] | i[20] | i[21] | i[23]; |
rc[31] = i[3] | i[5] | i[6] | i[10] | i[11] | i[12] | i[19] | i[20] | i[22] | i[23]; |
rc[63] = i[2] | i[3] | i[6] | i[7] | i[13] | i[14] | i[15] | i[16] | i[17] | i[19] | i[20] | i[21] | i[23]; |
end |
endmodule |
|