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

Subversion Repositories v6502

[/] [v6502/] [trunk/] [cpufsm.vhd] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 Valerio63
library IEEE;
2
use IEEE.std_logic_1164.all;  -- defines std_logic types
3
use IEEE.STD_LOGIC_unsigned.all;
4
use IEEE.STD_LOGIC_arith.all;
5
 
6
-- CPU FSM main state machine
7
entity cpufsm is
8
  port(      clk:  in STD_LOGIC;
9
             clr:  in STD_LOGIC;
10
           fwait:  in STD_LOGIC;
11
            ireq:  in STD_LOGIC;
12
          branch:  in STD_LOGIC;
13
           bflag:  in STD_LOGIC;
14
             aim:  in STD_LOGIC;
15
          bcarry:  in STD_LOGIC;
16
          icarry:  in STD_LOGIC;
17
              p1:  in STD_LOGIC_VECTOR(1 downto 0);
18
            e_ei:  in STD_LOGIC;
19
           mc_ei:  in STD_LOGIC;
20
          addsub:  in STD_LOGIC;
21
        dec_mode:  in STD_LOGIC;
22
           fetch: out STD_LOGIC;
23
         op_sync: out STD_LOGIC;
24
             pci: out STD_LOGIC;
25
              pq: out STD_LOGIC_VECTOR(1 downto 0);
26
              fb: out STD_LOGIC;
27
              od: out STD_LOGIC;
28
          mc_nop: out STD_LOGIC
29
      );
30
end cpufsm;
31
 
32
architecture rtl of cpufsm is
33
type states is (s0,s1,s2,s3,s4,s5,s6,s7,s8);
34
attribute ENUM_ENCODING:STRING;
35
attribute ENUM_ENCODING of states: type is "000000001 000000010 000000100 000001000 000010000 000100000 001000000 010000000 100000000";  -- one hot encoding for all states
36
signal present,nxt:states;
37
begin
38
  process(clk)
39
  begin
