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

Subversion Repositories light8080

[/] [light8080/] [trunk/] [vhdl/] [demos/] [4kbasic/] [c2sb_4kbasic_cpu.vhdl] - Blame information for rev 82

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 82 ja_rd
--#############################################################################
2
-- Altair 4K Basic on DE-1 board demo
3
--#############################################################################
4
-- This is enough to run the Altair 4K Basic from internal FPGA RAM.
5
-- The output signals of the DE-1 board are unused except for a reset button,
6
-- a clock input and two seral pins (txd/rxd). it should be easy to port the 
7
-- Altair Basic demo to any other FPGA starter kit.
8
--
9
-- The Altair Basic code is pre-loaded in an internal 4K RAM block. If the code
10
-- becomes corrupted, there's no way to restore it other than reloading the
11
-- FPGA -- a reset will not do.
12
--
13
-- Note there are a few unused registers here and there. They are remnants of
14
-- an unfinished CP/M-on-SD-card demo on which I based the Altair Basic demo.
15
-- You may just ignore them.
16
--#############################################################################
17
-- PORT ADDRESSES:
18
-- 00h : in           status serial port
19
-- 01h : in/out       data serial port
20
-- 23h : out          HEX display, L (not used)
21
-- 24h : out          HEX display, H (not used)
22
-- 40h : in           switches (not used)
23
-- 40h : out          green leds (not used)
24
--
25
-- Serial port status port:
26
-- 01h :              '1' => serial port RX busy
27
-- 80h :              '1' => serial port TX busy
28
--#############################################################################
29
 
30
library ieee;
31
use ieee.std_logic_1164.all;
32
use ieee.std_logic_arith.all;
33
use ieee.std_logic_unsigned.all;
34
 
35
-- Many of the board's i/o devices will go unused
36
entity c2sb_4kbasic_cpu is
37
    port (
38
        -- ***** Clocks
39
        clk_50MHz     : in std_logic;
40
 
41
        -- ***** Flash 4MB
42
        flash_addr    : out std_logic_vector(21 downto 0);
43
        flash_data    : in std_logic_vector(7 downto 0);
44
        flash_oe_n    : out std_logic;
45
        flash_we_n    : out std_logic;
46
        flash_reset_n : out std_logic;
47
 
48
        -- ***** SRAM 256K x 16
49
        sram_addr     : out std_logic_vector(17 downto 0);
50
        sram_data     : inout std_logic_vector(15 downto 0);
51
        sram_oe_n     : out std_logic;
52
        sram_ub_n     : out std_logic;
53
        sram_lb_n     : out std_logic;
54
        sram_ce_n     : out std_logic;
55
        sram_we_n     : out std_logic;
56
 
57
        -- ***** RS-232
58
        rxd           : in std_logic;
59
        txd           : out std_logic;
60
 
61
        -- ***** Switches and buttons
62
        switches      : in std_logic_vector(9 downto 0);
63
        buttons       : in std_logic_vector(3 downto 0);
64
 
65
        -- ***** Quad 7-seg displays
66
        hex0          : out std_logic_vector(0 to 6);
67
        hex1          : out std_logic_vector(0 to 6);
68
        hex2          : out std_logic_vector(0 to 6);
69
        hex3          : out std_logic_vector(0 to 6);
70
 
71
        -- ***** Leds
72
        red_leds      : out std_logic_vector(9 downto 0);
73
        green_leds    : out std_logic_vector(7 downto 0);
74
 
75
        -- ***** SD Card
76
        sd_data       : in  std_logic;
77
        sd_cs         : out std_logic;
78
        sd_cmd        : out std_logic;
79
        sd_clk        : out std_logic
80
    );
81
end c2sb_4kbasic_cpu;
82
 
83
architecture minimal of c2sb_4kbasic_cpu is
84
 
85
component light8080
86
port (
87
  addr_out :  out std_logic_vector(15 downto 0);
88
 
89
  inta :      out std_logic;
90
  inte :      out std_logic;
91
  halt :      out std_logic;
92
  intr :      in std_logic;
93
 
94
  vma :       out std_logic;
95
  io :        out std_logic;
96
  rd :        out std_logic;
97
  wr :        out std_logic;
98
  data_in :   in std_logic_vector(7 downto 0);
99
  data_out :  out std_logic_vector(7 downto 0);
100
 
101
  clk :       in std_logic;
102
  reset :     in std_logic );
