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

Subversion Repositories opencpu32

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

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 30 leonardoar
           FlagsDp : in  STD_LOGIC_VECTOR (2 downto 0);                          --! Flags comming from the Datapath
24 28 leonardoar
           DataDp : in  STD_LOGIC_VECTOR (n downto 0);                           --! Data comming from the Datapath
25 31 leonardoar
                          outEnDp : out  typeEnDis;                                                                             --! Enable/Disable datapath output
26 42 leonardoar
           MuxDp : out  dpMuxInputs;                                                                            --! Select on datapath data from (Memory, Imediate, RegFileA, RegFileB, AluOut)
27 47 leonardoar
                          MuxRegDp : out dpMuxAluIn;                                                                            --! Select Alu InputA (Memory,Imediate,RegFileA)
28 28 leonardoar
           ImmDp : out  STD_LOGIC_VECTOR (n downto 0);                           --! Imediate value passed to the Datapath
29 27 leonardoar
           DpAluOp : out  aluOps;                                                                                       --! Alu operations
30 28 leonardoar
                          DpRegFileWriteAddr : out  generalRegisters;                           --! General register address to write
31
           DpRegFileWriteEn : out  STD_LOGIC;                                                   --! Enable register write
32
           DpRegFileReadAddrA : out  generalRegisters;                          --! General register address to read
33
           DpRegFileReadAddrB : out  generalRegisters;                          --! General register address to read
34
           DpRegFileReadEnA : out  STD_LOGIC;                                                   --! Enable register read (PortA)
35
           DpRegFileReadEnB : out  STD_LOGIC;                                                   --! Enable register read (PortB)
36
           MemoryDataReadEn : out std_logic;                                                            --! Enable Main memory read
37
                          MemoryDataWriteEn: out std_logic;                                                             --! Enable Main memory write
38
                          MemoryDataInput : in  STD_LOGIC_VECTOR (n downto 0);   --! Incoming data from main memory
39 30 leonardoar
           MemoryDataRdAddr : out  STD_LOGIC_VECTOR (n downto 0);        --! Main memory Read address
40
                          MemoryDataWrAddr : out  STD_LOGIC_VECTOR (n downto 0); --! Main memory Write address
41 28 leonardoar
           MemoryDataOut : out  STD_LOGIC_VECTOR (n downto 0));  --! Data to write on main memory
42 22 leonardoar
end ControlUnit;
43
 
44
--! @brief ControlUnit http://en.wikipedia.org/wiki/Control_unit
45
--! @details The control unit receives external instructions or commands which it converts into a sequence of control signals that the control \n
46
--! unit applies to data path to implement a sequence of register-transfer level operations.
47
architecture Behavioral of ControlUnit is
48 26 leonardoar
 
49 25 leonardoar
signal currentCpuState : controlUnitStates;                                     -- CPU states
50
signal nextCpuState    : controlUnitStates;                                     -- CPU states
51 26 leonardoar
 
52
signal currentExState  : executionStates;                                               -- Execution states
53
signal nextExState     : executionStates;                                               -- Execution states
54
 
55 25 leonardoar
signal PC              : std_logic_vector(n downto 0);   -- Program Counter
56
signal IR              : std_logic_vector(n downto 0);   -- Intruction register
57
signal currInstruction : std_logic_vector(n downto 0);   -- Current Intruction
58 22 leonardoar
begin
59 24 leonardoar
 
60 26 leonardoar
        -- Next state logic (CPU, fetch, decode, execute states)
61 24 leonardoar
        process (clk, reset)
62
        begin
63
                if (reset = '1') then
64 26 leonardoar
                        currentCpuState <= initial;
65 24 leonardoar
                elsif rising_edge(clk) then
66
                        currentCpuState <= nextCpuState;
67
                end if;
68
        end process;
69
 
70 26 leonardoar
        -- Next state logic (Execution states)
71
        process (clk, currentCpuState)
72
        begin
73 33 leonardoar
                if (reset = '1') then
74 27 leonardoar
                        currentExState <= initInstructionExecution;
75 26 leonardoar
                elsif rising_edge(clk) then
76
                        currentExState <= nextExState;
77
                end if;
78
        end process;
79
 
80 29 leonardoar
        -- States Fetch, decode, execute from the processor (Also handles the execution of jump instructions)
81 24 leonardoar
        process (currentCpuState)
82 44 leonardoar
        variable cyclesExecute : integer range 0 to 20;          -- Cycles to wait while executing instruction
83 29 leonardoar
        variable opcodeIR : std_logic_vector(5 downto 0);
