├── doc ├── ST4081S.PDF ├── MC68901UM.pdf ├── ShifterSchemWip.zip └── Atari_STe_Schematic_Rev_A_C300780-001_Oct_3_1989.pdf ├── mist ├── cyc10 │ ├── .qsys_edit │ │ ├── filters.xml │ │ ├── preferences.xml │ │ └── vidclkcntrl_schematic.nlv │ ├── vidclkcntrl │ │ ├── vidclkcntrl_bb.v │ │ ├── vidclkcntrl.cmp │ │ ├── vidclkcntrl_inst.v │ │ ├── vidclkcntrl.ppf │ │ ├── vidclkcntrl_inst.vhd │ │ ├── synthesis │ │ │ ├── vidclkcntrl.v │ │ │ ├── vidclkcntrl.qip │ │ │ ├── submodules │ │ │ │ └── vidclkcntrl_altclkctrl_0.v │ │ │ └── vidclkcntrl.debuginfo │ │ ├── vidclkcntrl.bsf │ │ ├── vidclkcntrl.xml │ │ └── vidclkcntrl.html │ ├── clock.qip │ ├── clock32.qip │ ├── clock32.ppf │ ├── clock.ppf │ ├── vidclkcntrl.qsys │ └── vidclkcntrl.sopcinfo ├── cyc3 │ ├── vidclkcntrl.qip │ ├── clock.qip │ ├── clock32.qip │ ├── clock32.ppf │ ├── clock.ppf │ └── vidclkcntrl.v ├── MiSTery_SiDi128.sdc ├── mist.dpf ├── Makefile ├── mist.qip ├── mist.qpf ├── MiSTery_SiDi128.qpf ├── i2s.v ├── cofi.sv ├── video_cleaner.v ├── rgb2ypbpr.v ├── i2c_master.v ├── sigma_delta_dac.v ├── mist_video.v ├── mist.sdc ├── osd.v ├── data_io.v ├── scandoubler.v └── spdif.v ├── .gitignore ├── .gitmodules ├── atarist ├── ste_joypad.v ├── mfp_srff16.v ├── mste_ctrl.v ├── mfp_hbit16.v ├── io_fifo.v ├── atarist.qip ├── acsi.v ├── viking.v ├── cubase2_dongle.v ├── tg68k.v ├── mfp_timer.v ├── sdram.v ├── cubase3_dongle.v └── ethernec.v └── README.md /doc/ST4081S.PDF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyurco/MiSTery/HEAD/doc/ST4081S.PDF -------------------------------------------------------------------------------- /doc/MC68901UM.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyurco/MiSTery/HEAD/doc/MC68901UM.pdf -------------------------------------------------------------------------------- /doc/ShifterSchemWip.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyurco/MiSTery/HEAD/doc/ShifterSchemWip.zip -------------------------------------------------------------------------------- /mist/cyc10/.qsys_edit/filters.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /doc/Atari_STe_Schematic_Rev_A_C300780-001_Oct_3_1989.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyurco/MiSTery/HEAD/doc/Atari_STe_Schematic_Rev_A_C300780-001_Oct_3_1989.pdf -------------------------------------------------------------------------------- /mist/cyc3/vidclkcntrl.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name IP_TOOL_NAME "ALTCLKCTRL" 2 | set_global_assignment -name IP_TOOL_VERSION "13.1" 3 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "vidclkcntrl.v"] 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | out/ 2 | output_files/ 3 | db/ 4 | incremental_db/ 5 | greybox_tmp 6 | PLLJ_PLLSPE_INFO.txt 7 | history.db 8 | *.qdf 9 | *.qws 10 | *.bak 11 | *.jdi 12 | *.sof 13 | *.done 14 | *.pin 15 | *.rpt 16 | *.smsg 17 | *.summary 18 | -------------------------------------------------------------------------------- /mist/cyc10/vidclkcntrl/vidclkcntrl_bb.v: -------------------------------------------------------------------------------- 1 | 2 | module vidclkcntrl ( 3 | inclk1x, 4 | inclk0x, 5 | clkselect, 6 | outclk); 7 | 8 | input inclk1x; 9 | input inclk0x; 10 | input clkselect; 11 | output outclk; 12 | endmodule 13 | -------------------------------------------------------------------------------- /mist/MiSTery_SiDi128.sdc: -------------------------------------------------------------------------------- 1 | #************************************************************** 2 | # Create Clock 3 | #************************************************************** 4 | 5 | create_clock -name {clk_50} -period 20.000 -waveform { 0.000 10.000 } [get_ports {CLOCK_50}] 6 | -------------------------------------------------------------------------------- /mist/cyc3/clock.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name IP_TOOL_NAME "ALTPLL" 2 | set_global_assignment -name IP_TOOL_VERSION "13.1" 3 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "clock.v"] 4 | set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "clock.ppf"] 5 | -------------------------------------------------------------------------------- /mist/cyc3/clock32.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name IP_TOOL_NAME "ALTPLL" 2 | set_global_assignment -name IP_TOOL_VERSION "13.1" 3 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "clock32.v"] 4 | set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "clock32.ppf"] 5 | -------------------------------------------------------------------------------- /mist/cyc10/vidclkcntrl/vidclkcntrl.cmp: -------------------------------------------------------------------------------- 1 | component vidclkcntrl is 2 | port ( 3 | inclk1x : in std_logic := 'X'; -- inclk1x 4 | inclk0x : in std_logic := 'X'; -- inclk0x 5 | clkselect : in std_logic := 'X'; -- clkselect 6 | outclk : out std_logic -- outclk 7 | ); 8 | end component vidclkcntrl; 9 | 10 | -------------------------------------------------------------------------------- /mist/cyc10/vidclkcntrl/vidclkcntrl_inst.v: -------------------------------------------------------------------------------- 1 | vidclkcntrl u0 ( 2 | .inclk1x (), // altclkctrl_input.inclk1x 3 | .inclk0x (), // .inclk0x 4 | .clkselect (), // .clkselect 5 | .outclk () // altclkctrl_output.outclk 6 | ); 7 | 8 | -------------------------------------------------------------------------------- /mist/cyc10/clock.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name IP_TOOL_NAME "ALTPLL" 2 | set_global_assignment -name IP_TOOL_VERSION "22.1" 3 | set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{Cyclone 10 LP}" 4 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "clock.v"] 5 | set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "clock.ppf"] 6 | -------------------------------------------------------------------------------- /mist/cyc10/clock32.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name IP_TOOL_NAME "ALTPLL" 2 | set_global_assignment -name IP_TOOL_VERSION "22.1" 3 | set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{Cyclone 10 LP}" 4 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "clock32.v"] 5 | set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "clock32.ppf"] 6 | -------------------------------------------------------------------------------- /mist/cyc10/clock32.ppf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /mist/mist.dpf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /mist/cyc10/.qsys_edit/preferences.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "fx68k"] 2 | path = fx68k 3 | url = https://github.com/mist-devel/fx68k.git 4 | [submodule "gstmcu"] 5 | path = gstmcu 6 | url = https://github.com/gyurco/gstmcu 7 | [submodule "ikbd"] 8 | path = ikbd 9 | url = https://github.com/gyurco/ikbd 10 | [submodule "fdc1772"] 11 | path = fdc1772 12 | url = https://github.com/mist-devel/fdc1772-verilator.git 13 | [submodule "TG68K.C"] 14 | path = TG68K.C 15 | url = https://github.com/TobiFlex/TG68K.C.git 16 | -------------------------------------------------------------------------------- /mist/cyc3/clock32.ppf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /mist/cyc10/vidclkcntrl/vidclkcntrl.ppf: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /mist/cyc10/.qsys_edit/vidclkcntrl_schematic.nlv: -------------------------------------------------------------------------------- 1 | # # File gsaved with Nlview version 6.3.8 2013-12-19 bk=1.2992 VDI=34 GEI=35 2 | # 3 | preplace inst unsaved.altclkctrl_0 -pg 1 -lvl 1 -y 30 4 | preplace inst unsaved -pg 1 -lvl 1 -y 40 -regy -20 5 | preplace netloc EXPORTunsaved(SLAVE)unsaved.altclkctrl_output,(SLAVE)altclkctrl_0.altclkctrl_output) 1 0 1 NJ 6 | preplace netloc EXPORTunsaved(SLAVE)unsaved.altclkctrl_input,(SLAVE)altclkctrl_0.altclkctrl_input) 1 0 1 NJ 7 | levelinfo -pg 1 0 120 310 8 | levelinfo -hier unsaved 130 160 300 9 | -------------------------------------------------------------------------------- /mist/cyc10/clock.ppf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /mist/cyc3/clock.ppf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /mist/cyc10/vidclkcntrl/vidclkcntrl_inst.vhd: -------------------------------------------------------------------------------- 1 | component vidclkcntrl is 2 | port ( 3 | inclk1x : in std_logic := 'X'; -- inclk1x 4 | inclk0x : in std_logic := 'X'; -- inclk0x 5 | clkselect : in std_logic := 'X'; -- clkselect 6 | outclk : out std_logic -- outclk 7 | ); 8 | end component vidclkcntrl; 9 | 10 | u0 : component vidclkcntrl 11 | port map ( 12 | inclk1x => CONNECTED_TO_inclk1x, -- altclkctrl_input.inclk1x 13 | inclk0x => CONNECTED_TO_inclk0x, -- .inclk0x 14 | clkselect => CONNECTED_TO_clkselect, -- .clkselect 15 | outclk => CONNECTED_TO_outclk -- altclkctrl_output.outclk 16 | ); 17 | 18 | -------------------------------------------------------------------------------- /mist/cyc10/vidclkcntrl/synthesis/vidclkcntrl.v: -------------------------------------------------------------------------------- 1 | // vidclkcntrl.v 2 | 3 | // Generated using ACDS version 22.1 922 4 | 5 | `timescale 1 ps / 1 ps 6 | module vidclkcntrl ( 7 | input wire inclk1x, // altclkctrl_input.inclk1x 8 | input wire inclk0x, // .inclk0x 9 | input wire clkselect, // .clkselect 10 | output wire outclk // altclkctrl_output.outclk 11 | ); 12 | 13 | vidclkcntrl_altclkctrl_0 altclkctrl_0 ( 14 | .inclk1x (inclk1x), // altclkctrl_input.inclk1x 15 | .inclk0x (inclk0x), // .inclk0x 16 | .clkselect (clkselect), // .clkselect 17 | .outclk (outclk) // altclkctrl_output.outclk 18 | ); 19 | 20 | endmodule 21 | -------------------------------------------------------------------------------- /mist/Makefile: -------------------------------------------------------------------------------- 1 | QUARTUS_DIR=$(HOME)/altera/13.1/quartus/bin 2 | ### programs ### 3 | MAP=$(QUARTUS_DIR)/quartus_map 4 | FIT=$(QUARTUS_DIR)/quartus_fit 5 | ASM=$(QUARTUS_DIR)/quartus_asm 6 | PGM=$(QUARTUS_DIR)/quartus_pgm 7 | 8 | ### project ### 9 | PROJECT=`pwd`/mist 10 | 11 | TODAY = `date +"%m/%d/%y"` 12 | 13 | ### build rules ### 14 | 15 | # all 16 | all: 17 | @echo Making FPGA programming files ... 18 | @make map 19 | @make fit 20 | @make asm 21 | 22 | map: 23 | @echo Running mapper ... 24 | @$(MAP) $(PROJECT) 25 | 26 | fit: 27 | @echo Running fitter ... 28 | @$(FIT) $(PROJECT) 29 | 30 | asm: 31 | @echo Running assembler ... 32 | @$(ASM) $(PROJECT) 33 | 34 | # clean 35 | clean: 36 | @echo clean 37 | @rm -rf ./out/ 38 | @rm -rf ./db/ 39 | @rm -rf ./incremental_db/ 40 | -------------------------------------------------------------------------------- /mist/mist.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) user_io.v] 2 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) data_io.v] 3 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) mist_video.v] 4 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) scandoubler.v] 5 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) osd.v] 6 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) cofi.sv] 7 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) rgb2ypbpr.v] 8 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) video_cleaner.v] 9 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) i2c_master.v] 10 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) i2s.v] 11 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) spdif.v] -------------------------------------------------------------------------------- /mist/mist.qpf: -------------------------------------------------------------------------------- 1 | # Copyright (C) 1991-2007 Altera Corporation 2 | # Your use of Altera Corporation's design tools, logic functions 3 | # and other software and tools, and its AMPP partner logic 4 | # functions, and any output files from any of the foregoing 5 | # (including device programming or simulation files), and any 6 | # associated documentation or information are expressly subject 7 | # to the terms and conditions of the Altera Program License 8 | # Subscription Agreement, Altera MegaCore Function License 9 | # Agreement, or other applicable license agreement, including, 10 | # without limitation, that your use is for the sole purpose of 11 | # programming logic devices manufactured by Altera and sold by 12 | # Altera or its authorized distributors. Please refer to the 13 | # applicable agreement for further details. 14 | 15 | 16 | 17 | QUARTUS_VERSION = "7.2" 18 | DATE = "22:27:29 October 30, 2007" 19 | 20 | 21 | # Revisions 22 | 23 | PROJECT_REVISION = "mist" 24 | -------------------------------------------------------------------------------- /atarist/ste_joypad.v: -------------------------------------------------------------------------------- 1 | module ste_joypad ( 2 | input [15:0] joy, // R3,L3,R2,L2 3 | // R,L,Y,X 4 | // Start, Select, B, A 5 | // UDLR 6 | input [3:0] din, // pins 1-4 7 | output reg [7:0] dout, // pins 11-14, 1-4 8 | output reg [1:0] buttons // pins 10,6 9 | ); 10 | 11 | // To account for users with a procontroller, 12 | // X is mapped to 9, Y to 8 and Z to 7. 13 | // L and R are mapped to 4 and 6 respectively. 14 | 15 | always @(*) begin 16 | dout = 8'hff; 17 | buttons = 2'b11; 18 | 19 | //#0*U 20 | dout[4] = ~(/*(~din[3] & joy[xx]) | (~din[2] & joy[xx]) | (~din[1] & joy[xx]) |*/ (~din[0] & joy[3])); 21 | //987D 22 | dout[5] = ~((~din[3] & joy[8]) | (~din[2] & joy[9]) | (~din[1] & joy[12]) | (~din[0] & joy[2])); 23 | //654L 24 | dout[6] = ~((~din[3] & joy[11]) |/* (~din[2] & joy[xx]) |*/ (~din[1] & joy[10]) | (~din[0] & joy[1])); 25 | //321R 26 | dout[7] = ~(/*(~din[3] & joy[xx]) | (~din[2] & joy[xx]) | (~din[1] & joy[xx]) |*/ (~din[0] & joy[0])); 27 | //OCBA 28 | buttons[1] = ~((~din[3] & joy[7]) | (~din[2] & joy[6]) | (~din[1] & joy[5]) | (~din[0] & joy[4])); 29 | //Pause 30 | buttons[0] = ~((~din[0] & joy[13])); 31 | end 32 | 33 | endmodule 34 | -------------------------------------------------------------------------------- /mist/MiSTery_SiDi128.qpf: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- # 2 | # 3 | # Copyright (C) 1991-2011 Altera Corporation 4 | # Your use of Altera Corporation's design tools, logic functions 5 | # and other software and tools, and its AMPP partner logic 6 | # functions, and any output files from any of the foregoing 7 | # (including device programming or simulation files), and any 8 | # associated documentation or information are expressly subject 9 | # to the terms and conditions of the Altera Program License 10 | # Subscription Agreement, Altera MegaCore Function License 11 | # Agreement, or other applicable license agreement, including, 12 | # without limitation, that your use is for the sole purpose of 13 | # programming logic devices manufactured by Altera and sold by 14 | # Altera or its authorized distributors. Please refer to the 15 | # applicable agreement for further details. 16 | # 17 | # -------------------------------------------------------------------------- # 18 | # 19 | # Quartus II 20 | # Version 10.1 Build 197 01/19/2011 Service Pack 1 SJ Full Version 21 | # Date created = 23:49:02 July 13, 2012 22 | # 23 | # -------------------------------------------------------------------------- # 24 | 25 | QUARTUS_VERSION = "10.1" 26 | DATE = "23:49:02 July 13, 2012" 27 | 28 | # Revisions 29 | 30 | PROJECT_REVISION = "MiSTery_SiDi128" 31 | -------------------------------------------------------------------------------- /mist/i2s.v: -------------------------------------------------------------------------------- 1 | // taken and tweaked from MiSTer sys/ 2 | 3 | module i2s 4 | ( 5 | input reset, 6 | input clk, 7 | input [31:0] clk_rate, 8 | 9 | output reg sclk, 10 | output reg lrclk, 11 | output reg sdata, 12 | 13 | input [AUDIO_DW-1:0] left_chan, 14 | input [AUDIO_DW-1:0] right_chan 15 | ); 16 | 17 | // Clock Setting 18 | parameter I2S_Freq = 48_000; // 48 KHz 19 | parameter AUDIO_DW = 16; 20 | 21 | localparam I2S_FreqX2 = I2S_Freq*2*AUDIO_DW*2; 22 | 23 | reg [31:0] cnt; 24 | wire [31:0] cnt_next = cnt + I2S_FreqX2; 25 | 26 | reg ce; 27 | 28 | always @(posedge clk) begin 29 | ce <= 0; 30 | cnt <= cnt_next; 31 | if(cnt_next >= clk_rate) begin 32 | cnt <= cnt_next - clk_rate; 33 | ce <= 1; 34 | end 35 | end 36 | 37 | 38 | always @(posedge clk) begin 39 | reg [4:0] bit_cnt = 1; 40 | 41 | reg [AUDIO_DW-1:0] left; 42 | reg [AUDIO_DW-1:0] right; 43 | 44 | if (reset) begin 45 | bit_cnt <= 1; 46 | lrclk <= 1; 47 | sclk <= 1; 48 | sdata <= 1; 49 | sclk <= 1; 50 | end 51 | else begin 52 | if(ce) begin 53 | sclk <= ~sclk; 54 | if(sclk) begin 55 | if(bit_cnt == AUDIO_DW) begin 56 | bit_cnt <= 1; 57 | lrclk <= ~lrclk; 58 | if(lrclk) begin 59 | left <= left_chan; 60 | right <= right_chan; 61 | end 62 | end 63 | else begin 64 | bit_cnt <= bit_cnt + 1'd1; 65 | end 66 | sdata <= lrclk ? right[AUDIO_DW - bit_cnt] : left[AUDIO_DW - bit_cnt]; 67 | end 68 | end 69 | end 70 | end 71 | 72 | endmodule 73 | -------------------------------------------------------------------------------- /atarist/mfp_srff16.v: -------------------------------------------------------------------------------- 1 | // 2 | // mfp_srff16.v 3 | // 4 | // 16 bit set/reset flip flop. Each bit is set on the rising edge of set 5 | // and asynchronoulsy cleared by the corresponding reset bit. 6 | // Asynchronous operation is emulated in a synchronous way by using the 7 | // 32 MHz clock. 8 | // 9 | // https://github.com/mist-devel/mist-board 10 | // 11 | // Copyright (c) 2014 Till Harbaum 12 | // Copyright (c) 2019-2020 Gyorgy Szombathelyi 13 | // 14 | // This source file is free software: you can redistribute it and/or modify 15 | // it under the terms of the GNU General Public License as published 16 | // by the Free Software Foundation, either version 3 of the License, or 17 | // (at your option) any later version. 18 | // 19 | // This source file is distributed in the hope that it will be useful, 20 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | // GNU General Public License for more details. 23 | // 24 | // You should have received a copy of the GNU General Public License 25 | // along with this program. If not, see . 26 | 27 | module mfp_srff16 ( 28 | input clk, 29 | input [15:0] set, 30 | input [15:0] mask, 31 | input [15:0] reset, 32 | output reg [15:0] out 33 | ); 34 | 35 | integer i; 36 | always @(posedge clk) begin 37 | reg [15:0] setD; 38 | 39 | setD <= set; 40 | for(i=0; i<16; i=i+1) begin 41 | if (reset[i]) out[i] <= 0; 42 | else if (~setD[i] & set[i] & mask[i]) out[i] <= 1; 43 | end 44 | end 45 | 46 | endmodule 47 | -------------------------------------------------------------------------------- /atarist/mste_ctrl.v: -------------------------------------------------------------------------------- 1 | // 2 | // mste_ctrl.v 3 | // 4 | // Atari Mega STE cache/cpu controller implementation for the MiST board 5 | // https://github.com/mist-devel/mist-board 6 | // 7 | // Copyright (c) 2013 Till Harbaum 8 | // 9 | // This source file is free software: you can redistribute it and/or modify 10 | // it under the terms of the GNU General Public License as published 11 | // by the Free Software Foundation, either version 3 of the License, or 12 | // (at your option) any later version. 13 | // 14 | // This source file is distributed in the hope that it will be useful, 15 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | // GNU General Public License for more details. 18 | // 19 | // You should have received a copy of the GNU General Public License 20 | // along with this program. If not, see . 21 | 22 | module mste_ctrl ( 23 | // cpu register interface 24 | input clk, 25 | input reset, 26 | input [7:0] din, 27 | input sel, 28 | input rw, 29 | output reg [7:0] dout, 30 | 31 | output enable_cache, 32 | output enable_16mhz 33 | ); 34 | 35 | assign enable_16mhz = mste_config[1]; 36 | assign enable_cache = mste_config[0]; 37 | 38 | reg [7:0] mste_config; 39 | 40 | always @(sel, rw, mste_config) begin 41 | dout = 8'd0; 42 | if(sel && rw) 43 | dout = mste_config; 44 | end 45 | 46 | always @(posedge clk) begin 47 | if(reset) 48 | mste_config <= 8'h00; 49 | else begin 50 | if(sel && ~rw) 51 | mste_config <= din; 52 | end 53 | end 54 | 55 | endmodule 56 | -------------------------------------------------------------------------------- /mist/cofi.sv: -------------------------------------------------------------------------------- 1 | // Composite-like horizontal blending by Kitrinx 2 | 3 | // AMR - disable shift register recognition 4 | (* altera_attribute = "-name AUTO_SHIFT_REGISTER_RECOGNITION OFF" *) 5 | module cofi ( 6 | input clk, 7 | input pix_ce, 8 | input enable, 9 | 10 | input hblank, 11 | input vblank, 12 | input hs, 13 | input vs, 14 | input [VIDEO_DEPTH-1:0] red, 15 | input [VIDEO_DEPTH-1:0] green, 16 | input [VIDEO_DEPTH-1:0] blue, 17 | 18 | output reg hblank_out, 19 | output reg vblank_out, 20 | output reg hs_out, 21 | output reg vs_out, 22 | output reg [VIDEO_DEPTH-1:0] red_out, 23 | output reg [VIDEO_DEPTH-1:0] green_out, 24 | output reg [VIDEO_DEPTH-1:0] blue_out, 25 | output reg pix_ce_out 26 | ); 27 | 28 | parameter VIDEO_DEPTH=8; 29 | 30 | function bit [VIDEO_DEPTH-1:0] color_blend ( 31 | input [VIDEO_DEPTH-1:0] color_prev, 32 | input [VIDEO_DEPTH-1:0] color_curr, 33 | input blank_last 34 | ); 35 | begin 36 | color_blend = blank_last ? color_curr : (color_prev >> 1) + (color_curr >> 1); 37 | end 38 | endfunction 39 | 40 | reg [VIDEO_DEPTH-1:0] red_last; 41 | reg [VIDEO_DEPTH-1:0] green_last; 42 | reg [VIDEO_DEPTH-1:0] blue_last; 43 | 44 | wire ce = enable ? pix_ce : 1'b1; 45 | always @(posedge clk) begin 46 | pix_ce_out <= 0; 47 | if (ce) begin 48 | hblank_out <= hblank; 49 | vblank_out <= vblank; 50 | vs_out <= vs; 51 | hs_out <= hs; 52 | pix_ce_out <= pix_ce; 53 | 54 | red_last <= red; 55 | blue_last <= blue; 56 | green_last <= green; 57 | 58 | red_out <= enable ? color_blend(red_last, red, hblank_out) : red; 59 | blue_out <= enable ? color_blend(blue_last, blue, hblank_out) : blue; 60 | green_out <= enable ? color_blend(green_last, green, hblank_out) : green; 61 | end 62 | end 63 | 64 | endmodule 65 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MiSTery - An Atari ST/STe core for FPGAs 2 | 3 | ## Features: 4 | 5 | - Cycle accurate STe GLUE+MMU combo (re-created from the [original schematics](https://www.chzsoft.de/asic-web/)) 6 | - Cycle accurate [FX68K CPU core](https://github.com/ijor/fx68k) 7 | - Cycle accurate Blitter offered by Jorge Cwik 8 | - Mostly cycle accurate shifter based on [schematics made from reverse engineering](http://www.atari-forum.com/viewtopic.php?t=29658) 9 | - MegaSTe 16 MHz CPU mode 10 | - Turbo bus - double RAM access speed 11 | - RAM size up to 14MB 12 | - Support for all TOS versions 13 | - 2 Floppy disc drives 14 | - ACSI hard disc support 15 | - Viking compatible hi-res monochrome card support 16 | - [Real IKBD](https://github.com/harbaum/ikbd) with HD63701 MCU 17 | - Real MIDI input/output using MiST's UART pins 18 | - Serial/parallel port redirect to USB 19 | - Internal Cubase dongle 20 | - Gauntlet type 4 joystick interface support 21 | - STe controller port support 22 | - RP5C15 RTC Chip 23 | - Ethernet interface in cartridge port (Ethernec) support 24 | - [USB-RTC](https://github.com/mist-devel/mist-board/wiki/UsbRtc) support 25 | - Optional scandoubled/YPbPr video output 26 | - Currently it runs on the [MiST board](https://github.com/mist-devel/mist-board/wiki), but the code is modular, so it's possible to add other boards 27 | 28 | ## Usage for [MiST](https://github.com/mist-devel/mist-board/wiki): 29 | 30 | Put the core.rbf and the TOS as tos.img to the SD-Card. TOS/hard disc/floppy images are selectable in the OSD (F12). 31 | With F11, you can toggle between normal and STe joystick ports. 32 | 33 | ## Current issues/limitations: 34 | 35 | - No RAM cache for Mega STe (but the cache control selects turbo bus speed) 36 | - Only fake LMC1992 37 | - PAL clock only (32.084 MHz) 38 | - Since Jagpads have 21 buttons, not all are mapped to MiST controllers when using STe game ports 39 | - No STe paddle handling (but it has 0 software support) 40 | 41 | ## Thanks to: 42 | 43 | - Till Harbaum for the MiST board, original MiST core, new IKBD code 44 | - Jorge Cwik for the FX68K CPU core, FX ST Blitter code and shifter decap 45 | - Christian Zietz for recovering the schematics of the GSTMCU 46 | -------------------------------------------------------------------------------- /mist/video_cleaner.v: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Copyright (c) 2018 Sorgelig 4 | // 5 | // This program is GPL Licensed. See COPYING for the full license. 6 | // 7 | // 8 | //////////////////////////////////////////////////////////////////////////////////////////////////////// 9 | 10 | `timescale 1ns / 1ps 11 | 12 | // Align VBlank/VSync to HBlank/HSync edges. 13 | // Warning! Breaks interlaced VSync. 14 | 15 | module video_cleaner 16 | ( 17 | input clk_vid, 18 | input ce_pix, 19 | input enable, 20 | 21 | input [COLOR_DEPTH-1:0] R, 22 | input [COLOR_DEPTH-1:0] G, 23 | input [COLOR_DEPTH-1:0] B, 24 | 25 | input HSync, 26 | input VSync, 27 | input HBlank, 28 | input VBlank, 29 | 30 | // video output signals 31 | output reg [COLOR_DEPTH-1:0] VGA_R, 32 | output reg [COLOR_DEPTH-1:0] VGA_G, 33 | output reg [COLOR_DEPTH-1:0] VGA_B, 34 | output reg VGA_VS, 35 | output reg VGA_HS, 36 | 37 | // optional aligned blank 38 | output reg HBlank_out, 39 | output reg VBlank_out 40 | ); 41 | 42 | parameter COLOR_DEPTH = 8; 43 | 44 | wire hs, vs; 45 | s_fix sync_v(clk_vid, HSync, hs); 46 | s_fix sync_h(clk_vid, VSync, vs); 47 | 48 | wire hbl = hs | HBlank; 49 | wire vbl = vs | VBlank; 50 | 51 | always @(posedge clk_vid) begin 52 | if(!enable) begin 53 | HBlank_out <= HBlank; 54 | VBlank_out <= VBlank; 55 | VGA_HS <= HSync; 56 | VGA_VS <= VSync; 57 | VGA_R <= R; 58 | VGA_G <= G; 59 | VGA_B <= B; 60 | end else 61 | if(ce_pix) begin 62 | HBlank_out <= hbl; 63 | 64 | VGA_HS <= hs; 65 | if(~VGA_HS & hs) VGA_VS <= vs; 66 | 67 | VGA_R <= R; 68 | VGA_G <= G; 69 | VGA_B <= B; 70 | 71 | if(HBlank_out & ~hbl) VBlank_out <= vbl; 72 | end 73 | end 74 | 75 | endmodule 76 | 77 | module s_fix 78 | ( 79 | input clk, 80 | 81 | input sync_in, 82 | output sync_out 83 | ); 84 | 85 | assign sync_out = sync_in ^ pol; 86 | 87 | reg pol; 88 | always @(posedge clk) begin 89 | integer pos = 0, neg = 0, cnt = 0; 90 | reg s1,s2; 91 | 92 | s1 <= sync_in; 93 | s2 <= s1; 94 | 95 | if(~s2 & s1) neg <= cnt; 96 | if(s2 & ~s1) pos <= cnt; 97 | 98 | cnt <= cnt + 1; 99 | if(s2 != s1) cnt <= 0; 100 | 101 | pol <= pos > neg; 102 | end 103 | 104 | endmodule 105 | -------------------------------------------------------------------------------- /atarist/mfp_hbit16.v: -------------------------------------------------------------------------------- 1 | // 2 | // mfp_hbit16.v 3 | // 4 | // determines the index of the highest bit set in a 16 bit array 5 | // 6 | // https://github.com/mist-devel/mist-board 7 | // 8 | // Copyright (c) 2014 Till Harbaum 9 | // Copyright (c) 2019-2020 Gyorgy Szombathelyi 10 | // 11 | // This source file is free software: you can redistribute it and/or modify 12 | // it under the terms of the GNU General Public License as published 13 | // by the Free Software Foundation, either version 3 of the License, or 14 | // (at your option) any later version. 15 | // 16 | // This source file is distributed in the hope that it will be useful, 17 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | // GNU General Public License for more details. 20 | // 21 | // You should have received a copy of the GNU General Public License 22 | // along with this program. If not, see . 23 | 24 | module mfp_hbit16 ( 25 | input [15:0] value, 26 | output [15:0] mask, 27 | output [3:0] index 28 | ); 29 | 30 | assign index = 31 | (value[15] == 1'b1)?4'd15: 32 | (value[15:14] == 2'b1)?4'd14: 33 | (value[15:13] == 3'b1)?4'd13: 34 | (value[15:12] == 4'b1)?4'd12: 35 | (value[15:11] == 5'b1)?4'd11: 36 | (value[15:10] == 6'b1)?4'd10: 37 | (value[15:9] == 7'b1)?4'd9: 38 | (value[15:8] == 8'b1)?4'd8: 39 | (value[15:7] == 9'b1)?4'd7: 40 | (value[15:6] == 10'b1)?4'd6: 41 | (value[15:5] == 11'b1)?4'd5: 42 | (value[15:4] == 12'b1)?4'd4: 43 | (value[15:3] == 13'b1)?4'd3: 44 | (value[15:2] == 14'b1)?4'd2: 45 | (value[15:1] == 15'b1)?4'd1: 46 | (value[15:0] == 16'b1)?4'd0: 47 | 4'd0; 48 | 49 | assign mask = 50 | (value[15] == 1'b1)?16'h8000: 51 | (value[15:14] == 2'b1)?16'h4000: 52 | (value[15:13] == 3'b1)?16'h2000: 53 | (value[15:12] == 4'b1)?16'h1000: 54 | (value[15:11] == 5'b1)?16'h0800: 55 | (value[15:10] == 6'b1)?16'h0400: 56 | (value[15:9] == 7'b1)?16'h0200: 57 | (value[15:8] == 8'b1)?16'h0100: 58 | (value[15:7] == 9'b1)?16'h0080: 59 | (value[15:6] == 10'b1)?16'h0040: 60 | (value[15:5] == 11'b1)?16'h0020: 61 | (value[15:4] == 12'b1)?16'h0010: 62 | (value[15:3] == 13'b1)?16'h0008: 63 | (value[15:2] == 14'b1)?16'h0004: 64 | (value[15:1] == 15'b1)?16'h0002: 65 | (value[15:0] == 16'b1)?16'h0001: 66 | 16'h0000; 67 | 68 | endmodule 69 | -------------------------------------------------------------------------------- /mist/rgb2ypbpr.v: -------------------------------------------------------------------------------- 1 | // Multiplier-based RGB -> YPbPr conversion 2 | 3 | // Copyright 2020/2021 by Alastair M. Robinson 4 | 5 | (* altera_attribute = "-name AUTO_SHIFT_REGISTER_RECOGNITION OFF" *) 6 | module RGBtoYPbPr 7 | ( 8 | input clk, 9 | input ena, 10 | 11 | input [WIDTH-1:0] red_in, 12 | input [WIDTH-1:0] green_in, 13 | input [WIDTH-1:0] blue_in, 14 | input hs_in, 15 | input vs_in, 16 | input hb_in, 17 | input vb_in, 18 | input cs_in, 19 | input pixel_in, 20 | 21 | output [WIDTH-1:0] red_out, 22 | output [WIDTH-1:0] green_out, 23 | output [WIDTH-1:0] blue_out, 24 | output reg hs_out, 25 | output reg vs_out, 26 | output reg hb_out, 27 | output reg vb_out, 28 | output reg cs_out, 29 | output reg pixel_out 30 | ); 31 | 32 | parameter WIDTH = 8; 33 | 34 | reg [8+WIDTH-1:0] r_y; 35 | reg [8+WIDTH-1:0] g_y; 36 | reg [8+WIDTH-1:0] b_y; 37 | 38 | reg [8+WIDTH-1:0] r_b; 39 | reg [8+WIDTH-1:0] g_b; 40 | reg [8+WIDTH-1:0] b_b; 41 | 42 | reg [8+WIDTH-1:0] r_r; 43 | reg [8+WIDTH-1:0] g_r; 44 | reg [8+WIDTH-1:0] b_r; 45 | 46 | reg [8+WIDTH-1:0] y; 47 | reg [8+WIDTH-1:0] b; 48 | reg [8+WIDTH-1:0] r; 49 | 50 | reg hs_d; 51 | reg vs_d; 52 | reg cs_d; 53 | reg pixel_d; 54 | reg hb_d; 55 | reg vb_d; 56 | 57 | assign red_out = r[8+WIDTH-1:8]; 58 | assign green_out = y[8+WIDTH-1:8]; 59 | assign blue_out = b[8+WIDTH-1:8]; 60 | 61 | // Multiply in the first stage... 62 | always @(posedge clk) begin 63 | hs_d <= hs_in; // Register sync, pixel clock, etc 64 | vs_d <= vs_in; // so they're delayed the same amount as the incoming video 65 | cs_d <= cs_in; 66 | pixel_d <= pixel_in; 67 | hb_d <= hb_in; 68 | vb_d <= vb_in; 69 | 70 | if(ena) begin 71 | // (Y = 0.299*R + 0.587*G + 0.114*B) 72 | r_y <= red_in * 8'd76; 73 | g_y <= green_in * 8'd150; 74 | b_y <= blue_in * 8'd29; 75 | 76 | // (Pb = -0.169*R - 0.331*G + 0.500*B) 77 | r_b <= red_in * 8'd43; 78 | g_b <= green_in * 8'd84; 79 | b_b <= blue_in * 8'd128; 80 | 81 | // (Pr = 0.500*R - 0.419*G - 0.081*B) 82 | r_r <= red_in * 8'd128; 83 | g_r <= green_in * 8'd107; 84 | b_r <= blue_in * 8'd20; 85 | end else begin 86 | r_r[8+WIDTH-1:8] <= red_in; // Passthrough 87 | g_y[8+WIDTH-1:8] <= green_in; 88 | b_b[8+WIDTH-1:8] <= blue_in; 89 | end 90 | 91 | end 92 | 93 | // Second stage - adding 94 | 95 | always @(posedge clk) begin 96 | hs_out <= hs_d; 97 | vs_out <= vs_d; 98 | cs_out <= cs_d; 99 | pixel_out <= pixel_d; 100 | hb_out <= hb_d; 101 | vb_out <= vb_d; 102 | 103 | if(ena) begin 104 | y <= r_y + g_y + b_y; 105 | b <= 2'd2**(8+WIDTH-1) + b_b - r_b - g_b; 106 | r <= 2'd2**(8+WIDTH-1) + r_r - g_r - b_r; 107 | end else begin 108 | y <= g_y; // Passthrough 109 | b <= b_b; 110 | r <= r_r; 111 | end 112 | end 113 | 114 | endmodule 115 | -------------------------------------------------------------------------------- /mist/cyc10/vidclkcntrl.qsys: -------------------------------------------------------------------------------- 1 | 2 | 3 | 10 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 46 | 47 | 48 | 49 | 50 | 55 | 56 | 57 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /atarist/io_fifo.v: -------------------------------------------------------------------------------- 1 | // 2 | // io_fifo.v 3 | // 4 | // Atari ST(E) io controller FIFO for the MiST board 5 | // https://github.com/mist-devel/mist-board 6 | // 7 | // Copyright (c) 2013 Till Harbaum 8 | // 9 | // This source file is free software: you can redistribute it and/or modify 10 | // it under the terms of the GNU General Public License as published 11 | // by the Free Software Foundation, either version 3 of the License, or 12 | // (at your option) any later version. 13 | // 14 | // This source file is distributed in the hope that it will be useful, 15 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | // GNU General Public License for more details. 18 | // 19 | // You should have received a copy of the GNU General Public License 20 | // along with this program. If not, see . 21 | 22 | // TODO: Make this truly async 23 | // http://www.asic-world.com/examples/verilog/asyn_fifo.html 24 | 25 | module io_fifo #( 26 | parameter DATA_WIDTH = 8, 27 | parameter DEPTH = 4 28 | )( 29 | input reset, 30 | 31 | input [DATA_WIDTH-1:0] in, 32 | input in_clk, 33 | input in_strobe, 34 | input in_enable, 35 | 36 | input out_clk, 37 | output [DATA_WIDTH-1:0] out, 38 | input out_strobe, 39 | input out_enable, 40 | 41 | output [DEPTH-1:0] space, 42 | output empty, 43 | output data_available, 44 | output full 45 | ); 46 | 47 | localparam FIFO_ADDR_BITS = DEPTH; 48 | localparam FIFO_DEPTH = (1 << FIFO_ADDR_BITS); 49 | 50 | reg [DATA_WIDTH-1:0] fifo [FIFO_DEPTH-1:0]; 51 | reg [FIFO_ADDR_BITS-1:0] writeP, readP; 52 | 53 | assign full = (readP == (writeP + 1)); 54 | assign empty = (readP == writeP); 55 | assign data_available = (readP != writeP); 56 | 57 | assign space = readP - writeP - 1'd1; 58 | 59 | // the strobes may not be in the right clock domain, so bring them into the 60 | // local clock domain 61 | reg in_strobeD, in_strobeD2; 62 | reg out_strobeD, out_strobeD2; 63 | 64 | // present current value. If fifo is empty show last value 65 | assign out = data_available?fifo[readP]:fifo[readP-1'd1]; 66 | 67 | always @(posedge out_clk) begin 68 | // bring strobes in local clock domain 69 | out_strobeD <= out_strobe; 70 | out_strobeD2 <= out_strobeD; 71 | 72 | if(reset) 73 | readP <= 0; 74 | else begin 75 | // rising edge on fifo read strobe from io controller 76 | if((out_strobeD && !out_strobeD2) || out_enable) 77 | readP <= readP + 1'd1; 78 | end 79 | end 80 | 81 | always @(posedge in_clk) begin 82 | // bring strobes in local clock domain 83 | in_strobeD <= in_strobe; 84 | in_strobeD2 <= in_strobeD; 85 | 86 | if(reset) 87 | writeP <= 0; 88 | else begin 89 | // rising edge on strobe signal causes write 90 | // or in_enable being true 91 | if((in_strobeD && !in_strobeD2) || in_enable) begin 92 | fifo[writeP] <= in; 93 | writeP <= writeP + 1'd1; 94 | end 95 | end 96 | end 97 | 98 | endmodule -------------------------------------------------------------------------------- /mist/i2c_master.v: -------------------------------------------------------------------------------- 1 | // taken and tweaked from MiSTer sys/ 2 | module i2c_master 3 | ( 4 | input CLK, 5 | 6 | input I2C_START, 7 | input I2C_READ, 8 | input [6:0] I2C_ADDR, 9 | input [7:0] I2C_SUBADDR, 10 | input [7:0] I2C_WDATA, 11 | output [7:0] I2C_RDATA, 12 | output reg I2C_END = 1, 13 | output reg I2C_ACK = 0, 14 | 15 | //I2C bus 16 | inout I2C_SCL, 17 | inout I2C_SDA 18 | ); 19 | 20 | 21 | // Clock Setting 22 | parameter CLK_Freq = 50_000_000; // 50 MHz 23 | parameter I2C_Freq = 400_000; // 400 KHz 24 | 25 | localparam I2C_FreqX2 = I2C_Freq*2; 26 | 27 | reg I2C_CLOCK; 28 | reg [31:0] cnt; 29 | wire [31:0] cnt_next = cnt + I2C_FreqX2; 30 | 31 | always @(posedge CLK) begin 32 | cnt <= cnt_next; 33 | if(cnt_next >= CLK_Freq) begin 34 | cnt <= cnt_next - CLK_Freq; 35 | I2C_CLOCK <= ~I2C_CLOCK; 36 | end 37 | end 38 | 39 | reg SCLK; 40 | reg [7:0] SDO; 41 | reg [0:7] rdata; 42 | 43 | reg [6:0] SD_COUNTER; 44 | reg [0:42] SD; 45 | 46 | assign I2C_SCL = (SCLK | I2C_CLOCK) ? 1'bZ : 1'b0; 47 | assign I2C_SDA = SDO[7] ? 1'bZ : 1'b0; 48 | 49 | initial begin 50 | SD_COUNTER = 'b1111111; 51 | SD = {40'hFFFFFFFFFF, 3'b111}; 52 | SCLK = 1; 53 | SDO = 8'hFF; 54 | end 55 | 56 | assign I2C_RDATA = rdata; 57 | 58 | always @(posedge CLK) begin 59 | reg old_clk; 60 | reg old_st; 61 | reg rd; 62 | reg sda_in; 63 | 64 | old_clk <= I2C_CLOCK; 65 | old_st <= I2C_START; 66 | sda_in <= I2C_SDA; 67 | 68 | // delay to make sure SDA changed while SCL is stabilized at low 69 | if(old_clk && ~I2C_CLOCK && ~SD_COUNTER[6]) SDO[0] <= SD[SD_COUNTER[5:0]]; 70 | SDO[7:1] <= SDO[6:0]; 71 | 72 | if(~old_st && I2C_START) begin 73 | SCLK <= 1; 74 | SDO <= 8'hFF; 75 | I2C_ACK <= 0; 76 | I2C_END <= 0; 77 | rd <= I2C_READ; 78 | if(I2C_READ) SD[0:42] <= {2'b10, I2C_ADDR, 1'b0, 1'b1, I2C_SUBADDR, 3'b110, I2C_ADDR, 1'b1, 1'b1, 8'b11111111, 4'b1011}; 79 | else SD[0:31] <= {2'b10, I2C_ADDR, 1'b0, 1'b1, I2C_SUBADDR, 1'b1, I2C_WDATA, 4'b1011}; 80 | SD_COUNTER <= 0; 81 | end else begin 82 | if(~old_clk && I2C_CLOCK && ~SD_COUNTER[6]) begin 83 | SD_COUNTER <= SD_COUNTER + 6'd1; 84 | case(SD_COUNTER) 85 | 01: SCLK <= 0; 86 | 10: I2C_ACK <= ~sda_in; 87 | 19: I2C_ACK <= ~sda_in; 88 | 20: if (rd) SCLK <= 1; // repeated start 89 | 21: if (rd) SCLK <= 0; 90 | 28: if (~rd) I2C_ACK <= ~sda_in; 91 | 29: if (~rd) SCLK <= 1; 92 | 30: if (rd) I2C_ACK <= ~sda_in; 93 | 32: if (~rd) begin 94 | I2C_END <= 1; 95 | SD_COUNTER <= 64; 96 | end 97 | 40: SCLK <= 1; 98 | 42: begin 99 | I2C_END <= 1; 100 | SD_COUNTER <= 64; 101 | end 102 | 64: SCLK <= 1; 103 | default: ; 104 | endcase 105 | 106 | if(SD_COUNTER >= 31 && SD_COUNTER <= 38) rdata[SD_COUNTER[5:0]-31] <= sda_in; 107 | end 108 | end 109 | end 110 | 111 | endmodule -------------------------------------------------------------------------------- /mist/cyc10/vidclkcntrl/vidclkcntrl.bsf: -------------------------------------------------------------------------------- 1 | /* 2 | WARNING: Do NOT edit the input and output ports in this file in a text 3 | editor if you plan to continue editing the block that represents it in 4 | the Block Editor! File corruption is VERY likely to occur. 5 | */ 6 | /* 7 | Copyright (C) 2023 Intel Corporation. All rights reserved. 8 | Your use of Intel Corporation's design tools, logic functions 9 | and other software and tools, and any partner logic 10 | functions, and any output files from any of the foregoing 11 | (including device programming or simulation files), and any 12 | associated documentation or information are expressly subject 13 | to the terms and conditions of the Intel Program License 14 | Subscription Agreement, the Intel Quartus Prime License Agreement, 15 | the Intel FPGA IP License Agreement, or other applicable license 16 | agreement, including, without limitation, that your use is for 17 | the sole purpose of programming logic devices manufactured by 18 | Intel and sold by Intel or its authorized distributors. Please 19 | refer to the applicable agreement for further details, at 20 | https://fpgasoftware.intel.com/eula. 21 | */ 22 | (header "symbol" (version "1.1")) 23 | (symbol 24 | (rect 0 0 288 136) 25 | (text "vidclkcntrl" (rect 115 -1 153 11)(font "Arial" (font_size 10))) 26 | (text "inst" (rect 8 120 20 132)(font "Arial" )) 27 | (port 28 | (pt 0 72) 29 | (input) 30 | (text "inclk1x" (rect 0 0 24 12)(font "Arial" (font_size 8))) 31 | (text "inclk1x" (rect 4 61 46 72)(font "Arial" (font_size 8))) 32 | (line (pt 0 72)(pt 96 72)(line_width 1)) 33 | ) 34 | (port 35 | (pt 0 88) 36 | (input) 37 | (text "inclk0x" (rect 0 0 25 12)(font "Arial" (font_size 8))) 38 | (text "inclk0x" (rect 4 77 46 88)(font "Arial" (font_size 8))) 39 | (line (pt 0 88)(pt 96 88)(line_width 1)) 40 | ) 41 | (port 42 | (pt 0 104) 43 | (input) 44 | (text "clkselect" (rect 0 0 33 12)(font "Arial" (font_size 8))) 45 | (text "clkselect" (rect 4 93 58 104)(font "Arial" (font_size 8))) 46 | (line (pt 0 104)(pt 96 104)(line_width 1)) 47 | ) 48 | (port 49 | (pt 288 72) 50 | (output) 51 | (text "outclk" (rect 0 0 22 12)(font "Arial" (font_size 8))) 52 | (text "outclk" (rect 258 61 294 72)(font "Arial" (font_size 8))) 53 | (line (pt 288 72)(pt 176 72)(line_width 1)) 54 | ) 55 | (drawing 56 | (text "altclkctrl_input" (rect 13 43 122 99)(font "Arial" (color 128 0 0)(font_size 9))) 57 | (text "inclk1x" (rect 101 67 244 144)(font "Arial" (color 0 0 0))) 58 | (text "inclk0x" (rect 101 83 244 176)(font "Arial" (color 0 0 0))) 59 | (text "clkselect" (rect 101 99 256 208)(font "Arial" (color 0 0 0))) 60 | (text "altclkctrl_output" (rect 177 43 456 99)(font "Arial" (color 128 0 0)(font_size 9))) 61 | (text "outclk" (rect 148 67 332 144)(font "Arial" (color 0 0 0))) 62 | (text " system " (rect 253 120 554 250)(font "Arial" )) 63 | (line (pt 96 32)(pt 176 32)(line_width 1)) 64 | (line (pt 176 32)(pt 176 120)(line_width 1)) 65 | (line (pt 96 120)(pt 176 120)(line_width 1)) 66 | (line (pt 96 32)(pt 96 120)(line_width 1)) 67 | (line (pt 97 52)(pt 97 108)(line_width 1)) 68 | (line (pt 98 52)(pt 98 108)(line_width 1)) 69 | (line (pt 175 52)(pt 175 76)(line_width 1)) 70 | (line (pt 174 52)(pt 174 76)(line_width 1)) 71 | (line (pt 0 0)(pt 288 0)(line_width 1)) 72 | (line (pt 288 0)(pt 288 136)(line_width 1)) 73 | (line (pt 0 136)(pt 288 136)(line_width 1)) 74 | (line (pt 0 0)(pt 0 136)(line_width 1)) 75 | ) 76 | ) 77 | -------------------------------------------------------------------------------- /atarist/atarist.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) YM2149.vhd] 2 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) ../atarist/vol_table_array.vhd] 3 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../atarist/viking.v] 4 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../atarist/ste_joypad.v] 5 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ../atarist/stBlitter.sv] 6 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../atarist/sdram.v] 7 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../atarist/mste_ctrl.v] 8 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../atarist/mfp.v] 9 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../atarist/mfp_timer.v] 10 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../atarist/mfp_srff16.v] 11 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../atarist/mfp_hbit16.v] 12 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../atarist/io_fifo.v] 13 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../atarist/ethernec.v] 14 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../atarist/dma.v] 15 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ../atarist/atarist_sdram.sv] 16 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../atarist/acsi.v] 17 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../atarist/gen_uart.v] 18 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../atarist/cubase3_dongle.v] 19 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../atarist/cubase2_dongle.v] 20 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../gstmcu/hdl/shifter_video.v] 21 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../gstmcu/hdl/register.v] 22 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../gstmcu/hdl/mcucontrol.v] 23 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../gstmcu/hdl/latch.v] 24 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../gstmcu/hdl/gstshifter.v] 25 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../gstmcu/hdl/gstmcu.v] 26 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../gstmcu/hdl/clockgen.v] 27 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ../fx68k/uaddrPla.sv] 28 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ../fx68k/fx68kAlu.sv] 29 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ../fx68k/fx68k.sv] 30 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../fx68k/altera_regs.v] 31 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) ../TG68K.C/TG68KdotC_Kernel.vhd] 32 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) ../TG68K.C/TG68K_Pack.vhd] 33 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) ../TG68K.C/TG68K_ALU.vhd] 34 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../fdc1772/floppy.v] 35 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../fdc1772/fdc1772.v] 36 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ../ikbd/ps2.sv] 37 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ../ikbd/ikbd.sv] 38 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../ikbd/hd63701/HD63701.v] 39 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../ikbd/hd63701/HD63701_SEQ.v] 40 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../ikbd/hd63701/HD63701_MCROM.v] 41 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../ikbd/hd63701/HD63701_EXEC.v] 42 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../ikbd/hd63701/HD63701_CORE.v] 43 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../ikbd/hd63701/HD63701_ALU.v] 44 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../ikbd/rom/MCU_BIROM.v] 45 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../atarist/tg68k.v] 46 | 47 | -------------------------------------------------------------------------------- /atarist/acsi.v: -------------------------------------------------------------------------------- 1 | // acsi.v 2 | // 3 | // Atari ST ACSI implementation for the MIST board 4 | // https://github.com/mist-devel/mist-board 5 | // 6 | // Copyright (c) 2015 Till Harbaum 7 | // 8 | // This source file is free software: you can redistribute it and/or modify 9 | // it under the terms of the GNU General Public License as published 10 | // by the Free Software Foundation, either version 3 of the License, or 11 | // (at your option) any later version. 12 | // 13 | // This source file is distributed in the hope that it will be useful, 14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | // GNU General Public License for more details. 17 | // 18 | // You should have received a copy of the GNU General Public License 19 | // along with this program. If not, see . 20 | // 21 | 22 | module acsi ( 23 | // clocks and system interface 24 | input clk, 25 | input clk_en, 26 | input reset, 27 | 28 | input [7:0] enable, 29 | 30 | input dma_ack, // IO controller answers request 31 | input dma_nak, // IO controller rejects request 32 | input [7:0] dma_status, 33 | 34 | 35 | input [3:0] status_sel, // 10 command bytes + 1 status byte 36 | output [7:0] status_byte, 37 | 38 | // cpu interface 39 | input cpu_a1, 40 | input cpu_sel, 41 | input cpu_rw, 42 | input [7:0] cpu_din, 43 | output [7:0] cpu_dout, 44 | 45 | output reg irq 46 | ); 47 | 48 | reg cpu_selD; 49 | always @(posedge clk) if (clk_en) cpu_selD <= cpu_sel; 50 | wire cpu_req = ~cpu_selD & cpu_sel; 51 | 52 | // acsi always returns dma status on cpu_read 53 | assign cpu_dout = dma_status; 54 | 55 | // Total number of command bytes: 56 | // cmd 0..1f -> 6 57 | // cmd 20..5f -> 10 58 | // cmd 80..9f -> 16 59 | // cmd a0..bf -> 12 60 | 61 | wire [7:0] cmd_code = cmd_parameter[0]; 62 | wire [3:0] parms = 63 | ((cmd_code >= 8'h00)&&(cmd_code <= 8'h1f))?4'd5: 64 | ((cmd_code >= 8'h20)&&(cmd_code <= 8'h5f))?4'd9: 65 | ((cmd_code >= 8'h80)&&(cmd_code <= 8'h9f))?4'd15: 66 | 4'd11; 67 | 68 | reg [2:0] target; 69 | reg [3:0] byte_counter; 70 | reg [7:0] cmd_parameter [15:0]; 71 | reg busy; 72 | 73 | // acsi status as reported to the io controller 74 | assign status_byte = 75 | (status_sel == 0)?cmd_parameter[0]: 76 | (status_sel == 1)?cmd_parameter[1]: 77 | (status_sel == 2)?cmd_parameter[2]: 78 | (status_sel == 3)?cmd_parameter[3]: 79 | (status_sel == 4)?cmd_parameter[4]: 80 | (status_sel == 5)?cmd_parameter[5]: 81 | (status_sel == 6)?cmd_parameter[6]: 82 | (status_sel == 7)?cmd_parameter[7]: 83 | (status_sel == 8)?cmd_parameter[8]: 84 | (status_sel == 9)?cmd_parameter[9]: 85 | (status_sel == 10)?{ target, 4'b0000000, busy }: 86 | 8'h00; 87 | 88 | // CPU write interface 89 | always @(posedge clk) begin 90 | if(reset) begin 91 | target <= 3'd0; 92 | irq <= 1'b0; 93 | busy <= 1'b0; 94 | end else begin 95 | 96 | // DMA transfer has been ack'd by io controller 97 | if(dma_ack && busy) begin 98 | irq <= 1'b1; // set acsi irq 99 | busy <= 1'd0; 100 | end 101 | 102 | // DMA transfer has been rejected by io controller (no such device) 103 | if(dma_nak) 104 | busy <= 1'd0; 105 | 106 | // cpu is accessing acsi bus -> clear acsi irq 107 | // status itself is returned by the io controller with the dma_ack. 108 | if(clk_en && cpu_req) 109 | irq <= 1'b0; 110 | 111 | // acsi register access 112 | if(clk_en && cpu_req && !cpu_rw) begin 113 | if(!cpu_a1) begin 114 | // a0 == 0 -> first command byte 115 | target <= cpu_din[7:5]; 116 | 117 | // icd command? 118 | if(cpu_din[4:0] == 5'h1f) 119 | byte_counter <= 3'd0; // next byte will contain first command byte 120 | else begin 121 | cmd_parameter[0] <= { 3'd0, cpu_din[4:0] }; 122 | byte_counter <= 3'd1; // next byte will contain second command byte 123 | end 124 | 125 | // check if this acsi device is enabled 126 | if(enable[cpu_din[7:5]] == 1'b1) 127 | irq <= 1'b1; 128 | end else begin 129 | 130 | // if(byte_counter < 15) begin 131 | 132 | // further bytes 133 | cmd_parameter[byte_counter] <= cpu_din; 134 | byte_counter <= byte_counter + 3'd1; 135 | 136 | // check if this acsi device is enabled 137 | if(enable[target] == 1'b1) begin 138 | // auto-ack first 5 bytes, 6 bytes in case of icd command 139 | if(byte_counter < parms) 140 | irq <= 1'b1; 141 | else 142 | busy <= 1'b1; // request io cntroller 143 | end 144 | end 145 | // end 146 | end 147 | end 148 | end 149 | 150 | endmodule // acsi 151 | -------------------------------------------------------------------------------- /mist/cyc10/vidclkcntrl/synthesis/vidclkcntrl.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -entity "vidclkcntrl" -library "vidclkcntrl" -name IP_TOOL_NAME "Qsys" 2 | set_global_assignment -entity "vidclkcntrl" -library "vidclkcntrl" -name IP_TOOL_VERSION "22.1" 3 | set_global_assignment -entity "vidclkcntrl" -library "vidclkcntrl" -name IP_TOOL_ENV "Qsys" 4 | set_global_assignment -library "vidclkcntrl" -name SOPCINFO_FILE [file join $::quartus(qip_path) "../../vidclkcntrl.sopcinfo"] 5 | set_global_assignment -entity "vidclkcntrl" -library "vidclkcntrl" -name SLD_INFO "QSYS_NAME vidclkcntrl HAS_SOPCINFO 1 GENERATION_ID 1729161809" 6 | set_global_assignment -library "vidclkcntrl" -name MISC_FILE [file join $::quartus(qip_path) "../vidclkcntrl.cmp"] 7 | set_global_assignment -library "vidclkcntrl" -name SLD_FILE [file join $::quartus(qip_path) "vidclkcntrl.debuginfo"] 8 | set_global_assignment -entity "vidclkcntrl" -library "vidclkcntrl" -name IP_TARGETED_DEVICE_FAMILY "Cyclone 10 LP" 9 | set_global_assignment -entity "vidclkcntrl" -library "vidclkcntrl" -name IP_GENERATED_DEVICE_FAMILY "{Cyclone 10 LP}" 10 | set_global_assignment -entity "vidclkcntrl" -library "vidclkcntrl" -name IP_QSYS_MODE "STANDALONE" 11 | set_global_assignment -name SYNTHESIS_ONLY_QIP ON 12 | set_global_assignment -library "vidclkcntrl" -name MISC_FILE [file join $::quartus(qip_path) "../../vidclkcntrl.qsys"] 13 | set_global_assignment -entity "vidclkcntrl" -library "vidclkcntrl" -name IP_COMPONENT_NAME "dmlkY2xrY250cmw=" 14 | set_global_assignment -entity "vidclkcntrl" -library "vidclkcntrl" -name IP_COMPONENT_DISPLAY_NAME "dmlkY2xrY250cmw=" 15 | set_global_assignment -entity "vidclkcntrl" -library "vidclkcntrl" -name IP_COMPONENT_REPORT_HIERARCHY "On" 16 | set_global_assignment -entity "vidclkcntrl" -library "vidclkcntrl" -name IP_COMPONENT_INTERNAL "Off" 17 | set_global_assignment -entity "vidclkcntrl" -library "vidclkcntrl" -name IP_COMPONENT_VERSION "MS4w" 18 | set_global_assignment -entity "vidclkcntrl" -library "vidclkcntrl" -name IP_COMPONENT_PARAMETER "QVVUT19HRU5FUkFUSU9OX0lE::MTcyOTE2MTgwOQ==::QXV0byBHRU5FUkFUSU9OX0lE" 19 | set_global_assignment -entity "vidclkcntrl" -library "vidclkcntrl" -name IP_COMPONENT_PARAMETER "QVVUT19ERVZJQ0VfRkFNSUxZ::Q3ljbG9uZSAxMCBMUA==::QXV0byBERVZJQ0VfRkFNSUxZ" 20 | set_global_assignment -entity "vidclkcntrl" -library "vidclkcntrl" -name IP_COMPONENT_PARAMETER "QVVUT19ERVZJQ0U=::MTBDTDEyMFlGNDg0QzhH::QXV0byBERVZJQ0U=" 21 | set_global_assignment -entity "vidclkcntrl" -library "vidclkcntrl" -name IP_COMPONENT_PARAMETER "QVVUT19ERVZJQ0VfU1BFRURHUkFERQ==::OA==::QXV0byBERVZJQ0VfU1BFRURHUkFERQ==" 22 | set_global_assignment -entity "vidclkcntrl_altclkctrl_0" -library "vidclkcntrl" -name IP_COMPONENT_NAME "dmlkY2xrY250cmxfYWx0Y2xrY3RybF8w" 23 | set_global_assignment -entity "vidclkcntrl_altclkctrl_0" -library "vidclkcntrl" -name IP_COMPONENT_DISPLAY_NAME "QUxUQ0xLQ1RSTCBJbnRlbCBGUEdBIElQ" 24 | set_global_assignment -entity "vidclkcntrl_altclkctrl_0" -library "vidclkcntrl" -name IP_COMPONENT_REPORT_HIERARCHY "Off" 25 | set_global_assignment -entity "vidclkcntrl_altclkctrl_0" -library "vidclkcntrl" -name IP_COMPONENT_INTERNAL "Off" 26 | set_global_assignment -entity "vidclkcntrl_altclkctrl_0" -library "vidclkcntrl" -name IP_COMPONENT_AUTHOR "SW50ZWwgQ29ycG9yYXRpb24=" 27 | set_global_assignment -entity "vidclkcntrl_altclkctrl_0" -library "vidclkcntrl" -name IP_COMPONENT_VERSION "MjIuMQ==" 28 | set_global_assignment -entity "vidclkcntrl_altclkctrl_0" -library "vidclkcntrl" -name IP_COMPONENT_PARAMETER "REVWSUNFX0ZBTUlMWQ==::Q3ljbG9uZSAxMCBMUA==::RGV2aWNlIEZhbWlseQ==" 29 | set_global_assignment -entity "vidclkcntrl_altclkctrl_0" -library "vidclkcntrl" -name IP_COMPONENT_PARAMETER "Q0xPQ0tfVFlQRQ==::MQ==::SG93IGRvIHlvdSB3YW50IHRvIHVzZSB0aGUgQUxUQ0xLQ1RSTD8=" 30 | set_global_assignment -entity "vidclkcntrl_altclkctrl_0" -library "vidclkcntrl" -name IP_COMPONENT_PARAMETER "TlVNQkVSX09GX0NMT0NLUw==::Mg==::SG93IG1hbnkgY2xvY2sgaW5wdXRzIHdvdWxkIHlvdSBsaWtlPw==" 31 | set_global_assignment -entity "vidclkcntrl_altclkctrl_0" -library "vidclkcntrl" -name IP_COMPONENT_PARAMETER "R1VJX1VTRV9FTkE=::ZmFsc2U=::Q3JlYXRlICdlbmEnIHBvcnQgdG8gZW5hYmxlIG9yIGRpc2FibGUgdGhlIGNsb2NrIG5ldHdvcmsgZHJpdmVuIGJ5IHRoaXMgYnVmZmVyPw==" 32 | set_global_assignment -entity "vidclkcntrl_altclkctrl_0" -library "vidclkcntrl" -name IP_COMPONENT_PARAMETER "VVNFX0dMSVRDSF9GUkVFX1NXSVRDSF9PVkVSX0lNUExFTUVOVEFUSU9O::dHJ1ZQ==::RW5zdXJlIGdsaXRjaC1mcmVlIHN3aXRjaG92ZXIgaW1wbGVtZW50YXRpb24=" 33 | 34 | set_global_assignment -library "vidclkcntrl" -name VERILOG_FILE [file join $::quartus(qip_path) "vidclkcntrl.v"] 35 | set_global_assignment -library "vidclkcntrl" -name VERILOG_FILE [file join $::quartus(qip_path) "submodules/vidclkcntrl_altclkctrl_0.v"] 36 | 37 | set_global_assignment -entity "vidclkcntrl_altclkctrl_0" -library "vidclkcntrl" -name IP_TOOL_NAME "altclkctrl" 38 | set_global_assignment -entity "vidclkcntrl_altclkctrl_0" -library "vidclkcntrl" -name IP_TOOL_VERSION "22.1" 39 | set_global_assignment -entity "vidclkcntrl_altclkctrl_0" -library "vidclkcntrl" -name IP_TOOL_ENV "Qsys" 40 | -------------------------------------------------------------------------------- /atarist/viking.v: -------------------------------------------------------------------------------- 1 | // 2 | // viking.v 3 | // 4 | // Atari ST(E) Viking/SM194 5 | // https://github.com/mist-devel/mist-board 6 | // 7 | // Copyright (c) 2013-2015 Till Harbaum 8 | // 9 | // This source file is free software: you can redistribute it and/or modify 10 | // it under the terms of the GNU General Public License as published 11 | // by the Free Software Foundation, either version 3 of the License, or 12 | // (at your option) any later version. 13 | // 14 | // This source file is distributed in the hope that it will be useful, 15 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | // GNU General Public License for more details. 18 | // 19 | // You should have received a copy of the GNU General Public License 20 | // along with this program. If not, see . 21 | 22 | // The viking card does not have its own CPU interface as it is not 23 | // configurable in any way. It just etches data from ram and displays 24 | // it on screen. 25 | 26 | module viking ( 27 | input pclk, // 128 MHz pixel clock 28 | 29 | // memory interface 30 | input himem, // use memory behind rom 31 | input clk_8_en, // 8 MHz bus clock 32 | input [1:0] bus_cycle, // bus-cycle for bus access sync 33 | output reg [22:0] addr, // video word address 34 | output read, // video read cycle 35 | input [63:0] data, // video data read 36 | 37 | // VGA output (multiplexed with sm124 output in top level) 38 | output hs, 39 | output vs, 40 | output hb, 41 | output vb, 42 | output [3:0] r, 43 | output [3:0] g, 44 | output [3:0] b 45 | ); 46 | 47 | localparam BASE = 23'h600000; // c00000 48 | localparam BASE_HI = 23'h740000; // e80000 49 | 50 | // total width must be multiple of 64, so video runs synchronous 51 | // to main bus 52 | 53 | // Horizontal timing 54 | // HBP1 | H | HFP | HS | HBP2 55 | // -----|XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX|-----|____|----- 56 | // HBP1 is used for prefetch 57 | 58 | // 1280x 59 | localparam H = 1280; 60 | localparam HFP = 88; 61 | localparam HS = 136; 62 | localparam HBP1 = 64; 63 | localparam HBP2 = 160; 64 | 65 | // Vertical timing 66 | // V | VFP | VS | VBP 67 | // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX|-----|____|----- 68 | 69 | // x1024 70 | localparam V = 1024; 71 | localparam VFP = 9; 72 | localparam VS = 4; 73 | localparam VBP = 9; 74 | 75 | assign read = (bus_cycle == 1) && me; // memory enable can directly be used as a ram read signal 76 | 77 | // --------------------------------------------------------------------------- 78 | // --------------------------- internal state counter ------------------------ 79 | // --------------------------------------------------------------------------- 80 | 81 | reg [3:0] t; 82 | always @(posedge pclk) begin 83 | reg clk_8_enD; 84 | 85 | clk_8_enD <= clk_8_en; 86 | // clk_8_en is at the middle of the cycle 87 | if (~clk_8_enD & clk_8_en) t <= 4'hD; else t <= t + 1'd1; 88 | end 89 | 90 | // create internal bus_cycle signal 91 | reg [5:0] bus_cycle_L; 92 | always @(posedge pclk) 93 | bus_cycle_L <= { bus_cycle, t }; 94 | 95 | 96 | // --------------- horizontal timing ------------- 97 | reg[10:0] h_cnt; // 0..2047 98 | assign hs = ((h_cnt >= HBP1+H+HFP) && (h_cnt < HBP1+H+HFP+HS))?1'b0:1'b1; 99 | always@(posedge pclk) begin 100 | if(h_cnt==HBP1+H+HFP+HS+HBP2-1) begin 101 | // make sure a line starts with the "video" bus cyle (0) 102 | // cpu has cycles 1 and 2 103 | if(bus_cycle_L == 6'h2e) 104 | h_cnt<=0; 105 | end else 106 | h_cnt <= h_cnt + 1'd1; 107 | end 108 | 109 | // --------------- vertical timing ------------- 110 | reg[10:0] v_cnt; // 0..2047 111 | assign vs = ((v_cnt >= V+VFP) && (v_cnt < V+VFP+VS))?1'b0:1'b1; 112 | always@(posedge pclk) begin 113 | if(h_cnt==HBP1+H+HFP+HS+HBP2-1) begin 114 | if(v_cnt==V+VFP+VS+VBP-1) v_cnt <= 0; 115 | else v_cnt <= v_cnt+1'd1; 116 | end 117 | end 118 | 119 | reg [63:0] input_latch; 120 | reg [63:0] shift_register; 121 | 122 | // ---------------- memory timing ---------------- 123 | always@(posedge pclk) begin 124 | // last line on screen 125 | if(v_cnt == V+VFP+VS+VBP-2) 126 | addr <= himem?BASE_HI:BASE; 127 | else if(me && bus_cycle_L == 6'h1e) // directly after read 128 | addr <= addr + 23'd4; // advance 4 words (64 bits) 129 | 130 | if(me && (bus_cycle_L == 6'h1e)) 131 | input_latch <= data; 132 | 133 | if(bus_cycle_L == 6'h2e) 134 | // reorder words 1:2:3:4 -> 4:3:2:1 135 | shift_register <= 136 | { input_latch[15:0], input_latch[31:16], 137 | input_latch[47:32], input_latch[63:48] }; 138 | else 139 | shift_register[63:1] <= shift_register[62:0]; 140 | end 141 | 142 | // memory enable (data is being read from memory) 143 | wire me = (v_cnt < V)&&(h_cnt < H); 144 | // display enable (data is being displayed) 145 | wire hde = (h_cnt >= HBP1)&&(h_cnt < HBP1+H); 146 | wire vde = v_cnt < V; 147 | wire de = hde | vde; 148 | assign hb = ~hde; 149 | assign vb = ~vde; 150 | 151 | wire pix = de?(!shift_register[63]):1'b0; 152 | 153 | // drive all 12 rgb bits from the data bit 154 | wire [3:0] pix4 = { pix, pix, pix, pix }; 155 | assign r = pix4; 156 | assign g = pix4; 157 | assign b = pix4; 158 | 159 | endmodule 160 | -------------------------------------------------------------------------------- /atarist/cubase2_dongle.v: -------------------------------------------------------------------------------- 1 | module cubase2_dongle ( 2 | input clk, 3 | input reset, // POR actually 4 | input uds_n, 5 | input [8:1] A, 6 | output reg [15:8] D 7 | ); 8 | 9 | reg uds_nD; 10 | always @(posedge clk) begin 11 | uds_nD <= uds_n; 12 | if (reset) begin 13 | D <= 0; 14 | end 15 | else 16 | if (uds_n & !uds_nD) begin 17 | D[15] <= !( (A[8] & A[7] & !A[6] & A[5] & A[4] & !A[3] & !A[2] & !A[1]) 18 | | ( D[14] & D[12] & D[10] & A[1] ) 19 | | ( D[13] & !D[10] & A[4] ) 20 | | ( !D[15] & !D[14] & !D[13] & !D[12] & !D[11] & D[10] & !D[9] & A[4] ) 21 | | ( !D[14] & !D[10] & A[1]) 22 | | ( D[15] & !D[10] & A[4] ) 23 | | ( !D[12] & !D[10] & A[1]) 24 | | ( !D[8] & A[5])); 25 | 26 | D[14] <= !((A[8] & A[7] & !A[6] & A[5] & A[4] & !A[3] & !A[2] & !A[1] ) 27 | | ( !D[15] & !D[14] & !D[13] & !D[12] & !D[11] & !D[10] & !D[9] & D[8] & A[4]) 28 | | ( D[14] & D[12] & D[10] & D[8] & A[1] ) 29 | | ( !D[10] & !D[8] & A[1] ) 30 | | ( !D[12] & !D[8] & A[1] ) 31 | | ( D[15] & !D[8] & A[4]) 32 | | ( !D[14] & !D[8] & A[1] ) 33 | | ( !D[15] & A[5])); 34 | 35 | D[13] <= !((A[8] & A[7] & !A[6] & A[5] & A[4] & !A[3] & !A[2] & !A[1] ) 36 | | ( D[15] & D[14] & D[13] & D[12] & D[11] & D[10] & D[8] & A[1] ) 37 | | ( !D[15] & !D[13] & D[11] & A[4] ) 38 | | ( D[13] & !D[11] & A[4] ) 39 | | ( !D[12] & !D[11] & A[1] ) 40 | | ( D[15] & !D[11] & A[4] ) 41 | | ( !D[14] & !D[11] & A[1] ) 42 | | ( !D[9] & A[5])); 43 | 44 | D[12] <= !((A[8] & A[7] & !A[6] & A[5] & A[4] & !A[3] & !A[2] & !A[1]) 45 | | ( D[15] & D[14] & D[13] & D[12] & D[10] & D[8] & A[1] ) 46 | | ( !D[13] & !D[10] & A[1] ) 47 | | ( !D[15] & D[13] & A[4] ) 48 | | ( !D[13] & !D[12] & A[1] ) 49 | | ( D[15] & !D[13] & A[4] ) 50 | | ( !D[14] & !D[13] & A[1] ) 51 | | ( !D[11] & A[5])); 52 | 53 | D[11] <= !((A[8] & A[7] & !A[6] & A[5] & A[4] & !A[3] & !A[2] & !A[1]) 54 | | ( D[15] & D[14] & D[12] & D[10] & D[8] & A[1] ) 55 | | ( !D[15] & !D[8] & A[1] ) 56 | | ( !D[15] & !D[10] & A[1] ) 57 | | ( !D[15] & !D[12] & A[1] ) 58 | | ( !D[15] & !D[14] & A[1] ) 59 | | ( D[15] & A[4] ) 60 | | ( !D[13] & A[5])); 61 | 62 | D[10] <= !((A[8] & A[7] & !A[6] & A[5] & A[4] & !A[3] & !A[2] & !A[1] ) 63 | | ( D[15] & D[14] & D[13] & D[12] & D[11] & D[10] & D[9] & D[8] & A[1] ) 64 | | ( !D[15] & !D[13] & !D[11] & D[9] & A[4] ) 65 | | ( D[11] & !D[9] & A[4] ) 66 | | ( D[13] & !D[9] & A[4] ) 67 | | ( D[15] & !D[9] & A[4] ) 68 | | ( !D[14] & !D[9] & A[1] ) 69 | | ( !D[14] & A[5])); 70 | 71 | D[9] <= !((A[8] & A[7] & !A[6] & A[5] & A[4] & !A[3] & !A[2] & !A[1] ) 72 | | ( !D[15] & D[14] & !D[13] & !D[11] & !D[9] & A[4] ) 73 | | ( !D[14] & D[9] & A[4] ) 74 | | ( !D[14] & D[11] & A[4] ) 75 | | ( !D[14] & D[13] & A[4] ) 76 | | ( D[15] & !D[14] & A[4] ) 77 | | ( D[14] & A[1] ) 78 | | ( !D[12] & A[5])); 79 | 80 | D[8] <= !((A[8] & A[7] & !A[6] & A[5] & A[4] & !A[3] & !A[2] & !A[1] ) 81 | | ( !D[15] & !D[14] & !D[13] & D[12] & !D[11] & !D[9] & A[4] ) 82 | | ( D[14] & D[12] & A[1] ) 83 | | ( !D[12] & D[11] & A[4] ) 84 | | ( D[13] & !D[12] & A[4] ) 85 | | ( D[15] & !D[12] & A[4] ) 86 | | ( !D[14] & !D[12] & A[1] ) 87 | | ( !D[10] & A[5] )); 88 | end 89 | 90 | end 91 | 92 | endmodule 93 | -------------------------------------------------------------------------------- /mist/sigma_delta_dac.v: -------------------------------------------------------------------------------- 1 | // sigmadelta.v 2 | // two channel second order sigma delta dac 3 | // taken from Minimig 4 | 5 | // audio data processing 6 | // stereo sigma/delta bitstream modulator 7 | module sigma_delta_dac ( 8 | input clk, // bus clock 9 | input [14:0] ldatasum, // left channel data 10 | input [14:0] rdatasum, // right channel data 11 | output reg left=0, // left bitstream output 12 | output reg right=0 // right bitsteam output 13 | ); 14 | 15 | //-------------------------------------------------------------------------------------- 16 | 17 | // local signals 18 | localparam DW = 15; 19 | localparam CW = 2; 20 | localparam RW = 4; 21 | localparam A1W = 2; 22 | localparam A2W = 5; 23 | 24 | wire [DW+2+0 -1:0] sd_l_er0, sd_r_er0; 25 | reg [DW+2+0 -1:0] sd_l_er0_prev=0, sd_r_er0_prev=0; 26 | wire [DW+A1W+2-1:0] sd_l_aca1, sd_r_aca1; 27 | wire [DW+A2W+2-1:0] sd_l_aca2, sd_r_aca2; 28 | reg [DW+A1W+2-1:0] sd_l_ac1=0, sd_r_ac1=0; 29 | reg [DW+A2W+2-1:0] sd_l_ac2=0, sd_r_ac2=0; 30 | wire [DW+A2W+3-1:0] sd_l_quant, sd_r_quant; 31 | 32 | // LPF noise LFSR 33 | reg [24-1:0] seed1 = 24'h654321; 34 | reg [19-1:0] seed2 = 19'h12345; 35 | reg [24-1:0] seed_sum=0, seed_prev=0, seed_out=0; 36 | always @ (posedge clk) begin 37 | if (&seed1) 38 | seed1 <= #1 24'h654321; 39 | else 40 | seed1 <= #1 {seed1[22:0], ~(seed1[23] ^ seed1[22] ^ seed1[21] ^ seed1[16])}; 41 | end 42 | always @ (posedge clk) begin 43 | if (&seed2) 44 | seed2 <= #1 19'h12345; 45 | else 46 | seed2 <= #1 {seed2[17:0], ~(seed2[18] ^ seed2[17] ^ seed2[16] ^ seed2[13] ^ seed2[0])}; 47 | end 48 | always @ (posedge clk) begin 49 | seed_sum <= #1 seed1 + {5'b0, seed2}; 50 | seed_prev <= #1 seed_sum; 51 | seed_out <= #1 seed_sum - seed_prev; 52 | end 53 | 54 | // linear interpolate 55 | localparam ID=4; // counter size, also 2^ID = interpolation rate 56 | reg [ID+0-1:0] int_cnt = 0; 57 | always @ (posedge clk) int_cnt <= #1 int_cnt + 1'd1; 58 | 59 | reg [DW+0-1:0] ldata_cur=0, ldata_prev=0; 60 | reg [DW+0-1:0] rdata_cur=0, rdata_prev=0; 61 | wire [DW+1-1:0] ldata_step, rdata_step; 62 | reg [DW+ID-1:0] ldata_int=0, rdata_int=0; 63 | wire [DW+0-1:0] ldata_int_out, rdata_int_out; 64 | assign ldata_step = {ldata_cur[DW-1], ldata_cur} - {ldata_prev[DW-1], ldata_prev}; // signed subtract 65 | assign rdata_step = {rdata_cur[DW-1], rdata_cur} - {rdata_prev[DW-1], rdata_prev}; // signed subtract 66 | always @ (posedge clk) begin 67 | if (~|int_cnt) begin 68 | ldata_prev <= #1 ldata_cur; 69 | ldata_cur <= #1 ldatasum; //{~ldatasum[DW-1], ldatasum[DW-2:0]}; // convert to offset binary, samples no longer signed! 70 | rdata_prev <= #1 rdata_cur; 71 | rdata_cur <= #1 rdatasum; //{~rdatasum[DW-1], rdatasum[DW-2:0]}; // convert to offset binary, samples no longer signed! 72 | ldata_int <= #1 {ldata_cur[DW-1], ldata_cur, {ID{1'b0}}}; 73 | rdata_int <= #1 {rdata_cur[DW-1], rdata_cur, {ID{1'b0}}}; 74 | end else begin 75 | ldata_int <= #1 ldata_int + {{ID{ldata_step[DW+1-1]}}, ldata_step}; 76 | rdata_int <= #1 rdata_int + {{ID{rdata_step[DW+1-1]}}, rdata_step}; 77 | end 78 | end 79 | assign ldata_int_out = ldata_int[DW+ID-1:ID]; 80 | assign rdata_int_out = rdata_int[DW+ID-1:ID]; 81 | 82 | // input gain x3 83 | wire [DW+2-1:0] ldata_gain, rdata_gain; 84 | assign ldata_gain = {ldata_int_out[DW-1], ldata_int_out, 1'b0} + {{(2){ldata_int_out[DW-1]}}, ldata_int_out}; 85 | assign rdata_gain = {rdata_int_out[DW-1], rdata_int_out, 1'b0} + {{(2){rdata_int_out[DW-1]}}, rdata_int_out}; 86 | 87 | /* 88 | // random dither to 15 bits 89 | reg [DW-1:0] ldata=0, rdata=0; 90 | always @ (posedge clk) begin 91 | ldata <= #1 ldata_gain[DW+2-1:2] + ( (~(&ldata_gain[DW+2-1-1:2]) && (ldata_gain[1:0] > seed_out[1:0])) ? 15'd1 : 15'd0 ); 92 | rdata <= #1 rdata_gain[DW+2-1:2] + ( (~(&ldata_gain[DW+2-1-1:2]) && (ldata_gain[1:0] > seed_out[1:0])) ? 15'd1 : 15'd0 ); 93 | end 94 | */ 95 | 96 | // accumulator adders 97 | assign sd_l_aca1 = {{(A1W){ldata_gain[DW+2-1]}}, ldata_gain} - {{(A1W){sd_l_er0[DW+2-1]}}, sd_l_er0} + sd_l_ac1; 98 | assign sd_r_aca1 = {{(A1W){rdata_gain[DW+2-1]}}, rdata_gain} - {{(A1W){sd_r_er0[DW+2-1]}}, sd_r_er0} + sd_r_ac1; 99 | 100 | assign sd_l_aca2 = {{(A2W-A1W){sd_l_aca1[DW+A1W+2-1]}}, sd_l_aca1} - {{(A2W){sd_l_er0[DW+2-1]}}, sd_l_er0} - {{(A2W+1){sd_l_er0_prev[DW+2-1]}}, sd_l_er0_prev[DW+2-1:1]} + sd_l_ac2; 101 | assign sd_r_aca2 = {{(A2W-A1W){sd_r_aca1[DW+A1W+2-1]}}, sd_r_aca1} - {{(A2W){sd_r_er0[DW+2-1]}}, sd_r_er0} - {{(A2W+1){sd_r_er0_prev[DW+2-1]}}, sd_r_er0_prev[DW+2-1:1]} + sd_r_ac2; 102 | 103 | // accumulators 104 | always @ (posedge clk) begin 105 | sd_l_ac1 <= #1 sd_l_aca1; 106 | sd_r_ac1 <= #1 sd_r_aca1; 107 | sd_l_ac2 <= #1 sd_l_aca2; 108 | sd_r_ac2 <= #1 sd_r_aca2; 109 | end 110 | 111 | // value for quantizaton 112 | assign sd_l_quant = {sd_l_ac2[DW+A2W+2-1], sd_l_ac2} + {{(DW+A2W+3-RW){seed_out[RW-1]}}, seed_out[RW-1:0]}; 113 | assign sd_r_quant = {sd_r_ac2[DW+A2W+2-1], sd_r_ac2} + {{(DW+A2W+3-RW){seed_out[RW-1]}}, seed_out[RW-1:0]}; 114 | 115 | // error feedback 116 | assign sd_l_er0 = sd_l_quant[DW+A2W+3-1] ? {1'b1, {(DW+2-1){1'b0}}} : {1'b0, {(DW+2-1){1'b1}}}; 117 | assign sd_r_er0 = sd_r_quant[DW+A2W+3-1] ? {1'b1, {(DW+2-1){1'b0}}} : {1'b0, {(DW+2-1){1'b1}}}; 118 | always @ (posedge clk) begin 119 | sd_l_er0_prev <= #1 (&sd_l_er0) ? sd_l_er0 : sd_l_er0+1'd1; 120 | sd_r_er0_prev <= #1 (&sd_r_er0) ? sd_r_er0 : sd_r_er0+1'd1; 121 | end 122 | 123 | // output 124 | always @ (posedge clk) begin 125 | left <= #1 (~|ldata_gain) ? ~left : ~sd_l_er0[DW+2-1]; 126 | right <= #1 (~|rdata_gain) ? ~right : ~sd_r_er0[DW+2-1]; 127 | end 128 | 129 | endmodule 130 | -------------------------------------------------------------------------------- /atarist/tg68k.v: -------------------------------------------------------------------------------- 1 | /* 2 | 68000 compatible bus-wrapper for TG68K 3 | */ 4 | 5 | module tg68k ( 6 | input clk, 7 | input reset, 8 | input phi1, 9 | input phi2, 10 | input [1:0] cpu, 11 | 12 | input dtack_n, 13 | output rw_n, 14 | output as_n, 15 | output uds_n, 16 | output lds_n, 17 | output [2:0] fc, 18 | output reset_n, 19 | 20 | output reg E, 21 | output vma_n, 22 | input vpa_n, 23 | 24 | input br_n, 25 | output bg_n, 26 | input bgack_n, 27 | 28 | input [2:0] ipl, 29 | input berr, 30 | input [15:0] din, 31 | output [15:0] dout, 32 | output reg [31:0] addr 33 | ); 34 | 35 | wire [1:0] tg68_busstate; 36 | wire tg68_clkena = phi1 && (s_state == 7 || tg68_busstate == 2'b01); 37 | wire [31:0] tg68_addr; 38 | wire [15:0] tg68_din; 39 | reg [15:0] tg68_din_r; 40 | wire tg68_uds_n; 41 | wire tg68_lds_n; 42 | wire tg68_rw; 43 | 44 | // The tg68k core doesn't reliably support mixed usage of autovector and non-autovector 45 | // interrupts, so the TG68K kernel switched to non-autovector interrupts, and the 46 | // auto-vectors are provided here. 47 | wire auto_iack = fc == 3'b111 && !vpa_n; 48 | wire [7:0] auto_vector = {4'h1, 1'b1, addr[3:1]}; 49 | assign tg68_din = auto_iack ? {auto_vector, auto_vector} : din; 50 | 51 | reg uds_n_r; 52 | reg lds_n_r; 53 | reg rw_r; 54 | reg as_n_r; 55 | 56 | assign as_n = as_n_r; 57 | assign uds_n = uds_n_r; 58 | assign lds_n = lds_n_r; 59 | assign rw_n = rw_r; 60 | 61 | reg [2:0] s_state; 62 | 63 | always @(posedge clk) begin 64 | if (reset) begin 65 | s_state <= 0; 66 | as_n_r <= 1; 67 | rw_r <= 1; 68 | uds_n_r <= 1; 69 | lds_n_r <= 1; 70 | end else begin 71 | addr <= tg68_addr; 72 | 73 | if (phi1) begin 74 | 75 | if (s_state != 4) s_state <= s_state + 1'd1; 76 | if (busreq_ack || bus_granted) s_state <= s_state; 77 | if (tg68_busstate == 2'b01) s_state <= 0; 78 | 79 | case (s_state) 80 | 1: if (tg68_busstate != 2'b01) begin 81 | rw_r <= tg68_rw; 82 | if (tg68_rw) begin 83 | uds_n_r <= tg68_uds_n; 84 | lds_n_r <= tg68_lds_n; 85 | end 86 | as_n_r <= 0; 87 | end 88 | 3: if (tg68_busstate != 2'b01) begin 89 | if (!tg68_rw) begin 90 | uds_n_r <= tg68_uds_n; 91 | lds_n_r <= tg68_lds_n; 92 | end 93 | end 94 | 7: rw_r <= 1; 95 | default :; 96 | endcase 97 | 98 | end else if (phi2) begin 99 | 100 | if (s_state != 4 || tg68_busstate == 2'b01 || !dtack_n || xVma || berr) 101 | s_state <= s_state + 1'd1; 102 | if ((busreq_ack || bus_granted) && !busrel_ack) s_state <= s_state; 103 | if (tg68_busstate == 2'b01) s_state <= 0; 104 | 105 | case (s_state) 106 | 107 | 6: begin 108 | tg68_din_r <= tg68_din; 109 | uds_n_r <= 1; 110 | lds_n_r <= 1; 111 | as_n_r <= 1; 112 | end 113 | default :; 114 | endcase 115 | 116 | end 117 | end 118 | end 119 | 120 | // from FX68K 121 | // E clock and counter, VMA 122 | reg [3:0] eCntr; 123 | reg rVma; 124 | reg Vpai; 125 | assign vma_n = rVma; 126 | 127 | // Internal stop just one cycle before E falling edge 128 | wire xVma = ~rVma & (eCntr == 8); 129 | 130 | always @( posedge clk) begin 131 | if (reset) begin 132 | E <= 1'b0; 133 | eCntr <=0; 134 | rVma <= 1'b1; 135 | end 136 | if (phi1) Vpai <= vpa_n; 137 | if (phi2) begin 138 | if (eCntr == 9) 139 | E <= 1'b0; 140 | else if (eCntr == 5) 141 | E <= 1'b1; 142 | 143 | if (eCntr == 9) 144 | eCntr <= 0; 145 | else 146 | eCntr <= eCntr + 1'b1; 147 | end 148 | 149 | if (phi2 & s_state != 0 & ~Vpai & (eCntr == 3)) 150 | rVma <= 1'b0; 151 | else if (phi1 & eCntr == 0) 152 | rVma <= 1'b1; 153 | 154 | end 155 | 156 | // Bus arbitration 157 | reg bg_n_r; 158 | assign bg_n = bg_n_r; 159 | 160 | // process the bus request at the start of any bus cycle 161 | // (start at only instruction fetch doesn't work well with ACSI DMA) 162 | wire busreq_ack = !br_n /*&& tg68_busstate == 0*/ && s_state == 0; 163 | wire busrel_ack = bus_acked && !bgack; 164 | 165 | reg bgack, bus_granted, bus_acked, bus_acked_d; 166 | 167 | always @(posedge clk) begin 168 | if (reset) begin 169 | bg_n_r <= 1; 170 | bus_granted <= 0; 171 | bus_acked <= 0; 172 | end else begin 173 | if (phi1) begin 174 | bgack <= ~bgack_n; 175 | bus_acked_d <= bus_acked; 176 | end 177 | if (phi2) begin 178 | if (busreq_ack) begin 179 | bg_n_r <= 0; 180 | bus_granted <= 1; 181 | bus_acked <= bgack; 182 | end 183 | if (bus_granted && bgack) bus_acked <= 1; 184 | if (bus_granted && bus_acked_d) bg_n_r <= 1; 185 | if (busrel_ack) begin 186 | bus_acked <= 0; 187 | bus_granted <= 0; 188 | end 189 | end 190 | end 191 | end 192 | 193 | TG68KdotC_Kernel #(2,2,2,2,2,2,1,1) tg68k ( 194 | .clk ( clk ), 195 | .nReset ( ~reset ), 196 | .clkena_in ( tg68_clkena ), 197 | .data_in ( tg68_din_r ), 198 | .IPL ( ipl ), 199 | .IPL_autovector ( 1'b0 ), 200 | .berr ( berr ), 201 | .clr_berr ( tg68_clr_berr ), 202 | .CPU ( cpu ), // 00->68000 01->68010 11->68020(only some parts - yet) 203 | .addr_out ( tg68_addr ), 204 | .data_write ( dout ), 205 | .nUDS ( tg68_uds_n ), 206 | .nLDS ( tg68_lds_n ), 207 | .nWr ( tg68_rw ), 208 | .busstate ( tg68_busstate ), // 00-> fetch code 10->read data 11->write data 01->no memaccess 209 | .nResetOut ( reset_n ), 210 | .FC ( fc ) 211 | ); 212 | 213 | endmodule 214 | -------------------------------------------------------------------------------- /mist/cyc10/vidclkcntrl/synthesis/submodules/vidclkcntrl_altclkctrl_0.v: -------------------------------------------------------------------------------- 1 | //altclkctrl CBX_SINGLE_OUTPUT_FILE="ON" CLOCK_TYPE="Global Clock" DEVICE_FAMILY="Cyclone 10 LP" ENA_REGISTER_MODE="falling edge" USE_GLITCH_FREE_SWITCH_OVER_IMPLEMENTATION="ON" clkselect ena inclk outclk 2 | //VERSION_BEGIN 22.1 cbx_altclkbuf 2023:07:20:14:03:03:SC cbx_cycloneii 2023:07:20:14:03:03:SC cbx_lpm_add_sub 2023:07:20:14:03:03:SC cbx_lpm_compare 2023:07:20:14:03:03:SC cbx_lpm_decode 2023:07:20:14:03:02:SC cbx_lpm_mux 2023:07:20:14:03:03:SC cbx_mgl 2023:07:20:14:14:26:SC cbx_nadder 2023:07:20:14:03:03:SC cbx_stratix 2023:07:20:14:03:03:SC cbx_stratixii 2023:07:20:14:03:03:SC cbx_stratixiii 2023:07:20:14:03:03:SC cbx_stratixv 2023:07:20:14:03:03:SC VERSION_END 3 | // synthesis VERILOG_INPUT_VERSION VERILOG_2001 4 | // altera message_off 10463 5 | 6 | 7 | 8 | // Copyright (C) 2023 Intel Corporation. All rights reserved. 9 | // Your use of Intel Corporation's design tools, logic functions 10 | // and other software and tools, and any partner logic 11 | // functions, and any output files from any of the foregoing 12 | // (including device programming or simulation files), and any 13 | // associated documentation or information are expressly subject 14 | // to the terms and conditions of the Intel Program License 15 | // Subscription Agreement, the Intel Quartus Prime License Agreement, 16 | // the Intel FPGA IP License Agreement, or other applicable license 17 | // agreement, including, without limitation, that your use is for 18 | // the sole purpose of programming logic devices manufactured by 19 | // Intel and sold by Intel or its authorized distributors. Please 20 | // refer to the applicable agreement for further details, at 21 | // https://fpgasoftware.intel.com/eula. 22 | 23 | 24 | 25 | //synthesis_resources = clkctrl 1 reg 3 26 | //synopsys translate_off 27 | `timescale 1 ps / 1 ps 28 | //synopsys translate_on 29 | module vidclkcntrl_altclkctrl_0_sub 30 | ( 31 | clkselect, 32 | ena, 33 | inclk, 34 | outclk) /* synthesis synthesis_clearbox=1 */; 35 | input [1:0] clkselect; 36 | input ena; 37 | input [3:0] inclk; 38 | output outclk; 39 | `ifndef ALTERA_RESERVED_QIS 40 | // synopsys translate_off 41 | `endif 42 | tri0 [1:0] clkselect; 43 | tri1 ena; 44 | tri0 [3:0] inclk; 45 | `ifndef ALTERA_RESERVED_QIS 46 | // synopsys translate_on 47 | `endif 48 | 49 | (* ALTERA_ATTRIBUTE = {"POWER_UP_LEVEL=HIGH"} *) 50 | reg ena_reg; 51 | (* ALTERA_ATTRIBUTE = {"POWER_UP_LEVEL=LOW"} *) 52 | reg [1:0] select_reg; 53 | wire wire_clkctrl1_outclk; 54 | wire [1:0] clkselect_wire; 55 | wire [3:0] inclk_wire; 56 | wire [1:0] select_enable_wire; 57 | 58 | // synopsys translate_off 59 | initial 60 | ena_reg = {1{1'b1}}; 61 | // synopsys translate_on 62 | always @ ( negedge wire_clkctrl1_outclk) 63 | ena_reg <= (ena & (~ select_enable_wire[1])); 64 | // synopsys translate_off 65 | initial 66 | select_reg = 0; 67 | // synopsys translate_on 68 | always @ ( negedge wire_clkctrl1_outclk) 69 | if (ena_reg == 1'b0) select_reg <= clkselect_wire[1:0]; 70 | cyclone10lp_clkctrl clkctrl1 71 | ( 72 | .clkselect({select_reg}), 73 | .ena(1'b1), 74 | .inclk(inclk_wire), 75 | .outclk(wire_clkctrl1_outclk) 76 | // synopsys translate_off 77 | , 78 | .devclrn(1'b1), 79 | .devpor(1'b1) 80 | // synopsys translate_on 81 | ); 82 | defparam 83 | clkctrl1.clock_type = "Global Clock", 84 | clkctrl1.lpm_type = "cyclone10lp_clkctrl"; 85 | assign 86 | clkselect_wire = {clkselect}, 87 | inclk_wire = {inclk}, 88 | outclk = (wire_clkctrl1_outclk & ena_reg), 89 | select_enable_wire = {(select_enable_wire[0] | (clkselect_wire[1] ^ select_reg[1])), (clkselect_wire[0] ^ select_reg[0])}; 90 | endmodule //vidclkcntrl_altclkctrl_0_sub 91 | //VALID FILE // (C) 2001-2023 Intel Corporation. All rights reserved. 92 | // Your use of Intel Corporation's design tools, logic functions and other 93 | // software and tools, and its AMPP partner logic functions, and any output 94 | // files from any of the foregoing (including device programming or simulation 95 | // files), and any associated documentation or information are expressly subject 96 | // to the terms and conditions of the Intel Program License Subscription 97 | // Agreement, Intel FPGA IP License Agreement, or other applicable 98 | // license agreement, including, without limitation, that your use is for the 99 | // sole purpose of programming logic devices manufactured by Intel and sold by 100 | // Intel or its authorized distributors. Please refer to the applicable 101 | // agreement for further details. 102 | 103 | 104 | 105 | // synopsys translate_off 106 | `timescale 1 ps / 1 ps 107 | // synopsys translate_on 108 | module vidclkcntrl_altclkctrl_0 ( 109 | clkselect, 110 | inclk0x, 111 | inclk1x, 112 | outclk); 113 | 114 | input clkselect; 115 | input inclk0x; 116 | input inclk1x; 117 | output outclk; 118 | `ifndef ALTERA_RESERVED_QIS 119 | // synopsys translate_off 120 | `endif 121 | tri0 clkselect; 122 | `ifndef ALTERA_RESERVED_QIS 123 | // synopsys translate_on 124 | `endif 125 | 126 | wire sub_wire0; 127 | wire outclk; 128 | wire sub_wire1; 129 | wire [1:0] sub_wire2; 130 | wire [0:0] sub_wire3; 131 | wire sub_wire4; 132 | wire sub_wire5; 133 | wire [3:0] sub_wire6; 134 | wire sub_wire7; 135 | wire [1:0] sub_wire8; 136 | 137 | assign outclk = sub_wire0; 138 | assign sub_wire1 = clkselect; 139 | assign sub_wire2[1:0] = {sub_wire3, sub_wire1}; 140 | assign sub_wire3[0:0] = 1'h0; 141 | assign sub_wire4 = 1'h1; 142 | assign sub_wire5 = inclk0x; 143 | assign sub_wire6[3:0] = {sub_wire8, sub_wire7, sub_wire5}; 144 | assign sub_wire7 = inclk1x; 145 | assign sub_wire8[1:0] = 2'h0; 146 | 147 | vidclkcntrl_altclkctrl_0_sub vidclkcntrl_altclkctrl_0_sub_component ( 148 | .clkselect (sub_wire2), 149 | .ena (sub_wire4), 150 | .inclk (sub_wire6), 151 | .outclk (sub_wire0)); 152 | 153 | endmodule -------------------------------------------------------------------------------- /mist/cyc3/vidclkcntrl.v: -------------------------------------------------------------------------------- 1 | // megafunction wizard: %ALTCLKCTRL% 2 | // GENERATION: STANDARD 3 | // VERSION: WM1.0 4 | // MODULE: altclkctrl 5 | 6 | // ============================================================ 7 | // File Name: vidclkcntrl.v 8 | // Megafunction Name(s): 9 | // altclkctrl 10 | // 11 | // Simulation Library Files(s): 12 | // cycloneiii 13 | // ============================================================ 14 | // ************************************************************ 15 | // THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! 16 | // 17 | // 13.1.4 Build 182 03/12/2014 Patches 4.26 SJ Web Edition 18 | // ************************************************************ 19 | 20 | 21 | //Copyright (C) 1991-2014 Altera Corporation 22 | //Your use of Altera Corporation's design tools, logic functions 23 | //and other software and tools, and its AMPP partner logic 24 | //functions, and any output files from any of the foregoing 25 | //(including device programming or simulation files), and any 26 | //associated documentation or information are expressly subject 27 | //to the terms and conditions of the Altera Program License 28 | //Subscription Agreement, Altera MegaCore Function License 29 | //Agreement, or other applicable license agreement, including, 30 | //without limitation, that your use is for the sole purpose of 31 | //programming logic devices manufactured by Altera and sold by 32 | //Altera or its authorized distributors. Please refer to the 33 | //applicable agreement for further details. 34 | 35 | 36 | //altclkctrl CBX_AUTO_BLACKBOX="ALL" CLOCK_TYPE="Global Clock" DEVICE_FAMILY="Cyclone III" ENA_REGISTER_MODE="falling edge" USE_GLITCH_FREE_SWITCH_OVER_IMPLEMENTATION="OFF" clkselect ena inclk outclk 37 | //VERSION_BEGIN 13.1 cbx_altclkbuf 2014:03:12:18:15:27:SJ cbx_cycloneii 2014:03:12:18:15:29:SJ cbx_lpm_add_sub 2014:03:12:18:15:29:SJ cbx_lpm_compare 2014:03:12:18:15:29:SJ cbx_lpm_decode 2014:03:12:18:15:29:SJ cbx_lpm_mux 2014:03:12:18:15:30:SJ cbx_mgl 2014:03:12:21:10:00:SJ cbx_stratix 2014:03:12:18:15:31:SJ cbx_stratixii 2014:03:12:18:15:31:SJ cbx_stratixiii 2014:03:12:18:15:32:SJ cbx_stratixv 2014:03:12:18:15:32:SJ VERSION_END 38 | // synthesis VERILOG_INPUT_VERSION VERILOG_2001 39 | // altera message_off 10463 40 | 41 | 42 | //synthesis_resources = clkctrl 1 43 | //synopsys translate_off 44 | `timescale 1 ps / 1 ps 45 | //synopsys translate_on 46 | module vidclkcntrl_altclkctrl_uhi 47 | ( 48 | clkselect, 49 | ena, 50 | inclk, 51 | outclk) ; 52 | input [1:0] clkselect; 53 | input ena; 54 | input [3:0] inclk; 55 | output outclk; 56 | `ifndef ALTERA_RESERVED_QIS 57 | // synopsys translate_off 58 | `endif 59 | tri0 [1:0] clkselect; 60 | tri1 ena; 61 | tri0 [3:0] inclk; 62 | `ifndef ALTERA_RESERVED_QIS 63 | // synopsys translate_on 64 | `endif 65 | 66 | wire wire_clkctrl1_outclk; 67 | wire [1:0] clkselect_wire; 68 | wire [3:0] inclk_wire; 69 | 70 | cycloneiii_clkctrl clkctrl1 71 | ( 72 | .clkselect(clkselect_wire), 73 | .ena(ena), 74 | .inclk(inclk_wire), 75 | .outclk(wire_clkctrl1_outclk) 76 | // synopsys translate_off 77 | , 78 | .devclrn(1'b1), 79 | .devpor(1'b1) 80 | // synopsys translate_on 81 | ); 82 | defparam 83 | clkctrl1.clock_type = "Global Clock", 84 | clkctrl1.ena_register_mode = "falling edge", 85 | clkctrl1.lpm_type = "cycloneiii_clkctrl"; 86 | assign 87 | clkselect_wire = {clkselect}, 88 | inclk_wire = {inclk}, 89 | outclk = wire_clkctrl1_outclk; 90 | endmodule //vidclkcntrl_altclkctrl_uhi 91 | //VALID FILE 92 | 93 | 94 | // synopsys translate_off 95 | `timescale 1 ps / 1 ps 96 | // synopsys translate_on 97 | module vidclkcntrl ( 98 | clkselect, 99 | inclk0x, 100 | inclk1x, 101 | outclk); 102 | 103 | input clkselect; 104 | input inclk0x; 105 | input inclk1x; 106 | output outclk; 107 | `ifndef ALTERA_RESERVED_QIS 108 | // synopsys translate_off 109 | `endif 110 | tri0 clkselect; 111 | `ifndef ALTERA_RESERVED_QIS 112 | // synopsys translate_on 113 | `endif 114 | 115 | wire sub_wire0; 116 | wire [0:0] sub_wire3 = 1'h0; 117 | wire sub_wire4 = 1'h1; 118 | wire [1:0] sub_wire8 = 2'h0; 119 | wire sub_wire7 = inclk1x; 120 | wire outclk = sub_wire0; 121 | wire sub_wire1 = clkselect; 122 | wire [1:0] sub_wire2 = {sub_wire3, sub_wire1}; 123 | wire sub_wire5 = inclk0x; 124 | wire [3:0] sub_wire6 = {sub_wire8, sub_wire7, sub_wire5}; 125 | 126 | vidclkcntrl_altclkctrl_uhi vidclkcntrl_altclkctrl_uhi_component ( 127 | .clkselect (sub_wire2), 128 | .ena (sub_wire4), 129 | .inclk (sub_wire6), 130 | .outclk (sub_wire0)); 131 | 132 | endmodule 133 | 134 | // ============================================================ 135 | // CNX file retrieval info 136 | // ============================================================ 137 | // Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone III" 138 | // Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0" 139 | // Retrieval info: PRIVATE: clock_inputs NUMERIC "2" 140 | // Retrieval info: CONSTANT: ENA_REGISTER_MODE STRING "falling edge" 141 | // Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III" 142 | // Retrieval info: CONSTANT: USE_GLITCH_FREE_SWITCH_OVER_IMPLEMENTATION STRING "OFF" 143 | // Retrieval info: CONSTANT: clock_type STRING "Global Clock" 144 | // Retrieval info: USED_PORT: clkselect 0 0 0 0 INPUT GND "clkselect" 145 | // Retrieval info: USED_PORT: inclk0x 0 0 0 0 INPUT NODEFVAL "inclk0x" 146 | // Retrieval info: USED_PORT: inclk1x 0 0 0 0 INPUT NODEFVAL "inclk1x" 147 | // Retrieval info: USED_PORT: outclk 0 0 0 0 OUTPUT NODEFVAL "outclk" 148 | // Retrieval info: CONNECT: @clkselect 0 0 1 1 GND 0 0 0 0 149 | // Retrieval info: CONNECT: @clkselect 0 0 1 0 clkselect 0 0 0 0 150 | // Retrieval info: CONNECT: @ena 0 0 0 0 VCC 0 0 0 0 151 | // Retrieval info: CONNECT: @inclk 0 0 2 2 GND 0 0 2 0 152 | // Retrieval info: CONNECT: @inclk 0 0 1 0 inclk0x 0 0 0 0 153 | // Retrieval info: CONNECT: @inclk 0 0 1 1 inclk1x 0 0 0 0 154 | // Retrieval info: CONNECT: outclk 0 0 0 0 @outclk 0 0 0 0 155 | // Retrieval info: GEN_FILE: TYPE_NORMAL vidclkcntrl.v TRUE 156 | // Retrieval info: GEN_FILE: TYPE_NORMAL vidclkcntrl.inc FALSE 157 | // Retrieval info: GEN_FILE: TYPE_NORMAL vidclkcntrl.cmp FALSE 158 | // Retrieval info: GEN_FILE: TYPE_NORMAL vidclkcntrl.bsf FALSE 159 | // Retrieval info: GEN_FILE: TYPE_NORMAL vidclkcntrl_inst.v FALSE 160 | // Retrieval info: GEN_FILE: TYPE_NORMAL vidclkcntrl_bb.v FALSE 161 | // Retrieval info: LIB_FILE: cycloneiii 162 | -------------------------------------------------------------------------------- /atarist/mfp_timer.v: -------------------------------------------------------------------------------- 1 | // 2 | // mfp_timer.v 3 | // 4 | // Single MFP68901 timer implementation 5 | // https://github.com/mist-devel/mist-board 6 | // 7 | // Copyright (c) 2013 Stephen Leary 8 | // Copyright (c) 2013-15 Till Harbaum 9 | // Copyright (c) 2019-2020 Gyorgy Szombathelyi 10 | // 11 | // This source file is free software: you can redistribute it and/or modify 12 | // it under the terms of the GNU General Public License as published 13 | // by the Free Software Foundation, either version 3 of the License, or 14 | // (at your option) any later version. 15 | // 16 | // This source file is distributed in the hope that it will be useful, 17 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | // GNU General Public License for more details. 20 | // 21 | // You should have received a copy of the GNU General Public License 22 | // along with this program. If not, see . 23 | 24 | 25 | module mfp_timer( 26 | input CLK, 27 | input RST, 28 | input DS, 29 | 30 | input DAT_WE, 31 | input [7:0] DAT_I, 32 | output [7:0] DAT_O, 33 | 34 | input CTRL_WE, 35 | input [4:0] CTRL_I, 36 | output [3:0] CTRL_O, 37 | 38 | input XCLK_I, 39 | input T_I, // ext. trigger in 40 | 41 | output PULSE_MODE, // pulse and event mode disables input port irq 42 | output EVENT_MODE, 43 | 44 | output reg T_O, 45 | output reg T_O_PULSE, 46 | 47 | // current data bits are exported to allow mfp some rs232 bitrate 48 | // calculations 49 | output [7:0] SET_DATA_OUT 50 | ); 51 | 52 | parameter MFP_CEN = 0; 53 | 54 | assign SET_DATA_OUT = data; 55 | 56 | reg [7:0] data, down_counter, cur_counter; 57 | reg [3:0] control; 58 | 59 | assign PULSE_MODE = pulse_mode; 60 | assign EVENT_MODE = event_mode; 61 | 62 | wire[7:0] prescaler; // prescaler value 63 | reg [7:0] prescaler_counter; // prescaler counter 64 | wire prescaler_active; 65 | 66 | reg count; 67 | 68 | wire started; 69 | 70 | wire delay_mode; 71 | wire event_mode; 72 | wire pulse_mode; 73 | 74 | // async clock edge detect 75 | reg xclk, xclk_r, xclk_r2; 76 | 77 | // generate xclk_en from async clock input 78 | always @(posedge XCLK_I) xclk <= ~xclk; 79 | 80 | always @(posedge CLK) begin 81 | xclk_r <= xclk; 82 | xclk_r2 <= xclk_r; 83 | end 84 | 85 | wire xclk_en = MFP_CEN ? XCLK_I : xclk_r2 ^ xclk_r; 86 | 87 | // from datasheet: 88 | // read value when the DS pin last gone high prior to the current read cycle 89 | always @(posedge CLK) begin 90 | reg DS_last; 91 | DS_last <= DS; 92 | if (~DS_last & DS) cur_counter <= down_counter; 93 | end 94 | 95 | reg [7:0] trigger_shift; 96 | wire trigger_pulse = trigger_shift[5:2] == 4'b0011; // maintain enough delay, and still allow 1/4 of clock freq 97 | 98 | always @(posedge CLK) begin 99 | // In the datasheet, it's mentioned that T_I must be no more than 1/4 of the Timer Clock frequency 100 | // but a 4 stage shift register doesn't have enough delay for most of the bottom border opening code 101 | if (xclk_en) trigger_shift <= { trigger_shift[6:0], T_I }; 102 | end 103 | 104 | always @(posedge CLK) begin 105 | reg timer_tick; 106 | reg timer_tick_r; 107 | reg reload; 108 | 109 | if (RST === 1'b1) begin 110 | T_O <= 1'b0; 111 | control <= 4'd0; 112 | data <= 8'd0; 113 | down_counter <= 8'd0; 114 | count <= 1'b0; 115 | prescaler_counter <= 8'd0; 116 | reload <= 1'b0; 117 | end else begin 118 | 119 | if (xclk_en) timer_tick_r <= timer_tick; 120 | 121 | reload <= 1'b0; 122 | // if the timer is just stopped when oveflown, the MFP won't reload it from data 123 | // the next period will 256 timer cycles (from Hatari) 124 | if (started & reload) down_counter <= data; 125 | 126 | // if a write request comes from the main unit 127 | // then write the data to the appropriate register. 128 | if(DAT_WE) begin 129 | data <= DAT_I; 130 | // the counter itself is only loaded here if it's stopped 131 | if(!started) begin 132 | reload <= 1'b0; 133 | down_counter <= DAT_I; 134 | end 135 | end 136 | 137 | if(CTRL_WE) begin 138 | control <= CTRL_I[3:0]; 139 | if (CTRL_I[4] == 1'b1) 140 | T_O <= 1'b0; 141 | end 142 | 143 | count <= 1'b0; 144 | 145 | if (prescaler_active) begin 146 | if (xclk_en) begin 147 | // From datasheet: 148 | // If the prescaler value is changed while the timer is enabled, the first time out pulse will occur 149 | // at an indeterminate time no less than one or more than 200 timer clock cycles. Subsequent 150 | // time out pulses will then occur at the correct interval. 151 | // From this it can be guessed the prescaler resets at 200 unconditionally. 152 | if(prescaler_counter == prescaler || prescaler_counter == 8'd199) begin 153 | prescaler_counter <= 8'd0; 154 | timer_tick <= ~timer_tick; 155 | end else 156 | prescaler_counter <= prescaler_counter + 8'd1; 157 | end 158 | end else begin 159 | prescaler_counter <= 8'd0; 160 | end 161 | 162 | T_O_PULSE <= 1'b0; 163 | 164 | // handle event mode 165 | if (event_mode === 1'b1) 166 | if (xclk_en && trigger_pulse) 167 | count <= 1'b1; 168 | 169 | // handle delay mode 170 | if (delay_mode === 1'b1) 171 | if (xclk_en && (timer_tick_r ^ timer_tick)) 172 | count <= 1'b1; 173 | 174 | // handle pulse mode 175 | if (pulse_mode === 1'b1) 176 | if (xclk_en && (timer_tick_r ^ timer_tick) && trigger_pulse) 177 | count <= 1'b1; 178 | 179 | if (count) begin 180 | down_counter <= down_counter - 8'd1; 181 | 182 | // timeout pulse 183 | if (down_counter === 8'd1) begin 184 | // pulse the timer out 185 | T_O <= ~T_O; 186 | T_O_PULSE <= 1'b1; 187 | reload <= 1'b1; 188 | end 189 | end 190 | end 191 | end 192 | 193 | assign prescaler = control[2:0] === 3'd1 ? 8'd03 : 194 | control[2:0] === 3'd2 ? 8'd09 : 195 | control[2:0] === 3'd3 ? 8'd15 : 196 | control[2:0] === 3'd4 ? 8'd49 : 197 | control[2:0] === 3'd5 ? 8'd63 : 198 | control[2:0] === 3'd6 ? 8'd99 : 199 | control[2:0] === 3'd7 ? 8'd199 : 8'd1; 200 | 201 | assign prescaler_active = |control[2:0]; 202 | assign delay_mode = control[3] === 1'b0; 203 | assign pulse_mode = control[3] === 1'b1 & !event_mode; 204 | assign event_mode = control[3:0] === 4'b1000; 205 | 206 | assign started = control[3:0] != 4'd0; 207 | assign DAT_O = cur_counter; 208 | assign CTRL_O = control; 209 | 210 | endmodule // mfp_timer 211 | -------------------------------------------------------------------------------- /mist/cyc10/vidclkcntrl/vidclkcntrl.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 12 | 18 | 24 | 30 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 65 | 66 | 67 | 71 | 72 | 73 | 74 | 75 | 76 | 78 | 79 | 80 | queue size: 0 starting:vidclkcntrl "vidclkcntrl" 81 | 82 | 83 | 84 | Transform: CustomInstructionTransform 85 | No custom instruction connections, skipping transform 86 | 1 modules, 0 connections]]> 87 | Transform: MMTransform 88 | Transform: InterruptMapperTransform 89 | Transform: InterruptSyncTransform 90 | Transform: InterruptFanoutTransform 91 | Transform: AvalonStreamingTransform 92 | Transform: ResetAdaptation 93 | vidclkcntrl" reuses altclkctrl "submodules/vidclkcntrl_altclkctrl_0"]]> 94 | queue size: 0 starting:altclkctrl "submodules/vidclkcntrl_altclkctrl_0" 95 | Generating top-level entity vidclkcntrl_altclkctrl_0. 96 | Current quartus bindir: /home/gyuri/intelFPGA_lite/22.1std/quartus/linux64/. 97 | vidclkcntrl" instantiated altclkctrl "altclkctrl_0"]]> 98 | 99 | 100 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 118 | 119 | 120 | 121 | 123 | 124 | 125 | 126 | 127 | queue size: 0 starting:altclkctrl "submodules/vidclkcntrl_altclkctrl_0" 128 | Generating top-level entity vidclkcntrl_altclkctrl_0. 129 | Current quartus bindir: /home/gyuri/intelFPGA_lite/22.1std/quartus/linux64/. 130 | vidclkcntrl" instantiated altclkctrl "altclkctrl_0"]]> 131 | 132 | 133 | 134 | -------------------------------------------------------------------------------- /mist/mist_video.v: -------------------------------------------------------------------------------- 1 | // A video pipeline for MiST. Just insert between the core video output and the VGA pins 2 | // Provides an optional scandoubler, a rotateable OSD and (optional) RGb->YPbPr conversion 3 | 4 | module mist_video 5 | ( 6 | // master clock 7 | // it should be 4x (or 2x) pixel clock for the scandoubler 8 | input clk_sys, 9 | 10 | // OSD SPI interface 11 | input SPI_SCK, 12 | input SPI_SS3, 13 | input SPI_DI, 14 | 15 | // scanlines (00-none 01-25% 10-50% 11-75%) 16 | input [1:0] scanlines, 17 | 18 | // non-scandoubled pixel clock divider: 19 | // 0 - clk_sys/4, 1 - clk_sys/2, 2 - clk_sys/3, 3 - clk_sys/4, etc 20 | input [2:0] ce_divider, 21 | 22 | // 0 = HVSync 31KHz, 1 = CSync 15KHz 23 | input scandoubler_disable, 24 | // disable csync without scandoubler 25 | input no_csync, 26 | // YPbPr always uses composite sync 27 | input ypbpr, 28 | // Rotate OSD [0] - rotate [1] - left or right 29 | input [1:0] rotate, 30 | // composite-like blending 31 | input blend, 32 | 33 | // video in 34 | input [COLOR_DEPTH-1:0] R, 35 | input [COLOR_DEPTH-1:0] G, 36 | input [COLOR_DEPTH-1:0] B, 37 | 38 | input HBlank, 39 | input VBlank, 40 | input HSync, 41 | input VSync, 42 | 43 | // MiST video output signals 44 | output reg [OUT_COLOR_DEPTH-1:0] VGA_R, 45 | output reg [OUT_COLOR_DEPTH-1:0] VGA_G, 46 | output reg [OUT_COLOR_DEPTH-1:0] VGA_B, 47 | output reg VGA_VS, 48 | output reg VGA_HS, 49 | output reg VGA_HB, 50 | output reg VGA_VB, 51 | output reg VGA_DE 52 | ); 53 | 54 | parameter OSD_COLOR = 3'd4; 55 | parameter OSD_X_OFFSET = 10'd0; 56 | parameter OSD_Y_OFFSET = 10'd0; 57 | parameter SD_HCNT_WIDTH = 9; 58 | parameter COLOR_DEPTH = 6; // 1-8 59 | parameter OSD_AUTO_CE = 1'b1; 60 | parameter SYNC_AND = 1'b0; // 0 - XOR, 1 - AND 61 | parameter USE_BLANKS = 1'b0; // Honor H/VBlank signals? 62 | parameter SD_HSCNT_WIDTH = 12; 63 | parameter OUT_COLOR_DEPTH = 6; // 1-8 64 | parameter BIG_OSD = 0; // 16 line OSD 65 | parameter VIDEO_CLEANER = 0; // Align VSync/VBlank to HSync/HBlank edges. HDMI usually needs it. 66 | 67 | wire [OUT_COLOR_DEPTH-1:0] SD_R_O; 68 | wire [OUT_COLOR_DEPTH-1:0] SD_G_O; 69 | wire [OUT_COLOR_DEPTH-1:0] SD_B_O; 70 | wire SD_HS_O; 71 | wire SD_VS_O; 72 | wire SD_HB_O; 73 | wire SD_VB_O; 74 | 75 | wire pixel_ena; 76 | 77 | scandoubler #(SD_HCNT_WIDTH, COLOR_DEPTH, SD_HSCNT_WIDTH, OUT_COLOR_DEPTH) scandoubler 78 | ( 79 | .clk_sys ( clk_sys ), 80 | .bypass ( scandoubler_disable ), 81 | .ce_divider ( ce_divider ), 82 | .scanlines ( scanlines ), 83 | .pixel_ena ( pixel_ena ), 84 | .hb_in ( HBlank ), 85 | .vb_in ( VBlank ), 86 | .hs_in ( HSync ), 87 | .vs_in ( VSync ), 88 | .r_in ( R ), 89 | .g_in ( G ), 90 | .b_in ( B ), 91 | .hb_out ( SD_HB_O ), 92 | .vb_out ( SD_VB_O ), 93 | .hs_out ( SD_HS_O ), 94 | .vs_out ( SD_VS_O ), 95 | .r_out ( SD_R_O ), 96 | .g_out ( SD_G_O ), 97 | .b_out ( SD_B_O ) 98 | ); 99 | 100 | wire [OUT_COLOR_DEPTH-1:0] osd_r_o; 101 | wire [OUT_COLOR_DEPTH-1:0] osd_g_o; 102 | wire [OUT_COLOR_DEPTH-1:0] osd_b_o; 103 | 104 | osd #(OSD_X_OFFSET, OSD_Y_OFFSET, OSD_COLOR, OSD_AUTO_CE, USE_BLANKS, OUT_COLOR_DEPTH, BIG_OSD) osd 105 | ( 106 | .clk_sys ( clk_sys ), 107 | .rotate ( rotate ), 108 | .ce ( pixel_ena ), 109 | .SPI_DI ( SPI_DI ), 110 | .SPI_SCK ( SPI_SCK ), 111 | .SPI_SS3 ( SPI_SS3 ), 112 | .R_in ( SD_R_O ), 113 | .G_in ( SD_G_O ), 114 | .B_in ( SD_B_O ), 115 | .HBlank ( SD_HB_O ), 116 | .VBlank ( SD_VB_O ), 117 | .HSync ( SD_HS_O ), 118 | .VSync ( SD_VS_O ), 119 | .R_out ( osd_r_o ), 120 | .G_out ( osd_g_o ), 121 | .B_out ( osd_b_o ) 122 | ); 123 | 124 | wire [OUT_COLOR_DEPTH-1:0] cofi_r, cofi_g, cofi_b; 125 | wire cofi_hs, cofi_vs; 126 | wire cofi_hb, cofi_vb; 127 | wire cofi_pixel_ena; 128 | 129 | cofi #(OUT_COLOR_DEPTH) cofi ( 130 | .clk ( clk_sys ), 131 | .pix_ce ( pixel_ena ), 132 | .enable ( blend ), 133 | .hblank ( USE_BLANKS ? SD_HB_O : ~SD_HS_O ), 134 | .vblank ( SD_VB_O ), 135 | .hs ( SD_HS_O ), 136 | .vs ( SD_VS_O ), 137 | .red ( osd_r_o ), 138 | .green ( osd_g_o ), 139 | .blue ( osd_b_o ), 140 | .hs_out ( cofi_hs ), 141 | .vs_out ( cofi_vs ), 142 | .hblank_out( cofi_hb ), 143 | .vblank_out( cofi_vb ), 144 | .red_out ( cofi_r ), 145 | .green_out( cofi_g ), 146 | .blue_out( cofi_b ), 147 | .pix_ce_out(cofi_pixel_ena) 148 | ); 149 | 150 | wire [OUT_COLOR_DEPTH-1:0] cleaner_r_o; 151 | wire [OUT_COLOR_DEPTH-1:0] cleaner_g_o; 152 | wire [OUT_COLOR_DEPTH-1:0] cleaner_b_o; 153 | wire cleaner_hs_o, cleaner_vs_o, cleaner_hb_o, cleaner_vb_o; 154 | 155 | video_cleaner #(OUT_COLOR_DEPTH) video_cleaner( 156 | .clk_vid ( clk_sys ), 157 | .ce_pix ( scandoubler_disable ? 1'b1 : cofi_pixel_ena ), 158 | .enable ( VIDEO_CLEANER ), 159 | 160 | .R ( cofi_r ), 161 | .G ( cofi_g ), 162 | .B ( cofi_b ), 163 | 164 | .HSync ( cofi_hs ), 165 | .VSync ( cofi_vs ), 166 | .HBlank ( cofi_hb ), 167 | .VBlank ( cofi_vb ), 168 | 169 | .VGA_R ( cleaner_r_o ), 170 | .VGA_G ( cleaner_g_o ), 171 | .VGA_B ( cleaner_b_o ), 172 | .VGA_VS ( cleaner_vs_o), 173 | .VGA_HS ( cleaner_hs_o), 174 | .HBlank_out ( cleaner_hb_o), 175 | .VBlank_out ( cleaner_vb_o) 176 | ); 177 | 178 | wire hs, vs, cs; 179 | wire hb, vb; 180 | wire [OUT_COLOR_DEPTH-1:0] r,g,b; 181 | 182 | RGBtoYPbPr #(OUT_COLOR_DEPTH) rgb2ypbpr 183 | ( 184 | .clk ( clk_sys ), 185 | .ena ( ypbpr ), 186 | 187 | .red_in ( cleaner_r_o ), 188 | .green_in ( cleaner_g_o ), 189 | .blue_in ( cleaner_b_o ), 190 | .hs_in ( cleaner_hs_o ), 191 | .vs_in ( cleaner_vs_o ), 192 | .cs_in ( SYNC_AND ? (cleaner_hs_o & cleaner_vs_o) : ~(cleaner_hs_o ^ cleaner_vs_o) ), 193 | .hb_in ( cleaner_hb_o ), 194 | .vb_in ( cleaner_vb_o ), 195 | .red_out ( r ), 196 | .green_out ( g ), 197 | .blue_out ( b ), 198 | .hs_out ( hs ), 199 | .vs_out ( vs ), 200 | .cs_out ( cs ), 201 | .hb_out ( hb ), 202 | .vb_out ( vb ) 203 | ); 204 | 205 | always @(posedge clk_sys) begin 206 | 207 | VGA_R <= r; 208 | VGA_G <= g; 209 | VGA_B <= b; 210 | // a minimig vga->scart cable expects a composite sync signal on the VGA_HS output. 211 | // and VCC on VGA_VS (to switch into rgb mode) 212 | VGA_HS <= ((~no_csync & scandoubler_disable) || ypbpr)? cs : hs; 213 | VGA_VS <= ((~no_csync & scandoubler_disable) || ypbpr)? 1'b1 : vs; 214 | 215 | VGA_HB <= hb; 216 | VGA_VB <= vb; 217 | VGA_DE <= ~(hb | vb); 218 | end 219 | endmodule 220 | -------------------------------------------------------------------------------- /mist/mist.sdc: -------------------------------------------------------------------------------- 1 | ## Generated SDC file "constraints.sdc" 2 | 3 | ## Copyright (C) 1991-2011 Altera Corporation 4 | ## Your use of Altera Corporation's design tools, logic functions 5 | ## and other software and tools, and its AMPP partner logic 6 | ## functions, and any output files from any of the foregoing 7 | ## (including device programming or simulation files), and any 8 | ## associated documentation or information are expressly subject 9 | ## to the terms and conditions of the Altera Program License 10 | ## Subscription Agreement, Altera MegaCore Function License 11 | ## Agreement, or other applicable license agreement, including, 12 | ## without limitation, that your use is for the sole purpose of 13 | ## programming logic devices manufactured by Altera and sold by 14 | ## Altera or its authorized distributors. Please refer to the 15 | ## applicable agreement for further details. 16 | 17 | 18 | ## VENDOR "Altera" 19 | ## PROGRAM "Quartus II" 20 | ## VERSION "Version 11.1 Build 216 11/23/2011 Service Pack 1 SJ Web Edition" 21 | 22 | ## DATE "Fri Jul 06 23:05:47 2012" 23 | 24 | ## 25 | ## DEVICE "EP3C25E144C8" 26 | ## 27 | 28 | 29 | #************************************************************** 30 | # Time Information 31 | #************************************************************** 32 | 33 | set_time_format -unit ns -decimal_places 3 34 | 35 | 36 | 37 | #************************************************************** 38 | # Create Clock 39 | #************************************************************** 40 | 41 | create_clock -name {clk_27} -period 37.037 -waveform { 0.000 18.500 } [get_ports {CLOCK_27}] 42 | create_clock -name {SPI_SCK} -period 41.666 -waveform { 20.8 41.666 } [get_ports {SPI_SCK}] 43 | 44 | #************************************************************** 45 | # Create Generated Clock 46 | #************************************************************** 47 | 48 | derive_pll_clocks 49 | 50 | #************************************************************** 51 | # Set Clock Latency 52 | #************************************************************** 53 | 54 | 55 | #************************************************************** 56 | # Set Clock Uncertainty 57 | #************************************************************** 58 | 59 | derive_clock_uncertainty; 60 | 61 | #************************************************************** 62 | # Set Input Delay 63 | #************************************************************** 64 | 65 | set_input_delay -clock [get_clocks {clock|altpll_component|auto_generated|pll1|clk[0]}] -reference_pin [get_ports SDRAM_CLK] -max 6.4 [get_ports SDRAM_DQ[*]] 66 | set_input_delay -clock [get_clocks {clock|altpll_component|auto_generated|pll1|clk[0]}] -reference_pin [get_ports SDRAM_CLK] -min 3.2 [get_ports SDRAM_DQ[*]] 67 | 68 | #************************************************************** 69 | # Set Output Delay 70 | #************************************************************** 71 | 72 | set_output_delay -clock [get_clocks {clock|altpll_component|auto_generated|pll1|clk[0]}] -reference_pin [get_ports SDRAM_CLK] -max 1.5 [get_ports {SDRAM_D* SDRAM_A* SDRAM_BA* SDRAM_n* SDRAM_CKE}] 73 | set_output_delay -clock [get_clocks {clock|altpll_component|auto_generated|pll1|clk[0]}] -reference_pin [get_ports SDRAM_CLK] -min -0.8 [get_ports {SDRAM_D* SDRAM_A* SDRAM_BA* SDRAM_n* SDRAM_CKE}] 74 | 75 | set_output_delay -clock [get_clocks {clock|altpll_component|auto_generated|pll1|clk[2]}] -max 0 [get_ports {VGA_*}] 76 | set_output_delay -clock [get_clocks {clock|altpll_component|auto_generated|pll1|clk[2]}] -min -5 [get_ports {VGA_*}] 77 | 78 | #************************************************************** 79 | # Set Clock Groups 80 | #************************************************************** 81 | 82 | set_clock_groups -asynchronous -group [get_clocks {SPI_SCK}] -group [get_clocks {clock|altpll_component|auto_generated|pll1|clk[*]}] 83 | 84 | #************************************************************** 85 | # Set False Path 86 | #************************************************************** 87 | 88 | set_false_path -to [get_ports {SDRAM_CLK}] 89 | set_false_path -to [get_ports {UART_TX}] 90 | set_false_path -to [get_ports {AUDIO_L}] 91 | set_false_path -to [get_ports {AUDIO_R}] 92 | set_false_path -to [get_ports {LED}] 93 | 94 | set_false_path -from {mist_video:mist_video|scandoubler:scandoubler|*} -to [get_clocks {clock|altpll_component|auto_generated|pll1|clk[2]}] 95 | set_false_path -to {mist_video:mist_video|scandoubler:scandoubler|*} -from [get_clocks {clock|altpll_component|auto_generated|pll1|clk[2]}] 96 | 97 | #************************************************************** 98 | # Set Multicycle Path 99 | #************************************************************** 100 | 101 | # SDRAM 96 MHz to system 32 MHz 102 | set_multicycle_path -from [get_clocks {clock|altpll_component|auto_generated|pll1|clk[0]}] -to [get_clocks {clock|altpll_component|auto_generated|pll1|clk[1]}] -start -setup 2 103 | set_multicycle_path -from [get_clocks {clock|altpll_component|auto_generated|pll1|clk[0]}] -to [get_clocks {clock|altpll_component|auto_generated|pll1|clk[1]}] -start -hold 1 104 | 105 | # System 32 MHz to SDRAM 96 MHz 106 | set_multicycle_path -from [get_clocks {clock|altpll_component|auto_generated|pll1|clk[1]}] -to [get_clocks {clock|altpll_component|auto_generated|pll1|clk[0]}] -end -setup 2 107 | set_multicycle_path -from [get_clocks {clock|altpll_component|auto_generated|pll1|clk[1]}] -to [get_clocks {clock|altpll_component|auto_generated|pll1|clk[0]}] -end -hold 1 108 | 109 | # FX68K 110 | set_multicycle_path -start -setup -from [get_keepers atarist_sdram:atarist|fx68k:fx68k|Ir[*]] -to [get_keepers atarist_sdram:atarist|fx68k:fx68k|microAddr[*]] 2 111 | set_multicycle_path -start -hold -from [get_keepers atarist_sdram:atarist|fx68k:fx68k|Ir[*]] -to [get_keepers atarist_sdram:atarist|fx68k:fx68k|microAddr[*]] 1 112 | set_multicycle_path -start -setup -from [get_keepers atarist_sdram:atarist|fx68k:fx68k|Ir[*]] -to [get_keepers atarist_sdram:atarist|fx68k:fx68k|nanoAddr[*]] 2 113 | set_multicycle_path -start -hold -from [get_keepers atarist_sdram:atarist|fx68k:fx68k|Ir[*]] -to [get_keepers atarist_sdram:atarist|fx68k:fx68k|nanoAddr[*]] 1 114 | 115 | # Viking 128 MHz to SDRAM 96 MHz 116 | set_multicycle_path -from [get_clocks {clock|altpll_component|auto_generated|pll1|clk[2]}] -to [get_clocks {clock|altpll_component|auto_generated|pll1|clk[0]}] -setup 2 117 | set_multicycle_path -from [get_clocks {clock|altpll_component|auto_generated|pll1|clk[2]}] -to [get_clocks {clock|altpll_component|auto_generated|pll1|clk[0]}] -hold 1 118 | 119 | set_multicycle_path -from {atarist_sdram:atarist|sdram:sdram|dout[*]} -to {atarist_sdram:atarist|sdram:sdram|*} -setup 2 120 | set_multicycle_path -from {atarist_sdram:atarist|sdram:sdram|dout[*]} -to {atarist_sdram:atarist|sdram:sdram|*} -hold 1 121 | 122 | # VGA 123 | set_multicycle_path -start -to [get_ports {VGA_*}] -setup 4 124 | set_multicycle_path -start -to [get_ports {VGA_*}] -hold 3 125 | 126 | #************************************************************** 127 | # Set Maximum Delay 128 | #************************************************************** 129 | 130 | 131 | 132 | #************************************************************** 133 | # Set Minimum Delay 134 | #************************************************************** 135 | 136 | 137 | 138 | #************************************************************** 139 | # Set Input Transition 140 | #************************************************************** 141 | -------------------------------------------------------------------------------- /mist/cyc10/vidclkcntrl/vidclkcntrl.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | datasheet for vidclkcntrl 6 | 57 | 58 | 59 | 60 | 61 | 62 | 66 | 67 |
vidclkcntrl 63 |
64 |
65 |
68 | 69 | 70 | 71 | 72 | 73 |
2024.10.17.12:43:29Datasheet
74 |
75 |
Overview
76 |
77 |
78 | 79 | 80 | 81 | 82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
Memory Map
90 | 91 | 92 | 93 | 94 |
95 | 96 |
97 |
98 |

