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

Subversion Repositories opencpu32

[/] [opencpu32/] [trunk/] [hdl/] [opencpu32/] [ControlUnit.vhd] - Blame information for rev 29

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

Line No. Rev Author Line
1 22 leonardoar
--! @file
2
--! @brief ControlUnit http://en.wikipedia.org/wiki/Control_unit
3
 
4
--! Use standard library and import the packages (std_logic_1164,std_logic_unsigned,std_logic_arith)
5
library IEEE;
6
use ieee.std_logic_1164.all;
7
use ieee.std_logic_unsigned.all;
8
use ieee.std_logic_arith.all;
9
 
10
--! Use CPU Definitions package
11
use work.pkgOpenCPU32.all;
12
 
13
--! The control unit coordinates the input and output devices of a computer system. It fetches the code of all of the instructions \n
14
--! in the microprograms. It directs the operation of the other units by providing timing and control signals. \n
15
--! all computer resources are managed by the Control Unit.It directs the flow of data between the cpu and the other devices.\n
16
--! The outputs of the control unit control the activity of the rest of the device. A control unit can be thought of as a finite-state machine.
17
 
18
--! The purpose of datapaths is to provide routes for data to travel between functional units.
19
entity ControlUnit is
20 24 leonardoar
    generic (n : integer := nBits - 1);                                                                 --! Generic value (Used to easily change the size of the Alu on the package)
21
         Port ( reset : in  STD_LOGIC;
22 28 leonardoar
           clk : in  STD_LOGIC;                                                                                         --! Main system clock
23
           FlagsDp : in  STD_LOGIC_VECTOR (n downto 0);                          --! Flags comming from the Datapath
24
           DataDp : in  STD_LOGIC_VECTOR (n downto 0);                           --! Data comming from the Datapath
25
           MuxDp : out  STD_LOGIC_VECTOR (2 downto 0);                           --! Select on datapath data from (Memory, Imediate, RegFileA, RegFileB, AluOut)
26 27 leonardoar
                          MuxRegDp : out STD_LOGIC_VECTOR(1 downto 0);                           --! Select Alu InputA (Memory,Imediate,RegFileA)
27 28 leonardoar
           ImmDp : out  STD_LOGIC_VECTOR (n downto 0);                           --! Imediate value passed to the Datapath
28 27 leonardoar
           DpAluOp : out  aluOps;                                                                                       --! Alu operations
29 28 leonardoar
                          DpRegFileWriteAddr : out  generalRegisters;                           --! General register address to write
30
           DpRegFileWriteEn : out  STD_LOGIC;                                                   --! Enable register write
31
           DpRegFileReadAddrA : out  generalRegisters;                          --! General register address to read
32
           DpRegFileReadAddrB : out  generalRegisters;                          --! General register address to read
33
           DpRegFileReadEnA : out  STD_LOGIC;                                                   --! Enable register read (PortA)
34
           DpRegFileReadEnB : out  STD_LOGIC;                                                   --! Enable register read (PortB)
35
           MemoryDataReadEn : out std_logic;                                                            --! Enable Main memory read
36
                          MemoryDataWriteEn: out std_logic;                                                             --! Enable Main memory write
37
                          MemoryDataInput : in  STD_LOGIC_VECTOR (n downto 0);   --! Incoming data from main memory
38
           MemoryDataAddr : out  STD_LOGIC_VECTOR (n downto 0);  --! Main memory write address
39
           MemoryDataOut : out  STD_LOGIC_VECTOR (n downto 0));  --! Data to write on main memory
40 22 leonardoar
end ControlUnit;
41
 
42
--! @brief ControlUnit http://en.wikipedia.org/wiki/Control_unit
43
--! @details The control unit receives external instructions or commands which it converts into a sequence of control signals that the control \n
44
--! unit applies to data path to implement a sequence of register-transfer level operations.
45
architecture Behavioral of ControlUnit is
46 26 leonardoar
 
47 25 leonardoar
signal currentCpuState : controlUnitStates;                                     -- CPU states
48
signal nextCpuState    : controlUnitStates;                                     -- CPU states
49 26 leonardoar
 
50
signal currentExState  : executionStates;                                               -- Execution states
51
signal nextExState     : executionStates;                                               -- Execution states
52
 
53 25 leonardoar
signal PC              : std_logic_vector(n downto 0);   -- Program Counter
54
signal IR              : std_logic_vector(n downto 0);   -- Intruction register
55
signal currInstruction : std_logic_vector(n downto 0);   -- Current Intruction
56 22 leonardoar
begin
57 24 leonardoar
 
58 26 leonardoar
        -- Next state logic (CPU, fetch, decode, execute states)
59 24 leonardoar
        process (clk, reset)
60
        begin
61
                if (reset = '1') then
62 26 leonardoar
                        currentCpuState <= initial;
63 24 leonardoar
                elsif rising_edge(clk) then
64
                        currentCpuState <= nextCpuState;
65
                end if;
66
        end process;
67
 
68 26 leonardoar
        -- Next state logic (Execution states)
