-
Notifications
You must be signed in to change notification settings - Fork 1
/
EIU.vhd
160 lines (137 loc) · 5.07 KB
/
EIU.vhd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity EIU is port(
-- inputs
rst, clk, sendPC_memI,
-- to know if data requested real or not (not throw exceptions when no data needed!)
memEn: in std_logic;
-- alu res or stack pointer or INT
mem_address_mux_sel: in std_logic_vector(1 downto 0);
-- R destination, has idx of interrupt
Rd,
-- mem/stack | read/write | 16/32
mem_operI: in std_logic_vector(2 downto 0);
-- memory address from load,store OR index of INT
alu_res: in std_logic_vector(15 downto 0);
-- current Program Counter, Stack Pointer
PC, SP: in std_logic_vector(31 downto 0);
---
-- outputs
sendPC_memO: out std_logic;
-- mem/stack | read/write | 16/32
mem_operO: out std_logic_vector(2 downto 0);
-- could be alu res or stack pointer or INT or Excep
mem_address: out std_logic_vector(19 downto 0);
-- EXCEP FLAG
Exf: out std_logic
);
---
end entity;
--------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------
architecture arc_EIU of EIU is
signal EIU_to_EPC, EPC_to_EIU: std_logic_vector(31 downto 0);
constant Tp20: integer := 1048576;
constant RST_address: std_logic_vector(19 downto 0) := (others => '0');
constant EX1_address: std_logic_vector(19 downto 0) := (1 => '1', others => '0');
constant EX2_address: std_logic_vector(19 downto 0) := (2 => '1', others => '0');
constant IVT_address: std_logic_vector(19 downto 0) := (1 => '1', 2 => '1', others => '0');
begin
EPC: entity work.reg_N generic map (32) port map (clk, rst, EIU_to_EPC, EPC_to_EIU);
process(rst, clk)
begin
if rst='1' then
-- exc flag
ExF <= '0';
-- send mem[0] & m[1] to pc mux
-- mem oper = mem read 32
mem_operO <= "001";
-- mem address = 0
mem_address <= (others => '0');
-- avoid latch
sendPC_memO <= sendPC_memI;
-- avoid latching on GRABAGE
EIU_to_EPC <= EPC_to_EIU;
elsif rising_edge(clk) then
if mem_address_mux_sel="10" then
-- TODO: handle INT, hint: store a state
-- IDX is Rd
elsif mem_address_mux_sel="00" then
-- alu res --> data memory access
-- DATA ACCESS EXCEPTIONS
-- cant read/write 16 when res > 0xFF00
if ( (mem_operI="000" and memEn='1') or mem_operI="010" ) and alu_res >= X"FF00" then
EIU_to_EPC <= PC;
mem_address <= EX2_address;
mem_operO <= "001";
sendPC_memO <= '1';
ExF <= '1';
-- cant read/write 32 when res >= 0xFF00 - 1
elsif ( mem_operI="001" or mem_operI="011" ) and alu_res >= X"FEFF" then
EIU_to_EPC <= PC;
mem_address <= EX2_address;
mem_operO <= "001";
sendPC_memO <= '1';
ExF <= '1';
else
ExF <= '0';
sendPC_memO <= sendPC_memI;
mem_operO <= mem_operI;
mem_address(19 downto 16) <= (others=>'0');
mem_address(15 downto 0) <= alu_res;
end if;
elsif mem_address_mux_sel="01" then
-- STACK access, push
-- : check for exceptions
-- TODO: FLUSH ALL AFTER EXCEPTION
-- TODO: HLT AFTER EXCEPTION
-- STACK EXCEPTIONS
-- cant read 16 when pointing first place
if mem_operI="100" and unsigned(SP) = Tp20-1 then
EIU_to_EPC <= PC;
mem_address <= EX1_address;
mem_operO <= "001";
sendPC_memO <= '1';
ExF <= '1';
-- cant read 32 when pointing first or second place
elsif mem_operI="101" and unsigned(SP) >= Tp20-2 then
EIU_to_EPC <= PC;
mem_address <= EX1_address;
mem_operO <= "001";
sendPC_memO <= '1';
ExF <= '1';
-- cant write 32 when pointing first place
elsif mem_operI="111" and unsigned(SP) >= Tp20-1 then
EIU_to_EPC <= PC;
mem_address <= EX1_address;
mem_operO <= "001";
sendPC_memO <= '1';
ExF <= '1';
-- : handle, TAKE CARE OF INC / DEC -> DONE
-- stack read 16
elsif mem_operI="100" then
mem_address <= std_logic_vector( unsigned(SP(19 downto 0)) + to_unsigned(1, 20) );
mem_operO <= "000";
sendPC_memO <= sendPC_memI;
-- stack read 32
elsif mem_operI="101" then
mem_address <= std_logic_vector( unsigned(SP(19 downto 0)) + to_unsigned(1, 20) );
mem_operO <= "001";
sendPC_memO <= sendPC_memI;
-- stack write 16
elsif mem_operI="110" then
mem_address <= SP(19 downto 0);
mem_operO <= "010";
sendPC_memO <= sendPC_memI;
-- stack write 32
elsif mem_operI="111" then
mem_address <= SP(19 downto 0);
mem_operO <= "011";
sendPC_memO <= sendPC_memI;
end if;
end if;
end if;
end process;
end architecture;