1 |
2 |
hmanske |
------------------------------------------------------------------
|
2 |
4 |
hmanske |
-- PROJECT: HiCoVec (highly configurable vector processor)
|
3 |
2 |
hmanske |
--
|
4 |
|
|
-- ENTITY: vector_alu_32
|
5 |
|
|
--
|
6 |
|
|
-- PURPOSE: 32 bit vector alu
|
7 |
|
|
--
|
8 |
|
|
-- AUTHOR: harald manske, haraldmanske@gmx.de
|
9 |
|
|
--
|
10 |
|
|
-- VERSION: 1.0
|
11 |
|
|
-----------------------------------------------------------------
|
12 |
|
|
library ieee;
|
13 |
|
|
use ieee.std_logic_1164.all;
|
14 |
|
|
use ieee.std_logic_arith.all;
|
15 |
|
|
use ieee.numeric_std.all;
|
16 |
|
|
|
17 |
|
|
use work.cfg.all;
|
18 |
|
|
|
19 |
|
|
entity vector_alu_32 is
|
20 |
|
|
port(
|
21 |
|
|
-- clock
|
22 |
|
|
clk: in std_logic;
|
23 |
|
|
|
24 |
|
|
-- data in
|
25 |
|
|
v_in: in std_logic_vector(31 downto 0);
|
26 |
|
|
w_in: in std_logic_vector(31 downto 0);
|
27 |
|
|
carry_in: in std_logic;
|
28 |
|
|
rshift_in: in std_logic;
|
29 |
|
|
|
30 |
|
|
-- data out
|
31 |
|
|
carry_out: out std_logic;
|
32 |
|
|
valu_out: out std_logic_vector(31 downto 0);
|
33 |
|
|
|
34 |
|
|
-- control signals
|
35 |
|
|
valuop: in std_logic_vector(3 downto 0);
|
36 |
|
|
source_sel: in std_logic_vector(1 downto 0);
|
37 |
|
|
carry_sel: in std_logic_vector(1 downto 0);
|
38 |
|
|
mult_source_sel: in std_logic_vector(1 downto 0); -- *
|
39 |
|
|
mult_dest_sel: in std_logic_vector(1 downto 0); -- *
|
40 |
|
|
reg_input_sel: in std_logic; -- *
|
41 |
|
|
load_lsr: in std_logic;
|
42 |
|
|
load_other: in std_logic
|
43 |
|
|
);
|
44 |
|
|
end;
|
45 |
|
|
|
46 |
|
|
|
47 |
|
|
architecture rtl of vector_alu_32 is
|
48 |
|
|
|
49 |
|
|
signal carry, rshift: std_logic;
|
50 |
|
|
|
51 |
|
|
signal left : unsigned(8 downto 0); -- left operand
|
52 |
|
|
signal right : unsigned(8 downto 0); -- right operand
|
53 |
|
|
signal valu_res: unsigned(8 downto 0); -- result (mult_res8 or valu_res)
|
54 |
|
|
|
55 |
|
|
signal mult_right: unsigned(15 downto 0); -- right multiplication operand
|
56 |
|
|
signal mult_left: unsigned(15 downto 0); -- left multiplication operand
|
57 |
|
|
signal mult_res32: unsigned(31 downto 0); -- multiplication result
|
58 |
|
|
signal mult_res8: unsigned(7 downto 0); -- shift value for result shift register (multiplication)
|
59 |
|
|
|
60 |
|
|
signal output: unsigned(32 downto 0); -- result shift register
|
61 |
|
|
signal input : unsigned (8 downto 0); -- shift value for result shift register (other operations)
|
62 |
|
|
|
63 |
|
|
|
64 |
|
|
begin
|
65 |
|
|
carry <= carry_in when (carry_sel = "00") else
|
66 |
|
|
output(32) when (carry_sel = "01") else
|
67 |
|
|
'0';
|
68 |
|
|
|
69 |
|
|
rshift <= rshift_in when (carry_sel = "00") else
|
70 |
|
|
output(32) when (carry_sel = "01") else
|
71 |
|
|
'0';
|
72 |
|
|
|
73 |
|
|
left <= unsigned('0' & v_in(7 downto 0)) when (source_sel) = "00" else
|
74 |
|
|
unsigned('0' & v_in(15 downto 8)) when (source_sel) = "01" else
|
75 |
|
|
unsigned('0' & v_in(23 downto 16)) when (source_sel) = "10" else
|
76 |
|
|
unsigned('0' & v_in(31 downto 24));
|
77 |
|
|
|
78 |
|
|
right <= unsigned('0' & w_in(7 downto 0)) when (source_sel) = "00" else
|
79 |
|
|
unsigned('0' & w_in(15 downto 8)) when (source_sel) = "01" else
|
80 |
|
|
unsigned('0' & w_in(23 downto 16)) when (source_sel) = "10" else
|
81 |
|
|
unsigned('0' & w_in(31 downto 24));
|
82 |
|
|
|
83 |
|
|
-- execute all other operations
|
84 |
|
|
valu_res <= left + right + carry when (valuop = "0000") else
|
85 |
|
|
left - right - carry when (valuop = "0010") else
|
86 |
|
|
left(7 downto 0) & carry when (valuop = "1100") else
|
87 |
|
|
left(0) & rshift & left(7 downto 1) when (valuop = "1110") else
|
88 |
|
|
unsigned( std_logic_vector(left) and std_logic_vector(right)) when (valuop = "1000") else
|
89 |
|
|
unsigned( std_logic_vector(left) or std_logic_vector(right)) when (valuop = "1001") else
|
90 |
|
|
unsigned( std_logic_vector(left) xor std_logic_vector(right));
|
91 |
|
|
|
92 |
|
|
mult_gen: if use_vector_mult generate
|
93 |
|
|
-- operands for multiplication
|
94 |
|
|
mult_left <= unsigned("00000000" & v_in(7 downto 0)) when mult_source_sel = "00" else
|
95 |
|
|
unsigned("00000000" & v_in(23 downto 16)) when mult_source_sel = "01" else
|
96 |
|
|
unsigned(v_in(15 downto 0));
|
97 |
|
|
|
98 |
|
|
mult_right <= unsigned("00000000" & w_in(7 downto 0)) when mult_source_sel = "00" else
|
99 |
|
|
unsigned("00000000" & w_in(23 downto 16)) when mult_source_sel = "01" else
|
100 |
|
|
unsigned(w_in(15 downto 0));
|
101 |
|
|
|
102 |
|
|
-- execute multiplication
|
103 |
|
|
mult_res32 <= mult_left * mult_right;
|
104 |
|
|
|
105 |
|
|
mult_res8 <= mult_res32(7 downto 0) when mult_dest_sel = "00" else
|
106 |
|
|
mult_res32(15 downto 8) when mult_dest_sel = "01" else
|
107 |
|
|
mult_res32(23 downto 16) when mult_dest_sel = "10" else
|
108 |
|
|
mult_res32(31 downto 24);
|
109 |
|
|
|
110 |
|
|
|
111 |
|
|
end generate;
|
112 |
|
|
|
113 |
|
|
not_mult_gen: if not use_vector_mult generate
|
114 |
|
|
mult_res8 <= "00000000";
|
115 |
|
|
end generate;
|
116 |
|
|
|
117 |
|
|
-- use result from other operation or multiplication?
|
118 |
|
|
input <= valu_res when reg_input_sel = '0' else "0" & mult_res8;
|
119 |
|
|
|
120 |
|
|
-- output register
|
121 |
|
|
process
|
122 |
|
|
begin
|
123 |
|
|
wait until clk ='1' and clk'event;
|
124 |
|
|
if load_other = '1' then
|
125 |
|
|
-- shift from right to left
|
126 |
|
|
output(32 downto 24) <= input(8 downto 0);
|
127 |
|
|
output(23 downto 0) <= output(31 downto 8);
|
128 |
|
|
else
|
129 |
|
|
if load_lsr = '1' then
|
130 |
|
|
-- shift from left to right
|
131 |
|
|
output(7 downto 0) <= input(7 downto 0);
|
132 |
|
|
output(32) <= input(8);
|
133 |
|
|
output(31 downto 8) <= output(23 downto 0);
|
134 |
|
|
else
|
135 |
|
|
output <= output;
|
136 |
|
|
end if;
|
137 |
|
|
end if;
|
138 |
|
|
end process;
|
139 |
|
|
|
140 |
|
|
valu_out <= std_logic_vector(output(31 downto 0));
|
141 |
|
|
carry_out <= output(32);
|
142 |
|
|
|
143 |
|
|
end rtl;
|
144 |
|
|
|
145 |
|
|
|
146 |
|
|
|