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

Subversion Repositories System09

[/] [System09/] [trunk/] [rtl/] [System09_Xess_XuLA/] [System09_Xess_XuLA.vhd] - Blame information for rev 122

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 122 dilbert57
--=============================================================================--
2
--                                                                             --
3
--  System09 - Synthesizable System On a Chip - VHDL FPGA core top level file. --
4
--                                                                             --
5
--=============================================================================--
6
--
7
--
8
-- File name      : System09_Xess_XuLA.vhd
9
--
10
-- Entity name    : System09
11
--
12
-- Purpose        : Top level file for 6809 compatible system on a chip
13
--                  Designed with Xilinx XC3S200A Spartan 3A FPGA.
14
--                  Implemented with XESS XuLA board
15
--
16
-- Dependencies   : ieee.Std_Logic_1164
17
--                  ieee.std_logic_unsigned
18
--                  ieee.std_logic_arith
19
--                  ieee.numeric_std
20
--
21
-- Uses           : cpu09         (..\VHDL\cpu09.vhd)              CPU core
22
--                  dat_ram       (..\VHDL\datram.vhd)             Dynamic Address Translation
23
--                  SYS09BUG_F800 (..\Spartan3\sys09bug_xes_rom4K_b16.vhd)   Monitor ROM
24
--                  acia6850      (..\VHDL\acia6850.vhd)           ACIA (UART)
25
--                  ACIA_Clock    (..\VHDL\ACIA_Clock.vhd)         ACIA Baud Rate Clock Divider
26
--                  keyboard      (..\VHDL\keyboard.vhd)           PS/2 Keyboard register interface
27
--                  ps2_keyboard  (..\VHDL\ps2_keyboard.vhd)       PS/2 Keyboard interface logic
28
--                  keymap_rom    (..\Spartan3\keymap_rom_b4.vhd)  PS/2 Keyboard key code look up table
29
--                  vdu8          (..\VHDL\vdu8.vhd)                      Video Display Unit
30
--                                (..\Spartan3\char_rom2K_b16.vhd) Character Generator ROM (B16_RAM)
31
--                                (..\Spartan3\ram2k_b16.vhd)      Text & Attribute RAM Buffer
32
-- 
33
-- Author         : John E. Kent      
34
--                  dilbert57@opencores.org      
35
--
36
-- Memory Map     :
37
--
38
-- $0000 - $DFFF System RAM (1MB Mapped via DAT)
39
-- $E000 - ACIA (SWTPc)
40
-- $E010 - Reserved for SWTPc FD-01 FD1771 FDC
41
-- $E020 - Keyboard
42
-- $E030 - VDU
43
-- $E040 - Reserved for SWTPc MP-T (was Compact Flash)
44
-- $E050 - Timer
45
-- $E060 - Reserved for Bus Trap (Hardware Breakpoint Logic)
46
-- $E070 - Reserved for Trace Buffer
47
-- $E080 - Reserved for SWTPc MP-ID 6821 PIA (?)
48
-- $E090 - Reserved for SWTPc MP-ID 6840 PTM (?)
49
-- $E0A0 - Reserved for Switches in / LEDS out
50
-- $E0B0 - IO Port
51
-- $E0C0 - $E0FF Reserved for future I/O
52
-- $E100 - $EFFF Reserved for Future I/O
53
-- $F000 - $F7FF RAM for Sys09bug monitor extensions
54
-- $F800 - $FFFF Sys09bug ROM (Read only)
55
-- $FFF0 - $FFFF DAT - Dynamic Address Translation (Write Only)
56
--
57
--
58
--  Copyright (C) 2011 John Kent
59
--
60
--  This program is free software: you can redistribute it and/or modify
61
--  it under the terms of the GNU General Public License as published by
62
--  the Free Software Foundation, either version 3 of the License, or
63
--  (at your option) any later version.
64
--
65
--  This program is distributed in the hope that it will be useful,
66
--  but WITHOUT ANY WARRANTY; without even the implied warranty of
67
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
68
--  GNU General Public License for more details.
69
--
70
--  You should have received a copy of the GNU General Public License
71
--  along with this program.  If not, see <http://www.gnu.org/licenses/>.
72
--
73
--===========================================================================--
74
--
75
--                              Revision History:
76
--
77
--===========================================================================--
78
--
79
-- Version 0.1 - 20 March 2003
80
-- Version 0.2 - 30 March 2003
81
-- Version 0.3 - 29 April 2003
82
-- Version 0.4 - 29 June 2003
83
--
84
-- Version 0.5 - 19 July 2003
85
-- prints out "Hello World"
86
--
87
-- Version 0.6 - 5 September 2003
88
-- Runs SBUG
89
--
90
-- Version 1.0- 6 Sep 2003 - John Kent
91
-- Inverted SysClk
92
-- Initial release to Open Cores
93
--
94
-- Version 1.1 - 17 Jan 2004 - John Kent
95
-- Updated miniUart.
96
--
97
-- Version 1.2 - 25 Jan 2004 - John Kent
98
-- removed signals "test_alu" and "test_cc" 
99
-- Trap hardware re-instated.
100
--
101
-- Version 1.3 - 11 Feb 2004 - John Kent
102
-- Designed forked off to produce System09_VDU
103
-- Added VDU component
104
--      VDU runs at 25MHz and divides the clock by 2 for the CPU
105
-- UART Runs at 57.6 Kbps
106
--
107
-- Version 2.0 - 2 September 2004 - John Kent
108
-- ported to Digilent Xilinx Spartan3 starter board
109
--      removed Compact Flash and Trap Logic.
110
-- Replaced SBUG with KBug9s
111
--
112
-- Version 3.0 - 29th August 2006 - John Kent
113
-- Adapted to XSA-3S1000 board.
114
-- Removed DAT and miniUART.
115
-- Used 32KBytes of Block RAM.
116
--
117
-- Version 3.1 - 15th January 2007 - John Kent
118
-- Modified vdu8 interface
119
-- Added a clock divider
120
--
121
-- Version 3.2 - 25th February 2007 - John Kent
122
-- reinstated ACIA_6850 and ACIA_Clock
123
-- Updated VDU8 & Keyboard with generic parameters
124
-- Defined Constants for clock speed calculations
125
--
126
-- Version 3.3 - 1st July 2007 - John Kent
127
-- Made VDU mono to save on one RAMB16
128
-- Used distributed memory for Key Map ROM to save one RAMB16
129
-- Added Flex RAM at $C000 to $DFFF using 4 spare RAMB16s
130
-- Added timer and trap logic
131
-- Added IDE Interface for Compact Flash
132
-- Replaced KBug9s and stack with Sys09Bug.
133
--
134
-- Version 4.0 - 1st February 2008 - John kent
135
-- Replaced Block RAM with SDRAM Interface
136
-- Modified Hold timing for SDRAM
137
-- Added CF and Ethernet interface 
138
-- via the 16 bit peripheral bus at $E100
139
--
140
-- Version 5.0 - 30th April 2011
141
-- XESS XSA-3S1000 version Ported to the XESS XuLA board
142
-- Peripheral bus removed
143
-- UDS & LDS removed from SDRAM controller 
144
-- as the XuLA board does not support them
145
-- Updated some of the signal names 
146
-- as the XSA-3S1000 version appears to be out of date.
147
-- Added a DCM clock manager to generate 24MHz CPU & VGA clocks
148
-- and 48MHz system clock for the SDRAM from the 12MHz FPGA clock.
149
-- Removed Flex RAM at $C000-$DFFF although it could be reinstated
150
-- as there are 4 spare 2KByte block RAMs
151
--
152
--===========================================================================--
153
library ieee;
154
   use ieee.std_logic_1164.all;
