Noise_Shaper.vhd


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;