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

Subversion Repositories light8080

[/] [light8080/] [trunk/] [vhdl/] [soc/] [l80soc.vhdl] - Blame information for rev 70

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

Line No. Rev Author Line
1 70 ja_rd
--##############################################################################
2
-- l80soc : light8080 SOC
3
--##############################################################################
4
-- v1.0    (27 mar 2012) First release. Jose A. Ruiz.
5
--
6
-- This file and all the light8080 project files are freeware (See COPYING.TXT)
7
--##############################################################################
8
-- (See timing diagrams at bottom of file. More comprehensive explainations can 
9
-- be found in the design notes)
10
--##############################################################################
11
 
12
library ieee;
13
use ieee.std_logic_1164.all;
14
use ieee.std_logic_arith.all;
15
use ieee.std_logic_unsigned.all;
16
use work.l80pkg.all;
17
 
18
 
19
--##############################################################################
20
--
21
--##############################################################################
22
entity l80soc is
23
    generic (
24
      OBJ_CODE      : obj_code_t;       -- RAM initialization constant 
25
      RAM_ADDR_SIZE : integer := 12;    -- RAM address width
26
      UART_IRQ_LINE : integer := 4;     -- [0..3] or >3 for none
27
      UART_HARDWIRED: boolean := true;  -- UART baud rate is hardwired
28
      BAUD_RATE     : integer := 19200; -- UART (default) baud rate
29
      CLOCK_FREQ    : integer := 50E6   -- Clock frequency in Hz
30
    );
31
    port (
32
      p1in :          in std_logic_vector(7 downto 0);
33
      p2out :         out std_logic_vector(7 downto 0);
34
 
35
      rxd :           in std_logic;
36
      txd :           out std_logic;
37
 
38
      extint :        in std_logic_vector(3 downto 0);
39
 
40
      clk :           in std_logic;
41
      reset :         in std_logic
42
    );
43
end l80soc;
44
 
45
--##############################################################################
46
--
47
--##############################################################################
48
 
49
architecture hardwired of l80soc is
50
 
51
subtype t_byte is std_logic_vector(7 downto 0);
52
 
53
-- CPU signals -----------------------------------------------------------------
54
 
55
signal cpu_vma :      std_logic;
56
signal cpu_rd :       std_logic;
57
signal cpu_wr :       std_logic;
58
signal cpu_io :       std_logic;
59
signal cpu_fetch :    std_logic;
60
signal cpu_addr :     std_logic_vector(15 downto 0);
61
signal cpu_data_i :   std_logic_vector(7 downto 0);
62
signal cpu_data_o :   std_logic_vector(7 downto 0);
63
signal cpu_intr :     std_logic;
64
signal cpu_inte :     std_logic;
65
signal cpu_inta :     std_logic;
66
signal cpu_halt :     std_logic;
67
 
68
 
69
-- Aux CPU signals -------------------------------------------------------------
70
 
71
-- io_wr: asserted in IO write cycles
72
signal io_wr :        std_logic;
73
-- io_rd: asserted in IO read cycles
74
signal io_rd :        std_logic;
75
-- io_addr: IO port address, lowest 8 bits of address bus
76
signal io_addr :      std_logic_vector(7 downto 0);
77
-- io_rd_data: data coming from IO ports (io input mux)
78
signal io_rd_data :   std_logic_vector(7 downto 0);
79
-- cpu_io_reg: registered cpu_io, used to control mux after cpu_io deasserts
80
signal cpu_io_reg :   std_logic;
81
 
82
-- UART ------------------------------------------------------------------------
83
 
84
signal uart_ce :      std_logic;
85
signal uart_data_rd : std_logic_vector(7 downto 0);
86
signal uart_irq :     std_logic;
87
 
88
 
89
-- RAM -------------------------------------------------------------------------
90
 
91
constant RAM_SIZE : integer := 4096;--2**RAM_ADDR_SIZE;
92
 
93
signal ram_rd_data :  std_logic_vector(7 downto 0);
94
signal ram_we :       std_logic;
95
 
96
signal ram :          ram_t(0 to RAM_SIZE-1) := objcode_to_bram(OBJ_CODE, RAM_SIZE);
97
signal ram_addr :     std_logic_vector(RAM_ADDR_SIZE-1 downto 0);
98
 
99
-- IRQ controller interface ----------------------------------------------------
100
 
101
signal irqcon_we :    std_logic;
102
signal irqcon_data_rd: std_logic_vector(7 downto 0);
103
signal irq :          std_logic_vector(3 downto 0);
104
 
105
 
106
-- IO ports addresses ----------------------------------------------------------
107
 
108
subtype io_addr_t is std_logic_vector(7 downto 0);
109
 
110
constant ADDR_UART_0 : io_addr_t  := X"80"; -- UART registers (80h..83h)
111
constant ADDR_UART_1 : io_addr_t  := X"81"; -- UART registers (80h..83h)
112
constant ADDR_UART_2 : io_addr_t  := X"82"; -- UART registers (80h..83h)
113
constant ADDR_UART_3 : io_addr_t  := X"83"; -- UART registers (80h..83h)
114
constant P1_DATA_REG : io_addr_t  := X"84"; -- port 1 data register 
115
constant P2_DATA_REG : io_addr_t  := X"86"; -- port 2 data register 
116
constant INTR_EN_REG : io_addr_t  := X"88"; -- interrupts enable register 
117
 
118
begin
119
 
120
 
121
  cpu: entity work.light8080
