Demo Code for WS2812b LEDs created
This commit is contained in:
commit
5bdf863277
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
*.bak
|
||||
quartus
|
||||
|
10
.library_mapping.xml
Normal file
10
.library_mapping.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<com.sigasi.hdt.shared.librarymapping.model:LibraryMappings xmlns:com.sigasi.hdt.shared.librarymapping.model="com.sigasi.hdt.vhdl.scoping.librarymapping" Version="2">
|
||||
<Mappings Location="bench" Library="bench"/>
|
||||
<Mappings Location="src" Library="design"/>
|
||||
<Mappings Location="Common Libraries/IEEE" Library="ieee"/>
|
||||
<Mappings Location="Common Libraries" Library="not mapped"/>
|
||||
<Mappings Location="quartus" Library="not mapped"/>
|
||||
<Mappings Location="Common Libraries/STD" Library="std"/>
|
||||
<Mappings Location="" Library="work"/>
|
||||
</com.sigasi.hdt.shared.librarymapping.model:LibraryMappings>
|
45
.project
Normal file
45
.project
Normal file
@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>ws2812b</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.xtext.ui.shared.xtextBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>com.sigasi.hdt.vhdl.ui.vhdlNature</nature>
|
||||
<nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
|
||||
</natures>
|
||||
<linkedResources>
|
||||
<link>
|
||||
<name>Common Libraries</name>
|
||||
<type>2</type>
|
||||
<locationURI>virtual:/virtual</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Common Libraries/DRAG_REUSABLE_LIBRARIES_HERE.txt</name>
|
||||
<type>1</type>
|
||||
<locationURI>sigasiresource:/vhdl/readme2.txt</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Common Libraries/IEEE</name>
|
||||
<type>2</type>
|
||||
<locationURI>sigasiresource:/vhdl/93/IEEE</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Common Libraries/STD</name>
|
||||
<type>2</type>
|
||||
<locationURI>sigasiresource:/vhdl/93/STD</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Common Libraries/IEEE/Synopsys</name>
|
||||
<type>2</type>
|
||||
<locationURI>sigasiresource:/vhdl/93/IEEE%20Synopsys</locationURI>
|
||||
</link>
|
||||
</linkedResources>
|
||||
</projectDescription>
|
5
.settings/org.eclipse.core.resources.prefs
Normal file
5
.settings/org.eclipse.core.resources.prefs
Normal file
@ -0,0 +1,5 @@
|
||||
eclipse.preferences.version=1
|
||||
encoding//Common\ Libraries/IEEE=utf-8
|
||||
encoding//Common\ Libraries/IEEE/Synopsys=utf-8
|
||||
encoding//Common\ Libraries/STD=utf-8
|
||||
encoding/Common\ Libraries=utf-8
|
42
bench/ws2812test_bench.vhd
Normal file
42
bench/ws2812test_bench.vhd
Normal file
@ -0,0 +1,42 @@
|
||||
library ieee;
|
||||
library design;
|
||||
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
use design.all;
|
||||
|
||||
entity ws2812test_bench is
|
||||
end entity ws2812test_bench;
|
||||
|
||||
architecture RTL of ws2812test_bench is
|
||||
signal clk : std_logic;
|
||||
signal rst : std_logic;
|
||||
signal ws_out : std_logic;
|
||||
|
||||
begin
|
||||
clock_driver : process
|
||||
constant period : time := 20 ns;
|
||||
begin
|
||||
clk <= '0';
|
||||
wait for period / 2;
|
||||
clk <= '1';
|
||||
wait for period / 2;
|
||||
end process clock_driver;
|
||||
|
||||
resetprovider : process is
|
||||
begin
|
||||
rst <= '0';
|
||||
wait for 3 ns;
|
||||
rst <= '1';
|
||||
wait;
|
||||
end process resetprovider;
|
||||
|
||||
ws2812test_inst : entity design.ws2812test
|
||||
port map(
|
||||
clk => clk,
|
||||
reset => rst,
|
||||
ws_out => ws_out,
|
||||
gamma_req => '1'
|
||||
);
|
||||
|
||||
end architecture RTL;
|
35
src/gamma8bit.vhd
Normal file
35
src/gamma8bit.vhd
Normal file
@ -0,0 +1,35 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity gamma8bit is
|
||||
port(
|
||||
color_in : in unsigned(7 downto 0);
|
||||
color_out : out unsigned(7 downto 0)
|
||||
);
|
||||
end entity gamma8bit;
|
||||
|
||||
architecture RTL of gamma8bit is
|
||||
type gammatable_t is array (0 to 255) of integer range 0 to 255;
|
||||
signal table : gammatable_t;
|
||||
begin
|
||||
table <= (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5,
|
||||
5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10,
|
||||
10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16,
|
||||
17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25,
|
||||
25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36,
|
||||
37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50,
|
||||
51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68,
|
||||
69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89,
|
||||
90, 92, 93, 95, 96, 98, 99, 101, 102, 104, 105, 107, 109, 110, 112, 114,
|
||||
115, 117, 119, 120, 122, 124, 126, 127, 129, 131, 133, 135, 137, 138, 140, 142,
|
||||
144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 167, 169, 171, 173, 175,
|
||||
177, 180, 182, 184, 186, 189, 191, 193, 196, 198, 200, 203, 205, 208, 210, 213,
|
||||
215, 218, 220, 223, 225, 228, 231, 233, 236, 239, 241, 244, 247, 249, 252, 255);
|
||||
|
||||
color_out <= to_unsigned(table(to_integer(color_in)), color_out'length);
|
||||
|
||||
end architecture RTL;
|
123
src/ws2812b-phy/ws2812bphy.vhd
Normal file
123
src/ws2812b-phy/ws2812bphy.vhd
Normal file
@ -0,0 +1,123 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity ws2812bphy is
|
||||
generic(
|
||||
constant HIGH1 : integer := 40;
|
||||
constant LOW1 : integer := 23;
|
||||
constant HIGH0 : integer := 20;
|
||||
constant LOW0 : integer := 43
|
||||
);
|
||||
port(
|
||||
clk : in std_logic;
|
||||
rst : in std_logic;
|
||||
busy : out std_logic;
|
||||
ws_out : out std_logic;
|
||||
strb : in std_logic;
|
||||
red : in unsigned(7 downto 0);
|
||||
green : in unsigned(7 downto 0);
|
||||
blue : in unsigned(7 downto 0)
|
||||
);
|
||||
end entity ws2812bphy;
|
||||
|
||||
architecture RTL of ws2812bphy is
|
||||
|
||||
type ws_output_state_t is (IDLE, TRANSMITTING, INTERLEDDELAY);
|
||||
signal ws_output_state : ws_output_state_t;
|
||||
|
||||
type bitstate_t is (LOW, HIGH);
|
||||
signal bitstate : bitstate_t;
|
||||
|
||||
begin
|
||||
ws_output : process(clk, rst) is
|
||||
variable counter : integer range 0 to 255 := 0;
|
||||
|
||||
variable color_vector : std_logic_vector(23 downto 0);
|
||||
variable bitnum : integer range 0 to 23;
|
||||
begin
|
||||
if rst = '1' then
|
||||
ws_output_state <= IDLE;
|
||||
color_vector := (others => '0');
|
||||
counter := 0;
|
||||
bitstate <= LOW;
|
||||
bitnum := 0;
|
||||
elsif rising_edge(clk) then
|
||||
case ws_output_state is
|
||||
when IDLE =>
|
||||
bitstate <= LOW;
|
||||
if strb = '1' then
|
||||
ws_output_state <= TRANSMITTING;
|
||||
bitnum := 23;
|
||||
color_vector := std_logic_vector(green) & std_logic_vector(red) & std_logic_vector(blue);
|
||||
counter := 0;
|
||||
bitstate <= HIGH;
|
||||
end if;
|
||||
when TRANSMITTING =>
|
||||
case bitstate is
|
||||
when HIGH =>
|
||||
if color_vector(bitnum) = '1' then
|
||||
if counter < HIGH1 then
|
||||
counter := counter + 1;
|
||||
else
|
||||
bitstate <= LOW;
|
||||
counter := 0;
|
||||
end if;
|
||||
else
|
||||
if counter < HIGH0 then
|
||||
counter := counter + 1;
|
||||
else
|
||||
bitstate <= LOW;
|
||||
counter := 0;
|
||||
end if;
|
||||
end if;
|
||||
when LOW =>
|
||||
if color_vector(bitnum) = '1' then
|
||||
if counter < LOW1 then
|
||||
counter := counter + 1;
|
||||
else
|
||||
bitstate <= HIGH;
|
||||
counter := 0;
|
||||
if bitnum = 0 then
|
||||
ws_output_state <= INTERLEDDELAY;
|
||||
counter := 0;
|
||||
bitstate <= LOW;
|
||||
else
|
||||
bitnum := bitnum - 1;
|
||||
end if;
|
||||
end if;
|
||||
else
|
||||
if counter < LOW0 then
|
||||
counter := counter + 1;
|
||||
else
|
||||
bitstate <= HIGH;
|
||||
counter := 0;
|
||||
|
||||
if bitnum = 0 then
|
||||
ws_output_state <= INTERLEDDELAY;
|
||||
counter := 0;
|
||||
bitstate <= LOW;
|
||||
else
|
||||
bitnum := bitnum - 1;
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end if;
|
||||
|
||||
end case;
|
||||
|
||||
when INTERLEDDELAY =>
|
||||
if counter < HIGH1+LOW1+LOW1 then
|
||||
counter := counter + 1;
|
||||
else
|
||||
counter := 0;
|
||||
ws_output_state <= IDLE;
|
||||
end if;
|
||||
|
||||
end case;
|
||||
end if;
|
||||
end process ws_output;
|
||||
busy <= '0' when ws_output_state = IDLE else '1';
|
||||
ws_out <= '1' when bitstate = HIGH else '0';
|
||||
|
||||
end architecture RTL;
|
197
src/ws2812test.vhd
Normal file
197
src/ws2812test.vhd
Normal file
@ -0,0 +1,197 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity ws2812test is
|
||||
port(
|
||||
clk : in std_logic;
|
||||
reset : in std_logic;
|
||||
ws_out : out std_logic;
|
||||
gamma_req : in std_logic
|
||||
);
|
||||
end entity ws2812test;
|
||||
|
||||
architecture RTL of ws2812test is
|
||||
constant LEDCNT_c : integer := 60;
|
||||
constant HEARTBEATMAX_c : integer := 700000;
|
||||
signal rst : std_logic;
|
||||
signal ws_busy : std_logic;
|
||||
signal ws_strb : std_logic;
|
||||
signal red_gamma : unsigned(7 downto 0);
|
||||
signal green_gamma : unsigned(7 downto 0);
|
||||
signal blue_gamma : unsigned(7 downto 0);
|
||||
|
||||
-- Signals for renderer
|
||||
signal render_active : std_logic;
|
||||
type transition_t is (RY, YG, GC, CB, BM, MR);
|
||||
signal transition_active : transition_t;
|
||||
type color_rec_t is record
|
||||
red : unsigned(7 downto 0);
|
||||
green : unsigned(7 downto 0);
|
||||
blue : unsigned(7 downto 0);
|
||||
end record color_rec_t;
|
||||
signal color_active : color_rec_t;
|
||||
signal lednum : integer range 0 to LEDCNT_c - 1;
|
||||
-- Signals for rainbow
|
||||
signal heartbeat : std_logic;
|
||||
signal transition_start : transition_t;
|
||||
signal color_start : color_rec_t;
|
||||
signal red_ws : unsigned(7 downto 0);
|
||||
signal green_ws : unsigned(7 downto 0);
|
||||
signal blue_ws : unsigned(7 downto 0);
|
||||
begin
|
||||
rst <= not reset;
|
||||
|
||||
beatgen : process(clk, rst) is
|
||||
variable beat_counter : integer range 0 to HEARTBEATMAX_c := 0;
|
||||
begin
|
||||
if rst = '1' then
|
||||
beat_counter := 0;
|
||||
heartbeat <= '0';
|
||||
elsif rising_edge(clk) then
|
||||
heartbeat <= '0';
|
||||
if beat_counter /= HEARTBEATMAX_c then
|
||||
beat_counter := beat_counter + 1;
|
||||
else
|
||||
beat_counter := 0;
|
||||
heartbeat <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end process beatgen;
|
||||
|
||||
gamma_red : entity work.gamma8bit
|
||||
port map(
|
||||
color_in => color_active.red,
|
||||
color_out => red_gamma
|
||||
);
|
||||
gamma_green : entity work.gamma8bit
|
||||
port map(
|
||||
color_in => color_active.green,
|
||||
color_out => green_gamma
|
||||
);
|
||||
|
||||
gamma_blue : entity work.gamma8bit
|
||||
port map(
|
||||
color_in => color_active.blue,
|
||||
color_out => blue_gamma
|
||||
);
|
||||
|
||||
red_ws <= red_gamma when gamma_req = '1' else color_active.red;
|
||||
green_ws <= green_gamma when gamma_req = '1' else color_active.green;
|
||||
blue_ws <= blue_gamma when gamma_req = '1' else color_active.blue;
|
||||
|
||||
ws2812bphy_inst : entity work.ws2812bphy
|
||||
generic map(
|
||||
HIGH1 => 40,
|
||||
LOW1 => 23,
|
||||
HIGH0 => 20,
|
||||
LOW0 => 43
|
||||
)
|
||||
port map(
|
||||
clk => clk,
|
||||
rst => rst,
|
||||
busy => ws_busy,
|
||||
ws_out => ws_out,
|
||||
strb => ws_strb,
|
||||
red => red_ws,
|
||||
green => green_ws,
|
||||
blue => blue_ws
|
||||
);
|
||||
|
||||
rainbow : process(clk, rst) is
|
||||
procedure increment_col(signal color : inout unsigned(7 downto 0); is_renderer : boolean; next_state : transition_t) is
|
||||
begin
|
||||
color <= color + 20;
|
||||
if color = 220 then
|
||||
if is_renderer then
|
||||
transition_active <= next_state;
|
||||
else
|
||||
transition_start <= next_state;
|
||||
end if;
|
||||
end if;
|
||||
end procedure increment_col;
|
||||
|
||||
procedure decrement_col(signal color : inout unsigned(7 downto 0); is_renderer : boolean; next_state : transition_t) is
|
||||
begin
|
||||
color <= color - 20;
|
||||
if color = 20 then
|
||||
if is_renderer then
|
||||
transition_active <= next_state;
|
||||
else
|
||||
transition_start <= next_state;
|
||||
end if;
|
||||
end if;
|
||||
end procedure decrement_col;
|
||||
|
||||
begin
|
||||
if rst = '1' then
|
||||
render_active <= '1';
|
||||
color_active.red <= to_unsigned(240, color_start.red'length);
|
||||
color_active.green <= x"00";
|
||||
color_active.blue <= x"00";
|
||||
|
||||
color_start.red <= to_unsigned(240, color_start.red'length);
|
||||
color_start.green <= x"00";
|
||||
color_start.blue <= x"00";
|
||||
transition_active <= RY;
|
||||
transition_start <= RY;
|
||||
lednum <= 0;
|
||||
elsif rising_edge(clk) then
|
||||
-- renderer
|
||||
if render_active = '1' then
|
||||
ws_strb <= '0';
|
||||
if ws_busy = '0' and ws_strb = '0' then
|
||||
ws_strb <= '1';
|
||||
case transition_active is
|
||||
when RY =>
|
||||
increment_col(color_active.green, true, YG);
|
||||
|
||||
when YG =>
|
||||
decrement_col(color_active.red, true, GC);
|
||||
when GC =>
|
||||
increment_col(color_active.blue, true, CB);
|
||||
when CB =>
|
||||
decrement_col(color_active.green, true, BM);
|
||||
when BM =>
|
||||
increment_col(color_active.red, true, MR);
|
||||
when MR =>
|
||||
decrement_col(color_active.blue, true, RY);
|
||||
end case;
|
||||
|
||||
end if; -- phy ready
|
||||
if ws_strb = '1' then
|
||||
if lednum < (LEDCNT_c - 1) then
|
||||
lednum <= lednum + 1;
|
||||
else
|
||||
lednum <= 0;
|
||||
render_active <= '0';
|
||||
end if;
|
||||
end if;
|
||||
elsif heartbeat = '1' then
|
||||
case transition_start is
|
||||
when RY =>
|
||||
increment_col(color_start.green, false, YG);
|
||||
|
||||
when YG =>
|
||||
decrement_col(color_start.red, false, GC);
|
||||
when GC =>
|
||||
increment_col(color_start.blue, false, CB);
|
||||
when CB =>
|
||||
decrement_col(color_start.green, false, BM);
|
||||
when BM =>
|
||||
increment_col(color_start.red, false, MR);
|
||||
when MR =>
|
||||
decrement_col(color_start.blue, false, RY);
|
||||
end case;
|
||||
color_active <= color_start;
|
||||
transition_active <= transition_start;
|
||||
render_active <= '1';
|
||||
|
||||
end if; -- rainbow
|
||||
|
||||
|
||||
end if; -- rising edge
|
||||
|
||||
end process rainbow;
|
||||
|
||||
end architecture RTL;
|
Loading…
Reference in New Issue
Block a user