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

Subversion Repositories tinycpu

[/] [tinycpu/] [trunk/] [src/] [core.vhd] - Blame information for rev 24

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

Line No. Rev Author Line
1 19 earlz
--Core module. 
2
--This module is basically connects everything and decodes the opcodes.
3
--The only thing above this is toplevel.vhd which actually sets the pinout for the FPGA
4
 
5
 
6
library IEEE;
7
use IEEE.STD_LOGIC_1164.ALL;
8
use IEEE.NUMERIC_STD.ALL;
9
use work.tinycpu.all;
10
 
11
entity core is
12
  port(
13
    --memory interface 
14
    MemAddr: out std_logic_vector(15 downto 0); --memory address (in bytes)
15
    MemWW: out std_logic; --memory writeword
16
    MemWE: out std_logic; --memory writeenable
17 20 earlz
    MemIn: in std_logic_vector(15 downto 0);
18
    MemOut: out std_logic_vector(15 downto 0);
19 19 earlz
    --general interface
20
    Clock: in std_logic;
21
    Reset: in std_logic; --When this is high, CPU will reset within 1 clock cycles. 
22
    --Enable: in std_logic; --When this is high, the CPU executes as normal, when low the CPU stops at the next clock cycle(maintaining all state)
23
    Hold: in std_logic; --when high, CPU pauses execution and places Memory interfaces into high impendance state so the memory can be used by other components
24
    HoldAck: out std_logic; --when high, CPU acknowledged hold and buses are in high Z
25
    --todo: port interface
26
 
27
    --debug ports:
28
    DebugIR: out std_logic_vector(15 downto 0); --current instruction
29 20 earlz
    DebugIP: out std_logic_vector(7 downto 0); --current IP
30
    DebugCS: out std_logic_vector(7 downto 0); --current code segment
31 19 earlz
    DebugTR: out std_logic; --current value of TR
32 20 earlz
    DebugR0: out std_logic_vector(7 downto 0)
33 19 earlz
   );
34
end core;
35
 
36
architecture Behavioral of core is
37
  component fetch is
38
    port(
39
      Enable: in std_logic;
40
      AddressIn: in std_logic_vector(15 downto 0);
41
      Clock: in std_logic;
42
      DataIn: in std_logic_vector(15 downto 0); --interface from memory
43
      IROut: out std_logic_vector(15 downto 0);
44
      AddressOut: out std_logic_vector(15 downto 0) --interface to memory
45
    );
46
  end component;
47
  component alu is
48
    port(
49
      Op: in std_logic_vector(4 downto 0);
50
      DataIn1: in std_logic_vector(7 downto 0);
51
      DataIn2: in std_logic_vector(7 downto 0);
52
      DataOut: out std_logic_vector(7 downto 0);
53
      TR: out std_logic
54
    );
55
  end component;
56
  component carryover is
57
    port(
58
      EnableCarry: in std_logic; --When disabled, SegmentIn goes to SegmentOut
59
      DataIn: in std_logic_vector(7 downto 0);
60
      SegmentIn: in std_logic_vector(7 downto 0);
61
      Addend: in std_logic_vector(7 downto 0); --How much to increase DataIn by (as a signed number). Believe it or not, that's the actual word for what we need.
62
      DataOut: out std_logic_vector(7 downto 0);
63 21 earlz
      SegmentOut: out std_logic_vector(7 downto 0);
64
      Clock: in std_logic
65 19 earlz
    );
66
  end component;
67
  component registerfile is
68
  port(
69
    WriteEnable: in regwritetype;
70
    DataIn: in regdatatype;
71
    Clock: in std_logic;
72
    DataOut: out regdatatype
73
  );
74
  end component;
75
 
76
  constant REGIP: integer := 7;
77
  constant REGSP: integer := 6;
78
  constant REGSS: integer := 15;
79
  constant REGES: integer := 14;
80
  constant REGDS: integer := 13;
81
  constant REGCS: integer := 12;
82
 
