1 |
2 |
zguig52 |
-------------------------------
|
2 |
|
|
---- Project: EurySPACE CCSDS RX/TX with wishbone interface
|
3 |
|
|
---- Design Name: ccsds_rxtx_srrc
|
4 |
|
|
---- Version: 1.0.0
|
5 |
|
|
---- Description:
|
6 |
|
|
---- Squared Raised Root Cosine FIR filter (pipelined systolic symetric architecture)
|
7 |
|
|
---- Input: 1 clk / sam_val_i <= '1' / sam_i <= "SAMPLESDATATOBEFILTERED"
|
8 |
|
|
---- Timing requirements: 1 clock cycle for valid output sample / delay = (6*CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO+1) / impulse response time = (6*CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO*2+1)
|
9 |
|
|
---- Output: sam_val_o <= "1" / sam_o <= "FILTEREDSAMPLES"
|
10 |
|
|
---- Ressources requirements: pipelined samples registers + fir coefficients registers + input adders registers + output adders registers + multipliers registers = ((FilterCoefficientsNumber - 1) * 2 + 1) * QuantizationDepth + FilterCoefficientsNumber * QuantizationDepth + FilterCoefficientsNumber * (QuantizationDepth + 1) + (2 * FilterCoefficientsNumber) * (QuantizationDepth * 2 + 1) registers
|
11 |
|
|
-------------------------------
|
12 |
|
|
---- Author(s):
|
13 |
|
|
---- Guillaume REMBERT
|
14 |
|
|
-------------------------------
|
15 |
|
|
---- Licence:
|
16 |
|
|
---- MIT
|
17 |
|
|
-------------------------------
|
18 |
|
|
---- Changes list:
|
19 |
|
|
---- 2016/11/06: initial release
|
20 |
|
|
-------------------------------
|
21 |
|
|
-- Filter impulse response - SRRC(t):
|
22 |
|
|
-- t = 0 => SRRC(0) = (1-B + 4*B/PI)
|
23 |
|
|
-- t = +/-Ts/(4*B) => SRRC(+/-Ts/(4*B)) = (B/racine(2) * (1+2/PI) * sin(PI/(4*B)) + (1-2/PI) * cos(PI/(4*B)))
|
24 |
|
|
-- t /= 0 and t /= Ts/(4*B) => SRRC(t) = (sin(PI.t.(1-B)/Ts) + 4.B.t.cos(PI.t.(1+B)/Ts)/Ts) / (PI.t.(1-((4.B.t)/Ts)^2)/Ts)
|
25 |
|
|
-- t: time
|
26 |
|
|
-- Ts: symbol period
|
27 |
|
|
-- B: filter roll-off
|
28 |
|
|
|
29 |
|
|
-- libraries used
|
30 |
|
|
library ieee;
|
31 |
|
|
use ieee.std_logic_1164.all;
|
32 |
|
|
use ieee.numeric_std.all;
|
33 |
|
|
use ieee.math_real.all;
|
34 |
|
|
|
35 |
|
|
--=============================================================================
|
36 |
|
|
-- Entity declaration for ccsds_tx / unitary rxtx srrc inputs and outputs
|
37 |
|
|
--=============================================================================
|
38 |
|
|
entity ccsds_rxtx_srrc is
|
39 |
|
|
generic(
|
40 |
|
|
constant CCSDS_RXTX_SRRC_APODIZATION_WINDOW_TYPE: integer range 0 to 2 := 1; -- 0=Dirichlet (Rectangular) / 1=Hamming / 2=Bartlett (Triangular)
|
41 |
|
|
constant CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO: integer;
|
42 |
|
|
constant CCSDS_RXTX_SRRC_ROLL_OFF: real := 0.5;
|
43 |
|
|
constant CCSDS_RXTX_SRRC_SIG_QUANT_DEPTH: integer
|
44 |
|
|
);
|
45 |
|
|
port(
|
46 |
|
|
-- inputs
|
47 |
|
|
clk_i: in std_logic;
|
48 |
|
|
rst_i: in std_logic;
|
49 |
|
|
sam_i: in std_logic_vector(CCSDS_RXTX_SRRC_SIG_QUANT_DEPTH-1 downto 0);
|
50 |
|
|
sam_val_i: in std_logic;
|
51 |
|
|
-- outputs
|
52 |
|
|
sam_o: out std_logic_vector(CCSDS_RXTX_SRRC_SIG_QUANT_DEPTH-1 downto 0);
|
53 |
|
|
sam_val_o: out std_logic
|
54 |
|
|
);
|
55 |
|
|
end ccsds_rxtx_srrc;
|
56 |
|
|
|
57 |
|
|
--=============================================================================
|
58 |
|
|
-- architecture declaration / internal components and connections
|
59 |
|
|
--=============================================================================
|
60 |
|
|
architecture rtl of ccsds_rxtx_srrc is
|
61 |
|
|
-- internal constants
|
62 |
|
|
constant CCSDS_RXTX_SRRC_RESPONSE_SYMBOL_CYCLES: integer:= 6; -- in symbol Time
|
63 |
|
|
constant CCSDS_RXTX_SRRC_FIR_COEFFICIENTS_NUMBER: integer := CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO*CCSDS_RXTX_SRRC_RESPONSE_SYMBOL_CYCLES+1;
|
64 |
|
|
constant CCSDS_RXTX_SRRC_SAMPLES_NUMBER: integer := (CCSDS_RXTX_SRRC_FIR_COEFFICIENTS_NUMBER-1)*2+1;
|
65 |
|
|
constant CCSDS_RXTX_SRRC_SPECIFIC_COEFFICIENT_VALUE_T0: real := (1.0 - CCSDS_RXTX_SRRC_ROLL_OFF + 4.0 * CCSDS_RXTX_SRRC_ROLL_OFF / MATH_PI);
|
66 |
|
|
constant CCSDS_RXTX_SRRC_SPECIFIC_COEFFICIENT_VALUE_TS: real := (CCSDS_RXTX_SRRC_ROLL_OFF / sqrt(2.0) * (1.0 + 2.0 / MATH_PI) * sin (MATH_PI / (4.0 * CCSDS_RXTX_SRRC_ROLL_OFF)) + (1.0 - 2.0 / MATH_PI) * cos (MATH_PI / (4.0 * CCSDS_RXTX_SRRC_ROLL_OFF)));
|
67 |
|
|
constant CCSDS_RXTX_SRRC_NORMALIZATION_GAIN: real := (2.0**(CCSDS_RXTX_SRRC_SIG_QUANT_DEPTH - 1) - 1.0) / CCSDS_RXTX_SRRC_SPECIFIC_COEFFICIENT_VALUE_T0; -- Exact value should be FIR coefficients RMS Gain / T0 Gain = Sqrt(Sum(Pow(coef,2)))) * Full Scale Value
|
68 |
|
|
constant CCSDS_RXTX_SRRC_SIG_IN_ADD_SIZE: integer := CCSDS_RXTX_SRRC_SIG_QUANT_DEPTH+1;
|
69 |
|
|
constant CCSDS_RXTX_SRRC_SIG_MUL_SIZE: integer := CCSDS_RXTX_SRRC_SIG_IN_ADD_SIZE+CCSDS_RXTX_SRRC_SIG_QUANT_DEPTH;
|
70 |
|
|
constant CCSDS_RXTX_SRRC_SIG_OUT_ADD_SIZE: integer := CCSDS_RXTX_SRRC_SIG_MUL_SIZE;
|
71 |
|
|
-- internal variable signals
|
72 |
|
|
type samples_array is array(CCSDS_RXTX_SRRC_SAMPLES_NUMBER-1 downto 0) of signed(CCSDS_RXTX_SRRC_SIG_QUANT_DEPTH-1 downto 0);
|
73 |
|
|
type srrc_tap_array is array(CCSDS_RXTX_SRRC_FIR_COEFFICIENTS_NUMBER-1 downto 0) of signed(CCSDS_RXTX_SRRC_SIG_QUANT_DEPTH-1 downto 0);
|
74 |
|
|
type srrc_multiplier_array is array(CCSDS_RXTX_SRRC_FIR_COEFFICIENTS_NUMBER-1 downto 0) of signed(CCSDS_RXTX_SRRC_SIG_MUL_SIZE-1 downto 0);
|
75 |
|
|
type srrc_input_adder_array is array(CCSDS_RXTX_SRRC_FIR_COEFFICIENTS_NUMBER-1 downto 0) of signed(CCSDS_RXTX_SRRC_SIG_IN_ADD_SIZE-1 downto 0);
|
76 |
|
|
type srrc_output_adder_array is array(CCSDS_RXTX_SRRC_FIR_COEFFICIENTS_NUMBER-1 downto 0) of signed(CCSDS_RXTX_SRRC_SIG_OUT_ADD_SIZE-1 downto 0);
|
77 |
|
|
signal sam_i_pipeline_registers: samples_array := (others => (others => '0'));
|
78 |
|
|
signal srrc_coefficients: srrc_tap_array;
|
79 |
|
|
signal srrc_multipliers_registers: srrc_multiplier_array := (others => (others => '0'));
|
80 |
|
|
signal srrc_input_adders_registers: srrc_input_adder_array := (others => (others => '0'));
|
81 |
|
|
signal srrc_output_adders_registers: srrc_output_adder_array := (others => (others => '0'));
|
82 |
|
|
|
83 |
|
|
-- components instanciation and mapping
|
84 |
|
|
begin
|
85 |
|
|
-- SRRC coefficients generation
|
86 |
|
|
-- At t = 0
|
87 |
|
|
srrc_coefficients(0) <= to_signed(integer(CCSDS_RXTX_SRRC_NORMALIZATION_GAIN * CCSDS_RXTX_SRRC_SPECIFIC_COEFFICIENT_VALUE_T0),CCSDS_RXTX_SRRC_SIG_QUANT_DEPTH);
|
88 |
|
|
-- Coefficients are symetrical / they are computed only for positive time response
|
89 |
|
|
SRRC_COEFS_GENERATOR: for coefficient_counter in 1 to CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO*CCSDS_RXTX_SRRC_RESPONSE_SYMBOL_CYCLES generate
|
90 |
|
|
-- At t = Ts/(4*B)
|
91 |
|
|
SRRC_SPECIFIC_COEFS: if (real(CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO)/real(coefficient_counter) = 4.0*CCSDS_RXTX_SRRC_ROLL_OFF) generate
|
92 |
|
|
SRRC_COEFS_WINDOW_DIRICHLET: if (CCSDS_RXTX_SRRC_APODIZATION_WINDOW_TYPE = 0) generate
|
93 |
|
|
srrc_coefficients(coefficient_counter) <= to_signed(integer(CCSDS_RXTX_SRRC_NORMALIZATION_GAIN * CCSDS_RXTX_SRRC_SPECIFIC_COEFFICIENT_VALUE_TS),CCSDS_RXTX_SRRC_SIG_QUANT_DEPTH);
|
94 |
|
|
end generate SRRC_COEFS_WINDOW_DIRICHLET;
|
95 |
|
|
SRRC_COEFS_WINDOW_HAMMING: if (CCSDS_RXTX_SRRC_APODIZATION_WINDOW_TYPE = 1) generate
|
96 |
|
|
srrc_coefficients(coefficient_counter) <= to_signed(integer((0.53836 + 0.46164 * cos(2.0 * MATH_PI * real(coefficient_counter) / real(CCSDS_RXTX_SRRC_FIR_COEFFICIENTS_NUMBER-1))) * CCSDS_RXTX_SRRC_NORMALIZATION_GAIN * CCSDS_RXTX_SRRC_SPECIFIC_COEFFICIENT_VALUE_TS),CCSDS_RXTX_SRRC_SIG_QUANT_DEPTH);
|
97 |
|
|
end generate SRRC_COEFS_WINDOW_HAMMING;
|
98 |
|
|
SRRC_COEFS_WINDOW_BARTLETT: if (CCSDS_RXTX_SRRC_APODIZATION_WINDOW_TYPE = 2) generate
|
99 |
|
|
srrc_coefficients(0) <= to_signed(integer(CCSDS_RXTX_SRRC_NORMALIZATION_GAIN * CCSDS_RXTX_SRRC_SPECIFIC_COEFFICIENT_VALUE_T0),CCSDS_RXTX_SRRC_SIG_QUANT_DEPTH);
|
100 |
|
|
srrc_coefficients(coefficient_counter) <= to_signed(integer((1.0 - abs((real(coefficient_counter) - real(CCSDS_RXTX_SRRC_FIR_COEFFICIENTS_NUMBER-1)/2.0) / real(CCSDS_RXTX_SRRC_FIR_COEFFICIENTS_NUMBER-1)/2.0)) * CCSDS_RXTX_SRRC_NORMALIZATION_GAIN * CCSDS_RXTX_SRRC_SPECIFIC_COEFFICIENT_VALUE_TS),CCSDS_RXTX_SRRC_SIG_QUANT_DEPTH);
|
101 |
|
|
end generate SRRC_COEFS_WINDOW_BARTLETT;
|
102 |
|
|
end generate SRRC_SPECIFIC_COEFS;
|
103 |
|
|
-- At t > 0 and t /= Ts/(4*B)
|
104 |
|
|
SRRC_GENERIC_COEFS: if (real(CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO)/real(coefficient_counter) /= 4.0*CCSDS_RXTX_SRRC_ROLL_OFF) generate
|
105 |
|
|
SRRC_COEFS_WINDOW_DIRICHLET: if (CCSDS_RXTX_SRRC_APODIZATION_WINDOW_TYPE = 0) generate
|
106 |
|
|
srrc_coefficients(coefficient_counter) <= to_signed(integer(CCSDS_RXTX_SRRC_NORMALIZATION_GAIN * (sin(MATH_PI * real(coefficient_counter) / real(CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO) * (1.0 - CCSDS_RXTX_SRRC_ROLL_OFF)) + 4.0 * CCSDS_RXTX_SRRC_ROLL_OFF * real(coefficient_counter) / real(CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO) * cos(MATH_PI * real(coefficient_counter) / real(CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO) * (1.0 + CCSDS_RXTX_SRRC_ROLL_OFF))) / (MATH_PI * real(coefficient_counter) / real(CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO) * (1.0 - (4.0 * CCSDS_RXTX_SRRC_ROLL_OFF * real(coefficient_counter) / real(CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO))**2))),CCSDS_RXTX_SRRC_SIG_QUANT_DEPTH);
|
107 |
|
|
end generate SRRC_COEFS_WINDOW_DIRICHLET;
|
108 |
|
|
SRRC_COEFS_WINDOW_HAMMING: if (CCSDS_RXTX_SRRC_APODIZATION_WINDOW_TYPE = 1) generate
|
109 |
|
|
srrc_coefficients(coefficient_counter) <= to_signed(integer((0.53836 + 0.46164 * cos(2.0 * MATH_PI * real(coefficient_counter) / real(CCSDS_RXTX_SRRC_FIR_COEFFICIENTS_NUMBER-1))) * CCSDS_RXTX_SRRC_NORMALIZATION_GAIN * (sin(MATH_PI * real(coefficient_counter) / real(CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO) * (1.0 - CCSDS_RXTX_SRRC_ROLL_OFF)) + 4.0 * CCSDS_RXTX_SRRC_ROLL_OFF * real(coefficient_counter) / real(CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO) * cos(MATH_PI * real(coefficient_counter) / real(CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO) * (1.0 + CCSDS_RXTX_SRRC_ROLL_OFF))) / (MATH_PI * real(coefficient_counter) / real(CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO) * (1.0 - (4.0 * CCSDS_RXTX_SRRC_ROLL_OFF * real(coefficient_counter) / real(CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO))**2))),CCSDS_RXTX_SRRC_SIG_QUANT_DEPTH);
|
110 |
|
|
end generate SRRC_COEFS_WINDOW_HAMMING;
|
111 |
|
|
SRRC_COEFS_WINDOW_BARTLETT: if (CCSDS_RXTX_SRRC_APODIZATION_WINDOW_TYPE = 2) generate
|
112 |
|
|
srrc_coefficients(coefficient_counter) <= to_signed(integer((1.0 - abs((real(coefficient_counter) - real(CCSDS_RXTX_SRRC_FIR_COEFFICIENTS_NUMBER-1)/2.0) / real(CCSDS_RXTX_SRRC_FIR_COEFFICIENTS_NUMBER-1)/2.0)) * CCSDS_RXTX_SRRC_NORMALIZATION_GAIN * (sin(MATH_PI * real(coefficient_counter) / real(CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO) * (1.0 - CCSDS_RXTX_SRRC_ROLL_OFF)) + 4.0 * CCSDS_RXTX_SRRC_ROLL_OFF * real(coefficient_counter) / real(CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO) * cos(MATH_PI * real(coefficient_counter) / real(CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO) * (1.0 + CCSDS_RXTX_SRRC_ROLL_OFF))) / (MATH_PI * real(coefficient_counter) / real(CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO) * (1.0 - (4.0 * CCSDS_RXTX_SRRC_ROLL_OFF * real(coefficient_counter) / real(CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO))**2))),CCSDS_RXTX_SRRC_SIG_QUANT_DEPTH);
|
113 |
|
|
end generate SRRC_COEFS_WINDOW_BARTLETT;
|
114 |
|
|
end generate SRRC_GENERIC_COEFS;
|
115 |
|
|
end generate SRRC_COEFS_GENERATOR;
|
116 |
|
|
-- presynthesis checks
|
117 |
|
|
CHKSRRCP0: if CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO mod 2 /= 0 generate
|
118 |
|
|
process
|
119 |
|
|
begin
|
120 |
|
|
report "ERROR: SRRC OVERSAMPLING RATIO MUST BE A MULTIPLE OF 2" severity failure;
|
121 |
|
|
wait;
|
122 |
|
|
end process;
|
123 |
|
|
end generate CHKSRRCP0;
|
124 |
|
|
CHKSRRCP1: if CCSDS_RXTX_SRRC_OVERSAMPLING_RATIO = 0 generate
|
125 |
|
|
process
|
126 |
|
|
begin
|
127 |
|
|
report "ERROR: SRRC OVERSAMPLING RATIO CANNOT BE NULL" severity failure;
|
128 |
|
|
wait;
|
129 |
|
|
end process;
|
130 |
|
|
end generate CHKSRRCP1;
|
131 |
|
|
CHKSRRCP2: if (CCSDS_RXTX_SRRC_ROLL_OFF < 0.0) or (CCSDS_RXTX_SRRC_ROLL_OFF > 1.0) generate
|
132 |
|
|
process
|
133 |
|
|
begin
|
134 |
|
|
report "ERROR: SRRC ROLL OFF HAS TO BE BETWEEN 0.0 AND 1.0" severity failure;
|
135 |
|
|
wait;
|
136 |
|
|
end process;
|
137 |
|
|
end generate CHKSRRCP2;
|
138 |
|
|
-- internal processing
|
139 |
|
|
--=============================================================================
|
140 |
|
|
-- Begin of srrcp
|
141 |
|
|
-- FIR filter coefficients
|
142 |
|
|
--=============================================================================
|
143 |
|
|
-- read: rst_i, sam_val_i, sam_i
|
144 |
|
|
-- write: sam_o, sam_val_o
|
145 |
|
|
-- r/w: sam_i_memory, sam_i_pipeline_registers, srrc_adders_registers, srrc_multipliers_registers
|
146 |
|
|
SRRCP: process (clk_i)
|
147 |
|
|
variable srrc_zero_in: signed(CCSDS_RXTX_SRRC_SIG_IN_ADD_SIZE-1 downto 0) := (others => '0');
|
148 |
|
|
variable srrc_zero_out: signed(CCSDS_RXTX_SRRC_SIG_OUT_ADD_SIZE-1 downto 0) := (others => '0');
|
149 |
|
|
begin
|
150 |
|
|
-- on each clock rising edge
|
151 |
|
|
if rising_edge(clk_i) then
|
152 |
|
|
-- reset signal received
|
153 |
|
|
if (rst_i = '1') then
|
154 |
|
|
sam_o <= (others => '0');
|
155 |
|
|
sam_val_o <= '0';
|
156 |
|
|
else
|
157 |
|
|
if (sam_val_i = '1') then
|
158 |
|
|
sam_val_o <= '1';
|
159 |
|
|
sam_i_pipeline_registers(0) <= signed(sam_i);
|
160 |
|
|
sam_i_pipeline_registers(CCSDS_RXTX_SRRC_SAMPLES_NUMBER-1 downto 1) <= sam_i_pipeline_registers(CCSDS_RXTX_SRRC_SAMPLES_NUMBER-2 downto 0);
|
161 |
|
|
for i in 0 to CCSDS_RXTX_SRRC_FIR_COEFFICIENTS_NUMBER-1 loop
|
162 |
|
|
srrc_multipliers_registers(i) <= srrc_input_adders_registers(i) * srrc_coefficients(i);
|
163 |
|
|
if (i = 0) then
|
164 |
|
|
srrc_input_adders_registers(i) <= sam_i_pipeline_registers(0) + srrc_zero_in;
|
165 |
|
|
srrc_output_adders_registers(i) <= srrc_multipliers_registers(i) + srrc_zero_out;
|
166 |
|
|
else
|
167 |
|
|
srrc_input_adders_registers(i) <= sam_i_pipeline_registers(0) + srrc_zero_in + sam_i_pipeline_registers(i*2);
|
168 |
|
|
srrc_output_adders_registers(i) <= srrc_multipliers_registers(i) + srrc_output_adders_registers(i-1);
|
169 |
|
|
end if;
|
170 |
|
|
end loop;
|
171 |
|
|
sam_o <= std_logic_vector(srrc_output_adders_registers(CCSDS_RXTX_SRRC_FIR_COEFFICIENTS_NUMBER-1)(CCSDS_RXTX_SRRC_SIG_OUT_ADD_SIZE-1 downto CCSDS_RXTX_SRRC_SIG_OUT_ADD_SIZE-CCSDS_RXTX_SRRC_SIG_QUANT_DEPTH));
|
172 |
|
|
else
|
173 |
|
|
sam_val_o <= '0';
|
174 |
|
|
end if;
|
175 |
|
|
end if;
|
176 |
|
|
end if;
|
177 |
|
|
end process;
|
178 |
|
|
end rtl;
|