122
  port map (
123
    clk =>      clk,
124
    reset =>    reset,
125
    vma =>      cpu_vma,
126
    rd =>       cpu_rd,
127
    wr =>       cpu_wr,
128
    io =>       cpu_io,
129
    fetch =>    cpu_fetch,
130
    addr_out => cpu_addr,
131
    data_in =>  cpu_data_i,
132
    data_out => cpu_data_o,
133
 
134
    intr =>     cpu_intr,
135
    inte =>     cpu_inte,
136
    inta =>     cpu_inta,
137
    halt =>     cpu_halt
138
  );
139
 
140
  io_rd <= cpu_io and cpu_rd;
141
  io_wr <= '1' when cpu_io='1' and cpu_wr='1' else '0';
142
  io_addr <= cpu_addr(7 downto 0);
143
 
144
  -- Register some control signals that are needed to control multiplexors the
145
  -- cycle after the control signal asserts -- e.g. cpu_io.
146
  control_signal_registers:
147
  process(clk)
148
  begin
149
    if clk'event and clk='1' then
150
      cpu_io_reg <= cpu_io;
151
    end if;
152
  end process control_signal_registers;
153
 
154
  -- Input data mux -- remember, no 3-state buses within the FPGA --------------
155
  cpu_data_i <=
156
      irqcon_data_rd    when cpu_inta = '1' else
157
      io_rd_data        when cpu_io_reg = '1' else
158
      ram_rd_data;
159
 
160
 
161
  -- BRAM ----------------------------------------------------------------------
162
 
163
  ram_we <= '1' when cpu_io='0' and cpu_wr='1' else '0';
164
  ram_addr <= cpu_addr(RAM_ADDR_SIZE-1 downto 0);
165
 
166
  memory:
167
  process(clk)
168
  begin
169
    if clk'event and clk='1' then
170
      if ram_we = '1' then
171
        ram(conv_integer(ram_addr)) <= cpu_data_o;
172
      end if;
173
      ram_rd_data <= ram(conv_integer(ram_addr));
174
    end if;
175
  end process memory;
176
 
177
 
178
  -- Interrupt controller ------------------------------------------------------
179
  -- FIXME interrupts unused in this version
180
 
181
  irq_control: entity work.l80irq
182
  port map (
183
    clk =>          clk,
184
    reset =>        reset,
185
 
186
    irq_i =>        irq,
187
 
188
    data_i =>       cpu_data_o,
189
    data_o =>       irqcon_data_rd,
190
    addr_i =>       cpu_addr(0),
191
    data_we_i =>    irqcon_we,
192
 
193
    cpu_inta_i =>   cpu_inta,
194
    cpu_intr_o =>   cpu_intr,
195
    cpu_fetch_i =>  cpu_fetch
196
  );
197
 
198
  irq_line_connections:
199
  for i in 0 to 3 generate
200
  begin
201
    uart_irq_connection:
202
    if i = UART_IRQ_LINE generate
203
    begin
204
      irq(i) <= uart_irq;
205
    end generate;
206
    other_irq_connections:
207
    if i /= UART_IRQ_LINE generate
208
      irq(i) <= extint(i);
209
    end generate;
210
  end generate irq_line_connections;
211
 
212
  irqcon_we <= '1' when io_addr=INTR_EN_REG and io_wr='1' else '0';
213
 
214
  -- UART -- simple UART with hardwired baud rate ------------------------------
215
  -- NOTE: the serial port does NOT have interrupt capability (yet)
216
 
217
  uart : entity work.uart
218
  generic map (
219
    BAUD_RATE =>      BAUD_RATE,
220
    CLOCK_FREQ =>     CLOCK_FREQ
221
  )
222
  port map (
223
    clk_i =>          clk,
224
    reset_i =>        reset,
225
 
226
    irq_o =>          uart_irq,
227
    data_i =>         cpu_data_o,
228
    data_o =>         uart_data_rd,
229
    addr_i =>         cpu_addr(1 downto 0),
230
 
231
    ce_i =>           uart_ce,
232
    wr_i =>           io_wr,
233
    rd_i =>           io_rd,
234
 
235
    rxd_i =>          rxd,
236
    txd_o =>          txd
237
  );
238
 
239
  -- UART write enable
240
  uart_ce <= '1' when
241
        io_addr(7 downto 2) = ADDR_UART_0(7 downto 2)
242
        else '0';
243
 
244
  -- IO ports -- Simple IO ports with hardcoded direction ----------------------
245
  -- These are meant as an usage example mostly
246
 
247
  output_ports:
248
  process(clk)
249
  begin
250
    if clk'event and clk='1' then
251
      if reset = '1' then
252
        -- Reset values for all io ports
253
        p2out <= (others => '0');
254
      else
255
        if io_wr = '1' then
256
          if conv_integer(io_addr) = P2_DATA_REG then
257
            p2out <= cpu_data_o;
258
          end if;
259
        end if;
260
      end if;
261
    end if;
262
  end process output_ports;
263
 
264
  -- Input IO data multiplexor
265
  with io_addr select io_rd_data <=
266
    p1in            when P1_DATA_REG,
267
    uart_data_rd    when ADDR_UART_0,
268
    uart_data_rd    when ADDR_UART_1,
269
    uart_data_rd    when ADDR_UART_2,
270
    uart_data_rd    when ADDR_UART_3,
271
    irqcon_data_rd  when INTR_EN_REG,
272
    X"00"           when others;
273
 
274
 
275
end hardwired;
276
 

powered by: WebSVN 2.1.0

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