git-svn-id: http://moon:8086/svn/vhdl/trunk@1423 cc03376c-175c-47c8-b038-4cd826a8556b
This commit is contained in:
2021-03-21 11:31:55 +00:00
parent 5309734167
commit 73cfd45401
59 changed files with 16220 additions and 0 deletions
@@ -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;
@@ -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;
@@ -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;
+309
View File
@@ -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;
+182
View File
@@ -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.
+107
View File
@@ -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;
+854
View File
@@ -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;
+999
View File
@@ -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;
+66
View File
@@ -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;
+562
View File
@@ -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
+317
View File
@@ -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;
+413
View File
@@ -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;