OpenCores
URL https://opencores.org/ocsvn/System09/System09/trunk

Subversion Repositories System09

[/] [System09/] [trunk/] [rtl/] [System09_base/] [system09.vhd] - Blame information for rev 158

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 128 davidgb
--===========================================================================----
2
--
3
--  S Y N T H E Z I A B L E    System09 - SOC.
4
--
5
--  www.OpenCores.Org - February 2007
6
--  This core adheres to the GNU public license  
7
--
8
-- File name      : System09_Xess_XSA-3S1000.vhd
9
--
10
-- Purpose        : Top level file for 6809 compatible system on a chip
11
--                  Designed with Xilinx XC3S1000 Spartan 3 FPGA.
12
--                  Implemented With XESS XSA-3S1000 FPGA board.
13
--                  *** Note ***
14
--                  This configuration can run Flex9 however it only has
15
--                  32k bytes of user memory and the VDU is monochrome
16
--                  The design needs to be updated to use the SDRAM on 
17
--                  the XSA-3S1000 board.
18
--                  This configuration also lacks a DAT so cannot use
19
--                  the RAM Disk features of SYS09BUG.
20
--
21
-- Dependencies   : ieee.Std_Logic_1164
22
--                  ieee.std_logic_unsigned
23
--                  ieee.std_logic_arith
24
--                  ieee.numeric_std
25
--                  unisim.vcomponents
26
--
27
-- Uses           : mon_rom    (sys09bug_rom4k_b16.vhd) Sys09Bug Monitor ROM
28
--                  cpu09      (cpu09.vhd)          CPU core
29
--                  ACIA_6850  (acia6850.vhd)      ACIA / UART
30
--                  ACIA_Clock (ACIA_Clock.vhd)      ACIA clock.
31
--                  keyboard   (keyboard.vhd)        PS/2 Keyboard interface
32
--                             (ps2_keyboard.vhd)
33
--                             (keymap_rom_slice.vhd) Key map table 
34
--                  vdu8_mono  (vdu8_mono.vhd)        Monochrome VDU
35
--                             (char_rom2k_b16.vhd)
36
--                             (ram2k_b16.vhd)
37
--                  timer      (timer.vhd)            Interrupt timer
38
--                  trap       (trap.vhd)             Bus condition trap logic
39
--                  flex_ram   (flex9_ram8k_b16.vhd)  Flex operating system
40
--                  ram_32K    (ram32k_b16.vhd)       32 KBytes of Block RAM
41
--                  
42
-- 
43
-- Author         : John E. Kent      
44
--                  dilbert57@opencores.org      
45
--
46
-- Memory Map     :
47
--
48
-- $0000 - User program RAM (32K Bytes)
49
-- $C000 - Flex Operating System memory (8K Bytes)
50
-- $E000 - ACIA (SWTPc)
51
-- $E010 - Reserved for FD1771 FDC (SWTPc)
52
-- $E020 - Keyboard
53
-- $E030 - VDU
54
-- $E040 - IDE / Compact Flash interface
55
-- $E050 - Timer
56
-- $E060 - Bus trap
57
-- $E070 - Reserced for Parallel I/O (B5-X300)
58
-- $E080 - Reserved for 6821 PIA (?) (SWTPc)
59
-- $E090 - Reserved for 6840 PTM (?) (SWTPc)
60
-- $F000 - Sys09Bug monitor Program (4K Bytes)
61
--
62
--===========================================================================----
63
--
64
-- Revision History:
65
--===========================================================================--
66
-- Version 0.1 - 20 March 2003
67
-- Version 0.2 - 30 March 2003
68
-- Version 0.3 - 29 April 2003
69
-- Version 0.4 - 29 June 2003
70
--
71
-- Version 0.5 - 19 July 2003
72
-- prints out "Hello World"
73
--
74
-- Version 0.6 - 5 September 2003
75
-- Runs SBUG
76
--
77
-- Version 1.0- 6 Sep 2003 - John Kent
78
-- Inverted SysClk
79
-- Initial release to Open Cores
80
--
81
-- Version 1.1 - 17 Jan 2004 - John Kent
82
-- Updated miniUart.
83
--
84
-- Version 1.2 - 25 Jan 2004 - John Kent
85
-- removed signals "test_alu" and "test_cc" 
86
-- Trap hardware re-instated.
87
--
88
-- Version 1.3 - 11 Feb 2004 - John Kent
89
-- Designed forked off to produce System09_VDU
90
-- Added VDU component
91 137 davidgb
-- VDU runs at 25MHz and divides the clock by 2 for the CPU
92 128 davidgb
-- UART Runs at 57.6 Kbps
93
--
94
-- Version 2.0 - 2 September 2004 - John Kent
95
-- ported to Digilent Xilinx Spartan3 starter board
96 137 davidgb
-- removed Compact Flash and Trap Logic.
97 128 davidgb
-- Replaced SBUG with KBug9s
98
--
99
-- Version 3.0 - 29th August 2006 - John Kent
100
-- Adapted to XSA-3S1000 board.
101
-- Removed DAT and miniUART.
102
-- Used 32KBytes of Block RAM.
103
--
104
-- Version 3.1 - 15th January 2007 - John Kent
105
-- Modified vdu8 interface
106
-- Added a clock divider
107
--
108
-- Version 3.2 - 25th February 2007 - John Kent
109
-- reinstated ACIA_6850 and ACIA_Clock
110
-- Updated VDU8 & Keyboard with generic parameters
111
-- Defined Constants for clock speed calculations
112
--
113
-- Version 3.3 - 1st July 2007 - John Kent
114
-- Made VDU mono to save on one RAMB16
115
-- Used distributed memory for Key Map ROM to save one RAMB16
116
-- Added Flex RAM at $C000 to $DFFF using 4 spare RAMB16s
117
-- Added timer and trap logic
118
-- Added IDE Interface for Compact Flash
119
-- Replaced KBug9s and stack with Sys09Bug.
120
--
121
-- Version 4.0 - 1st February 2008 - John kent
122
-- Replaced Block RAM with SDRAM Interface
123
-- Modified Hold timing for SDRAM
124
-- Added CF and Ethernet interface 
125
-- via the 16 bit peripheral bus at $E100
126
--
127
--===========================================================================--
128
library ieee;
129
   use ieee.std_logic_1164.all;
130
   use IEEE.STD_LOGIC_ARITH.ALL;
131
   use IEEE.STD_LOGIC_UNSIGNED.ALL;
132
   use ieee.numeric_std.all;
133
library work;
134 137 davidgb
   use work.common.all;
135
   use WORK.xsasdram.all;
136 128 davidgb
library unisim;
137
   use unisim.vcomponents.all;
138
 
139
entity system09 is
140
  port(
141
    CLKA         : in  Std_Logic;  -- 100MHz Clock input
142
--    CLKB         : in  Std_Logic;  -- 50MHz Clock input
143 137 davidgb
    SW2_N        : in  Std_logic;  -- Master Reset input (active low)
144
    SW3_N        : in  Std_logic;  -- Non Maskable Interrupt input (active low)
145 128 davidgb
 
146 137 davidgb
    -- PS/2 Keyboard
147
    ps2_clk      : inout Std_logic;
148
    ps2_dat      : inout Std_Logic;
149 128 davidgb
 
150 137 davidgb
    -- CRTC output signals
151
    vga_vsync_n  : out Std_Logic;
152 128 davidgb
    vga_hsync_n  : out Std_Logic;
153
    vga_blue     : out std_logic_vector(2 downto 0);
154
    vga_green    : out std_logic_vector(2 downto 0);
155
    vga_red      : out std_logic_vector(2 downto 0);
156
 
157
    -- RS232 Port
158 137 davidgb
    RS232_RXD    : in  Std_Logic;
159
    RS232_TXD    : out Std_Logic;
160 128 davidgb
    RS232_CTS    : in  Std_Logic;
161
    RS232_RTS    : out Std_Logic;
162
 
163 137 davidgb
    -- Status 7 segment LED
164
    S            : out std_logic_vector(7 downto 0);
165 128 davidgb
 
166
    -- SDRAM side
167
    SDRAM_clkfb  : in  std_logic;            -- feedback SDRAM clock after PCB delays
168
    SDRAM_clkout : out std_logic;            -- clock to SDRAM
169
    SDRAM_CKE    : out std_logic;            -- clock-enable to SDRAM
170
    SDRAM_CS_N   : out std_logic;            -- chip-select to SDRAM
171
    SDRAM_RAS_N  : out std_logic;            -- SDRAM row address strobe
172
    SDRAM_CAS_N  : out std_logic;            -- SDRAM column address strobe
173
    SDRAM_WE_N   : out std_logic;            -- SDRAM write enable
174
    SDRAM_BA     : out std_logic_vector(1 downto 0);  -- SDRAM bank address
175
    SDRAM_A      : out std_logic_vector(12 downto 0);  -- SDRAM row/column address
176
    SDRAM_D      : inout  std_logic_vector(15 downto 0);  -- data from SDRAM
177
    SDRAM_DQMH   : out std_logic;            -- enable upper-byte of SDRAM databus if true
178
    SDRAM_DQML   : out std_logic;            -- enable lower-byte of SDRAM databus if true
179
 
180 137 davidgb
    -- Peripheral I/O bus $E100 - $E1FF
181 128 davidgb
    PB_RD_N      : out std_logic;
182
    PB_WR_N      : out std_logic;
183
    PB_A         : out std_logic_vector(4 downto 0);
184
    PB_D         : inout std_logic_vector(15 downto 0);
185
 
186
    -- IDE Compact Flash $E100 - $E13F
187
    ide_dmack_n  : out std_logic;
188 137 davidgb
    ide_cs0_n    : out std_logic;
189
    ide_cs1_n    : out std_logic;
190 128 davidgb
 
191
    -- Ethernet $E140 - $E17F
192
    ether_cs_n   : out std_logic;
193
    ether_aen    : out std_logic; -- Ethernet address enable not 
194
    ether_bhe_n  : out std_logic; -- Ethernet bus high enable 
195
    ether_clk    : in  std_logic; -- Ethernet clock 
196
    ether_rdy    : in  std_logic; -- Ethernet ready
197
    ether_irq    : in  std_logic; -- Ethernet irq - Shared with BAR6
198
 
199
    -- Slot 1 $E180 - $E1BF
200 137 davidgb
    slot1_cs_n   : out std_logic;
201
--  slot1_irq    : in  std_logic;
202 128 davidgb
 
203
    -- Slot 2 $E1C0 - $E1FF
204 137 davidgb
    slot2_cs_n   : out std_logic;
205
--  slot2_irq    : in  std_logic;
206 140 davidgb
 
207 128 davidgb
-- CPU Debug Interface signals
208
--    cpu_reset_o     : out Std_Logic;
209
--    cpu_clk_o       : out Std_Logic;
210
--    cpu_rw_o        : out std_logic;
211
--    cpu_vma_o       : out std_logic;
212
--    cpu_halt_o      : out std_logic;
213
--    cpu_hold_o      : out std_logic;
214
--    cpu_firq_o      : out std_logic;
215
--    cpu_irq_o       : out std_logic;
216
--    cpu_nmi_o       : out std_logic;
217
--    cpu_addr_o      : out std_logic_vector(15 downto 0);
218
--    cpu_data_in_o   : out std_logic_vector(7 downto 0);
219
--    cpu_data_out_o  : out std_logic_vector(7 downto 0);
220
 
221 137 davidgb
    -- Disable Flash
222
    FLASH_CE_N   : out std_logic
223
    );
224 128 davidgb
end system09;
225
 
226
-------------------------------------------------------------------------------
227
-- Architecture for System09
228
-------------------------------------------------------------------------------
229
architecture rtl of system09 is
230
 
231
  -----------------------------------------------------------------------------
232
  -- constants
233 140 davidgb
  -----------------------------------------------------------------------------
234
 
235 128 davidgb
  -- SDRAM
236
  constant MEM_CLK_FREQ         : natural := 100_000; -- operating frequency of Memory in KHz
237
  constant SYS_CLK_DIV          : real    := 2.0;    -- divisor for FREQ (can only be 1.0, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0, 8.0 or 16.0)
238
  constant PIPE_EN              : boolean := false;  -- if true, enable pipelined read operations
239
  constant MAX_NOP              : natural := 10000;  -- number of NOPs before entering self-refresh
240
  constant MULTIPLE_ACTIVE_ROWS : boolean := false;  -- if true, allow an active row in each bank
241
  constant DATA_WIDTH           : natural := 16;     -- host & SDRAM data width
242
  constant NROWS                : natural := 8192;   -- number of rows in SDRAM array
243
  constant NCOLS                : natural := 512;    -- number of columns in SDRAM array
244
  constant HADDR_WIDTH          : natural := 24;     -- host-side address width
245
  constant SADDR_WIDTH          : natural := 13;     -- SDRAM-side address width
246
 
247
  constant SYS_CLK_FREQ         : natural := ((MEM_CLK_FREQ*2)/integer(SYS_CLK_DIV*2.0))*1000;  -- FPGA System Clock
248 140 davidgb
  constant CPU_CLK_FREQ         : natural := 25_000_000;  -- CPU Clock (Hz)
249 128 davidgb
  constant CPU_CLK_DIV          : natural := (SYS_CLK_FREQ/CPU_CLK_FREQ);
250
  constant VGA_CLK_FREQ         : natural := 25_000_000;  -- VGA Pixel Clock
251
  constant VGA_CLK_DIV          : natural := ((MEM_CLK_FREQ*1000)/VGA_CLK_FREQ);
252 137 davidgb
  constant BAUD_RATE            : integer := 57600;     -- Baud Rate
253 140 davidgb
  constant ACIA_CLK_FREQ        : integer := BAUD_RATE * 16;
254
 
255
  constant TRESET               : natural := 300;      -- min initialization interval (us)
256 128 davidgb
  constant RST_CYCLES           : natural := 1+(TRESET*(MEM_CLK_FREQ/1_000));  -- SDRAM power-on initialization interval
257
 
258
  type hold_state_type is ( hold_release_state, hold_request_state );
259
 
260
  -----------------------------------------------------------------------------
261
  -- Signals
262
  -----------------------------------------------------------------------------
263
  -- BOOT ROM
264
  signal rom_cs         : Std_logic;
265
  signal rom_data_out   : Std_Logic_Vector(7 downto 0);
266
 
267
  -- Flex Memory & Monitor Stack
268
  signal flex_cs        : Std_logic;
269
  signal flex_data_out  : Std_Logic_Vector(7 downto 0);
270
 
271
  -- ACIA/UART Interface signals
272
  signal acia_data_out  : Std_Logic_Vector(7 downto 0);
273
  signal acia_cs        : Std_Logic;
274
  signal acia_irq       : Std_Logic;
275
  signal acia_clk       : Std_Logic;
276
  signal rxd            : Std_Logic;
277
  signal txd            : Std_Logic;
278
  signal DCD_n          : Std_Logic;
279
  signal RTS_n          : Std_Logic;
280
  signal CTS_n          : Std_Logic;
281
 
282
  -- keyboard port
283
  signal keyboard_data_out : std_logic_vector(7 downto 0);
284
  signal keyboard_cs       : std_logic;
285
  signal keyboard_irq      : std_logic;
286
 
287
  -- RAM
288
  signal ram_cs         : std_logic; -- memory chip select
289
  signal ram_data_out   : std_logic_vector(7 downto 0);
290 137 davidgb
  signal ram_rd_req     : std_logic; -- ram read request (asynch set on ram read, cleared falling CPU clock edge)
291 128 davidgb
  signal ram_wr_req     : std_logic; -- ram write request (set on rising CPU clock edge, asynch clear on acknowledge) 
292
  signal ram_hold       : std_logic; -- hold off slow accesses
293
  signal ram_release    : std_logic; -- Release ram hold
294
 
295
  -- CPU Interface signals
296
  signal cpu_reset      : Std_Logic;
297
  signal cpu_clk        : Std_Logic;
298
  signal cpu_rw         : std_logic;
299
  signal cpu_vma        : std_logic;
300
  signal cpu_halt       : std_logic;
301
  signal cpu_hold       : std_logic;
302
  signal cpu_firq       : std_logic;
303
  signal cpu_irq        : std_logic;
304
  signal cpu_nmi        : std_logic;
305
  signal cpu_addr       : std_logic_vector(15 downto 0);
306
  signal cpu_data_in    : std_logic_vector(7 downto 0);
307
  signal cpu_data_out   : std_logic_vector(7 downto 0);
308
 
309
  -- Dynamic Address Translation
310
  signal dat_cs       : std_logic;
311
  signal dat_addr     : std_logic_vector(7 downto 0);
312
 
313
  -- Video Display Unit
314
  signal vdu_cs         : std_logic;
315
  signal vdu_data_out   : std_logic_vector(7 downto 0);
316
  signal vga_red_o      : std_logic;
317
  signal vga_green_o    : std_logic;
318
  signal vga_blue_o     : std_logic;
319
 
320
  -- timer