84
        variable operand_reg1 : std_logic_vector(3 downto 0);
85
        variable operand_imm  : std_logic_vector(21 downto 0);
86 44 leonardoar
        variable accDp : std_logic_vector(n downto 0);                   -- Value stored from DataPath
87 24 leonardoar
        begin
88 29 leonardoar
                opcodeIR := IR((IR'HIGH) downto (IR'HIGH - 5));
89
                operand_reg1 := IR((IR'HIGH - 6) downto (IR'HIGH - 9));         -- 4 bits register operand1 (Max 16 registers)
90
                operand_imm  := IR((IR'HIGH - 10) downto (IR'LOW));                     -- 22 bits imediate value (Max value 4194304)
91 24 leonardoar
                case currentCpuState is
92
                        -- Initial state left from reset ...
93
                        when initial =>
94 25 leonardoar
                                cyclesExecute := 0;
95 24 leonardoar
                                PC <= (others => '0');
96 25 leonardoar
                                IR <= (others => '0');
97 30 leonardoar
                                MemoryDataRdAddr <= (others => '0');
98 28 leonardoar
                                MemoryDataReadEn <= '0';
99 30 leonardoar
                                MemoryDataWriteEn <= '0';
100 24 leonardoar
                                nextCpuState <= fetch;
101
 
102
                        -- Fetch state (Go to memory and get a instruction)
103
                        when fetch =>
