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 |
--------------------------------------------------------------------------------