321
  signal timer_data_out : std_logic_vector(7 downto 0);
322
  signal timer_cs       : std_logic;
323
  signal timer_irq      : std_logic;
324
 
325
  -- trap
326
  signal trap_cs        : std_logic;
327
  signal trap_data_out  : std_logic_vector(7 downto 0);
328
  signal trap_irq       : std_logic;
329
 
330
  -- Peripheral Bus port
331
  signal pb_data_out   : std_logic_vector(7 downto 0);
332 137 davidgb
  signal pb_cs         : std_logic;   -- peripheral bus chip select
333
  signal pb_wru        : std_logic;   -- upper byte write strobe
334
  signal pb_wrl        : std_logic;   -- lower byte write strobe
335
  signal pb_rdu        : std_logic;   -- upper byte read strobe
336
  signal pb_rdl        : std_logic;   -- lower byte read strobe
337
  signal pb_hold       : std_logic;   -- hold peripheral bus access
338
  signal pb_release    : std_logic;   -- release hold of peripheral bus
339 128 davidgb
  signal pb_count      : std_logic_vector(3 downto 0); -- hold counter
340
  signal pb_hold_state : hold_state_type;
341
  signal pb_wreg       : std_logic_vector(7 downto 0); -- lower byte write register
342
  signal pb_rreg       : std_logic_vector(7 downto 0); -- lower byte read register
343
 
344
  -- Peripheral chip selects on Peripheral Bus
345
  signal ide_cs        : std_logic; -- IDE CF interface
346 137 davidgb
  signal ether_cs      : std_logic; -- Ethernet interface
347
  signal slot1_cs      : std_logic; -- Expansion slot 1
348
  signal slot2_cs      : std_logic; -- Expansion slot 2
349 128 davidgb
 
350
  signal rst_i         : std_logic;     -- internal reset signal
351
  signal clk_i         : std_logic;     -- internal master clock signal
352
  signal lock          : std_logic;     -- SDRAM clock DLL lock indicator
353
 
354
  -- signals that go through the SDRAM host-side interface
355
  signal opBegun       : std_logic;        -- SDRAM operation started indicator
356
  signal earlyBegun    : std_logic;        -- SDRAM operation started indicator
357
  signal ramDone       : std_logic;        -- SDRAM operation complete indicator
358
  signal rdDone        : std_logic;        -- SDRAM read operation complete indicator
359
  signal wrDone        : std_logic;        -- SDRAM write operation complete indicator
360
  signal hAddr         : std_logic_vector(HADDR_WIDTH-1 downto 0);  -- host address bus
361
  signal hDIn          : std_logic_vector(DATA_WIDTH-1 downto 0);  -- host-side data to SDRAM
362
  signal hDOut         : std_logic_vector(DATA_WIDTH-1 downto 0);  -- host-side data from SDRAM
363
  signal hRd           : std_logic;        -- host-side read control signal
364
  signal hWr           : std_logic;        -- host-side write control signal
365 140 davidgb
  signal hUds          : std_logic;        -- host-side upper data strobe
366
  signal hLds          : std_logic;        -- host-side lower data strobe
367 128 davidgb
  signal rdPending     : std_logic;        -- read operation pending in SDRAM pipeline
368 140 davidgb
  type ram_type is (ram_state_0,
369
                    ram_state_rd1, ram_state_rd2,
370
                    ram_state_wr1,
371 137 davidgb
                    ram_state_3 );
372 128 davidgb
  signal ram_state     : ram_type;
373
 
374 140 davidgb
 
375 128 davidgb
--  signal BaudCount   : std_logic_vector(5 downto 0);
376
  signal CountL        : std_logic_vector(23 downto 0);
377
  signal clk_count     : natural range 0 to CPU_CLK_DIV;
378
  signal Clk25         : std_logic;
379
  signal vga_clk       : std_logic;
380
 
381
-----------------------------------------------------------------
382
--
383
-- CPU09 CPU core
384
--
385
-----------------------------------------------------------------
386
 
387
component cpu09
388
  port (
389 137 davidgb
    clk:      in  std_logic;
390
    rst:      in  std_logic;
391
    vma:      out std_logic;
392
    addr:     out std_logic_vector(15 downto 0);
393
    rw:       out std_logic;     -- Asynchronous memory interface
394
    data_out: out std_logic_vector(7 downto 0);
395
    data_in:  in  std_logic_vector(7 downto 0);
396
    irq:      in  std_logic;
397
    firq:     in  std_logic;
398
    nmi:      in  std_logic;
399
    halt:     in  std_logic;
400
    hold:     in  std_logic
401 128 davidgb
  );
402
end component;
403
 
404
 
405
----------------------------------------
406
--
407
-- 4K Block RAM Monitor ROM
408
--
409
----------------------------------------
410
component mon_rom
411
    Port (
412
       clk   : in  std_logic;
413 137 davidgb
       rst   : in  std_logic;
414
       cs    : in  std_logic;
415
       rw    : in  std_logic;
416 128 davidgb
       addr  : in  std_logic_vector (11 downto 0);
417
       data_out : out std_logic_vector (7 downto 0);
418
       data_in : in  std_logic_vector (7 downto 0)
419
    );
420
end component;
421
 
422
 
423
----------------------------------------
424
--
425
-- 8KBytes Block RAM for FLEX9
426
-- $C000 - $DFFF
427
--
428
----------------------------------------
429
component flex_ram
430
  Port (
431
    clk      : in  std_logic;
432
    rst      : in  std_logic;
433
    cs       : in  std_logic;
434
    rw       : in  std_logic;
435
    addr     : in  std_logic_vector (12 downto 0);
436
    data_out    : out std_logic_vector (7 downto 0);
437
    data_in    : in  std_logic_vector (7 downto 0)
438
    );
439
end component;
440
 
441
-----------------------------------------------------------------
442
--
443
-- 6850 Compatible ACIA / UART
444
--
445
-----------------------------------------------------------------
446
 
447
component acia6850
448
  port (
449
     clk      : in  Std_Logic;  -- System Clock
450
     rst      : in  Std_Logic;  -- Reset input (active high)
451
     cs       : in  Std_Logic;  -- miniUART Chip Select
452
     rw       : in  Std_Logic;  -- Read / Not Write
453
     addr     : in  Std_Logic;  -- Register Select
454
     data_in  : in  Std_Logic_Vector(7 downto 0); -- Data Bus In 
455
     data_out : out Std_Logic_Vector(7 downto 0); -- Data Bus Out
456
     irq      : out Std_Logic;  -- Interrupt
457
     RxC      : in  Std_Logic;  -- Receive Baud Clock
458
     TxC      : in  Std_Logic;  -- Transmit Baud Clock
459
     RxD      : in  Std_Logic;  -- Receive Data
460
     TxD      : out Std_Logic;  -- Transmit Data
461
     DCD_n    : in  Std_Logic;  -- Data Carrier Detect
462
     CTS_n    : in  Std_Logic;  -- Clear To Send
463
     RTS_n    : out Std_Logic );  -- Request To send
464
end component;
465
 
466
 
467
-----------------------------------------------------------------
468
--
469
-- ACIA Clock divider
470
--
471
-----------------------------------------------------------------
472
 
473
component ACIA_Clock
474
  generic (
475
     SYS_CLK_FREQ  : integer :=  SYS_CLK_FREQ;
476 137 davidgb
     ACIA_CLK_FREQ : integer := ACIA_CLK_FREQ
477 128 davidgb
  );
478
  port (
479
     clk      : in  Std_Logic;  -- System Clock Input
480 137 davidgb
     ACIA_clk : out Std_logic   -- ACIA Clock output
481 128 davidgb
  );
482
end component;
483
 
484
 
485
----------------------------------------
486
--
487
-- PS/2 Keyboard
488
--
489
----------------------------------------
490
 
491
component keyboard
492
  generic(
493
  KBD_CLK_FREQ : integer := CPU_CLK_FREQ
494
  );
495
  port(
496
  clk             : in    std_logic;
497
  rst             : in    std_logic;
498
  cs              : in    std_logic;
499
  rw              : in    std_logic;
500
  addr            : in    std_logic;
501
  data_in         : in    std_logic_vector(7 downto 0);
502
  data_out        : out   std_logic_vector(7 downto 0);
503
  irq             : out   std_logic;
504
  kbd_clk         : inout std_logic;
505
  kbd_data        : inout std_logic
506
  );
507
end component;
508
 
