OpenCores
URL https://opencores.org/ocsvn/am9080_cpu_based_on_microcoded_am29xx_bit-slices/am9080_cpu_based_on_microcoded_am29xx_bit-slices/trunk

Subversion Repositories am9080_cpu_based_on_microcoded_am29xx_bit-slices

[/] [am9080_cpu_based_on_microcoded_am29xx_bit-slices/] [trunk/] [sys9080.vhd] - Blame information for rev 8

Details | Compare with Previous | View Log

Line No. Rev Author Line
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;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.