- added
git-svn-id: http://moon:8086/svn/vhdl/trunk@1423 cc03376c-175c-47c8-b038-4cd826a8556b
This commit is contained in:
@@ -0,0 +1,134 @@
|
||||
--- ============================================================================
|
||||
--
|
||||
-- Design unit : aes_column_ops
|
||||
--
|
||||
-- File Name : aes_column_ops.vhd
|
||||
--
|
||||
-- Purpose : Design file
|
||||
--
|
||||
--
|
||||
-- Depends on :
|
||||
--
|
||||
-- - Package(s) : -
|
||||
--
|
||||
-- - Module(s) : -
|
||||
--
|
||||
--
|
||||
-- Dev. Platform : Xilinx ISE 8.1i SP3 / Win32 (W2k SP4)
|
||||
--
|
||||
-- - Simulator(s) : Modelsim XE III 6.0d
|
||||
--
|
||||
-- - Synthesis : Xilinx XST
|
||||
--
|
||||
-- - Place & Route : Xilinx PAR
|
||||
--
|
||||
--
|
||||
-- Errors : None known
|
||||
--
|
||||
--
|
||||
-- Limitations : None known
|
||||
--
|
||||
--
|
||||
-- Notes : -
|
||||
--
|
||||
--
|
||||
-- Author(s) : A. Freund (af) <a.freund@dsi-it.de>,
|
||||
-- M.v.d.Wall (mvdw) <vdwall@dsi-it.de>
|
||||
-- Digitale Signalverabeitung & Informationstechnik GmbH,
|
||||
-- Bremen, Germany
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Revision List:
|
||||
--
|
||||
-- see SVN logs
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Naming conventions:
|
||||
--
|
||||
-- - coding style: record-signals for related purposes (Gaisler-style)
|
||||
-- - active-low signals are indicated by appending "_n"
|
||||
-- - constants are in UPPERCASE
|
||||
-- - name parts are separated by "_"
|
||||
--
|
||||
-- ============================================================================
|
||||
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
use work.aes_gf_2exp8_arith.all;
|
||||
|
||||
|
||||
package aes_column_ops is
|
||||
|
||||
|
||||
type column_t is array (0 to 3) of gf_2exp8_t;
|
||||
|
||||
function mix_column(col : in column_t) return column_t;
|
||||
|
||||
function inv_mix_column(col : in column_t) return column_t;
|
||||
|
||||
|
||||
|
||||
end aes_column_ops;
|
||||
|
||||
|
||||
package body aes_column_ops is
|
||||
|
||||
|
||||
type trans_matrix_t is array (0 to 3, 0 to 3) of gf_2exp8_t;
|
||||
|
||||
constant TRANS_MATRIX : trans_matrix_t :=
|
||||
(
|
||||
(X"02", X"03", X"01", X"01"),
|
||||
(X"01", X"02", X"03", X"01"),
|
||||
(X"01", X"01", X"02", X"03"),
|
||||
(X"03", X"01", X"01", X"02")
|
||||
);
|
||||
|
||||
constant INV_TRANS_MATRIX : trans_matrix_t :=
|
||||
(
|
||||
(X"0e", X"0b", X"0d", X"09"),
|
||||
(X"09", X"0e", X"0b", X"0d"),
|
||||
(X"0d", X"09", X"0e", X"0b"),
|
||||
(X"0b", X"0d", X"09", X"0e")
|
||||
);
|
||||
|
||||
|
||||
function mix_column(col : in column_t) return column_t is
|
||||
variable v_col : column_t;
|
||||
begin
|
||||
for c in v_col'range loop
|
||||
v_col(c) := X"00";
|
||||
end loop;
|
||||
|
||||
for r in v_col'range loop
|
||||
for c in v_col'range loop
|
||||
v_col(r) := add_gf_2exp8(v_col(r), mul_gf_2exp8(TRANS_MATRIX(r,c), col(c)));
|
||||
end loop;
|
||||
end loop;
|
||||
|
||||
return v_col;
|
||||
end mix_column;
|
||||
|
||||
|
||||
function inv_mix_column(col : in column_t) return column_t is
|
||||
variable v_col : column_t;
|
||||
begin
|
||||
for c in v_col'range loop
|
||||
v_col(c) := X"00";
|
||||
end loop;
|
||||
|
||||
for r in v_col'range loop
|
||||
for c in v_col'range loop
|
||||
v_col(r) := add_gf_2exp8(v_col(r), mul_gf_2exp8(INV_TRANS_MATRIX(r,c), col(c)));
|
||||
end loop;
|
||||
end loop;
|
||||
|
||||
return v_col;
|
||||
end inv_mix_column;
|
||||
|
||||
|
||||
end aes_column_ops;
|
||||
@@ -0,0 +1,202 @@
|
||||
--- ============================================================================
|
||||
--
|
||||
-- Design unit : aes_common
|
||||
--
|
||||
-- File Name : aes_common.vhd
|
||||
--
|
||||
-- Purpose : This package defines supplemental types, subtypes,
|
||||
-- constants, and functions
|
||||
--
|
||||
--
|
||||
-- Depends on :
|
||||
--
|
||||
-- - Package(s) : -
|
||||
--
|
||||
-- - Module(s) : -
|
||||
--
|
||||
--
|
||||
-- Dev. Platform : Xilinx ISE 8.1i SP3 / Win32 (W2k SP4)
|
||||
--
|
||||
-- - Simulator(s) : Modelsim XE III 6.0d
|
||||
--
|
||||
-- - Synthesis : Xilinx XST
|
||||
--
|
||||
-- - Place & Route : Xilinx PAR
|
||||
--
|
||||
--
|
||||
-- Errors : None known
|
||||
--
|
||||
--
|
||||
-- Limitations : None known
|
||||
--
|
||||
--
|
||||
-- Notes : -
|
||||
--
|
||||
--
|
||||
-- Author(s) : A. Freund (af) <a.freund@dsi-it.de>,
|
||||
-- M.v.d.Wall (mvdw) <vdwall@dsi-it.de>
|
||||
-- Digitale Signalverabeitung & Informationstechnik GmbH,
|
||||
-- Bremen, Germany
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Revision List:
|
||||
--
|
||||
-- see SVN logs
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Naming conventions:
|
||||
--
|
||||
-- - coding style: record-signals for related purposes (Gaisler-style)
|
||||
-- - active-low signals are indicated by appending "_n"
|
||||
-- - constants are in UPPERCASE
|
||||
-- - name parts are separated by "_"
|
||||
--
|
||||
-- ============================================================================
|
||||
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
use work.aes_definitions.all;
|
||||
use work.aes_row_ops.all;
|
||||
use work.aes_column_ops.all;
|
||||
|
||||
|
||||
|
||||
package aes_common is
|
||||
|
||||
|
||||
function add_round_key(state, state_key : aes_state_t) return aes_state_t;
|
||||
|
||||
function select_column(state : aes_state_t; pos : natural) return column_t;
|
||||
|
||||
function replace_column(state : aes_state_t; col : column_t; pos : natural) return aes_state_t;
|
||||
|
||||
function select_row(state : aes_state_t; pos : natural) return row_t;
|
||||
|
||||
function replace_row(state : aes_state_t; row : row_t; pos : natural) return aes_state_t;
|
||||
|
||||
function to_aes_state_matrix(st : aes_state_t) return aes_sbox_matrix_t;
|
||||
function to_aes_state_vector(bb : aes_sbox_matrix_t) return aes_state_t;
|
||||
|
||||
end aes_common;
|
||||
|
||||
|
||||
package body aes_common is
|
||||
|
||||
|
||||
function add_round_key(state, state_key : aes_state_t) return aes_state_t is
|
||||
begin
|
||||
return (state xor state_key);
|
||||
end add_round_key;
|
||||
|
||||
|
||||
function select_column(state : aes_state_t; pos : natural) return column_t is
|
||||
variable v_col : column_t;
|
||||
begin
|
||||
for i in v_col'range loop
|
||||
v_col(i) := state((127 - 32*pos - 8*i) downto (127 - 32*pos - 8*i) - 7);
|
||||
end loop;
|
||||
|
||||
return v_col;
|
||||
end select_column;
|
||||
|
||||
|
||||
|
||||
|
||||
function replace_column(state : aes_state_t; col : column_t; pos : natural) return aes_state_t is
|
||||
variable v_st : aes_state_t;
|
||||
begin
|
||||
v_st := state;
|
||||
|
||||
for i in col'range loop
|
||||
v_st((127 - 32*pos - 8*i) downto (127 - 32*pos - 8*i) - 7) := col(i);
|
||||
end loop;
|
||||
|
||||
return v_st;
|
||||
end replace_column;
|
||||
|
||||
|
||||
|
||||
|
||||
function select_row(state : aes_state_t; pos : natural) return row_t is
|
||||
variable v_row : row_t;
|
||||
begin
|
||||
for i in v_row'range loop
|
||||
v_row(i) := state((127 - 8*pos - 32*i) downto (127 - 8*pos - 32*i) - 7);
|
||||
end loop;
|
||||
|
||||
return v_row;
|
||||
end select_row;
|
||||
|
||||
|
||||
|
||||
|
||||
function replace_row(state : aes_state_t; row : row_t; pos : natural) return aes_state_t is
|
||||
variable v_st : aes_state_t;
|
||||
begin
|
||||
v_st := state;
|
||||
|
||||
for i in row'range loop
|
||||
v_st((127 - 8*pos - 32*i) downto (127 - 8*pos - 32*i) - 7) := row(i);
|
||||
end loop;
|
||||
|
||||
return v_st;
|
||||
end replace_row;
|
||||
|
||||
|
||||
|
||||
function to_aes_state_matrix(st : aes_state_t) return aes_sbox_matrix_t is
|
||||
variable v_row : row_t;
|
||||
variable v_line : std_logic_vector(31 downto 0);
|
||||
variable v_bb : aes_sbox_matrix_t;
|
||||
begin
|
||||
for r in v_bb'range(1) loop
|
||||
for c in v_bb'range(2) loop
|
||||
v_bb(r, c) := (others => '0');
|
||||
end loop;
|
||||
end loop;
|
||||
|
||||
for r in v_bb'range(1) loop
|
||||
v_row := select_row(st, r);
|
||||
v_line := v_row(0) & v_row(1) & v_row(2) & v_row(3);
|
||||
|
||||
for c in v_bb'range(2) loop
|
||||
v_bb(r, c)(7 downto 0) := v_line(31 - 8*c downto 24 - 8*c);
|
||||
end loop;
|
||||
|
||||
end loop;
|
||||
|
||||
return v_bb;
|
||||
end to_aes_state_matrix;
|
||||
|
||||
|
||||
|
||||
function to_aes_state_vector(bb : aes_sbox_matrix_t) return aes_state_t is
|
||||
variable v_row : row_t;
|
||||
variable v_line : std_logic_vector(31 downto 0);
|
||||
variable v_st : aes_state_t;
|
||||
begin
|
||||
v_st := (others => '0');
|
||||
|
||||
for r in bb'range(1) loop
|
||||
v_line := (others => '0');
|
||||
|
||||
for c in bb'range(2) loop
|
||||
v_line(31 - 8*c downto 24 - 8*c) := bb(r, c)(7 downto 0);
|
||||
end loop;
|
||||
|
||||
for i in v_row'range loop
|
||||
v_row(i) := v_line(31 - 8*i downto 31-8*i - 7);
|
||||
end loop;
|
||||
|
||||
v_st := replace_row(v_st, v_row, r);
|
||||
end loop;
|
||||
|
||||
return v_st;
|
||||
end to_aes_state_vector;
|
||||
|
||||
|
||||
end aes_common;
|
||||
@@ -0,0 +1,115 @@
|
||||
--- ============================================================================
|
||||
--
|
||||
-- Design unit : aes_decryption
|
||||
--
|
||||
-- File Name : aes_decryption.vhd
|
||||
--
|
||||
-- Purpose : design file
|
||||
--
|
||||
--
|
||||
-- Depends on :
|
||||
--
|
||||
-- - Package(s) : -
|
||||
--
|
||||
-- - Module(s) : -
|
||||
--
|
||||
--
|
||||
-- Dev. Platform : Xilinx ISE 8.1i SP3 / Win32 (W2k SP4)
|
||||
--
|
||||
-- - Simulator(s) : Modelsim XE III 6.0d
|
||||
--
|
||||
-- - Synthesis : Xilinx XST
|
||||
--
|
||||
-- - Place & Route : Xilinx PAR
|
||||
--
|
||||
--
|
||||
-- Errors : None known
|
||||
--
|
||||
--
|
||||
-- Limitations : None known
|
||||
--
|
||||
--
|
||||
-- Notes : -
|
||||
--
|
||||
--
|
||||
-- Author(s) : A. Freund (af) <a.freund@dsi-it.de>,
|
||||
-- M.v.d.Wall (mvdw) <vdwall@dsi-it.de>
|
||||
-- Digitale Signalverabeitung & Informationstechnik GmbH,
|
||||
-- Bremen, Germany
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Revision List:
|
||||
--
|
||||
-- see SVN logs
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Naming conventions:
|
||||
--
|
||||
-- - coding style: record-signals for related purposes (Gaisler-style)
|
||||
-- - active-low signals are indicated by appending "_n"
|
||||
-- - constants are in UPPERCASE
|
||||
-- - name parts are separated by "_"
|
||||
--
|
||||
-- ============================================================================
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
use work.aes_definitions.all;
|
||||
use work.aes_common.all;
|
||||
use work.aes_column_ops.all;
|
||||
use work.aes_row_ops.all;
|
||||
|
||||
|
||||
|
||||
package aes_decryption is
|
||||
|
||||
|
||||
function inv_mix_columns(st : in aes_state_t) return aes_state_t;
|
||||
|
||||
function inv_shift_rows(st : in aes_state_t) return aes_state_t;
|
||||
|
||||
|
||||
end aes_decryption;
|
||||
|
||||
|
||||
package body aes_decryption is
|
||||
|
||||
|
||||
function inv_mix_columns(st : in aes_state_t) return aes_state_t is
|
||||
type columns_t is array(0 to 3) of column_t;
|
||||
variable v_cols : columns_t;
|
||||
variable v_st : aes_state_t;
|
||||
begin
|
||||
for i in v_cols'range loop
|
||||
v_cols(i) := inv_mix_column(select_column(st, i));
|
||||
v_st := replace_column(v_st, v_cols(i), i);
|
||||
end loop;
|
||||
|
||||
return v_st;
|
||||
end inv_mix_columns;
|
||||
|
||||
|
||||
|
||||
|
||||
function inv_shift_rows(st : in aes_state_t) return aes_state_t is
|
||||
type rows_t is array(0 to 3) of row_t;
|
||||
variable v_rows : rows_t;
|
||||
variable v_st : aes_state_t;
|
||||
begin
|
||||
for i in v_rows'range loop
|
||||
v_rows(i) := inv_shift_row(select_row(st, i), i);
|
||||
v_st := replace_row(v_st, v_rows(i), i);
|
||||
end loop;
|
||||
|
||||
return v_st;
|
||||
end inv_shift_rows;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
end aes_decryption;
|
||||
@@ -0,0 +1,83 @@
|
||||
--- ============================================================================
|
||||
--
|
||||
-- Design unit : aes_definitions
|
||||
--
|
||||
-- File Name : aes_definitions.vhd
|
||||
--
|
||||
-- Purpose : This package defines supplemental types, subtypes,
|
||||
-- constants, and functions
|
||||
--
|
||||
--
|
||||
-- Depends on :
|
||||
--
|
||||
-- - Package(s) : -
|
||||
--
|
||||
-- - Module(s) : -
|
||||
--
|
||||
--
|
||||
-- Dev. Platform : Xilinx ISE 8.1i SP3 / Win32 (W2k SP4)
|
||||
--
|
||||
-- - Simulator(s) : Modelsim XE III 6.0d
|
||||
--
|
||||
-- - Synthesis : Xilinx XST
|
||||
--
|
||||
-- - Place & Route : Xilinx PAR
|
||||
--
|
||||
--
|
||||
-- Errors : None known
|
||||
--
|
||||
--
|
||||
-- Limitations : None known
|
||||
--
|
||||
--
|
||||
-- Notes : -
|
||||
--
|
||||
--
|
||||
-- Author(s) : A. Freund (af) <a.freund@dsi-it.de>,
|
||||
-- M.v.d.Wall (mvdw) <vdwall@dsi-it.de>
|
||||
-- Digitale Signalverabeitung & Informationstechnik GmbH,
|
||||
-- Bremen, Germany
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Revision List:
|
||||
--
|
||||
-- see SVN logs
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Naming conventions:
|
||||
--
|
||||
-- - coding style: record-signals for related purposes (Gaisler-style)
|
||||
-- - active-low signals are indicated by appending "_n"
|
||||
-- - constants are in UPPERCASE
|
||||
-- - name parts are separated by "_"
|
||||
--
|
||||
-- ============================================================================
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
|
||||
|
||||
package aes_definitions is
|
||||
|
||||
|
||||
constant AES_128_ROUNDS : natural := 10;
|
||||
|
||||
constant AES_256_ROUNDS : natural := 14;
|
||||
|
||||
|
||||
subtype aes_state_t is std_logic_vector(127 downto 0);
|
||||
|
||||
-- 4 bit are sufficient to keep maximal round number
|
||||
subtype aes_round_no_t is std_logic_vector(3 downto 0);
|
||||
|
||||
|
||||
subtype aes_sbox_8_t is std_logic_vector(7 downto 0);
|
||||
|
||||
|
||||
type aes_sbox_matrix_t is array(0 to 3, 0 to 3) of aes_sbox_8_t;
|
||||
|
||||
|
||||
end aes_definitions;
|
||||
@@ -0,0 +1,110 @@
|
||||
--- ============================================================================
|
||||
--
|
||||
-- Design unit : aes_encryption
|
||||
--
|
||||
-- File Name : aes_encryption.vhd
|
||||
--
|
||||
-- Purpose : Design file
|
||||
--
|
||||
--
|
||||
-- Depends on :
|
||||
--
|
||||
-- - Package(s) : -
|
||||
--
|
||||
-- - Module(s) : -
|
||||
--
|
||||
--
|
||||
-- Dev. Platform : Xilinx ISE 8.1i SP3 / Win32 (W2k SP4)
|
||||
--
|
||||
-- - Simulator(s) : Modelsim XE III 6.0d
|
||||
--
|
||||
-- - Synthesis : Xilinx XST
|
||||
--
|
||||
-- - Place & Route : Xilinx PAR
|
||||
--
|
||||
--
|
||||
-- Errors : None known
|
||||
--
|
||||
--
|
||||
-- Limitations : None known
|
||||
--
|
||||
--
|
||||
-- Notes : -
|
||||
--
|
||||
--
|
||||
-- Author(s) : A. Freund (af) <a.freund@dsi-it.de>,
|
||||
-- M.v.d.Wall (mvdw) <vdwall@dsi-it.de>
|
||||
-- Digitale Signalverabeitung & Informationstechnik GmbH,
|
||||
-- Bremen, Germany
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Revision List:
|
||||
--
|
||||
-- see SVN logs
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Naming conventions:
|
||||
--
|
||||
-- - coding style: record-signals for related purposes (Gaisler-style)
|
||||
-- - active-low signals are indicated by appending "_n"
|
||||
-- - constants are in UPPERCASE
|
||||
-- - name parts are separated by "_"
|
||||
--
|
||||
-- ============================================================================
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
use work.aes_definitions.all;
|
||||
use work.aes_common.all;
|
||||
use work.aes_column_ops.all;
|
||||
use work.aes_row_ops.all;
|
||||
|
||||
|
||||
package aes_encryption is
|
||||
|
||||
|
||||
function mix_columns(st : in aes_state_t) return aes_state_t;
|
||||
|
||||
function shift_rows(st : in aes_state_t) return aes_state_t;
|
||||
|
||||
|
||||
end aes_encryption;
|
||||
|
||||
|
||||
package body aes_encryption is
|
||||
|
||||
|
||||
function mix_columns(st : in aes_state_t) return aes_state_t is
|
||||
type columns_t is array(0 to 3) of column_t;
|
||||
variable v_cols : columns_t;
|
||||
variable v_st : aes_state_t;
|
||||
begin
|
||||
for i in v_cols'range loop
|
||||
v_cols(i) := mix_column(select_column(st, i));
|
||||
v_st := replace_column(v_st, v_cols(i), i);
|
||||
end loop;
|
||||
|
||||
return v_st;
|
||||
end mix_columns;
|
||||
|
||||
|
||||
|
||||
|
||||
function shift_rows(st : in aes_state_t) return aes_state_t is
|
||||
type rows_t is array(0 to 3) of row_t;
|
||||
variable v_rows : rows_t;
|
||||
variable v_st : aes_state_t;
|
||||
begin
|
||||
for i in v_rows'range loop
|
||||
v_rows(i) := shift_row(select_row(st, i), i);
|
||||
v_st := replace_row(v_st, v_rows(i), i);
|
||||
end loop;
|
||||
|
||||
return v_st;
|
||||
end shift_rows;
|
||||
|
||||
|
||||
end aes_encryption;
|
||||
@@ -0,0 +1,168 @@
|
||||
--- ============================================================================
|
||||
--
|
||||
-- Design unit : aes_gf_2exp8_arith
|
||||
--
|
||||
-- File Name : aes_gf_2exp8_arith.vhd
|
||||
--
|
||||
-- Purpose : Design file
|
||||
--
|
||||
--
|
||||
-- Depends on :
|
||||
--
|
||||
-- - Package(s) : -
|
||||
--
|
||||
-- - Module(s) : -
|
||||
--
|
||||
--
|
||||
-- Dev. Platform : Xilinx ISE 8.1i SP3 / Win32 (W2k SP4)
|
||||
--
|
||||
-- - Simulator(s) : Modelsim XE III 6.0d
|
||||
--
|
||||
-- - Synthesis : Xilinx XST
|
||||
--
|
||||
-- - Place & Route : Xilinx PAR
|
||||
--
|
||||
--
|
||||
-- Errors : None known
|
||||
--
|
||||
--
|
||||
-- Limitations : None known
|
||||
--
|
||||
--
|
||||
-- Notes : -
|
||||
--
|
||||
--
|
||||
-- Author(s) : A. Freund (af) <a.freund@dsi-it.de>,
|
||||
-- M.v.d.Wall (mvdw) <vdwall@dsi-it.de>
|
||||
-- Digitale Signalverabeitung & Informationstechnik GmbH,
|
||||
-- Bremen, Germany
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Revision List:
|
||||
--
|
||||
-- see SVN logs
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Naming conventions:
|
||||
--
|
||||
-- - coding style: record-signals for related purposes (Gaisler-style)
|
||||
-- - active-low signals are indicated by appending "_n"
|
||||
-- - constants are in UPPERCASE
|
||||
-- - name parts are separated by "_"
|
||||
--
|
||||
-- ============================================================================
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
|
||||
package aes_gf_2exp8_arith is
|
||||
|
||||
|
||||
subtype gf_2exp8_t is std_logic_vector(7 downto 0);
|
||||
|
||||
|
||||
function add_gf_2exp8(a, b : in gf_2exp8_t) return gf_2exp8_t;
|
||||
|
||||
function mul_gf_2exp8(a, b : in gf_2exp8_t) return gf_2exp8_t;
|
||||
|
||||
|
||||
end aes_gf_2exp8_arith;
|
||||
|
||||
|
||||
-- AES irreducible polynomial
|
||||
-- POLY = 2**8 + 2**4 + 2**3 + 2**1 + 2**0
|
||||
|
||||
package body aes_gf_2exp8_arith is
|
||||
|
||||
|
||||
function add_gf_2exp8(a, b : in gf_2exp8_t) return gf_2exp8_t is
|
||||
begin
|
||||
return (a xor b);
|
||||
end add_gf_2exp8;
|
||||
|
||||
|
||||
function mul_gf_2exp8(a, b : in gf_2exp8_t) return gf_2exp8_t is
|
||||
variable c : gf_2exp8_t;
|
||||
begin
|
||||
|
||||
c(0) := ((a(0)) and b(0)) xor
|
||||
((a(7)) and b(1)) xor
|
||||
((a(6)) and b(2)) xor
|
||||
((a(5)) and b(3)) xor
|
||||
((a(4)) and b(4)) xor
|
||||
((a(3) xor a(7)) and b(5)) xor
|
||||
((a(2) xor a(6) xor a(7)) and b(6)) xor
|
||||
((a(1) xor a(5) xor a(6)) and b(7));
|
||||
|
||||
c(1) := ((a(1)) and b(0)) xor
|
||||
((a(0) xor a(7)) and b(1)) xor
|
||||
((a(6) xor a(7)) and b(2)) xor
|
||||
((a(5) xor a(6)) and b(3)) xor
|
||||
((a(4) xor a(5)) and b(4)) xor
|
||||
((a(3) xor a(4) xor a(7)) and b(5)) xor
|
||||
((a(2) xor a(3) xor a(6)) and b(6)) xor
|
||||
((a(1) xor a(2) xor a(5) xor a(7)) and b(7));
|
||||
|
||||
c(2) := ((a(2)) and b(0)) xor
|
||||
((a(1)) and b(1)) xor
|
||||
((a(0) xor a(7)) and b(2)) xor
|
||||
((a(6) xor a(7)) and b(3)) xor
|
||||
((a(5) xor a(6)) and b(4)) xor
|
||||
((a(4) xor a(5)) and b(5)) xor
|
||||
((a(3) xor a(4) xor a(7)) and b(6)) xor
|
||||
((a(2) xor a(3) xor a(6)) and b(7));
|
||||
|
||||
c(3) := ((a(3)) and b(0)) xor
|
||||
((a(2) xor a(7)) and b(1)) xor
|
||||
((a(1) xor a(6)) and b(2)) xor
|
||||
((a(0) xor a(5) xor a(7)) and b(3)) xor
|
||||
((a(4) xor a(6) xor a(7)) and b(4)) xor
|
||||
((a(3) xor a(5) xor a(6) xor a(7)) and b(5)) xor
|
||||
((a(2) xor a(4) xor a(5) xor a(6) xor a(7)) and b(6)) xor
|
||||
((a(1) xor a(3) xor a(4) xor a(5) xor a(6) xor a(7)) and b(7));
|
||||
|
||||
c(4) := ((a(4)) and b(0)) xor
|
||||
((a(3) xor a(7)) and b(1)) xor
|
||||
((a(2) xor a(6) xor a(7)) and b(2)) xor
|
||||
((a(1) xor a(5) xor a(6)) and b(3)) xor
|
||||
((a(0) xor a(4) xor a(5) xor a(7)) and b(4)) xor
|
||||
((a(3) xor a(4) xor a(6)) and b(5)) xor
|
||||
((a(2) xor a(3) xor a(5)) and b(6)) xor
|
||||
((a(1) xor a(2) xor a(4) xor a(7)) and b(7));
|
||||
|
||||
c(5) := ((a(5)) and b(0)) xor
|
||||
((a(4)) and b(1)) xor
|
||||
((a(3) xor a(7)) and b(2)) xor
|
||||
((a(2) xor a(6) xor a(7)) and b(3)) xor
|
||||
((a(1) xor a(5) xor a(6)) and b(4)) xor
|
||||
((a(0) xor a(4) xor a(5) xor a(7)) and b(5)) xor
|
||||
((a(3) xor a(4) xor a(6)) and b(6)) xor
|
||||
((a(2) xor a(3) xor a(5)) and b(7));
|
||||
|
||||
c(6) := ((a(6)) and b(0)) xor
|
||||
((a(5)) and b(1)) xor
|
||||
((a(4)) and b(2)) xor
|
||||
((a(3) xor a(7)) and b(3)) xor
|
||||
((a(2) xor a(6) xor a(7)) and b(4)) xor
|
||||
((a(1) xor a(5) xor a(6)) and b(5)) xor
|
||||
((a(0) xor a(4) xor a(5) xor a(7)) and b(6)) xor
|
||||
((a(3) xor a(4) xor a(6)) and b(7));
|
||||
|
||||
c(7) := ((a(7)) and b(0)) xor
|
||||
((a(6)) and b(1)) xor
|
||||
((a(5)) and b(2)) xor
|
||||
((a(4)) and b(3)) xor
|
||||
((a(3) xor a(7)) and b(4)) xor
|
||||
((a(2) xor a(6) xor a(7)) and b(5)) xor
|
||||
((a(1) xor a(5) xor a(6)) and b(6)) xor
|
||||
((a(0) xor a(4) xor a(5) xor a(7)) and b(7));
|
||||
|
||||
return c;
|
||||
|
||||
end mul_gf_2exp8;
|
||||
|
||||
|
||||
end aes_gf_2exp8_arith;
|
||||
@@ -0,0 +1,105 @@
|
||||
--- ============================================================================
|
||||
--
|
||||
-- Design unit : aes
|
||||
--
|
||||
-- File Name : aes_row_ops.vhd
|
||||
--
|
||||
-- Purpose : Row shift operations for ciper and inverse ciphers
|
||||
--
|
||||
--
|
||||
-- Depends on :
|
||||
--
|
||||
-- - Package(s) : -
|
||||
--
|
||||
-- - Module(s) : -
|
||||
--
|
||||
--
|
||||
-- Dev. Platform : Xilinx ISE 8.1i SP3 / Win32 (W2k SP4)
|
||||
--
|
||||
-- - Simulator(s) : Modelsim XE III 6.0d
|
||||
--
|
||||
-- - Synthesis : Xilinx XST
|
||||
--
|
||||
-- - Place & Route : Xilinx PAR
|
||||
--
|
||||
--
|
||||
-- Errors : None known
|
||||
--
|
||||
--
|
||||
-- Limitations : None known
|
||||
--
|
||||
--
|
||||
-- Notes : -
|
||||
--
|
||||
--
|
||||
-- Author(s) : A. Freund (af) <a.freund@dsi-it.de>,
|
||||
-- M.v.d.Wall (mvdw) <vdwall@dsi-it.de>
|
||||
-- J. Ahrensfeld (ja) <ja@dsi-it.de>
|
||||
-- Digitale Signalverabeitung & Informationstechnik GmbH,
|
||||
-- Bremen, Germany
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Revision List:
|
||||
--
|
||||
-- see SVN logs
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Naming conventions:
|
||||
--
|
||||
-- - coding style: record-signals for related purposes (Gaisler-style)
|
||||
-- - active-low signals are indicated by appending "_n"
|
||||
-- - constants are in UPPERCASE
|
||||
-- - name parts are separated by "_"
|
||||
--
|
||||
-- ============================================================================
|
||||
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
-- use ieee.numeric_bit.all;
|
||||
|
||||
use work.aes_gf_2exp8_arith.all;
|
||||
|
||||
|
||||
package aes_row_ops is
|
||||
|
||||
|
||||
type row_t is array (0 to 3) of gf_2exp8_t;
|
||||
|
||||
|
||||
function shift_row(row : in row_t; steps : natural) return row_t;
|
||||
|
||||
function inv_shift_row(row : in row_t; steps : natural) return row_t;
|
||||
|
||||
|
||||
end aes_row_ops;
|
||||
|
||||
|
||||
package body aes_row_ops is
|
||||
|
||||
|
||||
function shift_row(row : in row_t; steps : natural) return row_t is
|
||||
variable a_row : row_t;
|
||||
begin
|
||||
for i in a_row'range loop
|
||||
a_row(i) := row((i + steps) mod row'length);
|
||||
end loop;
|
||||
|
||||
return a_row;
|
||||
end shift_row;
|
||||
|
||||
|
||||
function inv_shift_row(row : in row_t; steps : natural) return row_t is
|
||||
variable a_row : row_t;
|
||||
begin
|
||||
for i in a_row'range loop
|
||||
a_row(i) := row((i - steps + row'length) mod row'length);
|
||||
end loop;
|
||||
|
||||
return a_row;
|
||||
end inv_shift_row;
|
||||
|
||||
|
||||
end aes_row_ops;
|
||||
@@ -0,0 +1,185 @@
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Design unit : cbc_128_encryption_core (CBC-mode encryption core with
|
||||
-- 128-bit key schedule)
|
||||
--
|
||||
-- File Name : cbc_128_encryption_core.vhd
|
||||
--
|
||||
-- Purpose : The module instantiates all necessary modules (S-box
|
||||
-- stages, encryption, CBC-mode, key schedule, subkey
|
||||
-- memory etc.) to provide an CBC-mode encryption core
|
||||
--
|
||||
--
|
||||
-- Depends on :
|
||||
--
|
||||
-- - Package(s) : tech_iface, key_schedule_iface, engine_iface,
|
||||
-- cbc_mode_iface, cbc_core_iface
|
||||
--
|
||||
-- - Module(s) : cbc_mode_encryption, encryption_engine, tech_sbox_stage,
|
||||
-- tech_subkey_memory, key_schedule_128
|
||||
--
|
||||
--
|
||||
-- Dev. Platform : Xilinx ISE 8.1i SP3 / Win32 (W2k SP4)
|
||||
--
|
||||
-- - Simulator(s) : Modelsim XE III 6.0d
|
||||
--
|
||||
-- - Synthesis : Xilinx XST
|
||||
--
|
||||
-- - Place & Route : Xilinx PAR
|
||||
--
|
||||
--
|
||||
-- Errors : None known
|
||||
--
|
||||
--
|
||||
-- Limitations : None known
|
||||
--
|
||||
--
|
||||
-- Notes : Version for implementation using 32-bit datapath
|
||||
--
|
||||
--
|
||||
-- Author(s) : A. Freund (af) <a.freund@dsi-it.de>
|
||||
-- Digitale Signalverabeitung & Informationstechnik GmbH,
|
||||
-- Bremen, Germany
|
||||
--
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Revision List:
|
||||
-- Version Author(s) Date Changes
|
||||
--
|
||||
-- v0.00 af 2007-01-31 initial version
|
||||
--
|
||||
-- see SVN logs
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Naming conventions:
|
||||
--
|
||||
-- - coding style: record-signals for related purposes (Gaisler-style)
|
||||
-- - active-low signals are indicated by appending "_n"
|
||||
-- - constants are in UPPERCASE
|
||||
-- - name parts are separated by "_"
|
||||
--
|
||||
-- ============================================================================
|
||||
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_arith.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
|
||||
|
||||
use work.tech_iface.all;
|
||||
use work.key_schedule_iface.all;
|
||||
use work.engine_iface.all;
|
||||
use work.cbc_mode_iface.all;
|
||||
use work.cbc_core_iface.all;
|
||||
|
||||
|
||||
entity cbc_128_encryption_core is
|
||||
port (
|
||||
rst : in std_logic; -- reset
|
||||
clk : in std_logic; -- clock
|
||||
mode_i : in cbc_mode_encryption_in_type; -- see package cbc_mode_iface
|
||||
mode_o : out cbc_mode_encryption_out_type; -- see package cbc_mode_iface
|
||||
key_i : in key_schedule_128_in_type; -- see package key_schedule_iface
|
||||
key_o : out key_schedule_128_out_type; -- see package key_schedule_iface
|
||||
sbld_i : in sbox_stage_load_in_type -- see package tech_iface
|
||||
);
|
||||
end cbc_128_encryption_core;
|
||||
|
||||
|
||||
architecture behavioural of cbc_128_encryption_core is
|
||||
|
||||
|
||||
signal enc_i : encryption_engine_in_type; -- input to the encryption engine
|
||||
signal enc_o : encryption_engine_out_type; -- output of the encryption engine
|
||||
|
||||
signal sbox_enc_i : sbox_stage_in_type; -- input to the S-box stage
|
||||
signal sbox_enc_o : sbox_stage_out_type; -- output of the S-box stage
|
||||
|
||||
signal sbox_ks_i : sbox_stage_in_type; -- input to the S-box stage (key schedule)
|
||||
signal sbox_ks_o : sbox_stage_out_type; -- output of the S-box stage (key schedule)
|
||||
|
||||
signal skm_enc_i : subkey_memory_ed_in_type; -- encryption-side subkey memory access (subkey selection)
|
||||
signal skm_enc_o : subkey_memory_ed_out_type; -- encryption-side subkey memory access (selected subkey)
|
||||
|
||||
signal skm_ks_enc_i : subkey_memory_ks_in_type; -- subkey storage by key schedule
|
||||
|
||||
|
||||
begin
|
||||
|
||||
|
||||
-- AES CBC-mode encryption
|
||||
cbc_mode: cbc_mode_encryption
|
||||
port map (
|
||||
rst => rst,
|
||||
clk => clk,
|
||||
mode_i => mode_i,
|
||||
mode_o => mode_o,
|
||||
enc_i => enc_o,
|
||||
enc_o => enc_i
|
||||
);
|
||||
|
||||
|
||||
-- AES encryption engine
|
||||
enc_eng: encryption_engine
|
||||
port map (
|
||||
rst => rst,
|
||||
clk => clk,
|
||||
enc_i => enc_i,
|
||||
enc_o => enc_o,
|
||||
skm_i => skm_enc_o,
|
||||
skm_o => skm_enc_i,
|
||||
sbox_i => sbox_enc_o,
|
||||
sbox_o => sbox_enc_i
|
||||
);
|
||||
|
||||
|
||||
-- S-Box stage for encryption engine
|
||||
sbox_enc: tech_sbox_stage
|
||||
port map (
|
||||
rst => rst,
|
||||
clk => clk,
|
||||
data_i => sbox_enc_i,
|
||||
data_o => sbox_enc_o,
|
||||
load_i => sbld_i
|
||||
);
|
||||
|
||||
|
||||
-- subkey memory for encryption engine
|
||||
skm_enc: tech_subkey_memory
|
||||
port map (
|
||||
clk => clk,
|
||||
key_sched_i => skm_ks_enc_i,
|
||||
enc_dec_i => skm_enc_i,
|
||||
enc_dec_o => skm_enc_o
|
||||
);
|
||||
|
||||
|
||||
-- 128-bit key schedule
|
||||
key_sched: key_schedule_128
|
||||
port map (
|
||||
rst => rst,
|
||||
clk => clk,
|
||||
key_i => key_i,
|
||||
key_o => key_o,
|
||||
sbox_i => sbox_ks_o,
|
||||
sbox_o => sbox_ks_i,
|
||||
skm_enc_o => skm_ks_enc_i,
|
||||
skm_dec_o => open
|
||||
);
|
||||
|
||||
|
||||
-- S-Box stage for key schedule
|
||||
sbox_ks: tech_sbox_stage
|
||||
port map (
|
||||
rst => rst,
|
||||
clk => clk,
|
||||
data_i => sbox_ks_i,
|
||||
data_o => sbox_ks_o,
|
||||
load_i => sbld_i
|
||||
);
|
||||
|
||||
|
||||
end behavioural;
|
||||
+2430
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,146 @@
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Design unit : cbc_core_iface (interfaces of CBC-mode en-/decryption
|
||||
-- cores)
|
||||
--
|
||||
-- File Name : cbc_core_iface.vhd
|
||||
--
|
||||
-- Purpose : The package collects type declarations for all non-
|
||||
-- trivial interfaces of used entities. Record types
|
||||
-- are used extensively to group related signals (e.g.
|
||||
-- data / control & status, physical attachment etc.).
|
||||
--
|
||||
--
|
||||
-- Depends on :
|
||||
--
|
||||
-- - Package(s) : tech_iface, key_schedule_iface, engine_iface,
|
||||
-- cbc_mode_iface
|
||||
--
|
||||
-- - Module(s) : -
|
||||
--
|
||||
--
|
||||
-- Dev. Platform : Xilinx ISE 8.1i SP3 / Win32 (W2k SP4)
|
||||
--
|
||||
-- - Simulator(s) : Modelsim XE III 6.0d
|
||||
--
|
||||
-- - Synthesis : Xilinx XST
|
||||
--
|
||||
-- - Place & Route : Xilinx PAR
|
||||
--
|
||||
--
|
||||
-- Errors : None known
|
||||
--
|
||||
--
|
||||
-- Limitations : None known
|
||||
--
|
||||
--
|
||||
-- Notes : Version for implementation using 32-bit datapath
|
||||
--
|
||||
--
|
||||
-- Author(s) : A. Freund (af) <a.freund@dsi-it.de>
|
||||
-- Digitale Signalverabeitung & Informationstechnik GmbH,
|
||||
-- Bremen, Germany
|
||||
--
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Revision List:
|
||||
-- Version Author(s) Date Changes
|
||||
--
|
||||
-- v0.00 af 2007-01-31 initial version
|
||||
--
|
||||
-- see SVN logs
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Naming conventions:
|
||||
--
|
||||
-- - coding style: record-signals for related purposes (Gaisler-style)
|
||||
-- - active-low signals are indicated by appending "_n"
|
||||
-- - constants are in UPPERCASE
|
||||
-- - name parts are separated by "_"
|
||||
--
|
||||
-- ============================================================================
|
||||
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
|
||||
use work.tech_iface.all;
|
||||
use work.key_schedule_iface.all;
|
||||
use work.engine_iface.all;
|
||||
use work.cbc_mode_iface.all;
|
||||
|
||||
|
||||
package cbc_core_iface is
|
||||
|
||||
|
||||
-- no new interfaces are needed yet
|
||||
|
||||
|
||||
|
||||
--
|
||||
--
|
||||
-- Component declarations
|
||||
--
|
||||
--
|
||||
|
||||
|
||||
-- AES-CBC-128 encryption core
|
||||
component cbc_128_encryption_core is
|
||||
port (
|
||||
rst : in std_logic; -- reset
|
||||
clk : in std_logic; -- clock
|
||||
mode_i : in cbc_mode_encryption_in_type; -- see package cbc_mode_iface
|
||||
mode_o : out cbc_mode_encryption_out_type; -- see package cbc_mode_iface
|
||||
key_i : in key_schedule_128_in_type; -- see package key_schedule_iface
|
||||
key_o : out key_schedule_128_out_type; -- see package key_schedule_iface
|
||||
sbld_i : in sbox_stage_load_in_type -- see package tech_iface
|
||||
);
|
||||
end component;
|
||||
|
||||
|
||||
-- AES-CBC-128 decryption core
|
||||
component cbc_128_decryption_core is
|
||||
port (
|
||||
rst : in std_logic; -- reset
|
||||
clk : in std_logic; -- clock
|
||||
mode_i : in cbc_mode_decryption_in_type; -- see package cbc_mode_iface
|
||||
mode_o : out cbc_mode_decryption_out_type; -- see package cbc_mode_iface
|
||||
key_i : in key_schedule_128_in_type; -- see package key_schedule_iface
|
||||
key_o : out key_schedule_128_out_type; -- see package key_schedule_iface
|
||||
sbld_i : in sbox_stage_load_in_type -- see package tech_iface
|
||||
);
|
||||
end component;
|
||||
|
||||
|
||||
-- AES-CBC-256 encryption core
|
||||
component cbc_256_encryption_core is
|
||||
port (
|
||||
rst : in std_logic; -- reset
|
||||
clk : in std_logic; -- clock
|
||||
mode_i : in cbc_mode_encryption_in_type; -- see package cbc_mode_iface
|
||||
mode_o : out cbc_mode_encryption_out_type; -- see package cbc_mode_iface
|
||||
key_i : in key_schedule_256_in_type; -- see package key_schedule_iface
|
||||
key_o : out key_schedule_256_out_type; -- see package key_schedule_iface
|
||||
sbld_i : in sbox_stage_load_in_type -- see package tech_iface
|
||||
);
|
||||
end component;
|
||||
|
||||
|
||||
-- AES-CBC-256 decryption core
|
||||
component cbc_256_decryption_core is
|
||||
port (
|
||||
rst : in std_logic; -- reset
|
||||
clk : in std_logic; -- clock
|
||||
mode_i : in cbc_mode_decryption_in_type; -- see package cbc_mode_iface
|
||||
mode_o : out cbc_mode_decryption_out_type; -- see package cbc_mode_iface
|
||||
key_i : in key_schedule_256_in_type; -- see package key_schedule_iface
|
||||
key_o : out key_schedule_256_out_type; -- see package key_schedule_iface
|
||||
sbld_i : in sbox_stage_load_in_type -- see package tech_iface
|
||||
);
|
||||
end component;
|
||||
|
||||
|
||||
end cbc_core_iface;
|
||||
@@ -0,0 +1,272 @@
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Design unit : cbc_mode_encryption (CBC-mode encryption)
|
||||
--
|
||||
-- File Name : cbc_mode_encryption.vhd
|
||||
--
|
||||
-- Purpose : The module provides CBC-mode encryption for AES
|
||||
-- using 32-bit datapath
|
||||
--
|
||||
--
|
||||
-- Depends on :
|
||||
--
|
||||
-- - Package(s) : aes_defnitions, tech_iface, engine_iface, cbc_mode_iface
|
||||
--
|
||||
-- - Module(s) : -
|
||||
--
|
||||
--
|
||||
-- Dev. Platform : Xilinx ISE 8.1i SP3 / Win32 (W2k SP4)
|
||||
--
|
||||
-- - Simulator(s) : Modelsim XE III 6.0d
|
||||
--
|
||||
-- - Synthesis : Xilinx XST
|
||||
--
|
||||
-- - Place & Route : Xilinx PAR
|
||||
--
|
||||
--
|
||||
-- Errors : None known
|
||||
--
|
||||
--
|
||||
-- Limitations : None known
|
||||
--
|
||||
--
|
||||
-- Notes : Version for implementation using 32-bit datapath
|
||||
--
|
||||
--
|
||||
-- Author(s) : A. Freund (af) <a.freund@dsi-it.de>
|
||||
-- Digitale Signalverabeitung & Informationstechnik GmbH,
|
||||
-- Bremen, Germany
|
||||
--
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Revision List:
|
||||
-- Version Author(s) Date Changes
|
||||
--
|
||||
-- v0.00 af 2007-01-31 initial version
|
||||
--
|
||||
-- see SVN logs
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Naming conventions:
|
||||
--
|
||||
-- - coding style: two-process method (Gaisler-style)
|
||||
-- - active-low signals are indicated by appending "_n"
|
||||
-- - constants are in UPPERCASE
|
||||
-- - name parts are separated by "_"
|
||||
--
|
||||
-- ============================================================================
|
||||
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_arith.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
|
||||
|
||||
use work.aes_definitions.all;
|
||||
use work.tech_iface.all;
|
||||
use work.engine_iface.all;
|
||||
use work.cbc_mode_iface.all;
|
||||
|
||||
|
||||
entity cbc_mode_encryption is
|
||||
port (
|
||||
rst : in std_logic; -- reset
|
||||
clk : in std_logic; -- clock
|
||||
mode_i : in cbc_mode_encryption_in_type; -- see package cbc_mode_iface
|
||||
mode_o : out cbc_mode_encryption_out_type; -- see package cbc_mode_iface
|
||||
enc_i : in encryption_engine_out_type; -- see package engine_iface
|
||||
enc_o : out encryption_engine_in_type -- see package engine_iface
|
||||
);
|
||||
end cbc_mode_encryption;
|
||||
|
||||
|
||||
architecture behavioural of cbc_mode_encryption is
|
||||
|
||||
|
||||
-- control fsm, states: idle / load IV / load input data / wait while encrypting / output data
|
||||
type ctrl_fsm_t is (cf_idle, cf_load_iv, cf_load_data, cf_wait_enc, cf_out_data);
|
||||
|
||||
type registers is record
|
||||
ctrl_fsm : ctrl_fsm_t; -- control fsm
|
||||
busy : std_logic; -- busy, encryption in progress
|
||||
part_no : part_no_t; -- partial word number
|
||||
cbc_fb_shr : aes_state_t; -- CBC-mode feedback shift-register
|
||||
fb_shr_src : std_logic; -- data source for fb-shr: ciphertext (0) / IV @ din (1)
|
||||
fb_shr_shift : std_logic; -- shift-data into / out of fb-shr
|
||||
key_id : key_id_t; -- stored key ID
|
||||
end record;
|
||||
|
||||
|
||||
type variables is record
|
||||
dummy : std_logic;
|
||||
end record;
|
||||
|
||||
|
||||
signal r, rin : registers;
|
||||
|
||||
|
||||
begin
|
||||
|
||||
|
||||
-- combinatorial logic
|
||||
comb: process (rst, r, mode_i, enc_i)
|
||||
variable v : registers;
|
||||
variable t : variables;
|
||||
begin
|
||||
|
||||
-- assign default values
|
||||
v := r;
|
||||
--
|
||||
--
|
||||
--
|
||||
|
||||
if (r.fb_shr_shift = '1') or (enc_i.valid = '1')
|
||||
then
|
||||
v.part_no := r.part_no + 1;
|
||||
end if;
|
||||
|
||||
|
||||
-- control fsm
|
||||
case r.ctrl_fsm is
|
||||
-- wait for start / IV loading
|
||||
when cf_idle =>
|
||||
-- handle IV loading
|
||||
if (mode_i.load_iv = '1')
|
||||
then
|
||||
v.busy := '1';
|
||||
v.key_id := mode_i.key_id;
|
||||
v.fb_shr_shift := '1';
|
||||
v.part_no := "01";
|
||||
|
||||
v.ctrl_fsm := cf_load_iv;
|
||||
-- handle encryption start
|
||||
elsif (mode_i.start = '1')
|
||||
then
|
||||
v.fb_shr_src := '0'; -- use ciphertext as source
|
||||
v.fb_shr_shift := '1';
|
||||
v.part_no := "01";
|
||||
|
||||
v.ctrl_fsm := cf_load_data;
|
||||
end if;
|
||||
|
||||
-- load iv
|
||||
when cf_load_iv =>
|
||||
-- handle last input data word
|
||||
if (r.part_no = "11")
|
||||
then
|
||||
v.busy := '0';
|
||||
v.fb_shr_shift := '0'; -- partial number is hold at "00"
|
||||
|
||||
v.ctrl_fsm := cf_idle;
|
||||
end if;
|
||||
|
||||
-- load input data
|
||||
when cf_load_data =>
|
||||
-- handle last input data word
|
||||
if (r.part_no = "11")
|
||||
then
|
||||
v.fb_shr_shift := '0'; -- partial number is hold at "00"
|
||||
|
||||
v.ctrl_fsm := cf_wait_enc;
|
||||
end if;
|
||||
|
||||
-- wait while encrypting
|
||||
when cf_wait_enc =>
|
||||
if (enc_i.valid = '1')
|
||||
then
|
||||
v.part_no := "01";
|
||||
v.fb_shr_shift := '1';
|
||||
|
||||
v.ctrl_fsm := cf_out_data;
|
||||
end if;
|
||||
|
||||
-- ouput data
|
||||
when cf_out_data =>
|
||||
-- handle last output data word
|
||||
if (r.part_no = "11")
|
||||
then
|
||||
v.fb_shr_src := '1';
|
||||
v.fb_shr_shift := '0';
|
||||
|
||||
v.ctrl_fsm := cf_idle;
|
||||
end if;
|
||||
|
||||
|
||||
when others =>
|
||||
v.ctrl_fsm := cf_idle;
|
||||
|
||||
end case;
|
||||
|
||||
|
||||
-- CBC-mode feedback register operation (4x32-bit shift-register)
|
||||
if (mode_i.load_iv = '1') or (enc_i.valid = '1') or (r.fb_shr_shift = '1')
|
||||
then
|
||||
if (r.fb_shr_src = '1')
|
||||
then
|
||||
-- handle IV loading
|
||||
v.cbc_fb_shr(31 downto 0) := mode_i.din;
|
||||
else
|
||||
v.cbc_fb_shr(31 downto 0) := enc_i.cipher;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
if (mode_i.start = '1') or (r.fb_shr_shift = '1')
|
||||
then
|
||||
v.cbc_fb_shr(127 downto 32) := r.cbc_fb_shr(95 downto 0);
|
||||
end if;
|
||||
|
||||
--
|
||||
--
|
||||
--
|
||||
-- reset handling
|
||||
if (rst = '1')
|
||||
then
|
||||
v.fb_shr_shift := '0';
|
||||
v.fb_shr_src := '1';
|
||||
v.part_no := "00";
|
||||
v.busy := '0';
|
||||
v.key_id := (others => '0');
|
||||
|
||||
v.ctrl_fsm := cf_idle;
|
||||
|
||||
end if;
|
||||
--
|
||||
--
|
||||
--
|
||||
-- update registers
|
||||
rin <= v;
|
||||
--
|
||||
--
|
||||
--
|
||||
-- drive outputs
|
||||
enc_o.start <= mode_i.start;
|
||||
enc_o.plain <= mode_i.din xor r.cbc_fb_shr(127 downto 96);
|
||||
enc_o.key_id <= r.key_id;
|
||||
|
||||
mode_o.valid <= enc_i.valid;
|
||||
mode_o.busy <= enc_i.busy or r.busy;
|
||||
mode_o.dout <= enc_i.cipher;
|
||||
|
||||
|
||||
end process;
|
||||
|
||||
|
||||
-- registers
|
||||
regs: process (clk, rst)
|
||||
begin
|
||||
if rising_edge(clk)
|
||||
then
|
||||
r <= rin;
|
||||
end if;
|
||||
|
||||
-- async. reset
|
||||
if (rst = '1')
|
||||
then
|
||||
end if;
|
||||
end process;
|
||||
|
||||
|
||||
end behavioural;
|
||||
@@ -0,0 +1,153 @@
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Design unit : cbc_mode_iface (interfaces of CBC-mode en-/decryption
|
||||
-- modules)
|
||||
--
|
||||
-- File Name : cbc_mode_iface.vhd
|
||||
--
|
||||
-- Purpose : The package collects type declarations for all non-
|
||||
-- trivial interfaces of used entities. Record types
|
||||
-- are used extensively to group related signals (e.g.
|
||||
-- data / control & status, physical attachment etc.).
|
||||
--
|
||||
--
|
||||
-- Depends on :
|
||||
--
|
||||
-- - Package(s) : aes_definitions, tech_iface, engine_iface
|
||||
--
|
||||
-- - Module(s) : -
|
||||
--
|
||||
--
|
||||
-- Dev. Platform : Xilinx ISE 8.1i SP3 / Win32 (W2k SP4)
|
||||
--
|
||||
-- - Simulator(s) : Modelsim XE III 6.0d
|
||||
--
|
||||
-- - Synthesis : Xilinx XST
|
||||
--
|
||||
-- - Place & Route : Xilinx PAR
|
||||
--
|
||||
--
|
||||
-- Errors : None known
|
||||
--
|
||||
--
|
||||
-- Limitations : None known
|
||||
--
|
||||
--
|
||||
-- Notes : Version for implementation using 32-bit datapath
|
||||
--
|
||||
--
|
||||
-- Author(s) : A. Freund (af) <a.freund@dsi-it.de>
|
||||
-- Digitale Signalverabeitung & Informationstechnik GmbH,
|
||||
-- Bremen, Germany
|
||||
--
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Revision List:
|
||||
-- Version Author(s) Date Changes
|
||||
--
|
||||
-- v0.00 af 2007-01-31 initial version
|
||||
--
|
||||
-- see SVN logs
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Naming conventions:
|
||||
--
|
||||
-- - coding style: record-signals for related purposes (Gaisler-style)
|
||||
-- - active-low signals are indicated by appending "_n"
|
||||
-- - constants are in UPPERCASE
|
||||
-- - name parts are separated by "_"
|
||||
--
|
||||
-- ============================================================================
|
||||
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
|
||||
use work.aes_definitions.all;
|
||||
use work.tech_iface.all;
|
||||
use work.engine_iface.all;
|
||||
|
||||
|
||||
package cbc_mode_iface is
|
||||
|
||||
|
||||
--
|
||||
-- CBC-mode encryption interface definition
|
||||
--
|
||||
|
||||
|
||||
-- data/control input signals
|
||||
type cbc_mode_encryption_in_type is record
|
||||
start : std_logic; -- start encryption
|
||||
load_iv : std_logic; -- load IV
|
||||
din : part_data_t; -- IV / data to be encrypted (plaintext)
|
||||
key_id : key_id_t; -- key id to use
|
||||
end record;
|
||||
|
||||
-- data/status outputs signals
|
||||
type cbc_mode_encryption_out_type is record
|
||||
dout : part_data_t; -- encrypted data (ciphertext)
|
||||
busy : std_logic; -- busy, encrypion in progress
|
||||
valid : std_logic; -- ciphertext is valid
|
||||
end record;
|
||||
|
||||
|
||||
--
|
||||
-- CBC-mode decryption interface definition
|
||||
--
|
||||
|
||||
|
||||
-- data/control input signals
|
||||
type cbc_mode_decryption_in_type is record
|
||||
start : std_logic; -- start decryption
|
||||
load_iv : std_logic; -- load IV
|
||||
din : part_data_t; -- IV / data to be decrypted (ciphertext)
|
||||
key_id : key_id_t; -- key id to use
|
||||
end record;
|
||||
|
||||
-- data/status outputs signals
|
||||
type cbc_mode_decryption_out_type is record
|
||||
dout : part_data_t; -- decrypted data (plaintext)
|
||||
busy : std_logic; -- busy, decrypion in progress
|
||||
valid : std_logic; -- plaintext is valid
|
||||
end record;
|
||||
|
||||
|
||||
--
|
||||
--
|
||||
-- Component declarations
|
||||
--
|
||||
--
|
||||
|
||||
|
||||
-- AES CBC-mode encryption
|
||||
component cbc_mode_encryption is
|
||||
port (
|
||||
rst : in std_logic; -- reset
|
||||
clk : in std_logic; -- clock
|
||||
mode_i : in cbc_mode_encryption_in_type; -- see package cbc_mode_iface
|
||||
mode_o : out cbc_mode_encryption_out_type; -- see package cbc_mode_iface
|
||||
enc_i : in encryption_engine_out_type; -- see package engine_iface
|
||||
enc_o : out encryption_engine_in_type -- see package engine_iface
|
||||
);
|
||||
end component;
|
||||
|
||||
|
||||
|
||||
-- AES CBC-mode decryption
|
||||
component cbc_mode_decryption is
|
||||
port (
|
||||
rst : in std_logic; -- reset
|
||||
clk : in std_logic; -- clock
|
||||
mode_i : in cbc_mode_decryption_in_type; -- see package cbc_mode_iface
|
||||
mode_o : out cbc_mode_decryption_out_type; -- see package cbc_mode_iface
|
||||
dec_i : in decryption_engine_out_type; -- see package engine_iface
|
||||
dec_o : out decryption_engine_in_type -- see package engine_iface
|
||||
);
|
||||
end component;
|
||||
|
||||
|
||||
end cbc_mode_iface;
|
||||
@@ -0,0 +1,185 @@
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Design unit : ecb_128_encryption_core (ECB-mode encryption core with
|
||||
-- 128-bit key schedule)
|
||||
--
|
||||
-- File Name : ecb_128_encryption_core.vhd
|
||||
--
|
||||
-- Purpose : The module instantiates all necessary modules (S-box
|
||||
-- stages, encryption, ECB-mode, key schedule, subkey
|
||||
-- memory etc.) to provide an ECB-mode encryption core
|
||||
--
|
||||
--
|
||||
-- Depends on :
|
||||
--
|
||||
-- - Package(s) : tech_iface, key_schedule_iface, engine_iface,
|
||||
-- ecb_mode_iface, ecb_core_iface
|
||||
--
|
||||
-- - Module(s) : ecb_mode_encryption, encryption_engine, tech_sbox_stage,
|
||||
-- tech_subkey_memory, key_schedule_128
|
||||
--
|
||||
--
|
||||
-- Dev. Platform : Xilinx ISE 8.1i SP3 / Win32 (W2k SP4)
|
||||
--
|
||||
-- - Simulator(s) : Modelsim XE III 6.0d
|
||||
--
|
||||
-- - Synthesis : Xilinx XST
|
||||
--
|
||||
-- - Place & Route : Xilinx PAR
|
||||
--
|
||||
--
|
||||
-- Errors : None known
|
||||
--
|
||||
--
|
||||
-- Limitations : None known
|
||||
--
|
||||
--
|
||||
-- Notes : Version for implementation using 32-bit datapath
|
||||
--
|
||||
--
|
||||
-- Author(s) : A. Freund (af) <a.freund@dsi-it.de>
|
||||
-- Digitale Signalverabeitung & Informationstechnik GmbH,
|
||||
-- Bremen, Germany
|
||||
--
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Revision List:
|
||||
-- Version Author(s) Date Changes
|
||||
--
|
||||
-- v0.00 af 2006-11-15 initial version
|
||||
--
|
||||
-- see SVN logs
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Naming conventions:
|
||||
--
|
||||
-- - coding style: record-signals for related purposes (Gaisler-style)
|
||||
-- - active-low signals are indicated by appending "_n"
|
||||
-- - constants are in UPPERCASE
|
||||
-- - name parts are separated by "_"
|
||||
--
|
||||
-- ============================================================================
|
||||
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_arith.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
|
||||
|
||||
use work.tech_iface.all;
|
||||
use work.key_schedule_iface.all;
|
||||
use work.engine_iface.all;
|
||||
use work.ecb_mode_iface.all;
|
||||
use work.ecb_core_iface.all;
|
||||
|
||||
|
||||
entity ecb_128_encryption_core is
|
||||
port (
|
||||
rst : in std_logic; -- reset
|
||||
clk : in std_logic; -- clock
|
||||
mode_i : in ecb_mode_encryption_in_type; -- see package ecb_mode_iface
|
||||
mode_o : out ecb_mode_encryption_out_type; -- see package ecb_mode_iface
|
||||
key_i : in key_schedule_128_in_type; -- see package key_schedule_iface
|
||||
key_o : out key_schedule_128_out_type; -- see package key_schedule_iface
|
||||
sbld_i : in sbox_stage_load_in_type -- see package tech_iface
|
||||
);
|
||||
end ecb_128_encryption_core;
|
||||
|
||||
|
||||
architecture behavioural of ecb_128_encryption_core is
|
||||
|
||||
|
||||
signal enc_i : encryption_engine_in_type; -- input to the encryption engine
|
||||
signal enc_o : encryption_engine_out_type; -- output of the encryption engine
|
||||
|
||||
signal sbox_enc_i : sbox_stage_in_type; -- input to the S-box stage
|
||||
signal sbox_enc_o : sbox_stage_out_type; -- output of the S-box stage
|
||||
|
||||
signal sbox_ks_i : sbox_stage_in_type; -- input to the S-box stage (key schedule)
|
||||
signal sbox_ks_o : sbox_stage_out_type; -- output of the S-box stage (key schedule)
|
||||
|
||||
signal skm_enc_i : subkey_memory_ed_in_type; -- encryption-side subkey memory access (subkey selection)
|
||||
signal skm_enc_o : subkey_memory_ed_out_type; -- encryption-side subkey memory access (selected subkey)
|
||||
|
||||
signal skm_ks_enc_i : subkey_memory_ks_in_type; -- subkey storage by key schedule
|
||||
|
||||
|
||||
begin
|
||||
|
||||
|
||||
-- AES ECB-mode encryption
|
||||
ecb_mode: ecb_mode_encryption
|
||||
port map (
|
||||
rst => rst,
|
||||
clk => clk,
|
||||
mode_i => mode_i,
|
||||
mode_o => mode_o,
|
||||
enc_i => enc_o,
|
||||
enc_o => enc_i
|
||||
);
|
||||
|
||||
|
||||
-- AES encryption engine
|
||||
enc_eng: encryption_engine
|
||||
port map (
|
||||
rst => rst,
|
||||
clk => clk,
|
||||
enc_i => enc_i,
|
||||
enc_o => enc_o,
|
||||
skm_i => skm_enc_o,
|
||||
skm_o => skm_enc_i,
|
||||
sbox_i => sbox_enc_o,
|
||||
sbox_o => sbox_enc_i
|
||||
);
|
||||
|
||||
|
||||
-- S-Box stage for encryption engine
|
||||
sbox_enc: tech_sbox_stage
|
||||
port map (
|
||||
rst => rst,
|
||||
clk => clk,
|
||||
data_i => sbox_enc_i,
|
||||
data_o => sbox_enc_o,
|
||||
load_i => sbld_i
|
||||
);
|
||||
|
||||
|
||||
-- subkey memory for encryption engine
|
||||
skm_enc: tech_subkey_memory
|
||||
port map (
|
||||
clk => clk,
|
||||
key_sched_i => skm_ks_enc_i,
|
||||
enc_dec_i => skm_enc_i,
|
||||
enc_dec_o => skm_enc_o
|
||||
);
|
||||
|
||||
|
||||
-- 128-bit key schedule
|
||||
key_sched: key_schedule_128
|
||||
port map (
|
||||
rst => rst,
|
||||
clk => clk,
|
||||
key_i => key_i,
|
||||
key_o => key_o,
|
||||
sbox_i => sbox_ks_o,
|
||||
sbox_o => sbox_ks_i,
|
||||
skm_enc_o => skm_ks_enc_i,
|
||||
skm_dec_o => open
|
||||
);
|
||||
|
||||
|
||||
-- S-Box stage for key schedule
|
||||
sbox_ks: tech_sbox_stage
|
||||
port map (
|
||||
rst => rst,
|
||||
clk => clk,
|
||||
data_i => sbox_ks_i,
|
||||
data_o => sbox_ks_o,
|
||||
load_i => sbld_i
|
||||
);
|
||||
|
||||
|
||||
end behavioural;
|
||||
+1221
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,146 @@
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Design unit : ecb_core_iface (interfaces of ECB-mode en-/decryption
|
||||
-- cores)
|
||||
--
|
||||
-- File Name : ecb_core_iface.vhd
|
||||
--
|
||||
-- Purpose : The package collects type declarations for all non-
|
||||
-- trivial interfaces of used entities. Record types
|
||||
-- are used extensively to group related signals (e.g.
|
||||
-- data / control & status, physical attachment etc.).
|
||||
--
|
||||
--
|
||||
-- Depends on :
|
||||
--
|
||||
-- - Package(s) : tech_iface, key_schedule_iface, engine_iface,
|
||||
-- ecb_mode_iface
|
||||
--
|
||||
-- - Module(s) : -
|
||||
--
|
||||
--
|
||||
-- Dev. Platform : Xilinx ISE 8.1i SP3 / Win32 (W2k SP4)
|
||||
--
|
||||
-- - Simulator(s) : Modelsim XE III 6.0d
|
||||
--
|
||||
-- - Synthesis : Xilinx XST
|
||||
--
|
||||
-- - Place & Route : Xilinx PAR
|
||||
--
|
||||
--
|
||||
-- Errors : None known
|
||||
--
|
||||
--
|
||||
-- Limitations : None known
|
||||
--
|
||||
--
|
||||
-- Notes : -
|
||||
--
|
||||
--
|
||||
-- Author(s) : A. Freund (af) <a.freund@dsi-it.de>
|
||||
-- Digitale Signalverabeitung & Informationstechnik GmbH,
|
||||
-- Bremen, Germany
|
||||
--
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Revision List:
|
||||
-- Version Author(s) Date Changes
|
||||
--
|
||||
-- v0.00 af 2006-11-15 initial version
|
||||
--
|
||||
-- see SVN logs
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Naming conventions:
|
||||
--
|
||||
-- - coding style: record-signals for related purposes (Gaisler-style)
|
||||
-- - active-low signals are indicated by appending "_n"
|
||||
-- - constants are in UPPERCASE
|
||||
-- - name parts are separated by "_"
|
||||
--
|
||||
-- ============================================================================
|
||||
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
|
||||
use work.tech_iface.all;
|
||||
use work.key_schedule_iface.all;
|
||||
use work.engine_iface.all;
|
||||
use work.ecb_mode_iface.all;
|
||||
|
||||
|
||||
package ecb_core_iface is
|
||||
|
||||
|
||||
-- no new interfaces are needed yet
|
||||
|
||||
|
||||
|
||||
--
|
||||
--
|
||||
-- Component declarations
|
||||
--
|
||||
--
|
||||
|
||||
|
||||
-- AES-ECB-128 encryption core
|
||||
component ecb_128_encryption_core is
|
||||
port (
|
||||
rst : in std_logic; -- reset
|
||||
clk : in std_logic; -- clock
|
||||
mode_i : in ecb_mode_encryption_in_type; -- see package ecb_mode_iface
|
||||
mode_o : out ecb_mode_encryption_out_type; -- see package ecb_mode_iface
|
||||
key_i : in key_schedule_128_in_type; -- see package key_schedule_iface
|
||||
key_o : out key_schedule_128_out_type; -- see package key_schedule_iface
|
||||
sbld_i : in sbox_stage_load_in_type -- see package tech_iface
|
||||
);
|
||||
end component;
|
||||
|
||||
|
||||
-- AES-ECB-128 decryption core
|
||||
component ecb_128_decryption_core is
|
||||
port (
|
||||
rst : in std_logic; -- reset
|
||||
clk : in std_logic; -- clock
|
||||
mode_i : in ecb_mode_decryption_in_type; -- see package ecb_mode_iface
|
||||
mode_o : out ecb_mode_decryption_out_type; -- see package ecb_mode_iface
|
||||
key_i : in key_schedule_128_in_type; -- see package key_schedule_iface
|
||||
key_o : out key_schedule_128_out_type; -- see package key_schedule_iface
|
||||
sbld_i : in sbox_stage_load_in_type -- see package tech_iface
|
||||
);
|
||||
end component;
|
||||
|
||||
|
||||
-- AES-ECB-256 encryption core
|
||||
component ecb_256_encryption_core is
|
||||
port (
|
||||
rst : in std_logic; -- reset
|
||||
clk : in std_logic; -- clock
|
||||
mode_i : in ecb_mode_encryption_in_type; -- see package ecb_mode_iface
|
||||
mode_o : out ecb_mode_encryption_out_type; -- see package ecb_mode_iface
|
||||
key_i : in key_schedule_256_in_type; -- see package key_schedule_iface
|
||||
key_o : out key_schedule_256_out_type; -- see package key_schedule_iface
|
||||
sbld_i : in sbox_stage_load_in_type -- see package tech_iface
|
||||
);
|
||||
end component;
|
||||
|
||||
|
||||
-- AES-ECB-256 decryption core
|
||||
component ecb_256_decryption_core is
|
||||
port (
|
||||
rst : in std_logic; -- reset
|
||||
clk : in std_logic; -- clock
|
||||
mode_i : in ecb_mode_decryption_in_type; -- see package ecb_mode_iface
|
||||
mode_o : out ecb_mode_decryption_out_type; -- see package ecb_mode_iface
|
||||
key_i : in key_schedule_256_in_type; -- see package key_schedule_iface
|
||||
key_o : out key_schedule_256_out_type; -- see package key_schedule_iface
|
||||
sbld_i : in sbox_stage_load_in_type -- see package tech_iface
|
||||
);
|
||||
end component;
|
||||
|
||||
|
||||
end ecb_core_iface;
|
||||
@@ -0,0 +1,161 @@
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Design unit : ecb_mode_encryption (ECB-mode encryption)
|
||||
--
|
||||
-- File Name : ecb_mode_encryption.vhd
|
||||
--
|
||||
-- Purpose : The module provides ECB-mode encryption (there is no
|
||||
-- internal logic, it's just a placeholder to hold up with
|
||||
-- common infrastructure used for more complex modes)
|
||||
--
|
||||
--
|
||||
-- Depends on :
|
||||
--
|
||||
-- - Package(s) : engine_iface, ecb_mode_iface
|
||||
--
|
||||
-- - Module(s) : -
|
||||
--
|
||||
--
|
||||
-- Dev. Platform : Xilinx ISE 8.1i SP3 / Win32 (W2k SP4)
|
||||
--
|
||||
-- - Simulator(s) : Modelsim XE III 6.0d
|
||||
--
|
||||
-- - Synthesis : Xilinx XST
|
||||
--
|
||||
-- - Place & Route : Xilinx PAR
|
||||
--
|
||||
--
|
||||
-- Errors : None known
|
||||
--
|
||||
--
|
||||
-- Limitations : None known
|
||||
--
|
||||
--
|
||||
-- Notes : Version for implementation using 32-bit datapath
|
||||
--
|
||||
--
|
||||
-- Author(s) : A. Freund (af) <a.freund@dsi-it.de>
|
||||
-- Digitale Signalverabeitung & Informationstechnik GmbH,
|
||||
-- Bremen, Germany
|
||||
--
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Revision List:
|
||||
-- Version Author(s) Date Changes
|
||||
--
|
||||
-- v0.00 af 2006-11-02 initial version
|
||||
--
|
||||
-- see SVN logs
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Naming conventions:
|
||||
--
|
||||
-- - coding style: two-process method (Gaisler-style)
|
||||
-- - active-low signals are indicated by appending "_n"
|
||||
-- - constants are in UPPERCASE
|
||||
-- - name parts are separated by "_"
|
||||
--
|
||||
-- ============================================================================
|
||||
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_arith.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
|
||||
|
||||
use work.engine_iface.all;
|
||||
use work.ecb_mode_iface.all;
|
||||
|
||||
|
||||
entity ecb_mode_encryption is
|
||||
port (
|
||||
rst : in std_logic; -- reset
|
||||
clk : in std_logic; -- clock
|
||||
mode_i : in ecb_mode_encryption_in_type; -- see package ecb_mode_iface
|
||||
mode_o : out ecb_mode_encryption_out_type; -- see package ecb_mode_iface
|
||||
enc_i : in encryption_engine_out_type; -- see package engine_iface
|
||||
enc_o : out encryption_engine_in_type -- see package engine_iface
|
||||
);
|
||||
end ecb_mode_encryption;
|
||||
|
||||
|
||||
architecture behavioural of ecb_mode_encryption is
|
||||
|
||||
|
||||
type registers is record
|
||||
dummy : std_logic;
|
||||
end record;
|
||||
|
||||
|
||||
type variables is record
|
||||
dummy : std_logic;
|
||||
end record;
|
||||
|
||||
|
||||
signal r, rin : registers;
|
||||
|
||||
|
||||
begin
|
||||
|
||||
|
||||
-- combinatorial logic
|
||||
comb: process (rst, r, mode_i, enc_i)
|
||||
variable v : registers;
|
||||
variable t : variables;
|
||||
begin
|
||||
|
||||
-- assign default values
|
||||
v := r;
|
||||
--
|
||||
--
|
||||
--
|
||||
|
||||
|
||||
|
||||
--
|
||||
--
|
||||
--
|
||||
-- reset handling
|
||||
if (rst = '1')
|
||||
then
|
||||
end if;
|
||||
--
|
||||
--
|
||||
--
|
||||
-- update registers
|
||||
rin <= v;
|
||||
--
|
||||
--
|
||||
--
|
||||
-- drive outputs
|
||||
enc_o.start <= mode_i.start;
|
||||
enc_o.plain <= mode_i.plain;
|
||||
enc_o.key_id <= mode_i.key_id;
|
||||
|
||||
mode_o.valid <= enc_i.valid;
|
||||
mode_o.busy <= enc_i.busy;
|
||||
mode_o.cipher <= enc_i.cipher;
|
||||
|
||||
|
||||
end process;
|
||||
|
||||
|
||||
-- registers
|
||||
regs: process (clk, rst)
|
||||
begin
|
||||
if rising_edge(clk)
|
||||
then
|
||||
r <= rin;
|
||||
end if;
|
||||
|
||||
-- async. reset
|
||||
if (rst = '1')
|
||||
then
|
||||
end if;
|
||||
end process;
|
||||
|
||||
|
||||
end behavioural;
|
||||
@@ -0,0 +1,151 @@
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Design unit : ecb_mode_iface (interfaces of ECB-mode en-/decryption
|
||||
-- modules)
|
||||
--
|
||||
-- File Name : ecb_mode_iface.vhd
|
||||
--
|
||||
-- Purpose : The package collects type declarations for all non-
|
||||
-- trivial interfaces of used entities. Record types
|
||||
-- are used extensively to group related signals (e.g.
|
||||
-- data / control & status, physical attachment etc.).
|
||||
--
|
||||
--
|
||||
-- Depends on :
|
||||
--
|
||||
-- - Package(s) : aes_definitions, tech_iface, engine_iface
|
||||
--
|
||||
-- - Module(s) : -
|
||||
--
|
||||
--
|
||||
-- Dev. Platform : Xilinx ISE 8.1i SP3 / Win32 (W2k SP4)
|
||||
--
|
||||
-- - Simulator(s) : Modelsim XE III 6.0d
|
||||
--
|
||||
-- - Synthesis : Xilinx XST
|
||||
--
|
||||
-- - Place & Route : Xilinx PAR
|
||||
--
|
||||
--
|
||||
-- Errors : None known
|
||||
--
|
||||
--
|
||||
-- Limitations : None known
|
||||
--
|
||||
--
|
||||
-- Notes : Version for implementation using 32-bit datapath
|
||||
--
|
||||
--
|
||||
-- Author(s) : A. Freund (af) <a.freund@dsi-it.de>
|
||||
-- Digitale Signalverabeitung & Informationstechnik GmbH,
|
||||
-- Bremen, Germany
|
||||
--
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Revision List:
|
||||
-- Version Author(s) Date Changes
|
||||
--
|
||||
-- v0.00 af 2006-11-15 initial version
|
||||
--
|
||||
-- see SVN logs
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Naming conventions:
|
||||
--
|
||||
-- - coding style: record-signals for related purposes (Gaisler-style)
|
||||
-- - active-low signals are indicated by appending "_n"
|
||||
-- - constants are in UPPERCASE
|
||||
-- - name parts are separated by "_"
|
||||
--
|
||||
-- ============================================================================
|
||||
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
|
||||
use work.aes_definitions.all;
|
||||
use work.tech_iface.all;
|
||||
use work.engine_iface.all;
|
||||
|
||||
|
||||
package ecb_mode_iface is
|
||||
|
||||
|
||||
--
|
||||
-- ECB-mode encryption interface definition
|
||||
--
|
||||
|
||||
|
||||
-- data/control input signals
|
||||
type ecb_mode_encryption_in_type is record
|
||||
start : std_logic; -- start encryption
|
||||
plain : part_data_t; -- data to be encrypted (plaintext)
|
||||
key_id : key_id_t; -- key id to use
|
||||
end record;
|
||||
|
||||
-- data/status outputs signals
|
||||
type ecb_mode_encryption_out_type is record
|
||||
cipher : part_data_t; -- encrypted data (ciphertext)
|
||||
busy : std_logic; -- busy, encrypion in progress
|
||||
valid : std_logic; -- ciphertext is valid (encryption finished)
|
||||
end record;
|
||||
|
||||
|
||||
--
|
||||
-- ECB-mode decryption interface definition
|
||||
--
|
||||
|
||||
|
||||
-- data/control input signals
|
||||
type ecb_mode_decryption_in_type is record
|
||||
start : std_logic; -- start decryption
|
||||
cipher : part_data_t; -- data to be decrypted (ciphertext)
|
||||
key_id : key_id_t; -- key id to use
|
||||
end record;
|
||||
|
||||
-- data/status outputs signals
|
||||
type ecb_mode_decryption_out_type is record
|
||||
plain : part_data_t; -- decrypted data (plaintext)
|
||||
busy : std_logic; -- busy, decrypion in progress
|
||||
valid : std_logic; -- plaintext is valid (decryption finished)
|
||||
end record;
|
||||
|
||||
|
||||
--
|
||||
--
|
||||
-- Component declarations
|
||||
--
|
||||
--
|
||||
|
||||
|
||||
-- AES ECB-mode encryption
|
||||
component ecb_mode_encryption is
|
||||
port (
|
||||
rst : in std_logic; -- reset
|
||||
clk : in std_logic; -- clock
|
||||
mode_i : in ecb_mode_encryption_in_type; -- see package ecb_mode_iface
|
||||
mode_o : out ecb_mode_encryption_out_type; -- see package ecb_mode_iface
|
||||
enc_i : in encryption_engine_out_type; -- see package engine_iface
|
||||
enc_o : out encryption_engine_in_type -- see package engine_iface
|
||||
);
|
||||
end component;
|
||||
|
||||
|
||||
|
||||
-- AES ECB-mode decryption
|
||||
component ecb_mode_decryption is
|
||||
port (
|
||||
rst : in std_logic; -- reset
|
||||
clk : in std_logic; -- clock
|
||||
mode_i : in ecb_mode_decryption_in_type; -- see package ecb_mode_iface
|
||||
mode_o : out ecb_mode_decryption_out_type; -- see package ecb_mode_iface
|
||||
dec_i : in decryption_engine_out_type; -- see package engine_iface
|
||||
dec_o : out decryption_engine_in_type -- see package engine_iface
|
||||
);
|
||||
end component;
|
||||
|
||||
|
||||
end ecb_mode_iface;
|
||||
@@ -0,0 +1,182 @@
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Design unit : aux_funcs (auxiliary functions)
|
||||
--
|
||||
-- File Name : aux_funcs.vhd
|
||||
--
|
||||
-- Purpose : The package collects type declarations and auxiliary
|
||||
-- functions which are commonly used by encryption,
|
||||
-- decryption and key schedule
|
||||
--
|
||||
--
|
||||
-- Depends on :
|
||||
--
|
||||
-- - Package(s) : aes_definitions, aes_common, aes_column_ops,
|
||||
-- aes_row_ops
|
||||
--
|
||||
-- - Module(s) : -
|
||||
--
|
||||
--
|
||||
-- Dev. Platform : Xilinx ISE 8.1i SP3 / Win32 (W2k SP4)
|
||||
--
|
||||
-- - Simulator(s) : Modelsim XE III 6.0d
|
||||
--
|
||||
-- - Synthesis : Xilinx XST
|
||||
--
|
||||
-- - Place & Route : Xilinx PAR
|
||||
--
|
||||
--
|
||||
-- Errors : None known
|
||||
--
|
||||
--
|
||||
-- Limitations : None known
|
||||
--
|
||||
--
|
||||
-- Notes : -
|
||||
--
|
||||
--
|
||||
-- Author(s) : A. Freund (af) <a.freund@dsi-it.de>
|
||||
-- Digitale Signalverabeitung & Informationstechnik GmbH,
|
||||
-- Bremen, Germany
|
||||
--
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Revision List:
|
||||
-- Version Author(s) Date Changes
|
||||
--
|
||||
-- v0.00 af 2006-11-14 initial version
|
||||
--
|
||||
-- see SVN logs
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Naming conventions:
|
||||
--
|
||||
-- - coding style: record-signals for related purposes (Gaisler-style)
|
||||
-- - active-low signals are indicated by appending "_n"
|
||||
-- - constants are in UPPERCASE
|
||||
-- - name parts are separated by "_"
|
||||
--
|
||||
-- ============================================================================
|
||||
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
|
||||
use work.aes_definitions.all;
|
||||
use work.aes_common.all;
|
||||
use work.aes_column_ops.all;
|
||||
use work.aes_row_ops.all;
|
||||
|
||||
|
||||
package aux_funcs is
|
||||
|
||||
|
||||
subtype slv256_t is std_logic_vector(255 downto 0);
|
||||
|
||||
subtype slv32_t is std_logic_vector(31 downto 0);
|
||||
|
||||
subtype slv3_t is std_logic_vector(2 downto 0);
|
||||
|
||||
subtype slv4_t is std_logic_vector(3 downto 0);
|
||||
|
||||
subtype slv5_t is std_logic_vector(4 downto 0);
|
||||
|
||||
subtype slv13_t is std_logic_vector(12 downto 0);
|
||||
|
||||
subtype slv19_t is std_logic_vector(18 downto 0);
|
||||
|
||||
|
||||
|
||||
-- rotate left
|
||||
function rotl(val : std_logic_vector; pos : natural) return std_logic_vector;
|
||||
|
||||
-- rotate right
|
||||
function rotr(val : std_logic_vector; pos : natural) return std_logic_vector;
|
||||
|
||||
|
||||
-- convert the row representation to 32-bit logic vector
|
||||
function row2slv(row : row_t) return slv32_t;
|
||||
|
||||
|
||||
-- convert 32-bit logic vector to row representation
|
||||
function slv2row(slv : slv32_t) return row_t;
|
||||
|
||||
|
||||
-- convert the column representation to 32-bit logic vector
|
||||
function col2slv(col : column_t) return slv32_t;
|
||||
|
||||
|
||||
-- convert 32-bit logic vector to column representation
|
||||
function slv2col(slv : slv32_t) return column_t;
|
||||
|
||||
|
||||
end aux_funcs;
|
||||
|
||||
|
||||
package body aux_funcs is
|
||||
|
||||
|
||||
-- rotate left
|
||||
function rotl(val : std_logic_vector; pos : natural) return std_logic_vector is
|
||||
variable v : std_logic_vector(val'high downto 0);
|
||||
begin
|
||||
v := val;
|
||||
return v(v'left - pos downto 0) & v(v'left downto v'left - pos + 1);
|
||||
end function;
|
||||
|
||||
|
||||
-- rotate right
|
||||
function rotr(val : std_logic_vector; pos : natural) return std_logic_vector is
|
||||
variable v : std_logic_vector(val'high downto 0);
|
||||
begin
|
||||
v := val;
|
||||
return v(pos - 1 downto 0) & v(v'left downto pos);
|
||||
end function;
|
||||
|
||||
|
||||
-- convert the row representation to 32-bit logic vector
|
||||
function row2slv(row : row_t) return slv32_t is
|
||||
variable v : slv32_t;
|
||||
begin
|
||||
v := row(0) & row(1) & row(2) & row(3);
|
||||
return v;
|
||||
end function;
|
||||
|
||||
|
||||
-- convert 32-bit logic vector to row representation
|
||||
function slv2row(slv : slv32_t) return row_t is
|
||||
variable row : row_t;
|
||||
begin
|
||||
for i in row'range loop
|
||||
row(i) := slv(31 - 8*i downto 31-8*i - 7);
|
||||
end loop;
|
||||
|
||||
return row;
|
||||
end function;
|
||||
|
||||
|
||||
-- convert the column representation to 32-bit logic vector
|
||||
function col2slv(col : column_t) return slv32_t is
|
||||
variable v : slv32_t;
|
||||
begin
|
||||
v := col(0) & col(1) & col(2) & col(3);
|
||||
return v;
|
||||
end function;
|
||||
|
||||
|
||||
-- convert 32-bit logic vector to column representation
|
||||
function slv2col(slv : slv32_t) return column_t is
|
||||
variable col : column_t;
|
||||
begin
|
||||
for i in col'range loop
|
||||
col(i) := slv(31 - 8*i downto 31-8*i - 7);
|
||||
end loop;
|
||||
|
||||
return col;
|
||||
end function;
|
||||
|
||||
|
||||
end aux_funcs;
|
||||
@@ -0,0 +1,150 @@
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Design unit : dual_sbox_virtex2 (dual AES S-box)
|
||||
--
|
||||
-- File Name : dual_sbox_virtex2.vhd
|
||||
--
|
||||
-- Purpose : The module provides dual (dual-port memory) AES S-box
|
||||
-- on Virtex2 family
|
||||
--
|
||||
--
|
||||
-- Depends on :
|
||||
--
|
||||
-- - Package(s) : Xilinx/unisim
|
||||
--
|
||||
-- - Module(s) : -
|
||||
--
|
||||
--
|
||||
-- Dev. Platform : Xilinx ISE 8.1i SP3 / Win32 (W2k SP4)
|
||||
--
|
||||
-- - Simulator(s) : Modelsim XE III 6.0d
|
||||
--
|
||||
-- - Synthesis : Xilinx XST
|
||||
--
|
||||
-- - Place & Route : Xilinx PAR
|
||||
--
|
||||
--
|
||||
-- Errors : None known
|
||||
--
|
||||
--
|
||||
-- Limitations : None known
|
||||
--
|
||||
--
|
||||
-- Notes : -
|
||||
--
|
||||
--
|
||||
-- Author(s) : A. Freund (af) <a.freund@dsi-it.de>
|
||||
-- Digitale Signalverabeitung & Informationstechnik GmbH,
|
||||
-- Bremen, Germany
|
||||
--
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Revision List:
|
||||
-- Version Author(s) Date Changes
|
||||
--
|
||||
-- v0.00 af 2006-11-15 initial version
|
||||
--
|
||||
-- see SVN logs
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Naming conventions:
|
||||
--
|
||||
-- - active-low signals are indicated by appending "_n"
|
||||
-- - constants are in UPPERCASE
|
||||
-- - name parts are separated by "_"
|
||||
--
|
||||
-- ============================================================================
|
||||
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_arith.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
|
||||
library unisim;
|
||||
use unisim.vcomponents.all;
|
||||
|
||||
|
||||
entity dual_sbox_virtex2 is
|
||||
port (
|
||||
clk : in std_logic; -- clock (rising)
|
||||
enca : in std_logic; -- encryption (0) / decryption (1) mode
|
||||
encb : in std_logic; -- encryption (0) / decryption (1) mode
|
||||
posa : in std_logic_vector(7 downto 0); -- position
|
||||
posb : in std_logic_vector(7 downto 0); -- position
|
||||
dina : in std_logic_vector(7 downto 0); -- write data
|
||||
dinb : in std_logic_vector(7 downto 0); -- write data
|
||||
wea : in std_logic; -- write enable
|
||||
web : in std_logic; -- write enable
|
||||
douta : out std_logic_vector(7 downto 0); -- read data
|
||||
doutb : out std_logic_vector(7 downto 0); -- read data
|
||||
is_init : out std_logic -- pre-initialised memory
|
||||
);
|
||||
end dual_sbox_virtex2;
|
||||
|
||||
|
||||
architecture behavioral of dual_sbox_virtex2 is
|
||||
|
||||
signal s_addra : std_logic_vector(10 downto 0);
|
||||
signal s_addrb : std_logic_vector(10 downto 0);
|
||||
|
||||
begin
|
||||
|
||||
s_addra <= "00" & enca & posa;
|
||||
|
||||
s_addrb <= "00" & encb & posb;
|
||||
|
||||
|
||||
-- RAMB16_S9_S9: Virtex-II/II-Pro 2k x 8 + 1 Parity bit Dual-Port RAM
|
||||
-- Xilinx HDL Language Template version 7.1i
|
||||
|
||||
sboxd: RAMB16_S9_S9
|
||||
generic map (
|
||||
WRITE_MODE_A => "READ_FIRST", -- WRITE_FIRST, READ_FIRST or NO_CHANGE
|
||||
WRITE_MODE_B => "READ_FIRST", -- WRITE_FIRST, READ_FIRST or NO_CHANGE
|
||||
SIM_COLLISION_CHECK => "NONE", -- "NONE", "WARNING", "GENERATE_X_ONLY", "ALL"
|
||||
INIT_00 => X"C072A49CAFA2D4ADF04759FA7DC982CA76ABD7FE2B670130C56F6BF27B777C63",
|
||||
INIT_01 => X"75B227EBE28012079A059618C323C7041531D871F1E5A534CCF73F362693FDB7",
|
||||
INIT_02 => X"CF584C4A39BECB6A5BB1FC20ED00D153842FE329B3D63B52A05A6E1B1A2C8309",
|
||||
INIT_03 => X"D2F3FF1021DAB6BCF5389D928F40A351A89F3C507F02F94585334D43FBAAEFD0",
|
||||
INIT_04 => X"DB0B5EDE14B8EE4688902A22DC4F816073195D643D7EA7C41744975FEC130CCD",
|
||||
INIT_05 => X"08AE7A65EAF4566CA94ED58D6D37C8E779E4959162ACD3C25C2406490A3A32E0",
|
||||
INIT_06 => X"9E1DC186B95735610EF6034866B53E708A8BBD4B1F74DDE8C6B4A61C2E2578BA",
|
||||
INIT_07 => X"16BB54B00F2D99416842E6BF0D89A18CDF2855CEE9871E9B948ED9691198F8E1",
|
||||
INIT_08 => X"CBE9DEC444438E3487FF2F9B8239E37CFBD7F3819EA340BF38A53630D56A0952",
|
||||
INIT_09 => X"25D18B6D49A25B76B224D92866A12E084EC3FA420B954CEE3D23C2A632947B54",
|
||||
INIT_0A => X"849D8DA75746155EDAB9EDFD5048706C92B6655DCC5CA4D41698688664F6F872",
|
||||
INIT_0B => X"6B8A130103BDAFC1020F3FCA8F1E2CD00645B3B80558E4F70AD3BC8C00ABD890",
|
||||
INIT_0C => X"6EDF751CE837F9E28535ADE72274AC9673E6B4F0CECFF297EADC674F4111913A",
|
||||
INIT_0D => X"F45ACD78FEC0DB9A2079D2C64B3E56FC1BBE18AA0E62B76F89C5291D711AF147",
|
||||
INIT_0E => X"EF9CC9939F7AE52D0D4AB519A97F51605FEC8027591012B131C7078833A8DD1F",
|
||||
INIT_0F => X"7D0C2155631469E126D677BA7E042B17619953833CBBEBC8B0F52AAE4D3BE0A0"
|
||||
)
|
||||
port map (
|
||||
DOA => douta(7 downto 0), -- Port A 8-bit Data Output
|
||||
DOB => doutb(7 downto 0), -- Port B 8-bit Data Output
|
||||
DOPA => open, -- Port A 1-bit Parity Output
|
||||
DOPB => open, -- Port B 1-bit Parity Output
|
||||
ADDRA => s_addra, -- Port A 11-bit Address Input
|
||||
ADDRB => s_addrb, -- Port B 11-bit Address Input
|
||||
CLKA => clk, -- Port A Clock
|
||||
CLKB => clk, -- Port B Clock
|
||||
DIA => dina(7 downto 0), -- Port A 8-bit Data Input
|
||||
DIB => dinb(7 downto 0), -- Port B 8-bit Data Input
|
||||
DIPA => "0", -- Port A 1-bit parity Input
|
||||
DIPB => "0", -- Port-B 1-bit parity Input
|
||||
ENA => '1', -- Port A RAM Enable Input
|
||||
ENB => '1', -- Port B RAM Enable Input
|
||||
SSRA => '0', -- Port A Synchronous Set/Reset Input
|
||||
SSRB => '0', -- Port B Synchronous Set/Reset Input
|
||||
WEA => wea, -- Port A Write Enable Input
|
||||
WEB => web -- Port B Write Enable Input
|
||||
);
|
||||
|
||||
|
||||
is_init <= '1';
|
||||
|
||||
|
||||
end behavioral;
|
||||
@@ -0,0 +1,207 @@
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Design unit : dual_sbox_virtex2 (dual AES S-box)
|
||||
--
|
||||
-- File Name : dual_sbox_virtex2_empty.vhd
|
||||
--
|
||||
-- Purpose : The module provides dual (dual-port memory) AES S-box
|
||||
-- on Virtex2 family
|
||||
--
|
||||
--
|
||||
-- Depends on :
|
||||
--
|
||||
-- - Package(s) : Xilinx/unisim
|
||||
--
|
||||
-- - Module(s) : -
|
||||
--
|
||||
--
|
||||
-- Dev. Platform : Xilinx ISE 8.1i SP3 / Win32 (W2k SP4)
|
||||
--
|
||||
-- - Simulator(s) : Modelsim XE III 6.0d
|
||||
--
|
||||
-- - Synthesis : Xilinx XST
|
||||
--
|
||||
-- - Place & Route : Xilinx PAR
|
||||
--
|
||||
--
|
||||
-- Errors : None known
|
||||
--
|
||||
--
|
||||
-- Limitations : None known
|
||||
--
|
||||
--
|
||||
-- Notes : the S-box in not pre-initialized to allow testing
|
||||
-- of S-box load I/F
|
||||
--
|
||||
--
|
||||
-- Author(s) : A. Freund (af) <a.freund@dsi-it.de>
|
||||
-- Digitale Signalverabeitung & Informationstechnik GmbH,
|
||||
-- Bremen, Germany
|
||||
--
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Revision List:
|
||||
-- Version Author(s) Date Changes
|
||||
--
|
||||
-- v0.00 af 2006-11-15 initial version
|
||||
--
|
||||
-- see SVN logs
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Naming conventions:
|
||||
--
|
||||
-- - active-low signals are indicated by appending "_n"
|
||||
-- - constants are in UPPERCASE
|
||||
-- - name parts are separated by "_"
|
||||
--
|
||||
-- ============================================================================
|
||||
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_arith.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
|
||||
library unisim;
|
||||
use unisim.vcomponents.all;
|
||||
|
||||
|
||||
entity dual_sbox_virtex2 is
|
||||
port (
|
||||
clk : in std_logic; -- clock (rising)
|
||||
enca : in std_logic; -- encryption (0) / decryption (1) mode
|
||||
encb : in std_logic; -- encryption (0) / decryption (1) mode
|
||||
posa : in std_logic_vector(7 downto 0); -- position
|
||||
posb : in std_logic_vector(7 downto 0); -- position
|
||||
dina : in std_logic_vector(7 downto 0); -- write data
|
||||
dinb : in std_logic_vector(7 downto 0); -- write data
|
||||
wea : in std_logic; -- write enable
|
||||
web : in std_logic; -- write enable
|
||||
douta : out std_logic_vector(7 downto 0); -- read data
|
||||
doutb : out std_logic_vector(7 downto 0); -- read data
|
||||
is_init : out std_logic -- pre-initialised memory
|
||||
);
|
||||
end dual_sbox_virtex2;
|
||||
|
||||
|
||||
architecture behavioral of dual_sbox_virtex2 is
|
||||
|
||||
signal s_addra : std_logic_vector(10 downto 0);
|
||||
signal s_addrb : std_logic_vector(10 downto 0);
|
||||
|
||||
begin
|
||||
|
||||
s_addra <= "00" & enca & posa;
|
||||
|
||||
s_addrb <= "00" & encb & posb;
|
||||
|
||||
|
||||
-- RAMB16_S9_S9: Virtex-II/II-Pro 2k x 8 + 1 Parity bit Dual-Port RAM
|
||||
-- Xilinx HDL Language Template version 7.1i
|
||||
|
||||
sboxd: RAMB16_S9_S9
|
||||
generic map (
|
||||
WRITE_MODE_A => "READ_FIRST", -- WRITE_FIRST, READ_FIRST or NO_CHANGE
|
||||
WRITE_MODE_B => "READ_FIRST", -- WRITE_FIRST, READ_FIRST or NO_CHANGE
|
||||
SIM_COLLISION_CHECK => "NONE", -- "NONE", "WARNING", "GENERATE_X_ONLY", "ALL"
|
||||
INIT_00 => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_01 => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_02 => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_03 => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_04 => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_05 => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_06 => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_07 => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_08 => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_09 => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_0A => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_0B => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_0C => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_0D => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_0E => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_0F => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_10 => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_11 => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_12 => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_13 => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_14 => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_15 => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_16 => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_17 => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_18 => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_19 => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_1A => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_1B => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_1C => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_1D => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_1E => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_1F => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_20 => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_21 => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_22 => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_23 => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_24 => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_25 => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_26 => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_27 => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_28 => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_29 => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_2A => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_2B => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_2C => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_2D => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_2E => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_2F => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_30 => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_31 => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_32 => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_33 => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_34 => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_35 => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_36 => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_37 => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_38 => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_39 => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_3A => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_3B => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_3C => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_3D => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_3E => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INIT_3F => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INITP_00 => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INITP_01 => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INITP_02 => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INITP_03 => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INITP_04 => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INITP_05 => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INITP_06 => X"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
INITP_07 => X"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
)
|
||||
port map (
|
||||
DOA => douta(7 downto 0), -- Port A 8-bit Data Output
|
||||
DOB => doutb(7 downto 0), -- Port B 8-bit Data Output
|
||||
DOPA => open, -- Port A 1-bit Parity Output
|
||||
DOPB => open, -- Port B 1-bit Parity Output
|
||||
ADDRA => s_addra, -- Port A 11-bit Address Input
|
||||
ADDRB => s_addrb, -- Port B 11-bit Address Input
|
||||
CLKA => clk, -- Port A Clock
|
||||
CLKB => clk, -- Port B Clock
|
||||
DIA => dina(7 downto 0), -- Port A 8-bit Data Input
|
||||
DIB => dinb(7 downto 0), -- Port B 8-bit Data Input
|
||||
DIPA => "0", -- Port A 1-bit parity Input
|
||||
DIPB => "0", -- Port-B 1-bit parity Input
|
||||
ENA => '1', -- Port A RAM Enable Input
|
||||
ENB => '1', -- Port B RAM Enable Input
|
||||
SSRA => '0', -- Port A Synchronous Set/Reset Input
|
||||
SSRB => '0', -- Port B Synchronous Set/Reset Input
|
||||
WEA => wea, -- Port A Write Enable Input
|
||||
WEB => web -- Port B Write Enable Input
|
||||
);
|
||||
|
||||
|
||||
is_init <= '0';
|
||||
|
||||
|
||||
end behavioral;
|
||||
@@ -0,0 +1,345 @@
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Design unit : encryption_engine (AES encryption engine)
|
||||
--
|
||||
-- File Name : encryption_engine.vhd
|
||||
--
|
||||
-- Purpose : The module provides encryption functionality (ECB-Mode)
|
||||
-- based on AES algorithm by using ressource sharing
|
||||
-- architecture (32-bit datapath) to reduce required area
|
||||
--
|
||||
-- Depends on :
|
||||
--
|
||||
-- - Package(s) : aes_definitions, aes_common, aes_column_ops,
|
||||
-- aes_row_ops, aes_common, aes_encryption, tech_iface,
|
||||
-- engine_iface
|
||||
--
|
||||
-- - Module(s) : -
|
||||
--
|
||||
--
|
||||
-- Dev. Platform : Xilinx ISE 8.1i SP3 / Win32 (W2k SP4)
|
||||
--
|
||||
-- - Simulator(s) : Modelsim XE III 6.0d
|
||||
--
|
||||
-- - Synthesis : Xilinx XST
|
||||
--
|
||||
-- - Place & Route : Xilinx PAR
|
||||
--
|
||||
--
|
||||
-- Errors : None known
|
||||
--
|
||||
--
|
||||
-- Limitations : None known
|
||||
--
|
||||
--
|
||||
-- Notes : - requires external S-box stage and subkey memory
|
||||
-- - number of rounds is obtained from the subkey memory
|
||||
-- (set by key schedule) and should be valid when the
|
||||
-- first subkey is read
|
||||
--
|
||||
--
|
||||
-- Author(s) : A. Freund (af) <a.freund@dsi-it.de>
|
||||
-- Digitale Signalverabeitung & Informationstechnik GmbH,
|
||||
-- Bremen, Germany
|
||||
--
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Revision List:
|
||||
-- Version Author(s) Date Changes
|
||||
--
|
||||
-- v0.00 af 2006-11-15 initial version
|
||||
--
|
||||
-- see SVN logs
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Naming conventions:
|
||||
--
|
||||
-- - coding style: two-process method (Gaisler-style)
|
||||
-- - active-low signals are indicated by appending "_n"
|
||||
-- - constants are in UPPERCASE
|
||||
-- - name parts are separated by "_"
|
||||
--
|
||||
-- ============================================================================
|
||||
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_arith.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
|
||||
|
||||
use work.aes_definitions.all;
|
||||
use work.aes_common.all;
|
||||
use work.aes_column_ops.all;
|
||||
use work.aes_row_ops.all;
|
||||
use work.aes_common.all;
|
||||
use work.aes_encryption.all;
|
||||
|
||||
use work.tech_iface.all;
|
||||
use work.engine_iface.all;
|
||||
use work.aux_funcs.all;
|
||||
|
||||
|
||||
entity encryption_engine is
|
||||
port (
|
||||
rst : in std_logic; -- reset
|
||||
clk : in std_logic; -- clock
|
||||
enc_i : in encryption_engine_in_type; -- see package engine_iface
|
||||
enc_o : out encryption_engine_out_type; -- see package engine_iface
|
||||
skm_i : in subkey_memory_ed_out_type; -- see package tech_iface
|
||||
skm_o : out subkey_memory_ed_in_type; -- see package tech_iface
|
||||
sbox_i : in sbox_stage_out_type; -- see package tech_iface
|
||||
sbox_o : out sbox_stage_in_type -- see package tech_iface
|
||||
);
|
||||
end encryption_engine;
|
||||
|
||||
|
||||
architecture behavioural of encryption_engine is
|
||||
|
||||
|
||||
-- control fsm, states: idle / load input data / shift-rows / sub-bytes + mix-column + add-key
|
||||
type ctrl_fsm_t is (cf_idle, cf_load, cf_sr, cf_sb_mc_ak);
|
||||
|
||||
|
||||
type registers is record
|
||||
busy : std_logic; -- busy, encryption in progress
|
||||
valid : std_logic; -- ciphertext is valid
|
||||
ctrl_fsm : ctrl_fsm_t; -- control fsm
|
||||
key_id : key_id_t; -- stored key id
|
||||
subkey_no : aes_round_no_t; -- subkey number (round number)
|
||||
part_no : part_no_t; -- partinal number of subkey (# of 32-bit slice within subkey)
|
||||
inc_part_no : std_logic; -- increment partial number
|
||||
state : aes_state_t; -- state matrix
|
||||
rounds : aes_round_no_t; -- stored number of rounds
|
||||
din_sel : std_logic; -- input data select (0 : process data, 1 : load data)
|
||||
sb_mx_sel : std_logic; -- select SubBytes() + MixColumn() path
|
||||
act_sbox : std_logic; -- activate S-box stage (to suppress simulation warnings on Actel)
|
||||
shift_rows : std_logic; -- perform ShiftRows() on state matrix
|
||||
end record;
|
||||
|
||||
|
||||
type variables is record
|
||||
key_id : key_id_t;
|
||||
sbox_dout : part_data_t;
|
||||
end record;
|
||||
|
||||
|
||||
signal r, rin : registers;
|
||||
|
||||
|
||||
begin
|
||||
|
||||
|
||||
-- combinatorial logic
|
||||
comb: process (rst, r, enc_i, skm_i, sbox_i)
|
||||
variable v : registers;
|
||||
variable t : variables;
|
||||
begin
|
||||
|
||||
-- assign default values
|
||||
v := r;
|
||||
--
|
||||
--
|
||||
--
|
||||
-- strobes
|
||||
v.shift_rows := '0';
|
||||
|
||||
|
||||
|
||||
if (r.inc_part_no = '1')
|
||||
then
|
||||
v.part_no := r.part_no + 1;
|
||||
end if;
|
||||
|
||||
-- count-up subkey # (round #)
|
||||
if (r.part_no = "11")
|
||||
then
|
||||
v.subkey_no := r.subkey_no + 1;
|
||||
end if;
|
||||
|
||||
|
||||
t.sbox_dout := (others => '-');
|
||||
|
||||
-- transform state matrix
|
||||
if (r.shift_rows = '1')
|
||||
then
|
||||
-- perform ShiftRows() (followed by one column-rotation step)
|
||||
v.state := shift_rows(r.state);
|
||||
v.state := v.state(95 downto 0) & (31 downto 0 => '-'); -- avoid unnecessary logic
|
||||
t.sbox_dout := col2slv(select_column(shift_rows(r.state), 0));
|
||||
else
|
||||
-- rotate column-weise
|
||||
if (r.sb_mx_sel = '0')
|
||||
then
|
||||
-- bypass SubBytes() and MixColumns() during loading
|
||||
v.state(31 downto 0) := r.state(127 downto 96) xor skm_i.subkey;
|
||||
else
|
||||
v.state(31 downto 0) := col2slv(mix_column(slv2col(sbox_i.dout))) xor skm_i.subkey;
|
||||
end if;
|
||||
v.state(127 downto 32) := r.state(95 downto 0);
|
||||
t.sbox_dout := col2slv(select_column(r.state, 0));
|
||||
end if;
|
||||
|
||||
-- shift-in input data
|
||||
if (r.din_sel = '1')
|
||||
then
|
||||
v.state(127 downto 96) := enc_i.plain;
|
||||
end if;
|
||||
|
||||
|
||||
-- control fsm
|
||||
case r.ctrl_fsm is
|
||||
-- wait for start
|
||||
when cf_idle =>
|
||||
v.sb_mx_sel := '0'; -- bypass SubBytes() + MixColumn()
|
||||
|
||||
-- handle loading
|
||||
if (enc_i.start = '1')
|
||||
then
|
||||
v.busy := '1';
|
||||
v.key_id := enc_i.key_id; -- store key-id
|
||||
v.part_no := "01"; -- consider synchronous subkey memory
|
||||
v.inc_part_no := '1'; -- allow part_no to increment
|
||||
|
||||
v.ctrl_fsm := cf_load;
|
||||
end if;
|
||||
|
||||
-- load input data
|
||||
when cf_load =>
|
||||
-- prepare to handle last input data word
|
||||
if (r.part_no = "11")
|
||||
then
|
||||
v.din_sel := '0';
|
||||
v.inc_part_no := '0'; -- hold partial number at "00"
|
||||
v.rounds := skm_i.rounds;
|
||||
end if;
|
||||
|
||||
-- finish loading
|
||||
if (r.din_sel = '0')
|
||||
then
|
||||
v.act_sbox := '1'; -- activate S-box stage
|
||||
v.sb_mx_sel := '1'; -- enable SubBytes() + MixColumn() path
|
||||
-- r.part_no is automatically set to "00" (wrap-around)
|
||||
v.shift_rows := '1';
|
||||
v.inc_part_no := '1'; -- re-activate partial number counting
|
||||
|
||||
v.ctrl_fsm := cf_sr;
|
||||
end if;
|
||||
|
||||
-- perform ShiftRows()
|
||||
when cf_sr =>
|
||||
-- check for last round
|
||||
if (r.subkey_no = r.rounds)
|
||||
then
|
||||
v.sb_mx_sel := '0'; -- bypass SubBytes() + MixColumn()
|
||||
v.valid := '1'; -- start output of encrypted data
|
||||
end if;
|
||||
|
||||
v.ctrl_fsm := cf_sb_mc_ak;
|
||||
|
||||
-- perform SubBytes(), MixColumn() and AddRoundKey()
|
||||
when cf_sb_mc_ak =>
|
||||
-- one clock cycle before completion
|
||||
if (r.part_no = "11")
|
||||
then
|
||||
v.inc_part_no := '0'; -- hold partial number at "00"
|
||||
v.act_sbox := '0'; -- deactivate S-box stage
|
||||
end if;
|
||||
|
||||
-- column-wise rotation completed
|
||||
if (r.act_sbox = '0')
|
||||
then
|
||||
-- check for last round
|
||||
if (r.sb_mx_sel = '0')
|
||||
then
|
||||
v.subkey_no := (others => '0'); -- consider synchronous subkey memory
|
||||
-- r.part_no is held at "00"
|
||||
v.din_sel := '1'; -- activate input data load mode
|
||||
v.busy := '0';
|
||||
v.valid := '0'; -- stop output of encrypted data
|
||||
|
||||
v.ctrl_fsm := cf_idle;
|
||||
else
|
||||
v.act_sbox := '1'; -- re-activate S-box stage
|
||||
v.inc_part_no := '1'; -- re-activate partial number counting
|
||||
v.shift_rows := '1';
|
||||
|
||||
v.ctrl_fsm := cf_sr;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
when others =>
|
||||
v.ctrl_fsm := cf_idle;
|
||||
|
||||
end case;
|
||||
|
||||
|
||||
-- handle start signal (synchronous subkey memory)
|
||||
if (enc_i.start = '1')
|
||||
then
|
||||
t.key_id := enc_i.key_id;
|
||||
else
|
||||
t.key_id := r.key_id;
|
||||
end if;
|
||||
|
||||
--
|
||||
--
|
||||
--
|
||||
-- reset handling
|
||||
if (rst = '1')
|
||||
then
|
||||
v.ctrl_fsm := cf_idle;
|
||||
v.rounds := (others => '0');
|
||||
v.key_id := (others => '0');
|
||||
v.subkey_no := (others => '0');
|
||||
v.part_no := (others => '0');
|
||||
v.busy := '0';
|
||||
v.valid := '0';
|
||||
v.inc_part_no := '0';
|
||||
v.din_sel := '1';
|
||||
v.act_sbox := '0';
|
||||
end if;
|
||||
--
|
||||
--
|
||||
--
|
||||
-- update registers
|
||||
rin <= v;
|
||||
--
|
||||
--
|
||||
--
|
||||
-- drive outputs
|
||||
enc_o.valid <= r.valid;
|
||||
enc_o.busy <= r.busy or (not sbox_i.ready);
|
||||
enc_o.cipher <= sbox_i.dout xor skm_i.subkey;
|
||||
|
||||
skm_o.rd_en <= enc_i.start or r.busy;
|
||||
skm_o.subkey_no <= r.subkey_no;
|
||||
skm_o.part_no <= r.part_no;
|
||||
skm_o.key_id <= t.key_id;
|
||||
|
||||
sbox_o.act <= r.act_sbox;
|
||||
sbox_o.din <= t.sbox_dout;
|
||||
sbox_o.ed_mode <= '0';
|
||||
|
||||
|
||||
end process;
|
||||
|
||||
|
||||
-- registers
|
||||
regs: process (clk, rst)
|
||||
begin
|
||||
if rising_edge(clk)
|
||||
then
|
||||
r <= rin;
|
||||
end if;
|
||||
|
||||
-- async. reset
|
||||
if (rst = '1')
|
||||
then
|
||||
end if;
|
||||
end process;
|
||||
|
||||
|
||||
end behavioural;
|
||||
@@ -0,0 +1,152 @@
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Design unit : engine_iface (interfaces of en-/decryption engines)
|
||||
--
|
||||
-- File Name : engine_iface.vhd
|
||||
--
|
||||
-- Purpose : The package collects type declarations for all non-
|
||||
-- trivial interfaces of used entities. Record types
|
||||
-- are used extensively to group related signals (e.g.
|
||||
-- data / control & status, physical attachment etc.).
|
||||
--
|
||||
--
|
||||
-- Depends on :
|
||||
--
|
||||
-- - Package(s) : tech_iface
|
||||
--
|
||||
-- - Module(s) : -
|
||||
--
|
||||
--
|
||||
-- Dev. Platform : Xilinx ISE 8.1i SP3 / Win32 (W2k SP4)
|
||||
--
|
||||
-- - Simulator(s) : Modelsim XE III 6.0d
|
||||
--
|
||||
-- - Synthesis : Xilinx XST
|
||||
--
|
||||
-- - Place & Route : Xilinx PAR
|
||||
--
|
||||
--
|
||||
-- Errors : None known
|
||||
--
|
||||
--
|
||||
-- Limitations : None known
|
||||
--
|
||||
--
|
||||
-- Notes : -
|
||||
--
|
||||
--
|
||||
-- Author(s) : A. Freund (af) <a.freund@dsi-it.de>
|
||||
-- Digitale Signalverabeitung & Informationstechnik GmbH,
|
||||
-- Bremen, Germany
|
||||
--
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Revision List:
|
||||
-- Version Author(s) Date Changes
|
||||
--
|
||||
-- v0.00 af 2006-11-15 initial version
|
||||
--
|
||||
-- see SVN logs
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Naming conventions:
|
||||
--
|
||||
-- - coding style: record-signals for related purposes (Gaisler-style)
|
||||
-- - active-low signals are indicated by appending "_n"
|
||||
-- - constants are in UPPERCASE
|
||||
-- - name parts are separated by "_"
|
||||
--
|
||||
-- ============================================================================
|
||||
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
|
||||
use work.tech_iface.all;
|
||||
|
||||
|
||||
package engine_iface is
|
||||
|
||||
|
||||
--
|
||||
-- encryption engine interface definition
|
||||
--
|
||||
|
||||
|
||||
-- data/control input signals
|
||||
type encryption_engine_in_type is record
|
||||
start : std_logic; -- start encryption
|
||||
plain : part_data_t; -- data to be encrypted (plaintext)
|
||||
key_id : key_id_t; -- key id to use
|
||||
end record;
|
||||
|
||||
-- data/status outputs signals
|
||||
type encryption_engine_out_type is record
|
||||
cipher : part_data_t; -- encrypted data (ciphertext)
|
||||
busy : std_logic; -- busy, encrypion in progress
|
||||
valid : std_logic; -- ciphertext is valid (encryption finished)
|
||||
end record;
|
||||
|
||||
|
||||
--
|
||||
-- decryption engine interface definition
|
||||
--
|
||||
|
||||
|
||||
-- data/control input signals
|
||||
type decryption_engine_in_type is record
|
||||
start : std_logic; -- start decryption
|
||||
cipher : part_data_t; -- data to be decrypted (ciphertext)
|
||||
key_id : key_id_t; -- key id to use
|
||||
end record;
|
||||
|
||||
-- data/status outputs signals
|
||||
type decryption_engine_out_type is record
|
||||
plain : part_data_t; -- decrypted data (plaintext)
|
||||
busy : std_logic; -- busy, decrypion in progress
|
||||
valid : std_logic; -- plaintext is valid (decryption finished)
|
||||
end record;
|
||||
|
||||
|
||||
--
|
||||
--
|
||||
-- Component declarations
|
||||
--
|
||||
--
|
||||
|
||||
|
||||
-- AES encryption engine
|
||||
component encryption_engine is
|
||||
port (
|
||||
rst : in std_logic; -- reset
|
||||
clk : in std_logic; -- clock
|
||||
enc_i : in encryption_engine_in_type; -- see package engine_iface
|
||||
enc_o : out encryption_engine_out_type; -- see package engine_iface
|
||||
skm_i : in subkey_memory_ed_out_type; -- see package tech_iface
|
||||
skm_o : out subkey_memory_ed_in_type; -- see package tech_iface
|
||||
sbox_i : in sbox_stage_out_type; -- see package tech_iface
|
||||
sbox_o : out sbox_stage_in_type -- see package tech_iface
|
||||
);
|
||||
end component;
|
||||
|
||||
|
||||
|
||||
-- AES decryption engine
|
||||
component decryption_engine is
|
||||
port (
|
||||
rst : in std_logic; -- reset
|
||||
clk : in std_logic; -- clock
|
||||
dec_i : in decryption_engine_in_type; -- see package engine_iface
|
||||
dec_o : out decryption_engine_out_type; -- see package engine_iface
|
||||
skm_i : in subkey_memory_ed_out_type; -- see package tech_iface
|
||||
skm_o : out subkey_memory_ed_in_type; -- see package tech_iface
|
||||
sbox_i : in sbox_stage_out_type; -- see package tech_iface
|
||||
sbox_o : out sbox_stage_in_type -- see package tech_iface
|
||||
);
|
||||
end component;
|
||||
|
||||
|
||||
end engine_iface;
|
||||
@@ -0,0 +1,282 @@
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Design unit : key_schedule_128 (AES 128-bit key schdeule)
|
||||
--
|
||||
-- File Name : key_schedule_128.vhd
|
||||
--
|
||||
-- Purpose : The module provides key expansion/subkey generaion
|
||||
-- functionality for AES algorithm by using ressource
|
||||
-- sharing architecture (32-bit datapath) to reduce
|
||||
-- required area
|
||||
--
|
||||
--
|
||||
-- Depends on :
|
||||
--
|
||||
-- - Package(s) : aes_definitions, aes_gf_2exp8_arith, tech_iface,
|
||||
-- key_schedule_iface, aux_funcs
|
||||
--
|
||||
-- - Module(s) : -
|
||||
--
|
||||
--
|
||||
-- Dev. Platform : Xilinx ISE 8.1i SP3 / Win32 (W2k SP4)
|
||||
--
|
||||
-- - Simulator(s) : Modelsim XE III 6.0d
|
||||
--
|
||||
-- - Synthesis : Xilinx XST
|
||||
--
|
||||
-- - Place & Route : Xilinx PAR
|
||||
--
|
||||
--
|
||||
-- Errors : None known
|
||||
--
|
||||
--
|
||||
-- Limitations : None known
|
||||
--
|
||||
--
|
||||
-- Notes : requires external S-box stage and subkey memory
|
||||
--
|
||||
--
|
||||
-- Author(s) : A. Freund (af) <a.freund@dsi-it.de>
|
||||
-- Digitale Signalverabeitung & Informationstechnik GmbH,
|
||||
-- Bremen, Germany
|
||||
--
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Revision List:
|
||||
-- Version Author(s) Date Changes
|
||||
--
|
||||
-- v0.00 af 2006-11-14 initial version
|
||||
--
|
||||
-- see SVN logs
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Naming conventions:
|
||||
--
|
||||
-- - coding style: two-process method (Gaisler-style)
|
||||
-- - active-low signals are indicated by appending "_n"
|
||||
-- - constants are in UPPERCASE
|
||||
-- - name parts are separated by "_"
|
||||
--
|
||||
-- ============================================================================
|
||||
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_arith.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
|
||||
|
||||
use work.aes_definitions.all;
|
||||
use work.aes_gf_2exp8_arith.all;
|
||||
|
||||
use work.tech_iface.all;
|
||||
use work.key_schedule_iface.all;
|
||||
use work.aux_funcs.all;
|
||||
|
||||
|
||||
entity key_schedule_128 is
|
||||
port (
|
||||
rst : in std_logic; -- reset
|
||||
clk : in std_logic; -- clock
|
||||
key_i : in key_schedule_128_in_type; -- see package key_schedule_iface
|
||||
key_o : out key_schedule_128_out_type; -- see package key_schedule_iface
|
||||
sbox_i : in sbox_stage_out_type; -- see package tech_iface
|
||||
sbox_o : out sbox_stage_in_type; -- see package tech_iface
|
||||
skm_enc_o : out subkey_memory_ks_in_type; -- see package tech_iface
|
||||
skm_dec_o : out subkey_memory_ks_in_type -- see package tech_iface
|
||||
);
|
||||
end key_schedule_128;
|
||||
|
||||
|
||||
architecture behavioural of key_schedule_128 is
|
||||
|
||||
|
||||
-- control fsm, states: idle / load key / expand key
|
||||
type ctrl_fsm_t is (cf_idle, cf_load, cf_expand);
|
||||
|
||||
type registers is record
|
||||
busy : std_logic; -- busy, key expansion in progress
|
||||
sk_slide : aes_state_t; -- sliding subkey register
|
||||
key_id : key_id_t; -- stored key id
|
||||
enc_sk_no : aes_round_no_t; -- encryption subkey number
|
||||
dec_sk_no : aes_round_no_t; -- decryption subkey number
|
||||
part_no : part_no_t; -- number of 32-bit slice within subkey
|
||||
rconst : gf_2exp8_t; -- round "constant"
|
||||
ctrl_fsm : ctrl_fsm_t; -- control fsm
|
||||
din_sel : std_logic; -- input data select (0 : input data, 1 : processing)
|
||||
sbox_sel : std_logic; -- select S-box path
|
||||
end record;
|
||||
|
||||
|
||||
type variables is record
|
||||
sbox_dout : std_logic_vector(sbox_o.din'range); -- input data to the S-box stage
|
||||
end record;
|
||||
|
||||
|
||||
signal r, rin : registers;
|
||||
|
||||
|
||||
begin
|
||||
|
||||
|
||||
-- combinatorial logic
|
||||
comb: process (rst, r, key_i, sbox_i)
|
||||
variable v : registers;
|
||||
variable t : variables;
|
||||
|
||||
begin
|
||||
-- assign default values
|
||||
v := r;
|
||||
--
|
||||
--
|
||||
--
|
||||
-- strobes
|
||||
v.sbox_sel := '0';
|
||||
|
||||
|
||||
-- count-up (down) subkey # / round constant / subkey / etc.
|
||||
if (r.busy = '1')
|
||||
then
|
||||
v.part_no := r.part_no + 1;
|
||||
|
||||
if (r.part_no = "10")
|
||||
then
|
||||
v.sbox_sel := '1';
|
||||
end if;
|
||||
end if;
|
||||
|
||||
|
||||
-- count-up (down) subkey # / round constant / subkey / etc.
|
||||
if (r.sbox_sel = '1')
|
||||
then
|
||||
v.enc_sk_no := r.enc_sk_no + 1;
|
||||
v.dec_sk_no := r.dec_sk_no - 1;
|
||||
v.rconst := mul_gf_2exp8(r.rconst, X"02");
|
||||
end if;
|
||||
|
||||
|
||||
|
||||
|
||||
v.sk_slide(127 downto 32) := r.sk_slide(95 downto 0);
|
||||
|
||||
if (r.din_sel = '0')
|
||||
then
|
||||
-- shift-in input data
|
||||
v.sk_slide(31 downto 0) := key_i.key;
|
||||
t.sbox_dout := rotl(key_i.key, 8);
|
||||
else
|
||||
if (r.sbox_sel = '1')
|
||||
then
|
||||
v.sk_slide(31 downto 0) := sbox_i.dout xor (r.rconst & X"000000") xor r.sk_slide(127 downto 96);
|
||||
else
|
||||
v.sk_slide(31 downto 0) := r.sk_slide(31 downto 0) xor r.sk_slide(127 downto 96);
|
||||
end if;
|
||||
t.sbox_dout := rotl(r.sk_slide(31 downto 0) xor r.sk_slide(127 downto 96), 8);
|
||||
end if;
|
||||
|
||||
|
||||
-- control fsm
|
||||
case r.ctrl_fsm is
|
||||
when cf_idle =>
|
||||
v.part_no := (others => '0');
|
||||
v.enc_sk_no := (others => '0');
|
||||
v.dec_sk_no := conv_std_logic_vector(AES_128_ROUNDS, skm_enc_o.rounds'length);
|
||||
v.rconst := X"01";
|
||||
|
||||
-- handle key loading
|
||||
if (key_i.load_key = '1')
|
||||
then
|
||||
v.busy := '1';
|
||||
v.key_id := key_i.key_id;
|
||||
|
||||
v.ctrl_fsm := cf_load;
|
||||
end if;
|
||||
|
||||
when cf_load =>
|
||||
-- handle last input word
|
||||
if (r.part_no = "10")
|
||||
then
|
||||
v.din_sel := '1'; -- switch to processing data
|
||||
|
||||
v.ctrl_fsm := cf_expand;
|
||||
end if;
|
||||
|
||||
when cf_expand =>
|
||||
if (r.part_no = "11") and (r.enc_sk_no = AES_128_ROUNDS)
|
||||
then
|
||||
v.din_sel := '0';
|
||||
v.busy := '0';
|
||||
|
||||
v.ctrl_fsm := cf_idle;
|
||||
end if;
|
||||
|
||||
|
||||
when others =>
|
||||
v.ctrl_fsm := cf_idle;
|
||||
end case;
|
||||
|
||||
--
|
||||
--
|
||||
--
|
||||
-- reset handling
|
||||
if (rst = '1')
|
||||
then
|
||||
v.ctrl_fsm := cf_idle;
|
||||
v.din_sel := '0';
|
||||
v.sbox_sel := '0';
|
||||
v.busy := '0';
|
||||
v.key_id := (others => '0');
|
||||
v.enc_sk_no := (others => '0');
|
||||
v.dec_sk_no := conv_std_logic_vector(AES_128_ROUNDS, skm_enc_o.rounds'length);
|
||||
v.part_no := (others => '0');
|
||||
end if;
|
||||
--
|
||||
--
|
||||
--
|
||||
-- update registers
|
||||
rin <= v;
|
||||
--
|
||||
--
|
||||
--
|
||||
-- drive outputs
|
||||
key_o.busy <= r.busy or (not sbox_i.ready);
|
||||
|
||||
sbox_o.act <= r.busy;
|
||||
sbox_o.din <= t.sbox_dout;
|
||||
sbox_o.ed_mode <= '0';
|
||||
|
||||
skm_enc_o.subkey_no <= r.enc_sk_no;
|
||||
skm_enc_o.part_no <= r.part_no;
|
||||
skm_enc_o.subkey <= r.sk_slide(31 downto 0);
|
||||
skm_enc_o.rounds <= conv_std_logic_vector(AES_128_ROUNDS, skm_enc_o.rounds'length);
|
||||
skm_enc_o.key_id <= r.key_id;
|
||||
skm_enc_o.write_en <= r.busy;
|
||||
|
||||
skm_dec_o.subkey_no <= r.dec_sk_no;
|
||||
skm_dec_o.part_no <= r.part_no;
|
||||
skm_dec_o.subkey <= r.sk_slide(31 downto 0);
|
||||
skm_dec_o.rounds <= conv_std_logic_vector(AES_128_ROUNDS, skm_enc_o.rounds'length);
|
||||
skm_dec_o.key_id <= r.key_id;
|
||||
skm_dec_o.write_en <= r.busy;
|
||||
|
||||
end process;
|
||||
|
||||
|
||||
-- registers
|
||||
regs: process (clk, rst)
|
||||
begin
|
||||
if rising_edge(clk)
|
||||
then
|
||||
r <= rin;
|
||||
end if;
|
||||
|
||||
-- async. reset
|
||||
if (rst = '1')
|
||||
then
|
||||
end if;
|
||||
end process;
|
||||
|
||||
|
||||
end behavioural;
|
||||
@@ -0,0 +1,151 @@
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Design unit : key_schedule_iface (interfaces of 128-bit and 256-bit
|
||||
-- key schedule)
|
||||
--
|
||||
-- File Name : key_schedule_iface.vhd
|
||||
--
|
||||
-- Purpose : The package collects type declarations for all non-
|
||||
-- trivial interfaces of used entities. Record types
|
||||
-- are used extensively to group related signals (e.g.
|
||||
-- data / control & status, physical attachment etc.).
|
||||
--
|
||||
--
|
||||
-- Depends on :
|
||||
--
|
||||
-- - Package(s) : aes_definitions, tech_iface
|
||||
--
|
||||
-- - Module(s) : -
|
||||
--
|
||||
--
|
||||
-- Dev. Platform : Xilinx ISE 8.1i SP3 / Win32 (W2k SP4)
|
||||
--
|
||||
-- - Simulator(s) : Modelsim XE III 6.0d
|
||||
--
|
||||
-- - Synthesis : Xilinx XST
|
||||
--
|
||||
-- - Place & Route : Xilinx PAR
|
||||
--
|
||||
--
|
||||
-- Errors : None known
|
||||
--
|
||||
--
|
||||
-- Limitations : None known
|
||||
--
|
||||
--
|
||||
-- Notes : Version for implementation using 32-bit datapath
|
||||
--
|
||||
--
|
||||
-- Author(s) : A. Freund (af) <a.freund@dsi-it.de>
|
||||
-- Digitale Signalverabeitung & Informationstechnik GmbH,
|
||||
-- Bremen, Germany
|
||||
--
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Revision List:
|
||||
-- Version Author(s) Date Changes
|
||||
--
|
||||
-- v0.00 af 2006-11-14 initial version
|
||||
--
|
||||
-- see SVN logs
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Naming conventions:
|
||||
--
|
||||
-- - coding style: record-signals for related purposes (Gaisler-style)
|
||||
-- - active-low signals are indicated by appending "_n"
|
||||
-- - constants are in UPPERCASE
|
||||
-- - name parts are separated by "_"
|
||||
--
|
||||
-- ============================================================================
|
||||
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
|
||||
use work.aes_definitions.all;
|
||||
use work.tech_iface.all;
|
||||
|
||||
|
||||
package key_schedule_iface is
|
||||
|
||||
|
||||
--
|
||||
-- 256-bit key schedule interface definition
|
||||
--
|
||||
|
||||
|
||||
-- key/control input signals
|
||||
type key_schedule_256_in_type is record
|
||||
load_key : std_logic; -- load key / start expansion
|
||||
key : part_data_t; -- encryption/decryption key
|
||||
key_id : key_id_t; -- key id to use
|
||||
end record;
|
||||
|
||||
|
||||
-- status output signals
|
||||
type key_schedule_256_out_type is record
|
||||
busy : std_logic; -- busy, key expansion in progress
|
||||
end record;
|
||||
|
||||
|
||||
--
|
||||
-- 128-bit key schedule interface definition
|
||||
--
|
||||
|
||||
|
||||
-- key/control input signals
|
||||
type key_schedule_128_in_type is record
|
||||
load_key : std_logic; -- load key / start expansion
|
||||
key : part_data_t; -- encryption/decryption key
|
||||
key_id : key_id_t; -- key id to use
|
||||
end record;
|
||||
|
||||
|
||||
-- status output signals
|
||||
type key_schedule_128_out_type is record
|
||||
busy : std_logic; -- busy, key expansion in progress
|
||||
end record;
|
||||
|
||||
|
||||
--
|
||||
--
|
||||
-- Component declarations
|
||||
--
|
||||
--
|
||||
|
||||
|
||||
-- 256-bit key schedule
|
||||
component key_schedule_256 is
|
||||
port (
|
||||
rst : in std_logic; -- reset
|
||||
clk : in std_logic; -- clock
|
||||
key_i : in key_schedule_256_in_type; -- see package key_schedule_iface
|
||||
key_o : out key_schedule_256_out_type; -- see package key_schedule_iface
|
||||
sbox_i : in sbox_stage_out_type; -- see package tech_iface
|
||||
sbox_o : out sbox_stage_in_type; -- see package tech_iface
|
||||
skm_enc_o : out subkey_memory_ks_in_type; -- see package tech_iface
|
||||
skm_dec_o : out subkey_memory_ks_in_type -- see package tech_iface
|
||||
);
|
||||
end component;
|
||||
|
||||
|
||||
-- 128-bit key schedule
|
||||
component key_schedule_128 is
|
||||
port (
|
||||
rst : in std_logic; -- reset
|
||||
clk : in std_logic; -- clock
|
||||
key_i : in key_schedule_128_in_type; -- see package key_schedule_iface
|
||||
key_o : out key_schedule_128_out_type; -- see package key_schedule_iface
|
||||
sbox_i : in sbox_stage_out_type; -- see package tech_iface
|
||||
sbox_o : out sbox_stage_in_type; -- see package tech_iface
|
||||
skm_enc_o : out subkey_memory_ks_in_type; -- see package tech_iface
|
||||
skm_dec_o : out subkey_memory_ks_in_type -- see package tech_iface
|
||||
);
|
||||
end component;
|
||||
|
||||
|
||||
end key_schedule_iface;
|
||||
@@ -0,0 +1,197 @@
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Design unit : tech_iface
|
||||
--
|
||||
-- File Name : tech_iface_virtex2.vhd
|
||||
--
|
||||
-- Purpose : The package collects type declarations for all non-
|
||||
-- trivial interfaces of used entities. Record types
|
||||
-- are used extensively to group related signals (e.g.
|
||||
-- data / control & status, physical attachment etc.).
|
||||
--
|
||||
--
|
||||
-- Depends on :
|
||||
--
|
||||
-- - Package(s) : aes_definitions
|
||||
--
|
||||
-- - Module(s) : -
|
||||
--
|
||||
--
|
||||
-- Dev. Platform : Xilinx ISE 8.1i SP3 / Win32 (W2k SP4)
|
||||
--
|
||||
-- - Simulator(s) : Modelsim XE III 6.0d
|
||||
--
|
||||
-- - Synthesis : Xilinx XST
|
||||
--
|
||||
-- - Place & Route : Xilinx PAR
|
||||
--
|
||||
--
|
||||
-- Errors : None known
|
||||
--
|
||||
--
|
||||
-- Limitations : None known
|
||||
--
|
||||
--
|
||||
-- Notes : -
|
||||
--
|
||||
--
|
||||
-- Author(s) : A. Freund (af) <a.freund@dsi-it.de>
|
||||
-- Digitale Signalverabeitung & Informationstechnik GmbH,
|
||||
-- Bremen, Germany
|
||||
--
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Revision List:
|
||||
-- Version Author(s) Date Changes
|
||||
--
|
||||
-- v0.00 af 2006-11-15 initial version
|
||||
--
|
||||
-- see SVN logs
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Naming conventions:
|
||||
--
|
||||
-- - coding style: record-signals for related purposes (Gaisler-style)
|
||||
-- - active-low signals are indicated by appending "_n"
|
||||
-- - constants are in UPPERCASE
|
||||
-- - name parts are separated by "_"
|
||||
--
|
||||
-- ============================================================================
|
||||
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
|
||||
use work.aes_definitions.all;
|
||||
|
||||
|
||||
package tech_iface is
|
||||
|
||||
|
||||
-- architecture-dependent key-id size (matching Virtex-II BlockRAM size)
|
||||
subtype key_id_t is std_logic_vector(2 downto 0);
|
||||
|
||||
|
||||
-- number of 32-bit slice within subkey
|
||||
subtype part_no_t is std_logic_vector(1 downto 0);
|
||||
|
||||
-- 32-bit slice of 128-bit data block
|
||||
subtype part_data_t is std_logic_vector(31 downto 0);
|
||||
|
||||
-- 32-bit slice of 128-bit subkey
|
||||
subtype part_subkey_t is std_logic_vector(31 downto 0);
|
||||
|
||||
|
||||
--
|
||||
-- S-box stage interface definition (32-bit version, 2x7-bit + 2x9-bit, mapping as required by KS-128)
|
||||
--
|
||||
|
||||
|
||||
-- s-box stage input signals
|
||||
type sbox_stage_in_type is record
|
||||
act : std_logic; -- read-enable control (to suppress simulation warnings)
|
||||
din : part_data_t; -- S-box input data
|
||||
ed_mode : std_logic; -- encryption (0) / decryption (1) mode
|
||||
end record;
|
||||
|
||||
|
||||
-- s-box stage load input signals
|
||||
type sbox_stage_load_in_type is record
|
||||
act : std_logic; -- activate load I/F
|
||||
ed_mode : std_logic; -- encryption (0) / decryption (1) mode
|
||||
pos : aes_sbox_8_t; -- position
|
||||
din : aes_sbox_8_t; -- new value
|
||||
wen : std_logic; -- write enable
|
||||
done : std_logic; -- S-box loading done
|
||||
end record;
|
||||
|
||||
|
||||
-- s-box stage outputs signals
|
||||
type sbox_stage_out_type is record
|
||||
dout : part_data_t; -- S-box output data
|
||||
ready : std_logic; -- S-box stage is ready
|
||||
end record;
|
||||
|
||||
|
||||
--
|
||||
-- subkey memory interface definition (32-bit version)
|
||||
--
|
||||
|
||||
|
||||
-- key-schedule - side input signals
|
||||
type subkey_memory_ks_in_type is record
|
||||
write_en : std_logic; -- write enable
|
||||
key_id : key_id_t; -- key id to use
|
||||
subkey_no : aes_round_no_t; -- subkey number
|
||||
part_no : part_no_t; -- 32-bit slice number
|
||||
subkey : part_subkey_t; -- subkey
|
||||
rounds : aes_round_no_t; -- number of rounds
|
||||
end record;
|
||||
|
||||
|
||||
-- key-schedule - side output signals
|
||||
type subkey_memory_ks_out_type is record
|
||||
dummy : std_logic;
|
||||
end record;
|
||||
|
||||
|
||||
-- encryption/decryption - side input signals
|
||||
type subkey_memory_ed_in_type is record
|
||||
rd_en : std_logic; -- read-enable control (to suppress simulation warnings)
|
||||
subkey_no : aes_round_no_t; -- subkey number
|
||||
part_no : part_no_t; -- 32-bit slice number
|
||||
key_id : key_id_t; -- key id to use
|
||||
end record;
|
||||
|
||||
|
||||
-- encryption/decryption - side output signals
|
||||
type subkey_memory_ed_out_type is record
|
||||
subkey : part_subkey_t; -- subkey
|
||||
rounds : aes_round_no_t; -- number of rounds
|
||||
end record;
|
||||
|
||||
|
||||
--
|
||||
--
|
||||
-- Component declarations
|
||||
--
|
||||
--
|
||||
|
||||
|
||||
-- S-Box stage
|
||||
component tech_sbox_stage is
|
||||
port (
|
||||
rst : in std_logic; -- reset
|
||||
clk : in std_logic; -- clock
|
||||
data_i : in sbox_stage_in_type; -- see package tech_iface
|
||||
data_o : out sbox_stage_out_type; -- see package tech_iface
|
||||
load_i : in sbox_stage_load_in_type -- see package tech_iface
|
||||
);
|
||||
end component;
|
||||
|
||||
|
||||
-- subkey memory
|
||||
component tech_subkey_memory is
|
||||
port (
|
||||
clk : in std_logic; -- clock
|
||||
key_sched_i : in subkey_memory_ks_in_type; -- see package tech_iface
|
||||
enc_dec_i : in subkey_memory_ed_in_type; -- see package tech_iface
|
||||
enc_dec_o : out subkey_memory_ed_out_type -- see package tech_iface
|
||||
);
|
||||
end component;
|
||||
|
||||
|
||||
-- S-box loader (mainly for simulation)
|
||||
component sbox_loader is
|
||||
port (
|
||||
rst : in std_logic; -- reset
|
||||
clk : in std_logic; -- clock
|
||||
load_o : out sbox_stage_load_in_type -- see package tech_iface
|
||||
);
|
||||
end component;
|
||||
|
||||
|
||||
end tech_iface;
|
||||
@@ -0,0 +1,184 @@
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Design unit : tech_sbox_stage
|
||||
--
|
||||
-- File Name : tech_sbox_stage_virtex2.vhd
|
||||
--
|
||||
-- Purpose : The module provides S-box stage for implementation of
|
||||
-- encryption, decryption and key schedule using 32-bit
|
||||
-- datapath on Virtex-II family
|
||||
--
|
||||
--
|
||||
-- Depends on :
|
||||
--
|
||||
-- - Package(s) : aes_definitions, tech_iface
|
||||
--
|
||||
-- - Module(s) : dual_sbox_virtex2 (dual-port RAM block)
|
||||
--
|
||||
--
|
||||
-- Dev. Platform : Xilinx ISE 8.1i SP3 / Win32 (W2k SP4)
|
||||
--
|
||||
-- - Simulator(s) : Modelsim XE III 6.0d
|
||||
--
|
||||
-- - Synthesis : Xilinx XST
|
||||
--
|
||||
-- - Place & Route : Xilinx PAR
|
||||
--
|
||||
--
|
||||
-- Errors : None known
|
||||
--
|
||||
--
|
||||
-- Limitations : None known
|
||||
--
|
||||
--
|
||||
-- Notes : S-box type mapping as required by 128-bit key schedule
|
||||
--
|
||||
--
|
||||
-- Author(s) : A. Freund (af) <a.freund@dsi-it.de>
|
||||
-- Digitale Signalverabeitung & Informationstechnik GmbH,
|
||||
-- Bremen, Germany
|
||||
--
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Revision List:
|
||||
-- Version Author(s) Date Changes
|
||||
--
|
||||
-- v0.00 af 2006-11-02 initial version
|
||||
--
|
||||
-- see SVN logs
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Naming conventions:
|
||||
--
|
||||
-- - active-low signals are indicated by appending "_n"
|
||||
-- - constants are in UPPERCASE
|
||||
-- - name parts are separated by "_"
|
||||
--
|
||||
-- ============================================================================
|
||||
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
|
||||
use work.aes_definitions.all;
|
||||
use work.tech_iface.all;
|
||||
|
||||
|
||||
entity tech_sbox_stage is
|
||||
port (
|
||||
rst : in std_logic; -- reset
|
||||
clk : in std_logic; -- clock
|
||||
data_i : in sbox_stage_in_type; -- see package tech_iface
|
||||
data_o : out sbox_stage_out_type; -- see package tech_iface
|
||||
load_i : in sbox_stage_load_in_type -- see package tech_iface
|
||||
);
|
||||
end tech_sbox_stage;
|
||||
|
||||
|
||||
architecture behavioural of tech_sbox_stage is
|
||||
|
||||
|
||||
component dual_sbox_virtex2 is
|
||||
port (
|
||||
clk : in std_logic; -- clock (rising)
|
||||
enca : in std_logic; -- encryption (0) / decryption (1) mode
|
||||
encb : in std_logic; -- encryption (0) / decryption (1) mode
|
||||
posa : in std_logic_vector(7 downto 0); -- position
|
||||
posb : in std_logic_vector(7 downto 0); -- position
|
||||
dina : in std_logic_vector(7 downto 0); -- write data
|
||||
dinb : in std_logic_vector(7 downto 0); -- write data
|
||||
wea : in std_logic; -- write enable
|
||||
web : in std_logic; -- write enable
|
||||
douta : out std_logic_vector(7 downto 0); -- read data
|
||||
doutb : out std_logic_vector(7 downto 0); -- read data
|
||||
is_init : out std_logic -- pre-initialised memory
|
||||
);
|
||||
end component;
|
||||
|
||||
|
||||
signal s_din : std_logic_vector(31 downto 0); -- S-box input data
|
||||
signal s_ed_mode : std_logic; -- en-/decryption mode selection
|
||||
|
||||
signal s_wen : std_logic; -- write enable
|
||||
signal s_ready : std_logic; -- S-box is ready
|
||||
|
||||
signal s_is_init : std_logic_vector(1 downto 0); -- S-box is pre-initialized
|
||||
|
||||
|
||||
begin
|
||||
|
||||
|
||||
-- handle activation of load I/F
|
||||
process (load_i, data_i)
|
||||
begin
|
||||
if (load_i.act = '1')
|
||||
then
|
||||
s_din <= load_i.pos & load_i.pos & load_i.pos & load_i.pos;
|
||||
s_ed_mode <= load_i.ed_mode;
|
||||
s_wen <= load_i.wen;
|
||||
else
|
||||
s_din <= data_i.din;
|
||||
s_ed_mode <= data_i.ed_mode;
|
||||
s_wen <= '0';
|
||||
end if;
|
||||
end process;
|
||||
|
||||
|
||||
sbox_2x8_1: dual_sbox_virtex2
|
||||
port map (
|
||||
clk => clk,
|
||||
enca => s_ed_mode,
|
||||
encb => s_ed_mode,
|
||||
posa => s_din(31 downto 24),
|
||||
posb => s_din(23 downto 16),
|
||||
dina => load_i.din,
|
||||
dinb => (others => '0'),
|
||||
wea => s_wen,
|
||||
web => '0',
|
||||
douta => data_o.dout(31 downto 24),
|
||||
doutb => data_o.dout(23 downto 16),
|
||||
is_init => s_is_init(1)
|
||||
);
|
||||
|
||||
|
||||
sbox_2x8_0: dual_sbox_virtex2
|
||||
port map (
|
||||
clk => clk,
|
||||
enca => s_ed_mode,
|
||||
encb => s_ed_mode,
|
||||
posa => s_din(15 downto 8),
|
||||
posb => s_din(7 downto 0),
|
||||
dina => load_i.din,
|
||||
dinb => (others => '0'),
|
||||
wea => s_wen,
|
||||
web => '0',
|
||||
douta => data_o.dout(15 downto 8),
|
||||
doutb => data_o.dout(7 downto 0),
|
||||
is_init => s_is_init(0)
|
||||
);
|
||||
|
||||
|
||||
-- generate S-box ready flag
|
||||
process
|
||||
begin
|
||||
wait until rising_edge(clk);
|
||||
if (rst = '1')
|
||||
then
|
||||
s_ready <= s_is_init(0) and s_is_init(1);
|
||||
elsif (load_i.act = '1') and (load_i.wen = '1')
|
||||
then
|
||||
s_ready <= '0';
|
||||
elsif (load_i.act = '1') and (load_i.done = '1')
|
||||
then
|
||||
s_ready <= '1';
|
||||
end if;
|
||||
end process;
|
||||
|
||||
|
||||
data_o.ready <= (not load_i.act) and s_ready;
|
||||
|
||||
|
||||
end behavioural;
|
||||
@@ -0,0 +1,142 @@
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Design unit : tech_subkey_memory
|
||||
--
|
||||
-- File Name : tech_subkey_memory_virtex2.vhd
|
||||
--
|
||||
-- Purpose : The module provides subkey memory for implementation of
|
||||
-- encryption, decryption and key schedule using 32-bit
|
||||
-- datapath on Virtex-II family
|
||||
--
|
||||
--
|
||||
-- Depends on :
|
||||
--
|
||||
-- - Package(s) : aes_definitions, tech_iface
|
||||
--
|
||||
-- - Module(s) : -
|
||||
--
|
||||
--
|
||||
-- Dev. Platform : Xilinx ISE 8.1i SP3 / Win32 (W2k SP4)
|
||||
--
|
||||
-- - Simulator(s) : Modelsim XE III 6.0d
|
||||
--
|
||||
-- - Synthesis : Xilinx XST
|
||||
--
|
||||
-- - Place & Route : Xilinx PAR
|
||||
--
|
||||
--
|
||||
-- Errors : None known
|
||||
--
|
||||
--
|
||||
-- Limitations : None known
|
||||
--
|
||||
--
|
||||
-- Notes : parity memory is used to store number of rounds
|
||||
-- beside the subkey
|
||||
--
|
||||
--
|
||||
-- Author(s) : A. Freund (af) <a.freund@dsi-it.de>
|
||||
-- Digitale Signalverabeitung & Informationstechnik GmbH,
|
||||
-- Bremen, Germany
|
||||
--
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Revision List:
|
||||
-- Version Author(s) Date Changes
|
||||
--
|
||||
-- v0.00 af 2006-11-15 initial version
|
||||
--
|
||||
-- see SVN logs
|
||||
--
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Naming conventions:
|
||||
--
|
||||
-- - active-low signals are indicated by appending "_n"
|
||||
-- - constants are in UPPERCASE
|
||||
-- - name parts are separated by "_"
|
||||
--
|
||||
-- ============================================================================
|
||||
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_arith.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
|
||||
library unisim;
|
||||
use unisim.vcomponents.all;
|
||||
|
||||
|
||||
use work.aes_definitions.all;
|
||||
use work.tech_iface.all;
|
||||
|
||||
|
||||
entity tech_subkey_memory is
|
||||
port (
|
||||
clk : in std_logic; -- clock
|
||||
key_sched_i : in subkey_memory_ks_in_type; -- see package tech_iface
|
||||
enc_dec_i : in subkey_memory_ed_in_type; -- see package tech_iface
|
||||
enc_dec_o : out subkey_memory_ed_out_type -- see package tech_iface
|
||||
);
|
||||
end tech_subkey_memory;
|
||||
|
||||
|
||||
architecture behavioural of tech_subkey_memory is
|
||||
|
||||
signal s_pm_a_in : std_logic_vector(3 downto 0) := (others => '0');
|
||||
signal s_pm_b_out : std_logic_vector(3 downto 0);
|
||||
|
||||
signal s_addr_a : std_logic_vector(key_id_t'length + aes_round_no_t'length + part_no_t'length - 1 downto 0);
|
||||
signal s_addr_b : std_logic_vector(key_id_t'length + aes_round_no_t'length + part_no_t'length - 1 downto 0);
|
||||
|
||||
|
||||
begin
|
||||
|
||||
|
||||
s_pm_a_in(aes_round_no_t'range) <= key_sched_i.rounds;
|
||||
|
||||
s_addr_a <= key_sched_i.key_id & key_sched_i.subkey_no & key_sched_i.part_no;
|
||||
|
||||
s_addr_b <= enc_dec_i.key_id & enc_dec_i.subkey_no & enc_dec_i.part_no;
|
||||
|
||||
|
||||
-- 1 Block-RAMs for subkey memory, port A : key schedule, port B : en-/decryprion
|
||||
|
||||
-- RAMB16_S36_S36: Virtex-II/II-Pro, Spartan-3/3E 512 x 32 + 4 Parity bits Dual-Port RAM
|
||||
-- Xilinx HDL Language Template version 7.1i
|
||||
|
||||
skm: RAMB16_S36_S36
|
||||
generic map (
|
||||
WRITE_MODE_A => "READ_FIRST", -- WRITE_FIRST, READ_FIRST or NO_CHANGE
|
||||
WRITE_MODE_B => "READ_FIRST", -- WRITE_FIRST, READ_FIRST or NO_CHANGE
|
||||
SIM_COLLISION_CHECK => "NONE" -- "NONE", "WARNING", "GENERATE_X_ONLY", "ALL"
|
||||
)
|
||||
port map (
|
||||
DOA => open, -- Port A 32-bit Data Output
|
||||
DOB => enc_dec_o.subkey, -- Port B 32-bit Data Output
|
||||
DOPA => open, -- Port A 4-bit Parity Output
|
||||
DOPB => s_pm_b_out, -- Port B 4-bit Parity Output
|
||||
ADDRA => s_addr_a, -- Port A 9-bit Address Input
|
||||
ADDRB => s_addr_b, -- Port B 9-bit Address Input
|
||||
CLKA => clk, -- Port A Clock
|
||||
CLKB => clk, -- Port B Clock
|
||||
DIA => key_sched_i.subkey, -- Port A 32-bit Data Input
|
||||
DIB => X"00000000", -- Port B 32-bit Data Input
|
||||
DIPA => s_pm_a_in, -- Port A 4-bit parity Input
|
||||
DIPB => "0000", -- Port-B 4-bit parity Input
|
||||
ENA => key_sched_i.write_en, -- Port A RAM Enable Input
|
||||
ENB => enc_dec_i.rd_en, -- PortB RAM Enable Input
|
||||
SSRA => '0', -- Port A Synchronous Set/Reset Input
|
||||
SSRB => '0', -- Port B Synchronous Set/Reset Input
|
||||
WEA => key_sched_i.write_en, -- Port A Write Enable Input
|
||||
WEB => '0' -- Port B Write Enable Input
|
||||
);
|
||||
|
||||
|
||||
|
||||
enc_dec_o.rounds <= s_pm_b_out(aes_round_no_t'range);
|
||||
|
||||
|
||||
end behavioural;
|
||||
@@ -0,0 +1,309 @@
|
||||
----------------------------------------------------------------------------------
|
||||
-- Company:
|
||||
-- Engineer:
|
||||
--
|
||||
-- Create Date: 08:27:43 08/26/2006
|
||||
-- Design Name:
|
||||
-- Module Name: ac_out - Behavioral
|
||||
-- Project Name:
|
||||
-- Target Devices:
|
||||
-- Tool versions:
|
||||
-- Description:
|
||||
--
|
||||
-- Dependencies:
|
||||
--
|
||||
-- Revision:
|
||||
-- Revision 0.01 - File Created
|
||||
-- Additional Comments:
|
||||
--
|
||||
----------------------------------------------------------------------------------
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
---- Uncomment the following library declaration if instantiating
|
||||
---- any Xilinx primitives in this code.
|
||||
--library UNISIM;
|
||||
--use UNISIM.VComponents.all;
|
||||
|
||||
entity ac_in is
|
||||
Port (
|
||||
rst : in std_logic;
|
||||
clk : in std_logic;
|
||||
sync_frame : out std_logic;
|
||||
sync_status : out std_logic;
|
||||
slot_valid : out unsigned(0 to 12);
|
||||
stat_addr : out unsigned (19 downto 0);
|
||||
stat_data : out unsigned (19 downto 0);
|
||||
pcm_out_addr : in unsigned (3 downto 0);
|
||||
pcm_out_data : out unsigned (19 downto 0);
|
||||
ac_reset : in std_logic;
|
||||
ac_bit_clk : in std_logic;
|
||||
ac_sdata_in : in std_logic;
|
||||
ac_ssync : in std_logic
|
||||
);
|
||||
end ac_in;
|
||||
|
||||
architecture Behavioral of ac_in is
|
||||
|
||||
------------------------------------------------------------------
|
||||
COMPONENT singleshot
|
||||
GENERIC (mode : integer);
|
||||
PORT(
|
||||
rst : IN std_logic;
|
||||
clk : IN std_logic;
|
||||
input : IN std_logic;
|
||||
output : OUT std_logic
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
------------------------------------------------------------------
|
||||
type sac_t is (ac_idle, ac_tag, ac_data);
|
||||
subtype bitcnt_t is integer range 0 to 19;
|
||||
subtype slotcnt_t is integer range 0 to 12;
|
||||
subtype slot_valid_t is UNSIGNED(0 to 12);
|
||||
subtype tag_t is UNSIGNED(15 downto 0);
|
||||
subtype slot_t is UNSIGNED(19 downto 0);
|
||||
type slot_array_t is array (natural range <>) of slot_t;
|
||||
|
||||
signal data_array : slot_array_t (1 to 12);
|
||||
signal tag : tag_t;
|
||||
|
||||
signal sac, snac : sac_t;
|
||||
signal bitcnt : bitcnt_t;
|
||||
signal bitcnt_rst, bitcnt_en : STD_LOGIC;
|
||||
signal slotcnt : slotcnt_t;
|
||||
signal slotcnt_rst, slotcnt_en : STD_LOGIC;
|
||||
|
||||
signal rx_reg : slot_t;
|
||||
signal stat_read, host_update : STD_LOGIC;
|
||||
signal sync_end, slot_end, last_slot, start_of_frame : STD_LOGIC;
|
||||
|
||||
------------------------------------------------------------------
|
||||
function GetSlotValid(data : tag_t) return slot_valid_t is
|
||||
variable res : slot_valid_t := (others => '0');
|
||||
begin
|
||||
res := (others => '0');
|
||||
for i in slot_valid_t'range loop
|
||||
res(i) := data(data'left-i);
|
||||
end loop;
|
||||
return res;
|
||||
|
||||
end GetSlotValid;
|
||||
|
||||
------------------------------------------------------------------
|
||||
begin
|
||||
|
||||
-------------------------------------------------------------
|
||||
-- proc_status_flags
|
||||
-------------------------------------------------------------
|
||||
proc_status_flags:
|
||||
process (rst, clk, host_update, tag, data_array)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
sync_status <= '0';
|
||||
if rst = '1' then
|
||||
slot_valid <= (others => '0');
|
||||
stat_addr <= (others => '0');
|
||||
stat_data <= (others => '0');
|
||||
elsif host_update = '1' then
|
||||
sync_status <= '1';
|
||||
slot_valid <= GetSlotValid(tag);
|
||||
stat_addr <= data_array(1);
|
||||
stat_data <= data_array(2);
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-------------------------------------------------------------
|
||||
-- proc_pcm_data
|
||||
-------------------------------------------------------------
|
||||
proc_pcm_data:
|
||||
process (clk, pcm_out_addr, data_array)
|
||||
variable slot_id : integer range 0 to 12;
|
||||
begin
|
||||
pcm_out_data <= (others => '-');
|
||||
slot_id := to_integer(pcm_out_addr);
|
||||
if (slot_id > 2) then
|
||||
pcm_out_data <= data_array(slot_id);
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-------------------------------------------------------------
|
||||
-- proc_read_data
|
||||
-------------------------------------------------------------
|
||||
proc_read_data :
|
||||
process (ac_reset, ac_bit_clk, slot_end, slotcnt)
|
||||
begin
|
||||
|
||||
if ac_reset = '1' then
|
||||
stat_read <= '0';
|
||||
elsif rising_edge(ac_bit_clk) then
|
||||
stat_read <= '0';
|
||||
if slot_end = '1' and slotcnt /= 0 then
|
||||
data_array(slotcnt) <= rx_reg;
|
||||
if slotcnt = 2 then
|
||||
stat_read <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-------------------------------------------------------------
|
||||
-- proc_read_stat
|
||||
-------------------------------------------------------------
|
||||
proc_read_tag :
|
||||
process (ac_reset, ac_bit_clk, sync_end)
|
||||
begin
|
||||
|
||||
if ac_reset = '1' then
|
||||
tag <= (others => '0');
|
||||
elsif rising_edge(ac_bit_clk) then
|
||||
if sync_end = '1' then
|
||||
tag <= rx_reg(15 downto 0);
|
||||
end if;
|
||||
end if;
|
||||
|
||||
end process;
|
||||
|
||||
-------------------------------------------------------------
|
||||
-- proc_slot_count
|
||||
-------------------------------------------------------------
|
||||
proc_slot_count:
|
||||
process (slotcnt_rst, ac_bit_clk, slotcnt_en, slotcnt)
|
||||
begin
|
||||
if rising_edge(ac_bit_clk) then
|
||||
if slotcnt_rst = '1' then
|
||||
slotcnt <= slotcnt_t'low;
|
||||
elsif slotcnt_en = '1' then
|
||||
if slotcnt /= slotcnt_t'high then
|
||||
slotcnt <= slotcnt + 1;
|
||||
else
|
||||
slotcnt <= slotcnt_t'low;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-------------------------------------------------------------
|
||||
-- proc_bit_count
|
||||
-------------------------------------------------------------
|
||||
proc_bit_count:
|
||||
process (bitcnt_rst, ac_bit_clk, bitcnt_en, bitcnt)
|
||||
begin
|
||||
if rising_edge(ac_bit_clk) then
|
||||
if bitcnt_rst = '1' then
|
||||
bitcnt <= bitcnt_t'low;
|
||||
elsif bitcnt_en = '1' then
|
||||
if bitcnt /= bitcnt_t'high then
|
||||
bitcnt <= bitcnt + 1;
|
||||
else
|
||||
bitcnt <= bitcnt_t'low;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
------------------------------------------------------------------
|
||||
proc_ac_fsm:
|
||||
process (bitcnt, slotcnt, sac, ac_ssync)
|
||||
begin
|
||||
snac <= sac;
|
||||
bitcnt_rst <= '0';
|
||||
bitcnt_en <= '1';
|
||||
slotcnt_rst <= '0';
|
||||
slotcnt_en <= '0';
|
||||
slot_end <= '0';
|
||||
sync_end <= '0';
|
||||
last_slot <= '0';
|
||||
start_of_frame <= '0';
|
||||
|
||||
if bitcnt = 19 then
|
||||
slot_end <= '1';
|
||||
end if;
|
||||
if slotcnt = 12 and bitcnt = 19 then
|
||||
last_slot <= '1';
|
||||
end if;
|
||||
|
||||
case sac is
|
||||
|
||||
when ac_idle =>
|
||||
bitcnt_rst <= '1';
|
||||
slotcnt_rst <= '1';
|
||||
if (ac_ssync = '1') then
|
||||
snac <= ac_tag;
|
||||
end if;
|
||||
|
||||
when ac_tag =>
|
||||
if (bitcnt = 0) then
|
||||
start_of_frame <= '1';
|
||||
elsif (bitcnt = 15) then
|
||||
slotcnt_en <= '1';
|
||||
bitcnt_rst <= '1';
|
||||
sync_end <= '1';
|
||||
if (ac_ssync = '0') then
|
||||
snac <= ac_data;
|
||||
else
|
||||
snac <= ac_idle;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
when ac_data =>
|
||||
if bitcnt = 19 then
|
||||
slotcnt_en <= '1';
|
||||
if slotcnt = 12 then
|
||||
slotcnt_rst <= '1';
|
||||
snac <= ac_tag;
|
||||
end if;
|
||||
end if;
|
||||
when others => null;
|
||||
end case;
|
||||
end process;
|
||||
|
||||
proc_ac_fsm_next:
|
||||
process (ac_reset, ac_bit_clk, snac)
|
||||
begin
|
||||
if ac_reset = '1' then
|
||||
sac <= ac_idle;
|
||||
elsif rising_edge(ac_bit_clk) then
|
||||
sac <= snac;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-------------------------------------------------------------
|
||||
-- Receive Shift Register
|
||||
-------------------------------------------------------------
|
||||
process (ac_reset, ac_bit_clk, ac_sdata_in)
|
||||
begin
|
||||
if ac_reset = '1' then
|
||||
rx_reg <= (others => '0');
|
||||
elsif falling_edge(ac_bit_clk) then
|
||||
rx_reg <= rx_reg(rx_reg'left-1 downto 0) & ac_sdata_in;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
------------------------------------------------------------------
|
||||
singleshot_inst1: singleshot
|
||||
GENERIC MAP (
|
||||
mode => 0)
|
||||
PORT MAP(
|
||||
rst => rst,
|
||||
clk => clk,
|
||||
input => stat_read,
|
||||
output => host_update
|
||||
);
|
||||
|
||||
singleshot_inst2: singleshot
|
||||
GENERIC MAP (
|
||||
mode => 1)
|
||||
PORT MAP(
|
||||
rst => rst,
|
||||
clk => clk,
|
||||
input => start_of_frame,
|
||||
output => sync_frame
|
||||
);
|
||||
|
||||
-------------------------------------------------------------
|
||||
|
||||
end Behavioral;
|
||||
|
||||
@@ -0,0 +1,182 @@
|
||||
----------------------------------------------------------------------------------
|
||||
-- Company:
|
||||
-- Engineer:
|
||||
--
|
||||
-- Create Date: 18:29:55 08/26/2006
|
||||
-- Design Name:
|
||||
-- Module Name: ac_io - Behavioral
|
||||
-- Project Name:
|
||||
-- Target Devices:
|
||||
-- Tool versions:
|
||||
-- Description:
|
||||
--
|
||||
-- Dependencies:
|
||||
--
|
||||
-- Revision:
|
||||
-- Revision 0.01 - File Created
|
||||
-- Additional Comments:
|
||||
--
|
||||
----------------------------------------------------------------------------------
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
---- Uncomment the following library declaration if instantiating
|
||||
---- any Xilinx primitives in this code.
|
||||
--library UNISIM;
|
||||
--use UNISIM.VComponents.all;
|
||||
|
||||
entity ac_io is
|
||||
Port (
|
||||
rst : in std_logic;
|
||||
clk : in std_logic;
|
||||
ready : out std_logic;
|
||||
sync_strobe : out unsigned(0 to 2);
|
||||
slot_valid : out unsigned(0 to 12);
|
||||
stat_addr : out unsigned (19 downto 0);
|
||||
stat_data : out unsigned (19 downto 0);
|
||||
rx_pcm_addr : in unsigned (3 downto 0);
|
||||
rx_pcm_data : out unsigned (19 downto 0);
|
||||
cmd_addr : in unsigned(19 downto 0);
|
||||
cmd_data : in unsigned(19 downto 0);
|
||||
cmd_we : in std_logic;
|
||||
tx_pcm_addr : in unsigned(3 downto 0);
|
||||
tx_pcm_data : in unsigned(19 downto 0);
|
||||
tx_pcm_we : in std_logic;
|
||||
ac_sdata_in : in std_logic;
|
||||
ac_bit_clk : in std_logic;
|
||||
ac_reset_n : out std_logic;
|
||||
ac_sdata_out : out std_logic;
|
||||
ac_ssync : out std_logic);
|
||||
|
||||
end ac_io;
|
||||
|
||||
architecture Behavioral of ac_io is
|
||||
|
||||
COMPONENT ac_in
|
||||
Port (
|
||||
rst : in std_logic;
|
||||
clk : in std_logic;
|
||||
sync_frame : out std_logic;
|
||||
sync_status : out std_logic;
|
||||
slot_valid : out unsigned(0 to 12);
|
||||
stat_addr : out unsigned (19 downto 0);
|
||||
stat_data : out unsigned (19 downto 0);
|
||||
pcm_out_addr : in unsigned (3 downto 0);
|
||||
pcm_out_data : out unsigned (19 downto 0);
|
||||
ac_reset : in std_logic;
|
||||
ac_bit_clk : in std_logic;
|
||||
ac_sdata_in : in std_logic;
|
||||
ac_ssync : in std_logic
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
COMPONENT ac_out
|
||||
PORT(
|
||||
rst : in std_logic;
|
||||
clk : in std_logic;
|
||||
sync_tx : out std_logic;
|
||||
cmd_addr : in unsigned(19 downto 0);
|
||||
cmd_data : in unsigned(19 downto 0);
|
||||
cmd_we : in std_logic;
|
||||
pcm_in_addr : in unsigned(3 downto 0);
|
||||
pcm_in_data : in unsigned(19 downto 0);
|
||||
pcm_in_we : in std_logic;
|
||||
ac_bit_clk : in std_logic;
|
||||
ac_reset : in std_logic;
|
||||
ac_sdata_out : out std_logic;
|
||||
ac_ssync : out std_logic
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
SIGNAL ac_reset : std_logic;
|
||||
SIGNAL ssync_rx : std_logic;
|
||||
SIGNAL ssync_tx : std_logic;
|
||||
SIGNAL sync_frame : std_logic;
|
||||
SIGNAL sync_status : std_logic;
|
||||
SIGNAL sync_tx : std_logic;
|
||||
|
||||
begin
|
||||
|
||||
inst_ac_in: ac_in PORT MAP(
|
||||
rst => rst,
|
||||
clk => clk,
|
||||
sync_frame => sync_frame,
|
||||
sync_status => sync_status,
|
||||
slot_valid => slot_valid,
|
||||
stat_addr => stat_addr,
|
||||
stat_data => stat_data,
|
||||
pcm_out_addr => rx_pcm_addr,
|
||||
pcm_out_data => rx_pcm_data,
|
||||
ac_reset => ac_reset,
|
||||
ac_bit_clk => ac_bit_clk,
|
||||
ac_sdata_in => ac_sdata_in,
|
||||
ac_ssync => ssync_rx
|
||||
);
|
||||
|
||||
inst_ac_out: ac_out PORT MAP(
|
||||
rst => rst,
|
||||
clk => clk,
|
||||
sync_tx => sync_tx,
|
||||
cmd_addr => cmd_addr,
|
||||
cmd_data => cmd_data,
|
||||
cmd_we => cmd_we,
|
||||
pcm_in_addr => tx_pcm_addr,
|
||||
pcm_in_data => tx_pcm_data,
|
||||
pcm_in_we => tx_pcm_we,
|
||||
ac_reset => ac_reset,
|
||||
ac_bit_clk => ac_bit_clk,
|
||||
ac_sdata_out => ac_sdata_out,
|
||||
ac_ssync => ssync_tx
|
||||
);
|
||||
|
||||
------------------------------------------------------------------
|
||||
ready <= not ac_reset;
|
||||
ac_ssync <= ssync_tx;
|
||||
ssync_rx <= ssync_tx;
|
||||
sync_strobe <= sync_frame & sync_status & sync_tx;
|
||||
|
||||
------------------------------------------------------------------
|
||||
proc_reset_gen:
|
||||
process (rst, clk, ac_bit_clk)
|
||||
type rstate_t is (s0, s1);
|
||||
variable rstate, rstaten : rstate_t;
|
||||
subtype cnt_t is integer range 0 to 999;
|
||||
variable cnt : cnt_t;
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' then
|
||||
rstate := s0;
|
||||
cnt := cnt_t'high;
|
||||
ac_reset <= '1';
|
||||
ac_reset_n <= '0';
|
||||
else
|
||||
rstaten := rstate;
|
||||
case rstate is
|
||||
when s0 =>
|
||||
if cnt /= 0 then
|
||||
cnt := cnt - 1;
|
||||
else
|
||||
ac_reset_n <= '1';
|
||||
if ac_bit_clk = '1' then
|
||||
rstaten := s1;
|
||||
cnt := cnt_t'high;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
when s1 =>
|
||||
if cnt /= 0 then
|
||||
cnt := cnt - 1;
|
||||
else
|
||||
ac_reset <= '0';
|
||||
end if;
|
||||
end case;
|
||||
rstate := rstaten;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
------------------------------------------------------------------
|
||||
|
||||
end Behavioral;
|
||||
|
||||
@@ -0,0 +1,276 @@
|
||||
----------------------------------------------------------------------------------
|
||||
-- Company:
|
||||
-- Engineer:
|
||||
--
|
||||
-- Create Date: 15:41:12 06/05/2007
|
||||
-- Design Name:
|
||||
-- Module Name: ac_out - Behavioral
|
||||
-- Project Name:
|
||||
-- Target Devices:
|
||||
-- Tool versions:
|
||||
-- Description:
|
||||
--
|
||||
-- Dependencies:
|
||||
--
|
||||
-- Revision:
|
||||
-- Revision 0.01 - File Created
|
||||
-- Additional Comments:
|
||||
--
|
||||
----------------------------------------------------------------------------------
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
---- Uncomment the following library declaration if instantiating
|
||||
---- any Xilinx primitives in this code.
|
||||
--library UNISIM;
|
||||
--use UNISIM.VComponents.all;
|
||||
|
||||
entity ac_out is
|
||||
Port (
|
||||
rst : in std_logic;
|
||||
clk : in std_logic;
|
||||
sync_tx : out std_logic;
|
||||
cmd_addr : in unsigned (19 downto 0);
|
||||
cmd_data : in unsigned (19 downto 0);
|
||||
cmd_we : in std_logic;
|
||||
pcm_in_addr : in unsigned (3 downto 0);
|
||||
pcm_in_data : in unsigned (19 downto 0);
|
||||
pcm_in_we : in std_logic;
|
||||
ac_reset : in std_logic;
|
||||
ac_bit_clk : in std_logic;
|
||||
ac_sdata_out : out std_logic;
|
||||
ac_ssync : out std_logic
|
||||
);
|
||||
end ac_out;
|
||||
|
||||
architecture Behavioral of ac_out is
|
||||
|
||||
------------------------------------------------------------------
|
||||
COMPONENT singleshot
|
||||
GENERIC (mode : integer);
|
||||
PORT(
|
||||
rst : IN std_logic;
|
||||
clk : IN std_logic;
|
||||
input : IN std_logic;
|
||||
output : OUT std_logic
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
------------------------------------------------------------------
|
||||
subtype tag_t is UNSIGNED(15 downto 0);
|
||||
subtype slot_valid_t is UNSIGNED(1 to 12);
|
||||
signal slot_valid : slot_valid_t;
|
||||
subtype slot_t is UNSIGNED(19 downto 0);
|
||||
type slot_array_t is array (natural range <>) of slot_t;
|
||||
signal data_array : slot_array_t (1 to 12);
|
||||
|
||||
signal tx_reg : UNSIGNED(19 downto 0);
|
||||
signal last_slot, ssync : STD_LOGIC;
|
||||
|
||||
type sac_t is (ac_idle, ac_tag, ac_data);
|
||||
signal sac, snac : sac_t;
|
||||
|
||||
subtype bitcnt_t is integer range 0 to 19;
|
||||
subtype slotcnt_t is integer range 0 to 12;
|
||||
|
||||
signal bitcnt : bitcnt_t;
|
||||
signal bitcnt_rst, bitcnt_en : STD_LOGIC;
|
||||
signal slotcnt : slotcnt_t;
|
||||
signal slotcnt_rst, slotcnt_en : STD_LOGIC;
|
||||
|
||||
signal slot_start : STD_LOGIC;
|
||||
|
||||
------------------------------------------------------------------
|
||||
function CreateTag(slot_valid : slot_valid_t) return tag_t is
|
||||
variable tag : tag_t := (others => '0');
|
||||
begin
|
||||
|
||||
tag := (others => '0');
|
||||
for i in slot_valid_t'range loop
|
||||
tag(15-i) := slot_valid(i);
|
||||
if slot_valid(i) = '1' then
|
||||
tag(15) := '1';
|
||||
end if;
|
||||
end loop;
|
||||
tag(0) := '0'; -- ID0
|
||||
tag(1) := '0'; -- ID1
|
||||
tag(2) := '0'; -- Reserved
|
||||
-- tag(15) := '1'; -- Frame is valid
|
||||
return tag;
|
||||
|
||||
end CreateTag;
|
||||
|
||||
begin
|
||||
|
||||
------------------------------------------------------------------
|
||||
proc_slot_reg:
|
||||
process (clk, cmd_addr, cmd_data, cmd_we, pcm_in_data, pcm_in_we, pcm_in_addr, last_slot)
|
||||
variable slot_id : integer range 0 to 12;
|
||||
begin
|
||||
slot_id := to_integer(pcm_in_addr);
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' then
|
||||
for i in data_array'range(1) loop
|
||||
data_array(i) <= (others => '0');
|
||||
end loop;
|
||||
slot_valid <= (others => '0');
|
||||
elsif last_slot = '1' then
|
||||
slot_valid <= (others => '0');
|
||||
else
|
||||
if cmd_we = '1' then
|
||||
slot_valid(1) <= '1';
|
||||
slot_valid(2) <= '1';
|
||||
data_array(1) <= cmd_addr;
|
||||
data_array(2) <= cmd_data;
|
||||
end if;
|
||||
if pcm_in_we = '1' then
|
||||
if (slot_id > 2) then
|
||||
data_array(slot_id) <= pcm_in_data;
|
||||
slot_valid(slot_id) <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-------------------------------------------------------------
|
||||
-- proc_slot_count
|
||||
-------------------------------------------------------------
|
||||
proc_slot_count:
|
||||
process (slotcnt_rst, ac_bit_clk, slotcnt_en, slotcnt)
|
||||
begin
|
||||
if rising_edge(ac_bit_clk) then
|
||||
if slotcnt_rst = '1' then
|
||||
slotcnt <= slotcnt_t'low;
|
||||
elsif slotcnt_en = '1' then
|
||||
if slotcnt /= slotcnt_t'high then
|
||||
slotcnt <= slotcnt + 1;
|
||||
else
|
||||
slotcnt <= slotcnt_t'low;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
------------------------------------------------------------------
|
||||
-- proc_bit_count
|
||||
------------------------------------------------------------------
|
||||
proc_bit_count:
|
||||
process (bitcnt_rst, ac_bit_clk, bitcnt_en, bitcnt)
|
||||
begin
|
||||
if rising_edge(ac_bit_clk) then
|
||||
if bitcnt_rst = '1' then
|
||||
bitcnt <= bitcnt_t'low;
|
||||
elsif bitcnt_en = '1' then
|
||||
if bitcnt /= bitcnt_t'high then
|
||||
bitcnt <= bitcnt + 1;
|
||||
else
|
||||
bitcnt <= bitcnt_t'low;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
|
||||
------------------------------------------------------------------
|
||||
proc_ac_fsm:
|
||||
process (bitcnt, slotcnt, sac)
|
||||
begin
|
||||
snac <= sac;
|
||||
bitcnt_rst <= '0';
|
||||
bitcnt_en <= '1';
|
||||
slotcnt_rst <= '0';
|
||||
slotcnt_en <= '0';
|
||||
slot_start <= '0';
|
||||
ssync <= '0';
|
||||
|
||||
if bitcnt = 0 then
|
||||
slot_start <= '1';
|
||||
end if;
|
||||
|
||||
case sac is
|
||||
|
||||
when ac_idle =>
|
||||
bitcnt_rst <= '1';
|
||||
slotcnt_rst <= '1';
|
||||
snac <= ac_tag;
|
||||
|
||||
when ac_tag =>
|
||||
ssync <= '1';
|
||||
if (bitcnt = 15) then
|
||||
slotcnt_en <= '1';
|
||||
bitcnt_rst <= '1';
|
||||
snac <= ac_data;
|
||||
end if;
|
||||
|
||||
when ac_data =>
|
||||
if bitcnt = 19 then
|
||||
slotcnt_en <= '1';
|
||||
if slotcnt = 12 then
|
||||
slotcnt_rst <= '1';
|
||||
snac <= ac_tag;
|
||||
end if;
|
||||
end if;
|
||||
when others => null;
|
||||
end case;
|
||||
end process;
|
||||
|
||||
proc_ac_fsm_next:
|
||||
process (ac_reset, ac_bit_clk, snac)
|
||||
begin
|
||||
if ac_reset = '1' then
|
||||
sac <= ac_idle;
|
||||
elsif rising_edge(ac_bit_clk) then
|
||||
sac <= snac;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
------------------------------------------------------------------
|
||||
proc_tx_shift_reg:
|
||||
process (ac_reset, ac_bit_clk, tx_reg, ssync, slot_valid, data_array)
|
||||
begin
|
||||
|
||||
if ac_reset = '1' then
|
||||
tx_reg <= (others => '0');
|
||||
elsif rising_edge(ac_bit_clk) then
|
||||
last_slot <= '0';
|
||||
if slot_start = '1' then
|
||||
if ssync = '1' then
|
||||
tx_reg <= CreateTag(slot_valid) & "0000";
|
||||
else
|
||||
if slotcnt /= 0 then
|
||||
tx_reg <= data_array(slotcnt);
|
||||
if slotcnt = 12 then
|
||||
last_slot <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
else
|
||||
tx_reg <= tx_reg(tx_reg'left-1 downto 0) & '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
------------------------------------------------------------------
|
||||
proc_ac_sync_out:
|
||||
process (ac_reset, ac_bit_clk, ssync, tx_reg)
|
||||
begin
|
||||
if ac_reset = '1' then
|
||||
ac_ssync <= '0';
|
||||
ac_sdata_out <= '0';
|
||||
elsif rising_edge(ac_bit_clk) then
|
||||
ac_ssync <= ssync;
|
||||
ac_sdata_out <= tx_reg(tx_reg'left);
|
||||
end if;
|
||||
end process;
|
||||
|
||||
------------------------------------------------------------------
|
||||
singleshot_inst1: singleshot
|
||||
GENERIC MAP (
|
||||
mode => 0)
|
||||
PORT MAP(
|
||||
rst => rst,
|
||||
clk => clk,
|
||||
input => last_slot,
|
||||
output => sync_tx
|
||||
@@ -0,0 +1,153 @@
|
||||
--------------------------------------------------------------------------------
|
||||
-- Company:
|
||||
-- Engineer:
|
||||
--
|
||||
-- Create Date: 21:52:19 10/22/05
|
||||
-- Design Name:
|
||||
-- Module Name: singleshot - Behavioral
|
||||
-- Project Name:
|
||||
-- Target Device:
|
||||
-- Tool versions:
|
||||
-- Description:
|
||||
--
|
||||
-- Dependencies:
|
||||
--
|
||||
-- Revision:
|
||||
-- Revision 0.01 - File Created
|
||||
-- Additional Comments:
|
||||
--
|
||||
--------------------------------------------------------------------------------
|
||||
-- Component Template
|
||||
--
|
||||
-- COMPONENT singleshot
|
||||
-- GENERIC (mode : integer);
|
||||
-- PORT(
|
||||
-- rst : IN std_logic;
|
||||
-- clk : IN std_logic;
|
||||
-- input : IN std_logic;
|
||||
-- output : OUT std_logic
|
||||
-- );
|
||||
-- END COMPONENT;
|
||||
--
|
||||
-- Instantation Template
|
||||
--
|
||||
-- singleshot_int: oneshot
|
||||
-- GENERIC MAP (
|
||||
-- mode => 1)
|
||||
-- PORT MAP(
|
||||
-- rst => ,
|
||||
-- clk => ,
|
||||
-- input => ,
|
||||
-- output =>
|
||||
-- );
|
||||
--
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
entity singleshot is
|
||||
Generic ( mode : integer range 0 to 2 := 1);
|
||||
Port ( rst : in std_logic;
|
||||
clk : in std_logic;
|
||||
input : in std_logic;
|
||||
output : out std_logic);
|
||||
end singleshot;
|
||||
|
||||
architecture Behavioral of singleshot is
|
||||
|
||||
type s_t is (idle, shot_in, active, shot_out);
|
||||
signal s, sn : s_t;
|
||||
|
||||
begin
|
||||
|
||||
process (rst, clk, sn)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' then
|
||||
s <= idle;
|
||||
else
|
||||
s <= sn;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
mode_1:
|
||||
if mode = 1 generate
|
||||
begin
|
||||
process (input, s)
|
||||
begin
|
||||
output <= '0';
|
||||
sn <= s;
|
||||
case s is
|
||||
when idle =>
|
||||
if input = '1' then
|
||||
sn <= shot_in;
|
||||
end if;
|
||||
when shot_in =>
|
||||
output <= '1';
|
||||
sn <= active;
|
||||
when active =>
|
||||
if input = '0' then
|
||||
sn <= shot_out;
|
||||
end if;
|
||||
when shot_out =>
|
||||
sn <= idle;
|
||||
when others => null;
|
||||
end case;
|
||||
end process;
|
||||
end generate;
|
||||
|
||||
mode_0:
|
||||
if mode = 0 generate
|
||||
begin
|
||||
process (input, s)
|
||||
begin
|
||||
output <= '0';
|
||||
sn <= s;
|
||||
case s is
|
||||
when idle =>
|
||||
if input = '1' then
|
||||
sn <= shot_in;
|
||||
end if;
|
||||
when shot_in =>
|
||||
sn <= active;
|
||||
when active =>
|
||||
if input = '0' then
|
||||
sn <= shot_out;
|
||||
end if;
|
||||
when shot_out =>
|
||||
output <= '1';
|
||||
sn <= idle;
|
||||
when others => null;
|
||||
end case;
|
||||
end process;
|
||||
end generate;
|
||||
|
||||
mode_2:
|
||||
if mode = 2 generate
|
||||
begin
|
||||
process (input, s)
|
||||
begin
|
||||
output <= '0';
|
||||
sn <= s;
|
||||
case s is
|
||||
when idle =>
|
||||
if input = '1' then
|
||||
sn <= shot_in;
|
||||
end if;
|
||||
when shot_in =>
|
||||
output <= '1';
|
||||
sn <= active;
|
||||
when active =>
|
||||
if input = '0' then
|
||||
sn <= shot_out;
|
||||
end if;
|
||||
when shot_out =>
|
||||
output <= '1';
|
||||
sn <= idle;
|
||||
when others => null;
|
||||
end case;
|
||||
end process;
|
||||
end generate;
|
||||
|
||||
end Behavioral;
|
||||
Binary file not shown.
@@ -0,0 +1,107 @@
|
||||
-------------------------------------------------------------------------
|
||||
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||
-- This file: cpu_embedded using cpu_core and rom
|
||||
|
||||
-- Copyright (C) 2007 J. Ahrensfeld
|
||||
|
||||
-- This library is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU Lesser General Public
|
||||
-- License as published by the Free Software Foundation; either
|
||||
-- version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
-- This library is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
-- Lesser General Public License for more details.
|
||||
|
||||
-- You should have received a copy of the GNU Lesser General Public
|
||||
-- License along with this library; if not, write to the Free Software
|
||||
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.numeric_std.ALL;
|
||||
|
||||
use work.cpu_pkg.all;
|
||||
|
||||
entity cpu_embedded is
|
||||
Port (
|
||||
rst : in STD_LOGIC;
|
||||
clk : in STD_LOGIC;
|
||||
ce : in STD_LOGIC;
|
||||
int_in : in STD_LOGIC;
|
||||
int_ack : out STD_LOGIC;
|
||||
xmem_we : out STD_LOGIC;
|
||||
xmem_re : out STD_LOGIC;
|
||||
xmem_din : in unsigned (DMEM_DATA_WIDTH-1 downto 0);
|
||||
xmem_dout : out unsigned (DMEM_DATA_WIDTH-1 downto 0);
|
||||
xmem_addr : out unsigned (DMEM_ADDR_WIDTH-1 downto 0);
|
||||
io_sel : out STD_LOGIC
|
||||
);
|
||||
end cpu_embedded;
|
||||
|
||||
architecture rtl of cpu_embedded is
|
||||
|
||||
signal rom_data : unsigned (IMEM_DATA_WIDTH-1 downto 0);
|
||||
signal rom_addr : unsigned (IMEM_ADDR_WIDTH-1 downto 0);
|
||||
|
||||
COMPONENT cpu
|
||||
Port (
|
||||
rst : in STD_LOGIC;
|
||||
clk : in STD_LOGIC;
|
||||
ce : in STD_LOGIC;
|
||||
int_in : in STD_LOGIC;
|
||||
int_ack : out STD_LOGIC;
|
||||
xmem_we : out STD_LOGIC;
|
||||
xmem_re : out STD_LOGIC;
|
||||
instr_din : in unsigned (IMEM_DATA_WIDTH-1 downto 0);
|
||||
instr_addr : out unsigned (IMEM_ADDR_WIDTH-1 downto 0);
|
||||
xmem_din : in unsigned (DMEM_DATA_WIDTH-1 downto 0);
|
||||
xmem_dout : out unsigned (DMEM_DATA_WIDTH-1 downto 0);
|
||||
xmem_addr : out unsigned (DMEM_DATA_WIDTH-1 downto 0);
|
||||
io_sel : out STD_LOGIC
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
|
||||
COMPONENT irom
|
||||
Port (
|
||||
clk : in STD_LOGIC;
|
||||
ce : in STD_LOGIC;
|
||||
addr : in inst_addr_t;
|
||||
dout : out inst_t
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
begin
|
||||
|
||||
inst_cpu: cpu
|
||||
PORT MAP(
|
||||
rst => rst,
|
||||
clk => clk,
|
||||
ce => ce,
|
||||
int_in => int_in,
|
||||
int_ack => int_ack,
|
||||
xmem_we => xmem_we,
|
||||
xmem_re => xmem_re,
|
||||
instr_din => rom_data,
|
||||
instr_addr => rom_addr,
|
||||
xmem_din => xmem_din,
|
||||
xmem_dout => xmem_dout,
|
||||
xmem_addr => xmem_addr,
|
||||
io_sel => io_sel
|
||||
);
|
||||
|
||||
inst_irom: irom
|
||||
PORT MAP(
|
||||
clk => clk,
|
||||
ce => ce,
|
||||
addr => rom_addr,
|
||||
dout => rom_data
|
||||
);
|
||||
|
||||
end rtl;
|
||||
@@ -0,0 +1,854 @@
|
||||
--------------------------------------------------------------------------
|
||||
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||
-- This file: Types, constants and functions for JCPU
|
||||
--
|
||||
-- Copyright (C) 2007 J. Ahrensfeld
|
||||
--
|
||||
-- This program is free software: you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation, either version 3 of the License, or
|
||||
-- (at your option) any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
--
|
||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.numeric_std.ALL;
|
||||
|
||||
|
||||
package cpu_pkg is
|
||||
|
||||
-- Revision of the CPU
|
||||
constant REVISION : integer := 2;
|
||||
|
||||
-- Chipram depth (can be tweaked)
|
||||
constant CHIPRAM_SIZE_BITS : integer := 10;
|
||||
|
||||
-- Chipregister file depth
|
||||
constant CHIPREG_SIZE_BITS : integer := 8;
|
||||
|
||||
-- Number of registers (can be tweaked)
|
||||
constant REG_SIZE_BITS : integer := 4;
|
||||
|
||||
-- Instruction memory
|
||||
constant IMEM_ADDR_WIDTH : integer := 12;
|
||||
|
||||
-- Data memory
|
||||
constant DMEM_DATA_WIDTH : integer := 8;
|
||||
constant DMEM_ADDR_WIDTH : integer := 8;
|
||||
|
||||
-- Instruction format
|
||||
constant INST_OPCODE_WIDTH : integer := 6;
|
||||
constant IMEM_DATA_WIDTH : integer := INST_OPCODE_WIDTH + DMEM_DATA_WIDTH + REG_SIZE_BITS;
|
||||
|
||||
-- Microcode ROM
|
||||
constant MUCODE_ADDR_WIDTH : integer := 9;
|
||||
|
||||
-- Stack depth
|
||||
constant STACK_SIZE_BITS : integer := CHIPRAM_SIZE_BITS-1;
|
||||
|
||||
--Types
|
||||
subtype iphase_t is integer range 0 to 1;
|
||||
type mem_access_t is (cmem_access, xmem_access, cio_access, xio_access);
|
||||
type reg_src_t is (alu_src, stk_src, cmem_src, xmem_src);
|
||||
type alu_src_t is (reg_a, reg_b, const);
|
||||
type ddata_src_t is (reg_a, reg_b, const);
|
||||
type daddr_src_t is (reg_a, reg_b, const);
|
||||
subtype instr_name_t is string(1 to 12);
|
||||
type instr_name_array_t is array (0 to 63) of instr_name_t;
|
||||
subtype opcode_t is unsigned (INST_OPCODE_WIDTH-1 downto 0);
|
||||
subtype inst_data_t is unsigned (IMEM_ADDR_WIDTH-1 downto 0);
|
||||
subtype inst_addr_t is unsigned (IMEM_ADDR_WIDTH-1 downto 0);
|
||||
subtype inst_t is unsigned (IMEM_DATA_WIDTH-1 downto 0);
|
||||
subtype dmem_data_t is unsigned (DMEM_DATA_WIDTH-1 downto 0);
|
||||
subtype dmem_addr_t is unsigned (DMEM_DATA_WIDTH-1 downto 0);
|
||||
subtype reg_ptr_t is unsigned (3 downto 0);
|
||||
type dmem_array_t is array (natural range <>) of dmem_data_t;
|
||||
type instr_addr_array is array (integer range <>) of inst_addr_t;
|
||||
subtype page_sel_t is unsigned (CHIPRAM_SIZE_BITS-DMEM_DATA_WIDTH-2 downto 0);
|
||||
|
||||
type alu_op_t is
|
||||
(
|
||||
pass_op2,
|
||||
op1_add_op2,
|
||||
op1_sub_op2,
|
||||
op1_addc_op2,
|
||||
op1_subc_op2,
|
||||
op1_and_op2,
|
||||
op1_or_op2,
|
||||
op1_xor_op2,
|
||||
swap_op,
|
||||
shl_op,
|
||||
shr_op,
|
||||
rol_op,
|
||||
ror_op,
|
||||
rolc_op,
|
||||
rorc_op
|
||||
);
|
||||
|
||||
type alu_status_t is record
|
||||
zero : STD_LOGIC;
|
||||
carry : STD_LOGIC;
|
||||
end record;
|
||||
|
||||
type cpu_status_t is record
|
||||
alu : alu_status_t;
|
||||
end record;
|
||||
|
||||
type ctrl_lines_t is record
|
||||
reg_we : STD_LOGIC;
|
||||
reg_src_sel : reg_src_t;
|
||||
alu_op1_src_sel : alu_src_t;
|
||||
alu_op2_src_sel : alu_src_t;
|
||||
alu_opsel : alu_op_t;
|
||||
alu_load : STD_LOGIC;
|
||||
ddata_src_sel : ddata_src_t;
|
||||
daddr_src_sel : daddr_src_t;
|
||||
pc_load : STD_LOGIC;
|
||||
pc_inc : STD_LOGIC;
|
||||
stk_push : STD_LOGIC;
|
||||
stk_pop : STD_LOGIC;
|
||||
stk_pushd : STD_LOGIC;
|
||||
stk_popd : STD_LOGIC;
|
||||
mem_access : mem_access_t;
|
||||
mem_read : STD_LOGIC;
|
||||
mem_write : STD_LOGIC;
|
||||
int_exit : STD_LOGIC;
|
||||
end record;
|
||||
|
||||
type dpath_ctrl_out_t is record
|
||||
lines : ctrl_lines_t;
|
||||
reg_a_ptr : reg_ptr_t;
|
||||
reg_b_ptr : reg_ptr_t;
|
||||
end record;
|
||||
|
||||
type int_ctrl_in_t is record
|
||||
enable : std_logic;
|
||||
polarity : std_logic;
|
||||
edge_sens : std_logic;
|
||||
request : std_logic;
|
||||
end record;
|
||||
|
||||
type creg_ctrl_out_t is record
|
||||
page_sel : page_sel_t;
|
||||
int_ctrl : int_ctrl_in_t;
|
||||
stk_high : unsigned(IMEM_ADDR_WIDTH-DMEM_ADDR_WIDTH-1 downto 0);
|
||||
cmem_high : unsigned(IMEM_ADDR_WIDTH-DMEM_ADDR_WIDTH-1 downto 0);
|
||||
end record;
|
||||
|
||||
type creg_ctrl_in_t is record
|
||||
alu : alu_status_t;
|
||||
end record;
|
||||
|
||||
|
||||
type murom_t is array (0 to integer(2**MUCODE_ADDR_WIDTH)-1) of ctrl_lines_t;
|
||||
|
||||
constant instr_name_array : instr_name_array_t :=
|
||||
(
|
||||
"NOP ", -- 00
|
||||
"HALT ", -- 01
|
||||
"MOV|R|R ", -- 02
|
||||
"MOV|R|K ", -- 03
|
||||
"MOVX|R|Ri ", -- 04
|
||||
"MOVX|R|Ki ", -- 05
|
||||
"MOVX|Ri|R ", -- 06
|
||||
"MOVX|Ri|K ", -- 07
|
||||
"MOVX|Ki|R ", -- 08
|
||||
"MOVC|R|Ri ", -- 09
|
||||
"MOVC|R|Ki ", -- 0A
|
||||
"MOVC|Ri|R ", -- 0B
|
||||
"MOVC|Ri|K ", -- 0C
|
||||
"MOVC|Ki|R ", -- 0D
|
||||
"CMP|R|R ", -- 0E
|
||||
"CMP|R|K ", -- 0F
|
||||
"ADD|R|R ", -- 10
|
||||
"ADD|R|K ", -- 11
|
||||
"ADDC|R|R ", -- 12
|
||||
"ADDC|R|K ", -- 13
|
||||
"SUB|R|R ", -- 14
|
||||
"SUB|R|K ", -- 15
|
||||
"SUBC|R|R ", -- 16
|
||||
"SUBC|R|K ", -- 17
|
||||
"AND|R|R ", -- 18
|
||||
"AND|R|K ", -- 19
|
||||
"OR|R|R ", -- 1A
|
||||
"OR|R|K ", -- 1B
|
||||
"XOR|R|R ", -- 1C
|
||||
"XOR|R|K ", -- 1D
|
||||
"SHL|R ", -- 1E
|
||||
"SHR|R ", -- 1F
|
||||
"ROL|R ", -- 20
|
||||
"ROR|R ", -- 21
|
||||
"ROLC|R ", -- 22
|
||||
"RORC|R ", -- 23
|
||||
"XOUT|Ki|R ", -- 24
|
||||
"XOUT|Ri|K ", -- 25
|
||||
"COUT|Ki|R ", -- 26
|
||||
"COUT|Ri|K ", -- 27
|
||||
"XIN|R|Ki ", -- 28
|
||||
"CIN|R|Ki ", -- 29
|
||||
"SWAP|R ", -- 2A
|
||||
"UNDEF ", -- 2B
|
||||
"UNDEF ", -- 2C
|
||||
"UNDEF ", -- 2D
|
||||
"SUB|K|R ", -- 2E
|
||||
"SUBC|K|R ", -- 2F
|
||||
"JMP|K ", -- 30
|
||||
"JZ|K ", -- 31
|
||||
"JNZ|K ", -- 32
|
||||
"JC|K ", -- 33
|
||||
"JNC|K ", -- 34
|
||||
"JLT|K ", -- 35
|
||||
"JGT|K ", -- 36
|
||||
"JLE|K ", -- 37
|
||||
"JGE|K ", -- 38
|
||||
"JEQ|K ", -- 39
|
||||
"JNE|K ", -- 3A
|
||||
"CALL|K ", -- 3B
|
||||
"PUSH|R ", -- 3C
|
||||
"POP|R ", -- 3D
|
||||
"RET ", -- 3E
|
||||
"RETI " -- 3F
|
||||
);
|
||||
-- Functions
|
||||
function Instr(opcode : opcode_t) return inst_t;
|
||||
function Instr(opcode : opcode_t; data : inst_data_t) return inst_t;
|
||||
function Instr(opcode : opcode_t; data : inst_data_t; reg : integer) return inst_t;
|
||||
function Instr(opcode : opcode_t; reg_a : integer) return inst_t;
|
||||
function Instr(opcode : opcode_t; reg_a, reg_b : integer) return inst_t;
|
||||
function Instr(opcode : opcode_t; reg_a, reg_b, reg_c : integer) return inst_t;
|
||||
function ctrl_lines_default return ctrl_lines_t;
|
||||
function idecoder(instr_name : instr_name_t; iphase : iphase_t; alu_status : alu_status_t) return ctrl_lines_t;
|
||||
function idecoder(opcode : opcode_t; iphase : iphase_t; alu_status : alu_status_t) return ctrl_lines_t;
|
||||
function gen_murom return murom_t;
|
||||
function get_muromaddr (opcode : opcode_t; iphase : iphase_t; alu_status : alu_status_t) return unsigned;
|
||||
function MIN (X, Y: INTEGER) return INTEGER;
|
||||
function MAX (X, Y: INTEGER) return INTEGER;
|
||||
|
||||
end cpu_pkg;
|
||||
|
||||
package body cpu_pkg is
|
||||
|
||||
function Instr(opcode : opcode_t) return inst_t is
|
||||
variable inst : inst_t := (others => '0');
|
||||
begin
|
||||
inst(inst_t'length-1 downto inst_t'length-opcode_t'length) := opcode;
|
||||
return inst;
|
||||
|
||||
end Instr;
|
||||
|
||||
function Instr(opcode : opcode_t; data : inst_data_t) return inst_t is
|
||||
variable inst : inst_t := (others => '0');
|
||||
begin
|
||||
inst(inst_t'length-1 downto inst_t'length-opcode_t'length) := opcode;
|
||||
inst(inst_t'length-opcode_t'length-1 downto inst_t'length-opcode_t'length-inst_addr_t'length) := data;
|
||||
return inst;
|
||||
|
||||
end Instr;
|
||||
|
||||
function Instr(opcode : opcode_t; data : inst_data_t; reg : integer) return inst_t is
|
||||
variable inst : inst_t := (others => '0');
|
||||
begin
|
||||
inst(inst_t'length-1 downto inst_t'length-opcode_t'length) := opcode;
|
||||
inst(inst_t'length-opcode_t'length-1 downto inst_t'length-opcode_t'length-inst_data_t'length) := data;
|
||||
inst(reg_ptr_t'length-1 downto 0) := reg_ptr_t(to_unsigned(reg, reg_ptr_t'length));
|
||||
|
||||
return inst;
|
||||
|
||||
end Instr;
|
||||
|
||||
function Instr(opcode : opcode_t; reg_a : integer) return inst_t is
|
||||
variable inst : inst_t := (others => '0');
|
||||
begin
|
||||
inst(inst_t'length-1 downto inst_t'length-opcode_t'length) := opcode;
|
||||
inst(reg_ptr_t'length-1 downto 0) := reg_ptr_t(to_unsigned(reg_a, reg_ptr_t'length));
|
||||
|
||||
return inst;
|
||||
|
||||
end Instr;
|
||||
|
||||
function Instr(opcode : opcode_t; reg_a, reg_b : integer) return inst_t is
|
||||
variable inst : inst_t := (others => '0');
|
||||
begin
|
||||
inst(inst_t'length-1 downto inst_t'length-opcode_t'length) := opcode;
|
||||
inst(2*(reg_ptr_t'length)-1 downto reg_ptr_t'length) := reg_ptr_t(to_unsigned(reg_b, reg_ptr_t'length));
|
||||
inst(reg_ptr_t'length-1 downto 0) := reg_ptr_t(to_unsigned(reg_a, reg_ptr_t'length));
|
||||
|
||||
return inst;
|
||||
|
||||
end Instr;
|
||||
|
||||
function Instr(opcode : opcode_t; reg_a, reg_b, reg_c : integer) return inst_t is
|
||||
variable inst : inst_t := (others => '0');
|
||||
begin
|
||||
inst(inst_t'length-1 downto inst_t'length-opcode_t'length) := opcode;
|
||||
inst(3*(reg_ptr_t'length)-1 downto 2*reg_ptr_t'length) := reg_ptr_t(to_unsigned(reg_c, reg_ptr_t'length));
|
||||
inst(2*(reg_ptr_t'length)-1 downto reg_ptr_t'length) := reg_ptr_t(to_unsigned(reg_b, reg_ptr_t'length));
|
||||
inst(reg_ptr_t'length-1 downto 0) := reg_ptr_t(to_unsigned(reg_a, reg_ptr_t'length));
|
||||
|
||||
return inst;
|
||||
|
||||
end Instr;
|
||||
|
||||
function ctrl_lines_default return ctrl_lines_t is
|
||||
variable result : ctrl_lines_t;
|
||||
begin
|
||||
result.pc_load := '0';
|
||||
result.pc_inc := '0';
|
||||
result.stk_push := '0';
|
||||
result.stk_pop := '0';
|
||||
result.stk_pushd := '0';
|
||||
result.stk_popd := '0';
|
||||
result.reg_we := '0';
|
||||
result.reg_src_sel := alu_src;
|
||||
result.ddata_src_sel := reg_a;
|
||||
result.daddr_src_sel := reg_b;
|
||||
result.alu_opsel := pass_op2;
|
||||
result.alu_op1_src_sel := reg_a;
|
||||
result.alu_op2_src_sel := reg_b;
|
||||
result.alu_load := '0';
|
||||
result.mem_access := cmem_access;
|
||||
result.mem_read := '0';
|
||||
result.mem_write := '0';
|
||||
result.int_exit := '0';
|
||||
return result;
|
||||
|
||||
end ctrl_lines_default;
|
||||
|
||||
function idecoder(opcode : opcode_t; iphase : iphase_t; alu_status : alu_status_t) return ctrl_lines_t is
|
||||
variable instr_name : instr_name_t;
|
||||
begin
|
||||
instr_name := instr_name_array(to_integer(opcode));
|
||||
return idecoder(instr_name, iphase, alu_status);
|
||||
end idecoder;
|
||||
|
||||
function idecoder(instr_name : instr_name_t; iphase : iphase_t; alu_status : alu_status_t) return ctrl_lines_t is
|
||||
variable result : ctrl_lines_t;
|
||||
variable ze, cy : STD_LOGIC;
|
||||
|
||||
begin
|
||||
ze := alu_status.zero;
|
||||
cy := alu_status.carry;
|
||||
|
||||
result := ctrl_lines_default;
|
||||
if iphase = 0 then
|
||||
result.pc_inc := '1';
|
||||
end if;
|
||||
|
||||
case instr_name is
|
||||
|
||||
when "HALT " =>
|
||||
result.pc_inc := '0';
|
||||
when "MOV|R|R " => -- R(a) <= R(b)
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_opsel := pass_op2;
|
||||
result.alu_op2_src_sel := reg_b;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "MOV|R|K " => -- R(a) <= #kk
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_opsel := pass_op2;
|
||||
result.alu_op2_src_sel := const;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "MOVC|Ri|R " => -- [R(b)] <= R(a)
|
||||
result.mem_access := cmem_access;
|
||||
result.daddr_src_sel := reg_b;
|
||||
result.ddata_src_sel := reg_a;
|
||||
if iphase = 0 then
|
||||
result.mem_write := '1';
|
||||
end if;
|
||||
when "MOVC|Ri|K " => -- [R(a)] <= kk
|
||||
result.mem_access := cmem_access;
|
||||
result.daddr_src_sel := reg_a;
|
||||
result.ddata_src_sel := const;
|
||||
if iphase = 0 then
|
||||
result.mem_write := '1';
|
||||
end if;
|
||||
when "COUT|Ri|K " => -- [R(a)] <= kk
|
||||
result.mem_access := cio_access;
|
||||
result.daddr_src_sel := reg_a;
|
||||
result.ddata_src_sel := const;
|
||||
if iphase = 0 then
|
||||
result.mem_write := '1';
|
||||
end if;
|
||||
when "MOVC|R|Ri " => -- R(a) <= [R(b)]
|
||||
result.mem_access := cmem_access;
|
||||
result.reg_src_sel := cmem_src;
|
||||
result.daddr_src_sel := reg_b;
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "MOVC|R|Ki " => -- R(a) <= [#addr]
|
||||
result.mem_access := cmem_access;
|
||||
result.reg_src_sel := cmem_src;
|
||||
result.daddr_src_sel := const;
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "CIN|R|Ki " => -- R(a) <= [#addr]
|
||||
result.mem_access := cio_access;
|
||||
result.reg_src_sel := cmem_src;
|
||||
result.daddr_src_sel := const;
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "MOVC|Ki|R " => -- [#addr] <= R(a)
|
||||
result.mem_access := cmem_access;
|
||||
result.daddr_src_sel := const;
|
||||
result.ddata_src_sel := reg_a;
|
||||
if iphase = 0 then
|
||||
result.mem_write := '1';
|
||||
end if;
|
||||
when "COUT|Ki|R " => -- [#addr] <= R(a)
|
||||
result.mem_access := cio_access;
|
||||
result.daddr_src_sel := const;
|
||||
result.ddata_src_sel := reg_a;
|
||||
if iphase = 0 then
|
||||
result.mem_write := '1';
|
||||
end if;
|
||||
when "MOVX|Ri|R " => -- [R(b)] <= R(a)
|
||||
result.mem_access := xmem_access;
|
||||
result.daddr_src_sel := reg_b;
|
||||
result.ddata_src_sel := reg_a;
|
||||
if iphase = 0 then
|
||||
result.mem_write := '1';
|
||||
end if;
|
||||
when "MOVX|Ri|K " => -- [R(a)] <= kk
|
||||
result.mem_access := xmem_access;
|
||||
result.daddr_src_sel := reg_a;
|
||||
result.ddata_src_sel := const;
|
||||
if iphase = 0 then
|
||||
result.mem_write := '1';
|
||||
end if;
|
||||
when "XOUT|Ri|K " => -- [R(a)] <= kk
|
||||
result.mem_access := xio_access;
|
||||
result.daddr_src_sel := reg_a;
|
||||
result.ddata_src_sel := const;
|
||||
if iphase = 0 then
|
||||
result.mem_write := '1';
|
||||
end if;
|
||||
when "MOVX|R|Ri " => -- R(a) <= [R(b)]
|
||||
result.mem_access := xmem_access;
|
||||
result.reg_src_sel := xmem_src;
|
||||
result.daddr_src_sel := reg_b;
|
||||
if iphase = 0 then
|
||||
result.mem_read := '1';
|
||||
elsif iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "MOVX|R|Ki " => -- R(a) <= [#addr]
|
||||
result.mem_access := xmem_access;
|
||||
result.reg_src_sel := xmem_src;
|
||||
result.daddr_src_sel := const;
|
||||
if iphase = 0 then
|
||||
result.mem_read := '1';
|
||||
elsif iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "XIN|R|Ki " => -- R(a) <= [#addr]
|
||||
result.mem_access := xio_access;
|
||||
result.reg_src_sel := xmem_src;
|
||||
result.daddr_src_sel := const;
|
||||
if iphase = 0 then
|
||||
result.mem_read := '1';
|
||||
elsif iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "MOVX|Ki|R " => -- [#addr] <= R(a)
|
||||
result.mem_access := xmem_access;
|
||||
result.daddr_src_sel := const;
|
||||
result.ddata_src_sel := reg_a;
|
||||
if iphase = 0 then
|
||||
result.mem_write := '1';
|
||||
end if;
|
||||
when "XOUT|Ki|R " => -- [#addr] <= R(a)
|
||||
result.mem_access := xio_access;
|
||||
result.daddr_src_sel := const;
|
||||
result.ddata_src_sel := reg_a;
|
||||
if iphase = 0 then
|
||||
result.mem_write := '1';
|
||||
end if;
|
||||
when "ADD|R|R " => -- R(a) <= R(a) + R(b)
|
||||
result.alu_opsel := op1_add_op2;
|
||||
result.alu_op1_src_sel := reg_a;
|
||||
result.alu_op2_src_sel := reg_b;
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "ADD|R|K " => -- R(a) <= R(a) + k
|
||||
result.alu_opsel := op1_add_op2;
|
||||
result.alu_op1_src_sel := reg_a;
|
||||
result.alu_op2_src_sel := const;
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "ADDC|R|R " => -- R(a) <= R(a) + R(b)
|
||||
result.alu_opsel := op1_addc_op2;
|
||||
result.alu_op1_src_sel := reg_a;
|
||||
result.alu_op2_src_sel := reg_b;
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "ADDC|R|K " => -- R(a) <= R(a) + k
|
||||
result.alu_opsel := op1_addc_op2;
|
||||
result.alu_op1_src_sel := reg_a;
|
||||
result.alu_op2_src_sel := const;
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "SUB|R|R " => -- R(a) <= R(a) + R(b)
|
||||
result.alu_opsel := op1_sub_op2;
|
||||
result.alu_op1_src_sel := reg_a;
|
||||
result.alu_op2_src_sel := reg_b;
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "SUB|R|K " => -- R(a) <= R(a) + k
|
||||
result.alu_opsel := op1_sub_op2;
|
||||
result.alu_op1_src_sel := reg_a;
|
||||
result.alu_op2_src_sel := const;
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "SUB|K|R " => -- R(a) <= k - R(a)
|
||||
result.alu_opsel := op1_sub_op2;
|
||||
result.alu_op1_src_sel := const;
|
||||
result.alu_op2_src_sel := reg_a;
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "SUBC|R|R " => -- R(a) <= R(a) + R(b)
|
||||
result.alu_opsel := op1_subc_op2;
|
||||
result.alu_op1_src_sel := reg_a;
|
||||
result.alu_op2_src_sel := reg_b;
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "SUBC|R|K " => -- R(a) <= R(a) + k
|
||||
result.alu_opsel := op1_subc_op2;
|
||||
result.alu_op1_src_sel := reg_a;
|
||||
result.alu_op2_src_sel := const;
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "SUBC|K|R " => -- R(a) <= K - R(a)
|
||||
result.alu_opsel := op1_subc_op2;
|
||||
result.alu_op1_src_sel := const;
|
||||
result.alu_op2_src_sel := reg_a;
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "AND|R|R " => -- R(a) <= R(a) and R(b)
|
||||
result.alu_opsel := op1_and_op2;
|
||||
result.alu_op1_src_sel := reg_a;
|
||||
result.alu_op2_src_sel := reg_b;
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "AND|R|K " => -- R(a) <= R(a) and k
|
||||
result.alu_opsel := op1_and_op2;
|
||||
result.alu_op1_src_sel := reg_a;
|
||||
result.alu_op2_src_sel := const;
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "OR|R|R " => -- R(a) <= R(a) or R(b)
|
||||
result.alu_opsel := op1_or_op2;
|
||||
result.alu_op1_src_sel := reg_a;
|
||||
result.alu_op2_src_sel := reg_b;
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "OR|R|K " => -- R(a) <= R(a) or R(b)
|
||||
result.alu_opsel := op1_or_op2;
|
||||
result.alu_op1_src_sel := reg_a;
|
||||
result.alu_op2_src_sel := const;
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "XOR|R|R " => -- R(a) <= R(a) xor R(b)
|
||||
result.alu_opsel := op1_xor_op2;
|
||||
result.alu_op1_src_sel := reg_a;
|
||||
result.alu_op2_src_sel := reg_b;
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "XOR|R|K " => -- R(a) <= R(a) xor R(b)
|
||||
result.alu_opsel := op1_xor_op2;
|
||||
result.alu_op1_src_sel := reg_a;
|
||||
result.alu_op2_src_sel := const;
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "SWAP|R " => -- R(a) <= R(b)
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_opsel := swap_op;
|
||||
result.alu_op1_src_sel := reg_a;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "SHL|R " => -- R(a) <= R(a) xor R(b)
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_opsel := shl_op;
|
||||
result.alu_op1_src_sel := reg_a;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "SHR|R " => -- R(a) <= R(a) xor R(b)
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_opsel := shr_op;
|
||||
result.alu_op1_src_sel := reg_a;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "ROL|R " => -- R(a) <= R(a) xor R(b)
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_opsel := rol_op;
|
||||
result.alu_op1_src_sel := reg_a;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "ROR|R " => -- R(a) <= R(a) xor R(b)
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_opsel := ror_op;
|
||||
result.alu_op1_src_sel := reg_a;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "ROLC|R " => -- R(a) <= R(a) xor R(b)
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_opsel := rolc_op;
|
||||
result.alu_op1_src_sel := reg_a;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "RORC|R " => -- R(a) <= R(a) xor R(b)
|
||||
result.reg_src_sel := alu_src;
|
||||
result.alu_opsel := rorc_op;
|
||||
result.alu_op1_src_sel := reg_a;
|
||||
result.alu_load := '1';
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "CMP|R|R " => --
|
||||
result.alu_opsel := op1_sub_op2;
|
||||
result.alu_op1_src_sel := reg_a;
|
||||
result.alu_op2_src_sel := reg_b;
|
||||
result.alu_load := '1';
|
||||
when "CMP|R|K " => --
|
||||
result.alu_opsel := op1_sub_op2;
|
||||
result.alu_op1_src_sel := reg_a;
|
||||
result.alu_op2_src_sel := const;
|
||||
result.alu_load := '1';
|
||||
when "JMP|K " => -- PC <= #addr
|
||||
if iphase = 0 then
|
||||
result.pc_load := '1';
|
||||
end if;
|
||||
when "JZ|K " => -- PC <= #addr, zero
|
||||
if iphase = 0 then
|
||||
if ze = '1' then
|
||||
result.pc_load := '1';
|
||||
end if;
|
||||
end if;
|
||||
when "JNZ|K " => -- PC <= #addr, !zero
|
||||
if iphase = 0 then
|
||||
if ze = '0' then
|
||||
result.pc_load := '1';
|
||||
end if;
|
||||
end if;
|
||||
when "JC|K " => -- PC <= #addr, carry
|
||||
if iphase = 0 then
|
||||
if cy = '1' then
|
||||
result.pc_load := '1';
|
||||
end if;
|
||||
end if;
|
||||
when "JNC|K " => -- PC <= #addr, !carry
|
||||
if iphase = 0 then
|
||||
if cy = '0' then
|
||||
result.pc_load := '1';
|
||||
end if;
|
||||
end if;
|
||||
when "JLT|K " => -- PC <= #addr, !carry
|
||||
if iphase = 0 then
|
||||
if cy = '1' then
|
||||
result.pc_load := '1';
|
||||
end if;
|
||||
end if;
|
||||
when "JGT|K " => --
|
||||
if iphase = 0 then
|
||||
if (cy or ze) = '0' then
|
||||
result.pc_load := '1';
|
||||
end if;
|
||||
end if;
|
||||
when "JLE|K " => --
|
||||
if iphase = 0 then
|
||||
if (cy xor ze) = '1' then
|
||||
result.pc_load := '1';
|
||||
end if;
|
||||
end if;
|
||||
when "JGE|K " => --
|
||||
if iphase = 0 then
|
||||
if (not cy or ze) = '1' then
|
||||
result.pc_load := '1';
|
||||
end if;
|
||||
end if;
|
||||
when "JEQ|K " => --
|
||||
if iphase = 0 then
|
||||
if ze = '1' then
|
||||
result.pc_load := '1';
|
||||
end if;
|
||||
end if;
|
||||
when "JNE|K " => --
|
||||
if iphase = 0 then
|
||||
if ze = '0' then
|
||||
result.pc_load := '1';
|
||||
end if;
|
||||
end if;
|
||||
when "PUSH|R " => -- push
|
||||
if iphase = 0 then
|
||||
result.stk_pushd := '1';
|
||||
end if;
|
||||
when "POP|R " => -- pop
|
||||
result.reg_src_sel := stk_src;
|
||||
if iphase = 0 then
|
||||
result.stk_popd := '1';
|
||||
elsif iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
when "CALL|K " => -- call
|
||||
if iphase = 0 then
|
||||
result.pc_load := '1';
|
||||
result.stk_push := '1';
|
||||
end if;
|
||||
when "RET " => -- return
|
||||
if iphase = 0 then
|
||||
result.pc_load := '1';
|
||||
result.stk_pop := '1';
|
||||
end if;
|
||||
when "RETI " => -- return
|
||||
result.pc_inc := '0';
|
||||
result.int_exit := '1';
|
||||
|
||||
when others => null; -- nop
|
||||
end case;
|
||||
|
||||
return result;
|
||||
|
||||
end idecoder;
|
||||
|
||||
function gen_murom return murom_t is
|
||||
variable result : murom_t;
|
||||
variable opcode : opcode_t;
|
||||
variable iphase : iphase_t;
|
||||
variable addr : unsigned(MUCODE_ADDR_WIDTH-1 downto 0);
|
||||
variable alu_status : alu_status_t;
|
||||
variable pos : integer := 0;
|
||||
|
||||
begin
|
||||
for i in 0 to 2**addr'length-1 loop
|
||||
addr := to_unsigned(i, addr'length);
|
||||
opcode := addr(opcode'length-1 downto 0);
|
||||
pos := opcode'length;
|
||||
iphase := 0;
|
||||
if addr(pos) = '1' then
|
||||
iphase := 1;
|
||||
end if;
|
||||
pos := pos + 1;
|
||||
alu_status.zero := addr(pos);
|
||||
pos := pos + 1;
|
||||
alu_status.carry := addr(pos);
|
||||
|
||||
result(i) := idecoder(opcode, iphase, alu_status);
|
||||
end loop;
|
||||
|
||||
return result;
|
||||
end gen_murom;
|
||||
|
||||
function get_muromaddr (opcode : opcode_t; iphase : iphase_t; alu_status : alu_status_t) return unsigned is
|
||||
variable addr : unsigned(MUCODE_ADDR_WIDTH-1 downto 0);
|
||||
begin
|
||||
addr := alu_status.carry & alu_status.zero & to_unsigned(iphase, 1) & opcode;
|
||||
return addr;
|
||||
|
||||
end get_muromaddr;
|
||||
|
||||
-------------------------------------------------------------
|
||||
function MIN (X, Y: INTEGER) return INTEGER is
|
||||
variable res : integer := X;
|
||||
begin
|
||||
if Y < X then
|
||||
res := Y;
|
||||
end if;
|
||||
|
||||
return res;
|
||||
|
||||
end MIN;
|
||||
|
||||
-------------------------------------------------------------
|
||||
function MAX (X, Y: INTEGER) return INTEGER is
|
||||
variable res : integer := X;
|
||||
begin
|
||||
if Y > X then
|
||||
res := Y;
|
||||
end if;
|
||||
|
||||
return res;
|
||||
|
||||
end MAX;
|
||||
|
||||
|
||||
end cpu_pkg;
|
||||
|
||||
@@ -0,0 +1,999 @@
|
||||
----------------------------------------------------------------------------------
|
||||
-- Company:
|
||||
-- Engineer:
|
||||
--
|
||||
-- Create Date: 11:30:30 08/27/2006
|
||||
-- Design Name:
|
||||
-- Module Name: ac97_test - Behavioral
|
||||
-- Project Name:
|
||||
-- Target Devices:
|
||||
-- Tool versions:
|
||||
-- Description:
|
||||
--
|
||||
-- Dependencies:
|
||||
--
|
||||
-- Revision:
|
||||
-- Revision 0.01 - File Created
|
||||
-- Additional Comments:
|
||||
--
|
||||
----------------------------------------------------------------------------------
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
use work.tech_iface.all;
|
||||
use work.key_schedule_iface.all;
|
||||
use work.engine_iface.all;
|
||||
|
||||
use work.ecb_mode_iface.all;
|
||||
use work.ecb_core_iface.all;
|
||||
|
||||
use work.cbc_mode_iface.all;
|
||||
use work.cbc_core_iface.all;
|
||||
|
||||
use work.cpu_pkg.all;
|
||||
|
||||
---- Uncomment the following library declaration if instantiating
|
||||
---- any Xilinx primitives in this code.
|
||||
library UNISIM;
|
||||
use UNISIM.VComponents.all;
|
||||
|
||||
entity messe_demo is
|
||||
Port (
|
||||
sys_rst_n_in : in std_logic;
|
||||
sys_clk_in : in std_logic;
|
||||
sys_btn : in std_logic_vector(4 downto 0);
|
||||
-- sys_dip : in std_logic_vector(7 downto 0);
|
||||
sys_led : out std_logic_vector(8 downto 0);
|
||||
sys_rx : in std_logic;
|
||||
sys_tx : out std_logic;
|
||||
sys_lcd_d : inout std_logic_vector(3 downto 0);
|
||||
sys_lcd_e : out std_logic;
|
||||
sys_lcd_rs : out std_logic;
|
||||
sys_lcd_rw : out std_logic;
|
||||
ac97_bit_clk : in STD_LOGIC;
|
||||
ac97_sdata_in : in STD_LOGIC;
|
||||
ac97_reset_n : out STD_LOGIC;
|
||||
ac97_sdata_out : out STD_LOGIC;
|
||||
ac97_sync : out STD_LOGIC
|
||||
);
|
||||
end messe_demo;
|
||||
|
||||
architecture Behavioral of messe_demo is
|
||||
|
||||
constant fa : REAL := 48.0E3;
|
||||
|
||||
type stereo_t is (left, right);
|
||||
type pcm_data_t is array (stereo_t) of signed(17 downto 0);
|
||||
type stereo_bits_t is array (stereo_t) of std_logic;
|
||||
type pcm_block_t is array (0 to 7) of unsigned(15 downto 0);
|
||||
signal plain_block_in : pcm_block_t;
|
||||
signal ecb_block_out : pcm_block_t;
|
||||
signal cbc_block_out : pcm_block_t;
|
||||
signal encrypt_audio : std_logic;
|
||||
|
||||
------------------------------------------------------------------
|
||||
COMPONENT singleshot
|
||||
GENERIC (mode : integer);
|
||||
PORT(
|
||||
rst : IN std_logic;
|
||||
clk : IN std_logic;
|
||||
input : IN std_logic;
|
||||
output : OUT std_logic
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
COMPONENT ac_io
|
||||
Port (
|
||||
rst : in std_logic;
|
||||
clk : in std_logic;
|
||||
ready : out std_logic;
|
||||
sync_strobe : out unsigned(0 to 2);
|
||||
slot_valid : out unsigned(0 to 12);
|
||||
stat_addr : out unsigned (19 downto 0);
|
||||
stat_data : out unsigned (19 downto 0);
|
||||
rx_pcm_addr : in unsigned (3 downto 0);
|
||||
rx_pcm_data : out unsigned (19 downto 0);
|
||||
cmd_addr : in unsigned(19 downto 0);
|
||||
cmd_data : in unsigned(19 downto 0);
|
||||
cmd_we : in std_logic;
|
||||
tx_pcm_addr : in unsigned(3 downto 0);
|
||||
tx_pcm_data : in unsigned(19 downto 0);
|
||||
tx_pcm_we : in std_logic;
|
||||
ac_sdata_in : in std_logic;
|
||||
ac_bit_clk : in std_logic;
|
||||
ac_reset_n : out std_logic;
|
||||
ac_sdata_out : out std_logic;
|
||||
ac_ssync : out std_logic
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
SIGNAL sync_strobe : unsigned(0 to 2);
|
||||
SIGNAL slot_valid : unsigned(0 to 12);
|
||||
SIGNAL cmd_we : std_logic;
|
||||
SIGNAL cmd_addr : unsigned(19 downto 0);
|
||||
SIGNAL cmd_data : unsigned(19 downto 0);
|
||||
SIGNAL stat_addr : unsigned(19 downto 0);
|
||||
SIGNAL stat_data : unsigned(19 downto 0);
|
||||
SIGNAL tx_pcm_addr : unsigned(3 downto 0);
|
||||
SIGNAL tx_pcm_data : unsigned(19 downto 0);
|
||||
SIGNAL rx_pcm_addr : unsigned(3 downto 0);
|
||||
SIGNAL tx_pcm_we : std_logic;
|
||||
SIGNAL rx_pcm_data : unsigned(19 downto 0);
|
||||
|
||||
COMPONENT cpu_embedded
|
||||
Port (
|
||||
rst : in STD_LOGIC;
|
||||
clk : in STD_LOGIC;
|
||||
ce : in STD_LOGIC;
|
||||
int_in : in STD_LOGIC;
|
||||
int_ack : out STD_LOGIC;
|
||||
xmem_we : out STD_LOGIC;
|
||||
xmem_re : out STD_LOGIC;
|
||||
xmem_din : in unsigned (DMEM_DATA_WIDTH-1 downto 0);
|
||||
xmem_dout : out unsigned (DMEM_DATA_WIDTH-1 downto 0);
|
||||
xmem_addr : out unsigned (DMEM_ADDR_WIDTH-1 downto 0);
|
||||
io_sel : out STD_LOGIC
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
signal cpu_ce : std_logic;
|
||||
signal cpu_int_in : std_logic;
|
||||
signal cpu_int_ack : std_logic;
|
||||
signal cpu_din : dmem_data_t;
|
||||
signal cpu_dout : dmem_data_t;
|
||||
signal cpu_addr : dmem_addr_t;
|
||||
signal cpu_we : std_logic;
|
||||
signal cpu_re : std_logic;
|
||||
signal cpu_io_sel : std_logic;
|
||||
|
||||
COMPONENT xrom
|
||||
Port (
|
||||
clk : in STD_LOGIC;
|
||||
ce : in STD_LOGIC;
|
||||
addr : in dmem_addr_t;
|
||||
dout : out dmem_data_t
|
||||
);
|
||||
END COMPONENT;
|
||||
signal xrom_data : dmem_data_t;
|
||||
|
||||
COMPONENT lcd_port
|
||||
PORT (
|
||||
rst : in std_logic;
|
||||
clk : in std_logic;
|
||||
we : in std_logic;
|
||||
din : in unsigned(7 downto 0);
|
||||
dout : out unsigned(7 downto 0);
|
||||
lcd_d : inout std_logic_vector(3 downto 0);
|
||||
lcd_e : out std_logic;
|
||||
lcd_rs : out std_logic;
|
||||
lcd_rw : out std_logic
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
signal cpu_lcd_in_reg, cpu_lcd_out_reg : unsigned(DMEM_DATA_WIDTH-1 downto 0);
|
||||
signal cpu_lcd_we : std_logic;
|
||||
|
||||
------------------------------------------------------------------
|
||||
-- X"1F400", -- W: DAC rate 8000Hz
|
||||
-- X"AC440", -- W: DAC rate 44100Hz
|
||||
------------------------------------------------------------------
|
||||
|
||||
type state_t is (st_reset, st_pcm_in, st_pcm_in3, st_pcm_in4, st_pcm_out, st_pcm_out3, st_pcm_out4);
|
||||
type enc_state_t is
|
||||
(
|
||||
enc_init,
|
||||
enc_keyload0, enc_keyload1, enc_keyload2, enc_keyload3,
|
||||
enc_ivload0, enc_ivload1, enc_ivload2, enc_ivload3,
|
||||
enc_wait_block,
|
||||
enc_block_in0, enc_block_in1, enc_block_in2, enc_block_in3);
|
||||
|
||||
signal ecb_state, ecb_state_next : enc_state_t;
|
||||
signal cbc_state, cbc_state_next : enc_state_t;
|
||||
|
||||
signal rst, clk : std_logic;
|
||||
signal acio_ready : std_logic;
|
||||
signal pcm_active : std_logic;
|
||||
signal state, nextstate : state_t;
|
||||
signal ac_reset_n : std_logic;
|
||||
signal ac_rst : std_logic;
|
||||
signal ac_ssync : std_logic;
|
||||
signal pcm_request, pcm_request_set, pcm_request_ack : std_logic;
|
||||
signal started_up : std_logic := '1';
|
||||
signal cpu_cmd_addr, cpu_cmd_data, cpu_stat_addr, cpu_stat_data : unsigned(15 downto 0);
|
||||
signal cpu_pcmin_dc_adj_left, cpu_pcmin_dc_adj_right : unsigned(15 downto 0);
|
||||
|
||||
|
||||
subtype low is unsigned(7 downto 0);
|
||||
subtype high is unsigned(15 downto 8);
|
||||
|
||||
signal pcm_in_data : pcm_data_t;
|
||||
signal pcm_out_data : pcm_data_t;
|
||||
|
||||
signal pcm_in_data_we, pcm_in_valid : stereo_bits_t;
|
||||
|
||||
type pcmout_mode_t is (PCMOUT_PASSTHROUGH, PCMOUT_CIPHER_ECB, PCMOUT_CIPHER_CBC);
|
||||
signal pcmout_mode : pcmout_mode_t;
|
||||
signal cpu_cmd_access, cpu_cmd_ready, cpu_stat_ready : std_logic;
|
||||
signal cpu_led_reg, cpu_btn_reg, cpu_dip_reg, cpu_pcmmode_reg : unsigned(DMEM_DATA_WIDTH-1 downto 0);
|
||||
signal cpu_cmd_we : std_logic;
|
||||
|
||||
------------------------------------------------------------------
|
||||
constant KEY_ID1 : key_id_t := std_logic_vector(to_unsigned(0, key_id_t'length));
|
||||
|
||||
signal ecb_mode_i : ecb_mode_encryption_in_type; -- see package ecb_mode_iface
|
||||
signal ecb_mode_o : ecb_mode_encryption_out_type; -- see package ecb_mode_iface
|
||||
signal ecb_key_i : key_schedule_128_in_type; -- see package key_schedule_iface
|
||||
signal ecb_key_o : key_schedule_128_out_type; -- see package key_schedule_iface
|
||||
signal ecb_sbld_i : sbox_stage_load_in_type; -- see package tech_iface
|
||||
signal ecb_cipher_pcm : unsigned(17 downto 0);
|
||||
|
||||
signal cbc_mode_i : cbc_mode_encryption_in_type; -- see package cbc_mode_iface
|
||||
signal cbc_mode_o : cbc_mode_encryption_out_type; -- see package cbc_mode_iface
|
||||
signal cbc_key_i : key_schedule_128_in_type; -- see package key_schedule_iface
|
||||
signal cbc_key_o : key_schedule_128_out_type; -- see package key_schedule_iface
|
||||
signal cbc_sbld_i : sbox_stage_load_in_type; -- see package tech_iface
|
||||
signal cbc_cipher_pcm : unsigned(17 downto 0);
|
||||
|
||||
signal plain_block_in_rdy : std_logic;
|
||||
signal encryption_constant_plain : unsigned(15 downto 0);
|
||||
|
||||
------------------------------------------------------------------
|
||||
function GetRequest(slot1 : unsigned) return unsigned is
|
||||
variable res : unsigned(3 to 12);
|
||||
begin
|
||||
res := (others => '0');
|
||||
for i in res'range loop
|
||||
res(i) := not slot1(14-i);
|
||||
end loop;
|
||||
return res;
|
||||
|
||||
end GetRequest;
|
||||
|
||||
begin
|
||||
|
||||
------------------------------------------------------------------
|
||||
cmd_data <= (cpu_cmd_data & "0000");
|
||||
cmd_addr <= (cpu_cmd_addr & "0000");
|
||||
|
||||
ac_rst <= not ac_reset_n;
|
||||
ac97_reset_n <= ac_reset_n;
|
||||
ac97_sync <= ac_ssync;
|
||||
|
||||
sys_tx <= sys_rx;
|
||||
|
||||
cpu_ce <= '1';
|
||||
clk <= sys_clk_in;
|
||||
rst <= not (started_up and sys_rst_n_in);
|
||||
-- rst <= not (sys_rst_n_in);
|
||||
|
||||
cpu_int_in <= sync_strobe(0);
|
||||
|
||||
------------------------------------------------------------------
|
||||
proc_led_btn:
|
||||
process (rst, clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
cpu_btn_reg <= "000" & unsigned(sys_btn);
|
||||
-- cpu_dip_reg <= unsigned(sys_dip);
|
||||
cpu_dip_reg <= (others => '0'); -- for FX12 (ML-403)
|
||||
if rst = '1' then
|
||||
sys_led <= (others => '0');
|
||||
else
|
||||
sys_led(7 downto 0) <= STD_LOGIC_VECTOR(cpu_led_reg);
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
------------------------------------------------------------------
|
||||
ecb_fsm: process(ecb_state, plain_block_in_rdy, ecb_mode_i, ecb_key_i, plain_block_in)
|
||||
begin
|
||||
ecb_state_next <= ecb_state;
|
||||
|
||||
ecb_mode_i.start <= '0';
|
||||
ecb_mode_i.plain <= (others => '0');
|
||||
ecb_mode_i.key_id <= KEY_ID1;
|
||||
ecb_key_i.load_key <= '0';
|
||||
ecb_key_i.key_id <= KEY_ID1;
|
||||
ecb_key_i.key <= (others => '0');
|
||||
|
||||
ecb_sbld_i.act <= '0';
|
||||
ecb_sbld_i.wen <= '0';
|
||||
|
||||
case ecb_state is
|
||||
when enc_init =>
|
||||
if ecb_key_o.busy = '0' then
|
||||
ecb_state_next <= enc_keyload0;
|
||||
end if;
|
||||
|
||||
when enc_keyload0 =>
|
||||
ecb_key_i.load_key <= '1';
|
||||
ecb_key_i.key <= X"2b7e1516";
|
||||
ecb_state_next <= enc_keyload1;
|
||||
when enc_keyload1 =>
|
||||
ecb_key_i.key <= X"28aed2a6";
|
||||
ecb_state_next <= enc_keyload2;
|
||||
when enc_keyload2 =>
|
||||
ecb_key_i.key <= X"abf71588";
|
||||
ecb_state_next <= enc_keyload3;
|
||||
when enc_keyload3 =>
|
||||
ecb_key_i.key <= X"09cf4f3c";
|
||||
if ecb_key_o.busy = '0' then
|
||||
ecb_state_next <= enc_wait_block;
|
||||
end if;
|
||||
|
||||
when enc_wait_block =>
|
||||
if plain_block_in_rdy = '1' then
|
||||
ecb_state_next <= enc_block_in0;
|
||||
end if;
|
||||
|
||||
when enc_block_in0 =>
|
||||
ecb_mode_i.start <= '1';
|
||||
ecb_mode_i.plain <= std_logic_vector(plain_block_in(1)) & std_logic_vector(plain_block_in(0));
|
||||
ecb_state_next <= enc_block_in1;
|
||||
when enc_block_in1 =>
|
||||
ecb_mode_i.plain <= std_logic_vector(plain_block_in(3)) & std_logic_vector(plain_block_in(2));
|
||||
ecb_state_next <= enc_block_in2;
|
||||
when enc_block_in2 =>
|
||||
ecb_mode_i.plain <= std_logic_vector(plain_block_in(5)) & std_logic_vector(plain_block_in(4));
|
||||
ecb_state_next <= enc_block_in3;
|
||||
when enc_block_in3 =>
|
||||
ecb_mode_i.plain <= std_logic_vector(plain_block_in(7)) & std_logic_vector(plain_block_in(6));
|
||||
if ecb_mode_o.busy = '0' then
|
||||
ecb_state_next <= enc_wait_block;
|
||||
end if;
|
||||
|
||||
when others =>
|
||||
ecb_state_next <= enc_init;
|
||||
|
||||
end case;
|
||||
end process;
|
||||
|
||||
proc_ecb_fsm_next:
|
||||
process (rst, clk)
|
||||
begin
|
||||
if rst = '1' then
|
||||
ecb_state <= enc_init;
|
||||
elsif rising_edge(clk) then
|
||||
ecb_state <= ecb_state_next;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
------------------------------------------------------------------
|
||||
cbc_fsm: process(cbc_state, plain_block_in_rdy, cbc_mode_i, cbc_key_i, plain_block_in)
|
||||
begin
|
||||
cbc_state_next <= cbc_state;
|
||||
|
||||
cbc_mode_i.start <= '0';
|
||||
cbc_mode_i.din <= (others => '0');
|
||||
cbc_mode_i.key_id <= KEY_ID1;
|
||||
cbc_mode_i.load_iv <= '0';
|
||||
|
||||
cbc_key_i.key <= (others => '0');
|
||||
cbc_key_i.key_id <= KEY_ID1;
|
||||
cbc_key_i.load_key <= '0';
|
||||
|
||||
cbc_sbld_i.act <= '0';
|
||||
cbc_sbld_i.wen <= '0';
|
||||
|
||||
case cbc_state is
|
||||
when enc_init =>
|
||||
if cbc_key_o.busy = '0' then
|
||||
cbc_state_next <= enc_keyload0;
|
||||
end if;
|
||||
|
||||
when enc_keyload0 =>
|
||||
cbc_key_i.load_key <= '1';
|
||||
cbc_key_i.key <= X"2b7e1516";
|
||||
cbc_state_next <= enc_keyload1;
|
||||
when enc_keyload1 =>
|
||||
cbc_key_i.key <= X"28aed2a6";
|
||||
cbc_state_next <= enc_keyload2;
|
||||
when enc_keyload2 =>
|
||||
cbc_key_i.key <= X"abf71588";
|
||||
cbc_state_next <= enc_keyload3;
|
||||
when enc_keyload3 =>
|
||||
cbc_key_i.key <= X"09cf4f3c";
|
||||
if cbc_key_o.busy = '0' then
|
||||
cbc_state_next <= enc_ivload0;
|
||||
end if;
|
||||
|
||||
when enc_ivload0 =>
|
||||
cbc_mode_i.load_iv <= '1';
|
||||
cbc_mode_i.din <= X"00010203";
|
||||
cbc_state_next <= enc_ivload1;
|
||||
when enc_ivload1 =>
|
||||
cbc_mode_i.din <= X"04050607";
|
||||
cbc_state_next <= enc_ivload2;
|
||||
when enc_ivload2 =>
|
||||
cbc_mode_i.din <= X"08090a0b";
|
||||
cbc_state_next <= enc_ivload3;
|
||||
when enc_ivload3 =>
|
||||
cbc_mode_i.din <= X"0c0d0e0f";
|
||||
if cbc_mode_o.busy = '0' then
|
||||
cbc_state_next <= enc_wait_block;
|
||||
end if;
|
||||
|
||||
when enc_wait_block =>
|
||||
if plain_block_in_rdy = '1' then
|
||||
cbc_state_next <= enc_block_in0;
|
||||
end if;
|
||||
|
||||
when enc_block_in0 =>
|
||||
cbc_mode_i.start <= '1';
|
||||
cbc_mode_i.din <= std_logic_vector(plain_block_in(1)) & std_logic_vector(plain_block_in(0));
|
||||
cbc_state_next <= enc_block_in1;
|
||||
when enc_block_in1 =>
|
||||
cbc_mode_i.din <= std_logic_vector(plain_block_in(3)) & std_logic_vector(plain_block_in(2));
|
||||
cbc_state_next <= enc_block_in2;
|
||||
when enc_block_in2 =>
|
||||
cbc_mode_i.din <= std_logic_vector(plain_block_in(5)) & std_logic_vector(plain_block_in(4));
|
||||
cbc_state_next <= enc_block_in3;
|
||||
when enc_block_in3 =>
|
||||
cbc_mode_i.din <= std_logic_vector(plain_block_in(7)) & std_logic_vector(plain_block_in(6));
|
||||
if cbc_mode_o.busy = '0' then
|
||||
cbc_state_next <= enc_wait_block;
|
||||
end if;
|
||||
|
||||
when others =>
|
||||
cbc_state_next <= enc_wait_block;
|
||||
|
||||
end case;
|
||||
end process;
|
||||
|
||||
proc_cbc_fsm_next:
|
||||
process (rst, clk)
|
||||
begin
|
||||
if rst = '1' then
|
||||
cbc_state <= enc_init;
|
||||
elsif rising_edge(clk) then
|
||||
cbc_state <= cbc_state_next;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
------------------------------------------------------------------
|
||||
proc_plain_block_in:
|
||||
process (rst, clk)
|
||||
variable index : natural range 0 to 15;
|
||||
variable dc_adj : unsigned(15 downto 0);
|
||||
|
||||
begin
|
||||
dc_adj := unsigned(resize(signed(cpu_pcmin_dc_adj_left), dc_adj'length));
|
||||
if rst = '1' then
|
||||
index := 0;
|
||||
elsif rising_edge(clk) then
|
||||
plain_block_in_rdy <= '0';
|
||||
if pcm_in_data_we(left) = '1' then
|
||||
if encrypt_audio = '1' then
|
||||
plain_block_in(index) <= (rx_pcm_data(19 downto 4) and X"F000");
|
||||
else
|
||||
plain_block_in(index) <= encryption_constant_plain;
|
||||
end if;
|
||||
if index < 7 then
|
||||
index := index + 1;
|
||||
else
|
||||
index := 0;
|
||||
plain_block_in_rdy <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
------------------------------------------------------------------
|
||||
proc_ecb_block_out:
|
||||
process (rst, clk)
|
||||
variable index : natural range 0 to 7;
|
||||
variable write_index : natural range 0 to 7;
|
||||
variable cipher : unsigned(31 downto 0);
|
||||
begin
|
||||
if rst = '1' then
|
||||
index := 0;
|
||||
write_index := 0;
|
||||
elsif rising_edge(clk) then
|
||||
if ecb_mode_o.valid = '1' then
|
||||
cipher := unsigned(ecb_mode_o.cipher);
|
||||
ecb_block_out(write_index+0) <= cipher(15 downto 0);
|
||||
ecb_block_out(write_index+1) <= cipher(31 downto 16);
|
||||
if write_index < 6 then
|
||||
write_index := write_index + 2;
|
||||
else
|
||||
index := 0;
|
||||
write_index := 0;
|
||||
end if;
|
||||
end if;
|
||||
if pcm_request = '1' and sync_strobe(2) = '1' then
|
||||
if index < 7 then
|
||||
index := index + 1;
|
||||
else
|
||||
index := 0;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
ecb_cipher_pcm <= "00" & ecb_block_out(index);
|
||||
end process;
|
||||
|
||||
------------------------------------------------------------------
|
||||
proc_cbc_block_out:
|
||||
process (rst, clk)
|
||||
variable index : natural range 0 to 7;
|
||||
variable write_index : natural range 0 to 7;
|
||||
variable cipher : unsigned(31 downto 0);
|
||||
variable cipher_rdy : std_logic;
|
||||
begin
|
||||
if rst = '1' then
|
||||
index := 0;
|
||||
write_index := 0;
|
||||
cipher_rdy := '0';
|
||||
elsif rising_edge(clk) then
|
||||
if cbc_mode_o.valid = '1' then
|
||||
cipher := unsigned(cbc_mode_o.dout);
|
||||
cbc_block_out(write_index+0) <= cipher(15 downto 0);
|
||||
cbc_block_out(write_index+1) <= cipher(31 downto 16);
|
||||
if write_index < 6 then
|
||||
write_index := write_index + 2;
|
||||
else
|
||||
index := 0;
|
||||
write_index := 0;
|
||||
end if;
|
||||
end if;
|
||||
if pcm_request = '1' and sync_strobe(2) = '1' then
|
||||
if index < 7 then
|
||||
index := index + 1;
|
||||
else
|
||||
index := 0;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
cbc_cipher_pcm <= "00" & cbc_block_out(index);
|
||||
end process;
|
||||
|
||||
------------------------------------------------------------------
|
||||
host_din : process (acio_ready, sync_strobe, slot_valid, stat_addr, state, pcm_request, pcm_out_data)
|
||||
variable request : unsigned(3 to 12);
|
||||
variable rx_frame_valid : std_logic;
|
||||
variable sync_frame, sync_status, sync_tx : std_logic;
|
||||
|
||||
begin
|
||||
request := GetRequest(stat_addr);
|
||||
rx_frame_valid := slot_valid(0);
|
||||
sync_frame := sync_strobe(0);
|
||||
sync_status := sync_strobe(1);
|
||||
sync_tx := sync_strobe(2);
|
||||
|
||||
tx_pcm_we <= '0';
|
||||
tx_pcm_addr <= to_unsigned(3, tx_pcm_addr'length);
|
||||
tx_pcm_data <= to_unsigned(0, tx_pcm_data'length);
|
||||
|
||||
rx_pcm_addr <= to_unsigned(3, rx_pcm_addr'length);
|
||||
|
||||
nextstate <= state;
|
||||
pcm_active <= '0';
|
||||
pcm_request_set <= '0';
|
||||
pcm_request_ack <= '0';
|
||||
pcm_in_data_we <= (others => '0');
|
||||
|
||||
case state is
|
||||
|
||||
when st_reset =>
|
||||
if rx_frame_valid = '1' and sync_status = '1' and acio_ready = '1' then
|
||||
nextstate <= st_pcm_in;
|
||||
end if;
|
||||
|
||||
when st_pcm_in =>
|
||||
if rx_frame_valid = '1' and sync_frame = '1' then
|
||||
nextstate <= st_pcm_in3;
|
||||
end if;
|
||||
|
||||
when st_pcm_in3 =>
|
||||
nextstate <= st_pcm_in4;
|
||||
rx_pcm_addr <= to_unsigned(3, rx_pcm_addr'length);
|
||||
if slot_valid(3) = '1' then
|
||||
pcm_in_data_we(left) <= '1';
|
||||
end if;
|
||||
|
||||
when st_pcm_in4 =>
|
||||
nextstate <= st_pcm_out;
|
||||
rx_pcm_addr <= to_unsigned(4, rx_pcm_addr'length);
|
||||
if slot_valid(4) = '1' then
|
||||
pcm_in_data_we(right) <= '1';
|
||||
end if;
|
||||
|
||||
when st_pcm_out =>
|
||||
pcm_active <= '1';
|
||||
if rx_frame_valid = '1' and sync_status = '1' then
|
||||
if request(3) = '1' and request(4) = '1' then
|
||||
pcm_request_set <= '1';
|
||||
end if;
|
||||
end if;
|
||||
if pcm_request = '1' and sync_tx = '1' then
|
||||
nextstate <= st_pcm_out3;
|
||||
end if;
|
||||
|
||||
when st_pcm_out3 =>
|
||||
tx_pcm_data <= unsigned(pcm_out_data(left)) & "00";
|
||||
pcm_active <= '1';
|
||||
tx_pcm_addr <= to_unsigned(3, tx_pcm_addr'length);
|
||||
tx_pcm_we <= '1';
|
||||
pcm_request_ack <= '1';
|
||||
nextstate <= st_pcm_out4;
|
||||
|
||||
when st_pcm_out4 =>
|
||||
tx_pcm_data <= unsigned(pcm_out_data(right)) & "00";
|
||||
pcm_active <= '1';
|
||||
tx_pcm_addr <= to_unsigned(4, tx_pcm_addr'length);
|
||||
tx_pcm_we <= '1';
|
||||
nextstate <= st_pcm_in;
|
||||
|
||||
when others =>
|
||||
nextstate <= st_reset;
|
||||
|
||||
end case;
|
||||
|
||||
end process;
|
||||
|
||||
proc_fsm_next:
|
||||
process (rst, clk)
|
||||
begin
|
||||
if rst = '1' then
|
||||
state <= st_reset;
|
||||
elsif rising_edge(clk) then
|
||||
state <= nextstate;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-------------------------------------------------------------
|
||||
-- proc_pcm_in (stereo - for bypass)
|
||||
-------------------------------------------------------------
|
||||
proc_pcm_in:
|
||||
process (rst, clk, pcm_in_data_we, rx_pcm_data)
|
||||
variable dc_adj : pcm_data_t;
|
||||
begin
|
||||
dc_adj(left) := resize(signed(cpu_pcmin_dc_adj_left), dc_adj(left)'length);
|
||||
dc_adj(right) := resize(signed(cpu_pcmin_dc_adj_right), dc_adj(right)'length);
|
||||
|
||||
if rst = '1' then
|
||||
for i in pcm_in_data'range loop
|
||||
dc_adj(i) := (others => '0');
|
||||
pcm_in_data(i) <= (others => '0');
|
||||
pcm_in_valid(i) <= '0';
|
||||
end loop;
|
||||
elsif rising_edge(clk) then
|
||||
for i in pcm_in_data'range loop
|
||||
pcm_in_valid(i) <= '0';
|
||||
end loop;
|
||||
for i in pcm_in_data'range loop
|
||||
if pcm_in_data_we(i) = '1' then
|
||||
pcm_in_valid(i) <= '1';
|
||||
pcm_in_data(i) <= dc_adj(i) + signed(rx_pcm_data(19 downto 2));
|
||||
end if;
|
||||
end loop;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-------------------------------------------------------------
|
||||
-- proc_pcmout_mode_mapper
|
||||
-------------------------------------------------------------
|
||||
proc_pcmout_mode_mapper:
|
||||
process (cpu_pcmmode_reg)
|
||||
begin
|
||||
case cpu_pcmmode_reg is
|
||||
when X"00" =>
|
||||
pcmout_mode <= PCMOUT_PASSTHROUGH;
|
||||
when X"01" =>
|
||||
pcmout_mode <= PCMOUT_CIPHER_ECB;
|
||||
when X"02" =>
|
||||
pcmout_mode <= PCMOUT_CIPHER_CBC;
|
||||
when others =>
|
||||
pcmout_mode <= PCMOUT_PASSTHROUGH;
|
||||
end case;
|
||||
end process;
|
||||
|
||||
-------------------------------------------------------------
|
||||
-- proc_pcm_out_mux
|
||||
-------------------------------------------------------------
|
||||
proc_pcm_out_mux:
|
||||
process (clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if pcm_request = '1' and sync_strobe(2) = '1' then
|
||||
case pcmout_mode is
|
||||
when PCMOUT_PASSTHROUGH =>
|
||||
pcm_out_data(left to right) <= pcm_in_data(left to right);
|
||||
when PCMOUT_CIPHER_ECB =>
|
||||
pcm_out_data(left) <= signed(ecb_cipher_pcm);
|
||||
pcm_out_data(right) <= signed(ecb_cipher_pcm);
|
||||
when PCMOUT_CIPHER_CBC =>
|
||||
pcm_out_data(left) <= signed(cbc_cipher_pcm);
|
||||
pcm_out_data(right) <= signed(cbc_cipher_pcm);
|
||||
when others =>
|
||||
pcm_out_data(left to right) <= pcm_in_data(left to right);
|
||||
end case;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-------------------------------------------------------------
|
||||
-- proc_cpu_flags
|
||||
-------------------------------------------------------------
|
||||
proc_cpu_stat_reg_control:
|
||||
process (clk, sync_strobe, slot_valid)
|
||||
variable rx_frame_valid : std_logic;
|
||||
variable sync_frame, sync_status, sync_tx : std_logic;
|
||||
begin
|
||||
rx_frame_valid := slot_valid(0);
|
||||
sync_frame := sync_strobe(0);
|
||||
sync_status := sync_strobe(1);
|
||||
sync_tx := sync_strobe(2);
|
||||
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' then
|
||||
cpu_cmd_ready <= '0';
|
||||
cpu_stat_ready <= '0';
|
||||
cpu_stat_addr <= (others => '0');
|
||||
cpu_stat_data <= (others => '0');
|
||||
else
|
||||
cpu_cmd_we <= '0';
|
||||
if cpu_cmd_access = '1' then
|
||||
cpu_cmd_ready <= '0';
|
||||
cpu_stat_ready <= '0';
|
||||
end if;
|
||||
|
||||
if cpu_cmd_ready = '0' then
|
||||
if sync_tx = '1' then
|
||||
cpu_cmd_we <= '1';
|
||||
cpu_cmd_ready <= '1';
|
||||
end if;
|
||||
end if;
|
||||
|
||||
if sync_status = '1' and slot_valid(0 to 2) = "111" then
|
||||
cpu_stat_ready <= '1';
|
||||
cpu_stat_addr <= stat_addr(19 downto 4);
|
||||
cpu_stat_data <= stat_data(19 downto 4);
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
end process;
|
||||
|
||||
-------------------------------------------------------------
|
||||
-- proc_cpu_dout_reg
|
||||
-------------------------------------------------------------
|
||||
proc_cpu_dout_reg:
|
||||
process (clk)
|
||||
variable addr : dmem_addr_t;
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' then
|
||||
cpu_led_reg <= (others => '0');
|
||||
cpu_pcmmode_reg <= (others => '0');
|
||||
encrypt_audio <= '1';
|
||||
cpu_cmd_addr <= (others => '0');
|
||||
cpu_cmd_data <= (others => '0');
|
||||
cpu_lcd_out_reg <= (others => '0');
|
||||
cpu_pcmin_dc_adj_left <= (others => '0');
|
||||
cpu_pcmin_dc_adj_right <= (others => '0');
|
||||
encryption_constant_plain <= (others => '0');
|
||||
else
|
||||
addr := cpu_addr;
|
||||
cpu_cmd_access <= '0';
|
||||
cpu_lcd_we <= '0';
|
||||
if cpu_we = '1' and cpu_io_sel = '1' then
|
||||
case addr is
|
||||
when X"00" =>
|
||||
cpu_led_reg <= cpu_dout;
|
||||
when X"01" =>
|
||||
cpu_pcmmode_reg <= cpu_dout;
|
||||
when X"02" =>
|
||||
encrypt_audio <= cpu_dout(0);
|
||||
when X"04" =>
|
||||
cpu_cmd_addr(low'range) <= cpu_dout;
|
||||
when X"05" =>
|
||||
cpu_cmd_addr(high'range) <= cpu_dout;
|
||||
when X"06" =>
|
||||
cpu_cmd_access <= '1';
|
||||
cpu_cmd_data(low'range) <= cpu_dout;
|
||||
when X"07" =>
|
||||
cpu_cmd_data(high'range) <= cpu_dout;
|
||||
when X"08" =>
|
||||
cpu_lcd_we <= '1';
|
||||
cpu_lcd_out_reg <= cpu_dout;
|
||||
when X"0D" =>
|
||||
cpu_pcmin_dc_adj_left(low'range) <= cpu_dout;
|
||||
when X"0E" =>
|
||||
cpu_pcmin_dc_adj_left(high'range) <= cpu_dout;
|
||||
when X"0F" =>
|
||||
cpu_pcmin_dc_adj_right(low'range) <= cpu_dout;
|
||||
when X"10" =>
|
||||
cpu_pcmin_dc_adj_right(high'range) <= cpu_dout;
|
||||
when X"11" =>
|
||||
encryption_constant_plain(7 downto 0) <= cpu_dout;
|
||||
when X"12" =>
|
||||
encryption_constant_plain(15 downto 8) <= cpu_dout;
|
||||
when others => null;
|
||||
end case;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-------------------------------------------------------------
|
||||
-- proc_cpu_din_reg
|
||||
-------------------------------------------------------------
|
||||
proc_cpu_din_reg:
|
||||
process (clk, cpu_io_sel, xrom_data)
|
||||
variable addr : dmem_addr_t;
|
||||
begin
|
||||
|
||||
if rising_edge(clk) then
|
||||
addr := cpu_addr;
|
||||
end if;
|
||||
|
||||
if cpu_io_sel = '0' then
|
||||
cpu_din <= xrom_data;
|
||||
else
|
||||
case addr is
|
||||
when X"00" =>
|
||||
cpu_din <= cpu_led_reg;
|
||||
when X"01" =>
|
||||
cpu_din <= cpu_pcmmode_reg;
|
||||
when X"02" =>
|
||||
cpu_din <= "0000000" & encrypt_audio;
|
||||
when X"04" =>
|
||||
cpu_din <= cpu_stat_addr(low'range);
|
||||
when X"05" =>
|
||||
cpu_din <= cpu_stat_addr(high'range);
|
||||
when X"06" =>
|
||||
cpu_din <= cpu_stat_data(low'range);
|
||||
when X"07" =>
|
||||
cpu_din <= cpu_stat_data(high'range);
|
||||
when X"08" =>
|
||||
cpu_din <= cpu_lcd_in_reg;
|
||||
when X"0D" =>
|
||||
cpu_din <= cpu_pcmin_dc_adj_left(low'range);
|
||||
when X"0E" =>
|
||||
cpu_din <= cpu_pcmin_dc_adj_left(high'range);
|
||||
when X"0F" =>
|
||||
cpu_din <= cpu_pcmin_dc_adj_right(low'range);
|
||||
when X"10" =>
|
||||
cpu_din <= cpu_pcmin_dc_adj_right(high'range);
|
||||
when X"11" =>
|
||||
cpu_din <= encryption_constant_plain(7 downto 0);
|
||||
when X"12" =>
|
||||
cpu_din <= encryption_constant_plain(15 downto 8);
|
||||
when X"80" =>
|
||||
cpu_din <= cpu_btn_reg;
|
||||
when X"81" =>
|
||||
cpu_din <= cpu_dip_reg;
|
||||
when X"82" =>
|
||||
cpu_din <= dmem_data_t(pcm_in_data(left)(low'range));
|
||||
when X"83" =>
|
||||
cpu_din <= dmem_data_t(pcm_in_data(left)(high'range));
|
||||
when X"84" =>
|
||||
cpu_din <= dmem_data_t(pcm_in_data(right)(low'range));
|
||||
when X"85" =>
|
||||
cpu_din <= dmem_data_t(pcm_in_data(right)(high'range));
|
||||
when X"A0" =>
|
||||
cpu_din <= "0000" & ecb_mode_o.busy & cpu_stat_ready & cpu_cmd_ready & (pcm_active and acio_ready and slot_valid(0));
|
||||
when others =>
|
||||
if addr(0) = '0' then
|
||||
cpu_din <= X"EF";
|
||||
else
|
||||
cpu_din <= X"BE";
|
||||
end if;
|
||||
end case;
|
||||
end if;
|
||||
|
||||
end process;
|
||||
-------------------------------------------------------------
|
||||
proc_pcm_request:
|
||||
process (clk, pcm_request_set, pcm_request_ack)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if pcm_request_ack = '1' or rst = '1' then
|
||||
pcm_request <= '0';
|
||||
elsif pcm_request_set = '1' then
|
||||
pcm_request <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
------------------------------------------------------------------
|
||||
-- Instantiate the Unit Under Test (UUT)
|
||||
inst_ac_io: ac_io PORT MAP(
|
||||
rst => rst,
|
||||
clk => clk,
|
||||
ready => acio_ready,
|
||||
sync_strobe => sync_strobe,
|
||||
slot_valid => slot_valid,
|
||||
stat_addr => stat_addr,
|
||||
stat_data => stat_data,
|
||||
rx_pcm_addr => rx_pcm_addr,
|
||||
rx_pcm_data => rx_pcm_data,
|
||||
cmd_addr => cmd_addr,
|
||||
cmd_data => cmd_data,
|
||||
cmd_we => cpu_cmd_we,
|
||||
tx_pcm_addr => tx_pcm_addr,
|
||||
tx_pcm_data => tx_pcm_data,
|
||||
tx_pcm_we => tx_pcm_we,
|
||||
ac_sdata_in => ac97_sdata_in,
|
||||
ac_bit_clk => ac97_bit_clk,
|
||||
ac_reset_n => ac_reset_n,
|
||||
ac_sdata_out => ac97_sdata_out,
|
||||
ac_ssync => ac_ssync
|
||||
);
|
||||
|
||||
inst_cpu_embedded: cpu_embedded
|
||||
PORT MAP(
|
||||
rst => rst,
|
||||
clk => clk,
|
||||
ce => cpu_ce,
|
||||
int_in => cpu_int_in,
|
||||
int_ack => cpu_int_ack,
|
||||
xmem_we => cpu_we,
|
||||
xmem_re => cpu_re,
|
||||
xmem_din => cpu_din,
|
||||
xmem_dout => cpu_dout,
|
||||
xmem_addr => cpu_addr,
|
||||
io_sel => cpu_io_sel
|
||||
);
|
||||
|
||||
inst_xrom: xrom
|
||||
PORT MAP(
|
||||
clk => clk,
|
||||
ce => cpu_ce,
|
||||
addr => cpu_addr,
|
||||
dout => xrom_data
|
||||
);
|
||||
|
||||
inst_lcd_port: lcd_port
|
||||
PORT MAP(
|
||||
rst => rst,
|
||||
clk => clk,
|
||||
we => cpu_lcd_we,
|
||||
din => cpu_lcd_out_reg,
|
||||
dout => cpu_lcd_in_reg,
|
||||
lcd_d => sys_lcd_d,
|
||||
lcd_e => sys_lcd_e,
|
||||
lcd_rs => sys_lcd_rs,
|
||||
lcd_rw => sys_lcd_rw
|
||||
);
|
||||
|
||||
inst_ecb_128_encryption_core: ecb_128_encryption_core
|
||||
port map (
|
||||
rst => rst,
|
||||
clk => clk,
|
||||
mode_i => ecb_mode_i,
|
||||
mode_o => ecb_mode_o,
|
||||
key_i => ecb_key_i,
|
||||
key_o => ecb_key_o,
|
||||
sbld_i => ecb_sbld_i
|
||||
);
|
||||
|
||||
inst_cbc_128_encryption_core: cbc_128_encryption_core
|
||||
port map (
|
||||
rst => rst,
|
||||
clk => clk,
|
||||
mode_i => cbc_mode_i,
|
||||
mode_o => cbc_mode_o,
|
||||
key_i => cbc_key_i,
|
||||
key_o => cbc_key_o,
|
||||
sbld_i => cbc_sbld_i
|
||||
);
|
||||
|
||||
------------------------------------------------------------------
|
||||
STARTUP_VIRTEX4_inst : STARTUP_VIRTEX4
|
||||
port map (
|
||||
EOS => started_up, -- End of Startup 1-bit output
|
||||
CLK => open, -- Clock input for start-up sequence
|
||||
GSR => '0', -- Global Set/Reset input (GSR cannot be used for the port name)
|
||||
GTS => '0', -- Global 3-state input (GTS cannot be used for the port name)
|
||||
USRCCLKO => '0', -- USRCCLKO 1-bit input
|
||||
USRCCLKTS => '0', -- USRCCLKTS 1-bit input
|
||||
USRDONEO => '0', -- USRDONEO 1-bit input
|
||||
USRDONETS => '0' -- USRDONETS 1-bit input
|
||||
);
|
||||
|
||||
------------------------------------------------------------------
|
||||
|
||||
end Behavioral;
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
------------------------------------------------------------------
|
||||
entity lcd_port is
|
||||
Port (
|
||||
rst : in std_logic;
|
||||
clk : in std_logic;
|
||||
we : in std_logic;
|
||||
din : in unsigned(7 downto 0);
|
||||
dout : out unsigned(7 downto 0);
|
||||
lcd_d : inout unsigned(3 downto 0);
|
||||
lcd_e : out std_logic;
|
||||
lcd_rs : out std_logic;
|
||||
lcd_rw : out std_logic
|
||||
);
|
||||
end lcd_port;
|
||||
|
||||
architecture Behavioral of lcd_port is
|
||||
|
||||
constant clcd_e : integer := 7;
|
||||
constant clcd_rs : integer := 6;
|
||||
constant clcd_rw : integer := 5;
|
||||
|
||||
type lcd_t is record
|
||||
d : unsigned(3 downto 0);
|
||||
e : std_logic;
|
||||
rs : std_logic;
|
||||
rw : std_logic;
|
||||
end record;
|
||||
|
||||
------------------------------------------------------------------
|
||||
begin
|
||||
|
||||
proc_lcd_port:
|
||||
process(rst, clk)
|
||||
variable vlcd : lcd_t;
|
||||
begin
|
||||
if (rst = '1') then
|
||||
dout <= (others => '0');
|
||||
vlcd.d := (others => '0');
|
||||
vlcd.e := '0';
|
||||
vlcd.rw := '1';
|
||||
vlcd.rs := '0';
|
||||
elsif rising_edge(clk) then
|
||||
dout <= unsigned("0000" & lcd_d);
|
||||
if we = '1' then
|
||||
vlcd.d := din(3 downto 0);
|
||||
vlcd.e := din(clcd_e);
|
||||
vlcd.rs := din(clcd_rs);
|
||||
vlcd.rw := din(clcd_rw);
|
||||
end if;
|
||||
end if;
|
||||
if vlcd.rw = '0' then
|
||||
lcd_d <= unsigned(vlcd.d);
|
||||
else
|
||||
lcd_d <= (others => 'Z');
|
||||
end if;
|
||||
lcd_e <= vlcd.e;
|
||||
lcd_rs <= vlcd.rs;
|
||||
lcd_rw <= vlcd.rw;
|
||||
end process;
|
||||
------------------------------------------------------------------
|
||||
|
||||
end Behavioral;
|
||||
@@ -0,0 +1,562 @@
|
||||
-------------------------------------------------------------------------
|
||||
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||
-- This file: The ROM file for use in your VHDL design
|
||||
--
|
||||
-- Copyright (C) 2007 J. Ahrensfeld
|
||||
--
|
||||
-- This program is free software: you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation, either version 3 of the License, or
|
||||
-- (at your option) any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
--
|
||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
LIBRARY ieee;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
USE ieee.numeric_std.ALL;
|
||||
|
||||
library work;
|
||||
use work.cpu_pkg.all;
|
||||
|
||||
-- JASM_ROM_INSERT_HERE
|
||||
ENTITY irom IS
|
||||
Port (
|
||||
clk : in STD_LOGIC;
|
||||
ce : in STD_LOGIC;
|
||||
addr : in inst_addr_t;
|
||||
dout : out inst_t
|
||||
);
|
||||
END irom;
|
||||
|
||||
ARCHITECTURE test OF irom IS
|
||||
|
||||
type imem_rom_t is array (0 to 500) of inst_t;
|
||||
|
||||
-- Assembled from test.jsm
|
||||
constant imem_rom : imem_rom_t :=
|
||||
(
|
||||
"110000" & X"002", -- 0x000: JMP 0x002
|
||||
"110000" & X"0EA", -- 0x001: JMP 0x0EA
|
||||
"000011" & X"000", -- 0x002: MOV R00, 0x00
|
||||
"000011" & X"021", -- 0x003: MOV R01, 0x02
|
||||
"001101" & X"040", -- 0x004: MOVC (0x04), R00
|
||||
"001101" & X"051", -- 0x005: MOVC (0x05), R01
|
||||
"000011" & X"000", -- 0x006: MOV R00, 0x00
|
||||
"100100" & X"000", -- 0x007: XOUT (0x00), R00
|
||||
"000011" & X"FF0", -- 0x008: MOV R00, 0xFF
|
||||
"100100" & X"110", -- 0x009: XOUT (0x11), R00
|
||||
"000011" & X"3B0", -- 0x00A: MOV R00, 0x3B
|
||||
"100100" & X"120", -- 0x00B: XOUT (0x12), R00
|
||||
"000011" & X"9C0", -- 0x00C: MOV R00, 0x9C
|
||||
"100100" & X"130", -- 0x00D: XOUT (0x13), R00
|
||||
"000011" & X"010", -- 0x00E: MOV R00, 0x01
|
||||
"100100" & X"140", -- 0x00F: XOUT (0x14), R00
|
||||
"000011" & X"000", -- 0x010: MOV R00, 0x00
|
||||
"001101" & X"080", -- 0x011: MOVC (0x08), R00
|
||||
"001101" & X"090", -- 0x012: MOVC (0x09), R00
|
||||
"000011" & X"000", -- 0x013: MOV R00, 0x00
|
||||
"001101" & X"060", -- 0x014: MOVC (0x06), R00
|
||||
"000011" & X"040", -- 0x015: MOV R00, 0x04
|
||||
"001101" & X"070", -- 0x016: MOVC (0x07), R00
|
||||
"000011" & X"0A0", -- 0x017: MOV R00, 0x0A
|
||||
"001101" & X"0A0", -- 0x018: MOVC (0x0A), R00
|
||||
"000011" & X"0C0", -- 0x019: MOV R00, 0x0C
|
||||
"001101" & X"0B0", -- 0x01A: MOVC (0x0B), R00
|
||||
"111011" & X"177", -- 0x01B: CALL 0x177
|
||||
"000011" & X"010", -- 0x01C: MOV R00, 0x01
|
||||
"111011" & X"194", -- 0x01D: CALL 0x194
|
||||
"000011" & X"001", -- 0x01E: MOV R01, 0x00
|
||||
"111011" & X"199", -- 0x01F: CALL 0x199
|
||||
"000011" & X"C00", -- 0x020: MOV R00, 0xC0
|
||||
"111011" & X"194", -- 0x021: CALL 0x194
|
||||
"000011" & X"111", -- 0x022: MOV R01, 0x11
|
||||
"111011" & X"199", -- 0x023: CALL 0x199
|
||||
"111011" & X"142", -- 0x024: CALL 0x142
|
||||
"101000" & X"A00", -- 0x025: XIN R00, (0xA0)
|
||||
"011001" & X"010", -- 0x026: AND R00, 0x01
|
||||
"110001" & X"025", -- 0x027: JZ 0x025
|
||||
"000011" & X"000", -- 0x028: MOV R00, 0x00
|
||||
"000011" & X"801", -- 0x029: MOV R01, 0x80
|
||||
"000011" & X"002", -- 0x02A: MOV R02, 0x00
|
||||
"000011" & X"003", -- 0x02B: MOV R03, 0x00
|
||||
"111011" & X"123", -- 0x02C: CALL 0x123
|
||||
"001101" & X"000", -- 0x02D: MOVC (0x00), R00
|
||||
"001101" & X"011", -- 0x02E: MOVC (0x01), R01
|
||||
"001101" & X"022", -- 0x02F: MOVC (0x02), R02
|
||||
"001101" & X"033", -- 0x030: MOVC (0x03), R03
|
||||
"000011" & X"000", -- 0x031: MOV R00, 0x00
|
||||
"000011" & X"A61", -- 0x032: MOV R01, 0xA6
|
||||
"000011" & X"002", -- 0x033: MOV R02, 0x00
|
||||
"000011" & X"003", -- 0x034: MOV R03, 0x00
|
||||
"111011" & X"123", -- 0x035: CALL 0x123
|
||||
"011001" & X"0F2", -- 0x036: AND R02, 0x0F
|
||||
"001111" & X"0F2", -- 0x037: CMP R02, 0x0F
|
||||
"111010" & X"031", -- 0x038: JNE 0x031
|
||||
"000011" & X"09F", -- 0x039: MOV R15, 0x09
|
||||
"000011" & X"A37", -- 0x03A: MOV R07, 0xA3
|
||||
"000011" & X"B58", -- 0x03B: MOV R08, 0xB5
|
||||
"000100" & X"070", -- 0x03C: MOVX R00, (R07)
|
||||
"010001" & X"017", -- 0x03D: INC R07
|
||||
"000100" & X"071", -- 0x03E: MOVX R01, (R07)
|
||||
"010001" & X"017", -- 0x03F: INC R07
|
||||
"000100" & X"082", -- 0x040: MOVX R02, (R08)
|
||||
"010001" & X"018", -- 0x041: INC R08
|
||||
"000100" & X"083", -- 0x042: MOVX R03, (R08)
|
||||
"010001" & X"018", -- 0x043: INC R08
|
||||
"111011" & X"123", -- 0x044: CALL 0x123
|
||||
"010101" & X"01F", -- 0x045: DEC R15
|
||||
"110010" & X"03C", -- 0x046: JNZ 0x03C
|
||||
"111011" & X"0A5", -- 0x047: CALL 0x0A5
|
||||
"000011" & X"FF0", -- 0x048: MOV R00, 0xFF
|
||||
"100100" & X"0E0", -- 0x049: XOUT (0x0E), R00
|
||||
"000011" & X"400", -- 0x04A: MOV R00, 0x40
|
||||
"100100" & X"0D0", -- 0x04B: XOUT (0x0D), R00
|
||||
"000011" & X"FF0", -- 0x04C: MOV R00, 0xFF
|
||||
"100100" & X"100", -- 0x04D: XOUT (0x10), R00
|
||||
"000011" & X"400", -- 0x04E: MOV R00, 0x40
|
||||
"100100" & X"0F0", -- 0x04F: XOUT (0x0F), R00
|
||||
"000011" & X"070", -- 0x050: MOV R00, 0x07
|
||||
"100110" & X"030", -- 0x051: COUT (0x03), R00
|
||||
"001010" & X"080", -- 0x052: MOVC R00, (0x08)
|
||||
"001111" & X"000", -- 0x053: TST R00
|
||||
"110010" & X"057", -- 0x054: JNZ 0x057
|
||||
"000011" & X"001", -- 0x055: MOV R01, 0x00
|
||||
"001101" & X"0C1", -- 0x056: MOVC (0x0C), R01
|
||||
"011001" & X"100", -- 0x057: AND R00, 0x10
|
||||
"110001" & X"091", -- 0x058: JZ 0x091
|
||||
"001010" & X"080", -- 0x059: MOVC R00, (0x08)
|
||||
"001111" & X"140", -- 0x05A: CMP R00, 0x14
|
||||
"111001" & X"063", -- 0x05B: JEQ 0x063
|
||||
"001111" & X"110", -- 0x05C: CMP R00, 0x11
|
||||
"111001" & X"07A", -- 0x05D: JEQ 0x07A
|
||||
"001010" & X"0C1", -- 0x05E: MOVC R01, (0x0C)
|
||||
"001111" & X"001", -- 0x05F: TST R01
|
||||
"110010" & X"052", -- 0x060: JNZ 0x052
|
||||
"111011" & X"0A5", -- 0x061: CALL 0x0A5
|
||||
"110000" & X"052", -- 0x062: JMP 0x052
|
||||
"001010" & X"0A0", -- 0x063: MOVC R00, (0x0A)
|
||||
"001111" & X"000", -- 0x064: CMP R00, 0x00
|
||||
"111001" & X"052", -- 0x065: JEQ 0x052
|
||||
"010101" & X"010", -- 0x066: DEC R00
|
||||
"001101" & X"0A0", -- 0x067: MOVC (0x0A), R00
|
||||
"111011" & X"0D6", -- 0x068: CALL 0x0D6
|
||||
"000011" & X"800", -- 0x069: MOV R00, 0x80
|
||||
"111011" & X"194", -- 0x06A: CALL 0x194
|
||||
"000011" & X"921", -- 0x06B: MOV R01, 0x92
|
||||
"111011" & X"199", -- 0x06C: CALL 0x199
|
||||
"000011" & X"800", -- 0x06D: MOV R00, 0x80
|
||||
"111011" & X"194", -- 0x06E: CALL 0x194
|
||||
"000011" & X"881", -- 0x06F: MOV R01, 0x88
|
||||
"111011" & X"199", -- 0x070: CALL 0x199
|
||||
"000011" & X"1F0", -- 0x071: MOV R00, 0x1F
|
||||
"001010" & X"0A1", -- 0x072: MOVC R01, (0x0A)
|
||||
"010100" & X"010", -- 0x073: SUB R00, R01
|
||||
"111011" & X"13D", -- 0x074: CALL 0x13D
|
||||
"111011" & X"149", -- 0x075: CALL 0x149
|
||||
"111011" & X"149", -- 0x076: CALL 0x149
|
||||
"000011" & X"010", -- 0x077: MOV R00, 0x01
|
||||
"001101" & X"0C0", -- 0x078: MOVC (0x0C), R00
|
||||
"110000" & X"052", -- 0x079: JMP 0x052
|
||||
"001010" & X"0A0", -- 0x07A: MOVC R00, (0x0A)
|
||||
"001111" & X"1F0", -- 0x07B: CMP R00, 0x1F
|
||||
"111001" & X"052", -- 0x07C: JEQ 0x052
|
||||
"010001" & X"010", -- 0x07D: INC R00
|
||||
"001101" & X"0A0", -- 0x07E: MOVC (0x0A), R00
|
||||
"111011" & X"0A5", -- 0x07F: CALL 0x0A5
|
||||
"000011" & X"800", -- 0x080: MOV R00, 0x80
|
||||
"111011" & X"194", -- 0x081: CALL 0x194
|
||||
"000011" & X"921", -- 0x082: MOV R01, 0x92
|
||||
"111011" & X"199", -- 0x083: CALL 0x199
|
||||
"000011" & X"800", -- 0x084: MOV R00, 0x80
|
||||
"111011" & X"194", -- 0x085: CALL 0x194
|
||||
"000011" & X"881", -- 0x086: MOV R01, 0x88
|
||||
"111011" & X"199", -- 0x087: CALL 0x199
|
||||
"000011" & X"1F0", -- 0x088: MOV R00, 0x1F
|
||||
"001010" & X"0A1", -- 0x089: MOVC R01, (0x0A)
|
||||
"010100" & X"010", -- 0x08A: SUB R00, R01
|
||||
"111011" & X"13D", -- 0x08B: CALL 0x13D
|
||||
"111011" & X"149", -- 0x08C: CALL 0x149
|
||||
"111011" & X"149", -- 0x08D: CALL 0x149
|
||||
"000011" & X"010", -- 0x08E: MOV R00, 0x01
|
||||
"001101" & X"0C0", -- 0x08F: MOVC (0x0C), R00
|
||||
"110000" & X"052", -- 0x090: JMP 0x052
|
||||
"001010" & X"080", -- 0x091: MOVC R00, (0x08)
|
||||
"011001" & X"090", -- 0x092: AND R00, 0x09
|
||||
"110001" & X"09B", -- 0x093: JZ 0x09B
|
||||
"000011" & X"011", -- 0x094: MOV R01, 0x01
|
||||
"011001" & X"010", -- 0x095: AND R00, 0x01
|
||||
"111010" & X"098", -- 0x096: JNE 0x098
|
||||
"000011" & X"001", -- 0x097: MOV R01, 0x00
|
||||
"100100" & X"021", -- 0x098: XOUT (0x02), R01
|
||||
"111011" & X"0B3", -- 0x099: CALL 0x0B3
|
||||
"110000" & X"052", -- 0x09A: JMP 0x052
|
||||
"001010" & X"080", -- 0x09B: MOVC R00, (0x08)
|
||||
"011001" & X"060", -- 0x09C: AND R00, 0x06
|
||||
"110001" & X"0A4", -- 0x09D: JZ 0x0A4
|
||||
"000011" & X"011", -- 0x09E: MOV R01, 0x01
|
||||
"011001" & X"040", -- 0x09F: AND R00, 0x04
|
||||
"111010" & X"0A2", -- 0x0A0: JNE 0x0A2
|
||||
"000011" & X"001", -- 0x0A1: MOV R01, 0x00
|
||||
"100100" & X"021", -- 0x0A2: XOUT (0x02), R01
|
||||
"111011" & X"0C5", -- 0x0A3: CALL 0x0C5
|
||||
"110000" & X"052", -- 0x0A4: JMP 0x052
|
||||
"000011" & X"000", -- 0x0A5: MOV R00, 0x00
|
||||
"100100" & X"010", -- 0x0A6: XOUT (0x01), R00
|
||||
"000011" & X"060", -- 0x0A7: MOV R00, 0x06
|
||||
"100100" & X"000", -- 0x0A8: XOUT (0x00), R00
|
||||
"111011" & X"0D6", -- 0x0A9: CALL 0x0D6
|
||||
"000011" & X"800", -- 0x0AA: MOV R00, 0x80
|
||||
"111011" & X"194", -- 0x0AB: CALL 0x194
|
||||
"000011" & X"221", -- 0x0AC: MOV R01, 0x22
|
||||
"111011" & X"199", -- 0x0AD: CALL 0x199
|
||||
"000011" & X"C00", -- 0x0AE: MOV R00, 0xC0
|
||||
"111011" & X"194", -- 0x0AF: CALL 0x194
|
||||
"000011" & X"331", -- 0x0B0: MOV R01, 0x33
|
||||
"111011" & X"199", -- 0x0B1: CALL 0x199
|
||||
"111110" & X"000", -- 0x0B2: RET
|
||||
"000011" & X"010", -- 0x0B3: MOV R00, 0x01
|
||||
"100100" & X"010", -- 0x0B4: XOUT (0x01), R00
|
||||
"000011" & X"080", -- 0x0B5: MOV R00, 0x08
|
||||
"100100" & X"000", -- 0x0B6: XOUT (0x00), R00
|
||||
"111011" & X"0E0", -- 0x0B7: CALL 0x0E0
|
||||
"000011" & X"800", -- 0x0B8: MOV R00, 0x80
|
||||
"111011" & X"194", -- 0x0B9: CALL 0x194
|
||||
"000011" & X"441", -- 0x0BA: MOV R01, 0x44
|
||||
"111011" & X"199", -- 0x0BB: CALL 0x199
|
||||
"000011" & X"661", -- 0x0BC: MOV R01, 0x66
|
||||
"101000" & X"020", -- 0x0BD: XIN R00, (0x02)
|
||||
"011001" & X"010", -- 0x0BE: AND R00, 0x01
|
||||
"110010" & X"0C1", -- 0x0BF: JNZ 0x0C1
|
||||
"000011" & X"771", -- 0x0C0: MOV R01, 0x77
|
||||
"000011" & X"C00", -- 0x0C1: MOV R00, 0xC0
|
||||
"111011" & X"194", -- 0x0C2: CALL 0x194
|
||||
"111011" & X"199", -- 0x0C3: CALL 0x199
|
||||
"111110" & X"000", -- 0x0C4: RET
|
||||
"000011" & X"020", -- 0x0C5: MOV R00, 0x02
|
||||
"100100" & X"010", -- 0x0C6: XOUT (0x01), R00
|
||||
"000011" & X"010", -- 0x0C7: MOV R00, 0x01
|
||||
"100100" & X"000", -- 0x0C8: XOUT (0x00), R00
|
||||
"111011" & X"0E0", -- 0x0C9: CALL 0x0E0
|
||||
"000011" & X"800", -- 0x0CA: MOV R00, 0x80
|
||||
"111011" & X"194", -- 0x0CB: CALL 0x194
|
||||
"000011" & X"551", -- 0x0CC: MOV R01, 0x55
|
||||
"111011" & X"199", -- 0x0CD: CALL 0x199
|
||||
"101000" & X"020", -- 0x0CE: XIN R00, (0x02)
|
||||
"011001" & X"010", -- 0x0CF: AND R00, 0x01
|
||||
"110010" & X"0D2", -- 0x0D0: JNZ 0x0D2
|
||||
"000011" & X"771", -- 0x0D1: MOV R01, 0x77
|
||||
"000011" & X"C00", -- 0x0D2: MOV R00, 0xC0
|
||||
"111011" & X"194", -- 0x0D3: CALL 0x194
|
||||
"111011" & X"199", -- 0x0D4: CALL 0x199
|
||||
"111110" & X"000", -- 0x0D5: RET
|
||||
"000011" & X"000", -- 0x0D6: MOV R00, 0x00
|
||||
"000011" & X"181", -- 0x0D7: MOV R01, 0x18
|
||||
"001010" & X"0A2", -- 0x0D8: MOVC R02, (0x0A)
|
||||
"001010" & X"0A3", -- 0x0D9: MOVC R03, (0x0A)
|
||||
"111011" & X"123", -- 0x0DA: CALL 0x123
|
||||
"001101" & X"000", -- 0x0DB: MOVC (0x00), R00
|
||||
"001101" & X"011", -- 0x0DC: MOVC (0x01), R01
|
||||
"001101" & X"022", -- 0x0DD: MOVC (0x02), R02
|
||||
"001101" & X"033", -- 0x0DE: MOVC (0x03), R03
|
||||
"111110" & X"000", -- 0x0DF: RET
|
||||
"000011" & X"000", -- 0x0E0: MOV R00, 0x00
|
||||
"000011" & X"181", -- 0x0E1: MOV R01, 0x18
|
||||
"001010" & X"0B2", -- 0x0E2: MOVC R02, (0x0B)
|
||||
"001010" & X"0B3", -- 0x0E3: MOVC R03, (0x0B)
|
||||
"111011" & X"123", -- 0x0E4: CALL 0x123
|
||||
"001101" & X"000", -- 0x0E5: MOVC (0x00), R00
|
||||
"001101" & X"011", -- 0x0E6: MOVC (0x01), R01
|
||||
"001101" & X"022", -- 0x0E7: MOVC (0x02), R02
|
||||
"001101" & X"033", -- 0x0E8: MOVC (0x03), R03
|
||||
"111110" & X"000", -- 0x0E9: RET
|
||||
"111100" & X"000", -- 0x0EA: PUSH R00
|
||||
"111100" & X"001", -- 0x0EB: PUSH R01
|
||||
"111100" & X"002", -- 0x0EC: PUSH R02
|
||||
"111100" & X"003", -- 0x0ED: PUSH R03
|
||||
"001010" & X"040", -- 0x0EE: MOVC R00, (0x04)
|
||||
"001010" & X"051", -- 0x0EF: MOVC R01, (0x05)
|
||||
"010101" & X"010", -- 0x0F0: DEC R00
|
||||
"010111" & X"001", -- 0x0F1: SUBC R01, 0x00
|
||||
"001101" & X"040", -- 0x0F2: MOVC (0x04), R00
|
||||
"001101" & X"051", -- 0x0F3: MOVC (0x05), R01
|
||||
"001111" & X"001", -- 0x0F4: TST R01
|
||||
"110010" & X"108", -- 0x0F5: JNZ 0x108
|
||||
"001111" & X"000", -- 0x0F6: TST R00
|
||||
"110010" & X"108", -- 0x0F7: JNZ 0x108
|
||||
"000011" & X"000", -- 0x0F8: MOV R00, 0x00
|
||||
"000011" & X"021", -- 0x0F9: MOV R01, 0x02
|
||||
"001101" & X"040", -- 0x0FA: MOVC (0x04), R00
|
||||
"001101" & X"051", -- 0x0FB: MOVC (0x05), R01
|
||||
"101000" & X"110", -- 0x0FC: XIN R00, (0x11)
|
||||
"101000" & X"121", -- 0x0FD: XIN R01, (0x12)
|
||||
"101000" & X"132", -- 0x0FE: XIN R02, (0x13)
|
||||
"101000" & X"143", -- 0x0FF: XIN R03, (0x14)
|
||||
"010001" & X"010", -- 0x100: INC R00
|
||||
"010011" & X"001", -- 0x101: ADDC R01, 0x00
|
||||
"010011" & X"002", -- 0x102: ADDC R02, 0x00
|
||||
"010011" & X"003", -- 0x103: ADDC R03, 0x00
|
||||
"100100" & X"110", -- 0x104: XOUT (0x11), R00
|
||||
"100100" & X"121", -- 0x105: XOUT (0x12), R01
|
||||
"100100" & X"132", -- 0x106: XOUT (0x13), R02
|
||||
"100100" & X"143", -- 0x107: XOUT (0x14), R03
|
||||
"101000" & X"800", -- 0x108: XIN R00, (0x80)
|
||||
"001010" & X"071", -- 0x109: MOVC R01, (0x07)
|
||||
"001010" & X"062", -- 0x10A: MOVC R02, (0x06)
|
||||
"001111" & X"001", -- 0x10B: TST R01
|
||||
"110010" & X"10F", -- 0x10C: JNZ 0x10F
|
||||
"001111" & X"002", -- 0x10D: TST R02
|
||||
"110001" & X"119", -- 0x10E: JZ 0x119
|
||||
"010101" & X"012", -- 0x10F: DEC R02
|
||||
"010111" & X"001", -- 0x110: SUBC R01, 0x00
|
||||
"001101" & X"071", -- 0x111: MOVC (0x07), R01
|
||||
"001101" & X"062", -- 0x112: MOVC (0x06), R02
|
||||
"001010" & X"091", -- 0x113: MOVC R01, (0x09)
|
||||
"101000" & X"800", -- 0x114: XIN R00, (0x80)
|
||||
"001101" & X"090", -- 0x115: MOVC (0x09), R00
|
||||
"001110" & X"010", -- 0x116: CMP R00, R01
|
||||
"111001" & X"11E", -- 0x117: JEQ 0x11E
|
||||
"110000" & X"11A", -- 0x118: JMP 0x11A
|
||||
"001101" & X"080", -- 0x119: MOVC (0x08), R00
|
||||
"000011" & X"041", -- 0x11A: MOV R01, 0x04
|
||||
"001101" & X"071", -- 0x11B: MOVC (0x07), R01
|
||||
"000011" & X"001", -- 0x11C: MOV R01, 0x00
|
||||
"001101" & X"061", -- 0x11D: MOVC (0x06), R01
|
||||
"111101" & X"003", -- 0x11E: POP R03
|
||||
"111101" & X"002", -- 0x11F: POP R02
|
||||
"111101" & X"001", -- 0x120: POP R01
|
||||
"111101" & X"000", -- 0x121: POP R00
|
||||
"111111" & X"000", -- 0x122: RETI
|
||||
"111011" & X"131", -- 0x123: CALL 0x131
|
||||
"100100" & X"051", -- 0x124: XOUT (0x05), R01
|
||||
"100100" & X"040", -- 0x125: XOUT (0x04), R00
|
||||
"100100" & X"073", -- 0x126: XOUT (0x07), R03
|
||||
"100100" & X"062", -- 0x127: XOUT (0x06), R02
|
||||
"011001" & X"801", -- 0x128: AND R01, 0x80
|
||||
"110010" & X"12B", -- 0x129: JNZ 0x12B
|
||||
"111110" & X"000", -- 0x12A: RET
|
||||
"111011" & X"137", -- 0x12B: CALL 0x137
|
||||
"101000" & X"051", -- 0x12C: XIN R01, (0x05)
|
||||
"101000" & X"040", -- 0x12D: XIN R00, (0x04)
|
||||
"101000" & X"073", -- 0x12E: XIN R03, (0x07)
|
||||
"101000" & X"062", -- 0x12F: XIN R02, (0x06)
|
||||
"111110" & X"000", -- 0x130: RET
|
||||
"111100" & X"000", -- 0x131: PUSH R00
|
||||
"101000" & X"A00", -- 0x132: XIN R00, (0xA0)
|
||||
"011001" & X"020", -- 0x133: AND R00, 0x02
|
||||
"110001" & X"132", -- 0x134: JZ 0x132
|
||||
"111101" & X"000", -- 0x135: POP R00
|
||||
"111110" & X"000", -- 0x136: RET
|
||||
"111100" & X"000", -- 0x137: PUSH R00
|
||||
"101000" & X"A00", -- 0x138: XIN R00, (0xA0)
|
||||
"011001" & X"040", -- 0x139: AND R00, 0x04
|
||||
"110001" & X"138", -- 0x13A: JZ 0x138
|
||||
"111101" & X"000", -- 0x13B: POP R00
|
||||
"111110" & X"000", -- 0x13C: RET
|
||||
"111011" & X"1EE", -- 0x13D: CALL 0x1EE
|
||||
"111011" & X"1AB", -- 0x13E: CALL 0x1AB
|
||||
"000010" & X"010", -- 0x13F: MOV R00, R01
|
||||
"111011" & X"1AB", -- 0x140: CALL 0x1AB
|
||||
"111110" & X"000", -- 0x141: RET
|
||||
"111100" & X"00F", -- 0x142: PUSH R15
|
||||
"000011" & X"0AF", -- 0x143: MOV R15, 0x0A
|
||||
"111011" & X"149", -- 0x144: CALL 0x149
|
||||
"010101" & X"01F", -- 0x145: DEC R15
|
||||
"110010" & X"144", -- 0x146: JNZ 0x144
|
||||
"111101" & X"00F", -- 0x147: POP R15
|
||||
"111110" & X"000", -- 0x148: RET
|
||||
"111100" & X"00F", -- 0x149: PUSH R15
|
||||
"000011" & X"0AF", -- 0x14A: MOV R15, 0x0A
|
||||
"111011" & X"150", -- 0x14B: CALL 0x150
|
||||
"010101" & X"01F", -- 0x14C: DEC R15
|
||||
"110010" & X"14B", -- 0x14D: JNZ 0x14B
|
||||
"111101" & X"00F", -- 0x14E: POP R15
|
||||
"111110" & X"000", -- 0x14F: RET
|
||||
"111100" & X"00F", -- 0x150: PUSH R15
|
||||
"000011" & X"0AF", -- 0x151: MOV R15, 0x0A
|
||||
"111011" & X"157", -- 0x152: CALL 0x157
|
||||
"010101" & X"01F", -- 0x153: DEC R15
|
||||
"110010" & X"152", -- 0x154: JNZ 0x152
|
||||
"111101" & X"00F", -- 0x155: POP R15
|
||||
"111110" & X"000", -- 0x156: RET
|
||||
"111100" & X"00F", -- 0x157: PUSH R15
|
||||
"000011" & X"0AF", -- 0x158: MOV R15, 0x0A
|
||||
"111011" & X"15E", -- 0x159: CALL 0x15E
|
||||
"010101" & X"01F", -- 0x15A: DEC R15
|
||||
"110010" & X"159", -- 0x15B: JNZ 0x159
|
||||
"111101" & X"00F", -- 0x15C: POP R15
|
||||
"111110" & X"000", -- 0x15D: RET
|
||||
"111100" & X"00F", -- 0x15E: PUSH R15
|
||||
"000011" & X"0AF", -- 0x15F: MOV R15, 0x0A
|
||||
"111011" & X"165", -- 0x160: CALL 0x165
|
||||
"010101" & X"01F", -- 0x161: DEC R15
|
||||
"110010" & X"160", -- 0x162: JNZ 0x160
|
||||
"111101" & X"00F", -- 0x163: POP R15
|
||||
"111110" & X"000", -- 0x164: RET
|
||||
"111100" & X"00F", -- 0x165: PUSH R15
|
||||
"000011" & X"63F", -- 0x166: MOV R15, 0x63
|
||||
"000000" & X"000", -- 0x167: NOP
|
||||
"000000" & X"000", -- 0x168: NOP
|
||||
"000000" & X"000", -- 0x169: NOP
|
||||
"010101" & X"01F", -- 0x16A: DEC R15
|
||||
"110010" & X"167", -- 0x16B: JNZ 0x167
|
||||
"111101" & X"00F", -- 0x16C: POP R15
|
||||
"111110" & X"000", -- 0x16D: RET
|
||||
"111100" & X"00F", -- 0x16E: PUSH R15
|
||||
"000011" & X"09F", -- 0x16F: MOV R15, 0x09
|
||||
"000000" & X"000", -- 0x170: NOP
|
||||
"000000" & X"000", -- 0x171: NOP
|
||||
"000000" & X"000", -- 0x172: NOP
|
||||
"010101" & X"01F", -- 0x173: DEC R15
|
||||
"110010" & X"170", -- 0x174: JNZ 0x170
|
||||
"111101" & X"00F", -- 0x175: POP R15
|
||||
"111110" & X"000", -- 0x176: RET
|
||||
"000011" & X"002", -- 0x177: MOV R02, 0x00
|
||||
"000011" & X"030", -- 0x178: MOV R00, 0x03
|
||||
"111011" & X"1C3", -- 0x179: CALL 0x1C3
|
||||
"111011" & X"150", -- 0x17A: CALL 0x150
|
||||
"000011" & X"002", -- 0x17B: MOV R02, 0x00
|
||||
"000011" & X"030", -- 0x17C: MOV R00, 0x03
|
||||
"111011" & X"1C3", -- 0x17D: CALL 0x1C3
|
||||
"111011" & X"150", -- 0x17E: CALL 0x150
|
||||
"000011" & X"002", -- 0x17F: MOV R02, 0x00
|
||||
"000011" & X"020", -- 0x180: MOV R00, 0x02
|
||||
"111011" & X"1C3", -- 0x181: CALL 0x1C3
|
||||
"111011" & X"157", -- 0x182: CALL 0x157
|
||||
"000011" & X"280", -- 0x183: MOV R00, 0x28
|
||||
"111011" & X"194", -- 0x184: CALL 0x194
|
||||
"000011" & X"0C0", -- 0x185: MOV R00, 0x0C
|
||||
"111011" & X"194", -- 0x186: CALL 0x194
|
||||
"000011" & X"060", -- 0x187: MOV R00, 0x06
|
||||
"111011" & X"194", -- 0x188: CALL 0x194
|
||||
"000011" & X"010", -- 0x189: MOV R00, 0x01
|
||||
"111011" & X"194", -- 0x18A: CALL 0x194
|
||||
"111110" & X"000", -- 0x18B: RET
|
||||
"111100" & X"000", -- 0x18C: PUSH R00
|
||||
"111011" & X"1B7", -- 0x18D: CALL 0x1B7
|
||||
"011001" & X"800", -- 0x18E: AND R00, 0x80
|
||||
"110001" & X"192", -- 0x18F: JZ 0x192
|
||||
"111011" & X"16E", -- 0x190: CALL 0x16E
|
||||
"110000" & X"18D", -- 0x191: JMP 0x18D
|
||||
"111101" & X"000", -- 0x192: POP R00
|
||||
"111110" & X"000", -- 0x193: RET
|
||||
"111100" & X"002", -- 0x194: PUSH R02
|
||||
"000011" & X"002", -- 0x195: MOV R02, 0x00
|
||||
"111011" & X"1B0", -- 0x196: CALL 0x1B0
|
||||
"111101" & X"002", -- 0x197: POP R02
|
||||
"111110" & X"000", -- 0x198: RET
|
||||
"111100" & X"000", -- 0x199: PUSH R00
|
||||
"000100" & X"010", -- 0x19A: MOVX R00, (R01)
|
||||
"010001" & X"011", -- 0x19B: INC R01
|
||||
"001111" & X"000", -- 0x19C: TST R00
|
||||
"110001" & X"1A0", -- 0x19D: JZ 0x1A0
|
||||
"111011" & X"1AB", -- 0x19E: CALL 0x1AB
|
||||
"110000" & X"19A", -- 0x19F: JMP 0x19A
|
||||
"111101" & X"000", -- 0x1A0: POP R00
|
||||
"111110" & X"000", -- 0x1A1: RET
|
||||
"111100" & X"000", -- 0x1A2: PUSH R00
|
||||
"001001" & X"010", -- 0x1A3: MOVC R00, (R01)
|
||||
"010001" & X"011", -- 0x1A4: INC R01
|
||||
"001111" & X"000", -- 0x1A5: TST R00
|
||||
"110001" & X"1A9", -- 0x1A6: JZ 0x1A9
|
||||
"111011" & X"1AB", -- 0x1A7: CALL 0x1AB
|
||||
"110000" & X"1A3", -- 0x1A8: JMP 0x1A3
|
||||
"111101" & X"000", -- 0x1A9: POP R00
|
||||
"111110" & X"000", -- 0x1AA: RET
|
||||
"111100" & X"002", -- 0x1AB: PUSH R02
|
||||
"000011" & X"402", -- 0x1AC: MOV R02, 0x40
|
||||
"111011" & X"1B0", -- 0x1AD: CALL 0x1B0
|
||||
"111101" & X"002", -- 0x1AE: POP R02
|
||||
"111110" & X"000", -- 0x1AF: RET
|
||||
"111011" & X"18C", -- 0x1B0: CALL 0x18C
|
||||
"111100" & X"000", -- 0x1B1: PUSH R00
|
||||
"101010" & X"000", -- 0x1B2: SWAP R00
|
||||
"111011" & X"1C3", -- 0x1B3: CALL 0x1C3
|
||||
"111101" & X"000", -- 0x1B4: POP R00
|
||||
"111011" & X"1C3", -- 0x1B5: CALL 0x1C3
|
||||
"111110" & X"000", -- 0x1B6: RET
|
||||
"111100" & X"002", -- 0x1B7: PUSH R02
|
||||
"000011" & X"002", -- 0x1B8: MOV R02, 0x00
|
||||
"111011" & X"1BC", -- 0x1B9: CALL 0x1BC
|
||||
"111101" & X"002", -- 0x1BA: POP R02
|
||||
"111110" & X"000", -- 0x1BB: RET
|
||||
"111011" & X"1D6", -- 0x1BC: CALL 0x1D6
|
||||
"101010" & X"000", -- 0x1BD: SWAP R00
|
||||
"111100" & X"000", -- 0x1BE: PUSH R00
|
||||
"111011" & X"1D6", -- 0x1BF: CALL 0x1D6
|
||||
"111101" & X"002", -- 0x1C0: POP R02
|
||||
"011010" & X"020", -- 0x1C1: OR R00, R02
|
||||
"111110" & X"000", -- 0x1C2: RET
|
||||
"111100" & X"001", -- 0x1C3: PUSH R01
|
||||
"011001" & X"0F0", -- 0x1C4: AND R00, 0x0F
|
||||
"000010" & X"001", -- 0x1C5: MOV R01, R00
|
||||
"011010" & X"021", -- 0x1C6: OR R01, R02
|
||||
"100100" & X"081", -- 0x1C7: XOUT (0x08), R01
|
||||
"111011" & X"16E", -- 0x1C8: CALL 0x16E
|
||||
"000010" & X"001", -- 0x1C9: MOV R01, R00
|
||||
"011010" & X"021", -- 0x1CA: OR R01, R02
|
||||
"011011" & X"801", -- 0x1CB: OR R01, 0x80
|
||||
"100100" & X"081", -- 0x1CC: XOUT (0x08), R01
|
||||
"111011" & X"16E", -- 0x1CD: CALL 0x16E
|
||||
"000010" & X"001", -- 0x1CE: MOV R01, R00
|
||||
"011010" & X"021", -- 0x1CF: OR R01, R02
|
||||
"100100" & X"081", -- 0x1D0: XOUT (0x08), R01
|
||||
"111011" & X"16E", -- 0x1D1: CALL 0x16E
|
||||
"011011" & X"201", -- 0x1D2: OR R01, 0x20
|
||||
"100100" & X"081", -- 0x1D3: XOUT (0x08), R01
|
||||
"111101" & X"001", -- 0x1D4: POP R01
|
||||
"111110" & X"000", -- 0x1D5: RET
|
||||
"111100" & X"001", -- 0x1D6: PUSH R01
|
||||
"000011" & X"201", -- 0x1D7: MOV R01, 0x20
|
||||
"011010" & X"021", -- 0x1D8: OR R01, R02
|
||||
"100100" & X"081", -- 0x1D9: XOUT (0x08), R01
|
||||
"111011" & X"16E", -- 0x1DA: CALL 0x16E
|
||||
"000011" & X"201", -- 0x1DB: MOV R01, 0x20
|
||||
"011010" & X"021", -- 0x1DC: OR R01, R02
|
||||
"011011" & X"801", -- 0x1DD: OR R01, 0x80
|
||||
"100100" & X"081", -- 0x1DE: XOUT (0x08), R01
|
||||
"111011" & X"16E", -- 0x1DF: CALL 0x16E
|
||||
"101000" & X"080", -- 0x1E0: XIN R00, (0x08)
|
||||
"011001" & X"0F0", -- 0x1E1: AND R00, 0x0F
|
||||
"000011" & X"201", -- 0x1E2: MOV R01, 0x20
|
||||
"011010" & X"021", -- 0x1E3: OR R01, R02
|
||||
"100100" & X"081", -- 0x1E4: XOUT (0x08), R01
|
||||
"111011" & X"16E", -- 0x1E5: CALL 0x16E
|
||||
"111101" & X"001", -- 0x1E6: POP R01
|
||||
"111110" & X"000", -- 0x1E7: RET
|
||||
"011001" & X"0F0", -- 0x1E8: AND R00, 0x0F
|
||||
"001111" & X"0A0", -- 0x1E9: CMP R00, 0x0A
|
||||
"110101" & X"1EC", -- 0x1EA: JLT 0x1EC
|
||||
"010001" & X"070", -- 0x1EB: ADD R00, 0x07
|
||||
"010001" & X"300", -- 0x1EC: ADD R00, 0x30
|
||||
"111110" & X"000", -- 0x1ED: RET
|
||||
"111100" & X"000", -- 0x1EE: PUSH R00
|
||||
"111011" & X"1E8", -- 0x1EF: CALL 0x1E8
|
||||
"000010" & X"001", -- 0x1F0: MOV R01, R00
|
||||
"111101" & X"000", -- 0x1F1: POP R00
|
||||
"101010" & X"000", -- 0x1F2: SWAP R00
|
||||
"111011" & X"1E8", -- 0x1F3: CALL 0x1E8
|
||||
"111110" & X"000" -- 0x1F4: RET
|
||||
);
|
||||
|
||||
begin
|
||||
|
||||
PROM_READ:
|
||||
process(clk, ce)
|
||||
begin
|
||||
if rising_edge(clk) and ce = '1' then
|
||||
dout <= imem_rom(to_integer(addr));
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end test;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,317 @@
|
||||
-------------------------------------------------------------------------
|
||||
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||
-- This file: The ROM file for use in your VHDL design
|
||||
--
|
||||
-- Copyright (C) 2007 J. Ahrensfeld
|
||||
--
|
||||
-- This program is free software: you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation, either version 3 of the License, or
|
||||
-- (at your option) any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
--
|
||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
LIBRARY ieee;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
USE ieee.numeric_std.ALL;
|
||||
|
||||
library work;
|
||||
use work.cpu_pkg.all;
|
||||
|
||||
-- JASM_ROM_INSERT_HERE
|
||||
ENTITY xrom IS
|
||||
Port (
|
||||
clk : in STD_LOGIC;
|
||||
ce : in STD_LOGIC;
|
||||
addr : in dmem_addr_t;
|
||||
dout : out dmem_data_t
|
||||
);
|
||||
END xrom;
|
||||
|
||||
ARCHITECTURE test OF xrom IS
|
||||
|
||||
type xmem_rom_t is array (0 to 255) of dmem_data_t;
|
||||
|
||||
-- Assembled from test.jsm
|
||||
constant xmem_rom : xmem_rom_t :=
|
||||
(
|
||||
X"44", -- 0x00
|
||||
X"53", -- 0x01
|
||||
X"49", -- 0x02
|
||||
X"20", -- 0x03
|
||||
X"47", -- 0x04
|
||||
X"6D", -- 0x05
|
||||
X"62", -- 0x06
|
||||
X"48", -- 0x07
|
||||
X"20", -- 0x08
|
||||
X"42", -- 0x09
|
||||
X"72", -- 0x0A
|
||||
X"65", -- 0x0B
|
||||
X"6D", -- 0x0C
|
||||
X"65", -- 0x0D
|
||||
X"6E", -- 0x0E
|
||||
X"20", -- 0x0F
|
||||
X"00", -- 0x10
|
||||
X"4F", -- 0x11
|
||||
X"63", -- 0x12
|
||||
X"74", -- 0x13
|
||||
X"6F", -- 0x14
|
||||
X"62", -- 0x15
|
||||
X"65", -- 0x16
|
||||
X"72", -- 0x17
|
||||
X"20", -- 0x18
|
||||
X"32", -- 0x19
|
||||
X"30", -- 0x1A
|
||||
X"30", -- 0x1B
|
||||
X"37", -- 0x1C
|
||||
X"20", -- 0x1D
|
||||
X"20", -- 0x1E
|
||||
X"20", -- 0x1F
|
||||
X"20", -- 0x20
|
||||
X"00", -- 0x21
|
||||
X"20", -- 0x22
|
||||
X"20", -- 0x23
|
||||
X"20", -- 0x24
|
||||
X"45", -- 0x25
|
||||
X"6E", -- 0x26
|
||||
X"63", -- 0x27
|
||||
X"72", -- 0x28
|
||||
X"79", -- 0x29
|
||||
X"70", -- 0x2A
|
||||
X"74", -- 0x2B
|
||||
X"69", -- 0x2C
|
||||
X"6F", -- 0x2D
|
||||
X"6E", -- 0x2E
|
||||
X"20", -- 0x2F
|
||||
X"20", -- 0x30
|
||||
X"20", -- 0x31
|
||||
X"00", -- 0x32
|
||||
X"20", -- 0x33
|
||||
X"20", -- 0x34
|
||||
X"20", -- 0x35
|
||||
X"20", -- 0x36
|
||||
X"20", -- 0x37
|
||||
X"42", -- 0x38
|
||||
X"79", -- 0x39
|
||||
X"70", -- 0x3A
|
||||
X"61", -- 0x3B
|
||||
X"73", -- 0x3C
|
||||
X"73", -- 0x3D
|
||||
X"20", -- 0x3E
|
||||
X"20", -- 0x3F
|
||||
X"20", -- 0x40
|
||||
X"20", -- 0x41
|
||||
X"20", -- 0x42
|
||||
X"00", -- 0x43
|
||||
X"45", -- 0x44
|
||||
X"43", -- 0x45
|
||||
X"42", -- 0x46
|
||||
X"2D", -- 0x47
|
||||
X"31", -- 0x48
|
||||
X"32", -- 0x49
|
||||
X"38", -- 0x4A
|
||||
X"20", -- 0x4B
|
||||
X"65", -- 0x4C
|
||||
X"6E", -- 0x4D
|
||||
X"63", -- 0x4E
|
||||
X"72", -- 0x4F
|
||||
X"79", -- 0x50
|
||||
X"70", -- 0x51
|
||||
X"74", -- 0x52
|
||||
X"2E", -- 0x53
|
||||
X"00", -- 0x54
|
||||
X"43", -- 0x55
|
||||
X"42", -- 0x56
|
||||
X"43", -- 0x57
|
||||
X"2D", -- 0x58
|
||||
X"31", -- 0x59
|
||||
X"32", -- 0x5A
|
||||
X"38", -- 0x5B
|
||||
X"20", -- 0x5C
|
||||
X"65", -- 0x5D
|
||||
X"6E", -- 0x5E
|
||||
X"63", -- 0x5F
|
||||
X"72", -- 0x60
|
||||
X"79", -- 0x61
|
||||
X"70", -- 0x62
|
||||
X"74", -- 0x63
|
||||
X"2E", -- 0x64
|
||||
X"00", -- 0x65
|
||||
X"20", -- 0x66
|
||||
X"20", -- 0x67
|
||||
X"20", -- 0x68
|
||||
X"41", -- 0x69
|
||||
X"75", -- 0x6A
|
||||
X"64", -- 0x6B
|
||||
X"69", -- 0x6C
|
||||
X"6F", -- 0x6D
|
||||
X"20", -- 0x6E
|
||||
X"64", -- 0x6F
|
||||
X"61", -- 0x70
|
||||
X"74", -- 0x71
|
||||
X"61", -- 0x72
|
||||
X"20", -- 0x73
|
||||
X"20", -- 0x74
|
||||
X"20", -- 0x75
|
||||
X"00", -- 0x76
|
||||
X"20", -- 0x77
|
||||
X"49", -- 0x78
|
||||
X"6E", -- 0x79
|
||||
X"63", -- 0x7A
|
||||
X"72", -- 0x7B
|
||||
X"65", -- 0x7C
|
||||
X"6D", -- 0x7D
|
||||
X"2E", -- 0x7E
|
||||
X"20", -- 0x7F
|
||||
X"62", -- 0x80
|
||||
X"6C", -- 0x81
|
||||
X"6F", -- 0x82
|
||||
X"63", -- 0x83
|
||||
X"6B", -- 0x84
|
||||
X"73", -- 0x85
|
||||
X"20", -- 0x86
|
||||
X"00", -- 0x87
|
||||
X"56", -- 0x88
|
||||
X"6F", -- 0x89
|
||||
X"6C", -- 0x8A
|
||||
X"75", -- 0x8B
|
||||
X"6D", -- 0x8C
|
||||
X"65", -- 0x8D
|
||||
X"20", -- 0x8E
|
||||
X"3A", -- 0x8F
|
||||
X"20", -- 0x90
|
||||
X"00", -- 0x91
|
||||
X"20", -- 0x92
|
||||
X"20", -- 0x93
|
||||
X"20", -- 0x94
|
||||
X"20", -- 0x95
|
||||
X"20", -- 0x96
|
||||
X"20", -- 0x97
|
||||
X"20", -- 0x98
|
||||
X"20", -- 0x99
|
||||
X"20", -- 0x9A
|
||||
X"20", -- 0x9B
|
||||
X"20", -- 0x9C
|
||||
X"20", -- 0x9D
|
||||
X"20", -- 0x9E
|
||||
X"20", -- 0x9F
|
||||
X"20", -- 0xA0
|
||||
X"20", -- 0xA1
|
||||
X"00", -- 0xA2
|
||||
X"00", -- 0xA3
|
||||
X"2A", -- 0xA4
|
||||
X"00", -- 0xA5
|
||||
X"1A", -- 0xA6
|
||||
X"00", -- 0xA7
|
||||
X"1C", -- 0xA8
|
||||
X"00", -- 0xA9
|
||||
X"2C", -- 0xAA
|
||||
X"00", -- 0xAB
|
||||
X"32", -- 0xAC
|
||||
X"00", -- 0xAD
|
||||
X"20", -- 0xAE
|
||||
X"00", -- 0xAF
|
||||
X"02", -- 0xB0
|
||||
X"00", -- 0xB1
|
||||
X"04", -- 0xB2
|
||||
X"00", -- 0xB3
|
||||
X"18", -- 0xB4
|
||||
X"01", -- 0xB5
|
||||
X"00", -- 0xB6
|
||||
X"04", -- 0xB7
|
||||
X"04", -- 0xB8
|
||||
X"00", -- 0xB9
|
||||
X"00", -- 0xBA
|
||||
X"80", -- 0xBB
|
||||
X"BB", -- 0xBC
|
||||
X"80", -- 0xBD
|
||||
X"BB", -- 0xBE
|
||||
X"00", -- 0xBF
|
||||
X"80", -- 0xC0
|
||||
X"00", -- 0xC1
|
||||
X"00", -- 0xC2
|
||||
X"00", -- 0xC3
|
||||
X"80", -- 0xC4
|
||||
X"0A", -- 0xC5
|
||||
X"0A", -- 0xC6
|
||||
X"00", -- 0xC7
|
||||
X"00", -- 0xC8
|
||||
X"00", -- 0xC9
|
||||
X"00", -- 0xCA
|
||||
X"00", -- 0xCB
|
||||
X"00", -- 0xCC
|
||||
X"00", -- 0xCD
|
||||
X"00", -- 0xCE
|
||||
X"00", -- 0xCF
|
||||
X"00", -- 0xD0
|
||||
X"00", -- 0xD1
|
||||
X"00", -- 0xD2
|
||||
X"00", -- 0xD3
|
||||
X"00", -- 0xD4
|
||||
X"00", -- 0xD5
|
||||
X"00", -- 0xD6
|
||||
X"00", -- 0xD7
|
||||
X"00", -- 0xD8
|
||||
X"00", -- 0xD9
|
||||
X"00", -- 0xDA
|
||||
X"00", -- 0xDB
|
||||
X"00", -- 0xDC
|
||||
X"00", -- 0xDD
|
||||
X"00", -- 0xDE
|
||||
X"00", -- 0xDF
|
||||
X"00", -- 0xE0
|
||||
X"00", -- 0xE1
|
||||
X"00", -- 0xE2
|
||||
X"00", -- 0xE3
|
||||
X"00", -- 0xE4
|
||||
X"00", -- 0xE5
|
||||
X"00", -- 0xE6
|
||||
X"00", -- 0xE7
|
||||
X"00", -- 0xE8
|
||||
X"00", -- 0xE9
|
||||
X"00", -- 0xEA
|
||||
X"00", -- 0xEB
|
||||
X"00", -- 0xEC
|
||||
X"00", -- 0xED
|
||||
X"00", -- 0xEE
|
||||
X"00", -- 0xEF
|
||||
X"00", -- 0xF0
|
||||
X"00", -- 0xF1
|
||||
X"00", -- 0xF2
|
||||
X"00", -- 0xF3
|
||||
X"00", -- 0xF4
|
||||
X"00", -- 0xF5
|
||||
X"00", -- 0xF6
|
||||
X"00", -- 0xF7
|
||||
X"00", -- 0xF8
|
||||
X"00", -- 0xF9
|
||||
X"00", -- 0xFA
|
||||
X"00", -- 0xFB
|
||||
X"00", -- 0xFC
|
||||
X"00", -- 0xFD
|
||||
X"00", -- 0xFE
|
||||
X"00" -- 0xFF
|
||||
);
|
||||
|
||||
begin
|
||||
|
||||
PROM_READ:
|
||||
process(clk, ce)
|
||||
begin
|
||||
if rising_edge(clk) and ce = '1' then
|
||||
dout <= xmem_rom(to_integer(addr));
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end test;
|
||||
|
||||
@@ -0,0 +1,413 @@
|
||||
-------------------------------------------------------------------------
|
||||
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||
-- This file: loadable ROM
|
||||
--
|
||||
-- Copyright (C) 2007 J. Ahrensfeld
|
||||
--
|
||||
-- This program is free software: you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation, either version 3 of the License, or
|
||||
-- (at your option) any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
--
|
||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
LIBRARY ieee;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
USE ieee.numeric_std.ALL;
|
||||
|
||||
library UNISIM;
|
||||
use UNISIM.VComponents.all;
|
||||
|
||||
library work;
|
||||
use work.cpu_pkg.all;
|
||||
|
||||
ENTITY xrom IS
|
||||
Port (
|
||||
clk : in STD_LOGIC;
|
||||
ce : in STD_LOGIC;
|
||||
addr : in dmem_addr_t;
|
||||
dout : out dmem_data_t
|
||||
);
|
||||
|
||||
END xrom;
|
||||
|
||||
ARCHITECTURE loadable OF xrom IS
|
||||
|
||||
-- JASM_ROM_INSERT_HERE
|
||||
|
||||
-- Assembled from test.jsm
|
||||
type xmem_rom_t is array (0 to 255) of dmem_data_t;
|
||||
signal xmem_rom : xmem_rom_t :=
|
||||
(
|
||||
X"44", -- 0x00
|
||||
X"53", -- 0x01
|
||||
X"49", -- 0x02
|
||||
X"20", -- 0x03
|
||||
X"47", -- 0x04
|
||||
X"6D", -- 0x05
|
||||
X"62", -- 0x06
|
||||
X"48", -- 0x07
|
||||
X"20", -- 0x08
|
||||
X"42", -- 0x09
|
||||
X"72", -- 0x0A
|
||||
X"65", -- 0x0B
|
||||
X"6D", -- 0x0C
|
||||
X"65", -- 0x0D
|
||||
X"6E", -- 0x0E
|
||||
X"20", -- 0x0F
|
||||
X"00", -- 0x10
|
||||
X"4F", -- 0x11
|
||||
X"63", -- 0x12
|
||||
X"74", -- 0x13
|
||||
X"6F", -- 0x14
|
||||
X"62", -- 0x15
|
||||
X"65", -- 0x16
|
||||
X"72", -- 0x17
|
||||
X"20", -- 0x18
|
||||
X"32", -- 0x19
|
||||
X"30", -- 0x1A
|
||||
X"30", -- 0x1B
|
||||
X"37", -- 0x1C
|
||||
X"20", -- 0x1D
|
||||
X"20", -- 0x1E
|
||||
X"20", -- 0x1F
|
||||
X"20", -- 0x20
|
||||
X"00", -- 0x21
|
||||
X"20", -- 0x22
|
||||
X"20", -- 0x23
|
||||
X"20", -- 0x24
|
||||
X"45", -- 0x25
|
||||
X"6E", -- 0x26
|
||||
X"63", -- 0x27
|
||||
X"72", -- 0x28
|
||||
X"79", -- 0x29
|
||||
X"70", -- 0x2A
|
||||
X"74", -- 0x2B
|
||||
X"69", -- 0x2C
|
||||
X"6F", -- 0x2D
|
||||
X"6E", -- 0x2E
|
||||
X"20", -- 0x2F
|
||||
X"20", -- 0x30
|
||||
X"20", -- 0x31
|
||||
X"00", -- 0x32
|
||||
X"20", -- 0x33
|
||||
X"20", -- 0x34
|
||||
X"20", -- 0x35
|
||||
X"20", -- 0x36
|
||||
X"20", -- 0x37
|
||||
X"42", -- 0x38
|
||||
X"79", -- 0x39
|
||||
X"70", -- 0x3A
|
||||
X"61", -- 0x3B
|
||||
X"73", -- 0x3C
|
||||
X"73", -- 0x3D
|
||||
X"20", -- 0x3E
|
||||
X"20", -- 0x3F
|
||||
X"20", -- 0x40
|
||||
X"20", -- 0x41
|
||||
X"20", -- 0x42
|
||||
X"00", -- 0x43
|
||||
X"45", -- 0x44
|
||||
X"43", -- 0x45
|
||||
X"42", -- 0x46
|
||||
X"2D", -- 0x47
|
||||
X"31", -- 0x48
|
||||
X"32", -- 0x49
|
||||
X"38", -- 0x4A
|
||||
X"20", -- 0x4B
|
||||
X"65", -- 0x4C
|
||||
X"6E", -- 0x4D
|
||||
X"63", -- 0x4E
|
||||
X"72", -- 0x4F
|
||||
X"79", -- 0x50
|
||||
X"70", -- 0x51
|
||||
X"74", -- 0x52
|
||||
X"2E", -- 0x53
|
||||
X"00", -- 0x54
|
||||
X"43", -- 0x55
|
||||
X"42", -- 0x56
|
||||
X"43", -- 0x57
|
||||
X"2D", -- 0x58
|
||||
X"31", -- 0x59
|
||||
X"32", -- 0x5A
|
||||
X"38", -- 0x5B
|
||||
X"20", -- 0x5C
|
||||
X"65", -- 0x5D
|
||||
X"6E", -- 0x5E
|
||||
X"63", -- 0x5F
|
||||
X"72", -- 0x60
|
||||
X"79", -- 0x61
|
||||
X"70", -- 0x62
|
||||
X"74", -- 0x63
|
||||
X"2E", -- 0x64
|
||||
X"00", -- 0x65
|
||||
X"20", -- 0x66
|
||||
X"20", -- 0x67
|
||||
X"20", -- 0x68
|
||||
X"41", -- 0x69
|
||||
X"75", -- 0x6A
|
||||
X"64", -- 0x6B
|
||||
X"69", -- 0x6C
|
||||
X"6F", -- 0x6D
|
||||
X"20", -- 0x6E
|
||||
X"64", -- 0x6F
|
||||
X"61", -- 0x70
|
||||
X"74", -- 0x71
|
||||
X"61", -- 0x72
|
||||
X"20", -- 0x73
|
||||
X"20", -- 0x74
|
||||
X"20", -- 0x75
|
||||
X"00", -- 0x76
|
||||
X"20", -- 0x77
|
||||
X"49", -- 0x78
|
||||
X"6E", -- 0x79
|
||||
X"63", -- 0x7A
|
||||
X"72", -- 0x7B
|
||||
X"65", -- 0x7C
|
||||
X"6D", -- 0x7D
|
||||
X"2E", -- 0x7E
|
||||
X"20", -- 0x7F
|
||||
X"62", -- 0x80
|
||||
X"6C", -- 0x81
|
||||
X"6F", -- 0x82
|
||||
X"63", -- 0x83
|
||||
X"6B", -- 0x84
|
||||
X"73", -- 0x85
|
||||
X"20", -- 0x86
|
||||
X"00", -- 0x87
|
||||
X"56", -- 0x88
|
||||
X"6F", -- 0x89
|
||||
X"6C", -- 0x8A
|
||||
X"75", -- 0x8B
|
||||
X"6D", -- 0x8C
|
||||
X"65", -- 0x8D
|
||||
X"20", -- 0x8E
|
||||
X"3A", -- 0x8F
|
||||
X"20", -- 0x90
|
||||
X"00", -- 0x91
|
||||
X"20", -- 0x92
|
||||
X"20", -- 0x93
|
||||
X"20", -- 0x94
|
||||
X"20", -- 0x95
|
||||
X"20", -- 0x96
|
||||
X"20", -- 0x97
|
||||
X"20", -- 0x98
|
||||
X"20", -- 0x99
|
||||
X"20", -- 0x9A
|
||||
X"20", -- 0x9B
|
||||
X"20", -- 0x9C
|
||||
X"20", -- 0x9D
|
||||
X"20", -- 0x9E
|
||||
X"20", -- 0x9F
|
||||
X"20", -- 0xA0
|
||||
X"20", -- 0xA1
|
||||
X"00", -- 0xA2
|
||||
X"00", -- 0xA3
|
||||
X"2A", -- 0xA4
|
||||
X"00", -- 0xA5
|
||||
X"1A", -- 0xA6
|
||||
X"00", -- 0xA7
|
||||
X"1C", -- 0xA8
|
||||
X"00", -- 0xA9
|
||||
X"2C", -- 0xAA
|
||||
X"00", -- 0xAB
|
||||
X"32", -- 0xAC
|
||||
X"00", -- 0xAD
|
||||
X"20", -- 0xAE
|
||||
X"00", -- 0xAF
|
||||
X"02", -- 0xB0
|
||||
X"00", -- 0xB1
|
||||
X"04", -- 0xB2
|
||||
X"00", -- 0xB3
|
||||
X"18", -- 0xB4
|
||||
X"01", -- 0xB5
|
||||
X"00", -- 0xB6
|
||||
X"04", -- 0xB7
|
||||
X"04", -- 0xB8
|
||||
X"00", -- 0xB9
|
||||
X"00", -- 0xBA
|
||||
X"80", -- 0xBB
|
||||
X"BB", -- 0xBC
|
||||
X"80", -- 0xBD
|
||||
X"BB", -- 0xBE
|
||||
X"00", -- 0xBF
|
||||
X"80", -- 0xC0
|
||||
X"00", -- 0xC1
|
||||
X"00", -- 0xC2
|
||||
X"00", -- 0xC3
|
||||
X"80", -- 0xC4
|
||||
X"0A", -- 0xC5
|
||||
X"0A", -- 0xC6
|
||||
X"00", -- 0xC7
|
||||
X"00", -- 0xC8
|
||||
X"00", -- 0xC9
|
||||
X"00", -- 0xCA
|
||||
X"00", -- 0xCB
|
||||
X"00", -- 0xCC
|
||||
X"00", -- 0xCD
|
||||
X"00", -- 0xCE
|
||||
X"00", -- 0xCF
|
||||
X"00", -- 0xD0
|
||||
X"00", -- 0xD1
|
||||
X"00", -- 0xD2
|
||||
X"00", -- 0xD3
|
||||
X"00", -- 0xD4
|
||||
X"00", -- 0xD5
|
||||
X"00", -- 0xD6
|
||||
X"00", -- 0xD7
|
||||
X"00", -- 0xD8
|
||||
X"00", -- 0xD9
|
||||
X"00", -- 0xDA
|
||||
X"00", -- 0xDB
|
||||
X"00", -- 0xDC
|
||||
X"00", -- 0xDD
|
||||
X"00", -- 0xDE
|
||||
X"00", -- 0xDF
|
||||
X"00", -- 0xE0
|
||||
X"00", -- 0xE1
|
||||
X"00", -- 0xE2
|
||||
X"00", -- 0xE3
|
||||
X"00", -- 0xE4
|
||||
X"00", -- 0xE5
|
||||
X"00", -- 0xE6
|
||||
X"00", -- 0xE7
|
||||
X"00", -- 0xE8
|
||||
X"00", -- 0xE9
|
||||
X"00", -- 0xEA
|
||||
X"00", -- 0xEB
|
||||
X"00", -- 0xEC
|
||||
X"00", -- 0xED
|
||||
X"00", -- 0xEE
|
||||
X"00", -- 0xEF
|
||||
X"00", -- 0xF0
|
||||
X"00", -- 0xF1
|
||||
X"00", -- 0xF2
|
||||
X"00", -- 0xF3
|
||||
X"00", -- 0xF4
|
||||
X"00", -- 0xF5
|
||||
X"00", -- 0xF6
|
||||
X"00", -- 0xF7
|
||||
X"00", -- 0xF8
|
||||
X"00", -- 0xF9
|
||||
X"00", -- 0xFA
|
||||
X"00", -- 0xFB
|
||||
X"00", -- 0xFC
|
||||
X"00", -- 0xFD
|
||||
X"00", -- 0xFE
|
||||
X"00" -- 0xFF
|
||||
);
|
||||
|
||||
signal jtag_ld_clk : STD_LOGIC;
|
||||
signal jtag_ld_we : STD_LOGIC;
|
||||
signal jtag_ld_addr : dmem_addr_t;
|
||||
signal jtag_ld_dout : dmem_data_t;
|
||||
signal jtag_ld_din : dmem_data_t;
|
||||
signal bs_rst, bs_sel, bs_shift, bs_tdi, bs_tdo : std_logic;
|
||||
signal bs_capture, bs_clk0, bs_clk1, bs_update0, bs_update1 : std_logic;
|
||||
signal user_regi, user_rego : unsigned (15 downto 0);
|
||||
constant id : unsigned (15 downto 0) := X"BEEF";
|
||||
|
||||
begin
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
-- Virtex-4: JTAG Loader
|
||||
--------------------------------------------------------------------------
|
||||
i00_BUFG : BUFG
|
||||
port map
|
||||
(
|
||||
O => bs_clk1,
|
||||
I => bs_clk0
|
||||
);
|
||||
|
||||
i01_BUFG : BUFG
|
||||
port map
|
||||
(
|
||||
O => bs_update1,
|
||||
I => bs_update0
|
||||
);
|
||||
|
||||
BSCAN_VIRTEX4_inst2 : BSCAN_VIRTEX4
|
||||
generic map
|
||||
(
|
||||
JTAG_CHAIN => 2 -- Value to set BSCAN site of device. Possible values: (1,2,3 or 4)
|
||||
)
|
||||
port map
|
||||
(
|
||||
CAPTURE => bs_capture, -- CAPTURE output from TAP controller
|
||||
DRCK => bs_clk0, -- Data register output for USER functions
|
||||
RESET => bs_rst, -- Reset output from TAP controller
|
||||
SEL => bs_sel, -- USER active output
|
||||
SHIFT => bs_shift, -- SHIFT output from TAP controller
|
||||
TDI => bs_tdi, -- TDI output from TAP controller
|
||||
UPDATE => bs_update0, -- UPDATE output from TAP controller
|
||||
TDO => bs_tdo -- Data input for USER function
|
||||
);
|
||||
|
||||
jtag_ld_addr <= user_regi(user_regi'left downto user_regi'left-dmem_data_t'length+1);
|
||||
jtag_ld_din <= user_regi(dmem_data_t'left downto 0);
|
||||
jtag_ld_clk <= bs_update1;
|
||||
jtag_ld_we <= bs_sel;
|
||||
|
||||
sipo:
|
||||
process (bs_rst, bs_clk1, bs_tdi, bs_shift)
|
||||
begin
|
||||
if bs_rst = '1' then
|
||||
user_regi <= (others => '0');
|
||||
elsif rising_edge(bs_clk1) then
|
||||
if bs_shift = '1' then
|
||||
user_regi <= bs_tdi & user_regi(user_regi'left downto 1);
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
piso:
|
||||
process (bs_rst, bs_clk1, bs_shift, user_rego)
|
||||
begin
|
||||
bs_tdo <= user_rego(0);
|
||||
if bs_rst = '1' then
|
||||
user_rego <= (others => '0');
|
||||
elsif rising_edge(bs_clk1) then
|
||||
if bs_shift = '1' then
|
||||
user_rego <= user_rego(0) & user_rego(user_rego'left downto 1);
|
||||
else
|
||||
user_rego <= (user_rego'left downto dmem_data_t'length => '0') & jtag_ld_dout;
|
||||
-- user_rego <= id;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
-- ROM Read/Write
|
||||
--------------------------------------------------------------------------
|
||||
PROM_READ:
|
||||
process(clk, ce)
|
||||
begin
|
||||
if rising_edge(clk) and ce = '1' then
|
||||
dout <= xmem_rom(to_integer(addr));
|
||||
end if;
|
||||
end process;
|
||||
|
||||
PROM_WRITE:
|
||||
process(jtag_ld_clk, jtag_ld_we)
|
||||
begin
|
||||
if rising_edge(jtag_ld_clk) then
|
||||
if jtag_ld_we = '1' then
|
||||
xmem_rom(to_integer(jtag_ld_addr)) <= jtag_ld_din;
|
||||
else
|
||||
jtag_ld_dout <= xmem_rom(to_integer(jtag_ld_addr));
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
end loadable;
|
||||
Reference in New Issue
Block a user