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

Subversion Repositories System09

[/] [System09/] [tags/] [LinuxPort/] [rtl/] [VHDL/] [unicpu09.vhd] - Blame information for rev 82

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 65 davidgb
--===========================================================================----
2
--
3
--  S Y N T H E Z I A B L E    unicpu09.vhd - Single 6809 processor core
4
--
5
--===========================================================================----
6
--
7
--  This core adheres to the GNU public license  
8
--
9
-- File name      : System09.vhd
10
--
11
-- Purpose        : Top level file for Hex Core 6809 compatible system on a chip
12
--                  Designed with Xilinx XC3S1000 Spartan 3 FPGA.
13
--                  Implemented With Digilent Xilinx Starter FPGA board,
14
--
15
-- Dependencies   : ieee.Std_Logic_1164
16
--                  ieee.std_logic_unsigned
17
--                  ieee.std_logic_arith
18
--                  ieee.numeric_std
19
--
20
-- Uses           : 
21
--                  cpu09  (cpu09.vhd)           6809 CPU core
22
-- 
23
-- Author         : John E. Kent      
24
--                  dilbert57@opencores.org      
25
--
26
--===========================================================================----
27
--
28
-- Revision History:
29
--
30
--===========================================================================--
31
-- Version 0.1 - 20 March 2003
32
--
33
--===========================================================================--
34
library ieee;
35
   use ieee.std_logic_1164.all;
36
   use IEEE.STD_LOGIC_ARITH.ALL;
37
   use IEEE.STD_LOGIC_UNSIGNED.ALL;
38
   use ieee.numeric_std.all;
39
library unisim;
40
        use unisim.vcomponents.all;
41
 
42
entity unicpu09 is
43
 
44
  port(
45
         clk      :     in  std_logic;
46
    rst      : in  std_logic;
47
         --
48
         -- cpu side signals
49
         --
50
    rw       : out std_logic;
51
    vma      : out std_logic;
52
    addr     : out std_logic_vector(19 downto 0);
53
    id       : in  std_logic_vector( 7 downto 0);
54
         --
55
         -- memory side signals
56
         --
57
    mem_rw   : in  std_logic;
58
    mem_vma  :  in  std_logic;
59
    mem_addr : in  std_logic_vector(19 downto 0);
60
    mem_dati : in        std_logic_vector(7 downto 0);
61
         mem_dato : out std_logic_vector(7 downto 0);
62
         --
63
         -- controls
64
         --
65
         halt     : in  std_logic;
66
         hold     : in  std_logic;
67
         irq      : in  std_logic;
68
         nmi      : in  std_logic;
69
         firq     : in  std_logic
70
    );
71
end entity;
72
 
73
-------------------------------------------------------------------------------
74
-- Architecture for System09
75
-------------------------------------------------------------------------------
76
architecture RTL of unicpu09 is
77
 
78
  -- CPU Interface signals
79
  signal cpu_rw       : std_logic;
80
  signal cpu_vma      : std_logic;
81
  signal cpu_addr     : std_logic_vector(15 downto 0);
82
  signal cpu_dati     : std_logic_vector(7 downto 0);
83
  signal cpu_dato     : std_logic_vector(7 downto 0);
84
 
85
  -- BOOT ROM
86
  signal rom_cs        : Std_logic;
87
  signal rom_dato      : Std_Logic_Vector(7 downto 0);
88
 
89
  -- cache host signals
90
  signal cache_cpu_addr : std_logic_vector(31 downto 0);
91
  signal cache_cpu_dati : std_logic_vector(15 downto 0);
92
  signal cache_cpu_dato : std_logic_vector(15 downto 0);
93
  signal cache_cpu_vma  : std_logic;
94
  signal cache_cpu_en   : std_logic;
95
 
96
  -- cache memory signals
97
  signal cache_mem_addr : std_logic_vector(31 downto 0);
98
  signal cache_mem_dati : std_logic_vector(15 downto 0);
99
  signal cache_mem_dato : std_logic_vector(15 downto 0);
100
  signal cache_mem_vma  : std_logic;
101
 
102
  -- Dynamic Address Translation
103
  signal dat_cs       : std_logic;