155
   use IEEE.STD_LOGIC_ARITH.ALL;
156
   use IEEE.STD_LOGIC_UNSIGNED.ALL;
157
   use ieee.numeric_std.all;
158
--library work;
159
--      use work.common.all;
160
--      use WORK.xsasdram.all;
161
library unisim;
162
   use unisim.vcomponents.all;
163
 
164
entity My_System09 is
165
  port(
166
    FPGA_CLK     : in    std_Logic;  -- 12MHz Clock input
167
         SW2_N        : in    std_logic;  -- Master Reset input (active low)
168
         SW3_N        : in    std_logic;  -- Non Maskable Interrupt input (active low)
169
 
170
         -- PS/2 Keyboard
171
         keyb_clk     : inout std_logic;
172
         keyb_dat     : inout std_Logic;
173
 
174
         -- CRTC output signals
175
    vga_red      : out   std_logic;
176
    vga_green    : out   std_logic;
177
    vga_blue     : out   std_logic;
178
    vga_hsync_n  : out   std_Logic;
179
         vga_vsync_n  : out   std_Logic;
180
 
181
    -- RS232 Port
182
         RS232_RXD    : in    std_Logic;
183
         RS232_TXD    : out   std_Logic;
184
    RS232_CTS    : in    std_Logic;
185
    RS232_RTS    : out   std_Logic;
186
 
187
    -- I/O Port
188
         PA           : inout std_logic_vector(7 downto 0);
189
         PB           : inout std_logic_vector(4 downto 0);
190
         PC           : in    std_logic_vector(7 downto 5);
191
 
192
    -- SDRAM side
193
    SDRAM_CLKFB  : in    std_logic;            -- feedback SDRAM clock after PCB delays
194
    SDRAM_CLK    : out   std_logic;            -- clock to SDRAM
195
    SDRAM_RAS_N  : out   std_logic;            -- SDRAM row address strobe
196
    SDRAM_CAS_N  : out   std_logic;            -- SDRAM column address strobe
197
    SDRAM_WE_N   : out   std_logic;            -- SDRAM write enable
198
    SDRAM_BS     : out   std_logic;            -- SDRAM bank address
199
    SDRAM_A      : out   std_logic_vector(11 downto 0);  -- SDRAM row/column address
200
    SDRAM_D      : inout std_logic_vector(15 downto 0)  -- data from SDRAM
201
         );
202
end My_System09;
203
 
204
-------------------------------------------------------------------------------
205
-- Architecture for System09
206
-------------------------------------------------------------------------------
207
architecture rtl of My_System09 is
208
 
209
  -----------------------------------------------------------------------------
210
  -- constants
211
  -----------------------------------------------------------------------------
212
  constant SYS_CLK_FREQ  : integer :=  48_000_000;  -- FPGA System Clock
213
  constant VGA_CLK_FREQ  : integer :=  24_000_000;  -- VGA Pixel Clock
214
  constant CPU_CLK_FREQ  : integer :=  24_000_000;  -- CPU Clock
215
  constant BAUD_RATE     : integer :=      57_600;  -- Baud Rate
216
  constant ACIA_CLK_FREQ : integer := BAUD_RATE * 16;
217
 
218
  type hold_state_type is ( hold_release_state, hold_request_state );
219
 
220
  -----------------------------------------------------------------------------
221
  -- Signals
222
  -----------------------------------------------------------------------------
223
  signal sys_clk        : std_logic;  -- 48MHz system clock
224
  signal rst_n          : std_logic;  -- Master Reset input (active low)
225
  signal nmi_n          : std_logic;  -- Non Maskable Interrupt input (active low)
226
 
227
  -- BOOT ROM
228
  signal rom_cs         : Std_logic;
229
  signal rom_data_out   : Std_Logic_Vector(7 downto 0);
230
 
231
  -- ACIA/UART Interface signals
232
  signal acia_data_out  : Std_Logic_Vector(7 downto 0);
233
  signal acia_cs        : Std_Logic;
234
  signal acia_irq       : Std_Logic;
235
  signal acia_clk       : Std_Logic;
236
  signal rxd            : Std_Logic;
237
  signal txd            : Std_Logic;
238
  signal DCD_n          : Std_Logic;
239
  signal RTS_n          : Std_Logic;
240
  signal CTS_n          : Std_Logic;
241
 
242
  -- Keyboard port
243
  signal key_data_out   : std_logic_vector(7 downto 0);
244
  signal key_cs         : std_logic;
245
  signal key_irq        : std_logic;
246
 
247
  -- IO port
248
  signal iop_data_out   : std_logic_vector(7 downto 0);
249
  signal iop_cs         : std_logic;
250
  signal iop_irq        : std_logic;
251
 
252
  -- RAM
