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

Subversion Repositories pwm_with_dithering

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /pwm_with_dithering/trunk
    from Rev 2 to Rev 3
    Reverse comparison

Rev 2 → Rev 3

/src/pwm.vhd
0,0 → 1,92
----------------------------------------------------------------------------------
-- Company: Aboa Space Research Oy (ASRO)
 
--
-- Create Date: 14:50:27 01/27/2021
-- Design Name: PWM
-- Module Name: pwm - Behavioral
-- Target Devices: None / non-specific
-- Tool versions: None / non-specific
-- Description: Dithered PWM. Simple implementation. Minimal size, but clock
-- frequency is not maximal. Also, may be sensitive to input
-- changes during operation. (Input value jumps to a lower value
-- than current counter value.) Fixable with additional register
-- which loaded if counter @ max value. The fix is implemented
-- in the pipelined version.
--
-- 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 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;
 
architecture Behavioral of pwm 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 target:std_logic_vector((bits-dithering) downto 0);
signal reversed_cnt_top:std_logic_vector((dithering)-1 downto 0);
signal inc: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;
 
zeros <= (others => '0');
 
normal: if dithering = 0 generate
doit:process(clk)
begin
if rising_edge(clk) then
cnt <= cnt + 1;
o_i <= o_i;
if cnt=zeros then o_i <= '1'; end if;
if cnt=set then o_i <= '0'; 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 <= ('0' & set(bits-1 downto dithering)) + inc;
 
doit:process(clk)
begin
if rising_edge(clk) then
cnt <= cnt + 1;
o_i <= o_i;
if cnt((bits-dithering)-1 downto 0) = zeros then o_i <= '1'; end if;
if ('0' & cnt((bits-dithering)-1 downto 0)) = target then o_i <= '0'; end if;
end if;
end process;
end generate;
 
end Behavioral;
 
/src/pwm_ineq.vhd
0,0 → 1,89
----------------------------------------------------------------------------------
-- Company: Aboa Space Research Oy (ASRO)
 
--
-- Create Date: 15:31:34 01/27/2021
-- Design Name: PWM
-- Module Name: pwm_ineq - Behavioral
-- Target Devices: None / non-specific
-- Tool versions: None / non-specific
-- Description: Dithered PWM. Cycle ends with inequality operation. 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_ineq 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_ineq;
 
architecture Behavioral of pwm_ineq 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 target:std_logic_vector((bits-dithering) downto 0);
signal reversed_cnt_top:std_logic_vector((dithering)-1 downto 0);
signal inc: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;
 
zeros <= (others => '0');
 
normal: if dithering = 0 generate
doit:process(clk)
begin
if rising_edge(clk) then
cnt <= cnt + 1;
o_i <= o_i;
if cnt=zeros then o_i <= '1'; end if;
if cnt>=set then o_i <= '0'; 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 <= ('0' & set(bits-1 downto dithering)) + inc;
 
doit:process(clk)
begin
if rising_edge(clk) then
cnt <= cnt + 1;
o_i <= o_i;
if cnt((bits-dithering)-1 downto 0) = zeros then o_i <= '1'; end if;
if ('0' & cnt((bits-dithering)-1 downto 0)) >= target then o_i <= '0'; end if;
end if;
end process;
end generate;
 
end Behavioral;
 
/src/pwm_pipelined.vhd
0,0 → 1,104
----------------------------------------------------------------------------------
-- Company: Aboa Space Research Oy (ASRO)
 
--
-- Create Date: 15:26:48 01/27/2021
-- Design Name: PWM
-- Module Name: pwm_pipelined - 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.
--
-- 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 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;
 
architecture Behavioral of pwm_pipelined 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));
 
pipelining: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;
target_i <= ('0' & set(bits-1 downto dithering)) + inc;
end if;
end process;
 
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;
 
/src/pwm_pipelined_small.vhd
0,0 → 1,98
----------------------------------------------------------------------------------
-- Company: Aboa Space Research Oy (ASRO)
 
--
-- 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;
 
/src/pwm_reg.vhd
0,0 → 1,98
----------------------------------------------------------------------------------
-- Company: Aboa Space Research Oy (ASRO)
 
--
-- 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;
 

powered by: WebSVN 2.1.0

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