OpenCores
URL https://opencores.org/ocsvn/pwm_with_dithering/pwm_with_dithering/trunk

Subversion Repositories pwm_with_dithering

[/] [pwm_with_dithering/] [trunk/] [src/] [pwm_reg.vhd] - Rev 3

Compare with Previous | Blame | View Log

----------------------------------------------------------------------------------
-- Company: 		 Aboa Space Research Oy (ASRO)
-- Engineer: 		 Tero Säntti
-- 
-- Create Date:    15:47:02 01/27/2021 
-- Design Name: 	 PWM
-- Module Name:    pwm_reg - Behavioral 
-- Target Devices: None / non-specific
-- Tool versions:  None / non-specific
-- Description: 	 Dithered PWM. Using register to hold target during op. Clock
--						 frequency is not maximal. Not sensitive to input 
--						 changes during operation. 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;  
 
entity pwm_reg is
    Generic ( 
				bits: integer:=16;
				dithering:integer:=5
				);
    Port ( clk : in  STD_LOGIC;
           set : in  STD_LOGIC_VECTOR(bits-1 downto 0);
           o   : out  STD_LOGIC);
end pwm_reg;
 
architecture Behavioral of pwm_reg is
signal o_i:std_logic:='0';
signal cnt:std_logic_vector(bits-1 downto 0):=(others => '0');
signal zeros:std_logic_vector((bits-dithering)-1 downto 0):=(others => '0');
signal ones:std_logic_vector((bits-dithering)-1 downto 0):=(others => '1');
signal target:std_logic_vector((bits-dithering) downto 0);
signal target_i:std_logic_vector((bits-dithering) downto 0);
signal reversed_cnt_top:std_logic_vector((dithering)-1 downto 0);
signal inc:std_logic;
signal trigger:std_logic;
 
function reverse_and_rebase_bit_order(a: in std_logic_vector)
return std_logic_vector is
  variable result: std_logic_vector(a'high-a'low downto 0);
begin
  for i in a'RANGE loop
    result(a'high-i) := a(i);
  end loop;
  return result;
end;
 
begin
 
-- output mapping:
o <= o_i;
 
normal: if dithering = 0  generate
 
zeros <= (others => '0');
ones  <= (others => '1');
 
doit:process(clk)
begin
if rising_edge(clk) then
	cnt <= cnt + 1;
	o_i <= o_i;
	trigger <= '0';
	if trigger = '1' then o_i <= '1'; end if;
	if '0' & cnt=target then o_i <= '0'; end if;
	if cnt(bits-1 downto 0) = ones then target <= '0' & set; trigger <= '1'; end if;
end if;
end process;
end generate;
 
dithered: if dithering > 0  generate
 
reversed_cnt_top <= reverse_and_rebase_bit_order(cnt(bits-1 downto bits-dithering));
inc <= '1' when (reversed_cnt_top < set(dithering-1 downto 0)) else '0';
target_i <= ('0' & set(bits-1 downto dithering)) + inc;
 
doit:process(clk)
begin
if rising_edge(clk) then
	cnt <= cnt + 1;
	o_i <= o_i;
	trigger <= '0';
	if trigger = '1' then o_i <= '1'; end if;
	if ('0' & cnt((bits-dithering)-1 downto 0)) = target then o_i <= '0'; end if;
	if cnt((bits-dithering)-1 downto 0) = ones then target <= target_i; trigger <= '1'; end if;
end if;
end process;
end generate;
 
end Behavioral;
 
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.