From 78e466fe6f798d6ee02859edb05501b3a427b837 Mon Sep 17 00:00:00 2001 From: Marcel Date: Mon, 20 Jun 2022 18:52:46 +0200 Subject: [PATCH] Release Supervision --- Console_MiST/Gamate_MiST/Gamate_MiST.qsf | 99 +- Console_MiST/Gamate_MiST/Gamate_MiST.sdc | 135 ++ Console_MiST/Gamate_MiST/Readme.md | 9 +- Console_MiST/Supervision_MiST/ReadMe.txt | 19 - Console_MiST/Supervision_MiST/Readme.md | 18 + .../Snapshot/Supervision_MiST.rbf | Bin 229296 -> 0 bytes .../Supervision_MiST/Supervision_MiST.qpf | 7 +- .../Supervision_MiST/Supervision_MiST.qsf | 41 +- .../Supervision_MiST/Supervision_MiST.sdc | 135 ++ Console_MiST/Supervision_MiST/clean.bat | 35 +- Console_MiST/Supervision_MiST/rtl/65c02/ALU.v | 108 -- .../Supervision_MiST/rtl/65c02/README | 67 - Console_MiST/Supervision_MiST/rtl/65c02/cpu.v | 1225 --------------- .../Supervision_MiST/rtl/65c02/cpu_65c02.v | 1395 ----------------- .../Supervision_MiST/rtl/Supervision_MiST.sv | 295 ++-- .../Supervision_MiST/rtl/Supervision_Top.sv | 333 ---- Console_MiST/Supervision_MiST/rtl/audio.sv | 304 +++- Console_MiST/Supervision_MiST/rtl/bram.vhd | 236 +++ Console_MiST/Supervision_MiST/rtl/dma.sv | 128 +- Console_MiST/Supervision_MiST/rtl/lcd.sv | 123 ++ .../rtl/{pll2.qip => pll.qip} | 4 +- Console_MiST/Supervision_MiST/rtl/pll.vhd | 397 +++++ Console_MiST/Supervision_MiST/rtl/pll1.v | 348 ---- Console_MiST/Supervision_MiST/rtl/pll2.v | 320 ---- Console_MiST/Supervision_MiST/rtl/ram88.sv | 23 - Console_MiST/Supervision_MiST/rtl/rom.v | 22 - Console_MiST/Supervision_MiST/rtl/sdram.sv | 427 ++--- Console_MiST/Supervision_MiST/rtl/sv_top.sv | 268 ++++ Console_MiST/Supervision_MiST/rtl/video.sv | 88 -- 29 files changed, 2080 insertions(+), 4529 deletions(-) create mode 100644 Console_MiST/Gamate_MiST/Gamate_MiST.sdc delete mode 100644 Console_MiST/Supervision_MiST/ReadMe.txt create mode 100644 Console_MiST/Supervision_MiST/Readme.md delete mode 100644 Console_MiST/Supervision_MiST/Snapshot/Supervision_MiST.rbf create mode 100644 Console_MiST/Supervision_MiST/Supervision_MiST.sdc delete mode 100644 Console_MiST/Supervision_MiST/rtl/65c02/ALU.v delete mode 100644 Console_MiST/Supervision_MiST/rtl/65c02/README delete mode 100644 Console_MiST/Supervision_MiST/rtl/65c02/cpu.v delete mode 100644 Console_MiST/Supervision_MiST/rtl/65c02/cpu_65c02.v delete mode 100644 Console_MiST/Supervision_MiST/rtl/Supervision_Top.sv create mode 100644 Console_MiST/Supervision_MiST/rtl/bram.vhd create mode 100644 Console_MiST/Supervision_MiST/rtl/lcd.sv rename Console_MiST/Supervision_MiST/rtl/{pll2.qip => pll.qip} (62%) create mode 100644 Console_MiST/Supervision_MiST/rtl/pll.vhd delete mode 100644 Console_MiST/Supervision_MiST/rtl/pll1.v delete mode 100644 Console_MiST/Supervision_MiST/rtl/pll2.v delete mode 100644 Console_MiST/Supervision_MiST/rtl/ram88.sv delete mode 100644 Console_MiST/Supervision_MiST/rtl/rom.v create mode 100644 Console_MiST/Supervision_MiST/rtl/sv_top.sv delete mode 100644 Console_MiST/Supervision_MiST/rtl/video.sv diff --git a/Console_MiST/Gamate_MiST/Gamate_MiST.qsf b/Console_MiST/Gamate_MiST/Gamate_MiST.qsf index d593499c..b8d57a48 100644 --- a/Console_MiST/Gamate_MiST/Gamate_MiST.qsf +++ b/Console_MiST/Gamate_MiST/Gamate_MiST.qsf @@ -18,14 +18,14 @@ # # Quartus II 64-Bit # Version 13.1.4 Build 182 03/12/2014 SJ Full Version -# Date created = 15:15:28 January 23, 2021 +# Date created = 18:49:14 June 20, 2022 # # -------------------------------------------------------------------------- # # # Notes: # # 1) The default values for assignments are stored in the file: -# Gaplus_assignment_defaults.qdf +# Gamate_MiST_assignment_defaults.qdf # If this file doesn't exist, see file: # assignment_defaults.qdf # @@ -43,6 +43,17 @@ set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL set_global_assignment -name LAST_QUARTUS_VERSION 13.1 set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:rtl/build_id.tcl" +set_global_assignment -name SYSTEMVERILOG_FILE rtl/Gamate_MiST.sv +set_global_assignment -name SYSTEMVERILOG_FILE rtl/gamate_top.sv +set_global_assignment -name VHDL_FILE rtl/bram.vhd +set_global_assignment -name SYSTEMVERILOG_FILE rtl/lcd.sv +set_global_assignment -name SYSTEMVERILOG_FILE rtl/ym2149.sv +set_global_assignment -name VHDL_FILE rtl/rom/gamate_bios_bit.vhd +set_global_assignment -name VHDL_FILE rtl/rom/gamate_bios_umc.vhd +set_global_assignment -name SYSTEMVERILOG_FILE rtl/sdram.sv +set_global_assignment -name VHDL_FILE rtl/pll.vhd +set_global_assignment -name QIP_FILE "D:/GitHub/Mist_FPGA/common/mist/mist.qip" +set_global_assignment -name QIP_FILE "D:/GitHub/Mist_FPGA/common/CPU/T65/T65.qip" # Pin & Location Assignments # ========================== @@ -169,69 +180,57 @@ set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" - set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -fall # ------------------------- -# start ENTITY(Gaplus_MiST) +# start ENTITY(Gamate_MiST) # Pin & Location Assignments # ========================== + set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[*] + set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[*] + set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_BA[0] + set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_BA[1] + set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQMH + set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQML + set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nRAS + set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nCAS + set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nWE + set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nCS + set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[*] + set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[*] # Fitter Assignments # ================== + set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[*] + set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[*] + set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_BA[*] + set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQML + set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQMH + set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nRAS + set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nCAS + set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nWE + set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nCS + set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_CKE + set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_CLK + set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_R[*] + set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_G[*] + set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_B[*] + set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_HS + set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_VS + set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to AUDIO_L + set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to AUDIO_R + set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SPI_DO # start DESIGN_PARTITION(Top) # --------------------------- # Incremental Compilation Assignments # =================================== + 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 # end DESIGN_PARTITION(Top) # ------------------------- -# end ENTITY(Gaplus_MiST) +# end ENTITY(Gamate_MiST) # ----------------------- -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_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[*] -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[*] -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_BA[0] -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_BA[1] -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQMH -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQML -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nRAS -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nCAS -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nWE -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nCS -set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[*] -set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[*] -set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[*] -set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[*] -set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_BA[*] -set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQML -set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQMH -set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nRAS -set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nCAS -set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nWE -set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nCS -set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_CKE -set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_CLK -set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_R[*] -set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_G[*] -set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_B[*] -set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_HS -set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_VS -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to AUDIO_L -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to AUDIO_R -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SPI_DO -set_global_assignment -name SYSTEMVERILOG_FILE rtl/Gamate_MiST.sv -set_global_assignment -name SYSTEMVERILOG_FILE rtl/gamate_top.sv -set_global_assignment -name VHDL_FILE rtl/bram.vhd -set_global_assignment -name SYSTEMVERILOG_FILE rtl/lcd.sv -set_global_assignment -name SYSTEMVERILOG_FILE rtl/ym2149.sv -set_global_assignment -name VHDL_FILE rtl/rom/gamate_bios_bit.vhd -set_global_assignment -name VHDL_FILE rtl/rom/gamate_bios_umc.vhd -set_global_assignment -name SYSTEMVERILOG_FILE rtl/sdram.sv -set_global_assignment -name VHDL_FILE rtl/pll.vhd -set_global_assignment -name QIP_FILE "D:/GitHub/Mist_FPGA/common/mist/mist.qip" -set_global_assignment -name QIP_FILE "D:/GitHub/Mist_FPGA/common/CPU/T65/T65.qip" -set_global_assignment -name VHDL_FILE rtl/rom/Cube_Up.vhd set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/Console_MiST/Gamate_MiST/Gamate_MiST.sdc b/Console_MiST/Gamate_MiST/Gamate_MiST.sdc new file mode 100644 index 00000000..dddfdcc4 --- /dev/null +++ b/Console_MiST/Gamate_MiST/Gamate_MiST.sdc @@ -0,0 +1,135 @@ +## Generated SDC file "Gamate_MiST.out.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 "Sun Jun 24 12:53:00 2018" + +## +## DEVICE "EP3C25E144C8" +## + +# Clock constraints + +# Automatically constrain PLL and other generated clocks +derive_pll_clocks -create_base_clocks + +# Automatically calculate clock uncertainty to jitter and other effects. +derive_clock_uncertainty + +# tsu/th constraints + +# tco constraints + +# tpd constraints + +#************************************************************** +# Time Information +#************************************************************** + +set_time_format -unit ns -decimal_places 3 + + + +#************************************************************** +# Create Clock +#************************************************************** + +create_clock -name {SPI_SCK} -period 41.666 -waveform { 20.8 41.666 } [get_ports {SPI_SCK}] + +set sys_clk "pll|altpll_component|auto_generated|pll1|clk[1]" +set vid_clk "pll|altpll_component|auto_generated|pll1|clk[0]" +set sdram_clk "pll|altpll_component|auto_generated|pll1|clk[0]" +#************************************************************** +# Create Generated Clock +#************************************************************** + + +#************************************************************** +# Set Clock Latency +#************************************************************** + + + +#************************************************************** +# Set Clock Uncertainty +#************************************************************** + +#************************************************************** +# Set Input Delay +#************************************************************** + +set_input_delay -add_delay -clock_fall -clock [get_clocks {CLOCK_27}] 1.000 [get_ports {CLOCK_27}] +set_input_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {CONF_DATA0}] +set_input_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_DI}] +set_input_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_SCK}] +set_input_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_SS2}] +set_input_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_SS3}] + +set_input_delay -clock [get_clocks $sdram_clk] -reference_pin [get_ports {SDRAM_CLK}] -max 6.6 [get_ports SDRAM_DQ[*]] +set_input_delay -clock [get_clocks $sdram_clk] -reference_pin [get_ports {SDRAM_CLK}] -min 3.5 [get_ports SDRAM_DQ[*]] + +#************************************************************** +# Set Output Delay +#************************************************************** + +set_output_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_DO}] +set_output_delay -add_delay -clock_fall -clock [get_clocks $sys_clk] 1.000 [get_ports {AUDIO_L}] +set_output_delay -add_delay -clock_fall -clock [get_clocks $sys_clk] 1.000 [get_ports {AUDIO_R}] +set_output_delay -add_delay -clock_fall -clock [get_clocks $sys_clk] 1.000 [get_ports {LED}] +set_output_delay -add_delay -clock_fall -clock [get_clocks $vid_clk] 1.000 [get_ports {VGA_*}] + +set_output_delay -clock [get_clocks $sdram_clk] -reference_pin [get_ports {SDRAM_CLK}] -max 1.5 [get_ports {SDRAM_D* SDRAM_A* SDRAM_BA* SDRAM_n* SDRAM_CKE}] +set_output_delay -clock [get_clocks $sdram_clk] -reference_pin [get_ports {SDRAM_CLK}] -min -0.8 [get_ports {SDRAM_D* SDRAM_A* SDRAM_BA* SDRAM_n* SDRAM_CKE}] + +#************************************************************** +# Set Clock Groups +#************************************************************** + +set_clock_groups -asynchronous -group [get_clocks {SPI_SCK}] -group [get_clocks {pll|altpll_component|auto_generated|pll1|clk[*]}] + +#************************************************************** +# Set False Path +#************************************************************** + + + +#************************************************************** +# Set Multicycle Path +#************************************************************** + +set_multicycle_path -to {VGA_*[*]} -setup 2 +set_multicycle_path -to {VGA_*[*]} -hold 1 + +#************************************************************** +# Set Maximum Delay +#************************************************************** + + + +#************************************************************** +# Set Minimum Delay +#************************************************************** + + + +#************************************************************** +# Set Input Transition +#************************************************************** + diff --git a/Console_MiST/Gamate_MiST/Readme.md b/Console_MiST/Gamate_MiST/Readme.md index c796dbdc..e080c359 100644 --- a/Console_MiST/Gamate_MiST/Readme.md +++ b/Console_MiST/Gamate_MiST/Readme.md @@ -1,4 +1,11 @@ -# Gamate Handheld System for MiSTer +# Gamate Handheld System for MiST + +Usage + +Start = ESC +Select = TAB +A = Control +B = LALT ## General description This is an FPGA implementation of the Gamate handheld system by Jamie Blanks. This was a Gameboy clone from the early 2000's from the Bit Corp, later to be part of UMC. There's not much to say about it. diff --git a/Console_MiST/Supervision_MiST/ReadMe.txt b/Console_MiST/Supervision_MiST/ReadMe.txt deleted file mode 100644 index 116c47a4..00000000 --- a/Console_MiST/Supervision_MiST/ReadMe.txt +++ /dev/null @@ -1,19 +0,0 @@ -Watara Supervision for MiSTer by Pierre Cornier - - - -wip - -VGA Only - - -Working for Now - -Brain Power -Galactic Crusader -Galaxy Fighter -Happy Pairs -John Advenzure -Kabi Island -Penguin Hideout -Super Kong diff --git a/Console_MiST/Supervision_MiST/Readme.md b/Console_MiST/Supervision_MiST/Readme.md new file mode 100644 index 00000000..fc1b1f5d --- /dev/null +++ b/Console_MiST/Supervision_MiST/Readme.md @@ -0,0 +1,18 @@ +# Watara Supervision for MiST +Based upon initial work by Pierco, rewritten by Jamie Blanks. + +Usage + +Start = ESC +Select = TAB +A = Control +B = LALT + +An implementation of the unfortunate GameBoy clone, the Watara SuperVision. No boot ROMs are required and there is no additional setup. + +This core is compatible with gameboy palettes which can be found with the GameBoy core. + +The full game library is supported, including the rare "Journey to the West". + +## Special Thanks +A special thank you to Osman Celimli for his very thorough reverse engineering notes and personal help in getting this core accurate. diff --git a/Console_MiST/Supervision_MiST/Snapshot/Supervision_MiST.rbf b/Console_MiST/Supervision_MiST/Snapshot/Supervision_MiST.rbf deleted file mode 100644 index cc2358e082e0dcef0305c2ddcc95b390bed0e73a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 229296 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

