diff --git a/projects/vga_ctrl/asm/main.jsm b/projects/vga_ctrl/asm/main.jsm
new file mode 100644
index 0000000..ae9fc24
--- /dev/null
+++ b/projects/vga_ctrl/asm/main.jsm
@@ -0,0 +1,171 @@
+; -------------------------------------------------
+; Constants
+; -------------------------------------------------
+
+; C-register
+cpu_revision: equ 0x00 ; RO
+cpu_control: equ 0x01 ; R/W
+cpu_status: equ 0x02 ; RO
+cpu_int_ctrl: equ 0x03 ; R/W
+
+; X-registers
+reg_btn: equ 0x00 ; RO
+reg_led: equ 0x01 ; RW
+reg_dip: equ 0x05 ; RO
+reg_hwstat: equ 0x0B ; RO
+
+reg_cred: equ 0x02 ; RW
+reg_cgrn: equ 0x03 ; RW
+reg_cblu: equ 0x04 ; RW
+reg_cg_char_addr: equ 0x08 ; RW
+reg_cg_line_addr: equ 0x09 ; RW
+reg_cg_data: equ 0x0A ; RW
+reg_cg_ctrl: equ 0x0B ; WO
+
+; External RAM/ROM
+ xmem
+crlf: dc 13, 10, 0
+msg_txt1: dc "J-CPU V1.", 0
+msg_txt2: dc "Ready.", 13, 10, 0
+msg_txt3: dc "Mimi ist eine liebe Katze !!!", 13, 10, 0
+
+; -------------------------------------------------
+; Program
+; -------------------------------------------------
+ code
+reset: jmp init
+
+ org 0x001
+; nop
+ reti
+
+; -------------------------------------------------
+; Main
+; -------------------------------------------------
+init: xin R0, (reg_hwstat)
+ xout (reg_led), R0
+ and R0, 0x01
+ jz init
+
+ xin R0, (reg_hwstat)
+ xout (reg_led), R0
+
+loop: call cg_wait_rdy
+ call cg_clr_screen
+
+ mov R0, 0
+ mov R1, 0
+ call cg_set_addr
+
+ call delay1s
+
+ ; Print line 0
+ mov R1, msg_txt1
+ call cg_clr_puts
+ cin R0, (cpu_revision)
+ add R0, 0x30
+ call cg_putchar
+ mov R1, crlf
+ call cg_puts
+
+ call delay1s
+ call delay1s
+
+ ; Print line 1
+ mov R1, msg_txt2
+ call cg_clr_puts
+
+ call delay100ms
+
+ ; Print line 3
+ mov R0, 0
+ mov R1, 3
+ call cg_set_addr
+
+ mov R1, msg_txt3
+ call cg_clr_puts
+
+ call delay1s
+
+ mov R0, 0
+ mov R1, 10
+ call cg_set_addr
+
+ mov R15, 160
+fill_lp: tst R15
+ jz ex_fill
+ dec R15
+ mov R1, 48
+ct_loop: cmp R1, 58
+ jeq ex_ct
+ mov R0, R1
+ inc R1
+ call cg_putchar
+ jmp ct_loop
+ex_ct: jmp fill_lp
+ex_fill:
+ call delay1s
+
+ ; Clear line at (R1)
+ mov R0, 0
+ mov R1, 12
+ call cg_set_addr
+ call cg_clr_line
+
+ mov R0, 0
+ mov R1, 30
+ call cg_set_addr
+
+ ; Print line 1
+ mov R1, msg_txt2
+ call cg_clr_puts
+
+ call delay100ms
+
+ ; Print line 1
+ mov R1, msg_txt2
+ call cg_clr_puts
+
+ call delay100ms
+
+ ; Print line 1
+ mov R1, msg_txt2
+ call cg_clr_puts
+
+ call delay100ms
+
+ ; Print line 1
+ mov R1, msg_txt2
+ call cg_clr_puts
+
+ call delay100ms
+
+ ; Print line 1
+ mov R1, msg_txt2
+ call cg_clr_puts
+
+ call delay100ms
+
+ ; Print line 1
+ mov R1, msg_txt2
+ call cg_clr_puts
+
+ call delay100ms
+
+ ; Print line 1
+ mov R1, msg_txt2
+ call cg_clr_puts
+
+ call delay100ms
+
+ ; Print line 1
+ mov R1, msg_txt2
+ call cg_clr_puts
+
+ call delay1s
+
+ jmp loop
+
+; -------------------------------------------------
+include "../../../lib/jasm/delays.inc.jsm"
+include "../../../lib/jasm/cg.inc.jsm"
diff --git a/projects/vga_ctrl/asm/main.tcl b/projects/vga_ctrl/asm/main.tcl
new file mode 100644
index 0000000..a31944c
--- /dev/null
+++ b/projects/vga_ctrl/asm/main.tcl
@@ -0,0 +1,634 @@
+# ----------------------------------------------------------------------
+# Project: JCPU, a portable 8-bit RISC CPU written in VHDL
+# This file: The ROM file for upload to target over JTAG
+#
+# 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 .
+#
+# For questions and ideas, please contact the author at jens@jayfield.org
+#
+# ---------------------------------------------------------------------
+
+# ---------------------------------------------------------------------
+# For Chipscope 9.1
+# ---------------------------------------------------------------------
+# Source JTAG/TCL frame work
+cd $env(CHIPSCOPE)\\bin\\nt
+source csejtag.tcl
+
+namespace import ::chipscope::*
+
+# Platform USB Cable
+set PLATFORM_USB_CABLE_ARGS [list "port=USB2" "frequency=6000000"]
+# frequency="24000000 | 12000000 | 6000000 | 3000000 | 1500000 | 750000"
+
+# Create session
+set handle [::chipscope::csejtag_session create 0]
+
+# Open JTAG and lock
+set open_result [::chipscope::csejtag_target open $handle $CSEJTAG_TARGET_PLATFORMUSB 0 $PLATFORM_USB_CABLE_ARGS]
+set lock_result [::chipscope::csejtag_target lock $handle 1000]
+
+set devlist [::chipscope::csejtag_tap autodetect_chain $handle $CSEJTAG_SCAN_DEFAULT]
+
+# Get Device ID
+set devtype "Virtex-4SX"
+set devid 2
+set irlength [::chipscope::csejtag_tap get_irlength $handle $devid]
+set idcode [::chipscope::csejtag_tap get_device_idcode $handle $devid]
+
+set CSE_OP $CSEJTAG_SHIFT_READWRITE
+set CSE_ES $CSEJTAG_RUN_TEST_IDLE
+
+# Write Program
+# JASM_ROM_INSERT_HERE
+# Assembled from main.jsm
+# ---------------------------------------------------------------
+# Shift the USER2 Instruction (b1111000010) into the Instruction Register of FPGA
+# User 1
+set result [::chipscope::csejtag_tap shift_device_ir $handle $devid $CSE_OP $CSE_ES 0 $irlength "3C2"]
+
+# 0x000: JMP 0x002
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00030002"
+
+# 0x001: RETI
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0013F000"
+
+# 0x002: XIN R00, (0x0B)
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "002280B0"
+
+# 0x003: XOUT (0x01), R00
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00324010"
+
+# 0x004: AND R00, 0x01
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00419010"
+
+# 0x005: JZ 0x002
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00531002"
+
+# 0x006: XIN R00, (0x0B)
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "006280B0"
+
+# 0x007: XOUT (0x01), R00
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00724010"
+
+# 0x008: CALL 0x06E
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0083B06E"
+
+# 0x009: CALL 0x055
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0093B055"
+
+# 0x00A: MOV R00, 0x00
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00A03000"
+
+# 0x00B: MOV R01, 0x00
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00B03001"
+
+# 0x00C: CALL 0x05A
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00C3B05A"
+
+# 0x00D: CALL 0x074
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00D3B074"
+
+# 0x00E: MOV R00, 0x03
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00E03030"
+
+# 0x00F: CALL 0x06B
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "00F3B06B"
+
+# 0x010: CIN R00, (0x00)
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "01029000"
+
+# 0x011: ADD R00, 0x30
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "01111300"
+
+# 0x012: CALL 0x05E
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0123B05E"
+
+# 0x013: MOV R00, 0x00
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "01303000"
+
+# 0x014: CALL 0x061
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0143B061"
+
+# 0x015: CALL 0x074
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0153B074"
+
+# 0x016: CALL 0x074
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0163B074"
+
+# 0x017: MOV R00, 0x0D
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "017030D0"
+
+# 0x018: CALL 0x06B
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0183B06B"
+
+# 0x019: CALL 0x07B
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0193B07B"
+
+# 0x01A: MOV R00, 0x00
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "01A03000"
+
+# 0x01B: MOV R01, 0x03
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "01B03031"
+
+# 0x01C: CALL 0x05A
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "01C3B05A"
+
+# 0x01D: MOV R00, 0x16
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "01D03160"
+
+# 0x01E: CALL 0x06B
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "01E3B06B"
+
+# 0x01F: CALL 0x074
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "01F3B074"
+
+# 0x020: MOV R00, 0x00
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "02003000"
+
+# 0x021: MOV R01, 0x0A
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "021030A1"
+
+# 0x022: CALL 0x05A
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0223B05A"
+
+# 0x023: MOV R15, 0xA0
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "02303A0F"
+
+# 0x024: TST R15
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0240F00F"
+
+# 0x025: JZ 0x02F
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0253102F"
+
+# 0x026: DEC R15
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0261501F"
+
+# 0x027: MOV R01, 0x30
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "02703301"
+
+# 0x028: CMP R01, 0x3A
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0280F3A1"
+
+# 0x029: JEQ 0x02E
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0293902E"
+
+# 0x02A: MOV R00, R01
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "02A02010"
+
+# 0x02B: INC R01
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "02B11011"
+
+# 0x02C: CALL 0x05E
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "02C3B05E"
+
+# 0x02D: JMP 0x028
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "02D30028"
+
+# 0x02E: JMP 0x024
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "02E30024"
+
+# 0x02F: CALL 0x074
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "02F3B074"
+
+# 0x030: MOV R00, 0x00
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "03003000"
+
+# 0x031: MOV R01, 0x0C
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "031030C1"
+
+# 0x032: CALL 0x05A
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0323B05A"
+
+# 0x033: CALL 0x050
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0333B050"
+
+# 0x034: MOV R00, 0x00
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "03403000"
+
+# 0x035: MOV R01, 0x1E
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "035031E1"
+
+# 0x036: CALL 0x05A
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0363B05A"
+
+# 0x037: MOV R00, 0x0D
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "037030D0"
+
+# 0x038: CALL 0x06B
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0383B06B"
+
+# 0x039: CALL 0x07B
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0393B07B"
+
+# 0x03A: MOV R00, 0x0D
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "03A030D0"
+
+# 0x03B: CALL 0x06B
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "03B3B06B"
+
+# 0x03C: CALL 0x07B
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "03C3B07B"
+
+# 0x03D: MOV R00, 0x0D
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "03D030D0"
+
+# 0x03E: CALL 0x06B
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "03E3B06B"
+
+# 0x03F: CALL 0x07B
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "03F3B07B"
+
+# 0x040: MOV R00, 0x0D
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "040030D0"
+
+# 0x041: CALL 0x06B
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0413B06B"
+
+# 0x042: CALL 0x07B
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0423B07B"
+
+# 0x043: MOV R00, 0x0D
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "043030D0"
+
+# 0x044: CALL 0x06B
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0443B06B"
+
+# 0x045: CALL 0x07B
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0453B07B"
+
+# 0x046: MOV R00, 0x0D
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "046030D0"
+
+# 0x047: CALL 0x06B
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0473B06B"
+
+# 0x048: CALL 0x07B
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0483B07B"
+
+# 0x049: MOV R00, 0x0D
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "049030D0"
+
+# 0x04A: CALL 0x06B
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "04A3B06B"
+
+# 0x04B: CALL 0x07B
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "04B3B07B"
+
+# 0x04C: MOV R00, 0x0D
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "04C030D0"
+
+# 0x04D: CALL 0x06B
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "04D3B06B"
+
+# 0x04E: CALL 0x074
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "04E3B074"
+
+# 0x04F: JMP 0x008
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "04F30008"
+
+# 0x050: PUSH R00
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0503C000"
+
+# 0x051: MOV R00, 0x02
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "05103020"
+
+# 0x052: XOUT (0x0B), R00
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "052240B0"
+
+# 0x053: POP R00
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0533D000"
+
+# 0x054: RET
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0543E000"
+
+# 0x055: PUSH R00
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0553C000"
+
+# 0x056: MOV R00, 0x01
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "05603010"
+
+# 0x057: XOUT (0x0B), R00
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "057240B0"
+
+# 0x058: POP R00
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0583D000"
+
+# 0x059: RET
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0593E000"
+
+# 0x05A: CALL 0x06E
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "05A3B06E"
+
+# 0x05B: XOUT (0x09), R01
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "05B24091"
+
+# 0x05C: XOUT (0x08), R00
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "05C24080"
+
+# 0x05D: RET
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "05D3E000"
+
+# 0x05E: CALL 0x06E
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "05E3B06E"
+
+# 0x05F: XOUT (0x0A), R00
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "05F240A0"
+
+# 0x060: RET
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0603E000"
+
+# 0x061: PUSH R01
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0613C001"
+
+# 0x062: MOV R01, R00
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "06202001"
+
+# 0x063: MOVX R00, (R01)
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "06304010"
+
+# 0x064: INC R01
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "06411011"
+
+# 0x065: TST R00
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0650F000"
+
+# 0x066: JZ 0x069
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "06631069"
+
+# 0x067: CALL 0x05E
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0673B05E"
+
+# 0x068: JMP 0x063
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "06830063"
+
+# 0x069: POP R01
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0693D001"
+
+# 0x06A: RET
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "06A3E000"
+
+# 0x06B: CALL 0x050
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "06B3B050"
+
+# 0x06C: CALL 0x061
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "06C3B061"
+
+# 0x06D: RET
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "06D3E000"
+
+# 0x06E: PUSH R00
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "06E3C000"
+
+# 0x06F: XIN R00, (0x0B)
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "06F280B0"
+
+# 0x070: AND R00, 0x02
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "07019020"
+
+# 0x071: JZ 0x06F
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0713106F"
+
+# 0x072: POP R00
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0723D000"
+
+# 0x073: RET
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0733E000"
+
+# 0x074: PUSH R15
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0743C00F"
+
+# 0x075: MOV R15, 0x0A
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "075030AF"
+
+# 0x076: CALL 0x07B
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0763B07B"
+
+# 0x077: DEC R15
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0771501F"
+
+# 0x078: JNZ 0x076
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "07832076"
+
+# 0x079: POP R15
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0793D00F"
+
+# 0x07A: RET
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "07A3E000"
+
+# 0x07B: PUSH R15
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "07B3C00F"
+
+# 0x07C: MOV R15, 0x0A
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "07C030AF"
+
+# 0x07D: CALL 0x082
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "07D3B082"
+
+# 0x07E: DEC R15
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "07E1501F"
+
+# 0x07F: JNZ 0x07D
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "07F3207D"
+
+# 0x080: POP R15
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0803D00F"
+
+# 0x081: RET
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0813E000"
+
+# 0x082: PUSH R15
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0823C00F"
+
+# 0x083: MOV R15, 0x0A
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "083030AF"
+
+# 0x084: CALL 0x089
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0843B089"
+
+# 0x085: DEC R15
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0851501F"
+
+# 0x086: JNZ 0x084
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "08632084"
+
+# 0x087: POP R15
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0873D00F"
+
+# 0x088: RET
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0883E000"
+
+# 0x089: PUSH R15
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0893C00F"
+
+# 0x08A: MOV R15, 0x0A
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "08A030AF"
+
+# 0x08B: CALL 0x090
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "08B3B090"
+
+# 0x08C: DEC R15
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "08C1501F"
+
+# 0x08D: JNZ 0x08B
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "08D3208B"
+
+# 0x08E: POP R15
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "08E3D00F"
+
+# 0x08F: RET
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "08F3E000"
+
+# 0x090: PUSH R15
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0903C00F"
+
+# 0x091: MOV R15, 0x0A
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "091030AF"
+
+# 0x092: CALL 0x097
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0923B097"
+
+# 0x093: DEC R15
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0931501F"
+
+# 0x094: JNZ 0x092
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "09432092"
+
+# 0x095: POP R15
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0953D00F"
+
+# 0x096: RET
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0963E000"
+
+# 0x097: PUSH R15
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0973C00F"
+
+# 0x098: MOV R15, 0x63
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0980363F"
+
+# 0x099: NOP
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "09900000"
+
+# 0x09A: NOP
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "09A00000"
+
+# 0x09B: NOP
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "09B00000"
+
+# 0x09C: DEC R15
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "09C1501F"
+
+# 0x09D: JNZ 0x099
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "09D32099"
+
+# 0x09E: POP R15
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "09E3D00F"
+
+# 0x09F: RET
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "09F3E000"
+
+# 0x0A0: PUSH R15
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0A03C00F"
+
+# 0x0A1: MOV R15, 0x09
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0A10309F"
+
+# 0x0A2: NOP
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0A200000"
+
+# 0x0A3: NOP
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0A300000"
+
+# 0x0A4: NOP
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0A400000"
+
+# 0x0A5: DEC R15
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0A51501F"
+
+# 0x0A6: JNZ 0x0A2
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0A6320A2"
+
+# 0x0A7: POP R15
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0A73D00F"
+
+# 0x0A8: RET
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 32 "0A83E000"
+
+# Assembled from main.jsm
+# ---------------------------------------------------------------
+# Shift the USER2 Instruction (b1111000011) into the Instruction Register of FPGA
+# User 2
+set result [::chipscope::csejtag_tap shift_device_ir $handle $devid $CSE_OP $CSE_ES 0 $irlength "3C3"]
+
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "000D"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "010A"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "0200"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "034A"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "042D"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "0543"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "0650"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "0755"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "0820"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "0956"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "0A31"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "0B2E"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "0C00"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "0D52"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "0E65"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "0F61"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "1064"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "1179"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "122E"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "130D"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "140A"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "1500"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "164D"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "1769"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "186D"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "1969"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "1A20"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "1B69"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "1C73"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "1D74"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "1E20"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "1F65"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "2069"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "216E"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "2265"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "2320"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "246C"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "2569"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "2665"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "2762"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "2865"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "2920"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "2A4B"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "2B61"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "2C74"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "2D7A"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "2E65"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "2F20"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "3021"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "3121"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "3221"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "330D"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "340A"
+::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 16 "3500"
+
+::chipscope::csejtag_target unlock $handle
+::chipscope::csejtag_target close $handle
+::chipscope::csejtag_session destroy $handle
+exit
diff --git a/projects/vga_ctrl/asm/make b/projects/vga_ctrl/asm/make
new file mode 100644
index 0000000..e7f598f
--- /dev/null
+++ b/projects/vga_ctrl/asm/make
@@ -0,0 +1,50 @@
+#!/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 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 .
+#
+# 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
diff --git a/projects/vga_ctrl/sim/compile_simprim.do b/projects/vga_ctrl/sim/compile_simprim.do
new file mode 100644
index 0000000..f61b10c
--- /dev/null
+++ b/projects/vga_ctrl/sim/compile_simprim.do
@@ -0,0 +1,6 @@
+vlib simprim
+
+vcom -93 -work simprim F:/Xilinx9/vhdl/src/simprims/simprim_Vcomponents_mti.vhd
+vcom -93 -work simprim F:/Xilinx9/vhdl/src/simprims/simprim_Vpackage_mti.vhd
+vcom -93 -work simprim F:/Xilinx9/vhdl/src/simprims/simprim_SMODEL_mti.vhd
+vcom -93 -work simprim F:/Xilinx9/vhdl/src/simprims/simprim_VITAL_mti.vhd
diff --git a/projects/vga_ctrl/sim/compile_unisim.do b/projects/vga_ctrl/sim/compile_unisim.do
new file mode 100644
index 0000000..db04bed
--- /dev/null
+++ b/projects/vga_ctrl/sim/compile_unisim.do
@@ -0,0 +1,6 @@
+vlib unisim
+
+vcom -93 -work unisim F:/Xilinx9/vhdl/src/unisims/unisim_vpkg.vhd
+vcom -93 -work unisim F:/Xilinx9/vhdl/src/unisims/unisim_vcomp.vhd
+vcom -93 -work unisim F:/Xilinx9/vhdl/src/unisims/unisim_smodel.vhd
+vcom -93 -work unisim F:/Xilinx9/vhdl/src/unisims/unisim_vital.vhd
diff --git a/projects/vga_ctrl/sim/tb_vga_ctrl.fdo b/projects/vga_ctrl/sim/tb_vga_ctrl.fdo
new file mode 100644
index 0000000..887cd97
--- /dev/null
+++ b/projects/vga_ctrl/sim/tb_vga_ctrl.fdo
@@ -0,0 +1,29 @@
+## NOTE: Do not edit this file.
+## Autogenerated by ProjNav (creatfdo.tcl) on Thu Jul 06 20:49:07 Westeuropäische Sommerzeit 2006
+##
+vlib work
+vcom -explicit -93 "../../../lib/VGA_ctrl/src/vga_types.vhd"
+vcom -explicit -93 "../../../lib/VGA_ctrl/src/dpram.vhd"
+vcom -explicit -93 "../../../lib/CPUs/JCpu/src/core/cpu_pkg.vhd"
+vcom -explicit -93 "../../../lib/FIFO/src/fifo_ctrl_pkg.vhd"
+vcom -explicit -93 "../../../lib/FIFO/src/gray_counter.vhd"
+vcom -explicit -93 "../../../lib/FIFO/src/async_fifo_ctrl.vhd"
+vcom -explicit -93 "../src/main_xrom.vhdl"
+vcom -explicit -93 "../src/main_irom.vhdl"
+vcom -explicit -93 "../src/cpu_embedded.vhd"
+vcom -explicit -93 "../../../lib/VGA_ctrl/src/clkgen_virtex4.vhd"
+vcom -explicit -93 "../../../lib/VGA_ctrl/src/linefifo.vhd"
+vcom -explicit -93 "../../../lib/VGA_ctrl/src/char_gen.vhd"
+vcom -explicit -93 "../../../lib/VGA_ctrl/src/vga_sync.vhd"
+vcom -explicit -93 "../../../lib/VGA_ctrl/src/vga_timing.vhd"
+vcom -explicit -93 "../../../lib/VGA_ctrl/src/vga_backend.vhd"
+vcom -explicit -93 "../../../lib/VGA_ctrl/src/fonts/char_rom_c64.vhd"
+vcom -explicit -93 "../src/vga_ctrl_top.vhd"
+vcom -explicit -93 "../src/tb_vga_ctrl.vhd"
+vsim -t 1ps -lib work tb_vga_ctrl_vhd
+view wave
+do {tb_vga_ctrl.wdo}
+view structure
+view signals
+
+run 150us
diff --git a/projects/vga_ctrl/sim/tb_vga_ctrl.wdo b/projects/vga_ctrl/sim/tb_vga_ctrl.wdo
new file mode 100644
index 0000000..96ce182
--- /dev/null
+++ b/projects/vga_ctrl/sim/tb_vga_ctrl.wdo
@@ -0,0 +1,47 @@
+onerror {resume}
+quietly WaveActivateNextPane {} 0
+add wave -noupdate -format Logic /tb_vga_ctrl_vhd/uut/rst
+add wave -noupdate -format Logic /tb_vga_ctrl_vhd/uut/sys_vga_sync_n
+add wave -noupdate -format Logic /tb_vga_ctrl_vhd/uut/sys_rstn_in
+add wave -noupdate -format Logic /tb_vga_ctrl_vhd/uut/sys_vga_hsync
+add wave -noupdate -format Logic /tb_vga_ctrl_vhd/uut/sys_vga_vsync
+add wave -noupdate -format Literal -radix hexadecimal /tb_vga_ctrl_vhd/sys_vga_red
+add wave -noupdate -format Literal -radix hexadecimal /tb_vga_ctrl_vhd/sys_vga_green
+add wave -noupdate -format Literal -radix hexadecimal /tb_vga_ctrl_vhd/sys_vga_blue
+add wave -noupdate -format Logic /tb_vga_ctrl_vhd/uut/scan_rdy_h
+add wave -noupdate -format Logic /tb_vga_ctrl_vhd/uut/scan_rdy_v
+add wave -noupdate -format Logic /tb_vga_ctrl_vhd/uut/scan_rdy
+add wave -noupdate -format Logic /tb_vga_ctrl_vhd/uut/hsync
+add wave -noupdate -format Logic /tb_vga_ctrl_vhd/uut/vsync
+add wave -noupdate -format Literal /tb_vga_ctrl_vhd/uut/src_pos_x
+add wave -noupdate -format Literal /tb_vga_ctrl_vhd/uut/src_pos_y
+add wave -noupdate -format Logic /tb_vga_ctrl_vhd/uut/inst_vga_backend/scan_enable
+add wave -noupdate -format Logic /tb_vga_ctrl_vhd/uut/inst_vga_backend/fifo_empty
+add wave -noupdate -format Literal /tb_vga_ctrl_vhd/uut/inst_vga_backend/inst_vga_timing/inst_vga_sync_v/count
+add wave -noupdate -format Logic /tb_vga_ctrl_vhd/uut/inst_vga_backend/is_scan
+add wave -noupdate -divider {Buffer Ctrl}
+add wave -noupdate -format Logic /tb_vga_ctrl_vhd/uut/sys_clk_in
+add wave -noupdate -format Logic /tb_vga_ctrl_vhd/uut/vga_clk
+add wave -noupdate -format Logic /tb_vga_ctrl_vhd/uut/scan_enable
+add wave -noupdate -format Logic /tb_vga_ctrl_vhd/uut/fifo_full
+add wave -noupdate -format Literal /tb_vga_ctrl_vhd/uut/color_w
+add wave -noupdate -format Logic /tb_vga_ctrl_vhd/uut/color_we
+add wave -noupdate -format Literal /tb_vga_ctrl_vhd/uut/src_pos_x
+add wave -noupdate -format Literal /tb_vga_ctrl_vhd/uut/src_pos_y
+add wave -noupdate -divider {Cell generator}
+TreeUpdate [SetDefaultTree]
+WaveRestoreCursors {{Cursor 1} {219014 ps} 0}
+configure wave -namecolwidth 183
+configure wave -valuecolwidth 100
+configure wave -justifyvalue left
+configure wave -signalnamewidth 1
+configure wave -snapdistance 10
+configure wave -datasetprefix 0
+configure wave -rowmargin 4
+configure wave -childrowmargin 2
+configure wave -gridoffset 0
+configure wave -gridperiod 100
+configure wave -griddelta 40
+configure wave -timeline 1
+update
+WaveRestoreZoom {0 ps} {1437573 ps}
diff --git a/projects/vga_ctrl/src/cpu_embedded.vhd b/projects/vga_ctrl/src/cpu_embedded.vhd
new file mode 100644
index 0000000..22e3a4a
--- /dev/null
+++ b/projects/vga_ctrl/src/cpu_embedded.vhd
@@ -0,0 +1,106 @@
+-------------------------------------------------------------------------
+-- 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 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 .
+--
+-- 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 irom_data : unsigned (IMEM_DATA_WIDTH-1 downto 0);
+ signal irom_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 => irom_data,
+ instr_addr => irom_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 => irom_addr,
+ dout => irom_data
+ );
+
+end rtl;
diff --git a/projects/vga_ctrl/src/cpu_pkg.vhd b/projects/vga_ctrl/src/cpu_pkg.vhd
new file mode 100644
index 0000000..0224726
--- /dev/null
+++ b/projects/vga_ctrl/src/cpu_pkg.vhd
@@ -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 .
+--
+-- 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;
+
diff --git a/projects/vga_ctrl/src/main_irom.vhdl b/projects/vga_ctrl/src/main_irom.vhdl
new file mode 100644
index 0000000..394cffe
--- /dev/null
+++ b/projects/vga_ctrl/src/main_irom.vhdl
@@ -0,0 +1,230 @@
+-------------------------------------------------------------------------
+-- 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 .
+--
+-- 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 main OF irom IS
+
+ type imem_rom_t is array (0 to 168) of inst_t;
+
+ -- Assembled from main.jsm
+ constant imem_rom : imem_rom_t :=
+ (
+ "110000" & X"002", -- 0x000: JMP 0x002
+ "111111" & X"000", -- 0x001: RETI
+ "101000" & X"0B0", -- 0x002: XIN R00, (0x0B)
+ "100100" & X"010", -- 0x003: XOUT (0x01), R00
+ "011001" & X"010", -- 0x004: AND R00, 0x01
+ "110001" & X"002", -- 0x005: JZ 0x002
+ "101000" & X"0B0", -- 0x006: XIN R00, (0x0B)
+ "100100" & X"010", -- 0x007: XOUT (0x01), R00
+ "111011" & X"06E", -- 0x008: CALL 0x06E
+ "111011" & X"055", -- 0x009: CALL 0x055
+ "000011" & X"000", -- 0x00A: MOV R00, 0x00
+ "000011" & X"001", -- 0x00B: MOV R01, 0x00
+ "111011" & X"05A", -- 0x00C: CALL 0x05A
+ "111011" & X"074", -- 0x00D: CALL 0x074
+ "000011" & X"030", -- 0x00E: MOV R00, 0x03
+ "111011" & X"06B", -- 0x00F: CALL 0x06B
+ "101001" & X"000", -- 0x010: CIN R00, (0x00)
+ "010001" & X"300", -- 0x011: ADD R00, 0x30
+ "111011" & X"05E", -- 0x012: CALL 0x05E
+ "000011" & X"000", -- 0x013: MOV R00, 0x00
+ "111011" & X"061", -- 0x014: CALL 0x061
+ "111011" & X"074", -- 0x015: CALL 0x074
+ "111011" & X"074", -- 0x016: CALL 0x074
+ "000011" & X"0D0", -- 0x017: MOV R00, 0x0D
+ "111011" & X"06B", -- 0x018: CALL 0x06B
+ "111011" & X"07B", -- 0x019: CALL 0x07B
+ "000011" & X"000", -- 0x01A: MOV R00, 0x00
+ "000011" & X"031", -- 0x01B: MOV R01, 0x03
+ "111011" & X"05A", -- 0x01C: CALL 0x05A
+ "000011" & X"160", -- 0x01D: MOV R00, 0x16
+ "111011" & X"06B", -- 0x01E: CALL 0x06B
+ "111011" & X"074", -- 0x01F: CALL 0x074
+ "000011" & X"000", -- 0x020: MOV R00, 0x00
+ "000011" & X"0A1", -- 0x021: MOV R01, 0x0A
+ "111011" & X"05A", -- 0x022: CALL 0x05A
+ "000011" & X"A0F", -- 0x023: MOV R15, 0xA0
+ "001111" & X"00F", -- 0x024: TST R15
+ "110001" & X"02F", -- 0x025: JZ 0x02F
+ "010101" & X"01F", -- 0x026: DEC R15
+ "000011" & X"301", -- 0x027: MOV R01, 0x30
+ "001111" & X"3A1", -- 0x028: CMP R01, 0x3A
+ "111001" & X"02E", -- 0x029: JEQ 0x02E
+ "000010" & X"010", -- 0x02A: MOV R00, R01
+ "010001" & X"011", -- 0x02B: INC R01
+ "111011" & X"05E", -- 0x02C: CALL 0x05E
+ "110000" & X"028", -- 0x02D: JMP 0x028
+ "110000" & X"024", -- 0x02E: JMP 0x024
+ "111011" & X"074", -- 0x02F: CALL 0x074
+ "000011" & X"000", -- 0x030: MOV R00, 0x00
+ "000011" & X"0C1", -- 0x031: MOV R01, 0x0C
+ "111011" & X"05A", -- 0x032: CALL 0x05A
+ "111011" & X"050", -- 0x033: CALL 0x050
+ "000011" & X"000", -- 0x034: MOV R00, 0x00
+ "000011" & X"1E1", -- 0x035: MOV R01, 0x1E
+ "111011" & X"05A", -- 0x036: CALL 0x05A
+ "000011" & X"0D0", -- 0x037: MOV R00, 0x0D
+ "111011" & X"06B", -- 0x038: CALL 0x06B
+ "111011" & X"07B", -- 0x039: CALL 0x07B
+ "000011" & X"0D0", -- 0x03A: MOV R00, 0x0D
+ "111011" & X"06B", -- 0x03B: CALL 0x06B
+ "111011" & X"07B", -- 0x03C: CALL 0x07B
+ "000011" & X"0D0", -- 0x03D: MOV R00, 0x0D
+ "111011" & X"06B", -- 0x03E: CALL 0x06B
+ "111011" & X"07B", -- 0x03F: CALL 0x07B
+ "000011" & X"0D0", -- 0x040: MOV R00, 0x0D
+ "111011" & X"06B", -- 0x041: CALL 0x06B
+ "111011" & X"07B", -- 0x042: CALL 0x07B
+ "000011" & X"0D0", -- 0x043: MOV R00, 0x0D
+ "111011" & X"06B", -- 0x044: CALL 0x06B
+ "111011" & X"07B", -- 0x045: CALL 0x07B
+ "000011" & X"0D0", -- 0x046: MOV R00, 0x0D
+ "111011" & X"06B", -- 0x047: CALL 0x06B
+ "111011" & X"07B", -- 0x048: CALL 0x07B
+ "000011" & X"0D0", -- 0x049: MOV R00, 0x0D
+ "111011" & X"06B", -- 0x04A: CALL 0x06B
+ "111011" & X"07B", -- 0x04B: CALL 0x07B
+ "000011" & X"0D0", -- 0x04C: MOV R00, 0x0D
+ "111011" & X"06B", -- 0x04D: CALL 0x06B
+ "111011" & X"074", -- 0x04E: CALL 0x074
+ "110000" & X"008", -- 0x04F: JMP 0x008
+ "111100" & X"000", -- 0x050: PUSH R00
+ "000011" & X"020", -- 0x051: MOV R00, 0x02
+ "100100" & X"0B0", -- 0x052: XOUT (0x0B), R00
+ "111101" & X"000", -- 0x053: POP R00
+ "111110" & X"000", -- 0x054: RET
+ "111100" & X"000", -- 0x055: PUSH R00
+ "000011" & X"010", -- 0x056: MOV R00, 0x01
+ "100100" & X"0B0", -- 0x057: XOUT (0x0B), R00
+ "111101" & X"000", -- 0x058: POP R00
+ "111110" & X"000", -- 0x059: RET
+ "111011" & X"06E", -- 0x05A: CALL 0x06E
+ "100100" & X"091", -- 0x05B: XOUT (0x09), R01
+ "100100" & X"080", -- 0x05C: XOUT (0x08), R00
+ "111110" & X"000", -- 0x05D: RET
+ "111011" & X"06E", -- 0x05E: CALL 0x06E
+ "100100" & X"0A0", -- 0x05F: XOUT (0x0A), R00
+ "111110" & X"000", -- 0x060: RET
+ "111100" & X"001", -- 0x061: PUSH R01
+ "000010" & X"001", -- 0x062: MOV R01, R00
+ "000100" & X"010", -- 0x063: MOVX R00, (R01)
+ "010001" & X"011", -- 0x064: INC R01
+ "001111" & X"000", -- 0x065: TST R00
+ "110001" & X"069", -- 0x066: JZ 0x069
+ "111011" & X"05E", -- 0x067: CALL 0x05E
+ "110000" & X"063", -- 0x068: JMP 0x063
+ "111101" & X"001", -- 0x069: POP R01
+ "111110" & X"000", -- 0x06A: RET
+ "111011" & X"050", -- 0x06B: CALL 0x050
+ "111011" & X"061", -- 0x06C: CALL 0x061
+ "111110" & X"000", -- 0x06D: RET
+ "111100" & X"000", -- 0x06E: PUSH R00
+ "101000" & X"0B0", -- 0x06F: XIN R00, (0x0B)
+ "011001" & X"020", -- 0x070: AND R00, 0x02
+ "110001" & X"06F", -- 0x071: JZ 0x06F
+ "111101" & X"000", -- 0x072: POP R00
+ "111110" & X"000", -- 0x073: RET
+ "111100" & X"00F", -- 0x074: PUSH R15
+ "000011" & X"0AF", -- 0x075: MOV R15, 0x0A
+ "111011" & X"07B", -- 0x076: CALL 0x07B
+ "010101" & X"01F", -- 0x077: DEC R15
+ "110010" & X"076", -- 0x078: JNZ 0x076
+ "111101" & X"00F", -- 0x079: POP R15
+ "111110" & X"000", -- 0x07A: RET
+ "111100" & X"00F", -- 0x07B: PUSH R15
+ "000011" & X"0AF", -- 0x07C: MOV R15, 0x0A
+ "111011" & X"082", -- 0x07D: CALL 0x082
+ "010101" & X"01F", -- 0x07E: DEC R15
+ "110010" & X"07D", -- 0x07F: JNZ 0x07D
+ "111101" & X"00F", -- 0x080: POP R15
+ "111110" & X"000", -- 0x081: RET
+ "111100" & X"00F", -- 0x082: PUSH R15
+ "000011" & X"0AF", -- 0x083: MOV R15, 0x0A
+ "111011" & X"089", -- 0x084: CALL 0x089
+ "010101" & X"01F", -- 0x085: DEC R15
+ "110010" & X"084", -- 0x086: JNZ 0x084
+ "111101" & X"00F", -- 0x087: POP R15
+ "111110" & X"000", -- 0x088: RET
+ "111100" & X"00F", -- 0x089: PUSH R15
+ "000011" & X"0AF", -- 0x08A: MOV R15, 0x0A
+ "111011" & X"090", -- 0x08B: CALL 0x090
+ "010101" & X"01F", -- 0x08C: DEC R15
+ "110010" & X"08B", -- 0x08D: JNZ 0x08B
+ "111101" & X"00F", -- 0x08E: POP R15
+ "111110" & X"000", -- 0x08F: RET
+ "111100" & X"00F", -- 0x090: PUSH R15
+ "000011" & X"0AF", -- 0x091: MOV R15, 0x0A
+ "111011" & X"097", -- 0x092: CALL 0x097
+ "010101" & X"01F", -- 0x093: DEC R15
+ "110010" & X"092", -- 0x094: JNZ 0x092
+ "111101" & X"00F", -- 0x095: POP R15
+ "111110" & X"000", -- 0x096: RET
+ "111100" & X"00F", -- 0x097: PUSH R15
+ "000011" & X"63F", -- 0x098: MOV R15, 0x63
+ "000000" & X"000", -- 0x099: NOP
+ "000000" & X"000", -- 0x09A: NOP
+ "000000" & X"000", -- 0x09B: NOP
+ "010101" & X"01F", -- 0x09C: DEC R15
+ "110010" & X"099", -- 0x09D: JNZ 0x099
+ "111101" & X"00F", -- 0x09E: POP R15
+ "111110" & X"000", -- 0x09F: RET
+ "111100" & X"00F", -- 0x0A0: PUSH R15
+ "000011" & X"09F", -- 0x0A1: MOV R15, 0x09
+ "000000" & X"000", -- 0x0A2: NOP
+ "000000" & X"000", -- 0x0A3: NOP
+ "000000" & X"000", -- 0x0A4: NOP
+ "010101" & X"01F", -- 0x0A5: DEC R15
+ "110010" & X"0A2", -- 0x0A6: JNZ 0x0A2
+ "111101" & X"00F", -- 0x0A7: POP R15
+ "111110" & X"000" -- 0x0A8: 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 main;
+
diff --git a/projects/vga_ctrl/src/main_irom_ld.vhdl b/projects/vga_ctrl/src/main_irom_ld.vhdl
new file mode 100644
index 0000000..f8edbf6
--- /dev/null
+++ b/projects/vga_ctrl/src/main_irom_ld.vhdl
@@ -0,0 +1,1181 @@
+-------------------------------------------------------------------------
+-- 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 .
+--
+-- 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 irom IS
+ Port (
+ clk : in STD_LOGIC;
+ ce : in STD_LOGIC;
+ addr : in inst_addr_t;
+ dout : out inst_t
+ );
+
+END irom;
+
+ARCHITECTURE loadable OF irom IS
+
+ -- JASM_ROM_INSERT_HERE
+
+ -- Assembled from main.jsm
+ type imem_rom_t is array (0 to 1023) of inst_t;
+ signal imem_rom : imem_rom_t :=
+ (
+ "110000" & X"002", -- 0x000: JMP 0x002
+ "111111" & X"000", -- 0x001: RETI
+ "101000" & X"0B0", -- 0x002: XIN R00, (0x0B)
+ "100100" & X"010", -- 0x003: XOUT (0x01), R00
+ "011001" & X"010", -- 0x004: AND R00, 0x01
+ "110001" & X"002", -- 0x005: JZ 0x002
+ "101000" & X"0B0", -- 0x006: XIN R00, (0x0B)
+ "100100" & X"010", -- 0x007: XOUT (0x01), R00
+ "111011" & X"06E", -- 0x008: CALL 0x06E
+ "111011" & X"055", -- 0x009: CALL 0x055
+ "000011" & X"000", -- 0x00A: MOV R00, 0x00
+ "000011" & X"001", -- 0x00B: MOV R01, 0x00
+ "111011" & X"05A", -- 0x00C: CALL 0x05A
+ "111011" & X"074", -- 0x00D: CALL 0x074
+ "000011" & X"030", -- 0x00E: MOV R00, 0x03
+ "111011" & X"06B", -- 0x00F: CALL 0x06B
+ "101001" & X"000", -- 0x010: CIN R00, (0x00)
+ "010001" & X"300", -- 0x011: ADD R00, 0x30
+ "111011" & X"05E", -- 0x012: CALL 0x05E
+ "000011" & X"000", -- 0x013: MOV R00, 0x00
+ "111011" & X"061", -- 0x014: CALL 0x061
+ "111011" & X"074", -- 0x015: CALL 0x074
+ "111011" & X"074", -- 0x016: CALL 0x074
+ "000011" & X"0D0", -- 0x017: MOV R00, 0x0D
+ "111011" & X"06B", -- 0x018: CALL 0x06B
+ "111011" & X"07B", -- 0x019: CALL 0x07B
+ "000011" & X"000", -- 0x01A: MOV R00, 0x00
+ "000011" & X"031", -- 0x01B: MOV R01, 0x03
+ "111011" & X"05A", -- 0x01C: CALL 0x05A
+ "000011" & X"160", -- 0x01D: MOV R00, 0x16
+ "111011" & X"06B", -- 0x01E: CALL 0x06B
+ "111011" & X"074", -- 0x01F: CALL 0x074
+ "000011" & X"000", -- 0x020: MOV R00, 0x00
+ "000011" & X"0A1", -- 0x021: MOV R01, 0x0A
+ "111011" & X"05A", -- 0x022: CALL 0x05A
+ "000011" & X"A0F", -- 0x023: MOV R15, 0xA0
+ "001111" & X"00F", -- 0x024: TST R15
+ "110001" & X"02F", -- 0x025: JZ 0x02F
+ "010101" & X"01F", -- 0x026: DEC R15
+ "000011" & X"301", -- 0x027: MOV R01, 0x30
+ "001111" & X"3A1", -- 0x028: CMP R01, 0x3A
+ "111001" & X"02E", -- 0x029: JEQ 0x02E
+ "000010" & X"010", -- 0x02A: MOV R00, R01
+ "010001" & X"011", -- 0x02B: INC R01
+ "111011" & X"05E", -- 0x02C: CALL 0x05E
+ "110000" & X"028", -- 0x02D: JMP 0x028
+ "110000" & X"024", -- 0x02E: JMP 0x024
+ "111011" & X"074", -- 0x02F: CALL 0x074
+ "000011" & X"000", -- 0x030: MOV R00, 0x00
+ "000011" & X"0C1", -- 0x031: MOV R01, 0x0C
+ "111011" & X"05A", -- 0x032: CALL 0x05A
+ "111011" & X"050", -- 0x033: CALL 0x050
+ "000011" & X"000", -- 0x034: MOV R00, 0x00
+ "000011" & X"1E1", -- 0x035: MOV R01, 0x1E
+ "111011" & X"05A", -- 0x036: CALL 0x05A
+ "000011" & X"0D0", -- 0x037: MOV R00, 0x0D
+ "111011" & X"06B", -- 0x038: CALL 0x06B
+ "111011" & X"07B", -- 0x039: CALL 0x07B
+ "000011" & X"0D0", -- 0x03A: MOV R00, 0x0D
+ "111011" & X"06B", -- 0x03B: CALL 0x06B
+ "111011" & X"07B", -- 0x03C: CALL 0x07B
+ "000011" & X"0D0", -- 0x03D: MOV R00, 0x0D
+ "111011" & X"06B", -- 0x03E: CALL 0x06B
+ "111011" & X"07B", -- 0x03F: CALL 0x07B
+ "000011" & X"0D0", -- 0x040: MOV R00, 0x0D
+ "111011" & X"06B", -- 0x041: CALL 0x06B
+ "111011" & X"07B", -- 0x042: CALL 0x07B
+ "000011" & X"0D0", -- 0x043: MOV R00, 0x0D
+ "111011" & X"06B", -- 0x044: CALL 0x06B
+ "111011" & X"07B", -- 0x045: CALL 0x07B
+ "000011" & X"0D0", -- 0x046: MOV R00, 0x0D
+ "111011" & X"06B", -- 0x047: CALL 0x06B
+ "111011" & X"07B", -- 0x048: CALL 0x07B
+ "000011" & X"0D0", -- 0x049: MOV R00, 0x0D
+ "111011" & X"06B", -- 0x04A: CALL 0x06B
+ "111011" & X"07B", -- 0x04B: CALL 0x07B
+ "000011" & X"0D0", -- 0x04C: MOV R00, 0x0D
+ "111011" & X"06B", -- 0x04D: CALL 0x06B
+ "111011" & X"074", -- 0x04E: CALL 0x074
+ "110000" & X"008", -- 0x04F: JMP 0x008
+ "111100" & X"000", -- 0x050: PUSH R00
+ "000011" & X"020", -- 0x051: MOV R00, 0x02
+ "100100" & X"0B0", -- 0x052: XOUT (0x0B), R00
+ "111101" & X"000", -- 0x053: POP R00
+ "111110" & X"000", -- 0x054: RET
+ "111100" & X"000", -- 0x055: PUSH R00
+ "000011" & X"010", -- 0x056: MOV R00, 0x01
+ "100100" & X"0B0", -- 0x057: XOUT (0x0B), R00
+ "111101" & X"000", -- 0x058: POP R00
+ "111110" & X"000", -- 0x059: RET
+ "111011" & X"06E", -- 0x05A: CALL 0x06E
+ "100100" & X"091", -- 0x05B: XOUT (0x09), R01
+ "100100" & X"080", -- 0x05C: XOUT (0x08), R00
+ "111110" & X"000", -- 0x05D: RET
+ "111011" & X"06E", -- 0x05E: CALL 0x06E
+ "100100" & X"0A0", -- 0x05F: XOUT (0x0A), R00
+ "111110" & X"000", -- 0x060: RET
+ "111100" & X"001", -- 0x061: PUSH R01
+ "000010" & X"001", -- 0x062: MOV R01, R00
+ "000100" & X"010", -- 0x063: MOVX R00, (R01)
+ "010001" & X"011", -- 0x064: INC R01
+ "001111" & X"000", -- 0x065: TST R00
+ "110001" & X"069", -- 0x066: JZ 0x069
+ "111011" & X"05E", -- 0x067: CALL 0x05E
+ "110000" & X"063", -- 0x068: JMP 0x063
+ "111101" & X"001", -- 0x069: POP R01
+ "111110" & X"000", -- 0x06A: RET
+ "111011" & X"050", -- 0x06B: CALL 0x050
+ "111011" & X"061", -- 0x06C: CALL 0x061
+ "111110" & X"000", -- 0x06D: RET
+ "111100" & X"000", -- 0x06E: PUSH R00
+ "101000" & X"0B0", -- 0x06F: XIN R00, (0x0B)
+ "011001" & X"020", -- 0x070: AND R00, 0x02
+ "110001" & X"06F", -- 0x071: JZ 0x06F
+ "111101" & X"000", -- 0x072: POP R00
+ "111110" & X"000", -- 0x073: RET
+ "111100" & X"00F", -- 0x074: PUSH R15
+ "000011" & X"0AF", -- 0x075: MOV R15, 0x0A
+ "111011" & X"07B", -- 0x076: CALL 0x07B
+ "010101" & X"01F", -- 0x077: DEC R15
+ "110010" & X"076", -- 0x078: JNZ 0x076
+ "111101" & X"00F", -- 0x079: POP R15
+ "111110" & X"000", -- 0x07A: RET
+ "111100" & X"00F", -- 0x07B: PUSH R15
+ "000011" & X"0AF", -- 0x07C: MOV R15, 0x0A
+ "111011" & X"082", -- 0x07D: CALL 0x082
+ "010101" & X"01F", -- 0x07E: DEC R15
+ "110010" & X"07D", -- 0x07F: JNZ 0x07D
+ "111101" & X"00F", -- 0x080: POP R15
+ "111110" & X"000", -- 0x081: RET
+ "111100" & X"00F", -- 0x082: PUSH R15
+ "000011" & X"0AF", -- 0x083: MOV R15, 0x0A
+ "111011" & X"089", -- 0x084: CALL 0x089
+ "010101" & X"01F", -- 0x085: DEC R15
+ "110010" & X"084", -- 0x086: JNZ 0x084
+ "111101" & X"00F", -- 0x087: POP R15
+ "111110" & X"000", -- 0x088: RET
+ "111100" & X"00F", -- 0x089: PUSH R15
+ "000011" & X"0AF", -- 0x08A: MOV R15, 0x0A
+ "111011" & X"090", -- 0x08B: CALL 0x090
+ "010101" & X"01F", -- 0x08C: DEC R15
+ "110010" & X"08B", -- 0x08D: JNZ 0x08B
+ "111101" & X"00F", -- 0x08E: POP R15
+ "111110" & X"000", -- 0x08F: RET
+ "111100" & X"00F", -- 0x090: PUSH R15
+ "000011" & X"0AF", -- 0x091: MOV R15, 0x0A
+ "111011" & X"097", -- 0x092: CALL 0x097
+ "010101" & X"01F", -- 0x093: DEC R15
+ "110010" & X"092", -- 0x094: JNZ 0x092
+ "111101" & X"00F", -- 0x095: POP R15
+ "111110" & X"000", -- 0x096: RET
+ "111100" & X"00F", -- 0x097: PUSH R15
+ "000011" & X"63F", -- 0x098: MOV R15, 0x63
+ "000000" & X"000", -- 0x099: NOP
+ "000000" & X"000", -- 0x09A: NOP
+ "000000" & X"000", -- 0x09B: NOP
+ "010101" & X"01F", -- 0x09C: DEC R15
+ "110010" & X"099", -- 0x09D: JNZ 0x099
+ "111101" & X"00F", -- 0x09E: POP R15
+ "111110" & X"000", -- 0x09F: RET
+ "111100" & X"00F", -- 0x0A0: PUSH R15
+ "000011" & X"09F", -- 0x0A1: MOV R15, 0x09
+ "000000" & X"000", -- 0x0A2: NOP
+ "000000" & X"000", -- 0x0A3: NOP
+ "000000" & X"000", -- 0x0A4: NOP
+ "010101" & X"01F", -- 0x0A5: DEC R15
+ "110010" & X"0A2", -- 0x0A6: JNZ 0x0A2
+ "111101" & X"00F", -- 0x0A7: POP R15
+ "111110" & X"000", -- 0x0A8: RET
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000",
+ "000000" & X"000"
+ );
+
+ signal jtag_ld_clk : STD_LOGIC;
+ signal jtag_ld_we : STD_LOGIC;
+ signal jtag_ld_addr : inst_addr_t;
+ signal jtag_ld_dout : inst_t;
+ signal jtag_ld_din : inst_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 (31 downto 0);
+ constant id : unsigned (31 downto 0) := X"BABE" & 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_inst1 : BSCAN_VIRTEX4
+ generic map
+ (
+ JTAG_CHAIN => 1 -- 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-inst_addr_t'length+1);
+ jtag_ld_din <= user_regi(inst_t'length-1 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 inst_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 <= imem_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
+ imem_rom(to_integer(jtag_ld_addr)) <= jtag_ld_din;
+ else
+ jtag_ld_dout <= imem_rom(to_integer(jtag_ld_addr));
+ end if;
+ end if;
+ end process;
+
+--------------------------------------------------------------------------
+end loadable;
diff --git a/projects/vga_ctrl/src/main_xrom.vhdl b/projects/vga_ctrl/src/main_xrom.vhdl
new file mode 100644
index 0000000..b6c163e
--- /dev/null
+++ b/projects/vga_ctrl/src/main_xrom.vhdl
@@ -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 .
+--
+-- 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 main OF xrom IS
+
+ type xmem_rom_t is array (0 to 255) of dmem_data_t;
+
+ -- Assembled from main.jsm
+ constant xmem_rom : xmem_rom_t :=
+ (
+ X"0D", -- 0x00
+ X"0A", -- 0x01
+ X"00", -- 0x02
+ X"4A", -- 0x03
+ X"2D", -- 0x04
+ X"43", -- 0x05
+ X"50", -- 0x06
+ X"55", -- 0x07
+ X"20", -- 0x08
+ X"56", -- 0x09
+ X"31", -- 0x0A
+ X"2E", -- 0x0B
+ X"00", -- 0x0C
+ X"52", -- 0x0D
+ X"65", -- 0x0E
+ X"61", -- 0x0F
+ X"64", -- 0x10
+ X"79", -- 0x11
+ X"2E", -- 0x12
+ X"0D", -- 0x13
+ X"0A", -- 0x14
+ X"00", -- 0x15
+ X"4D", -- 0x16
+ X"69", -- 0x17
+ X"6D", -- 0x18
+ X"69", -- 0x19
+ X"20", -- 0x1A
+ X"69", -- 0x1B
+ X"73", -- 0x1C
+ X"74", -- 0x1D
+ X"20", -- 0x1E
+ X"65", -- 0x1F
+ X"69", -- 0x20
+ X"6E", -- 0x21
+ X"65", -- 0x22
+ X"20", -- 0x23
+ X"6C", -- 0x24
+ X"69", -- 0x25
+ X"65", -- 0x26
+ X"62", -- 0x27
+ X"65", -- 0x28
+ X"20", -- 0x29
+ X"4B", -- 0x2A
+ X"61", -- 0x2B
+ X"74", -- 0x2C
+ X"7A", -- 0x2D
+ X"65", -- 0x2E
+ X"20", -- 0x2F
+ X"21", -- 0x30
+ X"21", -- 0x31
+ X"21", -- 0x32
+ X"0D", -- 0x33
+ X"0A", -- 0x34
+ X"00", -- 0x35
+ X"00", -- 0x36
+ X"00", -- 0x37
+ X"00", -- 0x38
+ X"00", -- 0x39
+ X"00", -- 0x3A
+ X"00", -- 0x3B
+ X"00", -- 0x3C
+ X"00", -- 0x3D
+ X"00", -- 0x3E
+ X"00", -- 0x3F
+ X"00", -- 0x40
+ X"00", -- 0x41
+ X"00", -- 0x42
+ X"00", -- 0x43
+ X"00", -- 0x44
+ X"00", -- 0x45
+ X"00", -- 0x46
+ X"00", -- 0x47
+ X"00", -- 0x48
+ X"00", -- 0x49
+ X"00", -- 0x4A
+ X"00", -- 0x4B
+ X"00", -- 0x4C
+ X"00", -- 0x4D
+ X"00", -- 0x4E
+ X"00", -- 0x4F
+ X"00", -- 0x50
+ X"00", -- 0x51
+ X"00", -- 0x52
+ X"00", -- 0x53
+ X"00", -- 0x54
+ X"00", -- 0x55
+ X"00", -- 0x56
+ X"00", -- 0x57
+ X"00", -- 0x58
+ X"00", -- 0x59
+ X"00", -- 0x5A
+ X"00", -- 0x5B
+ X"00", -- 0x5C
+ X"00", -- 0x5D
+ X"00", -- 0x5E
+ X"00", -- 0x5F
+ X"00", -- 0x60
+ X"00", -- 0x61
+ X"00", -- 0x62
+ X"00", -- 0x63
+ X"00", -- 0x64
+ X"00", -- 0x65
+ X"00", -- 0x66
+ X"00", -- 0x67
+ X"00", -- 0x68
+ X"00", -- 0x69
+ X"00", -- 0x6A
+ X"00", -- 0x6B
+ X"00", -- 0x6C
+ X"00", -- 0x6D
+ X"00", -- 0x6E
+ X"00", -- 0x6F
+ X"00", -- 0x70
+ X"00", -- 0x71
+ X"00", -- 0x72
+ X"00", -- 0x73
+ X"00", -- 0x74
+ X"00", -- 0x75
+ X"00", -- 0x76
+ X"00", -- 0x77
+ X"00", -- 0x78
+ X"00", -- 0x79
+ X"00", -- 0x7A
+ X"00", -- 0x7B
+ X"00", -- 0x7C
+ X"00", -- 0x7D
+ X"00", -- 0x7E
+ X"00", -- 0x7F
+ X"00", -- 0x80
+ X"00", -- 0x81
+ X"00", -- 0x82
+ X"00", -- 0x83
+ X"00", -- 0x84
+ X"00", -- 0x85
+ X"00", -- 0x86
+ X"00", -- 0x87
+ X"00", -- 0x88
+ X"00", -- 0x89
+ X"00", -- 0x8A
+ X"00", -- 0x8B
+ X"00", -- 0x8C
+ X"00", -- 0x8D
+ X"00", -- 0x8E
+ X"00", -- 0x8F
+ X"00", -- 0x90
+ X"00", -- 0x91
+ X"00", -- 0x92
+ X"00", -- 0x93
+ X"00", -- 0x94
+ X"00", -- 0x95
+ X"00", -- 0x96
+ X"00", -- 0x97
+ X"00", -- 0x98
+ X"00", -- 0x99
+ X"00", -- 0x9A
+ X"00", -- 0x9B
+ X"00", -- 0x9C
+ X"00", -- 0x9D
+ X"00", -- 0x9E
+ X"00", -- 0x9F
+ X"00", -- 0xA0
+ X"00", -- 0xA1
+ X"00", -- 0xA2
+ X"00", -- 0xA3
+ X"00", -- 0xA4
+ X"00", -- 0xA5
+ X"00", -- 0xA6
+ X"00", -- 0xA7
+ X"00", -- 0xA8
+ X"00", -- 0xA9
+ X"00", -- 0xAA
+ X"00", -- 0xAB
+ X"00", -- 0xAC
+ X"00", -- 0xAD
+ X"00", -- 0xAE
+ X"00", -- 0xAF
+ X"00", -- 0xB0
+ X"00", -- 0xB1
+ X"00", -- 0xB2
+ X"00", -- 0xB3
+ X"00", -- 0xB4
+ X"00", -- 0xB5
+ X"00", -- 0xB6
+ X"00", -- 0xB7
+ X"00", -- 0xB8
+ X"00", -- 0xB9
+ X"00", -- 0xBA
+ X"00", -- 0xBB
+ X"00", -- 0xBC
+ X"00", -- 0xBD
+ X"00", -- 0xBE
+ X"00", -- 0xBF
+ X"00", -- 0xC0
+ X"00", -- 0xC1
+ X"00", -- 0xC2
+ X"00", -- 0xC3
+ X"00", -- 0xC4
+ X"00", -- 0xC5
+ X"00", -- 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 main;
+
diff --git a/projects/vga_ctrl/src/main_xrom_ld.vhdl b/projects/vga_ctrl/src/main_xrom_ld.vhdl
new file mode 100644
index 0000000..e8f6ef3
--- /dev/null
+++ b/projects/vga_ctrl/src/main_xrom_ld.vhdl
@@ -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 .
+--
+-- 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 main.jsm
+ type xmem_rom_t is array (0 to 255) of dmem_data_t;
+ signal xmem_rom : xmem_rom_t :=
+ (
+ X"0D", -- 0x00
+ X"0A", -- 0x01
+ X"00", -- 0x02
+ X"4A", -- 0x03
+ X"2D", -- 0x04
+ X"43", -- 0x05
+ X"50", -- 0x06
+ X"55", -- 0x07
+ X"20", -- 0x08
+ X"56", -- 0x09
+ X"31", -- 0x0A
+ X"2E", -- 0x0B
+ X"00", -- 0x0C
+ X"52", -- 0x0D
+ X"65", -- 0x0E
+ X"61", -- 0x0F
+ X"64", -- 0x10
+ X"79", -- 0x11
+ X"2E", -- 0x12
+ X"0D", -- 0x13
+ X"0A", -- 0x14
+ X"00", -- 0x15
+ X"4D", -- 0x16
+ X"69", -- 0x17
+ X"6D", -- 0x18
+ X"69", -- 0x19
+ X"20", -- 0x1A
+ X"69", -- 0x1B
+ X"73", -- 0x1C
+ X"74", -- 0x1D
+ X"20", -- 0x1E
+ X"65", -- 0x1F
+ X"69", -- 0x20
+ X"6E", -- 0x21
+ X"65", -- 0x22
+ X"20", -- 0x23
+ X"6C", -- 0x24
+ X"69", -- 0x25
+ X"65", -- 0x26
+ X"62", -- 0x27
+ X"65", -- 0x28
+ X"20", -- 0x29
+ X"4B", -- 0x2A
+ X"61", -- 0x2B
+ X"74", -- 0x2C
+ X"7A", -- 0x2D
+ X"65", -- 0x2E
+ X"20", -- 0x2F
+ X"21", -- 0x30
+ X"21", -- 0x31
+ X"21", -- 0x32
+ X"0D", -- 0x33
+ X"0A", -- 0x34
+ X"00", -- 0x35
+ X"00", -- 0x36
+ X"00", -- 0x37
+ X"00", -- 0x38
+ X"00", -- 0x39
+ X"00", -- 0x3A
+ X"00", -- 0x3B
+ X"00", -- 0x3C
+ X"00", -- 0x3D
+ X"00", -- 0x3E
+ X"00", -- 0x3F
+ X"00", -- 0x40
+ X"00", -- 0x41
+ X"00", -- 0x42
+ X"00", -- 0x43
+ X"00", -- 0x44
+ X"00", -- 0x45
+ X"00", -- 0x46
+ X"00", -- 0x47
+ X"00", -- 0x48
+ X"00", -- 0x49
+ X"00", -- 0x4A
+ X"00", -- 0x4B
+ X"00", -- 0x4C
+ X"00", -- 0x4D
+ X"00", -- 0x4E
+ X"00", -- 0x4F
+ X"00", -- 0x50
+ X"00", -- 0x51
+ X"00", -- 0x52
+ X"00", -- 0x53
+ X"00", -- 0x54
+ X"00", -- 0x55
+ X"00", -- 0x56
+ X"00", -- 0x57
+ X"00", -- 0x58
+ X"00", -- 0x59
+ X"00", -- 0x5A
+ X"00", -- 0x5B
+ X"00", -- 0x5C
+ X"00", -- 0x5D
+ X"00", -- 0x5E
+ X"00", -- 0x5F
+ X"00", -- 0x60
+ X"00", -- 0x61
+ X"00", -- 0x62
+ X"00", -- 0x63
+ X"00", -- 0x64
+ X"00", -- 0x65
+ X"00", -- 0x66
+ X"00", -- 0x67
+ X"00", -- 0x68
+ X"00", -- 0x69
+ X"00", -- 0x6A
+ X"00", -- 0x6B
+ X"00", -- 0x6C
+ X"00", -- 0x6D
+ X"00", -- 0x6E
+ X"00", -- 0x6F
+ X"00", -- 0x70
+ X"00", -- 0x71
+ X"00", -- 0x72
+ X"00", -- 0x73
+ X"00", -- 0x74
+ X"00", -- 0x75
+ X"00", -- 0x76
+ X"00", -- 0x77
+ X"00", -- 0x78
+ X"00", -- 0x79
+ X"00", -- 0x7A
+ X"00", -- 0x7B
+ X"00", -- 0x7C
+ X"00", -- 0x7D
+ X"00", -- 0x7E
+ X"00", -- 0x7F
+ X"00", -- 0x80
+ X"00", -- 0x81
+ X"00", -- 0x82
+ X"00", -- 0x83
+ X"00", -- 0x84
+ X"00", -- 0x85
+ X"00", -- 0x86
+ X"00", -- 0x87
+ X"00", -- 0x88
+ X"00", -- 0x89
+ X"00", -- 0x8A
+ X"00", -- 0x8B
+ X"00", -- 0x8C
+ X"00", -- 0x8D
+ X"00", -- 0x8E
+ X"00", -- 0x8F
+ X"00", -- 0x90
+ X"00", -- 0x91
+ X"00", -- 0x92
+ X"00", -- 0x93
+ X"00", -- 0x94
+ X"00", -- 0x95
+ X"00", -- 0x96
+ X"00", -- 0x97
+ X"00", -- 0x98
+ X"00", -- 0x99
+ X"00", -- 0x9A
+ X"00", -- 0x9B
+ X"00", -- 0x9C
+ X"00", -- 0x9D
+ X"00", -- 0x9E
+ X"00", -- 0x9F
+ X"00", -- 0xA0
+ X"00", -- 0xA1
+ X"00", -- 0xA2
+ X"00", -- 0xA3
+ X"00", -- 0xA4
+ X"00", -- 0xA5
+ X"00", -- 0xA6
+ X"00", -- 0xA7
+ X"00", -- 0xA8
+ X"00", -- 0xA9
+ X"00", -- 0xAA
+ X"00", -- 0xAB
+ X"00", -- 0xAC
+ X"00", -- 0xAD
+ X"00", -- 0xAE
+ X"00", -- 0xAF
+ X"00", -- 0xB0
+ X"00", -- 0xB1
+ X"00", -- 0xB2
+ X"00", -- 0xB3
+ X"00", -- 0xB4
+ X"00", -- 0xB5
+ X"00", -- 0xB6
+ X"00", -- 0xB7
+ X"00", -- 0xB8
+ X"00", -- 0xB9
+ X"00", -- 0xBA
+ X"00", -- 0xBB
+ X"00", -- 0xBC
+ X"00", -- 0xBD
+ X"00", -- 0xBE
+ X"00", -- 0xBF
+ X"00", -- 0xC0
+ X"00", -- 0xC1
+ X"00", -- 0xC2
+ X"00", -- 0xC3
+ X"00", -- 0xC4
+ X"00", -- 0xC5
+ X"00", -- 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;
diff --git a/projects/vga_ctrl/src/tb_vga_ctrl.vhd b/projects/vga_ctrl/src/tb_vga_ctrl.vhd
new file mode 100644
index 0000000..8f244f3
--- /dev/null
+++ b/projects/vga_ctrl/src/tb_vga_ctrl.vhd
@@ -0,0 +1,147 @@
+
+--------------------------------------------------------------------------------
+-- Company:
+-- Engineer:
+--
+-- Create Date: 13:58:47 10/15/2005
+-- Design Name: vga_ctrl_top
+-- Module Name: tb_vga_ctrl.vhd
+-- Project Name: vga_ctrl
+-- Target Device:
+-- Tool versions:
+-- Description:
+--
+-- VHDL Test Bench Created by ISE for module: vga_ctrl_top
+--
+-- Dependencies:
+--
+-- Revision:
+-- Revision 0.01 - File Created
+-- Additional Comments:
+--
+-- Notes:
+-- This testbench has been automatically generated using types std_logic and
+-- std_logic_vector for the ports of the unit under test. Xilinx recommends
+-- that these types always be used for the top-level I/O of a design in order
+-- to guarantee that the testbench will bind correctly to the post-implementation
+-- simulation model.
+--------------------------------------------------------------------------------
+LIBRARY ieee;
+use IEEE.STD_LOGIC_1164.ALL;
+use IEEE.NUMERIC_STD.ALL;
+
+use work.vga_types.all;
+
+ENTITY tb_vga_ctrl_vhd IS
+END tb_vga_ctrl_vhd;
+
+ARCHITECTURE behavior OF tb_vga_ctrl_vhd IS
+
+ -- Component Declaration for the Unit Under Test (UUT)
+ COMPONENT vga_ctrl_top
+ GENERIC
+ (
+ sys_freq : real;
+ fifo_depth : integer;
+ tsvga : vga_timespec_t
+ );
+ PORT
+ (
+ sys_rstn_in : IN std_logic;
+ sys_clk_in : IN std_logic;
+ sys_vga_red : OUT unsigned(7 downto 0);
+ sys_vga_green : OUT unsigned(7 downto 0);
+ sys_vga_blue : OUT unsigned(7 downto 0);
+ sys_vga_blank_n : OUT std_logic;
+ sys_vga_sync_n : OUT std_logic;
+ sys_vga_hsync : OUT std_logic;
+ sys_vga_vsync : OUT std_logic;
+ sys_vga_clk : OUT std_logic;
+ sys_dip : in unsigned(7 downto 0);
+ sys_btn : in unsigned(4 downto 0);
+ sys_led : out unsigned(8 downto 0)
+ );
+ END COMPONENT;
+
+ --Constants
+ constant PERIOD : time := 9.9304865938430983118172790466733 ns;
+
+ --Inputs
+ SIGNAL sys_rstn_in : std_logic := '0';
+ SIGNAL sys_clk_in : std_logic := '0';
+ SIGNAL sys_color_en : unsigned(2 downto 0) := (others => '0');
+ SIGNAL sys_dip : unsigned(7 downto 0) := (others => '0');
+ SIGNAL sys_btn : unsigned(4 downto 0) := (others => '0');
+
+ --Outputs
+ SIGNAL sys_vga_red : unsigned(7 downto 0);
+ SIGNAL sys_vga_green : unsigned(7 downto 0);
+ SIGNAL sys_vga_blue : unsigned(7 downto 0);
+ SIGNAL sys_vga_blank_n : std_logic;
+ SIGNAL sys_vga_sync_n : std_logic;
+ SIGNAL sys_vga_hsync : std_logic;
+ SIGNAL sys_vga_vsync : std_logic;
+ SIGNAL sys_vga_clk : std_logic;
+ SIGNAL sys_led : unsigned(8 downto 0);
+ constant f_sys : real := 100.0;
+ constant f_vga : real := 130.0;
+-- SIGNAL test_M : natural := VGA_FREQ_M(f_sys, f_vga);
+-- SIGNAL test_D : natural := VGA_FREQ_D(f_sys, f_vga);
+
+BEGIN
+
+ -- Instantiate the Unit Under Test (UUT)
+ uut: vga_ctrl_top
+ GENERIC MAP
+ (
+ sys_freq => f_sys,
+ fifo_depth => 2048,
+ tsvga => ts_vga_testbench
+ )
+ PORT MAP(
+ sys_rstn_in => sys_rstn_in,
+ sys_clk_in => sys_clk_in,
+ sys_vga_red => sys_vga_red,
+ sys_vga_green => sys_vga_green,
+ sys_vga_blue => sys_vga_blue,
+ sys_vga_blank_n => sys_vga_blank_n,
+ sys_vga_sync_n => sys_vga_sync_n,
+ sys_vga_hsync => sys_vga_hsync,
+ sys_vga_vsync => sys_vga_vsync,
+ sys_vga_clk => sys_vga_clk,
+ sys_dip => sys_dip,
+ sys_btn => sys_btn,
+ sys_led => sys_led
+ );
+
+ tb_clk : PROCESS
+ BEGIN
+ sys_clk_in <= not sys_clk_in;
+ wait for PERIOD/2;
+ END PROCESS;
+
+ tb : PROCESS
+ BEGIN
+
+ -- Wait 100 ns for global reset to finish
+ wait for 20*PERIOD;
+ sys_rstn_in <= '1';
+
+ wait for PERIOD;
+ sys_dip <= X"AA";
+
+ wait for PERIOD;
+ sys_color_en <= "100";
+
+ wait for 10*PERIOD;
+ sys_color_en <= "000";
+
+ -- Wait 100 ns for global reset to finish
+ wait for 100 ns;
+
+ -- Place stimulus here
+
+ wait; -- will wait forever
+ END PROCESS;
+
+END;
diff --git a/projects/vga_ctrl/src/vga_ctrl_top.vhd b/projects/vga_ctrl/src/vga_ctrl_top.vhd
new file mode 100644
index 0000000..9de1476
--- /dev/null
+++ b/projects/vga_ctrl/src/vga_ctrl_top.vhd
@@ -0,0 +1,394 @@
+--------------------------------------------------------------------------------
+-- Company:
+-- Engineer:
+--
+-- Create Date: 11:25:45 10/15/05
+-- Design Name:
+-- Module Name: vga_ctrl_top - Behavioral
+-- Project Name:
+-- Target Device:
+-- 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.vga_types.all;
+use work.cpu_pkg.all;
+
+entity vga_ctrl_top is
+ Generic
+ (
+ sys_freq : real := 100.0;
+ fifo_depth : integer := 2048;
+ tsvga : vga_timespec_t := ts_vga_1280_1024_72
+ );
+ Port
+ (
+ sys_rstn_in : in std_logic;
+ sys_clk_in : in std_logic;
+ sys_vga_red : out unsigned(7 downto 0);
+ sys_vga_green : out unsigned(7 downto 0);
+ sys_vga_blue : out unsigned(7 downto 0);
+ sys_vga_blank_n : out std_logic;
+ sys_vga_sync_n : out std_logic;
+ sys_vga_hsync : out std_logic;
+ sys_vga_vsync : out std_logic;
+ sys_vga_clk : out std_logic;
+ -- Buttons and LEDs
+ sys_btn : in unsigned(4 downto 0);
+ sys_dip : in unsigned(7 downto 0);
+ sys_led : out unsigned(8 downto 0)
+ );
+end vga_ctrl_top;
+
+architecture Behavioral of vga_ctrl_top is
+
+ -- System signal
+ signal rst : std_logic;
+ signal clk : std_logic;
+ signal vga_rst : std_logic;
+ signal vga_clk : std_logic;
+ signal vga_ready : std_logic;
+
+ -- Timing
+ signal scan_rdy : std_logic;
+ signal scan_rdy_h : std_logic;
+ signal scan_rdy_v : std_logic;
+ signal vga_scan_x : std_logic;
+ signal vga_scan_y : std_logic;
+ signal hsync : std_logic;
+ signal vsync : std_logic;
+
+ signal src_pos_x : natural range 0 to tsvga.ts_h.ncyc_scan-1;
+ signal src_pos_y : natural range 0 to tsvga.ts_v.ncyc_scan-1;
+ signal vga_pos_x : natural range 0 to tsvga.ts_h.ncyc_scan-1;
+ signal vga_pos_y : natural range 0 to tsvga.ts_v.ncyc_scan-1;
+
+ -- Line buffers
+ signal color_w : color_t;
+ signal vga_color : color_t;
+ signal color_we : std_logic;
+ signal fifo_full : std_logic;
+ signal fifo_almost_full : std_logic;
+ signal scan_enable : std_logic;
+ signal src_enable : std_logic;
+ signal src_cnt_en : std_logic;
+ signal char_draw_en : std_logic;
+ signal cg_en : std_logic;
+ signal cpu_color : color_t;
+
+ -- CPU signals
+ signal cpu_rst : std_logic;
+ signal cpu_ce : std_logic;
+ signal cpu_int_in : std_logic;
+ signal cpu_int_ack : std_logic;
+ signal cpu_we : std_logic;
+ signal cpu_re : std_logic;
+ signal cpu_io_sel : std_logic;
+ signal cpu_din : dmem_data_t;
+ signal cpu_dout : dmem_data_t;
+ signal cpu_addr : dmem_addr_t;
+ signal cpu_xrom_data : dmem_data_t;
+
+ signal cg_ready : std_logic;
+ signal cg_clr_screen : std_logic;
+ signal cg_clr_line : std_logic;
+ signal cg_ascii_data : dmem_data_t;
+ signal cg_ascii_data_we : std_logic;
+ signal cg_ascii_posy_we : std_logic;
+ signal cg_ascii_posx_we : std_logic;
+
+ signal cpu_led : dmem_data_t;
+ signal cpu_red : dmem_data_t;
+ signal cpu_green : dmem_data_t;
+ signal cpu_blue : dmem_data_t;
+
+begin
+
+ inst_vga_backend: entity work.vga_backend
+ GENERIC MAP
+ (
+ sys_freq => sys_freq,
+ fifo_depth => fifo_depth,
+ tsvga => tsvga
+ )
+ PORT MAP
+ (
+ sys_rst => vga_rst,
+ sys_clk => clk,
+ vga_ready => vga_ready,
+ color_in => color_w,
+ color_fifo_we => color_we,
+ color_fifo_full => fifo_full,
+ color_fifo_afull => fifo_almost_full,
+ direct_color_in => cpu_color,
+ direct_draw_en => char_draw_en,
+ stat_hsync => hsync,
+ stat_vsync => vsync,
+ stat_hready => scan_rdy_h,
+ stat_vready => scan_rdy_v,
+ stat_hscan => vga_scan_x,
+ stat_vscan => vga_scan_y,
+ stat_hpos => vga_pos_x,
+ stat_vpos => vga_pos_y,
+ vga_clk_out => vga_clk,
+ vga_color_out => vga_color,
+ vga_blank_n => sys_vga_blank_n,
+ vga_sync_n => sys_vga_sync_n,
+ vga_hsync => sys_vga_hsync,
+ vga_vsync => sys_vga_vsync
+
+ );
+
+ inst_char_gen : entity work.char_gen
+ GENERIC MAP
+ (
+ tsvga => tsvga,
+ CHARACTER_SCALE => 1,
+ CHAR_ROM_SIZE_X => 8, -- Pixels
+ CHAR_ROM_SIZE_Y => 16, -- Pixels
+ CHAR_ROM_DEPTH => 256, -- Chars
+ MAX_CHAR_PER_LINE => 80, -- Chars
+ MAX_LINE_PER_FRAME => 32, -- Chars
+ CHAR_SPACING_X => 0, -- Pixels
+ CHAR_SPACING_Y => 0, -- Pixels
+ SCREEN_OFFSET_X => 16, -- Pixels
+ SCREEN_OFFSET_Y => 16 -- Pixels
+ )
+ PORT MAP
+ (
+ rst => rst,
+ sys_clk => clk,
+ vga_clk => vga_clk,
+ ce => cg_en,
+ frame_pulse => scan_rdy,
+ clr_screen => cg_clr_screen,
+ clr_line => cg_clr_line,
+ ascii_data => cg_ascii_data,
+ ascii_data_we => cg_ascii_data_we,
+ ascii_posy_we => cg_ascii_posy_we,
+ ascii_posx_we => cg_ascii_posx_we,
+ ready => cg_ready,
+ pos_x => vga_pos_x,
+ pos_y => vga_pos_y,
+ char_draw_en => char_draw_en
+ );
+
+ inst_cpu_embedded: entity work.cpu_embedded
+ PORT MAP(
+ rst => cpu_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: entity work.xrom
+ PORT MAP(
+ clk => clk,
+ ce => cpu_ce,
+ addr => cpu_addr,
+ dout => cpu_xrom_data
+ );
+
+ ---------------------------------------------------------------------------------------------
+ rst <= not vga_ready;
+ vga_rst <= not sys_rstn_in;
+
+-- clk <= vga_clk;
+ clk <= sys_clk_in;
+
+ scan_rdy <= scan_rdy_h and scan_rdy_v;
+
+ sys_vga_clk <= vga_clk;
+ sys_vga_red <= vga_color(r);
+ sys_vga_green <= vga_color(g);
+ sys_vga_blue <= vga_color(b);
+
+ cg_en <= vga_scan_x and vga_scan_y;
+ cpu_ce <= '1';
+
+ ---------------------------------------------------------------------------------------------
+led_out: process (clk)
+ begin
+ if rising_edge(clk) then
+ sys_led <= '0' & cpu_led;
+ end if;
+ end process;
+
+ ---------------------------------------------------------------------------------------------
+cpu_reg_read:
+ process(clk, cpu_io_sel, cpu_xrom_data)
+ variable reg : dmem_data_t;
+ begin
+
+ if rising_edge(clk) then
+ case cpu_addr is
+ when X"00" => -- 00
+ reg := "000" & unsigned(sys_btn(4 downto 0));
+ when X"01" => -- 01
+ reg := cpu_led;
+ when X"05" => -- 05
+ reg := unsigned(sys_dip);
+ when X"0B" =>
+ reg := "000000" & cg_ready & vga_ready;
+ when others => null;
+ end case;
+ end if;
+
+ cpu_din <= cpu_xrom_data;
+ if cpu_io_sel = '1' then
+ cpu_din <= reg;
+ end if;
+
+ end process;
+
+------------------------------------------------------------------
+cpu_reg_write:
+ process(rst, clk)
+ variable addr : unsigned(dmem_addr_t'length-1 downto 0);
+ begin
+ if (rst = '1') then
+ cpu_led <= (others => '0');
+ cg_ascii_data <= (others => '0');
+ cg_ascii_posy_we <= '0';
+ cg_ascii_posx_we <= '0';
+ cg_ascii_data_we <= '0';
+ cg_clr_line <= '0';
+ cg_clr_screen <= '0';
+ cpu_red <= X"80";
+ cpu_green <= X"80";
+ cpu_blue <= X"80";
+
+ elsif rising_edge(clk) then
+ cg_ascii_posy_we <= '0';
+ cg_ascii_posx_we <= '0';
+ cg_ascii_data_we <= '0';
+ cg_clr_line <= '0';
+ cg_clr_screen <= '0';
+ addr := cpu_addr;
+ if cpu_we = '1' then
+ if cpu_io_sel = '1' then
+ case addr is
+ when X"01" => -- 01
+ cpu_led <= cpu_dout;
+ when X"02" => -- 04
+ cpu_red <= cpu_dout;
+ when X"03" => -- 04
+ cpu_green <= cpu_dout;
+ when X"04" => -- 04
+ cpu_blue <= cpu_dout;
+ when X"08" => -- 08
+ cg_ascii_data <= cpu_dout;
+ cg_ascii_posx_we <= '1';
+ when X"09" => -- 09
+ cg_ascii_data <= cpu_dout;
+ cg_ascii_posy_we <= '1';
+ when X"0A" => -- 0A
+ cg_ascii_data <= cpu_dout;
+ cg_ascii_data_we <= '1';
+ when X"0B" => -- 0B
+ cg_clr_screen <= cpu_dout(0);
+ cg_clr_line <= cpu_dout(1);
+ when others => null;
+ end case;
+ end if;
+ end if;
+ end if;
+ end process;
+
+ ---------------------------------------------------------------------------------------------
+ --- Test
+ ---------------------------------------------------------------------------------------------
+ cpu_start: process (rst, vga_clk)
+ begin
+ if (rst = '1') then
+ cpu_rst <= '1';
+ elsif rising_edge(vga_clk) and scan_rdy = '1' then
+ cpu_rst <= '0';
+ end if;
+ end process;
+
+ scan_start: process (rst, clk)
+ begin
+ if (rst = '1') then
+ scan_enable <= '0';
+ elsif rising_edge(clk) then
+ scan_enable <= '1';
+ end if;
+ end process;
+
+ color_sel: process (vga_clk)
+ begin
+ if rising_edge(vga_clk) and scan_rdy = '1' then
+ cpu_color <= (cpu_red, cpu_green, cpu_blue);
+ end if;
+ end process;
+
+ color_we <= scan_enable and src_enable and not fifo_full;
+
+ src_inc_reg: process (rst, clk)
+ begin
+ if (rst = '1') then
+ src_enable <= '0';
+ elsif rising_edge(clk) then
+ if fifo_full = '1' then
+ src_enable <= '0';
+ elsif fifo_almost_full = '0' then
+ src_enable <= '1';
+ end if;
+ end if;
+ end process;
+
+ color_ctrl: process (rst, clk)
+ variable enable : std_logic;
+ begin
+ if (rst = '1') then
+ src_pos_x <= 0;
+ src_pos_y <= 0;
+ elsif rising_edge(clk) then
+ if color_we = '1' then
+ if src_pos_x < tsvga.ts_h.ncyc_scan-1 then
+ src_pos_x <= src_pos_x + 1;
+ else
+ src_pos_x <= 0;
+ if src_pos_y < tsvga.ts_v.ncyc_scan-1 then
+ src_pos_y <= src_pos_y + 1;
+ else
+ src_pos_y <= 0;
+ end if;
+ end if;
+ end if;
+ end if;
+ end process;
+
+ color_gen: process (src_pos_x, src_pos_y)
+ begin
+ color_w <= (X"00", X"00", X"00");
+ if src_pos_y = 0 then
+ color_w <= (X"00", X"FF", X"00");
+ elsif src_pos_y = (tsvga.ts_v.ncyc_scan-1) then
+ color_w <= (X"00", X"FF", X"00");
+ elsif src_pos_x = 0 then
+ color_w <= (X"FF", X"00", X"00");
+ elsif src_pos_x = (tsvga.ts_h.ncyc_scan-1) then
+ color_w <= (X"00", X"00", X"FF");
+ end if;
+ end process;
+
+end Behavioral;
diff --git a/projects/vga_ctrl/syn/ise/project/bitgen.ut b/projects/vga_ctrl/syn/ise/project/bitgen.ut
new file mode 100644
index 0000000..1d23f16
--- /dev/null
+++ b/projects/vga_ctrl/syn/ise/project/bitgen.ut
@@ -0,0 +1,34 @@
+
+-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 DCMShutDown:Disable
+-g DCIUpdateMode:AsRequired
+-g StartUpClk:JtagClk
+-g DONE_cycle:4
+-g GTS_cycle:5
+-g GWE_cycle:6
+-g LCK_cycle:NoWait
+-g Security:None
+-g DonePipe:No
+-g DriveDone:No
+-g Encrypt:No
diff --git a/projects/vga_ctrl/syn/ise/project/pepExtractor.prj b/projects/vga_ctrl/syn/ise/project/pepExtractor.prj
new file mode 100644
index 0000000..18e0610
--- /dev/null
+++ b/projects/vga_ctrl/syn/ise/project/pepExtractor.prj
@@ -0,0 +1,4 @@
+work "fsm_scan.vhd"
+work "sdcwr.vhd"
+work "vga_ctrl_core.vhd"
+work "vga_types.vhd"
diff --git a/projects/vga_ctrl/syn/ise/project/prjname.lso b/projects/vga_ctrl/syn/ise/project/prjname.lso
new file mode 100644
index 0000000..22de730
--- /dev/null
+++ b/projects/vga_ctrl/syn/ise/project/prjname.lso
@@ -0,0 +1 @@
+work
diff --git a/projects/vga_ctrl/syn/ise/project/system.ucf b/projects/vga_ctrl/syn/ise/project/system.ucf
new file mode 100644
index 0000000..ded5c66
--- /dev/null
+++ b/projects/vga_ctrl/syn/ise/project/system.ucf
@@ -0,0 +1,142 @@
+#
+# XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+# SOLELY FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR
+# XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION
+# AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION
+# OR STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS
+# IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+# AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+# FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY
+# WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+# IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+# REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+# INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+# (c) Copyright 2005 Xilinx, Inc.
+# All rights reserved.
+#
+
+CONFIG STEPPING = "ES";
+
+# Bus clock nets
+NET sys_clk_in TNM_NET = "sys_clk_in";
+TIMESPEC "TS_sys_clk_in" = PERIOD "sys_clk_in" 9.9 ns HIGH 50 %;
+
+NET "inst_vga_backend/inst_clkgen/vga_clk0" TNM_NET = "vga_clk";
+#TIMESPEC "TS_vga_clk" = PERIOD "vga_clk" 7.5 ns HIGH 50 %;
+TIMESPEC TS_unrelate = FROM sys_clk_in TO vga_clk TIG;
+
+NET sys_clk_in LOC = AE14;
+NET sys_clk_in IOSTANDARD = LVCMOS33;
+NET sys_rstn_in LOC = D6;
+NET sys_rstn_in PULLUP;
+NET sys_rstn_in TIG;
+NET sys_rstn_in IOSTANDARD = LVCMOS33;
+
+
+////////////////////////////////////////////////////////////////////////////
+// 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<*>" IOSTANDARD = LVCMOS33;
+# 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;
+NET "sys_btn<*>" PULLDOWN;
+NET "sys_btn<*>" IOSTANDARD = LVCMOS33;
+# 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<*>" PULLDOWN;
+NET "sys_dip<*>" IOSTANDARD = LVCMOS33;
+NET "sys_dip<*>" TIG;
+
+#------------------------------------------------------------------------------
+# IO Pad Location Constraints / Properties for TFT VGA LCD Controller
+#------------------------------------------------------------------------------
+
+NET sys_vga_blue<0> LOC = M21; # VGA_B0
+NET sys_vga_blue<1> LOC = M26; # VGA_B1
+NET sys_vga_blue<2> LOC = L26; # VGA_B2
+NET sys_vga_blue<3> LOC = C5; # VGA_B3
+NET sys_vga_blue<4> LOC = C7; # VGA_B4
+NET sys_vga_blue<5> LOC = B7; # VGA_B5
+NET sys_vga_blue<6> LOC = G8; # VGA_B6
+NET sys_vga_blue<7> LOC = F8; # VGA_B7
+NET sys_vga_blue<*> IOSTANDARD = LVCMOS33;
+NET sys_vga_blue<*> SLEW = FAST;
+NET sys_vga_blue<*> DRIVE = 8;
+
+NET sys_vga_clk LOC = AF8;
+NET sys_vga_clk IOSTANDARD = LVDCI_33;
+NET sys_vga_clk SLEW = FAST;
+NET sys_vga_clk DRIVE = 8;
+
+NET sys_vga_green<0> LOC = M22; # VGA_G0
+NET sys_vga_green<1> LOC = M23; # VGA_G1
+NET sys_vga_green<2> LOC = M20; # VGA_G2
+NET sys_vga_green<3> LOC = E4; # VGA_G3
+NET sys_vga_green<4> LOC = D3; # VGA_G4
+NET sys_vga_green<5> LOC = H7; # VGA_G5
+NET sys_vga_green<6> LOC = H8; # VGA_G6
+NET sys_vga_green<7> LOC = C1; # VGA_G7
+NET sys_vga_green<*> IOSTANDARD = LVCMOS33;
+NET sys_vga_green<*> SLEW = FAST;
+NET sys_vga_green<*> DRIVE = 8;
+
+NET sys_vga_hsync LOC = C10;
+NET sys_vga_hsync SLEW = FAST;
+NET sys_vga_hsync DRIVE = 8;
+NET sys_vga_hsync IOSTANDARD = LVCMOS33;
+
+NET sys_vga_red<0> LOC = N23; #VGA_R0
+NET sys_vga_red<1> LOC = N24; #VGA_R1
+NET sys_vga_red<2> LOC = N25; #VGA_R2
+NET sys_vga_red<3> LOC = C2; #VGA_R3
+NET sys_vga_red<4> LOC = G7; #VGA_R4
+NET sys_vga_red<5> LOC = F7; #VGA_R5
+NET sys_vga_red<6> LOC = E5; #VGA_R6
+NET sys_vga_red<7> LOC = E6; #VGA_R7
+NET sys_vga_red<*> IOSTANDARD = LVCMOS33;
+NET sys_vga_red<*> SLEW = FAST;
+NET sys_vga_red<*> DRIVE = 8;
+
+NET sys_vga_vsync LOC = A8;
+NET sys_vga_vsync SLEW = FAST;
+NET sys_vga_vsync DRIVE = 8;
+NET sys_vga_vsync IOSTANDARD = LVCMOS33;
+
+NET sys_vga_blank_n LOC = M24;
+NET sys_vga_blank_n SLEW = FAST;
+NET sys_vga_blank_n DRIVE = 8;
+NET sys_vga_blank_n IOSTANDARD = LVCMOS33;
+
+NET sys_vga_sync_n LOC = L23;
+NET sys_vga_sync_n SLEW = FAST;
+NET sys_vga_sync_n DRIVE = 8;
+NET sys_vga_sync_n IOSTANDARD = LVCMOS33;
+
diff --git a/projects/vga_ctrl/syn/ise/project/tb_vga_ctrl.do b/projects/vga_ctrl/syn/ise/project/tb_vga_ctrl.do
new file mode 100644
index 0000000..ae70d00
--- /dev/null
+++ b/projects/vga_ctrl/syn/ise/project/tb_vga_ctrl.do
@@ -0,0 +1,17 @@
+## NOTE: Do not edit this file.
+## Autogenerated by ProjNav (creatfdo.tcl) on Thu Jul 06 20:49:07 Westeuropäische Sommerzeit 2006
+##
+vlib work
+vcom -explicit -93 "vga_types.vhd"
+vcom -explicit -93 "sdcwr.vhd"
+vcom -explicit -93 "fsm_scan.vhd"
+vcom -explicit -93 "vga_ctrl_core.vhd"
+vcom -explicit -93 "vga_ctrl_top.vhd"
+vcom -explicit -93 "tb_vga_ctrl.vhd"
+vsim -t 1ps -lib work tb_vga_ctrl_vhd
+view wave
+do {wave_vga_ctrl.do}
+view structure
+view signals
+
+run 10us
diff --git a/projects/vga_ctrl/syn/ise/project/tb_vga_ctrl_vhd.udo b/projects/vga_ctrl/syn/ise/project/tb_vga_ctrl_vhd.udo
new file mode 100644
index 0000000..9804722
--- /dev/null
+++ b/projects/vga_ctrl/syn/ise/project/tb_vga_ctrl_vhd.udo
@@ -0,0 +1,4 @@
+-- ProjNav VHDL simulation template: tb_vga_ctrl_vhd.udo
+-- You may edit this file after the line that starts with
+-- '-- START' to customize your simulation
+-- START user-defined simulation commands
diff --git a/projects/vga_ctrl/syn/ise/project/vga_ctrl_core.lso b/projects/vga_ctrl/syn/ise/project/vga_ctrl_core.lso
new file mode 100644
index 0000000..22de730
--- /dev/null
+++ b/projects/vga_ctrl/syn/ise/project/vga_ctrl_core.lso
@@ -0,0 +1 @@
+work
diff --git a/projects/vga_ctrl/syn/ise/project/vga_ctrl_core.prj b/projects/vga_ctrl/syn/ise/project/vga_ctrl_core.prj
new file mode 100644
index 0000000..339f32e
--- /dev/null
+++ b/projects/vga_ctrl/syn/ise/project/vga_ctrl_core.prj
@@ -0,0 +1,4 @@
+vhdl work "sdcwr.vhd"
+vhdl work "vga_types.vhd"
+vhdl work "fsm_scan.vhd"
+vhdl work "vga_ctrl_core.vhd"
diff --git a/projects/vga_ctrl/syn/ise/project/vga_ctrl_top.lso b/projects/vga_ctrl/syn/ise/project/vga_ctrl_top.lso
new file mode 100644
index 0000000..22de730
--- /dev/null
+++ b/projects/vga_ctrl/syn/ise/project/vga_ctrl_top.lso
@@ -0,0 +1 @@
+work
diff --git a/projects/vga_ctrl/syn/ise/project/vga_ctrl_top.prj b/projects/vga_ctrl/syn/ise/project/vga_ctrl_top.prj
new file mode 100644
index 0000000..26a89b0
--- /dev/null
+++ b/projects/vga_ctrl/syn/ise/project/vga_ctrl_top.prj
@@ -0,0 +1,17 @@
+vhdl work "../../../lib/FIFO/src/fifo_ctrl_pkg.vhd"
+vhdl work "../../../lib/VGA_ctrl/src/vga_types.vhd"
+vhdl work "../src/cpu_pkg.vhd"
+vhdl work "../../../lib/FIFO/src/gray_counter.vhd"
+vhdl work "../../../lib/VGA_ctrl/src/vga_sync.vhd"
+vhdl work "../../../lib/VGA_ctrl/src/dpram.vhd"
+vhdl work "../../../lib/FIFO/src/async_fifo_ctrl.vhd"
+vhdl work "../src/main_irom_ld.vhdl"
+vhdl work "../../../lib/VGA_ctrl/src/vga_timing.vhd"
+vhdl work "../../../lib/VGA_ctrl/src/linefifo.vhd"
+vhdl work "../../../lib/VGA_ctrl/src/fonts/char_rom_fixedsys_8x16.vhd"
+vhdl work "../../../lib/VGA_ctrl/src/clkgen_virtex4.vhd"
+vhdl work "../src/main_xrom_ld.vhdl"
+vhdl work "../src/cpu_embedded.vhd"
+vhdl work "../../../lib/VGA_ctrl/src/vga_backend.vhd"
+vhdl work "../../../lib/VGA_ctrl/src/char_gen.vhd"
+vhdl work "../src/vga_ctrl_top.vhd"
diff --git a/projects/vga_ctrl/syn/ise/project/vga_ctrl_top.ut b/projects/vga_ctrl/syn/ise/project/vga_ctrl_top.ut
new file mode 100644
index 0000000..9899d18
--- /dev/null
+++ b/projects/vga_ctrl/syn/ise/project/vga_ctrl_top.ut
@@ -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:0x4A454E53
+-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
diff --git a/projects/vga_ctrl/syn/ise/project/vga_ctrl_top.xst b/projects/vga_ctrl/syn/ise/project/vga_ctrl_top.xst
new file mode 100644
index 0000000..22e522a
--- /dev/null
+++ b/projects/vga_ctrl/syn/ise/project/vga_ctrl_top.xst
@@ -0,0 +1,59 @@
+set -tmpdir "./xst/projnav.tmp"
+set -xsthdpdir "./xst"
+run
+-ifn vga_ctrl_top.prj
+-ifmt mixed
+-ofn vga_ctrl_top
+-ofmt NGC
+-p xc4vsx35-10-ff668
+-top vga_ctrl_top
+-opt_mode Speed
+-opt_level 1
+-power NO
+-iuc NO
+-lso vga_ctrl_top.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 YES
+-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 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 false
+-equivalent_register_removal YES
+-slice_utilization_ratio_maxmargin 5
diff --git a/projects/vga_ctrl/syn/ise/project/vga_ctrl_top_vhdl.prj b/projects/vga_ctrl/syn/ise/project/vga_ctrl_top_vhdl.prj
new file mode 100644
index 0000000..2d3f27b
--- /dev/null
+++ b/projects/vga_ctrl/syn/ise/project/vga_ctrl_top_vhdl.prj
@@ -0,0 +1,17 @@
+vhdl work "W:\vhdl\lib\FIFO\src\fifo_ctrl_pkg.vhd"
+vhdl work "W:\vhdl\lib\VGA_ctrl\src\vga_types.vhd"
+vhdl work "W:\vhdl\projects\vga_ctrl\src\cpu_pkg.vhd"
+vhdl work "W:\vhdl\lib\FIFO\src\gray_counter.vhd"
+vhdl work "W:\vhdl\lib\VGA_ctrl\src\vga_sync.vhd"
+vhdl work "W:\vhdl\lib\VGA_ctrl\src\dpram.vhd"
+vhdl work "W:\vhdl\lib\FIFO\src\async_fifo_ctrl.vhd"
+vhdl work "W:\vhdl\projects\vga_ctrl\src\main_irom_ld.vhdl"
+vhdl work "W:\vhdl\lib\VGA_ctrl\src\vga_timing.vhd"
+vhdl work "W:\vhdl\lib\VGA_ctrl\src\linefifo.vhd"
+vhdl work "W:\vhdl\lib\VGA_ctrl\src\fonts\char_rom_fixedsys_8x16.vhd"
+vhdl work "W:\vhdl\lib\VGA_ctrl\src\clkgen_virtex4.vhd"
+vhdl work "W:\vhdl\projects\vga_ctrl\src\main_xrom_ld.vhdl"
+vhdl work "W:\vhdl\projects\vga_ctrl\src\cpu_embedded.vhd"
+vhdl work "W:\vhdl\lib\VGA_ctrl\src\vga_backend.vhd"
+vhdl work "W:\vhdl\lib\VGA_ctrl\src\char_gen.vhd"
+vhdl work "W:\vhdl\projects\vga_ctrl\src\vga_ctrl_top.vhd"
diff --git a/projects/vga_ctrl/syn/ise/project/vga_types_vhdl.prj b/projects/vga_ctrl/syn/ise/project/vga_types_vhdl.prj
new file mode 100644
index 0000000..b8edb0c
--- /dev/null
+++ b/projects/vga_ctrl/syn/ise/project/vga_types_vhdl.prj
@@ -0,0 +1 @@
+work "vga_types.vhd"
diff --git a/projects/vga_ctrl/syn/ise/project/wave_vga_ctrl.do b/projects/vga_ctrl/syn/ise/project/wave_vga_ctrl.do
new file mode 100644
index 0000000..8d54326
--- /dev/null
+++ b/projects/vga_ctrl/syn/ise/project/wave_vga_ctrl.do
@@ -0,0 +1,35 @@
+onerror {resume}
+quietly WaveActivateNextPane {} 0
+add wave -noupdate -format Logic /tb_vga_ctrl_vhd/sys_rstn_in
+add wave -noupdate -format Logic /tb_vga_ctrl_vhd/sys_clk_in
+add wave -noupdate -format Logic /tb_vga_ctrl_vhd/sys_vga_clk
+add wave -noupdate -format Logic /tb_vga_ctrl_vhd/uut/hsync_i
+add wave -noupdate -format Logic /tb_vga_ctrl_vhd/uut/vsync_i
+add wave -noupdate -format Literal /tb_vga_ctrl_vhd/sys_vga_red
+add wave -noupdate -format Literal /tb_vga_ctrl_vhd/sys_vga_green
+add wave -noupdate -format Literal /tb_vga_ctrl_vhd/sys_vga_blue
+add wave -noupdate -format Logic /tb_vga_ctrl_vhd/sys_vga_clk
+add wave -noupdate -format Logic /tb_vga_ctrl_vhd/sys_vga_hsync
+add wave -noupdate -format Logic /tb_vga_ctrl_vhd/sys_vga_vsync
+add wave -noupdate -format Logic /tb_vga_ctrl_vhd/uut/is_scan_h
+add wave -noupdate -format Logic /tb_vga_ctrl_vhd/uut/is_scan_v
+add wave -noupdate -format Logic /tb_vga_ctrl_vhd/uut/h_scan_rdy
+add wave -noupdate -format Logic /tb_vga_ctrl_vhd/uut/v_scan_rdy
+add wave -noupdate -format Logic /tb_vga_ctrl_vhd/sys_dcm_locked
+add wave -noupdate -format Logic /tb_vga_ctrl_vhd/uut/clk_scan_rdy
+TreeUpdate [SetDefaultTree]
+WaveRestoreCursors {{Cursor 1} {1908400 ps} 0}
+configure wave -namecolwidth 212
+configure wave -valuecolwidth 68
+configure wave -justifyvalue left
+configure wave -signalnamewidth 1
+configure wave -snapdistance 10
+configure wave -datasetprefix 0
+configure wave -rowmargin 4
+configure wave -childrowmargin 2
+configure wave -gridoffset 0
+configure wave -gridperiod 1
+configure wave -griddelta 40
+configure wave -timeline 0
+update
+WaveRestoreZoom {993377 ps} {2954189 ps}