---------------------------------------------------------------------------------- -- Company: www.Circuit-Break.de -- Engineer: Jens Weiss -- -- Create Date: 08:43:14 02/14/2024 -- Design Name: -- Module Name: Npise_Shaper - Behavioral -- Project Name: -- Target Devices: -- Tool versions: -- Description: -- -- Dependencies: -- -- Revision: -- Revision 0.01 - File Created -- Additional Comments: -- -- https://www.edaboard.com/threads/dac-converter-using-a-pwm-modulation-in-vhdl.401689/ -- https://www.uni-ulm.de/en/in/mikro/forschung/schwerpunkte/ad-wandler/online-tool-for-rapid-continuous-time-sd-modulator-design/ -- ---------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity Noise_Shaper is Generic (--Input/Output definitions INPUT_WIDTH : integer := 24; OUTPUT_WIDTH : integer := 9; PULSE_DURATION : integer := 5; MAX_OUTPUT : integer := 250; MIN_OUTPUT : integer := -250; --MAC definitions MAC_DATA_WIDTH : integer := 26; --Opcode memory definitions OPCODE_ADRESS : integer := 5; DATA_SELECT_WIDTH : integer := 3; --Parameter memory definitions PARAMETER_WIDTH : integer := 16; PARAMETER_ADRESS : integer := 5; PARAMETER_SHIFT : integer := 15; --Calculation ram definitions CALC_RAM_DATA : integer := 43; CALC_RAM_ADRESS : integer := 7; --Integrator ram definitions INTEGRATOR_RAM_DATA : integer := 24; INTEGRATOR_RAM_ADRESS : integer := 2 ); Port ( clk : in std_logic; reset : in std_logic; data_in : in std_logic_vector (INPUT_WIDTH-1 downto 0); new_data : in std_logic; data_out : out std_logic_vector (OUTPUT_WIDTH-1 downto 0); debug_out : out std_logic_vector (INPUT_WIDTH-1 downto 0); ready : out std_logic; limit : out std_logic); end Noise_Shaper; architecture Behavioral of Noise_Shaper is --control signals for Noise shaper module signal state_reg : integer range 0 to 15 := 0; signal program_counter : integer range 0 to 63 := 0; signal int_ready : std_logic; signal data_select : std_logic_vector(DATA_SELECT_WIDTH-1 downto 0); signal int_limit : std_logic; signal LT_counter : integer range 0 to 4 := 0; signal LT1 : signed(MAC_DATA_WIDTH-1 downto 0); signal LT2 : signed(MAC_DATA_WIDTH-1 downto 0); signal LT3 : signed(MAC_DATA_WIDTH-1 downto 0); signal LT4 : signed(MAC_DATA_WIDTH-1 downto 0); signal LT1_old : signed(MAC_DATA_WIDTH-1 downto 0); signal LT2_old : signed(MAC_DATA_WIDTH-1 downto 0); signal LT3_old : signed(MAC_DATA_WIDTH-1 downto 0); signal LT4_old : signed(MAC_DATA_WIDTH-1 downto 0); signal int_output : signed(MAC_DATA_WIDTH-1 downto 0); signal int_output_old : signed(MAC_DATA_WIDTH-1 downto 0); signal int_quantized_out : signed(OUTPUT_WIDTH-1 downto 0); signal int_debug_out : signed(INPUT_WIDTH-1 downto 0); signal pulse_expand : integer range 0 to PULSE_DURATION := 0; --MAC Unit signals COMPONENT MAC_Unit PORT( clk : IN std_logic; MAC_preload : IN std_logic; MAC_exec : IN std_logic; MAC_Load : in std_logic_vector(MAC_DATA_WIDTH-1 downto 0); MAC_Din_a : IN std_logic_vector(MAC_DATA_WIDTH-1 downto 0); MAC_Din_b : IN std_logic_vector(PARAMETER_WIDTH-1 downto 0); MAC_Dout : OUT std_logic_vector(MAC_DATA_WIDTH-1 downto 0) ); END COMPONENT; signal MAC_preload : std_logic; signal MAC_exec : std_logic; signal MAC_Load : std_logic_vector(MAC_DATA_WIDTH-1 downto 0); signal MAC_Din_a : std_logic_vector(MAC_DATA_WIDTH-1 downto 0); signal MAC_Din_b : std_logic_vector(PARAMETER_WIDTH-1 downto 0); signal MAC_Dout : std_logic_vector(MAC_DATA_WIDTH-1 downto 0); --Opcode memory signals COMPONENT Opcode_memory PORT( clk : IN std_logic; A : IN std_logic_vector(OPCODE_ADRESS-1 downto 0); Dout : OUT std_logic_vector(PARAMETER_ADRESS+DATA_SELECT_WIDTH-1 downto 0) ); END COMPONENT; signal Opcode_Adr : std_logic_vector(OPCODE_ADRESS-1 downto 0); signal Opcode_Data : std_logic_vector(PARAMETER_ADRESS+DATA_SELECT_WIDTH-1 downto 0); --Parameter memory signals COMPONENT Parameter_memory PORT( clk : IN std_logic; A : IN std_logic_vector(PARAMETER_ADRESS-1 downto 0); Dout : OUT std_logic_vector(PARAMETER_WIDTH-1 downto 0) ); END COMPONENT; signal parameter_address : std_logic_vector(PARAMETER_ADRESS-1 downto 0); signal parameter_data : std_logic_vector(PARAMETER_WIDTH-1 downto 0); begin My_MAC_Unit: MAC_Unit PORT MAP( clk => clk, MAC_preload => MAC_preload, MAC_exec => MAC_exec, MAC_Load => MAC_Load, MAC_Din_a => MAC_Din_a, MAC_Din_b => MAC_Din_b, MAC_Dout => MAC_Dout ); My_Opcode_memory: Opcode_memory PORT MAP( clk => clk, A => Opcode_Adr, Dout => Opcode_Data ); My_Parameter_memory: Parameter_memory PORT MAP( clk => clk, A => parameter_address, Dout => parameter_data ); process begin wait until rising_edge(clk); if(reset = '1') then int_ready <= '0'; int_output <= (others => '0'); int_output_old <= (others => '0'); MAC_Load <= (others => '0'); LT1 <= (others => '0'); LT2 <= (others => '0'); LT3 <= (others => '0'); LT4 <= (others => '0'); LT1_old <= (others => '0'); LT2_old <= (others => '0'); LT3_old <= (others => '0'); LT4_old <= (others => '0'); else case state_reg is when 0 => if(new_data = '1') then state_reg <= 1; MAC_exec <= '0'; MAC_preload <= '0'; program_counter <= 0; LT_counter <= 0; pulse_expand <= 0; end if; --calculate all MAC operations when 1 => if(LT_counter = 0)then MAC_Load <= std_logic_vector(resize(signed(LT1),MAC_DATA_WIDTH)); elsif(LT_counter = 1)then MAC_Load <= std_logic_vector(resize(signed(LT2),MAC_DATA_WIDTH)); elsif(LT_counter = 2)then MAC_Load <= std_logic_vector(resize(signed(LT3),MAC_DATA_WIDTH)); elsif(LT_counter = 3)then MAC_Load <= std_logic_vector(resize(signed(LT4),MAC_DATA_WIDTH)); else MAC_Load <= (others => '0'); end if; state_reg <= 2; when 2 => MAC_preload <= '1'; state_reg <= 3; when 3 => MAC_preload <= '0'; state_reg <= 4; when 4 => MAC_exec <= '1'; state_reg <= 5; when 5 => MAC_exec <= '0'; program_counter <= program_counter + 1; state_reg <= 6; when 6 => if(program_counter = 5) then --1st stage LT1 LT1 <= signed(MAC_Dout); LT_counter <= LT_counter + 1; state_reg <= 1; elsif(program_counter = 10) then --2nd stage LT2 LT2 <= signed(MAC_Dout); LT_counter <= LT_counter + 1; state_reg <= 1; elsif(program_counter = 15) then --3rd stage LT2 LT3 <= signed(MAC_Dout); LT_counter <= LT_counter + 1; state_reg <= 1; elsif(program_counter = 20) then --4th stage LT4 LT4 <= signed(MAC_Dout); LT_counter <= LT_counter + 1; state_reg <= 1; elsif(program_counter = 26) then --last stage int_output <= signed(MAC_Dout); LT1_old <= LT1; LT2_old <= LT2; LT3_old <= LT3; LT4_old <= LT4; state_reg <= 7; else state_reg <= 4; end if; when 7 => int_output_old <= shift_right(signed(int_output), PARAMETER_SHIFT); state_reg <= 8; when 8 => if(int_output_old < MIN_OUTPUT) then int_quantized_out <= to_signed(MIN_OUTPUT, OUTPUT_WIDTH); int_limit <= '1'; elsif(int_output_old > MAX_OUTPUT) then int_quantized_out <= to_signed(MAX_OUTPUT, OUTPUT_WIDTH); int_limit <= '1'; else int_quantized_out <= resize(signed(int_output_old), OUTPUT_WIDTH); int_limit <= '0'; end if; state_reg <= 9; when 9 => int_ready <= '1'; int_output_old <= shift_left(signed(int_output_old), PARAMETER_SHIFT); --for debug information---------------------------------------------------- int_debug_out <= resize(signed(int_output_old), 24); --------------------------------------------------------------------------- state_reg <= 10; when 10 => if(pulse_expand < PULSE_DURATION)then pulse_expand <= pulse_expand + 1; else pulse_expand <= 0; int_ready <= '0'; state_reg <= 0; end if; when others => state_reg <= 0; end case; end if; end process; MAC_Din_b <= parameter_data; with data_select select MAC_Din_a <= std_logic_vector(resize(signed(data_in), MAC_DATA_WIDTH)) when "000", std_logic_vector(resize(signed(int_output_old), MAC_DATA_WIDTH)) when "001", std_logic_vector(LT1_old) when "010", std_logic_vector(LT2_old) when "011", std_logic_vector(LT3_old) when "100", std_logic_vector(LT4_old) when "101", (others => '0') when others; data_out <= std_logic_vector(int_quantized_out); parameter_address <= Opcode_Data(PARAMETER_ADRESS+DATA_SELECT_WIDTH-1 downto DATA_SELECT_WIDTH); Opcode_Adr <= std_logic_vector(to_unsigned(program_counter, OPCODE_ADRESS)); data_select <= Opcode_Data(DATA_SELECT_WIDTH-1 downto 0); ready <= int_ready; limit <= int_limit; debug_out <= std_logic_vector(int_debug_out); end Behavioral;