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

Subversion Repositories c16

[/] [c16/] [trunk/] [vhdl/] [cpu_engine.vhd] - Blame information for rev 31

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

Line No. Rev Author Line
1 2 jsauermann
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.STD_LOGIC_ARITH.ALL;
4
use IEEE.STD_LOGIC_UNSIGNED.ALL;
5
 
6
--  Uncomment the following lines to use the declarations that are
7
--  provided for instantiating Xilinx primitive components.
8
--library UNISIM;
9
--use UNISIM.VComponents.all;
10
 
11
use work.cpu_pack.ALL;
12
 
13
entity cpu_engine is
14 9 jsauermann
        PORT(   -- WISHBONE interface
15
                        CLK_I   : in  std_logic;
16
                        DAT_I   : in  std_logic_vector( 7 downto 0);
17
                        DAT_O   : out std_logic_vector( 7 downto 0);
18
                        RST_I   : in  std_logic;
19
                        ACK_I   : in  std_logic;
20
                        ADR_O   : out std_logic_vector(15 downto 0);
21
                        CYC_O   : out std_logic;
22
                        STB_O   : out std_logic;
23
                        TGA_O   : out std_logic_vector( 0 downto 0);              -- '1' if I/O
24
                        WE_O    : out std_logic;
25 2 jsauermann
 
26 9 jsauermann
                        INT     : in  std_logic;
27
                        HALT    : out std_logic;
28 2 jsauermann
 
29 9 jsauermann
                        -- debug signals
30
                        --
31
                        Q_PC    : out std_logic_vector(15 downto 0);
32
                        Q_OPC   : out std_logic_vector( 7 downto 0);
33
                        Q_CAT   : out op_category;
34
                        Q_IMM   : out std_logic_vector(15 downto 0);
35
                        Q_CYC   : out cycle;
36 2 jsauermann
 
37
                        -- select signals
38
                        Q_SX    : out std_logic_vector(1 downto 0);
39
                        Q_SY    : out std_logic_vector(3 downto 0);
40
                        Q_OP    : out std_logic_vector(4 downto 0);
41
                        Q_SA    : out std_logic_vector(4 downto 0);
42
                        Q_SMQ   : out std_logic;
43
 
44
                        -- write enable/select signal
45 9 jsauermann
                        Q_WE_RR : out std_logic;
46
                        Q_WE_LL : out std_logic;
47
                        Q_WE_SP : out SP_OP;
48 2 jsauermann
 
49 9 jsauermann
                        Q_RR    : out std_logic_vector(15 downto 0);
50
                        Q_LL    : out std_logic_vector(15 downto 0);
51
                        Q_SP    : out std_logic_vector(15 downto 0)
52 2 jsauermann
                );
53
end cpu_engine;
54
 
55
architecture Behavioral of cpu_engine is
56
 
57 9 jsauermann
        -- Unfortunately, the on-chip memory needs a clock to read data.
58
        -- Therefore we cannot make it wishbone compliant without a speed penalty.
59
        -- We avoid this problem by making the on-chip memory part of the CPU.
60
        -- However, as a consequence, you cannot DMA to the on-chip memory.
61
        --
62
        -- The on-chip memory is 8K, so that you can run a test SoC without external
63
        -- memory. For bigger applications, you should use external ROM and RAM and
64
        -- remove the internal memory entirely (setting EXTERN accordingly).
65
        --
66 2 jsauermann
        COMPONENT memory
67
        PORT(   CLK_I : IN  std_logic;
68
                        T2    : IN  std_logic;
69
                        CE    : IN  std_logic;
70
                        PC    : IN  std_logic_vector(15 downto 0);
71
                        ADR   : IN  std_logic_vector(15 downto 0);
72
                        WR    : IN  std_logic;
73
                        WDAT  : IN  std_logic_vector(7 downto 0);
74
 
75
                        OPC   : OUT std_logic_vector(7 downto 0);
76
                        RDAT  : OUT std_logic_vector(7 downto 0)
77
                );
78
        END COMPONENT;
79
 
80
        COMPONENT opcode_fetch
81
        PORT(   CLK_I  : IN  std_logic;
82
                        T2     : IN  std_logic;
83
                        CLR    : IN  std_logic;
84
                        CE     : IN  std_logic;
85
                        PC_OP  : IN  std_logic_vector(2 downto 0);
86
                        JDATA  : IN  std_logic_vector(15 downto 0);
87
                        RR     : IN  std_logic_vector(15 downto 0);
88
                        RDATA  : IN  std_logic_vector(7 downto 0);
89
                        PC     : OUT std_logic_vector(15 downto 0)
90
                );
91
        END COMPONENT;
92
 
93
        COMPONENT opcode_decoder
94
        PORT(   CLK_I  : IN  std_logic;
95
                        T2     : IN  std_logic;
96
                        CLR    : IN  std_logic;
97
                        CE     : IN  std_logic;
98
                        OPCODE : in std_logic_vector(7 downto 0);
99
                        OP_CYC : in cycle;
100
                        INT    : in std_logic;
101
                        RRZ    : in std_logic;
102
 
103
                        OP_CAT : out op_category;
104
 
105
                        -- select signals
106
                        D_SX    : out std_logic_vector(1 downto 0);              -- ALU select X
107
                        D_SY    : out std_logic_vector(3 downto 0);              -- ALU select Y
108
                        D_OP    : out std_logic_vector(4 downto 0);              -- ALU operation
109
                        D_SA    : out std_logic_vector(4 downto 0);              -- select address
110
                        D_SMQ   : out std_logic;
111
 
112
                        -- write enable/select signal
113
                        D_WE_RR  : out std_logic;
114
                        D_WE_LL  : out std_logic;
115
                        D_WE_SP  : out SP_OP;
116 9 jsauermann
                        D_RD_O   : out std_logic;
117
                        D_WE_O   : out std_logic;
118
                        D_LOCK   : out std_logic;
119 2 jsauermann
 
120
                        -- input/output
121 9 jsauermann
                        D_IO     : out std_logic;
122 2 jsauermann
 
123
                        PC_OP  : out std_logic_vector(2 downto 0);
124
 
125
                        LAST_M : out std_logic;
126
                        HLT    : out std_logic
127
                );
128
        END COMPONENT;
129
 
130
        COMPONENT data_core
131
        PORT(   CLK_I : in  std_logic;
132
                        T2    : in  std_logic;
133
                        CLR   : in  std_logic;
134
                        CE    : in  std_logic;
135
 
136
                        -- select signals
137
                        SX    : in  std_logic_vector( 1 downto 0);
138
                        SY    : in  std_logic_vector( 3 downto 0);
139
                        OP    : in  std_logic_vector( 4 downto 0);               -- alu op
140
                        PC    : in  std_logic_vector(15 downto 0);               -- PC
141
                        QU    : in  std_logic_vector( 3 downto 0);               -- quick operand
142
                        SA    : in  std_logic_vector(4 downto 0);                        -- select address
143
                        SMQ   : in  std_logic;                                                  -- select MQ (H/L)
144
 
145
                        -- write enable/select signal
146
                        WE_RR  : in  std_logic;
147
                        WE_LL  : in  std_logic;
148
                        WE_SP  : in  SP_OP;
149
 
150
                        IMM : in  std_logic_vector(15 downto 0);         -- immediate data
151 9 jsauermann
                        RDAT : in  std_logic_vector( 7 downto 0);                -- data from memory/IO
152
                        ADR   : out std_logic_vector(15 downto 0);               -- memory/IO address
153
                        MQ    : out std_logic_vector( 7 downto 0);               -- data to memory/IO
154 2 jsauermann
 
155
                        Q_RR  : out std_logic_vector(15 downto 0);
156
                        Q_LL  : out std_logic_vector(15 downto 0);
157
                        Q_SP  : out std_logic_vector(15 downto 0)
158
                );
159
        END COMPONENT;
160
 
161
        -- global signals
162
        signal CE      : std_logic;
163 9 jsauermann
        signal T2      : std_logic;
164 2 jsauermann
 
165
        -- memory signals
166 9 jsauermann
        signal  WDAT     : std_logic_vector(7 downto 0);
167
        signal  RDAT     : std_logic_vector(7 downto 0);
168 2 jsauermann
        signal  M_PC     : std_logic_vector(15 downto 0);
169
        signal  M_OPC    : std_logic_vector(7 downto 0);
170
 
171
        -- decoder signals
172
        --
173
        signal  D_CAT    : op_category;
174
        signal  D_OPC    : std_logic_vector(7 downto 0);
175
        signal  D_CYC    : cycle;
176
        signal  D_PC     : std_logic_vector(15 downto 0);        -- debug signal
177
        signal  D_PC_OP  : std_logic_vector( 2 downto 0);
178
        signal  D_LAST_M : std_logic;
179 9 jsauermann
        signal  D_IO     : std_logic;
180
 
181 2 jsauermann
        -- select signals
182
        signal  D_SX    : std_logic_vector(1 downto 0);
183
        signal  D_SY    : std_logic_vector(3 downto 0);
184
        signal  D_OP    : std_logic_vector(4 downto 0);
185
        signal  D_SA    : std_logic_vector(4 downto 0);
186
        signal  D_SMQ   : std_logic;
187 9 jsauermann
 
188 2 jsauermann
        -- write enable/select signals
189
        signal  D_WE_RR  : std_logic;
190
        signal  D_WE_LL  : std_logic;
191
        signal  D_WE_SP  : SP_OP;
192 9 jsauermann
        signal  D_RD_O   : std_logic;
193
        signal  D_WE_O   : std_logic;
194
        signal  D_LOCK   : std_logic;   -- first cycle
195 2 jsauermann
 
196 9 jsauermann
        signal  LM_WE    : std_logic;
197
 
198 2 jsauermann
        -- core signals
199
        --
200
        signal  C_IMM  : std_logic_vector(15 downto 0);
201
        signal  ADR    : std_logic_vector(15 downto 0);
202
 
203
        signal  C_CYC    : cycle;                                                               -- debug signal
204
        signal  C_PC     : std_logic_vector(15 downto 0);                -- debug signal
205
        signal  C_OPC    : std_logic_vector( 7 downto 0);                -- debug signal
206
        signal  C_RR     : std_logic_vector(15 downto 0);
207
 
208
        signal  RRZ      : std_logic;
209
        signal  OC_JD    : std_logic_vector(15 downto 0);
210
 
211
        -- select signals
212
        signal  C_SX     : std_logic_vector(1 downto 0);
213
        signal  C_SY     : std_logic_vector(3 downto 0);
214
        signal  C_OP     : std_logic_vector(4 downto 0);
215
        signal  C_SA     : std_logic_vector(4 downto 0);
216
        signal  C_SMQ    : std_logic;
217
        signal  C_WE_RR  : std_logic;
218
        signal  C_WE_LL  : std_logic;
219
        signal  C_WE_SP  : SP_OP;
220
 
221
        signal XM_OPC    : std_logic_vector(7 downto 0);
222
        signal LM_OPC    : std_logic_vector(7 downto 0);
223
        signal LM_RDAT   : std_logic_vector(7 downto 0);
224 9 jsauermann
        signal XM_RDAT   : std_logic_vector(7 downto 0);
225
        signal  C_IO     : std_logic;
226
        signal  C_RD_O   : std_logic;
227
        signal  C_WE_O   : std_logic;
228 2 jsauermann
 
229 9 jsauermann
        -- signals to remember, whether the previous read cycle
230
        -- addressed internal memory or external memory
231
        --
232
        signal OPCS      : std_logic;   -- '1' if opcode from external memory
233
        signal RDATS     : std_logic;   -- '1' if data   from external memory
234
        signal EXTERN    : std_logic;   -- '1' if opcode or data from external memory
235
 
236 2 jsauermann
begin
237
 
238
        memo: memory
239
        PORT MAP(       CLK_I => CLK_I,
240 9 jsauermann
                                T2    => T2,
241 2 jsauermann
                                CE    => CE,
242
 
243
                                -- read in T1
244
                                PC    => M_PC,
245
                                OPC   => LM_OPC,
246
 
247
                                -- read or written in T2
248
                                ADR   => ADR,
249 9 jsauermann
                                WR    => LM_WE,
250
                                WDAT  => WDAT,
251 2 jsauermann
                                RDAT  => LM_RDAT
252
                        );
253
 
254
        ocf: opcode_fetch
255
         PORT MAP(      CLK_I    => CLK_I,
256 9 jsauermann
                                T2       => T2,
257
                                CLR      => RST_I,
258 2 jsauermann
                                CE       => CE,
259
                                PC_OP    => D_PC_OP,
260
                                JDATA    => OC_JD,
261
                                RR       => C_RR,
262 9 jsauermann
                                RDATA    => RDAT,
263 2 jsauermann
                                PC       => M_PC
264
                        );
265
 
266
        opdec: opcode_decoder
267
        PORT MAP(       CLK_I    => CLK_I,
268 9 jsauermann
                                T2       => T2,
269
                                CLR      => RST_I,
270 2 jsauermann
                                CE       => CE,
271
                                OPCODE  => D_OPC,
272
                                OP_CYC  => D_CYC,
273
                                INT     => INT,
274
                                RRZ     => RRZ,
275
 
276
                                OP_CAT  => D_CAT,
277 9 jsauermann
 
278 2 jsauermann
                                -- select signals
279
                                D_SX    => D_SX,
280
                                D_SY    => D_SY,
281
                                D_OP    => D_OP,
282
                                D_SA    => D_SA,
283
                                D_SMQ   => D_SMQ,
284
 
285
                                -- write enable/select signal
286
                                D_WE_RR => D_WE_RR,
287
                                D_WE_LL => D_WE_LL,
288
                                D_WE_SP => D_WE_SP,
289 9 jsauermann
                                D_RD_O  => D_RD_O,
290
                                D_WE_O  => D_WE_O,
291
                                D_LOCK  => D_LOCK,
292 2 jsauermann
 
293 9 jsauermann
                                D_IO    => D_IO,
294 2 jsauermann
 
295
                                PC_OP   => D_PC_OP,
296
                                LAST_M  => D_LAST_M,
297
                                HLT     => HALT
298
        );
299
 
300
        dcore: data_core
301
        PORT MAP(       CLK_I  => CLK_I,
302 9 jsauermann
                                T2     => T2,
303
                                CLR    => RST_I,
304 2 jsauermann
                                CE     => CE,
305
 
306
                                -- select signals
307
                                SX     => C_SX,
308
                                SY     => C_SY,
309
                                OP     => C_OP,
310
                                PC     => C_PC,
311
                                QU     => C_OPC(3 downto 0),
312
                                SA     => C_SA,
313
                                SMQ    => C_SMQ,
314
 
315
                                -- write enable/select signal
316
                                WE_RR  => C_WE_RR,
317
                                WE_LL  => C_WE_LL,
318
                                WE_SP  => C_WE_SP,
319
 
320
                                IMM    => C_IMM,
321 9 jsauermann
                                RDAT   => RDAT,
322 2 jsauermann
                                ADR    => ADR,
323 9 jsauermann
                                MQ     => WDAT,
324 2 jsauermann
 
325
                                Q_RR   => C_RR,
326
                                Q_LL   => Q_LL,
327
                                Q_SP   => Q_SP
328 9 jsauermann
                        );
329 2 jsauermann
 
330 9 jsauermann
        CE       <= ACK_I or not EXTERN;
331
        TGA_O(0) <= T2 and C_IO;
332
        WE_O     <= T2 and C_WE_O;
333
        STB_O    <= EXTERN;
334
        CYC_O    <= EXTERN;
335 2 jsauermann
 
336
        Q_RR   <= C_RR;
337
        RRZ    <= '1' when (C_RR = X"0000") else '0';
338
        OC_JD  <= M_OPC & C_IMM(7 downto 0);
339
 
340
        Q_PC   <= C_PC;
341
        Q_OPC  <= C_OPC;
342
        Q_CYC  <= C_CYC;
343
        Q_IMM  <= C_IMM;
344
 
345
        -- select signals
346
        Q_SX    <= C_SX;
347
        Q_SY    <= C_SY;
348
        Q_OP    <= C_OP;
349
        Q_SA    <= C_SA;
350
        Q_SMQ   <= C_SMQ;
351
 
352 9 jsauermann
        -- write enable/select signal (debug)
353 2 jsauermann
        Q_WE_RR <= C_WE_RR;
354
        Q_WE_LL <= C_WE_LL;
355
        Q_WE_SP <= C_WE_SP;
356
 
357 9 jsauermann
        DAT_O   <= WDAT;
358 2 jsauermann
 
359
        process(CLK_I)
360
        begin
361
                if (rising_edge(CLK_I)) then
362 9 jsauermann
                        if (RST_I = '1') then   T2 <= '0';
363 23 jsauermann
                        elsif (CE = '1') then   T2 <= not T2;
364 9 jsauermann
                        end if;
365 2 jsauermann
                end if;
366
        end process;
367
 
368 21 jsauermann
        process(T2, M_PC, ADR, C_IO, C_RD_O, C_WE_O)
369 2 jsauermann
        begin
370 9 jsauermann
                if (T2 = '0') then                                                                       -- opcode fetch
371
                        EXTERN <= M_PC(15) or M_PC(14) or M_PC(13);             -- 8Kx8  internal memory
372
-- A            EXTERN <= M_PC(15) or M_PC(14) or M_PC(13) or   -- 512x8 internal memory
373
-- A                              M_PC(12) or M_PC(11) or M_PC(10) or M_PC(9)
374
-- B            EXTERN <= '1';                                                                  -- no    internal memory
375
                else                                                                                            -- data or I/O