104
  signal dat_addr     : std_logic_vector(15 downto 0);
105
 
106
  -- 32 bit harware multiplier
107
  signal mul_cs       : std_logic;
108
  signal mul_dato     : std_logic_vector(7 downto 0);
109
 
110
  -- external access
111
  signal ext_cs       : std_logic;
112
  signal ext_dato     : std_logic_vector(7 downto 0);
113
 
114
component cpu09
115
  port (
116
         clk      :     in  std_logic;
117
    rst      : in  std_logic;
118
    rw       :  out std_logic;
119
    vma      :  out std_logic;
120
    address  : out std_logic_vector(15 downto 0);
121
    data_in  : in        std_logic_vector(7 downto 0);
122
         data_out : out std_logic_vector(7 downto 0);
123
         halt     : in  std_logic;
124
         hold     : in  std_logic;
125
         irq      : in  std_logic;
126
         nmi      : in  std_logic;
127
         firq     : in  std_logic
128
  );
129
end component;
130
 
131
----------------------------------------
132
--
133
-- Dynamic Address Translation Registers
134
--
135
----------------------------------------
136
component dat_ram
137
  port (
138
    clk      : in  std_logic;
139
         rst      : in  std_logic;
140
         cs       : in  std_logic;
141
         rw       : in  std_logic;
142
         addr_lo  : in  std_logic_vector(3 downto 0);
143
         addr_hi  : in  std_logic_vector(3 downto 0);
144
    data_in  : in  std_logic_vector(7 downto 0);
145
         data_out : out std_logic_vector(7 downto 0)
146
  );
147
end component;
148
 
149
 
150
----------------------------------------
151
--
152
-- 4KByte Block RAM Monitor ROM
153
--
154
----------------------------------------
155
component mon_rom
156
  Port (
157
    clk      : in  std_logic;
158
    rst      : in  std_logic;
159
    cs       : in  std_logic;
160
    rw       : in  std_logic;
161
    addr     : in  std_logic_vector (11 downto 0);
162
    rdata    : out std_logic_vector (7 downto 0);
163
    wdata    : in  std_logic_vector (7 downto 0)
164
    );
165
end component;
166
 
167
----------------------------------------
168
--
169
-- Dual Port cache memory
170
--
171
----------------------------------------
172
component dpr_2k
173
  port (
174
    clk_a   : in  std_logic;
175
    rst_a   : in  std_logic;
176
    cs_a    : in  std_logic;
177
    rw_a    : in  std_logic;
178
    addr_a  : in  std_logic_vector (9 downto 0);
179
    dati_a  : in  std_logic_vector (15 downto 0);
180
    dato_a  : out std_logic_vector (15 downto 0);
181
    clk_b   : in  std_logic;
182
    rst_b   : in  std_logic;
183
    cs_b    : in  std_logic;
184
    rw_b    : in  std_logic;
185
    addr_b  : in  std_logic_vector (9 downto 0);
186
    dati_b  : in  std_logic_vector (15 downto 0);
187
    dato_b  : out std_logic_vector (15 downto 0)
188
  );
189
end component;
190
 
191
----------------------------------------
192
--
193
-- 32 bit hardware multiplier
194
--
195
----------------------------------------
196
component mul32
197
  port (
198
    clk      : in  std_logic;
199
         rst      : in  std_logic;
200
         cs       : in  std_logic;
201
         rw       : in  std_logic;
202
         addr     : in  std_logic_vector(3 downto 0);
203
    dati     : in  std_logic_vector(7 downto 0);
204
         dato     : out std_logic_vector(7 downto 0)
205
  );
206
end component;
207
 
208
begin
209
  -----------------------------------------------------------------------------
210
  -- Instantiation of internal components
211
  -----------------------------------------------------------------------------
212
 
213
my_cpu : cpu09  port map (
214
         clk         => clk,
215
    rst       => rst,
216
    rw       => cpu_rw,
217
    vma       => cpu_vma,
218
    address   => cpu_addr(15 downto 0),
219
    data_in   => cpu_dati,
220
         data_out  => cpu_dato,
221
         halt      => halt,
222
         hold      => hold,
223
         irq       => irq,
224
         nmi       => nmi,
225
         firq      => firq
226
    );
