1 |
8 |
zpekic |
----------------------------------------------------------------------------------
|
2 |
|
|
-- Company: @Home
|
3 |
|
|
-- Engineer: zpekic@hotmail.com
|
4 |
|
|
--
|
5 |
|
|
-- Create Date: 08/24/2017 11:13:02 PM
|
6 |
|
|
-- Design Name:
|
7 |
|
|
-- Module Name: sys9080 - Behavioral
|
8 |
|
|
-- Project Name: Simple 8-bit system around microcode implemented Am9080 CPU
|
9 |
|
|
-- Target Devices: https://www.micro-nova.com/mercury/ + Baseboard
|
10 |
|
|
-- Tool Versions: ISE 14.7 (nt)
|
11 |
|
|
-- Description:
|
12 |
|
|
--
|
13 |
|
|
-- Dependencies:
|
14 |
|
|
--
|
15 |
|
|
-- Revision:
|
16 |
|
|
-- Revision 0.99 - Kinda works...
|
17 |
|
|
-- Additional Comments:
|
18 |
|
|
-- https://en.wikichip.org/w/images/7/76/An_Emulation_of_the_Am9080A.pdf
|
19 |
|
|
----------------------------------------------------------------------------------
|
20 |
|
|
|
21 |
|
|
|
22 |
|
|
library IEEE;
|
23 |
|
|
use IEEE.STD_LOGIC_1164.ALL;
|
24 |
|
|
|
25 |
|
|
-- Uncomment the following library declaration if using
|
26 |
|
|
-- arithmetic functions with Signed or Unsigned values
|
27 |
|
|
use IEEE.NUMERIC_STD.ALL;
|
28 |
|
|
|
29 |
|
|
-- Uncomment the following library declaration if instantiating
|
30 |
|
|
-- any Xilinx leaf cells in this code.
|
31 |
|
|
--library UNISIM;
|
32 |
|
|
--use UNISIM.VComponents.all;
|
33 |
|
|
|
34 |
|
|
entity sys9080 is
|
35 |
|
|
Port (
|
36 |
|
|
-- 50MHz on the Mercury board
|
37 |
|
|
CLK: in std_logic;
|
38 |
|
|
-- Master reset button on Mercury board
|
39 |
|
|
USR_BTN: in std_logic;
|
40 |
|
|
-- Switches on baseboard
|
41 |
|
|
-- SW(1 downto 0) -- LED display selection
|
42 |
|
|
-- 0 0 Sys9080 - A(7:0) & D(7:0) & io and memory r/w on dots
|
43 |
|
|
-- 0 1 Sys9080 - OUT port 1 & port 0
|
44 |
|
|
-- 1 0 Am9080 - microinstruction counter & instruction register
|
45 |
|
|
-- 1 1 Am9080 - content of register as defined by SW5:2
|
46 |
|
|
-- SW(5 downto 2) -- 4 bit Am9080 register selector when inspecting register states in SS mode
|
47 |
|
|
-- SW(6 downto 5) -- system clock speed
|
48 |
|
|
-- 0 0 1Hz (can be used with SS mode)
|
49 |
|
|
-- 0 1 1024Hz (can be used with SS mode)
|
50 |
|
|
-- 1 0 6.125MHz
|
51 |
|
|
-- 1 1 25MHz
|
52 |
|
|
-- SW7
|
53 |
|
|
-- 0 single step mode off (BTN3 should be pressed once to start the system)
|
54 |
|
|
-- 1 single step mode on (use with BTN3)
|
55 |
|
|
SW: in std_logic_vector(7 downto 0);
|
56 |
|
|
-- Push buttons on baseboard
|
57 |
|
|
-- BTN0 - generate RST 7 interrupt which will dump processor regs and memory they are pointing to over ACIA0
|
58 |
|
|
-- BTN1 - bypass ACIA Rx char input processing and dump received bytes and status to ACIA0
|
59 |
|
|
-- BTN2 - put processor into HOLD mode
|
60 |
|
|
-- BTN3 - single step clock cycle forward if in SS mode (NOTE: single press on this button is needed after reset to unlock SS circuit)
|
61 |
|
|
BTN: in std_logic_vector(3 downto 0);
|
62 |
|
|
-- Stereo audio output on baseboard
|
63 |
|
|
--AUDIO_OUT_L, AUDIO_OUT_R: out std_logic;
|
64 |
|
|
-- 7seg LED on baseboard
|
65 |
|
|
A_TO_G: out std_logic_vector(6 downto 0);
|
66 |
|
|
AN: out std_logic_vector(3 downto 0);
|
67 |
|
|
DOT: out std_logic;
|
68 |
|
|
-- 4 LEDs on Mercury board
|
69 |
|
|
LED: out std_logic_vector(3 downto 0);
|
70 |
|
|
-- ADC interface
|
71 |
|
|
--ADC_MISO: in std_logic;
|
72 |
|
|
--ADC_MOSI: out std_logic;
|
73 |
|
|
--ADC_SCK: out std_logic;
|
74 |
|
|
--ADC_CSN: out std_logic;
|
75 |
|
|
--PMOD interface (for hex keypad)
|
76 |
|
|
PMOD: inout std_logic_vector(7 downto 0)
|
77 |
|
|
|
78 |
|
|
);
|
79 |
|
|
end sys9080;
|
80 |
|
|
|
81 |
|
|
architecture Structural of sys9080 is
|
82 |
|
|
|
83 |
|
|
component clock_divider is
|
84 |
|
|
Port ( reset : in STD_LOGIC;
|
85 |
|
|
clock : in STD_LOGIC;
|
86 |
|
|
slow : out STD_LOGIC_VECTOR (11 downto 0);
|
87 |
|
|
fast : out STD_LOGIC_VECTOR (3 downto 0)
|
88 |
|
|
);
|
89 |
|
|
end component;
|
90 |
|
|
|
91 |
|
|
component clocksinglestepper is
|
92 |
|
|
Port ( reset : in STD_LOGIC;
|
93 |
|
|
clock0_in : in STD_LOGIC;
|
94 |
|
|
clock1_in : in STD_LOGIC;
|
95 |
|
|
clock2_in : in STD_LOGIC;
|
96 |
|
|
clock3_in : in STD_LOGIC;
|
97 |
|
|
clocksel : in STD_LOGIC_VECTOR(1 downto 0);
|
98 |
|
|
modesel : in STD_LOGIC;
|
99 |
|
|
singlestep : in STD_LOGIC;
|
100 |
|
|
clock_out : out STD_LOGIC);
|
101 |
|
|
end component;
|
102 |
|
|
|
103 |
|
|
component counter16bit is
|
104 |
|
|
Port ( reset : in STD_LOGIC;
|
105 |
|
|
clk : in STD_LOGIC;
|
106 |
|
|
mode : in STD_LOGIC_VECTOR (1 downto 0);
|
107 |
|
|
d : in STD_LOGIC_VECTOR (31 downto 0);
|
108 |
|
|
q : out STD_LOGIC_VECTOR (31 downto 0));
|
109 |
|
|
end component;
|
110 |
|
|
|
111 |
|
|
component debouncer8channel is
|
112 |
|
|
Port ( clock : in STD_LOGIC;
|
113 |
|
|
reset : in STD_LOGIC;
|
114 |
|
|
signal_raw : in STD_LOGIC_VECTOR(7 downto 0);
|
115 |
|
|
signal_debounced : out STD_LOGIC_VECTOR(7 downto 0));
|
116 |
|
|
end component;
|
117 |
|
|
|
118 |
|
|
component fourdigitsevensegled is
|
119 |
|
|
Port ( -- inputs
|
120 |
|
|
data : in STD_LOGIC_VECTOR (15 downto 0);
|
121 |
|
|
digsel : in STD_LOGIC_VECTOR (1 downto 0);
|
122 |
|
|
showdigit : in STD_LOGIC_VECTOR (3 downto 0);
|
123 |
|
|
showdot : in STD_LOGIC_VECTOR (3 downto 0);
|
124 |
|
|
showsegments : in STD_LOGIC;
|
125 |
|
|
-- outputs
|
126 |
|
|
anode : out STD_LOGIC_VECTOR (3 downto 0);
|
127 |
|
|
segment : out STD_LOGIC_VECTOR (7 downto 0)
|
128 |
|
|
);
|
129 |
|
|
end component;
|
130 |
|
|
|
131 |
|
|
component simpledevice is
|
132 |
|
|
Port(
|
133 |
|
|
clk : in STD_LOGIC;
|
134 |
|
|
reset: in STD_LOGIC;
|
135 |
|
|
D: inout STD_LOGIC_VECTOR(7 downto 0);
|
136 |
|
|
A: in STD_LOGIC_VECTOR(3 downto 0);
|
137 |
|
|
nRead: in STD_LOGIC;
|
138 |
|
|
nWrite: in STD_LOGIC;
|
139 |
|
|
IntReq: out STD_LOGIC;
|
140 |
|
|
IntAck: in STD_LOGIC;
|
141 |
|
|
nSelect: in STD_LOGIC;
|
142 |
|
|
direct_in: in STD_LOGIC_VECTOR(15 downto 0);
|
143 |
|
|
direct_out: out STD_LOGIC_VECTOR(15 downto 0)
|
144 |
|
|
);
|
145 |
|
|
end component;
|
146 |
|
|
|
147 |
|
|
component ACIA is
|
148 |
|
|
Port(
|
149 |
|
|
clk : in STD_LOGIC;
|
150 |
|
|
reset: in STD_LOGIC;
|
151 |
|
|
D: inout STD_LOGIC_VECTOR(7 downto 0);
|
152 |
|
|
A: in STD_LOGIC;
|
153 |
|
|
nRead: in STD_LOGIC;
|
154 |
|
|
nWrite: in STD_LOGIC;
|
155 |
|
|
nSelect: in STD_LOGIC;
|
156 |
|
|
IntReq: out STD_LOGIC;
|
157 |
|
|
IntAck: in STD_LOGIC;
|
158 |
|
|
txd: out STD_LOGIC;
|
159 |
|
|
rxd: in STD_LOGIC
|
160 |
|
|
);
|
161 |
|
|
end component;
|
162 |
|
|
|
163 |
|
|
component simpleram is
|
164 |
|
|
generic (
|
165 |
|
|
address_size: integer;
|
166 |
|
|
default_value: STD_LOGIC_VECTOR(7 downto 0)
|
167 |
|
|
);
|
168 |
|
|
Port (
|
169 |
|
|
clk: in STD_LOGIC;
|
170 |
|
|
D : inout STD_LOGIC_VECTOR (7 downto 0);
|
171 |
|
|
A : in STD_LOGIC_VECTOR ((address_size - 1) downto 0);
|
172 |
|
|
nRead : in STD_LOGIC;
|
173 |
|
|
nWrite : in STD_LOGIC;
|
174 |
|
|
nSelect : in STD_LOGIC);
|
175 |
|
|
end component;
|
176 |
|
|
|
177 |
|
|
component hexfilerom is
|
178 |
|
|
Generic (
|
179 |
|
|
filename: string;
|
180 |
|
|
address_size: integer;
|
181 |
|
|
default_value: STD_LOGIC_VECTOR(7 downto 0)
|
182 |
|
|
);
|
183 |
|
|
Port (
|
184 |
|
|
D : out STD_LOGIC_VECTOR (7 downto 0);
|
185 |
|
|
A : in STD_LOGIC_VECTOR ((address_size - 1) downto 0);
|
186 |
|
|
nRead : in STD_LOGIC;
|
187 |
|
|
nSelect : in STD_LOGIC
|
188 |
|
|
);
|
189 |
|
|
end component;
|
190 |
|
|
|
191 |
|
|
component interrupt_controller is
|
192 |
|
|
Port ( CLK : in STD_LOGIC;
|
193 |
|
|
nRESET : in STD_LOGIC;
|
194 |
|
|
INT : out STD_LOGIC;
|
195 |
|
|
nINTA : in STD_LOGIC;
|
196 |
|
|
INTE : in STD_LOGIC;
|
197 |
|
|
D : out STD_LOGIC_VECTOR (7 downto 0);
|
198 |
|
|
DEVICEREQ : in STD_LOGIC_VECTOR (7 downto 0);
|
199 |
|
|
DEVICEACK : out STD_LOGIC_VECTOR (7 downto 0));
|
200 |
|
|
end component;
|
201 |
|
|
|
202 |
|
|
component Am9080a is
|
203 |
|
|
Port ( DBUS : inout STD_LOGIC_VECTOR (7 downto 0);
|
204 |
|
|
ABUS : out STD_LOGIC_VECTOR (15 downto 0);
|
205 |
|
|
WAITOUT : out STD_LOGIC;
|
206 |
|
|
nINTA : out STD_LOGIC;
|
207 |
|
|
nIOR : out STD_LOGIC;
|
208 |
|
|
nIOW : out STD_LOGIC;
|
209 |
|
|
nMEMR : out STD_LOGIC;
|
210 |
|
|
nMEMW : out STD_LOGIC;
|
211 |
|
|
HLDA : out STD_LOGIC;
|
212 |
|
|
INTE : out STD_LOGIC;
|
213 |
|
|
CLK : in STD_LOGIC;
|
214 |
|
|
nRESET : in STD_LOGIC;
|
215 |
|
|
INT: in STD_LOGIC;
|
216 |
|
|
READY: in STD_LOGIC;
|
217 |
|
|
HOLD: in STD_LOGIC;
|
218 |
|
|
-- debug port, not part of actual processor
|
219 |
|
|
debug_ena : in STD_LOGIC;
|
220 |
|
|
debug_sel : in STD_LOGIC;
|
221 |
|
|
debug_out : out STD_LOGIC_VECTOR (19 downto 0);
|
222 |
|
|
debug_reg : in STD_LOGIC_VECTOR(3 downto 0)
|
223 |
|
|
);
|
224 |
|
|
end component;
|
225 |
|
|
|
226 |
|
|
--component ila_0 IS
|
227 |
|
|
-- PORT (
|
228 |
|
|
-- clk : IN STD_LOGIC;
|
229 |
|
|
-- probe0 : IN STD_LOGIC_VECTOR(5 DOWNTO 0);
|
230 |
|
|
-- probe1 : IN STD_LOGIC_VECTOR(0 DOWNTO 0));
|
231 |
|
|
--end component;
|
232 |
|
|
|
233 |
|
|
component vio_0 IS
|
234 |
|
|
PORT (
|
235 |
|
|
clk : IN STD_LOGIC;
|
236 |
|
|
probe_in0 : IN STD_LOGIC_VECTOR(2 DOWNTO 0);
|
237 |
|
|
probe_in1 : IN STD_LOGIC_VECTOR(2 DOWNTO 0);
|
238 |
|
|
probe_in2 : IN STD_LOGIC_VECTOR(2 DOWNTO 0);
|
239 |
|
|
probe_in3 : IN STD_LOGIC_VECTOR(2 DOWNTO 0);
|
240 |
|
|
probe_out0 : OUT STD_LOGIC_VECTOR(23 DOWNTO 0);
|
241 |
|
|
probe_out1 : OUT STD_LOGIC_VECTOR(23 DOWNTO 0);
|
242 |
|
|
probe_out2 : OUT STD_LOGIC_VECTOR(23 DOWNTO 0);
|
243 |
|
|
probe_out3 : OUT STD_LOGIC_VECTOR(23 DOWNTO 0)
|
244 |
|
|
);
|
245 |
|
|
END component;
|
246 |
|
|
|
247 |
|
|
-- CPU buses
|
248 |
|
|
signal data_bus: std_logic_vector(7 downto 0);
|
249 |
|
|
signal address_bus: std_logic_vector(15 downto 0);
|
250 |
|
|
signal Reset, nReset: std_logic;
|
251 |
|
|
signal clock_main: std_logic;
|
252 |
|
|
signal nIORead, nIOWrite, nMemRead, nMemWrite: std_logic;
|
253 |
|
|
signal IntReq, nIntAck, Hold, HoldAck, IntE: std_logic;
|
254 |
|
|
|
255 |
|
|
-- other signals
|
256 |
|
|
signal reset_delay: std_logic_vector(3 downto 0);
|
257 |
|
|
signal DeviceReq: std_logic_vector(7 downto 0);
|
258 |
|
|
signal DeviceAck: std_logic_vector(7 downto 0);
|
259 |
|
|
signal switch: std_logic_vector(7 downto 0);
|
260 |
|
|
signal button: std_logic_vector(7 downto 0);
|
261 |
|
|
--signal cnt: std_logic_vector(31 downto 0);
|
262 |
|
|
signal io_output: std_logic_vector(15 downto 0);
|
263 |
|
|
signal led_bus: std_logic_vector(19 downto 0);
|
264 |
|
|
signal cpu_debug_bus, sys_debug_bus: std_logic_vector(19 downto 0);
|
265 |
|
|
signal nIoEnable, nACIA0Enable, nACIA1Enable, nBootRomEnable, nMonRomEnable, nRamEnable: std_logic;
|
266 |
|
|
signal readwritesignals: std_logic_vector(4 downto 0);
|
267 |
|
|
signal showsegments: std_logic;
|
268 |
|
|
signal flash: std_logic;
|
269 |
|
|
signal freq2k, freq1k, freq512, freq256, freq128, freq64, freq32, freq16, freq8, freq4, freq2, freq1: std_logic;
|
270 |
|
|
signal freq25M, freq12M5, freq6M25, freq3M125: std_logic;
|
271 |
|
|
|
272 |
|
|
begin
|
273 |
|
|
|
274 |
|
|
Reset <= USR_BTN;
|
275 |
|
|
nReset <= '0' when (Reset = '1') or (reset_delay /= "0000") else '1';
|
276 |
|
|
|
277 |
|
|
led_bus <= cpu_debug_bus when (switch(1) = '1') else sys_debug_bus;
|
278 |
|
|
sys_debug_bus <= readwritesignals(4 downto 1) & address_bus(7 downto 0) & data_bus when (switch(0) = '0') else "0000" & io_output;
|
279 |
|
|
|
280 |
|
|
readwritesignals <= (not nIORead) & (not nIOWrite) & (not nMemRead) & (not nMemWrite) & (not nIntAck);
|
281 |
|
|
showsegments <= '0' when (switch(1 downto 0) = "00" and readwritesignals = "00000") else '1';
|
282 |
|
|
|
283 |
|
|
Hold <= button(2);
|
284 |
|
|
flash <= HoldAck or freq2; -- blink in hold bus mode!
|
285 |
|
|
-- DISPLAY
|
286 |
|
|
LED(3) <= nIntAck;
|
287 |
|
|
LED(2) <= IntReq;
|
288 |
|
|
LED(1) <= HoldAck;
|
289 |
|
|
LED(0) <= clock_main;
|
290 |
|
|
led4x7: fourdigitsevensegled port map (
|
291 |
|
|
-- inputs
|
292 |
|
|
data => led_bus(15 downto 0),
|
293 |
|
|
digsel(1) => freq1k,
|
294 |
|
|
digsel(0) => freq2k,
|
295 |
|
|
showdigit(3) => flash,
|
296 |
|
|
showdigit(2) => flash,
|
297 |
|
|
showdigit(1) => flash,
|
298 |
|
|
showdigit(0) => flash,
|
299 |
|
|
showdot => led_bus(19 downto 16),
|
300 |
|
|
showsegments => showsegments,
|
301 |
|
|
-- outputs
|
302 |
|
|
anode => AN,
|
303 |
|
|
segment(6 downto 0) => A_TO_G(6 downto 0),
|
304 |
|
|
segment(7) => DOT
|
305 |
|
|
);
|
306 |
|
|
|
307 |
|
|
-- FREQUENCY GENERATOR
|
308 |
|
|
one_sec: clock_divider port map
|
309 |
|
|
(
|
310 |
|
|
clock => CLK,
|
311 |
|
|
reset => Reset,
|
312 |
|
|
slow(11) => freq1, -- 1Hz
|
313 |
|
|
slow(10) => freq2, -- 2Hz
|
314 |
|
|
slow(9) => freq4, -- 4Hz
|
315 |
|
|
slow(8) => freq8, -- 8Hz
|
316 |
|
|
slow(7) => freq16, -- 16Hz
|
317 |
|
|
slow(6) => freq32, -- 32Hz
|
318 |
|
|
slow(5) => freq64, -- 64Hz
|
319 |
|
|
slow(4) => freq128, -- 128Hz
|
320 |
|
|
slow(3) => freq256, -- 256Hz
|
321 |
|
|
slow(2) => freq512, -- 512Hz
|
322 |
|
|
slow(1) => freq1k, -- 1024Hz
|
323 |
|
|
slow(0) => freq2k, -- 2048Hz
|
324 |
|
|
fast(3) => freq3M125,
|
325 |
|
|
fast(2) => freq6M25,
|
326 |
|
|
fast(1) => freq12M5,
|
327 |
|
|
fast(0) => freq25M
|
328 |
|
|
);
|
329 |
|
|
|
330 |
|
|
-- DEBOUNCE the 8 switches and 4 buttons
|
331 |
|
|
debouncer_sw: debouncer8channel port map (
|
332 |
|
|
clock => freq128,
|
333 |
|
|
reset => Reset,
|
334 |
|
|
signal_raw => SW,
|
335 |
|
|
signal_debounced => switch
|
336 |
|
|
);
|
337 |
|
|
|
338 |
|
|
debouncer_btn: debouncer8channel port map (
|
339 |
|
|
clock => freq128,
|
340 |
|
|
reset => Reset,
|
341 |
|
|
signal_raw(7 downto 4) => "1111",
|
342 |
|
|
signal_raw(3 downto 0) => BTN(3 downto 0),
|
343 |
|
|
signal_debounced => button
|
344 |
|
|
);
|
345 |
|
|
|
346 |
|
|
-- Hook up buttons to generate interrupts
|
347 |
|
|
irq7: process(nReset, button(0), deviceack(7))
|
348 |
|
|
begin
|
349 |
|
|
if (nReset = '0' or deviceack(7) = '1') then
|
350 |
|
|
devicereq(7) <= '0';
|
351 |
|
|
else
|
352 |
|
|
if (rising_edge(button(0))) then
|
353 |
|
|
devicereq(7) <= '1';
|
354 |
|
|
end if;
|
355 |
|
|
end if;
|
356 |
|
|
end process;
|
357 |
|
|
|
358 |
|
|
irq6: process(nReset, button(1), deviceack(6))
|
359 |
|
|
begin
|
360 |
|
|
if (nReset = '0' or deviceack(6) = '1') then
|
361 |
|
|
devicereq(6) <= '0';
|
362 |
|
|
else
|
363 |
|
|
if (rising_edge(button(1))) then
|
364 |
|
|
devicereq(6) <= '1';
|
365 |
|
|
end if;
|
366 |
|
|
end if;
|
367 |
|
|
end process;
|
368 |
|
|
|
369 |
|
|
-- delay to generate nReset 4 cycles after reset
|
370 |
|
|
generate_nReset: process (clock_main, Reset)
|
371 |
|
|
begin
|
372 |
|
|
if (Reset = '1') then
|
373 |
|
|
reset_delay <= "1111";
|
374 |
|
|
else
|
375 |
|
|
if (rising_edge(clock_main)) then
|
376 |
|
|
reset_delay <= reset_delay(2 downto 0) & Reset;
|
377 |
|
|
end if;
|
378 |
|
|
end if;
|
379 |
|
|
end process;
|
380 |
|
|
|
381 |
|
|
-- Single step by each clock cycle, slow or fast
|
382 |
|
|
ss: clocksinglestepper port map (
|
383 |
|
|
reset => Reset,
|
384 |
|
|
clock0_in => freq2,
|
385 |
|
|
clock1_in => freq2k,
|
386 |
|
|
clock2_in => freq3M125,
|
387 |
|
|
clock3_in => freq25M,
|
388 |
|
|
clocksel => switch(6 downto 5),
|
389 |
|
|
modesel => switch(7),
|
390 |
|
|
singlestep => button(3),
|
391 |
|
|
clock_out => clock_main
|
392 |
|
|
);
|
393 |
|
|
|
394 |
|
|
-- ila_ss: ila_0 port map (
|
395 |
|
|
-- clk => CLK,
|
396 |
|
|
-- probe0(5) => RESET,
|
397 |
|
|
-- probe0(4) => button(3),
|
398 |
|
|
-- probe0(3) => switch(3),
|
399 |
|
|
-- probe0(2) => switch(2),
|
400 |
|
|
-- probe0(1) => freq2k,
|
401 |
|
|
-- probe0(0) => freq1,
|
402 |
|
|
-- probe1(0) => clock_main
|
403 |
|
|
-- );
|
404 |
|
|
|
405 |
|
|
nIoEnable <= (nIoRead and nIoWrite) when address_bus(7 downto 4) = "0000" else '1'; -- 0x00 - 0x0F
|
406 |
|
|
nACIA0Enable <= (nIoRead and nIoWrite) when address_bus(7 downto 1) = "0001000" else '1'; -- 0x10 - 0x11
|
407 |
|
|
nACIA1Enable <= (nIoRead and nIoWrite) when address_bus(7 downto 1) = "0001001" else '1'; -- 0x12 - 0x13
|
408 |
|
|
nBootRomEnable <= nMemRead when address_bus(15 downto 10) = "000000" else '1'; -- 1k ROM (0000 - 03FF)
|
409 |
|
|
nMonRomEnable <= nMemRead when address_bus(15 downto 10) = "000001" else '1'; -- 1k ROM (0400 - 07FF)
|
410 |
|
|
nRamEnable <= (nMemRead and nMemWrite) when address_bus(15 downto 8) = "11111111" else '1'; -- 256b RAM (FF00 - FFFF)
|
411 |
|
|
|
412 |
|
|
iodevice: simpledevice port map(
|
413 |
|
|
clk => CLK, -- this is the full 50MHz clock!
|
414 |
|
|
reset => Reset,
|
415 |
|
|
D => data_bus,
|
416 |
|
|
A => address_bus(3 downto 0),
|
417 |
|
|
nRead => nIORead,
|
418 |
|
|
nWrite => nIOWrite,
|
419 |
|
|
nSelect => nIoEnable,
|
420 |
|
|
IntReq => open,
|
421 |
|
|
IntAck => '1',
|
422 |
|
|
direct_in(7 downto 0) => switch,
|
423 |
|
|
direct_in(15 downto 8) => button,
|
424 |
|
|
direct_out => io_output
|
425 |
|
|
);
|
426 |
|
|
|
427 |
|
|
acia0: ACIA port map(
|
428 |
|
|
clk => CLK, -- this is the full 50MHz clock!
|
429 |
|
|
reset => Reset,
|
430 |
|
|
D => data_bus,
|
431 |
|
|
A => address_bus(0),
|
432 |
|
|
nRead => nIORead,
|
433 |
|
|
nWrite => nIOWrite,
|
434 |
|
|
nSelect => nAcia0Enable,
|
435 |
|
|
IntReq => DeviceReq(5),
|
436 |
|
|
IntAck => DeviceAck(5),
|
437 |
|
|
txd => PMOD(0),
|
438 |
|
|
rxd => PMOD(1)
|
439 |
|
|
);
|
440 |
|
|
|
441 |
|
|
acia1: ACIA port map(
|
442 |
|
|
clk => CLK, -- this is the full 50MHz clock!
|
443 |
|
|
reset => Reset,
|
444 |
|
|
D => data_bus,
|
445 |
|
|
A => address_bus(0),
|
446 |
|
|
nRead => nIORead,
|
447 |
|
|
nWrite => nIOWrite,
|
448 |
|
|
nSelect => nAcia1Enable,
|
449 |
|
|
IntReq => DeviceReq(4),
|
450 |
|
|
IntAck => DeviceAck(4),
|
451 |
|
|
txd => PMOD(2),
|
452 |
|
|
rxd => PMOD(3)
|
453 |
|
|
);
|
454 |
|
|
|
455 |
|
|
bootrom: hexfilerom
|
456 |
|
|
generic map(
|
457 |
|
|
filename => "./prog/zout/boot.hex",
|
458 |
|
|
address_size => 10,
|
459 |
|
|
default_value => X"FF" -- if executed, will be RST 7
|
460 |
|
|
)
|
461 |
|
|
port map(
|
462 |
|
|
D => data_bus,
|
463 |
|
|
A => address_bus(9 downto 0),
|
464 |
|
|
nRead => nMemRead,
|
465 |
|
|
nSelect => nBootRomEnable
|
466 |
|
|
);
|
467 |
|
|
|
468 |
|
|
monrom: hexfilerom
|
469 |
|
|
generic map(
|
470 |
|
|
filename => "./prog/zout/altmon.hex",
|
471 |
|
|
address_size => 10,
|
472 |
|
|
default_value => X"FF" -- if executed, will be RST 7
|
473 |
|
|
)
|
474 |
|
|
port map(
|
475 |
|
|
D => data_bus,
|
476 |
|
|
A => address_bus(9 downto 0),
|
477 |
|
|
nRead => nMemRead,
|
478 |
|
|
nSelect => nMonRomEnable
|
479 |
|
|
);
|
480 |
|
|
|
481 |
|
|
ram: simpleram
|
482 |
|
|
generic map(
|
483 |
|
|
address_size => 8,
|
484 |
|
|
default_value => X"FF" -- if executed, will be RST 7
|
485 |
|
|
)
|
486 |
|
|
port map(
|
487 |
|
|
clk => clock_main,
|
488 |
|
|
D => data_bus,
|
489 |
|
|
A => address_bus(7 downto 0),
|
490 |
|
|
nRead => nMemRead,
|
491 |
|
|
nWrite => nMemWrite,
|
492 |
|
|
nSelect => nRamEnable
|
493 |
|
|
);
|
494 |
|
|
|
495 |
|
|
ic: interrupt_controller Port map (
|
496 |
|
|
CLK => CLK, -- this is the full 50MHz clock!
|
497 |
|
|
nRESET => nReset,
|
498 |
|
|
INT => IntReq,
|
499 |
|
|
nINTA => nIntAck,
|
500 |
|
|
INTE => IntE,
|
501 |
|
|
D => data_bus,
|
502 |
|
|
DEVICEREQ(7) => devicereq(7), -- button 0
|
503 |
|
|
DEVICEREQ(6) => devicereq(6), -- button 1
|
504 |
|
|
DEVICEREQ(5) => devicereq(5), -- ACIA 0
|
505 |
|
|
DEVICEREQ(4) => '0', --devicereq(4), -- ACIA 1 $BUGBUG - interrupt req stuck for ACIA1?
|
506 |
|
|
DEVICEREQ(3) => '0',
|
507 |
|
|
DEVICEREQ(2) => '0',
|
508 |
|
|
DEVICEREQ(1) => '0',
|
509 |
|
|
DEVICEREQ(0) => '0',
|
510 |
|
|
DEVICEACK => DeviceAck
|
511 |
|
|
);
|
512 |
|
|
|
513 |
|
|
cpu: Am9080a port map (
|
514 |
|
|
DBUS => data_bus,
|
515 |
|
|
ABUS => address_bus,
|
516 |
|
|
WAITOUT => open,
|
517 |
|
|
nINTA => nIntAck,
|
518 |
|
|
nIOR => nIORead,
|
519 |
|
|
nIOW => nIOWrite,
|
520 |
|
|
nMEMR => nMemRead,
|
521 |
|
|
nMEMW => nMemWrite,
|
522 |
|
|
HLDA => HoldAck,
|
523 |
|
|
INTE => IntE,
|
524 |
|
|
CLK => clock_main,
|
525 |
|
|
nRESET => nReset,
|
526 |
|
|
INT => IntReq,
|
527 |
|
|
READY => '1', -- TODO - use to implement single stepping per instruction, not cycle
|
528 |
|
|
HOLD => Hold,
|
529 |
|
|
-- debug port, not part of actual processor
|
530 |
|
|
debug_ena => switch(1),
|
531 |
|
|
debug_sel => switch(0),
|
532 |
|
|
debug_out => cpu_debug_bus,
|
533 |
|
|
debug_reg => switch(5 downto 2)
|
534 |
|
|
);
|
535 |
|
|
|
536 |
|
|
end;
|