253
  signal ram_cs         : std_logic; -- memory chip select
254
  signal ram_data_out   : std_logic_vector(7 downto 0);
255
  signal ram_hold       : std_logic; -- hold off slow accesses
256
 
257
  -- CPU Interface signals
258
  signal cpu_rst        : Std_Logic;
259
  signal cpu_clk        : Std_Logic;
260
  signal cpu_rw         : std_logic;
261
  signal cpu_vma        : std_logic;
262
  signal cpu_halt       : std_logic;
263
  signal cpu_hold       : std_logic;
264
  signal cpu_firq       : std_logic;
265
  signal cpu_irq        : std_logic;
266
  signal cpu_nmi        : std_logic;
267
  signal cpu_addr       : std_logic_vector(15 downto 0);
268
  signal cpu_data_in    : std_logic_vector(7 downto 0);
269
  signal cpu_data_out   : std_logic_vector(7 downto 0);
270
 
271
  -- Dynamic Address Translation
272
  signal dat_cs       : std_logic;
273
  signal dat_addr     : std_logic_vector(7 downto 0);
274
 
275
  -- Video Display Unit
276
  signal vdu_cs         : std_logic;
277
  signal vdu_data_out   : std_logic_vector(7 downto 0);
278
  signal vga_clk        : std_logic;
279
 
280
  -- timer
281
  signal timer_data_out : std_logic_vector(7 downto 0);
282
  signal timer_cs       : std_logic;
283
  signal timer_irq      : std_logic;
284
 
285
-- SDRAM
286
 
287
  constant  FREQ                 :     natural := (SYS_CLK_FREQ/1000); -- operating frequency in KHz
288
  constant  CLK_DIV              :     real    := 1.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)
289
  constant  PIPE_EN              :     boolean := false;  -- if true, enable pipelined read operations
290
  constant  MAX_NOP              :     natural := 10000;  -- number of NOPs before entering self-refresh
291
  constant  MULTIPLE_ACTIVE_ROWS :     boolean := false;  -- if true, allow an active row in each bank
292
  constant  DATA_WIDTH           :     natural := 16;     -- host & SDRAM data width
293
  constant  NROWS                :     natural := 4096;   -- number of rows in SDRAM array
294
  constant  NCOLS                :     natural := 512;    -- number of columns in SDRAM array
295
  constant  HADDR_WIDTH          :     natural := 24;     -- host-side address width
296
  constant  SADDR_WIDTH          :     natural := 12;     -- SDRAM-side address width
297
 
298
  signal   rst_i        : std_logic;     -- internal reset signal
299
  signal   clk_i        : std_logic;     -- internal master clock signal
300
  signal   clk_b        : std_logic;     -- buffered master clock signal
301
  signal   lock         : std_logic;     -- SDRAM clock DLL lock indicator
302
 
303
  -- signals that go through the SDRAM host-side interface
304
  signal opBegun        : std_logic;        -- SDRAM operation started indicator
305
  signal earlyBegun     : std_logic;        -- SDRAM operation started indicator
306
  signal ramDone        : std_logic;        -- SDRAM operation complete indicator
307
  signal rdDone         : std_logic;        -- SDRAM read operation complete indicator
308
  signal wrDone         : std_logic;        -- SDRAM write operation complete indicator
309
  signal hAddr          : std_logic_vector(HADDR_WIDTH-1 downto 0);  -- host address bus
310
  signal hDIn           : std_logic_vector(DATA_WIDTH-1 downto 0);  -- host-side data to SDRAM
311
  signal hDOut          : std_logic_vector(DATA_WIDTH-1 downto 0);  -- host-side data from SDRAM
312
  signal hRd            : std_logic;        -- host-side read control signal
313
  signal hWr            : std_logic;        -- host-side write control signal
314
  signal rdPending      : std_logic;        -- read operation pending in SDRAM pipeline
315
  signal SDRAM_ba       : std_logic_vector(1 downto 0);
316
 
317
  type ram_rd_type is (rd_state0, rd_state1, rd_state2, rd_state3);
318
  type ram_wr_type is (wr_state0, wr_state1, wr_state2, wr_state3, wr_state4);
319
  signal ram_rd_state   : ram_rd_type;
320
  signal ram_wr_state   : ram_wr_type;
321
 
322
-----------------------------------------------------------------
323
--
324
-- XuLA System clock generator
325
--
326
-----------------------------------------------------------------
327
 
328
component XuLA_clk
329
  generic(
330
        FPGA_CLK_FREQ          : integer := 12000000;     -- 12MHZ
331
             CPU_CLK_FREQ           : integer := CPU_CLK_FREQ; -- 24MHz
332
             VDU_CLK_FREQ           : integer := VGA_CLK_FREQ; -- 24MHz
333
                  RAM_CLK_FREQ           : integer := SYS_CLK_FREQ  -- 48MHz
334
  );
335
  port(
336
    fpga_clk     : in  std_logic;      -- 12MHz FPGA Clock
337
    cpu_clk      : out std_logic;      -- 24MHz CPU clock
338
    vdu_clk      : out std_logic;      -- 24MHz VDU clock
339
         ram_clk      : out std_logic       -- 48MHz RAM clock
340
    );
341
end component;
342
 
343
-----------------------------------------------------------------
344
--
345
-- CPU09 CPU core
346
--
347
-----------------------------------------------------------------
348
 
349
component cpu09
350
  port (
351
         clk:        in std_logic;
352
    rst:      in        std_logic;
353
    rw:      out        std_logic;              -- Asynchronous memory interface
354
    vma:             out        std_logic;
355
    addr:     out       std_logic_vector(15 downto 0);
356
    data_in:  in        std_logic_vector(7 downto 0);
357
         data_out: out std_logic_vector(7 downto 0);
358
         halt:     in  std_logic;
359
         hold:     in  std_logic;
360
         irq:      in  std_logic;
361
         nmi:      in  std_logic;
362
         firq:     in  std_logic
363
  );
364
end component;
365
 
366
 
367
----------------------------------------
368
--
369
-- 4K Block RAM Monitor ROM
370
--
371
----------------------------------------
372
component mon_rom
373
    Port (
374
       clk      : in  std_logic;
375
                 rst      : in  std_logic;
376
                 cs       : in  std_logic;
377
                 rw       : in  std_logic;
378
       addr     : in  std_logic_vector (11 downto 0);
379
       data_in  : in  std_logic_vector (7 downto 0);
380
       data_out : out std_logic_vector (7 downto 0)
381
    );
