OpenCores
URL https://opencores.org/ocsvn/sha3/sha3/trunk

Subversion Repositories sha3

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /sha3
    from Rev 4 to Rev 5
    Reverse comparison

Rev 4 → Rev 5

/trunk/rtl/padder.v File deleted
/trunk/rtl/padder1.v File deleted
/trunk/rtl/keccak.v File deleted
/trunk/rtl/round2in1.v File deleted
/trunk/high_speed_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({64'b1, 448'h0, 1'b1, 63'h0});
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'h8134567890ABCDEF });
 
// 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}}, 1'b1, 62'b0, 1'b1 });
 
// 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'h8001567890ABCDEF });
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
/trunk/high_speed_core/testbench/test_keccak.v
0,0 → 1,214
/*
* 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);
 
// hash an string "\xA1\xA2\xA3\xA4\xA5", len == 5
reset = 1; #(`P); reset = 0;
#(7*`P); // wait some cycles
in = 64'hA5A4A3A2A1;
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'h1234567890ABCDEF;
#(`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'h1234567890ABCDEF;
#(`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'h1234567890ABCDEF; #(`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'h1234567890ABCDEF; #(`P);
end
byte_num = 6;
is_last = 1;
in = 64'h1234567890ABCDEF;
#(`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
/trunk/high_speed_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
/trunk/high_speed_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
/trunk/high_speed_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 = 64'h1;
check;
byte_num = 1;
wish = 64'h1ef;
check;
byte_num = 2;
wish = 64'h1cdef;
check;
byte_num = 3;
wish = 64'h1abcdef;
check;
byte_num = 4;
wish = 64'h190abcdef;
check;
byte_num = 5;
wish = 64'h17890abcdef;
check;
byte_num = 6;
wish = 64'h1567890abcdef;
check;
byte_num = 7;
wish = 64'h134567890abcdef;
check;
$display("Good!");
$finish;
end
 
task check;
begin
#(`P);
if (out !== wish)
begin
$display("E");
$finish;
end
end
endtask
endmodule
 
`undef P
/trunk/high_speed_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
/trunk/high_speed_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.
/trunk/high_speed_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
/trunk/high_speed_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[63] = v1[63] | i[7];
end
else if (is_last == 0)
v1 = in;
else
begin
v1 = v0;
v1[63] = v1[63] | i[7];
end
end
endmodule
/trunk/high_speed_core/rtl/keccak.v
0,0 → 1,87
/*
* 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;
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" */
 
assign out1 = f_out[1599:1599-511];
 
always @ (posedge clk)
if (reset)
i <= 0;
else
i <= (i << 1) | (state & f_ack);
 
always @ (posedge clk)
if (reset)
state <= 0;
else if (is_last)
state <= 1;
 
/* reorder byte ~ ~ */
generate
genvar w, b;
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
 
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, 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
/trunk/high_speed_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
/trunk/high_speed_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'h1;
1: out = {56'h1, in[7:0]};
2: out = {48'h1, in[15:0]};
3: out = {40'h1, in[23:0]};
4: out = {32'h1, in[31:0]};
5: out = {24'h1, in[39:0]};
6: out = {16'h1, in[47:0]};
7: out = {8'h1, in[55:0]};
endcase
endmodule
/trunk/high_speed_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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.