AK=BVwmwQ~SQ&?GS&UmJZuJ~07X-g#JIg~s?_ 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 3'd5); - -// CO9 is the carry-out bit when doing BCD add -wire CO9 = BCD & (temp_h[3:1] >= 3'd5); - -// combined half carry bit -wire temp_HC = temp_l[4] | HC9; - -// perform the addition as 2 separate nibble, so we get -// access to the half carry flag -always @* begin - temp_l = temp_logic[3:0] + temp_BI[3:0] + adder_CI; - temp_h = temp_logic[8:4] + temp_BI[7:4] + temp_HC; -end - -// calculate the flags -always @(posedge clk) - if( RDY ) begin - AI7 <= AI[7]; - BI7 <= temp_BI[7]; - OUT <= temp[7:0]; - CO <= temp[8] | CO9; - N <= temp[7]; - HC <= temp_HC; - end - -assign V = AI7 ^ BI7 ^ CO ^ N; -assign Z = ~|OUT; - -endmodule diff --git a/Console_MiST/Supervision_MiST/rtl/65c02/README b/Console_MiST/Supervision_MiST/rtl/65c02/README deleted file mode 100644 index dc2056b2..00000000 --- a/Console_MiST/Supervision_MiST/rtl/65c02/README +++ /dev/null @@ -1,67 +0,0 @@ -======================================================== -A Verilog HDL version of the old MOS 6502 and 65C02 CPUs -======================================================== - -Original 6502 core by Arlet Ottens - -65C02 extensions by David Banks and Ed Spittles - -========== -6502 Core -========== - -Arlet's original 6502 core (cpu.v) is unchanged. - -Note: the 6502/65C02 cores assumes a synchronous memory. This means -that valid data (DI) is expected on the cycle *after* valid -address. This allows direct connection to (Xilinx) block RAMs. When -using asynchronous memory, I suggest registering the address/control -lines for glitchless output signals. - -Have fun. - -========== -65C02 Core -========== - -A second core (cpu_65c02.v) has been added, based on Arlet's 6502 -core, with additional 65C02 instructions and addressing modes: -- PHX, PHY, PLX, PLY -- BRA -- INC A, DEC A -- (zp) addressing mode -- STZ -- BIT zpx, absx, imm -- TSB/TRB -- JMP (,X) -- NOPs (optional) -- 65C02 BCD N/Z flags (optional, disabled) - -The Rockwell/WDC specific instructions (RMB/SMB/BBR/BBS/WAI/STP) are -not currently implemented - -The 65C02 core passes the Dormann 6502 test suite, and also passes the -Dormann 65C02 test suite if the optional support for NOPs and 65C02 -BCD flags is enabled. - -It has been tested as a BBC Micro "Matchbox" 65C02 Co Processor, in a -XC6SLX9-2 FPGA, running at 80MHz using 64KB of internel block RAM. It -just meets timing at 80MHz in this environment. It successfully runs -BBC Basic IV and Tube Elite. - -============ -Known Issues -============ - -The Matchbox Co Processor needed one wait state (via RDY) to be added -to each ROM access (only needed early in the boot process, as -eventually everything runs from RAM). The DIHOLD logic did not work -correctly with a single wait state, and so has been commented out. - -I now believe the correct fix is actually just: - -always @(posedge clk ) - if( RDY ) - DIHOLD <= DI; - -assign DIMUX = ~RDY ? DIHOLD : DI; diff --git a/Console_MiST/Supervision_MiST/rtl/65c02/cpu.v b/Console_MiST/Supervision_MiST/rtl/65c02/cpu.v deleted file mode 100644 index a08804f4..00000000 --- a/Console_MiST/Supervision_MiST/rtl/65c02/cpu.v +++ /dev/null @@ -1,1225 +0,0 @@ -/* - * verilog model of 6502 CPU. - * - * (C) Arlet Ottens, - * - * Feel free to use this code in any project (commercial or not), as long as you - * keep this message, and the copyright notice. This code is provided "as is", - * without any warranties of any kind. - * - */ - -/* - * Note that not all 6502 interface signals are supported (yet). The goal - * is to create an Acorn Atom model, and the Atom didn't use all signals on - * the main board. - * - * The data bus is implemented as separate read/write buses. Combine them - * on the output pads if external memory is required. - */ - -module cpu( clk, reset, AB, DI, DO, WE, IRQ, NMI, RDY ); - -input clk; // CPU clock -input reset; // reset signal -output reg [15:0] AB; // address bus -input [7:0] DI; // data in, read bus -output [7:0] DO; // data out, write bus -output WE; // write enable -input IRQ; // interrupt request -input NMI; // non-maskable interrupt request -input RDY; // Ready signal. Pauses CPU when RDY=0 - -/* - * internal signals - */ - -reg [15:0] PC; // Program Counter -reg [7:0] ABL; // Address Bus Register LSB -reg [7:0] ABH; // Address Bus Register MSB -wire [7:0] ADD; // Adder Hold Register (registered in ALU) - -reg [7:0] DIHOLD; // Hold for Data In -reg DIHOLD_valid; // -wire [7:0] DIMUX; // - -reg [7:0] IRHOLD; // Hold for Instruction register -reg IRHOLD_valid; // Valid instruction in IRHOLD - -reg [7:0] AXYS[3:0]; // A, X, Y and S register file - -reg C = 0; // carry flag (init at zero to avoid X's in ALU sim) -reg Z = 0; // zero flag -reg I = 0; // interrupt flag -reg D = 0; // decimal flag -reg V = 0; // overflow flag -reg N = 0; // negative flag -wire AZ; // ALU Zero flag -wire AV; // ALU overflow flag -wire AN; // ALU negative flag -wire HC; // ALU half carry - -reg [7:0] AI; // ALU Input A -reg [7:0] BI; // ALU Input B -wire [7:0] DI; // Data In -wire [7:0] IR; // Instruction register -reg [7:0] DO; // Data Out -reg WE; // Write Enable -reg CI; // Carry In -wire CO; // Carry Out -wire [7:0] PCH = PC[15:8]; -wire [7:0] PCL = PC[7:0]; - -reg NMI_edge = 0; // captured NMI edge - -reg [1:0] regsel; // Select A, X, Y or S register -wire [7:0] regfile = AXYS[regsel]; // Selected register output - -parameter - SEL_A = 2'd0, - SEL_S = 2'd1, - SEL_X = 2'd2, - SEL_Y = 2'd3; - -/* - * define some signals for watching in simulator output - */ - - -`ifdef SIM -wire [7:0] A = AXYS[SEL_A]; // Accumulator -wire [7:0] X = AXYS[SEL_X]; // X register -wire [7:0] Y = AXYS[SEL_Y]; // Y register -wire [7:0] S = AXYS[SEL_S]; // Stack pointer -`endif - -wire [7:0] P = { N, V, 2'b11, D, I, Z, C }; - -/* - * instruction decoder/sequencer - */ - -reg [5:0] state; - -/* - * control signals - */ - -reg PC_inc; // Increment PC -reg [15:0] PC_temp; // intermediate value of PC - -reg [1:0] src_reg; // source register index -reg [1:0] dst_reg; // destination register index - -reg index_y; // if set, then Y is index reg rather than X -reg load_reg; // loading a register (A, X, Y, S) in this instruction -reg inc; // increment -reg write_back; // set if memory is read/modified/written -reg load_only; // LDA/LDX/LDY instruction -reg store; // doing store (STA/STX/STY) -reg adc_sbc; // doing ADC/SBC -reg compare; // doing CMP/CPY/CPX -reg shift; // doing shift/rotate instruction -reg rotate; // doing rotate (no shift) -reg backwards; // backwards branch -reg cond_true; // branch condition is true -reg [2:0] cond_code; // condition code bits from instruction -reg shift_right; // Instruction ALU shift/rotate right -reg alu_shift_right; // Current cycle shift right enable -reg [3:0] op; // Main ALU operation for instruction -reg [3:0] alu_op; // Current cycle ALU operation -reg adc_bcd; // ALU should do BCD style carry -reg adj_bcd; // results should be BCD adjusted - -/* - * some flip flops to remember we're doing special instructions. These - * get loaded at the DECODE state, and used later - */ -reg bit_ins; // doing BIT instruction -reg plp; // doing PLP instruction -reg php; // doing PHP instruction -reg clc; // clear carry -reg sec; // set carry -reg cld; // clear decimal -reg sed; // set decimal -reg cli; // clear interrupt -reg sei; // set interrupt -reg clv; // clear overflow -reg brk; // doing BRK - -reg res; // in reset - -/* - * ALU operations - */ - -parameter - OP_OR = 4'b1100, - OP_AND = 4'b1101, - OP_EOR = 4'b1110, - OP_ADD = 4'b0011, - OP_SUB = 4'b0111, - OP_ROL = 4'b1011, - OP_A = 4'b1111; - -/* - * Microcode state machine. Basically, every addressing mode has its own - * path through the state machine. Additional information, such as the - * operation, source and destination registers are decoded in parallel, and - * kept in separate flops. - */ - -parameter - ABS0 = 6'd0, // ABS - fetch LSB - ABS1 = 6'd1, // ABS - fetch MSB - ABSX0 = 6'd2, // ABS, X - fetch LSB and send to ALU (+X) - ABSX1 = 6'd3, // ABS, X - fetch MSB and send to ALU (+Carry) - ABSX2 = 6'd4, // ABS, X - Wait for ALU (only if needed) - BRA0 = 6'd5, // Branch - fetch offset and send to ALU (+PC[7:0]) - BRA1 = 6'd6, // Branch - fetch opcode, and send PC[15:8] to ALU - BRA2 = 6'd7, // Branch - fetch opcode (if page boundary crossed) - BRK0 = 6'd8, // BRK/IRQ - push PCH, send S to ALU (-1) - BRK1 = 6'd9, // BRK/IRQ - push PCL, send S to ALU (-1) - BRK2 = 6'd10, // BRK/IRQ - push P, send S to ALU (-1) - BRK3 = 6'd11, // BRK/IRQ - write S, and fetch @ fffe - DECODE = 6'd12, // IR is valid, decode instruction, and write prev reg - FETCH = 6'd13, // fetch next opcode, and perform prev ALU op - INDX0 = 6'd14, // (ZP,X) - fetch ZP address, and send to ALU (+X) - INDX1 = 6'd15, // (ZP,X) - fetch LSB at ZP+X, calculate ZP+X+1 - INDX2 = 6'd16, // (ZP,X) - fetch MSB at ZP+X+1 - INDX3 = 6'd17, // (ZP,X) - fetch data - INDY0 = 6'd18, // (ZP),Y - fetch ZP address, and send ZP to ALU (+1) - INDY1 = 6'd19, // (ZP),Y - fetch at ZP+1, and send LSB to ALU (+Y) - INDY2 = 6'd20, // (ZP),Y - fetch data, and send MSB to ALU (+Carry) - INDY3 = 6'd21, // (ZP),Y) - fetch data (if page boundary crossed) - JMP0 = 6'd22, // JMP - fetch PCL and hold - JMP1 = 6'd23, // JMP - fetch PCH - JMPI0 = 6'd24, // JMP IND - fetch LSB and send to ALU for delay (+0) - JMPI1 = 6'd25, // JMP IND - fetch MSB, proceed with JMP0 state - JSR0 = 6'd26, // JSR - push PCH, save LSB, send S to ALU (-1) - JSR1 = 6'd27, // JSR - push PCL, send S to ALU (-1) - JSR2 = 6'd28, // JSR - write S - JSR3 = 6'd29, // JSR - fetch MSB - PULL0 = 6'd30, // PLP/PLA - save next op in IRHOLD, send S to ALU (+1) - PULL1 = 6'd31, // PLP/PLA - fetch data from stack, write S - PULL2 = 6'd32, // PLP/PLA - prefetch op, but don't increment PC - PUSH0 = 6'd33, // PHP/PHA - send A to ALU (+0) - PUSH1 = 6'd34, // PHP/PHA - write A/P, send S to ALU (-1) - READ = 6'd35, // Read memory for read/modify/write (INC, DEC, shift) - REG = 6'd36, // Read register for reg-reg transfers - RTI0 = 6'd37, // RTI - send S to ALU (+1) - RTI1 = 6'd38, // RTI - read P from stack - RTI2 = 6'd39, // RTI - read PCL from stack - RTI3 = 6'd40, // RTI - read PCH from stack - RTI4 = 6'd41, // RTI - read PCH from stack - RTS0 = 6'd42, // RTS - send S to ALU (+1) - RTS1 = 6'd43, // RTS - read PCL from stack - RTS2 = 6'd44, // RTS - write PCL to ALU, read PCH - RTS3 = 6'd45, // RTS - load PC and increment - WRITE = 6'd46, // Write memory for read/modify/write - ZP0 = 6'd47, // Z-page - fetch ZP address - ZPX0 = 6'd48, // ZP, X - fetch ZP, and send to ALU (+X) - ZPX1 = 6'd49; // ZP, X - load from memory - -`ifdef SIM - -/* - * easy to read names in simulator output - */ -reg [8*6-1:0] statename; - -always @* - case( state ) - DECODE: statename = "DECODE"; - REG: statename = "REG"; - ZP0: statename = "ZP0"; - ZPX0: statename = "ZPX0"; - ZPX1: statename = "ZPX1"; - ABS0: statename = "ABS0"; - ABS1: statename = "ABS1"; - ABSX0: statename = "ABSX0"; - ABSX1: statename = "ABSX1"; - ABSX2: statename = "ABSX2"; - INDX0: statename = "INDX0"; - INDX1: statename = "INDX1"; - INDX2: statename = "INDX2"; - INDX3: statename = "INDX3"; - INDY0: statename = "INDY0"; - INDY1: statename = "INDY1"; - INDY2: statename = "INDY2"; - INDY3: statename = "INDY3"; - READ: statename = "READ"; - WRITE: statename = "WRITE"; - FETCH: statename = "FETCH"; - PUSH0: statename = "PUSH0"; - PUSH1: statename = "PUSH1"; - PULL0: statename = "PULL0"; - PULL1: statename = "PULL1"; - PULL2: statename = "PULL2"; - JSR0: statename = "JSR0"; - JSR1: statename = "JSR1"; - JSR2: statename = "JSR2"; - JSR3: statename = "JSR3"; - RTI0: statename = "RTI0"; - RTI1: statename = "RTI1"; - RTI2: statename = "RTI2"; - RTI3: statename = "RTI3"; - RTI4: statename = "RTI4"; - RTS0: statename = "RTS0"; - RTS1: statename = "RTS1"; - RTS2: statename = "RTS2"; - RTS3: statename = "RTS3"; - BRK0: statename = "BRK0"; - BRK1: statename = "BRK1"; - BRK2: statename = "BRK2"; - BRK3: statename = "BRK3"; - BRA0: statename = "BRA0"; - BRA1: statename = "BRA1"; - BRA2: statename = "BRA2"; - JMP0: statename = "JMP0"; - JMP1: statename = "JMP1"; - JMPI0: statename = "JMPI0"; - JMPI1: statename = "JMPI1"; - endcase - -//always @( PC ) -// $display( "%t, PC:%04x IR:%02x A:%02x X:%02x Y:%02x S:%02x C:%d Z:%d V:%d N:%d P:%02x", $time, PC, IR, A, X, Y, S, C, Z, V, N, P ); - -`endif - - - -/* - * Program Counter Increment/Load. First calculate the base value in - * PC_temp. - */ -always @* - case( state ) - DECODE: if( (~I & IRQ) | NMI_edge ) - PC_temp = { ABH, ABL }; - else - PC_temp = PC; - - - JMP1, - JMPI1, - JSR3, - RTS3, - RTI4: PC_temp = { DIMUX, ADD }; - - BRA1: PC_temp = { ABH, ADD }; - - BRA2: PC_temp = { ADD, PCL }; - - BRK2: PC_temp = res ? 16'hfffc : - NMI_edge ? 16'hfffa : 16'hfffe; - - default: PC_temp = PC; - endcase - -/* - * Determine wether we need PC_temp, or PC_temp + 1 - */ -always @* - case( state ) - DECODE: if( (~I & IRQ) | NMI_edge ) - PC_inc = 0; - else - PC_inc = 1; - - ABS0, - ABSX0, - FETCH, - BRA0, - BRA2, - BRK3, - JMPI1, - JMP1, - RTI4, - RTS3: PC_inc = 1; - - BRA1: PC_inc = CO ^~ backwards; - - default: PC_inc = 0; - endcase - -/* - * Set new PC - */ -always @(posedge clk) - if( RDY ) - PC <= PC_temp + PC_inc; - -/* - * Address Generator - */ - -parameter - ZEROPAGE = 8'h00, - STACKPAGE = 8'h01; - -always @* - case( state ) - ABSX1, - INDX3, - INDY2, - JMP1, - JMPI1, - RTI4, - ABS1: AB = { DIMUX, ADD }; - - BRA2, - INDY3, - ABSX2: AB = { ADD, ABL }; - - BRA1: AB = { ABH, ADD }; - - JSR0, - PUSH1, - RTS0, - RTI0, - BRK0: AB = { STACKPAGE, regfile }; - - BRK1, - JSR1, - PULL1, - RTS1, - RTS2, - RTI1, - RTI2, - RTI3, - BRK2: AB = { STACKPAGE, ADD }; - - INDY1, - INDX1, - ZPX1, - INDX2: AB = { ZEROPAGE, ADD }; - - ZP0, - INDY0: AB = { ZEROPAGE, DIMUX }; - - REG, - READ, - WRITE: AB = { ABH, ABL }; - - default: AB = PC; - endcase - -/* - * ABH/ABL pair is used for registering previous address bus state. - * This can be used to keep the current address, freeing up the original - * source of the address, such as the ALU or DI. - */ -always @(posedge clk) - if( state != PUSH0 && state != PUSH1 && RDY && - state != PULL0 && state != PULL1 && state != PULL2 ) - begin - ABL <= AB[7:0]; - ABH <= AB[15:8]; - end - -/* - * Data Out MUX - */ -always @* - case( state ) - WRITE: DO = ADD; - - JSR0, - BRK0: DO = PCH; - - JSR1, - BRK1: DO = PCL; - - PUSH1: DO = php ? P : ADD; - - BRK2: DO = (IRQ | NMI_edge) ? (P & 8'b1110_1111) : P; - - default: DO = regfile; - endcase - -/* - * Write Enable Generator - */ - -always @* - case( state ) - BRK0, // writing to stack or memory - BRK1, - BRK2, - JSR0, - JSR1, - PUSH1, - WRITE: WE = 1; - - INDX3, // only if doing a STA, STX or STY - INDY3, - ABSX2, - ABS1, - ZPX1, - ZP0: WE = store; - - default: WE = 0; - endcase - -/* - * register file, contains A, X, Y and S (stack pointer) registers. At each - * cycle only 1 of those registers needs to be accessed, so they combined - * in a small memory, saving resources. - */ - -reg write_register; // set when register file is written - -always @* - case( state ) - DECODE: write_register = load_reg & ~plp; - - PULL1, - RTS2, - RTI3, - BRK3, - JSR0, - JSR2 : write_register = 1; - - default: write_register = 0; - endcase - -/* - * BCD adjust logic - */ - -always @(posedge clk) - adj_bcd <= adc_sbc & D; // '1' when doing a BCD instruction - -reg [3:0] ADJL; -reg [3:0] ADJH; - -// adjustment term to be added to ADD[3:0] based on the following -// adj_bcd: '1' if doing ADC/SBC with D=1 -// adc_bcd: '1' if doing ADC with D=1 -// HC : half carry bit from ALU -always @* begin - casex( {adj_bcd, adc_bcd, HC} ) - 3'b0xx: ADJL = 4'd0; // no BCD instruction - 3'b100: ADJL = 4'd10; // SBC, and digital borrow - 3'b101: ADJL = 4'd0; // SBC, but no borrow - 3'b110: ADJL = 4'd0; // ADC, but no carry - 3'b111: ADJL = 4'd6; // ADC, and decimal/digital carry - endcase -end - -// adjustment term to be added to ADD[7:4] based on the following -// adj_bcd: '1' if doing ADC/SBC with D=1 -// adc_bcd: '1' if doing ADC with D=1 -// CO : carry out bit from ALU -always @* begin - casex( {adj_bcd, adc_bcd, CO} ) - 3'b0xx: ADJH = 4'd0; // no BCD instruction - 3'b100: ADJH = 4'd10; // SBC, and digital borrow - 3'b101: ADJH = 4'd0; // SBC, but no borrow - 3'b110: ADJH = 4'd0; // ADC, but no carry - 3'b111: ADJH = 4'd6; // ADC, and decimal/digital carry - endcase -end - -/* - * write to a register. Usually this is the (BCD corrected) output of the - * ALU, but in case of the JSR0 we use the S register to temporarily store - * the PCL. This is possible, because the S register itself is stored in - * the ALU during those cycles. - */ -always @(posedge clk) - if( write_register & RDY ) - AXYS[regsel] <= (state == JSR0) ? DIMUX : { ADD[7:4] + ADJH, ADD[3:0] + ADJL }; - -/* - * register select logic. This determines which of the A, X, Y or - * S registers will be accessed. - */ - -always @* - case( state ) - INDY1, - INDX0, - ZPX0, - ABSX0 : regsel = index_y ? SEL_Y : SEL_X; - - - DECODE : regsel = dst_reg; - - BRK0, - BRK3, - JSR0, - JSR2, - PULL0, - PULL1, - PUSH1, - RTI0, - RTI3, - RTS0, - RTS2 : regsel = SEL_S; - - default: regsel = src_reg; - endcase - -/* - * ALU - */ - -ALU ALU( .clk(clk), - .op(alu_op), - .right(alu_shift_right), - .AI(AI), - .BI(BI), - .CI(CI), - .BCD(adc_bcd & (state == FETCH)), - .CO(CO), - .OUT(ADD), - .V(AV), - .Z(AZ), - .N(AN), - .HC(HC), - .RDY(RDY) ); - -/* - * Select current ALU operation - */ - -always @* - case( state ) - READ: alu_op = op; - - BRA1: alu_op = backwards ? OP_SUB : OP_ADD; - - FETCH, - REG : alu_op = op; - - DECODE, - ABS1: alu_op = 1'bx; - - PUSH1, - BRK0, - BRK1, - BRK2, - JSR0, - JSR1: alu_op = OP_SUB; - - default: alu_op = OP_ADD; - endcase - -/* - * Determine shift right signal to ALU - */ - -always @* - if( state == FETCH || state == REG || state == READ ) - alu_shift_right = shift_right; - else - alu_shift_right = 0; - -/* - * Sign extend branch offset. - */ - -always @(posedge clk) - if( RDY ) - backwards <= DIMUX[7]; - -/* - * ALU A Input MUX - */ - -always @* - case( state ) - JSR1, - RTS1, - RTI1, - RTI2, - BRK1, - BRK2, - INDX1: AI = ADD; - - REG, - ZPX0, - INDX0, - ABSX0, - RTI0, - RTS0, - JSR0, - JSR2, - BRK0, - PULL0, - INDY1, - PUSH0, - PUSH1: AI = regfile; - - BRA0, - READ: AI = DIMUX; - - BRA1: AI = ABH; // don't use PCH in case we're - - FETCH: AI = load_only ? 0 : regfile; - - DECODE, - ABS1: AI = 8'hxx; // don't care - - default: AI = 0; - endcase - - -/* - * ALU B Input mux - */ - -always @* - case( state ) - BRA1, - RTS1, - RTI0, - RTI1, - RTI2, - INDX1, - READ, - REG, - JSR0, - JSR1, - JSR2, - BRK0, - BRK1, - BRK2, - PUSH0, - PUSH1, - PULL0, - RTS0: BI = 8'h00; - - BRA0: BI = PCL; - - DECODE, - ABS1: BI = 8'hxx; - - default: BI = DIMUX; - endcase - -/* - * ALU CI (carry in) mux - */ - -always @* - case( state ) - INDY2, - BRA1, - ABSX1: CI = CO; - - DECODE, - ABS1: CI = 1'bx; - - READ, - REG: CI = rotate ? C : - shift ? 0 : inc; - - FETCH: CI = rotate ? C : - compare ? 1 : - (shift | load_only) ? 0 : C; - - PULL0, - RTI0, - RTI1, - RTI2, - RTS0, - RTS1, - INDY0, - INDX1: CI = 1; - - default: CI = 0; - endcase - -/* - * Processor Status Register update - * - */ - -/* - * Update C flag when doing ADC/SBC, shift/rotate, compare - */ -always @(posedge clk ) - if( shift && state == WRITE ) - C <= CO; - else if( state == RTI2 ) - C <= DIMUX[0]; - else if( ~write_back && state == DECODE ) begin - if( adc_sbc | shift | compare ) - C <= CO; - else if( plp ) - C <= ADD[0]; - else begin - if( sec ) C <= 1; - if( clc ) C <= 0; - end - end - -/* - * Update Z, N flags when writing A, X, Y, Memory, or when doing compare - */ - -always @(posedge clk) - if( state == WRITE ) - Z <= AZ; - else if( state == RTI2 ) - Z <= DIMUX[1]; - else if( state == DECODE ) begin - if( plp ) - Z <= ADD[1]; - else if( (load_reg & (regsel != SEL_S)) | compare | bit_ins ) - Z <= AZ; - end - -always @(posedge clk) - if( state == WRITE ) - N <= AN; - else if( state == RTI2 ) - N <= DIMUX[7]; - else if( state == DECODE ) begin - if( plp ) - N <= ADD[7]; - else if( (load_reg & (regsel != SEL_S)) | compare ) - N <= AN; - end else if( state == FETCH && bit_ins ) - N <= DIMUX[7]; - -/* - * Update I flag - */ - -always @(posedge clk) - if( state == BRK3 ) - I <= 1; - else if( state == RTI2 ) - I <= DIMUX[2]; - else if( state == REG ) begin - if( sei ) I <= 1; - if( cli ) I <= 0; - end else if( state == DECODE ) - if( plp ) I <= ADD[2]; - -/* - * Update D flag - */ -always @(posedge clk ) - if( state == RTI2 ) - D <= DIMUX[3]; - else if( state == DECODE ) begin - if( sed ) D <= 1; - if( cld ) D <= 0; - if( plp ) D <= ADD[3]; - end - -/* - * Update V flag - */ -always @(posedge clk ) - if( state == RTI2 ) - V <= DIMUX[6]; - else if( state == DECODE ) begin - if( adc_sbc ) V <= AV; - if( clv ) V <= 0; - if( plp ) V <= ADD[6]; - end else if( state == FETCH && bit_ins ) - V <= DIMUX[6]; - -/* - * Instruction decoder - */ - -/* - * IR register/mux. Hold previous DI value in IRHOLD in PULL0 and PUSH0 - * states. In these states, the IR has been prefetched, and there is no - * time to read the IR again before the next decode. - */ - -reg RDY1 = 1; - -always @(posedge clk ) - RDY1 <= RDY; - -always @(posedge clk ) - if( ~RDY && RDY1 ) - DIHOLD <= DI; - -always @(posedge clk ) - if( reset ) - IRHOLD_valid <= 0; - else if( RDY ) begin - if( state == PULL0 || state == PUSH0 ) begin - IRHOLD <= DIMUX; - IRHOLD_valid <= 1; - end else if( state == DECODE ) - IRHOLD_valid <= 0; - end - -assign IR = (IRQ & ~I) | NMI_edge ? 8'h00 : - IRHOLD_valid ? IRHOLD : DIMUX; - -assign DIMUX = ~RDY1 ? DIHOLD : DI; - -/* - * Microcode state machine - */ -always @(posedge clk or posedge reset) - if( reset ) - state <= BRK0; - else if( RDY ) case( state ) - DECODE : - casex ( IR ) - 8'b0000_0000: state <= BRK0; - 8'b0010_0000: state <= JSR0; - 8'b0010_1100: state <= ABS0; // BIT abs - 8'b0100_0000: state <= RTI0; // - 8'b0100_1100: state <= JMP0; - 8'b0110_0000: state <= RTS0; - 8'b0110_1100: state <= JMPI0; - 8'b0x00_1000: state <= PUSH0; - 8'b0x10_1000: state <= PULL0; - 8'b0xx1_1000: state <= REG; // CLC, SEC, CLI, SEI - 8'b1xx0_00x0: state <= FETCH; // IMM - 8'b1xx0_1100: state <= ABS0; // X/Y abs - 8'b1xxx_1000: state <= REG; // DEY, TYA, ... - 8'bxxx0_0001: state <= INDX0; - 8'bxxx0_01xx: state <= ZP0; - 8'bxxx0_1001: state <= FETCH; // IMM - 8'bxxx0_1101: state <= ABS0; // even E column - 8'bxxx0_1110: state <= ABS0; // even E column - 8'bxxx1_0000: state <= BRA0; // odd 0 column - 8'bxxx1_0001: state <= INDY0; // odd 1 column - 8'bxxx1_01xx: state <= ZPX0; // odd 4,5,6,7 columns - 8'bxxx1_1001: state <= ABSX0; // odd 9 column - 8'bxxx1_11xx: state <= ABSX0; // odd C, D, E, F columns - 8'bxxxx_1010: state <= REG; // A, TXA, ... NOP - endcase - - ZP0 : state <= write_back ? READ : FETCH; - - ZPX0 : state <= ZPX1; - ZPX1 : state <= write_back ? READ : FETCH; - - ABS0 : state <= ABS1; - ABS1 : state <= write_back ? READ : FETCH; - - ABSX0 : state <= ABSX1; - ABSX1 : state <= (CO | store | write_back) ? ABSX2 : FETCH; - ABSX2 : state <= write_back ? READ : FETCH; - - INDX0 : state <= INDX1; - INDX1 : state <= INDX2; - INDX2 : state <= INDX3; - INDX3 : state <= FETCH; - - INDY0 : state <= INDY1; - INDY1 : state <= INDY2; - INDY2 : state <= (CO | store) ? INDY3 : FETCH; - INDY3 : state <= FETCH; - - READ : state <= WRITE; - WRITE : state <= FETCH; - FETCH : state <= DECODE; - - REG : state <= DECODE; - - PUSH0 : state <= PUSH1; - PUSH1 : state <= DECODE; - - PULL0 : state <= PULL1; - PULL1 : state <= PULL2; - PULL2 : state <= DECODE; - - JSR0 : state <= JSR1; - JSR1 : state <= JSR2; - JSR2 : state <= JSR3; - JSR3 : state <= FETCH; - - RTI0 : state <= RTI1; - RTI1 : state <= RTI2; - RTI2 : state <= RTI3; - RTI3 : state <= RTI4; - RTI4 : state <= DECODE; - - RTS0 : state <= RTS1; - RTS1 : state <= RTS2; - RTS2 : state <= RTS3; - RTS3 : state <= FETCH; - - BRA0 : state <= cond_true ? BRA1 : DECODE; - BRA1 : state <= (CO ^ backwards) ? BRA2 : DECODE; - BRA2 : state <= DECODE; - - JMP0 : state <= JMP1; - JMP1 : state <= DECODE; - - JMPI0 : state <= JMPI1; - JMPI1 : state <= JMP0; - - BRK0 : state <= BRK1; - BRK1 : state <= BRK2; - BRK2 : state <= BRK3; - BRK3 : state <= JMP0; - - endcase - -/* - * Additional control signals - */ - -always @(posedge clk) - if( reset ) - res <= 1; - else if( state == DECODE ) - res <= 0; - -always @(posedge clk) - if( state == DECODE && RDY ) - casex( IR ) - 8'b0xx01010, // ASLA, ROLA, LSRA, RORA - 8'b0xxxxx01, // ORA, AND, EOR, ADC - 8'b100x10x0, // DEY, TYA, TXA, TXS - 8'b1010xxx0, // LDA/LDX/LDY - 8'b10111010, // TSX - 8'b1011x1x0, // LDX/LDY - 8'b11001010, // DEX - 8'b1x1xxx01, // LDA, SBC - 8'bxxx01000: // DEY, TAY, INY, INX - load_reg <= 1; - - default: load_reg <= 0; - endcase - -always @(posedge clk) - if( state == DECODE && RDY ) - casex( IR ) - 8'b1110_1000, // INX - 8'b1100_1010, // DEX - 8'b101x_xx10: // LDX, TAX, TSX - dst_reg <= SEL_X; - - 8'b0x00_1000, // PHP, PHA - 8'b1001_1010: // TXS - dst_reg <= SEL_S; - - 8'b1x00_1000, // DEY, DEX - 8'b101x_x100, // LDY - 8'b1010_x000: // LDY #imm, TAY - dst_reg <= SEL_Y; - - default: dst_reg <= SEL_A; - endcase - -always @(posedge clk) - if( state == DECODE && RDY ) - casex( IR ) - 8'b1011_1010: // TSX - src_reg <= SEL_S; - - 8'b100x_x110, // STX - 8'b100x_1x10, // TXA, TXS - 8'b1110_xx00, // INX, CPX - 8'b1100_1010: // DEX - src_reg <= SEL_X; - - 8'b100x_x100, // STY - 8'b1001_1000, // TYA - 8'b1100_xx00, // CPY - 8'b1x00_1000: // DEY, INY - src_reg <= SEL_Y; - - default: src_reg <= SEL_A; - endcase - -always @(posedge clk) - if( state == DECODE && RDY ) - casex( IR ) - 8'bxxx1_0001, // INDY - 8'b10x1_x110, // LDX/STX zpg/abs, Y - 8'bxxxx_1001: // abs, Y - index_y <= 1; - - default: index_y <= 0; - endcase - - -always @(posedge clk) - if( state == DECODE && RDY ) - casex( IR ) - 8'b100x_x1x0, // STX, STY - 8'b100x_xx01: // STA - store <= 1; - - default: store <= 0; - - endcase - -always @(posedge clk ) - if( state == DECODE && RDY ) - casex( IR ) - 8'b0xxx_x110, // ASL, ROL, LSR, ROR - 8'b11xx_x110: // DEC/INC - write_back <= 1; - - default: write_back <= 0; - endcase - - -always @(posedge clk ) - if( state == DECODE && RDY ) - casex( IR ) - 8'b101x_xxxx: // LDA, LDX, LDY - load_only <= 1; - default: load_only <= 0; - endcase - -always @(posedge clk ) - if( state == DECODE && RDY ) - casex( IR ) - 8'b111x_x110, // INC - 8'b11x0_1000: // INX, INY - inc <= 1; - - default: inc <= 0; - endcase - -always @(posedge clk ) - if( (state == DECODE || state == BRK0) && RDY ) - casex( IR ) - 8'bx11x_xx01: // SBC, ADC - adc_sbc <= 1; - - default: adc_sbc <= 0; - endcase - -always @(posedge clk ) - if( (state == DECODE || state == BRK0) && RDY ) - casex( IR ) - 8'b011x_xx01: // ADC - adc_bcd <= D; - - default: adc_bcd <= 0; - endcase - -always @(posedge clk ) - if( state == DECODE && RDY ) - casex( IR ) - 8'b0xxx_x110, // ASL, ROL, LSR, ROR (abs, absx, zpg, zpgx) - 8'b0xxx_1010: // ASL, ROL, LSR, ROR (acc) - shift <= 1; - - default: shift <= 0; - endcase - -always @(posedge clk ) - if( state == DECODE && RDY ) - casex( IR ) - 8'b11x0_0x00, // CPX, CPY (imm/zp) - 8'b11x0_1100, // CPX, CPY (abs) - 8'b110x_xx01: // CMP - compare <= 1; - - default: compare <= 0; - endcase - -always @(posedge clk ) - if( state == DECODE && RDY ) - casex( IR ) - 8'b01xx_xx10: // ROR, LSR - shift_right <= 1; - - default: shift_right <= 0; - endcase - -always @(posedge clk ) - if( state == DECODE && RDY ) - casex( IR ) - 8'b0x1x_1010, // ROL A, ROR A - 8'b0x1x_x110: // ROR, ROL - rotate <= 1; - - default: rotate <= 0; - endcase - -always @(posedge clk ) - if( state == DECODE && RDY ) - casex( IR ) - 8'b00xx_xx10: // ROL, ASL - op <= OP_ROL; - - 8'b0010_x100: // BIT zp/abs - op <= OP_AND; - - 8'b01xx_xx10: // ROR, LSR - op <= OP_A; - - 8'b1000_1000, // DEY - 8'b1100_1010, // DEX - 8'b110x_x110, // DEC - 8'b11xx_xx01, // CMP, SBC - 8'b11x0_0x00, // CPX, CPY (imm, zpg) - 8'b11x0_1100: op <= OP_SUB; - - 8'b010x_xx01, // EOR - 8'b00xx_xx01: // ORA, AND - op <= { 2'b11, IR[6:5] }; - - default: op <= OP_ADD; - endcase - -always @(posedge clk ) - if( state == DECODE && RDY ) - casex( IR ) - 8'b0010_x100: // BIT zp/abs - bit_ins <= 1; - - default: bit_ins <= 0; - endcase - -/* - * special instructions - */ -always @(posedge clk ) - if( state == DECODE && RDY ) begin - php <= (IR == 8'h08); - clc <= (IR == 8'h18); - plp <= (IR == 8'h28); - sec <= (IR == 8'h38); - cli <= (IR == 8'h58); - sei <= (IR == 8'h78); - clv <= (IR == 8'hb8); - cld <= (IR == 8'hd8); - sed <= (IR == 8'hf8); - brk <= (IR == 8'h00); - end - -always @(posedge clk) - if( RDY ) - cond_code <= IR[7:5]; - -always @* - case( cond_code ) - 3'b000: cond_true = ~N; - 3'b001: cond_true = N; - 3'b010: cond_true = ~V; - 3'b011: cond_true = V; - 3'b100: cond_true = ~C; - 3'b101: cond_true = C; - 3'b110: cond_true = ~Z; - 3'b111: cond_true = Z; - endcase - - -reg NMI_1 = 0; // delayed NMI signal - -always @(posedge clk) - NMI_1 <= NMI; - -always @(posedge clk ) - if( NMI_edge && state == BRK3 ) - NMI_edge <= 0; - else if( NMI & ~NMI_1 ) - NMI_edge <= 1; - -endmodule diff --git a/Console_MiST/Supervision_MiST/rtl/65c02/cpu_65c02.v b/Console_MiST/Supervision_MiST/rtl/65c02/cpu_65c02.v deleted file mode 100644 index a0f0c731..00000000 --- a/Console_MiST/Supervision_MiST/rtl/65c02/cpu_65c02.v +++ /dev/null @@ -1,1395 +0,0 @@ -/* - * verilog model of 65C02 CPU. - * - * Based on original 6502 "Arlet 6502 Core" by Arlet Ottens - * - * (C) Arlet Ottens, - * - * Feel free to use this code in any project (commercial or not), as long as you - * keep this message, and the copyright notice. This code is provided "as is", - * without any warranties of any kind. - * - * Support for 65C02 instructions and addressing modes by David Banks and Ed Spittles - * - * (C) 2016 David Banks and Ed Spittles - * - * Feel free to use this code in any project (commercial or not), as long as you - * keep this message, and the copyright notice. This code is provided "as is", - * without any warranties of any kind. - * - */ - -/* - * Note that not all 6502 interface signals are supported (yet). The goal - * is to create an Acorn Atom model, and the Atom didn't use all signals on - * the main board. - * - * The data bus is implemented as separate read/write buses. Combine them - * on the output pads if external memory is required. - */ - -/* - * Two things were needed to correctly implement 65C02 NOPs - * 1. Ensure the microcode state machine uses an appropriate addressing mode for the opcode length - * 2. Ensure there are no side-effects (e.g. register updates, memory stores, etc) - * - * If IMPLEMENT_NOPS is defined, the state machine is modified accordingly. - */ - -`define IMPLEMENT_NOPS - -/* - * Two things were needed to correctly implement 65C02 BCD arithmentic - * 1. The Z flag needs calculating over the BCD adjusted ALU output - * 2. The N flag needs calculating over the BCD adjusted ALU output - * - * If IMPLEMENT_CORRECT_BCD_FLAGS is defined, this additional logic is added - */ - -// `define IMPLEMENT_CORRECT_BCD_FLAGS - -module cpu_65c02( clk, reset, AB, DI, DO, WE, IRQ, NMI, RDY ); - -input clk; // CPU clock -input reset; // reset signal -output reg [15:0] AB; // address bus -input [7:0] DI; // data in, read bus -output [7:0] DO; // data out, write bus -output WE; // write enable -input IRQ; // interrupt request -input NMI; // non-maskable interrupt request -input RDY; // Ready signal. Pauses CPU when RDY=0 - -/* - * internal signals - */ - -reg [15:0] PC; // Program Counter -reg [7:0] ABL; // Address Bus Register LSB -reg [7:0] ABH; // Address Bus Register MSB -wire [7:0] ADD; // Adder Hold Register (registered in ALU) - -reg [7:0] DIHOLD; // Hold for Data In -reg DIHOLD_valid; // -wire [7:0] DIMUX; // - -reg [7:0] IRHOLD; // Hold for Instruction register -reg IRHOLD_valid; // Valid instruction in IRHOLD - -reg [7:0] AXYS[3:0]; // A, X, Y and S register file - -reg C = 0; // carry flag (init at zero to avoid X's in ALU sim) -reg Z = 0; // zero flag -reg I = 0; // interrupt flag -reg D = 0; // decimal flag -reg V = 0; // overflow flag -reg N = 0; // negative flag -wire AZ; // ALU Zero flag -wire AZ1; // ALU Zero flag (BCD adjusted) -reg AZ2; // ALU Second Zero flag, set using TSB/TRB semantics -wire AV; // ALU overflow flag -wire AN; // ALU negative flag -wire AN1; // ALU negative flag (BCD adjusted) -wire HC; // ALU half carry - -reg [7:0] AI; // ALU Input A -reg [7:0] BI; // ALU Input B -wire [7:0] DI; // Data In -wire [7:0] IR; // Instruction register -reg [7:0] DO; // Data Out -wire [7:0] AO; // ALU output after BCD adjustment -reg WE; // Write Enable -reg CI; // Carry In -wire CO; // Carry Out -wire [7:0] PCH = PC[15:8]; -wire [7:0] PCL = PC[7:0]; - -reg NMI_edge = 0; // captured NMI edge - -reg [1:0] regsel; // Select A, X, Y or S register -wire [7:0] regfile = AXYS[regsel]; // Selected register output - -parameter - SEL_A = 2'd0, - SEL_S = 2'd1, - SEL_X = 2'd2, - SEL_Y = 2'd3; - -/* - * define some signals for watching in simulator output - */ - - -`ifdef SIM -wire [7:0] A = AXYS[SEL_A]; // Accumulator -wire [7:0] X = AXYS[SEL_X]; // X register -wire [7:0] Y = AXYS[SEL_Y]; // Y register -wire [7:0] S = AXYS[SEL_S]; // Stack pointer -`endif - -wire [7:0] P = { N, V, 2'b11, D, I, Z, C }; - -/* - * instruction decoder/sequencer - */ - -reg [5:0] state; - -/* - * control signals - */ - -reg PC_inc; // Increment PC -reg [15:0] PC_temp; // intermediate value of PC - -reg [1:0] src_reg; // source register index -reg [1:0] dst_reg; // destination register index - -reg index_y; // if set, then Y is index reg rather than X -reg load_reg; // loading a register (A, X, Y, S) in this instruction -reg inc; // increment -reg write_back; // set if memory is read/modified/written -reg load_only; // LDA/LDX/LDY instruction -reg store; // doing store (STA/STX/STY) -reg adc_sbc; // doing ADC/SBC -reg compare; // doing CMP/CPY/CPX -reg shift; // doing shift/rotate instruction -reg rotate; // doing rotate (no shift) -reg backwards; // backwards branch -reg cond_true; // branch condition is true -reg [3:0] cond_code; // condition code bits from instruction -reg shift_right; // Instruction ALU shift/rotate right -reg alu_shift_right; // Current cycle shift right enable -reg [3:0] op; // Main ALU operation for instruction -reg [3:0] alu_op; // Current cycle ALU operation -reg adc_bcd; // ALU should do BCD style carry -reg adj_bcd; // results should be BCD adjusted - -/* - * some flip flops to remember we're doing special instructions. These - * get loaded at the DECODE state, and used later - */ -reg store_zero; // doing STZ instruction -reg trb_ins; // doing TRB instruction -reg txb_ins; // doing TSB/TRB instruction -reg bit_ins; // doing BIT instruction -reg bit_ins_nv; // doing BIT instruction that will update the n and v flags (i.e. not BIT imm) -reg plp; // doing PLP instruction -reg php; // doing PHP instruction -reg clc; // clear carry -reg sec; // set carry -reg cld; // clear decimal -reg sed; // set decimal -reg cli; // clear interrupt -reg sei; // set interrupt -reg clv; // clear overflow -reg brk; // doing BRK - -reg res; // in reset - -/* - * ALU operations - */ - -parameter - OP_OR = 4'b1100, - OP_AND = 4'b1101, - OP_EOR = 4'b1110, - OP_ADD = 4'b0011, - OP_SUB = 4'b0111, - OP_ROL = 4'b1011, - OP_A = 4'b1111; - -/* - * Microcode state machine. Basically, every addressing mode has its own - * path through the state machine. Additional information, such as the - * operation, source and destination registers are decoded in parallel, and - * kept in separate flops. - */ - -parameter - ABS0 = 6'd0, // ABS - fetch LSB - ABS1 = 6'd1, // ABS - fetch MSB - ABSX0 = 6'd2, // ABS, X - fetch LSB and send to ALU (+X) - ABSX1 = 6'd3, // ABS, X - fetch MSB and send to ALU (+Carry) - ABSX2 = 6'd4, // ABS, X - Wait for ALU (only if needed) - BRA0 = 6'd5, // Branch - fetch offset and send to ALU (+PC[7:0]) - BRA1 = 6'd6, // Branch - fetch opcode, and send PC[15:8] to ALU - BRA2 = 6'd7, // Branch - fetch opcode (if page boundary crossed) - BRK0 = 6'd8, // BRK/IRQ - push PCH, send S to ALU (-1) - BRK1 = 6'd9, // BRK/IRQ - push PCL, send S to ALU (-1) - BRK2 = 6'd10, // BRK/IRQ - push P, send S to ALU (-1) - BRK3 = 6'd11, // BRK/IRQ - write S, and fetch @ fffe - DECODE = 6'd12, // IR is valid, decode instruction, and write prev reg - FETCH = 6'd13, // fetch next opcode, and perform prev ALU op - INDX0 = 6'd14, // (ZP,X) - fetch ZP address, and send to ALU (+X) - INDX1 = 6'd15, // (ZP,X) - fetch LSB at ZP+X, calculate ZP+X+1 - INDX2 = 6'd16, // (ZP,X) - fetch MSB at ZP+X+1 - INDX3 = 6'd17, // (ZP,X) - fetch data - INDY0 = 6'd18, // (ZP),Y - fetch ZP address, and send ZP to ALU (+1) - INDY1 = 6'd19, // (ZP),Y - fetch at ZP+1, and send LSB to ALU (+Y) - INDY2 = 6'd20, // (ZP),Y - fetch data, and send MSB to ALU (+Carry) - INDY3 = 6'd21, // (ZP),Y) - fetch data (if page boundary crossed) - JMP0 = 6'd22, // JMP - fetch PCL and hold - JMP1 = 6'd23, // JMP - fetch PCH - JMPI0 = 6'd24, // JMP IND - fetch LSB and send to ALU for delay (+0) - JMPI1 = 6'd25, // JMP IND - fetch MSB, proceed with JMP0 state - JSR0 = 6'd26, // JSR - push PCH, save LSB, send S to ALU (-1) - JSR1 = 6'd27, // JSR - push PCL, send S to ALU (-1) - JSR2 = 6'd28, // JSR - write S - JSR3 = 6'd29, // JSR - fetch MSB - PULL0 = 6'd30, // PLP/PLA/PLX/PLY - save next op in IRHOLD, send S to ALU (+1) - PULL1 = 6'd31, // PLP/PLA/PLX/PLY - fetch data from stack, write S - PULL2 = 6'd32, // PLP/PLA/PLX/PLY - prefetch op, but don't increment PC - PUSH0 = 6'd33, // PHP/PHA/PHX/PHY - send A to ALU (+0) - PUSH1 = 6'd34, // PHP/PHA/PHX/PHY - write A/P, send S to ALU (-1) - READ = 6'd35, // Read memory for read/modify/write (INC, DEC, shift) - REG = 6'd36, // Read register for reg-reg transfers - RTI0 = 6'd37, // RTI - send S to ALU (+1) - RTI1 = 6'd38, // RTI - read P from stack - RTI2 = 6'd39, // RTI - read PCL from stack - RTI3 = 6'd40, // RTI - read PCH from stack - RTI4 = 6'd41, // RTI - read PCH from stack - RTS0 = 6'd42, // RTS - send S to ALU (+1) - RTS1 = 6'd43, // RTS - read PCL from stack - RTS2 = 6'd44, // RTS - write PCL to ALU, read PCH - RTS3 = 6'd45, // RTS - load PC and increment - WRITE = 6'd46, // Write memory for read/modify/write - ZP0 = 6'd47, // Z-page - fetch ZP address - ZPX0 = 6'd48, // ZP, X - fetch ZP, and send to ALU (+X) - ZPX1 = 6'd49, // ZP, X - load from memory - IND0 = 6'd50, // (ZP) - fetch ZP address, and send to ALU (+0) - JMPIX0 = 6'd51, // JMP (,X)- fetch LSB and send to ALU (+X) - JMPIX1 = 6'd52, // JMP (,X)- fetch MSB and send to ALU (+Carry) - JMPIX2 = 6'd53; // JMP (,X)- Wait for ALU (only if needed) - -`ifdef SIM - -/* - * easy to read names in simulator output - */ -reg [8*6-1:0] statename; - -always @* - case( state ) - DECODE: statename = "DECODE"; - REG: statename = "REG"; - ZP0: statename = "ZP0"; - ZPX0: statename = "ZPX0"; - ZPX1: statename = "ZPX1"; - ABS0: statename = "ABS0"; - ABS1: statename = "ABS1"; - ABSX0: statename = "ABSX0"; - ABSX1: statename = "ABSX1"; - ABSX2: statename = "ABSX2"; - IND0: statename = "IND0"; - INDX0: statename = "INDX0"; - INDX1: statename = "INDX1"; - INDX2: statename = "INDX2"; - INDX3: statename = "INDX3"; - INDY0: statename = "INDY0"; - INDY1: statename = "INDY1"; - INDY2: statename = "INDY2"; - INDY3: statename = "INDY3"; - READ: statename = "READ"; - WRITE: statename = "WRITE"; - FETCH: statename = "FETCH"; - PUSH0: statename = "PUSH0"; - PUSH1: statename = "PUSH1"; - PULL0: statename = "PULL0"; - PULL1: statename = "PULL1"; - PULL2: statename = "PULL2"; - JSR0: statename = "JSR0"; - JSR1: statename = "JSR1"; - JSR2: statename = "JSR2"; - JSR3: statename = "JSR3"; - RTI0: statename = "RTI0"; - RTI1: statename = "RTI1"; - RTI2: statename = "RTI2"; - RTI3: statename = "RTI3"; - RTI4: statename = "RTI4"; - RTS0: statename = "RTS0"; - RTS1: statename = "RTS1"; - RTS2: statename = "RTS2"; - RTS3: statename = "RTS3"; - BRK0: statename = "BRK0"; - BRK1: statename = "BRK1"; - BRK2: statename = "BRK2"; - BRK3: statename = "BRK3"; - BRA0: statename = "BRA0"; - BRA1: statename = "BRA1"; - BRA2: statename = "BRA2"; - JMP0: statename = "JMP0"; - JMP1: statename = "JMP1"; - JMPI0: statename = "JMPI0"; - JMPI1: statename = "JMPI1"; - JMPIX0: statename = "JMPIX0"; - JMPIX1: statename = "JMPIX1"; - JMPIX2: statename = "JMPIX2"; - - endcase - -//always @( PC ) -// $display( "%t, PC:%04x IR:%02x A:%02x X:%02x Y:%02x S:%02x C:%d Z:%d V:%d N:%d P:%02x", $time, PC, IR, A, X, Y, S, C, Z, V, N, P ); - -`endif - - - -/* - * Program Counter Increment/Load. First calculate the base value in - * PC_temp. - */ -always @* - case( state ) - DECODE: if( (~I & IRQ) | NMI_edge ) - PC_temp = { ABH, ABL }; - else - PC_temp = PC; - - - JMP1, - JMPI1, - JMPIX1, - JSR3, - RTS3, - RTI4: PC_temp = { DIMUX, ADD }; - - BRA1: PC_temp = { ABH, ADD }; - - JMPIX2, - BRA2: PC_temp = { ADD, PCL }; - - BRK2: PC_temp = res ? 16'hfffc : - NMI_edge ? 16'hfffa : 16'hfffe; - - default: PC_temp = PC; - endcase - -/* - * Determine wether we need PC_temp, or PC_temp + 1 - */ -always @* - case( state ) - DECODE: if( (~I & IRQ) | NMI_edge ) - PC_inc = 0; - else - PC_inc = 1; - - ABS0, - JMPIX0, - JMPIX2, - ABSX0, - FETCH, - BRA0, - BRA2, - BRK3, - JMPI1, - JMP1, - RTI4, - RTS3: PC_inc = 1; - - JMPIX1: PC_inc = ~CO; // Don't increment PC if we are going to go through JMPIX2 - - BRA1: PC_inc = CO ^~ backwards; - - default: PC_inc = 0; - endcase - -/* - * Set new PC - */ -always @(posedge clk) - if( RDY ) - PC <= PC_temp + PC_inc; - -/* - * Address Generator - */ - -parameter - ZEROPAGE = 8'h00, - STACKPAGE = 8'h01; - -always @* - case( state ) - JMPIX1, - ABSX1, - INDX3, - INDY2, - JMP1, - JMPI1, - RTI4, - ABS1: AB = { DIMUX, ADD }; - - BRA2, - INDY3, - JMPIX2, - ABSX2: AB = { ADD, ABL }; - - BRA1: AB = { ABH, ADD }; - - JSR0, - PUSH1, - RTS0, - RTI0, - BRK0: AB = { STACKPAGE, regfile }; - - BRK1, - JSR1, - PULL1, - RTS1, - RTS2, - RTI1, - RTI2, - RTI3, - BRK2: AB = { STACKPAGE, ADD }; - - INDY1, - INDX1, - ZPX1, - INDX2: AB = { ZEROPAGE, ADD }; - - ZP0, - INDY0: AB = { ZEROPAGE, DIMUX }; - - REG, - READ, - WRITE: AB = { ABH, ABL }; - - default: AB = PC; - endcase - -/* - * ABH/ABL pair is used for registering previous address bus state. - * This can be used to keep the current address, freeing up the original - * source of the address, such as the ALU or DI. - */ -always @(posedge clk) - if( state != PUSH0 && state != PUSH1 && RDY && - state != PULL0 && state != PULL1 && state != PULL2 ) - begin - ABL <= AB[7:0]; - ABH <= AB[15:8]; - end - -/* - * Data Out MUX - */ -always @* - case( state ) - WRITE: DO = ADD; - - JSR0, - BRK0: DO = PCH; - - JSR1, - BRK1: DO = PCL; - - PUSH1: DO = php ? P : ADD; - - BRK2: DO = (IRQ | NMI_edge) ? (P & 8'b1110_1111) : P; - - default: DO = store_zero ? 0 : regfile; - endcase - -/* - * Write Enable Generator - */ - -always @* - case( state ) - BRK0, // writing to stack or memory - BRK1, - BRK2, - JSR0, - JSR1, - PUSH1, - WRITE: WE = 1; - - INDX3, // only if doing a STA, STX or STY - INDY3, - ABSX2, - ABS1, - ZPX1, - ZP0: WE = store; - - default: WE = 0; - endcase - -/* - * register file, contains A, X, Y and S (stack pointer) registers. At each - * cycle only 1 of those registers needs to be accessed, so they combined - * in a small memory, saving resources. - */ - -reg write_register; // set when register file is written - -always @* - case( state ) - DECODE: write_register = load_reg & ~plp; - - PULL1, - RTS2, - RTI3, - BRK3, - JSR0, - JSR2 : write_register = 1; - - default: write_register = 0; - endcase - -/* - * BCD adjust logic - */ - -always @(posedge clk) - adj_bcd <= adc_sbc & D; // '1' when doing a BCD instruction - -reg [3:0] ADJL; -reg [3:0] ADJH; - -// adjustment term to be added to ADD[3:0] based on the following -// adj_bcd: '1' if doing ADC/SBC with D=1 -// adc_bcd: '1' if doing ADC with D=1 -// HC : half carry bit from ALU -always @* begin - casex( {adj_bcd, adc_bcd, HC} ) - 3'b0xx: ADJL = 4'd0; // no BCD instruction - 3'b100: ADJL = 4'd10; // SBC, and digital borrow - 3'b101: ADJL = 4'd0; // SBC, but no borrow - 3'b110: ADJL = 4'd0; // ADC, but no carry - 3'b111: ADJL = 4'd6; // ADC, and decimal/digital carry - endcase -end - -// adjustment term to be added to ADD[7:4] based on the following -// adj_bcd: '1' if doing ADC/SBC with D=1 -// adc_bcd: '1' if doing ADC with D=1 -// CO : carry out bit from ALU -always @* begin - casex( {adj_bcd, adc_bcd, CO} ) - 3'b0xx: ADJH = 4'd0; // no BCD instruction - 3'b100: ADJH = 4'd10; // SBC, and digital borrow - 3'b101: ADJH = 4'd0; // SBC, but no borrow - 3'b110: ADJH = 4'd0; // ADC, but no carry - 3'b111: ADJH = 4'd6; // ADC, and decimal/digital carry - endcase -end - -assign AO = { ADD[7:4] + ADJH, ADD[3:0] + ADJL }; - -`ifdef IMPLEMENT_CORRECT_BCD_FLAGS - -assign AN1 = AO[7]; -assign AZ1 = ~|AO; - -`else - -assign AN1 = AN; -assign AZ1 = AZ; - -`endif - -/* - * write to a register. Usually this is the (BCD corrected) output of the - * ALU, but in case of the JSR0 we use the S register to temporarily store - * the PCL. This is possible, because the S register itself is stored in - * the ALU during those cycles. - */ -always @(posedge clk) - if( write_register & RDY ) - AXYS[regsel] <= (state == JSR0) ? DIMUX : AO; - -/* - * register select logic. This determines which of the A, X, Y or - * S registers will be accessed. - */ - -always @* - case( state ) - INDY1, - INDX0, - ZPX0, - JMPIX0, - ABSX0 : regsel = index_y ? SEL_Y : SEL_X; - - - DECODE : regsel = dst_reg; - - BRK0, - BRK3, - JSR0, - JSR2, - PULL0, - PULL1, - PUSH1, - RTI0, - RTI3, - RTS0, - RTS2 : regsel = SEL_S; - - default: regsel = src_reg; - endcase - -/* - * ALU - */ - -ALU ALU( .clk(clk), - .op(alu_op), - .right(alu_shift_right), - .AI(AI), - .BI(BI), - .CI(CI), - .BCD(adc_bcd & (state == FETCH)), - .CO(CO), - .OUT(ADD), - .V(AV), - .Z(AZ), - .N(AN), - .HC(HC), - .RDY(RDY) ); - -/* - * Select current ALU operation - */ - -always @* - case( state ) - READ: alu_op = op; - - BRA1: alu_op = backwards ? OP_SUB : OP_ADD; - - FETCH, - REG : alu_op = op; - - DECODE, - ABS1: alu_op = 1'bx; - - PUSH1, - BRK0, - BRK1, - BRK2, - JSR0, - JSR1: alu_op = OP_SUB; - - default: alu_op = OP_ADD; - endcase - -/* - * Determine shift right signal to ALU - */ - -always @* - if( state == FETCH || state == REG || state == READ ) - alu_shift_right = shift_right; - else - alu_shift_right = 0; - -/* - * Sign extend branch offset. - */ - -always @(posedge clk) - if( RDY ) - backwards <= DIMUX[7]; - -/* - * ALU A Input MUX - */ - -always @* - case( state ) - JSR1, - RTS1, - RTI1, - RTI2, - BRK1, - BRK2, - INDX1: AI = ADD; - - REG, - ZPX0, - INDX0, - JMPIX0, - ABSX0, - RTI0, - RTS0, - JSR0, - JSR2, - BRK0, - PULL0, - INDY1, - PUSH0, - PUSH1: AI = regfile; - - BRA0, - READ: AI = DIMUX; - - BRA1: AI = ABH; // don't use PCH in case we're - - FETCH: AI = load_only ? 0 : regfile; - - DECODE, - ABS1: AI = 8'hxx; // don't care - - default: AI = 0; - endcase - - -/* - * ALU B Input mux - */ - -always @* - case( state ) - BRA1, - RTS1, - RTI0, - RTI1, - RTI2, - INDX1, - REG, - JSR0, - JSR1, - JSR2, - BRK0, - BRK1, - BRK2, - PUSH0, - PUSH1, - PULL0, - RTS0: BI = 8'h00; - - READ: BI = txb_ins ? (trb_ins ? ~regfile : regfile) : 8'h00; - - BRA0: BI = PCL; - - DECODE, - ABS1: BI = 8'hxx; - - default: BI = DIMUX; - endcase - -/* - * ALU CI (carry in) mux - */ - -always @* - case( state ) - INDY2, - BRA1, - JMPIX1, - ABSX1: CI = CO; - - DECODE, - ABS1: CI = 1'bx; - - READ, - REG: CI = rotate ? C : - shift ? 0 : inc; - - FETCH: CI = rotate ? C : - compare ? 1 : - (shift | load_only) ? 0 : C; - - PULL0, - RTI0, - RTI1, - RTI2, - RTS0, - RTS1, - INDY0, - INDX1: CI = 1; - - default: CI = 0; - endcase - -/* - * Processor Status Register update - * - */ - -/* - * Update C flag when doing ADC/SBC, shift/rotate, compare - */ -always @(posedge clk ) - if( shift && state == WRITE ) - C <= CO; - else if( state == RTI2 ) - C <= DIMUX[0]; - else if( ~write_back && state == DECODE ) begin - if( adc_sbc | shift | compare ) - C <= CO; - else if( plp ) - C <= ADD[0]; - else begin - if( sec ) C <= 1; - if( clc ) C <= 0; - end - end - -/* - * Special Z flag got TRB/TSB - */ -always @(posedge clk) - AZ2 <= ~|(AI & regfile); - -/* - * Update Z, N flags when writing A, X, Y, Memory, or when doing compare - */ - -always @(posedge clk) - if( state == WRITE) - Z <= txb_ins ? AZ2 : AZ1; - else if( state == RTI2 ) - Z <= DIMUX[1]; - else if( state == DECODE ) begin - if( plp ) - Z <= ADD[1]; - else if( (load_reg & (regsel != SEL_S)) | compare | bit_ins ) - Z <= AZ1; - end - -always @(posedge clk) - if( state == WRITE && ~txb_ins) - N <= AN1; - else if( state == RTI2 ) - N <= DIMUX[7]; - else if( state == DECODE ) begin - if( plp ) - N <= ADD[7]; - else if( (load_reg & (regsel != SEL_S)) | compare ) - N <= AN1; - end else if( state == FETCH && bit_ins_nv ) - N <= DIMUX[7]; - -/* - * Update I flag - */ - -always @(posedge clk) - if( state == BRK3 ) - I <= 1; - else if( state == RTI2 ) - I <= DIMUX[2]; - else if( state == REG ) begin - if( sei ) I <= 1; - if( cli ) I <= 0; - end else if( state == DECODE ) - if( plp ) I <= ADD[2]; - -/* - * Update D flag - */ -always @(posedge clk ) - if( state == RTI2 ) - D <= DIMUX[3]; - else if( state == DECODE ) begin - if( sed ) D <= 1; - if( cld ) D <= 0; - if( plp ) D <= ADD[3]; - end - -/* - * Update V flag - */ -always @(posedge clk ) - if( state == RTI2 ) - V <= DIMUX[6]; - else if( state == DECODE ) begin - if( adc_sbc ) V <= AV; - if( clv ) V <= 0; - if( plp ) V <= ADD[6]; - end else if( state == FETCH && bit_ins_nv ) - V <= DIMUX[6]; - -/* - * Instruction decoder - */ - -/* - * IR register/mux. Hold previous DI value in IRHOLD in PULL0 and PUSH0 - * states. In these states, the IR has been prefetched, and there is no - * time to read the IR again before the next decode. - */ - -//reg RDY1 = 1; - -//always @(posedge clk ) -// RDY1 <= RDY; - -//always @(posedge clk ) -// if( ~RDY && RDY1 ) -// DIHOLD <= DI; - -always @(posedge clk ) - if( reset ) - IRHOLD_valid <= 0; - else if( RDY ) begin - if( state == PULL0 || state == PUSH0 ) begin - IRHOLD <= DIMUX; - IRHOLD_valid <= 1; - end else if( state == DECODE ) - IRHOLD_valid <= 0; - end - -assign IR = (IRQ & ~I) | NMI_edge ? 8'h00 : - IRHOLD_valid ? IRHOLD : DIMUX; - -//assign DIMUX = ~RDY1 ? DIHOLD : DI; - -assign DIMUX = DI; - -/* - * Microcode state machine - */ -always @(posedge clk or posedge reset) - if( reset ) - state <= BRK0; - else if( RDY ) case( state ) - DECODE : - casex ( IR ) - // TODO Review for simplifications as in verilog the first matching case has priority - 8'b0000_0000: state <= BRK0; - 8'b0010_0000: state <= JSR0; - 8'b0010_1100: state <= ABS0; // BIT abs - 8'b1001_1100: state <= ABS0; // STZ abs - 8'b000x_1100: state <= ABS0; // TSB/TRB - 8'b0100_0000: state <= RTI0; // - 8'b0100_1100: state <= JMP0; - 8'b0110_0000: state <= RTS0; - 8'b0110_1100: state <= JMPI0; - 8'b0111_1100: state <= JMPIX0; -`ifdef IMPLEMENT_NOPS - 8'bxxxx_xx11: state <= REG; // (NOP1: 3/7/B/F column) - 8'bxxx0_0010: state <= FETCH; // (NOP2: 2 column, 4 column handled correctly below) - 8'bx1x1_1100: state <= ABS0; // (NOP3: C column) -`endif - 8'b0x00_1000: state <= PUSH0; - 8'b0x10_1000: state <= PULL0; - 8'b0xx1_1000: state <= REG; // CLC, SEC, CLI, SEI - 8'b11x0_00x0: state <= FETCH; // IMM - 8'b1x10_00x0: state <= FETCH; // IMM - 8'b1xx0_1100: state <= ABS0; // X/Y abs - 8'b1xxx_1000: state <= REG; // DEY, TYA, ... - 8'bxxx0_0001: state <= INDX0; - 8'bxxx1_0010: state <= IND0; // (ZP) odd 2 column - 8'b000x_0100: state <= ZP0; // TSB/TRB - 8'bxxx0_01xx: state <= ZP0; - 8'bxxx0_1001: state <= FETCH; // IMM - 8'bxxx0_1101: state <= ABS0; // even D column - 8'bxxx0_1110: state <= ABS0; // even E column - 8'bxxx1_0000: state <= BRA0; // odd 0 column (Branches) - 8'b1000_0000: state <= BRA0; // BRA - 8'bxxx1_0001: state <= INDY0; // odd 1 column - 8'bxxx1_01xx: state <= ZPX0; // odd 4,5,6,7 columns - 8'bxxx1_1001: state <= ABSX0; // odd 9 column - 8'bx011_1100: state <= ABSX0; // C column BIT (3C), LDY (BC) - 8'bxxx1_11x1: state <= ABSX0; // odd D, F columns - 8'bxxx1_111x: state <= ABSX0; // odd E, F columns - 8'bx101_1010: state <= PUSH0; // PHX/PHY - 8'bx111_1010: state <= PULL0; // PLX/PLY - 8'bx0xx_1010: state <= REG; // A, TXA, ... NOP - 8'bxxx0_1010: state <= REG; // A, TXA, ... NOP - endcase - - ZP0 : state <= write_back ? READ : FETCH; - - ZPX0 : state <= ZPX1; - ZPX1 : state <= write_back ? READ : FETCH; - - ABS0 : state <= ABS1; - ABS1 : state <= write_back ? READ : FETCH; - - ABSX0 : state <= ABSX1; - ABSX1 : state <= (CO | store | write_back) ? ABSX2 : FETCH; - ABSX2 : state <= write_back ? READ : FETCH; - - JMPIX0 : state <= JMPIX1; - JMPIX1 : state <= CO ? JMPIX2 : JMP0; - JMPIX2 : state <= JMP0; - - IND0 : state <= INDX1; - - INDX0 : state <= INDX1; - INDX1 : state <= INDX2; - INDX2 : state <= INDX3; - INDX3 : state <= FETCH; - - INDY0 : state <= INDY1; - INDY1 : state <= INDY2; - INDY2 : state <= (CO | store) ? INDY3 : FETCH; - INDY3 : state <= FETCH; - - READ : state <= WRITE; - WRITE : state <= FETCH; - FETCH : state <= DECODE; - - REG : state <= DECODE; - - PUSH0 : state <= PUSH1; - PUSH1 : state <= DECODE; - - PULL0 : state <= PULL1; - PULL1 : state <= PULL2; - PULL2 : state <= DECODE; - - JSR0 : state <= JSR1; - JSR1 : state <= JSR2; - JSR2 : state <= JSR3; - JSR3 : state <= FETCH; - - RTI0 : state <= RTI1; - RTI1 : state <= RTI2; - RTI2 : state <= RTI3; - RTI3 : state <= RTI4; - RTI4 : state <= DECODE; - - RTS0 : state <= RTS1; - RTS1 : state <= RTS2; - RTS2 : state <= RTS3; - RTS3 : state <= FETCH; - - BRA0 : state <= cond_true ? BRA1 : DECODE; - BRA1 : state <= (CO ^ backwards) ? BRA2 : DECODE; - BRA2 : state <= DECODE; - - JMP0 : state <= JMP1; - JMP1 : state <= DECODE; - - JMPI0 : state <= JMPI1; - JMPI1 : state <= JMP0; - - BRK0 : state <= BRK1; - BRK1 : state <= BRK2; - BRK2 : state <= BRK3; - BRK3 : state <= JMP0; - - endcase - -/* - * Additional control signals - */ - -always @(posedge clk) - if( reset ) - res <= 1; - else if( state == DECODE ) - res <= 0; - -always @(posedge clk) - if( state == DECODE && RDY ) - casex( IR ) // DMB: Checked for 65C02 NOP collisions - 8'b0xx1_0010, // ORA, AND, EOR, ADC (zp) - 8'b1x11_0010, // LDA, SBC (zp) - 8'b0xxx_1010, // ASLA, INCA, ROLA, DECA, LSRA, PHY, RORA, PLY - 8'b0xxx_xx01, // ORA, AND, EOR, ADC - 8'b100x_10x0, // DEY, TYA, TXA, TXS - 8'b1010_xxx0, // LDA/LDX/LDY - 8'b1011_1010, // TSX - 8'b1011_x1x0, // LDX/LDY - 8'b1100_1010, // DEX - 8'b11x1_1010, // PHX, PLX - 8'b1x1x_xx01, // LDA, SBC - 8'bxxx0_1000: // PHP, PLP, PHA, PLA, DEY, TAY, INY, INX - load_reg <= 1; - - default: load_reg <= 0; - endcase - -always @(posedge clk) - if( state == DECODE && RDY ) - casex( IR ) - 8'b1110_1000, // INX - 8'b1100_1010, // DEX - 8'b1111_1010, // PLX - 8'b1010_0010, // LDX imm - 8'b101x_x110, // LDX - 8'b101x_1x10: // LDX, TAX, TSX - dst_reg <= SEL_X; - - 8'b0x00_1000, // PHP, PHA - 8'bx101_1010, // PHX, PHY - 8'b1001_1010: // TXS - dst_reg <= SEL_S; - - 8'b1x00_1000, // DEY, DEX - 8'b0111_1010, // PLY - 8'b101x_x100, // LDY - 8'b1010_x000: // LDY #imm, TAY - dst_reg <= SEL_Y; - - default: dst_reg <= SEL_A; - endcase - -always @(posedge clk) - if( state == DECODE && RDY ) - casex( IR ) - 8'b1011_1010: // TSX - src_reg <= SEL_S; - - 8'b100x_x110, // STX - 8'b100x_1x10, // TXA, TXS - 8'b1110_xx00, // INX, CPX - 8'b1101_1010, // PHX - 8'b1100_1010: // DEX - src_reg <= SEL_X; - - 8'b100x_x100, // STY - 8'b1001_1000, // TYA - 8'b1100_xx00, // CPY - 8'b0101_1010, // PHY - 8'b1x00_1000: // DEY, INY - src_reg <= SEL_Y; - - default: src_reg <= SEL_A; - endcase - -always @(posedge clk) - if( state == DECODE && RDY ) - casex( IR ) - 8'bxxx1_0001, // INDY - 8'b10x1_0110, // LDX zp,Y / STX zp,Y - 8'b1011_1110, // LDX abs,Y - 8'bxxxx_1001: // abs, Y - index_y <= 1; - - default: index_y <= 0; - endcase - - -always @(posedge clk) - if( state == DECODE && RDY ) - casex( IR ) // DMB: Checked for 65C02 NOP collisions - 8'b1001_0010, // STA (zp) - 8'b100x_x1x0, // STX, STY, STZ abs, STZ abs,x - 8'b011x_0100, // STZ zp, STZ zp,x - 8'b100x_xx01: // STA - store <= 1; - - default: store <= 0; - - endcase - -always @(posedge clk ) - if( state == DECODE && RDY ) - casex( IR ) // DMB: Checked for 65C02 NOP collisions - 8'b0xxx_x110, // ASL, ROL, LSR, ROR - 8'b000x_x100, // TSB/TRB - 8'b11xx_x110: // DEC/INC - write_back <= 1; - - default: write_back <= 0; - endcase - - -always @(posedge clk ) - if( state == DECODE && RDY ) - casex( IR ) - 8'b101x_xxxx: // LDA, LDX, LDY - load_only <= 1; - default: load_only <= 0; - endcase - -always @(posedge clk ) - if( state == DECODE && RDY ) - casex( IR ) - 8'b0001_1010, // INCA - 8'b111x_x110, // INC - 8'b11x0_1000: // INX, INY - inc <= 1; - - default: inc <= 0; - endcase - -always @(posedge clk ) - if( (state == DECODE || state == BRK0) && RDY ) - casex( IR ) - 8'bx111_0010, // SBC (zp), ADC (zp) - 8'bx11x_xx01: // SBC, ADC - adc_sbc <= 1; - - default: adc_sbc <= 0; - endcase - -always @(posedge clk ) - if( (state == DECODE || state == BRK0) && RDY ) - casex( IR ) - 8'b0111_0010, // ADC (zp) - 8'b011x_xx01: // ADC - adc_bcd <= D; - - default: adc_bcd <= 0; - endcase - -always @(posedge clk ) - if( state == DECODE && RDY ) - casex( IR ) - 8'b0xxx_x110, // ASL, ROL, LSR, ROR (abs, absx, zpg, zpgx) - 8'b0xx0_1010: // ASL, ROL, LSR, ROR (acc) - shift <= 1; - - default: shift <= 0; - endcase - -always @(posedge clk ) - if( state == DECODE && RDY ) - casex( IR ) - 8'b1101_0010, // CMP (zp) - 8'b11x0_0x00, // CPX, CPY (imm/zp) - 8'b11x0_1100, // CPX, CPY (abs) - 8'b110x_xx01: // CMP - compare <= 1; - - default: compare <= 0; - endcase - -always @(posedge clk ) - if( state == DECODE && RDY ) - casex( IR ) - 8'b01xx_x110, // ROR, LSR - 8'b01xx_1x10: // ROR, LSR - shift_right <= 1; - - default: shift_right <= 0; - endcase - -always @(posedge clk ) - if( state == DECODE && RDY ) - casex( IR ) - 8'b0x10_1010, // ROL A, ROR A - 8'b0x1x_x110: // ROR, ROL - rotate <= 1; - - default: rotate <= 0; - endcase - -always @(posedge clk ) - if( state == DECODE && RDY ) - casex( IR ) - 8'b0000_x100: // TSB - op <= OP_OR; - - 8'b0001_x100: // TRB - op <= OP_AND; - - 8'b00xx_x110, // ROL, ASL - 8'b00x0_1010: // ROL, ASL - op <= OP_ROL; - - 8'b1000_1001, // BIT imm - 8'b001x_x100: // BIT zp/abs/zpx/absx - op <= OP_AND; - - 8'b01xx_x110, // ROR, LSR - 8'b01xx_1x10: // ROR, LSR - op <= OP_A; - - 8'b11x1_0010, // CMP, SBC (zp) - 8'b0011_1010, // DEC A - 8'b1000_1000, // DEY - 8'b1100_1010, // DEX - 8'b110x_x110, // DEC - 8'b11xx_xx01, // CMP, SBC - 8'b11x0_0x00, // CPX, CPY (imm, zpg) - 8'b11x0_1100: op <= OP_SUB; - - 8'b00x1_0010, // ORA, AND (zp) - 8'b0x01_0010, // ORA, EOR (zp) - 8'b010x_xx01, // EOR - 8'b00xx_xx01: // ORA, AND - op <= { 2'b11, IR[6:5] }; - - default: op <= OP_ADD; - endcase - -always @(posedge clk ) - if( state == DECODE && RDY ) - casex( IR ) - 8'b001x_x100: // BIT zp/abs/zpx/absx (update N,V,Z) - {bit_ins, bit_ins_nv} <= 2'b11; - - 8'b1000_1001: // BIT imm (update Z) - {bit_ins, bit_ins_nv} <= 2'b10; - - default: // not a BIT instruction - {bit_ins, bit_ins_nv} <= 2'b00; - endcase - -always @(posedge clk ) - if( state == DECODE && RDY ) - casex( IR ) - 8'b000x_x100: // TRB/TSB - txb_ins <= 1; - - default: txb_ins <= 0; - endcase - -always @(posedge clk ) - if( state == DECODE && RDY ) - casex( IR ) - 8'b0001_x100: // TRB - trb_ins <= 1; - - default: trb_ins <= 0; - endcase - -always @(posedge clk ) - if( state == DECODE && RDY ) - casex( IR ) - 8'b1001_11x0, // STZ abs, STZ abs,x - 8'b011x_0100: // STZ zp, STZ zp,x - store_zero <= 1; - - default: store_zero <= 0; - endcase - -/* - * special instructions - */ -always @(posedge clk ) - if( state == DECODE && RDY ) begin - php <= (IR == 8'h08); - clc <= (IR == 8'h18); - plp <= (IR == 8'h28); - sec <= (IR == 8'h38); - cli <= (IR == 8'h58); - sei <= (IR == 8'h78); - clv <= (IR == 8'hb8); - cld <= (IR == 8'hd8); - sed <= (IR == 8'hf8); - brk <= (IR == 8'h00); - end - -always @(posedge clk) - if( RDY ) - cond_code <= IR[7:4]; - -always @* - case( cond_code ) - 4'b0001: cond_true = ~N; - 4'b0011: cond_true = N; - 4'b0101: cond_true = ~V; - 4'b0111: cond_true = V; - 4'b1001: cond_true = ~C; - 4'b1011: cond_true = C; - 4'b1101: cond_true = ~Z; - 4'b1111: cond_true = Z; - default: cond_true = 1; // BRA is 80 - endcase - - -reg NMI_1 = 0; // delayed NMI signal - -always @(posedge clk) - NMI_1 <= NMI; - -always @(posedge clk ) - if( NMI_edge && state == BRK3 ) - NMI_edge <= 0; - else if( NMI & ~NMI_1 ) - NMI_edge <= 1; - -endmodule diff --git a/Console_MiST/Supervision_MiST/rtl/Supervision_MiST.sv b/Console_MiST/Supervision_MiST/rtl/Supervision_MiST.sv index 2c94f913..8b4cbeb1 100644 --- a/Console_MiST/Supervision_MiST/rtl/Supervision_MiST.sv +++ b/Console_MiST/Supervision_MiST/rtl/Supervision_MiST.sv @@ -14,7 +14,6 @@ module Supervision_MiST( input SPI_SS3, input CONF_DATA0, input CLOCK_27, - output [12:0] SDRAM_A, inout [15:0] SDRAM_DQ, output SDRAM_DQML, @@ -26,60 +25,64 @@ module Supervision_MiST( output [1:0] SDRAM_BA, output SDRAM_CLK, output SDRAM_CKE + ); `include "rtl\build_id.v" localparam CONF_STR = { - "SVISION;bin;", -// "O34,Scanlines,Off,25%,50%,75%;", -// "O5,Blending,Off,On;", - "O6,Joyswap,Off,On;", - "O8,Screen Color,Green,White;", + "Supervision;;", + "F1,binsv,Load Cartridge;", +// "F2,sgbgbp,Load Palette;", + "O7,Custom Palette,Off,On;", + "O4,Flickerblend,On,Off;", + "O23,Scandoubler Fx,None,CRT 25%,CRT 50%,CRT 75%;", +// "O6,Framerate,60hz,Original;", "T0,Reset;", "V,v1.00.",`BUILD_DATE }; assign LED = ~ioctl_downl; -assign SDRAM_CLK = ~clk_sys; -assign SDRAM_CKE = 1; +wire clk_sys, clk_ram, pll_locked; -wire clk_sys, clk_vid, clk_cpu, pll_locked; -pll1 pll1( + +pll pll +( .inclk0(CLOCK_27), - .c0(clk_sys),//50 - .c1(clk_cpu),// 4 + .areset(0), + .c0(clk_ram),//64.000000 MHz Reduced 56Mhz(better Rom loading) + .c1(clk_sys), //16.000000 MHz .locked(pll_locked) - ); - -pll2 pll2( - .inclk0(CLOCK_27), - .c0(clk_vid)// 25.175 - ); +); + wire [63:0] status; wire [1:0] buttons; wire [1:0] switches; -wire ypbpr; -wire scandoublerD; -wire [3:0] audio_ch1, audio_ch2; -wire hs, vs, hb, vb; -wire blankn = ~(hb | vb); -wire [7:0] r, g, b; -wire key_strobe; -wire key_pressed; +wire [15:0] joystick_0; +wire [15:0] joystick_1; +wire scandoublerD; +wire ypbpr; +wire no_csync; +wire key_strobe; +wire key_pressed; wire [7:0] key_code; -wire [31:0] joystick_0, joystick_1; -wire [15:0] rom_addr; -wire [15:0] rom_do; + wire ioctl_downl; wire [7:0] ioctl_index; wire ioctl_wr; wire [24:0] ioctl_addr; wire [7:0] ioctl_dout; +wire ioctl_wait; +wire hs, vs; +wire hb, vb; +wire blankn = ~(hb | vb); +wire [8:0] r,g,b; +wire [15:0] audio_l, audio_r; + data_io data_io( - .clk_sys ( clk_sys ), + .clk_sys ( clk_ram ), .SPI_SCK ( SPI_SCK ), .SPI_SS2 ( SPI_SS2 ), .SPI_DI ( SPI_DI ), @@ -90,90 +93,8 @@ data_io data_io( .ioctl_dout ( ioctl_dout ) ); -reg port1_req; -sdram sdram( - .*, - .init_n ( pll_locked ), - .clk ( clk_sys ), - // port1 used for main CPU - .port1_req ( port1_req ), - .port1_ack ( ), - .port1_a ( ioctl_addr[23:1] ), - .port1_ds ( {ioctl_addr[0], ~ioctl_addr[0]} ), - .port1_we ( ioctl_downl ), - .port1_d ( {ioctl_dout, ioctl_dout} ), - .port1_q ( ), - - .cpu1_addr ( ioctl_downl ? 16'hffff : {1'b0, rom_addr[15:1]}), - .cpu1_q ( rom_do ) -); - -always @(posedge clk_sys) begin - reg ioctl_wr_last = 0; - - ioctl_wr_last <= ioctl_wr; - if (ioctl_downl) begin - if (~ioctl_wr_last && ioctl_wr) begin - port1_req <= ~port1_req; - end - end -end - -reg reset = 1; -reg rom_loaded = 0; -always @(posedge clk_sys) begin - reg ioctl_downlD; - ioctl_downlD <= ioctl_downl; - if (ioctl_downlD & ~ioctl_downl) rom_loaded <= 1; - reset <= status[0] | buttons[1] | ~rom_loaded; -end - -Supervision_Top Supervision_Top( - .clk_sys(clk_sys), - .clk_vid(clk_vid), - .clk_cpu(clk_cpu), - .reset(reset), - .hsync(hs), - .vsync(vs), - .hblank(hb), - .vblank(vb), - .white(status[8]), - .red(r), - .green(g), - .blue(b), - .joystick({m_fireA, m_fireB, m_fireC, m_fireD, m_up, m_down, m_left, m_right}), - .audio_ch1(audio_ch1), - .audio_ch2(audio_ch2), - .cpu_rom_addr(rom_addr), - .cpu_rom_data(rom_addr[0] ? rom_do[15:8] : rom_do[7:0]) -); - -mist_video #(.COLOR_DEPTH(6),.SD_HCNT_WIDTH(9)) mist_video( - .clk_sys(clk_vid), - .SPI_SCK(SPI_SCK), - .SPI_SS3(SPI_SS3), - .SPI_DI(SPI_DI), - .R(blankn ? r[7:2] : 0), - .G(blankn ? g[7:2] : 0), - .B(blankn ? b[7:2] : 0), - .HSync(~hs), - .VSync(~vs), - .VGA_R(VGA_R), - .VGA_G(VGA_G), - .VGA_B(VGA_B), - .VGA_VS(VGA_VS), - .VGA_HS(VGA_HS), - .ce_divider(1'b0), - .blend(status[5]), - .scandoubler_disable(1'b1),//scandoublerD), - .scanlines(status[4:3]), - .ypbpr(ypbpr) - ); - -user_io #( - .STRLEN(($size(CONF_STR)>>3))) -user_io( +user_io #(.STRLEN($size(CONF_STR)>>3))user_io( .clk_sys (clk_sys ), .conf_str (CONF_STR ), .SPI_CLK (SPI_SCK ), @@ -184,6 +105,7 @@ user_io( .switches (switches ), .scandoubler_disable (scandoublerD ), .ypbpr (ypbpr ), + .no_csync (no_csync ), .key_strobe (key_strobe ), .key_pressed (key_pressed ), .key_code (key_code ), @@ -191,26 +113,45 @@ user_io( .joystick_1 (joystick_1 ), .status (status ) ); + +mist_video #(.COLOR_DEPTH(6),.SD_HCNT_WIDTH(11)) mist_video( + .clk_sys(clk_sys), + .SPI_SCK(SPI_SCK), + .SPI_SS3(SPI_SS3), + .SPI_DI(SPI_DI), + .R(blankn ? r[7:2] : 0), + .G(blankn ? g[7:2] : 0), + .B(blankn ? b[7:2] : 0), + .HSync(hs), + .VSync(vs), + .VGA_R(VGA_R), + .VGA_G(VGA_G), + .VGA_B(VGA_B), + .VGA_VS(VGA_VS), + .VGA_HS(VGA_HS), + .ce_divider(1'b0), + .scandoubler_disable(scandoublerD), + .scanlines(status[3:2]), + .ypbpr(ypbpr) + ); -dac #( - .C_bits(4)) -dac_l( +dac #(16) dac_l( .clk_i(clk_sys), .res_n_i(1), - .dac_i(audio_ch1), + .dac_i(audio_l), .dac_o(AUDIO_L) ); -dac #( - .C_bits(4)) -dac_r( +dac #(16) dac_r( .clk_i(clk_sys), .res_n_i(1), - .dac_i(audio_ch2), + .dac_i(audio_r), .dac_o(AUDIO_R) ); + wire m_up, m_down, m_left, m_right, m_fireA, m_fireB, m_fireC, m_fireD, m_fireE, m_fireF; +wire m_up2, m_down2, m_left2, m_right2, m_fire2A, m_fire2B, m_fire2C, m_fire2D, m_fire2E, m_fire2F; wire m_tilt, m_coin1, m_coin2, m_coin3, m_coin4, m_one_player, m_two_players, m_three_players, m_four_players; arcade_inputs inputs ( @@ -219,10 +160,114 @@ arcade_inputs inputs ( .key_pressed ( key_pressed ), .key_code ( key_code ), .joystick_0 ( joystick_0 ), - .joyswap ( status[6] ), - .oneplayer ( 1'b1 ), + .joystick_1 ( joystick_1 ), + .joyswap ( 1'b0 ), + .oneplayer ( 1'b1 ), .controls ( {m_tilt, m_coin4, m_coin3, m_coin2, m_coin1, m_four_players, m_three_players, m_two_players, m_one_player} ), - .player1 ( {m_fireF, m_fireE, m_fireD, m_fireC, m_fireB, m_fireA, m_up, m_down, m_left, m_right} ) -); + .player1 ( {m_fireF, m_fireE, m_fireD, m_fireC, m_fireB, m_fireA, m_up, m_down, m_left, m_right} ), + .player2 ( {m_fire2F, m_fire2E, m_fire2D, m_fire2C, m_fire2B, m_fire2A, m_up2, m_down2, m_left2, m_right2} ) +); + +wire reset = status[0] | buttons[1] | rom_download; + +sv_top core( + .clk_sys (clk_sys), + .reset (reset), + .joystick ({m_coin1,m_tilt, m_fireB, m_fireA, m_up, m_down, m_left, m_right}), + .rom_dout (rom_dout), +// .compat60 (~status[6]), + .large_rom (|rom_mask[18:17]), + .hsync (hs), + .vsync (vs), + .hblank (hb), + .vblank (vb), + .audio_r (audio_r), + .audio_l (audio_l), + .pixel (pixel), + .pix_ce (ce_pix), + .addr_bus (rom_addr), + .rom_read (rom_cs) +); + + +sdram cart_rom +( + .SDRAM_DQ (SDRAM_DQ), + .SDRAM_A (SDRAM_A), + .SDRAM_DQML (SDRAM_DQML), + .SDRAM_DQMH (SDRAM_DQMH), + .SDRAM_BA (SDRAM_BA), + .SDRAM_nCS (SDRAM_nCS), + .SDRAM_nWE (SDRAM_nWE), + .SDRAM_nRAS (SDRAM_nRAS), + .SDRAM_nCAS (SDRAM_nCAS), + .SDRAM_CLK (SDRAM_CLK), + .SDRAM_CKE (SDRAM_CKE), + + .init (!pll_locked), + .clk (clk_ram), + + .ch0_addr (rom_download ? ioctl_addr : (rom_addr & rom_mask)), + .ch0_rd (rom_cs && ~rom_download), + .ch0_wr (rom_download & ioctl_wr), + .ch0_din (ioctl_dout), + .ch0_dout (rom_dout), + .ch0_busy (cart_busy) +); + +wire rom_download = (~|ioctl_index[5:0] || ioctl_index[5:0] == 1) && ioctl_downl; +wire ce_pix; +wire [7:0] rom_dout; +wire [18:0] rom_addr; +wire [1:0] last_pixel, pixel, prev_pixel; +wire rom_cs; +reg [14:0] vbuffer_addr; +wire cart_busy; +reg [18:0] rom_mask = 19'h7FFFF; + +assign ioctl_wait = cart_busy & rom_download; + +logic [127:0] user_palette = 128'hF7BEF7_E78686_7733E7_2C2C96_2020_2020; +wire [127:0] default_palette = 128'h87BA6B_6BA378_386B82_384052_0000_0000; + +logic [2:0][7:0] palette[4]; + +assign palette[0] = status[7] ? user_palette[127:104] : default_palette[127:104]; +assign palette[1] = status[7] ? user_palette[103:80] : default_palette[103:80]; +assign palette[2] = status[7] ? user_palette[79:56] : default_palette[79:56]; +assign palette[3] = status[7] ? user_palette[55:32] : default_palette[55:32]; + +always @(posedge clk_sys) begin + if (ce_pix) begin + r <= ~status[4] ? (({1'b0, palette[pixel][2]} + palette[prev_pixel][2]) >> 1'd1) : palette[pixel][2]; + g <= ~status[4] ? (({1'b0, palette[pixel][1]} + palette[prev_pixel][1]) >> 1'd1) : palette[pixel][1]; + b <= ~status[4] ? (({1'b0, palette[pixel][0]} + palette[prev_pixel][0]) >> 1'd1) : palette[pixel][0]; + last_pixel <= pixel; + + if (~vb && ~hb) + vbuffer_addr <= vbuffer_addr + 1'd1; + + if (vs) + vbuffer_addr <= 0; + end +end + +dpram #(.data_width(2), .addr_width(15)) vbuffer ( + .clock (clk_sys), + + .address_a (vbuffer_addr - 1'd1), + .data_a (last_pixel), + .wren_a (~vb && ~hb && ce_pix), + + .address_b (vbuffer_addr), + .q_b (prev_pixel) +); + +always @(posedge clk_sys) begin + if (rom_download && ioctl_wr) + rom_mask <= ioctl_addr[18:0]; +// if (palette_download) +// user_palette[{~ioctl_addr[3:0], 3'b000}+:8] <= ioctl_dout; +end endmodule \ No newline at end of file diff --git a/Console_MiST/Supervision_MiST/rtl/Supervision_Top.sv b/Console_MiST/Supervision_MiST/rtl/Supervision_Top.sv deleted file mode 100644 index bc2abce2..00000000 --- a/Console_MiST/Supervision_MiST/rtl/Supervision_Top.sv +++ /dev/null @@ -1,333 +0,0 @@ -module Supervision_Top( - input clk_sys,//50 - input clk_vid,// 25.175 - input clk_cpu,//4 - input reset, - output hsync, - output vsync, - output hblank, - output vblank, - input white, - output [7:0] red, - output [7:0] green, - output [7:0] blue, - output [3:0] audio_ch1, - output [3:0] audio_ch2, - input [7:0] joystick, - output [15:0]cpu_rom_addr, - input [7:0] cpu_rom_data -); - -reg [15:0] nmi_clk; -wire nmi = nmi_clk == 0; -always @(posedge clk_cpu) - nmi_clk <= nmi_clk + 16'b1; - -reg [7:0] sys_ctl; -reg [7:0] irq_timer; // 2023 -reg [7:0] irq_status; // 2027 ??????DT 1=expired/finished -reg irq_tim; -reg irq_dma; - -wire [15:0] cpu_addr; -wire [7:0] cpu_dout; -wire [7:0] wram_dout; -wire [7:0] vram_dout; -wire [7:0] rom_dout; -wire [7:0] sys_dout; - -reg [7:0] dma_src_lo; -reg [7:0] dma_src_hi; -reg [7:0] dma_dst_lo; -reg [7:0] dma_dst_hi; -reg [7:0] dma_length; -reg [7:0] dma_ctrl; -wire [7:0] dma_dout; -wire [13:0] dma_addr; -wire dma_busy; -wire dma_sel; -wire dma_write; - -reg [7:0] lcd_xscroll; -reg [7:0] lcd_yscroll; -reg [7:0] lcd_xsize; -reg [7:0] lcd_ysize; -wire [7:0] lcd_din; -wire lcd_pulse; -wire cpu_rdy = ~dma_busy; -wire dma_rdy = ~lcd_pulse; -wire cpu_we; -wire [15:0] lcd_addr; - -reg [7:0] ch1_freq_hi, ch1_freq_low, ch1_length, ch1_vduty; -reg [7:0] ch2_freq_hi, ch2_freq_low, ch2_length, ch2_vduty; -reg [7:0] audio_dma_addr_low, audio_dma_addr_high; -reg [7:0] audio_dma_ctrl, audio_dma_length, audio_dma_trigger; -reg [7:0] noise_ctrl, noise_freq_vol, noise_length; - -////////////////////// IRQ ////////////////////////// -reg [13:0] timer_div; - -// irq_tim -always @(posedge clk_sys) - if (sys_ctl[1]) begin // irq enable flag - if (irq_timer == 0 && ~irq_status[0]) irq_tim <= 1; - else if (sys_cs && cpu_we && AB[2:0] == 3'h3 && cpu_dout == 0) irq_tim <= 1; - else irq_tim <= 0; - end - -// irq status -always @(posedge clk_sys) - if (sys_cs && ~cpu_we && AB[2:0] == 3'h4) // write to irq timer ack - irq_status[0] <= 1'b0; - else if (irq_tim) // change status on irq - irq_status[0] <= 1'b1; - -// timer prescaler -always @(posedge clk_cpu) - if (timer_div > 0) - timer_div <= timer_div - 14'b1; - else if (sys_ctl[4]) - timer_div <= 14'h3fff; - else - timer_div <= 14'hff; - -// irq_timer -always @(posedge clk_cpu) - if (sys_cs && cpu_we && AB[2:0] == 3'h3) - irq_timer <= cpu_dout; - else if (timer_div == 0 && irq_timer > 0) - irq_timer <= irq_timer - 8'b1; - - -/////////////////////////// MEMORY MAP ///////////////////// - -// 0000 - 1FFF - WRAM -// 2000 - 202F - CTRL -// 2030 - 3FFF - CTRL - mirrors ?? -// 4000 - 5FFF - VRAM ?? -// 6000 - 7FFF - VRAM - mirrors ?? -// 8000 - BFFF - banks -// C000 - FFFF - last 16k of cartridge - - -wire wram_cs = AB ==? 16'b000x_xxxx_xxxx_xxxx; -wire lcd_cs = AB ==? 16'b0010_0000_0000_0xxx; // match 2000-2007 LCD control registers -wire dma_cs = AB ==? 16'b0010_0000_0000_1xxx; // match 2008-200F DMA control registers -wire snd_cs = AB ==? 16'b0010_0000_0001_xxxx; // match 2010-201F sound registers -wire sys_cs = AB ==? 16'b0010_0000_0010_0xxx; // match 2020-2027 sys registers -wire noi_cs = AB ==? 16'b0010_0000_0010_1xxx; // match 2028-202F sound registers (noise) -wire vram_cs = AB ==? 16'b01xx_xxxx_xxxx_xxxx; -wire rom_cs = AB ==? 16'b1xxx_xxxx_xxxx_xxxx; -wire rom_hi = AB ==? 16'b11xx_xxxx_xxxx_xxxx; - -wire [15:0] AB = dma_busy ? { 2'b0, dma_addr } : cpu_addr; - -reg [7:0] DI; - -wire [7:0] DO = dma_busy ? dma_dout : cpu_dout; -wire wram_we = wram_cs ? dma_busy ? ~dma_write : ~cpu_we : 1'b1; -wire vram_we = vram_cs ? dma_busy ? ~dma_write : ~cpu_we : 1'b1; - -wire [15:0] rom_addr = rom_hi ? AB : { sys_ctl[6:5], AB[13:0] }; - -always @(posedge clk_cpu) - DI <= sys_cs ? sys_dout : - wram_cs ? wram_dout : - vram_cs ? vram_dout : - rom_cs ? rom_dout : 8'hff; - -// write to lcd registers -always @(posedge clk_sys) - if (lcd_cs && cpu_we) begin - case (AB[1:0]) - 2'h0: lcd_xsize <= cpu_dout; - 2'h1: lcd_ysize <= cpu_dout; - 2'h2: lcd_xscroll <= cpu_dout; - 2'h3: lcd_yscroll <= cpu_dout; - endcase - end - -// write to audio registers -always @(posedge clk_sys) - if (snd_cs && cpu_we) begin - case (AB[3:0]) - 4'h0: ch1_freq_low <= cpu_dout; - 4'h1: ch1_freq_hi <= cpu_dout; - 4'h2: ch1_vduty <= cpu_dout; - 4'h3: ch1_length <= cpu_dout; - 4'h4: ch2_freq_low <= cpu_dout; - 4'h5: ch2_freq_hi <= cpu_dout; - 4'h6: ch2_vduty <= cpu_dout; - 4'h7: ch2_length <= cpu_dout; - 4'h8: audio_dma_addr_low <= cpu_dout; - 4'h9: audio_dma_addr_high <= cpu_dout; - 4'ha: audio_dma_length <= cpu_dout; - 4'hb: audio_dma_ctrl <= cpu_dout; - 4'hc: audio_dma_trigger <= cpu_dout; - endcase - end - -// write to noise registers -always @(posedge clk_sys) - if (noi_cs && cpu_we) begin - case (AB[2:0]) - 3'h0: noise_freq_vol <= cpu_dout; - 3'h1: noise_length <= cpu_dout; - 3'h2: noise_ctrl <= cpu_dout; - endcase - end - - -// write to dma registers -//CAUTION: This DMA can only be used to move data from WRAM/cartridge ROM to VRAM! -//Attempting to move data to a non-VRAM address will cause serious problems to occur. -//See my findings at the bottom of the document in the DMA timing section. - -always @(posedge clk_sys) - if (dma_cs && cpu_we) - case (AB[2:0]) - 3'h0: dma_src_lo <= cpu_dout;//DMA Source low - 3'h1: dma_src_hi <= cpu_dout;//DMA Source high - 3'h2: dma_dst_lo <= cpu_dout;//DMA Destination low - 3'h3: dma_dst_hi <= cpu_dout;//DMA Destination high - 3'h4: dma_length <= cpu_dout;//DMA Length - 3'h5: dma_ctrl <= cpu_dout;//DMA Control - default: - dma_ctrl <= 8'd0; - endcase - -// write to sys registers -always @(posedge clk_sys) - if (sys_cs && cpu_we) - case (AB[2:0]) -// 3'h3: irq_timer = cpu_dout; - 3'h6: sys_ctl <= cpu_dout; - endcase - -// read sys registers -always @(posedge clk_sys) - if (sys_cs && ~cpu_we) - case (AB[2:0]) - 3'h0: sys_dout <= { - ~joystick[7], - ~joystick[6], - ~joystick[5], - ~joystick[4], - ~joystick[3], - ~joystick[2], - ~joystick[1], - ~joystick[0] - }; - 3'h3: sys_dout <= irq_timer; - 3'h6: sys_dout <= sys_ctl; - endcase - - -//////////////////////////////////////////////// - - -//rom cart( -// .clk(clk_sys), -// .addr(rom_addr), -// .dout(rom_dout), -// .cs(~rom_cs), -// .rom_init(ioctl_download), -// .rom_init_clk(clk_sys), -// .rom_init_address(ioctl_addr), -// .rom_init_data(ioctl_dout) -//); - -assign cpu_rom_addr = rom_addr; -assign rom_dout = cpu_rom_data; - - -ram88 wram( - .clk(clk_sys), - .addr(AB[12:0]), - .din(DO), // <= cpu or dma - .dout(wram_dout), - .we(wram_we), - .cs(~wram_cs) -); - -// dual port ram -ram88 vram( - .clk(clk_sys), - .addr(AB[12:0]), - .din(DO), // <= cpu or dma - .dout(vram_dout), - .addrb(lcd_addr), - .doutb(lcd_din), - .we(vram_we), - .cs(~vram_cs) -); - -dma dma( - .clk(clk_sys), - .rdy(dma_rdy), - .irq_dma(irq_dma), - .ctrl(dma_ctrl), - .src_addr({ dma_src_hi, dma_src_lo }), - .dst_addr({ dma_dst_hi, dma_dst_lo }), - .addr(dma_addr), // => to AB - .din(DI), - .dout(dma_dout), - .length(dma_length), - .busy(dma_busy), - .sel(dma_sel), - .write(dma_write) -); - -audio audio( - .clk(clk_sys), - .CH1_freq({ ch1_freq_hi[2:0], ch1_freq_low }), - .CH1_vduty(ch1_vduty), - .CH1_length(ch1_length), - .CH2_freq({ ch2_freq_hi[2:0], ch2_freq_low }), - .CH2_vduty(ch2_vduty), - .CH2_length(ch2_length), - .DMA_addr({ audio_dma_addr_high, audio_dma_addr_low }), - .DMA_length(audio_dma_length), - .DMA_ctrl(audio_dma_ctrl), - .DMA_trigger(audio_dma_trigger), - .noise_freq_vol(noise_freq_vol), - .noise_length(noise_length), - .noise_ctrl(noise_ctrl), - .CH1(audio_ch1), - .CH2(audio_ch2) -); - -video video( - .clk(clk_vid), - .ce(sys_ctl[3]), - .white(white), - .lcd_xsize(lcd_xsize), - .lcd_ysize(lcd_ysize), - .lcd_xscroll(lcd_xscroll), - .lcd_yscroll(lcd_yscroll), - .lcd_pulse(lcd_pulse), - .addr(lcd_addr), - .data(lcd_din), - .hsync(hsync), - .vsync(vsync), - .hblank(hblank), - .vblank(vblank), - .red(red), - .green(green), - .blue(blue) -); - -cpu_65c02 cpu( - .clk(clk_cpu), - .reset(reset), - .AB(cpu_addr), - .DI(DI), - .DO(cpu_dout), - .WE(cpu_we), - .IRQ(irq_tim | irq_dma), - .NMI(nmi), - .RDY(cpu_rdy) -); - -endmodule \ No newline at end of file diff --git a/Console_MiST/Supervision_MiST/rtl/audio.sv b/Console_MiST/Supervision_MiST/rtl/audio.sv index 87272f63..390e4936 100644 --- a/Console_MiST/Supervision_MiST/rtl/audio.sv +++ b/Console_MiST/Supervision_MiST/rtl/audio.sv @@ -1,102 +1,236 @@ - module audio ( - input clk, // clk_sys + input clk, // clk_sys + input ce, + input reset, + input snd_cs, + input cpu_rwn, + input [5:0] AB, + input [7:0] dbus_in, + input [15:0] prescaler, + input adma_irq_en, - input [9:0] CH1_freq, - input [7:0] CH1_vduty, - input [7:0] CH1_length, + output reg [15:0] adma_addr, + output reg adma_irq_n, + output reg adma_read, + output [2:0] adma_bank, - input [9:0] CH2_freq, - input [7:0] CH2_vduty, - input [7:0] CH2_length, - - input [7:0] DMA_addr, - input [7:0] DMA_length, - input [7:0] DMA_ctrl, - input [7:0] DMA_trigger, - - input [7:0] noise_freq_vol, - input [7:0] noise_length, - input [7:0] noise_ctrl, - - output [3:0] CH1, - output [3:0] CH2 + output [3:0] CH1, + output [3:0] CH2 ); - +typedef enum bit[5:0] { + CH1_FREQ_LOW = 6'h10, + CH1_FREQ_HIGH = 6'h11, + CH1_VDUTY = 6'h12, + CH1_FRAME_LEN = 6'h13, + CH2_FREQ_LOW = 6'h14, + CH2_FREQ_HIGH = 6'h15, + CH2_VDUTY = 6'h16, + CH2_FRAME_LEN = 6'h17, + ADMA_ADDR_LO = 6'h18, + ADMA_ADDR_HI = 6'h19, + ADMA_LENGTH = 6'h1A, + ADMA_CONFIG = 6'h1B, + ADMA_REQ = 6'h1C, + ADMA_ACK = 6'h25, + NOISE_VDIV = 6'h28, + NOISE_LENGTH = 6'h29, + NOISE_CONFIG = 6'h2A +} apu_reg_t; reg [23:0] clk_cnt; reg pulse; -reg clk_audio; -reg [15:0] prescaler; -reg prescaler_overflow; - -// 50000/125=400/2=200 2^24/200=83886 -always @(posedge clk) - { pulse, clk_cnt } <= clk_cnt + 24'd83886; - -always @(posedge pulse) - clk_audio <= ~clk_audio; - -always @(posedge clk) - { prescaler_overflow, prescaler } <= prescaler + 16'd1; - -reg [16:0] CH1_sum, CH2_sum; -reg [16:0] CH1_dc, CH2_dc; // duty cycle +reg ch1_mute, ch2_mute, noise_mute; +reg [14:0] lfsr; +reg [10:0] ch1_freq, ch2_freq; +reg [3:0] adma_phase; +reg [7:0] adma_config, adma_length, adma_sample; +reg adma_sample_pending, adma_active; reg CH1_sw, CH2_sw; // square wave -reg [7:0] CH1_dlength, CH2_dlength, CH1_timer, CH2_timer; +reg [7:0] noise_vdiv, noise_timer, noise_config, ch1_vdiv, ch2_vdiv; +reg [7:0] CH1_dlength, CH2_dlength, ch1_timer, ch2_timer; +reg [16:0] CH1_sum, CH2_sum, noise_sum, adma_sum; -wire [3:0] CH1_out = CH1_sw ? CH1_vduty[3:0] : 4'd0; -wire [3:0] CH2_out = CH2_sw ? CH2_vduty[3:0] : 4'd0; -wire CH1_en = CH1_timer || CH1_vduty[6] ? 1'b1 : 1'b0; -wire CH2_en = CH2_timer || CH2_vduty[6] ? 1'b1 : 1'b0; -assign CH1 = CH1_en ? CH1_out : 4'd0; -assign CH2 = CH2_en ? CH2_out : 4'd0; +wire [3:0] CH1_dc, CH2_dc; // duty cycle +wire [3:0] adma_out = adma_sample_pending ? adma_sample[7:4] : adma_sample[3:0]; +wire [16:0] noise_div = (17'd8 << noise_vdiv[7:4]) - 1'd1; +wire lfsr_next = noise_config[0] ? (lfsr[14] ^ lfsr[13]) : (lfsr[6] ^ lfsr[5]); -always @(posedge clk) begin - if (prescaler_overflow && CH1_timer > 8'd0) CH1_timer <= CH1_timer - 8'd1; - if (prescaler_overflow && CH2_timer > 8'd0) CH2_timer <= CH2_length - 8'd1; - if (CH1_dlength != CH1_length) begin - CH1_dlength <= CH1_length; - CH1_timer <= CH1_length; - end - if (CH2_dlength != CH2_length) begin - CH2_dlength <= CH2_length; - CH2_timer <= CH2_length; - end +wire [3:0] CH1_out = CH1_sw ? ch1_vdiv[3:0] : 4'd0; +wire [3:0] CH2_out = CH2_sw ? ch2_vdiv[3:0] : 4'd0; +wire [3:0] noise_out = lfsr_next ? noise_vdiv[3:0] : 4'd0; + +wire CH1_en = ~ch1_mute || ch1_vdiv[6] ? 1'b1 : 1'b0; +wire CH2_en = ~ch2_mute || ch2_vdiv[6] ? 1'b1 : 1'b0; +wire noise_en = ~noise_mute || noise_config[1] ? noise_config[4] : 1'b0; + +// Clamp to 4 bits (real system had a 4 bit dac and did this) +wire [5:0] ch1_unclamped = (CH1_en ? CH1_out : 6'd0) + (adma_active && adma_config[2] ? adma_out : 6'd0) + (noise_en && noise_config[2] ? noise_out : 6'd0); +wire [5:0] ch2_unclamped = (CH2_en ? CH2_out : 6'd0) + (adma_active && adma_config[3] ? adma_out : 6'd0) + (noise_en && noise_config[3] ? noise_out : 6'd0); + +assign CH1 = |ch1_unclamped[5:4] ? 4'hF : ch1_unclamped[3:0]; +assign CH2 = |ch2_unclamped[5:4] ? 4'hF : ch2_unclamped[3:0]; + +assign adma_bank = adma_config[6:4]; + +always_comb begin + case (ch1_vdiv[5:4]) + 2'b00: CH1_dc = 4'd1; // 12.5% + 2'b01: CH1_dc = 4'd3; // 25% + 2'b10: CH1_dc = 4'd7; // 50% + 2'b11: CH1_dc = 4'd11; // 75% + endcase + + case (ch2_vdiv[5:4]) + 2'b00: CH2_dc = 4'd1; // 12.5% + 2'b01: CH2_dc = 4'd3; // 25% + 2'b10: CH2_dc = 4'd7; // 50% + 2'b11: CH2_dc = 4'd11; // 75% + endcase end -always @* - case (CH1_vduty[5:4]) - 2'b00: CH1_dc = 17'd15240; // 12.5% - 2'b01: CH1_dc = 17'd31750; // 25% - 2'b10: CH1_dc = 17'd63500; // 50% - 2'b11: CH1_dc = 17'd95250; // 75% - endcase +always_ff @(posedge clk) begin : audio_clock -always @* - case (CH2_vduty[5:4]) - 2'b00: CH2_dc = 17'd15240; // 12.5% - 2'b01: CH2_dc = 17'd31750; // 25% - 2'b10: CH2_dc = 17'd63500; // 50% - 2'b11: CH2_dc = 17'd95250; // 75% - endcase + reg sys_div; + reg ch1_clk; + reg ch2_clk; + reg [3:0] ch1_phase; + reg [3:0] ch2_phase; + reg old_ps15; -always @(posedge clk_audio) begin - CH1_sum <= CH1_sum + { 7'd0, CH1_freq }; - if (CH1_sum >= CH1_dc) begin - CH1_sum <= 17'd0; - CH1_sw = ~CH1_sw; - end + if (ce) begin // CPU CLK + + sys_div <= ~sys_div; + old_ps15 <= prescaler[15]; + + if (old_ps15 && ~prescaler[15]) begin + if (|ch1_timer) + ch1_timer <= ch1_timer - 8'd1; + if (~|ch1_timer[7:1]) + ch1_mute <= 1; + + if (|ch2_timer > 8'd0) + ch2_timer <= ch2_timer - 8'd1; + if (~|ch2_timer[7:1]) + ch2_mute <= 1; + + if (|noise_timer > 8'd0) + noise_timer <= noise_timer - 8'd1; + if (~|noise_timer[7:1]) + noise_mute <= 1; + end + + noise_sum <= noise_sum + 1'd1; + if (noise_sum >= noise_div) begin + lfsr <= {lfsr[13:0], lfsr_next}; + noise_sum <= 0; + end + + if (sys_div) begin + CH1_sum <= CH1_sum + 1'd1; + CH2_sum <= CH2_sum + 1'd1; + + if (CH1_sum == ch1_freq) begin + CH1_sum <= 0; + ch1_phase <= ch1_phase + 1'd1; + if (ch1_phase == CH1_dc) + CH1_sw <= 0; + else if (ch1_phase == 15) + CH1_sw <= 1; + end + if (CH2_sum == ch2_freq) begin + CH2_sum <= 0; + ch2_phase <= ch2_phase + 1'd1; + if (ch2_phase == CH2_dc) + CH2_sw <= 0; + else if (ch2_phase == 15) + CH2_sw <= 1; + end + end + + if (adma_read) begin + adma_read <= 0; + adma_sample <= dbus_in; + end + + if (adma_active) begin + adma_sum <= adma_sum + 1'd1; + if (adma_sum >= ((17'd256 << adma_config[1:0]) - 1'd1)) begin + adma_sum <= 0; + if (adma_sample_pending) begin + adma_sample_pending <= 0; + end else begin + adma_addr <= adma_addr + 1'd1; + adma_sample_pending <= 1; + adma_read <= 1; + adma_phase <= adma_phase - 1'd1; + if (~|adma_phase) begin + adma_length <= adma_length - 1'd1; + if (adma_length == 1) begin + adma_read <= 0; + adma_irq_n <= 0; + adma_active <= 0; + end + end + end + end + end + + if (snd_cs) begin + if (~cpu_rwn) begin + case (AB) + CH1_FREQ_LOW: begin ch1_freq[7:0] <= dbus_in; CH1_sum <= 0; end + CH1_FREQ_HIGH: begin ch1_freq[10:8] <= dbus_in[2:0]; CH1_sum <= 0; end + CH1_VDUTY: begin ch1_vdiv <= dbus_in; if (dbus_in[6] && ch1_timer > 0) CH1_sum <= 0; end + CH1_FRAME_LEN: begin ch1_timer <= dbus_in; if (dbus_in != 0) ch1_mute <= 0; end + CH2_FREQ_LOW: begin ch2_freq[7:0] <= dbus_in; CH2_sum <= 0; end + CH2_FREQ_HIGH: begin ch2_freq[10:8] <= dbus_in[2:0]; CH2_sum <= 0; end + CH2_VDUTY: begin ch2_vdiv <= dbus_in; if (dbus_in[6] && ch2_timer > 0) CH2_sum <= 0; end + CH2_FRAME_LEN: begin ch2_timer <= dbus_in; if (dbus_in != 0) ch2_mute <= 0; end + ADMA_ADDR_LO: begin adma_addr[7:0] <= dbus_in; end + ADMA_ADDR_HI: begin adma_addr[15:8] <= dbus_in; end + ADMA_LENGTH: begin adma_length <= dbus_in; + if (adma_active) begin + if (dbus_in == 0) begin + adma_length <= 0; + adma_active <= 0; + adma_irq_n <= 0; + end + end + end + ADMA_CONFIG: begin adma_config <= dbus_in; end + ADMA_REQ: begin adma_active <= dbus_in[7]; adma_phase <= 4'd15; adma_sample <= 0; adma_read <= 1; adma_sample_pending <= 1; end + ADMA_ACK: begin adma_irq_n <= 1; end + NOISE_VDIV, 6'h2c: begin noise_vdiv <= dbus_in; end + NOISE_LENGTH, 6'h2d: begin noise_timer <= dbus_in; if (dbus_in != 0) noise_mute <= 0; end + NOISE_CONFIG, 6'h2E: begin noise_config <= dbus_in; lfsr <= 15'h7FFF; noise_sum <= 0; end + endcase + end else begin + if (AB == ADMA_ACK) + adma_irq_n <= 1; + end + end + end + + if (reset) begin + adma_sample_pending <= 0; + adma_sample <= 0; + adma_read <= 0; + ch1_mute <= 0; + ch2_mute <= 0; + noise_mute <= 0; + adma_active <= 0; + adma_irq_n <= 1; + noise_config <= 0; + noise_timer <= 0; + noise_vdiv <= 0; + ch1_vdiv <= 0; + ch2_vdiv <= 0; + ch1_freq <= 0; + ch2_freq <= 0; + ch1_timer <= 0; + ch2_timer <= 0; + end end -always @(posedge clk_audio) begin - CH2_sum <= CH2_sum + { 7'd0, CH2_freq }; - if (CH2_sum >= CH2_dc) begin - CH2_sum <= 17'd0; - CH2_sw = ~CH2_sw; - end -end - - -endmodule \ No newline at end of file +endmodule diff --git a/Console_MiST/Supervision_MiST/rtl/bram.vhd b/Console_MiST/Supervision_MiST/rtl/bram.vhd new file mode 100644 index 00000000..607e062f --- /dev/null +++ b/Console_MiST/Supervision_MiST/rtl/bram.vhd @@ -0,0 +1,236 @@ +-------------------------------------------------------------- +-- Single port Block RAM +-------------------------------------------------------------- + +LIBRARY ieee; +USE ieee.std_logic_1164.all; + +LIBRARY altera_mf; +USE altera_mf.altera_mf_components.all; + +ENTITY spram IS + generic ( + addr_width : integer := 8; + data_width : integer := 8; + mem_init_file : string := " "; + mem_name : string := "MEM" -- for InSystem Memory content editor. + ); + PORT + ( + clock : in STD_LOGIC; + address : in STD_LOGIC_VECTOR (addr_width-1 DOWNTO 0); + data : in STD_LOGIC_VECTOR (data_width-1 DOWNTO 0) := (others => '0'); + enable : in STD_LOGIC := '1'; + wren : in STD_LOGIC := '0'; + q : out STD_LOGIC_VECTOR (data_width-1 DOWNTO 0); + cs : in std_logic := '1' + ); +END spram; + + +ARCHITECTURE SYN OF spram IS +BEGIN + spram_sz : work.spram_sz + generic map(addr_width, data_width, 2**addr_width, mem_init_file, mem_name) + port map(clock,address,data,enable,wren,q,cs); +END SYN; + + +-------------------------------------------------------------- +-- Single port Block RAM with specific size +-------------------------------------------------------------- + +LIBRARY ieee; +USE ieee.std_logic_1164.all; + +LIBRARY altera_mf; +USE altera_mf.altera_mf_components.all; + +ENTITY spram_sz IS + generic ( + addr_width : integer := 8; + data_width : integer := 8; + numwords : integer := 2**8; + mem_init_file : string := " "; + mem_name : string := "MEM" -- for InSystem Memory content editor. + ); + PORT + ( + clock : in STD_LOGIC; + address : in STD_LOGIC_VECTOR (addr_width-1 DOWNTO 0); + data : in STD_LOGIC_VECTOR (data_width-1 DOWNTO 0) := (others => '0'); + enable : in STD_LOGIC := '1'; + wren : in STD_LOGIC := '0'; + q : out STD_LOGIC_VECTOR (data_width-1 DOWNTO 0); + cs : in std_logic := '1' + ); +END ENTITY; + +ARCHITECTURE SYN OF spram_sz IS + signal q0 : std_logic_vector((data_width - 1) downto 0); +BEGIN + q<= q0 when cs = '1' else (others => '1'); + + altsyncram_component : altsyncram + GENERIC MAP ( + clock_enable_input_a => "BYPASS", + clock_enable_output_a => "BYPASS", + intended_device_family => "Cyclone III", + lpm_hint => "ENABLE_RUNTIME_MOD=YES,INSTANCE_NAME="&mem_name, + lpm_type => "altsyncram", + numwords_a => numwords, + operation_mode => "SINGLE_PORT", + outdata_aclr_a => "NONE", + outdata_reg_a => "UNREGISTERED", + power_up_uninitialized => "FALSE", + read_during_write_mode_port_a => "NEW_DATA_NO_NBE_READ", + init_file => mem_init_file, + widthad_a => addr_width, + width_a => data_width, + width_byteena_a => 1 + ) + PORT MAP ( + address_a => address, + clock0 => clock, + data_a => data, + wren_a => wren and cs, + q_a => q0 + ); + +END SYN; + +-------------------------------------------------------------- +-- Dual port Block RAM same parameters on both ports +-------------------------------------------------------------- +LIBRARY ieee; +USE ieee.std_logic_1164.all; + +LIBRARY altera_mf; +USE altera_mf.altera_mf_components.all; + +entity dpram is + generic ( + addr_width : integer := 8; + data_width : integer := 8; + mem_init_file : string := " " + ); + PORT + ( + clock : in STD_LOGIC; + + address_a : in STD_LOGIC_VECTOR (addr_width-1 DOWNTO 0); + data_a : in STD_LOGIC_VECTOR (data_width-1 DOWNTO 0) := (others => '0'); + enable_a : in STD_LOGIC := '1'; + wren_a : in STD_LOGIC := '0'; + q_a : out STD_LOGIC_VECTOR (data_width-1 DOWNTO 0); + cs_a : in std_logic := '1'; + + address_b : in STD_LOGIC_VECTOR (addr_width-1 DOWNTO 0) := (others => '0'); + data_b : in STD_LOGIC_VECTOR (data_width-1 DOWNTO 0) := (others => '0'); + enable_b : in STD_LOGIC := '1'; + wren_b : in STD_LOGIC := '0'; + q_b : out STD_LOGIC_VECTOR (data_width-1 DOWNTO 0); + cs_b : in std_logic := '1' + ); +end entity; + + +ARCHITECTURE SYN OF dpram IS +BEGIN + ram : work.dpram_dif generic map(addr_width,data_width,addr_width,data_width,mem_init_file) + port map(clock,address_a,data_a,enable_a,wren_a,q_a,cs_a,address_b,data_b,enable_b,wren_b,q_b,cs_b); +END SYN; + +-------------------------------------------------------------- +-- Dual port Block RAM different parameters on ports +-------------------------------------------------------------- +LIBRARY ieee; +USE ieee.std_logic_1164.all; + +LIBRARY altera_mf; +USE altera_mf.altera_mf_components.all; + +entity dpram_dif is + generic ( + addr_width_a : integer := 8; + data_width_a : integer := 8; + addr_width_b : integer := 8; + data_width_b : integer := 8; + mem_init_file : string := " " + ); + PORT + ( + clock : in STD_LOGIC; + + address_a : in STD_LOGIC_VECTOR (addr_width_a-1 DOWNTO 0); + data_a : in STD_LOGIC_VECTOR (data_width_a-1 DOWNTO 0) := (others => '0'); + enable_a : in STD_LOGIC := '1'; + wren_a : in STD_LOGIC := '0'; + q_a : out STD_LOGIC_VECTOR (data_width_a-1 DOWNTO 0); + cs_a : in std_logic := '1'; + + address_b : in STD_LOGIC_VECTOR (addr_width_b-1 DOWNTO 0) := (others => '0'); + data_b : in STD_LOGIC_VECTOR (data_width_b-1 DOWNTO 0) := (others => '0'); + enable_b : in STD_LOGIC := '1'; + wren_b : in STD_LOGIC := '0'; + q_b : out STD_LOGIC_VECTOR (data_width_b-1 DOWNTO 0); + cs_b : in std_logic := '1' + ); +end entity; + + +ARCHITECTURE SYN OF dpram_dif IS + + signal q0 : std_logic_vector((data_width_a - 1) downto 0); + signal q1 : std_logic_vector((data_width_b - 1) downto 0); + +BEGIN + q_a<= q0 when cs_a = '1' else (others => '1'); + q_b<= q1 when cs_b = '1' else (others => '1'); + + altsyncram_component : altsyncram + GENERIC MAP ( + address_reg_b => "CLOCK1", + clock_enable_input_a => "NORMAL", + clock_enable_input_b => "NORMAL", + clock_enable_output_a => "BYPASS", + clock_enable_output_b => "BYPASS", + indata_reg_b => "CLOCK1", + intended_device_family => "Cyclone III", + lpm_type => "altsyncram", + numwords_a => 2**addr_width_a, + numwords_b => 2**addr_width_b, + operation_mode => "BIDIR_DUAL_PORT", + outdata_aclr_a => "NONE", + outdata_aclr_b => "NONE", + outdata_reg_a => "UNREGISTERED", + outdata_reg_b => "UNREGISTERED", + power_up_uninitialized => "FALSE", + read_during_write_mode_port_a => "NEW_DATA_NO_NBE_READ", + read_during_write_mode_port_b => "NEW_DATA_NO_NBE_READ", + init_file => mem_init_file, + widthad_a => addr_width_a, + widthad_b => addr_width_b, + width_a => data_width_a, + width_b => data_width_b, + width_byteena_a => 1, + width_byteena_b => 1, + wrcontrol_wraddress_reg_b => "CLOCK1" + ) + PORT MAP ( + address_a => address_a, + address_b => address_b, + clock0 => clock, + clock1 => clock, + clocken0 => enable_a, + clocken1 => enable_b, + data_a => data_a, + data_b => data_b, + wren_a => wren_a and cs_a, + wren_b => wren_b and cs_b, + q_a => q0, + q_b => q1 + ); + +END SYN; + diff --git a/Console_MiST/Supervision_MiST/rtl/dma.sv b/Console_MiST/Supervision_MiST/rtl/dma.sv index b7d861b1..cd5c5fd9 100644 --- a/Console_MiST/Supervision_MiST/rtl/dma.sv +++ b/Console_MiST/Supervision_MiST/rtl/dma.sv @@ -1,77 +1,63 @@ - -module dma( - input clk, // 4 x CPU speed ? - input rdy, - output irq_dma, - input [7:0] ctrl, - input [15:0] src_addr, - input [15:0] dst_addr, - output reg [15:0] addr, - input [7:0] din, - output reg [7:0] dout, - input [7:0] length, - output busy, - output sel, // 1: src -> dst, 2: src <- dst - output write +module dma +( + input clk, + input ce, + input reset, + input [5:0] AB, + input cpu_rwn, + input dma_cs, + input lcd_en, + input [7:0] data_in, + output reg [15:0] cbus_addr, + output reg [12:0] vbus_addr, + output reg dma_dir, + output dma_en ); -reg [11:0] queue; -reg [12:0] addr_a, addr_b; -reg started; -assign irq_dma = 1'b1; + reg dma_started; + reg [7:0] dma_length; + reg [3:0] dma_phase; + reg [2:0] lcd_div; -assign sel = dst_addr[14]; -assign busy = state != DONE; -assign write = state == WRITE; -reg [1:0] state; + assign dma_en = dma_started; + wire lcd_ce = lcd_div == 5 && lcd_en; -parameter - DONE = 2'b00, - START = 2'b01, - READ = 2'b10, - WRITE = 2'b11; + always_ff @(posedge clk) begin + if (ce) begin + lcd_div <= lcd_div + 1'd1; + if (lcd_div == 5) + lcd_div <= 0; -always @(posedge clk) - started <= ctrl[7] ? 1'b1 : 1'b0; + if (dma_started && ~lcd_ce) begin + cbus_addr <= cbus_addr + 1'd1; + vbus_addr <= vbus_addr + 1'd1; + dma_phase <= dma_phase - 1'd1; + if (~|dma_phase) begin + dma_length <= dma_length - 1'd1; + if (dma_length == 1) begin + dma_started <= 0; + end + end + end -always @(posedge clk) - if (rdy) - case (state) - DONE: if (~started & ctrl[7]) state <= START; - START: state <= READ; - READ: state <= WRITE; - WRITE: state <= queue == 0 ? DONE : READ; - endcase - -always @(posedge clk) - if (rdy) - case (state) - START: queue <= { length, 4'd0 }; - WRITE: queue <= queue - 12'b1; - endcase - -always @(posedge clk) - if (rdy) - case (state) - READ: addr <= addr_a; - WRITE: addr <= addr_b; - endcase - -always @(posedge clk) - if (rdy && state == WRITE) dout <= din; - -always @(posedge clk) - if (rdy) - case (state) - START: begin - addr_a <= sel ? src_addr[12:0] : dst_addr[12:0]; - addr_b <= sel ? dst_addr[12:0] : src_addr[12:0]; - end - WRITE: begin - addr_a <= addr_a + 13'b1; - addr_b <= addr_b + 13'b1; - end - endcase - - -endmodule \ No newline at end of file + if (~cpu_rwn && dma_cs) begin + case(AB) + 6'h08: cbus_addr[7:0] <= data_in; + 6'h09: cbus_addr[15:8] <= data_in; + 6'h0A: vbus_addr[7:0] <= data_in; + 6'h0B: {dma_dir, vbus_addr[12:8]} <= {data_in[6], data_in[4:0]}; + 6'h0C: dma_length <= data_in; + 6'h0D: if (data_in[7]) begin dma_started <= 1; dma_phase <= 4'd15; end + endcase + end + end + if (reset) begin + dma_started <= 0; + dma_length <= 0; + vbus_addr <= 0; + cbus_addr <= 0; + lcd_div <= 0; + dma_dir <= 0; + end + end +endmodule \ No newline at end of file diff --git a/Console_MiST/Supervision_MiST/rtl/lcd.sv b/Console_MiST/Supervision_MiST/rtl/lcd.sv new file mode 100644 index 00000000..6ca039bd --- /dev/null +++ b/Console_MiST/Supervision_MiST/rtl/lcd.sv @@ -0,0 +1,123 @@ +module lcd +( + + input clk, + input ce, + input reset, + input lcd_cs, + input cpu_rwn, + input compat60, + input [5:0] AB, + input [7:0] dbus_in, + input [7:0] vram_data, + input lcd_off, + output ce_pix, + output reg [1:0]pixel, + output [13:0] vram_addr, + output hsync, + output vsync, + output reg hblank, + output reg vblank +); + +localparam H_WIDTH = 9'd300; +localparam H_WIDTH_COMPAT = 9'd254; +localparam V_HEIGHT = 9'd262; +localparam PHYS_WIDTH = 9'd160; +localparam PHYS_HEIGHT = 9'd160; + +wire [8:0] h_w = compat60 ? H_WIDTH_COMPAT : H_WIDTH; + +reg [7:0] lcd_xsize, lcd_ysize, lcd_xscroll, lcd_yscroll; +reg lcd_off_latch; +reg wrapped; +reg [9:0] wrap_offset; +reg [8:0] hblank_start, hblank_end, vblank_start, vblank_end, vpos, hpos; +reg [31:0] dot_count, frame_len; + +wire [9:0] vpos_off = (vpos - vblank_end) + lcd_yscroll; +wire [9:0] hpos_off = (hpos - hblank_end) + lcd_xscroll; +wire [9:0] vpos_wrap = vpos_off > 169 && lcd_xscroll < 8'h1C ? vpos_off - 10'd170 : vpos_off; +wire [7:0] hpos_div_4 = hpos_off[9:2]; +wire [13:0] vram_addr_t = (vpos_wrap * 8'h30) + hpos_div_4; + +// The lcd does a weird trunction of any extra bits past the end of it's buffer to make the 192x170 +// dimensions work, while the memory is 8kb. This is intentionally truncated to 12 bits. + +assign vram_addr = vram_addr_t > 14'h1FE0 ? (vram_addr_t + 8'h40) : vram_addr_t[12:0]; + +initial begin + hblank_end = 8'd70; + vblank_end = 8'd51; + vpos = 0; + hpos = 0; + lcd_xsize = 8'd160; + lcd_ysize = 8'd160; + frame_len = 20'd78719; +end + +assign ce_pix = ce; + +reg [7:0] vb; + +wire hblank_im = hpos <= hblank_end || hpos > hblank_end + PHYS_WIDTH; +wire vblank_im = vpos < vblank_end || vpos >= vblank_end + PHYS_HEIGHT; +assign vsync = vpos < 2 || vpos > V_HEIGHT - 1'd1; // Catch the uneven line in vsync to see if it helps +assign hsync = hpos < 16 || hpos > (h_w - 8'd16); + + +always_ff @(posedge clk) begin + reg old_compat; + if (ce) begin + old_compat <= compat60; + hblank <= hblank_im; + vblank <= vblank_im; + pixel <= lcd_off_latch ? 2'b00 : vram_data[{hpos_off[1:0], 1'b1}-:2]; + + if (lcd_off) + lcd_off_latch <= 1; + + dot_count <= dot_count + 1'd1; + hpos <= hpos + 1'd1; + if (hpos == (h_w - 1'd1)) begin + hpos <= 0; + vpos <= vpos + 1'd1; + end + + // Synchronize with real frame, we'll see how it goes. + if ((compat60 ? + (hpos == (h_w - 1'd1) && vpos == (V_HEIGHT - 1'd1)) : + (dot_count >= frame_len) + ) || (old_compat != compat60)) begin + hpos <= 0; + vpos <= 0; + dot_count <= 0; + hblank_end <= (h_w - PHYS_WIDTH) >> 1'd1; + vblank_end <= (V_HEIGHT - PHYS_HEIGHT) >> 1'd1; + lcd_off_latch <= lcd_off; + frame_len <= ((lcd_xsize[7:2] + 1'd1) * lcd_ysize * 12) - 1'd1; + end + + if (lcd_cs && ~cpu_rwn) begin + case(AB) + 6'h00, 6'h04: lcd_xsize <= dbus_in; + 6'h01, 6'h05: lcd_ysize <= dbus_in; + 6'h02, 6'h06: lcd_xscroll <= dbus_in; + 6'h03, 6'h07: lcd_yscroll <= dbus_in; + endcase + end + end + + if (reset) begin + lcd_xscroll <= 0; + lcd_yscroll <= 0; + hblank_end <= (h_w - lcd_xsize) >> 1'd1; + vblank_end <= (V_HEIGHT - lcd_ysize) >> 1'd1; + lcd_off_latch <= 1; + // Do not reset these registers intentionally + // lcd_xsize <= 8'd160; + // lcd_ysize <= 8'd160; + end +end + +endmodule \ No newline at end of file diff --git a/Console_MiST/Supervision_MiST/rtl/pll2.qip b/Console_MiST/Supervision_MiST/rtl/pll.qip similarity index 62% rename from Console_MiST/Supervision_MiST/rtl/pll2.qip rename to Console_MiST/Supervision_MiST/rtl/pll.qip index 75328294..48665362 100644 --- a/Console_MiST/Supervision_MiST/rtl/pll2.qip +++ b/Console_MiST/Supervision_MiST/rtl/pll.qip @@ -1,4 +1,4 @@ set_global_assignment -name IP_TOOL_NAME "ALTPLL" set_global_assignment -name IP_TOOL_VERSION "13.1" -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "pll2.v"] -set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll2.ppf"] +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "pll.vhd"] +set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll.ppf"] diff --git a/Console_MiST/Supervision_MiST/rtl/pll.vhd b/Console_MiST/Supervision_MiST/rtl/pll.vhd new file mode 100644 index 00000000..4538cd72 --- /dev/null +++ b/Console_MiST/Supervision_MiST/rtl/pll.vhd @@ -0,0 +1,397 @@ +-- megafunction wizard: %ALTPLL% +-- GENERATION: STANDARD +-- VERSION: WM1.0 +-- MODULE: altpll + +-- ============================================================ +-- File Name: pll.vhd +-- Megafunction Name(s): +-- altpll +-- +-- Simulation Library Files(s): +-- altera_mf +-- ============================================================ +-- ************************************************************ +-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! +-- +-- 13.1.4 Build 182 03/12/2014 SJ Full Version +-- ************************************************************ + + +--Copyright (C) 1991-2014 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 pll IS + PORT + ( + areset : IN STD_LOGIC := '0'; + inclk0 : IN STD_LOGIC := '0'; + c0 : OUT STD_LOGIC ; + c1 : OUT STD_LOGIC ; + locked : OUT STD_LOGIC + ); +END pll; + + +ARCHITECTURE SYN OF pll 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_VECTOR (1 DOWNTO 0); + SIGNAL sub_wire6_bv : BIT_VECTOR (0 DOWNTO 0); + SIGNAL sub_wire6 : 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; + compensate_clock : 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 + ); + PORT ( + areset : IN STD_LOGIC ; + clk : OUT STD_LOGIC_VECTOR (4 DOWNTO 0); + inclk : IN STD_LOGIC_VECTOR (1 DOWNTO 0); + locked : OUT STD_LOGIC + ); + END COMPONENT; + +BEGIN + sub_wire6_bv(0 DOWNTO 0) <= "0"; + sub_wire6 <= To_stdlogicvector(sub_wire6_bv); + sub_wire3 <= sub_wire0(0); + sub_wire1 <= sub_wire0(1); + c1 <= sub_wire1; + locked <= sub_wire2; + c0 <= sub_wire3; + sub_wire4 <= inclk0; + sub_wire5 <= sub_wire6(0 DOWNTO 0) & sub_wire4; + + altpll_component : altpll + GENERIC MAP ( + bandwidth_type => "AUTO", + clk0_divide_by => 27, + clk0_duty_cycle => 50, + clk0_multiply_by => 56, + clk0_phase_shift => "0", + clk1_divide_by => 27, + clk1_duty_cycle => 50, + clk1_multiply_by => 16, + clk1_phase_shift => "0", + compensate_clock => "CLK0", + inclk0_input_frequency => 37037, + intended_device_family => "Cyclone III", + lpm_hint => "CBX_MODULE_PREFIX=pll", + lpm_type => "altpll", + operation_mode => "NORMAL", + 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_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_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 + ) + PORT MAP ( + areset => areset, + inclk => sub_wire5, + 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 "0" +-- Retrieval info: PRIVATE: CREATE_CLKBAD_CHECK STRING "0" +-- Retrieval info: PRIVATE: CREATE_INCLK1_CHECK STRING "0" +-- Retrieval info: PRIVATE: CUR_DEDICATED_CLK STRING "c0" +-- Retrieval info: PRIVATE: CUR_FBIN_CLK STRING "c0" +-- Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "8" +-- Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "27" +-- Retrieval info: PRIVATE: DIV_FACTOR1 NUMERIC "27" +-- Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000" +-- Retrieval info: PRIVATE: DUTY_CYCLE1 STRING "50.00000000" +-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "56.000000" +-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE1 STRING "16.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 "27.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 "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: MULT_FACTOR0 NUMERIC "56" +-- Retrieval info: PRIVATE: MULT_FACTOR1 NUMERIC "16" +-- Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1" +-- Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "56.00000000" +-- Retrieval info: PRIVATE: OUTPUT_FREQ1 STRING "16.00000000" +-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "0" +-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE1 STRING "0" +-- Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz" +-- Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT1 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_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: 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 "pll.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: 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_CLKENA0 STRING "0" +-- Retrieval info: PRIVATE: USE_CLKENA1 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 "27" +-- Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50" +-- Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "56" +-- Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0" +-- Retrieval info: CONSTANT: CLK1_DIVIDE_BY NUMERIC "27" +-- 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: COMPENSATE_CLOCK STRING "CLK0" +-- Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "37037" +-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III" +-- Retrieval info: CONSTANT: LPM_TYPE STRING "altpll" +-- Retrieval info: CONSTANT: OPERATION_MODE STRING "NORMAL" +-- 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_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_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: 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: c1 0 0 0 0 OUTPUT_CLK_EXT VCC "c1" +-- Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT_CLK_EXT GND "inclk0" +-- Retrieval info: USED_PORT: locked 0 0 0 0 OUTPUT GND "locked" +-- Retrieval info: CONNECT: @areset 0 0 0 0 areset 0 0 0 0 +-- Retrieval info: CONNECT: @inclk 0 0 1 1 GND 0 0 0 0 +-- Retrieval info: CONNECT: @inclk 0 0 1 0 inclk0 0 0 0 0 +-- Retrieval info: CONNECT: c0 0 0 0 0 @clk 0 0 1 0 +-- Retrieval info: CONNECT: c1 0 0 0 0 @clk 0 0 1 1 +-- Retrieval info: CONNECT: locked 0 0 0 0 @locked 0 0 0 0 +-- Retrieval info: GEN_FILE: TYPE_NORMAL pll.vhd TRUE +-- Retrieval info: GEN_FILE: TYPE_NORMAL pll.ppf TRUE +-- Retrieval info: GEN_FILE: TYPE_NORMAL pll.inc FALSE +-- Retrieval info: GEN_FILE: TYPE_NORMAL pll.cmp FALSE +-- Retrieval info: GEN_FILE: TYPE_NORMAL pll.bsf FALSE +-- Retrieval info: GEN_FILE: TYPE_NORMAL pll_inst.vhd FALSE +-- Retrieval info: LIB_FILE: altera_mf +-- Retrieval info: CBX_MODULE_PREFIX: ON diff --git a/Console_MiST/Supervision_MiST/rtl/pll1.v b/Console_MiST/Supervision_MiST/rtl/pll1.v deleted file mode 100644 index bfd5fd25..00000000 --- a/Console_MiST/Supervision_MiST/rtl/pll1.v +++ /dev/null @@ -1,348 +0,0 @@ -// megafunction wizard: %ALTPLL% -// GENERATION: STANDARD -// VERSION: WM1.0 -// MODULE: altpll - -// ============================================================ -// File Name: pll1.v -// Megafunction Name(s): -// altpll -// -// Simulation Library Files(s): -// altera_mf -// ============================================================ -// ************************************************************ -// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! -// -// 13.1.4 Build 182 03/12/2014 SJ Full Version -// ************************************************************ - - -//Copyright (C) 1991-2014 Altera Corporation -//Your use of Altera Corporation's design tools, logic functions -//and other software and tools, and its AMPP partner logic -//functions, and any output files from any of the foregoing -//(including device programming or simulation files), and any -//associated documentation or information are expressly subject -//to the terms and conditions of the Altera Program License -//Subscription Agreement, Altera MegaCore Function License -//Agreement, or other applicable license agreement, including, -//without limitation, that your use is for the sole purpose of -//programming logic devices manufactured by Altera and sold by -//Altera or its authorized distributors. Please refer to the -//applicable agreement for further details. - - -// synopsys translate_off -`timescale 1 ps / 1 ps -// synopsys translate_on -module pll1 ( - areset, - inclk0, - c0, - c1, - locked); - - input areset; - input inclk0; - output c0; - output c1; - output locked; -`ifndef ALTERA_RESERVED_QIS -// synopsys translate_off -`endif - tri0 areset; -`ifndef ALTERA_RESERVED_QIS -// synopsys translate_on -`endif - - wire [4:0] sub_wire0; - wire sub_wire2; - wire [0:0] sub_wire6 = 1'h0; - wire [0:0] sub_wire3 = sub_wire0[0:0]; - wire [1:1] sub_wire1 = sub_wire0[1:1]; - wire c1 = sub_wire1; - wire locked = sub_wire2; - wire c0 = sub_wire3; - wire sub_wire4 = inclk0; - wire [1:0] sub_wire5 = {sub_wire6, sub_wire4}; - - altpll altpll_component ( - .areset (areset), - .inclk (sub_wire5), - .clk (sub_wire0), - .locked (sub_wire2), - .activeclock (), - .clkbad (), - .clkena ({6{1'b1}}), - .clkloss (), - .clkswitch (1'b0), - .configupdate (1'b0), - .enable0 (), - .enable1 (), - .extclk (), - .extclkena ({4{1'b1}}), - .fbin (1'b1), - .fbmimicbidir (), - .fbout (), - .fref (), - .icdrclk (), - .pfdena (1'b1), - .phasecounterselect ({4{1'b1}}), - .phasedone (), - .phasestep (1'b1), - .phaseupdown (1'b1), - .pllena (1'b1), - .scanaclr (1'b0), - .scanclk (1'b0), - .scanclkena (1'b1), - .scandata (1'b0), - .scandataout (), - .scandone (), - .scanread (1'b0), - .scanwrite (1'b0), - .sclkout0 (), - .sclkout1 (), - .vcooverrange (), - .vcounderrange ()); - defparam - altpll_component.bandwidth_type = "AUTO", - altpll_component.clk0_divide_by = 9, - altpll_component.clk0_duty_cycle = 50, - altpll_component.clk0_multiply_by = 20, - altpll_component.clk0_phase_shift = "0", - altpll_component.clk1_divide_by = 27, - altpll_component.clk1_duty_cycle = 50, - altpll_component.clk1_multiply_by = 4, - altpll_component.clk1_phase_shift = "0", - altpll_component.compensate_clock = "CLK0", - altpll_component.inclk0_input_frequency = 37037, - altpll_component.intended_device_family = "Cyclone III", - altpll_component.lpm_hint = "CBX_MODULE_PREFIX=pll1", - altpll_component.lpm_type = "altpll", - altpll_component.operation_mode = "NORMAL", - altpll_component.pll_type = "AUTO", - altpll_component.port_activeclock = "PORT_UNUSED", - altpll_component.port_areset = "PORT_USED", - altpll_component.port_clkbad0 = "PORT_UNUSED", - altpll_component.port_clkbad1 = "PORT_UNUSED", - altpll_component.port_clkloss = "PORT_UNUSED", - altpll_component.port_clkswitch = "PORT_UNUSED", - altpll_component.port_configupdate = "PORT_UNUSED", - altpll_component.port_fbin = "PORT_UNUSED", - altpll_component.port_inclk0 = "PORT_USED", - altpll_component.port_inclk1 = "PORT_UNUSED", - altpll_component.port_locked = "PORT_USED", - altpll_component.port_pfdena = "PORT_UNUSED", - altpll_component.port_phasecounterselect = "PORT_UNUSED", - altpll_component.port_phasedone = "PORT_UNUSED", - altpll_component.port_phasestep = "PORT_UNUSED", - altpll_component.port_phaseupdown = "PORT_UNUSED", - altpll_component.port_pllena = "PORT_UNUSED", - altpll_component.port_scanaclr = "PORT_UNUSED", - altpll_component.port_scanclk = "PORT_UNUSED", - altpll_component.port_scanclkena = "PORT_UNUSED", - altpll_component.port_scandata = "PORT_UNUSED", - altpll_component.port_scandataout = "PORT_UNUSED", - altpll_component.port_scandone = "PORT_UNUSED", - altpll_component.port_scanread = "PORT_UNUSED", - altpll_component.port_scanwrite = "PORT_UNUSED", - altpll_component.port_clk0 = "PORT_USED", - altpll_component.port_clk1 = "PORT_USED", - altpll_component.port_clk2 = "PORT_UNUSED", - altpll_component.port_clk3 = "PORT_UNUSED", - altpll_component.port_clk4 = "PORT_UNUSED", - altpll_component.port_clk5 = "PORT_UNUSED", - altpll_component.port_clkena0 = "PORT_UNUSED", - altpll_component.port_clkena1 = "PORT_UNUSED", - altpll_component.port_clkena2 = "PORT_UNUSED", - altpll_component.port_clkena3 = "PORT_UNUSED", - altpll_component.port_clkena4 = "PORT_UNUSED", - altpll_component.port_clkena5 = "PORT_UNUSED", - altpll_component.port_extclk0 = "PORT_UNUSED", - altpll_component.port_extclk1 = "PORT_UNUSED", - altpll_component.port_extclk2 = "PORT_UNUSED", - altpll_component.port_extclk3 = "PORT_UNUSED", - altpll_component.self_reset_on_loss_lock = "OFF", - altpll_component.width_clock = 5; - - -endmodule - -// ============================================================ -// CNX file retrieval info -// ============================================================ -// Retrieval info: PRIVATE: ACTIVECLK_CHECK STRING "0" -// Retrieval info: PRIVATE: BANDWIDTH STRING "1.000" -// Retrieval info: PRIVATE: BANDWIDTH_FEATURE_ENABLED STRING "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 "c0" -// Retrieval info: PRIVATE: CUR_FBIN_CLK STRING "c0" -// Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "8" -// Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "9" -// Retrieval info: PRIVATE: DIV_FACTOR1 NUMERIC "27" -// Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000" -// Retrieval info: PRIVATE: DUTY_CYCLE1 STRING "50.00000000" -// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "60.000000" -// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE1 STRING "4.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 "27.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 "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: MULT_FACTOR0 NUMERIC "20" -// Retrieval info: PRIVATE: MULT_FACTOR1 NUMERIC "4" -// Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1" -// Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "60.00000000" -// Retrieval info: PRIVATE: OUTPUT_FREQ1 STRING "4.00000000" -// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "0" -// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE1 STRING "0" -// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz" -// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT1 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_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: 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 "pll.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: 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_CLKENA0 STRING "0" -// Retrieval info: PRIVATE: USE_CLKENA1 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 "9" -// Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50" -// Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "20" -// Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0" -// Retrieval info: CONSTANT: CLK1_DIVIDE_BY NUMERIC "27" -// 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: COMPENSATE_CLOCK STRING "CLK0" -// Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "37037" -// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III" -// Retrieval info: CONSTANT: LPM_TYPE STRING "altpll" -// Retrieval info: CONSTANT: OPERATION_MODE STRING "NORMAL" -// 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_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_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: USED_PORT: @clk 0 0 5 0 OUTPUT_CLK_EXT VCC "@clk[4..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: c1 0 0 0 0 OUTPUT_CLK_EXT VCC "c1" -// Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT_CLK_EXT GND "inclk0" -// Retrieval info: USED_PORT: locked 0 0 0 0 OUTPUT GND "locked" -// Retrieval info: CONNECT: @areset 0 0 0 0 areset 0 0 0 0 -// Retrieval info: CONNECT: @inclk 0 0 1 1 GND 0 0 0 0 -// Retrieval info: CONNECT: @inclk 0 0 1 0 inclk0 0 0 0 0 -// Retrieval info: CONNECT: c0 0 0 0 0 @clk 0 0 1 0 -// Retrieval info: CONNECT: c1 0 0 0 0 @clk 0 0 1 1 -// Retrieval info: CONNECT: locked 0 0 0 0 @locked 0 0 0 0 -// Retrieval info: GEN_FILE: TYPE_NORMAL pll1.v TRUE -// Retrieval info: GEN_FILE: TYPE_NORMAL pll1.ppf TRUE -// Retrieval info: GEN_FILE: TYPE_NORMAL pll1.inc FALSE -// Retrieval info: GEN_FILE: TYPE_NORMAL pll1.cmp FALSE -// Retrieval info: GEN_FILE: TYPE_NORMAL pll1.bsf FALSE -// Retrieval info: GEN_FILE: TYPE_NORMAL pll1_inst.v FALSE -// Retrieval info: GEN_FILE: TYPE_NORMAL pll1_bb.v FALSE -// Retrieval info: LIB_FILE: altera_mf -// Retrieval info: CBX_MODULE_PREFIX: ON diff --git a/Console_MiST/Supervision_MiST/rtl/pll2.v b/Console_MiST/Supervision_MiST/rtl/pll2.v deleted file mode 100644 index 5e1278ec..00000000 --- a/Console_MiST/Supervision_MiST/rtl/pll2.v +++ /dev/null @@ -1,320 +0,0 @@ -// megafunction wizard: %ALTPLL% -// GENERATION: STANDARD -// VERSION: WM1.0 -// MODULE: altpll - -// ============================================================ -// File Name: pll2.v -// Megafunction Name(s): -// altpll -// -// Simulation Library Files(s): -// altera_mf -// ============================================================ -// ************************************************************ -// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! -// -// 13.1.4 Build 182 03/12/2014 SJ Full Version -// ************************************************************ - - -//Copyright (C) 1991-2014 Altera Corporation -//Your use of Altera Corporation's design tools, logic functions -//and other software and tools, and its AMPP partner logic -//functions, and any output files from any of the foregoing -//(including device programming or simulation files), and any -//associated documentation or information are expressly subject -//to the terms and conditions of the Altera Program License -//Subscription Agreement, Altera MegaCore Function License -//Agreement, or other applicable license agreement, including, -//without limitation, that your use is for the sole purpose of -//programming logic devices manufactured by Altera and sold by -//Altera or its authorized distributors. Please refer to the -//applicable agreement for further details. - - -// synopsys translate_off -`timescale 1 ps / 1 ps -// synopsys translate_on -module pll2 ( - areset, - inclk0, - c0, - locked); - - input areset; - input inclk0; - output c0; - output locked; -`ifndef ALTERA_RESERVED_QIS -// synopsys translate_off -`endif - tri0 areset; -`ifndef ALTERA_RESERVED_QIS -// synopsys translate_on -`endif - - wire sub_wire0; - wire [4:0] sub_wire1; - wire [0:0] sub_wire5 = 1'h0; - wire locked = sub_wire0; - wire [0:0] sub_wire2 = sub_wire1[0:0]; - wire c0 = sub_wire2; - wire sub_wire3 = inclk0; - wire [1:0] sub_wire4 = {sub_wire5, sub_wire3}; - - altpll altpll_component ( - .areset (areset), - .inclk (sub_wire4), - .locked (sub_wire0), - .clk (sub_wire1), - .activeclock (), - .clkbad (), - .clkena ({6{1'b1}}), - .clkloss (), - .clkswitch (1'b0), - .configupdate (1'b0), - .enable0 (), - .enable1 (), - .extclk (), - .extclkena ({4{1'b1}}), - .fbin (1'b1), - .fbmimicbidir (), - .fbout (), - .fref (), - .icdrclk (), - .pfdena (1'b1), - .phasecounterselect ({4{1'b1}}), - .phasedone (), - .phasestep (1'b1), - .phaseupdown (1'b1), - .pllena (1'b1), - .scanaclr (1'b0), - .scanclk (1'b0), - .scanclkena (1'b1), - .scandata (1'b0), - .scandataout (), - .scandone (), - .scanread (1'b0), - .scanwrite (1'b0), - .sclkout0 (), - .sclkout1 (), - .vcooverrange (), - .vcounderrange ()); - defparam - altpll_component.bandwidth_type = "AUTO", - altpll_component.clk0_divide_by = 44, - altpll_component.clk0_duty_cycle = 50, - altpll_component.clk0_multiply_by = 41, - altpll_component.clk0_phase_shift = "0", - altpll_component.compensate_clock = "CLK0", - altpll_component.inclk0_input_frequency = 37037, - altpll_component.intended_device_family = "Cyclone III", - altpll_component.lpm_hint = "CBX_MODULE_PREFIX=pll2", - altpll_component.lpm_type = "altpll", - altpll_component.operation_mode = "NORMAL", - altpll_component.pll_type = "AUTO", - altpll_component.port_activeclock = "PORT_UNUSED", - altpll_component.port_areset = "PORT_USED", - altpll_component.port_clkbad0 = "PORT_UNUSED", - altpll_component.port_clkbad1 = "PORT_UNUSED", - altpll_component.port_clkloss = "PORT_UNUSED", - altpll_component.port_clkswitch = "PORT_UNUSED", - altpll_component.port_configupdate = "PORT_UNUSED", - altpll_component.port_fbin = "PORT_UNUSED", - altpll_component.port_inclk0 = "PORT_USED", - altpll_component.port_inclk1 = "PORT_UNUSED", - altpll_component.port_locked = "PORT_USED", - altpll_component.port_pfdena = "PORT_UNUSED", - altpll_component.port_phasecounterselect = "PORT_UNUSED", - altpll_component.port_phasedone = "PORT_UNUSED", - altpll_component.port_phasestep = "PORT_UNUSED", - altpll_component.port_phaseupdown = "PORT_UNUSED", - altpll_component.port_pllena = "PORT_UNUSED", - altpll_component.port_scanaclr = "PORT_UNUSED", - altpll_component.port_scanclk = "PORT_UNUSED", - altpll_component.port_scanclkena = "PORT_UNUSED", - altpll_component.port_scandata = "PORT_UNUSED", - altpll_component.port_scandataout = "PORT_UNUSED", - altpll_component.port_scandone = "PORT_UNUSED", - altpll_component.port_scanread = "PORT_UNUSED", - altpll_component.port_scanwrite = "PORT_UNUSED", - altpll_component.port_clk0 = "PORT_USED", - altpll_component.port_clk1 = "PORT_UNUSED", - altpll_component.port_clk2 = "PORT_UNUSED", - altpll_component.port_clk3 = "PORT_UNUSED", - altpll_component.port_clk4 = "PORT_UNUSED", - altpll_component.port_clk5 = "PORT_UNUSED", - altpll_component.port_clkena0 = "PORT_UNUSED", - altpll_component.port_clkena1 = "PORT_UNUSED", - altpll_component.port_clkena2 = "PORT_UNUSED", - altpll_component.port_clkena3 = "PORT_UNUSED", - altpll_component.port_clkena4 = "PORT_UNUSED", - altpll_component.port_clkena5 = "PORT_UNUSED", - altpll_component.port_extclk0 = "PORT_UNUSED", - altpll_component.port_extclk1 = "PORT_UNUSED", - altpll_component.port_extclk2 = "PORT_UNUSED", - altpll_component.port_extclk3 = "PORT_UNUSED", - altpll_component.self_reset_on_loss_lock = "OFF", - altpll_component.width_clock = 5; - - -endmodule - -// ============================================================ -// CNX file retrieval info -// ============================================================ -// Retrieval info: PRIVATE: ACTIVECLK_CHECK STRING "0" -// Retrieval info: PRIVATE: BANDWIDTH STRING "1.000" -// Retrieval info: PRIVATE: BANDWIDTH_FEATURE_ENABLED STRING "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 "c0" -// Retrieval info: PRIVATE: CUR_FBIN_CLK STRING "c0" -// Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "8" -// Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "44" -// Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000" -// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "25.159090" -// 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 "27.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 "41" -// Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1" -// Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "25.17500000" -// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "0" -// 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 "pll.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: 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 "44" -// Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50" -// Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "41" -// Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0" -// Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK0" -// Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "37037" -// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III" -// Retrieval info: CONSTANT: LPM_TYPE STRING "altpll" -// Retrieval info: CONSTANT: OPERATION_MODE STRING "NORMAL" -// 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_UNUSED" -// Retrieval info: CONSTANT: PORT_FBIN STRING "PORT_UNUSED" -// Retrieval info: CONSTANT: PORT_INCLK0 STRING "PORT_USED" -// Retrieval info: CONSTANT: PORT_INCLK1 STRING "PORT_UNUSED" -// Retrieval info: CONSTANT: PORT_LOCKED STRING "PORT_USED" -// Retrieval info: CONSTANT: PORT_PFDENA STRING "PORT_UNUSED" -// Retrieval info: CONSTANT: PORT_PHASECOUNTERSELECT STRING "PORT_UNUSED" -// Retrieval info: CONSTANT: PORT_PHASEDONE STRING "PORT_UNUSED" -// Retrieval info: CONSTANT: PORT_PHASESTEP STRING "PORT_UNUSED" -// Retrieval info: CONSTANT: PORT_PHASEUPDOWN STRING "PORT_UNUSED" -// Retrieval info: CONSTANT: PORT_PLLENA STRING "PORT_UNUSED" -// Retrieval info: CONSTANT: PORT_SCANACLR STRING "PORT_UNUSED" -// Retrieval info: CONSTANT: PORT_SCANCLK STRING "PORT_UNUSED" -// Retrieval info: CONSTANT: PORT_SCANCLKENA STRING "PORT_UNUSED" -// Retrieval info: CONSTANT: PORT_SCANDATA STRING "PORT_UNUSED" -// Retrieval info: CONSTANT: PORT_SCANDATAOUT STRING "PORT_UNUSED" -// Retrieval info: CONSTANT: PORT_SCANDONE STRING "PORT_UNUSED" -// Retrieval info: CONSTANT: PORT_SCANREAD STRING "PORT_UNUSED" -// Retrieval info: CONSTANT: PORT_SCANWRITE STRING "PORT_UNUSED" -// Retrieval info: CONSTANT: PORT_clk0 STRING "PORT_USED" -// Retrieval info: CONSTANT: PORT_clk1 STRING "PORT_UNUSED" -// Retrieval info: CONSTANT: PORT_clk2 STRING "PORT_UNUSED" -// Retrieval info: CONSTANT: PORT_clk3 STRING "PORT_UNUSED" -// Retrieval info: CONSTANT: PORT_clk4 STRING "PORT_UNUSED" -// Retrieval info: CONSTANT: PORT_clk5 STRING "PORT_UNUSED" -// Retrieval info: CONSTANT: PORT_clkena0 STRING "PORT_UNUSED" -// Retrieval info: CONSTANT: PORT_clkena1 STRING "PORT_UNUSED" -// Retrieval info: CONSTANT: PORT_clkena2 STRING "PORT_UNUSED" -// Retrieval info: CONSTANT: PORT_clkena3 STRING "PORT_UNUSED" -// Retrieval info: CONSTANT: PORT_clkena4 STRING "PORT_UNUSED" -// Retrieval info: CONSTANT: PORT_clkena5 STRING "PORT_UNUSED" -// Retrieval info: CONSTANT: PORT_extclk0 STRING "PORT_UNUSED" -// Retrieval info: CONSTANT: PORT_extclk1 STRING "PORT_UNUSED" -// Retrieval info: CONSTANT: PORT_extclk2 STRING "PORT_UNUSED" -// Retrieval info: CONSTANT: PORT_extclk3 STRING "PORT_UNUSED" -// Retrieval info: CONSTANT: 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: areset 0 0 0 0 INPUT GND "areset" -// Retrieval info: USED_PORT: c0 0 0 0 0 OUTPUT_CLK_EXT VCC "c0" -// Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT_CLK_EXT GND "inclk0" -// Retrieval info: USED_PORT: locked 0 0 0 0 OUTPUT GND "locked" -// Retrieval info: CONNECT: @areset 0 0 0 0 areset 0 0 0 0 -// Retrieval info: CONNECT: @inclk 0 0 1 1 GND 0 0 0 0 -// Retrieval info: CONNECT: @inclk 0 0 1 0 inclk0 0 0 0 0 -// Retrieval info: CONNECT: c0 0 0 0 0 @clk 0 0 1 0 -// Retrieval info: CONNECT: locked 0 0 0 0 @locked 0 0 0 0 -// Retrieval info: GEN_FILE: TYPE_NORMAL pll2.v TRUE -// Retrieval info: GEN_FILE: TYPE_NORMAL pll2.ppf TRUE -// Retrieval info: GEN_FILE: TYPE_NORMAL pll2.inc FALSE -// Retrieval info: GEN_FILE: TYPE_NORMAL pll2.cmp FALSE -// Retrieval info: GEN_FILE: TYPE_NORMAL pll2.bsf FALSE -// Retrieval info: GEN_FILE: TYPE_NORMAL pll2_inst.v FALSE -// Retrieval info: GEN_FILE: TYPE_NORMAL pll2_bb.v FALSE -// Retrieval info: LIB_FILE: altera_mf -// Retrieval info: CBX_MODULE_PREFIX: ON diff --git a/Console_MiST/Supervision_MiST/rtl/ram88.sv b/Console_MiST/Supervision_MiST/rtl/ram88.sv deleted file mode 100644 index 9fd41d6e..00000000 --- a/Console_MiST/Supervision_MiST/rtl/ram88.sv +++ /dev/null @@ -1,23 +0,0 @@ - -module ram88 ( - input clk, - input [12:0] addr, - input [12:0] addrb, - input [7:0] din, - input we, - input cs, - output reg [7:0] dout, - output reg [7:0] doutb -); - -reg [7:0] memory[8191:0] /*verilator public_flat_rd*/; - -always @(posedge clk) begin - if (~cs) begin - if (~we) memory[addr] <= din; - dout <= memory[addr]; - end - doutb <= memory[addrb]; -end - -endmodule \ No newline at end of file diff --git a/Console_MiST/Supervision_MiST/rtl/rom.v b/Console_MiST/Supervision_MiST/rtl/rom.v deleted file mode 100644 index 05de1290..00000000 --- a/Console_MiST/Supervision_MiST/rtl/rom.v +++ /dev/null @@ -1,22 +0,0 @@ - -module rom ( - input clk, - input [15:0] addr, - output reg [7:0] dout, - input cs, - input rom_init, - input rom_init_clk, - input [15:0] rom_init_address, - input [7:0] rom_init_data -); - -reg [7:0] memory[65535:0]; - -always @(posedge clk) - if (~cs) dout <= memory[addr]; - -always @(posedge rom_init_clk) - if (rom_init) - memory[rom_init_address] <= rom_init_data; - -endmodule diff --git a/Console_MiST/Supervision_MiST/rtl/sdram.sv b/Console_MiST/Supervision_MiST/rtl/sdram.sv index d616184c..f8d20736 100644 --- a/Console_MiST/Supervision_MiST/rtl/sdram.sv +++ b/Console_MiST/Supervision_MiST/rtl/sdram.sv @@ -1,12 +1,10 @@ // // sdram.v +// This version issues refresh only when 8bit channel reads the same 16bit word 2 times // -// sdram controller implementation for the MiST board -// https://github.com/mist-devel/mist-board +// sdram controller implementation +// Copyright (c) 2018 Sorgelig // -// Copyright (c) 2013 Till Harbaum -// Copyright (c) 2019 Gyorgy Szombathelyi -// // 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 3 of the License, or @@ -21,222 +19,269 @@ // along with this program. If not, see . // -module sdram ( +module sdram +( // interface to the MT48LC16M16 chip inout reg [15:0] SDRAM_DQ, // 16 bit bidirectional data bus output reg [12:0] SDRAM_A, // 13 bit multiplexed address bus - output reg SDRAM_DQML, // two byte masks - output reg SDRAM_DQMH, // two byte masks - output reg [1:0] SDRAM_BA, // two banks - output SDRAM_nCS, // a single chip select - output SDRAM_nWE, // write enable - output SDRAM_nRAS, // row address select - output SDRAM_nCAS, // columns address select + output reg SDRAM_DQML, // byte mask + output reg SDRAM_DQMH, // byte mask + output reg [1:0] SDRAM_BA, // two banks + output reg SDRAM_nCS, // a single chip select + output reg SDRAM_nWE, // write enable + output reg SDRAM_nRAS, // row address select + output reg SDRAM_nCAS, // columns address select + output SDRAM_CLK, + output SDRAM_CKE, // cpu/chipset interface - input init_n, // init signal after FPGA config to initialize RAM - input clk, // sdram clock + input init, // init signal after FPGA config to initialize RAM + input clk, // sdram is accessed at up to 128MHz - input port1_req, - output reg port1_ack, - input port1_we, - input [23:1] port1_a, - input [1:0] port1_ds, - input [15:0] port1_d, - output [15:0] port1_q, + input [24:0] ch0_addr, + input ch0_rd, + input ch0_wr, + input [7:0] ch0_din, + output reg [7:0] ch0_dout, + output reg ch0_busy, - input [17:1] cpu1_addr, - output reg [15:0] cpu1_q + input [24:0] ch1_addr, + input ch1_rd, + input ch1_wr, + input [7:0] ch1_din, + output reg [7:0] ch1_dout, + output reg ch1_busy, + + input [24:0] ch2_addr, + input ch2_rd, + input ch2_wr, + input [7:0] ch2_din, + output reg [7:0] ch2_dout, + output reg ch2_busy ); -parameter MHZ = 80; // 80 MHz default clock, adjust to calculate the refresh rate correctly +assign SDRAM_nCS = 0; +assign SDRAM_CKE = 1; +assign {SDRAM_DQMH,SDRAM_DQML} = SDRAM_A[12:11]; -localparam RASCAS_DELAY = 3'd2; // tRCD=20ns -> 2 cycles@<100MHz -localparam BURST_LENGTH = 3'b000; // 000=1, 001=2, 010=4, 011=8 -localparam ACCESS_TYPE = 1'b0; // 0=sequential, 1=interleaved -localparam CAS_LATENCY = 3'd2; // 2/3 allowed -localparam OP_MODE = 2'b00; // only 00 (standard operation) allowed -localparam NO_WRITE_BURST = 1'b1; // 0= write burst enabled, 1=only single access write +localparam RASCAS_DELAY = 3'd1; // tRCD=20ns -> 2 cycles@85MHz +localparam BURST_LENGTH = 3'd0; // 0=1, 1=2, 2=4, 3=8, 7=full page +localparam ACCESS_TYPE = 1'd0; // 0=sequential, 1=interleaved +localparam CAS_LATENCY = 3'd2; // 2/3 allowed +localparam OP_MODE = 2'd0; // only 0 (standard operation) allowed +localparam NO_WRITE_BURST = 1'd1; // 0=write burst enabled, 1=only single access write localparam MODE = { 3'b000, NO_WRITE_BURST, OP_MODE, CAS_LATENCY, ACCESS_TYPE, BURST_LENGTH}; -// 64ms/8192 rows = 7.8us -> 842 cycles@108MHz -localparam RFRSH_CYCLES = 16'd78*MHZ/10; +localparam STATE_IDLE = 3'd0; // state to check the requests +localparam STATE_START = STATE_IDLE+1'd1; // state in which a new command is started +localparam STATE_NEXT = STATE_START+1'd1; // state in which a new command is started +localparam STATE_CONT = STATE_START+RASCAS_DELAY; +localparam STATE_READY = STATE_CONT+CAS_LATENCY+2'd2; +localparam STATE_LAST = STATE_READY; // last state in cycle -// --------------------------------------------------------------------- -// ------------------------ cycle state machine ------------------------ -// --------------------------------------------------------------------- +reg [2:0] state; +reg [22:0] a; +reg [1:0] bank; +reg [15:0] data; +reg we; +reg ram_req=0; -/* - SDRAM state machine - 1 word burst, CL2 -cmd issued registered - 0 RAS0 data ready - 1 - 2 CAS0 - 3 - 4 - 5 DATA0 -*/ +wire [2:0] rd,wr; -localparam STATE_RAS0 = 3'd0; // first state in cycle -localparam STATE_CAS0 = STATE_RAS0 + RASCAS_DELAY; // CAS phase - 2 -localparam STATE_READ0 = 3'd0; //STATE_CAS0 + CAS_LATENCY + 2'd2; // 6 -localparam STATE_LAST = 3'd5; - -reg [2:0] t; +assign rd = {ch2_rd, ch1_rd, ch0_rd}; +assign wr = {ch2_wr, ch1_wr, ch0_wr}; +// access manager always @(posedge clk) begin - t <= t + 1'd1; - if (t == STATE_LAST) t <= STATE_RAS0; -end + reg old_ref; + reg [2:0] old_rd,old_wr;//,rd,wr; + reg [24:1] last_a[3] = '{'1,'1,'1}; -// --------------------------------------------------------------------- -// --------------------------- startup/reset --------------------------- -// --------------------------------------------------------------------- + old_rd <= old_rd & rd; + old_wr <= old_wr & wr; -// wait 1ms (32 8Mhz cycles) after FPGA config is done before going -// into normal operation. Initialize the ram in the last 16 reset cycles (cycles 15-0) -reg [4:0] reset; -reg init = 1'b1; -always @(posedge clk, negedge init_n) begin - if(!init_n) begin - reset <= 5'h1f; - init <= 1'b1; - end else begin - if((t == STATE_LAST) && (reset != 0)) reset <= reset - 5'd1; - init <= !(reset == 0); - end -end - -// --------------------------------------------------------------------- -// ------------------ generate ram control signals --------------------- -// --------------------------------------------------------------------- - -// all possible commands -localparam CMD_INHIBIT = 4'b1111; -localparam CMD_NOP = 4'b0111; -localparam CMD_ACTIVE = 4'b0011; -localparam CMD_READ = 4'b0101; -localparam CMD_WRITE = 4'b0100; -localparam CMD_BURST_TERMINATE = 4'b0110; -localparam CMD_PRECHARGE = 4'b0010; -localparam CMD_AUTO_REFRESH = 4'b0001; -localparam CMD_LOAD_MODE = 4'b0000; - -reg [3:0] sd_cmd; // current command sent to sd ram -reg [15:0] sd_din; -// drive control signals according to current command -assign SDRAM_nCS = sd_cmd[3]; -assign SDRAM_nRAS = sd_cmd[2]; -assign SDRAM_nCAS = sd_cmd[1]; -assign SDRAM_nWE = sd_cmd[0]; - -reg [24:1] addr_latch; -reg [24:1] addr_latch_next; -reg [17:1] addr_last; -reg [15:0] din_latch; -reg oe_latch; -reg we_latch; -reg [1:0] ds; - -localparam PORT_NONE = 2'd0; -localparam PORT_CPU1 = 2'd1; -localparam PORT_REQ = 2'd2; - -reg [2:0] next_port; -reg [2:0] port; -reg port1_state; - -// PORT1 -always @(*) begin - if (port1_req ^ port1_state) begin - next_port = PORT_REQ; - addr_latch_next = { 1'b0, port1_a }; - end else if (cpu1_addr != addr_last) begin - next_port = PORT_CPU1; - addr_latch_next = { 7'd0, cpu1_addr }; - end else begin - next_port = PORT_NONE; - addr_latch_next = addr_latch; - end -end - -always @(posedge clk) begin - - // permanently latch ram data to reduce delays - sd_din <= SDRAM_DQ; - SDRAM_DQ <= 16'bZZZZZZZZZZZZZZZZ; - { SDRAM_DQMH, SDRAM_DQML } <= 2'b11; - sd_cmd <= CMD_NOP; // default: idle - - if(init) begin - // initialization takes place at the end of the reset phase - if(t == STATE_RAS0) begin - - if(reset == 15) begin - sd_cmd <= CMD_PRECHARGE; - SDRAM_A[10] <= 1'b1; // precharge all banks - end - - if(reset == 10 || reset == 8) begin - sd_cmd <= CMD_AUTO_REFRESH; - end - - if(reset == 2) begin - sd_cmd <= CMD_LOAD_MODE; - SDRAM_A <= MODE; - SDRAM_BA <= 2'b00; - end + if(state == STATE_IDLE && mode == MODE_NORMAL) begin + ram_req <= 0; + we <= 0; + ch0_busy <= 0; + ch1_busy <= 0; + ch2_busy <= 0; + if((~old_rd[0] & rd[0]) | (~old_wr[0] & wr[0])) begin + old_rd[0] <= rd[0]; + old_wr[0] <= wr[0]; + we <= wr[0]; + {bank,a} <= ch0_addr; + data <= {ch0_din,ch0_din}; + ram_req <= wr[0] || (last_a[0] != ch0_addr[24:1]); + last_a[0] <= wr[0] ? '1 : ch0_addr[24:1]; + ch0_busy <= 1; + state <= STATE_START; end - end else begin - // RAS phase - if(t == STATE_RAS0) begin - addr_latch <= addr_latch_next; - port <= next_port; - { oe_latch, we_latch } <= 2'b00; + else if((~old_rd[1] & rd[1]) | (~old_wr[1] & wr[1])) begin + old_rd[1] <= rd[1]; + old_wr[1] <= wr[1]; + we <= wr[1]; + {bank,a} <= ch1_addr; + data <= {ch1_din,ch1_din}; + ram_req <= wr[1] || (last_a[1] != ch1_addr[24:1]); + last_a[1] <= wr[1] ? '1 : ch1_addr[24:1]; + ch1_busy <= 1; + state <= STATE_START; + end + else if((~old_rd[2] & rd[2]) | (~old_wr[2] & wr[2])) begin + old_rd[2] <= rd[2]; + old_wr[2] <= wr[2]; + we <= wr[2]; + {bank,a} <= ch2_addr; + data <= {ch2_din,ch2_din}; + ram_req <= wr[2] || (last_a[2] != ch2_addr[24:1]); + last_a[2] <= wr[2] ? '1 : ch2_addr[24:1]; + ch2_busy <= 1; + state <= STATE_START; + end + end - if (next_port != PORT_NONE) begin - sd_cmd <= CMD_ACTIVE; - SDRAM_A <= addr_latch_next[22:10]; - SDRAM_BA <= addr_latch_next[24:23]; - if (next_port == PORT_REQ) begin - { oe_latch, we_latch } <= { ~port1_we, port1_we }; - ds <= port1_ds; - din_latch <= port1_d; - port1_state <= port1_req; - end else begin - { oe_latch, we_latch } <= 2'b10; - ds <= 2'b11; - addr_last <= cpu1_addr; + if (state == STATE_READY) begin + ch0_busy <= 0; + ch1_busy <= 0; + ch2_busy <= 0; + end + + if(mode != MODE_NORMAL || state != STATE_IDLE || reset) begin + state <= state + 1'd1; + if(state == STATE_LAST) state <= STATE_IDLE; + end +end + +localparam MODE_NORMAL = 2'b00; +localparam MODE_RESET = 2'b01; +localparam MODE_LDM = 2'b10; +localparam MODE_PRE = 2'b11; + +// initialization +reg [1:0] mode; +reg [4:0] reset=5'h1f; +always @(posedge clk) begin + reg init_old=0; + init_old <= init; + + if(init_old & ~init) reset <= 5'h1f; + else if(state == STATE_LAST) begin + if(reset != 0) begin + reset <= reset - 5'd1; + if(reset == 14) mode <= MODE_PRE; + else if(reset == 3) mode <= MODE_LDM; + else mode <= MODE_RESET; + end + else mode <= MODE_NORMAL; + end +end + +localparam CMD_NOP = 3'b111; +localparam CMD_ACTIVE = 3'b011; +localparam CMD_READ = 3'b101; +localparam CMD_WRITE = 3'b100; +localparam CMD_BURST_TERMINATE = 3'b110; +localparam CMD_PRECHARGE = 3'b010; +localparam CMD_AUTO_REFRESH = 3'b001; +localparam CMD_LOAD_MODE = 3'b000; + +wire [1:0] dqm = {we & ~a[0], we & a[0]}; + +// SDRAM state machines +always @(posedge clk) begin + reg [15:0] last_data[3]; + reg [15:0] data_reg; + + if(state == STATE_START) SDRAM_BA <= (mode == MODE_NORMAL) ? bank : 2'b00; + + SDRAM_DQ <= 'Z; + casex({ram_req,we,mode,state}) + {2'b1X, MODE_NORMAL, STATE_START}: {SDRAM_nRAS, SDRAM_nCAS, SDRAM_nWE} <= CMD_ACTIVE; + {2'b11, MODE_NORMAL, STATE_CONT }: {SDRAM_nRAS, SDRAM_nCAS, SDRAM_nWE, SDRAM_DQ} <= {CMD_WRITE, data}; + {2'b10, MODE_NORMAL, STATE_CONT }: {SDRAM_nRAS, SDRAM_nCAS, SDRAM_nWE} <= CMD_READ; + {2'b0X, MODE_NORMAL, STATE_START}: {SDRAM_nRAS, SDRAM_nCAS, SDRAM_nWE} <= CMD_AUTO_REFRESH; + + // init + {2'bXX, MODE_LDM, STATE_START}: {SDRAM_nRAS, SDRAM_nCAS, SDRAM_nWE} <= CMD_LOAD_MODE; + {2'bXX, MODE_PRE, STATE_START}: {SDRAM_nRAS, SDRAM_nCAS, SDRAM_nWE} <= CMD_PRECHARGE; + + default: {SDRAM_nRAS, SDRAM_nCAS, SDRAM_nWE} <= CMD_NOP; + endcase + + casex({ram_req,mode,state}) + {1'b1, MODE_NORMAL, STATE_START}: SDRAM_A <= a[13:1]; + {1'b1, MODE_NORMAL, STATE_CONT }: SDRAM_A <= {dqm, 2'b10, a[22:14]}; + + // init + {1'bX, MODE_LDM, STATE_START}: SDRAM_A <= MODE; + {1'bX, MODE_PRE, STATE_START}: SDRAM_A <= 13'b0010000000000; + + default: SDRAM_A <= 13'b0000000000000; + endcase + + data_reg <= SDRAM_DQ; + + if(state == STATE_READY) begin + if(ch0_busy) begin + if(ram_req) begin + if(we) ch0_dout <= data[7:0]; + else begin + ch0_dout <= a[0] ? data_reg[15:8] : data_reg[7:0]; + last_data[0] <= data_reg; end - end else begin - sd_cmd <= CMD_AUTO_REFRESH; end + else ch0_dout <= a[0] ? last_data[0][15:8] : last_data[0][7:0]; end - - // CAS phase - if(t == STATE_CAS0 && (we_latch || oe_latch)) begin - sd_cmd <= we_latch?CMD_WRITE:CMD_READ; - { SDRAM_DQMH, SDRAM_DQML } <= ~ds; - if (we_latch) begin - SDRAM_DQ <= din_latch; - port1_ack <= port1_req; + if(ch1_busy) begin + if(ram_req) begin + if(we) ch1_dout <= data[7:0]; + else begin + ch1_dout <= a[0] ? data_reg[15:8] : data_reg[7:0]; + last_data[1] <= data_reg; + end end - SDRAM_A <= { 4'b0010, addr_latch[9:1] }; // auto precharge - SDRAM_BA <= addr_latch[24:23]; + else ch1_dout <= a[0] ? last_data[1][15:8] : last_data[1][7:0]; end - - // Data returned - if(t == STATE_READ0 && oe_latch) begin - case(port) - PORT_REQ: begin port1_q <= sd_din; port1_ack <= port1_req; end - PORT_CPU1: begin cpu1_q <= sd_din; end - default: ; - endcase; + if(ch2_busy) begin + if(ram_req) begin + if(we) ch2_dout <= data[7:0]; + else begin + ch2_dout <= a[0] ? data_reg[15:8] : data_reg[7:0]; + last_data[2] <= data_reg; + end + end + else ch2_dout <= a[0] ? last_data[2][15:8] : last_data[2][7:0]; end end end + +altddio_out +#( + .extend_oe_disable("OFF"), + .intended_device_family("Cyclone V"), + .invert_output("OFF"), + .lpm_hint("UNUSED"), + .lpm_type("altddio_out"), + .oe_reg("UNREGISTERED"), + .power_up_high("OFF"), + .width(1) +) +sdramclk_ddr +( + .datain_h(1'b0), + .datain_l(1'b1), + .outclock(clk), + .dataout(SDRAM_CLK), + .aclr(1'b0), + .aset(1'b0), + .oe(1'b1), + .outclocken(1'b1), + .sclr(1'b0), + .sset(1'b0) +); + endmodule diff --git a/Console_MiST/Supervision_MiST/rtl/sv_top.sv b/Console_MiST/Supervision_MiST/rtl/sv_top.sv new file mode 100644 index 00000000..a0d94864 --- /dev/null +++ b/Console_MiST/Supervision_MiST/rtl/sv_top.sv @@ -0,0 +1,268 @@ +module sv_top +( + input clk_sys, + input reset, + input [7:0] joystick, + input [7:0] rom_dout, + input [3:0] user_in, + input large_rom, + input compat60, + output hsync, + output hblank, + output vsync, + output vblank, + output [15:0] audio_r, + output [15:0] audio_l, + output [1:0] pixel, + output pix_ce, + output [18:0] addr_bus, + output rom_read, + output reg [7:0] link_ddr, + output reg [7:0] link_data +); + +reg [1:0] sys_div = 0; +reg irq_pending = 0; +reg [7:0] open_bus = 8'hFF; +reg [15:0] nmi_clk; +reg irq_timer; +reg old_nmi_clk_15; +reg nmi_latch = 0; + +// System Registers +reg [7:0] irq_timer_len; +reg [7:0] sys_ctl; + +wire irq_adma_n; +wire [7:0] cpu_dout, wram_dout, vram_dout, sys_dout; +wire dma_en; +wire dma_dir; +wire adma_read; +wire [7:0] lcd_din; +wire [13:0] lcd_addr, vram_addr; +wire [15:0] adma_addr, dma_addr, cpu_addr; +wire [2:0] adma_bank; +wire [5:0] audio_right, audio_left; +wire cpu_rwn; + +// Clock divider +wire phi1 = sys_div == 2'b00; +wire phi2 = sys_div == 2'b10; + +// Chip Selects +wire wram_cs = AB[15:13] == 3'b000; // Work ram from 0000 to 1FFF +wire sys_cs = AB[15:6] == 10'b0010_0000_00; // System Registers from 2000 to 3FFF (open bus above 202F) +wire vram_cs = AB[15:13] == 3'b010; // Vram from 4000 to 5FFF +//wire ob_cs = AB[15:13] == 3'b011; // Open bus from 6000 to 7FFF +wire rom_cs = AB[15]; // Cart ROM at 8000 to FFFF banked from 8000-BFFF, fixed for the rest + +// Bank Selection +wire [2:0] b = AB[14] ? 3'b111 : adma_read ? adma_bank : sys_ctl[7:5]; +wire [18:0] magnum_addr = {(b[2] ? 4'b1111 : link_data[3:0]), b[0], AB[13:0]}; + +// IRQ/NMI Masking +wire nmi = old_nmi_clk_15 & ~nmi_clk[15]; +wire timer_tap = (sys_ctl[4] ? nmi_clk[13] : nmi_clk[7]); +wire irq_timer_masked = irq_timer & sys_ctl[1]; +wire irq_adma_masked = ~irq_adma_n & sys_ctl[2]; +wire nmi_masked = (nmi | nmi_latch) & sys_ctl[0]; // the CPU misses nmi's when paused in this implementation so we have to latch it + +// (A)DMA bus multiplexing +wire [15:0] AB = adma_read ? adma_addr : (dma_en ? dma_addr : cpu_addr); +wire cpu_rdy = ~dma_en && ~adma_read; +wire [7:0] DO = dma_en ? (dma_dir ? DII : vram_dout) : cpu_dout; +wire cpu_we = adma_read ? 1'b0 : dma_en ? ~dma_dir : ~cpu_rwn; + +// Read Data Bus +wire [7:0] DII = + sys_cs ? sys_dout : + wram_cs ? wram_dout : + vram_cs ? vram_dout : + rom_cs ? rom_dout : + open_bus; + +// Top Level assignments +assign addr_bus = large_rom ? magnum_addr : {2'b11, b, AB[13:0]}; +assign rom_read = rom_cs & ~phi1; +assign audio_l = { audio_left, 10'd0 }; +assign audio_r = { audio_right, 10'd0 }; + +// System Register reads +always_comb begin + sys_dout = open_bus; + if (~cpu_we) begin + case (AB[5:0]) + 6'h20: sys_dout = ~joystick; + 6'h21: sys_dout = {open_bus[7:4], (user_in[3:0] & link_ddr[3:0]) | (link_data[3:0] & ~link_ddr[3:0])}; + 6'h23: sys_dout = irq_timer_len; + 6'h26: sys_dout = sys_ctl; + 6'h27: sys_dout = {open_bus[7:2], ~irq_adma_n, irq_timer}; + default: sys_dout = open_bus; + endcase + end +end + +always_ff @(posedge clk_sys) begin + reg old_tap; + + sys_div <= sys_div + 1'd1; + + if (phi1) begin + if (~cpu_rdy) + nmi_latch <= nmi_masked | nmi_latch; + else + nmi_latch <= 0; + end + + if (phi2) begin + old_tap <= timer_tap; + old_nmi_clk_15 <= nmi_clk[15]; + nmi_clk <= nmi_clk + 16'b1; + + if (~old_tap && timer_tap) begin + if (irq_timer_len > 0) begin + irq_timer_len <= irq_timer_len - 8'b1; + if (irq_timer_len == 1) + irq_pending <= 1; + end + end + + if (irq_pending && ~timer_tap) begin + irq_pending <= 0; + irq_timer <= 1; + end + + open_bus <= ~cpu_we ? DII : DO; + + // System Register writes + if (sys_cs) begin + if (AB[5:0] == 6'h24) begin // read or write to ack timer IRQ + irq_timer <= 0; + end + if (cpu_we) begin + case (AB[5:0]) + 6'h21: link_data <= cpu_dout; + 6'h22: link_ddr <= cpu_dout; + 6'h23: begin + irq_timer_len <= cpu_dout; + if (cpu_dout == 0) begin + if (~timer_tap) begin + irq_timer <= 1; + end else begin + irq_pending <= 1; + end + end + end + 6'h26: sys_ctl <= cpu_dout; + endcase + end + end + end + + if (reset) begin + irq_timer <= 0; + irq_pending <= 0; + irq_timer_len <= 0; + nmi_clk <= 0; + sys_ctl <= 0; + link_ddr <= 0; + nmi_latch <= 0; + link_data <= 0; + end +end + +spram #(.addr_width(13)) wram +( + .clock(clk_sys), + .address(AB[12:0]), + .data(DO), + .wren(cpu_we && wram_cs && phi2), + .q(wram_dout) +); + +dpram #(.addr_width(14)) vram +( + .clock(clk_sys), + .address_a(dma_en ? vram_addr : AB[13:0]), + .data_a(DO), + .q_a(vram_dout), + .wren_a((dma_en ? dma_dir : (vram_cs && cpu_we)) && phi2), + + .address_b(lcd_addr), + .q_b(lcd_din) +); + +dma dma +( + .clk (clk_sys), + .ce (phi1), + .reset (reset), + .AB (AB[5:0]), + .cpu_rwn (~cpu_we), + .dma_cs (sys_cs), + .lcd_en (sys_ctl[3]), + .data_in (cpu_dout), + .vbus_addr (vram_addr), + .cbus_addr (dma_addr), + .dma_en (dma_en), + .dma_dir (dma_dir) +); + +audio audio +( + .clk (clk_sys), + .ce (phi1), + .reset (reset), + .cpu_rwn (~cpu_we), + .snd_cs (sys_cs), + .AB (AB[5:0]), + .dbus_in (adma_read ? DII : cpu_dout), + .adma_irq_n (irq_adma_n), + .prescaler (nmi_clk), + .adma_read (adma_read), + .adma_bank (adma_bank), + .adma_addr (adma_addr), + .CH1 (audio_right), + .CH2 (audio_left) +); + +lcd lcd +( + .clk (clk_sys), + .ce (phi2), + .compat60 (compat60), + .reset (reset), + .lcd_cs (sys_cs), + .cpu_rwn (~cpu_we), + .AB (AB[5:0]), + .dbus_in (cpu_dout), + .ce_pix (pix_ce), + .pixel (pixel), + .lcd_off (~sys_ctl[3] || (cpu_we && sys_cs && AB[5:0] == 16'h26)), + .vram_data (lcd_din), + .vram_addr (lcd_addr), + .hsync (hsync), + .vsync (vsync), + .hblank (hblank), + .vblank (vblank) +); + +r65c02_tc cpu3 +( + .clk_clk_i (clk_sys), + .d_i (cpu_rwn ? DII : DO), + .ce (phi1 && cpu_rdy), + .irq_n_i (~(irq_timer_masked | irq_adma_masked)), + .nmi_n_i (~nmi_masked), + .rdy_i (1), // This system seems to halt the clock for dma rather than use traditional rdy + .rst_rst_n_i (~reset), + .so_n_i (1), + .a_o (cpu_addr), + .d_o (cpu_dout), + .rd_o (), + .sync_o (), + .wr_n_o (cpu_rwn), + .wr_o () +); + +endmodule \ No newline at end of file diff --git a/Console_MiST/Supervision_MiST/rtl/video.sv b/Console_MiST/Supervision_MiST/rtl/video.sv deleted file mode 100644 index d8dc884d..00000000 --- a/Console_MiST/Supervision_MiST/rtl/video.sv +++ /dev/null @@ -1,88 +0,0 @@ - -module video( - - input clk,//vga - input clk7p16,//rgb - output ce_pxl, - input white, - // from lcd ctrl registers - input ce, - input [7:0] lcd_xsize, - input [7:0] lcd_ysize, - input [7:0] lcd_xscroll, - input [7:0] lcd_yscroll, - output lcd_pulse, - - // to/from vram - output [12:0] addr, - input [7:0] data, - - // to vga interface - output hsync, - output vsync, - output hblank, - output vblank, - output reg [7:0] red, - output reg [7:0] green, - output reg [7:0] blue -); - -reg [9:0] hcount; -reg [9:0] vcount; -assign lcd_pulse = ce_pxl; -// VGA industry standard 640x480@60 800 525 31.5 - - 25.2 16 96 48 10 2 33 MHi modelines table -// visible area | front porch back porch -// 640 | 32 < 48 > 112 -assign hsync = ~((hcount >= 672) && (hcount < 720)); -assign vsync = ~((vcount >= 481) && (vcount < 484)); -assign hblank = hcount > 639; -assign vblank = vcount > 479; - - -// convert vga coordinates to lcd coordinates (with borders) -wire [8:0] vgax = hcount < 640 ? hcount[9:1] : 9'd0; // 0 - 319 -wire [8:0] vgay = vcount < 480 ? vcount[9:1] : 9'd0; // 0 - 239 -wire [7:0] lcdx = vgax >= 80 && vgax < 240 ? vgax - 8'd80 : 8'd0; // 0-79(80)|80-239(160)|240-319(80) -wire [7:0] lcdy = vgay >= 40 && vgay < 200 ? vgay - 8'd40 : 8'd0; // 0-39(40)|40-199(160)|200-239(40) - - -// calcul vram address (TODO include xsize, ysize, xscroll[1:0] in calculation) -//assign addr = lcd_yscroll * 8'h30 + lcd_xscroll[7:2] + lcdy * 8'h30 + lcdx[7:2]; -assign addr = lcdy * 8'h30 + lcdx[7:2]; - -assign ce_pxl = hcount[0] == 1; - -// assign colors -wire [2:0] index = { lcdx[1:0], 1'b0 }; - -always @(posedge clk) - if (ce && lcdx != 0 && lcdy != 0) begin - if (ce_pxl) begin - case ({white,data[index+:2]}) - 3'b000: { red, green, blue } <= 24'h87BA6B;//lightest colour - 3'b001: { red, green, blue } <= 24'h6BA378;//1/3rd darkness - 3'b010: { red, green, blue } <= 24'h386B82;//2/3rd darkness - 3'b011: { red, green, blue } <= 24'h384052;//dark as possible - - 3'b100: { red, green, blue } <= 24'hFFFFFF;//white - 3'b101: { red, green, blue } <= 24'hC0C0C0;//light gray - 3'b110: { red, green, blue } <= 24'h808080;//gray - 3'b111: { red, green, blue } <= 24'h000000;//black - endcase - end - end - else - { red, green, blue } <= 24'h0; - -always @(posedge clk) begin - hcount <= hcount + 10'd1; - if (hcount == 10'd799) hcount <= 0; -end - -always @(posedge clk) - if (hcount == 10'd799) - vcount <= vcount + 10'd1; - else if (vcount == 10'd509) - vcount <= 0; - -endmodule \ No newline at end of file