104
                                -- Increment program counter (Remember that PC will be update only on the next cycle...
105
                                PC <= PC + conv_std_logic_vector(1, nBits);
106 30 leonardoar
                                MemoryDataRdAddr <= PC; -- Warning PC is not 1 yet...
107 24 leonardoar
                                IR <= MemoryDataInput;
108 28 leonardoar
                                MemoryDataReadEn <= '1';
109 44 leonardoar
                                MemoryDataWriteEn <= '0';
110 24 leonardoar
                                nextCpuState <= decode;
111
 
112 25 leonardoar
                        -- Detect with instruction came from memory, set the number of cycles to execute...
113 24 leonardoar
                        when decode =>
114 28 leonardoar
                                MemoryDataReadEn <= '0';
115
                                MemoryDataWriteEn <= '0';
116 25 leonardoar
 
117
                                -- The high attribute points to the highes bit position
118 26 leonardoar
                                case opcodeIR is
119 44 leonardoar
                                        when mov_reg | mov_val | add_reg | add_val | sub_reg | and_reg | or_reg | xor_reg =>
120 25 leonardoar
                                                        nextCpuState <= execute;
121 34 leonardoar
                                                        cyclesExecute := 1;     -- Wait 1 cycles
122 25 leonardoar
                                                        currInstruction <= IR;
123 44 leonardoar
 
124
                                        when ld_reg | ld_val | stom_reg | stom_val =>
125
                                                        nextCpuState <= execute;
126
                                                        cyclesExecute := 2;     -- Wait 2 cycles
127
                                                        currInstruction <= IR;
128 29 leonardoar
 
129
                                        when jmp_val | jmpr_val =>
130
                                                nextCpuState <= execute;
131 34 leonardoar
                                                cyclesExecute := 0;              -- No Wait cycle
132 29 leonardoar
 
133 26 leonardoar
                                        -- Invalid instruction (Now will be ignored, but latter should raise a trap
134 29 leonardoar
                                        when others =>
135
                                                null;
136 25 leonardoar
                                end case;
137 24 leonardoar
 
138 25 leonardoar
                        -- Wait while the process that handles the execution works..
139
                        when execute =>
140 29 leonardoar
                                -- On the case of jump instructions, it's execution will be handled on this process
141
                                case opcodeIR is
142 31 leonardoar
 
143 29 leonardoar
                                        when jmp_val =>
144 48 leonardoar
                                                PC      <= "0000000000" & operand_imm;
145
                                                nextCpuState <= fetch;
146 31 leonardoar
 
147 29 leonardoar
                                        when jmpr_val =>
148 48 leonardoar
                                                PC      <= PC + ("0000000000" & operand_imm);
149
                                                nextCpuState <= fetch;
150 31 leonardoar
 
151 46 leonardoar
                                        -- ld r5,20 (Load into r5 register the content of the memory at address 20)
152 31 leonardoar
                                        when ld_val =>
153
                                                MemoryDataRdAddr <= "0000000000" & operand_imm;
154 46 leonardoar
                                                MemoryDataReadEn <= '1';
155
                                                if cyclesExecute = 0 then
156
                                                        MemoryDataReadEn <= '0';
157
                                                end if;
158 31 leonardoar
 
159 44 leonardoar
                                        -- STORE r1,10 (Store the value 10 on memory address pointed by r1)
160
                                        when stom_val =>
161
                                                -- And put the imediate value ...                                                       
162
                                                        MemoryDataOut <= "0000000000" & operand_imm;
163
                                                        if cyclesExecute = 1 then
164
                                                                -- After the register data is avaible in DataDp we put it's address and                                                         
165
                                                                accDp := DataDp;
166
                                                                MemoryDataWrAddr <= accDp;
167
                                                        elsif cyclesExecute = 0 then
168
                                                                -- strobe in to enter the data
169
                                                                MemoryDataWriteEn <= '1';
170
                                                        end if;
171 31 leonardoar
 
172 29 leonardoar
                                        when others =>
173
                                                null;
174
                                end case;
175
 
176 26 leonardoar
                                if cyclesExecute = 0 then
177
                                        -- Finish the instruction execution get next
178 25 leonardoar
                                        nextCpuState <= fetch;
179 26 leonardoar
                                else
180 44 leonardoar
                                        nextCpuState <= executing;
181 26 leonardoar
                                end if;
182
 
183
                        -- Just wait a cycle and back again to execute state which verify if still need to wait some cycles
184
                        when executing =>
185
                                cyclesExecute := cyclesExecute - 1;
186 44 leonardoar
                                nextCpuState <= execute;
187 26 leonardoar
 
188 24 leonardoar
                        when others =>
189
                                null;
190
                end case;
191 25 leonardoar
        end process;
192
 
193 31 leonardoar
        -- Process that handles the execution of each instruction (Excluding the call,jump,load,store instructions)
194 26 leonardoar
        process (currentExState)
195
        --variable operando1_reg : std_logic_vector(generalRegisters'range);
196 27 leonardoar
        variable opcodeIR     : std_logic_vector(5 downto 0);
197
        variable operand_reg1 : std_logic_vector(3 downto 0);
198
        variable operand_reg2 : std_logic_vector(3 downto 0);
199
        variable operand_imm  : std_logic_vector(21 downto 0);
200 25 leonardoar
        begin
201 27 leonardoar
                -- Parse the common operands
202
                opcodeIR := IR((IR'HIGH) downto (IR'HIGH - 5));                                 -- 6 Bits opcode (Max 64 instructions)
203
                operand_reg1 := IR((IR'HIGH - 6) downto (IR'HIGH - 9));         -- 4 bits register operand1 (Max 16 registers)
204
                operand_reg2 := IR((IR'HIGH - 10) downto (IR'HIGH - 13));   -- 4 bits register operand2 (Max 16 registers
205
                operand_imm  := IR((IR'HIGH - 10) downto (IR'LOW));                     -- 22 bits imediate value (Max value 4194304)
206
 
207
                -- Select the instruction and init it's execution
208 26 leonardoar
                case currentExState is
209 27 leonardoar
                        when initInstructionExecution =>
210 33 leonardoar
                                nextExState <= waitToExecute;
211
 
212
                        when waitToExecute =>
213
                                if ( (currentCpuState /= execute) and (currentCpuState /= executing) ) then
214 44 leonardoar
                                        nextExState <= initInstructionExecution;
215 33 leonardoar
                                else
216
                                        case opcodeIR is
217 27 leonardoar
                                        -- MOV r2,r1 (See the testDatapath to see how to drive the datapath for this function)
218
                                        when mov_reg =>
219 42 leonardoar
                                                MuxDp <= fromRegFileB;
220 27 leonardoar
                                                DpRegFileReadAddrB <= Num2reg(conv_integer(UNSIGNED(operand_reg2)));
221
                                                DpRegFileWriteAddr <= Num2reg(conv_integer(UNSIGNED(operand_reg1)));
222
                                                DpRegFileReadEnB <= '1';
223
                                                nextExState <= writeRegister;
224
 
225 31 leonardoar
                                        -- LOAD r1,10 (Load into r1, the value in the main memory located at address 10)
226
                                        when ld_val =>
227 42 leonardoar
                                                MuxDp <= fromMemory;
228 31 leonardoar
                                                DpRegFileWriteAddr <= Num2reg(conv_integer(UNSIGNED(operand_reg1)));
229
                                                -- The part that interface with the memory is located on the first process
230
                                                nextExState <= writeRegister;
231
 
232 44 leonardoar
                                        -- STORE r1,10 (Store the value 10 on the main memory pointed by r1)
233 31 leonardoar
                                        when stom_val =>
234 42 leonardoar
                                        MuxDp <= fromRegFileB;
235 31 leonardoar
                                        DpRegFileReadAddrB <= Num2reg(conv_integer(UNSIGNED(operand_reg1)));
236 44 leonardoar
                                        DpRegFileReadEnB <= '1';
237 31 leonardoar
                                        -- The part that interface with the memory is located on the first process
238 44 leonardoar
                                        nextExState <= readRegisterB;
239 31 leonardoar
 
240 27 leonardoar
                                        -- ADD r2,r0 (See the testDatapath to see how to drive the datapath for this function)
241
                                        when add_reg | sub_reg | and_reg | or_reg | xor_reg =>
242 42 leonardoar
                                                MuxDp <= fromAlu;
243 47 leonardoar
                                                MuxRegDp <= fromRegFileA;
244 27 leonardoar
                                                DpRegFileReadAddrA <= Num2reg(conv_integer(UNSIGNED(operand_reg1)));    -- Read first operand
245
                                                DpRegFileReadAddrB <= Num2reg(conv_integer(UNSIGNED(operand_reg2))); -- Read second operand
246
                                                DpRegFileReadEnA <= '1';
247
                                                DpRegFileReadEnB <= '1';
248
                                                DpRegFileWriteAddr <= Num2reg(conv_integer(UNSIGNED(operand_reg1)));    -- Point to write in first operand (pointing to register)                                       
249
                                                DpAluOp <= opcode2AluOp(opcodeIR);      -- Select the alu operation from the operand
250
                                                nextExState <= writeRegister;
251
 
252
                                        -- MOV r0,10d (See the testDatapath to see how to drive the datapath for this function)
253
                                        when mov_val =>
254 42 leonardoar
                                                MuxDp <= fromImediate;
255 27 leonardoar
                                                DpRegFileWriteAddr <= Num2reg(conv_integer(UNSIGNED(operand_reg1)));
256
                                                ImmDp <= "0000000000" & operand_imm;    -- & is used to concatenate signals
257
                                                nextExState <= writeRegister;
258
 
259
                                        -- ADD r3,2 (r2 <= r2+2) (See the testDatapath to see how to drive the datapath for this function)
260
                                        when add_val | sub_val | and_val | or_val | xor_val =>
261 42 leonardoar
                                                MuxDp <= fromAlu;
262 47 leonardoar
                                                MuxRegDp <= fromImediate;
263 27 leonardoar
                                                DpRegFileWriteAddr <= Num2reg(conv_integer(UNSIGNED(operand_reg1)));
264
                                                DpRegFileReadAddrB <= Num2reg(conv_integer(UNSIGNED(operand_reg1)));    -- Read first operand
265
                                                DpRegFileReadEnB <= '1';
266
                                                ImmDp <= "0000000000" & operand_imm;    -- & is used to concatenate signals                                             
267
                                                DpAluOp <= opcode2AluOp(opcodeIR);      -- Select the alu operation from the operand
268
                                                nextExState <= writeRegister;
269
 
270 26 leonardoar
                                        when others =>
271
                                                null;
272 33 leonardoar
                                        end case;
273
                                end if;
274 27 leonardoar
 
275
                        -- Write something on the register files
276
                        when writeRegister =>
277
                                DpRegFileWriteEn <= '1';
278
                                nextExState <= releaseWriteRead;
279
 
280 31 leonardoar
                        when readRegisterB =>
281
                                DpRegFileReadEnB <= '1';
282
                                outEnDp <= enable;
283
                                nextExState <= releaseWriteRead;
284
 
285
                        when readRegisterA =>
286
                                DpRegFileReadEnA <= '1';
287
                                outEnDp <= enable;
288
                                nextExState <= releaseWriteRead;
289
 
290 27 leonardoar
                        -- Release lines (Reset Datapath lines to something that does nothing...)
291
                        when releaseWriteRead =>
292
                                DpRegFileReadEnB <= '0';
293
                                DpRegFileReadEnA <= '0';
294 31 leonardoar
                                DpRegFileWriteEn <= '0';
295 33 leonardoar
                                outEnDp <= disable;
296
                                -- Come back to waiting state
297 34 leonardoar
                                nextExState <= waitToExecute;
298 27 leonardoar
 
299 26 leonardoar
                        when others =>
300
                                null;
301
                end case;
302 24 leonardoar
        end process;
303 22 leonardoar
 
304
end Behavioral;
305
 

powered by: WebSVN 2.1.0

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