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 |
22 |
leonardoar |
clk : in STD_LOGIC;
|
23 |
24 |
leonardoar |
FlagsDp : in STD_LOGIC_VECTOR (n downto 0);
|
24 |
|
|
DataDp : in STD_LOGIC_VECTOR (n downto 0);
|
25 |
22 |
leonardoar |
MuxDp : out STD_LOGIC_VECTOR (2 downto 0);
|
26 |
24 |
leonardoar |
ImmDp : out STD_LOGIC_VECTOR (n downto 0);
|
27 |
22 |
leonardoar |
DpRegFileWriteAddr : out STD_LOGIC;
|
28 |
|
|
DpRegFileWriteEn : out STD_LOGIC;
|
29 |
|
|
DpRegFileReadAddrA : out STD_LOGIC;
|
30 |
|
|
DpRegFileReadAddrB : out STD_LOGIC;
|
31 |
|
|
DpRegFileReadEnA : out STD_LOGIC;
|
32 |
|
|
DpRegFileReadEnB : out STD_LOGIC;
|
33 |
24 |
leonardoar |
MemoryDataRead : out std_logic;
|
34 |
|
|
MemoryDataWrite : out std_logic;
|
35 |
|
|
MemoryDataInput : in STD_LOGIC_VECTOR (n downto 0);
|
36 |
|
|
MemoryDataAddr : out STD_LOGIC_VECTOR (n downto 0);
|
37 |
|
|
MemoryDataOut : out STD_LOGIC_VECTOR (n downto 0));
|
38 |
22 |
leonardoar |
end ControlUnit;
|
39 |
|
|
|
40 |
|
|
--! @brief ControlUnit http://en.wikipedia.org/wiki/Control_unit
|
41 |
|
|
--! @details The control unit receives external instructions or commands which it converts into a sequence of control signals that the control \n
|
42 |
|
|
--! unit applies to data path to implement a sequence of register-transfer level operations.
|
43 |
|
|
architecture Behavioral of ControlUnit is
|
44 |
25 |
leonardoar |
signal currentCpuState : controlUnitStates; -- CPU states
|
45 |
|
|
signal nextCpuState : controlUnitStates; -- CPU states
|
46 |
|
|
signal PC : std_logic_vector(n downto 0); -- Program Counter
|
47 |
|
|
signal IR : std_logic_vector(n downto 0); -- Intruction register
|
48 |
|
|
signal currInstruction : std_logic_vector(n downto 0); -- Current Intruction
|
49 |
22 |
leonardoar |
begin
|
50 |
24 |
leonardoar |
|
51 |
|
|
-- Next state logic
|
52 |
|
|
process (clk, reset)
|
53 |
|
|
begin
|
54 |
|
|
if (reset = '1') then
|
55 |
|
|
currentCpuState <= initial;
|
56 |
|
|
MemoryDataAddr <= (others => '0');
|
57 |
|
|
elsif rising_edge(clk) then
|
58 |
|
|
currentCpuState <= nextCpuState;
|
59 |
|
|
end if;
|
60 |
|
|
end process;
|
61 |
|
|
|
62 |
25 |
leonardoar |
-- States Fetch, decode, execute from the processor
|
63 |
24 |
leonardoar |
process (currentCpuState)
|
64 |
25 |
leonardoar |
variable cyclesExecute : integer range 0 to 20; -- Cycles to wait while executing instruction
|
65 |
24 |
leonardoar |
begin
|
66 |
|
|
case currentCpuState is
|
67 |
|
|
-- Initial state left from reset ...
|
68 |
|
|
when initial =>
|
69 |
25 |
leonardoar |
cyclesExecute := 0;
|
70 |
24 |
leonardoar |
PC <= (others => '0');
|
71 |
25 |
leonardoar |
IR <= (others => '0');
|
72 |
24 |
leonardoar |
MemoryDataRead <= (others => '0');
|
73 |
|
|
MemoryDataWrite <= (others => '0');
|
74 |
|
|
MemoryDataAddr <= (others => '0');
|
75 |
|
|
nextCpuState <= fetch;
|
76 |
|
|
|
77 |
|
|
-- Fetch state (Go to memory and get a instruction)
|
78 |
|
|
when fetch =>
|
79 |
|
|
-- Increment program counter (Remember that PC will be update only on the next cycle...
|
80 |
|
|
PC <= PC + conv_std_logic_vector(1, nBits);
|
81 |
|
|
MemoryDataAddr <= PC; -- Warning PC is not 1 yet...
|
82 |
|
|
IR <= MemoryDataInput;
|
83 |
|
|
MemoryDataRead <= '1';
|
84 |
|
|
nextCpuState <= decode;
|
85 |
|
|
|
86 |
25 |
leonardoar |
-- Detect with instruction came from memory, set the number of cycles to execute...
|
87 |
24 |
leonardoar |
when decode =>
|
88 |
|
|
MemoryDataRead <= '0';
|
89 |
25 |
leonardoar |
MemoryDataWrite <= '0';
|
90 |
|
|
|
91 |
|
|
-- The high attribute points to the highes bit position
|
92 |
|
|
case IR((IR'HIGH) downto (IR'HIGH - 5)) is
|
93 |
|
|
when mov_reg =>
|
94 |
|
|
nextCpuState <= execute;
|
95 |
|
|
cyclesExecute := 2;
|
96 |
|
|
currInstruction <= IR;
|
97 |
|
|
-- Invalid instruction (Now will be ignored, but latter shoud rais a trap
|
98 |
|
|
when others =>
|
99 |
|
|
end case;
|
100 |
24 |
leonardoar |
|
101 |
25 |
leonardoar |
-- Wait while the process that handles the execution works..
|
102 |
|
|
when execute =>
|
103 |
|
|
if cyclesExecute > 1 then
|
104 |
|
|
cyclesExecute := cyclesExecute - 1;
|
105 |
|
|
else
|
106 |
|
|
nextCpuState <= fetch;
|
107 |
|
|
end if;
|
108 |
24 |
leonardoar |
when others =>
|
109 |
|
|
null;
|
110 |
|
|
end case;
|
111 |
25 |
leonardoar |
end process;
|
112 |
|
|
|
113 |
|
|
-- Process that handles the execution of each instruction
|
114 |
|
|
process (currInstruction)
|
115 |
|
|
begin
|
116 |
|
|
|
117 |
24 |
leonardoar |
end process;
|
118 |
22 |
leonardoar |
|
119 |
|
|
end Behavioral;
|
120 |
|
|
|