376
                        EXTERN <= (ADR(15) or ADR(14) or ADR(13) or             -- 8Kx8  internal memory
377
-- A            EXTERN <= (ADR(15) or ADR(14) or ADR(13) or             -- 512x8  internal memory
378
-- A                               ADR(12) or ADR(11) or ADR(10) or ADR(9) or
379
-- B            EXTERN <= ('1' or                                                               -- no    internal memory
380
                                          C_IO) and (C_RD_O or C_WE_O);
381 2 jsauermann
                end if;
382
        end process;
383
 
384 9 jsauermann
        -- remember whether access is to internal or to external (incl I/O) memory.
385
        -- clock read data to XM_OPCODE in T1 or to XM_RDAT in T2
386
        --
387 2 jsauermann
        process(CLK_I)
388
        begin
389
                if (rising_edge(CLK_I)) then
390 23 jsauermann
                        if (CE = '1') then
391
                                if (T2 = '0') then
392
                                        OPCS   <= EXTERN;
393
                                        XM_OPC <= DAT_I;
394
                                else
395
                                        RDATS   <= EXTERN;
396
                                        XM_RDAT <= DAT_I;
397
                                end if;
398 2 jsauermann
                        end if;
399
                end if;
400
        end process;
401
 
402 9 jsauermann
        M_OPC <= LM_OPC  when (OPCS = '0')  else XM_OPC;
403
        ADR_O <= M_PC    when (T2 = '0')    else ADR;
404
        RDAT  <= LM_RDAT when (RDATS = '0') else XM_RDAT;
405 2 jsauermann
 
406 21 jsauermann
        process(CLK_I, RST_I)   -- nuovo (thanks to Riccardo Cerulli-Irelli)
407 2 jsauermann
        begin
408 21 jsauermann
                if (RST_I = '1') then
409 2 jsauermann
 
410 21 jsauermann
                        C_PC    <= X"0000";
411
                        C_OPC   <= X"01";
412
                        C_CYC   <= M1;
413 2 jsauermann
 
414 21 jsauermann
                        C_SX    <= "00";
415
                        C_SY    <= "0000";
416
                        C_OP    <= "00000";
417
                        C_SA    <= "00000";
418
                        C_SMQ   <= '0';
419
                        C_WE_RR <= '0';
420
                        C_WE_LL <= '0';
421
                        C_WE_SP <= SP_NOP;
422
                        C_IO    <= '0';
423
                        C_RD_O  <= '0';
424
                        C_WE_O  <= '0';
425
                        LM_WE   <= '0';
426
                elsif ((rising_edge(CLK_I) and T2 = '1') and CE = '1' ) then
427
                        C_CYC   <= D_CYC;
428
                        Q_CAT   <= D_CAT;
429
                        C_PC    <= D_PC;
430
                        C_OPC   <= D_OPC;
431
                        C_SX    <= D_SX;
432
                        C_SY    <= D_SY;
433
                        C_OP    <= D_OP;
434
                        C_SA    <= D_SA;
435
                        C_SMQ   <= D_SMQ;
436
                        C_WE_RR <= D_WE_RR;
437
                        C_WE_LL <= D_WE_LL;
438
                        C_WE_SP <= D_WE_SP;
439
                        C_IO    <= D_IO;
440
                        C_RD_O  <= D_RD_O;
441
                        C_WE_O  <= D_WE_O;
442
                        LM_WE   <= D_WE_O and not D_IO;
443 2 jsauermann
 
444 21 jsauermann
                end if;
445
        end process;
446
 
447
        process(CLK_I, RST_I)   -- nuovo (thanks to Riccardo Cerulli-Irelli)
448
        begin
449
                if (RST_I = '1') then
450
                        D_PC    <= X"0000";
451
                        D_OPC   <= X"01";
452
                        D_CYC   <= M1;
453
                        C_IMM   <= X"FFFF";
454
 
455
                elsif ((rising_edge(CLK_I) and T2 = '1') and CE = '1' ) then
456
                        if (D_LAST_M = '1') then        -- D goes to M1
457
                                -- signals valid for entire opcode...     PORTATO FUORI
458
                                D_OPC <= M_OPC;
459
                                D_PC  <= M_PC;
460
                                D_CYC <= M1;
461
                        else
462
                                case D_CYC is
463
                                        when M1 =>      D_CYC <= M2;    -- C goes to M1
464
                                                                C_IMM <= X"00" & M_OPC;
465
                                        when M2 =>      D_CYC <= M3;
466
                                                                C_IMM(15 downto 8) <= M_OPC;
467
                                        when M3 =>      D_CYC <= M4;
468
                                        when M4 =>      D_CYC <= M5;
469
                                        when M5 =>      D_CYC <= M1;
470
                                end case;
471 2 jsauermann
                        end if;
472
                end if;
473
        end process;
474
 
475
end Behavioral;

powered by: WebSVN 2.1.0

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