Line 171... |
Line 171... |
--
|
--
|
--
|
--
|
-- END BLOCK (full last block)
|
-- END BLOCK (full last block)
|
-- ==================
|
-- ==================
|
--
|
--
|
-- If the last block has exactly 16 full words, the controller inserts a dummy PADDING cycle, processes the input block, and inserts a
|
-- If the last block has exactly 16 full words, the controller starts the block processing in the PADDING cycle, processes the input block,
|
-- last PADDING block followed by a last BLK_PROCESS block.
|
-- and inserts a last PADDING block followed by a last BLK_PROCESS block.
|
--
|
--
|
-- STATE ... data |pad | process |next | pad | process |next | valid |reset| data
|
-- STATE ... data |pad | process |next | pad | process |next | valid |reset| data
|
-- __ __ __ |__ |__ |__ |__ __ __ |__ |__ |__ __ |__ |__ __
|
-- __ __ __ |__ |__ |__ |__ __ __ |__ |__ |__ __ |__ |__ __
|
-- clk_i \__/ \__/ \__/ \__/ \_ _ _ __/ \__/ \__/ \_ _ _ __/ \__/ \_ _ _ __/ \__/ \__/ \__/ \__/ \__/ \_... -- system clock
|
-- clk_i \__/ \__/ \__/ \__/ \_ _ _ __/ \__/ \__/ \_ _ _ __/ \__/ \_ _ _ __/ \__/ \__/ \__/ \__/ \__/ \_... -- system clock
|
-- ______
|
-- ______
|
Line 188... |
Line 188... |
-- ____________________ _________
|
-- ____________________ _________
|
-- wr_i \\\_______ _ _ ___________________ _ _ _____________ _ _ ___________________________/ ... -- 'wr_i' valid on rising edge of 'clk_i'
|
-- wr_i \\\_______ _ _ ___________________ _ _ _____________ _ _ ___________________________/ ... -- 'wr_i' valid on rising edge of 'clk_i'
|
-- _____ _____ _____ __________ _ _ ___________________ _ _ _____________ _ _ ________________________________ ____...
|
-- _____ _____ _____ __________ _ _ ___________________ _ _ _____________ _ _ ________________________________ ____...
|
-- di_i _W13_\_W14_\_W15_\__________ _ _ ___________________ _ _ _____________ _ _ ___________________________\_W0_\__W1... -- words after the end_i assertion are ignored
|
-- di_i _W13_\_W14_\_W15_\__________ _ _ ___________________ _ _ _____________ _ _ ___________________________\_W0_\__W1... -- words after the end_i assertion are ignored
|
-- _____ _____ _____ _____ ____ _ ____ _____ _____ ____ _ _ ________ ____ _ ____ _____ _______________________ ____
|
-- _____ _____ _____ _____ ____ _ ____ _____ _____ ____ _ _ ________ ____ _ ____ _____ _______________________ ____
|
-- st_cnt_reg _13__/_14__/_15__/_16__/_16_ _ _63_/__64_/__0__/__1_ _ _ __/_15__/_16_ _ _63_/__64_/_____0_____/__0__/__0__/__1_... -- internal state counter value
|
-- st_cnt_reg _13__/_14__/_15__/_16__/_17_ _ _63_/__64_/__0__/__1_ _ _ __/_15__/_16_ _ _63_/__64_/_____0_____/__0__/__0__/__1_... -- internal state counter value
|
-- _____ _____ _____ _____ ____
|
-- _____ _____ _____ _____ ____
|
-- bytes_i __0__/__0__/__0__>-----------------------------------------------------------------------------------<__0__/__0_... -- bytes_i mark number of valid bytes in each word
|
-- bytes_i __0__/__0__/__0__>-----------------------------------------------------------------------------------<__0__/__0_... -- bytes_i mark number of valid bytes in each word
|
-- ___________
|
-- ___________
|
-- do_valid_o ____________________________ _ _ ___________________ _ _ __________________________/ \________________... -- 'do_valid_o' goes high at the end of a computation
|
-- do_valid_o ____________________________ _ _ ___________________ _ _ __________________________/ \________________... -- 'do_valid_o' goes high at the end of a computation
|
--
|
--
|
Line 232... |
Line 232... |
-- 2016/06/11 v0.01.0105 [JD] verification against NIST-SHA2_Additional test vectors #1 to #10 passed.
|
-- 2016/06/11 v0.01.0105 [JD] verification against NIST-SHA2_Additional test vectors #1 to #10 passed.
|
-- 2016/06/11 v0.01.0110 [JD] optimized controller states, reduced 2 clocks per block.
|
-- 2016/06/11 v0.01.0110 [JD] optimized controller states, reduced 2 clocks per block.
|
-- 2016/06/18 v0.01.0120 [JD] implemented error detection on 'bytes_i' input.
|
-- 2016/06/18 v0.01.0120 [JD] implemented error detection on 'bytes_i' input.
|
-- 2016/07/06 v0.01.0210 [JD] optimized suspend logic on 'sch_ld' to supress possible glitch in 'pad_one_next'.
|
-- 2016/07/06 v0.01.0210 [JD] optimized suspend logic on 'sch_ld' to supress possible glitch in 'pad_one_next'.
|
-- 2016/09/25 v0.01.0220 [JD] changed 'ack_i' name to 'wr_i', and changed semantics to 'data write'.
|
-- 2016/09/25 v0.01.0220 [JD] changed 'ack_i' name to 'wr_i', and changed semantics to 'data write'.
|
|
-- 2016/10/01 v0.01.0250 [JD] optimized the last null-padding state, making the algorithm isochronous for full last data blocks.
|
|
-- 2016/10/01 v0.01.0260 [JD] eliminated bytes error register, streamlined error logic.
|
--
|
--
|
-----------------------------------------------------------------------------------------------------------------------
|
-----------------------------------------------------------------------------------------------------------------------
|
-- TODO
|
-- TODO
|
-- ====
|
-- ====
|
--
|
--
|
Line 300... |
Line 302... |
-- combinational flags: message data input / padding control / block internal process selection
|
-- combinational flags: message data input / padding control / block internal process selection
|
signal reset : std_logic;
|
signal reset : std_logic;
|
signal sha_reset : std_logic;
|
signal sha_reset : std_logic;
|
signal sha_init : std_logic;
|
signal sha_init : std_logic;
|
signal wait_run_ce : std_logic;
|
signal wait_run_ce : std_logic;
|
-- registered flags: last block, padding control and hmac processing
|
-- registered flags: last block, padding control
|
signal sha_last_blk_reg : std_logic;
|
signal sha_last_blk_reg : std_logic;
|
signal sha_last_blk_next : std_logic;
|
signal sha_last_blk_next : std_logic;
|
signal padding_reg : std_logic;
|
signal padding_reg : std_logic;
|
signal padding_next : std_logic;
|
signal padding_next : std_logic;
|
signal pad_one_reg : std_logic;
|
signal pad_one_reg : std_logic;
|
signal pad_one_next : std_logic;
|
signal pad_one_next : std_logic;
|
signal bytes_error_reg : std_logic;
|
|
signal bytes_error_next : std_logic;
|
|
-- 64 bit message bit counter
|
-- 64 bit message bit counter
|
signal msg_bit_cnt_reg : unsigned (63 downto 0);
|
signal msg_bit_cnt_reg : unsigned (63 downto 0);
|
signal msg_bit_cnt_next : unsigned (63 downto 0);
|
signal msg_bit_cnt_next : unsigned (63 downto 0);
|
signal bits_to_add : unsigned (5 downto 0);
|
signal bits_to_add : unsigned (5 downto 0);
|
signal msg_bit_cnt_ce : std_logic;
|
signal msg_bit_cnt_ce : std_logic;
|
Line 336... |
Line 336... |
signal bytes_ena : std_logic_vector (3 downto 0); -- byte lane selectors for padding logic block
|
signal bytes_ena : std_logic_vector (3 downto 0); -- byte lane selectors for padding logic block
|
signal one_insert : std_logic; -- insert leading one in the padding
|
signal one_insert : std_logic; -- insert leading one in the padding
|
signal di_req : std_logic; -- data request
|
signal di_req : std_logic; -- data request
|
signal di_wr_window : std_logic; -- valid data write window
|
signal di_wr_window : std_logic; -- valid data write window
|
signal data_valid : std_logic; -- operation finished. output data is valid
|
signal data_valid : std_logic; -- operation finished. output data is valid
|
|
signal data_input_error : std_logic; -- data write outside write valid window
|
|
signal bytes_error : std_logic; -- bytes selection error
|
|
signal error_lock : std_logic; -- error state lock
|
signal core_error : std_logic; -- operation aborted. output data is not valid
|
signal core_error : std_logic; -- operation aborted. output data is not valid
|
signal data_input_error : std_logic; -- internal error signal for data write
|
|
signal out_error : std_logic; -- operation aborted. output data is not valid
|
|
|
|
begin
|
begin
|
--=============================================================================================
|
--=============================================================================================
|
-- REGISTER TRANSFER PROCESSES
|
-- REGISTER TRANSFER PROCESSES
|
--=============================================================================================
|
--=============================================================================================
|
Line 352... |
Line 353... |
-- FSM state register: sync RESET on 'reset', and sync PRESET on error_i
|
-- FSM state register: sync RESET on 'reset', and sync PRESET on error_i
|
if clk_i'event and clk_i = '1' then
|
if clk_i'event and clk_i = '1' then
|
if reset = '1' then
|
if reset = '1' then
|
-- all registered values are reset on master clear
|
-- all registered values are reset on master clear
|
hash_control_st_reg <= st_reset;
|
hash_control_st_reg <= st_reset;
|
elsif out_error = '1' then
|
elsif core_error = '1' then
|
-- error latch: lock on the error state
|
-- error latch: lock on the error state
|
hash_control_st_reg <= st_error;
|
hash_control_st_reg <= st_error;
|
elsif ce_i = '1' then
|
elsif ce_i = '1' then
|
-- all registered values are held on master clock enable
|
-- all registered values are held on master clock enable
|
hash_control_st_reg <= hash_control_st_next;
|
hash_control_st_reg <= hash_control_st_next;
|
Line 372... |
Line 373... |
-- all registered values are held on master clock enable
|
-- all registered values are held on master clock enable
|
sha_last_blk_reg <= sha_last_blk_next;
|
sha_last_blk_reg <= sha_last_blk_next;
|
padding_reg <= padding_next;
|
padding_reg <= padding_next;
|
end if;
|
end if;
|
end if;
|
end if;
|
-- bytes_i error register: sync RESET on 'reset'
|
|
if clk_i'event and clk_i = '1' then
|
|
if reset = '1' then
|
|
-- all registered values are reset on master clear
|
|
bytes_error_reg <= '0';
|
|
else
|
|
-- all registered values are held on master clock enable
|
|
bytes_error_reg <= bytes_error_next;
|
|
end if;
|
|
end if;
|
|
end process control_fsm_proc;
|
end process control_fsm_proc;
|
|
|
-- bit counter register transfer logic
|
-- bit counter register transfer logic
|
bit_counter_proc: process (clk_i) is
|
bit_counter_proc: process (clk_i) is
|
begin
|
begin
|
Line 440... |
Line 431... |
hash_control_st_next <= hash_control_st_reg;
|
hash_control_st_next <= hash_control_st_reg;
|
sha_last_blk_next <= sha_last_blk_reg;
|
sha_last_blk_next <= sha_last_blk_reg;
|
padding_next <= padding_reg;
|
padding_next <= padding_reg;
|
-- handshaking
|
-- handshaking
|
sha_init <= '0';
|
sha_init <= '0';
|
core_error <= '0';
|
error_lock <= '0';
|
di_wr_window <= '0';
|
di_wr_window <= '0';
|
words_sel <= b"00";
|
words_sel <= b"00";
|
data_valid <= '0';
|
data_valid <= '0';
|
di_req <= '0'; -- data request only during data input
|
di_req <= '0'; -- data request only during data input
|
-- state counter
|
-- state counter
|
Line 501... |
Line 492... |
end if;
|
end if;
|
|
|
when st_sha_blk_nxt => -- prepare for next block
|
when st_sha_blk_nxt => -- prepare for next block
|
-- moore outputs
|
-- moore outputs
|
st_cnt_clr <= '1'; -- reset state counter at the beginning of each block
|
st_cnt_clr <= '1'; -- reset state counter at the beginning of each block
|
sch_ld <= '0';
|
|
sch_ce <= '0'; -- stop the message schedule
|
sch_ce <= '0'; -- stop the message schedule
|
core_ld <= '1'; -- load previous result value into core registers
|
core_ld <= '1'; -- load result value into core registers
|
core_ce <= '1'; -- latch result value into core registers
|
core_ce <= '1'; -- latch result value into core registers
|
oregs_ce <= '1'; -- latch core result into regs accumulator
|
oregs_ce <= '1'; -- latch core result into regs accumulator
|
-- next state
|
-- next state
|
if sha_last_blk_reg = '1' then
|
if sha_last_blk_reg = '1' then
|
hash_control_st_next <= st_sha_data_valid; -- no hmac operation: publish data valid
|
hash_control_st_next <= st_sha_data_valid; -- no hmac operation: publish data valid
|
Line 519... |
Line 509... |
|
|
when st_sha_padding => -- padding of bits on the last message block
|
when st_sha_padding => -- padding of bits on the last message block
|
-- moore outputs
|
-- moore outputs
|
padding_next <= '1';
|
padding_next <= '1';
|
if st_cnt_reg = 16 then -- if word 16, data block was full: proceed to process this block
|
if st_cnt_reg = 16 then -- if word 16, data block was full: proceed to process this block
|
-- pause processing for this cycle
|
-- process state #16 in this cycle and proceed to process the rest of the block
|
sch_ld <= '0';
|
st_cnt_ce <= '1'; -- enable state counter
|
sch_ce <= '0';
|
sch_ld <= '0'; -- recirculate scheduler data
|
core_ce <= '0';
|
sch_ce <= '1'; -- enable message scheduler clock
|
st_cnt_ce <= '0';
|
core_ce <= '1'; -- enable processing clock
|
-- next state
|
-- next state
|
hash_control_st_next <= st_sha_blk_process;
|
hash_control_st_next <= st_sha_blk_process;
|
else -- incomplete block: pad words until data block completes
|
else -- incomplete block: pad words until data block completes
|
sch_ld <= '1'; -- load padded data into scheduler
|
sch_ld <= '1'; -- load padded data into scheduler
|
sch_ce <= '1'; -- enable message scheduler clock
|
sch_ce <= '1'; -- enable message scheduler clock
|
Line 548... |
Line 538... |
end if;
|
end if;
|
|
|
when st_sha_data_valid => -- process is finished, waiting for begin command
|
when st_sha_data_valid => -- process is finished, waiting for begin command
|
-- moore outputs
|
-- moore outputs
|
data_valid <= '1'; -- output results are valid
|
data_valid <= '1'; -- output results are valid
|
-- wait for core reset with 'reset'
|
-- wait for core reset with 'start'
|
|
|
when st_error => -- processing or input error: reset with 'reset' = 1
|
when st_error => -- processing or input error: reset with 'reset' = 1
|
-- moore outputs
|
-- moore outputs
|
core_error <= '1';
|
error_lock <= '1'; -- lock error state
|
st_cnt_clr <= '1'; -- clear state counter
|
st_cnt_clr <= '1'; -- clear state counter
|
-- wait for core reset with 'reset'
|
-- wait for core reset with 'start'
|
|
|
when others => -- internal state machine error
|
when others => -- internal state machine error
|
-- next state
|
-- next state
|
hash_control_st_next <= st_error;
|
hash_control_st_next <= st_error;
|
|
|
end case;
|
end case;
|
end process control_combi_proc;
|
end process control_combi_proc;
|
|
|
|
|
--=============================================================================================
|
--=============================================================================================
|
-- COMBINATIONAL CONTROL LOGIC
|
-- COMBINATIONAL CONTROL LOGIC
|
--=============================================================================================
|
--=============================================================================================
|
|
|
-- controller RESET signal logic
|
-- controller RESET signal logic
|
Line 617... |
Line 606... |
end case;
|
end case;
|
msg_bit_cnt_next <= msg_bit_cnt_reg + bits_to_add;
|
msg_bit_cnt_next <= msg_bit_cnt_reg + bits_to_add;
|
end process msg_bit_cnt_next_combi_proc;
|
end process msg_bit_cnt_next_combi_proc;
|
|
|
-- data input wait/run: insert wait states during data input for 'wr_i' = '0'
|
-- data input wait/run: insert wait states during data input for 'wr_i' = '0'
|
wait_run_proc: wait_run_ce <= '1' when di_req = '1' and wr_i = '1' else '0';
|
wait_run_ce_proc: wait_run_ce <= '1' when di_req = '1' and wr_i = '1' else '0';
|
|
|
-- padding one-insertion control
|
-- padding one-insertion control
|
one_insert_proc: one_insert <= '1' when pad_one_reg = '1' else '0';
|
one_insert_proc: one_insert <= '1' when pad_one_reg = '1' else '0';
|
|
|
-- bit counter clock enable
|
-- bit counter clock enable
|
Line 629... |
Line 618... |
|
|
-- state counter next logic
|
-- state counter next logic
|
st_cnt_next_proc: st_cnt_next <= st_cnt_reg + 1;
|
st_cnt_next_proc: st_cnt_next <= st_cnt_reg + 1;
|
|
|
-- bytes_i error logic
|
-- bytes_i error logic
|
bytes_error_proc: bytes_error_next <= '1' when bytes_i /= b"00" and end_i /= '1' and di_req = '1' and wr_i = '1' else bytes_error_reg;
|
bytes_error_proc: bytes_error <= '1' when bytes_i /= b"00" and end_i /= '1' and di_req = '1' and wr_i = '1' else '0';
|
|
|
-- data input error logic
|
-- data input error logic
|
data_input_error_proc: data_input_error <= '1' when wr_i = '1' and di_wr_window /= '1' else '0';
|
data_input_error_proc: data_input_error <= '1' when wr_i = '1' and di_wr_window /= '1' else '0';
|
|
|
-- error detection logic
|
-- error detection logic
|
out_error_combi_proc: out_error <= '1' when error_i = '1' or core_error = '1' or bytes_error_reg = '1' or data_input_error = '1' else '0';
|
core_error_combi_proc: core_error <= '1' when error_i = '1' or error_lock = '1' or bytes_error = '1' or data_input_error = '1' else '0';
|
|
|
--=============================================================================================
|
--=============================================================================================
|
-- OUTPUT LOGIC PROCESSES
|
-- OUTPUT LOGIC PROCESSES
|
--=============================================================================================
|
--=============================================================================================
|
|
|
Line 654... |
Line 643... |
oregs_ce_o_proc : oregs_ce_o <= oregs_ce;
|
oregs_ce_o_proc : oregs_ce_o <= oregs_ce;
|
oregs_ld_o_proc : oregs_ld_o <= oregs_ld;
|
oregs_ld_o_proc : oregs_ld_o <= oregs_ld;
|
Kt_addr_o_proc : Kt_addr_o <= std_logic_vector(st_cnt_reg(5 downto 0));
|
Kt_addr_o_proc : Kt_addr_o <= std_logic_vector(st_cnt_reg(5 downto 0));
|
di_req_o_proc : di_req_o <= di_req;
|
di_req_o_proc : di_req_o <= di_req;
|
data_valid_o_proc : data_valid_o <= data_valid;
|
data_valid_o_proc : data_valid_o <= data_valid;
|
error_o_proc : error_o <= out_error;
|
error_o_proc : error_o <= core_error;
|
|
|
end rtl;
|
end rtl;
|
|
|
|
|
No newline at end of file
|
No newline at end of file
|