altclkctrl_0

altclkctrl v22.1 99 |
100 |
101 |
102 | 103 | 104 | 141 | 142 |
105 |

Parameters

106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 |
DEVICE_FAMILYCYCLONE10LP
CLOCK_TYPE1
NUMBER_OF_CLOCKS2
ENA_REGISTER_MODE1
GUI_USE_ENAfalse
USE_GLITCH_FREE_SWITCH_OVER_IMPLEMENTATIONtrue
deviceFamilyUNKNOWN
generateLegacySimfalse
140 |
   143 | 144 | 145 | 147 | 148 |
146 |

Software Assignments

(none)
149 |
150 | 151 | 152 | 153 | 154 | 155 |
generation took 0.00 secondsrendering took 0.01 seconds
156 | 157 | 158 | -------------------------------------------------------------------------------- /atarist/sdram.v: -------------------------------------------------------------------------------- 1 | // 2 | // sdram.v 3 | // 4 | // sdram controller implementation for the MiST board 5 | // https://github.com/mist-devel/mist-board 6 | // 7 | // Copyright (c) 2013 Till Harbaum 8 | // 9 | // This source file is free software: you can redistribute it and/or modify 10 | // it under the terms of the GNU General Public License as published 11 | // by the Free Software Foundation, either version 3 of the License, or 12 | // (at your option) any later version. 13 | // 14 | // This source file is distributed in the hope that it will be useful, 15 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | // GNU General Public License for more details. 18 | // 19 | // You should have received a copy of the GNU General Public License 20 | // along with this program. If not, see . 21 | // 22 | 23 | // TODO: 24 | // - optional 64 bit burst read 25 | // - setup of address+data earlier for increased stability? 26 | 27 | module sdram ( 28 | 29 | // interface to the MT48LC16M16 chip 30 | inout reg [15:0] sd_data, // 16 bit bidirectional data bus 31 | output reg [12:0] sd_addr, // 13 bit multiplexed address bus 32 | output reg [1:0] sd_dqm, // two byte masks 33 | output reg [1:0] sd_ba, // two banks 34 | output sd_cs, // a single chip select 35 | output sd_we, // write enable 36 | output sd_ras, // row address select 37 | output sd_cas, // columns address select 38 | 39 | // cpu/chipset interface 40 | input init, // init signal after FPGA config to initialize RAM 41 | input clk_96, // sdram is accessed at 96MHz 42 | input clk_8_en, // 8MHz chipset clock to which sdram state machine is synchonized 43 | 44 | input [15:0] din, // data input from chipset/cpu 45 | output reg [63:0] dout64, // data output to chipset/cpu 46 | output reg [15:0] dout, 47 | input [23:0] addr, // 24 bit word address 48 | input [1:0] ds, // upper/lower data strobe 49 | input req, // cpu/chipset requests read/write 50 | input we, // cpu/chipset requests write 51 | 52 | input rom_oe, 53 | input [23:0] rom_addr, 54 | output reg [15:0] rom_dout 55 | ); 56 | 57 | localparam RASCAS_DELAY = 3'd2; // tRCD=20ns -> 2 cycles@96MHz 58 | localparam BURST_LENGTH = 3'b010; // 000=1, 001=2, 010=4, 011=8 59 | localparam ACCESS_TYPE = 1'b0; // 0=sequential, 1=interleaved 60 | localparam CAS_LATENCY = 3'd2; // 2/3 allowed 61 | localparam OP_MODE = 2'b00; // only 00 (standard operation) allowed 62 | localparam NO_WRITE_BURST = 1'b1; // 0= write burst enabled, 1=only single access write 63 | 64 | localparam MODE = { 3'b000, NO_WRITE_BURST, OP_MODE, CAS_LATENCY, ACCESS_TYPE, BURST_LENGTH}; 65 | 66 | 67 | // --------------------------------------------------------------------- 68 | // ------------------------ cycle state machine ------------------------ 69 | // --------------------------------------------------------------------- 70 | 71 | // The state machine runs at 128Mhz synchronous to the 8 Mhz chipset clock. 72 | // It wraps from T15 to T0 on the rising edge of clk_8 73 | 74 | localparam STATE_FIRST = 4'd0; // first state in cycle 75 | localparam STATE_CMD_CONT = STATE_FIRST + RASCAS_DELAY; // command can be continued 76 | localparam STATE_READ = STATE_CMD_CONT + CAS_LATENCY + 2'd2; 77 | localparam STATE_LAST = 4'd11; // last state in cycle 78 | 79 | reg [3:0] t; 80 | 81 | always @(posedge clk_96) begin 82 | reg clk_8_enD; 83 | clk_8_enD <= clk_8_en; 84 | if (~clk_8_enD & clk_8_en) t <= 4'hA; else t <= t + 1'd1; 85 | if (t == STATE_LAST) t <= STATE_FIRST; 86 | end 87 | 88 | // --------------------------------------------------------------------- 89 | // --------------------------- startup/reset --------------------------- 90 | // --------------------------------------------------------------------- 91 | 92 | // wait 1ms (32 8Mhz cycles) after FPGA config is done before going 93 | // into normal operation. Initialize the ram in the last 16 reset cycles (cycles 15-0) 94 | reg [7:0] reset = 8'h1f; 95 | always @(posedge clk_96 or posedge init) begin 96 | if(init) reset <= 8'h1f; 97 | else if((t == STATE_LAST) && (reset != 0)) 98 | reset <= reset - 8'd1; 99 | end 100 | 101 | // --------------------------------------------------------------------- 102 | // ------------------ generate ram control signals --------------------- 103 | // --------------------------------------------------------------------- 104 | 105 | // all possible commands 106 | localparam CMD_INHIBIT = 4'b1111; 107 | localparam CMD_NOP = 4'b0111; 108 | localparam CMD_ACTIVE = 4'b0011; 109 | localparam CMD_READ = 4'b0101; 110 | localparam CMD_WRITE = 4'b0100; 111 | localparam CMD_BURST_TERMINATE = 4'b0110; 112 | localparam CMD_PRECHARGE = 4'b0010; 113 | localparam CMD_AUTO_REFRESH = 4'b0001; 114 | localparam CMD_LOAD_MODE = 4'b0000; 115 | 116 | reg [3:0] sd_cmd; // current command sent to sd ram 117 | // drive control signals according to current command 118 | assign sd_cs = sd_cmd[3]; 119 | assign sd_ras = sd_cmd[2]; 120 | assign sd_cas = sd_cmd[1]; 121 | assign sd_we = sd_cmd[0]; 122 | 123 | reg [15:0] sd_din; 124 | 125 | // 4 byte read burst goes through four addresses 126 | reg [1:0] burst_addr; 127 | 128 | reg [15:0] data_latch; 129 | reg [23:0] addr_latch; 130 | reg [15:0] din_latch; 131 | reg req_latch; 132 | reg rom_port; 133 | 134 | always @(posedge clk_96) begin 135 | // permanently latch ram data to reduce delays 136 | sd_din <= sd_data; 137 | sd_data <= 16'bZZZZZZZZZZZZZZZZ; 138 | sd_cmd <= CMD_INHIBIT; // default: idle 139 | 140 | if(reset != 0) begin 141 | // initialization takes place at the end of the reset phase 142 | if(t == STATE_FIRST) begin 143 | 144 | if(reset == 13) begin 145 | sd_cmd <= CMD_PRECHARGE; 146 | sd_addr[10] <= 1'b1; // precharge all banks 147 | end 148 | 149 | if(reset == 2) begin 150 | sd_cmd <= CMD_LOAD_MODE; 151 | sd_addr <= MODE; 152 | end 153 | 154 | end 155 | end else begin 156 | // normal operation 157 | if(t == STATE_FIRST) begin 158 | if (req) begin 159 | addr_latch <= addr; 160 | req_latch <= 1; 161 | din_latch <= din; 162 | rom_port <= 0; 163 | 164 | // RAS phase 165 | sd_cmd <= CMD_ACTIVE; 166 | sd_addr <= { 1'b0, addr[19:8] }; 167 | sd_ba <= addr[21:20]; 168 | 169 | // lowest address for burst read 170 | burst_addr <= addr[1:0]; 171 | 172 | end else if (rom_oe && (addr_latch != rom_addr)) begin 173 | addr_latch <= rom_addr; 174 | req_latch <= 1; 175 | rom_port <= 1; 176 | 177 | // RAS phase 178 | sd_cmd <= CMD_ACTIVE; 179 | sd_addr <= { 1'b0, rom_addr[19:8] }; 180 | sd_ba <= rom_addr[21:20]; 181 | burst_addr <= rom_addr[1:0]; 182 | end else begin 183 | req_latch <= 0; 184 | sd_cmd <= CMD_AUTO_REFRESH; 185 | end 186 | end 187 | 188 | // ------------------- cpu/chipset read/write ---------------------- 189 | if(req_latch) begin 190 | 191 | // CAS phase 192 | if(t == STATE_CMD_CONT) begin 193 | sd_cmd <= we?CMD_WRITE:CMD_READ; 194 | if (we) sd_data <= din_latch; 195 | // always return both bytes in a read. The cpu may not 196 | // need it, but the caches need to be able to store everything 197 | sd_dqm <= we ? ~ds : 2'b00; 198 | 199 | sd_addr <= { 4'b0010, addr_latch[22], addr_latch[7:0] }; // auto precharge 200 | end 201 | 202 | // read phase 203 | if(!we || rom_port) begin 204 | if((t >= STATE_READ) && (t < STATE_READ+4'd4)) begin 205 | if (burst_addr == addr_latch[1:0]) if (rom_port) rom_dout <= sd_din; else dout <= sd_din; 206 | // de-multiplex the data directly into the 64 bit buffer 207 | case (burst_addr) 208 | 2'd0: dout64[15: 0] <= sd_din; 209 | 2'd1: dout64[31:16] <= sd_din; 210 | 2'd2: dout64[47:32] <= sd_din; 211 | 2'd3: dout64[63:48] <= sd_din; 212 | endcase 213 | 214 | burst_addr <= burst_addr + 2'd1; 215 | end 216 | end 217 | end 218 | end 219 | end 220 | 221 | endmodule 222 | -------------------------------------------------------------------------------- /atarist/cubase3_dongle.v: -------------------------------------------------------------------------------- 1 | module cubase3_dongle ( 2 | input clk, 3 | input reset, // POR actually 4 | input rom3_n, 5 | input a8, 6 | output reg d8 7 | ); 8 | 9 | //File generated from rainbow unicorn farts 10 | // 11 | //From the source file SRD_OK.JED 12 | // 13 | //No rights reserved 14 | // 15 | //Device 5c060 16 | // pin02 = 2 17 | // pin03 = 3 18 | // pin04 = 4 19 | // pin05 = 5 20 | // pin06 = 6 21 | // pin07 = 7 22 | // pin08 = 8 23 | // pin09 = 9 24 | // pin10 = 10 25 | // pin11 = 11 26 | // pin14 = 14 27 | // pin15 = 15 28 | // pin16 = 16 29 | // pin17 = 17 30 | // pin18 = 18 31 | // pin19 = 19 32 | // pin20 = 20 33 | // pin21 = 21 34 | // pin22 = 22 35 | // pin23 = 23 36 | // 37 | //turbo 38 | // 39 | //start 40 | // 41 | // pin03 ^:= /pin03*/pin14 42 | // + pin03* pin14; 43 | // 44 | // pin04 ^:= /pin04* pin14 45 | // + pin03*/pin04*/pin14 46 | // + pin03* pin04* pin14; 47 | // 48 | // pin05 ^:= pin03*/pin05* pin14 49 | // + pin04* pin05* pin14 50 | // + pin03* pin04*/pin05*/pin14; 51 | // 52 | // pin06 ^:= pin03*/pin06*/pin14 53 | // + pin04*/pin05* pin06 54 | // + pin03* pin04* pin05*/pin06*/pin14; 55 | // 56 | // pin07 ^:= /pin03* pin05*/pin07 57 | // + /pin04*/pin06* pin07* pin14 58 | // + pin03* pin04* pin05* pin06*/pin07*/pin14; 59 | // 60 | // pin08 ^:= /pin03*/pin05* pin07*/pin08 61 | // + /pin04* pin06* pin08* pin14 62 | // + pin03* pin04* pin05* pin06* pin07*/pin08*/pin14; 63 | // 64 | // pin09 ^:= /pin07* pin08*/pin09 65 | // + pin04*/pin05*/pin06* pin09 66 | // + pin03* pin04* pin05* pin06* pin07* pin08*/pin09*/pin14; 67 | // 68 | // pin10 ^:= /pin04* pin07*/pin08*/pin10 69 | // + pin05* pin06*/pin09* pin10 70 | // + pin03* pin04* pin05* pin06* pin07* pin08* pin09*/pin10*/pin14; 71 | // 72 | // pin15 ^:= /pin07* pin08*/pin15 73 | // + /pin06* pin09*/pin10* pin15 74 | // + pin03* pin04* pin05* pin06* pin07* pin08* pin09* pin10*/pin14*/pin15; 75 | // 76 | // pin16 ^:= /pin09*/pin15* pin16 77 | // + /pin08* pin10*/pin16 78 | // + pin03* pin04* pin05* pin06* pin07* pin08* pin09* pin10*/pin14* pin15*/pin16; 79 | // 80 | // pin17 ^:= /pin08* pin17 81 | // + /pin10*/pin16*/pin17 82 | // + pin03* pin04* pin05* pin06* pin07* pin08* pin09* pin10*/pin14* pin15* pin16*/pin17; 83 | // 84 | // pin18 ^:= /pin15* pin16* pin18 85 | // + pin08*/pin10* pin17*/pin18 86 | // + pin03* pin04* pin05* pin06* pin07* pin08* pin09* pin10*/pin14* pin15* pin16* pin17*/pin18; 87 | // 88 | // pin19 ^:= pin10*/pin15*/pin19 89 | // + pin16*/pin17* pin18* pin19 90 | // + pin03* pin04* pin05* pin06* pin07* pin08* pin09* pin10*/pin14* pin15* pin16* pin17* pin18*/pin19; 91 | // 92 | // pin20 ^:= /pin16*/pin19*/pin20 93 | // + pin17*/pin18* pin20 94 | // + pin03* pin04* pin05* pin06* pin07* pin08* pin09* pin10*/pin14* pin15* pin16* pin17* pin18* pin19*/pin20; 95 | // 96 | // pin21 ^:= /pin17* pin18*/pin21 97 | // + /pin16* pin19*/pin20* pin21 98 | // + pin03* pin04* pin05* pin06* pin07* pin08* pin09* pin10*/pin14* pin15* pin16* pin17* pin18* pin19* pin20*/pin21; 99 | // 100 | // pin22.ena = /pin02; 101 | // pin22 ^:= /pin04* pin22 102 | // + pin05* pin14*/pin22 103 | // + pin09*/pin14*/pin16*/pin18* pin22 104 | // + /pin06* pin09* pin14* pin17*/pin21* pin22 105 | // + pin03* pin04* pin05* pin06* pin07* pin08* pin09* pin10*/pin14* pin15* pin16* pin17* pin18* pin19* pin20* pin21*/pin22; 106 | // 107 | // 108 | //end 109 | 110 | reg pin03; 111 | reg pin04; 112 | reg pin05; 113 | reg pin06; 114 | reg pin07; 115 | reg pin08; 116 | reg pin09; 117 | reg pin10; 118 | reg pin15; 119 | reg pin16; 120 | reg pin17; 121 | reg pin18; 122 | reg pin19; 123 | reg pin20; 124 | reg pin21; 125 | 126 | reg rom3_nD; 127 | always @(posedge clk) begin 128 | rom3_nD <= rom3_n; 129 | if (reset) begin 130 | pin03 <= 0; 131 | pin04 <= 0; 132 | pin05 <= 0; 133 | pin06 <= 0; 134 | pin07 <= 0; 135 | pin08 <= 0; 136 | pin09 <= 0; 137 | pin10 <= 0; 138 | pin16 <= 0; 139 | pin17 <= 0; 140 | pin18 <= 0; 141 | pin19 <= 0; 142 | pin20 <= 0; 143 | pin21 <= 0; 144 | d8 <= 0; 145 | end 146 | else 147 | if (rom3_n & !rom3_nD) begin 148 | pin03 <= pin03 ^ ( (!pin03&!a8) 149 | | (pin03& a8)); 150 | 151 | pin04 <= pin04 ^ ( ((!pin04& a8) 152 | | ( pin03&!pin04&!a8) 153 | | ( pin03& pin04& a8))); 154 | 155 | pin05 <= pin05 ^ ( (( pin03&!pin05& a8) 156 | | ( pin04& pin05& a8) 157 | | ( pin03& pin04&!pin05&!a8))); 158 | 159 | pin06 <= pin06 ^ ( (( pin03&!pin06&!a8) 160 | | ( pin04&!pin05& pin06) 161 | | ( pin03& pin04& pin05&!pin06&!a8))); 162 | 163 | pin07 <= pin07 ^ ( ((!pin03& pin05&!pin07) 164 | | (!pin04&!pin06& pin07& a8) 165 | | ( pin03& pin04& pin05& pin06&!pin07&!a8))); 166 | 167 | pin08 <= pin08 ^ ( ((!pin03&!pin05& pin07&!pin08) 168 | | (!pin04& pin06& pin08& a8) 169 | | ( pin03& pin04& pin05& pin06& pin07&!pin08&!a8))); 170 | 171 | pin09 <= pin09 ^ ( ((!pin07& pin08&!pin09) 172 | | ( pin04&!pin05&!pin06& pin09) 173 | | ( pin03& pin04& pin05& pin06& pin07& pin08&!pin09&!a8))); 174 | 175 | pin10 <= pin10 ^ ( ((!pin04& pin07&!pin08&!pin10) 176 | | ( pin05& pin06&!pin09& pin10) 177 | | ( pin03& pin04& pin05& pin06& pin07& pin08& pin09&!pin10&!a8))); 178 | 179 | pin15 <= pin15 ^ ( ((!pin07& pin08&!pin15) 180 | | (!pin06& pin09&!pin10& pin15) 181 | | ( pin03& pin04& pin05& pin06& pin07& pin08& pin09& pin10&!a8&!pin15))); 182 | 183 | pin16 <= pin16 ^ ( ((!pin09&!pin15& pin16) 184 | | (!pin08& pin10&!pin16) 185 | | ( pin03& pin04& pin05& pin06& pin07& pin08& pin09& pin10&!a8& pin15&!pin16))); 186 | 187 | pin17 <= pin17 ^ ( ((!pin08& pin17) 188 | | (!pin10&!pin16&!pin17) 189 | | ( pin03& pin04& pin05& pin06& pin07& pin08& pin09& pin10&!a8& pin15& pin16&!pin17))); 190 | 191 | pin18 <= pin18 ^ ( ((!pin15& pin16& pin18) 192 | | ( pin08&!pin10& pin17&!pin18) 193 | | ( pin03& pin04& pin05& pin06& pin07& pin08& pin09& pin10&!a8& pin15& pin16& pin17&!pin18))); 194 | 195 | pin19 <= pin19 ^ ( (( pin10&!pin15&!pin19) 196 | | ( pin16&!pin17& pin18& pin19) 197 | | ( pin03& pin04& pin05& pin06& pin07& pin08& pin09& pin10&!a8& pin15& pin16& pin17& pin18&!pin19))); 198 | 199 | pin20 <= pin20 ^ ( ((!pin16&!pin19&!pin20) 200 | | ( pin17&!pin18& pin20) 201 | | ( pin03& pin04& pin05& pin06& pin07& pin08& pin09& pin10&!a8& pin15& pin16& pin17& pin18& pin19&!pin20))); 202 | 203 | pin21 <= pin21 ^ ( ((!pin17& pin18&!pin21) 204 | | (!pin16& pin19&!pin20& pin21) 205 | | ( pin03& pin04& pin05& pin06& pin07& pin08& pin09& pin10&!a8& pin15& pin16& pin17& pin18& pin19& pin20&!pin21))); 206 | 207 | d8 <= d8 ^ ( (!pin04& d8) 208 | | ( pin05& a8&!d8) 209 | | ( pin09&!a8&!pin16&!pin18& d8) 210 | | (!pin06& pin09& a8& pin17&!pin21& d8) 211 | | ( pin03& pin04& pin05& pin06& pin07& pin08& pin09& pin10&!a8& pin15& pin16& pin17& pin18& pin19& pin20& pin21&!d8)); 212 | end 213 | 214 | end 215 | 216 | endmodule 217 | -------------------------------------------------------------------------------- /mist/osd.v: -------------------------------------------------------------------------------- 1 | // A simple OSD implementation. Can be hooked up between a cores 2 | // VGA output and the physical VGA pins 3 | 4 | module osd ( 5 | // OSDs pixel clock, should be synchronous to cores pixel clock to 6 | // avoid jitter. 7 | input clk_sys, 8 | input ce, 9 | 10 | // SPI interface 11 | input SPI_SCK, 12 | input SPI_SS3, 13 | input SPI_DI, 14 | 15 | input [1:0] rotate, //[0] - rotate [1] - left or right 16 | 17 | // VGA signals coming from core 18 | input [OUT_COLOR_DEPTH-1:0] R_in, 19 | input [OUT_COLOR_DEPTH-1:0] G_in, 20 | input [OUT_COLOR_DEPTH-1:0] B_in, 21 | input HBlank, 22 | input VBlank, 23 | input HSync, 24 | input VSync, 25 | 26 | // VGA signals going to video connector 27 | output [OUT_COLOR_DEPTH-1:0] R_out, 28 | output [OUT_COLOR_DEPTH-1:0] G_out, 29 | output [OUT_COLOR_DEPTH-1:0] B_out 30 | ); 31 | 32 | parameter OSD_X_OFFSET = 11'd0; 33 | parameter OSD_Y_OFFSET = 11'd0; 34 | parameter OSD_COLOR = 3'd0; 35 | parameter OSD_AUTO_CE = 1'b1; 36 | parameter USE_BLANKS = 1'b0; 37 | parameter OUT_COLOR_DEPTH = 6; 38 | parameter BIG_OSD = 1'b0; 39 | 40 | localparam OSD_WIDTH = 11'd256; 41 | localparam OSD_HEIGHT = 11'd128; 42 | localparam OSD_LINES = 8 << BIG_OSD; 43 | 44 | localparam OSD_WIDTH_PADDED = OSD_WIDTH + (OSD_WIDTH >> 1); // 25% padding left and right 45 | 46 | // ********************************************************************************* 47 | // spi client 48 | // ********************************************************************************* 49 | 50 | // this core supports only the display related OSD commands 51 | // of the minimig 52 | reg osd_enable; 53 | (* ramstyle = "no_rw_check" *) reg [7:0] osd_buffer[256*OSD_LINES-1:0]; // the OSD buffer itself 54 | 55 | // the OSD has its own SPI interface to the io controller 56 | always@(posedge SPI_SCK, posedge SPI_SS3) begin 57 | reg [4:0] cnt; 58 | reg [11:0] bcnt; 59 | reg [7:0] sbuf; 60 | reg [7:0] cmd; 61 | 62 | if(SPI_SS3) begin 63 | cnt <= 0; 64 | bcnt <= 0; 65 | end else begin 66 | sbuf <= {sbuf[6:0], SPI_DI}; 67 | 68 | // 0:7 is command, rest payload 69 | if(cnt < 15) cnt <= cnt + 1'd1; 70 | else cnt <= 8; 71 | 72 | if(cnt == 7) begin 73 | cmd <= {sbuf[6:0], SPI_DI}; 74 | 75 | // lower four command bits are line address 76 | bcnt <= {sbuf[2:0], SPI_DI, 8'h00}; 77 | 78 | // command 0x40: OSDCMDENABLE, OSDCMDDISABLE 79 | if(sbuf[6:3] == 4'b0100) osd_enable <= SPI_DI; 80 | end 81 | 82 | // command 0x20: OSDCMDWRITE 83 | if((cmd[7:4] == 4'b0010) && (cnt == 15)) begin 84 | osd_buffer[bcnt] <= {sbuf[6:0], SPI_DI}; 85 | bcnt <= bcnt + 1'd1; 86 | end 87 | end 88 | end 89 | 90 | // ********************************************************************************* 91 | // video timing and sync polarity anaylsis 92 | // ********************************************************************************* 93 | 94 | // horizontal counter 95 | reg [10:0] h_cnt; 96 | reg [10:0] hs_low, hs_high; 97 | wire hs_pol = hs_high < hs_low; 98 | wire [10:0] dsp_width = (hs_pol & !USE_BLANKS) ? hs_low : hs_high; 99 | 100 | // vertical counter 101 | reg [10:0] v_cnt; 102 | reg [10:0] vs_low, vs_high; 103 | wire vs_pol = vs_high < vs_low; 104 | wire [10:0] dsp_height = (vs_pol & !USE_BLANKS) ? vs_low : vs_high; 105 | 106 | wire doublescan = (dsp_height>350); 107 | 108 | reg auto_ce_pix; 109 | always @(posedge clk_sys) begin 110 | reg [15:0] cnt = 0; 111 | reg [2:0] pixsz; 112 | reg [2:0] pixcnt; 113 | reg hs; 114 | 115 | cnt <= cnt + 1'd1; 116 | hs <= HSync; 117 | 118 | pixcnt <= pixcnt + 1'd1; 119 | if(pixcnt == pixsz) pixcnt <= 0; 120 | auto_ce_pix <= !pixcnt; 121 | 122 | if(hs && ~HSync) begin 123 | cnt <= 0; 124 | if(cnt <= OSD_WIDTH_PADDED * 2) pixsz <= 0; 125 | else if(cnt <= OSD_WIDTH_PADDED * 3) pixsz <= 1; 126 | else if(cnt <= OSD_WIDTH_PADDED * 4) pixsz <= 2; 127 | else if(cnt <= OSD_WIDTH_PADDED * 5) pixsz <= 3; 128 | else if(cnt <= OSD_WIDTH_PADDED * 6) pixsz <= 4; 129 | else pixsz <= 5; 130 | 131 | pixcnt <= 0; 132 | auto_ce_pix <= 1; 133 | end 134 | end 135 | 136 | wire ce_pix = OSD_AUTO_CE ? auto_ce_pix : ce; 137 | 138 | always @(posedge clk_sys) begin 139 | reg hsD; 140 | reg vsD; 141 | 142 | if(ce_pix) begin 143 | if (USE_BLANKS) begin 144 | h_cnt <= h_cnt + 1'd1; 145 | if(HBlank) begin 146 | h_cnt <= 0; 147 | if (h_cnt != 0) begin 148 | hs_high <= h_cnt; 149 | v_cnt <= v_cnt + 1'd1; 150 | end 151 | end 152 | if(VBlank) begin 153 | v_cnt <= 0; 154 | if (v_cnt != 0 && vs_high != v_cnt + 1'd1) vs_high <= v_cnt; 155 | end 156 | end else begin 157 | // bring hsync into local clock domain 158 | hsD <= HSync; 159 | 160 | // falling edge of HSync 161 | if(!HSync && hsD) begin 162 | h_cnt <= 0; 163 | hs_high <= h_cnt; 164 | end 165 | 166 | // rising edge of HSync 167 | else if(HSync && !hsD) begin 168 | h_cnt <= 0; 169 | hs_low <= h_cnt; 170 | v_cnt <= v_cnt + 1'd1; 171 | end else begin 172 | h_cnt <= h_cnt + 1'd1; 173 | end 174 | 175 | vsD <= VSync; 176 | 177 | // falling edge of VSync 178 | if(!VSync && vsD) begin 179 | v_cnt <= 0; 180 | // if the difference is only one line, that might be interlaced picture 181 | if (vs_high != v_cnt + 1'd1) vs_high <= v_cnt; 182 | end 183 | 184 | // rising edge of VSync 185 | else if(VSync && !vsD) begin 186 | v_cnt <= 0; 187 | // if the difference is only one line, that might be interlaced picture 188 | if (vs_low != v_cnt + 1'd1) vs_low <= v_cnt; 189 | end 190 | end 191 | end 192 | end 193 | 194 | // area in which OSD is being displayed 195 | reg [10:0] h_osd_start; 196 | reg [10:0] h_osd_end; 197 | reg [10:0] v_osd_start; 198 | reg [10:0] v_osd_end; 199 | 200 | always @(posedge clk_sys) begin 201 | h_osd_start <= ((dsp_width - OSD_WIDTH)>> 1) + OSD_X_OFFSET; 202 | h_osd_end <= h_osd_start + OSD_WIDTH; 203 | v_osd_start <= ((dsp_height- (OSD_HEIGHT<> 1) + OSD_Y_OFFSET; 204 | v_osd_end <= v_osd_start + (OSD_HEIGHT<= h_osd_start) && (h_cnt < h_osd_end) && 238 | ((USE_BLANKS && !VBlank) || (!USE_BLANKS && VSync != vs_pol)) && (v_cnt >= v_osd_start) && (v_cnt < v_osd_end); 239 | end 240 | end 241 | 242 | assign R_out = !osd_de ? R_in : {osd_pixel, osd_pixel, OSD_COLOR[2], R_in[OUT_COLOR_DEPTH-1:3]}; 243 | assign G_out = !osd_de ? G_in : {osd_pixel, osd_pixel, OSD_COLOR[1], G_in[OUT_COLOR_DEPTH-1:3]}; 244 | assign B_out = !osd_de ? B_in : {osd_pixel, osd_pixel, OSD_COLOR[0], B_in[OUT_COLOR_DEPTH-1:3]}; 245 | 246 | endmodule 247 | -------------------------------------------------------------------------------- /mist/cyc10/vidclkcntrl.sopcinfo: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | java.lang.Integer 8 | 1729161809 9 | false 10 | true 11 | false 12 | true 13 | GENERATION_ID 14 | 15 | 16 | java.lang.String 17 | 18 | false 19 | true 20 | false 21 | true 22 | UNIQUE_ID 23 | 24 | 25 | java.lang.String 26 | CYCLONE10LP 27 | false 28 | true 29 | false 30 | true 31 | DEVICE_FAMILY 32 | 33 | 34 | java.lang.String 35 | 10CL120YF484C8G 36 | false 37 | true 38 | false 39 | true 40 | DEVICE 41 | 42 | 43 | java.lang.String 44 | 8 45 | false 46 | true 47 | false 48 | true 49 | DEVICE_SPEEDGRADE 50 | 51 | 52 | java.lang.String 53 | Cyclone 10 LP 54 | false 55 | true 56 | false 57 | true 58 | DEVICE_FAMILY 59 | 60 | 61 | boolean 62 | false 63 | false 64 | true 65 | true 66 | true 67 | 68 | 73 | 75 | 76 | java.lang.String 77 | CYCLONE10LP 78 | false 79 | true 80 | false 81 | true 82 | DEVICE_FAMILY 83 | 84 | 85 | int 86 | 1 87 | false 88 | true 89 | true 90 | true 91 | 92 | 93 | int 94 | 2 95 | false 96 | true 97 | true 98 | true 99 | 100 | 101 | int 102 | 1 103 | false 104 | false 105 | false 106 | true 107 | 108 | 109 | boolean 110 | false 111 | false 112 | true 113 | true 114 | true 115 | 116 | 117 | boolean 118 | true 119 | false 120 | true 121 | true 122 | true 123 | 124 | 125 | java.lang.String 126 | UNKNOWN 127 | false 128 | true 129 | true 130 | true 131 | 132 | 133 | boolean 134 | false 135 | false 136 | true 137 | true 138 | true 139 | 140 | 141 | 144 | 145 | ui.blockdiagram.direction 146 | input 147 | 148 | 149 | java.lang.String 150 | 151 | false 152 | true 153 | true 154 | true 155 | 156 | 157 | java.lang.String 158 | 159 | false 160 | true 161 | true 162 | true 163 | 164 | 165 | java.lang.String 166 | UNKNOWN 167 | false 168 | true 169 | true 170 | true 171 | 172 | 173 | boolean 174 | false 175 | false 176 | true 177 | true 178 | true 179 | 180 | conduit 181 | false 182 | 183 | inclk1x 184 | Input 185 | 1 186 | inclk1x 187 | 188 | 189 | inclk0x 190 | Input 191 | 1 192 | inclk0x 193 | 194 | 195 | clkselect 196 | Input 197 | 1 198 | clkselect 199 | 200 | 201 | 202 | 205 | 206 | ui.blockdiagram.direction 207 | output 208 | 209 | 210 | java.lang.String 211 | 212 | false 213 | true 214 | true 215 | true 216 | 217 | 218 | java.lang.String 219 | 220 | false 221 | true 222 | true 223 | true 224 | 225 | 226 | java.lang.String 227 | UNKNOWN 228 | false 229 | true 230 | true 231 | true 232 | 233 | 234 | boolean 235 | false 236 | false 237 | true 238 | true 239 | true 240 | 241 | conduit 242 | false 243 | 244 | outclk 245 | Output 246 | 1 247 | outclk 248 | 249 | 250 | 251 | 252 | 1 253 | altclkctrl 254 | com.altera.entityinterfaces.IElementClass 255 | com.altera.entityinterfaces.IModule 256 | ALTCLKCTRL Intel FPGA IP 257 | 22.1 258 | 259 | 260 | 2 261 | conduit_end 262 | com.altera.entityinterfaces.IElementClass 263 | com.altera.entityinterfaces.IMutableConnectionPoint 264 | Conduit 265 | 22.1 266 | 267 | 22.1 922 268 | 269 | 270 | -------------------------------------------------------------------------------- /mist/data_io.v: -------------------------------------------------------------------------------- 1 | // 2 | // data_io.v 3 | // 4 | // Data interface for the Atari ST core on the MiST board. 5 | // Providing ROM and ACSI data up- and download via the MISTs 6 | // own arm7 cpu. 7 | // 8 | // http://code.google.com/p/mist-board/ 9 | // 10 | // Copyright (c) 2014-2015 Till Harbaum 11 | // Copyright (c) 2019 György Szombathelyi 12 | 13 | // This source file is free software: you can redistribute it and/or modify 14 | // it under the terms of the GNU General Public License as published 15 | // by the Free Software Foundation, either version 3 of the License, or 16 | // (at your option) any later version. 17 | // 18 | // This source file is distributed in the hope that it will be useful, 19 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | // GNU General Public License for more details. 22 | // 23 | // You should have received a copy of the GNU General Public License 24 | // along with this program. If not, see . 25 | // 26 | 27 | module data_io #(parameter ADDR_WIDTH=24, START_ADDR = 0) ( 28 | input clk, 29 | // io controller spi interface 30 | input sck, 31 | input ss, 32 | input ss_sd, 33 | input sdi, 34 | output reg sdo, 35 | 36 | // MiST settings 37 | output reg [31:0] ctrl_out, 38 | // horizontal and vertical screen adjustments 39 | output reg [15:0] video_adj, 40 | 41 | // data_in_reg valid 42 | output reg data_in_strobe_mist, 43 | output reg data_in_strobe_uio, 44 | output reg [15:0] data_in_reg, 45 | output reg [23:1] data_addr, 46 | output reg data_download, 47 | 48 | // valid before the next data_out_reg required 49 | // give enough time to advance the pointer and load 50 | output reg data_out_strobe, 51 | input [15:0] data_out_reg, 52 | 53 | output reg dma_ack, 54 | output reg [7:0] dma_status, 55 | 56 | output reg dma_nak, 57 | 58 | input [7:0] status_in, 59 | output [3:0] status_index 60 | ); 61 | 62 | // ********************************************************************************* 63 | // spi client 64 | // ********************************************************************************* 65 | 66 | reg [6:0] sbuf; 67 | reg [7:0] data; 68 | reg [2:0] bit_cnt; 69 | reg [3:0] byte_cnt; 70 | reg [7:0] cmd; 71 | reg odd; 72 | 73 | assign status_index = byte_cnt - 1'd1; 74 | 75 | localparam MIST_SET_ADDRESS = 8'h01; // set DMA address - not used 76 | localparam MIST_WRITE_MEMORY = 8'h02; 77 | localparam MIST_READ_MEMORY = 8'h03; 78 | localparam MIST_SET_CONTROL = 8'h04; 79 | localparam MIST_GET_DMASTATE = 8'h05; // reads state of ACSI 80 | localparam MIST_ACK_DMA = 8'h06; // acknowledge a dma command 81 | localparam MIST_BUS_REQ = 8'h07; // request bus - not used 82 | localparam MIST_BUS_REL = 8'h08; // release bus - not used 83 | localparam MIST_SET_VADJ = 8'h09; 84 | localparam MIST_NAK_DMA = 8'h0a; // reject a dma command 85 | 86 | localparam UIO_FILE_TX = 8'h53; 87 | localparam UIO_FILE_TX_DAT = 8'h54; 88 | localparam UIO_FILE_INDEX = 8'h55; 89 | 90 | // SPI bit and byte counters 91 | reg [15:0] data_out_reg_r; 92 | reg [ 7:0] status_in_r; 93 | 94 | always@(posedge sck or posedge ss) begin 95 | if(ss == 1) begin 96 | bit_cnt <= 0; 97 | byte_cnt <= 0; 98 | cmd <= 0; 99 | odd <= 0; 100 | end else begin 101 | if (!bit_cnt) begin 102 | if (odd) data_out_reg_r <= data_out_reg; 103 | status_in_r <= status_in; 104 | end 105 | if(&bit_cnt) begin 106 | odd <= ~odd; 107 | if(~&byte_cnt) byte_cnt <= byte_cnt + 1'd1; 108 | if (!byte_cnt) cmd <= {sbuf, sdi}; 109 | end 110 | bit_cnt <= bit_cnt + 1'd1; 111 | end 112 | end 113 | 114 | reg spi_receiver_strobe_sd_r = 0; 115 | reg spi_transfer_end_sd_r = 1; 116 | reg [7:0] spi_byte_in_sd; 117 | reg [6:0] sbuf_sd; 118 | reg [2:0] bit_cnt_sd; 119 | 120 | // direct SD 121 | always@(posedge sck or posedge ss_sd) begin 122 | if(ss_sd == 1) begin 123 | bit_cnt_sd <= 0; 124 | spi_transfer_end_sd_r <= 1; 125 | end else begin 126 | bit_cnt_sd <= bit_cnt_sd + 1'd1; 127 | spi_transfer_end_sd_r <= 0; 128 | if(&bit_cnt_sd) begin 129 | // finished reading a byte, prepare to transfer to clk_sys 130 | spi_byte_in_sd <= { sbuf_sd, sdi}; 131 | spi_receiver_strobe_sd_r <= ~spi_receiver_strobe_sd_r; 132 | end else 133 | sbuf_sd[6:0] <= { sbuf_sd[5:0], sdi }; 134 | end 135 | end 136 | 137 | // SPI transmitter FPGA -> IO 138 | always@(negedge sck or posedge ss) begin 139 | 140 | if(ss == 1) begin 141 | sdo <= 1; 142 | end else begin 143 | if(cmd == MIST_READ_MEMORY) 144 | sdo <= !bit_cnt ? data_out_reg[{ odd, ~bit_cnt }]: data_out_reg_r[{ odd, ~bit_cnt }]; 145 | else 146 | sdo <= !bit_cnt ? status_in[~bit_cnt] : status_in_r[~bit_cnt]; 147 | end 148 | end 149 | 150 | // SPI receiver IO -> FPGA 151 | reg spi_receiver_strobe_r = 0; 152 | reg spi_transfer_end_r = 1; 153 | reg [7:0] spi_byte_in; 154 | 155 | // Read at spi_sck clock domain, assemble bytes for transferring to clk_sys 156 | always@(posedge sck or posedge ss) begin 157 | 158 | if(ss == 1) begin 159 | spi_transfer_end_r <= 1; 160 | end else begin 161 | spi_transfer_end_r <= 0; 162 | 163 | if(&bit_cnt) begin 164 | // finished reading a byte, prepare to transfer to clk_sys 165 | spi_byte_in <= { sbuf, sdi}; 166 | spi_receiver_strobe_r <= ~spi_receiver_strobe_r; 167 | end else 168 | sbuf[6:0] <= { sbuf[5:0], sdi }; 169 | end 170 | end 171 | 172 | // Process bytes from SPI at the clk_sys domain 173 | always @(posedge clk) begin 174 | 175 | reg spi_receiver_strobe; 176 | reg spi_transfer_end; 177 | reg spi_receiver_strobeD; 178 | reg spi_transfer_endD; 179 | reg [7:0] acmd; 180 | reg [9:0] abyte_cnt; 181 | reg [31:8] latch; 182 | reg lo; 183 | 184 | reg spi_receiver_strobe_sd; 185 | reg spi_transfer_end_sd; 186 | reg spi_receiver_strobe_sdD; 187 | reg spi_transfer_end_sdD; 188 | reg [8:0] word_cnt; 189 | 190 | //synchronize between SPI and sys clock domains 191 | spi_receiver_strobeD <= spi_receiver_strobe_r; 192 | spi_receiver_strobe <= spi_receiver_strobeD; 193 | spi_transfer_endD <= spi_transfer_end_r; 194 | spi_transfer_end <= spi_transfer_endD; 195 | 196 | // strobe is set whenever a valid byte has been received 197 | if (~spi_transfer_endD & spi_transfer_end) begin 198 | abyte_cnt <= 0; 199 | lo <= 0; 200 | end else if (spi_receiver_strobeD ^ spi_receiver_strobe) begin 201 | 202 | if(~&abyte_cnt) 203 | abyte_cnt <= abyte_cnt + 1'd1; 204 | 205 | if(!abyte_cnt) begin 206 | acmd <= spi_byte_in; 207 | if (spi_byte_in == MIST_NAK_DMA) dma_nak <= ~dma_nak; 208 | end else begin 209 | case(acmd) 210 | 211 | MIST_SET_VADJ: 212 | if (abyte_cnt == 1) latch[15:8] <= spi_byte_in; 213 | else if (abyte_cnt == 2) video_adj <= { latch[15:8], spi_byte_in }; 214 | 215 | MIST_SET_CONTROL: 216 | if (abyte_cnt == 1) latch[31:24] <= spi_byte_in; 217 | else if (abyte_cnt == 2) latch[23:16] <= spi_byte_in; 218 | else if (abyte_cnt == 3) latch[15: 8] <= spi_byte_in; 219 | else if (abyte_cnt == 4) ctrl_out <= { latch[31:8], spi_byte_in }; 220 | 221 | MIST_WRITE_MEMORY, UIO_FILE_TX_DAT: 222 | begin 223 | lo <= ~lo; 224 | if (~lo) latch[15: 8] <= spi_byte_in; 225 | else begin 226 | data_in_reg <= { latch[15:8], spi_byte_in }; 227 | if (acmd == UIO_FILE_TX_DAT) begin 228 | data_in_strobe_uio <= ~data_in_strobe_uio; 229 | data_addr <= data_addr + 1'd1; 230 | end else 231 | data_in_strobe_mist <= ~data_in_strobe_mist; 232 | end 233 | end 234 | 235 | MIST_READ_MEMORY: 236 | begin 237 | lo <= ~lo; 238 | if (~lo) data_out_strobe <= ~data_out_strobe; 239 | end 240 | 241 | MIST_ACK_DMA: 242 | begin 243 | dma_ack <= ~dma_ack; 244 | dma_status <= spi_byte_in; 245 | end 246 | 247 | UIO_FILE_TX: 248 | // prepare 249 | if(spi_byte_in) begin 250 | data_download <= 1; 251 | end else begin 252 | data_download <= 0; 253 | end 254 | 255 | // index 256 | UIO_FILE_INDEX: 257 | case (spi_byte_in) 258 | 8'h00: data_addr <= (24'he00000 - 2'd2) >> 1; // TOS 256k 259 | 8'h01: data_addr <= (24'hfc0000 - 2'd2) >> 1; // TOS 192k 260 | 8'h02: data_addr <= (24'hfa0000 - 2'd2) >> 1; // Cartridge 261 | 8'h03: data_addr <= 23'h0; // Clear memory 262 | endcase 263 | 264 | endcase; 265 | end 266 | end 267 | 268 | // direct-sd connection 269 | // synchronize between SPI and sys clock domains 270 | spi_receiver_strobe_sdD <= spi_receiver_strobe_sd_r; 271 | spi_receiver_strobe_sd <= spi_receiver_strobe_sdD; 272 | spi_transfer_end_sdD <= spi_transfer_end_sd_r; 273 | spi_transfer_end_sd <= spi_transfer_end_sdD; 274 | 275 | // strobe is set whenever a valid byte has been received 276 | if (~spi_transfer_end_sdD & spi_transfer_end_sd) begin 277 | lo <= 0; 278 | word_cnt <= 0; 279 | end else if (spi_receiver_strobe_sdD ^ spi_receiver_strobe_sd) begin 280 | 281 | lo <= ~lo; 282 | if (~lo) latch[15: 8] <= spi_byte_in_sd; 283 | else begin 284 | word_cnt <= word_cnt + 1'd1; 285 | if (word_cnt == 9'd256) 286 | // skip CRC 287 | word_cnt <= 0; 288 | else begin 289 | // signal a new word to the DMA controller 290 | data_in_reg <= { latch[15:8], spi_byte_in_sd }; 291 | data_in_strobe_mist <= ~data_in_strobe_mist; 292 | end 293 | end 294 | end 295 | 296 | end 297 | 298 | endmodule 299 | -------------------------------------------------------------------------------- /mist/scandoubler.v: -------------------------------------------------------------------------------- 1 | // 2 | // scandoubler.v 3 | // 4 | // Copyright (c) 2015 Till Harbaum 5 | // 6 | // This source file is free software: you can redistribute it and/or modify 7 | // it under the terms of the GNU General Public License as published 8 | // by the Free Software Foundation, either version 3 of the License, or 9 | // (at your option) any later version. 10 | // 11 | // This source file is distributed in the hope that it will be useful, 12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | // GNU General Public License for more details. 15 | // 16 | // You should have received a copy of the GNU General Public License 17 | // along with this program. If not, see . 18 | 19 | // AMR - generates and output a pixel clock with a reliable phase relationship with 20 | // with the scandoubled hsync pulse. Allows the incoming data to be sampled more 21 | // sparsely, reducing block RAM usage. ce_x1/x2 are replaced with a ce_divider 22 | // which is the largest value the counter will reach before resetting - so 3'111 to 23 | // divide clk_sys by 8, 3'011 to divide by 4, 3'101 to divide by six. 24 | 25 | // Also now has a bypass mode, in which the incoming data will be scaled to the output 26 | // width but otherwise unmodified. Simplifies the rest of the video chain. 27 | 28 | 29 | module scandoubler 30 | ( 31 | // system interface 32 | input clk_sys, 33 | 34 | input bypass, 35 | 36 | // Pixelclock 37 | input [2:0] ce_divider, // 0 - clk_sys/4, 1 - clk_sys/2, 2 - clk_sys/3, 3 - clk_sys/4, etc. 38 | output pixel_ena, 39 | 40 | // scanlines (00-none 01-25% 10-50% 11-75%) 41 | input [1:0] scanlines, 42 | 43 | // shifter video interface 44 | input hb_in, 45 | input vb_in, 46 | input hs_in, 47 | input vs_in, 48 | input [COLOR_DEPTH-1:0] r_in, 49 | input [COLOR_DEPTH-1:0] g_in, 50 | input [COLOR_DEPTH-1:0] b_in, 51 | 52 | // output interface 53 | output hb_out, 54 | output vb_out, 55 | output hs_out, 56 | output vs_out, 57 | output [OUT_COLOR_DEPTH-1:0] r_out, 58 | output [OUT_COLOR_DEPTH-1:0] g_out, 59 | output [OUT_COLOR_DEPTH-1:0] b_out 60 | ); 61 | 62 | parameter HCNT_WIDTH = 9; // Resolution of scandoubler buffer 63 | parameter COLOR_DEPTH = 6; // Bits per colour to be stored in the buffer 64 | parameter HSCNT_WIDTH = 12; // Resolution of hsync counters 65 | parameter OUT_COLOR_DEPTH = 6; // Bits per color outputted 66 | 67 | // --------------------- create output signals ----------------- 68 | // latch everything once more to make it glitch free and apply scanline effect 69 | reg scanline; 70 | reg [OUT_COLOR_DEPTH-1:0] r; 71 | reg [OUT_COLOR_DEPTH-1:0] g; 72 | reg [OUT_COLOR_DEPTH-1:0] b; 73 | 74 | wire [COLOR_DEPTH*3-1:0] sd_mux = bypass ? {r_in, g_in, b_in} : sd_out[COLOR_DEPTH*3-1:0]; 75 | 76 | localparam m = OUT_COLOR_DEPTH/COLOR_DEPTH; 77 | localparam n = OUT_COLOR_DEPTH%COLOR_DEPTH; 78 | 79 | always @(*) begin 80 | if (n>0) begin 81 | b = { {m{sd_mux[COLOR_DEPTH-1:0]}}, sd_mux[COLOR_DEPTH-1 -:n] }; 82 | g = { {m{sd_mux[COLOR_DEPTH*2-1:COLOR_DEPTH]}}, sd_mux[COLOR_DEPTH*2-1 -:n] }; 83 | r = { {m{sd_mux[COLOR_DEPTH*3-1:COLOR_DEPTH*2]}}, sd_mux[COLOR_DEPTH*3-1 -:n] }; 84 | end else begin 85 | b = { {m{sd_mux[COLOR_DEPTH-1:0]}} }; 86 | g = { {m{sd_mux[COLOR_DEPTH*2-1:COLOR_DEPTH]}} }; 87 | r = { {m{sd_mux[COLOR_DEPTH*3-1:COLOR_DEPTH*2]}} }; 88 | end 89 | end 90 | 91 | 92 | reg [OUT_COLOR_DEPTH+6:0] r_mul; 93 | reg [OUT_COLOR_DEPTH+6:0] g_mul; 94 | reg [OUT_COLOR_DEPTH+6:0] b_mul; 95 | reg hb_o; 96 | reg vb_o; 97 | reg hs_o; 98 | reg vs_o; 99 | 100 | wire scanline_bypass = (!scanline) | (!(|scanlines)) | bypass; 101 | 102 | // More subtle variant of the scanlines effect. 103 | // 0 00 -> 1000000 0x40 - bypass / inert mode 104 | // 1 01 -> 0111010 0x3a - 25% 105 | // 2 10 -> 0101110 0x2e - 50% 106 | // 3 11 -> 0011010 0x1a - 75% 107 | 108 | wire [6:0] scanline_coeff = scanline_bypass ? 109 | 7'b1000000 : {~(&scanlines),scanlines[0],1'b1,~scanlines[0],2'b10}; 110 | 111 | always @(posedge clk_sys) begin 112 | if(ce_x2) begin 113 | hs_o <= hs_sd; 114 | vs_o <= vs_sd; 115 | hb_o <= hb_sd; 116 | vb_o <= vb_sd; 117 | 118 | // reset scanlines at every new screen 119 | if(vs_o != vs_in) scanline <= 0; 120 | 121 | // toggle scanlines at begin of every hsync 122 | if(hs_o && !hs_sd) scanline <= !scanline; 123 | 124 | r_mul<=r*scanline_coeff; 125 | g_mul<=g*scanline_coeff; 126 | b_mul<=b*scanline_coeff; 127 | end 128 | end 129 | 130 | wire [OUT_COLOR_DEPTH-1:0] r_o = r_mul[OUT_COLOR_DEPTH+5 -:OUT_COLOR_DEPTH]; 131 | wire [OUT_COLOR_DEPTH-1:0] g_o = g_mul[OUT_COLOR_DEPTH+5 -:OUT_COLOR_DEPTH]; 132 | wire [OUT_COLOR_DEPTH-1:0] b_o = b_mul[OUT_COLOR_DEPTH+5 -:OUT_COLOR_DEPTH]; 133 | 134 | // Output multiplexing 135 | wire blank_out = hb_out | vb_out; 136 | assign r_out = blank_out ? {OUT_COLOR_DEPTH{1'b0}} : bypass ? r : r_o; 137 | assign g_out = blank_out ? {OUT_COLOR_DEPTH{1'b0}} : bypass ? g : g_o; 138 | assign b_out = blank_out ? {OUT_COLOR_DEPTH{1'b0}} : bypass ? b : b_o; 139 | assign hb_out = bypass ? hb_in : hb_o; 140 | assign vb_out = bypass ? vb_in : vb_o; 141 | assign hs_out = bypass ? hs_in : hs_o; 142 | assign vs_out = bypass ? vs_in : vs_o; 143 | 144 | 145 | // scan doubler output register 146 | reg [COLOR_DEPTH*3-1:0] sd_out; 147 | 148 | // ================================================================== 149 | // ======================== the line buffers ======================== 150 | // ================================================================== 151 | 152 | // 2 lines of 2**HCNT_WIDTH pixels 3*COLOR_DEPTH bit RGB 153 | (* ramstyle = "no_rw_check" *) reg [COLOR_DEPTH*3-1:0] sd_buffer[2*2**HCNT_WIDTH]; 154 | 155 | // use alternating sd_buffers when storing/reading data 156 | reg line_toggle; 157 | 158 | // total hsync time (in 16MHz cycles), hs_total reaches 1024 159 | reg [HCNT_WIDTH-1:0] hcnt; 160 | reg [HSCNT_WIDTH:0] hs_max; 161 | reg [HSCNT_WIDTH:0] hs_rise; 162 | reg [HCNT_WIDTH-1:0] hb_fall[2]; 163 | reg [HCNT_WIDTH-1:0] hb_rise[2]; 164 | reg [HCNT_WIDTH+1:0] vb_event[2]; 165 | reg [HCNT_WIDTH+1:0] vs_event[2]; 166 | reg [HSCNT_WIDTH:0] synccnt; 167 | 168 | // Input pixel clock, aligned with input sync: 169 | wire[2:0] ce_divider_adj = |ce_divider ? ce_divider : 3'd3; // 0 = clk/4 for compatiblity 170 | reg [2:0] ce_divider_in; 171 | reg [2:0] ce_divider_out; 172 | 173 | reg [2:0] i_div; 174 | wire ce_x1 = (i_div == ce_divider_in); 175 | 176 | always @(posedge clk_sys) begin 177 | reg hsD, vsD; 178 | reg vbD; 179 | reg hbD; 180 | 181 | // Pixel logic on x1 clkena 182 | if(ce_x1) begin 183 | hcnt <= hcnt + 1'd1; 184 | vsD <= vs_in; 185 | vbD <= vb_in; 186 | 187 | sd_buffer[{line_toggle, hcnt}] <= {r_in, g_in, b_in}; 188 | if (vbD ^ vb_in) vb_event[line_toggle] <= {1'b1, vb_in, hcnt}; 189 | if (vsD ^ vs_in) vs_event[line_toggle] <= {1'b1, vs_in, hcnt}; 190 | // save position of hblank 191 | hbD <= hb_in; 192 | if(!hbD && hb_in) hb_rise[line_toggle] <= hcnt; 193 | if( hbD && !hb_in) hb_fall[line_toggle] <= hcnt; 194 | end 195 | 196 | // Generate pixel clock 197 | i_div <= i_div + 1'd1; 198 | 199 | if (i_div==ce_divider_adj) i_div <= 3'b000; 200 | 201 | synccnt <= synccnt + 1'd1; 202 | hsD <= hs_in; 203 | if(hsD && !hs_in) begin 204 | // At hsync latch the ce_divider counter limit for the input clock 205 | // and pass the previous input clock limit to the output stage. 206 | // This should give correct output if the pixel clock changes mid-screen. 207 | ce_divider_out <= ce_divider_in; 208 | ce_divider_in <= ce_divider_adj; 209 | hs_max <= {1'b0,synccnt[HSCNT_WIDTH:1]}; 210 | hcnt <= 0; 211 | synccnt <= 0; 212 | i_div <= 3'b000; 213 | end 214 | 215 | // save position of rising edge 216 | if(!hsD && hs_in) hs_rise <= {1'b0,synccnt[HSCNT_WIDTH:1]}; 217 | 218 | // begin of incoming hsync 219 | if(hsD && !hs_in) begin 220 | line_toggle <= !line_toggle; 221 | vb_event[!line_toggle] <= 0; 222 | vs_event[!line_toggle] <= 0; 223 | end 224 | 225 | end 226 | 227 | // ================================================================== 228 | // ==================== output timing generation ==================== 229 | // ================================================================== 230 | 231 | reg [HSCNT_WIDTH:0] sd_synccnt; 232 | reg [HCNT_WIDTH-1:0] sd_hcnt; 233 | reg vb_sd = 0; 234 | reg hb_sd = 0; 235 | reg hs_sd = 0; 236 | reg vs_sd = 0; 237 | 238 | // Output pixel clock, aligned with output sync: 239 | reg [2:0] sd_i_div; 240 | wire ce_x2 = (sd_i_div == ce_divider_out) | (sd_i_div == {1'b0,ce_divider_out[2:1]}); 241 | 242 | // timing generation runs 32 MHz (twice the input signal analysis speed) 243 | always @(posedge clk_sys) begin 244 | reg hsD; 245 | 246 | // Output logic on x2 clkena 247 | if(ce_x2) begin 248 | // output counter synchronous to input and at twice the rate 249 | sd_hcnt <= sd_hcnt + 1'd1; 250 | 251 | // read data from line sd_buffer 252 | sd_out <= sd_buffer[{~line_toggle, sd_hcnt}]; 253 | 254 | // Handle VBlank event 255 | if(vb_event[~line_toggle][HCNT_WIDTH+1] && sd_hcnt == vb_event[~line_toggle][HCNT_WIDTH-1:0]) vb_sd <= vb_event[~line_toggle][HCNT_WIDTH]; 256 | // Handle VSync event 257 | if(vs_event[~line_toggle][HCNT_WIDTH+1] && sd_hcnt == vs_event[~line_toggle][HCNT_WIDTH-1:0]) vs_sd <= vs_event[~line_toggle][HCNT_WIDTH]; 258 | // Handle HBlank events 259 | if(sd_hcnt == hb_rise[~line_toggle]) hb_sd <= 1; 260 | if(sd_hcnt == hb_fall[~line_toggle]) hb_sd <= 0; 261 | end 262 | 263 | sd_i_div <= sd_i_div + 1'd1; 264 | if (sd_i_div==ce_divider_adj) sd_i_div <= 3'b000; 265 | 266 | // Framing logic on sysclk 267 | sd_synccnt <= sd_synccnt + 1'd1; 268 | hsD <= hs_in; 269 | 270 | if(sd_synccnt == hs_max || (hsD && !hs_in)) begin 271 | sd_synccnt <= 0; 272 | sd_hcnt <= 0; 273 | hs_sd <= 0; 274 | sd_i_div <= 3'b000; 275 | end 276 | 277 | if(sd_synccnt == hs_rise) hs_sd <= 1; 278 | 279 | end 280 | 281 | wire ce_x4 = sd_i_div[0]; // Faster pixel_ena for higher subdivisions to prevent blending from becoming to coarse. 282 | 283 | assign pixel_ena = ce_divider_out > 3'd5 ? 284 | bypass ? ce_x2 : ce_x4 : 285 | bypass ? ce_x1 : ce_x2 ; 286 | 287 | endmodule 288 | -------------------------------------------------------------------------------- /mist/spdif.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------- 2 | // SPDIF Transmitter 3 | // V0.1 4 | // Ultra-Embedded.com 5 | // Copyright 2012 6 | // 7 | // Email: admin@ultra-embedded.com 8 | // 9 | // License: GPL 10 | // If you would like a version with a more permissive license for 11 | // use in closed source commercial applications please contact me 12 | // for details. 13 | //----------------------------------------------------------------- 14 | // 15 | // This file is open source HDL; you can redistribute it and/or 16 | // modify it under the terms of the GNU General Public License as 17 | // published by the Free Software Foundation; either version 2 of 18 | // the License, or (at your option) any later version. 19 | // 20 | // This file is distributed in the hope that it will be useful, 21 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 22 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23 | // GNU General Public License for more details. 24 | // 25 | // You should have received a copy of the GNU General Public 26 | // License along with this file; if not, write to the Free Software 27 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 28 | // USA 29 | //----------------------------------------------------------------- 30 | // altera message_off 10762 31 | // altera message_off 10240 32 | 33 | module spdif 34 | ( 35 | input clk_i, 36 | input rst_i, 37 | 38 | input [31:0] clk_rate_i, 39 | 40 | // Output 41 | output spdif_o, 42 | 43 | // Audio interface (16-bit x 2 = RL) 44 | input [31:0] sample_i, 45 | output reg sample_req_o 46 | ); 47 | 48 | // SPDIF bit output enable 49 | // Single cycle pulse synchronous to clk_i which drives 50 | // the output bit rate. 51 | // For 44.1KHz, 44100×32×2×2 = 5,644,800Hz 52 | // For 48KHz, 48000×32×2×2 = 6,144,000Hz 53 | 54 | parameter bit_clk = 48000*32*2*2; 55 | 56 | reg bit_out_en_i; 57 | 58 | reg [31:0] cnt; 59 | wire [31:0] cnt_next = cnt + bit_clk; 60 | 61 | always @(posedge clk_i) begin 62 | bit_out_en_i <= 0; 63 | cnt <= cnt_next; 64 | if(cnt_next >= clk_rate_i) begin 65 | cnt <= cnt_next - clk_rate_i; 66 | bit_out_en_i <= 1; 67 | end 68 | end 69 | 70 | //----------------------------------------------------------------- 71 | // Registers 72 | //----------------------------------------------------------------- 73 | reg [15:0] audio_sample_q; 74 | reg [8:0] subframe_count_q; 75 | 76 | reg load_subframe_q; 77 | reg [7:0] preamble_q; 78 | wire [31:0] subframe_w; 79 | 80 | reg [5:0] bit_count_q; 81 | reg bit_toggle_q; 82 | 83 | reg spdif_out_q; 84 | 85 | reg [5:0] parity_count_q; 86 | 87 | reg channel_status_bit_q; 88 | 89 | //----------------------------------------------------------------- 90 | // Subframe Counter 91 | //----------------------------------------------------------------- 92 | always @ (posedge rst_i or posedge clk_i ) 93 | begin 94 | if (rst_i == 1'b1) 95 | subframe_count_q <= 9'd0; 96 | else if (load_subframe_q) 97 | begin 98 | // 192 frames (384 subframes) in an audio block 99 | if (subframe_count_q == 9'd383) 100 | subframe_count_q <= 9'd0; 101 | else 102 | subframe_count_q <= subframe_count_q + 9'd1; 103 | end 104 | end 105 | 106 | //----------------------------------------------------------------- 107 | // Sample capture 108 | //----------------------------------------------------------------- 109 | reg [15:0] sample_buf_q; 110 | 111 | always @ (posedge rst_i or posedge clk_i ) 112 | begin 113 | if (rst_i == 1'b1) 114 | begin 115 | audio_sample_q <= 16'h0000; 116 | sample_buf_q <= 16'h0000; 117 | sample_req_o <= 1'b0; 118 | end 119 | else if (load_subframe_q) 120 | begin 121 | // Start of frame (first subframe)? 122 | if (subframe_count_q[0] == 1'b0) 123 | begin 124 | // Use left sample 125 | audio_sample_q <= sample_i[15:0]; 126 | 127 | // Store right sample 128 | sample_buf_q <= sample_i[31:16]; 129 | 130 | // Request next sample 131 | sample_req_o <= 1'b1; 132 | end 133 | else 134 | begin 135 | // Use right sample 136 | audio_sample_q <= sample_buf_q; 137 | 138 | sample_req_o <= 1'b0; 139 | end 140 | end 141 | else 142 | sample_req_o <= 1'b0; 143 | end 144 | 145 | // Timeslots 3 - 0 = Preamble 146 | assign subframe_w[3:0] = 4'b0000; 147 | 148 | // Timeslots 7 - 4 = 24-bit audio LSB 149 | assign subframe_w[7:4] = 4'b0000; 150 | 151 | // Timeslots 11 - 8 = 20-bit audio LSB 152 | assign subframe_w[11:8] = 4'b0000; 153 | 154 | // Timeslots 27 - 12 = 16-bit audio 155 | assign subframe_w[27:12] = audio_sample_q; 156 | 157 | // Timeslots 28 = Validity 158 | assign subframe_w[28] = 1'b0; // Valid 159 | 160 | // Timeslots 29 = User bit 161 | assign subframe_w[29] = 1'b0; 162 | 163 | // Timeslots 30 = Channel status bit 164 | assign subframe_w[30] = channel_status_bit_q ; //was constant 1'b0 enabling copy-bit; 165 | 166 | // Timeslots 31 = Even Parity bit (31:4) 167 | assign subframe_w[31] = 1'b0; 168 | 169 | //----------------------------------------------------------------- 170 | // Preamble and Channel status bit 171 | //----------------------------------------------------------------- 172 | localparam PREAMBLE_Z = 8'b00010111; // "B" channel A data at start of block 173 | localparam PREAMBLE_Y = 8'b00100111; // "W" channel B data 174 | localparam PREAMBLE_X = 8'b01000111; // "M" channel A data not at start of block 175 | 176 | reg [7:0] preamble_r; 177 | reg channel_status_bit_r; 178 | 179 | always @ * 180 | begin 181 | // Start of audio block? 182 | // Z(B) - Left channel 183 | if (subframe_count_q == 9'd0) 184 | preamble_r = PREAMBLE_Z; // Z(B) 185 | // Right Channel? 186 | else if (subframe_count_q[0] == 1'b1) 187 | preamble_r = PREAMBLE_Y; // Y(W) 188 | // Left Channel (but not start of block)? 189 | else 190 | preamble_r = PREAMBLE_X; // X(M) 191 | 192 | if (subframe_count_q[8:1] == 8'd2) // frame 2 => subframes 4 and 5 => 0 = copy inhibited, 1 = copy permitted 193 | channel_status_bit_r = 1'b1; 194 | else if (subframe_count_q[8:1] == 8'd15) // frame 15 => 0 = no indication, 1 = original media 195 | channel_status_bit_r = 1'b1; 196 | else if (subframe_count_q[8:1] == 8'd25) // frame 24 to 27 => sample frequency, 0100 = 48kHz, 0000 = 44kHz (l2r) 197 | channel_status_bit_r = 1'b1; 198 | else 199 | channel_status_bit_r = 1'b0; // everything else defaults to 0 200 | end 201 | 202 | always @ (posedge rst_i or posedge clk_i ) 203 | begin 204 | if (rst_i == 1'b1) 205 | begin 206 | preamble_q <= 8'h00; 207 | channel_status_bit_q <= 1'b0; 208 | end 209 | else if (load_subframe_q) 210 | begin 211 | preamble_q <= preamble_r; 212 | channel_status_bit_q <= channel_status_bit_r; 213 | end 214 | end 215 | 216 | //----------------------------------------------------------------- 217 | // Parity Counter 218 | //----------------------------------------------------------------- 219 | always @ (posedge rst_i or posedge clk_i ) 220 | begin 221 | if (rst_i == 1'b1) 222 | begin 223 | parity_count_q <= 6'd0; 224 | end 225 | // Time to output a bit? 226 | else if (bit_out_en_i) 227 | begin 228 | // Preamble bits? 229 | if (bit_count_q < 6'd8) 230 | begin 231 | parity_count_q <= 6'd0; 232 | end 233 | // Normal timeslots 234 | else if (bit_count_q < 6'd62) 235 | begin 236 | // On first pass through this timeslot, count number of high bits 237 | if (bit_count_q[0] == 0 && subframe_w[bit_count_q / 2] == 1'b1) 238 | parity_count_q <= parity_count_q + 6'd1; 239 | end 240 | end 241 | end 242 | 243 | //----------------------------------------------------------------- 244 | // Bit Counter 245 | //----------------------------------------------------------------- 246 | always @ (posedge rst_i or posedge clk_i) 247 | begin 248 | if (rst_i == 1'b1) 249 | begin 250 | bit_count_q <= 6'b0; 251 | load_subframe_q <= 1'b1; 252 | end 253 | // Time to output a bit? 254 | else if (bit_out_en_i) 255 | begin 256 | // 32 timeslots (x2 for double frequency) 257 | if (bit_count_q == 6'd63) 258 | begin 259 | bit_count_q <= 6'd0; 260 | load_subframe_q <= 1'b1; 261 | end 262 | else 263 | begin 264 | bit_count_q <= bit_count_q + 6'd1; 265 | load_subframe_q <= 1'b0; 266 | end 267 | end 268 | else 269 | load_subframe_q <= 1'b0; 270 | end 271 | 272 | //----------------------------------------------------------------- 273 | // Bit half toggle 274 | //----------------------------------------------------------------- 275 | always @ (posedge rst_i or posedge clk_i) 276 | if (rst_i == 1'b1) 277 | bit_toggle_q <= 1'b0; 278 | // Time to output a bit? 279 | else if (bit_out_en_i) 280 | bit_toggle_q <= ~bit_toggle_q; 281 | 282 | //----------------------------------------------------------------- 283 | // Output bit (BMC encoded) 284 | //----------------------------------------------------------------- 285 | reg bit_r; 286 | 287 | always @ * 288 | begin 289 | bit_r = spdif_out_q; 290 | 291 | // Time to output a bit? 292 | if (bit_out_en_i) 293 | begin 294 | // Preamble bits? 295 | if (bit_count_q < 6'd8) 296 | begin 297 | bit_r = preamble_q[bit_count_q[2:0]]; 298 | end 299 | // Normal timeslots 300 | else if (bit_count_q < 6'd62) 301 | begin 302 | if (subframe_w[bit_count_q / 2] == 1'b0) 303 | begin 304 | if (bit_toggle_q == 1'b0) 305 | bit_r = ~spdif_out_q; 306 | else 307 | bit_r = spdif_out_q; 308 | end 309 | else 310 | bit_r = ~spdif_out_q; 311 | end 312 | // Parity timeslot 313 | else 314 | begin 315 | // Even number of high bits, make odd 316 | if (parity_count_q[0] == 1'b0) 317 | begin 318 | if (bit_toggle_q == 1'b0) 319 | bit_r = ~spdif_out_q; 320 | else 321 | bit_r = spdif_out_q; 322 | end 323 | else 324 | bit_r = ~spdif_out_q; 325 | end 326 | end 327 | end 328 | 329 | always @ (posedge rst_i or posedge clk_i ) 330 | if (rst_i == 1'b1) 331 | spdif_out_q <= 1'b0; 332 | else 333 | spdif_out_q <= bit_r; 334 | 335 | assign spdif_o = spdif_out_q; 336 | 337 | endmodule 338 | -------------------------------------------------------------------------------- /mist/cyc10/vidclkcntrl/synthesis/vidclkcntrl.debuginfo: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | com.altera.sopcmodel.ensemble.EClockAdapter 8 | HANDSHAKE 9 | false 10 | true 11 | true 12 | true 13 | 14 | 15 | java.lang.String 16 | 10CL120YF484C8G 17 | false 18 | true 19 | true 20 | true 21 | 22 | 23 | java.lang.String 24 | CYCLONE10LP 25 | false 26 | true 27 | true 28 | true 29 | 30 | 31 | java.lang.String 32 | 8 33 | false 34 | true 35 | false 36 | true 37 | 38 | 39 | com.altera.sopcmodel.ensemble.Ensemble$EFabricMode 40 | QSYS 41 | false 42 | true 43 | false 44 | true 45 | 46 | 47 | boolean 48 | false 49 | false 50 | true 51 | false 52 | true 53 | 54 | 55 | int 56 | 1729161809 57 | false 58 | true 59 | true 60 | true 61 | 62 | 63 | boolean 64 | false 65 | false 66 | true 67 | false 68 | true 69 | 70 | 71 | com.altera.entityinterfaces.moduleext.IModuleGenerateHDL$HDLLanguage 72 | VERILOG 73 | false 74 | false 75 | false 76 | true 77 | 78 | 79 | boolean 80 | true 81 | false 82 | true 83 | true 84 | true 85 | 86 | 87 | com.altera.sopcmodel.definition.BoundaryDefinition 88 | 89 | false 90 | true 91 | false 92 | true 93 | 94 | 95 | int 96 | 1 97 | false 98 | true 99 | true 100 | true 101 | 102 | 103 | java.lang.String 104 | 105 | false 106 | true 107 | false 108 | true 109 | 110 | 111 | boolean 112 | false 113 | false 114 | true 115 | false 116 | true 117 | 118 | 119 | long 120 | 0 121 | false 122 | true 123 | false 124 | true 125 | 126 | 127 | java.lang.String 128 | 129 | false 130 | true 131 | false 132 | true 133 | 134 | 135 | long 136 | 0 137 | false 138 | true 139 | false 140 | true 141 | 142 | 143 | boolean 144 | false 145 | false 146 | true 147 | false 148 | true 149 | 150 | 155 | 157 | 158 | java.lang.String 159 | CYCLONE10LP 160 | false 161 | true 162 | false 163 | true 164 | DEVICE_FAMILY 165 | 166 | 167 | int 168 | 1 169 | false 170 | true 171 | true 172 | true 173 | 174 | 175 | int 176 | 2 177 | false 178 | true 179 | true 180 | true 181 | 182 | 183 | int 184 | 1 185 | false 186 | false 187 | false 188 | true 189 | 190 | 191 | boolean 192 | false 193 | false 194 | true 195 | true 196 | true 197 | 198 | 199 | boolean 200 | true 201 | false 202 | true 203 | true 204 | true 205 | 206 | 207 | java.lang.String 208 | UNKNOWN 209 | false 210 | true 211 | true 212 | true 213 | 214 | 215 | boolean 216 | false 217 | false 218 | true 219 | true 220 | true 221 | 222 | 223 | 226 | 227 | ui.blockdiagram.direction 228 | input 229 | 230 | 231 | java.lang.String 232 | 233 | false 234 | true 235 | true 236 | true 237 | 238 | 239 | java.lang.String 240 | 241 | false 242 | true 243 | true 244 | true 245 | 246 | 247 | java.lang.String 248 | UNKNOWN 249 | false 250 | true 251 | true 252 | true 253 | 254 | 255 | boolean 256 | false 257 | false 258 | true 259 | true 260 | true 261 | 262 | conduit 263 | false 264 | 265 | inclk1x 266 | Input 267 | 1 268 | inclk1x 269 | 270 | 271 | inclk0x 272 | Input 273 | 1 274 | inclk0x 275 | 276 | 277 | clkselect 278 | Input 279 | 1 280 | clkselect 281 | 282 | 283 | 284 | 287 | 288 | ui.blockdiagram.direction 289 | output 290 | 291 | 292 | java.lang.String 293 | 294 | false 295 | true 296 | true 297 | true 298 | 299 | 300 | java.lang.String 301 | 302 | false 303 | true 304 | true 305 | true 306 | 307 | 308 | java.lang.String 309 | UNKNOWN 310 | false 311 | true 312 | true 313 | true 314 | 315 | 316 | boolean 317 | false 318 | false 319 | true 320 | true 321 | true 322 | 323 | conduit 324 | false 325 | 326 | outclk 327 | Output 328 | 1 329 | outclk 330 | 331 | 332 | 333 | 334 | 1 335 | altclkctrl 336 | com.altera.entityinterfaces.IElementClass 337 | com.altera.entityinterfaces.IModule 338 | ALTCLKCTRL Intel FPGA IP 339 | 22.1 340 | 341 | 342 | 2 343 | conduit_end 344 | com.altera.entityinterfaces.IElementClass 345 | com.altera.entityinterfaces.IMutableConnectionPoint 346 | Conduit 347 | 22.1 348 | 349 | 22.1 922 350 | F23F0600FC00000001929A135085 351 | 352 | -------------------------------------------------------------------------------- /atarist/ethernec.v: -------------------------------------------------------------------------------- 1 | // ethernec.v 2 | // 3 | // Atari ST NE2000/ethernec implementation for the MiST board 4 | // https://github.com/mist-devel/mist-board 5 | // 6 | // Copyright (c) 2014 Till Harbaum 7 | // 8 | // This source file is free software: you can redistribute it and/or modify 9 | // it under the terms of the GNU General Public License as published 10 | // by the Free Software Foundation, either version 3 of the License, or 11 | // (at your option) any later version. 12 | // 13 | // This source file is distributed in the hope that it will be useful, 14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | // GNU General Public License for more details. 17 | // 18 | // You should have received a copy of the GNU General Public License 19 | // along with this program. If not, see . 20 | // 21 | 22 | // TODO: 23 | // rename rx_begin/tx_begin to rx_enable/tx_enable 24 | // cpu writing curr?? 25 | // min framelen check here (not in io controller) 26 | 27 | module ethernec ( 28 | // cpu register interface 29 | input clk, 30 | input rd, 31 | input wr, 32 | input [4:0] addr, 33 | input [7:0] din, 34 | output reg [7:0] dout, 35 | 36 | // ethernet status word to be read by io controller 37 | output [31:0] status, 38 | 39 | // interface to allow the io controller to read frames from the tx buffer 40 | input tx_begin, // rising edge before new tx byte stream is sent 41 | input tx_strobe, // rising edge before each tx byte 42 | output reg [7:0] tx_byte, // byte from transmit buffer 43 | 44 | // interface to allow the io controller to write frames to the tx buffer 45 | input rx_begin, // rising edge before new rx byte stream is sent 46 | input rx_strobe, // rising edge before each rx byte 47 | input [7:0] rx_byte, // byte to be written to rx buffer 48 | 49 | // interface to allow mac address being set by io controller 50 | input mac_begin, // rising edge before new mac is sent 51 | input mac_strobe, // rising edge before each mac byte 52 | input [7:0] mac_byte // mac address byte 53 | ); 54 | 55 | // some non-zero and non-all-ones bytes as status flags 56 | localparam STATUS_IDLE = 8'hfe; 57 | localparam STATUS_TX_PENDING = 8'ha5; 58 | localparam STATUS_TX_DONE = 8'h12; 59 | 60 | reg [7:0] statusCode; 61 | assign status = { statusCode, 5'h00, tbcr == tx_w_cnt, isr[1:0], tbcr }; 62 | 63 | localparam RX_W_IDLE = 2'b00; 64 | localparam RX_W_MAC = 2'b01; 65 | localparam RX_W_DATA = 2'b10; 66 | localparam RX_W_HEADER = 2'b11; 67 | 68 | reg [1:0] rx_w_state; 69 | 70 | // ----- bus interface signals as wired up on the ethernec/netusbee ------ 71 | // sel[0] = 0xfa0000 -> normal read 72 | // sel[1] = 0xfb0000 -> write through address bus 73 | wire ne_read = rd; 74 | wire ne_write = wr; 75 | 76 | reg ne_readD, ne_writeD; 77 | always @(posedge clk) begin 78 | ne_readD <= ne_read; 79 | ne_writeD <= ne_write; 80 | end 81 | 82 | wire ne_read_en = ~ne_read & ne_readD; 83 | wire ne_write_en = ~ne_write & ne_writeD; 84 | 85 | // ---------- ne2000 internal registers ------------- 86 | reg reset = 0; 87 | reg [7:0] cr; // ne command register 88 | reg [7:0] isr; // ne interrupt service register 89 | reg [7:0] imr; // interrupt mask register 90 | reg [7:0] curr; // current page register 91 | reg [7:0] bnry; // boundary page 92 | reg [7:0] dcr; 93 | reg [7:0] rcr; // receiver control register 94 | reg [7:0] tcr; // transmitter control register 95 | reg [7:0] tpsr; 96 | reg [7:0] pstart; // rx buffer ring start page 97 | reg [7:0] pstop; // rx buffer ring stop page 98 | reg [7:0] par [5:0]; // 6 byte mac address register 99 | reg [7:0] mar [7:0]; // 8 byte multicast hash register 100 | reg [15:0] rbcr; // receiver byte count register 101 | reg [15:0] rsar; // receiver address register 102 | reg [15:0] tbcr; // transmitter byte count register 103 | 104 | 105 | wire [1:0] ps = cr[7:6]; // register page select 106 | 107 | // ------------- rx/tx buffers ------------ 108 | localparam FRAMESIZE = 1536; 109 | 110 | reg [7:0] rx_buffer [FRAMESIZE+3:0]; // 1 ethernet frame + 4 bytes header 111 | reg [15:0] rx_r_cnt, rx_w_cnt; // receive buffer byte counter 112 | 113 | reg [7:0] tx_buffer [FRAMESIZE-1:0]; // 1 ethernet frame 114 | reg [15:0] tx_w_cnt, tx_r_cnt; // transmit buffer byte counter 115 | 116 | // ------------- io controller read access to tx buffer ------------ 117 | always @(posedge clk) begin 118 | tx_byte <= tx_buffer[tx_r_cnt]; 119 | 120 | if (tx_done) 121 | tx_r_cnt <= 0; 122 | else if (tx_strobe_r2 & ~tx_strobe_r3) 123 | tx_r_cnt <= tx_r_cnt + 1'd1; 124 | 125 | end 126 | 127 | reg tx_begin_r, tx_begin_r2, tx_begin_r3; 128 | reg tx_strobe_r, tx_strobe_r2, tx_strobe_r3; 129 | reg rx_begin_d; 130 | 131 | always @(posedge clk) begin 132 | {tx_begin_r3, tx_begin_r2, tx_begin_r} <= {tx_begin_r2, tx_begin_r, tx_begin}; 133 | {tx_strobe_r3, tx_strobe_r2, tx_strobe_r} <= {tx_strobe_r2, tx_strobe_r, tx_strobe}; 134 | rx_begin_d <= rx_begin; 135 | end 136 | wire tx_done = tx_begin_r2 & !tx_begin_r3; 137 | 138 | // ------------- set local mac address ------------ 139 | 140 | // mac address from io controller 141 | reg [7:0] mac [5:0]; 142 | reg [2:0] mac_cnt; 143 | 144 | always @(posedge clk) begin 145 | if (mac_begin) 146 | mac_cnt <= 0; 147 | else if (mac_strobe) begin 148 | if(mac_cnt < 6) begin 149 | mac[mac_cnt] <= mac_byte; 150 | mac_cnt <= mac_cnt + 3'd1; 151 | end 152 | end 153 | end 154 | 155 | // cpu register read 156 | always @(*) begin 157 | dout = 8'd0; 158 | if(ne_read) begin // $faxxxx 159 | // cr, dma and reset are always available 160 | if(addr == 5'h00) dout = cr; 161 | 162 | // register page 0 163 | if(ps == 2'd0) begin 164 | if(addr == 5'h04) dout = 8'h23; // tsr: tx ok 165 | if(addr == 5'h07) dout = isr; 166 | end 167 | 168 | // register page 1 169 | if(ps == 2'd1) begin 170 | if(addr == 5'h07) dout = curr; 171 | end 172 | 173 | // read dma register $10 - $17 174 | if(addr[4:3] == 2'b10) 175 | dout = rx_buffer[rx_r_cnt]; 176 | 177 | end 178 | end 179 | 180 | reg resetD; 181 | 182 | // delay internal reset signal 183 | always @(posedge clk) resetD <= reset; 184 | 185 | // generate an internal strobe signal to copy mac address and to setup header 186 | wire int_strobe_en = ((rx_w_state == RX_W_MAC)||(rx_w_state == RX_W_HEADER)) ? 1'b1 : 1'b0; 187 | 188 | // internal mac transfer is started at the begin of the reset, internal header 189 | // transfer is started at the end of the data transmission 190 | wire int_begin = (reset & !resetD) || header_begin; 191 | 192 | // Several sources can write into the rx_buffer. The user_io SPI client receiving 193 | // data from the io controller or the ethernec core itself setting the mac address 194 | // or adding the rx header 195 | 196 | wire rx_write_en = rx_strobe || int_strobe_en; 197 | wire rx_write_begin = (!rx_begin_d & rx_begin) || int_begin; 198 | 199 | reg rx_lastByte; 200 | 201 | // the ne2000 page size is 256 bytes. thus the page counters are increased 202 | // every 256 bytes when a data transfer is in progress. First page is used when 203 | // the first byte is written to 0x0004 204 | wire rx_new_page = (rx_w_state == RX_W_DATA) && ((rx_w_cnt[7:0] == 8'h00) || (rx_w_cnt == 14'h0004)); 205 | reg rx_new_pageD; 206 | always @(posedge clk) 207 | rx_new_pageD <= rx_new_page; 208 | 209 | // -------- dummy page counter --------- 210 | reg [7:0] rx_page_cnt; 211 | always @(posedge clk) begin 212 | if(rx_new_page && !rx_new_pageD) 213 | rx_page_cnt <= rx_page_cnt + 8'd1; 214 | end 215 | 216 | // state/counter handling on one edge 217 | always @(posedge clk) begin 218 | if(rx_write_begin) begin 219 | if(rx_w_state == RX_W_MAC || rx_w_state == RX_W_HEADER) begin 220 | rx_w_cnt <= 16'd0; // mac and header is written to begin of buffer 221 | end else begin 222 | // payload starts at byte 4 (after ne2000 header) 223 | rx_w_cnt <= 16'd4; 224 | end 225 | 226 | end else if (rx_write_en) begin 227 | if(rx_w_state != RX_W_IDLE) begin 228 | // after reset the mac is written to the first 6 bytes of the rx buffer 229 | rx_w_cnt <= rx_w_cnt + 16'd1; 230 | end 231 | end 232 | end 233 | 234 | reg [15:0] rx_len; // number of bytes received from io controller 235 | 236 | wire [7:0] header_byte = 237 | (rx_w_cnt==0)?8'h01: 238 | (rx_w_cnt==1)?curr: 239 | (rx_w_cnt==2)?rx_len[7:0]: 240 | (rx_w_cnt==3)?rx_len[15:8]: 241 | 8'h55; 242 | 243 | always @(posedge clk) begin 244 | rx_lastByte <= 1'b0; 245 | 246 | if(((rx_w_state == RX_W_MAC) && (rx_w_cnt == 3'd6)) || 247 | ((rx_w_state == RX_W_HEADER) && (rx_w_cnt == 3'd4))) 248 | rx_lastByte <= !rx_write_begin; 249 | end 250 | 251 | // data transfer on other edge 252 | always @(posedge clk) begin 253 | if (rx_write_en) begin 254 | case (rx_w_state) 255 | RX_W_MAC: rx_buffer[rx_w_cnt] <= mac[rx_w_cnt]; 256 | RX_W_DATA: rx_buffer[rx_w_cnt] <= rx_byte; 257 | RX_W_HEADER: rx_buffer[rx_w_cnt] <= header_byte; 258 | default: ; 259 | endcase 260 | end 261 | end 262 | 263 | // register to delay receive counter increment by one cycle so this 264 | // does happen after the read cycle has finished 265 | reg rx_inc; 266 | reg tx_inc; 267 | 268 | // generate flag indicating that a header transfer is about to begin 269 | reg header_begin; 270 | always @(posedge clk) begin 271 | header_begin <= 1'b0; 272 | 273 | if(rx_begin_d & !rx_begin) 274 | header_begin <= 1'b1; 275 | end 276 | 277 | // write counter - header size (4) = number of bytes written 278 | always @(posedge clk) 279 | if (rx_begin_d & !rx_begin) 280 | rx_len <= rx_w_cnt - 16'd4; 281 | 282 | // cpu write via read 283 | always @(posedge clk) begin 284 | 285 | // rising edge of new page signal causes current page counter to advance 286 | // make sure counter stays within the limits of pstart/pstop 287 | if(rx_new_page && !rx_new_pageD) begin 288 | if(curr == (pstop-8'd1)) curr <= pstart; 289 | else curr <= curr + 8'd1; 290 | end 291 | 292 | // last byte ends a mac or header transfer and causes the 293 | // receiver state machine to return to the idle state 294 | if(rx_lastByte) begin 295 | rx_w_state <= RX_W_IDLE; 296 | 297 | // trigger rx interrupt (PRX) at end of transfer 298 | if(rx_w_state == RX_W_HEADER) 299 | isr[0] <= 1'b1; 300 | end 301 | 302 | // The rising edge of rx_begin indicates the start of a data transfer 303 | if(!rx_begin_d && rx_begin) 304 | rx_w_state <= RX_W_DATA; 305 | 306 | // The falling edge of rx_begin marks the end of a data transfer. 307 | // So we start setting up the pkt header after the end of the transfer 308 | if(rx_begin_d && !rx_begin) 309 | rx_w_state <= RX_W_HEADER; 310 | 311 | // cpu has read a byte from the rx buffer -> increase rx buffer read pointer 312 | rx_inc <= 1'b0; 313 | if(rx_inc && (rx_r_cnt < FRAMESIZE)) 314 | rx_r_cnt <= rx_r_cnt + 16'd1; 315 | 316 | // cpu has written a byte to the tx buffer -> increase tx buffer write pointer 317 | tx_inc <= 1'b0; 318 | if(tx_inc && (tx_w_cnt < FRAMESIZE)) 319 | tx_w_cnt <= tx_w_cnt + 16'd1; 320 | 321 | // signal end of transmission if tx buffer has been read by 322 | // io controller 323 | if(tx_done) begin 324 | isr[1] <= 1'b1; // PTX 325 | statusCode <= STATUS_TX_DONE; 326 | end 327 | 328 | // if cpu reads have internal side effects then ths is handled 329 | // here (and not in the "register read" block above) 330 | if(ne_read_en) begin 331 | // register page 0 332 | if(ps == 2'd0) begin 333 | end 334 | 335 | // register page 1 336 | if(ps == 2'd1) begin 337 | end 338 | 339 | // read dma register $10-$17 340 | if(addr[4:3] == 2'b10) 341 | rx_inc <= 1'b1; 342 | 343 | // read reset register $18-$1f 344 | if(addr[4:3] == 2'b11) begin 345 | reset <= 1'b1; // read to reset register sets reset 346 | isr[7] <= 1'b1; // set reset flag in isr 347 | 348 | statusCode <= STATUS_IDLE; 349 | rx_w_state <= RX_W_MAC; // mac address copy 350 | end 351 | end 352 | 353 | if(ne_write_en) begin 354 | if(addr == 5'h00) begin 355 | cr <= din; 356 | 357 | // writing the command register may actually start things ... 358 | 359 | // check for remote read 360 | if(din[5:3] == 3'd1) begin 361 | // this sets the receive counter, so data is being 362 | // read from the position specified in rsar of the buffer 363 | rx_r_cnt <= { 8'h00, rsar[7:0] }; 364 | end 365 | 366 | // check for remote write 367 | if(din[5:3] == 3'd2) begin 368 | // this resets the transmit counter, so data is being 369 | // written to the beginning of the buffer 370 | tx_w_cnt <= 16'h0000; 371 | end 372 | 373 | // check if TX bit was set 374 | if(din[2]) begin 375 | // tx buffer is now full and its contents need to be sent to 376 | // the io controller which in turn forwards it to its own nic 377 | 378 | // number of bytes to be transmitted is in tbcr, tx_w_cnt should 379 | // contain the same value since this is the number of write 380 | // cycles performed on the tx buffer 381 | statusCode <= STATUS_TX_PENDING; 382 | 383 | // once the io controller has sent the packet bit 2 in the isr 384 | // is being set. This will cause the ne2000 driver on atari side 385 | // to start filling the tx buffer again 386 | end 387 | 388 | end 389 | 390 | // register page 0 391 | if(ps == 2'd0) begin 392 | case (addr) 393 | 5'h01: pstart <= din; 394 | 5'h02: pstop <= din; 395 | 5'h03: bnry <= din; 396 | 5'h04: tpsr <= din; 397 | 5'h05: tbcr[7:0] <= din; 398 | 5'h06: tbcr[15:8] <= din; 399 | 5'h07: isr <= isr & (~din); // writing 1 clears bit 400 | 5'h08: rsar[7:0] <= din; 401 | 5'h09: rsar[15:8] <= din; 402 | 5'h0a: rbcr[7:0] <= din; 403 | 5'h0b: rbcr[15:8] <= din; 404 | 5'h0c: rcr <= din; 405 | 5'h0d: tcr <= din; 406 | 5'h0e: dcr <= din; 407 | 5'h0f: imr <= din; 408 | default: ; 409 | endcase 410 | end 411 | 412 | // register page 1 413 | if(ps == 2'd1) begin 414 | if((addr >= 5'h01) && (addr < 5'h07)) 415 | par[addr-5'd1] <= din; 416 | 417 | if(addr == 5'h07) curr <= din; 418 | 419 | if((addr >= 5'h08) && (addr < 5'h10)) 420 | mar[addr-5'd8] <= din; 421 | end 422 | 423 | // write to dma register $10-$17 424 | if(addr[4:3] == 2'b10) begin 425 | // prevent writing over end of buffer (whatever then happens ...) 426 | if(tx_w_cnt < FRAMESIZE) begin 427 | // store byte in buffer 428 | tx_buffer[tx_w_cnt] <= din; 429 | 430 | // increase byte counter 431 | tx_inc <= 1'b1; 432 | end 433 | end 434 | 435 | // reset register $18-$1f 436 | if(addr[4:3] == 2'b11) 437 | reset <= 1'b0; // write to reset register clears reset 438 | 439 | end 440 | end 441 | 442 | endmodule 443 | --------------------------------------------------------------------------------