From 727aa5bce92d678e9ac7d4bf27d81a11867b47b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Fr=C3=B6schle?= Date: Mon, 9 Jun 2014 20:35:29 +0000 Subject: [PATCH] initial import after removal of FPGA_quartus --- vhdl/backend/Altera/Firebee/altpll4.mif | 174 ++ vhdl/backend/Altera/Firebee/firebee.qpf | 30 + vhdl/backend/Altera/Firebee/firebee.qsf | 673 +++++ vhdl/backend/Altera/Firebee/firebee.sdc | 868 +++++++ .../Firebee/firebee_assignment_defaults.qdf | 692 +++++ vhdl/rtl/vhdl/Blitter/Blitter_WF.vhd | 101 + vhdl/rtl/vhdl/Blitter/tmp.txt | 75 + vhdl/rtl/vhdl/DDR/DDR_CTRL.vhd | 807 ++++++ vhdl/rtl/vhdl/DMA/dcfifo0.vhd | 202 ++ vhdl/rtl/vhdl/DMA/dcfifo1.vhd | 202 ++ vhdl/rtl/vhdl/DMA/fbee_dma.vhd | 589 +++++ vhdl/rtl/vhdl/DSP/DSP.vhd | 83 + vhdl/rtl/vhdl/DSP/src/adgen_stage.vhd | 216 ++ vhdl/rtl/vhdl/DSP/src/constants_pkg.vhd | 62 + vhdl/rtl/vhdl/DSP/src/decode_stage.vhd | 1221 +++++++++ vhdl/rtl/vhdl/DSP/src/exec_stage_alu.vhd | 603 +++++ .../vhdl/DSP/src/exec_stage_bit_modify.vhd | 79 + vhdl/rtl/vhdl/DSP/src/exec_stage_branch.vhd | 117 + .../vhdl/DSP/src/exec_stage_cc_flag_calc.vhd | 75 + vhdl/rtl/vhdl/DSP/src/exec_stage_cr_mod.vhd | 72 + vhdl/rtl/vhdl/DSP/src/exec_stage_loops.vhd | 200 ++ vhdl/rtl/vhdl/DSP/src/fetch_stage.vhd | 60 + vhdl/rtl/vhdl/DSP/src/mem_control.vhd | 1519 +++++++++++ vhdl/rtl/vhdl/DSP/src/memory_management.vhd | 206 ++ vhdl/rtl/vhdl/DSP/src/parameter_pkg.vhd | 10 + vhdl/rtl/vhdl/DSP/src/pipeline.vhd | 968 +++++++ vhdl/rtl/vhdl/DSP/src/reg_file.vhd | 679 +++++ vhdl/rtl/vhdl/DSP/src/types_pkg.vhd | 167 ++ vhdl/rtl/vhdl/Firebee_V1/Firebee_V1.sdc | 30 + vhdl/rtl/vhdl/Firebee_V1/Firebee_V1_Top.vhd | 1306 ++++++++++ vhdl/rtl/vhdl/Firebee_V1/Firebee_V1_pkg.vhd | 579 +++++ vhdl/rtl/vhdl/Firebee_V1/altpll0.ppf | 13 + vhdl/rtl/vhdl/Firebee_V1/altpll0.qip | 7 + vhdl/rtl/vhdl/Firebee_V1/altpll1.bsf | 100 + vhdl/rtl/vhdl/Firebee_V1/altpll1.cmp | 25 + vhdl/rtl/vhdl/Firebee_V1/altpll1.inc | 26 + vhdl/rtl/vhdl/Firebee_V1/altpll1.ppf | 12 + vhdl/rtl/vhdl/Firebee_V1/altpll1.qip | 7 + vhdl/rtl/vhdl/Firebee_V1/altpll1.vhd | 420 ++++ .../vhdl/Firebee_V1/altpll1_waveforms.html | 10 + vhdl/rtl/vhdl/Firebee_V1/altpll2.bsf | 117 + vhdl/rtl/vhdl/Firebee_V1/altpll2.cmp | 26 + vhdl/rtl/vhdl/Firebee_V1/altpll2.inc | 27 + vhdl/rtl/vhdl/Firebee_V1/altpll2.ppf | 13 + vhdl/rtl/vhdl/Firebee_V1/altpll2.qip | 7 + vhdl/rtl/vhdl/Firebee_V1/altpll2.vhd | 474 ++++ .../vhdl/Firebee_V1/altpll2_waveforms.html | 10 + vhdl/rtl/vhdl/Firebee_V1/altpll3.bsf | 105 + vhdl/rtl/vhdl/Firebee_V1/altpll3.cmp | 25 + vhdl/rtl/vhdl/Firebee_V1/altpll3.inc | 26 + vhdl/rtl/vhdl/Firebee_V1/altpll3.ppf | 12 + vhdl/rtl/vhdl/Firebee_V1/altpll3.qip | 7 + vhdl/rtl/vhdl/Firebee_V1/altpll3.vhd | 445 ++++ vhdl/rtl/vhdl/Firebee_V1/altpll4.mif | 174 ++ vhdl/rtl/vhdl/Firebee_V1/altpll4.ppf | 17 + vhdl/rtl/vhdl/Firebee_V1/altpll4.qip | 4 + vhdl/rtl/vhdl/Firebee_V1/altpll4.vhd | 400 +++ vhdl/rtl/vhdl/Firebee_V1/altpll_reconfig1.qip | 3 + vhdl/rtl/vhdl/Firebee_V1/altpll_reconfig1.vhd | 2239 +++++++++++++++++ .../vhdl/Firebee_V1/greybox_tmp/cbx_args.txt | 20 + vhdl/rtl/vhdl/Interrupt/interrupt.vhd | 306 +++ vhdl/rtl/vhdl/Peripherals/ide_cf_sd_rom.vhd | 181 ++ vhdl/rtl/vhdl/RTC/rtc.vhd | 232 ++ vhdl/rtl/vhdl/Video/VIDEO_CTRL.vhd | 958 +++++++ vhdl/rtl/vhdl/Video/Video_Top.vhd | 533 ++++ vhdl/rtl/vhdl/Video/lpm_fifoDZ.cmp | 26 + vhdl/rtl/vhdl/Video/lpm_fifoDZ.qip | 5 + vhdl/rtl/vhdl/Video/lpm_fifoDZ.vhd | 178 ++ vhdl/rtl/vhdl/Video/lpm_fifo_dc0.cmp | 29 + vhdl/rtl/vhdl/Video/lpm_fifo_dc0.qip | 6 + vhdl/rtl/vhdl/Video/lpm_fifo_dc0.vhd | 203 ++ vhdl/rtl/vhdl/WF5380/wf5380_control.vhd | 614 +++++ vhdl/rtl/vhdl/WF5380/wf5380_pkg.vhd | 122 + vhdl/rtl/vhdl/WF5380/wf5380_registers.vhd | 248 ++ vhdl/rtl/vhdl/WF5380/wf5380_soc_top.vhd | 283 +++ vhdl/rtl/vhdl/WF5380/wf5380_top.vhd | 258 ++ .../WF_FDC1772_IP/wf1772ip_am_detector.vhd | 253 ++ .../vhdl/WF_FDC1772_IP/wf1772ip_control.vhd | 1465 +++++++++++ .../vhdl/WF_FDC1772_IP/wf1772ip_crc_logic.vhd | 162 ++ .../WF_FDC1772_IP/wf1772ip_digital_pll.vhd | 426 ++++ vhdl/rtl/vhdl/WF_FDC1772_IP/wf1772ip_pkg.vhd | 232 ++ .../vhdl/WF_FDC1772_IP/wf1772ip_registers.vhd | 264 ++ vhdl/rtl/vhdl/WF_FDC1772_IP/wf1772ip_top.vhd | 154 ++ .../vhdl/WF_FDC1772_IP/wf1772ip_top_soc.vhd | 333 +++ .../WF_FDC1772_IP/wf1772ip_transceiver.vhd | 517 ++++ .../Test_CLKDIV/wf68901ip_clkdiv.vhd | 108 + .../Test_Timers/wf68901ip_timers.vhd | 107 + .../Test_USART_Rx/wf68901ip_usart_rx.vhd | 581 +++++ .../Test_USART_Tx/wf68901ip_usart_tx.vhd | 379 +++ .../vhdl/WF_MFP68901_IP/wf68901ip_gpio.vhd | 141 ++ .../WF_MFP68901_IP/wf68901ip_interrupts.vhd | 391 +++ .../rtl/vhdl/WF_MFP68901_IP/wf68901ip_pkg.vhd | 263 ++ .../vhdl/WF_MFP68901_IP/wf68901ip_timers.vhd | 530 ++++ .../rtl/vhdl/WF_MFP68901_IP/wf68901ip_top.vhd | 213 ++ .../vhdl/WF_MFP68901_IP/wf68901ip_top_soc.vhd | 309 +++ .../WF_MFP68901_IP/wf68901ip_usart_ctrl.vhd | 191 ++ .../WF_MFP68901_IP/wf68901ip_usart_rx.vhd | 590 +++++ .../WF_MFP68901_IP/wf68901ip_usart_top.vhd | 238 ++ .../WF_MFP68901_IP/wf68901ip_usart_tx.vhd | 387 +++ vhdl/rtl/vhdl/WF_SND2149_IP/wf2149ip_pkg.vhd | 84 + vhdl/rtl/vhdl/WF_SND2149_IP/wf2149ip_top.vhd | 170 ++ .../vhdl/WF_SND2149_IP/wf2149ip_top_soc.vhd | 229 ++ vhdl/rtl/vhdl/WF_SND2149_IP/wf2149ip_wave.vhd | 534 ++++ .../WF_UART6850_IP/wf6850ip_ctrl_status.vhd | 202 ++ .../vhdl/WF_UART6850_IP/wf6850ip_receive.vhd | 417 +++ vhdl/rtl/vhdl/WF_UART6850_IP/wf6850ip_top.vhd | 135 + .../vhdl/WF_UART6850_IP/wf6850ip_top_soc.vhd | 256 ++ .../vhdl/WF_UART6850_IP/wf6850ip_transmit.vhd | 338 +++ vhdl/testbenches/ddr_ctlr_tb.vhd | 82 + 109 files changed, 32299 insertions(+) create mode 100644 vhdl/backend/Altera/Firebee/altpll4.mif create mode 100755 vhdl/backend/Altera/Firebee/firebee.qpf create mode 100755 vhdl/backend/Altera/Firebee/firebee.qsf create mode 100755 vhdl/backend/Altera/Firebee/firebee.sdc create mode 100644 vhdl/backend/Altera/Firebee/firebee_assignment_defaults.qdf create mode 100644 vhdl/rtl/vhdl/Blitter/Blitter_WF.vhd create mode 100644 vhdl/rtl/vhdl/Blitter/tmp.txt create mode 100644 vhdl/rtl/vhdl/DDR/DDR_CTRL.vhd create mode 100644 vhdl/rtl/vhdl/DMA/dcfifo0.vhd create mode 100644 vhdl/rtl/vhdl/DMA/dcfifo1.vhd create mode 100644 vhdl/rtl/vhdl/DMA/fbee_dma.vhd create mode 100644 vhdl/rtl/vhdl/DSP/DSP.vhd create mode 100644 vhdl/rtl/vhdl/DSP/src/adgen_stage.vhd create mode 100644 vhdl/rtl/vhdl/DSP/src/constants_pkg.vhd create mode 100644 vhdl/rtl/vhdl/DSP/src/decode_stage.vhd create mode 100644 vhdl/rtl/vhdl/DSP/src/exec_stage_alu.vhd create mode 100644 vhdl/rtl/vhdl/DSP/src/exec_stage_bit_modify.vhd create mode 100644 vhdl/rtl/vhdl/DSP/src/exec_stage_branch.vhd create mode 100644 vhdl/rtl/vhdl/DSP/src/exec_stage_cc_flag_calc.vhd create mode 100644 vhdl/rtl/vhdl/DSP/src/exec_stage_cr_mod.vhd create mode 100644 vhdl/rtl/vhdl/DSP/src/exec_stage_loops.vhd create mode 100644 vhdl/rtl/vhdl/DSP/src/fetch_stage.vhd create mode 100644 vhdl/rtl/vhdl/DSP/src/mem_control.vhd create mode 100644 vhdl/rtl/vhdl/DSP/src/memory_management.vhd create mode 100644 vhdl/rtl/vhdl/DSP/src/parameter_pkg.vhd create mode 100644 vhdl/rtl/vhdl/DSP/src/pipeline.vhd create mode 100644 vhdl/rtl/vhdl/DSP/src/reg_file.vhd create mode 100644 vhdl/rtl/vhdl/DSP/src/types_pkg.vhd create mode 100644 vhdl/rtl/vhdl/Firebee_V1/Firebee_V1.sdc create mode 100644 vhdl/rtl/vhdl/Firebee_V1/Firebee_V1_Top.vhd create mode 100644 vhdl/rtl/vhdl/Firebee_V1/Firebee_V1_pkg.vhd create mode 100644 vhdl/rtl/vhdl/Firebee_V1/altpll0.ppf create mode 100644 vhdl/rtl/vhdl/Firebee_V1/altpll0.qip create mode 100644 vhdl/rtl/vhdl/Firebee_V1/altpll1.bsf create mode 100644 vhdl/rtl/vhdl/Firebee_V1/altpll1.cmp create mode 100644 vhdl/rtl/vhdl/Firebee_V1/altpll1.inc create mode 100644 vhdl/rtl/vhdl/Firebee_V1/altpll1.ppf create mode 100644 vhdl/rtl/vhdl/Firebee_V1/altpll1.qip create mode 100644 vhdl/rtl/vhdl/Firebee_V1/altpll1.vhd create mode 100644 vhdl/rtl/vhdl/Firebee_V1/altpll1_waveforms.html create mode 100644 vhdl/rtl/vhdl/Firebee_V1/altpll2.bsf create mode 100644 vhdl/rtl/vhdl/Firebee_V1/altpll2.cmp create mode 100644 vhdl/rtl/vhdl/Firebee_V1/altpll2.inc create mode 100644 vhdl/rtl/vhdl/Firebee_V1/altpll2.ppf create mode 100644 vhdl/rtl/vhdl/Firebee_V1/altpll2.qip create mode 100644 vhdl/rtl/vhdl/Firebee_V1/altpll2.vhd create mode 100644 vhdl/rtl/vhdl/Firebee_V1/altpll2_waveforms.html create mode 100644 vhdl/rtl/vhdl/Firebee_V1/altpll3.bsf create mode 100644 vhdl/rtl/vhdl/Firebee_V1/altpll3.cmp create mode 100644 vhdl/rtl/vhdl/Firebee_V1/altpll3.inc create mode 100644 vhdl/rtl/vhdl/Firebee_V1/altpll3.ppf create mode 100644 vhdl/rtl/vhdl/Firebee_V1/altpll3.qip create mode 100644 vhdl/rtl/vhdl/Firebee_V1/altpll3.vhd create mode 100644 vhdl/rtl/vhdl/Firebee_V1/altpll4.mif create mode 100644 vhdl/rtl/vhdl/Firebee_V1/altpll4.ppf create mode 100644 vhdl/rtl/vhdl/Firebee_V1/altpll4.qip create mode 100644 vhdl/rtl/vhdl/Firebee_V1/altpll4.vhd create mode 100644 vhdl/rtl/vhdl/Firebee_V1/altpll_reconfig1.qip create mode 100644 vhdl/rtl/vhdl/Firebee_V1/altpll_reconfig1.vhd create mode 100644 vhdl/rtl/vhdl/Firebee_V1/greybox_tmp/cbx_args.txt create mode 100644 vhdl/rtl/vhdl/Interrupt/interrupt.vhd create mode 100644 vhdl/rtl/vhdl/Peripherals/ide_cf_sd_rom.vhd create mode 100644 vhdl/rtl/vhdl/RTC/rtc.vhd create mode 100644 vhdl/rtl/vhdl/Video/VIDEO_CTRL.vhd create mode 100644 vhdl/rtl/vhdl/Video/Video_Top.vhd create mode 100644 vhdl/rtl/vhdl/Video/lpm_fifoDZ.cmp create mode 100644 vhdl/rtl/vhdl/Video/lpm_fifoDZ.qip create mode 100644 vhdl/rtl/vhdl/Video/lpm_fifoDZ.vhd create mode 100644 vhdl/rtl/vhdl/Video/lpm_fifo_dc0.cmp create mode 100644 vhdl/rtl/vhdl/Video/lpm_fifo_dc0.qip create mode 100644 vhdl/rtl/vhdl/Video/lpm_fifo_dc0.vhd create mode 100644 vhdl/rtl/vhdl/WF5380/wf5380_control.vhd create mode 100644 vhdl/rtl/vhdl/WF5380/wf5380_pkg.vhd create mode 100644 vhdl/rtl/vhdl/WF5380/wf5380_registers.vhd create mode 100644 vhdl/rtl/vhdl/WF5380/wf5380_soc_top.vhd create mode 100644 vhdl/rtl/vhdl/WF5380/wf5380_top.vhd create mode 100644 vhdl/rtl/vhdl/WF_FDC1772_IP/wf1772ip_am_detector.vhd create mode 100644 vhdl/rtl/vhdl/WF_FDC1772_IP/wf1772ip_control.vhd create mode 100644 vhdl/rtl/vhdl/WF_FDC1772_IP/wf1772ip_crc_logic.vhd create mode 100644 vhdl/rtl/vhdl/WF_FDC1772_IP/wf1772ip_digital_pll.vhd create mode 100644 vhdl/rtl/vhdl/WF_FDC1772_IP/wf1772ip_pkg.vhd create mode 100644 vhdl/rtl/vhdl/WF_FDC1772_IP/wf1772ip_registers.vhd create mode 100644 vhdl/rtl/vhdl/WF_FDC1772_IP/wf1772ip_top.vhd create mode 100644 vhdl/rtl/vhdl/WF_FDC1772_IP/wf1772ip_top_soc.vhd create mode 100644 vhdl/rtl/vhdl/WF_FDC1772_IP/wf1772ip_transceiver.vhd create mode 100644 vhdl/rtl/vhdl/WF_MFP68901_IP/Test_CLKDIV/wf68901ip_clkdiv.vhd create mode 100644 vhdl/rtl/vhdl/WF_MFP68901_IP/Test_Timers/wf68901ip_timers.vhd create mode 100644 vhdl/rtl/vhdl/WF_MFP68901_IP/Test_USART_Rx/wf68901ip_usart_rx.vhd create mode 100644 vhdl/rtl/vhdl/WF_MFP68901_IP/Test_USART_Tx/wf68901ip_usart_tx.vhd create mode 100644 vhdl/rtl/vhdl/WF_MFP68901_IP/wf68901ip_gpio.vhd create mode 100644 vhdl/rtl/vhdl/WF_MFP68901_IP/wf68901ip_interrupts.vhd create mode 100644 vhdl/rtl/vhdl/WF_MFP68901_IP/wf68901ip_pkg.vhd create mode 100644 vhdl/rtl/vhdl/WF_MFP68901_IP/wf68901ip_timers.vhd create mode 100644 vhdl/rtl/vhdl/WF_MFP68901_IP/wf68901ip_top.vhd create mode 100644 vhdl/rtl/vhdl/WF_MFP68901_IP/wf68901ip_top_soc.vhd create mode 100644 vhdl/rtl/vhdl/WF_MFP68901_IP/wf68901ip_usart_ctrl.vhd create mode 100644 vhdl/rtl/vhdl/WF_MFP68901_IP/wf68901ip_usart_rx.vhd create mode 100644 vhdl/rtl/vhdl/WF_MFP68901_IP/wf68901ip_usart_top.vhd create mode 100644 vhdl/rtl/vhdl/WF_MFP68901_IP/wf68901ip_usart_tx.vhd create mode 100644 vhdl/rtl/vhdl/WF_SND2149_IP/wf2149ip_pkg.vhd create mode 100644 vhdl/rtl/vhdl/WF_SND2149_IP/wf2149ip_top.vhd create mode 100644 vhdl/rtl/vhdl/WF_SND2149_IP/wf2149ip_top_soc.vhd create mode 100644 vhdl/rtl/vhdl/WF_SND2149_IP/wf2149ip_wave.vhd create mode 100644 vhdl/rtl/vhdl/WF_UART6850_IP/wf6850ip_ctrl_status.vhd create mode 100644 vhdl/rtl/vhdl/WF_UART6850_IP/wf6850ip_receive.vhd create mode 100644 vhdl/rtl/vhdl/WF_UART6850_IP/wf6850ip_top.vhd create mode 100644 vhdl/rtl/vhdl/WF_UART6850_IP/wf6850ip_top_soc.vhd create mode 100644 vhdl/rtl/vhdl/WF_UART6850_IP/wf6850ip_transmit.vhd create mode 100644 vhdl/testbenches/ddr_ctlr_tb.vhd diff --git a/vhdl/backend/Altera/Firebee/altpll4.mif b/vhdl/backend/Altera/Firebee/altpll4.mif new file mode 100644 index 0000000..08595de --- /dev/null +++ b/vhdl/backend/Altera/Firebee/altpll4.mif @@ -0,0 +1,174 @@ +-- Copyright (C) 1991-2012 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. + +-- MIF file representing initial state of PLL Scan Chain +-- Device Family: Cyclone III +-- Device Part: - +-- Device Speed Grade: 8 +-- PLL Scan Chain: Fast PLL (144 bits) +-- File Name: D:/WF/Projects/VHDL-Designs/Firebee-WF/rtl/vhdl/Firebee_V1//altpll4.mif +-- Generated: Tue Jul 17 11:06:24 2012 + +WIDTH=1; +DEPTH=144; + +ADDRESS_RADIX=UNS; +DATA_RADIX=UNS; + +CONTENT BEGIN + 0 : 0; -- Reserved Bits = 0 (1 bit(s)) + 1 : 0; -- Reserved Bits = 0 (1 bit(s)) + 2 : 0; -- Loop Filter Capacitance = 0 (2 bit(s)) (Setting 0) + 3 : 0; + 4 : 1; -- Loop Filter Resistance = 27 (5 bit(s)) (Setting 27) + 5 : 1; + 6 : 0; + 7 : 1; + 8 : 1; + 9 : 1; -- VCO Post Scale = 1 (1 bit(s)) (VCO post-scale divider counter value = 1) + 10 : 0; -- Reserved Bits = 0 (5 bit(s)) + 11 : 0; + 12 : 0; + 13 : 0; + 14 : 0; + 15 : 0; -- Charge Pump Current = 1 (3 bit(s)) (Setting 1) + 16 : 0; + 17 : 1; + 18 : 1; -- N counter: Bypass = 1 (1 bit(s)) + 19 : 0; -- N counter: High Count = 0 (8 bit(s)) + 20 : 0; + 21 : 0; + 22 : 0; + 23 : 0; + 24 : 0; + 25 : 0; + 26 : 0; + 27 : 0; -- N counter: Odd Division = 0 (1 bit(s)) + 28 : 0; -- N counter: Low Count = 0 (8 bit(s)) + 29 : 0; + 30 : 0; + 31 : 0; + 32 : 0; + 33 : 0; + 34 : 0; + 35 : 0; + 36 : 0; -- M counter: Bypass = 0 (1 bit(s)) + 37 : 0; -- M counter: High Count = 16 (8 bit(s)) + 38 : 0; + 39 : 0; + 40 : 1; + 41 : 0; + 42 : 0; + 43 : 0; + 44 : 0; + 45 : 0; -- M counter: Odd Division = 0 (1 bit(s)) + 46 : 0; -- M counter: Low Count = 16 (8 bit(s)) + 47 : 0; + 48 : 0; + 49 : 1; + 50 : 0; + 51 : 0; + 52 : 0; + 53 : 0; + 54 : 0; -- clk0 counter: Bypass = 0 (1 bit(s)) + 55 : 0; -- clk0 counter: High Count = 6 (8 bit(s)) + 56 : 0; + 57 : 0; + 58 : 0; + 59 : 0; + 60 : 1; + 61 : 1; + 62 : 0; + 63 : 1; -- clk0 counter: Odd Division = 1 (1 bit(s)) + 64 : 0; -- clk0 counter: Low Count = 5 (8 bit(s)) + 65 : 0; + 66 : 0; + 67 : 0; + 68 : 0; + 69 : 1; + 70 : 0; + 71 : 1; + 72 : 1; -- clk1 counter: Bypass = 1 (1 bit(s)) + 73 : 0; -- clk1 counter: High Count = 0 (8 bit(s)) + 74 : 0; + 75 : 0; + 76 : 0; + 77 : 0; + 78 : 0; + 79 : 0; + 80 : 0; + 81 : 0; -- clk1 counter: Odd Division = 0 (1 bit(s)) + 82 : 0; -- clk1 counter: Low Count = 0 (8 bit(s)) + 83 : 0; + 84 : 0; + 85 : 0; + 86 : 0; + 87 : 0; + 88 : 0; + 89 : 0; + 90 : 1; -- clk2 counter: Bypass = 1 (1 bit(s)) + 91 : 0; -- clk2 counter: High Count = 0 (8 bit(s)) + 92 : 0; + 93 : 0; + 94 : 0; + 95 : 0; + 96 : 0; + 97 : 0; + 98 : 0; + 99 : 0; -- clk2 counter: Odd Division = 0 (1 bit(s)) + 100 : 0; -- clk2 counter: Low Count = 0 (8 bit(s)) + 101 : 0; + 102 : 0; + 103 : 0; + 104 : 0; + 105 : 0; + 106 : 0; + 107 : 0; + 108 : 1; -- clk3 counter: Bypass = 1 (1 bit(s)) + 109 : 0; -- clk3 counter: High Count = 0 (8 bit(s)) + 110 : 0; + 111 : 0; + 112 : 0; + 113 : 0; + 114 : 0; + 115 : 0; + 116 : 0; + 117 : 0; -- clk3 counter: Odd Division = 0 (1 bit(s)) + 118 : 0; -- clk3 counter: Low Count = 0 (8 bit(s)) + 119 : 0; + 120 : 0; + 121 : 0; + 122 : 0; + 123 : 0; + 124 : 0; + 125 : 0; + 126 : 1; -- clk4 counter: Bypass = 1 (1 bit(s)) + 127 : 0; -- clk4 counter: High Count = 0 (8 bit(s)) + 128 : 0; + 129 : 0; + 130 : 0; + 131 : 0; + 132 : 0; + 133 : 0; + 134 : 0; + 135 : 0; -- clk4 counter: Odd Division = 0 (1 bit(s)) + 136 : 0; -- clk4 counter: Low Count = 0 (8 bit(s)) + 137 : 0; + 138 : 0; + 139 : 0; + 140 : 0; + 141 : 0; + 142 : 0; + 143 : 0; +END; diff --git a/vhdl/backend/Altera/Firebee/firebee.qpf b/vhdl/backend/Altera/Firebee/firebee.qpf new file mode 100755 index 0000000..8fbda4b --- /dev/null +++ b/vhdl/backend/Altera/Firebee/firebee.qpf @@ -0,0 +1,30 @@ +# -------------------------------------------------------------------------- # +# +# Copyright (C) 1991-2013 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 32-bit +# Version 13.1.0 Build 162 10/23/2013 SJ Web Edition +# Date created = 11:04:08 May 31, 2014 +# +# -------------------------------------------------------------------------- # + +QUARTUS_VERSION = "13.1" +DATE = "11:04:08 May 31, 2014" + +# Revisions + +PROJECT_REVISION = "firebee" diff --git a/vhdl/backend/Altera/Firebee/firebee.qsf b/vhdl/backend/Altera/Firebee/firebee.qsf new file mode 100755 index 0000000..9534b16 --- /dev/null +++ b/vhdl/backend/Altera/Firebee/firebee.qsf @@ -0,0 +1,673 @@ +# -------------------------------------------------------------------------- # +# +# Copyright (C) 1991-2013 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 32-bit +# Version 13.1.0 Build 162 10/23/2013 SJ Web Edition +# Date created = 11:04:08 May 31, 2014 +# +# -------------------------------------------------------------------------- # +# +# Notes: +# +# 1) The default values for assignments are stored in the file: +# firebee_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 III" +set_global_assignment -name DEVICE EP3C40F484C6 +set_global_assignment -name TOP_LEVEL_ENTITY firebee +set_global_assignment -name ORIGINAL_QUARTUS_VERSION 13.1 +set_global_assignment -name PROJECT_CREATION_TIME_DATE "11:04:08 MAY 31, 2014" +set_global_assignment -name LAST_QUARTUS_VERSION 13.1 +set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files +set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0 +set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85 +set_global_assignment -name DEVICE_FILTER_PACKAGE FBGA +set_global_assignment -name DEVICE_FILTER_PIN_COUNT 484 +set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR 1 +set_global_assignment -name CYCLONEII_OPTIMIZATION_TECHNIQUE SPEED +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 EDA_SIMULATION_TOOL "ModelSim-Altera (VHDL)" +set_global_assignment -name EDA_OUTPUT_DATA_FORMAT VHDL -section_id eda_simulation +set_global_assignment -name STRATIX_DEVICE_IO_STANDARD "2.5 V" +set_global_assignment -name OPTIMIZE_HOLD_TIMING "ALL PATHS" +set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING ON +set_global_assignment -name EDA_TEST_BENCH_ENABLE_STATUS TEST_BENCH_MODE -section_id eda_simulation +set_global_assignment -name EDA_NATIVELINK_SIMULATION_TEST_BENCH ddr_ctlr_tb -section_id eda_simulation +set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "23 MM HEAT SINK WITH 200 LFPM AIRFLOW" +set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)" +set_global_assignment -name USE_CONFIGURATION_DEVICE OFF +set_global_assignment -name GENERATE_RBF_FILE ON +set_global_assignment -name CRC_ERROR_OPEN_DRAIN OFF +set_global_assignment -name OUTPUT_IO_TIMING_NEAR_END_VMEAS "HALF VCCIO" -rise +set_global_assignment -name OUTPUT_IO_TIMING_NEAR_END_VMEAS "HALF VCCIO" -fall +set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -rise +set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -fall + +set_location_assignment PIN_Y3 -to FB_AD[0] +set_location_assignment PIN_Y6 -to FB_AD[1] +set_location_assignment PIN_AA3 -to FB_AD[2] +set_location_assignment PIN_AB3 -to FB_AD[3] +set_location_assignment PIN_W6 -to FB_AD[4] +set_location_assignment PIN_V7 -to FB_AD[5] +set_location_assignment PIN_AA4 -to FB_AD[6] +set_location_assignment PIN_AB4 -to FB_AD[7] +set_location_assignment PIN_AA5 -to FB_AD[8] +set_location_assignment PIN_AB5 -to FB_AD[9] +set_location_assignment PIN_W7 -to FB_AD[10] +set_location_assignment PIN_Y7 -to FB_AD[11] +set_location_assignment PIN_U9 -to FB_AD[12] +set_location_assignment PIN_V8 -to FB_AD[13] +set_location_assignment PIN_W8 -to FB_AD[14] +set_location_assignment PIN_AA7 -to FB_AD[15] +set_location_assignment PIN_AB7 -to FB_AD[16] +set_location_assignment PIN_Y8 -to FB_AD[17] +set_location_assignment PIN_V9 -to FB_AD[18] +set_location_assignment PIN_V10 -to FB_AD[19] +set_location_assignment PIN_T10 -to FB_AD[20] +set_location_assignment PIN_U10 -to FB_AD[21] +set_location_assignment PIN_AA8 -to FB_AD[22] +set_location_assignment PIN_AB8 -to FB_AD[23] +set_location_assignment PIN_T11 -to FB_AD[24] +set_location_assignment PIN_AA9 -to FB_AD[25] +set_location_assignment PIN_AB9 -to FB_AD[26] +set_location_assignment PIN_U11 -to FB_AD[27] +set_location_assignment PIN_V11 -to FB_AD[28] +set_location_assignment PIN_W10 -to FB_AD[29] +set_location_assignment PIN_Y10 -to FB_AD[30] +set_location_assignment PIN_AA10 -to FB_AD[31] +set_location_assignment PIN_R7 -to FB_ALE +set_location_assignment PIN_N19 -to LED_FPGA_OK +set_location_assignment PIN_R5 -to TIN0 +set_location_assignment PIN_W20 -to VA[0] +set_location_assignment PIN_W22 -to VA[1] +set_location_assignment PIN_W21 -to VA[2] +set_location_assignment PIN_Y22 -to VA[3] +set_location_assignment PIN_AA22 -to VA[4] +set_location_assignment PIN_Y21 -to VA[5] +set_location_assignment PIN_AA21 -to VA[6] +set_location_assignment PIN_AA20 -to VA[7] +set_location_assignment PIN_AB20 -to VA[8] +set_location_assignment PIN_AB19 -to VA[9] +set_location_assignment PIN_V21 -to VA[10] +set_location_assignment PIN_U19 -to VA[11] +set_location_assignment PIN_AA18 -to VA[12] +set_location_assignment PIN_U15 -to VCKE +set_location_assignment PIN_M22 -to VD[0] +set_location_assignment PIN_M21 -to VD[1] +set_location_assignment PIN_P22 -to VD[2] +set_location_assignment PIN_R20 -to VD[3] +set_location_assignment PIN_P21 -to VD[4] +set_location_assignment PIN_R17 -to VD[5] +set_location_assignment PIN_R19 -to VD[6] +set_location_assignment PIN_U21 -to VD[7] +set_location_assignment PIN_V22 -to VD[8] +set_location_assignment PIN_R18 -to VD[9] +set_location_assignment PIN_P17 -to VD[10] +set_location_assignment PIN_R21 -to VD[11] +set_location_assignment PIN_N17 -to VD[12] +set_location_assignment PIN_P20 -to VD[13] +set_location_assignment PIN_R22 -to VD[14] +set_location_assignment PIN_N20 -to VD[15] +set_location_assignment PIN_T12 -to VD[16] +set_location_assignment PIN_Y13 -to VD[17] +set_location_assignment PIN_AA13 -to VD[18] +set_location_assignment PIN_V14 -to VD[19] +set_location_assignment PIN_U13 -to VD[20] +set_location_assignment PIN_V15 -to VD[21] +set_location_assignment PIN_W14 -to VD[22] +set_location_assignment PIN_AB16 -to VD[23] +set_location_assignment PIN_AB15 -to VD[24] +set_location_assignment PIN_AA14 -to VD[25] +set_location_assignment PIN_AB14 -to VD[26] +set_location_assignment PIN_V13 -to VD[27] +set_location_assignment PIN_W13 -to VD[28] +set_location_assignment PIN_AB13 -to VD[29] +set_location_assignment PIN_V12 -to VD[30] +set_location_assignment PIN_U12 -to VD[31] +set_location_assignment PIN_AA16 -to VDM[0] +set_location_assignment PIN_V16 -to VDM[1] +set_location_assignment PIN_U20 -to VDM[2] +set_location_assignment PIN_T17 -to VDM[3] +set_location_assignment PIN_G18 -to VB[0] +set_location_assignment PIN_H17 -to VB[1] +set_location_assignment PIN_C22 -to VB[2] +set_location_assignment PIN_C21 -to VB[3] +set_location_assignment PIN_B22 -to VB[4] +set_location_assignment PIN_B21 -to VB[5] +set_location_assignment PIN_C20 -to VB[6] +set_location_assignment PIN_D20 -to VB[7] +set_location_assignment PIN_H19 -to VG[0] +set_location_assignment PIN_E22 -to VG[1] +set_location_assignment PIN_E21 -to VG[2] +set_location_assignment PIN_H18 -to VG[3] +set_location_assignment PIN_J17 -to VG[4] +set_location_assignment PIN_H16 -to VG[5] +set_location_assignment PIN_D22 -to VG[6] +set_location_assignment PIN_D21 -to VG[7] +set_location_assignment PIN_J22 -to VR[0] +set_location_assignment PIN_J21 -to VR[1] +set_location_assignment PIN_H22 -to VR[2] +set_location_assignment PIN_H21 -to VR[3] +set_location_assignment PIN_K17 -to VR[4] +set_location_assignment PIN_K18 -to VR[5] +set_location_assignment PIN_J18 -to VR[6] +set_location_assignment PIN_F22 -to VR[7] +set_location_assignment PIN_M6 -to ACSI_A1 +set_location_assignment PIN_B1 -to ACSI_D[0] +set_location_assignment PIN_G5 -to ACSI_D[1] +set_location_assignment PIN_E3 -to ACSI_D[2] +set_location_assignment PIN_C2 -to ACSI_D[3] +set_location_assignment PIN_C1 -to ACSI_D[4] +set_location_assignment PIN_D2 -to ACSI_D[5] +set_location_assignment PIN_H7 -to ACSI_D[6] +set_location_assignment PIN_H6 -to ACSI_D[7] +set_location_assignment PIN_L6 -to ACSI_DIR +set_location_assignment PIN_N1 -to AMKB_TX +set_location_assignment PIN_F15 -to DSA_D +set_location_assignment PIN_D15 -to DTR +set_location_assignment PIN_A11 -to DVI_INT +set_location_assignment PIN_G21 -to E0_INT +set_location_assignment PIN_M5 -to IDE_RES +set_location_assignment PIN_F7 -to LP_D[0] +set_location_assignment PIN_C4 -to LP_D[1] +set_location_assignment PIN_C3 -to LP_D[2] +set_location_assignment PIN_E7 -to LP_D[3] +set_location_assignment PIN_D6 -to LP_D[4] +set_location_assignment PIN_B3 -to LP_D[5] +set_location_assignment PIN_A3 -to LP_D[6] +set_location_assignment PIN_G8 -to LP_D[7] +set_location_assignment PIN_E6 -to LP_STR +set_location_assignment PIN_H5 -to MIDI_OLR +set_location_assignment PIN_B2 -to MIDI_TLR +set_location_assignment PIN_AA2 -to PIC_INT +set_location_assignment PIN_B18 -to RTS +set_location_assignment PIN_J6 -to SCSI_D[0] +set_location_assignment PIN_E1 -to SCSI_D[1] +set_location_assignment PIN_F2 -to SCSI_D[2] +set_location_assignment PIN_F1 -to SCSI_D[3] +set_location_assignment PIN_G4 -to SCSI_D[4] +set_location_assignment PIN_G3 -to SCSI_D[5] +set_location_assignment PIN_L8 -to SCSI_D[6] +set_location_assignment PIN_K8 -to SCSI_D[7] +set_location_assignment PIN_J7 -to SCSI_DIR +set_location_assignment PIN_M7 -to SCSI_PAR +set_location_assignment PIN_C15 -to SD_CLK +set_location_assignment PIN_E14 -to SD_CMD_D1 +set_location_assignment PIN_A18 -to TxD +set_location_assignment PIN_A17 -to YM_QA +set_location_assignment PIN_G13 -to YM_QB +set_location_assignment PIN_E15 -to YM_QC +set_location_assignment PIN_M19 -to SD_WP +set_location_assignment PIN_H15 -to RxD +set_location_assignment PIN_B19 -to RI +set_location_assignment PIN_L7 -to PIC_AMKB_RX +set_location_assignment PIN_E12 -to MIDI_IN +set_location_assignment PIN_G7 -to LP_BUSY +set_location_assignment PIN_Y1 -to IDE_RDY +set_location_assignment PIN_G22 -to IDE_INT +set_location_assignment PIN_A19 -to DCD +set_location_assignment PIN_H14 -to CTS +set_location_assignment PIN_Y2 -to AMKB_RX +set_location_assignment PIN_W19 -to BA[0] +set_location_assignment PIN_AA19 -to BA[1] + +set_global_assignment -name FMAX_REQUIREMENT "133 MHz" -section_id fast +set_global_assignment -name ASSIGNMENT_GROUP_MEMBER DDRCLK -section_id fast +set_global_assignment -name ASSIGNMENT_GROUP_MEMBER DDRCLK[0] -section_id fast +set_global_assignment -name ASSIGNMENT_GROUP_MEMBER DDRCLK[1] -section_id fast +set_global_assignment -name ASSIGNMENT_GROUP_MEMBER DDRCLK[2] -section_id fast +set_global_assignment -name ASSIGNMENT_GROUP_MEMBER DDRCLK[3] -section_id fast +set_global_assignment -name ASSIGNMENT_GROUP_MEMBER "video:b2v_Fredi_Aschwanden|DDRCLK" -section_id fast +set_global_assignment -name ASSIGNMENT_GROUP_MEMBER "video:b2v_Fredi_Aschwanden|DDRCLK[0]" -section_id fast +set_global_assignment -name ASSIGNMENT_GROUP_MEMBER "video:b2v_Fredi_Aschwanden|DDRCLK[1]" -section_id fast +set_global_assignment -name ASSIGNMENT_GROUP_MEMBER "video:b2v_Fredi_Aschwanden|DDRCLK[2]" -section_id fast +set_global_assignment -name ASSIGNMENT_GROUP_MEMBER "video:b2v_Fredi_Aschwanden|DDRCLK[3]" -section_id fast + +set_instance_assignment -name CLOCK_SETTINGS fast -to DDRCLK +set_instance_assignment -name CLOCK_SETTINGS fast -to DDRCLK[0] +set_instance_assignment -name CLOCK_SETTINGS fast -to DDRCLK[1] +set_instance_assignment -name CLOCK_SETTINGS fast -to DDRCLK[2] +set_instance_assignment -name CLOCK_SETTINGS fast -to DDRCLK[3] +set_instance_assignment -name CLOCK_SETTINGS fast -to "video:b2v_Fredi_Aschwanden|DDRCLK" +set_instance_assignment -name CLOCK_SETTINGS fast -to "video:b2v_Fredi_Aschwanden|DDRCLK[0]" +set_instance_assignment -name CLOCK_SETTINGS fast -to "video:b2v_Fredi_Aschwanden|DDRCLK[1]" +set_instance_assignment -name CLOCK_SETTINGS fast -to "video:b2v_Fredi_Aschwanden|DDRCLK[2]" +set_instance_assignment -name CLOCK_SETTINGS fast -to "video:b2v_Fredi_Aschwanden|DDRCLK[3]" +set_instance_assignment -name INPUT_MAX_DELAY "4 ns" -from * -to FB_ALE +set_instance_assignment -name MAX_DELAY "5 ns" -from VD -to FB_AD +set_instance_assignment -name MAX_DELAY "5 ns" -from FB_AD -to VA +set_instance_assignment -name MAX_DELAY "5 ns" -from FB_AD -to nVRAS +set_instance_assignment -name MAX_DELAY "5 ns" -from FB_AD -to BA +set_instance_assignment -name IO_STANDARD "2.5 V" -to VA +set_instance_assignment -name IO_STANDARD "2.5 V" -to VD +set_instance_assignment -name IO_STANDARD "2.5 V" -to VDM +set_instance_assignment -name IO_STANDARD "2.5 V" -to VCKE +set_instance_assignment -name IO_STANDARD "2.5 V" -to LED_FPGA_OK +set_instance_assignment -name IO_STANDARD "2.5 V" -to BA +set_instance_assignment -name IO_STANDARD "3.0-V LVTTL" -to VB +set_instance_assignment -name IO_STANDARD "3.0-V LVTTL" -to VG +set_instance_assignment -name IO_STANDARD "3.0-V LVTTL" -to VR +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to LED_FPGA_OK +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VCKE +set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to FB_AD +set_instance_assignment -name CURRENT_STRENGTH_NEW 12MA -to BA +set_instance_assignment -name CURRENT_STRENGTH_NEW 12MA -to VA +set_instance_assignment -name CURRENT_STRENGTH_NEW 12MA -to VD +set_instance_assignment -name CURRENT_STRENGTH_NEW 12MA -to VDM +set_instance_assignment -name CURRENT_STRENGTH_NEW 16MA -to VB +set_instance_assignment -name CURRENT_STRENGTH_NEW 16MA -to VG +set_instance_assignment -name CURRENT_STRENGTH_NEW 16MA -to VR +set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to AMKB_TX +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VA[0] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VA[1] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VA[2] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VA[3] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VA[4] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VA[5] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VA[6] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VA[7] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VA[8] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VA[9] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VA[10] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VA[11] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VA[12] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to BA[0] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to BA[1] +set_instance_assignment -name CURRENT_STRENGTH_NEW 12MA -to VDM[0] +set_instance_assignment -name CURRENT_STRENGTH_NEW 12MA -to VDM[1] +set_instance_assignment -name CURRENT_STRENGTH_NEW 12MA -to VDM[2] +set_instance_assignment -name CURRENT_STRENGTH_NEW 12MA -to VDM[3] +set_instance_assignment -name CURRENT_STRENGTH_NEW 12MA -to VD[0] +set_instance_assignment -name CURRENT_STRENGTH_NEW 12MA -to VD[1] +set_instance_assignment -name CURRENT_STRENGTH_NEW 12MA -to VD[2] +set_instance_assignment -name CURRENT_STRENGTH_NEW 12MA -to VD[3] +set_instance_assignment -name CURRENT_STRENGTH_NEW 12MA -to VD[4] +set_instance_assignment -name CURRENT_STRENGTH_NEW 12MA -to VD[5] +set_instance_assignment -name CURRENT_STRENGTH_NEW 12MA -to VD[6] +set_instance_assignment -name CURRENT_STRENGTH_NEW 12MA -to VD[7] +set_instance_assignment -name CURRENT_STRENGTH_NEW 12MA -to VD[8] +set_instance_assignment -name CURRENT_STRENGTH_NEW 12MA -to VD[9] +set_instance_assignment -name CURRENT_STRENGTH_NEW 12MA -to VD[10] +set_instance_assignment -name CURRENT_STRENGTH_NEW 12MA -to VD[11] +set_instance_assignment -name CURRENT_STRENGTH_NEW 12MA -to VD[12] +set_instance_assignment -name CURRENT_STRENGTH_NEW 12MA -to VD[13] +set_instance_assignment -name CURRENT_STRENGTH_NEW 12MA -to VD[14] +set_instance_assignment -name CURRENT_STRENGTH_NEW 12MA -to VD[15] +set_instance_assignment -name CURRENT_STRENGTH_NEW 12MA -to VD[16] +set_instance_assignment -name CURRENT_STRENGTH_NEW 12MA -to VD[17] +set_instance_assignment -name CURRENT_STRENGTH_NEW 12MA -to VD[18] +set_instance_assignment -name CURRENT_STRENGTH_NEW 12MA -to VD[19] +set_instance_assignment -name CURRENT_STRENGTH_NEW 12MA -to VD[20] +set_instance_assignment -name CURRENT_STRENGTH_NEW 12MA -to VD[21] +set_instance_assignment -name CURRENT_STRENGTH_NEW 12MA -to VD[22] +set_instance_assignment -name CURRENT_STRENGTH_NEW 12MA -to VD[23] +set_instance_assignment -name CURRENT_STRENGTH_NEW 12MA -to VD[24] +set_instance_assignment -name CURRENT_STRENGTH_NEW 12MA -to VD[25] +set_instance_assignment -name CURRENT_STRENGTH_NEW 12MA -to VD[26] +set_instance_assignment -name CURRENT_STRENGTH_NEW 12MA -to VD[27] +set_instance_assignment -name CURRENT_STRENGTH_NEW 12MA -to VD[28] +set_instance_assignment -name CURRENT_STRENGTH_NEW 12MA -to VD[29] +set_instance_assignment -name CURRENT_STRENGTH_NEW 12MA -to VD[30] +set_instance_assignment -name CURRENT_STRENGTH_NEW 12MA -to VD[31] +set_instance_assignment -name OUTPUT_ENABLE_GROUP 1077756020 -to VDM[0] +set_instance_assignment -name OUTPUT_ENABLE_GROUP 1077756020 -to VDM[1] +set_instance_assignment -name OUTPUT_ENABLE_GROUP 1077756020 -to VDM[2] +set_instance_assignment -name OUTPUT_ENABLE_GROUP 1077756020 -to VDM[3] +set_instance_assignment -name OUTPUT_ENABLE_GROUP 1077756020 -to VD[0] +set_instance_assignment -name OUTPUT_ENABLE_GROUP 1077756020 -to VD[1] +set_instance_assignment -name OUTPUT_ENABLE_GROUP 1077756020 -to VD[2] +set_instance_assignment -name OUTPUT_ENABLE_GROUP 1077756020 -to VD[3] +set_instance_assignment -name OUTPUT_ENABLE_GROUP 1077756020 -to VD[4] +set_instance_assignment -name OUTPUT_ENABLE_GROUP 1077756020 -to VD[5] +set_instance_assignment -name OUTPUT_ENABLE_GROUP 1077756020 -to VD[6] +set_instance_assignment -name OUTPUT_ENABLE_GROUP 1077756020 -to VD[7] +set_instance_assignment -name OUTPUT_ENABLE_GROUP 1077756020 -to VD[8] +set_instance_assignment -name OUTPUT_ENABLE_GROUP 1077756020 -to VD[9] +set_instance_assignment -name OUTPUT_ENABLE_GROUP 1077756020 -to VD[10] +set_instance_assignment -name OUTPUT_ENABLE_GROUP 1077756020 -to VD[11] +set_instance_assignment -name OUTPUT_ENABLE_GROUP 1077756020 -to VD[12] +set_instance_assignment -name OUTPUT_ENABLE_GROUP 1077756020 -to VD[13] +set_instance_assignment -name OUTPUT_ENABLE_GROUP 1077756020 -to VD[14] +set_instance_assignment -name OUTPUT_ENABLE_GROUP 1077756020 -to VD[15] +set_instance_assignment -name OUTPUT_ENABLE_GROUP 1077756020 -to VD[16] +set_instance_assignment -name OUTPUT_ENABLE_GROUP 1077756020 -to VD[17] +set_instance_assignment -name OUTPUT_ENABLE_GROUP 1077756020 -to VD[18] +set_instance_assignment -name OUTPUT_ENABLE_GROUP 1077756020 -to VD[19] +set_instance_assignment -name OUTPUT_ENABLE_GROUP 1077756020 -to VD[20] +set_instance_assignment -name OUTPUT_ENABLE_GROUP 1077756020 -to VD[21] +set_instance_assignment -name OUTPUT_ENABLE_GROUP 1077756020 -to VD[22] +set_instance_assignment -name OUTPUT_ENABLE_GROUP 1077756020 -to VD[23] +set_instance_assignment -name OUTPUT_ENABLE_GROUP 1077756020 -to VD[24] +set_instance_assignment -name OUTPUT_ENABLE_GROUP 1077756020 -to VD[25] +set_instance_assignment -name OUTPUT_ENABLE_GROUP 1077756020 -to VD[26] +set_instance_assignment -name OUTPUT_ENABLE_GROUP 1077756020 -to VD[27] +set_instance_assignment -name OUTPUT_ENABLE_GROUP 1077756020 -to VD[28] +set_instance_assignment -name OUTPUT_ENABLE_GROUP 1077756020 -to VD[29] +set_instance_assignment -name OUTPUT_ENABLE_GROUP 1077756020 -to VD[30] +set_instance_assignment -name OUTPUT_ENABLE_GROUP 1077756020 -to VD[31] +set_instance_assignment -name PASSIVE_RESISTOR "PULL-UP" -to FB_AD +set_instance_assignment -name PASSIVE_RESISTOR "PULL-UP" -to SD_WP +set_instance_assignment -name PASSIVE_RESISTOR "PULL-UP" -to SD_CMD_D1 +set_instance_assignment -name PASSIVE_RESISTOR "PULL-UP" -to SD_CLK +set_global_assignment -name SYNCHRONIZER_IDENTIFICATION AUTO +set_global_assignment -name TIMEQUEST_DO_CCPP_REMOVAL ON +set_global_assignment -name ENABLE_DRC_SETTINGS ON +set_global_assignment -name ENABLE_SIGNALTAP OFF + +set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC ON +set_global_assignment -name PHYSICAL_SYNTHESIS_MAP_LOGIC_TO_MEMORY_FOR_AREA ON +set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS ON +set_global_assignment -name MUX_RESTRUCTURE ON +set_global_assignment -name STATE_MACHINE_PROCESSING "MINIMAL BITS" +set_global_assignment -name AUTO_SHIFT_REGISTER_RECOGNITION OFF +set_global_assignment -name ALLOW_SHIFT_REGISTER_MERGING_ACROSS_HIERARCHIES ALWAYS +set_global_assignment -name AUTO_DSP_RECOGNITION ON +set_global_assignment -name FITTER_EFFORT "AUTO FIT" +set_global_assignment -name PLACEMENT_EFFORT_MULTIPLIER 2.5 +set_global_assignment -name ROUTER_CLOCKING_TOPOLOGY_ANALYSIS ON +set_global_assignment -name FITTER_AGGRESSIVE_ROUTABILITY_OPTIMIZATION ALWAYS +set_global_assignment -name OPTIMIZE_POWER_DURING_FITTING OFF +set_global_assignment -name EDA_TIME_SCALE "1 ps" -section_id eda_simulation +set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS ON +set_global_assignment -name SMART_RECOMPILE ON +set_global_assignment -name ADV_NETLIST_OPT_SYNTH_WYSIWYG_REMAP ON +set_global_assignment -name REMOVE_REDUNDANT_LOGIC_CELLS ON +set_global_assignment -name ALLOW_ANY_ROM_SIZE_FOR_RECOGNITION ON +set_global_assignment -name ALLOW_ANY_RAM_SIZE_FOR_RECOGNITION ON +set_global_assignment -name ALLOW_ANY_SHIFT_REGISTER_SIZE_FOR_RECOGNITION ON +set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC_FOR_AREA ON +set_global_assignment -name AUTO_RAM_RECOGNITION OFF +set_global_assignment -name VHDL_INPUT_VERSION VHDL_2008 +set_global_assignment -name VHDL_SHOW_LMF_MAPPING_MESSAGES OFF +set_location_assignment PIN_AB12 -to CLK_33M +set_location_assignment PIN_G2 -to CLK_MAIN +set_location_assignment PIN_AB10 -to CLK_24M576 +set_location_assignment PIN_J1 -to CLK_USB +set_location_assignment PIN_T4 -to CLK_25M +set_location_assignment PIN_U8 -to FB_SIZE[0] +set_location_assignment PIN_Y4 -to FB_SIZE[1] +set_location_assignment PIN_T3 -to FB_BURSTn +set_location_assignment PIN_T8 -to FB_CSn[1] +set_location_assignment PIN_T9 -to FB_CSn[2] +set_location_assignment PIN_V6 -to FB_CSn[3] +set_location_assignment PIN_R6 -to FB_OEn +set_location_assignment PIN_G14 -to FB_WRn +set_location_assignment PIN_T21 -to MASTERn +set_location_assignment PIN_E11 -to DREQ1n +set_location_assignment PIN_A12 -to DACK1n +set_location_assignment PIN_B12 -to DACK0n +set_location_assignment PIN_T22 -to TOUT0n +set_location_assignment PIN_AA17 -to CLK_DDR_OUT +set_location_assignment PIN_AB17 -to CLK_DDR_OUTn +set_location_assignment PIN_AB18 -to VCASn +set_location_assignment PIN_T18 -to VCSn +set_location_assignment PIN_W17 -to VRASn +set_location_assignment PIN_Y17 -to VWEn +set_location_assignment PIN_AA15 -to VD_QS[0] +set_location_assignment PIN_W15 -to VD_QS[1] +set_location_assignment PIN_U22 -to VD_QS[2] +set_location_assignment PIN_T16 -to VD_QS[3] +set_location_assignment PIN_V1 -to PD_VGAn +set_location_assignment PIN_A8 -to DSP_IO[0] +set_location_assignment PIN_A7 -to DSP_IO[1] +set_location_assignment PIN_B7 -to DSP_IO[2] +set_location_assignment PIN_A6 -to DSP_IO[3] +set_location_assignment PIN_B6 -to DSP_IO[4] +set_location_assignment PIN_E9 -to DSP_IO[5] +set_location_assignment PIN_C8 -to DSP_IO[6] +set_location_assignment PIN_C7 -to DSP_IO[7] +set_location_assignment PIN_G10 -to DSP_IO[8] +set_location_assignment PIN_A15 -to DSP_IO[9] +set_location_assignment PIN_B15 -to DSP_IO[10] +set_location_assignment PIN_C13 -to DSP_IO[11] +set_location_assignment PIN_D13 -to DSP_IO[12] +set_location_assignment PIN_E13 -to DSP_IO[13] +set_location_assignment PIN_A14 -to DSP_IO[14] +set_location_assignment PIN_B14 -to DSP_IO[15] +set_location_assignment PIN_A13 -to DSP_IO[16] +set_location_assignment PIN_B13 -to DSP_IO[17] +set_location_assignment PIN_M4 -to ACSI_ACKn +set_location_assignment PIN_M2 -to ACSI_CSn +set_location_assignment PIN_M1 -to ACSI_RESETn +set_location_assignment PIN_W2 -to CF_CSn[0] +set_location_assignment PIN_W1 -to CF_CSn[1] +set_location_assignment PIN_T7 -to FB_TAn +set_location_assignment PIN_R2 -to IDE_CSn[0] +set_location_assignment PIN_R1 -to IDE_CSn[1] +set_location_assignment PIN_P1 -to IDE_RDn +set_location_assignment PIN_P2 -to IDE_WRn +set_location_assignment PIN_F21 -to IRQn[2] +set_location_assignment PIN_H20 -to IRQn[3] +set_location_assignment PIN_F20 -to IRQn[4] +set_location_assignment PIN_P5 -to IRQn[5] +set_location_assignment PIN_P7 -to IRQn[6] +set_location_assignment PIN_N7 -to IRQn[7] +set_location_assignment PIN_AA1 -to PCI_INTAn +set_location_assignment PIN_V4 -to PCI_INTBn +set_location_assignment PIN_V3 -to PCI_INTCn +set_location_assignment PIN_P6 -to PCI_INTDn +set_location_assignment PIN_P3 -to ROM3n +set_location_assignment PIN_U2 -to ROM4n +set_location_assignment PIN_N5 -to RP_LDSn +set_location_assignment PIN_P4 -to RP_UDSn +set_location_assignment PIN_N2 -to SCSI_ACKn +set_location_assignment PIN_M3 -to SCSI_ATNn +set_location_assignment PIN_N8 -to SCSI_BUSYn +set_location_assignment PIN_N6 -to SCSI_RSTn +set_location_assignment PIN_M8 -to SCSI_SELn +set_location_assignment PIN_B20 -to FDD_SDSELn +set_location_assignment PIN_B4 -to DSP_SRBHEn +set_location_assignment PIN_A4 -to DSP_SRBLEn +set_location_assignment PIN_B8 -to DSP_SRCSn +set_location_assignment PIN_F11 -to DSP_SROEn +set_location_assignment PIN_F8 -to DSP_SRWEn +set_location_assignment PIN_D17 -to FDD_WR_GATE +set_instance_assignment -name CURRENT_STRENGTH_NEW 12MA -to VD_QS[0] +set_instance_assignment -name CURRENT_STRENGTH_NEW 12MA -to VD_QS[1] +set_instance_assignment -name CURRENT_STRENGTH_NEW 12MA -to VD_QS[2] +set_instance_assignment -name CURRENT_STRENGTH_NEW 12MA -to VD_QS[3] +set_instance_assignment -name OUTPUT_ENABLE_GROUP 1077756020 -to VD_QS[0] +set_instance_assignment -name OUTPUT_ENABLE_GROUP 1077756020 -to VD_QS[1] +set_instance_assignment -name OUTPUT_ENABLE_GROUP 1077756020 -to VD_QS[2] +set_instance_assignment -name OUTPUT_ENABLE_GROUP 1077756020 -to VD_QS[3] +set_instance_assignment -name CKN_CK_PAIR ON -from CLK_DDR_OUTn -to CLK_DDR_OUT +set_instance_assignment -name PASSIVE_RESISTOR "PULL-UP" -to ACSI_DRQn +set_instance_assignment -name PASSIVE_RESISTOR "PULL-UP" -to ACSI_INTn +set_instance_assignment -name PASSIVE_RESISTOR "PULL-UP" -to SD_CARD_DETECT +set_instance_assignment -name PASSIVE_RESISTOR "PULL-UP" -to SD_D2 +set_instance_assignment -name PASSIVE_RESISTOR "PULL-UP" -to SD_D1 +set_instance_assignment -name PASSIVE_RESISTOR "PULL-UP" -to SD_D0 +set_instance_assignment -name PASSIVE_RESISTOR "PULL-UP" -to SD_D3 +set_location_assignment PIN_J4 -to ACSI_INTn +set_location_assignment PIN_K7 -to ACSI_DRQn +set_location_assignment PIN_F16 -to FDD_HD_DD +set_location_assignment PIN_E16 -to FDD_INDEXn +set_location_assignment PIN_K21 -to HSYNC +set_location_assignment PIN_K19 -to VSYNC +set_location_assignment PIN_G17 -to BLANKn +set_location_assignment PIN_F19 -to CLK_PIXEL +set_location_assignment PIN_F17 -to SYNCn +set_location_assignment PIN_G15 -to FDD_STEP_DIR +set_location_assignment PIN_F14 -to FDD_STEP +set_location_assignment PIN_G16 -to FDD_MOT_ON +set_location_assignment PIN_E5 -to LP_DIR +set_location_assignment PIN_B11 -to RSTO_MCFn +set_instance_assignment -name IO_STANDARD "2.5 V" -to VD_QS +set_instance_assignment -name IO_STANDARD "2.5 V" -to VWEn +set_instance_assignment -name IO_STANDARD "2.5 V" -to VRASn +set_instance_assignment -name IO_STANDARD "2.5 V" -to VCSn +set_instance_assignment -name IO_STANDARD "2.5 V" -to VCASn +set_instance_assignment -name IO_STANDARD "3.0-V LVTTL" -to HSYNC +set_instance_assignment -name IO_STANDARD "3.0-V LVTTL" -to CLK_PIXEL +set_instance_assignment -name IO_STANDARD "3.0-V LVTTL" -to VSYNC +set_instance_assignment -name IO_STANDARD "3.0-V LVTTL" -to BLANKn +set_instance_assignment -name IO_STANDARD "3.0-V LVCMOS" -to SYNCn +set_instance_assignment -name IO_STANDARD "3.0-V LVCMOS" -to IRQn[2] +set_instance_assignment -name IO_STANDARD "3.0-V LVCMOS" -to IRQn[3] +set_instance_assignment -name IO_STANDARD "3.0-V LVCMOS" -to IRQn[4] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VCSn +set_instance_assignment -name CURRENT_STRENGTH_NEW 12MA -to VD_QS +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VWEn +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VRASn +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VCASn +set_instance_assignment -name CURRENT_STRENGTH_NEW 16MA -to HSYNC +set_instance_assignment -name CURRENT_STRENGTH_NEW 16MA -to CLK_PIXEL +set_instance_assignment -name CURRENT_STRENGTH_NEW 16MA -to BLANKn +set_instance_assignment -name CURRENT_STRENGTH_NEW 16MA -to VSYNC +set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to PD_VGAn +set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to SYNCn +set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to DSP_SRD +set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to DSP_IO +set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to DSP_SRWEn +set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to DSP_SROEn +set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to DSP_SRCSn +set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to DSP_SRBLEn +set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to DSP_SRBHEn +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to CLK_24M576 +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to CLK_USB +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to CLK_25M +set_location_assignment PIN_F13 -to SD_D3 +set_location_assignment PIN_A5 -to DSP_SRD[1] +set_location_assignment PIN_C6 -to DSP_SRD[2] +set_location_assignment PIN_G11 -to DSP_SRD[3] +set_location_assignment PIN_C10 -to DSP_SRD[4] +set_location_assignment PIN_F9 -to DSP_SRD[5] +set_location_assignment PIN_E10 -to DSP_SRD[6] +set_location_assignment PIN_H11 -to DSP_SRD[7] +set_location_assignment PIN_B9 -to DSP_SRD[8] +set_location_assignment PIN_A10 -to DSP_SRD[9] +set_location_assignment PIN_A9 -to DSP_SRD[10] +set_location_assignment PIN_B10 -to DSP_SRD[11] +set_location_assignment PIN_D10 -to DSP_SRD[12] +set_location_assignment PIN_F10 -to DSP_SRD[13] +set_location_assignment PIN_G9 -to DSP_SRD[14] +set_location_assignment PIN_H10 -to DSP_SRD[15] +set_location_assignment PIN_B17 -to SD_D2 +set_location_assignment PIN_A16 -to SD_D1 +set_location_assignment PIN_B16 -to SD_D0 +set_location_assignment PIN_M20 -to SD_CARD_DETECT +set_location_assignment PIN_A20 -to FDD_RDn +set_location_assignment PIN_B5 -to DSP_SRD[0] +set_location_assignment PIN_T1 -to CF_WP +set_location_assignment PIN_C19 -to FDD_TRACK00 +set_location_assignment PIN_C17 -to FDD_DCHGn +set_location_assignment PIN_D19 -to FDD_WPn +set_location_assignment PIN_H2 -to SCSI_MSGn +set_location_assignment PIN_J3 -to SCSI_IOn +set_location_assignment PIN_U1 -to SCSI_DRQn +set_location_assignment PIN_H1 -to SCSI_CDn +set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_DUPLICATION ON +set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_RETIMING ON +set_global_assignment -name ROUTER_LCELL_INSERTION_AND_LOGIC_DUPLICATION ON +set_global_assignment -name ROUTER_TIMING_OPTIMIZATION_LEVEL MAXIMUM +set_global_assignment -name AUTO_PACKED_REGISTERS_STRATIXII NORMAL + +set_global_assignment -name EDA_TEST_BENCH_NAME ddr_ctlr_tb -section_id eda_simulation +set_global_assignment -name EDA_DESIGN_INSTANCE_NAME NA -section_id ddr_ctlr_tb +set_global_assignment -name EDA_TEST_BENCH_RUN_SIM_FOR "1 us" -section_id ddr_ctlr_tb +set_global_assignment -name EDA_TEST_BENCH_MODULE_NAME ddr_ctlr_tb -section_id ddr_ctlr_tb +set_global_assignment -name EDA_TEST_BENCH_FILE ../../../testbenches/ddr_ctlr_tb.vhd -section_id ddr_ctlr_tb +set_instance_assignment -name AUTO_GLOBAL_CLOCK ON -to "altpll1:I_PLL1|altpll:altpll_component|clk[1]" +set_instance_assignment -name AUTO_GLOBAL_CLOCK ON -to "altpll1:I_PLL1|altpll:altpll_component|clk[2]" +set_instance_assignment -name AUTO_GLOBAL_CLOCK ON -to "altpll1:I_PLL1|altpll:altpll_component|clk[3]" +set_instance_assignment -name AUTO_GLOBAL_CLOCK ON -to "altpll2:I_PLL2|altpll:altpll_component|clk[0]" +set_instance_assignment -name AUTO_GLOBAL_CLOCK ON -to "altpll2:I_PLL2|altpll:altpll_component|clk[1]" +set_instance_assignment -name AUTO_GLOBAL_CLOCK ON -to "altpll2:I_PLL2|altpll:altpll_component|clk[2]" +set_instance_assignment -name AUTO_GLOBAL_CLOCK ON -to "altpll2:I_PLL2|altpll:altpll_component|clk[3]" +set_instance_assignment -name AUTO_GLOBAL_CLOCK ON -to "altpll3:I_PLL3|altpll:altpll_component|clk[0]" +set_instance_assignment -name AUTO_GLOBAL_CLOCK ON -to "altpll3:I_PLL3|altpll:altpll_component|clk[1]" +set_instance_assignment -name AUTO_GLOBAL_CLOCK ON -to "altpll3:I_PLL3|altpll:altpll_component|clk[2]" +set_instance_assignment -name AUTO_GLOBAL_CLOCK ON -to "altpll3:I_PLL3|altpll:altpll_component|clk[3]" +set_instance_assignment -name AUTO_GLOBAL_CLOCK ON -to "altpll4:I_PLL4|altpll:altpll_component|clk[0]" +set_instance_assignment -name AUTO_GLOBAL_CLOCK ON -to "altpll4:I_PLL4|altpll:altpll_component|clk[1]" +set_instance_assignment -name AUTO_GLOBAL_CLOCK ON -to "altpll4:I_PLL4|altpll:altpll_component|clk[2]" +set_instance_assignment -name AUTO_GLOBAL_CLOCK ON -to "altpll4:I_PLL4|altpll:altpll_component|clk[3]" +set_instance_assignment -name AUTO_GLOBAL_CLOCK ON -to "altpll1:I_PLL1|altpll:altpll_component|clk[0]" +set_global_assignment -name SDC_FILE firebee.sdc +set_global_assignment -name SOURCE_FILE firebee.qsf +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/Firebee_V1/Firebee_V1_Top.vhd +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/DDR/DDR_CTRL.vhd +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/Video/Video_Top.vhd +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/RTC/rtc.vhd +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/WF5380/wf5380_top.vhd +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/WF5380/wf5380_soc_top.vhd +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/WF5380/wf5380_registers.vhd +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/WF5380/wf5380_pkg.vhd +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/WF5380/wf5380_control.vhd +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/WF_MFP68901_IP/wf68901ip_usart_tx.vhd +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/WF_MFP68901_IP/wf68901ip_usart_top.vhd +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/WF_MFP68901_IP/wf68901ip_usart_rx.vhd +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/WF_MFP68901_IP/wf68901ip_usart_ctrl.vhd +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/WF_MFP68901_IP/wf68901ip_top_soc.vhd +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/WF_MFP68901_IP/wf68901ip_top.vhd +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/WF_MFP68901_IP/wf68901ip_timers.vhd +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/WF_MFP68901_IP/wf68901ip_pkg.vhd +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/WF_MFP68901_IP/wf68901ip_interrupts.vhd +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/WF_MFP68901_IP/wf68901ip_gpio.vhd +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/WF_UART6850_IP/wf6850ip_transmit.vhd +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/WF_UART6850_IP/wf6850ip_top_soc.vhd +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/WF_UART6850_IP/wf6850ip_top.vhd +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/WF_UART6850_IP/wf6850ip_receive.vhd +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/WF_UART6850_IP/wf6850ip_ctrl_status.vhd +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/WF_FDC1772_IP/wf1772ip_transceiver.vhd +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/WF_FDC1772_IP/wf1772ip_top_soc.vhd +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/WF_FDC1772_IP/wf1772ip_top.vhd +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/WF_FDC1772_IP/wf1772ip_registers.vhd +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/WF_FDC1772_IP/wf1772ip_pkg.vhd +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/WF_FDC1772_IP/wf1772ip_digital_pll.vhd +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/WF_FDC1772_IP/wf1772ip_crc_logic.vhd +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/WF_FDC1772_IP/wf1772ip_control.vhd +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/WF_FDC1772_IP/wf1772ip_am_detector.vhd +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/WF_SND2149_IP/wf2149ip_wave.vhd +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/WF_SND2149_IP/wf2149ip_top_soc.vhd +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/WF_SND2149_IP/wf2149ip_top.vhd +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/WF_SND2149_IP/wf2149ip_pkg.vhd +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/DSP/DSP.vhd +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/Peripherals/ide_cf_sd_rom.vhd +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/DMA/fbee_dma.vhd +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/Blitter/Blitter_WF.vhd +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/Interrupt/interrupt.vhd +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/Video/VIDEO_CTRL.vhd +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/DMA/dcfifo1.vhd +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/DMA/dcfifo0.vhd +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/Video/lpm_fifoDZ.vhd +set_global_assignment -name SOURCE_FILE ../../../rtl/vhdl/Video/lpm_fifoDZ.cmp +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/Video/lpm_fifo_dc0.vhd +set_global_assignment -name SOURCE_FILE ../../../rtl/vhdl/Video/lpm_fifo_dc0.cmp +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/Firebee_V1/altpll_reconfig1.vhd +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/Firebee_V1/altpll4.vhd +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/Firebee_V1/altpll3.vhd +set_global_assignment -name SOURCE_FILE ../../../rtl/vhdl/Firebee_V1/altpll3.cmp +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/Firebee_V1/altpll2.vhd +set_global_assignment -name SOURCE_FILE ../../../rtl/vhdl/Firebee_V1/altpll2.cmp +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/Firebee_V1/altpll1.vhd +set_global_assignment -name SOURCE_FILE ../../../rtl/vhdl/Firebee_V1/altpll1.cmp +set_global_assignment -name VHDL_FILE ../../../rtl/vhdl/Firebee_V1/Firebee_V1_pkg.vhd +set_global_assignment -name QIP_FILE ../../../rtl/vhdl/Firebee_V1/altpll_reconfig1.qip +set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/vhdl/backend/Altera/Firebee/firebee.sdc b/vhdl/backend/Altera/Firebee/firebee.sdc new file mode 100755 index 0000000..4f42583 --- /dev/null +++ b/vhdl/backend/Altera/Firebee/firebee.sdc @@ -0,0 +1,868 @@ +## Generated SDC file "firebee.sdc" + +## Copyright (C) 1991-2013 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. + + +## VENDOR "Altera" +## PROGRAM "Quartus II" +## VERSION "Version 13.1.0 Build 162 10/23/2013 SJ Web Edition" + +## DATE "Mon Jun 9 15:23:23 2014" + +## +## DEVICE "EP3C40F484C6" +## + + +#************************************************************** +# Time Information +#************************************************************** + +set_time_format -unit ns -decimal_places 3 + + + +#************************************************************** +# Create Clock +#************************************************************** + +create_clock -name {CLK_MAIN} -period 30.303 -waveform { 0.000 15.151 } [get_ports {CLK_MAIN}] +create_clock -name {CLK_33M} -period 30.303 -waveform { 0.000 15.151 } [get_ports {CLK_33M}] + + +#************************************************************** +# Create Generated Clock +#************************************************************** + +create_generated_clock -name {altpll1:I_PLL1|altpll:altpll_component|altpll_dnn2:auto_generated|clk[0]} -source [get_pins {I_PLL1|altpll_component|auto_generated|pll1|inclk[0]}] -duty_cycle 50.000 -multiply_by 16 -divide_by 215 -master_clock {CLK_MAIN} [get_pins {I_PLL1|altpll_component|auto_generated|pll1|clk[0]}] +create_generated_clock -name {altpll1:I_PLL1|altpll:altpll_component|altpll_dnn2:auto_generated|clk[1]} -source [get_pins {I_PLL1|altpll_component|auto_generated|pll1|inclk[0]}] -duty_cycle 50.000 -multiply_by 32 -divide_by 43 -master_clock {CLK_MAIN} [get_pins {I_PLL1|altpll_component|auto_generated|pll1|clk[1]}] +create_generated_clock -name {altpll1:I_PLL1|altpll:altpll_component|altpll_dnn2:auto_generated|clk[2]} -source [get_pins {I_PLL1|altpll_component|auto_generated|pll1|inclk[0]}] -duty_cycle 50.000 -multiply_by 16 -divide_by 11 -master_clock {CLK_MAIN} [get_pins {I_PLL1|altpll_component|auto_generated|pll1|clk[2]}] +create_generated_clock -name {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[0]} -source [get_pins {I_PLL3|altpll_component|auto_generated|pll1|inclk[0]}] -duty_cycle 50.000 -multiply_by 97 -divide_by 1600 -master_clock {CLK_MAIN} [get_pins {I_PLL3|altpll_component|auto_generated|pll1|clk[0]}] +create_generated_clock -name {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[1]} -source [get_pins {I_PLL3|altpll_component|auto_generated|pll1|inclk[0]}] -duty_cycle 50.000 -multiply_by 97 -divide_by 200 -master_clock {CLK_MAIN} [get_pins {I_PLL3|altpll_component|auto_generated|pll1|clk[1]}] +create_generated_clock -name {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]} -source [get_pins {I_PLL3|altpll_component|auto_generated|pll1|inclk[0]}] -duty_cycle 50.000 -multiply_by 97 -divide_by 128 -master_clock {CLK_MAIN} [get_pins {I_PLL3|altpll_component|auto_generated|pll1|clk[2]}] +create_generated_clock -name {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[3]} -source [get_pins {I_PLL3|altpll_component|auto_generated|pll1|inclk[0]}] -duty_cycle 50.000 -multiply_by 97 -divide_by 6416 -master_clock {CLK_MAIN} [get_pins {I_PLL3|altpll_component|auto_generated|pll1|clk[3]}] +create_generated_clock -name {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]} -source [get_pins {I_PLL2|altpll_component|auto_generated|pll1|inclk[0]}] -duty_cycle 50.000 -multiply_by 4 -phase 240.000 -master_clock {CLK_MAIN} [get_pins {I_PLL2|altpll_component|auto_generated|pll1|clk[0]}] +create_generated_clock -name {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[1]} -source [get_pins {I_PLL2|altpll_component|auto_generated|pll1|inclk[0]}] -duty_cycle 50.000 -multiply_by 4 -master_clock {CLK_MAIN} [get_pins {I_PLL2|altpll_component|auto_generated|pll1|clk[1]}] +create_generated_clock -name {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[2]} -source [get_pins {I_PLL2|altpll_component|auto_generated|pll1|inclk[0]}] -duty_cycle 50.000 -multiply_by 4 -phase 180.000 -master_clock {CLK_MAIN} [get_pins {I_PLL2|altpll_component|auto_generated|pll1|clk[2]}] +create_generated_clock -name {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[3]} -source [get_pins {I_PLL2|altpll_component|auto_generated|pll1|inclk[0]}] -duty_cycle 50.000 -multiply_by 4 -phase 105.000 -master_clock {CLK_MAIN} [get_pins {I_PLL2|altpll_component|auto_generated|pll1|clk[3]}] +create_generated_clock -name {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]} -source [get_pins {I_PLL2|altpll_component|auto_generated|pll1|inclk[0]}] -duty_cycle 50.000 -multiply_by 2 -phase 270.000 -master_clock {CLK_MAIN} [get_pins {I_PLL2|altpll_component|auto_generated|pll1|clk[4]}] +create_generated_clock -name {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]} -source [get_pins {I_PLL4|altpll_component|auto_generated|pll1|inclk[0]}] -duty_cycle 50.000 -multiply_by 32 -divide_by 11 -master_clock {CLK_MAIN} [get_pins {I_PLL4|altpll_component|auto_generated|pll1|clk[0]}] + + +#************************************************************** +# Set Clock Latency +#************************************************************** + + + +#************************************************************** +# Set Clock Uncertainty +#************************************************************** + +set_clock_uncertainty -rise_from [get_clocks {CLK_33M}] -rise_to [get_clocks {CLK_33M}] 0.020 +set_clock_uncertainty -rise_from [get_clocks {CLK_33M}] -fall_to [get_clocks {CLK_33M}] 0.020 +set_clock_uncertainty -rise_from [get_clocks {CLK_33M}] -rise_to [get_clocks {CLK_MAIN}] 0.040 +set_clock_uncertainty -rise_from [get_clocks {CLK_33M}] -fall_to [get_clocks {CLK_MAIN}] 0.040 +set_clock_uncertainty -rise_from [get_clocks {CLK_33M}] -rise_to [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] -setup 0.090 +set_clock_uncertainty -rise_from [get_clocks {CLK_33M}] -rise_to [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] -hold 0.110 +set_clock_uncertainty -rise_from [get_clocks {CLK_33M}] -fall_to [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] -setup 0.090 +set_clock_uncertainty -rise_from [get_clocks {CLK_33M}] -fall_to [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] -hold 0.110 +set_clock_uncertainty -rise_from [get_clocks {CLK_33M}] -rise_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] -setup 0.090 +set_clock_uncertainty -rise_from [get_clocks {CLK_33M}] -rise_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] -hold 0.110 +set_clock_uncertainty -rise_from [get_clocks {CLK_33M}] -fall_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] -setup 0.090 +set_clock_uncertainty -rise_from [get_clocks {CLK_33M}] -fall_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] -hold 0.110 +set_clock_uncertainty -rise_from [get_clocks {CLK_33M}] -rise_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[1]}] -setup 0.090 +set_clock_uncertainty -rise_from [get_clocks {CLK_33M}] -rise_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[1]}] -hold 0.110 +set_clock_uncertainty -rise_from [get_clocks {CLK_33M}] -fall_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[1]}] -setup 0.090 +set_clock_uncertainty -rise_from [get_clocks {CLK_33M}] -fall_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[1]}] -hold 0.110 +set_clock_uncertainty -rise_from [get_clocks {CLK_33M}] -rise_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] -setup 0.090 +set_clock_uncertainty -rise_from [get_clocks {CLK_33M}] -rise_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] -hold 0.110 +set_clock_uncertainty -rise_from [get_clocks {CLK_33M}] -fall_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] -setup 0.090 +set_clock_uncertainty -rise_from [get_clocks {CLK_33M}] -fall_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] -hold 0.110 +set_clock_uncertainty -rise_from [get_clocks {CLK_33M}] -rise_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] -setup 0.080 +set_clock_uncertainty -rise_from [get_clocks {CLK_33M}] -rise_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] -hold 0.100 +set_clock_uncertainty -rise_from [get_clocks {CLK_33M}] -fall_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] -setup 0.080 +set_clock_uncertainty -rise_from [get_clocks {CLK_33M}] -fall_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] -hold 0.100 +set_clock_uncertainty -rise_from [get_clocks {CLK_33M}] -rise_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[1]}] -setup 0.070 +set_clock_uncertainty -rise_from [get_clocks {CLK_33M}] -rise_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[1]}] -hold 0.100 +set_clock_uncertainty -rise_from [get_clocks {CLK_33M}] -fall_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[1]}] -setup 0.070 +set_clock_uncertainty -rise_from [get_clocks {CLK_33M}] -fall_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[1]}] -hold 0.100 +set_clock_uncertainty -fall_from [get_clocks {CLK_33M}] -rise_to [get_clocks {CLK_33M}] 0.020 +set_clock_uncertainty -fall_from [get_clocks {CLK_33M}] -fall_to [get_clocks {CLK_33M}] 0.020 +set_clock_uncertainty -fall_from [get_clocks {CLK_33M}] -rise_to [get_clocks {CLK_MAIN}] 0.040 +set_clock_uncertainty -fall_from [get_clocks {CLK_33M}] -fall_to [get_clocks {CLK_MAIN}] 0.040 +set_clock_uncertainty -fall_from [get_clocks {CLK_33M}] -rise_to [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] -setup 0.090 +set_clock_uncertainty -fall_from [get_clocks {CLK_33M}] -rise_to [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] -hold 0.110 +set_clock_uncertainty -fall_from [get_clocks {CLK_33M}] -fall_to [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] -setup 0.090 +set_clock_uncertainty -fall_from [get_clocks {CLK_33M}] -fall_to [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] -hold 0.110 +set_clock_uncertainty -fall_from [get_clocks {CLK_33M}] -rise_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] -setup 0.090 +set_clock_uncertainty -fall_from [get_clocks {CLK_33M}] -rise_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] -hold 0.110 +set_clock_uncertainty -fall_from [get_clocks {CLK_33M}] -fall_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] -setup 0.090 +set_clock_uncertainty -fall_from [get_clocks {CLK_33M}] -fall_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] -hold 0.110 +set_clock_uncertainty -fall_from [get_clocks {CLK_33M}] -rise_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[1]}] -setup 0.090 +set_clock_uncertainty -fall_from [get_clocks {CLK_33M}] -rise_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[1]}] -hold 0.110 +set_clock_uncertainty -fall_from [get_clocks {CLK_33M}] -fall_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[1]}] -setup 0.090 +set_clock_uncertainty -fall_from [get_clocks {CLK_33M}] -fall_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[1]}] -hold 0.110 +set_clock_uncertainty -fall_from [get_clocks {CLK_33M}] -rise_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] -setup 0.090 +set_clock_uncertainty -fall_from [get_clocks {CLK_33M}] -rise_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] -hold 0.110 +set_clock_uncertainty -fall_from [get_clocks {CLK_33M}] -fall_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] -setup 0.090 +set_clock_uncertainty -fall_from [get_clocks {CLK_33M}] -fall_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] -hold 0.110 +set_clock_uncertainty -fall_from [get_clocks {CLK_33M}] -rise_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] -setup 0.080 +set_clock_uncertainty -fall_from [get_clocks {CLK_33M}] -rise_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] -hold 0.100 +set_clock_uncertainty -fall_from [get_clocks {CLK_33M}] -fall_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] -setup 0.080 +set_clock_uncertainty -fall_from [get_clocks {CLK_33M}] -fall_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] -hold 0.100 +set_clock_uncertainty -fall_from [get_clocks {CLK_33M}] -rise_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[1]}] -setup 0.070 +set_clock_uncertainty -fall_from [get_clocks {CLK_33M}] -rise_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[1]}] -hold 0.100 +set_clock_uncertainty -fall_from [get_clocks {CLK_33M}] -fall_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[1]}] -setup 0.070 +set_clock_uncertainty -fall_from [get_clocks {CLK_33M}] -fall_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[1]}] -hold 0.100 +set_clock_uncertainty -rise_from [get_clocks {CLK_MAIN}] -rise_to [get_clocks {CLK_33M}] 0.040 +set_clock_uncertainty -rise_from [get_clocks {CLK_MAIN}] -fall_to [get_clocks {CLK_33M}] 0.040 +set_clock_uncertainty -rise_from [get_clocks {CLK_MAIN}] -rise_to [get_clocks {CLK_MAIN}] 0.020 +set_clock_uncertainty -rise_from [get_clocks {CLK_MAIN}] -fall_to [get_clocks {CLK_MAIN}] 0.020 +set_clock_uncertainty -rise_from [get_clocks {CLK_MAIN}] -rise_to [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] -setup 0.070 +set_clock_uncertainty -rise_from [get_clocks {CLK_MAIN}] -rise_to [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] -hold 0.100 +set_clock_uncertainty -rise_from [get_clocks {CLK_MAIN}] -fall_to [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] -setup 0.070 +set_clock_uncertainty -rise_from [get_clocks {CLK_MAIN}] -fall_to [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] -hold 0.100 +set_clock_uncertainty -rise_from [get_clocks {CLK_MAIN}] -rise_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] -setup 0.080 +set_clock_uncertainty -rise_from [get_clocks {CLK_MAIN}] -rise_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] -hold 0.100 +set_clock_uncertainty -rise_from [get_clocks {CLK_MAIN}] -fall_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] -setup 0.080 +set_clock_uncertainty -rise_from [get_clocks {CLK_MAIN}] -fall_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] -hold 0.100 +set_clock_uncertainty -rise_from [get_clocks {CLK_MAIN}] -rise_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] -setup 0.080 +set_clock_uncertainty -rise_from [get_clocks {CLK_MAIN}] -rise_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] -hold 0.100 +set_clock_uncertainty -rise_from [get_clocks {CLK_MAIN}] -fall_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] -setup 0.080 +set_clock_uncertainty -rise_from [get_clocks {CLK_MAIN}] -fall_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] -hold 0.100 +set_clock_uncertainty -rise_from [get_clocks {CLK_MAIN}] -rise_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] -setup 0.060 +set_clock_uncertainty -rise_from [get_clocks {CLK_MAIN}] -rise_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] -hold 0.090 +set_clock_uncertainty -rise_from [get_clocks {CLK_MAIN}] -fall_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] -setup 0.060 +set_clock_uncertainty -rise_from [get_clocks {CLK_MAIN}] -fall_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] -hold 0.090 +set_clock_uncertainty -rise_from [get_clocks {CLK_MAIN}] -rise_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[1]}] -setup 0.060 +set_clock_uncertainty -rise_from [get_clocks {CLK_MAIN}] -rise_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[1]}] -hold 0.090 +set_clock_uncertainty -rise_from [get_clocks {CLK_MAIN}] -fall_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[1]}] -setup 0.060 +set_clock_uncertainty -rise_from [get_clocks {CLK_MAIN}] -fall_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[1]}] -hold 0.090 +set_clock_uncertainty -fall_from [get_clocks {CLK_MAIN}] -rise_to [get_clocks {CLK_33M}] 0.040 +set_clock_uncertainty -fall_from [get_clocks {CLK_MAIN}] -fall_to [get_clocks {CLK_33M}] 0.040 +set_clock_uncertainty -fall_from [get_clocks {CLK_MAIN}] -rise_to [get_clocks {CLK_MAIN}] 0.020 +set_clock_uncertainty -fall_from [get_clocks {CLK_MAIN}] -fall_to [get_clocks {CLK_MAIN}] 0.020 +set_clock_uncertainty -fall_from [get_clocks {CLK_MAIN}] -rise_to [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] -setup 0.070 +set_clock_uncertainty -fall_from [get_clocks {CLK_MAIN}] -rise_to [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] -hold 0.100 +set_clock_uncertainty -fall_from [get_clocks {CLK_MAIN}] -fall_to [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] -setup 0.070 +set_clock_uncertainty -fall_from [get_clocks {CLK_MAIN}] -fall_to [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] -hold 0.100 +set_clock_uncertainty -fall_from [get_clocks {CLK_MAIN}] -rise_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] -setup 0.080 +set_clock_uncertainty -fall_from [get_clocks {CLK_MAIN}] -rise_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] -hold 0.100 +set_clock_uncertainty -fall_from [get_clocks {CLK_MAIN}] -fall_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] -setup 0.080 +set_clock_uncertainty -fall_from [get_clocks {CLK_MAIN}] -fall_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] -hold 0.100 +set_clock_uncertainty -fall_from [get_clocks {CLK_MAIN}] -rise_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] -setup 0.080 +set_clock_uncertainty -fall_from [get_clocks {CLK_MAIN}] -rise_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] -hold 0.100 +set_clock_uncertainty -fall_from [get_clocks {CLK_MAIN}] -fall_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] -setup 0.080 +set_clock_uncertainty -fall_from [get_clocks {CLK_MAIN}] -fall_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] -hold 0.100 +set_clock_uncertainty -fall_from [get_clocks {CLK_MAIN}] -rise_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] -setup 0.060 +set_clock_uncertainty -fall_from [get_clocks {CLK_MAIN}] -rise_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] -hold 0.090 +set_clock_uncertainty -fall_from [get_clocks {CLK_MAIN}] -fall_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] -setup 0.060 +set_clock_uncertainty -fall_from [get_clocks {CLK_MAIN}] -fall_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] -hold 0.090 +set_clock_uncertainty -fall_from [get_clocks {CLK_MAIN}] -rise_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[1]}] -setup 0.060 +set_clock_uncertainty -fall_from [get_clocks {CLK_MAIN}] -rise_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[1]}] -hold 0.090 +set_clock_uncertainty -fall_from [get_clocks {CLK_MAIN}] -fall_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[1]}] -setup 0.060 +set_clock_uncertainty -fall_from [get_clocks {CLK_MAIN}] -fall_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[1]}] -hold 0.090 +set_clock_uncertainty -rise_from [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] -rise_to [get_clocks {CLK_33M}] -setup 0.110 +set_clock_uncertainty -rise_from [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] -rise_to [get_clocks {CLK_33M}] -hold 0.090 +set_clock_uncertainty -rise_from [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] -fall_to [get_clocks {CLK_33M}] -setup 0.110 +set_clock_uncertainty -rise_from [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] -fall_to [get_clocks {CLK_33M}] -hold 0.090 +set_clock_uncertainty -rise_from [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] -rise_to [get_clocks {CLK_MAIN}] -setup 0.100 +set_clock_uncertainty -rise_from [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] -rise_to [get_clocks {CLK_MAIN}] -hold 0.070 +set_clock_uncertainty -rise_from [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] -fall_to [get_clocks {CLK_MAIN}] -setup 0.100 +set_clock_uncertainty -rise_from [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] -fall_to [get_clocks {CLK_MAIN}] -hold 0.070 +set_clock_uncertainty -rise_from [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] -rise_to [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] 0.030 +set_clock_uncertainty -rise_from [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] -fall_to [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] 0.030 +set_clock_uncertainty -rise_from [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] -rise_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] 0.160 +set_clock_uncertainty -rise_from [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] -fall_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] 0.160 +set_clock_uncertainty -rise_from [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] -rise_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] 0.150 +set_clock_uncertainty -rise_from [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] -fall_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] 0.150 +set_clock_uncertainty -fall_from [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] -rise_to [get_clocks {CLK_33M}] -setup 0.110 +set_clock_uncertainty -fall_from [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] -rise_to [get_clocks {CLK_33M}] -hold 0.090 +set_clock_uncertainty -fall_from [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] -fall_to [get_clocks {CLK_33M}] -setup 0.110 +set_clock_uncertainty -fall_from [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] -fall_to [get_clocks {CLK_33M}] -hold 0.090 +set_clock_uncertainty -fall_from [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] -rise_to [get_clocks {CLK_MAIN}] -setup 0.100 +set_clock_uncertainty -fall_from [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] -rise_to [get_clocks {CLK_MAIN}] -hold 0.070 +set_clock_uncertainty -fall_from [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] -fall_to [get_clocks {CLK_MAIN}] -setup 0.100 +set_clock_uncertainty -fall_from [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] -fall_to [get_clocks {CLK_MAIN}] -hold 0.070 +set_clock_uncertainty -fall_from [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] -rise_to [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] 0.030 +set_clock_uncertainty -fall_from [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] -fall_to [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] 0.030 +set_clock_uncertainty -fall_from [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] -rise_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] 0.160 +set_clock_uncertainty -fall_from [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] -fall_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] 0.160 +set_clock_uncertainty -fall_from [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] -rise_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] 0.150 +set_clock_uncertainty -fall_from [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] -fall_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] 0.150 +set_clock_uncertainty -rise_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] -rise_to [get_clocks {CLK_33M}] -setup 0.110 +set_clock_uncertainty -rise_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] -rise_to [get_clocks {CLK_33M}] -hold 0.090 +set_clock_uncertainty -rise_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] -fall_to [get_clocks {CLK_33M}] -setup 0.110 +set_clock_uncertainty -rise_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] -fall_to [get_clocks {CLK_33M}] -hold 0.090 +set_clock_uncertainty -rise_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] -rise_to [get_clocks {CLK_MAIN}] -setup 0.100 +set_clock_uncertainty -rise_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] -rise_to [get_clocks {CLK_MAIN}] -hold 0.080 +set_clock_uncertainty -rise_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] -fall_to [get_clocks {CLK_MAIN}] -setup 0.100 +set_clock_uncertainty -rise_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] -fall_to [get_clocks {CLK_MAIN}] -hold 0.080 +set_clock_uncertainty -rise_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] -rise_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] 0.020 +set_clock_uncertainty -rise_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] -fall_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] 0.020 +set_clock_uncertainty -rise_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] -rise_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[3]}] 0.020 +set_clock_uncertainty -rise_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] -fall_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[3]}] 0.020 +set_clock_uncertainty -rise_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] -rise_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] 0.020 +set_clock_uncertainty -rise_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] -fall_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] 0.020 +set_clock_uncertainty -rise_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] -rise_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[1]}] 0.150 +set_clock_uncertainty -rise_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] -fall_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[1]}] 0.150 +set_clock_uncertainty -fall_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] -rise_to [get_clocks {CLK_33M}] -setup 0.110 +set_clock_uncertainty -fall_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] -rise_to [get_clocks {CLK_33M}] -hold 0.090 +set_clock_uncertainty -fall_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] -fall_to [get_clocks {CLK_33M}] -setup 0.110 +set_clock_uncertainty -fall_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] -fall_to [get_clocks {CLK_33M}] -hold 0.090 +set_clock_uncertainty -fall_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] -rise_to [get_clocks {CLK_MAIN}] -setup 0.100 +set_clock_uncertainty -fall_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] -rise_to [get_clocks {CLK_MAIN}] -hold 0.080 +set_clock_uncertainty -fall_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] -fall_to [get_clocks {CLK_MAIN}] -setup 0.100 +set_clock_uncertainty -fall_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] -fall_to [get_clocks {CLK_MAIN}] -hold 0.080 +set_clock_uncertainty -fall_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] -rise_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] 0.020 +set_clock_uncertainty -fall_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] -fall_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] 0.020 +set_clock_uncertainty -fall_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] -rise_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[3]}] 0.020 +set_clock_uncertainty -fall_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] -fall_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[3]}] 0.020 +set_clock_uncertainty -fall_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] -rise_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] 0.020 +set_clock_uncertainty -fall_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] -fall_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] 0.020 +set_clock_uncertainty -fall_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] -rise_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[1]}] 0.150 +set_clock_uncertainty -fall_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] -fall_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[1]}] 0.150 +set_clock_uncertainty -rise_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[3]}] -rise_to [get_clocks {CLK_33M}] -setup 0.110 +set_clock_uncertainty -rise_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[3]}] -rise_to [get_clocks {CLK_33M}] -hold 0.090 +set_clock_uncertainty -rise_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[3]}] -fall_to [get_clocks {CLK_33M}] -setup 0.110 +set_clock_uncertainty -rise_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[3]}] -fall_to [get_clocks {CLK_33M}] -hold 0.090 +set_clock_uncertainty -rise_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[3]}] -rise_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] 0.020 +set_clock_uncertainty -rise_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[3]}] -fall_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] 0.020 +set_clock_uncertainty -rise_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[3]}] -rise_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[3]}] 0.020 +set_clock_uncertainty -rise_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[3]}] -fall_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[3]}] 0.020 +set_clock_uncertainty -fall_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[3]}] -rise_to [get_clocks {CLK_33M}] -setup 0.110 +set_clock_uncertainty -fall_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[3]}] -rise_to [get_clocks {CLK_33M}] -hold 0.090 +set_clock_uncertainty -fall_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[3]}] -fall_to [get_clocks {CLK_33M}] -setup 0.110 +set_clock_uncertainty -fall_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[3]}] -fall_to [get_clocks {CLK_33M}] -hold 0.090 +set_clock_uncertainty -fall_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[3]}] -rise_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] 0.020 +set_clock_uncertainty -fall_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[3]}] -fall_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] 0.020 +set_clock_uncertainty -fall_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[3]}] -rise_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[3]}] 0.020 +set_clock_uncertainty -fall_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[3]}] -fall_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[3]}] 0.020 +set_clock_uncertainty -rise_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[2]}] -rise_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[3]}] 0.020 +set_clock_uncertainty -rise_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[2]}] -fall_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[3]}] 0.020 +set_clock_uncertainty -fall_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[2]}] -rise_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[3]}] 0.020 +set_clock_uncertainty -fall_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[2]}] -fall_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[3]}] 0.020 +set_clock_uncertainty -rise_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[1]}] -rise_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[1]}] 0.020 +set_clock_uncertainty -rise_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[1]}] -fall_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[1]}] 0.020 +set_clock_uncertainty -rise_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[1]}] -rise_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] 0.020 +set_clock_uncertainty -rise_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[1]}] -fall_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] 0.020 +set_clock_uncertainty -fall_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[1]}] -rise_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[1]}] 0.020 +set_clock_uncertainty -fall_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[1]}] -fall_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[1]}] 0.020 +set_clock_uncertainty -fall_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[1]}] -rise_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] 0.020 +set_clock_uncertainty -fall_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[1]}] -fall_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] 0.020 +set_clock_uncertainty -rise_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] -rise_to [get_clocks {CLK_33M}] -setup 0.110 +set_clock_uncertainty -rise_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] -rise_to [get_clocks {CLK_33M}] -hold 0.090 +set_clock_uncertainty -rise_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] -fall_to [get_clocks {CLK_33M}] -setup 0.110 +set_clock_uncertainty -rise_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] -fall_to [get_clocks {CLK_33M}] -hold 0.090 +set_clock_uncertainty -rise_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] -rise_to [get_clocks {CLK_MAIN}] -setup 0.100 +set_clock_uncertainty -rise_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] -rise_to [get_clocks {CLK_MAIN}] -hold 0.080 +set_clock_uncertainty -rise_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] -fall_to [get_clocks {CLK_MAIN}] -setup 0.100 +set_clock_uncertainty -rise_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] -fall_to [get_clocks {CLK_MAIN}] -hold 0.080 +set_clock_uncertainty -rise_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] -rise_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] 0.020 +set_clock_uncertainty -rise_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] -fall_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] 0.020 +set_clock_uncertainty -rise_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] -rise_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[3]}] 0.020 +set_clock_uncertainty -rise_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] -fall_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[3]}] 0.020 +set_clock_uncertainty -rise_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] -rise_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[2]}] 0.020 +set_clock_uncertainty -rise_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] -fall_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[2]}] 0.020 +set_clock_uncertainty -rise_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] -rise_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] 0.020 +set_clock_uncertainty -rise_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] -fall_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] 0.020 +set_clock_uncertainty -fall_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] -rise_to [get_clocks {CLK_33M}] -setup 0.110 +set_clock_uncertainty -fall_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] -rise_to [get_clocks {CLK_33M}] -hold 0.090 +set_clock_uncertainty -fall_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] -fall_to [get_clocks {CLK_33M}] -setup 0.110 +set_clock_uncertainty -fall_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] -fall_to [get_clocks {CLK_33M}] -hold 0.090 +set_clock_uncertainty -fall_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] -rise_to [get_clocks {CLK_MAIN}] -setup 0.100 +set_clock_uncertainty -fall_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] -rise_to [get_clocks {CLK_MAIN}] -hold 0.080 +set_clock_uncertainty -fall_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] -fall_to [get_clocks {CLK_MAIN}] -setup 0.100 +set_clock_uncertainty -fall_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] -fall_to [get_clocks {CLK_MAIN}] -hold 0.080 +set_clock_uncertainty -fall_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] -rise_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] 0.020 +set_clock_uncertainty -fall_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] -fall_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[4]}] 0.020 +set_clock_uncertainty -fall_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] -rise_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[3]}] 0.020 +set_clock_uncertainty -fall_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] -fall_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[3]}] 0.020 +set_clock_uncertainty -fall_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] -rise_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[2]}] 0.020 +set_clock_uncertainty -fall_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] -fall_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[2]}] 0.020 +set_clock_uncertainty -fall_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] -rise_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] 0.020 +set_clock_uncertainty -fall_from [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] -fall_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] 0.020 +set_clock_uncertainty -rise_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[3]}] -rise_to [get_clocks {CLK_33M}] -setup 0.100 +set_clock_uncertainty -rise_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[3]}] -rise_to [get_clocks {CLK_33M}] -hold 0.070 +set_clock_uncertainty -rise_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[3]}] -fall_to [get_clocks {CLK_33M}] -setup 0.100 +set_clock_uncertainty -rise_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[3]}] -fall_to [get_clocks {CLK_33M}] -hold 0.070 +set_clock_uncertainty -rise_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[3]}] -rise_to [get_clocks {CLK_MAIN}] -setup 0.090 +set_clock_uncertainty -rise_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[3]}] -rise_to [get_clocks {CLK_MAIN}] -hold 0.060 +set_clock_uncertainty -rise_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[3]}] -fall_to [get_clocks {CLK_MAIN}] -setup 0.090 +set_clock_uncertainty -rise_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[3]}] -fall_to [get_clocks {CLK_MAIN}] -hold 0.060 +set_clock_uncertainty -rise_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[3]}] -rise_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[3]}] 0.020 +set_clock_uncertainty -rise_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[3]}] -fall_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[3]}] 0.020 +set_clock_uncertainty -fall_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[3]}] -rise_to [get_clocks {CLK_33M}] -setup 0.100 +set_clock_uncertainty -fall_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[3]}] -rise_to [get_clocks {CLK_33M}] -hold 0.070 +set_clock_uncertainty -fall_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[3]}] -fall_to [get_clocks {CLK_33M}] -setup 0.100 +set_clock_uncertainty -fall_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[3]}] -fall_to [get_clocks {CLK_33M}] -hold 0.070 +set_clock_uncertainty -fall_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[3]}] -rise_to [get_clocks {CLK_MAIN}] -setup 0.090 +set_clock_uncertainty -fall_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[3]}] -rise_to [get_clocks {CLK_MAIN}] -hold 0.060 +set_clock_uncertainty -fall_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[3]}] -fall_to [get_clocks {CLK_MAIN}] -setup 0.090 +set_clock_uncertainty -fall_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[3]}] -fall_to [get_clocks {CLK_MAIN}] -hold 0.060 +set_clock_uncertainty -fall_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[3]}] -rise_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[3]}] 0.020 +set_clock_uncertainty -fall_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[3]}] -fall_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[3]}] 0.020 +set_clock_uncertainty -rise_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] -rise_to [get_clocks {CLK_33M}] -setup 0.100 +set_clock_uncertainty -rise_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] -rise_to [get_clocks {CLK_33M}] -hold 0.080 +set_clock_uncertainty -rise_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] -fall_to [get_clocks {CLK_33M}] -setup 0.100 +set_clock_uncertainty -rise_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] -fall_to [get_clocks {CLK_33M}] -hold 0.080 +set_clock_uncertainty -rise_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] -rise_to [get_clocks {CLK_MAIN}] -setup 0.090 +set_clock_uncertainty -rise_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] -rise_to [get_clocks {CLK_MAIN}] -hold 0.060 +set_clock_uncertainty -rise_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] -fall_to [get_clocks {CLK_MAIN}] -setup 0.090 +set_clock_uncertainty -rise_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] -fall_to [get_clocks {CLK_MAIN}] -hold 0.060 +set_clock_uncertainty -rise_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] -rise_to [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] 0.150 +set_clock_uncertainty -rise_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] -fall_to [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] 0.150 +set_clock_uncertainty -rise_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] -rise_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] 0.150 +set_clock_uncertainty -rise_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] -fall_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] 0.150 +set_clock_uncertainty -rise_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] -rise_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] 0.030 +set_clock_uncertainty -rise_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] -fall_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] 0.030 +set_clock_uncertainty -fall_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] -rise_to [get_clocks {CLK_33M}] -setup 0.100 +set_clock_uncertainty -fall_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] -rise_to [get_clocks {CLK_33M}] -hold 0.080 +set_clock_uncertainty -fall_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] -fall_to [get_clocks {CLK_33M}] -setup 0.100 +set_clock_uncertainty -fall_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] -fall_to [get_clocks {CLK_33M}] -hold 0.080 +set_clock_uncertainty -fall_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] -rise_to [get_clocks {CLK_MAIN}] -setup 0.090 +set_clock_uncertainty -fall_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] -rise_to [get_clocks {CLK_MAIN}] -hold 0.060 +set_clock_uncertainty -fall_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] -fall_to [get_clocks {CLK_MAIN}] -setup 0.090 +set_clock_uncertainty -fall_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] -fall_to [get_clocks {CLK_MAIN}] -hold 0.060 +set_clock_uncertainty -fall_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] -rise_to [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] 0.150 +set_clock_uncertainty -fall_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] -fall_to [get_clocks {altpll4:I_PLL4|altpll:altpll_component|altpll4_altpll:auto_generated|wire_pll1_clk[0]}] 0.150 +set_clock_uncertainty -fall_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] -rise_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] 0.150 +set_clock_uncertainty -fall_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] -fall_to [get_clocks {altpll2:I_PLL2|altpll:altpll_component|altpll_da13:auto_generated|clk[0]}] 0.150 +set_clock_uncertainty -fall_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] -rise_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] 0.030 +set_clock_uncertainty -fall_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] -fall_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[2]}] 0.030 +set_clock_uncertainty -rise_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[1]}] -rise_to [get_clocks {CLK_33M}] -setup 0.100 +set_clock_uncertainty -rise_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[1]}] -rise_to [get_clocks {CLK_33M}] -hold 0.070 +set_clock_uncertainty -rise_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[1]}] -fall_to [get_clocks {CLK_33M}] -setup 0.100 +set_clock_uncertainty -rise_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[1]}] -fall_to [get_clocks {CLK_33M}] -hold 0.070 +set_clock_uncertainty -rise_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[1]}] -rise_to [get_clocks {CLK_MAIN}] -setup 0.090 +set_clock_uncertainty -rise_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[1]}] -rise_to [get_clocks {CLK_MAIN}] -hold 0.060 +set_clock_uncertainty -rise_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[1]}] -fall_to [get_clocks {CLK_MAIN}] -setup 0.090 +set_clock_uncertainty -rise_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[1]}] -fall_to [get_clocks {CLK_MAIN}] -hold 0.060 +set_clock_uncertainty -rise_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[1]}] -rise_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[1]}] 0.020 +set_clock_uncertainty -rise_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[1]}] -fall_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[1]}] 0.020 +set_clock_uncertainty -fall_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[1]}] -rise_to [get_clocks {CLK_33M}] -setup 0.100 +set_clock_uncertainty -fall_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[1]}] -rise_to [get_clocks {CLK_33M}] -hold 0.070 +set_clock_uncertainty -fall_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[1]}] -fall_to [get_clocks {CLK_33M}] -setup 0.100 +set_clock_uncertainty -fall_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[1]}] -fall_to [get_clocks {CLK_33M}] -hold 0.070 +set_clock_uncertainty -fall_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[1]}] -rise_to [get_clocks {CLK_MAIN}] -setup 0.090 +set_clock_uncertainty -fall_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[1]}] -rise_to [get_clocks {CLK_MAIN}] -hold 0.060 +set_clock_uncertainty -fall_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[1]}] -fall_to [get_clocks {CLK_MAIN}] -setup 0.090 +set_clock_uncertainty -fall_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[1]}] -fall_to [get_clocks {CLK_MAIN}] -hold 0.060 +set_clock_uncertainty -fall_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[1]}] -rise_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[1]}] 0.020 +set_clock_uncertainty -fall_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[1]}] -fall_to [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[1]}] 0.020 +set_clock_uncertainty -rise_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[0]}] -rise_to [get_clocks {CLK_MAIN}] -setup 0.090 +set_clock_uncertainty -rise_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[0]}] -rise_to [get_clocks {CLK_MAIN}] -hold 0.060 +set_clock_uncertainty -rise_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[0]}] -fall_to [get_clocks {CLK_MAIN}] -setup 0.090 +set_clock_uncertainty -rise_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[0]}] -fall_to [get_clocks {CLK_MAIN}] -hold 0.060 +set_clock_uncertainty -fall_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[0]}] -rise_to [get_clocks {CLK_MAIN}] -setup 0.090 +set_clock_uncertainty -fall_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[0]}] -rise_to [get_clocks {CLK_MAIN}] -hold 0.060 +set_clock_uncertainty -fall_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[0]}] -fall_to [get_clocks {CLK_MAIN}] -setup 0.090 +set_clock_uncertainty -fall_from [get_clocks {altpll3:I_PLL3|altpll:altpll_component|altpll_66t2:auto_generated|clk[0]}] -fall_to [get_clocks {CLK_MAIN}] -hold 0.060 +set_clock_uncertainty -rise_from [get_clocks {altpll1:I_PLL1|altpll:altpll_component|altpll_dnn2:auto_generated|clk[2]}] -rise_to [get_clocks {CLK_33M}] 0.040 +set_clock_uncertainty -rise_from [get_clocks {altpll1:I_PLL1|altpll:altpll_component|altpll_dnn2:auto_generated|clk[2]}] -fall_to [get_clocks {CLK_33M}] 0.040 +set_clock_uncertainty -fall_from [get_clocks {altpll1:I_PLL1|altpll:altpll_component|altpll_dnn2:auto_generated|clk[2]}] -rise_to [get_clocks {CLK_33M}] 0.040 +set_clock_uncertainty -fall_from [get_clocks {altpll1:I_PLL1|altpll:altpll_component|altpll_dnn2:auto_generated|clk[2]}] -fall_to [get_clocks {CLK_33M}] 0.040 +set_clock_uncertainty -rise_from [get_clocks {altpll1:I_PLL1|altpll:altpll_component|altpll_dnn2:auto_generated|clk[1]}] -rise_to [get_clocks {CLK_33M}] 0.040 +set_clock_uncertainty -rise_from [get_clocks {altpll1:I_PLL1|altpll:altpll_component|altpll_dnn2:auto_generated|clk[1]}] -fall_to [get_clocks {CLK_33M}] 0.040 +set_clock_uncertainty -fall_from [get_clocks {altpll1:I_PLL1|altpll:altpll_component|altpll_dnn2:auto_generated|clk[1]}] -rise_to [get_clocks {CLK_33M}] 0.040 +set_clock_uncertainty -fall_from [get_clocks {altpll1:I_PLL1|altpll:altpll_component|altpll_dnn2:auto_generated|clk[1]}] -fall_to [get_clocks {CLK_33M}] 0.040 +set_clock_uncertainty -rise_from [get_clocks {altpll1:I_PLL1|altpll:altpll_component|altpll_dnn2:auto_generated|clk[0]}] -rise_to [get_clocks {CLK_MAIN}] -setup 0.060 +set_clock_uncertainty -rise_from [get_clocks {altpll1:I_PLL1|altpll:altpll_component|altpll_dnn2:auto_generated|clk[0]}] -rise_to [get_clocks {CLK_MAIN}] -hold 0.090 +set_clock_uncertainty -rise_from [get_clocks {altpll1:I_PLL1|altpll:altpll_component|altpll_dnn2:auto_generated|clk[0]}] -fall_to [get_clocks {CLK_MAIN}] -setup 0.060 +set_clock_uncertainty -rise_from [get_clocks {altpll1:I_PLL1|altpll:altpll_component|altpll_dnn2:auto_generated|clk[0]}] -fall_to [get_clocks {CLK_MAIN}] -hold 0.090 +set_clock_uncertainty -fall_from [get_clocks {altpll1:I_PLL1|altpll:altpll_component|altpll_dnn2:auto_generated|clk[0]}] -rise_to [get_clocks {CLK_MAIN}] -setup 0.060 +set_clock_uncertainty -fall_from [get_clocks {altpll1:I_PLL1|altpll:altpll_component|altpll_dnn2:auto_generated|clk[0]}] -rise_to [get_clocks {CLK_MAIN}] -hold 0.090 +set_clock_uncertainty -fall_from [get_clocks {altpll1:I_PLL1|altpll:altpll_component|altpll_dnn2:auto_generated|clk[0]}] -fall_to [get_clocks {CLK_MAIN}] -setup 0.060 +set_clock_uncertainty -fall_from [get_clocks {altpll1:I_PLL1|altpll:altpll_component|altpll_dnn2:auto_generated|clk[0]}] -fall_to [get_clocks {CLK_MAIN}] -hold 0.090 + + +#************************************************************** +# Set Input Delay +#************************************************************** + +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {ACSI_DRQn}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {ACSI_D[0]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {ACSI_D[1]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {ACSI_D[2]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {ACSI_D[3]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {ACSI_D[4]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {ACSI_D[5]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {ACSI_D[6]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {ACSI_D[7]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {ACSI_INTn}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {AMKB_RX}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {CF_WP}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {CLK_33M}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {CLK_MAIN}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {CTS}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DACK0n}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DACK1n}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DCD}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_IO[0]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_IO[1]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_IO[2]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_IO[3]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_IO[4]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_IO[5]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_IO[6]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_IO[7]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_IO[8]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_IO[9]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_IO[10]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_IO[11]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_IO[12]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_IO[13]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_IO[14]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_IO[15]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_IO[16]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_IO[17]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_SRD[0]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_SRD[1]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_SRD[2]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_SRD[3]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_SRD[4]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_SRD[5]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_SRD[6]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_SRD[7]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_SRD[8]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_SRD[9]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_SRD[10]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_SRD[11]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_SRD[12]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_SRD[13]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_SRD[14]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_SRD[15]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DVI_INT}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {E0_INT}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[0]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[1]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[2]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[3]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[4]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[5]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[6]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[7]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[8]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[9]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[10]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[11]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[12]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[13]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[14]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[15]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[16]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[17]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[18]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[19]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[20]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[21]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[22]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[23]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[24]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[25]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[26]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[27]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[28]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[29]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[30]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[31]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_ALE}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_BURSTn}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_CSn[1]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_CSn[2]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_CSn[3]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_OEn}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_SIZE[0]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_SIZE[1]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_WRn}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FDD_DCHGn}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FDD_HD_DD}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FDD_INDEXn}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FDD_RDn}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FDD_TRACK00}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FDD_WPn}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {IDE_INT}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {IDE_RDY}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {LP_BUSY}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {LP_D[0]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {LP_D[1]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {LP_D[2]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {LP_D[3]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {LP_D[4]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {LP_D[5]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {LP_D[6]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {LP_D[7]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {MASTERn}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {MIDI_IN}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {PCI_INTAn}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {PCI_INTBn}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {PCI_INTCn}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {PCI_INTDn}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {PIC_AMKB_RX}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {PIC_INT}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {RI}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {RSTO_MCFn}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {RxD}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {SCSI_BUSYn}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {SCSI_CDn}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {SCSI_DRQn}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {SCSI_D[0]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {SCSI_D[1]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {SCSI_D[2]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {SCSI_D[3]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {SCSI_D[4]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {SCSI_D[5]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {SCSI_D[6]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {SCSI_D[7]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {SCSI_IOn}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {SCSI_MSGn}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {SCSI_PAR}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {SCSI_RSTn}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {SCSI_SELn}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {SD_CARD_DETECT}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {SD_CMD_D1}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {SD_D0}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {SD_D1}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {SD_D2}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {SD_D3}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {SD_WP}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {TOUT0n}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[0]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[1]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[2]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[3]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[4]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[5]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[6]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[7]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[8]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[9]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[10]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[11]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[12]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[13]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[14]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[15]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[16]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[17]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[18]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[19]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[20]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[21]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[22]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[23]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[24]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[25]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[26]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[27]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[28]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[29]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[30]}] +set_input_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[31]}] + + +#************************************************************** +# Set Output Delay +#************************************************************** + +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {ACSI_A1}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {ACSI_ACKn}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {ACSI_CSn}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {ACSI_DIR}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {ACSI_D[0]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {ACSI_D[1]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {ACSI_D[2]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {ACSI_D[3]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {ACSI_D[4]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {ACSI_D[5]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {ACSI_D[6]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {ACSI_D[7]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {ACSI_RESETn}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {AMKB_TX}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {BA[0]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {BA[1]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {BLANKn}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {CF_CSn[0]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {CF_CSn[1]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {CLK_24M576}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {CLK_25M}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {CLK_DDR_OUT}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {CLK_DDR_OUTn}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {CLK_PIXEL}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {CLK_USB}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DREQ1n}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSA_D}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_IO[0]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_IO[1]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_IO[2]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_IO[3]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_IO[4]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_IO[5]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_IO[6]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_IO[7]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_IO[8]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_IO[9]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_IO[10]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_IO[11]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_IO[12]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_IO[13]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_IO[14]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_IO[15]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_IO[16]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_IO[17]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_SRBHEn}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_SRBLEn}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_SRCSn}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_SRD[0]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_SRD[1]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_SRD[2]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_SRD[3]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_SRD[4]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_SRD[5]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_SRD[6]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_SRD[7]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_SRD[8]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_SRD[9]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_SRD[10]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_SRD[11]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_SRD[12]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_SRD[13]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_SRD[14]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_SRD[15]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_SROEn}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DSP_SRWEn}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {DTR}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[0]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[1]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[2]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[3]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[4]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[5]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[6]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[7]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[8]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[9]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[10]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[11]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[12]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[13]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[14]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[15]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[16]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[17]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[18]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[19]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[20]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[21]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[22]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[23]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[24]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[25]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[26]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[27]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[28]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[29]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[30]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_AD[31]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FB_TAn}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FDD_MOT_ON}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FDD_SDSELn}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FDD_STEP}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FDD_STEP_DIR}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FDD_WDn}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {FDD_WR_GATE}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {HSYNC}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {IDE_CSn[0]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {IDE_CSn[1]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {IDE_RDn}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {IDE_RES}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {IDE_WRn}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {IRQn[2]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {IRQn[3]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {IRQn[4]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {IRQn[5]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {IRQn[6]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {IRQn[7]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {LED_FPGA_OK}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {LP_DIR}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {LP_D[0]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {LP_D[1]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {LP_D[2]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {LP_D[3]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {LP_D[4]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {LP_D[5]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {LP_D[6]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {LP_D[7]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {LP_STR}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {MIDI_OLR}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {MIDI_TLR}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {PD_VGAn}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {RESERVED_1}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {ROM3n}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {ROM4n}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {RP_LDSn}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {RP_UDSn}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {RTS}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {SCSI_ACKn}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {SCSI_ATNn}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {SCSI_BUSYn}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {SCSI_DIR}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {SCSI_D[0]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {SCSI_D[1]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {SCSI_D[2]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {SCSI_D[3]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {SCSI_D[4]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {SCSI_D[5]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {SCSI_D[6]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {SCSI_D[7]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {SCSI_PAR}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {SCSI_RSTn}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {SCSI_SELn}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {SD_CLK}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {SD_CMD_D1}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {SD_D3}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {SYNCn}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {TIN0}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {TxD}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VA[0]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VA[1]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VA[2]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VA[3]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VA[4]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VA[5]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VA[6]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VA[7]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VA[8]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VA[9]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VA[10]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VA[11]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VA[12]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VB[0]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VB[1]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VB[2]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VB[3]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VB[4]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VB[5]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VB[6]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VB[7]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VCASn}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VCKE}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VCSn}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VDM[0]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VDM[1]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VDM[2]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VDM[3]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[0]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[1]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[2]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[3]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[4]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[5]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[6]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[7]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[8]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[9]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[10]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[11]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[12]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[13]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[14]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[15]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[16]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[17]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[18]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[19]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[20]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[21]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[22]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[23]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[24]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[25]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[26]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[27]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[28]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[29]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[30]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD[31]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD_QS[0]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD_QS[1]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD_QS[2]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VD_QS[3]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VG[0]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VG[1]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VG[2]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VG[3]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VG[4]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VG[5]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VG[6]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VG[7]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VRASn}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VR[0]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VR[1]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VR[2]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VR[3]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VR[4]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VR[5]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VR[6]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VR[7]}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VSYNC}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {VWEn}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {YM_QA}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {YM_QB}] +set_output_delay -add_delay -max -clock [get_clocks {CLK_33M}] 5.000 [get_ports {YM_QC}] + + +#************************************************************** +# Set Clock Groups +#************************************************************** + + + +#************************************************************** +# Set False Path +#************************************************************** + +set_false_path -from [get_keepers {*rdptr_g*}] -to [get_keepers {*ws_dgrp|dffpipe_id9:dffpipe17|dffe18a*}] +set_false_path -from [get_keepers {*delayed_wrptr_g*}] -to [get_keepers {*rs_dgwp|dffpipe_hd9:dffpipe12|dffe13a*}] +set_false_path -from [get_keepers {*rdptr_g*}] -to [get_keepers {*ws_dgrp|dffpipe_kd9:dffpipe15|dffe16a*}] +set_false_path -from [get_keepers {*delayed_wrptr_g*}] -to [get_keepers {*rs_dgwp|dffpipe_jd9:dffpipe12|dffe13a*}] +set_false_path -from [get_keepers {*rdptr_g*}] -to [get_keepers {*ws_dgrp|dffpipe_re9:dffpipe19|dffe20a*}] +set_false_path -from [get_registers {*dcfifo*delayed_wrptr_g[*]}] -to [get_registers {*dcfifo*rs_dgwp*}] +set_false_path -from [get_registers {*dcfifo*rdptr_g[*]}] -to [get_registers {*dcfifo*ws_dgrp*}] + + +#************************************************************** +# Set Multicycle Path +#************************************************************** + + + +#************************************************************** +# Set Maximum Delay +#************************************************************** + + + +#************************************************************** +# Set Minimum Delay +#************************************************************** + + + +#************************************************************** +# Set Input Transition +#************************************************************** + diff --git a/vhdl/backend/Altera/Firebee/firebee_assignment_defaults.qdf b/vhdl/backend/Altera/Firebee/firebee_assignment_defaults.qdf new file mode 100644 index 0000000..2558712 --- /dev/null +++ b/vhdl/backend/Altera/Firebee/firebee_assignment_defaults.qdf @@ -0,0 +1,692 @@ +# -------------------------------------------------------------------------- # +# +# Copyright (C) 1991-2013 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 64-Bit +# Version 13.1.0 Build 162 10/23/2013 SJ Web Edition +# Date created = 21:25:10 June 05, 2014 +# +# -------------------------------------------------------------------------- # +# +# Note: +# +# 1) Do not modify this file. This file was generated +# automatically by the Quartus II software and is used +# to preserve global assignments across Quartus II versions. +# +# -------------------------------------------------------------------------- # + +set_global_assignment -name PROJECT_SHOW_ENTITY_NAME On +set_global_assignment -name PROJECT_USE_SIMPLIFIED_NAMES Off +set_global_assignment -name VER_COMPATIBLE_DB_DIR export_db +set_global_assignment -name AUTO_EXPORT_VER_COMPATIBLE_DB Off +set_global_assignment -name SMART_RECOMPILE Off +set_global_assignment -name FLOW_DISABLE_ASSEMBLER Off +set_global_assignment -name FLOW_ENABLE_POWER_ANALYZER Off +set_global_assignment -name FLOW_ENABLE_HC_COMPARE Off +set_global_assignment -name HC_OUTPUT_DIR hc_output +set_global_assignment -name SAVE_MIGRATION_INFO_DURING_COMPILATION Off +set_global_assignment -name FLOW_ENABLE_IO_ASSIGNMENT_ANALYSIS Off +set_global_assignment -name RUN_FULL_COMPILE_ON_DEVICE_CHANGE On +set_global_assignment -name FLOW_ENABLE_RTL_VIEWER Off +set_global_assignment -name READ_OR_WRITE_IN_BYTE_ADDRESS "Use global settings" +set_global_assignment -name FLOW_HARDCOPY_DESIGN_READINESS_CHECK On +set_global_assignment -name FLOW_ENABLE_PARALLEL_MODULES On +set_global_assignment -name ENABLE_COMPACT_REPORT_TABLE Off +set_global_assignment -name REVISION_TYPE Base +set_global_assignment -name DEFAULT_HOLD_MULTICYCLE "Same as Multicycle" +set_global_assignment -name CUT_OFF_PATHS_BETWEEN_CLOCK_DOMAINS On +set_global_assignment -name CUT_OFF_READ_DURING_WRITE_PATHS On +set_global_assignment -name CUT_OFF_IO_PIN_FEEDBACK On +set_global_assignment -name DO_COMBINED_ANALYSIS Off +set_global_assignment -name TDC_AGGRESSIVE_HOLD_CLOSURE_EFFORT On +set_global_assignment -name USE_DLL_FREQUENCY_FOR_DQS_DELAY_CHAIN Off +set_global_assignment -name ANALYZE_LATCHES_AS_SYNCHRONOUS_ELEMENTS On +set_global_assignment -name TIMEQUEST_REPORT_SCRIPT_INCLUDE_DEFAULT_ANALYSIS On +set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS On -family "Arria V" +set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS On -family "Stratix IV" +set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS On -family "Cyclone IV E" +set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS On -family "Cyclone III" +set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS Off -family "MAX V" +set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS On -family "Stratix V" +set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS On -family "Arria V GZ" +set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS Off -family "MAX II" +set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS On -family "Arria II GX" +set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS On -family "Arria II GZ" +set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS On -family "Cyclone IV GX" +set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS On -family "Cyclone III LS" +set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS On -family "Stratix III" +set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS On -family "Cyclone V" +set_global_assignment -name TIMEQUEST_DO_REPORT_TIMING Off +set_global_assignment -name TIMEQUEST_REPORT_WORST_CASE_TIMING_PATHS Off -family "Arria V" +set_global_assignment -name TIMEQUEST_REPORT_WORST_CASE_TIMING_PATHS Off -family "Stratix IV" +set_global_assignment -name TIMEQUEST_REPORT_WORST_CASE_TIMING_PATHS On -family "Cyclone IV E" +set_global_assignment -name TIMEQUEST_REPORT_WORST_CASE_TIMING_PATHS On -family "Cyclone III" +set_global_assignment -name TIMEQUEST_REPORT_WORST_CASE_TIMING_PATHS On -family "MAX V" +set_global_assignment -name TIMEQUEST_REPORT_WORST_CASE_TIMING_PATHS Off -family "Stratix V" +set_global_assignment -name TIMEQUEST_REPORT_WORST_CASE_TIMING_PATHS Off -family "Arria V GZ" +set_global_assignment -name TIMEQUEST_REPORT_WORST_CASE_TIMING_PATHS On -family "MAX II" +set_global_assignment -name TIMEQUEST_REPORT_WORST_CASE_TIMING_PATHS Off -family "Arria II GX" +set_global_assignment -name TIMEQUEST_REPORT_WORST_CASE_TIMING_PATHS Off -family "Arria II GZ" +set_global_assignment -name TIMEQUEST_REPORT_WORST_CASE_TIMING_PATHS On -family "Cyclone IV GX" +set_global_assignment -name TIMEQUEST_REPORT_WORST_CASE_TIMING_PATHS On -family "Cyclone III LS" +set_global_assignment -name TIMEQUEST_REPORT_WORST_CASE_TIMING_PATHS Off -family "Stratix III" +set_global_assignment -name TIMEQUEST_REPORT_WORST_CASE_TIMING_PATHS Off -family "Cyclone V" +set_global_assignment -name TIMEQUEST_REPORT_NUM_WORST_CASE_TIMING_PATHS 100 +set_global_assignment -name TIMEQUEST_DO_CCPP_REMOVAL On -family "Arria V" +set_global_assignment -name TIMEQUEST_DO_CCPP_REMOVAL On -family "Cyclone IV E" +set_global_assignment -name TIMEQUEST_DO_CCPP_REMOVAL On -family "Stratix IV" +set_global_assignment -name TIMEQUEST_DO_CCPP_REMOVAL On -family "Cyclone III" +set_global_assignment -name TIMEQUEST_DO_CCPP_REMOVAL Off -family "MAX V" +set_global_assignment -name TIMEQUEST_DO_CCPP_REMOVAL On -family "Stratix V" +set_global_assignment -name TIMEQUEST_DO_CCPP_REMOVAL On -family "Arria V GZ" +set_global_assignment -name TIMEQUEST_DO_CCPP_REMOVAL Off -family "MAX II" +set_global_assignment -name TIMEQUEST_DO_CCPP_REMOVAL On -family "Arria II GX" +set_global_assignment -name TIMEQUEST_DO_CCPP_REMOVAL On -family "Arria II GZ" +set_global_assignment -name TIMEQUEST_DO_CCPP_REMOVAL On -family "Cyclone IV GX" +set_global_assignment -name TIMEQUEST_DO_CCPP_REMOVAL On -family "Cyclone III LS" +set_global_assignment -name TIMEQUEST_DO_CCPP_REMOVAL On -family "Stratix III" +set_global_assignment -name TIMEQUEST_DO_CCPP_REMOVAL On -family "Cyclone V" +set_global_assignment -name MUX_RESTRUCTURE Auto +set_global_assignment -name MLAB_ADD_TIMING_CONSTRAINTS_FOR_MIXED_PORT_FEED_THROUGH_MODE_SETTING_DONT_CARE Off +set_global_assignment -name ENABLE_IP_DEBUG Off +set_global_assignment -name SAVE_DISK_SPACE On +set_global_assignment -name DISABLE_OCP_HW_EVAL Off +set_global_assignment -name DEVICE_FILTER_PACKAGE Any +set_global_assignment -name DEVICE_FILTER_PIN_COUNT Any +set_global_assignment -name DEVICE_FILTER_SPEED_GRADE Any +set_global_assignment -name EDA_DESIGN_ENTRY_SYNTHESIS_TOOL "" +set_global_assignment -name VERILOG_INPUT_VERSION Verilog_2001 +set_global_assignment -name VHDL_INPUT_VERSION VHDL_1993 +set_global_assignment -name FAMILY "Cyclone IV GX" +set_global_assignment -name TRUE_WYSIWYG_FLOW Off +set_global_assignment -name SMART_COMPILE_IGNORES_TDC_FOR_STRATIX_PLL_CHANGES Off +set_global_assignment -name STATE_MACHINE_PROCESSING Auto +set_global_assignment -name SAFE_STATE_MACHINE Off +set_global_assignment -name EXTRACT_VERILOG_STATE_MACHINES On +set_global_assignment -name EXTRACT_VHDL_STATE_MACHINES On +set_global_assignment -name IGNORE_VERILOG_INITIAL_CONSTRUCTS Off +set_global_assignment -name VERILOG_CONSTANT_LOOP_LIMIT 5000 +set_global_assignment -name VERILOG_NON_CONSTANT_LOOP_LIMIT 250 +set_global_assignment -name INFER_RAMS_FROM_RAW_LOGIC On +set_global_assignment -name PARALLEL_SYNTHESIS On +set_global_assignment -name DSP_BLOCK_BALANCING Auto +set_global_assignment -name MAX_BALANCING_DSP_BLOCKS "-1 (Unlimited)" +set_global_assignment -name NOT_GATE_PUSH_BACK On +set_global_assignment -name ALLOW_POWER_UP_DONT_CARE On +set_global_assignment -name REMOVE_REDUNDANT_LOGIC_CELLS Off +set_global_assignment -name REMOVE_DUPLICATE_REGISTERS On +set_global_assignment -name IGNORE_CARRY_BUFFERS Off +set_global_assignment -name IGNORE_CASCADE_BUFFERS Off +set_global_assignment -name IGNORE_GLOBAL_BUFFERS Off +set_global_assignment -name IGNORE_ROW_GLOBAL_BUFFERS Off +set_global_assignment -name IGNORE_LCELL_BUFFERS Off +set_global_assignment -name MAX7000_IGNORE_LCELL_BUFFERS AUTO +set_global_assignment -name IGNORE_SOFT_BUFFERS On +set_global_assignment -name MAX7000_IGNORE_SOFT_BUFFERS Off +set_global_assignment -name LIMIT_AHDL_INTEGERS_TO_32_BITS Off +set_global_assignment -name AUTO_GLOBAL_CLOCK_MAX On +set_global_assignment -name AUTO_GLOBAL_OE_MAX On +set_global_assignment -name MAX_AUTO_GLOBAL_REGISTER_CONTROLS On +set_global_assignment -name AUTO_IMPLEMENT_IN_ROM Off +set_global_assignment -name APEX20K_TECHNOLOGY_MAPPER Lut +set_global_assignment -name OPTIMIZATION_TECHNIQUE Balanced +set_global_assignment -name STRATIXII_OPTIMIZATION_TECHNIQUE Balanced +set_global_assignment -name CYCLONE_OPTIMIZATION_TECHNIQUE Balanced +set_global_assignment -name CYCLONEII_OPTIMIZATION_TECHNIQUE Balanced +set_global_assignment -name STRATIX_OPTIMIZATION_TECHNIQUE Balanced +set_global_assignment -name MAXII_OPTIMIZATION_TECHNIQUE Balanced +set_global_assignment -name MAX7000_OPTIMIZATION_TECHNIQUE Speed +set_global_assignment -name APEX20K_OPTIMIZATION_TECHNIQUE Balanced +set_global_assignment -name MERCURY_OPTIMIZATION_TECHNIQUE Area +set_global_assignment -name FLEX6K_OPTIMIZATION_TECHNIQUE Area +set_global_assignment -name FLEX10K_OPTIMIZATION_TECHNIQUE Area +set_global_assignment -name ALLOW_XOR_GATE_USAGE On +set_global_assignment -name AUTO_LCELL_INSERTION On +set_global_assignment -name CARRY_CHAIN_LENGTH 48 +set_global_assignment -name FLEX6K_CARRY_CHAIN_LENGTH 32 +set_global_assignment -name FLEX10K_CARRY_CHAIN_LENGTH 32 +set_global_assignment -name MERCURY_CARRY_CHAIN_LENGTH 48 +set_global_assignment -name STRATIX_CARRY_CHAIN_LENGTH 70 +set_global_assignment -name STRATIXII_CARRY_CHAIN_LENGTH 70 +set_global_assignment -name CASCADE_CHAIN_LENGTH 2 +set_global_assignment -name PARALLEL_EXPANDER_CHAIN_LENGTH 16 +set_global_assignment -name MAX7000_PARALLEL_EXPANDER_CHAIN_LENGTH 4 +set_global_assignment -name AUTO_CARRY_CHAINS On +set_global_assignment -name AUTO_CASCADE_CHAINS On +set_global_assignment -name AUTO_PARALLEL_EXPANDERS On +set_global_assignment -name AUTO_OPEN_DRAIN_PINS On +set_global_assignment -name ADV_NETLIST_OPT_SYNTH_WYSIWYG_REMAP Off +set_global_assignment -name AUTO_ROM_RECOGNITION On +set_global_assignment -name AUTO_RAM_RECOGNITION On +set_global_assignment -name AUTO_DSP_RECOGNITION On +set_global_assignment -name AUTO_SHIFT_REGISTER_RECOGNITION Auto +set_global_assignment -name ALLOW_SHIFT_REGISTER_MERGING_ACROSS_HIERARCHIES Auto +set_global_assignment -name AUTO_CLOCK_ENABLE_RECOGNITION On +set_global_assignment -name STRICT_RAM_RECOGNITION Off +set_global_assignment -name ALLOW_SYNCH_CTRL_USAGE On +set_global_assignment -name FORCE_SYNCH_CLEAR Off +set_global_assignment -name AUTO_RAM_BLOCK_BALANCING On +set_global_assignment -name AUTO_RAM_TO_LCELL_CONVERSION Off +set_global_assignment -name AUTO_RESOURCE_SHARING Off +set_global_assignment -name ALLOW_ANY_RAM_SIZE_FOR_RECOGNITION Off +set_global_assignment -name ALLOW_ANY_ROM_SIZE_FOR_RECOGNITION Off +set_global_assignment -name ALLOW_ANY_SHIFT_REGISTER_SIZE_FOR_RECOGNITION Off +set_global_assignment -name MAX7000_FANIN_PER_CELL 100 +set_global_assignment -name USE_LOGICLOCK_CONSTRAINTS_IN_BALANCING On +set_global_assignment -name MAX_RAM_BLOCKS_M512 "-1 (Unlimited)" +set_global_assignment -name MAX_RAM_BLOCKS_M4K "-1 (Unlimited)" +set_global_assignment -name MAX_RAM_BLOCKS_MRAM "-1 (Unlimited)" +set_global_assignment -name IGNORE_TRANSLATE_OFF_AND_SYNTHESIS_OFF Off +set_global_assignment -name STRATIXGX_BYPASS_REMAPPING_OF_FORCE_SIGNAL_DETECT_SIGNAL_THRESHOLD_SELECT Off +set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS On -family "Arria II GZ" +set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS On -family "Arria V" +set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS On -family "Cyclone IV GX" +set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS On -family "Stratix IV" +set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS On -family "Cyclone IV E" +set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS On -family "Cyclone III LS" +set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS On -family "Cyclone III" +set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS On -family "Stratix III" +set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS On -family "Stratix V" +set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS On -family "Arria V GZ" +set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS On -family "Cyclone V" +set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS On -family "Arria II GX" +set_global_assignment -name REPORT_PARAMETER_SETTINGS On +set_global_assignment -name REPORT_SOURCE_ASSIGNMENTS On +set_global_assignment -name REPORT_CONNECTIVITY_CHECKS On +set_global_assignment -name IGNORE_MAX_FANOUT_ASSIGNMENTS Off +set_global_assignment -name SYNCHRONIZATION_REGISTER_CHAIN_LENGTH 3 -family "Arria V" +set_global_assignment -name SYNCHRONIZATION_REGISTER_CHAIN_LENGTH 2 -family "Cyclone IV E" +set_global_assignment -name SYNCHRONIZATION_REGISTER_CHAIN_LENGTH 3 -family "Stratix IV" +set_global_assignment -name SYNCHRONIZATION_REGISTER_CHAIN_LENGTH 2 -family "Cyclone III" +set_global_assignment -name SYNCHRONIZATION_REGISTER_CHAIN_LENGTH 2 -family "MAX V" +set_global_assignment -name SYNCHRONIZATION_REGISTER_CHAIN_LENGTH 3 -family "Stratix V" +set_global_assignment -name SYNCHRONIZATION_REGISTER_CHAIN_LENGTH 2 -family "MAX II" +set_global_assignment -name SYNCHRONIZATION_REGISTER_CHAIN_LENGTH 3 -family "Arria V GZ" +set_global_assignment -name SYNCHRONIZATION_REGISTER_CHAIN_LENGTH 3 -family "Arria II GX" +set_global_assignment -name SYNCHRONIZATION_REGISTER_CHAIN_LENGTH 3 -family "Arria II GZ" +set_global_assignment -name SYNCHRONIZATION_REGISTER_CHAIN_LENGTH 2 -family "Cyclone IV GX" +set_global_assignment -name SYNCHRONIZATION_REGISTER_CHAIN_LENGTH 2 -family "Cyclone III LS" +set_global_assignment -name SYNCHRONIZATION_REGISTER_CHAIN_LENGTH 2 -family "Stratix III" +set_global_assignment -name SYNCHRONIZATION_REGISTER_CHAIN_LENGTH 3 -family "Cyclone V" +set_global_assignment -name OPTIMIZE_POWER_DURING_SYNTHESIS "Normal compilation" +set_global_assignment -name HDL_MESSAGE_LEVEL Level2 +set_global_assignment -name USE_HIGH_SPEED_ADDER Auto +set_global_assignment -name NUMBER_OF_REMOVED_REGISTERS_REPORTED 5000 +set_global_assignment -name NUMBER_OF_SWEPT_NODES_REPORTED 5000 +set_global_assignment -name NUMBER_OF_INVERTED_REGISTERS_REPORTED 100 +set_global_assignment -name SYNTH_CLOCK_MUX_PROTECTION On +set_global_assignment -name SYNTH_GATED_CLOCK_CONVERSION Off +set_global_assignment -name BLOCK_DESIGN_NAMING Auto +set_global_assignment -name SYNTH_PROTECT_SDC_CONSTRAINT Off +set_global_assignment -name SYNTHESIS_EFFORT Auto +set_global_assignment -name SHIFT_REGISTER_RECOGNITION_ACLR_SIGNAL On +set_global_assignment -name PRE_MAPPING_RESYNTHESIS Off +set_global_assignment -name SYNTH_MESSAGE_LEVEL Medium +set_global_assignment -name DISABLE_REGISTER_MERGING_ACROSS_HIERARCHIES Auto +set_global_assignment -name SYNTH_RESOURCE_AWARE_INFERENCE_FOR_BLOCK_RAM On -family "Arria II GZ" +set_global_assignment -name SYNTH_RESOURCE_AWARE_INFERENCE_FOR_BLOCK_RAM On -family "Arria V" +set_global_assignment -name SYNTH_RESOURCE_AWARE_INFERENCE_FOR_BLOCK_RAM On -family "Cyclone IV GX" +set_global_assignment -name SYNTH_RESOURCE_AWARE_INFERENCE_FOR_BLOCK_RAM On -family "Stratix IV" +set_global_assignment -name SYNTH_RESOURCE_AWARE_INFERENCE_FOR_BLOCK_RAM On -family "Cyclone IV E" +set_global_assignment -name SYNTH_RESOURCE_AWARE_INFERENCE_FOR_BLOCK_RAM On -family "Cyclone III LS" +set_global_assignment -name SYNTH_RESOURCE_AWARE_INFERENCE_FOR_BLOCK_RAM On -family "Cyclone III" +set_global_assignment -name SYNTH_RESOURCE_AWARE_INFERENCE_FOR_BLOCK_RAM On -family "Stratix III" +set_global_assignment -name SYNTH_RESOURCE_AWARE_INFERENCE_FOR_BLOCK_RAM On -family "Stratix V" +set_global_assignment -name SYNTH_RESOURCE_AWARE_INFERENCE_FOR_BLOCK_RAM On -family "Arria V GZ" +set_global_assignment -name SYNTH_RESOURCE_AWARE_INFERENCE_FOR_BLOCK_RAM On -family "Cyclone V" +set_global_assignment -name SYNTH_RESOURCE_AWARE_INFERENCE_FOR_BLOCK_RAM On -family "Arria II GX" +set_global_assignment -name MAX_LABS "-1 (Unlimited)" +set_global_assignment -name RBCGEN_CRITICAL_WARNING_TO_ERROR On +set_global_assignment -name SYNTHESIS_SEED 1 +set_global_assignment -name MAX_NUMBER_OF_REGISTERS_FROM_UNINFERRED_RAMS "-1 (Unlimited)" +set_global_assignment -name AUTO_PARALLEL_SYNTHESIS On +set_global_assignment -name FLEX10K_ENABLE_LOCK_OUTPUT Off +set_global_assignment -name AUTO_MERGE_PLLS On +set_global_assignment -name IGNORE_MODE_FOR_MERGE Off +set_global_assignment -name TXPMA_SLEW_RATE Low +set_global_assignment -name ADCE_ENABLED Auto +set_global_assignment -name ROUTER_TIMING_OPTIMIZATION_LEVEL Normal +set_global_assignment -name ROUTER_CLOCKING_TOPOLOGY_ANALYSIS Off +set_global_assignment -name PLACEMENT_EFFORT_MULTIPLIER 1.0 +set_global_assignment -name ROUTER_EFFORT_MULTIPLIER 1.0 +set_global_assignment -name FIT_ATTEMPTS_TO_SKIP 0.0 +set_global_assignment -name ECO_ALLOW_ROUTING_CHANGES Off +set_global_assignment -name DEVICE AUTO +set_global_assignment -name BASE_PIN_OUT_FILE_ON_SAMEFRAME_DEVICE Off +set_global_assignment -name ENABLE_JTAG_BST_SUPPORT Off +set_global_assignment -name MAX7000_ENABLE_JTAG_BST_SUPPORT On +set_global_assignment -name ENABLE_NCEO_OUTPUT Off +set_global_assignment -name RESERVE_NCEO_AFTER_CONFIGURATION "Use as regular IO" +set_global_assignment -name CYCLONEII_RESERVE_NCEO_AFTER_CONFIGURATION "Use as programming pin" +set_global_assignment -name STRATIXIII_UPDATE_MODE Standard +set_global_assignment -name STRATIX_UPDATE_MODE Standard +set_global_assignment -name INTERNAL_FLASH_UPDATE_MODE Standard +set_global_assignment -name FALLBACK_TO_EXTERNAL_FLASH Off +set_global_assignment -name EXTERNAL_FLASH_FALLBACK_ADDRESS 00000000 +set_global_assignment -name CVP_MODE Off +set_global_assignment -name STRATIXV_CONFIGURATION_SCHEME "Passive Serial" +set_global_assignment -name STRATIXIII_CONFIGURATION_SCHEME "Passive Serial" +set_global_assignment -name MAX10FPGA_CONFIGURATION_SCHEME "Internal Configuration" +set_global_assignment -name CYCLONEIII_CONFIGURATION_SCHEME "Active Serial" +set_global_assignment -name STRATIXII_CONFIGURATION_SCHEME "Passive Serial" +set_global_assignment -name CYCLONEII_CONFIGURATION_SCHEME "Active Serial" +set_global_assignment -name APEX20K_CONFIGURATION_SCHEME "Passive Serial" +set_global_assignment -name STRATIX_CONFIGURATION_SCHEME "Passive Serial" +set_global_assignment -name CYCLONE_CONFIGURATION_SCHEME "Active Serial" +set_global_assignment -name MERCURY_CONFIGURATION_SCHEME "Passive Serial" +set_global_assignment -name FLEX6K_CONFIGURATION_SCHEME "Passive Serial" +set_global_assignment -name FLEX10K_CONFIGURATION_SCHEME "Passive Serial" +set_global_assignment -name APEXII_CONFIGURATION_SCHEME "Passive Serial" +set_global_assignment -name USER_START_UP_CLOCK Off +set_global_assignment -name DEVICE_INITIALIZATION_CLOCK INIT_INTOSC +set_global_assignment -name ENABLE_VREFA_PIN Off +set_global_assignment -name ENABLE_VREFB_PIN Off +set_global_assignment -name ALWAYS_ENABLE_INPUT_BUFFERS Off +set_global_assignment -name ENABLE_ASMI_FOR_FLASH_LOADER Off +set_global_assignment -name ENABLE_DEVICE_WIDE_RESET Off +set_global_assignment -name ENABLE_DEVICE_WIDE_OE Off +set_global_assignment -name RESERVE_ALL_UNUSED_PINS "As output driving ground" +set_global_assignment -name ENABLE_INIT_DONE_OUTPUT Off +set_global_assignment -name INIT_DONE_OPEN_DRAIN On +set_global_assignment -name RESERVE_NWS_NRS_NCS_CS_AFTER_CONFIGURATION "Use as regular IO" +set_global_assignment -name RESERVE_RDYNBUSY_AFTER_CONFIGURATION "Use as regular IO" +set_global_assignment -name RESERVE_DATA31_THROUGH_DATA16_AFTER_CONFIGURATION "Use as regular IO" +set_global_assignment -name RESERVE_DATA15_THROUGH_DATA8_AFTER_CONFIGURATION "Use as regular IO" +set_global_assignment -name RESERVE_DATA7_THROUGH_DATA1_AFTER_CONFIGURATION "Use as regular IO" +set_global_assignment -name RESERVE_DATA0_AFTER_CONFIGURATION "As input tri-stated" +set_global_assignment -name RESERVE_DATA1_AFTER_CONFIGURATION "As input tri-stated" +set_global_assignment -name RESERVE_DATA7_THROUGH_DATA2_AFTER_CONFIGURATION "Use as regular IO" +set_global_assignment -name RESERVE_DATA7_THROUGH_DATA5_AFTER_CONFIGURATION "Use as regular IO" +set_global_assignment -name RESERVE_FLASH_NCE_AFTER_CONFIGURATION "As input tri-stated" +set_global_assignment -name RESERVE_OTHER_AP_PINS_AFTER_CONFIGURATION "Use as regular IO" +set_global_assignment -name RESERVE_DCLK_AFTER_CONFIGURATION "Use as programming pin" +set_global_assignment -name ENABLE_CONFIGURATION_PINS On +set_global_assignment -name ENABLE_JTAG_PIN_SHARING Off +set_global_assignment -name ENABLE_NCE_PIN On +set_global_assignment -name ENABLE_BOOT_SEL_PIN On +set_global_assignment -name CRC_ERROR_CHECKING Off +set_global_assignment -name INTERNAL_SCRUBBING Off +set_global_assignment -name PR_ERROR_OPEN_DRAIN On +set_global_assignment -name PR_READY_OPEN_DRAIN On +set_global_assignment -name ENABLE_CVP_CONFDONE Off +set_global_assignment -name CVP_CONFDONE_OPEN_DRAIN On +set_global_assignment -name OPTIMIZE_HOLD_TIMING "All Paths" -family "Arria II GZ" +set_global_assignment -name OPTIMIZE_HOLD_TIMING "All Paths" -family "Arria V" +set_global_assignment -name OPTIMIZE_HOLD_TIMING "All Paths" -family "Cyclone IV GX" +set_global_assignment -name OPTIMIZE_HOLD_TIMING "All Paths" -family "Stratix IV" +set_global_assignment -name OPTIMIZE_HOLD_TIMING "All Paths" -family "Cyclone IV E" +set_global_assignment -name OPTIMIZE_HOLD_TIMING "All Paths" -family "Cyclone III LS" +set_global_assignment -name OPTIMIZE_HOLD_TIMING "All Paths" -family "Cyclone III" +set_global_assignment -name OPTIMIZE_HOLD_TIMING "All Paths" -family "Stratix III" +set_global_assignment -name OPTIMIZE_HOLD_TIMING "IO Paths and Minimum TPD Paths" -family "MAX V" +set_global_assignment -name OPTIMIZE_HOLD_TIMING "All Paths" -family "Stratix V" +set_global_assignment -name OPTIMIZE_HOLD_TIMING "IO Paths and Minimum TPD Paths" -family "MAX II" +set_global_assignment -name OPTIMIZE_HOLD_TIMING "All Paths" -family "Arria V GZ" +set_global_assignment -name OPTIMIZE_HOLD_TIMING "All Paths" -family "Cyclone V" +set_global_assignment -name OPTIMIZE_HOLD_TIMING "All Paths" -family "Arria II GX" +set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING On -family "Arria V" +set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING On -family "Cyclone IV E" +set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING On -family "Stratix IV" +set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING On -family "Cyclone III" +set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING Off -family "MAX V" +set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING On -family "Stratix V" +set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING On -family "Arria V GZ" +set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING Off -family "MAX II" +set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING On -family "Arria II GX" +set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING On -family "Arria II GZ" +set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING On -family "Cyclone IV GX" +set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING On -family "Cyclone III LS" +set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING On -family "Stratix III" +set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING On -family "Cyclone V" +set_global_assignment -name BLOCK_RAM_TO_MLAB_CELL_CONVERSION On +set_global_assignment -name BLOCK_RAM_AND_MLAB_EQUIVALENT_POWER_UP_CONDITIONS Auto +set_global_assignment -name BLOCK_RAM_AND_MLAB_EQUIVALENT_PAUSED_READ_CAPABILITIES Care +set_global_assignment -name PROGRAMMABLE_POWER_TECHNOLOGY_SETTING Automatic +set_global_assignment -name PROGRAMMABLE_POWER_MAXIMUM_HIGH_SPEED_FRACTION_OF_USED_LAB_TILES 1.0 +set_global_assignment -name GUARANTEE_MIN_DELAY_CORNER_IO_ZERO_HOLD_TIME On +set_global_assignment -name OPTIMIZE_POWER_DURING_FITTING "Normal compilation" +set_global_assignment -name OPTIMIZE_SSN Off +set_global_assignment -name OPTIMIZE_TIMING "Normal compilation" +set_global_assignment -name ECO_OPTIMIZE_TIMING Off +set_global_assignment -name ECO_REGENERATE_REPORT Off +set_global_assignment -name OPTIMIZE_IOC_REGISTER_PLACEMENT_FOR_TIMING Normal +set_global_assignment -name FIT_ONLY_ONE_ATTEMPT Off +set_global_assignment -name FINAL_PLACEMENT_OPTIMIZATION Automatically +set_global_assignment -name FITTER_AGGRESSIVE_ROUTABILITY_OPTIMIZATION Automatically +set_global_assignment -name SEED 1 +set_global_assignment -name SLOW_SLEW_RATE Off +set_global_assignment -name PCI_IO Off +set_global_assignment -name VREF_MODE EXTERNAL +set_global_assignment -name TURBO_BIT On +set_global_assignment -name WEAK_PULL_UP_RESISTOR Off +set_global_assignment -name ENABLE_BUS_HOLD_CIRCUITRY Off +set_global_assignment -name AUTO_GLOBAL_MEMORY_CONTROLS Off +set_global_assignment -name MIGRATION_CONSTRAIN_CORE_RESOURCES On +set_global_assignment -name AUTO_PACKED_REGISTERS_STRATIXII AUTO +set_global_assignment -name AUTO_PACKED_REGISTERS_MAXII AUTO +set_global_assignment -name AUTO_PACKED_REGISTERS_CYCLONE Auto +set_global_assignment -name AUTO_PACKED_REGISTERS Off +set_global_assignment -name AUTO_PACKED_REGISTERS_STRATIX AUTO +set_global_assignment -name NORMAL_LCELL_INSERT On +set_global_assignment -name CARRY_OUT_PINS_LCELL_INSERT On +set_global_assignment -name AUTO_DELAY_CHAINS On +set_global_assignment -name AUTO_DELAY_CHAINS_FOR_HIGH_FANOUT_INPUT_PINS OFF +set_global_assignment -name XSTL_INPUT_ALLOW_SE_BUFFER Off +set_global_assignment -name TREAT_BIDIR_AS_OUTPUT Off +set_global_assignment -name AUTO_TURBO_BIT ON +set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC_FOR_AREA Off +set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC Off +set_global_assignment -name PHYSICAL_SYNTHESIS_LOG_FILE Off +set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_DUPLICATION Off +set_global_assignment -name PHYSICAL_SYNTHESIS_MAP_LOGIC_TO_MEMORY_FOR_AREA Off +set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_RETIMING Off +set_global_assignment -name PHYSICAL_SYNTHESIS_ASYNCHRONOUS_SIGNAL_PIPELINING Off +set_global_assignment -name IO_PLACEMENT_OPTIMIZATION On +set_global_assignment -name ALLOW_LVTTL_LVCMOS_INPUT_LEVELS_TO_OVERDRIVE_INPUT_BUFFER Off +set_global_assignment -name OVERRIDE_DEFAULT_ELECTROMIGRATION_PARAMETERS Off +set_global_assignment -name FITTER_EFFORT "Auto Fit" +set_global_assignment -name FITTER_AUTO_EFFORT_DESIRED_SLACK_MARGIN 0ns +set_global_assignment -name PHYSICAL_SYNTHESIS_EFFORT Normal +set_global_assignment -name ROUTER_LCELL_INSERTION_AND_LOGIC_DUPLICATION AUTO +set_global_assignment -name ROUTER_REGISTER_DUPLICATION AUTO +set_global_assignment -name STRATIXGX_ALLOW_CLOCK_FANOUT_WITH_ANALOG_RESET Off +set_global_assignment -name AUTO_GLOBAL_CLOCK On +set_global_assignment -name AUTO_GLOBAL_OE On +set_global_assignment -name AUTO_GLOBAL_REGISTER_CONTROLS On +set_global_assignment -name FITTER_EARLY_TIMING_ESTIMATE_MODE Realistic +set_global_assignment -name STRATIXGX_ALLOW_GIGE_UNDER_FULL_DATARATE_RANGE Off +set_global_assignment -name STRATIXGX_ALLOW_RX_CORECLK_FROM_NON_RX_CLKOUT_SOURCE_IN_DOUBLE_DATA_WIDTH_MODE Off +set_global_assignment -name STRATIXGX_ALLOW_GIGE_IN_DOUBLE_DATA_WIDTH_MODE Off +set_global_assignment -name STRATIXGX_ALLOW_PARALLEL_LOOPBACK_IN_DOUBLE_DATA_WIDTH_MODE Off +set_global_assignment -name STRATIXGX_ALLOW_XAUI_IN_SINGLE_DATA_WIDTH_MODE Off +set_global_assignment -name STRATIXGX_ALLOW_XAUI_WITH_CORECLK_SELECTED_AT_RATE_MATCHER Off +set_global_assignment -name STRATIXGX_ALLOW_XAUI_WITH_RX_CORECLK_FROM_NON_TXPLL_SOURCE Off +set_global_assignment -name STRATIXGX_ALLOW_GIGE_WITH_CORECLK_SELECTED_AT_RATE_MATCHER Off +set_global_assignment -name STRATIXGX_ALLOW_GIGE_WITHOUT_8B10B Off +set_global_assignment -name STRATIXGX_ALLOW_GIGE_WITH_RX_CORECLK_FROM_NON_TXPLL_SOURCE Off +set_global_assignment -name STRATIXGX_ALLOW_POST8B10B_LOOPBACK Off +set_global_assignment -name STRATIXGX_ALLOW_REVERSE_PARALLEL_LOOPBACK Off +set_global_assignment -name STRATIXGX_ALLOW_USE_OF_GXB_COUPLED_IOS Off +set_global_assignment -name GENERATE_GXB_RECONFIG_MIF Off +set_global_assignment -name GENERATE_GXB_RECONFIG_MIF_WITH_PLL Off +set_global_assignment -name RESERVE_ALL_UNUSED_PINS_WEAK_PULLUP "As input tri-stated with weak pull-up" +set_global_assignment -name ENABLE_HOLD_BACK_OFF On +set_global_assignment -name CONFIGURATION_VCCIO_LEVEL Auto +set_global_assignment -name FORCE_CONFIGURATION_VCCIO Off +set_global_assignment -name SYNCHRONIZER_IDENTIFICATION Off +set_global_assignment -name ENABLE_BENEFICIAL_SKEW_OPTIMIZATION On +set_global_assignment -name OPTIMIZE_FOR_METASTABILITY On +set_global_assignment -name CRC_ERROR_OPEN_DRAIN On -family "Arria V" +set_global_assignment -name CRC_ERROR_OPEN_DRAIN Off -family "Cyclone IV E" +set_global_assignment -name CRC_ERROR_OPEN_DRAIN Off -family "Cyclone III" +set_global_assignment -name CRC_ERROR_OPEN_DRAIN On -family "Stratix V" +set_global_assignment -name CRC_ERROR_OPEN_DRAIN On -family "Arria V GZ" +set_global_assignment -name CRC_ERROR_OPEN_DRAIN Off -family "Cyclone III LS" +set_global_assignment -name CRC_ERROR_OPEN_DRAIN Off -family "Stratix III" +set_global_assignment -name CRC_ERROR_OPEN_DRAIN On -family "Cyclone V" +set_global_assignment -name MAX_GLOBAL_CLOCKS_ALLOWED "-1 (Unlimited)" +set_global_assignment -name MAX_REGIONAL_CLOCKS_ALLOWED "-1 (Unlimited)" +set_global_assignment -name MAX_PERIPHERY_CLOCKS_ALLOWED "-1 (Unlimited)" +set_global_assignment -name MAX_LARGE_PERIPHERY_CLOCKS_ALLOWED "-1 (Unlimited)" +set_global_assignment -name MAX_CLOCKS_ALLOWED "-1 (Unlimited)" +set_global_assignment -name ACTIVE_SERIAL_CLOCK FREQ_100MHz -family "Arria V" +set_global_assignment -name ACTIVE_SERIAL_CLOCK FREQ_100MHz -family "Stratix V" +set_global_assignment -name ACTIVE_SERIAL_CLOCK FREQ_40MHz -family "Cyclone IV GX" +set_global_assignment -name ACTIVE_SERIAL_CLOCK FREQ_100MHz -family "Arria V GZ" +set_global_assignment -name ACTIVE_SERIAL_CLOCK FREQ_40MHz -family "Arria II GX" +set_global_assignment -name ACTIVE_SERIAL_CLOCK FREQ_100MHz -family "Cyclone V" +set_global_assignment -name M144K_BLOCK_READ_CLOCK_DUTY_CYCLE_DEPENDENCY Off +set_global_assignment -name STRATIXIII_MRAM_COMPATIBILITY On +set_global_assignment -name FORCE_FITTER_TO_AVOID_PERIPHERY_PLACEMENT_WARNINGS Off +set_global_assignment -name AUTO_C3_M9K_BIT_SKIP Off +set_global_assignment -name PR_DONE_OPEN_DRAIN On +set_global_assignment -name NCEO_OPEN_DRAIN On +set_global_assignment -name ENABLE_CRC_ERROR_PIN Off +set_global_assignment -name ENABLE_PR_PINS Off +set_global_assignment -name PR_PINS_OPEN_DRAIN Off +set_global_assignment -name CLAMPING_DIODE Off +set_global_assignment -name TRI_STATE_SPI_PINS Off +set_global_assignment -name UNUSED_TSD_PINS_GND Off +set_global_assignment -name IMPLEMENT_MLAB_IN_16_BIT_DEEP_MODE Off +set_global_assignment -name FORM_DDR_CLUSTERING_CLIQUE Off +set_global_assignment -name ALM_REGISTER_PACKING_EFFORT MEDIUM +set_global_assignment -name EDA_SIMULATION_TOOL "" +set_global_assignment -name EDA_TIMING_ANALYSIS_TOOL "" +set_global_assignment -name EDA_BOARD_DESIGN_TIMING_TOOL "" +set_global_assignment -name EDA_BOARD_DESIGN_SYMBOL_TOOL "" +set_global_assignment -name EDA_BOARD_DESIGN_SIGNAL_INTEGRITY_TOOL "" +set_global_assignment -name EDA_BOARD_DESIGN_BOUNDARY_SCAN_TOOL "" +set_global_assignment -name EDA_BOARD_DESIGN_TOOL "" +set_global_assignment -name EDA_FORMAL_VERIFICATION_TOOL "" +set_global_assignment -name EDA_RESYNTHESIS_TOOL "" +set_global_assignment -name ON_CHIP_BITSTREAM_DECOMPRESSION On +set_global_assignment -name COMPRESSION_MODE Off +set_global_assignment -name CLOCK_SOURCE Internal +set_global_assignment -name CONFIGURATION_CLOCK_FREQUENCY "10 MHz" +set_global_assignment -name CONFIGURATION_CLOCK_DIVISOR 1 +set_global_assignment -name ENABLE_LOW_VOLTAGE_MODE_ON_CONFIG_DEVICE On +set_global_assignment -name FLEX6K_ENABLE_LOW_VOLTAGE_MODE_ON_CONFIG_DEVICE Off +set_global_assignment -name FLEX10K_ENABLE_LOW_VOLTAGE_MODE_ON_CONFIG_DEVICE On +set_global_assignment -name MAX7000S_JTAG_USER_CODE FFFF +set_global_assignment -name STRATIX_JTAG_USER_CODE FFFFFFFF +set_global_assignment -name APEX20K_JTAG_USER_CODE FFFFFFFF +set_global_assignment -name MERCURY_JTAG_USER_CODE FFFFFFFF +set_global_assignment -name FLEX10K_JTAG_USER_CODE 7F +set_global_assignment -name MAX7000_JTAG_USER_CODE FFFFFFFF +set_global_assignment -name MAX7000_USE_CHECKSUM_AS_USERCODE Off +set_global_assignment -name USE_CHECKSUM_AS_USERCODE On +set_global_assignment -name SECURITY_BIT Off +set_global_assignment -name USE_CONFIGURATION_DEVICE Off -family "Cyclone IV E" +set_global_assignment -name USE_CONFIGURATION_DEVICE Off -family "Stratix IV" +set_global_assignment -name USE_CONFIGURATION_DEVICE Off -family "Cyclone III" +set_global_assignment -name USE_CONFIGURATION_DEVICE On -family "MAX V" +set_global_assignment -name USE_CONFIGURATION_DEVICE On -family "MAX II" +set_global_assignment -name USE_CONFIGURATION_DEVICE Off -family "Arria II GX" +set_global_assignment -name USE_CONFIGURATION_DEVICE Off -family "Arria II GZ" +set_global_assignment -name USE_CONFIGURATION_DEVICE Off -family "Cyclone IV GX" +set_global_assignment -name USE_CONFIGURATION_DEVICE Off -family "Cyclone III LS" +set_global_assignment -name USE_CONFIGURATION_DEVICE Off -family "Stratix III" +set_global_assignment -name CYCLONEIII_CONFIGURATION_DEVICE Auto +set_global_assignment -name STRATIXII_CONFIGURATION_DEVICE Auto +set_global_assignment -name APEX20K_CONFIGURATION_DEVICE Auto +set_global_assignment -name MERCURY_CONFIGURATION_DEVICE Auto +set_global_assignment -name FLEX6K_CONFIGURATION_DEVICE Auto +set_global_assignment -name FLEX10K_CONFIGURATION_DEVICE Auto +set_global_assignment -name CYCLONE_CONFIGURATION_DEVICE Auto +set_global_assignment -name STRATIX_CONFIGURATION_DEVICE Auto +set_global_assignment -name APEX20K_CONFIG_DEVICE_JTAG_USER_CODE FFFFFFFF +set_global_assignment -name STRATIX_CONFIG_DEVICE_JTAG_USER_CODE FFFFFFFF +set_global_assignment -name MERCURY_CONFIG_DEVICE_JTAG_USER_CODE FFFFFFFF +set_global_assignment -name FLEX10K_CONFIG_DEVICE_JTAG_USER_CODE FFFFFFFF +set_global_assignment -name EPROM_USE_CHECKSUM_AS_USERCODE Off +set_global_assignment -name AUTO_INCREMENT_CONFIG_DEVICE_JTAG_USER_CODE On +set_global_assignment -name DISABLE_NCS_AND_OE_PULLUPS_ON_CONFIG_DEVICE Off +set_global_assignment -name GENERATE_TTF_FILE Off +set_global_assignment -name GENERATE_RBF_FILE Off +set_global_assignment -name GENERATE_HEX_FILE Off +set_global_assignment -name HEXOUT_FILE_START_ADDRESS 0 +set_global_assignment -name HEXOUT_FILE_COUNT_DIRECTION Up +set_global_assignment -name RESERVE_ALL_UNUSED_PINS_NO_OUTPUT_GND "As output driving an unspecified signal" +set_global_assignment -name RELEASE_CLEARS_BEFORE_TRI_STATES Off +set_global_assignment -name AUTO_RESTART_CONFIGURATION On +set_global_assignment -name HARDCOPYII_POWER_ON_EXTRA_DELAY Off +set_global_assignment -name STRATIXII_MRAM_COMPATIBILITY Off +set_global_assignment -name CYCLONEII_M4K_COMPATIBILITY On +set_global_assignment -name ENABLE_OCT_DONE Off +set_global_assignment -name USE_CHECKERED_PATTERN_AS_UNINITIALIZED_RAM_CONTENT OFF +set_global_assignment -name ARRIAIIGX_RX_CDR_LOCKUP_FIX_OVERRIDE Off +set_global_assignment -name ENABLE_AUTONOMOUS_PCIE_HIP Off +set_global_assignment -name START_TIME 0ns +set_global_assignment -name SIMULATION_MODE TIMING +set_global_assignment -name AUTO_USE_SIMULATION_PDB_NETLIST Off +set_global_assignment -name ADD_DEFAULT_PINS_TO_SIMULATION_OUTPUT_WAVEFORMS On +set_global_assignment -name SETUP_HOLD_DETECTION Off +set_global_assignment -name SETUP_HOLD_DETECTION_INPUT_REGISTERS_BIDIR_PINS_DISABLED Off +set_global_assignment -name CHECK_OUTPUTS Off +set_global_assignment -name SIMULATION_COVERAGE On +set_global_assignment -name SIMULATION_COMPLETE_COVERAGE_REPORT_PANEL On +set_global_assignment -name SIMULATION_MISSING_1_VALUE_COVERAGE_REPORT_PANEL On +set_global_assignment -name SIMULATION_MISSING_0_VALUE_COVERAGE_REPORT_PANEL On +set_global_assignment -name GLITCH_DETECTION Off +set_global_assignment -name GLITCH_INTERVAL 1ns +set_global_assignment -name SIMULATOR_GENERATE_SIGNAL_ACTIVITY_FILE Off +set_global_assignment -name SIMULATION_WITH_GLITCH_FILTERING_WHEN_GENERATING_SAF On +set_global_assignment -name SIMULATION_BUS_CHANNEL_GROUPING Off +set_global_assignment -name SIMULATION_VDB_RESULT_FLUSH On +set_global_assignment -name VECTOR_COMPARE_TRIGGER_MODE INPUT_EDGE +set_global_assignment -name SIMULATION_NETLIST_VIEWER Off +set_global_assignment -name SIMULATION_INTERCONNECT_DELAY_MODEL_TYPE TRANSPORT +set_global_assignment -name SIMULATION_CELL_DELAY_MODEL_TYPE TRANSPORT +set_global_assignment -name SIMULATOR_GENERATE_POWERPLAY_VCD_FILE Off +set_global_assignment -name SIMULATOR_PVT_TIMING_MODEL_TYPE AUTO +set_global_assignment -name SIMULATION_WITH_AUTO_GLITCH_FILTERING AUTO +set_global_assignment -name DRC_TOP_FANOUT 50 +set_global_assignment -name DRC_FANOUT_EXCEEDING 30 +set_global_assignment -name DRC_GATED_CLOCK_FEED 30 +set_global_assignment -name HARDCOPY_FLOW_AUTOMATION MIGRATION_ONLY +set_global_assignment -name ENABLE_DRC_SETTINGS Off +set_global_assignment -name CLK_RULE_CLKNET_CLKSPINES_THRESHOLD 25 +set_global_assignment -name DRC_DETAIL_MESSAGE_LIMIT 10 +set_global_assignment -name DRC_VIOLATION_MESSAGE_LIMIT 30 +set_global_assignment -name DRC_DEADLOCK_STATE_LIMIT 2 +set_global_assignment -name MERGE_HEX_FILE Off +set_global_assignment -name GENERATE_SVF_FILE Off +set_global_assignment -name GENERATE_ISC_FILE Off +set_global_assignment -name GENERATE_JAM_FILE Off +set_global_assignment -name GENERATE_JBC_FILE Off +set_global_assignment -name GENERATE_JBC_FILE_COMPRESSED On +set_global_assignment -name GENERATE_CONFIG_SVF_FILE Off +set_global_assignment -name GENERATE_CONFIG_ISC_FILE Off +set_global_assignment -name GENERATE_CONFIG_JAM_FILE Off +set_global_assignment -name GENERATE_CONFIG_JBC_FILE Off +set_global_assignment -name GENERATE_CONFIG_JBC_FILE_COMPRESSED On +set_global_assignment -name GENERATE_CONFIG_HEXOUT_FILE Off +set_global_assignment -name ISP_CLAMP_STATE_DEFAULT "Tri-state" +set_global_assignment -name SIGNALPROBE_ALLOW_OVERUSE Off +set_global_assignment -name SIGNALPROBE_DURING_NORMAL_COMPILATION Off +set_global_assignment -name POWER_DEFAULT_TOGGLE_RATE 12.5% +set_global_assignment -name POWER_DEFAULT_INPUT_IO_TOGGLE_RATE 12.5% +set_global_assignment -name POWER_USE_PVA On +set_global_assignment -name POWER_USE_INPUT_FILE "No File" +set_global_assignment -name POWER_USE_INPUT_FILES Off +set_global_assignment -name POWER_VCD_FILTER_GLITCHES On +set_global_assignment -name POWER_REPORT_SIGNAL_ACTIVITY Off +set_global_assignment -name POWER_REPORT_POWER_DISSIPATION Off +set_global_assignment -name POWER_USE_DEVICE_CHARACTERISTICS TYPICAL +set_global_assignment -name POWER_AUTO_COMPUTE_TJ On +set_global_assignment -name POWER_TJ_VALUE 25 +set_global_assignment -name POWER_USE_TA_VALUE 25 +set_global_assignment -name POWER_USE_CUSTOM_COOLING_SOLUTION Off +set_global_assignment -name POWER_BOARD_TEMPERATURE 25 +set_global_assignment -name POWER_HPS_ENABLE Off +set_global_assignment -name POWER_HPS_PROC_FREQ 0.0 +set_global_assignment -name IGNORE_PARTITIONS Off +set_global_assignment -name AUTO_EXPORT_INCREMENTAL_COMPILATION Off +set_global_assignment -name RAPID_RECOMPILE_ASSIGNMENT_CHECKING On +set_global_assignment -name OUTPUT_IO_TIMING_ENDPOINT "Near End" +set_global_assignment -name RTLV_REMOVE_FANOUT_FREE_REGISTERS On +set_global_assignment -name RTLV_SIMPLIFIED_LOGIC On +set_global_assignment -name RTLV_GROUP_RELATED_NODES On +set_global_assignment -name RTLV_GROUP_COMB_LOGIC_IN_CLOUD Off +set_global_assignment -name RTLV_GROUP_COMB_LOGIC_IN_CLOUD_TMV Off +set_global_assignment -name RTLV_GROUP_RELATED_NODES_TMV On +set_global_assignment -name EQC_CONSTANT_DFF_DETECTION On +set_global_assignment -name EQC_DUPLICATE_DFF_DETECTION On +set_global_assignment -name EQC_BBOX_MERGE On +set_global_assignment -name EQC_LVDS_MERGE On +set_global_assignment -name EQC_RAM_UNMERGING On +set_global_assignment -name EQC_DFF_SS_EMULATION On +set_global_assignment -name EQC_RAM_REGISTER_UNPACK On +set_global_assignment -name EQC_MAC_REGISTER_UNPACK On +set_global_assignment -name EQC_SET_PARTITION_BB_TO_VCC_GND On +set_global_assignment -name EQC_STRUCTURE_MATCHING On +set_global_assignment -name EQC_AUTO_BREAK_CONE On +set_global_assignment -name EQC_POWER_UP_COMPARE Off +set_global_assignment -name EQC_AUTO_COMP_LOOP_CUT On +set_global_assignment -name EQC_AUTO_INVERSION On +set_global_assignment -name EQC_AUTO_TERMINATE On +set_global_assignment -name EQC_SUB_CONE_REPORT Off +set_global_assignment -name EQC_RENAMING_RULES On +set_global_assignment -name EQC_PARAMETER_CHECK On +set_global_assignment -name EQC_AUTO_PORTSWAP On +set_global_assignment -name EQC_DETECT_DONT_CARES On +set_global_assignment -name EQC_SHOW_ALL_MAPPED_POINTS Off +set_global_assignment -name EDA_INPUT_GND_NAME GND -section_id ? +set_global_assignment -name EDA_INPUT_VCC_NAME VCC -section_id ? +set_global_assignment -name EDA_INPUT_DATA_FORMAT NONE -section_id ? +set_global_assignment -name EDA_SHOW_LMF_MAPPING_MESSAGES Off -section_id ? +set_global_assignment -name EDA_RUN_TOOL_AUTOMATICALLY Off -section_id ? +set_global_assignment -name RESYNTHESIS_RETIMING FULL -section_id ? +set_global_assignment -name RESYNTHESIS_OPTIMIZATION_EFFORT Normal -section_id ? +set_global_assignment -name RESYNTHESIS_PHYSICAL_SYNTHESIS Normal -section_id ? +set_global_assignment -name USE_GENERATED_PHYSICAL_CONSTRAINTS On -section_id ? +set_global_assignment -name VCCPD_VOLTAGE 3.3V -section_id ? +set_global_assignment -name EDA_USER_COMPILED_SIMULATION_LIBRARY_DIRECTORY "" -section_id ? +set_global_assignment -name EDA_LAUNCH_CMD_LINE_TOOL Off -section_id ? +set_global_assignment -name EDA_ENABLE_IPUTF_MODE On -section_id ? +set_global_assignment -name EDA_NATIVELINK_PORTABLE_FILE_PATHS Off -section_id ? +set_global_assignment -name EDA_NATIVELINK_GENERATE_SCRIPT_ONLY Off -section_id ? +set_global_assignment -name EDA_WAIT_FOR_GUI_TOOL_COMPLETION Off -section_id ? +set_global_assignment -name EDA_TRUNCATE_LONG_HIERARCHY_PATHS Off -section_id ? +set_global_assignment -name EDA_FLATTEN_BUSES Off -section_id ? +set_global_assignment -name EDA_MAP_ILLEGAL_CHARACTERS Off -section_id ? +set_global_assignment -name EDA_GENERATE_TIMING_CLOSURE_DATA Off -section_id ? +set_global_assignment -name EDA_GENERATE_POWER_INPUT_FILE Off -section_id ? +set_global_assignment -name EDA_TEST_BENCH_ENABLE_STATUS NOT_USED -section_id ? +set_global_assignment -name EDA_RTL_SIM_MODE NOT_USED -section_id ? +set_global_assignment -name EDA_MAINTAIN_DESIGN_HIERARCHY OFF -section_id ? +set_global_assignment -name EDA_GENERATE_FUNCTIONAL_NETLIST Off -section_id ? +set_global_assignment -name EDA_WRITE_DEVICE_CONTROL_PORTS Off -section_id ? +set_global_assignment -name EDA_SIMULATION_VCD_OUTPUT_TCL_FILE Off -section_id ? +set_global_assignment -name EDA_SIMULATION_VCD_OUTPUT_SIGNALS_TO_TCL_FILE "All Except Combinational Logic Element Outputs" -section_id ? +set_global_assignment -name EDA_ENABLE_GLITCH_FILTERING Off -section_id ? +set_global_assignment -name EDA_WRITE_NODES_FOR_POWER_ESTIMATION OFF -section_id ? +set_global_assignment -name EDA_SETUP_HOLD_DETECTION_INPUT_REGISTERS_BIDIR_PINS_DISABLED Off -section_id ? +set_global_assignment -name EDA_WRITER_DONT_WRITE_TOP_ENTITY Off -section_id ? +set_global_assignment -name EDA_VHDL_ARCH_NAME structure -section_id ? +set_global_assignment -name EDA_IBIS_MODEL_SELECTOR Off -section_id ? +set_global_assignment -name EDA_IBIS_MUTUAL_COUPLING Off -section_id ? +set_global_assignment -name EDA_FORMAL_VERIFICATION_ALLOW_RETIMING Off -section_id ? +set_global_assignment -name EDA_BOARD_BOUNDARY_SCAN_OPERATION PRE_CONFIG -section_id ? +set_global_assignment -name EDA_GENERATE_RTL_SIMULATION_COMMAND_SCRIPT Off -section_id ? +set_global_assignment -name EDA_GENERATE_GATE_LEVEL_SIMULATION_COMMAND_SCRIPT Off -section_id ? +set_global_assignment -name EDA_IBIS_SPECIFICATION_VERSION 4p1 -section_id ? +set_global_assignment -name SIM_VECTOR_COMPARED_CLOCK_OFFSET 0ns -section_id ? +set_global_assignment -name SIM_VECTOR_COMPARED_CLOCK_DUTY_CYCLE 50 -section_id ? +set_global_assignment -name APEX20K_CLIQUE_TYPE LAB -section_id ? -entity ? +set_global_assignment -name MAX7K_CLIQUE_TYPE LAB -section_id ? -entity ? +set_global_assignment -name MERCURY_CLIQUE_TYPE LAB -section_id ? -entity ? +set_global_assignment -name FLEX6K_CLIQUE_TYPE LAB -section_id ? -entity ? +set_global_assignment -name FLEX10K_CLIQUE_TYPE LAB -section_id ? -entity ? +set_global_assignment -name PARTITION_PRESERVE_HIGH_SPEED_TILES On -section_id ? -entity ? +set_global_assignment -name PARTITION_IGNORE_SOURCE_FILE_CHANGES Off -section_id ? -entity ? +set_global_assignment -name PARTITION_ALWAYS_USE_QXP_NETLIST Off -section_id ? -entity ? +set_global_assignment -name PARTITION_IMPORT_ASSIGNMENTS On -section_id ? -entity ? +set_global_assignment -name PARTITION_IMPORT_EXISTING_ASSIGNMENTS REPLACE_CONFLICTING -section_id ? -entity ? +set_global_assignment -name PARTITION_IMPORT_EXISTING_LOGICLOCK_REGIONS UPDATE_CONFLICTING -section_id ? -entity ? +set_global_assignment -name PARTITION_IMPORT_PROMOTE_ASSIGNMENTS On -section_id ? -entity ? +set_global_assignment -name ALLOW_MULTIPLE_PERSONAS Off -section_id ? -entity ? +set_global_assignment -name PARTITION_ASD_REGION_ID 1 -section_id ? -entity ? +set_global_assignment -name CROSS_BOUNDARY_OPTIMIZATIONS Off -section_id ? -entity ? +set_global_assignment -name PROPAGATE_CONSTANTS_ON_INPUTS On -section_id ? -entity ? +set_global_assignment -name PROPAGATE_INVERSIONS_ON_INPUTS On -section_id ? -entity ? +set_global_assignment -name REMOVE_LOGIC_ON_UNCONNECTED_OUTPUTS On -section_id ? -entity ? +set_global_assignment -name MERGE_EQUIVALENT_INPUTS On -section_id ? -entity ? +set_global_assignment -name MERGE_EQUIVALENT_BIDIRS On -section_id ? -entity ? +set_global_assignment -name ABSORB_PATHS_FROM_OUTPUTS_TO_INPUTS On -section_id ? -entity ? +set_global_assignment -name PARTITION_ENABLE_STRICT_PRESERVATION Off -section_id ? -entity ? diff --git a/vhdl/rtl/vhdl/Blitter/Blitter_WF.vhd b/vhdl/rtl/vhdl/Blitter/Blitter_WF.vhd new file mode 100644 index 0000000..c7274f2 --- /dev/null +++ b/vhdl/rtl/vhdl/Blitter/Blitter_WF.vhd @@ -0,0 +1,101 @@ +---------------------------------------------------------------------- +---- ---- +---- This file is part of the 'Firebee' project. ---- +---- http://acp.atari.org ---- +---- ---- +---- Description: ---- +---- This design unit provides the bit block transfer processor ---- +---- (BLITTER) of the 'Firebee' computer. ---- +---- It is optimized for the use of an Altera Cyclone ---- +---- FPGA (EP3C40F484). This IP-Core is based on the first edi- ---- +---- tion of the Firebee configware originally provided by Fredi ---- +---- Ashwanden and Wolfgang Förster. This release is in compa- ---- +---- rision to the first edition completely written in VHDL. ---- +---- ---- +---- Author(s): ---- +---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2012 Wolfgang Förster ---- +---- ---- +---- This source file 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 2 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, write to the Free ---- +---- Software Foundation, Inc., 51 Franklin Street, Fifth Floor, ---- +---- Boston, MA 02110-1301, USA. ---- +---- ---- +---------------------------------------------------------------------- +-- +-- Revision History +-- +-- Revision 2K12B 20120801 WF +-- Initial Release of the second edition. + + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity FBEE_BLITTER is + port( + RESETn : in std_logic; + CLK_MAIN : in std_logic; + CLK_DDR0 : in std_logic; + FB_ADR : in std_logic_vector(31 downto 0); + FB_ALE : in std_logic; + FB_SIZE1 : in std_logic; + FB_SIZE0 : in std_logic; + FB_CSn : in std_logic_vector(3 downto 1); + FB_OEn : in std_logic; + FB_WRn : in std_logic; + DATA_IN : in std_logic_vector(31 downto 0); + DATA_OUT : out std_logic_vector(31 downto 0); + DATA_EN : out std_logic; + BLITTER_ON : in std_logic; + BLITTER_DIN : in std_logic_vector(127 downto 0); + BLITTER_DACK_SR : in std_logic; + BLITTER_RUN : out std_logic; + BLITTER_DOUT : out std_logic_vector(127 downto 0); + BLITTER_ADR : out std_logic_vector(31 downto 0); + BLITTER_SIG : out std_logic; + BLITTER_WR : out std_logic; + BLITTER_TA : out std_logic + ); +end entity FBEE_BLITTER; + +architecture BEHAVIOUR of FBEE_BLITTER is +signal BLITTER_DACK : std_logic_vector(4 downto 0); +signal BLITTER_DIN_I : std_logic_vector(127 downto 0); +begin + + P_BLITTER_DACK: process + begin + wait until CLK_DDR0 = '1' and CLK_DDR0' event; + BLITTER_DACK <= BLITTER_DACK_SR & BLITTER_DACK(4 downto 1); + if BLITTER_DACK(0) = '1' then + BLITTER_DIN_I <= BLITTER_DIN; + end if; + end process P_BLITTER_DACK; + + + BLITTER_RUN <= '0'; + BLITTER_DOUT <= x"FEDCBA9876543210F0F0F0F0F0F0F0F0"; + DATA_OUT <= x"FEDCBA98"; + BLITTER_ADR <= x"76543210"; + BLITTER_SIG <= '0'; + BLITTER_WR <= '0'; + BLITTER_TA <= '0'; + DATA_EN <= '0'; +END BEHAVIOUR; diff --git a/vhdl/rtl/vhdl/Blitter/tmp.txt b/vhdl/rtl/vhdl/Blitter/tmp.txt new file mode 100644 index 0000000..e09ed0b --- /dev/null +++ b/vhdl/rtl/vhdl/Blitter/tmp.txt @@ -0,0 +1,75 @@ +-- WARNING: Do NOT edit the input and output ports in this file in a text +-- editor if you plan to continue editing the block that represents it in +-- the Block Editor! File corruption is VERY likely to occur. + +-- Copyright (C) 1991-2008 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. + + +-- Generated by Quartus II Version 8.1 (Build Build 163 10/28/2008) +-- Created on Fri Oct 16 15:40:59 2009 + +LIBRARY ieee; +USE ieee.std_logic_1164.all; + + +-- Entity Declaration + +ENTITY BLITTER IS + -- {{ALTERA_IO_BEGIN}} DO NOT REMOVE THIS LINE! + PORT + ( + nRSTO : IN STD_LOGIC; + MAIN_CLK : IN STD_LOGIC; + FB_ALE : IN STD_LOGIC; + nFB_WR : IN STD_LOGIC; + nFB_OE : IN STD_LOGIC; + FB_SIZE0 : IN STD_LOGIC; + FB_SIZE1 : IN STD_LOGIC; + VIDEO_RAM_CTR : IN STD_LOGIC_VECTOR(15 downto 0); + BLITTER_ON : IN STD_LOGIC; + FB_ADR : IN STD_LOGIC_VECTOR(31 downto 0); + nFB_CS1 : IN STD_LOGIC; + nFB_CS2 : IN STD_LOGIC; + nFB_CS3 : IN STD_LOGIC; + DDRCLK0 : IN STD_LOGIC; + BLITTER_DIN : IN STD_LOGIC_VECTOR(127 downto 0); + BLITTER_DACK : IN STD_LOGIC_VECTOR(4 downto 0); + BLITTER_RUN : OUT STD_LOGIC; + BLITTER_DOUT : OUT STD_LOGIC_VECTOR(127 downto 0); + BLITTER_ADR : OUT STD_LOGIC_VECTOR(31 downto 0); + BLITTER_SIG : OUT STD_LOGIC; + BLITTER_WR : OUT STD_LOGIC; + BLITTER_TA : OUT STD_LOGIC; + FB_AD : INOUT STD_LOGIC_VECTOR(31 downto 0) + ); + -- {{ALTERA_IO_END}} DO NOT REMOVE THIS LINE! + +END BLITTER; + + +-- Architecture Body + +ARCHITECTURE BLITTER_architecture OF BLITTER IS + + +BEGIN + BLITTER_RUN <= '0'; + BLITTER_DOUT <= x"FEDCBA9876543210F0F0F0F0F0F0F0F0"; + BLITTER_ADR <= x"76543210"; + BLITTER_SIG <= '0'; + BLITTER_WR <= '0'; + BLITTER_TA <= '0'; + +END BLITTER_architecture; diff --git a/vhdl/rtl/vhdl/DDR/DDR_CTRL.vhd b/vhdl/rtl/vhdl/DDR/DDR_CTRL.vhd new file mode 100644 index 0000000..9b8e5f4 --- /dev/null +++ b/vhdl/rtl/vhdl/DDR/DDR_CTRL.vhd @@ -0,0 +1,807 @@ +---------------------------------------------------------------------- +---- ---- +---- This file is part of the 'Firebee' project. ---- +---- http://acp.atari.org ---- +---- ---- +---- Description: ---- +---- This design unit provides the DDR controller of the 'Firebee'---- +---- computer. It is optimized for the use of an Altera Cyclone ---- +---- FPGA (EP3C40F484). This IP-Core is based on the first edi- ---- +---- tion of the Firebee configware originally provided by Fredi ---- +---- Ashwanden and Wolfgang Förster. This release is in compa- ---- +---- rision to the first edition completely written in VHDL. ---- +---- ---- +---- Author(s): ---- +---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2012 Fredi Aschwanden, Wolfgang Förster ---- +---- ---- +---- This source file 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 2 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, write to the Free ---- +---- Software Foundation, Inc., 51 Franklin Street, Fifth Floor, ---- +---- Boston, MA 02110-1301, USA. ---- +---- ---- +---------------------------------------------------------------------- +-- +-- Revision History +-- +-- Revision 2K12B 20120801 WF +-- Initial Release of the second edition. + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity DDR_CTRL_V1 is + port( + CLK_MAIN : in std_logic; + DDR_SYNC_66M : in std_logic; + FB_ADR : in std_logic_vector(31 downto 0); + FB_CS1n : in std_logic; + FB_OEn : in std_logic; + FB_SIZE0 : in std_logic; + FB_SIZE1 : in std_logic; + FB_ALE : in std_logic; + FB_WRn : in std_logic; + FIFO_CLR : in std_logic; + VIDEO_RAM_CTR : in std_logic_vector(15 downto 0); + BLITTER_ADR : in std_logic_vector(31 downto 0); + BLITTER_SIG : in std_logic; + BLITTER_WR : in std_logic; + DDRCLK0 : in std_logic; + CLK_33M : in std_logic; + FIFO_MW : in std_logic_vector(8 downto 0); + VA : out std_logic_vector(12 downto 0); + VWEn : out std_logic; + VRASn : out std_logic; + VCSn : out std_logic; + VCKE : out std_logic; + VCASn : out std_logic; + FB_LE : out std_logic_vector(3 downto 0); + FB_VDOE : out std_logic_vector(3 downto 0); + SR_FIFO_WRE : out std_logic; + SR_DDR_FB : out std_logic; + SR_DDR_WR : out std_logic; + SR_DDRWR_D_SEL : out std_logic; + SR_VDMP : out std_logic_vector(7 downto 0); + VIDEO_DDR_TA : out std_logic; + SR_BLITTER_DACK : out std_logic; + BA : out std_logic_vector(1 downto 0); + DDRWR_D_SEL1 : out std_logic; + VDM_SEL : out std_logic_vector(3 downto 0); + DATA_IN : in std_logic_vector(31 downto 0); + DATA_OUT : out std_logic_vector(31 downto 16); + DATA_EN_H : out std_logic; + DATA_EN_L : out std_logic + ); +end entity DDR_CTRL_V1; + +architecture BEHAVIOUR of DDR_CTRL_V1 is + -- FIFO WATER MARK: + constant FIFO_LWM : std_logic_vector(8 downto 0) := "000000000"; + constant FIFO_MWM : std_logic_vector(8 downto 0) := "011001000"; -- 200. + constant FIFO_HWM : std_logic_vector(8 downto 0) := "111110100"; -- 500. + + type ACCESS_WIDTH_TYPE is(LONG, WORD, BYTE); + type DDR_ACCESS_TYPE is(CPU, FIFO, BLITTER, NONE); + type FB_REGDDR_TYPE is(FR_WAIT,FR_S0,FR_S1,FR_S2,FR_S3); + type DDR_SM_TYPE is(DS_T1, DS_T2A, DS_T2B, DS_T3, DS_N5, DS_N6, DS_N7, DS_N8, -- Start (normal 8 cycles total = 60ns). + DS_C2, DS_C3, DS_C4, DS_C5, DS_C6, DS_C7, -- Configuration. + DS_T4R, DS_T5R, -- Read CPU or BLITTER. + DS_T4W, DS_T5W, DS_T6W, DS_T7W, DS_T8W, DS_T9W, -- Write CPU or BLITTER. + DS_T4F, DS_T5F, DS_T6F, DS_T7F, DS_T8F, DS_T9F, DS_T10F, -- Read FIFO. + DS_CB6, DS_CB8, -- Close FIFO bank. + DS_R2, DS_R3, DS_R4, DS_R5, DS_R6); -- Refresh: 10 x 7.5ns = 75ns. + + signal ACCESS_WIDTH : ACCESS_WIDTH_TYPE; + signal FB_REGDDR : FB_REGDDR_TYPE; + signal FB_REGDDR_NEXT : FB_REGDDR_TYPE; + signal DDR_ACCESS : DDR_ACCESS_TYPE; + signal DDR_STATE : DDR_SM_TYPE; + signal DDR_NEXT_STATE : DDR_SM_TYPE; + signal VCS_In : std_logic; + signal VCKE_I : std_logic; + signal BYTE_SEL : std_logic_vector(3 downto 0); + signal SR_FIFO_WRE_I : std_logic; + signal VCAS : std_logic; + signal VRAS : std_logic; + signal VWE : std_logic; + signal MCS : std_logic_vector(1 downto 0); + signal BUS_CYC : std_logic; + signal BUS_CYC_END : std_logic; + signal BLITTER_REQ : std_logic; + signal BLITTER_ROW_ADR : std_logic_vector(12 downto 0); + signal BLITTER_BA : std_logic_vector(1 downto 0); + signal BLITTER_COL_ADR : std_logic_vector(9 downto 0); + signal CPU_DDR_SYNC : std_logic; + signal CPU_ROW_ADR : std_logic_vector(12 downto 0); + signal CPU_BA : std_logic_vector(1 downto 0); + signal CPU_COL_ADR : std_logic_vector(9 downto 0); + signal CPU_REQ : std_logic; + signal DDR_SEL : std_logic; + signal DDR_CS : std_logic; + signal DDR_CONFIG : std_logic; + signal FIFO_REQ : std_logic; + signal FIFO_ROW_ADR : std_logic_vector(12 downto 0); + signal FIFO_BA : std_logic_vector(1 downto 0); + signal FIFO_COL_ADR : unsigned(9 downto 0); + signal FIFO_ACTIVE : std_logic; + signal FIFO_CLR_SYNC : std_logic; + signal VDM_SEL_I : std_logic_vector(3 downto 0); + signal CLEAR_FIFO_CNT : std_logic; + signal STOP : std_logic; + signal FIFO_BANK_OK : std_logic; + signal DDR_REFRESH_ON : std_logic; + signal DDR_REFRESH_CNT : unsigned(10 downto 0); + signal DDR_REFRESH_REQ : std_logic; + signal DDR_REFRESH_SIG : unsigned(3 downto 0); + signal REFRESH_TIME : std_logic; + signal VIDEO_BASE_L_D : std_logic_vector(7 downto 0); + signal VIDEO_BASE_L : std_logic; + signal VIDEO_BASE_M_D : std_logic_vector(7 downto 0); + signal VIDEO_BASE_M : std_logic; + signal VIDEO_BASE_H_D : std_logic_vector(7 downto 0); + signal VIDEO_BASE_H : std_logic; + signal VIDEO_BASE_X_D : std_logic_vector(2 downto 0); + signal VIDEO_ADR_CNT : unsigned(22 downto 0); + signal VIDEO_CNT_L : std_logic; + signal VIDEO_CNT_M : std_logic; + signal VIDEO_CNT_H : std_logic; + signal VIDEO_BASE_ADR : std_logic_vector(22 downto 0); + signal VIDEO_ACT_ADR : std_logic_vector(26 downto 0); + signal FB_ADR_I : std_logic_vector(32 downto 0); + + + signal VA_S : std_logic_vector(12 downto 0); + signal VA_P : std_logic_vector(12 downto 0); + signal BA_S : std_logic_vector(1 downto 0) ; + signal BA_P : std_logic_vector(1 downto 0); + signal TSIZ : std_logic_vector(1 downto 0); +begin + TSIZ <= FB_SIZE1 & FB_SIZE0; + with TSIZ select + ACCESS_WIDTH <= LONG when "11", + WORD when "00", + BYTE when others; + + -- Byte selectors: + BYTE_SEL(0) <= '1' when ACCESS_WIDTH = LONG or ACCESS_WIDTH = WORD else + '1' when FB_ADR(1 downto 0) = "00" else '0'; -- Byte 0. + + BYTE_SEL(1) <= '1' when ACCESS_WIDTH = LONG or ACCESS_WIDTH = WORD else + '1' when ACCESS_WIDTH = BYTE and FB_ADR(1) = '0' else -- High word. + '1' when FB_ADR(1 downto 0) = "01" else '0'; -- Byte 1. + + BYTE_SEL(2) <= '1' when ACCESS_WIDTH = LONG or ACCESS_WIDTH = WORD else + '1' when FB_ADR(1 downto 0) = "10" else '0'; -- Byte 2. + + BYTE_SEL(3) <= '1' when ACCESS_WIDTH = LONG or ACCESS_WIDTH = WORD else + '1' when ACCESS_WIDTH = BYTE and FB_ADR(1) = '1' else -- Low word. + '1' when FB_ADR(1 downto 0) = "11" else '0'; -- Byte 3. + + --------------------------------------------------------------------------------------------------------------------------------------------------------------- + ------------------------------------ CPU READ (REG DDR => CPU) AND WRITE (CPU => REG DDR) --------------------------------------------------------------------- + FBCTRL_REG: process + begin + wait until CLK_MAIN = '1' and CLK_MAIN' event; + FB_REGDDR <= FB_REGDDR_NEXT; + end process FBCTRL_REG; + + FBCTRL_DEC: process(FB_REGDDR, BUS_CYC, DDR_SEL, ACCESS_WIDTH, FB_WRn, DDR_CS) + begin + case FB_REGDDR is + when FR_WAIT => + if BUS_CYC = '1' then + FB_REGDDR_NEXT <= FR_S0; + elsif DDR_SEL = '1' and ACCESS_WIDTH = LONG and FB_WRn = '0' then + FB_REGDDR_NEXT <= FR_S0; + else + FB_REGDDR_NEXT <= FR_WAIT; + end if; + when FR_S0 => + if DDR_CS = '1' and ACCESS_WIDTH = LONG then + FB_REGDDR_NEXT <= FR_S1; + else + FB_REGDDR_NEXT <= FR_WAIT; + end if; + when FR_S1 => + if DDR_CS = '1' then + FB_REGDDR_NEXT <= FR_S2; + else + FB_REGDDR_NEXT <= FR_WAIT; + end if; + when FR_S2 => + if DDR_CS = '1' and BUS_CYC = '0' and ACCESS_WIDTH = LONG and FB_WRn = '0' then -- Eventually wait during long word access. + FB_REGDDR_NEXT <= FR_S2; + elsif DDR_CS = '1' then + FB_REGDDR_NEXT <= FR_S3; + else + FB_REGDDR_NEXT <= FR_WAIT; + end if; + when FR_S3 => + FB_REGDDR_NEXT <= FR_WAIT; + end case; + end process FBCTRL_DEC; + + -- Coldfire CPU access: + FB_LE(0) <= not FB_WRn when FB_REGDDR = FR_WAIT else + not FB_WRn when FB_REGDDR = FR_S0 and DDR_CS = '1' else '0'; + FB_LE(1) <= not FB_WRn when FB_REGDDR = FR_S1 and DDR_CS = '1' else '0'; + FB_LE(2) <= not FB_WRn when FB_REGDDR = FR_S2 and DDR_CS = '1' else '0'; + FB_LE(3) <= not FB_WRn when FB_REGDDR = FR_S3 and DDR_CS = '1' else '0'; + + -- Video data access: + VIDEO_DDR_TA <= '1' when FB_REGDDR = FR_S0 and DDR_CS = '1' else + '1' when FB_REGDDR = FR_S1 and DDR_CS = '1' else + '1' when FB_REGDDR = FR_S2 and FB_REGDDR_NEXT = FR_S3 else + '1' when FB_REGDDR = FR_S3 and DDR_CS = '1' else '0'; + + -- FB_VDOE # VIDEO_OE. + -- Write access for video data: + FB_VDOE(0) <= '1' when FB_REGDDR = FR_S0 and DDR_CS = '1' and FB_OEn = '0' and DDR_CONFIG = '0' and ACCESS_WIDTH = LONG else + '1' when FB_REGDDR = FR_S0 and DDR_CS = '1' and FB_OEn = '0' and DDR_CONFIG = '0' and ACCESS_WIDTH /= LONG and CLK_MAIN = '0' else '0'; + FB_VDOE(1) <= '1' when FB_REGDDR = FR_S1 and DDR_CS = '1' and FB_OEn = '0' and DDR_CONFIG = '0' else '0'; + FB_VDOE(2) <= '1' when FB_REGDDR = FR_S2 and DDR_CS = '1' and FB_OEn = '0' and DDR_CONFIG = '0' else '0'; + FB_VDOE(3) <= '1' when FB_REGDDR = FR_S3 and DDR_CS = '1' and FB_OEn = '0' and DDR_CONFIG = '0' and CLK_MAIN = '0' else '0'; + + BUS_CYC_END <= '1' when FB_REGDDR = FR_S0 and DDR_CS = '1' and ACCESS_WIDTH /= LONG else + '1' when FB_REGDDR = FR_S3 and DDR_CS = '1' else '0'; + + --------------------------------------------------------------------------------------------------------------------------------------------------------------- + ------------------------------------------------------ DDR State Machine -------------------------------------------------------------------------------------- + DDR_STATE_REG: process + begin + wait until DDRCLK0 = '1' and DDRCLK0' event; + DDR_STATE <= DDR_NEXT_STATE; + end process DDR_STATE_REG; + + DDR_STATE_DEC: process(DDR_STATE, DDR_REFRESH_REQ, CPU_DDR_SYNC, DDR_CONFIG, FB_WRn, DDR_ACCESS, BLITTER_WR, FIFO_REQ, FIFO_BANK_OK, + FIFO_MW, CPU_REQ, VIDEO_ADR_CNT, DDR_SEL, FB_SIZE1, FB_SIZE0, DATA_IN, FIFO_BA, DDR_REFRESH_SIG) + begin + case DDR_STATE is + when DS_T1 => + if DDR_REFRESH_REQ = '1' then + DDR_NEXT_STATE <= DS_R2; + elsif CPU_DDR_SYNC = '1' and DDR_CONFIG = '1' then -- Synchronous start. + DDR_NEXT_STATE <= DS_C2; + elsif CPU_DDR_SYNC = '1' and CPU_REQ = '1' then -- Synchronous start. + DDR_NEXT_STATE <= DS_T2B; + elsif CPU_DDR_SYNC = '1' then + DDR_NEXT_STATE <= DS_T2A; + else + DDR_NEXT_STATE <= DS_T1; -- Synchronize. + end if; + when DS_T2A => -- Fast access, in this case page is always not ok. + DDR_NEXT_STATE <= DS_T3; + when DS_T2B => + DDR_NEXT_STATE <= DS_T3; + when DS_T3 => + if DDR_ACCESS = CPU and FB_WRn = '0' then + DDR_NEXT_STATE <= DS_T4W; + elsif DDR_ACCESS = BLITTER and BLITTER_WR = '1' then + DDR_NEXT_STATE <= DS_T4W; + elsif DDR_ACCESS = CPU then -- CPU? + DDR_NEXT_STATE <= DS_T4R; + elsif DDR_ACCESS = FIFO then -- FIFO? + DDR_NEXT_STATE <= DS_T4F; + elsif DDR_ACCESS = BLITTER then + DDR_NEXT_STATE <= DS_T4R; + else + DDR_NEXT_STATE <= DS_N8; + end if; + -- Read: + when DS_T4R => + DDR_NEXT_STATE <= DS_T5R; + when DS_T5R => + if FIFO_REQ = '1' and FIFO_BANK_OK = '1' then -- Insert FIFO read, when bank ok. + DDR_NEXT_STATE <= DS_T6F; + else + DDR_NEXT_STATE <= DS_CB6; + end if; + -- Write: + when DS_T4W => + DDR_NEXT_STATE <= DS_T5W; + when DS_T5W => + DDR_NEXT_STATE <= DS_T6W; + when DS_T6W => + DDR_NEXT_STATE <= DS_T7W; + when DS_T7W => + DDR_NEXT_STATE <= DS_T8W; + when DS_T8W => + DDR_NEXT_STATE <= DS_T9W; + when DS_T9W => + if FIFO_REQ = '1' and FIFO_BANK_OK = '1' then + DDR_NEXT_STATE <= DS_T6F; + else + DDR_NEXT_STATE <= DS_CB6; + end if; + -- FIFO read: + when DS_T4F => + DDR_NEXT_STATE <= DS_T5F; + when DS_T5F => + if FIFO_REQ = '1' then + DDR_NEXT_STATE <= DS_T6F; + else + DDR_NEXT_STATE <= DS_CB6; -- Leave open. + end if; + when DS_T6F => + DDR_NEXT_STATE <= DS_T7F; + when DS_T7F => + if CPU_REQ = '1' and FIFO_MW > FIFO_LWM then + DDR_NEXT_STATE <= DS_CB8; -- Close bank. + elsif FIFO_REQ = '1' and VIDEO_ADR_CNT(7 downto 0) = x"FF" then -- New page? + DDR_NEXT_STATE <= DS_CB8; -- Close bank. + elsif FIFO_REQ = '1' then + DDR_NEXT_STATE <= DS_T8F; + else + DDR_NEXT_STATE <= DS_CB8; -- Close bank. + end if; + when DS_T8F => + if FIFO_MW < FIFO_LWM then -- Emergency? + DDR_NEXT_STATE <= DS_T5F; -- Yes! + else + DDR_NEXT_STATE <= DS_T9F; + end if; + when DS_T9F => + if FIFO_REQ = '1' and VIDEO_ADR_CNT(7 downto 0) = x"FF" then -- New page? + DDR_NEXT_STATE <= DS_CB6; -- Close bank. + elsif FIFO_REQ = '1' then + DDR_NEXT_STATE <= DS_T10F; + else + DDR_NEXT_STATE <= DS_CB6; -- Close bank. + end if; + when DS_T10F => + if DDR_SEL = '1' and (FB_WRn = '1' or (FB_SIZE0 and FB_SIZE1) = '0') and DATA_IN(13 downto 12) /= FIFO_BA then + DDR_NEXT_STATE <= DS_T3; + else + DDR_NEXT_STATE <= DS_T7F; + end if; + -- Configuration cycles: + when DS_C2 => + DDR_NEXT_STATE <= DS_C3; + when DS_C3 => + DDR_NEXT_STATE <= DS_C4; + when DS_C4 => + if CPU_REQ = '1' then + DDR_NEXT_STATE <= DS_C5; + else + DDR_NEXT_STATE <= DS_T1; + end if; + when DS_C5 => + DDR_NEXT_STATE <= DS_C6; + when DS_C6 => + DDR_NEXT_STATE <= DS_C7; + when DS_C7 => + DDR_NEXT_STATE <= DS_N8; + -- Close FIFO bank. + when DS_CB6 => + DDR_NEXT_STATE <= DS_N7; + when DS_CB8 => + DDR_NEXT_STATE <= DS_T1; + -- Refresh 70ns = ten cycles. + when DS_R2 => + if DDR_REFRESH_SIG = x"9" then -- One cycle delay to close all banks. + DDR_NEXT_STATE <= DS_R4; + else + DDR_NEXT_STATE <= DS_R3; + end if; + when DS_R3 => + DDR_NEXT_STATE <= DS_R4; + when DS_R4 => + DDR_NEXT_STATE <= DS_R5; + when DS_R5 => + DDR_NEXT_STATE <= DS_R6; + when DS_R6 => + DDR_NEXT_STATE <= DS_N5; + -- Loop: + when DS_N5 => + DDR_NEXT_STATE <= DS_N6; + when DS_N6 => + DDR_NEXT_STATE <= DS_N7; + when DS_N7 => + DDR_NEXT_STATE <= DS_N8; + when DS_N8 => + DDR_NEXT_STATE <= DS_T1; + end case; + end process DDR_STATE_DEC; + + P_CLK0: process + begin + wait until DDRCLK0 = '1' and DDRCLK0' event; + -- Default assignments; + DDR_ACCESS <= NONE; + SR_FIFO_WRE_I <= '0'; + SR_VDMP <= x"00"; + SR_DDR_WR <= '0'; + SR_DDRWR_D_SEL <= '0'; + + MCS <= MCS(0) & CLK_MAIN; + BLITTER_REQ <= BLITTER_SIG and not DDR_CONFIG and VCKE_I and not VCS_In; + FIFO_CLR_SYNC <= FIFO_CLR; + CLEAR_FIFO_CNT <= FIFO_CLR_SYNC or not FIFO_ACTIVE; + STOP <= FIFO_CLR_SYNC or CLEAR_FIFO_CNT; + + if FIFO_MW < FIFO_MWM then + FIFO_REQ <= '1'; + elsif FIFO_MW < FIFO_HWM and FIFO_REQ = '1' then + FIFO_REQ <= '1'; + elsif FIFO_ACTIVE = '1' and CLEAR_FIFO_CNT = '0' and STOP = '0' and DDR_CONFIG = '0' and VCKE_I = '1' and VCS_In = '0' then + FIFO_REQ <= '1'; + else + FIFO_REQ <= '1'; + end if; + + if CLEAR_FIFO_CNT = '1' then + VIDEO_ADR_CNT <= unsigned(VIDEO_BASE_ADR); + elsif SR_FIFO_WRE_I = '1' then + VIDEO_ADR_CNT <= VIDEO_ADR_CNT + 1; + end if; + + if MCS = "10" and VCKE_I = '1' and VCS_In = '0' then + CPU_DDR_SYNC <= '1'; + else + CPU_DDR_SYNC <= '0'; + end if; + + if DDR_REFRESH_SIG /= x"0" and DDR_REFRESH_ON = '1' and DDR_CONFIG = '0' and REFRESH_TIME = '1' then + DDR_REFRESH_REQ <= '1'; + else + DDR_REFRESH_REQ <= '0'; + end if; + + if DDR_REFRESH_CNT = "00000000000" and CLK_MAIN = '0' then + REFRESH_TIME <= '1'; + else + REFRESH_TIME <= '0'; + end if; + + if REFRESH_TIME = '1' and DDR_REFRESH_ON = '1' and DDR_CONFIG = '0' then + DDR_REFRESH_SIG <= x"9"; + elsif DDR_STATE = DS_R6 and DDR_REFRESH_ON = '1' and DDR_CONFIG = '0' then + DDR_REFRESH_SIG <= DDR_REFRESH_SIG - 1; + else + DDR_REFRESH_SIG <= x"0"; + end if; + + if BUS_CYC_END = '1' then + BUS_CYC <= '0'; + elsif DDR_STATE = DS_T1 and CPU_DDR_SYNC = '1' and CPU_REQ = '1' then + BUS_CYC <= '1'; + elsif DDR_STATE = DS_T2A and DDR_SEL = '1' and FB_WRn = '0' then + BUS_CYC <= '1'; + elsif DDR_STATE = DS_T2A and DDR_SEL = '1' and (FB_SIZE0 = '0' or FB_SIZE1= '0') then + BUS_CYC <= '1'; + elsif DDR_STATE = DS_T2B then + BUS_CYC <= '1'; + elsif DDR_STATE = DS_T10F and FB_WRn = '0' and DATA_IN(13 downto 12) = FIFO_BA then + BUS_CYC <= '1'; + elsif DDR_STATE = DS_T10F and (FB_SIZE0 = '0' or FB_SIZE1= '0') and DATA_IN(13 downto 12) = FIFO_BA then + BUS_CYC <= '1'; + elsif DDR_STATE = DS_C3 then + BUS_CYC <= CPU_REQ; + end if; + + if DDR_STATE = DS_T1 and CPU_DDR_SYNC = '1' and CPU_REQ = '1' then + VA_S <= CPU_ROW_ADR; + BA_S <= CPU_BA; + DDR_ACCESS <= CPU; + elsif DDR_STATE = DS_T1 and CPU_DDR_SYNC = '1' and FIFO_REQ = '1' then + VA_P <= FIFO_ROW_ADR; + BA_P <= FIFO_BA; + DDR_ACCESS <= FIFO; + elsif DDR_STATE = DS_T1 and CPU_DDR_SYNC = '1' and BLITTER_REQ = '0' then + VA_P <= BLITTER_ROW_ADR; + BA_P <= BLITTER_BA; + DDR_ACCESS <= BLITTER; + elsif DDR_STATE = DS_T2A and DDR_SEL = '1' and FB_WRn = '0' then + VA_S(10) <= '1'; + DDR_ACCESS <= CPU; + elsif DDR_STATE = DS_T2A and DDR_SEL = '1' and (FB_SIZE0 = '0' or FB_SIZE1= '0') then + VA_S(10) <= '1'; + DDR_ACCESS <= CPU; + elsif DDR_STATE = DS_T2A then + -- ?? mfro + VA_S(10) <= not (FIFO_ACTIVE and FIFO_REQ); + DDR_ACCESS <= FIFO; + FIFO_BANK_OK <= FIFO_ACTIVE and FIFO_REQ; + -- ?? mfro BLITTER_AC <= BLITTER_ACTIVE and BLITTER_REQ; + elsif DDR_STATE = DS_T2B then + FIFO_BANK_OK <= '0'; + elsif DDR_STATE = DS_T3 then + VA_S(10) <= VA_S(10); + if (FB_WRn = '0' and DDR_ACCESS = CPU) or (BLITTER_WR = '1' and DDR_ACCESS = BLITTER) then + VA_S(9 downto 0) <= CPU_COL_ADR; + BA_S <= CPU_BA; + elsif FIFO_ACTIVE = '1' then + VA_S(9 downto 0) <= std_logic_vector(FIFO_COL_ADR); + BA_S <= FIFO_BA; + elsif DDR_ACCESS = BLITTER then + VA_S(9 downto 0) <= BLITTER_COL_ADR; + BA_S <= BLITTER_BA; + end if; + elsif DDR_STATE = DS_T4R then +-- mfro SR_DDR_FB <= CPU_AC; +-- mfro SR_BLITTER_DACK <= BLITTER_AC; + elsif DDR_STATE = DS_T5R and FIFO_REQ = '1' and FIFO_BANK_OK = '1' then + VA_S(10) <= '0'; + VA_S(9 downto 0) <= std_logic_vector(FIFO_COL_ADR); + BA_S <= FIFO_BA; + elsif DDR_STATE = DS_T5R then + VA_S(10) <= '1'; + elsif DDR_STATE = DS_T4W then + VA_S(10) <= VA_S(10); +-- mfro SR_BLITTER_DACK <= BLITTER_AC; + elsif DDR_STATE = DS_T5W then + VA_S(10) <= VA_S(10); + if DDR_ACCESS = CPU then + VA_S(9 downto 0) <= CPU_COL_ADR; + BA_S <= CPU_BA; + elsif DDR_ACCESS = BLITTER then + VA_S(9 downto 0) <= BLITTER_COL_ADR; + BA_S <= BLITTER_BA; + end if; + if DDR_ACCESS = BLITTER and FB_SIZE1 = '1' and FB_SIZE0 = '1' then + SR_VDMP <= BYTE_SEL & x"F"; + elsif DDR_ACCESS = BLITTER then + SR_VDMP <= BYTE_SEL & x"0"; + else + SR_VDMP <= BYTE_SEL & x"0"; + end if; + elsif DDR_STATE = DS_T6W then + SR_DDR_WR <= '1'; + SR_DDRWR_D_SEL <= '1'; + if DDR_ACCESS = BLITTER or (FB_SIZE1 = '1' and FB_SIZE0 = '1') then + SR_VDMP <= x"FF"; + else + SR_VDMP <= x"00"; + end if; + elsif DDR_STATE = DS_T7W then + SR_DDR_WR <= '1'; + SR_DDRWR_D_SEL <= '1'; + elsif DDR_STATE = DS_T9W and FIFO_REQ = '1' and FIFO_BANK_OK = '1' then + VA_S(10) <= '0'; + VA_S(9 downto 0) <= std_logic_vector(FIFO_COL_ADR); + BA_S <= FIFO_BA; + elsif DDR_STATE = DS_T9W then + VA_S(10) <= '0'; + elsif DDR_STATE = DS_T4F then + SR_FIFO_WRE_I <= '1'; + elsif DDR_STATE = DS_T5F and FIFO_REQ = '1' and VIDEO_ADR_CNT(7 downto 0) = x"FF" then + VA_S(10) <= '1'; + elsif DDR_STATE = DS_T5F and FIFO_REQ = '1' then + VA_S(10) <= '0'; + VA_S(9 downto 0) <= std_logic_vector(FIFO_COL_ADR + "100"); + BA_S <= FIFO_BA; + elsif DDR_STATE = DS_T5F then + VA_S(10) <= '0'; + elsif DDR_STATE = DS_T6F then + SR_FIFO_WRE_I <= '1'; + elsif DDR_STATE = DS_T7F and CPU_REQ = '1' and FIFO_MW > FIFO_LWM then + VA_S(10) <= '1'; + elsif DDR_STATE = DS_T7F and FIFO_REQ = '1' and VIDEO_ADR_CNT(7 downto 0) = x"FF" then + VA_S(10) <= '1'; + elsif DDR_STATE = DS_T7F and FIFO_REQ = '1' then + VA_S(10) <= '0'; + VA_S(9 downto 0) <= std_logic_vector(FIFO_COL_ADR + "100"); + BA_S <= FIFO_BA; + elsif DDR_STATE = DS_T7F then + VA_S(10) <= '1'; + elsif DDR_STATE = DS_T9F and FIFO_REQ = '1' and VIDEO_ADR_CNT(7 downto 0) = x"FF" then + VA_S(10) <= '1'; + elsif DDR_STATE = DS_T9F and FIFO_REQ = '1' then + VA_P(10) <= '0'; + VA_P(9 downto 0) <= std_logic_vector(FIFO_COL_ADR + "100"); + BA_P <= FIFO_BA; + elsif DDR_STATE = DS_T9F then + VA_S(10) <= '1'; + elsif DDR_STATE = DS_T10F and FB_WRn = '0' and DATA_IN(13 downto 12) = FIFO_BA then + VA_S(10) <= '1'; + DDR_ACCESS <= CPU; + elsif DDR_STATE = DS_T10F and (FB_SIZE0 = '0' or FB_SIZE1= '0') and DATA_IN(13 downto 12) = FIFO_BA then + VA_S(10) <= '1'; + DDR_ACCESS <= CPU; + elsif DDR_STATE = DS_T10F then + SR_FIFO_WRE_I <= '1'; + elsif DDR_STATE = DS_C6 then + VA_S <= DATA_IN(12 downto 0); + BA_S <= DATA_IN(14 downto 13); + elsif DDR_STATE = DS_CB6 then + FIFO_BANK_OK <= '0'; + elsif DDR_STATE = DS_CB8 then + FIFO_BANK_OK <= '0'; + elsif DDR_STATE = DS_R2 then + FIFO_BANK_OK <= '0'; + else + end if; + end process P_CLK0; + + DDR_SEL <= '1' when FB_ALE = '1' and DATA_IN(31 downto 30) = "01" else '0'; + + P_DDR_CS: process + begin + wait until CLK_MAIN = '1' and CLK_MAIN' event; + if FB_ALE = '1' then + DDR_CS <= DDR_SEL; + end if; + end process P_DDR_CS; + + P_CPU_REQ: process + begin + wait until DDR_SYNC_66M = '1' and DDR_SYNC_66M' event; + if DDR_SEL = '1' and FB_WRn = '1' and DDR_CONFIG = '0' then + CPU_REQ <= '1'; + elsif DDR_SEL = '1' and FB_SIZE1 = '0' and FB_SIZE1 = '0' and DDR_CONFIG = '0' then -- Start when not config and not long word access. + CPU_REQ <= '1'; + elsif DDR_SEL = '1' and FB_SIZE1 = '0' and FB_SIZE1 = '1' and DDR_CONFIG = '0' then -- Start when not config and not long word access. + CPU_REQ <= '1'; + elsif DDR_SEL = '1' and FB_SIZE1 = '1' and FB_SIZE1 = '0' and DDR_CONFIG = '0' then -- Start when not config and not long word access. + CPU_REQ <= '1'; + elsif DDR_SEL = '1' and DDR_CONFIG = '1' then -- Config, start immediately. + CPU_REQ <= '1'; + elsif FB_REGDDR = FR_S1 and FB_WRn = '0' then -- Long word write later. + CPU_REQ <= '1'; + elsif FB_REGDDR /= FR_S1 and FB_REGDDR /= FR_S3 and BUS_CYC_END = '0' and BUS_CYC = '0' then -- Halt, bus cycle in progress or ready. + CPU_REQ <= '0'; + end if; + end process P_CPU_REQ; + + P_REFRESH: process + -- Refresh: Always 8 at a time every 7.8us. + -- 7.8us x 8 = 62.4us = 2059 -> 2048 @ 33MHz. + begin + wait until CLK_33M = '1' and CLK_33M' event; + DDR_REFRESH_CNT <= DDR_REFRESH_CNT + 1; -- Count 0 to 2047. + end process P_REFRESH; + + SR_FIFO_WRE <= SR_FIFO_WRE_I; + + VA <= DATA_IN(26 downto 14) when DDR_STATE = DS_T2A and DDR_SEL = '1' and FB_WRn = '0' else + DATA_IN(26 downto 14) when DDR_STATE = DS_T2A and DDR_SEL = '1' and (FB_SIZE0 = '0' or FB_SIZE1= '0') else + VA_P when DDR_STATE = DS_T2A else + DATA_IN(26 downto 14) when DDR_STATE = DS_T10F and FB_WRn = '0' and DATA_IN(13 downto 12) = FIFO_BA else + DATA_IN(26 downto 14) when DDR_STATE = DS_T10F and (FB_SIZE0 = '0' or FB_SIZE1= '0') and DATA_IN(13 downto 12) = FIFO_BA else + VA_P when DDR_STATE = DS_T10F else + "0010000000000" when DDR_STATE = DS_R2 and DDR_REFRESH_SIG = x"9" else VA_S; + + BA <= DATA_IN(13 downto 12) when DDR_STATE = DS_T2A and DDR_SEL = '1' and FB_WRn = '0' else + DATA_IN(13 downto 12) when DDR_STATE = DS_T2A and DDR_SEL = '1' and (FB_SIZE0 = '0' or FB_SIZE1= '0') else + BA_P when DDR_STATE = DS_T2A else + DATA_IN(13 downto 12) when DDR_STATE = DS_T10F and FB_WRn = '0' and DATA_IN(13 downto 12) = FIFO_BA else + DATA_IN(13 downto 12) when DDR_STATE = DS_T10F and (FB_SIZE0 = '0' or FB_SIZE1= '0') and DATA_IN(13 downto 12) = FIFO_BA else + BA_P when DDR_STATE = DS_T10F else BA_S; + + VRAS <= '1' when DDR_STATE = DS_T2A and DDR_SEL = '1' and FB_WRn = '0' else + '1' when DDR_STATE = DS_T2A and DDR_SEL = '1' and (FB_SIZE0 = '0' or FB_SIZE1= '0') else + '1' when DDR_STATE = DS_T2A and DDR_ACCESS = FIFO and FIFO_REQ = '1' else + '1' when DDR_STATE = DS_T2A and DDR_ACCESS = BLITTER and BLITTER_REQ = '1' else + '1' when DDR_STATE = DS_T2B else + '1' when DDR_STATE = DS_T10F and FB_WRn = '0' and DATA_IN(13 downto 12) = FIFO_BA else + '1' when DDR_STATE = DS_T10F and (FB_SIZE0 = '0' or FB_SIZE1= '0') and DATA_IN(13 downto 12) = FIFO_BA else +DATA_IN(18) and not FB_WRn and not FB_SIZE0 and not FB_SIZE1 when DDR_STATE = DS_C7 else + '1' when DDR_STATE = DS_CB6 else + '1' when DDR_STATE = DS_CB8 else + '1' when DDR_STATE = DS_R2 else '0'; + + VCAS <= '1' when DDR_STATE = DS_T4R else + '1' when DDR_STATE = DS_T6W else + '1' when DDR_STATE = DS_T4F else + '1' when DDR_STATE = DS_T6F else + '1' when DDR_STATE = DS_T8F else + '1' when DDR_STATE = DS_T10F and VRAS = '0' else + DATA_IN(17) and not FB_WRn and not FB_SIZE0 and not FB_SIZE1 when DDR_STATE = DS_C7 else + '1' when DDR_STATE = DS_R2 and DDR_REFRESH_SIG /= x"9" else '0'; + + VWE <= '1' when DDR_STATE = DS_T6W else + DATA_IN(16) and not FB_WRn and not FB_SIZE0 and not FB_SIZE1 when DDR_STATE = DS_C7 else + '1' when DDR_STATE = DS_CB6 else + '1' when DDR_STATE = DS_CB8 else + '1' when DDR_STATE = DS_R2 and DDR_REFRESH_SIG = x"9" else '0'; + + -- DDR controller: + -- VIDEO RAM CONTROL REGISTER (is in VIDEO_MUX_CTR) + -- $F0000400: BIT 0: VCKE; 1: not nVCS ;2:REFRESH ON , (0=FIFO and CNT CLEAR); + -- 3: CONFIG; 8: FIFO_ACTIVE; + VCKE <= VCKE_I; + VCKE_I <= VIDEO_RAM_CTR(0); + VCSn <= VCS_In; + VCS_In <= not VIDEO_RAM_CTR(1); + DDR_REFRESH_ON <= VIDEO_RAM_CTR(2); + DDR_CONFIG <= VIDEO_RAM_CTR(3); + FIFO_ACTIVE <= VIDEO_RAM_CTR(8); + + CPU_ROW_ADR <= FB_ADR(26 downto 14); + CPU_BA <= FB_ADR(13 downto 12); + CPU_COL_ADR <= FB_ADR(11 downto 2); + VRASn <= not VRAS; + VCASn <= not VCAS; + VWEn <= not VWE; + + DDRWR_D_SEL1 <= '1' when DDR_ACCESS = BLITTER else '0'; + + BLITTER_ROW_ADR <= BLITTER_ADR(26 downto 14); + BLITTER_BA <= BLITTER_ADR(13 downto 12); + BLITTER_COL_ADR <= BLITTER_ADR(11 downto 2); + + FIFO_ROW_ADR <= std_logic_vector(VIDEO_ADR_CNT(22 downto 10)); + FIFO_BA <= std_logic_vector(VIDEO_ADR_CNT)(9 downto 8); + FIFO_COL_ADR <= VIDEO_ADR_CNT(7 downto 0) & "00"; + + VIDEO_BASE_ADR(22 downto 20) <= VIDEO_BASE_X_D; + VIDEO_BASE_ADR(19 downto 12) <= VIDEO_BASE_H_D; + VIDEO_BASE_ADR(11 downto 4) <= VIDEO_BASE_M_D; + VIDEO_BASE_ADR(3 downto 0) <= VIDEO_BASE_L_D(7 downto 4); + + VDM_SEL <= VDM_SEL_I; + VDM_SEL_I <= VIDEO_BASE_L_D(3 downto 0); + + -- Current video address: + VIDEO_ACT_ADR(26 downto 4) <= std_logic_vector(VIDEO_ADR_CNT - unsigned(FIFO_MW)); + VIDEO_ACT_ADR(3 downto 0) <= VDM_SEL_I; + + P_VIDEO_REGS: process + -- Video registers. + begin + wait until CLK_MAIN = '1' and CLK_MAIN' event; + if VIDEO_BASE_L = '1' and FB_WRn = '0' and BYTE_SEL(1) = '1' then + VIDEO_BASE_L_D <= DATA_IN(23 downto 16); -- 16 byte boarders. + end if; + + if VIDEO_BASE_M = '1' and FB_WRn = '0' and BYTE_SEL(3) = '1' then + VIDEO_BASE_M_D <= DATA_IN(23 downto 16); + end if; + + if VIDEO_BASE_H = '1' and FB_WRn = '0' and BYTE_SEL(1) = '1' then + VIDEO_BASE_H_D <= DATA_IN(23 downto 16); + end if; + + if VIDEO_BASE_H = '1' and FB_WRn = '0' and BYTE_SEL(0) = '1' then + VIDEO_BASE_X_D <= DATA_IN(26 downto 24); + end if; + end process P_VIDEO_REGS; + + FB_ADR_I <= FB_ADR & '0'; + + VIDEO_BASE_L <= '1' when FB_CS1n = '0' and FB_ADR_I(15 downto 0) = x"820D" else '0'; -- x"FF820D". + VIDEO_BASE_M <= '1' when FB_CS1n = '0' and FB_ADR_I(15 downto 0) = x"8204" else '0'; -- x"FF8203". + VIDEO_BASE_H <= '1' when FB_CS1n = '0' and FB_ADR_I(15 downto 0) = x"8202" else '0'; -- x"FF8201". + + VIDEO_CNT_L <= '1' when FB_CS1n = '0' and FB_ADR_I(15 downto 0) = x"8208" else '0'; -- x"FF8209". + VIDEO_CNT_M <= '1' when FB_CS1n = '0' and FB_ADR_I(15 downto 0) = x"8206" else '0'; -- x"FF8207". + VIDEO_CNT_H <= '1' when FB_CS1n = '0' and FB_ADR_I(15 downto 0) = x"8204" else '0'; -- x"FF8205". + + DATA_OUT(31 downto 24) <= "00000" & VIDEO_BASE_X_D when VIDEO_BASE_H = '1' else + "00000" & VIDEO_ACT_ADR(26 downto 24) when VIDEO_CNT_H = '1' else (others => '0'); + + DATA_EN_H <= (VIDEO_BASE_H or VIDEO_CNT_H) and not FB_OEn; + + DATA_OUT(23 downto 16) <= VIDEO_BASE_L_D when VIDEO_BASE_L = '1' else + VIDEO_BASE_M_D when VIDEO_BASE_M = '1' else + VIDEO_BASE_H_D when VIDEO_BASE_H = '1' else + VIDEO_ACT_ADR(7 downto 0) when VIDEO_CNT_L = '1' else + VIDEO_ACT_ADR(15 downto 8) when VIDEO_CNT_M = '1' else + VIDEO_ACT_ADR(23 downto 16) when VIDEO_CNT_H = '1' else (others => '0'); + + DATA_EN_L <= (VIDEO_BASE_L or VIDEO_BASE_M or VIDEO_BASE_H or VIDEO_CNT_L or VIDEO_CNT_M or VIDEO_CNT_H) and not FB_OEn; +end architecture BEHAVIOUR; +-- VA : Video DDR address multiplexed. +-- VA_P : latched VA, wenn FIFO_AC, BLITTER_AC. +-- VA_S : latch for default VA. +-- BA : Video DDR bank address multiplexed. +-- BA_P : latched BA, wenn FIFO_AC, BLITTER_AC. +-- BA_S : latch for default BA. +-- +--FB_SIZE ersetzen. \ No newline at end of file diff --git a/vhdl/rtl/vhdl/DMA/dcfifo0.vhd b/vhdl/rtl/vhdl/DMA/dcfifo0.vhd new file mode 100644 index 0000000..9db22fa --- /dev/null +++ b/vhdl/rtl/vhdl/DMA/dcfifo0.vhd @@ -0,0 +1,202 @@ +-- megafunction wizard: %LPM_FIFO+% +-- GENERATION: STANDARD +-- VERSION: WM1.0 +-- MODULE: dcfifo_mixed_widths + +-- ============================================================ +-- File Name: dcfifo0.vhd +-- Megafunction Name(s): +-- dcfifo_mixed_widths +-- +-- Simulation Library Files(s): +-- altera_mf +-- ============================================================ +-- ************************************************************ +-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! +-- +-- 9.1 Build 222 10/21/2009 SJ Web Edition +-- ************************************************************ + + +--Copyright (C) 1991-2009 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. + + +LIBRARY ieee; +USE ieee.std_logic_1164.all; + +LIBRARY altera_mf; +USE altera_mf.all; + +ENTITY dcfifo0 IS + PORT + ( + aclr : IN STD_LOGIC := '0'; + data : IN STD_LOGIC_VECTOR (7 DOWNTO 0); + rdclk : IN STD_LOGIC ; + rdreq : IN STD_LOGIC ; + wrclk : IN STD_LOGIC ; + wrreq : IN STD_LOGIC ; + q : OUT STD_LOGIC_VECTOR (31 DOWNTO 0); + wrusedw : OUT STD_LOGIC_VECTOR (9 DOWNTO 0) + ); +END dcfifo0; + + +ARCHITECTURE SYN OF dcfifo0 IS + + SIGNAL sub_wire0 : STD_LOGIC_VECTOR (9 DOWNTO 0); + SIGNAL sub_wire1 : STD_LOGIC_VECTOR (31 DOWNTO 0); + + + + COMPONENT dcfifo_mixed_widths + GENERIC ( + intended_device_family : STRING; + lpm_numwords : NATURAL; + lpm_showahead : STRING; + lpm_type : STRING; + lpm_width : NATURAL; + lpm_widthu : NATURAL; + lpm_widthu_r : NATURAL; + lpm_width_r : NATURAL; + overflow_checking : STRING; + rdsync_delaypipe : NATURAL; + underflow_checking : STRING; + use_eab : STRING; + write_aclr_synch : STRING; + wrsync_delaypipe : NATURAL + ); + PORT ( + wrclk : IN STD_LOGIC ; + rdreq : IN STD_LOGIC ; + wrusedw : OUT STD_LOGIC_VECTOR (9 DOWNTO 0); + aclr : IN STD_LOGIC ; + rdclk : IN STD_LOGIC ; + q : OUT STD_LOGIC_VECTOR (31 DOWNTO 0); + wrreq : IN STD_LOGIC ; + data : IN STD_LOGIC_VECTOR (7 DOWNTO 0) + ); + END COMPONENT; + +BEGIN + wrusedw <= sub_wire0(9 DOWNTO 0); + q <= sub_wire1(31 DOWNTO 0); + + dcfifo_mixed_widths_component : dcfifo_mixed_widths + GENERIC MAP ( + intended_device_family => "Cyclone III", + lpm_numwords => 1024, + lpm_showahead => "OFF", + lpm_type => "dcfifo", + lpm_width => 8, + lpm_widthu => 10, + lpm_widthu_r => 8, + lpm_width_r => 32, + overflow_checking => "ON", + rdsync_delaypipe => 5, + underflow_checking => "ON", + use_eab => "ON", + write_aclr_synch => "OFF", + wrsync_delaypipe => 5 + ) + PORT MAP ( + wrclk => wrclk, + rdreq => rdreq, + aclr => aclr, + rdclk => rdclk, + wrreq => wrreq, + data => data, + wrusedw => sub_wire0, + q => sub_wire1 + ); + + + +END SYN; + +-- ============================================================ +-- 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 "1024" +-- Retrieval info: PRIVATE: Empty NUMERIC "1" +-- Retrieval info: PRIVATE: Full NUMERIC "1" +-- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone III" +-- Retrieval info: PRIVATE: LE_BasedFIFO NUMERIC "0" +-- Retrieval info: PRIVATE: LegacyRREQ NUMERIC "1" +-- Retrieval info: PRIVATE: MAX_DEPTH_BY_9 NUMERIC "0" +-- Retrieval info: PRIVATE: OVERFLOW_CHECKING NUMERIC "0" +-- Retrieval info: PRIVATE: Optimize NUMERIC "1" +-- 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 "8" +-- Retrieval info: PRIVATE: dc_aclr NUMERIC "1" +-- Retrieval info: PRIVATE: diff_widths NUMERIC "1" +-- Retrieval info: PRIVATE: msb_usedw NUMERIC "0" +-- Retrieval info: PRIVATE: output_width NUMERIC "32" +-- Retrieval info: PRIVATE: rsEmpty NUMERIC "0" +-- 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 "0" +-- Retrieval info: PRIVATE: wsUsedW NUMERIC "1" +-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III" +-- Retrieval info: CONSTANT: LPM_NUMWORDS NUMERIC "1024" +-- Retrieval info: CONSTANT: LPM_SHOWAHEAD STRING "OFF" +-- Retrieval info: CONSTANT: LPM_TYPE STRING "dcfifo" +-- Retrieval info: CONSTANT: LPM_WIDTH NUMERIC "8" +-- Retrieval info: CONSTANT: LPM_WIDTHU NUMERIC "10" +-- Retrieval info: CONSTANT: LPM_WIDTHU_R NUMERIC "8" +-- Retrieval info: CONSTANT: LPM_WIDTH_R NUMERIC "32" +-- 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 "OFF" +-- 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 8 0 INPUT NODEFVAL data[7..0] +-- Retrieval info: USED_PORT: q 0 0 32 0 OUTPUT NODEFVAL q[31..0] +-- Retrieval info: USED_PORT: rdclk 0 0 0 0 INPUT NODEFVAL rdclk +-- 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: wrreq 0 0 0 0 INPUT NODEFVAL wrreq +-- Retrieval info: USED_PORT: wrusedw 0 0 10 0 OUTPUT NODEFVAL wrusedw[9..0] +-- Retrieval info: CONNECT: @data 0 0 8 0 data 0 0 8 0 +-- Retrieval info: CONNECT: q 0 0 32 0 @q 0 0 32 0 +-- Retrieval info: CONNECT: @wrreq 0 0 0 0 wrreq 0 0 0 0 +-- Retrieval info: CONNECT: @rdreq 0 0 0 0 rdreq 0 0 0 0 +-- Retrieval info: CONNECT: @rdclk 0 0 0 0 rdclk 0 0 0 0 +-- Retrieval info: CONNECT: @wrclk 0 0 0 0 wrclk 0 0 0 0 +-- Retrieval info: CONNECT: wrusedw 0 0 10 0 @wrusedw 0 0 10 0 +-- Retrieval info: CONNECT: @aclr 0 0 0 0 aclr 0 0 0 0 +-- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all +-- Retrieval info: GEN_FILE: TYPE_NORMAL dcfifo0.vhd TRUE +-- Retrieval info: GEN_FILE: TYPE_NORMAL dcfifo0.inc FALSE +-- Retrieval info: GEN_FILE: TYPE_NORMAL dcfifo0.cmp TRUE +-- Retrieval info: GEN_FILE: TYPE_NORMAL dcfifo0.bsf TRUE FALSE +-- Retrieval info: GEN_FILE: TYPE_NORMAL dcfifo0_inst.vhd FALSE +-- Retrieval info: GEN_FILE: TYPE_NORMAL dcfifo0_waveforms.html FALSE +-- Retrieval info: GEN_FILE: TYPE_NORMAL dcfifo0_wave*.jpg FALSE +-- Retrieval info: LIB_FILE: altera_mf diff --git a/vhdl/rtl/vhdl/DMA/dcfifo1.vhd b/vhdl/rtl/vhdl/DMA/dcfifo1.vhd new file mode 100644 index 0000000..d05dd0a --- /dev/null +++ b/vhdl/rtl/vhdl/DMA/dcfifo1.vhd @@ -0,0 +1,202 @@ +-- megafunction wizard: %LPM_FIFO+% +-- GENERATION: STANDARD +-- VERSION: WM1.0 +-- MODULE: dcfifo_mixed_widths + +-- ============================================================ +-- File Name: dcfifo1.vhd +-- Megafunction Name(s): +-- dcfifo_mixed_widths +-- +-- Simulation Library Files(s): +-- altera_mf +-- ============================================================ +-- ************************************************************ +-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! +-- +-- 9.1 Build 222 10/21/2009 SJ Web Edition +-- ************************************************************ + + +--Copyright (C) 1991-2009 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. + + +LIBRARY ieee; +USE ieee.std_logic_1164.all; + +LIBRARY altera_mf; +USE altera_mf.all; + +ENTITY dcfifo1 IS + PORT + ( + aclr : IN STD_LOGIC := '0'; + data : IN STD_LOGIC_VECTOR (31 DOWNTO 0); + rdclk : IN STD_LOGIC ; + rdreq : IN STD_LOGIC ; + wrclk : IN STD_LOGIC ; + wrreq : IN STD_LOGIC ; + q : OUT STD_LOGIC_VECTOR (7 DOWNTO 0); + rdusedw : OUT STD_LOGIC_VECTOR (9 DOWNTO 0) + ); +END dcfifo1; + + +ARCHITECTURE SYN OF dcfifo1 IS + + SIGNAL sub_wire0 : STD_LOGIC_VECTOR (7 DOWNTO 0); + SIGNAL sub_wire1 : STD_LOGIC_VECTOR (9 DOWNTO 0); + + + + COMPONENT dcfifo_mixed_widths + GENERIC ( + intended_device_family : STRING; + lpm_numwords : NATURAL; + lpm_showahead : STRING; + lpm_type : STRING; + lpm_width : NATURAL; + lpm_widthu : NATURAL; + lpm_widthu_r : NATURAL; + lpm_width_r : NATURAL; + overflow_checking : STRING; + rdsync_delaypipe : NATURAL; + underflow_checking : STRING; + use_eab : STRING; + write_aclr_synch : STRING; + wrsync_delaypipe : NATURAL + ); + PORT ( + wrclk : IN STD_LOGIC ; + rdreq : IN STD_LOGIC ; + aclr : IN STD_LOGIC ; + rdclk : IN STD_LOGIC ; + q : OUT STD_LOGIC_VECTOR (7 DOWNTO 0); + wrreq : IN STD_LOGIC ; + data : IN STD_LOGIC_VECTOR (31 DOWNTO 0); + rdusedw : OUT STD_LOGIC_VECTOR (9 DOWNTO 0) + ); + END COMPONENT; + +BEGIN + q <= sub_wire0(7 DOWNTO 0); + rdusedw <= sub_wire1(9 DOWNTO 0); + + dcfifo_mixed_widths_component : dcfifo_mixed_widths + GENERIC MAP ( + intended_device_family => "Cyclone III", + lpm_numwords => 256, + lpm_showahead => "OFF", + lpm_type => "dcfifo", + lpm_width => 32, + lpm_widthu => 8, + lpm_widthu_r => 10, + lpm_width_r => 8, + overflow_checking => "ON", + rdsync_delaypipe => 5, + underflow_checking => "ON", + use_eab => "ON", + write_aclr_synch => "OFF", + wrsync_delaypipe => 5 + ) + PORT MAP ( + wrclk => wrclk, + rdreq => rdreq, + aclr => aclr, + rdclk => rdclk, + wrreq => wrreq, + data => data, + q => sub_wire0, + rdusedw => sub_wire1 + ); + + + +END SYN; + +-- ============================================================ +-- 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 III" +-- Retrieval info: PRIVATE: LE_BasedFIFO NUMERIC "0" +-- Retrieval info: PRIVATE: LegacyRREQ NUMERIC "1" +-- Retrieval info: PRIVATE: MAX_DEPTH_BY_9 NUMERIC "0" +-- Retrieval info: PRIVATE: OVERFLOW_CHECKING NUMERIC "0" +-- Retrieval info: PRIVATE: Optimize NUMERIC "1" +-- 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 "32" +-- Retrieval info: PRIVATE: dc_aclr NUMERIC "1" +-- Retrieval info: PRIVATE: diff_widths NUMERIC "1" +-- Retrieval info: PRIVATE: msb_usedw NUMERIC "0" +-- Retrieval info: PRIVATE: output_width NUMERIC "8" +-- Retrieval info: PRIVATE: rsEmpty NUMERIC "0" +-- Retrieval info: PRIVATE: rsFull NUMERIC "0" +-- Retrieval info: PRIVATE: rsUsedW NUMERIC "1" +-- 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 "0" +-- Retrieval info: PRIVATE: wsUsedW NUMERIC "0" +-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III" +-- Retrieval info: CONSTANT: LPM_NUMWORDS NUMERIC "256" +-- Retrieval info: CONSTANT: LPM_SHOWAHEAD STRING "OFF" +-- Retrieval info: CONSTANT: LPM_TYPE STRING "dcfifo" +-- Retrieval info: CONSTANT: LPM_WIDTH NUMERIC "32" +-- Retrieval info: CONSTANT: LPM_WIDTHU NUMERIC "8" +-- Retrieval info: CONSTANT: LPM_WIDTHU_R NUMERIC "10" +-- Retrieval info: CONSTANT: LPM_WIDTH_R 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 "OFF" +-- 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 32 0 INPUT NODEFVAL data[31..0] +-- Retrieval info: USED_PORT: q 0 0 8 0 OUTPUT NODEFVAL q[7..0] +-- Retrieval info: USED_PORT: rdclk 0 0 0 0 INPUT NODEFVAL rdclk +-- Retrieval info: USED_PORT: rdreq 0 0 0 0 INPUT NODEFVAL rdreq +-- Retrieval info: USED_PORT: rdusedw 0 0 10 0 OUTPUT NODEFVAL rdusedw[9..0] +-- Retrieval info: USED_PORT: wrclk 0 0 0 0 INPUT NODEFVAL wrclk +-- Retrieval info: USED_PORT: wrreq 0 0 0 0 INPUT NODEFVAL wrreq +-- Retrieval info: CONNECT: @data 0 0 32 0 data 0 0 32 0 +-- Retrieval info: CONNECT: q 0 0 8 0 @q 0 0 8 0 +-- Retrieval info: CONNECT: @wrreq 0 0 0 0 wrreq 0 0 0 0 +-- Retrieval info: CONNECT: @rdreq 0 0 0 0 rdreq 0 0 0 0 +-- Retrieval info: CONNECT: @rdclk 0 0 0 0 rdclk 0 0 0 0 +-- Retrieval info: CONNECT: @wrclk 0 0 0 0 wrclk 0 0 0 0 +-- Retrieval info: CONNECT: rdusedw 0 0 10 0 @rdusedw 0 0 10 0 +-- Retrieval info: CONNECT: @aclr 0 0 0 0 aclr 0 0 0 0 +-- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all +-- Retrieval info: GEN_FILE: TYPE_NORMAL dcfifo1.vhd TRUE +-- Retrieval info: GEN_FILE: TYPE_NORMAL dcfifo1.inc FALSE +-- Retrieval info: GEN_FILE: TYPE_NORMAL dcfifo1.cmp TRUE +-- Retrieval info: GEN_FILE: TYPE_NORMAL dcfifo1.bsf TRUE FALSE +-- Retrieval info: GEN_FILE: TYPE_NORMAL dcfifo1_inst.vhd FALSE +-- Retrieval info: GEN_FILE: TYPE_NORMAL dcfifo1_waveforms.html FALSE +-- Retrieval info: GEN_FILE: TYPE_NORMAL dcfifo1_wave*.jpg FALSE +-- Retrieval info: LIB_FILE: altera_mf diff --git a/vhdl/rtl/vhdl/DMA/fbee_dma.vhd b/vhdl/rtl/vhdl/DMA/fbee_dma.vhd new file mode 100644 index 0000000..efd39fb --- /dev/null +++ b/vhdl/rtl/vhdl/DMA/fbee_dma.vhd @@ -0,0 +1,589 @@ +---------------------------------------------------------------------- +---- ---- +---- This file is part of the 'Firebee' project. ---- +---- http://acp.atari.org ---- +---- ---- +---- Description: ---- +---- This design unit provides the DMA controller of the 'Firebee'---- +---- computer. It is optimized for the use of an Altera Cyclone ---- +---- FPGA (EP3C40F484). This IP-Core is based on the first edi- ---- +---- tion of the Firebee configware originally provided by Fredi ---- +---- Ashwanden and Wolfgang Förster. This release is in compa- ---- +---- rision to the first edition completely written in VHDL. ---- +---- ---- +---- Author(s): ---- +---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2012 Fredi Aschwanden, Wolfgang Förster ---- +---- ---- +---- This source file 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 2 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, write to the Free ---- +---- Software Foundation, Inc., 51 Franklin Street, Fifth Floor, ---- +---- Boston, MA 02110-1301, USA. ---- +---- ---- +---------------------------------------------------------------------- +-- +-- Revision History +-- +-- Revision 2K12B 20120801 WF +-- Initial Release of the second edition. + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + +entity FBEE_DMA is + port( + RESET : in std_logic; + CLK_MAIN : in std_logic; + CLK_FDC : in std_logic; + + FB_ADR : in std_logic_vector(26 downto 0); + FB_ALE : in std_logic; + FB_SIZE : in std_logic_vector(1 downto 0); + FB_CSn : in std_logic_vector(2 downto 1); + FB_OEn : in std_logic; + FB_WRn : in std_logic; + FB_AD_IN : in std_logic_vector(31 downto 0); + FB_AD_OUT : out std_logic_vector(31 downto 0); + FB_AD_EN_31_24 : out std_logic; + FB_AD_EN_23_16 : out std_logic; + FB_AD_EN_15_8 : out std_logic; + FB_AD_EN_7_0 : out std_logic; + + ACSI_DIR : out std_logic; + ACSI_D_IN : in std_logic_vector(7 downto 0); + ACSI_D_OUT : out std_logic_vector(7 downto 0); + ACSI_D_EN : out std_logic; + ACSI_CSn : out std_logic; + ACSI_A1 : out std_logic; + ACSI_RESETn : out std_logic; + ACSI_DRQn : in std_logic; + ACSI_ACKn : out std_logic; + + DATA_IN_FDC : in std_logic_vector(7 downto 0); + DATA_IN_SCSI : in std_logic_vector(7 downto 0); + DATA_OUT_FDC_SCSI : out std_logic_vector(7 downto 0); + + DMA_DRQ_IN : in std_logic; -- From 1772. + DMA_DRQ_OUT : out std_logic; -- To Interrupt handler. + DMA_DRQ11 : out std_logic; -- To MFP. + + SCSI_DRQ : in std_logic; + SCSI_DACKn : out std_logic; + SCSI_INT : in std_logic; + SCSI_CSn : out std_logic; + SCSI_CS : out std_logic; + + CA : out std_logic_vector(2 downto 0); + FLOPPY_HD_DD : in std_logic; + WDC_BSL0 : out std_logic; + FDC_CSn : out std_logic; + FDC_WRn : out std_logic; + FD_INT : in std_logic; + IDE_INT : in std_logic; + DMA_CS : out std_logic + ); +end entity FBEE_DMA; + +architecture BEHAVIOUR of FBEE_DMA is + component dcfifo0 is + port( + aclr : in std_logic := '0'; + data : in std_logic_vector (7 downto 0); + rdclk : in std_logic ; + rdreq : in std_logic ; + wrclk : in std_logic ; + wrreq : in std_logic ; + q : out std_logic_vector (31 downto 0); + wrusedw : out std_logic_vector (9 downto 0) + ); + end component; + + component dcfifo1 is + port( + aclr : in std_logic := '0'; + data : in std_logic_vector (31 downto 0); + rdclk : in std_logic ; + rdreq : in std_logic ; + wrclk : in std_logic ; + wrreq : in std_logic ; + q : out std_logic_vector (7 downto 0); + rdusedw : out std_logic_vector (9 downto 0) + ); + end component; + + type FCF_STATES is( FCF_IDLE, FCF_T0, FCF_T1, FCF_T2, FCF_T3, FCF_T6, FCF_T7); + signal FCF_STATE : FCF_STATES; + signal NEXT_FCF_STATE : FCF_STATES; + signal FCF_CS : std_logic; + signal FCF_APH : std_logic; + + signal DMA_MODE_CS : std_logic; + signal DMA_DATA_CS : std_logic; + signal DMA_MODE : std_logic_vector(15 downto 0); + signal DMA_DRQQ : std_logic; + signal DMA_DRQ11_I : std_logic; + signal DMA_REQ : std_logic; + signal DMA_ACTIVE : std_logic; + signal DMA_ACTIVE_NEW : std_logic; + signal DMA_DRQ_REG : std_logic_vector(1 downto 0); + signal DMA_STATUS : std_logic_vector(2 downto 0); + signal DMA_AZ_CS : std_logic; + + signal DMA_BYTECNT_CS : std_logic; + signal DMA_DIRECT_CS : std_logic; + signal DMA_TOP_CS : std_logic; + signal DMA_HIGH_CS : std_logic; + signal DMA_MID_CS : std_logic; + signal DMA_LOW_CS : std_logic; + signal DMA_ADR_CS : std_logic; + signal DMA_BYTECNT : std_logic_vector(31 downto 0); + signal DMA_TOP : std_logic_vector(7 downto 0); + signal DMA_HIGH : std_logic_vector(7 downto 0); + signal DMA_MID : std_logic_vector(7 downto 0); + signal DMA_LOW : std_logic_vector(7 downto 0); + + signal DMA_SND_CS : std_logic; + signal SNDMACTL : std_logic_vector(7 downto 0); + signal SNDBASHI : std_logic_vector(7 downto 0); + signal SNDBASMI : std_logic_vector(7 downto 0); + signal SNDBASLO : std_logic_vector(7 downto 0); + signal SNDADRHI : std_logic_vector(7 downto 0); + signal SNDADRMI : std_logic_vector(7 downto 0); + signal SNDADRLO : std_logic_vector(7 downto 0); + signal SNDENDHI : std_logic_vector(7 downto 0); + signal SNDENDMI : std_logic_vector(7 downto 0); + signal SNDENDLO : std_logic_vector(7 downto 0); + signal SNDMODE : std_logic_vector(7 downto 0); + + signal WDC_BSL : std_logic_vector(1 downto 0); + signal FDC_CS_In : std_logic; + signal CLR_FIFO : std_logic; + signal FDC_OUT : std_logic_vector(7 downto 0); + signal RDF_DIN : std_logic_vector(7 downto 0); + signal RDF_DOUT : std_logic_vector(31 downto 0); + signal RDF_AZ : std_logic_vector(9 downto 0); + signal RDF_RDE : std_logic; + signal RDF_WRE : std_logic; + signal WRF_DATA_OUT : std_logic_vector(7 downto 0); + signal WRF_AZ : std_logic_vector(9 downto 0); + signal WRF_RDE : std_logic; + signal WRF_WRE : std_logic; + signal WDC_BSL_CS : std_logic; + signal CA_I : std_logic_vector(2 downto 0); + signal FDC_CS : std_logic; + signal SCSI_CS_I : std_logic; + signal LONG : std_logic; + signal BYTE : std_logic; + signal FB_B1 : std_logic; + signal FB_B0 : std_logic; + signal WRF_DOUT : std_logic_vector(7 downto 0); + signal FB_AD_I : std_logic_vector(7 downto 0); + signal d : std_logic_vector(31 downto 0); +begin + LONG <= '1' when FB_SIZE(1) = '0' and FB_SIZE(0) = '0' else '0'; + BYTE <= '1' when FB_SIZE(1) = '0' and FB_SIZE(0) = '1' else '0'; + FB_B0 <= '1' when FB_ADR(0) = '0' or BYTE = '0' else '0'; + FB_B1 <= '1' when FB_ADR(0) = '1' or BYTE = '0' else '0'; + + FB_AD_OUT(31 downto 24) <= DMA_TOP when DMA_TOP_CS = '1' and FB_OEn = '0' else + x"00" when DMA_DATA_CS = '1' and FB_OEn = '0' else + DMA_TOP when DMA_ADR_CS = '1' and FB_OEn = '0' else + DMA_BYTECNT(31 downto 24) when DMA_BYTECNT_CS = '1' and FB_OEn = '0' else + DMA_MODE(15 downto 8) when DMA_DIRECT_CS = '1' and FB_OEn = '0' else + x"00" when DMA_MODE_CS = '1' and FB_OEn = '0' else + DMA_DRQ11_I & DMA_DRQ_REG & IDE_INT & FD_INT & SCSI_INT & RDF_AZ(9 downto 8) when DMA_AZ_CS = '1' and FB_OEn = '0' else + RDF_DOUT(7 downto 0) when FCF_CS = '1' and FB_OEn = '0' else x"00"; + + FB_AD_OUT(23 downto 16) <= "00000" & DMA_STATUS when DMA_MODE_CS = '1' and FB_OEn = '0' else + FDC_OUT when DMA_DATA_CS = '1' and DMA_MODE(4 downto 3) = "00" and FB_OEn = '0' else + DATA_IN_SCSI when DMA_DATA_CS = '1' and DMA_MODE(4 downto 3) = "01" and FB_OEn = '0' else + DMA_BYTECNT(16 downto 9) when DMA_DATA_CS = '1' and DMA_MODE(4) = '1' and FB_OEn = '0' else + "0000" & (not DMA_STATUS(1)) & "0" & WDC_BSL(1) & FLOPPY_HD_DD when WDC_BSL_CS = '1' and FB_OEn = '0' else + RDF_AZ(7 downto 0) when DMA_AZ_CS = '1' and FB_OEn = '0' else + SNDMACTL when DMA_SND_CS = '1' and FB_ADR(5 downto 1) = x"0" and FB_OEn = '0' else + SNDBASHI when DMA_SND_CS = '1' and FB_ADR(5 downto 1) = x"1" and FB_OEn = '0' else + SNDBASMI when DMA_SND_CS = '1' and FB_ADR(5 downto 1) = x"2" and FB_OEn = '0' else + SNDBASLO when DMA_SND_CS = '1' and FB_ADR(5 downto 1) = x"3" and FB_OEn = '0' else + SNDADRHI when DMA_SND_CS = '1' and FB_ADR(5 downto 1) = x"4" and FB_OEn = '0' else + SNDADRMI when DMA_SND_CS = '1' and FB_ADR(5 downto 1) = x"5" and FB_OEn = '0' else + SNDADRLO when DMA_SND_CS = '1' and FB_ADR(5 downto 1) = x"6" and FB_OEn = '0' else + SNDENDHI when DMA_SND_CS = '1' and FB_ADR(5 downto 1) = x"7" and FB_OEn = '0' else + SNDENDMI when DMA_SND_CS = '1' and FB_ADR(5 downto 1) = x"8" and FB_OEn = '0' else + SNDENDLO when DMA_SND_CS = '1' and FB_ADR(5 downto 1) = x"9" and FB_OEn = '0' else + SNDMODE when DMA_SND_CS = '1' and FB_ADR(5 downto 1) = x"10" and FB_OEn = '0' else + DMA_HIGH when DMA_HIGH_CS = '1' and FB_OEn = '0' else + DMA_MID when DMA_MID_CS = '1' and FB_OEn = '0' else + DMA_LOW when DMA_LOW_CS = '1' and FB_OEn = '0' else + DMA_MODE(7 downto 0) when DMA_DIRECT_CS = '1' and FB_OEn = '0' else + DMA_HIGH when DMA_ADR_CS = '1' and FB_OEn = '0' else + DMA_BYTECNT(23 downto 16) when DMA_BYTECNT_CS = '1' and FB_OEn = '0' else + RDF_DOUT(15 downto 8) when FCF_CS = '1' and FB_OEn = '0' else x"00"; + + FB_AD_OUT(15 downto 8) <= "0" & DMA_STATUS & "00" & WRF_AZ(9 downto 8) when DMA_AZ_CS = '1' and FB_OEn = '0' else + DMA_MID when DMA_ADR_CS = '1' and FB_OEn = '0' else + DMA_BYTECNT(15 downto 8) when DMA_BYTECNT_CS = '1' and FB_OEn = '0' else + RDF_DOUT(23 downto 16) when FCF_CS = '1' and FB_OEn = '0' else x"00"; + + FB_AD_OUT(7 downto 0) <= WRF_AZ(7 downto 0) when DMA_AZ_CS = '1' and FB_OEn = '0' else + DMA_LOW when DMA_ADR_CS = '1' and FB_OEn = '0' else + DMA_BYTECNT(7 downto 0) when DMA_BYTECNT_CS = '1' and FB_OEn = '0' else + RDF_DOUT(31 downto 24) when FCF_CS = '1' and FB_OEn = '0' else x"00"; + + FB_AD_EN_31_24 <= (DMA_TOP_CS or DMA_DATA_CS or DMA_ADR_CS or DMA_BYTECNT_CS or DMA_DIRECT_CS or + DMA_MODE_CS or DMA_AZ_CS or FCF_CS) and not FB_OEn; + + FB_AD_EN_23_16 <= (DMA_MODE_CS or DMA_DATA_CS or WDC_BSL_CS or DMA_AZ_CS or DMA_SND_CS or DMA_HIGH_CS or + DMA_MID_CS or DMA_LOW_CS or DMA_DIRECT_CS or DMA_ADR_CS or DMA_BYTECNT_CS or FCF_CS) and not FB_OEn; + + FB_AD_EN_15_8 <= (DMA_AZ_CS or DMA_ADR_CS or DMA_BYTECNT_CS or FCF_CS) and not FB_OEn; + + FB_AD_EN_7_0 <= (DMA_AZ_CS or DMA_ADR_CS or DMA_BYTECNT_CS or FCF_CS) and not FB_OEn; + + INBUFFER: process(CLK_MAIN) + begin + if rising_edge(CLK_MAIN) then + if FB_WRn = '0' THEN + FB_AD_I <= FB_AD_IN(23 downto 16); + end if; + end if; + end process INBUFFER; + + -- ACSI is currently disabled. + ACSI_DIR <= '0'; + ACSI_D_OUT <= x"00"; + ACSI_D_EN <= '0'; + ACSI_CSn <= '1'; + ACSI_A1 <= CA_I(1); + ACSI_RESETn <= not RESET; + ACSI_ACKn <= '1'; + + SCSI_CS <= SCSI_CS_I; + + DMA_MODE_CS <= '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 1) = x"7C303" else '0'; -- F8606/2 + DMA_DATA_CS <= '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 1) = x"7C302" else '0'; -- F8604/2 + FDC_CS <= '1' when DMA_DATA_CS = '1' and DMA_MODE(4 downto 3) = "00" and FB_B1 = '1' else '0'; + SCSI_CS_I <= '1' when DMA_DATA_CS = '1' and DMA_MODE(4 downto 3) = "01" and FB_B1 = '1' else '0'; + DMA_AZ_CS <= '1' when FB_CSn(2) = '0' and FB_ADR(26 downto 0) = x"002010C" else '0'; -- F002'010C LONG + DMA_TOP_CS <= '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 1) = x"7C304" and FB_B0 = '1' else '0'; -- F8608/2 + DMA_HIGH_CS <= '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 1) = x"7C304" and FB_B1 = '1' else '0'; -- F8609/2 + DMA_MID_CS <= '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 1) = x"7C305" and FB_B1 = '1' else '0'; -- F860B/2 + DMA_LOW_CS <= '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 1) = x"7C306" and FB_B1 = '1' else '0'; -- F860D/2 + DMA_DIRECT_CS <= '1' when FB_CSn(2) = '0' and FB_ADR(26 downto 0) = x"20100" else '0'; -- F002'0100 WORD + DMA_ADR_CS <= '1' when FB_CSn(2) = '0' and FB_ADR(26 downto 0) = x"20104" else '0'; -- F002'0104 LONG + DMA_BYTECNT_CS <= '1' when FB_CSn(2) = '0' and FB_ADR(26 downto 0) = x"20108" else '0'; -- F002'0108 LONG + DMA_SND_CS <= '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 6) = x"3E24" else '0'; -- F8900-F893F + FCF_CS <= '1' when FB_CSn(2) = '0' and FB_ADR(26 downto 0) = x"0020110" and LONG = '1' else '0'; -- F002'0110 LONG ONLY + DMA_CS <= FCF_CS or DMA_MODE_CS or DMA_SND_CS or DMA_ADR_CS or DMA_DIRECT_CS or DMA_BYTECNT_CS; + WDC_BSL_CS <= '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 1) = x"7C307" else '0'; -- F860E/2 + + FCF_APH <= '1' when FB_ALE = '1' and FB_AD_IN(31 downto 0) = x"F0020110" and LONG = '1' else '0'; -- ADRESSPHASE F0020110 LONG ONLY + + RDF_DIN <= DATA_IN_FDC when DMA_MODE(7) = '1' else DATA_IN_SCSI; + RDF_RDE <= '1' when FCF_APH = '1' and FB_WRn = '1' else '0'; -- AKTIVIEREN IN ADRESSPHASE + + DATA_OUT_FDC_SCSI <= WRF_DOUT when DMA_ACTIVE = '1' and DMA_MODE(8) = '1' else FB_AD_I; -- BEI DMA WRITE <-FIFO SONST <-FB + + CA_I(0) <= '1' when DMA_ACTIVE = '1' else DMA_MODE(0); + CA_I(1) <= '1' when DMA_ACTIVE = '1' else DMA_MODE(1); + CA_I(2) <= '1' when DMA_ACTIVE = '1' else DMA_MODE(2); + CA <= CA_I; + + FDC_WRn <= (not DMA_MODE(8)) when DMA_ACTIVE = '1' else FB_WRn; + + DMA_MODE_REGISTER: process(RESET, CLK_MAIN) + begin + if RESET = '1' then + DMA_MODE <= x"0000"; + elsif rising_edge(CLK_MAIN) then + if DMA_MODE_CS = '1' and FB_WRn = '0' and FB_B0 = '1' then + DMA_MODE(15 downto 8) <= FB_AD_IN(31 downto 24); + elsif DMA_MODE_CS = '1' and FB_WRn = '0' and FB_B1 = '1' then + DMA_MODE(7 downto 0) <= FB_AD_IN(23 downto 16); + end if; + end if; + end process DMA_MODE_REGISTER; + + BYTECOUNTER: process(RESET, CLR_FIFO, CLK_MAIN) + begin + if RESET = '1' or CLR_FIFO = '1' THEN + DMA_BYTECNT <= x"00000000"; + elsif rising_edge(CLK_MAIN) then + if DMA_DATA_CS = '1' and FB_WRn = '0' and DMA_MODE(4) = '1' and FB_B1 = '1' then + DMA_BYTECNT(31 downto 17) <= "000000000000000"; + DMA_BYTECNT(16 downto 9) <= FB_AD_IN(23 downto 16); + DMA_BYTECNT(8 downto 0) <= "000000000"; + elsif DMA_BYTECNT_CS = '1' and FB_WRn = '0' then + DMA_BYTECNT <= FB_AD_IN; + end if; + end if; + end process BYTECOUNTER; + + WDC_BSL_REG: process(RESET, CLK_MAIN) + begin + if RESET = '1' THEN + WDC_BSL <= "00"; + elsif rising_edge(CLK_MAIN) then + if WDC_BSL_CS = '1' and FB_WRn = '0' and FB_B0 = '1' then + WDC_BSL <= FB_AD_IN(25 downto 24); + end if; + WDC_BSL0 <= WDC_BSL(0); + end if; + end process WDC_BSL_REG; + +-- Rausoptimieren? + FDC_REG: process(RESET, CLK_FDC, FDC_CS_In) + begin + if RESET = '1' then + FDC_OUT <= x"00"; + elsif rising_edge(CLK_FDC) then + if FDC_CS_In = '0' then + FDC_OUT <= DATA_IN_FDC; + end if; + end if; + FDC_CSn <= FDC_CS_In; + end process FDC_REG; + + DMA_ADRESSREGISTERS: process(RESET, CLK_MAIN) + begin + if RESET = '1' THEN + DMA_TOP <= x"00"; + DMA_HIGH <= x"00"; + DMA_MID <= x"00"; + DMA_LOW <= x"00"; + elsif rising_edge(CLK_MAIN) then + if FB_WRn = '0' and (DMA_TOP_CS = '1' or DMA_ADR_CS = '1') then + DMA_TOP <= FB_AD_IN(31 downto 24); + end if; + if FB_WRn = '0' and (DMA_HIGH_CS = '1' or DMA_ADR_CS = '1') then + DMA_HIGH <= FB_AD_IN(23 downto 16); + end if; + if FB_WRn = '0' and DMA_MID_CS = '1' then + DMA_MID <= FB_AD_IN(23 downto 16); + elsif FB_WRn = '0' and DMA_ADR_CS = '1' then + DMA_MID <= FB_AD_IN(15 downto 8); + end if; + if FB_WRn = '0' and DMA_LOW_CS = '1' then + DMA_LOW <= FB_AD_IN(23 downto 16); + elsif FB_WRn = '0' and DMA_ADR_CS = '1' then + DMA_LOW <= FB_AD_IN(7 downto 0); + end if; + end if; + end process DMA_ADRESSREGISTERS; + + DMA_STATUS(0) <= '1'; -- DMA OK + DMA_STATUS(1) <= '1' when DMA_BYTECNT /= x"00000000" and DMA_BYTECNT(31) = '0' else '0'; -- When byts and not negative. + DMA_STATUS(2) <= '0' when DMA_DRQ_IN = '1' or SCSI_DRQ = '1' else '0'; + + DMA_REQ <= '1' when ((DMA_DRQ_IN = '1' and DMA_MODE(7) = '1') or (SCSI_DRQ = '1' and DMA_MODE(7) = '0')) and DMA_STATUS(1) = '1' and DMA_MODE(6) = '0' and CLR_FIFO = '0' else '0'; + DMA_DRQ_OUT <= '1' when DMA_DRQ_REG = "11" and DMA_MODE(6) = '0' else '0'; + DMA_DRQQ <= '1' when DMA_STATUS(1) = '1' and DMA_MODE(8) = '0' and RDF_AZ > 15 and DMA_MODE(6) = '0' else + '1' when DMA_STATUS(1) = '1' and DMA_MODE(8) = '1' and WRF_AZ < 512 and DMA_MODE(6) = '0' else '0'; + DMA_DRQ11_I <= '1' when DMA_DRQ_REG = "11" and DMA_MODE(6) = '0' else '0'; + DMA_DRQ11 <= DMA_DRQ11_I; + + SPIKEFILTER: process(RESET, CLK_FDC) + begin + if RESET = '1' THEN + DMA_DRQ_REG <= "00"; + elsif rising_edge(CLK_FDC) then + DMA_DRQ_REG(0) <= DMA_DRQQ; + DMA_DRQ_REG(1) <= DMA_DRQ_REG(0) and DMA_DRQQ; + end if; + end process SPIKEFILTER; + + READ_FIFO: dcfifo0 + port map( + aclr => CLR_FIFO, + data => RDF_DIN, + rdclk => CLK_MAIN, + rdreq => RDF_RDE, + wrclk => CLK_FDC, + wrreq => RDF_WRE, + q => RDF_DOUT, + wrusedw => RDF_AZ + ); + + FIFO_WRITE_CTRL: process(RESET, CLK_MAIN) + begin + if RESET = '1' THEN + WRF_WRE <= '0'; + elsif rising_edge(CLK_MAIN) then + if FCF_APH = '1' and FB_WRn = '0' then + WRF_WRE <= '1'; + else + WRF_WRE <= '0'; + end if; + end if; + end process FIFO_WRITE_CTRL; + + d <= FB_AD_IN(7 downto 0) & FB_AD_IN(15 downto 8) & FB_AD_IN(23 downto 16) & FB_AD_IN(31 downto 24); + + + WRITE_FIFO: dcfifo1 + port map( + aclr => CLR_FIFO, + data => d, + rdclk => CLK_FDC, + rdreq => WRF_RDE, + wrclk => CLK_MAIN, + wrreq => WRF_WRE, + q => WRF_DOUT, + rdusedw => WRF_AZ + ); + + SOUNDREGS: process(RESET, CLK_MAIN) + begin + if RESET = '1' then + SNDMACTL <= x"00"; + SNDBASHI <= x"00"; + SNDBASMI <= x"00"; + SNDBASLO <= x"00"; + SNDADRHI <= x"00"; + SNDADRMI <= x"00"; + SNDADRLO <= x"00"; + SNDENDHI <= x"00"; + SNDENDMI <= x"00"; + SNDENDLO <= x"00"; + SNDMODE <= x"00"; + elsif CLK_MAIN = '1' and CLK_MAIN' event then + if DMA_SND_CS = '1' and FB_ADR(5 downto 1) = x"0" and FB_WRn = '0' and FB_B1 ='1' then + SNDMACTL <= FB_AD_IN(23 downto 16); + elsif DMA_SND_CS = '1' and FB_ADR(5 downto 1) = x"1" and FB_WRn = '0' and FB_B1 ='1' then + SNDBASHI <= FB_AD_IN(23 downto 16); + elsif DMA_SND_CS = '1' and FB_ADR(5 downto 1) = x"2" and FB_WRn = '0' and FB_B1 ='1' then + SNDBASMI <= FB_AD_IN(23downto 16); + elsif DMA_SND_CS = '1' and FB_ADR(5 downto 1) = x"3" and FB_WRn = '0' and FB_B1 ='1' then + SNDBASLO <= FB_AD_IN(23 downto 16); + elsif DMA_SND_CS = '1' and FB_ADR(5 downto 1) = x"4" and FB_WRn = '0' and FB_B1 ='1' then + SNDADRHI <= FB_AD_IN(23 downto 16); + elsif DMA_SND_CS = '1' and FB_ADR(5 downto 1) = x"5" and FB_WRn = '0' and FB_B1 ='1' then + SNDADRMI <= FB_AD_IN(23 downto 16); + elsif DMA_SND_CS = '1' and FB_ADR(5 downto 1) = x"6" and FB_WRn = '0' and FB_B1 ='1' then + SNDADRLO <= FB_AD_IN(23 downto 16); + elsif DMA_SND_CS = '1' and FB_ADR(5 downto 1) = x"7" and FB_WRn = '0' and FB_B1 ='1' then + SNDENDHI <= FB_AD_IN(23 downto 16); + elsif DMA_SND_CS = '1' and FB_ADR(5 downto 1) = x"8" and FB_WRn = '0' and FB_B1 ='1' then + SNDENDMI <= FB_AD_IN(23 downto 16); + elsif DMA_SND_CS = '1' and FB_ADR(5 downto 1) = x"9" and FB_WRn = '0' and FB_B1 ='1' then + SNDENDLO <= FB_AD_IN(23 downto 16); + elsif DMA_SND_CS = '1' and FB_ADR(5 downto 1) = x"10" and FB_WRn = '0' and FB_B1 ='1' then + SNDMODE <= FB_AD_IN(23 downto 16); + end if; + end if; + end process SOUNDREGS; + + CLEAR_BY_TOGGLE: process(RESET, CLK_MAIN, DMA_MODE) + variable DMA_DIR_OLD : std_logic; + begin + if RESET = '1' THEN + DMA_DIR_OLD := '0'; + elsif CLK_MAIN = '1' and CLK_MAIN' event then + if DMA_MODE_CS = '0' then + DMA_DIR_OLD := DMA_MODE(8); + end if; + end if; + CLR_FIFO <= DMA_MODE(8) xor DMA_DIR_OLD; + end process CLEAR_BY_TOGGLE; + + FCF_REG: process(RESET, CLK_FDC) + begin + if RESET = '1' then + FCF_STATE <= FCF_IDLE; + DMA_ACTIVE <= '0'; + elsif rising_edge(CLK_FDC) then + FCF_STATE <= NEXT_FCF_STATE; + DMA_ACTIVE <= DMA_ACTIVE_NEW; + end if; + end process FCF_REG; + + FCF_DECODER: process(FCF_STATE, DMA_REQ, FDC_CS, SCSI_CS_I, DMA_ACTIVE, DMA_MODE) + begin + case FCF_STATE is + when FCF_IDLE => + SCSI_CSn <= '1'; + FDC_CS_In <= '1'; + RDF_WRE <= '0'; + WRF_RDE <= '0'; + SCSI_DACKn <= '1'; + if DMA_REQ = '1' or FDC_CS = '1' or SCSI_CS_I = '1' then + DMA_ACTIVE_NEW <= DMA_REQ; + NEXT_FCF_STATE <= FCF_T0; + else + DMA_ACTIVE_NEW <= '0'; + NEXT_FCF_STATE <= FCF_IDLE; + end if; + when FCF_T0 => + SCSI_CSn <= '1'; + FDC_CS_In <= '1'; + RDF_WRE <= '0'; + SCSI_DACKn <= '1'; + DMA_ACTIVE_NEW <= DMA_REQ; + WRF_RDE <= DMA_MODE(8) and DMA_REQ; -- Write -> Read from FIFO + if DMA_REQ = '0' and DMA_ACTIVE = '1' then -- Spike? + NEXT_FCF_STATE <= FCF_IDLE; -- Yes -> Start + else + NEXT_FCF_STATE <= FCF_T1; + end if; + when FCF_T1 => + RDF_WRE <= '0'; + WRF_RDE <= '0'; + DMA_ACTIVE_NEW <= DMA_ACTIVE; + SCSI_CSn <= not SCSI_CS_I; + FDC_CS_In <= DMA_MODE(4) or DMA_MODE(3); + SCSI_DACKn <= DMA_MODE(7) and DMA_ACTIVE; + NEXT_FCF_STATE <= FCF_T2; + when FCF_T2 => + RDF_WRE <= '0'; + WRF_RDE <= '0'; + DMA_ACTIVE_NEW <= DMA_ACTIVE; + SCSI_CSn <= not SCSI_CS_I; + FDC_CS_In <= DMA_MODE(4) or DMA_MODE(3); + SCSI_DACKn <= DMA_MODE(7) and DMA_ACTIVE; + NEXT_FCF_STATE <= FCF_T3; + when FCF_T3 => + RDF_WRE <= '0'; + WRF_RDE <= '0'; + DMA_ACTIVE_NEW <= DMA_ACTIVE; + SCSI_CSn <= not SCSI_CS_I; + FDC_CS_In <= DMA_MODE(4) or DMA_MODE(3); + SCSI_DACKn <= DMA_MODE(7) and DMA_ACTIVE; + NEXT_FCF_STATE <= FCF_T6; + when FCF_T6 => + WRF_RDE <= '0'; + DMA_ACTIVE_NEW <= DMA_ACTIVE; + SCSI_CSn <= not SCSI_CS_I; + FDC_CS_In <= DMA_MODE(4) or DMA_MODE(3); + SCSI_DACKn <= DMA_MODE(7) and DMA_ACTIVE; + RDF_WRE <= not DMA_MODE(8) and DMA_ACTIVE; -- Read -> Write to FIFO + NEXT_FCF_STATE <= FCF_T7; + when FCF_T7 => + SCSI_CSn <= '1'; + FDC_CS_In <= '1'; + RDF_WRE <= '0'; + WRF_RDE <= '0'; + SCSI_DACKn <= '1'; + DMA_ACTIVE_NEW <= '0'; + if FDC_CS = '1' and DMA_REQ = '0' then + NEXT_FCF_STATE <= FCF_T7; + else + NEXT_FCF_STATE <= FCF_IDLE; + end if; + end case; + end process FCF_DECODER; +end architecture BEHAVIOUR; \ No newline at end of file diff --git a/vhdl/rtl/vhdl/DSP/DSP.vhd b/vhdl/rtl/vhdl/DSP/DSP.vhd new file mode 100644 index 0000000..77699b2 --- /dev/null +++ b/vhdl/rtl/vhdl/DSP/DSP.vhd @@ -0,0 +1,83 @@ +-- WARNING: Do NOT edit the input and output ports in this file in a text +-- editor if you plan to continue editing the block that represents it in +-- the Block Editor! File corruption is VERY likely to occur. + +-- Copyright (C) 1991-2008 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. + + +-- Generated by Quartus II Version 8.1 (Build Build 163 10/28/2008) +-- Created on Tue Sep 08 16:24:57 2009 + +LIBRARY ieee; +USE ieee.std_logic_1164.all; + + +-- Entity Declaration + +ENTITY DSP IS + port( + CLK_33M : in std_logic; + CLK_MAIN : in std_logic; + FB_OEn : in std_logic; + FB_WRn : in std_logic; + FB_CS1n : in std_logic; + FB_CS2n : in std_logic; + FB_SIZE0 : in std_logic; + FB_SIZE1 : in std_logic; + FB_BURSTn : in std_logic; + FB_ADR : in std_logic_vector(31 downto 0); + RESETn : in std_logic; + FB_CS3n : in std_logic; +SRCSn : buffer std_logic; + SRBLEn : out std_logic; + SRBHEn : out std_logic; + SRWEn : out std_logic; + SROEn : out std_logic; + DSP_INT : out std_logic; + DSP_TA : out std_logic; + FB_AD_IN : in std_logic_vector(31 downto 0); + FB_AD_OUT : out std_logic_vector(31 downto 0); + FB_AD_EN : out std_logic; + IO_IN : in std_logic_vector(17 downto 0); + IO_OUT : out std_logic_vector(17 downto 0); + IO_EN : out std_logic; + SRD_IN : in std_logic_vector(15 downto 0); + SRD_OUT : out std_logic_vector(15 downto 0); + SRD_EN : out std_logic + ); +END DSP; + + +-- Architecture Body + +ARCHITECTURE DSP_architecture OF DSP IS + + +BEGIN + SRCSn <= '0' when FB_CS2n = '0' and FB_ADR(27 downto 24) = x"4" else '1'; --FB_CS3n; + SRBHEn <= '0' when FB_ADR(0 downto 0) = "0" else '1'; + SRBLEn <= '1' when FB_ADR(0 downto 0) = "0" and FB_SIZE1 = '0' and FB_SIZE0 = '1' else '0'; + SRWEn <= '0' when FB_WRn = '0' and SRCSn = '0' and CLK_MAIN = '0' else '1'; + SROEn <= '0' when FB_OEn = '0' and SRCSn = '0' else '1'; + DSP_INT <= '0'; + DSP_TA <= '0'; + IO_OUT(17 downto 0) <= FB_ADR(18 downto 1); + IO_EN <= '1'; + SRD_OUT(15 downto 0) <= FB_AD_IN(31 downto 16) when FB_WRn = '0' and SRCSn = '0' else x"0000"; + SRD_EN <= '1' when FB_WRn = '0' and SRCSn = '0' else '0'; + FB_AD_OUT(31 downto 16) <= SRD_IN(15 downto 0) when FB_OEn = '0' and SRCSn = '0' else x"0000"; + FB_AD_OUT(15 downto 0) <= SRD_IN(15 downto 0) when FB_OEn = '0' and SRCSn = '0' else x"0000"; + FB_AD_EN <= '1' when FB_OEn = '0' and SRCSn = '0' else '0'; +END DSP_architecture; diff --git a/vhdl/rtl/vhdl/DSP/src/adgen_stage.vhd b/vhdl/rtl/vhdl/DSP/src/adgen_stage.vhd new file mode 100644 index 0000000..1ff7e59 --- /dev/null +++ b/vhdl/rtl/vhdl/DSP/src/adgen_stage.vhd @@ -0,0 +1,216 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +library work; +use work.parameter_pkg.all; +use work.types_pkg.all; +use work.constants_pkg.all; + +entity adgen_stage is port( + activate_adgen : in std_logic; + activate_x_mem : in std_logic; + activate_y_mem : in std_logic; + activate_l_mem : in std_logic; + instr_word : in std_logic_vector(23 downto 0); + instr_array : in instructions_type; + optional_ea_word : in std_logic_vector(23 downto 0); + register_file : in register_file_type; + adgen_mode_a : in adgen_mode_type; + adgen_mode_b : in adgen_mode_type; + address_out_x : out unsigned(BW_ADDRESS-1 downto 0); + address_out_y : out unsigned(BW_ADDRESS-1 downto 0); + wr_R_port_A_valid : out std_logic; + wr_R_port_A : out addr_wr_port_type; + wr_R_port_B_valid : out std_logic; + wr_R_port_B : out addr_wr_port_type +); +end entity; + + +architecture rtl of adgen_stage is + + signal address_out_x_int : unsigned(BW_ADDRESS-1 downto 0); + + +begin + + address_out_x <= address_out_x_int; + + address_generator_X: process(activate_adgen, instr_word, register_file, adgen_mode_a) is + variable r_reg_local : unsigned(BW_ADDRESS-1 downto 0); + variable n_reg_local : unsigned(BW_ADDRESS-1 downto 0); + variable m_reg_local : unsigned(BW_ADDRESS-1 downto 0); + variable op1 : unsigned(BW_ADDRESS-1 downto 0); + variable op2 : unsigned(BW_ADDRESS-1 downto 0); + variable addr_mod : unsigned(BW_ADDRESS-1 downto 0); + variable new_r_reg : unsigned(BW_ADDRESS-1 downto 0); + variable new_r_reg_interm : unsigned(BW_ADDRESS-1 downto 0); + variable modulo_bitmask : std_logic_vector(BW_ADDRESS-1 downto 0); + variable bit_set : std_logic; + begin + r_reg_local := register_file.addr_r(to_integer(unsigned(instr_word(10 downto 8)))); + n_reg_local := register_file.addr_n(to_integer(unsigned(instr_word(10 downto 8)))); + m_reg_local := register_file.addr_m(to_integer(unsigned(instr_word(10 downto 8)))); + + -- select the operands for the calculation + case adgen_mode_a is + -- (Rn) - Nn + when POST_MIN_N => addr_mod := unsigned(- signed(n_reg_local)); + -- (Rn) + Nn + when POST_PLUS_N => addr_mod := n_reg_local; + -- (Rn)- + when POST_MIN_1 => addr_mod := (others => '1'); -- -1 + -- (Rn)+ + when POST_PLUS_1 => addr_mod := to_unsigned(1, BW_ADDRESS); + -- (Rn) + when NOP => addr_mod := (others => '0'); + -- (Rn + Nn) + when INDEXED_N => addr_mod := n_reg_local; + -- -(Rn) + when PRE_MIN_1 => addr_mod := (others => '1'); -- - 1 + -- absolute address (appended to instruction word) + when ABSOLUTE => addr_mod := (others => '0'); + when IMMEDIATE => addr_mod := (others => '0'); + end case; + + op1 := r_reg_local; + op2 := addr_mod; + -- linear addressing + if m_reg_local = 2**BW_ADDRESS-1 then + op1 := r_reg_local; + op2 := addr_mod; + -- bit reverse operation + elsif m_reg_local = 0 then + -- reverse the input to the adder bit wise + -- so we just need to use a single adder + for i in 0 to BW_ADDRESS-1 loop + op1(BW_ADDRESS - 1 - i) := r_reg_local(i); + op2(BW_ADDRESS - 1 - i) := addr_mod(i); + end loop; + -- modulo arithmetic + else + bit_set := '0'; + for i in BW_ADDRESS-1 downto 0 loop + if m_reg_local(i) = '1' then + bit_set := '1'; + end if; + if bit_set = '1' then + modulo_bitmask(i) := '0'; + else + modulo_bitmask(i) := '1'; + end if; + end loop; + end if; + + new_r_reg_interm := op1 + op2; + + new_r_reg := new_r_reg_interm; + -- linear addressing + if m_reg_local = 2**BW_ADDRESS-1 then + new_r_reg := new_r_reg_interm; + -- bit reverse operation + elsif m_reg_local = 0 then + for i in 0 to BW_ADDRESS-1 loop + new_r_reg(BW_ADDRESS - 1 - i) := new_r_reg_interm(i); + end loop; + else + + end if; + + -- store the updated register in the global register file + -- do not store when we do nothing or there is nothing to update + -- LUA instructions DO NOT UPDATE the source register!! + if (adgen_mode_a = NOP or adgen_mode_a = ABSOLUTE or adgen_mode_a = IMMEDIATE or instr_array = INSTR_LUA) then + wr_R_port_A_valid <= '0'; + else + wr_R_port_A_valid <= '1'; + end if; + wr_R_port_A.reg_number <= unsigned(instr_word(10 downto 8)); + wr_R_port_A.reg_value <= new_r_reg; + + -- select the output of the AGU + case adgen_mode_a is + -- (Rn) - Nn + when POST_MIN_N => address_out_x_int <= r_reg_local; + -- (Rn) + Nn + when POST_PLUS_N => address_out_x_int <= r_reg_local; + -- (Rn)- + when POST_MIN_1 => address_out_x_int <= r_reg_local; + -- (Rn)+ + when POST_PLUS_1 => address_out_x_int <= r_reg_local; + -- (Rn) + when NOP => address_out_x_int <= r_reg_local; + -- (Rn + Nn) + when INDEXED_N => address_out_x_int <= new_r_reg; + -- -(Rn) + when PRE_MIN_1 => address_out_x_int <= new_r_reg; + -- absolute address (appended to instruction word) + when ABSOLUTE => address_out_x_int <= unsigned(optional_ea_word(BW_ADDRESS-1 downto 0)); + when IMMEDIATE => address_out_x_int <= r_reg_local; -- Done externally, value never used + end case; + -- LUA instructions only use the updated address! + if instr_array = INSTR_LUA then + address_out_x_int <= new_r_reg; + end if; + + end process address_generator_X; + + address_generator_Y: process(activate_adgen, activate_x_mem, activate_y_mem, activate_l_mem, instr_word, + register_file, adgen_mode_b, address_out_x_int) is + variable r_reg_local : unsigned(BW_ADDRESS-1 downto 0); + variable n_reg_local : unsigned(BW_ADDRESS-1 downto 0); + variable m_reg_local : unsigned(BW_ADDRESS-1 downto 0); + variable op2 : unsigned(BW_ADDRESS-1 downto 0); + variable new_r_reg : unsigned(BW_ADDRESS-1 downto 0); + begin + r_reg_local := register_file.addr_r(to_integer(unsigned((not instr_word(10)) & instr_word(14 downto 13)))); + n_reg_local := register_file.addr_n(to_integer(unsigned((not instr_word(10)) & instr_word(14 downto 13)))); + m_reg_local := register_file.addr_m(to_integer(unsigned((not instr_word(10)) & instr_word(14 downto 13)))); + + -- select the operands for the calculation + case adgen_mode_b is + -- (Rn) + Nn + when POST_PLUS_N => op2 := n_reg_local; + -- (Rn)- + when POST_MIN_1 => op2 := (others => '1'); -- -1 + -- (Rn)+ + when POST_PLUS_1 => op2 := to_unsigned(1, BW_ADDRESS); + -- (Rn) + when others => op2 := (others => '0'); + end case; + + new_r_reg := r_reg_local + op2; + -- TODO: USE modifier register! + + -- store the updated register in the global register file + -- do not store when we do nothing or there is nothing to update + if adgen_mode_b = NOP then + wr_R_port_B_valid <= '0'; + else + wr_R_port_B_valid <= '1'; + end if; + wr_R_port_B.reg_number <= unsigned((not instr_word(10)) & instr_word(14 downto 13)); + wr_R_port_B.reg_value <= new_r_reg; + + -- the address for the y memory is calculated in the first AGU if the x memory is not accessed! + -- so use the other output as address output for the y memory! + -- Furthermore, use the same address for L memory accesses (X and Y memory access the same address!) + if (activate_y_mem = '1' and activate_x_mem = '0') or activate_l_mem = '1' then + address_out_y <= address_out_x_int; + -- in any other case use the locally computed value + else + -- select the output of the AGU + case adgen_mode_b is + -- (Rn) + Nn + when POST_PLUS_N => address_out_y <= r_reg_local; + -- (Rn)- + when POST_MIN_1 => address_out_y <= r_reg_local; + -- (Rn)+ + when POST_PLUS_1 => address_out_y <= r_reg_local; + -- (Rn) + when others => address_out_y <= r_reg_local; + end case; + end if; + end process address_generator_Y; + +end architecture; diff --git a/vhdl/rtl/vhdl/DSP/src/constants_pkg.vhd b/vhdl/rtl/vhdl/DSP/src/constants_pkg.vhd new file mode 100644 index 0000000..4b8122d --- /dev/null +++ b/vhdl/rtl/vhdl/DSP/src/constants_pkg.vhd @@ -0,0 +1,62 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +library work; +use work.parameter_pkg.all; +use work.types_pkg.all; + + +package constants_pkg is + + ------------------------- + -- Flags in CCR register + ------------------------- + constant C_FLAG : natural := 0; + constant V_FLAG : natural := 1; + constant Z_FLAG : natural := 2; + constant N_FLAG : natural := 3; + constant U_FLAG : natural := 4; + constant E_FLAG : natural := 5; + constant L_FLAG : natural := 6; + constant S_FLAG : natural := 7; + + ------------------- + -- Pipeline stages + ------------------- + constant ST_FETCH : natural := 0; + constant ST_FETCH2 : natural := 1; + constant ST_DECODE : natural := 2; + constant ST_ADGEN : natural := 3; + constant ST_EXEC : natural := 4; + + ---------------------- + -- Activation signals + ---------------------- + constant ACT_ADGEN : natural := 0; -- Run the address generator + constant ACT_ALU : natural := 1; -- Activation of ALU results in modification of the status register + constant ACT_EXEC_BRA : natural := 2; -- Branch (in execute stage) + constant ACT_EXEC_CR_MOD : natural := 3; -- Control Register Modification (in execute stage) + constant ACT_EXEC_LOOP : natural := 4; -- Loop instruction (REP, DO) + constant ACT_X_MEM_RD : natural := 5; -- Init read from X memory + constant ACT_Y_MEM_RD : natural := 6; -- Init read from Y memory + constant ACT_P_MEM_RD : natural := 7; -- Init read from P memory + constant ACT_X_MEM_WR : natural := 8; -- Init write to X memory + constant ACT_Y_MEM_WR : natural := 9; -- Init write to Y memory + constant ACT_P_MEM_WR : natural := 10; -- Init write to P memory + constant ACT_REG_RD : natural := 11; -- Read from register (6 bit addressing) + constant ACT_REG_WR : natural := 12; -- Write to register (6 bit addressing) + constant ACT_IMM_8BIT : natural := 13; -- 8 bit immediate operand (in instruction word) + constant ACT_IMM_12BIT : natural := 14; -- 12 bit immediate operand (in instruction word) + constant ACT_IMM_LONG : natural := 15; -- 24 bit immediate operant (in optional instruction word) + constant ACT_X_BUS_RD : natural := 16; -- Read data via X-bus (from x0,x1,a,b) + constant ACT_X_BUS_WR : natural := 17; -- Write data via X-bus (to x0,x1,a,b) + constant ACT_Y_BUS_RD : natural := 18; -- Read data via Y-bus (from y0,y1,a,b) + constant ACT_Y_BUS_WR : natural := 19; -- Write data via Y-bus (to y0,y1,a,b) + constant ACT_L_BUS_RD : natural := 20; -- Read data via L-bus (from a10, b10,x,y,a,b,ab,ba) + constant ACT_L_BUS_WR : natural := 21; -- Write data via L-bus (to a10, b10,x,y,a,b,ab,ba) + constant ACT_BIT_MOD_WR : natural := 22; -- Bit modify write (to set for BSET, BCLR, BCHG) + constant ACT_REG_WR_CC : natural := 23; -- Write to register file conditionally (Tcc) + constant ACT_ALU_WR_CC : natural := 24; -- Write ALU result conditionally (Tcc) + constant ACT_NORM : natural := 25; -- NORM instruction needs special handling + +end package constants_pkg; diff --git a/vhdl/rtl/vhdl/DSP/src/decode_stage.vhd b/vhdl/rtl/vhdl/DSP/src/decode_stage.vhd new file mode 100644 index 0000000..0c62149 --- /dev/null +++ b/vhdl/rtl/vhdl/DSP/src/decode_stage.vhd @@ -0,0 +1,1221 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +library work; +use work.parameter_pkg.all; +use work.types_pkg.all; +use work.constants_pkg.all; + +entity decode_stage is port( + activate_dec : in std_logic; + instr_word : in std_logic_vector(23 downto 0); + dble_word_instr : out std_logic; + instr_array : out instructions_type; + act_array : out std_logic_vector(NUM_ACT_SIGNALS-1 downto 0); + reg_wr_addr : out std_logic_vector(5 downto 0); + reg_rd_addr : out std_logic_vector(5 downto 0); + x_bus_rd_addr : out std_logic_vector(1 downto 0); + x_bus_wr_addr : out std_logic_vector(1 downto 0); + y_bus_rd_addr : out std_logic_vector(1 downto 0); + y_bus_wr_addr : out std_logic_vector(1 downto 0); + l_bus_addr : out std_logic_vector(2 downto 0); + adgen_mode_a : out adgen_mode_type; + adgen_mode_b : out adgen_mode_type; + alu_ctrl : out alu_ctrl_type +); +end entity; + + +architecture rtl of decode_stage is + + signal instr_array_int : instructions_type; +-- signal activate_pm_int : std_logic; + type adgen_bittype_type is (NOP, SINGLE_X, SINGLE_X_SHORT, DOUBLE_X_Y); + -- SINGLE_X : MMMRRR + -- SINGLE_X_SHORT : MMRRR + -- DOUBLE_X_Y : mmrrMMRRR + signal adgen_bittype : adgen_bittype_type; + + signal ea_extension_available : std_logic; + + signal alu_tcc_decoded : std_logic; + signal alu_div_decoded : std_logic; + signal alu_norm_decoded : std_logic; + +begin + + + -- output the decoded instruction + instr_array <= instr_array_int; + + -- calculate whether this is a double word instruction + dble_word_instr <= '1' when ea_extension_available = '1' or + instr_array_int = INSTR_DO or + instr_array_int = INSTR_JCLR or + instr_array_int = INSTR_JSCLR or + instr_array_int = INSTR_JSET or + instr_array_int = INSTR_JSSET else + '0'; + + alu_instruction_decoder: process(instr_word, activate_dec, alu_tcc_decoded, + alu_div_decoded, alu_norm_decoded) is + variable instr_word_var : std_logic_vector(23 downto 0); + begin + if activate_dec = '1' then + instr_word_var := instr_word; + else + instr_word_var := (others => '0'); + end if; + + alu_ctrl.mul_op1 <= (others => '0'); + alu_ctrl.mul_op2 <= (others => '0'); + alu_ctrl.rotate <= '0'; + alu_ctrl.div_instr <= '0'; + alu_ctrl.norm_instr <= '0'; + alu_ctrl.shift_src <= '0'; + alu_ctrl.shift_src_sign <= (others => '0'); + alu_ctrl.shift_mode <= ZEROS; + alu_ctrl.add_src_stage_1 <= (others => '0'); + alu_ctrl.add_src_stage_2 <= (others => '0'); + alu_ctrl.add_src_sign <= (others => '0'); + alu_ctrl.logic_function <= (others => '0'); + alu_ctrl.word_24_update <= '0'; + alu_ctrl.rounding_used <= (others => '0'); + alu_ctrl.store_result <= '0'; + for i in 0 to 7 loop -- by default do not touch any of the ccr flags (L;E;U;N;Z;V;C) + alu_ctrl.ccr_flags_ctrl(i) <= DONT_TOUCH; + end loop; + alu_ctrl.dst_accu <= instr_word_var(3); -- default value for all alu operations + + -- check wether instruction that allows parallel moves + -- has to be decoded, then it is an ALU operation in the 8 LSBs + -- Only exceptions are DIV, NORM, and Tcc + if instr_word_var(23 downto 20) /= "0000" then + -- ABS + if instr_word_var(7 downto 4) = "0010" and instr_word_var(2 downto 0) = "110" then + -- Read accu + alu_ctrl.shift_mode <= NO_SHIFT; + alu_ctrl.shift_src <= instr_word_var(3); -- source/dst are the same register + alu_ctrl.shift_src_sign <= "10"; -- the sign of the operand depends on the operand + -- negative operand will negate the content of the accu as + -- needed by the ABS instruction + alu_ctrl.add_src_stage_2 <= "00"; -- select zero + alu_ctrl.store_result <= '1'; -- store the result + -- set all flags but carry + for i in 1 to 7 loop + alu_ctrl.ccr_flags_ctrl(i) <= MODIFY; + end loop; + end if; + -- ADC + if instr_word_var(7 downto 5) = "001" and instr_word_var(2 downto 0) = "001" then + -- Read accu + alu_ctrl.shift_mode <= NO_SHIFT; + alu_ctrl.shift_src <= instr_word_var(3); -- accumulate to the same register we want to write to + alu_ctrl.shift_src_sign <= "00"; -- with the original sign + -- Read S + alu_ctrl.add_src_stage_1 <= "01" & instr_word_var(4); -- X or Y + alu_ctrl.add_src_stage_2 <= "01"; -- select the register source + alu_ctrl.add_src_sign <= "00"; -- with original sign + alu_ctrl.store_result <= '1'; -- store the result + alu_ctrl.rounding_used <= "10"; -- add carry to result of addition + -- set all flags + for i in 0 to 7 loop + alu_ctrl.ccr_flags_ctrl(i) <= MODIFY; + end loop; + end if; + -- ADD + if instr_word_var(7) = '0' and instr_word_var(2 downto 0) = "000" and instr_word_var(6 downto 4) /= "000" then + -- Read accu + alu_ctrl.shift_mode <= NO_SHIFT; + alu_ctrl.shift_src <= instr_word_var(3); -- accumulate to the same register we want to write to + alu_ctrl.shift_src_sign <= "00"; -- with the original sign + -- Read S + alu_ctrl.add_src_stage_1 <= instr_word_var(6 downto 4); -- source register (JJJ encoding) + alu_ctrl.add_src_stage_2 <= "01"; -- select the register source + alu_ctrl.add_src_sign <= "00"; -- with original sign + alu_ctrl.store_result <= '1'; -- store the result + alu_ctrl.rounding_used <= "00"; -- no rounding needed + -- set all flags + for i in 0 to 7 loop + alu_ctrl.ccr_flags_ctrl(i) <= MODIFY; + end loop; + end if; + -- ADDL + if instr_word_var(7 downto 4) = "0001" and instr_word_var(2 downto 0) = "010" then + -- Read accu + alu_ctrl.shift_mode <= SHIFT_LEFT; + alu_ctrl.shift_src <= instr_word_var(3); -- accumulate to the same register we want to write to + alu_ctrl.shift_src_sign <= "00"; -- with the original sign + -- Read S + alu_ctrl.add_src_stage_1 <= instr_word_var(6 downto 4); -- source register (JJJ encoding) (here: A,B) + alu_ctrl.add_src_stage_2 <= "01"; -- select the register source + alu_ctrl.add_src_sign <= "00"; -- with original sign + alu_ctrl.store_result <= '1'; -- store the result + alu_ctrl.rounding_used <= "00"; -- no rounding needed + -- set all flags + for i in 0 to 7 loop + alu_ctrl.ccr_flags_ctrl(i) <= MODIFY; + end loop; + end if; + -- ADDR + if instr_word_var(7 downto 4) = "0000" and instr_word_var(2 downto 0) = "010" then + -- Read accu + alu_ctrl.shift_mode <= SHIFT_RIGHT; + alu_ctrl.shift_src <= instr_word_var(3); -- accumulate to the same register we want to write to + alu_ctrl.shift_src_sign <= "00"; -- with the original sign + -- Read S + alu_ctrl.add_src_stage_1 <= instr_word_var(6 downto 5) & '1'; -- source register (JJJ encoding) (here: A,B) + alu_ctrl.add_src_stage_2 <= "01"; -- select the register source + alu_ctrl.add_src_sign <= "00"; -- with original sign + alu_ctrl.store_result <= '1'; -- store the result + alu_ctrl.rounding_used <= "00"; -- no rounding needed + -- set all flags + for i in 0 to 7 loop + alu_ctrl.ccr_flags_ctrl(i) <= MODIFY; + end loop; + end if; + -- AND / OR / EOR + if instr_word_var(7 downto 6) = "01" and (instr_word_var(2 downto 0) = "110" or -- and + instr_word_var(2 downto 0) = "010" or -- or + instr_word_var(2 downto 0) = "011") then -- eor + alu_ctrl.logic_function <= instr_word_var(2 downto 0); -- 000: none, 110: and, 010: or, 011: eor, 111: not + alu_ctrl.word_24_update <= '1'; -- only accumulator bits 47 downto 24 affected? + -- Read accu + alu_ctrl.shift_mode <= NO_SHIFT; + alu_ctrl.shift_src <= instr_word_var(3); -- accumulate to the same register we want to write to + alu_ctrl.shift_src_sign <= "00"; -- with the original sign + -- Read S + alu_ctrl.add_src_stage_1 <= instr_word_var(6 downto 4); -- source register (JJJ encoding) (here: A,B) + alu_ctrl.add_src_stage_2 <= "01"; -- select the register source + alu_ctrl.add_src_sign <= "00"; -- with original sign + alu_ctrl.store_result <= '1'; -- store the result + alu_ctrl.rounding_used <= "00"; -- no rounding needed + -- set following flags + alu_ctrl.ccr_flags_ctrl(N_FLAG) <= MODIFY; + alu_ctrl.ccr_flags_ctrl(Z_FLAG) <= MODIFY; + alu_ctrl.ccr_flags_ctrl(V_FLAG) <= CLEAR; + end if; + -- ASL + if instr_word_var(7 downto 4) = "0011" and instr_word_var(2 downto 0) = "010" then + -- Read accu + alu_ctrl.shift_mode <= SHIFT_LEFT; + alu_ctrl.shift_src <= instr_word_var(3); -- accumulate to the same register we want to write to + alu_ctrl.shift_src_sign <= "00"; -- with the original sign + -- Read S + alu_ctrl.add_src_stage_2 <= "00"; -- select zero as operand + alu_ctrl.add_src_sign <= "00"; -- with original sign + alu_ctrl.store_result <= '1'; -- store the result + alu_ctrl.rounding_used <= "00"; -- no rounding needed + -- set all flags + for i in 0 to 7 loop + alu_ctrl.ccr_flags_ctrl(i) <= MODIFY; + end loop; + end if; + -- ASR + if instr_word_var(7 downto 4) = "0010" and instr_word_var(2 downto 0) = "010" then + -- Read accu + alu_ctrl.shift_mode <= SHIFT_RIGHT; + alu_ctrl.shift_src <= instr_word_var(3); -- accumulate to the same register we want to write to + alu_ctrl.shift_src_sign <= "00"; -- with the original sign + -- Read S + alu_ctrl.add_src_stage_2 <= "00"; -- select zero as operand + alu_ctrl.add_src_sign <= "00"; -- with original sign + alu_ctrl.store_result <= '1'; -- store the result + alu_ctrl.rounding_used <= "00"; -- no rounding needed + -- set following flags +-- alu_ctrl.ccr_flags_ctrl(S_FLAG) <= MODIFY; +-- alu_ctrl.ccr_flags_ctrl(E_FLAG) <= MODIFY; +-- alu_ctrl.ccr_flags_ctrl(U_FLAG) <= MODIFY; +-- alu_ctrl.ccr_flags_ctrl(N_FLAG) <= MODIFY; +-- alu_ctrl.ccr_flags_ctrl(Z_FLAG) <= MODIFY; +-- alu_ctrl.ccr_flags_ctrl(V_FLAG) <= CLEAR; +-- alu_ctrl.ccr_flags_ctrl(C_FLAG) <= MODIFY; + -- set all flags, V-flag will be cleared due to shifting + for i in 0 to 7 loop + alu_ctrl.ccr_flags_ctrl(i) <= MODIFY; + end loop; + end if; + -- CLR + if instr_word_var(7 downto 4) = "0001" and instr_word_var(2 downto 0) = "011" then + -- Read accu + alu_ctrl.shift_mode <= ZEROS; + -- Read S + alu_ctrl.add_src_stage_2 <= "00"; -- select zero as operand + alu_ctrl.add_src_sign <= "00"; -- with original sign + alu_ctrl.store_result <= '1'; -- store the result + alu_ctrl.rounding_used <= "00"; -- no rounding needed + -- set following flags + alu_ctrl.ccr_flags_ctrl(S_FLAG) <= MODIFY; + alu_ctrl.ccr_flags_ctrl(E_FLAG) <= MODIFY; + alu_ctrl.ccr_flags_ctrl(U_FLAG) <= MODIFY; + alu_ctrl.ccr_flags_ctrl(N_FLAG) <= MODIFY; + alu_ctrl.ccr_flags_ctrl(Z_FLAG) <= MODIFY; + alu_ctrl.ccr_flags_ctrl(V_FLAG) <= CLEAR; + end if; + -- CMP + if instr_word_var(7) = '0' and instr_word_var(6 downto 5) /= "01" and + instr_word_var(2 downto 0) = "101" then + -- Read accu + alu_ctrl.shift_mode <= NO_SHIFT; + alu_ctrl.shift_src <= instr_word_var(3); -- accumulate to the same register we want to write to + alu_ctrl.shift_src_sign <= "00"; -- with the original sign + -- Read S + if instr_word_var(6) = '1' then + alu_ctrl.add_src_stage_1 <= instr_word_var(6 downto 4); -- source register (JJJ encoding) x0,x1,y0,y1 + else + alu_ctrl.add_src_stage_1 <= "001"; -- select opposite accu (JJJ encoding) + end if; + alu_ctrl.add_src_stage_2 <= "01"; -- select the register source + alu_ctrl.add_src_sign <= "01"; -- with negative sign + alu_ctrl.store_result <= '0'; -- do not store the result + alu_ctrl.rounding_used <= "00"; -- no rounding needed + -- set all flags + for i in 0 to 7 loop + alu_ctrl.ccr_flags_ctrl(i) <= MODIFY; + end loop; + end if; + -- CMPM + if instr_word_var(7) = '0' and instr_word_var(6 downto 5) /= "01" and + instr_word_var(2 downto 0) = "111" then + -- Read accu + alu_ctrl.shift_mode <= NO_SHIFT; + alu_ctrl.shift_src <= instr_word_var(3); -- accumulate to the same register we want to write to + alu_ctrl.shift_src_sign <= "10"; -- with the sign dependant sign (magnitude!) + -- Read S + if instr_word_var(6) = '1' then + alu_ctrl.add_src_stage_1 <= instr_word_var(6 downto 4); -- source register (JJJ encoding) x0,x1,y0,y1 + else + alu_ctrl.add_src_stage_1 <= "001"; -- select opposite accu (JJJ encoding) + end if; + alu_ctrl.add_src_stage_2 <= "01"; -- select the register source + alu_ctrl.add_src_sign <= "10"; -- with sign dependant sign (magnitude!) + alu_ctrl.store_result <= '0'; -- do not store the result + alu_ctrl.rounding_used <= "00"; -- no rounding needed + -- set all flags + for i in 0 to 7 loop + alu_ctrl.ccr_flags_ctrl(i) <= MODIFY; + end loop; + end if; + -- LSL + if instr_word_var(7 downto 4) = "0011" and instr_word_var(2 downto 0) = "011" then + alu_ctrl.word_24_update <= '1'; + -- Read accu + alu_ctrl.shift_mode <= SHIFT_LEFT; + alu_ctrl.shift_src <= instr_word_var(3); -- accumulate to the same register we want to write to + alu_ctrl.shift_src_sign <= "00"; -- with normal sign + alu_ctrl.store_result <= '1'; -- store the result + alu_ctrl.rounding_used <= "00"; -- no rounding needed + alu_ctrl.add_src_stage_2 <= "00"; -- select zero as second operand + -- set N,Z,V,C flags + for i in 0 to 3 loop + alu_ctrl.ccr_flags_ctrl(i) <= MODIFY; + end loop; + end if; + -- LSR + if instr_word_var(7 downto 4) = "0010" and instr_word_var(2 downto 0) = "011" then + alu_ctrl.word_24_update <= '1'; + -- Read accu + alu_ctrl.shift_mode <= SHIFT_RIGHT; + alu_ctrl.shift_src <= instr_word_var(3); -- accumulate to the same register we want to write to + alu_ctrl.shift_src_sign <= "00"; -- with normal sign + alu_ctrl.store_result <= '1'; -- store the result + alu_ctrl.rounding_used <= "00"; -- no rounding needed + alu_ctrl.add_src_stage_2 <= "00"; -- select zero as second operand + -- set N,Z,V,C flags + for i in 0 to 3 loop + alu_ctrl.ccr_flags_ctrl(i) <= MODIFY; + end loop; + end if; + -- MPY, MPYR, MAC, MACR + if instr_word_var(7) = '1' then + case instr_word_var(6 downto 4) is + when "000" => alu_ctrl.mul_op1 <= "00"; alu_ctrl.mul_op2 <= "00"; -- x0,x0 + when "001" => alu_ctrl.mul_op1 <= "10"; alu_ctrl.mul_op2 <= "10"; -- y0,y0 + when "010" => alu_ctrl.mul_op1 <= "01"; alu_ctrl.mul_op2 <= "00"; -- x1,x0 + when "011" => alu_ctrl.mul_op1 <= "11"; alu_ctrl.mul_op2 <= "10"; -- y1,y0 + when "100" => alu_ctrl.mul_op1 <= "00"; alu_ctrl.mul_op2 <= "11"; -- x0,y1 + when "101" => alu_ctrl.mul_op1 <= "10"; alu_ctrl.mul_op2 <= "00"; -- y0,x0 + when "110" => alu_ctrl.mul_op1 <= "01"; alu_ctrl.mul_op2 <= "10"; -- x1,y0 + when others => alu_ctrl.mul_op1 <= "11"; alu_ctrl.mul_op2 <= "01"; -- y1,x1 + end case; + alu_ctrl.store_result <= '1'; -- store result in accu + alu_ctrl.add_src_stage_2 <= "10"; -- select mul out for adder! + alu_ctrl.add_src_sign <= '0' & instr_word_var(2); -- select +/- + alu_ctrl.rounding_used <= '0' & instr_word_var(0); -- rounding is determined by that bit! + if instr_word_var(1) = '0' then -- MPY(R) + alu_ctrl.shift_mode <= ZEROS; + else -- MAC(R) + alu_ctrl.shift_mode <= NO_SHIFT; + alu_ctrl.shift_src <= instr_word_var(3); -- accumulate to the same register we want to write to + alu_ctrl.shift_src_sign <= "00"; -- with the original sign + end if; + -- set all flags but carry! + for i in 1 to 7 loop + alu_ctrl.ccr_flags_ctrl(i) <= MODIFY; + end loop; + end if; + -- NEG + if instr_word_var(7 downto 4) = "0011" and instr_word_var(2 downto 0) = "110" then + -- Read accu + alu_ctrl.shift_mode <= ZEROS; +-- alu_ctrl.shift_src <= instr_word_var(3); -- accumulate to the same register we want to write to +-- alu_ctrl.shift_src_sign <= "01"; -- with negative sign + -- Read Accu + alu_ctrl.add_src_stage_1 <= "000"; -- source register equal to dst_register + alu_ctrl.add_src_stage_2 <= "01"; -- select register as operand + alu_ctrl.add_src_sign <= "01"; -- with negative sign + alu_ctrl.store_result <= '1'; -- store the result + alu_ctrl.rounding_used <= "00"; -- no rounding needed + -- set all flags but carry! + for i in 1 to 7 loop + alu_ctrl.ccr_flags_ctrl(i) <= MODIFY; + end loop; + end if; + -- NOT + if instr_word_var(7 downto 4) = "0001" and instr_word_var(2 downto 0) = "111" then + alu_ctrl.word_24_update <= '1'; + -- Read accu + alu_ctrl.shift_mode <= NO_SHIFT; + alu_ctrl.shift_src <= instr_word_var(3); -- accumulate to the same register we want to write to + alu_ctrl.shift_src_sign <= "00"; -- with normal sign + alu_ctrl.logic_function <= instr_word_var(2 downto 0); -- select not operation + alu_ctrl.store_result <= '1'; -- store the result + alu_ctrl.rounding_used <= "00"; -- no rounding needed + -- set following flags + alu_ctrl.ccr_flags_ctrl(N_FLAG) <= MODIFY; + alu_ctrl.ccr_flags_ctrl(Z_FLAG) <= MODIFY; + alu_ctrl.ccr_flags_ctrl(V_FLAG) <= CLEAR; + end if; + -- RND + if instr_word_var(7 downto 4) = "0001" and instr_word_var(2 downto 0) = "001" then + -- Read accu + alu_ctrl.shift_mode <= NO_SHIFT; + alu_ctrl.shift_src <= instr_word_var(3); -- accumulate to the same register we want to write to + alu_ctrl.shift_src_sign <= "00"; -- with normal sign + alu_ctrl.store_result <= '1'; -- store the result + alu_ctrl.rounding_used <= "01"; -- normal rounding needed + alu_ctrl.add_src_stage_2 <= "00"; -- select zero as second operand + -- set all flags but carry! + for i in 1 to 7 loop + alu_ctrl.ccr_flags_ctrl(i) <= MODIFY; + end loop; + end if; + -- ROL + if instr_word_var(7 downto 4) = "0011" and instr_word_var(2 downto 0) = "111" then + alu_ctrl.word_24_update <= '1'; + alu_ctrl.rotate <= '1'; + -- Read accu + alu_ctrl.shift_mode <= SHIFT_LEFT; + alu_ctrl.shift_src <= instr_word_var(3); -- accumulate to the same register we want to write to + alu_ctrl.shift_src_sign <= "00"; -- with normal sign + alu_ctrl.store_result <= '1'; -- store the result + alu_ctrl.rounding_used <= "00"; -- no rounding needed + alu_ctrl.add_src_stage_2 <= "00"; -- select zero as second operand + -- set the following flags + alu_ctrl.ccr_flags_ctrl(C_FLAG) <= MODIFY; + alu_ctrl.ccr_flags_ctrl(V_FLAG) <= CLEAR; + alu_ctrl.ccr_flags_ctrl(Z_FLAG) <= MODIFY; + alu_ctrl.ccr_flags_ctrl(N_FLAG) <= MODIFY; + end if; + -- ROR + if instr_word_var(7 downto 4) = "0010" and instr_word_var(2 downto 0) = "111" then + alu_ctrl.word_24_update <= '1'; + alu_ctrl.rotate <= '1'; + -- Read accu + alu_ctrl.shift_mode <= SHIFT_RIGHT; + alu_ctrl.shift_src <= instr_word_var(3); -- accumulate to the same register we want to write to + alu_ctrl.shift_src_sign <= "00"; -- with normal sign + alu_ctrl.store_result <= '1'; -- store the result + alu_ctrl.rounding_used <= "00"; -- no rounding needed + alu_ctrl.add_src_stage_2 <= "00"; -- select zero as second operand + -- set the following flags + alu_ctrl.ccr_flags_ctrl(C_FLAG) <= MODIFY; + alu_ctrl.ccr_flags_ctrl(V_FLAG) <= CLEAR; + alu_ctrl.ccr_flags_ctrl(Z_FLAG) <= MODIFY; + alu_ctrl.ccr_flags_ctrl(N_FLAG) <= MODIFY; + end if; + -- SBC + if instr_word_var(7 downto 5) = "001" and instr_word_var(2 downto 0) = "101" then + -- Read accu + alu_ctrl.shift_mode <= NO_SHIFT; + alu_ctrl.shift_src <= instr_word_var(3); -- accumulate to the same register we want to write to + alu_ctrl.shift_src_sign <= "00"; -- with normal sign + -- Read S + alu_ctrl.add_src_stage_1 <= instr_word_var(6 downto 4); -- source register (JJJ encoding) X,Y + alu_ctrl.add_src_stage_2 <= "01"; -- select the register source + alu_ctrl.add_src_sign <= "01"; -- with negative sign + alu_ctrl.rounding_used <= "11"; -- subtract carry + alu_ctrl.store_result <= '1'; -- store the result + -- set all flags! + for i in 0 to 7 loop + alu_ctrl.ccr_flags_ctrl(i) <= MODIFY; + end loop; + end if; + -- SUB + if instr_word_var(7) = '0' and instr_word_var(2 downto 0) = "100" then + -- Read accu + alu_ctrl.shift_mode <= NO_SHIFT; + alu_ctrl.shift_src <= instr_word_var(3); -- accumulate to the same register we want to write to + alu_ctrl.shift_src_sign <= "00"; -- with normal sign + -- Read S + alu_ctrl.add_src_stage_1 <= instr_word_var(6 downto 4); -- source register (JJJ encoding) + alu_ctrl.add_src_stage_2 <= "01"; -- select the register source + alu_ctrl.add_src_sign <= "01"; -- with negative sign + alu_ctrl.rounding_used <= "00"; -- no rounding needed + alu_ctrl.store_result <= '1'; -- store the result + -- set all flags! + for i in 0 to 7 loop + alu_ctrl.ccr_flags_ctrl(i) <= MODIFY; + end loop; + end if; + -- SUBL + if instr_word_var(7 downto 4) = "0001" and instr_word_var(2 downto 0) = "110" then + -- Read accu + alu_ctrl.shift_mode <= SHIFT_LEFT; + alu_ctrl.shift_src <= instr_word_var(3); -- accumulate to the same register we want to write to + alu_ctrl.shift_src_sign <= "00"; -- with normal sign + -- Read S + alu_ctrl.add_src_stage_1 <= instr_word_var(6 downto 4); -- source register (JJJ encoding) + alu_ctrl.add_src_stage_2 <= "01"; -- select the register source + alu_ctrl.add_src_sign <= "01"; -- with negative sign + alu_ctrl.rounding_used <= "00"; -- no rounding needed + alu_ctrl.store_result <= '1'; -- store the result + -- set all flags! + for i in 0 to 7 loop + alu_ctrl.ccr_flags_ctrl(i) <= MODIFY; + end loop; + end if; + -- SUBR + if instr_word_var(7 downto 4) = "0000" and instr_word_var(2 downto 0) = "110" then + -- Read accu + alu_ctrl.shift_mode <= SHIFT_RIGHT; + alu_ctrl.shift_src <= instr_word_var(3); -- accumulate to the same register we want to write to + alu_ctrl.shift_src_sign <= "00"; -- with normal sign + -- Read S + alu_ctrl.add_src_stage_1 <= instr_word_var(6 downto 5) & '1'; -- source register (JJJ encoding) + alu_ctrl.add_src_stage_2 <= "01"; -- select the register source + alu_ctrl.add_src_sign <= "01"; -- with negative sign + alu_ctrl.rounding_used <= "00"; -- no rounding needed + alu_ctrl.store_result <= '1'; -- store the result + -- set all flags! + for i in 0 to 7 loop + alu_ctrl.ccr_flags_ctrl(i) <= MODIFY; + end loop; + end if; + -- TFR + if instr_word_var(7) = '0' and instr_word_var(6 downto 5) /= "01" and + instr_word_var(6 downto 4) /= "001" and instr_word_var(2 downto 0) = "001" then + -- do not read accu + alu_ctrl.shift_mode <= ZEROS; + -- Read S + if instr_word_var(6) = '1' then + alu_ctrl.add_src_stage_1 <= instr_word_var(6 downto 4); -- source register (JJJ encoding) + else + alu_ctrl.add_src_stage_1 <= "001"; -- B,A or A,B (depending on dest. accu) + end if; + alu_ctrl.add_src_stage_2 <= "01"; -- select the register source + alu_ctrl.add_src_sign <= "00"; -- with positive sign + alu_ctrl.rounding_used <= "00"; -- no rounding needed + alu_ctrl.store_result <= '1'; -- store the result + -- do not set any flag at all! + end if; + -- TST + if instr_word_var(7 downto 4) = "0000" and instr_word_var(2 downto 0) = "011" then + -- do not read accu + alu_ctrl.shift_mode <= NO_SHIFT; -- no shift + alu_ctrl.shift_src <= instr_word_var(3); -- read source accu + alu_ctrl.shift_src_sign <= "00"; -- sign unchanged + -- Read S + alu_ctrl.add_src_stage_2 <= "00"; -- select zero + alu_ctrl.add_src_sign <= "00"; -- with positive sign + alu_ctrl.rounding_used <= "00"; -- no rounding needed + alu_ctrl.store_result <= '0'; -- do not store the result + -- set all flags but carry! + for i in 1 to 7 loop + alu_ctrl.ccr_flags_ctrl(i) <= MODIFY; + end loop; + end if; + end if; -- Parallel move ALU instructions + + -- Tcc + if alu_tcc_decoded = '1' then + -- Read source + if instr_word_var(6) = '1' then + alu_ctrl.add_src_stage_1 <= instr_word_var(6 downto 4); -- source register (JJJ encoding) + else + alu_ctrl.add_src_stage_1 <= "001"; -- B,A or A,B (depending on dest. accu) + end if; + alu_ctrl.add_src_stage_2 <= "01"; -- select the registers as source + -- The .store_result flag is generated in the execute stage + -- depending on the condition codes + -- do not set any flag at all! + end if; +--mul_op1 : std_logic_vector(1 downto 0); -- x0,x1,y0,y1 +--mul_op2 : std_logic_vector(1 downto 0); -- x0,x1,y0,y1 +--shift_src : std_logic; -- a,b +--shift_src_sign : std_logic_vector(1 downto 0); -- 00: pos, 01: neg, 10: sign dependant, 11: reserved +--shift_mode : alu_shift_mode; +--add_src_stage_1 : std_logic_vector(2 downto 0); -- x0,x1,y0,y1,x,y,a,b +--add_src_stage_2 : std_logic_vector(1 downto 0); -- 00: 0 , 01: add_src_1, 10: mul_result, 11: reserved +--add_src_sign : std_logic_vector(1 downto 0); -- 00: pos, 01: neg, 10: sign dependant, 11: div instruction! +--logic_function : std_logic_vector(2 downto 0); -- 000: none, 110: and, 010: or, 011: eor, 111: not +--word_24_update : std_logic; -- only accumulator bits 47 downto 24 affected? +--rounding_used : std_logic_vector(1 downto 0); -- 00: no rounding, 01: rounding, 10: add carry, 11: subtract carry +--store_result : std_logic; -- 0: do not update accumulator, 1: update accumulator +--dst_accu : std_logic; -- 0: a, 1: b + -- DIV + if alu_div_decoded = '1' then + alu_ctrl.store_result <= '1'; -- do store the result + -- shifter operation + alu_ctrl.shift_mode <= SHIFT_LEFT; -- shift left + alu_ctrl.shift_src <= instr_word_var(3); -- read source accu + alu_ctrl.div_instr <= '1'; -- this is THE div instruction, special handling needed + -- source operand loading + alu_ctrl.add_src_stage_1 <= instr_word_var(6 downto 4); -- source register (JJJ encoding) + alu_ctrl.add_src_stage_2 <= "01"; -- select the registers as source + alu_ctrl.add_src_sign <= "11"; -- div instruction, sign dependant on D[55] XOR S[23] + -- if 1: positive, if 0: negative + alu_ctrl.ccr_flags_ctrl(C_FLAG) <= MODIFY; + alu_ctrl.ccr_flags_ctrl(V_FLAG) <= MODIFY; + alu_ctrl.ccr_flags_ctrl(L_FLAG) <= MODIFY; + end if; + -- NORM + if alu_norm_decoded = '1' then + -- set all alu-ctrl signals to ASL/ASR already here + -- depending on the condition code registers the flags + -- will be completed in the execute stage + alu_ctrl.norm_instr <= '1'; + -- Read accu + --alu_ctrl.shift_mode <= SHIFT_RIGHT/SHIFT_LEFT/NO_SHIFT; + alu_ctrl.shift_src <= instr_word_var(3); -- accumulate to the same register we want to write to + alu_ctrl.shift_src_sign <= "00"; -- with the original sign + -- Read S + alu_ctrl.add_src_stage_2 <= "00"; -- select zero as operand + alu_ctrl.add_src_sign <= "00"; -- with original sign + alu_ctrl.store_result <= '1'; -- store the result + alu_ctrl.rounding_used <= "00"; -- no rounding needed + -- set all flags, V-flag will be cleared due to shifting + for i in 0 to 7 loop + alu_ctrl.ccr_flags_ctrl(i) <= MODIFY; + end loop; + + end if; + end process; + + + instruction_decoder: process(instr_word, activate_dec) is + variable instr_word_var : std_logic_vector(23 downto 0); + procedure activate_AGU is + begin + -- check for immediate long addressing + if instr_word_var(13 downto 8) = "110100" then + act_array(ACT_IMM_LONG) <= '1'; + act_array(ACT_X_MEM_RD) <= '0'; -- No memory accesses for Immediate addressing! + act_array(ACT_Y_MEM_RD) <= '0'; + act_array(ACT_X_MEM_WR) <= '0'; + act_array(ACT_Y_MEM_WR) <= '0'; + else + act_array(ACT_ADGEN) <= '1'; + end if; + end procedure activate_AGU; + begin + instr_array_int <= INSTR_NOP; + act_array <= (others => '0'); + adgen_bittype <= NOP; + reg_rd_addr <= (others => '0'); + reg_wr_addr <= (others => '0'); + x_bus_rd_addr <= (others => '0'); + x_bus_wr_addr <= (others => '0'); + y_bus_rd_addr <= (others => '0'); + y_bus_wr_addr <= (others => '0'); + l_bus_addr <= instr_word_var(19) & instr_word_var(17 downto 16); + + alu_tcc_decoded <= '0'; + alu_div_decoded <= '0'; + alu_norm_decoded <= '0'; + + -- in case the decoding is not activated we insert a nop + if activate_dec = '1' then + instr_word_var := instr_word; + else + instr_word_var := (others => '0'); + end if; + + if instr_word_var(23 downto 16) = X"00" then + case instr_word_var(15 downto 0) is + when X"0000" => instr_array_int <= INSTR_NOP; + when X"0004" => instr_array_int <= INSTR_RTI; act_array(ACT_EXEC_BRA) <= '1'; + when X"0005" => instr_array_int <= INSTR_ILLEGAL; + when X"0006" => instr_array_int <= INSTR_SWI; + when X"000C" => instr_array_int <= INSTR_RTS; act_array(ACT_EXEC_BRA) <= '1'; + when X"0084" => instr_array_int <= INSTR_RESET; + when X"0086" => instr_array_int <= INSTR_WAIT; + when X"0087" => instr_array_int <= INSTR_STOP; + when X"008C" => instr_array_int <= INSTR_ENDDO; + act_array(ACT_EXEC_LOOP) <= '1'; + when others => + act_array(ACT_EXEC_CR_MOD) <= '1'; -- modify control register + if instr_word_var(7 downto 2) = "101110" then + instr_array_int <= INSTR_ANDI; + elsif instr_word_var(7 downto 2) = "111110" then + instr_array_int <= INSTR_ORI; + end if; + end case; + end if; + --------------------------------------------------------- + -- DIV and NORM + --------------------------------------------------------- + if instr_word_var(23 downto 16) = X"01" then + -- DIV + if instr_word_var(15 downto 6) = "1000000001" and instr_word_var(2 downto 0) = "000" then + alu_div_decoded <= '1'; + act_array(ACT_ALU) <= '1'; -- force ALU to update status register + end if; + -- NORM + if instr_word_var(15 downto 11) = "11011" and instr_word_var(7 downto 4) = "0001" and + instr_word_var(2 downto 0) = "101" then + alu_norm_decoded <= '1'; + act_array(ACT_NORM) <= '1'; -- NORM instruction decoded, + -- special handling in exec-stage is caused + act_array(ACT_REG_RD) <= '1'; + reg_rd_addr <= instr_word_var(13 downto 12) & '0' & instr_word_var(10 downto 8); -- Write same Rn + act_array(ACT_REG_WR) <= '1'; + reg_wr_addr <= instr_word_var(13 downto 12) & '0' & instr_word_var(10 downto 8); -- Write same Rn + end if; + end if; + --------------------------------------------------------- + -- Tcc + --------------------------------------------------------- + if instr_word_var(23 downto 16) = X"02" or instr_word_var(23 downto 16) = X"03" then + -- Tcc S1, D1 S2, D2 (ALU/Reg file) + if instr_word_var(16) = '0' and instr_word_var(11 downto 7) = "00000" and + instr_word_var(2 downto 0) = "000" then + act_array(ACT_ALU_WR_CC) <= '1'; + alu_tcc_decoded <= '1'; + -- Tcc S1, D1 S2, D2 (ALU/Reg file) + elsif instr_word_var(16) = '1' and instr_word_var(11) = '0' and + instr_word_var(7) = '0' then + act_array(ACT_ALU_WR_CC) <= '1'; + alu_tcc_decoded <= '1'; + act_array(ACT_REG_WR_CC) <= '1'; + reg_rd_addr <= "010" & instr_word_var(10 downto 8); -- Read Rn + reg_wr_addr <= "010" & instr_word_var( 2 downto 0); -- Write to other Rn + end if; + end if; + --------------------------------------------------------- + -- MOVEC and LUA instruction with registers + --------------------------------------------------------- + if instr_word_var(23 downto 16) = X"04" then + act_array(ACT_REG_WR) <= '1'; + -- LUA instruction + if instr_word_var(15 downto 13) = "010" and instr_word_var(7 downto 4) = "0001" then + instr_array_int <= INSTR_LUA; + act_array(ACT_ADGEN) <= '1'; + adgen_bittype <= SINGLE_X_SHORT; + reg_wr_addr <= instr_word_var(5 downto 0); + end if; + -- MOVEC instruction (S1, D2) or (S2, D1) + if instr_word_var(14) = '1' and instr_word_var(7 downto 5) = "101" then + instr_array_int <= INSTR_MOVEC; + act_array(ACT_REG_RD) <= '1'; + -- Write D1 + if instr_word_var(15) = '1' then + reg_wr_addr <= instr_word_var(5 downto 0); + reg_rd_addr <= instr_word_var(13 downto 8); + -- Read S1 + else + reg_wr_addr <= instr_word_var(13 downto 8); + reg_rd_addr <= instr_word_var(5 downto 0); + end if; + end if; + end if; + ------------------------------------------------------------------------- + -- MOVEC instruction with memory access/absolute address + ------------------------------------------------------------------------- + if instr_word_var(23 downto 16) = X"05" and + instr_word_var(7) = '0' and instr_word_var(5) = '1' then + + instr_array_int <= INSTR_MOVEC; + -- read from memory, write to register + if instr_word_var(15) = '1' then + act_array(ACT_REG_WR) <= '1'; + reg_wr_addr <= instr_word_var(5 downto 0); + -- X Memory read? + if instr_word_var(6) = '0' then + act_array(ACT_X_MEM_RD) <= '1'; + -- Y Memory read? + else + act_array(ACT_Y_MEM_RD) <= '1'; + end if; + -- write to memory, read register + else + act_array(ACT_REG_RD) <= '1'; + reg_rd_addr <= instr_word_var(5 downto 0); + -- X Memory write? + if instr_word_var(6) = '0' then + act_array(ACT_X_MEM_WR) <= '1'; + -- Y Memory write? + else + act_array(ACT_Y_MEM_WR) <= '1'; + end if; + end if; + -- AGU needed? + if instr_word_var(14) = '1' then + -- detect whether two word instruction! + adgen_bittype <= SINGLE_X; + -- check for immediate long addressing + if instr_word_var(13 downto 8) = "110100" then + act_array(ACT_IMM_LONG) <= '1'; + act_array(ACT_X_MEM_RD) <= '0'; -- No memory accesses for Immediate addressing! + act_array(ACT_Y_MEM_RD) <= '0'; + act_array(ACT_X_MEM_WR) <= '0'; + act_array(ACT_Y_MEM_WR) <= '0'; + else + act_array(ACT_ADGEN) <= '1'; + end if; + else + -- X:/Y:aa short is done in the adgen-stage automatically + end if; + end if; + ------------------------------------------------------------------------- + -- MOVEC instruction with immediate + ------------------------------------------------------------------------- + if instr_word_var(23 downto 16) = X"05" and instr_word_var(7 downto 5) = "101" then + instr_array_int <= INSTR_MOVEC; + act_array(ACT_IMM_8BIT) <= '1'; + act_array(ACT_REG_WR) <= '1'; + reg_wr_addr <= instr_word_var(5 downto 0); + end if; + --------------------------------- + -- REP or DO loop? + --------------------------------- + if instr_word_var(23 downto 16) = X"06" then + -- Instruction encoding is the same for both except of this bit + if instr_word_var(5) = '1' then + instr_array_int <= INSTR_REP; + else + instr_array_int <= INSTR_DO; + end if; + act_array(ACT_EXEC_LOOP) <= '1'; + -- Init reading of loop counter from memory + if instr_word_var(15) = '0' and instr_word_var(7) = '0' then + -- X/Y: ea? + if instr_word_var(14) = '1' then + act_array(ACT_ADGEN) <= '1'; + end if; + -- X/Y: aa? + -- Done automatically in the ADGEN stage by testing whether the ADGEN unit activated or not! + -- If not the absolute address stored in the instruction word is used. + ------- + -- only a single memory access is required + adgen_bittype <= SINGLE_X; + -- X/Y as source? + if instr_word_var(6) = '0' then + act_array(ACT_X_MEM_RD) <= '1'; + else + act_array(ACT_Y_MEM_RD) <= '1'; + end if; + elsif instr_word_var(15) = '1' and instr_word_var(7) = '0' then + -- S (register as source) + reg_rd_addr <= instr_word_var(13 downto 8); + act_array(ACT_REG_RD) <= '1'; + -- #xxx ,12 bit immediate + elsif instr_word_var(7 downto 6) = "10" and instr_word_var(4) = '0' then + act_array(ACT_IMM_12BIT) <= '1'; + end if; + end if; + -------------------------------- + -- MOVEM (Program memory move) + -------------------------------- + if instr_word_var(23 downto 16) = X"07" then + -- read memory, write reg + if instr_word_var(15) = '1' then + act_array(ACT_REG_WR) <= '1'; + reg_wr_addr <= instr_word_var(5 downto 0); + act_array(ACT_P_MEM_RD) <= '1'; + -- read reg, write memory + elsif instr_word_var(15) = '0' then + act_array(ACT_REG_RD) <= '1'; + reg_rd_addr <= instr_word_var(5 downto 0); + act_array(ACT_P_MEM_WR) <= '1'; + end if; + -- AGU needed? + if instr_word_var(14) = '1' and instr_word_var(7 downto 6) = "10" then + adgen_bittype <= SINGLE_X; + -- activate AGU and test whether immediate data is used + activate_AGU; + elsif instr_word_var(14) = '0' and instr_word_var(7 downto 6) = "00" then + -- X:/Y:aa short is done in the adgen-stage automatically + end if; + end if; + -------------------------------- + -- MOVEP (Peripheral memory move) + -------------------------------- + if instr_word_var(23 downto 16) = "0000100-" then + -- TODO?? Why parallel moves in software model?? + case instr_word_var(15 downto 0) is +-- when "-1------1-------" => instr_array_int(INSTR_MOVEP) <= '1'; +-- when "-1------01------" => instr_array_int(INSTR_MOVEP) <= '1'; +-- when "-1------00------" => instr_array_int(INSTR_MOVEP) <= '1'; + when others => + end case; + end if; + -- BSET, BCLR, BCHG, BTST, JCLR, JSET, JSCLR, JSSET, JMP, JCC, JSCC, JSR + if instr_word_var(23 downto 16) = X"0A" or instr_word_var(23 downto 16) = X"0B" then + + reg_rd_addr <= instr_word_var(13 downto 8); + reg_wr_addr <= instr_word_var(13 downto 8); + + if instr_word_var(16) = '0' then + if instr_word_var(7) = '0' and instr_word_var(5) = '0' then + instr_array_int <= INSTR_BCLR; + elsif instr_word_var(7) = '0' and instr_word_var(5) = '1' then + instr_array_int <= INSTR_BSET; + elsif instr_word_var(7) = '1' and instr_word_var(5) = '0' then + instr_array_int <= INSTR_JCLR; + elsif instr_word_var(7) = '1' and instr_word_var(5) = '1' then + instr_array_int <= INSTR_JSET; + end if; + elsif instr_word_var(16) = '1' then + if instr_word_var(7) = '0' and instr_word_var(5) = '0' then + instr_array_int <= INSTR_BCHG; + elsif instr_word_var(7) = '0' and instr_word_var(5) = '1' then + instr_array_int <= INSTR_BTST; + elsif instr_word_var(7) = '1' and instr_word_var(5) = '0' then + instr_array_int <= INSTR_JSCLR; + elsif instr_word_var(7) = '1' and instr_word_var(5) = '1' then + instr_array_int <= INSTR_JSSET; + end if; + end if; + if instr_word_var(7) = '1' then + act_array(ACT_EXEC_BRA) <= '1'; + end if; + + -- memory access? + if instr_word_var(15) = '0' then + -- X: + if instr_word_var(6) = '0' then + act_array(ACT_X_MEM_RD) <= '1'; + -- if not a jump instruction and not BTST write back the result + if instr_word_var(7) = '0' and not(instr_word_var(16) = '1' and instr_word_var(5) = '1') then + act_array(ACT_X_MEM_WR) <= '1'; + end if; + -- Y: + else + act_array(ACT_Y_MEM_RD) <= '1'; + -- if not a jump instruction and not BTST write back the result + if instr_word_var(7) = '0' and not(instr_word_var(16) = '1' and instr_word_var(5) = '1') then + act_array(ACT_Y_MEM_WR) <= '1'; + end if; + end if; + end if; + + case instr_word_var(15 downto 14) is + -- X:/Y: aa + when "00" => + + -- X:/Y: ea + when "01" => + act_array(ACT_ADGEN) <= '1'; + adgen_bittype <= SINGLE_X; + + -- X:/Y: pp + -- TODO! + when "10" => + + when others => -- "11" + if instr_word_var(7 downto 0) = "10000000" then + -- JMP/JSR ea + act_array(ACT_EXEC_BRA) <= '1'; + act_array(ACT_ADGEN) <= '1'; + adgen_bittype <= SINGLE_X; + if instr_word_var(16) = '0' then + instr_array_int <= INSTR_JMP; + elsif instr_word_var(16) = '1' then + instr_array_int <= INSTR_JSR; + end if; + elsif instr_word_var(7 downto 4) = "1010" then + -- JCC/JSCC ea + act_array(ACT_EXEC_BRA) <= '1'; + act_array(ACT_ADGEN) <= '1'; + adgen_bittype <= SINGLE_X; + if instr_word_var(16) = '0' then + instr_array_int <= INSTR_JCC; + elsif instr_word_var(16) = '1' then + instr_array_int <= INSTR_JSCC; + end if; + -- JSCLR,JSET,JCLR,JSSET,BTST,BCLR,BSET,BCHG S/D + else + act_array(ACT_REG_RD) <= '1'; + -- if not a jump instruction and not BTST write back the result + if instr_word_var(7) = '0' and not(instr_word_var(16) = '1' and instr_word_var(5) = '1') then + act_array(ACT_REG_WR) <= '1'; + end if; + end if; + end case; + end if; + -- JMP xxx (absoulute short) + if instr_word_var(23 downto 16) = X"0C" then + if instr_word_var(15 downto 12) = "0000" then + instr_array_int <= INSTR_JMP; + act_array(ACT_EXEC_BRA) <= '1'; + end if; + end if; + -- JSR xxx (absolute short) + if instr_word_var(23 downto 16) = X"0D" then + if instr_word_var(15 downto 12) = "0000" then + instr_array_int <= INSTR_JSR; + act_array(ACT_EXEC_BRA) <= '1'; + end if; + end if; + -- JCC xxx (absolute short) + if instr_word_var(23 downto 16) = X"0E" then + instr_array_int <= INSTR_JCC; + act_array(ACT_EXEC_BRA) <= '1'; + end if; + -- JSCC xxx (absolute short) + if instr_word_var(23 downto 16) = X"0F" then + instr_array_int <= INSTR_JSCC; + act_array(ACT_EXEC_BRA) <= '1'; + end if; + + ------------------------------------------------ + -- PARALLEL MOVE SECTION!! + ------------------------------------------------ + -- Here are the ALU operations that allow for parallel moves + if instr_word_var(23 downto 20) /= "0000" then + act_array(ACT_ALU) <= '1'; -- force ALU to update status register + end if; + -- PM: I + if instr_word_var(23 downto 21) = "001" and instr_word_var(20 downto 18) /= "000" then + act_array(ACT_IMM_8BIT) <= '1'; + act_array(ACT_REG_WR) <= '1'; + reg_wr_addr <= '0' & instr_word_var(20 downto 16); + end if; + -- PM: R + if instr_word_var(23 downto 18) = "001000" then + act_array(ACT_REG_WR) <= '1'; + reg_wr_addr <= '0' & instr_word_var(12 downto 8); + act_array(ACT_REG_RD) <= '1'; + reg_rd_addr <= '0' & instr_word_var(17 downto 13); + end if; + -- PM: U + if instr_word_var(23 downto 13) = "00100000010" then + act_array(ACT_ADGEN) <= '1'; + adgen_bittype <= SINGLE_X_SHORT; + end if; + -- PM: X or PM:Y + if instr_word_var(23 downto 22) = "01" and + -- Check whether L: type parallel move. If so do not enter this branch! + not (instr_word_var(21 downto 20) = "00" and instr_word_var(18) = '0') then + -- read memory, write reg + if instr_word_var(15) = '1' then + act_array(ACT_REG_WR) <= '1'; + reg_wr_addr <= '0' & instr_word_var(21 downto 20) & instr_word_var(18 downto 16); -- TODO: CHECK!! + -- X Memory read? + if instr_word_var(19) = '0' then + act_array(ACT_X_MEM_RD) <= '1'; + -- Y Memory read? + else + act_array(ACT_Y_MEM_RD) <= '1'; + end if; + -- read reg, write memory + elsif instr_word_var(15) = '0' then + act_array(ACT_REG_RD) <= '1'; + reg_rd_addr <= '0' & instr_word_var(21 downto 20) & instr_word_var(18 downto 16); -- TODO: CHECK!! + -- X Memory write? + if instr_word_var(19) = '0' then + act_array(ACT_X_MEM_WR) <= '1'; + -- Y Memory write? + else + act_array(ACT_Y_MEM_WR) <= '1'; + end if; + end if; + -- AGU needed? + if instr_word_var(14) = '1' then + -- detect whether two word instruction! + adgen_bittype <= SINGLE_X; + -- activate AGU and test whether immediate data is used + activate_AGU; + else + -- X:/Y:aa short is done in the adgen-stage automatically + end if; + end if; + -- PM: X:R or R:Y (Class I) + if instr_word_var(23 downto 20) = "0001" then + adgen_bittype <= SINGLE_X; + -- X:R + if instr_word_var(14) = '0' then + x_bus_rd_addr <= instr_word_var(19 downto 18); + x_bus_wr_addr <= instr_word_var(19 downto 18); + y_bus_rd_addr <= '1' & instr_word_var(17); + y_bus_wr_addr <= '0' & instr_word_var(16); -- TODO: Check encoding, manual uses three fs! + -- S2,D2 in any case! + act_array(ACT_Y_BUS_RD) <= '1'; + act_array(ACT_Y_BUS_WR) <= '1'; + -- Write D1? + if instr_word_var(15) = '1' then + act_array(ACT_X_MEM_RD) <= '1'; + act_array(ACT_X_BUS_WR) <= '1'; + else + -- Read S1? + act_array(ACT_X_MEM_WR) <= '1'; + act_array(ACT_X_BUS_RD) <= '1'; + end if; + -- R:Y + elsif instr_word_var(14) = '1' then + x_bus_rd_addr <= '1' & instr_word_var(19); + x_bus_wr_addr <= '0' & instr_word_var(18); + y_bus_rd_addr <= instr_word_var(17 downto 16); + y_bus_wr_addr <= instr_word_var(17 downto 16); + -- S1,D1 in any case! + act_array(ACT_X_BUS_RD) <= '1'; + act_array(ACT_X_BUS_WR) <= '1'; + -- Write D1? + if instr_word_var(15) = '1' then + act_array(ACT_Y_MEM_RD) <= '1'; + act_array(ACT_Y_BUS_WR) <= '1'; + else + -- Read S1? + act_array(ACT_Y_MEM_WR) <= '1'; + act_array(ACT_Y_BUS_RD) <= '1'; + end if; + + end if; + -- detect whether two word instruction! + adgen_bittype <= SINGLE_X; + -- activate AGU and test whether immediate data is used + activate_AGU; + end if; + -- PM: X:R or R:Y (Class II) + if instr_word_var(23 downto 17) = "0000100" and instr_word_var(14) = '0' then + act_array(ACT_REG_RD) <= '1'; + -- X:R + if instr_word_var(15) = '0' then + reg_rd_addr <= "00111" & instr_word_var(16); -- read A or B + act_array(ACT_X_MEM_WR) <= '1'; -- and store it in X memory + x_bus_rd_addr <= "00"; -- read x0 + x_bus_wr_addr <= '1' & instr_word_var(16); -- and write to A or B + act_array(ACT_X_BUS_RD) <= '1'; + act_array(ACT_X_BUS_WR) <= '1'; + -- R:Y + elsif instr_word_var(15) = '1' then + reg_rd_addr <= "00111" & instr_word_var(16); -- read A or B + act_array(ACT_Y_MEM_WR) <= '1'; -- and store it in Y memory + y_bus_rd_addr <= "00"; -- read y0 + y_bus_wr_addr <= '1' & instr_word_var(16); -- and write to A or B + act_array(ACT_Y_BUS_RD) <= '1'; + act_array(ACT_Y_BUS_WR) <= '1'; + end if; + -- detect whether two word instruction! + adgen_bittype <= SINGLE_X; + -- activate AGU and test whether immediate data is used + activate_AGU; + end if; + -- PM: L: + l_bus_addr <= instr_word_var(19) & instr_word_var(17 downto 16); + if instr_word_var(23 downto 20) = "0100" and instr_word_var(18) = '0' then + -- Read S? + if instr_word_var(15) = '0' then + act_array(ACT_L_BUS_RD) <= '1'; + act_array(ACT_X_MEM_WR) <= '1'; + act_array(ACT_Y_MEM_WR) <= '1'; + else -- Write D + act_array(ACT_L_BUS_WR) <= '1'; + act_array(ACT_X_MEM_RD) <= '1'; + act_array(ACT_Y_MEM_RD) <= '1'; + end if; + if instr_word_var(14) = '1' then + adgen_bittype <= SINGLE_X; + activate_AGU; + else + -- L:aa automatically performed in ADGEN stage + end if; + end if; + -- PM: X: Y: + if instr_word_var(23) = '1' then + adgen_bittype <= DOUBLE_X_Y; + -- No immediate value allowed, so activate in any case! + act_array(ACT_ADGEN) <= '1'; + -- S1, X: + if instr_word_var(15) = '0' then + act_array(ACT_X_BUS_RD) <= '1'; + x_bus_rd_addr <= instr_word_var(19 downto 18); + act_array(ACT_X_MEM_WR) <= '1'; + -- X:, D1 + else + act_array(ACT_X_BUS_WR) <= '1'; + x_bus_wr_addr <= instr_word_var(19 downto 18); + act_array(ACT_X_MEM_RD) <= '1'; + end if; + -- S2, Y: + if instr_word_var(22) = '0' then + act_array(ACT_Y_BUS_RD) <= '1'; + y_bus_rd_addr <= instr_word_var(17 downto 16); + act_array(ACT_Y_MEM_WR) <= '1'; + -- Y:, D2 + else + act_array(ACT_Y_BUS_WR) <= '1'; + y_bus_wr_addr <= instr_word_var(17 downto 16); + act_array(ACT_Y_MEM_RD) <= '1'; + end if; + end if; + end process; + + adgen_decoder: process(adgen_bittype, instr_word) is + begin + adgen_mode_a <= NOP; + adgen_mode_b <= NOP; + ea_extension_available <= '0'; + + case adgen_bittype is + when SINGLE_X => + case instr_word(13 downto 11) is + when "000" => adgen_mode_a <= POST_MIN_N; + when "001" => adgen_mode_a <= POST_PLUS_N; + when "010" => adgen_mode_a <= POST_MIN_1; + when "011" => adgen_mode_a <= POST_PLUS_1; + when "100" => adgen_mode_a <= NOP; + when "101" => adgen_mode_a <= INDEXED_N; + when "111" => adgen_mode_a <= PRE_MIN_1; + when "110" => + if instr_word(10 downto 8) = "000" then + adgen_mode_a <= ABSOLUTE; + ea_extension_available <= '1'; + elsif instr_word(10 downto 8) = "100" then + adgen_mode_a <= IMMEDIATE; + ea_extension_available <= '1'; + else + adgen_mode_a <= NOP; -- INVALID OPCODE! + end if; + when others => + end case; + when SINGLE_X_SHORT => + case instr_word(12 downto 11) is + when "00" => adgen_mode_a <= POST_MIN_N; + when "01" => adgen_mode_a <= POST_PLUS_N; + when "10" => adgen_mode_a <= POST_MIN_1; + when "11" => adgen_mode_a <= POST_PLUS_1; + when others => + end case; + when DOUBLE_X_Y => + case instr_word(12 downto 11) is + when "00" => adgen_mode_a <= NOP; + when "01" => adgen_mode_a <= POST_PLUS_N; + when "10" => adgen_mode_a <= POST_MIN_1; + when "11" => adgen_mode_a <= POST_PLUS_1; + when others => + end case; + case instr_word(21 downto 20) is + when "00" => adgen_mode_b <= NOP; + when "01" => adgen_mode_b <= POST_PLUS_N; + when "10" => adgen_mode_b <= POST_MIN_1; + when "11" => adgen_mode_b <= POST_PLUS_1; + when others => + end case; + when others => + end case; + end process adgen_decoder; + +end architecture rtl; + diff --git a/vhdl/rtl/vhdl/DSP/src/exec_stage_alu.vhd b/vhdl/rtl/vhdl/DSP/src/exec_stage_alu.vhd new file mode 100644 index 0000000..9f3c3b9 --- /dev/null +++ b/vhdl/rtl/vhdl/DSP/src/exec_stage_alu.vhd @@ -0,0 +1,603 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +library work; +use work.parameter_pkg.all; +use work.types_pkg.all; +use work.constants_pkg.all; + +entity exec_stage_alu is port( + alu_activate : in std_logic; + instr_word : in std_logic_vector(23 downto 0); + alu_ctrl : in alu_ctrl_type; + register_file : in register_file_type; + addr_r_in : in unsigned(BW_ADDRESS-1 downto 0); + addr_r_out : out unsigned(BW_ADDRESS-1 downto 0); + modify_accu : out std_logic; + dst_accu : out std_logic; + modified_accu : out signed(55 downto 0); + modify_sr : out std_logic; + modified_sr : out std_logic_vector(15 downto 0) +); +end entity; + +architecture rtl of exec_stage_alu is + + signal alu_shifter_out : signed(55 downto 0); + signal alu_shifter_carry_out : std_logic; + signal alu_shifter_overflow_out : std_logic; + + signal alu_logic_conj : signed(55 downto 0); + signal alu_multiplier_out : signed(55 downto 0); + signal alu_src_op : signed(55 downto 0); + signal alu_add_result : signed(56 downto 0); + signal alu_add_carry_out : std_logic; + signal alu_post_adder_result : signed(56 downto 0); + + signal scaling_mode : std_logic_vector(1 downto 0); + + signal modified_accu_int : signed(55 downto 0); + + signal norm_instr_asl : std_logic; + signal norm_instr_asr : std_logic; + signal norm_instr_nop : std_logic; + signal norm_update_ccr : std_logic; + +begin + + + -- store calculated value? + modify_accu <= alu_ctrl.store_result; + modified_accu <= modified_accu_int; + -- for the norm instruction we first need to determine whether we have to + -- update the CCR register or not + modify_sr <= alu_activate when alu_ctrl.norm_instr = '0' else + norm_update_ccr; + dst_accu <= alu_ctrl.dst_accu; + + scaling_mode <= register_file.sr(11 downto 10); + + + calcule_ccr_flags: process(register_file, alu_ctrl, alu_shifter_carry_out, + alu_post_adder_result, modified_accu_int, alu_add_carry_out) is + begin + -- by default do not modify the flags in the status register + modified_sr <= register_file.sr; + + -- Carry flag generation + ------------------------- + case alu_ctrl.ccr_flags_ctrl(C_FLAG) is + when CLEAR => modified_sr(C_FLAG) <= '0'; + when SET => modified_sr(C_FLAG) <= '1'; + when MODIFY => + -- the carry flag can stem from the shifter or from the post adder + -- in case we shift and add only a zero to the shift result (ASL, ASR, LSL, LSR, ROL, ROR) + -- take the carry flag from the shifter, else from the post adder + if (alu_ctrl.shift_mode = SHIFT_LEFT or alu_ctrl.shift_mode = SHIFT_RIGHT) and + alu_ctrl.add_src_stage_2 = "00" then -- add zero after shifting? + modified_sr(C_FLAG) <= alu_shifter_carry_out; + elsif alu_ctrl.div_instr = '1' then + modified_sr(C_FLAG) <= not std_logic(alu_post_adder_result(55)); + else +-- modified_sr(C_FLAG) <= std_logic(alu_post_adder_result(57)); + modified_sr(C_FLAG) <= alu_add_carry_out; + end if; + when others => -- Don't touch + end case; + + -- Overflow flag generation + ---------------------------- + case alu_ctrl.ccr_flags_ctrl(V_FLAG) is + when CLEAR => modified_sr(V_FLAG) <= '0'; + when SET => modified_sr(V_FLAG) <= '1'; + when MODIFY => + -- There are two sources for the overflow flag: + -- 1) + -- in case the result cannot be represented using 56 bits set + -- the overflow flag. this is the case when the two MSBs of + -- the 57 bit result are different + -- 2) + -- The shifter circuit performs a 56 bit left shift. In case the + -- two MSBs of the operand are different set the overflow flag as well + if (alu_ctrl.div_instr = '0' and alu_post_adder_result(56) /= alu_post_adder_result(55)) or + (alu_ctrl.shift_mode = SHIFT_LEFT and alu_ctrl.word_24_update = '0' and + alu_shifter_overflow_out = '1' ) then + modified_sr(V_FLAG) <= '1'; + else + modified_sr(V_FLAG) <= '0'; + end if; + when others => -- Don't touch + end case; + + -- Zero flag generation + ---------------------------- + case alu_ctrl.ccr_flags_ctrl(Z_FLAG) is + when CLEAR => modified_sr(Z_FLAG) <= '0'; + when SET => modified_sr(Z_FLAG) <= '1'; + when MODIFY => + -- in case the result is zero set this flag + -- distinguish between 24 bit and 56 bit ALU operations + -- 24 bit instructions are LSL, LSR, ROR, ROL, OR, EOR, NOT, AND + if (alu_ctrl.word_24_update = '1' and modified_accu_int(47 downto 24) = 0) or + (alu_ctrl.word_24_update = '0' and modified_accu_int(55 downto 0) = 0) then + modified_sr(Z_FLAG) <= '1'; + else + modified_sr(Z_FLAG) <= '0'; + end if; + when others => -- Don't touch + end case; + + -- Negative flag generation + ---------------------------- + case alu_ctrl.ccr_flags_ctrl(N_FLAG) is + when CLEAR => modified_sr(N_FLAG) <= '0'; + when SET => modified_sr(N_FLAG) <= '1'; + when MODIFY => + -- in case the result is negative set this flag + -- distinguish between 24 bit and 56 bit ALU operations + -- 24 bit instructions are LSL, LSR, ROR, ROL, OR, EOR, NOT, AND + if alu_ctrl.word_24_update = '1' then + modified_sr(N_FLAG) <= std_logic(modified_accu_int(47)); + else + modified_sr(N_FLAG) <= std_logic(modified_accu_int(55)); + end if; + when others => -- Don't touch + end case; + + -- Unnormalized flag generation + ---------------------------- + case alu_ctrl.ccr_flags_ctrl(U_FLAG) is + when CLEAR => modified_sr(U_FLAG) <= '0'; + when SET => modified_sr(U_FLAG) <= '1'; + when MODIFY => + -- Set unnormalized bit according to the scaling mode + if (scaling_mode = "00" and alu_post_adder_result(47) = alu_post_adder_result(46)) or + (scaling_mode = "01" and alu_post_adder_result(48) = alu_post_adder_result(47)) or + (scaling_mode = "10" and alu_post_adder_result(46) = alu_post_adder_result(45)) then + modified_sr(U_FLAG) <= '1'; + else + modified_sr(U_FLAG) <= '0'; + end if; + when others => -- Don't touch + end case; + + -- Extension flag generation + ---------------------------- + case alu_ctrl.ccr_flags_ctrl(E_FLAG) is + when CLEAR => modified_sr(E_FLAG) <= '0'; + when SET => modified_sr(E_FLAG) <= '1'; + when MODIFY => + -- Set extension flag by default + modified_sr(E_FLAG) <= '1'; + -- Clear extension flag according to the scaling mode + case scaling_mode is + when "00" => + if alu_post_adder_result(55 downto 47) = "111111111" or alu_post_adder_result(55 downto 47) = "000000000" then + modified_sr(E_FLAG) <= '0'; + end if; + when "01" => + if alu_post_adder_result(55 downto 48) = "11111111" or alu_post_adder_result(55 downto 48) = "00000000" then + modified_sr(E_FLAG) <= '0'; + end if; + when "10" => + if alu_post_adder_result(55 downto 46) = "1111111111" or alu_post_adder_result(55 downto 46) = "0000000000" then + modified_sr(E_FLAG) <= '0'; + end if; + when others => + modified_sr(E_FLAG) <= '0'; + end case; + when others => -- Don't touch + end case; + + -- Limit flag generation (equals overflow flag generaton!) + -- Clearing of the Limit flag has to be done by the user! + ----------------------------------------------------------- + case alu_ctrl.ccr_flags_ctrl(L_FLAG) is + when CLEAR => modified_sr(L_FLAG) <= '0'; + when SET => modified_sr(L_FLAG) <= '1'; + when MODIFY => + -- There are two sources for the overflow flag: + -- 1) + -- in case the result cannot be represented using 56 bits set + -- the overflow flag. this is the case when the two MSBs of + -- the 57 bit result are different + -- 2) + -- The shifter circuit performs a 56 bit left shift. In case the + -- two MSBs of the operand are different set the overflow flag as well + if (alu_ctrl.div_instr = '0' and alu_post_adder_result(56) /= alu_post_adder_result(55)) or + (alu_ctrl.shift_mode = SHIFT_LEFT and alu_ctrl.word_24_update = '0' and + alu_shifter_overflow_out = '1' ) then + modified_sr(L_FLAG) <= '1'; + end if; + when others => -- Don't touch + end case; + + -- Scaling flag generation (DSP56002 and up) + -------------------------------------------- + -- Scaling flag is not generated in the ALU, but when A or B are read to the XDB or YDB + + end process; + + + src_operand_select: process(register_file, alu_ctrl) is + begin + -- decoding according similar to JJJ representation + case alu_ctrl.add_src_stage_1 is + when "000" => + -- select depending on destination accu + if alu_ctrl.dst_accu = '0' then + alu_src_op <= register_file.a; + else + alu_src_op <= register_file.b; + end if; + when "001" => -- A,B or B,A + -- select depending on destination accu + if alu_ctrl.dst_accu = '0' then + alu_src_op <= register_file.b; + else + alu_src_op <= register_file.a; + end if; + when "010" => -- X + alu_src_op(55 downto 48) <= (others => register_file.x1(23)); + alu_src_op(47 downto 0) <= register_file.x1 & register_file.x0; + when "011" => -- Y + alu_src_op(55 downto 48) <= (others => register_file.y1(23)); + alu_src_op(47 downto 0) <= register_file.y1 & register_file.y0; + when "100" => -- x0 + alu_src_op(55 downto 48) <= (others => register_file.x0(23)); + alu_src_op(47 downto 24) <= register_file.x0; + alu_src_op(23 downto 0) <= (others => '0'); + when "101" => -- y0 + alu_src_op(55 downto 48) <= (others => register_file.y0(23)); + alu_src_op(47 downto 24) <= register_file.y0; + alu_src_op(23 downto 0) <= (others => '0'); + when "110" => -- x1 + alu_src_op(55 downto 48) <= (others => register_file.x1(23)); + alu_src_op(47 downto 24) <= register_file.x1; + alu_src_op(23 downto 0) <= (others => '0'); + when "111" => -- y1 + alu_src_op(55 downto 48) <= (others => register_file.y1(23)); + alu_src_op(47 downto 24) <= register_file.y1; + alu_src_op(23 downto 0) <= (others => '0'); + when others => + end case; + end process; + + alu_logical_functions: process(alu_ctrl, alu_src_op, alu_shifter_out) is + begin + alu_logic_conj <= alu_shifter_out; + case alu_ctrl.logic_function is + when "110" => + alu_logic_conj(47 downto 24) <= alu_shifter_out(47 downto 24) and alu_src_op(47 downto 24); + when "010" => + alu_logic_conj(47 downto 24) <= alu_shifter_out(47 downto 24) or alu_src_op(47 downto 24); + when "011" => + alu_logic_conj(47 downto 24) <= alu_shifter_out(47 downto 24) xor alu_src_op(47 downto 24); + when "111" => + alu_logic_conj(47 downto 24) <= not alu_shifter_out(47 downto 24); + when others => + end case; + end process; + + alu_adder : process(alu_ctrl, alu_src_op, alu_multiplier_out, alu_shifter_out) is + variable add_src_op_1 : signed(56 downto 0); + variable add_src_op_2 : signed(56 downto 0); + variable carry_const : signed(56 downto 0); + variable alu_shifter_out_57 : signed(56 downto 0); + variable alu_add_result_58 : signed(57 downto 0); + variable alu_add_result_interm : signed(56 downto 0); + variable invert_carry_flag : std_logic; + begin + + -- by default do not invert the carry + invert_carry_flag := '0'; + + -- determine whether to use multiplier output, the operand defined above, or zeros! + -- resizing is done here already. Like that we can see whether an overflow + -- occurs due to negating the source operand + case alu_ctrl.add_src_stage_2 is + when "00" => add_src_op_1 := (others => '0'); + when "10" => add_src_op_1 := resize(alu_multiplier_out, 57); + when others => add_src_op_1 := resize(alu_src_op, 57); + end case; + + -- determine the sign for the 1st operand! + case alu_ctrl.add_src_sign is + -- normal operation + when "00" => add_src_op_1 := add_src_op_1; + -- negative sign + when "01" => add_src_op_1 := - add_src_op_1; + invert_carry_flag := not invert_carry_flag; + -- change according to sign + -- performs - | accu | for the CMPM instruction + when "10" => + -- we subtract in any case, so invert the carry! + invert_carry_flag := not invert_carry_flag; + if add_src_op_1(55) = '0' then + add_src_op_1 := - add_src_op_1; + else + add_src_op_1 := add_src_op_1; + end if; + -- div instruction! + -- sign dependant of D[55] XOR S[23], if 1 => positive , if 0 => negative + -- add_src_op_1 holds S[23] (sign extension!) + when others => + if (alu_ctrl.shift_src = '0' and add_src_op_1(55) /= register_file.a(55)) or + (alu_ctrl.shift_src = '1' and add_src_op_1(55) /= register_file.b(55)) then + add_src_op_1 := add_src_op_1; + else + add_src_op_1 := - add_src_op_1; +-- invert_carry_flag := not invert_carry_flag; + end if; + end case; + + alu_shifter_out_57 := resize(alu_shifter_out, 57); + + -- determine the sign for the 2nd operand (coming from the shifter)! + case alu_ctrl.shift_src_sign is + -- negative sign + when "01" => + add_src_op_2 := - alu_shifter_out_57; + -- change according to sign + -- this allows to build the magnitude (ABS, CMPM) + when "10" => + if alu_shifter_out(55) = '1' then + add_src_op_2 := - alu_shifter_out_57; + else + add_src_op_2 := alu_shifter_out_57; + end if; + when others => + add_src_op_2 := alu_shifter_out_57; + end case; + + -- determine whether carry flag has to be added or subtracted + if alu_ctrl.rounding_used = "10" then + -- add carry flag + carry_const(0) := register_file.sr(C_FLAG); + elsif alu_ctrl.rounding_used = "11" then + -- subtract carry flag + carry_const := (others => register_file.sr(0)); -- carry flag + else + carry_const := (others => '0'); + end if; + + -- add the values and calculate the carry bit + alu_add_result_interm := ('0' & add_src_op_1(55 downto 0)) + + ('0' & add_src_op_2(55 downto 0)) + + ('0' & carry_const(55 downto 0)); + + -- here pops the new carry out of the adder + if invert_carry_flag = '0' then + alu_add_carry_out <= alu_add_result_interm(56); + else + alu_add_carry_out <= not alu_add_result_interm(56); + end if; + + -- calculate the last bit (56), in order to test for overflow later on + alu_add_result(55 downto 0) <= alu_add_result_interm(55 downto 0); +-- alu_add_result(56) <= add_src_op_1(56) xor add_src_op_2(56) xor alu_add_result_interm(56); + alu_add_result(56) <= add_src_op_1(56) xor add_src_op_2(56) + xor carry_const(56) xor alu_add_result_interm(56); + + end process alu_adder; + + + -- Adder after the normal arithmetic adder + -- This adder is responsible for +-- -- 1) carry addition +-- -- 2) carry subtration + -- 3) convergent rounding + alu_post_adder: process(alu_add_result, scaling_mode, alu_ctrl) is + variable post_adder_constant : signed(56 downto 0); + variable testing_constant : signed(24 downto 0); + begin + -- by default add nothing + post_adder_constant := (others => '0'); + + case alu_ctrl.rounding_used is + -- rounding dependant on scaling bits + when "01" => + case scaling_mode is + -- no scaling + when "00" => testing_constant := alu_add_result(23 downto 0) & '0'; + -- scale down + when "01" => testing_constant := alu_add_result(24 downto 0); + -- scale up + when "10" => testing_constant := alu_add_result(22 downto 0) & "00"; + when others => + testing_constant := alu_add_result(23 downto 0) & '0'; + end case; + + -- Special case! + if testing_constant(24) = '1' and testing_constant(23 downto 0) = X"000000" then + -- add depending on bit left to the rounding position + case scaling_mode is + -- no scaling + when "00" => post_adder_constant(23) := alu_add_result(24); + -- scale down + when "01" => post_adder_constant(24) := alu_add_result(25); + -- scale up + when "10" => post_adder_constant(22) := alu_add_result(23); + when others => + end case; + else -- testing_constant /= X"1000000" + -- add rounding constant depending on scaling mode + -- results in round up if MSB of testing constant is set, else nothing happens + case scaling_mode is + -- no scaling + when "00" => post_adder_constant(23) := '1'; + -- scale down + when "01" => post_adder_constant(24) := '1'; + -- scale up + when "10" => post_adder_constant(22) := '1'; + when others => + end case; + end if; + -- no rounding + when others => + post_adder_constant := (others => '0'); + + end case; + + -- Add the result of the first adder to the constant (e.g., carry flag) + alu_post_adder_result <= alu_add_result + post_adder_constant; + + -- When rounding is used set 24 LSBs to zero! + if alu_ctrl.rounding_used = "01" then + alu_post_adder_result(23 downto 0) <= (others => '0'); + end if; + end process; + + + + alu_select_new_accu: process(alu_post_adder_result, alu_logic_conj, alu_ctrl) is + begin + if alu_ctrl.logic_function /= "000" then + modified_accu_int <= alu_logic_conj; + else + modified_accu_int <= alu_post_adder_result(55 downto 0); + end if; + end process; + + + -- contains the 24*24 bit fractional multiplier + alu_multiplier : process(register_file, alu_ctrl) is + variable src_op1: signed(23 downto 0); + variable src_op2: signed(23 downto 0); + variable mul_result_interm : signed(47 downto 0); + begin + -- select source operands for multiplication + case alu_ctrl.mul_op1 is + when "00" => src_op1 := register_file.x0; + when "01" => src_op1 := register_file.x1; + when "10" => src_op1 := register_file.y0; + when others => src_op1 := register_file.y1; + end case; + case alu_ctrl.mul_op2 is + when "00" => src_op2 := register_file.x0; + when "01" => src_op2 := register_file.x1; + when "10" => src_op2 := register_file.y0; + when others => src_op2 := register_file.y1; + end case; + + -- perform integer multiplication + mul_result_interm := src_op1 * src_op2; + + -- sign extension of result + alu_multiplier_out(55 downto 48) <= (others => mul_result_interm(47)); + -- convert from two's complement representation to fractional format + -- signed integer multiplication delivers twice the sign bit, but only one is needed for the + -- fractional multiplication, so remove one and append a zero to the result + alu_multiplier_out(47 downto 0) <= mul_result_interm(46 downto 0) & '0'; + + end process alu_multiplier; + + + -- contains the data shifter + alu_shifter: process(register_file, alu_ctrl, norm_instr_asl, norm_instr_asr) is + variable src_accu : signed(55 downto 0); + variable shift_to_perform : alu_shift_mode; + begin + -- read source accumulator + if alu_ctrl.shift_src = '0' then + src_accu := register_file.a; + else + src_accu := register_file.b; + end if; + + alu_shifter_carry_out <= '0'; + alu_shifter_overflow_out <= '0'; + + -- NORM instruction determines the shift value just + -- in time, so overwrite the flag from the alu_ctrl + -- for this instruction by the calculated value + if alu_ctrl.norm_instr = '0' then + shift_to_perform := alu_ctrl.shift_mode; + else + if norm_instr_asl = '1' then + shift_to_perform := SHIFT_LEFT; + elsif norm_instr_asr = '1' then + shift_to_perform := SHIFT_RIGHT; + else + shift_to_perform := NO_SHIFT; + end if; + end if; + + case shift_to_perform is + when NO_SHIFT => + alu_shifter_out <= src_accu; + when SHIFT_LEFT => + -- ASL, ADDL, DIV? + if alu_ctrl.word_24_update = '0' then + -- special handling for div instruction required + if alu_ctrl.div_instr = '1' then + alu_shifter_out <= src_accu(54 downto 0) & register_file.sr(C_FLAG); + else + alu_shifter_out <= src_accu(54 downto 0) & '0'; + end if; + alu_shifter_carry_out <= src_accu(55); + -- detect overflow that results from left shifting + -- Needed for ASL, ADDL, DIV instructions + if src_accu(55) /= src_accu(54) then + alu_shifter_overflow_out <= '1'; + end if; + -- LSL/ROL? + elsif alu_ctrl.word_24_update = '1' then + alu_shifter_out(55 downto 48) <= src_accu(55 downto 48); + alu_shifter_out(23 downto 0) <= src_accu(23 downto 0); + alu_shifter_carry_out <= src_accu(47); + if alu_ctrl.rotate = '0' then -- LSL ? + alu_shifter_out(47 downto 24) <= src_accu(46 downto 24) & '0'; + else -- ROL ? + alu_shifter_out(47 downto 24) <= src_accu(46 downto 24) & register_file.sr(C_FLAG); + end if; + end if; + when SHIFT_RIGHT => + -- ASR? + if alu_ctrl.word_24_update = '0' then + alu_shifter_out <= src_accu(55) & src_accu(55 downto 1); + alu_shifter_carry_out <= src_accu(0); + -- LSR/ROR? + elsif alu_ctrl.word_24_update = '1' then + alu_shifter_out(55 downto 48) <= src_accu(55 downto 48); + alu_shifter_out(23 downto 0) <= src_accu(23 downto 0); + alu_shifter_carry_out <= src_accu(24); + if alu_ctrl.rotate = '0' then -- LSR + alu_shifter_out(47 downto 24) <= '0' & src_accu(47 downto 25); + else -- ROR + alu_shifter_out(47 downto 24) <= register_file.sr(C_FLAG) & src_accu(47 downto 25); + end if; + end if; + when ZEROS => + alu_shifter_out <= (others => '0'); + end case; + end process alu_shifter; + + + -- Special handling for NORM instruction + -- Determine which case occurs (see User's Manual for more information) + norm_instr_logic: process(register_file, addr_r_in) is + begin + norm_instr_asl <= '0'; + norm_instr_asr <= '0'; + + -- Either left shift + if register_file.sr(E_FLAG) = '0' and + register_file.sr(U_FLAG) = '1' and + register_file.sr(Z_FLAG) = '0' then + norm_instr_asl <= '1'; + norm_update_ccr <= '1'; + addr_r_out <= addr_r_in - 1; + -- Or right shift + elsif register_file.sr(E_FLAG) = '1' then + norm_instr_asr <= '1'; + norm_update_ccr <= '1'; + addr_r_out <= addr_r_in + 1; + -- Or do nothing! + else + norm_update_ccr <= '0'; + addr_r_out <= addr_r_in; + end if; + end process; + +end architecture; diff --git a/vhdl/rtl/vhdl/DSP/src/exec_stage_bit_modify.vhd b/vhdl/rtl/vhdl/DSP/src/exec_stage_bit_modify.vhd new file mode 100644 index 0000000..68fecbb --- /dev/null +++ b/vhdl/rtl/vhdl/DSP/src/exec_stage_bit_modify.vhd @@ -0,0 +1,79 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +library work; +use work.parameter_pkg.all; +use work.types_pkg.all; +use work.constants_pkg.all; + +entity exec_stage_bit_modify is port( + instr_word : in std_logic_vector(23 downto 0); + instr_array : in instructions_type; + src_operand : in std_logic_vector(23 downto 0); + register_file : in register_file_type; + dst_operand : out std_logic_vector(23 downto 0); + bit_cond_met : out std_logic; + modify_sr : out std_logic; + modified_sr : out std_logic_vector(15 downto 0) +); +end entity; + + +architecture rtl of exec_stage_bit_modify is + + signal operand_bit : std_logic; + signal src_operand_32 : std_logic_vector(31 downto 0); + +begin + + -- this is just a helper signal to prevent the simulator + -- to stop when accessing a bit > 23. + src_operand_32 <= "00000000" & src_operand; + -- read the bit we want to test (and modify) + operand_bit <= src_operand_32(to_integer(unsigned(instr_word(4 downto 0)))); + + -- modify the Carry flag only for the bit modify instructions! + modify_sr <= '1' when instr_array = INSTR_BCLR or instr_array = INSTR_BSET or instr_array = INSTR_BCHG or instr_array = INSTR_BTST else '0'; + modified_sr <= register_file.sr(15 downto 1) & operand_bit; + + bit_operation: process(instr_word, instr_array, src_operand, operand_bit) is + variable new_bit : std_logic; + begin + -- do nothing by default! + dst_operand <= src_operand; + bit_cond_met <= '0'; + + -- determine which bit to write + if instr_array = INSTR_BCLR then + new_bit := '0'; + elsif instr_array = INSTR_BSET then + new_bit := '1'; + else -- BCHG + new_bit := not operand_bit; + end if; + + if instr_array = INSTR_BCLR or instr_array = INSTR_BSET or instr_array = INSTR_BCHG then + dst_operand(to_integer(unsigned(instr_word(4 downto 0)))) <= new_bit; + end if; + + + -- check for the jump instructions whether condition is met or not! + if instr_array = INSTR_JCLR or instr_array = INSTR_JSCLR then + if operand_bit = '0' then + bit_cond_met <= '1'; + else + bit_cond_met <= '0'; + end if; + end if; + if instr_array = INSTR_JSET or instr_array = INSTR_JSSET then + if operand_bit = '0' then + bit_cond_met <= '0'; + else + bit_cond_met <= '1'; + end if; + end if; + + end process; + + +end architecture; diff --git a/vhdl/rtl/vhdl/DSP/src/exec_stage_branch.vhd b/vhdl/rtl/vhdl/DSP/src/exec_stage_branch.vhd new file mode 100644 index 0000000..9b07913 --- /dev/null +++ b/vhdl/rtl/vhdl/DSP/src/exec_stage_branch.vhd @@ -0,0 +1,117 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +library work; +use work.parameter_pkg.all; +use work.types_pkg.all; +use work.constants_pkg.all; + +entity exec_stage_branch is port( + activate_exec_bra : in std_logic; + instr_word : in std_logic_vector(23 downto 0); + instr_array : in instructions_type; + register_file : in register_file_type; + jump_address : in unsigned(BW_ADDRESS-1 downto 0); + bit_cond_met : in std_logic; + cc_flag_set : in std_logic; + push_stack : out push_stack_type; + pop_stack : out pop_stack_type; + modify_pc : out std_logic; + modified_pc : out unsigned(BW_ADDRESS-1 downto 0); + modify_sr : out std_logic; + modified_sr : out std_logic_vector(15 downto 0) +); +end entity; + + +architecture rtl of exec_stage_branch is + + signal branch_condition_met : std_logic; + signal modify_pc_int : std_logic; + +begin + + modify_pc_int <= '1' when activate_exec_bra = '1' and branch_condition_met = '1' else '0'; + modify_pc <= modify_pc_int; + + calculate_branch_condition : process(instr_word, instr_array, register_file, bit_cond_met) + begin + branch_condition_met <= '0'; + + -- unconditional jumps + if instr_array = INSTR_JMP or + instr_array = INSTR_JSR or + instr_array = INSTR_RTI or + instr_array = INSTR_RTS then + -- jump always + branch_condition_met <= '1'; + end if; + -- then see whether the branch condition is satisfied + if instr_array = INSTR_JCC or instr_array = INSTR_JSCC then + branch_condition_met <= cc_flag_set; + end if; + -- jmp that is executed according to a certain bit condition + if instr_array = INSTR_JCLR or instr_array = INSTR_JSCLR or + instr_array = INSTR_JSET or instr_array = INSTR_JSSET then + branch_condition_met <= bit_cond_met; + end if; + end process calculate_branch_condition; + + + calculate_branch_target : process(instr_array, instr_word, jump_address) + begin + modified_pc <= jump_address; + + -- address calculation is the same for the following instructions + if instr_array = INSTR_JMP or + instr_array = INSTR_JCC or + instr_array = INSTR_JSCC or + instr_array = INSTR_JSR then + if instr_word(18) = '1' then + -- short jump address included in opcode (bits 11 downto 0) + modified_pc(11 downto 0) <= unsigned(instr_word(11 downto 0)); + elsif instr_word(18) = '0' then + -- effective address defined by opcode and coming from address generator unit + modified_pc <= jump_address; + end if; + end if; + + -- jump address contains the obligatory address of the second + -- instruction word + if instr_array = INSTR_JCLR or + instr_array = INSTR_JSET or + instr_array = INSTR_JSCLR or + instr_array = INSTR_JSSET then + modified_pc <= jump_address; + end if; + + -- target address is stored on the stack + if instr_array = INSTR_RTS or + instr_array = INSTR_RTI then + modified_pc <= unsigned(register_file.current_ssh); + end if; + end process calculate_branch_target; + + -- Subroutine functions need to store PC and SR on the stack + push_stack.valid <= '1' when modify_pc_int = '1' and (instr_array = INSTR_JSCC or instr_array = INSTR_JSR or + instr_array = INSTR_JSCLR or instr_array = INSTR_JSSET) else '0'; + push_stack.content <= PC_AND_SR; + -- pc is set externally! + push_stack.pc <= (others => '0'); + + -- RTI/RTS instructions need to read from the stack + pop_stack.valid <= '1' when modify_pc_int = '1' and (instr_array = INSTR_RTI or instr_array = INSTR_RTS) else '0'; + + -- some instructions require to set the SR + calculate_status_register : process(instr_array) + begin + modify_sr <= '0'; + modified_sr <= (others => '0'); + if instr_array = INSTR_RTI then + modify_sr <= '1'; + modified_sr <= register_file.current_ssl; + end if; + end process calculate_status_register; + + +end architecture rtl; diff --git a/vhdl/rtl/vhdl/DSP/src/exec_stage_cc_flag_calc.vhd b/vhdl/rtl/vhdl/DSP/src/exec_stage_cc_flag_calc.vhd new file mode 100644 index 0000000..63a0b2c --- /dev/null +++ b/vhdl/rtl/vhdl/DSP/src/exec_stage_cc_flag_calc.vhd @@ -0,0 +1,75 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +library work; +use work.parameter_pkg.all; +use work.types_pkg.all; +use work.constants_pkg.all; + +entity exec_stage_cc_flag_calc is port( + instr_word : in std_logic_vector(23 downto 0); + instr_array : in instructions_type; + register_file : in register_file_type; + cc_flag_set : out std_logic +); +end entity; + + +architecture rtl of exec_stage_cc_flag_calc is + + +begin + + calculate_cc_flag : process(instr_word, instr_array, register_file) + + variable cc_select : std_logic_vector(3 downto 0); + + procedure calculate_cc_flag(cc: std_logic_vector(3 downto 0)) is + variable c_flag : std_logic := register_file.ccr(0); + variable v_flag : std_logic := register_file.ccr(1); + variable z_flag : std_logic := register_file.ccr(2); + variable n_flag : std_logic := register_file.ccr(3); + variable u_flag : std_logic := register_file.ccr(4); + variable e_flag : std_logic := register_file.ccr(5); + variable l_flag : std_logic := register_file.ccr(6); + + begin + if (cc = "0000" and c_flag = '0') or -- CC: carry clear + (cc = "1000" and c_flag = '1') or -- CS: carry set + (cc = "0101" and e_flag = '0') or -- EC: extension clear + (cc = "1010" and z_flag = '1') or -- EQ: equal + (cc = "1101" and e_flag = '1') or -- ES: extension set + (cc = "0001" and (n_flag = v_flag)) or -- GE: greater than or equal + (cc = "0001" and ((n_flag xor v_flag) or z_flag) = '0') or -- GT: greater than + (cc = "0110" and l_flag = '0') or -- LC: limit clear + (cc = "1111" and ((n_flag xor v_flag) or z_flag ) = '1') or -- LE: less or equal + (cc = "1110" and l_flag = '1') or -- LS: limit set + (cc = "1001" and (n_flag /= v_flag)) or -- LT: less than + (cc = "1011" and n_flag = '1') or -- MI: minus + (cc = "0010" and z_flag = '0') or -- NE: not equal + (cc = "1100" and (( not u_flag and not e_flag) or z_flag) = '1') or -- NR: normalized + (cc = "0011" and n_flag = '0') or -- PL: plus + (cc = "0100" and (( not u_flag and not e_flag ) or z_flag) = '0') -- NN: not normalized + then + cc_flag_set <= '1'; + end if; + end procedure; + + begin + + cc_flag_set <= '0'; + + -- Rip the flags we have to test for from the instruction word + if (instr_array = INSTR_JCC and instr_word(18) = '0') or + (instr_array = INSTR_JSCC) then + cc_select := instr_word(3 downto 0); + else + cc_select := instr_word(15 downto 12); + end if; + + calculate_cc_flag(cc_select); + + end process; + + +end architecture; diff --git a/vhdl/rtl/vhdl/DSP/src/exec_stage_cr_mod.vhd b/vhdl/rtl/vhdl/DSP/src/exec_stage_cr_mod.vhd new file mode 100644 index 0000000..c236db7 --- /dev/null +++ b/vhdl/rtl/vhdl/DSP/src/exec_stage_cr_mod.vhd @@ -0,0 +1,72 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +library work; +use work.parameter_pkg.all; +use work.types_pkg.all; +use work.constants_pkg.all; + +entity exec_stage_cr_mod is port ( + activate_exec_cr_mod : in std_logic; + instr_word : in std_logic_vector(23 downto 0); + instr_array : in instructions_type; + register_file : in register_file_type; + modify_sr : out std_logic; + modified_sr : out std_logic_vector(15 downto 0); + modify_omr : out std_logic; + modified_omr : out std_logic_vector(7 downto 0) +); +end exec_stage_cr_mod; + + +architecture rtl of exec_stage_cr_mod is + +begin + + process(activate_exec_cr_mod, instr_word, instr_array, register_file) is + variable imm8 : std_logic_vector(7 downto 0); + variable op8 : std_logic_vector(7 downto 0); + variable res8 : std_logic_vector(7 downto 0); + begin + modify_sr <= '0'; + modify_omr <= '0'; + modified_sr <= (others => '0'); + modified_omr <= (others => '0'); + + imm8 := instr_word(15 downto 8); + if instr_word(1 downto 0) = "00" then + -- read MR + op8 := register_file.mr; + elsif instr_word(1 downto 0) = "01" then + -- read CCR + op8 := register_file.ccr; + else -- instr_word(1 downto 0) = "10" + -- read OMR + op8 := register_file.omr; + end if; + + if instr_array = INSTR_ANDI then + res8 := imm8 and op8; + else -- instr_array = INSTR_ORI + res8 := imm8 or op8; + end if; + + -- only write the result when activated + if activate_exec_cr_mod = '1' then + if instr_word(1 downto 0) = "00" then + -- update MR + modify_sr <= '1'; + modified_sr <= res8 & register_file.ccr; + elsif instr_word(1 downto 0) = "01" then + -- update CCR + modify_sr <= '1'; + modified_sr <= register_file.mr & res8; + elsif instr_word(1 downto 0) = "10" then + -- update OMR + modify_omr <= '1'; + modified_omr <= res8; + end if; + end if; + end process; + +end architecture; diff --git a/vhdl/rtl/vhdl/DSP/src/exec_stage_loops.vhd b/vhdl/rtl/vhdl/DSP/src/exec_stage_loops.vhd new file mode 100644 index 0000000..cc32692 --- /dev/null +++ b/vhdl/rtl/vhdl/DSP/src/exec_stage_loops.vhd @@ -0,0 +1,200 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +library work; +use work.parameter_pkg.all; +use work.types_pkg.all; +use work.constants_pkg.all; + +entity exec_stage_loop is port( + clk, rst : in std_logic; + activate_exec_loop : in std_logic; + instr_word : in std_logic_vector(23 downto 0); + instr_array : in instructions_type; + loop_iterations : in unsigned(15 downto 0); + loop_address : in unsigned(BW_ADDRESS-1 downto 0); + loop_start_address: in unsigned(BW_ADDRESS-1 downto 0); + register_file : in register_file_type; + fetch_perform_enddo: in std_logic; + memory_stall : in std_logic; + push_stack : out push_stack_type; + pop_stack : out pop_stack_type; + stall_rep : out std_logic; + stall_do : out std_logic; + decrement_lc : out std_logic; + modify_lc : out std_logic; + modified_lc : out unsigned(15 downto 0); + modify_la : out std_logic; + modified_la : out unsigned(15 downto 0); + modify_pc : out std_logic; + modified_pc : out unsigned(BW_ADDRESS-1 downto 0); + modify_sr : out std_logic; + modified_sr : out std_logic_vector(15 downto 0) +); +end entity; + + +architecture rtl of exec_stage_loop is + + signal rep_loop_polling : std_logic; + signal do_loop_polling : std_logic; + signal enddo_polling : std_logic; + signal lc_temp : unsigned(15 downto 0); + signal rf_lc_eq_1 : std_logic; + signal memory_stall_t : std_logic; + +begin + + modified_pc <= loop_start_address; + + + -- loop counter in register file equal to 1? + rf_lc_eq_1 <= '1' when register_file.lc = 1 else '0'; + + process(activate_exec_loop, instr_array, register_file, fetch_perform_enddo, + rep_loop_polling, loop_iterations, rf_lc_eq_1, loop_start_address) is + begin + stall_rep <= '0'; + stall_do <= '0'; + + modify_la <= '0'; + modify_lc <= '0'; + modify_pc <= '0'; + modify_sr <= '0'; + modified_la <= loop_address; + modified_lc <= loop_iterations; -- default + -- set the loop flag LF (bit 15) of Status register + modified_sr(15) <= '1'; + modified_sr(14 downto 0) <= register_file.sr(14 downto 0); + + push_stack.valid <= '0'; -- push PC and SR on the stack + push_stack.pc <= loop_start_address; + push_stack.content <= LA_AND_LC; + + pop_stack.valid <= '0'; + decrement_lc <= '0'; + ------------------ + -- DO instruction + ------------------ + if activate_exec_loop = '1' and instr_array = INSTR_DO then + -- first instruction of the do loop instruction? + if do_loop_polling = '0' then + stall_do <= '1'; + modify_lc <= '1'; -- store the new loop counter + modify_la <= '1'; -- store the new loop address + push_stack.valid <= '1'; -- push LA and LC on the stack + push_stack.content <= LA_AND_LC; + else -- second clock cycle of the do loop instruction ? + push_stack.valid <= '1'; -- push PC and SR on the stack + push_stack.pc <= loop_start_address; + push_stack.content <= PC_AND_SR; + -- set the PC to the first instruction of the loop + -- the already fetched instruction are flushed from the pipeline + -- this prevents problems, when the loop consists of only one or two instructions + modify_pc <= '1'; + -- set the loop flag + modify_sr <= '1'; + end if; + end if; + ----------------------------------------------- + -- ENDDO instruction / loop end in fetch stage + ----------------------------------------------- + if (activate_exec_loop = '1' and instr_array = INSTR_ENDDO) or fetch_perform_enddo = '1' or enddo_polling = '1' then + pop_stack.valid <= '1'; + if enddo_polling = '0' then + -- only restore the LF from the stack + modified_sr(15) <= register_file.current_ssl(15); + modify_sr <= '1'; + stall_do <= '1'; -- stall one clock cycle + else + -- restore loop counter and loop address in second clock cycle + modified_lc <= unsigned(register_file.current_ssl); + modify_lc <= '1'; + modified_la <= unsigned(register_file.current_ssh); + modify_la <= '1'; + end if; + end if; + ------------------- + -- REP instruction + ------------------- + if activate_exec_loop = '1' and instr_array = INSTR_REP then + -- only do something when there are more than 1 iterations + -- the first execution is already on the way + if loop_iterations /= 1 then + stall_rep <= '1'; -- stall the fetch and decode stages + modify_lc <= '1'; -- store the loop counter + modified_lc <= loop_iterations - 1; + end if; + end if; + + -- keep processing the single instruction + if rep_loop_polling = '1' then + stall_rep <= '1'; + -- if the REP instruction cause a stall do not modify the lc! + if memory_stall_t = '0' then + if rf_lc_eq_1 = '0' then + decrement_lc <= '1'; + -- when the instruction to repeat caused a memory stall + -- do not continue! + else + -- finish the REP instruction by restoring the LC + stall_rep <= '0'; + modify_lc <= '1'; + modified_lc <= lc_temp; + end if; + end if; + end if; + end process; + + + -- process that allows to remember that we are processing a REP/DO instruction + -- even though the REP instruction is not available in the pipeline anymore + -- also store the old loop counter + process(clk) is + begin + if rising_edge(clk) then + if rst = '1' then + rep_loop_polling <= '0'; + do_loop_polling <= '0'; + enddo_polling <= '0'; + lc_temp <= (others => '0'); + memory_stall_t <= '0'; + else + memory_stall_t <= memory_stall; + + if activate_exec_loop = '1' and instr_array = INSTR_REP then + -- only do something when there are more than 1 iterations + -- the first execution is already on the way + if loop_iterations /= 1 then + rep_loop_polling <= '1'; + lc_temp <= register_file.lc; + end if; + end if; + -- test whether the REP instruction has been executed + if rep_loop_polling = '1' and rf_lc_eq_1 = '1' and memory_stall_t = '0' then + rep_loop_polling <= '0'; + end if; + + -- do loop execution takes two clock cycles + -- in the first clock cycle we store loop address and loop counter on the stack + -- in the second clock cycle we store programm counter and status register on the stack + if activate_exec_loop = '1' and instr_array = INSTR_DO then + do_loop_polling <= '1'; + end if; + -- clear the flag immediately again (only two cycles execution time!) + if do_loop_polling = '1' then + do_loop_polling <= '0'; + end if; + + -- ENDDO instructions take two clock cycles as well! + if (activate_exec_loop = '1' and instr_array = INSTR_ENDDO) or fetch_perform_enddo = '1' then + enddo_polling <= '1'; + end if; + if enddo_polling = '1' then + enddo_polling <= '0'; + end if; + end if; + end if; + end process; + +end architecture; diff --git a/vhdl/rtl/vhdl/DSP/src/fetch_stage.vhd b/vhdl/rtl/vhdl/DSP/src/fetch_stage.vhd new file mode 100644 index 0000000..6b22f09 --- /dev/null +++ b/vhdl/rtl/vhdl/DSP/src/fetch_stage.vhd @@ -0,0 +1,60 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +library work; +use work.parameter_pkg.all; +use work.types_pkg.all; + + +entity fetch_stage is port( + + pc_old : in unsigned(BW_ADDRESS-1 downto 0); + pc_new : out unsigned(BW_ADDRESS-1 downto 0); + modify_pc : in std_logic; + modified_pc : in unsigned(BW_ADDRESS-1 downto 0); + register_file : in register_file_type; + decrement_lc : out std_logic; + perform_enddo : out std_logic + +); +end fetch_stage; + + +architecture rtl of fetch_stage is + + +begin + + pc_calculation: process(pc_old, modify_pc, modified_pc, register_file) is + begin + decrement_lc <= '0'; + perform_enddo <= '0'; + + -- by default increment pc by one + pc_new <= pc_old + 1; + if modify_pc = '1' then + pc_new <= modified_pc; + end if; + -- Loop Flag set? + if register_file.sr(15) = '1' then + if register_file.la = pc_old then + -- Loop not finished? + -- => start from the beginning if necessary + if register_file.lc /= 1 then + -- if the last address was LA and the loop is not finished yet, we have to + -- read now from the beginning of the loop again + pc_new <= unsigned(register_file.current_ssh(BW_ADDRESS-1 downto 0)); + -- decrement loop counter + decrement_lc <= '1'; + else + -- loop done! + -- => tell the loop controller in the exec stage to perform the enddo operation + -- (without flushing of the pipeline!) + perform_enddo <= '1'; + end if; + end if; + end if; + end process pc_calculation; + +end architecture rtl; + diff --git a/vhdl/rtl/vhdl/DSP/src/mem_control.vhd b/vhdl/rtl/vhdl/DSP/src/mem_control.vhd new file mode 100644 index 0000000..091fcf0 --- /dev/null +++ b/vhdl/rtl/vhdl/DSP/src/mem_control.vhd @@ -0,0 +1,1519 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +library work; +use work.parameter_pkg.all; +use work.types_pkg.all; + +entity mem_control is + generic( + mem_type : memory_type := P_MEM + ); + port( + clk, rst : in std_logic; + rd_addr : in unsigned(BW_ADDRESS-1 downto 0); + rd_en : in std_logic; + data_out : out std_logic_vector(23 downto 0); + data_out_valid : out std_logic; + wr_addr : in unsigned(BW_ADDRESS-1 downto 0); + wr_en : in std_logic; + wr_accomplished : out std_logic; + data_in : in std_logic_vector(23 downto 0) + ); +end entity mem_control; + + +architecture rtl of mem_control is + + signal int_mem_rd_addr : std_logic_vector(7 downto 0); + type int_mem_type is array(0 to 255) of std_logic_vector(23 downto 0); + signal int_mem : int_mem_type; + signal int_pmem : int_mem_type := ( +-- ABS begin +--X"0000B9", +--X"56F400", +--X"200000", +--X"200026", +--X"56F400", +--X"E00000", +--X"200026", +--X"56F400", +--X"000000", +--X"200026", +--X"52F400", +--X"000080", +--X"200026", +-- ABS end + +-- ADC begin +--X"46F400", +--X"000000", +--X"47F400", +--X"000001", +--X"20001B", +--X"51F400", +--X"000001", +--X"0000B9", +--X"0001F9", +--X"200039", +--X"47F400", +--X"800000", +--X"53F400", +--X"000080", +--X"200039", +-- ADC end + +-- ADD begin +--X"46F400", +--X"000000", +--X"47F400", +--X"000001", +--X"20001B", +--X"51F400", +--X"000001", +--X"0000B9", +--X"0001F9", +--X"200038", +--X"47F400", +--X"800000", +--X"53F400", +--X"000080", +--X"200038", +-- ADD end + +-- ADDL begin +--X"56F400", +--X"000055", +--X"20001B", +--X"51F400", +--X"000055", +--X"0000B9", +--X"20001A", +--X"56F400", +--X"0000AA", +--X"20001A", +--X"53F400", +--X"000080", +--X"20001A", +-- ADDL end + +-- ADDR begin +--X"56F400", +--X"000055", +--X"20001B", +--X"51F400", +--X"000055", +--X"0000B9", +--X"20000A", +--X"56F400", +--X"0000AA", +--X"20000A", +--X"53F400", +--X"000080", +--X"20000A", +-- ADDR end + +-- AND begin +--X"46F400", +--X"000FFF", +--X"57F400", +--X"FFFFFF", +--X"0000B9", +--X"20005E", +--X"46F400", +--X"FFF000", +--X"57F400", +--X"FFFFFF", +--X"0000B9", +--X"20005E", +--X"46F400", +--X"000000", +--X"57F400", +--X"FFFFFF", +--X"0000B9", +--X"20005E", +-- AND end + +-- EOR begin +--X"46F400", +--X"000FFF", +--X"57F400", +--X"FF00FF", +--X"0000B9", +--X"20005B", +--X"46F400", +--X"FFFFFF", +--X"57F400", +--X"FFFFFF", +--X"0000B9", +--X"20005B", +-- EOR end + +-- OR begin +--X"46F400", +--X"000FFF", +--X"57F400", +--X"FF00FF", +--X"0000B9", +--X"20005A", +--X"46F400", +--X"000000", +--X"57F400", +--X"000000", +--X"0000B9", +--X"20005A", +-- OR end + +-- NOT begin +--X"46F400", +--X"000FFF", +--X"57F400", +--X"7F00FF", +--X"0000B9", +--X"20001F", +--X"46F400", +--X"000000", +--X"57F400", +--X"FFFFFF", +--X"0000B9", +--X"20001F", +-- NOT end + +-- ASL begin +--X"20001B", +--X"51F400", +--X"0000A5", +--X"55F400", +--X"0000A5", +--X"53F400", +--X"0000A5", +--X"0000B9", +--X"20003A", +-- ASL end + +-- ASR begin +--X"20001B", +--X"51F400", +--X"0000A5", +--X"55F400", +--X"0000A5", +--X"53F400", +--X"0000A5", +--X"0000B9", +--X"20002A", +-- ASR end + +-- CLR begin +--X"0000B9", +--X"56F400", +--X"200000", +--X"200013", +--X"56F400", +--X"E00000", +--X"0000B9", +--X"0001F9", +--X"200013", +-- CLR end + +-- CMP begin +--X"2F2000", +--X"262400", +--X"0000B9", +--X"20005D", +--X"2F2000", +--X"262000", +--X"0000B9", +--X"20005D", +--X"2F2400", +--X"262000", +--X"0000B9", +--X"20005D", +--X"57F400", +--X"800AAA", +--X"262000", +--X"0000B9", +--X"20005D", +--X"46F400", +--X"800AAA", +--X"2F2000", +--X"0000B9", +--X"20005D", +-- CMP end + +-- CMPM begin +--X"2F2000", +--X"262400", +--X"0000B9", +--X"20005F", +--X"2F2000", +--X"262000", +--X"0000B9", +--X"20005F", +--X"2F2400", +--X"262000", +--X"0000B9", +--X"20005F", +--X"57F400", +--X"800AAA", +--X"262000", +--X"0000B9", +--X"20005F", +--X"46F400", +--X"800AAA", +--X"2F2000", +--X"0000B9", +--X"20005F", +-- CMPM end + +-- DIV begin +--X"00FEB9", +--X"44F400", +--X"600000", +--X"56F400", +--X"200000", +--X"0618A0", +--X"018040", +--X"210E00", +-- DIV end + +-- LSL begin +--X"0000B9", +--X"56F400", +--X"200000", +--X"56F400", +--X"AAAAAA", +--X"50F400", +--X"BCDEFA", +--X"0618A0", +--X"200033", +-- LSL end + +-- LSR begin +--X"0000B9", +--X"56F400", +--X"200000", +--X"56F400", +--X"AAAAAA", +--X"50F400", +--X"BCDEFA", +--X"0618A0", +--X"200023", +-- LSR end + +-- MPY begin +--X"0000B9", +--X"44F400", +--X"200000", +--X"46F400", +--X"400000", +--X"2000D0", +--X"44F400", +--X"E00000", +--X"46F400", +--X"B9999A", +--X"2000D0", +--X"44F400", +--X"E66666", +--X"46F400", +--X"466666", +--X"2000D0", +--X"44F400", +--X"E66666", +--X"46F400", +--X"466666", +--X"2000D4", +-- MPY end + +-- MAC begin +--X"0000B9", +--X"200013", +--X"2A8000", +--X"44F400", +--X"200000", +--X"46F400", +--X"400000", +--X"2000D6", +--X"44F400", +--X"E00000", +--X"46F400", +--X"B9999A", +--X"2000D2", +--X"44F400", +--X"E66666", +--X"46F400", +--X"466666", +--X"2000D2", +--X"44F400", +--X"E66666", +--X"46F400", +--X"466666", +--X"2000D6", +-- MAC end + +-- MACR begin +--X"0000B9", +--X"200013", +--X"2E1000", +--X"44F400", +--X"123456", +--X"46F400", +--X"123456", +--X"2000D3", +--X"56F400", +--X"100001", +--X"44F400", +--X"123456", +--X"46F400", +--X"123456", +--X"2000D3", +--X"2E1000", +--X"50F400", +--X"800000", +--X"44F400", +--X"123456", +--X"46F400", +--X"123456", +--X"2000D3", +-- MACR end + +-- MPYR begin +--X"0000B9", +--X"46F400", +--X"654321", +--X"200095", +-- MPYR end + +-- NEG begin +--X"0000B9", +--X"56F400", +--X"654321", +--X"200036", +--X"200013", +--X"52F400", +--X"000080", +--X"200036", +--X"56F400", +--X"800000", +--X"200036", +-- NEG end + +-- NORM begin +X"200013", +X"2C0100", +X"200003", +X"062FA0", +X"01DB15", +X"200013", +X"2EFF00", +X"2A8400", +X"200003", +X"062FA0", +X"01D915", +X"200013", +X"062FA0", +X"01DA15", +-- NORM end + +-- RND begin +--X"0000B9", +--X"54F400", +--X"123456", +--X"50F400", +--X"789ABC", +--X"200011", +--X"54F400", +--X"123456", +--X"50F400", +--X"800000", +--X"200011", +--X"54F400", +--X"123455", +--X"50F400", +--X"800000", +--X"200011", +-- RND end + +-- ROR begin +--X"0000B9", +--X"56F400", +--X"AAAAAA", +--X"50F400", +--X"BCDEFA", +--X"0618A0", +--X"200027", +-- ROR end + +-- ROL begin +--X"0000B9", +--X"56F400", +--X"AAAAAA", +--X"50F400", +--X"BCDEFA", +--X"0618A0", +--X"200037", +-- ROL end + + +-- SUB begin +--X"46F400", +--X"000000", +--X"47F400", +--X"000001", +--X"20001B", +--X"51F400", +--X"000001", +--X"0000B9", +--X"0001F9", +--X"20003C", +--X"47F400", +--X"800000", +--X"53F400", +--X"000080", +--X"20003C", +--X"20001B", +--X"53F400", +--X"000080", +--X"47F400", +--X"000001", +--X"20007C", +-- SUB end + +-- SUBL begin +--X"50F400", +--X"000000", +--X"54F400", +--X"000001", +--X"20001B", +--X"51F400", +--X"000001", +--X"0000B9", +--X"0001F9", +--X"20001E", +--X"54F400", +--X"800000", +--X"53F400", +--X"000080", +--X"20001E", +--X"20001B", +--X"53F400", +--X"000080", +--X"54F400", +--X"000001", +--X"20001E", +-- SUBL end + +-- SUBR begin +--X"50F400", +--X"000000", +--X"54F400", +--X"000001", +--X"20001B", +--X"51F400", +--X"000001", +--X"0000B9", +--X"0001F9", +--X"20000E", +--X"54F400", +--X"800000", +--X"53F400", +--X"000080", +--X"20000E", +--X"20001B", +--X"53F400", +--X"000080", +--X"54F400", +--X"000001", +--X"20000E", +-- SUBR end + +-- SBC begin +--X"46F400", +--X"000000", +--X"47F400", +--X"000001", +--X"20001B", +--X"51F400", +--X"000001", +--X"0000B9", +--X"0001F9", +--X"20003D", +--X"47F400", +--X"800000", +--X"53F400", +--X"000080", +--X"20003D", +--X"20001B", +--X"53F400", +--X"000080", +--X"47F400", +--X"000001", +--X"20003D", +-- SBC end + +-- TCC begin +--X"311400", +--X"44F400", +--X"ABCDEF", +--X"57F400", +--X"123456", +--X"0000B9", +--X"038143", +--X"03014A", +--X"0004F9", +--X"03A143", +--X"03214A", +-- TCC end + +-- TFR begin +--X"56F400", +--X"ABCDEF", +--X"57F400", +--X"123456", +--X"21EE09", +--X"44F400", +--X"555555", +--X"47F400", +--X"AAAAAA", +--X"21C441", +--X"21E679", +-- TFR end + +-- TST begin +--X"20001B", +--X"20000B", +--X"0000B9", +--X"0001F9", +--X"53F400", +--X"000080", +--X"20000B", +--X"53F400", +--X"00007F", +--X"20000B", +-- TST end + + +--X"2AFF00", +--X"54F400", +--X"FFFFFF", +--X"50F400", +--X"FFFFF2", +--X"200026", +--X"000000", +--X"000000", +--X"000000", +--X"000000", +--X"000000", +--X"000000", +--X"000000", +--X"000000", +--X"000000", +--X"000000", +X"000000", +X"000000", +X"000000", +X"000000", +X"000000", +X"000000", +X"000000", +X"000000", +X"000000", +--X"44F400", +--X"100010", +--X"45F400", +--X"100011", +--X"0B5880", +--X"000017", +--X"46F400", +--X"100026", +--X"47F400", +--X"100027", +--X"425800", +--X"435800", +--X"420A00", +--X"431F00", +--X"437000", +--X"0000A0", +--X"427000", +--X"00004F", +-- X"42F800", +-- X"43F800", +-- X"428A00", +-- X"439F00", +-- "001100000100100000000000", -- 0 move #72,r0 +-- "001110000000100000000000", -- 1 move #8,n0 +-- "000001010000000010100000", -- 2 move #0,m0 +-- "000001010001000010100001", -- 3 move #16,m1 +-- "000001101110000100100000", -- 4 rep m1 +-- "010001001100100000000000", -- 5 move x:(r0)+n0,x0 +-- "000000000000000000000000", -- 6 +-- "000000000000000000000000", -- 7 +-- "000000000000000000000000", -- 8 +-- "000000000000000000000000", -- 9 +-- "000000000000000000000000", -- 10 +-- "000000000000000000000000", -- 11 +-- "000000000000000000000000", -- 12 +-- "000000000000000000000000", -- 13 +-- "000000000000000000000000", -- 14 +-- "000000000000000000000000", -- 15 +-- "000000000000000000000000", -- 16 +-- "000000000000000000000000", -- 17 +-- "000000000000000000000000", -- 18 +-- "000000000000000000000000", -- 19 +-- "000010101101101010000000", -- 20 -- JMP (r2)+ +-- "000000000000000000000000", -- 20 +-- "000000000000000000000000", -- 21 +-- "000000000000000000000000", -- 22 + "000000000000000000000000", -- 23 + "000000000000000000000000", -- 24 + "000000000000000000000000", -- 25 + "000000000000000000000000", -- 26 + "000000000000000000000000", -- 27 + "000000000000000000000000", -- 28 + "000000000000000000000000", -- 29 + "000000000000000000000000", -- 30 + "000000000000000000000000", -- 31 +-- "000000000000000000000000", -- 32 +-- "000011010000000000000000", -- 32 -- JSR #0 + "000010111111000010000000", -- 32 -- JSR absolute + "000000000000000001000000", -- 33 -- #64 + "000000000000000000000000", -- 34 + "000000000000000000000000", -- 35 + "000000000000000000000000", -- 36 + "000000000000000000000000", -- 37 + "000000000000000000000000", -- 38 + "000000000000000000000000", -- 39 + "000000000000000000000000", -- 40 + "000000000000000000000000", -- 41 + "000000000000000000000000", -- 42 + "000000000000000000000000", -- 43 + "000000000000000000000000", -- 44 + "000000000000000000000000", -- 45 + "000000000000000000000000", -- 46 + "000000000000000000000000", -- 47 + "000000000000000000000000", -- 48 + "000000000000000000000000", -- 49 + "000000000000000000000000", -- 50 + "000000000000000000000000", -- 51 + "000000000000000000000000", -- 52 + "000000000000000000000000", -- 53 + "000000000000000000000000", -- 54 + "000000000000000000000000", -- 55 + "000000000000000000000000", -- 56 + "000000000000000000000000", -- 57 + "000000000000000000000000", -- 58 + "000000000000000000000000", -- 59 + "000000000000000000000000", -- 60 + "000000000000000000000000", -- 61 + "000000000000000000000000", -- 62 + "000000000000000000000000", -- 63 + "000000000000000000000000", -- 64 + "000000000000000000000000", -- 65 + "000000000000000000000000", -- 66 + "000000000000000000000000", -- 67 + "000000000000000000000000", -- 68 + "000000000000000000000000", -- 69 + "000000000000000000000100", -- 70 -- RTI + "000000000000000000000000", -- 71 + "000000000000000000000000", -- 72 + "000000000000000000000000", -- 73 + "000000000000000000000000", -- 74 + "000000000000000000000000", -- 75 + "000000000000000000000000", -- 76 + "000000000000000000000000", -- 77 + "000000000000000000000000", -- 78 + "000000000000000000000000", -- 79 + "000000000000000000000000", -- 80 + "000000000000000000000000", -- 81 + "000000000000000000000000", -- 82 + "000000000000000000000000", -- 83 + "000000000000000000000000", -- 84 + "000000000000000000000000", -- 85 + "000000000000000000000000", -- 86 + "000000000000000000000000", -- 87 + "000000000000000000000000", -- 88 + "000000000000000000000000", -- 89 + "000000000000000000000000", -- 90 + "000000000000000000000000", -- 91 + "000000000000000000000000", -- 92 + "000000000000000000000000", -- 93 + "000000000000000000000000", -- 94 + "000000000000000000000000", -- 95 + "000000000000000000000000", -- 96 + "000000000000000000000000", -- 97 + "000000000000000000000000", -- 98 + "000000000000000000000000", -- 99 + "000000000000000000000000", -- 100 + "000000000000000000000000", -- 101 + "000000000000000000000000", -- 102 + "000000000000000000000000", -- 103 + "000000000000000000000000", -- 104 + "000000000000000000000000", -- 105 + "000000000000000000000000", -- 106 + "000000000000000000000000", -- 107 + "000000000000000000000000", -- 108 + "000000000000000000000000", -- 109 + "000000000000000000000000", -- 110 + "000000000000000000000000", -- 111 + "000000000000000000000000", -- 112 + "000000000000000000000000", -- 113 + "000000000000000000000000", -- 114 + "000000000000000000000000", -- 115 + "000000000000000000000000", -- 116 + "000000000000000000000000", -- 117 + "000000000000000000000000", -- 118 + "000000000000000000000000", -- 119 + "000000000000000000000000", -- 120 + "000000000000000000000000", -- 121 + "000000000000000000000000", -- 122 + "000000000000000000000000", -- 123 + "000000000000000000000000", -- 124 + "000000000000000000000000", -- 125 + "000000000000000000000000", -- 126 + "000000000000000000000000", -- 127 + "000000000000000000000000", -- 128 + "000000000000000000000000", -- 129 + "000000000000000000000000", -- 130 + "000000000000000000000000", -- 131 + "000000000000000000000000", -- 132 + "000000000000000000000000", -- 133 + "000000000000000000000000", -- 134 + "000000000000000000000000", -- 135 + "000000000000000000000000", -- 136 + "000000000000000000000000", -- 137 + "000000000000000000000000", -- 138 + "000000000000000000000000", -- 139 + "000000000000000000000000", -- 140 + "000000000000000000000000", -- 141 + "000000000000000000000000", -- 142 + "000000000000000000000000", -- 143 + "000000000000000000000000", -- 144 + "000000000000000000000000", -- 145 + "000000000000000000000000", -- 146 + "000000000000000000000000", -- 147 + "000000000000000000000000", -- 148 + "000000000000000000000000", -- 149 + "000000000000000000000000", -- 150 + "000000000000000000000000", -- 151 + "000000000000000000000000", -- 152 + "000000000000000000000000", -- 153 + "000000000000000000000000", -- 154 + "000000000000000000000000", -- 155 + "000000000000000000000000", -- 156 + "000000000000000000000000", -- 157 + "000000000000000000000000", -- 158 + "000000000000000000000000", -- 159 + "000000000000000000000000", -- 160 + "000000000000000000000000", -- 161 + "000000000000000000000000", -- 162 + "000000000000000000000000", -- 163 + "000000000000000000000000", -- 164 + "000000000000000000000000", -- 165 + "000000000000000000000000", -- 166 + "000000000000000000000000", -- 167 + "000000000000000000000000", -- 168 + "000000000000000000000000", -- 169 + "000000000000000000000000", -- 170 + "000000000000000000000000", -- 171 + "000000000000000000000000", -- 172 + "000000000000000000000000", -- 173 + "000000000000000000000000", -- 174 + "000000000000000000000000", -- 175 + "000000000000000000000000", -- 176 + "000000000000000000000000", -- 177 + "000000000000000000000000", -- 178 + "000000000000000000000000", -- 179 + "000000000000000000000000", -- 180 + "000000000000000000000000", -- 181 + "000000000000000000000000", -- 182 + "000000000000000000000000", -- 183 + "000000000000000000000000", -- 184 + "000000000000000000000000", -- 185 + "000000000000000000000000", -- 186 + "000000000000000000000000", -- 187 + "000000000000000000000000", -- 188 + "000000000000000000000000", -- 189 + "000000000000000000000000", -- 190 + "000000000000000000000000", -- 191 + "000000000000000000000000", -- 192 + "000000000000000000000000", -- 193 + "000000000000000000000000", -- 194 + "000000000000000000000000", -- 195 + "000000000000000000000000", -- 196 + "000000000000000000000000", -- 197 + "000000000000000000000000", -- 198 + "000000000000000000000000", -- 199 + "000000000000000000000000", -- 200 + "000000000000000000000000", -- 201 + "000000000000000000000000", -- 202 + "000000000000000000000000", -- 203 + "000000000000000000000000", -- 204 + "000000000000000000000000", -- 205 + "000000000000000000000000", -- 206 + "000000000000000000000000", -- 207 + "000000000000000000000000", -- 208 + "000000000000000000000000", -- 209 + "000000000000000000000000", -- 210 + "000000000000000000000000", -- 211 + "000000000000000000000000", -- 212 + "000000000000000000000000", -- 213 + "000000000000000000000000", -- 214 + "000000000000000000000000", -- 215 + "000000000000000000000000", -- 216 + "000000000000000000000000", -- 217 + "000000000000000000000000", -- 218 + "000000000000000000000000", -- 219 + "000000000000000000000000", -- 220 + "000000000000000000000000", -- 221 + "000000000000000000000000", -- 222 + "000000000000000000000000", -- 223 + "000000000000000000000000", -- 224 + "000000000000000000000000", -- 225 + "000000000000000000000000", -- 226 + "000000000000000000000000", -- 227 + "000000000000000000000000", -- 228 + "000000000000000000000000", -- 229 + "000000000000000000000000", -- 230 + "000000000000000000000000", -- 231 + "000000000000000000000000", -- 232 + "000000000000000000000000", -- 233 + "000000000000000000000000", -- 234 + "000000000000000000000000", -- 235 + "000000000000000000000000", -- 236 + "000000000000000000000000", -- 237 + "000000000000000000000000", -- 238 + "000000000000000000000000", -- 239 + "000000000000000000000000", -- 240 + "000000000000000000000000", -- 241 + "000000000000000000000000", -- 242 + "000000000000000000000000", -- 243 + "000000000000000000000000", -- 244 + "000000000000000000000000", -- 245 + "000000000000000000000000", -- 246 + "000000000000000000000000", -- 247 + "000000000000000000000000", -- 248 + "000000000000000000000000", -- 249 + "000000000000000000000000", -- 250 + "000000000000000000000000", -- 251 + "000000000000000000000000", -- 252 + "000000000000000000000000", -- 253 + "000000000000000000000000", -- 254 + "000000000000000000000000"); -- 255 + signal int_xmem : int_mem_type := ( +-- when "11------10000000" => instr_array(JMP_INSTR) <= '1'; +-- "000000000000111011111001", -- 0 -- ORI #$0E, CCR + "000000000000000000001100", -- 0 -- REP + "000000000000000000000101", -- 1 -- ORI #$0E, MR + "000000000000111011111010", -- 2 -- ORI #$0E, OMR + "000000000000100010111010", -- 3 -- ANDI #$08, OMR +-- "000010101111000010000000", -- 1 -- JMP absolute +-- "000000000000000000011111", -- 2 -- #31 +-- "000011000000000000010000", -- 3 -- JMP #16 + "000000000000000000000000", -- 4 + "000000000000000000000000", -- 5 + "000000000000000000000000", -- 6 + "000000000000000000000000", -- 7 + "000000000000000000000000", -- 8 + "000000000000000000000000", -- 9 + "000000000000000000000000", -- 10 + "000000000000000000000000", -- 11 + "000000000000000000000000", -- 12 + "000000000000000000000000", -- 13 + "000000000000000000000000", -- 14 + "000000000000000000000000", -- 15 + "000000000000000000000000", -- 16 +-- "000000000000000000000000", -- 17 + "000010101101010110100000", -- 17 -- JCC (r5)- + "000000000000000000000000", -- 18 + "000000000000000000000000", -- 19 + "000010101101101010000000", -- 20 -- JMP (r2)+ + "000000000000000000000000", -- 21 + "000000000000000000000000", -- 22 + "000000000000000000000000", -- 23 + "000000000000000000000000", -- 24 + "000000000000000000000000", -- 25 + "000000000000000000000000", -- 26 + "000000000000000000000000", -- 27 + "000000000000000000000000", -- 28 + "000000000000000000000000", -- 29 + "000000000000000000000000", -- 30 + "000000000000000000000000", -- 31 +-- "000000000000000000000000", -- 32 +-- "000011010000000000000000", -- 32 -- JSR #0 + "000010111111000010000000", -- 32 -- JSR absolute + "000000000000000001000000", -- 33 -- #64 + "000000000000000000000000", -- 34 + "000000000000000000000000", -- 35 + "000000000000000000000000", -- 36 + "000000000000000000000000", -- 37 + "000000000000000000000000", -- 38 + "000000000000000000000000", -- 39 + "000000000000000000000000", -- 40 + "000000000000000000000000", -- 41 + "000000000000000000000000", -- 42 + "000000000000000000000000", -- 43 + "000000000000000000000000", -- 44 + "000000000000000000000000", -- 45 + "000000000000000000000000", -- 46 + "000000000000000000000000", -- 47 + "000000000000000000000000", -- 48 + "000000000000000000000000", -- 49 + "000000000000000000000000", -- 50 + "000000000000000000000000", -- 51 + "000000000000000000000000", -- 52 + "000000000000000000000000", -- 53 + "000000000000000000000000", -- 54 + "000000000000000000000000", -- 55 + "000000000000000000000000", -- 56 + "000000000000000000000000", -- 57 + "000000000000000000000000", -- 58 + "000000000000000000000000", -- 59 + "000000000000000000000000", -- 60 + "000000000000000000000000", -- 61 + "000000000000000000000000", -- 62 + "000000000000000000000000", -- 63 + "000000000000000000000000", -- 64 + "000000000000000000000000", -- 65 + "000000000000000000000000", -- 66 + "000000000000000000000000", -- 67 + "000000000000000000000000", -- 68 + "000000000000000000000000", -- 69 + "000000000000000000000100", -- 70 -- RTI + "000000000000000000000000", -- 71 + "000000000000000000000000", -- 72 + "000000000000000000000000", -- 73 + "000000000000000000000000", -- 74 + "000000000000000000000000", -- 75 + "000000000000000000000000", -- 76 + "000000000000000000000000", -- 77 + "000000000000000000000000", -- 78 + "000000000000000000000000", -- 79 + "000000000000000000000000", -- 80 + "000000000000000000000000", -- 81 + "000000000000000000000000", -- 82 + "000000000000000000000000", -- 83 + "000000000000000000000000", -- 84 + "000000000000000000000000", -- 85 + "000000000000000000000000", -- 86 + "000000000000000000000000", -- 87 + "000000000000000000000000", -- 88 + "000000000000000000000000", -- 89 + "000000000000000000000000", -- 90 + "000000000000000000000000", -- 91 + "000000000000000000000000", -- 92 + "000000000000000000000000", -- 93 + "000000000000000000000000", -- 94 + "000000000000000000000000", -- 95 + "000000000000000000000000", -- 96 + "000000000000000000000000", -- 97 + "000000000000000000000000", -- 98 + "000000000000000000000000", -- 99 + "000000000000000000000000", -- 100 + "000000000000000000000000", -- 101 + "000000000000000000000000", -- 102 + "000000000000000000000000", -- 103 + "000000000000000000000000", -- 104 + "000000000000000000000000", -- 105 + "000000000000000000000000", -- 106 + "000000000000000000000000", -- 107 + "000000000000000000000000", -- 108 + "000000000000000000000000", -- 109 + "000000000000000000000000", -- 110 + "000000000000000000000000", -- 111 + "000000000000000000000000", -- 112 + "000000000000000000000000", -- 113 + "000000000000000000000000", -- 114 + "000000000000000000000000", -- 115 + "000000000000000000000000", -- 116 + "000000000000000000000000", -- 117 + "000000000000000000000000", -- 118 + "000000000000000000000000", -- 119 + "000000000000000000000000", -- 120 + "000000000000000000000000", -- 121 + "000000000000000000000000", -- 122 + "000000000000000000000000", -- 123 + "000000000000000000000000", -- 124 + "000000000000000000000000", -- 125 + "000000000000000000000000", -- 126 + "000000000000000000000000", -- 127 + "000000000000000000000000", -- 128 + "000000000000000000000000", -- 129 + "000000000000000000000000", -- 130 + "000000000000000000000000", -- 131 + "000000000000000000000000", -- 132 + "000000000000000000000000", -- 133 + "000000000000000000000000", -- 134 + "000000000000000000000000", -- 135 + "000000000000000000000000", -- 136 + "000000000000000000000000", -- 137 + "000000000000000000000000", -- 138 + "000000000000000000000000", -- 139 + "000000000000000000000000", -- 140 + "000000000000000000000000", -- 141 + "000000000000000000000000", -- 142 + "000000000000000000000000", -- 143 + "000000000000000000000000", -- 144 + "000000000000000000000000", -- 145 + "000000000000000000000000", -- 146 + "000000000000000000000000", -- 147 + "000000000000000000000000", -- 148 + "000000000000000000000000", -- 149 + "000000000000000000000000", -- 150 + "000000000000000000000000", -- 151 + "000000000000000000000000", -- 152 + "000000000000000000000000", -- 153 + "000000000000000000000000", -- 154 + "000000000000000000000000", -- 155 + "000000000000000000000000", -- 156 + "000000000000000000000000", -- 157 + "000000000000000000000000", -- 158 + "000000000000000000000000", -- 159 + "000000000000000000000000", -- 160 + "000000000000000000000000", -- 161 + "000000000000000000000000", -- 162 + "000000000000000000000000", -- 163 + "000000000000000000000000", -- 164 + "000000000000000000000000", -- 165 + "000000000000000000000000", -- 166 + "000000000000000000000000", -- 167 + "000000000000000000000000", -- 168 + "000000000000000000000000", -- 169 + "000000000000000000000000", -- 170 + "000000000000000000000000", -- 171 + "000000000000000000000000", -- 172 + "000000000000000000000000", -- 173 + "000000000000000000000000", -- 174 + "000000000000000000000000", -- 175 + "000000000000000000000000", -- 176 + "000000000000000000000000", -- 177 + "000000000000000000000000", -- 178 + "000000000000000000000000", -- 179 + "000000000000000000000000", -- 180 + "000000000000000000000000", -- 181 + "000000000000000000000000", -- 182 + "000000000000000000000000", -- 183 + "000000000000000000000000", -- 184 + "000000000000000000000000", -- 185 + "000000000000000000000000", -- 186 + "000000000000000000000000", -- 187 + "000000000000000000000000", -- 188 + "000000000000000000000000", -- 189 + "000000000000000000000000", -- 190 + "000000000000000000000000", -- 191 + "000000000000000000000000", -- 192 + "000000000000000000000000", -- 193 + "000000000000000000000000", -- 194 + "000000000000000000000000", -- 195 + "000000000000000000000000", -- 196 + "000000000000000000000000", -- 197 + "000000000000000000000000", -- 198 + "000000000000000000000000", -- 199 + "000000000000000000000000", -- 200 + "000000000000000000000000", -- 201 + "000000000000000000000000", -- 202 + "000000000000000000000000", -- 203 + "000000000000000000000000", -- 204 + "000000000000000000000000", -- 205 + "000000000000000000000000", -- 206 + "000000000000000000000000", -- 207 + "000000000000000000000000", -- 208 + "000000000000000000000000", -- 209 + "000000000000000000000000", -- 210 + "000000000000000000000000", -- 211 + "000000000000000000000000", -- 212 + "000000000000000000000000", -- 213 + "000000000000000000000000", -- 214 + "000000000000000000000000", -- 215 + "000000000000000000000000", -- 216 + "000000000000000000000000", -- 217 + "000000000000000000000000", -- 218 + "000000000000000000000000", -- 219 + "000000000000000000000000", -- 220 + "000000000000000000000000", -- 221 + "000000000000000000000000", -- 222 + "000000000000000000000000", -- 223 + "000000000000000000000000", -- 224 + "000000000000000000000000", -- 225 + "000000000000000000000000", -- 226 + "000000000000000000000000", -- 227 + "000000000000000000000000", -- 228 + "000000000000000000000000", -- 229 + "000000000000000000000000", -- 230 + "000000000000000000000000", -- 231 + "000000000000000000000000", -- 232 + "000000000000000000000000", -- 233 + "000000000000000000000000", -- 234 + "000000000000000000000000", -- 235 + "000000000000000000000000", -- 236 + "000000000000000000000000", -- 237 + "000000000000000000000000", -- 238 + "000000000000000000000000", -- 239 + "000000000000000000000000", -- 240 + "000000000000000000000000", -- 241 + "000000000000000000000000", -- 242 + "000000000000000000000000", -- 243 + "000000000000000000000000", -- 244 + "000000000000000000000000", -- 245 + "000000000000000000000000", -- 246 + "000000000000000000000000", -- 247 + "000000000000000000000000", -- 248 + "000000000000000000000000", -- 249 + "000000000000000000000000", -- 250 + "000000000000000000000000", -- 251 + "000000000000000000000000", -- 252 + "000000000000000000000000", -- 253 + "000000000000000000000000", -- 254 + "000000000000000000000000"); -- 255 + signal int_ymem : int_mem_type := ( +-- when "11------10000000" => instr_array(JMP_INSTR) <= '1'; +-- "000000000000111011111001", -- 0 -- ORI #$0E, CCR + "000000000000000000000001", -- 0 -- REP + "000000000000000000000010", -- 1 -- ORI #$0E, MR + "000000000000000000000011", -- 2 -- ORI #$0E, OMR + "000000000000000000000100", -- 3 -- ANDI #$08, OMR +-- "000010101111000010000000", -- 1 -- JMP absolute +-- "000000000000000000011111", -- 2 -- #31 +-- "000011000000000000010000", -- 3 -- JMP #16 + "000000000000000000000101", -- 4 + "000000000000000000000110", -- 5 + "000000000000000000000111", -- 6 + "000000000000000000001000", -- 7 + "000000000000000000001001", -- 8 + "000000000000000000001010", -- 9 + "000000000000000000001011", -- 10 + "000000000000000000001100", -- 11 + "000000000000000000001101", -- 12 + "000000000000000000001110", -- 13 + "000000000000000000001111", -- 14 + "000000000000000000010000", -- 15 + "000000000000000000010001", -- 16 +-- "000000000000000000000000", -- 17 + "000010101101010110100000", -- 17 -- JCC (r5)- + "000000000000000000000000", -- 18 + "000000000000000000000000", -- 19 + "000010101101101010000000", -- 20 -- JMP (r2)+ + "000000000000000000000000", -- 21 + "000000000000000000000000", -- 22 + "000000000000000000000000", -- 23 + "000000000000000000000000", -- 24 + "000000000000000000000000", -- 25 + "000000000000000000000000", -- 26 + "000000000000000000000000", -- 27 + "000000000000000000000000", -- 28 + "000000000000000000000000", -- 29 + "000000000000000000000000", -- 30 + "000000000000000000000000", -- 31 +-- "000000000000000000000000", -- 32 +-- "000011010000000000000000", -- 32 -- JSR #0 + "000010111111000010000000", -- 32 -- JSR absolute + "000000000000000001000000", -- 33 -- #64 + "000000000000000000000000", -- 34 + "000000000000000000000000", -- 35 + "000000000000000000000000", -- 36 + "000000000000000000000000", -- 37 + "000000000000000000000000", -- 38 + "000000000000000000000000", -- 39 + "000000000000000000000000", -- 40 + "000000000000000000000000", -- 41 + "000000000000000000000000", -- 42 + "000000000000000000000000", -- 43 + "000000000000000000000000", -- 44 + "000000000000000000000000", -- 45 + "000000000000000000000000", -- 46 + "000000000000000000000000", -- 47 + "000000000000000000000000", -- 48 + "000000000000000000000000", -- 49 + "000000000000000000000000", -- 50 + "000000000000000000000000", -- 51 + "000000000000000000000000", -- 52 + "000000000000000000000000", -- 53 + "000000000000000000000000", -- 54 + "000000000000000000000000", -- 55 + "000000000000000000000000", -- 56 + "000000000000000000000000", -- 57 + "000000000000000000000000", -- 58 + "000000000000000000000000", -- 59 + "000000000000000000000000", -- 60 + "000000000000000000000000", -- 61 + "000000000000000000000000", -- 62 + "000000000000000000000000", -- 63 + "000000000000000000000000", -- 64 + "000000000000000000000000", -- 65 + "000000000000000000000000", -- 66 + "000000000000000000000000", -- 67 + "000000000000000000000000", -- 68 + "000000000000000000000000", -- 69 + "000000000000000000000100", -- 70 -- RTI + "000000000000000000000000", -- 71 + "000000000000000000000000", -- 72 + "000000000000000000000000", -- 73 + "000000000000000000000000", -- 74 + "000000000000000000000000", -- 75 + "000000000000000000000000", -- 76 + "000000000000000000000000", -- 77 + "000000000000000000000000", -- 78 + "000000000000000000000000", -- 79 + "000000000000000000000000", -- 80 + "000000000000000000000000", -- 81 + "000000000000000000000000", -- 82 + "000000000000000000000000", -- 83 + "000000000000000000000000", -- 84 + "000000000000000000000000", -- 85 + "000000000000000000000000", -- 86 + "000000000000000000000000", -- 87 + "000000000000000000000000", -- 88 + "000000000000000000000000", -- 89 + "000000000000000000000000", -- 90 + "000000000000000000000000", -- 91 + "000000000000000000000000", -- 92 + "000000000000000000000000", -- 93 + "000000000000000000000000", -- 94 + "000000000000000000000000", -- 95 + "000000000000000000000000", -- 96 + "000000000000000000000000", -- 97 + "000000000000000000000000", -- 98 + "000000000000000000000000", -- 99 + "000000000000000000000000", -- 100 + "000000000000000000000000", -- 101 + "000000000000000000000000", -- 102 + "000000000000000000000000", -- 103 + "000000000000000000000000", -- 104 + "000000000000000000000000", -- 105 + "000000000000000000000000", -- 106 + "000000000000000000000000", -- 107 + "000000000000000000000000", -- 108 + "000000000000000000000000", -- 109 + "000000000000000000000000", -- 110 + "000000000000000000000000", -- 111 + "000000000000000000000000", -- 112 + "000000000000000000000000", -- 113 + "000000000000000000000000", -- 114 + "000000000000000000000000", -- 115 + "000000000000000000000000", -- 116 + "000000000000000000000000", -- 117 + "000000000000000000000000", -- 118 + "000000000000000000000000", -- 119 + "000000000000000000000000", -- 120 + "000000000000000000000000", -- 121 + "000000000000000000000000", -- 122 + "000000000000000000000000", -- 123 + "000000000000000000000000", -- 124 + "000000000000000000000000", -- 125 + "000000000000000000000000", -- 126 + "000000000000000000000000", -- 127 + "000000000000000000000000", -- 128 + "000000000000000000000000", -- 129 + "000000000000000000000000", -- 130 + "000000000000000000000000", -- 131 + "000000000000000000000000", -- 132 + "000000000000000000000000", -- 133 + "000000000000000000000000", -- 134 + "000000000000000000000000", -- 135 + "000000000000000000000000", -- 136 + "000000000000000000000000", -- 137 + "000000000000000000000000", -- 138 + "000000000000000000000000", -- 139 + "000000000000000000000000", -- 140 + "000000000000000000000000", -- 141 + "000000000000000000000000", -- 142 + "000000000000000000000000", -- 143 + "000000000000000000000000", -- 144 + "000000000000000000000000", -- 145 + "000000000000000000000000", -- 146 + "000000000000000000000000", -- 147 + "000000000000000000000000", -- 148 + "000000000000000000000000", -- 149 + "000000000000000000000000", -- 150 + "000000000000000000000000", -- 151 + "000000000000000000000000", -- 152 + "000000000000000000000000", -- 153 + "000000000000000000000000", -- 154 + "000000000000000000000000", -- 155 + "000000000000000000000000", -- 156 + "000000000000000000000000", -- 157 + "000000000000000000000000", -- 158 + "000000000000000000000000", -- 159 + "000000000000000000000000", -- 160 + "000000000000000000000000", -- 161 + "000000000000000000000000", -- 162 + "000000000000000000000000", -- 163 + "000000000000000000000000", -- 164 + "000000000000000000000000", -- 165 + "000000000000000000000000", -- 166 + "000000000000000000000000", -- 167 + "000000000000000000000000", -- 168 + "000000000000000000000000", -- 169 + "000000000000000000000000", -- 170 + "000000000000000000000000", -- 171 + "000000000000000000000000", -- 172 + "000000000000000000000000", -- 173 + "000000000000000000000000", -- 174 + "000000000000000000000000", -- 175 + "000000000000000000000000", -- 176 + "000000000000000000000000", -- 177 + "000000000000000000000000", -- 178 + "000000000000000000000000", -- 179 + "000000000000000000000000", -- 180 + "000000000000000000000000", -- 181 + "000000000000000000000000", -- 182 + "000000000000000000000000", -- 183 + "000000000000000000000000", -- 184 + "000000000000000000000000", -- 185 + "000000000000000000000000", -- 186 + "000000000000000000000000", -- 187 + "000000000000000000000000", -- 188 + "000000000000000000000000", -- 189 + "000000000000000000000000", -- 190 + "000000000000000000000000", -- 191 + "000000000000000000000000", -- 192 + "000000000000000000000000", -- 193 + "000000000000000000000000", -- 194 + "000000000000000000000000", -- 195 + "000000000000000000000000", -- 196 + "000000000000000000000000", -- 197 + "000000000000000000000000", -- 198 + "000000000000000000000000", -- 199 + "000000000000000000000000", -- 200 + "000000000000000000000000", -- 201 + "000000000000000000000000", -- 202 + "000000000000000000000000", -- 203 + "000000000000000000000000", -- 204 + "000000000000000000000000", -- 205 + "000000000000000000000000", -- 206 + "000000000000000000000000", -- 207 + "000000000000000000000000", -- 208 + "000000000000000000000000", -- 209 + "000000000000000000000000", -- 210 + "000000000000000000000000", -- 211 + "000000000000000000000000", -- 212 + "000000000000000000000000", -- 213 + "000000000000000000000000", -- 214 + "000000000000000000000000", -- 215 + "000000000000000000000000", -- 216 + "000000000000000000000000", -- 217 + "000000000000000000000000", -- 218 + "000000000000000000000000", -- 219 + "000000000000000000000000", -- 220 + "000000000000000000000000", -- 221 + "000000000000000000000000", -- 222 + "000000000000000000000000", -- 223 + "000000000000000000000000", -- 224 + "000000000000000000000000", -- 225 + "000000000000000000000000", -- 226 + "000000000000000000000000", -- 227 + "000000000000000000000000", -- 228 + "000000000000000000000000", -- 229 + "000000000000000000000000", -- 230 + "000000000000000000000000", -- 231 + "000000000000000000000000", -- 232 + "000000000000000000000000", -- 233 + "000000000000000000000000", -- 234 + "000000000000000000000000", -- 235 + "000000000000000000000000", -- 236 + "000000000000000000000000", -- 237 + "000000000000000000000000", -- 238 + "000000000000000000000000", -- 239 + "000000000000000000000000", -- 240 + "000000000000000000000000", -- 241 + "000000000000000000000000", -- 242 + "000000000000000000000000", -- 243 + "000000000000000000000000", -- 244 + "000000000000000000000000", -- 245 + "000000000000000000000000", -- 246 + "000000000000000000000000", -- 247 + "000000000000000000000000", -- 248 + "000000000000000000000000", -- 249 + "000000000000000000000000", -- 250 + "000000000000000000000000", -- 251 + "000000000000000000000000", -- 252 + "000000000000000000000000", -- 253 + "000000000000000000000000", -- 254 + "000000000000000000000000"); -- 255 + +begin + +-- int_mem <= int_pmem when mem_type = P_MEM else +-- int_xmem when mem_type = X_MEM else +-- int_ymem when mem_type = Y_MEM; + + wr_accomplished <= wr_en; + + PMEM_GEN: if mem_type = P_MEM generate + data_out <= int_pmem(to_integer(unsigned(int_mem_rd_addr))); + process(clk) is + begin + if rising_edge(clk) then +-- if rst = '1' then +-- data_out_valid <= '0'; +-- int_mem_rd_addr <= (others => '0'); +-- else + int_mem_rd_addr <= std_logic_vector(rd_addr(7 downto 0)); + data_out_valid <= rd_en; + if wr_en = '1' then + int_pmem(to_integer(wr_addr)) <= data_in; + end if; +-- end if; + end if; + end process; + end generate; + + XMEM_GEN: if mem_type = X_MEM generate + data_out <= int_xmem(to_integer(unsigned(int_mem_rd_addr))); + process(clk) is + begin + if rising_edge(clk) then +-- if rst = '1' then +-- data_out_valid <= '0'; +-- int_mem_rd_addr <= (others => '0'); +-- else + int_mem_rd_addr <= std_logic_vector(rd_addr(7 downto 0)); + data_out_valid <= rd_en; + if wr_en = '1' then + int_xmem(to_integer(wr_addr)) <= data_in; + end if; +-- end if; + end if; + end process; + end generate; + + YMEM_GEN: if mem_type = Y_MEM generate + data_out <= int_ymem(to_integer(unsigned(int_mem_rd_addr))); + process(clk) is + begin + if rising_edge(clk) then +-- if rst = '1' then +-- data_out_valid <= '0'; +-- int_mem_rd_addr <= (others => '0'); +-- else + int_mem_rd_addr <= std_logic_vector(rd_addr(7 downto 0)); + data_out_valid <= rd_en; + if wr_en = '1' then + int_ymem(to_integer(wr_addr)) <= data_in; + end if; +-- end if; + end if; + end process; + end generate; +-- process(clk, rst) is +-- begin +-- if rising_edge(clk) then +-- if rst = '1' then +-- data_out_valid <= '0'; +-- int_mem_rd_addr <= (others => '0'); +-- else +-- int_mem_rd_addr <= std_logic_vector(rd_addr(7 downto 0)); +-- data_out_valid <= rd_en; +-- if wr_en = '1' then +-- if mem_type = P_MEM then +-- int_pmem(to_integer(wr_addr)) <= data_in; +-- elsif mem_type = X_MEM then +-- int_xmem(to_integer(wr_addr)) <= data_in; +-- elsif mem_type = Y_MEM then +-- int_ymem(to_integer(wr_addr)) <= data_in; +-- end if; +-- end if; +-- end if; +-- end if; +-- end process; + +end architecture rtl; + diff --git a/vhdl/rtl/vhdl/DSP/src/memory_management.vhd b/vhdl/rtl/vhdl/DSP/src/memory_management.vhd new file mode 100644 index 0000000..6a25ac8 --- /dev/null +++ b/vhdl/rtl/vhdl/DSP/src/memory_management.vhd @@ -0,0 +1,206 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +library work; +use work.parameter_pkg.all; +use work.types_pkg.all; +use work.constants_pkg.all; + +entity memory_management is port ( + clk, rst : in std_logic; + stall_flags : in std_logic_vector(PIPELINE_DEPTH-1 downto 0); + memory_stall : out std_logic; + data_rom_enable: in std_logic; + pmem_ctrl_in : in mem_ctrl_type_in; + pmem_ctrl_out : out mem_ctrl_type_out; + xmem_ctrl_in : in mem_ctrl_type_in; + xmem_ctrl_out : out mem_ctrl_type_out; + ymem_ctrl_in : in mem_ctrl_type_in; + ymem_ctrl_out : out mem_ctrl_type_out +); +end memory_management; + + +architecture rtl of memory_management is + + + component mem_control is + generic( + mem_type : memory_type + ); + port( + clk, rst : in std_logic; + rd_addr : in unsigned(BW_ADDRESS-1 downto 0); + rd_en : in std_logic; + data_out : out std_logic_vector(23 downto 0); + data_out_valid : out std_logic; + wr_addr : in unsigned(BW_ADDRESS-1 downto 0); + wr_en : in std_logic; + wr_accomplished : out std_logic; + data_in : in std_logic_vector(23 downto 0) + ); + end component mem_control; + + signal pmem_data_out : std_logic_vector(23 downto 0); + signal pmem_data_out_valid : std_logic; + + signal pmem_rd_addr : unsigned(BW_ADDRESS-1 downto 0); + signal pmem_rd_en : std_logic; + + signal xmem_rd_en : std_logic; + signal xmem_data_out : std_logic_vector(23 downto 0); + signal xmem_data_out_valid : std_logic; + signal xmem_rd_polling : std_logic; + + signal ymem_rd_en : std_logic; + signal ymem_data_out : std_logic_vector(23 downto 0); + signal ymem_data_out_valid : std_logic; + signal ymem_rd_polling : std_logic; + + signal pmem_stall_buffer : std_logic_vector(23 downto 0); + signal pmem_stall_buffer_valid : std_logic; + signal xmem_stall_buffer : std_logic_vector(23 downto 0); + signal ymem_stall_buffer : std_logic_vector(23 downto 0); + + signal stall_flags_d : std_logic_vector(PIPELINE_DEPTH-1 downto 0); + +begin + + -- here it is necessary to store the output of the pmem/xmem/ymem when the pipeline enters a stall + -- when the pipeline wakes up, this temporal result is inserted into the pipeline + stall_buffer: process(clk) is + begin + if rising_edge(clk) then + if rst = '1' then + pmem_stall_buffer <= (others => '0'); + pmem_stall_buffer_valid <= '0'; + xmem_stall_buffer <= (others => '0'); + ymem_stall_buffer <= (others => '0'); + stall_flags_d <= (others => '0'); + else + stall_flags_d <= stall_flags; + if stall_flags(ST_FETCH2) = '1' and stall_flags_d(ST_FETCH2) = '0' then + if pmem_data_out_valid = '1' then + pmem_stall_buffer <= pmem_data_out; + pmem_stall_buffer_valid <= '1'; + end if; + end if; + if stall_flags(ST_FETCH2) = '0' and stall_flags_d(ST_FETCH2) = '1' then + pmem_stall_buffer_valid <= '0'; + end if; + + + end if; + end if; + end process stall_buffer; + + memory_stall <= '1' when ( xmem_rd_en = '1' or (xmem_rd_polling = '1' and xmem_data_out_valid = '0') ) or + ( ymem_rd_en = '1' or (ymem_rd_polling = '1' and ymem_data_out_valid = '0') ) else + '0'; + + ------------------------------- + -- PMEM CONTROLLER + ------------------------------- + inst_pmem_ctrl : mem_control + generic map( + mem_type => P_MEM + ) + port map( + clk => clk, + rst => rst, + rd_addr => pmem_ctrl_in.rd_addr, + rd_en => pmem_ctrl_in.rd_en, + data_out => pmem_data_out, + data_out_valid => pmem_data_out_valid, + wr_addr => pmem_ctrl_in.wr_addr, + wr_en => pmem_ctrl_in.wr_en, + data_in => pmem_ctrl_in.data_in + ); + + -- In case we wake up from a stall use the buffered value + pmem_ctrl_out.data_out <= pmem_stall_buffer when stall_flags(ST_FETCH2) = '0' and + stall_flags_d(ST_FETCH2) = '1' and + pmem_stall_buffer_valid = '1' else + pmem_data_out; + + pmem_ctrl_out.data_out_valid <= pmem_stall_buffer_valid when stall_flags(ST_FETCH2) = '0' and + stall_flags_d(ST_FETCH2) = '1' else + '0' when stall_flags(ST_FETCH2) = '1' else + pmem_data_out_valid; + + ------------------------------- + -- XMEM CONTROLLER + ------------------------------- + inst_xmem_ctrl : mem_control + generic map( + mem_type => X_MEM + ) + port map( + clk => clk, + rst => rst, + rd_addr => xmem_ctrl_in.rd_addr, + rd_en => xmem_rd_en, + data_out => xmem_data_out, + data_out_valid => xmem_data_out_valid, + wr_addr => xmem_ctrl_in.wr_addr, + wr_en => xmem_ctrl_in.wr_en, + data_in => xmem_ctrl_in.data_in + ); + + xmem_rd_en <= '1' when xmem_rd_polling = '0' and xmem_ctrl_in.rd_en = '1' else '0'; + + xmem_ctrl_out.data_out <= xmem_data_out; + xmem_ctrl_out.data_out_valid <= xmem_data_out_valid; + + ------------------------------- + -- YMEM CONTROLLER + ------------------------------- + inst_ymem_ctrl : mem_control + generic map( + mem_type => Y_MEM + ) + port map( + clk => clk, + rst => rst, + rd_addr => ymem_ctrl_in.rd_addr, + rd_en => ymem_rd_en, + data_out => ymem_data_out, + data_out_valid => ymem_data_out_valid, + wr_addr => ymem_ctrl_in.wr_addr, + wr_en => ymem_ctrl_in.wr_en, + data_in => ymem_ctrl_in.data_in + ); + + ymem_rd_en <= '1' when ymem_rd_polling = '0' and ymem_ctrl_in.rd_en = '1' else '0'; + + ymem_ctrl_out.data_out <= ymem_data_out; + ymem_ctrl_out.data_out_valid <= ymem_data_out_valid; + + mem_stall_control: process(clk) is + begin + if rising_edge(clk) then + if rst = '1' then + xmem_rd_polling <= '0'; + ymem_rd_polling <= '0'; + else + if xmem_rd_en = '1' then + xmem_rd_polling <= '1'; + end if; + + if xmem_data_out_valid = '1' then + xmem_rd_polling <= '0'; + end if; + + if ymem_rd_en = '1' then + ymem_rd_polling <= '1'; + end if; + + if ymem_data_out_valid = '1' then + ymem_rd_polling <= '0'; + end if; + + end if; + end if; + end process; +end architecture; + diff --git a/vhdl/rtl/vhdl/DSP/src/parameter_pkg.vhd b/vhdl/rtl/vhdl/DSP/src/parameter_pkg.vhd new file mode 100644 index 0000000..9e3c301 --- /dev/null +++ b/vhdl/rtl/vhdl/DSP/src/parameter_pkg.vhd @@ -0,0 +1,10 @@ + +package parameter_pkg is + + constant BW_ADDRESS : natural := 16; + + constant PIPELINE_DEPTH : natural := 5; + + constant NUM_ACT_SIGNALS : natural := 26; + +end package; diff --git a/vhdl/rtl/vhdl/DSP/src/pipeline.vhd b/vhdl/rtl/vhdl/DSP/src/pipeline.vhd new file mode 100644 index 0000000..5b5a98e --- /dev/null +++ b/vhdl/rtl/vhdl/DSP/src/pipeline.vhd @@ -0,0 +1,968 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +library work; +use work.parameter_pkg.all; +use work.types_pkg.all; +use work.constants_pkg.all; + +entity pipeline is port ( + clk, rst : in std_logic; + register_file_out : out register_file_type + +); +end pipeline; + +-- TODOs: +-- External memory accesses +-- ROM tables +-- Reading from SSH flag has to modify stack pointer +-- Memory access (x,y,p) and talling accordingly +-- Address Generator: ring buffers are not yet supported + +-- List of BUGS: +-- - Reading from address one clock cycle after writing to the same address might result in corrupted data!! +-- - SBC instruction has errorneous carry flag calculation + +-- List of probable issues: +-- - Reading from XMEM/YMEM with stalls probably results in corrupted data +-- - ENDDO instruction probably has to flush the pipeline afterwards +-- - Writing to memory occurs twice, when stalls occur + +-- Things to optimize: +-- - RTS/RTI could be executed in the ADGEN Stage already +-- - DO loops always flush the pipeline. This is necessary in case we have a very short loop. +-- The single instruction of the loop then has passed the fetch stage already without the branch + + +architecture rtl of pipeline is + + signal pipeline_regs : pipeline_type; + signal stall_flags : std_logic_vector(PIPELINE_DEPTH-1 downto 0); + + component fetch_stage is port( + pc_old : in unsigned(BW_ADDRESS-1 downto 0); + pc_new : out unsigned(BW_ADDRESS-1 downto 0); + modify_pc : in std_logic; + modified_pc : in unsigned(BW_ADDRESS-1 downto 0); + register_file : in register_file_type; + decrement_lc : out std_logic; + perform_enddo : out std_logic + ); + end component fetch_stage; + + signal pc_old, pc_new : unsigned(BW_ADDRESS-1 downto 0); + signal fetch_modify_pc : std_logic; + signal fetch_modified_pc : unsigned(BW_ADDRESS-1 downto 0); + signal fetch_perform_enddo: std_logic; + signal fetch_decrement_lc: std_logic; + + + component decode_stage is port( + activate_dec : in std_logic; + instr_word : in std_logic_vector(23 downto 0); + dble_word_instr : out std_logic; + instr_array : out instructions_type; + act_array : out std_logic_vector(NUM_ACT_SIGNALS-1 downto 0); + reg_wr_addr : out std_logic_vector(5 downto 0); + reg_rd_addr : out std_logic_vector(5 downto 0); + x_bus_rd_addr : out std_logic_vector(1 downto 0); + x_bus_wr_addr : out std_logic_vector(1 downto 0); + y_bus_rd_addr : out std_logic_vector(1 downto 0); + y_bus_wr_addr : out std_logic_vector(1 downto 0); + l_bus_addr : out std_logic_vector(2 downto 0); + adgen_mode_a : out adgen_mode_type; + adgen_mode_b : out adgen_mode_type; + alu_ctrl : out alu_ctrl_type + ); + end component decode_stage; + + signal dec_activate : std_logic; + signal dec_instr_word : std_logic_vector(23 downto 0); + signal dec_dble_word_instr : std_logic; + signal dec_instr_array : instructions_type; + signal dec_act_array : std_logic_vector(NUM_ACT_SIGNALS-1 downto 0); + signal dec_reg_wr_addr : std_logic_vector(5 downto 0); + signal dec_reg_rd_addr : std_logic_vector(5 downto 0); + signal dec_x_bus_wr_addr : std_logic_vector(1 downto 0); + signal dec_x_bus_rd_addr : std_logic_vector(1 downto 0); + signal dec_y_bus_wr_addr : std_logic_vector(1 downto 0); + signal dec_y_bus_rd_addr : std_logic_vector(1 downto 0); + signal dec_l_bus_addr : std_logic_vector(2 downto 0); + signal dec_adgen_mode_a : adgen_mode_type; + signal dec_adgen_mode_b : adgen_mode_type; + signal dec_alu_ctrl : alu_ctrl_type; + + component adgen_stage is port( + activate_adgen : in std_logic; + activate_x_mem : in std_logic; + activate_y_mem : in std_logic; + activate_l_mem : in std_logic; + instr_word : in std_logic_vector(23 downto 0); + instr_array : in instructions_type; + optional_ea_word : in std_logic_vector(23 downto 0); + register_file : in register_file_type; + adgen_mode_a : in adgen_mode_type; + adgen_mode_b : in adgen_mode_type; + address_out_x : out unsigned(BW_ADDRESS-1 downto 0); + address_out_y : out unsigned(BW_ADDRESS-1 downto 0); + wr_R_port_A_valid : out std_logic; + wr_R_port_A : out addr_wr_port_type; + wr_R_port_B_valid : out std_logic; + wr_R_port_B : out addr_wr_port_type + ); + end component adgen_stage; + + signal adgen_activate : std_logic; + signal adgen_activate_x_mem : std_logic; + signal adgen_activate_y_mem : std_logic; + signal adgen_activate_l_mem : std_logic; + signal adgen_instr_word : std_logic_vector(23 downto 0); + signal adgen_instr_array : instructions_type; + signal adgen_optional_ea_word : std_logic_vector(23 downto 0); + signal adgen_register_file : register_file_type; + signal adgen_mode_a : adgen_mode_type; + signal adgen_mode_b : adgen_mode_type; + signal adgen_address_out_x : unsigned(BW_ADDRESS-1 downto 0); + signal adgen_address_out_y : unsigned(BW_ADDRESS-1 downto 0); + signal adgen_wr_R_port_A_valid : std_logic; + signal adgen_wr_R_port_A : addr_wr_port_type; + signal adgen_wr_R_port_B_valid : std_logic; + signal adgen_wr_R_port_B : addr_wr_port_type; + + component exec_stage_bit_modify is port( + instr_word : in std_logic_vector(23 downto 0); + instr_array : in instructions_type; + src_operand : in std_logic_vector(23 downto 0); + register_file : in register_file_type; + dst_operand : out std_logic_vector(23 downto 0); + bit_cond_met : out std_logic; + modify_sr : out std_logic; + modified_sr : out std_logic_vector(15 downto 0) + ); + end component exec_stage_bit_modify; + + signal exec_bit_modify_instr_word : std_logic_vector(23 downto 0); + signal exec_bit_modify_instr_array : instructions_type; + signal exec_bit_modify_src_operand : std_logic_vector(23 downto 0); + signal exec_bit_modify_dst_operand : std_logic_vector(23 downto 0); + signal exec_bit_modify_bit_cond_met : std_logic; + signal exec_bit_modify_modify_sr : std_logic; + signal exec_bit_modify_modified_sr : std_logic_vector(15 downto 0); + + component exec_stage_branch is port( + activate_exec_bra : in std_logic; + instr_word : in std_logic_vector(23 downto 0); + instr_array : in instructions_type; + register_file : in register_file_type; + jump_address : in unsigned(BW_ADDRESS-1 downto 0); + bit_cond_met : in std_logic; + cc_flag_set : in std_logic; + push_stack : out push_stack_type; + pop_stack : out pop_stack_type; + modify_pc : out std_logic; + modified_pc : out unsigned(BW_ADDRESS-1 downto 0); + modify_sr : out std_logic; + modified_sr : out std_logic_vector(15 downto 0) + ); + end component exec_stage_branch; + + signal exec_bra_activate : std_logic; + signal exec_bra_instr_word : std_logic_vector(23 downto 0); + signal exec_bra_instr_array : instructions_type; + signal exec_bra_jump_address : unsigned(BW_ADDRESS-1 downto 0); + signal exec_bra_bit_cond_met : std_logic; + signal exec_bra_push_stack : push_stack_type; + signal exec_bra_pop_stack : pop_stack_type; + signal exec_bra_modify_pc : std_logic; + signal exec_bra_modified_pc : unsigned(BW_ADDRESS-1 downto 0); + signal exec_bra_modify_sr : std_logic; + signal exec_bra_modified_sr : std_logic_vector(15 downto 0); + + component exec_stage_cr_mod is port( + activate_exec_cr_mod : in std_logic; + instr_word : in std_logic_vector(23 downto 0); + instr_array : in instructions_type; + register_file : in register_file_type; + modify_sr : out std_logic; + modified_sr : out std_logic_vector(15 downto 0); + modify_omr : out std_logic; + modified_omr : out std_logic_vector(7 downto 0) + ); + end component exec_stage_cr_mod; + + signal exec_cr_mod_activate : std_logic; + signal exec_cr_mod_instr_word : std_logic_vector(23 downto 0); + signal exec_cr_mod_instr_array : instructions_type; + signal exec_cr_mod_modify_sr : std_logic; + signal exec_cr_mod_modified_sr : std_logic_vector(15 downto 0); + signal exec_cr_mod_modify_omr : std_logic; + signal exec_cr_mod_modified_omr : std_logic_vector(7 downto 0); + + component exec_stage_loop is port( + clk, rst : in std_logic; + activate_exec_loop : in std_logic; + instr_word : in std_logic_vector(23 downto 0); + instr_array : in instructions_type; + loop_iterations : in unsigned(15 downto 0); + loop_address : in unsigned(BW_ADDRESS-1 downto 0); + loop_start_address: in unsigned(BW_ADDRESS-1 downto 0); + register_file : in register_file_type; + fetch_perform_enddo: in std_logic; + memory_stall : in std_logic; + push_stack : out push_stack_type; + pop_stack : out pop_stack_type; + stall_rep : out std_logic; + stall_do : out std_logic; + decrement_lc : out std_logic; + modify_lc : out std_logic; + modified_lc : out unsigned(15 downto 0); + modify_la : out std_logic; + modified_la : out unsigned(15 downto 0); + modify_pc : out std_logic; + modified_pc : out unsigned(BW_ADDRESS-1 downto 0); + modify_sr : out std_logic; + modified_sr : out std_logic_vector(15 downto 0) + ); + end component exec_stage_loop; + + signal exec_loop_activate : std_logic; + signal exec_loop_instr_word : std_logic_vector(23 downto 0); + signal exec_loop_instr_array : instructions_type; + signal exec_loop_iterations : unsigned(15 downto 0); + signal exec_loop_address : unsigned(BW_ADDRESS-1 downto 0); + signal exec_loop_start_address : unsigned(BW_ADDRESS-1 downto 0); + signal exec_loop_register_file : register_file_type; + signal exec_loop_push_stack : push_stack_type; + signal exec_loop_pop_stack : pop_stack_type; + signal exec_loop_stall_rep : std_logic; + signal exec_loop_stall_do : std_logic; + signal exec_loop_decrement_lc : std_logic; + signal exec_loop_modify_lc : std_logic; + signal exec_loop_modified_lc : unsigned(15 downto 0); + signal exec_loop_modify_la : std_logic; + signal exec_loop_modified_la : unsigned(BW_ADDRESS-1 downto 0); + signal exec_loop_modify_pc : std_logic; + signal exec_loop_modified_pc : unsigned(BW_ADDRESS-1 downto 0); + signal exec_loop_modify_sr : std_logic; + signal exec_loop_modified_sr : std_logic_vector(BW_ADDRESS-1 downto 0); + + component exec_stage_alu is port( + alu_activate : in std_logic; + instr_word : in std_logic_vector(23 downto 0); + alu_ctrl : in alu_ctrl_type; + register_file : in register_file_type; + addr_r_in : in unsigned(BW_ADDRESS-1 downto 0); + addr_r_out : out unsigned(BW_ADDRESS-1 downto 0); + modify_accu : out std_logic; + dst_accu : out std_logic; + modified_accu : out signed(55 downto 0); + modify_sr : out std_logic; + modified_sr : out std_logic_vector(15 downto 0) + ); + end component exec_stage_alu; + + signal exec_alu_activate : std_logic; + signal exec_alu_instr_word : std_logic_vector(23 downto 0); + signal exec_alu_ctrl : alu_ctrl_type; + signal exec_alu_addr_r_in : unsigned(BW_ADDRESS-1 downto 0); + signal exec_alu_addr_r_out : unsigned(BW_ADDRESS-1 downto 0); + signal exec_alu_modify_accu : std_logic; + signal exec_alu_dst_accu : std_logic; + signal exec_alu_modified_accu : signed(55 downto 0); + signal exec_alu_modify_sr : std_logic; + signal exec_alu_modified_sr : std_logic_vector(15 downto 0); + + signal exec_imm_8bit : std_logic_vector(23 downto 0); + signal exec_imm_12bit : std_logic_vector(23 downto 0); + signal exec_src_operand : std_logic_vector(23 downto 0); + signal exec_dst_operand : std_logic_vector(23 downto 0); + + component exec_stage_cc_flag_calc is port( + instr_word : in std_logic_vector(23 downto 0); + instr_array : in instructions_type; + register_file : in register_file_type; + cc_flag_set : out std_logic + ); + end component exec_stage_cc_flag_calc; + + signal exec_cc_flag_calc_instr_word : std_logic_vector(23 downto 0); + signal exec_cc_flag_calc_instr_array : instructions_type; + signal exec_cc_flag_set : std_logic; + + component reg_file is port( + clk, rst : in std_logic; + register_file : out register_file_type; + wr_R_port_A_valid : in std_logic; + wr_R_port_A : in addr_wr_port_type; + wr_R_port_B_valid : in std_logic; + wr_R_port_B : in addr_wr_port_type; + alu_wr_valid : in std_logic; + alu_wr_addr : in std_logic; + alu_wr_data : in signed(55 downto 0); + reg_wr_addr : in std_logic_vector(5 downto 0); + reg_wr_addr_valid : in std_logic; + reg_wr_data : in std_Logic_vector(23 downto 0); + reg_rd_addr : in std_logic_vector(5 downto 0); + reg_rd_data : out std_Logic_vector(23 downto 0); + X_bus_rd_addr : in std_logic_vector(1 downto 0); + X_bus_data_out : out std_logic_vector(23 downto 0); + X_bus_wr_addr : in std_logic_vector(1 downto 0); + X_bus_wr_valid : in std_logic; + X_bus_data_in : in std_logic_vector(23 downto 0); + Y_bus_rd_addr : in std_logic_vector(1 downto 0); + Y_bus_data_out : out std_logic_vector(23 downto 0); + Y_bus_wr_addr : in std_logic_vector(1 downto 0); + Y_bus_wr_valid : in std_logic; + Y_bus_data_in : in std_logic_vector(23 downto 0); + L_bus_rd_addr : in std_logic_vector(2 downto 0); + L_bus_rd_valid : in std_logic; + L_bus_wr_addr : in std_logic_vector(2 downto 0); + L_bus_wr_valid : in std_logic; + push_stack : in push_stack_type; + pop_stack : in pop_stack_type; + set_sr : in std_logic; + new_sr : in std_logic_vector(15 downto 0); + set_omr : in std_logic; + new_omr : in std_logic_vector(7 downto 0); + set_lc : in std_logic; + new_lc : in unsigned(15 downto 0); + dec_lc : in std_logic; + set_la : in std_logic; + new_la : in unsigned(BW_ADDRESS-1 downto 0) + ); + end component reg_file; + + signal register_file : register_file_type; + signal rf_wr_R_port_A_valid : std_logic; + signal rf_wr_R_port_B_valid : std_logic; + signal rf_reg_wr_addr : std_logic_vector(5 downto 0); + signal rf_reg_wr_addr_valid : std_logic; + signal rf_reg_wr_data : std_logic_vector(23 downto 0); + signal rf_reg_rd_addr : std_logic_vector(5 downto 0); + signal rf_reg_rd_data : std_logic_vector(23 downto 0); + signal rf_X_bus_rd_addr : std_logic_vector(1 downto 0); + signal rf_X_bus_data_out : std_logic_vector(23 downto 0); + signal rf_X_bus_wr_addr : std_logic_vector(1 downto 0); + signal rf_X_bus_wr_valid : std_logic; + signal rf_X_bus_data_in : std_logic_vector(23 downto 0); + signal rf_Y_bus_rd_addr : std_logic_vector(1 downto 0); + signal rf_Y_bus_data_out : std_logic_vector(23 downto 0); + signal rf_Y_bus_wr_addr : std_logic_vector(1 downto 0); + signal rf_Y_bus_wr_valid : std_logic; + signal rf_Y_bus_data_in : std_logic_vector(23 downto 0); + signal rf_L_bus_rd_addr : std_logic_vector(2 downto 0); + signal rf_L_bus_rd_valid : std_logic; + signal rf_L_bus_wr_addr : std_logic_vector(2 downto 0); + signal rf_L_bus_wr_valid : std_logic; + signal push_stack : push_stack_type; + signal pop_stack : pop_stack_type; + signal rf_set_sr : std_logic; + signal rf_new_sr : std_logic_vector(15 downto 0); + signal rf_set_omr : std_logic; + signal rf_new_omr : std_logic_vector(7 downto 0); + signal rf_dec_lc : std_logic; + signal rf_set_lc : std_logic; + signal rf_new_lc : unsigned(15 downto 0); + signal rf_set_la : std_logic; + signal rf_new_la : unsigned(BW_ADDRESS-1 downto 0); + signal rf_alu_wr_valid : std_logic; + + component memory_management is port ( + clk, rst : in std_logic; + stall_flags : in std_logic_vector(PIPELINE_DEPTH-1 downto 0); + memory_stall : out std_logic; + data_rom_enable: in std_logic; + pmem_ctrl_in : in mem_ctrl_type_in; + pmem_ctrl_out : out mem_ctrl_type_out; + xmem_ctrl_in : in mem_ctrl_type_in; + xmem_ctrl_out : out mem_ctrl_type_out; + ymem_ctrl_in : in mem_ctrl_type_in; + ymem_ctrl_out : out mem_ctrl_type_out + ); + end component memory_management; + + signal memory_stall : std_logic; + signal pmem_ctrl_in : mem_ctrl_type_in; + signal pmem_ctrl_out : mem_ctrl_type_out; + signal xmem_ctrl_in : mem_ctrl_type_in; + signal xmem_ctrl_out : mem_ctrl_type_out; + signal ymem_ctrl_in : mem_ctrl_type_in; + signal ymem_ctrl_out : mem_ctrl_type_out; + + signal pmem_data_out : std_logic_vector(23 downto 0); + signal pmem_data_out_valid : std_logic; + signal xmem_data_out : std_logic_vector(23 downto 0); + signal xmem_data_out_valid : std_logic; + signal ymem_data_out : std_logic_vector(23 downto 0); + signal ymem_data_out_valid : std_logic; + +begin + register_file_out <= register_file; + + -- merge all stall sources + stall_flags(ST_FETCH) <= '1' when exec_loop_stall_rep = '1' or + memory_stall = '1' or + exec_loop_stall_do = '1' else '0'; + stall_flags(ST_FETCH2) <= '1' when exec_loop_stall_rep = '1' or + memory_stall = '1' or + exec_loop_stall_do = '1' else '0'; + stall_flags(ST_DECODE) <= '1' when exec_loop_stall_rep = '1' or + memory_stall = '1' or + exec_loop_stall_do = '1' else '0'; + stall_flags(ST_ADGEN) <= exec_loop_stall_do; +-- stall_flags(ST_ADGEN) <= '1' when memory_stall = '1' or +-- exec_loop_stall_do = '1' else '0'; +-- stall_flags(ST_EXEC) <= '0'; + stall_flags(ST_EXEC) <= exec_loop_stall_do; +-- stall_flags(ST_EXEC) <= '1' when memory_stall = '1' or +-- exec_loop_stall_do = '1' else '0'; + + shift_pipeline: process(clk, rst) is + procedure flush_pipeline_stage(stage: natural) is + begin + pipeline_regs(stage).pc <= (others => '1'); + pipeline_regs(stage).instr_word <= (others => '0'); + pipeline_regs(stage).act_array <= (others => '0'); + pipeline_regs(stage).instr_array <= INSTR_NOP; + pipeline_regs(stage).dble_word_instr <= '0'; + pipeline_regs(stage).dec_activate <= '0'; + pipeline_regs(stage).adgen_mode_a <= NOP; + pipeline_regs(stage).adgen_mode_b <= NOP; + pipeline_regs(stage).reg_wr_addr <= (others => '0'); + pipeline_regs(stage).reg_rd_addr <= (others => '0'); + pipeline_regs(stage).x_bus_rd_addr <= (others => '0'); + pipeline_regs(stage).x_bus_wr_addr <= (others => '0'); + pipeline_regs(stage).y_bus_rd_addr <= (others => '0'); + pipeline_regs(stage).y_bus_wr_addr <= (others => '0'); + pipeline_regs(stage).l_bus_addr <= (others => '0'); + pipeline_regs(stage).adgen_address_x <= (others => '0'); + pipeline_regs(stage).adgen_address_y <= (others => '0'); + pipeline_regs(stage).RAM_out_x <= (others => '0'); + pipeline_regs(stage).RAM_out_y <= (others => '0'); + pipeline_regs(stage).alu_ctrl.store_result <= '0'; + end procedure flush_pipeline_stage; + begin + if rising_edge(clk) then + if rst = '1' then + for i in 0 to PIPELINE_DEPTH-1 loop + flush_pipeline_stage(i); + end loop; + else + -- shift the pipeline registers when no stall applies + for i in 1 to PIPELINE_DEPTH-1 loop + if stall_flags(i) = '0' then + -- do not copy the pipeline registers from a stalled pipeline stage + -- for REP we do not flush +-- if stall_flags(i-1) = '1' then + if (stall_flags(i-1) = '1' and exec_loop_stall_rep = '0') or + (i = ST_ADGEN and memory_stall = '1' and exec_loop_stall_rep = '1') then + flush_pipeline_stage(i); + else + pipeline_regs(i) <= pipeline_regs(i-1); + end if; + end if; + end loop; + -- FETCH Pipeline Registers + if stall_flags(ST_FETCH) = '0' then + pipeline_regs(ST_FETCH).pc <= pc_new; + pipeline_regs(ST_FETCH).dec_activate <= '1'; + end if; + + -- FETCH2 Pipeline Registers + if stall_flags(ST_FETCH2) = '0' then + -- Normal pipeline operation? + -- Buffering of RAM output when stalling is performed in the memory management + if pmem_data_out_valid = '1' then + pipeline_regs(ST_FETCH2).instr_word <= pmem_data_out; + end if; + end if; + + -- DECODE Pipeline registers + if stall_flags(ST_DECODE) = '0' then + pipeline_regs(ST_DECODE).act_array <= dec_act_array; + pipeline_regs(ST_DECODE).instr_array <= dec_instr_array; + pipeline_regs(ST_DECODE).dble_word_instr <= dec_dble_word_instr; + pipeline_regs(ST_DECODE).reg_wr_addr <= dec_reg_wr_addr; + pipeline_regs(ST_DECODE).reg_rd_addr <= dec_reg_rd_addr; + pipeline_regs(ST_DECODE).x_bus_wr_addr <= dec_x_bus_wr_addr; + pipeline_regs(ST_DECODE).x_bus_rd_addr <= dec_x_bus_rd_addr; + pipeline_regs(ST_DECODE).y_bus_wr_addr <= dec_y_bus_wr_addr; + pipeline_regs(ST_DECODE).y_bus_rd_addr <= dec_y_bus_rd_addr; + pipeline_regs(ST_DECODE).l_bus_addr <= dec_l_bus_addr; + pipeline_regs(ST_DECODE).adgen_mode_a <= dec_adgen_mode_a; + pipeline_regs(ST_DECODE).adgen_mode_b <= dec_adgen_mode_b; + pipeline_regs(ST_DECODE).alu_ctrl <= dec_alu_ctrl; + end if; + + -- ADGEN Pipeline registers + if stall_flags(ST_ADGEN) = '0' then + pipeline_regs(ST_ADGEN).adgen_address_x <= adgen_address_out_x; + pipeline_regs(ST_ADGEN).adgen_address_y <= adgen_address_out_y; + end if; + if xmem_data_out_valid = '1' then + pipeline_regs(ST_ADGEN).RAM_out_x <= xmem_data_out; + end if; + if ymem_data_out_valid = '1' then + pipeline_regs(ST_ADGEN).RAM_out_y <= ymem_data_out; + end if; + + -- EXEC Pipeline stuff + if exec_bra_modify_pc = '1' or exec_loop_modify_pc = '1' then + -- clear the following pipeline stages, + -- since we modified the pc. + -- Do not flush ST_FETCH - it will hold the correct pc. + flush_pipeline_stage(ST_FETCH2); + flush_pipeline_stage(ST_DECODE); + flush_pipeline_stage(ST_ADGEN); + end if; + end if; + end if; + end process shift_pipeline; + + ------------------------------- + -- FETCH STAGE INSTANTIATION + ------------------------------- + inst_fetch_stage: fetch_stage port map( + pc_old => pc_old, + pc_new => pc_new, + modify_pc => fetch_modify_pc, + modified_pc => fetch_modified_pc, + register_file => register_file, + decrement_lc => fetch_decrement_lc, + perform_enddo => fetch_perform_enddo + ); + + pc_old <= pipeline_regs(ST_FETCH).pc; + + fetch_modify_pc <= '1' when exec_bra_modify_pc = '1' or exec_loop_modify_pc = '1' else '0'; + fetch_modified_pc <= exec_bra_modified_pc when exec_bra_modify_pc = '1' else + exec_loop_modified_pc; + + ------------------------------- + -- DECODE STAGE INSTANTIATION + ------------------------------- + inst_decode_stage : decode_stage port map( + activate_dec => dec_activate, + instr_word => dec_instr_word, + dble_word_instr => dec_dble_word_instr, + instr_array => dec_instr_array, + act_array => dec_act_array, + reg_wr_addr => dec_reg_wr_addr, + reg_rd_addr => dec_reg_rd_addr, + x_bus_wr_addr => dec_x_bus_wr_addr, + x_bus_rd_addr => dec_x_bus_rd_addr, + y_bus_wr_addr => dec_y_bus_wr_addr, + y_bus_rd_addr => dec_y_bus_rd_addr, + l_bus_addr => dec_l_bus_addr, + adgen_mode_a => dec_adgen_mode_a, + adgen_mode_b => dec_adgen_mode_b, + alu_ctrl => dec_alu_ctrl + ); + + dec_instr_word <= pipeline_regs(ST_DECODE-1).instr_word; + -- do not decode, when we have no valid instruction. This can happen when + -- 1) the pipeline just started its operation + -- 2) the pipeline was flushed due to a jump + -- 3) we are processing a instruction that consists of two words + dec_activate <= '1' when pipeline_regs(ST_DECODE-1).dec_activate = '1' and pipeline_regs(ST_DECODE).dble_word_instr = '0' else '0'; + + ------------------------------- + -- AGU STAGE INSTANTIATION + ------------------------------- + inst_adgen_stage: adgen_stage port map( + activate_adgen => adgen_activate, + activate_x_mem => adgen_activate_x_mem, + activate_y_mem => adgen_activate_y_mem, + activate_l_mem => adgen_activate_l_mem, + instr_word => adgen_instr_word, + instr_array => adgen_instr_array, + optional_ea_word => adgen_optional_ea_word, + register_file => register_file, + adgen_mode_a => adgen_mode_a, + adgen_mode_b => adgen_mode_b, + address_out_x => adgen_address_out_x, + address_out_y => adgen_address_out_y, + wr_R_port_A_valid => adgen_wr_R_port_A_valid, + wr_R_port_A => adgen_wr_R_port_A, + wr_R_port_B_valid => adgen_wr_R_port_B_valid, + wr_R_port_B => adgen_wr_R_port_B + ); + + adgen_activate <= pipeline_regs(ST_ADGEN-1).act_array(ACT_ADGEN); + adgen_activate_x_mem <= '1' when pipeline_regs(ST_ADGEN-1).act_array(ACT_X_MEM_RD) = '1' or + pipeline_regs(ST_ADGEN-1).act_array(ACT_X_MEM_WR) = '1' else '0'; + adgen_activate_y_mem <= '1' when pipeline_regs(ST_ADGEN-1).act_array(ACT_Y_MEM_RD) = '1' or + pipeline_regs(ST_ADGEN-1).act_array(ACT_Y_MEM_WR) = '1' else '0'; + adgen_activate_l_mem <= '1' when pipeline_regs(ST_ADGEN-1).act_array(ACT_L_BUS_RD) = '1' or + pipeline_regs(ST_ADGEN-1).act_array(ACT_L_BUS_WR) = '1' else '0'; + adgen_instr_word <= pipeline_regs(ST_ADGEN-1).instr_word; + adgen_instr_array <= pipeline_regs(ST_ADGEN-1).instr_array; + adgen_optional_ea_word <= pipeline_regs(ST_ADGEN-2).instr_word; + adgen_mode_a <= pipeline_regs(ST_ADGEN-1).adgen_mode_a; + adgen_mode_b <= pipeline_regs(ST_ADGEN-1).adgen_mode_b; + + ------------------------------- + -- EXECUTE STAGE INSTANTIATIONS + ------------------------------- + inst_exec_stage_alu: exec_stage_alu port map( + alu_activate => exec_alu_activate, + instr_word => exec_alu_instr_word, + alu_ctrl => exec_alu_ctrl, + register_file => register_file, + addr_r_in => exec_alu_addr_r_in, + addr_r_out => exec_alu_addr_r_out, + modify_accu => exec_alu_modify_accu, + dst_accu => exec_alu_dst_accu, + modified_accu => exec_alu_modified_accu, + modify_sr => exec_alu_modify_sr, + modified_sr => exec_alu_modified_sr + ); + + exec_alu_activate <= pipeline_regs(ST_EXEC-1).act_array(ACT_ALU); + exec_alu_instr_word <= pipeline_regs(ST_EXEC-1).instr_word; + exec_alu_ctrl <= pipeline_regs(ST_EXEC-1).alu_ctrl; + + exec_alu_addr_r_in <= unsigned(rf_reg_rd_data(BW_ADDRESS-1 downto 0)); + + inst_exec_stage_bit_modify: exec_stage_bit_modify port map( + instr_word => exec_bit_modify_instr_word, + instr_array => exec_bit_modify_instr_array, + src_operand => exec_bit_modify_src_operand, + register_file => register_file, + dst_operand => exec_bit_modify_dst_operand, + bit_cond_met => exec_bit_modify_bit_cond_met, + modify_sr => exec_bit_modify_modify_sr, + modified_sr => exec_bit_modify_modified_sr + ); + + exec_bit_modify_instr_word <= pipeline_regs(ST_EXEC-1).instr_word; + exec_bit_modify_instr_array <= pipeline_regs(ST_EXEC-1).instr_array; + exec_bit_modify_src_operand <= exec_src_operand; + + -- Writing to the register file using the 6 bit addressing scheme + -- sources are: + -- 1) X-RAM output + -- 2) Y-RAM output + -- 3) register file itself + -- 4) short immediate value (8 bit stored in instruction word) + -- 5) long immediate value (from optional effective address extension) + -- 5) address generated by the address generation unit (LUA instr) + exec_src_operand <= pipeline_regs(ST_EXEC-1).RAM_out_x when pipeline_regs(ST_EXEC-1).act_array(ACT_X_MEM_RD) = '1' else + pipeline_regs(ST_EXEC-1).RAM_out_y when pipeline_regs(ST_EXEC-1).act_array(ACT_Y_MEM_RD) = '1' else + rf_reg_rd_data when pipeline_regs(ST_EXEC-1).act_array(ACT_REG_RD) = '1' else + exec_imm_8bit when pipeline_regs(ST_EXEC-1).act_array(ACT_IMM_8BIT) = '1' else + exec_imm_12bit when pipeline_regs(ST_EXEC-1).act_array(ACT_IMM_12BIT) = '1' else + pipeline_regs(ST_EXEC-2).instr_word when pipeline_regs(ST_EXEC-1).act_array(ACT_IMM_LONG) = '1' else + std_logic_vector(resize(pipeline_regs(ST_EXEC-1).adgen_address_x, 24)); -- for LUA instr. + + -- Destination for the register file using the 6 bit addressing scheme. + -- Either read the bit modified version of the read value + -- or use the modified Rn in case of a NORM instruction +-- exec_dst_operand <= exec_bit_modify_dst_operand; + exec_dst_operand <= exec_bit_modify_dst_operand when pipeline_regs(ST_EXEC-1).act_array(ACT_NORM) = '0' else + std_logic_vector(resize(exec_alu_addr_r_out,24)); + + -- Unit to check whether cc (in Jcc, JScc, Tcc, ...) is true + inst_exec_stage_cc_flag_calc: exec_stage_cc_flag_calc port map( + instr_word => exec_cc_flag_calc_instr_word, + instr_array => exec_cc_flag_calc_instr_array, + register_file => register_file, + cc_flag_set => exec_cc_flag_set + ); + + exec_cc_flag_calc_instr_word <= pipeline_regs(ST_EXEC-1).instr_word; + exec_cc_flag_calc_instr_array <= pipeline_regs(ST_EXEC-1).instr_array; + + + inst_exec_stage_branch : exec_stage_branch port map( + activate_exec_bra => exec_bra_activate, + instr_word => exec_bra_instr_word, + instr_array => exec_bra_instr_array, + register_file => register_file, + jump_address => exec_bra_jump_address, + bit_cond_met => exec_bra_bit_cond_met, + cc_flag_set => exec_cc_flag_set, + push_stack => exec_bra_push_stack, + pop_stack => exec_bra_pop_stack, + modify_pc => exec_bra_modify_pc, + modified_pc => exec_bra_modified_pc, + modify_sr => exec_bra_modify_sr, + modified_sr => exec_bra_modified_sr + ); + + exec_bra_activate <= pipeline_regs(ST_EXEC-1).act_array(ACT_EXEC_BRA); + exec_bra_instr_word <= pipeline_regs(ST_EXEC-1).instr_word; + exec_bra_instr_array <= pipeline_regs(ST_EXEC-1).instr_array; + exec_bra_jump_address <= pipeline_regs(ST_EXEC-1).adgen_address_x when pipeline_regs(ST_EXEC-1).dble_word_instr = '0' else + unsigned(pipeline_regs(ST_EXEC-2).instr_word(BW_ADDRESS-1 downto 0)); + exec_bra_bit_cond_met <= exec_bit_modify_bit_cond_met; + + inst_exec_stage_cr_mod : exec_stage_cr_mod port map( + activate_exec_cr_mod => exec_cr_mod_activate, + instr_word => exec_cr_mod_instr_word, + instr_array => exec_cr_mod_instr_array, + register_file => register_file, + modify_sr => exec_cr_mod_modify_sr, + modified_sr => exec_cr_mod_modified_sr, + modify_omr => exec_cr_mod_modify_omr, + modified_omr => exec_cr_mod_modified_omr + ); + + exec_cr_mod_activate <= pipeline_regs(ST_EXEC-1).act_array(ACT_EXEC_CR_MOD); + exec_cr_mod_instr_word <= pipeline_regs(ST_EXEC-1).instr_word; + exec_cr_mod_instr_array <= pipeline_regs(ST_EXEC-1).instr_array; + + inst_exec_stage_loop: exec_stage_loop port map( + clk => clk, + rst => rst, + activate_exec_loop => exec_loop_activate, + instr_word => exec_loop_instr_word, + instr_array => exec_loop_instr_array, + loop_iterations => exec_loop_iterations, + loop_address => exec_loop_address, + loop_start_address => exec_loop_start_address, + register_file => register_file, + fetch_perform_enddo=> fetch_perform_enddo, + memory_stall => memory_stall, + push_stack => exec_loop_push_stack, + pop_stack => exec_loop_pop_stack, + stall_rep => exec_loop_stall_rep, + stall_do => exec_loop_stall_do, + modify_lc => exec_loop_modify_lc, + decrement_lc => exec_loop_decrement_lc, + modified_lc => exec_loop_modified_lc, + modify_la => exec_loop_modify_la, + modified_la => exec_loop_modified_la, + modify_pc => exec_loop_modify_pc, + modified_pc => exec_loop_modified_pc, + modify_sr => exec_loop_modify_sr, + modified_sr => exec_loop_modified_sr + ); + + exec_loop_activate <= pipeline_regs(ST_EXEC-1).act_array(ACT_EXEC_LOOP); + exec_loop_instr_word <= pipeline_regs(ST_EXEC-1).instr_word; + exec_loop_instr_array <= pipeline_regs(ST_EXEC-1).instr_array; + exec_loop_iterations <= unsigned(exec_src_operand(15 downto 0)); + -- from which source is our operand? + -- - XMEM + -- - YMEM + -- - Any register + -- - Immediate (from instruction word) +-- exec_src_operand <= unsigned(pipeline_regs(ST_EXEC-1).RAM_out_x(BW_ADDRESS-1 downto 0)) when +-- pipeline_regs(ST_EXEC-1).act_array(ACT_X_MEM_RD) = '1' else +-- unsigned(pipeline_regs(ST_EXEC-1).RAM_out_y(BW_ADDRESS-1 downto 0)) when +-- pipeline_regs(ST_EXEC-1).act_array(ACT_Y_MEM_RD) = '1' else +-- unsigned(rf_reg_rd_data(15 downto 0)) when +-- pipeline_regs(ST_EXEC-1).act_array(ACT_REG_RD) = '1' else +-- "00000000" & unsigned(pipeline_regs(ST_EXEC-1).instr_word(15 downto 8)); + + -- Loop address is given by the second instruction word of the DO instruction. + -- This address is available one previous stage within the pipeline + exec_loop_address <= unsigned(pipeline_regs(ST_EXEC-2).instr_word(BW_ADDRESS-1 downto 0)) - 1; + -- one more stage before we find the programm counter of the first instruction to be executed in a DO loop + exec_loop_start_address <= unsigned(pipeline_regs(ST_EXEC-3).pc); + + -- For the 8 bit immediate is can be either a fractional (registers x0,x1,y0,y1,a,b) or an unsigned (the rest) + exec_imm_8bit(23 downto 16) <= (others => '0') when rf_reg_wr_addr(5 downto 2) /= "0001" and rf_reg_wr_addr(5 downto 1) /= "00111" else + pipeline_regs(ST_EXEC-1).instr_word(15 downto 8); + exec_imm_8bit(15 downto 8) <= (others => '0'); + exec_imm_8bit( 7 downto 0) <= (others => '0') when rf_reg_wr_addr(5 downto 2) = "0001" or rf_reg_wr_addr(5 downto 1) = "00111" else + pipeline_regs(ST_EXEC-1).instr_word(15 downto 8); + -- The 12 bit immediate stems from the instruction word + exec_imm_12bit(23 downto 12) <= (others => '0'); + exec_imm_12bit(11 downto 0) <= pipeline_regs(ST_EXEC-1).instr_word(3 downto 0) & pipeline_regs(ST_EXEC-1).instr_word(15 downto 8); + ----------------- + -- REGISTER FILE + ----------------- + inst_reg_file: reg_file port map( + clk => clk, + rst => rst, + register_file => register_file, + wr_R_port_A_valid => rf_wr_R_port_A_valid, + wr_R_port_A => adgen_wr_R_port_A, + wr_R_port_B_valid => rf_wr_R_port_B_valid, + wr_R_port_B => adgen_wr_R_port_B, + reg_wr_addr => rf_reg_wr_addr, + reg_wr_addr_valid => rf_reg_wr_addr_valid, + reg_wr_data => rf_reg_wr_data, + reg_rd_addr => rf_reg_rd_addr, + reg_rd_data => rf_reg_rd_data, + alu_wr_valid => rf_alu_wr_valid, + alu_wr_addr => exec_alu_dst_accu, + alu_wr_data => exec_alu_modified_accu, + X_bus_rd_addr => rf_X_bus_rd_addr, + X_bus_data_out => rf_X_bus_data_out, + X_bus_wr_addr => rf_X_bus_wr_addr , + X_bus_wr_valid => rf_X_bus_wr_valid, + X_bus_data_in => rf_X_bus_data_in , + Y_bus_rd_addr => rf_Y_bus_rd_addr , + Y_bus_data_out => rf_Y_bus_data_out, + Y_bus_wr_addr => rf_Y_bus_wr_addr , + Y_bus_wr_valid => rf_Y_bus_wr_valid, + Y_bus_data_in => rf_Y_bus_data_in , + L_bus_rd_addr => rf_L_bus_rd_addr , + L_bus_rd_valid => rf_L_bus_rd_valid, + L_bus_wr_addr => rf_L_bus_wr_addr , + L_bus_wr_valid => rf_L_bus_wr_valid, + push_stack => push_stack, + pop_stack => pop_stack, + set_sr => rf_set_sr, + new_sr => rf_new_sr, + set_omr => rf_set_omr, + new_omr => rf_new_omr, + set_la => rf_set_la, + new_la => rf_new_la, + dec_lc => rf_dec_lc, + set_lc => rf_set_lc, + new_lc => rf_new_lc + ); + + ----------------- + -- BUSES (X,Y,L) + ----------------- + rf_X_bus_wr_valid <= pipeline_regs(ST_EXEC-1).act_array(ACT_X_BUS_WR); + rf_X_bus_wr_addr <= pipeline_regs(ST_EXEC-1).x_bus_wr_addr; + rf_X_bus_rd_addr <= pipeline_regs(ST_EXEC-1).x_bus_rd_addr; + rf_X_bus_data_in <= rf_X_bus_data_out when pipeline_regs(ST_EXEC-1).act_array(ACT_X_BUS_RD) = '1' else + pipeline_regs(ST_EXEC-1).RAM_out_x; -- when pipeline_regs(ST_EXEC-1).act_array(ACT_X_MEM_RD) = '1' else + + rf_Y_bus_wr_valid <= pipeline_regs(ST_EXEC-1).act_array(ACT_Y_BUS_WR); + rf_Y_bus_wr_addr <= pipeline_regs(ST_EXEC-1).y_bus_wr_addr; + rf_Y_bus_rd_addr <= pipeline_regs(ST_EXEC-1).y_bus_rd_addr; + rf_Y_bus_data_in <= rf_Y_bus_data_out when pipeline_regs(ST_EXEC-1).act_array(ACT_Y_BUS_RD) = '1' else + pipeline_regs(ST_EXEC-1).RAM_out_y; -- when pipeline_regs(ST_EXEC-1).act_array(ACT_Y_MEM_RD) = '1' else + + rf_L_bus_wr_valid <= pipeline_regs(ST_EXEC-1).act_array(ACT_L_BUS_WR); + rf_L_bus_rd_valid <= pipeline_regs(ST_EXEC-1).act_array(ACT_L_BUS_RD); + rf_L_bus_wr_addr <= pipeline_regs(ST_EXEC-1).l_bus_addr; -- equal to bits in instruction word + rf_L_bus_rd_addr <= pipeline_regs(ST_EXEC-1).l_bus_addr; -- could be simplified by taking these bits.. + + -- writing to the R registers within the ADGEN stage has to be prevented when + -- 1) a jump is currently being executed (which is detected in the exec stage) + -- 2) stall cycles occur. In this case the write will happen in the last cycle, when we stop stalling. + -- 3) a memory access results in a stall (e.g. caused by the instruction to REP) + rf_wr_R_port_A_valid <= '0' when stall_flags(ST_ADGEN) = '1' or + exec_bra_modify_pc = '1' or + memory_stall = '1' else + adgen_wr_R_port_A_valid; + rf_wr_R_port_B_valid <= '0' when stall_flags(ST_ADGEN) = '1' or + exec_bra_modify_pc = '1' or + memory_stall = '1' else + adgen_wr_R_port_B_valid; + + + rf_reg_wr_addr <= pipeline_regs(ST_EXEC-1).reg_wr_addr; + -- can be set due to + -- 1) normal write operation (e.g., move) + -- 2) conditional move (Tcc) + rf_reg_wr_addr_valid <= '1' when pipeline_regs(ST_EXEC-1).act_array(ACT_REG_WR) = '1' else + exec_cc_flag_set when pipeline_regs(ST_EXEC-1).act_array(ACT_REG_WR_CC) = '1' else '0'; + rf_reg_wr_data <= exec_dst_operand; + + rf_reg_rd_addr <= pipeline_regs(ST_EXEC-1).reg_rd_addr; + + -- Writing from the ALU can depend on the condition code (Tcc) instruction + rf_alu_wr_valid <= exec_cc_flag_set when pipeline_regs(ST_EXEC-1).act_array(ACT_ALU_WR_CC) = '1' else + exec_alu_modify_accu; + + push_stack.valid <= '1' when exec_bra_push_stack.valid = '1' or exec_loop_push_stack.valid = '1' else '0'; + push_stack.content <= exec_bra_push_stack.content when exec_bra_push_stack.valid = '1' else + exec_loop_push_stack.content; + -- for jump to subroutine store the pc of the subsequent instruction + push_stack.pc <= pipeline_regs(ST_EXEC-2).pc when exec_bra_push_stack.valid = '1' and pipeline_regs(ST_EXEC-1).dble_word_instr = '0' else + pipeline_regs(ST_EXEC-3).pc when exec_bra_push_stack.valid = '1' and pipeline_regs(ST_EXEC-1).dble_word_instr = '1' else + exec_loop_push_stack.pc when exec_loop_push_stack.valid = '1' else + (others => '0'); + + pop_stack.valid <= '1' when exec_bra_pop_stack.valid = '1' or exec_loop_pop_stack.valid = '1' else '0'; + + rf_set_sr <= '1' when exec_bra_modify_sr = '1' or + exec_cr_mod_modify_sr = '1' or + exec_loop_modify_sr = '1' or + exec_alu_modify_sr = '1' or + exec_bit_modify_modify_sr = '1' else '0'; + rf_new_sr <= exec_bra_modified_sr when exec_bra_modify_sr = '1' else + exec_cr_mod_modified_sr when exec_cr_mod_modify_sr = '1' else + exec_loop_modified_sr when exec_loop_modify_sr = '1' else + exec_alu_modified_sr when exec_alu_modify_sr = '1' else + exec_bit_modify_modified_sr; -- when exec_bit_modify_modify_sr = '1' else + + rf_set_omr <= exec_cr_mod_modify_omr; + rf_new_omr <= exec_cr_mod_modified_omr; + rf_set_lc <= exec_loop_modify_lc; + rf_new_lc <= exec_loop_modified_lc; + rf_set_la <= exec_loop_modify_la; + rf_new_la <= exec_loop_modified_la; + + rf_dec_lc <= '1' when exec_loop_decrement_lc = '1' or fetch_decrement_lc = '1' else '0'; + + --------------------- + -- MEMORY MANAGEMENT + --------------------- + MMU_inst: memory_management port map ( + clk => clk, + rst => rst, + stall_flags => stall_flags, + memory_stall => memory_stall, + data_rom_enable => register_file.omr(2), + pmem_ctrl_in => pmem_ctrl_in, + pmem_ctrl_out => pmem_ctrl_out, + xmem_ctrl_in => xmem_ctrl_in, + xmem_ctrl_out => xmem_ctrl_out, + ymem_ctrl_in => ymem_ctrl_in, + ymem_ctrl_out => ymem_ctrl_out + ); + + ------------------ + -- Program Memory + ------------------ + pmem_ctrl_in.rd_addr <= pc_new; + pmem_ctrl_in.rd_en <= '1' when stall_flags(ST_FETCH) = '0' else '0'; + -- TODO: Writing to PMEM! + pmem_ctrl_in.wr_addr <= (others => '0'); + pmem_ctrl_in.wr_en <= '0'; + pmem_ctrl_in.data_in <= (others => '0'); + + pmem_data_out <= pmem_ctrl_out.data_out; + pmem_data_out_valid <= pmem_ctrl_out.data_out_valid; + + + ------------------ + -- X Memory + ------------------ + -- Either take the result of the AGU or use the short absolute value stored in the instruction word + xmem_ctrl_in.rd_addr <= adgen_address_out_x when pipeline_regs(ST_ADGEN-1).act_array(ACT_ADGEN) = '1' else + "0000000000" & unsigned(pipeline_regs(ST_ADGEN-1).instr_word(13 downto 8)); + xmem_ctrl_in.rd_en <= '1' when pipeline_regs(ST_ADGEN-1).act_array(ACT_X_MEM_RD) = '1' else '0'; + -- Either take the result of the AGU or use the absolute value stored in the instruction word + xmem_ctrl_in.wr_addr <= pipeline_regs(ST_EXEC-1).adgen_address_x when pipeline_regs(ST_EXEC-1).act_array(ACT_ADGEN) = '1' else + "0000000000" & unsigned(pipeline_regs(ST_EXEC-1).instr_word(13 downto 8)); + xmem_ctrl_in.wr_en <= '1' when pipeline_regs(ST_EXEC-1).act_array(ACT_X_MEM_WR) = '1' else '0'; + xmem_ctrl_in.data_in <= rf_X_bus_data_out when pipeline_regs(ST_EXEC-1).act_array(ACT_X_BUS_RD) = '1' or + pipeline_regs(ST_EXEC-1).act_array(ACT_L_BUS_RD) = '1' else + exec_dst_operand; + + xmem_data_out <= xmem_ctrl_out.data_out; + xmem_data_out_valid <= xmem_ctrl_out.data_out_valid; + + ------------------ + -- Y Memory + ------------------ + -- Either take the result of the AGU or use the absolute value stored in the instruction word + ymem_ctrl_in.rd_addr <= adgen_address_out_y when pipeline_regs(ST_ADGEN-1).act_array(ACT_ADGEN) = '1' else + "0000000000" & unsigned(pipeline_regs(ST_ADGEN-1).instr_word(13 downto 8)); + ymem_ctrl_in.rd_en <= '1' when pipeline_regs(ST_ADGEN-1).act_array(ACT_Y_MEM_RD) = '1' else '0'; + -- Either take the result of the AGU or use the absolute value stored in the instruction word + ymem_ctrl_in.wr_addr <= pipeline_regs(ST_EXEC-1).adgen_address_y when pipeline_regs(ST_EXEC-1).act_array(ACT_ADGEN) = '1' else + "0000000000" & unsigned(pipeline_regs(ST_EXEC-1).instr_word(13 downto 8)); + ymem_ctrl_in.wr_en <= '1' when pipeline_regs(ST_EXEC-1).act_array(ACT_Y_MEM_WR) = '1' else '0'; + ymem_ctrl_in.data_in <= rf_Y_bus_data_out when pipeline_regs(ST_EXEC-1).act_array(ACT_Y_BUS_RD) = '1' or + pipeline_regs(ST_EXEC-1).act_array(ACT_L_BUS_RD) = '1' else + exec_dst_operand; + + ymem_data_out <= ymem_ctrl_out.data_out; + ymem_data_out_valid <= ymem_ctrl_out.data_out_valid; + + +end architecture rtl; diff --git a/vhdl/rtl/vhdl/DSP/src/reg_file.vhd b/vhdl/rtl/vhdl/DSP/src/reg_file.vhd new file mode 100644 index 0000000..7f3244c --- /dev/null +++ b/vhdl/rtl/vhdl/DSP/src/reg_file.vhd @@ -0,0 +1,679 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +library work; +use work.parameter_pkg.all; +use work.types_pkg.all; +use work.constants_pkg.all; + +entity reg_file is port( + clk, rst : in std_logic; + register_file : out register_file_type; + wr_R_port_A_valid : in std_logic; + wr_R_port_A : in addr_wr_port_type; + wr_R_port_B_valid : in std_logic; + wr_R_port_B : in addr_wr_port_type; + alu_wr_valid : in std_logic; + alu_wr_addr : in std_logic; + alu_wr_data : in signed(55 downto 0); + reg_wr_addr : in std_logic_vector(5 downto 0); + reg_wr_addr_valid : in std_logic; + reg_wr_data : in std_Logic_vector(23 downto 0); + reg_rd_addr : in std_logic_vector(5 downto 0); + reg_rd_data : out std_Logic_vector(23 downto 0); + X_bus_rd_addr : in std_logic_vector(1 downto 0); + X_bus_data_out : out std_logic_vector(23 downto 0); + X_bus_wr_addr : in std_logic_vector(1 downto 0); + X_bus_wr_valid : in std_logic; + X_bus_data_in : in std_logic_vector(23 downto 0); + Y_bus_rd_addr : in std_logic_vector(1 downto 0); + Y_bus_data_out : out std_logic_vector(23 downto 0); + Y_bus_wr_addr : in std_logic_vector(1 downto 0); + Y_bus_wr_valid : in std_logic; + Y_bus_data_in : in std_logic_vector(23 downto 0); + L_bus_rd_addr : in std_logic_vector(2 downto 0); + L_bus_rd_valid : in std_logic; + L_bus_wr_addr : in std_logic_vector(2 downto 0); + L_bus_wr_valid : in std_logic; + push_stack : in push_stack_type; + pop_stack : in pop_stack_type; + set_sr : in std_logic; + new_sr : in std_logic_vector(15 downto 0); + set_omr : in std_logic; + new_omr : in std_logic_vector(7 downto 0); + dec_lc : in std_logic; + set_lc : in std_logic; + new_lc : in unsigned(15 downto 0); + set_la : in std_logic; + new_la : in unsigned(BW_ADDRESS-1 downto 0) +); +end entity; + + +architecture rtl of reg_file is + + signal addr_r : addr_array; + signal addr_m : addr_array; + signal addr_n : addr_array; + + signal loop_address : unsigned(BW_ADDRESS-1 downto 0); + signal loop_counter : unsigned(15 downto 0); + + -- condition code register + signal ccr : std_logic_vector(7 downto 0); + -- mode register + signal mr : std_logic_vector(7 downto 0); + -- status register = mode register + condition code register + signal sr : std_logic_vector(15 downto 0); + -- operation mode register + signal omr : std_logic_vector(7 downto 0); + + signal stack_pointer : unsigned(5 downto 0); + signal system_stack_ssh : stack_array_type; + signal system_stack_ssl : stack_array_type; + + signal x0 : signed(23 downto 0); + signal x1 : signed(23 downto 0); + signal y0 : signed(23 downto 0); + signal y1 : signed(23 downto 0); + + signal a0 : signed(23 downto 0); + signal a1 : signed(23 downto 0); + signal a2 : signed(7 downto 0); + + signal b0 : signed(23 downto 0); + signal b1 : signed(23 downto 0); + signal b2 : signed(7 downto 0); + + signal limited_a1 : signed(23 downto 0); + signal limited_b1 : signed(23 downto 0); + signal limited_a0 : signed(23 downto 0); + signal limited_b0 : signed(23 downto 0); + signal set_limiting_flag : std_logic; + signal X_bus_rd_limited_a : std_logic; + signal X_bus_rd_limited_b : std_logic; + signal Y_bus_rd_limited_a : std_logic; + signal Y_bus_rd_limited_b : std_logic; + signal reg_rd_limited_a : std_logic; + signal reg_rd_limited_b : std_logic; + signal rd_limited_a : std_logic; + signal rd_limited_b : std_logic; + +begin + + + + sr <= mr & ccr; + + register_file.addr_r <= addr_r; + register_file.addr_n <= addr_n; + register_file.addr_m <= addr_m; + register_file.lc <= loop_counter; + register_file.la <= loop_address; + register_file.ccr <= ccr; + register_file.mr <= mr; + register_file.sr <= sr; + register_file.omr <= omr; + register_file.stack_pointer <= stack_pointer; + register_file.current_ssh <= system_stack_ssh(to_integer(stack_pointer(3 downto 0))); + register_file.current_ssl <= system_stack_ssl(to_integer(stack_pointer(3 downto 0))); + register_file.a <= a2 & a1 & a0; + register_file.b <= b2 & b1 & b0; + register_file.x0 <= x0; + register_file.x1 <= x1; + register_file.y0 <= y0; + register_file.y1 <= y1; + + + global_register_file: process(clk) is + variable stack_pointer_plus_1 : unsigned(3 downto 0); + variable reg_addr : integer range 0 to 7; + begin + if rising_edge(clk) then + if rst = '1' then + addr_r <= (others => (others => '0')); + addr_n <= (others => (others => '0')); + addr_m <= (others => (others => '1')); + ccr <= (others => '0'); + mr <= (others => '0'); + omr <= (others => '0'); + system_stack_ssl <= (others => (others => '0')); + system_stack_ssh <= (others => (others => '0')); + stack_pointer <= (others => '0'); + loop_counter <= (others => '0'); + loop_address <= (others => '0'); + x0 <= (others => '0'); + x1 <= (others => '0'); + y0 <= (others => '0'); + y1 <= (others => '0'); + a0 <= (others => '0'); + a1 <= (others => '0'); + a2 <= (others => '0'); + b0 <= (others => '0'); + b1 <= (others => '0'); + b2 <= (others => '0'); + else + reg_addr := to_integer(unsigned(reg_wr_addr(2 downto 0))); + ----------------------------------------------------------------------- + -- General write port to register file using 6 bit addressing scheme + ----------------------------------------------------------------------- + if reg_wr_addr_valid = '1' then + case reg_wr_addr(5 downto 3) is + -- X0, X1, Y0, Y1 + when "000" => + case reg_wr_addr(2 downto 0) is + when "100" => + x0 <= signed(reg_wr_data); + when "101" => + x1 <= signed(reg_wr_data); + when "110" => + y0 <= signed(reg_wr_data); + when "111" => + y1 <= signed(reg_wr_data); + when others => + end case; + + -- A0, B0, A2, B2, A1, B1, A, B + when "001" => + case reg_wr_addr(2 downto 0) is + when "000" => + a0 <= signed(reg_wr_data); + when "001" => + b0 <= signed(reg_wr_data); + when "010" => + a2 <= signed(reg_wr_data(7 downto 0)); + when "011" => + b2 <= signed(reg_wr_data(7 downto 0)); + when "100" => + a1 <= signed(reg_wr_data); + when "101" => + b1 <= signed(reg_wr_data); + when "110" => + a2 <= (others => reg_wr_data(23)); + a1 <= signed(reg_wr_data); + a0 <= (others => '0'); + when "111" => + b2 <= (others => reg_wr_data(23)); + b1 <= signed(reg_wr_data); + b0 <= (others => '0'); + when others => + end case; + + -- R0-R7 + when "010" => + addr_r(reg_addr) <= unsigned(reg_wr_data(BW_ADDRESS-1 downto 0)); + + -- N0-N7 + when "011" => + addr_n(reg_addr) <= unsigned(reg_wr_data(BW_ADDRESS-1 downto 0)); + + -- M0-M7 + when "100" => + addr_m(reg_addr) <= unsigned(reg_wr_data(BW_ADDRESS-1 downto 0)); + + -- SR, OMR, SP, SSH, SSL, LA, LC + when "111" => + case reg_wr_addr(2 downto 0) is + -- SR + when "001" => + mr <= reg_wr_data(15 downto 8); + ccr <= reg_wr_data( 7 downto 0); + + -- OMR + when "010" => + omr <= reg_wr_data(7 downto 0); + + -- SP + when "011" => + stack_pointer <= unsigned(reg_wr_data(5 downto 0)); + + -- SSH + when "100" => + system_stack_ssh(to_integer(stack_pointer_plus_1)) <= reg_wr_data(BW_ADDRESS-1 downto 0); + -- increase stack after writing + stack_pointer(3 downto 0) <= stack_pointer_plus_1; + -- test whether stack is full, if so set the stack error flag (SE) + if stack_pointer(3 downto 0) = "1111" then + stack_pointer(4) <= '1'; + end if; + + -- SSL + when "101" => + system_stack_ssl(to_integer(stack_pointer)) <= reg_wr_data(BW_ADDRESS-1 downto 0); + + -- LA + when "110" => + loop_address <= unsigned(reg_wr_data(BW_ADDRESS-1 downto 0)); + + -- LC + when "111" => + loop_counter <= unsigned(reg_wr_data(15 downto 0)); + + when others => + end case; + when others => + end case; + end if; + + ---------------- + -- X BUS Write + ---------------- + if X_bus_wr_valid = '1' then + case X_bus_wr_addr is + when "00" => + x0 <= signed(X_bus_data_in); + when "01" => + x1 <= signed(X_bus_data_in); + when "10" => + a2 <= (others => X_bus_data_in(23)); + a1 <= signed(X_bus_data_in); + a0 <= (others => '0'); + when others => + b2 <= (others => X_bus_data_in(23)); + b1 <= signed(X_bus_data_in); + b0 <= (others => '0'); + end case; + end if; + ---------------- + -- Y BUS Write + ---------------- + if Y_bus_wr_valid = '1' then + case Y_bus_wr_addr is + when "00" => + y0 <= signed(Y_bus_data_in); + when "01" => + y1 <= signed(Y_bus_data_in); + when "10" => + a2 <= (others => Y_bus_data_in(23)); + a1 <= signed(Y_bus_data_in); + a0 <= (others => '0'); + when others => + b2 <= (others => Y_bus_data_in(23)); + b1 <= signed(Y_bus_data_in); + b0 <= (others => '0'); + end case; + end if; + ------------------ + -- L BUS Write + ------------------ + if L_bus_wr_valid = '1' then + case L_bus_wr_addr is + -- A10 + when "000" => + a1 <= signed(X_bus_data_in); + a0 <= signed(Y_bus_data_in); + -- B10 + when "001" => + b1 <= signed(X_bus_data_in); + b0 <= signed(Y_bus_data_in); + -- X + when "010" => + x1 <= signed(X_bus_data_in); + x0 <= signed(Y_bus_data_in); + -- Y + when "011" => + y1 <= signed(X_bus_data_in); + y0 <= signed(Y_bus_data_in); + -- A + when "100" => + a2 <= (others => X_bus_data_in(23)); + a1 <= signed(X_bus_data_in); + a0 <= signed(Y_bus_data_in); + -- B + when "101" => + b2 <= (others => X_bus_data_in(23)); + b1 <= signed(X_bus_data_in); + b0 <= signed(Y_bus_data_in); + -- AB + when "110" => + a2 <= (others => X_bus_data_in(23)); + a1 <= signed(X_bus_data_in); + a0 <= (others => '0'); + b2 <= (others => Y_bus_data_in(23)); + b1 <= signed(Y_bus_data_in); + b0 <= (others => '0'); + -- BA + when others => + a2 <= (others => Y_bus_data_in(23)); + a1 <= signed(Y_bus_data_in); + a0 <= (others => '0'); + b2 <= (others => X_bus_data_in(23)); + b1 <= signed(X_bus_data_in); + b0 <= (others => '0'); + end case; + end if; + + --------------------- + -- STATUS REGISTERS + --------------------- + if set_sr = '1' then + ccr <= new_sr( 7 downto 0); + mr <= new_sr(15 downto 8); + end if; + if set_omr = '1' then + omr <= new_omr; + end if; + -- data limiter active? + -- listing this statement after the set_sr test results + -- in the correct behaviour for ALU operations with parallel move + if set_limiting_flag = '1' then + ccr(6) <= '1'; + end if; + + -------------------- + -- LOOP REGISTERS + -------------------- + if set_la = '1' then + loop_address <= new_la; + end if; + if set_lc = '1' then + loop_counter <= new_lc; + end if; + if dec_lc = '1' then + loop_counter <= loop_counter - 1; + end if; + + --------------------- + -- ADDRESS REGISTER + --------------------- + if wr_R_port_A_valid = '1' then + addr_r(to_integer(wr_R_port_A.reg_number)) <= wr_R_port_A.reg_value; + end if; + if wr_R_port_B_valid = '1' then + addr_r(to_integer(wr_R_port_B.reg_number)) <= wr_R_port_B.reg_value; + end if; + + ------------------------- + -- ALU ACCUMULATOR WRITE + ------------------------- + if alu_wr_valid = '1' then + if alu_wr_addr = '0' then + a2 <= alu_wr_data(55 downto 48); + a1 <= alu_wr_data(47 downto 24); + a0 <= alu_wr_data(23 downto 0); + else + b2 <= alu_wr_data(55 downto 48); + b1 <= alu_wr_data(47 downto 24); + b0 <= alu_wr_data(23 downto 0); + end if; + end if; + + --------------------- + -- STACK CONTROLLER + --------------------- + stack_pointer_plus_1 := stack_pointer(3 downto 0) + 1; + if push_stack.valid = '1' then + -- increase stack after writing + stack_pointer(3 downto 0) <= stack_pointer_plus_1; + -- test whether stack is full, if so set the stack error flag (SE) + if stack_pointer(3 downto 0) = "1111" then + stack_pointer(4) <= '1'; + end if; + case push_stack.content is + when PC => + system_stack_ssh(to_integer(stack_pointer_plus_1)) <= std_logic_vector(push_stack.pc); + + when PC_AND_SR => + system_stack_ssh(to_integer(stack_pointer_plus_1)) <= std_logic_vector(push_stack.pc); + system_stack_ssl(to_integer(stack_pointer_plus_1)) <= SR; + + when LA_AND_LC => + system_stack_ssh(to_integer(stack_pointer_plus_1)) <= std_logic_vector(loop_address); + system_stack_ssl(to_integer(stack_pointer_plus_1)) <= std_logic_vector(loop_counter); + + end case; + end if; + + -- decrease stack pointer + if pop_stack.valid = '1' then + stack_pointer(3 downto 0) <= stack_pointer(3 downto 0) - 1; + -- if stack is empty set the underflow flag (bit 5, UF) and the stack error flag (bit 4, SE) + if stack_pointer(3 downto 0) = "0000" then + stack_pointer(5) <= '1'; + stack_pointer(4) <= '1'; + end if; + end if; + end if; + end if; + end process; + + + x_bus_rd_port: process(X_bus_rd_addr,x0,x1,a1,b1,limited_a1,limited_b1, + L_bus_rd_addr,L_bus_rd_valid,y1) is + begin + X_bus_rd_limited_a <= '0'; + X_bus_rd_limited_b <= '0'; + case X_bus_rd_addr is + when "00" => X_bus_data_out <= std_logic_vector(x0); + when "01" => X_bus_data_out <= std_logic_vector(x1); + when "10" => X_bus_data_out <= std_logic_vector(limited_a1); X_bus_rd_limited_a <= '1'; + when others => X_bus_data_out <= std_logic_vector(limited_b1); X_bus_rd_limited_b <= '1'; + end case; + if L_bus_rd_valid = '1' then + case L_bus_rd_addr is + when "000" => X_bus_data_out <= std_logic_vector(a1); + when "001" => X_bus_data_out <= std_logic_vector(b1); + when "010" => X_bus_data_out <= std_logic_vector(x1); + when "011" => X_bus_data_out <= std_logic_vector(y1); + when "100" => X_bus_data_out <= std_logic_vector(limited_a1); X_bus_rd_limited_a <= '1'; + when "101" => X_bus_data_out <= std_logic_vector(limited_b1); X_bus_rd_limited_b <= '1'; + when "110" => X_bus_data_out <= std_logic_vector(limited_a1); X_bus_rd_limited_a <= '1'; + when others => X_bus_data_out <= std_logic_vector(limited_b1); X_bus_rd_limited_b <= '1'; + end case; + end if; + end process x_bus_rd_port; + + y_bus_rd_port: process(Y_bus_rd_addr,y0,y1,a1,b1,limited_a1,limited_b1, + L_bus_rd_addr,L_bus_rd_valid,a0,b0,x0,limited_a0,limited_b0) is + begin + Y_bus_rd_limited_a <= '0'; + Y_bus_rd_limited_b <= '0'; + case Y_bus_rd_addr is + when "00" => Y_bus_data_out <= std_logic_vector(y0); + when "01" => Y_bus_data_out <= std_logic_vector(y1); + when "10" => Y_bus_data_out <= std_logic_vector(limited_a1); Y_bus_rd_limited_a <= '1'; + when others => Y_bus_data_out <= std_logic_vector(limited_b1); Y_bus_rd_limited_b <= '1'; + end case; + if L_bus_rd_valid = '1' then + case L_bus_rd_addr is + when "000" => Y_bus_data_out <= std_logic_vector(a0); + when "001" => Y_bus_data_out <= std_logic_vector(b0); + when "010" => Y_bus_data_out <= std_logic_vector(x0); + when "011" => Y_bus_data_out <= std_logic_vector(y0); + when "100" => Y_bus_data_out <= std_logic_vector(limited_a0); Y_bus_rd_limited_a <= '1'; + when "101" => Y_bus_data_out <= std_logic_vector(limited_b0); Y_bus_rd_limited_b <= '1'; + when "110" => Y_bus_data_out <= std_logic_vector(limited_b1); Y_bus_rd_limited_b <= '1'; + when others => Y_bus_data_out <= std_logic_vector(limited_a1); Y_bus_rd_limited_a <= '1'; + end case; + end if; + end process y_bus_rd_port; + + + reg_rd_port: process(reg_rd_addr, x0,x1,y0,y1,a0,a1,a2,b0,b1,b2, + omr,ccr,mr,addr_r,addr_n,addr_m,stack_pointer, + loop_address,loop_counter,system_stack_ssl,system_stack_ssh) is + variable reg_addr : integer range 0 to 7; + begin + reg_addr := to_integer(unsigned(reg_rd_addr(2 downto 0))); + reg_rd_data <= (others => '0'); + reg_rd_limited_a <= '0'; + reg_rd_limited_b <= '0'; + + case reg_rd_addr(5 downto 3) is + -- X0, X1, Y0, Y1 + when "000" => + case reg_rd_addr(2 downto 0) is + when "100" => + reg_rd_data <= std_logic_vector(x0); + when "101" => + reg_rd_data <= std_logic_vector(x1); + when "110" => + reg_rd_data <= std_logic_vector(y0); + when "111" => + reg_rd_data <= std_logic_vector(y1); + when others => + end case; + + -- A0, B0, A2, B2, A1, B1, A, B + when "001" => + case reg_rd_addr(2 downto 0) is + when "000" => + reg_rd_data <= std_logic_vector(a0); + when "001" => + reg_rd_data <= std_logic_vector(b0); + when "010" => + -- MSBs are read as zero! + reg_rd_data(23 downto 8) <= (others => '0'); + reg_rd_data(7 downto 0) <= std_logic_vector(a2); + when "011" => + -- MSBs are read as zero! + reg_rd_data(23 downto 8) <= (others => '0'); + reg_rd_data(7 downto 0) <= std_logic_vector(b2); + when "100" => + reg_rd_data <= std_logic_vector(a1); + when "101" => + reg_rd_data <= std_logic_vector(b1); + when "110" => + reg_rd_data <= std_logic_vector(limited_a1); + reg_rd_limited_a <= '1'; + when "111" => + reg_rd_data <= std_logic_vector(limited_b1); + reg_rd_limited_b <= '1'; + when others => + end case; + + -- R0-R7 + when "010" => + reg_rd_data <= std_logic_vector(resize(addr_r(reg_addr), 24)); + + -- N0-N7 + when "011" => + reg_rd_data <= std_logic_vector(resize(addr_n(reg_addr), 24)); + + -- M0-M7 + when "100" => + reg_rd_data <= std_logic_vector(resize(addr_m(reg_addr), 24)); + + -- SR, OMR, SP, SSH, SSL, LA, LC + when "111" => + case reg_wr_addr(2 downto 0) is + -- SR + when "001" => + reg_rd_data(23 downto 16) <= (others => '0'); + reg_rd_data(15 downto 0) <= mr & ccr; + + -- OMR + when "010" => + reg_rd_data(23 downto 8) <= (others => '0'); + reg_rd_data( 7 downto 0) <= omr; + + -- SP + when "011" => + reg_rd_data(23 downto 6) <= (others => '0'); + reg_rd_data(5 downto 0) <= std_logic_vector(stack_pointer); + + -- SSH + when "100" => +-- TODO! +-- system_stack_ssh(to_integer(stack_pointer_plus_1)) <= reg_wr_data(BW_ADDRESS-1 downto 0); +-- -- increase stack after writing +-- stack_pointer(3 downto 0) <= stack_pointer_plus_1; +-- -- test whether stack is full, if so set the stack error flag (SE) +-- if stack_pointer(3 downto 0) = "1111" then +-- stack_pointer(4) <= '1'; +-- end if; + + -- SSL + when "101" => + reg_rd_data <= (others => '0'); + reg_rd_data(BW_ADDRESS-1 downto 0) <= std_logic_vector(system_stack_ssl(to_integer(stack_pointer))); + + -- LA + when "110" => + reg_rd_data <= (others => '0'); + reg_rd_data(BW_ADDRESS-1 downto 0) <= std_logic_vector(loop_address); + + -- LC + when "111" => + reg_rd_data <= (others => '0'); + reg_rd_data(15 downto 0) <= std_logic_vector(loop_counter); + + when others => + end case; + when others => + end case; + end process; + + rd_limited_a <= '1' when reg_rd_limited_a = '1' or X_bus_rd_limited_a = '1' or Y_bus_rd_limited_a = '1' else '0'; + rd_limited_b <= '1' when reg_rd_limited_b = '1' or X_bus_rd_limited_b = '1' or Y_bus_rd_limited_b = '1' else '0'; + + data_shifter_limiter: process(a2,a1,a0,b2,b1,b0,sr,rd_limited_a,rd_limited_b) is + variable scaled_a : signed(55 downto 0); + variable scaled_b : signed(55 downto 0); + begin + + set_limiting_flag <= '0'; + ----------------- + -- DATA SCALING + ----------------- + -- test against scaling bits S1, S0 + case sr(11 downto 10) is + -- scale down (right shift) + when "01" => + scaled_a := a2(7) & a2 & a1 & a0(23 downto 1); + scaled_b := b2(7) & b2 & b1 & b0(23 downto 1); + -- scale up (arithmetic left shift) + when "10" => + scaled_a := a2(6 downto 0) & a1 & a0 & '0'; + scaled_b := b2(6 downto 0) & b1 & b0 & '0'; + -- "00" do not scale! + when others => + scaled_a := a2 & a1 & a0; + scaled_b := b2 & b1 & b0; + end case; + + -- only sign extension stored in a2? + -- Yes: No limiting needed! + if scaled_a(55 downto 47) = "111111111" or scaled_a(55 downto 47) = "000000000" then + limited_a1 <= scaled_a(47 downto 24); + limited_a0 <= scaled_a(23 downto 0); + else + -- positive value in a? + if scaled_a(55) = '0' then + limited_a1 <= X"7FFFFF"; + limited_a0 <= X"FFFFFF"; + -- negative value in a? + else + limited_a1 <= X"800000"; + limited_a0 <= X"000000"; + end if; + -- set the limit flag in the status register + if rd_limited_a = '1' then + set_limiting_flag <= '1'; + end if; + end if; + -- only sign extension stored in b2? + -- Yes: No limiting needed! + if scaled_b(55 downto 47) = "111111111" or scaled_b(55 downto 47) = "000000000" then + limited_b1 <= scaled_b(47 downto 24); + limited_b0 <= scaled_b(23 downto 0); + else + -- positive value in b? + if scaled_b(55) = '0' then + limited_b1 <= X"7FFFFF"; + limited_b0 <= X"FFFFFF"; + -- negative value in b? + else + limited_b1 <= X"800000"; + limited_b0 <= X"000000"; + end if; + -- set the limit flag in the status register + if rd_limited_b = '1' then + set_limiting_flag <= '1'; + end if; + end if; + + end process; + + +end architecture rtl; diff --git a/vhdl/rtl/vhdl/DSP/src/types_pkg.vhd b/vhdl/rtl/vhdl/DSP/src/types_pkg.vhd new file mode 100644 index 0000000..131f7fa --- /dev/null +++ b/vhdl/rtl/vhdl/DSP/src/types_pkg.vhd @@ -0,0 +1,167 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +library work; +use work.parameter_pkg.all; + + + +package types_pkg is + + -- the different addressing modes + type adgen_mode_type is (NOP, POST_MIN_N, POST_PLUS_N, POST_MIN_1, POST_PLUS_1, INDEXED_N, PRE_MIN_1, ABSOLUTE, IMMEDIATE); + ------------------------ + -- Decoded instructions + ------------------------ + type instructions_type is ( + INSTR_NOP , + INSTR_RTI , + INSTR_ILLEGAL , + INSTR_SWI , + INSTR_RTS , + INSTR_RESET , + INSTR_WAIT , + INSTR_STOP , + INSTR_ENDDO , + INSTR_ANDI , + INSTR_ORI , + INSTR_DIV , + INSTR_NORM , + INSTR_LUA , + INSTR_MOVEC , + INSTR_REP , + INSTR_DO , + INSTR_MOVEM , + INSTR_MOVEP , + INSTR_PM_MOVEM, + INSTR_BCLR , + INSTR_BSET , + INSTR_JCLR , + INSTR_JSET , + INSTR_JMP , + INSTR_JCC , + INSTR_BCHG , + INSTR_BTST , + INSTR_JSCLR , + INSTR_JSSET , + INSTR_JSR , + INSTR_JSCC ); + + type addr_array is array(0 to 7) of unsigned(BW_ADDRESS-1 downto 0); + + type alu_shift_mode is (NO_SHIFT, SHIFT_LEFT, SHIFT_RIGHT, ZEROS); + type alu_ccr_flag is (DONT_TOUCH, CLEAR, MODIFY, SET); + type alu_ccr_flag_array is array(7 downto 0) of alu_ccr_flag; + + type alu_ctrl_type is record + mul_op1 : std_logic_vector(1 downto 0); -- x0,x1,y0,y1 + mul_op2 : std_logic_vector(1 downto 0); -- x0,x1,y0,y1 + shift_src : std_logic; -- a,b + shift_src_sign : std_logic_vector(1 downto 0); -- 00: pos, 01: neg, 10: sign dependant, 11: reserved + shift_mode : alu_shift_mode; + rotate : std_logic; -- 0: logical shift, 1: rotate shift + add_src_stage_1 : std_logic_vector(2 downto 0); -- x0,x1,y0,y1,x,y,a,b + add_src_stage_2 : std_logic_vector(1 downto 0); -- 00: 0 , 01: add_src_1, 10: mul_result, 11: reserved + add_src_sign : std_logic_vector(1 downto 0); -- 00: pos, 01: neg, 10: sign dependant, 11: reserved + logic_function : std_logic_vector(2 downto 0); -- 000: none, 001: and, 010: or, 011: eor, 100: not + word_24_update : std_logic; -- only accumulator bits 47 downto 24 affected? + rounding_used : std_logic_vector(1 downto 0); -- 00: no rounding, 01: rounding, 10: add carry, 11: subtract carry + store_result : std_logic; -- 0: do not update accumulator, 1: update accumulator + dst_accu : std_logic; -- 0: a, 1: b + div_instr : std_logic; -- DIV instruction? Special ALU operations needed! + norm_instr : std_logic; -- NORM instruction? Special ALU operations needed! + ccr_flags_ctrl : alu_ccr_flag_array; + end record; + + type pipeline_signals is record + instr_word: std_logic_vector(23 downto 0); + pc : unsigned(BW_ADDRESS-1 downto 0); + dble_word_instr : std_logic; + instr_array : instructions_type; + act_array : std_logic_vector(NUM_ACT_SIGNALS-1 downto 0); + dec_activate : std_logic; + adgen_mode_a : adgen_mode_type; + adgen_mode_b : adgen_mode_type; + reg_wr_addr : std_logic_vector(5 downto 0); + reg_rd_addr : std_logic_vector(5 downto 0); + x_bus_rd_addr : std_logic_vector(1 downto 0); + x_bus_wr_addr : std_logic_vector(1 downto 0); + y_bus_rd_addr : std_logic_vector(1 downto 0); + y_bus_wr_addr : std_logic_vector(1 downto 0); + l_bus_addr : std_logic_vector(2 downto 0); + adgen_address_x : unsigned(BW_ADDRESS-1 downto 0); + adgen_address_y : unsigned(BW_ADDRESS-1 downto 0); + RAM_out_x : std_logic_vector(23 downto 0); + RAM_out_y : std_logic_vector(23 downto 0); + alu_ctrl : alu_ctrl_type; + end record; + + type pipeline_type is array(0 to PIPELINE_DEPTH-1) of pipeline_signals; + + + type register_file_type is record + a : signed(55 downto 0); + b : signed(55 downto 0); + x0 : signed(23 downto 0); + x1 : signed(23 downto 0); + y0 : signed(23 downto 0); + y1 : signed(23 downto 0); + la : unsigned(BW_ADDRESS-1 downto 0); + lc : unsigned(15 downto 0); + addr_r : addr_array; + addr_n : addr_array; + addr_m : addr_array; + ccr : std_logic_vector(7 downto 0); + mr : std_logic_vector(7 downto 0); + sr : std_logic_vector(15 downto 0); + omr : std_logic_vector(7 downto 0); + stack_pointer : unsigned(5 downto 0); +-- system_stack_ssh : stack_array_type; +-- system_stack_ssl : stack_array_type; + current_ssh : std_logic_vector(BW_ADDRESS-1 downto 0); + current_ssl : std_logic_vector(BW_ADDRESS-1 downto 0); + + end record; + + type addr_wr_port_type is record +-- write_valid : std_logic; + reg_number : unsigned(2 downto 0); + reg_value : unsigned(15 downto 0); + end record; + + type mem_ctrl_type_in is record + rd_addr : unsigned(BW_ADDRESS-1 downto 0); + rd_en : std_logic; + wr_addr : unsigned(BW_ADDRESS-1 downto 0); + wr_en : std_logic; + data_in : std_logic_vector(23 downto 0); + end record; + + type mem_ctrl_type_out is record + data_out : std_logic_vector(23 downto 0); + data_out_valid : std_logic; + end record; + + type memory_type is (X_MEM, Y_MEM, P_MEM); + --------------- + -- STACK TYPES + --------------- + type stack_array_type is array(0 to 15) of std_logic_vector(BW_ADDRESS-1 downto 0); + + type push_stack_content_type is (PC, PC_AND_SR, LA_AND_LC); + + type push_stack_type is record + valid : std_logic; + pc : unsigned(BW_ADDRESS-1 downto 0); + content : push_stack_content_type; + end record; + +-- type pop_stack_content_type is (PC, PC_AND_SR, SR, LA_AND_LC); + +-- type pop_stack_type is std_logic; + type pop_stack_type is record + valid : std_logic; +-- content : pop_stack_content_type; + end record; + +end package types_pkg; diff --git a/vhdl/rtl/vhdl/Firebee_V1/Firebee_V1.sdc b/vhdl/rtl/vhdl/Firebee_V1/Firebee_V1.sdc new file mode 100644 index 0000000..ffe6d02 --- /dev/null +++ b/vhdl/rtl/vhdl/Firebee_V1/Firebee_V1.sdc @@ -0,0 +1,30 @@ +#************************************************************** +# Time Information +#************************************************************** + + set_time_format -unit ps + + + +#************************************************************** +# Create Clock +#************************************************************** + +# create_clock -name CLK -period 100.000 -waveform {0.000 50.000} [get_ports {CLK}] + +create_clock -period 30.303 -name CLK_MAIN [get_ports {CLK_MAIN}] +create_clock -period 30.303 -name CLK_33M [get_ports {CLK_33M}] + +derive_pll_clocks -use_net_name +derive_clock_uncertainty + +#set_clock_groups -exclusive -group {CLK_2M0} +#set_clock_groups -exclusive -group {CLK_500K} +#set_clock_groups -exclusive -group {CLK_2M4576} +#set_clock_groups -exclusive -group {CLK_24M576} +#set_clock_groups -exclusive -group {CLK_FDC} +#set_clock_groups -exclusive -group {CLK_VIDEO} +#set_clock_groups -exclusive -group {CLK_25M} +#set_clock_groups -exclusive -group {CLK_48M} +#set_clock_groups -exclusive -group {CLK_PIXEL} + diff --git a/vhdl/rtl/vhdl/Firebee_V1/Firebee_V1_Top.vhd b/vhdl/rtl/vhdl/Firebee_V1/Firebee_V1_Top.vhd new file mode 100644 index 0000000..87379b7 --- /dev/null +++ b/vhdl/rtl/vhdl/Firebee_V1/Firebee_V1_Top.vhd @@ -0,0 +1,1306 @@ +---------------------------------------------------------------------- +---- ---- +---- This file is part of the 'Firebee' project. ---- +---- http://acp.atari.org ---- +---- ---- +---- Description: ---- +---- This design unit provides the toplevel of the 'Firebee' ---- +---- computer. It is optimized for the use of an Altera Cyclone ---- +---- FPGA (EP3C40F484). This IP-Core is based on the first edi- ---- +---- tion of the Firebee configware originally provided by Fredi ---- +---- Ashwanden and Wolfgang Förster. This release is in compa- ---- +---- rision to the first edition completely written in VHDL. ---- +---- ---- +---- Author(s): ---- +---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2012 Wolfgang Förster ---- +---- ---- +---- This source file 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 2 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, write to the Free ---- +---- Software Foundation, Inc., 51 Franklin Street, Fifth Floor, ---- +---- Boston, MA 02110-1301, USA. ---- +---- ---- +---------------------------------------------------------------------- +-- +-- Revision History +-- +-- Revision 2K12B 20120801 WF +-- Initial Release of the second edition, the most important changes are listed below. +-- Structural work: +-- Replaced the graphical top level by a VHDL model. +-- The new toplevel is now FIREBEE_V1. +-- Replaced the graphical Video Top Level by a VHDL model +-- The DDR_CTR is no DDR_CTRL. +-- Rewritten the DDR_CTR in VHDL. +-- Moved the DDR_CTRL to the FIREBEE_V1 top level. +-- Moved the BLITTER to the FIREBEE_V1 top level. +-- Removed the VIDEO_MOD_MUX_CLUTCTR. +-- Extracted from the AHDL code of MOD_MUX_CLUTCTR the new VIDEO_CTRL. +-- VIDEO_CTRL is now written in VHDL. +-- Removed the FalconIO_SDCard_IDE_CF. +-- Moved the keyboard ACIA from FalconIO_SDCard_IDE_CF to the FIREBEE_V1 top level. +-- Moved the MIDI ACIA from FalconIO_SDCard_IDE_CF to the FIREBEE_V1 top level. +-- Moved the soundchip module from FalconIO_SDCard_IDE_CF to the FIREBEE_V1 top level. +-- Moved the multi function port (MFP) from FalconIO_SDCard_IDE_CF to the FIREBEE_V1 top level. +-- Moved the floppy disk controller (FDC) from FalconIO_SDCard_IDE_CF to the FIREBEE_V1 top level. +-- Moved the SCSI controller from FalconIO_SDCard_IDE_CF to the FIREBEE_V1 top level. +-- Extracted a DMA logic from FalconIO_SDCard_IDE_CF which is now located in the FIREBEE_V1 top level. +-- Extracted a IDE_CF_SD_ROM logic from FalconIO_SDCard_IDE_CF which is now located in the FIREBEE_V1 top level. +-- Moved the PADDLE logic from FalconIO_SDCard_IDE_CF to the FIREBEE_V1 top level. +-- Rewritten the interrupt handler in VHDL. +-- Extracted the real time clock (RTC) logic from the interrupt handler (VHDL). +-- The RTC is now located in the FIREBEE_V1 top level. +-- Several code cleanups: +-- Resolved the tri state logic in all modules. The only tri states are now in the +-- top level FIREBEE_V1. +-- Replaced several Altera lpm modules to achieve a manufacturer independant code. +-- However we have still some modules like memory or FIFOs which are required up to now. +-- Removed the VDR latch. +-- Removed the AMKBD filter. +-- Updated all Suska-Codes (ACIA, MFP, 5380, 1772, 2149) to the latest code base. +-- The sound module works now on the positive clock edge. +-- The multi function port works now on the positive clock edge. +-- Naming conventions: +-- Replaced the 'n' prefixes with 'n' postfixes to achieve consistent signal names. +-- Replaced the old ACP_xx signal names by FBEE_xx (ACP is the old working title). +-- Improvements (hopefully) +-- Fixed the VIDEO_RECONFIG strobe logic in the video control section. +-- Others: +-- Provided file headers to all Firebee relevant design units. +-- Provided a timequest constraint file. +-- Switched all code elements to English language. +-- Provided a complete new file structure for the project. +-- + +library work; +use work.firebee_pkg.all; + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + +entity firebee is + port( + RSTO_MCFn : in std_logic; + CLK_33M : in std_logic; + CLK_MAIN : in std_logic; + + CLK_24M576 : out std_logic; + CLK_25M : out std_logic; + CLK_DDR_OUT : out std_logic; + CLK_DDR_OUTn : out std_logic; + CLK_USB : out std_logic; + + FB_AD : inout std_logic_vector(31 downto 0); + FB_ALE : in std_logic; + FB_BURSTn : in std_logic; + FB_CSn : in std_logic_vector(3 downto 1); + FB_SIZE : in std_logic_vector(1 downto 0); + FB_OEn : in std_logic; + FB_WRn : in std_logic; + FB_TAn : out std_logic; + + DACK1n : in std_logic; + DREQ1n : out std_logic; + + MASTERn : in std_logic; -- Not used so far. + TOUT0n : in std_logic; -- Not used so far. + + LED_FPGA_OK : out std_logic; + RESERVED_1 : out std_logic; + + VA : out std_logic_vector(12 downto 0); + BA : out std_logic_vector(1 downto 0); + VWEn : out std_logic; + VCASn : out std_logic; + VRASn : out std_logic; + VCSn : out std_logic; + + CLK_PIXEL : out std_logic; + SYNCn : out std_logic; + VSYNC : out std_logic; + HSYNC : out std_logic; + BLANKn : out std_logic; + + VR : out std_logic_vector(7 downto 0); + VG : out std_logic_vector(7 downto 0); + VB : out std_logic_vector(7 downto 0); + + VDM : out std_logic_vector(3 downto 0); + + VD : inout std_logic_vector(31 downto 0); + VD_QS : out std_logic_vector(3 downto 0); + + PD_VGAn : out std_logic; + VCKE : out std_logic; + PIC_INT : in std_logic; + E0_INT : in std_logic; + DVI_INT : in std_logic; + PCI_INTAn : in std_logic; + PCI_INTBn : in std_logic; + PCI_INTCn : in std_logic; + PCI_INTDn : in std_logic; + + IRQn : out std_logic_vector(7 downto 2); + TIN0 : out std_logic; + + YM_QA : out std_logic; + YM_QB : out std_logic; + YM_QC : out std_logic; + + LP_D : inout std_logic_vector(7 downto 0); + LP_DIR : out std_logic; + + DSA_D : out std_logic; + LP_STR : out std_logic; + DTR : out std_logic; + RTS : out std_logic; + CTS : in std_logic; + RI : in std_logic; + DCD : in std_logic; + LP_BUSY : in std_logic; + RxD : in std_logic; + TxD : out std_logic; + MIDI_IN : in std_logic; + MIDI_OLR : out std_logic; + MIDI_TLR : out std_logic; + PIC_AMKB_RX : in std_logic; + AMKB_RX : in std_logic; + AMKB_TX : out std_logic; + DACK0n : in std_logic; -- Not used. + + SCSI_DRQn : in std_logic; + SCSI_MSGn : in std_logic; + SCSI_CDn : in std_logic; + SCSI_IOn : in std_logic; + SCSI_ACKn : out std_logic; + SCSI_ATNn : out std_logic; + SCSI_SELn : inout std_logic; + SCSI_BUSYn : inout std_logic; + SCSI_RSTn : inout std_logic; + SCSI_DIR : out std_logic; + SCSI_D : inout std_logic_vector(7 downto 0); + SCSI_PAR : inout std_logic; + + ACSI_DIR : out std_logic; + ACSI_D : inout std_logic_vector(7 downto 0); + ACSI_CSn : out std_logic; + ACSI_A1 : out std_logic; + ACSI_RESETn : out std_logic; + ACSI_ACKn : out std_logic; + ACSI_DRQn : in std_logic; + ACSI_INTn : in std_logic; + + FDD_DCHGn : in bit; + FDD_SDSELn : out std_logic; + FDD_HD_DD : in std_logic; + FDD_RDn : in std_logic; + FDD_TRACK00 : in std_logic; + FDD_INDEXn : in std_logic; + FDD_WPn : in std_logic; + FDD_MOT_ON : out std_logic; + FDD_WR_GATE : out std_logic; + FDD_WDn : out std_logic; + FDD_STEP : out std_logic; + FDD_STEP_DIR : out std_logic; + + ROM4n : out std_logic; + ROM3n : out std_logic; + + RP_UDSn : out std_logic; + RP_LDSn : out std_logic; + SD_CLK : out std_logic; + SD_D3 : inout std_logic; + SD_CMD_D1 : inout std_logic; + SD_D0 : in std_logic; + SD_D1 : in std_logic; + SD_D2 : in std_logic; + SD_CARD_DETECT : in std_logic; + SD_WP : in std_logic; + + CF_WP : in bit; + CF_CSn : out std_logic_vector(1 downto 0); + + DSP_IO : inout std_logic_vector(17 downto 0); + DSP_SRD : inout std_logic_vector(15 downto 0); + DSP_SRCSn : out std_logic; + DSP_SRBLEn : out std_logic; + DSP_SRBHEn : out std_logic; + DSP_SRWEn : out std_logic; + DSP_SROEn : out std_logic; + + IDE_INT : in std_logic; + IDE_RDY : in std_logic; + IDE_RES : out std_logic; + IDE_WRn : out std_logic; + IDE_RDn : out std_logic; + IDE_CSn : out std_logic_vector(1 downto 0) + ); +end entity firebee; + +architecture Structure of firebee is +component altpll1 + port( + inclk0 : in std_logic := '0'; + c0 : out std_logic ; + c1 : out std_logic ; + c2 : out std_logic ; + locked : out std_logic + ); +end component; + +component altpll2 + port( + inclk0 : in std_logic := '0'; + c0 : out std_logic ; + c1 : out std_logic ; + c2 : out std_logic ; + c3 : out std_logic ; + c4 : out std_logic + ); +end component; + +component altpll3 + port( + inclk0 : in std_logic := '0'; + c0 : out std_logic ; + c1 : out std_logic ; + c2 : out std_logic ; + c3 : out std_logic + ); +end component; + +component altpll4 + port( + areset : in std_logic := '0'; + configupdate : in std_logic := '0'; + inclk0 : in std_logic := '0'; + scanclk : in std_logic := '1'; + scanclkena : in std_logic := '0'; + scandata : in std_logic := '0'; + c0 : out std_logic ; + locked : out std_logic ; + scandataout : out std_logic ; + scandone : out std_logic + ); +end component; + +component altpll_reconfig1 + port( + busy : out std_logic; + clock : in std_logic; + counter_param : in std_logic_VECTOR (2 DOWNTO 0) := (OTHERS => '0'); + counter_type : in std_logic_VECTOR (3 DOWNTO 0) := (OTHERS => '0'); + data_in : in std_logic_VECTOR (8 DOWNTO 0) := (OTHERS => '0'); + data_out : out std_logic_VECTOR (8 DOWNTO 0); + pll_areset : out std_logic; + pll_areset_in : in std_logic := '0'; + pll_configupdate : out std_logic; + pll_scanclk : out std_logic; + pll_scanclkena : out std_logic; + pll_scandata : out std_logic; + pll_scandataout : in std_logic := '0'; + pll_scandone : in std_logic := '0'; + read_param : in std_logic := '0'; + reconfig : in std_logic := '0'; + reset : in std_logic; + write_param : in std_logic := '0' + ); + end component; + + signal ACIA_CS : std_logic; + signal ACIA_IRQn : std_logic; + signal ACSI_D_OUT : std_logic_vector(7 downto 0); + signal ACSI_D_EN : std_logic; + signal BLANK_In : std_logic; + signal BLITTER_ADR : std_logic_vector(31 downto 0); + signal BLITTER_DACK_SR : std_logic; + signal BLITTER_DOUT : std_logic_vector(127 downto 0); + signal BLITTER_ON : std_logic; + signal BLITTER_RUN : std_logic; + signal BLITTER_SIG : std_logic; + signal BLITTER_TA : std_logic; + signal BLITTER_WR : std_logic; + signal BYTE : std_logic; -- When Byte -> 1 + signal CA : std_logic_vector(2 downto 0); + signal CLK_2M0 : std_logic; + signal CLK_2M4576 : std_logic; + signal CLK_25M_I : std_logic; + signal CLK_48M : std_logic; + signal CLK_500K : std_logic; + signal CLK_DDR : std_logic_vector(3 downto 0); + signal CLK_FDC : std_logic; + signal CLK_PIXEL_I : std_logic; + signal CLK_VIDEO : std_logic; + signal DA_OUT_X : std_logic_vector(7 downto 0); + signal DATA_EN_BLITTER : std_logic; + signal DATA_EN_H_DDR_CTRL : std_logic; + signal DATA_EN_L_DDR_CTRL : std_logic; + signal DATA_IN_FDC_SCSI : std_logic_vector(7 downto 0); + signal DATA_OUT_ACIA_I : std_logic_vector(7 downto 0); + signal DATA_OUT_ACIA_II : std_logic_vector(7 downto 0); + signal DATA_OUT_BLITTER : std_logic_vector(31 downto 0); + signal DATA_OUT_DDR_CTRL : std_logic_vector(31 downto 16); + signal DATA_OUT_FDC : std_logic_vector(7 downto 0); + signal DATA_OUT_MFP : std_logic_vector(7 downto 0); + signal DATA_OUT_SCSI : std_logic_vector(7 downto 0); + signal DINTn : std_logic; + signal DDR_D_IN_N : std_logic_vector(31 downto 0); + signal DDR_FB : std_logic_vector(4 downto 0); + signal DDR_SYNC_66M : std_logic; + signal DDR_WR : std_logic; + signal DDRWR_D_SEL : std_logic_vector(1 downto 0); + signal DMA_CS : std_logic; + signal DRQ11_DMA : std_logic; + signal DRQ_FDC : std_logic; + signal DRQ_DMA : std_logic; + signal DSP_INT : std_logic; + signal DSP_IO_EN : std_logic; + signal DSP_IO_OUT : std_logic_vector(17 downto 0); + signal DSP_SRD_EN : std_logic; + signal DSP_SRD_OUT : std_logic_vector(15 downto 0); + signal DSP_TA : std_logic; + signal DTACK_OUT_MFPn : std_logic; + signal FALCON_IO_TA : std_logic; + signal FB_AD_EN_15_0_VIDEO : std_logic; + signal FB_AD_EN_31_16_VIDEO : std_logic; + signal FB_AD_EN_7_0_DMA : std_logic; + signal FB_AD_EN_7_0_IH : std_logic; + signal FB_AD_EN_15_8_DMA : std_logic; + signal FB_AD_EN_15_8_IH : std_logic; + signal FB_AD_EN_23_16_DMA : std_logic; + signal FB_AD_EN_23_16_IH : std_logic; + signal FB_AD_EN_31_24_DMA : std_logic; + signal FB_AD_EN_31_24_IH : std_logic; + signal FB_AD_EN_DSP : std_logic; + signal FB_AD_EN_RTC : std_logic; + signal FB_AD_OUT_DMA : std_logic_vector(31 downto 0); + signal FB_AD_OUT_DSP : std_logic_vector(31 downto 0); + signal FB_AD_OUT_IH : std_logic_vector(31 downto 0); + signal FB_AD_OUT_RTC : std_logic_vector(7 downto 0); + signal FB_AD_OUT_VIDEO : std_logic_vector(31 downto 0); + signal FB_ADR : std_logic_vector(31 downto 0); + signal FB_B0 : std_logic; -- UPPER Byte BEI 16 BIT BUS + signal FB_B1 : std_logic; -- LOWER Byte BEI 16 BIT BUS + signal FB_DDR : std_logic_vector(127 downto 0); + signal FB_LE : std_logic_vector(3 downto 0); + signal FB_VDOE : std_logic_vector(3 downto 0); + signal FBEE_CONF : std_logic_vector(31 downto 0); + signal FD_INT : std_logic; + signal FDC_CSn : std_logic; + signal FDC_WRn : std_logic; + signal FIFO_CLR : std_logic; + signal FIFO_MW : std_logic_vector(8 downto 0); + signal HD_DD_OUT : std_logic; + signal HSYNC_I : std_logic; + signal IDE_CF_TA : std_logic; + signal IDE_RES_I : std_logic; + signal INT_HANDLER_TA : std_logic; + signal IRQ_KEYBDn : std_logic; + signal IRQ_MIDIn : std_logic; + signal KEYB_RxD : std_logic; + signal LDS : std_logic; + signal LOCKED : std_logic; + signal LP_D_X : std_logic_vector(7 downto 0); + signal LP_DIR_X : std_logic; + signal MFP_CS : std_logic; + signal MFP_INTACK : std_logic; + signal MFP_INTn : std_logic; + signal MIDI_OUT : std_logic; + signal PADDLE_CS : std_logic; + signal PLL_ARESET : std_logic; + signal PLL_SCANCLK : std_logic; + signal PLL_SCANDATA : std_logic; + signal PLL_SCANCLKENA : std_logic; + signal PLL_CONFIGUPDATE : std_logic; + signal PLL_SCANDONE : std_logic; + signal PLL_SCANDATAOUT : std_logic; + signal RESETn : std_logic; + signal SCSI_BSY_EN : std_logic; + signal SCSI_BSY_OUTn : std_logic; + signal SCSI_CS : std_logic; + signal SCSI_CSn : std_logic; + signal SCSI_D_EN : std_logic; + signal SCSI_DACKn : std_logic; + signal SCSI_DBP_EN : std_logic; + signal SCSI_DBP_OUTn : std_logic; + signal SCSI_DRQ : std_logic; + signal SCSI_INT : std_logic; + signal SCSI_D_OUTn : std_logic_vector(7 downto 0); + signal SCSI_RST_EN : std_logic; + signal SCSI_RST_OUTn : std_logic; + signal SCSI_SEL_EN : std_logic; + signal SCSI_SEL_OUTn : std_logic; + signal SD_CD_D3_EN : std_logic; + signal SD_CD_D3_OUT : std_logic; + signal SD_CMD_D1_EN : std_logic; + signal SD_CMD_D1_OUT : std_logic; + signal SNDCS : std_logic; + signal SNDCS_I : std_logic; + signal SNDIR_I : std_logic; + signal SR_DDR_FB : std_logic; + signal SR_DDR_WR : std_logic; + signal SR_DDRWR_D_SEL : std_logic; + signal SR_FIFO_WRE : std_logic; + signal SR_VDMP : std_logic_vector(7 downto 0); + signal TDO : std_logic; + signal TIMEBASE : std_logic_vector(17 downto 0); + signal VD_EN : std_logic; + signal VD_EN_I : std_logic; + signal VD_OUT : std_logic_vector(31 downto 0); + signal VD_QS_EN : std_logic; + signal VD_QS_OUT : std_logic_vector(3 downto 0); + signal VD_VZ : std_logic_vector(127 downto 0); + signal VDM_SEL : std_logic_vector(3 downto 0); + signal VDP_IN : std_logic_vector(63 downto 0); + signal VDP_OUT : std_logic_vector(63 downto 0); + signal VDP_Q1 : std_logic_vector(31 downto 0); + signal VDP_Q2 : std_logic_vector(31 downto 0); + signal VDP_Q3 : std_logic_vector(31 downto 0); + signal VDR : std_logic_vector(31 downto 0); + signal VIDEO_DDR_TA : std_logic; + signal VIDEO_MOD_TA : std_logic; + signal VIDEO_RAM_CTR : std_logic_vector(15 downto 0); + signal VIDEO_RECONFIG : std_logic; + signal VR_BUSY : std_logic; + signal VR_D : std_logic_vector(8 downto 0); + signal VR_RD : std_logic; + signal VR_WR : std_logic; + signal VSYNC_I : std_logic; + signal WDC_BSL0 : std_logic; + +begin + I_PLL1: altpll1 + port map( + inclk0 => CLK_MAIN, + c0 => CLK_2M4576, + c1 => CLK_24M576, + c2 => CLK_48M, + locked => LOCKED + ); + + I_PLL2: altpll2 + port map( + inclk0 => CLK_MAIN, + c0 => CLK_DDR(0), + c1 => CLK_DDR(1), + c2 => CLK_DDR(2), + c3 => CLK_DDR(3), + c4 => DDR_SYNC_66M + ); + + I_PLL3: altpll3 + port map( + inclk0 => CLK_MAIN, + c0 => CLK_2M0, + c1 => CLK_FDC, + c2 => CLK_25M_I, + c3 => CLK_500K + ); + + I_PLL4: altpll4 + port map( + inclk0 => CLK_MAIN, + areset => PLL_ARESET, + scanclk => PLL_SCANCLK, + scandata => PLL_SCANDATA, + scanclkena => PLL_SCANCLKENA, + configupdate => PLL_CONFIGUPDATE, + c0 => CLK_VIDEO, + scandataout => PLL_SCANDATAOUT, + scandone => PLL_SCANDONE + --locked => -- Not used. + ); + + I_RECONFIG: altpll_reconfig1 + port map( + reconfig => VIDEO_RECONFIG, + read_param => VR_RD, + write_param => VR_WR, + data_in => FB_ADR(24 downto 16), + counter_type => FB_ADR(5 downto 2), + counter_param => FB_ADR(8 downto 6), + pll_scandataout => PLL_SCANDATAOUT, + pll_scandone => PLL_SCANDONE, + clock => CLK_MAIN, + reset => not RESETn, + pll_areset_in => '0', -- Not used. + busy => VR_BUSY, + data_out => VR_D, + pll_scandata => PLL_SCANDATA, + pll_scanclk => PLL_SCANCLK, + pll_scanclkena => PLL_SCANCLKENA, + pll_configupdate => PLL_CONFIGUPDATE, + pll_areset => PLL_ARESET + ); + + CLK_25M <= CLK_25M_I; + CLK_USB <= CLK_48M; + CLK_DDR_OUT <= CLK_DDR(0); + CLK_DDR_OUTn <= not CLK_DDR(0); + CLK_PIXEL <= CLK_PIXEL_I; + + P_TIMEBASE: process + begin + wait until CLK_500K = '1' and CLK_500K' event; + TIMEBASE <= TIMEBASE + '1'; + end process P_TIMEBASE; + + RESETn <= RSTO_MCFn and LOCKED; + IDE_RES <= not IDE_RES_I and RESETn; + DREQ1n <= DACK1n; + LED_FPGA_OK <= TIMEBASE(17); + + FALCON_IO_TA <= ACIA_CS or SNDCS or not DTACK_OUT_MFPn or PADDLE_CS or IDE_CF_TA or DMA_CS; + FB_TAn <= '0' when (BLITTER_TA or VIDEO_DDR_TA or VIDEO_MOD_TA or FALCON_IO_TA or DSP_TA or INT_HANDLER_TA)= '1' else '1'; + + ACIA_CS <= '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 3) = x"1FF80" else '0'; -- FFC00-FFC07 FFC00/8 + MFP_CS <= '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 6) = x"3FE8" else '0'; -- FFA00/40 + PADDLE_CS <= '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 6) = x"3E48" else '0'; -- F9200-F923F + SNDCS <= '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 2) = x"3E200" else '0'; -- 8800-8803 F8800/4 + SNDCS_I <= '1' when SNDCS = '1' and FB_ADR (1) = '0' else '0'; + SNDIR_I <= '1' when SNDCS = '1' and FB_WRn = '0' else '0'; + + LP_D <= LP_D_X when LP_DIR_X = '0' else (others => 'Z'); + LP_DIR <= LP_DIR_X; + + ACSI_D <= ACSI_D_OUT when ACSI_D_EN = '1' else (others => 'Z'); + + SCSI_D <= SCSI_D_OUTn when SCSI_D_EN = '1' else (others => 'Z'); + SCSI_DIR <= '0' when SCSI_D_EN = '1' else '1'; + SCSI_PAR <= SCSI_DBP_OUTn when SCSI_DBP_EN = '1' else 'Z'; + SCSI_RSTn <= SCSI_RST_OUTn when SCSI_RST_EN = '1' else 'Z'; + SCSI_BUSYn <= SCSI_BSY_OUTn when SCSI_BSY_EN = '1' else 'Z'; + SCSI_SELn <= SCSI_SEL_OUTn when SCSI_SEL_EN = '1' else 'Z'; + + KEYB_RxD <= '0' when AMKB_RX = '0' or PIC_AMKB_RX = '0' else '1'; -- TASTATUR DATEN VOM PIC(PS2) OR NORMAL // + + SD_D3 <= SD_CD_D3_OUT when SD_CD_D3_EN = '1' else 'Z'; + SD_CMD_D1 <= SD_CMD_D1_OUT when SD_CMD_D1_EN = '1' else 'Z'; + + DSP_IO <= DSP_IO_OUT when DSP_IO_EN = '1' else (others => 'Z'); + DSP_SRD <= DSP_SRD_OUT when DSP_SRD_EN = '1' else (others => 'Z'); + + HD_DD_OUT <= FDD_HD_DD when FBEE_CONF(29) = '0' else WDC_BSL0; + LDS <= '1' when MFP_CS = '1' or MFP_INTACK = '1' else '0'; + ACIA_IRQn <= IRQ_KEYBDn and IRQ_MIDIn; + MFP_INTACK <= '1' when FB_CSn(2) = '0' and FB_ADR(26 downto 0) = x"20000" else '0'; --F002'0000 + DINTn <= '0' when IDE_INT = '1' and FBEE_CONF(28) = '1' else + '0' when FD_INT = '1' else + '0' when SCSI_INT = '1' and FBEE_CONF(28) = '1' else '1'; + + MIDI_TLR <= MIDI_OUT; + MIDI_OLR <= MIDI_OUT; + + BYTE <= '1' when FB_SIZE(1) = '0' and FB_SIZE(0) = '1' else '0'; + FB_B0 <= '1' when FB_ADR(0) = '0' or BYTE = '0' else '0'; + FB_B1 <= '1' when FB_ADR(0) = '1' or BYTE = '0' else '0'; + + FB_AD(31 downto 24) <= DATA_OUT_BLITTER(31 downto 24) when DATA_EN_BLITTER = '1' else + VDP_Q1(31 downto 24) when FB_VDOE = x"2" else + VDP_Q2(31 downto 24) when FB_VDOE = x"4" else + VDP_Q3(31 downto 24) when FB_VDOE = x"8" else + FB_AD_OUT_VIDEO(31 downto 24) when FB_AD_EN_31_16_VIDEO = '1' else + FB_AD_OUT_DSP(31 downto 24) when FB_AD_EN_DSP = '1' else + FB_AD_OUT_IH(31 downto 24) when FB_AD_EN_31_24_IH = '1' else + FB_AD_OUT_DMA(31 downto 24) when FB_AD_EN_31_24_DMA = '1' else + VDR(31 downto 24) when FB_VDOE = x"1" else + DATA_OUT_DDR_CTRL(31 downto 24) when DATA_EN_H_DDR_CTRL = '1' else + DA_OUT_X when SNDCS_I = '1' and FB_OEn = '0' else + x"00" when MFP_INTACK = '1' and FB_OEn = '0' else + DATA_OUT_ACIA_I when ACIA_CS = '1' and FB_ADR(2) = '0' and FB_OEn = '0' else + DATA_OUT_ACIA_II when ACIA_CS = '1' and FB_ADR(2) = '1' and FB_OEn = '0' else + x"BF" when PADDLE_CS = '1' and FB_ADR(5 downto 1) = x"0" and FB_OEn = '0' else + x"FF" when PADDLE_CS = '1' and FB_ADR(5 downto 1) = x"1" and FB_OEn = '0' else + x"FF" when PADDLE_CS = '1' and FB_ADR(5 downto 1) = x"8" and FB_OEn = '0' else + x"FF" when PADDLE_CS = '1' and FB_ADR(5 downto 1) = x"9" and FB_OEn = '0' else + x"FF" when PADDLE_CS = '1' and FB_ADR(5 downto 1) = x"A" and FB_OEn = '0' else + x"FF" when PADDLE_CS = '1' and FB_ADR(5 downto 1) = x"B" and FB_OEn = '0' else + x"00" when PADDLE_CS = '1' and FB_ADR(5 downto 1) = x"10" and FB_OEn = '0' else + x"00" when PADDLE_CS = '1' and FB_ADR(5 downto 1) = x"11" and FB_OEn = '0' else (others => 'Z'); + + FB_AD(23 downto 16) <= DATA_OUT_BLITTER(23 downto 16) when DATA_EN_BLITTER = '1' else + VDP_Q1(23 downto 16) when FB_VDOE = x"2" else + VDP_Q2(23 downto 16) when FB_VDOE = x"4" else + VDP_Q3(23 downto 16) when FB_VDOE = x"8" else + FB_AD_OUT_VIDEO(23 downto 16) when FB_AD_EN_31_16_VIDEO = '1' else + FB_AD_OUT_DSP(23 downto 16) when FB_AD_EN_DSP = '1' else + FB_AD_OUT_IH(23 downto 16) when FB_AD_EN_23_16_IH = '1' else + FB_AD_OUT_DMA(23 downto 16) when FB_AD_EN_23_16_DMA = '1' else + VDR(23 downto 16) when FB_VDOE = x"1" else + DATA_OUT_DDR_CTRL(23 downto 16) when DATA_EN_L_DDR_CTRL = '1' else + DATA_OUT_MFP when MFP_CS = '1' and FB_OEn = '0' else + x"00" when MFP_INTACK = '1' and FB_OEn = '0' else + FB_AD_OUT_RTC when FB_AD_EN_RTC = '1' else + x"FF" when PADDLE_CS = '1' and FB_ADR(5 downto 1) = x"0" and FB_OEn = '0' else + x"FF" when PADDLE_CS = '1' and FB_ADR(5 downto 1) = x"1" and FB_OEn = '0' else + x"FF" when PADDLE_CS = '1' and FB_ADR(5 downto 1) = x"8" and FB_OEn = '0' else + x"FF" when PADDLE_CS = '1' and FB_ADR(5 downto 1) = x"9" and FB_OEn = '0' else + x"FF" when PADDLE_CS = '1' and FB_ADR(5 downto 1) = x"A" and FB_OEn = '0' else + x"FF" when PADDLE_CS = '1' and FB_ADR(5 downto 1) = x"B" and FB_OEn = '0' else + x"00" when PADDLE_CS = '1' and FB_ADR(5 downto 1) = x"10" and FB_OEn = '0' else + x"00" when PADDLE_CS = '1' and FB_ADR(5 downto 1) = x"11" and FB_OEn = '0' else (others => 'Z'); + + FB_AD(15 downto 8) <= DATA_OUT_BLITTER(15 downto 8) when DATA_EN_BLITTER = '1' else + VDP_Q1(15 downto 8) when FB_VDOE = x"2" else + VDP_Q2(15 downto 8) when FB_VDOE = x"4" else + VDP_Q3(15 downto 8) when FB_VDOE = x"8" else + FB_AD_OUT_VIDEO(15 downto 8) when FB_AD_EN_15_0_VIDEO = '1' else + FB_AD_OUT_DSP(15 downto 8) when FB_AD_EN_DSP = '1' else + FB_AD_OUT_IH(15 downto 8) when FB_AD_EN_15_8_IH = '1' else + FB_AD_OUT_DMA(15 downto 8) when FB_AD_EN_15_8_DMA = '1' else + VDR(15 downto 8) when FB_VDOE = x"1" else + "000000" & DATA_OUT_MFP(7 downto 6) when MFP_INTACK = '1' and FB_OEn = '0' else (others => 'Z'); + + FB_AD(7 downto 0) <= DATA_OUT_BLITTER(7 downto 0) when DATA_EN_BLITTER = '1' else + VDP_Q1(7 downto 0) when FB_VDOE = x"2" else + VDP_Q2(7 downto 0) when FB_VDOE = x"4" else + VDP_Q3(7 downto 0) when FB_VDOE = x"8" else + FB_AD_OUT_VIDEO(7 downto 0) when FB_AD_EN_15_0_VIDEO = '1' else + FB_AD_OUT_DSP(7 downto 0) when FB_AD_EN_DSP = '1' else + FB_AD_OUT_IH(7 downto 0) when FB_AD_EN_7_0_IH = '1' else + FB_AD_OUT_DMA(7 downto 0) when FB_AD_EN_7_0_DMA = '1' else + VDR(7 downto 0) when FB_VDOE = x"1" else + DATA_OUT_MFP(5 downto 0) & "00" when MFP_INTACK = '1' and FB_OEn = '0' else (others => 'Z'); + + SYNCHRONIZATION: process + begin + wait until DDR_SYNC_66M = '1' and DDR_SYNC_66M' event; + if FB_ALE = '1' then + FB_ADR <= FB_AD; + end if; + -- + if VD_EN_I = '0' then + VDR <= VD; + else + VDR <= VD_OUT; + end if; + -- + if FB_LE(0) = '1' then + FB_DDR(127 downto 96) <= FB_AD; + end if; + -- + if FB_LE(1) = '1' then + FB_DDR(95 downto 64) <= FB_AD; + end if; + -- + if FB_LE(2) = '1' then + FB_DDR(63 downto 32) <= FB_AD; + end if; + -- + if FB_LE(3) = '1' then + FB_DDR(31 downto 0) <= FB_AD; + end if; + end process SYNCHRONIZATION; + + VIDEO_OUT: process + begin + wait until CLK_PIXEL_I = '1' and CLK_PIXEL_I' event; + VSYNC <= VSYNC_I; + HSYNC <= HSYNC_I; + BLANKn <= BLANK_In; + end process VIDEO_OUT; + + P_DDR_WR: process + begin + wait until CLK_DDR(3) = '1' and CLK_DDR(3)' event; + DDR_WR <= SR_DDR_WR; + DDRWR_D_SEL(0) <= SR_DDRWR_D_SEL; + end process P_DDR_WR; + + VD_QS_EN <= DDR_WR; + VD <= VD_OUT when VD_EN = '1' else (others => 'Z'); + + VD_QS_OUT(0) <= CLK_DDR(0); + VD_QS_OUT(1) <= CLK_DDR(0); + VD_QS_OUT(2) <= CLK_DDR(0); + VD_QS_OUT(3) <= CLK_DDR(0); + VD_QS <= VD_QS_OUT when VD_QS_EN = '1' else (others => 'Z'); + + DDR_DATA_IN_N: process + begin + wait until CLK_DDR(1) = '0' and CLK_DDR(1)' event; + DDR_D_IN_N <= VD; + end process DDR_DATA_IN_N; + -- + DDR_DATA_IN_P: process + begin + wait until CLK_DDR(1) = '1' and CLK_DDR(1)' event; + VDP_IN(31 downto 0) <= VD; + VDP_IN(63 downto 32) <= DDR_D_IN_N; + end process DDR_DATA_IN_P; + + DDR_DATA_OUT_P: process(CLK_DDR(3)) + variable DDR_D_OUT_H : std_logic_vector(31 downto 0); + variable DDR_D_OUT_L : std_logic_vector(31 downto 0); + begin + if CLK_DDR(3) = '1' and CLK_DDR(3)' event then + DDR_D_OUT_H := VDP_OUT(63 downto 32); + DDR_D_OUT_L := VDP_OUT(31 downto 0); + VD_EN <= SR_DDR_WR or DDR_WR; + end if; + -- + case CLK_DDR(3) is + when '1' => VD_OUT <= DDR_D_OUT_H; + when others => VD_OUT <= DDR_D_OUT_L; + end case; + end process DDR_DATA_OUT_P; + + with DDRWR_D_SEL select + VDP_OUT <= BLITTER_DOUT(63 downto 0) when "11", + BLITTER_DOUT(127 downto 64) when "10", + FB_DDR(63 downto 0) when "01", + FB_DDR(127 downto 64) when "00"; + + VD_EN_I <= SR_DDR_WR or DDR_WR; + + VDP_Q_BUFFER: process + begin + wait until CLK_DDR(0) = '1' and CLK_DDR(0)' event; + DDR_FB <= SR_DDR_FB & DDR_FB(4 downto 1); + -- + if DDR_FB(1) = '1' then + VDP_Q1 <= VDP_IN(31 downto 0); + end if; + -- + if DDR_FB(0) = '1' then + VDP_Q2 <= VDP_IN(63 downto 32); + VDP_Q3 <= VDP_IN(31 downto 0); + end if; + end process VDP_Q_BUFFER; + + I_DDR_CTRL: DDR_CTRL_V1 + port map( + CLK_MAIN => CLK_MAIN, + DDR_SYNC_66M => DDR_SYNC_66M, + FB_ADR => FB_ADR, + FB_CS1n => FB_CSn(1), + FB_OEn => FB_OEn, + FB_SIZE0 => FB_SIZE(0), + FB_SIZE1 => FB_SIZE(1), + FB_ALE => FB_ALE, + FB_WRn => FB_WRn, + BLITTER_ADR => BLITTER_ADR, + BLITTER_SIG => BLITTER_SIG, + BLITTER_WR => BLITTER_WR, + SR_BLITTER_DACK => BLITTER_DACK_SR, + BA => BA, + VA => VA, + FB_LE => FB_LE, + CLK_33M => CLK_33M, + VRASn => VRASn, + VCASn => VCASn, + VWEn => VWEn, + VCSn => VCSn, + FIFO_CLR => FIFO_CLR, + DDRCLK0 => CLK_DDR(0), + VIDEO_RAM_CTR => VIDEO_RAM_CTR, + VCKE => VCKE, + DATA_IN => FB_AD, + DATA_OUT => DATA_OUT_DDR_CTRL, + DATA_EN_H => DATA_EN_H_DDR_CTRL, + DATA_EN_L => DATA_EN_L_DDR_CTRL, + VDM_SEL => VDM_SEL, + FIFO_MW => FIFO_MW, + FB_VDOE => FB_VDOE, + SR_FIFO_WRE => SR_FIFO_WRE, + SR_DDR_FB => SR_DDR_FB, + SR_DDR_WR => SR_DDR_WR, + SR_DDRWR_D_SEL => SR_DDRWR_D_SEL, + SR_VDMP => SR_VDMP, + VIDEO_DDR_TA => VIDEO_DDR_TA, + DDRWR_D_SEL1 => DDRWR_D_SEL(1) + ); + + I_BLITTER: FBEE_BLITTER + port map( + RESETn => RESETn, + CLK_MAIN => CLK_MAIN, + CLK_DDR0 => CLK_DDR(0), + FB_ADR => FB_ADR, + FB_ALE => FB_ALE, + FB_SIZE1 => FB_SIZE(1), + FB_SIZE0 => FB_SIZE(0), + FB_CSn => FB_CSn, + FB_OEn => FB_OEn, + FB_WRn => FB_WRn, + DATA_IN => FB_AD, + DATA_OUT => DATA_OUT_BLITTER, + DATA_EN => DATA_EN_BLITTER, + BLITTER_ADR => BLITTER_ADR, + BLITTER_SIG => BLITTER_SIG, + BLITTER_WR => BLITTER_WR, + BLITTER_ON => BLITTER_ON, + BLITTER_RUN => BLITTER_RUN, + BLITTER_DIN => VD_VZ, + BLITTER_DOUT => BLITTER_DOUT, + BLITTER_TA => BLITTER_TA, + BLITTER_DACK_SR => BLITTER_DACK_SR + ); + + I_VIDEOSYSTEM: VIDEO_SYSTEM + port map( + CLK_MAIN => CLK_MAIN, + CLK_33M => CLK_33M, + CLK_25M => CLK_25M_I, + CLK_VIDEO => CLK_VIDEO, + CLK_DDR3 => CLK_DDR(3), + CLK_DDR2 => CLK_DDR(2), + CLK_DDR0 => CLK_DDR(0), + CLK_PIXEL => CLK_PIXEL_I, + + VR_D => VR_D, + VR_BUSY => VR_BUSY, + + FB_ADR => FB_ADR, + FB_AD_IN => FB_AD, + FB_AD_OUT => FB_AD_OUT_VIDEO, + FB_AD_EN_31_16 => FB_AD_EN_31_16_VIDEO, + FB_AD_EN_15_0 => FB_AD_EN_15_0_VIDEO, + FB_ALE => FB_ALE, + FB_CSn => FB_CSn, + FB_OEn => FB_OEn, + FB_WRn => FB_WRn, + FB_SIZE1 => FB_SIZE(1), + FB_SIZE0 => FB_SIZE(0), + + VDP_IN => VDP_IN, + + VR_RD => VR_RD, + VR_WR => VR_WR, + VIDEO_RECONFIG => VIDEO_RECONFIG, + + RED => VR, + GREEN => VG, + BLUE => VB, + VSYNC => VSYNC_I, + HSYNC => HSYNC_I, + SYNCn => SYNCn, + BLANKn => BLANK_In, + + PD_VGAn => PD_VGAn, + VIDEO_MOD_TA => VIDEO_MOD_TA, + + VD_VZ => VD_VZ, + SR_FIFO_WRE => SR_FIFO_WRE, + SR_VDMP => SR_VDMP, + FIFO_MW => FIFO_MW, + VDM_SEL => VDM_SEL, + VIDEO_RAM_CTR => VIDEO_RAM_CTR, + FIFO_CLR => FIFO_CLR, + VDM => VDM, + BLITTER_ON => BLITTER_ON, + BLITTER_RUN => BLITTER_RUN + ); + + I_INTHANDLER: INTHANDLER + port map( + CLK_MAIN => CLK_MAIN, + RESETn => RESETn, + FB_ADR => FB_ADR, + FB_CSn => FB_CSn(2 downto 1), + FB_OEn => FB_OEn, + FB_SIZE0 => FB_SIZE(0), + FB_SIZE1 => FB_SIZE(1), + FB_WRn => FB_WRn, + FB_AD_IN => FB_AD, + FB_AD_OUT => FB_AD_OUT_IH, + FB_AD_EN_31_24 => FB_AD_EN_31_24_IH, + FB_AD_EN_23_16 => FB_AD_EN_23_16_IH, + FB_AD_EN_15_8 => FB_AD_EN_15_8_IH, + FB_AD_EN_7_0 => FB_AD_EN_7_0_IH, + PIC_INT => PIC_INT, + E0_INT => E0_INT, + DVI_INT => DVI_INT, + PCI_INTAn => PCI_INTAn, + PCI_INTBn => PCI_INTBn, + PCI_INTCn => PCI_INTCn, + PCI_INTDn => PCI_INTDn, + MFP_INTn => MFP_INTn, + DSP_INT => DSP_INT, + VSYNC => VSYNC_I, + HSYNC => HSYNC_I, + DRQ_DMA => DRQ_DMA, + IRQn => IRQn, + INT_HANDLER_TA => INT_HANDLER_TA, + FBEE_CONF => FBEE_CONF, + TIN0 => TIN0 + ); + + I_DMA: FBEE_DMA + port map( + RESET => not RESETn, + CLK_MAIN => CLK_MAIN, + CLK_FDC => CLK_FDC, + + FB_ADR => FB_ADR(26 downto 0), + FB_ALE => FB_ALE, + FB_SIZE => FB_SIZE, + FB_CSn => FB_CSn(2 downto 1), + FB_OEn => FB_OEn, + FB_WRn => FB_WRn, + FB_AD_IN => FB_AD, + FB_AD_OUT => FB_AD_OUT_DMA, + FB_AD_EN_31_24 => FB_AD_EN_31_24_DMA, + FB_AD_EN_23_16 => FB_AD_EN_23_16_DMA, + FB_AD_EN_15_8 => FB_AD_EN_15_8_DMA, + FB_AD_EN_7_0 => FB_AD_EN_7_0_DMA, + + ACSI_DIR => ACSI_DIR, + ACSI_D_IN => ACSI_D, + ACSI_D_OUT => ACSI_D_OUT, + ACSI_D_EN => ACSI_D_EN, + ACSI_CSn => ACSI_CSn, + ACSI_A1 => ACSI_A1, + ACSI_RESETn => ACSI_RESETn, + ACSI_DRQn => ACSI_DRQn, + ACSI_ACKn => ACSI_ACKn, + + DATA_IN_FDC => DATA_OUT_FDC, + DATA_IN_SCSI => DATA_OUT_SCSI, + DATA_OUT_FDC_SCSI => DATA_IN_FDC_SCSI, + + DMA_DRQ_IN => DRQ_FDC, + DMA_DRQ_OUT => DRQ_DMA, + DMA_DRQ11 => DRQ11_DMA, + + SCSI_DRQ => SCSI_DRQ, + SCSI_DACKn => SCSI_DACKn, + SCSI_INT => SCSI_INT, + SCSI_CSn => SCSI_CSn, + SCSI_CS => SCSI_CS, + + CA => CA, + FLOPPY_HD_DD => FDD_HD_DD, + WDC_BSL0 => WDC_BSL0, + FDC_CSn => FDC_CSn, + FDC_WRn => FDC_WRn, + FD_INT => FD_INT, + IDE_INT => IDE_INT, + DMA_CS => DMA_CS + ); + + I_IDE_CF_SD_ROM: IDE_CF_SD_ROM + port map( + RESET => not RESETn, + CLK_MAIN => CLK_MAIN, + + FB_ADR => FB_ADR(19 downto 5), + FB_CS1n => FB_CSn(1), + FB_WRn => FB_WRn, + FB_B0 => FB_B0, + FB_B1 => FB_B1, + + FBEE_CONF => FBEE_CONF(31 downto 30), + + RP_UDSn => RP_UDSn, + RP_LDSn => RP_LDSn, + + SD_CLK => SD_CLK, + SD_D0 => SD_D0, + SD_D1 => SD_D1, + SD_D2 => SD_D2, + SD_CD_D3_IN => SD_D3, + SD_CD_D3_OUT => SD_CD_D3_OUT, + SD_CD_D3_EN => SD_CD_D3_EN, + SD_CMD_D1_IN => SD_CMD_D1, + SD_CMD_D1_OUT => SD_CMD_D1_OUT, + SD_CMD_D1_EN => SD_CMD_D1_EN, + SD_CARD_DETECT => SD_CARD_DETECT, + SD_WP => SD_WP, + + IDE_RDY => IDE_RDY, + IDE_WRn => IDE_WRn, + IDE_RDn => IDE_RDn, + IDE_CSn => IDE_CSn, + -- IDE_DRQn =>, -- Not used. + IDE_CF_TA => IDE_CF_TA, + + ROM4n => ROM4n, + ROM3n => ROM3n, + + CF_WP => CF_WP, + CF_CSn => CF_CSn + ); + + I_DSP: DSP + port map( + CLK_33M => CLK_33M, + CLK_MAIN => CLK_MAIN, + FB_OEn => FB_OEn, + FB_WRn => FB_WRn, + FB_CS1n => FB_CSn(1), + FB_CS2n => FB_CSn(2), + FB_SIZE0 => FB_SIZE(0), + FB_SIZE1 => FB_SIZE(1), + FB_BURSTn => FB_BURSTn, + FB_ADR => FB_ADR, + RESETn => RESETn, + FB_CS3n => FB_CSn(3), + SRCSn => DSP_SRCSn, + SRBLEn => DSP_SRBLEn, + SRBHEn => DSP_SRBHEn, + SRWEn => DSP_SRWEn, + SROEn => DSP_SROEn, + DSP_INT => DSP_INT, + DSP_TA => DSP_TA, + FB_AD_IN => FB_AD, + FB_AD_OUT => FB_AD_OUT_DSP, + FB_AD_EN => FB_AD_EN_DSP, + IO_IN => DSP_IO, + IO_OUT => DSP_IO_OUT, + IO_EN => DSP_IO_EN, + SRD_IN => DSP_SRD, + SRD_OUT => DSP_SRD_OUT, + SRD_EN => DSP_SRD_EN + ); + + I_SOUND: WF2149IP_TOP_SOC + port map( + SYS_CLK => CLK_MAIN, + RESETn => RESETn, + + WAV_CLK => CLK_2M0, + SELn => '1', + + BDIR => SNDIR_I, + BC2 => '1', + BC1 => SNDCS_I, + + A9n => '0', + A8 => '1', + DA_IN => FB_AD(31 downto 24), + DA_OUT => DA_OUT_X, + + IO_A_IN => x"00", -- All port pins are dedicated outputs. + IO_A_OUT(7) => IDE_RES_I, + IO_A_OUT(6) => LP_DIR_X, + IO_A_OUT(5) => LP_STR, + IO_A_OUT(4) => DTR, + IO_A_OUT(3) => RTS, + IO_A_OUT(2) => RESERVED_1, + IO_A_OUT(1) => DSA_D, + IO_A_OUT(0) => FDD_SDSELn, + -- IO_A_EN => TOUT0n, -- Not required. + IO_B_IN => LP_D, + IO_B_OUT => LP_D_X, + -- IO_B_EN => -- Not used. + + OUT_A => YM_QA, + OUT_B => YM_QB, + OUT_C => YM_QC + ); + + I_MFP: WF68901IP_TOP_SOC + port map( + -- System control: + CLK => CLK_MAIN, + RESETn => RESETn, + -- Asynchronous bus control: + DSn => not LDS, + CSn => not MFP_CS, + RWn => FB_WRn, + DTACKn => DTACK_OUT_MFPn, + -- Data and Adresses: + RS => FB_ADR(5 downto 1), + DATA_IN => FB_AD(23 downto 16), + DATA_OUT => DATA_OUT_MFP, + -- DATA_EN => DATA_EN_MFP, -- Not used. + GPIP_IN(7) => not DRQ11_DMA, + GPIP_IN(6) => not RI, + GPIP_IN(5) => DINTn, + GPIP_IN(4) => ACIA_IRQn, + GPIP_IN(3) => DSP_INT, + GPIP_IN(2) => not CTS, + GPIP_IN(1) => not DCD, + GPIP_IN(0) => LP_BUSY, + -- GPIP_OUT =>, -- Not used; all GPIPs are direction input. + -- GPIP_EN =>, -- Not used; all GPIPs are direction input. + -- Interrupt control: + IACKn => not MFP_INTACK, + IEIn => '0', + -- IEOn =>, -- Not used. + IRQn => MFP_INTn, + -- Timers and timer control: + XTAL1 => CLK_2M4576, + TAI => '0', + TBI => BLANK_In, + -- TAO =>, + -- TBO =>, + -- TCO =>, + TDO => TDO, + -- Serial I/O control: + RC => TDO, + TC => TDO, + SI => RxD, + SO => TxD + -- SO_EN => -- Not used. + -- DMA control: + -- RRn => -- Not used. + -- TRn => -- Not used. + ); + + I_ACIA_MIDI: WF6850IP_TOP_SOC + port map( + CLK => CLK_MAIN, + RESETn => RESETn, + + CS2n => '0', + CS1 => FB_ADR(2), + CS0 => ACIA_CS, + E => ACIA_CS, + RWn => FB_WRN, + RS => FB_ADR(1), + + DATA_IN => FB_AD(31 downto 24), + DATA_OUT => DATA_OUT_ACIA_II, + -- DATA_EN => -- Not used. + + TXCLK => CLK_500K, + RXCLK => CLK_500K, + RXDATA => MIDI_IN, + CTSn => '0', + DCDn => '0', + + IRQn => IRQ_MIDIn, + TXDATA => MIDI_OUT + --RTSn => -- Not used. + ); + + I_ACIA_KEYBOARD: WF6850IP_TOP_SOC + port map( + CLK => CLK_MAIN, + RESETn => RESETn, + + CS2n => FB_ADR(2), + CS1 => '1', + CS0 => ACIA_CS, + E => ACIA_CS, + RWn => FB_WRn, + RS => FB_ADR(1), + + DATA_IN => FB_AD(31 downto 24), + DATA_OUT => DATA_OUT_ACIA_I, + -- DATA_EN => Not used. + + TXCLK => CLK_500K, + RXCLK => CLK_500K, + RXDATA => KEYB_RxD, + + CTSn => '0', + DCDn => '0', + + IRQn => IRQ_KEYBDn, + TXDATA => AMKB_TX + --RTSn => -- Not used. + ); + + I_SCSI: WF5380_TOP_SOC + port map( + CLK => CLK_FDC, + RESETn => RESETn, + ADR => CA, + DATA_IN => DATA_IN_FDC_SCSI, + DATA_OUT => DATA_OUT_SCSI, + --DATA_EN =>, + -- Bus and DMA controls: + CSn => SCSI_CSn, + RDn => not FDC_WRn or not SCSI_CS, + WRn => FDC_WRn or not SCSI_CS, + EOPn => '1', + DACKn => SCSI_DACKn, + DRQ => SCSI_DRQ, + INT => SCSI_INT, + -- READY =>, + -- SCSI bus: + DB_INn => SCSI_D, + DB_OUTn => SCSI_D_OUTn, + DB_EN => SCSI_D_EN, + DBP_INn => SCSI_PAR, + DBP_OUTn => SCSI_DBP_OUTn, + DBP_EN => SCSI_DBP_EN, -- wenn 1 dann output + RST_INn => SCSI_RSTn, + RST_OUTn => SCSI_RST_OUTn, + RST_EN => SCSI_RST_EN, + BSY_INn => SCSI_BUSYn, + BSY_OUTn => SCSI_BSY_OUTn, + BSY_EN => SCSI_BSY_EN, + SEL_INn => SCSI_SELn, + SEL_OUTn => SCSI_SEL_OUTn, + SEL_EN => SCSI_SEL_EN, + ACK_INn => '1', + ACK_OUTn => SCSI_ACKn, + -- ACK_EN => ACK_EN, + ATN_INn => '1', + ATN_OUTn => SCSI_ATNn, + -- ATN_EN => ATN_EN, + REQ_INn => SCSI_DRQn, + -- REQ_OUTn => REQ_OUTn, + -- REQ_EN => REQ_EN, + IOn_IN => SCSI_IOn, + -- IOn_OUT => IOn_OUT, + -- IO_EN => IO_EN, + CDn_IN => SCSI_CDn, + -- CDn_OUT => CDn_OUT, + -- CD_EN => CD_EN, + MSG_INn => SCSI_MSGn + -- MSG_OUTn => MSG_OUTn, + -- MSG_EN => MSG_EN + ); + + I_FDC: WF1772IP_TOP_SOC + port map( + CLK => CLK_FDC, + RESETn => RESETn, + CSn => FDC_CSn, + RWn => FDC_WRn, + A1 => CA(2), + A0 => CA(1), + DATA_IN => DATA_IN_FDC_SCSI, + DATA_OUT => DATA_OUT_FDC, + -- DATA_EN => CD_EN_FDC, + RDn => FDD_RDn, + TR00n => FDD_TRACK00, + IPn => FDD_INDEXn, + WPRTn => FDD_WPn, + DDEn => '0', -- Fixed to MFM. + HDTYPE => HD_DD_OUT, + MO => FDD_MOT_ON, + WG => FDD_WR_GATE, + WD => FDD_WDn, + STEP => FDD_STEP, + DIRC => FDD_STEP_DIR, + DRQ => DRQ_FDC, + INTRQ => FD_INT + ); + + I_RTC: RTC + port map( + CLK_MAIN => CLK_MAIN, + FB_ADR => FB_ADR(19 downto 0), + FB_CS1n => FB_CSn(1), + FB_SIZE0 => FB_SIZE(0), + FB_SIZE1 => FB_SIZE(1), + FB_WRn => FB_WRn, + FB_OEn => FB_OEn, + FB_AD_IN => FB_AD(23 downto 16), + FB_AD_OUT => FB_AD_OUT_RTC, + FB_AD_EN_23_16 => FB_AD_EN_RTC, + PIC_INT => PIC_INT + ); +end architecture; diff --git a/vhdl/rtl/vhdl/Firebee_V1/Firebee_V1_pkg.vhd b/vhdl/rtl/vhdl/Firebee_V1/Firebee_V1_pkg.vhd new file mode 100644 index 0000000..d9846c8 --- /dev/null +++ b/vhdl/rtl/vhdl/Firebee_V1/Firebee_V1_pkg.vhd @@ -0,0 +1,579 @@ +---------------------------------------------------------------------- +---- ---- +---- This file is part of the 'Firebee' project. ---- +---- http://acp.atari.org ---- +---- ---- +---- Description: ---- +---- This design unit provides the package of the 'Firebee' ---- +---- computer. It is optimized for the use of an Altera Cyclone ---- +---- FPGA (EP3C40F484). This IP-Core is based on the first edi- ---- +---- tion of the Firebee configware originally provided by Fredi ---- +---- Ashwanden and Wolfgang Förster. This release is in compa- ---- +---- rision to the first edition completely written in VHDL. ---- +---- ---- +---- Author(s): ---- +---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2012 Wolfgang Förster ---- +---- ---- +---- This source file 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 2 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, write to the Free ---- +---- Software Foundation, Inc., 51 Franklin Street, Fifth Floor, ---- +---- Boston, MA 02110-1301, USA. ---- +---- ---- +---------------------------------------------------------------------- +-- +-- Revision History +-- +-- Revision 2K12B 20120801 WF +-- Initial Release of the second edition. +library ieee; +use ieee.std_logic_1164.all; +package firebee_pkg is + component VIDEO_SYSTEM + port( + CLK_MAIN : in std_logic; + CLK_33M : in std_logic; + CLK_25M : in std_logic; + CLK_VIDEO : in std_logic; + CLK_DDR3 : in std_logic; + CLK_DDR2 : in std_logic; + CLK_DDR0 : in std_logic; + CLK_PIXEL : out std_logic; + + VR_D : in std_logic_vector(8 downto 0); + VR_BUSY : in std_logic; + + FB_ADR : in std_logic_vector(31 downto 0); + FB_AD_IN : in std_logic_vector(31 downto 0); + FB_AD_OUT : out std_logic_vector(31 downto 0); + FB_AD_EN_31_16 : out std_logic; -- Hi word. + FB_AD_EN_15_0 : out std_logic; -- Low word. + FB_ALE : in std_logic; + FB_CSn : in std_logic_vector(3 downto 1); + FB_OEn : in std_logic; + FB_WRn : in std_logic; + FB_SIZE1 : in std_logic; + FB_SIZE0 : in std_logic; + + VDP_IN : in std_logic_vector(63 downto 0); + + VR_RD : out std_logic; + VR_WR : out std_logic; + VIDEO_RECONFIG : out std_logic; + + RED : out std_logic_vector(7 downto 0); + GREEN : out std_logic_vector(7 downto 0); + BLUE : out std_logic_vector(7 downto 0); + VSYNC : out std_logic; + HSYNC : out std_logic; + SYNCn : out std_logic; + BLANKn : out std_logic; + + PD_VGAn : out std_logic; + VIDEO_MOD_TA : out std_logic; + + VD_VZ : out std_logic_vector(127 downto 0); + SR_FIFO_WRE : in std_logic; + SR_VDMP : in std_logic_vector(7 downto 0); + FIFO_MW : out std_logic_vector(8 downto 0); + VDM_SEL : in std_logic_vector(3 downto 0); + VIDEO_RAM_CTR : out std_logic_vector(15 downto 0); + FIFO_CLR : out std_logic; + + VDM : out std_logic_vector(3 downto 0); + + BLITTER_RUN : in std_logic; + BLITTER_ON : out std_logic + ); + end component; + + component VIDEO_CTRL + port( + CLK_MAIN : in std_logic; + FB_CSn : in std_logic_vector(2 downto 1); + FB_WRn : in std_logic; + FB_OEn : in std_logic; + FB_SIZE : in std_logic_vector(1 downto 0); + FB_ADR : in std_logic_vector(31 downto 0); + CLK33M : in std_logic; + CLK25M : in std_logic; + BLITTER_RUN : in std_logic; + CLK_VIDEO : in std_logic; + VR_D : in std_logic_vector(8 downto 0); + VR_BUSY : in std_logic; + COLOR8 : out std_logic; + FBEE_CLUT_RD : out std_logic; + COLOR1 : out std_logic; + FALCON_CLUT_RDH : out std_logic; + FALCON_CLUT_RDL : out std_logic; + FALCON_CLUT_WR : out std_logic_vector(3 downto 0); + CLUT_ST_RD : out std_logic; + CLUT_ST_WR : out std_logic_vector(1 downto 0); + CLUT_MUX_ADR : out std_logic_vector(3 downto 0); + HSYNC : out std_logic; + VSYNC : out std_logic; + BLANKn : out std_logic; + SYNCn : out std_logic; + PD_VGAn : out std_logic; + FIFO_RDE : out std_logic; + COLOR2 : out std_logic; + COLOR4 : out std_logic; + CLK_PIXEL : out std_logic; + CLUT_OFF : out std_logic_vector(3 downto 0); + BLITTER_ON : out std_logic; + VIDEO_RAM_CTR : out std_logic_vector(15 downto 0); + VIDEO_MOD_TA : out std_logic; + CCR : out std_logic_vector(23 downto 0); + CCSEL : out std_logic_vector(2 downto 0); + FBEE_CLUT_WR : out std_logic_vector(3 downto 0); + INTER_ZEI : out std_logic; + DOP_FIFO_CLR : out std_logic; + VIDEO_RECONFIG : out std_logic; + VR_WR : out std_logic; + VR_RD : out std_logic; + FIFO_CLR : out std_logic; + DATA_IN : in std_logic_vector(31 downto 0); + DATA_OUT : out std_logic_vector(31 downto 0); + DATA_EN_H : out std_logic; + DATA_EN_L : out std_logic + ); + end component; + + component DDR_CTRL_V1 is + port( + CLK_MAIN : in std_logic; + DDR_SYNC_66M : in std_logic; + FB_ADR : in std_logic_vector(31 downto 0); + FB_CS1n : in std_logic; + FB_OEn : in std_logic; + FB_SIZE0 : in std_logic; + FB_SIZE1 : in std_logic; + FB_ALE : in std_logic; + FB_WRn : in std_logic; + FIFO_CLR : in std_logic; + VIDEO_RAM_CTR : in std_logic_vector(15 downto 0); + BLITTER_ADR : in std_logic_vector(31 downto 0); + BLITTER_SIG : in std_logic; + BLITTER_WR : in std_logic; + DDRCLK0 : in std_logic; + CLK_33M : in std_logic; + FIFO_MW : in std_logic_vector(8 downto 0); + VA : out std_logic_vector(12 downto 0); + VWEn : out std_logic; + VRASn : out std_logic; + VCSn : out std_logic; + VCKE : out std_logic; + VCASn : out std_logic; + FB_LE : out std_logic_vector(3 downto 0); + FB_VDOE : out std_logic_vector(3 downto 0); + SR_FIFO_WRE : out std_logic; + SR_DDR_FB : out std_logic; + SR_DDR_WR : out std_logic; + SR_DDRWR_D_SEL : out std_logic; + SR_VDMP : out std_logic_vector(7 downto 0); + VIDEO_DDR_TA : out std_logic; + SR_BLITTER_DACK : out std_logic; + BA : out std_logic_vector(1 downto 0); + DDRWR_D_SEL1 : out std_logic; + VDM_SEL : out std_logic_vector(3 downto 0); + DATA_IN : in std_logic_vector(31 downto 0); + DATA_OUT : out std_logic_vector(31 downto 16); + DATA_EN_H : out std_logic; + DATA_EN_L : out std_logic + ); + end component; + + component INTHANDLER + port( + CLK_MAIN : in std_logic; + RESETn : in std_logic; + FB_ADR : in std_logic_vector(31 downto 0); + FB_CSn : in std_logic_vector(2 downto 1); + FB_SIZE0 : in std_logic; + FB_SIZE1 : in std_logic; + FB_WRn : in std_logic; + FB_OEn : in std_logic; + FB_AD_IN : in std_logic_vector(31 downto 0); + FB_AD_OUT : out std_logic_vector(31 downto 0); + FB_AD_EN_31_24 : out std_logic; + FB_AD_EN_23_16 : out std_logic; + FB_AD_EN_15_8 : out std_logic; + FB_AD_EN_7_0 : out std_logic; + PIC_INT : in std_logic; + E0_INT : in std_logic; + DVI_INT : in std_logic; + PCI_INTAn : in std_logic; + PCI_INTBn : in std_logic; + PCI_INTCn : in std_logic; + PCI_INTDn : in std_logic; + MFP_INTn : in std_logic; + DSP_INT : in std_logic; + VSYNC : in std_logic; + HSYNC : in std_logic; + DRQ_DMA : in std_logic; + IRQn : out std_logic_vector(7 downto 2); + INT_HANDLER_TA : out std_logic; + FBEE_CONF : out std_logic_vector(31 downto 0); + TIN0 : out std_logic + ); + end component; + + component FBEE_DMA is + port( + RESET : in std_logic; + CLK_MAIN : in std_logic; + CLK_FDC : in std_logic; + + FB_ADR : in std_logic_vector(26 downto 0); + FB_ALE : in std_logic; + FB_SIZE : in std_logic_vector(1 downto 0); + FB_CSn : in std_logic_vector(2 downto 1); + FB_OEn : in std_logic; + FB_WRn : in std_logic; + FB_AD_IN : in std_logic_vector(31 downto 0); + FB_AD_OUT : out std_logic_vector(31 downto 0); + FB_AD_EN_31_24 : out std_logic; + FB_AD_EN_23_16 : out std_logic; + FB_AD_EN_15_8 : out std_logic; + FB_AD_EN_7_0 : out std_logic; + + ACSI_DIR : out std_logic; + ACSI_D_IN : in std_logic_vector(7 downto 0); + ACSI_D_OUT : out std_logic_vector(7 downto 0); + ACSI_D_EN : out std_logic; + ACSI_CSn : out std_logic; + ACSI_A1 : out std_logic; + ACSI_RESETn : out std_logic; + ACSI_DRQn : in std_logic; + ACSI_ACKn : out std_logic; + + DATA_IN_FDC : in std_logic_vector(7 downto 0); + DATA_IN_SCSI : in std_logic_vector(7 downto 0); + DATA_OUT_FDC_SCSI : out std_logic_vector(7 downto 0); + + DMA_DRQ_IN : in std_logic; -- From 1772. + DMA_DRQ_OUT : out std_logic; -- To Interrupt handler. + DMA_DRQ11 : out std_logic; + + SCSI_DRQ : in std_logic; + SCSI_DACKn : out std_logic; + SCSI_INT : in std_logic; + SCSI_CSn : out std_logic; + SCSI_CS : out std_logic; + + CA : out std_logic_vector(2 downto 0); + FLOPPY_HD_DD : in std_logic; + WDC_BSL0 : out std_logic; + FDC_CSn : out std_logic; + FDC_WRn : out std_logic; + FD_INT : in std_logic; + IDE_INT : in std_logic; + DMA_CS : out std_logic + ); + end component; + + component IDE_CF_SD_ROM is + port( + RESET : in std_logic; + CLK_MAIN : in std_logic; + + FB_ADR : in std_logic_vector(19 downto 5); + FB_CS1n : in std_logic; + FB_WRn : in std_logic; + FB_B0 : in std_logic; + FB_B1 : in std_logic; + + FBEE_CONF : in std_logic_vector(31 downto 30); + + RP_UDSn : out std_logic; + RP_LDSn : out std_logic; + + SD_CLK : out std_logic; + SD_D0 : in std_logic; + SD_D1 : in std_logic; + SD_D2 : in std_logic; + SD_CD_D3_IN : in std_logic; + SD_CD_D3_OUT : out std_logic; + SD_CD_D3_EN : out std_logic; + SD_CMD_D1_IN : in std_logic; + SD_CMD_D1_OUT : out std_logic; + SD_CMD_D1_EN : out std_logic; + SD_CARD_DETECT : in std_logic; + SD_WP : in std_logic; + + IDE_RDY : in std_logic; + IDE_WRn : buffer std_logic; + IDE_RDn : out std_logic; + IDE_CSn : out std_logic_vector(1 downto 0); + IDE_DRQn : out std_logic; + IDE_CF_TA : out std_logic; + + ROM4n : out std_logic; + ROM3n : out std_logic; + + CF_WP : in bit; + CF_CSn : out std_logic_vector(1 downto 0) + ); + end component; + + component FBEE_BLITTER is + port( + RESETn : in std_logic; + CLK_MAIN : in std_logic; + CLK_DDR0 : in std_logic; + FB_ADR : in std_logic_vector(31 downto 0); + FB_ALE : in std_logic; + FB_SIZE1 : in std_logic; + FB_SIZE0 : in std_logic; + FB_CSn : in std_logic_vector(3 downto 1); + FB_OEn : in std_logic; + FB_WRn : in std_logic; + DATA_IN : in std_logic_vector(31 downto 0); + DATA_OUT : out std_logic_vector(31 downto 0); + DATA_EN : out std_logic; + BLITTER_ON : in std_logic; + BLITTER_DIN : in std_logic_vector(127 downto 0); + BLITTER_DACK_SR : in std_logic; + BLITTER_RUN : out std_logic; + BLITTER_DOUT : out std_logic_vector(127 downto 0); + BLITTER_ADR : out std_logic_vector(31 downto 0); + BLITTER_SIG : out std_logic; + BLITTER_WR : out std_logic; + BLITTER_TA : out std_logic + ); + end component; + + component DSP is + port( + CLK_33M : in std_logic; + CLK_MAIN : in std_logic; + FB_OEn : in std_logic; + FB_WRn : in std_logic; + FB_CS1n : in std_logic; + FB_CS2n : in std_logic; + FB_SIZE0 : in std_logic; + FB_SIZE1 : in std_logic; + FB_BURSTn : in std_logic; + FB_ADR : in std_logic_vector(31 downto 0); + RESETn : in std_logic; + FB_CS3n : in std_logic; + SRCSn : out std_logic; + SRBLEn : out std_logic; + SRBHEn : out std_logic; + SRWEn : out std_logic; + SROEn : out std_logic; + DSP_INT : out std_logic; + DSP_TA : out std_logic; + FB_AD_IN : in std_logic_vector(31 downto 0); + FB_AD_OUT : out std_logic_vector(31 downto 0); + FB_AD_EN : out std_logic; + IO_IN : in std_logic_vector(17 downto 0); + IO_OUT : out std_logic_vector(17 downto 0); + IO_EN : out std_logic; + SRD_IN : in std_logic_vector(15 downto 0); + SRD_OUT : out std_logic_vector(15 downto 0); + SRD_EN : out std_logic + ); + end component DSP; + + component WF2149IP_TOP_SOC + port( + + SYS_CLK : in std_logic; + RESETn : in std_logic; + + WAV_CLK : in std_logic; + SELn : in std_logic; + + BDIR : in std_logic; + BC2, BC1 : in std_logic; + + A9n, A8 : in std_logic; + DA_IN : in std_logic_vector(7 downto 0); + DA_OUT : out std_logic_vector(7 downto 0); + DA_EN : out std_logic; + + IO_A_IN : in std_logic_vector(7 downto 0); + IO_A_OUT : out std_logic_vector(7 downto 0); + IO_A_EN : out std_logic; + IO_B_IN : in std_logic_vector(7 downto 0); + IO_B_OUT : out std_logic_vector(7 downto 0); + IO_B_EN : out std_logic; + + OUT_A : out std_logic; + OUT_B : out std_logic; + OUT_C : out std_logic + ); + end component WF2149IP_TOP_SOC; + + component WF68901IP_TOP_SOC + port ( + CLK : in std_logic; + RESETn : in std_logic; + DSn : in std_logic; + CSn : in std_logic; + RWn : in std_logic; + DTACKn : out std_logic; + RS : in std_logic_vector(5 downto 1); + DATA_IN : in std_logic_vector(7 downto 0); + DATA_OUT : out std_logic_vector(7 downto 0); + DATA_EN : out std_logic; + GPIP_IN : in std_logic_vector(7 downto 0); + GPIP_OUT : out std_logic_vector(7 downto 0); + GPIP_EN : out std_logic_vector(7 downto 0); + IACKn : in std_logic; + IEIn : in std_logic; + IEOn : out std_logic; + IRQn : out std_logic; + XTAL1 : in std_logic; + TAI : in std_logic; + TBI : in std_logic; + TAO : out std_logic; + TBO : out std_logic; + TCO : out std_logic; + TDO : out std_logic; + RC : in std_logic; + TC : in std_logic; + SI : in std_logic; + SO : out std_logic; + SO_EN : out std_logic; + RRn : out std_logic; + TRn : out std_logic + ); + end component WF68901IP_TOP_SOC; + + component WF6850IP_TOP_SOC + port ( + CLK : in std_logic; + RESETn : in std_logic; + + CS2n, CS1, CS0 : in std_logic; + E : in std_logic; + RWn : in std_logic; + RS : in std_logic; + + DATA_IN : in std_logic_vector(7 downto 0); + DATA_OUT : out std_logic_vector(7 downto 0); + DATA_EN : out std_logic; + + TXCLK : in std_logic; + RXCLK : in std_logic; + RXDATA : in std_logic; + CTSn : in std_logic; + DCDn : in std_logic; + + IRQn : out std_logic; + TXDATA : out std_logic; + RTSn : out std_logic + ); + end component WF6850IP_TOP_SOC; + + component WF5380_TOP_SOC + port ( + CLK : in std_logic; + RESETn : in std_logic; + ADR : in std_logic_vector(2 downto 0); + DATA_IN : in std_logic_vector(7 downto 0); + DATA_OUT : out std_logic_vector(7 downto 0); + DATA_EN : out std_logic; + CSn : in std_logic; + RDn : in std_logic; + WRn : in std_logic; + EOPn : in std_logic; + DACKn : in std_logic; + DRQ : out std_logic; + INT : out std_logic; + READY : out std_logic; + DB_INn : in std_logic_vector(7 downto 0); + DB_OUTn : out std_logic_vector(7 downto 0); + DB_EN : out std_logic; + DBP_INn : in std_logic; + DBP_OUTn : out std_logic; + DBP_EN : out std_logic; + RST_INn : in std_logic; + RST_OUTn : out std_logic; + RST_EN : out std_logic; + BSY_INn : in std_logic; + BSY_OUTn : out std_logic; + BSY_EN : out std_logic; + SEL_INn : in std_logic; + SEL_OUTn : out std_logic; + SEL_EN : out std_logic; + ACK_INn : in std_logic; + ACK_OUTn : out std_logic; + ACK_EN : out std_logic; + ATN_INn : in std_logic; + ATN_OUTn : out std_logic; + ATN_EN : out std_logic; + REQ_INn : in std_logic; + REQ_OUTn : out std_logic; + REQ_EN : out std_logic; + IOn_IN : in std_logic; + IOn_OUT : out std_logic; + IO_EN : out std_logic; + CDn_IN : in std_logic; + CDn_OUT : out std_logic; + CD_EN : out std_logic; + MSG_INn : in std_logic; + MSG_OUTn : out std_logic; + MSG_EN : out std_logic + ); + end component WF5380_TOP_SOC; + + component WF1772IP_TOP_SOC + port ( + CLK : in std_logic; + RESETn : in std_logic; + CSn : in std_logic; + RWn : in std_logic; + A1, A0 : in std_logic; + DATA_IN : in std_logic_vector(7 downto 0); + DATA_OUT : out std_logic_vector(7 downto 0); + DATA_EN : out std_logic; + RDn : in std_logic; + TR00n : in std_logic; + IPn : in std_logic; + WPRTn : in std_logic; + DDEn : in std_logic; + HDTYPE : in std_logic; + MO : out std_logic; + WG : out std_logic; + WD : out std_logic; + STEP : out std_logic; + DIRC : out std_logic; + DRQ : out std_logic; + INTRQ : out std_logic + ); + end component WF1772IP_TOP_SOC; + + component RTC is + port( + CLK_MAIN : in std_logic; + FB_ADR : in std_logic_vector(19 downto 0); + FB_CS1n : in std_logic; + FB_SIZE0 : in std_logic; + FB_SIZE1 : in std_logic; + FB_WRn : in std_logic; + FB_OEn : in std_logic; + FB_AD_IN : in std_logic_vector(23 downto 16); + FB_AD_OUT : out std_logic_vector(23 downto 16); + FB_AD_EN_23_16 : out std_logic; + PIC_INT : in std_logic + ); + end component RTC; +end firebee_pkg; diff --git a/vhdl/rtl/vhdl/Firebee_V1/altpll0.ppf b/vhdl/rtl/vhdl/Firebee_V1/altpll0.ppf new file mode 100644 index 0000000..521a742 --- /dev/null +++ b/vhdl/rtl/vhdl/Firebee_V1/altpll0.ppf @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/vhdl/rtl/vhdl/Firebee_V1/altpll0.qip b/vhdl/rtl/vhdl/Firebee_V1/altpll0.qip new file mode 100644 index 0000000..1b4cd11 --- /dev/null +++ b/vhdl/rtl/vhdl/Firebee_V1/altpll0.qip @@ -0,0 +1,7 @@ +set_global_assignment -name IP_TOOL_NAME "ALTPLL" +set_global_assignment -name IP_TOOL_VERSION "9.1" +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "altpll0.vhd"] +set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "altpll0.bsf"] +set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "altpll0.inc"] +set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "altpll0.cmp"] +set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "altpll0.ppf"] diff --git a/vhdl/rtl/vhdl/Firebee_V1/altpll1.bsf b/vhdl/rtl/vhdl/Firebee_V1/altpll1.bsf new file mode 100644 index 0000000..9f2d7ab --- /dev/null +++ b/vhdl/rtl/vhdl/Firebee_V1/altpll1.bsf @@ -0,0 +1,100 @@ +/* +WARNING: Do NOT edit the input and output ports in this file in a text +editor if you plan to continue editing the block that represents it in +the Block Editor! File corruption is VERY likely to occur. +*/ +/* +Copyright (C) 1991-2013 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. +*/ +(header "symbol" (version "1.2")) +(symbol + (rect 0 0 280 176) + (text "altpll1" (rect 123 0 165 16)(font "Arial" (font_size 10))) + (text "inst" (rect 8 161 26 172)(font "Arial" )) + (port + (pt 0 64) + (input) + (text "inclk0" (rect 0 0 34 13)(font "Arial" (font_size 8))) + (text "inclk0" (rect 4 51 31 63)(font "Arial" (font_size 8))) + (line (pt 0 64)(pt 40 64)) + ) + (port + (pt 280 64) + (output) + (text "c0" (rect 0 0 15 13)(font "Arial" (font_size 8))) + (text "c0" (rect 265 51 277 63)(font "Arial" (font_size 8))) + ) + (port + (pt 280 80) + (output) + (text "c1" (rect 0 0 15 13)(font "Arial" (font_size 8))) + (text "c1" (rect 265 67 277 79)(font "Arial" (font_size 8))) + ) + (port + (pt 280 96) + (output) + (text "c2" (rect 0 0 15 13)(font "Arial" (font_size 8))) + (text "c2" (rect 265 83 277 95)(font "Arial" (font_size 8))) + ) + (port + (pt 280 112) + (output) + (text "locked" (rect 0 0 37 13)(font "Arial" (font_size 8))) + (text "locked" (rect 245 99 276 111)(font "Arial" (font_size 8))) + ) + (drawing + (text "Cyclone III" (rect 222 162 490 334)(font "Arial" )) + (text "inclk0 frequency: 33.000 MHz" (rect 50 60 226 130)(font "Arial" )) + (text "Operation Mode: No Compensation" (rect 50 72 248 154)(font "Arial" )) + (text "Clk " (rect 51 91 117 192)(font "Arial" )) + (text "Ratio" (rect 82 91 187 192)(font "Arial" )) + (text "Ph (dg)" (rect 119 91 269 192)(font "Arial" )) + (text "DC (%)" (rect 154 91 340 192)(font "Arial" )) + (text "c0" (rect 54 104 119 218)(font "Arial" )) + (text "512/6875" (rect 74 104 187 218)(font "Arial" )) + (text "0.00" (rect 125 104 269 218)(font "Arial" )) + (text "50.00" (rect 158 104 340 218)(font "Arial" )) + (text "c1" (rect 54 117 119 244)(font "Arial" )) + (text "1024/1375" (rect 71 117 186 244)(font "Arial" )) + (text "0.00" (rect 125 117 269 244)(font "Arial" )) + (text "50.00" (rect 158 117 340 244)(font "Arial" )) + (text "c2" (rect 54 130 119 270)(font "Arial" )) + (text "16/11" (rect 82 130 188 270)(font "Arial" )) + (text "0.00" (rect 125 130 269 270)(font "Arial" )) + (text "50.00" (rect 158 130 340 270)(font "Arial" )) + (line (pt 0 0)(pt 281 0)) + (line (pt 281 0)(pt 281 177)) + (line (pt 0 177)(pt 281 177)) + (line (pt 0 0)(pt 0 177)) + (line (pt 48 89)(pt 186 89)) + (line (pt 48 101)(pt 186 101)) + (line (pt 48 114)(pt 186 114)) + (line (pt 48 127)(pt 186 127)) + (line (pt 48 140)(pt 186 140)) + (line (pt 48 89)(pt 48 140)) + (line (pt 68 89)(pt 68 140)(line_width 3)) + (line (pt 116 89)(pt 116 140)(line_width 3)) + (line (pt 151 89)(pt 151 140)(line_width 3)) + (line (pt 185 89)(pt 185 140)) + (line (pt 40 48)(pt 231 48)) + (line (pt 231 48)(pt 231 159)) + (line (pt 40 159)(pt 231 159)) + (line (pt 40 48)(pt 40 159)) + (line (pt 279 64)(pt 231 64)) + (line (pt 279 80)(pt 231 80)) + (line (pt 279 96)(pt 231 96)) + (line (pt 279 112)(pt 231 112)) + ) +) diff --git a/vhdl/rtl/vhdl/Firebee_V1/altpll1.cmp b/vhdl/rtl/vhdl/Firebee_V1/altpll1.cmp new file mode 100644 index 0000000..1e96bfe --- /dev/null +++ b/vhdl/rtl/vhdl/Firebee_V1/altpll1.cmp @@ -0,0 +1,25 @@ +--Copyright (C) 1991-2013 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. + + +component altpll1 + PORT + ( + inclk0 : IN STD_LOGIC := '0'; + c0 : OUT STD_LOGIC ; + c1 : OUT STD_LOGIC ; + c2 : OUT STD_LOGIC ; + locked : OUT STD_LOGIC + ); +end component; diff --git a/vhdl/rtl/vhdl/Firebee_V1/altpll1.inc b/vhdl/rtl/vhdl/Firebee_V1/altpll1.inc new file mode 100644 index 0000000..dde00bd --- /dev/null +++ b/vhdl/rtl/vhdl/Firebee_V1/altpll1.inc @@ -0,0 +1,26 @@ +--Copyright (C) 1991-2013 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. + + +FUNCTION altpll1 +( + inclk0 +) + +RETURNS ( + c0, + c1, + c2, + locked +); diff --git a/vhdl/rtl/vhdl/Firebee_V1/altpll1.ppf b/vhdl/rtl/vhdl/Firebee_V1/altpll1.ppf new file mode 100644 index 0000000..d292d4b --- /dev/null +++ b/vhdl/rtl/vhdl/Firebee_V1/altpll1.ppf @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/vhdl/rtl/vhdl/Firebee_V1/altpll1.qip b/vhdl/rtl/vhdl/Firebee_V1/altpll1.qip new file mode 100644 index 0000000..01791b7 --- /dev/null +++ b/vhdl/rtl/vhdl/Firebee_V1/altpll1.qip @@ -0,0 +1,7 @@ +set_global_assignment -name IP_TOOL_NAME "ALTPLL" +set_global_assignment -name IP_TOOL_VERSION "13.1" +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "altpll1.vhd"] +set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "altpll1.bsf"] +set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "altpll1.inc"] +set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "altpll1.cmp"] +set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "altpll1.ppf"] diff --git a/vhdl/rtl/vhdl/Firebee_V1/altpll1.vhd b/vhdl/rtl/vhdl/Firebee_V1/altpll1.vhd new file mode 100644 index 0000000..90092c4 --- /dev/null +++ b/vhdl/rtl/vhdl/Firebee_V1/altpll1.vhd @@ -0,0 +1,420 @@ +-- megafunction wizard: %ALTPLL% +-- GENERATION: STANDARD +-- VERSION: WM1.0 +-- MODULE: altpll + +-- ============================================================ +-- File Name: altpll1.vhd +-- Megafunction Name(s): +-- altpll +-- +-- Simulation Library Files(s): +-- altera_mf +-- ============================================================ +-- ************************************************************ +-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! +-- +-- 13.1.0 Build 162 10/23/2013 SJ Web Edition +-- ************************************************************ + + +--Copyright (C) 1991-2013 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. + + +LIBRARY ieee; +USE ieee.std_logic_1164.all; + +LIBRARY altera_mf; +USE altera_mf.all; + +ENTITY altpll1 IS + PORT + ( + inclk0 : IN STD_LOGIC := '0'; + c0 : OUT STD_LOGIC ; + c1 : OUT STD_LOGIC ; + c2 : OUT STD_LOGIC ; + locked : OUT STD_LOGIC + ); +END altpll1; + + +ARCHITECTURE SYN OF altpll1 IS + + SIGNAL sub_wire0 : STD_LOGIC_VECTOR (4 DOWNTO 0); + SIGNAL sub_wire1 : STD_LOGIC ; + SIGNAL sub_wire2 : STD_LOGIC ; + SIGNAL sub_wire3 : STD_LOGIC ; + SIGNAL sub_wire4 : STD_LOGIC ; + SIGNAL sub_wire5 : STD_LOGIC ; + SIGNAL sub_wire6 : STD_LOGIC_VECTOR (1 DOWNTO 0); + SIGNAL sub_wire7_bv : BIT_VECTOR (0 DOWNTO 0); + SIGNAL sub_wire7 : STD_LOGIC_VECTOR (0 DOWNTO 0); + + + + COMPONENT altpll + GENERIC ( + bandwidth_type : STRING; + clk0_divide_by : NATURAL; + clk0_duty_cycle : NATURAL; + clk0_multiply_by : NATURAL; + clk0_phase_shift : STRING; + clk1_divide_by : NATURAL; + clk1_duty_cycle : NATURAL; + clk1_multiply_by : NATURAL; + clk1_phase_shift : STRING; + clk2_divide_by : NATURAL; + clk2_duty_cycle : NATURAL; + clk2_multiply_by : NATURAL; + clk2_phase_shift : STRING; + inclk0_input_frequency : NATURAL; + intended_device_family : STRING; + lpm_type : STRING; + operation_mode : STRING; + pll_type : STRING; + port_activeclock : STRING; + port_areset : STRING; + port_clkbad0 : STRING; + port_clkbad1 : STRING; + port_clkloss : STRING; + port_clkswitch : STRING; + port_configupdate : STRING; + port_fbin : STRING; + port_inclk0 : STRING; + port_inclk1 : STRING; + port_locked : STRING; + port_pfdena : STRING; + port_phasecounterselect : STRING; + port_phasedone : STRING; + port_phasestep : STRING; + port_phaseupdown : STRING; + port_pllena : STRING; + port_scanaclr : STRING; + port_scanclk : STRING; + port_scanclkena : STRING; + port_scandata : STRING; + port_scandataout : STRING; + port_scandone : STRING; + port_scanread : STRING; + port_scanwrite : STRING; + port_clk0 : STRING; + port_clk1 : STRING; + port_clk2 : STRING; + port_clk3 : STRING; + port_clk4 : STRING; + port_clk5 : STRING; + port_clkena0 : STRING; + port_clkena1 : STRING; + port_clkena2 : STRING; + port_clkena3 : STRING; + port_clkena4 : STRING; + port_clkena5 : STRING; + port_extclk0 : STRING; + port_extclk1 : STRING; + port_extclk2 : STRING; + port_extclk3 : STRING; + self_reset_on_loss_lock : STRING; + width_clock : NATURAL + ); + PORT ( + clk : OUT STD_LOGIC_VECTOR (4 DOWNTO 0); + inclk : IN STD_LOGIC_VECTOR (1 DOWNTO 0); + locked : OUT STD_LOGIC + ); + END COMPONENT; + +BEGIN + sub_wire7_bv(0 DOWNTO 0) <= "0"; + sub_wire7 <= To_stdlogicvector(sub_wire7_bv); + sub_wire4 <= sub_wire0(2); + sub_wire3 <= sub_wire0(0); + sub_wire1 <= sub_wire0(1); + c1 <= sub_wire1; + locked <= sub_wire2; + c0 <= sub_wire3; + c2 <= sub_wire4; + sub_wire5 <= inclk0; + sub_wire6 <= sub_wire7(0 DOWNTO 0) & sub_wire5; + + altpll_component : altpll + GENERIC MAP ( + bandwidth_type => "AUTO", + clk0_divide_by => 6875, + clk0_duty_cycle => 50, + clk0_multiply_by => 512, + clk0_phase_shift => "0", + clk1_divide_by => 1375, + clk1_duty_cycle => 50, + clk1_multiply_by => 1024, + clk1_phase_shift => "0", + clk2_divide_by => 11, + clk2_duty_cycle => 50, + clk2_multiply_by => 16, + clk2_phase_shift => "0", + inclk0_input_frequency => 30303, + intended_device_family => "Cyclone III", + lpm_type => "altpll", + operation_mode => "NO_COMPENSATION", + pll_type => "AUTO", + port_activeclock => "PORT_UNUSED", + port_areset => "PORT_UNUSED", + port_clkbad0 => "PORT_UNUSED", + port_clkbad1 => "PORT_UNUSED", + port_clkloss => "PORT_UNUSED", + port_clkswitch => "PORT_UNUSED", + port_configupdate => "PORT_UNUSED", + port_fbin => "PORT_UNUSED", + port_inclk0 => "PORT_USED", + port_inclk1 => "PORT_UNUSED", + port_locked => "PORT_USED", + port_pfdena => "PORT_UNUSED", + port_phasecounterselect => "PORT_UNUSED", + port_phasedone => "PORT_UNUSED", + port_phasestep => "PORT_UNUSED", + port_phaseupdown => "PORT_UNUSED", + port_pllena => "PORT_UNUSED", + port_scanaclr => "PORT_UNUSED", + port_scanclk => "PORT_UNUSED", + port_scanclkena => "PORT_UNUSED", + port_scandata => "PORT_UNUSED", + port_scandataout => "PORT_UNUSED", + port_scandone => "PORT_UNUSED", + port_scanread => "PORT_UNUSED", + port_scanwrite => "PORT_UNUSED", + port_clk0 => "PORT_USED", + port_clk1 => "PORT_USED", + port_clk2 => "PORT_USED", + port_clk3 => "PORT_UNUSED", + port_clk4 => "PORT_UNUSED", + port_clk5 => "PORT_UNUSED", + port_clkena0 => "PORT_UNUSED", + port_clkena1 => "PORT_UNUSED", + port_clkena2 => "PORT_UNUSED", + port_clkena3 => "PORT_UNUSED", + port_clkena4 => "PORT_UNUSED", + port_clkena5 => "PORT_UNUSED", + port_extclk0 => "PORT_UNUSED", + port_extclk1 => "PORT_UNUSED", + port_extclk2 => "PORT_UNUSED", + port_extclk3 => "PORT_UNUSED", + self_reset_on_loss_lock => "OFF", + width_clock => 5 + ) + PORT MAP ( + inclk => sub_wire6, + clk => sub_wire0, + locked => sub_wire2 + ); + + + +END SYN; + +-- ============================================================ +-- 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 "1" +-- 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_PRESET STRING "0" +-- Retrieval info: PRIVATE: CLKBAD_SWITCHOVER_CHECK STRING "0" +-- Retrieval info: PRIVATE: CLKLOSS_CHECK STRING "0" +-- Retrieval info: PRIVATE: CLKSWITCH_CHECK STRING "0" +-- Retrieval info: PRIVATE: CNX_NO_COMPENSATE_RADIO STRING "1" +-- 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 "e0" +-- Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "8" +-- Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "90" +-- Retrieval info: PRIVATE: DIV_FACTOR1 NUMERIC "900" +-- Retrieval info: PRIVATE: DIV_FACTOR2 NUMERIC "90" +-- Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000" +-- Retrieval info: PRIVATE: DUTY_CYCLE1 STRING "50.00000000" +-- Retrieval info: PRIVATE: DUTY_CYCLE2 STRING "50.00000000" +-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "2.457600" +-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE1 STRING "24.576000" +-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE2 STRING "48.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 "0" +-- Retrieval info: PRIVATE: GLOCKED_MODE_CHECK STRING "0" +-- Retrieval info: PRIVATE: GLOCK_COUNTER_EDIT NUMERIC "1048575" +-- Retrieval info: PRIVATE: HAS_MANUAL_SWITCHOVER STRING "1" +-- Retrieval info: PRIVATE: INCLK0_FREQ_EDIT STRING "33.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 III" +-- 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: LVDS_PHASE_SHIFT_UNIT1 STRING "deg" +-- Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT2 STRING "deg" +-- Retrieval info: PRIVATE: MIG_DEVICE_SPEED_GRADE STRING "Any" +-- Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0" +-- Retrieval info: PRIVATE: MIRROR_CLK1 STRING "0" +-- Retrieval info: PRIVATE: MIRROR_CLK2 STRING "0" +-- Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "67" +-- Retrieval info: PRIVATE: MULT_FACTOR1 NUMERIC "67" +-- Retrieval info: PRIVATE: MULT_FACTOR2 NUMERIC "67" +-- Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "0" +-- Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "2.45760000" +-- Retrieval info: PRIVATE: OUTPUT_FREQ1 STRING "24.57600000" +-- Retrieval info: PRIVATE: OUTPUT_FREQ2 STRING "48.00000000" +-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "1" +-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE1 STRING "1" +-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE2 STRING "1" +-- Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz" +-- Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT1 STRING "MHz" +-- Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT2 STRING "MHz" +-- Retrieval info: PRIVATE: PHASE_RECONFIG_FEATURE_ENABLED STRING "1" +-- Retrieval info: PRIVATE: PHASE_RECONFIG_INPUTS_CHECK STRING "0" +-- Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000" +-- Retrieval info: PRIVATE: PHASE_SHIFT1 STRING "0.00000000" +-- Retrieval info: PRIVATE: PHASE_SHIFT2 STRING "0.00000000" +-- Retrieval info: PRIVATE: PHASE_SHIFT_STEP_ENABLED_CHECK STRING "0" +-- Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg" +-- Retrieval info: PRIVATE: PHASE_SHIFT_UNIT1 STRING "deg" +-- Retrieval info: PRIVATE: PHASE_SHIFT_UNIT2 STRING "deg" +-- Retrieval info: PRIVATE: PLL_ADVANCED_PARAM_CHECK STRING "0" +-- Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "0" +-- Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1" +-- 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 "altpll1.mif" +-- Retrieval info: PRIVATE: SACN_INPUTS_CHECK STRING "0" +-- Retrieval info: PRIVATE: SCAN_FEATURE_ENABLED STRING "1" +-- 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: STICKY_CLK1 STRING "1" +-- Retrieval info: PRIVATE: STICKY_CLK2 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_CLK1 STRING "1" +-- Retrieval info: PRIVATE: USE_CLK2 STRING "1" +-- Retrieval info: PRIVATE: USE_CLKENA0 STRING "0" +-- Retrieval info: PRIVATE: USE_CLKENA1 STRING "0" +-- Retrieval info: PRIVATE: USE_CLKENA2 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: BANDWIDTH_TYPE STRING "AUTO" +-- Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "6875" +-- Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50" +-- Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "512" +-- Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0" +-- Retrieval info: CONSTANT: CLK1_DIVIDE_BY NUMERIC "1375" +-- Retrieval info: CONSTANT: CLK1_DUTY_CYCLE NUMERIC "50" +-- Retrieval info: CONSTANT: CLK1_MULTIPLY_BY NUMERIC "1024" +-- Retrieval info: CONSTANT: CLK1_PHASE_SHIFT STRING "0" +-- Retrieval info: CONSTANT: CLK2_DIVIDE_BY NUMERIC "11" +-- Retrieval info: CONSTANT: CLK2_DUTY_CYCLE NUMERIC "50" +-- Retrieval info: CONSTANT: CLK2_MULTIPLY_BY NUMERIC "16" +-- Retrieval info: CONSTANT: CLK2_PHASE_SHIFT STRING "0" +-- Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "30303" +-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III" +-- Retrieval info: CONSTANT: LPM_TYPE STRING "altpll" +-- Retrieval info: CONSTANT: OPERATION_MODE STRING "NO_COMPENSATION" +-- Retrieval info: CONSTANT: PLL_TYPE STRING "AUTO" +-- Retrieval info: CONSTANT: PORT_ACTIVECLOCK STRING "PORT_UNUSED" +-- Retrieval info: CONSTANT: PORT_ARESET STRING "PORT_UNUSED" +-- 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_USED" +-- Retrieval info: CONSTANT: PORT_clk2 STRING "PORT_USED" +-- 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: SELF_RESET_ON_LOSS_LOCK STRING "OFF" +-- Retrieval info: CONSTANT: WIDTH_CLOCK NUMERIC "5" +-- Retrieval info: USED_PORT: @clk 0 0 5 0 OUTPUT_CLK_EXT VCC "@clk[4..0]" +-- Retrieval info: USED_PORT: @inclk 0 0 2 0 INPUT_CLK_EXT VCC "@inclk[1..0]" +-- Retrieval info: USED_PORT: c0 0 0 0 0 OUTPUT_CLK_EXT VCC "c0" +-- Retrieval info: USED_PORT: c1 0 0 0 0 OUTPUT_CLK_EXT VCC "c1" +-- Retrieval info: USED_PORT: c2 0 0 0 0 OUTPUT_CLK_EXT VCC "c2" +-- 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: @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: c1 0 0 0 0 @clk 0 0 1 1 +-- Retrieval info: CONNECT: c2 0 0 0 0 @clk 0 0 1 2 +-- Retrieval info: CONNECT: locked 0 0 0 0 @locked 0 0 0 0 +-- Retrieval info: GEN_FILE: TYPE_NORMAL altpll1.vhd TRUE +-- Retrieval info: GEN_FILE: TYPE_NORMAL altpll1.ppf TRUE +-- Retrieval info: GEN_FILE: TYPE_NORMAL altpll1.inc TRUE +-- Retrieval info: GEN_FILE: TYPE_NORMAL altpll1.cmp TRUE +-- Retrieval info: GEN_FILE: TYPE_NORMAL altpll1.bsf TRUE +-- Retrieval info: GEN_FILE: TYPE_NORMAL altpll1_inst.vhd FALSE +-- Retrieval info: GEN_FILE: TYPE_NORMAL altpll1_waveforms.html TRUE +-- Retrieval info: GEN_FILE: TYPE_NORMAL altpll1_wave*.jpg FALSE +-- Retrieval info: LIB_FILE: altera_mf diff --git a/vhdl/rtl/vhdl/Firebee_V1/altpll1_waveforms.html b/vhdl/rtl/vhdl/Firebee_V1/altpll1_waveforms.html new file mode 100644 index 0000000..1382a12 --- /dev/null +++ b/vhdl/rtl/vhdl/Firebee_V1/altpll1_waveforms.html @@ -0,0 +1,10 @@ + + +Sample Waveforms for "altpll1.vhd" + + +

Sample behavioral waveforms for design file "altpll1.vhd"

+

+

+ + diff --git a/vhdl/rtl/vhdl/Firebee_V1/altpll2.bsf b/vhdl/rtl/vhdl/Firebee_V1/altpll2.bsf new file mode 100644 index 0000000..8e104b2 --- /dev/null +++ b/vhdl/rtl/vhdl/Firebee_V1/altpll2.bsf @@ -0,0 +1,117 @@ +/* +WARNING: Do NOT edit the input and output ports in this file in a text +editor if you plan to continue editing the block that represents it in +the Block Editor! File corruption is VERY likely to occur. +*/ +/* +Copyright (C) 1991-2013 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. +*/ +(header "symbol" (version "1.2")) +(symbol + (rect 0 0 264 200) + (text "altpll2" (rect 115 0 157 16)(font "Arial" (font_size 10))) + (text "inst" (rect 8 185 26 196)(font "Arial" )) + (port + (pt 0 64) + (input) + (text "inclk0" (rect 0 0 34 13)(font "Arial" (font_size 8))) + (text "inclk0" (rect 4 51 31 63)(font "Arial" (font_size 8))) + (line (pt 0 64)(pt 40 64)) + ) + (port + (pt 264 64) + (output) + (text "c0" (rect 0 0 15 13)(font "Arial" (font_size 8))) + (text "c0" (rect 249 51 261 63)(font "Arial" (font_size 8))) + ) + (port + (pt 264 80) + (output) + (text "c1" (rect 0 0 15 13)(font "Arial" (font_size 8))) + (text "c1" (rect 249 67 261 79)(font "Arial" (font_size 8))) + ) + (port + (pt 264 96) + (output) + (text "c2" (rect 0 0 15 13)(font "Arial" (font_size 8))) + (text "c2" (rect 249 83 261 95)(font "Arial" (font_size 8))) + ) + (port + (pt 264 112) + (output) + (text "c3" (rect 0 0 15 13)(font "Arial" (font_size 8))) + (text "c3" (rect 249 99 261 111)(font "Arial" (font_size 8))) + ) + (port + (pt 264 128) + (output) + (text "c4" (rect 0 0 15 13)(font "Arial" (font_size 8))) + (text "c4" (rect 249 115 261 127)(font "Arial" (font_size 8))) + ) + (drawing + (text "Cyclone III" (rect 206 186 458 382)(font "Arial" )) + (text "inclk0 frequency: 33.000 MHz" (rect 50 60 226 130)(font "Arial" )) + (text "Operation Mode: No Compensation" (rect 50 72 248 154)(font "Arial" )) + (text "Clk " (rect 51 91 117 192)(font "Arial" )) + (text "Ratio" (rect 71 91 165 192)(font "Arial" )) + (text "Ph (dg)" (rect 97 91 225 192)(font "Arial" )) + (text "DC (%)" (rect 132 91 296 192)(font "Arial" )) + (text "c0" (rect 54 104 119 218)(font "Arial" )) + (text "4/1" (rect 76 104 166 218)(font "Arial" )) + (text "240.00" (rect 98 104 225 218)(font "Arial" )) + (text "50.00" (rect 136 104 296 218)(font "Arial" )) + (text "c1" (rect 54 117 119 244)(font "Arial" )) + (text "4/1" (rect 76 117 166 244)(font "Arial" )) + (text "0.00" (rect 103 117 225 244)(font "Arial" )) + (text "50.00" (rect 136 117 296 244)(font "Arial" )) + (text "c2" (rect 54 130 119 270)(font "Arial" )) + (text "4/1" (rect 76 130 166 270)(font "Arial" )) + (text "180.00" (rect 98 130 225 270)(font "Arial" )) + (text "50.00" (rect 136 130 296 270)(font "Arial" )) + (text "c3" (rect 54 143 119 296)(font "Arial" )) + (text "4/1" (rect 76 143 166 296)(font "Arial" )) + (text "105.00" (rect 98 143 225 296)(font "Arial" )) + (text "50.00" (rect 136 143 296 296)(font "Arial" )) + (text "c4" (rect 54 156 119 322)(font "Arial" )) + (text "2/1" (rect 76 156 166 322)(font "Arial" )) + (text "270.00" (rect 98 156 225 322)(font "Arial" )) + (text "50.00" (rect 136 156 296 322)(font "Arial" )) + (line (pt 0 0)(pt 265 0)) + (line (pt 265 0)(pt 265 201)) + (line (pt 0 201)(pt 265 201)) + (line (pt 0 0)(pt 0 201)) + (line (pt 48 89)(pt 164 89)) + (line (pt 48 101)(pt 164 101)) + (line (pt 48 114)(pt 164 114)) + (line (pt 48 127)(pt 164 127)) + (line (pt 48 140)(pt 164 140)) + (line (pt 48 153)(pt 164 153)) + (line (pt 48 166)(pt 164 166)) + (line (pt 48 89)(pt 48 166)) + (line (pt 68 89)(pt 68 166)(line_width 3)) + (line (pt 94 89)(pt 94 166)(line_width 3)) + (line (pt 129 89)(pt 129 166)(line_width 3)) + (line (pt 163 89)(pt 163 166)) + (line (pt 40 48)(pt 231 48)) + (line (pt 231 48)(pt 231 183)) + (line (pt 40 183)(pt 231 183)) + (line (pt 40 48)(pt 40 183)) + (line (pt 263 64)(pt 231 64)) + (line (pt 263 80)(pt 231 80)) + (line (pt 263 96)(pt 231 96)) + (line (pt 263 112)(pt 231 112)) + (line (pt 263 128)(pt 231 128)) + ) +) diff --git a/vhdl/rtl/vhdl/Firebee_V1/altpll2.cmp b/vhdl/rtl/vhdl/Firebee_V1/altpll2.cmp new file mode 100644 index 0000000..b88b00d --- /dev/null +++ b/vhdl/rtl/vhdl/Firebee_V1/altpll2.cmp @@ -0,0 +1,26 @@ +--Copyright (C) 1991-2013 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. + + +component altpll2 + PORT + ( + inclk0 : IN STD_LOGIC := '0'; + c0 : OUT STD_LOGIC ; + c1 : OUT STD_LOGIC ; + c2 : OUT STD_LOGIC ; + c3 : OUT STD_LOGIC ; + c4 : OUT STD_LOGIC + ); +end component; diff --git a/vhdl/rtl/vhdl/Firebee_V1/altpll2.inc b/vhdl/rtl/vhdl/Firebee_V1/altpll2.inc new file mode 100644 index 0000000..ef3c9d4 --- /dev/null +++ b/vhdl/rtl/vhdl/Firebee_V1/altpll2.inc @@ -0,0 +1,27 @@ +--Copyright (C) 1991-2013 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. + + +FUNCTION altpll2 +( + inclk0 +) + +RETURNS ( + c0, + c1, + c2, + c3, + c4 +); diff --git a/vhdl/rtl/vhdl/Firebee_V1/altpll2.ppf b/vhdl/rtl/vhdl/Firebee_V1/altpll2.ppf new file mode 100644 index 0000000..0e421c1 --- /dev/null +++ b/vhdl/rtl/vhdl/Firebee_V1/altpll2.ppf @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/vhdl/rtl/vhdl/Firebee_V1/altpll2.qip b/vhdl/rtl/vhdl/Firebee_V1/altpll2.qip new file mode 100644 index 0000000..294e5db --- /dev/null +++ b/vhdl/rtl/vhdl/Firebee_V1/altpll2.qip @@ -0,0 +1,7 @@ +set_global_assignment -name IP_TOOL_NAME "ALTPLL" +set_global_assignment -name IP_TOOL_VERSION "13.1" +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "altpll2.vhd"] +set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "altpll2.bsf"] +set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "altpll2.inc"] +set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "altpll2.cmp"] +set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "altpll2.ppf"] diff --git a/vhdl/rtl/vhdl/Firebee_V1/altpll2.vhd b/vhdl/rtl/vhdl/Firebee_V1/altpll2.vhd new file mode 100644 index 0000000..9098de9 --- /dev/null +++ b/vhdl/rtl/vhdl/Firebee_V1/altpll2.vhd @@ -0,0 +1,474 @@ +-- megafunction wizard: %ALTPLL% +-- GENERATION: STANDARD +-- VERSION: WM1.0 +-- MODULE: altpll + +-- ============================================================ +-- File Name: altpll2.vhd +-- Megafunction Name(s): +-- altpll +-- +-- Simulation Library Files(s): +-- altera_mf +-- ============================================================ +-- ************************************************************ +-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! +-- +-- 13.1.0 Build 162 10/23/2013 SJ Web Edition +-- ************************************************************ + + +--Copyright (C) 1991-2013 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. + + +LIBRARY ieee; +USE ieee.std_logic_1164.all; + +LIBRARY altera_mf; +USE altera_mf.all; + +ENTITY altpll2 IS + PORT + ( + inclk0 : IN STD_LOGIC := '0'; + c0 : OUT STD_LOGIC ; + c1 : OUT STD_LOGIC ; + c2 : OUT STD_LOGIC ; + c3 : OUT STD_LOGIC ; + c4 : OUT STD_LOGIC + ); +END altpll2; + + +ARCHITECTURE SYN OF altpll2 IS + + SIGNAL sub_wire0 : STD_LOGIC_VECTOR (4 DOWNTO 0); + SIGNAL sub_wire1 : STD_LOGIC ; + SIGNAL sub_wire2 : STD_LOGIC ; + SIGNAL sub_wire3 : STD_LOGIC ; + SIGNAL sub_wire4 : STD_LOGIC ; + SIGNAL sub_wire5 : STD_LOGIC ; + SIGNAL sub_wire6 : STD_LOGIC ; + SIGNAL sub_wire7 : STD_LOGIC_VECTOR (1 DOWNTO 0); + SIGNAL sub_wire8_bv : BIT_VECTOR (0 DOWNTO 0); + SIGNAL sub_wire8 : STD_LOGIC_VECTOR (0 DOWNTO 0); + + + + COMPONENT altpll + GENERIC ( + bandwidth_type : STRING; + clk0_divide_by : NATURAL; + clk0_duty_cycle : NATURAL; + clk0_multiply_by : NATURAL; + clk0_phase_shift : STRING; + clk1_divide_by : NATURAL; + clk1_duty_cycle : NATURAL; + clk1_multiply_by : NATURAL; + clk1_phase_shift : STRING; + clk2_divide_by : NATURAL; + clk2_duty_cycle : NATURAL; + clk2_multiply_by : NATURAL; + clk2_phase_shift : STRING; + clk3_divide_by : NATURAL; + clk3_duty_cycle : NATURAL; + clk3_multiply_by : NATURAL; + clk3_phase_shift : STRING; + clk4_divide_by : NATURAL; + clk4_duty_cycle : NATURAL; + clk4_multiply_by : NATURAL; + clk4_phase_shift : STRING; + inclk0_input_frequency : NATURAL; + intended_device_family : STRING; + lpm_type : STRING; + operation_mode : STRING; + pll_type : STRING; + port_activeclock : STRING; + port_areset : STRING; + port_clkbad0 : STRING; + port_clkbad1 : STRING; + port_clkloss : STRING; + port_clkswitch : STRING; + port_configupdate : STRING; + port_fbin : STRING; + port_inclk0 : STRING; + port_inclk1 : STRING; + port_locked : STRING; + port_pfdena : STRING; + port_phasecounterselect : STRING; + port_phasedone : STRING; + port_phasestep : STRING; + port_phaseupdown : STRING; + port_pllena : STRING; + port_scanaclr : STRING; + port_scanclk : STRING; + port_scanclkena : STRING; + port_scandata : STRING; + port_scandataout : STRING; + port_scandone : STRING; + port_scanread : STRING; + port_scanwrite : STRING; + port_clk0 : STRING; + port_clk1 : STRING; + port_clk2 : STRING; + port_clk3 : STRING; + port_clk4 : STRING; + port_clk5 : STRING; + port_clkena0 : STRING; + port_clkena1 : STRING; + port_clkena2 : STRING; + port_clkena3 : STRING; + port_clkena4 : STRING; + port_clkena5 : STRING; + port_extclk0 : STRING; + port_extclk1 : STRING; + port_extclk2 : STRING; + port_extclk3 : STRING; + width_clock : NATURAL + ); + PORT ( + clk : OUT STD_LOGIC_VECTOR (4 DOWNTO 0); + inclk : IN STD_LOGIC_VECTOR (1 DOWNTO 0) + ); + END COMPONENT; + +BEGIN + sub_wire8_bv(0 DOWNTO 0) <= "0"; + sub_wire8 <= To_stdlogicvector(sub_wire8_bv); + sub_wire5 <= sub_wire0(4); + sub_wire4 <= sub_wire0(2); + sub_wire3 <= sub_wire0(0); + sub_wire2 <= sub_wire0(3); + sub_wire1 <= sub_wire0(1); + c1 <= sub_wire1; + c3 <= sub_wire2; + c0 <= sub_wire3; + c2 <= sub_wire4; + c4 <= sub_wire5; + sub_wire6 <= inclk0; + sub_wire7 <= sub_wire8(0 DOWNTO 0) & sub_wire6; + + altpll_component : altpll + GENERIC MAP ( + bandwidth_type => "AUTO", + clk0_divide_by => 1, + clk0_duty_cycle => 50, + clk0_multiply_by => 4, + clk0_phase_shift => "5051", + clk1_divide_by => 1, + clk1_duty_cycle => 50, + clk1_multiply_by => 4, + clk1_phase_shift => "0", + clk2_divide_by => 1, + clk2_duty_cycle => 50, + clk2_multiply_by => 4, + clk2_phase_shift => "3788", + clk3_divide_by => 1, + clk3_duty_cycle => 50, + clk3_multiply_by => 4, + clk3_phase_shift => "2210", + clk4_divide_by => 1, + clk4_duty_cycle => 50, + clk4_multiply_by => 2, + clk4_phase_shift => "11364", + inclk0_input_frequency => 30303, + intended_device_family => "Cyclone III", + lpm_type => "altpll", + operation_mode => "NO_COMPENSATION", + pll_type => "AUTO", + port_activeclock => "PORT_UNUSED", + port_areset => "PORT_UNUSED", + port_clkbad0 => "PORT_UNUSED", + port_clkbad1 => "PORT_UNUSED", + port_clkloss => "PORT_UNUSED", + port_clkswitch => "PORT_UNUSED", + port_configupdate => "PORT_UNUSED", + port_fbin => "PORT_UNUSED", + port_inclk0 => "PORT_USED", + port_inclk1 => "PORT_UNUSED", + port_locked => "PORT_UNUSED", + port_pfdena => "PORT_UNUSED", + port_phasecounterselect => "PORT_UNUSED", + port_phasedone => "PORT_UNUSED", + port_phasestep => "PORT_UNUSED", + port_phaseupdown => "PORT_UNUSED", + port_pllena => "PORT_UNUSED", + port_scanaclr => "PORT_UNUSED", + port_scanclk => "PORT_UNUSED", + port_scanclkena => "PORT_UNUSED", + port_scandata => "PORT_UNUSED", + port_scandataout => "PORT_UNUSED", + port_scandone => "PORT_UNUSED", + port_scanread => "PORT_UNUSED", + port_scanwrite => "PORT_UNUSED", + port_clk0 => "PORT_USED", + port_clk1 => "PORT_USED", + port_clk2 => "PORT_USED", + port_clk3 => "PORT_USED", + port_clk4 => "PORT_USED", + port_clk5 => "PORT_UNUSED", + port_clkena0 => "PORT_UNUSED", + port_clkena1 => "PORT_UNUSED", + port_clkena2 => "PORT_UNUSED", + port_clkena3 => "PORT_UNUSED", + port_clkena4 => "PORT_UNUSED", + port_clkena5 => "PORT_UNUSED", + port_extclk0 => "PORT_UNUSED", + port_extclk1 => "PORT_UNUSED", + port_extclk2 => "PORT_UNUSED", + port_extclk3 => "PORT_UNUSED", + width_clock => 5 + ) + PORT MAP ( + inclk => sub_wire7, + clk => sub_wire0 + ); + + + +END SYN; + +-- ============================================================ +-- 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 "1" +-- 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_PRESET STRING "0" +-- Retrieval info: PRIVATE: CLKBAD_SWITCHOVER_CHECK STRING "0" +-- Retrieval info: PRIVATE: CLKLOSS_CHECK STRING "0" +-- Retrieval info: PRIVATE: CLKSWITCH_CHECK STRING "0" +-- Retrieval info: PRIVATE: CNX_NO_COMPENSATE_RADIO STRING "1" +-- 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 "8" +-- Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "1" +-- Retrieval info: PRIVATE: DIV_FACTOR1 NUMERIC "1" +-- Retrieval info: PRIVATE: DIV_FACTOR2 NUMERIC "1" +-- Retrieval info: PRIVATE: DIV_FACTOR3 NUMERIC "1" +-- Retrieval info: PRIVATE: DIV_FACTOR4 NUMERIC "1" +-- Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000" +-- Retrieval info: PRIVATE: DUTY_CYCLE1 STRING "50.00000000" +-- Retrieval info: PRIVATE: DUTY_CYCLE2 STRING "50.00000000" +-- Retrieval info: PRIVATE: DUTY_CYCLE3 STRING "50.00000000" +-- Retrieval info: PRIVATE: DUTY_CYCLE4 STRING "50.00000000" +-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "132.000000" +-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE1 STRING "132.000000" +-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE2 STRING "132.000000" +-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE3 STRING "132.000000" +-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE4 STRING "66.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 "0" +-- Retrieval info: PRIVATE: GLOCKED_MODE_CHECK STRING "0" +-- Retrieval info: PRIVATE: GLOCK_COUNTER_EDIT NUMERIC "1048575" +-- Retrieval info: PRIVATE: HAS_MANUAL_SWITCHOVER STRING "1" +-- Retrieval info: PRIVATE: INCLK0_FREQ_EDIT STRING "33.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 III" +-- Retrieval info: PRIVATE: INT_FEEDBACK__MODE_RADIO STRING "1" +-- Retrieval info: PRIVATE: LOCKED_OUTPUT_CHECK STRING "0" +-- 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: LVDS_PHASE_SHIFT_UNIT1 STRING "deg" +-- Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT2 STRING "deg" +-- Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT3 STRING "ps" +-- Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT4 STRING "ps" +-- Retrieval info: PRIVATE: MIG_DEVICE_SPEED_GRADE STRING "Any" +-- Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0" +-- Retrieval info: PRIVATE: MIRROR_CLK1 STRING "0" +-- Retrieval info: PRIVATE: MIRROR_CLK2 STRING "0" +-- Retrieval info: PRIVATE: MIRROR_CLK3 STRING "0" +-- Retrieval info: PRIVATE: MIRROR_CLK4 STRING "0" +-- Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "4" +-- Retrieval info: PRIVATE: MULT_FACTOR1 NUMERIC "4" +-- Retrieval info: PRIVATE: MULT_FACTOR2 NUMERIC "4" +-- Retrieval info: PRIVATE: MULT_FACTOR3 NUMERIC "4" +-- Retrieval info: PRIVATE: MULT_FACTOR4 NUMERIC "2" +-- Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "0" +-- Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "133.33333000" +-- Retrieval info: PRIVATE: OUTPUT_FREQ1 STRING "133.33330000" +-- Retrieval info: PRIVATE: OUTPUT_FREQ2 STRING "133.33330000" +-- Retrieval info: PRIVATE: OUTPUT_FREQ3 STRING "133.33330000" +-- Retrieval info: PRIVATE: OUTPUT_FREQ4 STRING "100.00000000" +-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "0" +-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE1 STRING "0" +-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE2 STRING "0" +-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE3 STRING "0" +-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE4 STRING "0" +-- Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz" +-- Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT1 STRING "MHz" +-- Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT2 STRING "MHz" +-- Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT3 STRING "MHz" +-- Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT4 STRING "MHz" +-- Retrieval info: PRIVATE: PHASE_RECONFIG_FEATURE_ENABLED STRING "1" +-- Retrieval info: PRIVATE: PHASE_RECONFIG_INPUTS_CHECK STRING "0" +-- Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "240.00000000" +-- Retrieval info: PRIVATE: PHASE_SHIFT1 STRING "0.00000000" +-- Retrieval info: PRIVATE: PHASE_SHIFT2 STRING "180.00000000" +-- Retrieval info: PRIVATE: PHASE_SHIFT3 STRING "105.00000000" +-- Retrieval info: PRIVATE: PHASE_SHIFT4 STRING "270.00000000" +-- Retrieval info: PRIVATE: PHASE_SHIFT_STEP_ENABLED_CHECK STRING "0" +-- Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg" +-- Retrieval info: PRIVATE: PHASE_SHIFT_UNIT1 STRING "deg" +-- Retrieval info: PRIVATE: PHASE_SHIFT_UNIT2 STRING "deg" +-- Retrieval info: PRIVATE: PHASE_SHIFT_UNIT3 STRING "deg" +-- Retrieval info: PRIVATE: PHASE_SHIFT_UNIT4 STRING "deg" +-- Retrieval info: PRIVATE: PLL_ADVANCED_PARAM_CHECK STRING "0" +-- Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "0" +-- Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1" +-- 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 "altpll2.mif" +-- Retrieval info: PRIVATE: SACN_INPUTS_CHECK STRING "0" +-- Retrieval info: PRIVATE: SCAN_FEATURE_ENABLED STRING "1" +-- 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: STICKY_CLK1 STRING "1" +-- Retrieval info: PRIVATE: STICKY_CLK2 STRING "1" +-- Retrieval info: PRIVATE: STICKY_CLK3 STRING "1" +-- Retrieval info: PRIVATE: STICKY_CLK4 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_CLK1 STRING "1" +-- Retrieval info: PRIVATE: USE_CLK2 STRING "1" +-- Retrieval info: PRIVATE: USE_CLK3 STRING "1" +-- Retrieval info: PRIVATE: USE_CLK4 STRING "1" +-- Retrieval info: PRIVATE: USE_CLKENA0 STRING "0" +-- Retrieval info: PRIVATE: USE_CLKENA1 STRING "0" +-- Retrieval info: PRIVATE: USE_CLKENA2 STRING "0" +-- Retrieval info: PRIVATE: USE_CLKENA3 STRING "0" +-- Retrieval info: PRIVATE: USE_CLKENA4 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: BANDWIDTH_TYPE STRING "AUTO" +-- Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "1" +-- Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50" +-- Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "4" +-- Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "5051" +-- Retrieval info: CONSTANT: CLK1_DIVIDE_BY NUMERIC "1" +-- Retrieval info: CONSTANT: CLK1_DUTY_CYCLE NUMERIC "50" +-- Retrieval info: CONSTANT: CLK1_MULTIPLY_BY NUMERIC "4" +-- Retrieval info: CONSTANT: CLK1_PHASE_SHIFT STRING "0" +-- Retrieval info: CONSTANT: CLK2_DIVIDE_BY NUMERIC "1" +-- Retrieval info: CONSTANT: CLK2_DUTY_CYCLE NUMERIC "50" +-- Retrieval info: CONSTANT: CLK2_MULTIPLY_BY NUMERIC "4" +-- Retrieval info: CONSTANT: CLK2_PHASE_SHIFT STRING "3788" +-- Retrieval info: CONSTANT: CLK3_DIVIDE_BY NUMERIC "1" +-- Retrieval info: CONSTANT: CLK3_DUTY_CYCLE NUMERIC "50" +-- Retrieval info: CONSTANT: CLK3_MULTIPLY_BY NUMERIC "4" +-- Retrieval info: CONSTANT: CLK3_PHASE_SHIFT STRING "2210" +-- Retrieval info: CONSTANT: CLK4_DIVIDE_BY NUMERIC "1" +-- Retrieval info: CONSTANT: CLK4_DUTY_CYCLE NUMERIC "50" +-- Retrieval info: CONSTANT: CLK4_MULTIPLY_BY NUMERIC "2" +-- Retrieval info: CONSTANT: CLK4_PHASE_SHIFT STRING "11364" +-- Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "30303" +-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III" +-- Retrieval info: CONSTANT: LPM_TYPE STRING "altpll" +-- Retrieval info: CONSTANT: OPERATION_MODE STRING "NO_COMPENSATION" +-- Retrieval info: CONSTANT: PLL_TYPE STRING "AUTO" +-- Retrieval info: CONSTANT: PORT_ACTIVECLOCK STRING "PORT_UNUSED" +-- Retrieval info: CONSTANT: PORT_ARESET STRING "PORT_UNUSED" +-- 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_UNUSED" +-- 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_USED" +-- Retrieval info: CONSTANT: PORT_clk2 STRING "PORT_USED" +-- Retrieval info: CONSTANT: PORT_clk3 STRING "PORT_USED" +-- Retrieval info: CONSTANT: PORT_clk4 STRING "PORT_USED" +-- 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: WIDTH_CLOCK NUMERIC "5" +-- Retrieval info: USED_PORT: @clk 0 0 5 0 OUTPUT_CLK_EXT VCC "@clk[4..0]" +-- Retrieval info: USED_PORT: @inclk 0 0 2 0 INPUT_CLK_EXT VCC "@inclk[1..0]" +-- Retrieval info: USED_PORT: c0 0 0 0 0 OUTPUT_CLK_EXT VCC "c0" +-- Retrieval info: USED_PORT: c1 0 0 0 0 OUTPUT_CLK_EXT VCC "c1" +-- Retrieval info: USED_PORT: c2 0 0 0 0 OUTPUT_CLK_EXT VCC "c2" +-- Retrieval info: USED_PORT: c3 0 0 0 0 OUTPUT_CLK_EXT VCC "c3" +-- Retrieval info: USED_PORT: c4 0 0 0 0 OUTPUT_CLK_EXT VCC "c4" +-- Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT_CLK_EXT GND "inclk0" +-- 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: c1 0 0 0 0 @clk 0 0 1 1 +-- Retrieval info: CONNECT: c2 0 0 0 0 @clk 0 0 1 2 +-- Retrieval info: CONNECT: c3 0 0 0 0 @clk 0 0 1 3 +-- Retrieval info: CONNECT: c4 0 0 0 0 @clk 0 0 1 4 +-- Retrieval info: GEN_FILE: TYPE_NORMAL altpll2.vhd TRUE +-- Retrieval info: GEN_FILE: TYPE_NORMAL altpll2.ppf TRUE +-- Retrieval info: GEN_FILE: TYPE_NORMAL altpll2.inc TRUE +-- Retrieval info: GEN_FILE: TYPE_NORMAL altpll2.cmp TRUE +-- Retrieval info: GEN_FILE: TYPE_NORMAL altpll2.bsf TRUE +-- Retrieval info: GEN_FILE: TYPE_NORMAL altpll2_inst.vhd FALSE +-- Retrieval info: GEN_FILE: TYPE_NORMAL altpll2_waveforms.html TRUE +-- Retrieval info: GEN_FILE: TYPE_NORMAL altpll2_wave*.jpg FALSE +-- Retrieval info: LIB_FILE: altera_mf diff --git a/vhdl/rtl/vhdl/Firebee_V1/altpll2_waveforms.html b/vhdl/rtl/vhdl/Firebee_V1/altpll2_waveforms.html new file mode 100644 index 0000000..1932527 --- /dev/null +++ b/vhdl/rtl/vhdl/Firebee_V1/altpll2_waveforms.html @@ -0,0 +1,10 @@ + + +Sample Waveforms for "altpll2.vhd" + + +

Sample behavioral waveforms for design file "altpll2.vhd"

+

+

+ + diff --git a/vhdl/rtl/vhdl/Firebee_V1/altpll3.bsf b/vhdl/rtl/vhdl/Firebee_V1/altpll3.bsf new file mode 100644 index 0000000..810ff9e --- /dev/null +++ b/vhdl/rtl/vhdl/Firebee_V1/altpll3.bsf @@ -0,0 +1,105 @@ +/* +WARNING: Do NOT edit the input and output ports in this file in a text +editor if you plan to continue editing the block that represents it in +the Block Editor! File corruption is VERY likely to occur. +*/ +/* +Copyright (C) 1991-2012 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. +*/ +(header "symbol" (version "1.2")) +(symbol + (rect 0 0 256 192) + (text "altpll3" (rect 111 0 151 16)(font "Arial" (font_size 10))) + (text "inst" (rect 8 176 25 188)(font "Arial" )) + (port + (pt 0 64) + (input) + (text "inclk0" (rect 0 0 31 14)(font "Arial" (font_size 8))) + (text "inclk0" (rect 4 50 29 63)(font "Arial" (font_size 8))) + (line (pt 0 64)(pt 40 64)) + ) + (port + (pt 256 64) + (output) + (text "c0" (rect 0 0 14 14)(font "Arial" (font_size 8))) + (text "c0" (rect 240 50 250 63)(font "Arial" (font_size 8))) + ) + (port + (pt 256 80) + (output) + (text "c1" (rect 0 0 14 14)(font "Arial" (font_size 8))) + (text "c1" (rect 240 66 248 79)(font "Arial" (font_size 8))) + ) + (port + (pt 256 96) + (output) + (text "c2" (rect 0 0 14 14)(font "Arial" (font_size 8))) + (text "c2" (rect 240 82 250 95)(font "Arial" (font_size 8))) + ) + (port + (pt 256 112) + (output) + (text "c3" (rect 0 0 14 14)(font "Arial" (font_size 8))) + (text "c3" (rect 240 98 250 111)(font "Arial" (font_size 8))) + ) + (drawing + (text "Cyclone III" (rect 194 176 433 363)(font "Arial" )) + (text "inclk0 frequency: 33.000 MHz" (rect 50 59 223 129)(font "Arial" )) + (text "Operation Mode: Src Sync Comp" (rect 50 72 236 155)(font "Arial" )) + (text "Clk " (rect 51 93 116 197)(font "Arial" )) + (text "Ratio" (rect 82 93 184 197)(font "Arial" )) + (text "Ph (dg)" (rect 119 93 267 197)(font "Arial" )) + (text "DC (%)" (rect 153 93 336 197)(font "Arial" )) + (text "c0" (rect 54 107 116 225)(font "Arial" )) + (text "2/33" (rect 84 107 184 225)(font "Arial" )) + (text "0.00" (rect 125 107 266 225)(font "Arial" )) + (text "50.00" (rect 157 107 335 225)(font "Arial" )) + (text "c1" (rect 54 121 115 253)(font "Arial" )) + (text "16/33" (rect 82 121 185 253)(font "Arial" )) + (text "0.00" (rect 125 121 266 253)(font "Arial" )) + (text "50.00" (rect 157 121 335 253)(font "Arial" )) + (text "c2" (rect 54 135 116 281)(font "Arial" )) + (text "25/33" (rect 82 135 185 281)(font "Arial" )) + (text "0.00" (rect 125 135 266 281)(font "Arial" )) + (text "50.00" (rect 157 135 335 281)(font "Arial" )) + (text "c3" (rect 54 149 116 309)(font "Arial" )) + (text "499/33000" (rect 72 149 185 309)(font "Arial" )) + (text "0.00" (rect 125 149 266 309)(font "Arial" )) + (text "50.00" (rect 157 149 335 309)(font "Arial" )) + (line (pt 0 0)(pt 257 0)) + (line (pt 257 0)(pt 257 193)) + (line (pt 0 193)(pt 257 193)) + (line (pt 0 0)(pt 0 193)) + (line (pt 48 91)(pt 185 91)) + (line (pt 48 104)(pt 185 104)) + (line (pt 48 118)(pt 185 118)) + (line (pt 48 132)(pt 185 132)) + (line (pt 48 146)(pt 185 146)) + (line (pt 48 160)(pt 185 160)) + (line (pt 48 91)(pt 48 160)) + (line (pt 69 91)(pt 69 160)(line_width 3)) + (line (pt 116 91)(pt 116 160)(line_width 3)) + (line (pt 150 91)(pt 150 160)(line_width 3)) + (line (pt 184 91)(pt 184 160)) + (line (pt 40 48)(pt 223 48)) + (line (pt 223 48)(pt 223 175)) + (line (pt 40 175)(pt 223 175)) + (line (pt 40 48)(pt 40 175)) + (line (pt 255 64)(pt 223 64)) + (line (pt 255 80)(pt 223 80)) + (line (pt 255 96)(pt 223 96)) + (line (pt 255 112)(pt 223 112)) + ) +) diff --git a/vhdl/rtl/vhdl/Firebee_V1/altpll3.cmp b/vhdl/rtl/vhdl/Firebee_V1/altpll3.cmp new file mode 100644 index 0000000..9218d25 --- /dev/null +++ b/vhdl/rtl/vhdl/Firebee_V1/altpll3.cmp @@ -0,0 +1,25 @@ +--Copyright (C) 1991-2012 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. + + +component altpll3 + PORT + ( + inclk0 : IN STD_LOGIC := '0'; + c0 : OUT STD_LOGIC ; + c1 : OUT STD_LOGIC ; + c2 : OUT STD_LOGIC ; + c3 : OUT STD_LOGIC + ); +end component; diff --git a/vhdl/rtl/vhdl/Firebee_V1/altpll3.inc b/vhdl/rtl/vhdl/Firebee_V1/altpll3.inc new file mode 100644 index 0000000..974e6f4 --- /dev/null +++ b/vhdl/rtl/vhdl/Firebee_V1/altpll3.inc @@ -0,0 +1,26 @@ +--Copyright (C) 1991-2012 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. + + +FUNCTION altpll3 +( + inclk0 +) + +RETURNS ( + c0, + c1, + c2, + c3 +); diff --git a/vhdl/rtl/vhdl/Firebee_V1/altpll3.ppf b/vhdl/rtl/vhdl/Firebee_V1/altpll3.ppf new file mode 100644 index 0000000..2a7b695 --- /dev/null +++ b/vhdl/rtl/vhdl/Firebee_V1/altpll3.ppf @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/vhdl/rtl/vhdl/Firebee_V1/altpll3.qip b/vhdl/rtl/vhdl/Firebee_V1/altpll3.qip new file mode 100644 index 0000000..82d1686 --- /dev/null +++ b/vhdl/rtl/vhdl/Firebee_V1/altpll3.qip @@ -0,0 +1,7 @@ +set_global_assignment -name IP_TOOL_NAME "ALTPLL" +set_global_assignment -name IP_TOOL_VERSION "12.0" +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "altpll3.vhd"] +set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "altpll3.bsf"] +set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "altpll3.inc"] +set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "altpll3.cmp"] +set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "altpll3.ppf"] diff --git a/vhdl/rtl/vhdl/Firebee_V1/altpll3.vhd b/vhdl/rtl/vhdl/Firebee_V1/altpll3.vhd new file mode 100644 index 0000000..376a53d --- /dev/null +++ b/vhdl/rtl/vhdl/Firebee_V1/altpll3.vhd @@ -0,0 +1,445 @@ +-- megafunction wizard: %ALTPLL% +-- GENERATION: STANDARD +-- VERSION: WM1.0 +-- MODULE: altpll + +-- ============================================================ +-- File Name: altpll3.vhd +-- Megafunction Name(s): +-- altpll +-- +-- Simulation Library Files(s): +-- altera_mf +-- ============================================================ +-- ************************************************************ +-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! +-- +-- 12.0 Build 178 05/31/2012 SJ Web Edition +-- ************************************************************ + + +--Copyright (C) 1991-2012 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. + + +LIBRARY ieee; +USE ieee.std_logic_1164.all; + +LIBRARY altera_mf; +USE altera_mf.all; + +ENTITY altpll3 IS + PORT + ( + inclk0 : IN STD_LOGIC := '0'; + c0 : OUT STD_LOGIC ; + c1 : OUT STD_LOGIC ; + c2 : OUT STD_LOGIC ; + c3 : OUT STD_LOGIC + ); +END altpll3; + + +ARCHITECTURE SYN OF altpll3 IS + + SIGNAL sub_wire0 : STD_LOGIC_VECTOR (4 DOWNTO 0); + SIGNAL sub_wire1 : STD_LOGIC ; + SIGNAL sub_wire2 : STD_LOGIC ; + SIGNAL sub_wire3 : STD_LOGIC ; + SIGNAL sub_wire4 : STD_LOGIC ; + SIGNAL sub_wire5 : STD_LOGIC ; + SIGNAL sub_wire6 : STD_LOGIC_VECTOR (1 DOWNTO 0); + SIGNAL sub_wire7_bv : BIT_VECTOR (0 DOWNTO 0); + SIGNAL sub_wire7 : STD_LOGIC_VECTOR (0 DOWNTO 0); + + + + COMPONENT altpll + GENERIC ( + bandwidth_type : STRING; + clk0_divide_by : NATURAL; + clk0_duty_cycle : NATURAL; + clk0_multiply_by : NATURAL; + clk0_phase_shift : STRING; + clk1_divide_by : NATURAL; + clk1_duty_cycle : NATURAL; + clk1_multiply_by : NATURAL; + clk1_phase_shift : STRING; + clk2_divide_by : NATURAL; + clk2_duty_cycle : NATURAL; + clk2_multiply_by : NATURAL; + clk2_phase_shift : STRING; + clk3_divide_by : NATURAL; + clk3_duty_cycle : NATURAL; + clk3_multiply_by : NATURAL; + clk3_phase_shift : STRING; + compensate_clock : STRING; + inclk0_input_frequency : NATURAL; + intended_device_family : STRING; + lpm_type : STRING; + operation_mode : STRING; + pll_type : STRING; + port_activeclock : STRING; + port_areset : STRING; + port_clkbad0 : STRING; + port_clkbad1 : STRING; + port_clkloss : STRING; + port_clkswitch : STRING; + port_configupdate : STRING; + port_fbin : STRING; + port_inclk0 : STRING; + port_inclk1 : STRING; + port_locked : STRING; + port_pfdena : STRING; + port_phasecounterselect : STRING; + port_phasedone : STRING; + port_phasestep : STRING; + port_phaseupdown : STRING; + port_pllena : STRING; + port_scanaclr : STRING; + port_scanclk : STRING; + port_scanclkena : STRING; + port_scandata : STRING; + port_scandataout : STRING; + port_scandone : STRING; + port_scanread : STRING; + port_scanwrite : STRING; + port_clk0 : STRING; + port_clk1 : STRING; + port_clk2 : STRING; + port_clk3 : STRING; + port_clk4 : STRING; + port_clk5 : STRING; + port_clkena0 : STRING; + port_clkena1 : STRING; + port_clkena2 : STRING; + port_clkena3 : STRING; + port_clkena4 : STRING; + port_clkena5 : STRING; + port_extclk0 : STRING; + port_extclk1 : STRING; + port_extclk2 : STRING; + port_extclk3 : STRING; + width_clock : NATURAL + ); + PORT ( + clk : OUT STD_LOGIC_VECTOR (4 DOWNTO 0); + inclk : IN STD_LOGIC_VECTOR (1 DOWNTO 0) + ); + END COMPONENT; + +BEGIN + sub_wire7_bv(0 DOWNTO 0) <= "0"; + sub_wire7 <= To_stdlogicvector(sub_wire7_bv); + sub_wire4 <= sub_wire0(2); + sub_wire3 <= sub_wire0(0); + sub_wire2 <= sub_wire0(3); + sub_wire1 <= sub_wire0(1); + c1 <= sub_wire1; + c3 <= sub_wire2; + c0 <= sub_wire3; + c2 <= sub_wire4; + sub_wire5 <= inclk0; + sub_wire6 <= sub_wire7(0 DOWNTO 0) & sub_wire5; + + altpll_component : altpll + GENERIC MAP ( + bandwidth_type => "AUTO", + clk0_divide_by => 33, + clk0_duty_cycle => 50, + clk0_multiply_by => 2, + clk0_phase_shift => "0", + clk1_divide_by => 33, + clk1_duty_cycle => 50, + clk1_multiply_by => 16, + clk1_phase_shift => "0", + clk2_divide_by => 33, + clk2_duty_cycle => 50, + clk2_multiply_by => 25, + clk2_phase_shift => "0", + clk3_divide_by => 33000, + clk3_duty_cycle => 50, + clk3_multiply_by => 499, + clk3_phase_shift => "0", + compensate_clock => "CLK1", + inclk0_input_frequency => 30303, + intended_device_family => "Cyclone III", + lpm_type => "altpll", + operation_mode => "SOURCE_SYNCHRONOUS", + pll_type => "AUTO", + port_activeclock => "PORT_UNUSED", + port_areset => "PORT_UNUSED", + port_clkbad0 => "PORT_UNUSED", + port_clkbad1 => "PORT_UNUSED", + port_clkloss => "PORT_UNUSED", + port_clkswitch => "PORT_UNUSED", + port_configupdate => "PORT_UNUSED", + port_fbin => "PORT_UNUSED", + port_inclk0 => "PORT_USED", + port_inclk1 => "PORT_UNUSED", + port_locked => "PORT_UNUSED", + port_pfdena => "PORT_UNUSED", + port_phasecounterselect => "PORT_UNUSED", + port_phasedone => "PORT_UNUSED", + port_phasestep => "PORT_UNUSED", + port_phaseupdown => "PORT_UNUSED", + port_pllena => "PORT_UNUSED", + port_scanaclr => "PORT_UNUSED", + port_scanclk => "PORT_UNUSED", + port_scanclkena => "PORT_UNUSED", + port_scandata => "PORT_UNUSED", + port_scandataout => "PORT_UNUSED", + port_scandone => "PORT_UNUSED", + port_scanread => "PORT_UNUSED", + port_scanwrite => "PORT_UNUSED", + port_clk0 => "PORT_USED", + port_clk1 => "PORT_USED", + port_clk2 => "PORT_USED", + port_clk3 => "PORT_USED", + port_clk4 => "PORT_UNUSED", + port_clk5 => "PORT_UNUSED", + port_clkena0 => "PORT_UNUSED", + port_clkena1 => "PORT_UNUSED", + port_clkena2 => "PORT_UNUSED", + port_clkena3 => "PORT_UNUSED", + port_clkena4 => "PORT_UNUSED", + port_clkena5 => "PORT_UNUSED", + port_extclk0 => "PORT_UNUSED", + port_extclk1 => "PORT_UNUSED", + port_extclk2 => "PORT_UNUSED", + port_extclk3 => "PORT_UNUSED", + width_clock => 5 + ) + PORT MAP ( + inclk => sub_wire6, + clk => sub_wire0 + ); + + + +END SYN; + +-- ============================================================ +-- 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 "1" +-- 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_PRESET STRING "0" +-- Retrieval info: PRIVATE: CLKBAD_SWITCHOVER_CHECK STRING "0" +-- Retrieval info: PRIVATE: CLKLOSS_CHECK STRING "0" +-- Retrieval info: PRIVATE: CLKSWITCH_CHECK STRING "0" +-- 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 "c1" +-- Retrieval info: PRIVATE: CUR_FBIN_CLK STRING "e0" +-- Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "8" +-- Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "33" +-- Retrieval info: PRIVATE: DIV_FACTOR1 NUMERIC "33" +-- Retrieval info: PRIVATE: DIV_FACTOR2 NUMERIC "33" +-- Retrieval info: PRIVATE: DIV_FACTOR3 NUMERIC "33" +-- Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000" +-- Retrieval info: PRIVATE: DUTY_CYCLE1 STRING "50.00000000" +-- Retrieval info: PRIVATE: DUTY_CYCLE2 STRING "50.00000000" +-- Retrieval info: PRIVATE: DUTY_CYCLE3 STRING "50.00000000" +-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "2.000000" +-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE1 STRING "16.000000" +-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE2 STRING "25.000000" +-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE3 STRING "0.499000" +-- 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 "0" +-- Retrieval info: PRIVATE: GLOCKED_MODE_CHECK STRING "0" +-- Retrieval info: PRIVATE: GLOCK_COUNTER_EDIT NUMERIC "1048575" +-- Retrieval info: PRIVATE: HAS_MANUAL_SWITCHOVER STRING "1" +-- Retrieval info: PRIVATE: INCLK0_FREQ_EDIT STRING "33.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 III" +-- Retrieval info: PRIVATE: INT_FEEDBACK__MODE_RADIO STRING "1" +-- Retrieval info: PRIVATE: LOCKED_OUTPUT_CHECK STRING "0" +-- 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: LVDS_PHASE_SHIFT_UNIT1 STRING "deg" +-- Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT2 STRING "deg" +-- Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT3 STRING "ps" +-- Retrieval info: PRIVATE: MIG_DEVICE_SPEED_GRADE STRING "Any" +-- Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0" +-- Retrieval info: PRIVATE: MIRROR_CLK1 STRING "0" +-- Retrieval info: PRIVATE: MIRROR_CLK2 STRING "0" +-- Retrieval info: PRIVATE: MIRROR_CLK3 STRING "0" +-- Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "2" +-- Retrieval info: PRIVATE: MULT_FACTOR1 NUMERIC "16" +-- Retrieval info: PRIVATE: MULT_FACTOR2 NUMERIC "25" +-- Retrieval info: PRIVATE: MULT_FACTOR3 NUMERIC "48" +-- Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "0" +-- Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "2.00000000" +-- Retrieval info: PRIVATE: OUTPUT_FREQ1 STRING "16.00000000" +-- Retrieval info: PRIVATE: OUTPUT_FREQ2 STRING "25.00000000" +-- Retrieval info: PRIVATE: OUTPUT_FREQ3 STRING "0.49900000" +-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "1" +-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE1 STRING "1" +-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE2 STRING "1" +-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE3 STRING "1" +-- Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz" +-- Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT1 STRING "MHz" +-- Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT2 STRING "MHz" +-- Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT3 STRING "MHz" +-- Retrieval info: PRIVATE: PHASE_RECONFIG_FEATURE_ENABLED STRING "1" +-- Retrieval info: PRIVATE: PHASE_RECONFIG_INPUTS_CHECK STRING "0" +-- Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000" +-- Retrieval info: PRIVATE: PHASE_SHIFT1 STRING "0.00000000" +-- Retrieval info: PRIVATE: PHASE_SHIFT2 STRING "0.00000000" +-- Retrieval info: PRIVATE: PHASE_SHIFT3 STRING "0.00000000" +-- Retrieval info: PRIVATE: PHASE_SHIFT_STEP_ENABLED_CHECK STRING "0" +-- Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg" +-- Retrieval info: PRIVATE: PHASE_SHIFT_UNIT1 STRING "deg" +-- Retrieval info: PRIVATE: PHASE_SHIFT_UNIT2 STRING "deg" +-- Retrieval info: PRIVATE: PHASE_SHIFT_UNIT3 STRING "ps" +-- Retrieval info: PRIVATE: PLL_ADVANCED_PARAM_CHECK STRING "0" +-- Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "0" +-- Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1" +-- 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 "altpll3.mif" +-- Retrieval info: PRIVATE: SACN_INPUTS_CHECK STRING "0" +-- Retrieval info: PRIVATE: SCAN_FEATURE_ENABLED STRING "1" +-- 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 "1" +-- Retrieval info: PRIVATE: STICKY_CLK0 STRING "1" +-- Retrieval info: PRIVATE: STICKY_CLK1 STRING "1" +-- Retrieval info: PRIVATE: STICKY_CLK2 STRING "1" +-- Retrieval info: PRIVATE: STICKY_CLK3 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_CLK1 STRING "1" +-- Retrieval info: PRIVATE: USE_CLK2 STRING "1" +-- Retrieval info: PRIVATE: USE_CLK3 STRING "1" +-- Retrieval info: PRIVATE: USE_CLKENA0 STRING "0" +-- Retrieval info: PRIVATE: USE_CLKENA1 STRING "0" +-- Retrieval info: PRIVATE: USE_CLKENA2 STRING "0" +-- Retrieval info: PRIVATE: USE_CLKENA3 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: BANDWIDTH_TYPE STRING "AUTO" +-- Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "33" +-- 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: CLK1_DIVIDE_BY NUMERIC "33" +-- Retrieval info: CONSTANT: CLK1_DUTY_CYCLE NUMERIC "50" +-- Retrieval info: CONSTANT: CLK1_MULTIPLY_BY NUMERIC "16" +-- Retrieval info: CONSTANT: CLK1_PHASE_SHIFT STRING "0" +-- Retrieval info: CONSTANT: CLK2_DIVIDE_BY NUMERIC "33" +-- Retrieval info: CONSTANT: CLK2_DUTY_CYCLE NUMERIC "50" +-- Retrieval info: CONSTANT: CLK2_MULTIPLY_BY NUMERIC "25" +-- Retrieval info: CONSTANT: CLK2_PHASE_SHIFT STRING "0" +-- Retrieval info: CONSTANT: CLK3_DIVIDE_BY NUMERIC "33000" +-- Retrieval info: CONSTANT: CLK3_DUTY_CYCLE NUMERIC "50" +-- Retrieval info: CONSTANT: CLK3_MULTIPLY_BY NUMERIC "499" +-- Retrieval info: CONSTANT: CLK3_PHASE_SHIFT STRING "0" +-- Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK1" +-- Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "30303" +-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III" +-- Retrieval info: CONSTANT: LPM_TYPE STRING "altpll" +-- Retrieval info: CONSTANT: OPERATION_MODE STRING "SOURCE_SYNCHRONOUS" +-- Retrieval info: CONSTANT: PLL_TYPE STRING "AUTO" +-- Retrieval info: CONSTANT: PORT_ACTIVECLOCK STRING "PORT_UNUSED" +-- Retrieval info: CONSTANT: PORT_ARESET STRING "PORT_UNUSED" +-- 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_UNUSED" +-- 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_USED" +-- Retrieval info: CONSTANT: PORT_clk2 STRING "PORT_USED" +-- Retrieval info: CONSTANT: PORT_clk3 STRING "PORT_USED" +-- 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: WIDTH_CLOCK NUMERIC "5" +-- Retrieval info: USED_PORT: @clk 0 0 5 0 OUTPUT_CLK_EXT VCC "@clk[4..0]" +-- Retrieval info: USED_PORT: @inclk 0 0 2 0 INPUT_CLK_EXT VCC "@inclk[1..0]" +-- Retrieval info: USED_PORT: c0 0 0 0 0 OUTPUT_CLK_EXT VCC "c0" +-- Retrieval info: USED_PORT: c1 0 0 0 0 OUTPUT_CLK_EXT VCC "c1" +-- Retrieval info: USED_PORT: c2 0 0 0 0 OUTPUT_CLK_EXT VCC "c2" +-- Retrieval info: USED_PORT: c3 0 0 0 0 OUTPUT_CLK_EXT VCC "c3" +-- Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT_CLK_EXT GND "inclk0" +-- 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: c1 0 0 0 0 @clk 0 0 1 1 +-- Retrieval info: CONNECT: c2 0 0 0 0 @clk 0 0 1 2 +-- Retrieval info: CONNECT: c3 0 0 0 0 @clk 0 0 1 3 +-- Retrieval info: GEN_FILE: TYPE_NORMAL altpll3.vhd TRUE +-- Retrieval info: GEN_FILE: TYPE_NORMAL altpll3.ppf TRUE +-- Retrieval info: GEN_FILE: TYPE_NORMAL altpll3.inc TRUE +-- Retrieval info: GEN_FILE: TYPE_NORMAL altpll3.cmp TRUE +-- Retrieval info: GEN_FILE: TYPE_NORMAL altpll3.bsf TRUE +-- Retrieval info: GEN_FILE: TYPE_NORMAL altpll3_inst.vhd FALSE +-- Retrieval info: GEN_FILE: TYPE_NORMAL altpll3_waveforms.html TRUE +-- Retrieval info: GEN_FILE: TYPE_NORMAL altpll3_wave*.jpg FALSE +-- Retrieval info: LIB_FILE: altera_mf diff --git a/vhdl/rtl/vhdl/Firebee_V1/altpll4.mif b/vhdl/rtl/vhdl/Firebee_V1/altpll4.mif new file mode 100644 index 0000000..e51d0f2 --- /dev/null +++ b/vhdl/rtl/vhdl/Firebee_V1/altpll4.mif @@ -0,0 +1,174 @@ +-- Copyright (C) 1991-2013 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. + +-- MIF file representing initial state of PLL Scan Chain +-- Device Family: Cyclone III +-- Device Part: - +-- Device Speed Grade: 8 +-- PLL Scan Chain: Fast PLL (144 bits) +-- File Name: /home/mfro/Dokumente/Development/workspace/firebee_vhdl/rtl/vhdl/Firebee_V1/altpll4.mif +-- Generated: Sat Jun 7 08:17:17 2014 + +WIDTH=1; +DEPTH=144; + +ADDRESS_RADIX=UNS; +DATA_RADIX=UNS; + +CONTENT BEGIN + 0 : 0; -- Reserved Bits = 0 (1 bit(s)) + 1 : 0; -- Reserved Bits = 0 (1 bit(s)) + 2 : 0; -- Loop Filter Capacitance = 0 (2 bit(s)) (Setting 0) + 3 : 0; + 4 : 1; -- Loop Filter Resistance = 27 (5 bit(s)) (Setting 27) + 5 : 1; + 6 : 0; + 7 : 1; + 8 : 1; + 9 : 1; -- VCO Post Scale = 1 (1 bit(s)) (VCO post-scale divider counter value = 1) + 10 : 0; -- Reserved Bits = 0 (5 bit(s)) + 11 : 0; + 12 : 0; + 13 : 0; + 14 : 0; + 15 : 0; -- Charge Pump Current = 1 (3 bit(s)) (Setting 1) + 16 : 0; + 17 : 1; + 18 : 1; -- N counter: Bypass = 1 (1 bit(s)) + 19 : 0; -- N counter: High Count = 0 (8 bit(s)) + 20 : 0; + 21 : 0; + 22 : 0; + 23 : 0; + 24 : 0; + 25 : 0; + 26 : 0; + 27 : 0; -- N counter: Odd Division = 0 (1 bit(s)) + 28 : 0; -- N counter: Low Count = 0 (8 bit(s)) + 29 : 0; + 30 : 0; + 31 : 0; + 32 : 0; + 33 : 0; + 34 : 0; + 35 : 0; + 36 : 0; -- M counter: Bypass = 0 (1 bit(s)) + 37 : 0; -- M counter: High Count = 16 (8 bit(s)) + 38 : 0; + 39 : 0; + 40 : 1; + 41 : 0; + 42 : 0; + 43 : 0; + 44 : 0; + 45 : 0; -- M counter: Odd Division = 0 (1 bit(s)) + 46 : 0; -- M counter: Low Count = 16 (8 bit(s)) + 47 : 0; + 48 : 0; + 49 : 1; + 50 : 0; + 51 : 0; + 52 : 0; + 53 : 0; + 54 : 0; -- clk0 counter: Bypass = 0 (1 bit(s)) + 55 : 0; -- clk0 counter: High Count = 6 (8 bit(s)) + 56 : 0; + 57 : 0; + 58 : 0; + 59 : 0; + 60 : 1; + 61 : 1; + 62 : 0; + 63 : 1; -- clk0 counter: Odd Division = 1 (1 bit(s)) + 64 : 0; -- clk0 counter: Low Count = 5 (8 bit(s)) + 65 : 0; + 66 : 0; + 67 : 0; + 68 : 0; + 69 : 1; + 70 : 0; + 71 : 1; + 72 : 1; -- clk1 counter: Bypass = 1 (1 bit(s)) + 73 : 0; -- clk1 counter: High Count = 0 (8 bit(s)) + 74 : 0; + 75 : 0; + 76 : 0; + 77 : 0; + 78 : 0; + 79 : 0; + 80 : 0; + 81 : 0; -- clk1 counter: Odd Division = 0 (1 bit(s)) + 82 : 0; -- clk1 counter: Low Count = 0 (8 bit(s)) + 83 : 0; + 84 : 0; + 85 : 0; + 86 : 0; + 87 : 0; + 88 : 0; + 89 : 0; + 90 : 1; -- clk2 counter: Bypass = 1 (1 bit(s)) + 91 : 0; -- clk2 counter: High Count = 0 (8 bit(s)) + 92 : 0; + 93 : 0; + 94 : 0; + 95 : 0; + 96 : 0; + 97 : 0; + 98 : 0; + 99 : 0; -- clk2 counter: Odd Division = 0 (1 bit(s)) + 100 : 0; -- clk2 counter: Low Count = 0 (8 bit(s)) + 101 : 0; + 102 : 0; + 103 : 0; + 104 : 0; + 105 : 0; + 106 : 0; + 107 : 0; + 108 : 1; -- clk3 counter: Bypass = 1 (1 bit(s)) + 109 : 0; -- clk3 counter: High Count = 0 (8 bit(s)) + 110 : 0; + 111 : 0; + 112 : 0; + 113 : 0; + 114 : 0; + 115 : 0; + 116 : 0; + 117 : 0; -- clk3 counter: Odd Division = 0 (1 bit(s)) + 118 : 0; -- clk3 counter: Low Count = 0 (8 bit(s)) + 119 : 0; + 120 : 0; + 121 : 0; + 122 : 0; + 123 : 0; + 124 : 0; + 125 : 0; + 126 : 1; -- clk4 counter: Bypass = 1 (1 bit(s)) + 127 : 0; -- clk4 counter: High Count = 0 (8 bit(s)) + 128 : 0; + 129 : 0; + 130 : 0; + 131 : 0; + 132 : 0; + 133 : 0; + 134 : 0; + 135 : 0; -- clk4 counter: Odd Division = 0 (1 bit(s)) + 136 : 0; -- clk4 counter: Low Count = 0 (8 bit(s)) + 137 : 0; + 138 : 0; + 139 : 0; + 140 : 0; + 141 : 0; + 142 : 0; + 143 : 0; +END; diff --git a/vhdl/rtl/vhdl/Firebee_V1/altpll4.ppf b/vhdl/rtl/vhdl/Firebee_V1/altpll4.ppf new file mode 100644 index 0000000..03b008b --- /dev/null +++ b/vhdl/rtl/vhdl/Firebee_V1/altpll4.ppf @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/vhdl/rtl/vhdl/Firebee_V1/altpll4.qip b/vhdl/rtl/vhdl/Firebee_V1/altpll4.qip new file mode 100644 index 0000000..4995044 --- /dev/null +++ b/vhdl/rtl/vhdl/Firebee_V1/altpll4.qip @@ -0,0 +1,4 @@ +set_global_assignment -name IP_TOOL_NAME "ALTPLL" +set_global_assignment -name IP_TOOL_VERSION "13.1" +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "altpll4.vhd"] +set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "altpll4.ppf"] diff --git a/vhdl/rtl/vhdl/Firebee_V1/altpll4.vhd b/vhdl/rtl/vhdl/Firebee_V1/altpll4.vhd new file mode 100644 index 0000000..931584a --- /dev/null +++ b/vhdl/rtl/vhdl/Firebee_V1/altpll4.vhd @@ -0,0 +1,400 @@ +-- megafunction wizard: %ALTPLL% +-- GENERATION: STANDARD +-- VERSION: WM1.0 +-- MODULE: altpll + +-- ============================================================ +-- File Name: altpll4.vhd +-- Megafunction Name(s): +-- altpll +-- +-- Simulation Library Files(s): +-- altera_mf +-- ============================================================ +-- ************************************************************ +-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! +-- +-- 13.1.0 Build 162 10/23/2013 SJ Web Edition +-- ************************************************************ + + +--Copyright (C) 1991-2013 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. + + +LIBRARY ieee; +USE ieee.std_logic_1164.all; + +LIBRARY altera_mf; +USE altera_mf.all; + +ENTITY altpll4 IS + PORT + ( + areset : IN STD_LOGIC := '0'; + configupdate : IN STD_LOGIC := '0'; + inclk0 : IN STD_LOGIC := '0'; + scanclk : IN STD_LOGIC := '1'; + scanclkena : IN STD_LOGIC := '0'; + scandata : IN STD_LOGIC := '0'; + c0 : OUT STD_LOGIC ; + locked : OUT STD_LOGIC ; + scandataout : OUT STD_LOGIC ; + scandone : OUT STD_LOGIC + ); +END altpll4; + + +ARCHITECTURE SYN OF altpll4 IS + + SIGNAL sub_wire0 : STD_LOGIC_VECTOR (4 DOWNTO 0); + SIGNAL sub_wire1 : STD_LOGIC ; + SIGNAL sub_wire2 : STD_LOGIC ; + SIGNAL sub_wire3 : STD_LOGIC ; + SIGNAL sub_wire4 : STD_LOGIC ; + SIGNAL sub_wire5 : STD_LOGIC ; + SIGNAL sub_wire6 : STD_LOGIC_VECTOR (1 DOWNTO 0); + SIGNAL sub_wire7_bv : BIT_VECTOR (0 DOWNTO 0); + SIGNAL sub_wire7 : STD_LOGIC_VECTOR (0 DOWNTO 0); + + + + COMPONENT altpll + GENERIC ( + bandwidth_type : STRING; + clk0_divide_by : NATURAL; + clk0_duty_cycle : NATURAL; + clk0_multiply_by : NATURAL; + clk0_phase_shift : STRING; + inclk0_input_frequency : NATURAL; + intended_device_family : STRING; + lpm_hint : STRING; + lpm_type : STRING; + operation_mode : STRING; + pll_type : STRING; + port_activeclock : STRING; + port_areset : STRING; + port_clkbad0 : STRING; + port_clkbad1 : STRING; + port_clkloss : STRING; + port_clkswitch : STRING; + port_configupdate : STRING; + port_fbin : STRING; + port_inclk0 : STRING; + port_inclk1 : STRING; + port_locked : STRING; + port_pfdena : STRING; + port_phasecounterselect : STRING; + port_phasedone : STRING; + port_phasestep : STRING; + port_phaseupdown : STRING; + port_pllena : STRING; + port_scanaclr : STRING; + port_scanclk : STRING; + port_scanclkena : STRING; + port_scandata : STRING; + port_scandataout : STRING; + port_scandone : STRING; + port_scanread : STRING; + port_scanwrite : STRING; + port_clk0 : STRING; + port_clk1 : STRING; + port_clk2 : STRING; + port_clk3 : STRING; + port_clk4 : STRING; + port_clk5 : STRING; + port_clkena0 : STRING; + port_clkena1 : STRING; + port_clkena2 : STRING; + port_clkena3 : STRING; + port_clkena4 : STRING; + port_clkena5 : STRING; + port_extclk0 : STRING; + port_extclk1 : STRING; + port_extclk2 : STRING; + port_extclk3 : STRING; + self_reset_on_loss_lock : STRING; + width_clock : NATURAL; + scan_chain_mif_file : STRING + ); + PORT ( + areset : IN STD_LOGIC ; + configupdate : IN STD_LOGIC ; + inclk : IN STD_LOGIC_VECTOR (1 DOWNTO 0); + scanclk : IN STD_LOGIC ; + scanclkena : IN STD_LOGIC ; + scandata : IN STD_LOGIC ; + scandataout : OUT STD_LOGIC ; + scandone : OUT STD_LOGIC ; + clk : OUT STD_LOGIC_VECTOR (4 DOWNTO 0); + locked : OUT STD_LOGIC + ); + END COMPONENT; + +BEGIN + sub_wire7_bv(0 DOWNTO 0) <= "0"; + sub_wire7 <= To_stdlogicvector(sub_wire7_bv); + sub_wire1 <= sub_wire0(0); + c0 <= sub_wire1; + scandataout <= sub_wire2; + scandone <= sub_wire3; + locked <= sub_wire4; + sub_wire5 <= inclk0; + sub_wire6 <= sub_wire7(0 DOWNTO 0) & sub_wire5; + + altpll_component : altpll + GENERIC MAP ( + bandwidth_type => "AUTO", + clk0_divide_by => 11, + clk0_duty_cycle => 50, + clk0_multiply_by => 32, + clk0_phase_shift => "0", + inclk0_input_frequency => 30303, + intended_device_family => "Cyclone III", + lpm_hint => "CBX_MODULE_PREFIX=altpll4", + lpm_type => "altpll", + operation_mode => "NO_COMPENSATION", + pll_type => "AUTO", + port_activeclock => "PORT_UNUSED", + port_areset => "PORT_USED", + port_clkbad0 => "PORT_UNUSED", + port_clkbad1 => "PORT_UNUSED", + port_clkloss => "PORT_UNUSED", + port_clkswitch => "PORT_UNUSED", + port_configupdate => "PORT_USED", + port_fbin => "PORT_UNUSED", + port_inclk0 => "PORT_USED", + port_inclk1 => "PORT_UNUSED", + port_locked => "PORT_USED", + port_pfdena => "PORT_UNUSED", + port_phasecounterselect => "PORT_UNUSED", + port_phasedone => "PORT_UNUSED", + port_phasestep => "PORT_UNUSED", + port_phaseupdown => "PORT_UNUSED", + port_pllena => "PORT_UNUSED", + port_scanaclr => "PORT_UNUSED", + port_scanclk => "PORT_USED", + port_scanclkena => "PORT_USED", + port_scandata => "PORT_USED", + port_scandataout => "PORT_USED", + port_scandone => "PORT_USED", + port_scanread => "PORT_UNUSED", + port_scanwrite => "PORT_UNUSED", + port_clk0 => "PORT_USED", + port_clk1 => "PORT_UNUSED", + port_clk2 => "PORT_UNUSED", + port_clk3 => "PORT_UNUSED", + port_clk4 => "PORT_UNUSED", + port_clk5 => "PORT_UNUSED", + port_clkena0 => "PORT_UNUSED", + port_clkena1 => "PORT_UNUSED", + port_clkena2 => "PORT_UNUSED", + port_clkena3 => "PORT_UNUSED", + port_clkena4 => "PORT_UNUSED", + port_clkena5 => "PORT_UNUSED", + port_extclk0 => "PORT_UNUSED", + port_extclk1 => "PORT_UNUSED", + port_extclk2 => "PORT_UNUSED", + port_extclk3 => "PORT_UNUSED", + self_reset_on_loss_lock => "OFF", + width_clock => 5, + scan_chain_mif_file => "altpll4.mif" + ) + PORT MAP ( + areset => areset, + configupdate => configupdate, + inclk => sub_wire6, + scanclk => scanclk, + scanclkena => scanclkena, + scandata => scandata, + clk => sub_wire0, + scandataout => sub_wire2, + scandone => sub_wire3, + locked => sub_wire4 + ); + + + +END SYN; + +-- ============================================================ +-- 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 "1" +-- 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_PRESET STRING "0" +-- Retrieval info: PRIVATE: CLKBAD_SWITCHOVER_CHECK STRING "0" +-- Retrieval info: PRIVATE: CLKLOSS_CHECK STRING "0" +-- Retrieval info: PRIVATE: CLKSWITCH_CHECK STRING "0" +-- Retrieval info: PRIVATE: CNX_NO_COMPENSATE_RADIO STRING "1" +-- 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 "8" +-- Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "1" +-- Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000" +-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "96.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 "0" +-- Retrieval info: PRIVATE: GLOCKED_MODE_CHECK STRING "0" +-- Retrieval info: PRIVATE: GLOCK_COUNTER_EDIT NUMERIC "1048575" +-- Retrieval info: PRIVATE: HAS_MANUAL_SWITCHOVER STRING "1" +-- Retrieval info: PRIVATE: INCLK0_FREQ_EDIT STRING "33.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 III" +-- 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 "2" +-- Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "0" +-- Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "96.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 "1" +-- 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_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 "altpll4.mif" +-- Retrieval info: PRIVATE: SACN_INPUTS_CHECK STRING "1" +-- Retrieval info: PRIVATE: SCAN_FEATURE_ENABLED STRING "1" +-- 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: BANDWIDTH_TYPE STRING "AUTO" +-- Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "11" +-- Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50" +-- Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "32" +-- Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0" +-- Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "30303" +-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III" +-- Retrieval info: CONSTANT: LPM_TYPE STRING "altpll" +-- Retrieval info: CONSTANT: OPERATION_MODE STRING "NO_COMPENSATION" +-- Retrieval info: CONSTANT: PLL_TYPE STRING "AUTO" +-- 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_USED" +-- 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_USED" +-- Retrieval info: CONSTANT: PORT_SCANCLKENA STRING "PORT_USED" +-- Retrieval info: CONSTANT: PORT_SCANDATA STRING "PORT_USED" +-- Retrieval info: CONSTANT: PORT_SCANDATAOUT STRING "PORT_USED" +-- Retrieval info: CONSTANT: PORT_SCANDONE STRING "PORT_USED" +-- 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: SELF_RESET_ON_LOSS_LOCK STRING "OFF" +-- Retrieval info: CONSTANT: WIDTH_CLOCK NUMERIC "5" +-- Retrieval info: CONSTANT: scan_chain_mif_file STRING "altpll4.mif" +-- Retrieval info: USED_PORT: @clk 0 0 5 0 OUTPUT_CLK_EXT VCC "@clk[4..0]" +-- Retrieval info: USED_PORT: @inclk 0 0 2 0 INPUT_CLK_EXT VCC "@inclk[1..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: configupdate 0 0 0 0 INPUT GND "configupdate" +-- 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: USED_PORT: scanclk 0 0 0 0 INPUT_CLK_EXT VCC "scanclk" +-- Retrieval info: USED_PORT: scanclkena 0 0 0 0 INPUT GND "scanclkena" +-- Retrieval info: USED_PORT: scandata 0 0 0 0 INPUT GND "scandata" +-- Retrieval info: USED_PORT: scandataout 0 0 0 0 OUTPUT VCC "scandataout" +-- Retrieval info: USED_PORT: scandone 0 0 0 0 OUTPUT VCC "scandone" +-- Retrieval info: CONNECT: @areset 0 0 0 0 areset 0 0 0 0 +-- Retrieval info: CONNECT: @configupdate 0 0 0 0 configupdate 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: @scanclk 0 0 0 0 scanclk 0 0 0 0 +-- Retrieval info: CONNECT: @scanclkena 0 0 0 0 scanclkena 0 0 0 0 +-- Retrieval info: CONNECT: @scandata 0 0 0 0 scandata 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: CONNECT: scandataout 0 0 0 0 @scandataout 0 0 0 0 +-- Retrieval info: CONNECT: scandone 0 0 0 0 @scandone 0 0 0 0 +-- Retrieval info: GEN_FILE: TYPE_NORMAL altpll4.vhd TRUE +-- Retrieval info: GEN_FILE: TYPE_NORMAL altpll4.ppf TRUE +-- Retrieval info: GEN_FILE: TYPE_NORMAL altpll4.inc FALSE +-- Retrieval info: GEN_FILE: TYPE_NORMAL altpll4.cmp FALSE +-- Retrieval info: GEN_FILE: TYPE_NORMAL altpll4.bsf FALSE +-- Retrieval info: GEN_FILE: TYPE_NORMAL altpll4_inst.vhd FALSE +-- Retrieval info: GEN_FILE: TYPE_NORMAL altpll4.mif TRUE +-- Retrieval info: LIB_FILE: altera_mf +-- Retrieval info: CBX_MODULE_PREFIX: ON diff --git a/vhdl/rtl/vhdl/Firebee_V1/altpll_reconfig1.qip b/vhdl/rtl/vhdl/Firebee_V1/altpll_reconfig1.qip new file mode 100644 index 0000000..6e452de --- /dev/null +++ b/vhdl/rtl/vhdl/Firebee_V1/altpll_reconfig1.qip @@ -0,0 +1,3 @@ +set_global_assignment -name IP_TOOL_NAME "ALTPLL_RECONFIG" +set_global_assignment -name IP_TOOL_VERSION "13.1" +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "altpll_reconfig1.vhd"] diff --git a/vhdl/rtl/vhdl/Firebee_V1/altpll_reconfig1.vhd b/vhdl/rtl/vhdl/Firebee_V1/altpll_reconfig1.vhd new file mode 100644 index 0000000..3a22bac --- /dev/null +++ b/vhdl/rtl/vhdl/Firebee_V1/altpll_reconfig1.vhd @@ -0,0 +1,2239 @@ +-- megafunction wizard: %ALTPLL_RECONFIG% +-- GENERATION: STANDARD +-- VERSION: WM1.0 +-- MODULE: altpll_reconfig + +-- ============================================================ +-- File Name: altpll_reconfig1.vhd +-- Megafunction Name(s): +-- altpll_reconfig +-- +-- Simulation Library Files(s): +-- +-- ============================================================ +-- ************************************************************ +-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! +-- +-- 13.1.0 Build 162 10/23/2013 SJ Web Edition +-- ************************************************************ + + +--Copyright (C) 1991-2013 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. + + +--altpll_reconfig CBX_AUTO_BLACKBOX="ALL" device_family="Cyclone III" busy clock counter_param counter_type data_in data_out pll_areset pll_areset_in pll_configupdate pll_scanclk pll_scanclkena pll_scandata pll_scandataout pll_scandone read_param reconfig reset write_param +--VERSION_BEGIN 13.1 cbx_altpll_reconfig 2013:10:17:04:07:49:SJ cbx_altsyncram 2013:10:17:04:07:49:SJ cbx_cycloneii 2013:10:17:04:07:49:SJ cbx_lpm_add_sub 2013:10:17:04:07:49:SJ cbx_lpm_compare 2013:10:17:04:07:49:SJ cbx_lpm_counter 2013:10:17:04:07:49:SJ cbx_lpm_decode 2013:10:17:04:07:49:SJ cbx_lpm_mux 2013:10:17:04:07:49:SJ cbx_mgl 2013:10:17:04:34:36:SJ cbx_stratix 2013:10:17:04:07:49:SJ cbx_stratixii 2013:10:17:04:07:49:SJ cbx_stratixiii 2013:10:17:04:07:49:SJ cbx_stratixv 2013:10:17:04:07:49:SJ cbx_util_mgl 2013:10:17:04:07:49:SJ VERSION_END + + LIBRARY altera_mf; + USE altera_mf.all; + + LIBRARY cycloneiii; + USE cycloneiii.all; + + LIBRARY lpm; + USE lpm.all; + +--synthesis_resources = altsyncram 1 lpm_add_sub 2 lpm_compare 1 lpm_counter 7 lpm_decode 1 lut 3 reg 80 + LIBRARY ieee; + USE ieee.std_logic_1164.all; + + ENTITY altpll_reconfig1_pllrcfg_t4q IS + PORT + ( + busy : OUT STD_LOGIC; + clock : IN STD_LOGIC; + counter_param : IN STD_LOGIC_VECTOR (2 DOWNTO 0) := (OTHERS => '0'); + counter_type : IN STD_LOGIC_VECTOR (3 DOWNTO 0) := (OTHERS => '0'); + data_in : IN STD_LOGIC_VECTOR (8 DOWNTO 0) := (OTHERS => '0'); + data_out : OUT STD_LOGIC_VECTOR (8 DOWNTO 0); + pll_areset : OUT STD_LOGIC; + pll_areset_in : IN STD_LOGIC := '0'; + pll_configupdate : OUT STD_LOGIC; + pll_scanclk : OUT STD_LOGIC; + pll_scanclkena : OUT STD_LOGIC; + pll_scandata : OUT STD_LOGIC; + pll_scandataout : IN STD_LOGIC := '0'; + pll_scandone : IN STD_LOGIC := '0'; + read_param : IN STD_LOGIC := '0'; + reconfig : IN STD_LOGIC := '0'; + reset : IN STD_LOGIC; + write_param : IN STD_LOGIC := '0' + ); + END altpll_reconfig1_pllrcfg_t4q; + + ARCHITECTURE RTL OF altpll_reconfig1_pllrcfg_t4q IS + + ATTRIBUTE synthesis_clearbox : natural; + ATTRIBUTE synthesis_clearbox OF RTL : ARCHITECTURE IS 2; + ATTRIBUTE ALTERA_ATTRIBUTE : string; + ATTRIBUTE ALTERA_ATTRIBUTE OF RTL : ARCHITECTURE IS "ADV_NETLIST_OPT_ALLOWED=""NEVER_ALLOW"";suppress_da_rule_internal=C106;{-to le_comb10} PLL_SCAN_RECONFIG_COUNTER_REMAP_LCELL=2;{-to le_comb8} PLL_SCAN_RECONFIG_COUNTER_REMAP_LCELL=0;{-to le_comb9} PLL_SCAN_RECONFIG_COUNTER_REMAP_LCELL=1"; + + SIGNAL wire_altsyncram4_data_a : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_altsyncram4_q_a : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_le_comb10_combout : STD_LOGIC; + SIGNAL wire_le_comb8_combout : STD_LOGIC; + SIGNAL wire_le_comb9_combout : STD_LOGIC; + SIGNAL areset_init_state_1 : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL areset_state : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL C0_data_state : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL C0_ena_state : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL C1_data_state : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL C1_ena_state : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL wire_C1_ena_state_w_lg_q1766w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL C2_data_state : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL C2_ena_state : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL wire_C2_ena_state_w_lg_q1767w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL C3_data_state : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL C3_ena_state : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL C4_data_state : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL C4_ena_state : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL configupdate2_state : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL configupdate3_state : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL wire_configupdate3_state_w_lg_q1842w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL configupdate_state : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL counter_param_latch_reg : STD_LOGIC_VECTOR(2 DOWNTO 0) + -- synopsys translate_off + := (OTHERS => '0') + -- synopsys translate_on + ; + SIGNAL counter_type_latch_reg : STD_LOGIC_VECTOR(3 DOWNTO 0) + -- synopsys translate_off + := (OTHERS => '0') + -- synopsys translate_on + ; + SIGNAL idle_state : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + ATTRIBUTE ALTERA_ATTRIBUTE OF idle_state : SIGNAL IS "POWER_UP_LEVEL=LOW"; + + SIGNAL wire_idle_state_w_lg_w_lg_w_lg_w_lg_q1731w1732w1733w1734w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_idle_state_w_lg_w_lg_w_lg_q1731w1732w1733w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_idle_state_w_lg_w_lg_q1731w1732w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_idle_state_w_lg_q1731w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_idle_state_w_lg_q1672w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_idle_state_w1735w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_idle_state_w_lg_w1735w1736w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_idle_state_w_lg_w_lg_w1735w1736w1737w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_idle_state_w_lg_w_lg_w_lg_w1735w1736w1737w1738w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL nominal_data0 : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL nominal_data1 : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL nominal_data2 : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL nominal_data3 : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL nominal_data4 : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL nominal_data5 : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL nominal_data6 : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL nominal_data7 : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL nominal_data8 : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL nominal_data9 : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL nominal_data10 : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL nominal_data11 : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL nominal_data12 : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL nominal_data13 : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL nominal_data14 : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL nominal_data15 : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL nominal_data16 : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL nominal_data17 : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL read_data_nominal_state : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + ATTRIBUTE ALTERA_ATTRIBUTE OF read_data_nominal_state : SIGNAL IS "POWER_UP_LEVEL=LOW"; + + SIGNAL wire_read_data_nominal_state_w_lg_q1752w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_read_data_nominal_state_w_lg_q1686w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL read_data_state : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + ATTRIBUTE ALTERA_ATTRIBUTE OF read_data_state : SIGNAL IS "POWER_UP_LEVEL=LOW"; + + SIGNAL wire_read_data_state_w_lg_q1745w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_read_data_state_w_lg_q1678w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL read_first_nominal_state : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + ATTRIBUTE ALTERA_ATTRIBUTE OF read_first_nominal_state : SIGNAL IS "POWER_UP_LEVEL=LOW"; + + SIGNAL wire_read_first_nominal_state_w_lg_q1753w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_read_first_nominal_state_w_lg_q1684w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL read_first_state : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + ATTRIBUTE ALTERA_ATTRIBUTE OF read_first_state : SIGNAL IS "POWER_UP_LEVEL=LOW"; + + SIGNAL wire_read_first_state_w_lg_q1746w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_read_first_state_w_lg_q1676w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL read_init_nominal_state : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + ATTRIBUTE ALTERA_ATTRIBUTE OF read_init_nominal_state : SIGNAL IS "POWER_UP_LEVEL=LOW"; + + SIGNAL wire_read_init_nominal_state_w_lg_q1682w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL read_init_state : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + ATTRIBUTE ALTERA_ATTRIBUTE OF read_init_state : SIGNAL IS "POWER_UP_LEVEL=LOW"; + + SIGNAL wire_read_init_state_w_lg_q1674w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_read_init_state_w_lg_q1848w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL read_last_nominal_state : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + ATTRIBUTE ALTERA_ATTRIBUTE OF read_last_nominal_state : SIGNAL IS "POWER_UP_LEVEL=LOW"; + + SIGNAL wire_read_last_nominal_state_w_lg_q1865w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_read_last_nominal_state_w_lg_q1688w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL read_last_state : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + ATTRIBUTE ALTERA_ATTRIBUTE OF read_last_state : SIGNAL IS "POWER_UP_LEVEL=LOW"; + + SIGNAL wire_read_last_state_w_lg_q1680w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL reconfig_counter_state : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + ATTRIBUTE ALTERA_ATTRIBUTE OF reconfig_counter_state : SIGNAL IS "POWER_UP_LEVEL=LOW"; + + SIGNAL wire_reconfig_counter_state_w_lg_q1700w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL reconfig_init_state : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + ATTRIBUTE ALTERA_ATTRIBUTE OF reconfig_init_state : SIGNAL IS "POWER_UP_LEVEL=LOW"; + + SIGNAL wire_reconfig_init_state_w_lg_q1698w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL reconfig_post_state : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + ATTRIBUTE ALTERA_ATTRIBUTE OF reconfig_post_state : SIGNAL IS "POWER_UP_LEVEL=LOW"; + + SIGNAL wire_reconfig_post_state_w_lg_q1829w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_reconfig_post_state_w_lg_q1706w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL reconfig_seq_data_state : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + ATTRIBUTE ALTERA_ATTRIBUTE OF reconfig_seq_data_state : SIGNAL IS "POWER_UP_LEVEL=LOW"; + + SIGNAL wire_reconfig_seq_data_state_w_lg_q1704w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL reconfig_seq_ena_state : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + ATTRIBUTE ALTERA_ATTRIBUTE OF reconfig_seq_ena_state : SIGNAL IS "POWER_UP_LEVEL=LOW"; + + SIGNAL wire_reconfig_seq_ena_state_w_lg_q1856w : STD_LOGIC_VECTOR (7 DOWNTO 0); + SIGNAL wire_reconfig_seq_ena_state_w_lg_q1857w : STD_LOGIC_VECTOR (5 DOWNTO 0); + SIGNAL wire_reconfig_seq_ena_state_w_lg_q1702w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL reconfig_wait_state : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + ATTRIBUTE ALTERA_ATTRIBUTE OF reconfig_wait_state : SIGNAL IS "POWER_UP_LEVEL=LOW"; + + SIGNAL wire_reconfig_wait_state_w_lg_q1833w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_reconfig_wait_state_w_lg_q1708w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL reset_state : STD_LOGIC + -- synopsys translate_off + := '1' + -- synopsys translate_on + ; + ATTRIBUTE ALTERA_ATTRIBUTE OF reset_state : SIGNAL IS "POWER_UP_LEVEL=HIGH"; + + SIGNAL wire_reset_state_w_lg_q1671w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL shift_reg0 : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL wire_shift_reg_w_lg_q217w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_shift_reg_w_lg_w_lg_q217w218w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL shift_reg1 : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL wire_shift_reg_w_lg_q223w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_shift_reg_w_lg_w_lg_q223w224w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL shift_reg2 : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL wire_shift_reg_w_lg_q228w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_shift_reg_w_lg_w_lg_q228w229w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL shift_reg3 : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL wire_shift_reg_w_lg_q233w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_shift_reg_w_lg_w_lg_q233w234w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL shift_reg4 : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL wire_shift_reg_w_lg_q238w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_shift_reg_w_lg_w_lg_q238w239w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL shift_reg5 : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL wire_shift_reg_w_lg_q243w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_shift_reg_w_lg_w_lg_q243w244w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL shift_reg6 : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL wire_shift_reg_w_lg_q248w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_shift_reg_w_lg_w_lg_q248w249w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL shift_reg7 : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL wire_shift_reg_w_lg_q253w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_shift_reg_w_lg_w_lg_q253w254w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL shift_reg8 : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL wire_shift_reg_w_lg_q258w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_shift_reg_w_lg_w_lg_q258w259w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL shift_reg9 : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL shift_reg10 : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL shift_reg11 : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL shift_reg12 : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL shift_reg13 : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL shift_reg14 : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL shift_reg15 : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL shift_reg16 : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL shift_reg17 : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL wire_shift_reg_w_lg_q262w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_shift_reg_w_lg_q264w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_shift_reg_w_lg_q267w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_shift_reg_w_lg_q270w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_shift_reg_w_lg_q273w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_shift_reg_w_lg_q276w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_shift_reg_w_lg_q279w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_shift_reg_w_lg_q282w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_shift_reg_ena : STD_LOGIC_VECTOR(17 DOWNTO 0); + SIGNAL tmp_nominal_data_out_state : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL tmp_seq_ena_state : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + SIGNAL write_data_state : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + ATTRIBUTE ALTERA_ATTRIBUTE OF write_data_state : SIGNAL IS "POWER_UP_LEVEL=LOW"; + + SIGNAL wire_write_data_state_w_lg_q1726w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_write_data_state_w_lg_q1692w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL write_init_nominal_state : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + ATTRIBUTE ALTERA_ATTRIBUTE OF write_init_nominal_state : SIGNAL IS "POWER_UP_LEVEL=LOW"; + + SIGNAL wire_write_init_nominal_state_w_lg_q1694w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL write_init_state : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + ATTRIBUTE ALTERA_ATTRIBUTE OF write_init_state : SIGNAL IS "POWER_UP_LEVEL=LOW"; + + SIGNAL wire_write_init_state_w_lg_q1690w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_write_init_state_w_lg_q1853w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL write_nominal_state : STD_LOGIC + -- synopsys translate_off + := '0' + -- synopsys translate_on + ; + ATTRIBUTE ALTERA_ATTRIBUTE OF write_nominal_state : SIGNAL IS "POWER_UP_LEVEL=LOW"; + + SIGNAL wire_write_nominal_state_w_lg_q1725w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_write_nominal_state_w_lg_q1696w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_add_sub5_w_lg_w_result_range214w215w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_add_sub5_w_lg_w_result_range221w222w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_add_sub5_w_lg_w_result_range226w227w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_add_sub5_w_lg_w_result_range231w232w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_add_sub5_w_lg_w_result_range236w237w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_add_sub5_w_lg_w_result_range241w242w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_add_sub5_w_lg_w_result_range246w247w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_add_sub5_w_lg_w_result_range251w252w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_add_sub5_w_lg_w_result_range256w257w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_gnd : STD_LOGIC; + SIGNAL wire_add_sub5_dataa : STD_LOGIC_VECTOR (8 DOWNTO 0); + SIGNAL wire_add_sub5_datab : STD_LOGIC_VECTOR (8 DOWNTO 0); + SIGNAL wire_add_sub5_result : STD_LOGIC_VECTOR (8 DOWNTO 0); + SIGNAL wire_add_sub5_w_result_range214w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_add_sub5_w_result_range221w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_add_sub5_w_result_range226w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_add_sub5_w_result_range231w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_add_sub5_w_result_range236w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_add_sub5_w_result_range241w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_add_sub5_w_result_range246w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_add_sub5_w_result_range251w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_add_sub5_w_result_range256w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_add_sub6_dataa : STD_LOGIC_VECTOR (7 DOWNTO 0); + SIGNAL wire_add_sub6_result : STD_LOGIC_VECTOR (7 DOWNTO 0); + SIGNAL wire_cmpr7_aeb : STD_LOGIC; + SIGNAL wire_cmpr7_dataa : STD_LOGIC_VECTOR (7 DOWNTO 0); + SIGNAL wire_cmpr7_datab : STD_LOGIC_VECTOR (7 DOWNTO 0); + SIGNAL wire_cntr1_q : STD_LOGIC_VECTOR (7 DOWNTO 0); + SIGNAL wire_cntr12_q : STD_LOGIC_VECTOR (7 DOWNTO 0); + SIGNAL wire_cntr13_q : STD_LOGIC_VECTOR (5 DOWNTO 0); + SIGNAL wire_cntr14_q : STD_LOGIC_VECTOR (4 DOWNTO 0); + SIGNAL wire_cntr15_q : STD_LOGIC_VECTOR (7 DOWNTO 0); + SIGNAL wire_cntr2_q : STD_LOGIC_VECTOR (7 DOWNTO 0); + SIGNAL wire_cntr3_q : STD_LOGIC_VECTOR (4 DOWNTO 0); + SIGNAL wire_decode11_eq : STD_LOGIC_VECTOR (4 DOWNTO 0); + SIGNAL wire_w_lg_addr_counter_out1880w : STD_LOGIC_VECTOR (7 DOWNTO 0); + SIGNAL wire_w_lg_addr_decoder_out1854w : STD_LOGIC_VECTOR (7 DOWNTO 0); + SIGNAL wire_w_lg_c0_wire1808w : STD_LOGIC_VECTOR (7 DOWNTO 0); + SIGNAL wire_w_lg_c1_wire1806w : STD_LOGIC_VECTOR (7 DOWNTO 0); + SIGNAL wire_w_lg_c2_wire1804w : STD_LOGIC_VECTOR (7 DOWNTO 0); + SIGNAL wire_w_lg_c3_wire1802w : STD_LOGIC_VECTOR (7 DOWNTO 0); + SIGNAL wire_w_lg_c4_wire1800w : STD_LOGIC_VECTOR (7 DOWNTO 0); + SIGNAL wire_w_lg_read_addr_counter_out1879w : STD_LOGIC_VECTOR (7 DOWNTO 0); + SIGNAL wire_w_lg_read_addr_decoder_out1849w : STD_LOGIC_VECTOR (7 DOWNTO 0); + SIGNAL wire_w_lg_reconfig_addr_counter_out1877w : STD_LOGIC_VECTOR (7 DOWNTO 0); + SIGNAL wire_w_lg_rotate_addr_counter_out1878w : STD_LOGIC_VECTOR (7 DOWNTO 0); + SIGNAL wire_w_lg_shift_reg_load_enable187w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_shift_reg_load_enable179w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_shift_reg_load_enable171w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_shift_reg_load_enable163w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_shift_reg_load_enable155w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_shift_reg_load_enable147w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_shift_reg_load_enable139w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_shift_reg_load_enable131w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_shift_reg_load_enable123w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_w_counter_param_latch_range294w379w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_w_counter_type_latch_range284w710w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_dummy_scandataout1873w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_pll_scandone1875w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_read_nominal_out216w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_read_param1730w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_reconfig1728w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_reconfig_done1832w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_reconfig_post_done1828w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_reconfig_width_counter_done1825w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_reset1w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_rotate_width_counter_done1776w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_width_counter_done1744w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_write_from_rom1727w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_write_param1729w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_w_counter_param_latch_range296w297w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_w_counter_type_latch_range286w530w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_w_lg_w_lg_w1329w1392w1452w1516w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_w_lg_w1329w1392w1452w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_w_lg_w_lg_w1361w1422w1483w1550w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_w1329w1392w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_w_lg_w1361w1422w1483w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w1329w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_w1361w1422w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_w_lg_w_lg_w_lg_w980w1055w1126w1195w1261w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w1361w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_w_lg_w_lg_w980w1055w1126w1195w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_w_lg_w_lg_w_lg_w1016w1091w1160w1228w1294w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_w_lg_w980w1055w1126w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_w_lg_w_lg_w1016w1091w1160w1228w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_w980w1055w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_w_lg_w1016w1091w1160w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w980w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_w1016w1091w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_w_lg_w_lg_w_lg_w_lg_w423w570w637w749w817w920w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w1016w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w63w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_w_lg_w_lg_w_lg_w423w570w637w749w817w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_w_lg_w_lg_w_lg_w571w672w784w850w951w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_w_lg_w_lg_shift_reg_load_enable60w61w62w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_w_lg_w_lg_w423w570w637w749w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_w_lg_w_lg_w571w672w784w850w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_w_lg_shift_reg_load_enable60w61w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_w_lg_w423w570w637w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_w_lg_w571w672w784w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_dummy_scandataout1874w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_shift_reg_load_enable60w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_w301w378w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_w381w495w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_w423w570w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_w571w672w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_lg_w675w885w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL addr_counter_enable : STD_LOGIC; + SIGNAL addr_counter_out : STD_LOGIC_VECTOR (7 DOWNTO 0); + SIGNAL addr_counter_sload : STD_LOGIC; + SIGNAL addr_counter_sload_value : STD_LOGIC_VECTOR (7 DOWNTO 0); + SIGNAL addr_decoder_out : STD_LOGIC_VECTOR (7 DOWNTO 0); + SIGNAL c0_wire : STD_LOGIC_VECTOR (7 DOWNTO 0); + SIGNAL c1_wire : STD_LOGIC_VECTOR (7 DOWNTO 0); + SIGNAL c2_wire : STD_LOGIC_VECTOR (7 DOWNTO 0); + SIGNAL c3_wire : STD_LOGIC_VECTOR (7 DOWNTO 0); + SIGNAL c4_wire : STD_LOGIC_VECTOR (7 DOWNTO 0); + SIGNAL counter_param_latch : STD_LOGIC_VECTOR (2 DOWNTO 0); + SIGNAL counter_type_latch : STD_LOGIC_VECTOR (3 DOWNTO 0); + SIGNAL cuda_combout_wire : STD_LOGIC_VECTOR (2 DOWNTO 0); + SIGNAL dummy_scandataout : STD_LOGIC; + SIGNAL encode_out : STD_LOGIC_VECTOR (2 DOWNTO 0); + SIGNAL input_latch_enable : STD_LOGIC; + SIGNAL power_up : STD_LOGIC; + SIGNAL read_addr_counter_enable : STD_LOGIC; + SIGNAL read_addr_counter_out : STD_LOGIC_VECTOR (7 DOWNTO 0); + SIGNAL read_addr_counter_sload : STD_LOGIC; + SIGNAL read_addr_counter_sload_value : STD_LOGIC_VECTOR (7 DOWNTO 0); + SIGNAL read_addr_decoder_out : STD_LOGIC_VECTOR (7 DOWNTO 0); + SIGNAL read_nominal_out : STD_LOGIC; + SIGNAL reconfig_addr_counter_enable : STD_LOGIC; + SIGNAL reconfig_addr_counter_out : STD_LOGIC_VECTOR (7 DOWNTO 0); + SIGNAL reconfig_addr_counter_sload : STD_LOGIC; + SIGNAL reconfig_addr_counter_sload_value : STD_LOGIC_VECTOR (7 DOWNTO 0); + SIGNAL reconfig_done : STD_LOGIC; + SIGNAL reconfig_post_done : STD_LOGIC; + SIGNAL reconfig_width_counter_done : STD_LOGIC; + SIGNAL reconfig_width_counter_enable : STD_LOGIC; + SIGNAL reconfig_width_counter_sload : STD_LOGIC; + SIGNAL reconfig_width_counter_sload_value : STD_LOGIC_VECTOR (5 DOWNTO 0); + SIGNAL rotate_addr_counter_enable : STD_LOGIC; + SIGNAL rotate_addr_counter_out : STD_LOGIC_VECTOR (7 DOWNTO 0); + SIGNAL rotate_addr_counter_sload : STD_LOGIC; + SIGNAL rotate_addr_counter_sload_value : STD_LOGIC_VECTOR (7 DOWNTO 0); + SIGNAL rotate_decoder_wires : STD_LOGIC_VECTOR (4 DOWNTO 0); + SIGNAL rotate_width_counter_done : STD_LOGIC; + SIGNAL rotate_width_counter_enable : STD_LOGIC; + SIGNAL rotate_width_counter_sload : STD_LOGIC; + SIGNAL rotate_width_counter_sload_value : STD_LOGIC_VECTOR (4 DOWNTO 0); + SIGNAL scan_cache_address : STD_LOGIC_VECTOR (7 DOWNTO 0); + SIGNAL scan_cache_in : STD_LOGIC; + SIGNAL scan_cache_out : STD_LOGIC; + SIGNAL scan_cache_write_enable : STD_LOGIC; + SIGNAL sel_param_bypass_LF_unused : STD_LOGIC; + SIGNAL sel_param_c : STD_LOGIC; + SIGNAL sel_param_high_i_postscale : STD_LOGIC; + SIGNAL sel_param_low_r : STD_LOGIC; + SIGNAL sel_param_nominal_count : STD_LOGIC; + SIGNAL sel_param_odd_CP_unused : STD_LOGIC; + SIGNAL sel_type_c0 : STD_LOGIC; + SIGNAL sel_type_c1 : STD_LOGIC; + SIGNAL sel_type_c2 : STD_LOGIC; + SIGNAL sel_type_c3 : STD_LOGIC; + SIGNAL sel_type_c4 : STD_LOGIC; + SIGNAL sel_type_cplf : STD_LOGIC; + SIGNAL sel_type_m : STD_LOGIC; + SIGNAL sel_type_n : STD_LOGIC; + SIGNAL sel_type_vco : STD_LOGIC; + SIGNAL seq_addr_wire : STD_LOGIC_VECTOR (7 DOWNTO 0); + SIGNAL seq_sload_value : STD_LOGIC_VECTOR (5 DOWNTO 0); + SIGNAL shift_reg_clear : STD_LOGIC; + SIGNAL shift_reg_load_enable : STD_LOGIC; + SIGNAL shift_reg_load_nominal_enable : STD_LOGIC; + SIGNAL shift_reg_serial_in : STD_LOGIC; + SIGNAL shift_reg_serial_out : STD_LOGIC; + SIGNAL shift_reg_shift_enable : STD_LOGIC; + SIGNAL shift_reg_shift_nominal_enable : STD_LOGIC; + SIGNAL shift_reg_width_select : STD_LOGIC_VECTOR (7 DOWNTO 0); + SIGNAL w1019w : STD_LOGIC; + SIGNAL w1056w : STD_LOGIC; + SIGNAL w1092w : STD_LOGIC; + SIGNAL w1127w : STD_LOGIC; + SIGNAL w1163w : STD_LOGIC; + SIGNAL w1196w : STD_LOGIC; + SIGNAL w1229w : STD_LOGIC; + SIGNAL w1262w : STD_LOGIC; + SIGNAL w1297w : STD_LOGIC; + SIGNAL w1330w : STD_LOGIC; + SIGNAL w1362w : STD_LOGIC; + SIGNAL w1393w : STD_LOGIC; + SIGNAL w1424w : STD_LOGIC; + SIGNAL w1453w : STD_LOGIC; + SIGNAL w1484w : STD_LOGIC; + SIGNAL w1517w : STD_LOGIC; + SIGNAL w1565w : STD_LOGIC; + SIGNAL w1592w : STD_LOGIC; + SIGNAL w301w : STD_LOGIC; + SIGNAL w341w : STD_LOGIC; + SIGNAL w381w : STD_LOGIC; + SIGNAL w423w : STD_LOGIC; + SIGNAL w460w : STD_LOGIC; + SIGNAL w496w : STD_LOGIC; + SIGNAL w534w : STD_LOGIC; + SIGNAL w571w : STD_LOGIC; + SIGNAL w605w : STD_LOGIC; + SIGNAL w638w : STD_LOGIC; + SIGNAL w64w : STD_LOGIC; + SIGNAL w675w : STD_LOGIC; + SIGNAL w713w : STD_LOGIC; + SIGNAL w750w : STD_LOGIC; + SIGNAL w785w : STD_LOGIC; + SIGNAL w818w : STD_LOGIC; + SIGNAL w851w : STD_LOGIC; + SIGNAL w888w : STD_LOGIC; + SIGNAL w921w : STD_LOGIC; + SIGNAL w952w : STD_LOGIC; + SIGNAL w981w : STD_LOGIC; + SIGNAL width_counter_done : STD_LOGIC; + SIGNAL width_counter_enable : STD_LOGIC; + SIGNAL width_counter_sload : STD_LOGIC; + SIGNAL width_counter_sload_value : STD_LOGIC_VECTOR (4 DOWNTO 0); + SIGNAL width_decoder_out : STD_LOGIC_VECTOR (4 DOWNTO 0); + SIGNAL width_decoder_select : STD_LOGIC_VECTOR (7 DOWNTO 0); + SIGNAL write_from_rom : STD_LOGIC; + SIGNAL wire_w_counter_param_latch_range294w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_counter_param_latch_range296w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_counter_type_latch_range284w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_counter_type_latch_range286w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_data_in_range186w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_data_in_range178w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_data_in_range170w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_data_in_range162w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_data_in_range154w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_data_in_range146w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_data_in_range138w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_data_in_range130w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_data_in_range122w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_rotate_decoder_wires_range1807w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_rotate_decoder_wires_range1805w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_rotate_decoder_wires_range1803w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_rotate_decoder_wires_range1801w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_rotate_decoder_wires_range1799w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_shift_reg_width_select_range261w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_shift_reg_width_select_range263w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_shift_reg_width_select_range266w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_shift_reg_width_select_range269w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_shift_reg_width_select_range272w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_shift_reg_width_select_range275w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_shift_reg_width_select_range278w : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL wire_w_shift_reg_width_select_range281w : STD_LOGIC_VECTOR (0 DOWNTO 0); + COMPONENT altsyncram + GENERIC + ( + ADDRESS_ACLR_A : STRING := "UNUSED"; + ADDRESS_ACLR_B : STRING := "NONE"; + ADDRESS_REG_B : STRING := "CLOCK1"; + BYTE_SIZE : NATURAL := 8; + BYTEENA_ACLR_A : STRING := "UNUSED"; + BYTEENA_ACLR_B : STRING := "NONE"; + BYTEENA_REG_B : STRING := "CLOCK1"; + CLOCK_ENABLE_CORE_A : STRING := "USE_INPUT_CLKEN"; + CLOCK_ENABLE_CORE_B : STRING := "USE_INPUT_CLKEN"; + CLOCK_ENABLE_INPUT_A : STRING := "NORMAL"; + CLOCK_ENABLE_INPUT_B : STRING := "NORMAL"; + CLOCK_ENABLE_OUTPUT_A : STRING := "NORMAL"; + CLOCK_ENABLE_OUTPUT_B : STRING := "NORMAL"; + ECC_PIPELINE_STAGE_ENABLED : STRING := "FALSE"; + ENABLE_ECC : STRING := "FALSE"; + IMPLEMENT_IN_LES : STRING := "OFF"; + INDATA_ACLR_A : STRING := "UNUSED"; + INDATA_ACLR_B : STRING := "NONE"; + INDATA_REG_B : STRING := "CLOCK1"; + INIT_FILE : STRING := "UNUSED"; + INIT_FILE_LAYOUT : STRING := "PORT_A"; + MAXIMUM_DEPTH : NATURAL := 0; + NUMWORDS_A : NATURAL := 0; + NUMWORDS_B : NATURAL := 0; + OPERATION_MODE : STRING := "BIDIR_DUAL_PORT"; + OUTDATA_ACLR_A : STRING := "NONE"; + OUTDATA_ACLR_B : STRING := "NONE"; + OUTDATA_REG_A : STRING := "UNREGISTERED"; + OUTDATA_REG_B : STRING := "UNREGISTERED"; + POWER_UP_UNINITIALIZED : STRING := "FALSE"; + RAM_BLOCK_TYPE : STRING := "AUTO"; + RDCONTROL_ACLR_B : STRING := "NONE"; + RDCONTROL_REG_B : STRING := "CLOCK1"; + READ_DURING_WRITE_MODE_MIXED_PORTS : STRING := "DONT_CARE"; + read_during_write_mode_port_a : STRING := "NEW_DATA_NO_NBE_READ"; + read_during_write_mode_port_b : STRING := "NEW_DATA_NO_NBE_READ"; + WIDTH_A : NATURAL; + WIDTH_B : NATURAL := 1; + WIDTH_BYTEENA_A : NATURAL := 1; + WIDTH_BYTEENA_B : NATURAL := 1; + WIDTH_ECCSTATUS : NATURAL := 3; + WIDTHAD_A : NATURAL; + WIDTHAD_B : NATURAL := 1; + WRCONTROL_ACLR_A : STRING := "UNUSED"; + WRCONTROL_ACLR_B : STRING := "NONE"; + WRCONTROL_WRADDRESS_REG_B : STRING := "CLOCK1"; + INTENDED_DEVICE_FAMILY : STRING := "Cyclone III"; + lpm_hint : STRING := "UNUSED"; + lpm_type : STRING := "altsyncram" + ); + PORT + ( + aclr0 : IN STD_LOGIC := '0'; + aclr1 : IN STD_LOGIC := '0'; + address_a : IN STD_LOGIC_VECTOR(WIDTHAD_A-1 DOWNTO 0); + address_b : IN STD_LOGIC_VECTOR(WIDTHAD_B-1 DOWNTO 0) := (OTHERS => '1'); + addressstall_a : IN STD_LOGIC := '0'; + addressstall_b : IN STD_LOGIC := '0'; + byteena_a : IN STD_LOGIC_VECTOR(WIDTH_BYTEENA_A-1 DOWNTO 0) := (OTHERS => '1'); + byteena_b : IN STD_LOGIC_VECTOR(WIDTH_BYTEENA_B-1 DOWNTO 0) := (OTHERS => '1'); + clock0 : IN STD_LOGIC := '1'; + clock1 : IN STD_LOGIC := '1'; + clocken0 : IN STD_LOGIC := '1'; + clocken1 : IN STD_LOGIC := '1'; + clocken2 : IN STD_LOGIC := '1'; + clocken3 : IN STD_LOGIC := '1'; + data_a : IN STD_LOGIC_VECTOR(WIDTH_A-1 DOWNTO 0) := (OTHERS => '1'); + data_b : IN STD_LOGIC_VECTOR(WIDTH_B-1 DOWNTO 0) := (OTHERS => '1'); + eccstatus : OUT STD_LOGIC_VECTOR(WIDTH_ECCSTATUS-1 DOWNTO 0); + q_a : OUT STD_LOGIC_VECTOR(WIDTH_A-1 DOWNTO 0); + q_b : OUT STD_LOGIC_VECTOR(WIDTH_B-1 DOWNTO 0); + rden_a : IN STD_LOGIC := '1'; + rden_b : IN STD_LOGIC := '1'; + wren_a : IN STD_LOGIC := '0'; + wren_b : IN STD_LOGIC := '0' + ); + END COMPONENT; + COMPONENT cycloneiii_lcell_comb + GENERIC + ( + DONT_TOUCH : STRING := "off"; + LUT_MASK : STD_LOGIC_VECTOR(15 DOWNTO 0) := "0000000000000000"; + SUM_LUTC_INPUT : STRING := "datac"; + lpm_type : STRING := "cycloneiii_lcell_comb" + ); + PORT + ( + cin : IN STD_LOGIC := '0'; + combout : OUT STD_LOGIC; + cout : OUT STD_LOGIC; + dataa : IN STD_LOGIC := '0'; + datab : IN STD_LOGIC := '0'; + datac : IN STD_LOGIC := '0'; + datad : IN STD_LOGIC := '0' + ); + END COMPONENT; + COMPONENT lpm_add_sub + GENERIC + ( + LPM_DIRECTION : STRING := "DEFAULT"; + LPM_PIPELINE : NATURAL := 0; + LPM_REPRESENTATION : STRING := "SIGNED"; + LPM_WIDTH : NATURAL; + lpm_hint : STRING := "UNUSED"; + lpm_type : STRING := "lpm_add_sub" + ); + PORT + ( + aclr : IN STD_LOGIC := '0'; + add_sub : IN STD_LOGIC := '1'; + cin : IN STD_LOGIC := 'Z'; + clken : IN STD_LOGIC := '1'; + clock : IN STD_LOGIC := '0'; + cout : OUT STD_LOGIC; + dataa : IN STD_LOGIC_VECTOR(LPM_WIDTH-1 DOWNTO 0) := (OTHERS => '0'); + datab : IN STD_LOGIC_VECTOR(LPM_WIDTH-1 DOWNTO 0) := (OTHERS => '0'); + overflow : OUT STD_LOGIC; + result : OUT STD_LOGIC_VECTOR(LPM_WIDTH-1 DOWNTO 0) + ); + END COMPONENT; + COMPONENT lpm_compare + GENERIC + ( + LPM_PIPELINE : NATURAL := 0; + LPM_REPRESENTATION : STRING := "UNSIGNED"; + LPM_WIDTH : NATURAL; + lpm_hint : STRING := "UNUSED"; + lpm_type : STRING := "lpm_compare" + ); + PORT + ( + aclr : IN STD_LOGIC := '0'; + aeb : OUT STD_LOGIC; + agb : OUT STD_LOGIC; + ageb : OUT STD_LOGIC; + alb : OUT STD_LOGIC; + aleb : OUT STD_LOGIC; + aneb : OUT STD_LOGIC; + clken : IN STD_LOGIC := '1'; + clock : IN STD_LOGIC := '0'; + dataa : IN STD_LOGIC_VECTOR(LPM_WIDTH-1 DOWNTO 0) := (OTHERS => '0'); + datab : IN STD_LOGIC_VECTOR(LPM_WIDTH-1 DOWNTO 0) := (OTHERS => '0') + ); + END COMPONENT; + COMPONENT lpm_counter + GENERIC + ( + lpm_avalue : STRING := "0"; + lpm_direction : STRING := "DEFAULT"; + lpm_modulus : NATURAL := 0; + lpm_port_updown : STRING := "PORT_CONNECTIVITY"; + lpm_pvalue : STRING := "0"; + lpm_svalue : STRING := "0"; + lpm_width : NATURAL; + lpm_type : STRING := "lpm_counter" + ); + PORT + ( + aclr : IN STD_LOGIC := '0'; + aload : IN STD_LOGIC := '0'; + aset : IN STD_LOGIC := '0'; + cin : IN STD_LOGIC := '1'; + clk_en : IN STD_LOGIC := '1'; + clock : IN STD_LOGIC; + cnt_en : IN STD_LOGIC := '1'; + cout : OUT STD_LOGIC; + data : IN STD_LOGIC_VECTOR(LPM_WIDTH-1 DOWNTO 0) := (OTHERS => '0'); + eq : OUT STD_LOGIC_VECTOR(15 DOWNTO 0); + q : OUT STD_LOGIC_VECTOR(LPM_WIDTH-1 DOWNTO 0); + sclr : IN STD_LOGIC := '0'; + sload : IN STD_LOGIC := '0'; + sset : IN STD_LOGIC := '0'; + updown : IN STD_LOGIC := '1' + ); + END COMPONENT; + COMPONENT lpm_decode + GENERIC + ( + LPM_DECODES : NATURAL; + LPM_PIPELINE : NATURAL := 0; + LPM_WIDTH : NATURAL; + lpm_hint : STRING := "UNUSED"; + lpm_type : STRING := "lpm_decode" + ); + PORT + ( + aclr : IN STD_LOGIC := '0'; + clken : IN STD_LOGIC := '1'; + clock : IN STD_LOGIC := '0'; + data : IN STD_LOGIC_VECTOR(LPM_WIDTH-1 DOWNTO 0) := (OTHERS => '0'); + enable : IN STD_LOGIC := '1'; + eq : OUT STD_LOGIC_VECTOR(LPM_DECODES-1 DOWNTO 0) + ); + END COMPONENT; + BEGIN + + wire_gnd <= '0'; + loop0 : FOR i IN 0 TO 7 GENERATE + wire_w_lg_addr_counter_out1880w(i) <= addr_counter_out(i) AND addr_counter_enable; + END GENERATE loop0; + loop1 : FOR i IN 0 TO 7 GENERATE + wire_w_lg_addr_decoder_out1854w(i) <= addr_decoder_out(i) AND wire_write_init_state_w_lg_q1853w(0); + END GENERATE loop1; + loop2 : FOR i IN 0 TO 7 GENERATE + wire_w_lg_c0_wire1808w(i) <= c0_wire(i) AND wire_w_rotate_decoder_wires_range1807w(0); + END GENERATE loop2; + loop3 : FOR i IN 0 TO 7 GENERATE + wire_w_lg_c1_wire1806w(i) <= c1_wire(i) AND wire_w_rotate_decoder_wires_range1805w(0); + END GENERATE loop3; + loop4 : FOR i IN 0 TO 7 GENERATE + wire_w_lg_c2_wire1804w(i) <= c2_wire(i) AND wire_w_rotate_decoder_wires_range1803w(0); + END GENERATE loop4; + loop5 : FOR i IN 0 TO 7 GENERATE + wire_w_lg_c3_wire1802w(i) <= c3_wire(i) AND wire_w_rotate_decoder_wires_range1801w(0); + END GENERATE loop5; + loop6 : FOR i IN 0 TO 7 GENERATE + wire_w_lg_c4_wire1800w(i) <= c4_wire(i) AND wire_w_rotate_decoder_wires_range1799w(0); + END GENERATE loop6; + loop7 : FOR i IN 0 TO 7 GENERATE + wire_w_lg_read_addr_counter_out1879w(i) <= read_addr_counter_out(i) AND read_addr_counter_enable; + END GENERATE loop7; + loop8 : FOR i IN 0 TO 7 GENERATE + wire_w_lg_read_addr_decoder_out1849w(i) <= read_addr_decoder_out(i) AND wire_read_init_state_w_lg_q1848w(0); + END GENERATE loop8; + loop9 : FOR i IN 0 TO 7 GENERATE + wire_w_lg_reconfig_addr_counter_out1877w(i) <= reconfig_addr_counter_out(i) AND reconfig_addr_counter_enable; + END GENERATE loop9; + loop10 : FOR i IN 0 TO 7 GENERATE + wire_w_lg_rotate_addr_counter_out1878w(i) <= rotate_addr_counter_out(i) AND rotate_addr_counter_enable; + END GENERATE loop10; + wire_w_lg_shift_reg_load_enable187w(0) <= shift_reg_load_enable AND wire_w_data_in_range186w(0); + wire_w_lg_shift_reg_load_enable179w(0) <= shift_reg_load_enable AND wire_w_data_in_range178w(0); + wire_w_lg_shift_reg_load_enable171w(0) <= shift_reg_load_enable AND wire_w_data_in_range170w(0); + wire_w_lg_shift_reg_load_enable163w(0) <= shift_reg_load_enable AND wire_w_data_in_range162w(0); + wire_w_lg_shift_reg_load_enable155w(0) <= shift_reg_load_enable AND wire_w_data_in_range154w(0); + wire_w_lg_shift_reg_load_enable147w(0) <= shift_reg_load_enable AND wire_w_data_in_range146w(0); + wire_w_lg_shift_reg_load_enable139w(0) <= shift_reg_load_enable AND wire_w_data_in_range138w(0); + wire_w_lg_shift_reg_load_enable131w(0) <= shift_reg_load_enable AND wire_w_data_in_range130w(0); + wire_w_lg_shift_reg_load_enable123w(0) <= shift_reg_load_enable AND wire_w_data_in_range122w(0); + wire_w_lg_w_counter_param_latch_range294w379w(0) <= wire_w_counter_param_latch_range294w(0) AND wire_w_lg_w_counter_param_latch_range296w297w(0); + wire_w_lg_w_counter_type_latch_range284w710w(0) <= wire_w_counter_type_latch_range284w(0) AND wire_w_lg_w_counter_type_latch_range286w530w(0); + wire_w_lg_dummy_scandataout1873w(0) <= NOT dummy_scandataout; + wire_w_lg_pll_scandone1875w(0) <= NOT pll_scandone; + wire_w_lg_read_nominal_out216w(0) <= NOT read_nominal_out; + wire_w_lg_read_param1730w(0) <= NOT read_param; + wire_w_lg_reconfig1728w(0) <= NOT reconfig; + wire_w_lg_reconfig_done1832w(0) <= NOT reconfig_done; + wire_w_lg_reconfig_post_done1828w(0) <= NOT reconfig_post_done; + wire_w_lg_reconfig_width_counter_done1825w(0) <= NOT reconfig_width_counter_done; + wire_w_lg_reset1w(0) <= NOT reset; + wire_w_lg_rotate_width_counter_done1776w(0) <= NOT rotate_width_counter_done; + wire_w_lg_width_counter_done1744w(0) <= NOT width_counter_done; + wire_w_lg_write_from_rom1727w(0) <= NOT write_from_rom; + wire_w_lg_write_param1729w(0) <= NOT write_param; + wire_w_lg_w_counter_param_latch_range296w297w(0) <= NOT wire_w_counter_param_latch_range296w(0); + wire_w_lg_w_counter_type_latch_range286w530w(0) <= NOT wire_w_counter_type_latch_range286w(0); + wire_w_lg_w_lg_w_lg_w1329w1392w1452w1516w(0) <= wire_w_lg_w_lg_w1329w1392w1452w(0) OR w1484w; + wire_w_lg_w_lg_w1329w1392w1452w(0) <= wire_w_lg_w1329w1392w(0) OR w1424w; + wire_w_lg_w_lg_w_lg_w1361w1422w1483w1550w(0) <= wire_w_lg_w_lg_w1361w1422w1483w(0) OR w1517w; + wire_w_lg_w1329w1392w(0) <= wire_w1329w(0) OR w1362w; + wire_w_lg_w_lg_w1361w1422w1483w(0) <= wire_w_lg_w1361w1422w(0) OR w1453w; + wire_w1329w(0) <= wire_w_lg_w_lg_w_lg_w_lg_w980w1055w1126w1195w1261w(0) OR w1297w; + wire_w_lg_w1361w1422w(0) <= wire_w1361w(0) OR w1393w; + wire_w_lg_w_lg_w_lg_w_lg_w980w1055w1126w1195w1261w(0) <= wire_w_lg_w_lg_w_lg_w980w1055w1126w1195w(0) OR w1229w; + wire_w1361w(0) <= wire_w_lg_w_lg_w_lg_w_lg_w1016w1091w1160w1228w1294w(0) OR w1330w; + wire_w_lg_w_lg_w_lg_w980w1055w1126w1195w(0) <= wire_w_lg_w_lg_w980w1055w1126w(0) OR w1163w; + wire_w_lg_w_lg_w_lg_w_lg_w1016w1091w1160w1228w1294w(0) <= wire_w_lg_w_lg_w_lg_w1016w1091w1160w1228w(0) OR w1262w; + wire_w_lg_w_lg_w980w1055w1126w(0) <= wire_w_lg_w980w1055w(0) OR w1092w; + wire_w_lg_w_lg_w_lg_w1016w1091w1160w1228w(0) <= wire_w_lg_w_lg_w1016w1091w1160w(0) OR w1196w; + wire_w_lg_w980w1055w(0) <= wire_w980w(0) OR w1019w; + wire_w_lg_w_lg_w1016w1091w1160w(0) <= wire_w_lg_w1016w1091w(0) OR w1127w; + wire_w980w(0) <= wire_w_lg_w_lg_w_lg_w_lg_w_lg_w423w570w637w749w817w920w(0) OR w952w; + wire_w_lg_w1016w1091w(0) <= wire_w1016w(0) OR w1056w; + wire_w_lg_w_lg_w_lg_w_lg_w_lg_w423w570w637w749w817w920w(0) <= wire_w_lg_w_lg_w_lg_w_lg_w423w570w637w749w817w(0) OR w888w; + wire_w1016w(0) <= wire_w_lg_w_lg_w_lg_w_lg_w571w672w784w850w951w(0) OR w981w; + wire_w63w(0) <= wire_w_lg_w_lg_w_lg_shift_reg_load_enable60w61w62w(0) OR shift_reg_clear; + wire_w_lg_w_lg_w_lg_w_lg_w423w570w637w749w817w(0) <= wire_w_lg_w_lg_w_lg_w423w570w637w749w(0) OR w785w; + wire_w_lg_w_lg_w_lg_w_lg_w571w672w784w850w951w(0) <= wire_w_lg_w_lg_w_lg_w571w672w784w850w(0) OR w921w; + wire_w_lg_w_lg_w_lg_shift_reg_load_enable60w61w62w(0) <= wire_w_lg_w_lg_shift_reg_load_enable60w61w(0) OR shift_reg_shift_nominal_enable; + wire_w_lg_w_lg_w_lg_w423w570w637w749w(0) <= wire_w_lg_w_lg_w423w570w637w(0) OR w713w; + wire_w_lg_w_lg_w_lg_w571w672w784w850w(0) <= wire_w_lg_w_lg_w571w672w784w(0) OR w818w; + wire_w_lg_w_lg_shift_reg_load_enable60w61w(0) <= wire_w_lg_shift_reg_load_enable60w(0) OR shift_reg_load_nominal_enable; + wire_w_lg_w_lg_w423w570w637w(0) <= wire_w_lg_w423w570w(0) OR w605w; + wire_w_lg_w_lg_w571w672w784w(0) <= wire_w_lg_w571w672w(0) OR w750w; + wire_w_lg_dummy_scandataout1874w(0) <= dummy_scandataout OR wire_w_lg_dummy_scandataout1873w(0); + wire_w_lg_shift_reg_load_enable60w(0) <= shift_reg_load_enable OR shift_reg_shift_enable; + wire_w_lg_w301w378w(0) <= w301w OR w341w; + wire_w_lg_w381w495w(0) <= w381w OR w460w; + wire_w_lg_w423w570w(0) <= w423w OR w534w; + wire_w_lg_w571w672w(0) <= w571w OR w638w; + wire_w_lg_w675w885w(0) <= w675w OR w851w; + addr_counter_enable <= (write_data_state OR write_nominal_state); + addr_counter_out <= wire_cntr1_q; + addr_counter_sload <= wire_write_init_state_w_lg_q1853w(0); + addr_counter_sload_value <= wire_w_lg_addr_decoder_out1854w; + addr_decoder_out <= (((((((((((((((((((((((((((((((((((( "0" & "0" & "0" & "0" & "0" & "0" & "0" & w301w) OR ( "0" & "0" & "0" & "0" & "0" & "0" & w341w & w341w)) OR ( "0" & "0" & "0" & "0" & w381w & "0" & "0" & "0")) OR ( "0" & "0" & "0" & "0" & w423w & "0" & "0" & w423w)) OR ( "0" & "0" & "0" & "0" & w460w & w460w & w460w & "0")) OR ( "0" & "0" & "0" & w496w & "0" & "0" & "0" & w496w)) OR ( "0" & "0" & "0" & w534w & "0" & "0" & w534w & "0")) OR ( "0" & "0" & "0" & w571w & w571w & "0" & w571w & "0")) OR ( "0" & "0" & "0" & w605w & w605w & "0" & w605w & w605w)) OR ( "0" & "0" & w638w & "0" & "0" & "0" & w638w & w638w)) OR ( "0" & "0" & w675w & "0" & "0" & "0" & w675w & w675w)) OR ( "0" & "0" & w713w & "0" & "0" & w713w & "0" & "0")) OR ( "0" & "0" & w750w & "0" & w750w & w750w & "0" & "0")) OR ( "0" & "0" & w785w & "0" & w785w & w785w & "0" & w785w)) OR ( "0" & "0" & w818w & w818w & "0" & w818w & "0" & w818w)) OR ( "0" & "0" & w851w & w851w & "0" & w851w & "0" & w851w)) OR ( "0" & "0" & w888w & w888w & "0" & w888w & w888w & "0")) OR ( "0" & "0" & w921w & w921w & w921w & w921w & w921w & "0")) OR ( "0" & "0" & w952w & w952w & w952w & w952w & w952w & w952w)) OR ( "0" & w981w & "0" & "0" & "0" & w981w & w981w & w981w)) OR ( "0" & w1019w & "0" & "0" & w1019w & "0" & "0" & "0")) OR ( "0" & w1056w & "0" & w1056w & "0" & "0" & "0" & "0")) OR ( "0" & w1092w & "0" & w1092w & "0" & "0" & "0" & w1092w)) OR ( "0" & w1127w & "0" & w1127w & w1127w & "0" & "0" & w1127w)) OR ( "0" & w1163w & "0" & w1163w & w1163w & "0" & w1163w & "0")) OR ( "0" & w1196w & w1196w & "0" & "0" & "0" & w1196w & "0")) OR ( "0" & w1229w & w1229w & "0" & "0" & "0" & w1229w & w1229w)) OR ( "0" & w1262w & w1262w & "0" & w1262w & "0" & w1262w & w1262w)) OR ( "0" & w1297w & w1297w & "0" & w1297w & w1297w & "0" & "0")) OR ( "0" & w1330w & w1330w & w1330w & "0" & w1330w & "0" & "0")) OR ( "0" & w1362w & w1362w & w1362w & "0" & w1362w & "0" & w1362w)) OR ( "0" & w1393w & w1393w & w1393w & w1393w & w1393w & "0" & w1393w)) OR ( "0" & w1424w & w1424w & w1424w & w1424w + & w1424w & w1424w & "0")) OR ( w1453w & "0" & "0" & "0" & "0" & w1453w & w1453w & "0")) OR ( w1484w & "0" & "0" & "0" & "0" & w1484w & w1484w & w1484w)) OR ( w1517w & "0" & "0" & "0" & w1517w & w1517w & w1517w & w1517w)); + busy <= (wire_idle_state_w_lg_q1672w(0) OR areset_state); + c0_wire <= "01000111"; + c1_wire <= "01011001"; + c2_wire <= "01101011"; + c3_wire <= "01111101"; + c4_wire <= "10001111"; + counter_param_latch <= counter_param_latch_reg; + counter_type_latch <= counter_type_latch_reg; + cuda_combout_wire <= ( wire_le_comb10_combout & wire_le_comb9_combout & wire_le_comb8_combout); + data_out <= ( wire_shift_reg_w_lg_w_lg_q258w259w & wire_shift_reg_w_lg_w_lg_q253w254w & wire_shift_reg_w_lg_w_lg_q248w249w & wire_shift_reg_w_lg_w_lg_q243w244w & wire_shift_reg_w_lg_w_lg_q238w239w & wire_shift_reg_w_lg_w_lg_q233w234w & wire_shift_reg_w_lg_w_lg_q228w229w & wire_shift_reg_w_lg_w_lg_q223w224w & wire_shift_reg_w_lg_w_lg_q217w218w); + dummy_scandataout <= pll_scandataout; + encode_out <= ( C4_ena_state & wire_C2_ena_state_w_lg_q1767w & wire_C1_ena_state_w_lg_q1766w); + input_latch_enable <= (idle_state AND (write_param OR read_param)); + pll_areset <= (pll_areset_in OR (areset_state AND reconfig_wait_state)); + pll_configupdate <= (configupdate_state AND wire_configupdate3_state_w_lg_q1842w(0)); + pll_scanclk <= clock; + pll_scanclkena <= ((rotate_width_counter_enable AND wire_w_lg_rotate_width_counter_done1776w(0)) OR reconfig_seq_data_state); + pll_scandata <= (scan_cache_out AND ((rotate_width_counter_enable OR reconfig_seq_data_state) OR reconfig_post_state)); + power_up <= (((((((((((((((((((wire_reset_state_w_lg_q1671w(0) AND wire_idle_state_w_lg_q1672w(0)) AND wire_read_init_state_w_lg_q1674w(0)) AND wire_read_first_state_w_lg_q1676w(0)) AND wire_read_data_state_w_lg_q1678w(0)) AND wire_read_last_state_w_lg_q1680w(0)) AND wire_read_init_nominal_state_w_lg_q1682w(0)) AND wire_read_first_nominal_state_w_lg_q1684w(0)) AND wire_read_data_nominal_state_w_lg_q1686w(0)) AND wire_read_last_nominal_state_w_lg_q1688w(0)) AND wire_write_init_state_w_lg_q1690w(0)) AND wire_write_data_state_w_lg_q1692w(0)) AND wire_write_init_nominal_state_w_lg_q1694w(0)) AND wire_write_nominal_state_w_lg_q1696w(0)) AND wire_reconfig_init_state_w_lg_q1698w(0)) AND wire_reconfig_counter_state_w_lg_q1700w(0)) AND wire_reconfig_seq_ena_state_w_lg_q1702w(0)) AND wire_reconfig_seq_data_state_w_lg_q1704w(0)) AND wire_reconfig_post_state_w_lg_q1706w(0)) AND wire_reconfig_wait_state_w_lg_q1708w(0)); + read_addr_counter_enable <= (((read_first_state OR read_data_state) OR read_first_nominal_state) OR read_data_nominal_state); + read_addr_counter_out <= wire_cntr2_q; + read_addr_counter_sload <= wire_read_init_state_w_lg_q1848w(0); + read_addr_counter_sload_value <= wire_w_lg_read_addr_decoder_out1849w; + read_addr_decoder_out <= (((((((((((((((((((((((((((((((((((( "0" & "0" & "0" & "0" & "0" & "0" & "0" & "0") OR ( "0" & "0" & "0" & "0" & "0" & "0" & w341w & "0")) OR ( "0" & "0" & "0" & "0" & "0" & w381w & "0" & "0")) OR ( "0" & "0" & "0" & "0" & w423w & "0" & "0" & w423w)) OR ( "0" & "0" & "0" & "0" & w460w & "0" & w460w & "0")) OR ( "0" & "0" & "0" & "0" & w496w & w496w & w496w & w496w)) OR ( "0" & "0" & "0" & w534w & "0" & "0" & w534w & "0")) OR ( "0" & "0" & "0" & w571w & "0" & "0" & w571w & w571w)) OR ( "0" & "0" & "0" & w605w & w605w & "0" & w605w & w605w)) OR ( "0" & "0" & "0" & w638w & w638w & w638w & "0" & "0")) OR ( "0" & "0" & "0" & w675w & "0" & "0" & w675w & "0")) OR ( "0" & "0" & w713w & "0" & "0" & w713w & "0" & "0")) OR ( "0" & "0" & w750w & "0" & "0" & w750w & "0" & w750w)) OR ( "0" & "0" & w785w & "0" & w785w & w785w & "0" & w785w)) OR ( "0" & "0" & w818w & "0" & w818w & w818w & w818w & "0")) OR ( "0" & "0" & w851w & "0" & "0" & w851w & "0" & "0")) OR ( "0" & "0" & w888w & w888w & "0" & w888w & w888w & "0")) OR ( "0" & "0" & w921w & w921w & "0" & w921w & w921w & w921w)) OR ( "0" & "0" & w952w & w952w & w952w & w952w & w952w & w952w)) OR ( "0" & w981w & "0" & "0" & "0" & "0" & "0" & "0")) OR ( "0" & w1019w & "0" & "0" & w1019w & "0" & "0" & "0")) OR ( "0" & w1056w & "0" & "0" & w1056w & "0" & "0" & w1056w)) OR ( "0" & w1092w & "0" & w1092w & "0" & "0" & "0" & w1092w)) OR ( "0" & w1127w & "0" & w1127w & "0" & "0" & w1127w & "0")) OR ( "0" & w1163w & "0" & w1163w & w1163w & "0" & w1163w & "0")) OR ( "0" & w1196w & "0" & w1196w & w1196w & "0" & w1196w & w1196w)) OR ( "0" & w1229w & w1229w & "0" & "0" & "0" & w1229w & w1229w)) OR ( "0" & w1262w & w1262w & "0" & "0" & w1262w & "0" & "0")) OR ( "0" & w1297w & w1297w & "0" & w1297w & w1297w & "0" & "0")) OR ( "0" & w1330w & w1330w & "0" & w1330w & w1330w & "0" & w1330w)) OR ( "0" & w1362w & w1362w & w1362w & "0" & w1362w & "0" & w1362w)) OR ( "0" & w1393w & w1393w & w1393w & "0" & w1393w & w1393w & "0")) OR ( "0" & w1424w & w1424w & w1424w & w1424w & w1424w + & w1424w & "0")) OR ( "0" & w1453w & w1453w & w1453w & w1453w & w1453w & w1453w & w1453w)) OR ( w1484w & "0" & "0" & "0" & "0" & w1484w & w1484w & w1484w)) OR ( w1517w & "0" & "0" & "0" & w1517w & "0" & "0" & "0")); + read_nominal_out <= tmp_nominal_data_out_state; + reconfig_addr_counter_enable <= reconfig_seq_data_state; + reconfig_addr_counter_out <= wire_cntr12_q; + reconfig_addr_counter_sload <= reconfig_seq_ena_state; + reconfig_addr_counter_sload_value <= wire_reconfig_seq_ena_state_w_lg_q1856w; + reconfig_done <= (wire_w_lg_pll_scandone1875w(0) AND wire_w_lg_dummy_scandataout1874w(0)); + reconfig_post_done <= pll_scandone; + reconfig_width_counter_done <= ((((((NOT wire_cntr13_q(0)) AND (NOT wire_cntr13_q(1))) AND (NOT wire_cntr13_q(2))) AND (NOT wire_cntr13_q(3))) AND (NOT wire_cntr13_q(4))) AND (NOT wire_cntr13_q(5))); + reconfig_width_counter_enable <= reconfig_seq_data_state; + reconfig_width_counter_sload <= reconfig_seq_ena_state; + reconfig_width_counter_sload_value <= wire_reconfig_seq_ena_state_w_lg_q1857w; + rotate_addr_counter_enable <= ((((C0_data_state OR C1_data_state) OR C2_data_state) OR C3_data_state) OR C4_data_state); + rotate_addr_counter_out <= wire_cntr15_q; + rotate_addr_counter_sload <= ((((C0_ena_state OR C1_ena_state) OR C2_ena_state) OR C3_ena_state) OR C4_ena_state); + rotate_addr_counter_sload_value <= ((((wire_w_lg_c0_wire1808w OR wire_w_lg_c1_wire1806w) OR wire_w_lg_c2_wire1804w) OR wire_w_lg_c3_wire1802w) OR wire_w_lg_c4_wire1800w); + rotate_decoder_wires <= wire_decode11_eq; + rotate_width_counter_done <= (((((NOT wire_cntr14_q(0)) AND (NOT wire_cntr14_q(1))) AND (NOT wire_cntr14_q(2))) AND (NOT wire_cntr14_q(3))) AND (NOT wire_cntr14_q(4))); + rotate_width_counter_enable <= ((((C0_data_state OR C1_data_state) OR C2_data_state) OR C3_data_state) OR C4_data_state); + rotate_width_counter_sload <= ((((C0_ena_state OR C1_ena_state) OR C2_ena_state) OR C3_ena_state) OR C4_ena_state); + rotate_width_counter_sload_value <= "10010"; + scan_cache_address <= (((wire_w_lg_addr_counter_out1880w OR wire_w_lg_read_addr_counter_out1879w) OR wire_w_lg_rotate_addr_counter_out1878w) OR wire_w_lg_reconfig_addr_counter_out1877w); + scan_cache_in <= shift_reg_serial_out; + scan_cache_out <= wire_altsyncram4_q_a(0); + scan_cache_write_enable <= (write_data_state OR write_nominal_state); + sel_param_bypass_LF_unused <= (((NOT counter_param_latch(0)) AND wire_w_lg_w_counter_param_latch_range296w297w(0)) AND counter_param_latch(2)); + sel_param_c <= (((NOT counter_param_latch(0)) AND counter_param_latch(1)) AND (NOT counter_param_latch(2))); + sel_param_high_i_postscale <= (((NOT counter_param_latch(0)) AND wire_w_lg_w_counter_param_latch_range296w297w(0)) AND (NOT counter_param_latch(2))); + sel_param_low_r <= (wire_w_lg_w_counter_param_latch_range294w379w(0) AND (NOT counter_param_latch(2))); + sel_param_nominal_count <= ((counter_param_latch(0) AND counter_param_latch(1)) AND counter_param_latch(2)); + sel_param_odd_CP_unused <= (wire_w_lg_w_counter_param_latch_range294w379w(0) AND counter_param_latch(2)); + sel_type_c0 <= ((((NOT counter_type_latch(0)) AND wire_w_lg_w_counter_type_latch_range286w530w(0)) AND counter_type_latch(2)) AND (NOT counter_type_latch(3))); + sel_type_c1 <= ((wire_w_lg_w_counter_type_latch_range284w710w(0) AND counter_type_latch(2)) AND (NOT counter_type_latch(3))); + sel_type_c2 <= ((((NOT counter_type_latch(0)) AND counter_type_latch(1)) AND counter_type_latch(2)) AND (NOT counter_type_latch(3))); + sel_type_c3 <= (((counter_type_latch(0) AND counter_type_latch(1)) AND counter_type_latch(2)) AND (NOT counter_type_latch(3))); + sel_type_c4 <= ((((NOT counter_type_latch(0)) AND wire_w_lg_w_counter_type_latch_range286w530w(0)) AND (NOT counter_type_latch(2))) AND counter_type_latch(3)); + sel_type_cplf <= ((((NOT counter_type_latch(0)) AND counter_type_latch(1)) AND (NOT counter_type_latch(2))) AND (NOT counter_type_latch(3))); + sel_type_m <= ((wire_w_lg_w_counter_type_latch_range284w710w(0) AND (NOT counter_type_latch(2))) AND (NOT counter_type_latch(3))); + sel_type_n <= ((((NOT counter_type_latch(0)) AND wire_w_lg_w_counter_type_latch_range286w530w(0)) AND (NOT counter_type_latch(2))) AND (NOT counter_type_latch(3))); + sel_type_vco <= (((counter_type_latch(0) AND counter_type_latch(1)) AND (NOT counter_type_latch(2))) AND (NOT counter_type_latch(3))); + seq_addr_wire <= "00110101"; + seq_sload_value <= "110110"; + shift_reg_clear <= wire_read_init_state_w_lg_q1848w(0); + shift_reg_load_enable <= ((idle_state AND write_param) AND (NOT ((((((NOT counter_type(3)) AND (NOT counter_type(2))) AND (NOT counter_type(1))) AND counter_param(2)) AND counter_param(1)) AND counter_param(0)))); + shift_reg_load_nominal_enable <= ((idle_state AND write_param) AND ((((((NOT counter_type(3)) AND (NOT counter_type(2))) AND (NOT counter_type(1))) AND counter_param(2)) AND counter_param(1)) AND counter_param(0))); + shift_reg_serial_in <= scan_cache_out; + shift_reg_serial_out <= (((((((wire_shift_reg_w_lg_q262w(0) OR wire_shift_reg_w_lg_q264w(0)) OR wire_shift_reg_w_lg_q267w(0)) OR wire_shift_reg_w_lg_q270w(0)) OR wire_shift_reg_w_lg_q273w(0)) OR wire_shift_reg_w_lg_q276w(0)) OR wire_shift_reg_w_lg_q279w(0)) OR wire_shift_reg_w_lg_q282w(0)); + shift_reg_shift_enable <= ((read_data_state OR read_last_state) OR write_data_state); + shift_reg_shift_nominal_enable <= ((read_data_nominal_state OR read_last_nominal_state) OR write_nominal_state); + shift_reg_width_select <= width_decoder_select; + w1019w <= (sel_type_c1 AND sel_param_bypass_LF_unused); + w1056w <= (sel_type_c1 AND sel_param_high_i_postscale); + w1092w <= (sel_type_c1 AND sel_param_odd_CP_unused); + w1127w <= (sel_type_c1 AND sel_param_low_r); + w1163w <= (sel_type_c2 AND sel_param_bypass_LF_unused); + w1196w <= (sel_type_c2 AND sel_param_high_i_postscale); + w1229w <= (sel_type_c2 AND sel_param_odd_CP_unused); + w1262w <= (sel_type_c2 AND sel_param_low_r); + w1297w <= (sel_type_c3 AND sel_param_bypass_LF_unused); + w1330w <= (sel_type_c3 AND sel_param_high_i_postscale); + w1362w <= (sel_type_c3 AND sel_param_odd_CP_unused); + w1393w <= (sel_type_c3 AND sel_param_low_r); + w1424w <= (sel_type_c4 AND sel_param_bypass_LF_unused); + w1453w <= (sel_type_c4 AND sel_param_high_i_postscale); + w1484w <= (sel_type_c4 AND sel_param_odd_CP_unused); + w1517w <= (sel_type_c4 AND sel_param_low_r); + w1565w <= '0'; + w1592w <= '0'; + w301w <= (sel_type_cplf AND sel_param_bypass_LF_unused); + w341w <= (sel_type_cplf AND sel_param_c); + w381w <= (sel_type_cplf AND sel_param_low_r); + w423w <= (sel_type_vco AND sel_param_high_i_postscale); + w460w <= (sel_type_cplf AND sel_param_odd_CP_unused); + w496w <= (sel_type_cplf AND sel_param_high_i_postscale); + w534w <= (sel_type_n AND sel_param_bypass_LF_unused); + w571w <= (sel_type_n AND sel_param_high_i_postscale); + w605w <= (sel_type_n AND sel_param_odd_CP_unused); + w638w <= (sel_type_n AND sel_param_low_r); + w64w <= '0'; + w675w <= (sel_type_n AND sel_param_nominal_count); + w713w <= (sel_type_m AND sel_param_bypass_LF_unused); + w750w <= (sel_type_m AND sel_param_high_i_postscale); + w785w <= (sel_type_m AND sel_param_odd_CP_unused); + w818w <= (sel_type_m AND sel_param_low_r); + w851w <= (sel_type_m AND sel_param_nominal_count); + w888w <= (sel_type_c0 AND sel_param_bypass_LF_unused); + w921w <= (sel_type_c0 AND sel_param_high_i_postscale); + w952w <= (sel_type_c0 AND sel_param_odd_CP_unused); + w981w <= (sel_type_c0 AND sel_param_low_r); + width_counter_done <= (((((NOT wire_cntr3_q(0)) AND (NOT wire_cntr3_q(1))) AND (NOT wire_cntr3_q(2))) AND (NOT wire_cntr3_q(3))) AND (NOT wire_cntr3_q(4))); + width_counter_enable <= ((((read_first_state OR read_data_state) OR write_data_state) OR read_data_nominal_state) OR write_nominal_state); + width_counter_sload <= (((read_init_state OR write_init_state) OR read_init_nominal_state) OR write_init_nominal_state); + width_counter_sload_value <= width_decoder_out; + width_decoder_out <= (((((( "0" & "0" & "0" & "0" & "0") OR ( width_decoder_select(2) & "0" & "0" & "0" & width_decoder_select(2))) OR ( "0" & "0" & "0" & "0" & width_decoder_select(3))) OR ( "0" & "0" & width_decoder_select(5) & width_decoder_select(5) & width_decoder_select(5))) OR ( "0" & "0" & "0" & width_decoder_select(6) & "0")) OR ( "0" & "0" & width_decoder_select(7) & "0" & "0")); + width_decoder_select <= ( wire_w_lg_w381w495w & w496w & wire_w_lg_w_lg_w_lg_w1361w1422w1483w1550w & w1592w & wire_w_lg_w301w378w & wire_w_lg_w675w885w & w1565w & wire_w_lg_w_lg_w_lg_w1329w1392w1452w1516w); + write_from_rom <= '0'; + wire_w_counter_param_latch_range294w(0) <= counter_param_latch(0); + wire_w_counter_param_latch_range296w(0) <= counter_param_latch(1); + wire_w_counter_type_latch_range284w(0) <= counter_type_latch(0); + wire_w_counter_type_latch_range286w(0) <= counter_type_latch(1); + wire_w_data_in_range186w(0) <= data_in(0); + wire_w_data_in_range178w(0) <= data_in(1); + wire_w_data_in_range170w(0) <= data_in(2); + wire_w_data_in_range162w(0) <= data_in(3); + wire_w_data_in_range154w(0) <= data_in(4); + wire_w_data_in_range146w(0) <= data_in(5); + wire_w_data_in_range138w(0) <= data_in(6); + wire_w_data_in_range130w(0) <= data_in(7); + wire_w_data_in_range122w(0) <= data_in(8); + wire_w_rotate_decoder_wires_range1807w(0) <= rotate_decoder_wires(0); + wire_w_rotate_decoder_wires_range1805w(0) <= rotate_decoder_wires(1); + wire_w_rotate_decoder_wires_range1803w(0) <= rotate_decoder_wires(2); + wire_w_rotate_decoder_wires_range1801w(0) <= rotate_decoder_wires(3); + wire_w_rotate_decoder_wires_range1799w(0) <= rotate_decoder_wires(4); + wire_w_shift_reg_width_select_range261w(0) <= shift_reg_width_select(0); + wire_w_shift_reg_width_select_range263w(0) <= shift_reg_width_select(1); + wire_w_shift_reg_width_select_range266w(0) <= shift_reg_width_select(2); + wire_w_shift_reg_width_select_range269w(0) <= shift_reg_width_select(3); + wire_w_shift_reg_width_select_range272w(0) <= shift_reg_width_select(4); + wire_w_shift_reg_width_select_range275w(0) <= shift_reg_width_select(5); + wire_w_shift_reg_width_select_range278w(0) <= shift_reg_width_select(6); + wire_w_shift_reg_width_select_range281w(0) <= shift_reg_width_select(7); + wire_altsyncram4_data_a(0) <= ( scan_cache_in); + altsyncram4 : altsyncram + GENERIC MAP ( + NUMWORDS_A => 144, + OPERATION_MODE => "SINGLE_PORT", + WIDTH_A => 1, + WIDTH_BYTEENA_A => 1, + WIDTHAD_A => 8, + INTENDED_DEVICE_FAMILY => "Cyclone III" + ) + PORT MAP ( + address_a => scan_cache_address, + clock0 => clock, + data_a => wire_altsyncram4_data_a, + q_a => wire_altsyncram4_q_a, + wren_a => scan_cache_write_enable + ); + le_comb10 : cycloneiii_lcell_comb + GENERIC MAP ( + DONT_TOUCH => "on", + LUT_MASK => "1111000011110000", + SUM_LUTC_INPUT => "datac" + ) + PORT MAP ( + combout => wire_le_comb10_combout, + dataa => encode_out(0), + datab => encode_out(1), + datac => encode_out(2) + ); + le_comb8 : cycloneiii_lcell_comb + GENERIC MAP ( + DONT_TOUCH => "on", + LUT_MASK => "1010101010101010", + SUM_LUTC_INPUT => "datac" + ) + PORT MAP ( + combout => wire_le_comb8_combout, + dataa => encode_out(0), + datab => encode_out(1), + datac => encode_out(2) + ); + le_comb9 : cycloneiii_lcell_comb + GENERIC MAP ( + DONT_TOUCH => "on", + LUT_MASK => "1100110011001100", + SUM_LUTC_INPUT => "datac" + ) + PORT MAP ( + combout => wire_le_comb9_combout, + dataa => encode_out(0), + datab => encode_out(1), + datac => encode_out(2) + ); + PROCESS (clock) + BEGIN + IF (clock = '1' AND clock'event) THEN areset_init_state_1 <= pll_scandone; + END IF; + END PROCESS; + PROCESS (clock) + BEGIN + IF (clock = '1' AND clock'event) THEN areset_state <= (areset_init_state_1 AND wire_w_lg_reset1w(0)); + END IF; + END PROCESS; + PROCESS (clock) + BEGIN + IF (clock = '1' AND clock'event) THEN C0_data_state <= (C0_ena_state OR (C0_data_state AND wire_w_lg_rotate_width_counter_done1776w(0))); + END IF; + END PROCESS; + PROCESS (clock) + BEGIN + IF (clock = '1' AND clock'event) THEN C0_ena_state <= (C1_data_state AND rotate_width_counter_done); + END IF; + END PROCESS; + PROCESS (clock) + BEGIN + IF (clock = '1' AND clock'event) THEN C1_data_state <= (C1_ena_state OR (C1_data_state AND wire_w_lg_rotate_width_counter_done1776w(0))); + END IF; + END PROCESS; + PROCESS (clock) + BEGIN + IF (clock = '1' AND clock'event) THEN C1_ena_state <= (C2_data_state AND rotate_width_counter_done); + END IF; + END PROCESS; + wire_C1_ena_state_w_lg_q1766w(0) <= C1_ena_state OR C3_ena_state; + PROCESS (clock) + BEGIN + IF (clock = '1' AND clock'event) THEN C2_data_state <= (C2_ena_state OR (C2_data_state AND wire_w_lg_rotate_width_counter_done1776w(0))); + END IF; + END PROCESS; + PROCESS (clock) + BEGIN + IF (clock = '1' AND clock'event) THEN C2_ena_state <= (C3_data_state AND rotate_width_counter_done); + END IF; + END PROCESS; + wire_C2_ena_state_w_lg_q1767w(0) <= C2_ena_state OR C3_ena_state; + PROCESS (clock) + BEGIN + IF (clock = '1' AND clock'event) THEN C3_data_state <= (C3_ena_state OR (C3_data_state AND wire_w_lg_rotate_width_counter_done1776w(0))); + END IF; + END PROCESS; + PROCESS (clock) + BEGIN + IF (clock = '1' AND clock'event) THEN C3_ena_state <= (C4_data_state AND rotate_width_counter_done); + END IF; + END PROCESS; + PROCESS (clock) + BEGIN + IF (clock = '1' AND clock'event) THEN C4_data_state <= (C4_ena_state OR (C4_data_state AND wire_w_lg_rotate_width_counter_done1776w(0))); + END IF; + END PROCESS; + PROCESS (clock) + BEGIN + IF (clock = '1' AND clock'event) THEN C4_ena_state <= reconfig_init_state; + END IF; + END PROCESS; + PROCESS (clock) + BEGIN + IF (clock = '1' AND clock'event) THEN configupdate2_state <= configupdate_state; + END IF; + END PROCESS; + PROCESS (clock) + BEGIN + IF (clock = '0' AND clock'event) THEN configupdate3_state <= configupdate2_state; + END IF; + END PROCESS; + wire_configupdate3_state_w_lg_q1842w(0) <= NOT configupdate3_state; + PROCESS (clock) + BEGIN + IF (clock = '1' AND clock'event) THEN configupdate_state <= reconfig_post_state; + END IF; + END PROCESS; + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN counter_param_latch_reg <= (OTHERS => '0'); + ELSIF (clock = '1' AND clock'event) THEN + IF (input_latch_enable = '1') THEN counter_param_latch_reg <= counter_param; + END IF; + END IF; + END PROCESS; + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN counter_type_latch_reg <= (OTHERS => '0'); + ELSIF (clock = '1' AND clock'event) THEN + IF (input_latch_enable = '1') THEN counter_type_latch_reg <= counter_type; + END IF; + END IF; + END PROCESS; + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN idle_state <= '0'; + ELSIF (clock = '1' AND clock'event) THEN idle_state <= ((wire_idle_state_w_lg_w_lg_w_lg_w1735w1736w1737w1738w(0) OR (reconfig_wait_state AND reconfig_done)) OR reset_state); + END IF; + END PROCESS; + wire_idle_state_w_lg_w_lg_w_lg_w_lg_q1731w1732w1733w1734w(0) <= wire_idle_state_w_lg_w_lg_w_lg_q1731w1732w1733w(0) AND wire_w_lg_write_from_rom1727w(0); + wire_idle_state_w_lg_w_lg_w_lg_q1731w1732w1733w(0) <= wire_idle_state_w_lg_w_lg_q1731w1732w(0) AND wire_w_lg_reconfig1728w(0); + wire_idle_state_w_lg_w_lg_q1731w1732w(0) <= wire_idle_state_w_lg_q1731w(0) AND wire_w_lg_write_param1729w(0); + wire_idle_state_w_lg_q1731w(0) <= idle_state AND wire_w_lg_read_param1730w(0); + wire_idle_state_w_lg_q1672w(0) <= NOT idle_state; + wire_idle_state_w1735w(0) <= wire_idle_state_w_lg_w_lg_w_lg_w_lg_q1731w1732w1733w1734w(0) OR read_last_state; + wire_idle_state_w_lg_w1735w1736w(0) <= wire_idle_state_w1735w(0) OR wire_write_data_state_w_lg_q1726w(0); + wire_idle_state_w_lg_w_lg_w1735w1736w1737w(0) <= wire_idle_state_w_lg_w1735w1736w(0) OR wire_write_nominal_state_w_lg_q1725w(0); + wire_idle_state_w_lg_w_lg_w_lg_w1735w1736w1737w1738w(0) <= wire_idle_state_w_lg_w_lg_w1735w1736w1737w(0) OR read_last_nominal_state; + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN nominal_data0 <= '0'; + ELSIF (clock = '1' AND clock'event) THEN nominal_data0 <= wire_add_sub6_result(0); + END IF; + END PROCESS; + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN nominal_data1 <= '0'; + ELSIF (clock = '1' AND clock'event) THEN nominal_data1 <= wire_add_sub6_result(1); + END IF; + END PROCESS; + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN nominal_data2 <= '0'; + ELSIF (clock = '1' AND clock'event) THEN nominal_data2 <= wire_add_sub6_result(2); + END IF; + END PROCESS; + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN nominal_data3 <= '0'; + ELSIF (clock = '1' AND clock'event) THEN nominal_data3 <= wire_add_sub6_result(3); + END IF; + END PROCESS; + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN nominal_data4 <= '0'; + ELSIF (clock = '1' AND clock'event) THEN nominal_data4 <= wire_add_sub6_result(4); + END IF; + END PROCESS; + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN nominal_data5 <= '0'; + ELSIF (clock = '1' AND clock'event) THEN nominal_data5 <= wire_add_sub6_result(5); + END IF; + END PROCESS; + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN nominal_data6 <= '0'; + ELSIF (clock = '1' AND clock'event) THEN nominal_data6 <= wire_add_sub6_result(6); + END IF; + END PROCESS; + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN nominal_data7 <= '0'; + ELSIF (clock = '1' AND clock'event) THEN nominal_data7 <= wire_add_sub6_result(7); + END IF; + END PROCESS; + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN nominal_data8 <= '0'; + ELSIF (clock = '1' AND clock'event) THEN nominal_data8 <= wire_w_data_in_range186w(0); + END IF; + END PROCESS; + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN nominal_data9 <= '0'; + ELSIF (clock = '1' AND clock'event) THEN nominal_data9 <= wire_w_data_in_range178w(0); + END IF; + END PROCESS; + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN nominal_data10 <= '0'; + ELSIF (clock = '1' AND clock'event) THEN nominal_data10 <= wire_w_data_in_range170w(0); + END IF; + END PROCESS; + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN nominal_data11 <= '0'; + ELSIF (clock = '1' AND clock'event) THEN nominal_data11 <= wire_w_data_in_range162w(0); + END IF; + END PROCESS; + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN nominal_data12 <= '0'; + ELSIF (clock = '1' AND clock'event) THEN nominal_data12 <= wire_w_data_in_range154w(0); + END IF; + END PROCESS; + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN nominal_data13 <= '0'; + ELSIF (clock = '1' AND clock'event) THEN nominal_data13 <= wire_w_data_in_range146w(0); + END IF; + END PROCESS; + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN nominal_data14 <= '0'; + ELSIF (clock = '1' AND clock'event) THEN nominal_data14 <= wire_w_data_in_range138w(0); + END IF; + END PROCESS; + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN nominal_data15 <= '0'; + ELSIF (clock = '1' AND clock'event) THEN nominal_data15 <= wire_w_data_in_range130w(0); + END IF; + END PROCESS; + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN nominal_data16 <= '0'; + ELSIF (clock = '1' AND clock'event) THEN nominal_data16 <= wire_w_data_in_range122w(0); + END IF; + END PROCESS; + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN nominal_data17 <= '0'; + ELSIF (clock = '1' AND clock'event) THEN nominal_data17 <= wire_cmpr7_aeb; + END IF; + END PROCESS; + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN read_data_nominal_state <= '0'; + ELSIF (clock = '1' AND clock'event) THEN read_data_nominal_state <= (wire_read_first_nominal_state_w_lg_q1753w(0) OR wire_read_data_nominal_state_w_lg_q1752w(0)); + END IF; + END PROCESS; + wire_read_data_nominal_state_w_lg_q1752w(0) <= read_data_nominal_state AND wire_w_lg_width_counter_done1744w(0); + wire_read_data_nominal_state_w_lg_q1686w(0) <= NOT read_data_nominal_state; + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN read_data_state <= '0'; + ELSIF (clock = '1' AND clock'event) THEN read_data_state <= (wire_read_first_state_w_lg_q1746w(0) OR wire_read_data_state_w_lg_q1745w(0)); + END IF; + END PROCESS; + wire_read_data_state_w_lg_q1745w(0) <= read_data_state AND wire_w_lg_width_counter_done1744w(0); + wire_read_data_state_w_lg_q1678w(0) <= NOT read_data_state; + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN read_first_nominal_state <= '0'; + ELSIF (clock = '1' AND clock'event) THEN read_first_nominal_state <= read_init_nominal_state; + END IF; + END PROCESS; + wire_read_first_nominal_state_w_lg_q1753w(0) <= read_first_nominal_state AND wire_w_lg_width_counter_done1744w(0); + wire_read_first_nominal_state_w_lg_q1684w(0) <= NOT read_first_nominal_state; + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN read_first_state <= '0'; + ELSIF (clock = '1' AND clock'event) THEN read_first_state <= read_init_state; + END IF; + END PROCESS; + wire_read_first_state_w_lg_q1746w(0) <= read_first_state AND wire_w_lg_width_counter_done1744w(0); + wire_read_first_state_w_lg_q1676w(0) <= NOT read_first_state; + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN read_init_nominal_state <= '0'; + ELSIF (clock = '1' AND clock'event) THEN read_init_nominal_state <= ((idle_state AND read_param) AND ((((((NOT counter_type(3)) AND (NOT counter_type(2))) AND (NOT counter_type(1))) AND counter_param(2)) AND counter_param(1)) AND counter_param(0))); + END IF; + END PROCESS; + wire_read_init_nominal_state_w_lg_q1682w(0) <= NOT read_init_nominal_state; + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN read_init_state <= '0'; + ELSIF (clock = '1' AND clock'event) THEN read_init_state <= ((idle_state AND read_param) AND (NOT ((((((NOT counter_type(3)) AND (NOT counter_type(2))) AND (NOT counter_type(1))) AND counter_param(2)) AND counter_param(1)) AND counter_param(0)))); + END IF; + END PROCESS; + wire_read_init_state_w_lg_q1674w(0) <= NOT read_init_state; + wire_read_init_state_w_lg_q1848w(0) <= read_init_state OR read_init_nominal_state; + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN read_last_nominal_state <= '0'; + ELSIF (clock = '1' AND clock'event) THEN read_last_nominal_state <= ((read_first_nominal_state AND width_counter_done) OR (read_data_nominal_state AND width_counter_done)); + END IF; + END PROCESS; + wire_read_last_nominal_state_w_lg_q1865w(0) <= read_last_nominal_state AND wire_idle_state_w_lg_q1672w(0); + wire_read_last_nominal_state_w_lg_q1688w(0) <= NOT read_last_nominal_state; + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN read_last_state <= '0'; + ELSIF (clock = '1' AND clock'event) THEN read_last_state <= ((read_first_state AND width_counter_done) OR (read_data_state AND width_counter_done)); + END IF; + END PROCESS; + wire_read_last_state_w_lg_q1680w(0) <= NOT read_last_state; + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN reconfig_counter_state <= '0'; + ELSIF (clock = '1' AND clock'event) THEN reconfig_counter_state <= ((((((((((reconfig_init_state OR C0_data_state) OR C1_data_state) OR C2_data_state) OR C3_data_state) OR C4_data_state) OR C0_ena_state) OR C1_ena_state) OR C2_ena_state) OR C3_ena_state) OR C4_ena_state); + END IF; + END PROCESS; + wire_reconfig_counter_state_w_lg_q1700w(0) <= NOT reconfig_counter_state; + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN reconfig_init_state <= '0'; + ELSIF (clock = '1' AND clock'event) THEN reconfig_init_state <= (idle_state AND reconfig); + END IF; + END PROCESS; + wire_reconfig_init_state_w_lg_q1698w(0) <= NOT reconfig_init_state; + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN reconfig_post_state <= '0'; + ELSIF (clock = '1' AND clock'event) THEN reconfig_post_state <= ((reconfig_seq_data_state AND reconfig_width_counter_done) OR wire_reconfig_post_state_w_lg_q1829w(0)); + END IF; + END PROCESS; + wire_reconfig_post_state_w_lg_q1829w(0) <= reconfig_post_state AND wire_w_lg_reconfig_post_done1828w(0); + wire_reconfig_post_state_w_lg_q1706w(0) <= NOT reconfig_post_state; + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN reconfig_seq_data_state <= '0'; + ELSIF (clock = '1' AND clock'event) THEN reconfig_seq_data_state <= (reconfig_seq_ena_state OR (reconfig_seq_data_state AND wire_w_lg_reconfig_width_counter_done1825w(0))); + END IF; + END PROCESS; + wire_reconfig_seq_data_state_w_lg_q1704w(0) <= NOT reconfig_seq_data_state; + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN reconfig_seq_ena_state <= '0'; + ELSIF (clock = '1' AND clock'event) THEN reconfig_seq_ena_state <= tmp_seq_ena_state; + END IF; + END PROCESS; + loop11 : FOR i IN 0 TO 7 GENERATE + wire_reconfig_seq_ena_state_w_lg_q1856w(i) <= reconfig_seq_ena_state AND seq_addr_wire(i); + END GENERATE loop11; + loop12 : FOR i IN 0 TO 5 GENERATE + wire_reconfig_seq_ena_state_w_lg_q1857w(i) <= reconfig_seq_ena_state AND seq_sload_value(i); + END GENERATE loop12; + wire_reconfig_seq_ena_state_w_lg_q1702w(0) <= NOT reconfig_seq_ena_state; + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN reconfig_wait_state <= '0'; + ELSIF (clock = '1' AND clock'event) THEN reconfig_wait_state <= ((reconfig_post_state AND reconfig_post_done) OR wire_reconfig_wait_state_w_lg_q1833w(0)); + END IF; + END PROCESS; + wire_reconfig_wait_state_w_lg_q1833w(0) <= reconfig_wait_state AND wire_w_lg_reconfig_done1832w(0); + wire_reconfig_wait_state_w_lg_q1708w(0) <= NOT reconfig_wait_state; + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN reset_state <= '1'; + ELSIF (clock = '1' AND clock'event) THEN reset_state <= power_up; + END IF; + END PROCESS; + wire_reset_state_w_lg_q1671w(0) <= NOT reset_state; + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN shift_reg0 <= '0'; + ELSIF (clock = '1' AND clock'event) THEN + IF (wire_shift_reg_ena(0) = '1') THEN + IF (shift_reg_clear = '1') THEN shift_reg0 <= '0'; + ELSE shift_reg0 <= ((((shift_reg_load_nominal_enable AND nominal_data17) OR (shift_reg_load_enable AND w64w)) OR (shift_reg_shift_enable AND shift_reg_serial_in)) OR (shift_reg_shift_nominal_enable AND shift_reg_serial_in)); + END IF; + END IF; + END IF; + END PROCESS; + wire_shift_reg_w_lg_q217w(0) <= shift_reg0 AND wire_w_lg_read_nominal_out216w(0); + wire_shift_reg_w_lg_w_lg_q217w218w(0) <= wire_shift_reg_w_lg_q217w(0) OR wire_add_sub5_w_lg_w_result_range214w215w(0); + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN shift_reg1 <= '0'; + ELSIF (clock = '1' AND clock'event) THEN + IF (wire_shift_reg_ena(1) = '1') THEN + IF (shift_reg_clear = '1') THEN shift_reg1 <= '0'; + ELSE shift_reg1 <= ((((shift_reg_load_nominal_enable AND nominal_data16) OR (shift_reg_load_enable AND w64w)) OR (shift_reg_shift_enable AND shift_reg0)) OR (shift_reg_shift_nominal_enable AND shift_reg0)); + END IF; + END IF; + END IF; + END PROCESS; + wire_shift_reg_w_lg_q223w(0) <= shift_reg1 AND wire_w_lg_read_nominal_out216w(0); + wire_shift_reg_w_lg_w_lg_q223w224w(0) <= wire_shift_reg_w_lg_q223w(0) OR wire_add_sub5_w_lg_w_result_range221w222w(0); + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN shift_reg2 <= '0'; + ELSIF (clock = '1' AND clock'event) THEN + IF (wire_shift_reg_ena(2) = '1') THEN + IF (shift_reg_clear = '1') THEN shift_reg2 <= '0'; + ELSE shift_reg2 <= ((((shift_reg_load_nominal_enable AND nominal_data15) OR (shift_reg_load_enable AND w64w)) OR (shift_reg_shift_enable AND shift_reg1)) OR (shift_reg_shift_nominal_enable AND shift_reg1)); + END IF; + END IF; + END IF; + END PROCESS; + wire_shift_reg_w_lg_q228w(0) <= shift_reg2 AND wire_w_lg_read_nominal_out216w(0); + wire_shift_reg_w_lg_w_lg_q228w229w(0) <= wire_shift_reg_w_lg_q228w(0) OR wire_add_sub5_w_lg_w_result_range226w227w(0); + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN shift_reg3 <= '0'; + ELSIF (clock = '1' AND clock'event) THEN + IF (wire_shift_reg_ena(3) = '1') THEN + IF (shift_reg_clear = '1') THEN shift_reg3 <= '0'; + ELSE shift_reg3 <= ((((shift_reg_load_nominal_enable AND nominal_data14) OR (shift_reg_load_enable AND w64w)) OR (shift_reg_shift_enable AND shift_reg2)) OR (shift_reg_shift_nominal_enable AND shift_reg2)); + END IF; + END IF; + END IF; + END PROCESS; + wire_shift_reg_w_lg_q233w(0) <= shift_reg3 AND wire_w_lg_read_nominal_out216w(0); + wire_shift_reg_w_lg_w_lg_q233w234w(0) <= wire_shift_reg_w_lg_q233w(0) OR wire_add_sub5_w_lg_w_result_range231w232w(0); + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN shift_reg4 <= '0'; + ELSIF (clock = '1' AND clock'event) THEN + IF (wire_shift_reg_ena(4) = '1') THEN + IF (shift_reg_clear = '1') THEN shift_reg4 <= '0'; + ELSE shift_reg4 <= ((((shift_reg_load_nominal_enable AND nominal_data13) OR (shift_reg_load_enable AND w64w)) OR (shift_reg_shift_enable AND shift_reg3)) OR (shift_reg_shift_nominal_enable AND shift_reg3)); + END IF; + END IF; + END IF; + END PROCESS; + wire_shift_reg_w_lg_q238w(0) <= shift_reg4 AND wire_w_lg_read_nominal_out216w(0); + wire_shift_reg_w_lg_w_lg_q238w239w(0) <= wire_shift_reg_w_lg_q238w(0) OR wire_add_sub5_w_lg_w_result_range236w237w(0); + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN shift_reg5 <= '0'; + ELSIF (clock = '1' AND clock'event) THEN + IF (wire_shift_reg_ena(5) = '1') THEN + IF (shift_reg_clear = '1') THEN shift_reg5 <= '0'; + ELSE shift_reg5 <= ((((shift_reg_load_nominal_enable AND nominal_data12) OR (shift_reg_load_enable AND w64w)) OR (shift_reg_shift_enable AND shift_reg4)) OR (shift_reg_shift_nominal_enable AND shift_reg4)); + END IF; + END IF; + END IF; + END PROCESS; + wire_shift_reg_w_lg_q243w(0) <= shift_reg5 AND wire_w_lg_read_nominal_out216w(0); + wire_shift_reg_w_lg_w_lg_q243w244w(0) <= wire_shift_reg_w_lg_q243w(0) OR wire_add_sub5_w_lg_w_result_range241w242w(0); + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN shift_reg6 <= '0'; + ELSIF (clock = '1' AND clock'event) THEN + IF (wire_shift_reg_ena(6) = '1') THEN + IF (shift_reg_clear = '1') THEN shift_reg6 <= '0'; + ELSE shift_reg6 <= ((((shift_reg_load_nominal_enable AND nominal_data11) OR (shift_reg_load_enable AND w64w)) OR (shift_reg_shift_enable AND shift_reg5)) OR (shift_reg_shift_nominal_enable AND shift_reg5)); + END IF; + END IF; + END IF; + END PROCESS; + wire_shift_reg_w_lg_q248w(0) <= shift_reg6 AND wire_w_lg_read_nominal_out216w(0); + wire_shift_reg_w_lg_w_lg_q248w249w(0) <= wire_shift_reg_w_lg_q248w(0) OR wire_add_sub5_w_lg_w_result_range246w247w(0); + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN shift_reg7 <= '0'; + ELSIF (clock = '1' AND clock'event) THEN + IF (wire_shift_reg_ena(7) = '1') THEN + IF (shift_reg_clear = '1') THEN shift_reg7 <= '0'; + ELSE shift_reg7 <= ((((shift_reg_load_nominal_enable AND nominal_data10) OR (shift_reg_load_enable AND w64w)) OR (shift_reg_shift_enable AND shift_reg6)) OR (shift_reg_shift_nominal_enable AND shift_reg6)); + END IF; + END IF; + END IF; + END PROCESS; + wire_shift_reg_w_lg_q253w(0) <= shift_reg7 AND wire_w_lg_read_nominal_out216w(0); + wire_shift_reg_w_lg_w_lg_q253w254w(0) <= wire_shift_reg_w_lg_q253w(0) OR wire_add_sub5_w_lg_w_result_range251w252w(0); + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN shift_reg8 <= '0'; + ELSIF (clock = '1' AND clock'event) THEN + IF (wire_shift_reg_ena(8) = '1') THEN + IF (shift_reg_clear = '1') THEN shift_reg8 <= '0'; + ELSE shift_reg8 <= ((((shift_reg_load_nominal_enable AND nominal_data9) OR (shift_reg_load_enable AND w64w)) OR (shift_reg_shift_enable AND shift_reg7)) OR (shift_reg_shift_nominal_enable AND shift_reg7)); + END IF; + END IF; + END IF; + END PROCESS; + wire_shift_reg_w_lg_q258w(0) <= shift_reg8 AND wire_w_lg_read_nominal_out216w(0); + wire_shift_reg_w_lg_w_lg_q258w259w(0) <= wire_shift_reg_w_lg_q258w(0) OR wire_add_sub5_w_lg_w_result_range256w257w(0); + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN shift_reg9 <= '0'; + ELSIF (clock = '1' AND clock'event) THEN + IF (wire_shift_reg_ena(9) = '1') THEN + IF (shift_reg_clear = '1') THEN shift_reg9 <= '0'; + ELSE shift_reg9 <= ((((shift_reg_load_nominal_enable AND nominal_data8) OR wire_w_lg_shift_reg_load_enable123w(0)) OR (shift_reg_shift_enable AND shift_reg8)) OR (shift_reg_shift_nominal_enable AND shift_reg8)); + END IF; + END IF; + END IF; + END PROCESS; + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN shift_reg10 <= '0'; + ELSIF (clock = '1' AND clock'event) THEN + IF (wire_shift_reg_ena(10) = '1') THEN + IF (shift_reg_clear = '1') THEN shift_reg10 <= '0'; + ELSE shift_reg10 <= ((((shift_reg_load_nominal_enable AND nominal_data7) OR wire_w_lg_shift_reg_load_enable131w(0)) OR (shift_reg_shift_enable AND shift_reg9)) OR (shift_reg_shift_nominal_enable AND shift_reg9)); + END IF; + END IF; + END IF; + END PROCESS; + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN shift_reg11 <= '0'; + ELSIF (clock = '1' AND clock'event) THEN + IF (wire_shift_reg_ena(11) = '1') THEN + IF (shift_reg_clear = '1') THEN shift_reg11 <= '0'; + ELSE shift_reg11 <= ((((shift_reg_load_nominal_enable AND nominal_data6) OR wire_w_lg_shift_reg_load_enable139w(0)) OR (shift_reg_shift_enable AND shift_reg10)) OR (shift_reg_shift_nominal_enable AND shift_reg10)); + END IF; + END IF; + END IF; + END PROCESS; + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN shift_reg12 <= '0'; + ELSIF (clock = '1' AND clock'event) THEN + IF (wire_shift_reg_ena(12) = '1') THEN + IF (shift_reg_clear = '1') THEN shift_reg12 <= '0'; + ELSE shift_reg12 <= ((((shift_reg_load_nominal_enable AND nominal_data5) OR wire_w_lg_shift_reg_load_enable147w(0)) OR (shift_reg_shift_enable AND shift_reg11)) OR (shift_reg_shift_nominal_enable AND shift_reg11)); + END IF; + END IF; + END IF; + END PROCESS; + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN shift_reg13 <= '0'; + ELSIF (clock = '1' AND clock'event) THEN + IF (wire_shift_reg_ena(13) = '1') THEN + IF (shift_reg_clear = '1') THEN shift_reg13 <= '0'; + ELSE shift_reg13 <= ((((shift_reg_load_nominal_enable AND nominal_data4) OR wire_w_lg_shift_reg_load_enable155w(0)) OR (shift_reg_shift_enable AND shift_reg12)) OR (shift_reg_shift_nominal_enable AND shift_reg12)); + END IF; + END IF; + END IF; + END PROCESS; + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN shift_reg14 <= '0'; + ELSIF (clock = '1' AND clock'event) THEN + IF (wire_shift_reg_ena(14) = '1') THEN + IF (shift_reg_clear = '1') THEN shift_reg14 <= '0'; + ELSE shift_reg14 <= ((((shift_reg_load_nominal_enable AND nominal_data3) OR wire_w_lg_shift_reg_load_enable163w(0)) OR (shift_reg_shift_enable AND shift_reg13)) OR (shift_reg_shift_nominal_enable AND shift_reg13)); + END IF; + END IF; + END IF; + END PROCESS; + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN shift_reg15 <= '0'; + ELSIF (clock = '1' AND clock'event) THEN + IF (wire_shift_reg_ena(15) = '1') THEN + IF (shift_reg_clear = '1') THEN shift_reg15 <= '0'; + ELSE shift_reg15 <= ((((shift_reg_load_nominal_enable AND nominal_data2) OR wire_w_lg_shift_reg_load_enable171w(0)) OR (shift_reg_shift_enable AND shift_reg14)) OR (shift_reg_shift_nominal_enable AND shift_reg14)); + END IF; + END IF; + END IF; + END PROCESS; + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN shift_reg16 <= '0'; + ELSIF (clock = '1' AND clock'event) THEN + IF (wire_shift_reg_ena(16) = '1') THEN + IF (shift_reg_clear = '1') THEN shift_reg16 <= '0'; + ELSE shift_reg16 <= ((((shift_reg_load_nominal_enable AND nominal_data1) OR wire_w_lg_shift_reg_load_enable179w(0)) OR (shift_reg_shift_enable AND shift_reg15)) OR (shift_reg_shift_nominal_enable AND shift_reg15)); + END IF; + END IF; + END IF; + END PROCESS; + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN shift_reg17 <= '0'; + ELSIF (clock = '1' AND clock'event) THEN + IF (wire_shift_reg_ena(17) = '1') THEN + IF (shift_reg_clear = '1') THEN shift_reg17 <= '0'; + ELSE shift_reg17 <= ((((shift_reg_load_nominal_enable AND nominal_data0) OR wire_w_lg_shift_reg_load_enable187w(0)) OR (shift_reg_shift_enable AND shift_reg16)) OR (shift_reg_shift_nominal_enable AND shift_reg16)); + END IF; + END IF; + END IF; + END PROCESS; + wire_shift_reg_w_lg_q262w(0) <= shift_reg17 AND wire_w_shift_reg_width_select_range261w(0); + wire_shift_reg_w_lg_q264w(0) <= shift_reg17 AND wire_w_shift_reg_width_select_range263w(0); + wire_shift_reg_w_lg_q267w(0) <= shift_reg17 AND wire_w_shift_reg_width_select_range266w(0); + wire_shift_reg_w_lg_q270w(0) <= shift_reg17 AND wire_w_shift_reg_width_select_range269w(0); + wire_shift_reg_w_lg_q273w(0) <= shift_reg17 AND wire_w_shift_reg_width_select_range272w(0); + wire_shift_reg_w_lg_q276w(0) <= shift_reg17 AND wire_w_shift_reg_width_select_range275w(0); + wire_shift_reg_w_lg_q279w(0) <= shift_reg17 AND wire_w_shift_reg_width_select_range278w(0); + wire_shift_reg_w_lg_q282w(0) <= shift_reg17 AND wire_w_shift_reg_width_select_range281w(0); + loop13 : FOR i IN 0 TO 17 GENERATE + wire_shift_reg_ena(i) <= wire_w63w(0); + END GENERATE loop13; + PROCESS (clock) + BEGIN + IF (clock = '1' AND clock'event) THEN tmp_nominal_data_out_state <= (wire_read_last_nominal_state_w_lg_q1865w(0) OR (tmp_nominal_data_out_state AND idle_state)); + END IF; + END PROCESS; + PROCESS (clock) + BEGIN + IF (clock = '1' AND clock'event) THEN tmp_seq_ena_state <= (reconfig_counter_state AND (C0_data_state AND rotate_width_counter_done)); + END IF; + END PROCESS; + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN write_data_state <= '0'; + ELSIF (clock = '1' AND clock'event) THEN write_data_state <= (write_init_state OR (write_data_state AND wire_w_lg_width_counter_done1744w(0))); + END IF; + END PROCESS; + wire_write_data_state_w_lg_q1726w(0) <= write_data_state AND width_counter_done; + wire_write_data_state_w_lg_q1692w(0) <= NOT write_data_state; + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN write_init_nominal_state <= '0'; + ELSIF (clock = '1' AND clock'event) THEN write_init_nominal_state <= ((idle_state AND write_param) AND ((((((NOT counter_type(3)) AND (NOT counter_type(2))) AND (NOT counter_type(1))) AND counter_param(2)) AND counter_param(1)) AND counter_param(0))); + END IF; + END PROCESS; + wire_write_init_nominal_state_w_lg_q1694w(0) <= NOT write_init_nominal_state; + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN write_init_state <= '0'; + ELSIF (clock = '1' AND clock'event) THEN write_init_state <= ((idle_state AND write_param) AND (NOT ((((((NOT counter_type(3)) AND (NOT counter_type(2))) AND (NOT counter_type(1))) AND counter_param(2)) AND counter_param(1)) AND counter_param(0)))); + END IF; + END PROCESS; + wire_write_init_state_w_lg_q1690w(0) <= NOT write_init_state; + wire_write_init_state_w_lg_q1853w(0) <= write_init_state OR write_init_nominal_state; + PROCESS (clock, reset) + BEGIN + IF (reset = '1') THEN write_nominal_state <= '0'; + ELSIF (clock = '1' AND clock'event) THEN write_nominal_state <= (write_init_nominal_state OR (write_nominal_state AND wire_w_lg_width_counter_done1744w(0))); + END IF; + END PROCESS; + wire_write_nominal_state_w_lg_q1725w(0) <= write_nominal_state AND width_counter_done; + wire_write_nominal_state_w_lg_q1696w(0) <= NOT write_nominal_state; + wire_add_sub5_w_lg_w_result_range214w215w(0) <= wire_add_sub5_w_result_range214w(0) AND read_nominal_out; + wire_add_sub5_w_lg_w_result_range221w222w(0) <= wire_add_sub5_w_result_range221w(0) AND read_nominal_out; + wire_add_sub5_w_lg_w_result_range226w227w(0) <= wire_add_sub5_w_result_range226w(0) AND read_nominal_out; + wire_add_sub5_w_lg_w_result_range231w232w(0) <= wire_add_sub5_w_result_range231w(0) AND read_nominal_out; + wire_add_sub5_w_lg_w_result_range236w237w(0) <= wire_add_sub5_w_result_range236w(0) AND read_nominal_out; + wire_add_sub5_w_lg_w_result_range241w242w(0) <= wire_add_sub5_w_result_range241w(0) AND read_nominal_out; + wire_add_sub5_w_lg_w_result_range246w247w(0) <= wire_add_sub5_w_result_range246w(0) AND read_nominal_out; + wire_add_sub5_w_lg_w_result_range251w252w(0) <= wire_add_sub5_w_result_range251w(0) AND read_nominal_out; + wire_add_sub5_w_lg_w_result_range256w257w(0) <= wire_add_sub5_w_result_range256w(0) AND read_nominal_out; + wire_add_sub5_dataa <= ( "0" & shift_reg8 & shift_reg7 & shift_reg6 & shift_reg5 & shift_reg4 & shift_reg3 & shift_reg2 & shift_reg1); + wire_add_sub5_datab <= ( "0" & shift_reg17 & shift_reg16 & shift_reg15 & shift_reg14 & shift_reg13 & shift_reg12 & shift_reg11 & shift_reg10); + wire_add_sub5_w_result_range214w(0) <= wire_add_sub5_result(0); + wire_add_sub5_w_result_range221w(0) <= wire_add_sub5_result(1); + wire_add_sub5_w_result_range226w(0) <= wire_add_sub5_result(2); + wire_add_sub5_w_result_range231w(0) <= wire_add_sub5_result(3); + wire_add_sub5_w_result_range236w(0) <= wire_add_sub5_result(4); + wire_add_sub5_w_result_range241w(0) <= wire_add_sub5_result(5); + wire_add_sub5_w_result_range246w(0) <= wire_add_sub5_result(6); + wire_add_sub5_w_result_range251w(0) <= wire_add_sub5_result(7); + wire_add_sub5_w_result_range256w(0) <= wire_add_sub5_result(8); + add_sub5 : lpm_add_sub + GENERIC MAP ( + LPM_WIDTH => 9 + ) + PORT MAP ( + cin => wire_gnd, + dataa => wire_add_sub5_dataa, + datab => wire_add_sub5_datab, + result => wire_add_sub5_result + ); + wire_add_sub6_dataa <= ( data_in(8 DOWNTO 1)); + add_sub6 : lpm_add_sub + GENERIC MAP ( + LPM_WIDTH => 8 + ) + PORT MAP ( + cin => data_in(0), + dataa => wire_add_sub6_dataa, + result => wire_add_sub6_result + ); + wire_cmpr7_dataa <= ( data_in(7 DOWNTO 0)); + wire_cmpr7_datab <= "00000001"; + cmpr7 : lpm_compare + GENERIC MAP ( + LPM_WIDTH => 8 + ) + PORT MAP ( + aeb => wire_cmpr7_aeb, + dataa => wire_cmpr7_dataa, + datab => wire_cmpr7_datab + ); + cntr1 : lpm_counter + GENERIC MAP ( + lpm_direction => "DOWN", + lpm_modulus => 144, + lpm_port_updown => "PORT_UNUSED", + lpm_width => 8 + ) + PORT MAP ( + clock => clock, + cnt_en => addr_counter_enable, + data => addr_counter_sload_value, + q => wire_cntr1_q, + sload => addr_counter_sload + ); + cntr12 : lpm_counter + GENERIC MAP ( + lpm_direction => "DOWN", + lpm_modulus => 144, + lpm_port_updown => "PORT_UNUSED", + lpm_width => 8 + ) + PORT MAP ( + clock => clock, + cnt_en => reconfig_addr_counter_enable, + data => reconfig_addr_counter_sload_value, + q => wire_cntr12_q, + sload => reconfig_addr_counter_sload + ); + cntr13 : lpm_counter + GENERIC MAP ( + lpm_direction => "DOWN", + lpm_port_updown => "PORT_UNUSED", + lpm_width => 6 + ) + PORT MAP ( + clock => clock, + cnt_en => reconfig_width_counter_enable, + data => reconfig_width_counter_sload_value, + q => wire_cntr13_q, + sload => reconfig_width_counter_sload + ); + cntr14 : lpm_counter + GENERIC MAP ( + lpm_direction => "DOWN", + lpm_port_updown => "PORT_UNUSED", + lpm_width => 5 + ) + PORT MAP ( + clock => clock, + cnt_en => rotate_width_counter_enable, + data => rotate_width_counter_sload_value, + q => wire_cntr14_q, + sload => rotate_width_counter_sload + ); + cntr15 : lpm_counter + GENERIC MAP ( + lpm_direction => "DOWN", + lpm_modulus => 144, + lpm_port_updown => "PORT_UNUSED", + lpm_width => 8 + ) + PORT MAP ( + clock => clock, + cnt_en => rotate_addr_counter_enable, + data => rotate_addr_counter_sload_value, + q => wire_cntr15_q, + sload => rotate_addr_counter_sload + ); + cntr2 : lpm_counter + GENERIC MAP ( + lpm_direction => "UP", + lpm_port_updown => "PORT_UNUSED", + lpm_width => 8 + ) + PORT MAP ( + clock => clock, + cnt_en => read_addr_counter_enable, + data => read_addr_counter_sload_value, + q => wire_cntr2_q, + sload => read_addr_counter_sload + ); + cntr3 : lpm_counter + GENERIC MAP ( + lpm_direction => "DOWN", + lpm_port_updown => "PORT_UNUSED", + lpm_width => 5 + ) + PORT MAP ( + clock => clock, + cnt_en => width_counter_enable, + data => width_counter_sload_value, + q => wire_cntr3_q, + sload => width_counter_sload + ); + decode11 : lpm_decode + GENERIC MAP ( + LPM_DECODES => 5, + LPM_WIDTH => 3 + ) + PORT MAP ( + data => cuda_combout_wire, + eq => wire_decode11_eq + ); + + END RTL; --altpll_reconfig1_pllrcfg_t4q +--VALID FILE + + +LIBRARY ieee; +USE ieee.std_logic_1164.all; + +ENTITY altpll_reconfig1 IS + PORT + ( + clock : IN STD_LOGIC ; + counter_param : IN STD_LOGIC_VECTOR (2 DOWNTO 0); + counter_type : IN STD_LOGIC_VECTOR (3 DOWNTO 0); + data_in : IN STD_LOGIC_VECTOR (8 DOWNTO 0); + pll_areset_in : IN STD_LOGIC := '0'; + pll_scandataout : IN STD_LOGIC ; + pll_scandone : IN STD_LOGIC ; + read_param : IN STD_LOGIC ; + reconfig : IN STD_LOGIC ; + reset : IN STD_LOGIC ; + write_param : IN STD_LOGIC ; + busy : OUT STD_LOGIC ; + data_out : OUT STD_LOGIC_VECTOR (8 DOWNTO 0); + pll_areset : OUT STD_LOGIC ; + pll_configupdate : OUT STD_LOGIC ; + pll_scanclk : OUT STD_LOGIC ; + pll_scanclkena : OUT STD_LOGIC ; + pll_scandata : OUT STD_LOGIC + ); +END altpll_reconfig1; + + +ARCHITECTURE RTL OF altpll_reconfig1 IS + + ATTRIBUTE synthesis_clearbox: natural; + ATTRIBUTE synthesis_clearbox OF RTL: ARCHITECTURE IS 2; + ATTRIBUTE clearbox_macroname: string; + ATTRIBUTE clearbox_macroname OF RTL: ARCHITECTURE IS "altpll_reconfig"; + ATTRIBUTE clearbox_defparam: string; + ATTRIBUTE clearbox_defparam OF RTL: ARCHITECTURE IS "intended_device_family=Cyclone III;"; + SIGNAL sub_wire0 : STD_LOGIC ; + SIGNAL sub_wire1 : STD_LOGIC_VECTOR (8 DOWNTO 0); + SIGNAL sub_wire2 : STD_LOGIC ; + SIGNAL sub_wire3 : STD_LOGIC ; + SIGNAL sub_wire4 : STD_LOGIC ; + SIGNAL sub_wire5 : STD_LOGIC ; + SIGNAL sub_wire6 : STD_LOGIC ; + + + + COMPONENT altpll_reconfig1_pllrcfg_t4q + PORT ( + counter_param : IN STD_LOGIC_VECTOR (2 DOWNTO 0); + data_in : IN STD_LOGIC_VECTOR (8 DOWNTO 0); + pll_configupdate : OUT STD_LOGIC ; + counter_type : IN STD_LOGIC_VECTOR (3 DOWNTO 0); + data_out : OUT STD_LOGIC_VECTOR (8 DOWNTO 0); + pll_areset_in : IN STD_LOGIC ; + reconfig : IN STD_LOGIC ; + pll_scanclk : OUT STD_LOGIC ; + pll_scanclkena : OUT STD_LOGIC ; + pll_scandata : OUT STD_LOGIC ; + pll_scandataout : IN STD_LOGIC ; + pll_scandone : IN STD_LOGIC ; + busy : OUT STD_LOGIC ; + pll_areset : OUT STD_LOGIC ; + reset : IN STD_LOGIC ; + write_param : IN STD_LOGIC ; + clock : IN STD_LOGIC ; + read_param : IN STD_LOGIC + ); + END COMPONENT; + +BEGIN + pll_configupdate <= sub_wire0; + data_out <= sub_wire1(8 DOWNTO 0); + pll_scanclk <= sub_wire2; + pll_scanclkena <= sub_wire3; + pll_scandata <= sub_wire4; + busy <= sub_wire5; + pll_areset <= sub_wire6; + + altpll_reconfig1_pllrcfg_t4q_component : altpll_reconfig1_pllrcfg_t4q + PORT MAP ( + counter_param => counter_param, + data_in => data_in, + counter_type => counter_type, + pll_areset_in => pll_areset_in, + reconfig => reconfig, + pll_scandataout => pll_scandataout, + pll_scandone => pll_scandone, + reset => reset, + write_param => write_param, + clock => clock, + read_param => read_param, + pll_configupdate => sub_wire0, + data_out => sub_wire1, + pll_scanclk => sub_wire2, + pll_scanclkena => sub_wire3, + pll_scandata => sub_wire4, + busy => sub_wire5, + pll_areset => sub_wire6 + ); + + + +END RTL; + +-- ============================================================ +-- CNX file retrieval info +-- ============================================================ +-- Retrieval info: PRIVATE: CHAIN_TYPE NUMERIC "0" +-- Retrieval info: PRIVATE: INIT_FILE_NAME STRING "" +-- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone III" +-- Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0" +-- Retrieval info: PRIVATE: USE_INIT_FILE STRING "0" +-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III" +-- Retrieval info: USED_PORT: busy 0 0 0 0 OUTPUT NODEFVAL "busy" +-- Retrieval info: USED_PORT: clock 0 0 0 0 INPUT NODEFVAL "clock" +-- Retrieval info: USED_PORT: counter_param 0 0 3 0 INPUT NODEFVAL "counter_param[2..0]" +-- Retrieval info: USED_PORT: counter_type 0 0 4 0 INPUT NODEFVAL "counter_type[3..0]" +-- Retrieval info: USED_PORT: data_in 0 0 9 0 INPUT NODEFVAL "data_in[8..0]" +-- Retrieval info: USED_PORT: data_out 0 0 9 0 OUTPUT NODEFVAL "data_out[8..0]" +-- Retrieval info: USED_PORT: pll_areset 0 0 0 0 OUTPUT NODEFVAL "pll_areset" +-- Retrieval info: USED_PORT: pll_areset_in 0 0 0 0 INPUT GND "pll_areset_in" +-- Retrieval info: USED_PORT: pll_configupdate 0 0 0 0 OUTPUT NODEFVAL "pll_configupdate" +-- Retrieval info: USED_PORT: pll_scanclk 0 0 0 0 OUTPUT NODEFVAL "pll_scanclk" +-- Retrieval info: USED_PORT: pll_scanclkena 0 0 0 0 OUTPUT NODEFVAL "pll_scanclkena" +-- Retrieval info: USED_PORT: pll_scandata 0 0 0 0 OUTPUT NODEFVAL "pll_scandata" +-- Retrieval info: USED_PORT: pll_scandataout 0 0 0 0 INPUT NODEFVAL "pll_scandataout" +-- Retrieval info: USED_PORT: pll_scandone 0 0 0 0 INPUT NODEFVAL "pll_scandone" +-- Retrieval info: USED_PORT: read_param 0 0 0 0 INPUT NODEFVAL "read_param" +-- Retrieval info: USED_PORT: reconfig 0 0 0 0 INPUT NODEFVAL "reconfig" +-- Retrieval info: USED_PORT: reset 0 0 0 0 INPUT NODEFVAL "reset" +-- Retrieval info: USED_PORT: write_param 0 0 0 0 INPUT NODEFVAL "write_param" +-- Retrieval info: CONNECT: @clock 0 0 0 0 clock 0 0 0 0 +-- Retrieval info: CONNECT: @counter_param 0 0 3 0 counter_param 0 0 3 0 +-- Retrieval info: CONNECT: @counter_type 0 0 4 0 counter_type 0 0 4 0 +-- Retrieval info: CONNECT: @data_in 0 0 9 0 data_in 0 0 9 0 +-- Retrieval info: CONNECT: @pll_areset_in 0 0 0 0 pll_areset_in 0 0 0 0 +-- Retrieval info: CONNECT: @pll_scandataout 0 0 0 0 pll_scandataout 0 0 0 0 +-- Retrieval info: CONNECT: @pll_scandone 0 0 0 0 pll_scandone 0 0 0 0 +-- Retrieval info: CONNECT: @read_param 0 0 0 0 read_param 0 0 0 0 +-- Retrieval info: CONNECT: @reconfig 0 0 0 0 reconfig 0 0 0 0 +-- Retrieval info: CONNECT: @reset 0 0 0 0 reset 0 0 0 0 +-- Retrieval info: CONNECT: @write_param 0 0 0 0 write_param 0 0 0 0 +-- Retrieval info: CONNECT: busy 0 0 0 0 @busy 0 0 0 0 +-- Retrieval info: CONNECT: data_out 0 0 9 0 @data_out 0 0 9 0 +-- Retrieval info: CONNECT: pll_areset 0 0 0 0 @pll_areset 0 0 0 0 +-- Retrieval info: CONNECT: pll_configupdate 0 0 0 0 @pll_configupdate 0 0 0 0 +-- Retrieval info: CONNECT: pll_scanclk 0 0 0 0 @pll_scanclk 0 0 0 0 +-- Retrieval info: CONNECT: pll_scanclkena 0 0 0 0 @pll_scanclkena 0 0 0 0 +-- Retrieval info: CONNECT: pll_scandata 0 0 0 0 @pll_scandata 0 0 0 0 +-- Retrieval info: GEN_FILE: TYPE_NORMAL altpll_reconfig1.vhd TRUE +-- Retrieval info: GEN_FILE: TYPE_NORMAL altpll_reconfig1.inc FALSE +-- Retrieval info: GEN_FILE: TYPE_NORMAL altpll_reconfig1.cmp FALSE +-- Retrieval info: GEN_FILE: TYPE_NORMAL altpll_reconfig1.bsf FALSE +-- Retrieval info: GEN_FILE: TYPE_NORMAL altpll_reconfig1_inst.vhd FALSE diff --git a/vhdl/rtl/vhdl/Firebee_V1/greybox_tmp/cbx_args.txt b/vhdl/rtl/vhdl/Firebee_V1/greybox_tmp/cbx_args.txt new file mode 100644 index 0000000..c6df87a --- /dev/null +++ b/vhdl/rtl/vhdl/Firebee_V1/greybox_tmp/cbx_args.txt @@ -0,0 +1,20 @@ +INTENDED_DEVICE_FAMILY="Cyclone III" +DEVICE_FAMILY="Cyclone III" +clock +counter_param +counter_type +data_in +pll_areset_in +pll_scandataout +pll_scandone +read_param +reconfig +reset +write_param +busy +data_out +pll_areset +pll_configupdate +pll_scanclk +pll_scanclkena +pll_scandata diff --git a/vhdl/rtl/vhdl/Interrupt/interrupt.vhd b/vhdl/rtl/vhdl/Interrupt/interrupt.vhd new file mode 100644 index 0000000..c9f5116 --- /dev/null +++ b/vhdl/rtl/vhdl/Interrupt/interrupt.vhd @@ -0,0 +1,306 @@ +---------------------------------------------------------------------- +---- ---- +---- This file is part of the 'Firebee' project. ---- +---- http://acp.atari.org ---- +---- ---- +---- Description: ---- +---- This design unit provides the interruptlogic of the 'Firebee'---- +---- computer. It is optimized for the use of an Altera Cyclone ---- +---- FPGA (EP3C40F484). This IP-Core is based on the first edi- ---- +---- tion of the Firebee configware originally provided by Fredi ---- +---- Ashwanden and Wolfgang Förster. This release is in compa- ---- +---- rision to the first edition completely written in VHDL. ---- +---- ---- +---- Author(s): ---- +---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2012 Fredi Aschwanden, Wolfgang Förster ---- +---- ---- +---- This source file 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 2 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, write to the Free ---- +---- Software Foundation, Inc., 51 Franklin Street, Fifth Floor, ---- +---- Boston, MA 02110-1301, USA. ---- +---- ---- +---------------------------------------------------------------------- +-- +-- Revision History +-- +-- Revision 2K12B 20120801 WF +-- Initial Release of the second edition. + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; +use ieee.std_logic_arith.all; + +entity INTHANDLER is + port( + CLK_MAIN : in std_logic; + RESETn : in std_logic; + FB_ADR : in std_logic_vector(31 downto 0); + FB_CSn : in std_logic_vector(2 downto 1); + FB_SIZE0 : in std_logic; + FB_SIZE1 : in std_logic; + FB_WRn : in std_logic; + FB_OEn : in std_logic; + FB_AD_IN : in std_logic_vector(31 downto 0); + FB_AD_OUT : out std_logic_vector(31 downto 0); + FB_AD_EN_31_24 : out std_logic; + FB_AD_EN_23_16 : out std_logic; + FB_AD_EN_15_8 : out std_logic; + FB_AD_EN_7_0 : out std_logic; + PIC_INT : in std_logic; + E0_INT : in std_logic; + DVI_INT : in std_logic; + PCI_INTAn : in std_logic; + PCI_INTBn : in std_logic; + PCI_INTCn : in std_logic; + PCI_INTDn : in std_logic; + MFP_INTn : in std_logic; + DSP_INT : in std_logic; + VSYNC : in std_logic; + HSYNC : in std_logic; + DRQ_DMA : in std_logic; + IRQn : out std_logic_vector(7 downto 2); + INT_HANDLER_TA : out std_logic; + FBEE_CONF : out std_logic_vector(31 downto 0); + TIN0 : out std_logic + ); +end entity INTHANDLER; + +architecture BEHAVIOUR of INTHANDLER is +type INT_LA_TYPE is array(9 downto 0) of std_logic_vector(3 downto 0); +signal INT_LA : INT_LA_TYPE; +signal FB_B : std_logic_vector(3 downto 0); +signal INT_CTR : std_logic_vector(31 downto 0); +signal INT_CTR_CS : std_logic; +signal INT_LATCH : std_logic_vector(31 downto 0); +signal INT_LATCH_CS : std_logic; +signal INT_CLEAR : std_logic_vector(31 downto 0); +signal INT_CLEAR_CS : std_logic; +signal INT_IN : std_logic_vector(31 downto 0); +signal INT_ENA : std_logic_vector(31 downto 0); +signal INT_ENA_CS : std_logic; +signal INT_L : std_logic_vector(9 downto 0); +signal FBEE_CONF_REG : std_logic_vector(31 downto 0); +signal FBEE_CONF_CS : std_logic; +signal PSEUDO_BUS_ERROR : std_logic; +begin + -- Byte selectors: + FB_B(0) <= '1' when FB_SIZE1 = '1' and FB_SIZE0 = '0' and FB_ADR(1) = '0' else -- High word. + '1' when FB_SIZE1 = '0' and FB_SIZE0 = '1' and FB_ADR(1 downto 0) = "00" else -- HH Byte. + '1' when FB_SIZE1 = '0' and FB_SIZE0 = '0' else -- Long. + '1' when FB_SIZE1 = '1' and FB_SIZE0 = '1' else '0';-- Line. + + FB_B(1) <= '1' when FB_SIZE1 = '1' and FB_SIZE0 = '0' and FB_ADR(1) = '0' else -- High word. + '1' when FB_SIZE1 = '0' and FB_SIZE0 = '1' and FB_ADR(1 downto 0) = "01" else -- HL Byte. + '1' when FB_SIZE1 = '0' and FB_SIZE0 = '0' else -- Long. + '1' when FB_SIZE1 = '1' and FB_SIZE0 = '1' else '0';-- Line. + + FB_B(2) <= '1' when FB_SIZE1 = '1' and FB_SIZE0 = '0' and FB_ADR(1) = '1' else -- Low word. + '1' when FB_SIZE1 = '0' and FB_SIZE0 = '1' and FB_ADR(1 downto 0) = "10" else -- LH Byte. + '1' when FB_SIZE1 = '0' and FB_SIZE0 = '0' else -- Long. + '1' when FB_SIZE1 = '1' and FB_SIZE0 = '1' else '0';-- Line. + + FB_B(3) <= '1' when FB_SIZE1 = '1' and FB_SIZE0 = '0' and FB_ADR(1) = '1' else -- Low word. + '1' when FB_SIZE1 = '0' and FB_SIZE0 = '1' and FB_ADR(1 downto 0) = "11" else -- LL Byte. + '1' when FB_SIZE1 = '0' and FB_SIZE0 = '0' else -- Long. + '1' when FB_SIZE1 = '1' and FB_SIZE0 = '1' else '0';-- Line. + + INT_CTR_CS <= '1' when FB_CSn(2) = '0' and FB_ADR(27 downto 2) = "00000000000100000000000000" else '0'; -- $10000/4; + INT_ENA_CS <= '1' when FB_CSn(2) = '0' and FB_ADR(27 downto 2) = "00000000000100000000000001" else '0'; -- $10004/4; + INT_CLEAR_CS <= '1' when FB_CSn(2) = '0' and FB_ADR(27 downto 2) = "00000000000100000000000010" else '0'; -- $10008/4; + INT_LATCH_CS <= '1' when FB_CSn(2) = '0' and FB_ADR(27 downto 2) = "00000000000100000000000011" else '0'; -- $1000C/4; + + P_INT_CTRL : process + -- Interrupt control register: + --BIT0 = INT5, Bit1 = INT7. + -- Interrupt enabe register: + -- BIT31 = INT7, Bit30 = INT6, Bit29 = INT5, Bit28 = INT4, Bit27 = INT3, Bit26 = INT2 + -- The interrupt clear register is write only; 1 = interrupt clear. + begin + wait until CLK_MAIN = '1' and CLK_MAIN' event; + if INT_CTR_CS = '1' and FB_B(0) = '1' and FB_WRn = '0' then + INT_CTR(31 downto 24) <= FB_AD_IN(31 downto 24); + elsif INT_CTR_CS = '1' and FB_B(1) = '1' and FB_WRn = '0' then + INT_CTR(23 downto 16) <= FB_AD_IN(23 downto 16); + elsif INT_CTR_CS = '1' and FB_B(2) = '1' and FB_WRn = '0' then + INT_CTR(15 downto 8) <= FB_AD_IN(15 downto 8); + elsif INT_CTR_CS = '1' and FB_B(3) = '1' and FB_WRn = '0' then + INT_CTR(7 downto 0) <= FB_AD_IN(7 downto 0); + end if; + -- + if RESETn = '0' then + INT_ENA <= (others => '0'); + elsif INT_ENA_CS = '1' and FB_B(0) = '1' and FB_WRn = '0' then + INT_ENA(31 downto 24) <= FB_AD_IN(31 downto 24); + elsif INT_ENA_CS = '1' and FB_B(1) = '1' and FB_WRn = '0' then + INT_ENA(23 downto 16) <= FB_AD_IN(23 downto 16); + elsif INT_ENA_CS = '1' and FB_B(2) = '1' and FB_WRn = '0' then + INT_ENA(15 downto 8) <= FB_AD_IN(15 downto 8); + elsif INT_ENA_CS = '1' and FB_B(3) = '1' and FB_WRn = '0' then + INT_ENA(7 downto 0) <= FB_AD_IN(7 downto 0); + end if; + -- + if INT_CLEAR_CS = '1' and FB_B(0) = '1' and FB_WRn = '0' then + INT_CLEAR(31 downto 24) <= FB_AD_IN(31 downto 24); + elsif INT_CLEAR_CS = '1' and FB_B(1) = '1' and FB_WRn = '0' then + INT_CLEAR(23 downto 16) <= FB_AD_IN(23 downto 16); + elsif INT_CLEAR_CS = '1' and FB_B(2) = '1' and FB_WRn = '0' then + INT_CLEAR(15 downto 8) <= FB_AD_IN(15 downto 8); + elsif INT_CLEAR_CS = '1' and FB_B(3) = '1' and FB_WRn = '0' then + INT_CLEAR(7 downto 0) <= FB_AD_IN(7 downto 0); + end if; + end process P_INT_CTRL; + + -- Interrupt latch register: read only. + IRQn(2) <= '0' when HSYNC = '1' and INT_ENA(26) = '1' else '1'; + IRQn(3) <= '0' when INT_CTR(0) = '1' and INT_ENA(27) = '1' else '1'; + IRQn(4) <= '0' when VSYNC = '1' and INT_ENA(28) = '1' else '1'; + IRQn(5) <= '0' when INT_LATCH /= x"00000000" and INT_ENA(29) = '1' else '1'; + IRQn(6) <= '0' when MFP_INTn = '0' and INT_ENA(30) = '1' else '1'; + IRQn(7) <= '0' when PSEUDO_BUS_ERROR = '1' and INT_ENA(31) = '1' else '1'; + + PSEUDO_BUS_ERROR <= '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 4) = x"F8C8" else -- SCC + '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 4) = x"F8E0" else -- VME + -- '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 4) = x"F920" else -- PADDLE + -- '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 4) = x"F921" else -- PADDLE + -- '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 4) = x"F922" else -- PADDLE + '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 4) = x"FFA8" else -- MFP2 + '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 4) = x"FFA9" else -- MFP2 + '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 4) = x"FFAA" else -- MFP2 + '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 4) = x"FFA8" else -- MFP2 + '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 8) = x"F87" else -- TT SCSI + '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 4) = x"FFC2" else -- ST UHR + '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 4) = x"FFC3" else '0'; -- ST UHR + -- '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 4) = x"F890" else -- DMA SOUND + -- '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 4) = x"F891" else -- DMA SOUND + -- '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 4) = x"F892" else '0'; -- DMA SOUND + + -- IF video ADR changes: + TIN0 <= '1' when FB_CSn(1) = '0' and FB_WRn = '0' and FB_ADR(19 downto 1) = x"7C100" else '0'; -- Write video base address high 0xFFFF8201/2. + + P_INT_LATCH : process + begin + wait until CLK_MAIN = '1' and CLK_MAIN' event; + if RESETn = '0' then + INT_L <= (others => '0'); + else + INT_L(0) <= PIC_INT and INT_ENA(0); + INT_L(1) <= E0_INT and INT_ENA(1); + INT_L(2) <= DVI_INT and INT_ENA(2); + INT_L(3) <= not PCI_INTAn and INT_ENA(3); + INT_L(4) <= not PCI_INTBn and INT_ENA(4); + INT_L(5) <= not PCI_INTCn and INT_ENA(5); + INT_L(6) <= not PCI_INTDn and INT_ENA(6); + INT_L(7) <= DSP_INT and INT_ENA(7); + INT_L(8) <= VSYNC and INT_ENA(8); + INT_L(9) <= HSYNC and INT_ENA(9); + end if; + + for i in 0 to 9 loop + if INT_ENA(i) = '1' and RESETn = '1' then + INT_LA(i) <= x"0"; + elsif INT_L(i) = '1' and INT_LA(i) < x"7" then + INT_LA(i) <= INT_LA(i) + '1'; + elsif INT_L(i) = '0' and INT_LA(i) > x"8" then + INT_LA(i) <= INT_LA(i) - '1'; + elsif INT_L(i) = '1' and INT_LA(i) > x"6" then + INT_LA(i) <= x"F"; + elsif INT_L(i) = '0' and INT_LA(i) > x"9" then + INT_LA(i) <= x"0"; + end if; + end loop; + + for i in 0 to 31 loop + if INT_CLEAR(i) = '0' and RESETn = '1' then + INT_LATCH(i) <= '0'; + end if; + end loop; + + for i in 0 to 9 loop + if INT_LA(i)(3) = '1' then + INT_LATCH(i) <= '1'; + end if; + end loop; + end process P_INT_LATCH; + + -- INT_IN: + INT_IN(0) <= PIC_INT; + INT_IN(1) <= E0_INT; + INT_IN(2) <= DVI_INT; + INT_IN(3) <= not PCI_INTAn; + INT_IN(4) <= not PCI_INTBn; + INT_IN(5) <= not PCI_INTCn; + INT_IN(6) <= not PCI_INTDn; + INT_IN(7) <= DSP_INT; + INT_IN(8) <= VSYNC; + INT_IN(9) <= HSYNC; + INT_IN(25 downto 10) <= x"0000"; + INT_IN(26) <= HSYNC; + INT_IN(27) <= INT_CTR(0); + INT_IN(28) <= VSYNC; + INT_IN(29) <= '1' when INT_LATCH /= x"00000000"; + INT_IN(30) <= not MFP_INTn; + INT_IN(31) <= DRQ_DMA; + + FBEE_CONF_CS <= '1' when FB_CSn(2) = '0' and FB_ADR(27 downto 2) = "00000001000000000000000000" else '0'; -- $40000/4. + + P_FBEE_CONFIG : process + -- Firebee configuration register: BIT 31 -> 0 = CF 1 = IDE + begin + wait until CLK_MAIN = '1' and CLK_MAIN' event; + if FBEE_CONF_CS = '1' and FB_B(0) = '1' and FB_WRn = '0' then + FBEE_CONF_REG(31 downto 24) <= FB_AD_IN(31 downto 24); + elsif FBEE_CONF_CS = '1' and FB_B(1) = '1' and FB_WRn = '0' then + FBEE_CONF_REG(23 downto 16) <= FB_AD_IN(23 downto 16); + elsif FBEE_CONF_CS = '1' and FB_B(2) = '1' and FB_WRn = '0' then + FBEE_CONF_REG(15 downto 8) <= FB_AD_IN(15 downto 8); + elsif FBEE_CONF_CS = '1' and FB_B(3) = '1' and FB_WRn = '0' then + FBEE_CONF_REG(7 downto 0) <= FB_AD_IN(7 downto 0); + end if; + FBEE_CONF <= FBEE_CONF_REG; + end process P_FBEE_CONFIG; + + -- Data out multiplexers: + FB_AD_EN_31_24 <= (INT_CTR_CS or INT_ENA_CS or INT_LATCH_CS or INT_CLEAR_CS or FBEE_CONF_CS) and not FB_OEn; + FB_AD_EN_23_16 <= (INT_CTR_CS or INT_ENA_CS or INT_LATCH_CS or INT_CLEAR_CS or FBEE_CONF_CS) and not FB_OEn; + FB_AD_EN_15_8 <= (INT_CTR_CS or INT_ENA_CS or INT_LATCH_CS or INT_CLEAR_CS or FBEE_CONF_CS) and not FB_OEn; + FB_AD_EN_7_0 <= (INT_CTR_CS or INT_ENA_CS or INT_LATCH_CS or INT_CLEAR_CS or FBEE_CONF_CS) and not FB_OEn; + + FB_AD_OUT(31 downto 24) <= INT_CTR(31 downto 24) when INT_CTR_CS = '1' else + INT_ENA(31 downto 24) when INT_ENA_CS = '1' else + INT_LATCH(31 downto 24) when INT_LATCH_CS = '1' else + INT_IN(31 downto 24) when INT_CLEAR_CS = '1' else FBEE_CONF_REG(31 downto 24); + + FB_AD_OUT(23 downto 16) <= INT_CTR(23 downto 16) when INT_CTR_CS = '1' else + INT_ENA(23 downto 16) when INT_ENA_CS = '1' else + INT_LATCH(23 downto 16) when INT_LATCH_CS = '1' else + INT_IN(23 downto 16) when INT_CLEAR_CS = '1' else FBEE_CONF_REG(23 downto 16); + + FB_AD_OUT(15 downto 8) <= INT_CTR(15 downto 8) when INT_CTR_CS = '1' else + INT_ENA(15 downto 8) when INT_ENA_CS = '1' else + INT_LATCH(15 downto 8) when INT_LATCH_CS = '1' else + INT_CLEAR(15 downto 8) when INT_CLEAR_CS = '1' else FBEE_CONF_REG(15 downto 8); + + FB_AD_OUT(7 downto 0) <= INT_CTR(7 downto 0) when INT_CTR_CS = '1' else + INT_ENA(7 downto 0) when INT_ENA_CS = '1' else + INT_LATCH(7 downto 0) when INT_LATCH_CS = '1' else + INT_CLEAR(7 downto 0) when INT_CLEAR_CS = '1' else FBEE_CONF_REG(7 downto 0); + + INT_HANDLER_TA <= INT_CTR_CS or INT_ENA_CS or INT_LATCH_CS or INT_CLEAR_CS; +end architecture BEHAVIOUR; diff --git a/vhdl/rtl/vhdl/Peripherals/ide_cf_sd_rom.vhd b/vhdl/rtl/vhdl/Peripherals/ide_cf_sd_rom.vhd new file mode 100644 index 0000000..52e213d --- /dev/null +++ b/vhdl/rtl/vhdl/Peripherals/ide_cf_sd_rom.vhd @@ -0,0 +1,181 @@ +---------------------------------------------------------------------- +---- ---- +---- This file is part of the 'Firebee' project. ---- +---- http://acp.atari.org ---- +---- ---- +---- Description: ---- +---- This design unit provides peripheral logic for the 'Firebee' ---- +---- computer. It is optimized for the use of an Altera Cyclone ---- +---- FPGA (EP3C40F484). This IP-Core is based on the first edi- ---- +---- tion of the Firebee configware originally provided by Fredi ---- +---- Ashwanden and Wolfgang Förster. This release is in compa- ---- +---- rision to the first edition completely written in VHDL. ---- +---- ---- +---- Author(s): ---- +---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2012 Fredi Aschwanden, Wolfgang Förster ---- +---- ---- +---- This source file 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 2 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, write to the Free ---- +---- Software Foundation, Inc., 51 Franklin Street, Fifth Floor, ---- +---- Boston, MA 02110-1301, USA. ---- +---- ---- +---------------------------------------------------------------------- +-- +-- Revision History +-- +-- Revision 2K12B 20120801 WF +-- Initial Release of the second edition. + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + +entity IDE_CF_SD_ROM is + port( + RESET : in std_logic; + CLK_MAIN : in std_logic; + + FB_ADR : in std_logic_vector(19 downto 5); + FB_CS1n : in std_logic; + FB_WRn : in std_logic; + FB_B0 : in std_logic; + FB_B1 : in std_logic; + + FBEE_CONF : in std_logic_vector(31 downto 30); + + RP_UDSn : out std_logic; + RP_LDSn : out std_logic; + + SD_CLK : out std_logic; + SD_D0 : in std_logic; + SD_D1 : in std_logic; + SD_D2 : in std_logic; + SD_CD_D3_IN : in std_logic; + SD_CD_D3_OUT : out std_logic; + SD_CD_D3_EN : out std_logic; + SD_CMD_D1_IN : in std_logic; + SD_CMD_D1_OUT : out std_logic; + SD_CMD_D1_EN : out std_logic; + SD_CARD_DETECT : in std_logic; + SD_WP : in std_logic; + + IDE_RDY : in std_logic; + IDE_WRn : buffer std_logic; + IDE_RDn : out std_logic; + IDE_CSn : out std_logic_vector(1 downto 0); + IDE_DRQn : out std_logic; + IDE_CF_TA : out std_logic; + + ROM4n : out std_logic; + ROM3n : out std_logic; + + CF_WP : in bit; + CF_CSn : out std_logic_vector(1 downto 0) + ); +end entity IDE_CF_SD_ROM; + +architecture BEHAVIOUR of IDE_CF_SD_ROM is +type CMD_STATES is( IDLE, T1, T6, T7); +signal CMD_STATE : CMD_STATES; +signal NEXT_CMD_STATE : CMD_STATES; + +signal ROM_CS : STD_LOGIC; + +signal IDE_CF_CS : std_logic; +signal NEXT_IDE_RDn : std_logic; +signal NEXT_IDE_WRn : std_logic; +begin + ROM_CS <= '1' when FB_CS1n = '0' and FB_WRn = '1' and FB_ADR(19 downto 17) = x"5" else '0'; -- FFF A'0000/2'0000 + + RP_UDSn <= '0' when FB_WRn = '1' and FB_B0 = '1' and (ROM_CS = '1' or IDE_CF_CS = '1' or IDE_WRn = '0') else '1'; + RP_LDSn <= '0' when FB_WRn = '1' and FB_B1 = '1' and (ROM_CS = '1' or IDE_CF_CS = '1' or IDE_WRn = '0') else '1'; + + IDE_CF_CS <= '1' when FB_CS1n = '0' and FB_ADR(19 downto 7) = x"0" else '0'; -- FFF0'0000/80 + + IDE_CSn(0) <= '0' when FBEE_CONF(30) = '0' and FB_ADR(19 downto 5) = x"2" else -- FFF0'0040-FFF0'005F + '0' when FBEE_CONF(30) = '1' and FB_ADR(19 downto 5) = x"0" else '1'; -- FFFO'0000-FFF0'001F + IDE_CSn(1) <= '0' when FBEE_CONF(30) = '0' and FB_ADR(19 downto 5) = x"3" else -- FFF0'0060-FFF0'007F + '0' when FBEE_CONF(30) = '1' and FB_ADR(19 downto 5) = x"1" else '1'; -- FFFO'0020-FFF0'003F + + CF_CSn(0) <= '0' when FBEE_CONF(31) = '0' and FB_ADR(19 downto 5) = x"0" else -- FFFO'0000-FFF0'001F + '0' when FBEE_CONF(31) = '1' and FB_ADR(19 downto 5) = x"2" else '1'; -- FFFO'0040-FFF0'005F + CF_CSn(1) <= '0' when FBEE_CONF(31) = '0' and FB_ADR(19 downto 5) = x"1" else -- FFF0'0020-FFF0'003F + '0' when FBEE_CONF(31) = '1' and FB_ADR(19 downto 5) = x"3" else '1'; -- FFFO'0060-FFF0'007F + + IDE_DRQn <= '0'; + + IDE_CMD_REG: process(RESET, CLK_MAIN) + begin + if RESET = '1' then + CMD_STATE <= IDLE; + elsif rising_edge(CLK_MAIN) then + CMD_STATE <= NEXT_CMD_STATE; + IDE_RDn <= NEXT_IDE_RDn; + IDE_WRn <= NEXT_IDE_WRn; + end if; + end process IDE_CMD_REG; + + IDE_CMD_DECODER: process(CMD_STATE, IDE_CF_CS, FB_WRn, IDE_RDY) + begin + case CMD_STATE is + when IDLE => + IDE_CF_TA <= '0'; + if IDE_CF_CS = '1' then + NEXT_IDE_RDn <= not FB_WRn; + NEXT_IDE_WRn <= FB_WRn; + NEXT_CMD_STATE <= T1; + else + NEXT_IDE_RDn <= '1'; + NEXT_IDE_WRn <= '1'; + NEXT_CMD_STATE <= IDLE; + end if; + when T1 => + IDE_CF_TA <= '0'; + NEXT_IDE_RDn <= not FB_WRn; + NEXT_IDE_WRn <= FB_WRn; + NEXT_CMD_STATE <= T6; + when T6 => + IF IDE_RDY = '1' then + IDE_CF_TA <= '1'; + NEXT_IDE_RDn <= '1'; + NEXT_IDE_WRn <= '1'; + NEXT_CMD_STATE <= T7; + else + IDE_CF_TA <= '0'; + NEXT_IDE_RDn <= not FB_WRn; + NEXT_IDE_WRn <= FB_WRn; + NEXT_CMD_STATE <= T6; + end if; + when T7 => + IDE_CF_TA <= '0'; + NEXT_IDE_RDn <= '1'; + NEXT_IDE_WRn <= '1'; + NEXT_CMD_STATE <= IDLE; + end case; + end process IDE_CMD_DECODER; + + SD_CLK <= '0'; + SD_CD_D3_OUT <= '0'; + SD_CD_D3_EN <= '0'; + SD_CMD_D1_OUT <= '0'; + SD_CMD_D1_EN <= '0'; + + ROM4n <= '0' when FB_CS1n = '0' and FB_WRn = '1' and FB_ADR(19 downto 17) = x"5" and FB_ADR(16) = '0' else '1'; -- FFF A'0000/2'0000 + ROM3n <= '0' when FB_CS1n = '0' and FB_WRn = '1' and FB_ADR(19 downto 17) = x"5" and FB_ADR(16) = '1' else '1'; -- FFF A'0000/2'0000 +end architecture BEHAVIOUR; diff --git a/vhdl/rtl/vhdl/RTC/rtc.vhd b/vhdl/rtl/vhdl/RTC/rtc.vhd new file mode 100644 index 0000000..f63ec69 --- /dev/null +++ b/vhdl/rtl/vhdl/RTC/rtc.vhd @@ -0,0 +1,232 @@ +---------------------------------------------------------------------- +---- ---- +---- This file is part of the 'Firebee' project. ---- +---- http://acp.atari.org ---- +---- ---- +---- Description: ---- +---- This design unit provides the RTC logic for the 'Firebee' ---- +---- computer. It is optimized for the use of an Altera Cyclone ---- +---- FPGA (EP3C40F484). This IP-Core is based on the first edi- ---- +---- tion of the Firebee configware originally provided by Fredi ---- +---- Ashwanden and Wolfgang Förster. This release is in compa- ---- +---- rision to the first edition completely written in VHDL. ---- +---- ---- +---- Author(s): ---- +---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2012 Fredi Aschwanden, Wolfgang Förster ---- +---- ---- +---- This source file 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 2 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, write to the Free ---- +---- Software Foundation, Inc., 51 Franklin Street, Fifth Floor, ---- +---- Boston, MA 02110-1301, USA. ---- +---- ---- +---------------------------------------------------------------------- +-- +-- Revision History +-- +-- Revision 2K12B 20120801 WF +-- Initial Release of the second edition. + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; +use ieee.std_logic_arith.all; + +entity RTC is + port( + CLK_MAIN : in std_logic; + FB_ADR : in std_logic_vector(19 downto 0); + FB_CS1n : in std_logic; + FB_SIZE0 : in std_logic; + FB_SIZE1 : in std_logic; + FB_WRn : in std_logic; + FB_OEn : in std_logic; + FB_AD_IN : in std_logic_vector(23 downto 16); + FB_AD_OUT : out std_logic_vector(23 downto 16); + FB_AD_EN_23_16 : out std_logic; + PIC_INT : in std_logic + ); +end entity RTC; + +architecture BEHAVIOUR of RTC is + type VALUES_TYPE is array(63 downto 0) of std_logic_vector(7 downto 0); + signal VALUES : VALUES_TYPE; + signal FB_B1 : std_logic; + signal FB_B3 : std_logic; + signal UHR_AS : std_logic; + signal UHR_DS : std_logic; + signal RTC_ADR : std_logic_vector(5 downto 0); + signal EIGHTHs_OF_SECOND : std_logic_vector(2 downto 0); + signal PIC_INT_SYNC : std_logic_vector(2 downto 0); + signal INC_SEC : std_logic; + signal INC_MIN : std_logic; + signal INC_HOUR : std_logic; + signal INC_DAY : std_logic; + signal DAYs_PER_MONTH : std_logic_vector(7 downto 0); + signal WINTERTIME : std_logic; + signal SUMMERTIME : std_logic; + signal INC_MONAT : std_logic; + signal INC_JAHR : std_logic; + signal UPDATE_ON : std_logic; +begin + -- Byte selectors: + FB_B1 <= '1' when FB_SIZE1 = '1' and FB_SIZE0 = '0' and FB_ADR(1) = '0' else -- High word. + '1' when FB_SIZE1 = '0' and FB_SIZE0 = '1' and FB_ADR(1 downto 0) = "01" else -- HL Byte. + '1' when FB_SIZE1 = '0' and FB_SIZE0 = '0' else -- Long. + '1' when FB_SIZE1 = '1' and FB_SIZE0 = '1' else '0';-- Line. + + FB_B3 <= '1' when FB_SIZE1 = '1' and FB_SIZE0 = '0' and FB_ADR(1) = '1' else -- Low word. + '1' when FB_SIZE1 = '0' and FB_SIZE0 = '1' and FB_ADR(1 downto 0) = "11" else -- LL Byte. + '1' when FB_SIZE1 = '0' and FB_SIZE0 = '0' else -- Long. + '1' when FB_SIZE1 = '1' and FB_SIZE0 = '1' else '0';-- Line. + + UHR_AS <= '1' when FB_B1 = '1' and FB_CS1n = '0' and FB_ADR(19 downto 1) = x"7C4B0" else '0'; -- $FFFF8961. + UHR_DS <= '1' when FB_B3 = '1' and FB_CS1n = '0' and FB_ADR(19 downto 1) = x"7C4B1" else '0'; -- $FFFF8963. + + UPDATE_ON <= not VALUES(11)(7); -- UPDATE ON OFF + + INC_SEC <= '1' when EIGHTHs_OF_SECOND = 7 and PIC_INT_SYNC(2) = '1' and UPDATE_ON = '1' else '0'; + INC_MIN <= '1' when INC_SEC = '1' and VALUES(0) = x"3B" else '0'; -- 59. + INC_HOUR <= '1' when INC_MIN = '1' and VALUES(2) = x"3B" else '0'; -- 59. + INC_DAY <= '1' when INC_HOUR = '1' and VALUES(2) = x"17" else '0'; -- 23. + INC_MONAT <= '1' when INC_DAY = '1' and VALUES(7) = DAYs_PER_MONTH else '0'; + INC_JAHR <= '1' when INC_MONAT = '1' and VALUES(8) = x"C" else '0'; -- 12. + + DAYs_PER_MONTH <= x"1F" when VALUES(8) = x"01" or VALUES(8) = x"03" or VALUES(8) = x"05" or VALUES(8) = x"07" or VALUES(8) = x"08" or VALUES(8) = x"0A" or VALUES(8) = x"0C" else + x"1E" when VALUES(8) = x"04" or VALUES(8) = x"06" or VALUES(8) = x"09" or VALUES(8) = x"0B" else + x"1D" when VALUES(8) = x"02" and VALUES(9)(1 downto 0) = x"00" else x"1C"; + + P_1287 : process + -- C1287: 0 = SEK 2 = MIN 4 = STD 6 = WOCHENTAG 7 = TAG 8 = MONAT 9 = JAHR + variable ADRVAR : std_logic_vector(5 downto 0); + begin + wait until CLK_MAIN = '1' and CLK_MAIN' event; + if UHR_AS = '1' and FB_WRn = '0' then + RTC_ADR <= FB_AD_IN(21 downto 16); + end if; + + for i in 0 to 63 loop + ADRVAR := conv_std_logic_vector(i,6); + if RTC_ADR = ADRVAR and UHR_DS = '1' and FB_WRn = '0' then + VALUES(i) <= FB_AD_IN(23 downto 16); + end if; + end loop; + + PIC_INT_SYNC(0) <= PIC_INT; + PIC_INT_SYNC(1) <= PIC_INT_SYNC(0); + PIC_INT_SYNC(2) <= not PIC_INT_SYNC(1) and PIC_INT_SYNC(0); + + VALUES(10)(6) <= '0'; -- No UIP. + VALUES(11)(2) <= '1'; -- Always binary. + VALUES(11)(1) <= '1'; -- Always 24h format. + VALUES(11)(0) <= '1'; -- Always correction of summertime. + VALUES(13)(7) <= '1'; -- Always true. + + -- Summer- wintertime: bit 0 in the register D provides information wether there is summer- or wintertime. + if VALUES(6)= x"01" and VALUES(4) = x"01" and VALUES(8) = x"04" and VALUES(7) > x"17" then -- Last Sunday in April. + SUMMERTIME <= '1'; + else + SUMMERTIME <= '0'; + end if; + + if VALUES(6)= x"01" and VALUES(4) = x"01" and VALUES(8) = x"0A" and VALUES(7) > x"18" then -- Last Sunday in October. + WINTERTIME <= '1'; + else + WINTERTIME <= '0'; + end if; + + if INC_HOUR = '1' and (SUMMERTIME or WINTERTIME) = '1' then + VALUES(13)(0) <= SUMMERTIME; + end if; + + -- Eighths of a second: + if PIC_INT_SYNC(2) = '1' and UPDATE_ON = '1' then + EIGHTHs_OF_SECOND <= EIGHTHs_OF_SECOND + '1'; + end if; + + -- Seconds: + if INC_SEC = '1' and (RTC_ADR /= "000000" or UHR_DS = '0' or FB_WRn = '1') then + if VALUES(0) = x"3B" then -- 59. + VALUES(0) <= (others => '0'); + else + VALUES(0) <= VALUES(0) + '1'; + end if; + end if; + + -- Minutes: + if INC_MIN = '1' and (RTC_ADR /= "000010" or UHR_DS = '0' or FB_WRn = '1') then + if VALUES(2) = x"3B" then -- 59. + VALUES(2) <= (others => '0'); + else + VALUES(2) <= VALUES(2) + '1'; + end if; + end if; + + -- Hours: + if INC_HOUR = '1' and (WINTERTIME = '0' or VALUES(12)(0) = '0') and (RTC_ADR /= "000100" or UHR_DS = '0' or FB_WRn = '1') then + if VALUES(4) = x"17" then -- 23. + VALUES(4) <= (others => '0'); + elsif SUMMERTIME = '1' then + VALUES(4) <= VALUES(4) + "10"; + else + VALUES(4) <= VALUES(4) + '1'; + end if; + end if; + + -- Day and day of the week: + if INC_DAY = '1' and (RTC_ADR /= "000110" or UHR_DS = '0' or FB_WRn = '1') then + if VALUES(6) = x"07" then + VALUES(6) <= x"01"; + else + VALUES(6) <= VALUES(6) + '1'; + end if; + end if; + + if INC_DAY = '1' and (RTC_ADR /= "000111" or UHR_DS = '0' or FB_WRn = '1') then + if VALUES(7) = DAYs_PER_MONTH then + VALUES(7) <= x"01"; + else + VALUES(7) <= VALUES(7) + '1'; + end if; + end if; + + -- Month: + if INC_MONAT = '1' and (RTC_ADR /= "001000" or UHR_DS = '0' or FB_WRn = '1') then + if VALUES(8) = x"0C" then + VALUES(8) <= x"01"; + else + VALUES(8) <= VALUES(8) + '1'; + end if; + end if; + + -- Year: + if INC_JAHR = '1' and (RTC_ADR /= "001001" or UHR_DS = '0' or FB_WRn = '1') then + if VALUES(9) = x"63" then -- 99. + VALUES(9) <= (others => '0'); + else + VALUES(9) <= VALUES(9) + '1'; + end if; + end if; + end process P_1287; + + -- Data out multiplexers: + FB_AD_EN_23_16 <= (UHR_DS or UHR_AS) and not FB_OEn; + + FB_AD_OUT(23 downto 16) <= VALUES(conv_integer(RTC_ADR)) when UHR_DS = '1' else + "00" & RTC_ADR when UHR_AS = '1' else x"00"; +end architecture BEHAVIOUR; diff --git a/vhdl/rtl/vhdl/Video/VIDEO_CTRL.vhd b/vhdl/rtl/vhdl/Video/VIDEO_CTRL.vhd new file mode 100644 index 0000000..da9791b --- /dev/null +++ b/vhdl/rtl/vhdl/Video/VIDEO_CTRL.vhd @@ -0,0 +1,958 @@ +---------------------------------------------------------------------- +---- ---- +---- This file is part of the 'Firebee' project. ---- +---- http://acp.atari.org ---- +---- ---- +---- Description: ---- +---- This design unit provides the video controller of the 'Fire- ---- +---- bee' computer. It is optimized for the use of an Altera Cyc- ---- +---- lone FPGA (EP3C40F484). This IP-Core is based on the first ---- +---- edition of the Firebee configware originally provided by ---- +---- Fredi Ashwanden and Wolfgang Förster. This release is in ---- +---- comparision to the first edition completely written in VHDL. ---- +---- ---- +---- Author(s): ---- +---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2012 Fredi Aschwanden, Wolfgang Förster ---- +---- ---- +---- This source file 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 2 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, write to the Free ---- +---- Software Foundation, Inc., 51 Franklin Street, Fifth Floor, ---- +---- Boston, MA 02110-1301, USA. ---- +---- ---- +---------------------------------------------------------------------- +-- +-- Revision History +-- +-- Revision 2K12B 20120801 WF +-- Initial Release of the second edition. + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + +entity VIDEO_CTRL is + port( + CLK_MAIN : in std_logic; + FB_CSn : in std_logic_vector(2 downto 1); + FB_WRn : in std_logic; + FB_OEn : in std_logic; + FB_SIZE : in std_logic_vector(1 downto 0); + FB_ADR : in std_logic_vector(31 downto 0); + CLK33M : in std_logic; + CLK25M : in std_logic; + BLITTER_RUN : in std_logic; + CLK_VIDEO : in std_logic; + VR_D : in std_logic_vector(8 downto 0); + VR_BUSY : in std_logic; + COLOR8 : out std_logic; + FBEE_CLUT_RD : out std_logic; + COLOR1 : out std_logic; + FALCON_CLUT_RDH : out std_logic; + FALCON_CLUT_RDL : out std_logic; + FALCON_CLUT_WR : out std_logic_vector(3 downto 0); + CLUT_ST_RD : out std_logic; + CLUT_ST_WR : out std_logic_vector(1 downto 0); + CLUT_MUX_ADR : out std_logic_vector(3 downto 0); + HSYNC : out std_logic; + VSYNC : out std_logic; + BLANKn : out std_logic; + SYNCn : out std_logic; + PD_VGAn : out std_logic; + FIFO_RDE : out std_logic; + COLOR2 : out std_logic; + COLOR4 : out std_logic; + CLK_PIXEL : out std_logic; + CLUT_OFF : out std_logic_vector(3 downto 0); + BLITTER_ON : out std_logic; + VIDEO_RAM_CTR : out std_logic_vector(15 downto 0); + VIDEO_MOD_TA : out std_logic; + CCR : out std_logic_vector(23 downto 0); + CCSEL : out std_logic_vector(2 downto 0); + FBEE_CLUT_WR : out std_logic_vector(3 downto 0); + INTER_ZEI : out std_logic; + DOP_FIFO_CLR : out std_logic; + VIDEO_RECONFIG : out std_logic; + VR_WR : out std_logic; + VR_RD : out std_logic; + FIFO_CLR : out std_logic; + DATA_IN : in std_logic_vector(31 downto 0); + DATA_OUT : out std_logic_vector(31 downto 0); + DATA_EN_H : out std_logic; + DATA_EN_L : out std_logic + ); +end entity VIDEO_CTRL; + +architecture BEHAVIOUR of VIDEO_CTRL is + signal CLK17M : std_logic; + signal CLK13M : std_logic; + signal FBEE_CLUT_CS : std_logic; + signal FBEE_CLUT : std_logic; + signal VIDEO_PLL_CONFIG_CS : std_logic; + signal VR_WR_I : std_logic; + signal VR_DOUT : std_logic_vector(8 downto 0); + signal VR_FRQ : std_logic_vector(7 downto 0); + signal VIDEO_PLL_RECONFIG_CS : std_logic; + signal VIDEO_RECONFIG_I : std_logic; + signal FALCON_CLUT_CS : std_logic; + signal FALCON_CLUT : std_logic; + signal ST_CLUT_CS : std_logic; + signal ST_CLUT : std_logic; + signal FB_B : std_logic_vector(3 downto 0); + signal FB_16B : std_logic_vector(1 downto 0); + signal ST_SHIFT_MODE : std_logic_vector(1 downto 0); + signal ST_SHIFT_MODE_CS : std_logic; + signal FALCON_SHIFT_MODE : std_logic_vector(10 downto 0); + signal FALCON_SHIFT_MODE_CS : std_logic; + signal CLUT_MUX_AV_1 : std_logic_vector(3 downto 0); + signal CLUT_MUX_AV_0 : std_logic_vector(3 downto 0); + signal FBEE_VCTR_CS : std_logic; + signal FBEE_VCTR : std_logic_vector(31 downto 0); + signal CCR_CS : std_logic; + signal CCR_I : std_logic_vector(23 downto 0); + signal FBEE_VIDEO_ON : std_logic; + signal SYS_CTR : std_logic_vector(6 downto 0); + signal SYS_CTR_CS : std_logic; + signal VDL_LOF : std_logic_vector(15 downto 0); + signal VDL_LOF_CS : std_logic; + signal VDL_LWD : std_logic_vector(15 downto 0); + signal VDL_LWD_CS : std_logic; + + -- Miscellaneous control registers: + signal CLUT_TA : std_logic; -- Requires one wait state. + signal HSYNC_I : std_logic_vector(7 downto 0); + signal HSY_LEN : std_logic_vector(7 downto 0); -- Length of a HSYNC pulse in CLK_PIXEL cycles. + signal HSYNC_START : std_logic; + signal LAST : std_logic; -- Last pixel of a line indicator. + signal VSYNC_START : std_logic; + signal VSYNC_I : std_logic_vector(2 downto 0); + signal BLANK_In : std_logic; + signal DISP_ON : std_logic; + signal DPO_ZL : std_logic; + signal DPO_ON : std_logic; + signal DPO_OFF : std_logic; + signal VDTRON : std_logic; + signal VDO_ZL : std_logic; + signal VDO_ON : std_logic; + signal VDO_OFF : std_logic; + signal VHCNT : std_logic_vector(11 downto 0); + signal SUB_PIXEL_CNT : std_logic_vector(6 downto 0); + signal VVCNT : std_logic_vector(10 downto 0); + signal VERZ_2 : std_logic_vector(9 downto 0); + signal VERZ_1 : std_logic_vector(9 downto 0); + signal VERZ_0 : std_logic_vector(9 downto 0); + signal RAND : std_logic_vector(6 downto 0); + signal RAND_ON : std_logic; + signal START_ZEILE : std_logic; + signal SYNC_PIX : std_logic; + signal SYNC_PIX1 : std_logic; + signal SYNC_PIX2 : std_logic; + + -- Legacy ATARI resolutions: + signal ATARI_SYNC : std_logic; + signal ATARI_HH : std_logic_vector(31 downto 0); -- Horizontal timing 640x480. + signal ATARI_HH_CS : std_logic; + signal ATARI_VH : std_logic_vector(31 downto 0); -- Vertical timing 640x480. + signal ATARI_VH_CS : std_logic; + signal ATARI_HL : std_logic_vector(31 downto 0); -- Horizontal timing 320x240. + signal ATARI_HL_CS : std_logic; + signal ATARI_VL : std_logic_vector(31 downto 0); -- Vertical timing 320x240. + signal ATARI_VL_CS : std_logic; + + -- Horizontal stuff: + signal BORDER_LEFT : std_logic_vector(11 downto 0); + signal HDIS_START : std_logic_vector(11 downto 0); + signal HDIS_END : std_logic_vector(11 downto 0); + signal BORDER_RIGHT : std_logic_vector(11 downto 0); + signal HS_START : std_logic_vector(11 downto 0); + signal H_TOTAL : std_logic_vector(11 downto 0); + signal HDIS_LEN : std_logic_vector(11 downto 0); + signal MULF : std_logic_vector(5 downto 0); + signal VDL_HHT : std_logic_vector(11 downto 0); + signal VDL_HHT_CS : std_logic; + signal VDL_HBE : std_logic_vector(11 downto 0); + signal VDL_HBE_CS : std_logic; + signal VDL_HDB : std_logic_vector(11 downto 0); + signal VDL_HDB_CS : std_logic; + signal VDL_HDE : std_logic_vector(11 downto 0); + signal VDL_HDE_CS : std_logic; + signal VDL_HBB : std_logic_vector(11 downto 0); + signal VDL_HBB_CS : std_logic; + signal VDL_HSS : std_logic_vector(11 downto 0); + signal VDL_HSS_CS : std_logic; + + -- Vertical stuff: + signal BORDER_TOP : std_logic_vector(10 downto 0); + signal VDIS_START : std_logic_vector(10 downto 0); + signal VDIS_END : std_logic_vector(10 downto 0); + signal BORDER_BOTTOM : std_logic_vector(10 downto 0); + signal VS_START : std_logic_vector(10 downto 0); + signal V_TOTAL : std_logic_vector(10 downto 0); + signal FALCON_VIDEO : std_logic; + signal ST_VIDEO : std_logic; + signal INTER_ZEI_I : std_logic; + signal DOP_ZEI : std_logic; + + signal VDL_VBE : std_logic_vector(10 downto 0); + signal VDL_VBE_CS : std_logic; + signal VDL_VDB : std_logic_vector(10 downto 0); + signal VDL_VDB_CS : std_logic; + signal VDL_VDE : std_logic_vector(10 downto 0); + signal VDL_VDE_CS : std_logic; + signal VDL_VBB : std_logic_vector(10 downto 0); + signal VDL_VBB_CS : std_logic; + signal VDL_VSS : std_logic_vector(10 downto 0); + signal VDL_VSS_CS : std_logic; + signal VDL_VFT : std_logic_vector(10 downto 0); + signal VDL_VFT_CS : std_logic; + signal VDL_VCT : std_logic_vector(8 downto 0); + signal VDL_VCT_CS : std_logic; + signal VDL_VMD : std_logic_vector(3 downto 0); + signal VDL_VMD_CS : std_logic; + signal COLOR1_I : std_logic; + signal COLOR2_I : std_logic; + signal COLOR4_I : std_logic; + signal COLOR8_I : std_logic; + signal COLOR16_I : std_logic; + signal COLOR24_I : std_logic; + signal VIDEO_MOD_TA_I : std_logic; + signal VR_RD_I : std_logic; + signal CLK_PIXEL_I : std_logic; + signal MUL1 : std_logic_vector(16 downto 0); + signal MUL2 : std_logic_vector(16 downto 0); + signal MUL3 : std_logic_vector(16 downto 0); +begin + VR_WR <= VR_WR_I; + VIDEO_RECONFIG <= VIDEO_RECONFIG_I; + CCR <= CCR_I; + INTER_ZEI <= INTER_ZEI_I; + VIDEO_MOD_TA <= VIDEO_MOD_TA_I; + VR_RD <= VR_RD_I; + CLK_PIXEL <= CLK_PIXEL_I; + + -- Byte selectors: + FB_B(0) <= '1' when FB_ADR(1 downto 0) = "00" else '0'; -- Byte 0. + + FB_B(1) <= '1' when FB_SIZE(1) = '1' and FB_SIZE(0) = '1' else -- Long word. + '1' when FB_SIZE(1) = '0' and FB_SIZE(0) = '0' else -- Long. + '1' when FB_SIZE(1) = '1' and FB_SIZE(0) = '0' and FB_ADR(1) = '0' else -- High word. + '1' when FB_ADR(1 downto 0) = "01" else '0'; -- Byte 1. + + FB_B(2) <= '1' when FB_SIZE(1) = '1' and FB_SIZE(0) = '1' else -- Long word. + '1' when FB_SIZE(1) = '0' and FB_SIZE(0) = '0' else -- Long. + '1' when FB_ADR(1 downto 0) = "10" else '0'; -- Byte 2. + + FB_B(3) <= '1' when FB_SIZE(1) = '1' and FB_SIZE(0) = '1' else -- Long word. + '1' when FB_SIZE(1) = '0' and FB_SIZE(0) = '0' else -- Long. + '1' when FB_SIZE(1) = '1' and FB_SIZE(0) = '0' and FB_ADR(1) = '1' else -- Low word. + '1' when FB_ADR(1 downto 0) = "11" else '0'; -- Byte 3. + + -- 16 bit selectors: + FB_16B(0) <= not FB_ADR(0); + FB_16B(1) <= '1'when FB_ADR(0) = '1' else + '1' when FB_SIZE(1) = '0' and FB_SIZE(0) = '0' else -- No byte. + '1' when FB_SIZE(1) = '1' and FB_SIZE(0) = '0' else -- No byte. + '1' when FB_SIZE(1) = '1' and FB_SIZE(0) = '1' else '0'; -- No byte. + + -- Firebee CLUT: + FBEE_CLUT_CS <= '1' when FB_CSn(2) = '0' and FB_ADR(27 downto 10) = "000000000000000000" else '0'; -- 0-3FF/1024 + FBEE_CLUT_RD <= '1' when FBEE_CLUT_CS = '1' and FB_OEn = '0' else '0'; + FBEE_CLUT_WR <= FB_B when FBEE_CLUT_CS = '1' and FB_WRn = '0' else x"0"; + + P_CLUT_TA : process + begin + wait until CLK_MAIN = '1' and CLK_MAIN' event; + if VIDEO_MOD_TA_I = '0' and FBEE_CLUT_CS = '1' then + CLUT_TA <= '1'; + elsif VIDEO_MOD_TA_I = '0' and FALCON_CLUT_CS = '1' then + CLUT_TA <= '1'; + elsif VIDEO_MOD_TA_I = '0' and ST_CLUT_CS = '1' then + CLUT_TA <= '1'; + else + CLUT_TA <= '0'; + end if; + end process P_CLUT_TA; + + --Falcon CLUT: + FALCON_CLUT_CS <= '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 10) = "1111100110" else '0'; -- $F9800/$400 + FALCON_CLUT_RDH <= '1' when FALCON_CLUT_CS = '1' and FB_OEn = '0' and FB_ADR(1) = '0' else '0'; -- High word. + FALCON_CLUT_RDL <= '1' when FALCON_CLUT_CS = '1' and FB_OEn = '0' and FB_ADR(1) = '1' else '0'; -- Low word. + FALCON_CLUT_WR(1 downto 0) <= FB_16B when FB_ADR(1) = '0' and FALCON_CLUT_CS = '1' and FB_WRn = '0' else "00"; + FALCON_CLUT_WR(3 downto 2) <= FB_16B when FB_ADR(1) = '1' and FALCON_CLUT_CS = '1' and FB_WRn = '0' else "00"; + + -- ST CLUT: + ST_CLUT_CS <= '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 5) = "111110000010010" else '0'; -- $F8240/$2 + CLUT_ST_RD <= '1' when ST_CLUT_CS = '1' and FB_OEn = '0' else '0'; + CLUT_ST_WR <= FB_16B when ST_CLUT_CS = '1' and FB_WRn = '0' else "00"; + + ST_SHIFT_MODE_CS <= '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 1) = "1111100000100110000" else '0'; -- $F8260/$2. + FALCON_SHIFT_MODE_CS <= '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 1) = "1111100000100110011" else '0'; -- $F8266/$2. + FBEE_VCTR_CS <= '1' when FB_CSn(2) = '0' and FB_ADR(27 downto 2) = "00000000000000000100000000" else '0'; -- $400/$4 + ATARI_HH_CS <= '1' when FB_CSn(2) = '0' and FB_ADR(27 downto 2) = "00000000000000000100000100" else '0'; -- $410/4 + ATARI_VH_CS <= '1' when FB_CSn(2) = '0' and FB_ADR(27 downto 2) = "00000000000000000100000101" else '0'; -- $414/4 + ATARI_HL_CS <= '1' when FB_CSn(2) = '0' and FB_ADR(27 downto 2) = "00000000000000000100000110" else '0'; -- $418/4 + ATARI_VL_CS <= '1' when FB_CSn(2) = '0' and FB_ADR(27 downto 2) = "00000000000000000100000111" else '0'; -- $41C/4 + + P_VIDEO_CONTROL : process + begin + wait until CLK_MAIN = '1' and CLK_MAIN' event; + if ST_SHIFT_MODE_CS = '1' and FB_WRn = '0' and FB_B(0) = '1' then + ST_SHIFT_MODE <= DATA_IN(25 downto 24); + end if; + + if FALCON_SHIFT_MODE_CS = '1' and FB_WRn = '0' and FB_B(2) = '1' then + FALCON_SHIFT_MODE(10 downto 8) <= DATA_IN(26 downto 24); + elsif FALCON_SHIFT_MODE_CS = '1' and FB_WRn = '0' and FB_B(3) = '1' then + FALCON_SHIFT_MODE(7 downto 0) <= DATA_IN(23 downto 16); + end if; + + -- Firebee VIDEO CONTROL: + -- Bit 0 = FBEE VIDEO ON, 1 = POWER ON VIDEO DAC, 2 = FBEE 24BIT, + -- Bit 3 = FBEE 16BIT, 4 = FBEE 8BIT, 5 = FBEE 1BIT, + -- Bit 6 = FALCON SHIFT MODE, 7 = ST SHIFT MODE, 9..8 = VCLK frequency, + -- Bit 15 = SYNC ALLOWED, 31..16 = VIDEO_RAM_CTR, + -- Bit 25 = RANDFARBE EINSCHALTEN, 26 = STANDARD ATARI SYNCS. + if FBEE_VCTR_CS = '1' and FB_B(0) = '1' and FB_WRn = '0' then + FBEE_VCTR(31 downto 24) <= DATA_IN(31 downto 24); + elsif FBEE_VCTR_CS = '1' and FB_B(1) = '1' and FB_WRn = '0' then + FBEE_VCTR(23 downto 16) <= DATA_IN(23 downto 16); + elsif FBEE_VCTR_CS = '1' and FB_B(2) = '1' and FB_WRn = '0' then + FBEE_VCTR(15 downto 8) <= DATA_IN(15 downto 8); + elsif FBEE_VCTR_CS = '1' and FB_B(3) = '1' and FB_WRn = '0' then + FBEE_VCTR(5 downto 0) <= DATA_IN(5 downto 0); + end if; + + -- ST or Falcon shift mode: assert when X..shift register: + if FALCON_SHIFT_MODE_CS = '1' and FB_WRn = '0' then + FBEE_VCTR(7) <= FALCON_SHIFT_MODE_CS and not FB_WRn and not FBEE_VIDEO_ON; + FBEE_VCTR(6) <= ST_SHIFT_MODE_CS and not FB_WRn and not FBEE_VIDEO_ON; + end if; + if ST_SHIFT_MODE_CS = '1' and FB_WRn = '0' then + FBEE_VCTR(7) <= FALCON_SHIFT_MODE_CS and not FB_WRn and not FBEE_VIDEO_ON; + FBEE_VCTR(6) <= ST_SHIFT_MODE_CS and not FB_WRn and not FBEE_VIDEO_ON; + end if; + if FBEE_VCTR_CS = '1' and FB_B(3) = '1' and FB_WRn = '0' and DATA_IN(0) = '1' then + FBEE_VCTR(7) <= FALCON_SHIFT_MODE_CS and not FB_WRn and not FBEE_VIDEO_ON; + FBEE_VCTR(6) <= ST_SHIFT_MODE_CS and not FB_WRn and not FBEE_VIDEO_ON; + end if; + + -- ATARI ST mode + -- Horizontal timing 640x480: + if ATARI_HH_CS = '1' and FB_B(0) = '1' and FB_WRn = '0' then + ATARI_HH(31 downto 24) <= DATA_IN(31 downto 24); + elsif ATARI_HH_CS = '1' and FB_B(1) = '1' and FB_WRn = '0' then + ATARI_HH(23 downto 16) <= DATA_IN(23 downto 16); + elsif ATARI_HH_CS = '1' and FB_B(2) = '1' and FB_WRn = '0' then + ATARI_HH(15 downto 8) <= DATA_IN(15 downto 8); + elsif ATARI_HH_CS = '1' and FB_B(3) = '1' and FB_WRn = '0' then + ATARI_HH(7 downto 0) <= DATA_IN(7 downto 0); + end if; + + -- Vertical timing 640x480: + if ATARI_VH_CS = '1' and FB_B(0) = '1' and FB_WRn = '0' then + ATARI_VH(31 downto 24) <= DATA_IN(31 downto 24); + elsif ATARI_VH_CS = '1' and FB_B(1) = '1' and FB_WRn = '0' then + ATARI_VH(23 downto 16) <= DATA_IN(23 downto 16); + elsif ATARI_VH_CS = '1' and FB_B(2) = '1' and FB_WRn = '0' then + ATARI_VH(15 downto 8) <= DATA_IN(15 downto 8); + elsif ATARI_VH_CS = '1' and FB_B(3) = '1' and FB_WRn = '0' then + ATARI_VH(7 downto 0) <= DATA_IN(7 downto 0); + end if; + + -- Horizontal timing 320x240: + if ATARI_HL_CS = '1' and FB_B(0) = '1' and FB_WRn = '0' then + ATARI_HL(31 downto 24) <= DATA_IN(31 downto 24); + elsif ATARI_HL_CS = '1' and FB_B(1) = '1' and FB_WRn = '0' then + ATARI_HL(23 downto 16) <= DATA_IN(23 downto 16); + elsif ATARI_HL_CS = '1' and FB_B(2) = '1' and FB_WRn = '0' then + ATARI_HL(15 downto 8) <= DATA_IN(15 downto 8); + elsif ATARI_HL_CS = '1' and FB_B(3) = '1' and FB_WRn = '0' then + ATARI_HL(7 downto 0) <= DATA_IN(7 downto 0); + end if; + + -- Vertical timing 320x240: + if ATARI_VL_CS = '1' and FB_B(0) = '1' and FB_WRn = '0' then + ATARI_VL(31 downto 24) <= DATA_IN(31 downto 24); + elsif ATARI_VL_CS = '1' and FB_B(1) = '1' and FB_WRn = '0' then + ATARI_VL(23 downto 16) <= DATA_IN(23 downto 16); + elsif ATARI_VL_CS = '1' and FB_B(2) = '1' and FB_WRn = '0' then + ATARI_VL(15 downto 8) <= DATA_IN(15 downto 8); + elsif ATARI_VL_CS = '1' and FB_B(3) = '1' and FB_WRn = '0' then + ATARI_VL(7 downto 0) <= DATA_IN(7 downto 0); + end if; + end process P_VIDEO_CONTROL; + + CLUT_OFF <= FALCON_SHIFT_MODE(3 downto 0) when COLOR4_I = '1' else x"0"; + PD_VGAn <= FBEE_VCTR(1); + FBEE_VIDEO_ON <= FBEE_VCTR(0); + ATARI_SYNC <= FBEE_VCTR(26); -- If 1 -> automatic resolution. + + COLOR1_I <= '1' when ST_VIDEO = '1' and FBEE_VIDEO_ON = '0' and ST_SHIFT_MODE = "10" and COLOR8_I = '0' else -- ST mono. + '1' when FALCON_VIDEO = '1' and FBEE_VIDEO_ON = '0' and FALCON_SHIFT_MODE(10) = '1' and COLOR16_I = '0' and COLOR8_I = '0' else -- Falcon mono. + '1' when FBEE_VIDEO_ON = '1' and FBEE_VCTR(5 downto 2) = "1000" else '0'; -- Firebee mode. + COLOR2_I <= '1' when ST_VIDEO = '1' and FBEE_VIDEO_ON = '0' and ST_SHIFT_MODE = "01" and COLOR8_I = '0' else '0'; -- ST 4 colours. + COLOR4_I <= '1' when ST_VIDEO = '1' and FBEE_VIDEO_ON = '0' and ST_SHIFT_MODE = "00" and COLOR8_I = '0' else -- ST 16 colours. + '1' when FALCON_VIDEO = '1' and FBEE_VIDEO_ON = '0' and COLOR16_I = '0' and COLOR8_I = '0' and COLOR1_I = '0' else '0'; -- Falcon mode. + COLOR8_I <= '1' when FALCON_VIDEO = '1' and FBEE_VIDEO_ON = '0' and FALCON_SHIFT_MODE(4) = '1' and COLOR16_I = '0' else -- Falcon mode. + '1' when FBEE_VIDEO_ON = '1' and FBEE_VCTR(4 downto 2) = "100" else '0'; -- Firebee mode. + COLOR16_I <= '1' when FALCON_VIDEO = '1' and FBEE_VIDEO_ON = '0' and FALCON_SHIFT_MODE(8) = '1' else -- Falcon mode. + '1' when FBEE_VIDEO_ON = '1' and FBEE_VCTR(3 downto 2) = "10" else '0'; -- Firebee mode. + COLOR24_I <= '1' when FBEE_VIDEO_ON = '1' and FBEE_VCTR(2) = '1' else '0'; -- Firebee mode. + + COLOR1 <= COLOR1_I; + COLOR2 <= COLOR2_I; + COLOR4 <= COLOR4_I; + COLOR8 <= COLOR8_I; + -- VIDEO PLL config and reconfig: + VIDEO_PLL_CONFIG_CS <= '1' when FB_CSn(2) = '0' and FB_B(0) = '1' and FB_B(1) = '1' and FB_ADR(27 downto 9) = "0000000000000000011" else '0'; -- $(F)000'0600-7FF -> 6/2 word and long only. + VIDEO_PLL_RECONFIG_CS <= '1' when FB_CSn(2) = '0' and FB_B(0) = '1' and FB_ADR(27 downto 0) = x"0000800" else '0'; -- $(F)000'0800. + VR_RD_I <= '1' when VIDEO_PLL_CONFIG_CS = '1' and FB_WRn = '0' and VR_BUSY = '0' else '0'; + + P_VIDEO_CONFIG: process + variable LOCK : boolean; + begin + wait until CLK_MAIN = '1' and CLK_MAIN' event; + if VIDEO_PLL_CONFIG_CS = '1' and FB_WRn = '0' and VR_BUSY = '0' and VR_WR_I = '0' then + VR_WR_I <= '1'; -- This is a strobe. + else + VR_WR_I <= '0'; + end if; + + if VR_BUSY = '1' then + VR_DOUT <= VR_D; + end if; + + if VR_WR_I = '1' and FB_ADR(8 downto 0) = "000000100" then + VR_FRQ <= DATA_IN(23 downto 16); + end if; + + if VIDEO_PLL_RECONFIG_CS = '1' and FB_WRn = '0' and VR_BUSY = '0' and LOCK = false then + VIDEO_RECONFIG_I <= '1'; -- This is a strobe. + LOCK := true; + elsif VIDEO_PLL_RECONFIG_CS = '0' or FB_WRn = '1' or VR_BUSY = '1' then + VIDEO_RECONFIG_I <= '0'; + LOCK := false; + else + VIDEO_RECONFIG_I <= '0'; + end if; + end process P_VIDEO_CONFIG; + + VIDEO_RAM_CTR <= FBEE_VCTR(31 downto 16); + + -- Firebee colour modi: + FBEE_CLUT <= '1' when FBEE_VIDEO_ON = '1' and (COLOR1_I = '1' or COLOR8_I = '1') else + '1' when ST_VIDEO = '1' and COLOR1_I = '1'; + + FALCON_VIDEO <= FBEE_VCTR(7); + FALCON_CLUT <= '1' when FALCON_VIDEO = '1' and FBEE_VIDEO_ON = '0' and COLOR16_I = '0' else '0'; + ST_VIDEO <= FBEE_VCTR(6); + ST_CLUT <= '1' when ST_VIDEO = '1' and FBEE_VIDEO_ON = '0' and FALCON_CLUT = '0' and COLOR1_I = '0' else '0'; + + -- Several (video)-registers: + CCR_CS <= '1' when FB_CSn(2) = '0' and FB_ADR(27 downto 2) = "000000000000000000100000001" else '0';-- $404/4. + SYS_CTR_CS <= '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 1) = "1111100000000000011" else '0'; -- $8006/2. + VDL_LOF_CS <= '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 1) = "1111100000100000111" else '0'; -- $820E/2. + VDL_LWD_CS <= '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 1) = "1111100000100001000" else '0'; -- $8210/2. + VDL_HHT_CS <= '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 1) = "1111100000101000001" else '0'; -- $8282/2. + VDL_HBE_CS <= '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 1) = "1111100000101000011" else '0'; -- $8286/2. + VDL_HDB_CS <= '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 1) = "1111100000101000100" else '0'; -- $8288/2. + VDL_HDE_CS <= '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 1) = "1111100000101000101" else '0'; -- $828A/2. + VDL_HBB_CS <= '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 1) = "1111100000101000010" else '0'; -- $8284/2. + VDL_HSS_CS <= '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 1) = "1111100000101000110" else '0'; -- $828C/2. + VDL_VBE_CS <= '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 1) = "1111100000101010011" else '0'; -- $82A6/2. + VDL_VDB_CS <= '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 1) = "1111100000101010100" else '0'; -- $82A8/2. + VDL_VDE_CS <= '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 1) = "1111100000101010101" else '0'; -- $82AA/2. + VDL_VBB_CS <= '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 1) = "1111100000101010010" else '0'; -- $82A4/2. + VDL_VSS_CS <= '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 1) = "1111100000101010110" else '0'; -- $82AC/2. + VDL_VFT_CS <= '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 1) = "1111100000101010001" else '0'; -- $82A2/2. + VDL_VCT_CS <= '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 1) = "1111100000101100000" else '0'; -- $82C0/2. + VDL_VMD_CS <= '1' when FB_CSn(1) = '0' and FB_ADR(19 downto 1) = "1111100000101100001" else '0'; -- $82C2/2. + + P_MISC_CTRL : process + begin + wait until CLK_MAIN = '1' and CLK_MAIN' event; + + -- Colour of video borders + if CCR_CS = '1' and FB_B(1) = '1' and FB_WRn = '0' then + CCR_I(23 downto 16) <= DATA_IN(23 downto 16); + elsif CCR_CS = '1' and FB_B(2) = '1' and FB_WRn = '0' then + CCR_I(15 downto 8) <= DATA_IN(15 downto 8); + elsif CCR_CS = '1' and FB_B(3) = '1' and FB_WRn = '0' then + CCR_I(7 downto 0) <= DATA_IN(7 downto 0); + end if; + + --SYS CTRL: + if SYS_CTR_CS = '1' and FB_B(3) = '1' and FB_WRn = '0' then + SYS_CTR <= DATA_IN(22 downto 16); + end if; + + --VDL_LOF: + if VDL_LOF_CS = '1' and FB_B(2) = '1' and FB_WRn = '0' then + VDL_LOF(15 downto 8) <= DATA_IN(31 downto 24); + elsif VDL_LOF_CS = '1' and FB_B(3) = '1' and FB_WRn = '0' then + VDL_LOF(7 downto 0) <= DATA_IN(23 downto 16); + end if; + + --VDL_LWD + if VDL_LWD_CS = '1' and FB_B(0) = '1' and FB_WRn = '0' then + VDL_LWD(15 downto 8) <= DATA_IN(31 downto 24); + elsif VDL_LWD_CS = '1' and FB_B(1) = '1' and FB_WRn = '0' then + VDL_LWD(7 downto 0) <= DATA_IN(23 downto 16); + end if; + + -- Horizontal: + -- VDL_HHT: + if VDL_HHT_CS = '1' and FB_B(2) = '1' and FB_WRn = '0' then + VDL_HHT(11 downto 8) <= DATA_IN(27 downto 24); + elsif VDL_HHT_CS = '1' and FB_B(3) = '1' and FB_WRn = '0' then + VDL_HHT(7 downto 0) <= DATA_IN(23 downto 16); + end if; + + -- VDL_HBE: + if VDL_HBE_CS = '1' and FB_B(2) = '1' and FB_WRn = '0' then + VDL_HBE(11 downto 8) <= DATA_IN(27 downto 24); + elsif VDL_HBE_CS = '1' and FB_B(3) = '1' and FB_WRn = '0' then + VDL_HBE(7 downto 0) <= DATA_IN(23 downto 16); + end if; + + -- VDL_HDB: + if VDL_HDB_CS = '1' and FB_B(0) = '1' and FB_WRn = '0' then + VDL_HDB(11 downto 8) <= DATA_IN(27 downto 24); + elsif VDL_HDB_CS = '1' and FB_B(1) = '1' and FB_WRn = '0' then + VDL_HDB(7 downto 0) <= DATA_IN(23 downto 16); + end if; + + -- VDL_HDE: + if VDL_HDE_CS = '1' and FB_B(2) = '1' and FB_WRn = '0' then + VDL_HDE(11 downto 8) <= DATA_IN(27 downto 24); + elsif VDL_HDE_CS = '1' and FB_B(3) = '1' and FB_WRn = '0' then + VDL_HDE(7 downto 0) <= DATA_IN(23 downto 16); + end if; + + -- VDL_HBB: + if VDL_HBB_CS = '1' and FB_B(0) = '1' and FB_WRn = '0' then + VDL_HBB(11 downto 8) <= DATA_IN(27 downto 24); + elsif VDL_HBB_CS = '1' and FB_B(1) = '1' and FB_WRn = '0' then + VDL_HBB(7 downto 0) <= DATA_IN(23 downto 16); + end if; + + -- VDL_HSS: + if VDL_HSS_CS = '1' and FB_B(0) = '1' and FB_WRn = '0' then + VDL_HSS(11 downto 8) <= DATA_IN(27 downto 24); + elsif VDL_HSS_CS = '1' and FB_B(1) = '1' and FB_WRn = '0' then + VDL_HSS(7 downto 0) <= DATA_IN(23 downto 16); + end if; + + -- Vertical: + -- VDL_VBE: + if VDL_VBE_CS = '1' and FB_B(2) = '1' and FB_WRn = '0' then + VDL_VBE(10 downto 8) <= DATA_IN(26 downto 24); + elsif VDL_VBE_CS = '1' and FB_B(3) = '1' and FB_WRn = '0' then + VDL_VBE(7 downto 0) <= DATA_IN(23 downto 16); + end if; + + -- VDL_VDB: + if VDL_VDB_CS = '1' and FB_B(0) = '1' and FB_WRn = '0' then + VDL_VDB(10 downto 8) <= DATA_IN(26 downto 24); + elsif VDL_VDB_CS = '1' and FB_B(1) = '1' and FB_WRn = '0' then + VDL_VDB(7 downto 0) <= DATA_IN(23 downto 16); + end if; + -- VDL_VDE: + if VDL_VDE_CS = '1' and FB_B(2) = '1' and FB_WRn = '0' then + VDL_VDE(10 downto 8) <= DATA_IN(26 downto 24); + elsif VDL_VDE_CS = '1' and FB_B(3) = '1' and FB_WRn = '0' then + VDL_VDE(7 downto 0) <= DATA_IN(23 downto 16); + end if; + + -- VDL_VBB: + if VDL_VBB_CS = '1' and FB_B(0) = '1' and FB_WRn = '0' then + VDL_VBB(10 downto 8) <= DATA_IN(26 downto 24); + elsif VDL_VBB_CS = '1' and FB_B(1) = '1' and FB_WRn = '0' then + VDL_VBB(7 downto 0) <= DATA_IN(23 downto 16); + end if; + + -- VDL_VSS + if VDL_VSS_CS = '1' and FB_B(0) = '1' and FB_WRn = '0' then + VDL_VSS(10 downto 8) <= DATA_IN(26 downto 24); + elsif VDL_VSS_CS = '1' and FB_B(1) = '1' and FB_WRn = '0' then + VDL_VSS(7 downto 0) <= DATA_IN(23 downto 16); + end if; + + -- VDL_VFT + if VDL_VFT_CS = '1' and FB_B(2) = '1' and FB_WRn = '0' then + VDL_VFT(10 downto 8) <= DATA_IN(26 downto 24); + elsif VDL_VFT_CS = '1' and FB_B(3) = '1' and FB_WRn = '0' then + VDL_VFT(7 downto 0) <= DATA_IN(23 downto 16); + end if; + + -- VDL_VCT(2): 1 = 32MHz CLK_PIXEL, 0 = 25MHZ; VDL_VCT(0): 1 = linedoubling. + if VDL_VCT_CS = '1' and FB_B(0) = '1' and FB_WRn = '0' then + VDL_VCT(8) <= DATA_IN(24); + elsif VDL_VCT_CS = '1' and FB_B(1) = '1' and FB_WRn = '0' then + VDL_VCT(7 downto 0) <= DATA_IN(23 downto 16); + end if; + + -- VDL_VMD(2): 1 = CLK_PIXEL/2. + if VDL_VMD_CS = '1' and FB_B(3) = '1' and FB_WRn = '0' then + VDL_VMD <= DATA_IN(19 downto 16); + end if; + end process P_MISC_CTRL; + + BLITTER_ON <= not SYS_CTR(3); + + -- Register out: + DATA_OUT(31 downto 16) <= "000000" & ST_SHIFT_MODE & x"00" when ST_SHIFT_MODE_CS = '1' else + "00000" & FALCON_SHIFT_MODE when FALCON_SHIFT_MODE_CS = '1' else + "100000000" & SYS_CTR(6 downto 4) & not BLITTER_RUN & SYS_CTR(2 downto 0) when SYS_CTR_CS = '1' else + VDL_LOF when VDL_LOF_CS = '1' else + VDL_LWD when VDL_LWD_CS = '1' else + x"0" & VDL_HBE when VDL_HBE_CS = '1' else + x"0" & VDL_HDB when VDL_HDB_CS = '1' else + x"0" & VDL_HDE when VDL_HDE_CS = '1' else + x"0" & VDL_HBB when VDL_HBB_CS = '1' else + x"0" & VDL_HSS when VDL_HSS_CS = '1' else + x"0" & VDL_HHT when VDL_HHT_CS = '1' else + "00000" & VDL_VBE when VDL_VBE_CS = '1' else + "00000" & VDL_VDB when VDL_VDB_CS = '1' else + "00000" & VDL_VDE when VDL_VDE_CS = '1' else + "00000" & VDL_VBB when VDL_VBB_CS = '1' else + "00000" & VDL_VSS when VDL_VSS_CS = '1' else + "00000" & VDL_VFT when VDL_VFT_CS = '1' else + "0000000" & VDL_VCT when VDL_VCT_CS = '1' else + x"000" & VDL_VMD when VDL_VMD_CS = '1' else + FBEE_VCTR(31 downto 16) when FBEE_VCTR_CS = '1' else + ATARI_HH(31 downto 16) when ATARI_HH_CS = '1' else + ATARI_VH(31 downto 16) when ATARI_VH_CS = '1' else + ATARI_HL(31 downto 16) when ATARI_HL_CS = '1' else + ATARI_VL(31 downto 16) when ATARI_VL_CS = '1' else + x"00" & CCR_I(23 downto 16) when CCR_CS = '1' else + "0000000" & VR_DOUT when VIDEO_PLL_CONFIG_CS = '1' else + VR_BUSY & "0000" & VR_WR_I & VR_RD_I & VIDEO_RECONFIG_I & x"FA" when VIDEO_PLL_RECONFIG_CS = '1' else (others => '0'); + + DATA_OUT(15 downto 0) <= FBEE_VCTR(15 downto 0) when FBEE_VCTR_CS = '1' else + ATARI_HH(15 downto 0) when ATARI_HH_CS = '1' else + ATARI_VH(15 downto 0) when ATARI_VH_CS = '1' else + ATARI_HL(15 downto 0) when ATARI_HL_CS = '1' else + ATARI_VL(15 downto 0) when ATARI_VL_CS = '1' else + CCR_I(15 downto 0) when CCR_CS = '1' else (others => '0'); + + DATA_EN_H <= (ST_SHIFT_MODE_CS or FALCON_SHIFT_MODE_CS or FBEE_VCTR_CS or CCR_CS or SYS_CTR_CS or VDL_LOF_CS or VDL_LWD_CS or + VDL_HBE_CS or VDL_HDB_CS or VDL_HDE_CS or VDL_HBB_CS or VDL_HSS_CS or VDL_HHT_CS or + ATARI_HH_CS or ATARI_VH_CS or ATARI_HL_CS or ATARI_VL_CS or VIDEO_PLL_CONFIG_CS or VIDEO_PLL_RECONFIG_CS or + VDL_VBE_CS or VDL_VDB_CS or VDL_VDE_CS or VDL_VBB_CS or VDL_VSS_CS or VDL_VFT_CS or VDL_VCT_CS or VDL_VMD_CS) and not FB_OEn; + + DATA_EN_L <= (FBEE_VCTR_CS or CCR_CS or ATARI_HH_CS or ATARI_VH_CS or ATARI_HL_CS or ATARI_VL_CS ) and not FB_OEn; + + VIDEO_MOD_TA_I <= CLUT_TA or ST_SHIFT_MODE_CS or FALCON_SHIFT_MODE_CS or FBEE_VCTR_CS or SYS_CTR_CS or VDL_LOF_CS or VDL_LWD_CS or + VDL_HBE_CS or VDL_HDB_CS or VDL_HDE_CS or VDL_HBB_CS or VDL_HSS_CS or VDL_HHT_CS or + ATARI_HH_CS or ATARI_VH_CS or ATARI_HL_CS or ATARI_VL_CS or + VDL_VBE_CS or VDL_VDB_CS or VDL_VDE_CS or VDL_VBB_CS or VDL_VSS_CS or VDL_VFT_CS or VDL_VCT_CS or VDL_VMD_CS; + + P_CLK_16M5 : process + begin + wait until CLK33M = '1' and CLK33M' event; + CLK17M <= not CLK17M; + end process P_CLK_16M5; + + P_CLK_12M5 : process + begin + wait until CLK25M = '1' and CLK25M' event; + CLK13M <= not CLK13M; + end process P_CLK_12M5; + + CLK_PIXEL_I <= CLK13M when FBEE_VIDEO_ON = '0' and (FALCON_VIDEO = '1' or ST_VIDEO = '1') and VDL_VMD(2) = '1' and VDL_VCT(2) = '1' else + CLK13M when FBEE_VIDEO_ON = '0' and (FALCON_VIDEO = '1' or ST_VIDEO = '1') and VDL_VMD(2) = '1' and VDL_VCT(0) = '1' else + CLK17M when FBEE_VIDEO_ON = '0' and (FALCON_VIDEO = '1' or ST_VIDEO = '1') and VDL_VMD(2) = '1' and VDL_VCT(2) = '0' else + CLK17M when FBEE_VIDEO_ON = '0' and (FALCON_VIDEO = '1' or ST_VIDEO = '1') and VDL_VMD(2) = '1' and VDL_VCT(0) = '0' else + CLK25M when FBEE_VIDEO_ON = '0' and (FALCON_VIDEO = '1' or ST_VIDEO = '1') and VDL_VMD(2) = '0' and VDL_VCT(2) = '1' and VDL_VCT(0) = '0' else + CLK33M when FBEE_VIDEO_ON = '0' and (FALCON_VIDEO = '1' or ST_VIDEO = '1') and VDL_VMD(2) = '0' and VDL_VCT(2) = '0' and VDL_VCT(0) = '0' else + CLK25M when FBEE_VIDEO_ON = '1' and FBEE_VCTR(9 downto 8) = "00" else + CLK33M when FBEE_VIDEO_ON = '1' and FBEE_VCTR(9 downto 8) = "01" else + CLK_VIDEO when FBEE_VIDEO_ON = '1' and FBEE_VCTR(9) = '1' else '0'; + + P_HSYN_LEN : process + -- Horizontal SYNC in CLK_PIXEL: + begin + wait until CLK_MAIN = '1' and CLK_MAIN' event; + if FBEE_VIDEO_ON = '0' and (FALCON_VIDEO = '1' or ST_VIDEO = '1') and VDL_VMD(2) = '1' and VDL_VCT(2) = '1' then + HSY_LEN <= x"0E"; + elsif FBEE_VIDEO_ON = '0' and (FALCON_VIDEO = '1' or ST_VIDEO = '1') and VDL_VMD(2) = '1' and VDL_VCT(0) = '1' then + HSY_LEN <= x"0E"; + elsif FBEE_VIDEO_ON = '0' and (FALCON_VIDEO or ST_VIDEO) = '1' and VDL_VMD(2) = '1' and VDL_VCT(2) = '0' then + HSY_LEN <= x"10"; + elsif FBEE_VIDEO_ON = '0' and (FALCON_VIDEO or ST_VIDEO) = '1' and VDL_VMD(2) = '1' and VDL_VCT(0) = '0' then + HSY_LEN <= x"10"; + elsif FBEE_VIDEO_ON = '0' and (FALCON_VIDEO or ST_VIDEO) = '1' and VDL_VMD(2) = '0' and VDL_VCT(2) = '1' and VDL_VCT(0) = '0' then + HSY_LEN <= x"1C"; + elsif FBEE_VIDEO_ON = '0' and (FALCON_VIDEO or ST_VIDEO) = '1' and VDL_VMD(2) = '0' and VDL_VCT(2) = '0' and VDL_VCT(0) = '0' then + HSY_LEN <= x"20"; + elsif FBEE_VIDEO_ON = '1' and FBEE_VCTR(9 downto 8) = "00" then + HSY_LEN <= x"1C"; + elsif FBEE_VIDEO_ON = '1' and FBEE_VCTR(9 downto 8) = "01" then + HSY_LEN <= x"20"; + elsif FBEE_VIDEO_ON = '1' and FBEE_VCTR(9) = '1' then + HSY_LEN <= x"10" + ('0' & VR_FRQ(7 downto 1)); -- HSYNC pulse length in pixels = frequency/500ns. + else + HSY_LEN <= x"00"; + end if; + end process P_HSYN_LEN; + + MULF <= "000010" when ST_VIDEO = '0' and VDL_VMD(2) = '1' else -- Multiplier. + "000100" when ST_VIDEO = '0' and VDL_VMD(2) = '0' else + "010000" when ST_VIDEO = '1' and VDL_VMD(2) = '1' else + "100000" when ST_VIDEO = '1' and VDL_VMD(2) = '0' else "000000"; + + HDIS_LEN <= x"140" when VDL_VMD(2) = '1' else x"280"; -- Width in pixels (320 / 640). + + P_DOUBLE_LINE_1 : process + begin + wait until CLK_MAIN = '1' and CLK_MAIN' event; + DOP_ZEI <= VDL_VMD(0) and ST_VIDEO; -- Line doubling on off. + end process P_DOUBLE_LINE_1; + + P_DOUBLE_LINE_2 : process + begin + wait until CLK_PIXEL_I = '1' and CLK_PIXEL_I' event; + if DOP_ZEI = '1' and VVCNT(0) /= VDIS_START(0) and VVCNT /= "00000000000" and VHCNT < HDIS_END - '1' then + INTER_ZEI_I <= '1'; -- Switch insertion line to "double". Line zero due to SYNC. + elsif DOP_ZEI = '1' and VVCNT(0) = VDIS_START(0) and VVCNT /= "00000000000" and VHCNT > HDIS_END - "10" then + INTER_ZEI_I <= '1'; -- Switch insertion mode to "normal". Lines and line zero due to SYNC. + else + INTER_ZEI_I <= '0'; + end if; + -- + DOP_FIFO_CLR <= INTER_ZEI_I and HSYNC_START and SYNC_PIX; -- Double line info erase at the end of a double line and at main FIFO start. + end process P_DOUBLE_LINE_2; + + -- The following multiplications change every time the video resolution is changed. + MUL1 <= VDL_HBE * MULF(5 downto 1); + MUL2 <= (VDL_HHT + '1' + VDL_HSS) * MULF(5 downto 1); + MUL3 <= (VDL_HHT + "10") * MULF(5 downto 1); + + BORDER_LEFT <= VDL_HBE when FBEE_VIDEO_ON = '1' else + x"015" when ATARI_SYNC = '1' and VDL_VMD(2) = '1' else + x"02A" when ATARI_SYNC = '1' else MUL1(16 downto 5); + HDIS_START <= VDL_HDB when FBEE_VIDEO_ON = '1' else BORDER_LEFT + '1'; + HDIS_END <= VDL_HDE when FBEE_VIDEO_ON = '1' else BORDER_LEFT + HDIS_LEN; + BORDER_RIGHT <= VDL_HBB when FBEE_VIDEO_ON = '1' else HDIS_END + '1'; + HS_START <= VDL_HSS when FBEE_VIDEO_ON = '1' else + ATARI_HL(11 downto 0) when ATARI_SYNC = '1' and VDL_VMD(2) = '1' else + ATARI_HH(11 downto 0) when VDL_VMD(2) = '1' else MUL2(16 downto 5); + H_TOTAL <= VDL_HHT when FBEE_VIDEO_ON = '1' else + ATARI_HL(27 downto 16) when ATARI_SYNC = '1' and VDL_VMD(2) = '1' else + ATARI_HH(27 downto 16) when ATARI_SYNC = '1' else MUL3(16 downto 5); + BORDER_TOP <= VDL_VBE when FBEE_VIDEO_ON = '1' else + "00000011111" when ATARI_SYNC = '1' else '0' & VDL_VBE(10 downto 1); + VDIS_START <= VDL_VDB when FBEE_VIDEO_ON = '1' else + "00000100000" when ATARI_SYNC = '1' else '0' & VDL_VDB(10 downto 1); + VDIS_END <= VDL_VDE when FBEE_VIDEO_ON = '1' else + "00110101111" when ATARI_SYNC = '1' and ST_VIDEO = '1' else -- 431. + "00111111111" when ATARI_SYNC = '1' else '0' & VDL_VDE(10 downto 1); -- 511. + BORDER_BOTTOM <= VDL_VBB when FBEE_VIDEO_ON = '1' else + VDIS_END + '1' when ATARI_SYNC = '1' else ('0' & VDL_VBB(10 downto 1)) + '1'; + VS_START <= VDL_VSS when FBEE_VIDEO_ON = '1' else + ATARI_VL(10 downto 0) when ATARI_SYNC = '1' and VDL_VMD(2) = '1' else + ATARI_VH(10 downto 0) when ATARI_SYNC = '1' else '0' & VDL_VSS(10 downto 1); + V_TOTAL <= VDL_VFT when FBEE_VIDEO_ON = '1' else + ATARI_VL(26 downto 16) when ATARI_SYNC = '1' and VDL_VMD(2) = '1' else + ATARI_VH(26 downto 16) when ATARI_SYNC = '1' else '0' & VDL_VFT(10 downto 1); + + LAST <= '1' when VHCNT = H_TOTAL - "10" else '0'; + + VIDEO_CLOCK_DOMAIN : process + begin + wait until CLK_PIXEL_I = '1' and CLK_PIXEL_I' event; + + if ST_CLUT = '1' then + CCSEL <= "000"; -- For information only. + elsif FALCON_CLUT = '1' then + CCSEL <= "001"; + elsif FBEE_CLUT = '1' then + CCSEL <= "100"; + elsif COLOR16_I = '1' then + CCSEL <= "101"; + elsif COLOR24_I = '1' then + CCSEL <= "110"; + elsif RAND_ON = '1' then + CCSEL <= "111"; + end if; + + if LAST = '0' then + VHCNT <= VHCNT + '1'; + else + VHCNT <= (others => '0'); + end if; + + if LAST = '1' and VVCNT = V_TOTAL - '1' then + VVCNT <= (others => '0'); + elsif LAST = '1' then + VVCNT <= VVCNT + '1'; + end if; + + -- Display on/off: + if LAST = '1' and VVCNT > BORDER_TOP - '1' and VVCNT < BORDER_BOTTOM - '1' then + DPO_ZL <= '1'; + elsif LAST = '1' then + DPO_ZL <= '0'; + end if; + + if VHCNT = BORDER_LEFT then + DPO_ON <= '1'; -- BESSER EINZELN WEGEN TIMING + else + DPO_ON <= '0'; + end if; + + if VHCNT = BORDER_RIGHT - '1' then + DPO_OFF <= '1'; + else + DPO_OFF <= '0'; + end if; + + DISP_ON <= (DISP_ON and not DPO_OFF) or (DPO_ON and DPO_ZL); + + -- Data transfer on/off: + if VHCNT = HDIS_START - '1' then + VDO_ON <= '1'; -- BESSER EINZELN WEGEN TIMING. + else + VDO_ON <= '0'; + end if; + + if VHCNT = HDIS_END then + VDO_OFF <= '1'; + else + VDO_OFF <= '0'; + end if; + + if LAST = '1' and VVCNT >= VDIS_START - '1' and VVCNT < VDIS_END then + VDO_ZL <= '1'; -- Take over at the end of the line. + elsif LAST = '1' then + VDO_ZL <= '0'; -- 1 ZEILE DAVOR ON OFF + + end if; + + VDTRON <= (VDTRON and not VDO_OFF) or (VDO_ON and VDO_ZL); + + -- Delay and SYNC + if VHCNT = HS_START - "11" then + HSYNC_START <= '1'; + else + HSYNC_START <= '0'; + end if; + + if HSYNC_START = '1' then + HSYNC_I <= HSY_LEN; + elsif HSYNC_I > x"00" then + HSYNC_I <= HSYNC_I - '1'; + end if; + + if LAST = '1' and VVCNT = VS_START - "11" then + VSYNC_START <= '1'; -- start am ende der Zeile vor dem vsync + else + VSYNC_START <= '0'; + end if; + + if LAST = '1' and VSYNC_START = '1' then -- Start at the end of the line before VSYNC. + VSYNC_I <= "011"; -- 3 lines vsync length. + elsif LAST = '1' and VSYNC_I > "000" then + VSYNC_I <= VSYNC_I - '1'; -- Count down. + end if; + + if FBEE_VCTR(15) = '1' and VDL_VCT(5) = '1' and VSYNC_I = "000" then + VERZ_2 <= VERZ_2(8 downto 0) & '1'; + elsif (FBEE_VCTR(15) = '0' or VDL_VCT(5) = '0') and VSYNC_I /= "000" then + VERZ_2 <= VERZ_2(8 downto 0) & '1'; + else + VERZ_2 <= VERZ_2(8 downto 0) & '0'; + end if; + + if HSYNC_I > x"00" then + VERZ_1 <= VERZ_1(8 downto 0) & '1'; + else + VERZ_1 <= VERZ_1(8 downto 0) & '0'; + end if; + + VERZ_0 <= VERZ_0(8 downto 0) & DISP_ON; + + BLANKn <= VERZ_0(8); + HSYNC <= VERZ_1(9); + VSYNC <= VERZ_2(9); + SYNCn <= not(VERZ_2(9) or VERZ_1(9)); + + -- Boarder colours: + RAND <= RAND(5 downto 0) & (DISP_ON and not VDTRON and FBEE_VCTR(25)); + RAND_ON <= RAND(6); + + if LAST = '1' and VVCNT = V_TOTAL - "10" then + FIFO_CLR <= '1'; + elsif LAST = '1' then + FIFO_CLR <= '0'; + end if; + + if LAST = '1' and VVCNT = "00000000000" then + START_ZEILE <= '1'; + elsif LAST = '1' then + START_ZEILE <= '0'; + end if; + + if VHCNT = x"003" and START_ZEILE = '1' then + SYNC_PIX <= '1'; + else + SYNC_PIX <= '0'; + end if; + + if VHCNT = x"005" and START_ZEILE = '1' then + SYNC_PIX1 <= '1'; + else + SYNC_PIX1 <= '0'; + end if; + + if VHCNT = x"007" and START_ZEILE = '1' then + SYNC_PIX2 <= '1'; + else + SYNC_PIX2 <= '0'; + end if; + + if VDTRON = '1' and SYNC_PIX = '0' then + SUB_PIXEL_CNT <= SUB_PIXEL_CNT + '1'; + elsif VDTRON = '1' then + SUB_PIXEL_CNT <= (others => '0'); + end if; + + if VDTRON = '1' and SUB_PIXEL_CNT(6 downto 0) = "0000001" and COLOR1_I = '1' then + FIFO_RDE <= '1'; + elsif VDTRON = '1' and SUB_PIXEL_CNT(5 downto 0) = "000001" and COLOR2_I = '1' then + FIFO_RDE <= '1'; + elsif VDTRON = '1' and SUB_PIXEL_CNT(4 downto 0) = "00001" and COLOR4_I = '1' then + FIFO_RDE <= '1'; + elsif VDTRON = '1' and SUB_PIXEL_CNT(3 downto 0) = "0001" and COLOR8_I = '1' then + FIFO_RDE <= '1'; + elsif VDTRON = '1' and SUB_PIXEL_CNT(2 downto 0) = "001" and COLOR16_I = '1' then + FIFO_RDE <= '1'; + elsif VDTRON = '1' and SUB_PIXEL_CNT(1 downto 0) = "01" and COLOR24_I = '1' then + FIFO_RDE <= '1'; + elsif SYNC_PIX = '1' or SYNC_PIX1 = '1' or SYNC_PIX2 = '1' then + FIFO_RDE <= '1'; -- 3 CLOCK ZUS�TZLICH F�R FIFO SHIFT DATAOUT UND SHIFT RIGTH POSITION + else + FIFO_RDE <= '0'; + end if; + + CLUT_MUX_AV_0 <= SUB_PIXEL_CNT(3 downto 0); + CLUT_MUX_AV_1 <= CLUT_MUX_AV_0; + CLUT_MUX_ADR <= CLUT_MUX_AV_1; + end process VIDEO_CLOCK_DOMAIN; +end architecture BEHAVIOUR; diff --git a/vhdl/rtl/vhdl/Video/Video_Top.vhd b/vhdl/rtl/vhdl/Video/Video_Top.vhd new file mode 100644 index 0000000..9a44bf5 --- /dev/null +++ b/vhdl/rtl/vhdl/Video/Video_Top.vhd @@ -0,0 +1,533 @@ +---------------------------------------------------------------------- +---- ---- +---- This file is part of the 'Firebee' project. ---- +---- http://acp.atari.org ---- +---- ---- +---- Description: ---- +---- This design unit provides the video toplevel of the 'Firebee'---- +---- computer. It is optimized for the use of an Altera Cyclone ---- +---- FPGA (EP3C40F484). This IP-Core is based on the first edi- ---- +---- tion of the Firebee configware originally provided by Fredi ---- +---- Ashwanden and Wolfgang Förster. This release is in compa- ---- +---- rision to the first edition completely written in VHDL. ---- +---- ---- +---- Author(s): ---- +---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2012 Wolfgang Förster ---- +---- ---- +---- This source file 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 2 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, write to the Free ---- +---- Software Foundation, Inc., 51 Franklin Street, Fifth Floor, ---- +---- Boston, MA 02110-1301, USA. ---- +---- ---- +---------------------------------------------------------------------- +-- +-- Revision History +-- +-- Revision 2K12B 20120801 WF +-- Initial Release of the second edition. +-- ST colours enhanced to 4 bit colour mode (STE compatibility). + +library work; +use work.firebee_pkg.all; + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + +entity VIDEO_SYSTEM is + port( + CLK_MAIN : in std_logic; + CLK_33M : in std_logic; + CLK_25M : in std_logic; + CLK_VIDEO : in std_logic; + CLK_DDR3 : in std_logic; + CLK_DDR2 : in std_logic; + CLK_DDR0 : in std_logic; + CLK_PIXEL : out std_logic; + + VR_D : in std_logic_vector(8 downto 0); + VR_BUSY : in std_logic; + + FB_ADR : in std_logic_vector(31 downto 0); + FB_AD_IN : in std_logic_vector(31 downto 0); + FB_AD_OUT : out std_logic_vector(31 downto 0); + FB_AD_EN_31_16 : out std_logic; -- Hi word. + FB_AD_EN_15_0 : out std_logic; -- Low word. + FB_ALE : in std_logic; + FB_CSn : in std_logic_vector(3 downto 1); + FB_OEn : in std_logic; + FB_WRn : in std_logic; + FB_SIZE1 : in std_logic; + FB_SIZE0 : in std_logic; + + VDP_IN : in std_logic_vector(63 downto 0); + + VR_RD : out std_logic; + VR_WR : out std_logic; + VIDEO_RECONFIG : out std_logic; + + RED : out std_logic_vector(7 downto 0); + GREEN : out std_logic_vector(7 downto 0); + BLUE : out std_logic_vector(7 downto 0); + VSYNC : out std_logic; + HSYNC : out std_logic; + SYNCn : out std_logic; + BLANKn : out std_logic; + + PD_VGAn : out std_logic; + VIDEO_MOD_TA : out std_logic; + + VD_VZ : out std_logic_vector(127 downto 0); + SR_FIFO_WRE : in std_logic; + SR_VDMP : in std_logic_vector(7 downto 0); + FIFO_MW : out std_logic_vector(8 downto 0); + VDM_SEL : in std_logic_vector(3 downto 0); + VIDEO_RAM_CTR : out std_logic_vector(15 downto 0); + FIFO_CLR : out std_logic; + VDM : out std_logic_vector(3 downto 0); + + BLITTER_RUN : in std_logic; + BLITTER_ON : out std_logic + ); +end entity VIDEO_SYSTEM; + +architecture BEHAVIOUR of VIDEO_SYSTEM is +component lpm_fifo_dc0 + port( + aclr : in std_logic := '0'; + data : in std_logic_vector (127 downto 0); + rdclk : in std_logic ; + rdreq : in std_logic ; + wrclk : in std_logic ; + wrreq : in std_logic ; + q : out std_logic_vector (127 downto 0); + rdempty : out STD_LOGIC ; + wrusedw : out std_logic_vector (8 downto 0) + ); +end component; + +component lpm_fifoDZ is + port( + aclr : in std_logic ; + clock : in std_logic ; + data : in std_logic_vector (127 downto 0); + rdreq : in std_logic ; + wrreq : in std_logic ; + q : out std_logic_vector (127 downto 0) + ); +end component; + +type CLUT_SHIFTREG_TYPE is array(0 to 7) of std_logic_vector(15 downto 0); +type CLUT_ST_TYPE is array(0 to 15) of std_logic_vector(11 downto 0); +type CLUT_FA_TYPE is array(0 to 255) of std_logic_vector(17 downto 0); +type CLUT_FBEE_TYPE is array(0 to 255) of std_logic_vector(23 downto 0); + +signal CLUT_FA : CLUT_FA_TYPE; +signal CLUT_FI : CLUT_FBEE_TYPE; +signal CLUT_ST : CLUT_ST_TYPE; + +signal CLUT_FA_R : std_logic_vector(5 downto 0); +signal CLUT_FA_G : std_logic_vector(5 downto 0); +signal CLUT_FA_B : std_logic_vector(5 downto 0); +signal CLUT_FBEE_R : std_logic_vector(7 downto 0); +signal CLUT_FBEE_G : std_logic_vector(7 downto 0); +signal CLUT_FBEE_B : std_logic_vector(7 downto 0); +signal CLUT_ST_R : std_logic_vector(3 downto 0); +signal CLUT_ST_G : std_logic_vector(3 downto 0); +signal CLUT_ST_B : std_logic_vector(3 downto 0); + +signal CLUT_FA_OUT : std_logic_vector(17 downto 0); +signal CLUT_FBEE_OUT : std_logic_vector(23 downto 0); +signal CLUT_ST_OUT : std_logic_vector(11 downto 0); + +signal CLUT_ADR : std_logic_vector(7 downto 0); +signal CLUT_ADR_A : std_logic_vector(7 downto 0); +signal CLUT_ADR_MUX : std_logic_vector(3 downto 0); + +signal CLUT_SHIFT_IN : std_logic_vector(5 downto 0); + +signal CLUT_SHIFT_LOAD : std_logic; +signal CLUT_OFF : std_logic_vector(3 downto 0); +signal CLUT_FBEE_RD : std_logic; +signal CLUT_FBEE_WR : std_logic_vector(3 downto 0); +signal CLUT_FA_RDH : std_logic; +signal CLUT_FA_RDL : std_logic; +signal CLUT_FA_WR : std_logic_vector(3 downto 0); +signal CLUT_ST_RD : std_logic; +signal CLUT_ST_WR : std_logic_vector(1 downto 0); + +signal DATA_OUT_VIDEO_CTRL : std_logic_vector(31 downto 0); +signal DATA_EN_H_VIDEO_CTRL : std_logic; +signal DATA_EN_L_VIDEO_CTRL : std_logic; + +signal COLOR1 : std_logic; +signal COLOR2 : std_logic; +signal COLOR4 : std_logic; +signal COLOR8 : std_logic; +signal CCR : std_logic_vector(23 downto 0); +signal CC_SEL : std_logic_vector(2 downto 0); + +signal FIFO_CLR_I : std_logic; +signal DOP_FIFO_CLR : std_logic; +signal FIFO_WRE : std_logic; + +signal FIFO_RD_REQ_128 : std_logic; +signal FIFO_RD_REQ_512 : std_logic; +signal FIFO_RDE : std_logic; +signal INTER_ZEI : std_logic; +signal FIFO_D_OUT_128 : std_logic_vector(127 downto 0); +signal FIFO_D_OUT_512 : std_logic_vector(127 downto 0); +signal FIFO_D_IN_512 : std_logic_vector(127 downto 0); +signal FIFO_D : std_logic_vector(127 downto 0); + +signal VD_VZ_I : std_logic_vector(127 downto 0); +signal VDM_A : std_logic_vector(127 downto 0); +signal VDM_B : std_logic_vector(127 downto 0); +signal VDM_C : std_logic_vector(127 downto 0); +signal V_DMA_SEL : std_logic_vector(3 downto 0); +signal VDMP : std_logic_vector(7 downto 0); +signal VDMP_I : std_logic_vector(7 downto 0); +signal CC_24 : std_logic_vector(31 downto 0); +signal CC_16 : std_logic_vector(23 downto 0); +signal CLK_PIXEL_I : std_logic; +signal VD_OUT_I : std_logic_vector(31 downto 0); +signal ZR_C8 : std_logic_vector(7 downto 0); +begin + CLK_PIXEL <= CLK_PIXEL_I; + + FIFO_CLR <= FIFO_CLR_I; + + P_CLUT_ST_MC: process + + -- This is the dual ported ram for the ST colour lookup tables. + begin + wait until CLK_MAIN = '1' and CLK_MAIN' event; + if CLUT_ST_WR(0) = '1' then + CLUT_ST(conv_integer(FB_ADR(4 downto 1)))(11 downto 8) <= FB_AD_IN(27 downto 24); + end if; + if CLUT_ST_WR(1) = '1' then + CLUT_ST(conv_integer(FB_ADR(4 downto 1)))(7 downto 0) <= FB_AD_IN(23 downto 16); + end if; + -- + if CLUT_FA_WR(0) = '1' then + CLUT_FA(conv_integer(FB_ADR(9 downto 2)))(17 downto 12) <= FB_AD_IN(31 downto 26); + end if; + if CLUT_FA_WR(1) = '1' then + CLUT_FA(conv_integer(FB_ADR(9 downto 2)))(11 downto 6) <= FB_AD_IN(23 downto 18); + end if; + if CLUT_FA_WR(3) = '1' then + CLUT_FA(conv_integer(FB_ADR(9 downto 2)))(5 downto 0) <= FB_AD_IN(23 downto 18); + end if; + -- + if CLUT_FBEE_WR(1) = '1' then + CLUT_FI(conv_integer(FB_ADR(9 downto 2)))(23 downto 16) <= FB_AD_IN(23 downto 16); + end if; + if CLUT_FBEE_WR(2) = '1' then + CLUT_FI(conv_integer(FB_ADR(9 downto 2)))(15 downto 8) <= FB_AD_IN(15 downto 8); + end if; + if CLUT_FBEE_WR(3) = '1' then + CLUT_FI(conv_integer(FB_ADR(9 downto 2)))(7 downto 0) <= FB_AD_IN(7 downto 0); + end if; + -- + CLUT_ST_OUT <= CLUT_ST(conv_integer(FB_ADR(4 downto 1))); + CLUT_FA_OUT <= CLUT_FA(conv_integer(FB_ADR(9 downto 2))); + CLUT_FBEE_OUT <= CLUT_FI(conv_integer(FB_ADR(9 downto 2))); + end process P_CLUT_ST_MC; + + P_CLUT_ST_PX: process + -- This is the dual ported ram for the ST colour lookup tables. + begin + wait until CLK_PIXEL_I = '1' and CLK_PIXEL_I' event; + CLUT_ST_R <= CLUT_ST(conv_integer(CLUT_ADR(3 downto 0)))(8) & CLUT_ST(conv_integer(CLUT_ADR(3 downto 0)))(11 downto 9); + CLUT_ST_G <= CLUT_ST(conv_integer(CLUT_ADR(3 downto 0)))(4) & CLUT_ST(conv_integer(CLUT_ADR(3 downto 0)))(7 downto 5); + CLUT_ST_B <= CLUT_ST(conv_integer(CLUT_ADR(3 downto 0)))(0) & CLUT_ST(conv_integer(CLUT_ADR(3 downto 0)))(3 downto 1); + CLUT_FA_R <= CLUT_FA(conv_integer(CLUT_ADR))(17 downto 12); + CLUT_FA_G <= CLUT_FA(conv_integer(CLUT_ADR))(11 downto 6); + CLUT_FA_B <= CLUT_FA(conv_integer(CLUT_ADR))(5 downto 0); + CLUT_FBEE_R <= CLUT_FI(conv_integer(ZR_C8))(23 downto 16); + CLUT_FBEE_G <= CLUT_FI(conv_integer(ZR_C8))(15 downto 8); + CLUT_FBEE_B <= CLUT_FI(conv_integer(ZR_C8))(7 downto 0); + end process P_CLUT_ST_PX; + + P_VIDEO_OUT: process + variable VIDEO_OUT : std_logic_vector(23 downto 0); + begin + wait until CLK_PIXEL_I = '1' and CLK_PIXEL_I' event; + case CC_SEL is + when "111" => VIDEO_OUT := CCR; -- Register type video. + when "110" => VIDEO_OUT := CC_24(23 downto 0); -- 3 byte FIFO type video. + when "101" => VIDEO_OUT := CC_16; -- 2 byte FIFO type video. + when "100" => VIDEO_OUT := CLUT_FBEE_R & CLUT_FBEE_G & CLUT_FBEE_B; -- Firebee type video. + when "001" => VIDEO_OUT := CLUT_FA_R & "00" & CLUT_FA_G & "00" & CLUT_FA_B & "00"; -- Falcon type video. + when "000" => VIDEO_OUT := CLUT_ST_R & x"0" & CLUT_ST_G & x"0" & CLUT_ST_B & x"0"; -- ST type video. + when others => VIDEO_OUT := (others => '0'); + end case; + RED <= VIDEO_OUT(23 downto 16); + GREEN <= VIDEO_OUT(15 downto 8); + BLUE <= VIDEO_OUT(7 downto 0); + end process P_VIDEO_OUT; + + P_CC: process + variable CC24_I : std_logic_vector(31 downto 0); + variable CC_I : std_logic_vector(15 downto 0); + variable ZR_C8_I : std_logic_vector(7 downto 0); + begin + wait until CLK_PIXEL_I = '1' and CLK_PIXEL_I' event; + case CLUT_ADR_MUX(1 downto 0) is + when "11" => CC24_I := FIFO_D(31 downto 0); + when "10" => CC24_I := FIFO_D(63 downto 32); + when "01" => CC24_I := FIFO_D(95 downto 64); + when "00" => CC24_I := FIFO_D(127 downto 96); + end case; + -- + CC_24 <= CC24_I; + -- + case CLUT_ADR_MUX(2 downto 0) is + when "111" => CC_I := FIFO_D(15 downto 0); + when "110" => CC_I := FIFO_D(31 downto 16); + when "101" => CC_I := FIFO_D(47 downto 32); + when "100" => CC_I := FIFO_D(63 downto 48); + when "011" => CC_I := FIFO_D(79 downto 64); + when "010" => CC_I := FIFO_D(95 downto 80); + when "001" => CC_I := FIFO_D(111 downto 96); + when "000" => CC_I := FIFO_D(127 downto 112); + end case; + -- + CC_16 <= CC_I(15 downto 11) & "000" & CC_I(10 downto 5) & "00" & CC_I(4 downto 0) & "000"; + -- + case CLUT_ADR_MUX(3 downto 0) is + when x"F" => ZR_C8_I := FIFO_D(7 downto 0); + when x"E" => ZR_C8_I := FIFO_D(15 downto 8); + when x"D" => ZR_C8_I := FIFO_D(23 downto 16); + when x"C" => ZR_C8_I := FIFO_D(31 downto 24); + when x"B" => ZR_C8_I := FIFO_D(39 downto 32); + when x"A" => ZR_C8_I := FIFO_D(47 downto 40); + when x"9" => ZR_C8_I := FIFO_D(55 downto 48); + when x"8" => ZR_C8_I := FIFO_D(63 downto 56); + when x"7" => ZR_C8_I := FIFO_D(71 downto 64); + when x"6" => ZR_C8_I := FIFO_D(79 downto 72); + when x"5" => ZR_C8_I := FIFO_D(87 downto 80); + when x"4" => ZR_C8_I := FIFO_D(95 downto 88); + when x"3" => ZR_C8_I := FIFO_D(103 downto 96); + when x"2" => ZR_C8_I := FIFO_D(111 downto 104); + when x"1" => ZR_C8_I := FIFO_D(119 downto 112); + when x"0" => ZR_C8_I := FIFO_D(127 downto 120); + end case; + -- + case COLOR1 is + when '1' => ZR_C8 <= ZR_C8_I; + when others => ZR_C8 <= "0000000" & ZR_C8_I(0); + end case; + end process P_CC; + + CLUT_SHIFT_IN <= CLUT_ADR_A(6 downto 1) when COLOR4 = '0' and COLOR2 = '0' else + CLUT_ADR_A(7 downto 2) when COLOR4 = '0' and COLOR2 = '1' else + "00" & CLUT_ADR_A(7 downto 4) when COLOR4 = '1' and COLOR2 = '0' else "000000"; + + FIFO_RD_REQ_128 <= '1' when FIFO_RDE = '1' and INTER_ZEI = '1' else '0'; + FIFO_RD_REQ_512 <= '1' when FIFO_RDE = '1' and INTER_ZEI = '0' else '0'; + + FIFO_DMUX: process + begin + wait until CLK_PIXEL_I = '1' and CLK_PIXEL_I' event; + if FIFO_RDE = '1' and INTER_ZEI = '1' then + FIFO_D <= FIFO_D_OUT_128; + elsif FIFO_RDE = '1' then + FIFO_D <= FIFO_D_OUT_512; + end if; + end process FIFO_DMUX; + + CLUT_SHIFTREGS: process + variable CLUT_SHIFTREG : CLUT_SHIFTREG_TYPE; + begin + wait until CLK_PIXEL_I = '1' and CLK_PIXEL_I' event; + CLUT_SHIFT_LOAD <= FIFO_RDE; + if CLUT_SHIFT_LOAD = '1' then + for i in 0 to 7 loop + CLUT_SHIFTREG(7 - i) := FIFO_D((i+1)*16 -1 downto i*16); + end loop; + else + CLUT_SHIFTREG(7) := CLUT_SHIFTREG(7)(14 downto 0) & CLUT_ADR_A(0); + CLUT_SHIFTREG(6) := CLUT_SHIFTREG(6)(14 downto 0) & CLUT_ADR_A(7); + CLUT_SHIFTREG(5) := CLUT_SHIFTREG(5)(14 downto 0) & CLUT_SHIFT_IN(5); + CLUT_SHIFTREG(4) := CLUT_SHIFTREG(4)(14 downto 0) & CLUT_SHIFT_IN(4); + CLUT_SHIFTREG(3) := CLUT_SHIFTREG(3)(14 downto 0) & CLUT_SHIFT_IN(3); + CLUT_SHIFTREG(2) := CLUT_SHIFTREG(2)(14 downto 0) & CLUT_SHIFT_IN(2); + CLUT_SHIFTREG(1) := CLUT_SHIFTREG(1)(14 downto 0) & CLUT_SHIFT_IN(1); + CLUT_SHIFTREG(0) := CLUT_SHIFTREG(0)(14 downto 0) & CLUT_SHIFT_IN(0); + end if; + -- + for i in 0 to 7 loop + CLUT_ADR_A(i) <= CLUT_SHIFTREG(i)(15); + end loop; + end process CLUT_SHIFTREGS; + + CLUT_ADR(7) <= CLUT_OFF(3) or (CLUT_ADR_A(7) and COLOR8); + CLUT_ADR(6) <= CLUT_OFF(2) or (CLUT_ADR_A(6) and COLOR8); + CLUT_ADR(5) <= CLUT_OFF(1) or (CLUT_ADR_A(5) and COLOR8); + CLUT_ADR(4) <= CLUT_OFF(0) or (CLUT_ADR_A(4) and COLOR8); + CLUT_ADR(3) <= CLUT_ADR_A(3) and (COLOR8 or COLOR4); + CLUT_ADR(2) <= CLUT_ADR_A(2) and (COLOR8 or COLOR4); + CLUT_ADR(1) <= CLUT_ADR_A(1) and (COLOR8 or COLOR4 or COLOR2); + CLUT_ADR(0) <= CLUT_ADR_A(0); + + FB_AD_OUT <= x"0" & CLUT_ST_OUT & x"0000" when CLUT_ST_RD = '1' else + CLUT_FA_OUT(17 downto 12) & "00" & CLUT_FA_OUT(11 downto 6) & "00" & x"0000" when CLUT_FA_RDH = '1' else + x"00" & CLUT_FA_OUT(5 downto 0) & "00" & x"0000" when CLUT_FA_RDL = '1' else + x"00" & CLUT_FBEE_OUT when CLUT_FBEE_RD = '1' else + DATA_OUT_VIDEO_CTRL when DATA_EN_H_VIDEO_CTRL = '1' else -- Use upper word. + DATA_OUT_VIDEO_CTRL when DATA_EN_L_VIDEO_CTRL = '1' else (others => '0'); -- Use lower word. + + FB_AD_EN_31_16 <= '1' when CLUT_FBEE_RD = '1' else + '1' when CLUT_FA_RDH = '1' else + '1' when DATA_EN_H_VIDEO_CTRL = '1' else '0'; + + FB_AD_EN_15_0 <= '1' when CLUT_FBEE_RD = '1' else + '1' when CLUT_FA_RDL = '1' else + '1' when DATA_EN_L_VIDEO_CTRL = '1' else '0'; + + VD_VZ <= VD_VZ_I; + + DFF_CLK0: process + begin + wait until CLK_DDR0 = '1' and CLK_DDR0' event; + VD_VZ_I <= VD_VZ_I(63 downto 0) & VDP_IN(63 downto 0); + -- + if FIFO_WRE = '1' then + VDM_A <= VD_VZ_I; + VDM_B <= VDM_A; + end if; + end process DFF_CLK0; + + DFF_CLK2: process + begin + wait until CLK_DDR2 = '1' and CLK_DDR2' event; + VDMP <= SR_VDMP; + end process DFF_CLK2; + + DFF_CLK3: process + begin + wait until CLK_DDR3 = '1' and CLK_DDR3' event; + VDMP_I <= VDMP; + end process DFF_CLK3; + + VDM <= VDMP_I(7 downto 4) when CLK_DDR3 = '1' else VDMP_I(3 downto 0); + + SHIFT_CLK0: process + variable TMP : std_logic_vector(4 downto 0); + begin + wait until CLK_DDR0 = '1' and CLK_DDR0' event; + TMP := SR_FIFO_WRE & TMP(4 downto 1); + FIFO_WRE <= TMP(0); + end process SHIFT_CLK0; + + with VDM_SEL select + VDM_C <= VDM_B when x"0", + VDM_B(119 downto 0) & VDM_A(127 downto 120) when x"1", + VDM_B(111 downto 0) & VDM_A(127 downto 112) when x"2", + VDM_B(103 downto 0) & VDM_A(127 downto 104) when x"3", + VDM_B(95 downto 0) & VDM_A(127 downto 96) when x"4", + VDM_B(87 downto 0) & VDM_A(127 downto 88) when x"5", + VDM_B(79 downto 0) & VDM_A(127 downto 80) when x"6", + VDM_B(71 downto 0) & VDM_A(127 downto 72) when x"7", + VDM_B(63 downto 0) & VDM_A(127 downto 64) when x"8", + VDM_B(55 downto 0) & VDM_A(127 downto 56) when x"9", + VDM_B(47 downto 0) & VDM_A(127 downto 48) when x"A", + VDM_B(39 downto 0) & VDM_A(127 downto 40) when x"B", + VDM_B(31 downto 0) & VDM_A(127 downto 32) when x"C", + VDM_B(23 downto 0) & VDM_A(127 downto 24) when x"D", + VDM_B(15 downto 0) & VDM_A(127 downto 16) when x"E", + VDM_B(7 downto 0) & VDM_A(127 downto 8) when x"F"; + + I_FIFO_DC0: lpm_fifo_dc0 + port map( + aclr => FIFO_CLR_I, + data => VDM_C, + rdclk => CLK_PIXEL_I, + rdreq => FIFO_RD_REQ_512, + wrclk => CLK_DDR0, + wrreq => FIFO_WRE, + q => FIFO_D_OUT_512, + --rdempty =>, -- Not used. + wrusedw => FIFO_MW + ); + + I_FIFO_DZ: lpm_fifoDZ + port map( + aclr => DOP_FIFO_CLR, + clock => CLK_PIXEL_I, + data => FIFO_D_OUT_512, + rdreq => FIFO_RD_REQ_128, + wrreq => FIFO_RD_REQ_512, + q => FIFO_D_OUT_128 + ); + + I_VIDEO_CTRL: VIDEO_CTRL + port map( + CLK_MAIN => CLK_MAIN, + FB_CSn(1) => FB_CSn(1), + FB_CSn(2) => FB_CSn(2), + FB_WRn => FB_WRn, + FB_OEn => FB_OEn, + FB_SIZE(0) => FB_SIZE0, + FB_SIZE(1) => FB_SIZE1, + FB_ADR => FB_ADR, + CLK33M => CLK_33M, + CLK25M => CLK_25M, + BLITTER_RUN => BLITTER_RUN, + CLK_VIDEO => CLK_VIDEO, + VR_D => VR_D, + VR_BUSY => VR_BUSY, + COLOR8 => COLOR8, + FBEE_CLUT_RD => CLUT_FBEE_RD, + COLOR1 => COLOR1, + FALCON_CLUT_RDH => CLUT_FA_RDH, + FALCON_CLUT_RDL => CLUT_FA_RDL, + FALCON_CLUT_WR => CLUT_FA_WR, + CLUT_ST_RD => CLUT_ST_RD, + CLUT_ST_WR => CLUT_ST_WR, + CLUT_MUX_ADR => CLUT_ADR_MUX, + HSYNC => HSYNC, + VSYNC => VSYNC, + BLANKn => BLANKn, + SYNCn => SYNCn, + PD_VGAn => PD_VGAn, + FIFO_RDE => FIFO_RDE, + COLOR2 => COLOR2, + COLOR4 => COLOR4, + CLK_PIXEL => CLK_PIXEL_I, + CLUT_OFF => CLUT_OFF, + BLITTER_ON => BLITTER_ON, + VIDEO_RAM_CTR => VIDEO_RAM_CTR, + VIDEO_MOD_TA => VIDEO_MOD_TA, + CCR => CCR, + CCSEL => CC_SEL, + FBEE_CLUT_WR => CLUT_FBEE_WR, + INTER_ZEI => INTER_ZEI, + DOP_FIFO_CLR => DOP_FIFO_CLR, + VIDEO_RECONFIG => VIDEO_RECONFIG, + VR_WR => VR_WR, + VR_RD => VR_RD, + FIFO_CLR => FIFO_CLR_I, + DATA_IN => FB_AD_IN, + DATA_OUT => DATA_OUT_VIDEO_CTRL, + DATA_EN_H => DATA_EN_H_VIDEO_CTRL, + DATA_EN_L => DATA_EN_L_VIDEO_CTRL + ); +end architecture; diff --git a/vhdl/rtl/vhdl/Video/lpm_fifoDZ.cmp b/vhdl/rtl/vhdl/Video/lpm_fifoDZ.cmp new file mode 100644 index 0000000..153e7c2 --- /dev/null +++ b/vhdl/rtl/vhdl/Video/lpm_fifoDZ.cmp @@ -0,0 +1,26 @@ +--Copyright (C) 1991-2010 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. + + +component lpm_fifoDZ + PORT + ( + aclr : IN STD_LOGIC ; + clock : IN STD_LOGIC ; + data : IN STD_LOGIC_VECTOR (127 DOWNTO 0); + rdreq : IN STD_LOGIC ; + wrreq : IN STD_LOGIC ; + q : OUT STD_LOGIC_VECTOR (127 DOWNTO 0) + ); +end component; diff --git a/vhdl/rtl/vhdl/Video/lpm_fifoDZ.qip b/vhdl/rtl/vhdl/Video/lpm_fifoDZ.qip new file mode 100644 index 0000000..5444627 --- /dev/null +++ b/vhdl/rtl/vhdl/Video/lpm_fifoDZ.qip @@ -0,0 +1,5 @@ +set_global_assignment -name IP_TOOL_NAME "LPM_FIFO+" +set_global_assignment -name IP_TOOL_VERSION "9.1" +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "lpm_fifoDZ.vhd"] +set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "lpm_fifoDZ.bsf"] +set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "lpm_fifoDZ.cmp"] diff --git a/vhdl/rtl/vhdl/Video/lpm_fifoDZ.vhd b/vhdl/rtl/vhdl/Video/lpm_fifoDZ.vhd new file mode 100644 index 0000000..95486bb --- /dev/null +++ b/vhdl/rtl/vhdl/Video/lpm_fifoDZ.vhd @@ -0,0 +1,178 @@ +-- megafunction wizard: %LPM_FIFO+% +-- GENERATION: STANDARD +-- VERSION: WM1.0 +-- MODULE: scfifo + +-- ============================================================ +-- File Name: lpm_fifoDZ.vhd +-- Megafunction Name(s): +-- scfifo +-- +-- Simulation Library Files(s): +-- altera_mf +-- ============================================================ +-- ************************************************************ +-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! +-- +-- 9.1 Build 350 03/24/2010 SP 2 SJ Web Edition +-- ************************************************************ + + +--Copyright (C) 1991-2010 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. + + +LIBRARY ieee; +USE ieee.std_logic_1164.all; + +LIBRARY altera_mf; +USE altera_mf.all; + +ENTITY lpm_fifoDZ IS + PORT + ( + aclr : IN STD_LOGIC ; + clock : IN STD_LOGIC ; + data : IN STD_LOGIC_VECTOR (127 DOWNTO 0); + rdreq : IN STD_LOGIC ; + wrreq : IN STD_LOGIC ; + q : OUT STD_LOGIC_VECTOR (127 DOWNTO 0) + ); +END lpm_fifoDZ; + + +ARCHITECTURE SYN OF lpm_fifodz IS + + SIGNAL sub_wire0 : STD_LOGIC_VECTOR (127 DOWNTO 0); + + + + COMPONENT scfifo + GENERIC ( + add_ram_output_register : STRING; + intended_device_family : STRING; + lpm_numwords : NATURAL; + lpm_showahead : STRING; + lpm_type : STRING; + lpm_width : NATURAL; + lpm_widthu : NATURAL; + overflow_checking : STRING; + underflow_checking : STRING; + use_eab : STRING + ); + PORT ( + rdreq : IN STD_LOGIC ; + aclr : IN STD_LOGIC ; + clock : IN STD_LOGIC ; + q : OUT STD_LOGIC_VECTOR (127 DOWNTO 0); + wrreq : IN STD_LOGIC ; + data : IN STD_LOGIC_VECTOR (127 DOWNTO 0) + ); + END COMPONENT; + +BEGIN + q <= sub_wire0(127 DOWNTO 0); + + scfifo_component : scfifo + GENERIC MAP ( + add_ram_output_register => "OFF", + intended_device_family => "Cyclone III", + lpm_numwords => 128, + lpm_showahead => "ON", + lpm_type => "scfifo", + lpm_width => 128, + lpm_widthu => 7, + overflow_checking => "OFF", + underflow_checking => "OFF", + use_eab => "ON" + ) + PORT MAP ( + rdreq => rdreq, + aclr => aclr, + clock => clock, + wrreq => wrreq, + data => data, + q => sub_wire0 + ); + + + +END SYN; + +-- ============================================================ +-- 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 "1" +-- Retrieval info: PRIVATE: Clock NUMERIC "0" +-- Retrieval info: PRIVATE: Depth NUMERIC "128" +-- Retrieval info: PRIVATE: Empty NUMERIC "0" +-- Retrieval info: PRIVATE: Full NUMERIC "0" +-- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone III" +-- 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 "1" +-- 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 "1" +-- Retrieval info: PRIVATE: UsedW NUMERIC "0" +-- Retrieval info: PRIVATE: Width NUMERIC "128" +-- Retrieval info: PRIVATE: dc_aclr NUMERIC "0" +-- Retrieval info: PRIVATE: diff_widths NUMERIC "0" +-- Retrieval info: PRIVATE: msb_usedw NUMERIC "0" +-- Retrieval info: PRIVATE: output_width NUMERIC "128" +-- Retrieval info: PRIVATE: rsEmpty NUMERIC "1" +-- Retrieval info: PRIVATE: rsFull NUMERIC "0" +-- Retrieval info: PRIVATE: rsUsedW NUMERIC "0" +-- Retrieval info: PRIVATE: sc_aclr NUMERIC "1" +-- Retrieval info: PRIVATE: sc_sclr NUMERIC "0" +-- Retrieval info: PRIVATE: wsEmpty NUMERIC "0" +-- Retrieval info: PRIVATE: wsFull NUMERIC "1" +-- Retrieval info: PRIVATE: wsUsedW NUMERIC "0" +-- Retrieval info: CONSTANT: ADD_RAM_OUTPUT_REGISTER STRING "OFF" +-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III" +-- Retrieval info: CONSTANT: LPM_NUMWORDS NUMERIC "128" +-- Retrieval info: CONSTANT: LPM_SHOWAHEAD STRING "ON" +-- Retrieval info: CONSTANT: LPM_TYPE STRING "scfifo" +-- Retrieval info: CONSTANT: LPM_WIDTH NUMERIC "128" +-- Retrieval info: CONSTANT: LPM_WIDTHU NUMERIC "7" +-- Retrieval info: CONSTANT: OVERFLOW_CHECKING STRING "OFF" +-- Retrieval info: CONSTANT: UNDERFLOW_CHECKING STRING "OFF" +-- Retrieval info: CONSTANT: USE_EAB STRING "ON" +-- Retrieval info: USED_PORT: aclr 0 0 0 0 INPUT NODEFVAL aclr +-- Retrieval info: USED_PORT: clock 0 0 0 0 INPUT NODEFVAL clock +-- Retrieval info: USED_PORT: data 0 0 128 0 INPUT NODEFVAL data[127..0] +-- Retrieval info: USED_PORT: q 0 0 128 0 OUTPUT NODEFVAL q[127..0] +-- Retrieval info: USED_PORT: rdreq 0 0 0 0 INPUT NODEFVAL rdreq +-- Retrieval info: USED_PORT: wrreq 0 0 0 0 INPUT NODEFVAL wrreq +-- Retrieval info: CONNECT: @data 0 0 128 0 data 0 0 128 0 +-- Retrieval info: CONNECT: q 0 0 128 0 @q 0 0 128 0 +-- Retrieval info: CONNECT: @wrreq 0 0 0 0 wrreq 0 0 0 0 +-- Retrieval info: CONNECT: @rdreq 0 0 0 0 rdreq 0 0 0 0 +-- Retrieval info: CONNECT: @clock 0 0 0 0 clock 0 0 0 0 +-- Retrieval info: CONNECT: @aclr 0 0 0 0 aclr 0 0 0 0 +-- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all +-- Retrieval info: GEN_FILE: TYPE_NORMAL lpm_fifoDZ.vhd TRUE +-- Retrieval info: GEN_FILE: TYPE_NORMAL lpm_fifoDZ.inc FALSE +-- Retrieval info: GEN_FILE: TYPE_NORMAL lpm_fifoDZ.cmp TRUE +-- Retrieval info: GEN_FILE: TYPE_NORMAL lpm_fifoDZ.bsf TRUE FALSE +-- Retrieval info: GEN_FILE: TYPE_NORMAL lpm_fifoDZ_inst.vhd FALSE +-- Retrieval info: GEN_FILE: TYPE_NORMAL lpm_fifoDZ_waveforms.html TRUE +-- Retrieval info: GEN_FILE: TYPE_NORMAL lpm_fifoDZ_wave*.jpg FALSE +-- Retrieval info: LIB_FILE: altera_mf diff --git a/vhdl/rtl/vhdl/Video/lpm_fifo_dc0.cmp b/vhdl/rtl/vhdl/Video/lpm_fifo_dc0.cmp new file mode 100644 index 0000000..08f6114 --- /dev/null +++ b/vhdl/rtl/vhdl/Video/lpm_fifo_dc0.cmp @@ -0,0 +1,29 @@ +--Copyright (C) 1991-2008 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. + + +component lpm_fifo_dc0 + PORT + ( + aclr : IN STD_LOGIC := '0'; + data : IN STD_LOGIC_VECTOR (127 DOWNTO 0); + rdclk : IN STD_LOGIC ; + rdreq : IN STD_LOGIC ; + wrclk : IN STD_LOGIC ; + wrreq : IN STD_LOGIC ; + q : OUT STD_LOGIC_VECTOR (127 DOWNTO 0); + rdempty : OUT STD_LOGIC ; + wrusedw : OUT STD_LOGIC_VECTOR (8 DOWNTO 0) + ); +end component; diff --git a/vhdl/rtl/vhdl/Video/lpm_fifo_dc0.qip b/vhdl/rtl/vhdl/Video/lpm_fifo_dc0.qip new file mode 100644 index 0000000..e883724 --- /dev/null +++ b/vhdl/rtl/vhdl/Video/lpm_fifo_dc0.qip @@ -0,0 +1,6 @@ +set_global_assignment -name IP_TOOL_NAME "LPM_FIFO+" +set_global_assignment -name IP_TOOL_VERSION "8.1" +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "lpm_fifo_dc0.vhd"] +set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "lpm_fifo_dc0.bsf"] +set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "lpm_fifo_dc0.inc"] +set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "lpm_fifo_dc0.cmp"] diff --git a/vhdl/rtl/vhdl/Video/lpm_fifo_dc0.vhd b/vhdl/rtl/vhdl/Video/lpm_fifo_dc0.vhd new file mode 100644 index 0000000..8646d9c --- /dev/null +++ b/vhdl/rtl/vhdl/Video/lpm_fifo_dc0.vhd @@ -0,0 +1,203 @@ +-- megafunction wizard: %LPM_FIFO+% +-- GENERATION: STANDARD +-- VERSION: WM1.0 +-- MODULE: dcfifo + +-- ============================================================ +-- File Name: lpm_fifo_dc0.vhd +-- Megafunction Name(s): +-- dcfifo +-- +-- Simulation Library Files(s): +-- altera_mf +-- ============================================================ +-- ************************************************************ +-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! +-- +-- 8.1 Build 163 10/28/2008 SJ Web Edition +-- ************************************************************ + + +--Copyright (C) 1991-2008 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. + + +LIBRARY ieee; +USE ieee.std_logic_1164.all; + +LIBRARY altera_mf; +USE altera_mf.all; + +ENTITY lpm_fifo_dc0 IS + PORT + ( + aclr : IN STD_LOGIC := '0'; + data : IN STD_LOGIC_VECTOR (127 DOWNTO 0); + rdclk : IN STD_LOGIC ; + rdreq : IN STD_LOGIC ; + wrclk : IN STD_LOGIC ; + wrreq : IN STD_LOGIC ; + q : OUT STD_LOGIC_VECTOR (127 DOWNTO 0); + rdempty : OUT STD_LOGIC ; + wrusedw : OUT STD_LOGIC_VECTOR (8 DOWNTO 0) + ); +END lpm_fifo_dc0; + + +ARCHITECTURE SYN OF lpm_fifo_dc0 IS + + SIGNAL sub_wire0 : STD_LOGIC ; + SIGNAL sub_wire1 : STD_LOGIC_VECTOR (8 DOWNTO 0); + SIGNAL sub_wire2 : STD_LOGIC_VECTOR (127 DOWNTO 0); + + + + COMPONENT dcfifo + GENERIC ( + intended_device_family : STRING; + lpm_numwords : NATURAL; + lpm_showahead : STRING; + lpm_type : STRING; + lpm_width : NATURAL; + lpm_widthu : NATURAL; + overflow_checking : STRING; + rdsync_delaypipe : NATURAL; + underflow_checking : STRING; + use_eab : STRING; + write_aclr_synch : STRING; + wrsync_delaypipe : NATURAL + ); + PORT ( + wrclk : IN STD_LOGIC ; + rdempty : OUT STD_LOGIC ; + rdreq : IN STD_LOGIC ; + wrusedw : OUT STD_LOGIC_VECTOR (8 DOWNTO 0); + aclr : IN STD_LOGIC ; + rdclk : IN STD_LOGIC ; + q : OUT STD_LOGIC_VECTOR (127 DOWNTO 0); + wrreq : IN STD_LOGIC ; + data : IN STD_LOGIC_VECTOR (127 DOWNTO 0) + ); + END COMPONENT; + +BEGIN + rdempty <= sub_wire0; + wrusedw <= sub_wire1(8 DOWNTO 0); + q <= sub_wire2(127 DOWNTO 0); + + dcfifo_component : dcfifo + GENERIC MAP ( + intended_device_family => "Cyclone III", + lpm_numwords => 512, + lpm_showahead => "OFF", + lpm_type => "dcfifo", + lpm_width => 128, + lpm_widthu => 9, + overflow_checking => "OFF", + rdsync_delaypipe => 6, + underflow_checking => "OFF", + use_eab => "ON", + write_aclr_synch => "ON", + wrsync_delaypipe => 6 + ) + PORT MAP ( + wrclk => wrclk, + rdreq => rdreq, + aclr => aclr, + rdclk => rdclk, + wrreq => wrreq, + data => data, + rdempty => sub_wire0, + wrusedw => sub_wire1, + q => sub_wire2 + ); + + + +END SYN; + +-- ============================================================ +-- 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 "512" +-- Retrieval info: PRIVATE: Empty NUMERIC "1" +-- Retrieval info: PRIVATE: Full NUMERIC "1" +-- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone III" +-- Retrieval info: PRIVATE: LE_BasedFIFO NUMERIC "0" +-- Retrieval info: PRIVATE: LegacyRREQ NUMERIC "1" +-- Retrieval info: PRIVATE: MAX_DEPTH_BY_9 NUMERIC "0" +-- Retrieval info: PRIVATE: OVERFLOW_CHECKING NUMERIC "1" +-- Retrieval info: PRIVATE: Optimize NUMERIC "1" +-- Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0" +-- Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0" +-- Retrieval info: PRIVATE: UNDERFLOW_CHECKING NUMERIC "1" +-- Retrieval info: PRIVATE: UsedW NUMERIC "1" +-- Retrieval info: PRIVATE: Width NUMERIC "128" +-- 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 "128" +-- 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 "0" +-- Retrieval info: PRIVATE: wsUsedW NUMERIC "1" +-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III" +-- Retrieval info: CONSTANT: LPM_NUMWORDS NUMERIC "512" +-- Retrieval info: CONSTANT: LPM_SHOWAHEAD STRING "OFF" +-- Retrieval info: CONSTANT: LPM_TYPE STRING "dcfifo" +-- Retrieval info: CONSTANT: LPM_WIDTH NUMERIC "128" +-- Retrieval info: CONSTANT: LPM_WIDTHU NUMERIC "9" +-- Retrieval info: CONSTANT: OVERFLOW_CHECKING STRING "OFF" +-- Retrieval info: CONSTANT: RDSYNC_DELAYPIPE NUMERIC "6" +-- Retrieval info: CONSTANT: UNDERFLOW_CHECKING STRING "OFF" +-- Retrieval info: CONSTANT: USE_EAB STRING "ON" +-- Retrieval info: CONSTANT: WRITE_ACLR_SYNCH STRING "ON" +-- Retrieval info: CONSTANT: WRSYNC_DELAYPIPE NUMERIC "6" +-- Retrieval info: USED_PORT: aclr 0 0 0 0 INPUT GND aclr +-- Retrieval info: USED_PORT: data 0 0 128 0 INPUT NODEFVAL data[127..0] +-- Retrieval info: USED_PORT: q 0 0 128 0 OUTPUT NODEFVAL q[127..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: wrreq 0 0 0 0 INPUT NODEFVAL wrreq +-- Retrieval info: USED_PORT: wrusedw 0 0 9 0 OUTPUT NODEFVAL wrusedw[8..0] +-- Retrieval info: CONNECT: @data 0 0 128 0 data 0 0 128 0 +-- Retrieval info: CONNECT: q 0 0 128 0 @q 0 0 128 0 +-- Retrieval info: CONNECT: @wrreq 0 0 0 0 wrreq 0 0 0 0 +-- Retrieval info: CONNECT: @rdreq 0 0 0 0 rdreq 0 0 0 0 +-- Retrieval info: CONNECT: @rdclk 0 0 0 0 rdclk 0 0 0 0 +-- Retrieval info: CONNECT: @wrclk 0 0 0 0 wrclk 0 0 0 0 +-- Retrieval info: CONNECT: rdempty 0 0 0 0 @rdempty 0 0 0 0 +-- Retrieval info: CONNECT: wrusedw 0 0 9 0 @wrusedw 0 0 9 0 +-- Retrieval info: CONNECT: @aclr 0 0 0 0 aclr 0 0 0 0 +-- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all +-- Retrieval info: GEN_FILE: TYPE_NORMAL lpm_fifo_dc0.vhd TRUE +-- Retrieval info: GEN_FILE: TYPE_NORMAL lpm_fifo_dc0.inc TRUE +-- Retrieval info: GEN_FILE: TYPE_NORMAL lpm_fifo_dc0.cmp TRUE +-- Retrieval info: GEN_FILE: TYPE_NORMAL lpm_fifo_dc0.bsf TRUE FALSE +-- Retrieval info: GEN_FILE: TYPE_NORMAL lpm_fifo_dc0_inst.vhd FALSE +-- Retrieval info: GEN_FILE: TYPE_NORMAL lpm_fifo_dc0_waveforms.html TRUE +-- Retrieval info: GEN_FILE: TYPE_NORMAL lpm_fifo_dc0_wave*.jpg FALSE +-- Retrieval info: LIB_FILE: altera_mf diff --git a/vhdl/rtl/vhdl/WF5380/wf5380_control.vhd b/vhdl/rtl/vhdl/WF5380/wf5380_control.vhd new file mode 100644 index 0000000..dff7458 --- /dev/null +++ b/vhdl/rtl/vhdl/WF5380/wf5380_control.vhd @@ -0,0 +1,614 @@ +---------------------------------------------------------------------- +---- ---- +---- WF5380 IP Core ---- +---- ---- +---- Description: ---- +---- This model provides an asynchronous SCSI interface compa- ---- +---- tible to the DP5380 from National Semiconductor and others. ---- +---- ---- +---- This file is the 5380's system controller. ---- +---- ---- +---- ---- +---- Author(s): ---- +---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright © 2009-2010 Wolfgang Foerster Inventronik GmbH. ---- +---- All rights reserved. No portion of this sourcecode may be ---- +---- reproduced or transmitted in any form by any means, whether ---- +---- by electronic, mechanical, photocopying, recording or ---- +---- otherwise, without my written permission. ---- +---- ---- +---------------------------------------------------------------------- +-- +-- Revision History +-- +-- Revision 2K9A 2009/06/20 WF +-- Initial Release. +-- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + +entity WF5380_CONTROL is + port ( + -- System controls: + CLK : in bit; + RESETn : in bit; -- System reset. + + -- System controls: + BSY_INn : in bit; -- SCSI BSY_INn bit. + BSY_OUTn : out bit; -- SCSI BSY_INn bit. + DATA_EN : out bit; -- Enable the SCSI data lines. + SEL_INn : in bit; -- SCSI SEL_INn bit. + ARB_EN : in bit; -- Arbitration enable. + BSY_DISn : in bit; -- BSY monitoring enable. + RSTn : in bit; -- SCSI reset. + + ARB : out bit; -- Arbitration flag. + AIP : out bit; -- Arbitration in progress flag. + LA : out bit; -- Lost arbitration flag. + + ACK_INn : in bit; + ACK_OUTn : out bit; + REQ_INn : in bit; + REQ_OUTn : out bit; + + DACKn : in bit; -- Data acknowledge. + READY : out bit; + DRQ : out bit; -- Data request. + + TARG : in bit; -- Target mode indicator. + BLK : in bit; -- Block mode indicator. + PINT_EN : in bit; -- Parity interrupt enable. + SPER : in bit; -- Parity error. + SER_ID : in bit; -- SER matches ODR bits. + RPI : in bit; -- Reset interrupts. + DMA_EN : in bit; -- DMA mode enable. + SDS : in bit; -- Start DMA send, write only. + SDT : in bit; -- Start DMA target receive, write only. + SDI : in bit; -- Start DMA initiator receive, write only. + EOP_EN : in bit; -- EOP interrupt enable. + EOPn : in bit; -- End of process indicator. + PHSM : in bit; -- Phase match flag. + + INT : out bit; -- Interrupt. + IDR_WR : out bit; -- Write input data register during DMA. + ODR_WR : out bit; -- Write output data register, during DMA. + CHK_PAR : out bit; -- Check Parity during DMA operation. + BSY_ERR : out bit; -- Busy monitoring error. + DMA_SND : out bit; -- Indicates direction of target DMA. + DMA_ACTIVE : out bit -- DMA is active. + ); +end entity WF5380_CONTROL; + +architecture BEHAVIOUR of WF5380_CONTROL is +type CTRL_STATES is (IDLE, WAIT_800ns, WAIT_2200ns, DMA_SEND, DMA_TARG_RCV, DMA_INIT_RCV); +type DMA_STATES is (IDLE, DMA_STEP_1, DMA_STEP_2, DMA_STEP_3, DMA_STEP_4); +signal CTRL_STATE : CTRL_STATES; +signal NEXT_CTRL_STATE : CTRL_STATES; +signal DMA_STATE : DMA_STATES; +signal NEXT_DMA_STATE : DMA_STATES; +signal BUS_FREE : bit; +signal DELAY_800ns : boolean; +signal DELAY_2200ns : boolean; +signal DMA_ACTIVE_I : bit; +signal EOP_In : bit; +begin + IN_BUFFER: process + -- This buffer shall prevent some signals against + -- setup hold effects and thus the state machine + -- against unpredictable behaviour. + begin + wait until CLK = '1' and CLK' event; + EOP_In <= EOPn; + end process IN_BUFFER; + + STATE_REGISTERS: process(RESETn, CLK) + -- This is the controller's state machine register. + variable BSY_LOCK : boolean; + begin + if RESETn = '0' then + CTRL_STATE <= IDLE; + DMA_STATE <= IDLE; + elsif CLK = '1' and CLK' event then + if RSTn = '0' then -- SCSI reset. + CTRL_STATE <= IDLE; + DMA_STATE <= IDLE; + else + CTRL_STATE <= NEXT_CTRL_STATE; + DMA_STATE <= NEXT_DMA_STATE; + end if; + -- + if DMA_EN = '0' then + DMA_STATE <= IDLE; + end if; + end if; + end process STATE_REGISTERS; + + CTRL_DECODER: process(CTRL_STATE, ARB_EN, BUS_FREE, DELAY_800ns, SEL_INn, DMA_ACTIVE_I, SDS, SDT, SDI) + -- This is the controller's state machine decoder. + variable BSY_LOCK : boolean; + begin + -- Defaults. + DMA_SND <= '0'; + -- + case CTRL_STATE is + when IDLE => + if ARB_EN = '1' and BUS_FREE = '1' then + NEXT_CTRL_STATE <= WAIT_800ns; + else + NEXT_CTRL_STATE <= IDLE; + end if; + when WAIT_800ns => + if DELAY_800ns = true then + NEXT_CTRL_STATE <= WAIT_2200ns; + else + NEXT_CTRL_STATE <= WAIT_800ns; + end if; + when WAIT_2200ns => + -- In this state the delay is provided by the + -- microprocessor and is at least 2.2us. The + -- delay is released by deasserting SELn. + if SEL_INn = '1' and SDS = '1' then + NEXT_CTRL_STATE <= DMA_SEND; + elsif SEL_INn = '1' and SDT = '1' then + NEXT_CTRL_STATE <= DMA_TARG_RCV; + elsif SEL_INn = '1' and SDI = '1' then + NEXT_CTRL_STATE <= DMA_INIT_RCV; + else + NEXT_CTRL_STATE <= WAIT_2200ns; + end if; + when DMA_SEND => + if DMA_ACTIVE_I = '0' then + NEXT_CTRL_STATE <= IDLE; + else + NEXT_CTRL_STATE <= DMA_SEND; + end if; + -- + DMA_SND <= '1'; + when DMA_TARG_RCV => + if DMA_ACTIVE_I = '0' then + NEXT_CTRL_STATE <= IDLE; + else + NEXT_CTRL_STATE <= DMA_TARG_RCV; + end if; + when DMA_INIT_RCV => + if DMA_ACTIVE_I = '0' then + NEXT_CTRL_STATE <= IDLE; + else + NEXT_CTRL_STATE <= DMA_INIT_RCV; + end if; + end case; + end process CTRL_DECODER; + + DMA_DECODER: process(CTRL_STATE, DMA_STATE, TARG, BLK, DACKn, REQ_INn, ACK_INn) + -- This is the DMA state machine decoder. + begin + -- Defaults: + IDR_WR <= '0'; + ODR_WR <= '0'; + CHK_PAR <= '0'; + -- + case DMA_STATE is + when IDLE => + if CTRL_STATE = DMA_SEND then + NEXT_DMA_STATE <= DMA_STEP_1; + elsif CTRL_STATE = DMA_INIT_RCV then + NEXT_DMA_STATE <= DMA_STEP_1; + elsif CTRL_STATE = DMA_TARG_RCV then + NEXT_DMA_STATE <= DMA_STEP_1; + else + NEXT_DMA_STATE <= IDLE; + end if; + when DMA_STEP_1 => + -- Initiator modes: + if CTRL_STATE = DMA_SEND and TARG = '0' and BLK = '0' and DACKn = '0' then + NEXT_DMA_STATE <= DMA_STEP_2; -- Wait for DACKn asserted. + ODR_WR <= '1'; + elsif CTRL_STATE = DMA_SEND and TARG = '0' and BLK = '1' and DACKn = '0' then + NEXT_DMA_STATE <= DMA_STEP_2; -- Wait for DACKn asserted. + ODR_WR <= '1'; + elsif CTRL_STATE = DMA_INIT_RCV and BLK = '0' and REQ_INn = '0' then + NEXT_DMA_STATE <= DMA_STEP_2; -- Wait for REQn asserted. + IDR_WR <= '1'; + elsif CTRL_STATE = DMA_INIT_RCV and BLK = '1' and REQ_INn = '0' then + NEXT_DMA_STATE <= DMA_STEP_2; -- Wait for REQn asserted. + IDR_WR <= '1'; + -- Target modes: + elsif CTRL_STATE = DMA_SEND and TARG = '1' and BLK = '0' and DACKn = '0' then + NEXT_DMA_STATE <= DMA_STEP_2; -- Wait for DACKn asserted. + ODR_WR <= '1'; + elsif CTRL_STATE = DMA_SEND and TARG = '0' and BLK = '1' and DACKn = '0' then + NEXT_DMA_STATE <= DMA_STEP_2; -- Wait for DACKn asserted. + ODR_WR <= '1'; + elsif CTRL_STATE = DMA_TARG_RCV and BLK = '0' and ACK_INn = '0' then + NEXT_DMA_STATE <= DMA_STEP_2; -- Wait for ACKn asserted. + IDR_WR <= '1'; + elsif CTRL_STATE = DMA_TARG_RCV and BLK = '1' and ACK_INn = '0' then + NEXT_DMA_STATE <= DMA_STEP_2; -- Wait for ACKn asserted. + IDR_WR <= '1'; + else + NEXT_DMA_STATE <= DMA_STEP_1; + end if; + when DMA_STEP_2 => + -- Initiator modes: + if CTRL_STATE = DMA_SEND and TARG = '0' and BLK = '0' and DACKn = '1' then + NEXT_DMA_STATE <= DMA_STEP_3; -- Wait for DACKn deasserted. + elsif CTRL_STATE = DMA_SEND and TARG = '0' and BLK = '1' and DACKn = '1' then + NEXT_DMA_STATE <= DMA_STEP_3; -- Wait for DACKn deasserted. + elsif CTRL_STATE = DMA_INIT_RCV and BLK = '0' and REQ_INn = '1' then + NEXT_DMA_STATE <= DMA_STEP_3; -- Wait for REQn deasserted. + elsif CTRL_STATE = DMA_INIT_RCV and BLK = '1' and REQ_INn = '1' then + NEXT_DMA_STATE <= DMA_STEP_3; -- Wait for REQn deasserted. + -- Target modes: + elsif CTRL_STATE = DMA_SEND and TARG = '1' and BLK = '0' and DACKn = '1' then + NEXT_DMA_STATE <= DMA_STEP_3; -- Wait for DACKn deasserted. + elsif CTRL_STATE = DMA_SEND and TARG = '0' and BLK = '1' and DACKn = '1' then + NEXT_DMA_STATE <= DMA_STEP_3; -- Wait for DACKn deasserted. + elsif CTRL_STATE = DMA_TARG_RCV and BLK = '0' and ACK_INn = '1' then + NEXT_DMA_STATE <= DMA_STEP_3; -- Wait for ACKn deasserted. + elsif CTRL_STATE = DMA_TARG_RCV and BLK = '1' and ACK_INn = '1' then + NEXT_DMA_STATE <= DMA_STEP_3; -- Wait for ACKn deasserted. + else + NEXT_DMA_STATE <= DMA_STEP_2; + end if; + when DMA_STEP_3 => + -- Initiator modes: + if CTRL_STATE = DMA_SEND and TARG = '0' and BLK = '0' and REQ_INn = '0' then + NEXT_DMA_STATE <= DMA_STEP_4; -- Wait REQn asserted. + elsif CTRL_STATE = DMA_SEND and TARG = '0' and BLK = '1' and REQ_INn = '0' then + NEXT_DMA_STATE <= DMA_STEP_4; -- Wait REQn asserted. + elsif CTRL_STATE = DMA_INIT_RCV and BLK = '0' and DACKn = '0' then + NEXT_DMA_STATE <= DMA_STEP_4; -- Wait DACKn asserted. + CHK_PAR <= '1'; + elsif CTRL_STATE = DMA_INIT_RCV and BLK = '1' and DACKn = '0' then + NEXT_DMA_STATE <= DMA_STEP_4; -- Wait DACKn asserted. + CHK_PAR <= '1'; + -- Target modes: + elsif CTRL_STATE = DMA_SEND and TARG = '1' and BLK = '0' and ACK_INn = '0' then + NEXT_DMA_STATE <= DMA_STEP_4; -- Wait ACKn asserted. + elsif CTRL_STATE = DMA_SEND and TARG = '1' and BLK = '1' and ACK_INn = '0' then + NEXT_DMA_STATE <= DMA_STEP_4; -- Wait ACKn asserted. + elsif CTRL_STATE = DMA_TARG_RCV and BLK = '0' and DACKn = '0' then + NEXT_DMA_STATE <= DMA_STEP_4; -- Wait DACKn asserted. + CHK_PAR <= '1'; + elsif CTRL_STATE = DMA_TARG_RCV and BLK = '1' and DACKn = '0' then + NEXT_DMA_STATE <= DMA_STEP_4; -- Wait DACKn asserted. + CHK_PAR <= '1'; + else + NEXT_DMA_STATE <= DMA_STEP_3; + end if; + when DMA_STEP_4 => + -- Initiator modes: + if CTRL_STATE = DMA_SEND and TARG = '0' and BLK = '0' and REQ_INn = '1' then + NEXT_DMA_STATE <= DMA_STEP_1; -- Wait REQn deasserted. + elsif CTRL_STATE = DMA_SEND and TARG = '0' and BLK = '1' and REQ_INn = '1' then + NEXT_DMA_STATE <= DMA_STEP_1; -- Wait REQn deasserted. + elsif CTRL_STATE = DMA_INIT_RCV and BLK = '0' and DACKn = '1' then + NEXT_DMA_STATE <= DMA_STEP_1; -- Wait DACKn deasserted. + elsif CTRL_STATE = DMA_INIT_RCV and BLK = '1' and DACKn = '1' then + NEXT_DMA_STATE <= DMA_STEP_1; -- Wait DACKn deasserted. + -- Target modes: + elsif CTRL_STATE = DMA_SEND and TARG = '1' and BLK = '0' and ACK_INn = '1' then + NEXT_DMA_STATE <= DMA_STEP_1; -- Wait ACKn deasserted. + elsif CTRL_STATE = DMA_SEND and TARG = '1' and BLK = '1' and ACK_INn = '1' then + NEXT_DMA_STATE <= DMA_STEP_1; -- Wait ACKn deasserted. + elsif CTRL_STATE = DMA_TARG_RCV and BLK = '0' and DACKn = '1' then + NEXT_DMA_STATE <= DMA_STEP_1; -- Wait DACKn deasserted. + elsif CTRL_STATE = DMA_TARG_RCV and BLK = '1' and DACKn = '1' then + NEXT_DMA_STATE <= DMA_STEP_1; -- Wait DACKn deasserted. + else + NEXT_DMA_STATE <= DMA_STEP_4; + end if; + end case; + end process DMA_DECODER; + + P_REQn: process(DMA_STATE, CTRL_STATE, TARG, BLK) + -- This logic controls the REQn output in target mode. + begin + if DMA_STATE = DMA_STEP_1 and CTRL_STATE = DMA_TARG_RCV and BLK = '0' then + REQ_OUTn <= '0'; + elsif DMA_STATE = DMA_STEP_1 and CTRL_STATE = DMA_TARG_RCV and BLK = '1' then + REQ_OUTn <= '0'; + elsif DMA_STATE = DMA_STEP_3 and CTRL_STATE = DMA_SEND and TARG = '1' and BLK = '0' then + REQ_OUTn <= '0'; + elsif DMA_STATE = DMA_STEP_3 and CTRL_STATE = DMA_SEND and TARG = '1' and BLK = '1' then + REQ_OUTn <= '0'; + else + REQ_OUTn <= '1'; + end if; + end process P_REQn; + + P_ACKn: process(DMA_STATE, CTRL_STATE, TARG, BLK) + -- This logic controls the ACKn output in initiator mode. + begin + if DMA_STATE = DMA_STEP_2 and CTRL_STATE = DMA_INIT_RCV and BLK = '0' then + ACK_OUTn <= '0'; + elsif DMA_STATE = DMA_STEP_2 and CTRL_STATE = DMA_INIT_RCV and BLK = '1' then + ACK_OUTn <= '0'; + elsif DMA_STATE = DMA_STEP_4 and CTRL_STATE = DMA_SEND and TARG = '0' and BLK = '0' then + ACK_OUTn <= '0'; + elsif DMA_STATE = DMA_STEP_4 and CTRL_STATE = DMA_SEND and TARG = '0' and BLK = '1' then + ACK_OUTn <= '0'; + else + ACK_OUTn <= '1'; + end if; + end process P_ACKn; + + P_READY: process(DMA_STATE, CTRL_STATE, TARG, BLK) + -- This logic controls the READY output in initiator and target block mode. + begin + if DMA_STATE = DMA_STEP_1 and CTRL_STATE = DMA_SEND and TARG = '1' and BLK = '1' then + READY <= '1'; + elsif DMA_STATE = DMA_STEP_1 and CTRL_STATE = DMA_TARG_RCV and BLK = '1' then + READY <= '1'; + elsif DMA_STATE = DMA_STEP_3 and CTRL_STATE = DMA_SEND and TARG = '0' and BLK = '1' then + READY <= '1'; + elsif DMA_STATE = DMA_STEP_3 and CTRL_STATE = DMA_INIT_RCV and BLK = '1' then + READY <= '1'; + else + READY <= '0'; + end if; + end process P_READY; + + P_DRQ: process(RESETn, CLK) + -- This flip flop controls the DRQ flag during all initiator and all target modes + -- for both block mode and non block mode operation. + variable LOCK : boolean; + begin + if RESETn = '0' then + DRQ <= '0'; + LOCK := false; + elsif CLK = '1' and CLK' event then + -- Initiator modes: + if DMA_STATE = DMA_STEP_1 and CTRL_STATE = DMA_SEND and TARG = '0' and BLK = '0' then + DRQ <= '1'; + elsif DMA_STATE = DMA_STEP_1 and CTRL_STATE = DMA_SEND and TARG = '0' and BLK = '1' and LOCK = false then + DRQ <= '1'; + LOCK := true; + elsif DMA_STATE = DMA_STEP_3 and CTRL_STATE = DMA_INIT_RCV and BLK = '0' then + DRQ <= '1'; + elsif DMA_STATE = DMA_STEP_3 and CTRL_STATE = DMA_INIT_RCV and BLK = '1' then + DRQ <= '1'; + LOCK := true; + -- Target modes: + elsif DMA_STATE = DMA_STEP_3 and CTRL_STATE = DMA_SEND and TARG = '1' and BLK = '0' then + DRQ <= '1'; + elsif DMA_STATE = DMA_STEP_3 and CTRL_STATE = DMA_SEND and TARG = '1' and BLK = '1' then + DRQ <= '1'; + LOCK := true; + elsif DMA_STATE = DMA_STEP_1 and CTRL_STATE = DMA_TARG_RCV and BLK = '0' then + DRQ <= '1'; + elsif DMA_STATE = DMA_STEP_1 and CTRL_STATE = DMA_TARG_RCV and BLK = '1' then + DRQ <= '1'; + LOCK := true; + elsif DACKn = '0' and LOCK = false then + DRQ <= '0'; + elsif EOPn = '0' and DACKn = '0' then + DRQ <= '0'; + LOCK := false; + end if; + end if; + end process P_DRQ; + + P_BUSFREE: process(RESETn, CLK) + -- This is the logic for the bus free signal. + -- A bus free is valid if the BSY_INn signal is + -- at least 437.5ns inactive ans SEL_INn is inactive. + -- The delay are 7 clock cycles of 16MHz. + variable TMP : std_logic_vector(2 downto 0); + begin + if RESETn = '0' then + BUS_FREE <= '0'; + TMP := "000"; + elsif CLK = '1' and CLK' event then + if BSY_INn = '1' and TMP < x"111" then + TMP := TMP + '1'; + elsif BSY_INn = '0' then + TMP := "000"; + end if; + -- + if RSTn = '0' then -- SCSI reset. + BUS_FREE <= '0'; + elsif SEL_INn = '1' and TMP = "111" then + BUS_FREE <= '1'; + else + BUS_FREE <= '0'; + end if; + end if; + end process P_BUSFREE; + + DELAY_800: process(RESETn, CLK) + -- This is the delay of 812.5ns. + -- It is derived from 13 16MHz clock cycles. + variable TMP : std_logic_vector(3 downto 0); + begin + if RESETn = '0' then + DELAY_800ns <= false; + TMP := x"0"; + elsif CLK = '1' and CLK' event then + if CTRL_STATE /= WAIT_800ns then + TMP := x"0"; + elsif TMP <= x"D" then + TMP := TMP + '1'; + end if; + -- + if TMP = x"D" then + DELAY_800ns <= true; + else + DELAY_800ns <= false; + end if; + end if; + end process DELAY_800; + + P_ARB: process(RESETn, CLK) + -- This flip flop controls the ARB flag read back + -- by the microcontroller. + begin + if RESETn = '0' then + ARB <= '0'; + elsif CLK = '1' and CLK' event then + if CTRL_STATE /= WAIT_800ns and NEXT_CTRL_STATE = WAIT_800ns then + ARB <= '1'; + elsif ARB_EN = '0' then + ARB <= '0'; + end if; + end if; + end process P_ARB; + + P_AIP: process(RESETn, CLK) + -- This flip flop controls the AIP flag read back + -- by the microcontroller. + begin + if RESETn = '0' then + AIP <= '0'; + elsif CLK = '1' and CLK' event then + if CTRL_STATE = WAIT_800ns and NEXT_CTRL_STATE /= WAIT_800ns then + AIP <= '1'; + elsif ARB_EN = '0' then + AIP <= '0'; + end if; + end if; + end process P_AIP; + + P_BSY: process + -- This flip flop controls the BSYn output + -- to the SCSI bus. + begin + wait until CLK = '1' and CLK' event; + if RESETn = '0' then + BSY_OUTn <= '1'; + elsif CTRL_STATE = WAIT_800ns and NEXT_CTRL_STATE /= WAIT_800ns then + BSY_OUTn <= '0'; + elsif ARB_EN = '0' then + BSY_OUTn <= '1'; + end if; + end process P_BSY; + + P_DATA_EN: process(RESETn, CLK) + -- This flip flop controls the data enable + -- of the SCSI bus. + begin + if RESETn = '0' then + DATA_EN <= '0'; + elsif CLK = '1' and CLK' event then + if CTRL_STATE = WAIT_800ns and NEXT_CTRL_STATE /= WAIT_800ns then + DATA_EN <= '1'; + elsif ARB_EN = '0' then + DATA_EN <= '0'; + end if; + end if; + end process P_DATA_EN; + + P_LA: process(RESETn, CLK) + -- This flip flop controls the LA + -- (lost arbitration) flag. + begin + if RESETn = '0' then + LA <= '0'; + elsif CLK = '1' and CLK' event then + if (CTRL_STATE = WAIT_800ns or CTRL_STATE = WAIT_2200ns) and SEL_INn = '0' then + LA <= '1'; + elsif ARB_EN = '0' then + LA <= '0'; + end if; + end if; + end process P_LA; + + P_DMA_ACTIVE: process(RESETn, CLK, DMA_ACTIVE_I) + -- This is the Flip Flop indicating if there is DMA + -- operation. + begin + if RESETn = '0' then + DMA_ACTIVE_I <= '0'; + elsif CLK = '1' and CLK' event then + if DMA_EN = '1' and SDS = '1' then + DMA_ACTIVE_I <= '1'; -- Start DMA send. + elsif DMA_EN = '1' and SDT = '1' then + DMA_ACTIVE_I <= '1'; -- Start DMA target receive. + elsif DMA_EN = '1' and SDI = '1' then + DMA_ACTIVE_I <= '1'; -- Start DMA initiator receive. + elsif DMA_EN = '0' then + DMA_ACTIVE_I <= '0'; -- Halt DMA via DMA flag in MR2. + elsif EOP_In = '0' then + DMA_ACTIVE_I <= '0'; -- Halt DMA via EOPn. + elsif PHSM = '0' then + DMA_ACTIVE_I <= '0'; -- Halt DMA via phase mismatch. + end if; + end if; + -- + DMA_ACTIVE <= DMA_ACTIVE_I; + end process P_DMA_ACTIVE; + + INTERRUPTS: process(RESETn, CLK) + -- This is the logic for all DP5380's interrupt sources. + -- A busy interrupt occurs if the BSY_INn signal is at + -- least 437.5ns inactive. The delay are 7 clock cycles + -- of 16MHz. This logic also provides the respective + -- error flags for the BSR. + variable TMP : std_logic_vector(2 downto 0); + begin + if RESETn = '0' then + INT <= '0'; + BSY_ERR <= '0'; + TMP := "000"; + elsif CLK = '1' and CLK' event then + if SPER = '1' and PINT_EN = '1' then + INT <= '1'; -- Parity interrupt. + elsif RPI = '0' then -- Reset interrupts. + INT <= '0'; + end if; + -- + if EOP_In = '0' and CTRL_STATE = DMA_SEND then + BSY_ERR <= '1'; -- End of DMA error. + elsif EOP_In = '0' and CTRL_STATE = DMA_TARG_RCV then + BSY_ERR <= '1'; -- End of DMA error. + elsif EOP_In = '0' and CTRL_STATE = DMA_INIT_RCV then + BSY_ERR <= '1'; -- End of DMA error. + elsif DMA_EN = '0' then -- Reset error. + INT <= '0'; + end if; + -- + if EOP_EN = '1' and EOP_In = '0' and CTRL_STATE = DMA_SEND then + INT <= '1'; -- End of DMA interrupt. + elsif EOP_EN = '1' and EOP_In = '0' and CTRL_STATE = DMA_TARG_RCV then + INT <= '1'; -- End of DMA interrupt. + elsif EOP_EN = '1' and EOP_In = '0' and CTRL_STATE = DMA_INIT_RCV then + INT <= '1'; -- End of DMA interrupt. + elsif DMA_EN = '0' then -- Reset interrupt. + INT <= '0'; + end if; + + -- + if PHSM = '0' then + INT <= '1'; -- Phase mismatch interrupt. + elsif DMA_EN = '0' then -- Reset interrupts. + INT <= '0'; + end if; + -- + if SEL_INn = '0' and BSY_INn = '1' and SER_ID = '1' then + INT <= '1'; -- (Re)Selection interrupt. + elsif RPI = '1' then -- Reset interrupts. + INT <= '0'; + end if; + -- + if BSY_INn = '1' and TMP < x"111" then + TMP := TMP + '1'; -- Bus settle delay. + elsif BSY_INn = '0' then + TMP := "000"; + end if; + -- + if BSY_DISn = '1' and BSY_INn = '1' and TMP = x"111" then + INT <= '1'; -- Busy monitoring interrupt. + BSY_ERR <= '1'; + elsif RPI = '1' then -- Reset interrupts. + INT <= '0'; + BSY_ERR <= '0'; + end if; + -- + end if; + end process INTERRUPTS; +end BEHAVIOUR; \ No newline at end of file diff --git a/vhdl/rtl/vhdl/WF5380/wf5380_pkg.vhd b/vhdl/rtl/vhdl/WF5380/wf5380_pkg.vhd new file mode 100644 index 0000000..7b37801 --- /dev/null +++ b/vhdl/rtl/vhdl/WF5380/wf5380_pkg.vhd @@ -0,0 +1,122 @@ +---------------------------------------------------------------------- +---- ---- +---- WF5380 IP Core ---- +---- ---- +---- Description: ---- +---- This model provides an asynchronous SCSI interface compa- ---- +---- tible to the DP5380 from National Semiconductor and others. ---- +---- ---- +---- This file is the package file of the ip core. ---- +---- ---- +---- ---- +---- ---- +---- ---- +---- Author(s): ---- +---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright © 2009-2010 Wolfgang Foerster Inventronik GmbH. ---- +---- All rights reserved. No portion of this sourcecode may be ---- +---- reproduced or transmitted in any form by any means, whether ---- +---- by electronic, mechanical, photocopying, recording or ---- +---- otherwise, without my written permission. ---- +---- ---- +---------------------------------------------------------------------- +-- +-- Revision History +-- +-- Revision 2K9A 2009/06/20 WF +-- Initial Release. + +library ieee; +use ieee.std_logic_1164.all; + +package WF5380_PKG is + component WF5380_REGISTERS + port ( + CLK : in bit; + RESETn : in bit; + ADR : in bit_vector(2 downto 0); + DATA_IN : in bit_vector(7 downto 0); + DATA_OUT : out bit_vector(7 downto 0); + DATA_EN : out bit; + CSn : in bit; + RDn : in bit; + WRn : in bit; + RSTn : in bit; + RST : out bit; + ARB_EN : out bit; + DMA_ACTIVE : in bit; + DMA_EN : out bit; + BSY_DISn : out bit; + EOP_EN : out bit; + PINT_EN : out bit; + SPER : out bit; + TARG : out bit; + BLK : out bit; + DMA_DIS : in bit; + IDR_WR : in bit; + ODR_WR : in bit; + CHK_PAR : in bit; + AIP : in bit; + ARB : in bit; + LA : in bit; + CSD : in bit_vector(7 downto 0); + CSB : in bit_vector(7 downto 0); + BSR : in bit_vector(7 downto 0); + ODR_OUT : out bit_vector(7 downto 0); + ICR_OUT : out bit_vector(7 downto 0); + TCR_OUT : out bit_vector(3 downto 0); + SER_OUT : out bit_vector(7 downto 0); + SDS : out bit; + SDT : out bit; + SDI : out bit; + RPI : out bit + ); + end component; + + component WF5380_CONTROL + port ( + CLK : in bit; + RESETn : in bit; + BSY_INn : in bit; + BSY_OUTn : out bit; + DATA_EN : out bit; + SEL_INn : in bit; + ARB_EN : in bit; + BSY_DISn : in bit; + RSTn : in bit; + ARB : out bit; + AIP : out bit; + LA : out bit; + ACK_INn : in bit; + ACK_OUTn : out bit; + REQ_INn : in bit; + REQ_OUTn : out bit; + DACKn : in bit; + READY : out bit; + DRQ : out bit; + TARG : in bit; + BLK : in bit; + PINT_EN : in bit; + SPER : in bit; + SER_ID : in bit; + RPI : in bit; + DMA_EN : in bit; + SDS : in bit; + SDT : in bit; + SDI : in bit; + EOP_EN : in bit; + EOPn : in bit; + PHSM : in bit; + INT : out bit; + IDR_WR : out bit; + ODR_WR : out bit; + CHK_PAR : out bit; + BSY_ERR : out bit; + DMA_SND : out bit; + DMA_ACTIVE : out bit + ); + end component; +end WF5380_PKG; diff --git a/vhdl/rtl/vhdl/WF5380/wf5380_registers.vhd b/vhdl/rtl/vhdl/WF5380/wf5380_registers.vhd new file mode 100644 index 0000000..2e3266b --- /dev/null +++ b/vhdl/rtl/vhdl/WF5380/wf5380_registers.vhd @@ -0,0 +1,248 @@ +---------------------------------------------------------------------- +---- ---- +---- WF5380 IP Core ---- +---- ---- +---- Description: ---- +---- This model provides an asynchronous SCSI interface compa- ---- +---- tible to the DP5380 from National Semiconductor and others. ---- +---- ---- +---- This file is the 5380's register model. ---- +---- ---- +---- ---- +---- Author(s): ---- +---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Register description (for more information see the DP5380 ---- +---- data sheet: ---- +---- ODR (address 0) Output data register, write only. ---- +---- CSD (address 0) Current SCSI data, read only. ---- +---- ICR (address 1) Initiator command register, read/write. ---- +---- MR2 (address 2) Mode register 2, read/write. ---- +---- TCR (address 3) Target command register, read/write. ---- +---- SER (address 4) Select enable register, write only. ---- +---- CSB (address 4) Current SCSI bus status, read only. ---- +---- BSR (address 5) Start DMA send, write only. ---- +---- SDS (address 5) Bus and status, read only. ---- +---- SDT (address 6) Start DMA target receive, write only. ---- +---- IDR (address 6) Input data register, read only. ---- +---- SDI (address 7) Start DMA initiator recive, write only. ---- +---- RPI (address 7) Reset parity / interrupts, read only. ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright © 2009-2010 Wolfgang Foerster Inventronik GmbH. ---- +---- All rights reserved. No portion of this sourcecode may be ---- +---- reproduced or transmitted in any form by any means, whether ---- +---- by electronic, mechanical, photocopying, recording or ---- +---- otherwise, without my written permission. ---- +---- ---- +---------------------------------------------------------------------- +-- +-- Revision History +-- +-- Revision 2K9A 2009/06/20 WF +-- Initial Release. +-- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + +entity WF5380_REGISTERS is + port ( + -- System controls: + CLK : in bit; + RESETn : in bit; -- System reset. + + -- Address and data: + ADR : in bit_vector(2 downto 0); + DATA_IN : in bit_vector(7 downto 0); + DATA_OUT : out bit_vector(7 downto 0); + DATA_EN : out bit; + + -- Bus and DMA controls: + CSn : in bit; + RDn : in bit; + WRn : in bit; + + -- Core controls: + RSTn : in bit; -- SCSI reset. + RST : out bit; -- Programmed SCSI reset. + ARB_EN : out bit; -- Arbitration enable. + DMA_ACTIVE : in bit; -- DMA is running. + DMA_EN : out bit; -- DMA mode enable. + BSY_DISn : out bit; -- BSY monitoring enable. + EOP_EN : out bit; -- EOP interrupt enable. + PINT_EN : out bit; -- Parity interrupt enable. + SPER : out bit; -- Parity error. + TARG : out bit; -- Target mode. + BLK : out bit; -- Block DMA mode. + DMA_DIS : in bit; -- Reset the DMA_EN by this signal. + IDR_WR : in bit; -- Write input data register during DMA. + ODR_WR : in bit; -- Write output data register, during DMA. + CHK_PAR : in bit; -- Check Parity during DMA operation. + AIP : in bit; -- Arbitration in progress. + ARB : in bit; -- Arbitration. + LA : in bit; -- Lost arbitration. + + CSD : in bit_vector(7 downto 0); -- SCSI data. + CSB : in bit_vector(7 downto 0); -- Current SCSI bus status. + BSR : in bit_vector(7 downto 0); -- Bus and status. + + ODR_OUT : out bit_vector(7 downto 0); -- This is the ODR register. + ICR_OUT : out bit_vector(7 downto 0); -- This is the ICR register. + TCR_OUT : out bit_vector(3 downto 0); -- This is the TCR register. + SER_OUT : out bit_vector(7 downto 0); -- This is the SER register. + + SDS : out bit; -- Start DMA send, write only. + SDT : out bit; -- Start DMA target receive, write only. + SDI : out bit; -- Start DMA initiator receive, write only. + RPI : out bit + ); +end entity WF5380_REGISTERS; + +architecture BEHAVIOUR of WF5380_REGISTERS is +signal ICR : bit_vector(7 downto 0); -- Initiator command register, read/write. +signal IDR : bit_vector(7 downto 0); -- Input data register. +signal MR2 : bit_vector(7 downto 0); -- Mode register 2, read/write. +signal ODR : bit_vector(7 downto 0); -- Output data register, write only. +signal SER : bit_vector(7 downto 0); -- Select enable register, write only. +signal TCR : bit_vector(3 downto 0); -- Target command register, read/write. +begin + REGISTERS: process(RESETn, CLK) + -- This process reflects all registers in the 5380. + variable BSY_LOCK : boolean; + begin + if RESETn = '0' then + ODR <= (others => '0'); + ICR <= (others => '0'); + MR2 <= (others => '0'); + TCR <= (others => '0'); + SER <= (others => '0'); + BSY_LOCK := false; + elsif CLK = '1' and CLK' event then + if RSTn = '0' then -- SCSI reset. + ODR <= (others => '0'); + ICR(6 downto 0) <= (others => '0'); + MR2(7) <= '0'; + MR2(5 downto 0) <= (others => '0'); + TCR <= (others => '0'); + SER <= (others => '0'); + BSY_LOCK := false; + elsif ADR = "000" and CSn = '0' and WRn = '0' then + ODR <= DATA_IN; + elsif ADR = "001" and CSn = '0' and WRn = '0' then + ICR <= DATA_IN; + elsif ADR = "010" and CSn = '0' and WRn = '0' then + MR2 <= DATA_IN; + elsif ADR = "011" and CSn = '0' and WRn = '0' then + TCR <= DATA_IN(3 downto 0); + elsif ADR = "100" and CSn = '0' and WRn = '0' then + SER <= DATA_IN; + end if; + -- + if ODR_WR = '1' then + ODR <= DATA_IN; + end if; + -- + -- This reset function is edge triggered on the 'Monitor Busy' + -- MR2(2). + if MR2(2) = '1' and BSY_LOCK = false then + ICR(5 downto 0) <= "000000"; + BSY_LOCK := true; + elsif MR2(2) = '0' then + BSY_LOCK := false; + end if; + -- + if DMA_DIS = '1' then + MR2(1) <= '0'; + end if; + end if; + end process REGISTERS; + + IDR_REGISTER: process(RESETn, CLK) + begin + if RESETn = '0' then + IDR <= x"00"; + elsif CLK = '1' and CLK' event then + if RSTn = '0' or ICR(7) = '1' then + IDR <= x"00"; -- SCSI reset. + elsif IDR_WR = '1' then + IDR <= CSD; + end if; + end if; + end process IDR_REGISTER; + + PARITY: process(RESETn, CLK) + -- This is the parity generating logic with it's related + -- error generation. + variable PAR_VAR : bit; + variable LOCK : boolean; + begin + if RESETn = '0' then + SPER <= '0'; + LOCK := false; + elsif CLK = '1' and CLK' event then + -- Parity checked during 'Read from CSD' + -- (registered I/O and selection/reselection): + if ADR = "000" and CSn = '0' and RDn = '0' and LOCK = false then + for i in 1 to 7 loop + PAR_VAR := CSD(i) xor CSD(i-1); + end loop; + SPER <= not PAR_VAR; + LOCK := true; + end if; + -- + -- Parity checking during DMA operation: + if DMA_ACTIVE = '1' and CHK_PAR = '1' then + for i in 1 to 7 loop + PAR_VAR := IDR(i) xor IDR(i-1); + end loop; + SPER <= not PAR_VAR; + LOCK := true; + end if; + -- + -- Reset parity flag: + if MR2(5) <= '0' then -- MR2(5) = PCHK (disabled). + SPER <= '0'; + elsif ADR = "111" and CSn = '0' and RDn = '0' then -- Reset parity/interrupts. + SPER <= '0'; + LOCK := false; + end if; + end if; + end process PARITY; + + DATA_EN <= '1' when ADR < "101" and CSn = '0' and WRn = '0' else '0'; + + SDS <= '1' when ADR = "101" and CSn = '0' and WRn = '0' else '0'; + SDT <= '1' when ADR = "110" and CSn = '0' and WRn = '0' else '0'; + SDI <= '1' when ADR = "111" and CSn = '0' and WRn = '0' else '0'; + + ICR_OUT <= ICR; + TCR_OUT <= TCR; + SER_OUT <= SER; + ODR_OUT <= ODR; + + ARB_EN <= MR2(0); + DMA_EN <= MR2(1); + BSY_DISn <= MR2(2); + EOP_EN <= MR2(3); + PINT_EN <= MR2(4); + TARG <= MR2(6); + BLK <= MR2(7); + + RST <= ICR(7); + + -- Readback, unused bit positions are read back zero. + DATA_OUT <= CSD when ADR = "000" and CSn = '0' and RDn = '0' else -- Current SCSI data. + ICR(7) & AIP & LA & ICR(4 downto 0) when ADR = "001" and CSn = '0' and RDn = '0' else + MR2 when ADR = "010" and CSn = '0' and RDn = '0' else + x"0" & TCR when ADR = "011" and CSn = '0' and RDn = '0' else + CSB when ADR = "100" and CSn = '0' and RDn = '0' else -- Current SCSI bus status. + BSR when ADR = "101" and CSn = '0' and RDn = '0' else -- Bus and status. + IDR when ADR = "110" and CSn = '0' and RDn = '0' else x"00"; -- Input data register. + + RPI <= '1' when ADR = "111" and CSn = '0' and RDn = '0' else '0'; -- Reset parity/interrupts. +end BEHAVIOUR; \ No newline at end of file diff --git a/vhdl/rtl/vhdl/WF5380/wf5380_soc_top.vhd b/vhdl/rtl/vhdl/WF5380/wf5380_soc_top.vhd new file mode 100644 index 0000000..da8cd81 --- /dev/null +++ b/vhdl/rtl/vhdl/WF5380/wf5380_soc_top.vhd @@ -0,0 +1,283 @@ +---------------------------------------------------------------------- +---- ---- +---- WF5380 IP Core ---- +---- ---- +---- Description: ---- +---- This model provides an asynchronous SCSI interface compa- ---- +---- tible to the DP5380 from National Semiconductor and others. ---- +---- ---- +---- Some remarks to the required input clock: ---- +---- This core is provided for a 16MHz input clock. To use other ---- +---- frequencies, it is necessary to modify the following proces- ---- +---- ses in the control file section: ---- +---- P_BUSFREE, DELAY_800, INTERRUPTS. ---- +---- ---- +---- This file is the top level file without tree state buses for ---- +---- use in 'systems on chip' designs. ---- +---- ---- +---- ---- +---- Author(s): ---- +---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright © 2009-2010 Wolfgang Foerster Inventronik GmbH. ---- +---- All rights reserved. No portion of this sourcecode may be ---- +---- reproduced or transmitted in any form by any means, whether ---- +---- by electronic, mechanical, photocopying, recording or ---- +---- otherwise, without my written permission. ---- +---- ---- +---------------------------------------------------------------------- +-- +-- Revision History +-- +-- Revision 2K9A 2009/06/20 WF +-- Initial Release. +-- + +library work; +use work.wf5380_pkg.all; + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + +entity WF5380_TOP_SOC is + port ( + -- System controls: + CLK : in bit; -- Use a 16MHz Clock. + RESETn : in bit; + + -- Address and data: + ADR : in bit_vector(2 downto 0); + DATA_IN : in bit_vector(7 downto 0); + DATA_OUT : out bit_vector(7 downto 0); + DATA_EN : out bit; + + -- Bus and DMA controls: + CSn : in bit; + RDn : in bit; + WRn : in bit; + EOPn : in bit; + DACKn : in bit; + DRQ : out bit; + INT : out bit; + READY : out bit; + + -- SCSI bus: + DB_INn : in bit_vector(7 downto 0); + DB_OUTn : out bit_vector(7 downto 0); + DB_EN : out bit; + DBP_INn : in bit; + DBP_OUTn : out bit; + DBP_EN : out bit; + RST_INn : in bit; + RST_OUTn : out bit; + RST_EN : out bit; + BSY_INn : in bit; + BSY_OUTn : out bit; + BSY_EN : out bit; + SEL_INn : in bit; + SEL_OUTn : out bit; + SEL_EN : out bit; + ACK_INn : in bit; + ACK_OUTn : out bit; + ACK_EN : out bit; + ATN_INn : in bit; + ATN_OUTn : out bit; + ATN_EN : out bit; + REQ_INn : in bit; + REQ_OUTn : out bit; + REQ_EN : out bit; + IOn_IN : in bit; + IOn_OUT : out bit; + IO_EN : out bit; + CDn_IN : in bit; + CDn_OUT : out bit; + CD_EN : out bit; + MSG_INn : in bit; + MSG_OUTn : out bit; + MSG_EN : out bit + ); +end entity WF5380_TOP_SOC; + +architecture STRUCTURE of WF5380_TOP_SOC is +signal ACK_OUT_CTRLn : bit; +signal AIP : bit; +signal ARB : bit; +signal ARB_EN : bit; +signal BLK : bit; +signal BSR : bit_vector(7 downto 0); +signal BSY_DISn : bit; +signal BSY_ERR : bit; +signal BSY_OUT_CTRLn : bit; +signal CHK_PAR : bit; +signal CSD : bit_vector(7 downto 0); +signal CSB : bit_vector(7 downto 0); +signal DATA_EN_CTRL : bit; +signal DB_EN_I : bit; +signal DMA_ACTIVE : bit; +signal DMA_EN : bit; +signal DMA_DIS : bit; +signal DMA_SND : bit; +signal DRQ_I : bit; +signal EDMA : bit; +signal EOP_EN : bit; +signal ICR : bit_vector(7 downto 0); +signal IDR_WR : bit; +signal INT_I : bit; +signal LA : bit; +signal ODR : bit_vector(7 downto 0); +signal ODR_WR : bit; +signal PCHK : bit; +signal PHSM : bit; +signal PINT_EN : bit; +signal REQ_OUT_CTRLn : bit; +signal RPI : bit; +signal RST : bit; +signal SDI : bit; +signal SDS : bit; +signal SDT : bit; +signal SER : bit_vector(7 downto 0); +signal SER_ID : bit; +signal SPER : bit; +signal TARG : bit; +signal TCR : bit_vector(3 downto 0); +begin + EDMA <= '1' when EOPn = '0' and DACKn = '0' and RDn = '0' else + '1' when EOPn = '0' and DACKn = '0' and WRn = '0' else '0'; + + PHSM <= '1' when DMA_ACTIVE = '0' else -- Always true, if there is no DMA. + '1' when DMA_ACTIVE = '1' and REQ_INn = '0' and CDn_In = TCR(1) and IOn_IN = TCR(0) and MSG_INn = TCR(2) else '0'; -- Phasematch. + + DMA_DIS <= '1' when DMA_ACTIVE = '1' and BSY_INn = '1' else '0'; + + SER_ID <= '1' when SER /= x"00" and SER = not CSD else '0'; + + DRQ <= DRQ_I; + INT <= INT_I; + + -- Pay attention: the SCSI bus is driven with inverted signals. + ACK_OUTn <= ACK_OUT_CTRLn when DMA_ACTIVE = '1' else not ICR(4); -- Valid in initiator mode. + REQ_OUTn <= REQ_OUT_CTRLn when DMA_ACTIVE = '1' else not TCR(3); -- Valid in Target mode. + BSY_OUTn <= '0' when BSY_OUT_CTRLn = '0' and TARG = '0' else -- Valid in initiator mode. + '0' when ICR(3) = '1' else '1'; + ATN_OUTn <= not ICR(1); -- Valid in initiator mode. + SEL_OUTn <= not ICR(2); -- Valid in initiator mode. + IOn_OUT <= not TCR(0); -- Valid in Target mode. + CDn_OUT <= not TCR(1); -- Valid in Target mode. + MSG_OUTn <= not TCR(2); -- Valid in Target mode. + RST_OUTn <= not RST; + + DB_OUTn <= not ODR; + DBP_OUTn <= not SPER; + + CSD <= not DB_INn; + CSB <= not RST_INn & not BSY_INn & not REQ_INn & not MSG_INn & not CDn_IN & not IOn_IN & not SEL_INn & not DBP_INn; + BSR <= EDMA & DRQ_I & SPER & INT_I & PHSM & BSY_ERR & not ATN_INn & not ACK_INn; + + -- Hi impedance control: + ATN_EN <= '1' when TARG = '0' else '0'; -- Initiator mode. + SEL_EN <= '1' when TARG = '0' else '0'; -- Initiator mode. + BSY_EN <= '1' when TARG = '0' else '0'; -- Initiator mode. + ACK_EN <= '1' when TARG = '0' else '0'; -- Initiator mode. + IO_EN <= '1' when TARG = '1' else '0'; -- Target mode. + CD_EN <= '1' when TARG = '1' else '0'; -- Target mode. + MSG_EN <= '1' when TARG = '1' else '0'; -- Target mode. + REQ_EN <= '1' when TARG = '1' else '0'; -- Target mode. + RST_EN <= '1' when RST = '1' else '0'; -- Open drain control. + + -- Data enables: + DB_EN_I <= '1' when DATA_EN_CTRL = '1' else -- During Arbitration. + '1' when ICR(0) = '1' and TARG = '1' and DMA_SND = '1' else -- Target 'Send' mode. + '1' when ICR(0) = '1' and TARG = '0' and IOn_IN = '0' and PHSM = '1' else + '1' when ICR(6) = '1' else '0'; -- Test mode enable. + + DB_EN <= DB_EN_I; + DBP_EN <= DB_EN_I; + + I_REGISTERS: WF5380_REGISTERS + port map( + CLK => CLK, + RESETn => RESETn, + ADR => ADR, + DATA_IN => DATA_IN, + DATA_OUT => DATA_OUT, + DATA_EN => DATA_EN, + CSn => CSn, + RDn => RDn, + WRn => WRn, + RSTn => RST_INn, + RST => RST, + ARB_EN => ARB_EN, + DMA_ACTIVE => DMA_ACTIVE, + DMA_EN => DMA_EN, + BSY_DISn => BSY_DISn, + EOP_EN => EOP_EN, + PINT_EN => PINT_EN, + SPER => SPER, + TARG => TARG, + BLK => BLK, + DMA_DIS => DMA_DIS, + IDR_WR => IDR_WR, + ODR_WR => ODR_WR, + CHK_PAR => CHK_PAR, + AIP => AIP, + ARB => ARB, + LA => LA, + CSD => CSD, + CSB => CSB, + BSR => BSR, + ODR_OUT => ODR, + ICR_OUT => ICR, + TCR_OUT => TCR, + SER_OUT => SER, + SDS => SDS, + SDT => SDT, + SDI => SDI, + RPI => RPI + ); + + I_CONTROL: WF5380_CONTROL + port map( + CLK => CLK, + RESETn => RESETn, + BSY_INn => BSY_INn, + BSY_OUTn => BSY_OUT_CTRLn, + DATA_EN => DATA_EN_CTRL, + SEL_INn => SEL_INn, + ARB_EN => ARB_EN, + BSY_DISn => BSY_DISn, + RSTn => RST_INn, + ARB => ARB, + AIP => AIP, + LA => LA, + ACK_INn => ACK_INn, + ACK_OUTn => ACK_OUT_CTRLn, + REQ_INn => REQ_INn, + REQ_OUTn => REQ_OUT_CTRLn, + DACKn => DACKn, + READY => READY, + DRQ => DRQ_I, + TARG => TARG, + BLK => BLK, + PINT_EN => PINT_EN, + SPER => SPER, + SER_ID => SER_ID, + RPI => RPI, + DMA_EN => DMA_EN, + SDS => SDS, + SDT => SDT, + SDI => SDI, + EOP_EN => EOP_EN, + EOPn => EOPn, + PHSM => PHSM, + INT => INT_I, + IDR_WR => IDR_WR, + ODR_WR => ODR_WR, + CHK_PAR => CHK_PAR, + BSY_ERR => BSY_ERR, + DMA_SND => DMA_SND, + DMA_ACTIVE => DMA_ACTIVE + ); +end STRUCTURE; diff --git a/vhdl/rtl/vhdl/WF5380/wf5380_top.vhd b/vhdl/rtl/vhdl/WF5380/wf5380_top.vhd new file mode 100644 index 0000000..2f594b2 --- /dev/null +++ b/vhdl/rtl/vhdl/WF5380/wf5380_top.vhd @@ -0,0 +1,258 @@ +---------------------------------------------------------------------- +---- ---- +---- WF5380 IP Core ---- +---- ---- +---- Description: ---- +---- This model provides an asynchronous SCSI interface compa- ---- +---- tible to the DP5380 from National Semiconductor and others. ---- +---- ---- +---- This file is the top level file with tree state buses. ---- +---- ---- +---- ---- +---- ---- +---- ---- +---- Author(s): ---- +---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright © 2009-2010 Wolfgang Foerster Inventronik GmbH. ---- +---- All rights reserved. No portion of this sourcecode may be ---- +---- reproduced or transmitted in any form by any means, whether ---- +---- by electronic, mechanical, photocopying, recording or ---- +---- otherwise, without my written permission. ---- +---- ---- +---------------------------------------------------------------------- +-- +-- Revision History +-- +-- Revision 2K9A 2009/06/20 WF +-- Initial Release. +-- + +library work; +use work.wf5380_pkg.all; + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + +entity WF5380_TOP is + port ( + -- System controls: + CLK : in bit; + RESETn : in bit; + + -- Address and data: + ADR : in std_logic_vector(2 downto 0); + DATA : inout std_logic_vector(7 downto 0); + + -- Bus and DMA controls: + CSn : in bit; + RDn : in bit; + WRn : in bit; + EOPn : in bit; + DACKn : in bit; + DRQ : out bit; + INT : out bit; + READY : out bit; + + -- SCSI bus: + DBn : inout std_logic_vector(7 downto 0); + DBPn : inout std_logic; + RSTn : inout std_logic; + BSYn : inout std_logic; + SELn : inout std_logic; + ACKn : inout std_logic; + ATNn : inout std_logic; + REQn : inout std_logic; + IOn : inout std_logic; + CDn : inout std_logic; + MSGn : inout std_logic + ); +end entity WF5380_TOP; + +architecture STRUCTURE of WF5380_TOP is +component WF5380_TOP_SOC + port ( + -- System controls: + CLK : in bit; + RESETn : in bit; + ADR : in bit_vector(2 downto 0); + DATA_IN : in bit_vector(7 downto 0); + DATA_OUT : out bit_vector(7 downto 0); + DATA_EN : out bit; + CSn : in bit; + RDn : in bit; + WRn : in bit; + EOPn : in bit; + DACKn : in bit; + DRQ : out bit; + INT : out bit; + READY : out bit; + DB_INn : in bit_vector(7 downto 0); + DB_OUTn : out bit_vector(7 downto 0); + DB_EN : out bit; + DBP_INn : in bit; + DBP_OUTn : out bit; + DBP_EN : out bit; + RST_INn : in bit; + RST_OUTn : out bit; + RST_EN : out bit; + BSY_INn : in bit; + BSY_OUTn : out bit; + BSY_EN : out bit; + SEL_INn : in bit; + SEL_OUTn : out bit; + SEL_EN : out bit; + ACK_INn : in bit; + ACK_OUTn : out bit; + ACK_EN : out bit; + ATN_INn : in bit; + ATN_OUTn : out bit; + ATN_EN : out bit; + REQ_INn : in bit; + REQ_OUTn : out bit; + REQ_EN : out bit; + IOn_IN : in bit; + IOn_OUT : out bit; + IO_EN : out bit; + CDn_IN : in bit; + CDn_OUT : out bit; + CD_EN : out bit; + MSG_INn : in bit; + MSG_OUTn : out bit; + MSG_EN : out bit + ); +end component; +-- +signal ADR_IN : bit_vector(2 downto 0); +signal DATA_IN : bit_vector(7 downto 0); +signal DATA_OUT : bit_vector(7 downto 0); +signal DATA_EN : bit; +signal DB_INn : bit_vector(7 downto 0); +signal DB_OUTn : bit_vector(7 downto 0); +signal DB_EN : bit; +signal DBP_INn : bit; +signal DBP_OUTn : bit; +signal DBP_EN : bit; +signal RST_INn : bit; +signal RST_OUTn : bit; +signal RST_EN : bit; +signal BSY_INn : bit; +signal BSY_OUTn : bit; +signal BSY_EN : bit; +signal SEL_INn : bit; +signal SEL_OUTn : bit; +signal SEL_EN : bit; +signal ACK_INn : bit; +signal ACK_OUTn : bit; +signal ACK_EN : bit; +signal ATN_INn : bit; +signal ATN_OUTn : bit; +signal ATN_EN : bit; +signal REQ_INn : bit; +signal REQ_OUTn : bit; +signal REQ_EN : bit; +signal IOn_IN : bit; +signal IOn_OUT : bit; +signal IO_EN : bit; +signal CDn_IN : bit; +signal CDn_OUT : bit; +signal CD_EN : bit; +signal MSG_INn : bit; +signal MSG_OUTn : bit; +signal MSG_EN : bit; +begin + ADR_IN <= To_BitVector(ADR); + + DATA_IN <= To_BitVector(DATA); + DATA <= To_StdLogicVector(DATA_OUT) when DATA_EN = '1' else (others => 'Z'); + + DB_INn <= To_BitVector(DBn); + DBn <= To_StdLogicVector(DB_OUTn) when DB_EN = '1' else (others => 'Z'); + + DBP_INn <= To_Bit(DBPn); + + RST_INn <= To_Bit(RSTn); + BSY_INn <= To_Bit(BSYn); + SEL_INn <= To_Bit(SELn); + ACK_INn <= To_Bit(ACKn); + ATN_INn <= To_Bit(ATNn); + REQ_INn <= To_Bit(REQn); + IOn_IN <= To_Bit(IOn); + CDn_IN <= To_Bit(CDn); + MSG_INn <= To_Bit(MSGn); + + DBPn <= '1' when DBP_OUTn = '1' and DBP_EN = '1' else + '0' when DBP_OUTn = '0' and DBP_EN = '1' else 'Z'; + RSTn <= '1' when RST_OUTn = '1' and RST_EN = '1'else + '0' when RST_OUTn = '0' and RST_EN = '1' else 'Z'; + BSYn <= '1' when BSY_OUTn = '1' and BSY_EN = '1' else + '0' when BSY_OUTn = '0' and BSY_EN = '1' else 'Z'; + SELn <= '1' when SEL_OUTn = '1' and SEL_EN = '1' else + '0' when SEL_OUTn = '0' and SEL_EN = '1' else 'Z'; + ACKn <= '1' when ACK_OUTn = '1' and ACK_EN = '1' else + '0' when ACK_OUTn = '0' and ACK_EN = '1' else 'Z'; + ATNn <= '1' when ATN_OUTn = '1' and ATN_EN = '1' else + '0' when ATN_OUTn = '0' and ATN_EN = '1' else 'Z'; + REQn <= '1' when REQ_OUTn = '1' and REQ_EN = '1' else + '0' when REQ_OUTn = '0' and REQ_EN = '1' else 'Z'; + IOn <= '1' when IOn_OUT = '1' and IO_EN = '1' else + '0' when IOn_OUT = '0' and IO_EN = '1' else 'Z'; + CDn <= '1' when CDn_OUT = '1' and CD_EN = '1' else + '0' when CDn_OUT = '0' and CD_EN = '1' else 'Z'; + MSGn <= '1' when MSG_OUTn = '1' and MSG_EN = '1' else + '0' when MSG_OUTn = '0' and MSG_EN = '1' else 'Z'; + + I_5380: WF5380_TOP_SOC + port map( + CLK => CLK, + RESETn => RESETn, + ADR => ADR_IN, + DATA_IN => DATA_IN, + DATA_OUT => DATA_OUT, + DATA_EN => DATA_EN, + CSn => CSn, + RDn => RDn, + WRn => WRn, + EOPn => EOPn, + DACKn => DACKn, + DRQ => DRQ, + INT => INT, + READY => READY, + DB_INn => DB_INn, + DB_OUTn => DB_OUTn, + DB_EN => DB_EN, + DBP_INn => DBP_INn, + DBP_OUTn => DBP_OUTn, + DBP_EN => DBP_EN, + RST_INn => RST_INn, + RST_OUTn => RST_OUTn, + RST_EN => RST_EN, + BSY_INn => BSY_INn, + BSY_OUTn => BSY_OUTn, + BSY_EN => BSY_EN, + SEL_INn => SEL_INn, + SEL_OUTn => SEL_OUTn, + SEL_EN => SEL_EN, + ACK_INn => ACK_INn, + ACK_OUTn => ACK_OUTn, + ACK_EN => ACK_EN, + ATN_INn => ATN_INn, + ATN_OUTn => ATN_OUTn, + ATN_EN => ATN_EN, + REQ_INn => REQ_INn, + REQ_OUTn => REQ_OUTn, + REQ_EN => REQ_EN, + IOn_IN => IOn_IN, + IOn_OUT => IOn_OUT, + IO_EN => IO_EN, + CDn_IN => CDn_IN, + CDn_OUT => CDn_OUT, + CD_EN => CD_EN, + MSG_INn => MSG_INn, + MSG_OUTn => MSG_OUTn, + MSG_EN => MSG_EN + ); +end STRUCTURE; diff --git a/vhdl/rtl/vhdl/WF_FDC1772_IP/wf1772ip_am_detector.vhd b/vhdl/rtl/vhdl/WF_FDC1772_IP/wf1772ip_am_detector.vhd new file mode 100644 index 0000000..97fe4db --- /dev/null +++ b/vhdl/rtl/vhdl/WF_FDC1772_IP/wf1772ip_am_detector.vhd @@ -0,0 +1,253 @@ +---------------------------------------------------------------------- +---- ---- +---- WD1772 compatible floppy disk controller IP Core. ---- +---- ---- +---- This file is part of the SUSKA ATARI clone project. ---- +---- http://www.experiment-s.de ---- +---- ---- +---- Description: ---- +---- Floppy disk controller with all features of the Western ---- +---- Digital WD1772-02 controller. ---- +---- ---- +---- Address mark detector file. This part detects the address ---- +---- mark in the incoming data stream in FM and also in MFM mode ---- +---- and provides therewith synchronisation information for the ---- +---- control state machine and for the data separator in the ---- +---- transceiver unit. ---- +---- ---- +------------------------------- Some theory ------------------------------------- +---- Frequency modulation FM: ---- +---- The frequency modulation works as follows: ---- +---- 1. every first pulse of the clock and data line is a clock. ---- +---- 2. every second pulse is a data. ---- +---- 3. a logic 1 is represented by two consecutive pulses (clock and data). ---- +---- 4. a logic 0 is represented by one clock pulse and no data pulse. ---- +---- 5. Hence there are a maximum of two pulses per data bit. ---- +---- 6. one clock and one data pulse come together in one bit cell. ---- +---- 7. the duration of a bit cell in FM is 4 microseconds. ---- +---- 8. an ID address mark is represented as data FE with clock C7. ---- +---- 9. a DATA address mark is represented as data FB with clock C7. ---- +---- Examples: ---- +---- Binary data 1 1 0 0 1 0 1 1 is represented in FM as follows: ---- +---- 1111101011101111 ---- +---- the FE data 1 1 1 1 1 1 1 0 is represented as follows: ---- +---- 1111111111111110 ---- +---- with C7 clock mask 1 1 0 0 0 1 1 1 which masks the clock pulses there ---- +---- results: 1111010101111110 this is the ID address mark. ---- +---- the FB data 1 1 1 1 1 0 1 1 is represented as follows: ---- +---- 1111111111101111 ---- +---- with C7 clock mask 1 1 0 0 0 1 1 1 which masks the clock pulses there ---- +---- results: 1111010101101111 this is the DATA address mark. ---- +---- the F8 data 1 1 1 1 1 0 0 0 is represented as follows: ---- +---- 1111111111101010 ---- +---- with C7 clock mask 1 1 0 0 0 1 1 1 which masks the clock pulses there ---- +---- results: 1111010101101010 this is the deleted DATA mark. ---- +---- ---- +---- ---- +---- Modified frequency modulation MFM: ---- +---- The modified frequency modulation works as follows: ---- +---- 1. every first pulse of the clock and data line is a clock. ---- +---- 2. every second pulse is a data. ---- +---- 3. a logic 1 is represented by no clock but a data pulse. ---- +---- 4. a logic 0 is represented by a clock pulse and no data pulse if ---- +---- following a 0. ---- +---- 5. a logic 0 is represented by no pulse if following a 1. ---- +---- 6. Hence there are a maximum of one pulse per data bit. ---- +---- 7. one clock and one data pulse form together one bit cell. ---- +---- 8. the duration of a bit cell in MFM is 2 microseconds. ---- +---- 9. an address mark sync is represented as data A1 with missing clock ---- +---- pulse between bit 4 and 5. ---- +---- Examples: ---- +---- Binary data FE 1 1 1 1 1 1 1 0 is represented in MFM as follows: ---- +---- 0101010101010100 this is the ID address mark. ---- +---- Binary data FB 1 1 1 1 1 0 1 1 is represented in MFM as follows: ---- +---- 0101010101000101 this is the DATA address mark. ---- +---- Binary data F8 1 1 1 1 1 0 0 0 is represented in MFM as follows: ---- +---- 0101010101001010 this is the deleted DATA address mark. ---- +---- the A1 data 1 0 1 0 0 0 0 1 is represented as follows: ---- +---- 0100010010101001 ---- +---- with the missing clock pulse between bits 4 and 5 there results: ---- +---- results: 0100010010001001 this is the address mark sync. ---- +---- ---- +---- Both MFM and FM are during read and write shifted with most significant ---- +---- bit (MSB) first. During the FM address marks are written without a ---- +---- SYNC pulse the MFM coded data requires a synchronisation (A1 with ---- +---- missing clock pulse because at the beginning of the data stream it is ---- +---- not defined wether a clock pulse or a data pulse appears first. In FM ---- +---- coding the first pulse is in any case a clock pulse. ---- +--------------------------------------------------------------------------------- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2006 - 2011 Wolfgang Foerster ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.gnu.org/licenses/lgpl.html ---- +---- ---- +---------------------------------------------------------------------- +-- +-- Revision History +-- +-- Revision 2006A 2006/06/03 WF +-- Initial Release. +-- Revision 2K6B 2006/11/05 WF +-- Modified Source to compile with the Xilinx ISE. +-- Revision 2K8A 2008/07/14 WF +-- Minor changes. +-- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + +entity WF1772IP_AM_DETECTOR is + port( + -- System control + CLK : in bit; + RESETn : in bit; + + -- Controls: + DDEn : in bit; + + -- Serial data and clock: + DATA : in bit; + DATA_STRB : in bit; + + -- Address mark detector: + ID_AM : out bit; -- ID address mark strobe. + DATA_AM : out bit; -- Data address mark strobe. + DDATA_AM : out bit -- Deleted data address mark strobe. + ); +end WF1772IP_AM_DETECTOR; + +architecture BEHAVIOR of WF1772IP_AM_DETECTOR is +signal SHIFT : bit_vector(15 downto 0); +signal SYNC : boolean; +signal ID_AM_I : bit; +signal DATA_AM_I : bit; +signal DDATA_AM_I : bit; +begin + SHIFTREG: process(RESETn, CLK) + begin + if RESETn = '0' then + SHIFT <= (others => '0'); + elsif CLK = '1' and CLK' event then + if DATA_STRB = '1' then + -- MSB first leads to a shift left operation. + SHIFT <= SHIFT(14 downto 0) & DATA; + elsif DDEn = '0' and SHIFT = "0100010010001001" then -- This is the synchronisation in MFM. + SHIFT <= (others => '0'); + end if; + end if; + end process SHIFTREG; + + MFM_SYNCLOCK: process(RESETn, CLK) + -- The SYNC pulse is generated in MFM mode only when the sync character + -- appears in the shift register (A1 sync mark, see file header). + -- After the sync character is detected, the sync time counter is loaded + -- with a value of 17. During counting the following 17 read clock pulses + -- down, the SYNC is true. After exactly 16 pulses the address mark is + -- detected if the pattern in the shift register fits one of the address + -- marks. The address mark pulses are valid for one read clock cycle until + -- SYNC goes low again. This mechanism is used to detect the correct address + -- marks in the MFM data stream during the type III read track command. + -- This is an improvement over the original WD1772 chip. + variable TMP : std_logic_vector(4 downto 0); + begin + if RESETn = '0' then + TMP := "00000"; + elsif CLK = '1' and CLK' event then + if SHIFT = "0100010010001001" and DDEn = '0' then + TMP := "10001"; -- Load sync time counter. + elsif DATA_STRB = '1' and TMP > "00000" then + TMP := TMP - '1'; + end if; + end if; + case TMP is + when "00000" => SYNC <= false; + when others => SYNC <= true; + end case; + end process MFM_SYNCLOCK; + + -- The addressmark is nominally valid for one data pulse cycle (1us, 2us, 4us). + -- The pulse is shorter due to the fact that the detected address marks change the + -- state of the control state machine and so clear the address mark shift register... + ID_AM_I <= '1' when DDEn = '1' and SHIFT = "1111010101111110" else + '1' when DDEn = '0' and SHIFT = "0101010101010100" and SYNC = true else '0'; + DATA_AM_I <= '1' when DDEn = '1' and SHIFT = "1111010101101111" else + -- Normal data address mark... + '1' when DDEn = '0' and SHIFT = "0101010101000101" and SYNC = true else '0'; + DDATA_AM_I <= '1' when DDEn = '1' and SHIFT = "1111010101101010" else + -- ... and deleted address mark in MFM mode: + '1' when DDEn = '0' and SHIFT = "0101010101001010" and SYNC = true else '0'; + + ADRMARK_STROBES: process(RESETn, CLK) + -- ... nevertheless The controller and the transceiver require ID address mark strobes + -- and DATA address mark strobes. Therefore this process provides these strobe + -- signals independant of any 'feedbacks' like pulse shortening by the controller + -- state machine itself. + variable ID_AM_LOCK, DATA_AM_LOCK, DDATA_AM_LOCK : boolean; + begin + if RESETn = '0' then + ID_AM_LOCK := false; + DATA_AM_LOCK := false; + ID_AM <= '0'; + DATA_AM <= '0'; + elsif CLK = '1' and CLK' event then + -- ID address mark: + if ID_AM_I = '1' and ID_AM_LOCK = false then + ID_AM <= '1'; + ID_AM_LOCK := true; + elsif ID_AM_I = '0' then + ID_AM <= '0'; + ID_AM_LOCK := false; + else + ID_AM <= '0'; + end if; + -- Data address mark: + if DATA_AM_I = '1' and DATA_AM_LOCK = false then + DATA_AM <= '1'; + DATA_AM_LOCK := true; + elsif DATA_AM_I = '0' then + DATA_AM <= '0'; + DATA_AM_LOCK := false; + else + DATA_AM <= '0'; + end if; + -- Deleted data address mark: + if DDATA_AM_I = '1' and DDATA_AM_LOCK = false then + DDATA_AM <= '1'; + DDATA_AM_LOCK := true; + elsif DDATA_AM_I = '0' then + DDATA_AM <= '0'; + DDATA_AM_LOCK := false; + else + DDATA_AM <= '0'; + end if; + end if; + end process ADRMARK_STROBES; +end architecture BEHAVIOR; diff --git a/vhdl/rtl/vhdl/WF_FDC1772_IP/wf1772ip_control.vhd b/vhdl/rtl/vhdl/WF_FDC1772_IP/wf1772ip_control.vhd new file mode 100644 index 0000000..5cba67e --- /dev/null +++ b/vhdl/rtl/vhdl/WF_FDC1772_IP/wf1772ip_control.vhd @@ -0,0 +1,1465 @@ +---------------------------------------------------------------------- +---- ---- +---- WD1772 compatible floppy disk controller IP Core. ---- +---- ---- +---- This file is part of the SUSKA ATARI clone project. ---- +---- http://www.experiment-s.de ---- +---- ---- +---- Description: ---- +---- Floppy disk controller with all features of the Western ---- +---- Digital WD1772-02 controller. ---- +---- ---- +---- This is file the control unit providing all signals for the ---- +---- data processing units like registers, addressmark detector, ---- +---- data separator, CRC redundancy checker or transceiver. ---- +---- ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2006 - 2011 Wolfgang Foerster ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.gnu.org/licenses/lgpl.html ---- +---- ---- +---------------------------------------------------------------------- +-- +-- Revision History +-- +-- Revision 2006A 2006/06/03 WF +-- Initial Release. +-- Revision 2K6B 2006/11/05 WF +-- Modified Source to compile with the Xilinx ISE. +-- Fixed the polarity of the precompensation flag. +-- The flag is no active '0'. Thanks to Jorma +-- Oksanen for the information. +-- Revision 2K8A 2008/02/26 WF +-- Fixed a bug in the 6ms delay. Thanks to Lyndon Amsdon. +-- Revision 2K8B 2008/12/24 WF +-- Bugfixes to avoid hanging state machine. +-- Changed DELAY_30MS to DELAY_15MS, which is the correct value. Thanks to L. Amsdon for the information. +-- Removed CRC_BUSY. +-- Fixed a bug in the Delay for the state T2_VERIFY_AM. +-- Revision 2K9A 2009/06/20 WF +-- Fix to provide correct LOST_DATA_TR00 flag during seek command. +-- Revision 2K9A 2009/06/20 WF +-- Fixed the timing for DR_LOAD. +-- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + +entity WF1772IP_CONTROL is + port( + -- System control: + CLK : in bit; + RESETn : in bit; + + -- Chip control signals: + A1, A0 : in bit; + RWn : in bit; + CSn : in bit; + DDEn : in bit; + + -- Registers: + DR : in bit_vector(7 downto 0); -- Data register. + CMD : in std_logic_vector(7 downto 0); -- Command register. + DSR : in std_logic_vector(7 downto 0); -- Shift register. + TR : in std_logic_vector(7 downto 0); -- Track register. + SR : in std_logic_vector(7 downto 0); -- Sector register. + + -- Status flags: + MO : buffer bit; -- Motor on status flag. + WR_PR : out bit; -- Write protect status flag. + SPINUP_RECTYPE : out bit; -- Spin up / record type status flag. + SEEK_RNF : out bit; -- Seek error / record not found status flag. + CRC_ERRFLAG : out bit; -- CRC status flag. + LOST_DATA_TR00 : out bit; -- Status flag indicates lost data or track 00 position. + DRQ : out bit; -- Data request. + DRQ_IPn : out bit; -- Data request status flag. + BUSY : buffer bit; -- BUSY status flag. + + -- Address mark detector controls: + AM_2_DISK : out bit; -- Enables / disables the address mark detector. + ID_AM : in bit; -- Address mark of the ID field + DATA_AM : in bit; -- Address mark of the data field + DDATA_AM : in bit; -- Address mark of a deleted data field + + -- CRC unit controls: + CRC_ERR : in bit; -- CRC decoder's error. + CRC_PRES : out bit; -- Preset CRC during write operations. + + -- Track register controls: + TR_PRES : out bit; -- Set x"FF". + TR_CLR : out bit; -- Clear. + TR_INC : out bit; -- Increment. + TR_DEC : out bit; -- Decrement. + + -- Sector register control: + SR_LOAD : out bit; -- Load. + SR_INC : out bit; -- Increment. + -- The TRACK_NR is required during the type III command + -- 'Read Address'. TRACK_NR is the content of the TRACKMEM. + TRACK_NR : out std_logic_vector(7 downto 0); + + -- DATA register control: + DR_CLR : out bit; -- Clear. + DR_LOAD : out bit; -- LOAD. + + -- Shift register control: + SHFT_LOAD_ND : out bit; -- Load normal data. + SHFT_LOAD_SD : out bit; -- Load special data. + + -- Transceiver controls: + CRC_2_DISK : out bit; -- Cause the Transceiver to write out CRC data. + DSR_2_DISK : out bit; -- Cause the Transceiver to write normal data. + FF_2_DISK : out bit; -- Cause the Transceiver to write x"FF" bytes. + PRECOMP_EN : out bit; -- Enables the write precompensation. + + -- Miscellaneous Controls: + DATA_STRB : in bit; -- Data strobe (read and write operation) + WPRTn : in bit; -- Write protect flag + IPn : in bit; -- Index pulse flag + TRACK00n : in bit; -- Track zero flag + DISK_RWn : out bit; -- This signal reflects the data direction. + DIRC : out bit; -- Step direction control. + STEP : out bit; -- Step pulse. + WG : out bit; -- Write gate control. + INTRQ : out bit -- Interrupt request flag. + ); +end WF1772IP_CONTROL; + +architecture BEHAVIOR of WF1772IP_CONTROL is + -- The control state machine for the three command types I, II and III + -- (10 commands) has 73 states: + type CMD_STATES is( IDLE, INIT, SPINUP, DELAY_15MS, DECODE, T1_SEEK_RESTORE, T1_STEPPING, + T1_LOAD_SHFT, T1_COMP_TR_DSR, T1_CHECK_DIR, T1_HEAD_CTRL, T1_STEP, T1_TRAP, T1_STEP_DELAY, + T1_SPINDOWN, T1_SCAN_TRACK, T1_SCAN_CRC, T1_VERIFY_DELAY, T1_VERIFY_CRC, T2_RD_WR_SECT, + T2_INIT, T2_SCAN_TRACK, T2_SCAN_SECT, T2_SCAN_LEN, T2_VERIFY_CRC_1, T2_VERIFY_AM, T2_FIRSTBYTE, + T2_LOAD_DATA, T2_NEXTBYTE, T2_VERIFY_DRQ_1, T2_RDSTAT, T2_VERIFY_CRC_2, + T2_MULTISECT, T2_DELAY_B2, T2_SET_DRQ, T2_DELAY_B8, T2_VERIFY_DRQ_2, + T2_DELAY_B1, T2_CHECK_MODE, T2_DELAY_B11, T2_WR_LEADIN, T2_WR_AM, + T2_LOAD_SHFT, T2_WR_BYTE, T2_VERIFY_DRQ_3, T2_DATALOST, T2_WRSTAT, T2_WR_CRC, + T2_WR_FF, T3_WR, T3_DELAY_B3, T3_VERIFY_DRQ, T3_CHECK_INDEX_1, T3_LOAD_SHFT, + T3_WR_DATA, T3_CHECK_INDEX_2, T3_DATALOST, T3_RD_TRACK, T3_SHIFT, + T3_CHECK_INDEX_3, T3_DETECT_AM, T3_CHECK_BYTE, T3_CHECK_DR, T3_LOAD_DATA_1, + T3_SET_DRQ_1, T3_RD_ADR, T3_VERIFY_AM, T3_SHIFT_ADR, T3_LOAD_DATA_2, + T3_SET_DRQ_2, T3_CHECK_RD, T3_LOAD_SR, T3_VERIFY_CRC); + signal CMD_STATE : CMD_STATES; + signal NEXT_CMD_STATE : CMD_STATES; + signal DATA_WR : boolean; + signal DATA_RD : boolean; + signal CMD_WR : boolean; + signal STAT_RD : boolean; + signal DELAY : boolean; + signal DRQ_I : bit; + signal INDEX_CNT : boolean; + signal DIR : bit; + signal INDEX_MARK : bit; + signal STEP_TRAP : boolean; + signal TYPE_IV_BREAK : boolean; + signal BYTE_RDY : boolean; + signal SECT_LEN : std_logic_vector(10 downto 0); + signal TRACKMEM : std_logic_vector(7 downto 0); + signal T3_TRADR : boolean; + signal T3_DATATYPE : bit_vector(7 downto 0); +begin + -- The Forced interrupt stops any command at the end of an internal micro instruction. + -- Forced interrupt waits until ALU operations in progress are complete (CRC calculations, + -- compares etc.). the TYPE_IV_BREAK controls this behavior. + TYPE_IV_BREAK <= true when CMD(7 downto 4) = x"D" and DELAY = true else false; + + CMD_REG: process(RESETn, CLK) + begin + if RESETn = '0' then + CMD_STATE <= IDLE; + elsif CLK = '1' and CLK' event then + if TYPE_IV_BREAK = true then + CMD_STATE <= IDLE; -- Forced interrupt break. + else + CMD_STATE <= NEXT_CMD_STATE; -- Normal operation. + end if; + end if; + end process CMD_REG; + + CMD_DECODER: process(CMD_STATE, CMD, DSR, TR, SR, INDEX_CNT, IPn, INDEX_MARK, DELAY, DIR, MO, CMD_WR, DRQ_I, + DDEn, CRC_ERR, TRACK00n, STEP_TRAP, ID_AM, DATA_AM, DDATA_AM, WPRTn, SECT_LEN, BYTE_RDY, + T3_TRADR) + begin + case CMD_STATE is + -------------------------------------------------------------------- + ------------------ type1, -2, -3 command stuff --------------------- + -------------------------------------------------------------------- + when IDLE => + -- The write access to the command register indicates a new command. + -- Any command received (type1, -2 or -3 but not type4): + if CMD_WR = true and CMD /= x"FF" and CMD(7 downto 4) /= "1101" then + NEXT_CMD_STATE <= INIT; + else + NEXT_CMD_STATE <= IDLE; -- No CMD detected. + end if; + when INIT => + -- The process goes on when the CMD_WR flag is released. + if CMD_WR = false and CMD(3) = '0' and MO = '0' then + -- Do not enter the SPINUP sequence + -- when the motor is already on (MO = '1'). + NEXT_CMD_STATE <= SPINUP; + elsif CMD_WR = false then + -- Proceed with the DELAY_15MS when the motor was + -- already on or when the SPINUP sequence is + -- disabled (CMD(3) = '1'). + NEXT_CMD_STATE <= DELAY_15MS; + else + NEXT_CMD_STATE <= INIT; + end if; + when SPINUP => + if INDEX_CNT = true then -- proceed after 6 revolutions + NEXT_CMD_STATE <= DELAY_15MS; + else + NEXT_CMD_STATE <= SPINUP; + end if; + when DELAY_15MS => + if CMD(7) = '0' then -- No delay for type1 commands. + NEXT_CMD_STATE <= DECODE; + elsif CMD(7) = '1' and CMD(2) = '0' then -- Delay for type2 and -3 disabled. + NEXT_CMD_STATE <= DECODE; + elsif CMD(7) = '1' and CMD(2) = '1' and DELAY = true then -- Delay enabled by CMD(2). + NEXT_CMD_STATE <= DECODE; + else + NEXT_CMD_STATE <= DELAY_15MS; + end if; + when DECODE => + case CMD(7 downto 5) is + when "000" => -- 'restore', 'seek'. + NEXT_CMD_STATE <= T1_SEEK_RESTORE; + when "001" |"010" | "011" => -- 'step', 'step in', 'step out'. + NEXT_CMD_STATE <= T1_STEPPING; + when "100" | "101" => -- 'read sector', 'write sector' + NEXT_CMD_STATE <= T2_RD_WR_SECT; + when "110" => -- 'read address'. + -- "110" is also used by the 'force interrupt'. + -- There will result no wrong encoding because + -- the 'force intterrupt' is predecoded in IDLE. + NEXT_CMD_STATE <= T3_RD_ADR; + when "111" => -- 'read track', 'write track'. + case CMD(4) is + when '0' => NEXT_CMD_STATE <= T3_RD_TRACK; + when '1' => NEXT_CMD_STATE <= T3_WR; + when others => NEXT_CMD_STATE <= T3_WR; -- Dummy for U, X, Z, W, H, L, -. + end case; + when others => + -- The following NEXT_CMD_STATE is chosen to compile fine with + -- the Xilinx ISE not to produce a latch. + NEXT_CMD_STATE <= IDLE; -- Never true due to IDLE preselection. + end case; + -------------------------------------------------------------------- + ------------------ special type1 command stuff --------------------- + -------------------------------------------------------------------- + when T1_SEEK_RESTORE => + -- In this state, the data register and the track register are updated, if the + -- command is a RESTORE. The update is done further down with the track register + -- and the data register controls. + NEXT_CMD_STATE <= T1_LOAD_SHFT; + when T1_STEPPING => + if CMD(4) = '1' then -- '1' means update track register. + NEXT_CMD_STATE <= T1_CHECK_DIR; + else + NEXT_CMD_STATE <= T1_HEAD_CTRL; + end if; + when T1_LOAD_SHFT => + NEXT_CMD_STATE <= T1_COMP_TR_DSR; + when T1_COMP_TR_DSR => + if DSR = TR then + NEXT_CMD_STATE <= T1_VERIFY_DELAY; + else + -- The direction control is done further down. + NEXT_CMD_STATE <= T1_CHECK_DIR; + end if; + when T1_CHECK_DIR => + -- Track register modifications are done in + -- statements further down. + -- The delay is to provide the timing of the WD1772 which is DIR to step = + -- 24us in MFM mode and 48us in FM mode. + if DELAY = true then + NEXT_CMD_STATE <= T1_HEAD_CTRL; + else + NEXT_CMD_STATE <= T1_CHECK_DIR; + end if; + when T1_HEAD_CTRL => + if TRACK00n = '0' and DIR = '0' then + NEXT_CMD_STATE <= T1_VERIFY_DELAY; + else + NEXT_CMD_STATE <= T1_STEP; + end if; + when T1_STEP => + NEXT_CMD_STATE <= T1_TRAP; + when T1_TRAP => + if STEP_TRAP = true then + NEXT_CMD_STATE <= IDLE; -- Break due to seek error. + else + NEXT_CMD_STATE <= T1_STEP_DELAY; + end if; + when T1_STEP_DELAY => + -- The delay in here is according to the CMD(1 downto 0) as follows: + -- "11" = 3ms, "10" = 2ms, "01" = 12ms, "00" = 6ms. + if DELAY = true then + case CMD(7 downto 5) is + when "001" | "010" | "011" => -- STEP - STEP IN - STEP OUT. + NEXT_CMD_STATE <= T1_VERIFY_DELAY; + when others => -- Seek or restore command. + NEXT_CMD_STATE <= T1_LOAD_SHFT; + end case; + else + NEXT_CMD_STATE <= T1_STEP_DELAY; + end if; + when T1_VERIFY_DELAY => + if CMD(2) = '0' then -- No verify. + NEXT_CMD_STATE <= IDLE; + else + if DELAY = true then -- Wait, if verify is active. + NEXT_CMD_STATE <= T1_SPINDOWN; + else + NEXT_CMD_STATE <= T1_VERIFY_DELAY; + end if; + end if; + when T1_SPINDOWN => -- Detect ID address mark in here. + if INDEX_CNT = true then + NEXT_CMD_STATE <= IDLE; -- Break due to timeout. + elsif ID_AM = '1' then -- Addressmark found. + NEXT_CMD_STATE <= T1_SCAN_TRACK; + else + NEXT_CMD_STATE <= T1_SPINDOWN; + end if; + when T1_SCAN_TRACK => + if DELAY = true then + -- Track found if shift register (DSR) equals track register (TR). + if DSR = TR then + NEXT_CMD_STATE <= T1_SCAN_CRC; + else + NEXT_CMD_STATE <= T1_SPINDOWN; + end if; + else + NEXT_CMD_STATE <= T1_SCAN_TRACK; + end if; + when T1_SCAN_CRC => + -- Scan the rest of the data header for correct CRC generation (3 Bytes). + -- Sector number side select byte and data length byte. + if DELAY = true then + NEXT_CMD_STATE <= T1_VERIFY_CRC; + else + NEXT_CMD_STATE <= T1_SCAN_CRC; + end if; + when T1_VERIFY_CRC => + -- The CRC logic starts during T1_SPINDOWN (missing clock transitions). + if DELAY = true then + if CRC_ERR = '1' then + NEXT_CMD_STATE <= T1_SPINDOWN; -- CRC error. + else + NEXT_CMD_STATE <= IDLE; -- Operation finished. + end if; + else + NEXT_CMD_STATE <= T1_VERIFY_CRC; -- Wait until CRC logic is ready. + end if; + -------------------------------------------------------------------- + ------------------ special type2 command stuff --------------------- + -------------------------------------------------------------------- + when T2_RD_WR_SECT => + if CMD(7 downto 5) = "101" and WPRTn = '0' then + NEXT_CMD_STATE <= IDLE; -- Break due to write protected disk. + else + NEXT_CMD_STATE <= T2_INIT; + end if; + when T2_INIT => + if INDEX_CNT = true then + NEXT_CMD_STATE <= IDLE; -- Break due to timeout. + elsif ID_AM = '0' then + NEXT_CMD_STATE <= T2_INIT; -- Wait for address mark. + else -- INDEX_CNT = false and ID_AM = '1' -> ID address mark detected + NEXT_CMD_STATE <= T2_SCAN_TRACK; + end if; + when T2_SCAN_TRACK => + -- Track found if shift register (DSR) equals track register (TR). + if DELAY = true then + if DSR = TR then + NEXT_CMD_STATE <= T2_SCAN_SECT; + else + NEXT_CMD_STATE <= T2_INIT; + end if; + else + NEXT_CMD_STATE <= T2_SCAN_TRACK; + end if; + when T2_SCAN_SECT => + -- Sector found if shift register (DSR) equals sector register (SR). + if DELAY = true then + if DSR = SR then + NEXT_CMD_STATE <= T2_SCAN_LEN; + else + NEXT_CMD_STATE <= T2_INIT; + end if; + else + NEXT_CMD_STATE <= T2_SCAN_SECT; + end if; + when T2_SCAN_LEN => + if DELAY = true then + NEXT_CMD_STATE <= T2_VERIFY_CRC_1; + else + NEXT_CMD_STATE <= T2_SCAN_LEN; + end if; + when T2_VERIFY_CRC_1 => + -- The CRC logic starts after T2_INIT (missing clock transitions). + if DELAY = true then + if CRC_ERR = '1' then + NEXT_CMD_STATE <= T2_INIT; -- CRC error. + elsif CRC_ERR = '0' and CMD(7 downto 5) = "101" then + NEXT_CMD_STATE <= T2_DELAY_B2; -- Comand is a write. + else -- Command is a read. + NEXT_CMD_STATE <= T2_VERIFY_AM; + end if; + else + NEXT_CMD_STATE <= T2_VERIFY_CRC_1; -- Wait until CRC logic is ready. + end if; + when T2_VERIFY_AM => + if DATA_AM = '1' or DDATA_AM = '1' then -- Data address mark detected, go on. + NEXT_CMD_STATE <= T2_FIRSTBYTE; + elsif DELAY = false then -- Stay in this state. + NEXT_CMD_STATE <= T2_VERIFY_AM; + else + NEXT_CMD_STATE <= T2_INIT; -- No addressmark detected. + end if; + when T2_FIRSTBYTE => + if DELAY = true then + NEXT_CMD_STATE <= T2_LOAD_DATA; + else + NEXT_CMD_STATE <= T2_FIRSTBYTE; + end if; + when T2_LOAD_DATA => + NEXT_CMD_STATE <= T2_NEXTBYTE; + when T2_NEXTBYTE => + if DELAY = true then + NEXT_CMD_STATE <= T2_VERIFY_DRQ_1; + else + NEXT_CMD_STATE <= T2_NEXTBYTE; + end if; + when T2_VERIFY_DRQ_1 => + NEXT_CMD_STATE <= T2_RDSTAT; + when T2_RDSTAT => + if SECT_LEN = "00000000000" then + NEXT_CMD_STATE <= T2_VERIFY_CRC_2; + else + NEXT_CMD_STATE <= T2_LOAD_DATA; + end if; + when T2_VERIFY_CRC_2 => + -- The CRC logic starts after T2_VERIFY_AM (missing clock transitions). + if DELAY = true then + if CRC_ERR = '1' then + NEXT_CMD_STATE <= IDLE; -- Break due to CRC error. + else + NEXT_CMD_STATE <= T2_MULTISECT; + end if; + else + NEXT_CMD_STATE <= T2_VERIFY_CRC_2; -- Wait until CRC logic is ready. + end if; + when T2_MULTISECT => + if CMD(4) = '1' then + NEXT_CMD_STATE <= T2_RD_WR_SECT; + else + NEXT_CMD_STATE <= IDLE; -- Operation finished. + end if; + when T2_DELAY_B2 => + if DELAY = true then + NEXT_CMD_STATE <= T2_SET_DRQ; + else + NEXT_CMD_STATE <= T2_DELAY_B2; + end if; + when T2_SET_DRQ => + NEXT_CMD_STATE <= T2_DELAY_B8; + when T2_DELAY_B8 => + if DELAY = true then + NEXT_CMD_STATE <= T2_VERIFY_DRQ_2; + else + NEXT_CMD_STATE <= T2_DELAY_B8; + end if; + when T2_VERIFY_DRQ_2 => + if DRQ_I = '0' then + NEXT_CMD_STATE <= T2_DELAY_B1; + else + NEXT_CMD_STATE <= IDLE; -- Break due to lost data (no new data by host). + end if; + when T2_DELAY_B1 => + if DELAY = true then + NEXT_CMD_STATE <= T2_CHECK_MODE; + else + NEXT_CMD_STATE <= T2_DELAY_B1; + end if; + when T2_CHECK_MODE => + if DDEn = '1' then -- FM mode + NEXT_CMD_STATE <= T2_WR_LEADIN; + else + NEXT_CMD_STATE <= T2_DELAY_B11; + end if; + when T2_DELAY_B11 => + if DELAY = true then + NEXT_CMD_STATE <= T2_WR_LEADIN; + else + NEXT_CMD_STATE <= T2_DELAY_B11; + end if; + when T2_WR_LEADIN => + if DELAY = true then + NEXT_CMD_STATE <= T2_WR_AM; + else + NEXT_CMD_STATE <= T2_WR_LEADIN; + end if; + when T2_WR_AM => -- Write data address mark. + if DELAY = true then + NEXT_CMD_STATE <= T2_LOAD_SHFT; + else + NEXT_CMD_STATE <= T2_WR_AM; + end if; + when T2_LOAD_SHFT => + NEXT_CMD_STATE <= T2_WR_BYTE; + when T2_WR_BYTE => + if DELAY = true then + NEXT_CMD_STATE <= T2_VERIFY_DRQ_3; + else + NEXT_CMD_STATE <= T2_WR_BYTE; + end if; + when T2_VERIFY_DRQ_3 => + if DRQ_I = '0' then + NEXT_CMD_STATE <= T2_WRSTAT; + else + NEXT_CMD_STATE <= T2_DATALOST; + end if; + when T2_DATALOST => + if DELAY = true then + NEXT_CMD_STATE <= T2_WRSTAT; + else + NEXT_CMD_STATE <= T2_DATALOST; + end if; + when T2_WRSTAT => + if SECT_LEN = "00000000000" then + NEXT_CMD_STATE <= T2_WR_CRC; -- Write operation finished. + else + NEXT_CMD_STATE <= T2_LOAD_SHFT; + end if; + when T2_WR_CRC => + if DELAY = true then + NEXT_CMD_STATE <= T2_WR_FF; + else + NEXT_CMD_STATE <= T2_WR_CRC; + end if; + when T2_WR_FF => + if DELAY = true then + NEXT_CMD_STATE <= T2_MULTISECT; + else + NEXT_CMD_STATE <= T2_WR_FF; + end if; + -------------------------------------------------------------------- + ---------------- type3 write track command stuff ------------------- + -------------------------------------------------------------------- + when T3_WR => + if WPRTn = '0' then + NEXT_CMD_STATE <= IDLE; -- Break due to write protected disk. + else + NEXT_CMD_STATE <= T3_DELAY_B3; + end if; + when T3_DELAY_B3 => + if DELAY = true then + NEXT_CMD_STATE <= T3_VERIFY_DRQ; + else + NEXT_CMD_STATE <= T3_DELAY_B3; + end if; + when T3_VERIFY_DRQ => + if DRQ_I = '0' then + NEXT_CMD_STATE <= T3_CHECK_INDEX_1; + else + NEXT_CMD_STATE <= IDLE; -- Break due to lost data (no new data by host). + end if; + when T3_CHECK_INDEX_1 => + if IPn = '0' then + NEXT_CMD_STATE <= T3_LOAD_SHFT; + else + NEXT_CMD_STATE <= T3_CHECK_INDEX_1; + end if; + when T3_LOAD_SHFT => + NEXT_CMD_STATE <= T3_WR_DATA; + when T3_WR_DATA => + if DELAY = true then + NEXT_CMD_STATE <= T3_CHECK_INDEX_2; + else + NEXT_CMD_STATE <= T3_WR_DATA; + end if; + when T3_CHECK_INDEX_2 => + if INDEX_MARK = '1' then + NEXT_CMD_STATE <= IDLE; -- End of track reached. + elsif DRQ_I = '0' then -- New data has been loaded. + NEXT_CMD_STATE <= T3_LOAD_SHFT; -- Fetch new data. + else + NEXT_CMD_STATE <= T3_DATALOST; -- Fill in nullbyte. + end if; + when T3_DATALOST => + if DELAY = true then + NEXT_CMD_STATE <= T3_CHECK_INDEX_2; + else + NEXT_CMD_STATE <= T3_DATALOST; + end if; + -------------------------------------------------------------------- + --------------- type3 read track command stuff -------------------- + -------------------------------------------------------------------- + when T3_RD_TRACK => + -- wait for index pulse: + if IPn = '0' then + NEXT_CMD_STATE <= T3_SHIFT; + else + NEXT_CMD_STATE <= T3_RD_TRACK; + end if; + when T3_SHIFT => + if DELAY = true then + NEXT_CMD_STATE <= T3_CHECK_INDEX_3; + else + NEXT_CMD_STATE <= T3_SHIFT; + end if; + when T3_CHECK_INDEX_3 => + if INDEX_MARK = '1' then + NEXT_CMD_STATE <= IDLE; -- End of track reached. + else + NEXT_CMD_STATE <= T3_DETECT_AM; + end if; + when T3_DETECT_AM => -- Detect for ID address mark. + if ID_AM = '1' then + NEXT_CMD_STATE <= T3_CHECK_DR; + else + NEXT_CMD_STATE <= T3_CHECK_BYTE; + end if; + when T3_CHECK_BYTE => + if BYTE_RDY = true then + NEXT_CMD_STATE <= T3_CHECK_DR; + else + NEXT_CMD_STATE <= T3_SHIFT; + end if; + when T3_CHECK_DR => + NEXT_CMD_STATE <= T3_LOAD_DATA_1; + when T3_LOAD_DATA_1 => + NEXT_CMD_STATE <= T3_SET_DRQ_1; + when T3_SET_DRQ_1 => + NEXT_CMD_STATE <= T3_SHIFT; + -------------------------------------------------------------------- + ---------------- type3 read address command stuff ------------------ + -------------------------------------------------------------------- + when T3_RD_ADR => + -- check for 6 index holes + if INDEX_CNT = true then + NEXT_CMD_STATE <= IDLE; -- Break due to timeout. + else + NEXT_CMD_STATE <= T3_VERIFY_AM; + end if; + when T3_VERIFY_AM => -- Check for existing ID address mark + if ID_AM = '1' then + NEXT_CMD_STATE <= T3_SHIFT_ADR; + else + NEXT_CMD_STATE <= T3_RD_ADR; + end if; + when T3_SHIFT_ADR => + if DELAY = true then + NEXT_CMD_STATE <= T3_LOAD_DATA_2; + else + NEXT_CMD_STATE <= T3_SHIFT_ADR; + end if; + when T3_LOAD_DATA_2 => + NEXT_CMD_STATE <= T3_SET_DRQ_2; + when T3_SET_DRQ_2 => + NEXT_CMD_STATE <= T3_CHECK_RD; + when T3_CHECK_RD => + if T3_TRADR = true then + NEXT_CMD_STATE <= T3_LOAD_SR; + else + NEXT_CMD_STATE <= T3_SHIFT_ADR; + end if; + when T3_LOAD_SR => + NEXT_CMD_STATE <= T3_VERIFY_CRC; + when T3_VERIFY_CRC => + -- The CRC logic starts during T3_VERIFY_AM (missing clock transitions). + if DELAY = true then + NEXT_CMD_STATE <= IDLE; -- Operation finished (with or without CRC error). + else + NEXT_CMD_STATE <= T3_VERIFY_CRC; -- Wait until CRC logic is ready. + end if; + end case; + end process CMD_DECODER; + + P_DELAY: process(RESETn, CLK, CMD_STATE, T3_DATATYPE, DDEn, CMD) + -- This process is responsible to control the DELAY signal in the different command + -- states of the main state machine. These states finish, if the signal DELAY is + -- asserted. The condition for asserted DELAY is the correct number of data strobes + -- which are supervised by the DATA_STRB inputs. + -- Another condition is a time delay required in the following states: + -- In DELAY_15MS there is a delay of 30ms. + -- In T1_STEP_PULSE the delay is according to the CMD(1 downto 0) as follows: + -- "11" = 3ms, "10" = 2ms, "01" = 12ms, "00" = 6ms. + -- In T1_VERIFY_DELAY there is a delay of 30ms. + variable DELCNT : std_logic_vector(19 downto 0); + begin + if RESETn = '0' then + DELCNT := (others => '0'); + elsif CLK = '1' and CLK' event then + -- Reset the delay right after it occurs: + if DELAY = true then + DELCNT := (others => '0'); + elsif DATA_AM = '1' or DDATA_AM = '1' then -- Reset in command state T2_VERIFY_AM. + DELCNT := (others => '0'); + else + case CMD_STATE is + -- Time delays work on CLK edges. + when DELAY_15MS | T1_CHECK_DIR | T1_STEP_DELAY | T1_VERIFY_DELAY => + DELCNT := DELCNT + '1'; + -- Bit count delays work on data strobes. + -- Read from disk operation: + when T1_SCAN_TRACK | T1_SCAN_CRC | T1_VERIFY_CRC | T2_SCAN_TRACK | T2_SCAN_SECT | + T2_SCAN_LEN | T2_VERIFY_CRC_1 | T2_VERIFY_AM | T2_FIRSTBYTE | + T2_NEXTBYTE | T2_VERIFY_CRC_2 | T3_SHIFT | T3_SHIFT_ADR | T3_VERIFY_CRC => + if DATA_STRB = '1' then + DELCNT := DELCNT + '1'; + end if; + -- Write to disk operation: + when T2_DELAY_B2 | T2_DELAY_B8 | T2_WR_LEADIN | + T2_WR_AM | T2_DELAY_B1 |T2_DELAY_B11 | T2_WR_BYTE | T2_DATALOST | + T2_WR_CRC | T2_WR_FF | T3_DELAY_B3 | T3_WR_DATA | T3_DATALOST => + if DATA_STRB = '1' then + DELCNT := DELCNT + '1'; + end if; + when others => + DELCNT := (others => '0'); -- Clear the delay counter if not used. + end case; + end if; + end if; + + case CMD_STATE is + when DELAY_15MS | T1_VERIFY_DELAY => + case DELCNT is + --when x"75300" => DELAY <= true; -- 30ms + when x"3A980" => DELAY <= true; -- 15ms, thanks to L. Amsdon. + when others => DELAY <= false; + end case; + when T1_CHECK_DIR => + if DDEn = '1' and DELCNT = x"00300" then -- 48us in FM + DELAY <= true; + elsif DDEn = '0' and DELCNT = x"00180" then -- 24us in MFM. + DELAY <= true; + else + DELAY <= false; + end if; + when T1_STEP_DELAY => + if CMD(1 downto 0) = "11" and DELCNT >= x"0BB80" then -- 3ms + DELAY <= true; + elsif CMD(1 downto 0) = "10" and DELCNT >= x"07D00" then -- 2ms + DELAY <= true; + elsif CMD(1 downto 0) = "01" and DELCNT >= x"2EE00" then -- 12ms + DELAY <= true; + elsif CMD(1 downto 0) = "00" and DELCNT >= x"17700" then -- 6ms + DELAY <= true; + else + DELAY <= false; + end if; + when T1_SCAN_TRACK | T2_SCAN_TRACK | T2_SCAN_LEN | T2_FIRSTBYTE | T2_NEXTBYTE | + T2_WR_BYTE | T2_DATALOST | T2_WR_FF | T3_DATALOST | T3_SHIFT_ADR => + case DELCNT is + when x"00008" => DELAY <= true; -- The delay in this case is 8 bit times. + when others => DELAY <= false; + end case; + when T1_SCAN_CRC => + case DELCNT is + when x"00018" => DELAY <= true; -- Scan for 3 bytes. + when others => DELAY <= false; + end case; + when T2_WR_AM => + if DDEn = '1' and DELCNT = x"00008" then -- Wait for 8 address mark bits (FM mode). + DELAY <= true; + elsif DDEn = '0' and DELCNT = x"00020" then -- Wait for 32 sync and address mark bits (MFM mode). + DELAY <= true; + else + DELAY <= false; + end if; + when T2_VERIFY_AM => + if DDEn = '1' and DELCNT >= x"00148" then -- FM mode. + DELAY <= true; -- (11+6+1)+1 = 19 Byte Times, plus 10 Byte times uncertainty. + elsif DDEn = '0' and DELCNT >= x"00188" then -- MFM mode. + DELAY <= true; -- (22+12+3+1)+1 = 39 Byte Times, plus 10 Byte times uncertainty. + else + DELAY <= false; + end if; + when T2_WR_LEADIN => + if DDEn = '1' and DELCNT = x"00030" then -- Scan for 48 zero bits in FM mode. + DELAY <= true; + elsif DDEn = '0' and DELCNT = x"00060" then -- Scan for 96 zero bits in MFM mode. + DELAY <= true; + else + DELAY <= false; + end if; + when T2_DELAY_B1 => + case DELCNT is + when x"00008" => DELAY <= true; -- Delay is 1 byte. + when others => DELAY <= false; + end case; + when T3_DELAY_B3 => + case DELCNT is + when x"00018" => DELAY <= true; -- Delay is 3 bytes. + when others => DELAY <= false; + end case; + when T2_DELAY_B8 => + case DELCNT is + when x"00040" => DELAY <= true; -- Delay is 8 bytes. + when others => DELAY <= false; + end case; + when T2_DELAY_B11 => + case DELCNT is + when x"00058" => DELAY <= true; -- Delay is 11 bytes. + when others => DELAY <= false; + end case; + when T2_VERIFY_CRC_2 => + -- In this state the original WD1772 state machine causes the CRC data to appear 1 byte + -- too early. The reason is the construction of the states T2_LOAD_DATA and T2_NEXTBYTE + -- where the length counter and the DRQ flag are serviced in T2_LOAD_DATA. Therefore the + -- delay is only 1 byte instead of 2. + case DELCNT is + when x"00008" => DELAY <= true; -- Scan for 2 bytes but wait only 1 byte. + when others => DELAY <= false; + end case; + when T1_VERIFY_CRC | T2_SCAN_SECT | T2_VERIFY_CRC_1 | T2_DELAY_B2 | T2_WR_CRC | T3_VERIFY_CRC => + case DELCNT is + when x"00010" => DELAY <= true; -- Scan for 2 bytes (e. g. side and sector in T2_SCAN_SECT). + when others => DELAY <= false; + end case; + when T3_WR_DATA => + if T3_DATATYPE = x"F7" and DELCNT = x"00010" then -- Wait for 16 CRC bits. + DELAY <= true; + elsif T3_DATATYPE /= x"F7" and DELCNT = x"00008" then -- Wait for 8 data bits. + DELAY <= true; + else + DELAY <= false; + end if; + when T3_SHIFT => + case DELCNT is + when x"00001" => DELAY <= true; -- Scan just one data bit. + when others => DELAY <= false; + end case; + when others => + DELAY <= false; + end case; + end process P_DELAY; + + INDEX_COUNTER: process(RESETn, CLK, CMD_STATE) + -- This process is intended to control some command states via the index pulse behavior. + -- In the original WD177x there is foreseen a delay of several index pulses (about 1s). + -- It is achieved by counting the index pulses of the disk. This encounters problems, + -- if the disk is not inserted. For this reason there is additionally to the index counter + -- a timeout which is active if there are no index pulses. + variable CNT : std_logic_vector(3 downto 0); + variable TIMEOUT : std_logic_vector(27 downto 0); + variable LOCK : boolean; + begin + if RESETn = '0' then + CNT := x"0"; + TIMEOUT := (others => '0'); + LOCK := false; + elsif CLK = '1' and CLK' event then + case CMD_STATE is + -- Be aware that there must sometimes checked several states for the presence of IPn! + when SPINUP | T1_SPINDOWN | T1_SCAN_TRACK | T1_SCAN_CRC | T1_VERIFY_CRC | + T2_INIT | T2_SCAN_TRACK | T2_SCAN_SECT |T2_SCAN_LEN | T2_VERIFY_CRC_1 | T3_RD_ADR | T3_VERIFY_AM => + if IPn = '0' and LOCK = false then -- Count the index pulses. + CNT := CNT + '1'; + LOCK := true; + elsif IPn = '1' then + LOCK := false; + end if; + -- + if TIMEOUT < x"17FFFFF" then -- Timeout of about 1.5s. + TIMEOUT := TIMEOUT + '1'; + end if; + when others => + CNT := x"0"; + TIMEOUT := (others => '0'); + end case; + end if; + -- + if CMD_STATE = SPINUP and (CNT = "110" or TIMEOUT = x"17FFFFF") then -- 6 pulses or timeout. + INDEX_CNT <= true; + elsif CMD_STATE = T1_SPINDOWN and (CNT = "110" or TIMEOUT = x"17FFFFF") then -- 6 pulses or timeout. + INDEX_CNT <= true; + elsif CMD_STATE = T2_INIT and (CNT = "101" or TIMEOUT = x"17FFFFF") then -- 5 pulses or timeout. + INDEX_CNT <= true; + elsif CMD_STATE = T3_RD_ADR and (CNT = "110" or TIMEOUT = x"17FFFFF") then -- 6 pulses or timeout. + INDEX_CNT <= true; + else + INDEX_CNT <= false; + end if; + end process INDEX_COUNTER; + + P_INDEX_MARK: process + -- This process controls the occurence of an index pulse during read track + -- and write track commands. The flag INDEX_MARK is cleared at the + -- beginning of these two commands during the first check for an index + -- pulse and is set right after the next index pulse occurs, which means + -- track processing has completed. + variable LOCK: boolean; + begin + wait until CLK = '1' and CLK' event; + if CMD_STATE = T3_RD_TRACK and IPn = '0' then + INDEX_MARK <= '0'; -- Reset the flag. + LOCK := true; + elsif CMD_STATE = T3_CHECK_INDEX_1 and IPn = '0' then + INDEX_MARK <= '0'; -- Reset the flag. + LOCK := true; + elsif IPn = '0' and LOCK = false then + INDEX_MARK <= '1'; -- Index pulse has passed. + LOCK := true; + elsif IPn = '1' then + LOCK := false; + end if; + end process P_INDEX_MARK; + + P_T3_DATATYPE: process(RESETn, CLK) + -- In type 3 write track command, it is necessary to store the information, which data + -- has to be written to disk (in command state T3_WR_DATA. This information is sampled + -- in the command state T3_LOAD_SHFT which preceeds the command state T3_WR_DATA. + begin + if RESETn = '0' then + T3_DATATYPE <= x"00"; + elsif CLK = '1' and CLK' event then + if CMD_STATE = T3_LOAD_SHFT then + T3_DATATYPE <= DR; + end if; + end if; + end process P_T3_DATATYPE; + + CNT_T3BYTES: process(RESETn, CLK, CMD_STATE) + -- This process counts the bytes read in the type III read address + -- command during the command states T3_SHIFT_ADR, T3_LOAD_DATA2, + -- T3_SET_DRQ_2 and T3_CHECK_RD. + variable CNT : std_logic_vector(2 downto 0); + begin + if RESETn = '0' then + CNT := "000"; + elsif CLK = '1' and CLK' event then + case CMD_STATE is + when T3_VERIFY_AM => + CNT := "000"; -- Clear the counter right befor the count operation. + when T3_SET_DRQ_2 => + CNT := CNT + '1'; -- Increment after each read cycle. + when others => + null; + end case; + end if; + case CNT is + when "100" => T3_TRADR <= true; + when others => T3_TRADR <= false; + end case; + end process CNT_T3BYTES; + + BYTEASMBLY: process(RESETn, CLK) + -- This process controls the condition in the CMD_STATE T3_CHECK_DR. + -- Therefore the bits shifted into the DSR in command state T3_SHIFT are counted. + -- The count condition is entering the command state T3_CHECK_INDEX_3. The clear + -- condition is either the command state IDLE or the command state T3_CHECK_DR. + variable CNT : std_logic_vector(3 downto 0); + begin + if RESETn = '0' then + CNT := x"0"; + elsif CLK = '1' and CLK' event then + case CMD_STATE is + when IDLE => CNT := x"0"; + when T3_CHECK_INDEX_3 => CNT := CNT + '1'; + when T3_CHECK_DR => CNT := (others => '0'); + when others => null; + end case; + end if; + case CNT is + when x"8" => BYTE_RDY <= true; + when others => BYTE_RDY <= false; + end case; + end process BYTEASMBLY; + + P_DIR: process(RESETn, CLK, DIR) + -- This portion of code is responsible to control the right stepping + -- direction in type I commands. + begin + if RESETn = '0' then + DIR <= '0'; + elsif CLK = '1' and CLK' event then + if CMD_STATE = DECODE and CMD(7 downto 5) = "010" then -- Step in. + DIR <= '1'; + elsif CMD_STATE = DECODE and CMD(7 downto 5) = "011" then -- Step out. + DIR <= '0'; + elsif CMD_STATE = T1_COMP_TR_DSR and DSR > TR then -- Seek. + DIR <= '1'; + elsif CMD_STATE = T1_COMP_TR_DSR and DSR < TR then -- Seek. + DIR <= '0'; + end if; + end if; + DIRC <= DIR; -- Copy signal to the output. + end process P_DIR; + + P_DRQ: process(RESETn, CLK, DRQ_I) + begin + if RESETn = '0' then + DRQ_I <= '0'; + elsif CLK = '1' and CLK' event then + case CMD_STATE is + when INIT => + DRQ_I <= '0'; + when T2_LOAD_DATA | T2_SET_DRQ | T2_LOAD_SHFT => + DRQ_I <= '1'; + when T3_WR | T3_LOAD_SHFT | T3_SET_DRQ_1 | T3_SET_DRQ_2 => + DRQ_I <= '1'; + when others => + null; + end case; + -- The data request bit is also cleared by reading or writing the + -- data register (direct memory access operation). + if (DATA_RD = true or DATA_WR = true) then + DRQ_I <= '0'; + end if; + end if; + -- + DRQ <= DRQ_I; -- Copy to entity. + -- + end process P_DRQ; + + -- The DRQ_IPn detects the index pulse during type I commands and a forced interrupt or + -- DRQ during type II and III commands. + -- The index pulse flag is active high and can be used for the detection of an inserted disk. + DRQ_IPn <= not IPn when CMD(7) = '0' else + not IPn when CMD(7 downto 4) = x"D" and BUSY = '0' else DRQ_I; + + P_BUSY: process(RESETn, CLK) + begin + if RESETn = '0' then + BUSY <= '0'; + elsif CLK = '1' and CLK' event then + -- During forced interrupt, the busy flag is reset when the command + -- state machine enters the IDLE state. + if CMD_STATE = INIT then + BUSY <= '1'; -- set BUSY flag for all command types I ... III. + elsif CMD_STATE = IDLE then + BUSY <= '0'; -- Reset BUSY after entering IDLE in any case. + end if; + end if; + end process P_BUSY; + + P_SEEK_RNF: process(RESETn, CLK) + -- Seek error or record not found error flag. + begin + if RESETn = '0' then + SEEK_RNF <= '0'; + elsif CLK = '1' and CLK' event then + if CMD_STATE = INIT then + SEEK_RNF <= '0'; -- Clear the flag for all command types I ... III. + elsif CMD_STATE = T1_TRAP and STEP_TRAP = true then + SEEK_RNF <= '1'; -- Seek error (SEEK). + elsif CMD_STATE = T1_SPINDOWN and INDEX_CNT = true then + SEEK_RNF <= '1'; -- Seek error (SEEK). + elsif CMD_STATE = T2_INIT and INDEX_CNT = true then + SEEK_RNF <= '1'; -- Record not found (RNF). + elsif CMD_STATE = T3_RD_ADR and INDEX_CNT = true then + SEEK_RNF <= '1'; -- Record not found (RNF). + end if; + end if; + end process P_SEEK_RNF; + + P_INTRQ: process(RESETn, CLK) + begin + if RESETn = '0' then + INTRQ <= '0'; + elsif CLK = '1' and CLK' event then + -- Interrupt reset conditions: + if STAT_RD = true and CMD /= x"D8" then + -- No clear during immediately forced interrupt. + INTRQ <= '0'; -- Clear the flag when status register is read. + elsif CMD_WR = true and CMD = x"D0" then + -- Clear with the next write access to the command register after the + -- forced interrupt x"D0" was written. + INTRQ <= '0'; + elsif CMD_STATE = INIT and CMD(7 downto 6) /= "11" then + INTRQ <= '0'; -- Clear the flag for type I and type II commands during start of execution. + -- Interrupt set conditions. + elsif CMD = x"D8" and CMD_STATE = IDLE then + INTRQ <= '1'; -- Force interrupt immediately (after the break took affect). + elsif CMD = x"D4" and IPn = '0' and CMD_STATE = IDLE then + INTRQ <= '1'; -- Force interrupt on next index pulse (after the break took affect). + elsif CMD_STATE = T1_TRAP and STEP_TRAP = true then + INTRQ <= '1'; -- Indicate interrupt request due to seek error. + elsif CMD_STATE = T1_VERIFY_DELAY and CMD(2) = '0' then + INTRQ <= '1'; -- Indicate interrupt: command finished or interrupted. + elsif CMD_STATE = T1_SPINDOWN and INDEX_CNT = true then + INTRQ <= '1'; -- Indicate interrupt request, reason: seek error. + elsif CMD_STATE = T1_VERIFY_CRC and CRC_ERR = '0' then + INTRQ <= '1'; -- Indicate interrupt request; command correct, no CRC error. + elsif CMD_STATE = T2_RD_WR_SECT and CMD(7 downto 5) = "101" and WPRTn = '0' then + INTRQ <= '1'; -- Indicate interrupt request because disk is write protected. + elsif CMD_STATE = T2_INIT and INDEX_CNT = true then + INTRQ <= '1'; -- Indicate interrupt request, reason: timeout. + elsif CMD_STATE = T2_VERIFY_CRC_2 and DELAY = true and CRC_ERR = '1' then + INTRQ <= '1'; -- Indicate interrupt request due to CRC error. + elsif CMD_STATE = T2_MULTISECT and CMD(4) = '0' then + INTRQ <= '1'; -- Indicate interrupt request, command correct finished. + elsif CMD_STATE = T2_VERIFY_DRQ_2 and DRQ_I = '1' then + INTRQ <= '1'; -- Indicate interrupt request, reason: lost data. + elsif CMD_STATE = T3_WR and WPRTn = '0' then + INTRQ <= '1'; -- Indicate interrupt request, reason: disk is write protected. + elsif CMD_STATE = T3_VERIFY_DRQ and DRQ_I = '1' then + INTRQ <= '1'; -- Indicate interrupt request due to lost data. + elsif CMD_STATE = T3_CHECK_INDEX_2 and INDEX_MARK = '1' then + INTRQ <= '1'; -- Indicate interrupt request, reason: command finished correctly. + elsif CMD_STATE = T3_CHECK_INDEX_3 and INDEX_MARK = '1' then + INTRQ <= '1'; -- Indicate interrupt request, reason: command finished correctly. + elsif CMD_STATE = T3_RD_ADR and INDEX_CNT = true then + INTRQ <= '1'; -- Indicate interrupt request because record was not found. + elsif CMD_STATE = T3_VERIFY_CRC then + INTRQ <= '1'; -- Indicate interrupt request; command finished with or without CRC error. + end if; + end if; + end process P_INTRQ; + + P_LOST_DATA_TR00: process(RESETn, CLK) + -- Logic for the status bit number 2: + -- The TRACK00 flag is used to detect wether a floppy disk drive + -- is connected or not. + begin + if RESETn = '0' then + LOST_DATA_TR00 <= '0'; + elsif CLK = '1' and CLK' event then + if CMD(7 downto 4) = x"D" and BUSY = '0' then -- Forced interrupt. + LOST_DATA_TR00 <= not TRACK00n; + elsif CMD_STATE = INIT then + LOST_DATA_TR00 <= '0'; + elsif CMD_STATE = T1_VERIFY_DELAY then + LOST_DATA_TR00 <= not TRACK00n; + elsif CMD_STATE = T2_VERIFY_DRQ_1 and DRQ_I = '1' then + LOST_DATA_TR00 <= '1'; + elsif CMD_STATE = T2_VERIFY_DRQ_2 and DRQ_I = '1' then + LOST_DATA_TR00 <= '1'; + elsif CMD_STATE = T2_VERIFY_DRQ_3 and DRQ_I = '1' then + LOST_DATA_TR00 <= '1'; + elsif CMD_STATE = T3_VERIFY_DRQ and DRQ_I = '1' then + LOST_DATA_TR00 <= '1'; + elsif CMD_STATE = T3_DATALOST then + LOST_DATA_TR00 <= '1'; + elsif CMD_STATE = T3_CHECK_DR and DRQ_I = '1' then + LOST_DATA_TR00 <= '1'; + end if; + end if; + end process P_LOST_DATA_TR00; + + MOTORSWITCH: process(RESETn, CLK) + variable INDEXCNT : std_logic_vector(3 downto 0); + variable LOCK : boolean; + begin + if RESETn = '0' then + MO <= '0'; + INDEXCNT := x"0"; + LOCK := false; + elsif CLK = '1' and CLK' event then + if CMD_STATE /= IDLE then + INDEXCNT := x"9"; -- Initialise the index counter. + LOCK := false; + elsif LOCK = false and IPn = '0' and INDEXCNT > x"0" then + INDEXCNT := INDEXCNT - '1'; -- Count the index pulses in the IDLE state. + LOCK := true; + elsif IPn = '1' then + LOCK := false; + end if; + -- + if CMD_STATE = INIT and CMD_WR = false then + MO <= '1'; -- Start the motor for all command types I ... III in this state. + elsif INDEXCNT = x"0" then + MO <= '0'; -- The motor stops after 9 index pulses in idle state. + end if; + end if; + end process MOTORSWITCH; + + WRITE_PROTECT: process(RESETn, CLK) + begin + if RESETn = '0' then + WR_PR <= '0'; + elsif CLK = '1' and CLK' event then + if CMD_STATE = INIT and CMD(7) = '1' then + WR_PR <= '0'; -- Clear the flag for type II and type III commands. + elsif CMD_STATE = T2_RD_WR_SECT and WPRTn = '0' then + WR_PR <= '1'; + elsif CMD_STATE = T3_WR and WPRTn = '0' then + WR_PR <= '1'; + end if; + end if; + end process WRITE_PROTECT; + + RECTYPE_SPINUP: process(RESETn, CLK) + begin + if RESETn = '0' then + SPINUP_RECTYPE <= '0'; + elsif CLK = '1' and CLK' event then + if CMD_STATE = INIT then + SPINUP_RECTYPE <= '0'; -- Clear the flag for type II...III commands. + elsif CMD_STATE = SPINUP and CMD(7) = '0' and INDEX_CNT = true then + SPINUP_RECTYPE <= '1'; -- SPINUP SEQUENCE for type I commands has finished. + elsif CMD_STATE = T2_VERIFY_AM and (DATA_AM = '1' or DDATA_AM = '1') then + case DSR is + when x"F8" => SPINUP_RECTYPE <= '1'; -- Deleted data address mark. + when x"FB" => SPINUP_RECTYPE <= '0'; -- Normal data address mark. + when others => null; -- Forbidden, should never appear. + end case; + end if; + end if; + end process RECTYPE_SPINUP; + + WRITEGATE: process(RESETn, CLK) + begin + if RESETn = '0' then + WG <= '0'; + elsif CLK = '1' and CLK' event then + case CMD_STATE is + when T2_WR_LEADIN | T3_LOAD_SHFT => + WG <= '1'; + when T2_MULTISECT | IDLE => + WG <= '0'; + when others => + null; + end case; + end if; + end process WRITEGATE; + + RESTORE_TRAP: process(RESETn, CLK) + -- This process is responsible to supervise the RESTORE command. + -- If after 255 stepping pulses no TRACK00n was not detected, the + -- RESTORE command is terminated and the interrupt request and the + -- seek error are set. + variable STEP_CNT : std_logic_vector(7 downto 0); + begin + if RESETn = '0' then + STEP_CNT := (others => '0'); + elsif CLK = '1' and CLK' event then + if CMD_STATE = IDLE then + STEP_CNT := x"00"; + elsif CMD(7 downto 4) /= "0000" then -- No RESTORE command. + STEP_CNT := x"00"; + elsif CMD_STATE = T1_STEP and STEP_CNT < x"FF" then + STEP_CNT := STEP_CNT + '1'; + end if; + end if; + -- + case STEP_CNT is + when x"FF" => STEP_TRAP <= true; + when others => STEP_TRAP <= false; + end case; + end process RESTORE_TRAP; + + STEPPULSE: process(RESETn, CLK) + -- The step pulse duration is in the original WD1772 4us in MFM mode and 8 us. + -- in FM mode This process is responsible to provide the correct pulse lengths. + variable CNT : std_logic_vector(7 downto 0); + begin + if RESETn = '0' then + CNT := (others => '0'); + elsif CLK = '1' and CLK' event then + if CMD_STATE = T1_STEP then + case DDEn is + when '1' => CNT := x"80"; --Start counter for FM step pulse. + when '0' => CNT := x"40"; --Start counter for MFM step pulse. + end case; + elsif CNT > x"00" then + CNT := CNT -1; -- Count 63 or 127 CLK cycles ... + end if; + case CNT is + when x"00" => STEP <= '0'; + when others => STEP <= '1'; --...result in 3.875us or 7.75us pulse. + end case; + end if; + end process STEPPULSE; + + TRACK_MEM: process(RESETn, CLK, TRACKMEM) + -- This process is necessary to store the actual track number in the + -- type III command 'read address' because the track number is written + -- to the sector register some byte times after the detection of the + -- track number from disk. + begin + if RESETn = '0' then + TRACKMEM <= x"00"; + elsif CLK = '1' and CLK' event then + case CMD_STATE is + when IDLE => + TRACKMEM <= x"00"; -- Clear the Track memory. + when T3_LOAD_DATA_2 => + TRACKMEM <= DSR; -- Store the actual track number. + when others => + null; + end case; + end if; + TRACK_NR <= TRACKMEM; -- Output the TRACKMEM. + end process TRACK_MEM; + + SECT_LENGTH: process(RESETn, CLK, SECT_LEN) + -- This process supervises the read sector and write sector + -- commands. If the sector read or write are equal to the + -- sector length, the commands read sector and write sector + -- are ready. + begin + if RESETn = '0' then + SECT_LEN <= "00000000000"; + elsif CLK = '1' and CLK' event then + case CMD_STATE is + when T2_SCAN_LEN => + -- Bring in the correct sector length. + case DSR(1 downto 0) is + when "00" => SECT_LEN <= "00010000000"; -- 128 Byte per sector. + when "01" => SECT_LEN <= "00100000000"; -- 256 Byte per sector. + when "10" => SECT_LEN <= "01000000000"; -- 512 Byte per sector. + when "11" => SECT_LEN <= "10000000000"; -- 1024 Byte per sector. + when others => SECT_LEN <= "10000000000"; -- Dummy for U, X, Z, W, H, L, -. + end case; + when T2_LOAD_DATA | T2_LOAD_SHFT => + SECT_LEN <= SECT_LEN - '1'; + when others => + null; + end case; + end if; + end process SECT_LENGTH; + + P_CRC_ERR: process(RESETn, CLK) + -- This code checks the CRC status in the right command states + -- and sets or resets the CRC error status flag. + begin + if RESETn = '0' then + CRC_ERRFLAG <= '0'; + elsif CLK = '1' and CLK' event then + case CMD_STATE is + when INIT => + if CMD(7) = '0' then + CRC_ERRFLAG <= '0'; -- Reset for type I commands only. + end if; + when T1_VERIFY_CRC | T2_VERIFY_CRC_1 => + if CRC_ERR = '1' and DELAY = true then + CRC_ERRFLAG <= '1'; -- Set CRC error flag... + elsif CRC_ERR = '0' and DELAY = true then + CRC_ERRFLAG <= '0'; -- ... or reset CRC error flag. + end if; + when T2_VERIFY_CRC_2 | T3_VERIFY_CRC => + if CRC_ERR = '1' and DELAY = true then + -- Set CRC error flag but no reset in here. + -- The CRC is already reset by the previous checks. + CRC_ERRFLAG <= '1'; + end if; + when others => + null; + end case; + end if; + end process P_CRC_ERR; + + CMD_WR <= true when CSn = '0' and A1 = '0' and A0 = '0' and RWn = '0' else false; -- Command register write. + STAT_RD <= true when CSn = '0' and A1 = '0' and A0 = '0' and RWn = '1' else false; -- Status register read. + DATA_WR <= true when CSn = '0' and A1 = '1' and A0 = '1' and RWn = '0' else false; -- Data register write. + DATA_RD <= true when CSn = '0' and A1 = '1' and A0 = '1' and RWn = '1' else false; -- Data register read. + + -- Track register arithmetics controls: + TR_PRES <= '1' when CMD_STATE = T1_SEEK_RESTORE and CMD(7 downto 4) = "0000" else '0'; -- Restore command. + TR_CLR <= '1' when CMD_STATE = T1_HEAD_CTRL and TRACK00n = '0' and DIR = '0' else '0'; + TR_INC <= '1' when CMD_STATE = T1_CHECK_DIR and DELAY = true and DIR = '1' else '0'; + TR_DEC <= '1' when CMD_STATE = T1_CHECK_DIR and DELAY = true and DIR = '0' else '0'; + + -- Sector register arithmetics: + SR_INC <= '1' when CMD_STATE = T2_MULTISECT and CMD(4) = '1' else '0'; -- Multi sector enabled. + SR_LOAD <= '1' when CMD_STATE = T3_LOAD_SR else '0'; + + -- Data register arithmetics controls: + DR_CLR <= '1' when CMD_STATE = T1_SEEK_RESTORE and CMD(7 downto 4) = "0000" else '0'; -- Restore command. + DR_LOAD <= '1' when NEXT_CMD_STATE = T2_LOAD_DATA else -- Write prior to asserting DRQ in T2_LOAD_DATA. + '1' when CMD_STATE = T3_LOAD_DATA_1 else + '1' when CMD_STATE = T3_LOAD_DATA_2 else '0'; + + -- Shift register arithmetics controls: + -- During type I and type II commands all characters are allowed as data. + -- During the type III write track command, there are some special characters + -- which may not appear as normal data. See the register file for more information. + SHFT_LOAD_SD <= '1' when CMD_STATE = T3_LOAD_SHFT else '0'; -- Special data. + SHFT_LOAD_ND <= '1' when CMD_STATE = T1_LOAD_SHFT else + '1' when CMD_STATE = T2_LOAD_SHFT else '0'; -- Normal data. + + P_CRC_PRES: process(RESETn, CLK) + -- CRC preset during write sector and write track commands. + variable LOCK : boolean; + begin + if RESETn = '0' then + CRC_PRES <= '0'; + LOCK := false; + elsif CLK = '1' and CLK' event then + -- In write track command, the CRC is initialised at the beginning of the + -- first A1 data and released during shifting the CRC out. + if CMD_STATE = T2_WR_AM and LOCK = false then + CRC_PRES <= '1'; -- Write sector command. + LOCK := true; + elsif CMD_STATE = T3_LOAD_SHFT and DR = x"F5" and LOCK = false then -- x"F5" means write A1. + CRC_PRES <= '1'; -- Write track command. + LOCK := true; + elsif CMD_STATE = T2_WR_CRC then + CRC_PRES <= '0'; -- Write sector command. + LOCK := false; + elsif CMD_STATE = T3_LOAD_SHFT and DR = x"F7" then + CRC_PRES <= '0'; -- Write track command. + LOCK := false; + else + CRC_PRES <= '0'; + end if; + end if; + end process P_CRC_PRES; + + -- Write control signals: + AM_2_DISK <= '1' when CMD_STATE = T2_WR_AM else '0'; + FF_2_DISK <= '1' when CMD_STATE = T2_WR_FF else '0'; + DSR_2_DISK <= '1' when CMD_STATE = T2_WR_BYTE else + '1' when CMD_STATE = T3_WR_DATA and T3_DATATYPE /= x"F7" else '0'; -- not during CRC. + CRC_2_DISK <= '1' when CMD_STATE = T2_WR_CRC else + '1' when CMD_STATE = T3_WR_DATA and T3_DATATYPE = x"F7" else '0'; + + -- Write precompensation control: + PRECOMP_EN <= '1' when CMD(7 downto 4) = x"A" and CMD(1) = '0' else -- Write single sector. + '1' when CMD(7 downto 4) = x"B" and CMD(1) = '0' else -- Write multiple sector. + '1' when CMD(7 downto 4) = x"F" and CMD(1) = '0' else '0'; -- Write track. + + -- Disk data flow direction: + DISK_RWn <= -- Write sector command: + '0' when CMD_STATE = T2_WR_LEADIN else + '0' when CMD_STATE = T2_WR_AM else + '0' when CMD_STATE = T2_LOAD_SHFT else + '0' when CMD_STATE = T2_WR_BYTE else + '0' when CMD_STATE = T2_VERIFY_DRQ_3 else + '0' when CMD_STATE = T2_DATALOST else + '0' when CMD_STATE = T2_WRSTAT else + '0' when CMD_STATE = T2_WR_CRC else + '0' when CMD_STATE = T2_WR_FF else + -- Write track command: + '0' when CMD_STATE = T3_LOAD_SHFT else + '0' when CMD_STATE = T3_WR_DATA else + '0' when CMD_STATE = T3_CHECK_INDEX_2 else + '0' when CMD_STATE = T3_DATALOST else '1'; +end BEHAVIOR; \ No newline at end of file diff --git a/vhdl/rtl/vhdl/WF_FDC1772_IP/wf1772ip_crc_logic.vhd b/vhdl/rtl/vhdl/WF_FDC1772_IP/wf1772ip_crc_logic.vhd new file mode 100644 index 0000000..6d5e81c --- /dev/null +++ b/vhdl/rtl/vhdl/WF_FDC1772_IP/wf1772ip_crc_logic.vhd @@ -0,0 +1,162 @@ +---------------------------------------------------------------------- +---- ---- +---- WD1772 compatible floppy disk controller IP Core. ---- +---- ---- +---- This file is part of the SUSKA ATARI clone project. ---- +---- http://www.experiment-s.de ---- +---- ---- +---- Description: ---- +---- Floppy disk controller with all features of the Western ---- +---- Digital WD1772-02 controller. ---- +---- ---- +---- The CRC cyclic redundancy checker unit. Further description ---- +---- see below. ---- +---- ---- +---- Working principle of the CRC generator and verify unit: ---- +---- During read operation: ---- +---- The CRC generator is switched on via after the detection of ---- +---- the address ID of the data ID mark. The CRC generation last ---- +---- in case of the address ID until the lenght byte is read. ---- +---- In case of generation after the data address mark the CRC ---- +---- generator is activated until the last data byte is read. ---- +---- The number of data bytes to be read depends on the LENGHT ---- +---- information in the header file. After generation of the CRC ---- +---- the CRC_GEN is switched off and the VERIFY procedure begins ---- +---- by activating CRC_VERIFY. The previously generated CRC is ---- +---- then compared (serially) with the two consecutive read CRC ---- +---- bytes. The CRC error appeas, when the comparision fails. ---- +---- During write operation: ---- +---- The CRC generator is switched on via after the detection of ---- +---- the address ID of the data ID mark. The CRC generation last ---- +---- in case of the address ID until the lenght byte is read. ---- +---- In case of generation after the data address mark the CRC ---- +---- generator is activated until the last data byte is read. ---- +---- The number of data bytes to be read depends on the LENGHT ---- +---- information in the header file. After the generation of the ---- +---- two CRC bytes, the write out process begins by activating ---- +---- CRC_SHFTOUT. The CRC data appears in this case serially on ---- +---- the CRC_SDOUT. ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2006 - 2011 Wolfgang Foerster ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.gnu.org/licenses/lgpl.html ---- +---- ---- +---------------------------------------------------------------------- +-- +-- Revision History +-- +-- Revision 2006A 2006/06/03 WF +-- Initial Release. +-- Revision 2K6B 2006/11/05 WF +-- Modified Source to compile with the Xilinx ISE. +-- Revision 2K8A 2008/07/14 WF +-- Minor changes. +-- Revision 2K9A 2009/06/20 WF +-- CRC_SHIFT has now synchronous reset to meeet preset behaviour. +-- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + +entity WF1772IP_CRC_LOGIC is + port( + -- System control + CLK : in bit; + RESETn : in bit; + DISK_RWn : in bit; + + -- Preset controls: + DDEn : in bit; + ID_AM : in bit; + DATA_AM : in Bit; + DDATA_AM : in Bit; + + -- CRC unit: + SD : in bit; -- Serial data input. + CRC_STRB : in bit; -- Data strobe. + CRC_2_DISK : in bit; -- Forces the unit to flush the CRC remainder. + CRC_PRES : in bit; -- Presets the CRC unit during write to disk. + CRC_SDOUT : out bit; -- Serial data output. + CRC_ERR : out bit -- Indicates CRC error. + ); +end WF1772IP_CRC_LOGIC; + +architecture BEHAVIOR of WF1772IP_CRC_LOGIC is +signal CRC_SHIFT : bit_vector(15 downto 0); +begin + P_CRC: process + -- The shift register is initialised with appropriate values in HD or DD mode. + -- In theory the shift register should be preset to ones. Due to a latency of one byte + -- in FM mode or 4 bytes in MFM mode it is necessary to preset the shift register with + -- the CRC values of this ID address mark, data address mark and the A1 sync bytes. The + -- latency is caused by the addressmark detector which needs one or 4 byte time(s) for + -- detection. The CRC unit therefore starts with every detection of an address mark and + -- ends if the CRC unit is flushed. + begin + wait until CLK = '1' and CLK' event; + if RESETn = '0' then + CRC_SHIFT <= (others => '1'); + elsif CRC_2_DISK = '1' then + if CRC_STRB = '1' then + CRC_SHIFT <= CRC_SHIFT(14 downto 0) & '0'; + end if; + elsif CRC_PRES = '1' then -- Preset during write sector or write track command. + CRC_SHIFT <= x"FFFF"; + elsif DDEn = '1' and ID_AM = '1' then -- DD mode and ID address mark detected. + CRC_SHIFT <= x"EF21"; -- The CRC-CCITT for data x"FE" is x"EF21" + elsif DDEn = '1' and DATA_AM = '1' then -- DD mode and data address mark detected. + CRC_SHIFT <= x"BF84"; -- The CRC-CCITT for data x"FB" is x"BF84" + elsif DDEn = '1' and DDATA_AM = '1' then -- DD mode and deleted data address mark detected. + CRC_SHIFT <= x"8FE7"; -- The CRC-CCITT for data x"F8" is x"8FE7" + elsif DDEn = '0' and ID_AM = '1' then -- HD mode and ID address mark detected. + CRC_SHIFT <= x"B230"; -- The CRC-CCITT for data x"A1A1A1FE" is x"B230" + elsif DDEn = '0' and DATA_AM = '1' then -- HD mode and data address mark detected. + CRC_SHIFT <= x"E295"; -- The CRC-CCITT for data x"A1A1A1FB" is x"E295" + elsif DDEn = '0' and DDATA_AM = '1' then -- HD mode and deleted data address mark detected. + CRC_SHIFT <= x"D2F6"; -- The CRC-CCITT for data x"A1A1A1F8" is x"D2F6" + elsif CRC_STRB = '1' then + -- CRC-CCITT (xFFFF): + -- the polynomial is G(x) = x^16 + x^12 + x^5 + 1 + -- In this mode the CRC is encoded. In read from disk mode, the encoding works as CRC + -- verification. In this operating condition the ID or the data field is compared + -- against the CRC checksum. if there are no errors, the shift register's value is + -- x"0000" after the last bit of the checksum is shifted in. In write to disk mode the + -- CRC linear feedback shift register (lfsr) works to generate the CRC remainder of the + -- ID or data field. + CRC_SHIFT <= CRC_SHIFT(14 downto 12) & (CRC_SHIFT(15) xor CRC_SHIFT(11) xor SD) & + CRC_SHIFT(10 downto 5) & (CRC_SHIFT(15) xor CRC_SHIFT(4) xor SD) & + CRC_SHIFT(3 downto 0) & (CRC_SHIFT(15) xor SD); + end if; + end process P_CRC; + + CRC_SDOUT <= CRC_SHIFT(15); + CRC_ERR <= '0' when CRC_SHIFT = x"0000" else '1'; +end architecture BEHAVIOR; diff --git a/vhdl/rtl/vhdl/WF_FDC1772_IP/wf1772ip_digital_pll.vhd b/vhdl/rtl/vhdl/WF_FDC1772_IP/wf1772ip_digital_pll.vhd new file mode 100644 index 0000000..872ff95 --- /dev/null +++ b/vhdl/rtl/vhdl/WF_FDC1772_IP/wf1772ip_digital_pll.vhd @@ -0,0 +1,426 @@ +---------------------------------------------------------------------- +---- ---- +---- WD1772 compatible floppy disk controller IP Core. ---- +---- ---- +---- This file is part of the SUSKA ATARI clone project. ---- +---- http://www.experiment-s.de ---- +---- ---- +---- Description: ---- +---- Floppy disk controller with all features of the Western ---- +---- Digital WD1772-02 controller. ---- +---- ---- +---- The digital PLL is responsible to detect the incoming serial ---- +---- data stream and provide a system clock synchronous signal ---- +---- containing the data and clock information. ---- +---- To understand how the code works in detail refer to the free ---- +---- US patent no. 4,780,844. ---- +---- ---- +---- Attention: The settings for TOP and BOTTOM, which control ---- +---- the PLL frequency and for PHASE_CORR which control the PLL ---- +---- phase are rather critical for a good read condition! To test ---- +---- the PLL in the WD1772 compatible core do the following: ---- +---- Sample on an oscilloscope on one channel the falling edge of ---- +---- the RDn pulse and on the other channel the PLL_DSTRB. The ---- +---- RDn must be located exactly between the PLL_DSTRB pulses. ---- +---- Otherwise, the parameters TOP, BOTTOM and PHASE_CORR have to ---- +---- be optimized. ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2006 - 2011 Wolfgang Foerster ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.gnu.org/licenses/lgpl.html ---- +---- ---- +---------------------------------------------------------------------- +-- +-- Revision History +-- +-- Revision 2006A 2006/06/03 WF +-- Initial Release: the MFM portion for HD and DD floppies is tested. +-- The FM mode (DDEn = '1') is not completely tested due to lack of FM +-- drives. +-- Revision 2K6B 2006/11/05 WF +-- Modified Source to compile with the Xilinx ISE. +-- Revision 2K7B 2006/12/29 WF +-- Introduced several improvements based on a very good examination +-- of the pll code by Jean Louis-Guerin. +-- Revision 2K8A 2008/07/14 WF +-- Minor changes. +-- Revision 2K8B 2008/12/24 WF +-- Improvement of the INPORT process. +-- Bugfix of the FREQ_AMOUNT counter: now stops if its value is zero. +-- Several changes concerning the PLL parameters to improve the +-- stability of the PLL. +-- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + +entity WF1772IP_DIGITAL_PLL is + generic( + -- The valid range of the period counter of the PLL is given by the TOP and BOTTOM + -- limits. The counter range is therefore BOTTOM <= counter value <= TOP. + -- The generic PHASE_CORR is responsible fo the center setting of PLL_DSTRB concerning + -- the RDn period. + -- The nominal frequency setting is 128. So it is recommended to use TOP and BOTTOM + -- settings symmetrically around 128. If TOP = BOTTOM = 128, the frequency control + -- is disabled. TOP + PHASE_CORR may not exceed a value of 255. BOTTOM - PHASE_CORR + -- may not drop below zero. + TOP : integer range 0 to 255 := 152; -- +18.0% + BOTTOM : integer range 0 to 255 := 104; -- -18.0% + PHASE_CORR : integer range 0 to 128 := 75 + ); + port( + -- System control + CLK : in bit; -- 16MHz clock. + RESETn : in bit; + + -- Controls + DDEn : in bit; -- Double density enable. + HDTYPE : in bit; -- This control is '1' when HD disks are inserted. + DISK_RWn : in bit; -- Read write control. + + -- Data and clock lines + RDn : in bit; -- Read signal from the disk. + PLL_D : out bit; -- Synchronous read signal. + PLL_DSTRB : out bit -- Read strobe. + ); +end WF1772IP_DIGITAL_PLL; + +architecture BEHAVIOR of WF1772IP_DIGITAL_PLL is +signal RD_In : bit; +signal UP, DOWN : bit; +signal PHASE_DECREASE : bit; +signal PHASE_INCREASE : bit; +signal HI_STOP, LOW_STOP : bit; +signal PER_CNT : std_logic_vector(7 downto 0); +signal ADDER_IN : std_logic_vector(7 downto 0); +signal ADDER_MSBs : bit_vector(2 downto 0); +signal RD_PULSE : bit; +signal ROLL_OVER : bit; +signal HISTORY_REG : bit_vector(1 downto 0); +signal ERROR_HISTORY : integer range 0 to 2; +begin + INPORT: process + -- This process is necessary due to the poor quality of the rising + -- edge of RDn. Let it work on the negative clock edge. + begin + wait until CLK = '0' and CLK' event; + RD_In <= RDn; + end process INPORT; + + EDGEDETECT: process(RESETn, CLK) + -- This process forms a falling edge detector for the incoming + -- data read port. The output (RD_PULSE) goes high for exactly + -- one clock period after the RDn is low and the positive + -- clock edge is detected. + variable LOCK : boolean; + begin + if RESETn = '0' then + RD_PULSE <= '0'; + LOCK := false; + elsif CLK = '1' and CLK' event then + if DISK_RWn = '0' then -- Disable detector in write mode. + RD_PULSE <= '0'; + elsif RD_In = '0' and LOCK = false then + RD_PULSE <= '1'; -- READ_PULSE is inverted against RDn + LOCK := true; + elsif RD_In = '1' then + LOCK := false; + RD_PULSE <= '0'; + else + RD_PULSE <= '0'; + end if; + end if; + end process EDGEDETECT; + + PERIOD_CNT: process(RESETn, CLK) + -- This process provides the nominal variable added to the adder. To achieve a good + -- settling time of the PLL in all cases, the period counter is controlled via the DDEn + -- and HDTYPE flags respective to its added value. Be aware, that in case of adding "10" + -- or "11", the TOP value may be exceeded or the period counter may drop below the BOTTOM + -- value. The higher the value added, the faster will be the settling time of phase locked + -- loop . + begin + if RESETn = '0' then + PER_CNT <= "10000000"; -- Initial value is 128. + elsif CLK = '1' and CLK' event then + if UP = '1' then + PER_CNT <= PER_CNT + '1'; + elsif DOWN = '1' then + PER_CNT <= PER_CNT - '1'; + end if; + end if; + end process PERIOD_CNT; + + HI_STOP <= '1' when PER_CNT >= TOP else '0'; + LOW_STOP <= '1' when PER_CNT <= BOTTOM else '0'; + + ADDER_IN <= -- This DISK_RWn = '0' implementation keeps the last phase information + -- of the PLL in read from disk mode. It should be a good solution concer- + -- ning alternative read write cycles. + "10000000" when DISK_RWn = '0' else -- Nominal value for write to disk. + PER_CNT + PHASE_CORR when PHASE_INCREASE = '1' else -- Phase lags. + PER_CNT - PHASE_CORR when PHASE_DECREASE = '1' else -- Phase leeds. + PER_CNT; -- No phase correction; + + ADDER: process(RESETn, CLK, DDEn, HDTYPE) + -- Clock adjustment: The clock cycle is 62.5ns for the 16MHz system clock. + -- The offset (LSBs) of the adder input is chosen to be conform with the required + -- rollover period in the different DDEn and HDTYPE modi as follows: + -- With a nominal adder input term of 128: + -- The adder rolls over every 4us for DDEn = 1 and HDTYPE = 0. + -- The adder rolls over every 2us for DDEn = 1 and HDTYPE = 1. + -- The adder rolls over every 2us for DDEn = 0 and HDTYPE = 0. + -- The adder rolls over every 1us for DDEn = 0 and HDTYPE = 1. + -- The given times are the half of a data period time in MFM or FM. + variable ADDER_DATA : std_logic_vector(12 downto 0); + begin + if RESETn = '0' then + ADDER_DATA := (others => '0'); + elsif CLK = '1' and CLK' event then + ADDER_DATA := ADDER_DATA + ADDER_IN; + end if; + -- + case DDEn & HDTYPE is + when "01" => -- MFM mode using HD disks, results in 1us inspection period: + ADDER_MSBs <= To_BitVector(ADDER_DATA(10 downto 8)); + when "00" => -- MFM mode using DD disks, results in 2us inspection period: + ADDER_MSBs <= To_BitVector(ADDER_DATA(11 downto 9)); + when "11" => -- FM mode using HD disks, results in 2us inspection period: + ADDER_MSBs <= To_BitVector(ADDER_DATA(11 downto 9)); + when "10" => -- FM mode using DD disks, results in 4us inspection period: + ADDER_MSBs <= To_BitVector(ADDER_DATA(12 downto 10)); + end case; + end process ADDER; + + ROLLOVER: process(RESETn, CLK) + -- This process forms a falling edge detector for the detection + -- of the adder's rollover time. The output goes low for exactly + -- one clock period after the rollover is detected and the positive + -- clock edge appears. + variable LOCK : boolean; + begin + if RESETn = '0' then + ROLL_OVER <= '0'; + LOCK := false; + elsif CLK = '1' and CLK' event then + if ADDER_MSBs /= "111" and LOCK = false then + ROLL_OVER <= '1'; + LOCK := true; + elsif ADDER_MSBs = "111" then + LOCK := false; + ROLL_OVER <= '0'; + else + ROLL_OVER <= '0'; + end if; + end if; + end process ROLLOVER; + PLL_DSTRB <= ROLL_OVER; + + DATA_FLIP_FLOP: process(RESETn, CLK, RD_PULSE) + -- This flip-flop is responsible for 'catching' the read pulses of the + -- serial data input. + begin + if RESETn = '0' then + PLL_D <= '0'; -- Asynchronous reset. + elsif CLK = '1' and CLK' event then + if RD_PULSE = '1' then + PLL_D <= '1'; -- Read pulse detected. + elsif ROLL_OVER = '1' then + PLL_D <= '0'; + end if; + end if; + end process DATA_FLIP_FLOP; + + WIN_HISTORY: process(RESETn, CLK) + begin + if RESETn = '0' then + HISTORY_REG <= "00"; + elsif CLK = '1' and CLK' event then + if RD_PULSE = '1' then + HISTORY_REG <= ADDER_MSBs(2) & HISTORY_REG(1); + end if; + end if; + end process WIN_HISTORY; + + -- Error history: + -- This signal indicates the number of consequtive levels of the adder's + -- MSB and the history register as shown in the following table. The default + -- setting of 0 was added to compile with the Xilinx ISE. + ERROR_HISTORY <= 2 when ADDER_MSBs(2) = '0' and HISTORY_REG = "00" else -- Speed strongly up. + 1 when ADDER_MSBs(2) = '0' and HISTORY_REG = "01" else -- Speed up. + 0 when ADDER_MSBs(2) = '0' and HISTORY_REG = "10" else -- o.k. + 0 when ADDER_MSBs(2) = '0' and HISTORY_REG = "11" else -- Now adjusted. + 0 when ADDER_MSBs(2) = '1' and HISTORY_REG = "00" else -- Now adjusted. + 0 when ADDER_MSBs(2) = '1' and HISTORY_REG = "01" else -- o.k. + 1 when ADDER_MSBs(2) = '1' and HISTORY_REG = "10" else -- Slow down. + 2 when ADDER_MSBs(2) = '1' and HISTORY_REG = "11" else 0; -- Slow strongly down. + + FREQUENCY_DECODER: process(RESETn, CLK, HI_STOP, LOW_STOP) + -- The frequency decoder controls the period of the data inspection window respective to the + -- ERROR_HISTORY for the 11 bit adder is as follows: + -- ERROR_HISTORY = 0: + -- -> no correction necessary <- + -- ERROR_HISTORY = 1: + -- MSBs input: 7 6 5 4 3 2 1 0 + -- Correction output: -3 -2 -1 0 0 +1 +2 +3 + -- ERROR_HISTORY = 2: + -- MSBs input: 7 6 5 4 3 2 1 0 + -- Correction output: -4 -3 -2 -1 +1 +2 +3 +4 + -- The most significant bit of the FREQ_AMOUNT controls incrementation or decrementation + -- of the adder (0 is up). + variable FREQ_AMOUNT: std_logic_vector(3 downto 0); + begin + if RESETn = '0' then + FREQ_AMOUNT := "0000"; + elsif CLK = '1' and CLK' event then + if RD_PULSE = '1' then -- Load the frequency amount register. + case ERROR_HISTORY is + when 2 => + case ADDER_MSBs is + when "000" => FREQ_AMOUNT := "0100"; + when "001" => FREQ_AMOUNT := "0011"; + when "010" => FREQ_AMOUNT := "0010"; + when "011" => FREQ_AMOUNT := "0001"; + when "100" => FREQ_AMOUNT := "1001"; + when "101" => FREQ_AMOUNT := "1010"; + when "110" => FREQ_AMOUNT := "1011"; + when "111" => FREQ_AMOUNT := "1100"; + end case; + when 1 => + case ADDER_MSBs is + when "000" => FREQ_AMOUNT := "0011"; + when "001" => FREQ_AMOUNT := "0010"; + when "010" => FREQ_AMOUNT := "0001"; + when "011" => FREQ_AMOUNT := "0000"; + when "100" => FREQ_AMOUNT := "1000"; + when "101" => FREQ_AMOUNT := "1001"; + when "110" => FREQ_AMOUNT := "1010"; + when "111" => FREQ_AMOUNT := "1011"; + end case; + when others => + FREQ_AMOUNT := "0000"; + end case; + elsif FREQ_AMOUNT(2 downto 0) > "000" then + FREQ_AMOUNT := FREQ_AMOUNT - '1'; -- Modify the frequency amount register. + end if; + end if; + -- + if FREQ_AMOUNT(3) = '0' and FREQ_AMOUNT(2 downto 0) /= "000" and HI_STOP = '0' then + -- FREQ_AMOUNT(3) = '0' means Frequency is too low. Count up when counter is not at HI_STOP. + UP <= '1'; + DOWN <= '0'; + elsif FREQ_AMOUNT(3) = '1' and FREQ_AMOUNT (2 downto 0) /= "000" and LOW_STOP = '0' then + -- FREQ_AMOUNT(3) = '1' means Frequency is too high. Count down when counter is not at LOW_STOP. + UP <= '0'; + DOWN <= '1'; + else + UP <= '0'; + DOWN <= '0'; + end if; + end process FREQUENCY_DECODER; + + PHASE_DECODER: process(RESETn, CLK) + -- The phase decoder depends on the value of ADDER_MSBs. If the phase leeds, the most significant bit + -- of PHASE_AMOUNT indicates with a '0', that the next rollover should appear earlier. In case of a + -- phase lag, the next rollover should come later (indicated by a '1' of the most significant bit of + -- PHASE_AMOUNT). + -- This implementation gives the freedom to adjust the phase amount individually for every mode + -- depending on DDEn and HDTYPE. + variable PHASE_AMOUNT: std_logic_vector(5 downto 0); + begin + if RESETn = '0' then + PHASE_AMOUNT := "000000"; + elsif CLK = '1' and CLK' event then + if RD_PULSE = '1' and DDEn = '1' and HDTYPE = '0' then -- FM mode, single density. + case ADDER_MSBs is -- Multiplier: 4. + when "000" => PHASE_AMOUNT := "010000"; + when "001" => PHASE_AMOUNT := "001101"; + when "010" => PHASE_AMOUNT := "001000"; + when "011" => PHASE_AMOUNT := "000100"; + when "100" => PHASE_AMOUNT := "100100"; + when "101" => PHASE_AMOUNT := "101000"; + when "110" => PHASE_AMOUNT := "101100"; + when "111" => PHASE_AMOUNT := "110000"; + end case; + elsif RD_PULSE = '1' and DDEn = '1' and HDTYPE = '1' then -- FM mode, double density + case ADDER_MSBs is -- Multiplier: 2. + when "000" => PHASE_AMOUNT := "001000"; + when "001" => PHASE_AMOUNT := "000110"; + when "010" => PHASE_AMOUNT := "000100"; + when "011" => PHASE_AMOUNT := "000010"; + when "100" => PHASE_AMOUNT := "100010"; + when "101" => PHASE_AMOUNT := "100100"; + when "110" => PHASE_AMOUNT := "100110"; + when "111" => PHASE_AMOUNT := "101000"; + end case; + elsif RD_PULSE = '1' and DDEn = '0' and HDTYPE = '0' then -- MFM mode, single density + case ADDER_MSBs is -- Multiplier: 2. + when "000" => PHASE_AMOUNT := "000110"; + when "001" => PHASE_AMOUNT := "000100"; + when "010" => PHASE_AMOUNT := "000011"; + when "011" => PHASE_AMOUNT := "000010"; + when "100" => PHASE_AMOUNT := "100010"; + when "101" => PHASE_AMOUNT := "100011"; + when "110" => PHASE_AMOUNT := "100100"; + when "111" => PHASE_AMOUNT := "100110"; + end case; + elsif RD_PULSE = '1' and DDEn = '0' and HDTYPE = '1' then -- MFM mode, double density. + case ADDER_MSBs is -- Multiplier: 1. + when "000" => PHASE_AMOUNT := "000100"; + when "001" => PHASE_AMOUNT := "000011"; + when "010" => PHASE_AMOUNT := "000010"; + when "011" => PHASE_AMOUNT := "000001"; + when "100" => PHASE_AMOUNT := "100001"; + when "101" => PHASE_AMOUNT := "100010"; + when "110" => PHASE_AMOUNT := "100011"; + when "111" => PHASE_AMOUNT := "100100"; + end case; + else -- Modify phase amount register: + if PHASE_AMOUNT(4 downto 0) > x"0" then + PHASE_AMOUNT := PHASE_AMOUNT - 1; + end if; + end if; + end if; + -- + if PHASE_AMOUNT(5) = '0' and PHASE_AMOUNT(4 downto 0) > x"0" then + -- PHASE_AMOUNT(5) = '0' means, that the phase leeds. + PHASE_INCREASE <= '1'; -- Speed phase up, accelerate next rollover. + PHASE_DECREASE <= '0'; + elsif PHASE_AMOUNT(5) = '1' and PHASE_AMOUNT(4 downto 0) > x"0" then + -- PHASE_AMOUNT(5) = '1' means, that the phase lags. + PHASE_INCREASE <= '0'; + PHASE_DECREASE <= '1'; -- Speed phase down, delay of next rollover. + else + PHASE_INCREASE <= '0'; + PHASE_DECREASE <= '0'; + end if; + end process PHASE_DECODER; +end architecture BEHAVIOR; \ No newline at end of file diff --git a/vhdl/rtl/vhdl/WF_FDC1772_IP/wf1772ip_pkg.vhd b/vhdl/rtl/vhdl/WF_FDC1772_IP/wf1772ip_pkg.vhd new file mode 100644 index 0000000..d690ca7 --- /dev/null +++ b/vhdl/rtl/vhdl/WF_FDC1772_IP/wf1772ip_pkg.vhd @@ -0,0 +1,232 @@ +---------------------------------------------------------------------- +---- ---- +---- WD1772 compatible floppy disk controller IP Core. ---- +---- ---- +---- This file is part of the SUSKA ATARI clone project. ---- +---- http://www.experiment-s.de ---- +---- ---- +---- Description: ---- +---- Floppy disk controller with all features of the Western ---- +---- Digital WD1772-02 controller. ---- +---- ---- +---- This is the package file containing the component ---- +---- declarations. ---- +---- ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2006 - 2011 Wolfgang Foerster ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.gnu.org/licenses/lgpl.html ---- +---- ---- +---------------------------------------------------------------------- +-- +-- Revision History +-- +-- Revision 2006A 2006/06/03 WF +-- Initial Release. +-- Revision 2K6B 2006/11/05 WF +-- Modified Source to compile with the Xilinx ISE. +-- Revision 2K8A 2008/07/14 WF +-- Minor changes. +-- Removed CRC_BUSY. + + +library ieee; +use ieee.std_logic_1164.all; + +package WF1772IP_PKG is +-- component declarations: +component WF1772IP_AM_DETECTOR + port( + CLK : in bit; + RESETn : in bit; + DDEn : in bit; + DATA : in bit; + DATA_STRB : in bit; + ID_AM : out bit; + DATA_AM : out bit; + DDATA_AM : out bit + ); +end component; + +component WF1772IP_CONTROL + port( + CLK : in bit; + RESETn : in bit; + A1, A0 : in bit; + RWn : in bit; + CSn : in bit; + DDEn : in bit; + DR : in bit_vector(7 downto 0); + CMD : in std_logic_vector(7 downto 0); + DSR : in std_logic_vector(7 downto 0); + TR : in std_logic_vector(7 downto 0); + SR : in std_logic_vector(7 downto 0); + MO : out bit; + WR_PR : out bit; + SPINUP_RECTYPE : out bit; + SEEK_RNF : out bit; + CRC_ERRFLAG : out bit; + LOST_DATA_TR00 : out bit; + DRQ : out bit; + DRQ_IPn : out bit; + BUSY : out bit; + AM_2_DISK : out bit; + ID_AM : in bit; + DATA_AM : in bit; + DDATA_AM : in bit; + CRC_ERR : in bit; + CRC_PRES : out bit; + TR_PRES : out bit; + TR_CLR : out bit; + TR_INC : out bit; + TR_DEC : out bit; + SR_LOAD : out bit; + SR_INC : out bit; + TRACK_NR : out std_logic_vector(7 downto 0); + DR_CLR : out bit; + DR_LOAD : out bit; + SHFT_LOAD_SD : out bit; + SHFT_LOAD_ND : out bit; + CRC_2_DISK : out bit; + DSR_2_DISK : out bit; + FF_2_DISK : out bit; + PRECOMP_EN : out bit; + DATA_STRB : in bit; + DISK_RWn : out bit; + WPRTn : in bit; + TRACK00n : in bit; + IPn : in bit; + DIRC : out bit; + STEP : out bit; + WG : out bit; + INTRQ : out bit + ); +end component; + +component WF1772IP_CRC_LOGIC + port( + CLK : in bit; + RESETn : in bit; + DDEn : in bit; + DISK_RWn : in bit; + ID_AM : in bit; + DATA_AM : in bit; + DDATA_AM : in bit; + SD : in bit; + CRC_STRB : in bit; + CRC_2_DISK : in bit; + CRC_PRES : in bit; + CRC_SDOUT : out bit; + CRC_ERR : out bit + ); +end component; + +component WF1772IP_DIGITAL_PLL + port( + CLK : in bit; + RESETn : in bit; + DDEn : in bit; + HDTYPE : in bit; + DISK_RWn : in bit; + RDn : in bit; + PLL_D : out bit; + PLL_DSTRB : out bit + ); +end component; + +component WF1772IP_REGISTERS + port( + CLK : in bit; + RESETn : in bit; + CSn : in bit; + ADR : in bit_vector(1 downto 0); + RWn : in bit; + DATA_IN : in std_logic_vector (7 downto 0); + DATA_OUT : out std_logic_vector (7 downto 0); + DATA_EN : out bit; + CMD : out std_logic_vector(7 downto 0); + SR : out std_logic_vector(7 downto 0); + TR : out std_logic_vector(7 downto 0); + DSR : out std_logic_vector(7 downto 0); + DR : out bit_vector(7 downto 0); + SD_R : in bit; + DATA_STRB : in bit; + DR_CLR : in bit; + DR_LOAD : in bit; + TR_PRES : in bit; + TR_CLR : in bit; + TR_INC : in bit; + TR_DEC : in bit; + TRACK_NR : in std_logic_vector(7 downto 0); + SR_LOAD : in bit; + SR_INC : in bit; + SHFT_LOAD_SD : in bit; + SHFT_LOAD_ND : in bit; + MOTOR_ON : in bit; + WRITE_PROTECT : in bit; + SPINUP_RECTYPE : in bit; + SEEK_RNF : in bit; + CRC_ERRFLAG : in bit; + LOST_DATA_TR00 : in bit; + DRQ : in bit; + DRQ_IPn : in bit; + BUSY : in bit; + DDEn : in bit + ); +end component; + +component WF1772IP_TRANSCEIVER + port( + CLK : in bit; + RESETn : in bit; + DDEn : in bit; + HDTYPE : in bit; + ID_AM : in bit; + DATA_AM : in bit; + DDATA_AM : in bit; + SHFT_LOAD_SD : in bit; + DR : in bit_vector(7 downto 0); + PRECOMP_EN : in bit; + AM_TYPE : in bit; + AM_2_DISK : in bit; + CRC_2_DISK : in bit; + DSR_2_DISK : in bit; + FF_2_DISK : in bit; + SR_SDOUT : in std_logic; + CRC_SDOUT : in bit; + WRn : out bit; + PLL_DSTRB : in bit; + PLL_D : in bit; + WDATA : out bit; + DATA_STRB : out bit; + SD_R : out bit + ); +end component; +end WF1772IP_PKG; diff --git a/vhdl/rtl/vhdl/WF_FDC1772_IP/wf1772ip_registers.vhd b/vhdl/rtl/vhdl/WF_FDC1772_IP/wf1772ip_registers.vhd new file mode 100644 index 0000000..a593c01 --- /dev/null +++ b/vhdl/rtl/vhdl/WF_FDC1772_IP/wf1772ip_registers.vhd @@ -0,0 +1,264 @@ +---------------------------------------------------------------------- +---- ---- +---- WD1772 compatible floppy disk controller IP Core. ---- +---- ---- +---- This file is part of the SUSKA ATARI clone project. ---- +---- http://www.experiment-s.de ---- +---- ---- +---- Description: ---- +---- Floppy disk controller with all features of the Western ---- +---- Digital WD1772-02 controller. ---- +---- ---- +---- This file models all the five WD1772 registers: DATA-, ---- +---- COMMAND-, SECTOR-, TRACK- and STATUS register as also the ---- +---- shift register. ---- +---- ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2006 - 2011 Wolfgang Foerster ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.gnu.org/licenses/lgpl.html ---- +---- ---- +---------------------------------------------------------------------- +-- +-- Revision History +-- +-- Revision 2006A 2006/06/03 WF +-- Initial Release. +-- Revision 2K6B 2006/11/05 WF +-- Modified Source to compile with the Xilinx ISE. +-- Revision 2K8A 2008/07/14 WF +-- Minor changes. +-- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + +entity WF1772IP_REGISTERS is + port( + -- System control: + CLK : in bit; + RESETn : in bit; + + -- Bus interface: + CSn : in bit; + ADR : in bit_vector(1 downto 0); + RWn : in bit; + DATA_IN : in std_logic_vector (7 downto 0); + DATA_OUT : out std_logic_vector (7 downto 0); + DATA_EN : out bit; + + -- FDC data: + CMD : out std_logic_vector(7 downto 0); -- Command register. + SR : out std_logic_vector(7 downto 0); -- Sector register. + TR : out std_logic_vector(7 downto 0); -- Track register. + DSR : out std_logic_vector(7 downto 0); -- Data shift register. + DR : out bit_vector(7 downto 0); -- Data register. + + -- Serial data and clock strobes (in and out): + DATA_STRB : in bit; -- Strobe for the incoming data. + SD_R : in bit; -- Serial data input. + + -- DATA register control: + DR_CLR : in bit; -- Clear. + DR_LOAD : in bit; -- LOAD. + + -- Track register controls: + TR_PRES : in bit; -- Set x"FF". + TR_CLR : in bit; -- Clear. + TR_INC : in bit; -- Increment. + TR_DEC : in bit; -- Decrement. + + -- Sector register control: + TRACK_NR : in std_logic_vector(7 downto 0); + SR_LOAD : in bit; -- Load. + SR_INC : in bit; -- Increment. + + -- Shift register control: + SHFT_LOAD_SD : in bit; + SHFT_LOAD_ND : in bit; + + -- Status register stuff + MOTOR_ON : in bit; + WRITE_PROTECT : in bit; + SPINUP_RECTYPE : in bit; -- Disk is on speed / data mark status. + SEEK_RNF : in bit; -- Seek error / record not found status flag. + CRC_ERRFLAG : in bit; -- CRC status flag. + LOST_DATA_TR00 : in bit; + DRQ : in bit; + DRQ_IPn : in bit; + BUSY : in bit; + + -- Others: + DDEn : in bit + ); +end WF1772IP_REGISTERS; + +architecture BEHAVIOR of WF1772IP_REGISTERS is +-- Remark: In the original data sheet 'WD17X-00' there is the following statement: +-- "After any register is written to, the same register cannot be read from until +-- 16us in MFM or 32us in FMMM have elapsed." If this is a hint for a hardware read +-- lock ... this lock is not implemented in this code. +signal SHIFT_REG : std_logic_vector(7 downto 0); +signal DATA_REG : std_logic_vector(7 downto 0); +signal COMMAND_REG : std_logic_vector(7 downto 0); +signal SECTOR_REG : std_logic_vector(7 downto 0); +signal TRACK_REG : std_logic_vector(7 downto 0); +signal STATUS_REG : bit_vector(7 downto 0); +signal SD_R_I : std_logic; +begin + -- Type conversion To_Std_Logic: + SD_R_I <= '1' when SD_R = '1' else '0'; + + P_SHIFTREG: process(RESETn, CLK) + begin + if RESETn = '0' then + SHIFT_REG <= x"00"; + elsif CLK = '1' and CLK' event then + if SHFT_LOAD_ND = '1' then + SHIFT_REG <= DATA_REG; -- Load data register stuff. + elsif SHFT_LOAD_SD = '1' and DDEn = '1' then + SHIFT_REG <= DATA_REG; -- Normal data in FM mode. + elsif SHFT_LOAD_SD = '1' and DDEn = '0' then -- MFM mode: + case DATA_REG is + when x"F5" => SHIFT_REG <= x"A1"; -- Special character. + when x"F6" => SHIFT_REG <= x"C2"; -- Special character. + when others => SHIFT_REG <= DATA_REG; -- Normal MFM data. + end case; + elsif DATA_STRB = '1' then -- Shift left during read from disk or write to disk. + SHIFT_REG <= SHIFT_REG(6 downto 0) & SD_R_I; -- for write operation SD_R_I is a dummy. + end if; + end if; + end process P_SHIFTREG; + DSR <= SHIFT_REG; + + DATAREG: process(RESETn, CLK) + begin + if RESETn = '0' then + DATA_REG <= x"00"; + elsif CLK = '1' and CLK' event then + if CSn = '0' and ADR = "11" and RWn = '0' then + DATA_REG <= DATA_IN; -- Write bus data to register + elsif DR_LOAD = '1' and DRQ = '0' then + DATA_REG <= SHIFT_REG; -- Correct data loaded to shift register. + elsif DR_LOAD = '1' and DRQ = '1' then + DATA_REG <= x"00"; -- Dummy byte due to lost data loaded to shift register. + elsif DR_CLR = '1' then + DATA_REG <= (others => '0'); + end if; + end if; + end process DATAREG; + -- Data register buffered for further data processing. + DR <= To_BitVector(DATA_REG); + + SECTORREG: process(RESETn, CLK) + begin + if RESETn = '0' then + SECTOR_REG <= x"00"; + elsif CLK = '1' and CLK' event then + if CSn = '0' and ADR = "10" and RWn = '0' and BUSY = '0' then + SECTOR_REG <= DATA_IN; -- Write to register when device is not busy. + elsif SR_LOAD = '1' then + -- Load the track number to the sector register in the type III command + -- 'Read Address'. + SECTOR_REG <= TRACK_NR; + elsif SR_INC = '1' then + SECTOR_REG <= SECTOR_REG + '1'; + end if; + end if; + end process SECTORREG; + SR <= SECTOR_REG; + + TRACKREG: process(RESETn, CLK) + begin + if RESETn = '0' then + TRACK_REG <= x"00"; + elsif CLK = '1' and CLK' event then + if CSn = '0' and ADR = "01" and RWn = '0' and BUSY = '0' then + TRACK_REG <= DATA_IN; -- Write to register when device is busy. + elsif TR_PRES = '1' then + TRACK_REG <= (others => '1'); -- Preset the track register. + elsif TR_CLR = '1' then + TRACK_REG <= (others => '0'); -- Reset the track register. + elsif TR_INC = '1' then + TRACK_REG <= TRACK_REG + '1'; -- Increment register contents. + elsif TR_DEC = '1' then + TRACK_REG <= TRACK_REG - '1'; -- Decrement register contents. + end if; + end if; + end process TRACKREG; + TR <= TRACK_REG; + + COMMANDREG: process(RESETn, CLK) + -- The command register is write only. + begin + if RESETn = '0' then + COMMAND_REG <= x"00"; + elsif CLK = '1' and CLK' event then + if CSn = '0' and ADR = "00" and RWn = '0' and BUSY = '0' then + COMMAND_REG <= DATA_IN; -- Write to register when device is not busy. + -- Write 'force interrupt' to register even when device is busy: + elsif CSn = '0' and ADR = "00" and RWn = '0' and DATA_IN(7 downto 4) = x"D" then + COMMAND_REG <= DATA_IN; + end if; + end if; + end process COMMANDREG; + CMD <= COMMAND_REG; + + STATUSREG: process(RESETn, CLK) + -- The status register is read only to the data bus. + begin + -- Status register wiring: + if RESETn = '0' then + STATUS_REG <= x"00"; + elsif CLK = '1' and CLK' event then + STATUS_REG(7) <= MOTOR_ON; + STATUS_REG(6) <= WRITE_PROTECT; + STATUS_REG(5) <= SPINUP_RECTYPE; + STATUS_REG(4) <= SEEK_RNF; + STATUS_REG(3) <= CRC_ERRFLAG; + STATUS_REG(2) <= LOST_DATA_TR00; + STATUS_REG(1) <= DRQ_IPn; + STATUS_REG(0) <= BUSY; + end if; + end process STATUSREG; + -- Read from track, sector or data register: + -- The register data after writing to the track register is valid at least + -- after 32us in FM mode and after 16us in MFM mode. + -- Read from status register. This register is read only: + -- Be aware, that the status register data bits 7 to 1 after writing + -- the command regsiter are valid at least after 64us in FM mode or 32us in MFM mode and + -- the bit 0 (BUSY) is valid after 48us in FM mode or 24us in MFM mode. + DATA_OUT <= TRACK_REG when CSn = '0' and ADR = "01" and RWn = '1' else + SECTOR_REG when CSn = '0' and ADR = "10" and RWn = '1' else + DATA_REG when CSn = '0' and ADR = "11" and RWn = '1' else + To_StdLogicVector(STATUS_REG) when CSn = '0' and ADR = "00" and RWn = '1' else (others => '0'); + DATA_EN <= '1' when CSn = '0' and RWn = '1' else '0'; +end architecture BEHAVIOR; \ No newline at end of file diff --git a/vhdl/rtl/vhdl/WF_FDC1772_IP/wf1772ip_top.vhd b/vhdl/rtl/vhdl/WF_FDC1772_IP/wf1772ip_top.vhd new file mode 100644 index 0000000..71ef3f3 --- /dev/null +++ b/vhdl/rtl/vhdl/WF_FDC1772_IP/wf1772ip_top.vhd @@ -0,0 +1,154 @@ +---------------------------------------------------------------------- +---- ---- +---- WD1772 compatible floppy disk controller IP Core. ---- +---- ---- +---- This file is part of the SUSKA ATARI clone project. ---- +---- http://www.experiment-s.de ---- +---- ---- +---- Description: ---- +---- Floppy disk controller with all features of the Western ---- +---- Digital WD1772-02 controller. ---- +---- ---- +---- This is the top level file. ---- +---- ---- +---- ---- +---- To Do: ---- +---- - Test of the FM portion of the code (if there is any need). ---- +---- - Test of the read track command. ---- +---- - Test of the read address command. ---- +---- ---- +---- Author(s): ---- +---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2006 Wolfgang Foerster ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.gnu.org/licenses/lgpl.html ---- +---- ---- +---------------------------------------------------------------------- +-- +-- Revision History +-- +-- Revision 2006A 2006/06/03 WF +-- Initial Release: the MFM portion for HD and DD floppies is tested. +-- The FM mode (DDEn = '1') is not completely tested due to the lack +-- of FM drives. +-- Revision 2K6B 2006/11/05 WF +-- Modified Source to compile with the Xilinx ISE. +-- Fixed the polarity of the precompensation flag. +-- The flag is no active '0'. Thanks to Jorma +-- Oksanen for the information. +-- Revision 2K7B 2006/12/29 WF +-- Introduced several improvements based on a very good examination +-- of the pll code by Jean Louis-Guerin. +-- Revision 2K8B 2008/12/24 WF +-- Rewritten this top level file as a wrapper for the top_soc file. + +library work; +use work.WF1772IP_PKG.all; + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + +entity WF1772IP_TOP is + port ( + CLK : in bit; -- 16MHz clock! + MRn : in bit; + CSn : in bit; + RWn : in bit; + A1, A0 : in bit; + DATA : inout std_logic_vector(7 downto 0); + RDn : in bit; + TR00n : in bit; + IPn : in bit; + WPRTn : in bit; + DDEn : in bit; + HDTYPE : in bit; -- '0' = DD disks, '1' = HD disks. + MO : out bit; + WG : out bit; + WD : out bit; + STEP : out bit; + DIRC : out bit; + DRQ : out bit; + INTRQ : out bit + ); +end entity WF1772IP_TOP; + +architecture STRUCTURE of WF1772IP_TOP is +component WF1772IP_TOP_SOC + port ( + CLK : in bit; + RESETn : in bit; + CSn : in bit; + RWn : in bit; + A1, A0 : in bit; + DATA_IN : in std_logic_vector(7 downto 0); + DATA_OUT : out std_logic_vector(7 downto 0); + DATA_EN : out bit; + RDn : in bit; + TR00n : in bit; + IPn : in bit; + WPRTn : in bit; + DDEn : in bit; + HDTYPE : in bit; + MO : out bit; + WG : out bit; + WD : out bit; + STEP : out bit; + DIRC : out bit; + DRQ : out bit; + INTRQ : out bit + ); +end component; +signal DATA_OUT : std_logic_vector(7 downto 0); +signal DATA_EN : bit; +begin + DATA <= DATA_OUT when DATA_EN = '1' else (others => 'Z'); + + I_1772: WF1772IP_TOP_SOC + port map( + CLK => CLK, + RESETn => MRn, + CSn => CSn, + RWn => RWn, + A1 => A1, + A0 => A0, + DATA_IN => DATA, + DATA_OUT => DATA_OUT, + DATA_EN => DATA_EN, + RDn => RDn, + TR00n => TR00n, + IPn => IPn, + WPRTn => WPRTn, + DDEn => DDEn, + HDTYPE => HDTYPE, + MO => MO, + WG => WG, + WD => WD, + STEP => STEP, + DIRC => DIRC, + DRQ => DRQ, + INTRQ => INTRQ + ); +end architecture STRUCTURE; \ No newline at end of file diff --git a/vhdl/rtl/vhdl/WF_FDC1772_IP/wf1772ip_top_soc.vhd b/vhdl/rtl/vhdl/WF_FDC1772_IP/wf1772ip_top_soc.vhd new file mode 100644 index 0000000..92793da --- /dev/null +++ b/vhdl/rtl/vhdl/WF_FDC1772_IP/wf1772ip_top_soc.vhd @@ -0,0 +1,333 @@ +---------------------------------------------------------------------- +---- ---- +---- WD1772 compatible floppy disk controller IP Core. ---- +---- ---- +---- This file is part of the SUSKA ATARI clone project. ---- +---- http://www.experiment-s.de ---- +---- ---- +---- Description: ---- +---- Floppy disk controller with all features of the Western ---- +---- Digital WD1772-02 controller. ---- +---- ---- +---- Top level file for use in systems on programmable chips. ---- +---- ---- +---- ---- +---- To Do: ---- +---- - Test of the FM portion of the code (if there is any need). ---- +---- - Test of the read track command. ---- +---- - Test of the read address command. ---- +---- ---- +---- Author(s): ---- +---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2006 - 2011 Wolfgang Foerster ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.gnu.org/licenses/lgpl.html ---- +---- ---- +---------------------------------------------------------------------- +-- +-- Revision History +-- +-- Revision 2006A 2006/06/03 WF +-- Initial Release: the MFM portion for HD and DD floppies is tested. +-- The FM mode (DDEn = '1') is not completely tested due to the lack +-- of FM drives. +-- Revision 2K6B 2006/11/05 WF +-- Modified Source to compile with the Xilinx ISE. +-- Fixed the polarity of the precompensation flag. +-- The flag is no active '0'. Thanks to Jorma Oksanen for the information. +-- Top level file provided for SOC (systems on programmable chips). +-- Revision 2K7B 2006/12/29 WF +-- Introduced several improvements based on a very good examination +-- of the pll code by Jean Louis-Guerin. +-- Revision 2K8A 2008/07/14 WF +-- Minor changes. +-- Revision 2K8B 2009/12/24 WF +-- Bugfixes in the controller due to hanging state machine. +-- Removed CRC_BUSY. +-- + +library work; +use work.WF1772IP_PKG.all; + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + +entity WF1772IP_TOP_SOC is + port ( + CLK : in bit; -- 16MHz clock! + RESETn : in bit; + CSn : in bit; + RWn : in bit; + A1, A0 : in bit; + DATA_IN : in std_logic_vector(7 downto 0); + DATA_OUT : out std_logic_vector(7 downto 0); + DATA_EN : out bit; + RDn : in bit; + TR00n : in bit; + IPn : in bit; + WPRTn : in bit; + DDEn : in bit; + HDTYPE : in bit; -- '0' = DD disks, '1' = HD disks. + MO : out bit; + WG : out bit; + WD : out bit; + STEP : out bit; + DIRC : out bit; + DRQ : out bit; + INTRQ : out bit + ); +end entity WF1772IP_TOP_SOC; + +architecture STRUCTURE of WF1772IP_TOP_SOC is +signal DATA_OUT_REG : std_logic_vector(7 downto 0); +signal DATA_EN_REG : bit; +signal CMD_I : std_logic_vector(7 downto 0); +signal DR_I : bit_vector(7 downto 0); +signal DSR_I : std_logic_vector(7 downto 0); +signal TR_I : std_logic_vector(7 downto 0); +signal SR_I : std_logic_vector(7 downto 0); +signal ID_AM_I : bit; +signal DATA_AM_I : bit; +signal DDATA_AM_I : bit; +signal AM_TYPE_I : bit; +signal AM_2_DISK_I : bit; +signal DATA_STRB_I : bit; +signal BUSY_I : bit; +signal DRQ_I : bit; +signal DRQ_IPn_I : bit; +signal LD_TR00_I : bit; +signal SP_RT_I : bit; +signal SEEK_RNF_I : bit; +signal WR_PR_I : bit; +signal MO_I : bit; +signal PLL_DSTRB_I : bit; +signal PLL_D_I : bit; +signal CRC_SD_I : bit; +signal CRC_ERR_I : bit; +signal CRC_PRES_I : bit; +signal CRC_ERRFLAG_I : bit; +signal SD_R_I : bit; +signal CRC_SDOUT_I : bit; +signal SHFT_LOAD_SD_I : bit; +signal SHFT_LOAD_ND_I : bit; +signal WR_In : bit; +signal TR_PRES_I : bit; +signal TR_CLR_I : bit; +signal TR_INC_I : bit; +signal TR_DEC_I : bit; +signal SR_LOAD_I : bit; +signal SR_INC_I : bit; +signal DR_CLR_I : bit; +signal DR_LOAD_I : bit; +signal TRACK_NR_I : std_logic_vector(7 downto 0); +signal CRC_2_DISK_I : bit; +signal DSR_2_DISK_I : bit; +signal FF_2_DISK_I : bit; +signal PRECOMP_EN_I : bit; +signal DISK_RWn_I : bit; +signal WDATA_I : bit; +begin + -- Three state data bus: + DATA_OUT <= DATA_OUT_REG when DATA_EN_REG = '1' else (others => '0'); + DATA_EN <= DATA_EN_REG; + + -- Some signals copied to the outputs: + WD <= not WR_In; + MO <= MO_I; + DRQ <= DRQ_I; + + -- Write deleted data address mark in MFM mode in 'Write Sector' command in + -- case of asserted command bit 0. + AM_TYPE_I <= '0' when CMD_I(7 downto 5) = "101" and CMD_I(0) = '1' else '1'; + + -- The CRC unit is used during read from disk and write to disk. + -- This is the data multiplexer for the data stream to encode. + CRC_SD_I <= SD_R_I when DISK_RWn_I = '1' else WDATA_I; + + I_CONTROL: WF1772IP_CONTROL + port map( + CLK => CLK, + RESETn => RESETn, + A1 => A0, + A0 => A1, + RWn => RWn, + CSn => CSn, + DDEn => DDEn, + DR => DR_I, + CMD => CMD_I, + DSR => DSR_I, + TR => TR_I, + SR => SR_I, + MO => MO_I, + WR_PR => WR_PR_I, + SPINUP_RECTYPE => SP_RT_I, + SEEK_RNF => SEEK_RNF_I, + CRC_ERRFLAG => CRC_ERRFLAG_I, + LOST_DATA_TR00 => LD_TR00_I, + DRQ => DRQ_I, + DRQ_IPn => DRQ_IPn_I, + BUSY => BUSY_I, + AM_2_DISK => AM_2_DISK_I, + ID_AM => ID_AM_I, + DATA_AM => DATA_AM_I, + DDATA_AM => DDATA_AM_I, + CRC_ERR => CRC_ERR_I, + CRC_PRES => CRC_PRES_I, + TR_PRES => TR_PRES_I, + TR_CLR => TR_CLR_I, + TR_INC => TR_INC_I, + TR_DEC => TR_DEC_I, + SR_LOAD => SR_LOAD_I, + SR_INC => SR_INC_I, + TRACK_NR => TRACK_NR_I, + DR_CLR => DR_CLR_I, + DR_LOAD => DR_LOAD_I, + SHFT_LOAD_SD => SHFT_LOAD_SD_I, + SHFT_LOAD_ND => SHFT_LOAD_ND_I, + CRC_2_DISK => CRC_2_DISK_I, + DSR_2_DISK => DSR_2_DISK_I, + FF_2_DISK => FF_2_DISK_I, + PRECOMP_EN => PRECOMP_EN_I, + DATA_STRB => DATA_STRB_I, + DISK_RWn => DISK_RWn_I, + WPRTn => WPRTn, + TRACK00n => TR00n, + IPn => IPn, + DIRC => DIRC, + STEP => STEP, + WG => WG, + INTRQ => INTRQ + ); + + I_REGISTERS: WF1772IP_REGISTERS + port map( + CLK => CLK, + RESETn => RESETn, + CSn => CSn, + ADR(1) => A1, + ADR(0) => A0, + RWn => RWn, + DATA_IN => DATA_IN, + DATA_OUT => DATA_OUT_REG, + DATA_EN => DATA_EN_REG, + CMD => CMD_I, + TR => TR_I, + SR => SR_I, + DSR => DSR_I, + DR => DR_I, + SD_R => SD_R_I, + DATA_STRB => DATA_STRB_I, + DR_CLR => DR_CLR_I, + DR_LOAD => DR_LOAD_I, + TR_PRES => TR_PRES_I, + TR_CLR => TR_CLR_I, + TR_INC => TR_INC_I, + TR_DEC => TR_DEC_I, + TRACK_NR => TRACK_NR_I, + SR_LOAD => SR_LOAD_I, + SR_INC => SR_INC_I, + SHFT_LOAD_SD => SHFT_LOAD_SD_I, + SHFT_LOAD_ND => SHFT_LOAD_ND_I, + MOTOR_ON => MO_I, + WRITE_PROTECT => WR_PR_I, + SPINUP_RECTYPE => SP_RT_I, + SEEK_RNF => SEEK_RNF_I, + CRC_ERRFLAG => CRC_ERRFLAG_I, + LOST_DATA_TR00 => LD_TR00_I, + DRQ => DRQ_I, + DRQ_IPn => DRQ_IPn_I, + BUSY => BUSY_I, + DDEn => DDEn + ); + + I_DIGITAL_PLL: WF1772IP_DIGITAL_PLL + port map( + CLK => CLK, + RESETn => RESETn, + DDEn => DDEn, + HDTYPE => HDTYPE, + DISK_RWn => DISK_RWn_I, + RDn => RDn, + PLL_D => PLL_D_I, + PLL_DSTRB => PLL_DSTRB_I + ); + + I_AM_DETECTOR: WF1772IP_AM_DETECTOR + port map( + CLK => CLK, + RESETn => RESETn, + DDEn => DDEn, + DATA => PLL_D_I, + DATA_STRB => PLL_DSTRB_I, + ID_AM => ID_AM_I, + DATA_AM => DATA_AM_I, + DDATA_AM => DDATA_AM_I + ); + + I_CRC_LOGIC: WF1772IP_CRC_LOGIC + port map( + CLK => CLK, + RESETn => RESETn, + DDEn => DDEn, + DISK_RWn => DISK_RWn_I, + ID_AM => ID_AM_I, + DATA_AM => DATA_AM_I, + DDATA_AM => DDATA_AM_I, + SD => CRC_SD_I, + CRC_STRB => DATA_STRB_I, + CRC_2_DISK => CRC_2_DISK_I, + CRC_PRES => CRC_PRES_I, + CRC_SDOUT => CRC_SDOUT_I, + CRC_ERR => CRC_ERR_I + ); + + I_TRANSCEIVER: WF1772IP_TRANSCEIVER + port map( + CLK => CLK, + RESETn => RESETn, + DDEn => DDEn, + HDTYPE => HDTYPE, + ID_AM => ID_AM_I, + DATA_AM => DATA_AM_I, + DDATA_AM => DDATA_AM_I, + SHFT_LOAD_SD => SHFT_LOAD_SD_I, + DR => DR_I, + PRECOMP_EN => PRECOMP_EN_I, + AM_TYPE => AM_TYPE_I, + AM_2_DISK => AM_2_DISK_I, + CRC_2_DISK => CRC_2_DISK_I, + DSR_2_DISK => DSR_2_DISK_I, + FF_2_DISK => FF_2_DISK_I, + SR_SDOUT => DSR_I(7), + CRC_SDOUT => CRC_SDOUT_I, + WRn => WR_In, + WDATA => WDATA_I, + PLL_DSTRB => PLL_DSTRB_I, + PLL_D => PLL_D_I, + DATA_STRB => DATA_STRB_I, + SD_R => SD_R_I + ); +end architecture STRUCTURE; \ No newline at end of file diff --git a/vhdl/rtl/vhdl/WF_FDC1772_IP/wf1772ip_transceiver.vhd b/vhdl/rtl/vhdl/WF_FDC1772_IP/wf1772ip_transceiver.vhd new file mode 100644 index 0000000..ab2b07d --- /dev/null +++ b/vhdl/rtl/vhdl/WF_FDC1772_IP/wf1772ip_transceiver.vhd @@ -0,0 +1,517 @@ +---------------------------------------------------------------------- +---- ---- +---- WD1772 compatible floppy disk controller IP Core. ---- +---- ---- +---- This file is part of the SUSKA ATARI clone project. ---- +---- http://www.experiment-s.de ---- +---- ---- +---- Description: ---- +---- Floppy disk controller with all features of the Western ---- +---- Digital WD1772-02 controller. ---- +---- ---- +---- The transceiver unit contains on the one hand the receiver ---- +---- part which strips off the clock signal from the data stream ---- +---- and on the other hand the transmitter unit which provides in ---- +---- the different modes (FM and MFM) all functions which are ---- +---- necessary to send data, CRC bytes, 'FF', '00' or the address ---- +---- marks. ---- +---- ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2006 - 2011 Wolfgang Foerster ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.gnu.org/licenses/lgpl.html ---- +---- ---- +---------------------------------------------------------------------- +-- +-- Revision History +-- +-- Revision 2006A 2006/06/03 WF +-- Initial Release. +-- Revision 2K6B 2006/11/05 WF +-- Modified Source to compile with the Xilinx ISE. +-- Revision 2K8A 2008/07/14 WF +-- Minor changes. +-- Revision 2K9A 2009/06/20 WF +-- MFM_In and MASK_SHFT have now synchronous reset to meet preset requirement. +-- + + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + +entity WF1772IP_TRANSCEIVER is + port( + -- System control + CLK : in bit; -- must be 16MHz + RESETn : in bit; + + -- Data and Control: + HDTYPE : in bit; -- Floppy type HD or DD. + DDEn : in bit; -- Double density select (FM or MFM). + ID_AM : in bit; -- ID addressmark strobe. + DATA_AM : in Bit; -- Data addressmark strobe. + DDATA_AM : in Bit; -- Deleted data addressmark strobe. + SHFT_LOAD_SD : in bit; -- Indication for shift register load time. + DR : in bit_vector(7 downto 0); -- Content of the data register. + + -- Data strobes: + PLL_DSTRB : in bit; -- Clock strobe for RD serial data input. + DATA_STRB : buffer bit; + + -- Data strobe and data for the CRC during write operation: + WDATA : buffer bit; + + -- Encoder (logic to disk): + PRECOMP_EN : in bit; -- control signal for MFM write precompensation. + AM_TYPE : in bit; -- Write deleted address mark in MFM mode when 0. + AM_2_DISK : in bit; + DSR_2_DISK : in bit; + FF_2_DISK : in bit; + CRC_2_DISK : in bit; + SR_SDOUT : in std_logic; -- encoder's data input from the shift register (serial). + CRC_SDOUT : in bit; -- encoder's data input from the CRC unit (serial). + WRn : out bit; -- write output for the MFM drive containing clock and data. + + -- Decoder (disk to logic): + PLL_D : in bit; -- Serial data input. + SD_R : out bit -- Serial (decoded) data output. + ); +end WF1772IP_TRANSCEIVER; + +architecture BEHAVIOR of WF1772IP_TRANSCEIVER is +type MFM_STATES is (A_00, B_01, C_10); +type PRECOMP_VALUES is (EARLY, NOMINAL, LATE); +type DEC_STATES is (CLK_PHASE, DATA_PHASE); + +signal MFM_STATE : MFM_STATES; +signal NEXT_MFM_STATE : MFM_STATES; +signal PRECOMP : PRECOMP_VALUES; +signal DEC_STATE : DEC_STATES; +signal NEXT_DEC_STATE : DEC_STATES; + +signal FM_In : bit; + +signal CLKMASK : bit; -- Control for suppression of FM clock transitions. + +signal MFM_10_STRB : bit; +signal MFM_01_STRB : bit; + +signal WR_CNT : std_logic_vector(3 downto 0); +signal MFM_In : bit; + +signal AM_SHFT : bit_vector(31 downto 0); + +begin + -- ####################### encoder stuff ########################### + ADRMARK: process(RESETn, CLK) + -- This process provides the address mark data for both FM and MFM in + -- write to disk mode. In FM only one byte is written where in MFM + -- 3 sync bytes x"A1" and one data address mark is written. + -- In this process only the data address mark is provided. The only way + -- writing the ID address mark is the write track command. + begin + if RESETn = '0' then + AM_SHFT <= (others => '0'); + elsif CLK = '1' and CLK' event then + if AM_2_DISK = '1' and DATA_STRB = '1' then + AM_SHFT <= AM_SHFT (30 downto 0) & '0'; -- Shift out. + elsif AM_2_DISK = '0' and DDEn = '1' and AM_TYPE = '0' then -- FM mode. + AM_SHFT <= x"F8000000"; -- Load deleted FM address mark. + elsif AM_2_DISK = '0' and DDEn = '1' and AM_TYPE = '1' then -- FM mode. + AM_SHFT <= x"FB000000"; -- Load normal FM address mark. + elsif AM_2_DISK = '0' and DDEn = '0' and AM_TYPE = '0' then -- MFM mode deleted data mark. + AM_SHFT <= x"A1A1A1F8"; -- Load MFM syncs and address mark. + elsif AM_2_DISK = '0' and DDEn = '0' and AM_TYPE = '1' then -- Default: MFM mode normal data mark. + AM_SHFT <= x"A1A1A1FB"; -- Load MFM syncs and address mark. + end if; + end if; + end process ADRMARK; + + -- Input multiplexer: + WDATA <= AM_SHFT(31) when AM_2_DISK = '1' else -- Address mark data data. + To_Bit(SR_SDOUT) when DSR_2_DISK = '1' else -- Shift register data. + CRC_SDOUT when CRC_2_DISK = '1' else -- CRC data. + '1' when FF_2_DISK = '1' else '0'; -- Write zeros is default. + + -- Output multiplexer: + WRn <= '0' when FM_In = '0' and DDEn = '1' else -- FM portion. + '0' when MFM_In = '0' and DDEn = '0' else '1'; -- MFM portion and default. + + CLK_MASK: process(CLK) + -- This part of software controls the suppression of the clock pulses + -- during transmission of several FM special characters. During writing + -- 'normal' data to the disk, only 8 mask bits of the shift register are + -- used. During writing MFM sync and address mark bits, the register is + -- used with 32 mask bits. + variable MASK_SHFT : bit_vector(23 downto 0); + variable LOCK : boolean; + begin + if CLK = '1' and CLK' event then + if RESETn = '0' then + MASK_SHFT := (others => '1'); + LOCK := false; + -- Load the mask shift register just in time when the shift register is + -- loaded with valid data from the data register. + elsif SHFT_LOAD_SD = '1' and DDEn = '1' then -- FM mode. + case DR is + when x"F8" | x"F9" | x"FA" | x"FB" | x"FE" => MASK_SHFT := x"C7FFFF"; + when x"FC" => MASK_SHFT := x"D7FFFF"; + when x"F5" | x"F6" => MASK_SHFT := (others => '0'); -- Not allowed. + when others => MASK_SHFT := x"FFFFFF"; -- Normal data. + end case; + elsif SHFT_LOAD_SD = '1' and DDEn = '0' then -- MFM mode. + case DR is + when x"F5" => MASK_SHFT := x"FBFFFF"; -- Suppress clock pulse between bits 4 and 5. + when x"F6" => MASK_SHFT := x"F7FFFF"; -- Suppress clock pulse between bits 3 and 4. + when others => MASK_SHFT := x"FFFFFF"; -- Normal data. + end case; + elsif AM_2_DISK = '1' and DDEn = '1' and LOCK = false then -- FM mode. + MASK_SHFT := x"C7FFFF"; -- Load just once per AM_2_DISK rising edge. + LOCK := true; + elsif AM_2_DISK = '1' and DDEn = '0' and LOCK = false then -- MFM mode. + MASK_SHFT := x"FBFBFB"; -- Three syncs with suppressed clock pulse then transparent mask. + LOCK := true; + elsif DATA_STRB = '1' then -- shift as long as transmission is active + -- The Shift register is shifted left. After shifting the clockmasks out it is + -- transparent due to the '1's filled up from the left. + MASK_SHFT := MASK_SHFT(22 downto 0) & '1'; -- Shift left. + elsif AM_2_DISK = '0' then + LOCK := false; -- Release the lock after address mark has been written. + end if; + end if; + CLKMASK <= MASK_SHFT(23); + end process CLK_MASK; + + FM_ENCODER: process (RESETn, DATA_STRB, CLK) + -- For DD type floppies the data rate is 125kBps. Therefore there are 128 16-MHz clocks cycles + -- per FM bit. + -- For HD type floppies the data rate is 250kBps. Therefore there are 64 16-MHz clocks cycles + -- per FM bit. + -- The FM write pulse width is 1.375us for DD and 0.750us HD type floppies. + -- This process provides the FM encoded signal. The first pulse is in any case the clock + -- pulse and the second pulse is due to data. The FM encoding is very simple and therefore + -- self explaining. + variable CNT : std_logic_vector(7 downto 0); + begin + if RESETn = '0' then + FM_In <= '1'; + CNT := x"00"; + elsif CLK = '1' and CLK' event then + -- In case of HD type floppies the counter reaches a value of b"0100000" + -- In case of DD type floppies the counter reaches a value of b"1000000" + if DATA_STRB = '1' then + CNT := x"00"; + else + CNT := CNT + '1'; + end if; + -- The flux reversal pulses are centered between the DATA_STRB pulses. + -- In detail: the clock pulse appears in the middle of the first half + -- of the DATA_STRB period and the data pulse appears in the middle of + -- the second half. + case HDTYPE is + when '0' => -- DD type floppies: + if CNT > "00010101" and CNT <= "00101011" then + FM_In <= not CLKMASK; -- FM clock. + elsif CNT > "01010101" and CNT <= "01101011" then + FM_In <= not WDATA; -- FM data. + else + FM_In <= '1'; + end if; + when '1' => -- HD type floppies: + if CNT > "00001010" and CNT <= "00010110" then + FM_In <= not CLKMASK; -- FM clock. + elsif CNT > "00101010" and CNT <= "00110110" then + FM_In <= not WDATA; -- FM data. + else + FM_In <= '1'; + end if; + end case; + end if; + end process FM_ENCODER; + + MFM_ENCODE_REG: process(RESETn, CLK) + -- This process is the first portion of the more complicated MFM encoder. It can be interpreted + -- as a Moore machine. This part is the current state register. + begin + if RESETn = '0' then + MFM_STATE <= A_00; + elsif CLK = '1' and CLK' event then + MFM_STATE <= NEXT_MFM_STATE; + end if; + end process MFM_ENCODE_REG; + + MFM_ENCODE_LOGIC: process(MFM_STATE, WDATA, DATA_STRB) + -- Rules for Encoding: + -- transitions are never located at the mid point of a 'zero'. + -- transistions are always located at the mid point of a '1'. + -- no transitions at the borders of a '1'. + -- transitions appear between two adjacent 'zeros'. + -- states are as follows: + -- A_00: idle state, no transition. + -- B_01: transistion between the MFM clock edges. + -- C_10: transition on the leading MFM clock edges. + -- The timing of the MFM output is done in the process MFM_WR_OUT. + begin + case MFM_STATE is + when A_00 => + if WDATA = '0' and DATA_STRB = '1' then + NEXT_MFM_STATE <= C_10; + elsif WDATA = '1' and DATA_STRB = '1' then + NEXT_MFM_STATE <= B_01; + else + NEXT_MFM_STATE <= A_00; -- Stay, if there is no strobe. + end if; + when C_10 => + if WDATA = '0' and DATA_STRB = '1' then + NEXT_MFM_STATE <= C_10; + elsif WDATA = '1' and DATA_STRB = '1' then + NEXT_MFM_STATE <= B_01; + else + NEXT_MFM_STATE <= C_10; -- Stay, if there is no strobe. + end if; + when B_01 => + if WDATA = '0' and DATA_STRB = '1' then + NEXT_MFM_STATE <= A_00; + elsif WDATA = '1' and DATA_STRB = '1' then + NEXT_MFM_STATE <= B_01; + else + NEXT_MFM_STATE <= B_01; -- Stay, if there is no strobe. + end if; + end case; + end process MFM_ENCODE_LOGIC; + + MFM_PRECOMPENSATION: process(RESETn, CLK) + -- The write pattern is adjusted in the MFM write timing process as follows: + -- after DATA_STRB (the duty cycle of this strobe is exactly one CLK) the + -- incoming data is bufferd in WRITEPATTERN. After the following DATA_STRB + -- the WDATA is shifted through WRITEPATTERN. After further DATA_STRBs the + -- WRITEPATTERN consists of previous, current and next WDATA like this: + -- WRITEPATTERN(3) is the second previous WDATA. + -- WRITEPATTERN(2) is the previous WDATA. + -- WRITEPATTERN(1) is the current WDATA to be sent. + -- WRITEPATTERN(0) is the next WDATA to be sent. + variable WRITEPATTERN : bit_vector(3 downto 0); + begin + if RESETn = '0' then + PRECOMP <= NOMINAL; + WRITEPATTERN := "0000"; + elsif CLK = '1' and CLK' event then + if DATA_STRB = '1' then + WRITEPATTERN := WRITEPATTERN(2 downto 0) & WDATA; -- shift left + end if; + if PRECOMP_EN = '0' then + PRECOMP <= NOMINAL; -- no precompensation + else + case WRITEPATTERN is + when "1110" | "0110" => PRECOMP <= EARLY; + when "1011" | "0011" => PRECOMP <= LATE; + when "0001" => PRECOMP <= EARLY; + when "1000" => PRECOMP <= LATE; + when others => PRECOMP <= NOMINAL; + end case; + end if; + end if; + end process MFM_PRECOMPENSATION; + + MFM_STROBES: process (RESETn, DATA_STRB, CLK) + -- For the MFM frequency is 250 kBps for DD type floppies, there are 64 + -- 16 MHz clock cycles per MFM bit and for HD type floppies, which have + -- 500 kBps there are 32 16MHz clock pulses for one MFM bit. + -- The MFM state machine (Moore) switches on the DATA_STRB. + -- During one cycle there are the two further strobes MFM_10_STRB and + -- MFM_01_STRB which control the MFM output in the process MFM_WR_OUT. + -- The strobes are centered in the middle of the first half and in the + -- middle of the second half of the DATA_STRB cycle. + variable CNT : std_logic_vector(5 downto 0); + begin + if RESETn = '0' then + CNT := "000000"; + elsif CLK = '1' and CLK' event then + if DATA_STRB = '1' then + CNT := (others => '0'); + else + CNT := CNT + '1'; + end if; + if HDTYPE = '1' then + case CNT is + -- encoder timing for MFM and HD type floppies. + when "000100" => MFM_10_STRB <= '1'; MFM_01_STRB <= '0'; -- Pulse centered in the first half. + when "010100" => MFM_10_STRB <= '0'; MFM_01_STRB <= '1'; -- Pulse centered in the second half. + when others => MFM_10_STRB <= '0'; MFM_01_STRB <= '0'; + end case; + else + case CNT is + -- encoder timing for MFM and DD type floppies. + when "001010" => MFM_10_STRB <= '1'; MFM_01_STRB <= '0'; -- Pulse centered in the first half. + when "101000" => MFM_10_STRB <= '0'; MFM_01_STRB <= '1'; -- Pulse centered in the second half. + when others => MFM_10_STRB <= '0'; MFM_01_STRB <= '0'; + end case; + end if; + end if; + end process MFM_STROBES; + + -- MFM_WR_TIMING generates the timing for the write pulses which are + -- required by a MFM device like floppy disk drive. The pulse timing + -- meets the timing of the MFM data with pulse width of 700ns +/- 100ns + -- depending on write precompensation. + -- The original WD1772 (CLK = 8MHz) data timing was as follows: + -- The output is asserted as long as CNT is active; in detail + -- this are 4,5; 5,5 or 6,5 CLK cycles depending on the write + -- precompensation. + -- The new design which works with a 16MHz clock requires the following + -- timing: 9; 11 or 13 CLK cycles depending on the writeprecompensation + -- for DD floppies and 5; 6 or 7 CLK cycles depending on the write + -- precompensation for HD floppies. + -- To meet the timing requirements of half clocks + -- the WRn is controlled by the following three processes where the one + -- syncs on the positive clock edge and the other on the negative. + -- For more information on the WTn timing see the datasheet of the + -- WD177x floppy disc controller. + + MFM_WR_TIMING: process(RESETn, CLK) + variable CLKMASK_MFM : bit; + begin + if RESETn = '0' then + WR_CNT <= x"F"; + elsif CLK = '1' and CLK' event then + if DATA_STRB = '1' then + -- The CLKMASK_MFM is synchronised to DATA_STRB. This brings one strobe latency. + -- The timing in connection with the data is correct because the MFM encoder state machine + -- causes the data to be 1 DATA_STRB late too. + CLKMASK_MFM := CLKMASK; + end if; + if MFM_STATE = C_10 and MFM_10_STRB = '1' and CLKMASK_MFM = '1' then + WR_CNT <= x"0"; + elsif MFM_STATE = B_01 and MFM_01_STRB = '1' then + WR_CNT <= x"0"; + elsif WR_CNT < x"F" then + WR_CNT <= WR_CNT + '1'; + end if; + end if; + end process MFM_WR_TIMING; + + MFM_WR_OUT: process + begin + wait until CLK = '1' and CLK' event; + if RESETn = '0' then + MFM_In <= '1'; + else + case HDTYPE is + when '1' => -- HD type. + if PRECOMP = EARLY and WR_CNT > x"0" and WR_CNT <= x"9" then + MFM_In <= '0'; -- 9,0 clock cycles for WRn --> early timing + elsif PRECOMP = NOMINAL and WR_CNT > x"0" and WR_CNT <= x"8" then + MFM_In <= '0'; -- 8,0 clock cycles for WRn --> nominal timing + elsif PRECOMP = LATE and WR_CNT > x"0" and WR_CNT <= x"7" then + MFM_In <= '0'; -- 7,0 clock cycles for WRn --> late timing + else + MFM_In <= '1'; + end if; + when '0' => -- DD type. + if PRECOMP = EARLY and WR_CNT > x"0" and WR_CNT <= x"D" then + MFM_In <= '0'; -- 13,0 clock cycles for WRn --> early timing + elsif PRECOMP = NOMINAL and WR_CNT > x"0" and WR_CNT <= x"B" then + MFM_In <= '0'; -- 11,0 clock cycles for WRn --> nominal timing + elsif PRECOMP = LATE and WR_CNT > x"0" and WR_CNT <= x"9" then + MFM_In <= '0'; -- 9,0 clock cycles for WRn --> late timing + else + MFM_In <= '1'; + end if; + end case; + end if; + end process MFM_WR_OUT; + + -- ####################### Decoder stuff ########################### + -- The decoding of the serial FM or MFM encoded data stream + -- is done in the following two processes (Moore machine). + -- The decoder works in principle like a simple toggle Flip-Flop. + -- It is important to synchronise it in a way, that the clock + -- pulses are separated from the data pulses. The principle + -- works for both FM and MFM data due to the digital phase + -- locked loop, which delivers the serial data and the clock + -- strobe. In general this decoder can be understood as the + -- data separator where the digital phase locked loop provides + -- the FM or the MFM decoding. The data separation lives from + -- the fact, that FM and also MFM encoded signals consist of a + -- mixture of alternating data and clock pulses. + -- FM works as follows: + -- every first pulse of the FM signal is a clock pulse and every + -- second pulse is a logic '1' of the data. A missing second + -- pulse represents a logic '0' of the data. + -- MFM works as follows: + -- every first pulse of the MFM signal is a clock pulse. The coding + -- principle causes clock pulses to be absent in some conditions. + -- Every second pulse is a logic '1' of the data. A missing second + -- pulse represents a logic '0' of the data. + -- So FM and MFM compared, the data is represented directly by the + -- second pulses and the data separator has to look only for these. + -- The missing MFM clock pulses do not cause a problem because the + -- digital PLL used in conjunction with this data separator fills + -- up the clock pulses and delivers a PLL_DSTRB containing aequidistant + -- clock strobes and data strobes. + + DEC_REG: process(RESETn, CLK) + begin + if RESETn = '0' then + DEC_STATE <= CLK_PHASE; + elsif CLK = '1' and CLK' event then + DEC_STATE <= NEXT_DEC_STATE; + end if; + end process DEC_REG; + + DEC_LOGIC: process(DEC_STATE, ID_AM, DATA_AM, DDATA_AM, PLL_DSTRB, PLL_D) + begin + case DEC_STATE is + when CLK_PHASE => + if PLL_DSTRB = '1' then + NEXT_DEC_STATE <= DATA_PHASE; + else + NEXT_DEC_STATE <= CLK_PHASE; + end if; + DATA_STRB <= '0'; -- Inactive during clock pulse time. + SD_R <= '0'; -- Inactive during clock pulse time. + when DATA_PHASE => + if ID_AM = '1' or DATA_AM = '1' or DDATA_AM = '1' then + -- Here the state machine is synchronised + -- to separate data and clock pulses correctly. + NEXT_DEC_STATE <= CLK_PHASE; + elsif PLL_DSTRB = '1' then + NEXT_DEC_STATE <= CLK_PHASE; + else + NEXT_DEC_STATE <= DATA_PHASE; + end if; + -- During the data phase valid data appears at SD. + -- The data is valid during DATA_STRB. + DATA_STRB <= PLL_DSTRB; + SD_R <= PLL_D; + end case; + end process DEC_LOGIC; +end architecture BEHAVIOR; diff --git a/vhdl/rtl/vhdl/WF_MFP68901_IP/Test_CLKDIV/wf68901ip_clkdiv.vhd b/vhdl/rtl/vhdl/WF_MFP68901_IP/Test_CLKDIV/wf68901ip_clkdiv.vhd new file mode 100644 index 0000000..accec86 --- /dev/null +++ b/vhdl/rtl/vhdl/WF_MFP68901_IP/Test_CLKDIV/wf68901ip_clkdiv.vhd @@ -0,0 +1,108 @@ +---------------------------------------------------------------------- +---- ---- +---- ATARI MFP compatible IP Core ---- +---- ---- +---- This file is part of the SUSKA ATARI clone project. ---- +---- http://www.experiment-s.de ---- +---- ---- +---- Description: ---- +---- Teststuff: clock divider. ---- +---- ---- +---- ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2006 Wolfgang Foerster ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.gnu.org/licenses/lgpl.html ---- +---- ---- +---------------------------------------------------------------------- +-- +-- Revision History +-- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + +entity TEST_CLKDIV is + port ( + CLK : in bit; + TXCLK : in bit; + CLK_MODE : in bit; + CLK_STRB : out bit; + CLK_2_STRB : out bit + + ); +end entity TEST_CLKDIV; + +architecture BEHAVIOR of TEST_CLKDIV is +begin + CLKDIV: process + variable CLK_LOCK : boolean; + variable STRB_LOCK : boolean; + variable CLK_DIVCNT : std_logic_vector(4 downto 0); + begin + wait until CLK = '1' and CLK' event; + if CLK_MODE = '0' then -- Divider off. + if TXCLK = '0' and STRB_LOCK = false then -- Works on negative TXCLK edge. + CLK_STRB <= '1'; + STRB_LOCK := true; + elsif TXCLK = '1' then + CLK_STRB <= '0'; + STRB_LOCK := false; + else + CLK_STRB <= '0'; + end if; + CLK_2_STRB <= '0'; -- No 1 1/2 stop bits in no div by 16 mode. + else + CLK_STRB <= '0'; -- Default. + CLK_2_STRB <= '0'; -- Default. + -- Works on negative TXCLK edge: + if CLK_DIVCNT > "00000" and TXCLK = '0' and CLK_LOCK = false then + CLK_DIVCNT := CLK_DIVCNT - '1'; + CLK_LOCK := true; + if CLK_DIVCNT = "01000" then + -- This strobe is asserted at half of the clock cycle. + -- It is used for the stop bit timing. + CLK_2_STRB <= '1'; + end if; + elsif CLK_DIVCNT = "00000" then + CLK_DIVCNT := "10000"; -- Div by 16 mode. + if STRB_LOCK = false then + STRB_LOCK := true; + CLK_STRB <= '1'; + end if; + elsif TXCLK = '1' then + CLK_LOCK := false; + STRB_LOCK := false; + end if; + end if; + end process CLKDIV; +end architecture BEHAVIOR; + diff --git a/vhdl/rtl/vhdl/WF_MFP68901_IP/Test_Timers/wf68901ip_timers.vhd b/vhdl/rtl/vhdl/WF_MFP68901_IP/Test_Timers/wf68901ip_timers.vhd new file mode 100644 index 0000000..d774fec --- /dev/null +++ b/vhdl/rtl/vhdl/WF_MFP68901_IP/Test_Timers/wf68901ip_timers.vhd @@ -0,0 +1,107 @@ +---------------------------------------------------------------------- +---- ---- +---- Test module to verify the timer prescalers. ---- +---- ---- +---- ---- +---- Author(s): ---- +---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2006 Wolfgang Foerster ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.gnu.org/licenses/lgpl.html ---- +---- ---- +---------------------------------------------------------------------- +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + +entity TIMERS is + port ( -- System control: + CLK : in bit; + RESETn : in bit; + + -- Timers and timer control: + XTAL1 : in bit; + TCDCR : in bit_vector(5 downto 3); + C_CNTSTRB : out bit + ); +end entity TIMERS; + +architecture BEHAVIOR of TIMERS is +signal XTAL1_S : bit; +signal XTAL_STRB : bit; +begin + SYNC: process + -- This process provides a 'clean' XTAL1. + -- Without this sync, the edge detector for + -- XTAL_STRB does not work properly. + begin + wait until CLK = '1' and CLK' event; + XTAL1_S <= XTAL1; + end process SYNC; + + XTAL_STROBE: process(RESETn, CLK) + -- This process provides a strobe with 1 clock cycle + -- (CLK) length after every rising edge of XTAL1. + variable LOCK : boolean; + begin + if RESETn = '0' then + XTAL_STRB <= '0'; + elsif CLK = '1' and CLK' event then + if XTAL1_S = '1' and LOCK = false then + XTAL_STRB <= '1'; + LOCK := true; + elsif XTAL1_S = '0' then + XTAL_STRB <= '0'; + LOCK := false; + + else + XTAL_STRB <= '0'; + end if; + end if; + end process XTAL_STROBE; + + PRESCALE_C: process + -- The prescalers work even if the RESETn is asserted. + variable PRESCALE : std_logic_vector(7 downto 0); + begin + wait until CLK = '1' and CLK' event; + C_CNTSTRB <= '0'; + if PRESCALE > x"00" and XTAL_STRB = '1' then + PRESCALE := PRESCALE - '1'; + elsif XTAL_STRB = '1' then + case TCDCR(5 downto 3) is + when "111" => PRESCALE := x"C7"; -- Prescaler = 200. + when "110" => PRESCALE := x"63"; -- Prescaler = 100. + when "101" => PRESCALE := x"3F"; -- Prescaler = 64. + when "100" => PRESCALE := x"31"; -- Prescaler = 50. + when "011" => PRESCALE := x"0F"; -- Prescaler = 16. + when "010" => PRESCALE := x"09"; -- Prescaler = 10. + when "001" => PRESCALE := x"03"; -- Prescaler = 4. + when "000" => PRESCALE := x"00"; -- Timer stopped. + end case; + C_CNTSTRB <= '1'; + end if; + end process PRESCALE_C; +end architecture BEHAVIOR; \ No newline at end of file diff --git a/vhdl/rtl/vhdl/WF_MFP68901_IP/Test_USART_Rx/wf68901ip_usart_rx.vhd b/vhdl/rtl/vhdl/WF_MFP68901_IP/Test_USART_Rx/wf68901ip_usart_rx.vhd new file mode 100644 index 0000000..8c184cf --- /dev/null +++ b/vhdl/rtl/vhdl/WF_MFP68901_IP/Test_USART_Rx/wf68901ip_usart_rx.vhd @@ -0,0 +1,581 @@ +---------------------------------------------------------------------- +---- ---- +---- ATARI MFP compatible IP Core ---- +---- ---- +---- This file is part of the SUSKA ATARI clone project. ---- +---- http://www.experiment-s.de ---- +---- ---- +---- Description: ---- +---- This is the SUSKA MFP IP core USART receiver file. ---- +---- ---- +---- ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2006 Wolfgang Foerster ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.gnu.org/licenses/lgpl.html ---- +---- ---- +---------------------------------------------------------------------- +-- +-- Revision History +-- +-- Revision 1.0 2006/04/06 WF +-- Initial Release. +-- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + +entity WF68901IP_USART_RX is + port ( + CLK : in bit; + RESETn : in bit; + + SCR : in bit_vector(7 downto 0); -- Synchronous character. + RX_SAMPLE : buffer bit; -- Flag indicating valid shift register data. + RX_DATA : out bit_vector(7 downto 0); -- Received data. + + RXCLK : in bit; -- Receiver clock. + SDATA_IN : in bit; -- Serial data input. + + CL : in bit_vector(1 downto 0); -- Character length. + ST : in bit_vector(1 downto 0); -- Start and stop bit configuration. + P_ENA : in bit; -- Parity enable. + P_EOn : in bit; -- Even or odd parity. + CLK_MODE : in bit; -- Clock mode configuration bit. + RE : in bit; -- Receiver enable. + FS_CLR : in bit; -- Clear the Found/Search flag for resynchronisation purpose. + SS : in bit; -- Synchronous strip enable. + UDR_READ : in bit; -- Flag indicating reading the data register. + RSR_READ : in bit; -- Flag indicating reading the receiver status register. + + M_CIP : out bit; -- Match/Character in progress. + FS_B : buffer bit; -- Find/Search or Break detect flag. + BF : out bit; -- Buffer full. + OE : out bit; -- Overrun error. + PE : out bit; -- Parity error. + FE : out bit -- Framing error. + ); +end entity WF68901IP_USART_RX; + +architecture BEHAVIOR of WF68901IP_USART_RX is +type RCV_STATES is (IDLE, WAIT_START, SAMPLE, PARITY, STOP1, STOP2, SYNC); +signal RCV_STATE, RCV_NEXT_STATE : RCV_STATES; +signal SDATA_DIV16 : bit; +signal SDATA_IN_I : bit; +signal SDATA_EDGE : bit; +signal SHIFT_REG : bit_vector(7 downto 0); +signal CLK_STRB : bit; +signal CLK_2_STRB : bit; +signal BITCNT : std_logic_vector(2 downto 0); +signal BREAK : boolean; +signal RDRF : bit; +signal STARTBIT : boolean; +begin + BF <= RDRF; -- Buffer full = Receiver Data Register Full. + RX_SAMPLE <= '1' when RCV_STATE = SYNC and ST /= "00" else -- Asynchronous mode: + -- Synchronous modes: + '1' when RCV_STATE = SYNC and ST = "00" and SS = '0' else + '1' when RCV_STATE = SYNC and ST = "00" and SS = '1' and SHIFT_REG /= SCR else '0'; + + -- Data multiplexer for the received data: + RX_DATA <= "000" & SHIFT_REG(7 downto 3) when RX_SAMPLE = '1' and CL = "11" else -- 5 databits. + "00" & SHIFT_REG(7 downto 2) when RX_SAMPLE = '1' and CL = "10" else -- 6 databits. + '0' & SHIFT_REG(7 downto 1) when RX_SAMPLE = '1' and CL = "01" else -- 6 databits. + SHIFT_REG when RX_SAMPLE = '1' and CL = "00" else x"00"; -- 8 databits. + + P_SAMPLE: process(RESETn, CLK, RE) + -- This process provides the 'valid transition logic' of the originally MC68901. For further + -- details see the 'M68000 FAMILY REFERENCE MANUAL'. + variable LOW_FLT : std_logic_vector(1 downto 0); + variable HI_FLT : std_logic_vector(1 downto 0); + variable CLK_LOCK : boolean; + variable EDGE_LOCK : boolean; + variable TIMER : std_logic_vector(2 downto 0); + variable TIMER_LOCK : boolean; + variable NEW_SDATA : bit; + begin + if RESETn = '0' or RE = '0' then + -- The reset condition assumes the SDATA_IN logic high. Otherwise + -- one not valid SDATA_EDGE pulse occurs during system startup. + CLK_LOCK := true; + EDGE_LOCK := true; + HI_FLT := "11"; + LOW_FLT := "11"; + SDATA_EDGE <= '0'; + TIMER := "111"; + TIMER_LOCK := true; + NEW_SDATA := '1'; + SDATA_DIV16 <= '1'; + elsif CLK = '1' and CLK' event then + -- Positive or negative edge detector for the incoming data. + -- Any transition must be valid for at least three receiver clock + -- cycles. The TIMER locking inhibits detecting four receiver + -- clock cycles after a valid transition. + if RXCLK = '1' and SDATA_IN = '0' and CLK_LOCK = false and LOW_FLT > "00" then + CLK_LOCK := true; + EDGE_LOCK := false; + HI_FLT := "00"; + LOW_FLT := LOW_FLT - '1'; + elsif RXCLK = '1' and SDATA_IN = '1' and CLK_LOCK = false and HI_FLT < "11" then + CLK_LOCK := true; + EDGE_LOCK := false; + LOW_FLT := "11"; + HI_FLT := HI_FLT + '1'; + elsif RXCLK = '1' and EDGE_LOCK = false and LOW_FLT = "00" then + EDGE_LOCK := true; + SDATA_EDGE <= '1'; -- Falling edge detected. + NEW_SDATA := '0'; + elsif RXCLK = '1' and EDGE_LOCK = false and HI_FLT = "11" then + EDGE_LOCK := true; + SDATA_EDGE <= '1'; -- Rising edge detected. + NEW_SDATA := '1'; + elsif RXCLK = '1' and CLK_LOCK = false then + CLK_LOCK := true; + SDATA_EDGE <= '0'; + elsif RXCLK = '0' then + CLK_LOCK := false; + end if; + + -- The timer controls the SDATA in a way, that after a detected valid + -- Transistion, the serial data is sampled on the 8th receiver clock + -- edge after the initial valid transition occured. + if RXCLK = '1' and SDATA_EDGE = '1' and TIMER_LOCK = false then + TIMER_LOCK := true; + TIMER := "000"; -- Resynchronisation. + elsif RXCLK = '1' and TIMER = "011" and TIMER_LOCK = false then + TIMER_LOCK := true; + SDATA_DIV16 <= NEW_SDATA; -- Scan the new data. + TIMER := TIMER + '1'; -- Timing is active. + elsif RXCLK = '1' and TIMER < "111" and TIMER_LOCK = false then + TIMER_LOCK := true; + TIMER := TIMER + '1'; -- Timing is active. + elsif RXCLK = '0' then + TIMER_LOCK := false; + end if; + end if; + end process P_SAMPLE; + + P_START_BIT: process(RESETn, CLK) + -- This is the valid start bit logic of the original MC68901 multi function + -- port's USART receiver. + variable TMP : std_logic_vector(2 downto 0); + variable LOCK : boolean; + begin + if RESETn = '0' then + TMP := "000"; + LOCK := true; + elsif CLK = '1' and CLK' event then + if RE = '0' or RCV_STATE /= IDLE then -- Start bit logic disabled. + TMP := "000"; + LOCK := true; + elsif SDATA_EDGE = '1' then + TMP := "000"; -- (Re)-Initialize. + LOCK := false; -- Start counting. + elsif RXCLK = '1' and SDATA_IN = '0' and TMP < "111" and LOCK = false then + LOCK := true; + TMP := TMP + '1'; -- Count 8 low bits to declare start condition valid. + elsif RXCLK = '0' then + LOCK := false; + end if; + end if; + + case TMP is + when "111" => STARTBIT <= true; + when others => STARTBIT <= false; + end case; + end process P_START_BIT; + + SDATA_IN_I <= SDATA_IN when CLK_MODE = '0' else -- Clock div by 1 mode. + SDATA_IN when ST = "00" else SDATA_DIV16; -- Synchronous mode. + + CLKDIV: process + variable CLK_LOCK : boolean; + variable STRB_LOCK : boolean; + variable CLK_DIVCNT : std_logic_vector(4 downto 0); + begin + wait until CLK = '1' and CLK' event; + if CLK_MODE = '0' then -- Divider off. + if RXCLK = '1' and STRB_LOCK = false then + CLK_STRB <= '1'; + STRB_LOCK := true; + elsif RXCLK = '0' then + CLK_STRB <= '0'; + STRB_LOCK := false; + else + CLK_STRB <= '0'; + end if; + CLK_2_STRB <= '0'; -- No 1 1/2 stop bits in no div by 16 mode. + elsif SDATA_EDGE = '1' then +CLK_DIVCNT := "01100"; -- Div by 16 mode. + CLK_STRB <= '0'; -- Default. + CLK_2_STRB <= '0'; -- Default. + else + CLK_STRB <= '0'; -- Default. + CLK_2_STRB <= '0'; -- Default. + if CLK_DIVCNT > "00000" and RXCLK = '1' and CLK_LOCK = false then + CLK_DIVCNT := CLK_DIVCNT - '1'; + CLK_LOCK := true; + if CLK_DIVCNT = "01000" then + -- This strobe is asserted at half of the clock cycle. + -- It is used for the stop bit timing. + CLK_2_STRB <= '1'; + end if; + elsif CLK_DIVCNT = "00000" then + CLK_DIVCNT := "10000"; -- Div by 16 mode. + if STRB_LOCK = false then + STRB_LOCK := true; + CLK_STRB <= '1'; + end if; + elsif RXCLK = '0' then + CLK_LOCK := false; + STRB_LOCK := false; + end if; + end if; + end process CLKDIV; + + SHIFTREG: process(RESETn, CLK) + begin + if RESETn = '0' then + SHIFT_REG <= x"00"; + elsif CLK = '1' and CLK' event then + if RE = '0' then + SHIFT_REG <= x"00"; + elsif RCV_STATE = SAMPLE and CLK_STRB = '1' then + SHIFT_REG <= SDATA_IN_I & SHIFT_REG(7 downto 1); -- Shift right. + end if; + end if; + end process SHIFTREG; + + P_M_CIP: process(RESETn, CLK) + -- In Synchronous mode this flag indicates wether a synchronous character M_CIP = '1' + -- or another character (M_CIP = '0') is transferred to the receive buffer. + -- In asynchronous mode the flag indicates sampling condition. + begin + if RESETn = '0' then + M_CIP <= '0'; + elsif CLK = '0' and CLK' event then + if RE = '0' then + M_CIP <= '0'; + elsif ST = "00" then -- Synchronous mode. + if RCV_STATE = SYNC and SHIFT_REG = SCR and RDRF = '0' then + M_CIP <= '1'; -- SCR transferred. + elsif RCV_STATE = SYNC and RDRF = '0' then + M_CIP <= '0'; -- No SCR transferred. + end if; + else -- Asynchronous mode. + case RCV_STATE is + when SAMPLE | PARITY | STOP1 | STOP2 => M_CIP <= '1'; -- Sampling. + when others => M_CIP <= '0'; -- No Sampling. + end case; + end if; + end if; + end process P_M_CIP; + + BREAK_DETECT: process(RESETn, CLK) + -- A break condition occurs, if there is no STOP1 bit and the + -- shift register contains zero data. + begin + if RESETn = '0' then + BREAK <= false; + elsif CLK = '1' and CLK' event then + if RE = '0' then + BREAK <= false; + elsif CLK_STRB = '1' then + if RCV_STATE = STOP1 and SDATA_IN_I = '0' and SHIFT_REG = x"00" then + BREAK <= true; -- Break detected (empty shift register and no stop bit). + elsif RCV_STATE = STOP1 and SDATA_IN_I = '1' then + BREAK <= false; -- UPDATE. + elsif RCV_STATE = STOP1 and SDATA_IN_I = '0' and SHIFT_REG /= x"00" then + BREAK <= false; -- UPDATE, but framing error. + end if; + end if; + end if; + end process BREAK_DETECT; + + P_FS_B: process(RESETn, CLK) + -- In the synchronous mode, this process provides the flag detecting the synchronous + -- character. In the asynchronous mode, the flag indicates a break condition. + variable FS_B_I : bit; + variable FIRST_READ : boolean; + begin + if RESETn = '0' then + FS_B <= '0'; + FIRST_READ := false; + FS_B_I := '0'; + elsif CLK = '0' and CLK' event then + if RE = '0' then + FS_B <= '0'; + FS_B_I := '0'; + else + if ST = "00" then -- Synchronous operation. + if FS_CLR = '1' then + FS_B <= '0'; -- Clear during writing to the SCR. + elsif SHIFT_REG = SCR then + FS_B <= '1'; -- SCR detected. + end if; + else -- Asynchronous operation. + if RX_SAMPLE = '1' and BREAK = true then -- Break condition detected. + FS_B_I := '1'; -- Update. + elsif RX_SAMPLE = '1' then -- No break condition. + FS_B_I := '0'; -- Update. + elsif RSR_READ = '1' and FS_B_I = '1' then + -- If a break condition was detected, the concerning flag is + -- set when the valid data word in the receiver data + -- register is read. Thereafter the break flag is reset + -- and the break condition disappears after a second read + -- (in time) of the receiver status register. + if FIRST_READ = false then + FS_B <= '1'; + FIRST_READ := true; + else + FS_B <= '0'; + FIRST_READ := false; + end if; + end if; + end if; + end if; + end if; + end process P_FS_B; + + P_BITCNT: process + begin + wait until CLK = '1' and CLK' event; + if RCV_STATE = SAMPLE and CLK_STRB = '1' and ST /= "00" then -- Asynchronous mode. + BITCNT <= BITCNT + '1'; + elsif RCV_STATE = SAMPLE and CLK_STRB = '1' and ST = "00" and FS_B = '1' then -- Synchronous mode. + BITCNT <= BITCNT + '1'; -- Count, if matched data found (FS_B = '1'). + elsif RCV_STATE /= SAMPLE then + BITCNT <= (others => '0'); + end if; + end process P_BITCNT; + + BUFFER_FULL: process(RESETn, CLK) + -- Receive data register full flag. + begin + if RESETn = '0' then + RDRF <= '0'; + elsif CLK = '1' and CLK' event then + if RE = '0' then + RDRF <= '0'; + elsif RX_SAMPLE = '1' then + RDRF <= '1'; -- Data register is full until now! + elsif UDR_READ = '1' then + RDRF <= '0'; -- After reading the data register ... + end if; + end if; + end process BUFFER_FULL; + + OVERRUN: process(RESETn, CLK) + variable OE_I : bit; + variable FIRST_READ : boolean; + begin + if RESETn = '0' then + OE_I := '0'; + OE <= '0'; + FIRST_READ := false; + elsif CLK = '1' and CLK' event then + if RESETn = '0' then + OE_I := '0'; + OE <= '0'; + FIRST_READ := false; + elsif CLK_STRB = '1' and RCV_STATE = SYNC and BREAK = false then + -- Overrun appears if RDRF is '1' in this state and there + -- is no break condition. + OE_I := RDRF; + end if; + if RSR_READ = '1' and OE_I = '1' then + -- if an overrun was detected, the concerning flag is + -- set when the valid data word in the receiver data + -- register is read. Thereafter the RDRF flag is reset + -- and the overrun disappears (OE_I goes low) after + -- a second read (in time) of the receiver data register. + if FIRST_READ = false then + OE <= '1'; + FIRST_READ := true; + else + OE <= '0'; + FIRST_READ := false; + end if; + end if; + end if; + end process OVERRUN; + + PARITY_TEST: process(RESETn, CLK) + variable PAR_TMP : bit; + variable P_ERR : bit; + begin + if RESETn = '0' then + PE <= '0'; + elsif CLK = '1' and CLK' event then + if RE = '0' then + PE <= '0'; + elsif RX_SAMPLE = '1' then + PE <= P_ERR; -- Update on load shift register to data register. + elsif CLK_STRB = '1' then -- Sample parity on clock strobe. + P_ERR := '0'; -- Initialise. + if RCV_STATE = PARITY then + for i in 1 to 7 loop + if i = 1 then + PAR_TMP := SHIFT_REG(i-1) xor SHIFT_REG(i); + else + PAR_TMP := PAR_TMP xor SHIFT_REG(i); + end if; + end loop; + if P_ENA = '1' and P_EOn = '1' then -- Even parity. + P_ERR := PAR_TMP xor SDATA_IN_I; + elsif P_ENA = '1' and P_EOn = '0' then -- Odd parity. + P_ERR := not PAR_TMP xor SDATA_IN_I; + elsif P_ENA = '0' then -- No parity. + P_ERR := '0'; + end if; + end if; + end if; + end if; + end process PARITY_TEST; + + FRAME_ERR: process(RESETn, CLK) + -- This module detects a framing error + -- during stop bit 1 and stop bit 2. + variable FE_I: bit; + begin + if RESETn = '0' then + FE_I := '0'; + FE <= '0'; + elsif CLK = '1' and CLK' event then + if RE = '0' then + FE_I := '0'; + FE <= '0'; + elsif CLK_STRB = '1' then + if RCV_STATE = STOP1 and SDATA_IN_I = '0' and SHIFT_REG /= x"00" then + FE_I := '1'; + elsif RCV_STATE = STOP2 and SDATA_IN_I = '0' and SHIFT_REG /= x"00" then + FE_I := '1'; + elsif RCV_STATE = STOP1 or RCV_STATE = STOP2 then + FE_I := '0'; -- Error resets when correct data appears. + end if; + end if; + if RCV_STATE = SYNC then + FE <= FE_I; -- Update the FE every SYNC time. + end if; + end if; + end process FRAME_ERR; + + RCV_STATEREG: process(RESETn, CLK) + begin + if RESETn = '0' then + RCV_STATE <= IDLE; + elsif CLK = '1' and CLK' event then + if RE = '0' then + RCV_STATE <= IDLE; + else + RCV_STATE <= RCV_NEXT_STATE; + end if; + end if; + end process RCV_STATEREG; + + RCV_STATEDEC: process(RCV_STATE, SDATA_IN_I, BITCNT, CLK_STRB, STARTBIT, + CLK_2_STRB, ST, CLK_MODE, CL, P_ENA, SHIFT_REG) + begin + case RCV_STATE is + when IDLE => + if ST = "00" then + RCV_NEXT_STATE <= SAMPLE; -- Synchronous mode. + elsif SDATA_IN_I = '0' and CLK_MODE = '0' then + RCV_NEXT_STATE <= SAMPLE; -- Startbit detected in div by 1 mode. + elsif STARTBIT = true and CLK_MODE = '1' then + RCV_NEXT_STATE <= WAIT_START; -- Startbit detected in div by 16 mode. + else + RCV_NEXT_STATE <= IDLE; -- No startbit; sleep well :-) + end if; + when WAIT_START => + -- This state delays the sample process by one CLK_STRB pulse + -- to eliminate the start bit. + if CLK_STRB = '1' then + RCV_NEXT_STATE <= SAMPLE; + else + RCV_NEXT_STATE <= WAIT_START; + end if; + when SAMPLE => + if CLK_STRB = '1' then + if CL = "11" and BITCNT < "100" then + RCV_NEXT_STATE <= SAMPLE; -- Go on sampling 5 data bits. + elsif CL = "10" and BITCNT < "101" then + RCV_NEXT_STATE <= SAMPLE; -- Go on sampling 6 data bits. + elsif CL = "01" and BITCNT < "110" then + RCV_NEXT_STATE <= SAMPLE; -- Go on sampling 7 data bits. + elsif CL = "00" and BITCNT < "111" then + RCV_NEXT_STATE <= SAMPLE; -- Go on sampling 8 data bits. + elsif ST = "00" and P_ENA = '0' then -- Synchronous mode (no stop bits). + RCV_NEXT_STATE <= IDLE; -- No parity check enabled. + elsif P_ENA = '0' then + RCV_NEXT_STATE <= STOP1; -- No parity check enabled. + else + RCV_NEXT_STATE <= PARITY; -- Parity enabled. + end if; + else + RCV_NEXT_STATE <= SAMPLE; -- Stay in sample mode. + end if; + when PARITY => + if CLK_STRB = '1' then + if ST = "00" then -- Synchronous mode (no stop bits). + RCV_NEXT_STATE <= IDLE; + else + RCV_NEXT_STATE <= STOP1; + end if; + else + RCV_NEXT_STATE <= PARITY; + end if; + when STOP1 => + if CLK_STRB = '1' then + if SHIFT_REG > x"00" and SDATA_IN_I = '0' then -- No Stop bit after non zero data. + RCV_NEXT_STATE <= SYNC; -- Framing error detected. + elsif ST = "11" or ST = "10" then + RCV_NEXT_STATE <= STOP2; -- More than one stop bits selected. + else + RCV_NEXT_STATE <= SYNC; -- One stop bit selected. + end if; + else + RCV_NEXT_STATE <= STOP1; + end if; + when STOP2 => + if CLK_2_STRB = '1' and ST = "10" then + RCV_NEXT_STATE <= SYNC; -- One and a half stop bits selected. + elsif CLK_STRB = '1' then + RCV_NEXT_STATE <= SYNC; -- Two stop bits selected. + else + RCV_NEXT_STATE <= STOP2; + end if; + when SYNC => + RCV_NEXT_STATE <= IDLE; + end case; + end process RCV_STATEDEC; +end architecture BEHAVIOR; + diff --git a/vhdl/rtl/vhdl/WF_MFP68901_IP/Test_USART_Tx/wf68901ip_usart_tx.vhd b/vhdl/rtl/vhdl/WF_MFP68901_IP/Test_USART_Tx/wf68901ip_usart_tx.vhd new file mode 100644 index 0000000..69dd6db --- /dev/null +++ b/vhdl/rtl/vhdl/WF_MFP68901_IP/Test_USART_Tx/wf68901ip_usart_tx.vhd @@ -0,0 +1,379 @@ +---------------------------------------------------------------------- +---- ---- +---- ATARI MFP compatible IP Core ---- +---- ---- +---- This file is part of the SUSKA ATARI clone project. ---- +---- http://www.experiment-s.de ---- +---- ---- +---- Description: ---- +---- This is the SUSKA MFP IP core USART transmitter file. ---- +---- ---- +---- ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2006 Wolfgang Foerster ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.gnu.org/licenses/lgpl.html ---- +---- ---- +---------------------------------------------------------------------- +-- +-- Revision History +-- +-- Revision 1.0 2006/03/31 WF +-- Initial Release. +-- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + +entity WF68901IP_USART_TX is + port ( + CLK : in bit; + RESETn : in bit; + + SCR : in bit_vector(7 downto 0); -- Synchronous character. + TX_DATA : in bit_vector(7 downto 0); -- Normal data. + + SDATA_OUT : out bit; -- Serial data output. + TXCLK : in bit; -- Transmitter clock. + + CL : in bit_vector(1 downto 0); -- Character length. + ST : in bit_vector(1 downto 0); -- Start and stop bit configuration. + TE : in bit; -- Transmitter enable. + BR : in bit; -- BREAK character send enable (all '0' without stop bit). + P_ENA : in bit; -- Parity enable. + P_EOn : in bit; -- Even or odd parity. + UDR_WRITE : in bit; -- Flag indicating writing the data register. + TSR_READ : in bit; -- Flag indicating reading the transmitter status register. + CLK_MODE : in bit; -- Transmitter clock mode. + + TX_END : out bit; -- End of transmission flag. + UE : out bit; -- Underrun Flag. + BE : out bit -- Buffer empty flag. + ); +end entity WF68901IP_USART_TX; + +architecture BEHAVIOR of WF68901IP_USART_TX is +type TR_STATES is (IDLE, CHECK_BREAK, LOAD_SHFT, START, SHIFTOUT, PARITY, STOP1, STOP2); +signal TR_STATE, TR_NEXT_STATE : TR_STATES; +signal CLK_STRB : bit; +signal CLK_2_STRB : bit; +signal SHIFT_REG : bit_vector(7 downto 0); +signal BITCNT : std_logic_vector(2 downto 0); +signal PARITY_I : bit; +signal TDRE : bit; +signal BREAK : bit; +begin + BE <= TDRE; -- Buffer empty flag. + + -- The default condition in this statement is to ensure + -- to cover all possibilities for example if there is a + -- one hot decoding of the state machine with wrong states + -- (e.g. not one of the given here). + SDATA_OUT <= '0' when BREAK = '1' else + '1' when TR_STATE = IDLE else + '1' when TR_STATE = LOAD_SHFT else + '0' when TR_STATE = START else + SHIFT_REG(0) when TR_STATE = SHIFTOUT else + PARITY_I when TR_STATE = PARITY else + '1' when TR_STATE = STOP1 else + '1' when TR_STATE = STOP2 else '1'; + + P_BREAK : process(RESETn, CLK) + -- This process is responsible to control the BREAK signal. After the break request + -- is asserted via BR, the break character will be sent after the current transmission has + -- finished. The BREAK character is sent until the BR is disabled. + variable LOCK : boolean; + begin + if RESETn = '0' then + BREAK <= '0'; + elsif CLK = '1' and CLK' event then + -- Break is only available in the asynchronous mode (ST /= "00"). + -- The LOCK mechanism is reponsible for sending the BREAK character just once. + if TE = '1' and BR = '1' and ST /= "00" and TR_STATE = IDLE and LOCK = false then + BREAK <= '1'; -- Break for the case that there is no current transmission. + LOCK := true; + elsif BR = '1' and ST /= "00" and TR_STATE = STOP1 then + BREAK <= '0'; -- Break character sent. + elsif BR = '0' then + BREAK <= '0'; + LOCK := false; + else + BREAK <= '0'; + end if; + end if; + end process P_BREAK; + + CLKDIV: process + variable CLK_LOCK : boolean; + variable STRB_LOCK : boolean; + variable CLK_DIVCNT : std_logic_vector(4 downto 0); + begin + wait until CLK = '1' and CLK' event; + if CLK_MODE = '0' then -- Divider off. + if TXCLK = '0' and STRB_LOCK = false then -- Works on negative TXCLK edge. + CLK_STRB <= '1'; + STRB_LOCK := true; + elsif TXCLK = '1' then + CLK_STRB <= '0'; + STRB_LOCK := false; + else + CLK_STRB <= '0'; + end if; + CLK_2_STRB <= '0'; -- No 1 1/2 stop bits in no div by 16 mode. + else + CLK_STRB <= '0'; -- Default. + CLK_2_STRB <= '0'; -- Default. + -- Works on negative TXCLK edge: + if CLK_DIVCNT > "00000" and TXCLK = '0' and CLK_LOCK = false then + CLK_DIVCNT := CLK_DIVCNT - '1'; + CLK_LOCK := true; + if CLK_DIVCNT = "01000" then + -- This strobe is asserted at half of the clock cycle. + -- It is used for the stop bit timing. + CLK_2_STRB <= '1'; + end if; + elsif CLK_DIVCNT = "00000" then + CLK_DIVCNT := "10000"; -- Div by 16 mode. + if STRB_LOCK = false then + STRB_LOCK := true; + CLK_STRB <= '1'; + end if; + elsif TXCLK = '1' then + CLK_LOCK := false; + STRB_LOCK := false; + end if; + end if; + end process CLKDIV; + + SHIFTREG: process(RESETn, CLK) + begin + if RESETn = '0' then + SHIFT_REG <= x"00"; + elsif CLK = '1' and CLK' event then + if TR_STATE = LOAD_SHFT and TDRE = '1' then -- Lost data ... + case ST is + when "00" => -- Synchronous mode. + SHIFT_REG <= SCR; -- Send the synchronous character. + when others => -- Asynchronous mode. + SHIFT_REG <= x"5A"; -- Load the shift register with a mark (underrun). + end case; + elsif TR_STATE = LOAD_SHFT then + -- Load 'normal' data if there is no break condition: + case CL is + when "11" => SHIFT_REG <= "000" & TX_DATA(4 downto 0); -- 5 databits. + when "10" => SHIFT_REG <= "00" & TX_DATA(5 downto 0); -- 6 databits. + when "01" => SHIFT_REG <= '0' & TX_DATA(6 downto 0); -- 7 databits. + when "00" => SHIFT_REG <= TX_DATA; -- 8 databits. + end case; + elsif TR_STATE = SHIFTOUT and CLK_STRB = '1' then + SHIFT_REG <= '0' & SHIFT_REG(7 downto 1); -- Shift right. + end if; + end if; + end process SHIFTREG; + + P_BITCNT: process + -- Counter for the data bits transmitted. + begin + wait until CLK = '1' and CLK' event; + if TR_STATE = SHIFTOUT and CLK_STRB = '1' then + BITCNT <= BITCNT + '1'; + elsif TR_STATE /= SHIFTOUT then + BITCNT <= "000"; + end if; + end process P_BITCNT; + + BUFFER_EMPTY: process(RESETn, CLK) + -- Transmit data register empty flag. + begin + if RESETn = '0' then + TDRE <= '1'; + elsif CLK = '1' and CLK' event then + if TE = '0' then + TDRE <= '1'; + elsif TR_STATE = START and BREAK = '0' then + -- Data has been loaded to the shift register, + -- thus data register is free again. + -- If the BREAK flag is enabled, the BE flag + -- respective TDRE flag cannot be set. + TDRE <= '1'; + elsif UDR_WRITE = '1' then + TDRE <= '0'; + end if; + end if; + end process BUFFER_EMPTY; + + UNDERRUN: process(RESETn, CLK) + variable LOCK : boolean; + begin + if RESETn = '0' then + UE <= '0'; + LOCK := false; + elsif CLK = '1' and CLK' event then + if TE = '0' then + UE <= '0'; + LOCK := false; + elsif CLK_STRB = '1' and TR_STATE = START then + -- Underrun appears if TDRE is '0' at the end of this state. + UE <= TDRE; -- Never true for enabled BREAK flag. See alos process BUFFER_EMPTY. + LOCK := true; + elsif CLK_STRB = '1' then + LOCK := false; -- Disables clearing UE one transmit clock cycle. + elsif TSR_READ = '1' and LOCK = false then + UE <= '0'; + end if; + end if; + end process UNDERRUN; + + P_TX_END: process(RESETn, CLK) + begin + if RESETn = '0' then + TX_END <= '0'; + elsif CLK = '1' and CLK' event then + if TE = '1' then -- Transmitter enabled. + TX_END <= '0'; + elsif TE = '0' and TR_STATE = IDLE then + TX_END <= '1'; + end if; + end if; + end process P_TX_END; + + PARITY_GEN: process + variable PAR_TMP : bit; + begin + wait until CLK = '1' and CLK' event; + if TR_STATE = START then -- Calculate the parity during the start phase. + for i in 1 to 7 loop + if i = 1 then + PAR_TMP := SHIFT_REG(i-1) xor SHIFT_REG(i); + else + PAR_TMP := PAR_TMP xor SHIFT_REG(i); + end if; + end loop; + if P_ENA = '1' and P_EOn = '1' then -- Even parity. + PARITY_I <= PAR_TMP; + elsif P_ENA = '1' and P_EOn = '0' then -- Odd parity. + PARITY_I <= not PAR_TMP; + else -- No parity. + PARITY_I <= '0'; + end if; + end if; + end process PARITY_GEN; + + TR_STATEREG: process(RESETn, CLK) + begin + if RESETn = '0' then + TR_STATE <= IDLE; + elsif CLK = '1' and CLK' event then + TR_STATE <= TR_NEXT_STATE; + end if; + end process TR_STATEREG; + + TR_STATEDEC: process(TR_STATE, CLK_STRB, CLK_2_STRB, BITCNT, TDRE, BREAK, TE, ST, P_ENA, CL, BR) + begin + case TR_STATE is + when IDLE => + -- This IDLE state is just one clock cycle and is required to give the + -- break process time to set the BREAK flag. + TR_NEXT_STATE <= CHECK_BREAK; + when CHECK_BREAK => + if BREAK = '1' then -- Send break character. + -- Do not load any data to the shift register, go directly + -- to the START state. + TR_NEXT_STATE <= START; + -- Start enabled transmitter, if the data register is not empty. + -- Do not send any further data for the case of an asserted BR flag. + elsif TE = '1' and TDRE = '0' and BR = '0' then + TR_NEXT_STATE <= LOAD_SHFT; + else + TR_NEXT_STATE <= IDLE; -- Go back, scan for BREAK. + end if; + when LOAD_SHFT => + TR_NEXT_STATE <= START; + when START => + if CLK_STRB = '1' then + TR_NEXT_STATE <= SHIFTOUT; + else + TR_NEXT_STATE <= START; + end if; + when SHIFTOUT => + if CLK_STRB = '1' then + if BITCNT < "100" and CL = "11" then + TR_NEXT_STATE <= SHIFTOUT; -- Transmit 5 data bits. + elsif BITCNT < "101" and CL = "10" then + TR_NEXT_STATE <= SHIFTOUT; -- Transmit 6 data bits. + elsif BITCNT < "110" and CL = "01" then + TR_NEXT_STATE <= SHIFTOUT; -- Transmit 7 data bits. + elsif BITCNT < "111" and CL = "00" then + TR_NEXT_STATE <= SHIFTOUT; -- Transmit 8 data bits. + elsif P_ENA = '0' and BREAK = '1' then + TR_NEXT_STATE <= IDLE; -- Break condition, no parity check enabled, no stop bits. + elsif P_ENA = '0' and ST = "00" then + TR_NEXT_STATE <= IDLE; -- Synchronous mode, no parity check enabled. + elsif P_ENA = '0' then + TR_NEXT_STATE <= STOP1; -- Asynchronous mode, no parity check enabled. + else + TR_NEXT_STATE <= PARITY; -- Parity enabled. + end if; + else + TR_NEXT_STATE <= SHIFTOUT; + end if; + when PARITY => + if CLK_STRB = '1' then + if ST = "00" then -- Synchronous mode (no stop bits). + TR_NEXT_STATE <= IDLE; + elsif BREAK = '1' then -- No stop bits during break condition. + TR_NEXT_STATE <= IDLE; + else + TR_NEXT_STATE <= STOP1; + end if; + else + TR_NEXT_STATE <= PARITY; + end if; + when STOP1 => + if CLK_STRB = '1' and (ST = "11" or ST = "10") then + TR_NEXT_STATE <= STOP2; -- More than one stop bits selected. + elsif CLK_STRB = '1' then + TR_NEXT_STATE <= IDLE; -- One stop bits selected. + else + TR_NEXT_STATE <= STOP1; + end if; + when STOP2 => + if CLK_2_STRB = '1' and ST = "10" then + TR_NEXT_STATE <= IDLE; -- One and a half stop bits selected. + elsif CLK_STRB = '1' then + TR_NEXT_STATE <= IDLE; -- Two stop bits detected. + else + TR_NEXT_STATE <= STOP2; + end if; + end case; + end process TR_STATEDEC; +end architecture BEHAVIOR; + diff --git a/vhdl/rtl/vhdl/WF_MFP68901_IP/wf68901ip_gpio.vhd b/vhdl/rtl/vhdl/WF_MFP68901_IP/wf68901ip_gpio.vhd new file mode 100644 index 0000000..ce5b196 --- /dev/null +++ b/vhdl/rtl/vhdl/WF_MFP68901_IP/wf68901ip_gpio.vhd @@ -0,0 +1,141 @@ +---------------------------------------------------------------------- +---- ---- +---- ATARI MFP compatible IP Core ---- +---- ---- +---- This file is part of the SUSKA ATARI clone project. ---- +---- http://www.experiment-s.de ---- +---- ---- +---- Description: ---- +---- MC68901 compatible multi function port core. ---- +---- ---- +---- This are the SUSKA MFP IP core's general purpose I/Os. ---- +---- ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2006 - 2011 Wolfgang Foerster ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.gnu.org/licenses/lgpl.html ---- +---- ---- +---------------------------------------------------------------------- +-- +-- Revision History +-- +-- Revision 2K6A 2006/06/03 WF +-- Initial Release. +-- Revision 2K6B 2006/11/07 WF +-- Modified Source to compile with the Xilinx ISE. +-- Revision 2K8A 2008/07/14 WF +-- Minor changes. +-- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + +entity WF68901IP_GPIO is + port ( -- System control: + CLK : in bit; + RESETn : in bit; + + -- Asynchronous bus control: + DSn : in bit; + CSn : in bit; + RWn : in bit; + + -- Data and Adresses: + RS : in bit_vector(5 downto 1); + DATA_IN : in bit_vector(7 downto 0); + DATA_OUT : out bit_vector(7 downto 0); + DATA_OUT_EN : out bit; + + -- Timer controls: + AER_4 : out bit; + AER_3 : out bit; + + GPIP_IN : in bit_vector(7 downto 0); + GPIP_OUT : out bit_vector(7 downto 0); + GPIP_OUT_EN : buffer bit_vector(7 downto 0); + GP_INT : out bit_vector(7 downto 0) + ); +end entity WF68901IP_GPIO; + +architecture BEHAVIOR of WF68901IP_GPIO is +signal GPDR : bit_vector(7 downto 0); +signal DDR : bit_vector(7 downto 0); +signal AER : bit_vector(7 downto 0); +signal GPDR_I : bit_vector(7 downto 0); +begin + -- These two bits control the timers A and B pulse width operation and the + -- timers A and B event count operation. + AER_4 <= AER(4); + AER_3 <= AER(3); + -- This statement provides 8 XOR units setting the desired interrupt polarity. + -- While the level control is done here, the edge triggering is provided by + -- the interrupt control hardware. The level control is individually for each + -- GPIP port pin. The interrupt edge trigger unit must operate in any case on + -- the low to high transistion of the respective port pin. + GP_INT <= AER xnor GPIP_IN; + + GPIO_REGISTERS: process(RESETn, CLK) + begin + if RESETn = '0' then + GPDR <= (others => '0'); + DDR <= (others => '0'); + AER <= (others => '0'); + elsif CLK = '1' and CLK' event then + if CSn = '0' and DSn = '0' and RWn = '0' then + case RS is + when "00000" => GPDR <= DATA_IN; + when "00001" => AER <= DATA_IN; + when "00010" => DDR <= DATA_IN; + when others => null; + end case; + end if; + end if; + end process GPIO_REGISTERS; + GPIP_OUT <= GPDR; -- Port outputs. + GPIP_OUT_EN <= DDR; -- The DDR is capable to control bitwise the GPIP. + DATA_OUT_EN <= '1' when CSn = '0' and DSn = '0' and RWn = '1' and RS <= "00010" else '0'; + DATA_OUT <= DDR when CSn = '0' and DSn = '0' and RWn = '1' and RS = "00010" else + AER when CSn = '0' and DSn = '0' and RWn = '1' and RS = "00001" else + GPDR_I when CSn = '0' and DSn = '0' and RWn = '1' and RS = "00000" else (others => '0'); + + P_GPDR: process(GPIP_IN, GPIP_OUT_EN, GPDR) + -- Read back control: Read the port pins, if the data direction is configured as input. + -- Read the respective GPDR register bit, if the data direction is configured as output. + begin + for i in 7 downto 0 loop + if GPIP_OUT_EN(i) = '1' then -- Port is configured output. + GPDR_I(i) <= GPDR(i); + else + GPDR_I(i) <= GPIP_IN(i); -- Port is configured input. + end if; + end loop; + end process P_GPDR; +end architecture BEHAVIOR; diff --git a/vhdl/rtl/vhdl/WF_MFP68901_IP/wf68901ip_interrupts.vhd b/vhdl/rtl/vhdl/WF_MFP68901_IP/wf68901ip_interrupts.vhd new file mode 100644 index 0000000..931ce78 --- /dev/null +++ b/vhdl/rtl/vhdl/WF_MFP68901_IP/wf68901ip_interrupts.vhd @@ -0,0 +1,391 @@ +---------------------------------------------------------------------- +---- ---- +---- ATARI MFP compatible IP Core ---- +---- ---- +---- This file is part of the SUSKA ATARI clone project. ---- +---- http://www.experiment-s.de ---- +---- ---- +---- Description: ---- +---- MC68901 compatible multi function port core. ---- +---- ---- +---- This is the SUSKA MFP IP core interrupt logic file. ---- +---- ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2006 - 2011 Wolfgang Foerster ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.gnu.org/licenses/lgpl.html ---- +---- ---- +---------------------------------------------------------------------- +-- +-- Revision History +-- +-- Revision 2K6A 2006/06/03 WF +-- Initial Release. +-- Revision 2K6B 2006/11/07 WF +-- Modified Source to compile with the Xilinx ISE. +-- Revision 2K8A 2008/06/03 WF +-- Fixed Pending register logic. +-- Revision 2K9A 2009/06/20 WF +-- Fixed interrupt polarity for TA_I and TB_I. +-- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + +entity WF68901IP_INTERRUPTS is + port ( -- System control: + CLK : in bit; + RESETn : in bit; + + -- Asynchronous bus control: + DSn : in bit; + CSn : in bit; + RWn : in bit; + + -- Data and Adresses: + RS : in bit_vector(5 downto 1); + DATA_IN : in bit_vector(7 downto 0); + DATA_OUT : out bit_vector(7 downto 0); + DATA_OUT_EN : out bit; + + -- Interrupt control: + IACKn : in bit; + IEIn : in bit; + IEOn : out bit; + IRQn : out bit; + + -- Interrupt sources: + GP_INT : in bit_vector(7 downto 0); + + AER_4 : in bit; + AER_3 : in bit; + TAI : in bit; + TBI : in bit; + TA_PWM : in bit; + TB_PWM : in bit; + TIMER_A_INT : in bit; + TIMER_B_INT : in bit; + TIMER_C_INT : in bit; + TIMER_D_INT : in bit; + + RCV_ERR : in bit; + TRM_ERR : in bit; + RCV_BUF_F : in bit; + TRM_BUF_E : in bit + ); +end entity WF68901IP_INTERRUPTS; + +architecture BEHAVIOR of WF68901IP_INTERRUPTS is +-- Interrupt state machine: +type INT_STATES is (SCAN, REQUEST, VECTOR_OUT); +signal INT_STATE : INT_STATES; +-- The registers: +signal IERA : bit_vector(7 downto 0); +signal IERB : bit_vector(7 downto 0); +signal IPRA : bit_vector(7 downto 0); +signal IPRB : bit_vector(7 downto 0); +signal ISRA : bit_vector(7 downto 0); +signal ISRB : bit_vector(7 downto 0); +signal IMRA : bit_vector(7 downto 0); +signal IMRB : bit_vector(7 downto 0); +signal VR : bit_vector(7 downto 3); +-- Interconnect: +signal VECT_NUMBER : bit_vector(7 downto 0); +signal INT_SRC : bit_vector(15 downto 0); +signal INT_SRC_EDGE : bit_vector(15 downto 0); +signal INT_ENA : bit_vector(15 downto 0); +signal INT_MASK : bit_vector(15 downto 0); +signal INT_PENDING : bit_vector(15 downto 0); +signal INT_SERVICE : bit_vector(15 downto 0); +signal INT_PASS : bit_vector(15 downto 0); +signal INT_OUT : bit_vector(15 downto 0); +signal GP_INT_4 : bit; +signal GP_INT_3 : bit; +begin + -- Interrupt source for the GPI_4 and GPI_3 is normally the respective port pin. + -- But when the timers operate in their PWM modes, the GPI_4 and GPI_3 are associated + -- to timer A and timer B. + -- The xor logic provides polarity control for the interrupt transition. Be aware, + -- that the PWM signals cause an interrupt on the opposite transition like the + -- respective GPIP port pins (with the same AER settings). + --GP_INT_4 <= GP_INT(4) when TA_PWM = '0' else TAI xor AER_4; + --GP_INT_3 <= GP_INT(3) when TB_PWM = '0' else TBI xor AER_3; + GP_INT_4 <= GP_INT(4) when TA_PWM = '0' else TAI xnor AER_4; -- This should be correct. + GP_INT_3 <= GP_INT(3) when TB_PWM = '0' else TBI xnor AER_3; + + + -- Interrupt source priority sorted (15 = highest): + INT_SRC <= GP_INT(7 downto 6) & TIMER_A_INT & RCV_BUF_F & RCV_ERR & TRM_BUF_E & TRM_ERR & TIMER_B_INT & + GP_INT(5) & GP_INT_4 & TIMER_C_INT & TIMER_D_INT & GP_INT_3 & GP_INT(2 downto 0); + + INT_ENA <= IERA & IERB; + INT_MASK <= IMRA & IMRB; + INT_PENDING <= IPRA & IPRB; + INT_SERVICE <= ISRA & ISRB; + INT_OUT <= INT_PENDING and INT_MASK; -- Masking: + + -- Enable the daisy chain, if there is no pending interrupt and + -- the interrupt state machine is not in service. + IEOn <= '0' when INT_OUT = x"0000" and INT_STATE = SCAN else '1'; + + -- Interrupt request: + IRQn <= '0' when INT_OUT /= x"0000" and INT_STATE = REQUEST else '1'; + + EDGE_ENA: process(RESETn, CLK) + -- These are the 16 edge detectors of the 16 interrupt input sources. This + -- process also provides the disabling or enabling via the IERA and IERB registers. + variable LOCK : bit_vector(15 downto 0); + begin + if RESETn = '0' then + INT_SRC_EDGE <= x"0000"; + LOCK := x"0000"; + elsif CLK = '1' and CLK' event then + for i in 15 downto 0 loop + if INT_SRC(i) = '1' and INT_ENA(i) = '1' and LOCK(i) = '0' then + LOCK(i) := '1'; + INT_SRC_EDGE(i) <= '1'; + elsif INT_SRC(i) = '0' then + LOCK(i) := '0'; + INT_SRC_EDGE(i) <= '0'; + else + INT_SRC_EDGE(i) <= '0'; + end if; + end loop; + end if; + end process EDGE_ENA; + + INT_REGISTERS: process(RESETn, CLK) + begin + if RESETn = '0' then + IERA <= (others => '0'); + IERB <= (others => '0'); + IPRA <= (others => '0'); + IPRB <= (others => '0'); + ISRA <= (others => '0'); + ISRB <= (others => '0'); + IMRA <= (others => '0'); + IMRB <= (others => '0'); + elsif CLK = '1' and CLK' event then + if CSn = '0' and DSn = '0' and RWn = '0' then + case RS is + when "00011" => IERA <= DATA_IN; -- Enable A. + when "00100" => IERB <= DATA_IN; -- Enable B. + when "00101" => + -- Only a '0' can be written to the pending register. + for i in 7 downto 0 loop + if DATA_IN(i) = '0' then + IPRA(i) <= '0'; -- Pending A. + end if; + end loop; + when "00110" => + -- Only a '0' can be written to the pending register. + for i in 7 downto 0 loop + if DATA_IN(i) = '0' then + IPRB(i) <= '0'; -- Pending B. + end if; + end loop; + when "00111" => + -- Only a '0' can be written to the in service register. + for i in 7 downto 0 loop + if DATA_IN(i) = '0' then + ISRA(i) <= '0'; -- In Service A. + end if; + end loop; + when "01000" => + -- Only a '0' can be written to the in service register. + for i in 7 downto 0 loop + if DATA_IN(i) = '0' then + ISRB(i) <= '0'; -- In Service B. + end if; + end loop; + when "01001" => IMRA <= DATA_IN; -- Mask A. + when "01010" => IMRB <= DATA_IN; -- Mask B. + when "01011" => VR <= DATA_IN(7 downto 3); -- Vector register. + when others => null; + end case; + end if; + + -- Pending register: + -- set and clear bit logic. + for i in 15 downto 8 loop + if INT_SRC_EDGE(i) = '1' then + IPRA(i-8) <= '1'; + elsif INT_ENA(i) = '0' then + IPRA(i-8) <= '0'; -- Clear by disabling the channel. + elsif INT_PASS(i) = '1' then + IPRA(i-8) <= '0'; -- Clear by passing the interrupt. + end if; + end loop; + for i in 7 downto 0 loop + if INT_SRC_EDGE(i) = '1' then + IPRB(i) <= '1'; + elsif INT_ENA(i) = '0' then + IPRB(i) <= '0'; -- Clear by disabling the channel. + elsif INT_PASS(i) = '1' then + IPRB(i) <= '0'; -- Clear by passing the interrupt. + end if; + end loop; + + -- In-Service register: + -- Set bit logic, VR(3) is the service register enable. + for i in 15 downto 8 loop + if INT_OUT(i) = '1' and INT_PASS(i) = '1' and VR(3) = '1' then + ISRA(i-8) <= '1'; + end if; + end loop; + for i in 7 downto 0 loop + if INT_OUT(i) = '1' and INT_PASS(i) = '1' and VR(3) = '1' then + ISRB(i) <= '1'; + end if; + end loop; + end if; + end process INT_REGISTERS; + DATA_OUT_EN <= '1' when CSn = '0' and DSn = '0' and RWn = '1' and RS > "00010" and RS <= "01011" else '1' when INT_STATE = VECTOR_OUT else '0'; + + DATA_OUT <= IERA when CSn = '0' and DSn = '0' and RWn = '1' and RS = "00011" else + IERB when CSn = '0' and DSn = '0' and RWn = '1' and RS = "00100" else + IPRA when CSn = '0' and DSn = '0' and RWn = '1' and RS = "00101" else + IPRB when CSn = '0' and DSn = '0' and RWn = '1' and RS = "00110" else + ISRA when CSn = '0' and DSn = '0' and RWn = '1' and RS = "00111" else + ISRB when CSn = '0' and DSn = '0' and RWn = '1' and RS = "01000" else + IMRA when CSn = '0' and DSn = '0' and RWn = '1' and RS = "01001" else + IMRB when CSn = '0' and DSn = '0' and RWn = '1' and RS = "01010" else + VR & "000" when CSn = '0' and DSn = '0' and RWn = '1' and RS = "01011" else + VECT_NUMBER when INT_STATE = VECTOR_OUT else x"00"; + + P_INT_STATE : process(RESETn, CLK) + begin + if RESETn = '0' then + INT_STATE <= SCAN; + elsif CLK = '1' and CLK' event then + case INT_STATE is + when SCAN => + INT_PASS <= x"0000"; + -- Automatic End of Interrupt mode. Service register disabled. + -- The MFP does not respond for an interrupt acknowledge cycle for an uninitialized + -- vector number (VR(7 downto 4) = x"0"). + if INT_OUT /= x"0000" and VR(7 downto 4) /= x"0" and VR(3) = '0' and IEIn = '0' then + INT_STATE <= REQUEST; -- Non masked interrupt is pending. + -- The following 16 are the Software end of interrupt mode. Service register enabled. + -- The MFP does not respond for an interrupt acknowledge cycle for an uninitialized + -- vector number (VR(7 downto 4) = x"0"). The interrupts are prioritized. + elsif INT_OUT /= x"0000" and VR(7 downto 4) /= x"0" and VR(3) = '1' and IEIn = '0' then + if INT_OUT (15) = '1' and INT_SERVICE(15) = '0' then + INT_STATE <= REQUEST; + elsif INT_OUT (14) = '1' and INT_SERVICE(15 downto 14) = "00" then + INT_STATE <= REQUEST; + elsif INT_OUT (13) = '1' and INT_SERVICE(15 downto 13) = "000" then + INT_STATE <= REQUEST; + elsif INT_OUT (12) = '1' and INT_SERVICE(15 downto 12) = x"0" then + INT_STATE <= REQUEST; + elsif INT_OUT (11) = '1' and INT_SERVICE(15 downto 11) = x"0" & '0' then + INT_STATE <= REQUEST; + elsif INT_OUT (10) = '1' and INT_SERVICE(15 downto 10) = x"0" & "00" then + INT_STATE <= REQUEST; + elsif INT_OUT (9) = '1' and INT_SERVICE(15 downto 9) = x"0" & "000" then + INT_STATE <= REQUEST; + elsif INT_OUT (8) = '1' and INT_SERVICE(15 downto 8) = x"00" then + INT_STATE <= REQUEST; + elsif INT_OUT (7) = '1' and INT_SERVICE(15 downto 7) = x"00" & '0' then + INT_STATE <= REQUEST; + elsif INT_OUT (6) = '1' and INT_SERVICE(15 downto 6) = x"00" & "00" then + INT_STATE <= REQUEST; + elsif INT_OUT (5) = '1' and INT_SERVICE(15 downto 5) = x"00" & "000" then + INT_STATE <= REQUEST; + elsif INT_OUT (4) = '1' and INT_SERVICE(15 downto 4) = x"000" then + INT_STATE <= REQUEST; + elsif INT_OUT (3) = '1' and INT_SERVICE(15 downto 3) = x"000" & '0' then + INT_STATE <= REQUEST; + elsif INT_OUT (2) = '1' and INT_SERVICE(15 downto 2) = x"000" & "00" then + INT_STATE <= REQUEST; + elsif INT_OUT (1) = '1' and INT_SERVICE(15 downto 1) = x"000" & "000" then + INT_STATE <= REQUEST; + elsif INT_OUT (0) = '1' and INT_SERVICE(15 downto 0) = x"0000" then + INT_STATE <= REQUEST; + else + INT_STATE <= SCAN; -- Wait for interrupt. + end if; + else + INT_STATE <= SCAN; + end if; + when REQUEST => + if IACKn = '0' and DSn = '0' then -- Vectored interrupt mode. + INT_STATE <= VECTOR_OUT; -- Non masked interrupt is pending. + if INT_OUT(15) = '1' then + INT_PASS(15) <= '1'; VECT_NUMBER <= VR(7 downto 4) & x"F"; -- GPI 7. + elsif INT_OUT(14) = '1' then + INT_PASS(14) <= '1'; VECT_NUMBER <= VR(7 downto 4) & x"E"; -- GPI 6. + elsif INT_OUT(13) = '1' then + INT_PASS(13) <= '1'; VECT_NUMBER <= VR(7 downto 4) & x"D"; -- TIMER A. + elsif INT_OUT(12) = '1' then + INT_PASS(12) <= '1'; VECT_NUMBER <= VR(7 downto 4) & x"C"; -- Receive buffer full. + elsif INT_OUT(11) = '1' then + INT_PASS(11) <= '1'; VECT_NUMBER <= VR(7 downto 4) & x"B"; -- Receiver error. + elsif INT_OUT(10) = '1' then + INT_PASS(10) <= '1'; VECT_NUMBER <= VR(7 downto 4) & x"A"; -- Transmit buffer empty. + elsif INT_OUT(9) = '1' then + INT_PASS(9) <= '1'; VECT_NUMBER <= VR(7 downto 4) & x"9"; -- Transmit error. + elsif INT_OUT(8) = '1' then + INT_PASS(8) <= '1'; VECT_NUMBER <= VR(7 downto 4) & x"8"; -- Timer B. + elsif INT_OUT(7) = '1' then + INT_PASS(7) <= '1'; VECT_NUMBER <= VR(7 downto 4) & x"7"; -- GPI 5. + elsif INT_OUT(6) = '1' then + INT_PASS(6) <= '1'; VECT_NUMBER <= VR(7 downto 4) & x"6"; -- GPI 4. + elsif INT_OUT(5) = '1' then + INT_PASS(5) <= '1'; VECT_NUMBER <= VR(7 downto 4) & x"5"; -- Timer C. + elsif INT_OUT(4) = '1' then + INT_PASS(4) <= '1'; VECT_NUMBER <= VR(7 downto 4) & x"4"; -- Timer D. + elsif INT_OUT(3) = '1' then + INT_PASS(3) <= '1'; VECT_NUMBER <= VR(7 downto 4) & x"3"; -- GPI 3. + elsif INT_OUT(2) = '1' then + INT_PASS(2) <= '1'; VECT_NUMBER <= VR(7 downto 4) & x"2"; -- GPI 2. + elsif INT_OUT(1) = '1' then + INT_PASS(1) <= '1'; VECT_NUMBER <= VR(7 downto 4) & x"1"; -- GPI 1. + elsif INT_OUT(0) = '1' then + INT_PASS(0) <= '1'; VECT_NUMBER <= VR(7 downto 4) & x"0"; -- GPI 0. + end if; + -- Polled interrupt mode: End of interrupt by writing to the pending registers. + elsif CSn = '0' and DSn = '0' and RWn = '0' and (RS = "00101" or RS = "00110") then + INT_STATE <= SCAN; + else + INT_STATE <= REQUEST; -- Wait. + end if; + when VECTOR_OUT => + INT_PASS <= x"0000"; + if DSn = '1' or IACKn = '1' then + INT_STATE <= SCAN; -- Finished. + else + INT_STATE <= VECTOR_OUT; -- Wait for processor to read the vector. + end if; + end case; + end if; + end process P_INT_STATE; +end architecture BEHAVIOR; diff --git a/vhdl/rtl/vhdl/WF_MFP68901_IP/wf68901ip_pkg.vhd b/vhdl/rtl/vhdl/WF_MFP68901_IP/wf68901ip_pkg.vhd new file mode 100644 index 0000000..9d9f0e1 --- /dev/null +++ b/vhdl/rtl/vhdl/WF_MFP68901_IP/wf68901ip_pkg.vhd @@ -0,0 +1,263 @@ +---------------------------------------------------------------------- +---- ---- +---- ATARI MFP compatible IP Core ---- +---- ---- +---- This file is part of the SUSKA ATARI clone project. ---- +---- http://www.experiment-s.de ---- +---- ---- +---- Description: ---- +---- MC68901 compatible multi function port core. ---- +---- ---- +---- This is the package file containing the component ---- +---- declarations. ---- +---- ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2006 - 2011 Wolfgang Foerster ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.gnu.org/licenses/lgpl.html ---- +---- ---- +---------------------------------------------------------------------- +-- +-- Revision History +-- +-- Revision 2K6A 2006/06/03 WF +-- Initial Release. +-- Revision 2K6B 2006/11/07 WF +-- Modified Source to compile with the Xilinx ISE. +-- Revision 2K8A 2008/07/14 WF +-- Minor changes. +-- + +library ieee; +use ieee.std_logic_1164.all; + +package WF68901IP_PKG is +component WF68901IP_USART_TOP + port ( CLK : in bit; + RESETn : in bit; + DSn : in bit; + CSn : in bit; + RWn : in bit; + RS : in bit_vector(5 downto 1); + DATA_IN : in bit_vector(7 downto 0); + DATA_OUT : out bit_vector(7 downto 0); + DATA_OUT_EN : out bit; + RC : in bit; + TC : in bit; + SI : in bit; + SO : out bit; + SO_EN : out bit; + RX_ERR_INT : out bit; + RX_BUFF_INT : out bit; + TX_ERR_INT : out bit; + TX_BUFF_INT : out bit; + RRn : out bit; + TRn : out bit + ); +end component; + +component WF68901IP_USART_CTRL + port ( + CLK : in bit; + RESETn : in bit; + DSn : in bit; + CSn : in bit; + RWn : in bit; + RS : in bit_vector(5 downto 1); + DATA_IN : in bit_vector(7 downto 0); + DATA_OUT : out bit_vector(7 downto 0); + DATA_OUT_EN : out bit; + RX_SAMPLE : in bit; + RX_DATA : in bit_vector(7 downto 0); + TX_DATA : out bit_vector(7 downto 0); + SCR_OUT : out bit_vector(7 downto 0); + BF : in bit; + BE : in bit; + FE : in bit; + OE : in bit; + UE : in bit; + PE : in bit; + M_CIP : in bit; + FS_B : in bit; + TX_END : in bit; + CL : out bit_vector(1 downto 0); + ST : out bit_vector(1 downto 0); + FS_CLR : out bit; + RSR_READ : out bit; + TSR_READ : out bit; + UDR_READ : out bit; + UDR_WRITE : out bit; + LOOPBACK : out bit; + SDOUT_EN : out bit; + SD_LEVEL : out bit; + CLK_MODE : out bit; + RE : out bit; + TE : out bit; + P_ENA : out bit; + P_EOn : out bit; + SS : out bit; + BR : out bit + ); +end component; + +component WF68901IP_USART_TX + port ( + CLK : in bit; + RESETn : in bit; + SCR : in bit_vector(7 downto 0); + TX_DATA : in bit_vector(7 downto 0); + SDATA_OUT : out bit; + TXCLK : in bit; + CL : in bit_vector(1 downto 0); + ST : in bit_vector(1 downto 0); + TE : in bit; + BR : in bit; + P_ENA : in bit; + P_EOn : in bit; + UDR_WRITE : in bit; + TSR_READ : in bit; + CLK_MODE : in bit; + TX_END : out bit; + UE : out bit; + BE : out bit + ); +end component; + +component WF68901IP_USART_RX + port ( + CLK : in bit; + RESETn : in bit; + SCR : in bit_vector(7 downto 0); + RX_SAMPLE : out bit; + RX_DATA : out bit_vector(7 downto 0); + RXCLK : in bit; + SDATA_IN : in bit; + CL : in bit_vector(1 downto 0); + ST : in bit_vector(1 downto 0); + P_ENA : in bit; + P_EOn : in bit; + CLK_MODE : in bit; + RE : in bit; + FS_CLR : in bit; + SS : in bit; + RSR_READ : in bit; + UDR_READ : in bit; + M_CIP : out bit; + FS_B : out bit; + BF : out bit; + OE : out bit; + PE : out bit; + FE : out bit + ); +end component; + +component WF68901IP_INTERRUPTS + port ( + CLK : in bit; + RESETn : in bit; + DSn : in bit; + CSn : in bit; + RWn : in bit; + RS : in bit_vector(5 downto 1); + DATA_IN : in bit_vector(7 downto 0); + DATA_OUT : out bit_vector(7 downto 0); + DATA_OUT_EN : out bit; + IACKn : in bit; + IEIn : in bit; + IEOn : out bit; + IRQn : out bit; + GP_INT : in bit_vector(7 downto 0); + AER_4 : in bit; + AER_3 : in bit; + TAI : in bit; + TBI : in bit; + TA_PWM : in bit; + TB_PWM : in bit; + TIMER_A_INT : in bit; + TIMER_B_INT : in bit; + TIMER_C_INT : in bit; + TIMER_D_INT : in bit; + RCV_ERR : in bit; + TRM_ERR : in bit; + RCV_BUF_F : in bit; + TRM_BUF_E : in bit + ); +end component; + +component WF68901IP_GPIO + port ( + CLK : in bit; + RESETn : in bit; + DSn : in bit; + CSn : in bit; + RWn : in bit; + RS : in bit_vector(5 downto 1); + DATA_IN : in bit_vector(7 downto 0); + DATA_OUT : out bit_vector(7 downto 0); + DATA_OUT_EN : out bit; + AER_4 : out bit; + AER_3 : out bit; + GPIP_IN : in bit_vector(7 downto 0); + GPIP_OUT : out bit_vector(7 downto 0); + GPIP_OUT_EN : out bit_vector(7 downto 0); + GP_INT : out bit_vector(7 downto 0) + ); +end component; + +component WF68901IP_TIMERS + port ( + CLK : in bit; + RESETn : in bit; + DSn : in bit; + CSn : in bit; + RWn : in bit; + RS : in bit_vector(5 downto 1); + DATA_IN : in bit_vector(7 downto 0); + DATA_OUT : out bit_vector(7 downto 0); + DATA_OUT_EN : out bit; + XTAL1 : in bit; + TAI : in bit; + TBI : in bit; + AER_4 : in bit; + AER_3 : in bit; + TA_PWM : out bit; + TB_PWM : out bit; + TAO : out bit; + TBO : out bit; + TCO : out bit; + TDO : out bit; + TIMER_A_INT : out bit; + TIMER_B_INT : out bit; + TIMER_C_INT : out bit; + TIMER_D_INT : out bit + ); +end component; + +end WF68901IP_PKG; diff --git a/vhdl/rtl/vhdl/WF_MFP68901_IP/wf68901ip_timers.vhd b/vhdl/rtl/vhdl/WF_MFP68901_IP/wf68901ip_timers.vhd new file mode 100644 index 0000000..18b8204 --- /dev/null +++ b/vhdl/rtl/vhdl/WF_MFP68901_IP/wf68901ip_timers.vhd @@ -0,0 +1,530 @@ +---------------------------------------------------------------------- +---- ---- +---- ATARI MFP compatible IP Core ---- +---- ---- +---- This file is part of the SUSKA ATARI clone project. ---- +---- http://www.experiment-s.de ---- +---- ---- +---- Description: ---- +---- MC68901 compatible multi function port core. ---- +---- ---- +---- This is the SUSKA MFP IP core timers logic file. ---- +---- ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2006 - 2011 Wolfgang Foerster ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.gnu.org/licenses/lgpl.html ---- +---- ---- +---------------------------------------------------------------------- +-- +-- Revision History +-- +-- Revision 2K6A 2006/06/03 WF +-- Initial Release. +-- Revision 2K6B 2006/11/07 WF +-- Modified Source to compile with the Xilinx ISE. +-- Revision 2K7A 2006/12/28 WF +-- The timer is modified to work on the CLK instead +-- of XTAL1. This modification is done to provide +-- a synchronous design. +-- Revision 2K8A 2008/02/29 WF +-- Fixed a serious prescaler bug. +-- Revision 2K9A 20090620 WF +-- Introduced timer readback registers. +-- TIMER_x_INT is now a strobe. +-- Minor improvements. +-- Revision 2K11A 20110620 WF +-- A minor change in the data readback logic (RWn is now taken into consideration). + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + +entity WF68901IP_TIMERS is + port ( -- System control: + CLK : in bit; + RESETn : in bit; + + -- Asynchronous bus control: + DSn : in bit; + CSn : in bit; + RWn : in bit; + + -- Data and Adresses: + RS : in bit_vector(5 downto 1); + DATA_IN : in bit_vector(7 downto 0); + DATA_OUT : out bit_vector(7 downto 0); + DATA_OUT_EN : out bit; + + -- Timers and timer control: + XTAL1 : in bit; -- Use an oszillator instead of a quartz. + TAI : in bit; + TBI : in bit; + AER_4 : in bit; + AER_3 : in bit; + TA_PWM : out bit; -- Indicates, that timer A is in PWM mode (used in Interrupt logic). + TB_PWM : out bit; -- Indicates, that timer B is in PWM mode (used in Interrupt logic). + TAO : buffer bit; + TBO : buffer bit; + TCO : buffer bit; + TDO : buffer bit; + TIMER_A_INT : out bit; + TIMER_B_INT : out bit; + TIMER_C_INT : out bit; + TIMER_D_INT : out bit + ); +end entity WF68901IP_TIMERS; + +architecture BEHAVIOR of WF68901IP_TIMERS is +signal XTAL1_S : bit; +signal XTAL_STRB : bit; +signal TACR : bit_vector(4 downto 0); -- Timer A control register. +signal TBCR : bit_vector(4 downto 0); -- Timer B control register. +signal TCDCR : bit_vector(5 downto 0); -- Timer C and D control register. +signal TADR : bit_vector(7 downto 0); -- Timer A data register. +signal TBDR : bit_vector(7 downto 0); -- Timer B data register. +signal TCDR : bit_vector(7 downto 0); -- Timer C data register. +signal TDDR : bit_vector(7 downto 0); -- Timer D data register. +signal TIMER_A : std_logic_vector(7 downto 0); -- Timer A count register. +signal TIMER_B : std_logic_vector(7 downto 0); -- Timer B count register. +signal TIMER_C : std_logic_vector(7 downto 0); -- Timer C count register. +signal TIMER_D : std_logic_vector(7 downto 0); -- Timer D count register. +signal TIMER_R_A : bit_vector(7 downto 0); -- Timer A readback register. +signal TIMER_R_B : bit_vector(7 downto 0); -- Timer B readback register. +signal TIMER_R_C : bit_vector(7 downto 0); -- Timer C readback register. +signal TIMER_R_D : bit_vector(7 downto 0); -- Timer D readback register. +signal A_CNTSTRB : bit; +signal B_CNTSTRB : bit; +signal C_CNTSTRB : bit; +signal D_CNTSTRB : bit; +signal TAI_I : bit; +signal TBI_I : bit; +signal TAI_STRB : bit; -- Strobe for the event counter mode. +signal TBI_STRB : bit; -- Strobe for the event counter mode. +signal TAO_I : bit; -- Timer A output signal. +signal TBO_I : bit; -- Timer A output signal. +begin + SYNC: process + -- This process provides a 'clean' XTAL1. + -- Without this sync, the edge detector for + -- XTAL_STRB does not work properly. + begin + wait until CLK = '1' and CLK' event; + XTAL1_S <= XTAL1; + -- Polarity control for the event counter and the PWM mode: + TAI_I <= TAI xnor AER_4; + TBI_I <= TBI xnor AER_3; + end process SYNC; + + -- Output enables for timer A and timer B: + -- The outputs are held low for asserted reset flags in the control registers TACR + -- and TBCR but also during a write operation to these registers. + TAO <= '0' when TACR(4) = '1' else + '0' when CSn = '0' and DSn = '0' and RWn = '0' and RS = "01100" else TAO_I; + TBO <= '0' when TBCR(4) = '1' else + '0' when CSn = '0' and DSn = '0' and RWn = '0' and RS = "01101" else TBO_I; + + -- Control outputs for the PWM modi of the timers A and B. These + -- controls are used in the interrupt logic to select the interrupt + -- sources GPIP4 or TAI repective GPIP3 or TBI. + TA_PWM <= '1' when TACR(3 downto 0) > x"8" else '0'; + TB_PWM <= '1' when TBCR(3 downto 0) > x"8" else '0'; + + TIMER_REGISTERS: process(RESETn, CLK) + begin + if RESETn = '0' then + TACR <= (others => '0'); + TBCR <= (others => '0'); + TCDCR <= (others => '0'); + -- TADR <= Do not clear during reset! + -- TBDR <= Do not clear during reset! + -- TCDR <= Do not clear during reset! + -- TDDR <= Do not clear during reset! + elsif CLK = '1' and CLK' event then + if CSn = '0' and DSn = '0' and RWn = '0' then + case RS is + when "01100" => TACR <= DATA_IN(4 downto 0); + when "01101" => TBCR <= DATA_IN(4 downto 0); + when "01110" => TCDCR <= DATA_IN(6 downto 4) & DATA_IN(2 downto 0); + when "01111" => TADR <= DATA_IN; + when "10000" => TBDR <= DATA_IN; + when "10001" => TCDR <= DATA_IN; + when "10010" => TDDR <= DATA_IN; + when others => null; + end case; + end if; + end if; + end process TIMER_REGISTERS; + + TIMER_READBACK : process(RESETn, CLK) + -- This process provides the readback information for the + -- timers A to D. The information read is the information + -- last clocked into the timer read register when the DSn + -- pin had last gone high prior to the current read cycle. + variable READ_A : boolean; + variable READ_B : boolean; + variable READ_C : boolean; + variable READ_D : boolean; + begin + if RESETn = '0' then + TIMER_R_A <= x"00"; + TIMER_R_B <= x"00"; + TIMER_R_C <= x"00"; + TIMER_R_D <= x"00"; + elsif CLK = '1' and CLK' event then + if DSn = '0' and RWn = '1' and RS = "01111" then + READ_A := true; + elsif DSn = '0' and RWn = '1' and RS = "10000" then + READ_B := true; + elsif DSn = '0' and RWn = '1' and RS = "10001" then + READ_C := true; + elsif DSn = '0' and RWn = '1' and RS = "10010" then + READ_D := true; + elsif DSn = '1' and READ_A = true then + TIMER_R_A <= To_BitVector(TIMER_A); + READ_A := false; + elsif DSn = '1' and READ_B = true then + TIMER_R_B <= To_BitVector(TIMER_B); + READ_B := false; + elsif DSn = '1' and READ_C = true then + TIMER_R_C <= To_BitVector(TIMER_C); + READ_C := false; + elsif DSn = '1' and READ_D = true then + TIMER_R_D <= To_BitVector(TIMER_D); + READ_D := false; + end if; + end if; + end process TIMER_READBACK; + + DATA_OUT_EN <= '1' when CSn = '0' and DSn = '0' and RWn = '1' and RS > "01011" and RS <= "10010" else '0'; + DATA_OUT <= "000" & TACR when CSn = '0' and DSn = '0' and RWn = '1' and RS = "01100" else + "000" & TBCR when CSn = '0' and DSn = '0' and RWn = '1' and RS = "01101" else + '0' & TCDCR(5 downto 3) & '0' & TCDCR(2 downto 0) when CSn = '0' and DSn = '0' and RWn = '1' and RS = "01110" else + TIMER_R_A when CSn = '0' and DSn = '0' and RWn = '1' and RS = "01111" else + TIMER_R_B when CSn = '0' and DSn = '0' and RWn = '1' and RS = "10000" else + TIMER_R_C when CSn = '0' and DSn = '0' and RWn = '1' and RS = "10001" else + TIMER_R_D when CSn = '0' and DSn = '0' and RWn = '1' and RS = "10010" else (others => '0'); + + XTAL_STROBE: process(RESETn, CLK) + -- This process provides a strobe with 1 clock cycle + -- (CLK) length after every rising edge of XTAL1. + variable LOCK : boolean; + begin + if RESETn = '0' then + XTAL_STRB <= '0'; + elsif CLK = '1' and CLK' event then + if XTAL1_S = '1' and LOCK = false then + XTAL_STRB <= '1'; + LOCK := true; + elsif XTAL1_S = '0' then + XTAL_STRB <= '0'; + LOCK := false; + else + XTAL_STRB <= '0'; + end if; + end if; + end process XTAL_STROBE; + + TAI_STROBE: process(RESETn, CLK) + variable LOCK : boolean; + begin + if RESETn = '0' then + TAI_STRB <= '0'; + elsif CLK = '1' and CLK' event then + if TAI_I = '1' and XTAL_STRB = '1' and LOCK = false then + LOCK := true; + TAI_STRB <= '1'; + elsif TAI_I = '0' then + LOCK := false; + TAI_STRB <= '0'; + else + TAI_STRB <= '0'; + end if; + end if; + end process TAI_STROBE; + + TBI_STROBE: process(RESETn, CLK) + variable LOCK : boolean; + begin + if RESETn = '0' then + TBI_STRB <= '0'; + elsif CLK = '1' and CLK' event then + if TBI_I = '1' and XTAL_STRB = '1' and LOCK = false then + LOCK := true; + TBI_STRB <= '1'; + elsif TBI_I = '0' then + LOCK := false; + TBI_STRB <= '0'; + else + TBI_STRB <= '0'; + end if; + end if; + end process TBI_STROBE; + + PRESCALE_A: process + -- The prescalers work even if the RESETn is asserted. + variable PRESCALE : std_logic_vector(7 downto 0); + begin + wait until CLK = '1' and CLK' event; + A_CNTSTRB <= '0'; + if PRESCALE > x"00" and XTAL_STRB = '1' then + PRESCALE := PRESCALE - '1'; + elsif XTAL_STRB = '1' then + case TACR(2 downto 0) is + when "111" => PRESCALE := x"C7"; -- Prescaler = 200. + when "110" => PRESCALE := x"63"; -- Prescaler = 100. + when "101" => PRESCALE := x"3F"; -- Prescaler = 64. + when "100" => PRESCALE := x"31"; -- Prescaler = 50. + when "011" => PRESCALE := x"0F"; -- Prescaler = 16. + when "010" => PRESCALE := x"09"; -- Prescaler = 10. + when "001" => PRESCALE := x"03"; -- Prescaler = 4. + when "000" => PRESCALE := x"00"; -- Timer stopped or event count mode. + end case; + A_CNTSTRB <= '1'; + end if; + end process PRESCALE_A; + + PRESCALE_B: process + -- The prescalers work even if the RESETn is asserted. + variable PRESCALE : std_logic_vector(7 downto 0); + begin + wait until CLK = '1' and CLK' event; + B_CNTSTRB <= '0'; + if PRESCALE > x"00" and XTAL_STRB = '1' then + PRESCALE := PRESCALE - '1'; + elsif XTAL_STRB = '1' then + case TBCR(2 downto 0) is + when "111" => PRESCALE := x"C7"; -- Prescaler = 200. + when "110" => PRESCALE := x"63"; -- Prescaler = 100. + when "101" => PRESCALE := x"3F"; -- Prescaler = 64. + when "100" => PRESCALE := x"31"; -- Prescaler = 50. + when "011" => PRESCALE := x"0F"; -- Prescaler = 16. + when "010" => PRESCALE := x"09"; -- Prescaler = 10. + when "001" => PRESCALE := x"03"; -- Prescaler = 4. + when "000" => PRESCALE := x"00"; -- Timer stopped or event count mode. + end case; + B_CNTSTRB <= '1'; + end if; + end process PRESCALE_B; + + PRESCALE_C: process + -- The prescalers work even if the RESETn is asserted. + variable PRESCALE : std_logic_vector(7 downto 0); + begin + wait until CLK = '1' and CLK' event; + C_CNTSTRB <= '0'; + if PRESCALE > x"00" and XTAL_STRB = '1' then + PRESCALE := PRESCALE - '1'; + elsif XTAL_STRB = '1' then + case TCDCR(5 downto 3) is + when "111" => PRESCALE := x"C7"; -- Prescaler = 200. + when "110" => PRESCALE := x"63"; -- Prescaler = 100. + when "101" => PRESCALE := x"3F"; -- Prescaler = 64. + when "100" => PRESCALE := x"31"; -- Prescaler = 50. + when "011" => PRESCALE := x"0F"; -- Prescaler = 16. + when "010" => PRESCALE := x"09"; -- Prescaler = 10. + when "001" => PRESCALE := x"03"; -- Prescaler = 4. + when "000" => PRESCALE := x"00"; -- Timer stopped. + end case; + C_CNTSTRB <= '1'; + end if; + end process PRESCALE_C; + + PRESCALE_D: process + -- The prescalers work even if the RESETn is asserted. + variable PRESCALE : std_logic_vector(7 downto 0); + begin + wait until CLK = '1' and CLK' event; + D_CNTSTRB <= '0'; + if PRESCALE > x"00" and XTAL_STRB = '1' then + PRESCALE := PRESCALE - '1'; + elsif XTAL_STRB = '1' then + case TCDCR(2 downto 0) is + when "111" => PRESCALE := x"C7"; -- Prescaler = 200. + when "110" => PRESCALE := x"63"; -- Prescaler = 100. + when "101" => PRESCALE := x"3F"; -- Prescaler = 64. + when "100" => PRESCALE := x"31"; -- Prescaler = 50. + when "011" => PRESCALE := x"0F"; -- Prescaler = 16. + when "010" => PRESCALE := x"09"; -- Prescaler = 10. + when "001" => PRESCALE := x"03"; -- Prescaler = 4. + when "000" => PRESCALE := x"00"; -- Timer stopped. + end case; + D_CNTSTRB <= '1'; + end if; + end process PRESCALE_D; + + TIMERA: process(RESETn, CLK) + begin + if RESETn = '0' then + -- Do not clear the timer registers during system reset. + TAO_I <= '0'; + TIMER_A_INT <= '0'; + elsif CLK = '1' and CLK' event then + TIMER_A_INT <= '0'; + -- + if CSn = '0' and DSn = '0' and RWn = '0' and RS = "01111" and TACR(3 downto 0) = x"0" then + -- The timer is reloaded simultaneously to it's timer data register, if it is off. + TIMER_A <= To_StdLogicVector(DATA_IN); + else + case TACR(3 downto 0) is + when x"0" => -- Timer is off. + TAO_I <= '0'; + when x"1" | x"2" | x"3" | x"4" | x"5" | x"6" | x"7" => -- Delay counter mode. + if A_CNTSTRB = '1' and TIMER_A /= x"01" then -- Count. + TIMER_A <= TIMER_A - '1'; + elsif A_CNTSTRB = '1' and TIMER_A = x"01" then -- Reload. + TIMER_A <= To_StdLogicVector(TADR); + TAO_I <= not TAO_I; -- Toggle the timer A output pin. + TIMER_A_INT <= '1'; + end if; + when x"8" => -- Event count operation. + if TAI_STRB = '1' and TIMER_A /= x"01" then -- Count. + TIMER_A <= TIMER_A - '1'; + elsif TAI_STRB = '1' and TIMER_A = x"01" then -- Reload. + TIMER_A <= To_StdLogicVector(TADR); + TAO_I <= not TAO_I; -- Toggle the timer A output pin. + TIMER_A_INT <= '1'; + end if; + when x"9" | x"A" | x"B" | x"C" | x"D" | x"E" | x"F" => -- PWM mode. + if TAI_I = '1' and A_CNTSTRB = '1' and TIMER_A /= x"01" then -- Count. + TIMER_A <= TIMER_A - '1'; + elsif TAI_I = '1' and A_CNTSTRB = '1' and TIMER_A = x"01" then -- Reload. + TIMER_A <= To_StdLogicVector(TADR); + TAO_I <= not TAO_I; -- Toggle the timer A output pin. + TIMER_A_INT <= '1'; + end if; + end case; + end if; + end if; + end process TIMERA; + + TIMERB: process(RESETn, CLK) + begin + if RESETn = '0' then + -- Do not clear the timer registers during system reset. + TBO_I <= '0'; + TIMER_B_INT <= '0'; + elsif CLK = '1' and CLK' event then + TIMER_B_INT <= '0'; + -- + if CSn = '0' and DSn = '0' and RWn = '0' and RS = "10000" and TBCR(3 downto 0) = x"0" then + -- The timer is reloaded simultaneously to it's timer data register, if it is off. + TIMER_B <= To_StdLogicVector(DATA_IN); + else + case TBCR(3 downto 0) is + when x"0" => -- Timer is off. + TBO_I <= '0'; + when x"1" | x"2" | x"3" | x"4" | x"5" | x"6" | x"7" => -- Delay counter mode. + if B_CNTSTRB = '1' and TIMER_B /= x"01" then -- Count. + TIMER_B <= TIMER_B - '1'; + elsif B_CNTSTRB = '1' and TIMER_B = x"01" then -- Reload. + TIMER_B <= To_StdLogicVector(TBDR); + TBO_I <= not TBO_I; -- Toggle the timer B output pin. + TIMER_B_INT <= '1'; + end if; + when x"8" => -- Event count operation. + if TBI_STRB = '1' and TIMER_B /= x"01" then -- Count. + TIMER_B <= TIMER_B - '1'; + elsif TBI_STRB = '1' and TIMER_B = x"01" then -- Reload. + TIMER_B <= To_StdLogicVector(TBDR); + TBO_I <= not TBO_I; -- Toggle the timer B output pin. + TIMER_B_INT <= '1'; + end if; + when x"9" | x"A" | x"B" | x"C" | x"D" | x"E" | x"F" => -- PWM mode. + if TBI_I = '1' and B_CNTSTRB = '1' and TIMER_B /= x"01" then -- Count. + TIMER_B <= TIMER_B - '1'; + elsif TBI_I = '1' and B_CNTSTRB = '1' and TIMER_B = x"01" then -- Reload. + TIMER_B <= To_StdLogicVector(TBDR); + TBO_I <= not TBO_I; -- Toggle the timer B output pin. + TIMER_B_INT <= '1'; + end if; + end case; + end if; + end if; + end process TIMERB; + + TIMERC: process(RESETn, CLK) + begin + if RESETn = '0' then + -- Do not clear the timer registers during system reset. + TCO <= '0'; + TIMER_C_INT <= '0'; + elsif CLK = '1' and CLK' event then + TIMER_C_INT <= '0'; + -- + if CSn = '0' and DSn = '0' and RWn = '0' and RS = "10001" and TCDCR(5 downto 3) = "000" then + -- The timer is reloaded simultaneously to it's timer data register, if it is off. + TIMER_C <= To_StdLogicVector(DATA_IN); + else + case TCDCR(5 downto 3) is + when "000" => -- Timer is off. + TCO <= '0'; + when others => -- Delay counter mode. + if C_CNTSTRB = '1' and TIMER_C /= x"01" then -- Count. + TIMER_C <= TIMER_C - '1'; + elsif C_CNTSTRB = '1' and TIMER_C = x"01" then -- Reload. + TIMER_C <= To_StdLogicVector(TCDR); + TCO <= not TCO; -- Toggle the timer C output pin. + TIMER_C_INT <= '1'; + end if; + end case; + end if; + end if; + end process TIMERC; + + TIMERD: process(RESETn, CLK) + begin + if RESETn = '0' then + -- Do not clear the timer registers during system reset. + TDO <= '0'; + TIMER_D_INT <= '0'; + elsif CLK = '1' and CLK' event then + TIMER_D_INT <= '0'; + -- + if CSn = '0' and DSn = '0' and RWn = '0' and RS = "10010" and TCDCR(2 downto 0) = "000" then + -- The timer is reloaded simultaneously to it's timer data register, if it is off. + TIMER_D <= To_StdLogicVector(DATA_IN); + else + case TCDCR(2 downto 0) is + when "000" => -- Timer is off. + TDO <= '0'; + when others => -- Delay counter mode. + if D_CNTSTRB = '1' and TIMER_D /= x"01" then -- Count. + TIMER_D <= TIMER_D - '1'; + elsif D_CNTSTRB = '1' and TIMER_D = x"01" then -- Reload. + TIMER_D <= To_StdLogicVector(TDDR); + TDO <= not TDO; -- Toggle the timer D output pin. + TIMER_D_INT <= '1'; + end if; + end case; + end if; + end if; + end process TIMERD; +end architecture BEHAVIOR; \ No newline at end of file diff --git a/vhdl/rtl/vhdl/WF_MFP68901_IP/wf68901ip_top.vhd b/vhdl/rtl/vhdl/WF_MFP68901_IP/wf68901ip_top.vhd new file mode 100644 index 0000000..783ba56 --- /dev/null +++ b/vhdl/rtl/vhdl/WF_MFP68901_IP/wf68901ip_top.vhd @@ -0,0 +1,213 @@ +---------------------------------------------------------------------- +---- ---- +---- ATARI MFP compatible IP Core ---- +---- ---- +---- This file is part of the SUSKA ATARI clone project. ---- +---- http://www.experiment-s.de ---- +---- ---- +---- Description: ---- +---- MC68901 compatible multi function port core. ---- +---- ---- +---- This is the SUSKA MFP IP core top level file. ---- +---- ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2006 Wolfgang Foerster ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.gnu.org/licenses/lgpl.html ---- +---- ---- +---------------------------------------------------------------------- +-- +-- Revision History +-- +-- Revision 2K6A 2006/06/03 WF +-- Initial Release. +-- Revision 2K6B 2006/11/07 WF +-- Modified Source to compile with the Xilinx ISE. +-- Revision 2K7A 2006/12/28 WF +-- The timer is modified to work on the CLK instead +-- of XTAL1. This modification is done to provide +-- a synchronous design. +-- Revision 2K8B 2008/12/24 WF +-- Rewritten this top level file as a wrapper for the top_soc file. +-- + +use work.wf68901ip_pkg.all; + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + +entity WF68901IP_TOP is + port ( -- System control: + CLK : in bit; + RESETn : in bit; + + -- Asynchronous bus control: + DSn : in bit; + CSn : in bit; + RWn : in bit; + DTACKn : out std_logic; + + -- Data and Adresses: + RS : in bit_vector(5 downto 1); + DATA : inout std_logic_vector(7 downto 0); + GPIP : inout std_logic_vector(7 downto 0); + + -- Interrupt control: + IACKn : in bit; + IEIn : in bit; + IEOn : out bit; + IRQn : out std_logic; + + -- Timers and timer control: + XTAL1 : in bit; -- Use an oszillator instead of a quartz. + TAI : in bit; + TBI : in bit; + TAO : out bit; + TBO : out bit; + TCO : out bit; + TDO : out bit; + + -- Serial I/O control: + RC : in bit; + TC : in bit; + SI : in bit; + SO : out std_logic; + + -- DMA control: + RRn : out bit; + TRn : out bit + ); +end entity WF68901IP_TOP; + +architecture STRUCTURE of WF68901IP_TOP is +component WF68901IP_TOP_SOC + port(CLK : in bit; + RESETn : in bit; + DSn : in bit; + CSn : in bit; + RWn : in bit; + DTACKn : out bit; + RS : in bit_vector(5 downto 1); + DATA_IN : in std_logic_vector(7 downto 0); + DATA_OUT : out std_logic_vector(7 downto 0); + DATA_EN : out bit; + GPIP_IN : in bit_vector(7 downto 0); + GPIP_OUT : out bit_vector(7 downto 0); + GPIP_EN : out bit_vector(7 downto 0); + IACKn : in bit; + IEIn : in bit; + IEOn : out bit; + IRQn : out bit; + XTAL1 : in bit; + TAI : in bit; + TBI : in bit; + TAO : out bit; + TBO : out bit; + TCO : out bit; + TDO : out bit; + RC : in bit; + TC : in bit; + SI : in bit; + SO : out bit; + SO_EN : out bit; + RRn : out bit; + TRn : out bit + ); +end component; +-- +signal DTACK_In : bit; +signal IRQ_In : bit; +signal DATA_OUT : std_logic_vector(7 downto 0); +signal DATA_EN : bit; +signal GPIP_IN : bit_vector(7 downto 0); +signal GPIP_OUT : bit_vector(7 downto 0); +signal GPIP_EN : bit_vector(7 downto 0); +signal SO_I : bit; +signal SO_EN : bit; +begin + DTACKn <= '0' when DTACK_In = '0' else 'Z'; -- Open drain. + IRQn <= '0' when IRQ_In = '0' else 'Z'; -- Open drain. + + DATA <= DATA_OUT when DATA_EN = '1' else (others => 'Z'); + + GPIP_IN <= To_BitVector(GPIP); + + P_GPIP_OUT: process(GPIP_OUT, GPIP_EN) + begin + for i in 7 downto 0 loop + if GPIP_EN(i) = '1' then + case GPIP_OUT(i) is + when '0' => GPIP(i) <= '0'; + when others => GPIP(i) <= '1'; + end case; + else + GPIP(i) <= 'Z'; + end if; + end loop; + end process P_GPIP_OUT; + + SO <= '0' when SO_I = '0' and SO_EN = '1' else + '1' when SO_I = '1' and SO_EN = '1' else 'Z'; + + I_MFP: WF68901IP_TOP_SOC + port map(CLK => CLK, + RESETn => RESETn, + DSn => DSn, + CSn => CSn, + RWn => RWn, + DTACKn => DTACK_In, + RS => RS, + DATA_IN => DATA, + DATA_OUT => DATA_OUT, + DATA_EN => DATA_EN, + GPIP_IN => GPIP_IN, + GPIP_OUT => GPIP_OUT, + GPIP_EN => GPIP_EN, + IACKn => IACKn, + IEIn => IEIn, + IEOn => IEOn, + IRQn => IRQ_In, + XTAL1 => XTAL1, + TAI => TAI, + TBI => TBI, + TAO => TAO, + TBO => TBO, + TCO => TCO, + TDO => TDO, + RC => RC, + TC => TC, + SI => SI, + SO => SO_I, + SO_EN => SO_EN, + RRn => RRn, + TRn => TRn + ); +end architecture STRUCTURE; diff --git a/vhdl/rtl/vhdl/WF_MFP68901_IP/wf68901ip_top_soc.vhd b/vhdl/rtl/vhdl/WF_MFP68901_IP/wf68901ip_top_soc.vhd new file mode 100644 index 0000000..9efcfde --- /dev/null +++ b/vhdl/rtl/vhdl/WF_MFP68901_IP/wf68901ip_top_soc.vhd @@ -0,0 +1,309 @@ +---------------------------------------------------------------------- +---- ---- +---- ATARI MFP compatible IP Core ---- +---- ---- +---- This file is part of the SUSKA ATARI clone project. ---- +---- http://www.experiment-s.de ---- +---- ---- +---- Description: ---- +---- MC68901 compatible multi function port core. ---- +---- ---- +---- This is the SUSKA MFP IP core top level file. ---- +---- Top level file for use in systems on programmable chips. ---- +---- ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2006 - 2011 Wolfgang Foerster ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.gnu.org/licenses/lgpl.html ---- +---- ---- +---------------------------------------------------------------------- +-- +-- Revision History +-- +-- Revision 2K6A 2006/06/03 WF +-- Initial Release. +-- Revision 2K6B 2006/11/07 WF +-- Modified Source to compile with the Xilinx ISE. +-- Top level file provided for SOC (systems on programmable chips). +-- Revision 2K7A 2006/12/28 WF +-- The timer is modified to work on the CLK instead +-- of XTAL1. This modification is done to provide +-- a synchronous design. +-- Revision 2K8A 2008/07/14 WF +-- Minor changes. +-- Revision 2K9A 2009/06/20 WF +-- DTACK_OUTn has now synchronous reset to meet preset requirement. +-- +-- + +use work.wf68901ip_pkg.all; + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + +entity WF68901IP_TOP_SOC is + port ( -- System control: + CLK : in bit; + RESETn : in bit; + + -- Asynchronous bus control: + DSn : in bit; + CSn : in bit; + RWn : in bit; + DTACKn : out bit; + + -- Data and Adresses: + RS : in bit_vector(5 downto 1); + DATA_IN : in std_logic_vector(7 downto 0); + DATA_OUT : out std_logic_vector(7 downto 0); + DATA_EN : out bit; + GPIP_IN : in bit_vector(7 downto 0); + GPIP_OUT : out bit_vector(7 downto 0); + GPIP_EN : out bit_vector(7 downto 0); + + -- Interrupt control: + IACKn : in bit; + IEIn : in bit; + IEOn : out bit; + IRQn : out bit; + + -- Timers and timer control: + XTAL1 : in bit; -- Use an oszillator instead of a quartz. + TAI : in bit; + TBI : in bit; + TAO : out bit; + TBO : out bit; + TCO : out bit; + TDO : out bit; + + -- Serial I/O control: + RC : in bit; + TC : in bit; + SI : in bit; + SO : out bit; + SO_EN : out bit; + + -- DMA control: + RRn : out bit; + TRn : out bit + ); +end entity WF68901IP_TOP_SOC; + +architecture STRUCTURE of WF68901IP_TOP_SOC is +signal DATA_IN_I : bit_vector(7 downto 0); +signal DTACK_In : bit; +signal DTACK_LOCK : boolean; +signal DTACK_OUTn : bit; +signal RX_ERR_INT_I : bit; +signal TX_ERR_INT_I : bit; +signal RX_BUFF_INT_I : bit; +signal TX_BUFF_INT_I : bit; +signal DATA_OUT_USART_I : bit_vector(7 downto 0); +signal DATA_OUT_EN_USART_I : bit; +signal DATA_OUT_INT_I : bit_vector(7 downto 0); +signal DATA_OUT_EN_INT_I : bit; +signal DATA_OUT_GPIO_I : bit_vector(7 downto 0); +signal DATA_OUT_EN_GPIO_I : bit; +signal DATA_OUT_TIMERS_I : bit_vector(7 downto 0); +signal DATA_OUT_EN_TIMERS_I : bit; +signal SO_I : bit; +signal SO_EN_I : bit; +signal GPIP_IN_I : bit_vector(7 downto 0); +signal GPIP_OUT_I : bit_vector(7 downto 0); +signal GPIP_EN_I : bit_vector(7 downto 0); +signal GP_INT_I : bit_vector(7 downto 0); +signal TIMER_A_INT_I : bit; +signal TIMER_B_INT_I : bit; +signal TIMER_C_INT_I : bit; +signal TIMER_D_INT_I : bit; +signal IRQ_In : bit; +signal AER_4_I : bit; +signal AER_3_I : bit; +signal TA_PWM_I : bit; +signal TB_PWM_I : bit; +begin + -- Interrupt request (open drain): + IRQn <= IRQ_In; + + -- Serial data output: + SO <= SO_I; + SO_EN <= SO_EN_I and RESETn; + + -- General purpose port: + GPIP_IN_I <= GPIP_IN; + GPIP_OUT <= GPIP_OUT_I; + GPIP_EN <= GPIP_EN_I; + + DATA_IN_I <= To_BitVector(DATA_IN); + DATA_EN <= DATA_OUT_EN_USART_I or DATA_OUT_EN_INT_I or DATA_OUT_EN_GPIO_I or DATA_OUT_EN_TIMERS_I; + -- Output data multiplexer: + DATA_OUT <= To_StdLogicVector(DATA_OUT_USART_I) when DATA_OUT_EN_USART_I = '1' else + To_StdLogicVector(DATA_OUT_INT_I) when DATA_OUT_EN_INT_I = '1' else + To_StdLogicVector(DATA_OUT_GPIO_I) when DATA_OUT_EN_GPIO_I = '1' else + To_StdLogicVector(DATA_OUT_TIMERS_I) when DATA_OUT_EN_TIMERS_I = '1' else (others => '1'); + + -- Data acknowledge handshake is provided by the following statement and the consecutive two + -- processes. For more information refer to the M68000 family reference manual. + DTACK_In <= '0' when CSn = '0' and DSn = '0' and RS <= "10111" else -- Read and write operation. + '0' when IACKn = '0' and DSn = '0' and IEIn = '0' else '1'; -- Interrupt vector data acknowledge. + + P_DTACK_LOCK: process + -- This process releases a data acknowledge detect, one rising clock + -- edge after the DTACK_In occured. This is necessary to ensure write + -- data to registers for there is one rising clock edge required. + begin + wait until CLK = '1' and CLK' event; + if DTACK_In = '0' then + DTACK_LOCK <= false; + else + DTACK_LOCK <= true; + end if; + end process P_DTACK_LOCK; + + DTACK_OUT: process + -- The DTACKn port pin is released on the falling clock edge after the data + -- acknowledge detect (DTACK_LOCK) is asserted. The DTACKn is deasserted + -- immediately when there is no further register access DTACK_In = '1'; + begin + wait until CLK = '0' and CLK' event; + if RESETn = '0' then + DTACK_OUTn <= '1'; + elsif DTACK_In = '1' then + DTACK_OUTn <= '1'; + elsif DTACK_LOCK = false then + DTACK_OUTn <= '0'; + end if; + end process DTACK_OUT; + DTACKn <= '0' when DTACK_OUTn = '0' else '1'; + + I_USART: WF68901IP_USART_TOP + port map( + CLK => CLK, + RESETn => RESETn, + DSn => DSn, + CSn => CSn, + RWn => RWn, + RS => RS, + DATA_IN => DATA_IN_I, + DATA_OUT => DATA_OUT_USART_I, + DATA_OUT_EN => DATA_OUT_EN_USART_I, + RC => RC, + TC => TC, + SI => SI, + SO => SO_I, + SO_EN => SO_EN_I, + RX_ERR_INT => RX_ERR_INT_I, + RX_BUFF_INT => RX_BUFF_INT_I, + TX_ERR_INT => TX_ERR_INT_I, + TX_BUFF_INT => TX_BUFF_INT_I, + RRn => RRn, + TRn => TRn + ); + + I_INTERRUPTS: WF68901IP_INTERRUPTS + port map( + CLK => CLK, + RESETn => RESETn, + DSn => DSn, + CSn => CSn, + RWn => RWn, + RS => RS, + DATA_IN => DATA_IN_I, + DATA_OUT => DATA_OUT_INT_I, + DATA_OUT_EN => DATA_OUT_EN_INT_I, + IACKn => IACKn, + IEIn => IEIn, + IEOn => IEOn, + IRQn => IRQ_In, + GP_INT => GP_INT_I, + AER_4 => AER_4_I, + AER_3 => AER_3_I, + TAI => TAI, + TBI => TBI, + TA_PWM => TA_PWM_I, + TB_PWM => TB_PWM_I, + TIMER_A_INT => TIMER_A_INT_I, + TIMER_B_INT => TIMER_B_INT_I, + TIMER_C_INT => TIMER_C_INT_I, + TIMER_D_INT => TIMER_D_INT_I, + RCV_ERR => RX_ERR_INT_I, + TRM_ERR => TX_ERR_INT_I, + RCV_BUF_F => RX_BUFF_INT_I, + TRM_BUF_E => TX_BUFF_INT_I + ); + + I_GPIO: WF68901IP_GPIO + port map( + CLK => CLK, + RESETn => RESETn, + DSn => DSn, + CSn => CSn, + RWn => RWn, + RS => RS, + DATA_IN => DATA_IN_I, + DATA_OUT => DATA_OUT_GPIO_I, + DATA_OUT_EN => DATA_OUT_EN_GPIO_I, + AER_4 => AER_4_I, + AER_3 => AER_3_I, + GPIP_IN => GPIP_IN_I, + GPIP_OUT => GPIP_OUT_I, + GPIP_OUT_EN => GPIP_EN_I, + GP_INT => GP_INT_I + ); + + I_TIMERS: WF68901IP_TIMERS + port map( + CLK => CLK, + RESETn => RESETn, + DSn => DSn, + CSn => CSn, + RWn => RWn, + RS => RS, + DATA_IN => DATA_IN_I, + DATA_OUT => DATA_OUT_TIMERS_I, + DATA_OUT_EN => DATA_OUT_EN_TIMERS_I, + XTAL1 => XTAL1, + AER_4 => AER_4_I, + AER_3 => AER_3_I, + TAI => TAI, + TBI => TBI, + TAO => TAO, + TBO => TBO, + TCO => TCO, + TDO => TDO, + TA_PWM => TA_PWM_I, + TB_PWM => TB_PWM_I, + TIMER_A_INT => TIMER_A_INT_I, + TIMER_B_INT => TIMER_B_INT_I, + TIMER_C_INT => TIMER_C_INT_I, + TIMER_D_INT => TIMER_D_INT_I + ); +end architecture STRUCTURE; diff --git a/vhdl/rtl/vhdl/WF_MFP68901_IP/wf68901ip_usart_ctrl.vhd b/vhdl/rtl/vhdl/WF_MFP68901_IP/wf68901ip_usart_ctrl.vhd new file mode 100644 index 0000000..076d7ae --- /dev/null +++ b/vhdl/rtl/vhdl/WF_MFP68901_IP/wf68901ip_usart_ctrl.vhd @@ -0,0 +1,191 @@ +---------------------------------------------------------------------- +---- ---- +---- ATARI MFP compatible IP Core ---- +---- ---- +---- This file is part of the SUSKA ATARI clone project. ---- +---- http://www.experiment-s.de ---- +---- ---- +---- Description: ---- +---- This is the SUSKA MFP IP core USART control file. ---- +---- ---- +---- Control unit and status logic. ---- +---- ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2006 - 2011 Wolfgang Foerster ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.gnu.org/licenses/lgpl.html ---- +---- ---- +---------------------------------------------------------------------- +-- +-- Revision History +-- +-- Revision 2K6A 2006/06/03 WF +-- Initial Release. +-- Revision 2K6B 2006/11/07 WF +-- Modified Source to compile with the Xilinx ISE. +-- Revision 2K8A 2008/07/14 WF +-- Minor changes. +-- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + +entity WF68901IP_USART_CTRL is + port ( + -- System Control: + CLK : in bit; + RESETn : in bit; + + -- Bus control: + DSn : in bit; + CSn : in bit; + RWn : in bit; + RS : in bit_vector(5 downto 1); + DATA_IN : in bit_vector(7 downto 0); + DATA_OUT : out bit_vector(7 downto 0); + DATA_OUT_EN : out bit; + + -- USART data register + RX_SAMPLE : in bit; + RX_DATA : in bit_vector(7 downto 0); + TX_DATA : out bit_vector(7 downto 0); + SCR_OUT : out bit_vector(7 downto 0); + + -- USART control inputs: + BF : in bit; + BE : in bit; + FE : in bit; + OE : in bit; + UE : in bit; + PE : in bit; + M_CIP : in bit; + FS_B : in bit; + TX_END : in bit; + + -- USART control outputs: + CL : out bit_vector(1 downto 0); + ST : out bit_vector(1 downto 0); + FS_CLR : out bit; + UDR_WRITE : out bit; + UDR_READ : out bit; + RSR_READ : out bit; + TSR_READ : out bit; + LOOPBACK : out bit; + SDOUT_EN : out bit; + SD_LEVEL : out bit; + CLK_MODE : out bit; + RE : out bit; + TE : out bit; + P_ENA : out bit; + P_EOn : out bit; + SS : out bit; + BR : out bit + ); +end entity WF68901IP_USART_CTRL; + +architecture BEHAVIOR of WF68901IP_USART_CTRL is +signal SCR : bit_vector(7 downto 0); -- Synchronous data register. +signal UCR : bit_vector(7 downto 1); -- USART control register. +signal RSR : bit_vector(7 downto 0); -- Receiver status register. +signal TSR : bit_vector(7 downto 0); -- Transmitter status register. +signal UDR : bit_vector(7 downto 0); -- USART data register. +begin + USART_REGISTERS: process(RESETn, CLK) + begin + if RESETn = '0' then + SCR <= (others => '0'); + UCR <= (others => '0'); + RSR <= (others => '0'); + -- TSR and UDR are not cleared during an asserted RESETn + elsif CLK = '1' and CLK' event then + -- Loading via receiver shift register + -- has priority over data buss access: + if RX_SAMPLE = '1' then + UDR <= RX_DATA; + elsif CSn = '0' and DSn = '0' and RWn = '0' then + case RS is + when "10011" => SCR <= DATA_IN; + when "10100" => UCR <= DATA_IN(7 downto 1); + when "10101" => RSR(1 downto 0) <= DATA_IN(1 downto 0); -- Only the two LSB are read/write. + when "10110" => TSR(5) <= DATA_IN(5); TSR(3 downto 0) <= DATA_IN(3 downto 0); + when "10111" => UDR <= DATA_IN; + when others => null; + end case; + end if; + RSR(7 downto 2) <= BF & OE & PE & FE & FS_B & M_CIP; + TSR(7 downto 6) <= BE & UE; + TSR(4) <= TX_END; + TX_DATA <= UDR; + end if; + end process USART_REGISTERS; + DATA_OUT_EN <= '1' when CSn = '0' and DSn = '0' and RWn = '1' and RS >= "10011" and RS <= "10111" else '0'; + DATA_OUT <= SCR when CSn = '0' and DSn = '0' and RWn = '1' and RS = "10011" else + UCR & '0' when CSn = '0' and DSn = '0' and RWn = '1' and RS = "10100" else + RSR when CSn = '0' and DSn = '0' and RWn = '1' and RS = "10101" else + TSR when CSn = '0' and DSn = '0' and RWn = '1' and RS = "10110" else + UDR when CSn = '0' and DSn = '0' and RWn = '1' and RS = "10111" else x"00"; + + UDR_WRITE <= '1' when CSn = '0' and DSn = '0' and RWn = '0' and RS = "10111" else '0'; + UDR_READ <= '1' when CSn = '0' and DSn = '0' and RWn = '1' and RS = "10111" else '0'; + RSR_READ <= '1' when CSn = '0' and DSn = '0' and RWn = '1' and RS = "10101" else '0'; + TSR_READ <= '1' when CSn = '0' and DSn = '0' and RWn = '1' and RS = "10110" else '0'; + FS_CLR <= '1' when CSn = '0' and DSn = '0' and RWn = '0' and RS = "10011" else '0'; + + RE <= '1' when RSR(0) = '1' else -- Receiver enable. + '1' when TSR(5) = '1' and TX_END = '1' else '0'; -- Auto Turnaround. + SS <= RSR(1); -- Synchronous strip enable. + BR <= TSR(3); -- Send break. + TE <= TSR(0); -- Transmitter enable. + + SCR_OUT <= SCR; + + CLK_MODE <= UCR(7); -- Clock mode. + CL <= UCR(6 downto 5); -- Character length. + ST <= UCR(4 downto 3); -- Start/Stop configuration. + P_ENA <= UCR(2); -- Parity enable. + P_EOn <= UCR(1); -- Even or odd parity. + + SOUT_CONFIG: process + begin + wait until CLK = '1' and CLK' event; + -- Do not change the output configuration until the transmitter is disabled and + -- current character has been transmitted (TX_END = '1'). + if TX_END = '1' then + case TSR(2 downto 1) is + when "00" => LOOPBACK <= '0'; SD_LEVEL <= '0'; SDOUT_EN <= '0'; + when "01" => LOOPBACK <= '0'; SD_LEVEL <= '0'; SDOUT_EN <= '1'; + when "10" => LOOPBACK <= '0'; SD_LEVEL <= '1'; SDOUT_EN <= '1'; + when "11" => LOOPBACK <= '1'; SD_LEVEL <= '1'; SDOUT_EN <= '1'; + end case; + end if; + end process SOUT_CONFIG; +end architecture BEHAVIOR; + diff --git a/vhdl/rtl/vhdl/WF_MFP68901_IP/wf68901ip_usart_rx.vhd b/vhdl/rtl/vhdl/WF_MFP68901_IP/wf68901ip_usart_rx.vhd new file mode 100644 index 0000000..597bac8 --- /dev/null +++ b/vhdl/rtl/vhdl/WF_MFP68901_IP/wf68901ip_usart_rx.vhd @@ -0,0 +1,590 @@ +---------------------------------------------------------------------- +---- ---- +---- ATARI MFP compatible IP Core ---- +---- ---- +---- This file is part of the SUSKA ATARI clone project. ---- +---- http://www.experiment-s.de ---- +---- ---- +---- Description: ---- +---- This is the SUSKA MFP IP core USART receiver file. ---- +---- ---- +---- ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2006 - 2011 Wolfgang Foerster ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.gnu.org/licenses/lgpl.html ---- +---- ---- +---------------------------------------------------------------------- +-- +-- Revision History +-- +-- Revision 2K6A 2006/06/03 WF +-- Initial Release. +-- Revision 2K6B 2006/11/07 WF +-- Modified Source to compile with the Xilinx ISE. +-- Revision 2K8A 2008/07/14 WF +-- Minor changes. +-- Revision 2K9A 2009/06/20 WF +-- Process P_STARTBIT has now synchronous reset to meet preset requirement. +-- Process P_SAMPLE has now synchronous reset to meet preset requirement. +-- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + +entity WF68901IP_USART_RX is + port ( + CLK : in bit; + RESETn : in bit; + + SCR : in bit_vector(7 downto 0); -- Synchronous character. + RX_SAMPLE : buffer bit; -- Flag indicating valid shift register data. + RX_DATA : out bit_vector(7 downto 0); -- Received data. + + RXCLK : in bit; -- Receiver clock. + SDATA_IN : in bit; -- Serial data input. + + CL : in bit_vector(1 downto 0); -- Character length. + ST : in bit_vector(1 downto 0); -- Start and stop bit configuration. + P_ENA : in bit; -- Parity enable. + P_EOn : in bit; -- Even or odd parity. + CLK_MODE : in bit; -- Clock mode configuration bit. + RE : in bit; -- Receiver enable. + FS_CLR : in bit; -- Clear the Found/Search flag for resynchronisation purpose. + SS : in bit; -- Synchronous strip enable. + UDR_READ : in bit; -- Flag indicating reading the data register. + RSR_READ : in bit; -- Flag indicating reading the receiver status register. + + M_CIP : out bit; -- Match/Character in progress. + FS_B : buffer bit; -- Find/Search or Break detect flag. + BF : out bit; -- Buffer full. + OE : out bit; -- Overrun error. + PE : out bit; -- Parity error. + FE : out bit -- Framing error. + ); +end entity WF68901IP_USART_RX; + +architecture BEHAVIOR of WF68901IP_USART_RX is +type RCV_STATES is (IDLE, WAIT_START, SAMPLE, PARITY, STOP1, STOP2, SYNC); +signal RCV_STATE, RCV_NEXT_STATE : RCV_STATES; +signal SDATA_DIV16 : bit; +signal SDATA_IN_I : bit; +signal SDATA_EDGE : bit; +signal SHIFT_REG : bit_vector(7 downto 0); +signal CLK_STRB : bit; +signal CLK_2_STRB : bit; +signal BITCNT : std_logic_vector(2 downto 0); +signal BREAK : boolean; +signal RDRF : bit; +signal STARTBIT : boolean; +begin + BF <= RDRF; -- Buffer full = Receiver Data Register Full. + RX_SAMPLE <= '1' when RCV_STATE = SYNC and ST /= "00" else -- Asynchronous mode: + -- Synchronous modes: + '1' when RCV_STATE = SYNC and ST = "00" and SS = '0' else + '1' when RCV_STATE = SYNC and ST = "00" and SS = '1' and SHIFT_REG /= SCR else '0'; + + -- Data multiplexer for the received data: + RX_DATA <= "000" & SHIFT_REG(7 downto 3) when RX_SAMPLE = '1' and CL = "11" else -- 5 databits. + "00" & SHIFT_REG(7 downto 2) when RX_SAMPLE = '1' and CL = "10" else -- 6 databits. + '0' & SHIFT_REG(7 downto 1) when RX_SAMPLE = '1' and CL = "01" else -- 6 databits. + SHIFT_REG when RX_SAMPLE = '1' and CL = "00" else x"00"; -- 8 databits. + + P_SAMPLE: process + -- This process provides the 'valid transition logic' of the originally MC68901. For further + -- details see the 'M68000 FAMILY REFERENCE MANUAL'. + variable LOW_FLT : std_logic_vector(1 downto 0); + variable HI_FLT : std_logic_vector(1 downto 0); + variable CLK_LOCK : boolean; + variable EDGE_LOCK : boolean; + variable TIMER : std_logic_vector(2 downto 0); + variable TIMER_LOCK : boolean; + variable NEW_SDATA : bit; + begin + wait until CLK = '1' and CLK' event; + if RESETn = '0' or RE = '0' then + -- The reset condition assumes the SDATA_IN logic high. Otherwise + -- one not valid SDATA_EDGE pulse occurs during system startup. + CLK_LOCK := true; + EDGE_LOCK := true; + HI_FLT := "11"; + LOW_FLT := "11"; + SDATA_EDGE <= '0'; + NEW_SDATA := '1'; + -- Positive or negative edge detector for the incoming data. + -- Any transition must be valid for at least three receiver clock + -- cycles. The TIMER locking inhibits detecting four receiver + -- clock cycles after a valid transition. + elsif RXCLK = '1' and SDATA_IN = '0' and CLK_LOCK = false and LOW_FLT > "00" then + CLK_LOCK := true; + EDGE_LOCK := false; + HI_FLT := "00"; + LOW_FLT := LOW_FLT - '1'; + elsif RXCLK = '1' and SDATA_IN = '1' and CLK_LOCK = false and HI_FLT < "11" then + CLK_LOCK := true; + EDGE_LOCK := false; + LOW_FLT := "11"; + HI_FLT := HI_FLT + '1'; + elsif RXCLK = '1' and EDGE_LOCK = false and LOW_FLT = "00" then + EDGE_LOCK := true; + SDATA_EDGE <= '1'; -- Falling edge detected. + NEW_SDATA := '0'; + elsif RXCLK = '1' and EDGE_LOCK = false and HI_FLT = "11" then + EDGE_LOCK := true; + SDATA_EDGE <= '1'; -- Rising edge detected. + NEW_SDATA := '1'; + elsif RXCLK = '1' and CLK_LOCK = false then + CLK_LOCK := true; + SDATA_EDGE <= '0'; + elsif RXCLK = '0' then + CLK_LOCK := false; + end if; + -- + if RESETn = '0' or RE = '0' then + -- The reset condition assumes the SDATA_IN logic high. Otherwise + -- one not valid SDATA_EDGE pulse occurs during system startup. + TIMER := "111"; + TIMER_LOCK := true; + SDATA_DIV16 <= '1'; + -- The timer controls the SDATA in a way, that after a detected valid + -- Transistion, the serial data is sampled on the 8th receiver clock + -- edge after the initial valid transition occured. + elsif RXCLK = '1' and SDATA_EDGE = '1' and TIMER_LOCK = false then + TIMER_LOCK := true; + TIMER := "000"; -- Resynchronisation. + elsif RXCLK = '1' and TIMER = "011" and TIMER_LOCK = false then + TIMER_LOCK := true; + SDATA_DIV16 <= NEW_SDATA; -- Scan the new data. + TIMER := TIMER + '1'; -- Timing is active. + elsif RXCLK = '1' and TIMER < "111" and TIMER_LOCK = false then + TIMER_LOCK := true; + TIMER := TIMER + '1'; -- Timing is active. + elsif RXCLK = '0' then + TIMER_LOCK := false; + end if; + end process P_SAMPLE; + + P_START_BIT: process(CLK) + -- This is the valid start bit logic of the original MC68901 multi function + -- port's USART receiver. + variable TMP : std_logic_vector(2 downto 0); + variable LOCK : boolean; + begin + if CLK = '1' and CLK' event then + if RESETn = '0' then + TMP := "000"; + LOCK := true; + elsif RE = '0' or RCV_STATE /= IDLE then -- Start bit logic disabled. + TMP := "000"; + LOCK := true; + elsif SDATA_EDGE = '1' then + TMP := "000"; -- (Re)-Initialize. + LOCK := false; -- Start counting. + elsif RXCLK = '1' and SDATA_IN = '0' and TMP < "111" and LOCK = false then + LOCK := true; + TMP := TMP + '1'; -- Count 8 low bits to declare start condition valid. + elsif RXCLK = '0' then + LOCK := false; + end if; + end if; + + case TMP is + when "111" => STARTBIT <= true; + when others => STARTBIT <= false; + end case; + end process P_START_BIT; + + SDATA_IN_I <= SDATA_IN when CLK_MODE = '0' else -- Clock div by 1 mode. + SDATA_IN when ST = "00" else SDATA_DIV16; -- Synchronous mode. + + CLKDIV: process + variable CLK_LOCK : boolean; + variable STRB_LOCK : boolean; + variable CLK_DIVCNT : std_logic_vector(4 downto 0); + begin + wait until CLK = '1' and CLK' event; + if CLK_MODE = '0' then -- Divider off. + if RXCLK = '1' and STRB_LOCK = false then + CLK_STRB <= '1'; + STRB_LOCK := true; + elsif RXCLK = '0' then + CLK_STRB <= '0'; + STRB_LOCK := false; + else + CLK_STRB <= '0'; + end if; + CLK_2_STRB <= '0'; -- No 1 1/2 stop bits in no div by 16 mode. + elsif SDATA_EDGE = '1' then +CLK_DIVCNT := "01100"; -- Div by 16 mode. + CLK_STRB <= '0'; -- Default. + CLK_2_STRB <= '0'; -- Default. + else + CLK_STRB <= '0'; -- Default. + CLK_2_STRB <= '0'; -- Default. + if CLK_DIVCNT > "00000" and RXCLK = '1' and CLK_LOCK = false then + CLK_DIVCNT := CLK_DIVCNT - '1'; + CLK_LOCK := true; + if CLK_DIVCNT = "01000" then + -- This strobe is asserted at half of the clock cycle. + -- It is used for the stop bit timing. + CLK_2_STRB <= '1'; + end if; + elsif CLK_DIVCNT = "00000" then + CLK_DIVCNT := "10000"; -- Div by 16 mode. + if STRB_LOCK = false then + STRB_LOCK := true; + CLK_STRB <= '1'; + end if; + elsif RXCLK = '0' then + CLK_LOCK := false; + STRB_LOCK := false; + end if; + end if; + end process CLKDIV; + + SHIFTREG: process(RESETn, CLK) + begin + if RESETn = '0' then + SHIFT_REG <= x"00"; + elsif CLK = '1' and CLK' event then + if RE = '0' then + SHIFT_REG <= x"00"; + elsif RCV_STATE = SAMPLE and CLK_STRB = '1' then + SHIFT_REG <= SDATA_IN_I & SHIFT_REG(7 downto 1); -- Shift right. + end if; + end if; + end process SHIFTREG; + + P_M_CIP: process(RESETn, CLK) + -- In Synchronous mode this flag indicates wether a synchronous character M_CIP = '1' + -- or another character (M_CIP = '0') is transferred to the receive buffer. + -- In asynchronous mode the flag indicates sampling condition. + begin + if RESETn = '0' then + M_CIP <= '0'; + elsif CLK = '0' and CLK' event then + if RE = '0' then + M_CIP <= '0'; + elsif ST = "00" then -- Synchronous mode. + if RCV_STATE = SYNC and SHIFT_REG = SCR and RDRF = '0' then + M_CIP <= '1'; -- SCR transferred. + elsif RCV_STATE = SYNC and RDRF = '0' then + M_CIP <= '0'; -- No SCR transferred. + end if; + else -- Asynchronous mode. + case RCV_STATE is + when SAMPLE | PARITY | STOP1 | STOP2 => M_CIP <= '1'; -- Sampling. + when others => M_CIP <= '0'; -- No Sampling. + end case; + end if; + end if; + end process P_M_CIP; + + BREAK_DETECT: process(RESETn, CLK) + -- A break condition occurs, if there is no STOP1 bit and the + -- shift register contains zero data. + begin + if RESETn = '0' then + BREAK <= false; + elsif CLK = '1' and CLK' event then + if RE = '0' then + BREAK <= false; + elsif CLK_STRB = '1' then + if RCV_STATE = STOP1 and SDATA_IN_I = '0' and SHIFT_REG = x"00" then + BREAK <= true; -- Break detected (empty shift register and no stop bit). + elsif RCV_STATE = STOP1 and SDATA_IN_I = '1' then + BREAK <= false; -- UPDATE. + elsif RCV_STATE = STOP1 and SDATA_IN_I = '0' and SHIFT_REG /= x"00" then + BREAK <= false; -- UPDATE, but framing error. + end if; + end if; + end if; + end process BREAK_DETECT; + + P_FS_B: process(RESETn, CLK) + -- In the synchronous mode, this process provides the flag detecting the synchronous + -- character. In the asynchronous mode, the flag indicates a break condition. + variable FS_B_I : bit; + variable FIRST_READ : boolean; + begin + if RESETn = '0' then + FS_B <= '0'; + FIRST_READ := false; + FS_B_I := '0'; + elsif CLK = '0' and CLK' event then + if RE = '0' then + FS_B <= '0'; + FS_B_I := '0'; + else + if ST = "00" then -- Synchronous operation. + if FS_CLR = '1' then + FS_B <= '0'; -- Clear during writing to the SCR. + elsif SHIFT_REG = SCR then + FS_B <= '1'; -- SCR detected. + end if; + else -- Asynchronous operation. + if RX_SAMPLE = '1' and BREAK = true then -- Break condition detected. + FS_B_I := '1'; -- Update. + elsif RX_SAMPLE = '1' then -- No break condition. + FS_B_I := '0'; -- Update. + elsif RSR_READ = '1' and FS_B_I = '1' then + -- If a break condition was detected, the concerning flag is + -- set when the valid data word in the receiver data + -- register is read. Thereafter the break flag is reset + -- and the break condition disappears after a second read + -- (in time) of the receiver status register. + if FIRST_READ = false then + FS_B <= '1'; + FIRST_READ := true; + else + FS_B <= '0'; + FIRST_READ := false; + end if; + end if; + end if; + end if; + end if; + end process P_FS_B; + + P_BITCNT: process + begin + wait until CLK = '1' and CLK' event; + if RCV_STATE = SAMPLE and CLK_STRB = '1' and ST /= "00" then -- Asynchronous mode. + BITCNT <= BITCNT + '1'; + elsif RCV_STATE = SAMPLE and CLK_STRB = '1' and ST = "00" and FS_B = '1' then -- Synchronous mode. + BITCNT <= BITCNT + '1'; -- Count, if matched data found (FS_B = '1'). + elsif RCV_STATE /= SAMPLE then + BITCNT <= (others => '0'); + end if; + end process P_BITCNT; + + BUFFER_FULL: process(RESETn, CLK) + -- Receive data register full flag. + begin + if RESETn = '0' then + RDRF <= '0'; + elsif CLK = '1' and CLK' event then + if RE = '0' then + RDRF <= '0'; + elsif RX_SAMPLE = '1' then + RDRF <= '1'; -- Data register is full until now! + elsif UDR_READ = '1' then + RDRF <= '0'; -- After reading the data register ... + end if; + end if; + end process BUFFER_FULL; + + OVERRUN: process(RESETn, CLK) + variable OE_I : bit; + variable FIRST_READ : boolean; + begin + if RESETn = '0' then + OE_I := '0'; + OE <= '0'; + FIRST_READ := false; + elsif CLK = '1' and CLK' event then + if RESETn = '0' then + OE_I := '0'; + OE <= '0'; + FIRST_READ := false; + elsif CLK_STRB = '1' and RCV_STATE = SYNC and BREAK = false then + -- Overrun appears if RDRF is '1' in this state and there + -- is no break condition. + OE_I := RDRF; + end if; + if RSR_READ = '1' and OE_I = '1' then + -- if an overrun was detected, the concerning flag is + -- set when the valid data word in the receiver data + -- register is read. Thereafter the RDRF flag is reset + -- and the overrun disappears (OE_I goes low) after + -- a second read (in time) of the receiver data register. + if FIRST_READ = false then + OE <= '1'; + FIRST_READ := true; + else + OE <= '0'; + FIRST_READ := false; + end if; + end if; + end if; + end process OVERRUN; + + PARITY_TEST: process(RESETn, CLK) + variable PAR_TMP : bit; + variable P_ERR : bit; + begin + if RESETn = '0' then + PE <= '0'; + elsif CLK = '1' and CLK' event then + if RE = '0' then + PE <= '0'; + elsif RX_SAMPLE = '1' then + PE <= P_ERR; -- Update on load shift register to data register. + elsif CLK_STRB = '1' then -- Sample parity on clock strobe. + P_ERR := '0'; -- Initialise. + if RCV_STATE = PARITY then + for i in 1 to 7 loop + if i = 1 then + PAR_TMP := SHIFT_REG(i-1) xor SHIFT_REG(i); + else + PAR_TMP := PAR_TMP xor SHIFT_REG(i); + end if; + end loop; + if P_ENA = '1' and P_EOn = '1' then -- Even parity. + P_ERR := PAR_TMP xor SDATA_IN_I; + elsif P_ENA = '1' and P_EOn = '0' then -- Odd parity. + P_ERR := not PAR_TMP xor SDATA_IN_I; + elsif P_ENA = '0' then -- No parity. + P_ERR := '0'; + end if; + end if; + end if; + end if; + end process PARITY_TEST; + + FRAME_ERR: process(RESETn, CLK) + -- This module detects a framing error + -- during stop bit 1 and stop bit 2. + variable FE_I: bit; + begin + if RESETn = '0' then + FE_I := '0'; + FE <= '0'; + elsif CLK = '1' and CLK' event then + if RE = '0' then + FE_I := '0'; + FE <= '0'; + elsif CLK_STRB = '1' then + if RCV_STATE = STOP1 and SDATA_IN_I = '0' and SHIFT_REG /= x"00" then + FE_I := '1'; + elsif RCV_STATE = STOP2 and SDATA_IN_I = '0' and SHIFT_REG /= x"00" then + FE_I := '1'; + elsif RCV_STATE = STOP1 or RCV_STATE = STOP2 then + FE_I := '0'; -- Error resets when correct data appears. + end if; + end if; + if RCV_STATE = SYNC then + FE <= FE_I; -- Update the FE every SYNC time. + end if; + end if; + end process FRAME_ERR; + + RCV_STATEREG: process(RESETn, CLK) + begin + if RESETn = '0' then + RCV_STATE <= IDLE; + elsif CLK = '1' and CLK' event then + if RE = '0' then + RCV_STATE <= IDLE; + else + RCV_STATE <= RCV_NEXT_STATE; + end if; + end if; + end process RCV_STATEREG; + + RCV_STATEDEC: process(RCV_STATE, SDATA_IN_I, BITCNT, CLK_STRB, STARTBIT, + CLK_2_STRB, ST, CLK_MODE, CL, P_ENA, SHIFT_REG) + begin + case RCV_STATE is + when IDLE => + if ST = "00" then + RCV_NEXT_STATE <= SAMPLE; -- Synchronous mode. + elsif SDATA_IN_I = '0' and CLK_MODE = '0' then + RCV_NEXT_STATE <= SAMPLE; -- Startbit detected in div by 1 mode. + elsif STARTBIT = true and CLK_MODE = '1' then + RCV_NEXT_STATE <= WAIT_START; -- Startbit detected in div by 16 mode. + else + RCV_NEXT_STATE <= IDLE; -- No startbit; sleep well :-) + end if; + when WAIT_START => + -- This state delays the sample process by one CLK_STRB pulse + -- to eliminate the start bit. + if CLK_STRB = '1' then + RCV_NEXT_STATE <= SAMPLE; + else + RCV_NEXT_STATE <= WAIT_START; + end if; + when SAMPLE => + if CLK_STRB = '1' then + if CL = "11" and BITCNT < "100" then + RCV_NEXT_STATE <= SAMPLE; -- Go on sampling 5 data bits. + elsif CL = "10" and BITCNT < "101" then + RCV_NEXT_STATE <= SAMPLE; -- Go on sampling 6 data bits. + elsif CL = "01" and BITCNT < "110" then + RCV_NEXT_STATE <= SAMPLE; -- Go on sampling 7 data bits. + elsif CL = "00" and BITCNT < "111" then + RCV_NEXT_STATE <= SAMPLE; -- Go on sampling 8 data bits. + elsif ST = "00" and P_ENA = '0' then -- Synchronous mode (no stop bits). + RCV_NEXT_STATE <= IDLE; -- No parity check enabled. + elsif P_ENA = '0' then + RCV_NEXT_STATE <= STOP1; -- No parity check enabled. + else + RCV_NEXT_STATE <= PARITY; -- Parity enabled. + end if; + else + RCV_NEXT_STATE <= SAMPLE; -- Stay in sample mode. + end if; + when PARITY => + if CLK_STRB = '1' then + if ST = "00" then -- Synchronous mode (no stop bits). + RCV_NEXT_STATE <= IDLE; + else + RCV_NEXT_STATE <= STOP1; + end if; + else + RCV_NEXT_STATE <= PARITY; + end if; + when STOP1 => + if CLK_STRB = '1' then + if SHIFT_REG > x"00" and SDATA_IN_I = '0' then -- No Stop bit after non zero data. + RCV_NEXT_STATE <= SYNC; -- Framing error detected. + elsif ST = "11" or ST = "10" then + RCV_NEXT_STATE <= STOP2; -- More than one stop bits selected. + else + RCV_NEXT_STATE <= SYNC; -- One stop bit selected. + end if; + else + RCV_NEXT_STATE <= STOP1; + end if; + when STOP2 => + if CLK_2_STRB = '1' and ST = "10" then + RCV_NEXT_STATE <= SYNC; -- One and a half stop bits selected. + elsif CLK_STRB = '1' then + RCV_NEXT_STATE <= SYNC; -- Two stop bits selected. + else + RCV_NEXT_STATE <= STOP2; + end if; + when SYNC => + RCV_NEXT_STATE <= IDLE; + end case; + end process RCV_STATEDEC; +end architecture BEHAVIOR; + diff --git a/vhdl/rtl/vhdl/WF_MFP68901_IP/wf68901ip_usart_top.vhd b/vhdl/rtl/vhdl/WF_MFP68901_IP/wf68901ip_usart_top.vhd new file mode 100644 index 0000000..ab1e403 --- /dev/null +++ b/vhdl/rtl/vhdl/WF_MFP68901_IP/wf68901ip_usart_top.vhd @@ -0,0 +1,238 @@ +---------------------------------------------------------------------- +---- ---- +---- ATARI MFP compatible IP Core ---- +---- ---- +---- This file is part of the SUSKA ATARI clone project. ---- +---- http://www.experiment-s.de ---- +---- ---- +---- Description: ---- +---- MC68901 compatible multi function port core. ---- +---- ---- +---- This is the SUSKA MFP IP core USART top level file. ---- +---- ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2006 - 2011 Wolfgang Foerster ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.gnu.org/licenses/lgpl.html ---- +---- ---- +---------------------------------------------------------------------- +-- +-- Revision History +-- +-- Revision 2K6A 2006/06/03 WF +-- Initial Release. +-- Revision 2K6B 2006/11/07 WF +-- Modified Source to compile with the Xilinx ISE. +-- Revision 2K8A 2008/07/14 WF +-- Minor changes. +-- + +use work.wf68901ip_pkg.all; + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + +entity WF68901IP_USART_TOP is + port ( -- System control: + CLK : in bit; + RESETn : in bit; + + -- Asynchronous bus control: + DSn : in bit; + CSn : in bit; + RWn : in bit; + + -- Data and Adresses: + RS : in bit_vector(5 downto 1); + DATA_IN : in bit_vector(7 downto 0); + DATA_OUT : out bit_vector(7 downto 0); + DATA_OUT_EN : out bit; + + -- Serial I/O control: + RC : in bit; -- Receiver clock. + TC : in bit; -- Transmitter clock. + SI : in bit; -- Serial input. + SO : out bit; -- Serial output. + SO_EN : out bit; -- Serial output enable. + + -- Interrupt channels: + RX_ERR_INT : out bit; -- Receiver errors. + RX_BUFF_INT : out bit; -- Receiver buffer full. + TX_ERR_INT : out bit; -- Transmitter errors. + TX_BUFF_INT : out bit; -- Transmitter buffer empty. + + -- DMA control: + RRn : out bit; + TRn : out bit + ); +end entity WF68901IP_USART_TOP; + +architecture STRUCTURE of WF68901IP_USART_TOP is + signal BF_I : bit; + signal BE_I : bit; + signal FE_I : bit; + signal OE_I : bit; + signal UE_I : bit; + signal PE_I : bit; + signal LOOPBACK_I : bit; + signal SD_LEVEL_I : bit; + signal SDATA_IN_I : bit; + signal SDATA_OUT_I : bit; + signal RXCLK_I : bit; + signal CLK_MODE_I : bit; + signal SCR_I : bit_vector(7 downto 0); + signal RX_SAMPLE_I : bit; + signal RX_DATA_I : bit_vector(7 downto 0); + signal TX_DATA_I : bit_vector(7 downto 0); + signal CL_I : bit_vector(1 downto 0); + signal ST_I : bit_vector(1 downto 0); + signal P_ENA_I : bit; + signal P_EOn_I : bit; + signal RE_I : bit; + signal TE_I : bit; + signal FS_CLR_I : bit; + signal SS_I : bit; + signal M_CIP_I : bit; + signal FS_B_I : bit; + signal BR_I : bit; + signal UDR_READ_I : bit; + signal UDR_WRITE_I : bit; + signal RSR_READ_I : bit; + signal TSR_READ_I : bit; + signal TX_END_I : bit; +begin + SO <= SDATA_OUT_I when TE_I = '1' else SD_LEVEL_I; + -- Loopback mode: + SDATA_IN_I <= SDATA_OUT_I when LOOPBACK_I = '1' and TE_I = '1' else -- Loopback, transmitter enabled. + '1' when LOOPBACK_I = '1' and TE_I = '0' else SI; -- Loopback, transmitter disabled. + + RXCLK_I <= TC when LOOPBACK_I = '1' else RC; + RRn <= '0' when BF_I = '1' and PE_I = '0' and FE_I = '0' else '1'; + TRn <= not BE_I; + + -- Interrupt sources: + RX_ERR_INT <= OE_I or PE_I or FE_I or FS_B_I; + RX_BUFF_INT <= BF_I; + TX_ERR_INT <= UE_I or TX_END_I; + TX_BUFF_INT <= BE_I; + + I_USART_CTRL: WF68901IP_USART_CTRL + port map( + CLK => CLK, + RESETn => RESETn, + DSn => DSn, + CSn => CSn, + RWn => RWn, + RS => RS, + DATA_IN => DATA_IN, + DATA_OUT => DATA_OUT, + DATA_OUT_EN => DATA_OUT_EN, + LOOPBACK => LOOPBACK_I, + SDOUT_EN => SO_EN, + SD_LEVEL => SD_LEVEL_I, + CLK_MODE => CLK_MODE_I, + RE => RE_I, + TE => TE_I, + P_ENA => P_ENA_I, + P_EOn => P_EOn_I, + BF => BF_I, + BE => BE_I, + FE => FE_I, + OE => OE_I, + UE => UE_I, + PE => PE_I, + M_CIP => M_CIP_I, + FS_B => FS_B_I, + SCR_OUT => SCR_I, + TX_DATA => TX_DATA_I, + RX_SAMPLE => RX_SAMPLE_I, + RX_DATA => RX_DATA_I, + SS => SS_I, + BR => BR_I, + CL => CL_I, + ST => ST_I, + FS_CLR => FS_CLR_I, + UDR_READ => UDR_READ_I, + UDR_WRITE => UDR_WRITE_I, + RSR_READ => RSR_READ_I, + TSR_READ => TSR_READ_I, + TX_END => TX_END_I + ); + + I_USART_RECEIVE: WF68901IP_USART_RX + port map ( + CLK => CLK, + RESETn => RESETn, + SCR => SCR_I, + RX_SAMPLE => RX_SAMPLE_I, + RX_DATA => RX_DATA_I, + CL => CL_I, + ST => ST_I, + P_ENA => P_ENA_I, + P_EOn => P_EOn_I, + CLK_MODE => CLK_MODE_I, + RE => RE_I, + FS_CLR => FS_CLR_I, + SS => SS_I, + RXCLK => RXCLK_I, + SDATA_IN => SDATA_IN_I, + RSR_READ => RSR_READ_I, + UDR_READ => UDR_READ_I, + M_CIP => M_CIP_I, + FS_B => FS_B_I, + BF => BF_I, + OE => OE_I, + PE => PE_I, + FE => FE_I + ); + + I_USART_TRANSMIT: WF68901IP_USART_TX + port map ( + CLK => CLK, + RESETn => RESETn, + SCR => SCR_I, + TX_DATA => TX_DATA_I, + SDATA_OUT => SDATA_OUT_I, + TXCLK => TC, + CL => CL_I, + ST => ST_I, + TE => TE_I, + BR => BR_I, + P_ENA => P_ENA_I, + P_EOn => P_EOn_I, + UDR_WRITE => UDR_WRITE_I, + TSR_READ => TSR_READ_I, + CLK_MODE => CLK_MODE_I, + TX_END => TX_END_I, + UE => UE_I, + BE => BE_I + ); +end architecture STRUCTURE; diff --git a/vhdl/rtl/vhdl/WF_MFP68901_IP/wf68901ip_usart_tx.vhd b/vhdl/rtl/vhdl/WF_MFP68901_IP/wf68901ip_usart_tx.vhd new file mode 100644 index 0000000..160a570 --- /dev/null +++ b/vhdl/rtl/vhdl/WF_MFP68901_IP/wf68901ip_usart_tx.vhd @@ -0,0 +1,387 @@ +---------------------------------------------------------------------- +---- ---- +---- ATARI MFP compatible IP Core ---- +---- ---- +---- This file is part of the SUSKA ATARI clone project. ---- +---- http://www.experiment-s.de ---- +---- ---- +---- Description: ---- +---- This is the SUSKA MFP IP core USART transmitter file. ---- +---- ---- +---- ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2006 - 2011 Wolfgang Foerster ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.gnu.org/licenses/lgpl.html ---- +---- ---- +---------------------------------------------------------------------- +-- +-- Revision History +-- +-- Revision 2K6A 2006/06/03 WF +-- Initial Release. +-- Revision 2K6B 2006/11/07 WF +-- Modified Source to compile with the Xilinx ISE. +-- Revision 2K8A 2008/07/14 WF +-- Minor changes. +-- Revision 2K9A 2009/06/20 WF +-- TDRE has now synchronous reset to meet preset requirement. +-- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + +entity WF68901IP_USART_TX is + port ( + CLK : in bit; + RESETn : in bit; + + SCR : in bit_vector(7 downto 0); -- Synchronous character. + TX_DATA : in bit_vector(7 downto 0); -- Normal data. + + SDATA_OUT : out bit; -- Serial data output. + TXCLK : in bit; -- Transmitter clock. + + CL : in bit_vector(1 downto 0); -- Character length. + ST : in bit_vector(1 downto 0); -- Start and stop bit configuration. + TE : in bit; -- Transmitter enable. + BR : in bit; -- BREAK character send enable (all '0' without stop bit). + P_ENA : in bit; -- Parity enable. + P_EOn : in bit; -- Even or odd parity. + UDR_WRITE : in bit; -- Flag indicating writing the data register. + TSR_READ : in bit; -- Flag indicating reading the transmitter status register. + CLK_MODE : in bit; -- Transmitter clock mode. + + TX_END : out bit; -- End of transmission flag. + UE : out bit; -- Underrun Flag. + BE : out bit -- Buffer empty flag. + ); +end entity WF68901IP_USART_TX; + +architecture BEHAVIOR of WF68901IP_USART_TX is +type TR_STATES is (IDLE, CHECK_BREAK, LOAD_SHFT, START, SHIFTOUT, PARITY, STOP1, STOP2); +signal TR_STATE, TR_NEXT_STATE : TR_STATES; +signal CLK_STRB : bit; +signal CLK_2_STRB : bit; +signal SHIFT_REG : bit_vector(7 downto 0); +signal BITCNT : std_logic_vector(2 downto 0); +signal PARITY_I : bit; +signal TDRE : bit; +signal BREAK : bit; +begin + BE <= TDRE; -- Buffer empty flag. + + -- The default condition in this statement is to ensure + -- to cover all possibilities for example if there is a + -- one hot decoding of the state machine with wrong states + -- (e.g. not one of the given here). + SDATA_OUT <= '0' when BREAK = '1' else + '1' when TR_STATE = IDLE else + '1' when TR_STATE = LOAD_SHFT else + '0' when TR_STATE = START else + SHIFT_REG(0) when TR_STATE = SHIFTOUT else + PARITY_I when TR_STATE = PARITY else + '1' when TR_STATE = STOP1 else + '1' when TR_STATE = STOP2 else '1'; + + P_BREAK : process(RESETn, CLK) + -- This process is responsible to control the BREAK signal. After the break request + -- is asserted via BR, the break character will be sent after the current transmission has + -- finished. The BREAK character is sent until the BR is disabled. + variable LOCK : boolean; + begin + if RESETn = '0' then + BREAK <= '0'; + elsif CLK = '1' and CLK' event then + -- Break is only available in the asynchronous mode (ST /= "00"). + -- The LOCK mechanism is reponsible for sending the BREAK character just once. + if TE = '1' and BR = '1' and ST /= "00" and TR_STATE = IDLE and LOCK = false then + BREAK <= '1'; -- Break for the case that there is no current transmission. + LOCK := true; + elsif BR = '1' and ST /= "00" and TR_STATE = STOP1 then + BREAK <= '0'; -- Break character sent. + elsif BR = '0' then + BREAK <= '0'; + LOCK := false; + else + BREAK <= '0'; + end if; + end if; + end process P_BREAK; + + CLKDIV: process + variable CLK_LOCK : boolean; + variable STRB_LOCK : boolean; + variable CLK_DIVCNT : std_logic_vector(4 downto 0); + begin + wait until CLK = '1' and CLK' event; + if CLK_MODE = '0' then -- Divider off. + if TXCLK = '0' and STRB_LOCK = false then -- Works on negative TXCLK edge. + CLK_STRB <= '1'; + STRB_LOCK := true; + elsif TXCLK = '1' then + CLK_STRB <= '0'; + STRB_LOCK := false; + else + CLK_STRB <= '0'; + end if; + CLK_2_STRB <= '0'; -- No 1 1/2 stop bits in no div by 16 mode. + elsif TR_STATE = IDLE then + CLK_DIVCNT := "10000"; -- Div by 16 mode. + CLK_STRB <= '0'; + else + CLK_STRB <= '0'; -- Default. + CLK_2_STRB <= '0'; -- Default. + -- Works on negative TXCLK edge: + if CLK_DIVCNT > "00000" and TXCLK = '0' and CLK_LOCK = false then + CLK_DIVCNT := CLK_DIVCNT - '1'; + CLK_LOCK := true; + if CLK_DIVCNT = "01000" then + -- This strobe is asserted at half of the clock cycle. + -- It is used for the stop bit timing. + CLK_2_STRB <= '1'; + end if; + elsif CLK_DIVCNT = "00000" then + CLK_DIVCNT := "10000"; -- Div by 16 mode. + if STRB_LOCK = false then + STRB_LOCK := true; + CLK_STRB <= '1'; + end if; + elsif TXCLK = '1' then + CLK_LOCK := false; + STRB_LOCK := false; + end if; + end if; + end process CLKDIV; + + SHIFTREG: process(RESETn, CLK) + begin + if RESETn = '0' then + SHIFT_REG <= x"00"; + elsif CLK = '1' and CLK' event then + if TR_STATE = LOAD_SHFT and TDRE = '1' then -- Lost data ... + case ST is + when "00" => -- Synchronous mode. + SHIFT_REG <= SCR; -- Send the synchronous character. + when others => -- Asynchronous mode. + SHIFT_REG <= x"5A"; -- Load the shift register with a mark (underrun). + end case; + elsif TR_STATE = LOAD_SHFT then + -- Load 'normal' data if there is no break condition: + case CL is + when "11" => SHIFT_REG <= "000" & TX_DATA(4 downto 0); -- 5 databits. + when "10" => SHIFT_REG <= "00" & TX_DATA(5 downto 0); -- 6 databits. + when "01" => SHIFT_REG <= '0' & TX_DATA(6 downto 0); -- 7 databits. + when "00" => SHIFT_REG <= TX_DATA; -- 8 databits. + end case; + elsif TR_STATE = SHIFTOUT and CLK_STRB = '1' then + SHIFT_REG <= '0' & SHIFT_REG(7 downto 1); -- Shift right. + end if; + end if; + end process SHIFTREG; + + P_BITCNT: process + -- Counter for the data bits transmitted. + begin + wait until CLK = '1' and CLK' event; + if TR_STATE = SHIFTOUT and CLK_STRB = '1' then + BITCNT <= BITCNT + '1'; + elsif TR_STATE /= SHIFTOUT then + BITCNT <= "000"; + end if; + end process P_BITCNT; + + BUFFER_EMPTY: process + -- Transmit data register empty flag. + begin + wait until CLK = '1' and CLK' event; + if RESETn = '0' then + TDRE <= '1'; + elsif TE = '0' then + TDRE <= '1'; + elsif TR_STATE = START and BREAK = '0' then + -- Data has been loaded to the shift register, + -- thus data register is free again. + -- If the BREAK flag is enabled, the BE flag + -- respective TDRE flag cannot be set. + TDRE <= '1'; + elsif UDR_WRITE = '1' then + TDRE <= '0'; + end if; + end process BUFFER_EMPTY; + + UNDERRUN: process(RESETn, CLK) + variable LOCK : boolean; + begin + if RESETn = '0' then + UE <= '0'; + LOCK := false; + elsif CLK = '1' and CLK' event then + if TE = '0' then + UE <= '0'; + LOCK := false; + elsif CLK_STRB = '1' and TR_STATE = START then + -- Underrun appears if TDRE is '0' at the end of this state. + UE <= TDRE; -- Never true for enabled BREAK flag. See alos process BUFFER_EMPTY. + LOCK := true; + elsif CLK_STRB = '1' then + LOCK := false; -- Disables clearing UE one transmit clock cycle. + elsif TSR_READ = '1' and LOCK = false then + UE <= '0'; + end if; + end if; + end process UNDERRUN; + + P_TX_END: process(RESETn, CLK) + begin + if RESETn = '0' then + TX_END <= '0'; + elsif CLK = '1' and CLK' event then + if TE = '1' then -- Transmitter enabled. + TX_END <= '0'; + elsif TE = '0' and TR_STATE = IDLE then + TX_END <= '1'; + end if; + end if; + end process P_TX_END; + + PARITY_GEN: process + variable PAR_TMP : bit; + begin + wait until CLK = '1' and CLK' event; + if TR_STATE = START then -- Calculate the parity during the start phase. + for i in 1 to 7 loop + if i = 1 then + PAR_TMP := SHIFT_REG(i-1) xor SHIFT_REG(i); + else + PAR_TMP := PAR_TMP xor SHIFT_REG(i); + end if; + end loop; + if P_ENA = '1' and P_EOn = '1' then -- Even parity. + PARITY_I <= PAR_TMP; + elsif P_ENA = '1' and P_EOn = '0' then -- Odd parity. + PARITY_I <= not PAR_TMP; + else -- No parity. + PARITY_I <= '0'; + end if; + end if; + end process PARITY_GEN; + + TR_STATEREG: process(RESETn, CLK) + begin + if RESETn = '0' then + TR_STATE <= IDLE; + elsif CLK = '1' and CLK' event then + TR_STATE <= TR_NEXT_STATE; + end if; + end process TR_STATEREG; + + TR_STATEDEC: process(TR_STATE, CLK_STRB, CLK_2_STRB, BITCNT, TDRE, BREAK, TE, ST, P_ENA, CL, BR) + begin + case TR_STATE is + when IDLE => + -- This IDLE state is just one clock cycle and is required to give the + -- break process time to set the BREAK flag. + TR_NEXT_STATE <= CHECK_BREAK; + when CHECK_BREAK => + if BREAK = '1' then -- Send break character. + -- Do not load any data to the shift register, go directly + -- to the START state. + TR_NEXT_STATE <= START; + -- Start enabled transmitter, if the data register is not empty. + -- Do not send any further data for the case of an asserted BR flag. + elsif TE = '1' and TDRE = '0' and BR = '0' then + TR_NEXT_STATE <= LOAD_SHFT; + else + TR_NEXT_STATE <= IDLE; -- Go back, scan for BREAK. + end if; + when LOAD_SHFT => + TR_NEXT_STATE <= START; + when START => -- Send the start bit. + if CLK_STRB = '1' then + TR_NEXT_STATE <= SHIFTOUT; + else + TR_NEXT_STATE <= START; + end if; + when SHIFTOUT => + if CLK_STRB = '1' then + if BITCNT < "100" and CL = "11" then + TR_NEXT_STATE <= SHIFTOUT; -- Transmit 5 data bits. + elsif BITCNT < "101" and CL = "10" then + TR_NEXT_STATE <= SHIFTOUT; -- Transmit 6 data bits. + elsif BITCNT < "110" and CL = "01" then + TR_NEXT_STATE <= SHIFTOUT; -- Transmit 7 data bits. + elsif BITCNT < "111" and CL = "00" then + TR_NEXT_STATE <= SHIFTOUT; -- Transmit 8 data bits. + elsif P_ENA = '0' and BREAK = '1' then + TR_NEXT_STATE <= IDLE; -- Break condition, no parity check enabled, no stop bits. + elsif P_ENA = '0' and ST = "00" then + TR_NEXT_STATE <= IDLE; -- Synchronous mode, no parity check enabled. + elsif P_ENA = '0' then + TR_NEXT_STATE <= STOP1; -- Asynchronous mode, no parity check enabled. + else + TR_NEXT_STATE <= PARITY; -- Parity enabled. + end if; + else + TR_NEXT_STATE <= SHIFTOUT; + end if; + when PARITY => + if CLK_STRB = '1' then + if ST = "00" then -- Synchronous mode (no stop bits). + TR_NEXT_STATE <= IDLE; + elsif BREAK = '1' then -- No stop bits during break condition. + TR_NEXT_STATE <= IDLE; + else + TR_NEXT_STATE <= STOP1; + end if; + else + TR_NEXT_STATE <= PARITY; + end if; + when STOP1 => + if CLK_STRB = '1' and (ST = "11" or ST = "10") then + TR_NEXT_STATE <= STOP2; -- More than one stop bits selected. + elsif CLK_STRB = '1' then + TR_NEXT_STATE <= IDLE; -- One stop bits selected. + else + TR_NEXT_STATE <= STOP1; + end if; + when STOP2 => + if CLK_2_STRB = '1' and ST = "10" then + TR_NEXT_STATE <= IDLE; -- One and a half stop bits selected. + elsif CLK_STRB = '1' then + TR_NEXT_STATE <= IDLE; -- Two stop bits detected. + else + TR_NEXT_STATE <= STOP2; + end if; + end case; + end process TR_STATEDEC; +end architecture BEHAVIOR; + diff --git a/vhdl/rtl/vhdl/WF_SND2149_IP/wf2149ip_pkg.vhd b/vhdl/rtl/vhdl/WF_SND2149_IP/wf2149ip_pkg.vhd new file mode 100644 index 0000000..ef29052 --- /dev/null +++ b/vhdl/rtl/vhdl/WF_SND2149_IP/wf2149ip_pkg.vhd @@ -0,0 +1,84 @@ +---------------------------------------------------------------------- +---- ---- +---- YM2149 compatible sound generator. ---- +---- ---- +---- This file is part of the SUSKA ATARI clone project. ---- +---- http://www.experiment-s.de ---- +---- ---- +---- Description: ---- +---- Model of the ST or STE's YM2149 sound generator. ---- +---- ---- +---- This is the package file containing the component ---- +---- declarations. ---- +---- ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2006 - 2011 Wolfgang Foerster ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.gnu.org/licenses/lgpl.html ---- +---- ---- +---------------------------------------------------------------------- +-- +-- Revision History +-- +-- Revision 2K6A 2006/06/03 WF +-- Initial Release. +-- Revision 2K6B 2006/11/07 WF +-- Modified Source to compile with the Xilinx ISE. +-- Revision 2K8A 2008/07/14 WF +-- Minor changes. +-- + +library ieee; +use ieee.std_logic_1164.all; + +package WF2149IP_PKG is +type BUSCYCLES is (INACTIVE, R_READ, R_WRITE, ADDRESS); + +component WF2149IP_WAVE + port( + RESETn : in bit; + SYS_CLK : in bit; + + WAV_STRB : in bit; + + ADR : in bit_vector(3 downto 0); + DATA_IN : in std_logic_vector(7 downto 0); + DATA_OUT : out std_logic_vector(7 downto 0); + DATA_EN : out bit; + + BUSCYCLE : in BUSCYCLES; + CTRL_REG : in bit_vector(5 downto 0); + + OUT_A : out bit; + OUT_B : out bit; + OUT_C : out bit + ); +end component; +end WF2149IP_PKG; \ No newline at end of file diff --git a/vhdl/rtl/vhdl/WF_SND2149_IP/wf2149ip_top.vhd b/vhdl/rtl/vhdl/WF_SND2149_IP/wf2149ip_top.vhd new file mode 100644 index 0000000..3f5024a --- /dev/null +++ b/vhdl/rtl/vhdl/WF_SND2149_IP/wf2149ip_top.vhd @@ -0,0 +1,170 @@ +---------------------------------------------------------------------- +---- ---- +---- YM2149 compatible sound generator. ---- +---- ---- +---- This file is part of the SUSKA ATARI clone project. ---- +---- http://www.experiment-s.de ---- +---- ---- +---- Description: ---- +---- Model of the ST or STE's YM2149 sound generator. ---- +---- This IP core of the sound generator differs slightly from ---- +---- the original. Firstly it is a synchronous design without any ---- +---- latches (like assumed in the original chip). This required ---- +---- the introduction of a system adequate clock. In detail this ---- +---- SYS_CLK should on the one hand be fast enough to meet the ---- +---- timing requirements of the system's bus cycle and should one ---- +---- the other hand drive the PWM modules correctly. To meet both ---- +---- a SYS_CLK of 16MHz or above is recommended. ---- +---- Secondly, the original chip has an implemented DA converter. ---- +---- This feature is not possible in today's FPGAs. Therefore the ---- +---- converter is replaced by pulse width modulators. This solu- ---- +---- tion is very simple in comparison to other approaches like ---- +---- external DA converters with wave tables etc. The soltution ---- +---- with the pulse width modulators is probably not as accurate ---- +---- DAs with wavetables. For a detailed descrition of the hard- ---- +---- ware PWM filter look at the end of the wave file, where the ---- +---- pulse width modulators can be found. ---- +---- For a proper operation it is required, that the wave clock ---- +---- is lower than the system clock. A good choice is for example ---- +---- 2MHz for the wave clock and 16MHz for the system clock. ---- +---- ---- +---- Main module file. ---- +---- ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2006 Wolfgang Foerster ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.gnu.org/licenses/lgpl.html ---- +---- ---- +---------------------------------------------------------------------- +-- +-- Revision History +-- +-- Revision 2K6A 2006/06/03 WF +-- Initial Release. +-- Revision 2K6B 2006/11/07 WF +-- Modified Source to compile with the Xilinx ISE. +-- Revision 2K8B 2008/12/24 WF +-- Rewritten this top level file as a wrapper for the top_soc file. +-- + +library ieee; +use ieee.std_logic_1164.all; +use work.wf2149ip_pkg.all; + +entity WF2149IP_TOP is + port( + + SYS_CLK : in bit; -- Read the inforation in the header! + RESETn : in bit; + + WAV_CLK : in bit; -- Read the inforation in the header! + SELn : in bit; + + BDIR : in bit; + BC2, BC1 : in bit; + + A9n, A8 : in bit; + DA : inout std_logic_vector(7 downto 0); + + IO_A : inout std_logic_vector(7 downto 0); + IO_B : inout std_logic_vector(7 downto 0); + + OUT_A : out bit; -- Analog (PWM) outputs. + OUT_B : out bit; + OUT_C : out bit + ); +end WF2149IP_TOP; + +architecture STRUCTURE of WF2149IP_TOP is +component WF2149IP_TOP_SOC + port( + SYS_CLK : in bit; + RESETn : in bit; + WAV_CLK : in bit; + SELn : in bit; + BDIR : in bit; + BC2, BC1 : in bit; + A9n, A8 : in bit; + DA_IN : in std_logic_vector(7 downto 0); + DA_OUT : out std_logic_vector(7 downto 0); + DA_EN : out bit; + IO_A_IN : in bit_vector(7 downto 0); + IO_A_OUT : out bit_vector(7 downto 0); + IO_A_EN : out bit; + IO_B_IN : in bit_vector(7 downto 0); + IO_B_OUT : out bit_vector(7 downto 0); + IO_B_EN : out bit; + OUT_A : out bit; + OUT_B : out bit; + OUT_C : out bit + ); +end component; +-- +signal DA_OUT : std_logic_vector(7 downto 0); +signal DA_EN : bit; +signal IO_A_IN : bit_vector(7 downto 0); +signal IO_A_OUT : bit_vector(7 downto 0); +signal IO_A_EN : bit; +signal IO_B_IN : bit_vector(7 downto 0); +signal IO_B_OUT : bit_vector(7 downto 0); +signal IO_B_EN : bit; +begin + IO_A_IN <= To_BitVector(IO_A); + IO_B_IN <= To_BitVector(IO_B); + + IO_A <= To_StdLogicVector(IO_A_OUT) when IO_A_EN = '1' else (others => 'Z'); + IO_B <= To_StdLogicVector(IO_B_OUT) when IO_B_EN = '1' else (others => 'Z'); + + DA <= DA_OUT when DA_EN = '1' else (others => 'Z'); + + I_SOUND: WF2149IP_TOP_SOC + port map(SYS_CLK => SYS_CLK, + RESETn => RESETn, + WAV_CLK => WAV_CLK, + SELn => SELn, + BDIR => BDIR, + BC2 => BC2, + BC1 => BC1, + A9n => A9n, + A8 => A8, + DA_IN => DA, + DA_OUT => DA_OUT, + DA_EN => DA_EN, + IO_A_IN => IO_A_IN, + IO_A_OUT => IO_A_OUT, + IO_A_EN => IO_A_EN, + IO_B_IN => IO_B_IN, + IO_B_OUT => IO_B_OUT, + IO_B_EN => IO_B_EN, + OUT_A => OUT_A, + OUT_B => OUT_B, + OUT_C => OUT_C + ); +end STRUCTURE; diff --git a/vhdl/rtl/vhdl/WF_SND2149_IP/wf2149ip_top_soc.vhd b/vhdl/rtl/vhdl/WF_SND2149_IP/wf2149ip_top_soc.vhd new file mode 100644 index 0000000..720c4be --- /dev/null +++ b/vhdl/rtl/vhdl/WF_SND2149_IP/wf2149ip_top_soc.vhd @@ -0,0 +1,229 @@ +---------------------------------------------------------------------- +---- ---- +---- YM2149 compatible sound generator. ---- +---- ---- +---- This file is part of the SUSKA ATARI clone project. ---- +---- http://www.experiment-s.de ---- +---- ---- +---- Description: ---- +---- Model of the ST or STE's YM2149 sound generator. ---- +---- This IP core of the sound generator differs slightly from ---- +---- the original. Firstly it is a synchronous design without any ---- +---- latches (like assumed in the original chip). This required ---- +---- the introduction of a system adequate clock. In detail this ---- +---- SYS_CLK should on the one hand be fast enough to meet the ---- +---- timing requirements of the system's bus cycle and should one ---- +---- the other hand drive the PWM modules correctly. To meet both ---- +---- a SYS_CLK of 16MHz or above is recommended. ---- +---- Secondly, the original chip has an implemented DA converter. ---- +---- This feature is not possible in today's FPGAs. Therefore the ---- +---- converter is replaced by pulse width modulators. This solu- ---- +---- tion is very simple in comparison to other approaches like ---- +---- external DA converters with wave tables etc. The soltution ---- +---- with the pulse width modulators is probably not as accurate ---- +---- DAs with wavetables. For a detailed descrition of the hard- ---- +---- ware PWM filter look at the end of the wave file, where the ---- +---- pulse width modulators can be found. ---- +---- For a proper operation it is required, that the wave clock ---- +---- is lower than the system clock. A good choice is for example ---- +---- 2MHz for the wave clock and 16MHz for the system clock. ---- +---- ---- +---- Main module file. ---- +---- Top level file for use in systems on programmable chips. ---- +---- ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2006 - 2011 Wolfgang Foerster ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.gnu.org/licenses/lgpl.html ---- +---- ---- +---------------------------------------------------------------------- +-- +-- Revision History +-- +-- Revision 2K6A 2006/06/03 WF +-- Initial Release. +-- Revision 2K6B 2006/11/07 WF +-- Modified Source to compile with the Xilinx ISE. +-- Top level file provided for SOC (systems on programmable chips). +-- Revision 2K8A 2008/07/14 WF +-- Minor changes. +-- + +library ieee; +use ieee.std_logic_1164.all; +use work.wf2149ip_pkg.all; + +entity WF2149IP_TOP_SOC is + port( + + SYS_CLK : in bit; -- Read the inforation in the header! + RESETn : in bit; + + WAV_CLK : in bit; -- Read the inforation in the header! + SELn : in bit; + + BDIR : in bit; + BC2, BC1 : in bit; + + A9n, A8 : in bit; + DA_IN : in std_logic_vector(7 downto 0); + DA_OUT : out std_logic_vector(7 downto 0); + DA_EN : out bit; + + IO_A_IN : in bit_vector(7 downto 0); + IO_A_OUT : out bit_vector(7 downto 0); + IO_A_EN : out bit; + IO_B_IN : in bit_vector(7 downto 0); + IO_B_OUT : out bit_vector(7 downto 0); + IO_B_EN : out bit; + + OUT_A : out bit; -- Analog (PWM) outputs. + OUT_B : out bit; + OUT_C : out bit + ); +end WF2149IP_TOP_SOC; + +architecture STRUCTURE of WF2149IP_TOP_SOC is +signal BUSCYCLE : BUSCYCLES; +signal DATA_OUT_I : std_logic_vector(7 downto 0); +signal DATA_EN_I : bit; +signal WAV_STRB : bit; +signal ADR_I : bit_vector(3 downto 0); +signal CTRL_REG : bit_vector(7 downto 0); +signal PORT_A : bit_vector(7 downto 0); +signal PORT_B : bit_vector(7 downto 0); +begin + P_WAVSTRB: process(RESETn, SYS_CLK) + variable LOCK : boolean; + variable TMP : bit; + begin + if RESETn = '0' then + LOCK := false; + TMP := '0'; + elsif SYS_CLK = '1' and SYS_CLK' event then + if WAV_CLK = '1' and LOCK = false then + LOCK := true; + TMP := not TMP; -- Divider by 2. + case SELn is + when '1' => WAV_STRB <= '1'; + when others => WAV_STRB <= TMP; + end case; + elsif WAV_CLK = '0' then + LOCK := false; + WAV_STRB <= '0'; + else + WAV_STRB <= '0'; + end if; + end if; + end process P_WAVSTRB; + + with BDIR & BC2 & BC1 select + BUSCYCLE <= INACTIVE when "000" | "010" | "101", + ADDRESS when "001" | "100" | "111", + R_READ when "011", + R_WRITE when "110"; + + ADDRESSLATCH: process(RESETn, SYS_CLK) + -- This process is responsible to store the desired register + -- address. The default (after reset) is channel A fine tone + -- adjustment. + begin + if RESETn = '0' then + ADR_I <= (others => '0'); + elsif SYS_CLK = '1' and SYS_CLK' event then + if BUSCYCLE = ADDRESS and A9n = '0' and A8 = '1' and DA_IN(7 downto 4) = x"0" then + ADR_I <= To_BitVector(DA_IN(3 downto 0)); + end if; + end if; + end process ADDRESSLATCH; + + P_CTRL_REG: process(RESETn, SYS_CLK) + -- THIS is the Control register for the mixer and for the I/O ports. + begin + if RESETn = '0' then + CTRL_REG <= x"00"; + elsif SYS_CLK = '1' and SYS_CLK' event then + if BUSCYCLE = R_WRITE and ADR_I = x"7" then + CTRL_REG <= To_BitVector(DA_IN); + end if; + end if; + end process P_CTRL_REG; + + DIG_PORTS: process(RESETn, SYS_CLK) + begin + if RESETn = '0' then + PORT_A <= x"00"; + PORT_B <= x"00"; + elsif SYS_CLK = '1' and SYS_CLK' event then + if BUSCYCLE = R_WRITE and ADR_I = x"E" then + PORT_A <= To_BitVector(DA_IN); + elsif BUSCYCLE = R_WRITE and ADR_I = x"F" then + PORT_B <= To_BitVector(DA_IN); + end if; + end if; + end process DIG_PORTS; + -- Set port direction to input or to output: + IO_A_EN <= '1' when CTRL_REG(6) = '1' else '0'; + IO_B_EN <= '1' when CTRL_REG(7) = '1' else '0'; + IO_A_OUT <= PORT_A; + IO_B_OUT <= PORT_B; + + I_PSG_WAVE: WF2149IP_WAVE + port map( + RESETn => RESETn, + SYS_CLK => SYS_CLK, + + WAV_STRB => WAV_STRB, + + ADR => ADR_I, + DATA_IN => DA_IN, + DATA_OUT => DATA_OUT_I, + DATA_EN => DATA_EN_I, + + BUSCYCLE => BUSCYCLE, + CTRL_REG => CTRL_REG(5 downto 0), + + OUT_A => OUT_A, + OUT_B => OUT_B, + OUT_C => OUT_C + ); + + -- Read the ports and registers: + DA_EN <= '1' when DATA_EN_I = '1' else + '1' when BUSCYCLE = R_READ and ADR_I = x"7" else + '1' when BUSCYCLE = R_READ and ADR_I = x"E" else + '1' when BUSCYCLE = R_READ and ADR_I = x"F" else '0'; + + DA_OUT <= DATA_OUT_I when DATA_EN_I = '1' else -- WAV stuff. + To_StdLogicVector(IO_A_IN) when BUSCYCLE = R_READ and ADR_I = x"E" else + To_StdLogicVector(IO_B_IN) when BUSCYCLE = R_READ and ADR_I = x"F" else + To_StdLogicVector(CTRL_REG) when BUSCYCLE = R_READ and ADR_I = x"7" else (others => '0'); + +end STRUCTURE; diff --git a/vhdl/rtl/vhdl/WF_SND2149_IP/wf2149ip_wave.vhd b/vhdl/rtl/vhdl/WF_SND2149_IP/wf2149ip_wave.vhd new file mode 100644 index 0000000..e5bd62a --- /dev/null +++ b/vhdl/rtl/vhdl/WF_SND2149_IP/wf2149ip_wave.vhd @@ -0,0 +1,534 @@ +---------------------------------------------------------------------- +---- ---- +---- YM2149 compatible sound generator. ---- +---- ---- +---- This file is part of the SUSKA ATARI clone project. ---- +---- http://www.experiment-s.de ---- +---- ---- +---- Description: ---- +---- Model of the ST or STE's YM2149 sound generator. ---- +---- ---- +---- Waveform generator. ---- +---- ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2006 - 2011 Wolfgang Foerster ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.gnu.org/licenses/lgpl.html ---- +---- ---- +---------------------------------------------------------------------- +-- +-- Revision History +-- +-- Revision 2K6A 2006/06/03 WF +-- Initial Release. +-- Revision 2K6B 2006/11/07 WF +-- Modified Source to compile with the Xilinx ISE. +-- Revision 2K8A 2008/07/14 WF +-- Minor changes. +-- Revision 2K9A 2009/06/20 WF +-- NOISE_OUT has now synchronous reset to meet preset requirement. +-- Fixed a bug in the envelope generator. Thanks to Lyndon Amsdon finding it. +-- Correction of the schematic given in the end of this file. +-- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; +use work.wf2149ip_pkg.all; + +entity WF2149IP_WAVE is + port( + RESETn : in bit; + SYS_CLK : in bit; + + WAV_STRB : in bit; + + ADR : in bit_vector(3 downto 0); + DATA_IN : in std_logic_vector(7 downto 0); + DATA_OUT : out std_logic_vector(7 downto 0); + DATA_EN : out bit; + + BUSCYCLE : in BUSCYCLES; + CTRL_REG : in bit_vector(5 downto 0); + + OUT_A : out bit; + OUT_B : out bit; + OUT_C : out bit + ); +end entity WF2149IP_WAVE; + +architecture BEHAVIOR of WF2149IP_WAVE is +signal FREQUENCY_A : std_logic_vector(11 downto 0); +signal FREQUENCY_B : std_logic_vector(11 downto 0); +signal FREQUENCY_C : std_logic_vector(11 downto 0); +signal NOISE_FREQ : std_logic_vector(4 downto 0); +signal LEVEL_A : std_logic_vector(4 downto 0); +signal LEVEL_B : std_logic_vector(4 downto 0); +signal LEVEL_C : std_logic_vector(4 downto 0); +signal ENV_FREQ : std_logic_vector(15 downto 0); +signal ENV_SHAPE : std_logic_vector(3 downto 0); +signal ENV_RESET : boolean; +signal ENV_STRB : bit; +signal OSC_A_OUT : bit; +signal OSC_B_OUT : bit; +signal OSC_C_OUT : bit; +signal NOISE_OUT : bit; +signal AUDIO_A : bit; +signal AUDIO_B : bit; +signal AUDIO_C : bit; +signal VOL_ENV : std_logic_vector(4 downto 0); +signal AMPLITUDE_A : std_logic_vector(4 downto 0); +signal AMPLITUDE_B : std_logic_vector(4 downto 0); +signal AMPLITUDE_C : std_logic_vector(4 downto 0); +signal VOLUME_A : std_logic_vector(7 downto 0); +signal VOLUME_B : std_logic_vector(7 downto 0); +signal VOLUME_C : std_logic_vector(7 downto 0); +signal PWM_RAMP : std_logic_vector(7 downto 0); +begin + REGISTERS: process(RESETn, SYS_CLK) + -- This process is responsible for initialisation + -- and write access to the configuration registers. + begin + if RESETn = '0' then + FREQUENCY_A <= x"000"; + FREQUENCY_B <= x"000"; + FREQUENCY_C <= x"000"; + NOISE_FREQ <= "00000"; + LEVEL_A <= "00000"; + LEVEL_B <= "00000"; + LEVEL_C <= "00000"; + ENV_FREQ <= (others => '0'); + ENV_SHAPE <= "0000"; + elsif SYS_CLK = '1' and SYS_CLK' event then + ENV_RESET <= false; -- Initialize signal. + if BUSCYCLE = R_WRITE then + case ADR is + when x"0" => FREQUENCY_A(7 downto 0) <= DATA_IN; + when x"1" => FREQUENCY_A(11 downto 8) <= DATA_IN(3 downto 0); + when x"2" => FREQUENCY_B(7 downto 0) <= DATA_IN; + when x"3" => FREQUENCY_B(11 downto 8) <= DATA_IN(3 downto 0); + when x"4" => FREQUENCY_C(7 downto 0) <= DATA_IN; + when x"5" => FREQUENCY_C(11 downto 8) <= DATA_IN(3 downto 0); + when x"6" => NOISE_FREQ <= DATA_IN(4 downto 0); + when x"8" => LEVEL_A <= DATA_IN(4 downto 0); + when x"9" => LEVEL_B <= DATA_IN(4 downto 0); + when x"A" => LEVEL_C <= DATA_IN(4 downto 0); + when x"B" => ENV_FREQ(7 downto 0) <= DATA_IN; + when x"C" => ENV_FREQ(15 downto 8) <= DATA_IN; + ENV_RESET <= true; -- Initialize the envelope generator. + when x"D" => ENV_SHAPE <= DATA_IN(3 downto 0); + when others => null; + end case; + end if; + end if; + end process REGISTERS; + + -- Read back the configuration registers: + DATA_OUT <= FREQUENCY_A(7 downto 0) when BUSCYCLE = R_READ and ADR = x"0" else + "0000" & FREQUENCY_A(11 downto 8) when BUSCYCLE = R_READ and ADR = x"1" else + FREQUENCY_B(7 downto 0) when BUSCYCLE = R_READ and ADR = x"2" else + "0000" & FREQUENCY_B(11 downto 8) when BUSCYCLE = R_READ and ADR = x"3" else + FREQUENCY_C(7 downto 0) when BUSCYCLE = R_READ and ADR = x"4" else + "0000" & FREQUENCY_C(11 downto 8) when BUSCYCLE = R_READ and ADR = x"5" else + "000" & NOISE_FREQ when BUSCYCLE = R_READ and ADR = x"6" else + "000" & LEVEL_A when BUSCYCLE = R_READ and ADR = x"8" else + "000" & LEVEL_B when BUSCYCLE = R_READ and ADR = x"9" else + "000" & LEVEL_C when BUSCYCLE = R_READ and ADR = x"A" else + ENV_FREQ(7 downto 0) when BUSCYCLE = R_READ and ADR = x"B" else + ENV_FREQ(15 downto 8) when BUSCYCLE = R_READ and ADR = x"C" else + x"0" & ENV_SHAPE when BUSCYCLE = R_READ and ADR = x"D" else (others => '0'); + DATA_EN <= '1' when BUSCYCLE = R_READ and ADR >= x"0" and ADR <= x"6" else + '1' when BUSCYCLE = R_READ and ADR >= x"8" and ADR <= x"D" else '0'; + + MUSICGENERATOR: process(RESETn, SYS_CLK) + variable CLK_DIV : std_logic_vector(2 downto 0); + variable CNT_CH_A : std_logic_vector(11 downto 0); + variable CNT_CH_B : std_logic_vector(11 downto 0); + variable CNT_CH_C : std_logic_vector(11 downto 0); + begin + if RESETn = '0' then + CLK_DIV := "000"; + CNT_CH_A := (others => '0'); + CNT_CH_B := (others => '0'); + CNT_CH_C := (others => '0'); + OSC_A_OUT <= '0'; + OSC_B_OUT <= '0'; + OSC_C_OUT <= '0'; + elsif SYS_CLK = '1' and SYS_CLK' event then + if WAV_STRB = '1' then + -- Divider by 8 for the oscillators brings in connection + -- with the toggle flip flops CH_x_OUT the required divider + -- ratio of 16. + CLK_DIV := CLK_DIV + '1'; + + if CLK_DIV = "000" then + if FREQUENCY_A = x"000" then + CNT_CH_A := (others => '0'); + OSC_A_OUT <= '0'; + elsif CNT_CH_A = x"000" then + CNT_CH_A := FREQUENCY_A - '1' ; + OSC_A_OUT <= not OSC_A_OUT; + else + CNT_CH_A := CNT_CH_A - '1'; + end if; + + if FREQUENCY_B = x"000" then + CNT_CH_B := (others => '0'); + OSC_B_OUT <= '0'; + elsif CNT_CH_B = x"000" then + CNT_CH_B := FREQUENCY_B - '1' ; + OSC_B_OUT <= not OSC_B_OUT; + else + CNT_CH_B := CNT_CH_B - '1'; + end if; + + if FREQUENCY_C = x"000" then + CNT_CH_C := (others => '0'); + OSC_C_OUT <= '0'; + elsif CNT_CH_C = x"000" then + CNT_CH_C := FREQUENCY_C - '1' ; + OSC_C_OUT <= not OSC_C_OUT; + else + CNT_CH_C := CNT_CH_C - '1'; + end if; + end if; + end if; + end if; + end process MUSICGENERATOR; + + NOISEGENERATOR: process + -- The noise shift polynomial is taken from a template of Kazuhiro TSUJIKAWA's + -- (ESE Artists' factory) approach for a 2149 equivalent. But the implementation + -- is done in another way. + -- LFSR (linear feedback shift register polynomial: f(x) = x^17 + x^14 + 1. + variable CLK_DIV : std_logic_vector(3 downto 0); + variable CNT_NOISE : std_logic_vector(4 downto 0); + variable N_SHFT : std_logic_vector(16 downto 0); + begin + wait until SYS_CLK = '1' and SYS_CLK' event; + if RESETn = '0' then + CLK_DIV := x"0"; + CNT_NOISE := (others => '1'); -- Preset the polynomial shift register. + NOISE_OUT <= '1'; + elsif WAV_STRB = '1' then + -- Divider by 16 for the noise generator. + CLK_DIV := CLK_DIV + '1'; + if CLK_DIV = x"0" then + -- Noise frequency counter. + if NOISE_FREQ = "00000" then + CNT_NOISE := (others => '0'); + elsif CNT_NOISE = "00000" then + CNT_NOISE := NOISE_FREQ - '1' ; + N_SHFT := N_SHFT(15 downto 14) & not(N_SHFT(16) xor N_SHFT(13)) & + N_SHFT(12 downto 0) & not N_SHFT(16); + else + CNT_NOISE := CNT_NOISE - '1'; + end if; + end if; + end if; + NOISE_OUT <= To_Bit(N_SHFT(16)); + end process NOISEGENERATOR; + + ENVELOPE_PERIOD: process(RESETn, SYS_CLK) + -- The envelope period is controlled by the Envelope Frequency and the divider ratio which is + -- 256/32 = 8. For further information see the original data sheet. + variable ENV_CLK : std_logic_vector(18 downto 0); + variable LOCK : boolean; + begin + if RESETn = '0' then + ENV_STRB <= '0'; + ENV_CLK := (others => '0'); + LOCK := false; + elsif SYS_CLK = '1' and SYS_CLK' event then + if WAV_STRB = '1' and LOCK = false then + LOCK := true; + if ENV_FREQ = x"0000" then + ENV_STRB <= '0'; + elsif ENV_CLK = x"0000" & "000" then + ENV_CLK := (ENV_FREQ & "111") - '1' ; + ENV_STRB <= '1'; + else + ENV_CLK := ENV_CLK - '1'; + ENV_STRB <= '0'; + end if; + elsif WAV_STRB = '0' then + LOCK := false; + ENV_STRB <= '0'; + else + ENV_STRB <= '0'; + end if; + end if; + end process ENVELOPE_PERIOD; + + ENVELOPE: process(RESETn, SYS_CLK) + -- Envelope shapes: + -- case ENV_SHAPE: + -- + -- 0 0 x x \___ + -- + -- 0 1 x x /|___ + -- + -- 1 0 0 0 _|\|\|\|\| + -- + -- 1 0 0 1 \___ + -- + -- 1 0 1 0 \/\/ + -- ___ + -- 1 0 1 1 \| + -- + -- 1 1 0 0 /|/|/|/| + -- ___ + -- 1 1 0 1 / + -- + -- 1 1 1 0 /\/\ + -- + -- 1 1 1 1 /|___ + -- + variable ENV_STOP : boolean; + variable ENV_UP_DNn : bit; + begin + if RESETn = '0' then + VOL_ENV <= (others => '0'); + ENV_UP_DNn := '0'; + ENV_STOP := false; + elsif SYS_CLK = '1' and SYS_CLK' event then + if ENV_RESET = true then + ENV_STOP := false; + case ENV_SHAPE is + when "1011" | "1010" | "1001" | "1000" | "0011" | "0010" | "0001" | "0000" => + VOL_ENV <= "11111"; -- Start on top. + ENV_UP_DNn := '0'; + when others => + VOL_ENV <= "00000"; -- Start at bottom. + ENV_UP_DNn := '1'; + end case; + elsif ENV_STRB = '1' then + case ENV_SHAPE is + when "1001" | "0011" | "0010" | "0001" | "0000" => + if VOL_ENV > "00000" then + VOL_ENV <= VOL_ENV - '1'; + end if; + when "1111" | "0111" | "0110" | "0101" | "0100" => + if VOL_ENV < "11111" and ENV_STOP = false then + VOL_ENV <= VOL_ENV + '1'; + else + VOL_ENV <= "00000"; + ENV_STOP := true; + end if; + when "1000" => + VOL_ENV <= VOL_ENV - '1'; + when "1110" | "1010" => + if ENV_UP_DNn = '0' then + VOL_ENV <= VOL_ENV - '1'; + else + VOL_ENV <= VOL_ENV + '1'; + end if; + -- + if VOL_ENV = "00001" then + ENV_UP_DNn := '1'; + elsif VOL_ENV = "11110" then + ENV_UP_DNn := '0'; + end if; + when "1011" => + if VOL_ENV > "00000" and ENV_STOP = false then + VOL_ENV <= VOL_ENV - '1'; + else + VOL_ENV <= "11111"; + ENV_STOP := true; + end if; + when "1100" => + VOL_ENV <= VOL_ENV + '1'; + when "1101" => + if VOL_ENV < "11111" then + VOL_ENV <= VOL_ENV + '1'; + end if; + when others => null; -- Covers U, X, Z, W, H, L, -. + end case; + end if; + end if; + end process ENVELOPE; + + --MIXER: + -- The mixer controls are dependant on the mixer settings and the output of the + -- audio data for all three channels. The noise generator and the square wave + -- generators A, B and C are mixed together by a simple boolean OR. + AUDIO_A <= (OSC_A_OUT and not CTRL_REG(0)) or (NOISE_OUT and not CTRL_REG(3)); + AUDIO_B <= (OSC_B_OUT and not CTRL_REG(1)) or (NOISE_OUT and not CTRL_REG(4)); + AUDIO_C <= (OSC_C_OUT and not CTRL_REG(2)) or (NOISE_OUT and not CTRL_REG(5)); + + --LEVEL (e.g. volume control): + -- The linear amplitude for the DA converters of channel A, B or C are fixed + -- (LEVEL(3 downto 0)) or delivered by the envelope generator. + -- The following behavior is taken from the 2149 IP core of Mike J (www.fpgaarcade.com): + -- "make sure level 31 (env) = level 15 (tone)" + -- Thus there is a resulting & '1' modeling if LEVEL amplitudes are selected. + AMPLITUDE_A <= LEVEL_A(3 downto 0) & '1' when LEVEL_A(4) = '0' and AUDIO_A = '1' else + VOL_ENV when LEVEL_A(4) = '1' and AUDIO_A = '1' else "00000"; + AMPLITUDE_B <= LEVEL_B(3 downto 0) & '1' when LEVEL_B(4) = '0' and AUDIO_B = '1' else + VOL_ENV when LEVEL_B(4) = '1' and AUDIO_B = '1' else "00000"; + AMPLITUDE_C <= LEVEL_C(3 downto 0) & '1' when LEVEL_C(4) = '0' and AUDIO_C = '1' else + VOL_ENV when LEVEL_C(4) = '1' and AUDIO_C = '1' else "00000"; + + -- The values for the logarithmic DA converter volume controls are taken from the linear + -- mixer of Mike J's 2149 IP core (www.fpgaarcade.com). + with AMPLITUDE_A select + VOLUME_A <= x"FF" when "11111", + x"D9" when "11110", + x"BA" when "11101", + x"9F" when "11100", + x"88" when "11011", + x"74" when "11010", + x"63" when "11001", + x"54" when "11000", + x"48" when "10111", + x"3D" when "10110", + x"34" when "10101", + x"2C" when "10100", + x"25" when "10011", + x"1F" when "10010", + x"1A" when "10001", + x"16" when "10000", + x"13" when "01111", + x"10" when "01110", + x"0D" when "01101", + x"0B" when "01100", + x"09" when "01011", + x"08" when "01010", + x"07" when "01001", + x"06" when "01000", + x"05" when "00111", + x"04" when "00110", + x"03" when "00101", + x"03" when "00100", + x"02" when "00011", + x"02" when "00010", + x"01" when "00001", + x"00" when others; -- Also covers U, X, Z, W, H, L, -. + + with AMPLITUDE_B select + VOLUME_B <= x"FF" when "11111", + x"D9" when "11110", + x"BA" when "11101", + x"9F" when "11100", + x"88" when "11011", + x"74" when "11010", + x"63" when "11001", + x"54" when "11000", + x"48" when "10111", + x"3D" when "10110", + x"34" when "10101", + x"2C" when "10100", + x"25" when "10011", + x"1F" when "10010", + x"1A" when "10001", + x"16" when "10000", + x"13" when "01111", + x"10" when "01110", + x"0D" when "01101", + x"0B" when "01100", + x"09" when "01011", + x"08" when "01010", + x"07" when "01001", + x"06" when "01000", + x"05" when "00111", + x"04" when "00110", + x"03" when "00101", + x"03" when "00100", + x"02" when "00011", + x"02" when "00010", + x"01" when "00001", + x"00" when others; -- Also covers U, X, Z, W, H, L, -. + + with AMPLITUDE_C select + VOLUME_C <= x"FF" when "11111", + x"D9" when "11110", + x"BA" when "11101", + x"9F" when "11100", + x"88" when "11011", + x"74" when "11010", + x"63" when "11001", + x"54" when "11000", + x"48" when "10111", + x"3D" when "10110", + x"34" when "10101", + x"2C" when "10100", + x"25" when "10011", + x"1F" when "10010", + x"1A" when "10001", + x"16" when "10000", + x"13" when "01111", + x"10" when "01110", + x"0D" when "01101", + x"0B" when "01100", + x"09" when "01011", + x"08" when "01010", + x"07" when "01001", + x"06" when "01000", + x"05" when "00111", + x"04" when "00110", + x"03" when "00101", + x"03" when "00100", + x"02" when "00011", + x"02" when "00010", + x"01" when "00001", + x"00" when others; -- Also covers U, X, Z, W, H, L, -. + + DA_CONVERSION: process + -- The DA conversion for the three analog outputs is originally performed by a built in DA converter. + -- For this is not possible in current FPGA designs, the converter is replaced by three PWM units + -- operating at a frequency which is 100 times higher than the highest noise or music frequency which + -- is 2MHz/16 = 125kHz. So the PWM frequency requires about 12.5MHz or more. The design is done for + -- a PWM frequency of 16MHz). + begin + wait until SYS_CLK = '1' and SYS_CLK' event; + PWM_RAMP <= PWM_RAMP + '1'; + end process DA_CONVERSION; + OUT_A <= '0' when VOLUME_A = x"00" else '1' when PWM_RAMP < VOLUME_A else '0'; + OUT_B <= '0' when VOLUME_B = x"00" else '1' when PWM_RAMP < VOLUME_B else '0'; + OUT_C <= '0' when VOLUME_C = x"00" else '1' when PWM_RAMP < VOLUME_C else '0'; + -- + -- To obtain proper analog output it is necessary to install analog RC filters to the pulse width + -- outputs. An example is given for the direct wiring of the three analog outputs and for a system + -- clock frequency of 16MHz. The output circuitry looks in this case as follows: + -- + -- OUT_A ---------|1kOhm|-----------| |\ e.g. LM741 + -- |----------------------|+\ || + -- OUT_B ---------|1kOhm|-----------| | OP------||--- Analog Signal + -- | |-----|-/ | || + -- OUT_C ---------|1kOhm|-----------| | |/ | 4u7 + -- | |__________| + -- | + -- --- 10nF. + -- --- + -- | + -- | + -- --- + -- WF. +end architecture BEHAVIOR; diff --git a/vhdl/rtl/vhdl/WF_UART6850_IP/wf6850ip_ctrl_status.vhd b/vhdl/rtl/vhdl/WF_UART6850_IP/wf6850ip_ctrl_status.vhd new file mode 100644 index 0000000..5ce2f2e --- /dev/null +++ b/vhdl/rtl/vhdl/WF_UART6850_IP/wf6850ip_ctrl_status.vhd @@ -0,0 +1,202 @@ +---------------------------------------------------------------------- +---- ---- +---- 6850 compatible IP Core ---- +---- ---- +---- This file is part of the SUSKA ATARI clone project. ---- +---- http://www.experiment-s.de ---- +---- ---- +---- Description: ---- +---- UART 6850 compatible IP core ---- +---- ---- +---- Control unit and status logic. ---- +---- ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2006 - 2008 Wolfgang Foerster ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.gnu.org/licenses/lgpl.html ---- +---- ---- +---------------------------------------------------------------------- +-- +-- Revision History +-- +-- Revision 2K6A 2006/06/03 WF +-- Initial Release. +-- Revision 2K6B 2006/11/07 WF +-- Modified Source to compile with the Xilinx ISE. +-- Revision 2K8A 2008/07/14 WF +-- Minor changes. +-- Revision 2K9A 2009/06/20 WF +-- CTRL_REG has now synchronous reset to meet preset requirements. +-- Process P_DCD has now synchronous reset to meet preset requirements. +-- IRQ_In has now synchronous reset to meet preset requirement. +-- Revision 2K9B 2009/12/24 WF +-- Fixed the interrupt logic. +-- Introduced a minor RTSn correction. +-- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + +entity WF6850IP_CTRL_STATUS is + port ( + CLK : in std_logic; + RESETn : in bit; + + CS : in bit_vector(2 downto 0); -- Active if "011". + E : in bit; + RWn : in bit; + RS : in bit; + + DATA_IN : in bit_vector(7 downto 0); + DATA_OUT : out bit_vector(7 downto 0); + DATA_EN : out bit; + + -- Status register stuff: + RDRF : in bit; -- Receive data register full. + TDRE : in bit; -- Transmit data register empty. + DCDn : in bit; -- Data carrier detect. + CTSn : in bit; -- Clear to send. + FE : in bit; -- Framing error. + OVR : in bit; -- Overrun error. + PE : in bit; -- Parity error. + + -- Control register stuff: + MCLR : buffer bit; -- Master clear (high active). + RTSn : out bit; -- Request to send. + CDS : out bit_vector(1 downto 0); -- Clock control. + WS : out bit_vector(2 downto 0); -- Word select. + TC : out bit_vector(1 downto 0); -- Transmit control. + IRQn : buffer bit -- Interrupt request. + ); +end entity WF6850IP_CTRL_STATUS; + +architecture BEHAVIOR of WF6850IP_CTRL_STATUS is +signal CTRL_REG : bit_vector(7 downto 0); +signal STATUS_REG : bit_vector(7 downto 0); +signal RIE : bit; +signal CTS_In : bit; +signal DCD_In : bit; +signal DCD_FLAGn : bit; +begin + CTS_In <= CTSn; + DCD_In <= DCDn; -- immer 0 + + STATUS_REG(7) <= not IRQn; + STATUS_REG(6) <= PE; + STATUS_REG(5) <= OVR; + STATUS_REG(4) <= FE; + STATUS_REG(3) <= CTS_In; -- Reflexion of the input pin. + STATUS_REG(2) <= DCD_FLAGn; + STATUS_REG(1) <= TDRE and not CTS_In; -- No TDRE for CTSn = '1'. + STATUS_REG(0) <= RDRF and not DCD_In; -- DCDn = '1' indicates empty. + + DATA_OUT <= STATUS_REG when CS = "011" and RWn = '1' and RS = '0' else (others => '0'); + DATA_EN <= '1' when CS = "011" and RWn = '1' and RS = '0' else '0'; + + MCLR <= '1' when CTRL_REG(1 downto 0) = "11" else '0'; + RTSn <= '0' when CTRL_REG(6 downto 5) /= "10" else '1'; + + CDS <= CTRL_REG(1 downto 0); + WS <= CTRL_REG(4 downto 2); + TC <= CTRL_REG(6 downto 5); + RIE <= CTRL_REG(7); + + P_IRQ: process(CLK) + begin + if rising_edge(CLK) then + if RESETn = '0' or MCLR = '1' then + IRQn <= '1'; + else + -- Transmitter interrupt: + if TDRE = '1' and CTRL_REG(6 downto 5) = "01" then + IRQn <= '0'; + end if; + -- Receiver interrupts: + if RDRF = '1' and RIE = '1' then + IRQn <= '0'; + end if; + -- Overrun + if OVR = '1' and RIE = '1' then + IRQn <= '0'; + end if; + -- The reset of the IRQ status flag: + -- Clear by writing to the transmit data register. + -- Clear by reading the receive data register. + if CS = "011" and RS = '1' then + IRQn <= '1'; + end if; + end if; + end if; + end process P_IRQ; + + CONTROL: process(CLK) + begin + if rising_edge(CLK) then + if RESETn = '0' then + CTRL_REG <= "01000000"; + elsif CS = "011" and RWn = '0' and RS = '0' then + CTRL_REG <= DATA_IN; + end if; + end if; + end process CONTROL; + + P_DCD: process(CLK) + -- This process is some kind of tricky. Refer to the MC6850 data + -- sheet for more information. + variable READ_LOCK : boolean; + variable DCD_RELEASE : boolean; + begin + if rising_edge(CLK) then + if RESETn = '0' then + DCD_FLAGn <= '0'; -- This interrupt source must initialise low. + READ_LOCK := true; + DCD_RELEASE := false; + elsif MCLR = '1' then + DCD_FLAGn <= DCD_In; + READ_LOCK := true; + elsif DCD_In = '1' then + DCD_FLAGn <= '1'; + elsif CS = "011" and RWn = '1' and RS = '0' then + READ_LOCK := false; -- Un-READ_LOCK if receiver data register is read. + elsif CS = "011" and RWn = '1' and RS = '1' and READ_LOCK = false then + -- Clear if receiver status register read access. + -- After data register has ben read and READ_LOCK again. + DCD_RELEASE := true; + READ_LOCK := true; + DCD_FLAGn <= DCD_In; + elsif DCD_In = '0' and DCD_RELEASE = true then + DCD_FLAGn <= '0'; + DCD_RELEASE := false; + end if; + end if; + end process P_DCD; +end architecture BEHAVIOR; + diff --git a/vhdl/rtl/vhdl/WF_UART6850_IP/wf6850ip_receive.vhd b/vhdl/rtl/vhdl/WF_UART6850_IP/wf6850ip_receive.vhd new file mode 100644 index 0000000..91746ad --- /dev/null +++ b/vhdl/rtl/vhdl/WF_UART6850_IP/wf6850ip_receive.vhd @@ -0,0 +1,417 @@ +---------------------------------------------------------------------- +---- ---- +---- 6850 compatible IP Core ---- +---- ---- +---- This file is part of the SUSKA ATARI clone project. ---- +---- http://www.experiment-s.de ---- +---- ---- +---- Description: ---- +---- UART 6850 compatible IP core ---- +---- ---- +---- 6850's receiver unit. ---- +---- ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2006 - 2011 Wolfgang Foerster ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.gnu.org/licenses/lgpl.html ---- +---- ---- +---------------------------------------------------------------------- +-- +-- Revision History +-- +-- Revision 2K6A 2006/06/03 WF +-- Initial Release. +-- Revision 2K6B 2006/11/07 WF +-- Modified Source to compile with the Xilinx ISE. +-- Revision 2K8A 2008/07/14 WF +-- Minor changes. +-- Revision 2K12B 20121224 WF +-- Removed a latch driving PE. +-- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + +entity WF6850IP_RECEIVE is + port ( + CLK : in bit; + RESETn : in bit; + MCLR : in bit; + + CS : in bit_vector(2 downto 0); + E : in bit; + RWn : in bit; + RS : in bit; + + DATA_OUT : out bit_vector(7 downto 0); + DATA_EN : out bit; + + WS : in bit_vector(2 downto 0); + CDS : in bit_vector(1 downto 0); + + RXCLK : in bit; + RXDATA : in bit; + + RDRF : buffer bit; + OVR : out bit; + PE : out bit; + FE : out bit + ); +end entity WF6850IP_RECEIVE; + +architecture BEHAVIOR of WF6850IP_RECEIVE is +type RCV_STATES is (IDLE, WAIT_START, SAMPLE, PARITY, STOP1, STOP2, SYNC); +signal RCV_STATE, RCV_NEXT_STATE : RCV_STATES; +signal RXDATA_I : bit; +signal RXDATA_S : bit; +signal DATA_REG : bit_vector(7 downto 0); +signal SHIFT_REG : bit_vector(7 downto 0); +signal CLK_STRB : bit; +signal BITCNT : std_logic_vector(2 downto 0); +begin + P_SAMPLE: process + -- This filter provides a synchronisation to the system + -- clock, even for random baud rates of the received data + -- stream. + variable FLT_TMP : integer range 0 to 2; + begin + wait until CLK = '1' and CLK' event; + -- + RXDATA_I <= RXDATA; + -- + if RXDATA_I = '1' and FLT_TMP < 2 then + FLT_TMP := FLT_TMP + 1; + elsif RXDATA_I = '1' then + RXDATA_S <= '1'; + elsif RXDATA_I = '0' and FLT_TMP > 0 then + FLT_TMP := FLT_TMP - 1; + elsif RXDATA_I = '0' then + RXDATA_S <= '0'; + end if; + end process P_SAMPLE; + + CLKDIV: process + variable CLK_LOCK : boolean; + variable STRB_LOCK : boolean; + variable CLK_DIVCNT : std_logic_vector(6 downto 0); + begin + wait until CLK = '1' and CLK' event; + if CDS = "00" then -- Divider off. + if RXCLK = '1' and STRB_LOCK = false then + CLK_STRB <= '1'; + STRB_LOCK := true; + elsif RXCLK = '0' then + CLK_STRB <= '0'; + STRB_LOCK := false; + else + CLK_STRB <= '0'; + end if; + elsif RCV_STATE = IDLE then + -- Preset the CLKDIV with the start delays. + if CDS = "01" then + CLK_DIVCNT := "0001000"; -- Half of div by 16 mode. + elsif CDS = "10" then + CLK_DIVCNT := "0100000"; -- Half of div by 64 mode. + end if; + CLK_STRB <= '0'; + else + if CLK_DIVCNT > "0000000" and RXCLK = '1' and CLK_LOCK = false then + CLK_DIVCNT := CLK_DIVCNT - '1'; + CLK_STRB <= '0'; + CLK_LOCK := true; + elsif CDS = "01" and CLK_DIVCNT = "0000000" then + CLK_DIVCNT := "0010000"; -- Div by 16 mode. + -- + if STRB_LOCK = false then + STRB_LOCK := true; + CLK_STRB <= '1'; + else + CLK_STRB <= '0'; + end if; + elsif CDS = "10" and CLK_DIVCNT = "0000000" then + CLK_DIVCNT := "1000000"; -- Div by 64 mode. + if STRB_LOCK = false then + STRB_LOCK := true; + CLK_STRB <= '1'; + else + CLK_STRB <= '0'; + end if; + elsif RXCLK = '0' then + CLK_LOCK := false; + STRB_LOCK := false; + CLK_STRB <= '0'; + else + CLK_STRB <= '0'; + end if; + end if; + end process CLKDIV; + + DATAREG: process(RESETn, CLK) + begin + if RESETn = '0' then + DATA_REG <= x"00"; + elsif CLK = '1' and CLK' event then + if MCLR = '1' then + DATA_REG <= x"00"; + elsif RCV_STATE = SYNC and WS(2) = '0' and RDRF = '0' then -- 7 bit data. + -- Transfer from shift- to data register only if + -- data register is empty (RDRF = '0'). + DATA_REG <= '0' & SHIFT_REG(7 downto 1); + elsif RCV_STATE = SYNC and WS(2) = '1' and RDRF = '0' then -- 8 bit data. + -- Transfer from shift- to data register only if + -- data register is empty (RDRF = '0'). + DATA_REG <= SHIFT_REG; + end if; + end if; + end process DATAREG; + DATA_OUT <= DATA_REG when CS = "011" and RWn = '1' and RS = '1' and E = '1' else (others => '0'); + DATA_EN <= '1' when CS = "011" and RWn = '1' and RS = '1' and E = '1' else '0'; + + SHIFTREG: process(RESETn, CLK) + begin + if RESETn = '0' then + SHIFT_REG <= x"00"; + elsif CLK = '1' and CLK' event then + if MCLR = '1' then + SHIFT_REG <= x"00"; + elsif RCV_STATE = SAMPLE and CLK_STRB = '1' then + SHIFT_REG <= RXDATA_S & SHIFT_REG(7 downto 1); -- Shift right. + end if; + end if; + end process SHIFTREG; + + P_BITCNT: process + begin + wait until CLK = '1' and CLK' event; + if RCV_STATE = SAMPLE and CLK_STRB = '1' then + BITCNT <= BITCNT + '1'; + elsif RCV_STATE /= SAMPLE then + BITCNT <= (others => '0'); + end if; + end process P_BITCNT; + + FRAME_ERR: process(RESETn, CLK) + -- This module detects a framing error + -- during stop bit 1 and stop bit 2. + variable FE_I: bit; + begin + if RESETn = '0' then + FE_I := '0'; + FE <= '0'; + elsif CLK = '1' and CLK' event then + if MCLR = '1' then + FE_I := '0'; + FE <= '0'; + elsif CLK_STRB = '1' then + if RCV_STATE = STOP1 and RXDATA_S = '0' then + FE_I := '1'; + elsif RCV_STATE = STOP2 and RXDATA_S = '0' then + FE_I := '1'; + elsif RCV_STATE = STOP1 or RCV_STATE = STOP2 then + FE_I := '0'; -- Error resets when correct data appears. + end if; + end if; + if RCV_STATE = SYNC then + FE <= FE_I; -- Update the FE every SYNC time. + end if; + end if; + end process FRAME_ERR; + + OVERRUN: process(RESETn, CLK) + variable OVR_I : bit; + variable FIRST_READ : boolean; + begin + if RESETn = '0' then + OVR_I := '0'; + OVR <= '0'; + FIRST_READ := false; + elsif CLK = '1' and CLK' event then + if MCLR = '1' then + OVR_I := '0'; + OVR <= '0'; + FIRST_READ := false; + elsif CLK_STRB = '1' and RCV_STATE = STOP1 then + -- Overrun appears if RDRF is '1' in this state. + OVR_I := RDRF; + end if; + if CS = "011" and RWn = '1' and RS = '1' and E = '1' and OVR_I = '1' then + -- If an overrun was detected, the concerning flag is + -- set when the valid data word in the receiver data + -- register is read. Thereafter the RDRF flag is reset + -- and the overrun disappears (OVR_I goes low) after + -- a second read (in time) of the receiver data register. + if FIRST_READ = false then + OVR <= '1'; + FIRST_READ := true; + else + OVR <= '0'; + FIRST_READ := false; + end if; + end if; + end if; + end process OVERRUN; + + PARITY_TEST: process(RESETn, CLK) + variable PAR_TMP : bit; + variable PE_I : bit; + begin + if RESETn = '0' then + PE <= '0'; + elsif CLK = '1' and CLK' event then + if MCLR = '1' then + PE <= '0'; + elsif CLK_STRB = '1' then -- Sample parity on clock strobe. + PE_I := '0'; -- Initialise. + if RCV_STATE = PARITY then + for i in 1 to 7 loop + if i = 1 then + PAR_TMP := SHIFT_REG(i-1) xor SHIFT_REG(i); + else + PAR_TMP := PAR_TMP xor SHIFT_REG(i); + end if; + end loop; + if WS = "000" or WS = "010" or WS = "110" then -- Even parity. + PE_I := PAR_TMP xor RXDATA_S; + elsif WS = "001" or WS = "011" or WS = "111" then -- Odd parity. + PE_I := not PAR_TMP xor RXDATA_S; + else -- No parity for WS = "100" and WS = "101". + PE_I := '0'; + end if; + end if; + end if; + -- Transmit the parity flag together with the data + -- In other words: no parity to the status register + -- when RDRF inhibits the data transfer to the + -- receiver data register. + if RCV_STATE = SYNC and RDRF = '0' then + PE <= PE_I; + elsif CS = "011" and RWn = '1' and RS = '1' and E = '1' then + PE <= '0'; -- Clear when reading the data register. + end if; + end if; + end process PARITY_TEST; + + P_RDRF: process(RESETn, CLK) + -- Receive data register full flag. + begin + if RESETn = '0' then + RDRF <= '0'; + elsif CLK = '1' and CLK' event then + if MCLR = '1' then + RDRF <= '0'; + elsif RCV_STATE = SYNC then + RDRF <= '1'; -- Data register is full until now! + elsif CS = "011" and RWn = '1' and RS = '1' and E = '1' then + RDRF <= '0'; -- After reading the data register ... + end if; + end if; + end process P_RDRF; + + RCV_STATEREG: process(RESETn, CLK) + begin + if RESETn = '0' then + RCV_STATE <= IDLE; + elsif CLK = '1' and CLK' event then + if MCLR = '1' then + RCV_STATE <= IDLE; + else + RCV_STATE <= RCV_NEXT_STATE; + end if; + end if; + end process RCV_STATEREG; + + RCV_STATEDEC: process(RCV_STATE, RXDATA_S, CDS, WS, BITCNT, CLK_STRB) + begin + case RCV_STATE is + when IDLE => + if RXDATA_S = '0' and CDS = "00" then + RCV_NEXT_STATE <= SAMPLE; -- Startbit detected in div by 1 mode. + elsif RXDATA_S = '0' and CDS = "01" then + RCV_NEXT_STATE <= WAIT_START; -- Startbit detected in div by 16 mode. + elsif RXDATA_S = '0' and CDS = "10" then + RCV_NEXT_STATE <= WAIT_START; -- Startbit detected in div by 64 mode. + else + RCV_NEXT_STATE <= IDLE; -- No startbit; sleep well :-) + end if; + when WAIT_START => + if CLK_STRB = '1' then + if RXDATA_S = '0' then + RCV_NEXT_STATE <= SAMPLE; -- Start condition in no div by 1 modes. + else + RCV_NEXT_STATE <= IDLE; -- No valid start condition, go back. + end if; + else + RCV_NEXT_STATE <= WAIT_START; -- Stay. + end if; + when SAMPLE => + if CLK_STRB = '1' then + if BITCNT < "110" and WS(2) = '0' then + RCV_NEXT_STATE <= SAMPLE; -- Go on sampling 7 data bits. + elsif BITCNT < "111" and WS(2) = '1' then + RCV_NEXT_STATE <= SAMPLE; -- Go on sampling 8 data bits. + elsif WS = "100" or WS = "101" then + RCV_NEXT_STATE <= STOP1; -- No parity check enabled. + else + RCV_NEXT_STATE <= PARITY; -- Parity enabled. + end if; + else + RCV_NEXT_STATE <= SAMPLE; -- Stay in sample mode. + end if; + when PARITY => + if CLK_STRB = '1' then + RCV_NEXT_STATE <= STOP1; + else + RCV_NEXT_STATE <= PARITY; + end if; + when STOP1 => + if CLK_STRB = '1' then + if RXDATA_S = '0' then + RCV_NEXT_STATE <= SYNC; -- Framing error detected. + elsif WS = "000" or WS = "001" or WS = "100" then + RCV_NEXT_STATE <= STOP2; -- Two stop bits selected. + else + RCV_NEXT_STATE <= SYNC; -- One stop bit selected. + end if; + else + RCV_NEXT_STATE <= STOP1; + end if; + when STOP2 => + if CLK_STRB = '1' then + RCV_NEXT_STATE <= SYNC; + else + RCV_NEXT_STATE <= STOP2; + end if; + when SYNC => + RCV_NEXT_STATE <= IDLE; + end case; + end process RCV_STATEDEC; +end architecture BEHAVIOR; + diff --git a/vhdl/rtl/vhdl/WF_UART6850_IP/wf6850ip_top.vhd b/vhdl/rtl/vhdl/WF_UART6850_IP/wf6850ip_top.vhd new file mode 100644 index 0000000..60a7885 --- /dev/null +++ b/vhdl/rtl/vhdl/WF_UART6850_IP/wf6850ip_top.vhd @@ -0,0 +1,135 @@ +---------------------------------------------------------------------- +---- ---- +---- 6850 compatible IP Core ---- +---- ---- +---- This file is part of the SUSKA ATARI clone project. ---- +---- http://www.experiment-s.de ---- +---- ---- +---- Description: ---- +---- UART 6850 compatible IP core ---- +---- ---- +---- This is the top level file. ---- +---- ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2006 Wolfgang Foerster ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.gnu.org/licenses/lgpl.html ---- +---- ---- +---------------------------------------------------------------------- +-- +-- Revision History +-- +-- Revision 2K6A 2006/06/03 WF +-- Initial Release. +-- Revision 2K6B 2006/11/07 WF +-- Modified Source to compile with the Xilinx ISE. +-- Revision 2K8B 2008/12/24 WF +-- Rewritten this top level file as a wrapper for the top_soc file. +-- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + +entity WF6850IP_TOP is + port ( + CLK : in bit; + RESETn : in bit; + + CS2n, CS1, CS0 : in bit; + E : in bit; + RWn : in bit; + RS : in bit; + + DATA : inout std_logic_vector(7 downto 0); + + TXCLK : in bit; + RXCLK : in bit; + RXDATA : in bit; + CTSn : in bit; + DCDn : in bit; + + IRQn : out std_logic; + TXDATA : out bit; + RTSn : out bit + ); +end entity WF6850IP_TOP; + +architecture STRUCTURE of WF6850IP_TOP is +component WF6850IP_TOP_SOC + port ( + CLK : in bit; + RESETn : in bit; + CS2n, CS1, CS0 : in bit; + E : in bit; + RWn : in bit; + RS : in bit; + DATA_IN : in std_logic_vector(7 downto 0); + DATA_OUT : out std_logic_vector(7 downto 0); + DATA_EN : out bit; + TXCLK : in bit; + RXCLK : in bit; + RXDATA : in bit; + CTSn : in bit; + DCDn : in bit; + IRQn : out bit; + TXDATA : out bit; + RTSn : out bit + ); +end component; +signal DATA_OUT : std_logic_vector(7 downto 0); +signal DATA_EN : bit; +signal IRQ_In : bit; +begin + DATA <= DATA_OUT when DATA_EN = '1' else (others => 'Z'); + IRQn <= '0' when IRQ_In = '0' else 'Z'; -- Open drain. + + I_UART: WF6850IP_TOP_SOC + port map(CLK => CLK, + RESETn => RESETn, + CS2n => CS2n, + CS1 => CS1, + CS0 => CS0, + E => E, + RWn => RWn, + RS => RS, + DATA_IN => DATA, + DATA_OUT => DATA_OUT, + DATA_EN => DATA_EN, + TXCLK => TXCLK, + RXCLK => RXCLK, + RXDATA => RXDATA, + CTSn => CTSn, + DCDn => DCDn, + IRQn => IRQ_In, + TXDATA => TXDATA, + RTSn => RTSn + ); +end architecture STRUCTURE; \ No newline at end of file diff --git a/vhdl/rtl/vhdl/WF_UART6850_IP/wf6850ip_top_soc.vhd b/vhdl/rtl/vhdl/WF_UART6850_IP/wf6850ip_top_soc.vhd new file mode 100644 index 0000000..47fdc91 --- /dev/null +++ b/vhdl/rtl/vhdl/WF_UART6850_IP/wf6850ip_top_soc.vhd @@ -0,0 +1,256 @@ +---------------------------------------------------------------------- +---- ---- +---- 6850 compatible IP Core ---- +---- ---- +---- This file is part of the SUSKA ATARI clone project. ---- +---- http://www.experiment-s.de ---- +---- ---- +---- Description: ---- +---- UART 6850 compatible IP core ---- +---- ---- +---- This is the top level file. ---- +---- Top level file for use in systems on programmable chips. ---- +---- ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2006 - 2011 Wolfgang Foerster ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.gnu.org/licenses/lgpl.html ---- +---- ---- +---------------------------------------------------------------------- +-- +-- Revision History +-- +-- Revision 2K6A 2006/06/03 WF +-- Initial Release. +-- Revision 2K6B 2006/11/07 WF +-- Modified Source to compile with the Xilinx ISE. +-- Top level file provided for SOC (systems on programmable chips). +-- Revision 2K8A 2008/07/14 WF +-- Minor changes. +-- Revision 2K9B 2009/12/24 WF +-- Fixed the interrupt logic. +-- Introduced a minor RTSn correction. +-- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + +entity WF6850IP_TOP_SOC is + port ( + CLK : in bit; + RESETn : in bit; + + CS2n, CS1, CS0 : in bit; + E : in bit; + RWn : in bit; + RS : in bit; + + DATA_IN : in std_logic_vector(7 downto 0); + DATA_OUT : out std_logic_vector(7 downto 0); + DATA_EN : out bit; + + TXCLK : in bit; + RXCLK : in bit; + RXDATA : in bit; + CTSn : in bit; + DCDn : in bit; + + IRQn : out bit; + TXDATA : out bit; + RTSn : out bit + ); +end entity WF6850IP_TOP_SOC; + +architecture STRUCTURE of WF6850IP_TOP_SOC is + component WF6850IP_CTRL_STATUS + port ( + CLK : in bit; + RESETn : in bit; + CS : in bit_vector(2 downto 0); + E : in bit; + RWn : in bit; + RS : in bit; + DATA_IN : in bit_vector(7 downto 0); + DATA_OUT : out bit_vector(7 downto 0); + DATA_EN : out bit; + RDRF : in bit; + TDRE : in bit; + DCDn : in bit; + CTSn : in bit; + FE : in bit; + OVR : in bit; + PE : in bit; + MCLR : out bit; + RTSn : out bit; + CDS : out bit_vector(1 downto 0); + WS : out bit_vector(2 downto 0); + TC : out bit_vector(1 downto 0); + IRQn : out bit + ); + end component; + + component WF6850IP_RECEIVE + port ( + CLK : in bit; + RESETn : in bit; + MCLR : in bit; + CS : in bit_vector(2 downto 0); + E : in bit; + RWn : in bit; + RS : in bit; + DATA_OUT : out bit_vector(7 downto 0); + DATA_EN : out bit; + WS : in bit_vector(2 downto 0); + CDS : in bit_vector(1 downto 0); + RXCLK : in bit; + RXDATA : in bit; + RDRF : out bit; + OVR : out bit; + PE : out bit; + FE : out bit + ); + end component; + + component WF6850IP_TRANSMIT + port ( + CLK : in bit; + RESETn : in bit; + MCLR : in bit; + CS : in bit_vector(2 downto 0); + E : in bit; + RWn : in bit; + RS : in bit; + DATA_IN : in bit_vector(7 downto 0); + CTSn : in bit; + TC : in bit_vector(1 downto 0); + WS : in bit_vector(2 downto 0); + CDS : in bit_vector(1 downto 0); + TXCLK : in bit; + TDRE : out bit; + TXDATA : out bit + ); + end component; + + signal DATA_IN_I : bit_vector(7 downto 0); + signal DATA_RX : bit_vector(7 downto 0); + signal DATA_RX_EN : bit; + signal DATA_CTRL : bit_vector(7 downto 0); + signal DATA_CTRL_EN : bit; + signal RDRF_I : bit; + signal TDRE_I : bit; + signal FE_I : bit; + signal OVR_I : bit; + signal PE_I : bit; + signal MCLR_I : bit; + signal CDS_I : bit_vector(1 downto 0); + signal WS_I : bit_vector(2 downto 0); + signal TC_I : bit_vector(1 downto 0); + signal IRQ_In : bit; +begin + DATA_IN_I <= To_BitVector(DATA_IN); + DATA_EN <= DATA_RX_EN or DATA_CTRL_EN; + DATA_OUT <= To_StdLogicVector(DATA_RX) when DATA_RX_EN = '1' else + To_StdLogicVector(DATA_CTRL) when DATA_CTRL_EN = '1' else (others => '0'); + + IRQn <= '0' when IRQ_In = '0' else '1'; + + I_UART_CTRL_STATUS: WF6850IP_CTRL_STATUS + port map( + CLK => CLK, + RESETn => RESETn, + CS(2) => CS2n, + CS(1) => CS1, + CS(0) => CS0, + E => E, + RWn => RWn, + RS => RS, + DATA_IN => DATA_IN_I, + DATA_OUT => DATA_CTRL, + DATA_EN => DATA_CTRL_EN, + RDRF => RDRF_I, + TDRE => TDRE_I, + DCDn => DCDn, + CTSn => CTSn, + FE => FE_I, + OVR => OVR_I, + PE => PE_I, + MCLR => MCLR_I, + RTSn => RTSn, + CDS => CDS_I, + WS => WS_I, + TC => TC_I, + IRQn => IRQ_In + ); + + I_UART_RECEIVE: WF6850IP_RECEIVE + port map ( + CLK => CLK, + RESETn => RESETn, + MCLR => MCLR_I, + CS(2) => CS2n, + CS(1) => CS1, + CS(0) => CS0, + E => E, + RWn => RWn, + RS => RS, + DATA_OUT => DATA_RX, + DATA_EN => DATA_RX_EN, + WS => WS_I, + CDS => CDS_I, + RXCLK => RXCLK, + RXDATA => RXDATA, + RDRF => RDRF_I, + OVR => OVR_I, + PE => PE_I, + FE => FE_I + ); + + I_UART_TRANSMIT: WF6850IP_TRANSMIT + port map ( + CLK => CLK, + RESETn => RESETn, + MCLR => MCLR_I, + CS(2) => CS2n, + CS(1) => CS1, + CS(0) => CS0, + E => E, + RWn => RWn, + RS => RS, + DATA_IN => DATA_IN_I, + CTSn => CTSn, + TC => TC_I, + WS => WS_I, + CDS => CDS_I, + TDRE => TDRE_I, + TXCLK => TXCLK, + TXDATA => TXDATA + ); +end architecture STRUCTURE; \ No newline at end of file diff --git a/vhdl/rtl/vhdl/WF_UART6850_IP/wf6850ip_transmit.vhd b/vhdl/rtl/vhdl/WF_UART6850_IP/wf6850ip_transmit.vhd new file mode 100644 index 0000000..8a0a9fa --- /dev/null +++ b/vhdl/rtl/vhdl/WF_UART6850_IP/wf6850ip_transmit.vhd @@ -0,0 +1,338 @@ +---------------------------------------------------------------------- +---- ---- +---- 6850 compatible IP Core ---- +---- ---- +---- This file is part of the SUSKA ATARI clone project. ---- +---- http://www.experiment-s.de ---- +---- ---- +---- Description: ---- +---- UART 6850 compatible IP core ---- +---- ---- +---- 6850's transmitter unit. ---- +---- ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2006 - 2008 Wolfgang Foerster ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source is distributed in the hope that it will be ---- +---- useful, but WITHOUT ANY WARRANTY; without even the implied ---- +---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ---- +---- PURPOSE. See the GNU Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.gnu.org/licenses/lgpl.html ---- +---- ---- +---------------------------------------------------------------------- +-- +-- Revision History +-- +-- Revision 2K6A 2006/06/03 WF +-- Initial Release. +-- Revision 2K6B 2006/11/07 WF +-- Modified Source to compile with the Xilinx ISE. +-- Revision 2K8A 2008/07/14 WF +-- Minor changes. +-- Revision 2K8B 2008/11/01 WF +-- Fixed the T_DRE process concerning the TDRE <= '1' setting. +-- Thanks to Lyndon Amsdon finding the bug. +-- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + +entity WF6850IP_TRANSMIT is + port ( + CLK : in std_logic; + RESETn : in bit; + MCLR : in bit; + + CS : in bit_vector(2 downto 0); + E : in bit; + RWn : in bit; + RS : in bit; + + DATA_IN : in bit_vector(7 downto 0); + + CTSn : in bit; + + TC : in bit_vector(1 downto 0); + WS : in bit_vector(2 downto 0); + CDS : in bit_vector(1 downto 0); + + TXCLK : in bit; + + TDRE : buffer bit; + TXDATA : out bit + ); +end entity WF6850IP_TRANSMIT; + +architecture BEHAVIOR of WF6850IP_TRANSMIT is +type TR_STATES is (IDLE, LOAD_SHFT, START, SHIFTOUT, PARITY, STOP1, STOP2); +signal TR_STATE, TR_NEXT_STATE : TR_STATES; +signal CLK_STRB : bit; +signal DATA_REG : bit_vector(7 downto 0); +signal SHIFT_REG : bit_vector(7 downto 0); +signal BITCNT : std_logic_vector(2 downto 0); +signal PARITY_I : bit; +begin + -- The default condition in this statement is to ensure + -- to cover all possibilities for example if there is a + -- one hot decoding of the state machine with wrong states + -- (e.g. not one of the given here). + TXDATA <= '1' when TR_STATE = IDLE else + '1' when TR_STATE = LOAD_SHFT else + '0' when TR_STATE = START else + SHIFT_REG(0) when TR_STATE = SHIFTOUT else + PARITY_I when TR_STATE = PARITY else + '1' when TR_STATE = STOP1 else + '1' when TR_STATE = STOP2 else '1'; + + CLKDIV: process(CLK) + variable CLK_LOCK : boolean; + variable STRB_LOCK : boolean; + variable CLK_DIVCNT : std_logic_vector(6 downto 0); + begin + if rising_edge(CLK) then + if CDS = "00" then -- divider off + if TXCLK = '0' and STRB_LOCK = false then -- Works on negative TXCLK edge. + CLK_STRB <= '1'; + STRB_LOCK := true; + elsif TXCLK = '1' then + CLK_STRB <= '0'; + STRB_LOCK := false; + else + CLK_STRB <= '0'; + end if; + elsif TR_STATE = IDLE then + -- preset the CLKDIV with the start delays + if CDS = "01" then + CLK_DIVCNT := "0010000"; -- div by 16 mode + elsif CDS = "10" then + CLK_DIVCNT := "1000000"; -- div by 64 mode + end if; + CLK_STRB <= '0'; + else + -- Works on negative TXCLK edge: + if CLK_DIVCNT > "0000000" and TXCLK = '0' and CLK_LOCK = false then + CLK_DIVCNT := CLK_DIVCNT - '1'; + CLK_STRB <= '0'; + CLK_LOCK := true; + elsif CDS = "01" and CLK_DIVCNT = "0000000" then + CLK_DIVCNT := "0010000"; -- Div by 16 mode. + if STRB_LOCK = false then + STRB_LOCK := true; + CLK_STRB <= '1'; + else + CLK_STRB <= '0'; + end if; + elsif CDS = "10" and CLK_DIVCNT = "0000000" then + CLK_DIVCNT := "1000000"; -- Div by 64 mode. + if STRB_LOCK = false then + STRB_LOCK := true; + CLK_STRB <= '1'; + else + CLK_STRB <= '0'; + end if; + elsif TXCLK = '1' then + CLK_LOCK := false; + STRB_LOCK := false; + CLK_STRB <= '0'; + else + CLK_STRB <= '0'; + end if; + end if; + end if; + end process CLKDIV; + + DATAREG: process(RESETn, CLK) + begin + if RESETn = '0' then + DATA_REG <= x"00"; + elsif rising_edge(CLK) then + if MCLR = '1' then + DATA_REG <= x"00"; + elsif WS(2) = '0' and CS = "011" and RWn = '0' and RS = '1' and E = '1' then + DATA_REG <= '0' & DATA_IN(6 downto 0); -- 7 bit data mode. + elsif WS(2) = '1' and CS = "011" and RWn = '0' and RS = '1' and E = '1' then + DATA_REG <= DATA_IN; -- 8 bit data mode. + end if; + end if; + end process DATAREG; + + SHIFTREG: process(RESETn, CLK) + begin + if RESETn = '0' then + SHIFT_REG <= x"00"; + elsif rising_edge(CLK) then + if MCLR = '1' then + SHIFT_REG <= x"00"; + elsif TR_STATE = LOAD_SHFT and TDRE = '0' then + -- If during LOAD_SHIFT the transmitter data register + -- is empty (TDRE = '1') the shift register will not + -- be loaded. When additionally TC = "11", the break + -- character (zero data and no stop bits) is sent. + SHIFT_REG <= DATA_REG; + elsif TR_STATE = SHIFTOUT and CLK_STRB = '1' then + SHIFT_REG <= '0' & SHIFT_REG(7 downto 1); -- Shift right. + end if; + end if; + end process SHIFTREG; + + P_BITCNT: process(CLK) + -- Counter for the data bits transmitted. + begin + if rising_edge(CLK) then + if TR_STATE = SHIFTOUT and CLK_STRB = '1' then + BITCNT <= BITCNT + '1'; + elsif TR_STATE /= SHIFTOUT then + BITCNT <= "000"; + end if; + end if; + end process P_BITCNT; + + P_TDRE: process(RESETn, CLK) + -- Transmit data register empty flag. + begin + if rising_edge(CLK) then + if RESETn = '0' or MCLR = '1' then + TDRE <= '1'; + else + if TR_NEXT_STATE = START and TR_STATE /= START then + -- Data has been loaded to shift register, thus data register is free again. + -- Thanks to Lyndon Amsdon for finding a bug here. The TDRE is set to one once + -- entering the state now. + TDRE <= '1'; + end if; + if CS = "011" and RWn = '0' and RS = '1' then + TDRE <= '0'; + end if; + end if; + end if; + end process P_TDRE; + + PARITY_GEN: process(CLK) + variable PAR_TMP : bit; + begin + if rising_edge(CLK) then + if TR_STATE = START then -- Calculate the parity during the start phase. + for i in 1 to 7 loop + if i = 1 then + PAR_TMP := SHIFT_REG(i-1) xor SHIFT_REG(i); + else + PAR_TMP := PAR_TMP xor SHIFT_REG(i); + end if; + end loop; + if WS = "000" or WS = "010" or WS = "110" then -- Even parity. + PARITY_I <= PAR_TMP; + elsif WS = "001" or WS = "011" or WS = "111" then -- Odd parity. + PARITY_I <= not PAR_TMP; + else -- No parity for WS = "100" and WS = "101". + PARITY_I <= '0'; + end if; + end if; + end if; + end process PARITY_GEN; + + TR_STATEREG: process(RESETn, CLK) + begin + if RESETn = '0' then + TR_STATE <= IDLE; + else + if rising_edge(CLK) then + if MCLR = '1' then + TR_STATE <= IDLE; + else + TR_STATE <= TR_NEXT_STATE; + end if; + end if; + end if; + end process TR_STATEREG; + + TR_STATEDEC: process(TR_STATE, CLK_STRB, TC, BITCNT, WS, TDRE, CTSn) + begin + case TR_STATE is + when IDLE => + if TDRE = '1' and TC = "11" then + TR_NEXT_STATE <= LOAD_SHFT; + elsif TDRE = '0' and CTSn = '0' then -- Start if data register is not empty. + TR_NEXT_STATE <= LOAD_SHFT; + else + TR_NEXT_STATE <= IDLE; + end if; + when LOAD_SHFT => + TR_NEXT_STATE <= START; + when START => + if CLK_STRB = '1' then + TR_NEXT_STATE <= SHIFTOUT; + else + TR_NEXT_STATE <= START; + end if; + when SHIFTOUT => + if CLK_STRB = '1' then + if BITCNT < "110" and WS(2) = '0' then + TR_NEXT_STATE <= SHIFTOUT; -- Transmit 7 data bits. + elsif BITCNT < "111" and WS(2) = '1' then + TR_NEXT_STATE <= SHIFTOUT; -- Transmit 8 data bits. + elsif WS = "100" or WS = "101" then + if TDRE = '1' and TC = "11" then + -- Break condition, do not send a stop bit. + TR_NEXT_STATE <= IDLE; + else + TR_NEXT_STATE <= STOP1; -- No parity check enabled. + end if; + else + TR_NEXT_STATE <= PARITY; -- Parity enabled. + end if; + else + TR_NEXT_STATE <= SHIFTOUT; + end if; + when PARITY => + if CLK_STRB = '1' then + if TDRE = '1' and TC = "11" then + -- Break condition, do not send a stop bit. + TR_NEXT_STATE <= IDLE; + else + TR_NEXT_STATE <= STOP1; -- No parity check enabled. + end if; + else + TR_NEXT_STATE <= PARITY; + end if; + when STOP1 => + if CLK_STRB = '1' and (WS = "000" or WS = "001" or WS = "100") then + TR_NEXT_STATE <= STOP2; -- Two stop bits selected. + elsif CLK_STRB = '1' then + TR_NEXT_STATE <= IDLE; -- One stop bits selected. + else + TR_NEXT_STATE <= STOP1; + end if; + when STOP2 => + if CLK_STRB = '1' then + TR_NEXT_STATE <= IDLE; + else + TR_NEXT_STATE <= STOP2; + end if; + end case; + end process TR_STATEDEC; +end architecture BEHAVIOR; + diff --git a/vhdl/testbenches/ddr_ctlr_tb.vhd b/vhdl/testbenches/ddr_ctlr_tb.vhd new file mode 100644 index 0000000..590c573 --- /dev/null +++ b/vhdl/testbenches/ddr_ctlr_tb.vhd @@ -0,0 +1,82 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity ddr_ctlr_tb is +end ddr_ctlr_tb; + +architecture beh of ddr_ctlr_tb is + signal clock : std_logic := '0'; -- main clock + signal clock_33 : std_logic := '0'; -- 33 MHz clock + signal ddr_clk : std_logic := '0'; -- ddr clock + + signal vec : std_logic_vector(31 downto 0) := "00000000000000000000000000000000"; + signal o : std_logic_vector(31 downto 0); + component DDR_CTRL_V1 + port( + CLK_MAIN : in std_logic; + DDR_SYNC_66M : in std_logic; + FB_ADR : in std_logic_vector(31 downto 0); + FB_CS1n : in std_logic; + FB_OEn : in std_logic; + FB_SIZE0 : in std_logic; + FB_SIZE1 : in std_logic; + FB_ALE : in std_logic; + FB_WRn : in std_logic; + FIFO_CLR : in std_logic; + VIDEO_RAM_CTR : in std_logic_vector(15 downto 0); + BLITTER_ADR : in std_logic_vector(31 downto 0); + BLITTER_SIG : in std_logic; + BLITTER_WR : in std_logic; + DDRCLK0 : in std_logic; + CLK_33M : in std_logic; + FIFO_MW : in std_logic_vector(8 downto 0); + VA : out std_logic_vector(12 downto 0); + VWEn : out std_logic; + VRASn : out std_logic; + VCSn : out std_logic; + VCKE : out std_logic; + VCASn : out std_logic; + FB_LE : out std_logic_vector(3 downto 0); + FB_VDOE : out std_logic_vector(3 downto 0); + SR_FIFO_WRE : out std_logic; + SR_DDR_FB : out std_logic; + SR_DDR_WR : out std_logic; + SR_DDRWR_D_SEL : out std_logic; + SR_VDMP : out std_logic_vector(7 downto 0); + VIDEO_DDR_TA : out std_logic; + SR_BLITTER_DACK : out std_logic; + BA : out std_logic_vector(1 downto 0); + DDRWR_D_SEL1 : out std_logic; + VDM_SEL : out std_logic_vector(3 downto 0); + DATA_IN : in std_logic_vector(31 downto 0); + DATA_OUT : out std_logic_vector(31 downto 16); + DATA_EN_H : out std_logic; + DATA_EN_L : out std_logic + ); + end component; +begin + t : DDR_CTRL_V1 + port map + ( + CLK_MAIN => clock, + vec_in => vec, + vec_out => o + ); + + stimulate_clock : process + begin + wait for 5 ps; + clock <= not clock; + end process; + + stimulate : process + begin + vec <= "00000000000000000000000000000001"; + wait for 20 ps; + vec <= "10000000000000000000000000000000"; + wait for 20 ps; + vec <= "00000000000000000000000000000101"; + wait for 20 ps; + end process; +end beh;