103
end component;
104
 
105
-- Serial port, RX 
106
component rs232_rx
107
port(
108
    rxd       : IN std_logic;
109
    read_rx   : IN std_logic;
110
    clk       : IN std_logic;
111
    reset     : IN std_logic;
112
    data_rx   : OUT std_logic_vector(7 downto 0);
113
    rx_rdy    : OUT std_logic
114
    );
115
end component;
116
 
117
-- Serial port, TX
118
component rs232_tx
119
port(
120
    clk       : in std_logic;
121
    reset     : in std_logic;
122
    load      : in std_logic;
123
    data_i    : in std_logic_vector(7 downto 0);
124
    rdy       : out std_logic;
125
    txd       : out std_logic
126
    );
127
end component;
128
 
129
-- Program ROM
130
component c2sb_4kbasic_rom
131
port(
132
    clk       : in std_logic;
133
    addr      : in std_logic_vector(15 downto 0);
134
    we        : in std_logic;
135
    data_in   : in std_logic_vector(7 downto 0);
136
    data_out  : out std_logic_vector(7 downto 0)
137
);
138
end component;
139
 
140
--##############################################################################
141
-- light8080 CPU system signals
142
 
143
signal data_in :          std_logic_vector(7 downto 0);
144
signal vma :              std_logic;
145
signal rd :               std_logic;
146
signal wr  :              std_logic;
147
signal io  :              std_logic;
148
signal data_out :         std_logic_vector(7 downto 0);
149
signal addr :             std_logic_vector(15 downto 0);
150
signal inta :             std_logic;
151
signal inte :             std_logic;
152
signal intr :             std_logic;
153
signal halt :             std_logic;
154
 
155
-- signals for sram 'synchronization' 
156
signal sram_data_out :    std_logic_vector(7 downto 0); -- sram output reg
157
signal sram_write :       std_logic; -- sram we register
158
 
159
-- signals for debug
160
signal address_reg :      std_logic_vector(15 downto 0); -- registered addr bus
161
 
162
signal rs_tx_data :       std_logic_vector(7 downto 0);
163
 
164
--##############################################################################
165
-- General I/O control signals
166
 
167
signal io_q :             std_logic;
168
signal rd_q :             std_logic;
169
signal io_read :          std_logic;
170
signal io_write :         std_logic;
171
signal low_ram_we :       std_logic;
172
 
173
--##############################################################################
174
-- RS232 signals
175
 
176
signal rx_rdy :           std_logic;
177
signal tx_rdy :           std_logic;
178
signal rs232_data_rx :    std_logic_vector(7 downto 0);
179
signal rs232_status :     std_logic_vector(7 downto 0);
180
signal data_io_out :      std_logic_vector(7 downto 0);
181
signal io_port :          std_logic_vector(7 downto 0);
182
signal read_rx :          std_logic;
183
signal write_tx :         std_logic;
184
 
185
 
186
--##############################################################################
187
-- Application signals
188
 
189
-- general control port (rom paging)
190
signal reg_control :      std_logic_vector(7 downto 0);
191
 
192
-- CPU access to hex display (unused by Altair SW)
193
signal reg_display_h :    std_logic_vector(7 downto 0);
194
signal reg_display_l :    std_logic_vector(7 downto 0);
195
 
196
 
197
--##############################################################################
198
-- Quad 7-segment display (non multiplexed) & LEDS
199
 
200
signal display_data :     std_logic_vector(15 downto 0);
201
signal reg_gleds :        std_logic_vector(7 downto 0);
202
 
203
-- i/o signals
204
signal data_io_in :       std_logic_vector(7 downto 0);
205
signal data_mem_in :      std_logic_vector(7 downto 0);
206
signal data_rom_in :      std_logic_vector(7 downto 0);
207
signal rom_access :       std_logic;
208
signal rom_space :        std_logic;
209
signal breakpoint :       std_logic;
210
 
211
 