509
----------------------------------------
510
--
511
-- Video Display Unit.
512
--
513
----------------------------------------
514
component vdu8
515
      generic(
516
        VDU_CLK_FREQ           : integer := CPU_CLK_FREQ; -- HZ
517
        VGA_CLK_FREQ           : integer := VGA_CLK_FREQ; -- HZ
518 137 davidgb
        VGA_HOR_CHARS          : integer := 80; -- CHARACTERS
519
        VGA_VER_CHARS          : integer := 25; -- CHARACTERS
520
        VGA_PIX_PER_CHAR       : integer := 8;  -- PIXELS
521
        VGA_LIN_PER_CHAR       : integer := 16; -- LINES
522
        VGA_HOR_BACK_PORCH     : integer := 40; -- PIXELS
523
        VGA_HOR_SYNC           : integer := 96; -- PIXELS
524
        VGA_HOR_FRONT_PORCH    : integer := 24; -- PIXELS
525
        VGA_VER_BACK_PORCH     : integer := 13; -- LINES
526
        VGA_VER_SYNC           : integer := 2;  -- LINES
527
        VGA_VER_FRONT_PORCH    : integer := 35  -- LINES
528 128 davidgb
      );
529
      port(
530 137 davidgb
      -- control register interface
531
      vdu_clk      : in  std_logic;  -- CPU Clock - 25MHz
532 128 davidgb
      vdu_rst      : in  std_logic;
533 137 davidgb
      vdu_cs       : in  std_logic;
534
      vdu_rw       : in  std_logic;
535
      vdu_addr     : in  std_logic_vector(2 downto 0);
536 128 davidgb
      vdu_data_in  : in  std_logic_vector(7 downto 0);
537
      vdu_data_out : out std_logic_vector(7 downto 0);
538
 
539
      -- vga port connections
540 137 davidgb
      vga_clk      : in  std_logic; -- VGA Pixel Clock - 25 MHz
541 128 davidgb
      vga_red_o    : out std_logic;
542
      vga_green_o  : out std_logic;
543
      vga_blue_o   : out std_logic;
544
      vga_hsync_o  : out std_logic;
545
      vga_vsync_o  : out std_logic
546
   );
547
end component;
548
 
549
 
550
----------------------------------------
551
--
552
-- Timer module
553
--
554
----------------------------------------
555
 
556
component timer
557
  port (
558
     clk       : in std_logic;
559
     rst       : in std_logic;
560
     cs        : in std_logic;
561
     rw        : in std_logic;
562
     addr      : in std_logic;
563
     data_in   : in std_logic_vector(7 downto 0);
564 137 davidgb
     data_out  : out std_logic_vector(7 downto 0);
565
     irq       : out std_logic
566
     );
567 128 davidgb
end component;
568
 
569
------------------------------------------------------------
570
--
571
-- Bus Trap logic
572
--
573
------------------------------------------------------------
574
 
575
component trap
576 137 davidgb
   port (
577
    clk        : in  std_logic;
578 128 davidgb
    rst        : in  std_logic;
579
    cs         : in  std_logic;
580
    rw         : in  std_logic;
581
    vma        : in  std_logic;
582
    addr       : in  std_logic_vector(15 downto 0);
583
    data_in    : in  std_logic_vector(7 downto 0);
584 137 davidgb
    data_out   : out std_logic_vector(7 downto 0);
585
    irq        : out std_logic
586 128 davidgb
  );
587
end component;
588
 
589
 
590
----------------------------------------
591
--
592
-- Dynamic Address Translation Registers
593
--
594
----------------------------------------
595
component dat_ram
596
  port (
597
    clk      : in  std_logic;
598 137 davidgb
    rst      : in  std_logic;
599
    cs       : in  std_logic;
600
    rw       : in  std_logic;
601
    addr_lo  : in  std_logic_vector(3 downto 0);
602
    addr_hi  : in  std_logic_vector(3 downto 0);
603 128 davidgb
    data_in  : in  std_logic_vector(7 downto 0);
604 137 davidgb
    data_out : out std_logic_vector(7 downto 0)
605 128 davidgb
  );
606
end component;
607
 
608 140 davidgb
 
609 128 davidgb
component XSASDRAMCntl
610
  generic(
611
    FREQ                 :     natural := MEM_CLK_FREQ;-- operating frequency in KHz
612
    CLK_DIV              :     real    := SYS_CLK_DIV; -- divisor for FREQ (can only be 1.0, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0, 8.0 or 16.0)
613
    PIPE_EN              :     boolean := PIPE_EN;     -- if true, enable pipelined read operations
614
    MAX_NOP              :     natural := MAX_NOP;     -- number of NOPs before entering self-refresh
615
    MULTIPLE_ACTIVE_ROWS :     boolean := MULTIPLE_ACTIVE_ROWS;  -- if true, allow an active row in each bank
616
    DATA_WIDTH           :     natural := DATA_WIDTH;  -- host & SDRAM data width
617
    NROWS                :     natural := NROWS;       -- number of rows in SDRAM array
618
    NCOLS                :     natural := NCOLS;       -- number of columns in SDRAM array
619
    HADDR_WIDTH          :     natural := HADDR_WIDTH; -- host-side address width
620
    SADDR_WIDTH          :     natural := SADDR_WIDTH  -- SDRAM-side address width
621
    );
622
  port(
623
    -- host side
624
    clk                  : in  std_logic;  -- master clock
625
    bufclk               : out std_logic;  -- buffered master clock
626
    clk1x                : out std_logic;  -- host clock sync'ed to master clock (and divided if CLK_DIV>1)
627
    clk2x                : out std_logic;  -- double-speed host clock
628
    lock                 : out std_logic;  -- true when host clock is locked to master clock
629
    rst                  : in  std_logic;  -- reset
630
    rd                   : in  std_logic;  -- initiate read operation
631
    wr                   : in  std_logic;  -- initiate write operation
632 140 davidgb
    uds                  : in  std_logic;  -- upper data strobe
633
    lds                  : in  std_logic;  -- lower data strobe
634 128 davidgb
    earlyOpBegun         : out std_logic;  -- read/write/self-refresh op begun     (async)
635
    opBegun              : out std_logic;  -- read/write/self-refresh op begun (clocked)
636
    rdPending            : out std_logic;  -- read operation(s) are still in the pipeline
637
    done                 : out std_logic;  -- read or write operation is done
638
    rdDone               : out std_logic;  -- read done and data is available
639
    hAddr                : in  std_logic_vector(HADDR_WIDTH-1 downto 0);  -- address from host
640
    hDIn                 : in  std_logic_vector(DATA_WIDTH-1 downto 0);  -- data from host
641
    hDOut                : out std_logic_vector(DATA_WIDTH-1 downto 0);  -- data to host
642
    status               : out std_logic_vector(3 downto 0);  -- diagnostic status of the FSM         
643
 
644
    -- SDRAM side
645
    sclkfb               : in    std_logic;           -- clock from SDRAM after PCB delays
646
    sclk                 : out   std_logic;           -- SDRAM clock sync'ed to master clock
647
    cke                  : out   std_logic;           -- clock-enable to SDRAM
648
    cs_n                 : out   std_logic;           -- chip-select to SDRAM
649
    ras_n                : out   std_logic;           -- SDRAM row address strobe
650
    cas_n                : out   std_logic;           -- SDRAM column address strobe
651
    we_n                 : out   std_logic;           -- SDRAM write enable
652
    ba                   : out   std_logic_vector(1 downto 0);  -- SDRAM bank address bits
653
    sAddr                : out   std_logic_vector(SADDR_WIDTH-1 downto 0);  -- SDRAM row/column address
654
    sData                : inout std_logic_vector(DATA_WIDTH-1 downto 0);  -- SDRAM in/out databus
655
    dqmh                 : out   std_logic;           -- high databits I/O mask
656
    dqml                 : out   std_logic            -- low databits I/O mask
657
    );
658
end component;
659 140 davidgb
 
660 128 davidgb
--
661
-- Clock buffer
662
--
663
component BUFG
664
   Port (
665
     i: in std_logic;
666 137 davidgb
     o: out std_logic
667 128 davidgb
  );
668
end component;
669
 
670
begin
671
  -----------------------------------------------------------------------------
672
  -- Instantiation of internal components
673
  -----------------------------------------------------------------------------
674
 
675
my_cpu : cpu09  port map (
676 137 davidgb
    clk       => cpu_clk,
677 128 davidgb
    rst       => cpu_reset,
678
    vma       => cpu_vma,
679
    addr      => cpu_addr(15 downto 0),
680 137 davidgb
    rw        => cpu_rw,
681
    data_out  => cpu_data_out,
682 128 davidgb
    data_in   => cpu_data_in,
683 137 davidgb
    irq       => cpu_irq,
684
    firq      => cpu_firq,
685
    nmi       => cpu_nmi,
686
    halt      => cpu_halt,
687
    hold      => cpu_hold
688 128 davidgb
  );
