Initial commit
This commit is contained in:
commit
c94765003f
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[submodule "ws2812b-vhdl"]
|
||||||
|
path = ws2812b-vhdl
|
||||||
|
url = git@github.com:cclassic/ws2812b-vhdl.git
|
9
.library_mapping.xml
Normal file
9
.library_mapping.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?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="design" Library="design"/>
|
||||||
|
<Mappings Location="Common Libraries/IEEE" Library="ieee"/>
|
||||||
|
<Mappings Location="" Library="not mapped"/>
|
||||||
|
<Mappings Location="Common Libraries/STD" Library="std"/>
|
||||||
|
<Mappings Location="ws2812b-vhdl/ws2812b" Library="ws2812b"/>
|
||||||
|
</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>ws2812-wall</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>
|
1
.settings/com.sigasi.hdt.vhdl.version.prefs
Normal file
1
.settings/com.sigasi.hdt.vhdl.version.prefs
Normal file
@ -0,0 +1 @@
|
|||||||
|
<project>=93
|
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
|
105
bench/bench_top.vhd
Normal file
105
bench/bench_top.vhd
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
|
||||||
|
library design;
|
||||||
|
use design.all;
|
||||||
|
|
||||||
|
entity bench_top is
|
||||||
|
end entity bench_top;
|
||||||
|
|
||||||
|
architecture RTL of bench_top is
|
||||||
|
constant SIM_SPEEDUP : natural := 2;
|
||||||
|
|
||||||
|
signal clk_hw : std_logic;
|
||||||
|
signal rst_hw : std_logic;
|
||||||
|
signal ws2812_out : std_logic_vector(4 - 1 downto 0);
|
||||||
|
signal uart_tx : std_logic;
|
||||||
|
|
||||||
|
begin
|
||||||
|
top_inst : entity design.top
|
||||||
|
generic map(
|
||||||
|
f_clk => 24_000_000 / SIM_SPEEDUP,
|
||||||
|
ROWS => 4,
|
||||||
|
COLUMNS => 4
|
||||||
|
)
|
||||||
|
port map(
|
||||||
|
clk_hw => clk_hw,
|
||||||
|
rst_hw => rst_hw,
|
||||||
|
ws2812_out => ws2812_out,
|
||||||
|
uart_rx => uart_tx
|
||||||
|
);
|
||||||
|
|
||||||
|
clock_driver : process
|
||||||
|
constant period : time := (1 sec / 24_000_000);
|
||||||
|
begin
|
||||||
|
clk_hw <= '0';
|
||||||
|
wait for period / 2;
|
||||||
|
clk_hw <= '1';
|
||||||
|
wait for period / 2;
|
||||||
|
end process clock_driver;
|
||||||
|
|
||||||
|
test : process is
|
||||||
|
constant UART_BITTIME : time := 1 sec / 115200 / SIM_SPEEDUP;
|
||||||
|
procedure uart_transmit(data : in std_logic_vector(7 downto 0)) is
|
||||||
|
begin
|
||||||
|
uart_tx <= '0';
|
||||||
|
wait for UART_BITTIME;
|
||||||
|
for i in 0 to 7 loop
|
||||||
|
uart_tx <= data(i);
|
||||||
|
wait for UART_BITTIME;
|
||||||
|
end loop;
|
||||||
|
uart_tx <= '1';
|
||||||
|
wait for UART_BITTIME;
|
||||||
|
end procedure uart_transmit;
|
||||||
|
|
||||||
|
begin
|
||||||
|
rst_hw <= '0';
|
||||||
|
uart_tx <= '1';
|
||||||
|
wait until clk_hw = '1';
|
||||||
|
wait until clk_hw = '1';
|
||||||
|
rst_hw <= '1';
|
||||||
|
wait until clk_hw = '1';
|
||||||
|
wait for UART_BITTIME * 13;
|
||||||
|
wait until clk_hw = '1';
|
||||||
|
|
||||||
|
-- Write LED data (cmd 0x00)
|
||||||
|
uart_transmit(x"00");
|
||||||
|
|
||||||
|
uart_transmit(x"00"); -- Start address 0
|
||||||
|
uart_transmit(x"00");
|
||||||
|
|
||||||
|
uart_transmit(x"00"); -- Write two LEDs
|
||||||
|
uart_transmit(x"02");
|
||||||
|
|
||||||
|
uart_transmit(x"01"); -- First LED
|
||||||
|
uart_transmit(x"02");
|
||||||
|
uart_transmit(x"03");
|
||||||
|
uart_transmit(x"11");
|
||||||
|
uart_transmit(x"12");
|
||||||
|
uart_transmit(x"13");
|
||||||
|
uart_transmit(x"21");
|
||||||
|
uart_transmit(x"22");
|
||||||
|
uart_transmit(x"23");
|
||||||
|
uart_transmit(x"31");
|
||||||
|
uart_transmit(x"32");
|
||||||
|
uart_transmit(x"33");
|
||||||
|
|
||||||
|
uart_transmit(x"a1"); -- Second LED
|
||||||
|
uart_transmit(x"a2");
|
||||||
|
uart_transmit(x"a3");
|
||||||
|
uart_transmit(x"b1");
|
||||||
|
uart_transmit(x"b2");
|
||||||
|
uart_transmit(x"b3");
|
||||||
|
uart_transmit(x"c1");
|
||||||
|
uart_transmit(x"c2");
|
||||||
|
uart_transmit(x"c3");
|
||||||
|
uart_transmit(x"d1");
|
||||||
|
uart_transmit(x"d2");
|
||||||
|
uart_transmit(x"d3");
|
||||||
|
|
||||||
|
-- Render (cmd 0x01)
|
||||||
|
uart_transmit(x"01");
|
||||||
|
wait;
|
||||||
|
end process test;
|
||||||
|
end architecture RTL;
|
80
bench_top.gtkw
Normal file
80
bench_top.gtkw
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
[*]
|
||||||
|
[*] GTKWave Analyzer v3.3.86 (w)1999-2017 BSI
|
||||||
|
[*] Sun Jan 21 17:51:06 2018
|
||||||
|
[*]
|
||||||
|
[dumpfile] "/tmp/SigasiCompileCache7616390032050217445/ws2812-wall/mentor/bench_top.ghw"
|
||||||
|
[dumpfile_mtime] "Sun Jan 21 17:50:57 2018"
|
||||||
|
[dumpfile_size] 5545813
|
||||||
|
[savefile] "/home/markus/workspaceSigasi/ws2812-wall/bench_top.gtkw"
|
||||||
|
[timestart] 1288000000000
|
||||||
|
[size] 1920 1043
|
||||||
|
[pos] -1 -1
|
||||||
|
*-34.891136 1372229144711 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
|
||||||
|
[treeopen] top.
|
||||||
|
[treeopen] top.bench_top.
|
||||||
|
[treeopen] top.bench_top.top_inst.
|
||||||
|
[treeopen] top.bench_top.top_inst.uart_rx_inst.
|
||||||
|
[sst_width] 267
|
||||||
|
[signals_width] 261
|
||||||
|
[sst_expanded] 1
|
||||||
|
[sst_vpaned_height] 298
|
||||||
|
@420
|
||||||
|
top.bench_top.top_inst.renderer_state
|
||||||
|
@28
|
||||||
|
top.bench_top.top_inst.render_stb
|
||||||
|
top.bench_top.top_inst.rst
|
||||||
|
top.bench_top.top_inst.clk
|
||||||
|
top.bench_top.top_inst.rst_hw
|
||||||
|
top.bench_top.top_inst.clk_hw
|
||||||
|
@c00022
|
||||||
|
#{top.bench_top.ws2812_out[6:0]} top.bench_top.ws2812_out[3] top.bench_top.ws2812_out[2] top.bench_top.ws2812_out[1] top.bench_top.ws2812_out[0]
|
||||||
|
@28
|
||||||
|
top.bench_top.ws2812_out[3]
|
||||||
|
top.bench_top.ws2812_out[2]
|
||||||
|
top.bench_top.ws2812_out[1]
|
||||||
|
top.bench_top.ws2812_out[0]
|
||||||
|
@1401200
|
||||||
|
-group_end
|
||||||
|
@22
|
||||||
|
#{top.bench_top.top_inst.renderer_data[167:0]} top.bench_top.top_inst.renderer_data[95] top.bench_top.top_inst.renderer_data[94] top.bench_top.top_inst.renderer_data[93] top.bench_top.top_inst.renderer_data[92] top.bench_top.top_inst.renderer_data[91] top.bench_top.top_inst.renderer_data[90] top.bench_top.top_inst.renderer_data[89] top.bench_top.top_inst.renderer_data[88] top.bench_top.top_inst.renderer_data[87] top.bench_top.top_inst.renderer_data[86] top.bench_top.top_inst.renderer_data[85] top.bench_top.top_inst.renderer_data[84] top.bench_top.top_inst.renderer_data[83] top.bench_top.top_inst.renderer_data[82] top.bench_top.top_inst.renderer_data[81] top.bench_top.top_inst.renderer_data[80] top.bench_top.top_inst.renderer_data[79] top.bench_top.top_inst.renderer_data[78] top.bench_top.top_inst.renderer_data[77] top.bench_top.top_inst.renderer_data[76] top.bench_top.top_inst.renderer_data[75] top.bench_top.top_inst.renderer_data[74] top.bench_top.top_inst.renderer_data[73] top.bench_top.top_inst.renderer_data[72] top.bench_top.top_inst.renderer_data[71] top.bench_top.top_inst.renderer_data[70] top.bench_top.top_inst.renderer_data[69] top.bench_top.top_inst.renderer_data[68] top.bench_top.top_inst.renderer_data[67] top.bench_top.top_inst.renderer_data[66] top.bench_top.top_inst.renderer_data[65] top.bench_top.top_inst.renderer_data[64] top.bench_top.top_inst.renderer_data[63] top.bench_top.top_inst.renderer_data[62] top.bench_top.top_inst.renderer_data[61] top.bench_top.top_inst.renderer_data[60] top.bench_top.top_inst.renderer_data[59] top.bench_top.top_inst.renderer_data[58] top.bench_top.top_inst.renderer_data[57] top.bench_top.top_inst.renderer_data[56] top.bench_top.top_inst.renderer_data[55] top.bench_top.top_inst.renderer_data[54] top.bench_top.top_inst.renderer_data[53] top.bench_top.top_inst.renderer_data[52] top.bench_top.top_inst.renderer_data[51] top.bench_top.top_inst.renderer_data[50] top.bench_top.top_inst.renderer_data[49] top.bench_top.top_inst.renderer_data[48] top.bench_top.top_inst.renderer_data[47] top.bench_top.top_inst.renderer_data[46] top.bench_top.top_inst.renderer_data[45] top.bench_top.top_inst.renderer_data[44] top.bench_top.top_inst.renderer_data[43] top.bench_top.top_inst.renderer_data[42] top.bench_top.top_inst.renderer_data[41] top.bench_top.top_inst.renderer_data[40] top.bench_top.top_inst.renderer_data[39] top.bench_top.top_inst.renderer_data[38] top.bench_top.top_inst.renderer_data[37] top.bench_top.top_inst.renderer_data[36] top.bench_top.top_inst.renderer_data[35] top.bench_top.top_inst.renderer_data[34] top.bench_top.top_inst.renderer_data[33] top.bench_top.top_inst.renderer_data[32] top.bench_top.top_inst.renderer_data[31] top.bench_top.top_inst.renderer_data[30] top.bench_top.top_inst.renderer_data[29] top.bench_top.top_inst.renderer_data[28] top.bench_top.top_inst.renderer_data[27] top.bench_top.top_inst.renderer_data[26] top.bench_top.top_inst.renderer_data[25] top.bench_top.top_inst.renderer_data[24] top.bench_top.top_inst.renderer_data[23] top.bench_top.top_inst.renderer_data[22] top.bench_top.top_inst.renderer_data[21] top.bench_top.top_inst.renderer_data[20] top.bench_top.top_inst.renderer_data[19] top.bench_top.top_inst.renderer_data[18] top.bench_top.top_inst.renderer_data[17] top.bench_top.top_inst.renderer_data[16] top.bench_top.top_inst.renderer_data[15] top.bench_top.top_inst.renderer_data[14] top.bench_top.top_inst.renderer_data[13] top.bench_top.top_inst.renderer_data[12] top.bench_top.top_inst.renderer_data[11] top.bench_top.top_inst.renderer_data[10] top.bench_top.top_inst.renderer_data[9] top.bench_top.top_inst.renderer_data[8] top.bench_top.top_inst.renderer_data[7] top.bench_top.top_inst.renderer_data[6] top.bench_top.top_inst.renderer_data[5] top.bench_top.top_inst.renderer_data[4] top.bench_top.top_inst.renderer_data[3] top.bench_top.top_inst.renderer_data[2] top.bench_top.top_inst.renderer_data[1] top.bench_top.top_inst.renderer_data[0]
|
||||||
|
@800022
|
||||||
|
#{top.bench_top.top_inst.pixdata_next[6:0]} top.bench_top.top_inst.pixdata_next[3] top.bench_top.top_inst.pixdata_next[2] top.bench_top.top_inst.pixdata_next[1] top.bench_top.top_inst.pixdata_next[0]
|
||||||
|
@28
|
||||||
|
top.bench_top.top_inst.pixdata_next[3]
|
||||||
|
top.bench_top.top_inst.pixdata_next[2]
|
||||||
|
top.bench_top.top_inst.pixdata_next[1]
|
||||||
|
top.bench_top.top_inst.pixdata_next[0]
|
||||||
|
@1001200
|
||||||
|
-group_end
|
||||||
|
@800022
|
||||||
|
#{top.bench_top.top_inst.pixdata_valid[6:0]} top.bench_top.top_inst.pixdata_valid[3] top.bench_top.top_inst.pixdata_valid[2] top.bench_top.top_inst.pixdata_valid[1] top.bench_top.top_inst.pixdata_valid[0]
|
||||||
|
@28
|
||||||
|
top.bench_top.top_inst.pixdata_valid[3]
|
||||||
|
top.bench_top.top_inst.pixdata_valid[2]
|
||||||
|
top.bench_top.top_inst.pixdata_valid[1]
|
||||||
|
top.bench_top.top_inst.pixdata_valid[0]
|
||||||
|
@1001200
|
||||||
|
-group_end
|
||||||
|
@420
|
||||||
|
top.bench_top.top_inst.controller_state
|
||||||
|
@28
|
||||||
|
top.bench_top.top_inst.uart_rx
|
||||||
|
@420
|
||||||
|
top.bench_top.top_inst.uart_rx_inst.state
|
||||||
|
top.bench_top.top_inst.uart_rx_inst.bitcounter
|
||||||
|
@22
|
||||||
|
#{top.bench_top.top_inst.uart_rx_inst.clkdivider[15:0]} top.bench_top.top_inst.uart_rx_inst.clkdivider[15] top.bench_top.top_inst.uart_rx_inst.clkdivider[14] top.bench_top.top_inst.uart_rx_inst.clkdivider[13] top.bench_top.top_inst.uart_rx_inst.clkdivider[12] top.bench_top.top_inst.uart_rx_inst.clkdivider[11] top.bench_top.top_inst.uart_rx_inst.clkdivider[10] top.bench_top.top_inst.uart_rx_inst.clkdivider[9] top.bench_top.top_inst.uart_rx_inst.clkdivider[8] top.bench_top.top_inst.uart_rx_inst.clkdivider[7] top.bench_top.top_inst.uart_rx_inst.clkdivider[6] top.bench_top.top_inst.uart_rx_inst.clkdivider[5] top.bench_top.top_inst.uart_rx_inst.clkdivider[4] top.bench_top.top_inst.uart_rx_inst.clkdivider[3] top.bench_top.top_inst.uart_rx_inst.clkdivider[2] top.bench_top.top_inst.uart_rx_inst.clkdivider[1] top.bench_top.top_inst.uart_rx_inst.clkdivider[0]
|
||||||
|
@28
|
||||||
|
top.bench_top.top_inst.uart_rx_stb
|
||||||
|
@22
|
||||||
|
#{top.bench_top.top_inst.uart_rx_data[7:0]} top.bench_top.top_inst.uart_rx_data[7] top.bench_top.top_inst.uart_rx_data[6] top.bench_top.top_inst.uart_rx_data[5] top.bench_top.top_inst.uart_rx_data[4] top.bench_top.top_inst.uart_rx_data[3] top.bench_top.top_inst.uart_rx_data[2] top.bench_top.top_inst.uart_rx_data[1] top.bench_top.top_inst.uart_rx_data[0]
|
||||||
|
@29
|
||||||
|
top.bench_top.top_inst.controller_ram_we
|
||||||
|
@420
|
||||||
|
top.bench_top.top_inst.byte_cnt
|
||||||
|
@22
|
||||||
|
#{top.bench_top.top_inst.sr[167:0]} top.bench_top.top_inst.sr[95] top.bench_top.top_inst.sr[94] top.bench_top.top_inst.sr[93] top.bench_top.top_inst.sr[92] top.bench_top.top_inst.sr[91] top.bench_top.top_inst.sr[90] top.bench_top.top_inst.sr[89] top.bench_top.top_inst.sr[88] top.bench_top.top_inst.sr[87] top.bench_top.top_inst.sr[86] top.bench_top.top_inst.sr[85] top.bench_top.top_inst.sr[84] top.bench_top.top_inst.sr[83] top.bench_top.top_inst.sr[82] top.bench_top.top_inst.sr[81] top.bench_top.top_inst.sr[80] top.bench_top.top_inst.sr[79] top.bench_top.top_inst.sr[78] top.bench_top.top_inst.sr[77] top.bench_top.top_inst.sr[76] top.bench_top.top_inst.sr[75] top.bench_top.top_inst.sr[74] top.bench_top.top_inst.sr[73] top.bench_top.top_inst.sr[72] top.bench_top.top_inst.sr[71] top.bench_top.top_inst.sr[70] top.bench_top.top_inst.sr[69] top.bench_top.top_inst.sr[68] top.bench_top.top_inst.sr[67] top.bench_top.top_inst.sr[66] top.bench_top.top_inst.sr[65] top.bench_top.top_inst.sr[64] top.bench_top.top_inst.sr[63] top.bench_top.top_inst.sr[62] top.bench_top.top_inst.sr[61] top.bench_top.top_inst.sr[60] top.bench_top.top_inst.sr[59] top.bench_top.top_inst.sr[58] top.bench_top.top_inst.sr[57] top.bench_top.top_inst.sr[56] top.bench_top.top_inst.sr[55] top.bench_top.top_inst.sr[54] top.bench_top.top_inst.sr[53] top.bench_top.top_inst.sr[52] top.bench_top.top_inst.sr[51] top.bench_top.top_inst.sr[50] top.bench_top.top_inst.sr[49] top.bench_top.top_inst.sr[48] top.bench_top.top_inst.sr[47] top.bench_top.top_inst.sr[46] top.bench_top.top_inst.sr[45] top.bench_top.top_inst.sr[44] top.bench_top.top_inst.sr[43] top.bench_top.top_inst.sr[42] top.bench_top.top_inst.sr[41] top.bench_top.top_inst.sr[40] top.bench_top.top_inst.sr[39] top.bench_top.top_inst.sr[38] top.bench_top.top_inst.sr[37] top.bench_top.top_inst.sr[36] top.bench_top.top_inst.sr[35] top.bench_top.top_inst.sr[34] top.bench_top.top_inst.sr[33] top.bench_top.top_inst.sr[32] top.bench_top.top_inst.sr[31] top.bench_top.top_inst.sr[30] top.bench_top.top_inst.sr[29] top.bench_top.top_inst.sr[28] top.bench_top.top_inst.sr[27] top.bench_top.top_inst.sr[26] top.bench_top.top_inst.sr[25] top.bench_top.top_inst.sr[24] top.bench_top.top_inst.sr[23] top.bench_top.top_inst.sr[22] top.bench_top.top_inst.sr[21] top.bench_top.top_inst.sr[20] top.bench_top.top_inst.sr[19] top.bench_top.top_inst.sr[18] top.bench_top.top_inst.sr[17] top.bench_top.top_inst.sr[16] top.bench_top.top_inst.sr[15] top.bench_top.top_inst.sr[14] top.bench_top.top_inst.sr[13] top.bench_top.top_inst.sr[12] top.bench_top.top_inst.sr[11] top.bench_top.top_inst.sr[10] top.bench_top.top_inst.sr[9] top.bench_top.top_inst.sr[8] top.bench_top.top_inst.sr[7] top.bench_top.top_inst.sr[6] top.bench_top.top_inst.sr[5] top.bench_top.top_inst.sr[4] top.bench_top.top_inst.sr[3] top.bench_top.top_inst.sr[2] top.bench_top.top_inst.sr[1] top.bench_top.top_inst.sr[0]
|
||||||
|
@28
|
||||||
|
top.bench_top.top_inst.controller_ram_addr[0]
|
||||||
|
[pattern_trace] 1
|
||||||
|
[pattern_trace] 0
|
41
design/edgeDetector.vhd
Normal file
41
design/edgeDetector.vhd
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
-- -------------------------------------------------------------------------- --
|
||||||
|
-- edgeDetector.vhd: Basic edge detector
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2017 Markus Koch <markus@notsyncing.net>
|
||||||
|
--
|
||||||
|
-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
-- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
-- file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
-- -------------------------------------------------------------------------- --
|
||||||
|
|
||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
|
||||||
|
entity edgeDetector is
|
||||||
|
port(
|
||||||
|
clk : in std_logic;
|
||||||
|
rst : in std_logic;
|
||||||
|
sig : in std_logic;
|
||||||
|
risingEdge : out std_logic;
|
||||||
|
fallingEdge : out std_logic;
|
||||||
|
anyEdge : out std_logic
|
||||||
|
);
|
||||||
|
end entity edgeDetector;
|
||||||
|
|
||||||
|
architecture RTL of edgeDetector is
|
||||||
|
signal temp : std_logic_vector(1 downto 0);
|
||||||
|
begin
|
||||||
|
shiftomat : process(rst, clk) is
|
||||||
|
begin
|
||||||
|
if rst = '1' then
|
||||||
|
temp <= "00";
|
||||||
|
elsif rising_edge(clk) then
|
||||||
|
temp <= temp(0) & sig;
|
||||||
|
end if;
|
||||||
|
end process shiftomat;
|
||||||
|
|
||||||
|
risingEdge <= '1' when (temp = "01") else '0';
|
||||||
|
fallingEdge <= '1' when (temp = "10") else '0';
|
||||||
|
anyEdge <= '1' when (temp = "01" or temp = "10") else '0';
|
||||||
|
end architecture RTL;
|
36
design/ram.vhd
Normal file
36
design/ram.vhd
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
|
||||||
|
entity ram is
|
||||||
|
generic(
|
||||||
|
WIDTH : natural := 8;
|
||||||
|
DEPTH : natural := 4
|
||||||
|
);
|
||||||
|
port(
|
||||||
|
clk : in std_logic;
|
||||||
|
addr_a : in std_logic_vector(DEPTH - 1 downto 0);
|
||||||
|
data_out_a : out std_logic_vector(WIDTH - 1 downto 0);
|
||||||
|
data_in_a : in std_logic_vector(WIDTH - 1 downto 0);
|
||||||
|
we_a : in std_logic;
|
||||||
|
addr_b : in std_logic_vector(DEPTH - 1 downto 0);
|
||||||
|
data_out_b : out std_logic_vector(WIDTH - 1 downto 0)
|
||||||
|
);
|
||||||
|
end entity ram;
|
||||||
|
|
||||||
|
architecture rtl of ram is
|
||||||
|
type memory_t is array (0 to integer(2**DEPTH) - 1) of std_logic_vector(WIDTH - 1 downto 0);
|
||||||
|
signal memory : memory_t;
|
||||||
|
|
||||||
|
begin
|
||||||
|
ram_p : process(clk) is
|
||||||
|
begin
|
||||||
|
if (rising_edge(clk)) then
|
||||||
|
data_out_a <= memory(to_integer(unsigned(addr_a)));
|
||||||
|
if (we_a = '1') then
|
||||||
|
memory(to_integer(unsigned(addr_a))) <= data_in_a;
|
||||||
|
end if;
|
||||||
|
data_out_b <= memory(to_integer(unsigned(addr_b)));
|
||||||
|
end if;
|
||||||
|
end process ram_p;
|
||||||
|
end architecture rtl;
|
31
design/synchronizer.vhd
Normal file
31
design/synchronizer.vhd
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
|
||||||
|
entity synchronizer is
|
||||||
|
generic(COUNT : integer := 1);
|
||||||
|
port(
|
||||||
|
clk : in std_logic;
|
||||||
|
rst : in std_logic;
|
||||||
|
dIn : in std_logic_vector(COUNT - 1 downto 0);
|
||||||
|
dOut : out std_logic_vector(COUNT - 1 downto 0)
|
||||||
|
);
|
||||||
|
end entity synchronizer;
|
||||||
|
|
||||||
|
architecture RTL of synchronizer is
|
||||||
|
signal temp : std_logic_vector(COUNT - 1 downto 0);
|
||||||
|
begin
|
||||||
|
synch : process(rst, clk) is
|
||||||
|
begin
|
||||||
|
for i in 0 to COUNT - 1 loop
|
||||||
|
if rst = '1' then
|
||||||
|
temp(i) <= '0';
|
||||||
|
dOut(i) <= '0';
|
||||||
|
elsif rising_edge(clk) then
|
||||||
|
temp(i) <= dIn(i);
|
||||||
|
dOut(i) <= temp(i);
|
||||||
|
end if;
|
||||||
|
end loop;
|
||||||
|
end process synch;
|
||||||
|
|
||||||
|
end architecture RTL;
|
252
design/top.vhd
Normal file
252
design/top.vhd
Normal file
@ -0,0 +1,252 @@
|
|||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
use ieee.math_real.all;
|
||||||
|
|
||||||
|
library ws2812b;
|
||||||
|
use ws2812b.all;
|
||||||
|
|
||||||
|
use work.top_pkg.all;
|
||||||
|
|
||||||
|
entity top is
|
||||||
|
generic(
|
||||||
|
f_clk : natural := 24_000_000;
|
||||||
|
ROWS : natural := 7;
|
||||||
|
COLUMNS : natural := 64
|
||||||
|
);
|
||||||
|
port(
|
||||||
|
clk_hw : in std_logic; -- HW clock
|
||||||
|
rst_hw : in std_logic; -- Hardware reset (active low)
|
||||||
|
|
||||||
|
uart_rx : in std_logic; -- UART RX pin
|
||||||
|
|
||||||
|
ws2812_out : out std_logic_vector(ROWS - 1 downto 0) -- WS2812B data line
|
||||||
|
);
|
||||||
|
end entity top;
|
||||||
|
|
||||||
|
architecture RTL of top is
|
||||||
|
constant RAM_WIDTH : natural := 8 * 3 * ROWS;
|
||||||
|
constant RAM_DEPTH : natural := integer(ceil(log2(real(COLUMNS))));
|
||||||
|
constant UART_CKDIV : std_logic_vector(15 downto 0) := std_logic_vector(to_unsigned(f_clk / 115200, 16));
|
||||||
|
|
||||||
|
signal clk : std_logic;
|
||||||
|
signal rst : std_logic;
|
||||||
|
|
||||||
|
signal pixData_red : color_vector(ROWS - 1 downto 0);
|
||||||
|
signal pixData_green : color_vector(ROWS - 1 downto 0);
|
||||||
|
signal pixData_blue : color_vector(ROWS - 1 downto 0);
|
||||||
|
signal pixData_valid : std_logic_vector(ROWS - 1 downto 0);
|
||||||
|
signal pixData_next : std_logic_vector(ROWS - 1 downto 0);
|
||||||
|
|
||||||
|
signal uart_rx_data : std_logic_vector(7 downto 0);
|
||||||
|
signal uart_rx_stb : std_logic;
|
||||||
|
signal uart_rx_error : std_logic;
|
||||||
|
|
||||||
|
type controller_state_t is (IDLE, ADDR, LENGTH, DATA);
|
||||||
|
signal controller_state : controller_state_t;
|
||||||
|
signal controller_ram_addr : std_logic_vector(RAM_DEPTH - 1 downto 0);
|
||||||
|
signal controller_ram_din : std_logic_vector(RAM_WIDTH - 1 downto 0);
|
||||||
|
signal controller_ram_dout : std_logic_vector(RAM_WIDTH - 1 downto 0);
|
||||||
|
signal controller_ram_we : std_logic;
|
||||||
|
signal sr : std_logic_vector(controller_ram_din'range);
|
||||||
|
signal byte_cnt : integer range 0 to ROWS * 3 - 1;
|
||||||
|
signal leds_left : integer range 0 to 2**RAM_DEPTH - 1;
|
||||||
|
|
||||||
|
signal render_stb : std_logic;
|
||||||
|
type renderer_state_t is (IDLE, RENDER, LOCK);
|
||||||
|
signal renderer_state : renderer_state_t;
|
||||||
|
signal renderer_addr : std_logic_vector(RAM_DEPTH - 1 downto 0);
|
||||||
|
signal renderer_data : std_logic_vector(RAM_WIDTH - 1 downto 0);
|
||||||
|
|
||||||
|
begin
|
||||||
|
clk <= clk_hw;
|
||||||
|
|
||||||
|
reset_gen : process(clk, rst_hw) is
|
||||||
|
variable tmp : std_logic;
|
||||||
|
|
||||||
|
begin
|
||||||
|
if (rst_hw = '0') then
|
||||||
|
tmp := '1';
|
||||||
|
rst <= '1';
|
||||||
|
elsif (rising_edge(clk)) then
|
||||||
|
rst <= tmp;
|
||||||
|
tmp := '0';
|
||||||
|
end if;
|
||||||
|
end process reset_gen;
|
||||||
|
|
||||||
|
ws2812b_phys : for i in 0 to ROWS - 1 generate
|
||||||
|
ws2812b_phy_inst : entity ws2812b.ws2812b_phy
|
||||||
|
generic map(
|
||||||
|
f_clk => f_clk
|
||||||
|
)
|
||||||
|
port map(
|
||||||
|
clk => clk,
|
||||||
|
rst => rst,
|
||||||
|
so => ws2812_out(i),
|
||||||
|
pixData_red => pixData_red(i),
|
||||||
|
pixData_green => pixData_green(i),
|
||||||
|
pixData_blue => pixData_blue(i),
|
||||||
|
pixData_valid => pixData_valid(i),
|
||||||
|
pixData_next => pixData_next(i)
|
||||||
|
);
|
||||||
|
end generate ws2812b_phys;
|
||||||
|
|
||||||
|
-- Upon receiving ```renderer_stb```, it sends the data in memory out to the LEDs
|
||||||
|
renderer : process(clk, rst) is
|
||||||
|
procedure set_all_valid(state : std_logic) is
|
||||||
|
begin
|
||||||
|
for i in 0 to ROWS - 1 loop
|
||||||
|
pixData_valid(i) <= state;
|
||||||
|
end loop;
|
||||||
|
end procedure set_all_valid;
|
||||||
|
|
||||||
|
begin
|
||||||
|
if (rst = '1') then
|
||||||
|
renderer_state <= IDLE;
|
||||||
|
renderer_addr <= (others => '0');
|
||||||
|
set_all_valid('0');
|
||||||
|
|
||||||
|
elsif (rising_edge(clk)) then
|
||||||
|
case renderer_state is
|
||||||
|
when IDLE =>
|
||||||
|
set_all_valid('0');
|
||||||
|
renderer_addr <= (others => '0'); -- Note: We need to have been in this state for at least one cycle
|
||||||
|
if (render_stb = '1') then
|
||||||
|
set_all_valid('1');
|
||||||
|
renderer_state <= RENDER;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
when RENDER =>
|
||||||
|
if (pixData_next(0) = '1') then -- TODO: This expects all PHYs to run synchronously
|
||||||
|
renderer_addr <= std_logic_vector(unsigned(renderer_addr) + 1);
|
||||||
|
if (unsigned(renderer_addr) = (COLUMNS - 1)) then
|
||||||
|
set_all_valid('0');
|
||||||
|
renderer_state <= LOCK;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
when LOCK =>
|
||||||
|
set_all_valid('0');
|
||||||
|
if (pixData_next(0) = '1') then
|
||||||
|
renderer_state <= IDLE;
|
||||||
|
end if;
|
||||||
|
end case;
|
||||||
|
end if;
|
||||||
|
end process renderer;
|
||||||
|
|
||||||
|
pixData_connections : for i in 0 to ROWS - 1 generate
|
||||||
|
pixData_red(i) <= renderer_data(i * 24 + 7 downto i * 24);
|
||||||
|
pixData_green(i) <= renderer_data(i * 24 + 15 downto i * 24 + 8);
|
||||||
|
pixData_blue(i) <= renderer_data(i * 24 + 23 downto i * 24 + 16);
|
||||||
|
end generate pixData_connections;
|
||||||
|
|
||||||
|
ram_inst : entity work.ram
|
||||||
|
generic map(
|
||||||
|
WIDTH => RAM_WIDTH,
|
||||||
|
DEPTH => RAM_DEPTH
|
||||||
|
)
|
||||||
|
port map(
|
||||||
|
clk => clk,
|
||||||
|
addr_a => controller_ram_addr,
|
||||||
|
data_out_a => controller_ram_dout,
|
||||||
|
data_in_a => controller_ram_din,
|
||||||
|
we_a => controller_ram_we,
|
||||||
|
addr_b => renderer_addr,
|
||||||
|
data_out_b => renderer_data
|
||||||
|
);
|
||||||
|
|
||||||
|
controller : process(clk, rst) is
|
||||||
|
variable sr_v : std_logic_vector(sr'range);
|
||||||
|
begin
|
||||||
|
if (rst = '1') then
|
||||||
|
sr <= (others => '0');
|
||||||
|
controller_state <= IDLE;
|
||||||
|
byte_cnt <= 0;
|
||||||
|
render_stb <= '0';
|
||||||
|
controller_ram_addr <= (others => '0');
|
||||||
|
controller_ram_we <= '0';
|
||||||
|
|
||||||
|
elsif (rising_edge(clk)) then
|
||||||
|
render_stb <= '0';
|
||||||
|
controller_ram_we <= '0';
|
||||||
|
|
||||||
|
if (uart_rx_stb = '1') then
|
||||||
|
sr_v := sr(sr'high - uart_rx_data'length downto sr'low) & uart_rx_data;
|
||||||
|
sr <= sr_v;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
case controller_state is
|
||||||
|
when IDLE =>
|
||||||
|
byte_cnt <= 0;
|
||||||
|
if (uart_rx_stb = '1') then
|
||||||
|
if (uart_rx_data = x"00") then
|
||||||
|
controller_state <= ADDR;
|
||||||
|
|
||||||
|
elsif (uart_rx_data = x"01") then
|
||||||
|
render_stb <= '1';
|
||||||
|
controller_state <= IDLE;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
when ADDR =>
|
||||||
|
if (uart_rx_stb = '1') then
|
||||||
|
if (byte_cnt = 1) then
|
||||||
|
controller_ram_addr <= std_logic_vector(to_unsigned(to_integer(unsigned(sr_v(15 downto 0)) * 3), controller_ram_addr'length));
|
||||||
|
controller_state <= LENGTH;
|
||||||
|
byte_cnt <= 0;
|
||||||
|
|
||||||
|
else
|
||||||
|
byte_cnt <= byte_cnt + 1;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
when LENGTH =>
|
||||||
|
if (uart_rx_stb = '1') then
|
||||||
|
if (byte_cnt = 1) then
|
||||||
|
leds_left <= to_integer(unsigned(sr_v(15 downto 0))) - 1;
|
||||||
|
controller_state <= DATA;
|
||||||
|
byte_cnt <= 0;
|
||||||
|
|
||||||
|
else
|
||||||
|
byte_cnt <= byte_cnt + 1;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
when DATA =>
|
||||||
|
if (controller_ram_we = '1') then
|
||||||
|
controller_ram_addr <= std_logic_vector(unsigned(controller_ram_addr) + 1);
|
||||||
|
end if;
|
||||||
|
if (uart_rx_stb = '1') then
|
||||||
|
if (byte_cnt = ROWS * 3 - 1) then
|
||||||
|
byte_cnt <= 0;
|
||||||
|
controller_ram_we <= '1';
|
||||||
|
if (leds_left = 0) then
|
||||||
|
controller_state <= IDLE;
|
||||||
|
else
|
||||||
|
leds_left <= leds_left - 1;
|
||||||
|
end if;
|
||||||
|
else
|
||||||
|
byte_cnt <= byte_cnt + 1;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end case;
|
||||||
|
end if;
|
||||||
|
end process controller;
|
||||||
|
|
||||||
|
controller_ram_din <= sr;
|
||||||
|
|
||||||
|
uart_rx_inst : entity work.uart_rx
|
||||||
|
port map(
|
||||||
|
clk => clk,
|
||||||
|
rst => rst,
|
||||||
|
data => uart_rx_data,
|
||||||
|
byte_ready => uart_rx_stb,
|
||||||
|
error => uart_rx_error,
|
||||||
|
ckDiv => UART_CKDIV,
|
||||||
|
parityEnable => '0',
|
||||||
|
parityOdd => '0',
|
||||||
|
twoStopBits => '0',
|
||||||
|
rx => uart_rx
|
||||||
|
);
|
||||||
|
|
||||||
|
end architecture RTL;
|
6
design/top_pkg.vhd
Normal file
6
design/top_pkg.vhd
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
|
||||||
|
package top_pkg is
|
||||||
|
type color_vector is array(natural range <>) of std_logic_vector(7 downto 0);
|
||||||
|
end package top_pkg;
|
161
design/uart_rx.vhd
Normal file
161
design/uart_rx.vhd
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
-- -------------------------------------------------------------------------- --
|
||||||
|
-- uart_rx.vhd: Basic UART (rx)
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2017 Markus Koch <markus@notsyncing.net>
|
||||||
|
--
|
||||||
|
-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
-- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
-- file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
-- -------------------------------------------------------------------------- --
|
||||||
|
|
||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
|
||||||
|
entity uart_rx is
|
||||||
|
port(
|
||||||
|
clk : in std_logic;
|
||||||
|
rst : in std_logic;
|
||||||
|
data : out std_logic_vector(7 downto 0);
|
||||||
|
byte_ready : out std_logic;
|
||||||
|
error : out std_logic;
|
||||||
|
|
||||||
|
ckDiv : in std_logic_vector(15 downto 0);
|
||||||
|
parityEnable : in std_logic;
|
||||||
|
parityOdd : in std_logic;
|
||||||
|
twoStopBits : in std_logic;
|
||||||
|
|
||||||
|
rx : in std_logic
|
||||||
|
);
|
||||||
|
end entity uart_rx;
|
||||||
|
|
||||||
|
architecture RTL of uart_rx is
|
||||||
|
constant SYNCH_COUNT : integer := 11; -- Min. 8
|
||||||
|
constant BITCOUNT : integer := 8;
|
||||||
|
|
||||||
|
type state_t is (SYNCH, IDLE, START, RECEIVE, PARITY, STOP);
|
||||||
|
|
||||||
|
signal state : state_t;
|
||||||
|
signal clkDivider : unsigned(15 downto 0);
|
||||||
|
signal bitCounter : integer range 0 to SYNCH_COUNT;
|
||||||
|
signal data_i : std_logic_vector(7 downto 0);
|
||||||
|
signal rx_edge : std_logic;
|
||||||
|
signal parity_calc : std_logic;
|
||||||
|
signal rx_i : std_logic;
|
||||||
|
|
||||||
|
begin
|
||||||
|
synchronizer_inst : entity work.synchronizer
|
||||||
|
generic map(
|
||||||
|
COUNT => 1
|
||||||
|
)
|
||||||
|
port map(
|
||||||
|
clk => clk,
|
||||||
|
rst => rst,
|
||||||
|
dIn(0) => rx,
|
||||||
|
dOut(0) => rx_i
|
||||||
|
);
|
||||||
|
|
||||||
|
edgeDetector_inst : entity work.edgeDetector
|
||||||
|
port map(clk => clk,
|
||||||
|
rst => rst,
|
||||||
|
sig => rx_i,
|
||||||
|
risingEdge => open,
|
||||||
|
fallingEdge => open,
|
||||||
|
anyEdge => rx_edge);
|
||||||
|
|
||||||
|
rxFSM : process(clk, rst, parityOdd, ckDiv) is
|
||||||
|
begin
|
||||||
|
if rst = '1' then
|
||||||
|
state <= SYNCH;
|
||||||
|
bitCounter <= SYNCH_COUNT;
|
||||||
|
clkDivider <= unsigned(ckDiv);
|
||||||
|
error <= '0';
|
||||||
|
parity_calc <= parityOdd;
|
||||||
|
data_i <= x"00";
|
||||||
|
data <= x"00";
|
||||||
|
byte_ready <= '0';
|
||||||
|
elsif rising_edge(clk) then
|
||||||
|
byte_ready <= '0';
|
||||||
|
error <= '0';
|
||||||
|
if (clkDivider = 0) then
|
||||||
|
clkDivider <= unsigned(ckDiv);
|
||||||
|
else
|
||||||
|
clkDivider <= clkDivider - 1;
|
||||||
|
end if;
|
||||||
|
case state is
|
||||||
|
when SYNCH => -- Wait for 11 consecutive ones
|
||||||
|
if (clkDivider = to_unsigned(0, clkDivider'length)) then
|
||||||
|
if rx_i = '1' then
|
||||||
|
if bitCounter = 0 then
|
||||||
|
state <= IDLE;
|
||||||
|
else
|
||||||
|
bitCounter <= bitcounter - 1;
|
||||||
|
end if;
|
||||||
|
else
|
||||||
|
bitCounter <= SYNCH_COUNT;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
when IDLE => -- Detect transition for sync
|
||||||
|
if rx_i = '0' then
|
||||||
|
state <= START;
|
||||||
|
clkDivider <= unsigned('0' & ckDiv(15 downto 1)); -- cMax_half. After that we are in the middle of the start bit
|
||||||
|
parity_calc <= parityOdd;
|
||||||
|
end if;
|
||||||
|
when START =>
|
||||||
|
if (clkDivider = to_unsigned(0, clkDivider'length)) then
|
||||||
|
if rx_i = '0' then
|
||||||
|
state <= RECEIVE;
|
||||||
|
bitCounter <= 0;
|
||||||
|
else
|
||||||
|
report "uart_rx: START BIT ERROR" severity warning;
|
||||||
|
error <= '1';
|
||||||
|
state <= SYNCH;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
when RECEIVE =>
|
||||||
|
if (clkDivider = to_unsigned(0, clkDivider'length)) then
|
||||||
|
data_i(bitCounter) <= rx_i;
|
||||||
|
if rx_i = '1' then
|
||||||
|
parity_calc <= not parity_calc;
|
||||||
|
end if;
|
||||||
|
if bitCounter = BITCOUNT - 1 then
|
||||||
|
bitCounter <= 0;
|
||||||
|
if parityEnable = '1' then
|
||||||
|
state <= PARITY;
|
||||||
|
else
|
||||||
|
state <= STOP;
|
||||||
|
end if;
|
||||||
|
else
|
||||||
|
bitCounter <= bitCounter + 1;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
when PARITY =>
|
||||||
|
if (clkDivider = to_unsigned(0, clkDivider'length)) then
|
||||||
|
if parity_calc = rx_i then
|
||||||
|
state <= STOP;
|
||||||
|
else
|
||||||
|
state <= SYNCH;
|
||||||
|
error <= '1';
|
||||||
|
report "uart_rx: PARITY ERROR" severity warning;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
when STOP =>
|
||||||
|
if (clkDivider = to_unsigned(0, clkDivider'length)) then
|
||||||
|
if (rx_i = '1') then
|
||||||
|
bitCounter <= bitCounter + 1;
|
||||||
|
if bitCounter = 1 or twoStopBits = '0' then
|
||||||
|
state <= IDLE;
|
||||||
|
data <= data_i;
|
||||||
|
byte_ready <= '1';
|
||||||
|
end if;
|
||||||
|
else
|
||||||
|
error <= '1';
|
||||||
|
state <= SYNCH;
|
||||||
|
report "uart_rx: STOP BIT ERROR" severity warning;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end case;
|
||||||
|
end if;
|
||||||
|
end process rxFSM;
|
||||||
|
|
||||||
|
end architecture RTL;
|
110
design/uart_tx.vhd
Normal file
110
design/uart_tx.vhd
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
-- -------------------------------------------------------------------------- --
|
||||||
|
-- uart_tx.vhd: Basic UART (tx)
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2017 Markus Koch <markus@notsyncing.net>
|
||||||
|
--
|
||||||
|
-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
-- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
-- file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
-- -------------------------------------------------------------------------- --
|
||||||
|
|
||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
|
||||||
|
entity uart_tx is
|
||||||
|
port(
|
||||||
|
clk : in std_logic;
|
||||||
|
rst : in std_logic;
|
||||||
|
data : in std_logic_vector(7 downto 0);
|
||||||
|
byte_ready : in std_logic;
|
||||||
|
busy : out std_logic;
|
||||||
|
|
||||||
|
ckDiv : in std_logic_vector(15 downto 0);
|
||||||
|
parityEnable : in std_logic;
|
||||||
|
parityOdd : in std_logic;
|
||||||
|
twoStopBits : in std_logic;
|
||||||
|
|
||||||
|
tx : out std_logic
|
||||||
|
);
|
||||||
|
end entity uart_tx;
|
||||||
|
|
||||||
|
architecture RTL of uart_tx is
|
||||||
|
type state_t is (IDLE, START, TRANSMIT, PARITY, STOP);
|
||||||
|
|
||||||
|
signal state : state_t;
|
||||||
|
signal clkDivider : unsigned(15 downto 0);
|
||||||
|
signal data_i : std_logic_vector(7 downto 0);
|
||||||
|
signal bitCounter : integer range 0 to 7;
|
||||||
|
signal parity_calc : std_logic;
|
||||||
|
|
||||||
|
begin
|
||||||
|
txFSM : process(clk, rst, ckDiv, parityOdd) is
|
||||||
|
begin
|
||||||
|
if rst = '1' then
|
||||||
|
data_i <= x"00";
|
||||||
|
state <= IDLE;
|
||||||
|
tx <= '1';
|
||||||
|
bitCounter <= 0;
|
||||||
|
busy <= '0';
|
||||||
|
clkDivider <= unsigned(ckDiv);
|
||||||
|
parity_calc <= parityOdd;
|
||||||
|
elsif rising_edge(clk) then
|
||||||
|
busy <= '1';
|
||||||
|
|
||||||
|
if (clkDivider = 0) then
|
||||||
|
clkDivider <= unsigned(ckDiv);
|
||||||
|
else
|
||||||
|
clkDivider <= clkDivider - 1;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
case state is
|
||||||
|
when IDLE =>
|
||||||
|
busy <= '0';
|
||||||
|
tx <= '1';
|
||||||
|
if byte_ready = '1' then
|
||||||
|
data_i <= data;
|
||||||
|
state <= START;
|
||||||
|
clkDivider <= unsigned(ckDiv);
|
||||||
|
bitCounter <= 0;
|
||||||
|
parity_calc <= '0';
|
||||||
|
busy <= '1';
|
||||||
|
tx <= '1';
|
||||||
|
end if;
|
||||||
|
when START =>
|
||||||
|
tx <= '0';
|
||||||
|
state <= TRANSMIT;
|
||||||
|
when TRANSMIT =>
|
||||||
|
if (clkDivider = to_unsigned(0, clkDivider'length)) then
|
||||||
|
tx <= data_i(bitCounter);
|
||||||
|
if data_i(bitCounter) = '1' then
|
||||||
|
parity_calc <= not parity_calc;
|
||||||
|
end if;
|
||||||
|
if bitCounter = 7 then
|
||||||
|
bitCounter <= 0;
|
||||||
|
if parityEnable = '1' then
|
||||||
|
state <= PARITY;
|
||||||
|
else
|
||||||
|
state <= STOP;
|
||||||
|
end if;
|
||||||
|
else
|
||||||
|
bitCounter <= bitCounter + 1;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
when PARITY =>
|
||||||
|
if (clkDivider = to_unsigned(0, clkDivider'length)) then
|
||||||
|
tx <= parity_calc;
|
||||||
|
state <= STOP;
|
||||||
|
end if;
|
||||||
|
when STOP =>
|
||||||
|
if (clkDivider = to_unsigned(0, clkDivider'length)) then
|
||||||
|
tx <= '1';
|
||||||
|
bitCounter <= bitCounter + 1;
|
||||||
|
if (bitCounter = 1 and twoStopBits = '0') or (bitCounter = 2 and twoStopBits = '1') then
|
||||||
|
state <= IDLE;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end case;
|
||||||
|
end if;
|
||||||
|
end process txFSM;
|
||||||
|
end architecture RTL;
|
35
diamond/ws2812wall.ldf
Normal file
35
diamond/ws2812wall.ldf
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<BaliProject version="3.2" title="ws2812wall" device="LCMXO2-7000HC-5TG144C" default_implementation="impl1">
|
||||||
|
<Options/>
|
||||||
|
<Implementation title="impl1" dir="impl1" description="impl1" synthesis="lse" default_strategy="Strategy1">
|
||||||
|
<Options def_top="uart_tx" top="top"/>
|
||||||
|
<Source name="../design/edgeDetector.vhd" type="VHDL" type_short="VHDL">
|
||||||
|
<Options/>
|
||||||
|
</Source>
|
||||||
|
<Source name="../design/ram.vhd" type="VHDL" type_short="VHDL">
|
||||||
|
<Options/>
|
||||||
|
</Source>
|
||||||
|
<Source name="../design/synchronizer.vhd" type="VHDL" type_short="VHDL">
|
||||||
|
<Options/>
|
||||||
|
</Source>
|
||||||
|
<Source name="../design/top_pkg.vhd" type="VHDL" type_short="VHDL">
|
||||||
|
<Options/>
|
||||||
|
</Source>
|
||||||
|
<Source name="../design/top.vhd" type="VHDL" type_short="VHDL">
|
||||||
|
<Options top_module="top"/>
|
||||||
|
</Source>
|
||||||
|
<Source name="../design/uart_rx.vhd" type="VHDL" type_short="VHDL">
|
||||||
|
<Options/>
|
||||||
|
</Source>
|
||||||
|
<Source name="../design/uart_tx.vhd" type="VHDL" type_short="VHDL">
|
||||||
|
<Options/>
|
||||||
|
</Source>
|
||||||
|
<Source name="../ws2812b-vhdl/ws2812b/ws2812b_phy.vhd" type="VHDL" type_short="VHDL">
|
||||||
|
<Options lib="ws2812b"/>
|
||||||
|
</Source>
|
||||||
|
<Source name="ws2812wall.lpf" type="Logic Preference" type_short="LPF">
|
||||||
|
<Options/>
|
||||||
|
</Source>
|
||||||
|
</Implementation>
|
||||||
|
<Strategy name="Strategy1" file="ws2812wall1.sty"/>
|
||||||
|
</BaliProject>
|
2
diamond/ws2812wall.lpf
Normal file
2
diamond/ws2812wall.lpf
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
BLOCK RESETPATHS;
|
||||||
|
BLOCK ASYNCPATHS;
|
1
ws2812b-vhdl
Submodule
1
ws2812b-vhdl
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 6e5249641d014cbe0b3723ff22c1637231e351f7
|
Loading…
Reference in New Issue
Block a user