Commit 3acb0fce by Enrico Pozzobon

removing hardware (Verilog and VHDL) implementations

parent 04be7d51

Too many changes to show.

To preserve performance only 1000 of 1000+ files are displayed.

-- This work is licensed under a Creative Commons
-- Attribution-NonCommercial-ShareAlike 4.0 International License.
-- http://creativecommons.org/licenses/by-nc-sa/4.0
-- Mark D. Aagaard
-- Riham AlTawy
-- Guang Gong
-- Kalikinkar Mandal
-- Raghvendra Rohit
-- Marat Sattarov
-- Nusa Zidaric
-- http://uwaterloo.ca/communications-security-lab/lwc/ace
-- This is a human-readable summary of (and not a substitute for) the license.
-- You are free to:
-- Share: copy and redistribute the material in any medium or format
-- Adapt: remix, transform, and build upon the material
-- The licensor cannot revoke these freedoms as long as you follow
-- the license terms.
-- Under the following terms:
-- Attribution — You must give appropriate credit, provide a link to
-- the license, and indicate if changes were made. You may do so in
-- any reasonable manner, but not in any way that suggests the
-- licensor endorses you or your use.
-- NonCommercial — You may not use the material for commercial
-- purposes.
-- ShareAlike — If you remix, transform, or build upon the material,
-- you must distribute your contributions under the same license as
-- the original.
-- No additional restrictions — You may not apply legal terms or
-- technological measures that legally restrict others from doing
-- anything the license permits.
architecture rtl of ace is
signal ctl_control : ace_ctl_ty;
signal ctl_onehot : onehot_ty;
signal ctl_lfsr_en : std_logic;
signal ctl_lfsr_reset : std_logic;
begin
u_dp :
entity work.dp port map
( clk => clk
, reset => reset
, i_mode => i_mode
, i_control => ctl_control
, i_onehot => ctl_onehot
, i_dom_sep => i_dom_sep
, i_valid => i_valid
, i_data => i_data
, i_padding => i_padding
, o_data => o_data
);
u_ctl :
entity work.ctl port map
( clk => clk
, reset => reset
, i_mode => i_mode
, i_dom_sep => i_dom_sep
, i_valid => i_valid
, i_padding => i_padding
, o_valid => o_valid
, o_onehot => ctl_onehot
, o_ready => o_ready
, o_control => ctl_control
);
end architecture;
LIB_VHDL =+ ace_pkg.vhd
TB_ENTITY = ace_tb
TB_ARCH = main
TB_VHDL =+ util_unsynth.vhd
TB_VHDL =+ ace_unsynth.vhd
TB_VHDL =+ ace_tb.vhd
SIM_SCRIPT = ace_tb.sim
DESIGN_ARCH = rtl
DESIGN_ENTITY = ace
DESIGN_VHDL =+ sb_64.vhd
DESIGN_VHDL =+ lfsr_c.vhd
DESIGN_VHDL =+ ctl.vhd
DESIGN_VHDL =+ dp.vhd
ENTITY_VHDL =+ ace.vhd
DESIGN_VHDL =+ ace-rtl.vhd
-- This work is licensed under a Creative Commons
-- Attribution-NonCommercial-ShareAlike 4.0 International License.
-- http://creativecommons.org/licenses/by-nc-sa/4.0
-- Mark D. Aagaard
-- Riham AlTawy
-- Guang Gong
-- Kalikinkar Mandal
-- Raghvendra Rohit
-- Marat Sattarov
-- Nusa Zidaric
-- http://uwaterloo.ca/communications-security-lab/lwc/ace
-- This is a human-readable summary of (and not a substitute for) the license.
-- You are free to:
-- Share: copy and redistribute the material in any medium or format
-- Adapt: remix, transform, and build upon the material
-- The licensor cannot revoke these freedoms as long as you follow
-- the license terms.
-- Under the following terms:
-- Attribution — You must give appropriate credit, provide a link to
-- the license, and indicate if changes were made. You may do so in
-- any reasonable manner, but not in any way that suggests the
-- licensor endorses you or your use.
-- NonCommercial — You may not use the material for commercial
-- purposes.
-- ShareAlike — If you remix, transform, or build upon the material,
-- you must distribute your contributions under the same license as
-- the original.
-- No additional restrictions — You may not apply legal terms or
-- technological measures that legally restrict others from doing
-- anything the license permits.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.ace_pkg.all;
entity ace is
port
( clk : in std_logic;
reset : in std_logic;
i_mode : in mode_ty;
i_dom_sep : in domsep_ty;
i_valid : in std_logic;
i_data : in word;
i_padding : in std_logic;
o_valid : out std_logic;
o_ready : out std_logic;
o_data : out word
);
end entity;
-- This work is licensed under a Creative Commons
-- Attribution-NonCommercial-ShareAlike 4.0 International License.
-- http://creativecommons.org/licenses/by-nc-sa/4.0
-- Mark D. Aagaard
-- Riham AlTawy
-- Guang Gong
-- Kalikinkar Mandal
-- Raghvendra Rohit
-- Marat Sattarov
-- Nusa Zidaric
-- http://uwaterloo.ca/communications-security-lab/lwc/ace
-- This is a human-readable summary of (and not a substitute for) the license.
-- You are free to:
-- Share: copy and redistribute the material in any medium or format
-- Adapt: remix, transform, and build upon the material
-- The licensor cannot revoke these freedoms as long as you follow
-- the license terms.
-- Under the following terms:
-- Attribution — You must give appropriate credit, provide a link to
-- the license, and indicate if changes were made. You may do so in
-- any reasonable manner, but not in any way that suggests the
-- licensor endorses you or your use.
-- NonCommercial — You may not use the material for commercial
-- purposes.
-- ShareAlike — If you remix, transform, or build upon the material,
-- you must distribute your contributions under the same license as
-- the original.
-- No additional restrictions — You may not apply legal terms or
-- technological measures that legally restrict others from doing
-- anything the license permits.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
package ace_pkg is
--for constants
constant lfsr_c_sz : integer := 7;
subtype lfsr_c_output is std_logic_vector(0 to lfsr_c_sz+2);
------------------------------------------------------------
constant half_word_sz : natural := 32;
constant word_sz : natural := 2*half_word_sz;
subtype half_word is std_logic_vector( 0 to half_word_sz - 1 );
subtype word is std_logic_vector( 0 to word_sz - 1 );
type word_vector is array( natural range <> ) of word;
type half_word_vector is array( natural range <> ) of half_word;
------------------------------------------------------------
-- A, B, C, D, E
constant state_sz : natural := 320;
constant word_max_idx : natural := state_sz / word_sz - 1;
constant half_word_max_idx : natural := state_sz / half_word_sz - 1;
constant key_sz : natural := 128;
constant nonce_sz : natural := 128;
subtype word_state_ty is word_vector ( 0 to word_max_idx );
constant a_idx : natural := 0;
constant b_idx : natural := 1;
constant c_idx : natural := 2;
constant d_idx : natural := 3;
constant e_idx : natural := 4;
subtype half_word_data is half_word_vector ( 0 to 1 );
subtype half_word_state_ty is half_word_vector ( 0 to half_word_max_idx );
constant a0_idx : natural := 1;
constant a1_idx : natural := 0;
constant b0_idx : natural := 3;
constant b1_idx : natural := 2;
constant c0_idx : natural := 5;
constant c1_idx : natural := 4;
constant d0_idx : natural := 7;
constant d1_idx : natural := 6;
constant e0_idx : natural := 9;
constant e1_idx : natural := 8;
function b2x( b : boolean ) return std_logic;
function half_words_to_words( st : half_word_state_ty ) return word_state_ty;
function words_to_half_words( st : word_state_ty ) return half_word_state_ty;
------------------------------------------------------------
-- mode
subtype mode_ty is std_logic_vector( 1 downto 0 ); -- top lvl input
constant encrypt_mode : mode_ty := ( 1 => '0', 0 => '0' );
constant decrypt_mode : mode_ty := ( 1 => '0', 0 => '1' );
constant absorb_mode : mode_ty := ( 1 => '1', 0 => '0' );
constant squeeze_mode : mode_ty := ( 1 => '1', 0 => '1' );
subtype domsep_ty is std_logic_vector( 1 downto 0 ); -- top lvl input
-- derived control (from counter and more)
subtype ace_ctl_ty is std_logic_vector( 7 downto 0 );
constant absorb_idx : natural := 0;
constant replace_idx : natural := 1;
constant output_idx : natural := 2;
constant endstep_idx : natural := 3;
constant permoff_idx : natural := 4;
constant squeeze_idx : natural := 5;
constant lfsr_c_reset_idx : natural := 6;
constant lfsr_c_en_idx : natural := 7;
-- extras cntl for load, init, fin, tag, sqeeze
subtype onehot_ty is std_logic_vector( 3 downto 0); -- extrs cntl for load, init, fin, tag, sqeeze
------------------------------------------------------------
-- round and step counters
-- use last bit for end ACE perm - for o_ready
-- -> i_valid will reset the counter!
-- counter only runs if msb = 0
constant bits_counter : natural := 8;
subtype count_ty is unsigned( bits_counter - 1 downto 0 );
----------------------------------------------------------------------
-- standard vhdl operators
-- function "sll"( a : half_word; n : natural ) return half_word;
function onehot_rotate (a : onehot_ty) return onehot_ty;
function vector_to_data ( st : half_word_data ) return word;
function data_to_vector ( st : word ) return half_word_data;
----------------------------------------------------------------------
end package;
----------------------------------------------------------------------
--
----------------------------------------------------------------------
package body ace_pkg is
function onehot_rotate (a : onehot_ty)
return onehot_ty
is
variable z : onehot_ty;
begin
z(onehot_ty'high downto 1) := a(onehot_ty'high - 1 downto 0);
z(0) := a(onehot_ty'high);
return z;
end function;
function b2x( b : boolean ) return std_logic is
begin
if b then
return '1';
else
return '0';
end if;
end function;
------------------------------------------------------------
-- standard vhdl operators cast to state
------------------------------------------------------------
-- function "sll"( a : half_word; n : natural ) return half_word is
-- begin
-- return half_word( std_logic_vector( a ) sll n );
-- end function;
------------------------------------------------------------
-- state functions
------------------------------------------------------------
function half_words_to_words( st : half_word_state_ty ) ---- CHECK THIS!!!!!! PLEASE
return word_state_ty
is
variable i : natural;
variable z : word_state_ty;
begin
main_loop : for i in 0 to word_max_idx loop
z(i)(0 to half_word_sz - 1) := st(2*i);
z(i)(half_word_sz to word_sz - 1) := st(2*i+1);
end loop;
return z;
end function;
function words_to_half_words( st : word_state_ty )
return half_word_state_ty
is
variable i : natural;
variable z : half_word_state_ty;
begin
main_loop : for i in 0 to word_max_idx loop
z(2*i) := st(i)(0 to half_word_sz - 1);
z(2*i+1) := st(i)(half_word_sz to word_sz - 1);
end loop;
return z;
end function;
function data_to_vector( st : word )
return half_word_data
is
variable z : half_word_data;
begin
z(0) := st(0 to half_word_sz - 1);
z(1) := st(half_word_sz to word_sz - 1);
return z;
end function;
function vector_to_data( st : half_word_data )
return word
is
variable z : word;
begin
z(0 to half_word_sz - 1) := st(0);
z(half_word_sz to word_sz - 1) := st(1);
return z;
end function;
end package body;
if { $gui_mode } {
add wave clk
add wave reset
add wave i_mode
add wave i_dom_sep
add wave o_ready
add wave i_valid
add wave i_data
add wave i_padding
add wave o_valid
add wave o_data
if { $sim_mode eq "PROG_MODE" } then {
add wave -noupdate -divider -height 32 STUFF
add wave /uut/u_ctl/state
add wave /uut/u_ctl/o_ready
add wave /uut/u_ctl/i_valid
add wave /uut/u_dp/i_data
add wave /uut/u_ctl/o_valid
add wave /uut/u_dp/o_data
add wave -noupdate -divider -height 32 DP
add wave -radix binary /uut/u_dp/ctl_const
add wave /uut/u_dp/i_data
add wave /uut/u_dp/o_data
add wave -radix binary /uut/u_dp/ctl_const
add wave /uut/u_dp/lfsr_c_en
add wave /uut/u_dp/lfsr_c_reset
add wave /uut/u_dp/permoff
add wave /uut/u_dp/endstep
add wave /uut/u_dp/absorb
add wave /uut/u_dp/replace
add wave /uut/u_dp/output
add wave /uut/u_dp/dsxor
add wave /uut/u_dp/post_input
add wave /uut/u_dp/pre_round
add wave /uut/u_dp/post_round
add wave /uut/u_dp/post_xor
add wave /uut/u_dp/post_step_const
add wave /uut/u_dp/post_linear
add wave /uut/u_dp/ace_path
add wave /uut/u_dp/ace_state
add wave -noupdate -divider -height 32 CTL
add wave /uut/u_ctl/state
add wave -radix unsigned /uut/u_ctl/count
add wave /uut/u_ctl/i_valid
add wave /uut/u_ctl/o_valid
add wave /uut/u_ctl/o_ready
add wave -radix binary /uut/u_ctl/onehot
add wave /uut/u_ctl/lfsr_c_reset
add wave -radix binary /uut/u_ctl/i_mode
add wave -radix binary /uut/u_ctl/i_dom_sep
}
}
vcd file uw_tmp/ace.vcd
vcd add /ace_tb/uut/*
vcd add -r *
vcd on
run -all
vcd checkpoint
vcd off
vcd flush
if { $gui_mode } {
wave zoom full
} else {
exit
}
**** Line 63 (old) / 63 (new) ****
Description:
Moved EDH to the list of generics
Change:
; EDH : std_logic_vector(0 to 2) := "111" -- ENCRYPTION, DECRYPTION, HASH bits. example: 'xx0' = don't do HASH, 'xx1' = do HASH
**** Line 68 (old) / 69 (new) ****
Description:
Removed EDH signal declaration
**** Line 91,96 (old) / 92,98 (new) ****
Description:
Added new signal declarations to delay primary inputs after clock edge
Change:
signal i_mode_buf : mode_ty;
signal i_dom_sep_buf : domsep_ty;
**** Line 114 (old) / 117 - 125 (new) ****
Description:
added new processes to delay a change in primary inputs after clock edge
Change:
i_dom_sep_proc : process(i_dom_sep_buf)
begin
i_dom_sep <= i_dom_sep_buf after hold;
end process;
i_mode_proc : process(i_mode_buf)
begin
i_mode <= i_mode_buf after hold;
end process;
**** Line 199 (old) / 212 (new) ****
**** Line 285 (old) / 304 (new) ****
**** Line 370 (old) / 395 (new) ****
**** Line 390 (old) / 416 (new) ****
Description:
changed signal name
Change:
was
i_mode
now
i_mode_buf
**** Line 216 (old) / 229 (new) ****
**** Line 226 (old) / 241 (new) ****
**** Line 234 (old) / 250 (new) ****
**** Line 239 (old) / 256 (new) ****
**** Line 265 (old) / 284 (new) ****
**** Line 303 (old) / 322 (new) ****
**** Line 314 (old) / 335 (new) ****
**** Line 324 (old) / 346 (new) ****
**** Line 330 (old) / 353 (new) ****
**** Line 358 (old) / 383 (new) ****
**** Line 382 (old) / 406 (new) ****
Description:
changed signal name
Change:
was
i_dom_sep
now
i_dom_sep_buf
**** Line 202 (old) / 215 (new) ****
**** Line 287 (old) / 306 (new) ****
**** Line 372 (old) / 396 (new) ****
**** Line 387 (old) / 413 (new) ****
Description:
Hold statements are now in ace_unsynth.vhd
Change:
removed
wait for hold;
**** Line 383 (old) / 407 (new) ****
Description
Added a report
Change:
report( "HASH DRIVE ALL" );
**** Line 130 (old), 132 (new) ****
**** Line 198 (old), 200 (new) ****
**** Line 227 (old), 230 (new) ****
Description:
added a hold statement to delay primary inputs from clock edge
Change:
wait for hold;
The file dp_pure.vhd was removed from the submission, because it is not part of the functional complete cipher.
-- This work is licensed under a Creative Commons
-- Attribution-NonCommercial-ShareAlike 4.0 International License.
-- http://creativecommons.org/licenses/by-nc-sa/4.0
-- Mark D. Aagaard
-- Riham AlTawy
-- Guang Gong
-- Kalikinkar Mandal
-- Raghvendra Rohit
-- Marat Sattarov
-- Nusa Zidaric
-- http://uwaterloo.ca/communications-security-lab/lwc/ace
-- This is a human-readable summary of (and not a substitute for) the license.
-- You are free to:
-- Share: copy and redistribute the material in any medium or format
-- Adapt: remix, transform, and build upon the material
-- The licensor cannot revoke these freedoms as long as you follow
-- the license terms.
-- Under the following terms:
-- Attribution — You must give appropriate credit, provide a link to
-- the license, and indicate if changes were made. You may do so in
-- any reasonable manner, but not in any way that suggests the
-- licensor endorses you or your use.
-- NonCommercial — You may not use the material for commercial
-- purposes.
-- ShareAlike — If you remix, transform, or build upon the material,
-- you must distribute your contributions under the same license as
-- the original.
-- No additional restrictions — You may not apply legal terms or
-- technological measures that legally restrict others from doing
-- anything the license permits.
library ieee;
use ieee.std_logic_1164.all;
use work.ace_pkg.all;
entity lfsr_c is
port
( clk : in std_logic
; lfsr_c_en : in std_logic
; lfsr_c_reset : in std_logic
; o_const : out lfsr_c_output
);
end lfsr_c;
architecture rtl of lfsr_c is
signal sa: std_logic_vector(lfsr_c_sz - 1 downto 0);
signal xa: std_logic_vector(lfsr_c_sz + 2 downto 0);
begin
-- 10 output bits for the constants
o_const <= xa; -- "to" type <= "downto" type. Index flip intended
-- just rename signal
xa(lfsr_c_sz-1 downto 0) <= sa(lfsr_c_sz-1 downto 0);
-- for updates and outputs
xa(lfsr_c_sz + 2 downto lfsr_c_sz) <= xa(3 downto 1) xor xa(2 downto 0);
lfsr_shift: for i in lfsr_c_sz-1 downto 0 generate
lfsr_step: process(clk) begin
if rising_edge(clk) then
if lfsr_c_reset ='1' then
sa(i) <= '1';
elsif lfsr_c_en ='1' then
sa(i) <= xa(i+3);
end if;
end if;
end process;
end generate lfsr_shift;
end;
------------ ACE readme file ---------------
----- list of files for ACE synthesis: -----
ace_pkg.vhd -- main package
sb_64.vhd -- s-box with simeck
lfsr.vhd -- lfsr for step / round constant generation
ctl.vhd -- control (FSM)
dp.vhd -- datapath
ace.vhd -- top level entity declaration
ace-rtl.vhd -- top level architecture
----- additional files for simulation: -----
util_unsynth.vhd -- functions used in TB (general purpose)
ace_unsynth.vhd -- specific ACE functions and procedures used in TB
ace_tb.vhd -- ACE testbench
-------------- pure datapath ---------------
dp_pure.vhd -- datapath with most input/output multiplexers removed
----------- TB info (ace_tb.vhd): ----------
********
EDH is a 3-bit constant used to select which modes to test
"100" - encryption only
"010" - decyption only
"001" - hash only
"110" - encryption and decryption
etc.
********
stim_file_path -- stimulus file
output_file_path -- output file
********
------------ stimulus file format --------------
1 file = 1 set of Key, Nonce, AD, Plaintext and Ciphertext
K 00111122335588DD00111122335588DD <--- 128 bits of Key (all 128 bits in a single line)
N 111122335588DD00111122335588DD00 <--- 128 bits of Nonce (all 128 bits in a single line)
A 1122335588DD00111122335588DD00 <--- from 4 to 128 bits of AD
P 335588DD00111122335588DD001111 <--- from 4 to 128 bits of Plaintext
C F9362385DC213A07CEFEF38C34CEFF <--- from 4 to 128 bits of Ciphertext
--- padding is done by testbench
--- multiple lines for AD, Plaintext and Ciphertext are supported
-- This work is licensed under a Creative Commons
-- Attribution-NonCommercial-ShareAlike 4.0 International License.
-- http://creativecommons.org/licenses/by-nc-sa/4.0
-- Mark D. Aagaard
-- Riham AlTawy
-- Guang Gong
-- Kalikinkar Mandal
-- Raghvendra Rohit
-- Marat Sattarov
-- Nusa Zidaric
-- http://uwaterloo.ca/communications-security-lab/lwc/ace
-- This is a human-readable summary of (and not a substitute for) the license.
-- You are free to:
-- Share: copy and redistribute the material in any medium or format
-- Adapt: remix, transform, and build upon the material
-- The licensor cannot revoke these freedoms as long as you follow
-- the license terms.
-- Under the following terms:
-- Attribution — You must give appropriate credit, provide a link to
-- the license, and indicate if changes were made. You may do so in
-- any reasonable manner, but not in any way that suggests the
-- licensor endorses you or your use.
-- NonCommercial — You may not use the material for commercial
-- purposes.
-- ShareAlike — If you remix, transform, or build upon the material,
-- you must distribute your contributions under the same license as
-- the original.
-- No additional restrictions — You may not apply legal terms or
-- technological measures that legally restrict others from doing
-- anything the license permits.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.ace_pkg.all;
entity sb_64 is
port
( i_state : in word
; i_rc : in std_logic
; o_state : out word
);
end entity;
architecture rtl of sb_64 is
signal x0, x1, z0, z1 : half_word;
signal rc : half_word;
begin
x1 <= i_state( 0 to half_word_sz-1 );
x0 <= i_state( half_word_sz to word_sz - 1 );
rc <= ( 0 to half_word_sz - 2 => '1', half_word_sz - 1 => i_rc );
z0 <= x1;
z1 <= ( ( x1(5 to half_word_sz - 1) & x1 (0 to 4) ) and x1)
xor ( x1(1 to half_word_sz - 1) & x1 (0) )
xor x0
xor rc;
o_state <= z1 & z0;
end architecture;
-- This work is licensed under a Creative Commons
-- Attribution-NonCommercial-ShareAlike 4.0 International License.
-- http://creativecommons.org/licenses/by-nc-sa/4.0
-- Mark D. Aagaard
-- Riham AlTawy
-- Guang Gong
-- Kalikinkar Mandal
-- Raghvendra Rohit
-- Marat Sattarov
-- Nusa Zidaric
-- http://uwaterloo.ca/communications-security-lab/lwc/ace
-- This is a human-readable summary of (and not a substitute for) the license.
-- You are free to:
-- Share: copy and redistribute the material in any medium or format
-- Adapt: remix, transform, and build upon the material
-- The licensor cannot revoke these freedoms as long as you follow
-- the license terms.
-- Under the following terms:
-- Attribution — You must give appropriate credit, provide a link to
-- the license, and indicate if changes were made. You may do so in
-- any reasonable manner, but not in any way that suggests the
-- licensor endorses you or your use.
-- NonCommercial — You may not use the material for commercial
-- purposes.
-- ShareAlike — If you remix, transform, or build upon the material,
-- you must distribute your contributions under the same license as
-- the original.
-- No additional restrictions — You may not apply legal terms or
-- technological measures that legally restrict others from doing
-- anything the license permits.
architecture rtl of ace is
signal ctl_control : ace_ctl_ty;
signal ctl_onehot : onehot_ty;
signal ctl_lfsr_en : std_logic;
signal ctl_lfsr_reset : std_logic;
begin
u_dp :
entity work.dp port map
( clk => clk
, reset => reset
, i_mode => i_mode
, i_control => ctl_control
, i_onehot => ctl_onehot
, i_dom_sep => i_dom_sep
, i_valid => i_valid
, i_data => i_data
, i_padding => i_padding
, o_data => o_data
);
u_ctl :
entity work.ctl port map
( clk => clk
, reset => reset
, i_mode => i_mode
, i_dom_sep => i_dom_sep
, i_valid => i_valid
, i_padding => i_padding
, o_valid => o_valid
, o_onehot => ctl_onehot
, o_ready => o_ready
, o_control => ctl_control
);
end architecture;
-- This work is licensed under a Creative Commons
-- Attribution-NonCommercial-ShareAlike 4.0 International License.
-- http://creativecommons.org/licenses/by-nc-sa/4.0
-- Mark D. Aagaard
-- Riham AlTawy
-- Guang Gong
-- Kalikinkar Mandal
-- Raghvendra Rohit
-- Marat Sattarov
-- Nusa Zidaric
-- http://uwaterloo.ca/communications-security-lab/lwc/ace
-- This is a human-readable summary of (and not a substitute for) the license.
-- You are free to:
-- Share: copy and redistribute the material in any medium or format
-- Adapt: remix, transform, and build upon the material
-- The licensor cannot revoke these freedoms as long as you follow
-- the license terms.
-- Under the following terms:
-- Attribution — You must give appropriate credit, provide a link to
-- the license, and indicate if changes were made. You may do so in
-- any reasonable manner, but not in any way that suggests the
-- licensor endorses you or your use.
-- NonCommercial — You may not use the material for commercial
-- purposes.
-- ShareAlike — If you remix, transform, or build upon the material,
-- you must distribute your contributions under the same license as
-- the original.
-- No additional restrictions — You may not apply legal terms or
-- technological measures that legally restrict others from doing
-- anything the license permits.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.ace_pkg.all;
entity ace is
port
( clk : in std_logic;
reset : in std_logic;
i_mode : in mode_ty;
i_dom_sep : in domsep_ty;
i_valid : in std_logic;
i_data : in word;
i_padding : in std_logic;
o_valid : out std_logic;
o_ready : out std_logic;
o_data : out word
);
end entity;
-- This work is licensed under a Creative Commons
-- Attribution-NonCommercial-ShareAlike 4.0 International License.
-- http://creativecommons.org/licenses/by-nc-sa/4.0
-- Mark D. Aagaard
-- Riham AlTawy
-- Guang Gong
-- Kalikinkar Mandal
-- Raghvendra Rohit
-- Marat Sattarov
-- Nusa Zidaric
-- http://uwaterloo.ca/communications-security-lab/lwc/ace
-- This is a human-readable summary of (and not a substitute for) the license.
-- You are free to:
-- Share: copy and redistribute the material in any medium or format
-- Adapt: remix, transform, and build upon the material
-- The licensor cannot revoke these freedoms as long as you follow
-- the license terms.
-- Under the following terms:
-- Attribution — You must give appropriate credit, provide a link to
-- the license, and indicate if changes were made. You may do so in
-- any reasonable manner, but not in any way that suggests the
-- licensor endorses you or your use.
-- NonCommercial — You may not use the material for commercial
-- purposes.
-- ShareAlike — If you remix, transform, or build upon the material,
-- you must distribute your contributions under the same license as
-- the original.
-- No additional restrictions — You may not apply legal terms or
-- technological measures that legally restrict others from doing
-- anything the license permits.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
package ace_pkg is
--for constants
constant lfsr_c_sz : integer := 7;
subtype lfsr_c_output is std_logic_vector(0 to lfsr_c_sz+2);
------------------------------------------------------------
constant half_word_sz : natural := 32;
constant word_sz : natural := 2*half_word_sz;
subtype half_word is std_logic_vector( 0 to half_word_sz - 1 );
subtype word is std_logic_vector( 0 to word_sz - 1 );
type word_vector is array( natural range <> ) of word;
type half_word_vector is array( natural range <> ) of half_word;
------------------------------------------------------------
-- A, B, C, D, E
constant state_sz : natural := 320;
constant word_max_idx : natural := state_sz / word_sz - 1;
constant half_word_max_idx : natural := state_sz / half_word_sz - 1;
constant key_sz : natural := 128;
constant nonce_sz : natural := 128;
subtype word_state_ty is word_vector ( 0 to word_max_idx );
constant a_idx : natural := 0;
constant b_idx : natural := 1;
constant c_idx : natural := 2;
constant d_idx : natural := 3;
constant e_idx : natural := 4;
subtype half_word_data is half_word_vector ( 0 to 1 );
subtype half_word_state_ty is half_word_vector ( 0 to half_word_max_idx );
constant a0_idx : natural := 1;
constant a1_idx : natural := 0;
constant b0_idx : natural := 3;
constant b1_idx : natural := 2;
constant c0_idx : natural := 5;
constant c1_idx : natural := 4;
constant d0_idx : natural := 7;
constant d1_idx : natural := 6;
constant e0_idx : natural := 9;
constant e1_idx : natural := 8;
function b2x( b : boolean ) return std_logic;
function half_words_to_words( st : half_word_state_ty ) return word_state_ty;
function words_to_half_words( st : word_state_ty ) return half_word_state_ty;
------------------------------------------------------------
-- mode
subtype mode_ty is std_logic_vector( 1 downto 0 ); -- top lvl input
constant encrypt_mode : mode_ty := ( 1 => '0', 0 => '0' );
constant decrypt_mode : mode_ty := ( 1 => '0', 0 => '1' );
constant absorb_mode : mode_ty := ( 1 => '1', 0 => '0' );
constant squeeze_mode : mode_ty := ( 1 => '1', 0 => '1' );
subtype domsep_ty is std_logic_vector( 1 downto 0 ); -- top lvl input
-- derived control (from counter and more)
subtype ace_ctl_ty is std_logic_vector( 7 downto 0 );
constant absorb_idx : natural := 0;
constant replace_idx : natural := 1;
constant output_idx : natural := 2;
constant endstep_idx : natural := 3;
constant permoff_idx : natural := 4;
constant squeeze_idx : natural := 5;
constant lfsr_c_reset_idx : natural := 6;
constant lfsr_c_en_idx : natural := 7;
-- extras cntl for load, init, fin, tag, sqeeze
subtype onehot_ty is std_logic_vector( 3 downto 0); -- extrs cntl for load, init, fin, tag, sqeeze
------------------------------------------------------------
-- round and step counters
-- use last bit for end ACE perm - for o_ready
-- -> i_valid will reset the counter!
-- counter only runs if msb = 0
constant bits_counter : natural := 8;
subtype count_ty is unsigned( bits_counter - 1 downto 0 );
----------------------------------------------------------------------
-- standard vhdl operators
-- function "sll"( a : half_word; n : natural ) return half_word;
function onehot_rotate (a : onehot_ty) return onehot_ty;
function vector_to_data ( st : half_word_data ) return word;
function data_to_vector ( st : word ) return half_word_data;
----------------------------------------------------------------------
end package;
----------------------------------------------------------------------
--
----------------------------------------------------------------------
package body ace_pkg is
function onehot_rotate (a : onehot_ty)
return onehot_ty
is
variable z : onehot_ty;
begin
z(onehot_ty'high downto 1) := a(onehot_ty'high - 1 downto 0);
z(0) := a(onehot_ty'high);
return z;
end function;
function b2x( b : boolean ) return std_logic is
begin
if b then
return '1';
else
return '0';
end if;
end function;
------------------------------------------------------------
-- standard vhdl operators cast to state
------------------------------------------------------------
-- function "sll"( a : half_word; n : natural ) return half_word is
-- begin
-- return half_word( std_logic_vector( a ) sll n );
-- end function;
------------------------------------------------------------
-- state functions
------------------------------------------------------------
function half_words_to_words( st : half_word_state_ty ) ---- CHECK THIS!!!!!! PLEASE
return word_state_ty
is
variable i : natural;
variable z : word_state_ty;
begin
main_loop : for i in 0 to word_max_idx loop
z(i)(0 to half_word_sz - 1) := st(2*i);
z(i)(half_word_sz to word_sz - 1) := st(2*i+1);
end loop;
return z;
end function;
function words_to_half_words( st : word_state_ty )
return half_word_state_ty
is
variable i : natural;
variable z : half_word_state_ty;
begin
main_loop : for i in 0 to word_max_idx loop
z(2*i) := st(i)(0 to half_word_sz - 1);
z(2*i+1) := st(i)(half_word_sz to word_sz - 1);
end loop;
return z;
end function;
function data_to_vector( st : word )
return half_word_data
is
variable z : half_word_data;
begin
z(0) := st(0 to half_word_sz - 1);
z(1) := st(half_word_sz to word_sz - 1);
return z;
end function;
function vector_to_data( st : half_word_data )
return word
is
variable z : word;
begin
z(0 to half_word_sz - 1) := st(0);
z(half_word_sz to word_sz - 1) := st(1);
return z;
end function;
end package body;
if { $gui_mode } {
add wave clk
add wave reset
add wave i_mode
add wave i_dom_sep
add wave o_ready
add wave i_valid
add wave i_data
add wave i_padding
add wave o_valid
add wave o_data
if { $sim_mode eq "PROG_MODE" } then {
add wave -noupdate -divider -height 32 STUFF
add wave /uut/u_ctl/state
add wave /uut/u_ctl/o_ready
add wave /uut/u_ctl/i_valid
add wave /uut/u_dp/i_data
add wave /uut/u_ctl/o_valid
add wave /uut/u_dp/o_data
add wave -noupdate -divider -height 32 DP
add wave -radix binary /uut/u_dp/ctl_const
add wave /uut/u_dp/i_data
add wave /uut/u_dp/o_data
add wave -radix binary /uut/u_dp/ctl_const
add wave /uut/u_dp/lfsr_c_en
add wave /uut/u_dp/lfsr_c_reset
add wave /uut/u_dp/permoff
add wave /uut/u_dp/endstep
add wave /uut/u_dp/absorb
add wave /uut/u_dp/replace
add wave /uut/u_dp/output
add wave /uut/u_dp/dsxor
add wave /uut/u_dp/post_input
add wave /uut/u_dp/pre_round
add wave /uut/u_dp/post_round
add wave /uut/u_dp/post_xor
add wave /uut/u_dp/post_step_const
add wave /uut/u_dp/post_linear
add wave /uut/u_dp/ace_path
add wave /uut/u_dp/ace_state
add wave -noupdate -divider -height 32 CTL
add wave /uut/u_ctl/state
add wave -radix unsigned /uut/u_ctl/count
add wave /uut/u_ctl/i_valid
add wave /uut/u_ctl/o_valid
add wave /uut/u_ctl/o_ready
add wave -radix binary /uut/u_ctl/onehot
add wave /uut/u_ctl/lfsr_c_reset
add wave -radix binary /uut/u_ctl/i_mode
add wave -radix binary /uut/u_ctl/i_dom_sep
}
}
vcd file uw_tmp/ace.vcd
vcd add /ace_tb/uut/*
vcd add -r *
vcd on
run -all
vcd checkpoint
vcd off
vcd flush
if { $gui_mode } {
wave zoom full
} else {
exit
}
**** Line 63 (old) / 63 (new) ****
Description:
Moved EDH to the list of generics
Change:
; EDH : std_logic_vector(0 to 2) := "111" -- ENCRYPTION, DECRYPTION, HASH bits. example: 'xx0' = don't do HASH, 'xx1' = do HASH
**** Line 68 (old) / 69 (new) ****
Description:
Removed EDH signal declaration
**** Line 91,96 (old) / 92,98 (new) ****
Description:
Added new signal declarations to delay primary inputs after clock edge
Change:
signal i_mode_buf : mode_ty;
signal i_dom_sep_buf : domsep_ty;
**** Line 114 (old) / 117 - 125 (new) ****
Description:
added new processes to delay a change in primary inputs after clock edge
Change:
i_dom_sep_proc : process(i_dom_sep_buf)
begin
i_dom_sep <= i_dom_sep_buf after hold;
end process;
i_mode_proc : process(i_mode_buf)
begin
i_mode <= i_mode_buf after hold;
end process;
**** Line 199 (old) / 212 (new) ****
**** Line 285 (old) / 304 (new) ****
**** Line 370 (old) / 395 (new) ****
**** Line 390 (old) / 416 (new) ****
Description:
changed signal name
Change:
was
i_mode
now
i_mode_buf
**** Line 216 (old) / 229 (new) ****
**** Line 226 (old) / 241 (new) ****
**** Line 234 (old) / 250 (new) ****
**** Line 239 (old) / 256 (new) ****
**** Line 265 (old) / 284 (new) ****
**** Line 303 (old) / 322 (new) ****
**** Line 314 (old) / 335 (new) ****
**** Line 324 (old) / 346 (new) ****
**** Line 330 (old) / 353 (new) ****
**** Line 358 (old) / 383 (new) ****
**** Line 382 (old) / 406 (new) ****
Description:
changed signal name
Change:
was
i_dom_sep
now
i_dom_sep_buf
**** Line 202 (old) / 215 (new) ****
**** Line 287 (old) / 306 (new) ****
**** Line 372 (old) / 396 (new) ****
**** Line 387 (old) / 413 (new) ****
Description:
Hold statements are now in ace_unsynth.vhd
Change:
removed
wait for hold;
**** Line 383 (old) / 407 (new) ****
Description
Added a report
Change:
report( "HASH DRIVE ALL" );
**** Line 130 (old), 132 (new) ****
**** Line 198 (old), 200 (new) ****
**** Line 227 (old), 230 (new) ****
Description:
added a hold statement to delay primary inputs from clock edge
Change:
wait for hold;
The file dp_pure.vhd was removed from the submission, because it is not part of the functional complete cipher.
-- This work is licensed under a Creative Commons
-- Attribution-NonCommercial-ShareAlike 4.0 International License.
-- http://creativecommons.org/licenses/by-nc-sa/4.0
-- Mark D. Aagaard
-- Riham AlTawy
-- Guang Gong
-- Kalikinkar Mandal
-- Raghvendra Rohit
-- Marat Sattarov
-- Nusa Zidaric
-- http://uwaterloo.ca/communications-security-lab/lwc/ace
-- This is a human-readable summary of (and not a substitute for) the license.
-- You are free to:
-- Share: copy and redistribute the material in any medium or format
-- Adapt: remix, transform, and build upon the material
-- The licensor cannot revoke these freedoms as long as you follow
-- the license terms.
-- Under the following terms:
-- Attribution — You must give appropriate credit, provide a link to
-- the license, and indicate if changes were made. You may do so in
-- any reasonable manner, but not in any way that suggests the
-- licensor endorses you or your use.
-- NonCommercial — You may not use the material for commercial
-- purposes.
-- ShareAlike — If you remix, transform, or build upon the material,
-- you must distribute your contributions under the same license as
-- the original.
-- No additional restrictions — You may not apply legal terms or
-- technological measures that legally restrict others from doing
-- anything the license permits.
library ieee;
use ieee.std_logic_1164.all;
use work.ace_pkg.all;
entity lfsr_c is
port
( clk : in std_logic
; lfsr_c_en : in std_logic
; lfsr_c_reset : in std_logic
; o_const : out lfsr_c_output
);
end lfsr_c;
architecture rtl of lfsr_c is
signal sa: std_logic_vector(lfsr_c_sz - 1 downto 0);
signal xa: std_logic_vector(lfsr_c_sz + 2 downto 0);
begin
-- 10 output bits for the constants
o_const <= xa; -- "to" type <= "downto" type. Index flip intended
-- just rename signal
xa(lfsr_c_sz-1 downto 0) <= sa(lfsr_c_sz-1 downto 0);
-- for updates and outputs
xa(lfsr_c_sz + 2 downto lfsr_c_sz) <= xa(3 downto 1) xor xa(2 downto 0);
lfsr_shift: for i in lfsr_c_sz-1 downto 0 generate
lfsr_step: process(clk) begin
if rising_edge(clk) then
if lfsr_c_reset ='1' then
sa(i) <= '1';
elsif lfsr_c_en ='1' then
sa(i) <= xa(i+3);
end if;
end if;
end process;
end generate lfsr_shift;
end;
------------ ACE readme file ---------------
----- list of files for ACE synthesis: -----
ace_pkg.vhd -- main package
sb_64.vhd -- s-box with simeck
lfsr.vhd -- lfsr for step / round constant generation
ctl.vhd -- control (FSM)
dp.vhd -- datapath
ace.vhd -- top level entity declaration
ace-rtl.vhd -- top level architecture
----- additional files for simulation: -----
util_unsynth.vhd -- functions used in TB (general purpose)
ace_unsynth.vhd -- specific ACE functions and procedures used in TB
ace_tb.vhd -- ACE testbench
-------------- pure datapath ---------------
dp_pure.vhd -- datapath with most input/output multiplexers removed
----------- TB info (ace_tb.vhd): ----------
********
EDH is a 3-bit constant used to select which modes to test
"100" - encryption only
"010" - decyption only
"001" - hash only
"110" - encryption and decryption
etc.
********
stim_file_path -- stimulus file
output_file_path -- output file
********
------------ stimulus file format --------------
1 file = 1 set of Key, Nonce, AD, Plaintext and Ciphertext
K 00111122335588DD00111122335588DD <--- 128 bits of Key (all 128 bits in a single line)
N 111122335588DD00111122335588DD00 <--- 128 bits of Nonce (all 128 bits in a single line)
A 1122335588DD00111122335588DD00 <--- from 4 to 128 bits of AD
P 335588DD00111122335588DD001111 <--- from 4 to 128 bits of Plaintext
C F9362385DC213A07CEFEF38C34CEFF <--- from 4 to 128 bits of Ciphertext
--- padding is done by testbench
--- multiple lines for AD, Plaintext and Ciphertext are supported
-- This work is licensed under a Creative Commons
-- Attribution-NonCommercial-ShareAlike 4.0 International License.
-- http://creativecommons.org/licenses/by-nc-sa/4.0
-- Mark D. Aagaard
-- Riham AlTawy
-- Guang Gong
-- Kalikinkar Mandal
-- Raghvendra Rohit
-- Marat Sattarov
-- Nusa Zidaric
-- http://uwaterloo.ca/communications-security-lab/lwc/ace
-- This is a human-readable summary of (and not a substitute for) the license.
-- You are free to:
-- Share: copy and redistribute the material in any medium or format
-- Adapt: remix, transform, and build upon the material
-- The licensor cannot revoke these freedoms as long as you follow
-- the license terms.
-- Under the following terms:
-- Attribution — You must give appropriate credit, provide a link to
-- the license, and indicate if changes were made. You may do so in
-- any reasonable manner, but not in any way that suggests the
-- licensor endorses you or your use.
-- NonCommercial — You may not use the material for commercial
-- purposes.
-- ShareAlike — If you remix, transform, or build upon the material,
-- you must distribute your contributions under the same license as
-- the original.
-- No additional restrictions — You may not apply legal terms or
-- technological measures that legally restrict others from doing
-- anything the license permits.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.ace_pkg.all;
entity sb_64 is
port
( i_state : in word
; i_rc : in std_logic
; o_state : out word
);
end entity;
architecture rtl of sb_64 is
signal x0, x1, z0, z1 : half_word;
signal rc : half_word;
begin
x1 <= i_state( 0 to half_word_sz-1 );
x0 <= i_state( half_word_sz to word_sz - 1 );
rc <= ( 0 to half_word_sz - 2 => '1', half_word_sz - 1 => i_rc );
z0 <= x1;
z1 <= ( ( x1(5 to half_word_sz - 1) & x1 (0 to 4) ) and x1)
xor ( x1(1 to half_word_sz - 1) & x1 (0) )
xor x0
xor rc;
o_state <= z1 & z0;
end architecture;
#!/bin/sh
tgpp -file drygascon128.tgpp.v
FILES="tb_drygascon128.v drygascon128.v"
FLAGS="+interp +dump2fst +fst+parallel2=on"
#cvc64 +xprop2 +dump2fst +fst+parallel2=on tb_data_path.v ctrl.v gf2m_alu.v gf2m_mul.v
cvc64 $FLAGS $FILES
FILES="tb_drygascon128.v drygascon128_ACC_PIPE.v"
cvc64 $FLAGS $FILES
FILES="tb_drygascon128.v drygascon128_ACC_PIPE_MIX_SHIFT_REG.v"
cvc64 $FLAGS $FILES
#!/bin/sh
FILES="tb_drygascon128.v drygascon128_use_funcs.v"
FLAGS="+interp +dump2fst +fst+parallel2=on"
cvc64 $FLAGS $FILES
#!/bin/sh
PATH=/opt/Xilinx/Vivado/2018.3/bin:$PATH
mkdir -p xsim
cd xsim
../xsim.py --top tb_drygascon128 --src ../tb_drygascon128.v --src ../drygascon128.v --log ../xsim.log
#!/bin/sh
FILES="tb_wrapper.v wrapper.v drygascon128_use_funcs.v"
FLAGS="+interp +dump2fst +fst+parallel2=on"
cvc64 $FLAGS $FILES
//Configuration flags: ""
`timescale 1ns / 1ps
`default_nettype none
module birotr(
input wire [64-1:0] din,
input wire [ 6-1:0] shift,
output reg [64-1:0] out
);
wire [32-1:0] i0 = din[0*32+:32];
wire [32-1:0] i1 = din[1*32+:32];
wire [ 6-1:0] shift2 = shift>>1;
wire [ 6-1:0] shift3 = (shift2 + 1'b1) % 6'd32;
always @* begin
if(shift & 1'b1) begin
out[ 0+:32] = (i1>>shift2) | (i1 << (6'd32-shift2));
out[32+:32] = (i0>>shift3) | (i0 << (6'd32-shift3));
end else begin
out[ 0+:32] = (i0>>shift2) | (i0 << (6'd32-shift2));
out[32+:32] = (i1>>shift2) | (i1 << (6'd32-shift2));
end
end
endmodule
module gascon5_round(
input wire [320-1:0] din,
input wire [4-1:0] round,
output reg [320-1:0] out
);
wire [5*6-1:0] rot_lut0 = {6'd07,6'd10,6'd01,6'd61,6'd19};
wire [5*6-1:0] rot_lut1 = {6'd40,6'd17,6'd06,6'd38,6'd28};
reg [7:0] round_constant;
always @* round_constant = (((4'hf - round)<<4) | round);
reg [320-1:0] add_constant_out;
always @* add_constant_out = din ^ {{5*64-8-2*64{1'b0}},round_constant,{2*64{1'b0}}};
reg [320-1:0] sbox_stage0;
always @* begin
sbox_stage0 = add_constant_out;
sbox_stage0[0*64+:64] = add_constant_out[0*64+:64] ^ add_constant_out[4*64+:64];
sbox_stage0[2*64+:64] = add_constant_out[2*64+:64] ^ add_constant_out[1*64+:64];
sbox_stage0[4*64+:64] = add_constant_out[4*64+:64] ^ add_constant_out[3*64+:64];
end
reg [320-1:0] t;
always @* begin
t[0*64+:64] = (~sbox_stage0[0*64+:64]) & sbox_stage0[1*64+:64];
t[1*64+:64] = (~sbox_stage0[1*64+:64]) & sbox_stage0[2*64+:64];
t[2*64+:64] = (~sbox_stage0[2*64+:64]) & sbox_stage0[3*64+:64];
t[3*64+:64] = (~sbox_stage0[3*64+:64]) & sbox_stage0[4*64+:64];
t[4*64+:64] = (~sbox_stage0[4*64+:64]) & sbox_stage0[0*64+:64];
end
reg [320-1:0] sbox_stage1;
always @* begin
sbox_stage1[0*64+:64] = sbox_stage0[0*64+:64] ^ t[1*64+:64];
sbox_stage1[1*64+:64] = sbox_stage0[1*64+:64] ^ t[2*64+:64];
sbox_stage1[2*64+:64] = sbox_stage0[2*64+:64] ^ t[3*64+:64];
sbox_stage1[3*64+:64] = sbox_stage0[3*64+:64] ^ t[4*64+:64];
sbox_stage1[4*64+:64] = sbox_stage0[4*64+:64] ^ t[0*64+:64];
end
reg [320-1:0] sbox_stage2;
always @* begin
sbox_stage2 = sbox_stage1;
sbox_stage2[1*64+:64] = sbox_stage1[1*64+:64] ^ sbox_stage1[0*64+:64];
sbox_stage2[3*64+:64] = sbox_stage1[3*64+:64] ^ sbox_stage1[2*64+:64];
sbox_stage2[0*64+:64] = sbox_stage1[0*64+:64] ^ sbox_stage1[4*64+:64];
end
reg [320-1:0] sbox_stage3;
always @* begin
sbox_stage3 = sbox_stage2;
sbox_stage3[2*64+:64] = ~sbox_stage2[2*64+:64];
end
wire [320-1:0] lin_layer_r0;
wire [320-1:0] lin_layer_r1;
birotr u_birotr00(.out(lin_layer_r0[0*64+:64]), .din(sbox_stage3[0*64+:64]), .shift(6'd19));
birotr u_birotr10(.out(lin_layer_r1[0*64+:64]), .din(sbox_stage3[0*64+:64]), .shift(6'd28));
birotr u_birotr01(.out(lin_layer_r0[1*64+:64]), .din(sbox_stage3[1*64+:64]), .shift(6'd61));
birotr u_birotr11(.out(lin_layer_r1[1*64+:64]), .din(sbox_stage3[1*64+:64]), .shift(6'd38));
birotr u_birotr02(.out(lin_layer_r0[2*64+:64]), .din(sbox_stage3[2*64+:64]), .shift(6'd01));
birotr u_birotr12(.out(lin_layer_r1[2*64+:64]), .din(sbox_stage3[2*64+:64]), .shift(6'd06));
birotr u_birotr03(.out(lin_layer_r0[3*64+:64]), .din(sbox_stage3[3*64+:64]), .shift(6'd10));
birotr u_birotr13(.out(lin_layer_r1[3*64+:64]), .din(sbox_stage3[3*64+:64]), .shift(6'd17));
birotr u_birotr04(.out(lin_layer_r0[4*64+:64]), .din(sbox_stage3[4*64+:64]), .shift(6'd07));
birotr u_birotr14(.out(lin_layer_r1[4*64+:64]), .din(sbox_stage3[4*64+:64]), .shift(6'd40));
reg [320-1:0] lin_layer;
always @* begin
lin_layer[0*64+:64] = sbox_stage3[0*64+:64] ^ lin_layer_r0[0*64+:64] ^ lin_layer_r1[0*64+:64];
lin_layer[1*64+:64] = sbox_stage3[1*64+:64] ^ lin_layer_r0[1*64+:64] ^ lin_layer_r1[1*64+:64];
lin_layer[2*64+:64] = sbox_stage3[2*64+:64] ^ lin_layer_r0[2*64+:64] ^ lin_layer_r1[2*64+:64];
lin_layer[3*64+:64] = sbox_stage3[3*64+:64] ^ lin_layer_r0[3*64+:64] ^ lin_layer_r1[3*64+:64];
lin_layer[4*64+:64] = sbox_stage3[4*64+:64] ^ lin_layer_r0[4*64+:64] ^ lin_layer_r1[4*64+:64];
end
always @* out = lin_layer;
endmodule
module mixsx32(
input wire [320-1:0] c,
input wire [128-1:0] x,
input wire [10-1:0] d,
output reg [320-1:0] out
);
reg [2-1:0] idx0;
reg [32-1:0] xw0;
always @* idx0 = d[0*2+:2];
always @* xw0 = x[idx0*32+:32];
always @* out[0*64+:64] = c[0*64+:64] ^ {{32{1'b0}},xw0};
reg [2-1:0] idx1;
reg [32-1:0] xw1;
always @* idx1 = d[1*2+:2];
always @* xw1 = x[idx1*32+:32];
always @* out[1*64+:64] = c[1*64+:64] ^ {{32{1'b0}},xw1};
reg [2-1:0] idx2;
reg [32-1:0] xw2;
always @* idx2 = d[2*2+:2];
always @* xw2 = x[idx2*32+:32];
always @* out[2*64+:64] = c[2*64+:64] ^ {{32{1'b0}},xw2};
reg [2-1:0] idx3;
reg [32-1:0] xw3;
always @* idx3 = d[3*2+:2];
always @* xw3 = x[idx3*32+:32];
always @* out[3*64+:64] = c[3*64+:64] ^ {{32{1'b0}},xw3};
reg [2-1:0] idx4;
reg [32-1:0] xw4;
always @* idx4 = d[4*2+:2];
always @* xw4 = x[idx4*32+:32];
always @* out[4*64+:64] = c[4*64+:64] ^ {{32{1'b0}},xw4};
endmodule
module accumulate(
input wire [256-1:0] din,
input wire [128-1:0] r,
output reg [128-1:0] out
);
always @* out = r ^ din[0+:128] ^ {din[128+:32],din[128+32+:96]};
endmodule
//F and G
module drygascon128(
input wire clk,
input wire clk_en,
input wire rst,
input wire [31:0] din,
input wire [3:0] ds,
input wire wr_i,
input wire wr_c,
input wire wr_x,
input wire [3:0] rounds,
input wire start,
input wire rd_r,
input wire rd_c,
output reg [31:0] dout,
output reg idle
);
localparam C_QWORDS = 5;
localparam X_QWORDS = 2;
localparam R_QWORDS = 2;
localparam CIDX_WIDTH = 3;//log2(X_QWORDS)
localparam XIDX_WIDTH = 2;//log2(X_QWORDS*2)
localparam C_DWORDS = C_QWORDS * 2;
localparam C_WIDTH = C_QWORDS * 64;
localparam X_DWORDS = X_QWORDS * 2;
localparam X_WIDTH = X_QWORDS * 64;
localparam R_DWORDS = R_QWORDS*2;
localparam R_WIDTH = R_QWORDS*64;
reg [C_WIDTH-1:0] c;
reg [X_WIDTH-1:0] x;
reg [R_WIDTH-1:0] r;
reg absorb;
reg [3:0] cnt;
always @(posedge clk) begin
if(clk_en) begin
case(1'b1)
rd_c: dout <= c[cnt*32+:32];
rd_r: dout <= r[cnt*32+:32];
default: dout <= {32{1'b0}};
endcase
end
end
localparam D_WIDTH = C_QWORDS*XIDX_WIDTH;
localparam MIX_ROUNDS = (R_WIDTH+4+D_WIDTH-1)/D_WIDTH;
reg [D_WIDTH-1:0] d;
wire [C_WIDTH-1:0] mixsx32_out;
reg [C_WIDTH-1:0] core_in;
reg [3:0] core_round;
wire [C_WIDTH-1:0] core_out;
wire [128-1:0] accu_out;
localparam MIX_I_PAD = D_WIDTH*MIX_ROUNDS - R_WIDTH+4;
reg [D_WIDTH*MIX_ROUNDS-1:0] mix_i;
always @* mix_i = {{MIX_I_PAD{1'b0}},ds,r};
always @* d = mix_i[cnt*D_WIDTH+:D_WIDTH];
mixsx32 u_mixsx32(.out(mixsx32_out), .c(c), .x(x), .d(d));
always @* core_in = absorb ? mixsx32_out : c;
always @* core_round = absorb ? {4{1'b0}} : cnt;
gascon5_round u_gascon5_round(.out(core_out), .din(core_in), .round(core_round));
accumulate u_accumulate(.out(accu_out), .din(core_out[0+:256]), .r(r));
localparam STATE_WIDTH = 2;
localparam STATE_IDLE = 2'b00;
localparam STATE_MIX_ENTRY = 2'b01;
localparam STATE_G_ENTRY = 2'b10;
reg [STATE_WIDTH-1:0] state;
always @(posedge clk) begin
if(clk_en) begin
if(rst) begin
state <= STATE_IDLE;
absorb <= 1'b0;
cnt <= {4{1'b0}};
idle <= 1'b1;
end else begin
case(state)
STATE_IDLE: begin
if(wr_i) begin
r[cnt*32+:32] <= din;
absorb <= 1'b1;
end
if(wr_c) begin
c[cnt*32+:32] <= din;
end
if(wr_x) begin
x <= {din,x[32+:X_WIDTH-32]};
end
case(1'b1)
wr_c,rd_c: cnt <= (cnt + 1'b1) % C_DWORDS;
wr_x: cnt <= (cnt + 1'b1) % X_DWORDS;
wr_i,rd_r: cnt <= (cnt + 1'b1) % R_DWORDS;
endcase
if(start) begin
if(absorb) begin
state <= STATE_MIX_ENTRY;
end else begin
r <= {R_WIDTH{1'b0}};
state <= STATE_G_ENTRY;
end
cnt <= {4{1'b0}};
idle <= 1'b0;
end
end
STATE_MIX_ENTRY: begin
c <= core_out;
if(MIX_ROUNDS-2==cnt) begin
r <= {R_WIDTH{1'b0}};
cnt <= cnt +1'b1;//to get last chunk
state <= STATE_G_ENTRY;//let absorb for the first round to consume last chunk
end else begin
cnt <= cnt +1'b1;
end
end
STATE_G_ENTRY: begin
//$display("round = %d",core_round);
//$display("core_in: %X",int_to_le(core_in));
//$display("core_out: %X",int_to_le(core_out));
//$display("accu_out: %X",int128_to_le(accu_out));
absorb <= 1'b0;
c <= core_out;
r <= accu_out;
if(rounds-1==cnt) begin
cnt <= {4{1'b0}};
state <= STATE_IDLE;
idle <= 1'b1;
end else begin
cnt <= absorb ? {{3{1'b0}},1'b1} : cnt +1'b1;
end
end
//default: begin
//end
endcase
end
end
end
endmodule
`default_nettype wire
//module generated using Spinal HDL, verified using VexRiscv - Murax SOC
module drygascon128_apb3 (
input [7:0] io_apb_PADDR,
input [0:0] io_apb_PSEL,
input io_apb_PENABLE,
output io_apb_PREADY,
input io_apb_PWRITE,
input [31:0] io_apb_PWDATA,
output reg [31:0] io_apb_PRDATA,
output io_apb_PSLVERROR,
input toplevel_resetCtrl_systemReset,
input toplevel_io_mainClk);
wire _zz_1_;
wire [31:0] core_dout;
wire core_idle;
wire selected;
wire askWrite;
wire askRead;
wire doWrite;
wire doRead;
reg start;
reg [3:0] ds;
reg [3:0] rounds;
reg rd_c;
reg wr_c;
reg rd_r;
reg wr_x;
reg wr_i;
wire [31:0] ctrl;
wire [31:0] zeroes;
wire ctrl_hit;
drygascon128 core (
.clk(toplevel_io_mainClk),
.clk_en(_zz_1_),
.rst(toplevel_resetCtrl_systemReset),
.din(io_apb_PWDATA),
.ds(ds),
.wr_i(wr_i),
.wr_c(wr_c),
.wr_x(wr_x),
.rounds(rounds),
.start(start),
.rd_r(rd_r),
.rd_c(rd_c),
.dout(core_dout),
.idle(core_idle)
);
assign _zz_1_ = 1'b1;
assign selected = (io_apb_PSEL[0] && io_apb_PENABLE);
assign askWrite = (selected && io_apb_PWRITE);
assign askRead = (selected && (! io_apb_PWRITE));
assign doWrite = ((selected && io_apb_PREADY) && io_apb_PWRITE);
assign doRead = ((selected && io_apb_PREADY) && (! io_apb_PWRITE));
assign zeroes = (1'b0 ? (32'b11111111111111111111111111111111) : (32'b00000000000000000000000000000000));
assign ctrl = {{{{core_idle,zeroes[30 : 9]},start},ds},rounds};
assign io_apb_PSLVERROR = 1'b0;
assign io_apb_PREADY = 1'b1;
always @ (*) begin
rd_c = 1'b0;
wr_c = 1'b0;
rd_r = 1'b0;
wr_x = 1'b0;
wr_i = 1'b0;
io_apb_PRDATA = (32'b00001110101011011011111011101111);
if(selected)begin
case(io_apb_PADDR)
8'b00000000 : begin
io_apb_PRDATA = ctrl;
end
8'b00000100 : begin
io_apb_PRDATA = core_dout;
rd_c = (! doWrite);
wr_c = doWrite;
end
8'b00001000 : begin
io_apb_PRDATA = core_dout;
rd_r = (! doWrite);
wr_i = doWrite;
end
8'b00001100 : begin
wr_x = doWrite;
end
default : begin
end
endcase
end
end
assign ctrl_hit = (selected && (io_apb_PADDR == (8'b00000000)));
always @ (posedge toplevel_io_mainClk or posedge toplevel_resetCtrl_systemReset) begin
if (toplevel_resetCtrl_systemReset) begin
start <= 1'b0;
ds <= (4'b0000);
rounds <= (4'b1011);
end else begin
start <= 1'b0;
if((doWrite && ctrl_hit))begin
rounds <= io_apb_PWDATA[3 : 0];
ds <= io_apb_PWDATA[7 : 4];
start <= io_apb_PWDATA[8];
end
end
end
endmodule
`ifndef __DRYGASCON128_FUNCTIONS__
`define __DRYGASCON128_FUNCTIONS__
function [320-1:0] int_to_le;
input [320-1:0] din;
reg [320-1:0] o;
integer i;
begin
o = {320{1'b0}};
for(i=0;i<8*5;i=i+1) begin
o[320-1-i*8-:8] = din[i*8+:8];
end
int_to_le = o;
end
endfunction
function [320-1:0] le_to_int;
input [320-1:0] din;
reg [320-1:0] o;
integer i;
begin
o = {320{1'b0}};
for(i=0;i<8*5;i=i+1) begin
o[i*8+:8] = din[320-1-i*8-:8];
end
le_to_int = o;
end
endfunction
function [128-1:0] int128_to_le;
input [128-1:0] din;
reg [128-1:0] o;
integer i;
begin
o = {128{1'b0}};
for(i=0;i<8*4;i=i+1) begin
o[128-1-i*8-:8] = din[i*8+:8];
end
int128_to_le = o;
end
endfunction
function [128-1:0] le_to_int128;
input [128-1:0] din;
reg [128-1:0] o;
integer i;
begin
o = {128{1'b0}};
for(i=0;i<8*4;i=i+1) begin
o[i*8+:8] = din[128-1-i*8-:8];
end
le_to_int128 = o;
end
endfunction
function [64-1:0] int64_to_le;
input [64-1:0] din;
reg [64-1:0] o;
integer i;
begin
o = {64{1'b0}};
for(i=0;i<8;i=i+1) begin
o[64-1-i*8-:8] = din[i*8+:8];
end
int64_to_le = o;
end
endfunction
function [64-1:0] le_to_int64;
input [64-1:0] din;
reg [64-1:0] o;
integer i;
begin
o = {64{1'b0}};
for(i=0;i<8;i=i+1) begin
o[i*8+:8] = din[64-1-i*8-:8];
end
le_to_int64 = o;
end
endfunction
function [128-1:0] accumulate;
input [256-1:0] din;
input [128-1:0] r;
reg [128-1:0] o;
begin
accumulate = r ^ din[0+:128] ^ {din[128+:32],din[128+32+:96]};
end
endfunction
function [32-1:0] rotr32;
input [32-1:0] din;
input [ 5-1:0] shift;
reg [5:0] i;
reg [32-1:0] o;
begin
o = {32{1'b0}};
for(i=0;i<32;i=i+1'b1) begin
//o[(i+32-shift)%32] = din[i];
o[i] = din[(i+shift)%32];
end
rotr32 = o;
end
endfunction
function [64-1:0] birotr;
input [64-1:0] din;
input [ 6-1:0] shift;
reg [32-1:0] i0;
reg [32-1:0] i1;
reg [32-1:0] t;
integer shift2;
begin
shift2 = shift>>1;
i0 = din[0*32+:32];
i1 = din[1*32+:32];
if(shift & 1'b1) begin
t = rotr32(i1,shift2);
i1 = rotr32(i0,(shift2+1'b1)%32);
i0 = t;
end else begin
i0 = rotr32(i0,shift2);
i1 = rotr32(i1,shift2);
end
birotr = {i1,i0};
end
endfunction
wire [5*6-1:0] rot_lut0 = {6'd07,6'd10,6'd01,6'd61,6'd19};
wire [5*6-1:0] rot_lut1 = {6'd40,6'd17,6'd06,6'd38,6'd28};
//function print_words64;
// input [320-1:0] c;
// integer i;
//begin
// for(i=0;i<5;i=i+1) begin
// $display("%x",c[i*64+:64]);
// end
// print_words64 = 0;
//end
//endfunction
function [320-1:0] gascon5_round;
input [320-1:0] din;
input [4-1:0] round;
reg [4-1:0] r;
integer i;
integer mid;
integer cwords;
integer d;
integer s;
reg [64-1:0] wi;
reg [64-1:0] ws;
reg [320-1:0] t;
reg [320-1:0] c;
integer dummy;
begin
c = din;
mid = 2;
cwords = 5;
//$display("i: %x",c);
//add constant
r = round;
c[mid*64+:64] = c[mid*64+:64] ^ (((4'hf - r)<<4) | r);
//$display("c mid: %x, r=%x",c[mid*64+:64],r);
//$display("c: %x",c);
//sbox
for(i=0;i<=2;i=i+1'b1) begin
d = 2*i;
s = (cwords + d - 1'b1) % cwords;
c[d*64+:64] = c[d*64+:64] ^ c[s*64+:64];
end
for(i=0;i<cwords;i=i+1'b1) begin
s = (i+1) % cwords;
wi = c[i*64+:64];
ws = c[s*64+:64];
t[i*64+:64] = (~wi) & ws;
end
for(i=0;i<cwords;i=i+1'b1) begin
s = (i+1) % cwords;
c[i*64+:64] = c[i*64+:64] ^ t[s*64+:64];
end
for(i=0;i<=2;i=i+1'b1) begin
s = 2*i;
d = (s + 1'b1) % cwords;
c[d*64+:64] = c[d*64+:64] ^ c[s*64+:64];
end
c[mid*64+:64] = ~c[mid*64+:64];
//$display("c: %x",c);
//linlayer
for(i=0;i<3'd5;i=i+1'b1) begin
c[i*64+:64] = c[i*64+:64] ^ birotr(c[i*64+:64],rot_lut0[i*6+:6]) ^ birotr(c[i*64+:64],rot_lut1[i*6+:6]);
end
//$display("c: %x",c);
//$display("c: ");dummy=print_words64(c);
gascon5_round = c;
end
endfunction
function [320-1:0] mixsx32;
input [320-1:0] c;
input [128-1:0] x;
input [10-1:0] d;
reg [320-1:0] co;
reg [2-1:0] idx;
reg [32-1:0] xw;
integer j;
begin
co = c;
for(j=0;j<5;j=j+1) begin
idx = d[j*2+:2];
xw = x[idx*32+:32];
co[j*2*32+:32] = co[j*2*32+:32] ^ xw;
end
mixsx32 = co;
end
endfunction
function [3:0] compute_ds;
input padded;
input [1:0] domain;
input finalize;
begin
compute_ds = {domain,finalize,padded};
end
endfunction
`endif
`timescale 1ns / 1ps
`default_nettype none
//F and G
module drygascon128(
input wire clk,
input wire clk_en,
input wire rst,
input wire [31:0] din,
input wire [3:0] ds,
input wire wr_i,
input wire wr_c,
input wire wr_x,
input wire [3:0] rounds,
input wire start,
input wire rd_r,
input wire rd_c,
output reg [31:0] dout,
output reg idle
);
`include "drygascon128_functions.v"
localparam C_QWORDS = 5;
localparam X_QWORDS = 2;
localparam R_QWORDS = 2;
localparam CIDX_WIDTH = 3;//log2(X_QWORDS)
localparam XIDX_WIDTH = 2;//log2(X_QWORDS*2)
localparam C_DWORDS = C_QWORDS * 2;
localparam C_WIDTH = C_QWORDS * 64;
localparam X_DWORDS = X_QWORDS * 2;
localparam X_WIDTH = X_QWORDS * 64;
localparam R_DWORDS = R_QWORDS*2;
localparam R_WIDTH = R_QWORDS*64;
reg [C_WIDTH-1:0] c;
reg [X_WIDTH-1:0] x;
reg [R_WIDTH-1:0] r;
reg absorb;
reg [3:0] cnt;
always @(posedge clk) begin
if(clk_en) begin
case(1'b1)
rd_c: dout <= c[cnt*32+:32];
rd_r: dout <= r[cnt*32+:32];
default: dout <= {32{1'b0}};
endcase
end
end
localparam D_WIDTH = C_QWORDS*XIDX_WIDTH;
localparam MIX_ROUNDS = (R_WIDTH+4+D_WIDTH-1)/D_WIDTH;
localparam MIX_I_PAD = D_WIDTH*MIX_ROUNDS - R_WIDTH+4;
wire [D_WIDTH*MIX_ROUNDS-1:0] mix_i = {{MIX_I_PAD{1'b0}},ds,r};
wire [D_WIDTH-1:0] d = mix_i[cnt*D_WIDTH+:D_WIDTH];
wire [C_WIDTH-1:0] mixsx32_out = mixsx32(c,x,d);
wire [C_WIDTH-1:0] core_in = absorb ? mixsx32_out : c;
wire [3:0] core_round = absorb ? {4{1'b0}} : cnt;
wire [C_WIDTH-1:0] core_out = gascon5_round(core_in,core_round);
wire [128-1:0] accu_out = accumulate(core_out[0+:256],r);//free pipelining can be done here by taking c instead
localparam STATE_WIDTH = 2;
localparam STATE_IDLE = 2'b00;
localparam STATE_MIX_ENTRY = 2'b01;
localparam STATE_G_ENTRY = 2'b10;
reg [STATE_WIDTH-1:0] state;
always @(posedge clk) begin
if(clk_en) begin
if(rst) begin
state <= STATE_IDLE;
absorb <= 1'b0;
cnt <= {4{1'b0}};
idle <= 1'b1;
end else begin
case(state)
STATE_IDLE: begin
if(wr_i) begin
r[cnt*32+:32] <= din;
absorb <= 1'b1;
end
if(wr_c) begin
c[cnt*32+:32] <= din;
end
if(wr_x) begin
x <= {din,x[32+:X_WIDTH-32]};
end
case(1'b1)
wr_c,rd_c: cnt <= (cnt + 1'b1) % C_DWORDS;
wr_x: cnt <= (cnt + 1'b1) % X_DWORDS;
wr_i,rd_r: cnt <= (cnt + 1'b1) % R_DWORDS;
endcase
if(start) begin
if(absorb) begin
state <= STATE_MIX_ENTRY;
end else begin
r <= {R_WIDTH{1'b0}};
state <= STATE_G_ENTRY;
end
cnt <= {4{1'b0}};
idle <= 1'b0;
end
end
STATE_MIX_ENTRY: begin
c <= core_out;
if(MIX_ROUNDS-2==cnt) begin
r <= {R_WIDTH{1'b0}};
cnt <= cnt +1'b1;//to get last chunk
state <= STATE_G_ENTRY;//let absorb for the first round to consume last chunk
end else begin
cnt <= cnt +1'b1;
end
end
STATE_G_ENTRY: begin
//$display("round = %d",core_round);
//$display("core_in: %X",int_to_le(core_in));
//$display("core_out: %X",int_to_le(core_out));
//$display("accu_out: %X",int128_to_le(accu_out));
absorb <= 1'b0;
c <= core_out;
r <= accu_out;
if(rounds-1==cnt) begin
cnt <= {4{1'b0}};
state <= STATE_IDLE;
idle <= 1'b1;
end else begin
cnt <= absorb ? {{3{1'b0}},1'b1} : cnt +1'b1;
end
end
endcase
end
end
end
endmodule
`default_nettype wire
`timescale 1ns / 1ps
`default_nettype none
`define assert(signal, value) \
if (signal !== value) begin \
$display("%t ASSERTION FAILED in %m: %x != %x",$realtime,signal,value); \
#100; \
$finish; \
end
module tb_drygascon128();
//`define func_path u_dut
`ifndef func_path
`define func_path tb_drygascon128
`include "drygascon128_functions.v"
`endif
reg clk;
reg clk_en;
reg reset;
reg [31:0] din;
reg [3:0] ds;
reg wr_i;
reg wr_c;
reg wr_x;
reg [3:0] rounds;
reg start;
reg rd_r;
reg rd_c;
wire [31:0] dout;
wire idle;
drygascon128 u_dut(
.clk(clk),
.clk_en(clk_en),
.rst(reset),
.din(din),
.ds(ds),
.wr_i(wr_i),
.wr_c(wr_c),
.wr_x(wr_x),
.rounds(rounds),
.start(start),
.rd_r(rd_r),
.rd_c(rd_c),
.dout(dout),
.idle(idle)
);
wire [63:0] c0 = u_dut.c[0*64+:64];
wire [63:0] c1 = u_dut.c[1*64+:64];
wire [63:0] c2 = u_dut.c[2*64+:64];
wire [63:0] c3 = u_dut.c[3*64+:64];
wire [63:0] c4 = u_dut.c[4*64+:64];
reg [320-1:0] c_out;
reg [128-1:0] r_out;
wire done = idle;
task wait_clock;
begin
@ (negedge clk);
end
endtask
task reset_dut;
begin
wait_clock();
reset = 1;
wait_clock();
reset = 0;
end
endtask
task wait_clocks;
input integer nclocks;
integer i;
begin
for(i=0;i < nclocks; i= i+1) begin
wait_clock();
end
end
endtask
task start_op;
begin
start = 1;
@(negedge clk);
start = 0;
end
endtask
reg done_reg;
always @(posedge clk) done_reg <= done;
task wait_done;
begin
wait_clock();
while(!done) begin
wait_clock();
end
end
endtask
task write_x;
input [128-1:0] x;
integer i;
begin
wr_x = 1;
for(i=0;i<4;i=i+1) begin
din = x[i*32+:32];
wait_clock();
end
wr_x=0;
end
endtask
task write_x_le;
input [128-1:0] x;
begin
write_x(`func_path.le_to_int128(x));
end
endtask
task write_c;
input [320-1:0] c;
integer i;
begin
wr_c = 1;
for(i=0;i<10;i=i+1) begin
din = c[i*32+:32];
wait_clock();
end
wr_c=0;
end
endtask
task write_c_le;
input [320-1:0] c;
begin
write_c(`func_path.le_to_int(c));
end
endtask
task read_c;
integer i;
begin
rd_c = 1;
for(i=0;i<10;i=i+1) begin
wait_clock();
c_out[i*32+:32] = dout;
end
rd_c=0;
end
endtask
task check_c;
input [320-1:0] expected;
begin
read_c();
`assert(c_out,expected)
end
endtask
task check_c_le;
input [320-1:0] expected;
begin
check_c(`func_path.le_to_int(expected));
end
endtask
task write_i;
input [128-1:0] di;
integer i;
begin
wr_i = 1;
for(i=0;i<4;i=i+1) begin
din = di[i*32+:32];
wait_clock();
end
wr_i=0;
end
endtask
task write_i_le;
input [128-1:0] i;
begin
write_i(`func_path.le_to_int128(i));
end
endtask
task read_r;
integer i;
begin
rd_r = 1;
for(i=0;i<4;i=i+1) begin
wait_clock();
r_out[i*32+:32] = dout;
end
rd_r=0;
end
endtask
task check_r;
input [128-1:0] expected;
begin
read_r();
`assert(r_out,expected)
end
endtask
task check_r_le;
input [128-1:0] expected;
begin
check_r(`func_path.le_to_int128(expected));
end
endtask
task gascon128_f;
input [3:0] ds_in;
input [3:0] rounds_in;
input [128-1:0] i;
begin
rounds=rounds_in;
ds = ds_in;
write_i(i);
start_op();
wait_done();
end
endtask
task gascon128_g;
input [3:0] rounds_in;
begin
rounds=rounds_in;
start_op();
wait_done();
end
endtask
task gascon128_f_le;
input [3:0] ds_in;
input [3:0] rounds_in;
input [128-1:0] i;
begin
gascon128_f(ds_in,rounds_in,`func_path.le_to_int128(i));
end
endtask
task check_gascon128_f_le;
input [3:0] ds_in;
input [3:0] rounds_in;
input [128-1:0] i;
input [128-1:0] expected;
begin
gascon128_f_le(ds_in,rounds_in,i);
check_r_le(expected);
end
endtask
task check_gascon128_g_le;
input [3:0] rounds_in;
input [128-1:0] expected;
begin
gascon128_g(rounds_in);
check_r_le(expected);
end
endtask
initial begin
clk = 0;
forever #5 clk = ~clk;
end
`define DRYGASCON128_IROUNDS 11
`define DRYGASCON128_ROUNDS 7
task init_dut;
begin
start = 0;
clk_en = 1;
wr_c=0;
wr_x=0;
wr_i=0;
rd_c=0;
rd_r=0;
ds=0;
rounds=11;
reset_dut();
end
endtask
task basic_test;
begin
init_dut();
write_x_le(128'h28292A2B2C2D2E2F3031323334353637);
`assert(u_dut.x,`func_path.le_to_int128(128'h28292A2B2C2D2E2F3031323334353637))
write_c_le(320'h000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627);
`assert(u_dut.c,`func_path.le_to_int(320'h000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627))
check_c_le(320'h000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627);
check_gascon128_f_le(6,`DRYGASCON128_IROUNDS,128'hF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF,128'hF1FBA3D719B00A49BF170F832EB7649F);
write_c_le(320'h000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627);
check_gascon128_f_le(6,`DRYGASCON128_IROUNDS,128'hF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF,128'hF1FBA3D719B00A49BF170F832EB7649F);
end
endtask
`define PAD 1
`define FINAL 1
`define DS_S 2
`define DS_D 1
`define DS_A 2
`define DS_M 3
task init_hash;
begin
init_dut();
write_x_le(128'hA4093822299F31D0082EFA98EC4E6C89);
`assert(u_dut.x,`func_path.le_to_int128(128'hA4093822299F31D0082EFA98EC4E6C89))
write_c_le(320'h243F6A8885A308D313198A2E03707344243F6A8885A308D313198A2E03707344243F6A8885A308D3);
`assert(u_dut.c,`func_path.le_to_int(320'h243F6A8885A308D313198A2E03707344243F6A8885A308D313198A2E03707344243F6A8885A308D3))
check_c_le(320'h243F6A8885A308D313198A2E03707344243F6A8885A308D313198A2E03707344243F6A8885A308D3);
end
endtask
task hash_null;
begin
init_hash();
check_gascon128_f_le(`func_path.compute_ds(`PAD,`DS_S,`FINAL),`DRYGASCON128_ROUNDS,128'h01000000000000000000000000000000,128'h1EDC77386E20A37C721D6E77ADABB9C4);
check_gascon128_g_le(`DRYGASCON128_ROUNDS,128'h830F199F5ED25284A13C1D84B9FC257A);
end
endtask
task hash_detailed_tv;
begin
init_hash();
check_gascon128_f_le(`func_path.compute_ds(`PAD,`DS_S,`FINAL),`DRYGASCON128_ROUNDS,128'h00010203040506070100000000000000,128'hCDE2DEE0235345CBFA51EC2CE5743571);
check_gascon128_g_le(`DRYGASCON128_ROUNDS,128'h8EC0133EC2756E035FA404C1CE511E24);
end
endtask
task hash_tv17;
begin
init_hash();
gascon128_f_le(0,`DRYGASCON128_ROUNDS,128'h000102030405060708090A0B0C0D0E0F);
check_gascon128_f_le(`func_path.compute_ds(`PAD,`DS_S,`FINAL),`DRYGASCON128_ROUNDS,128'h10010000000000000000000000000000,128'h20CDB78974D692100612978096CCFE82);
check_gascon128_g_le(`DRYGASCON128_ROUNDS,128'hE39F15969F493FAD8FA870F93B7252EA);
end
endtask
initial begin
basic_test();
hash_null();
hash_detailed_tv();
hash_tv17();
$display("sim pass");
$finish();
end
endmodule
`default_nettype wire
`timescale 1ns / 1ps
`default_nettype none
`define assert(signal, value) \
if (signal !== value) begin \
$display("%t ASSERTION FAILED in %m: %x != %x",$realtime,signal,value); \
#100; \
$finish; \
end
module tb_wrapper();
reg clk;
reg reset;
reg [31:0] din;
reg [3:0] ds;
reg wr_i;
reg wr_c;
reg wr_x;
reg [3:0] rounds;
reg start;
reg rd_r;
reg rd_c;
reg [31:0] dout;
reg idle;
reg tc;
reg ts;
reg di;
wire do;
wrapper u_dut(
.clk(clk),
.tc(tc),
.ts(ts),
.di(di),
.do(do)
);
wire [63:0] c0 = u_dut.u_impl.c[0*64+:64];
wire [63:0] c1 = u_dut.u_impl.c[1*64+:64];
wire [63:0] c2 = u_dut.u_impl.c[2*64+:64];
wire [63:0] c3 = u_dut.u_impl.c[3*64+:64];
wire [63:0] c4 = u_dut.u_impl.c[4*64+:64];
reg [320-1:0] c_out;
reg [128-1:0] r_out;
wire done = ts ? 0 : do;
localparam INPUT_WIDTH = 1+32+4+3+4+3;
localparam OUTPUT_WIDTH = 32+1;
localparam IOS_WIDTH = OUTPUT_WIDTH+INPUT_WIDTH;
reg [IOS_WIDTH-1:0] ios;
task wait_clock;
begin
@ (negedge clk);
end
endtask
task io;
integer i;
begin
ios = {{OUTPUT_WIDTH{1'b0}},reset,din,ds,wr_i,wr_c,wr_x,rounds,start,rd_r,rd_c};
tc=0;
ts=1;
//shift data in
for(i=0;i<IOS_WIDTH;i=i+1) begin
di = ios[IOS_WIDTH-1];
wait_clock();
ios = {ios[0+:IOS_WIDTH-1],di};
end
ts=0;
tc=0;
//set next clock as functional clock cycle
wait_clock();
tc=1;
wait_clock();//actual functional clock
wait_clock();//actual capture clock cycle
ts=1;
tc=0;
//shift data out (set same data in)
ios = {{OUTPUT_WIDTH{1'b0}},reset,din,ds,wr_i,wr_c,wr_x,rounds,start,rd_r,rd_c};
for(i=0;i<IOS_WIDTH;i=i+1) begin
di = ios[IOS_WIDTH-1];
wait_clock();
ios = {ios[0+:IOS_WIDTH-1],do};
end
{idle,dout} = ios[INPUT_WIDTH+:OUTPUT_WIDTH];
//any cycle done outside this task is a functional clock cycle
ts=0;
tc=0;
end
endtask
task reset_dut;
begin
wait_clock();
reset = 1;
io();
reset = 0;
io();
end
endtask
task wait_clocks;
input integer nclocks;
integer i;
begin
for(i=0;i < nclocks; i= i+1) begin
wait_clock();
end
end
endtask
task start_op;
begin
start = 1;
io();
start = 0;
io();
end
endtask
task wait_done;
begin
io();//ensure that any input change is taken into account
while(!done) begin
wait_clock();
end
end
endtask
task write_x;
input [128-1:0] x;
integer i;
begin
wr_x = 1;
for(i=0;i<4;i=i+1) begin
din = x[i*32+:32];
io();
end
wr_x=0;
end
endtask
task write_x_le;
input [128-1:0] x;
begin
write_x(u_dut.u_impl.le_to_int128(x));
end
endtask
task write_c;
input [320-1:0] c;
integer i;
begin
wr_c = 1;
for(i=0;i<10;i=i+1) begin
din = c[i*32+:32];
io();
end
wr_c=0;
end
endtask
task write_c_le;
input [320-1:0] c;
begin
write_c(u_dut.u_impl.le_to_int(c));
end
endtask
task read_c;
integer i;
begin
rd_c = 1;
for(i=0;i<10;i=i+1) begin
io();
c_out[i*32+:32] = dout;
end
rd_c=0;
end
endtask
task check_c;
input [320-1:0] expected;
begin
read_c();
`assert(c_out,expected)
end
endtask
task check_c_le;
input [320-1:0] expected;
begin
check_c(u_dut.u_impl.le_to_int(expected));
end
endtask
task write_i;
input [128-1:0] di;
integer i;
begin
wr_i = 1;
for(i=0;i<4;i=i+1) begin
din = di[i*32+:32];
io();
end
wr_i=0;
end
endtask
task write_i_le;
input [128-1:0] i;
begin
write_i(u_dut.u_impl.le_to_int128(i));
end
endtask
task read_r;
integer i;
begin
rd_r = 1;
for(i=0;i<4;i=i+1) begin
io();
r_out[i*32+:32] = dout;
end
rd_r=0;
end
endtask
task check_r;
input [128-1:0] expected;
begin
read_r();
`assert(r_out,expected)
end
endtask
task check_r_le;
input [128-1:0] expected;
begin
check_r(u_dut.u_impl.le_to_int128(expected));
end
endtask
task gascon128_f;
input [3:0] ds_in;
input [3:0] rounds_in;
input [128-1:0] i;
begin
rounds=rounds_in;
ds = ds_in;
write_i(i);
start_op();
wait_done();
end
endtask
task gascon128_g;
input [3:0] rounds_in;
begin
rounds=rounds_in;
start_op();
wait_done();
end
endtask
task gascon128_f_le;
input [3:0] ds_in;
input [3:0] rounds_in;
input [128-1:0] i;
begin
gascon128_f(ds_in,rounds_in,u_dut.u_impl.le_to_int128(i));
end
endtask
task check_gascon128_f_le;
input [3:0] ds_in;
input [3:0] rounds_in;
input [128-1:0] i;
input [128-1:0] expected;
begin
gascon128_f_le(ds_in,rounds_in,i);
check_r_le(expected);
end
endtask
task check_gascon128_g_le;
input [3:0] rounds_in;
input [128-1:0] expected;
begin
gascon128_g(rounds_in);
check_r_le(expected);
end
endtask
initial begin
clk = 0;
forever #5 clk = ~clk;
end
`define DRYGASCON128_IROUNDS 11
`define DRYGASCON128_ROUNDS 7
task init_dut;
begin
start = 0;
wr_c=0;
wr_x=0;
wr_i=0;
rd_c=0;
rd_r=0;
ds=0;
din = 0;
rounds=11;
tc=0;
ts=0;
reset_dut();
end
endtask
task basic_test;
begin
init_dut();
write_x_le(128'h28292A2B2C2D2E2F3031323334353637);
`assert(u_dut.u_impl.x,u_dut.u_impl.le_to_int128(128'h28292A2B2C2D2E2F3031323334353637))
write_c_le(320'h000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627);
`assert(u_dut.u_impl.c,u_dut.u_impl.le_to_int(320'h000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627))
check_c_le(320'h000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627);
check_gascon128_f_le(6,`DRYGASCON128_IROUNDS,128'hF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF,128'hF1FBA3D719B00A49BF170F832EB7649F);
write_c_le(320'h000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627);
check_gascon128_f_le(6,`DRYGASCON128_IROUNDS,128'hF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF,128'hF1FBA3D719B00A49BF170F832EB7649F);
end
endtask
`define PAD 1
`define FINAL 1
`define DS_S 2
`define DS_D 1
`define DS_A 2
`define DS_M 3
task init_hash;
begin
init_dut();
write_x_le(128'hA4093822299F31D0082EFA98EC4E6C89);
`assert(u_dut.u_impl.x,u_dut.u_impl.le_to_int128(128'hA4093822299F31D0082EFA98EC4E6C89))
write_c_le(320'h243F6A8885A308D313198A2E03707344243F6A8885A308D313198A2E03707344243F6A8885A308D3);
`assert(u_dut.u_impl.c,u_dut.u_impl.le_to_int(320'h243F6A8885A308D313198A2E03707344243F6A8885A308D313198A2E03707344243F6A8885A308D3))
check_c_le(320'h243F6A8885A308D313198A2E03707344243F6A8885A308D313198A2E03707344243F6A8885A308D3);
end
endtask
task hash_null;
begin
init_hash();
check_gascon128_f_le(u_dut.u_impl.compute_ds(`PAD,`DS_S,`FINAL),`DRYGASCON128_ROUNDS,128'h01000000000000000000000000000000,128'h1EDC77386E20A37C721D6E77ADABB9C4);
check_gascon128_g_le(`DRYGASCON128_ROUNDS,128'h830F199F5ED25284A13C1D84B9FC257A);
end
endtask
task hash_detailed_tv;
begin
init_hash();
check_gascon128_f_le(u_dut.u_impl.compute_ds(`PAD,`DS_S,`FINAL),`DRYGASCON128_ROUNDS,128'h00010203040506070100000000000000,128'hCDE2DEE0235345CBFA51EC2CE5743571);
check_gascon128_g_le(`DRYGASCON128_ROUNDS,128'h8EC0133EC2756E035FA404C1CE511E24);
end
endtask
task hash_tv17;
begin
init_hash();
gascon128_f_le(0,`DRYGASCON128_ROUNDS,128'h000102030405060708090A0B0C0D0E0F);
check_gascon128_f_le(u_dut.u_impl.compute_ds(`PAD,`DS_S,`FINAL),`DRYGASCON128_ROUNDS,128'h10010000000000000000000000000000,128'h20CDB78974D692100612978096CCFE82);
check_gascon128_g_le(`DRYGASCON128_ROUNDS,128'hE39F15969F493FAD8FA870F93B7252EA);
end
endtask
initial begin
basic_test();
hash_null();
hash_detailed_tv();
hash_tv17();
$display("sim pass");
$finish();
end
endmodule
`default_nettype wire
OSS_CVC_7.00b-x86_64-rhel6x of 07/07/14 (Linux-elf).
Copyright (c) 1991-2014 Tachyon Design Automation Corp.
All Rights reserved. Licensed software subject to prohibitions and
restrictions. See OSS CVC artistic license included with release.
Today is Sun Sep 22 12:23:56 2019.
Elaborating source file "tb_drygascon128.v"
Elaborating source file "drygascon128_use_funcs.v"
Highest level modules:
tb_drygascon128
sim pass
Halted at location **tb_drygascon128.v(360) time 3280000 ps from call to $finish.
There were 0 error(s), 0 warning(s), and 102 inform(s).
//wrapper module to reduce pin count and also for synthesis trial without taking care of I/O delays
`default_nettype none
module wrapper(
input wire clk,
input wire tc,//test capture: update ios reg
input wire ts,//test shift, data shift in from di and shift out to do
input wire di,
output reg do //output idle when ts=0
);
localparam INPUT_WIDTH = 1+32+4+3+4+3;
localparam OUTPUT_WIDTH = 32+1;
localparam IOS_WIDTH = OUTPUT_WIDTH+INPUT_WIDTH;
wire io_mode = tc | ts;
reg clk_en;
always @(posedge clk) clk_en <= ~io_mode;
reg rst;
reg [31:0] din;
reg [3:0] ds;
reg wr_i;
reg wr_c;
reg wr_x;
reg [3:0] rounds;
reg start;
reg rd_r;
reg rd_c;
wire [31:0] dout;
wire idle;
drygascon128 u_impl(
.clk(clk),
.clk_en(clk_en),
.rst(rst),
.din(din),
.ds(ds),
.wr_i(wr_i),
.wr_c(wr_c),
.wr_x(wr_x),
.rounds(rounds),
.start(start),
.rd_r(rd_r),
.rd_c(rd_c),
.dout(dout),
.idle(idle)
);
reg [IOS_WIDTH-1:0] ios;
always @(*) begin
{rst,din,ds,wr_i,wr_c,wr_x,rounds,start,rd_r,rd_c} = ios[0+:INPUT_WIDTH];
end
always @(posedge clk) do <= io_mode ? ios[IOS_WIDTH-1] : idle;
wire [OUTPUT_WIDTH-1:0] captured_output = ios[INPUT_WIDTH+:OUTPUT_WIDTH];
always @(posedge clk) begin
if(io_mode) begin
if(tc) ios[INPUT_WIDTH+:OUTPUT_WIDTH] <= {idle,dout};
else if(ts) ios <= {ios[0+:IOS_WIDTH-1],di};
end
end
endmodule
`default_nettype wire
This source diff could not be displayed because it is too large. You can view the blob instead.
DryGASCON128 on RISC-V / HX8K FPGA
# Overview
This project demonstrate how the verilog implementation can be integrated into a the low cost FPGA board "iCE40-HX8K Breakout Board". It allows to send arbitrary messages to DryGASCON128 core and to read its output. It also allows to run the core on pseudo random data and generate trigger signal for DPA traces gathering with minimal I/O overhead.
All the heavy lifting is done by the Murax project: the core is integrated as an APB3 slave peripheral, the serial communication and the overall protocol is handled by software (C99 code running on Murax's RV32I CPU).
# Dependencies
To merely load the prebuilt image, you need:
* icestorm tools (like icepack and iceprog)
To modify the bitfile:
* Yosys
* arachne-pnr
* sbt
To modify the software:
* riscv toolchain
# Loading the pre-built image:
![CRAM Programming Config](scripts/Murax/iCE40-hx8k_breakout_board/img/cram-programming-config.png)
* Configure the board for CRAM Programming mode (see figure)
* Connect to your computer via USB cable
* Connect a serial terminal program such as [moserial](http://live.gnome.org/moserial). The board shall appear as something like "/dev/ttyUSB1"
* In a shell, go to scripts/Murax/iCE40-hx8k_breakout_board
* type "make prog"
You shall get the following:
user@lafite:/tmp/diff/r2/drygasconv1_hx8k_fpga/scripts/Murax/iCE40-hx8k_breakout_board$ make prog
iceprog -S bin/toplevel.bin
init..
cdone: high
reset..
cdone: low
programming..
cdone: high
Bye.
The serial terminal shall display the following:
A00000000
OK
00000087 00000087
00000087 00000087
00000087 00000087
# Regenerating the Murax verilog:
* In a shell, go to scripts/Murax/iCE40-hx8k_breakout_board
* type "make"
# Compiling the bitfile:
* In a shell, go to scripts/Murax/iCE40-hx8k_breakout_board
* type "make compile"
# Compiling the software:
* In a shell, go to software/projects/murax
* type "make"
WARNING: to take the changes into account in the FPGA bitfile, you need to regenerate the Murax verilog.
# Serial communication usage
After startup the software is sending its version as a single byte. Then it is checking the consistency between the hardware implementation and a software implementation, if they match, it sends "OK".
Then it does a benchmark of the software implementation and print 3 lines of results.
Finally it enters the interactive loop which gives you control of the hardware implementation. C and X are fixed (hardcoded in the source code), you can control only the input I and the domain separator. The software expect to receive I as 16 bytes and then the domain seperator as a full byte.
lazy val root = (project in file(".")).
settings(
inThisBuild(List(
organization := "com.github.spinalhdl",
scalaVersion := "2.11.12",
version := "1.0.0"
)),
libraryDependencies ++= Seq(
"com.github.spinalhdl" % "spinalhdl-core_2.11" % "1.3.2",
"com.github.spinalhdl" % "spinalhdl-lib_2.11" % "1.3.2",
"org.scalatest" % "scalatest_2.11" % "2.2.1",
"org.yaml" % "snakeyaml" % "1.8"
),
name := "VexRiscv"
)//.dependsOn(spinalHdlSim,spinalHdlCore,spinalHdlLib)
//lazy val spinalHdlSim = ProjectRef(file("../SpinalHDL"), "sim")
//lazy val spinalHdlCore = ProjectRef(file("../SpinalHDL"), "core")
//lazy val spinalHdlLib = ProjectRef(file("../SpinalHDL"), "lib")
fork := true
\ No newline at end of file
debug: !!vexriscv.DebugReport {hardwareBreakpointCount: 0}
VERILOG = ../../../Murax.v toplevel.v ../../../src/drygascon128.v
generate :
(cd ../../..; sbt "runMain vexriscv.demo.MuraxHex")
../../../Murax.v :
(cd ../../..; sbt "runMain vexriscv.demo.MuraxHex")
../../../Murax.v*.bin:
bin/toplevel.blif : ${VERILOG} ../../../Murax.v*.bin
mkdir -p bin
rm -f Murax.v*.bin
cp ../../../Murax.v*.bin . | true
yosys -v3 -p "synth_ice40 -top toplevel -blif bin/toplevel.blif" ${VERILOG}
bin/toplevel.asc : toplevel.pcf bin/toplevel.blif
arachne-pnr -p toplevel.pcf -d 8k --max-passes 600 -P ct256 bin/toplevel.blif -o bin/toplevel.asc
bin/toplevel.bin : bin/toplevel.asc
icepack bin/toplevel.asc bin/toplevel.bin
compile : bin/toplevel.bin
time: bin/toplevel.bin
icetime -tmd hx8k bin/toplevel.asc
prog : bin/toplevel.bin
iceprog -S bin/toplevel.bin
sudo-prog : bin/toplevel.bin
sudo iceprog -S bin/toplevel.bin
clean :
rm -rf bin
rm -f Murax.v*.bin
This example is for the
[Lattice iCE40HX-8K Breakout Board](http://www.latticesemi.com/Products/DevelopmentBoardsAndKits/iCE40HX8KBreakoutBoard.aspx).
An image of this board is shown below;
![`iCE40HX8K breakout revA`](img/iCE40HX8K-breakout-revA.png)
This board can be purchased for ~$USD 49 directly from Lattice and is supported
by the IceStorm
[`iceprog`](https://github.com/cliffordwolf/icestorm/tree/master/iceprog) tool.
# Using the example
## Before Starting
Before starting make sure that your board is configured for `CRAM Programming`
mode. This requires removing jumper `J7` and putting the pair of jumpers on
`J6` to be parallel to the text on the board.
This is shown in **Figure 5** of the
[iCE40HX-8K Breakout Board User Guide](http://www.latticesemi.com/view_document?document_id=50373).
which is also reproduced below;
![CRAM Programming Config](img/cram-programming-config.png)
Once your board is ready, you should follow the setup instructions at the
[top level](../../../README.md).
You should make sure you have the following tools installed;
* Yosys
* arachne-pnr
* icestorm tools (like icepack and iceprog)
* riscv toolchain
* sbt
## Building
You should be able to just type `make compile` and get output similar to this;
```
...
place time 10.14s
route...
pass 1, 15 shared.
pass 2, 4 shared.
pass 3, 1 shared.
pass 4, 0 shared.
After routing:
span_4 4406 / 29696
span_12 951 / 5632
route time 9.12s
write_txt bin/toplevel.asc...
icepack bin/toplevel.asc bin/toplevel.bin
```
The process should take around 30 seconds on a reasonable fast computer.
## Programming
After building you should be able to run `make prog`. You may need to run `make
sudo-prog` if root is needed to access your USB devices.
You should get output like the following;
```
iceprog -S bin/toplevel.bin
init..
cdone: high
reset..
cdone: low
programming..
cdone: high
Bye.
```
After programming the LEDs at the top of the board should start flashing in an
interesting pattern.
## Connect
After programming you should be able to connect to the serial port and have the
output echoed back to you.
On Linux you can do this using a command like `screen /dev/ttyUSB1`. Then as
you type you should get back the same characters.
## iCE40-hx8k breakout board
set_io io_J3 J3
set_io io_H16 H16
set_io io_G15 G15
set_io io_G16 G16
set_io io_F15 F15
set_io io_B12 B12
set_io io_B10 B10
set_io io_led[0] B5
set_io io_led[1] B4
set_io io_led[2] A2
set_io io_led[3] A1
set_io io_led[4] C5
set_io io_led[5] C4
set_io io_led[6] B3
set_io io_led[7] C3
`timescale 1ns / 1ps
module toplevel(
input io_J3,
input io_H16,
input io_G15,
output io_G16,
input io_F15,
output io_B12,
input io_B10,
output [7:0] io_led
);
wire [31:0] io_gpioA_read;
wire [31:0] io_gpioA_write;
wire [31:0] io_gpioA_writeEnable;
wire io_mainClk;
wire io_jtag_tck;
SB_GB mainClkBuffer (
.USER_SIGNAL_TO_GLOBAL_BUFFER (io_J3),
.GLOBAL_BUFFER_OUTPUT ( io_mainClk)
);
SB_GB jtagClkBuffer (
.USER_SIGNAL_TO_GLOBAL_BUFFER (io_H16),
.GLOBAL_BUFFER_OUTPUT ( io_jtag_tck)
);
assign io_led = io_gpioA_write[7 : 0];
Murax murax (
.io_asyncReset(0),
.io_mainClk (io_mainClk ),
.io_jtag_tck(io_jtag_tck),
.io_jtag_tdi(io_G15),
.io_jtag_tdo(io_G16),
.io_jtag_tms(io_F15),
.io_gpioA_read (io_gpioA_read),
.io_gpioA_write (io_gpioA_write),
.io_gpioA_writeEnable(io_gpioA_writeEnable),
.io_uart_txd(io_B12),
.io_uart_rxd(io_B10)
);
endmodule
\ No newline at end of file
#ifndef __DRYGASCON128_APB_H__
#define __DRYGASCON128_APB_H__
#include <stdint.h>
typedef struct {
volatile uint32_t CTRL;
volatile uint32_t C;
volatile uint32_t IO;
volatile uint32_t X;
} Drygascon128_Regs;
#define DRYGASCON128_ROUNDS_O (0)
#define DRYGASCON128_DS_O (4)
#define DRYGASCON128_START_O (8)
#define DRYGASCON128_IDLE_O (31)
#define DRYGASCON128_START_MASK (1<<DRYGASCON128_START_O)
#define DRYGASCON128_IDLE_MASK (1<<DRYGASCON128_IDLE_O)
static unsigned int drygascon128hw_idle(Drygascon128_Regs *hw){
return hw->CTRL & DRYGASCON128_IDLE_MASK;
}
static unsigned int drygascon128hw_wait_idle(Drygascon128_Regs *hw){
while(!drygascon128hw_idle(hw));
}
static void drygascon128hw_start(Drygascon128_Regs *hw, unsigned int ds, unsigned int rounds){
hw->CTRL = DRYGASCON128_START_MASK | (ds << DRYGASCON128_DS_O) | (rounds<<DRYGASCON128_ROUNDS_O);
}
static void drygascon128hw_set_x(Drygascon128_Regs *hw, const uint32_t *const x){
hw->X = x[0];
hw->X = x[1];
hw->X = x[2];
hw->X = x[3];
}
static void drygascon128hw_set_io(Drygascon128_Regs *hw, const uint32_t *const i){
hw->IO = i[0];
hw->IO = i[1];
hw->IO = i[2];
hw->IO = i[3];
}
static void drygascon128hw_get_io(Drygascon128_Regs *hw, uint32_t *const o){
o[0] = hw->IO;
o[1] = hw->IO;
o[2] = hw->IO;
o[3] = hw->IO;
}
static void drygascon128hw_set_c(Drygascon128_Regs *hw, const uint32_t *const c){
for(unsigned int i=0;i<10;i++){
hw->C = c[i];
}
}
static void drygascon128hw_get_c(Drygascon128_Regs *hw, uint32_t *const c){
for(unsigned int i=0;i<10;i++){
c[i] = hw->C;
}
}
static void drygascon128hw_g(Drygascon128_Regs *hw, uint32_t*const r, unsigned int rounds){
drygascon128hw_start(hw, 0, rounds);
drygascon128hw_wait_idle(hw);
drygascon128hw_get_io(hw,r);
}
static void drygascon128hw_f(Drygascon128_Regs *hw, uint32_t*const r, const uint32_t*const in, uint32_t ds, unsigned int rounds){
drygascon128hw_set_io(hw,in);
drygascon128hw_start(hw, ds, rounds);
drygascon128hw_wait_idle(hw);
drygascon128hw_get_io(hw,r);
}
//return 0 if success or error code
static unsigned int drygascon128hw_test_ctrl(Drygascon128_Regs *hw){
if(!drygascon128hw_idle(hw)) return 0x2;
for(unsigned int i=0;i<256;i++){
hw->CTRL = i;
if(i!=(hw->CTRL & ~DRYGASCON128_IDLE_MASK)) return 0x01000000 | i;
}
hw->CTRL = 0xFFFFFE00;
uint32_t z = hw->CTRL & ~DRYGASCON128_IDLE_MASK;
if(z) return z;
uint32_t p = 0;
uint32_t q = 0;
uint32_t c[10];
for(unsigned int i=0;i<256;i++){
for(unsigned int j=0;j<10;j++){
p = i*16 + j;
c[j] = p;
}
drygascon128hw_set_c(hw,c);
drygascon128hw_get_c(hw,c);
for(unsigned int j=0;j<10;j++){
q = i*16 + j;
if(c[j] != q) return 0x02000000 | i;
}
}
for(unsigned int i=0;i<256;i++){
for(unsigned int j=0;j<4;j++){
p = i*16 + j;
c[j] = p;
}
drygascon128hw_set_io(hw,c);
drygascon128hw_get_io(hw,c);
for(unsigned int j=0;j<4;j++){
q = i*16 + j;
if(c[j] != q) return 0x03000000 | i;
}
}
//purge the internal state
drygascon128hw_start(hw, 0, 1);
drygascon128hw_wait_idle(hw);
return 0;
}
#endif
#ifndef GPIO_H_
#define GPIO_H_
typedef struct
{
volatile uint32_t INPUT;
volatile uint32_t OUTPUT;
volatile uint32_t OUTPUT_ENABLE;
} Gpio_Reg;
#endif /* GPIO_H_ */
#ifndef INTERRUPTCTRL_H_
#define INTERRUPTCTRL_H_
#include <stdint.h>
typedef struct
{
volatile uint32_t PENDINGS;
volatile uint32_t MASKS;
} InterruptCtrl_Reg;
static void interruptCtrl_init(InterruptCtrl_Reg* reg){
reg->MASKS = 0;
reg->PENDINGS = 0xFFFFFFFF;
}
#endif /* INTERRUPTCTRL_H_ */
#ifndef PRESCALERCTRL_H_
#define PRESCALERCTRL_H_
#include <stdint.h>
typedef struct
{
volatile uint32_t LIMIT;
} Prescaler_Reg;
static void prescaler_init(Prescaler_Reg* reg){
}
#endif /* PRESCALERCTRL_H_ */
#ifndef TIMERCTRL_H_
#define TIMERCTRL_H_
#include <stdint.h>
typedef struct
{
volatile uint32_t CLEARS_TICKS;
volatile uint32_t LIMIT;
volatile uint32_t VALUE;
} Timer_Reg;
static void timer_init(Timer_Reg *reg){
reg->CLEARS_TICKS = 0;
reg->VALUE = 0;
}
#endif /* TIMERCTRL_H_ */
#ifndef UART_H_
#define UART_H_
typedef struct
{
volatile uint32_t DATA;
volatile uint32_t STATUS;
volatile uint32_t CLOCK_DIVIDER;
volatile uint32_t FRAME_CONFIG;
} Uart_Reg;
enum UartParity {NONE = 0,EVEN = 1,ODD = 2};
enum UartStop {ONE = 0,TWO = 1};
typedef struct {
uint32_t dataLength;
enum UartParity parity;
enum UartStop stop;
uint32_t clockDivider;
} Uart_Config;
static uint32_t uart_writeAvailability(Uart_Reg *reg){
return (reg->STATUS >> 16) & 0xFF;
}
static uint32_t uart_readOccupancy(Uart_Reg *reg){
return reg->STATUS >> 24;
}
static void uart_write(Uart_Reg *reg, uint32_t data){
while(uart_writeAvailability(reg) == 0);
reg->DATA = data;
}
static void uart_applyConfig(Uart_Reg *reg, Uart_Config *config){
reg->CLOCK_DIVIDER = config->clockDivider;
reg->FRAME_CONFIG = ((config->dataLength-1) << 0) | (config->parity << 8) | (config->stop << 16);
}
#endif /* UART_H_ */
/*
* vga.h
*
* Created on: Jul 8, 2017
* Author: spinalvm
*/
#ifndef VGA_H_
#define VGA_H_
#include <stdint.h>
typedef struct {
uint32_t hSyncStart ,hSyncEnd;
uint32_t hColorStart,hColorEnd;
uint32_t vSyncStart ,vSyncEnd;
uint32_t vColorStart,vColorEnd;
}Vga_Timing;
static const Vga_Timing vga_h640_v480_r60 = {
.hSyncStart = 96,
.hSyncEnd = 800,
.hColorStart = 96 + 16,
.hColorEnd = 800 - 48,
.vSyncStart = 2,
.vSyncEnd = 525,
.vColorStart = 2 + 10,
.vColorEnd = 525 - 33
};
static const Vga_Timing vga_simRes = {
.hSyncStart = 8,
.hSyncEnd = 70,
.hColorStart = 16,
.hColorEnd = 64,
.vSyncStart = 2,
.vSyncEnd = 48,
.vColorStart = 8,
.vColorEnd = 40
};
static const Vga_Timing vga_simRes_h160_v120 = {
.hSyncStart = 8,
.hSyncEnd = 24+160,
.hColorStart = 16,
.hColorEnd = 16+160,
.vSyncStart = 2,
.vSyncEnd = 10+120,
.vColorStart = 6,
.vColorEnd = 6+120
};
typedef struct
{
volatile uint32_t STATUS;
volatile uint32_t FRAME_SIZE;
volatile uint32_t FRAME_BASE;
volatile uint32_t DUMMY0[13];
volatile Vga_Timing TIMING;
} Vga_Reg;
static uint32_t vga_isBusy(Vga_Reg *reg){
return (reg->STATUS & 2) != 0;
}
static void vga_run(Vga_Reg *reg){
reg->STATUS = 1;
}
static void vga_stop(Vga_Reg *reg){
reg->STATUS = 0;
while(vga_isBusy(reg));
}
#endif /* VGA_H_ */
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="cdt.managedbuild.toolchain.gnu.base.1720386410">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.toolchain.gnu.base.1720386410" moduleId="org.eclipse.cdt.core.settings" name="Default">
<externalSettings/>
<extensions>
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration buildProperties="" id="cdt.managedbuild.toolchain.gnu.base.1720386410" name="Default" optionalBuildProperties="" parent="org.eclipse.cdt.build.core.emptycfg">
<folderInfo id="cdt.managedbuild.toolchain.gnu.base.1720386410.965656806" name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.base.1780089110" name="cdt.managedbuild.toolchain.gnu.base" superClass="cdt.managedbuild.toolchain.gnu.base">
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.target.gnu.platform.base.519428669" name="Debug Platform" osList="linux,hpux,aix,qnx" superClass="cdt.managedbuild.target.gnu.platform.base"/>
<builder id="cdt.managedbuild.target.gnu.builder.base.2010336761" managedBuildOn="false" name="Gnu Make Builder.Default" superClass="cdt.managedbuild.target.gnu.builder.base"/>
<tool id="cdt.managedbuild.tool.gnu.archiver.base.2124635842" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.base.474451157" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.base">
<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1540030426" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.c.compiler.base.864173006" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.base">
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1271618987" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.c.linker.base.1724066123" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.base"/>
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.base.1197203554" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.base">
<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.1006131808" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
</tool>
<tool id="cdt.managedbuild.tool.gnu.assembler.base.1094492825" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.base">
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1891475174" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
</tool>
</toolChain>
</folderInfo>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="demo.null.2049339336" name="demo"/>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="makefileGenerator">
<runAction arguments="-E -P -v -dD" command="" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/${specs_file}&quot;'" command="sh" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-c 'g++ -E -P -v -dD &quot;${plugin_state_location}/specs.cpp&quot;'" command="sh" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/specs.c&quot;'" command="sh" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
</storageModule>
</cproject>
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>demo</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
<dictionary>
<key>?name?</key>
<value></value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.append_environment</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.autoBuildTarget</key>
<value>all</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.buildArguments</key>
<value></value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.buildCommand</key>
<value>make</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.cleanBuildTarget</key>
<value>clean</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.contents</key>
<value>org.eclipse.cdt.make.core.activeConfigSettings</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enableAutoBuild</key>
<value>false</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enableCleanBuild</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enableFullBuild</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.fullBuildTarget</key>
<value>all</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.stopOnError</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
<value>true</value>
</dictionary>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.core.ccnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
</projectDescription>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project>
<configuration id="cdt.managedbuild.toolchain.gnu.base.1720386410" name="Default">
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
<provider copy-of="extension" id="org.eclipse.cdt.managedbuilder.core.GCCBuildCommandParser"/>
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="43063298597590532" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
</extension>
</configuration>
</project>
Allocating common symbols
Common symbol size file
clen 0x4 build/src/main.o
drygascon128_state 0x58 build/src/main.o
Memory Configuration
Name Origin Length Attributes
onChipRam 0x0000000080000000 0x0000000000001800
*default* 0x0000000000000000 0xffffffffffffffff
Linker script and memory map
LOAD build/src/main.o
LOAD build/src/crt.o
LOAD build/src/drygascon128_riscv32e.o
LOAD /opt/riscv/bin/../lib/gcc/riscv64-unknown-elf/7.2.0/rv32i/ilp32/libgcc.a
0x0000000000000200 _stack_size = DEFINED (_stack_size)?_stack_size:0x200
0x0000000000000000 _heap_size = DEFINED (_heap_size)?_heap_size:0x0
.vector 0x0000000080000000 0x128
*crt.o(.text)
.text 0x0000000080000000 0x128 build/src/crt.o
0x0000000080000000 crtStart
0x0000000080000020 trap_entry
.memory 0x0000000080000128 0xc94
*(.text)
.text 0x0000000080000128 0x518 build/src/main.o
0x000000008000017c drygascon128_benchmark
0x00000000800001dc memcpy
0x0000000080000200 memcmp
0x0000000080000234 memset
0x0000000080000250 nibble_to_hexstr
0x0000000080000274 u8_to_hexstr
0x00000000800002b0 bin_to_hexstr
0x0000000080000304 u32_to_hexstr
0x0000000080000360 benchmark
0x0000000080000424 test_drygascon128_g
0x0000000080000500 test_drygascon128_f
0x000000008000063c irqCallback
.text 0x0000000080000640 0x77c build/src/drygascon128_riscv32e.o
0x0000000080000640 drygascon128_g
0x00000000800009a8 drygascon128_f
0x0000000080000dbc end = .
.text.startup 0x0000000080000dbc 0x518
.text.startup 0x0000000080000dbc 0x518 build/src/main.o
0x0000000080000dbc main
.rodata 0x00000000800012e0 0x1f0
*(.rdata)
*(.rodata .rodata.*)
.rodata 0x00000000800012e0 0x1d8 build/src/main.o
0x00000000800013c8 drygascon128_benchmark5_expected
0x0000000080001428 drygascon128_nonce
0x0000000080001438 drygascon128_key
0x0000000080001470 drygascon128_key_state
*fill* 0x00000000800014b8 0x8
.rodata 0x00000000800014c0 0x10 build/src/drygascon128_riscv32e.o
*(.gnu.linkonce.r.*)
.rela.dyn 0x00000000800014d0 0x0
.rela.text 0x00000000800014d0 0x0 build/src/main.o
.rela.text.startup
0x00000000800014d0 0x0 build/src/main.o
.rela.sdata 0x00000000800014d0 0x0 build/src/main.o
.ctors 0x00000000800014d0 0x0
0x00000000800014d0 . = ALIGN (0x4)
0x00000000800014d0 _ctors_start = .
*(.init_array*)
*(SORT(.ctors.*))
*(.ctors)
0x00000000800014d0 . = ALIGN (0x4)
0x00000000800014d0 _ctors_end = .
.data 0x00000000800014d0 0x10
*(.rdata)
*(.rodata .rodata.*)
*(.gnu.linkonce.r.*)
*(.data .data.*)
.data 0x00000000800014d0 0x0 build/src/main.o
.data 0x00000000800014d0 0x0 build/src/crt.o
.data 0x00000000800014d0 0x0 build/src/drygascon128_riscv32e.o
*(.gnu.linkonce.d.*)
0x00000000800014d0 . = ALIGN (0x8)
0x0000000080001cd0 PROVIDE (__global_pointer$, (. + 0x800))
*(.sdata .sdata.*)
.sdata 0x00000000800014d0 0xc build/src/main.o
0x00000000800014d0 drygascon128_state32
0x00000000800014d4 drygascon128_state8
0x00000000800014d8 min_time
*(.gnu.linkonce.s.*)
0x00000000800014e0 . = ALIGN (0x8)
*fill* 0x00000000800014dc 0x4
*(.srodata.cst16)
*(.srodata.cst8)
*(.srodata.cst4)
*(.srodata.cst2)
*(.srodata .srodata.*)
.bss 0x00000000800014e0 0xc8
0x00000000800014e0 . = ALIGN (0x4)
0x00000000800014e0 _bss_start = .
*(.sbss*)
.sbss 0x00000000800014e0 0x4 build/src/main.o
0x00000000800014e0 max_time
*(.gnu.linkonce.sb.*)
*(.bss .bss.*)
*fill* 0x00000000800014e4 0x4
.bss 0x00000000800014e8 0x60 build/src/main.o
0x00000000800014e8 io
.bss 0x0000000080001548 0x0 build/src/crt.o
.bss 0x0000000080001548 0x0 build/src/drygascon128_riscv32e.o
*(.gnu.linkonce.b.*)
*(COMMON)
COMMON 0x0000000080001548 0x60 build/src/main.o
0x0000000080001548 clen
0x0000000080001550 drygascon128_state
0x00000000800015a8 . = ALIGN (0x4)
0x00000000800015a8 _bss_end = .
.noinit 0x00000000800015a8 0x0
0x00000000800015a8 . = ALIGN (0x4)
*(.noinit .noinit.*)
0x00000000800015a8 . = ALIGN (0x4)
._user_heap 0x00000000800015a8 0x0
0x00000000800015a8 . = ALIGN (0x8)
[!provide] PROVIDE (end, .)
[!provide] PROVIDE (_end, .)
[!provide] PROVIDE (_heap_start, .)
0x00000000800015a8 . = (. + _heap_size)
0x00000000800015a8 . = ALIGN (0x8)
[!provide] PROVIDE (_heap_end, .)
._stack 0x00000000800015a8 0x208
0x00000000800015b0 . = ALIGN (0x10)
*fill* 0x00000000800015a8 0x8
[!provide] PROVIDE (_stack_end, .)
0x00000000800017b0 . = (. + _stack_size)
*fill* 0x00000000800015b0 0x200
0x00000000800017b0 . = ALIGN (0x10)
0x00000000800017b0 PROVIDE (_stack_start, .)
OUTPUT(build/demo.elf elf32-littleriscv)
.debug_info 0x0000000000000000 0x1f49
.debug_info 0x0000000000000000 0x1efd build/src/main.o
.debug_info 0x0000000000001efd 0x26 build/src/crt.o
.debug_info 0x0000000000001f23 0x26 build/src/drygascon128_riscv32e.o
.debug_abbrev 0x0000000000000000 0x4d8
.debug_abbrev 0x0000000000000000 0x4b0 build/src/main.o
.debug_abbrev 0x00000000000004b0 0x14 build/src/crt.o
.debug_abbrev 0x00000000000004c4 0x14 build/src/drygascon128_riscv32e.o
.debug_loc 0x0000000000000000 0xf25
.debug_loc 0x0000000000000000 0xf25 build/src/main.o
.debug_aranges 0x0000000000000000 0x68
.debug_aranges
0x0000000000000000 0x28 build/src/main.o
.debug_aranges
0x0000000000000028 0x20 build/src/crt.o
.debug_aranges
0x0000000000000048 0x20 build/src/drygascon128_riscv32e.o
.debug_ranges 0x0000000000000000 0x2f0
.debug_ranges 0x0000000000000000 0x2f0 build/src/main.o
.debug_line 0x0000000000000000 0x181b
.debug_line 0x0000000000000000 0xad6 build/src/main.o
.debug_line 0x0000000000000ad6 0x1d0 build/src/crt.o
.debug_line 0x0000000000000ca6 0xb75 build/src/drygascon128_riscv32e.o
.debug_str 0x0000000000000000 0x8bd
.debug_str 0x0000000000000000 0x88b build/src/main.o
0x944 (size before relaxing)
.debug_str 0x000000000000088b 0x16 build/src/crt.o
0x56 (size before relaxing)
.debug_str 0x00000000000008a1 0x1c build/src/drygascon128_riscv32e.o
0x68 (size before relaxing)
.comment 0x0000000000000000 0x11
.comment 0x0000000000000000 0x11 build/src/main.o
0x12 (size before relaxing)
.debug_frame 0x0000000000000000 0x1dc
.debug_frame 0x0000000000000000 0x1dc build/src/main.o
build/src/main.o: src/main.c \
/opt/riscv/lib/gcc/riscv64-unknown-elf/7.2.0/include/stdint.h \
/opt/riscv/riscv64-unknown-elf/include/stdint.h \
/opt/riscv/riscv64-unknown-elf/include/machine/_default_types.h \
/opt/riscv/riscv64-unknown-elf/include/sys/features.h \
/opt/riscv/riscv64-unknown-elf/include/_newlib_version.h \
/opt/riscv/riscv64-unknown-elf/include/sys/_intsup.h \
/opt/riscv/riscv64-unknown-elf/include/sys/_stdint.h \
/opt/riscv/riscv64-unknown-elf/include/stdlib.h \
/opt/riscv/riscv64-unknown-elf/include/machine/ieeefp.h \
/opt/riscv/riscv64-unknown-elf/include/_ansi.h \
/opt/riscv/riscv64-unknown-elf/include/newlib.h \
/opt/riscv/riscv64-unknown-elf/include/sys/config.h \
/opt/riscv/lib/gcc/riscv64-unknown-elf/7.2.0/include/stddef.h \
/opt/riscv/riscv64-unknown-elf/include/sys/reent.h \
/opt/riscv/riscv64-unknown-elf/include/_ansi.h \
/opt/riscv/riscv64-unknown-elf/include/sys/_types.h \
/opt/riscv/riscv64-unknown-elf/include/machine/_types.h \
/opt/riscv/riscv64-unknown-elf/include/sys/lock.h \
/opt/riscv/riscv64-unknown-elf/include/sys/cdefs.h \
/opt/riscv/riscv64-unknown-elf/include/machine/stdlib.h \
/opt/riscv/riscv64-unknown-elf/include/alloca.h ../libs/murax.h \
../../../libs/timer.h ../../../libs/prescaler.h \
../../../libs/interrupt.h ../../../libs/gpio.h ../../../libs/uart.h \
../../../libs/drygascon128_apb.h src/drysponge.h src/drygascon128_le32.h \
src/drygascon_le32.h src/drysponge_common.h \
/opt/riscv/riscv64-unknown-elf/include/string.h \
/opt/riscv/riscv64-unknown-elf/include/sys/_locale.h \
/opt/riscv/riscv64-unknown-elf/include/sys/string.h \
/opt/riscv/riscv64-unknown-elf/include/assert.h src/drysponge_le32.h \
src/drysponge_dbg_support.h
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment