-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmath_pipeline.vhd
executable file
·133 lines (116 loc) · 3.36 KB
/
math_pipeline.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
library ieee;
use ieee.numeric_std.all;
use ieee.std_logic_1164.all;
entity math_pipeline is
port(
clk : in std_logic;
en : in std_logic;
op : in std_logic_vector(3 downto 0);
regA : in std_logic_vector(7 downto 0);
regB : in std_logic_vector(7 downto 0);
regC : out std_logic_vector(7 downto 0);
flags : in std_logic_vector(7 downto 0);
writeR: out std_logic;
fetchE: out std_logic;
outFlg: out std_logic_vector(7 downto 0);
flgUpd: out std_logic;
reset : in std_logic
);
end entity math_pipeline;
architecture a_mpline of math_pipeline is
type etat is (Idle, ReadRegs, Exec, WriteReg);
signal currentState : etat := Idle;
signal resultReg : std_logic_vector(17 downto 0);
signal iFlags : std_logic_vector(7 downto 0);
signal iFlags_down : std_logic_vector(7 downto 0);
begin
process
begin
wait until rising_edge(clk);
if en = '1' then
case currentState is
when Idle =>
currentState <= ReadRegs;
when ReadRegs =>
currentState <= Exec;
when Exec =>
currentState <= WriteReg;
when WriteReg =>
currentState <= Idle;
when others =>
currentState <= Idle;
end case;
else
currentState <= Idle;
end if;
if reset = '0' then
currentState <= Idle;
end if;
end process;
process
begin
wait until falling_edge(clk);
case currentState is
when Idle =>
writeR <= '0';
resultReg <= (others => '0');
fetchE <= '0';
flgUpd <= '0';
iFlags <= (others => '0');
when ReadRegs =>
fetchE <= '1';
when Exec =>
if op = "0001" then -- Add
resultReg(8 downto 0) <= std_logic_vector(unsigned('0' & regA) + unsigned('0' & regB));
elsif op = "0010" then -- Mul
resultReg <= std_logic_vector(unsigned('0' & regA) * unsigned('0' & regB));
elsif op = "0011" then -- Sub
resultReg(8 downto 0) <= std_logic_vector(unsigned('0' & regA) - unsigned('0' & regB));
elsif op = "0100" then -- Div
resultReg(8 downto 0) <= std_logic_vector(unsigned('0' & regA) / unsigned('0' & regB));
elsif op = "0101" then -- And
resultReg(8 downto 0) <= std_logic_vector(unsigned('0' & regA) and unsigned('0' & regB));
elsif op = "0110" then -- Or
resultReg(8 downto 0) <= std_logic_vector(unsigned('0' & regA) or unsigned('0' & regB));
elsif op = "0111" then -- Xor
resultReg(8 downto 0) <= std_logic_vector(unsigned('0' & regA) xor unsigned('0' & regB));
elsif op = "1000" then -- Not
resultReg(8 downto 0) <= std_logic_vector(not unsigned('0' & regA));
elsif op = "1001" then -- Cmp
if regA = regB then
iFlags(1) <= '1';
else
iFlags_down(1) <= '1';
if unsigned(regA) > unsigned(regB) then
iFlags(2) <= '1';
iFlags_down(3) <= '1';
else
iFlags_down(2) <= '1';
iFlags(3) <= '1';
end if;
end if;
else
resultReg(8 downto 0) <= (others => '0');
end if;
iFlags(0) <= resultReg(8);
if resultReg(8) = '1' then
iFlags(0) <= '1';
else
iFlags_down(0) <= '1';
end if;
if op = "1001" then
flgUpd <= '1';
writeR <= '0';
else
flgUpd <= '1';
writeR <= '1';
end if;
when WriteReg =>
fetchE <= '0';
flgUpd <= '0';
writeR <= '0';
end case;
end process;
regC <= resultReg(7 downto 0);
outFlg <= (iFlags or ((not iFlags_down) and flags));
end architecture a_mpline;