URL
https://opencores.org/ocsvn/pwm_with_dithering/pwm_with_dithering/trunk
Subversion Repositories pwm_with_dithering
[/] [pwm_with_dithering/] [trunk/] [src/] [pwm_pipelined_small.vhd] - Rev 3
Compare with Previous | Blame | View Log
---------------------------------------------------------------------------------- -- Company: Aboa Space Research Oy (ASRO) -- Engineer: Tero Säntti -- -- Create Date: 11:43:23 02/03/2021 -- Design Name: PWM -- Module Name: pwm_pipelined_small - Behavioral -- Target Devices: None / non-specific -- Tool versions: None / non-specific -- Description: Dithered PWM with pipelining to increase maximum clock -- frequency. Somewhat larger and added latency during input -- changes. Not sensitive to input changes during operation. -- Modified by removing one register (target_i) to give smaller -- size with slight speed trade-off. -- -- 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_pipelined_small 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_pipelined_small; architecture Behavioral of pwm_pipelined_small 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 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)); doit:process(clk) begin if rising_edge(clk) then if (reversed_cnt_top < set(dithering-1 downto 0)) then inc <= '1'; else inc <= '0'; end if; 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 <= ('0' & set(bits-1 downto dithering)) + inc; trigger <= '1'; end if; end if; end process; end generate; end Behavioral;