382
end component;
383
 
384
 
385
-----------------------------------------------------------------
386
--
387
-- 6850 Compatible ACIA / UART
388
--
389
-----------------------------------------------------------------
390
 
391
component acia6850
392
  port (
393
     clk      : in  Std_Logic;  -- System Clock
394
     rst      : in  Std_Logic;  -- Reset input (active high)
395
     cs       : in  Std_Logic;  -- miniUART Chip Select
396
     rw       : in  Std_Logic;  -- Read / Not Write
397
     irq      : out Std_Logic;  -- Interrupt
398
     addr     : in  Std_Logic;  -- Register Select
399
     data_in  : in  Std_Logic_Vector(7 downto 0); -- Data Bus In 
400
     data_out : out Std_Logic_Vector(7 downto 0); -- Data Bus Out
401
     RxC      : in  Std_Logic;  -- Receive Baud Clock
402
     TxC      : in  Std_Logic;  -- Transmit Baud Clock
403
     RxD      : in  Std_Logic;  -- Receive Data
404
     TxD      : out Std_Logic;  -- Transmit Data
405
     DCD_n    : in  Std_Logic;  -- Data Carrier Detect
406
     CTS_n    : in  Std_Logic;  -- Clear To Send
407
     RTS_n    : out Std_Logic );  -- Request To send
408
end component;
409
 
410
 
411
-----------------------------------------------------------------
412
--
413
-- ACIA Clock divider
414
--
415
-----------------------------------------------------------------
416
 
417
component ACIA_Clock
418
  generic (
419
     SYS_CLK_FREQ  : integer :=  SYS_CLK_FREQ;
420
          ACIA_CLK_FREQ : integer := ACIA_CLK_FREQ
421
  );
422
  port (
423
     clk      : in  Std_Logic;  -- System Clock Input
424
          ACIA_clk : out Std_logic   -- ACIA Clock output
425
  );
426
end component;
427
 
428
 
429
----------------------------------------
430
--
431
-- PS/2 Keyboard
432
--
433
----------------------------------------
434
 
435
component keyboard
436
  generic(
437
  KBD_CLK_FREQ : integer := CPU_CLK_FREQ
438
  );
439
  port(
440
     clk       : in    std_logic;
441
     rst       : in    std_logic;
442
     cs        : in    std_logic;
443
     rw        : in    std_logic;
444
     addr      : in    std_logic;
445
     data_in   : in    std_logic_vector(7 downto 0);
446
     data_out  : out   std_logic_vector(7 downto 0);
447
     irq       : out   std_logic;
448
     kbd_clk   : inout std_logic;
449
     kbd_data  : inout std_logic
450
  );
451
end component;
452
 
453
----------------------------------------
454
--
455
-- Video Display Unit.
456
--
457
----------------------------------------
458
component vdu8
459
      generic(
460
        VDU_CLK_FREQ           : integer := CPU_CLK_FREQ; -- HZ
461
        VGA_CLK_FREQ           : integer := VGA_CLK_FREQ; -- HZ
462
             VGA_HOR_CHARS          : integer := 80; -- CHARACTERS
463
             VGA_VER_CHARS          : integer := 25; -- CHARACTERS
464
             VGA_PIX_PER_CHAR       : integer := 8;  -- PIXELS
465
             VGA_LIN_PER_CHAR       : integer := 16; -- LINES
466
             VGA_HOR_BACK_PORCH     : integer := 40; -- PIXELS
467
             VGA_HOR_SYNC           : integer := 96; -- PIXELS
468
             VGA_HOR_FRONT_PORCH    : integer := 24; -- PIXELS
469
             VGA_VER_BACK_PORCH     : integer := 13; -- LINES
470
             VGA_VER_SYNC           : integer := 1;  -- LINES
471
             VGA_VER_FRONT_PORCH    : integer := 36  -- LINES
472
      );
473
      port(
474
                -- control register interface
475
      vdu_clk      : in  std_logic;      -- CPU Clock - 25MHz
476
      vdu_rst      : in  std_logic;
477
                vdu_cs       : in  std_logic;
478
                vdu_rw       : in  std_logic;
479
                vdu_addr     : in  std_logic_vector(2 downto 0);
480
      vdu_data_in  : in  std_logic_vector(7 downto 0);
481
      vdu_data_out : out std_logic_vector(7 downto 0);
482
 
483
      -- vga port connections
484
                vga_clk      : in  std_logic;   -- VGA Pixel Clock - 25 MHz
485
      vga_red_o    : out std_logic;
486
      vga_green_o  : out std_logic;
487
      vga_blue_o   : out std_logic;
488
      vga_hsync_o  : out std_logic;
489
      vga_vsync_o  : out std_logic
490
   );
491
end component;
492
 
493
 
494
----------------------------------------
495
--
496
-- Timer module
497
--
498
----------------------------------------
499
 
500
component timer
501
  port (
502
     clk       : in std_logic;
503
     rst       : in std_logic;
504
     cs        : in std_logic;
505
     rw        : in std_logic;
506
     addr      : in std_logic;
507
     data_in   : in std_logic_vector(7 downto 0);
508
          data_out  : out std_logic_vector(7 downto 0);
509
          irq       : out std_logic
510
          );
511
end component;
512
 
513
----------------------------------------
514
--
515
-- Dynamic Address Translation Registers
516
--
517
----------------------------------------
518
component dat_ram
519
  port (
520
    clk      : in  std_logic;
521
         rst      : in  std_logic;
522
         cs       : in  std_logic;
523
         rw       : in  std_logic;
524
         addr_lo  : in  std_logic_vector(3 downto 0);
525
         addr_hi  : in  std_logic_vector(3 downto 0);
526
    data_in  : in  std_logic_vector(7 downto 0);
527
         data_out : out std_logic_vector(7 downto 0)
528
  );
529
end component;
530
 
531
----------------------------------------
532
--
533
-- SDRAM Interface
534
--
535
----------------------------------------
536
 
