Compare commits
7 commits
0230edd2fb
...
6ff0e77d38
Author | SHA1 | Date | |
---|---|---|---|
6ff0e77d38 | |||
645a838a73 | |||
70a7b0520a | |||
9ca64a7d4d | |||
0f497e76e8 | |||
fcfa9eb7d0 | |||
3c5c3a4555 |
5 changed files with 60 additions and 15 deletions
|
@ -2,7 +2,7 @@ SYNTH_OUTPUT_FILE = $(SYNTH_WORKDIR)/$(YOSYS_MODULE_NAME).json
|
||||||
|
|
||||||
$(SYNTH_WORKDIR)/%.json: $(VHDL_FILES) $(VERILOG_FILES) | $(SYNTH_WORKDIR) $(GHDL_WORKDIR)/work-obj$(VHDL_STD).cf
|
$(SYNTH_WORKDIR)/%.json: $(VHDL_FILES) $(VERILOG_FILES) | $(SYNTH_WORKDIR) $(GHDL_WORKDIR)/work-obj$(VHDL_STD).cf
|
||||||
$(GHDL) make $(GHDL_FLAGS) $(SYNTH_ENTITY)
|
$(GHDL) make $(GHDL_FLAGS) $(SYNTH_ENTITY)
|
||||||
$(YOSYS) -m $(GHDL_YOSYS_PLUGIN) -l $(SYNTH_WORKDIR)/yosys.log -p 'ghdl $(GHDL_FLAGS) $(SYNTH_ENTITY); read_verilog $(VERILOG_FILES); chformal -remove; synth_xilinx -nodsp -nosrl -flatten -top $*; write_json $@'
|
$(YOSYS) -m $(GHDL_YOSYS_PLUGIN) -l $(SYNTH_WORKDIR)/yosys.log -p 'ghdl $(GHDL_FLAGS) -Werror -Wno-error=binding $(SYNTH_ENTITY); read_verilog $(VERILOG_FILES); chformal -remove; synth_xilinx -nodsp -nosrl -flatten -top $*; write_json $@'
|
||||||
|
|
||||||
$(SYNTH_WORKDIR)/%.fasm: $(SYNTH_WORKDIR)/%.json $(XDC)
|
$(SYNTH_WORKDIR)/%.fasm: $(SYNTH_WORKDIR)/%.json $(XDC)
|
||||||
$(NEXTPNR) --xdc $(XDC) --json $< --chipdb /usr/share/nextpnr/xilinx-chipdb/$(PART).bin --fasm $@
|
$(NEXTPNR) --xdc $(XDC) --json $< --chipdb /usr/share/nextpnr/xilinx-chipdb/$(PART).bin --fasm $@
|
||||||
|
|
|
@ -2,6 +2,8 @@ library ieee;
|
||||||
use ieee.std_logic_1164.all,
|
use ieee.std_logic_1164.all,
|
||||||
ieee.numeric_std.all;
|
ieee.numeric_std.all;
|
||||||
|
|
||||||
|
use work.util.flip_endianness;
|
||||||
|
|
||||||
entity arty_a7 is
|
entity arty_a7 is
|
||||||
generic (
|
generic (
|
||||||
IS_SIMULATION : std_logic := '0'
|
IS_SIMULATION : std_logic := '0'
|
||||||
|
@ -119,6 +121,7 @@ architecture a of arty_a7 is
|
||||||
signal pixel_source_src_ip_address : std_logic_vector(31 downto 0);
|
signal pixel_source_src_ip_address : std_logic_vector(31 downto 0);
|
||||||
signal pixel_source_src_port : std_logic_vector(15 downto 0);
|
signal pixel_source_src_port : std_logic_vector(15 downto 0);
|
||||||
|
|
||||||
|
signal pixel_source_length : std_logic_vector(15 downto 0);
|
||||||
signal pixel_source_valid : std_logic;
|
signal pixel_source_valid : std_logic;
|
||||||
signal pixel_source_last : std_logic;
|
signal pixel_source_last : std_logic;
|
||||||
signal pixel_source_data : std_logic_vector(31 downto 0);
|
signal pixel_source_data : std_logic_vector(31 downto 0);
|
||||||
|
@ -192,6 +195,11 @@ architecture a of arty_a7 is
|
||||||
|
|
||||||
signal frame_number : unsigned(31 downto 0);
|
signal frame_number : unsigned(31 downto 0);
|
||||||
signal prev_frame_number : unsigned(31 downto 0);
|
signal prev_frame_number : unsigned(31 downto 0);
|
||||||
|
|
||||||
|
-- little-endian pixel sink data
|
||||||
|
signal pixel_sink_data_le : std_logic_vector(31 downto 0);
|
||||||
|
-- big-endian pixel source data
|
||||||
|
signal pixel_source_data_be : std_logic_vector(31 downto 0);
|
||||||
begin
|
begin
|
||||||
leds_simple <= (others => '0');
|
leds_simple <= (others => '0');
|
||||||
led0 <= (others => '0');
|
led0 <= (others => '0');
|
||||||
|
@ -242,19 +250,20 @@ begin
|
||||||
pixel_sink_last => pixel_sink_last,
|
pixel_sink_last => pixel_sink_last,
|
||||||
pixel_sink_last_be => pixel_sink_last_be,
|
pixel_sink_last_be => pixel_sink_last_be,
|
||||||
pixel_sink_ready => pixel_sink_ready,
|
pixel_sink_ready => pixel_sink_ready,
|
||||||
pixel_sink_data => pixel_sink_data,
|
pixel_sink_data => pixel_sink_data_le,
|
||||||
|
|
||||||
-- source
|
-- source
|
||||||
pixel_source_src_ip_address => pixel_source_src_ip_address,
|
pixel_source_src_ip_address => pixel_source_src_ip_address,
|
||||||
pixel_source_src_port => pixel_source_src_port,
|
pixel_source_src_port => pixel_source_src_port,
|
||||||
|
|
||||||
pixel_source_length => open,
|
pixel_source_length => pixel_source_length,
|
||||||
pixel_source_valid => pixel_source_valid,
|
pixel_source_valid => pixel_source_valid,
|
||||||
pixel_source_last => pixel_source_last,
|
pixel_source_last => pixel_source_last,
|
||||||
pixel_source_last_be => open,
|
pixel_source_last_be => open,
|
||||||
pixel_source_ready => '1',
|
pixel_source_ready => '1',
|
||||||
pixel_source_data => pixel_source_data
|
pixel_source_data => pixel_source_data
|
||||||
);
|
);
|
||||||
|
pixel_sink_data_le <= flip_endianness(pixel_sink_data);
|
||||||
|
|
||||||
-- 800 MHz VCO
|
-- 800 MHz VCO
|
||||||
-- 80 MHz system clock
|
-- 80 MHz system clock
|
||||||
|
@ -335,12 +344,14 @@ begin
|
||||||
clk => sys_clk,
|
clk => sys_clk,
|
||||||
reset => sys_reset,
|
reset => sys_reset,
|
||||||
|
|
||||||
|
udp_length => pixel_source_length,
|
||||||
udp_valid => pixel_source_valid,
|
udp_valid => pixel_source_valid,
|
||||||
udp_last => pixel_source_last,
|
udp_last => pixel_source_last,
|
||||||
udp_data => pixel_source_data,
|
udp_data => pixel_source_data_be,
|
||||||
|
|
||||||
frame_number => frame_number,
|
frame_number => frame_number,
|
||||||
|
|
||||||
drivers => drivers
|
drivers => drivers
|
||||||
);
|
);
|
||||||
|
pixel_source_data_be <= flip_endianness(pixel_source_data);
|
||||||
end architecture;
|
end architecture;
|
||||||
|
|
|
@ -11,6 +11,7 @@ entity splink is
|
||||||
clk : in std_logic;
|
clk : in std_logic;
|
||||||
reset : in std_logic;
|
reset : in std_logic;
|
||||||
|
|
||||||
|
udp_length : in std_logic_vector(15 downto 0);
|
||||||
udp_valid : in std_logic;
|
udp_valid : in std_logic;
|
||||||
udp_last : in std_logic;
|
udp_last : in std_logic;
|
||||||
udp_data : in std_logic_vector(31 downto 0);
|
udp_data : in std_logic_vector(31 downto 0);
|
||||||
|
@ -40,6 +41,7 @@ architecture a of splink is
|
||||||
signal current_frame: unsigned(31 downto 0);
|
signal current_frame: unsigned(31 downto 0);
|
||||||
signal pixels_received: natural range 0 to MAX_STRAND_LEN-1;
|
signal pixels_received: natural range 0 to MAX_STRAND_LEN-1;
|
||||||
|
|
||||||
|
signal run : std_logic;
|
||||||
signal clear_write_flags : std_logic;
|
signal clear_write_flags : std_logic;
|
||||||
|
|
||||||
signal all_strands_written : std_logic;
|
signal all_strands_written : std_logic;
|
||||||
|
@ -47,6 +49,8 @@ architecture a of splink is
|
||||||
|
|
||||||
-- "PIXL"
|
-- "PIXL"
|
||||||
constant MAGIC_NUMBER : std_logic_vector(31 downto 0) := x"5049584c";
|
constant MAGIC_NUMBER : std_logic_vector(31 downto 0) := x"5049584c";
|
||||||
|
-- magic + frame num + strand num (4 bytes each)
|
||||||
|
constant HEADER_LEN : natural := 12;
|
||||||
|
|
||||||
type receive_state_t is (MAGIC, FRAME_NUM, STRAND_NUM, DATA, DROP);
|
type receive_state_t is (MAGIC, FRAME_NUM, STRAND_NUM, DATA, DROP);
|
||||||
constant RESET_STATE : receive_state_t := MAGIC;
|
constant RESET_STATE : receive_state_t := MAGIC;
|
||||||
|
@ -69,6 +73,7 @@ begin
|
||||||
port map (
|
port map (
|
||||||
n_reset => not reset,
|
n_reset => not reset,
|
||||||
clk => clk,
|
clk => clk,
|
||||||
|
run => run,
|
||||||
|
|
||||||
led_addr => led_data_arr(i).addr,
|
led_addr => led_data_arr(i).addr,
|
||||||
|
|
||||||
|
@ -119,10 +124,12 @@ begin
|
||||||
begin
|
begin
|
||||||
if rising_edge(clk) then
|
if rising_edge(clk) then
|
||||||
clear_write_flags <= '0';
|
clear_write_flags <= '0';
|
||||||
|
run <= '0';
|
||||||
|
|
||||||
if all_strands_written then
|
if all_strands_written then
|
||||||
frame_number <= current_frame;
|
frame_number <= current_frame;
|
||||||
clear_write_flags <= '1';
|
clear_write_flags <= '1';
|
||||||
|
run <= '1';
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
if reset then
|
if reset then
|
||||||
|
@ -136,20 +143,24 @@ begin
|
||||||
|
|
||||||
case receive_state is
|
case receive_state is
|
||||||
when MAGIC =>
|
when MAGIC =>
|
||||||
if udp_data = MAGIC_NUMBER then
|
if udp_data /= MAGIC_NUMBER then
|
||||||
receive_state <= STRAND_NUM;
|
|
||||||
else
|
|
||||||
receive_state <= DROP;
|
receive_state <= DROP;
|
||||||
|
else
|
||||||
|
if (unsigned(udp_length) - HEADER_LEN) / 4 > MAX_STRAND_LEN then
|
||||||
|
receive_state <= DROP;
|
||||||
|
else
|
||||||
|
num_pixels <= (to_integer(unsigned(udp_length)) - HEADER_LEN) / 4;
|
||||||
|
receive_state <= STRAND_NUM;
|
||||||
|
end if;
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
when STRAND_NUM =>
|
when STRAND_NUM =>
|
||||||
-- TODO udp_length, range check with MAX_STRAND_LEN
|
if unsigned(udp_data) >= NUM_STRANDS then
|
||||||
num_pixels <= MAX_STRAND_LEN;
|
receive_state <= DROP;
|
||||||
|
else
|
||||||
-- FIXME bounds check
|
|
||||||
active_strand <= to_integer(unsigned(udp_data));
|
active_strand <= to_integer(unsigned(udp_data));
|
||||||
|
|
||||||
receive_state <= FRAME_NUM;
|
receive_state <= FRAME_NUM;
|
||||||
|
end if;
|
||||||
|
|
||||||
when FRAME_NUM =>
|
when FRAME_NUM =>
|
||||||
if not some_strands_written then
|
if not some_strands_written then
|
||||||
|
|
23
vhdl/util.vhdl
Normal file
23
vhdl/util.vhdl
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
|
||||||
|
package util is
|
||||||
|
function flip_endianness(val : in std_logic_vector) return std_logic_vector;
|
||||||
|
end package;
|
||||||
|
|
||||||
|
package body util is
|
||||||
|
function flip_endianness(val : in std_logic_vector) return std_logic_vector is
|
||||||
|
constant BYTES : natural := val'length / 8;
|
||||||
|
variable ret : std_logic_vector(val'length-1 downto 0);
|
||||||
|
begin
|
||||||
|
assert val'length mod 8 = 0
|
||||||
|
report "length of vector not a multiple of 8"
|
||||||
|
severity failure;
|
||||||
|
|
||||||
|
for i in 0 to BYTES-1 loop
|
||||||
|
ret((BYTES-i)*8 - 1 downto (BYTES-i-1) * 8) := val((i+1)*8 - 1 downto i*8);
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
end function;
|
||||||
|
end package body;
|
|
@ -1 +1 @@
|
||||||
Subproject commit 0d1688f1840b8b5894b9f4cd027fcc1653dd3657
|
Subproject commit 0d4146d3a3abeb6a20f9228e61e58f95a71b340a
|
Loading…
Reference in a new issue