227
 
228
my_dat : dat_ram port map (
229
    clk       => clk,
230
         rst       => rst,
231
         cs        => dat_cs,
232
         rw        => cpu_rw,
233
         addr_hi   => cpu_addr(15 downto 12),
234
         addr_lo   => cpu_addr(3 downto 0),
235
    data_in   => cpu_dato,
236
         data_out  => dat_addr(7 downto 0)
237
         );
238
 
239
my_rom : mon_rom port map (
240
    clk       => clk,
241
    rst       => rst,
242
         cs        => rom_cs,
243
         rw        => '1',
244
    addr      => cpu_addr(11 downto 0),
245
    rdata     => rom_dato,
246
    wdata     => cpu_dato
247
    );
248
--
249
-- high address cache
250
--
251
my_dpr_0 : dpr_2k port map (
252
    clk_a     => clk,
253
    rst_a     => rst,
254
    cs_a      => cpu_vma,
255
    rw_a      => '0',
256
    addr_a    => cpu_addr(9 downto 0),
257
    dati_a    => dat_addr(15 downto 0),
258
    dato_a    => cache_cpu_addr(31 downto 16),
259
    clk_b     => clk,
260
    rst_b     => rst,
261
    cs_b      => mem_vma,
262
    rw_b      => '1',
263
    addr_b    => mem_addr(9 downto 0),
264
    dati_b    => (others=>'0'),
265
    dato_b    => cache_mem_addr(31 downto 16)
266
  );
267
--
268
-- low address cache
269
--
270
my_dpr_1 : dpr_2k port map (
271
    clk_a     => clk,
272
    rst_a     => rst,
273
    cs_a      => cpu_vma,
274
    rw_a      => '0',
275
    addr_a    => cpu_addr(9 downto 0),
276
    dati_a    => cpu_addr(15 downto 0),
277
    dato_a    => cache_cpu_addr(15 downto 0),
278
    clk_b     => clk,
279
    rst_b     => rst,
280
    cs_b      => mem_vma,
281
    rw_b      => '1',
282
    addr_b    => mem_addr(9 downto 0),
283
    dati_b    => (others=>'0'),
284
    dato_b    => cache_mem_addr(15 downto 0)
285
  );
286
 
287
--
288
-- data cache
289
--
290
my_dpr_2 : dpr_2k port map (
291
    clk_a     => clk,
292
    rst_a     => rst,
293
    cs_a      => cache_cpu_vma,
294
    rw_a      => cpu_rw,
295
    addr_a    => cpu_addr(9 downto 0),
296
    dati_a    => cache_cpu_dati(15 downto 0),
297
    dato_a    => cache_cpu_dato(15 downto 0),
298
    clk_b     => clk,
299
    rst_b     => rst,
300
    cs_b      => cache_mem_vma,
301
    rw_b      => mem_rw,
302
    addr_b    => mem_addr(9 downto 0),
303
    dati_b    => cache_mem_dati(15 downto 0),
304
    dato_b    => cache_mem_dato(15 downto 0)
305
  );
306
 
307
my_mul32 : mul32 port map (
308
    clk       => clk,
309
         rst       => rst,
310
         cs        => mul_cs,
311
         rw        => cpu_rw,
312
         addr      => cpu_addr(3 downto 0),
313
    dati      => cpu_dato,
314
         dato      => mul_dato
315
         );
316
 
317
----------------------------------------------------------------------
318
--
319
-- Process to decode internal registers
320
--
321
----------------------------------------------------------------------
322
 
323
int_decode: process( cpu_addr, cpu_rw, cpu_vma,
324
                     cache_cpu_dato,
325
                                              dat_cs, dat_addr,
326
                                                        cache_cpu_dato,
327
                                                        mul_dato,
328
                                                        rom_dato
329
                                                        )
330
begin
331
  cpu_dati     <= cache_cpu_dato( 7 downto 0);
332
  cache_cpu_en <= '1';
333
  ext_cs       <= cpu_vma; -- Assume external access
334
  dat_cs       <= '0';     -- Dynamic Address Translation
335
  rom_cs       <= '0';
