mirror of
https://github.com/cclassic/ws2812b-vhdl
synced 2024-12-22 12:15:04 +01:00
Added rainbow example
This commit is contained in:
parent
e21415b367
commit
f7444c25d5
197
design/demo_rainbow.vhd
Normal file
197
design/demo_rainbow.vhd
Normal file
@ -0,0 +1,197 @@
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- WS2812B CONTROLLER FOR FPGAS
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- top.vhd : Demo code to demonstrate the WS2812B Controller module.
|
||||
-- : This uses only the PHY to create a rotating rainbow effect.
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- Author : Markus Koch <markus@notsyncing.net>
|
||||
-- Contributors : None
|
||||
-- Created on : 2016/10/16
|
||||
-- License : Mozilla Public License (MPL) Version 2
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
use ieee.math_real.all;
|
||||
|
||||
entity demo_rainbow is
|
||||
port(
|
||||
clk : in std_logic;
|
||||
rst_hw : in std_logic;
|
||||
btn_n : in std_logic;
|
||||
so : out std_logic
|
||||
);
|
||||
end entity demo_rainbow;
|
||||
|
||||
architecture RTL of demo_rainbow is
|
||||
constant F_CLK : integer := 50000000;
|
||||
constant F_SYSTICK : integer := 100
|
||||
-- pragma translate_off
|
||||
-- pragma synthesis_off
|
||||
* 10
|
||||
--pragma translate_on
|
||||
-- pragma synthesis_on
|
||||
;
|
||||
constant LENGTH : integer := 120
|
||||
-- pragma translate_off
|
||||
-- pragma synthesis_off
|
||||
/ 10
|
||||
--pragma translate_on
|
||||
-- pragma synthesis_on
|
||||
;
|
||||
constant INCREMENT : integer := 10;
|
||||
constant PIXDATA_MAX : integer := 250; -- Must be a multiple of INCREMENT
|
||||
|
||||
signal rst : std_logic;
|
||||
|
||||
signal pixData_red : unsigned(7 downto 0);
|
||||
signal pixData_green : unsigned(7 downto 0);
|
||||
signal pixData_blue : unsigned(7 downto 0);
|
||||
signal pixData_red_start : unsigned(7 downto 0);
|
||||
signal pixData_green_start : unsigned(7 downto 0);
|
||||
signal pixData_blue_start : unsigned(7 downto 0);
|
||||
signal pixData_valid : std_logic;
|
||||
signal pixData_next : std_logic;
|
||||
|
||||
type color_transition_t is (RY, YG, GC, CB, BP, PR);
|
||||
signal color_transition_live : color_transition_t;
|
||||
signal color_transition_start : color_transition_t;
|
||||
signal pixCount : integer range 0 to LENGTH - 1;
|
||||
signal render_active : std_logic;
|
||||
signal render_stb : std_logic;
|
||||
|
||||
signal systick : std_logic;
|
||||
begin
|
||||
rst <= not rst_hw;
|
||||
|
||||
ws2812b_phy_inst : entity work.ws2812b_phy
|
||||
generic map(
|
||||
f_clk => F_CLK
|
||||
)
|
||||
port map(
|
||||
clk => clk,
|
||||
rst => rst,
|
||||
so => so,
|
||||
pixData_red => std_logic_vector(pixData_red),
|
||||
pixData_green => std_logic_vector(pixData_green),
|
||||
pixData_blue => std_logic_vector(pixData_blue),
|
||||
pixData_valid => pixData_valid,
|
||||
pixData_next => pixData_next
|
||||
);
|
||||
|
||||
systick_p : process(clk, rst) is
|
||||
constant cmax : integer := (F_CLK / F_SYSTICK);
|
||||
variable cnt : integer range 0 to cmax;
|
||||
begin
|
||||
if rst = '1' then
|
||||
cnt := 0;
|
||||
systick <= '0';
|
||||
elsif rising_edge(clk) then
|
||||
systick <= '0';
|
||||
if cnt = cmax then
|
||||
cnt := 0;
|
||||
systick <= '1';
|
||||
else
|
||||
cnt := cnt + 1;
|
||||
end if;
|
||||
end if;
|
||||
end process systick_p;
|
||||
|
||||
rainbow_p : process(clk, rst) is
|
||||
procedure incr(signal col : inout unsigned(7 downto 0); next_transition : in color_transition_t; is_live : boolean) is
|
||||
begin
|
||||
col <= col + INCREMENT;
|
||||
if col = PIXDATA_MAX - INCREMENT then
|
||||
if is_live then
|
||||
color_transition_live <= next_transition;
|
||||
else
|
||||
color_transition_start <= next_transition;
|
||||
end if;
|
||||
end if;
|
||||
end procedure;
|
||||
|
||||
procedure decr(signal col : inout unsigned(7 downto 0); next_transition : in color_transition_t; is_live : boolean) is
|
||||
begin
|
||||
col <= col - INCREMENT;
|
||||
if col = INCREMENT then
|
||||
if is_live then
|
||||
color_transition_live <= next_transition;
|
||||
else
|
||||
color_transition_start <= next_transition;
|
||||
end if;
|
||||
end if;
|
||||
end procedure;
|
||||
begin
|
||||
if rst = '1' then
|
||||
pixData_red <= to_unsigned(PIXDATA_MAX, pixData_red'length);
|
||||
pixData_green <= (others => '0');
|
||||
pixData_blue <= (others => '0');
|
||||
pixData_red_start <= to_unsigned(PIXDATA_MAX, pixData_red'length);
|
||||
pixData_green_start <= (others => '0');
|
||||
pixData_blue_start <= (others => '0');
|
||||
--pixData_valid <= '0';
|
||||
color_transition_live <= RY;
|
||||
pixCount <= 0;
|
||||
render_active <= '0';
|
||||
elsif rising_edge(clk) then
|
||||
-- Render one strip
|
||||
if render_active = '1' then
|
||||
if pixData_next = '1' then
|
||||
--pixData_valid <= '1';
|
||||
if pixCount = LENGTH - 1 then
|
||||
pixCount <= 0;
|
||||
--pixData_valid <= '0'; -- Insert inter-strip delay
|
||||
render_active <= '0';
|
||||
else
|
||||
pixCount <= pixCount + 1;
|
||||
-- Rotate colors
|
||||
case color_transition_live is
|
||||
when RY =>
|
||||
incr(pixData_green, YG, true);
|
||||
when YG =>
|
||||
decr(pixData_red, GC, true);
|
||||
when GC =>
|
||||
incr(pixData_blue, CB, true);
|
||||
when CB =>
|
||||
decr(pixData_green, BP, true);
|
||||
when BP =>
|
||||
incr(pixData_red, PR, true);
|
||||
when PR =>
|
||||
decr(pixData_blue, RY, true);
|
||||
end case;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
-- Advance image on trigger
|
||||
if systick = '1' then
|
||||
report "rainbow: render strobe" severity note;
|
||||
|
||||
case color_transition_start is
|
||||
when RY =>
|
||||
incr(pixData_green_start, YG, false);
|
||||
when YG =>
|
||||
decr(pixData_red_start, GC, false);
|
||||
when GC =>
|
||||
incr(pixData_blue_start, CB, false);
|
||||
when CB =>
|
||||
decr(pixData_green_start, BP, false);
|
||||
when BP =>
|
||||
incr(pixData_red_start, PR, false);
|
||||
when PR =>
|
||||
decr(pixData_blue_start, RY, false);
|
||||
end case;
|
||||
|
||||
render_active <= '1';
|
||||
if render_active = '0' then
|
||||
pixData_red <= pixData_red_start;
|
||||
pixData_green <= pixData_green_start;
|
||||
pixData_blue <= pixData_blue_start;
|
||||
color_transition_live <= color_transition_start;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process rainbow_p;
|
||||
pixData_valid <= render_active;
|
||||
end architecture RTL;
|
Loading…
Reference in New Issue
Block a user