537
component XSASDRAMCntl
538
  generic(
539
    FREQ                 :     natural := FREQ;        -- operating frequency in KHz
540
    CLK_DIV              :     real    := 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)
541
    PIPE_EN              :     boolean := PIPE_EN;     -- if true, enable pipelined read operations
542
    MAX_NOP              :     natural := MAX_NOP;     -- number of NOPs before entering self-refresh
543
    MULTIPLE_ACTIVE_ROWS :     boolean := MULTIPLE_ACTIVE_ROWS;  -- if true, allow an active row in each bank
544
    DATA_WIDTH           :     natural := DATA_WIDTH;  -- host & SDRAM data width
545
    NROWS                :     natural := NROWS;       -- number of rows in SDRAM array
546
    NCOLS                :     natural := NCOLS;       -- number of columns in SDRAM array
547
    HADDR_WIDTH          :     natural := HADDR_WIDTH; -- host-side address width
548
    SADDR_WIDTH          :     natural := SADDR_WIDTH  -- SDRAM-side address width
549
    );
550
  port(
551
    -- host side
552
    clk                  : in  std_logic;  -- master clock
553
    bufclk               : out std_logic;  -- buffered master clock
554
    clk1x                : out std_logic;  -- host clock sync'ed to master clock (and divided if CLK_DIV>1)
555
    clk2x                : out std_logic;  -- double-speed host clock
556
    lock                 : out std_logic;  -- true when host clock is locked to master clock
557
    rst                  : in  std_logic;  -- reset
558
    rd                   : in  std_logic;  -- initiate read operation
559
    wr                   : in  std_logic;  -- initiate write operation
560
    earlyOpBegun         : out std_logic;  -- read/write/self-refresh op begun     (async)
561
    opBegun              : out std_logic;  -- read/write/self-refresh op begun (clocked)
562
    rdPending            : out std_logic;  -- read operation(s) are still in the pipeline
563
    done                 : out std_logic;  -- read or write operation is done
564
    rdDone               : out std_logic;  -- read done and data is available
565
    hAddr                : in  std_logic_vector(HADDR_WIDTH-1 downto 0);  -- address from host
566
    hDIn                 : in  std_logic_vector(DATA_WIDTH-1 downto 0);  -- data from host
567
    hDOut                : out std_logic_vector(DATA_WIDTH-1 downto 0);  -- data to host
568
    status               : out std_logic_vector(3 downto 0);  -- diagnostic status of the FSM         
569
 
570
    -- SDRAM side
571
    sclkfb               : in    std_logic;           -- clock from SDRAM after PCB delays
572
    sclk                 : out   std_logic;           -- SDRAM clock sync'ed to master clock
573
    cke                  : out   std_logic;           -- clock-enable to SDRAM
574
    cs_n                 : out   std_logic;           -- chip-select to SDRAM
575
    ras_n                : out   std_logic;           -- SDRAM row address strobe
576
    cas_n                : out   std_logic;           -- SDRAM column address strobe
577
    we_n                 : out   std_logic;           -- SDRAM write enable
578
    ba                   : out   std_logic_vector(1 downto 0);  -- SDRAM bank address bits
579
    sAddr                : out   std_logic_vector(SADDR_WIDTH-1 downto 0);  -- SDRAM row/column address
580
    sData                : inout std_logic_vector(DATA_WIDTH-1 downto 0)  -- SDRAM in/out databus
581
    );
582
end component;
583
 
584
----------------------------------------
585
--
586
-- Parallel I/O port
587
--
588
----------------------------------------
589
 
590
component xula_ioport
591
  port (
592
    clk       : in    std_logic;
593
    rst       : in    std_logic;
594
    cs        : in    std_logic;
595
    rw        : in    std_logic;
596
    addr      : in    std_logic_vector(1 downto 0);
597
    data_in   : in    std_logic_vector(7 downto 0);
598
    data_out  : out   std_logic_vector(7 downto 0);
599
    porta_io  : inout std_logic_vector(7 downto 0);
600
    portb_io  : inout std_logic_vector(4 downto 0);
601
    portc_in  : in    std_logic_vector(7 downto 5);
602
    irq       : out   std_logic
603
  );
604
end component;
605
 
606
--
607
-- Clock buffer
608
--
609
component BUFG
610
   Port (
611
     i: in std_logic;
612
          o: out std_logic
613
  );
614
end component;
615
 
616
begin
617
  -----------------------------------------------------------------------------
618
  -- Instantiation of internal components
619
  -----------------------------------------------------------------------------
620
 
621
my_clk : XuLA_clk port map(
622
    fpga_clk     => fpga_clk,     -- 12MHz FPGA Clock
623
    cpu_clk      => cpu_clk,      -- 24MHz CPU clock
624
    vdu_clk      => vga_clk,      -- 24MHz VDU VGA clock
625
         ram_clk      => sys_clk       -- 48MHz System / RAM clock
626
    );
627
 
628
my_cpu : cpu09  port map (
629
         clk         => cpu_clk,
630
    rst       => cpu_rst,
631
    rw       => cpu_rw,
632
    vma       => cpu_vma,
633
    addr      => cpu_addr(15 downto 0),
634
    data_in   => cpu_data_in,
635
         data_out  => cpu_data_out,
636
         halt      => cpu_halt,
637
         hold      => cpu_hold,
638
         irq       => cpu_irq,
639
         nmi       => cpu_nmi,
640
         firq      => cpu_firq
641
  );
642
 
643
my_rom : mon_rom port map (
644
    clk      => cpu_clk,
645
    rst      => cpu_rst,
646
    cs       => rom_cs,
647
    rw       => '1',
648
    addr     => cpu_addr(11 downto 0),
649
    data_in  => cpu_data_out,
650
    data_out => rom_data_out
651
    );
652
 
653
my_acia  : acia6850 port map (
654
         clk         => cpu_clk,
655
         rst       => cpu_rst,
656
    cs        => acia_cs,
657
         rw        => cpu_rw,
658
    irq       => acia_irq,
659
    addr      => cpu_addr(0),
660
         data_in   => cpu_data_out,
661
         data_out  => acia_data_out,
662
         RxC       => acia_clk,
663
         TxC       => acia_clk,
664
         RxD       => rxd,
665
         TxD       => txd,
666
         DCD_n     => dcd_n,
667
         CTS_n     => cts_n,
668
         RTS_n     => rts_n
669
         );
