Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
P
Platform-independent core collection
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
18
Issues
18
List
Board
Labels
Milestones
Merge Requests
6
Merge Requests
6
Wiki
Wiki
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Projects
Platform-independent core collection
Commits
f1dad2ef
Commit
f1dad2ef
authored
Feb 25, 2022
by
Tomasz Wlostowski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dsp: added generic pipelined FIR filter core
parent
141e6c2c
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
215 additions
and
14 deletions
+215
-14
Manifest.py
modules/dsp/Manifest.py
+16
-14
gc_dsp_pkg.vhd
modules/dsp/gc_dsp_pkg.vhd
+12
-0
gc_pipelined_fir_filter.vhd
modules/dsp/gc_pipelined_fir_filter.vhd
+187
-0
No files found.
modules/dsp/Manifest.py
View file @
f1dad2ef
files
=
[
"cordic_init.vhd"
,
"cordic_modulo_360.vhd"
,
"cordic_xy_logic_hd.vhd"
,
"cordic_xy_logic_nhd.vhd"
,
"cordic_xy_logic_nmhd.vhd"
,
"gc_averager_decimator.vhd"
,
"gc_cordic_pkg.vhd"
,
"gc_cordic.vhd"
,
#"gc_frequency_detector.vhd",
"gc_iq_amplitude_limiter.vhd"
,
"gc_iq_demodulator.vhd"
,
"gc_iq_modulator.vhd"
,
"gc_iq_rotate.vhd"
,
"gc_pi_regulator.vhd"
,
"gc_rate_limiter.vhd"
];
"cordic_modulo_360.vhd"
,
"cordic_xy_logic_hd.vhd"
,
"cordic_xy_logic_nhd.vhd"
,
"cordic_xy_logic_nmhd.vhd"
,
"gc_pipelined_fir_filter.vhd"
,
"gc_averager_decimator.vhd"
,
"gc_cordic_pkg.vhd"
,
"gc_cordic.vhd"
,
"gc_dsp_pkg.vhd"
,
#"gc_frequency_detector.vhd",
"gc_iq_amplitude_limiter.vhd"
,
"gc_iq_demodulator.vhd"
,
"gc_iq_modulator.vhd"
,
"gc_iq_rotate.vhd"
,
"gc_pi_regulator.vhd"
,
"gc_rate_limiter.vhd"
];
modules/dsp/gc_dsp_pkg.vhd
0 → 100644
View file @
f1dad2ef
library
ieee
;
use
ieee
.
std_logic_1164
.
All
;
use
ieee
.
numeric_std
.
All
;
package
gc_dsp_pkg
is
constant
c_MAX_COEF_BITS
:
integer
:
=
32
;
constant
c_FIR_MAX_COEFS
:
integer
:
=
128
;
type
t_FIR_COEF_ARRAY
is
array
(
c_FIR_MAX_COEFS
-1
downto
0
)
of
signed
(
c_MAX_COEF_BITS
-1
downto
0
);
end
package
;
modules/dsp/gc_pipelined_fir_filter.vhd
0 → 100644
View file @
f1dad2ef
--------------------------------------------------------------------------------
-- CERN BE-CO-HT
-- General Cores Library
-- https://www.ohwr.org/projects/general-cores
--------------------------------------------------------------------------------
--
-- unit name: gc_pipelined_fir_filter
--
-- author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
--
-- description: Fully pipelined FIR filter (transposed) structure. Infers
-- FPGA multiplier/MAC blocks. Programmable coefficients. Supports
-- symmetric impulse response optimization.
--
--------------------------------------------------------------------------------
-- Copyright CERN 2020
--------------------------------------------------------------------------------
-- Copyright and related rights are licensed under the Solderpad Hardware
-- License, Version 2.0 (the "License"); you may not use this file except
-- in compliance with the License. You may obtain a copy of the License at
-- http://solderpad.org/licenses/SHL-2.0.
-- Unless required by applicable law or agreed to in writing, software,
-- hardware and materials distributed under this License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
-- or implied. See the License for the specific language governing permissions
-- and limitations under the License.
--------------------------------------------------------------------------------
library
ieee
;
use
ieee
.
std_logic_1164
.
all
;
use
ieee
.
numeric_std
.
all
;
use
work
.
gencores_pkg
.
all
;
use
work
.
genram_pkg
.
all
;
use
work
.
gc_dsp_pkg
.
all
;
entity
gc_pipelined_fir_filter
is
generic
(
-- number of coefficient bits
g_COEF_BITS
:
integer
:
=
16
;
-- number of data bits
g_DATA_BITS
:
integer
:
=
16
;
-- number of output bits
g_OUTPUT_BITS
:
integer
:
=
16
;
-- MAC post-sum shift
g_OUTPUT_SHIFT
:
integer
:
=
16
;
-- when true, takes the 1st half of the coefficients and assumes
-- the other half is symmetric to it. Saves 50% of multiplier resources.
g_SYMMETRIC
:
boolean
:
=
false
;
-- Order of the filter
g_ORDER
:
integer
);
port
(
clk_i
:
in
std_logic
;
rst_i
:
in
std_logic
;
coefs_i
:
in
t_FIR_COEF_ARRAY
;
d_i
:
in
std_logic_vector
(
g_DATA_BITS
-1
downto
0
);
d_valid_i
:
in
std_logic
;
d_o
:
out
std_logic_vector
(
g_OUTPUT_BITS
-1
downto
0
);
d_valid_o
:
out
std_logic
);
end
gc_pipelined_fir_filter
;
architecture
rtl
of
gc_pipelined_fir_filter
is
constant
c_ACC_BITS
:
integer
:
=
g_DATA_BITS
+
g_COEF_BITS
+
f_log2_size
(
g_ORDER
)
+
1
;
type
t_postmul_array
is
array
(
g_ORDER
-1
downto
0
)
of
signed
(
g_DATA_BITS
+
g_COEF_BITS
downto
0
);
function
f_eval_num_taps
(
ncoefs
:
integer
;
is_symmetric
:
boolean
)
return
integer
is
begin
if
is_symmetric
then
if
ncoefs
mod
2
=
0
then
return
ncoefs
/
2
;
else
return
ncoefs
/
2
+
1
;
end
if
;
else
return
ncoefs
;
end
if
;
end
f_eval_num_taps
;
impure
function
f_convert_coef
(
n
:
integer
)
return
signed
is
begin
return
coefs_i
(
n
)(
g_COEF_BITS
-1
downto
0
);
end
f_convert_coef
;
constant
c_NUM_TAPS
:
integer
:
=
f_eval_num_taps
(
g_ORDER
,
g_SYMMETRIC
);
type
t_chainsum_array
is
array
(
g_ORDER
-1
downto
0
)
of
signed
(
c_ACC_BITS
-1
downto
0
);
signal
d_reg
:
signed
(
g_DATA_BITS
downto
0
);
signal
premul_valid
:
std_logic
;
signal
postmul
:
t_postmul_array
;
signal
postmul_valid
:
std_logic
;
signal
acc_out_rounded
:
signed
(
g_OUTPUT_BITS
downto
0
);
signal
acc_out_valid
:
std_logic
;
signal
chain_sum
:
t_chainsum_array
;
signal
chain_sum_valid
:
std_logic_vector
(
g_ORDER
-1
downto
0
);
begin
p_multipliers
:
process
(
clk_i
)
begin
if
rising_edge
(
clk_i
)
then
d_reg
<=
resize
(
signed
(
d_i
),
g_DATA_BITS
+
1
);
premul_valid
<=
d_valid_i
;
postmul_valid
<=
premul_valid
;
for
i
in
0
to
c_NUM_TAPS
-1
loop
postmul
(
i
)
<=
d_reg
*
f_convert_coef
(
i
);
end
loop
;
end
if
;
end
process
;
p_sum_pipe
:
process
(
clk_i
)
begin
if
rising_edge
(
clk_i
)
then
chain_sum_valid
<=
chain_sum_valid
(
g_ORDER
-2
downto
0
)
&
postmul_valid
;
chain_sum
(
0
)
<=
resize
(
postmul
(
0
),
c_ACC_BITS
);
if
not
g_SYMMETRIC
then
for
i
in
1
to
g_ORDER
-1
loop
chain_sum
(
i
)
<=
chain_sum
(
i
-1
)
+
postmul
(
i
);
end
loop
;
else
if
g_ORDER
mod
2
=
0
then
for
i
in
1
to
c_NUM_TAPS
-1
loop
chain_sum
(
i
)
<=
chain_sum
(
i
-1
)
+
postmul
(
i
);
end
loop
;
for
i
in
0
to
c_NUM_TAPS
-1
loop
chain_sum
(
i
+
c_NUM_TAPS
)
<=
chain_sum
(
i
+
c_NUM_TAPS
-
1
)
+
postmul
(
c_NUM_TAPS
-
1
-
i
);
end
loop
;
else
for
i
in
1
to
c_NUM_TAPS
-1
loop
chain_sum
(
i
)
<=
chain_sum
(
i
-1
)
+
postmul
(
i
);
end
loop
;
for
i
in
1
to
c_NUM_TAPS
-1
loop
chain_sum
(
i
+
c_NUM_TAPS
-
1
)
<=
chain_sum
(
i
+
c_NUM_TAPS
-
2
)
+
postmul
(
c_NUM_TAPS
-
1
-
i
);
end
loop
;
end
if
;
end
if
;
end
if
;
end
process
;
p_round_output
:
process
(
clk_i
)
begin
if
rising_edge
(
clk_i
)
then
if
d_valid_i
=
'1'
then
if
chain_sum
(
g_ORDER
-1
)(
g_OUTPUT_SHIFT
-1
)
=
'1'
then
acc_out_rounded
<=
chain_sum
(
g_ORDER
-1
)(
g_OUTPUT_BITS
+
g_OUTPUT_SHIFT
-
1
downto
g_OUTPUT_SHIFT
-1
)
+
1
;
else
acc_out_rounded
<=
chain_sum
(
g_ORDER
-1
)(
g_OUTPUT_BITS
+
g_OUTPUT_SHIFT
-
1
downto
g_OUTPUT_SHIFT
-1
);
end
if
;
acc_out_valid
<=
chain_sum_valid
(
g_ORDER
-1
);
else
acc_out_valid
<=
'0'
;
end
if
;
end
if
;
end
process
;
d_o
<=
std_logic_vector
(
acc_out_rounded
(
g_OUTPUT_BITS
downto
1
));
d_valid_o
<=
acc_out_valid
;
end
rtl
;
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment