Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
Marc Solé Bonet
XOHW_GRLIB_AI_extension
Commits
4092f2f4
Commit
4092f2f4
authored
May 22, 2021
by
Marc
Browse files
version 1.2 and 1.2.1
parent
16d5a3b0
Changes
42
Hide whitespace changes
Inline
Side-by-side
grlib/designs/leon3-xilinx/vivado_pid3546.zip
0 → 100644
View file @
4092f2f4
File added
grlib/lib/gaisler/leon3v3/iu3.vhd
View file @
4092f2f4
...
...
@@ -495,13 +495,14 @@ architecture rtl of iu3 is
sa
=>
swizzling_init
,
sb
=>
swizzling_init
,
ol
=>
(
others
=>
'0'
),
od => (others => '0')
od
=>
(
others
=>
'0'
),
hp
=>
'0'
--ac => vector_reg_res
);
function
to_word
(
reg
:
simd_ctrl_reg_type
)
return
word
is
begin
return "0000
0
" & reg.od & reg.ol & swizzling_get(reg.sa) & swizzling_get(reg.sb) & reg.ms & reg.mk;
return
"0000"
&
reg
.
hp
&
reg
.
od
&
reg
.
ol
&
swizzling_get
(
reg
.
sa
)
&
swizzling_get
(
reg
.
sb
)
&
reg
.
ms
&
reg
.
mk
;
end
to_word
;
function
to_scr
(
data
:
word
)
return
simd_ctrl_reg_type
is
...
...
@@ -513,6 +514,7 @@ architecture rtl of iu3 is
reg
.
sb
:
=
swizzling_set
(
data
(
20
downto
13
));
reg
.
ol
:
=
data
(
22
downto
21
);
reg
.
od
:
=
data
(
26
downto
23
);
reg
.
hp
:
=
data
(
27
);
return
reg
;
end
to_scr
;
...
...
grlib/lib/gaisler/leon3v3/leon3x.vhd
View file @
4092f2f4
...
...
@@ -149,6 +149,8 @@ constant dummy_ft_consistency_check:
signal
holdn
:
std_logic
;
signal
rfi
:
iregfile_in_type
;
signal
rfo
:
iregfile_out_type
;
--signal rfo1 : iregfile_out_type;
--signal rfo2 : iregfile_out_type;
signal
crami
:
cram_in_type
;
signal
cramo
:
cram_out_type
;
signal
tbi
:
tracebuf_in_type
;
...
...
@@ -197,6 +199,11 @@ begin
tbi
,
tbo
,
tbi_2p
,
tbo_2p
,
fpi
,
fpo
,
cpi
,
cpo
,
irqi
,
irqo
,
dbgi
,
dbgo
,
clk
,
clk2
,
clken
);
-- rfo.data1 <= rfo1.data1 when rfo1.data1 = rfo2.data1 else
-- rfo2.data1;
-- rfo.data2 <= rfo1.data2 when rfo1.data2 = rfo2.data2 else
-- rfo2.data2;
-- IU register file
rf0
:
regfile_3p_l3
generic
map
(
MEMTECH_MOD
*
(
1
-
IURF_INFER
),
IRFBITS
,
32
,
IRFWT
,
IREGNUM
,
scantest
,
RFREADHOLD
)
...
...
@@ -206,6 +213,14 @@ begin
ahbi
.
testin
);
-- rf1 : regfile_3p_l3 generic map (MEMTECH_MOD*(1-IURF_INFER), IRFBITS, 32, IRFWT, IREGNUM,
-- scantest, RFREADHOLD)
-- port map (gclk2, rfi.waddr(IRFBITS-1 downto 0), rfi.wdata, rfi.wren,
-- gclk2, rfi.raddr1(IRFBITS-1 downto 0), rfi.ren1, rfo2.data1,
-- rfi.raddr2(IRFBITS-1 downto 0), rfi.ren2, rfo2.data2,
-- ahbi.testin
-- );
-- cache memory
cmem0
:
cachemem
generic
map
(
MEMTECH_MOD
,
icen
,
irepl
,
isets
,
ilinesize
,
isetsize
,
isetlock
,
dcen
,
...
...
grlib/lib/marcmod/simd/lpmul.vhd
View file @
4092f2f4
...
...
@@ -16,9 +16,9 @@ entity lpmul is
end
;
architecture
rtl
of
lpmul
is
constant
SMAX
:
std_logic_vector
(
VLEN
-1
downto
0
)
:
=
"0"
&
(
VLEN
-2
downto
0
=>
'1'
);
constant
SMIN
:
std_logic_vector
(
VLEN
-1
downto
0
)
:
=
"1"
&
(
VLEN
-2
downto
0
=>
'0'
);
constant
UMAX
:
std_logic_vector
(
VLEN
-1
downto
0
)
:
=
(
others
=>
'1'
);
constant
SMAX
:
vector_component
:
=
"0"
&
(
VLEN
-2
downto
0
=>
'1'
);
constant
SMIN
:
vector_component
:
=
"1"
&
(
VLEN
-2
downto
0
=>
'0'
);
constant
UMAX
:
vector_component
:
=
(
others
=>
'1'
);
function
sign_invert
(
a
:
std_logic_vector
)
return
std_logic_vector
is
begin
...
...
@@ -61,20 +61,25 @@ architecture rtl of lpmul is
sel
:
=
"111"
;
-- result is ff unsigned max
end
if
;
end
if
;
elsif
sign
=
'1'
then
-- if no saturation but signed
if
asign
/=
bsign
then
-- and result should be negative
sel
:
=
"001"
;
-- result is ca2 negative
end
if
;
end
if
;
return
sel
;
end
sat_mux
;
procedure
sat_sel
(
sel
:
in
std_logic_vector
(
2
downto
0
);
r
,
nr
:
in
std_logic_vector
(
VLEN
-1
downto
0
)
;
mulres
:
out
std_logic_vector
(
VLEN
-1
downto
0
)
)
is
r
,
nr
:
in
high_prec_component
;
mulres
:
out
high_prec_component
)
is
begin
case
sel
is
when
"000"
=>
mulres
:
=
r
;
when
"001"
=>
mulres
:
=
nr
;
when
"011"
=>
mulres
:
=
SMAX
;
when
"100"
=>
mulres
:
=
SMIN
;
when
"111"
=>
mulres
:
=
UMAX
;
when
"011"
=>
mulres
:
=
(
vector_component
'range
=>
'0'
)
&
SMAX
;
when
"100"
=>
mulres
:
=
(
vector_component
'range
=>
'1'
)
&
SMIN
;
when
"111"
=>
mulres
:
=
(
vector_component
'range
=>
'0'
)
&
UMAX
;
when
others
=>
mulres
:
=
(
others
=>
'0'
);
end
case
;
end
sat_sel
;
...
...
@@ -82,9 +87,9 @@ architecture rtl of lpmul is
begin
comb
:
process
(
muli
)
variable
z
:
std_logic_vector
(
VLEN
*
2-1
downto
0
)
;
variable
r
:
std_logic_vector
(
VLEN
-1
downto
0
)
;
variable
a
,
b
:
std_logic_vector
(
VLEN
-1
downto
0
)
;
variable
z
:
high_prec_component
;
variable
r
:
high_prec_component
;
variable
a
,
b
:
vector_component
;
variable
signA
,
signB
:
std_logic
;
variable
mux
:
std_logic_vector
(
2
downto
0
);
begin
...
...
@@ -93,17 +98,19 @@ begin
signB
:
=
muli
.
opB
(
muli
.
opB
'left
);
-- have both operands as positive if signed and saturation
if
(
muli
.
sign
and
signA
and
muli
.
sat
)
=
'1'
then
--if (muli.sign and signA and muli.sat) = '1' then
if
(
muli
.
sign
and
signA
)
=
'1'
then
a
:
=
sign_invert
(
muli
.
opA
);
end
if
;
if
(
muli
.
sign
and
signB
and
muli
.
sat
)
=
'1'
then
--if (muli.sign and signB and muli.sat) = '1' then
if
(
muli
.
sign
and
signB
)
=
'1'
then
b
:
=
sign_invert
(
muli
.
opB
);
end
if
;
-- low precision product
z
:
=
product
(
a
,
b
);
-- select result with sign and saturation
mux
:
=
sat_mux
(
signA
,
signB
,
z
(
r
'left
),
muli
.
sign
,
muli
.
sat
,
z
(
z
'left
downto
r
'length
));
sat_sel
(
mux
,
z
(
r
'range
)
,
sign_invert
(
z
(
r
'range
)
),
r
);
mux
:
=
sat_mux
(
signA
,
signB
,
z
(
vector_component
'left
),
muli
.
sign
,
muli
.
sat
,
z
(
z
'left
downto
vector_component
'length
));
sat_sel
(
mux
,
z
,
sign_invert
(
z
),
r
);
mulo
.
mul_res
<=
r
;
end
process
;
end
;
grlib/lib/marcmod/simd/simd.v1.1.vhd
0 → 100644
View file @
4092f2f4
library
ieee
;
use
ieee
.
std_logic_1164
.
all
;
use
ieee
.
numeric_std
.
all
;
library
grlib
;
use
grlib
.
stdlib
.
all
;
library
marcmod
;
use
marcmod
.
simdmod
.
all
;
entity
simd_module
is
port
(
clk
:
in
std_ulogic
;
rstn
:
in
std_ulogic
;
holdn
:
in
std_ulogic
;
sdi
:
in
simd_in_type
;
sdo
:
out
simd_out_type
);
end
;
architecture
rtl
of
simd_module
is
---------------------------------------------------------------
-- REGISTER TYPES DEFINITION --
--------------------------------------------------------------
type
lpmul_in_array
is
array
(
0
to
VSIZE
-1
)
of
lpmul_in_type
;
type
lpmul_out_array
is
array
(
0
to
VSIZE
-1
)
of
lpmul_out_type
;
type
l1_sum_array
is
array
(
0
to
VSIZE
/
2
)
of
std_logic_vector
(
VLEN
downto
0
);
type
l2_sum_array
is
array
(
0
to
VSIZE
/
4
)
of
std_logic_vector
(
VLEN
+
1
downto
0
);
-- Stage1 entry register
type
s1_reg_type
is
record
ra
:
vector_reg_type
;
rb
:
vector_reg_type
;
op1
:
std_logic_vector
(
4
downto
0
);
op2
:
std_logic_vector
(
2
downto
0
);
en
:
std_logic
;
end
record
;
-- Stage2 entry register
type
s2_reg_type
is
record
ra
:
inter_reg_type
;
op2
:
std_logic_vector
(
2
downto
0
);
sat
:
std_logic
;
en
:
std_logic
;
end
record
;
-- Stage3 entry register
type
s3_reg_type
is
record
rc
:
word
;
end
record
;
-- Group of pipeline registers
type
registers
is
record
s1
:
s1_reg_type
;
s2
:
s2_reg_type
;
s3
:
s3_reg_type
;
end
record
;
---------------------------------------------------------------
-- CONSTANTS FOR PIPELINE REGISTERS RESET --
--------------------------------------------------------------
constant
vector_reg_res
:
vector_reg_type
:
=
(
others
=>
(
others
=>
'0'
));
constant
inter_reg_res
:
inter_reg_type
:
=
(
others
=>
(
others
=>
'0'
));
-- set the 1st stage registers reset
constant
s1_reg_res
:
s1_reg_type
:
=
(
ra
=>
vector_reg_res
,
rb
=>
vector_reg_res
,
op1
=>
(
others
=>
'0'
),
op2
=>
(
others
=>
'0'
),
en
=>
'0'
);
-- set the 2nd stage registers reset
constant
s2_reg_res
:
s2_reg_type
:
=
(
ra
=>
inter_reg_res
,
op2
=>
(
others
=>
'0'
),
sat
=>
'0'
,
en
=>
'0'
);
-- set the 3rd stage registers reset
constant
s3_reg_res
:
s3_reg_type
:
=
(
rc
=>
(
others
=>
'0'
)
);
-- reset all registers
constant
RRES
:
registers
:
=
(
s1
=>
s1_reg_res
,
s2
=>
s2_reg_res
,
s3
=>
s3_reg_res
);
---------------------------------------------------------------
-- FUNCTIONS
--------------------------------------------------------------
function
to_vector
(
data
:
word
)
return
vector_reg_type
is
variable
vec
:
vector_reg_type
;
begin
for
i
in
vec
'range
loop
vec
(
i
)
:
=
data
(
VLEN
*
i
+
VLEN
-1
downto
VLEN
*
i
);
end
loop
;
return
vec
;
end
;
function
to_word
(
vec
:
vector_reg_type
)
return
word
is
variable
data
:
word
;
begin
for
i
in
vec
'range
loop
data
(
VLEN
*
i
+
VLEN
-1
downto
VLEN
*
i
)
:
=
vec
(
i
);
end
loop
;
return
data
;
end
;
function
to_word
(
vec
:
inter_reg_type
)
return
word
is
variable
data
:
word
;
begin
for
i
in
vec
'range
loop
data
(
VLEN
*
i
+
VLEN
-1
downto
VLEN
*
i
)
:
=
vec
(
i
)(
vector_component
'range
);
end
loop
;
return
data
;
end
;
function
swizzling
(
data
:
vector_reg_type
;
sz
:
swizzling_reg_type
)
return
vector_reg_type
is
variable
result
:
vector_reg_type
;
begin
for
i
in
result
'range
loop
result
(
i
)
:
=
data
(
sz
(
i
));
end
loop
;
return
result
;
end
function
swizzling
;
---------------------------------------------------------------
-- SATURATION FUNCTIONS
--------------------------------------------------------------
function
clipping
(
value
,
max_val
,
min_val
:
integer
)
return
integer
is
begin
if
value
>
max_val
then
return
max_val
;
elsif
value
<
min_val
then
return
min_val
;
else
return
value
;
end
if
;
end
clipping
;
function
extend
(
value
:
std_logic_vector
;
sign
:
std_logic
;
size
:
integer
)
return
std_logic_vector
is
begin
if
sign
=
'1'
then
return
std_logic_vector
(
resize
(
signed
(
value
),
size
));
else
return
std_logic_vector
(
resize
(
unsigned
(
value
),
size
));
end
if
;
end
extend
;
function
signed_sat
(
a
,
leng
:
integer
;
sat
:
std_logic
)
return
std_logic_vector
is
begin
if
sat
=
'1'
then
return
std_logic_vector
(
to_signed
(
clipping
(
a
,
127
,
-128
),
leng
));
else
return
std_logic_vector
(
to_signed
(
a
,
leng
));
end
if
;
end
signed_sat
;
function
unsigned_sat
(
a
,
leng
:
integer
;
sat
:
std_logic
)
return
std_logic_vector
is
begin
if
sat
=
'1'
then
return
std_logic_vector
(
to_unsigned
(
clipping
(
a
,
255
,
0
),
leng
));
else
return
std_logic_vector
(
to_signed
(
a
,
leng
));
end
if
;
end
unsigned_sat
;
---------------------------------------------------------------
-- SIGNALS DEFINITIONS
--------------------------------------------------------------
--signals for the registers r -> current, rin -> next
signal
r
,
rin
:
registers
;
signal
lpmuli
:
lpmul_in_array
;
signal
lpmulo
:
lpmul_out_array
;
---------------------------------------------------------------
-- TWO OPERANDS OPERATIONS (S1) --
--------------------------------------------------------------
-- s1 result multiplexor
procedure
s1_mux
(
op
:
in
std_logic_vector
(
4
downto
0
);
sel
:
out
std_logic_vector
(
3
downto
0
))
is
begin
sel
:
=
'0'
&
op
(
2
downto
0
);
case
op
is
when
S1_SADD
|
S1_USADD
=>
sel
:
=
"0001"
;
when
S1_SSUB
|
S1_USSUB
=>
sel
:
=
"0010"
;
when
S1_SMUL
|
S1_USMUL
=>
sel
:
=
"0011"
;
when
S1_AND
|
S1_OR
|
S1_XOR
|
S1_NAND
|
S1_NOR
|
S1_XNOR
=>
sel
:
=
"0111"
;
when
S1_MOVB
=>
sel
:
=
"0100"
;
when
S1_SHFT
|
S1_SSHFT
=>
sel
:
=
"1000"
;
when
others
=>
end
case
;
end
s1_mux
;
procedure
s1_select
(
sel
:
in
std_logic_vector
(
3
downto
0
);
ra
,
rs2
,
add_res
,
sub_res
,
max_res
,
min_res
,
logic_res
,
shift_res
,
mul_res
:
in
inter_reg_type
;
s1_res
:
out
inter_reg_type
)
is
begin
case
sel
is
when
"0000"
=>
s1_res
:
=
ra
;
when
"0001"
=>
s1_res
:
=
add_res
;
when
"0010"
=>
s1_res
:
=
sub_res
;
when
"0011"
=>
s1_res
:
=
mul_res
;
when
"0100"
=>
s1_res
:
=
rs2
;
when
"0101"
=>
s1_res
:
=
max_res
;
when
"0110"
=>
s1_res
:
=
min_res
;
when
"0111"
=>
s1_res
:
=
logic_res
;
when
"1000"
=>
s1_res
:
=
shift_res
;
when
others
=>
s1_res
:
=
(
others
=>
(
others
=>
'0'
));
end
case
;
end
s1_select
;
function
add
(
a
,
b
:
vector_component
;
sign
,
sat
:
std_logic
)
return
std_logic_vector
is
variable
z
:
integer
;
begin
if
sign
=
'1'
then
z
:
=
to_integer
(
signed
(
a
))
+
to_integer
(
signed
(
b
));
return
signed_sat
(
z
,
high_prec_component
'length
,
sat
);
else
z
:
=
to_integer
(
unsigned
(
a
))
+
to_integer
(
unsigned
(
b
));
return
unsigned_sat
(
z
,
high_prec_component
'length
,
sat
);
end
if
;
end
add
;
function
sub
(
a
,
b
:
vector_component
;
sign
,
sat
:
std_logic
)
return
std_logic_vector
is
variable
z
:
integer
range
-512
to
512
;
begin
if
sign
=
'1'
then
z
:
=
to_integer
(
signed
(
a
))
-
to_integer
(
signed
(
b
));
return
signed_sat
(
z
,
high_prec_component
'length
,
sat
);
else
z
:
=
to_integer
(
signed
(
a
))
-
to_integer
(
signed
(
b
));
return
unsigned_sat
(
z
,
high_prec_component
'length
,
sat
);
end
if
;
end
sub
;
-- max function
function
max
(
a
,
b
:
vector_component
;
sign
:
std_logic
)
return
high_prec_component
is
variable
z
:
vector_component
;
begin
if
sign
=
'1'
then
if
signed
(
a
)
>
signed
(
b
)
then
z
:
=
a
;
else
z
:
=
b
;
end
if
;
else
if
a
>
b
then
z
:
=
a
;
else
z
:
=
b
;
end
if
;
end
if
;
return
(
z
(
z
'left
)
and
sign
)
&
z
;
end
max
;
-- min function
function
min
(
a
,
b
:
vector_component
;
sign
:
std_logic
)
return
high_prec_component
is
variable
z
:
vector_component
;
begin
if
sign
=
'1'
then
if
signed
(
a
)
>
signed
(
b
)
then
z
:
=
b
;
else
z
:
=
a
;
end
if
;
else
if
a
>
b
then
z
:
=
b
;
else
z
:
=
a
;
end
if
;
end
if
;
return
(
z
(
z
'left
)
and
sign
)
&
z
;
end
min
;
--logic operations
function
logic_op
(
a
,
b
:
vector_component
;
op
:
std_logic_vector
(
2
downto
0
))
return
vector_component
is
variable
z
:
vector_component
;
begin
case
op
is
when
"111"
=>
z
:
=
a
and
b
;
when
"000"
=>
z
:
=
a
or
b
;
when
"001"
=>
z
:
=
a
xor
b
;
when
"010"
=>
z
:
=
a
nand
b
;
when
"011"
=>
z
:
=
a
nor
b
;
when
"100"
=>
z
:
=
a
xnor
b
;
when
others
=>
z
:
=
(
others
=>
'0'
);
end
case
;
return
z
;
end
logic_op
;
function
shift
(
a
,
b
:
vector_component
;
sat
:
std_logic
)
return
high_prec_component
is
variable
z
:
high_prec_component
;
variable
i
:
integer
;
begin
i
:
=
to_integer
(
signed
(
b
(
b
'left
downto
1
)));
if
b
(
b
'left
)
=
'1'
then
-- shift right
if
b
(
0
)
=
'1'
then
-- arithmetic
z
:
=
std_logic_vector
(
shift_right
(
signed
(
a
(
a
'left
)
&
a
),
-
i
));
else
z
:
=
std_logic_vector
(
shift_right
(
unsigned
(
'0'
&
a
),
-
i
));
end
if
;
else
z
:
=
std_logic_vector
(
shift_left
(
unsigned
(
'0'
&
a
),
i
));
end
if
;
return
z
;
end
shift
;
--apply mask to vector
procedure
mask
(
vector
,
original
:
in
inter_reg_type
;
msk
:
in
std_logic_vector
(
VSIZE
-1
downto
0
);
msk_res
:
out
inter_reg_type
)
is
begin
msk_res
:
=
original
;
for
i
in
msk
'range
loop
if
msk
(
i
)
=
'1'
then
msk_res
(
i
)
:
=
vector
(
i
);
end
if
;
end
loop
;
end
mask
;
--apply shift and accumulate
--procedure shift_and_acc(be : in s2byteen_reg_type;
-- acc : in vector_reg_type;
-- data: in vector_reg_type;
-- res : out vector_reg_type;
-- nxt_be : out s2byteen_reg_type) is
-- variable new_acc : vector_reg_type;
--begin
-- new_acc := acc;
-- for i in be'range loop
-- if be(i) = '1' then
-- new_acc(i) := data(0);
-- end if;
-- end loop;
-- res := new_acc; nxt_be := be(be'left-1 downto 0) & '0';
--end shift_and_acc;
---------------------------------------------------------------
-- REDUCTION OPERATIONS (S2) --
--------------------------------------------------------------
procedure
s2_select
(
sel
:
in
std_logic_vector
(
2
downto
0
);
ra
,
sum_res
,
max_res
,
min_res
,
xor_res
:
in
word
;
rc
:
out
word
)
is
begin
case
sel
is
when
"000"
=>
rc
:
=
ra
;
when
"001"
|
"101"
=>
rc
:
=
sum_res
;
when
"010"
|
"110"
=>
rc
:
=
max_res
;
when
"011"
|
"111"
=>
rc
:
=
min_res
;
when
"100"
=>
rc
:
=
xor_res
;
when
others
=>
rc
:
=
ra
;
end
case
;
end
s2_select
;
function
sum
(
a
:
inter_reg_type
;
sign
,
sat
:
std_logic
)
return
word
is
variable
acc
:
integer
:
=
0
;
begin
if
sign
=
'1'
then
for
i
in
0
to
VSIZE
-1
loop
acc
:
=
acc
+
to_integer
(
signed
(
a
(
i
)));
end
loop
;
return
signed_sat
(
acc
,
word
'length
,
sat
);
else
for
i
in
0
to
VSIZE
-1
loop
acc
:
=
acc
+
to_integer
(
unsigned
(
a
(
i
)));
end
loop
;
return
unsigned_sat
(
acc
,
word
'length
,
sat
);
end
if
;
end
sum
;
--max recursive function
function
max_red
(
a
:
inter_reg_type
;
sign
:
std_logic
)
return
word
is
variable
acc
:
integer
;
begin
if
sign
=
'1'
then
acc
:
=
to_integer
(
signed
(
a
(
0
)));
for
i
in
1
to
VSIZE
-1
loop
if
to_integer
(
signed
(
a
(
i
)))
>
acc
then
acc
:
=
to_integer
(
signed
(
a
(
i
)));
end
if
;
end
loop
;
else
acc
:
=
to_integer
(
unsigned
(
a
(
0
)));
for
i
in
1
to
VSIZE
-1
loop
if
to_integer
(
unsigned
(
a
(
i
)))
>
acc
then
acc
:
=
to_integer
(
unsigned
(
a
(
i
)));
end
if
;
end
loop
;
end
if
;
return
unsigned_sat
(
acc
,
word
'length
,
'0'
);
end
max_red
;
--min recursive function
function
min_red
(
a
:
inter_reg_type
;
sign
:
std_logic
)
return
word
is
variable
acc
:
integer
;
begin
if
sign
=
'1'
then
acc
:
=
to_integer
(
signed
(
a
(
0
)));
for
i
in
1
to
VSIZE
-1
loop
if
to_integer
(
signed
(
a
(
i
)))
<
acc
then
acc
:
=
to_integer
(
signed
(
a
(
i
)));
end
if
;
end
loop
;
else
acc
:
=
to_integer
(
unsigned
(
a
(
0
)));
for
i
in
1
to
VSIZE
-1
loop
if
to_integer
(
unsigned
(
a
(
i
)))
<
acc
then
acc
:
=
to_integer
(
unsigned
(
a
(
i
)));
end
if
;
end
loop
;
end
if
;
return
unsigned_sat
(
acc
,
word
'length
,
'0'
);
end
min_red
;
function
xor_red
(
a
:
inter_reg_type
)
return
word
is
variable
acc
:
vector_component
;
begin
acc
:
=
a
(
0
)(
vector_component
'range
);
for
i
in
1
to
VSIZE
-1
loop
acc
:
=
a
(
i
)(
vector_component
'range
)
xor
acc
;
end
loop
;
return
std_logic_vector
(
resize
(
unsigned
(
acc
),
word
'length
));
end
xor_red
;
begin
---------------------------------------------------------------
-- MAIN BODY --
--------------------------------------------------------------
genmul
:
for
i
in
0
to
XLEN
/
VLEN
-1
generate
mul
:
lpmul
port
map
(
lpmuli
(
i
),
lpmulo
(
i
));
end
generate
genmul
;