670
 
671
 
672
my_ACIA_Clock : ACIA_Clock
673
  generic map(
674
    SYS_CLK_FREQ  => SYS_CLK_FREQ,
675
         ACIA_CLK_FREQ => ACIA_CLK_FREQ
676
  )
677
  port map(
678
    clk        => sys_clk,
679
    acia_clk   => acia_clk
680
  );
681
 
682
----------------------------------------
683
--
684
-- PS/2 Keyboard Interface
685
--
686
----------------------------------------
687
my_keyboard : keyboard
688
   generic map (
689
      KBD_CLK_FREQ => CPU_CLK_FREQ
690
        )
691
   port map(
692
      clk          => cpu_clk,
693
      rst          => cpu_rst,
694
      cs           => key_cs,
695
      rw           => cpu_rw,
696
      addr         => cpu_addr(0),
697
      data_in      => cpu_data_out(7 downto 0),
698
      data_out     => key_data_out(7 downto 0),
699
      irq          => key_irq,
700
      kbd_clk      => keyb_clk,
701
      kbd_data     => keyb_dat
702
        );
703
 
704
----------------------------------------
705
--
706
-- Video Display Unit instantiation
707
--
708
----------------------------------------
709
my_vdu : vdu8
710
  generic map(
711
      VDU_CLK_FREQ           => CPU_CLK_FREQ, -- HZ
712
      VGA_CLK_FREQ           => VGA_CLK_FREQ, -- HZ
713
           VGA_HOR_CHARS          => 80, -- CHARACTERS
714
           VGA_VER_CHARS          => 25, -- CHARACTERS
715
           VGA_PIX_PER_CHAR       => 8,  -- PIXELS
716
           VGA_LIN_PER_CHAR       => 16, -- LINES
717
           VGA_HOR_BACK_PORCH     => 40, -- PIXELS
718
           VGA_HOR_SYNC           => 96, -- PIXELS
719
           VGA_HOR_FRONT_PORCH    => 24, -- PIXELS
720
           VGA_VER_BACK_PORCH     => 13, -- LINES
721
           VGA_VER_SYNC           => 1,  -- LINES
722
           VGA_VER_FRONT_PORCH    => 36  -- LINES
723
  )
724
  port map(
725
 
726
                -- Control Registers
727
                vdu_clk       => cpu_clk,
728
      vdu_rst       => cpu_rst,
729
                vdu_cs        => vdu_cs,
730
                vdu_rw        => cpu_rw,
731
                vdu_addr      => cpu_addr(2 downto 0),
732
                vdu_data_in   => cpu_data_out,
733
                vdu_data_out  => vdu_data_out,
734
 
735
      -- vga port connections
736
      vga_clk       => vga_clk,                                  -- 25 MHz VDU pixel clock
737
      vga_red_o     => vga_red,
738
      vga_green_o   => vga_green,
739
      vga_blue_o    => vga_blue,
740
      vga_hsync_o   => vga_hsync_n,
741
      vga_vsync_o   => vga_vsync_n
742
   );
743
 
744
----------------------------------------
745
--
746
-- Timer Module
747
--
748
----------------------------------------
749
my_timer  : timer port map (
750
    clk       => cpu_clk,
751
         rst       => cpu_rst,
752
    cs        => timer_cs,
753
         rw        => cpu_rw,
754
    addr      => cpu_addr(0),
755
         data_in   => cpu_data_out,
756
         data_out  => timer_data_out,
757
    irq       => timer_irq
758
    );
759
 
760
----------------------------------------
761
--
762
-- I/O Port
763
--
764
----------------------------------------
765
 
766
my_ioport : xula_ioport
767
  port map (
768
    clk       => cpu_clk,
769
    rst       => cpu_rst,
770
    cs        => iop_cs,
771
    rw        => cpu_rw,
772
    addr      => cpu_addr(1 downto 0),
773
    data_in   => cpu_data_out,
774
    data_out  => iop_data_out,
775
    porta_io  => pa,
776
    portb_io  => pb(4 downto 0),
777
    portc_in  => pc(7 downto 5),
778
    irq       => iop_irq
779
  );
780
 
781
----------------------------------------
782
--
783
-- Dynamic Address Translation
784
--
785
----------------------------------------
786
 
787
my_dat : dat_ram port map (
788
    clk       => cpu_clk,
789
         rst       => cpu_rst,
790
         cs        => dat_cs,
791
         rw        => cpu_rw,
792
         addr_hi   => cpu_addr(15 downto 12),
793
         addr_lo   => cpu_addr(3 downto 0),
794
    data_in   => cpu_data_out,
795
         data_out  => dat_addr(7 downto 0)
796
         );
797
 
798
  ------------------------------------------------------------------------
799
  -- Instantiate the SDRAM controller that connects to the memory tester
800
  -- module and interfaces to the external SDRAM chip.
801
  ------------------------------------------------------------------------
802
  u1 : xsaSDRAMCntl
803
    generic map(
804
      FREQ                 => FREQ,
805
      CLK_DIV              => CLK_DIV,
806
      PIPE_EN              => PIPE_EN,
807
      MAX_NOP              => MAX_NOP,
808
      DATA_WIDTH           => DATA_WIDTH,
809
      MULTIPLE_ACTIVE_ROWS => MULTIPLE_ACTIVE_ROWS,
810
      NROWS                => NROWS,
811
      NCOLS                => NCOLS,
812
      HADDR_WIDTH          => HADDR_WIDTH,
813
      SADDR_WIDTH          => SADDR_WIDTH
814
      )
