URL
https://opencores.org/ocsvn/pwm_with_dithering/pwm_with_dithering/trunk
Subversion Repositories pwm_with_dithering
[/] [pwm_with_dithering/] [trunk/] [testbench/] [pwm_to_voltage.vhd] - Rev 2
Compare with Previous | Blame | View Log
---------------------------------------------------------------------------------- -- Company: Aboa Space Research Oy (ASRO) -- Engineer: Tero Säntti -- -- Create Date: 15:02:39 01/27/2021 -- Design Name: PWM verifier -- Module Name: pwm_to_voltage - Behavioral -- Target Devices: None / Simulation ONLY -- Tool versions: None / non-specific -- Description: Calculate PWM to real voltage. Adjustable R, C and supply -- voltage. Auto refresh option, in case PWM is halted or keeps -- '0' or '1' for extended time, also usefull if RC filters are -- cascaded after this, and require smaller time steps. -- -- Revision: -- Revision 0.01 - File Created -- Additional Comments: -- ---------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; use IEEE.math_real.all; entity pwm_to_voltage is Generic ( autorefresh_interval : time; autorefresh_enabled : boolean; supply_voltage : real:=3.3; R : real:=100.0; C : real:=0.0001 ); Port ( pwm : in STD_LOGIC; voltage : out real; frequency : out real ); end pwm_to_voltage; architecture Behavioral of pwm_to_voltage is signal cur:real:=0.0; signal prev_dir:std_logic:='0'; signal auto:std_logic:='0'; begin -- output mapping: voltage <= cur; doit:process(pwm,auto) variable time_diff:time; variable real_time_diff_sec:real; variable last_update:time:= 0 ns; begin time_diff := now - last_update; real_time_diff_sec:=(real(time_diff/(1 ps)))/1000000000000.0; if prev_dir='0' then cur <= cur*((2.71828182845904523536028747135266249775724709369995 ** ((0.0-real_time_diff_sec)/(R*C)))); else cur <= cur + (supply_voltage-cur)*(1.0-(2.71828182845904523536028747135266249775724709369995 ** ((0.0-real_time_diff_sec)/(R*C)))); end if; last_update := now; prev_dir <= pwm; end process; autorefresh:process begin if autorefresh_enabled then auto <= '0'; wait for autorefresh_interval; auto <= '1'; wait for autorefresh_interval; else auto <= '0'; wait; end if; end process; freq_monitor:process(pwm) variable up_time:time; begin if pwm='1' then frequency <= 1000000000000.0 / ((now - up_time)/1.0 ps); up_time := now; end if; end process; end Behavioral;