implemented first draft
This commit is contained in:
commit
660765e332
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
*.o
|
||||
*~
|
||||
|
187
bench.vhd
Normal file
187
bench.vhd
Normal file
@ -0,0 +1,187 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity bench is
|
||||
|
||||
end entity bench;
|
||||
|
||||
architecture sim of bench is
|
||||
signal clk : std_logic;
|
||||
signal rst_hw : std_logic;
|
||||
signal sck : std_logic;
|
||||
signal mosi : std_logic;
|
||||
signal cs : std_logic;
|
||||
signal ready : std_logic;
|
||||
signal ws_out : std_logic;
|
||||
begin -- architecture sim
|
||||
|
||||
top_1 : entity work.top
|
||||
port map (
|
||||
clk => clk,
|
||||
rst_hw => rst_hw,
|
||||
sck => sck,
|
||||
mosi => mosi,
|
||||
cs => cs,
|
||||
ready => ready,
|
||||
ws_out => ws_out);
|
||||
|
||||
clk_gen : process is
|
||||
begin
|
||||
clk <= '0';
|
||||
wait for 10 ns;
|
||||
clk <= '1';
|
||||
wait for 10 ns;
|
||||
end process clk_gen;
|
||||
|
||||
rst_gen : process is
|
||||
begin
|
||||
rst_hw <= '1';
|
||||
wait for 15 ns;
|
||||
rst_hw <= '0';
|
||||
wait;
|
||||
end process rst_gen;
|
||||
|
||||
sck_gen : process is
|
||||
begin
|
||||
sck <= '0';
|
||||
wait for 40 ns;
|
||||
sck <= '1';
|
||||
wait for 40 ns;
|
||||
end process sck_gen;
|
||||
|
||||
send_spi : process is
|
||||
procedure send24(dat : in std_logic_vector(23 downto 0)) is
|
||||
variable data : std_logic_vector(dat'range);
|
||||
begin
|
||||
cs <= '1';
|
||||
if ready /= '1' then
|
||||
wait until ready = '1';
|
||||
end if;
|
||||
wait for 30 ns;
|
||||
data := dat;
|
||||
wait until falling_edge(sck);
|
||||
cs <= '0';
|
||||
mosi <= data(23);
|
||||
data := data(22 downto 0) & '0';
|
||||
wait until falling_edge(sck);
|
||||
cs <= '0';
|
||||
mosi <= data(23);
|
||||
data := data(22 downto 0) & '0';
|
||||
wait until falling_edge(sck);
|
||||
cs <= '0';
|
||||
mosi <= data(23);
|
||||
data := data(22 downto 0) & '0';
|
||||
wait until falling_edge(sck);
|
||||
cs <= '0';
|
||||
mosi <= data(23);
|
||||
data := data(22 downto 0) & '0';
|
||||
wait until falling_edge(sck);
|
||||
cs <= '0';
|
||||
mosi <= data(23);
|
||||
data := data(22 downto 0) & '0';
|
||||
wait until falling_edge(sck);
|
||||
cs <= '0';
|
||||
mosi <= data(23);
|
||||
data := data(22 downto 0) & '0';
|
||||
wait until falling_edge(sck);
|
||||
cs <= '0';
|
||||
mosi <= data(23);
|
||||
data := data(22 downto 0) & '0';
|
||||
wait until falling_edge(sck);
|
||||
cs <= '0';
|
||||
mosi <= data(23);
|
||||
data := data(22 downto 0) & '0';
|
||||
wait until falling_edge(sck);
|
||||
cs <= '0';
|
||||
mosi <= data(23);
|
||||
data := data(22 downto 0) & '0';
|
||||
wait until falling_edge(sck);
|
||||
cs <= '0';
|
||||
mosi <= data(23);
|
||||
data := data(22 downto 0) & '0';
|
||||
wait until falling_edge(sck);
|
||||
cs <= '0';
|
||||
mosi <= data(23);
|
||||
data := data(22 downto 0) & '0';
|
||||
wait until falling_edge(sck);
|
||||
cs <= '0';
|
||||
mosi <= data(23);
|
||||
data := data(22 downto 0) & '0';
|
||||
wait until falling_edge(sck);
|
||||
cs <= '0';
|
||||
mosi <= data(23);
|
||||
data := data(22 downto 0) & '0';
|
||||
wait until falling_edge(sck);
|
||||
cs <= '0';
|
||||
mosi <= data(23);
|
||||
data := data(22 downto 0) & '0';
|
||||
wait until falling_edge(sck);
|
||||
cs <= '0';
|
||||
mosi <= data(23);
|
||||
data := data(22 downto 0) & '0';
|
||||
wait until falling_edge(sck);
|
||||
cs <= '0';
|
||||
mosi <= data(23);
|
||||
data := data(22 downto 0) & '0';
|
||||
wait until falling_edge(sck);
|
||||
cs <= '0';
|
||||
mosi <= data(23);
|
||||
data := data(22 downto 0) & '0';
|
||||
wait until falling_edge(sck);
|
||||
cs <= '0';
|
||||
mosi <= data(23);
|
||||
data := data(22 downto 0) & '0';
|
||||
wait until falling_edge(sck);
|
||||
cs <= '0';
|
||||
mosi <= data(23);
|
||||
data := data(22 downto 0) & '0';
|
||||
wait until falling_edge(sck);
|
||||
cs <= '0';
|
||||
mosi <= data(23);
|
||||
data := data(22 downto 0) & '0';
|
||||
wait until falling_edge(sck);
|
||||
cs <= '0';
|
||||
mosi <= data(23);
|
||||
data := data(22 downto 0) & '0';
|
||||
wait until falling_edge(sck);
|
||||
cs <= '0';
|
||||
mosi <= data(23);
|
||||
data := data(22 downto 0) & '0';
|
||||
wait until falling_edge(sck);
|
||||
cs <= '0';
|
||||
mosi <= data(23);
|
||||
data := data(22 downto 0) & '0';
|
||||
wait until falling_edge(sck);
|
||||
cs <= '0';
|
||||
mosi <= data(23);
|
||||
data := data(22 downto 0) & '0';
|
||||
wait until falling_edge(sck);
|
||||
cs <= '1';
|
||||
end send24;
|
||||
begin
|
||||
cs <= '1';
|
||||
wait for 50 ns;
|
||||
send24(x"FF0055");
|
||||
send24(x"CCFFAA");
|
||||
send24(x"FF0055");
|
||||
send24(x"CCFFAA");
|
||||
send24(x"FF0055");
|
||||
send24(x"CCFFAA");
|
||||
send24(x"FF0055");
|
||||
send24(x"CCFFAA");
|
||||
send24(x"FF0055");
|
||||
send24(x"CCFFAA");
|
||||
send24(x"FF0055");
|
||||
send24(x"CCFFAA");
|
||||
send24(x"FF0055");
|
||||
send24(x"CCFFAA");
|
||||
send24(x"FF0055");
|
||||
send24(x"CCFFAA");
|
||||
send24(x"FF0055");
|
||||
send24(x"CCFFAA");
|
||||
send24(x"FF0055");
|
||||
send24(x"CCFFAA");
|
||||
wait;
|
||||
end process send_spi;
|
||||
end architecture sim;
|
96
fifo.vhd
Normal file
96
fifo.vhd
Normal file
@ -0,0 +1,96 @@
|
||||
-- Thanks to: http://www.deathbylogic.com/2013/07/vhdl-standard-fifo/
|
||||
library IEEE;
|
||||
USE IEEE.STD_LOGIC_1164.ALL;
|
||||
USE IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
entity STD_FIFO is
|
||||
Generic (
|
||||
DATA_WIDTH : positive := 8;
|
||||
FIFO_DEPTH : positive := 256
|
||||
);
|
||||
Port (
|
||||
CLK : in STD_LOGIC;
|
||||
RST : in STD_LOGIC;
|
||||
WriteEn : in STD_LOGIC;
|
||||
DataIn : in STD_LOGIC_VECTOR (DATA_WIDTH - 1 downto 0);
|
||||
ReadEn : in STD_LOGIC;
|
||||
DataOut : out STD_LOGIC_VECTOR (DATA_WIDTH - 1 downto 0);
|
||||
Empty : out STD_LOGIC;
|
||||
Full : out STD_LOGIC
|
||||
);
|
||||
end STD_FIFO;
|
||||
|
||||
architecture Behavioral of STD_FIFO is
|
||||
|
||||
begin
|
||||
|
||||
-- Memory Pointer Process
|
||||
fifo_proc : process (CLK)
|
||||
type FIFO_Memory is array (0 to FIFO_DEPTH - 1) of STD_LOGIC_VECTOR (DATA_WIDTH - 1 downto 0);
|
||||
variable Memory : FIFO_Memory;
|
||||
|
||||
variable Head : natural range 0 to FIFO_DEPTH - 1;
|
||||
variable Tail : natural range 0 to FIFO_DEPTH - 1;
|
||||
|
||||
variable Looped : boolean;
|
||||
begin
|
||||
if rising_edge(CLK) then
|
||||
if RST = '1' then
|
||||
Head := 0;
|
||||
Tail := 0;
|
||||
|
||||
Looped := false;
|
||||
|
||||
Full <= '0';
|
||||
Empty <= '1';
|
||||
else
|
||||
if (ReadEn = '1') then
|
||||
if ((Looped = true) or (Head /= Tail)) then
|
||||
-- Update data output
|
||||
DataOut <= Memory(Tail);
|
||||
|
||||
-- Update Tail pointer as needed
|
||||
if (Tail = FIFO_DEPTH - 1) then
|
||||
Tail := 0;
|
||||
|
||||
Looped := false;
|
||||
else
|
||||
Tail := Tail + 1;
|
||||
end if;
|
||||
|
||||
|
||||
end if;
|
||||
end if;
|
||||
|
||||
if (WriteEn = '1') then
|
||||
if ((Looped = false) or (Head /= Tail)) then
|
||||
-- Write Data to Memory
|
||||
Memory(Head) := DataIn;
|
||||
|
||||
-- Increment Head pointer as needed
|
||||
if (Head = FIFO_DEPTH - 1) then
|
||||
Head := 0;
|
||||
|
||||
Looped := true;
|
||||
else
|
||||
Head := Head + 1;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
-- Update Empty and Full flags
|
||||
if (Head = Tail) then
|
||||
if Looped then
|
||||
Full <= '1';
|
||||
else
|
||||
Empty <= '1';
|
||||
end if;
|
||||
else
|
||||
Empty <= '0';
|
||||
Full <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end Behavioral;
|
113
spi_slave.vhd
Normal file
113
spi_slave.vhd
Normal file
@ -0,0 +1,113 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- Title : simple SPI slave
|
||||
-- Project :
|
||||
-------------------------------------------------------------------------------
|
||||
-- File : spi_slave.vhd
|
||||
-- Author : Mario Hüttel <mario.huettel@gmx.net>
|
||||
-- Company :
|
||||
-- Created : 2018-04-15
|
||||
-- Last update: 2018-04-15
|
||||
-- Platform :
|
||||
-- Standard : VHDL'93/02
|
||||
-------------------------------------------------------------------------------
|
||||
-- Description: This SPI slaves samples the SPI's sck line
|
||||
-- Therefore freq(clk) > 2.5 * freq(sck)
|
||||
-------------------------------------------------------------------------------
|
||||
-- Copyright (c) 2018
|
||||
-------------------------------------------------------------------------------
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity spi_slave is
|
||||
generic (
|
||||
DAT_WIDTH : natural := 8);
|
||||
port (
|
||||
clk : in std_logic;
|
||||
rst : in std_logic;
|
||||
cs : in std_logic;
|
||||
sck : in std_logic;
|
||||
miso : out std_logic;
|
||||
mosi : in std_logic;
|
||||
dat_o : out std_logic_vector(DAT_WIDTH - 1 downto 0);
|
||||
dat_i : in std_logic_vector(DAT_WIDTH - 1 downto 0);
|
||||
dat_o_strb : out std_logic;
|
||||
dat_i_ack : out std_logic);
|
||||
|
||||
end entity spi_slave;
|
||||
|
||||
|
||||
architecture RTL of spi_slave is
|
||||
signal sck_old : std_logic;
|
||||
signal sck_sync : std_logic;
|
||||
signal mosi_sync : std_logic;
|
||||
signal cs_sync : std_logic;
|
||||
signal pos_edge : std_logic;
|
||||
signal neg_edge : std_logic;
|
||||
signal miso_int : std_logic;
|
||||
signal cnt : integer range 0 to DAT_WIDTH-1;
|
||||
signal shift_reg : std_logic_vector(DAT_WIDTH -1 downto 0);
|
||||
begin -- architecture RTL
|
||||
|
||||
sync : process (clk, rst) is
|
||||
begin -- process sck_sync
|
||||
if rst = '1' then -- asynchronous reset (active high)
|
||||
sck_sync <= '0';
|
||||
mosi_sync <= '0';
|
||||
cs_sync <= '0';
|
||||
elsif rising_edge(clk) then -- rising clock edge
|
||||
cs_sync <= cs;
|
||||
mosi_sync <= mosi;
|
||||
sck_sync <= sck;
|
||||
end if;
|
||||
end process sync;
|
||||
|
||||
edge_detector : process (clk, rst) is
|
||||
begin -- process edge_detector
|
||||
if rst = '1' then -- asynchronous reset (active high)
|
||||
pos_edge <= '0';
|
||||
neg_edge <= '0';
|
||||
elsif rising_edge(clk) then -- rising clock edge
|
||||
neg_edge <= '0';
|
||||
pos_edge <= '0';
|
||||
sck_old <= sck_sync;
|
||||
if sck_old = '1' and sck_sync = '0' then
|
||||
neg_edge <= '1';
|
||||
elsif sck_old = '0' and sck_sync = '1' then
|
||||
pos_edge <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end process edge_detector;
|
||||
|
||||
shifter : process (clk, rst) is
|
||||
begin -- process shifter
|
||||
if rst = '1' then -- asynchronous reset (active high)
|
||||
shift_reg <= (others => '0');
|
||||
dat_i_ack <= '0';
|
||||
dat_o <= (others => '0');
|
||||
miso_int <= '0';
|
||||
cnt <= 0;
|
||||
elsif rising_edge(clk) then -- rising clock edge
|
||||
dat_i_ack <= '0';
|
||||
dat_o_strb <= '0';
|
||||
if pos_edge = '1' and cs_sync = '0' then
|
||||
shift_reg <= shift_reg(DAT_WIDTH-2 downto 0) & mosi_sync;
|
||||
miso_int <= shift_reg(7);
|
||||
if cnt < DAT_WIDTH-1 then
|
||||
cnt <= cnt + 1;
|
||||
else
|
||||
cnt <= 0;
|
||||
end if;
|
||||
if cnt = DAT_WIDTH - 1 then
|
||||
dat_o <= shift_reg(DAT_WIDTH -2 downto 0) & mosi_sync;
|
||||
dat_o_strb <= '1';
|
||||
shift_reg <= dat_i;
|
||||
dat_i_ack <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process shifter;
|
||||
|
||||
miso <= miso_int when cs = '0' else 'Z';
|
||||
|
||||
end architecture RTL;
|
184
top.vhd
Normal file
184
top.vhd
Normal file
@ -0,0 +1,184 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- Title : Top Level of SPI => WS2812b
|
||||
-- Project :
|
||||
-------------------------------------------------------------------------------
|
||||
-- File : top.vhd
|
||||
-- Author : Mario Hüttel <mario.huettel@gmx.net>
|
||||
-- Company :
|
||||
-- Created : 2018-04-15
|
||||
-- Last update: 2018-04-15
|
||||
-- Platform :
|
||||
-- Standard : VHDL'93/02
|
||||
-------------------------------------------------------------------------------
|
||||
-- Description:
|
||||
-------------------------------------------------------------------------------
|
||||
-- Copyright (c) 2018 GPLv2
|
||||
-------------------------------------------------------------------------------
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity top is
|
||||
|
||||
port (
|
||||
clk : in std_logic;
|
||||
rst_hw : in std_logic;
|
||||
sck : in std_logic;
|
||||
mosi : in std_logic;
|
||||
cs : in std_logic;
|
||||
ready : out std_logic; -- goes high when at least 10 LEDs can
|
||||
-- be accepted
|
||||
ws_out : out std_logic);
|
||||
|
||||
end entity top;
|
||||
|
||||
architecture RTL of top is
|
||||
constant FIFO_DEPTH : positive := 20;
|
||||
|
||||
signal rst : std_logic;
|
||||
signal fifo_empty : std_logic;
|
||||
signal fifo_full : std_logic;
|
||||
signal fifo_wr : std_logic;
|
||||
signal fifo_rd : std_logic;
|
||||
signal fifo_i : std_logic_vector(23 downto 0);
|
||||
signal fifo_o : std_logic_vector(23 downto 0);
|
||||
signal spi_dat_o : std_logic_vector(23 downto 0);
|
||||
signal spi_dat_o_strb : std_logic;
|
||||
signal fifo_fill_cnt : integer range 0 to FIFO_DEPTH;
|
||||
signal ws_strb : std_logic;
|
||||
signal red : unsigned(7 downto 0);
|
||||
signal green : unsigned(7 downto 0);
|
||||
signal blue : unsigned(7 downto 0);
|
||||
signal ws_busy : std_logic;
|
||||
signal fifo_inc : std_logic;
|
||||
signal fifo_dec : std_logic;
|
||||
signal fifo_data_req : std_logic;
|
||||
signal fifo_data_avail : std_logic;
|
||||
begin -- architecture RTL
|
||||
|
||||
reset_sync : process (clk, rst_hw) is
|
||||
begin -- process reset_sync
|
||||
if rst_hw = '1' then -- asynchronous reset (active high)
|
||||
rst <= '1';
|
||||
elsif rising_edge(clk) then -- rising clock edge
|
||||
rst <= rst_hw;
|
||||
end if;
|
||||
end process reset_sync;
|
||||
|
||||
STD_FIFO_1 : entity work.STD_FIFO
|
||||
generic map (
|
||||
DATA_WIDTH => 24,
|
||||
FIFO_DEPTH => FIFO_DEPTH) -- 20 LEDs FIFO depth
|
||||
port map (
|
||||
CLK => clk,
|
||||
RST => rst,
|
||||
WriteEn => fifo_wr,
|
||||
DataIn => fifo_i,
|
||||
ReadEn => fifo_rd,
|
||||
DataOut => fifo_o,
|
||||
Empty => fifo_empty,
|
||||
Full => fifo_full);
|
||||
|
||||
spi_slave_1 : entity work.spi_slave
|
||||
generic map (
|
||||
DAT_WIDTH => 24)
|
||||
port map (
|
||||
clk => clk,
|
||||
rst => rst,
|
||||
cs => cs,
|
||||
sck => sck,
|
||||
miso => open,
|
||||
mosi => mosi,
|
||||
dat_o => spi_dat_o,
|
||||
dat_i => (others => '0'),
|
||||
dat_o_strb => spi_dat_o_strb,
|
||||
dat_i_ack => open);
|
||||
|
||||
ws2812bphy_1 : 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,
|
||||
green => green,
|
||||
blue => blue);
|
||||
|
||||
fill_cnt_proc : process (clk, rst) is
|
||||
variable inc_dec : std_logic_vector(1 downto 0);
|
||||
begin -- process fill_cnt_proc
|
||||
if rst = '1' then -- asynchronous reset (active high)
|
||||
fifo_fill_cnt <= 0;
|
||||
elsif rising_edge(clk) then -- rising clock edge
|
||||
inc_dec := fifo_inc & fifo_dec;
|
||||
if inc_dec = "10" then
|
||||
fifo_fill_cnt <= fifo_fill_cnt + 1;
|
||||
elsif inc_dec = "01" then
|
||||
fifo_fill_cnt <= fifo_fill_cnt -1;
|
||||
end if;
|
||||
end if;
|
||||
end process fill_cnt_proc;
|
||||
|
||||
ready <= '1' when fifo_fill_cnt <= 10 else '0';
|
||||
|
||||
spi2fifo_proc : process (clk, rst) is
|
||||
begin -- process spi2fifo_proc
|
||||
if rst = '1' then -- asynchronous reset (active high)
|
||||
fifo_inc <= '0';
|
||||
fifo_wr <= '0';
|
||||
fifo_i <= (others => '0');
|
||||
elsif rising_edge(clk) then -- rising clock edge
|
||||
fifo_wr <= '0';
|
||||
fifo_inc <= '0';
|
||||
if spi_dat_o_strb = '1' and fifo_full /= '1' then
|
||||
fifo_wr <= '1';
|
||||
fifo_i <= spi_dat_o;
|
||||
fifo_inc <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end process spi2fifo_proc;
|
||||
|
||||
fifo2ws_proc : process (clk, rst) is
|
||||
begin -- process fifo2ws_proc
|
||||
if rst = '1' then -- asynchronous reset (active high)
|
||||
fifo_rd <= '0';
|
||||
fifo_dec <= '0';
|
||||
ws_strb <= '0';
|
||||
red <= x"00";
|
||||
blue <= x"00";
|
||||
green <= x"00";
|
||||
fifo_data_req <= '0';
|
||||
fifo_data_avail <= '0';
|
||||
elsif rising_edge(clk) then -- rising clock edge
|
||||
fifo_rd <= '0';
|
||||
ws_strb <= '0';
|
||||
fifo_dec <= '0';
|
||||
-- TODO: Write following lines as statemachine
|
||||
if fifo_empty = '0' and fifo_data_req = '0' and fifo_data_avail = '0' then
|
||||
fifo_data_req <= '1';
|
||||
fifo_rd <= '1';
|
||||
fifo_dec <= '1';
|
||||
end if;
|
||||
if fifo_data_req = '1' then
|
||||
fifo_data_avail <= '1';
|
||||
fifo_data_req <= '0';
|
||||
end if;
|
||||
if ws_busy = '0' and ws_strb = '0' and fifo_data_avail = '1' then
|
||||
red <= unsigned(fifo_o(23 downto 16));
|
||||
green <= unsigned(fifo_o(15 downto 8));
|
||||
blue <= unsigned(fifo_o(7 downto 0));
|
||||
ws_strb <= '1';
|
||||
fifo_data_avail <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process fifo2ws_proc;
|
||||
|
||||
end architecture RTL;
|
||||
|
||||
|
121
ws2812/ws2812bphy.vhd
Normal file
121
ws2812/ws2812bphy.vhd
Normal file
@ -0,0 +1,121 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity ws2812bphy is
|
||||
generic(
|
||||
HIGH1 : integer := 40;
|
||||
LOW1 : integer := 23;
|
||||
HIGH0 : integer := 20;
|
||||
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 - 1 then
|
||||
counter := counter + 1;
|
||||
else
|
||||
bitstate <= LOW;
|
||||
counter := 0;
|
||||
end if;
|
||||
else
|
||||
if counter < HIGH0 -1 then
|
||||
counter := counter + 1;
|
||||
else
|
||||
bitstate <= LOW;
|
||||
counter := 0;
|
||||
end if;
|
||||
end if;
|
||||
when LOW =>
|
||||
if color_vector(bitnum) = '1' then
|
||||
if counter < LOW1 -1 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 - 1 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;
|
Loading…
Reference in New Issue
Block a user