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

Subversion Repositories cowgirl

[/] [cowgirl/] [trunk/] [control.vhdl] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 thebeekeep
-- 10/24/2005
2
-- Control Unit
3
 
4
 
5
 
6
library ieee;
7
use ieee.std_logic_1164.all;
8
 
9
entity control is port(
10
  instr:        in std_logic_vector(15 downto 0);
11
  clk:          in std_logic;
12
  reset:        in std_logic;
13
  mem_ready:    in std_logic;
14
  a_or_l:       out std_logic;
15
  op:           out std_logic_vector(2 downto 0);
16
  addr_a:       out std_logic_vector(2 downto 0);
17
  addr_b:       out std_logic_vector(2 downto 0);
18
  reg_addr:     out std_logic_vector(2 downto 0);
19
  to_regs:      out std_logic_vector(15 downto 0);
20
  to_pc:        out std_logic_vector(15 downto 0);
21
  load_pc:      out std_logic;
22
  reg_wr:       out std_logic;
23
  alu_or_imm:   out std_logic;
24
  next_instr:   out std_logic;
25
  curr_state:   out std_logic_vector(15 downto 0)
26
  );
27
end control;
28
 
29
architecture control_arch of control is
30
 
31
  type state_type is (idle, alu_arith, alu_logic, load_imm_lo, load_imm_hi, mov_r, mov_w, mem, len, jmp_br, save_addr, wr_pc, halt, ret, compare, set_flags, write_res, alu_wait);
32
  signal state, next_state : state_type;
33
 
34
  signal return_addr: std_logic_vector(15 downto 0);
35
  signal temp_imm : std_logic_vector(15 downto 0) := x"0000";
36
 
37
begin
38
  -- don't forget to put the instruction in the sensitivity list!!!
39
  -- if you don't, nothing will happen, since the code won't run when the
40
  -- instruction changes!!
41
  state_logic:process(state, instr)
42
  begin
43
    case state is
44
      when idle =>
45
        curr_state <= x"0000";
46
        --initialize all signals to zero
47
        next_instr <= '1';
48
        a_or_l <= '0';
49
        op <= "000";
50
        addr_a <= "000";
51
        addr_b <= "000";
52
        --reg_addr <= "000";
53
        to_regs <= x"0000";
54
        to_pc <= x"0000";
55
        load_pc <= '0';
56
        reg_wr <= '0';
57
        --alu_or_imm <= '0';              -- 0 for alu, 1 for immediate
58
        case instr(15 downto 12) is
59
          when "0000" =>                                -- nop
60
            next_state <= idle;
61
          when "0001" =>                                -- return
62
            next_state <= ret;
63
          when "0010" =>                                -- alu arithmetic
64
            next_state <= alu_arith;
65
          when "0011" =>                                -- alu logic
66
            next_state <= alu_logic;
67
          when "0100" =>                                -- load immediate
68
            if instr(0) = '0' then
69
              next_state <= load_imm_lo;
70
            else
71
              next_state <= load_imm_hi;
72
            end if;
73
          when "0101" =>                                -- jump or branch
74
            next_state <= jmp_br;
75
          --when "0110" =>                              -- shift
76
            --next_state <= shift;
77
          when "0111" =>                                -- compare
78
            next_state <= compare;
79
          when "1000" =>                                -- move
80
            next_state <= mov_r;
81
          when "1001" =>                                -- memory access
82
            next_state <= mem;
83
          when "1110" =>                                -- len
84
            next_state <= len;
85
          when "1111" =>                                -- halt
86
            next_state <= halt;
87
          when others =>
88
            next_state <= idle;
89
        end case;
90
      when alu_arith =>
91
        curr_state <= x"0001";
92
        next_instr <= '0';
93
        alu_or_imm <= '0';
94
        a_or_l <= '0';
95
        op <= instr(2 downto 0);
96
        --op <= "001";
97
        addr_a <= instr(8 downto 6);
98
        addr_b <= instr(5 downto 3);
99
        --next_state <= write_res;
100
        next_state <= alu_wait;
101
      when alu_wait =>
102
        curr_state <= x"001A";
103
        next_instr <= '0';
104
        next_state <= write_res;
105
      when alu_logic =>
106
        curr_state <= x"0002";
107
        next_instr <= '0';
108
        a_or_l <= '1';
109
        op <= instr(2 downto 0);
110
        addr_a <= instr(8 downto 6);
111
        addr_b <= instr(5 downto 3);
112
        next_state <= write_res;
113
      when load_imm_lo =>
114
        next_instr <= '0';
115
        alu_or_imm <= '1';
116
        --reg_addr <= instr(11 downto 9);
117
        addr_a <= instr(11 downto 9);
118
        curr_state <= x"003A";
119
        temp_imm(7 downto 0) <= instr(8 downto 1);
120
        next_state <= idle;
121
      when load_imm_hi =>
122
        curr_state <= x"003B";
123
        next_instr <= '0';
124
        alu_or_imm <= '1';
125
        --reg_addr <= instr(11 downto 9);
126
        addr_a <= instr(11 downto 9);
127
        temp_imm(15 downto 8) <= instr(8 downto 1);
128
        to_regs <= temp_imm;
129
        reg_wr <= '1';
130
 
131
        next_state <= idle;
132
        --next_state <= write_res;
133
      when mov_r =>
134
        curr_state <= x"0004";
135
        next_instr <= '0';
136
        addr_a <= instr(8 downto 6);
137
        next_state <= mov_w;
138
      when mov_w =>
139
        curr_state <= x"0005";
140
        next_instr <= '0';
141
        reg_wr <= '1';
142
        reg_addr <= instr(11 downto 9);
143
        next_state <= idle;
144
      when wr_pc =>
145
        curr_state <= x"0006";
146
        next_instr <= '0';
147
        load_pc <= '1';
148
        to_pc <= return_addr;
149
      when write_res =>
150
        curr_state <= x"0007";
151
        next_instr <= '0';
152
        reg_addr <= instr(11 downto 9);
153
        reg_wr <= '1';
154
        next_state <= idle;
155
      when halt =>
156
        curr_state <= x"0008";
157
        next_instr <= '0';
158
        next_state <= halt;
159
      when others =>
160
        curr_state <= x"0009";
161
        next_instr <= '0';
162
        next_state <= idle;
163
    end case;
164
  end process state_logic;
165
 
166
 
167
 
168
  state_reg:process(clk, reset)
169
  begin
170
    if reset = '1' then
171
      state <= idle;
172
      -- i set clk='0' here because it was transitioning states after 1 full
173
      -- clock cycle, which made things not work, since i'm looking at the
174
      -- instruction for how to process things.  and the instruction has
175
      -- changed by the time the state changes
176
      -- that doesn't seem to be working though, and it confuses me
177
    elsif (clk'EVENT and clk='1') then
178
      state <= next_state;
179
    end if;
180
  end process state_reg;
181
end control_arch;

powered by: WebSVN 2.1.0

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