815
    port map(
816
           -- Host Side
817
      clk                  => SYS_CLK,  -- master clock from external clock source (unbuffered)
818
      bufclk               => clk_b,    -- buffered master clock output
819
      clk1x                => clk_i,    -- synchronized master clock (accounts for delays to external SDRAM)
820
      clk2x                => open,     -- synchronized doubled master clock
821
      lock                 => lock,     -- DLL lock indicator
822
      rst                  => rst_i,    -- reset
823
      rd                   => hRd,      -- host-side SDRAM read control from memory tester
824
      wr                   => hWr,      -- host-side SDRAM write control from memory tester
825
      rdPending            => rdPending,-- read operation to SDRAM is in progress
826
      opBegun              => opBegun,  -- indicates memory read/write has begun
827
      earlyOpBegun         => earlyBegun,  -- early indicator that memory operation has begun
828
      rdDone               => rdDone,   -- indicates SDRAM memory read operation is done
829
      done                 => ramDone, -- indicates SDRAM memory read or write operation is done
830
      hAddr                => hAddr,    -- host-side address from memory tester to SDRAM
831
      hDIn                 => hDIn,     -- test data pattern from memory tester to SDRAM
832
      hDOut                => hDOut,    -- SDRAM data output to memory tester
833
      status               => open,     -- SDRAM controller state (for diagnostics)
834
                -- SDRAM Side
835
      sclkfb               => SDRAM_clkfb,    -- clock feedback with added external PCB delays
836
      sclk                 => SDRAM_clk,      -- synchronized clock to external SDRAM
837
      cke                  => open,           -- SDRAM clock enable
838
      cs_n                 => open,           -- SDRAM chip-select
839
      ras_n                => SDRAM_ras_n,    -- SDRAM RAS
840
      cas_n                => SDRAM_cas_n,    -- SDRAM CAS
841
      we_n                 => SDRAM_we_n,     -- SDRAM write-enable
842
      ba                   => SDRAM_ba,       -- SDRAM bank address
843
      sAddr                => SDRAM_A,        -- SDRAM address
844
      sData                => SDRAM_D         -- SDRAM databus
845
      );
846
 
847
----------------------------------------------------------------------
848
--
849
-- Process to decode memory map
850
--
851
----------------------------------------------------------------------
852
 
853
mem_decode: process( cpu_clk,
854
                     cpu_addr, cpu_rw, cpu_vma,
855
                                                        dat_addr,
856
                                              rom_data_out,
857
                                                   acia_data_out,
858
                                                        key_data_out,
859
                                                        vdu_data_out,
860
                                                        timer_data_out,
861
                                                        iop_data_out,
862
                                                        ram_data_out
863
                                                        )
864
begin
865
      cpu_data_in <= (others=>'0');
866
      dat_cs      <= '0';
867
      rom_cs      <= '0';
868
           acia_cs     <= '0';
869
           key_cs      <= '0';
870
           vdu_cs      <= '0';
871
           timer_cs    <= '0';
872
                iop_cs      <= '0';
873
           ram_cs      <= '0';
874
      if cpu_addr( 15 downto 8 ) = "11111111" then
875
              cpu_data_in <= rom_data_out;
876
         dat_cs      <= cpu_vma;              -- write DAT
877
         rom_cs      <= cpu_vma;              -- read  ROM
878
           --
879
                -- Sys09Bug Monitor ROM $F000 - $FFFF
880
                --
881
           elsif dat_addr(3 downto 0) = "1111" then -- $XF000 - $XFFFF
882
                   cpu_data_in <= rom_data_out;
883
                        rom_cs      <= cpu_vma;
884
 
885
      --
886
                -- IO Devices $E000 - $E7FF
887
                --
888
                elsif dat_addr(3 downto 0) = "1110" then -- $XE000 - $XEFFF
889
                        case cpu_addr(11 downto 8) is
890
                        --
891
                        -- SWTPC peripherals from $E000 to $E0FF
892
                        --
893
                        when "0000" =>
894
                     case cpu_addr(7 downto 4) is
895
                          --
896
                          -- Console Port ACIA $E000 - $E00F
897
                          --
898
                          when "0000" => -- $E000
899
                       cpu_data_in <= acia_data_out;
900
                            acia_cs     <= cpu_vma;
901
 
902
           --
903
           -- Reserved
904
                          -- Floppy Disk Controller port $E010 - $E01F
905
                          --
906
 
907
           --
908
           -- Keyboard port $E020 - $E02F
909
                          --
910
                          when "0010" => -- $E020
911
             cpu_data_in <= key_data_out;
912
                            key_cs <= cpu_vma;
913
 
914
           --
915
           -- VDU port $E030 - $E03F
916
                          --
917
                          when "0011" => -- $E030
918
             cpu_data_in <= vdu_data_out;
919
                            vdu_cs      <= cpu_vma;
920
 
921
           --
922
                          -- Reserved SWTPc MP-T Timer $E040 - $E04F
923
                          --
924
                          when "0100" => -- $E040
925
             cpu_data_in <= (others=> '0');
926
 
927
           --
928
           -- Timer $E050 - $E05F
929
                          --
930
                          when "0101" => -- $E050
931
             cpu_data_in <= timer_data_out;
932
             timer_cs    <= cpu_vma;
933
 
934
           --
935
           -- Bus Trap Logic $E060 - $E06F
936
                          --
937
                          when "0110" => -- $E060
938
             cpu_data_in <= (others=> '0');
939
 
940
           --
941
                          -- Reserved SWTPc MP-ID PIA Timer/Printer Port $E080 - $E08F
942
                          --
943
 
944
           --
945
                          -- Reserved SWTPc MP-ID PTM 6840 Timer Port $E090 - $E09F
946
                          --
947
 
948
           --
949
           -- IO Port $E0B0 - $E0BF
950
                          --
951
                          when "1011" => -- $E0B0
952
             cpu_data_in <= iop_data_out;
953
             iop_cs    <= cpu_vma;
954
 
955
                          --
956
                          -- Remaining 6 slots reserved for non SWTPc Peripherals
957
                          --
958
                          when others => -- $E0A0 to $E0FF
959
             cpu_data_in <= (others=> '0');
960
                     end case;
961
         --
962
                        --      $E100 to $EFFF reserved for future use
963
                        --
964
                when others =>
965
           cpu_data_in <= (others=> '0');
966
         end case;
967
                --
968
                -- Everything else is RAM
969
                --
970
                else
971
                   cpu_data_in <= ram_data_out;
972
                   ram_cs      <= cpu_vma;
973
          end if;
974
end process;
975
 
976
 
977
--
978
-- Interrupts and other bus control signals
979
--
980
interrupts : process( rst_n, rst_i, nmi_n,
981
                                                         ram_cs, ram_hold,
982
                      acia_irq,
983
                                                         key_irq,
984
                                                         timer_irq,
985
                                                         iop_irq
986
                                                         )