40
    if (clk'event and clk = '1') then
41
      if fwait = '1' then
42
        present <= present;
43
      else
44
        present <= nxt;
45
      end if;
46
    end if;
47
  end process;
48
 
49
  process(present,ireq,branch,bflag,bcarry,icarry,p1,e_ei,mc_ei,aim,clr,addsub,dec_mode)
50
  begin
51
    case present is
52
      -- reset
53
      when s0 =>
54
      fetch <= '0';
55
      op_sync <= '0';
56
      pci <= '0';
57
      pq <= "00";
58
      fb <= '1';                              -- force BRK                              
59
      od <= '1';                              -- clear microcode sequencer
60
      mc_nop <= '0';
61
      if clr = '1' then
62
        nxt <= s0;
63
      else
64
        nxt <= s2;
65
      end if;
66
 
67
      -- fetch opcode
68
      when s1 =>
69
      pq <= "00";
70
      if ireq = '1' then                      -- if interrupt request
71
        od <= '0';
72
                fetch <= '0';
73
        fb <= '0';
74
        pci <= '0';                           -- PC doesn't increment
75
        op_sync <= '0';
76
        mc_nop <= '1';                        -- stop microcode execution
77
        nxt <= s8;                            -- goto s8
78
      else
79
        od <= '1';                            -- clear microcode sequencer
80
        fetch <= '1';                         -- fetch opcode
81
                fb <= '0';
82
        pci <= '1';                           -- PC increment
83
        if addsub = '1'then                   -- if ADD/SUB opcode may require an extra cycle for DAA/DAS adjustement
84
          op_sync <= '0';
85
          mc_nop <= '0';
86
          nxt <= s7;                          -- goto s7
87
        else
88
          if e_ei = '1' then                  -- if end of instruction is reached on fetch 
89
            mc_nop <= '1';
90
            if clr = '1' then                 -- if reset
91
              op_sync <= '0';
92
              nxt <= s0;                      -- goto reset 
93
            else
94
              op_sync <= '1';                 -- remain in this state to fetch a new opcode
95
              nxt <= s1;
96
            end if;
97
          else
98
            mc_nop <= '0';
99
            op_sync <= '0';                   -- goto s2
100
            nxt <= s2;
101
          end if;
102
        end if;
103
      end if;
104
 
105
      -- wait until end of instruction
106
      when s2 =>
107
      fetch <= '0';
108
      pq <= p1;
109
      fb <= '0';
110
      od <= '0';
111
      if branch = '0' then                    -- normal execution
112
        mc_nop <= '0';
113
        pci <= '0';
114
        if aim = '1' then                     -- opcode with indexed mode
115
          op_sync <= '0';
116
          nxt <= s5;
117
        else
118
          if mc_ei = '1' then                 -- if end of instruction is reached 
119
            if clr = '1' then
120
              op_sync <= '0';
121
              nxt <= s0;
122
            else
123
              op_sync <= '1';
124
              nxt <= s1;
125
            end if;
126
          else
127
            op_sync <= '0';
128
            nxt <= s2;
129
          end if;
130
        end if;
131
      else                                    -- branch opcode execution 
132
        pci <= '1';
133
        if bflag = '0' then                   -- branch not taken
134
          mc_nop <= '1';
135
          if clr = '1' then
136
            op_sync <= '0';
137
            nxt <= s0;
138
          else
139
            op_sync <= '1';
140
            nxt <= s1;
141
          end if;
142
        else
143
          mc_nop <= '0';
144
          op_sync <= '0';
145
          nxt <= s3;                          -- branch taken      
146
        end if;
147
      end if;
148
 
149
      -- branch taken: add branch offset to lsb PC
150
      when s3 =>
151
      fetch <= '0';
152
      pq <= p1;
153
      fb <= '0';
154
      od <= '0';
155
      pci <= '0';
156
      if bcarry = '0' then
157
        mc_nop <= '1';                        -- stops microcode execution to avoid PC msb adjustement
158
        if clr = '1' then
159
          op_sync <= '0';
160
          nxt <= s0;
161
        else
162
          op_sync <= '1';
163
          nxt <= s1;
164
        end if;
165
      else
166
        mc_nop <= '0';
167
        op_sync <= '0';
168
        nxt <= s4;
169
      end if;
170
 
171
      -- branch taken: adjust msb PC
172
      when s4 =>
173
      fetch <= '0';
174
      pq <= p1;
175
      fb <= '0';
176
      od <= '0';
177
      mc_nop <= '0';
178
      pci <= '0';
179
      if clr = '1' then
180
        op_sync <= '0';
181
        nxt <= s0;
182
      else
183
        op_sync <= '1';
184
        nxt <= s1;
185
      end if;
186
 
187
      when s5 =>                            -- opcode with absolute indexed mode
188
      fetch <= '0';
189
      pq <= p1;
190
      fb <= '0';
191
      od <= '0';
192
      pci <= '0';
193
      if mc_ei = '1' then                   -- if end of instruction is reached 
194
        if icarry = '0' then
195
          mc_nop <= '1';
196
          if clr = '1' then
197
            op_sync <= '0';
198
            nxt <= s0;
199
          else
200
            op_sync <= '1';
201
            nxt <= s1;
202
          end if;
203
        else
204
          op_sync <= '0';
205
          mc_nop <= '0';
206
          nxt <= s6;
207
        end if;
208
      else
209
        op_sync <= '0';
210
        mc_nop <= '0';
211
        nxt <= s5;
212
      end if;
213
 
214
      when s6 =>                            -- opcode with absolute indexed mode: add carry to msb PC
215
      fetch <= '0';
216
      pq <= p1;
217
      fb <= '0';
218
      od <= '0';
219
      pci <= '0';
220
      if clr = '1' then
221
        mc_nop <= '0';
222
        op_sync <= '0';
223
        nxt <= s0;
224
      else
225
        mc_nop <= '1';
226
        op_sync <= '1';
227
        nxt <= s1;
228
      end if;
229
 
230
      -- ADD/SUB decimal adjustement extra cycle
231
      when s7 =>
232
      fetch <= '0';
233
      pq <= p1;
234
      fb <= '0';
235
      od <= '0';
236
      pci <= '0';
237
      if mc_ei = '1' then
238
        if dec_mode = '0' then
239
          mc_nop <= '1';
240
        else
241
          mc_nop <= '0';
242
        end if;
243
        if clr = '1' then
244
          op_sync <= '0';
245
          nxt <= s0;
246
        else
247
          op_sync <= '1';
248
          nxt <= s1;
249
        end if;
250
      else
251
        mc_nop <= '0';
252
        op_sync <= '0';
253
        nxt <= s7;
254
      end if;
255
 
256
      when s8 =>
257
      pq <= "00";
258
      od <= '1';                            -- clear microcode sequencer
259
      fetch <= '0';
260
      fb <= '1';                            -- force load BRK to opcode register 
261
      pci <= '0';                           -- PC doesn't increment
262
      op_sync <= '1';
263
      mc_nop <= '0';
264
      nxt <= s2;                            -- goto s2
265
 
266
      -- illegal state covering
267
      when others =>
268
      fetch <= '0';
269
      op_sync <= '0';
270
      pci <= '0';
271
      pq <= "00";
272
      fb <= '0';
273
      od <= '1';
274
      mc_nop <= '0';
275
      nxt <= s0;
276
 
277
    end case;
278
  end process;
279
end rtl;
280
 
281
 

powered by: WebSVN 2.1.0

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