69
        process (clk, currentCpuState)
70
        begin
71 27 leonardoar
                if ( (currentCpuState /= execute) and (currentCpuState /= executing) ) then
72
                        currentExState <= initInstructionExecution;
73 26 leonardoar
                elsif rising_edge(clk) then
74
                        currentExState <= nextExState;
75
                end if;
76
        end process;
77
 
78 29 leonardoar
        -- States Fetch, decode, execute from the processor (Also handles the execution of jump instructions)
79 24 leonardoar
        process (currentCpuState)
80 25 leonardoar
        variable cyclesExecute : integer range 0 to 20; -- Cycles to wait while executing instruction
81 29 leonardoar
        variable opcodeIR : std_logic_vector(5 downto 0);
82
        variable operand_reg1 : std_logic_vector(3 downto 0);
83
        variable operand_imm  : std_logic_vector(21 downto 0);
84 24 leonardoar
        begin
85 29 leonardoar
                opcodeIR := IR((IR'HIGH) downto (IR'HIGH - 5));
86
                operand_reg1 := IR((IR'HIGH - 6) downto (IR'HIGH - 9));         -- 4 bits register operand1 (Max 16 registers)
87
                operand_imm  := IR((IR'HIGH - 10) downto (IR'LOW));                     -- 22 bits imediate value (Max value 4194304)
88 24 leonardoar
                case currentCpuState is
89
                        -- Initial state left from reset ...
90
                        when initial =>
91 25 leonardoar
                                cyclesExecute := 0;
92 24 leonardoar
                                PC <= (others => '0');
93 25 leonardoar
                                IR <= (others => '0');
94 24 leonardoar
                                MemoryDataAddr <= (others => '0');
95 28 leonardoar
                                MemoryDataReadEn <= '0';
96
                                MemoryDataWriteEn <= '0';
97 26 leonardoar
                                MemoryDataAddr <= (others => '0');
98 24 leonardoar
                                nextCpuState <= fetch;
99
 
100
                        -- Fetch state (Go to memory and get a instruction)
101
                        when fetch =>