689
 
690
my_rom : mon_rom port map (
691
       clk   => cpu_clk,
692 137 davidgb
       rst   => cpu_reset,
693
       cs    => rom_cs,
694
       rw    => '1',
695 128 davidgb
       addr  => cpu_addr(11 downto 0),
696
       data_in => cpu_data_out,
697
       data_out => rom_data_out
698
    );
699
 
700
my_flex : flex_ram port map (
701
    clk       => cpu_clk,
702
    rst       => cpu_reset,
703 137 davidgb
    cs        => flex_cs,
704
    rw        => cpu_rw,
705 128 davidgb
    addr      => cpu_addr(12 downto 0),
706
    data_out     => flex_data_out,
707
    data_in     => cpu_data_out
708
    );
709
 
710
my_acia  : acia6850 port map (
711 137 davidgb
    clk       => cpu_clk,
712
    rst       => cpu_reset,
713 128 davidgb
    cs        => acia_cs,
714 137 davidgb
    rw        => cpu_rw,
715 128 davidgb
    addr      => cpu_addr(0),
716 137 davidgb
    data_in   => cpu_data_out,
717
    data_out  => acia_data_out,
718 128 davidgb
    irq       => acia_irq,
719 137 davidgb
    RxC       => acia_clk,
720
    TxC       => acia_clk,
721
    RxD       => rxd,
722
    TxD       => txd,
723
    DCD_n     => dcd_n,
724
    CTS_n     => cts_n,
725
    RTS_n     => rts_n
726
    );
727 128 davidgb
 
728
 
729
my_ACIA_Clock : ACIA_Clock
730
  generic map(
731
    SYS_CLK_FREQ  =>  SYS_CLK_FREQ,
732 137 davidgb
    ACIA_CLK_FREQ => ACIA_CLK_FREQ
733 128 davidgb
  )
734
  port map(
735
    clk        => Clk_i,
736
    acia_clk   => acia_clk
737
  );
738
 
739
----------------------------------------
740
--
741
-- PS/2 Keyboard Interface
742
--
743
----------------------------------------
744
my_keyboard : keyboard
745
   generic map (
746 137 davidgb
   KBD_CLK_FREQ => CPU_CLK_FREQ
747
   )
748 128 davidgb
   port map(
749 137 davidgb
   clk          => cpu_clk,
750
   rst          => cpu_reset,
751
   cs           => keyboard_cs,
752
   rw           => cpu_rw,
753
   addr         => cpu_addr(0),
754
   data_in      => cpu_data_out(7 downto 0),
755
   data_out     => keyboard_data_out(7 downto 0),
756
   irq          => keyboard_irq,
757
   kbd_clk      => ps2_clk,
758
   kbd_data     => ps2_dat
759
   );
760 128 davidgb
 
761
----------------------------------------
762
--
763
-- Video Display Unit instantiation
764
--
765
----------------------------------------
766
my_vdu : vdu8
767
  generic map(
768
      VDU_CLK_FREQ           => CPU_CLK_FREQ, -- HZ
769
      VGA_CLK_FREQ           => VGA_CLK_FREQ, -- HZ
770 137 davidgb
      VGA_HOR_CHARS          => 80, -- CHARACTERS
771
      VGA_VER_CHARS          => 25, -- CHARACTERS
772
      VGA_PIX_PER_CHAR       => 8,  -- PIXELS
773
      VGA_LIN_PER_CHAR       => 16, -- LINES
774
      VGA_HOR_BACK_PORCH     => 40, -- PIXELS
775
      VGA_HOR_SYNC           => 96, -- PIXELS
776
      VGA_HOR_FRONT_PORCH    => 24, -- PIXELS
777
      VGA_VER_BACK_PORCH     => 13, -- LINES
778
      VGA_VER_SYNC           => 2,  -- LINES
779
      VGA_VER_FRONT_PORCH    => 35  -- LINES
780 128 davidgb
  )
781
  port map(
782
 
783 137 davidgb
      -- Control Registers
784
      vdu_clk       => cpu_clk,               -- 12.5 MHz System Clock in
785 128 davidgb
      vdu_rst       => cpu_reset,
786 137 davidgb
      vdu_cs        => vdu_cs,
787
      vdu_rw        => cpu_rw,
788
      vdu_addr      => cpu_addr(2 downto 0),
789
      vdu_data_in   => cpu_data_out,
790
      vdu_data_out  => vdu_data_out,
791 128 davidgb
 
792
      -- vga port connections
793 137 davidgb
      vga_clk       => vga_clk,               -- 25 MHz VDU pixel clock
794 128 davidgb
      vga_red_o     => vga_red_o,
795
      vga_green_o   => vga_green_o,
796
      vga_blue_o    => vga_blue_o,
797
      vga_hsync_o   => vga_hsync_n,
798
      vga_vsync_o   => vga_vsync_n
799
   );
800
 
801
----------------------------------------
802
--
803
-- Timer Module
804
--
805
----------------------------------------
806
my_timer  : timer port map (
807
    clk       => cpu_clk,
808 137 davidgb
    rst       => cpu_reset,
809 128 davidgb
    cs        => timer_cs,
810 137 davidgb
    rw        => cpu_rw,
811 128 davidgb
    addr      => cpu_addr(0),
812 137 davidgb
    data_in   => cpu_data_out,
813
    data_out  => timer_data_out,
814 128 davidgb
    irq       => timer_irq
815
    );
816
 
817
----------------------------------------
818
--
819
-- Bus Trap Interrupt logic
820
--
821
----------------------------------------
822 137 davidgb
my_trap : trap port map (
823
    clk        => cpu_clk,
824 128 davidgb
    rst        => cpu_reset,
825
    cs         => trap_cs,
826
    rw         => cpu_rw,
827 137 davidgb
    vma        => cpu_vma,
828 128 davidgb
    addr       => cpu_addr,
829
    data_in    => cpu_data_out,
830 137 davidgb
    data_out   => trap_data_out,
831
    irq        => trap_irq
832 128 davidgb
    );
833
 
834
 
835
my_dat : dat_ram port map (
836
    clk       => cpu_clk,
837 137 davidgb
    rst       => cpu_reset,
838
    cs        => dat_cs,
839
    rw        => cpu_rw,
840
    addr_hi   => cpu_addr(15 downto 12),
841
    addr_lo   => cpu_addr(3 downto 0),
842 128 davidgb
    data_in   => cpu_data_out,
843 137 davidgb
    data_out  => dat_addr(7 downto 0)
844
    );
845 140 davidgb
 
846 128 davidgb
  ------------------------------------------------------------------------
847
  -- Instantiate the SDRAM controller that connects to the memory tester
848
  -- module and interfaces to the external SDRAM chip.
849
  ------------------------------------------------------------------------
850
  u1 : xsaSDRAMCntl
851
    generic map(
852 140 davidgb
      FREQ                 => MEM_CLK_FREQ,
853 137 davidgb
      CLK_DIV              => SYS_CLK_DIV,
854 140 davidgb
      PIPE_EN              => PIPE_EN,
855 137 davidgb
      MAX_NOP              => MAX_NOP,
856 128 davidgb
      MULTIPLE_ACTIVE_ROWS => MULTIPLE_ACTIVE_ROWS,
857
      DATA_WIDTH           => DATA_WIDTH,
858
      NROWS                => NROWS,
859
      NCOLS                => NCOLS,
860
      HADDR_WIDTH          => HADDR_WIDTH,
861
      SADDR_WIDTH          => SADDR_WIDTH
862
      )
