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; |
|