83
  type ProcessorState is (
84
    ResetProcessor,
85 21 earlz
    FirstFetch1, --the fetcher needs two clock cycles to catch up
86
    FirstFetch2,
87 23 earlz
    Firstfetch3,
88 19 earlz
    Execute,
89
    WaitForMemory,
90
    HoldMemory
91
  );
92 20 earlz
  signal state: ProcessorState;
93
  signal HeldState: ProcessorState; --state the processor was in when HOLD was activated
94 19 earlz
 
95
  --carryout signals
96
  signal CarryCS: std_logic;
97
  signal CarrySS: std_logic;
98
  signal IPAddend: std_logic_vector(7 downto 0);
99
  signal SPAddend: std_logic_vector(7 downto 0);
100
  signal IPCarryOut: std_logic_vector(7 downto 0);
101
  signal CSCarryOut: std_logic_vector(7 downto 0);
102
  --register signals
103
  signal regWE:regwritetype;
104
  signal regIn: regdatatype;
105
  signal regOut: regdatatype;
106
  --fetch signals
107
  signal fetchEN: std_logic;
108
  signal IR: std_logic_vector(15 downto 0);
109
 
110
  --control signals
111
  signal InReset: std_logic;
112
 
113
  --opcode shortcut signals
114
  signal opmain: std_logic_vector(3 downto 0);
115
  signal opimmd: std_logic_vector(7 downto 0);
116
  signal opcond1: std_logic; --first conditional bit
117
  signal opcond2: std_logic; --second conditional bit
118
  signal opreg1: std_logic_vector(2 downto 0);
119
  signal opreg2: std_logic_vector(2 downto 0);
120
  signal opreg3: std_logic_vector(2 downto 0);
121
  signal opseges: std_logic; --use ES segment
122
 
123 20 earlz
  signal fetcheraddress: std_logic_vector(15 downto 0);
124 19 earlz
begin
125 20 earlz
  reg: registerfile port map(
126 19 earlz
    WriteEnable => regWE,
127
    DataIn => regIn,
128
    Clock => Clock,
129
    DataOut => regOut
130
  );
131 20 earlz
  carryovercs: carryover port map(
132 19 earlz
    EnableCarry => CarryCS,
133 21 earlz
    DataIn => regIn(REGIP),
134
    SegmentIn => regIn(REGCS),
135 20 earlz
    Addend => IPAddend,
136
    DataOut => IPCarryOut,
137 21 earlz
    SegmentOut => CSCarryOut,
138
    Clock => Clock
139 19 earlz
  );
140 20 earlz
  fetcher: fetch port map(
141 19 earlz
    Enable => fetchEN,
142 20 earlz
    AddressIn => fetcheraddress,
143 19 earlz
    Clock => Clock,
144
    DataIn => MemIn,
145
    IROut => IR,
146
    AddressOut => MemAddr --this component supports tristate, so no worries about an intermediate signal
147
  );
148 21 earlz
  fetcheraddress <= regIn(REGCS) & regIn(REGIP);
149 20 earlz
 
150
 
151
  --opcode shortcuts
152 19 earlz
  opmain <= IR(15 downto 12);
153
  opimmd <= IR(7 downto 0);
154
  opcond1 <= IR(8);
155
  opcond2 <= IR(7);
156
  opreg1 <= IR(11 downto 9);
157
  opreg3 <= IR(2 downto 0);
158
  opreg2 <= IR(5 downto 3);
159
  opseges <= IR(6);
160 20 earlz
  --debug ports
161
  DebugCS <= regOut(REGCS);
162
  DebugIP <= regOut(REGIP);
163
  DebugR0 <= regOut(0);
164
  DebugIR <= IR;
165
 
166 19 earlz
 
167 21 earlz
 
168
  decode: process(Clock, Hold, state, IR, inreset, reset, regin, regout, IPCarryOut, CSCarryOut)
169 19 earlz
  begin
170
    if rising_edge(Clock) then
171 21 earlz
 