987
begin
988
         cpu_rst <= (not rst_n) or rst_i; -- CPU reset is active high
989
    cpu_irq   <= acia_irq or key_irq;
990
         cpu_nmi   <= not( nmi_n );
991
         cpu_firq  <= timer_irq or iop_irq;
992
         cpu_halt  <= '0';
993
         cpu_hold  <= ram_hold;
994
end process;
995
 
996
--
997
-- Push buttons
998
--
999
my_switch_assignments : process( SW2_N, SW3_N )
1000
begin
1001
  rst_n    <= SW2_N;
1002
  nmi_n    <= SW3_N;
1003
end process;
1004
 
1005
  ------------------------------------------------------------------------
1006
  -- internal reset flag is set active by config. bitstream
1007
  -- and then gets reset after clocks start.
1008
  ------------------------------------------------------------------------
1009
  process(clk_b)
1010
  begin
1011
    if rising_edge(clk_b) then
1012
      if lock = '0' then
1013
        rst_i <= '1';                   -- keep in reset until DLLs start up and lock
1014
      else
1015
        rst_i <= '0';                    -- release reset once DLLs lock
1016
      end if;
1017
    end if;
1018
  end process;
1019
 
1020
--
1021
-- RS232 signals:
1022
--
1023
my_acia_assignments : process( RS232_RXD, RS232_CTS, txd, rts_n )
1024
begin
1025
  rxd       <= RS232_RXD;
1026
  cts_n     <= RS232_CTS;
1027
  dcd_n     <= '0';
1028
  RS232_TXD <= txd;
1029
  RS232_RTS <= rts_n;
1030
end process;
1031
 
1032
--
1033
-- SDRAM assignments
1034
--
1035
my_sdram_assignments : process( cpu_clk, clk_i, cpu_rst,
1036
                                opBegun, rdDone, wrDone,
1037
                                                                                  ram_rd_state, ram_wr_state,
1038
                                cpu_addr, dat_addr,
1039
                                cpu_data_out, hDout,
1040
                                                                                  ram_cs, cpu_rw, ram_hold, SDRAM_ba )
1041
begin
1042
  if( cpu_rst = '1' ) then
1043
    hWr    <= '0';
1044
         hRd    <= '0';
1045
         wrDone <= '0';
1046
         ram_wr_state <= wr_state0;
1047
         ram_rd_state <= rd_state0;
1048
 
1049
  elsif( clk_i'event and clk_i='0' ) then
1050
    --
1051
         -- read state machine
1052
         --
1053
    case ram_rd_state is
1054
 
1055
    when rd_state0 =>
1056
           if (ram_hold = '1') and (cpu_rw = '1') then
1057
                  hRd          <= '1';
1058
                  ram_rd_state <= rd_state1;
1059
      end if;
1060
 
1061
    when rd_state1 =>
1062
           if opBegun = '1' then
1063
                  ram_rd_state <= rd_state2;
1064
      end if;
1065
 
1066
    when rd_state2 =>
1067
           if rdDone = '1' then
1068
                  hRd <= '0';
1069
                  ram_rd_state <= rd_state3;
1070
                end if;
1071
 
1072
    when rd_state3 =>
1073
           if rdDone = '0' then
1074
                  ram_rd_state <= rd_state0;
1075
      end if;
1076
 
1077
         when others =>
1078
                hRd          <= '0';
1079
                ram_rd_state <= rd_state0;
1080
         end case;
1081
 
1082
         --
1083
         -- Write state machine
1084
         --
1085
    case ram_wr_state is
1086
 
1087
    when wr_state0 =>
1088
           if (ram_hold = '1') and (cpu_rw = '0') then
1089
                  hWr          <= '1';
1090
        wrDone       <= '0';
1091
                  ram_wr_state <= wr_state1;
1092
      end if;
1093
 
1094
    when wr_state1 =>
1095
           if opBegun = '1' then
1096
                  hWr          <= '0';
1097
        wrDone       <= '0';
1098
                  ram_wr_state <= wr_state2;
1099
      end if;
1100
 
1101
    when wr_state2 =>
1102
                hWr          <= '0';
1103
      wrDone       <= '0';
1104
                ram_wr_state <= wr_state3;
1105
 
1106
    when wr_state3 =>
1107
                hWr          <= '0';
1108
      wrDone       <= '1';
1109
                ram_wr_state <= wr_state4;
1110
 
1111
    when wr_state4 =>
1112
                hWr          <= '0';
1113
      wrDone       <= '0';
1114
                ram_wr_state <= wr_state0;
1115
 
1116
         when others =>
1117
                hWr          <= '0';
1118
      wrDone       <= '0';
1119
                ram_wr_state <= wr_state0;
1120
 
1121
         end case;
1122
 
1123
  end if;
1124
  --
1125
  -- Strobe host RD and WR signals high on RAM select
1126
  -- Return low when cycle has started
1127
  --
1128
  if( cpu_rst = '1' ) then
1129
         ram_hold     <= '0';
1130
  elsif( cpu_clk'event and cpu_clk='1' ) then
1131
    --
1132
    -- Hold is intitiated when the RAM is selected
1133
    -- and released when access cycle is complete
1134
    -- 
1135
         if (ram_hold = '0') and (ram_cs = '1') then
1136
                ram_hold <= '1';
1137
    elsif (ram_hold = '1') and ((rdDone = '1') or (wrDone = '1')) then
1138
                ram_hold <= '0';
1139
    end if;
1140
  end if;
1141
 
1142
  hAddr(23 downto 20) <= (others=>'0');
1143
  hAddr(19 downto 12) <= dat_addr;
1144
  hAddr(11 downto 0)  <= cpu_addr(11 downto 0);
1145
  hDin( 7 downto 0)   <= cpu_data_out;
1146
  hDin(15 downto 8)   <= (others=>'0');
1147
  ram_data_out        <= hDout(7 downto 0);
1148
  SDRAM_BS            <= SDRAM_ba(0);
1149
end process;
1150
 
1151
end rtl; --===================== End of architecture =======================--
1152
 

powered by: WebSVN 2.1.0

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