1 | ----------------------------------------------------------------------------------
|
2 | -- Company: www.Circuit-Break.de
|
3 | -- Engineer: Jens Weiss
|
4 | --
|
5 | -- Create Date: 08:43:14 02/14/2024
|
6 | -- Design Name:
|
7 | -- Module Name: Npise_Shaper - Behavioral
|
8 | -- Project Name:
|
9 | -- Target Devices:
|
10 | -- Tool versions:
|
11 | -- Description:
|
12 | --
|
13 | -- Dependencies:
|
14 | --
|
15 | -- Revision:
|
16 | -- Revision 0.01 - File Created
|
17 | -- Additional Comments:
|
18 | --
|
19 | -- https://www.edaboard.com/threads/dac-converter-using-a-pwm-modulation-in-vhdl.401689/
|
20 | -- https://www.uni-ulm.de/en/in/mikro/forschung/schwerpunkte/ad-wandler/online-tool-for-rapid-continuous-time-sd-modulator-design/
|
21 | --
|
22 | ----------------------------------------------------------------------------------
|
23 | library IEEE;
|
24 | use IEEE.STD_LOGIC_1164.ALL;
|
25 | use IEEE.NUMERIC_STD.ALL;
|
26 |
|
27 |
|
28 | entity Noise_Shaper is
|
29 | Generic (--Input/Output definitions
|
30 | INPUT_WIDTH : integer := 24;
|
31 | OUTPUT_WIDTH : integer := 9;
|
32 | PULSE_DURATION : integer := 5;
|
33 | MAX_OUTPUT : integer := 250;
|
34 | MIN_OUTPUT : integer := -250;
|
35 | --MAC definitions
|
36 | MAC_DATA_WIDTH : integer := 26;
|
37 | --Opcode memory definitions
|
38 | OPCODE_ADRESS : integer := 5;
|
39 | DATA_SELECT_WIDTH : integer := 3;
|
40 | --Parameter memory definitions
|
41 | PARAMETER_WIDTH : integer := 16;
|
42 | PARAMETER_ADRESS : integer := 5;
|
43 | PARAMETER_SHIFT : integer := 15;
|
44 | --Calculation ram definitions
|
45 | CALC_RAM_DATA : integer := 43;
|
46 | CALC_RAM_ADRESS : integer := 7;
|
47 | --Integrator ram definitions
|
48 | INTEGRATOR_RAM_DATA : integer := 24;
|
49 | INTEGRATOR_RAM_ADRESS : integer := 2
|
50 | );
|
51 |
|
52 | Port ( clk : in std_logic;
|
53 | reset : in std_logic;
|
54 | data_in : in std_logic_vector (INPUT_WIDTH-1 downto 0);
|
55 | new_data : in std_logic;
|
56 | data_out : out std_logic_vector (OUTPUT_WIDTH-1 downto 0);
|
57 | debug_out : out std_logic_vector (INPUT_WIDTH-1 downto 0);
|
58 | ready : out std_logic;
|
59 | limit : out std_logic);
|
60 | end Noise_Shaper;
|
61 |
|
62 | architecture Behavioral of Noise_Shaper is
|
63 |
|
64 | --control signals for Noise shaper module
|
65 | signal state_reg : integer range 0 to 15 := 0;
|
66 | signal program_counter : integer range 0 to 63 := 0;
|
67 | signal int_ready : std_logic;
|
68 | signal data_select : std_logic_vector(DATA_SELECT_WIDTH-1 downto 0);
|
69 | signal int_limit : std_logic;
|
70 | signal LT_counter : integer range 0 to 4 := 0;
|
71 | signal LT1 : signed(MAC_DATA_WIDTH-1 downto 0);
|
72 | signal LT2 : signed(MAC_DATA_WIDTH-1 downto 0);
|
73 | signal LT3 : signed(MAC_DATA_WIDTH-1 downto 0);
|
74 | signal LT4 : signed(MAC_DATA_WIDTH-1 downto 0);
|
75 | signal LT1_old : signed(MAC_DATA_WIDTH-1 downto 0);
|
76 | signal LT2_old : signed(MAC_DATA_WIDTH-1 downto 0);
|
77 | signal LT3_old : signed(MAC_DATA_WIDTH-1 downto 0);
|
78 | signal LT4_old : signed(MAC_DATA_WIDTH-1 downto 0);
|
79 | signal int_output : signed(MAC_DATA_WIDTH-1 downto 0);
|
80 | signal int_output_old : signed(MAC_DATA_WIDTH-1 downto 0);
|
81 | signal int_quantized_out : signed(OUTPUT_WIDTH-1 downto 0);
|
82 | signal int_debug_out : signed(INPUT_WIDTH-1 downto 0);
|
83 | signal pulse_expand : integer range 0 to PULSE_DURATION := 0;
|
84 |
|
85 | --MAC Unit signals
|
86 | COMPONENT MAC_Unit
|
87 | PORT(
|
88 | clk : IN std_logic;
|
89 | MAC_preload : IN std_logic;
|
90 | MAC_exec : IN std_logic;
|
91 | MAC_Load : in std_logic_vector(MAC_DATA_WIDTH-1 downto 0);
|
92 | MAC_Din_a : IN std_logic_vector(MAC_DATA_WIDTH-1 downto 0);
|
93 | MAC_Din_b : IN std_logic_vector(PARAMETER_WIDTH-1 downto 0);
|
94 | MAC_Dout : OUT std_logic_vector(MAC_DATA_WIDTH-1 downto 0)
|
95 | );
|
96 | END COMPONENT;
|
97 | signal MAC_preload : std_logic;
|
98 | signal MAC_exec : std_logic;
|
99 | signal MAC_Load : std_logic_vector(MAC_DATA_WIDTH-1 downto 0);
|
100 | signal MAC_Din_a : std_logic_vector(MAC_DATA_WIDTH-1 downto 0);
|
101 | signal MAC_Din_b : std_logic_vector(PARAMETER_WIDTH-1 downto 0);
|
102 | signal MAC_Dout : std_logic_vector(MAC_DATA_WIDTH-1 downto 0);
|
103 |
|
104 | --Opcode memory signals
|
105 | COMPONENT Opcode_memory
|
106 | PORT(
|
107 | clk : IN std_logic;
|
108 | A : IN std_logic_vector(OPCODE_ADRESS-1 downto 0);
|
109 | Dout : OUT std_logic_vector(PARAMETER_ADRESS+DATA_SELECT_WIDTH-1 downto 0)
|
110 | );
|
111 | END COMPONENT;
|
112 | signal Opcode_Adr : std_logic_vector(OPCODE_ADRESS-1 downto 0);
|
113 | signal Opcode_Data : std_logic_vector(PARAMETER_ADRESS+DATA_SELECT_WIDTH-1 downto 0);
|
114 |
|
115 | --Parameter memory signals
|
116 | COMPONENT Parameter_memory
|
117 | PORT(
|
118 | clk : IN std_logic;
|
119 | A : IN std_logic_vector(PARAMETER_ADRESS-1 downto 0);
|
120 | Dout : OUT std_logic_vector(PARAMETER_WIDTH-1 downto 0)
|
121 | );
|
122 | END COMPONENT;
|
123 | signal parameter_address : std_logic_vector(PARAMETER_ADRESS-1 downto 0);
|
124 | signal parameter_data : std_logic_vector(PARAMETER_WIDTH-1 downto 0);
|
125 |
|
126 | begin
|
127 |
|
128 | My_MAC_Unit: MAC_Unit PORT MAP(
|
129 | clk => clk,
|
130 | MAC_preload => MAC_preload,
|
131 | MAC_exec => MAC_exec,
|
132 | MAC_Load => MAC_Load,
|
133 | MAC_Din_a => MAC_Din_a,
|
134 | MAC_Din_b => MAC_Din_b,
|
135 | MAC_Dout => MAC_Dout
|
136 | );
|
137 |
|
138 | My_Opcode_memory: Opcode_memory PORT MAP(
|
139 | clk => clk,
|
140 | A => Opcode_Adr,
|
141 | Dout => Opcode_Data
|
142 | );
|
143 |
|
144 | My_Parameter_memory: Parameter_memory PORT MAP(
|
145 | clk => clk,
|
146 | A => parameter_address,
|
147 | Dout => parameter_data
|
148 | );
|
149 |
|
150 | process
|
151 | begin
|
152 | wait until rising_edge(clk);
|
153 |
|
154 | if(reset = '1') then
|
155 | int_ready <= '0';
|
156 | int_output <= (others => '0');
|
157 | int_output_old <= (others => '0');
|
158 | MAC_Load <= (others => '0');
|
159 | LT1 <= (others => '0');
|
160 | LT2 <= (others => '0');
|
161 | LT3 <= (others => '0');
|
162 | LT4 <= (others => '0');
|
163 | LT1_old <= (others => '0');
|
164 | LT2_old <= (others => '0');
|
165 | LT3_old <= (others => '0');
|
166 | LT4_old <= (others => '0');
|
167 | else
|
168 | case state_reg is
|
169 | when 0 =>
|
170 | if(new_data = '1') then
|
171 | state_reg <= 1;
|
172 | MAC_exec <= '0';
|
173 | MAC_preload <= '0';
|
174 | program_counter <= 0;
|
175 | LT_counter <= 0;
|
176 | pulse_expand <= 0;
|
177 | end if;
|
178 |
|
179 | --calculate all MAC operations
|
180 | when 1 =>
|
181 | if(LT_counter = 0)then
|
182 | MAC_Load <= std_logic_vector(resize(signed(LT1),MAC_DATA_WIDTH));
|
183 | elsif(LT_counter = 1)then
|
184 | MAC_Load <= std_logic_vector(resize(signed(LT2),MAC_DATA_WIDTH));
|
185 | elsif(LT_counter = 2)then
|
186 | MAC_Load <= std_logic_vector(resize(signed(LT3),MAC_DATA_WIDTH));
|
187 | elsif(LT_counter = 3)then
|
188 | MAC_Load <= std_logic_vector(resize(signed(LT4),MAC_DATA_WIDTH));
|
189 | else
|
190 | MAC_Load <= (others => '0');
|
191 | end if;
|
192 | state_reg <= 2;
|
193 |
|
194 | when 2 =>
|
195 | MAC_preload <= '1';
|
196 | state_reg <= 3;
|
197 |
|
198 | when 3 =>
|
199 | MAC_preload <= '0';
|
200 | state_reg <= 4;
|
201 |
|
202 | when 4 =>
|
203 | MAC_exec <= '1';
|
204 | state_reg <= 5;
|
205 |
|
206 | when 5 =>
|
207 | MAC_exec <= '0';
|
208 | program_counter <= program_counter + 1;
|
209 | state_reg <= 6;
|
210 |
|
211 | when 6 =>
|
212 | if(program_counter = 5) then --1st stage LT1
|
213 | LT1 <= signed(MAC_Dout);
|
214 | LT_counter <= LT_counter + 1;
|
215 | state_reg <= 1;
|
216 | elsif(program_counter = 10) then --2nd stage LT2
|
217 | LT2 <= signed(MAC_Dout);
|
218 | LT_counter <= LT_counter + 1;
|
219 | state_reg <= 1;
|
220 | elsif(program_counter = 15) then --3rd stage LT2
|
221 | LT3 <= signed(MAC_Dout);
|
222 | LT_counter <= LT_counter + 1;
|
223 | state_reg <= 1;
|
224 | elsif(program_counter = 20) then --4th stage LT4
|
225 | LT4 <= signed(MAC_Dout);
|
226 | LT_counter <= LT_counter + 1;
|
227 | state_reg <= 1;
|
228 | elsif(program_counter = 26) then --last stage
|
229 | int_output <= signed(MAC_Dout);
|
230 | LT1_old <= LT1;
|
231 | LT2_old <= LT2;
|
232 | LT3_old <= LT3;
|
233 | LT4_old <= LT4;
|
234 | state_reg <= 7;
|
235 | else
|
236 | state_reg <= 4;
|
237 | end if;
|
238 |
|
239 |
|
240 | when 7 =>
|
241 | int_output_old <= shift_right(signed(int_output), PARAMETER_SHIFT);
|
242 | state_reg <= 8;
|
243 |
|
244 | when 8 =>
|
245 | if(int_output_old < MIN_OUTPUT) then
|
246 | int_quantized_out <= to_signed(MIN_OUTPUT, OUTPUT_WIDTH);
|
247 | int_limit <= '1';
|
248 | elsif(int_output_old > MAX_OUTPUT) then
|
249 | int_quantized_out <= to_signed(MAX_OUTPUT, OUTPUT_WIDTH);
|
250 | int_limit <= '1';
|
251 | else
|
252 | int_quantized_out <= resize(signed(int_output_old), OUTPUT_WIDTH);
|
253 | int_limit <= '0';
|
254 | end if;
|
255 | state_reg <= 9;
|
256 |
|
257 | when 9 =>
|
258 | int_ready <= '1';
|
259 | int_output_old <= shift_left(signed(int_output_old), PARAMETER_SHIFT);
|
260 | --for debug information----------------------------------------------------
|
261 | int_debug_out <= resize(signed(int_output_old), 24);
|
262 | ---------------------------------------------------------------------------
|
263 | state_reg <= 10;
|
264 |
|
265 | when 10 =>
|
266 | if(pulse_expand < PULSE_DURATION)then
|
267 | pulse_expand <= pulse_expand + 1;
|
268 | else
|
269 | pulse_expand <= 0;
|
270 | int_ready <= '0';
|
271 | state_reg <= 0;
|
272 | end if;
|
273 |
|
274 | when others => state_reg <= 0;
|
275 | end case;
|
276 | end if;
|
277 | end process;
|
278 |
|
279 | MAC_Din_b <= parameter_data;
|
280 | with data_select select
|
281 | MAC_Din_a <= std_logic_vector(resize(signed(data_in), MAC_DATA_WIDTH)) when "000",
|
282 | std_logic_vector(resize(signed(int_output_old), MAC_DATA_WIDTH)) when "001",
|
283 | std_logic_vector(LT1_old) when "010",
|
284 | std_logic_vector(LT2_old) when "011",
|
285 | std_logic_vector(LT3_old) when "100",
|
286 | std_logic_vector(LT4_old) when "101",
|
287 | (others => '0') when others;
|
288 |
|
289 | data_out <= std_logic_vector(int_quantized_out);
|
290 | parameter_address <= Opcode_Data(PARAMETER_ADRESS+DATA_SELECT_WIDTH-1 downto DATA_SELECT_WIDTH);
|
291 | Opcode_Adr <= std_logic_vector(to_unsigned(program_counter, OPCODE_ADRESS));
|
292 | data_select <= Opcode_Data(DATA_SELECT_WIDTH-1 downto 0);
|
293 | ready <= int_ready;
|
294 | limit <= int_limit;
|
295 |
|
296 | debug_out <= std_logic_vector(int_debug_out);
|
297 |
|
298 | end Behavioral;
|