863
    port map(
864 137 davidgb
      -- Host Side
865 128 davidgb
      clk                  => CLKA,     -- master clock from external clock source (unbuffered)
866
      bufclk               => open,     -- buffered master clock output
867
      clk1x                => clk_i,    -- synchronized master clock (accounts for delays to external SDRAM)
868
      clk2x                => open,     -- synchronized doubled master clock
869
      lock                 => lock,     -- DLL lock indicator
870
      rst                  => rst_i,    -- reset
871
      rd                   => hRd,      -- host-side SDRAM read control from memory tester
872
      wr                   => hWr,      -- host-side SDRAM write control from memory tester
873 140 davidgb
      uds                  => hUds,     -- host-side SDRAM upper data strobe
874
      lds                  => hLds,     -- host-side SDRAM lower data strobe
875 128 davidgb
      rdPending            => rdPending,-- read operation to SDRAM is in progress
876
      opBegun              => opBegun,  -- indicates memory read/write has begun
877
      earlyOpBegun         => earlyBegun,  -- early indicator that memory operation has begun
878
      rdDone               => rdDone,   -- indicates SDRAM memory read operation is done
879
      done                 => ramDone, -- indicates SDRAM memory read or write operation is done
880
      hAddr                => hAddr,    -- host-side address from memory tester to SDRAM
881
      hDIn                 => hDIn,     -- test data pattern from memory tester to SDRAM
882
      hDOut                => hDOut,    -- SDRAM data output to memory tester
883
      status               => open,     -- SDRAM controller state (for diagnostics)
884 137 davidgb
      -- SDRAM Side
885 128 davidgb
      sclkfb               => SDRAM_clkfb,    -- clock feedback with added external PCB delays
886
      sclk                 => SDRAM_clkout,   -- synchronized clock to external SDRAM
887
      cke                  => SDRAM_cke,      -- SDRAM clock enable
888
      cs_n                 => SDRAM_cs_n,     -- SDRAM chip-select
889
      ras_n                => SDRAM_ras_n,    -- SDRAM RAS
890
      cas_n                => SDRAM_cas_n,    -- SDRAM CAS
891
      we_n                 => SDRAM_we_n,     -- SDRAM write-enable
892
      ba                   => SDRAM_ba,       -- SDRAM bank address
893
      sAddr                => SDRAM_A,        -- SDRAM address
894
      sData                => SDRAM_D,        -- SDRAM databus
895
      dqmh                 => SDRAM_dqmh,     -- SDRAM DQMH
896
      dqml                 => SDRAM_dqml      -- SDRAM DQML
897
      );
898 140 davidgb
 
899 128 davidgb
cpu_clk_buffer : BUFG port map(
900
    i => Clk25,
901 137 davidgb
    o => cpu_clk
902
    );
903 128 davidgb
 
904
vga_clk_buffer : BUFG port map(
905
    i => Clk25,
906 137 davidgb
    o => vga_clk
907
    );
908
 
909 128 davidgb
----------------------------------------------------------------------
910
--
911
-- Process to decode memory map
912
--
913
----------------------------------------------------------------------
914
 
915
mem_decode: process( cpu_addr, cpu_rw, cpu_vma,
916 137 davidgb
                     dat_addr,
917
                     rom_data_out,
918
                     flex_data_out,
919
                     acia_data_out,
920
                     keyboard_data_out,
921
                     vdu_data_out,
922
                     pb_data_out,
923
                     timer_data_out,
924
                     trap_data_out,
925
                     ram_data_out
926
                     )
927 128 davidgb
begin
928
      cpu_data_in <= (others=>'0');
929
      dat_cs      <= '0';
930
      rom_cs      <= '0';
931
      flex_cs     <= '0';
932 137 davidgb
      acia_cs     <= '0';
933
      keyboard_cs <= '0';
934
      vdu_cs      <= '0';
935
      timer_cs    <= '0';
936
      trap_cs     <= '0';
937
      pb_cs       <= '0';
938
      ide_cs      <= '0';
939
      ether_cs    <= '0';
940
      slot1_cs    <= '0';
941
      slot2_cs    <= '0';
942
      ram_cs      <= '0';
943 128 davidgb
      if cpu_addr( 15 downto 8 ) = "11111111" then
944 137 davidgb
         cpu_data_in <= rom_data_out;
945 128 davidgb
         dat_cs      <= cpu_vma;              -- write DAT
946
         rom_cs      <= cpu_vma;              -- read  ROM
947 137 davidgb
      --
948
      -- Sys09Bug Monitor ROM $F000 - $FFFF
949
      --
950
      elsif dat_addr(3 downto 0) = "1111" then -- $XF000 - $XFFFF
951
         cpu_data_in <= rom_data_out;
952
         rom_cs      <= cpu_vma;
953 128 davidgb
 
954
      --
955 137 davidgb
      -- IO Devices $E000 - $E7FF
956
      --
957
      elsif dat_addr(3 downto 0) = "1110" then -- $XE000 - $XEFFF
958
         case cpu_addr(11 downto 8) is
959
         --
960
         -- SWTPC peripherals from $E000 to $E0FF
961
         --
962
         when "0000" =>
963
           case cpu_addr(7 downto 4) is
964
           --
965
           -- Console Port ACIA $E000 - $E00F
966
           --
967
           when "0000" => -- $E000
968
             cpu_data_in <= acia_data_out;
969
             acia_cs     <= cpu_vma;
970 128 davidgb
 
971
           --
972
           -- Reserved
973 137 davidgb
           -- Floppy Disk Controller port $E010 - $E01F
974
           --
975 128 davidgb
 
976
           --
977
           -- Keyboard port $E020 - $E02F
978 137 davidgb
           --
979
           when "0010" => -- $E020
980 128 davidgb
             cpu_data_in <= keyboard_data_out;
981 137 davidgb
             keyboard_cs <= cpu_vma;
982 128 davidgb
 
983
           --
984
           -- VDU port $E030 - $E03F
985 137 davidgb
           --
986
           when "0011" => -- $E030
987 128 davidgb
             cpu_data_in <= vdu_data_out;
988 137 davidgb
             vdu_cs      <= cpu_vma;
989 128 davidgb
 
990
           --
991 137 davidgb
           -- Reserved SWTPc MP-T Timer $E040 - $E04F
992
           --
993
           when "0100" => -- $E040
994 128 davidgb
             cpu_data_in <= (others=> '0');
995
 
996
           --
997
           -- Timer $E050 - $E05F
998 137 davidgb
           --
999
           when "0101" => -- $E050
1000 128 davidgb
             cpu_data_in <= timer_data_out;
1001
             timer_cs    <= cpu_vma;
1002
 
1003
           --
1004
           -- Bus Trap Logic $E060 - $E06F
1005 137 davidgb
           --
1006
           when "0110" => -- $E060
1007 128 davidgb
             cpu_data_in <= trap_data_out;
1008 137 davidgb
             trap_cs     <= cpu_vma;
1009 128 davidgb
 
1010
           --
1011 137 davidgb
           -- Reserved SWTPc MP-ID PIA Timer/Printer Port $E080 - $E08F
1012
           --
1013 128 davidgb
 
1014
           --
1015 137 davidgb
           -- Reserved SWTPc MP-ID PTM 6840 Timer Port $E090 - $E09F
1016
           --
1017 128 davidgb
 
1018
           --
1019 137 davidgb
           -- Remaining 6 slots reserved for non SWTPc Peripherals
1020
           --
1021
           when others => -- $E0A0 to $E0FF
1022
             null;
1023
           end case;
1024
         --
1025
         -- XST-3.0 Peripheral Bus goes here
1026
         -- $E100 to $E1FF
1027
         -- Four devices
1028
         -- IDE, Ethernet, Slot1, Slot2
1029
         --
1030
         when "0001" =>
1031
           cpu_data_in <= pb_data_out;
1032
           pb_cs       <= cpu_vma;
1033
           case cpu_addr(7 downto 6) is
1034
           --
1035
           -- IDE Interface $E100 to $E13F
1036
           --
1037
           when "00" =>
1038
             ide_cs   <= cpu_vma;
1039
           --
1040
           -- Ethernet Interface $E140 to $E17F
1041
           --
1042
           when "01" =>
1043
             ether_cs <= cpu_vma;
1044
           --
1045
           -- Slot 1 Interface $E180 to $E1BF
1046
           --
1047
           when "10" =>
1048
             slot1_cs <= cpu_vma;
1049
           --
1050
           -- Slot 2 Interface $E1C0 to $E1FF
1051
           --
1052
           when "11" =>
1053
             slot2_cs <= cpu_vma;
1054
           --
1055
           -- Nothing else
1056
           --
1057 128 davidgb
           when others =>
1058 137 davidgb
             null;
1059 128 davidgb
           end case;
1060
         --
1061 137 davidgb
         -- $E200 to $EFFF reserved for future use
1062
         --
1063
         when others =>
1064
           null;
1065 128 davidgb
         end case;
1066 137 davidgb
      --
1067
      -- Flex RAM $0C000 - $0DFFF
1068
      --
1069
      elsif dat_addr(7 downto 1) = "0000110" then -- $0C000 - $0DFFF
1070
         cpu_data_in <= flex_data_out;
1071
         flex_cs     <= cpu_vma;
1072
      --
1073
      -- Everything else is RAM
1074
      --
1075
      else
1076
         cpu_data_in <= ram_data_out;
1077
         ram_cs      <= cpu_vma;
1078
     end if;
1079 128 davidgb
end process;
1080
 
1081
 
1082
--
1083
-- 16-bit Peripheral Bus
1084
-- 6809 Big endian
1085
-- ISA bus little endian
1086
-- Not sure about IDE interface
1087
--
1088 140 davidgb
peripheral_bus: process( clk_i, cpu_reset, cpu_rw, cpu_addr, cpu_data_out,
1089 128 davidgb
                         pb_cs, pb_wreg, pb_rreg )
1090
begin
1091
  pb_wru <= pb_cs and (not cpu_rw) and (not cpu_addr(0));
1092
  pb_wrl <= pb_cs and (not cpu_rw) and      cpu_addr(0) ;
1093
  pb_rdu <= pb_cs and      cpu_rw  and (not cpu_addr(0));
1094
  pb_rdl <= pb_cs and      cpu_rw  and      cpu_addr(0) ;
1095
  pb_a   <= cpu_addr(5 downto 1);
1096
 
1097
  --
1098
  -- Register upper byte from CPU on first CPU write
1099
  -- and lower byte from the peripheral bus on first CPU read
1100
  --
1101
  if cpu_reset = '1' then
1102
    pb_wreg <= (others => '0');
1103
    pb_rreg <= (others => '0');
1104
  elsif clk_i'event and clk_i ='1' then
1105
    if pb_wru = '1' then
1106 137 davidgb
      pb_wreg <= cpu_data_out;
1107 128 davidgb
    end if;
1108
    if pb_rdu = '1' then
1109 137 davidgb
      pb_rreg <= pb_d(7 downto 0);
1110 128 davidgb
    end if;
1111
   end if;
1112
  --
1113
  -- Peripheral bus read and write strobes are
1114
  -- Syncronized with the 50 MHz clock
1115
  -- and are asserted until the peripheral bus hold is released
1116
  --
1117
  if cpu_reset = '1' then
1118
    pb_wr_n <= '1';
1119
    pb_rd_n <= '1';
1120
  elsif clk_i'event and clk_i ='1' then
1121 137 davidgb
    if pb_hold = '1' then
1122
      pb_wr_n  <= not pb_wrl;
1123
      pb_rd_n  <= not pb_rdu;
1124 128 davidgb
    else
1125
      pb_wr_n <= '1';
1126
      pb_rd_n <= '1';
1127
    end if;
1128
  end if;
1129
  --
1130
  -- The peripheral bus will be an output 
1131
  -- the registered even byte on data(15 downto 8)
1132
  -- and the CPU odd bytes on data(7 downto 0)
1133
  -- on odd byte writes
1134
  --
1135
  if pb_wrl = '1' then
1136
    pb_d <= pb_wreg & cpu_data_out;
1137
  else
1138
    pb_d <= (others => 'Z');
1139
  end if;
1140
 
1141
  --
1142
  -- On even byte reads,
1143
  -- the CPU reads the low (even) byte of the peripheral bus
1144
  -- On odd byte reads,
1145
  -- the CPU reads the registered (odd byte) input from the peripheral bus
1146
  --
1147
  if pb_rdu = '1' then
1148
    pb_data_out <= pb_d(15 downto 8);
1149
  elsif pb_rdl = '1' then
1150
    pb_data_out <= pb_rreg;
1151
  else
1152
    pb_data_out <= (others => '0');
1153
  end if;
1154
 
1155
end process;
1156
 
1157
--
1158
-- Hold Peripheral bus accesses for a few cycles
1159
--
1160
peripheral_bus_hold: process( cpu_clk, cpu_reset, pb_rdu, pb_wrl ) --, ether_rdy )
1161
begin
1162
    if cpu_reset = '1' then
1163 137 davidgb
       pb_release    <= '0';
1164
       pb_count      <= "0000";
1165
       pb_hold_state <= hold_release_state;
1166
    elsif rising_edge(cpu_clk) then
1167 128 davidgb
  --
1168
  -- The perpheral bus hold signal should be generated on 
1169
  -- 16 bit bus read which will be on even byte reads or 
1170
  -- 16 bit bus write which will be on odd byte writes.
1171
  -- 
1172 137 davidgb
       case pb_hold_state is
1173
       when hold_release_state =>
1174 128 davidgb
          pb_release <= '0';
1175 137 davidgb
          if (pb_rdu = '1') or (pb_wrl = '1') then
1176
             pb_count      <= "0100";
1177
             pb_hold_state <= hold_request_state;
1178 128 davidgb
          elsif (pb_rdl = '1') or (pb_wru = '1') then
1179
             pb_release    <= '1';
1180 137 davidgb
             pb_hold_state <= hold_release_state;
1181
          end if;
1182 128 davidgb
 
1183 137 davidgb
       when hold_request_state =>
1184
          if pb_count = "0000" then
1185 128 davidgb
--            if ether_rdy = '1' then
1186
              pb_release    <= '1';
1187 137 davidgb
              pb_hold_state <= hold_release_state;
1188 128 davidgb
--            end if;
1189
          else
1190 137 davidgb
             pb_count <= pb_count - "0001";
1191
          end if;
1192 128 davidgb
       when others =>
1193 137 davidgb
          null;
1194 128 davidgb
       end case;
1195 137 davidgb
    end if;
1196 128 davidgb
end process;
1197
 
1198
--
1199
-- Compact Flash Control
1200
--
1201
compact_flash: process( ide_cs, cpu_addr )
1202
begin
1203 137 davidgb
    ide_cs0_n  <= not( ide_cs ) or cpu_addr(4);
1204
    ide_cs1_n  <= not( ide_cs and cpu_addr(4));
1205
    ide_dmack_n  <= '1';
1206 128 davidgb
end process;
1207
 
1208
--
1209
-- Interrupts and other bus control signals
1210
--
1211
interrupts : process( SW3_N,
1212 137 davidgb
                      pb_cs, pb_hold, pb_release, ram_hold,
1213
--                    ether_irq, 
1214 128 davidgb
                      acia_irq,
1215 137 davidgb
                      keyboard_irq,
1216
                      trap_irq,
1217
                      timer_irq
1218
                      )
1219 128 davidgb
begin
1220
    pb_hold    <= pb_cs and (not pb_release);
1221
    cpu_irq    <= acia_irq or keyboard_irq;
1222 137 davidgb
    cpu_nmi    <= trap_irq or not( SW3_N );
1223
    cpu_firq   <= timer_irq;
1224
    cpu_halt   <= '0';
1225
    cpu_hold   <= pb_hold or ram_hold;
1226 128 davidgb
    FLASH_CE_N <= '1';
1227
end process;
1228
 
1229
 
1230
--
1231
-- Flash 7 segment LEDS
1232
--
1233
my_led_flasher: process( clk_i, rst_i, CountL )
1234
begin
1235
    if rst_i = '1' then
1236 137 davidgb
         CountL <= "000000000000000000000000";
1237 128 davidgb
    elsif rising_edge(clk_i) then
1238 137 davidgb
         CountL <= CountL + 1;
1239 128 davidgb
    end if;
1240 137 davidgb
--  S(7 downto 0) <= CountL(23 downto 16);
1241 128 davidgb
end process;
1242
 
1243
--
1244
-- Generate CPU & Pixel Clock from Memory Clock
1245
--
1246
my_prescaler : process( clk_i, clk_count )
1247
begin
1248
  if rising_edge( clk_i ) then
1249
 
1250 140 davidgb
    if clk_count = 0 then
1251
      clk_count <= CPU_CLK_DIV-1;
1252
    else
1253
      clk_count <= clk_count - 1;
1254 128 davidgb
    end if;
1255 140 davidgb
 
1256
    if clk_count = 0 then
1257
       clk25 <= '0';
1258
    elsif clk_count = (CPU_CLK_DIV/2) then
1259
       clk25 <= '1';
1260
    end if;
1261
 
1262
  end if;
1263 128 davidgb
end process;
1264
 
1265
--
1266
-- Reset button and reset timer
1267
--
1268
my_switch_assignments : process( rst_i, SW2_N, lock )
1269
begin
1270 140 davidgb
  rst_i <= not SW2_N;
1271
  cpu_reset <= rst_i or (not lock);
1272 128 davidgb
end process;
1273
 
1274
--
1275
-- RS232 signals:
1276
--
1277
my_acia_assignments : process( RS232_RXD, RS232_CTS, txd, rts_n )
1278
begin
1279
  rxd       <= RS232_RXD;
1280
  cts_n     <= RS232_CTS;
1281
  dcd_n     <= '0';
1282
  RS232_TXD <= txd;
1283
  RS232_RTS <= rts_n;
1284
end process;
1285
 