172
    --states
173 20 earlz
      if reset='1' and hold='0' then
174 19 earlz
        InReset <= '1';
175
        state <= ResetProcessor;
176 20 earlz
        HoldAck <= '0';
177 21 earlz
        CarryCS <= '1';
178
        CarrySS <= '0';
179
        regWE <= (others => '1');
180
        regIn <= (others => "00000000");
181
        regIn(REGCS) <= x"01";
182
        IPAddend <= x"00";
183
        fetchEN <= '1';
184 19 earlz
        --finish up
185
      elsif InReset='1' and reset='0' and Hold='0' then --reset is done, start executing
186
        InReset <= '0';
187 21 earlz
        fetchEN <= '1';
188
        state <= FirstFetch1;
189 19 earlz
      elsif Hold = '1' and (state=HoldMemory or state=Execute or state=ResetProcessor) then
190 20 earlz
        --do not hold immediately if waiting on memory or if waiting on the first fetch of an instruction after reset
191 19 earlz
        state <= HoldMemory;
192
        HoldAck <= '1';
193 21 earlz
        FetchEN <= '0';
194
        MemAddr <= "ZZZZZZZZZZZZZZZZ";
195
        MemOut <= "ZZZZZZZZZZZZZZZZ";
196
        MemWE <= 'Z';
197
        MemWW <= 'Z';
198 19 earlz
      elsif Hold='0' and state=HoldMemory then
199 20 earlz
        if reset='1' or InReset='1' then
200
          state <= ResetProcessor;
201
        else
202
          state <= Execute;
203
        end if;
204 21 earlz
        FetchEN <= '1';
205
      elsif state=FirstFetch1 then --we have to let IR get loaded before we can execute.
206 20 earlz
        --regWE <= (others => '0');
207 21 earlz
        fetchEN <= '1'; --already enabled, but anyway
208 23 earlz
        --regWE <= (others => '0');
209 21 earlz
        IPAddend <= x"02";
210
        SPAddend <= x"00"; --no addend unless pushing or popping
211
        RegWE <= (others => '0');
212
        regIn(REGIP) <= IPCarryOut;
213
        regWE(REGIP) <= '1';
214
        regWE(REGCS) <= '1';
215
        regIn(REGCS) <= CSCarryOut;
216 23 earlz
        state <= Execute;
217
      elsif state=FirstFetch2 then
218
        state <= FirstFetch3;
219
 
220
      elsif state=FirstFetch3 then
221
        state <= Execute;
222 19 earlz
      end if;
223 21 earlz
 
224
 
225 19 earlz
      if state=Execute then
226 20 earlz
        fetchEN <= '1';
227 19 earlz
        --reset to "usual"
228 20 earlz
        IPAddend <= x"02";
229
        SPAddend <= x"00"; --no addend unless pushing or popping
230 19 earlz
        RegWE <= (others => '0');
231 21 earlz
        regIn(REGIP) <= IPCarryOut;
232
        regWE(REGIP) <= '1';
233
        regWE(REGCS) <= '1';
234
        regIn(REGCS) <= CSCarryOut;
235
 
236 20 earlz
        MemWE <= '0';
237
        MemWW <= '0';
238 19 earlz
 
239
        --actual decoding
240
        case opmain is
241
          when "0000" => --mov reg,imm
242 24 earlz
            --if to_integer(unsigned(opreg1)) = REGIP then
243
 
244 19 earlz
            RegIn(to_integer(unsigned(opreg1))) <= opimmd;
245
            RegWE(to_integer(unsigned(opreg1))) <= '1';
246
          when others =>
247
            --synthesis off
248
            report "Not implemented" severity error;
249
            --synthesis on
250
        end case;
251
      end if;
252 21 earlz
 
253
 
254
 
255
 
256 19 earlz
    end if;
257
  end process;
258
 
259
 
260
 
261
 
262
 
263
 
264
 
265
 
266
 
267
end Behavioral;

powered by: WebSVN 2.1.0

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