102
                                -- Increment program counter (Remember that PC will be update only on the next cycle...
103
                                PC <= PC + conv_std_logic_vector(1, nBits);
104
                                MemoryDataAddr <= PC;   -- Warning PC is not 1 yet...
105
                                IR <= MemoryDataInput;
106 28 leonardoar
                                MemoryDataReadEn <= '1';
107 24 leonardoar
                                nextCpuState <= decode;
108
 
109 25 leonardoar
                        -- Detect with instruction came from memory, set the number of cycles to execute...
110 24 leonardoar
                        when decode =>
111 28 leonardoar
                                MemoryDataReadEn <= '0';
112
                                MemoryDataWriteEn <= '0';
113 25 leonardoar
 
114
                                -- The high attribute points to the highes bit position
115 26 leonardoar
                                case opcodeIR is
116 27 leonardoar
                                        when mov_reg | mov_val | add_reg | sub_reg | and_reg | or_reg | xor_reg =>
117 25 leonardoar
                                                        nextCpuState <= execute;
118 27 leonardoar
                                                        cyclesExecute := 3;     -- Wait 3 cycles for mov operation
119 25 leonardoar
                                                        currInstruction <= IR;
120 29 leonardoar
 
121
                                        when jmp_val | jmpr_val =>
122
                                                nextCpuState <= execute;
123
                                                cyclesExecute := 1;
124
 
125 26 leonardoar
                                        -- Invalid instruction (Now will be ignored, but latter should raise a trap
126 29 leonardoar
                                        when others =>
127
                                                null;
128 25 leonardoar
                                end case;
129 24 leonardoar
 
130 25 leonardoar
                        -- Wait while the process that handles the execution works..
131
                        when execute =>
132 29 leonardoar
                                -- On the case of jump instructions, it's execution will be handled on this process
133
                                case opcodeIR is
134
                                        when jmp_val =>
135
                                                PC      <= "0000000000" & operand_imm;
136
                                        when jmpr_val =>
137
                                                PC      <= PC + ("0000000000" & operand_imm);
138
                                        when others =>
139
                                                null;
140
                                end case;
141
 
142 26 leonardoar
                                if cyclesExecute = 0 then
143
                                        -- Finish the instruction execution get next
144 25 leonardoar
                                        nextCpuState <= fetch;
145 26 leonardoar
                                else
146
                                        nextCpuState <= executing;
147
                                end if;
148
 
149
                        -- Just wait a cycle and back again to execute state which verify if still need to wait some cycles
150
                        when executing =>
151
                                cyclesExecute := cyclesExecute - 1;
152
                                nextCpuState <= execute;
153
 
154 24 leonardoar
                        when others =>
155
                                null;
156
                end case;
157 25 leonardoar
        end process;
158
 
159 29 leonardoar
        -- Process that handles the execution of each instruction (Excluding the call and jump instructions)
160 26 leonardoar
        process (currentExState)
161
        --variable operando1_reg : std_logic_vector(generalRegisters'range);
162 27 leonardoar
        variable opcodeIR     : std_logic_vector(5 downto 0);
163
        variable operand_reg1 : std_logic_vector(3 downto 0);
164
        variable operand_reg2 : std_logic_vector(3 downto 0);
165
        variable operand_imm  : std_logic_vector(21 downto 0);
166 25 leonardoar
        begin
167 27 leonardoar
                -- Parse the common operands
168
                opcodeIR := IR((IR'HIGH) downto (IR'HIGH - 5));                                 -- 6 Bits opcode (Max 64 instructions)
169
                operand_reg1 := IR((IR'HIGH - 6) downto (IR'HIGH - 9));         -- 4 bits register operand1 (Max 16 registers)
170
                operand_reg2 := IR((IR'HIGH - 10) downto (IR'HIGH - 13));   -- 4 bits register operand2 (Max 16 registers
171
                operand_imm  := IR((IR'HIGH - 10) downto (IR'LOW));                     -- 22 bits imediate value (Max value 4194304)
172
 
173
                -- Select the instruction and init it's execution
174 26 leonardoar
                case currentExState is
175 27 leonardoar
                        when initInstructionExecution =>
176
                                case opcodeIR is
177
                                        -- MOV r2,r1 (See the testDatapath to see how to drive the datapath for this function)
178
                                        when mov_reg =>
179
                                                MuxDp <= muxPos(fromRegFileB);
180
                                                DpRegFileReadAddrB <= Num2reg(conv_integer(UNSIGNED(operand_reg2)));
181
                                                DpRegFileWriteAddr <= Num2reg(conv_integer(UNSIGNED(operand_reg1)));
182
                                                DpRegFileReadEnB <= '1';
183
                                                nextExState <= writeRegister;
184
 
185
                                        -- ADD r2,r0 (See the testDatapath to see how to drive the datapath for this function)
186
                                        when add_reg | sub_reg | and_reg | or_reg | xor_reg =>
187
                                                MuxDp <= muxPos(fromAlu);
188
                                                MuxRegDp <= muxRegPos(fromRegFileA);
189
                                                DpRegFileReadAddrA <= Num2reg(conv_integer(UNSIGNED(operand_reg1)));    -- Read first operand
190
                                                DpRegFileReadAddrB <= Num2reg(conv_integer(UNSIGNED(operand_reg2))); -- Read second operand
191
                                                DpRegFileReadEnA <= '1';
192
                                                DpRegFileReadEnB <= '1';
193
                                                DpRegFileWriteAddr <= Num2reg(conv_integer(UNSIGNED(operand_reg1)));    -- Point to write in first operand (pointing to register)                                       
194
                                                DpAluOp <= opcode2AluOp(opcodeIR);      -- Select the alu operation from the operand
195
                                                nextExState <= writeRegister;
196
 
197
                                        -- MOV r0,10d (See the testDatapath to see how to drive the datapath for this function)
198
                                        when mov_val =>
199
                                                MuxDp <= muxPos(fromImediate);
200
                                                DpRegFileWriteAddr <= Num2reg(conv_integer(UNSIGNED(operand_reg1)));
201
                                                ImmDp <= "0000000000" & operand_imm;    -- & is used to concatenate signals
202
                                                nextExState <= writeRegister;
203
 
204
                                        -- ADD r3,2 (r2 <= r2+2) (See the testDatapath to see how to drive the datapath for this function)
205
                                        when add_val | sub_val | and_val | or_val | xor_val =>
206
                                                MuxDp <= muxPos(fromAlu);
207
                                                MuxRegDp <= muxRegPos(fromImediate);
208
                                                DpRegFileWriteAddr <= Num2reg(conv_integer(UNSIGNED(operand_reg1)));
209
                                                DpRegFileReadAddrB <= Num2reg(conv_integer(UNSIGNED(operand_reg1)));    -- Read first operand
210
                                                DpRegFileReadEnB <= '1';
211
                                                ImmDp <= "0000000000" & operand_imm;    -- & is used to concatenate signals                                             
212
                                                DpAluOp <= opcode2AluOp(opcodeIR);      -- Select the alu operation from the operand
213
                                                nextExState <= writeRegister;
214
 
215 26 leonardoar
                                        when others =>
216
                                                null;
217
                                end case;
218 27 leonardoar
 
219
                        -- Write something on the register files
220
                        when writeRegister =>
221
                                DpRegFileWriteEn <= '1';
222
                                nextExState <= releaseWriteRead;
223
 
224
                        -- Release lines (Reset Datapath lines to something that does nothing...)
225
                        when releaseWriteRead =>
226
                                DpRegFileReadEnB <= '0';
227
                                DpRegFileReadEnA <= '0';
228
                                DpRegFileWriteEn <= '0';
229
 
230 26 leonardoar
                        when others =>
231
                                null;
232
                end case;
233 24 leonardoar
        end process;
234 22 leonardoar
 
235
end Behavioral;
236
 

powered by: WebSVN 2.1.0

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