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
+51
View File
@@ -0,0 +1,51 @@
#!/bin/sh
# ----------------------------------------------------------------------
# Project: JCPU, a portable 8-bit RISC CPU written in VHDL
# This file: rom-file generation for cpu_core
# 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
# ---------------------------------------------------------------------
TARGET=$2
DSTDIR=$1
JASM_HOME=/cygdrive/w/vhdl/lib/CPUs/JCpu/tools
$JASM_HOME/jasm.rb $TARGET.jsm
irom_tcl_snippet="$TARGET.irom.tcl.snip"
irom_vhdl_snippet="$TARGET.irom.vhdl.snip"
irom_ld_vhdl_snippet="$TARGET.irom_ld.vhdl.snip"
xrom_tcl_snippet="$TARGET.xrom.tcl.snip"
xrom_vhdl_snippet="$TARGET.xrom.vhdl.snip"
xrom_ld_vhdl_snippet="$TARGET.xrom_ld.vhdl.snip"
$JASM_HOME/insrom.rb $irom_vhdl_snippet $JASM_HOME/irom.vhd.tpl >$DSTDIR/$TARGET\_irom.vhdl
$JASM_HOME/insrom.rb $irom_ld_vhdl_snippet $JASM_HOME/irom_ld.vhd.tpl >$DSTDIR/$TARGET\_irom_ld.vhdl
$JASM_HOME/insrom.rb $xrom_vhdl_snippet $JASM_HOME/xrom.vhd.tpl >$DSTDIR/$TARGET\_xrom.vhdl
$JASM_HOME/insrom.rb $xrom_ld_vhdl_snippet $JASM_HOME/xrom_ld.vhd.tpl >$DSTDIR/$TARGET\_xrom_ld.vhdl
cat $irom_tcl_snippet > $TARGET.tcl.snip.snip
cat $xrom_tcl_snippet >> $TARGET.tcl.snip.snip
$JASM_HOME/insrom.rb $TARGET.tcl.snip.snip $JASM_HOME/rom.tcl.tpl >$TARGET.tcl
rm -f *.snip
+534
View File
@@ -0,0 +1,534 @@
; -------------------------------------------------
; Constants
; -------------------------------------------------
include "../../../lib/jasm/cregs.inc.jsm"
; XIO registers
reg_led: equ 0x00 ; R/W
reg_pcmmode: equ 0x01 ; R/W
reg_encrypt_src: equ 0x02 ; R/W
reg_cmd_addr: equ 0x04 ; WO
reg_cmd_data: equ 0x06 ; WO
lcd_port: equ 0x08 ; R/W
reg_pcmin_dc_adj_left: equ 0x0D ; R/W
reg_pcmin_dc_adj_right: equ 0x0F ; R/W
reg_encrypt_const0: equ 0x11 ; R/W
reg_encrypt_const1: equ 0x12 ; R/W
reg_encrypt_const2: equ 0x13 ; R/W
reg_encrypt_const3: equ 0x14 ; R/W
reg_stat_addr: equ 0x04 ; RO
reg_stat_data: equ 0x06 ; RO
reg_btn: equ 0x80 ; RO
reg_dip: equ 0x81 ; RO
reg_pcm_left: equ 0x82 ; RO
reg_pcm_right: equ 0x84 ; RO
reg_stat_hw: equ 0xA0 ; RO
reg_beef: equ 0x8E
; reg_stat_hw
; Bits
omsk_ac_rdy: equ 0x01
omsk_cmd_rdy: equ 0x02
omsk_stat_rdy: equ 0x04
; Flag masks
omsk_led0: equ 0x01
omsk_led1: equ 0x02
omsk_led2: equ 0x04
omsk_led3: equ 0x08
amsk_led0: equ 0xFE
amsk_led1: equ 0xFD
amsk_led2: equ 0xFB
amsk_led3: equ 0xF7
omsk_btn_W: equ 0x01
omsk_btn_N: equ 0x02
omsk_btn_E: equ 0x04
omsk_btn_S: equ 0x08
omsk_btn_C: equ 0x10
DC_CORR_PCM: equ 0xFF40
COUNT_RELOAD: equ 0x0200
BTN_BOUNCE_RELOAD: equ 0x0400
; -------------------------------------------------
; On-Chip memory
; -------------------------------------------------
cmem 0
stat_addr: db 2
stat_data: db 2
count: db 2
btn_bounce_cnt: db 2
btn_state: db 1
btn_last: db 1
audio_vol: db 1
cipher_vol: db 1
vol_was_set: db 1
xmem
msg_dsi: dc "DSI GmbH Bremen ", 0
msg_dsi2: dc "October 2007 ", 0
msg_byp1: dc " Encryption ", 0
msg_byp2: dc " Bypass ", 0
msg_ecb: dc "ECB-128 encrypt.", 0
msg_cbc: dc "CBC-128 encrypt.", 0
msg_audio: dc " Audio data ", 0
msg_incdata: dc " Increm. blocks ", 0
msg_setvol: dc "Volume : ", 0
msg_blank16: dc " ", 0
ac97_cfg_addr: dc 0x00, 0x2A ; W: Extended Audio CTRL/STATUS
dc 0x00, 0x1A ; W: Record select
dc 0x00, 0x1C ; W: Record gain
dc 0x00, 0x2C ; W: PCM DAC rate
dc 0x00, 0x32 ; W: PCM ADC rate
dc 0x00, 0x20 ; W: General purpose
dc 0x00, 0x02 ; W: Master volume
dc 0x00, 0x04 ; W: Headphone volume
dc 0x00, 0x18 ; W: PCM volume
ac97_cfg_data: dc 0x01, 0x00 ; W: VRA=1
dc 0x04, 0x04 ; W: Record source = LINE_IN
dc 0x00, 0x00 ; W: Record gain = 0dB
dc 0x80, 0xBB ; W: DAC rate 8000Hz
dc 0x80, 0xBB ; W: ADC rate 8000Hz
; dc 0x80, 0xBB ; W: DAC rate 48000Hz
; dc 0x80, 0xBB ; W: ADC rate 48000Hz
dc 0x00, 0x80 ; W: POP=1
dc 0x00, 0x00 ; W: Master volume = 0dB
dc 0x00, 0x80 ; W: Headphone volume = 0dB, muted
dc 0x0A, 0x0A ; W: PCM volume = -3dB
; -------------------------------------------------
; Program
; -------------------------------------------------
code
org 0x000
reset: jmp init
org 0x001
jmp frame_isr
; -------------------------------------------------
; Main
; -------------------------------------------------
init: mov R0, COUNT_RELOAD'low
mov R1, COUNT_RELOAD'high
movc (count+0), R0
movc (count+1), R1
mov R0, 0x00
xout (reg_led), R0
mov R0, 0xFF
xout (reg_encrypt_const0), R0
mov R0, 0x3b
xout (reg_encrypt_const1), R0
mov R0, 0x9c
xout (reg_encrypt_const2), R0
mov R0, 0x01
xout (reg_encrypt_const3), R0
mov R0, 0x00
movc (btn_state), R0
movc (btn_last), R0
mov R0, BTN_BOUNCE_RELOAD'low
movc (btn_bounce_cnt+0), R0
mov R0, BTN_BOUNCE_RELOAD'high
movc (btn_bounce_cnt+1), R0
mov R0, 0x0A
movc (audio_vol), R0
mov R0, 0x0C
movc (cipher_vol), R0
call LCD_init
; Print Hello world
mov R0, LCD_CMD_CLEAR
call LCD_writecmd
mov R1, msg_dsi
call LCD_putsx
mov R0, LCD_CMD_Z2
call LCD_writecmd
mov R1, msg_dsi2
call LCD_putsx
call delay1s
wait_ac_rdy: xin R0, (reg_stat_hw)
and R0, omsk_ac_rdy
jz wait_ac_rdy
; Send AC97 Status register read-request (CODEC_ID)
mov R0, 0x00 ; Addr(LSW)
mov R1, 0x80 ; Addr(MSW)
mov R2, 0x00 ; Data(LSW)
mov R3, 0x00 ; Data(MSW)
call AC_status_io
movc (stat_addr+0), R0
movc (stat_addr+1), R1
movc (stat_data+0), R2
movc (stat_data+1), R3
; Initialize AC97
; check status
ac97_rdy_lp: mov R0, 0x00
mov R1, 0xA6
mov R2, 0x00
mov R3, 0x00
call AC_status_io
and R2, 0x0F
cmp R2, 0x0F
jne ac97_rdy_lp
mov R15, 9
mov R7, ac97_cfg_addr
mov R8, ac97_cfg_data
ac97_init_lp: movx R0, (R7)
inc R7
movx R1, (R7)
inc R7
movx R2, (R8)
inc R8
movx R3, (R8)
inc R8
call AC_status_io
dec R15
jnz ac97_init_lp
; Set PCM mode
call set_pcm_byp
; PCM-IN: Set DC correction LEFT
mov R0, DC_CORR_PCM'high
xout (reg_pcmin_dc_adj_left+1), R0
mov R0, DC_CORR_PCM'low
xout (reg_pcmin_dc_adj_left+0), R0
; PCM-IN: Set DC correction RIGHT
mov R0, DC_CORR_PCM'high
xout (reg_pcmin_dc_adj_right+1), R0
mov R0, DC_CORR_PCM'low
xout (reg_pcmin_dc_adj_right+0), R0
; Enable Interrupt
mov R0, 0x07
cout (cpu_int_ctrl), R0
; -----------------------------------------------------
; Check buttons
; -----------------------------------------------------
main: movc R0, (btn_state)
tst R0
jnz chk_vol
mov R1, 0
movc (vol_was_set), R1
chk_vol: and R0, 0x10
jz chk_ecb
movc R0, (btn_state)
cmp R0, 0x14
jeq incvol
cmp R0, 0x11
jeq decvol
movc R1, (vol_was_set)
tst R1
jnz main
call set_pcm_byp
jmp main
incvol: movc R0, (audio_vol)
cmp R0, 0x00
jeq main
dec R0
movc (audio_vol), R0
call set_audio_vol
mov R0, LCD_CMD_Z1
call LCD_writecmd
mov R1, msg_blank16
call LCD_putsx
mov R0, LCD_CMD_Z1
call LCD_writecmd
mov R1, msg_setvol
call LCD_putsx
mov R0, 0x1F
movc R1, (audio_vol)
sub R0, R1
call PutHexByte
call delay100ms
call delay100ms
mov R0, 1
movc (vol_was_set), R0
jmp main
decvol: movc R0, (audio_vol)
cmp R0, 0x1F
jeq main
inc R0
movc (audio_vol), R0
call set_pcm_byp
mov R0, LCD_CMD_Z1
call LCD_writecmd
mov R1, msg_blank16
call LCD_putsx
mov R0, LCD_CMD_Z1
call LCD_writecmd
mov R1, msg_setvol
call LCD_putsx
mov R0, 0x1F
movc R1, (audio_vol)
sub R0, R1
call PutHexByte
call delay100ms
call delay100ms
mov R0, 1
movc (vol_was_set), R0
jmp main
chk_ecb: movc R0, (btn_state)
and R0, 0x09
jz chk_cbc
mov R1, 0x01
and R0, 0x01
jne ecb_set_now
mov R1, 0x00
ecb_set_now: xout (reg_encrypt_src), R1
call set_pcm_ecb
jmp main
chk_cbc: movc R0, (btn_state)
and R0, 0x06
jz ex_chk
mov R1, 0x01
and R0, 0x04
jne cbc_set_now
mov R1, 0x00
cbc_set_now: xout (reg_encrypt_src), R1
call set_pcm_cbc
ex_chk: jmp main
; -----------------------------------------------------
set_pcm_byp: ; Set PCM mode
mov R0, 0x00
xout (reg_pcmmode), R0
; Switch on LED
mov R0, 0x06
xout (reg_led), R0
call set_audio_vol
; Set LCD text
mov R0, LCD_CMD_Z1
call LCD_writecmd
mov R1, msg_byp1
call LCD_putsx
mov R0, LCD_CMD_Z2
call LCD_writecmd
mov R1, msg_byp2
call LCD_putsx
ret
set_pcm_ecb: ; Set PCM mode
mov R0, 0x01
xout (reg_pcmmode), R0
; Switch on LED
mov R0, 0x08
xout (reg_led), R0
call set_cipher_vol
; Set LCD text
mov R0, LCD_CMD_Z1
call LCD_writecmd
mov R1, msg_ecb
call LCD_putsx
mov R1, msg_audio
xin R0, (reg_encrypt_src)
and R0, 0x01
jnz ecb_print
mov R1, msg_incdata
ecb_print: mov R0, LCD_CMD_Z2
call LCD_writecmd
call LCD_putsx
ret
set_pcm_cbc: ; Set PCM mode
mov R0, 0x02
xout (reg_pcmmode), R0
; Switch on LED
mov R0, 0x01
xout (reg_led), R0
call set_cipher_vol
; Set LCD text
mov R0, LCD_CMD_Z1
call LCD_writecmd
mov R1, msg_cbc
call LCD_putsx
xin R0, (reg_encrypt_src)
and R0, 0x01
jnz cbc_print
mov R1, msg_incdata
cbc_print: mov R0, LCD_CMD_Z2
call LCD_writecmd
call LCD_putsx
ret
; -------------------------------------------------
set_audio_vol:
; Set PCM volume
mov R0, 0x00 ; Addr(LSW)
mov R1, 0x18 ; Addr(MSW)
movc R2, (audio_vol) ; Data(LSW)
movc R3, (audio_vol) ; Data(MSW)
call AC_status_io
movc (stat_addr+0), R0
movc (stat_addr+1), R1
movc (stat_data+0), R2
movc (stat_data+1), R3
ret
; -------------------------------------------------
set_cipher_vol:
; Set PCM volume
mov R0, 0x00 ; Addr(LSW)
mov R1, 0x18 ; Addr(MSW)
movc R2, (cipher_vol) ; Data(LSW)
movc R3, (cipher_vol) ; Data(MSW)
call AC_status_io
movc (stat_addr+0), R0
movc (stat_addr+1), R1
movc (stat_data+0), R2
movc (stat_data+1), R3
ret
; -------------------------------------------------
frame_isr: push R0
push R1
push R2
push R3
movc R0, (count+0)
movc R1, (count+1)
dec R0
subc R1, 0
movc (count+0), R0
movc (count+1), R1
tst R1
jnz ex_fisr
tst R0
jnz ex_fisr
mov R0, COUNT_RELOAD'low
mov R1, COUNT_RELOAD'high
movc (count+0), R0
movc (count+1), R1
xin R0, (reg_encrypt_const0)
xin R1, (reg_encrypt_const1)
xin R2, (reg_encrypt_const2)
xin R3, (reg_encrypt_const3)
inc R0
addc R1, 0
addc R2, 0
addc R3, 0
xout (reg_encrypt_const0), R0
xout (reg_encrypt_const1), R1
xout (reg_encrypt_const2), R2
xout (reg_encrypt_const3), R3
;Sample switches and buttons
ex_fisr: xin R0, (reg_btn)
movc R1, (btn_bounce_cnt+1)
movc R2, (btn_bounce_cnt+0)
tst R1
jnz dec_bounce
tst R2
jz btn_is_valid
dec_bounce: dec R2
subc R1, 0
movc (btn_bounce_cnt+1), R1
movc (btn_bounce_cnt+0), R2
movc R1, (btn_last)
xin R0, (reg_btn)
movc (btn_last), R0
cmp R0, R1
jeq exit_isr
jmp bounce_wait
btn_is_valid: movc (btn_state), R0
bounce_wait: mov R1, BTN_BOUNCE_RELOAD'high
movc (btn_bounce_cnt+1), R1
mov R1, BTN_BOUNCE_RELOAD'low
movc (btn_bounce_cnt+0), R1
exit_isr: pop R3
pop R2
pop R1
pop R0
reti
; -------------------------------------------------
; AC Read/Write register
; R0 : IN/OUT AC register address 7..0. Written, if cmd was READ (i.e. address[15] = 1)
; R1 : IN/OUT AC register address 15..8. Written, if cmd was READ (i.e. address[15] = 1)
; R2 : IN/OUT AC register data 7..0. Written, if cmd was READ (i.e. address[15] = 1)
; R3 : IN/OUT AC register data 15..8. Written, if cmd was READ (i.e. address[15] = 1)
AC_status_io: call wait_cmd_rdy
xout (reg_cmd_addr+1), R1
xout (reg_cmd_addr+0), R0
xout (reg_cmd_data+1), R3
xout (reg_cmd_data+0), R2
; Check if command was read
and R1, 0x80
jnz wait_read
ret
; Wait for READ command being processed
wait_read: call wait_stat_rdy
; Read AC97 Status register address
xin R1, (reg_stat_addr+1)
xin R0, (reg_stat_addr+0)
; Read AC97 Status register data
xin R3, (reg_stat_data+1)
xin R2, (reg_stat_data+0)
ret
; -------------------------------------------------
wait_cmd_rdy: push R0
wcr_loop: xin R0, (reg_stat_hw)
and R0, omsk_cmd_rdy
jz wcr_loop
pop R0
ret
; -------------------------------------------------
wait_stat_rdy: push R0
wsr_loop: xin R0, (reg_stat_hw)
and R0, omsk_stat_rdy
jz wsr_loop
pop R0
ret
; -------------------------------------------------
; PutHexByte
; R0 : Byte value
PutHexByte: call bin2hex
call LCD_writechar
mov R0, R1
call LCD_writechar
ret
include "../../../lib/jasm/delays.inc.jsm"
include "../../../lib/jasm/lcd.inc.jsm"
include "../../../lib/jasm/utils.inc.jsm"
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -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;
@@ -0,0 +1 @@
work
@@ -0,0 +1,19 @@
vhdl work "W:/vhdl/projects/messe_demo/src/AES_32bit_datapath/aes_gf_2exp8_arith.vhd"
vhdl work "W:/vhdl/projects/messe_demo/src/AES_32bit_datapath/aes_definitions.vhd"
vhdl work "W:/vhdl/projects/messe_demo/src/AES_32bit_datapath/enc/tech_iface_virtex2.vhd"
vhdl work "W:/vhdl/projects/messe_demo/src/AES_32bit_datapath/aes_row_ops.vhd"
vhdl work "W:/vhdl/projects/messe_demo/src/AES_32bit_datapath/aes_column_ops.vhd"
vhdl work "W:/vhdl/projects/messe_demo/src/AES_32bit_datapath/enc/engine_iface.vhd"
vhdl work "W:/vhdl/projects/messe_demo/src/AES_32bit_datapath/aes_common.vhd"
vhdl work "W:/vhdl/projects/messe_demo/src/AES_32bit_datapath/enc/key_schedule_iface.vhd"
vhdl work "W:/vhdl/projects/messe_demo/src/AES_32bit_datapath/enc/dual_sbox_virtex2.vhd"
vhdl work "W:/vhdl/projects/messe_demo/src/AES_32bit_datapath/enc/aux_funcs.vhd"
vhdl work "W:/vhdl/projects/messe_demo/src/AES_32bit_datapath/enc/CBC_128/cbc_mode_iface.vhd"
vhdl work "W:/vhdl/projects/messe_demo/src/AES_32bit_datapath/aes_encryption.vhd"
vhdl work "W:/vhdl/projects/messe_demo/src/AES_32bit_datapath/enc/tech_subkey_memory_virtex2.vhd"
vhdl work "W:/vhdl/projects/messe_demo/src/AES_32bit_datapath/enc/tech_sbox_stage_virtex2.vhd"
vhdl work "W:/vhdl/projects/messe_demo/src/AES_32bit_datapath/enc/key_schedule_128.vhd"
vhdl work "W:/vhdl/projects/messe_demo/src/AES_32bit_datapath/enc/encryption_engine.vhd"
vhdl work "W:/vhdl/projects/messe_demo/src/AES_32bit_datapath/enc/CBC_128/cbc_mode_encryption.vhd"
vhdl work "W:/vhdl/projects/messe_demo/src/AES_32bit_datapath/enc/CBC_128/cbc_core_iface.vhd"
vhdl work "W:/vhdl/projects/messe_demo/src/AES_32bit_datapath/enc/CBC_128/cbc_128_encryption_core.vhd"
@@ -0,0 +1,55 @@
set -tmpdir ./xst/projnav.tmp
set -xsthdpdir ./xst
run
-ifn cbc_128_encryption_core.prj
-ifmt mixed
-ofn cbc_128_encryption_core
-ofmt NGC
-p xc4vsx35-10-ff668
-top cbc_128_encryption_core
-opt_mode Speed
-opt_level 1
-iuc NO
-lso cbc_128_encryption_core.lso
-keep_hierarchy NO
-rtlview Yes
-glob_opt AllClockNets
-read_cores YES
-write_timing_constraints NO
-cross_clock_analysis NO
-hierarchy_separator /
-bus_delimiter <>
-case maintain
-slice_utilization_ratio 100
-dsp_utilization_ratio 100
-verilog2001 YES
-fsm_extract YES -fsm_encoding Auto
-safe_implementation No
-fsm_style lut
-ram_extract Yes
-ram_style Auto
-rom_extract Yes
-mux_style Auto
-decoder_extract YES
-priority_extract YES
-shreg_extract YES
-shift_extract YES
-xor_collapse YES
-rom_style Auto
-mux_extract YES
-resource_sharing YES
-use_dsp48 auto
-iobuf NO
-max_fanout 500
-bufg 32
-bufr 24
-register_duplication YES
-register_balancing No
-slice_packing YES
-optimize_primitives NO
-use_clock_enable Auto
-use_sync_set Auto
-use_sync_reset Auto
-iob auto
-equivalent_register_removal YES
-slice_utilization_ratio_maxmargin 5
@@ -0,0 +1 @@
work
@@ -0,0 +1,19 @@
vhdl work "W:/vhdl/projects/messe_demo/src/AES_32bit_datapath/aes_gf_2exp8_arith.vhd"
vhdl work "W:/vhdl/projects/messe_demo/src/AES_32bit_datapath/aes_definitions.vhd"
vhdl work "W:/vhdl/projects/messe_demo/src/AES_32bit_datapath/enc/tech_iface_virtex2.vhd"
vhdl work "W:/vhdl/projects/messe_demo/src/AES_32bit_datapath/aes_row_ops.vhd"
vhdl work "W:/vhdl/projects/messe_demo/src/AES_32bit_datapath/aes_column_ops.vhd"
vhdl work "W:/vhdl/projects/messe_demo/src/AES_32bit_datapath/enc/engine_iface.vhd"
vhdl work "W:/vhdl/projects/messe_demo/src/AES_32bit_datapath/aes_common.vhd"
vhdl work "W:/vhdl/projects/messe_demo/src/AES_32bit_datapath/enc/key_schedule_iface.vhd"
vhdl work "W:/vhdl/projects/messe_demo/src/AES_32bit_datapath/enc/dual_sbox_virtex2.vhd"
vhdl work "W:/vhdl/projects/messe_demo/src/AES_32bit_datapath/enc/aux_funcs.vhd"
vhdl work "W:/vhdl/projects/messe_demo/src/AES_32bit_datapath/enc/ECB_128/ecb_mode_iface.vhd"
vhdl work "W:/vhdl/projects/messe_demo/src/AES_32bit_datapath/aes_encryption.vhd"
vhdl work "W:/vhdl/projects/messe_demo/src/AES_32bit_datapath/enc/tech_subkey_memory_virtex2.vhd"
vhdl work "W:/vhdl/projects/messe_demo/src/AES_32bit_datapath/enc/tech_sbox_stage_virtex2.vhd"
vhdl work "W:/vhdl/projects/messe_demo/src/AES_32bit_datapath/enc/key_schedule_128.vhd"
vhdl work "W:/vhdl/projects/messe_demo/src/AES_32bit_datapath/enc/encryption_engine.vhd"
vhdl work "W:/vhdl/projects/messe_demo/src/AES_32bit_datapath/enc/ECB_128/ecb_mode_encryption.vhd"
vhdl work "W:/vhdl/projects/messe_demo/src/AES_32bit_datapath/enc/ECB_128/ecb_core_iface.vhd"
vhdl work "W:/vhdl/projects/messe_demo/src/AES_32bit_datapath/enc/ECB_128/ecb_128_encryption_core.vhd"
@@ -0,0 +1,55 @@
set -tmpdir ./xst/projnav.tmp
set -xsthdpdir ./xst
run
-ifn ecb_128_encryption_core.prj
-ifmt mixed
-ofn ecb_128_encryption_core
-ofmt NGC
-p xc4vsx35-10-ff668
-top ecb_128_encryption_core
-opt_mode Speed
-opt_level 1
-iuc NO
-lso ecb_128_encryption_core.lso
-keep_hierarchy NO
-rtlview Yes
-glob_opt AllClockNets
-read_cores YES
-write_timing_constraints NO
-cross_clock_analysis NO
-hierarchy_separator /
-bus_delimiter <>
-case maintain
-slice_utilization_ratio 100
-dsp_utilization_ratio 100
-verilog2001 YES
-fsm_extract YES -fsm_encoding Auto
-safe_implementation No
-fsm_style lut
-ram_extract Yes
-ram_style Auto
-rom_extract Yes
-mux_style Auto
-decoder_extract YES
-priority_extract YES
-shreg_extract YES
-shift_extract YES
-xor_collapse YES
-rom_style Auto
-mux_extract YES
-resource_sharing YES
-use_dsp48 auto
-iobuf NO
-max_fanout 500
-bufg 32
-bufr 24
-register_duplication YES
-register_balancing No
-slice_packing YES
-optimize_primitives NO
-use_clock_enable Auto
-use_sync_set Auto
-use_sync_reset Auto
-iob auto
-equivalent_register_removal YES
-slice_utilization_ratio_maxmargin 5
@@ -0,0 +1 @@
work
@@ -0,0 +1,18 @@
vhdl work "../src/AES_32bit_datapath/aes_definitions.vhd"
vhdl work "../src/cpu_pkg.vhd"
vhdl work "../src/AES_32bit_datapath/enc/tech_iface_virtex2.vhd"
vhdl work "../src/ac97_ctrl/singleshot.vhd"
vhdl work "../src/AES_32bit_datapath/enc/engine_iface.vhd"
vhdl work "../src/test_irom_ld.vhdl"
vhdl work "../src/ac97_ctrl/ac_out.vhd"
vhdl work "../src/ac97_ctrl/ac_in.vhd"
vhdl work "../src/AES_32bit_datapath/enc/key_schedule_iface.vhd"
vhdl work "../src/AES_32bit_datapath/enc/ECB_128/ecb_mode_iface.vhd"
vhdl work "../src/AES_32bit_datapath/enc/CBC_128/cbc_mode_iface.vhd"
vhdl work "../src/test_xrom_ld.vhdl"
vhdl work "../src/lcd_port.vhd"
vhdl work "../src/cpu_embedded.vhd"
vhdl work "../src/ac97_ctrl/ac_io.vhd"
vhdl work "../src/AES_32bit_datapath/enc/ECB_128/ecb_core_iface.vhd"
vhdl work "../src/AES_32bit_datapath/enc/CBC_128/cbc_core_iface.vhd"
vhdl work "../src/demo_top.vhd"
@@ -0,0 +1,33 @@
-w
-g DebugBitstream:No
-g Binary:no
-g CRC:Enable
-g ConfigRate:4
-g CclkPin:PullUp
-g M0Pin:PullUp
-g M1Pin:PullUp
-g M2Pin:PullUp
-g ProgPin:PullUp
-g DonePin:PullUp
-g InitPin:Pullup
-g CsPin:Pullup
-g DinPin:Pullup
-g BusyPin:Pullup
-g RdWrPin:Pullup
-g TckPin:PullUp
-g TdiPin:PullUp
-g TdoPin:PullUp
-g TmsPin:PullUp
-g UnusedPin:PullDown
-g UserID:0xFFFFFFFF
-g DCIUpdateMode:AsRequired
-g StartUpClk:JtagClk
-g DONE_cycle:4
-g GTS_cycle:5
-g GWE_cycle:6
-g LCK_cycle:NoWait
-g Match_cycle:Auto
-g Security:None
-g DonePipe:No
-g DriveDone:No
-g Encrypt:No
@@ -0,0 +1,59 @@
set -tmpdir "./xst/projnav.tmp"
set -xsthdpdir "./xst"
run
-ifn messe_demo.prj
-ifmt mixed
-ofn messe_demo
-ofmt NGC
-p xc4vfx12-10-ff668
-top messe_demo
-opt_mode Speed
-opt_level 1
-power NO
-iuc NO
-lso messe_demo.lso
-keep_hierarchy NO
-rtlview Yes
-glob_opt AllClockNets
-read_cores YES
-write_timing_constraints NO
-cross_clock_analysis NO
-hierarchy_separator /
-bus_delimiter <>
-case maintain
-slice_utilization_ratio 100
-bram_utilization_ratio 100
-dsp_utilization_ratio 100
-verilog2001 YES
-fsm_extract YES -fsm_encoding Auto
-safe_implementation No
-fsm_style lut
-ram_extract Yes
-ram_style Auto
-rom_extract Yes
-mux_style Auto
-decoder_extract YES
-priority_extract YES
-shreg_extract NO
-shift_extract YES
-xor_collapse YES
-rom_style Auto
-auto_bram_packing NO
-mux_extract YES
-resource_sharing YES
-async_to_sync NO
-use_dsp48 auto
-iobuf YES
-max_fanout 500
-bufg 32
-bufr 16
-register_duplication YES
-register_balancing No
-slice_packing YES
-optimize_primitives NO
-use_clock_enable Auto
-use_sync_set Auto
-use_sync_reset Auto
-iob auto
-equivalent_register_removal YES
-slice_utilization_ratio_maxmargin 5
@@ -0,0 +1,18 @@
vhdl work "W:\vhdl\projects\messe_demo\src\AES_32bit_datapath\aes_definitions.vhd"
vhdl work "W:\vhdl\projects\messe_demo\src\cpu_pkg.vhd"
vhdl work "W:\vhdl\projects\messe_demo\src\AES_32bit_datapath\enc\tech_iface_virtex2.vhd"
vhdl work "W:\vhdl\projects\messe_demo\src\ac97_ctrl\singleshot.vhd"
vhdl work "W:\vhdl\projects\messe_demo\src\AES_32bit_datapath\enc\engine_iface.vhd"
vhdl work "W:\vhdl\projects\messe_demo\src\test_irom_ld.vhdl"
vhdl work "W:\vhdl\projects\messe_demo\src\ac97_ctrl\ac_out.vhd"
vhdl work "W:\vhdl\projects\messe_demo\src\ac97_ctrl\ac_in.vhd"
vhdl work "W:\vhdl\projects\messe_demo\src\AES_32bit_datapath\enc\key_schedule_iface.vhd"
vhdl work "W:\vhdl\projects\messe_demo\src\AES_32bit_datapath\enc\ECB_128\ecb_mode_iface.vhd"
vhdl work "W:\vhdl\projects\messe_demo\src\AES_32bit_datapath\enc\CBC_128\cbc_mode_iface.vhd"
vhdl work "W:\vhdl\projects\messe_demo\src\test_xrom_ld.vhdl"
vhdl work "W:\vhdl\projects\messe_demo\src\lcd_port.vhd"
vhdl work "W:\vhdl\projects\messe_demo\src\cpu_embedded.vhd"
vhdl work "W:\vhdl\projects\messe_demo\src\ac97_ctrl\ac_io.vhd"
vhdl work "W:\vhdl\projects\messe_demo\src\AES_32bit_datapath\enc\ECB_128\ecb_core_iface.vhd"
vhdl work "W:\vhdl\projects\messe_demo\src\AES_32bit_datapath\enc\CBC_128\cbc_core_iface.vhd"
vhdl work "W:\vhdl\projects\messe_demo\src\demo_top.vhd"
@@ -0,0 +1,97 @@
#CONFIG STEPPING="ES";
# Bus clock nets
NET "sys_clk_in" TNM_NET = "sys_clk";
NET "ac97_bit_clk" TNM_NET = "ac97_clk";
TIMESPEC "TSSYSCLK" = PERIOD "sys_clk" 9.9 ns HIGH 50 %;
TIMESPEC "TSBITCLK" = PERIOD "ac97_clk" 80 ns HIGH 50 %;
NET sys_clk_in LOC = AE14;
NET sys_clk_in IOSTANDARD = LVCMOS33;
NET sys_rst_n_in LOC = D6;
NET sys_rst_n_in PULLUP;
NET sys_rst_n_in TIG;
////////////////////////////////////////////////////////////////////////////
// AC97 Sound Controller
////////////////////////////////////////////////////////////////////////////
NET ac97_bit_clk LOC = AE10;
NET ac97_bit_clk IOSTANDARD = LVCMOS33;
NET ac97_bit_clk PERIOD = 80;
NET ac97_sdata_in LOC = AD16;
NET ac97_sdata_in IOSTANDARD = LVCMOS33;
NET ac97_reset_n LOC = AD10;
NET ac97_reset_n IOSTANDARD = LVCMOS33;
NET ac97_reset_n TIG;
NET ac97_reset_n SLEW = SLOW;
NET ac97_sdata_out LOC = C8;
NET ac97_sdata_out SLEW = FAST;
NET ac97_sync LOC = D9;
NET ac97_sync SLEW = FAST;
////////////////////////////////////////////////////////////////////////////
// RS-232
////////////////////////////////////////////////////////////////////////////
NET sys_rx LOC = W2;
NET sys_rx IOSTANDARD = LVCMOS33;
NET sys_rx TIG;
NET "sys_tx" LOC = "W1";
NET sys_tx IOSTANDARD = LVCMOS33;
NET "sys_tx" TIG;
////////////////////////////////////////////////////////////////////////////
// Buttons, LEDs, and DIP Switches
////////////////////////////////////////////////////////////////////////////
# GPLED 0-3
NET "sys_led<0>" LOC = "G5"; #GPLED0
NET "sys_led<1>" LOC = "G6"; #GPLED1
NET "sys_led<2>" LOC = "A11"; #GPLED2
NET "sys_led<3>" LOC = "A12"; #GPLED3
# North-East-South-West-Center LEDs
NET "sys_led<4>" LOC = "F9"; # W LED
NET "sys_led<5>" LOC = "E2"; # N LED
NET "sys_led<6>" LOC = "E10"; # E LED
NET "sys_led<7>" LOC = "A5"; # S LED
NET "sys_led<8>" LOC = "C6"; # C LED
NET "sys_led<*>" TIG;
NET "sys_led<*>" SLEW = SLOW;
NET "sys_led<*>" DRIVE = 2;
NET "sys_led<*>" TIG;
# North-East-South-West-Center Buttons
NET "sys_btn<0>" LOC = "E9"; # W Button
NET "sys_btn<1>" LOC = "E7"; # N Button
NET "sys_btn<2>" LOC = "F10"; # E Button
NET "sys_btn<3>" LOC = "A6"; # S Button
NET "sys_btn<4>" LOC = "B6"; # C Button
NET "sys_btn<*>" TIG;
# Dip Switches 1-8
NET "sys_dip<7>" LOC = "U24"; # DIP SW 8
NET "sys_dip<6>" LOC = "U25"; # DIP SW 7
NET "sys_dip<5>" LOC = "V23"; # DIP SW 6
NET "sys_dip<4>" LOC = "U23"; # DIP SW 5
NET "sys_dip<3>" LOC = "U26"; # DIP SW 4
NET "sys_dip<2>" LOC = "T26"; # DIP SW 3
NET "sys_dip<1>" LOC = "R19"; # DIP SW 2
NET "sys_dip<0>" LOC = "R20"; # DIP SW 1
NET "sys_dip<*>" IOSTANDARD = LVCMOS33;
NET "sys_dip<*>" TIG;
////////////////////////////////////////////////////////////////////////////
// LCD
////////////////////////////////////////////////////////////////////////////
NET sys_lcd_e LOC = AE13; # LCD_E
NET sys_lcd_e IOSTANDARD = LVCMOS33;
NET sys_lcd_e TIG;
NET sys_lcd_rs LOC = AC17; # LCD_RS
NET sys_lcd_rs IOSTANDARD = LVCMOS33;
NET sys_lcd_rs TIG;
NET sys_lcd_rw LOC = AB17; # LCD_RW
NET sys_lcd_rw IOSTANDARD = LVCMOS33;
NET sys_lcd_rw TIG;
NET sys_lcd_d<3> LOC = AF12; # LCD_DB7
NET sys_lcd_d<2> LOC = AE12; # LCD_DB6
NET sys_lcd_d<1> LOC = AC10; # LCD_DB5
NET sys_lcd_d<0> LOC = AB10; # LCD_DB4
NET sys_lcd_d<*> IOSTANDARD = LVCMOS33;
NET sys_lcd_d<*> TIG;
NET sys_lcd_d<*> PULLDOWN;
@@ -0,0 +1,97 @@
#CONFIG STEPPING="ES";
# Bus clock nets
NET "sys_clk_in" TNM_NET = "sys_clk";
NET "ac97_bit_clk" TNM_NET = "ac97_clk";
TIMESPEC "TSSYSCLK" = PERIOD "sys_clk" 9.9 ns HIGH 50 %;
TIMESPEC "TSBITCLK" = PERIOD "ac97_clk" 80 ns HIGH 50 %;
NET sys_clk_in LOC = AE14;
NET sys_clk_in IOSTANDARD = LVCMOS33;
NET sys_rst_n_in LOC = D6;
NET sys_rst_n_in PULLUP;
NET sys_rst_n_in TIG;
////////////////////////////////////////////////////////////////////////////
// AC97 Sound Controller
////////////////////////////////////////////////////////////////////////////
NET ac97_bit_clk LOC = AE10;
NET ac97_bit_clk IOSTANDARD = LVCMOS33;
NET ac97_bit_clk PERIOD = 80;
NET ac97_sdata_in LOC = AD16;
NET ac97_sdata_in IOSTANDARD = LVCMOS33;
NET ac97_reset_n LOC = AD10;
NET ac97_reset_n IOSTANDARD = LVCMOS33;
NET ac97_reset_n TIG;
NET ac97_reset_n SLEW = SLOW;
NET ac97_sdata_out LOC = C8;
NET ac97_sdata_out SLEW = FAST;
NET ac97_sync LOC = D9;
NET ac97_sync SLEW = FAST;
////////////////////////////////////////////////////////////////////////////
// RS-232
////////////////////////////////////////////////////////////////////////////
NET sys_rx LOC = W2;
NET sys_rx IOSTANDARD = LVCMOS33;
NET sys_rx TIG;
NET "sys_tx" LOC = "W1";
NET sys_tx IOSTANDARD = LVCMOS33;
NET "sys_tx" TIG;
////////////////////////////////////////////////////////////////////////////
// Buttons, LEDs, and DIP Switches
////////////////////////////////////////////////////////////////////////////
# GPLED 0-3
NET "sys_led<0>" LOC = "G5"; #GPLED0
NET "sys_led<1>" LOC = "G6"; #GPLED1
NET "sys_led<2>" LOC = "A11"; #GPLED2
NET "sys_led<3>" LOC = "A12"; #GPLED3
# North-East-South-West-Center LEDs
NET "sys_led<4>" LOC = "F9"; # W LED
NET "sys_led<5>" LOC = "E2"; # N LED
NET "sys_led<6>" LOC = "E10"; # E LED
NET "sys_led<7>" LOC = "A5"; # S LED
NET "sys_led<8>" LOC = "C6"; # C LED
NET "sys_led<*>" TIG;
NET "sys_led<*>" SLEW = SLOW;
NET "sys_led<*>" DRIVE = 2;
NET "sys_led<*>" TIG;
# North-East-South-West-Center Buttons
NET "sys_btn<0>" LOC = "E9"; # W Button
NET "sys_btn<1>" LOC = "E7"; # N Button
NET "sys_btn<2>" LOC = "F10"; # E Button
NET "sys_btn<3>" LOC = "A6"; # S Button
NET "sys_btn<4>" LOC = "B6"; # C Button
NET "sys_btn<*>" TIG;
# Dip Switches 1-8
#NET "sys_dip<7>" LOC = "U24"; # DIP SW 8
#NET "sys_dip<6>" LOC = "U25"; # DIP SW 7
#NET "sys_dip<5>" LOC = "V23"; # DIP SW 6
#NET "sys_dip<4>" LOC = "U23"; # DIP SW 5
#NET "sys_dip<3>" LOC = "U26"; # DIP SW 4
#NET "sys_dip<2>" LOC = "T26"; # DIP SW 3
#NET "sys_dip<1>" LOC = "R19"; # DIP SW 2
#NET "sys_dip<0>" LOC = "R20"; # DIP SW 1
#NET "sys_dip<*>" IOSTANDARD = LVCMOS33;
#NET "sys_dip<*>" TIG;
////////////////////////////////////////////////////////////////////////////
// LCD
////////////////////////////////////////////////////////////////////////////
NET sys_lcd_e LOC = AE13; # LCD_E
NET sys_lcd_e IOSTANDARD = LVCMOS33;
NET sys_lcd_e TIG;
NET sys_lcd_rs LOC = AC17; # LCD_RS
NET sys_lcd_rs IOSTANDARD = LVCMOS33;
NET sys_lcd_rs TIG;
NET sys_lcd_rw LOC = AB17; # LCD_RW
NET sys_lcd_rw IOSTANDARD = LVCMOS33;
NET sys_lcd_rw TIG;
NET sys_lcd_d<3> LOC = AF12; # LCD_DB7
NET sys_lcd_d<2> LOC = AE12; # LCD_DB6
NET sys_lcd_d<1> LOC = AC10; # LCD_DB5
NET sys_lcd_d<0> LOC = AB10; # LCD_DB4
NET sys_lcd_d<*> IOSTANDARD = LVCMOS33;
NET sys_lcd_d<*> TIG;
NET sys_lcd_d<*> PULLDOWN;