336
  mul_cs       <= '0';     -- Hardware Multiplier
337
 
338
  if cpu_addr( 15 downto 8 ) = "11111111" then
339
    --
340
    -- DAT write registers at $FFF0 to $FFFF
341
         --
342
    cpu_dati     <= rom_dato;
343
    rom_cs       <= cpu_vma;
344
    dat_cs       <= cpu_vma;
345
         ext_cs       <= '0';
346
    cache_cpu_en <= '0';
347
  --
348
  -- ROM  $F000 - $FFFF
349
  --
350
  elsif dat_addr(3 downto 0) = "1111" then -- $XE000 - $XEFFF
351
    cpu_dati     <= rom_dato;
352
    rom_cs       <= cpu_vma;
353
    cache_cpu_en <= '0';
354
  --
355
  -- IO Devices $E000 - $EFFF
356
  --
357
  elsif dat_addr(3 downto 0) = "1110" then -- $XE000 - $XEFFF
358
    --
359
         -- disable cache for I/O
360
         --
361
    cache_cpu_en <= '0';
362
 
363
         case cpu_addr(11 downto 8) is
364
    --
365
    -- CPU specific registers from $E200 to $E2FF
366
    --
367
    when "0010" =>
368
           ext_cs   <= '0';              -- assume this segment is internal
369
      cpu_dati <= (others=>'0');         -- default to null data
370
      --
371
      -- Unique number to identify CPU
372
      --
373
      case cpu_addr(7 downto 4) is
374
      when "0000" =>
375
        cpu_dati <= cpu_id;  -- CPU ID register
376
      --
377
      -- hardware 32 bit multiplier
378
      --
379
      when "0001" =>
380
        cpu_dati <= mul_dato;  -- Hardware Multiplier register
381
        mul_cs   <= cpu_vma;
382
 
383
      when others =>
384
                  null;
385
      end case;
386
 
387
    --
388
    -- Everything else is external
389
    --
390
    when others =>
391
           null;
392
 
393
    end case;
394
  end if;
395
end process;
396
 
397
--
398
-- cpu side cache controller
399
--
400
my_cpu_cache : process( cpu_vma, cpu_rw, cpu_dato, cpu_addr, dat_addr,
401
                        cache_cpu_addr, cache_cpu_en, ext_cs )
402
begin
403
  dat_addr(15 downto 8) <= (others=>'0');
404
  addr(19 downto 12) <= dat_addr xor id;
405
  addr(11 downto  0) <= cpu_addr(11 downto 0);
406
  rw   <= cpu_rw;
407
  vma  <= '0';
408
  --
409
  -- external access if cache miss or write through or if i/o space
410
  --
411
  if (cache_cpu_addr(23 downto 16) /= dat_addr( 7 downto 0) ) or
412
          (cache_cpu_addr(11 downto  0) /= cpu_addr(11 downto 0) ) or
413
     (cpu_rw = '0') or (cache_cpu_en = '0') then
414
    vma <= ext_cs;
415
  end if;
416
  cache_cpu_dati( 7 downto 0) <= cpu_dato;
417
  cache_cpu_dati(15 downto 8) <= (others=>'0');
418
end process;
419
 
420
--
421
-- memory side cache controller
422
--
423
my_mem_cache : process( mem_vma, mem_addr, mem_dati, mem_rw,
424
                        cache_mem_addr, cache_mem_dato )
425
begin
426
  --
427
  -- write through from another CPU will update cache entry
428
  -- if there is a cache hit
429
  --
430
  cache_mem_vma <= '0';
431
  if (cache_mem_addr(23 downto 16) = mem_addr(19 downto 12)) and
432
     (cache_mem_addr(11 downto  0) = mem_addr(11 downto  0)) then
433
    cache_mem_vma <= mem_vma;
434
  end if;
435
  mem_dato <= cache_mem_dato( 7 downto 0);
436
  cache_mem_dati( 7 downto 0) <= mem_dati;
437
  cache_mem_dati(15 downto 8) <= (others=>'0');
438
end process;
439
 
440
end architecture;
441
 
442
  -----------------------------------------------------------------------------

powered by: WebSVN 2.1.0

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