summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2011-06-04 23:36:03 (GMT)
committerH. Peter Anvin <hpa@zytor.com>2011-06-04 23:36:03 (GMT)
commitc683552974872354785eb31dc4e18498560d46a3 (patch)
treed1416486b7bf020aab672a2c672c5270499a94e9
downloadde1flash-c683552974872354785eb31dc4e18498560d46a3.zip
de1flash-c683552974872354785eb31dc4e18498560d46a3.tar.gz
de1flash-c683552974872354785eb31dc4e18498560d46a3.tar.bz2
de1flash-c683552974872354785eb31dc4e18498560d46a3.tar.xz
Utility to flash the NOR flash on an Altera DE1 board over JTAG
-rw-r--r--.gitignore18
-rw-r--r--README50
-rw-r--r--de1flash.qpf30
-rw-r--r--de1flash.qsf347
-rw-r--r--de1flash.sdc41
-rw-r--r--de1flash.tcl294
-rw-r--r--de1flash.v828
-rw-r--r--fl_fifo.qip4
-rw-r--r--fl_fifo.v185
-rw-r--r--hexled.v72
-rw-r--r--pll.qip5
-rw-r--r--pll.v323
-rw-r--r--protocol.txt61
-rw-r--r--vjtag_mega.qip6
-rw-r--r--vjtag_mega.v181
15 files changed, 2445 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..3a195d0
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,18 @@
+/db
+/greybox_tmp
+/incremental_db
+*_bb.v
+*.bsf
+*_inst.v
+*.rpt
+*.cdf
+*.done
+*.summary
+*.jdi
+*.smsg
+*.pin
+*.pof
+*.sof
+*.ppf
+*~
+#*
diff --git a/README b/README
new file mode 100644
index 0000000..44beb0b
--- /dev/null
+++ b/README
@@ -0,0 +1,50 @@
+## -----------------------------------------------------------------------
+##
+## Copyright 2011 H. Peter Anvin - All Rights Reserved
+##
+## Permission is hereby granted, free of charge, to any person
+## obtaining a copy of this software and associated documentation
+## files (the "Software"), to deal in the Software without
+## restriction, including without limitation the rights to use,
+## copy, modify, merge, publish, distribute, sublicense, and/or
+## sell copies of the Software, and to permit persons to whom
+## the Software is furnished to do so, subject to the following
+## conditions:
+##
+## The above copyright notice and this permission notice shall
+## be included in all copies or substantial portions of the Software.
+##
+## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+## EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+## OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+## NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+## HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+## WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+## FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+## OTHER DEALINGS IN THE SOFTWARE.
+##
+## -----------------------------------------------------------------------
+
+This is a combination of a FPGA design and a Tcl program to read and
+write the flash part on a Terasic DE1/Altera Cyclone II Starter Kit
+FPGA development board.
+
+It should be fairly trivial to port to other boards using parallel
+NOR flash with Altera FPGAs; porting to other vendors will require
+porting to their specific JTAG solution.
+
+Currently this only supports one file and writing from the start of
+the flash; this I hope to fix in the near future:
+
+Usage:
+
+ # First upload the FPGA design
+ quartus_pgm -m JTAG -p 'p;de1flash.sof'
+
+ # Second, execute either of these commands
+ quartus_stp -t de1flash.tcl read filename [length]
+ quartus_stp -t de1flash.tcl write filename [length]
+ quartus_stp -t de1flash.tcl eraseall
+
+Note that it is NOT necessary to erase before writing; the utility
+will automatically erase any sectors that are being written.
diff --git a/de1flash.qpf b/de1flash.qpf
new file mode 100644
index 0000000..6c4d9ae
--- /dev/null
+++ b/de1flash.qpf
@@ -0,0 +1,30 @@
+# -------------------------------------------------------------------------- #
+#
+# Copyright (C) 1991-2011 Altera Corporation
+# Your use of Altera Corporation's design tools, logic functions
+# and other software and tools, and its AMPP partner logic
+# functions, and any output files from any of the foregoing
+# (including device programming or simulation files), and any
+# associated documentation or information are expressly subject
+# to the terms and conditions of the Altera Program License
+# Subscription Agreement, Altera MegaCore Function License
+# Agreement, or other applicable license agreement, including,
+# without limitation, that your use is for the sole purpose of
+# programming logic devices manufactured by Altera and sold by
+# Altera or its authorized distributors. Please refer to the
+# applicable agreement for further details.
+#
+# -------------------------------------------------------------------------- #
+#
+# Quartus II
+# Version 11.0 Build 157 04/27/2011 SJ Web Edition
+# Date created = 15:03:51 May 30, 2011
+#
+# -------------------------------------------------------------------------- #
+
+QUARTUS_VERSION = "11.0"
+DATE = "15:03:51 May 30, 2011"
+
+# Revisions
+
+PROJECT_REVISION = "de1flash"
diff --git a/de1flash.qsf b/de1flash.qsf
new file mode 100644
index 0000000..f1bbf50
--- /dev/null
+++ b/de1flash.qsf
@@ -0,0 +1,347 @@
+# -------------------------------------------------------------------------- #
+#
+# Copyright (C) 1991-2011 Altera Corporation
+# Your use of Altera Corporation's design tools, logic functions
+# and other software and tools, and its AMPP partner logic
+# functions, and any output files from any of the foregoing
+# (including device programming or simulation files), and any
+# associated documentation or information are expressly subject
+# to the terms and conditions of the Altera Program License
+# Subscription Agreement, Altera MegaCore Function License
+# Agreement, or other applicable license agreement, including,
+# without limitation, that your use is for the sole purpose of
+# programming logic devices manufactured by Altera and sold by
+# Altera or its authorized distributors. Please refer to the
+# applicable agreement for further details.
+#
+# -------------------------------------------------------------------------- #
+#
+# Quartus II
+# Version 11.0 Build 157 04/27/2011 SJ Web Edition
+# Date created = 15:03:51 May 30, 2011
+#
+# -------------------------------------------------------------------------- #
+#
+# Notes:
+#
+# 1) The default values for assignments are stored in the file:
+# de1flash_assignment_defaults.qdf
+# If this file doesn't exist, see file:
+# assignment_defaults.qdf
+#
+# 2) Altera recommends that you do not modify this file. This
+# file is updated automatically by the Quartus II software
+# and any changes you make may be lost or overwritten.
+#
+# -------------------------------------------------------------------------- #
+
+
+set_global_assignment -name FAMILY "Cyclone II"
+set_global_assignment -name DEVICE EP2C20F484C7
+set_global_assignment -name TOP_LEVEL_ENTITY de1flash
+set_global_assignment -name ORIGINAL_QUARTUS_VERSION 11.0
+set_global_assignment -name PROJECT_CREATION_TIME_DATE "15:03:51 MAY 30, 2011"
+set_global_assignment -name LAST_QUARTUS_VERSION 11.0
+set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0
+set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85
+set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR 1
+set_location_assignment PIN_A13 -to gpio_0[0]
+set_location_assignment PIN_B13 -to gpio_0[1]
+set_location_assignment PIN_A14 -to gpio_0[2]
+set_location_assignment PIN_B14 -to gpio_0[3]
+set_location_assignment PIN_A15 -to gpio_0[4]
+set_location_assignment PIN_B15 -to gpio_0[5]
+set_location_assignment PIN_A16 -to gpio_0[6]
+set_location_assignment PIN_B16 -to gpio_0[7]
+set_location_assignment PIN_A17 -to gpio_0[8]
+set_location_assignment PIN_B17 -to gpio_0[9]
+set_location_assignment PIN_A18 -to gpio_0[10]
+set_location_assignment PIN_B18 -to gpio_0[11]
+set_location_assignment PIN_A19 -to gpio_0[12]
+set_location_assignment PIN_B19 -to gpio_0[13]
+set_location_assignment PIN_A20 -to gpio_0[14]
+set_location_assignment PIN_B20 -to gpio_0[15]
+set_location_assignment PIN_C21 -to gpio_0[16]
+set_location_assignment PIN_C22 -to gpio_0[17]
+set_location_assignment PIN_D21 -to gpio_0[18]
+set_location_assignment PIN_D22 -to gpio_0[19]
+set_location_assignment PIN_E21 -to gpio_0[20]
+set_location_assignment PIN_E22 -to gpio_0[21]
+set_location_assignment PIN_F21 -to gpio_0[22]
+set_location_assignment PIN_F22 -to gpio_0[23]
+set_location_assignment PIN_G21 -to gpio_0[24]
+set_location_assignment PIN_G22 -to gpio_0[25]
+set_location_assignment PIN_J21 -to gpio_0[26]
+set_location_assignment PIN_J22 -to gpio_0[27]
+set_location_assignment PIN_K21 -to gpio_0[28]
+set_location_assignment PIN_K22 -to gpio_0[29]
+set_location_assignment PIN_J19 -to gpio_0[30]
+set_location_assignment PIN_J20 -to gpio_0[31]
+set_location_assignment PIN_J18 -to gpio_0[32]
+set_location_assignment PIN_K20 -to gpio_0[33]
+set_location_assignment PIN_L19 -to gpio_0[34]
+set_location_assignment PIN_L18 -to gpio_0[35]
+set_location_assignment PIN_H12 -to gpio_1[0]
+set_location_assignment PIN_H13 -to gpio_1[1]
+set_location_assignment PIN_H14 -to gpio_1[2]
+set_location_assignment PIN_G15 -to gpio_1[3]
+set_location_assignment PIN_E14 -to gpio_1[4]
+set_location_assignment PIN_E15 -to gpio_1[5]
+set_location_assignment PIN_F15 -to gpio_1[6]
+set_location_assignment PIN_G16 -to gpio_1[7]
+set_location_assignment PIN_F12 -to gpio_1[8]
+set_location_assignment PIN_F13 -to gpio_1[9]
+set_location_assignment PIN_C14 -to gpio_1[10]
+set_location_assignment PIN_D14 -to gpio_1[11]
+set_location_assignment PIN_D15 -to gpio_1[12]
+set_location_assignment PIN_D16 -to gpio_1[13]
+set_location_assignment PIN_C17 -to gpio_1[14]
+set_location_assignment PIN_C18 -to gpio_1[15]
+set_location_assignment PIN_C19 -to gpio_1[16]
+set_location_assignment PIN_C20 -to gpio_1[17]
+set_location_assignment PIN_D19 -to gpio_1[18]
+set_location_assignment PIN_D20 -to gpio_1[19]
+set_location_assignment PIN_E20 -to gpio_1[20]
+set_location_assignment PIN_F20 -to gpio_1[21]
+set_location_assignment PIN_E19 -to gpio_1[22]
+set_location_assignment PIN_E18 -to gpio_1[23]
+set_location_assignment PIN_G20 -to gpio_1[24]
+set_location_assignment PIN_G18 -to gpio_1[25]
+set_location_assignment PIN_G17 -to gpio_1[26]
+set_location_assignment PIN_H17 -to gpio_1[27]
+set_location_assignment PIN_J15 -to gpio_1[28]
+set_location_assignment PIN_H18 -to gpio_1[29]
+set_location_assignment PIN_N22 -to gpio_1[30]
+set_location_assignment PIN_N21 -to gpio_1[31]
+set_location_assignment PIN_P15 -to gpio_1[32]
+set_location_assignment PIN_N15 -to gpio_1[33]
+set_location_assignment PIN_P17 -to gpio_1[34]
+set_location_assignment PIN_P18 -to gpio_1[35]
+set_location_assignment PIN_L22 -to sw[0]
+set_location_assignment PIN_L21 -to sw[1]
+set_location_assignment PIN_M22 -to sw[2]
+set_location_assignment PIN_V12 -to sw[3]
+set_location_assignment PIN_W12 -to sw[4]
+set_location_assignment PIN_U12 -to sw[5]
+set_location_assignment PIN_U11 -to sw[6]
+set_location_assignment PIN_M2 -to sw[7]
+set_location_assignment PIN_M1 -to sw[8]
+set_location_assignment PIN_L2 -to sw[9]
+set_location_assignment PIN_J2 -to s7_0[0]
+set_location_assignment PIN_J1 -to s7_0[1]
+set_location_assignment PIN_H2 -to s7_0[2]
+set_location_assignment PIN_H1 -to s7_0[3]
+set_location_assignment PIN_F2 -to s7_0[4]
+set_location_assignment PIN_F1 -to s7_0[5]
+set_location_assignment PIN_E2 -to s7_0[6]
+set_location_assignment PIN_E1 -to s7_1[0]
+set_location_assignment PIN_H6 -to s7_1[1]
+set_location_assignment PIN_H5 -to s7_1[2]
+set_location_assignment PIN_H4 -to s7_1[3]
+set_location_assignment PIN_G3 -to s7_1[4]
+set_location_assignment PIN_D2 -to s7_1[5]
+set_location_assignment PIN_D1 -to s7_1[6]
+set_location_assignment PIN_G5 -to s7_2[0]
+set_location_assignment PIN_G6 -to s7_2[1]
+set_location_assignment PIN_C2 -to s7_2[2]
+set_location_assignment PIN_C1 -to s7_2[3]
+set_location_assignment PIN_E3 -to s7_2[4]
+set_location_assignment PIN_E4 -to s7_2[5]
+set_location_assignment PIN_D3 -to s7_2[6]
+set_location_assignment PIN_F4 -to s7_3[0]
+set_location_assignment PIN_D5 -to s7_3[1]
+set_location_assignment PIN_D6 -to s7_3[2]
+set_location_assignment PIN_J4 -to s7_3[3]
+set_location_assignment PIN_L8 -to s7_3[4]
+set_location_assignment PIN_F3 -to s7_3[5]
+set_location_assignment PIN_D4 -to s7_3[6]
+set_location_assignment PIN_R22 -to key_n[0]
+set_location_assignment PIN_R21 -to key_n[1]
+set_location_assignment PIN_T22 -to key_n[2]
+set_location_assignment PIN_T21 -to key_n[3]
+set_location_assignment PIN_R20 -to ledr[0]
+set_location_assignment PIN_R19 -to ledr[1]
+set_location_assignment PIN_U19 -to ledr[2]
+set_location_assignment PIN_Y19 -to ledr[3]
+set_location_assignment PIN_T18 -to ledr[4]
+set_location_assignment PIN_V19 -to ledr[5]
+set_location_assignment PIN_Y18 -to ledr[6]
+set_location_assignment PIN_U18 -to ledr[7]
+set_location_assignment PIN_R18 -to ledr[8]
+set_location_assignment PIN_R17 -to ledr[9]
+set_location_assignment PIN_U22 -to ledg[0]
+set_location_assignment PIN_U21 -to ledg[1]
+set_location_assignment PIN_V22 -to ledg[2]
+set_location_assignment PIN_V21 -to ledg[3]
+set_location_assignment PIN_W22 -to ledg[4]
+set_location_assignment PIN_W21 -to ledg[5]
+set_location_assignment PIN_Y22 -to ledg[6]
+set_location_assignment PIN_Y21 -to ledg[7]
+set_location_assignment PIN_D12 -to clock_27[0]
+set_location_assignment PIN_E12 -to clock_27[1]
+set_location_assignment PIN_B12 -to clock_24[0]
+set_location_assignment PIN_A12 -to clock_24[1]
+set_location_assignment PIN_L1 -to clock_50
+set_location_assignment PIN_M21 -to ext_clock
+set_location_assignment PIN_H15 -to ps2_clk
+set_location_assignment PIN_J14 -to ps2_dat
+set_location_assignment PIN_F14 -to uart_rxd
+set_location_assignment PIN_G12 -to uart_txd
+set_location_assignment PIN_E8 -to tdi
+set_location_assignment PIN_D8 -to tcs
+set_location_assignment PIN_C7 -to tck
+set_location_assignment PIN_D7 -to tdo
+set_location_assignment PIN_D9 -to vga_r[0]
+set_location_assignment PIN_C9 -to vga_r[1]
+set_location_assignment PIN_A7 -to vga_r[2]
+set_location_assignment PIN_B7 -to vga_r[3]
+set_location_assignment PIN_B8 -to vga_g[0]
+set_location_assignment PIN_C10 -to vga_g[1]
+set_location_assignment PIN_B9 -to vga_g[2]
+set_location_assignment PIN_A8 -to vga_g[3]
+set_location_assignment PIN_A9 -to vga_b[0]
+set_location_assignment PIN_D11 -to vga_b[1]
+set_location_assignment PIN_A10 -to vga_b[2]
+set_location_assignment PIN_B10 -to vga_b[3]
+set_location_assignment PIN_A11 -to vga_hs
+set_location_assignment PIN_B11 -to vga_vs
+set_location_assignment PIN_A3 -to i2c_scl
+set_location_assignment PIN_B3 -to i2c_sda
+set_location_assignment PIN_A6 -to aud_adclrck
+set_location_assignment PIN_B6 -to aud_adcdat
+set_location_assignment PIN_A5 -to aud_daclrck
+set_location_assignment PIN_B5 -to aud_dacdat
+set_location_assignment PIN_B4 -to aud_xck
+set_location_assignment PIN_A4 -to aud_bclk
+set_location_assignment PIN_W4 -to dram_a[0]
+set_location_assignment PIN_W5 -to dram_a[1]
+set_location_assignment PIN_Y3 -to dram_a[2]
+set_location_assignment PIN_Y4 -to dram_a[3]
+set_location_assignment PIN_R6 -to dram_a[4]
+set_location_assignment PIN_R5 -to dram_a[5]
+set_location_assignment PIN_P6 -to dram_a[6]
+set_location_assignment PIN_P5 -to dram_a[7]
+set_location_assignment PIN_P3 -to dram_a[8]
+set_location_assignment PIN_N4 -to dram_a[9]
+set_location_assignment PIN_W3 -to dram_a[10]
+set_location_assignment PIN_N6 -to dram_a[11]
+set_location_assignment PIN_U3 -to dram_ba[0]
+set_location_assignment PIN_V4 -to dram_ba[1]
+set_location_assignment PIN_T3 -to dram_cas_n
+set_location_assignment PIN_N3 -to dram_cke
+set_location_assignment PIN_U4 -to dram_clk
+set_location_assignment PIN_T6 -to dram_cs_n
+set_location_assignment PIN_U1 -to dram_dq[0]
+set_location_assignment PIN_U2 -to dram_dq[1]
+set_location_assignment PIN_V1 -to dram_dq[2]
+set_location_assignment PIN_V2 -to dram_dq[3]
+set_location_assignment PIN_W1 -to dram_dq[4]
+set_location_assignment PIN_W2 -to dram_dq[5]
+set_location_assignment PIN_Y1 -to dram_dq[6]
+set_location_assignment PIN_Y2 -to dram_dq[7]
+set_location_assignment PIN_N1 -to dram_dq[8]
+set_location_assignment PIN_N2 -to dram_dq[9]
+set_location_assignment PIN_P1 -to dram_dq[10]
+set_location_assignment PIN_P2 -to dram_dq[11]
+set_location_assignment PIN_R1 -to dram_dq[12]
+set_location_assignment PIN_R2 -to dram_dq[13]
+set_location_assignment PIN_T1 -to dram_dq[14]
+set_location_assignment PIN_T2 -to dram_dq[15]
+set_location_assignment PIN_R7 -to dram_dqm[0]
+set_location_assignment PIN_T5 -to dram_ras_n
+set_location_assignment PIN_M5 -to dram_dqm[1]
+set_location_assignment PIN_R8 -to dram_we_n
+set_location_assignment PIN_AB20 -to fl_a[0]
+set_location_assignment PIN_AA14 -to fl_a[1]
+set_location_assignment PIN_Y16 -to fl_a[2]
+set_location_assignment PIN_R15 -to fl_a[3]
+set_location_assignment PIN_T15 -to fl_a[4]
+set_location_assignment PIN_U15 -to fl_a[5]
+set_location_assignment PIN_V15 -to fl_a[6]
+set_location_assignment PIN_W15 -to fl_a[7]
+set_location_assignment PIN_R14 -to fl_a[8]
+set_location_assignment PIN_Y13 -to fl_a[9]
+set_location_assignment PIN_R12 -to fl_a[10]
+set_location_assignment PIN_T12 -to fl_a[11]
+set_location_assignment PIN_AB14 -to fl_a[12]
+set_location_assignment PIN_AA13 -to fl_a[13]
+set_location_assignment PIN_AB13 -to fl_a[14]
+set_location_assignment PIN_AA12 -to fl_a[15]
+set_location_assignment PIN_AB12 -to fl_a[16]
+set_location_assignment PIN_AA20 -to fl_a[17]
+set_location_assignment PIN_U14 -to fl_a[18]
+set_location_assignment PIN_V14 -to fl_a[19]
+set_location_assignment PIN_U13 -to fl_a[20]
+set_location_assignment PIN_R13 -to fl_a[21]
+set_location_assignment PIN_AB16 -to fl_dq[0]
+set_location_assignment PIN_AA16 -to fl_dq[1]
+set_location_assignment PIN_AB17 -to fl_dq[2]
+set_location_assignment PIN_AA17 -to fl_dq[3]
+set_location_assignment PIN_AB18 -to fl_dq[4]
+set_location_assignment PIN_AA18 -to fl_dq[5]
+set_location_assignment PIN_AB19 -to fl_dq[6]
+set_location_assignment PIN_AA19 -to fl_dq[7]
+set_location_assignment PIN_AA15 -to fl_oe_n
+set_location_assignment PIN_W14 -to fl_rst_n
+set_location_assignment PIN_Y14 -to fl_we_n
+set_location_assignment PIN_AB15 -to fl_ce_n
+set_location_assignment PIN_AA3 -to sram_a[0]
+set_location_assignment PIN_AB3 -to sram_a[1]
+set_location_assignment PIN_AA4 -to sram_a[2]
+set_location_assignment PIN_AB4 -to sram_a[3]
+set_location_assignment PIN_AA5 -to sram_a[4]
+set_location_assignment PIN_AB10 -to sram_a[5]
+set_location_assignment PIN_AA11 -to sram_a[6]
+set_location_assignment PIN_AB11 -to sram_a[7]
+set_location_assignment PIN_V11 -to sram_a[8]
+set_location_assignment PIN_W11 -to sram_a[9]
+set_location_assignment PIN_R11 -to sram_a[10]
+set_location_assignment PIN_T11 -to sram_a[11]
+set_location_assignment PIN_Y10 -to sram_a[12]
+set_location_assignment PIN_U10 -to sram_a[13]
+set_location_assignment PIN_R10 -to sram_a[14]
+set_location_assignment PIN_T7 -to sram_a[15]
+set_location_assignment PIN_Y6 -to sram_a[16]
+set_location_assignment PIN_Y5 -to sram_a[17]
+set_location_assignment PIN_AB5 -to sram_ce_n
+set_location_assignment PIN_AA6 -to sram_dq[0]
+set_location_assignment PIN_AB6 -to sram_dq[1]
+set_location_assignment PIN_AA7 -to sram_dq[2]
+set_location_assignment PIN_AB7 -to sram_dq[3]
+set_location_assignment PIN_AA8 -to sram_dq[4]
+set_location_assignment PIN_AB8 -to sram_dq[5]
+set_location_assignment PIN_AA9 -to sram_dq[6]
+set_location_assignment PIN_AB9 -to sram_dq[7]
+set_location_assignment PIN_Y9 -to sram_dq[8]
+set_location_assignment PIN_W9 -to sram_dq[9]
+set_location_assignment PIN_V9 -to sram_dq[10]
+set_location_assignment PIN_U9 -to sram_dq[11]
+set_location_assignment PIN_R9 -to sram_dq[12]
+set_location_assignment PIN_W8 -to sram_dq[13]
+set_location_assignment PIN_V8 -to sram_dq[14]
+set_location_assignment PIN_U8 -to sram_dq[15]
+set_location_assignment PIN_Y7 -to sram_be_n[0]
+set_location_assignment PIN_T8 -to sram_oe_n
+set_location_assignment PIN_W7 -to sram_be_n[1]
+set_location_assignment PIN_AA10 -to sram_we_n
+set_location_assignment PIN_V20 -to sd_clk
+set_location_assignment PIN_Y20 -to sd_cmd
+set_location_assignment PIN_W20 -to sd_dat0
+set_location_assignment PIN_U20 -to sd_dat3
+
+set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
+set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top
+set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
+set_global_assignment -name USE_CONFIGURATION_DEVICE ON
+set_global_assignment -name RESERVE_ALL_UNUSED_PINS "AS INPUT TRI-STATED WITH WEAK PULL-UP"
+set_global_assignment -name CYCLONEII_RESERVE_NCEO_AFTER_CONFIGURATION "USE AS REGULAR IO"
+set_global_assignment -name RESERVE_ASDO_AFTER_CONFIGURATION "USE AS REGULAR IO"
+set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "NO HEAT SINK WITH STILL AIR"
+set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)"
+set_global_assignment -name VERILOG_FILE hexled.v
+set_global_assignment -name VERILOG_FILE de1flash.v
+set_global_assignment -name QIP_FILE vjtag_mega.qip
+set_global_assignment -name SDC_FILE de1flash.sdc
+set_global_assignment -name QIP_FILE pll.qip
+set_global_assignment -name QIP_FILE fl_fifo.qip
+set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file
diff --git a/de1flash.sdc b/de1flash.sdc
new file mode 100644
index 0000000..41b6d33
--- /dev/null
+++ b/de1flash.sdc
@@ -0,0 +1,41 @@
+#************************************************************
+# THIS IS A WIZARD-GENERATED FILE.
+#
+# Version 11.0 Build 157 04/27/2011 SJ Web Edition
+#
+#************************************************************
+
+# Copyright (C) 1991-2011 Altera Corporation
+# Your use of Altera Corporation's design tools, logic functions
+# and other software and tools, and its AMPP partner logic
+# functions, and any output files from any of the foregoing
+# (including device programming or simulation files), and any
+# associated documentation or information are expressly subject
+# to the terms and conditions of the Altera Program License
+# Subscription Agreement, Altera MegaCore Function License
+# Agreement, or other applicable license agreement, including,
+# without limitation, that your use is for the sole purpose of
+# programming logic devices manufactured by Altera and sold by
+# Altera or its authorized distributors. Please refer to the
+# applicable agreement for further details.
+
+
+
+# Clock constraints
+
+create_clock -name "clock_50" -period 20.000ns [get_ports {clock_50}] -waveform {0.000 10.000}
+
+
+# Automatically constrain PLL and other generated clocks
+derive_pll_clocks -create_base_clocks
+
+# Automatically calculate clock uncertainty to jitter and other effects.
+#derive_clock_uncertainty
+# Not supported for family Cyclone II
+
+# tsu/th constraints
+
+# tco constraints
+
+# tpd constraints
+
diff --git a/de1flash.tcl b/de1flash.tcl
new file mode 100644
index 0000000..0480e82
--- /dev/null
+++ b/de1flash.tcl
@@ -0,0 +1,294 @@
+## -----------------------------------------------------------------------
+##
+## Copyright 2011 H. Peter Anvin - All Rights Reserved
+##
+## Permission is hereby granted, free of charge, to any person
+## obtaining a copy of this software and associated documentation
+## files (the "Software"), to deal in the Software without
+## restriction, including without limitation the rights to use,
+## copy, modify, merge, publish, distribute, sublicense, and/or
+## sell copies of the Software, and to permit persons to whom
+## the Software is furnished to do so, subject to the following
+## conditions:
+##
+## The above copyright notice and this permission notice shall
+## be included in all copies or substantial portions of the Software.
+##
+## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+## EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+## OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+## NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+## HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+## WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+## FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+## OTHER DEALINGS IN THE SOFTWARE.
+##
+## -----------------------------------------------------------------------
+
+# Virtual JTAG instance index
+set fl_instance 0
+# Current IR value
+set fl_current_ir -1
+# Known space in the write FIFO
+set fl_free_space 0
+
+# Device parameters which really should come from reading the CFI data
+set fl_device_size 0x400000
+proc fl_sector_size addr {
+ expr ($addr < 65536) ? 8192 : 65536
+}
+
+proc select_ir new_ir {
+ global fl_instance fl_current_ir
+ if { $new_ir != $fl_current_ir } {
+ device_virtual_ir_shift -instance_index $fl_instance \
+ -ir_value $new_ir -no_captured_ir_value
+ set fl_current_ir $new_ir
+ }
+}
+
+# Send a command (given as a 72-bit hex string)
+proc fl_send cmd {
+ global fl_instance fl_free_space
+
+ while { $fl_free_space < 1 } {
+ # Poll the free space register until nonzero
+ select_ir 2
+ scan [device_virtual_dr_shift -instance_index $fl_instance \
+ -length 8 -value_in_hex] "%x" fl_free_space
+ }
+
+ select_ir 3
+ device_virtual_dr_shift -instance_index $fl_instance \
+ -dr_value $cmd -length 72 -value_in_hex -no_captured_dr_value
+ incr fl_free_space -1
+}
+
+# Receive a reply (returned as a 72-bit hex string)
+proc fl_recv {} {
+ global fl_instance
+
+ set status 0
+
+ select_ir 1
+ while { ($status & 0x80) == 0 } {
+ set v [device_virtual_dr_shift -instance_index $fl_instance \
+ -length 72 -value_in_hex]
+ scan $v "%2x" status
+ }
+ return $v
+}
+
+# Receive bulk data (returned as a binary string)
+proc fl_recv_bulk bytes {
+ global fl_instance
+
+ select_ir 1
+
+ set qwords [expr ($bytes + 7) >> 3]
+ set outdata ""
+
+ while { $qwords } {
+ set d [device_virtual_dr_shift -instance_index $fl_instance \
+ -length [expr $qwords * 72] -value_in_hex]
+
+ # The LSW is the first transaction, so we need to process
+ # the returned string backwards
+ for { set n [expr $qwords - 1] } { $n >= 0 } { incr n -1 } {
+ set ix [expr $n * 18]
+ set di [string range $d $ix [expr $ix + 17]]
+ scan $di "%2x%2x%2x%2x%2x%2x%2x%2x%2x" st d7 d6 d5 d4 d3 d2 d1 d0
+ if { $st & 0x80 } {
+ set bd [binary format cccccccc $d0 $d1 $d2 $d3 $d4 $d5 $d6 $d7]
+ set nbytes 8
+ if { $bytes < 8 } {
+ set bd [string range $bd 0 [expr $bytes - 1]]
+ set nbytes $bytes
+ }
+ append outdata $bd
+ incr qwords -1
+ set bytes [expr $bytes - $nbytes]
+ } else {
+ # puts "Dropping non-data: $di"
+ }
+ }
+ }
+ return $outdata
+}
+
+# Reset state machine
+proc fl_reset {} {
+ global fl_instance
+
+ puts -nonewline "Issuing reset... "
+
+ select_ir 5
+ device_virtual_dr_shift -instance_index $fl_instance \
+ -dr_value 1 -length 1 -no_captured_dr_value
+
+ select_ir 4
+ set rdy 0
+ while { !$rdy } {
+ set rdy [device_virtual_dr_shift -instance_index $fl_instance -length 1]
+ }
+
+ puts "done."
+}
+
+# Sector erase
+proc fl_erase addr {
+ set secsize [fl_sector_size $addr]
+ set secaddr [expr $addr & ~($secsize - 1)]
+
+ puts -nonewline [format "Erasing sector at 0x%x(0x%x)... " $secaddr $secsize]
+
+ # Blank check the sector before erasing
+ fl_send [format "50%08X%08X" $secaddr $secsize]
+ set zc [fl_recv]
+ set ze [format "85%08XFFFFFFFF" [expr $secaddr + $secsize]]
+
+ if { [string compare $zc $ze] } {
+ fl_send 81AAAAAAAAAAAAAAAA
+ fl_send 815555555555555555
+ fl_send 81AAAAAAAA80808080
+ fl_send 81AAAAAAAAAAAAAAAA
+ fl_send 815555555555555555
+ fl_send [format "81%08X30303030" $secaddr]
+
+ set read_cmd [format "D0%08X%08X" $secaddr 8]
+
+ set ndone 1
+ while { $ndone } {
+ fl_send $read_cmd
+ set ndone [string compare [fl_recv] 8DFFFFFFFFFFFFFFFF]
+ }
+ puts "done."
+ } else {
+ puts "already blank."
+ }
+}
+
+# Read file
+proc fl_read_file { file size } {
+ global fl_device_size
+
+ set f [open $file {WRONLY CREAT TRUNC BINARY}]
+ if { $size < 0 || $size > $fl_device_size } {
+ set size $fl_device_size
+ }
+
+ # XXX: obviously wrong...
+ set addr 0
+
+ # This is an arbitrary tunable, but at least for Quartus 11 is doesn't
+ # seem to get any better with a larger block size...
+ set max_block 4096
+
+ # Read data
+ set left $size
+ fl_send [format "D0%08X%08X" $addr $size]
+ while { $left > 0 } {
+ set blk [expr ($left < $max_block) ? $left : $max_block]
+ puts -nonewline $f [fl_recv_bulk $blk]
+ set left [expr $left - $blk]
+ }
+
+ close $f
+}
+
+# Erase a region
+proc fl_erase_range {addr size} {
+ set xptr $addr
+ set left $size
+ while { $left > 0 } {
+ set secleft [fl_sector_size $xptr]
+ fl_erase $xptr
+ set left [expr ($secleft >= $left) ? 0 : ($left - $secleft)]
+ incr xptr $secleft
+ }
+}
+
+# Write file
+proc fl_write_file { file size } {
+ set f [open $file {RDONLY BINARY}]
+ set fsize [file size $file]
+
+ if { $size < 0 || $fsize > $size } {
+ set size $fsize
+ }
+
+ # XXX: obviously wrong...
+ set addr 0
+
+ # First, erase...
+ fl_erase_range $addr $size
+
+ # Then, program
+ set left $size
+ fl_send [format "D0%08X%08X" $size 0]
+ while { $left > 0 } {
+ set blk [expr ($left < 8) ? $left : 8]
+ set d [read $f $blk]
+ append d [string repeat "\xff" [expr 8 - $blk]]
+ binary scan $d H2H2H2H2H2H2H2H2 d0 d1 d2 d3 d4 d5 d6 d7
+ fl_send [format "B%X%s%s%s%s%s%s%s%s" $blk $d7 $d6 $d5 $d4 $d3 $d2 $d1 $d0]
+ set left [expr $left - $blk]
+ }
+
+ # Synchronize
+ fl_send 6000000000AEAEAEAE
+ fl_recv
+
+ close $f
+}
+
+if {$argc < 1} {
+ error "Usage: quartus_stp -t de1flash.tcl command"
+}
+
+set fl_cmd [lindex $argv 0]
+set fl_file [lindex $argv 1]
+if {$argc > 2} {
+ set fl_size [lindex $argv 2]
+} else {
+ set fl_size -1
+}
+
+# List all available programming hardwares, and select the USBBlaster.
+# (Note: this example assumes only one USBBlaster connected.)
+puts "Programming Hardwares:"
+foreach hardware_name [get_hardware_names] {
+ puts $hardware_name
+ if { [string match "USB-Blaster*" $hardware_name] } {
+ set usbblaster_name $hardware_name
+ }
+}
+puts "\nUsing programming cable \"$usbblaster_name\".\n";
+
+# List all devices on the chain, and select the first device on the
+# chain.
+puts "\nDevices on the JTAG chain:"
+foreach device_name [get_device_names -hardware_name $usbblaster_name] {
+ puts $device_name
+ if { [string match "@1*" $device_name] } {
+ set test_device $device_name
+ }
+}
+puts "\nSelecting device: $test_device.\n";
+
+# Open device
+open_device -hardware_name $usbblaster_name -device_name $test_device
+
+device_lock -timeout 120000
+
+fl_reset
+
+switch $fl_cmd {
+ write { fl_write_file $fl_file $fl_size }
+ read { fl_read_file $fl_file $fl_size }
+ eraseall { fl_erase_range 0 $fl_device_size }
+ default { error "Unknown de1flash command" }
+}
+
+device_unlock
+close_device
diff --git a/de1flash.v b/de1flash.v
new file mode 100644
index 0000000..fa9f8ec
--- /dev/null
+++ b/de1flash.v
@@ -0,0 +1,828 @@
+// -----------------------------------------------------------------------
+//
+// Copyright 2003-2011 H. Peter Anvin - All Rights Reserved
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom
+// the Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall
+// be included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+// -----------------------------------------------------------------------
+
+//
+// de1flash.v
+//
+// Top-level module template for the Terasic DE1/Altera Cyclone II
+// Starter Board virtual JTAG programmer module
+//
+module de1flash (
+ input clock_50, // 50 MHz clock
+ input [1:0] clock_24, // 24 MHz clock (on two pins)
+ input [1:0] clock_27, // 27 MHz clock (on two pins)
+ input ext_clock, // External clock input
+
+ inout ps2_clk, // PS/2 keyboard clock
+ inout ps2_dat, // PS/2 keyboard data
+
+ output [9:0] ledr, // Red LEDs
+ output [7:0] ledg, // Green LEDs
+ output [6:0] s7_0, // 7-segment LEDs
+ output [6:0] s7_1, // 7-segment LEDs
+ output [6:0] s7_2, // 7-segment LEDs
+ output [6:0] s7_3, // 7-segment LEDs
+
+ input [3:0] key_n, // Pushbutton switches
+ input [9:0] sw, // Slide switches
+
+ output fl_rst_n, // Flash ROM RST#
+ output fl_ce_n, // Flash ROM CE#
+ output fl_oe_n, // Flash ROM OE#
+ output fl_we_n, // Flash ROM WE#
+ output [21:0] fl_a, // Flash ROM address bus
+ inout [7:0] fl_dq, // Flash ROM data bus
+
+ output [1:0] dram_ba, // SDRAM bank selects
+ output dram_ras_n, // SDRAM RAS#
+ output dram_cas_n, // SDRAM CAS#
+ output dram_cke, // SDRAM clock enable
+ output dram_clk, // SDRAM clock
+ output dram_cs_n, // SDRAM CS#
+ output dram_we_n, // SDRAM WE#
+ output [1:0] dram_dqm, // SDRAM DQM (per byte)
+ output [11:0] dram_a, // SDRAM address bus
+ inout [15:0] dram_dq, // SDRAM data bus
+
+ output sram_ce_n, // SRAM CE#
+ output sram_oe_n, // SRAM OE#
+ output sram_we_n, // SRAM WE#
+ output [1:0] sram_be_n, // SRAM UB#, LB#
+ output [17:0] sram_a, // SRAM address bus
+ inout [15:0] sram_dq, // SRAM data bus
+
+ output sd_clk, // SD card clock
+ inout sd_cmd, // SD card DI/MOSI/CMD
+ inout sd_dat0, // SD card SO/MISO/DAT0
+ inout sd_dat3, // SD card CS#/CD/DAT3
+
+ output uart_txd, // RS232 port TxD
+ input uart_rxd, // RS232 port RxD
+
+ output [3:0] vga_r, // VGA red
+ output [3:0] vga_g, // VGA green
+ output [3:0] vga_b, // VGA blue
+ output vga_hs, // VGA horz sync
+ output vga_vs, // VGA vert sync
+
+ output aud_xck, // Audio master clock
+ output aud_bclk, // Audio bitclock
+ output aud_dacdat, // Audio DAC data
+ output aud_daclrck, // Audio DAC framing
+ input aud_adcdat, // Audio ADC data
+ output aud_adclrck, // Audio ADC framing
+
+ inout i2c_scl, // I2C SCK line
+ inout i2c_sda, // I2C SDA line
+
+ inout [35:0] gpio_0, // GPIO headers
+ inout [35:0] gpio_1 // GPIO headers
+ );
+
+ wire fl_reset_n;
+
+ reg tdo;
+ wire [3:0] ir_in;
+ wire tck, tdi, v_sdr, v_cdr, v_uir, v_udr;
+
+ reg [71:0] jtag_wr_data;
+ reg [71:0] jtag_rd_data;
+ reg jtag_rd_valid;
+ reg [ 6:0] jtag_data_ctr;
+ wire [71:0] jtag_rd_q;
+ wire [ 7:0] jtag_wr_used;
+ reg [ 7:0] jtag_wr_free;
+ wire jtag_rd_empty;
+ reg jtag_bypass;
+ reg jtag_reset = 1'b0;
+
+ assign ledg[3:0] = ir_in;
+ assign ledg[7:4] = { v_udr, v_sdr, v_cdr, v_uir };
+
+ reg jtag_wr_wrq = 1'b0; // FIFO write strobe
+ reg jtag_rd_rrq = 1'b0; // FIFO read strobe
+
+ parameter cmd_read_fifo = 4'b0001;
+ parameter cmd_free_space = 4'b0010;
+ parameter cmd_write_fifo = 4'b0011;
+ parameter cmd_check_ready = 4'b0100;
+ parameter cmd_reset = 4'b0101;
+
+ // Shift registers and TDI input
+ always @(posedge tck)
+ begin
+ jtag_wr_wrq <= 1'b0;
+ jtag_rd_rrq <= 1'b0;
+ jtag_reset <= 1'b0;
+
+ if (v_udr)
+ begin
+ case (ir_in)
+ cmd_write_fifo:
+ jtag_wr_wrq <= 1'b1;
+ endcase // case(ir_in)
+ end // if (v_udr)
+ else if (v_cdr)
+ begin
+ case (ir_in)
+ cmd_read_fifo:
+ begin
+ jtag_rd_data <= { ~jtag_rd_empty, jtag_rd_q[70:0] };
+ jtag_rd_valid <= ~jtag_rd_empty;
+ jtag_data_ctr <= 7'd71;
+ end
+ cmd_free_space:
+ begin
+ jtag_wr_free <= ~jtag_wr_used;
+ end
+ endcase // case(ir_in)
+ end
+ else if (v_sdr)
+ begin
+ jtag_bypass <= tdi;
+
+ case (ir_in)
+ cmd_read_fifo:
+ begin
+ if ( jtag_data_ctr == 7'd1 )
+ begin
+ jtag_rd_rrq <= jtag_rd_valid;
+ jtag_rd_valid <= 1'b0;
+ end
+
+ if ( ~|jtag_data_ctr )
+ begin
+ jtag_rd_data <= { ~jtag_rd_empty, jtag_rd_q[70:0] };
+ jtag_rd_valid <= ~jtag_rd_empty;
+ jtag_data_ctr <= 7'd71;
+ end
+ else
+ begin
+ jtag_rd_data <= { tdi, jtag_rd_data[71:1] };
+ jtag_data_ctr <= jtag_data_ctr - 1'b1;
+ end
+ end // case: cmd_read_fifo
+ cmd_free_space:
+ jtag_wr_free <= { tdi, jtag_wr_free[ 7:1] };
+ cmd_write_fifo:
+ jtag_wr_data <= { tdi, jtag_wr_data[71:1] };
+ cmd_reset:
+ jtag_reset <= tdi;
+ endcase // case(ir_in)
+ end // if (v_sdr)
+ end
+
+ reg [2:0] jtag_ready = 3'b000;
+
+ always @(posedge tck)
+ jtag_ready <= { jtag_ready[1:0], fl_reset_n };
+
+ // TDO output MUX
+ always @ (*)
+ begin
+ case (ir_in)
+ cmd_read_fifo:
+ tdo <= jtag_rd_data[0];
+ cmd_free_space:
+ tdo <= jtag_wr_free[0];
+ cmd_write_fifo:
+ tdo <= jtag_wr_data[0];
+ cmd_reset:
+ tdo <= 1'b0; // Always read as zero
+ cmd_check_ready:
+ tdo <= jtag_ready[2];
+ default:
+ tdo <= jtag_bypass;
+ endcase // case(ir_in)
+ end // always @ (*)
+
+ vjtag_mega vjtag_mega_1
+ (
+ .ir_out ( ),
+ .tdo ( tdo ),
+ .ir_in ( ir_in ),
+ .tck ( tck ),
+ .tdi ( tdi ),
+ .virtual_state_cdr ( v_cdr ),
+ .virtual_state_cir ( ),
+ .virtual_state_e1dr ( v_udr ),
+ .virtual_state_e2dr ( ),
+ .virtual_state_pdr ( ),
+ .virtual_state_sdr ( v_sdr ),
+ .virtual_state_udr ( ),
+ .virtual_state_uir ( v_uir )
+ );
+
+ // ------------------------------------------------------------------
+ // Flash clock PLL and reset logic
+ // ------------------------------------------------------------------
+
+ wire pll_locked;
+ wire fl_clk;
+
+ pll pll (
+ .areset ( jtag_reset ),
+ .inclk0 ( clock_50 ),
+ .c0 ( fl_clk ), // 20 MHz
+ .locked ( pll_locked )
+ );
+
+ assign fl_reset_n = pll_locked;
+
+ // ------------------------------------------------------------------
+ // Write FIFO (JTAG -> programmer)
+ // ------------------------------------------------------------------
+
+ wire [71: 0] prog_wr_q;
+ wire prog_wr_rrq;
+ wire prog_wr_empty;
+
+ fl_fifo fl_wr_fifo
+ (
+ .aclr ( ~fl_reset_n ),
+
+ .wrclk ( tck ),
+ .data ( jtag_wr_data ),
+ .wrreq ( jtag_wr_wrq ),
+ .wrusedw ( jtag_wr_used ),
+ .wrfull ( ),
+
+ .rdclk ( fl_clk ),
+ .q ( prog_wr_q ),
+ .rdreq ( prog_wr_rrq ),
+ .rdempty ( prog_wr_empty )
+ );
+
+ // ------------------------------------------------------------------
+ // Read FIFO (programmer -> JTAG)
+ // ------------------------------------------------------------------
+
+ wire [71:0] prog_rd_data;
+ wire prog_rd_wrq;
+ wire prog_rd_full;
+
+ fl_fifo fl_rd_fifo
+ (
+ .aclr ( ~fl_reset_n ),
+
+ .wrclk ( fl_clk ),
+ .data ( prog_rd_data ),
+ .wrreq ( prog_rd_wrq ),
+ .wrusedw ( ),
+ .wrfull ( prog_rd_full ),
+
+ .rdclk ( tck ),
+ .q ( jtag_rd_q ),
+ .rdreq ( jtag_rd_rrq ),
+ .rdempty ( jtag_rd_empty )
+ );
+
+ // ------------------------------------------------------------------
+ // Flash state machine
+ // This is clocked at 20 MHz (50 ns); one clock cycle for each
+ // rising or falling edge
+ // ------------------------------------------------------------------
+
+ reg [63:0] fl_data; // Data shift register
+ reg [31:0] fl_bytectr; // Byte counter
+ reg [ 2:0] fl_rbctr; // Read bytes in shift register
+ reg [ 3:0] fl_rbcmd; // Command code
+ reg fl_incaddr; // Increment between bytes
+ reg [31:0] fl_addr;
+
+ reg fl_ce_q;
+ reg fl_oe_q;
+ reg fl_we_q;
+ reg [31:0] fl_a_q;
+ reg [ 7:0] fl_d_q;
+ reg fl_d_en;
+
+ assign fl_rst_n = fl_reset_n;
+ assign fl_ce_n = ~fl_ce_q;
+ assign fl_oe_n = ~fl_oe_q;
+ assign fl_we_n = ~fl_we_q;
+ assign fl_a = fl_a_q[21:0];
+ assign fl_dq = fl_d_en ? fl_d_q : 8'hzz;
+
+ reg [4:0] prog_state;
+ parameter pst_idle = 5'h00;
+ parameter pst_delay = 5'h01;
+ parameter pst_status = 5'h02;
+ parameter pst_read0 = 5'h04;
+ parameter pst_read1 = 5'h05;
+ parameter pst_read2 = 5'h06;
+ parameter pst_readpad = 5'h07;
+ parameter pst_write0 = 5'h08;
+ parameter pst_write1 = 5'h09;
+ parameter pst_zchk0 = 5'h0C;
+ parameter pst_zchk1 = 5'h0D;
+ parameter pst_zchk2 = 5'h0E;
+ parameter pst_program0 = 5'h10;
+ parameter pst_program1 = 5'h11;
+ parameter pst_program2 = 5'h12;
+ parameter pst_program3 = 5'h13;
+ parameter pst_program4 = 5'h14;
+ parameter pst_program5 = 5'h15;
+ parameter pst_program6 = 5'h16;
+ parameter pst_program7 = 5'h17;
+ parameter pst_program8 = 5'h18;
+ parameter pst_program9 = 5'h19;
+ parameter pst_program10 = 5'h1A;
+ parameter pst_program11 = 5'h1B;
+ parameter pst_program12 = 5'h1C;
+ parameter pst_program13 = 5'h1D;
+ parameter pst_program14 = 5'h1E;
+
+ reg rd_ack;
+
+ reg [7:0] pgm_data;
+ reg [7:0] tst_data;
+
+ // Debugging... registering these is "free" since there are
+ // registers in the I/O buffers, and deconstrains the design
+ reg [9:0] ledr_q;
+ assign ledr = ledr_q;
+
+ always @(posedge fl_clk or negedge fl_reset_n)
+ if (~fl_reset_n)
+ begin
+ ledr_q <= ~10'b0;
+ end
+ else
+ begin
+ ledr_q[0] <= prog_rd_full;
+ ledr_q[1] <= fl_ce_q;
+ ledr_q[2] <= fl_oe_q;
+ ledr_q[3] <= fl_we_q;
+ ledr_q[4] <= fl_d_en;
+ ledr_q[9:5] <= prog_state;
+ end
+
+ reg [6:0] s7_0_q;
+ reg [6:0] s7_1_q;
+ reg [6:0] s7_2_q;
+ reg [6:0] s7_3_q;
+
+ wire [6:0] s7_0_w;
+ wire [6:0] s7_1_w;
+ wire [6:0] s7_2_w;
+ wire [6:0] s7_3_w;
+
+ assign s7_0 = s7_0_q;
+ assign s7_1 = s7_1_q;
+ assign s7_2 = s7_2_q;
+ assign s7_3 = s7_3_q;
+
+ hexled hexled0 ( .value (fl_addr[11: 8]), .s7 (s7_0_w) );
+ hexled hexled1 ( .value (fl_addr[15:12]), .s7 (s7_1_w) );
+ hexled hexled2 ( .value (fl_addr[19:16]), .s7 (s7_2_w) );
+ hexled hexled3 ( .value (fl_addr[23:20]), .s7 (s7_3_w) );
+
+ always @(posedge fl_clk or negedge fl_reset_n)
+ if (~fl_reset_n)
+ begin
+ s7_0_q <= ~7'b1000000;
+ s7_1_q <= ~7'b1000000;
+ s7_2_q <= ~7'b1000000;
+ s7_3_q <= ~7'b1000000;
+ end
+ else
+ begin
+ s7_0_q <= s7_0_w;
+ s7_1_q <= s7_1_w;
+ s7_2_q <= s7_2_w;
+ s7_3_q <= s7_3_w;
+ end
+
+ assign prog_wr_rrq = ~prog_wr_empty & (prog_state == pst_idle);
+ assign prog_rd_wrq = rd_ack;
+ assign prog_rd_data = { 4'b0, fl_rbcmd, fl_data };
+
+ wire bump_addr =
+ (prog_state == pst_read2) |
+ (prog_state == pst_write1) |
+ ((prog_state == pst_program3) & ~|(tst_data & ~fl_data[7:0])) |
+ ((prog_state == pst_program14) & (tst_data == pgm_data));
+
+ always @(negedge fl_reset_n or posedge fl_clk)
+ if (~fl_reset_n)
+ begin
+ fl_ce_q <= 1'b0;
+ fl_oe_q <= 1'b0;
+ fl_we_q <= 1'b0;
+ fl_addr <= 32'h0;
+ fl_a_q <= 32'h0;
+ fl_d_q <= 8'h0;
+ fl_d_en <= 1'b0;
+
+ fl_data <= 64'bx;
+ fl_bytectr <= 32'h0;
+ fl_rbctr <= 3'h0;
+ fl_rbcmd <= 4'bx;
+ fl_incaddr <= 1'b0;
+
+ prog_state <= pst_idle;
+ rd_ack <= 1'b0;
+
+ pgm_data <= 8'hxx;
+ tst_data <= 8'hff;
+ end
+ else
+ begin
+ fl_ce_q <= 1'b0;
+ fl_oe_q <= 1'b0;
+ fl_we_q <= 1'b0;
+ fl_d_en <= 1'b0;
+
+ rd_ack <= 1'b0;
+
+ if ( bump_addr )
+ fl_addr <= fl_addr + fl_incaddr;
+
+ case ( prog_state )
+ pst_idle:
+ begin
+ fl_rbctr <= 3'h0;
+ fl_rbcmd <= prog_wr_q[71:68];
+ tst_data <= 8'hff;
+
+ if ( ~prog_wr_empty )
+ case ( prog_wr_q[71:69] )
+ 3'b001: // Delay command
+ begin
+ fl_bytectr <= prog_wr_q[31:0];
+ prog_state <= pst_delay;
+ end
+ 3'b010: // Zero check
+ begin
+ fl_incaddr <= prog_wr_q[68];
+ fl_addr <= prog_wr_q[63:32];
+ fl_bytectr <= prog_wr_q[31:0];
+ prog_state <= pst_zchk0;
+ end
+ 3'b011: // Read back address, token
+ begin
+ fl_data <= { fl_addr, prog_wr_q[31:0] };
+ prog_state <= pst_status;
+ end
+ 3'b100: // Write bytes command
+ begin
+ fl_incaddr <= prog_wr_q[68];
+ fl_data <= prog_wr_q[63:0];
+ if ( prog_wr_q[68] )
+ fl_addr <= prog_wr_q[63:32];
+ prog_state <= pst_write0;
+ end
+ 3'b101: // Program bytes command
+ begin
+ fl_incaddr <= prog_wr_q[68];
+ fl_bytectr <= { 28'b0, prog_wr_q[67:64] };
+ fl_data <= prog_wr_q[63:0];
+ prog_state <= pst_program0;
+ end
+ 3'b110: // Set address register/read command
+ begin
+ fl_incaddr <= prog_wr_q[68];
+ fl_addr <= prog_wr_q[63:32];
+ fl_bytectr <= prog_wr_q[31:0];
+ prog_state <= pst_read0;
+ end
+ endcase // case( prog_wr_q[71:69] )
+ end // case: pst_idle
+
+ pst_delay:
+ begin
+ if ( |fl_bytectr )
+ fl_bytectr <= fl_bytectr - 1'b1;
+ else
+ prog_state <= pst_idle;
+ end
+
+ pst_status:
+ begin
+ if ( ~prog_rd_full )
+ begin
+ rd_ack <= 1'b1;
+ prog_state <= pst_idle;
+ end
+ end
+
+ pst_read0: // Read initial state
+ begin
+ fl_a_q <= fl_addr;
+ if ( |fl_bytectr )
+ begin
+ if ( ~prog_rd_full )
+ begin
+ fl_ce_q <= 1'b1;
+ fl_oe_q <= 1'b1;
+ prog_state <= pst_read1;
+ end
+ end
+ else if ( |fl_rbctr )
+ begin
+ if ( ~prog_rd_full )
+ prog_state <= pst_readpad;
+ end
+ else
+ prog_state <= pst_idle;
+ end // case: pst_read0
+
+ pst_read1: // Read output waveform #1
+ begin
+ fl_ce_q <= 1'b1;
+ fl_oe_q <= 1'b1;
+ prog_state <= pst_read2;
+ end
+
+ pst_read2:
+ begin
+ fl_data <= { fl_dq, fl_data[63:8] };
+ rd_ack <= &fl_rbctr;
+ fl_bytectr <= fl_bytectr - 1'b1;
+ fl_rbctr <= fl_rbctr + 1'b1;
+ prog_state <= pst_read0;
+ end
+
+ pst_readpad:
+ begin
+ fl_data <= { 8'hFF, fl_data[63:8] };
+ rd_ack <= &fl_rbctr;
+ fl_rbctr <= fl_rbctr + 1'b1;
+ prog_state <= pst_read0;
+ end
+
+ pst_zchk0: // Zero check
+ begin
+ fl_a_q <= fl_addr;
+ if ( &tst_data & |fl_bytectr )
+ begin
+ fl_ce_q <= 1'b1;
+ fl_oe_q <= 1'b1;
+ prog_state <= pst_zchk1;
+ end
+ else if ( ~prog_rd_full )
+ begin
+ fl_data[63:32] <= fl_addr;
+ fl_data[31: 8] <= 24'hffffff;
+ fl_data[ 7: 0] <= tst_data;
+ rd_ack <= 1'b1;
+ prog_state <= pst_idle;
+ end // else: !if( |fl_bytectr )
+ end // case: pst_zchk0
+
+ pst_zchk1:
+ begin
+ fl_ce_q <= 1'b1;
+ fl_oe_q <= 1'b1;
+ prog_state <= pst_zchk2;
+ end
+
+ pst_zchk2:
+ begin
+ tst_data <= fl_dq;
+ fl_bytectr <= fl_bytectr - 1'b1;
+ prog_state <= pst_zchk0;
+ end
+
+ pst_write0:
+ begin
+ fl_ce_q <= 1'b1;
+ fl_we_q <= 1'b1;
+ fl_d_en <= 1'b1;
+ fl_d_q <= fl_data[7:0];
+ fl_a_q <= fl_data[63:32];
+ prog_state <= pst_write1;
+ end
+
+ pst_write1:
+ begin
+ fl_ce_q <= 1'b1;
+ fl_d_en <= 1'b1;
+ prog_state <= pst_idle;
+ end
+
+ // Programming algorithm: read individual bytes to avoid
+ // hanging the flash chip due to zero bits
+ pst_program0:
+ begin
+ fl_ce_q <= 1'b1;
+ fl_oe_q <= 1'b1;
+ fl_a_q <= fl_addr;
+ prog_state <= pst_program1;
+ end
+
+ pst_program1:
+ begin
+ fl_ce_q <= 1'b1;
+ fl_oe_q <= 1'b1;
+ prog_state <= pst_program2;
+ end
+
+ pst_program2:
+ begin
+ fl_ce_q <= 1'b1;
+ tst_data <= fl_dq;
+ prog_state <= pst_program3;
+ fl_bytectr <= fl_bytectr - 1'b1;
+ end
+
+ pst_program3:
+ begin
+ pgm_data <= tst_data & fl_data[7:0];
+ fl_data <= { 8'hFF, fl_data[63:8] };
+
+ if ( |(tst_data & ~fl_data[7:0]) )
+ begin
+ fl_ce_q <= 1'b1;
+ fl_we_q <= 1'b1;
+ fl_d_en <= 1'b1;
+ fl_d_q <= 8'hAA;
+ fl_a_q <= 32'hAAAAAAAA;
+ prog_state <= pst_program4;
+ end
+ else
+ begin
+ if ( |fl_bytectr )
+ prog_state <= pst_program0;
+ else
+ prog_state <= pst_idle;
+ end
+ end // case: pst_program3
+
+ pst_program4:
+ begin
+ fl_ce_q <= 1'b1;
+ fl_d_en <= 1'b1;
+ prog_state <= pst_program5;
+ end
+
+ pst_program5:
+ begin
+ fl_ce_q <= 1'b1;
+ fl_we_q <= 1'b1;
+ fl_d_en <= 1'b1;
+ fl_d_q <= 8'h55;
+ fl_a_q <= 32'h55555555;
+ prog_state <= pst_program6;
+ end
+
+ pst_program6:
+ begin
+ fl_ce_q <= 1'b1;
+ fl_d_en <= 1'b1;
+ prog_state <= pst_program7;
+ end
+
+ pst_program7:
+ begin
+ fl_ce_q <= 1'b1;
+ fl_we_q <= 1'b1;
+ fl_d_en <= 1'b1;
+ fl_d_q <= 8'hA0;
+ fl_a_q <= 32'hAAAAAAAA;
+ prog_state <= pst_program8;
+ end
+
+ pst_program8:
+ begin
+ fl_ce_q <= 1'b1;
+ fl_d_en <= 1'b1;
+ prog_state <= pst_program9;
+ end
+
+ pst_program9:
+ begin
+ fl_ce_q <= 1'b1;
+ fl_we_q <= 1'b1;
+ fl_d_en <= 1'b1;
+ fl_d_q <= pgm_data;
+ fl_a_q <= fl_addr;
+ prog_state <= pst_program10;
+ end
+
+ pst_program10:
+ begin
+ fl_ce_q <= 1'b1;
+ fl_d_en <= 1'b1;
+ prog_state <= pst_program11;
+ end
+
+ pst_program11:
+ begin
+ fl_ce_q <= 1'b1;
+ fl_oe_q <= 1'b1;
+ prog_state <= pst_program12;
+ end
+
+ pst_program12:
+ begin
+ fl_ce_q <= 1'b1;
+ fl_oe_q <= 1'b1;
+ prog_state <= pst_program13;
+ end
+
+ pst_program13:
+ begin
+ fl_ce_q <= 1'b1;
+ tst_data <= fl_dq;
+ prog_state <= pst_program14;
+ end
+
+ pst_program14:
+ begin
+ fl_ce_q <= 1'b1;
+ if ( tst_data != pgm_data )
+ prog_state <= pst_program11;
+ else if ( |fl_bytectr )
+ prog_state <= pst_program0;
+ else
+ prog_state <= pst_idle;
+ end
+ endcase // case( prog_state )
+ end
+
+ // ------------------------------------------------------------------
+ // Unused hardware ports
+ // ------------------------------------------------------------------
+
+ // PS/2 port
+ assign ps2_clk = 1'bz;
+ assign ps2_dat = 1'bz;
+
+ // SDRAM
+ assign dram_ba = 2'b11;
+ assign dram_ras_n = 1'b1;
+ assign dram_cas_n = 1'b1;
+ assign dram_cke = 1'b1;
+ assign dram_clk = 1'b1;
+ assign dram_cs_n = 1'b1;
+ assign dram_we_n = 1'b1;
+ assign dram_dqm = 2'b11;
+ assign dram_a = ~12'b0;
+ assign dram_dq = 16'hzzzz;
+
+ // SRAM
+ assign sram_ce_n = 1'b1;
+ assign sram_oe_n = 1'b1;
+ assign sram_we_n = 1'b1;
+ assign sram_be_n = 2'b11;
+ assign sram_a = ~18'b0;
+ assign sram_dq = 16'hzzzz;
+
+ // SD card
+ assign sd_clk = 1'b1;
+ assign sd_cmd = 1'bz;
+ assign sd_dat0 = 1'bz;
+ assign sd_dat3 = 1'bz;
+
+ // RS232
+ assign uart_txd = 1'b1;
+
+ // Video
+ assign vga_r = 4'b0;
+ assign vga_g = 4'b0;
+ assign vga_b = 4'b0;
+ assign vga_hs = 1'b0;
+ assign vga_vs = 1'b0;
+
+ // Audio I2S
+ assign aud_xck = 1'b1;
+ assign aud_bclk = 1'b1;
+ assign aud_dacdat = 1'b1;
+ assign aud_daclrck = 1'b1;
+ assign aud_adclrck = 1'b1;
+
+ // Audio I2C
+ assign i2c_scl = 1'bz;
+ assign i2c_sda = 1'bz;
+
+ // GPIO
+ assign gpio_0 = 36'hz_zzzz_zzzz;
+ assign gpio_1 = 36'hz_zzzz_zzzz;
+
+endmodule // de1flash
diff --git a/fl_fifo.qip b/fl_fifo.qip
new file mode 100644
index 0000000..7981a70
--- /dev/null
+++ b/fl_fifo.qip
@@ -0,0 +1,4 @@
+set_global_assignment -name IP_TOOL_NAME "FIFO"
+set_global_assignment -name IP_TOOL_VERSION "11.0"
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "fl_fifo.v"]
+set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "fl_fifo_bb.v"]
diff --git a/fl_fifo.v b/fl_fifo.v
new file mode 100644
index 0000000..c16e687
--- /dev/null
+++ b/fl_fifo.v
@@ -0,0 +1,185 @@
+// megafunction wizard: %FIFO%
+// GENERATION: STANDARD
+// VERSION: WM1.0
+// MODULE: dcfifo
+
+// ============================================================
+// File Name: fl_fifo.v
+// Megafunction Name(s):
+// dcfifo
+//
+// Simulation Library Files(s):
+// altera_mf
+// ============================================================
+// ************************************************************
+// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
+//
+// 11.0 Build 157 04/27/2011 SJ Web Edition
+// ************************************************************
+
+
+//Copyright (C) 1991-2011 Altera Corporation
+//Your use of Altera Corporation's design tools, logic functions
+//and other software and tools, and its AMPP partner logic
+//functions, and any output files from any of the foregoing
+//(including device programming or simulation files), and any
+//associated documentation or information are expressly subject
+//to the terms and conditions of the Altera Program License
+//Subscription Agreement, Altera MegaCore Function License
+//Agreement, or other applicable license agreement, including,
+//without limitation, that your use is for the sole purpose of
+//programming logic devices manufactured by Altera and sold by
+//Altera or its authorized distributors. Please refer to the
+//applicable agreement for further details.
+
+
+// synopsys translate_off
+`timescale 1 ps / 1 ps
+// synopsys translate_on
+module fl_fifo (
+ aclr,
+ data,
+ rdclk,
+ rdreq,
+ wrclk,
+ wrreq,
+ q,
+ rdempty,
+ wrfull,
+ wrusedw);
+
+ input aclr;
+ input [71:0] data;
+ input rdclk;
+ input rdreq;
+ input wrclk;
+ input wrreq;
+ output [71:0] q;
+ output rdempty;
+ output wrfull;
+ output [7:0] wrusedw;
+`ifndef ALTERA_RESERVED_QIS
+// synopsys translate_off
+`endif
+ tri0 aclr;
+`ifndef ALTERA_RESERVED_QIS
+// synopsys translate_on
+`endif
+
+ wire sub_wire0;
+ wire [71:0] sub_wire1;
+ wire sub_wire2;
+ wire [7:0] sub_wire3;
+ wire wrfull = sub_wire0;
+ wire [71:0] q = sub_wire1[71:0];
+ wire rdempty = sub_wire2;
+ wire [7:0] wrusedw = sub_wire3[7:0];
+
+ dcfifo dcfifo_component (
+ .rdclk (rdclk),
+ .wrclk (wrclk),
+ .wrreq (wrreq),
+ .aclr (aclr),
+ .data (data),
+ .rdreq (rdreq),
+ .wrfull (sub_wire0),
+ .q (sub_wire1),
+ .rdempty (sub_wire2),
+ .wrusedw (sub_wire3),
+ .rdfull (),
+ .rdusedw (),
+ .wrempty ());
+ defparam
+ dcfifo_component.intended_device_family = "Cyclone II",
+ dcfifo_component.lpm_hint = "MAXIMIZE_SPEED=5,",
+ dcfifo_component.lpm_numwords = 256,
+ dcfifo_component.lpm_showahead = "ON",
+ dcfifo_component.lpm_type = "dcfifo",
+ dcfifo_component.lpm_width = 72,
+ dcfifo_component.lpm_widthu = 8,
+ dcfifo_component.overflow_checking = "ON",
+ dcfifo_component.rdsync_delaypipe = 5,
+ dcfifo_component.underflow_checking = "ON",
+ dcfifo_component.use_eab = "ON",
+ dcfifo_component.write_aclr_synch = "ON",
+ dcfifo_component.wrsync_delaypipe = 5;
+
+
+endmodule
+
+// ============================================================
+// CNX file retrieval info
+// ============================================================
+// Retrieval info: PRIVATE: AlmostEmpty NUMERIC "0"
+// Retrieval info: PRIVATE: AlmostEmptyThr NUMERIC "-1"
+// Retrieval info: PRIVATE: AlmostFull NUMERIC "0"
+// Retrieval info: PRIVATE: AlmostFullThr NUMERIC "-1"
+// Retrieval info: PRIVATE: CLOCKS_ARE_SYNCHRONIZED NUMERIC "0"
+// Retrieval info: PRIVATE: Clock NUMERIC "4"
+// Retrieval info: PRIVATE: Depth NUMERIC "256"
+// Retrieval info: PRIVATE: Empty NUMERIC "1"
+// Retrieval info: PRIVATE: Full NUMERIC "1"
+// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone II"
+// Retrieval info: PRIVATE: LE_BasedFIFO NUMERIC "0"
+// Retrieval info: PRIVATE: LegacyRREQ NUMERIC "0"
+// Retrieval info: PRIVATE: MAX_DEPTH_BY_9 NUMERIC "0"
+// Retrieval info: PRIVATE: OVERFLOW_CHECKING NUMERIC "0"
+// Retrieval info: PRIVATE: Optimize NUMERIC "2"
+// Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
+// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
+// Retrieval info: PRIVATE: UNDERFLOW_CHECKING NUMERIC "0"
+// Retrieval info: PRIVATE: UsedW NUMERIC "1"
+// Retrieval info: PRIVATE: Width NUMERIC "72"
+// Retrieval info: PRIVATE: dc_aclr NUMERIC "1"
+// Retrieval info: PRIVATE: diff_widths NUMERIC "0"
+// Retrieval info: PRIVATE: msb_usedw NUMERIC "0"
+// Retrieval info: PRIVATE: output_width NUMERIC "72"
+// Retrieval info: PRIVATE: rsEmpty NUMERIC "1"
+// Retrieval info: PRIVATE: rsFull NUMERIC "0"
+// Retrieval info: PRIVATE: rsUsedW NUMERIC "0"
+// Retrieval info: PRIVATE: sc_aclr NUMERIC "0"
+// Retrieval info: PRIVATE: sc_sclr NUMERIC "0"
+// Retrieval info: PRIVATE: wsEmpty NUMERIC "0"
+// Retrieval info: PRIVATE: wsFull NUMERIC "1"
+// Retrieval info: PRIVATE: wsUsedW NUMERIC "1"
+// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
+// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone II"
+// Retrieval info: CONSTANT: LPM_HINT STRING "MAXIMIZE_SPEED=5,"
+// Retrieval info: CONSTANT: LPM_NUMWORDS NUMERIC "256"
+// Retrieval info: CONSTANT: LPM_SHOWAHEAD STRING "ON"
+// Retrieval info: CONSTANT: LPM_TYPE STRING "dcfifo"
+// Retrieval info: CONSTANT: LPM_WIDTH NUMERIC "72"
+// Retrieval info: CONSTANT: LPM_WIDTHU NUMERIC "8"
+// Retrieval info: CONSTANT: OVERFLOW_CHECKING STRING "ON"
+// Retrieval info: CONSTANT: RDSYNC_DELAYPIPE NUMERIC "5"
+// Retrieval info: CONSTANT: UNDERFLOW_CHECKING STRING "ON"
+// Retrieval info: CONSTANT: USE_EAB STRING "ON"
+// Retrieval info: CONSTANT: WRITE_ACLR_SYNCH STRING "ON"
+// Retrieval info: CONSTANT: WRSYNC_DELAYPIPE NUMERIC "5"
+// Retrieval info: USED_PORT: aclr 0 0 0 0 INPUT GND "aclr"
+// Retrieval info: USED_PORT: data 0 0 72 0 INPUT NODEFVAL "data[71..0]"
+// Retrieval info: USED_PORT: q 0 0 72 0 OUTPUT NODEFVAL "q[71..0]"
+// Retrieval info: USED_PORT: rdclk 0 0 0 0 INPUT NODEFVAL "rdclk"
+// Retrieval info: USED_PORT: rdempty 0 0 0 0 OUTPUT NODEFVAL "rdempty"
+// Retrieval info: USED_PORT: rdreq 0 0 0 0 INPUT NODEFVAL "rdreq"
+// Retrieval info: USED_PORT: wrclk 0 0 0 0 INPUT NODEFVAL "wrclk"
+// Retrieval info: USED_PORT: wrfull 0 0 0 0 OUTPUT NODEFVAL "wrfull"
+// Retrieval info: USED_PORT: wrreq 0 0 0 0 INPUT NODEFVAL "wrreq"
+// Retrieval info: USED_PORT: wrusedw 0 0 8 0 OUTPUT NODEFVAL "wrusedw[7..0]"
+// Retrieval info: CONNECT: @aclr 0 0 0 0 aclr 0 0 0 0
+// Retrieval info: CONNECT: @data 0 0 72 0 data 0 0 72 0
+// Retrieval info: CONNECT: @rdclk 0 0 0 0 rdclk 0 0 0 0
+// Retrieval info: CONNECT: @rdreq 0 0 0 0 rdreq 0 0 0 0
+// Retrieval info: CONNECT: @wrclk 0 0 0 0 wrclk 0 0 0 0
+// Retrieval info: CONNECT: @wrreq 0 0 0 0 wrreq 0 0 0 0
+// Retrieval info: CONNECT: q 0 0 72 0 @q 0 0 72 0
+// Retrieval info: CONNECT: rdempty 0 0 0 0 @rdempty 0 0 0 0
+// Retrieval info: CONNECT: wrfull 0 0 0 0 @wrfull 0 0 0 0
+// Retrieval info: CONNECT: wrusedw 0 0 8 0 @wrusedw 0 0 8 0
+// Retrieval info: GEN_FILE: TYPE_NORMAL fl_fifo.v TRUE
+// Retrieval info: GEN_FILE: TYPE_NORMAL fl_fifo.inc FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL fl_fifo.cmp FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL fl_fifo.bsf FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL fl_fifo_inst.v FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL fl_fifo_bb.v TRUE
+// Retrieval info: LIB_FILE: altera_mf
diff --git a/hexled.v b/hexled.v
new file mode 100644
index 0000000..1c25a59
--- /dev/null
+++ b/hexled.v
@@ -0,0 +1,72 @@
+module hexled (
+ value,
+ s7
+ );
+
+ input [3:0] value;
+ output [6:0] s7;
+ reg [6:0] s7;
+
+ always @( value )
+ begin
+ case ( value )
+ 4'h0: s7 = ~7'b0111111;
+ 4'h1: s7 = ~7'b0000110;
+ 4'h2: s7 = ~7'b1011011;
+ 4'h3: s7 = ~7'b1001111;
+ 4'h4: s7 = ~7'b1100110;
+ 4'h5: s7 = ~7'b1101101;
+ 4'h6: s7 = ~7'b1111101;
+ 4'h7: s7 = ~7'b0000111;
+ 4'h8: s7 = ~7'b1111111;
+ 4'h9: s7 = ~7'b1101111;
+ 4'hA: s7 = ~7'b1110111;
+ 4'hB: s7 = ~7'b1111100;
+ 4'hC: s7 = ~7'b0111001;
+ 4'hD: s7 = ~7'b1011110;
+ 4'hE: s7 = ~7'b1111001;
+ 4'hF: s7 = ~7'b1110001;
+ endcase
+ end
+endmodule // hexled
+
+module hexledx (
+ value,
+ blank,
+ minus,
+ s7
+ );
+
+ input [3:0] value;
+ input blank;
+ input minus;
+ output [6:0] s7;
+ reg [6:0] s7;
+
+ always @( value or blank or minus )
+ begin
+ if ( blank )
+ s7 = ~7'b0000000;
+ else if ( minus )
+ s7 = ~7'b1000000;
+ else case ( value )
+ 4'h0: s7 = ~7'b0111111;
+ 4'h1: s7 = ~7'b0000110;
+ 4'h2: s7 = ~7'b1011011;
+ 4'h3: s7 = ~7'b1001111;
+ 4'h4: s7 = ~7'b1100110;
+ 4'h5: s7 = ~7'b1101101;
+ 4'h6: s7 = ~7'b1111101;
+ 4'h7: s7 = ~7'b0000111;
+ 4'h8: s7 = ~7'b1111111;
+ 4'h9: s7 = ~7'b1101111;
+ 4'hA: s7 = ~7'b1110111;
+ 4'hB: s7 = ~7'b1111100;
+ 4'hC: s7 = ~7'b0111001;
+ 4'hD: s7 = ~7'b1011110;
+ 4'hE: s7 = ~7'b1111001;
+ 4'hF: s7 = ~7'b1110001;
+ endcase
+ end
+endmodule // hexledx
+
diff --git a/pll.qip b/pll.qip
new file mode 100644
index 0000000..39950ff
--- /dev/null
+++ b/pll.qip
@@ -0,0 +1,5 @@
+set_global_assignment -name IP_TOOL_NAME "ALTPLL"
+set_global_assignment -name IP_TOOL_VERSION "11.0"
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "pll.v"]
+set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll_bb.v"]
+set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll.ppf"]
diff --git a/pll.v b/pll.v
new file mode 100644
index 0000000..93ce8a4
--- /dev/null
+++ b/pll.v
@@ -0,0 +1,323 @@
+// megafunction wizard: %ALTPLL%
+// GENERATION: STANDARD
+// VERSION: WM1.0
+// MODULE: altpll
+
+// ============================================================
+// File Name: pll.v
+// Megafunction Name(s):
+// altpll
+//
+// Simulation Library Files(s):
+// altera_mf
+// ============================================================
+// ************************************************************
+// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
+//
+// 11.0 Build 157 04/27/2011 SJ Web Edition
+// ************************************************************
+
+
+//Copyright (C) 1991-2011 Altera Corporation
+//Your use of Altera Corporation's design tools, logic functions
+//and other software and tools, and its AMPP partner logic
+//functions, and any output files from any of the foregoing
+//(including device programming or simulation files), and any
+//associated documentation or information are expressly subject
+//to the terms and conditions of the Altera Program License
+//Subscription Agreement, Altera MegaCore Function License
+//Agreement, or other applicable license agreement, including,
+//without limitation, that your use is for the sole purpose of
+//programming logic devices manufactured by Altera and sold by
+//Altera or its authorized distributors. Please refer to the
+//applicable agreement for further details.
+
+
+// synopsys translate_off
+`timescale 1 ps / 1 ps
+// synopsys translate_on
+module pll (
+ areset,
+ inclk0,
+ c0,
+ locked);
+
+ input areset;
+ input inclk0;
+ output c0;
+ output locked;
+`ifndef ALTERA_RESERVED_QIS
+// synopsys translate_off
+`endif
+ tri0 areset;
+`ifndef ALTERA_RESERVED_QIS
+// synopsys translate_on
+`endif
+
+ wire sub_wire0;
+ wire [5:0] sub_wire1;
+ wire [0:0] sub_wire5 = 1'h0;
+ wire locked = sub_wire0;
+ wire [0:0] sub_wire2 = sub_wire1[0:0];
+ wire c0 = sub_wire2;
+ wire sub_wire3 = inclk0;
+ wire [1:0] sub_wire4 = {sub_wire5, sub_wire3};
+
+ altpll altpll_component (
+ .areset (areset),
+ .inclk (sub_wire4),
+ .locked (sub_wire0),
+ .clk (sub_wire1),
+ .activeclock (),
+ .clkbad (),
+ .clkena ({6{1'b1}}),
+ .clkloss (),
+ .clkswitch (1'b0),
+ .configupdate (1'b0),
+ .enable0 (),
+ .enable1 (),
+ .extclk (),
+ .extclkena ({4{1'b1}}),
+ .fbin (1'b1),
+ .fbmimicbidir (),
+ .fbout (),
+ .fref (),
+ .icdrclk (),
+ .pfdena (1'b1),
+ .phasecounterselect ({4{1'b1}}),
+ .phasedone (),
+ .phasestep (1'b1),
+ .phaseupdown (1'b1),
+ .pllena (1'b1),
+ .scanaclr (1'b0),
+ .scanclk (1'b0),
+ .scanclkena (1'b1),
+ .scandata (1'b0),
+ .scandataout (),
+ .scandone (),
+ .scanread (1'b0),
+ .scanwrite (1'b0),
+ .sclkout0 (),
+ .sclkout1 (),
+ .vcooverrange (),
+ .vcounderrange ());
+ defparam
+ altpll_component.clk0_divide_by = 5,
+ altpll_component.clk0_duty_cycle = 50,
+ altpll_component.clk0_multiply_by = 2,
+ altpll_component.clk0_phase_shift = "0",
+ altpll_component.compensate_clock = "CLK0",
+ altpll_component.gate_lock_counter = 1048575,
+ altpll_component.gate_lock_signal = "YES",
+ altpll_component.inclk0_input_frequency = 20000,
+ altpll_component.intended_device_family = "Cyclone II",
+ altpll_component.invalid_lock_multiplier = 5,
+ altpll_component.lpm_hint = "CBX_MODULE_PREFIX=pll",
+ altpll_component.lpm_type = "altpll",
+ altpll_component.operation_mode = "NORMAL",
+ altpll_component.port_activeclock = "PORT_UNUSED",
+ altpll_component.port_areset = "PORT_USED",
+ altpll_component.port_clkbad0 = "PORT_UNUSED",
+ altpll_component.port_clkbad1 = "PORT_UNUSED",
+ altpll_component.port_clkloss = "PORT_UNUSED",
+ altpll_component.port_clkswitch = "PORT_UNUSED",
+ altpll_component.port_configupdate = "PORT_UNUSED",
+ altpll_component.port_fbin = "PORT_UNUSED",
+ altpll_component.port_inclk0 = "PORT_USED",
+ altpll_component.port_inclk1 = "PORT_UNUSED",
+ altpll_component.port_locked = "PORT_USED",
+ altpll_component.port_pfdena = "PORT_UNUSED",
+ altpll_component.port_phasecounterselect = "PORT_UNUSED",
+ altpll_component.port_phasedone = "PORT_UNUSED",
+ altpll_component.port_phasestep = "PORT_UNUSED",
+ altpll_component.port_phaseupdown = "PORT_UNUSED",
+ altpll_component.port_pllena = "PORT_UNUSED",
+ altpll_component.port_scanaclr = "PORT_UNUSED",
+ altpll_component.port_scanclk = "PORT_UNUSED",
+ altpll_component.port_scanclkena = "PORT_UNUSED",
+ altpll_component.port_scandata = "PORT_UNUSED",
+ altpll_component.port_scandataout = "PORT_UNUSED",
+ altpll_component.port_scandone = "PORT_UNUSED",
+ altpll_component.port_scanread = "PORT_UNUSED",
+ altpll_component.port_scanwrite = "PORT_UNUSED",
+ altpll_component.port_clk0 = "PORT_USED",
+ altpll_component.port_clk1 = "PORT_UNUSED",
+ altpll_component.port_clk2 = "PORT_UNUSED",
+ altpll_component.port_clk3 = "PORT_UNUSED",
+ altpll_component.port_clk4 = "PORT_UNUSED",
+ altpll_component.port_clk5 = "PORT_UNUSED",
+ altpll_component.port_clkena0 = "PORT_UNUSED",
+ altpll_component.port_clkena1 = "PORT_UNUSED",
+ altpll_component.port_clkena2 = "PORT_UNUSED",
+ altpll_component.port_clkena3 = "PORT_UNUSED",
+ altpll_component.port_clkena4 = "PORT_UNUSED",
+ altpll_component.port_clkena5 = "PORT_UNUSED",
+ altpll_component.port_extclk0 = "PORT_UNUSED",
+ altpll_component.port_extclk1 = "PORT_UNUSED",
+ altpll_component.port_extclk2 = "PORT_UNUSED",
+ altpll_component.port_extclk3 = "PORT_UNUSED",
+ altpll_component.valid_lock_multiplier = 1;
+
+
+endmodule
+
+// ============================================================
+// CNX file retrieval info
+// ============================================================
+// Retrieval info: PRIVATE: ACTIVECLK_CHECK STRING "0"
+// Retrieval info: PRIVATE: BANDWIDTH STRING "1.000"
+// Retrieval info: PRIVATE: BANDWIDTH_FEATURE_ENABLED STRING "0"
+// Retrieval info: PRIVATE: BANDWIDTH_FREQ_UNIT STRING "MHz"
+// Retrieval info: PRIVATE: BANDWIDTH_PRESET STRING "Low"
+// Retrieval info: PRIVATE: BANDWIDTH_USE_AUTO STRING "1"
+// Retrieval info: PRIVATE: BANDWIDTH_USE_CUSTOM STRING "0"
+// Retrieval info: PRIVATE: BANDWIDTH_USE_PRESET STRING "0"
+// Retrieval info: PRIVATE: CLKBAD_SWITCHOVER_CHECK STRING "0"
+// Retrieval info: PRIVATE: CLKLOSS_CHECK STRING "0"
+// Retrieval info: PRIVATE: CLKSWITCH_CHECK STRING "1"
+// Retrieval info: PRIVATE: CNX_NO_COMPENSATE_RADIO STRING "0"
+// Retrieval info: PRIVATE: CREATE_CLKBAD_CHECK STRING "0"
+// Retrieval info: PRIVATE: CREATE_INCLK1_CHECK STRING "0"
+// Retrieval info: PRIVATE: CUR_DEDICATED_CLK STRING "c0"
+// Retrieval info: PRIVATE: CUR_FBIN_CLK STRING "c0"
+// Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "7"
+// Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "1"
+// Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000"
+// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "20.000000"
+// Retrieval info: PRIVATE: EXPLICIT_SWITCHOVER_COUNTER STRING "0"
+// Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0"
+// Retrieval info: PRIVATE: GLOCKED_COUNTER_EDIT_CHANGED STRING "1"
+// Retrieval info: PRIVATE: GLOCKED_FEATURE_ENABLED STRING "1"
+// Retrieval info: PRIVATE: GLOCKED_MODE_CHECK STRING "1"
+// Retrieval info: PRIVATE: GLOCK_COUNTER_EDIT NUMERIC "1048575"
+// Retrieval info: PRIVATE: HAS_MANUAL_SWITCHOVER STRING "1"
+// Retrieval info: PRIVATE: INCLK0_FREQ_EDIT STRING "50.000"
+// Retrieval info: PRIVATE: INCLK0_FREQ_UNIT_COMBO STRING "MHz"
+// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT STRING "100.000"
+// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT_CHANGED STRING "1"
+// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_CHANGED STRING "1"
+// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_COMBO STRING "MHz"
+// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone II"
+// Retrieval info: PRIVATE: INT_FEEDBACK__MODE_RADIO STRING "1"
+// Retrieval info: PRIVATE: LOCKED_OUTPUT_CHECK STRING "1"
+// Retrieval info: PRIVATE: LONG_SCAN_RADIO STRING "1"
+// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE STRING "Not Available"
+// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE_DIRTY NUMERIC "0"
+// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT0 STRING "deg"
+// Retrieval info: PRIVATE: MIG_DEVICE_SPEED_GRADE STRING "Any"
+// Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0"
+// Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "1"
+// Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1"
+// Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "20.00000000"
+// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "1"
+// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz"
+// Retrieval info: PRIVATE: PHASE_RECONFIG_FEATURE_ENABLED STRING "0"
+// Retrieval info: PRIVATE: PHASE_RECONFIG_INPUTS_CHECK STRING "0"
+// Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000"
+// Retrieval info: PRIVATE: PHASE_SHIFT_STEP_ENABLED_CHECK STRING "0"
+// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg"
+// Retrieval info: PRIVATE: PLL_ADVANCED_PARAM_CHECK STRING "0"
+// Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "1"
+// Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1"
+// Retrieval info: PRIVATE: PLL_ENA_CHECK STRING "0"
+// Retrieval info: PRIVATE: PLL_ENHPLL_CHECK NUMERIC "0"
+// Retrieval info: PRIVATE: PLL_FASTPLL_CHECK NUMERIC "0"
+// Retrieval info: PRIVATE: PLL_FBMIMIC_CHECK STRING "0"
+// Retrieval info: PRIVATE: PLL_LVDS_PLL_CHECK NUMERIC "0"
+// Retrieval info: PRIVATE: PLL_PFDENA_CHECK STRING "0"
+// Retrieval info: PRIVATE: PLL_TARGET_HARCOPY_CHECK NUMERIC "0"
+// Retrieval info: PRIVATE: PRIMARY_CLK_COMBO STRING "inclk0"
+// Retrieval info: PRIVATE: RECONFIG_FILE STRING "pll.mif"
+// Retrieval info: PRIVATE: SACN_INPUTS_CHECK STRING "0"
+// Retrieval info: PRIVATE: SCAN_FEATURE_ENABLED STRING "0"
+// Retrieval info: PRIVATE: SELF_RESET_LOCK_LOSS STRING "0"
+// Retrieval info: PRIVATE: SHORT_SCAN_RADIO STRING "0"
+// Retrieval info: PRIVATE: SPREAD_FEATURE_ENABLED STRING "0"
+// Retrieval info: PRIVATE: SPREAD_FREQ STRING "50.000"
+// Retrieval info: PRIVATE: SPREAD_FREQ_UNIT STRING "KHz"
+// Retrieval info: PRIVATE: SPREAD_PERCENT STRING "0.500"
+// Retrieval info: PRIVATE: SPREAD_USE STRING "0"
+// Retrieval info: PRIVATE: SRC_SYNCH_COMP_RADIO STRING "0"
+// Retrieval info: PRIVATE: STICKY_CLK0 STRING "1"
+// Retrieval info: PRIVATE: SWITCHOVER_COUNT_EDIT NUMERIC "1"
+// Retrieval info: PRIVATE: SWITCHOVER_FEATURE_ENABLED STRING "1"
+// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
+// Retrieval info: PRIVATE: USE_CLK0 STRING "1"
+// Retrieval info: PRIVATE: USE_CLKENA0 STRING "0"
+// Retrieval info: PRIVATE: USE_MIL_SPEED_GRADE NUMERIC "0"
+// Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0"
+// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
+// Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "5"
+// Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50"
+// Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "2"
+// Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0"
+// Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK0"
+// Retrieval info: CONSTANT: GATE_LOCK_COUNTER NUMERIC "1048575"
+// Retrieval info: CONSTANT: GATE_LOCK_SIGNAL STRING "YES"
+// Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "20000"
+// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone II"
+// Retrieval info: CONSTANT: INVALID_LOCK_MULTIPLIER NUMERIC "5"
+// Retrieval info: CONSTANT: LPM_TYPE STRING "altpll"
+// Retrieval info: CONSTANT: OPERATION_MODE STRING "NORMAL"
+// Retrieval info: CONSTANT: PORT_ACTIVECLOCK STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_ARESET STRING "PORT_USED"
+// Retrieval info: CONSTANT: PORT_CLKBAD0 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_CLKBAD1 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_CLKLOSS STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_CLKSWITCH STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_CONFIGUPDATE STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_FBIN STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_INCLK0 STRING "PORT_USED"
+// Retrieval info: CONSTANT: PORT_INCLK1 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_LOCKED STRING "PORT_USED"
+// Retrieval info: CONSTANT: PORT_PFDENA STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_PHASECOUNTERSELECT STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_PHASEDONE STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_PHASESTEP STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_PHASEUPDOWN STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_PLLENA STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_SCANACLR STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_SCANCLK STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_SCANCLKENA STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_SCANDATA STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_SCANDATAOUT STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_SCANDONE STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_SCANREAD STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_SCANWRITE STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_clk0 STRING "PORT_USED"
+// Retrieval info: CONSTANT: PORT_clk1 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_clk2 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_clk3 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_clk4 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_clk5 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_clkena0 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_clkena1 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_clkena2 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_clkena3 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_clkena4 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_clkena5 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_extclk0 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_extclk1 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_extclk2 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_extclk3 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: VALID_LOCK_MULTIPLIER NUMERIC "1"
+// Retrieval info: USED_PORT: @clk 0 0 6 0 OUTPUT_CLK_EXT VCC "@clk[5..0]"
+// Retrieval info: USED_PORT: @extclk 0 0 4 0 OUTPUT_CLK_EXT VCC "@extclk[3..0]"
+// Retrieval info: USED_PORT: areset 0 0 0 0 INPUT GND "areset"
+// Retrieval info: USED_PORT: c0 0 0 0 0 OUTPUT_CLK_EXT VCC "c0"
+// Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT_CLK_EXT GND "inclk0"
+// Retrieval info: USED_PORT: locked 0 0 0 0 OUTPUT GND "locked"
+// Retrieval info: CONNECT: @areset 0 0 0 0 areset 0 0 0 0
+// Retrieval info: CONNECT: @inclk 0 0 1 1 GND 0 0 0 0
+// Retrieval info: CONNECT: @inclk 0 0 1 0 inclk0 0 0 0 0
+// Retrieval info: CONNECT: c0 0 0 0 0 @clk 0 0 1 0
+// Retrieval info: CONNECT: locked 0 0 0 0 @locked 0 0 0 0
+// Retrieval info: GEN_FILE: TYPE_NORMAL pll.v TRUE
+// Retrieval info: GEN_FILE: TYPE_NORMAL pll.ppf TRUE
+// Retrieval info: GEN_FILE: TYPE_NORMAL pll.inc FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL pll.cmp FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL pll.bsf FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL pll_inst.v FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL pll_bb.v TRUE
+// Retrieval info: LIB_FILE: altera_mf
+// Retrieval info: CBX_MODULE_PREFIX: ON
diff --git a/protocol.txt b/protocol.txt
new file mode 100644
index 0000000..c332f7c
--- /dev/null
+++ b/protocol.txt
@@ -0,0 +1,61 @@
+Virtual IR register (4 bits):
+
+0 - bypass
+1 - read fifo
+2 - write fifo space query
+3 - write fifo
+4 - read ready (single bit)
+5 - write reset flag (single bit; write 1 then 0)
+F - bypass
+
+Virtual DR register 1:
+
+READ FIFO
+
+72 bits:
+-binary- -------hex-------
+V000CCCC DDDDDDD DDDDDDDDD - V = valid
+ - C = top 4 bits of command
+
+Read transactions can be streamed by shifting out a multiple of 72 bits.
+
+Virtual DR register 2:
+
+Reads the amount of space in the write FIFO as an 8-bit number.
+
+
+Virtual DR register 3:
+
+WRITE FIFO
+
+72 bits:
+-binary- -------hex-------
+000XXXXX XXXXXXXX XXXXXXXX - noop
+
+001XXXXX XXXXXXXX CCCCCCCC - delay for C cycles @ 20 MHz
+
+010IXXXX AAAAAAAA CCCCCCCC - zero check
+ Returns last address read in [63:32]
+ Returns last datum 1's extended in [31:0] - FFFFFFFF on success
+
+011XXXXX XXXXXXXX TTTTTTTT - read back address register, token
+ Returns address register in [63:32]
+ Returns token in [31:0]
+
+100SEEEE AAAAAAAA DDDDDDDD - write cycle (address, data)
+ address register set to A if S=1
+ E is byte enables; for a byte flash
+ E should be set to 0001
+
+101ICCCC DDDDDDDD DDDDDDDD - program bytes (C = byte count)
+ address register incremented if I=1
+ (this should always be the case)
+
+110IXXXX AAAAAAAA CCCCCCCC - set address register to A
+ read C bytes (pad output to 64 bits)
+ address register incremented if I=1
+ if C=0 no read is done
+
+111XXXXX XXXXXXXX XXXXXXXX - noop
+
+For vestigial writes the data should be right-justified (LSB valid)
diff --git a/vjtag_mega.qip b/vjtag_mega.qip
new file mode 100644
index 0000000..9bff0d2
--- /dev/null
+++ b/vjtag_mega.qip
@@ -0,0 +1,6 @@
+set_global_assignment -name IP_TOOL_NAME "Virtual JTAG"
+set_global_assignment -name IP_TOOL_VERSION "11.0"
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "vjtag_mega.v"]
+set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "vjtag_mega.bsf"]
+set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "vjtag_mega_inst.v"]
+set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "vjtag_mega_bb.v"]
diff --git a/vjtag_mega.v b/vjtag_mega.v
new file mode 100644
index 0000000..844c24d
--- /dev/null
+++ b/vjtag_mega.v
@@ -0,0 +1,181 @@
+// megafunction wizard: %Virtual JTAG%
+// GENERATION: STANDARD
+// VERSION: WM1.0
+// MODULE: sld_virtual_jtag
+
+// ============================================================
+// File Name: vjtag_mega.v
+// Megafunction Name(s):
+// sld_virtual_jtag
+//
+// Simulation Library Files(s):
+// altera_mf
+// ============================================================
+// ************************************************************
+// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
+//
+// 11.0 Build 157 04/27/2011 SJ Web Edition
+// ************************************************************
+
+
+//Copyright (C) 1991-2011 Altera Corporation
+//Your use of Altera Corporation's design tools, logic functions
+//and other software and tools, and its AMPP partner logic
+//functions, and any output files from any of the foregoing
+//(including device programming or simulation files), and any
+//associated documentation or information are expressly subject
+//to the terms and conditions of the Altera Program License
+//Subscription Agreement, Altera MegaCore Function License
+//Agreement, or other applicable license agreement, including,
+//without limitation, that your use is for the sole purpose of
+//programming logic devices manufactured by Altera and sold by
+//Altera or its authorized distributors. Please refer to the
+//applicable agreement for further details.
+
+
+// synopsys translate_off
+`timescale 1 ps / 1 ps
+// synopsys translate_on
+module vjtag_mega (
+ ir_out,
+ tdo,
+ ir_in,
+ tck,
+ tdi,
+ virtual_state_cdr,
+ virtual_state_cir,
+ virtual_state_e1dr,
+ virtual_state_e2dr,
+ virtual_state_pdr,
+ virtual_state_sdr,
+ virtual_state_udr,
+ virtual_state_uir);
+
+ input [3:0] ir_out;
+ input tdo;
+ output [3:0] ir_in;
+ output tck;
+ output tdi;
+ output virtual_state_cdr;
+ output virtual_state_cir;
+ output virtual_state_e1dr;
+ output virtual_state_e2dr;
+ output virtual_state_pdr;
+ output virtual_state_sdr;
+ output virtual_state_udr;
+ output virtual_state_uir;
+
+ wire sub_wire0;
+ wire sub_wire1;
+ wire [3:0] sub_wire2;
+ wire sub_wire3;
+ wire sub_wire4;
+ wire sub_wire5;
+ wire sub_wire6;
+ wire sub_wire7;
+ wire sub_wire8;
+ wire sub_wire9;
+ wire sub_wire10;
+ wire virtual_state_cir = sub_wire0;
+ wire virtual_state_pdr = sub_wire1;
+ wire [3:0] ir_in = sub_wire2[3:0];
+ wire tdi = sub_wire3;
+ wire virtual_state_udr = sub_wire4;
+ wire tck = sub_wire5;
+ wire virtual_state_e1dr = sub_wire6;
+ wire virtual_state_uir = sub_wire7;
+ wire virtual_state_cdr = sub_wire8;
+ wire virtual_state_e2dr = sub_wire9;
+ wire virtual_state_sdr = sub_wire10;
+
+ sld_virtual_jtag sld_virtual_jtag_component (
+ .ir_out (ir_out),
+ .tdo (tdo),
+ .virtual_state_cir (sub_wire0),
+ .virtual_state_pdr (sub_wire1),
+ .ir_in (sub_wire2),
+ .tdi (sub_wire3),
+ .virtual_state_udr (sub_wire4),
+ .tck (sub_wire5),
+ .virtual_state_e1dr (sub_wire6),
+ .virtual_state_uir (sub_wire7),
+ .virtual_state_cdr (sub_wire8),
+ .virtual_state_e2dr (sub_wire9),
+ .virtual_state_sdr (sub_wire10)
+ // synopsys translate_off
+ ,
+ .jtag_state_cdr (),
+ .jtag_state_cir (),
+ .jtag_state_e1dr (),
+ .jtag_state_e1ir (),
+ .jtag_state_e2dr (),
+ .jtag_state_e2ir (),
+ .jtag_state_pdr (),
+ .jtag_state_pir (),
+ .jtag_state_rti (),
+ .jtag_state_sdr (),
+ .jtag_state_sdrs (),
+ .jtag_state_sir (),
+ .jtag_state_sirs (),
+ .jtag_state_tlr (),
+ .jtag_state_udr (),
+ .jtag_state_uir (),
+ .tms ()
+ // synopsys translate_on
+ );
+ defparam
+ sld_virtual_jtag_component.sld_auto_instance_index = "YES",
+ sld_virtual_jtag_component.sld_instance_index = 0,
+ sld_virtual_jtag_component.sld_ir_width = 4,
+ sld_virtual_jtag_component.sld_sim_action = "",
+ sld_virtual_jtag_component.sld_sim_n_scan = 0,
+ sld_virtual_jtag_component.sld_sim_total_length = 0;
+
+
+endmodule
+
+// ============================================================
+// CNX file retrieval info
+// ============================================================
+// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone II"
+// Retrieval info: PRIVATE: show_jtag_state STRING "0"
+// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
+// Retrieval info: CONSTANT: SLD_AUTO_INSTANCE_INDEX STRING "YES"
+// Retrieval info: CONSTANT: SLD_INSTANCE_INDEX NUMERIC "0"
+// Retrieval info: CONSTANT: SLD_IR_WIDTH NUMERIC "4"
+// Retrieval info: CONSTANT: SLD_SIM_ACTION STRING ""
+// Retrieval info: CONSTANT: SLD_SIM_N_SCAN NUMERIC "0"
+// Retrieval info: CONSTANT: SLD_SIM_TOTAL_LENGTH NUMERIC "0"
+// Retrieval info: USED_PORT: ir_in 0 0 4 0 OUTPUT NODEFVAL "ir_in[3..0]"
+// Retrieval info: USED_PORT: ir_out 0 0 4 0 INPUT NODEFVAL "ir_out[3..0]"
+// Retrieval info: USED_PORT: tck 0 0 0 0 OUTPUT NODEFVAL "tck"
+// Retrieval info: USED_PORT: tdi 0 0 0 0 OUTPUT NODEFVAL "tdi"
+// Retrieval info: USED_PORT: tdo 0 0 0 0 INPUT NODEFVAL "tdo"
+// Retrieval info: USED_PORT: virtual_state_cdr 0 0 0 0 OUTPUT NODEFVAL "virtual_state_cdr"
+// Retrieval info: USED_PORT: virtual_state_cir 0 0 0 0 OUTPUT NODEFVAL "virtual_state_cir"
+// Retrieval info: USED_PORT: virtual_state_e1dr 0 0 0 0 OUTPUT NODEFVAL "virtual_state_e1dr"
+// Retrieval info: USED_PORT: virtual_state_e2dr 0 0 0 0 OUTPUT NODEFVAL "virtual_state_e2dr"
+// Retrieval info: USED_PORT: virtual_state_pdr 0 0 0 0 OUTPUT NODEFVAL "virtual_state_pdr"
+// Retrieval info: USED_PORT: virtual_state_sdr 0 0 0 0 OUTPUT NODEFVAL "virtual_state_sdr"
+// Retrieval info: USED_PORT: virtual_state_udr 0 0 0 0 OUTPUT NODEFVAL "virtual_state_udr"
+// Retrieval info: USED_PORT: virtual_state_uir 0 0 0 0 OUTPUT NODEFVAL "virtual_state_uir"
+// Retrieval info: CONNECT: @ir_out 0 0 4 0 ir_out 0 0 4 0
+// Retrieval info: CONNECT: @tdo 0 0 0 0 tdo 0 0 0 0
+// Retrieval info: CONNECT: ir_in 0 0 4 0 @ir_in 0 0 4 0
+// Retrieval info: CONNECT: tck 0 0 0 0 @tck 0 0 0 0
+// Retrieval info: CONNECT: tdi 0 0 0 0 @tdi 0 0 0 0
+// Retrieval info: CONNECT: virtual_state_cdr 0 0 0 0 @virtual_state_cdr 0 0 0 0
+// Retrieval info: CONNECT: virtual_state_cir 0 0 0 0 @virtual_state_cir 0 0 0 0
+// Retrieval info: CONNECT: virtual_state_e1dr 0 0 0 0 @virtual_state_e1dr 0 0 0 0
+// Retrieval info: CONNECT: virtual_state_e2dr 0 0 0 0 @virtual_state_e2dr 0 0 0 0
+// Retrieval info: CONNECT: virtual_state_pdr 0 0 0 0 @virtual_state_pdr 0 0 0 0
+// Retrieval info: CONNECT: virtual_state_sdr 0 0 0 0 @virtual_state_sdr 0 0 0 0
+// Retrieval info: CONNECT: virtual_state_udr 0 0 0 0 @virtual_state_udr 0 0 0 0
+// Retrieval info: CONNECT: virtual_state_uir 0 0 0 0 @virtual_state_uir 0 0 0 0
+// Retrieval info: GEN_FILE: TYPE_NORMAL vjtag_mega.v TRUE
+// Retrieval info: GEN_FILE: TYPE_NORMAL vjtag_mega.inc FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL vjtag_mega.cmp FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL vjtag_mega.bsf TRUE
+// Retrieval info: GEN_FILE: TYPE_NORMAL vjtag_mega_inst.v TRUE
+// Retrieval info: GEN_FILE: TYPE_NORMAL vjtag_mega_bb.v TRUE
+// Retrieval info: LIB_FILE: altera_mf