--! --! @file pwm_16chan_gen.vhd --! @brief 16-channel PWM, generic bit-width --! --! @par License: --! Creative Commons Attribution-ShareAlike --! http://creativecommons.org/licenses/by-sa/3.0/ --! --! @par Authors: --! Sylvain MIERMONT --! --! @par Id: $Id$ --! library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; entity pwm_16chan_gen is generic ( BIT_WIDTH : positive := 6 ); port ( reset_n : in std_logic; clk : in std_logic; value_0 : in std_logic_vector ((BIT_WIDTH-1) downto 0); value_1 : in std_logic_vector ((BIT_WIDTH-1) downto 0); value_2 : in std_logic_vector ((BIT_WIDTH-1) downto 0); value_3 : in std_logic_vector ((BIT_WIDTH-1) downto 0); value_4 : in std_logic_vector ((BIT_WIDTH-1) downto 0); value_5 : in std_logic_vector ((BIT_WIDTH-1) downto 0); value_6 : in std_logic_vector ((BIT_WIDTH-1) downto 0); value_7 : in std_logic_vector ((BIT_WIDTH-1) downto 0); value_8 : in std_logic_vector ((BIT_WIDTH-1) downto 0); value_9 : in std_logic_vector ((BIT_WIDTH-1) downto 0); value_A : in std_logic_vector ((BIT_WIDTH-1) downto 0); value_B : in std_logic_vector ((BIT_WIDTH-1) downto 0); value_C : in std_logic_vector ((BIT_WIDTH-1) downto 0); value_D : in std_logic_vector ((BIT_WIDTH-1) downto 0); value_E : in std_logic_vector ((BIT_WIDTH-1) downto 0); value_F : in std_logic_vector ((BIT_WIDTH-1) downto 0); pwm_out : out std_logic_vector (15 downto 0) ); end entity pwm_16chan_gen; architecture RTL of pwm_16chan_gen is subtype longunsigned is unsigned ((BIT_WIDTH-1) downto 0); type longunsigned_vector is array (natural range <>) of longunsigned; signal value_in : longunsigned_vector(0 to 15); signal value_r : longunsigned_vector(0 to 15); signal cpt_r : longunsigned_vector(0 to 15); begin value_in(0) <= unsigned(value_0); value_in(1) <= unsigned(value_1); value_in(2) <= unsigned(value_2); value_in(3) <= unsigned(value_3); value_in(4) <= unsigned(value_4); value_in(5) <= unsigned(value_5); value_in(6) <= unsigned(value_6); value_in(7) <= unsigned(value_7); value_in(8) <= unsigned(value_8); value_in(9) <= unsigned(value_9); value_in(10) <= unsigned(value_A); value_in(11) <= unsigned(value_B); value_in(12) <= unsigned(value_C); value_in(13) <= unsigned(value_D); value_in(14) <= unsigned(value_E); value_in(15) <= unsigned(value_F); -- staggered counters staggered_counters: process(clk, reset_n) variable cpt_common : unsigned((BIT_WIDTH-5) downto 0); begin if reset_n = '0' then for i in 0 to 15 loop cpt_r(i)((BIT_WIDTH-1) downto (BIT_WIDTH-4)) <= to_unsigned(i, 4); cpt_r(i)((BIT_WIDTH-5) downto 0) <= to_unsigned(0, (BIT_WIDTH-4)); end loop; elsif rising_edge(clk) then cpt_common := cpt_r(0)((BIT_WIDTH-5) downto 0); for i in 0 to 15 loop cpt_r(i)((BIT_WIDTH-5) downto 0) <= cpt_common + 1; end loop; if cpt_common = ((BIT_WIDTH-5) downto 0 => '1') then for i in 0 to 14 loop cpt_r(i)((BIT_WIDTH-1) downto (BIT_WIDTH-4)) <= cpt_r(i+1)((BIT_WIDTH-1) downto (BIT_WIDTH-4)); end loop; cpt_r(15)((BIT_WIDTH-1) downto (BIT_WIDTH-4)) <= cpt_r(0)((BIT_WIDTH-1) downto (BIT_WIDTH-4)); end if; end if; end process staggered_counters; -- registers to hold the value reg_value: process(clk, reset_n) begin if reset_n = '0' then value_r <= (0 to 15 => (others => '0')); elsif rising_edge(clk) then for i in 0 to 15 loop if cpt_r(i) = ((BIT_WIDTH-1) downto 0 => '1') then value_r(i) <= value_in(i); end if; end loop; end if; end process reg_value; pwm_logic: process(clk, reset_n) begin if reset_n = '0' then pwm_out <= (others => '0'); elsif rising_edge(clk) then for i in 0 to 15 loop if value_r(i) = cpt_r(i) then pwm_out(i) <= '0'; elsif cpt_r(i) = to_unsigned(0, (BIT_WIDTH-1)) then pwm_out(i) <= '1'; end if; end loop; end if; end process pwm_logic; end architecture RTL;