1 | library ieee;
|
2 | use ieee.std_logic_1164.all;
|
3 | use ieee.numeric_std.all;
|
4 |
|
5 | entity cvsd_encoder is
|
6 | -- Anfangswerte für die Integratoren bzw. Summierer
|
7 | -- demin = 0.001; demax = 0.1; ts = 1.0; td = 4.0
|
8 | -- samprate = 16000
|
9 | -- leakageFactor=exp(-1/(samprate*td/1000));
|
10 | -- predictorCoefficient=exp(-1/(samprate*ts/1000));
|
11 | -- Mittels Simulink Fixpoint wurden folgende Zahlenformate ermittelt:
|
12 | -- Für leakageFactor, predictorCoefficient, demin und demax Unsigned Fix(14,14) (14 Nachkommastellen)
|
13 | -- Für alle anderen Faktoren Signed Fix(16,14) (Vorzeichen, 1 Vorkommastelle, 14 Nachkommastellen)
|
14 |
|
15 | -- leakageFactor für:
|
16 | -- 2000;4000:8000:16000
|
17 | -- 0,8825;0,9394;0,9692;0,9845
|
18 | -- 2.000 = 0.11100001'11101011
|
19 | -- 4.000 = 0.11110000'01111101
|
20 | -- 8.000 = 0.11111000'00011111
|
21 | -- 16.000 = 0.11111100'00000111
|
22 | -- predictorCoefficient für:
|
23 | -- 2000;4000;8000;16000
|
24 | -- 0,6065;0,7788;0,8825;0,9394
|
25 | -- 2.000 = 0.10011011'01000101
|
26 | -- 4.000 = 0.11000111'01011111
|
27 | -- 8.000 = 0.11100001'11101011
|
28 | -- 16.000 = 0.11110000'01111101
|
29 | -- leakageFactor = 0.9845
|
30 | -- predictorCoefficient = 0.9394
|
31 | generic
|
32 | (
|
33 | SampleRate : natural := 16000;
|
34 | inputSize : natural := 8
|
35 | );
|
36 |
|
37 | port
|
38 | (
|
39 | -----------------------------> Inputs
|
40 | FilteredWaveSample : in std_logic_vector(inputSize-1 downto 0);
|
41 | clock : in std_logic;
|
42 | reset : in std_logic;
|
43 | load : in std_logic;
|
44 | -----------------------------> Outputs
|
45 | output_valid : out std_logic;
|
46 | cvsdOut : out std_logic
|
47 | );
|
48 | end cvsd_encoder;
|
49 |
|
50 |
|
51 |
|
52 | architecture cvsd_rtl of cvsd_encoder is
|
53 | constant int : natural := 1;
|
54 | constant frac : natural := 14;
|
55 | type states is (init_state, diff_state, overload_state, unipolar_state);
|
56 | signal state : states;
|
57 | subtype sfix1614 is signed (int+frac downto 0);
|
58 | subtype sfix3014 is signed (2*(int+frac)-1 downto 0);
|
59 | subtype ufix1414 is unsigned (frac-1 downto 0);
|
60 | signal diff, stepSize, estimatedSignal, encStep : sfix1614;
|
61 | signal overload : bit;
|
62 | signal cvsd : bit_vector (2 downto 0);
|
63 | -- Nur Nachkommastellen
|
64 | constant leakageFactor : ufix1414 := b"11111100_000001";
|
65 | constant predictorCoeffizient : ufix1414 := b"11110000_011111";
|
66 | -- demin 0.001 = 0.00000000'01000001
|
67 | -- demax 0.1 = 0.00011001'10011001
|
68 | -- Nur Nachkommastellen
|
69 | constant demin : ufix1414 := b"00000000_010000";
|
70 | constant demax : ufix1414 := b"00011001_100110";
|
71 | -- (Vorzeichen, 1 Vorkommastelle, 14 Nachkommastellen)
|
72 | signal summe : sfix1614;
|
73 | -- signal product1, product2 : sfix3014;
|
74 | begin
|
75 | process (clock)
|
76 | variable product1, product2 : sfix3014;
|
77 | begin
|
78 | if rising_edge(clock)
|
79 | then
|
80 | case state is
|
81 | when init_state => if reset = '1'
|
82 | then
|
83 | estimatedSignal <= (others => '0');
|
84 | encStep <= (others => '0');
|
85 | cvsd(0) <= '0';
|
86 | cvsd(1) <= '0';
|
87 | if load = '1'
|
88 | then
|
89 | state <= diff_state;
|
90 | end if;
|
91 | end if;
|
92 |
|
93 | when diff_state => -- SFix(16,14) = UFix(16,0) - SFix(16,14)
|
94 | diff <= signed(FilteredWaveSample) - estimatedSignal;
|
95 | if to_integer(diff) >= 0
|
96 | then
|
97 | cvsd(2) <= '1';
|
98 | else
|
99 | cvsd(2) <= '0';
|
100 | end if;
|
101 | state <= overload_state;
|
102 |
|
103 | when overload_state => overload <= (cvsd(0) and cvsd(1) and cvsd(2)) or
|
104 | (not cvsd(0) and not cvsd(1) and not cvsd(2));
|
105 | if overload = '1'
|
106 | then
|
107 | -- Addition des Nachkommaanteils
|
108 | -- SFix(16,14) = SFix(16,14) + UFix(14,14)
|
109 | summe <= encStep + signed(demin);
|
110 | -- encStep <= min(summe,demax);
|
111 | if summe < to_integer(demax)
|
112 | then
|
113 | encStep <= summe;
|
114 | else
|
115 | -- Zuweisung des Nachkommaanteils
|
116 | -- SFix(16,14) = UFix(14,14)
|
117 | encStep(frac-1 downto 0) <= signed(demax);
|
118 | end if;
|
119 | else
|
120 | -- SFix(30,14) = SFix(16,14) * UFix(14,14)
|
121 | product1 := encStep * signed(leakageFactor);
|
122 | -- encStep <= max(produkt,demin);
|
123 | if product1 < to_integer(demin)
|
124 | then
|
125 | encStep <= product1(int+frac downto 0);
|
126 | else
|
127 | encStep(frac-1 downto 0) <= signed(demin);
|
128 | end if;
|
129 | end if;
|
130 | state <= unipolar_state;
|
131 |
|
132 | when unipolar_state => -- Unipolar to Bipolar
|
133 | -- Aus [0,1] wird [-1,+1]
|
134 | -- stepSize <= factor * encStep;
|
135 | if cvsd(2) = '0'
|
136 | then
|
137 | stepSize <= -encStep;
|
138 | else
|
139 | stepSize <= encStep;
|
140 | end if;
|
141 | -- SFix(30,14) = SFix(16,14) * UFix(14,14)
|
142 | product2 := estimatedSignal * signed(predictorCoeffizient);
|
143 | -- SFix(16,14) = SFix(16,14) + ????
|
144 | estimatedSignal <= stepSize + product2(int+frac downto 0);
|
145 | cvsd(0) <= cvsd(1);
|
146 | cvsd(1) <= cvsd(2);
|
147 | cvsdout <= to_stdulogic(cvsd(2));
|
148 | output_valid <= '1';
|
149 | end case;
|
150 | end if;
|
151 | end process;
|
152 |
|
153 | end architecture cvsd_rtl;
|