1286
--
1287
-- Pin assignments for ethernet controller
1288
--
1289
my_ethernet_assignments : process( clk_i, cpu_reset, ether_cs )
1290
begin
1291
    ether_cs_n  <= not ether_cs;
1292
    ether_aen   <= not ether_cs; -- Ethernet address enable not 
1293
    ether_bhe_n <= '1';          -- Ethernet bus high enable - 8 bit access only
1294
end process;
1295
 
1296
--
1297
-- I/O expansion slot assignments
1298
--
1299
my_slot_assignments : process( slot1_cs, slot2_cs)
1300
begin
1301
    slot1_cs_n <= not slot1_cs;
1302
    slot2_cs_n <= not slot2_cs;
1303
end process;
1304
 
1305
--
1306
-- VGA ouputs
1307
--
1308
my_vga_assignments : process( vga_red_o, vga_green_o, vga_blue_o )
1309
begin
1310
  VGA_red(0)   <= vga_red_o;
1311
  VGA_red(1)   <= vga_red_o;
1312
  VGA_red(2)   <= vga_red_o;
1313
  VGA_green(0) <= vga_green_o;
1314
  VGA_green(1) <= vga_green_o;
1315
  VGA_green(2) <= vga_green_o;
1316
  VGA_blue(0)  <= vga_blue_o;
1317
  VGA_blue(1)  <= vga_blue_o;
1318
  VGA_blue(2)  <= vga_blue_o;
1319
end process;
1320 140 davidgb
 
1321 128 davidgb
--
1322
-- SDRAM read write control
1323
--
1324
my_sdram_rw : process( clk_i, cpu_reset,
1325
                       opBegun, ramDone,
1326 137 davidgb
                       ram_state,
1327 128 davidgb
                       ram_rd_req, ram_wr_req )
1328
begin
1329
  if( cpu_reset = '1' ) then
1330 140 davidgb
    hRd        <= '0';
1331 128 davidgb
    hWr        <= '0';
1332 137 davidgb
    ram_hold   <= '0';
1333
    ram_state  <= ram_state_0;
1334 128 davidgb
 
1335
  elsif( falling_edge(clk_i) ) then
1336
    --
1337 137 davidgb
    -- ram state machine
1338
    --
1339 128 davidgb
    case ram_state is
1340
 
1341
    when ram_state_0 =>
1342 137 davidgb
      if ram_rd_req = '1' then
1343 140 davidgb
        ram_hold   <= '1';
1344 137 davidgb
        hRd        <= '1';
1345 140 davidgb
        ram_state  <= ram_state_rd1;
1346
      elsif ram_wr_req = '1' then
1347
        ram_hold   <= '1';
1348
        hWr        <= '1';
1349
        ram_state  <= ram_state_wr1;
1350 128 davidgb
      end if;
1351
 
1352
    when ram_state_rd1 =>
1353 137 davidgb
      if opBegun = '1' then
1354
        hRd        <= '0';
1355
        ram_state  <= ram_state_rd2;
1356 128 davidgb
      end if;
1357
 
1358
    when ram_state_rd2 =>
1359 137 davidgb
      if ramDone = '1' then
1360 140 davidgb
        ram_hold   <= '0';
1361 137 davidgb
        ram_state  <= ram_state_3;
1362
      end if;
1363 128 davidgb
 
1364
    when ram_state_wr1 =>
1365 137 davidgb
      if opBegun = '1' then
1366 140 davidgb
        ram_hold   <= '0';
1367 137 davidgb
        hWr        <= '0';
1368
        ram_state  <= ram_state_3;
1369 128 davidgb
      end if;
1370
 
1371
    when ram_state_3 =>
1372 137 davidgb
      if ram_release = '1' then
1373
        ram_state  <= ram_state_0;
1374 128 davidgb
      end if;
1375
 
1376 137 davidgb
    when others =>
1377
      hRd        <= '0';
1378
      hWr        <= '0';
1379 140 davidgb
      ram_hold   <= '0';
1380 137 davidgb
      ram_state  <= ram_state_0;
1381
    end case;
1382 128 davidgb
 
1383
  end if;
1384
end process;
1385 140 davidgb
 
1386 128 davidgb
--
1387 140 davidgb
-- SDRAM Address and data bus assignments
1388
--
1389 128 davidgb
my_sdram_addr_data : process( cpu_addr, dat_addr,
1390
                                cpu_data_out, hDout )
1391 140 davidgb
begin
1392
  hAddr(23 downto 19)  <= "00000";
1393
  hAddr(18 downto 11)  <= dat_addr;
1394
  hAddr(10 downto 0)   <= cpu_addr(11 downto 1);
1395
  hUds                 <= not cpu_addr(0);
1396
  hLds                 <=     cpu_addr(0);
1397
  if cpu_addr(0) = '0' then
1398
     hDin( 7 downto 0) <= (others=>'0');
1399
     hDin(15 downto 8) <= cpu_data_out;
1400
     ram_data_out      <= hDout(15 downto 8);
1401
  else
1402
     hDin( 7 downto 0) <= cpu_data_out;
1403
     hDin(15 downto 8) <= (others=>'0');
1404
     ram_data_out      <= hDout( 7 downto 0);
1405
  end if;
1406 128 davidgb
end process;
1407 140 davidgb
 
1408 128 davidgb
--
1409
-- Hold RAM until falling CPU clock edge
1410
--
1411
ram_bus_hold: process( cpu_clk, cpu_reset, ram_hold )
1412
begin
1413
    if ram_hold = '1' then
1414 137 davidgb
       ram_release   <= '0';
1415
    elsif falling_edge(cpu_clk) then
1416
       ram_release   <= '1';
1417
    end if;
1418 128 davidgb
end process;
1419 140 davidgb
 
1420 128 davidgb
--
1421
-- CPU read data request on rising CPU clock edge
1422
--
1423
ram_read_request: process( hRd, cpu_clk, ram_cs, cpu_rw, ram_release )
1424
begin
1425 140 davidgb
    if hRd = '1' then
1426 137 davidgb
      ram_rd_req   <= '0';
1427 140 davidgb
    elsif rising_edge(cpu_clk) then
1428 137 davidgb
      if (ram_cs = '1') and (cpu_rw = '1') and (ram_release = '1') then
1429 140 davidgb
        ram_rd_req   <= '1';
1430
      end if;
1431 137 davidgb
    end if;
1432 128 davidgb
end process;
1433 140 davidgb
 
1434 128 davidgb
--
1435
-- CPU write data to RAM valid on rising CPU clock edge
1436
--
1437
ram_write_request: process( hWr, cpu_clk, ram_cs, cpu_rw, ram_release )
1438
begin
1439
    if hWr = '1' then
1440 137 davidgb
       ram_wr_req   <= '0';
1441 140 davidgb
    elsif rising_edge(cpu_clk) then
1442 137 davidgb
      if (ram_cs = '1') and (cpu_rw = '0') and (ram_release = '1') then
1443 140 davidgb
        ram_wr_req   <= '1';
1444 128 davidgb
      end if;
1445 137 davidgb
    end if;
1446 128 davidgb
end process;
1447
 
1448
 
1449
 
1450 140 davidgb
status_leds : process( rst_i, cpu_reset, lock )
1451
begin
1452
    S(0) <= rst_i;
1453
    S(1) <= cpu_reset;
1454
    S(2) <= lock;
1455
    S(3) <= countL(23);
1456
    S(7 downto 4) <= "0000";
1457
end process;
1458
 
1459
--debug_proc : process( cpu_reset, cpu_clk, cpu_rw, cpu_vma,
1460
--                      cpu_halt, cpu_hold,
1461
--                      cpu_firq, cpu_irq, cpu_nmi,
1462
--                      cpu_addr, cpu_data_out, cpu_data_in )
1463
--begin
1464
--  cpu_reset_o    <= cpu_reset;
1465
--  cpu_clk_o      <= cpu_clk;
1466
--  cpu_rw_o       <= cpu_rw;
1467
--  cpu_vma_o      <= cpu_vma;
1468
--  cpu_halt_o     <= cpu_halt;
1469
--  cpu_hold_o     <= cpu_hold;
1470
--  cpu_firq_o     <= cpu_firq;
1471
--  cpu_irq_o      <= cpu_irq;
1472
--  cpu_nmi_o      <= cpu_nmi;
1473
--  cpu_addr_o     <= cpu_addr;
1474
--  cpu_data_out_o <= cpu_data_out;
1475
--  cpu_data_in_o  <= cpu_data_in;
1476
--end process;
1477
 
1478
 
1479 128 davidgb
end rtl; --===================== End of architecture =======================--
1480
 

powered by: WebSVN 2.1.0

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