212
-- Clock & reset signals
213
signal clk_1hz :          std_logic;
214
signal clk_master :       std_logic;
215
signal counter_1hz :      std_logic_vector(25 downto 0);
216
signal reset :            std_logic;
217
signal clk :              std_logic;
218
 
219
-- SD control signals
220
signal sd_in :            std_logic;
221
signal reg_sd_dout :      std_logic;
222
signal reg_sd_clk :       std_logic;
223
signal reg_sd_cs :        std_logic;
224
 
225
begin
226
 
227
-- CS for the lowest 4K block
228
low_ram_we <= '1' when wr='1' and io='0' and addr(15 downto 12)="0000" else '0';
229
 
230
-- program ROM. Note the 'ROM' is actually initialized RAM
231
program_rom : c2sb_4kbasic_rom port map(
232
    clk =>      clk,
233
    addr =>     addr,
234
    we =>       low_ram_we,
235
    data_in =>  data_out,
236
    data_out => data_rom_in
237
  );
238
 
239
-- rom CS decoder
240
rom_space <= '1' when (reg_control(0)='0' and addr(15 downto 12) = "0000")
241
             else  '0';
242
 
243
-- registered rom CS 
244
process(clk)
245
begin
246
  if (clk'event and clk='1') then
247
    if reset='1' then
248
      rom_access <= '1';
249
      breakpoint <= '0';
250
    else
251
      if rd='1' and rom_space='1' then
252
        rom_access <= '1';
253
      else
254
        rom_access <= '0';
255
      end if;
256
 
257
    end if;
258
  end if;
259
end process;
260
 
261
-- rom vs ram mux: hardwired to always use the internal RAM (or ROM)
262
data_mem_in <=  data_rom_in; -- when rom_access='1' else
263
                --sram_data(7 downto 0);
264
 
265
 
266
-- output port registers, all unused except for the serial io
267
process(clk)
268
begin
269
  if (clk'event and clk='1') then
270
    if reset='1' then
271
      reg_gleds   <= X"00";
272
      reg_control <= X"00";
273
      reg_display_h <= X"00";
274
      reg_display_l <= X"00";
275
      reg_sd_dout <= '0';
276
      reg_sd_clk <= '0';
277
      reg_sd_cs <= '0';
278
    else
279
      if io_write='1' then
280
        if addr(7 downto 0)=X"40" then
281
          reg_gleds <= data_out;
282
        end if;
283
        if addr(7 downto 0)=X"23" then
284
          reg_display_l <= data_out;
285
        end if;
286
        if addr(7 downto 0)=X"24" then
287
          reg_display_h <= data_out;
288
        end if;
289
      end if;
290
    end if;
291
  end if;
292
end process;
293
 
294
 
295
-- The interrupt is unused in the Altair 4K Basic demo
296
intr <= '0';
297
 
298
-- CPU instance
299
cpu: light8080 port map(
300
    clk => clk,
301
    reset => reset,
302
    vma => vma,
303
    rd => rd,
304
    wr => wr,
305
    io => io,
306
    addr_out => addr,
307
    data_in => data_in,
308
    data_out => data_out,
309
    intr => intr,
310
    inte => inte,
311
    inta => inta,
312
    halt => halt
313
);
314
 
315
 
316
-- delayed (registered) control signals, plus data synchronization registers 
317
process(clk)
318
begin
319
  if clk'event and clk = '1' then
320
    if reset = '1' then
321
      io_q <= '0';
322
      rd_q <= '0';
323
      io_port <= X"00";
324
      data_io_out <= X"00";
325
    else
326
      io_q <= io;
327
      rd_q <= rd;
328
      io_port <= addr(7 downto 0);
329
      data_io_out <= data_out;
330
    end if;
331
  end if;
332
end process;
333
 
334
-- red leds (light with '1') -- some CPU control signals 
335
red_leds(0) <= halt;
336
red_leds(1) <= inte;
337
red_leds(2) <= vma;
338
red_leds(3) <= rd;
339
red_leds(4) <= wr;
340
 
341
red_leds(5) <= inta;
342
red_leds(6) <= clk_1hz;-- intr;
343
red_leds(7) <= rom_space;
344
red_leds(8) <= rx_rdy;
345
red_leds(9) <= tx_rdy;
346
 
347
 
348
--##### Input ports ###########################################################
349
 
350
-- mem vs. io input mux (note IRQ vector is hardwired to FFh)
351
data_in <=  data_io_in    when io_q='1' and inta='0' else -- I/O port data 
352
            data_mem_in   when io_q='0' and inta='0' else -- MEM data
353
            X"ff";                                        -- IRQ vector (RST 7)
354
 
355
-- io read enable (for async io ports; data read in cycle following io='1')
356
io_read <= '1' when io_q='1' and rd_q='1' else '0';
357
 
358
-- io write enable (for sync io ports; data written in cycle following io='1') 
359
io_write <= '1' when io='1' and wr='1' else '0';
360
 
361
-- read/write signals for rs232 modules
362
read_rx <=  '1' when io_read='1' and addr(7 downto 0)=X"01" else '0';
363
write_tx <= '1' when io_write='1' and addr(7 downto 0)=X"01" else '0';
364
 
365
-- synchronized input port mux (using registered port address)
366
with io_port(7 downto 0) select data_io_in <=
367
  -- Altair serial input status port
368
  rs232_status                            when X"00",
369
  -- Altair serial input data port, with MSB cleared 
370
  "0" & rs232_data_rx(6 DOWNTO 0)         when X"01",
371
  -- Some other ports unused by the 4K Basic code
372
  --sd_in & "0000000"                       when X"88",
373
  switches(7 downto 0)                    when others;
374
 
375
 
376
--##############################################################################
377
-- terasIC Cyclone II STARTER KIT BOARD
378
--##############################################################################
379
 
380
--##############################################################################
381
-- FLASH (flash is unused in this demo)
382
--##############################################################################
383
 
384
flash_addr <= (others => '0');
385
 
386
flash_we_n <= '1'; -- all enable signals inactive
387
flash_oe_n <= '1';
388
flash_reset_n <= '1';
389
 
390
 
391
--##############################################################################
392
-- SRAM (used as 64K x 8)
393
--
394
-- NOTE: All writes go to SRAM independent of rom paging status
395
--##############################################################################
396
 
397
process(clk)
398
begin
399
  if clk'event and clk='1' then
400
    if reset='1' then
401
      sram_addr <= "000000000000000000";
402
      address_reg <= "0000000000000000";
403
      sram_data_out <= X"00";
404
      sram_write <= '0';
405
    else
406
      -- load address register
407
      if vma='1' and io='0' then
408
        sram_addr <= "00" & addr;
409
        address_reg <= addr;
410
      end if;
411
      -- load data and write enable registers 
412
      if vma='1' and wr='1' and io='0' then
413
        sram_data_out <= data_out;
414
        sram_write <= '1';
415
      else
416
        sram_write <= '0';
417
      end if;
418
    end if;
419
  end if;
420
end process;
421
 
422
sram_data(15 downto 8) <= "ZZZZZZZZ"; -- high byte unused
423
sram_data(7 downto 0)  <= "ZZZZZZZZ" when sram_write='0' else sram_data_out;
424
-- (the X"ZZ" will physically be the read input data)
425
 
426
-- sram access controlled by WE_N
427
sram_oe_n <= '0';
428
sram_ce_n <= '0';
429
sram_we_n <= not sram_write;
430
sram_ub_n <= '1'; -- always disable
431
sram_lb_n <= '0';
432
 
433
--##############################################################################
434
-- RESET, CLOCK
435
--##############################################################################
436
 
437
-- Use button 3 as reset
438
reset <= not buttons(3);
439
 
440
 
441
-- Generate a 1-Hz 'clock' to flash a LED for visual reference.
442
process(clk_50MHz)
443
begin
444
  if clk_50MHz'event and clk_50MHz='1' then
445
    if reset = '1' then
446
      clk_1hz <= '0';
447
      counter_1hz <= (others => '0');
448
    else
449
      if conv_integer(counter_1hz) = 50000000 then
450
        counter_1hz <= (others => '0');
451
        clk_1hz <= not clk_1hz;
452
      else
453
        counter_1hz <= counter_1hz + 1;
454
      end if;
455
    end if;
456
  end if;
457
end process;
458
 
459
-- Master clock is external 50MHz oscillator
460
clk <= clk_50MHz;
461
 
462
 
463
--##############################################################################
464
-- LEDS, SWITCHES
465
--##############################################################################
466
 
467
-- Display the contents of a debug register at the green leds bar
468
green_leds <= reg_gleds;
469
 
470
 
471
--##############################################################################
472
-- QUAD 7-SEGMENT DISPLAYS
473
--##############################################################################
474
 
475
-- We'll be displaying valid memory addresses in the hex display.
476
process(clk)
477
begin
478
  if clk'event and clk='1' then
479
    if vma = '1' then
480
      display_data <= addr(15 downto 0);
481
    end if;
482
  end if;
483
end process;
484
 
485
-- alternatively, we might display the contents of some debug registers
486
--display_data <= addr(15 downto 0) when switches(9)='1' else
487
--                reg_display_h & reg_display_l;
488
 
489
-- 7-segment encoders; the dev board displays are not multiplexed or encoded
490
with display_data(15 downto 12) select hex3 <=
491
"0000001" when X"0","1001111" when X"1","0010010" when X"2","0000110" when X"3",
492
"1001100" when X"4","0100100" when X"5","0100000" when X"6","0001111" when X"7",
493
"0000000" when X"8","0000100" when X"9","0001000" when X"a","1100000" when X"b",
494
"0110001" when X"c","1000010" when X"d","0110000" when X"e","0111000" when others;
495
 
496
with display_data(11 downto 8) select hex2 <=
497
"0000001" when X"0","1001111" when X"1","0010010" when X"2","0000110" when X"3",
498
"1001100" when X"4","0100100" when X"5","0100000" when X"6","0001111" when X"7",
499
"0000000" when X"8","0000100" when X"9","0001000" when X"a","1100000" when X"b",
500
"0110001" when X"c","1000010" when X"d","0110000" when X"e","0111000" when others;
501
 
502
with display_data(7 downto 4) select hex1 <=
503
"0000001" when X"0","1001111" when X"1","0010010" when X"2","0000110" when X"3",
504
"1001100" when X"4","0100100" when X"5","0100000" when X"6","0001111" when X"7",
505
"0000000" when X"8","0000100" when X"9","0001000" when X"a","1100000" when X"b",
506
"0110001" when X"c","1000010" when X"d","0110000" when X"e","0111000" when others;
507
 
508
with display_data(3 downto 0) select hex0 <=
509
"0000001" when X"0","1001111" when X"1","0010010" when X"2","0000110" when X"3",
510
"1001100" when X"4","0100100" when X"5","0100000" when X"6","0001111" when X"7",
511
"0000000" when X"8","0000100" when X"9","0001000" when X"a","1100000" when X"b",
512
"0110001" when X"c","1000010" when X"d","0110000" when X"e","0111000" when others;
513
 
514
--##############################################################################
515
-- SD card interface
516
--##############################################################################
517
 
518
-- unused in this demo, but I did not bother to cut away the attached registers
519
sd_cs     <= reg_sd_cs;
520
sd_cmd    <= reg_sd_dout;
521
sd_clk    <= reg_sd_clk;
522
sd_in     <= sd_data;
523
 
524
 
525
--##############################################################################
526
-- SERIAL
527
--##############################################################################
528
 
529
serial_rx : rs232_rx port map(
530
    rxd => rxd,
531
    data_rx => rs232_data_rx,
532
    rx_rdy => rx_rdy,
533
    read_rx => read_rx,
534
    clk => clk,
535
    reset => reset
536
  );
537
 
538
-- Clear the MSB so the terminal gets clean ASCII codes
539
rs_tx_data <= "0" & data_out(6 downto 0);
540
 
541
serial_tx : rs232_tx port map(
542
    clk => clk,
543
    reset => reset,
544
    rdy => tx_rdy,
545
    load => write_tx,
546
    data_i => rs_tx_data,
547
    txd => txd
548
  );
549
 
550
rs232_status <= (not tx_rdy) & "000000" & (not rx_rdy);
551
 
552
end minimal;

powered by: WebSVN 2.1.0

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