├── .gitignore ├── README.md ├── ROMs ├── make_decoder_vhdl.py └── make_rom_file.py ├── doc └── photo │ └── robotron-on-nexys2.jpg ├── hardware └── mc6809e_adapter │ ├── mc6809e_adapter.brd │ ├── mc6809e_adapter.sch │ ├── mc6809e_adapter_bom.csv │ ├── mc6809e_adapter_laen2.cam │ ├── mc6809e_adapter_placements_bottom.pdf │ ├── mc6809e_adapter_placements_top.pdf │ └── mc6809e_adapter_schematic.pdf ├── hdl ├── robotron_cpu │ ├── board_digilent_nexys2_s3e_1200.ucf │ ├── led_decoder.vhd │ ├── mc6821.vhd │ ├── mc6821_tb.vhd │ ├── robotron_cpu.vhd │ ├── robotron_cpu_test.vhd │ ├── sc1.vhd │ └── sc1_tb.vhd └── robotron_sound │ ├── 7442.vhd │ ├── COPYING │ ├── board_digilent_nexys2_s3e_1200.ucf │ ├── board_xilinx_s3_400_starter_board.ucf │ ├── cpu68.vhd │ ├── m6810.vhd │ ├── m6810_test.vhd │ ├── pia6821.vhd │ ├── robotron_fpga_digilent_nexys2_s3e_1200.xise │ ├── robotron_fpga_xilinx_s3_400_starter_board.xise │ ├── robotron_sound.vhd │ ├── robotron_sound_digilent_nexys2_s3e_1200.vhd │ ├── robotron_test.vhd │ ├── rom_snd.vhd │ └── rom_test.vhd └── tools ├── dac_out_wave.py └── make_sound_rom.py /.gitignore: -------------------------------------------------------------------------------- 1 | /.gitignore.swp 2 | /_xmsgs/ 3 | /_ngo/ 4 | /iseconfig/ 5 | /xlnx_auto_0_xdb/ 6 | /xst/ 7 | /*.gise 8 | /*.bgn 9 | /*.bit 10 | /*.bld 11 | /*.cmd_log 12 | /*.drc 13 | /*.lso 14 | /*.map 15 | /*.mrp 16 | /*.ncd 17 | /*.ngc 18 | /*.ngd 19 | /*.ngm 20 | /*.ngr 21 | /*.pad 22 | /*.par 23 | /*.pcf 24 | /*.prj 25 | /*.ptwx 26 | /*.stx 27 | /*.syr 28 | /*.twr 29 | /*.twx 30 | /*.unroutes 31 | /*.ut 32 | /*.xpi 33 | /*.xrpt 34 | /*.xst 35 | /*.xwbt 36 | /*_pad.csv 37 | /*_pad.txt 38 | /*_summary.xml 39 | /*_usage.xml 40 | /*_webtalk.html 41 | /rom_*_blocks.vhd 42 | /webtalk.log 43 | /webtalk_pn.xml 44 | /tools/robotron.snd 45 | /tools/rom_*_blocks.vhd 46 | 47 | /ROMs/decoder.4 48 | /ROMs/decoder.6 49 | /ROMs/robotron.sb? 50 | /ROMs/robotron.snd 51 | /sounds/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | robotron-fpga 2 | ============= 3 | 4 | An implementation of the classic Robotron: 2084 video arcade game from 1982. 5 | Both the sound board and CPU/interface boards are implemented, but are in 6 | separate sub-projects at the moment. The CPU/interface implementation relies 7 | on a Motorola MC6809E processor attached to the FPGA board via an adapter 8 | board design that is part of this project. 9 | 10 | ![robotron-cpu on NEXYS2 FPGA board](https://github.com/sharebrained/robotron-fpga/raw/master/doc/photo/robotron-on-nexys2.jpg) 11 | 12 | The goal is to have a complete Robotron: 2084 game implemented in a single, 13 | compact, inexpensive FPGA board which includes the necessary peripherals: 14 | video and sound outputs, joysticks interface, and coin/player buttons. 15 | 16 | Status 17 | ====== 18 | 19 | The CPU/interface and sound boards are implemented as separate projects. 20 | Both appear to function well. 21 | 22 | The MC6809E breakout board has been fabricated, but has some design issues 23 | that need to be addressed. The primary issue is the lack of pull-up/-down 24 | resistors on key MC6809E signals, to keep the processor in a RESET state 25 | until the FPGA board is ready to work with the MC6809E. I also screwed up 26 | and put the NEXYS2 connector on the "bottom side" of the board. Smooth! 27 | 28 | Documentation 29 | ============= 30 | 31 | These documents served me well during development of this project. 32 | 33 | [Sean Riddle](http://seanriddle.com/) - Williams arcade machine information, 34 | including Robotron: 2084. 35 | 36 | * [Hardware overview](http://seanriddle.com/willhard.html) 37 | * [Memory map](http://seanriddle.com/memmap.gif) 38 | * [Processor and video timing](http://seanriddle.com/timing.html) 39 | * [BLTter description and test code](http://seanriddle.com/blittest.html) 40 | 41 | [Robotron-2084](http://www.robotron-2084.co.uk/) - Williams arcade machine 42 | official documentation. 43 | 44 | * [Robotron schematics and instruction manuals](http://www.robotron-2084.co.uk/manualsrobotron.html) 45 | * [Defender "later series" theory of operation](http://www.robotron-2084.co.uk/manualsdefender.html), 46 | interesting because the Robotron and Defender hardware is quite 47 | similar. 48 | 49 | Documentation for various ICs in the original Robotron: 2084 machine. 50 | 51 | * [MC6809E microprocessor datasheet](http://www.classiccmp.org/dunfield/r/6809e.pdf) 52 | * [MC6809E microprocessor programming manual](http://www.classiccmp.org/dunfield/r/6809prog.pdf) 53 | * [DM9316 Synchronous 4-Bit Binary Counter](http://www.ti.com/product/dm9316) 54 | * National Semiconductor(?) DM7489 64-bit random access read/write memory 55 | (no good reference) 56 | * [Harris HM-7641 512 x 8 PROM](http://www.bitsavers.org/pdf/harris/_dataBooks/1978_Harris_Memory_Vol1.pdf) (page 2-35) 57 | * [Harris HM-6514 1024 x 4 CMOS RAM](http://www.bitsavers.org/pdf/harris/_dataBooks/1978_Harris_Memory_Vol1.pdf) (page 3-49) 58 | * [Mostek MK4116 16,384 x 1 bit dynamic RAM](http://hardware.speccy.org/datasheet/MK4116.pdf) 59 | * [Signetics 8T97 hex buffer](http://www.bitsavers.org/pdf/signetics/_dataBooks/1977_Bipolar_Microprocessor.pdf) (page 96) 60 | * [Various 74-series logic ICs](http://www.ti.com/lsds/ti/logic/home_overview.page) 61 | 62 | [Digilent](http://www.digilentinc.com/) - FPGA development boards and 63 | accessories. 64 | 65 | * [NEXYS2 FPGA development board](http://digilentinc.com/Products/Detail.cfm?NavPath=2,400,789&Prod=NEXYS2) 66 | 67 | [Xilinx](http://www.xilinx.com/) - FPGA silicon and tools vendor. 68 | 69 | * [Spartan-3E documentation](http://www.xilinx.com/support/documentation/spartan-3e.htm) 70 | 71 | Requirements 72 | ============ 73 | 74 | * Digilent NEXYS2 Spartan-3E FPGA development board. 75 | 76 | This is the board I've done my development on, and is a good choice 77 | because it has plenty of inputs, a VGA output connector, many switches 78 | and LEDs, and enough onboard RAM and flash to meet the game's memory 79 | needs. 80 | 81 | * Williams Robotron: 2084 ROM binary files: 82 | 83 | These files are often used with MAME, the arcade emulator. CPU board 84 | ROM files are named "robotron.sb?", where "?" is "1" through "9" and 85 | "a" through "c". The sound board ROM file is named "robotron.snd". 86 | 87 | * Python 2.7: 88 | 89 | Used to transform ROM and PROM files into VHDL files. 90 | 91 | * Xilinx ISE WebPack 13.4: 92 | 93 | For compiling VHDL and generating the bit file for the FPGA. 94 | 95 | * Digilent Adept or other JTAG tool: 96 | 97 | For loading the bit file into FPGA board. 98 | 99 | * VGA monitor: 100 | 101 | Video output is 31.25 kHz horizontal sync and 60 Hz vertical sync, 102 | which is compatible with VGA monitors. The output is line-doubled 103 | from the arcade game's original 15.625 kHz horizontal sync. 104 | 105 | * RC lowpass filter: 106 | 107 | The PWM audio output from the FPGA needs filtering to sound reasonable, 108 | or an eight-bit DAC can be attached to the 8-bit audio output pins of 109 | the FPGA board. 110 | 111 | Tools 112 | ===== 113 | 114 | * make_rom_file.py: 115 | 116 | Translates a set of Robotron ROM board ROM files 117 | (like those you would use with the MAME arcade emulator) into a 118 | binary file that can be loaded into the flash device on the Digilent 119 | FPGA board. 120 | 121 | * make_decoder_vhdl.py: 122 | 123 | Translates a decoder.4 or decoder.6 file (data 124 | dumped from decoder PROMs on the Robotron CPU board) into a VHDL 125 | file used by the robotron_cpu project. 126 | 127 | * dac_out_wave.py: 128 | 129 | Translates the text file output of robotron_test.vhd 130 | into a WAV file that can be played. 131 | 132 | * make_sound_rom.py: 133 | 134 | Produces rom_snd_blocks.vhd, containing VHDL ROM 135 | blocks, from the contents of a robotron.snd ROM file. The 136 | robotron.snd file is not provided due to copyright on the original 137 | ROM binaries produced by Williams. I happen to have a physical 138 | instance of the ROM board, so I'm in the clear. :-) 139 | 140 | Contributing 141 | ============ 142 | 143 | Contributions are welcome! 144 | 145 | Please respect Williams Electronics' copyright and do not post any VHDL 146 | or .bit files containing their binary code. 147 | 148 | License 149 | ======= 150 | 151 | This hardware design is licensed under a 152 | [Creative Commons Attribution-ShareAlike 3.0 Unported License] 153 | (http://creativecommons.org/licenses/by-sa/3.0/). 154 | 155 | The associated software is provided under the GNU Public License, 156 | version 3: 157 | 158 | This project is free software: you can redistribute it and/or 159 | modify it under the terms of the GNU General Public License as 160 | published by the Free Software Foundation, either version 3 of the 161 | License, or (at your option) any later version. 162 | 163 | This project is distributed in the hope that it will be useful, 164 | but WITHOUT ANY WARRANTY; without even the implied warranty of 165 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 166 | General Public License for more details. 167 | 168 | You should have received a copy of the GNU General Public License 169 | along with this project. If not, see . 170 | 171 | Contact 172 | ======= 173 | 174 | Jared Boone 175 | 176 | ShareBrained Technology, Inc. 177 | 178 | 179 | 180 | 181 | The latest version of this repository can be found at 182 | https://github.com/sharebrained/robotron-fpga 183 | -------------------------------------------------------------------------------- /ROMs/make_decoder_vhdl.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | import numpy 5 | from math import log 6 | from os.path import splitext 7 | 8 | filename = sys.argv[1] 9 | entity_name = filename.replace(".", "_") 10 | data = numpy.fromfile(filename, dtype=numpy.uint8) 11 | bit_high = int(log(len(data), 2) - 1) 12 | bit_low = 0 13 | 14 | cases = [] 15 | for index in range(len(data)): 16 | value = data[index] 17 | index_bit_pattern = bin(index)[2:].zfill(bit_high+1) 18 | value_bit_pattern = bin(value)[2:].zfill(8) 19 | d = { 20 | "index": index, 21 | "index_bin": index_bit_pattern, 22 | "value": value, 23 | "value_bin": value_bit_pattern, 24 | } 25 | case = """ when "%(index_bin)s" => -- %(index)x 26 | data <= "%(value_bin)s"; -- %(value)x 27 | """ % d 28 | cases.append(case) 29 | cases = ''.join(cases) 30 | 31 | print("""-- From %(filename)s 32 | library ieee; 33 | use ieee.std_logic_1164.all; 34 | use ieee.numeric_std.all; 35 | 36 | entity %(entity_name)s is 37 | port( 38 | address : in std_logic_vector(%(bit_high)d downto %(bit_low)d); 39 | data : out std_logic_vector(7 downto 0) 40 | ); 41 | end %(entity_name)s; 42 | 43 | architecture Behavioral of %(entity_name)s is 44 | begin 45 | 46 | process(address) 47 | begin 48 | case address is 49 | %(cases)s 50 | when others => 51 | data <= (others => '0'); 52 | end case; 53 | end process; 54 | 55 | end Behavioral; 56 | """ % locals()) 57 | 58 | -------------------------------------------------------------------------------- /ROMs/make_rom_file.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | ####################################################################### 4 | # 5 | # Copyright 2012 ShareBrained Technology, Inc. 6 | # 7 | # This file is part of robotron-fpga. 8 | # 9 | # robotron-fpga is free software: you can redistribute 10 | # it and/or modify it under the terms of the GNU General 11 | # Public License as published by the Free Software 12 | # Foundation, either version 3 of the License, or (at your 13 | # option) any later version. 14 | # 15 | # robotron-fpga is distributed in the hope that it will 16 | # be useful, but WITHOUT ANY WARRANTY; without even the 17 | # implied warranty of MERCHANTABILITY or FITNESS FOR A 18 | # PARTICULAR PURPOSE. See the GNU General Public License 19 | # for more details. 20 | # 21 | # You should have received a copy of the GNU General 22 | # Public License along with robotron-fpga. If not, see 23 | # . 24 | # 25 | ####################################################################### 26 | 27 | # Generate a ROM file appropriate for uploading into the flash device 28 | # on the Digilent Nexys 2 FPGA development board. 29 | 30 | # The ROM files are those from the individual ROMs on the Robotron 31 | # ROM board. They are named in the same fashion as used with the MAME 32 | # arcade emulator. 33 | 34 | import numpy 35 | 36 | def make_robotron_rom(): 37 | rom_map = { 38 | '1': 0x0000, 39 | '2': 0x1000, 40 | '3': 0x2000, 41 | '4': 0x3000, 42 | '5': 0x4000, 43 | '6': 0x5000, 44 | '7': 0x6000, 45 | '8': 0x7000, 46 | '9': 0x8000, 47 | 'a': 0xd000, 48 | 'b': 0xe000, 49 | 'c': 0xf000, 50 | } 51 | 52 | memory = numpy.zeros((65536,), dtype=numpy.uint8) 53 | block_size = 4096 54 | for c, address in rom_map.items(): 55 | filename = 'robotron.sb%s' % c 56 | block = numpy.fromfile(filename, dtype=numpy.uint8) 57 | memory[address:address+block_size] = block 58 | 59 | return memory 60 | 61 | memory = make_robotron_rom() 62 | 63 | # Alternately, make a BLT test ROM image for Sean Riddle's 64 | # BLITTEST.BIN, available from his Web site. 65 | #memory = numpy.fromfile("BLITTEST.BIN", dtype=numpy.uint8) 66 | 67 | flash = numpy.array(memory, dtype=numpy.uint16) 68 | for i in range(len(flash)): 69 | l = (memory[i] >> 0) & 0xF 70 | h = (memory[i] >> 4) & 0xF 71 | flash[i] = (((((h << 4) | h) << 4) | l) << 4) | l 72 | flash.tofile('rom.bin') 73 | -------------------------------------------------------------------------------- /doc/photo/robotron-on-nexys2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sharebrained/robotron-fpga/291b721533f3563867da755f85314d5f934fde06/doc/photo/robotron-on-nexys2.jpg -------------------------------------------------------------------------------- /hardware/mc6809e_adapter/mc6809e_adapter.brd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sharebrained/robotron-fpga/291b721533f3563867da755f85314d5f934fde06/hardware/mc6809e_adapter/mc6809e_adapter.brd -------------------------------------------------------------------------------- /hardware/mc6809e_adapter/mc6809e_adapter.sch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sharebrained/robotron-fpga/291b721533f3563867da755f85314d5f934fde06/hardware/mc6809e_adapter/mc6809e_adapter.sch -------------------------------------------------------------------------------- /hardware/mc6809e_adapter/mc6809e_adapter_bom.csv: -------------------------------------------------------------------------------- 1 | Ref,Qty,Mfr,Mfr Part,Desc,Vendor,Vendor Part 2 | J1,1,Hirose,FX2-100S-1.27DS(71),CONN RECEPT R/A 100POS 1.27MM,Digi-Key,H10644-ND 3 | J2,1,CUI,PJ-102A,CONN JACK POWER 2.1MM PCB,Digi-Key,CP-102A-ND 4 | U1,1,Motorola,MC6809EP,"Microprocessor, 8bit CISC, 1MHz",Jameco,43545 5 | U1 (socket),1,Assmann,AR40-HZL-TT-R,IC SOCKET MACH PIN ST 40POS TIN,Digi-Key,AE10018-ND 6 | "U2,3,4,5,6",5,Texas Instruments,SN74LVC4245APW,IC BUS TRANSCEIVER 8BIT 24TSSOP,Digi-Key,296-12183-1-ND 7 | U7,1,Texas Instruments,SN74LVC1G14DCK,IC SGL SCHMT-TRIG INVERT SC70-5,Digi-Key,296-11608-1-ND 8 | U8,1,Microchip,TC1262-5.0VDB,IC CMOS LDO 500MA 5.0V SOT223-3,Digi-Key,TC1262-5.0VDB-ND 9 | R1,1,Yageo,RC0603FR-07220RL,RES 220 OHM 1/10W 1% 0603 SMD,Digi-Key,311-220HRCT-ND 10 | "R2,3,4,5,6,7,8",7,Yageo,RC0603FR-0710KL,RES 10.0K OHM 1/10W 1% 0603 SMD,Digi-Key,311-10.0KHRCT-ND 11 | "C1,2,3,4,5,6,7,8,9,10,11",11,Murata,GRM188R71C104KA01D,CAP CER 0.1UF 16V 10% X7R 0603,Digi-Key,490-1532-1-ND 12 | C12,1,Kemet,T491D476M010AT,CAP TANT 47UF 10V 20% 2917,Digi-Key,399-3796-1-ND 13 | "C13,14,15",2,Kemet,C0805C475K8PACTU,CAP CER 4.7UF 10V 10% X5R 0805,Digi-Key,399-3133-1-ND 14 | PCB,1,Laen,,Two-layer service,, -------------------------------------------------------------------------------- /hardware/mc6809e_adapter/mc6809e_adapter_laen2.cam: -------------------------------------------------------------------------------- 1 | [CAM Processor Job] 2 | Description[en]="Generates Extended Gerber Format

\nThis CAM job consists of five sections that generate data for a two layer board.

\nYou will get five gerber files that contain data for:
\ncomponent side *.cmp
\nsolder side *.sol
\nsilkscreen component side *.plc
\nsolder stop component side *.stc
\nsolder stop solder sid *.sts
" 3 | Section=Sec_1 4 | Section=Sec_2 5 | Section=Sec_3 6 | Section=Sec_4 7 | Section=Sec_5 8 | Section=Sec_6 9 | Section=Sec_7 10 | Section=Sec_8 11 | 12 | [Sec_1] 13 | Name[C]="Component side" 14 | Name[en]="Top Copper" 15 | Prompt[C]="" 16 | Prompt[en]="" 17 | Device="GERBER_RS274X" 18 | Wheel=".whl" 19 | Rack="" 20 | Scale=1 21 | Output=".toplayer.ger" 22 | Flags="0 0 0 1 0 1 1" 23 | Emulate="0 0 0" 24 | Offset="0.0mil 0.0mil" 25 | Sheet=1 26 | Tolerance="0 0 0 0 0 0" 27 | Pen="0.0mil 0" 28 | Page="12000.0mil 8000.0mil" 29 | Layers=" 1 17 18" 30 | Colors=" 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 6 6 4 8 8 8 8 8 8 8 8 8 8 8 8 8 4 4 1 1 1 1 3 3 1 2 6 8 8 5 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 2 4 3 6 6 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0" 31 | 32 | [Sec_2] 33 | Name[C]="Solder side" 34 | Name[en]="Bottom Copper" 35 | Prompt[C]="" 36 | Prompt[en]="" 37 | Device="GERBER_RS274X" 38 | Wheel=".whl" 39 | Rack="" 40 | Scale=1 41 | Output=".bottomlayer.ger" 42 | Flags="0 0 0 1 0 1 1" 43 | Emulate="0 0 0" 44 | Offset="0.0mil 0.0mil" 45 | Sheet=1 46 | Tolerance="0 0 0 0 0 0" 47 | Pen="0.0mil 0" 48 | Page="12000.0mil 8000.0mil" 49 | Layers=" 16 17 18" 50 | Colors=" 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 6 6 4 8 8 8 8 8 8 8 8 8 8 8 8 8 4 4 1 1 1 1 3 3 1 2 6 8 8 5 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 2 4 3 6 6 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0" 51 | 52 | [Sec_3] 53 | Name[C]="Silk screen CMP" 54 | Name[en]="Top Silk" 55 | Prompt[C]="" 56 | Prompt[en]="" 57 | Device="GERBER_RS274X" 58 | Wheel=".whl" 59 | Rack="" 60 | Scale=1 61 | Output=".topsilkscreen.ger" 62 | Flags="0 0 0 1 0 1 1" 63 | Emulate="0 0 0" 64 | Offset="0.0mil 0.0mil" 65 | Sheet=1 66 | Tolerance="0 0 0 0 0 0" 67 | Pen="0.0mil 0" 68 | Page="12000.0mil 8000.0mil" 69 | Layers=" 20 21" 70 | Colors=" 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 6 6 4 8 8 8 8 8 8 8 8 8 8 8 8 8 4 4 1 1 1 1 3 3 1 2 6 8 8 5 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 2 4 3 6 6 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0" 71 | 72 | [Sec_4] 73 | Name[C]="Silk screen SOL" 74 | Name[en]="Bottom Silk" 75 | Prompt[C]="" 76 | Prompt[en]="" 77 | Device="GERBER_RS274X" 78 | Wheel=".whl" 79 | Rack="" 80 | Scale=1 81 | Output=".bottomsilkscreen.ger" 82 | Flags="0 0 0 1 0 1 1" 83 | Emulate="0 0 0" 84 | Offset="0.0mil 0.0mil" 85 | Sheet=1 86 | Tolerance="0 0 0 0 0 0" 87 | Pen="0.0mil 0" 88 | Page="12000.0mil 8000.0mil" 89 | Layers=" 20 22" 90 | Colors=" 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 6 6 4 8 8 8 8 8 8 8 8 8 8 8 8 8 4 4 1 1 1 1 3 3 1 2 6 8 8 5 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 2 4 3 6 6 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0" 91 | 92 | [Sec_5] 93 | Name[C]="Solder stop mask CMP" 94 | Name[en]="Top Mask" 95 | Prompt[C]="" 96 | Prompt[en]="" 97 | Device="GERBER_RS274X" 98 | Wheel=".whl" 99 | Rack="" 100 | Scale=1 101 | Output=".topsoldermask.ger" 102 | Flags="0 0 0 1 0 1 1" 103 | Emulate="0 0 0" 104 | Offset="0.0mil 0.0mil" 105 | Sheet=1 106 | Tolerance="0 0 0 0 0 0" 107 | Pen="0.0mil 0" 108 | Page="12000.0mil 8000.0mil" 109 | Layers=" 29" 110 | Colors=" 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 6 6 4 8 8 8 8 8 8 8 8 8 8 8 8 8 4 4 1 1 1 1 3 3 1 2 6 8 8 5 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 2 4 3 6 6 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0" 111 | 112 | [Sec_6] 113 | Name[C]="Solder stop mask SOL" 114 | Name[en]="Bottom Mask" 115 | Prompt[C]="" 116 | Prompt[en]="" 117 | Device="GERBER_RS274X" 118 | Wheel=".whl" 119 | Rack="" 120 | Scale=1 121 | Output=".bottomsoldermask.ger" 122 | Flags="0 0 0 1 0 1 1" 123 | Emulate="0 0 0" 124 | Offset="0.0mil 0.0mil" 125 | Sheet=1 126 | Tolerance="0 0 0 0 0 0" 127 | Pen="0.0mil 0" 128 | Page="12000.0mil 8000.0mil" 129 | Layers=" 30" 130 | Colors=" 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 6 6 4 8 8 8 8 8 8 8 8 8 8 8 8 8 4 4 1 1 1 1 3 3 1 2 6 8 8 5 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 2 4 3 6 6 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0" 131 | 132 | [Sec_7] 133 | Name[C]="Board Outline" 134 | Name[en]="Board Outline" 135 | Prompt[C]="" 136 | Prompt[en]="" 137 | Device="GERBER_RS274X" 138 | Wheel=".whl" 139 | Rack="" 140 | Scale=1 141 | Output=".boardoutline.ger" 142 | Flags="0 0 0 1 0 1 1" 143 | Emulate="0 0 0" 144 | Offset="0.0mil 0.0mil" 145 | Sheet=1 146 | Tolerance="0 0 0 0 0 0" 147 | Pen="0.0mil 0" 148 | Page="12000.0mil 8000.0mil" 149 | Layers=" 20" 150 | Colors=" 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 6 6 4 8 8 8 8 8 8 8 8 8 8 8 8 8 4 4 1 1 1 1 3 3 1 2 6 8 8 5 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 2 4 3 6 6 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0" 151 | 152 | [Sec_8] 153 | Name[C]="Excellion Drill" 154 | Name[en]="Excellion Drill" 155 | Prompt[C]="" 156 | Prompt[en]="" 157 | Device="EXCELLON" 158 | Wheel=".whl" 159 | Rack="" 160 | Scale=1 161 | Output=".drills.xln" 162 | Flags="0 0 0 1 0 1 1" 163 | Emulate="0 0 0" 164 | Offset="0.0mil 0.0mil" 165 | Sheet=1 166 | Tolerance="0 0 0 0 0 0" 167 | Pen="0.0mil 0" 168 | Page="12000.0mil 8000.0mil" 169 | Layers=" 44 45" 170 | Colors=" 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 6 6 4 8 8 8 8 8 8 8 8 8 8 8 8 8 4 4 1 1 1 1 3 3 1 2 6 8 8 5 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 2 4 3 6 6 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0" 171 | -------------------------------------------------------------------------------- /hardware/mc6809e_adapter/mc6809e_adapter_placements_bottom.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sharebrained/robotron-fpga/291b721533f3563867da755f85314d5f934fde06/hardware/mc6809e_adapter/mc6809e_adapter_placements_bottom.pdf -------------------------------------------------------------------------------- /hardware/mc6809e_adapter/mc6809e_adapter_placements_top.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sharebrained/robotron-fpga/291b721533f3563867da755f85314d5f934fde06/hardware/mc6809e_adapter/mc6809e_adapter_placements_top.pdf -------------------------------------------------------------------------------- /hardware/mc6809e_adapter/mc6809e_adapter_schematic.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sharebrained/robotron-fpga/291b721533f3563867da755f85314d5f934fde06/hardware/mc6809e_adapter/mc6809e_adapter_schematic.pdf -------------------------------------------------------------------------------- /hdl/robotron_cpu/board_digilent_nexys2_s3e_1200.ucf: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2009-2012 ShareBrained Technology, Inc. 3 | # 4 | # This file is part of robotron-fpga. 5 | # 6 | # robotron-fpga is free software: you can redistribute 7 | # it and/or modify it under the terms of the GNU General 8 | # Public License as published by the Free Software 9 | # Foundation, either version 3 of the License, or (at your 10 | # option) any later version. 11 | # 12 | # robotron-fpga is distributed in the hope that it will 13 | # be useful, but WITHOUT ANY WARRANTY; without even the 14 | # implied warranty of MERCHANTABILITY or FITNESS FOR A 15 | # PARTICULAR PURPOSE. See the GNU General Public License 16 | # for more details. 17 | # 18 | # You should have received a copy of the GNU General 19 | # Public License along with robotron-fpga. If not, see 20 | # . 21 | 22 | #PACE: Start of Constraints generated by PACE 23 | #PACE: Start of PACE I/O Pin Assignments 24 | 25 | NET "*" IOSTANDARD = LVCMOS33; 26 | 27 | # Clock signals 28 | NET "CLK" LOC = "B8"; 29 | #NET "FX2_CLKIN" LOC = "B9"; 30 | #NET "FX2_CLKOUT" LOC = "D9"; 31 | #NET "FX2_CLKIO" LOC = "M9"; 32 | 33 | # FX2 I/O signals 34 | NET "HALT_N" LOC = "C3"; 35 | NET "NMI_N" LOC = "B6"; 36 | NET "TSC" LOC = "C4"; 37 | NET "IRQ_N" LOC = "C5"; 38 | NET "RESET_N" LOC = "D5"; 39 | NET "FIRQ_N" LOC = "F7"; 40 | NET "E" LOC = "B4"; 41 | NET "Q" LOC = "A4"; 42 | 43 | NET "LIC" LOC = "C7"; 44 | NET "AVMA" LOC = "D7"; 45 | NET "BUSY" LOC = "E9"; 46 | NET "BS" LOC = "F8"; 47 | NET "R_W_N" LOC = "C9"; 48 | NET "BA" LOC = "E8"; 49 | 50 | NET "D<0>" LOC = "B16"; 51 | NET "D<1>" LOC = "A16"; 52 | NET "D<2>" LOC = "B14"; 53 | NET "D<3>" LOC = "D14"; 54 | NET "D<4>" LOC = "C14"; 55 | NET "D<5>" LOC = "A14"; 56 | NET "D<6>" LOC = "E13"; 57 | NET "D<7>" LOC = "B13"; 58 | NET "A<0>" LOC = "A8"; 59 | NET "A<15>" LOC = "C11"; 60 | NET "A<1>" LOC = "G9"; 61 | NET "A<14>" LOC = "F11"; 62 | NET "A<2>" LOC = "F9"; 63 | NET "A<13>" LOC = "F12"; 64 | NET "A<3>" LOC = "D10"; 65 | NET "A<4>" LOC = "A10"; 66 | NET "A<5>" LOC = "B10"; 67 | NET "A<6>" LOC = "A11"; 68 | NET "A<7>" LOC = "D11"; 69 | NET "A<8>" LOC = "E10"; 70 | NET "A<9>" LOC = "B11"; 71 | NET "A<10>" LOC = "E11"; 72 | NET "A<11>" LOC = "E12"; 73 | NET "A<12>" LOC = "A13"; 74 | 75 | NET "SEG<0>" LOC = "L18"; 76 | NET "SEG<1>" LOC = "F18"; 77 | NET "SEG<2>" LOC = "D17"; 78 | NET "SEG<3>" LOC = "D16"; 79 | NET "SEG<4>" LOC = "G14"; 80 | NET "SEG<5>" LOC = "J17"; 81 | NET "SEG<6>" LOC = "H14"; 82 | NET "DP" LOC = "C17"; 83 | NET "AN<0>" LOC = "F17"; 84 | NET "AN<1>" LOC = "H17"; 85 | NET "AN<2>" LOC = "C18"; 86 | NET "AN<3>" LOC = "F15"; 87 | 88 | NET "LED<0>" LOC = "J14"; 89 | NET "LED<1>" LOC = "J15"; 90 | NET "LED<2>" LOC = "K15"; 91 | NET "LED<3>" LOC = "K14"; 92 | NET "LED<4>" LOC = "E16"; 93 | NET "LED<5>" LOC = "P16"; 94 | NET "LED<6>" LOC = "E4"; 95 | NET "LED<7>" LOC = "P4"; 96 | 97 | NET "SW<0>" LOC = "G18"; 98 | NET "SW<1>" LOC = "H18"; 99 | NET "SW<2>" LOC = "K18"; 100 | NET "SW<3>" LOC = "K17"; 101 | NET "SW<4>" LOC = "L14"; 102 | NET "SW<5>" LOC = "L13"; 103 | NET "SW<6>" LOC = "N17"; 104 | NET "SW<7>" LOC = "R17"; 105 | 106 | NET "BTN<0>" LOC = "B18"; 107 | NET "BTN<1>" LOC = "D18"; 108 | NET "BTN<2>" LOC = "E18"; 109 | NET "BTN<3>" LOC = "H13"; 110 | 111 | NET "MemOE" OFFSET = OUT 77.5 ns BEFORE "CLK"; 112 | NET "MemWR" OFFSET = OUT 78.5 ns BEFORE "CLK"; 113 | TIMEGRP "MemAdr" OFFSET = OUT 78.5 ns BEFORE "CLK"; 114 | TIMEGRP "MemDB" OFFSET = OUT 78 ns BEFORE "CLK"; 115 | 116 | NET "FlashCS" OFFSET = OUT 77.5 ns BEFORE "CLK"; 117 | 118 | NET "RamCS" OFFSET = OUT 77 ns BEFORE "CLK"; 119 | NET "RamLB" OFFSET = OUT 77.5 ns BEFORE "CLK"; 120 | NET "RamUB" OFFSET = OUT 77.5 ns BEFORE "CLK"; 121 | 122 | # onBoard Cellular RAM and StrataFlash 123 | NET "MemOE" LOC = "T2"; 124 | NET "MemWR" LOC = "N7"; 125 | NET "RamAdv" LOC = "J4"; 126 | NET "RamCS" LOC = "R6"; 127 | NET "RamClk" LOC = "H5"; 128 | NET "RamCRE" LOC = "P7"; 129 | NET "RamLB" LOC = "K5"; 130 | NET "RamUB" LOC = "K4"; 131 | NET "RamWait" LOC = "F5"; 132 | NET "FlashRp" LOC = "T5"; 133 | NET "FlashCS" LOC = "R5"; 134 | NET "FlashStSts" LOC = "D3"; 135 | NET "MemAdr<1>" LOC = "J1"; 136 | NET "MemAdr<2>" LOC = "J2"; 137 | NET "MemAdr<3>" LOC = "H4"; 138 | NET "MemAdr<4>" LOC = "H1"; 139 | NET "MemAdr<5>" LOC = "H2"; 140 | NET "MemAdr<6>" LOC = "J5"; 141 | NET "MemAdr<7>" LOC = "H3"; 142 | NET "MemAdr<8>" LOC = "H6"; 143 | NET "MemAdr<9>" LOC = "F1"; 144 | NET "MemAdr<10>" LOC = "G3"; 145 | NET "MemAdr<11>" LOC = "G6"; 146 | NET "MemAdr<12>" LOC = "G5"; 147 | NET "MemAdr<13>" LOC = "G4"; 148 | NET "MemAdr<14>" LOC = "F2"; 149 | NET "MemAdr<15>" LOC = "E1"; 150 | NET "MemAdr<16>" LOC = "M5"; 151 | NET "MemAdr<17>" LOC = "E2"; 152 | NET "MemAdr<18>" LOC = "C2"; 153 | NET "MemAdr<19>" LOC = "C1"; 154 | NET "MemAdr<20>" LOC = "D2"; 155 | NET "MemAdr<21>" LOC = "K3"; 156 | NET "MemAdr<22>" LOC = "D1"; 157 | NET "MemAdr<23>" LOC = "K6"; 158 | NET "MemDB<0>" LOC = "L1"; 159 | NET "MemDB<1>" LOC = "L4"; 160 | NET "MemDB<2>" LOC = "L6"; 161 | NET "MemDB<3>" LOC = "M4"; 162 | NET "MemDB<4>" LOC = "N5"; 163 | NET "MemDB<5>" LOC = "P1"; 164 | NET "MemDB<6>" LOC = "P2"; 165 | NET "MemDB<7>" LOC = "R2"; 166 | NET "MemDB<8>" LOC = "L3"; 167 | NET "MemDB<9>" LOC = "L5"; 168 | NET "MemDB<10>" LOC = "M3"; 169 | NET "MemDB<11>" LOC = "M6"; 170 | NET "MemDB<12>" LOC = "L2"; 171 | NET "MemDB<13>" LOC = "N4"; 172 | NET "MemDB<14>" LOC = "R3"; 173 | NET "MemDB<15>" LOC = "T1"; 174 | 175 | # VGA Connector 176 | NET "vgaRed<0>" LOC = "R9"; 177 | NET "vgaRed<1>" LOC = "T8"; 178 | NET "vgaRed<2>" LOC = "R8"; 179 | NET "vgaGreen<0>" LOC = "N8"; 180 | NET "vgaGreen<1>" LOC = "P8"; 181 | NET "vgaGreen<2>" LOC = "P6"; 182 | NET "vgaBlue<0>" LOC = "U5"; 183 | NET "vgaBlue<1>" LOC = "U4"; 184 | NET "Hsync" LOC = "T4"; 185 | NET "Vsync" LOC = "U3"; 186 | 187 | # Joysticks interface 1 188 | NET "JA<0>" LOC = "L15" |PULLUP; 189 | NET "JA<1>" LOC = "K12" |PULLUP; 190 | NET "JA<2>" LOC = "L17" |PULLUP; 191 | NET "JA<3>" LOC = "M15" |PULLUP; 192 | NET "JA<4>" LOC = "K13" |PULLUP; 193 | NET "JA<5>" LOC = "L16" |PULLUP; 194 | NET "JA<6>" LOC = "M14" |PULLUP; 195 | NET "JA<7>" LOC = "M16" |PULLUP; 196 | 197 | # Joysticks interface 2 198 | NET "JB<0>" LOC = "M13" |PULLUP; 199 | NET "JB<1>" LOC = "R18" |PULLUP; 200 | NET "JB<2>" LOC = "R15" |PULLUP; 201 | NET "JB<3>" LOC = "T17" |PULLUP; 202 | NET "JB<4>" LOC = "P17" |PULLUP; 203 | NET "JB<5>" LOC = "R16" |PULLUP; 204 | NET "JB<6>" LOC = "T18" |PULLUP; 205 | NET "JB<7>" LOC = "U18" |PULLUP; 206 | 207 | #PACE: Start of PACE Area Constraints 208 | #PACE: Start of PACE Prohibit Constraints 209 | #PACE: End of Constraints generated by PACE 210 | 211 | #Created by Constraints Editor (xc3s1200e-fg320-4) - 2011/08/31 212 | NET "CLK" TNM_NET = CLK; 213 | TIMESPEC TS_CLK = PERIOD "CLK" 50 MHz HIGH 50%; 214 | 215 | #Created by Constraints Editor (xc3s1200e-fg320-4) - 2012/08/28 216 | INST "MemAdr<1>" TNM = MemAdr; 217 | INST "MemAdr<2>" TNM = MemAdr; 218 | INST "MemAdr<3>" TNM = MemAdr; 219 | INST "MemAdr<4>" TNM = MemAdr; 220 | INST "MemAdr<5>" TNM = MemAdr; 221 | INST "MemAdr<6>" TNM = MemAdr; 222 | INST "MemAdr<7>" TNM = MemAdr; 223 | INST "MemAdr<8>" TNM = MemAdr; 224 | INST "MemAdr<9>" TNM = MemAdr; 225 | INST "MemAdr<10>" TNM = MemAdr; 226 | INST "MemAdr<11>" TNM = MemAdr; 227 | INST "MemAdr<12>" TNM = MemAdr; 228 | INST "MemAdr<13>" TNM = MemAdr; 229 | INST "MemAdr<14>" TNM = MemAdr; 230 | INST "MemAdr<15>" TNM = MemAdr; 231 | INST "MemAdr<16>" TNM = MemAdr; 232 | INST "MemAdr<17>" TNM = MemAdr; 233 | INST "MemAdr<18>" TNM = MemAdr; 234 | INST "MemAdr<19>" TNM = MemAdr; 235 | INST "MemAdr<20>" TNM = MemAdr; 236 | INST "MemAdr<21>" TNM = MemAdr; 237 | INST "MemAdr<22>" TNM = MemAdr; 238 | INST "MemAdr<23>" TNM = MemAdr; 239 | INST "MemDB<0>" TNM = MemDB; 240 | INST "MemDB<1>" TNM = MemDB; 241 | INST "MemDB<2>" TNM = MemDB; 242 | INST "MemDB<3>" TNM = MemDB; 243 | INST "MemDB<4>" TNM = MemDB; 244 | INST "MemDB<5>" TNM = MemDB; 245 | INST "MemDB<6>" TNM = MemDB; 246 | INST "MemDB<7>" TNM = MemDB; 247 | INST "MemDB<8>" TNM = MemDB; 248 | INST "MemDB<9>" TNM = MemDB; 249 | INST "MemDB<10>" TNM = MemDB; 250 | INST "MemDB<11>" TNM = MemDB; 251 | INST "MemDB<12>" TNM = MemDB; 252 | INST "MemDB<13>" TNM = MemDB; 253 | INST "MemDB<14>" TNM = MemDB; 254 | INST "MemDB<15>" TNM = MemDB; 255 | -------------------------------------------------------------------------------- /hdl/robotron_cpu/led_decoder.vhd: -------------------------------------------------------------------------------- 1 | ----------------------------------------------------------------------- 2 | -- 3 | -- Copyright 2009-2012 ShareBrained Technology, Inc. 4 | -- 5 | -- This file is part of robotron-fpga. 6 | -- 7 | -- robotron-fpga is free software: you can redistribute 8 | -- it and/or modify it under the terms of the GNU General 9 | -- Public License as published by the Free Software 10 | -- Foundation, either version 3 of the License, or (at your 11 | -- option) any later version. 12 | -- 13 | -- robotron-fpga is distributed in the hope that it will 14 | -- be useful, but WITHOUT ANY WARRANTY; without even the 15 | -- implied warranty of MERCHANTABILITY or FITNESS FOR A 16 | -- PARTICULAR PURPOSE. See the GNU General Public License 17 | -- for more details. 18 | -- 19 | -- You should have received a copy of the GNU General 20 | -- Public License along with robotron-fpga. If not, see 21 | -- . 22 | -- 23 | ----------------------------------------------------------------------- 24 | 25 | library ieee; 26 | use ieee.std_logic_1164.all; 27 | 28 | entity led_decoder is 29 | port( 30 | input : in std_logic_vector (3 downto 0); 31 | output : out std_logic_vector (6 downto 0) 32 | ); 33 | end led_decoder; 34 | 35 | architecture rtl of led_decoder is 36 | 37 | begin 38 | 39 | with input select 40 | output <= "1111001" when "0001", --1 41 | "0100100" when "0010", --2 42 | "0110000" when "0011", --3 43 | "0011001" when "0100", --4 44 | "0010010" when "0101", --5 45 | "0000010" when "0110", --6 46 | "1111000" when "0111", --7 47 | "0000000" when "1000", --8 48 | "0010000" when "1001", --9 49 | "0001000" when "1010", --A 50 | "0000011" when "1011", --b 51 | "1000110" when "1100", --C 52 | "0100001" when "1101", --d 53 | "0000110" when "1110", --E 54 | "0001110" when "1111", --F 55 | "1000000" when others; --0 56 | 57 | end architecture rtl; 58 | -------------------------------------------------------------------------------- /hdl/robotron_cpu/mc6821.vhd: -------------------------------------------------------------------------------- 1 | ----------------------------------------------------------------------- 2 | -- 3 | -- Copyright 2012 ShareBrained Technology, Inc. 4 | -- 5 | -- This file is part of robotron-fpga. 6 | -- 7 | -- robotron-fpga is free software: you can redistribute 8 | -- it and/or modify it under the terms of the GNU General 9 | -- Public License as published by the Free Software 10 | -- Foundation, either version 3 of the License, or (at your 11 | -- option) any later version. 12 | -- 13 | -- robotron-fpga is distributed in the hope that it will 14 | -- be useful, but WITHOUT ANY WARRANTY; without even the 15 | -- implied warranty of MERCHANTABILITY or FITNESS FOR A 16 | -- PARTICULAR PURPOSE. See the GNU General Public License 17 | -- for more details. 18 | -- 19 | -- You should have received a copy of the GNU General 20 | -- Public License along with robotron-fpga. If not, see 21 | -- . 22 | -- 23 | ----------------------------------------------------------------------- 24 | 25 | library ieee; 26 | use ieee.std_logic_1164.all; 27 | use ieee.numeric_std.all; 28 | 29 | entity mc6821 is 30 | port( 31 | reset : in std_logic; 32 | clock : in std_logic; 33 | e_sync : in std_logic; 34 | 35 | rs : in std_logic_vector(1 downto 0); 36 | cs : in std_logic; 37 | write : in std_logic; 38 | 39 | data_in : in std_logic_vector(7 downto 0); 40 | data_out : out std_logic_vector(7 downto 0); 41 | 42 | ca1 : in std_logic; 43 | ca2_in : in std_logic; 44 | ca2_out : out std_logic; 45 | ca2_dir : out std_logic; 46 | irq_a : out std_logic; 47 | pa_in : in std_logic_vector(7 downto 0); 48 | pa_out : out std_logic_vector(7 downto 0); 49 | pa_dir : out std_logic_vector(7 downto 0); 50 | 51 | cb1 : in std_logic; 52 | cb2_in : in std_logic; 53 | cb2_out : out std_logic; 54 | cb2_dir : out std_logic; 55 | irq_b : out std_logic; 56 | pb_in : in std_logic_vector(7 downto 0); 57 | pb_out : out std_logic_vector(7 downto 0); 58 | pb_dir : out std_logic_vector(7 downto 0) 59 | ); 60 | end mc6821; 61 | 62 | architecture Behavioral of mc6821 is 63 | signal read : std_logic := '0'; 64 | 65 | signal ca1_q : std_logic := '0'; 66 | signal ca2_q : std_logic := '0'; 67 | signal cb1_q : std_logic := '0'; 68 | signal cb2_q : std_logic := '0'; 69 | 70 | signal output_a : std_logic_vector(7 downto 0) := (others => '0'); 71 | signal ddr_a : std_logic_vector(7 downto 0) := (others => '0'); 72 | 73 | signal cr_a : std_logic_vector(7 downto 0) := (others => '0'); 74 | signal irqa_1_intf : std_logic := '0'; 75 | signal irqa_2_intf : std_logic := '0'; 76 | signal ca2_is_output : std_logic := '0'; 77 | signal cr_a_4 : std_logic := '0'; 78 | signal cr_a_3 : std_logic := '0'; 79 | signal output_a_access : std_logic := '0'; 80 | signal ca1_edge : std_logic := '0'; 81 | signal ca2_edge : std_logic := '0'; 82 | signal ca1_int_en : std_logic := '0'; 83 | signal ca2_int_en : std_logic := '0'; 84 | signal ca2_in_gated : std_logic := '0'; 85 | signal ca2_out_value : std_logic := '0'; 86 | 87 | signal output_b : std_logic_vector(7 downto 0) := (others => '0'); 88 | signal ddr_b : std_logic_vector(7 downto 0) := (others => '0'); 89 | 90 | signal cr_b : std_logic_vector(7 downto 0) := (others => '0'); 91 | signal irqb_1_intf : std_logic := '0'; 92 | signal irqb_2_intf : std_logic := '0'; 93 | signal cb2_is_output : std_logic := '0'; 94 | signal cr_b_4 : std_logic := '0'; 95 | signal cr_b_3 : std_logic := '0'; 96 | signal output_b_access : std_logic := '0'; 97 | signal cb1_edge : std_logic := '0'; 98 | signal cb2_edge : std_logic := '0'; 99 | signal cb1_int_en : std_logic := '0'; 100 | signal cb2_int_en : std_logic := '0'; 101 | signal cb2_in_gated : std_logic := '0'; 102 | signal cb2_out_value : std_logic := '0'; 103 | 104 | begin 105 | 106 | irq_a <= ((irqa_1_intf and ca1_int_en) or 107 | (irqa_2_intf and ca2_int_en)); 108 | irq_b <= ((irqb_1_intf and cb1_int_en) or 109 | (irqb_2_intf and cb2_int_en)); 110 | 111 | ca2_out <= ca2_out_value; 112 | ca2_dir <= ca2_is_output; 113 | 114 | cb2_out <= cb2_out_value; 115 | cb2_dir <= cb2_is_output; 116 | 117 | read <= not write; 118 | 119 | pa_out <= output_a; 120 | pa_dir <= ddr_a; 121 | 122 | pb_out <= output_b; 123 | pb_dir <= ddr_b; 124 | 125 | cr_a <= irqa_1_intf & irqa_2_intf & ca2_is_output & 126 | cr_a_4 & cr_a_3 & 127 | output_a_access & ca1_edge & ca1_int_en; 128 | cr_b <= irqb_1_intf & irqb_2_intf & cb2_is_output & 129 | cr_b_4 & cr_b_3 & 130 | output_b_access & cb1_edge & cb1_int_en; 131 | 132 | -- TODO: Port B reads from output data register, not from pin state. 133 | 134 | data_out <= pa_in when rs = "00" and output_a_access = '1' else 135 | ddr_a when rs = "00" and output_a_access = '0' else 136 | cr_a when rs = "01" else 137 | pb_in when rs = "10" and output_b_access = '1' else 138 | ddr_b when rs = "10" and output_b_access = '0' else 139 | cr_b when rs = "11" else 140 | (others => '0'); 141 | 142 | ca2_edge <= cr_a_4; 143 | cb2_edge <= cr_b_4; 144 | 145 | ca2_int_en <= cr_a_3 and (not ca2_is_output); 146 | cb2_int_en <= cr_b_3 and (not cb2_is_output); 147 | 148 | ------------------------------------------------------------------- 149 | -- Effects of register reads. 150 | -- See elsewhere, this is not the only place. 151 | 152 | process(clock) 153 | begin 154 | if rising_edge(clock) then 155 | if cs = '1' and read = '1' then 156 | case rs is 157 | when "00" => 158 | -- TODO: Crazy CA2 output handling 159 | --if ddr_a_access = '0' then 160 | -- if ca2_is_output = '1' and cr_a_4 = '0' then 161 | -- ca2_output <= '0'; 162 | -- end if; 163 | --end if; 164 | 165 | when "01" => 166 | -- Do nothing! 167 | 168 | when "10" => 169 | -- TODO: Crazy CB2 output handling 170 | --if ddr_b_access = '0' then 171 | -- if cb2_is_output = '1' and cr_b_4 = '0' then 172 | -- cb2_output <= '0'; 173 | -- end if; 174 | --end if; 175 | 176 | when "11" => 177 | -- Do nothing! 178 | 179 | when others => 180 | -- Do nothing! 181 | 182 | end case; 183 | end if; 184 | end if; 185 | end process; 186 | 187 | ------------------------------------------------------------------- 188 | -- Register writes. 189 | 190 | process(clock) 191 | begin 192 | if rising_edge(clock) then 193 | if cs = '1' and write = '1' then 194 | case rs is 195 | when "00" => 196 | if output_a_access = '1' then 197 | output_a <= data_in; 198 | else 199 | ddr_a <= data_in; 200 | end if; 201 | 202 | when "01" => 203 | ca2_is_output <= data_in(5); 204 | cr_a_4 <= data_in(4); 205 | cr_a_3 <= data_in(3); 206 | output_a_access <= data_in(2); 207 | ca1_edge <= data_in(1); 208 | ca1_int_en <= data_in(0); 209 | 210 | if data_in(4) = '1' and data_in(5) = '1' then 211 | ca2_out_value <= data_in(3); 212 | end if; 213 | 214 | when "10" => 215 | if output_b_access = '1' then 216 | output_b <= data_in; 217 | else 218 | ddr_b <= data_in; 219 | end if; 220 | 221 | when "11" => 222 | cb2_is_output <= data_in(5); 223 | cr_b_4 <= data_in(4); 224 | cr_b_3 <= data_in(3); 225 | output_b_access <= data_in(2); 226 | cb1_edge <= data_in(1); 227 | cb1_int_en <= data_in(0); 228 | 229 | if data_in(4) = '1' and data_in(5) = '1' then 230 | cb2_out_value <= data_in(3); 231 | end if; 232 | 233 | when others => 234 | -- Do nothing! 235 | 236 | end case; 237 | end if; 238 | end if; 239 | end process; 240 | 241 | ------------------------------------------------------------------- 242 | -- Sampling of interrupt inputs. 243 | 244 | ca2_in_gated <= ca2_in and (not ca2_is_output); 245 | cb2_in_gated <= cb2_in and (not cb2_is_output); 246 | 247 | process(clock, e_sync) 248 | begin 249 | if rising_edge(clock) and e_sync = '1' then 250 | ca1_q <= ca1; 251 | ca2_q <= ca2_in_gated; 252 | cb1_q <= cb1; 253 | cb2_q <= cb2_in_gated; 254 | end if; 255 | end process; 256 | 257 | ------------------------------------------------------------------- 258 | -- Interrupt edge detection. 259 | 260 | process(clock, e_sync) 261 | begin 262 | if rising_edge(clock) then 263 | if ((ca1_edge = '0' and ca1_q = '1' and ca1 = '0') or 264 | (ca1_edge = '1' and ca1_q = '0' and ca1 = '1')) and 265 | e_sync = '1' then 266 | irqa_1_intf <= '1'; 267 | elsif cs = '1' and read = '1' and rs = "00" and output_a_access = '1' then 268 | irqa_1_intf <= '0'; 269 | end if; 270 | end if; 271 | end process; 272 | 273 | process(clock, e_sync) 274 | begin 275 | if rising_edge(clock) then 276 | if ((ca2_edge = '0' and ca2_q = '1' and ca2_in_gated = '0') or 277 | (ca2_edge = '1' and ca2_q = '0' and ca2_in_gated = '1')) and 278 | e_sync = '1' then 279 | irqa_2_intf <= '1'; 280 | elsif cs = '1' and read = '1' and rs = "00" and output_a_access = '1' then 281 | irqa_2_intf <= '0'; 282 | end if; 283 | end if; 284 | end process; 285 | 286 | process(clock, e_sync) 287 | begin 288 | if rising_edge(clock) then 289 | if ((cb1_edge = '0' and cb1_q = '1' and cb1 = '0') or 290 | (cb1_edge = '1' and cb1_q = '0' and cb1 = '1')) and 291 | e_sync = '1' then 292 | irqb_1_intf <= '1'; 293 | elsif cs = '1' and read = '1' and rs = "00" and output_b_access = '1' then 294 | irqb_1_intf <= '0'; 295 | end if; 296 | end if; 297 | end process; 298 | 299 | process(clock, e_sync) 300 | begin 301 | if rising_edge(clock) then 302 | if ((cb2_edge = '0' and cb2_q = '1' and cb2_in_gated = '0') or 303 | (cb2_edge = '1' and cb2_q = '0' and cb2_in_gated = '1')) and 304 | e_sync = '1' then 305 | irqb_2_intf <= '1'; 306 | elsif cs = '1' and read = '1' and rs = "00" and output_b_access = '1' then 307 | irqb_2_intf <= '0'; 308 | end if; 309 | end if; 310 | end process; 311 | 312 | end Behavioral; 313 | -------------------------------------------------------------------------------- /hdl/robotron_cpu/mc6821_tb.vhd: -------------------------------------------------------------------------------- 1 | ----------------------------------------------------------------------- 2 | -- 3 | -- Copyright 2012 ShareBrained Technology, Inc. 4 | -- 5 | -- This file is part of robotron-fpga. 6 | -- 7 | -- robotron-fpga is free software: you can redistribute 8 | -- it and/or modify it under the terms of the GNU General 9 | -- Public License as published by the Free Software 10 | -- Foundation, either version 3 of the License, or (at your 11 | -- option) any later version. 12 | -- 13 | -- robotron-fpga is distributed in the hope that it will 14 | -- be useful, but WITHOUT ANY WARRANTY; without even the 15 | -- implied warranty of MERCHANTABILITY or FITNESS FOR A 16 | -- PARTICULAR PURPOSE. See the GNU General Public License 17 | -- for more details. 18 | -- 19 | -- You should have received a copy of the GNU General 20 | -- Public License along with robotron-fpga. If not, see 21 | -- . 22 | -- 23 | ----------------------------------------------------------------------- 24 | 25 | library ieee; 26 | use ieee.std_logic_1164.all; 27 | 28 | entity mc6821_tb is 29 | end mc6821_tb; 30 | 31 | architecture behavior of mc6821_tb is 32 | component mc6821 33 | port( 34 | reset : in std_logic; 35 | clock : in std_logic; 36 | e_set : in std_logic; 37 | e_clear : in std_logic; 38 | rs : in std_logic_vector(1 downto 0); 39 | cs : in std_logic; 40 | write : in std_logic; 41 | data_in : in std_logic_vector(7 downto 0); 42 | data_out : out std_logic_vector(7 downto 0); 43 | ca1 : in std_logic; 44 | ca2_in : in std_logic; 45 | ca2_out : out std_logic; 46 | ca2_dir : out std_logic; 47 | irq_a_n : out std_logic; 48 | pa_in : in std_logic_vector(7 downto 0); 49 | pa_out : out std_logic_vector(7 downto 0); 50 | pa_dir : out std_logic_vector(7 downto 0); 51 | cb1 : in std_logic; 52 | cb2_in : in std_logic; 53 | cb2_out : out std_logic; 54 | cb2_dir : out std_logic; 55 | irq_b_n : out std_logic; 56 | pb_in : in std_logic_vector(7 downto 0); 57 | pb_out : out std_logic_vector(7 downto 0); 58 | pb_dir : out std_logic_vector(7 downto 0) 59 | ); 60 | end component; 61 | 62 | signal reset : std_logic := '0'; 63 | signal clock : std_logic := '0'; 64 | signal e_set : std_logic := '0'; 65 | signal e_clear : std_logic := '0'; 66 | signal rs : std_logic_vector(1 downto 0) := (others => '0'); 67 | signal cs : std_logic := '0'; 68 | signal write : std_logic := '0'; 69 | signal data_in : std_logic_vector(7 downto 0) := (others => '0'); 70 | signal data_out : std_logic_vector(7 downto 0); 71 | signal ca1 : std_logic := '0'; 72 | signal ca2_in : std_logic := '0'; 73 | signal ca2_out : std_logic; 74 | signal ca2_dir : std_logic; 75 | signal irq_a_n : std_logic; 76 | signal pa_in : std_logic_vector(7 downto 0) := (others => '0'); 77 | signal pa_out : std_logic_vector(7 downto 0); 78 | signal pa_dir : std_logic_vector(7 downto 0); 79 | signal cb1 : std_logic := '0'; 80 | signal cb2_in : std_logic := '0'; 81 | signal cb2_out : std_logic; 82 | signal cb2_dir : std_logic; 83 | signal irq_b_n : std_logic; 84 | signal pb_in : std_logic_vector(7 downto 0) := (others => '0'); 85 | signal pb_out : std_logic_vector(7 downto 0); 86 | signal pb_dir : std_logic_vector(7 downto 0); 87 | 88 | constant clock_period : time := 83.333 ns; 89 | 90 | BEGIN 91 | 92 | uut: mc6821 93 | port map( 94 | reset => reset, 95 | clock => clock, 96 | e_set => e_set, 97 | e_clear => e_clear, 98 | rs => rs, 99 | cs => cs, 100 | write => write, 101 | data_in => data_in, 102 | data_out => data_out, 103 | ca1 => ca1, 104 | ca2_in => ca2_in, 105 | ca2_out => ca2_out, 106 | ca2_dir => ca2_dir, 107 | irq_a_n => irq_a_n, 108 | pa_in => pa_in, 109 | pa_out => pa_out, 110 | pa_dir => pa_dir, 111 | cb1 => cb1, 112 | cb2_in => cb2_in, 113 | cb2_out => cb2_out, 114 | cb2_dir => cb2_dir, 115 | irq_b_n => irq_b_n, 116 | pb_in => pb_in, 117 | pb_out => pb_out, 118 | pb_dir => pb_dir 119 | ); 120 | 121 | clock_process: process 122 | begin 123 | clock <= '0'; 124 | wait for clock_period/2; 125 | clock <= '1'; 126 | wait for clock_period/2; 127 | end process; 128 | 129 | e_process: process 130 | begin 131 | wait until rising_edge(clock); 132 | wait until rising_edge(clock); 133 | e_set <= '1'; 134 | wait until rising_edge(clock); 135 | e_set <= '0'; 136 | wait until rising_edge(clock); 137 | wait until rising_edge(clock); 138 | wait until rising_edge(clock); 139 | wait until rising_edge(clock); 140 | wait until rising_edge(clock); 141 | e_clear <= '1'; 142 | wait until rising_edge(clock); 143 | e_clear <= '0'; 144 | wait until rising_edge(clock); 145 | wait until rising_edge(clock); 146 | wait until rising_edge(clock); 147 | end process; 148 | 149 | stim_proc: process 150 | begin 151 | pb_in <= "01010101"; 152 | 153 | -- Configure CRA, with DDR register selected 154 | wait until rising_edge(e_set); 155 | rs <= "01"; 156 | cs <= '1'; 157 | data_in <= "00011011"; 158 | write <= '1'; 159 | 160 | -- Configure DDR as all outputs 161 | wait until rising_edge(e_set); 162 | rs <= "00"; 163 | cs <= '1'; 164 | data_in <= "11111111"; 165 | write <= '1'; 166 | 167 | -- Configure CRA, with output register selected 168 | wait until rising_edge(e_set); 169 | rs <= "01"; 170 | cs <= '1'; 171 | data_in <= "00011111"; 172 | write <= '1'; 173 | 174 | -- Configure output register value 175 | wait until rising_edge(e_set); 176 | rs <= "00"; 177 | cs <= '1'; 178 | data_in <= "10101010"; 179 | write <= '1'; 180 | 181 | -- Configure CRB, with output register selected 182 | wait until rising_edge(e_set); 183 | rs <= "11"; 184 | cs <= '1'; 185 | data_in <= "00011111"; 186 | write <= '1'; 187 | 188 | wait until rising_edge(e_set); 189 | cs <= '0'; 190 | write <= '0'; 191 | ca1 <= '1'; 192 | ca2_in <= '1'; 193 | 194 | wait until rising_edge(e_set); 195 | wait until rising_edge(e_set); 196 | rs <= "00"; 197 | cs <= '1'; 198 | write <= '0'; 199 | 200 | wait until rising_edge(e_set); 201 | cs <= '0'; 202 | 203 | wait until rising_edge(e_set); 204 | rs <= "00"; 205 | cs <= '1'; 206 | write <= '0'; 207 | 208 | wait until rising_edge(e_set); 209 | rs <= "10"; 210 | cs <= '1'; 211 | write <= '0'; 212 | 213 | wait until rising_edge(e_set); 214 | 215 | wait; 216 | end process; 217 | 218 | end; 219 | -------------------------------------------------------------------------------- /hdl/robotron_cpu/robotron_cpu_test.vhd: -------------------------------------------------------------------------------- 1 | ----------------------------------------------------------------------- 2 | -- 3 | -- Copyright 2012 ShareBrained Technology, Inc. 4 | -- 5 | -- This file is part of robotron-fpga. 6 | -- 7 | -- robotron-fpga is free software: you can redistribute 8 | -- it and/or modify it under the terms of the GNU General 9 | -- Public License as published by the Free Software 10 | -- Foundation, either version 3 of the License, or (at your 11 | -- option) any later version. 12 | -- 13 | -- robotron-fpga is distributed in the hope that it will 14 | -- be useful, but WITHOUT ANY WARRANTY; without even the 15 | -- implied warranty of MERCHANTABILITY or FITNESS FOR A 16 | -- PARTICULAR PURPOSE. See the GNU General Public License 17 | -- for more details. 18 | -- 19 | -- You should have received a copy of the GNU General 20 | -- Public License along with robotron-fpga. If not, see 21 | -- . 22 | -- 23 | ----------------------------------------------------------------------- 24 | 25 | library ieee; 26 | use ieee.std_logic_1164.all; 27 | use ieee.numeric_std.all; 28 | 29 | entity robotron_cpu_test is 30 | end robotron_cpu_test; 31 | 32 | architecture behavior of robotron_cpu_test is 33 | 34 | component robotron_cpu 35 | port( 36 | CLK : in std_logic; 37 | 38 | -- MC6809E interface 39 | A : in std_logic_vector(15 downto 0); 40 | D : inout std_logic_vector(7 downto 0); 41 | RESET_N : out std_logic; 42 | NMI_N : out std_logic; 43 | FIRQ_N : out std_logic; 44 | IRQ_N : out std_logic; 45 | LIC : in std_logic; 46 | AVMA : in std_logic; 47 | R_W_N : in std_logic; 48 | TSC : out std_logic; 49 | HALT_N : out std_logic; 50 | BA : in std_logic; 51 | BS : in std_logic; 52 | BUSY : in std_logic; 53 | E : out std_logic; 54 | Q : out std_logic; 55 | 56 | -- RAM and flash memories 57 | MemOE : out std_logic; 58 | MemWR : out std_logic; 59 | 60 | RamAdv : out std_logic; 61 | RamCS : out std_logic; 62 | RamClk : out std_logic; 63 | RamCRE : out std_logic; 64 | RamLB : out std_logic; 65 | RamUB : out std_logic; 66 | RamWait : in std_logic; 67 | 68 | FlashRp : out std_logic; 69 | FlashCS : out std_logic; 70 | FlashStSts : in std_logic; 71 | 72 | MemAdr : out std_logic_vector(23 downto 1); 73 | MemDB : inout std_logic_vector(15 downto 0); 74 | 75 | -- 7-segment display 76 | SEG : out std_logic_vector(6 downto 0); 77 | DP : out std_logic; 78 | AN : out std_logic_vector(3 downto 0); 79 | 80 | -- LEDs 81 | LED : out std_logic_vector(7 downto 0); 82 | 83 | -- Switches 84 | SW : in std_logic_vector(7 downto 0); 85 | 86 | -- Buttons 87 | BTN : in std_logic_vector(3 downto 0); 88 | 89 | -- VGA 90 | vgaRed : out std_logic_vector(2 downto 0); 91 | vgaGreen : out std_logic_vector(2 downto 0); 92 | vgaBlue : out std_logic_vector(1 downto 0); 93 | Hsync : out std_logic; 94 | Vsync : out std_logic 95 | ); 96 | end component; 97 | 98 | constant CLK_frequency : real := 48.0e6; 99 | constant CLK_period : time := 1 sec / CLK_frequency; 100 | 101 | signal CLK : std_logic := '0'; 102 | 103 | signal A : std_logic_vector(15 downto 0) := (others => '0'); 104 | signal D : std_logic_vector(7 downto 0); 105 | signal RESET_N : std_logic := '1'; 106 | signal NMI_N : std_logic := '1'; 107 | signal FIRQ_N : std_logic := '1'; 108 | signal IRQ_N : std_logic := '1'; 109 | signal LIC : std_logic := '0'; 110 | signal AVMA : std_logic := '0'; 111 | signal R_W_N : std_logic := '0'; 112 | signal TSC : std_logic := '0'; 113 | signal HALT_N : std_logic := '1'; 114 | signal BA : std_logic := '0'; 115 | signal BS : std_logic := '0'; 116 | signal BUSY : std_logic := '0'; 117 | signal E : std_logic := '0'; 118 | signal Q : std_logic := '0'; 119 | 120 | signal MemOE : std_logic; 121 | signal MemWR : std_logic; 122 | 123 | signal RamAdv : std_logic; 124 | signal RamCS : std_logic; 125 | signal RamClk : std_logic; 126 | signal RamCRE : std_logic; 127 | signal RamLB : std_logic; 128 | signal RamUB : std_logic; 129 | signal RamWait : std_logic; 130 | 131 | signal FlashRp : std_logic; 132 | signal FlashCS : std_logic; 133 | signal FlashStSts : std_logic; 134 | 135 | signal MemAdr : std_logic_vector(23 downto 1); 136 | signal MemDB : std_logic_vector(15 downto 0); 137 | 138 | signal SEG : std_logic_vector(6 downto 0); 139 | signal DP : std_logic; 140 | signal AN : std_logic_vector(3 downto 0); 141 | 142 | signal LED : std_logic_vector(7 downto 0); 143 | 144 | signal SW : std_logic_vector(7 downto 0) := (others => '0'); 145 | 146 | signal BTN : std_logic_vector(3 downto 0) := (others => '0'); 147 | 148 | signal vgaRed : std_logic_vector(2 downto 0); 149 | signal vgaGreen : std_logic_vector(2 downto 0); 150 | signal vgaBlue : std_logic_vector(1 downto 0); 151 | signal Hsync : std_logic; 152 | signal Vsync : std_logic; 153 | 154 | ------------------------------------------------------------------- 155 | 156 | signal bus_address : std_logic_vector(15 downto 0) := (others => '1'); 157 | signal bus_read : std_logic := '1'; 158 | signal bus_data : std_logic_vector(7 downto 0) := (others => 'Z'); 159 | signal bus_available: std_logic := 'Z'; 160 | signal bus_status : std_logic := 'Z'; 161 | 162 | begin 163 | 164 | uut: robotron_cpu PORT MAP ( 165 | CLK => CLK, 166 | A => A, 167 | D => D, 168 | RESET_N => RESET_N, 169 | NMI_N => NMI_N, 170 | FIRQ_N => FIRQ_N, 171 | IRQ_N => IRQ_N, 172 | LIC => LIC, 173 | AVMA => AVMA, 174 | R_W_N => R_W_N, 175 | TSC => TSC, 176 | HALT_N => HALT_N, 177 | BA => BA, 178 | BS => BS, 179 | BUSY => BUSY, 180 | E => E, 181 | Q => Q, 182 | MemOE => MemOE, 183 | MemWR => MemWR, 184 | RamAdv => RamAdv, 185 | RamCS => RamCS, 186 | RamClk => RamClk, 187 | RamCRE => RamCRE, 188 | RamLB => RamLB, 189 | RamUB => RamUB, 190 | RamWait => RamWait, 191 | FlashRp => FlashRp, 192 | FlashCS => FlashCS, 193 | FlashStSts => FlashStSts, 194 | MemAdr => MemAdr, 195 | MemDB => MemDB, 196 | SEG => SEG, 197 | DP => DP, 198 | AN => AN, 199 | LED => LED, 200 | SW => SW, 201 | BTN => BTN, 202 | vgaRed => vgaRed, 203 | vgaGreen => vgaGreen, 204 | vgaBlue => vgaBlue, 205 | Hsync => Hsync, 206 | Vsync => Vsync 207 | ); 208 | 209 | CLK_process :process 210 | begin 211 | CLK <= '0'; 212 | wait for CLK_period/2; 213 | CLK <= '1'; 214 | wait for CLK_period/2; 215 | end process; 216 | 217 | bus_process: process 218 | begin 219 | wait until falling_edge(E); 220 | 221 | -- E=0 + 0 ns 222 | wait for 20 ns; 223 | R_W_N <= 'U'; 224 | A <= (others => 'U'); 225 | BA <= 'U'; 226 | BS <= 'U'; 227 | 228 | -- E=0 + 20 ns 229 | wait for 10 ns; 230 | D <= (others => 'Z'); 231 | 232 | -- E=0 + 30 ns 233 | wait for 170 ns; 234 | 235 | if bus_available = '0' then 236 | R_W_N <= bus_read; 237 | A <= bus_address; 238 | else 239 | R_W_N <= 'Z'; 240 | A <= (others => 'Z'); 241 | end if; 242 | 243 | BA <= bus_available; 244 | BS <= bus_status; 245 | 246 | -- E=0 + 200 ns 247 | wait until rising_edge(Q); 248 | 249 | -- Q=1 250 | wait for 200 ns; 251 | 252 | -- Q=1 + 200 ns 253 | if bus_available = '0' then 254 | if bus_read = '0' then 255 | D <= bus_data; 256 | end if; 257 | end if; 258 | end process; 259 | 260 | stim_proc: process 261 | begin 262 | BTN(0) <= '1'; 263 | wait for 100 ns; 264 | BTN(0) <= '0'; 265 | 266 | wait until rising_edge(RESET_N); 267 | 268 | wait until falling_edge(E); 269 | bus_available <= '0'; 270 | bus_status <= '0'; 271 | 272 | bus_address <= X"FFFE"; 273 | bus_read <= '1'; 274 | bus_data <= (others => 'Z'); 275 | 276 | wait until falling_edge(E); 277 | bus_address <= X"9000"; 278 | bus_read <= '1'; 279 | bus_data <= (others => 'Z'); 280 | 281 | wait until falling_edge(E); 282 | bus_address <= X"0000"; 283 | bus_read <= '0'; 284 | bus_data <= X"69"; 285 | 286 | -- Turn on ROM PIA CA2 287 | wait until falling_edge(E); 288 | bus_address <= X"C80D"; 289 | bus_read <= '0'; 290 | bus_data <= X"3C"; 291 | 292 | -- IDLE 293 | wait until falling_edge(E); 294 | bus_address <= (others => 'Z'); 295 | bus_read <= '1'; 296 | bus_data <= (others => 'Z'); 297 | 298 | -- Turn off ROM PIA CA2 299 | wait until falling_edge(E); 300 | bus_address <= X"C80D"; 301 | bus_read <= '0'; 302 | bus_data <= X"34"; 303 | 304 | -- Write BLT 305 | wait until falling_edge(E); 306 | bus_address <= X"CA02"; 307 | bus_read <= '0'; 308 | bus_data <= X"D0"; 309 | 310 | wait until falling_edge(E); 311 | bus_address <= X"CA03"; 312 | bus_read <= '0'; 313 | bus_data <= X"00"; 314 | 315 | wait until falling_edge(E); 316 | bus_address <= X"CA04"; 317 | bus_read <= '0'; 318 | bus_data <= X"33"; 319 | 320 | wait until falling_edge(E); 321 | bus_address <= X"CA05"; 322 | bus_read <= '0'; 323 | bus_data <= X"44"; 324 | 325 | wait until falling_edge(E); 326 | bus_address <= X"CA06"; 327 | bus_read <= '0'; 328 | bus_data <= X"00"; 329 | 330 | wait until falling_edge(E); 331 | bus_address <= X"CA07"; 332 | bus_read <= '0'; 333 | bus_data <= X"00"; 334 | 335 | wait until falling_edge(E); 336 | bus_address <= X"CA00"; 337 | bus_read <= '0'; 338 | bus_data <= X"01"; 339 | 340 | -- IDLE 341 | wait until falling_edge(E); 342 | bus_address <= (others => 'Z'); 343 | bus_read <= '1'; 344 | bus_data <= (others => 'Z'); 345 | 346 | -- HALT should assert from BLT. 347 | wait until falling_edge(E); 348 | wait until falling_edge(E); 349 | 350 | wait until falling_edge(E); 351 | -- Release bus to BLT. 352 | bus_status <= '1'; 353 | bus_available <= '1'; 354 | 355 | -- HALT should deassert from BLT. 356 | wait until falling_edge(E); 357 | wait until falling_edge(E); 358 | wait until falling_edge(E); 359 | 360 | wait; 361 | end process; 362 | 363 | end; 364 | -------------------------------------------------------------------------------- /hdl/robotron_cpu/sc1.vhd: -------------------------------------------------------------------------------- 1 | ----------------------------------------------------------------------- 2 | -- 3 | -- Copyright 2012 ShareBrained Technology, Inc. 4 | -- 5 | -- This file is part of robotron-fpga. 6 | -- 7 | -- robotron-fpga is free software: you can redistribute 8 | -- it and/or modify it under the terms of the GNU General 9 | -- Public License as published by the Free Software 10 | -- Foundation, either version 3 of the License, or (at your 11 | -- option) any later version. 12 | -- 13 | -- robotron-fpga is distributed in the hope that it will 14 | -- be useful, but WITHOUT ANY WARRANTY; without even the 15 | -- implied warranty of MERCHANTABILITY or FITNESS FOR A 16 | -- PARTICULAR PURPOSE. See the GNU General Public License 17 | -- for more details. 18 | -- 19 | -- You should have received a copy of the GNU General 20 | -- Public License along with robotron-fpga. If not, see 21 | -- . 22 | -- 23 | ----------------------------------------------------------------------- 24 | 25 | -- This entity models a pair of Williams SC1 pixel BLTter ICs. 26 | -- The interface is modified to be more conducive to synchronous 27 | -- FPGA implementation. 28 | 29 | library ieee; 30 | use ieee.std_logic_1164.all; 31 | use ieee.numeric_std.all; 32 | 33 | entity sc1 is 34 | port( 35 | clk : in std_logic; 36 | reset : in std_logic; 37 | e_sync : in std_logic; 38 | 39 | reg_cs : in std_logic; 40 | reg_data_in : in std_logic_vector(7 downto 0); 41 | rs : in std_logic_vector(2 downto 0); 42 | 43 | halt : out boolean; 44 | halt_ack : in boolean; 45 | 46 | blt_ack : in std_logic; 47 | 48 | read : out boolean; 49 | write : out boolean; 50 | 51 | blt_address_out : out std_logic_vector(15 downto 0); 52 | blt_data_in : in std_logic_vector(7 downto 0); 53 | blt_data_out : out std_logic_vector(7 downto 0); 54 | 55 | en_upper : out boolean; 56 | en_lower : out boolean 57 | ); 58 | end sc1; 59 | 60 | architecture Behavioral of sc1 is 61 | 62 | type state_t is (state_idle, state_wait_for_halt, state_src, state_dst); 63 | 64 | -- 0: Run register 65 | signal span_src : boolean := false; 66 | signal span_dst : boolean := false; 67 | signal synchronize_e : std_logic := '0'; 68 | signal zero_write_suppress : boolean := false; 69 | signal constant_substitution : boolean := false; 70 | signal shift_right : std_logic := '0'; 71 | signal suppress_lower : boolean := false; 72 | signal suppress_upper : boolean := false; 73 | 74 | -- 1: constant substitution value 75 | signal constant_value : std_logic_vector(7 downto 0) := (others => '1'); 76 | 77 | -- 2, 3: source address 78 | signal src_base : unsigned(15 downto 0) := (others => '0'); 79 | 80 | -- 4, 5: destination address 81 | signal dst_base : unsigned(15 downto 0) := (others => '0'); 82 | 83 | -- 6: width 84 | signal width : unsigned(8 downto 0) := (others => '0'); 85 | 86 | -- 7: height 87 | signal height : unsigned(8 downto 0) := (others => '0'); 88 | 89 | -- Internal 90 | signal state : state_t := state_idle; 91 | 92 | signal blt_src_data : std_logic_vector(7 downto 0) := (others => '0'); 93 | 94 | signal src_address : unsigned(15 downto 0) := (others => '0'); 95 | signal dst_address : unsigned(15 downto 0) := (others => '0'); 96 | 97 | signal x_count : unsigned(8 downto 0) := (others => '0'); 98 | signal x_count_next : unsigned(8 downto 0) := (others => '0'); 99 | signal y_count : unsigned(8 downto 0) := (others => '0'); 100 | signal y_count_next : unsigned(8 downto 0) := (others => '0'); 101 | 102 | begin 103 | 104 | halt <= not (state = state_idle); 105 | 106 | blt_address_out <= std_logic_vector(dst_address) when state = state_dst else 107 | std_logic_vector(src_address); 108 | read <= (state = state_src); 109 | write <= (state = state_dst); 110 | 111 | en_upper <= (state = state_src) or 112 | (not (suppress_upper or 113 | (zero_write_suppress and blt_src_data(7 downto 4) = "0000") 114 | )); 115 | en_lower <= (state = state_src) or 116 | (not (suppress_lower or 117 | (zero_write_suppress and blt_src_data(3 downto 0) = "0000") 118 | )); 119 | 120 | blt_data_out <= constant_value when constant_substitution else 121 | blt_src_data; 122 | 123 | x_count_next <= x_count + 1; 124 | y_count_next <= y_count + 1; 125 | 126 | process(clk) 127 | begin 128 | if rising_edge(clk) then 129 | case state is 130 | when state_idle => 131 | if reg_cs = '1' then 132 | case rs is 133 | when "000" => -- 0: Start BLT with attributes 134 | suppress_upper <= reg_data_in(7) = '1'; 135 | suppress_lower <= reg_data_in(6) = '1'; 136 | shift_right <= reg_data_in(5); 137 | constant_substitution <= reg_data_in(4) = '1'; 138 | zero_write_suppress <= reg_data_in(3) = '1'; 139 | synchronize_e <= reg_data_in(2); 140 | span_dst <= reg_data_in(1) = '1'; 141 | span_src <= reg_data_in(0) = '1'; 142 | 143 | state <= state_wait_for_halt; 144 | 145 | when "001" => -- 1: mask 146 | constant_value <= reg_data_in; 147 | 148 | when "010" => -- 2: source address (high) 149 | src_base(15 downto 8) <= unsigned(reg_data_in); 150 | 151 | when "011" => -- 3: source address (low) 152 | src_base(7 downto 0) <= unsigned(reg_data_in); 153 | 154 | when "100" => -- 4: destination address (high) 155 | dst_base(15 downto 8) <= unsigned(reg_data_in); 156 | 157 | when "101" => -- 5: destination address (low) 158 | dst_base(7 downto 0) <= unsigned(reg_data_in); 159 | 160 | when "110" => -- 6: width 161 | width <= '0' & unsigned(reg_data_in xor "00000100"); 162 | 163 | when "111" => -- 7: height 164 | height <= '0' & unsigned(reg_data_in xor "00000100"); 165 | 166 | when others => 167 | -- Do nothing. 168 | 169 | end case; 170 | end if; 171 | 172 | when state_wait_for_halt => 173 | if halt_ack then 174 | src_address <= src_base; 175 | dst_address <= dst_base; 176 | 177 | -- TODO: Handle width or height = 0? 178 | x_count <= (others => '0'); 179 | y_count <= (others => '0'); 180 | 181 | state <= state_src; 182 | end if; 183 | 184 | when state_src => 185 | if blt_ack = '1' then 186 | blt_src_data <= blt_data_in; 187 | state <= state_dst; 188 | end if; 189 | 190 | when state_dst => 191 | if blt_ack = '1' then 192 | state <= state_src; 193 | 194 | if x_count_next = width then 195 | x_count <= (others => '0'); 196 | y_count <= y_count_next; 197 | 198 | if y_count_next = height then 199 | state <= state_idle; 200 | end if; 201 | 202 | if span_src then 203 | src_address <= src_base + resize(y_count_next, 16); 204 | else 205 | src_address <= src_address + 1; 206 | end if; 207 | 208 | if span_dst then 209 | dst_address <= dst_base + resize(y_count_next, 16); 210 | else 211 | dst_address <= dst_address + 1; 212 | end if; 213 | else 214 | x_count <= x_count_next; 215 | 216 | if span_src then 217 | src_address <= src_address + 256; 218 | else 219 | src_address <= src_address + 1; 220 | end if; 221 | 222 | if span_dst then 223 | dst_address <= dst_address + 256; 224 | else 225 | dst_address <= dst_address + 1; 226 | end if; 227 | end if; 228 | end if; 229 | 230 | when others => 231 | -- Do nothing. 232 | 233 | end case; 234 | end if; 235 | end process; 236 | 237 | end Behavioral; -------------------------------------------------------------------------------- /hdl/robotron_cpu/sc1_tb.vhd: -------------------------------------------------------------------------------- 1 | ----------------------------------------------------------------------- 2 | -- 3 | -- Copyright 2012 ShareBrained Technology, Inc. 4 | -- 5 | -- This file is part of robotron-fpga. 6 | -- 7 | -- robotron-fpga is free software: you can redistribute 8 | -- it and/or modify it under the terms of the GNU General 9 | -- Public License as published by the Free Software 10 | -- Foundation, either version 3 of the License, or (at your 11 | -- option) any later version. 12 | -- 13 | -- robotron-fpga is distributed in the hope that it will 14 | -- be useful, but WITHOUT ANY WARRANTY; without even the 15 | -- implied warranty of MERCHANTABILITY or FITNESS FOR A 16 | -- PARTICULAR PURPOSE. See the GNU General Public License 17 | -- for more details. 18 | -- 19 | -- You should have received a copy of the GNU General 20 | -- Public License along with robotron-fpga. If not, see 21 | -- . 22 | -- 23 | ----------------------------------------------------------------------- 24 | 25 | library ieee; 26 | use ieee.std_logic_1164.all; 27 | 28 | entity sc1_tb is 29 | end sc1_tb; 30 | 31 | architecture behavior of sc1_tb is 32 | 33 | component sc1 34 | port( 35 | clk : in std_logic; 36 | reset : in std_logic; 37 | e_sync : in std_logic; 38 | reg_cs : in std_logic; 39 | reg_data_in : in std_logic_vector(7 downto 0); 40 | rs : in std_logic_vector(2 downto 0); 41 | halt : out boolean; 42 | halt_ack : in boolean; 43 | blt_ack : in std_logic; 44 | blt_address_out : out std_logic_vector(15 downto 0); 45 | read : out boolean; 46 | write : out boolean; 47 | blt_data_in : in std_logic_vector(7 downto 0); 48 | blt_data_out : out std_logic_vector(7 downto 0); 49 | en_upper : out boolean; 50 | en_lower : out boolean 51 | ); 52 | end component; 53 | 54 | signal clk : std_logic := '0'; 55 | signal reset : std_logic := '0'; 56 | signal e_sync : std_logic := '0'; 57 | signal reg_cs : std_logic := '0'; 58 | signal reg_data_in : std_logic_vector(7 downto 0) := (others => '0'); 59 | signal rs : std_logic_vector(2 downto 0) := (others => '0'); 60 | signal halt : boolean := false; 61 | signal halt_ack : boolean := false; 62 | signal blt_ack : std_logic := '0'; 63 | signal blt_address_out : std_logic_vector(15 downto 0); 64 | signal read : boolean := false; 65 | signal write : boolean := false; 66 | signal blt_data_in : std_logic_vector(7 downto 0) := (others => '0'); 67 | signal blt_data_out : std_logic_vector(7 downto 0); 68 | signal en_upper : boolean; 69 | signal en_lower : boolean; 70 | 71 | constant clk_period : time := 83.333333 ns; 72 | 73 | begin 74 | 75 | uut: sc1 76 | port map( 77 | clk => clk, 78 | reset => reset, 79 | e_sync => e_sync, 80 | reg_cs => reg_cs, 81 | reg_data_in => reg_data_in, 82 | rs => rs, 83 | halt => halt, 84 | halt_ack => halt_ack, 85 | blt_ack => blt_ack, 86 | blt_address_out => blt_address_out, 87 | read => read, 88 | write => write, 89 | blt_data_in => blt_data_in, 90 | blt_data_out => blt_data_out, 91 | en_upper => en_upper, 92 | en_lower => en_lower 93 | ); 94 | 95 | clk_process: process 96 | begin 97 | clk <= '0'; 98 | wait for clk_period/2; 99 | 100 | clk <= '1'; 101 | wait for clk_period/2; 102 | end process; 103 | 104 | stim_proc: process 105 | begin 106 | e_sync <= '1'; 107 | 108 | wait until rising_edge(clk); 109 | rs <= "010"; 110 | reg_data_in <= X"11"; 111 | reg_cs <= '1'; 112 | 113 | wait until rising_edge(clk); 114 | rs <= "011"; 115 | reg_data_in <= X"22"; 116 | reg_cs <= '1'; 117 | 118 | wait until rising_edge(clk); 119 | rs <= "100"; 120 | reg_data_in <= X"33"; 121 | reg_cs <= '1'; 122 | 123 | wait until rising_edge(clk); 124 | rs <= "101"; 125 | reg_data_in <= X"44"; 126 | reg_cs <= '1'; 127 | 128 | wait until rising_edge(clk); 129 | rs <= "110"; 130 | reg_data_in <= X"00"; 131 | reg_cs <= '1'; 132 | 133 | wait until rising_edge(clk); 134 | rs <= "111"; 135 | reg_data_in <= X"00"; 136 | reg_cs <= '1'; 137 | 138 | wait until rising_edge(clk); 139 | rs <= "000"; 140 | reg_data_in <= "00000001"; 141 | reg_cs <= '1'; 142 | 143 | wait until rising_edge(clk); 144 | reg_cs <= '0'; 145 | 146 | wait until halt = true; 147 | halt_ack <= true; 148 | 149 | wait until rising_edge(clk); 150 | blt_ack <= '1'; 151 | blt_data_in <= X"69"; 152 | 153 | wait until halt = false; 154 | blt_ack <= '0'; 155 | halt_ack <= false; 156 | 157 | wait; 158 | end process; 159 | 160 | end; 161 | -------------------------------------------------------------------------------- /hdl/robotron_sound/7442.vhd: -------------------------------------------------------------------------------- 1 | ----------------------------------------------------------------------- 2 | -- 3 | -- Copyright 2009-2011 ShareBrained Technology, Inc. 4 | -- 5 | -- This file is part of robotron-fpga. 6 | -- 7 | -- robotron-fpga is free software: you can redistribute 8 | -- it and/or modify it under the terms of the GNU General 9 | -- Public License as published by the Free Software 10 | -- Foundation, either version 3 of the License, or (at your 11 | -- option) any later version. 12 | -- 13 | -- robotron-fpga is distributed in the hope that it will 14 | -- be useful, but WITHOUT ANY WARRANTY; without even the 15 | -- implied warranty of MERCHANTABILITY or FITNESS FOR A 16 | -- PARTICULAR PURPOSE. See the GNU General Public License 17 | -- for more details. 18 | -- 19 | -- You should have received a copy of the GNU General 20 | -- Public License along with robotron-fpga. If not, see 21 | -- . 22 | -- 23 | ----------------------------------------------------------------------- 24 | 25 | library IEEE; 26 | use IEEE.STD_LOGIC_1164.ALL; 27 | use IEEE.STD_LOGIC_ARITH.ALL; 28 | use IEEE.STD_LOGIC_UNSIGNED.ALL; 29 | 30 | ---- Uncomment the following library declaration if instantiating 31 | ---- any Xilinx primitives in this code. 32 | --library UNISIM; 33 | --use UNISIM.VComponents.all; 34 | 35 | entity logic7442 is 36 | Port ( input : in std_logic_vector (3 downto 0); 37 | output : out std_logic_vector (9 downto 0) 38 | ); 39 | end logic7442; 40 | 41 | architecture rtl of logic7442 is 42 | 43 | begin 44 | 45 | logic7442 : process(input) 46 | begin 47 | case input is 48 | when "0000" => 49 | output <= "1111111110"; 50 | when "0001" => 51 | output <= "1111111101"; 52 | when "0010" => 53 | output <= "1111111011"; 54 | when "0011" => 55 | output <= "1111110111"; 56 | when "0100" => 57 | output <= "1111101111"; 58 | when "0101" => 59 | output <= "1111011111"; 60 | when "0110" => 61 | output <= "1110111111"; 62 | when "0111" => 63 | output <= "1101111111"; 64 | when "1000" => 65 | output <= "1011111111"; 66 | when "1001" => 67 | output <= "0111111111"; 68 | when others => 69 | output <= "1111111111"; 70 | end case; 71 | end process; 72 | 73 | end architecture rtl; 74 | 75 | -------------------------------------------------------------------------------- /hdl/robotron_sound/board_digilent_nexys2_s3e_1200.ucf: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2009-2011 ShareBrained Technology, Inc. 3 | # 4 | # This file is part of robotron-fpga. 5 | # 6 | # robotron-fpga is free software: you can redistribute 7 | # it and/or modify it under the terms of the GNU General 8 | # Public License as published by the Free Software 9 | # Foundation, either version 3 of the License, or (at your 10 | # option) any later version. 11 | # 12 | # robotron-fpga is distributed in the hope that it will 13 | # be useful, but WITHOUT ANY WARRANTY; without even the 14 | # implied warranty of MERCHANTABILITY or FITNESS FOR A 15 | # PARTICULAR PURPOSE. See the GNU General Public License 16 | # for more details. 17 | # 18 | # You should have received a copy of the GNU General 19 | # Public License along with robotron-fpga. If not, see 20 | # . 21 | 22 | #PACE: Start of Constraints generated by PACE 23 | #PACE: Start of PACE I/O Pin Assignments 24 | NET "CLK_50M_IN" LOC = "B8" |IOSTANDARD = LVCMOS33 ; 25 | 26 | NET "DAC_OUT<0>" LOC = "L15" |IOSTANDARD = LVCMOS33 |DRIVE = 12 |SLEW = SLOW ; 27 | NET "DAC_OUT<1>" LOC = "K12" |IOSTANDARD = LVCMOS33 |DRIVE = 12 |SLEW = SLOW ; 28 | NET "DAC_OUT<2>" LOC = "L17" |IOSTANDARD = LVCMOS33 |DRIVE = 12 |SLEW = SLOW ; 29 | NET "DAC_OUT<3>" LOC = "M15" |IOSTANDARD = LVCMOS33 |DRIVE = 12 |SLEW = SLOW ; 30 | NET "DAC_OUT<4>" LOC = "K13" |IOSTANDARD = LVCMOS33 |DRIVE = 12 |SLEW = SLOW ; 31 | NET "DAC_OUT<5>" LOC = "L16" |IOSTANDARD = LVCMOS33 |DRIVE = 12 |SLEW = SLOW ; 32 | NET "DAC_OUT<6>" LOC = "M14" |IOSTANDARD = LVCMOS33 |DRIVE = 12 |SLEW = SLOW ; 33 | NET "DAC_OUT<7>" LOC = "M16" |IOSTANDARD = LVCMOS33 |DRIVE = 12 |SLEW = SLOW ; 34 | 35 | NET "PWM_OUT" LOC = "M13" |IOSTANDARD = LVCMOS33 |DRIVE = 12 |SLEW = SLOW ; 36 | 37 | NET "PB_IN<0>" LOC = "G18" |IOSTANDARD = LVCMOS33 ; 38 | NET "PB_IN<1>" LOC = "H18" |IOSTANDARD = LVCMOS33 ; 39 | NET "PB_IN<2>" LOC = "K18" |IOSTANDARD = LVCMOS33 ; 40 | NET "PB_IN<3>" LOC = "K17" |IOSTANDARD = LVCMOS33 ; 41 | NET "PB_IN<4>" LOC = "L14" |IOSTANDARD = LVCMOS33 ; 42 | NET "PB_IN<5>" LOC = "L13" |IOSTANDARD = LVCMOS33 ; 43 | NET "HAND_IN" LOC = "N17" |IOSTANDARD = LVCMOS33 ; 44 | NET "RESET_IN" LOC = "B18" |IOSTANDARD = LVCMOS33 ; 45 | NET "STROBE_IN" LOC = "D18" |IOSTANDARD = LVCMOS33 ; 46 | 47 | NET "STATUS_OUT<0>" LOC = "J14" |IOSTANDARD = LVCMOS33 |SLEW = SLOW |DRIVE = 12 ; 48 | NET "STATUS_OUT<1>" LOC = "J15" |IOSTANDARD = LVCMOS33 |SLEW = SLOW |DRIVE = 12 ; 49 | NET "STATUS_OUT<2>" LOC = "K15" |IOSTANDARD = LVCMOS33 |SLEW = SLOW |DRIVE = 12 ; 50 | NET "STATUS_OUT<3>" LOC = "K14" |IOSTANDARD = LVCMOS33 |SLEW = SLOW |DRIVE = 12 ; 51 | NET "STATUS_OUT<4>" LOC = "E16" |IOSTANDARD = LVCMOS33 |SLEW = SLOW |DRIVE = 12 ; 52 | NET "STATUS_OUT<5>" LOC = "P16" |IOSTANDARD = LVCMOS33 |SLEW = SLOW |DRIVE = 12 ; 53 | NET "STATUS_OUT<6>" LOC = "E4" |IOSTANDARD = LVCMOS33 |SLEW = SLOW |DRIVE = 12 ; 54 | NET "STATUS_OUT<7>" LOC = "P4" |IOSTANDARD = LVCMOS33 |SLEW = SLOW |DRIVE = 12 ; 55 | 56 | #PACE: Start of PACE Area Constraints 57 | #PACE: Start of PACE Prohibit Constraints 58 | #PACE: End of Constraints generated by PACE 59 | #Created by Constraints Editor (xc3s1200e-fg320-4) - 2011/08/31 60 | NET "CLK_50M_IN" TNM_NET = CLK_50M_IN; 61 | TIMESPEC TS_CLK_50M_IN = PERIOD "CLK_50M_IN" 50 MHz HIGH 50%; 62 | -------------------------------------------------------------------------------- /hdl/robotron_sound/board_xilinx_s3_400_starter_board.ucf: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2009-2011 ShareBrained Technology, Inc. 3 | # 4 | # This file is part of robotron-fpga. 5 | # 6 | # robotron-fpga is free software: you can redistribute 7 | # it and/or modify it under the terms of the GNU General 8 | # Public License as published by the Free Software 9 | # Foundation, either version 3 of the License, or (at your 10 | # option) any later version. 11 | # 12 | # robotron-fpga is distributed in the hope that it will 13 | # be useful, but WITHOUT ANY WARRANTY; without even the 14 | # implied warranty of MERCHANTABILITY or FITNESS FOR A 15 | # PARTICULAR PURPOSE. See the GNU General Public License 16 | # for more details. 17 | # 18 | # You should have received a copy of the GNU General 19 | # Public License along with robotron-fpga. If not, see 20 | # . 21 | 22 | #PACE: Start of Constraints generated by PACE 23 | 24 | #PACE: Start of PACE I/O Pin Assignments 25 | NET "CLK_50M_IN" LOC = "T9" | IOSTANDARD = LVCMOS33 ; 26 | NET "DAC_OUT<0>" LOC = "L15" | IOSTANDARD = LVCMOS33 | DRIVE = 12 | SLEW = SLOW ; 27 | NET "DAC_OUT<1>" LOC = "K16" | IOSTANDARD = LVCMOS33 | DRIVE = 12 | SLEW = SLOW ; 28 | NET "DAC_OUT<2>" LOC = "H16" | IOSTANDARD = LVCMOS33 | DRIVE = 12 | SLEW = SLOW ; 29 | NET "DAC_OUT<3>" LOC = "G16" | IOSTANDARD = LVCMOS33 | DRIVE = 12 | SLEW = SLOW ; 30 | NET "DAC_OUT<4>" LOC = "F15" | IOSTANDARD = LVCMOS33 | DRIVE = 12 | SLEW = SLOW ; 31 | NET "DAC_OUT<5>" LOC = "E15" | IOSTANDARD = LVCMOS33 | DRIVE = 12 | SLEW = SLOW ; 32 | NET "DAC_OUT<6>" LOC = "D15" | IOSTANDARD = LVCMOS33 | DRIVE = 12 | SLEW = SLOW ; 33 | NET "DAC_OUT<7>" LOC = "C15" | IOSTANDARD = LVCMOS33 | DRIVE = 12 | SLEW = SLOW ; 34 | NET "BIT_OUT" LOC = "C16" | IOSTANDARD = LVCMOS33 | DRIVE = 12 | SLEW = SLOW ; 35 | NET "PB_IN<0>" LOC = "F12" | IOSTANDARD = LVCMOS33 ; 36 | NET "PB_IN<1>" LOC = "G12" | IOSTANDARD = LVCMOS33 ; 37 | NET "PB_IN<2>" LOC = "H14" | IOSTANDARD = LVCMOS33 ; 38 | NET "PB_IN<3>" LOC = "H13" | IOSTANDARD = LVCMOS33 ; 39 | NET "PB_IN<4>" LOC = "J14" | IOSTANDARD = LVCMOS33 ; 40 | NET "PB_IN<5>" LOC = "J13" | IOSTANDARD = LVCMOS33 ; 41 | NET "HAND_IN" LOC = "K14" | IOSTANDARD = LVCMOS33 ; 42 | NET "RST_IN" LOC = "M13" | IOSTANDARD = LVCMOS33 ; 43 | NET "STROBE_IN" LOC = "M14" | IOSTANDARD = LVCMOS33 ; 44 | NET "STATUS_OUT<0>" LOC = "K12" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12 ; 45 | NET "STATUS_OUT<1>" LOC = "P14" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12 ; 46 | NET "STATUS_OUT<2>" LOC = "L12" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12 ; 47 | NET "STATUS_OUT<3>" LOC = "N14" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12 ; 48 | NET "STATUS_OUT<4>" LOC = "P13" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12 ; 49 | NET "STATUS_OUT<5>" LOC = "N12" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12 ; 50 | NET "STATUS_OUT<6>" LOC = "P12" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12 ; 51 | NET "STATUS_OUT<7>" LOC = "P11" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12 ; 52 | 53 | #PACE: Start of PACE Area Constraints 54 | 55 | #PACE: Start of PACE Prohibit Constraints 56 | 57 | #PACE: End of Constraints generated by PACE 58 | -------------------------------------------------------------------------------- /hdl/robotron_sound/m6810.vhd: -------------------------------------------------------------------------------- 1 | ----------------------------------------------------------------------- 2 | -- 3 | -- Copyright 2009-2011 ShareBrained Technology, Inc. 4 | -- 5 | -- This file is part of robotron-fpga. 6 | -- 7 | -- robotron-fpga is free software: you can redistribute 8 | -- it and/or modify it under the terms of the GNU General 9 | -- Public License as published by the Free Software 10 | -- Foundation, either version 3 of the License, or (at your 11 | -- option) any later version. 12 | -- 13 | -- robotron-fpga is distributed in the hope that it will 14 | -- be useful, but WITHOUT ANY WARRANTY; without even the 15 | -- implied warranty of MERCHANTABILITY or FITNESS FOR A 16 | -- PARTICULAR PURPOSE. See the GNU General Public License 17 | -- for more details. 18 | -- 19 | -- You should have received a copy of the GNU General 20 | -- Public License along with robotron-fpga. If not, see 21 | -- . 22 | -- 23 | ----------------------------------------------------------------------- 24 | 25 | library IEEE; 26 | use IEEE.STD_LOGIC_1164.ALL; 27 | use IEEE.NUMERIC_STD.ALL; 28 | 29 | entity m6810 is 30 | Port ( clk : in std_logic; 31 | rst : in std_logic; 32 | address : in std_logic_vector (6 downto 0); 33 | cs : in std_logic; 34 | rw : in std_logic; 35 | data_in : in std_logic_vector (7 downto 0); 36 | data_out : out std_logic_vector (7 downto 0)); 37 | end m6810; 38 | 39 | architecture rtl of m6810 is 40 | subtype word_t is std_logic_vector(7 downto 0); 41 | type memory_t is array(127 downto 0) of word_t; 42 | 43 | signal ram : memory_t; 44 | signal address_reg : std_logic_vector(6 downto 0); 45 | 46 | signal we : std_logic; 47 | begin 48 | 49 | process(clk) 50 | begin 51 | if( rising_edge(clk) ) then 52 | if( we = '1' and cs = '1' ) then 53 | ram(to_integer(unsigned(address))) <= data_in; 54 | end if; 55 | 56 | address_reg <= address; 57 | end if; 58 | end process; 59 | 60 | we <= not rw; 61 | 62 | data_out <= ram(to_integer(unsigned(address))); 63 | 64 | end architecture rtl; 65 | 66 | -------------------------------------------------------------------------------- /hdl/robotron_sound/m6810_test.vhd: -------------------------------------------------------------------------------- 1 | ----------------------------------------------------------------------- 2 | -- 3 | -- Copyright 2009-2011 ShareBrained Technology, Inc. 4 | -- 5 | -- This file is part of robotron-fpga. 6 | -- 7 | -- robotron-fpga is free software: you can redistribute 8 | -- it and/or modify it under the terms of the GNU General 9 | -- Public License as published by the Free Software 10 | -- Foundation, either version 3 of the License, or (at your 11 | -- option) any later version. 12 | -- 13 | -- robotron-fpga is distributed in the hope that it will 14 | -- be useful, but WITHOUT ANY WARRANTY; without even the 15 | -- implied warranty of MERCHANTABILITY or FITNESS FOR A 16 | -- PARTICULAR PURPOSE. See the GNU General Public License 17 | -- for more details. 18 | -- 19 | -- You should have received a copy of the GNU General 20 | -- Public License along with robotron-fpga. If not, see 21 | -- . 22 | -- 23 | ----------------------------------------------------------------------- 24 | 25 | LIBRARY ieee; 26 | USE ieee.std_logic_1164.ALL; 27 | USE ieee.std_logic_unsigned.all; 28 | USE ieee.numeric_std.ALL; 29 | 30 | entity m6810_test is 31 | end m6810_test; 32 | 33 | architecture behavior of m6810_test is 34 | 35 | -- Component Declaration for the Unit Under Test (UUT) 36 | 37 | component m6810 38 | port( 39 | clk : IN std_logic; 40 | rst : IN std_logic; 41 | address : IN std_logic_vector(6 downto 0); 42 | cs : IN std_logic; 43 | rw : IN std_logic; 44 | data_in : IN std_logic_vector(7 downto 0); 45 | data_out : OUT std_logic_vector(7 downto 0) 46 | ); 47 | end component; 48 | 49 | 50 | --Inputs 51 | signal clk : std_logic := '0'; 52 | signal rst : std_logic := '0'; 53 | signal address : std_logic_vector(6 downto 0) := (others => 'Z'); 54 | signal cs : std_logic := '0'; 55 | signal rw : std_logic := '0'; 56 | signal data_in : std_logic_vector(7 downto 0) := (others => 'Z'); 57 | 58 | --Outputs 59 | signal data_out : std_logic_vector(7 downto 0); 60 | 61 | -- Clock period definitions 62 | constant clk_period : time := (279.365 ns * 4); 63 | 64 | signal phase_1 : std_logic; 65 | signal phase_2 : std_logic; 66 | signal E : std_logic; 67 | 68 | begin 69 | 70 | clk_process: process 71 | begin 72 | clk <= '0'; 73 | wait for clk_period/2; 74 | clk <= '1'; 75 | wait for clk_period/2; 76 | end process; 77 | 78 | phase_1 <= clk; 79 | phase_2 <= not phase_1; 80 | E <= phase_2; 81 | 82 | -- Instantiate the Unit Under Test (UUT) 83 | uut: m6810 port map ( 84 | clk => clk, 85 | rst => rst, 86 | address => address, 87 | cs => cs, 88 | rw => rw, 89 | data_in => data_in, 90 | data_out => data_out 91 | ); 92 | 93 | -- Stimulus process 94 | stim_proc: process 95 | begin 96 | rw <= '1'; 97 | 98 | rst <= '1'; 99 | wait for clk_period*10; 100 | rst <= '0'; 101 | 102 | -- WRITE 103 | wait until falling_edge(E); 104 | wait for (clk_period / 2) - 160 ns; 105 | address <= "0110110"; 106 | cs <= '1'; 107 | rw <= '0'; 108 | 109 | wait until rising_edge(E); 110 | wait for 225 ns; 111 | data_in <= "01011010"; 112 | 113 | wait until falling_edge(E); 114 | wait for 20 ns; 115 | cs <= '0'; 116 | address <= "ZZZZZZZ"; 117 | rw <= '1'; 118 | wait for 10 ns; 119 | data_in <= "ZZZZZZZZ"; 120 | 121 | -- READ 122 | wait until falling_edge(E); 123 | wait for (clk_period / 2) - 160 ns; 124 | address <= "0100110"; 125 | cs <= '1'; 126 | rw <= '1'; 127 | 128 | wait until rising_edge(E); 129 | wait for (clk_period / 2) - 100 ns; 130 | -- sample data_in 131 | wait until falling_edge(E); 132 | wait for 10 ns; 133 | -- sample data_in 134 | wait for 10 ns; 135 | cs <= '0'; 136 | address <= "ZZZZZZZ"; 137 | rw <= '0'; 138 | 139 | -- READ 140 | wait until falling_edge(E); 141 | wait for (clk_period / 2) - 160 ns; 142 | address <= "0110110"; 143 | cs <= '1'; 144 | rw <= '1'; 145 | 146 | wait until rising_edge(E); 147 | wait for (clk_period / 2) - 100 ns; 148 | -- sample data_in 149 | wait until falling_edge(E); 150 | wait for 10 ns; 151 | -- sample data_in 152 | wait for 10 ns; 153 | cs <= '0'; 154 | address <= "ZZZZZZZ"; 155 | rw <= '0'; 156 | 157 | wait; 158 | end process; 159 | 160 | end; 161 | -------------------------------------------------------------------------------- /hdl/robotron_sound/pia6821.vhd: -------------------------------------------------------------------------------- 1 | --===========================================================================-- 2 | -- 3 | -- S Y N T H E Z I A B L E I/O Port C O R E 4 | -- 5 | -- www.OpenCores.Org - May 2004 6 | -- This core adheres to the GNU public license 7 | -- 8 | -- File name : pia6821.vhd 9 | -- 10 | -- Purpose : Implements 2 x 8 bit parallel I/O ports 11 | -- with programmable data direction registers 12 | -- 13 | -- Dependencies : ieee.Std_Logic_1164 14 | -- ieee.std_logic_unsigned 15 | -- 16 | -- Author : John E. Kent 17 | -- 18 | --===========================================================================---- 19 | -- 20 | -- Revision History: 21 | -- 22 | -- Date: Revision Author 23 | -- 1 May 2004 0.0 John Kent 24 | -- Initial version developed from ioport.vhd 25 | -- 26 | --===========================================================================---- 27 | -- 28 | -- Memory Map 29 | -- 30 | -- IO + $00 - Port A Data & Direction register 31 | -- IO + $01 - Port A Control register 32 | -- IO + $02 - Port B Data & Direction Direction Register 33 | -- IO + $03 - Port B Control Register 34 | -- 35 | 36 | library ieee; 37 | use ieee.std_logic_1164.all; 38 | use ieee.std_logic_unsigned.all; 39 | 40 | entity pia6821 is 41 | port ( 42 | clk : in std_logic; 43 | rst : in std_logic; 44 | cs : in std_logic; 45 | rw : in std_logic; 46 | addr : in std_logic_vector(1 downto 0); 47 | data_in : in std_logic_vector(7 downto 0); 48 | data_out : out std_logic_vector(7 downto 0); 49 | irqa : out std_logic; 50 | irqb : out std_logic; 51 | pa_i : in std_logic_vector(7 downto 0); 52 | pa_o : out std_logic_vector(7 downto 0); 53 | ca1 : in std_logic; 54 | ca2_i : in std_logic; 55 | ca2_o : out std_logic; 56 | pb_i : in std_logic_vector(7 downto 0); 57 | pb_o : out std_logic_vector(7 downto 0); 58 | cb1 : in std_logic; 59 | cb2_i : in std_logic; 60 | cb2_o : out std_logic 61 | ); 62 | end; 63 | 64 | architecture pia_arch of pia6821 is 65 | 66 | signal porta_ddr : std_logic_vector(7 downto 0); 67 | signal porta_data : std_logic_vector(7 downto 0); 68 | signal porta_ctrl : std_logic_vector(5 downto 0); 69 | signal porta_read : std_logic; 70 | 71 | signal portb_ddr : std_logic_vector(7 downto 0); 72 | signal portb_data : std_logic_vector(7 downto 0); 73 | signal portb_ctrl : std_logic_vector(5 downto 0); 74 | signal portb_read : std_logic; 75 | signal portb_write : std_logic; 76 | 77 | signal ca1_del : std_logic; 78 | signal ca1_rise : std_logic; 79 | signal ca1_fall : std_logic; 80 | signal ca1_edge : std_logic; 81 | signal irqa1 : std_logic; 82 | 83 | signal ca2_del : std_logic; 84 | signal ca2_rise : std_logic; 85 | signal ca2_fall : std_logic; 86 | signal ca2_edge : std_logic; 87 | signal irqa2 : std_logic; 88 | signal ca2_out : std_logic; 89 | 90 | signal cb1_del : std_logic; 91 | signal cb1_rise : std_logic; 92 | signal cb1_fall : std_logic; 93 | signal cb1_edge : std_logic; 94 | signal irqb1 : std_logic; 95 | 96 | signal cb2_del : std_logic; 97 | signal cb2_rise : std_logic; 98 | signal cb2_fall : std_logic; 99 | signal cb2_edge : std_logic; 100 | signal irqb2 : std_logic; 101 | signal cb2_out : std_logic; 102 | 103 | begin 104 | 105 | -------------------------------- 106 | -- 107 | -- read I/O port 108 | -- 109 | -------------------------------- 110 | 111 | pia_read : process( addr, cs, 112 | irqa1, irqa2, irqb1, irqb2, 113 | porta_ddr, portb_ddr, 114 | porta_data, portb_data, 115 | porta_ctrl, portb_ctrl, 116 | pa_i, pb_i ) 117 | variable count : integer; 118 | begin 119 | case addr is 120 | when "00" => 121 | for count in 0 to 7 loop 122 | if porta_ctrl(2) = '0' then 123 | data_out(count) <= porta_ddr(count); 124 | porta_read <= '0'; 125 | else 126 | if porta_ddr(count) = '1' then 127 | data_out(count) <= porta_data(count); 128 | else 129 | data_out(count) <= pa_i(count); 130 | end if; 131 | porta_read <= cs; 132 | end if; 133 | end loop; 134 | portb_read <= '0'; 135 | 136 | when "01" => 137 | data_out <= irqa1 & irqa2 & porta_ctrl; 138 | porta_read <= '0'; 139 | portb_read <= '0'; 140 | 141 | when "10" => 142 | for count in 0 to 7 loop 143 | if portb_ctrl(2) = '0' then 144 | data_out(count) <= portb_ddr(count); 145 | portb_read <= '0'; 146 | else 147 | if portb_ddr(count) = '1' then 148 | data_out(count) <= portb_data(count); 149 | else 150 | data_out(count) <= pb_i(count); 151 | end if; 152 | portb_read <= cs; 153 | end if; 154 | end loop; 155 | porta_read <= '0'; 156 | 157 | when "11" => 158 | data_out <= irqb1 & irqb2 & portb_ctrl; 159 | porta_read <= '0'; 160 | portb_read <= '0'; 161 | 162 | when others => 163 | data_out <= "00000000"; 164 | porta_read <= '0'; 165 | portb_read <= '0'; 166 | 167 | end case; 168 | end process; 169 | 170 | --------------------------------- 171 | -- 172 | -- Write I/O ports 173 | -- 174 | --------------------------------- 175 | 176 | pia_write : process( clk, rst, addr, cs, rw, data_in, 177 | porta_ctrl, portb_ctrl, 178 | porta_data, portb_data, 179 | porta_ctrl, portb_ctrl, 180 | porta_ddr, portb_ddr ) 181 | begin 182 | if rst = '1' then 183 | porta_ddr <= "00000000"; 184 | porta_data <= "00000000"; 185 | porta_ctrl <= "000000"; 186 | portb_ddr <= "00000000"; 187 | portb_data <= "00000000"; 188 | portb_ctrl <= "000000"; 189 | portb_write <= '0'; 190 | elsif clk'event and clk = '1' then 191 | if cs = '1' and rw = '0' then 192 | case addr is 193 | when "00" => 194 | if porta_ctrl(2) = '0' then 195 | porta_ddr <= data_in; 196 | porta_data <= porta_data; 197 | else 198 | porta_ddr <= porta_ddr; 199 | porta_data <= data_in; 200 | end if; 201 | porta_ctrl <= porta_ctrl; 202 | portb_ddr <= portb_ddr; 203 | portb_data <= portb_data; 204 | portb_ctrl <= portb_ctrl; 205 | portb_write <= '0'; 206 | when "01" => 207 | porta_ddr <= porta_ddr; 208 | porta_data <= porta_data; 209 | porta_ctrl <= data_in(5 downto 0); 210 | portb_ddr <= portb_ddr; 211 | portb_data <= portb_data; 212 | portb_ctrl <= portb_ctrl; 213 | portb_write <= '0'; 214 | when "10" => 215 | porta_ddr <= porta_ddr; 216 | porta_data <= porta_data; 217 | porta_ctrl <= porta_ctrl; 218 | if portb_ctrl(2) = '0' then 219 | portb_ddr <= data_in; 220 | portb_data <= portb_data; 221 | portb_write <= '0'; 222 | else 223 | portb_ddr <= portb_ddr; 224 | portb_data <= data_in; 225 | portb_write <= '1'; 226 | end if; 227 | portb_ctrl <= portb_ctrl; 228 | when "11" => 229 | porta_ddr <= porta_ddr; 230 | porta_data <= porta_data; 231 | porta_ctrl <= porta_ctrl; 232 | portb_ddr <= portb_ddr; 233 | portb_data <= portb_data; 234 | portb_ctrl <= data_in(5 downto 0); 235 | portb_write <= '0'; 236 | when others => 237 | porta_ddr <= porta_ddr; 238 | porta_data <= porta_data; 239 | porta_ctrl <= porta_ctrl; 240 | portb_ddr <= portb_ddr; 241 | portb_data <= portb_data; 242 | portb_ctrl <= portb_ctrl; 243 | portb_write <= '0'; 244 | end case; 245 | else 246 | porta_ddr <= porta_ddr; 247 | porta_data <= porta_data; 248 | porta_ctrl <= porta_ctrl; 249 | portb_data <= portb_data; 250 | portb_ddr <= portb_ddr; 251 | portb_ctrl <= portb_ctrl; 252 | portb_write <= '0'; 253 | end if; 254 | end if; 255 | end process; 256 | 257 | --------------------------------- 258 | -- 259 | -- direction control port a 260 | -- 261 | --------------------------------- 262 | porta_direction : process ( porta_data, porta_ddr ) 263 | variable count : integer; 264 | begin 265 | for count in 0 to 7 loop 266 | if porta_ddr(count) = '1' then 267 | pa_o(count) <= porta_data(count); 268 | else 269 | pa_o(count) <= 'Z'; 270 | end if; 271 | end loop; 272 | end process; 273 | 274 | --------------------------------- 275 | -- 276 | -- CA1 Edge detect 277 | -- 278 | --------------------------------- 279 | ca1_input : process( clk, rst, ca1, ca1_del, 280 | ca1_rise, ca1_fall, ca1_edge, 281 | irqa1, porta_ctrl, porta_read ) 282 | begin 283 | if rst = '1' then 284 | ca1_del <= '0'; 285 | ca1_rise <= '0'; 286 | ca1_fall <= '0'; 287 | ca1_edge <= '0'; 288 | irqa1 <= '0'; 289 | elsif clk'event and clk = '0' then 290 | ca1_del <= ca1; 291 | ca1_rise <= (not ca1_del) and ca1; 292 | ca1_fall <= ca1_del and (not ca1); 293 | if ca1_edge = '1' then 294 | irqa1 <= '1'; 295 | elsif porta_read = '1' then 296 | irqa1 <= '0'; 297 | else 298 | irqa1 <= irqa1; 299 | end if; 300 | end if; 301 | 302 | if porta_ctrl(1) = '0' then 303 | ca1_edge <= ca1_fall; 304 | else 305 | ca1_edge <= ca1_rise; 306 | end if; 307 | end process; 308 | 309 | --------------------------------- 310 | -- 311 | -- CA2 Edge detect 312 | -- 313 | --------------------------------- 314 | ca2_input : process( clk, rst, ca2_i, ca2_del, 315 | ca2_rise, ca2_fall, ca2_edge, 316 | irqa2, porta_ctrl, porta_read ) 317 | begin 318 | if rst = '1' then 319 | ca2_del <= '0'; 320 | ca2_rise <= '0'; 321 | ca2_fall <= '0'; 322 | ca2_edge <= '0'; 323 | irqa2 <= '0'; 324 | elsif clk'event and clk = '0' then 325 | ca2_del <= ca2_i; 326 | ca2_rise <= (not ca2_del) and ca2_i; 327 | ca2_fall <= ca2_del and (not ca2_i); 328 | if porta_ctrl(5) = '0' and ca2_edge = '1' then 329 | irqa2 <= '1'; 330 | elsif porta_read = '1' then 331 | irqa2 <= '0'; 332 | else 333 | irqa2 <= irqa2; 334 | end if; 335 | end if; 336 | 337 | if porta_ctrl(4) = '0' then 338 | ca2_edge <= ca2_fall; 339 | else 340 | ca2_edge <= ca2_rise; 341 | end if; 342 | end process; 343 | 344 | --------------------------------- 345 | -- 346 | -- CA2 output control 347 | -- 348 | --------------------------------- 349 | ca2_output : process( clk, rst, porta_ctrl, porta_read, ca1_edge, ca2_out ) 350 | begin 351 | if rst='1' then 352 | ca2_out <= '0'; 353 | elsif clk'event and clk='0' then 354 | case porta_ctrl(5 downto 3) is 355 | when "100" => -- read PA clears, CA1 edge sets 356 | if porta_read = '1' then 357 | ca2_out <= '0'; 358 | elsif ca1_edge = '1' then 359 | ca2_out <= '1'; 360 | else 361 | ca2_out <= ca2_out; 362 | end if; 363 | when "101" => -- read PA clears, E sets 364 | ca2_out <= not porta_read; 365 | when "110" => -- set low 366 | ca2_out <= '0'; 367 | when "111" => -- set high 368 | ca2_out <= '1'; 369 | when others => -- no change 370 | ca2_out <= ca2_out; 371 | end case; 372 | end if; 373 | end process; 374 | 375 | --------------------------------- 376 | -- 377 | -- CA2 direction control 378 | -- 379 | --------------------------------- 380 | ca2_direction : process( porta_ctrl, ca2_out ) 381 | begin 382 | if porta_ctrl(5) = '0' then 383 | ca2_o <= 'Z'; 384 | else 385 | ca2_o <= ca2_out; 386 | end if; 387 | end process; 388 | 389 | --------------------------------- 390 | -- 391 | -- direction control port b 392 | -- 393 | --------------------------------- 394 | portb_direction : process ( portb_data, portb_ddr ) 395 | variable count : integer; 396 | begin 397 | for count in 0 to 7 loop 398 | if portb_ddr(count) = '1' then 399 | pb_o(count) <= portb_data(count); 400 | else 401 | pb_o(count) <= 'Z'; 402 | end if; 403 | end loop; 404 | end process; 405 | 406 | --------------------------------- 407 | -- 408 | -- CB1 Edge detect 409 | -- 410 | --------------------------------- 411 | cb1_input : process( clk, rst, cb1, cb1_del, 412 | cb1_rise, cb1_fall, cb1_edge, 413 | irqb1, portb_ctrl, portb_read ) 414 | begin 415 | if rst = '1' then 416 | cb1_del <= '0'; 417 | cb1_rise <= '0'; 418 | cb1_fall <= '0'; 419 | cb1_edge <= '0'; 420 | irqb1 <= '0'; 421 | elsif clk'event and clk = '0' then 422 | cb1_del <= cb1; 423 | cb1_rise <= (not cb1_del) and cb1; 424 | cb1_fall <= cb1_del and (not cb1); 425 | if cb1_edge = '1' then 426 | irqb1 <= '1'; 427 | elsif portb_read = '1' then 428 | irqb1 <= '0'; 429 | else 430 | irqb1 <= irqb1; 431 | end if; 432 | end if; 433 | 434 | if portb_ctrl(1) = '0' then 435 | cb1_edge <= cb1_fall; 436 | else 437 | cb1_edge <= cb1_rise; 438 | end if; 439 | end process; 440 | 441 | --------------------------------- 442 | -- 443 | -- CB2 Edge detect 444 | -- 445 | --------------------------------- 446 | cb2_input : process( clk, rst, cb2_i, cb2_del, 447 | cb2_rise, cb2_fall, cb2_edge, 448 | irqb2, portb_ctrl, portb_read ) 449 | begin 450 | if rst = '1' then 451 | cb2_del <= '0'; 452 | cb2_rise <= '0'; 453 | cb2_fall <= '0'; 454 | cb2_edge <= '0'; 455 | irqb2 <= '0'; 456 | elsif clk'event and clk = '0' then 457 | cb2_del <= cb2_i; 458 | cb2_rise <= (not cb2_del) and cb2_i; 459 | cb2_fall <= cb2_del and (not cb2_i); 460 | if portb_ctrl(5) = '0' and cb2_edge = '1' then 461 | irqb2 <= '1'; 462 | elsif portb_read = '1' then 463 | irqb2 <= '0'; 464 | else 465 | irqb2 <= irqb2; 466 | end if; 467 | end if; 468 | 469 | if portb_ctrl(4) = '0' then 470 | cb2_edge <= cb2_fall; 471 | else 472 | cb2_edge <= cb2_rise; 473 | end if; 474 | 475 | end process; 476 | 477 | --------------------------------- 478 | -- 479 | -- CB2 output control 480 | -- 481 | --------------------------------- 482 | cb2_output : process( clk, rst, portb_ctrl, portb_write, cb1_edge, cb2_out ) 483 | begin 484 | if rst='1' then 485 | cb2_out <= '0'; 486 | elsif clk'event and clk='0' then 487 | case portb_ctrl(5 downto 3) is 488 | when "100" => -- write PB clears, CA1 edge sets 489 | if portb_write = '1' then 490 | cb2_out <= '0'; 491 | elsif cb1_edge = '1' then 492 | cb2_out <= '1'; 493 | else 494 | cb2_out <= cb2_out; 495 | end if; 496 | when "101" => -- write PB clears, E sets 497 | cb2_out <= not portb_write; 498 | when "110" => -- set low 499 | cb2_out <= '0'; 500 | when "111" => -- set high 501 | cb2_out <= '1'; 502 | when others => -- no change 503 | cb2_out <= cb2_out; 504 | end case; 505 | end if; 506 | end process; 507 | 508 | --------------------------------- 509 | -- 510 | -- CB2 direction control 511 | -- 512 | --------------------------------- 513 | cb2_direction : process( portb_ctrl, cb2_out ) 514 | begin 515 | if portb_ctrl(5) = '0' then 516 | cb2_o <= 'Z'; 517 | else 518 | cb2_o <= cb2_out; 519 | end if; 520 | end process; 521 | 522 | --------------------------------- 523 | -- 524 | -- IRQ control 525 | -- 526 | --------------------------------- 527 | pia_irq : process( irqa1, irqa2, irqb1, irqb2, porta_ctrl, portb_ctrl ) 528 | begin 529 | irqa <= (irqa1 and porta_ctrl(0)) or (irqa2 and porta_ctrl(3)); 530 | irqb <= (irqb1 and portb_ctrl(0)) or (irqb2 and portb_ctrl(3)); 531 | end process; 532 | 533 | end pia_arch; 534 | 535 | -------------------------------------------------------------------------------- /hdl/robotron_sound/robotron_fpga_digilent_nexys2_s3e_1200.xise: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |

5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 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 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | -------------------------------------------------------------------------------- /hdl/robotron_sound/robotron_fpga_xilinx_s3_400_starter_board.xise: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 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 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 |
361 | -------------------------------------------------------------------------------- /hdl/robotron_sound/robotron_sound.vhd: -------------------------------------------------------------------------------- 1 | ----------------------------------------------------------------------- 2 | -- 3 | -- Copyright 2009-2013 ShareBrained Technology, Inc. 4 | -- 5 | -- This file is part of robotron-fpga. 6 | -- 7 | -- robotron-fpga is free software: you can redistribute 8 | -- it and/or modify it under the terms of the GNU General 9 | -- Public License as published by the Free Software 10 | -- Foundation, either version 3 of the License, or (at your 11 | -- option) any later version. 12 | -- 13 | -- robotron-fpga is distributed in the hope that it will 14 | -- be useful, but WITHOUT ANY WARRANTY; without even the 15 | -- implied warranty of MERCHANTABILITY or FITNESS FOR A 16 | -- PARTICULAR PURPOSE. See the GNU General Public License 17 | -- for more details. 18 | -- 19 | -- You should have received a copy of the GNU General 20 | -- Public License along with robotron-fpga. If not, see 21 | -- . 22 | -- 23 | ----------------------------------------------------------------------- 24 | 25 | library IEEE; 26 | use IEEE.STD_LOGIC_1164.ALL; 27 | use IEEE.STD_LOGIC_ARITH.ALL; 28 | use IEEE.STD_LOGIC_UNSIGNED.ALL; 29 | 30 | entity robotron_sound is 31 | port( 32 | clk_fast : in STD_LOGIC; 33 | clk_cpu : in STD_LOGIC; 34 | reset : in STD_LOGIC; 35 | pb : in STD_LOGIC_VECTOR (5 downto 0); 36 | hand : in STD_LOGIC; 37 | dac : out STD_LOGIC_VECTOR (7 downto 0) 38 | ); 39 | end robotron_sound; 40 | 41 | architecture Behavioral of robotron_sound is 42 | 43 | component cpu68 44 | port ( clk : in std_logic; 45 | rst : in std_logic; 46 | hold : in std_logic; 47 | halt : in std_logic; 48 | irq : in std_logic; 49 | nmi : in std_logic; 50 | data_in : in std_logic_vector (7 downto 0); 51 | rw : out std_logic; 52 | vma : out std_logic; 53 | address : out std_logic_vector (15 downto 0); 54 | data_out : out std_logic_vector (7 downto 0); 55 | test_alu : out std_logic_vector (15 downto 0); 56 | test_cc : out std_logic_vector (7 downto 0) 57 | ); 58 | end component; 59 | 60 | component m6810 61 | port ( clk : in std_logic; 62 | rst : in std_logic; 63 | address : in std_logic_vector (6 downto 0); 64 | cs : in std_logic; 65 | rw : in std_logic; 66 | data_in : in std_logic_vector (7 downto 0); 67 | data_out : out std_logic_vector (7 downto 0) 68 | ); 69 | end component; 70 | 71 | component pia6821 72 | port ( clk : in std_logic; 73 | rst : in std_logic; 74 | cs : in std_logic; 75 | rw : in std_logic; 76 | ca1 : in std_logic; 77 | cb1 : in std_logic; 78 | addr : in std_logic_vector (1 downto 0); 79 | data_in : in std_logic_vector (7 downto 0); 80 | irqa : out std_logic; 81 | irqb : out std_logic; 82 | data_out : out std_logic_vector (7 downto 0); 83 | ca2_i : in std_logic; 84 | ca2_o : out std_logic; 85 | cb2_i : in std_logic; 86 | cb2_o : out std_logic; 87 | pa_i : in std_logic_vector (7 downto 0); 88 | pa_o : out std_logic_vector (7 downto 0); 89 | pb_i : in std_logic_vector (7 downto 0); 90 | pb_o : out std_logic_vector (7 downto 0) 91 | ); 92 | end component; 93 | 94 | component rom_snd 95 | port ( clk : in std_logic; 96 | rst : in std_logic; 97 | cs : in std_logic; 98 | addr : in std_logic_vector (11 downto 0); 99 | data : out std_logic_vector (7 downto 0) 100 | ); 101 | end component; 102 | 103 | component logic7442 104 | port ( input : in std_logic_vector (3 downto 0); 105 | output : out std_logic_vector (9 downto 0) 106 | ); 107 | end component; 108 | 109 | signal CPU_ADDRESS_OUT : std_logic_vector (15 downto 0); 110 | signal CPU_DATA_IN : std_logic_vector (7 downto 0); 111 | signal CPU_DATA_OUT : std_logic_vector (7 downto 0); 112 | signal CPU_RW : std_logic; 113 | signal CPU_IRQ : std_logic; 114 | signal CPU_VMA : std_logic; 115 | signal CPU_HALT : std_logic; 116 | signal CPU_HOLD : std_logic; 117 | signal CPU_NMI : std_logic; 118 | 119 | signal ROM_CS : std_logic; 120 | signal ROM_DATA_OUT : std_logic_vector (7 downto 0); 121 | 122 | signal RAM_CS : std_logic; 123 | signal RAM_RW : std_logic; 124 | signal RAM_DATA_IN : std_logic_vector (7 downto 0); 125 | signal RAM_DATA_OUT : std_logic_vector (7 downto 0); 126 | 127 | signal PIA_RW : std_logic; 128 | signal PIA_CS : std_logic; 129 | signal PIA_IRQA : std_logic; 130 | signal PIA_IRQB : std_logic; 131 | signal PIA_DATA_IN : std_logic_vector (7 downto 0); 132 | signal PIA_DATA_OUT : std_logic_vector (7 downto 0); 133 | signal PIA_CA1 : std_logic; 134 | signal PIA_CB1 : std_logic; 135 | signal PIA_CA2_I : std_logic; 136 | signal PIA_CA2_O : std_logic; 137 | signal PIA_CB2_I : std_logic; 138 | signal PIA_CB2_O : std_logic; 139 | signal PIA_PA_I : std_logic_vector (7 downto 0); 140 | signal PIA_PA_O : std_logic_vector (7 downto 0); 141 | signal PIA_PB_I : std_logic_vector (7 downto 0); 142 | signal PIA_PB_O : std_logic_vector (7 downto 0); 143 | 144 | signal BCD_DEMUX_INPUT : std_logic_vector (3 downto 0); 145 | signal BCD_DEMUX_OUTPUT : std_logic_vector (9 downto 0); 146 | 147 | signal SPEECH_CLOCK : std_logic; 148 | signal SPEECH_DATA : std_logic; 149 | 150 | begin 151 | 152 | CPU_HALT <= '0'; 153 | CPU_HOLD <= '0'; 154 | CPU_NMI <= '0'; 155 | 156 | SPEECH_CLOCK <= '0'; 157 | SPEECH_DATA <= '0'; 158 | 159 | CPU : cpu68 160 | port map (clk => clk_cpu, 161 | data_in => CPU_DATA_IN, 162 | halt => CPU_HALT, 163 | hold => CPU_HOLD, 164 | irq => CPU_IRQ, 165 | nmi => CPU_NMI, 166 | rst => reset, 167 | address => CPU_ADDRESS_OUT, 168 | data_out => CPU_DATA_OUT, 169 | rw => CPU_RW, 170 | test_alu => open, 171 | test_cc => open, 172 | vma => CPU_VMA); 173 | 174 | CPU_IRQ <= PIA_IRQA or PIA_IRQB; 175 | 176 | process (PIA_CS, PIA_DATA_OUT, RAM_CS, RAM_DATA_OUT, ROM_DATA_OUT) 177 | begin 178 | if (PIA_CS = '1') then 179 | CPU_DATA_IN <= PIA_DATA_OUT; 180 | elsif (RAM_CS = '1') then 181 | CPU_DATA_IN <= RAM_DATA_OUT; 182 | else 183 | CPU_DATA_IN <= ROM_DATA_OUT; 184 | end if; 185 | end process; 186 | 187 | RAM : m6810 188 | port map (clk => clk_cpu, 189 | rst => reset, 190 | address => CPU_ADDRESS_OUT(6 downto 0), 191 | cs => RAM_CS, 192 | rw => RAM_RW, 193 | data_in => RAM_DATA_IN, 194 | data_out => RAM_DATA_OUT); 195 | 196 | RAM_CS <= (not CPU_ADDRESS_OUT(8)) and (not CPU_ADDRESS_OUT(9)) and (not CPU_ADDRESS_OUT(10)) and (not CPU_ADDRESS_OUT(11)) 197 | and (not BCD_DEMUX_OUTPUT(8)) 198 | and CPU_VMA; 199 | RAM_RW <= CPU_RW; 200 | RAM_DATA_IN <= CPU_DATA_OUT; 201 | 202 | PIA : pia6821 203 | port map (addr => CPU_ADDRESS_OUT(1 downto 0), 204 | ca1 => PIA_CA1, 205 | cb1 => PIA_CB1, 206 | clk => clk_cpu, 207 | cs => PIA_CS, 208 | data_in => PIA_DATA_IN, 209 | rst => reset, 210 | rw => PIA_RW, 211 | data_out=> PIA_DATA_OUT, 212 | irqa => PIA_IRQA, 213 | irqb => PIA_IRQB, 214 | ca2_i => PIA_CA2_I, 215 | ca2_o => PIA_CA2_O, 216 | cb2_i => PIA_CB2_I, 217 | cb2_o => PIA_CB2_O, 218 | pa_i => PIA_PA_I, 219 | pa_o => PIA_PA_O, 220 | pb_i => PIA_PB_I, 221 | pb_o => PIA_PB_O 222 | ); 223 | 224 | PIA_CA1 <= '1'; 225 | PIA_CA2_I <= SPEECH_DATA; 226 | PIA_CB1 <= not (HAND and pb(5) and pb(4) and pb(3) and pb(2) and pb(1) and pb(0)); 227 | PIA_CB2_I <= SPEECH_CLOCK; 228 | PIA_CS <= (not (BCD_DEMUX_OUTPUT(0) and BCD_DEMUX_OUTPUT(8))) 229 | and CPU_ADDRESS_OUT(10) 230 | and CPU_VMA; 231 | PIA_DATA_IN <= CPU_DATA_OUT; 232 | PIA_RW <= CPU_RW; 233 | PIA_PA_I <= "00000000"; 234 | dac <= PIA_PA_O; 235 | PIA_PB_I(5 downto 0) <= pb(5 downto 0); 236 | PIA_PB_I(6) <= '0'; 237 | PIA_PB_I(7) <= '0'; 238 | 239 | ROM : rom_snd 240 | port map (addr => CPU_ADDRESS_OUT(11 downto 0), 241 | clk => clk_cpu, 242 | cs => ROM_CS, 243 | rst => reset, 244 | data => ROM_DATA_OUT); 245 | 246 | ROM_CS <= (not BCD_DEMUX_OUTPUT(7)) 247 | and CPU_VMA; 248 | 249 | BCD_DEMUX : logic7442 250 | port map (input => BCD_DEMUX_INPUT, 251 | output => BCD_DEMUX_OUTPUT); 252 | 253 | BCD_DEMUX_INPUT <= (not CPU_ADDRESS_OUT(15)) & CPU_ADDRESS_OUT(14 downto 12); 254 | 255 | end Behavioral; 256 | -------------------------------------------------------------------------------- /hdl/robotron_sound/robotron_sound_digilent_nexys2_s3e_1200.vhd: -------------------------------------------------------------------------------- 1 | ----------------------------------------------------------------------- 2 | -- 3 | -- Copyright 2009-2011 ShareBrained Technology, Inc. 4 | -- 5 | -- This file is part of robotron-fpga. 6 | -- 7 | -- robotron-fpga is free software: you can redistribute 8 | -- it and/or modify it under the terms of the GNU General 9 | -- Public License as published by the Free Software 10 | -- Foundation, either version 3 of the License, or (at your 11 | -- option) any later version. 12 | -- 13 | -- robotron-fpga is distributed in the hope that it will 14 | -- be useful, but WITHOUT ANY WARRANTY; without even the 15 | -- implied warranty of MERCHANTABILITY or FITNESS FOR A 16 | -- PARTICULAR PURPOSE. See the GNU General Public License 17 | -- for more details. 18 | -- 19 | -- You should have received a copy of the GNU General 20 | -- Public License along with robotron-fpga. If not, see 21 | -- . 22 | -- 23 | ----------------------------------------------------------------------- 24 | 25 | library IEEE; 26 | use IEEE.STD_LOGIC_1164.ALL; 27 | use IEEE.STD_LOGIC_ARITH.ALL; 28 | use IEEE.STD_LOGIC_UNSIGNED.ALL; 29 | 30 | entity robotron is 31 | port( 32 | CLK_50M_IN : in STD_LOGIC; 33 | RESET_IN : in STD_LOGIC; 34 | PB_IN : in STD_LOGIC_VECTOR (5 downto 0); 35 | HAND_IN : in STD_LOGIC; 36 | STROBE_IN : in STD_LOGIC; 37 | DAC_OUT : out STD_LOGIC_VECTOR (7 downto 0); 38 | STATUS_OUT : out STD_LOGIC_VECTOR (7 downto 0); 39 | PWM_OUT : out std_logic 40 | ); 41 | end robotron; 42 | 43 | architecture Behavioral of robotron is 44 | 45 | signal CLKDIV : std_logic_vector (23 downto 0); 46 | signal reset : std_logic; 47 | signal clk_fast : std_logic; 48 | signal clk_cpu : std_logic; 49 | 50 | signal pb : std_logic_vector(5 downto 0); 51 | signal hand : std_logic; 52 | 53 | signal dac : std_logic_vector(7 downto 0); 54 | 55 | component robotron_sound 56 | port( 57 | clk_fast : in STD_LOGIC; 58 | clk_cpu : in STD_LOGIC; 59 | reset : in STD_LOGIC; 60 | pb : in STD_LOGIC_VECTOR (5 downto 0); 61 | hand : in STD_LOGIC; 62 | dac : out STD_LOGIC_VECTOR (7 downto 0) 63 | ); 64 | end component; 65 | 66 | begin 67 | 68 | reset <= RESET_IN; 69 | clk_fast <= CLK_50M_IN; 70 | clk_cpu <= CLKDIV(5); 71 | 72 | sound: robotron_sound 73 | port map( 74 | clk_fast => clk_fast, 75 | clk_cpu => clk_cpu, 76 | reset => reset, 77 | pb => pb, 78 | hand => hand, 79 | dac => dac 80 | ); 81 | 82 | process (STROBE_IN, PB_IN, HAND_IN) 83 | begin 84 | if (STROBE_IN = '1') then 85 | pb <= PB_IN; 86 | hand <= HAND_IN; 87 | else 88 | pb <= "111111"; 89 | hand <= '1'; 90 | end if; 91 | end process; 92 | 93 | process (clk_fast) 94 | begin 95 | if rising_edge(clk_fast) then 96 | if (reset = '1') then 97 | CLKDIV <= "000000000000000000000000"; 98 | else 99 | CLKDIV <= CLKDIV + 1; 100 | end if; 101 | end if; 102 | end process; 103 | 104 | process (clk_fast) 105 | begin 106 | if rising_edge(clk_fast) then 107 | if CLKDIV(7 downto 0) >= dac then 108 | PWM_OUT <= '1'; 109 | else 110 | PWM_OUT <= '0'; 111 | end if; 112 | end if; 113 | end process; 114 | 115 | STATUS_OUT <= CLKDIV(23) & RESET_IN & STROBE_IN & dac(4 downto 0); 116 | 117 | DAC_OUT <= dac; 118 | 119 | end Behavioral; 120 | -------------------------------------------------------------------------------- /hdl/robotron_sound/robotron_test.vhd: -------------------------------------------------------------------------------- 1 | ----------------------------------------------------------------------- 2 | -- 3 | -- Copyright 2009-2011 ShareBrained Technology, Inc. 4 | -- 5 | -- This file is part of robotron-fpga. 6 | -- 7 | -- robotron-fpga is free software: you can redistribute 8 | -- it and/or modify it under the terms of the GNU General 9 | -- Public License as published by the Free Software 10 | -- Foundation, either version 3 of the License, or (at your 11 | -- option) any later version. 12 | -- 13 | -- robotron-fpga is distributed in the hope that it will 14 | -- be useful, but WITHOUT ANY WARRANTY; without even the 15 | -- implied warranty of MERCHANTABILITY or FITNESS FOR A 16 | -- PARTICULAR PURPOSE. See the GNU General Public License 17 | -- for more details. 18 | -- 19 | -- You should have received a copy of the GNU General 20 | -- Public License along with robotron-fpga. If not, see 21 | -- . 22 | -- 23 | ----------------------------------------------------------------------- 24 | 25 | LIBRARY ieee; 26 | USE ieee.std_logic_1164.ALL; 27 | USE ieee.std_logic_unsigned.all; 28 | USE ieee.numeric_std.ALL; 29 | use ieee.std_logic_textio.all; 30 | 31 | library std; 32 | use std.textio.all; 33 | 34 | ENTITY robotron_test IS 35 | END robotron_test; 36 | 37 | ARCHITECTURE behavior OF robotron_test IS 38 | 39 | -- Component Declaration for the Unit Under Test (UUT) 40 | 41 | COMPONENT top 42 | PORT( 43 | CLK : IN std_logic; 44 | RST : IN std_logic; 45 | PB_IN : INOUT std_logic_vector(5 downto 0); 46 | HAND_IN : INOUT std_logic; 47 | DAC_OUT : OUT std_logic_vector(7 downto 0) 48 | ); 49 | END COMPONENT; 50 | 51 | 52 | --Inputs 53 | signal CLK : std_logic := '0'; 54 | signal RST : std_logic := '0'; 55 | 56 | --BiDirs 57 | signal PB_IN : std_logic_vector(5 downto 0); 58 | signal HAND_IN : std_logic; 59 | 60 | --Outputs 61 | signal DAC_OUT : std_logic_vector(7 downto 0); 62 | 63 | constant CLK_frequency : integer := 3579545 / 4; 64 | constant CLK_period : TIME := 1000 ms / CLK_frequency; 65 | 66 | BEGIN 67 | 68 | -- Instantiate the Unit Under Test (UUT) 69 | uut: top PORT MAP ( 70 | CLK => CLK, 71 | RST => RST, 72 | PB_IN => PB_IN, 73 | HAND_IN => HAND_IN, 74 | DAC_OUT => DAC_OUT 75 | ); 76 | 77 | CLK_process :process 78 | begin 79 | CLK <= '0'; 80 | wait for CLK_period / 2; 81 | CLK <= '1'; 82 | wait for CLK_period / 2; 83 | end process; 84 | 85 | 86 | -- Stimulus process 87 | stim_proc: process 88 | begin 89 | PB_IN <= "111111"; 90 | HAND_IN <= '1'; 91 | 92 | -- hold reset state 93 | RST <= '1'; 94 | wait for CLK_period * 10; 95 | RST <= '0'; 96 | 97 | wait for 100 us; 98 | PB_IN <= "111111"; 99 | HAND_IN <= '0'; 100 | 101 | wait; 102 | end process; 103 | 104 | dac_proc: process(DAC_OUT) 105 | file dac_out_file : text is out "dac_out-111111.txt"; 106 | variable dac_out_line : line; 107 | begin 108 | if DAC_OUT'event then 109 | write(dac_out_line, now); 110 | write(dac_out_line, HT); 111 | write(dac_out_line, DAC_OUT); 112 | writeline(dac_out_file, dac_out_line); 113 | end if; 114 | end process; 115 | 116 | END; 117 | -------------------------------------------------------------------------------- /hdl/robotron_sound/rom_snd.vhd: -------------------------------------------------------------------------------- 1 | ----------------------------------------------------------------------- 2 | -- 3 | -- Copyright 2009-2011 ShareBrained Technology, Inc. 4 | -- 5 | -- This file is part of robotron-fpga. 6 | -- 7 | -- robotron-fpga is free software: you can redistribute 8 | -- it and/or modify it under the terms of the GNU General 9 | -- Public License as published by the Free Software 10 | -- Foundation, either version 3 of the License, or (at your 11 | -- option) any later version. 12 | -- 13 | -- robotron-fpga is distributed in the hope that it will 14 | -- be useful, but WITHOUT ANY WARRANTY; without even the 15 | -- implied warranty of MERCHANTABILITY or FITNESS FOR A 16 | -- PARTICULAR PURPOSE. See the GNU General Public License 17 | -- for more details. 18 | -- 19 | -- You should have received a copy of the GNU General 20 | -- Public License along with robotron-fpga. If not, see 21 | -- . 22 | -- 23 | ----------------------------------------------------------------------- 24 | 25 | library IEEE; 26 | use IEEE.STD_LOGIC_1164.ALL; 27 | use IEEE.STD_LOGIC_ARITH.ALL; 28 | library unisim; 29 | use unisim.vcomponents.all; 30 | 31 | entity rom_snd is 32 | Port ( clk : in std_logic; 33 | rst : in std_logic; 34 | cs : in std_logic; 35 | addr : in std_logic_vector (11 downto 0); 36 | data : out std_logic_vector (7 downto 0) 37 | ); 38 | end rom_snd; 39 | 40 | architecture rtl of rom_snd is 41 | 42 | signal cs0 : std_logic; 43 | signal cs1 : std_logic; 44 | signal data0 : std_logic_vector(7 downto 0); 45 | signal data1 : std_logic_vector(7 downto 0); 46 | 47 | component ROM_SND_F000 48 | Port ( clk : in std_logic; 49 | rst : in std_logic; 50 | cs : in std_logic; 51 | addr : in std_logic_vector (10 downto 0); 52 | data : out std_logic_vector (7 downto 0) 53 | ); 54 | end component; 55 | 56 | component ROM_SND_F800 57 | Port ( clk : in std_logic; 58 | rst : in std_logic; 59 | cs : in std_logic; 60 | addr : in std_logic_vector (10 downto 0); 61 | data : out std_logic_vector (7 downto 0) 62 | ); 63 | end component; 64 | 65 | begin 66 | addr_f000 : ROM_SND_F000 port map ( 67 | clk => clk, 68 | rst => rst, 69 | cs => cs0, 70 | addr => addr(10 downto 0), 71 | data => data0 72 | ); 73 | 74 | addr_f800 : ROM_SND_F800 port map ( 75 | clk => clk, 76 | rst => rst, 77 | cs => cs1, 78 | addr => addr(10 downto 0), 79 | data => data1 80 | ); 81 | 82 | rom_snd : process ( clk, addr, cs, data0, data1 ) 83 | begin 84 | case addr(11) is 85 | when '0' => 86 | cs0 <= cs; 87 | cs1 <= '0'; 88 | data <= data0; 89 | when '1' => 90 | cs0 <= '0'; 91 | cs1 <= cs; 92 | data <= data1; 93 | when others => 94 | null; 95 | end case; 96 | end process; 97 | 98 | end architecture rtl; 99 | 100 | -------------------------------------------------------------------------------- /hdl/robotron_sound/rom_test.vhd: -------------------------------------------------------------------------------- 1 | ----------------------------------------------------------------------- 2 | -- 3 | -- Copyright 2009-2011 ShareBrained Technology, Inc. 4 | -- 5 | -- This file is part of robotron-fpga. 6 | -- 7 | -- robotron-fpga is free software: you can redistribute 8 | -- it and/or modify it under the terms of the GNU General 9 | -- Public License as published by the Free Software 10 | -- Foundation, either version 3 of the License, or (at your 11 | -- option) any later version. 12 | -- 13 | -- robotron-fpga is distributed in the hope that it will 14 | -- be useful, but WITHOUT ANY WARRANTY; without even the 15 | -- implied warranty of MERCHANTABILITY or FITNESS FOR A 16 | -- PARTICULAR PURPOSE. See the GNU General Public License 17 | -- for more details. 18 | -- 19 | -- You should have received a copy of the GNU General 20 | -- Public License along with robotron-fpga. If not, see 21 | -- . 22 | -- 23 | ----------------------------------------------------------------------- 24 | 25 | LIBRARY ieee; 26 | USE ieee.std_logic_1164.ALL; 27 | USE ieee.std_logic_unsigned.all; 28 | USE ieee.numeric_std.ALL; 29 | 30 | ENTITY rom_test IS 31 | END rom_test; 32 | 33 | ARCHITECTURE behavior OF rom_test IS 34 | 35 | -- Component Declaration for the Unit Under Test (UUT) 36 | 37 | COMPONENT rom_snd 38 | PORT( 39 | clk : IN std_logic; 40 | rst : IN std_logic; 41 | cs : IN std_logic; 42 | addr : IN std_logic_vector(11 downto 0); 43 | data : OUT std_logic_vector(7 downto 0) 44 | ); 45 | END COMPONENT; 46 | 47 | --Inputs 48 | signal clk : std_logic := '0'; 49 | signal rst : std_logic := '0'; 50 | signal cs : std_logic := '0'; 51 | signal addr : std_logic_vector(11 downto 0) := (others => '0'); 52 | 53 | --Outputs 54 | signal data : std_logic_vector(7 downto 0); 55 | 56 | -- Clock period definitions 57 | constant clk_period : time := 280 ns; 58 | 59 | BEGIN 60 | 61 | -- Instantiate the Unit Under Test (UUT) 62 | uut: rom_snd PORT MAP ( 63 | clk => clk, 64 | rst => rst, 65 | cs => cs, 66 | addr => addr, 67 | data => data 68 | ); 69 | 70 | -- Clock process definitions 71 | clk_process :process 72 | begin 73 | clk <= '0'; 74 | wait for clk_period/2; 75 | clk <= '1'; 76 | wait for clk_period/2; 77 | end process; 78 | 79 | 80 | -- Stimulus process 81 | stim_proc: process 82 | begin 83 | cs <= '1'; 84 | 85 | rst <= '1'; 86 | wait for clk_period * 2; 87 | rst <= '0'; 88 | wait for clk_period * 2; 89 | 90 | -- insert stimulus here 91 | addr <= "000000000000"; 92 | wait until rising_edge(clk); 93 | 94 | addr <= "000000000001"; 95 | wait until rising_edge(clk); 96 | --assert data = "01110110" report "Address 0x000 read incorrect" severity failure; 97 | 98 | addr <= "000000000010"; 99 | wait until rising_edge(clk); 100 | --assert data = "00101000" report "Address 0x001 read incorrect" severity failure; 101 | 102 | addr <= "000000000011"; 103 | wait until rising_edge(clk); 104 | --assert data = "01000011" report "Address 0x002 read incorrect" severity failure; 105 | 106 | addr <= "011111111111"; 107 | wait until rising_edge(clk); 108 | --assert data = "00101001" report "Address 0x003 read incorrect" severity failure; 109 | 110 | addr <= "100000000000"; 111 | wait until rising_edge(clk); 112 | --assert data = "10010001" report "Address 0x7ff read incorrect" severity failure; 113 | 114 | addr <= "100000000001"; 115 | wait until rising_edge(clk); 116 | --assert data = "00000110" report "Address 0x800 read incorrect" severity failure; 117 | 118 | addr <= "100000000010"; 119 | wait until rising_edge(clk); 120 | --assert data = "00100010" report "Address 0x801 read incorrect" severity failure; 121 | 122 | addr <= "100000000011"; 123 | wait until rising_edge(clk); 124 | --assert data = "11110000" report "Address 0x802 read incorrect" severity failure; 125 | 126 | addr <= "111111111111"; 127 | wait until rising_edge(clk); 128 | --assert data = "10010110" report "Address 0x803 read incorrect" severity failure; 129 | 130 | wait until rising_edge(clk); 131 | --assert data = "00011101" report "Address 0xfff read incorrect" severity failure; 132 | 133 | wait; 134 | end process; 135 | 136 | END; 137 | -------------------------------------------------------------------------------- /tools/dac_out_wave.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # 4 | # Copyright 2009-2011 ShareBrained Technology, Inc. 5 | # 6 | # This file is part of robotron-fpga. 7 | # 8 | # robotron-fpga is free software: you can redistribute 9 | # it and/or modify it under the terms of the GNU General 10 | # Public License as published by the Free Software 11 | # Foundation, either version 3 of the License, or (at your 12 | # option) any later version. 13 | # 14 | # robotron-fpga is distributed in the hope that it will 15 | # be useful, but WITHOUT ANY WARRANTY; without even the 16 | # implied warranty of MERCHANTABILITY or FITNESS FOR A 17 | # PARTICULAR PURPOSE. See the GNU General Public License 18 | # for more details. 19 | # 20 | # You should have received a copy of the GNU General 21 | # Public License along with robotron-fpga. If not, see 22 | # . 23 | 24 | import sys 25 | import wave 26 | from struct import pack 27 | 28 | sample_rate = 48000 29 | 30 | def convert(code): 31 | file_in = open('dac_out-%(code)s.txt' % {'code': code}, 'r') 32 | 33 | wave_out = wave.open('dac_out-%(code)s.wav' % {'code': code}, 'wb') 34 | wave_out.setnchannels(1) 35 | wave_out.setsampwidth(1) 36 | wave_out.setframerate(sample_rate) 37 | 38 | wave_out_sample = 0 39 | dac_sample = 0 40 | dac_value = 0 41 | 42 | for line in file_in: 43 | time_ns, dac_binary = line.split('\t') 44 | if time_ns[-3:] != ' ns': 45 | raise 'unhandled time format' 46 | time = float(time_ns[:-3]) / 1000000000.0 47 | if 'Z' in dac_binary: 48 | dac = 128 49 | else: 50 | dac = int(dac_binary, 2) 51 | 52 | dac_sample = time * sample_rate 53 | 54 | while wave_out_sample < dac_sample: 55 | wave_out.writeframes(chr(dac_value)) 56 | wave_out_sample += 1 57 | 58 | dac_value = dac 59 | #print time, dac_value 60 | 61 | wave_out.close() 62 | file_in.close() 63 | 64 | def make_binary_string(i): 65 | result = [] 66 | while i != 0: 67 | if i & 1: 68 | result.append('1') 69 | else: 70 | result.append('0') 71 | i >>= 1 72 | return ''.join(reversed(result)) 73 | 74 | convert('111111') 75 | #for code in ['000000', '000001', '000101', '001010']: 76 | # convert(code) 77 | #for n in range(64): 78 | # n_base_2 = make_binary_string(n).zfill(6) 79 | # convert(n_base_2) 80 | -------------------------------------------------------------------------------- /tools/make_sound_rom.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # 4 | # Copyright 2009-2011 ShareBrained Technology, Inc. 5 | # 6 | # This file is part of robotron-fpga. 7 | # 8 | # robotron-fpga is free software: you can redistribute 9 | # it and/or modify it under the terms of the GNU General 10 | # Public License as published by the Free Software 11 | # Foundation, either version 3 of the License, or (at your 12 | # option) any later version. 13 | # 14 | # robotron-fpga is distributed in the hope that it will 15 | # be useful, but WITHOUT ANY WARRANTY; without even the 16 | # implied warranty of MERCHANTABILITY or FITNESS FOR A 17 | # PARTICULAR PURPOSE. See the GNU General Public License 18 | # for more details. 19 | # 20 | # You should have received a copy of the GNU General 21 | # Public License along with robotron-fpga. If not, see 22 | # . 23 | 24 | def write_file_header(f): 25 | f.write("""library IEEE; 26 | use IEEE.std_logic_1164.all; 27 | use IEEE.std_logic_arith.all; 28 | library unisim; 29 | use unisim.vcomponents.all; 30 | 31 | """) 32 | 33 | def write_entity(name, f): 34 | f.write("""entity %(name)s is 35 | port( 36 | clk : in std_logic; 37 | rst : in std_logic; 38 | cs : in std_logic; 39 | addr : in std_logic_vector(10 downto 0); 40 | data : out std_logic_vector(7 downto 0) 41 | ); 42 | end %(name)s; 43 | 44 | """ % {'name': name}) 45 | 46 | def write_architecture(name, data, f): 47 | f.write("""architecture rtl of %(name)s is 48 | signal dp : std_logic; 49 | begin 50 | ROM: RAMB16_S9 51 | generic map ( 52 | """ % {'name': name}) 53 | step = 32 54 | init_lines = [] 55 | for n in range(0, len(data) / step): 56 | start = n * step 57 | end = (n + 1) * step 58 | init_data = reversed(data[start:end]) 59 | init_data = ''.join([hex(ord(c))[2:].zfill(2) for c in init_data]) 60 | init_line = ' INIT_%02x => x"%s"' % (n, init_data) 61 | init_lines.append(init_line) 62 | f.write(',\n'.join(init_lines)) 63 | f.write(""" 64 | ) 65 | port map ( 66 | do => data, 67 | dop(0) => dp, 68 | addr => addr, 69 | clk => clk, 70 | di => "00000000", 71 | dip(0) => '0', 72 | en => cs, 73 | ssr => rst, 74 | we => '0' 75 | ); 76 | end architecture rtl; 77 | 78 | """) 79 | 80 | data = open('robotron.snd', 'rb').read() 81 | file_out = open('rom_snd_blocks.vhd', 'w') 82 | 83 | write_file_header(file_out) 84 | write_entity('ROM_SND_F000', file_out) 85 | write_architecture('ROM_SND_F000', data[0:2048], file_out) 86 | 87 | write_file_header(file_out) 88 | write_entity('ROM_SND_F800', file_out) 89 | write_architecture('ROM_SND_F800', data[2048:4096], file_out) 90 | 91 | file_out.close() 92 | --------------------------------------------------------------------------------