* Re-wrote "rtps_ahandler"
- Compiles
This commit is contained in:
parent
d61b9dc80a
commit
ce72c147a4
@ -103,8 +103,3 @@ DESIGN DECISIONS
|
||||
|
||||
-- Input FIFO Guard
|
||||
-- Output FIFO Guard
|
||||
-- Memory Operation Guard
|
||||
-- Ignore in-line QoS
|
||||
-- Only relevant for Endpoint Discovery Protocol
|
||||
-- Check QoS Compatibility (Unmark match on incompatibility)
|
||||
-- COMPATIBLE (DDS v1.4): offered >= requested, with INSTANCE < TOPIC < GROUP
|
||||
@ -120,7 +120,7 @@ architecture arch of rtps_builtin_endpoint is
|
||||
end record;
|
||||
|
||||
--*****CONSTANT DECLARATION*****
|
||||
-- Memory Size in 32-bit Words
|
||||
-- Memory Size in 4-Byte Words
|
||||
constant BUILTIN_BUFFER_SIZE : natural := MAX_REMOTE_PARTICIPANTS*PARTICIPANT_FRAME_SIZE;
|
||||
-- Memory Address Width
|
||||
constant BUILTIN_BUFFER_ADDR_WIDTH : natural := log2c(BUILTIN_BUFFER_SIZE);
|
||||
@ -189,7 +189,7 @@ architecture arch of rtps_builtin_endpoint is
|
||||
signal rd_sig : std_logic := '0';
|
||||
-- Signal used to reset the word counter
|
||||
signal reset_read_cnt : std_logic;
|
||||
-- Word (32-bit) counter (Counts words read from input fifo)
|
||||
-- Word (4-Byte) counter (Counts words read from input fifo)
|
||||
signal read_cnt : unsigned(13 downto 0) := (others => '0');
|
||||
-- RTPS Submessage ID Latch
|
||||
signal opcode, opcode_next : std_logic_vector(SUBMESSAGE_ID_WIDTH-1 downto 0) := (others => '0');
|
||||
@ -215,7 +215,7 @@ architecture arch of rtps_builtin_endpoint is
|
||||
signal data_in_swapped : std_logic_vector(31 downto 0) := (others => '0');
|
||||
-- Byte Length of string
|
||||
signal string_length, string_length_next : unsigned(31 downto 0) := (others => '0');
|
||||
-- Counter of compared string words (32-bit)
|
||||
-- Counter of compared string words (4-Byte)
|
||||
signal compare_length, compare_length_next : unsigned(29 downto 0) := (others => '0');
|
||||
-- Bitmask of local Endpoint Matches
|
||||
signal endpoint_mask, endpoint_mask_next : std_logic_vector(0 to MAX_ENDPOINTS-1) := (others => '0');
|
||||
@ -390,27 +390,6 @@ architecture arch of rtps_builtin_endpoint is
|
||||
return ret;
|
||||
end function;
|
||||
|
||||
-- Returns the 'data' argument either as is, or with reversed Byte order, depending on the
|
||||
-- 'endianness' argument.
|
||||
function endian_swap( endianness : std_logic;
|
||||
data :std_logic_vector) return std_logic_vector is
|
||||
variable ret : std_logic_vector(data'range);
|
||||
begin
|
||||
-- Assert that Data Signal is Byte aligned
|
||||
assert (data'length mod 8 = 0) severity failure;
|
||||
-- Little Endian
|
||||
if (endianness = '1') then
|
||||
-- Reverse byte Order
|
||||
for i in 0 to (data'length/8)-1 loop
|
||||
ret(i*8+8-1 downto i*8) := data(((data'length/8)-1-i)*8+8-1 downto ((data'length/8)-1-i)*8);
|
||||
end loop;
|
||||
-- Big Endian
|
||||
else
|
||||
ret := data;
|
||||
end if;
|
||||
return ret;
|
||||
end function;
|
||||
|
||||
begin
|
||||
|
||||
--*****COMPONENT INSTANTIATION*****
|
||||
@ -721,7 +700,7 @@ begin
|
||||
|
||||
-- Reset Latches
|
||||
def_addr_next <= (others => '0');
|
||||
meta_addr_next <= DEFAULT_IPv4_MULTICAST_ADDRESS;
|
||||
meta_addr_next <= DEFAULT_IPv4_META_ADDRESS;
|
||||
def_port_next <= (others => '0');
|
||||
meta_port_next <= META_IPv4_MULTICAST_PORT;
|
||||
lease_duration_next <= (others => (others => '0'));
|
||||
@ -840,7 +819,7 @@ begin
|
||||
cnt_next <= 0;
|
||||
|
||||
-- Unmark all Writers
|
||||
endpoint_mask_next(NUM_READERS to MAX_ENDPOINTS-1) <= (others => '0');
|
||||
endpoint_mask_next <= ENDPOINT_READERS;
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
@ -873,7 +852,7 @@ begin
|
||||
cnt_next <= 0;
|
||||
|
||||
-- Unmark all Readers
|
||||
endpoint_mask_next(0 to NUM_READERS-1) <= (others => '0');
|
||||
endpoint_mask_next <= not ENDPOINT_READERS;
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
@ -907,7 +886,7 @@ begin
|
||||
cnt_next <= 0;
|
||||
|
||||
-- Unmark all Writers
|
||||
endpoint_mask_next(NUM_READERS to MAX_ENDPOINTS-1) <= (others => '0');
|
||||
endpoint_mask_next <= ENDPOINT_READERS;
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
@ -960,7 +939,7 @@ begin
|
||||
cnt_next <= 0;
|
||||
|
||||
-- Unmark all Writers
|
||||
endpoint_mask_next(NUM_READERS to MAX_ENDPOINTS-1) <= (others => '0');
|
||||
endpoint_mask_next <= ENDPOINT_READERS;
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
@ -993,7 +972,7 @@ begin
|
||||
cnt_next <= 0;
|
||||
|
||||
-- Unmark all Readers
|
||||
endpoint_mask_next(0 to NUM_READERS-1) <= (others => '0');
|
||||
endpoint_mask_next <= not ENDPOINT_READERS;
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
@ -1027,7 +1006,7 @@ begin
|
||||
cnt_next <= 0;
|
||||
|
||||
-- Unmark all Writers
|
||||
endpoint_mask_next(NUM_READERS to MAX_ENDPOINTS-1) <= (others => '0');
|
||||
endpoint_mask_next <= ENDPOINT_READERS;
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
@ -1907,7 +1886,7 @@ begin
|
||||
null;
|
||||
end case;
|
||||
|
||||
-- NOTE: "compare_length" counts the 32-bit words, while "string_length" contains the total string octets/bytes
|
||||
-- NOTE: "compare_length" counts the 4-Byte words, while "string_length" contains the total string octets/bytes
|
||||
-- End of String (Exit Condition)
|
||||
if ((compare_length & "00") >= string_length) then
|
||||
-- DONE
|
||||
@ -1990,7 +1969,16 @@ begin
|
||||
else
|
||||
meta_port_next <= data_in_swapped(meta_port'length-1 downto 0);
|
||||
end if;
|
||||
-- Locator Addr (IPv4)
|
||||
-- Locator Address 1/4
|
||||
when 2 =>
|
||||
null;
|
||||
-- Locator Address 2/4
|
||||
when 3 =>
|
||||
null;
|
||||
-- Locator Address 3/4
|
||||
when 4 =>
|
||||
null;
|
||||
-- Locator Address 4/4 (IPv4)
|
||||
when 5 =>
|
||||
-- Latch Src Addr
|
||||
if (is_meta_addr = '0') then
|
||||
@ -2547,12 +2535,12 @@ begin
|
||||
-- OUTPUT HEADER
|
||||
-- Src IPv4 Address
|
||||
when 0 =>
|
||||
output_sig <= DEFAULT_IPv4_MULTICAST_ADDRESS;
|
||||
output_sig <= DEFAULT_IPv4_META_ADDRESS;
|
||||
-- Dest IPv4 Address
|
||||
when 1 =>
|
||||
-- Set Default Multicast Announce Address if Participant Announcement
|
||||
if (return_stage = SEND_PARTICIPANT_ANNOUNCEMENT) then
|
||||
output_sig <= DEFAULT_IPv4_MULTICAST_ADDRESS;
|
||||
output_sig <= DEFAULT_IPv4_META_ADDRESS;
|
||||
else
|
||||
output_sig <= mem_participant_data.meta_addr;
|
||||
end if;
|
||||
|
||||
1197
src/rtps_handler.vhd
1197
src/rtps_handler.vhd
File diff suppressed because it is too large
Load Diff
@ -1,516 +0,0 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
use work.math_pkg.all;
|
||||
|
||||
entity rtps_handler is
|
||||
generic(
|
||||
|
||||
);
|
||||
port (
|
||||
clk : in std_logic; -- Input Clock
|
||||
reset : in std_logic; -- Synchronous Reset
|
||||
empty : in std_logic; -- Input FIFO empty flag
|
||||
rd : out std_logic; -- Input FIFO read signal
|
||||
data_in : in std_logic_vector(31 downto 0); -- Input FIFO data signal
|
||||
|
||||
);
|
||||
end entity;
|
||||
|
||||
architecture arch of rtps_handler is
|
||||
|
||||
--*****COMPOENENT DECLARATION******
|
||||
entity adder is
|
||||
generic (
|
||||
PIPELINE_STAGES : integer := 1;
|
||||
DATA_WIDTH : integer := 32
|
||||
);
|
||||
port (
|
||||
clk : in std_logic;
|
||||
reset : in std_logic;
|
||||
cin : in std_logic;
|
||||
A : in std_logic_vector(DATA_WIDTH-1 downto 0);
|
||||
B : in std_logic_vector(DATA_WIDTH-1 downto 0);
|
||||
RES : out std_logic_vector(DATA_WIDTH-1 downto 0);
|
||||
cout : out std_logic
|
||||
);
|
||||
end entity;
|
||||
|
||||
--*****CONSTANT DECLARATION*****
|
||||
-- Minimum Packet Length to consider valid
|
||||
-- 2 UDP Header 32-bit Words, 5 RTPS Header 32-bit Words
|
||||
constant MIN_PACKET_LENGTH : integer := 7;
|
||||
constant MAX_ENDPOINTS : integer := NUM_READERS+NUM_WRITERS;
|
||||
|
||||
|
||||
--GUIDPREFIX(1 downto 0) <= VENDORID;
|
||||
|
||||
--*****TYPE DECLARATION*****
|
||||
type STAGE_TYPE is (INIT, SRC_ADDR, DEST_ADDR, UDP_HEADER_1, UDP_HEADER_2, RTPS_HEADER_1,
|
||||
RTPS_HEADER_2, RTPS_HEADER_3, RTPS_HEADER_4, SKIP_PACKET);
|
||||
|
||||
|
||||
--*****SIGNAL DECLARATION*****
|
||||
-- FSM state
|
||||
signal stage, stage_next : PARSER_STAGE_TYPE := INIT;
|
||||
-- Intermediate input read signal. (Read from output port not allowed)
|
||||
signal rd_sig : std_logic := '0';
|
||||
-- Signal used to reset the word counter
|
||||
signal reset_read_cnt : std_logic;
|
||||
-- 32-bit word counter (Counts words read from input fifo)
|
||||
signal read_cnt : unsigned(13 downto 0) := (others => '0');
|
||||
-- 32-bit aligned total packet length
|
||||
signal packet_length, packet_length_next : unsigned(13 downto 0) := (others => '0');
|
||||
signal sub_length, sub_length_next : unsigned(13 downto 0) := (others => '0');
|
||||
signal align_sig, align_sig_next : std_logic_vector(23 downto 0) := (others => '0');
|
||||
signal aligned_data_in : std_logic_vector(31 downto 0);
|
||||
signal align_offset, align_offset_next : std_logic_vector(1 downto 0) := (others => '0');
|
||||
signal offset_latch, offset_latch_next : std_logic_vector(1 downto 0) := (others => '0');
|
||||
signal src_addr, src_addr_next : std_logic_vector(31 downto 0) := (others => '0');
|
||||
signal src_port, src_port_next : std_logic_vector(15 downto 0) := (others => '0');
|
||||
signal is_multicast, is_multicast_next : std_logic := '0';
|
||||
signal is_metatraffic, is_metatraffic_next : std_logic := '0';
|
||||
signal participant_id, participant_id_next : integer range 0 to NUM_DOMAIN-1 := 0;
|
||||
signal flags, flags_next : std_logic_vector(7 downto 0) := (others => '0');
|
||||
-- General purpose counter
|
||||
signal cnt, cnt_next : integer := 0; --TODO: Range
|
||||
-- Adder Signals
|
||||
signal add_res, add_a, add_b : std_logic_vector(31 downto 0) := (others => '0');
|
||||
signal add_cin, add_cout : std_logic := '0';
|
||||
|
||||
--*****ALIAS DEFINATION*****
|
||||
-- UDP HEADER
|
||||
alias udp_src_port : std_logic_vector(15 downto 0) is data_in(31 downto 16);
|
||||
alias udp_dest_port : std_logic_vector(15 downto 0) is data_in(15 downto 0);
|
||||
alias udp_length : std_logic_vector(15 downto 0) is data_in(31 downto 16);
|
||||
alias udp_checksum : std_logic_vector(15 downto 0) is data_in(15 downto 0);
|
||||
-- RTPS HEADER
|
||||
alias rtps_version : std_logic_vector(15 downto 0) is data_in(31 downto 16);
|
||||
alias rtps_vendorid : std_logic_vector(15 downto 0) is data_in(15 downto 0);
|
||||
-- RTPS SUBMESSAGE HEADER
|
||||
alias rtps_sub_id : std_logic_vector(7 downto 0) is aligned_data_in(31 downto 24);
|
||||
alias rtps_sub_flags : std_logic_vector(7 downto 0) is aligned_data_in(23 downto 16);
|
||||
alias rtps_sub_length : std_logic_vector(7 downto 0) is aligned_data_in(15 downto 0);
|
||||
-- ACKNACK
|
||||
alias rtps_acknack_final : std_logic is rtps_sub_flags(1);
|
||||
-- MISC
|
||||
|
||||
--*****FUNCTION DECLARATION*****
|
||||
|
||||
-- Truncates the lower 2 bits of the input, and if they are not equal zero, adds one to the result.
|
||||
-- This is used to round the byte length to 32-bit word length.
|
||||
function normalize_length (len : std_logic_vector(15 downto 0)) return std_logic_vector is
|
||||
variable tmp : std_logic_vector(13 downto 0) := (others => '0');
|
||||
begin
|
||||
tmp := len(15 downto 2);
|
||||
if(len(1 downto 0) /= "00") then
|
||||
tmp := std_logic_vector(unsigned(tmp) + to_unsigned(1, tmp'length));
|
||||
end if;
|
||||
return tmp;
|
||||
end function;
|
||||
|
||||
-- Depending on the offset argument "off" returns a 32-bit slice from the 56-bit input signal
|
||||
-- This is used to extract 32-bit aligned words from the input signal
|
||||
function align_word ( off : std_logic_vector(1 downto 0),
|
||||
input : std_logic_vector(56 downto 0)) return std_logic_vector is
|
||||
variable ret : std_logic_vector(31 downto 0) := (others => '0');
|
||||
begin
|
||||
case(off) is
|
||||
when "00" =>
|
||||
ret := input(31 downto 0);
|
||||
when "01" =>
|
||||
ret := input(39 downto 8);
|
||||
when "10" =>
|
||||
ret := input(47 downto 16);
|
||||
when "11" =>
|
||||
ret := input(55 downto 24);
|
||||
end case;
|
||||
return ret;
|
||||
end function;
|
||||
|
||||
-- Compares argument 'ref' with every elemant of 'ar', and returns the index of the last match.
|
||||
-- If no match is found, array length is returned.
|
||||
function match_domain_id ( ref : std_logic_vector(UDP_PORT_WIDTH-1 downto 0),
|
||||
ar : IPv4_PORT_TYPE) return integer is
|
||||
variable id : integer := 0;
|
||||
begin
|
||||
id := ar'length(1);
|
||||
for i in 0 to ar'length-1 loop
|
||||
if(ref = ar(i)) then
|
||||
id := i;
|
||||
end if;
|
||||
end loop;
|
||||
return id;
|
||||
end function;
|
||||
|
||||
-- Returns the 'data' argument either as is, or with reversed Byte order, depending on the
|
||||
-- 'endianness' argument.
|
||||
function endian_swap( endianness : std_logic,
|
||||
data :std_logic_vector(31 downto 0)) return std_logic_vector is
|
||||
variable ret : std_logic_vector(31 downto 0);
|
||||
begin
|
||||
-- Little Endian
|
||||
if (endianness = '1') then
|
||||
-- Reverse byte Order
|
||||
for i in 0 to 3 loop
|
||||
ret(i*8+8-1 downto i*8) := data((3-i)*8+8-1 downto (3-i)*8);
|
||||
end loop;
|
||||
-- Big Endian
|
||||
else
|
||||
ret := data;
|
||||
end if;
|
||||
return ret;
|
||||
end function;
|
||||
begin
|
||||
|
||||
rd <= rd_sig;
|
||||
|
||||
align_prc : process(all)
|
||||
variable input : std_logic_vector(55 downto 0) := (others => '0');
|
||||
begin
|
||||
input := align_sig & data_in;
|
||||
case(align_offset) is
|
||||
when "00" =>
|
||||
aligned_data_in <= input(31 downto 0);
|
||||
when "01" =>
|
||||
aligned_data_in <= input(39 downto 8);
|
||||
when "10" =>
|
||||
aligned_data_in <= input(47 downto 16);
|
||||
when "11" =>
|
||||
aligned_data_in <= input(55 downto 24);
|
||||
end case;
|
||||
end process;
|
||||
|
||||
checksum_adder : adder
|
||||
generic map (
|
||||
PIPELINE_STAGES => 1,
|
||||
DATA_WIDTH => 32
|
||||
)
|
||||
port map(
|
||||
clk => clk,
|
||||
reset => reset,
|
||||
cin => add_cin,
|
||||
A => add_a,
|
||||
B => add_b,
|
||||
RES => add_res,
|
||||
cout => add_cout
|
||||
);
|
||||
end entity;
|
||||
|
||||
parse_prc: process(all)
|
||||
variable tmp : integer range 0 to MAX_ENDPOINTS := 0;
|
||||
begin
|
||||
--DEFAULT
|
||||
stage_next <= stage;
|
||||
reset_read_cnt <= '0';
|
||||
add_a <= (others => '0');
|
||||
add_b <= (others => '0');
|
||||
add_cin <= '0';
|
||||
cnt_next <= count;
|
||||
align_offset_next <= align_offset;
|
||||
align_sig_next <= align_sig;
|
||||
packet_length_next <= packet_length;
|
||||
sub_length_next <= sub_length;
|
||||
offset_latch_next <= offset_latch;
|
||||
src_addr_next <= src_addr;
|
||||
is_multicast_next <= is_multicast;
|
||||
src_port_next <= src_port;
|
||||
is_metatraffic_next <= is_metatraffic;
|
||||
participant_id_next <= participant_id;
|
||||
flags_next <= flags;
|
||||
|
||||
case(stage) is
|
||||
-- Initial/Idle State
|
||||
-- Src Addr
|
||||
when SRC_ADDR =>
|
||||
if (empty = '0') then
|
||||
rd_sig <= '1';
|
||||
-- Latch Src Address
|
||||
src_addr_next <= data_in;
|
||||
-- Initiate Checksum Calculation
|
||||
add_a <= data_in;
|
||||
-- TODO: Reset Flags
|
||||
is_multicast_next <= '0';
|
||||
is_metatraffic_next <= '0';
|
||||
-- Next Stage
|
||||
stage_next <= DEST_ADDR;
|
||||
end if;
|
||||
-- Dest Addr
|
||||
when DEST_ADDR =>
|
||||
if (empty = '0') then
|
||||
rd_sig <= '1';
|
||||
-- Check Destination Address
|
||||
if (data_in = IPv4_UNICAST_ADDRESS or data_in = DEFAULT_IPv4_MULTICAST_ADDRESS) then
|
||||
-- Latch if Addr is Multicast
|
||||
if (data_in = DEFAULT_IPv4_MULTICAST_ADDRESS) then
|
||||
is_multicast_next <= '1';
|
||||
end if;
|
||||
-- Checksum Calculation
|
||||
add_a <= data_in;
|
||||
add_b <= add_res;
|
||||
add_cin <= add_cout;
|
||||
-- Next Stage
|
||||
stage_next <= UDP_HEADER_1;
|
||||
-- packet not for us, skip
|
||||
else
|
||||
stage_next <= SKIP_PACKET;
|
||||
end if;
|
||||
else
|
||||
-- Hold Checksum Value
|
||||
add_a <= add_res;
|
||||
end if;
|
||||
when LEN =>
|
||||
-- Reset packet Byte Counter
|
||||
reset_read_cnt <= '1';
|
||||
-- Hold Checksum Value
|
||||
add_a <= add_res;
|
||||
if (empty = '0') then
|
||||
rd_sig <= '1';
|
||||
-- Read Packet Length from input
|
||||
packet_length_next <= unsigned(data_in(13 downto 0));
|
||||
-- Check Packet Length
|
||||
if(to_integer(unsigned(data_in(13 downto 0))) < MIN_PACKET_LENGTH) then
|
||||
stage_next <= SKIP_PACKET;
|
||||
else
|
||||
-- Begin Processing
|
||||
stage_next <= UDP_HEADER_1;
|
||||
end if;
|
||||
end if;
|
||||
-- First UDP Header word (Fields: Src Port, Dest Port)
|
||||
when UDP_HEADER_1 =>
|
||||
if (empty = '0') then
|
||||
rd_sig <= '1';
|
||||
-- Latch Src Port
|
||||
src_port_next <= udp_src_port;
|
||||
-- Checksum Calculation
|
||||
add_a <= data_in;
|
||||
add_b <= add_res;
|
||||
add_cin <= add_cout;
|
||||
-- Default Next Stage
|
||||
stage_next <= SKIP_PACKET;
|
||||
-- Check if Dest Port is valid, if not Skip Packet
|
||||
if (is_multicast = '1') then
|
||||
-- Check if Metatraffic (via Mutlicast)
|
||||
tmp := match_domain_id(udp_dest_port, META_IPv4_MULTICAST_PORT);
|
||||
if (tmp != MAX_ENDPOINTS) then
|
||||
is_metatraffic_next <= '1';
|
||||
participant_id_next <= tmp;
|
||||
stage_next <= UDP_HEADER_2;
|
||||
-- Check if User Traffic (via Multicast)
|
||||
else
|
||||
tmp := match_domain_id(udp_dest_port, USER_IPv4_MULTICAST_PORT);
|
||||
if (tmp != MAX_ENDPOINTS) then
|
||||
stage_next <= UDP_HEADER_2;
|
||||
participant_id_next <= tmp;
|
||||
end if;
|
||||
end if;
|
||||
else
|
||||
-- Check if Metatraffic (via Unicast)
|
||||
tmp := match_domain_id(udp_dest_port, META_IPv4_UNICAST_PORT);
|
||||
if (tmp != MAX_ENDPOINTS) then
|
||||
is_metatraffic_next <= '1';
|
||||
participant_id_next <= tmp;
|
||||
stage_next <= UDP_HEADER_2;
|
||||
-- Check if User Traffic (via Unicast)
|
||||
else
|
||||
tmp := match_domain_id(udp_dest_port, USER_IPv4_UNICAST_PORT);
|
||||
if (tmp != MAX_ENDPOINTS) then
|
||||
stage_next <= UDP_HEADER_2;
|
||||
participant_id_next <= tmp;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
else
|
||||
-- Hold Checksum Value
|
||||
add_a <= add_res;
|
||||
end if;
|
||||
-- Second UDP Header Word (Fields: Length, Checksum)
|
||||
when UDP_HEADER_2 =>
|
||||
if (empty = '0') then
|
||||
rd_sig <= '1';
|
||||
-- If UPD header length does not match actual packet length, skip packet
|
||||
if (normalize_length(udp_length) /= std_logic_vector(packet_length)) then
|
||||
stage_next <= SKIP_PACKET;
|
||||
else
|
||||
-- Checksum Calculation
|
||||
add_a <= (udp_length & x"0000");
|
||||
add_b <= add_res;
|
||||
add_cin <= add_cout;
|
||||
-- Next Stage
|
||||
stage_next <= RTPS_HEADER_1;
|
||||
end if;
|
||||
else
|
||||
-- Hold Checksum Value
|
||||
add_a <= add_res;
|
||||
end if;
|
||||
-- First RTPS Header word (Fields: Protocolld)
|
||||
when RTPS_HEADER_1 =>
|
||||
if (empty = '0') then
|
||||
rd_sig <= '1';
|
||||
-- If underlying Protocol is not RTPS, skip packet
|
||||
if(data_in /= PROTOCOLLD_RTPS) then
|
||||
stage_next <= SKIP_PACKET;
|
||||
-- Continue Parsing
|
||||
else
|
||||
-- Checksum Calculation
|
||||
add_a <= data_in;
|
||||
add_b <= add_res;
|
||||
add_cin <= add_cout;
|
||||
-- Next Stage
|
||||
stage_next <= RTPS_HEADER_2;
|
||||
end if;
|
||||
else
|
||||
-- Hold Checksum Value
|
||||
add_a <= add_res;
|
||||
end if;
|
||||
-- Second RTPS Header word (Fields: Protocol Version, Vendor ID)
|
||||
when RTPS_HEADER_2 =>
|
||||
if (empty = '0') then
|
||||
rd_sig <= '1';
|
||||
-- If RTPS Protocol Major Version is not 2, skip packet
|
||||
if(rtps_version(15 downto 8) /= PROTOCOLVERSION_2_4(15 downto 8)) then
|
||||
stage_next <= SKIP_PACKET;
|
||||
-- Continue Parsing
|
||||
else
|
||||
-- Checksum Calculation
|
||||
add_a <= data_in;
|
||||
add_b <= add_res;
|
||||
add_cin <= add_cout;
|
||||
-- Reset GP Counter
|
||||
cnt_next <= 1;
|
||||
-- Next Stage
|
||||
stage_next <= RTPS_HEADER_3;
|
||||
|
||||
end if;
|
||||
else
|
||||
-- Hold Checksum Value
|
||||
add_a <= add_res;
|
||||
end if;
|
||||
-- Rest of RTPS Header (Fields: GUID Prefix)
|
||||
when RTPS_HEADER_3 =>
|
||||
if (empty = '0') then
|
||||
rd_sig <= '1';
|
||||
-- Sender GUID_Prefix
|
||||
TODO <= data_in;
|
||||
-- Checksum Calculation
|
||||
add_a <= data_in;
|
||||
add_b <= add_res;
|
||||
add_cin <= add_cout;
|
||||
if (cnt = GUIDPREFIX_WIDTH/32) then
|
||||
-- Next Stage
|
||||
stage_next <= RTPS_SUB_HEADER;
|
||||
else
|
||||
cnt_next <= cnt + 1;
|
||||
end if;
|
||||
else
|
||||
-- Hold Checksum Value
|
||||
add_a <= add_res;
|
||||
end if;
|
||||
-- NOTE: From here on, due to the nature of the RTPS Protocol, 32-bit word alignement
|
||||
-- is not guaranteed, and has to be handled.
|
||||
-- RTPS Submessage Header (Fields: Submessage ID, Flags, Submessage Length)
|
||||
when RTPS_SUB_HEADER =>
|
||||
if (empty = '0') then
|
||||
rd_sig <= '1';
|
||||
|
||||
case (rtps_sub_id) is
|
||||
when SID_ACKNACK =>
|
||||
-- Ignore Submessage if Final Flag not set
|
||||
if (rtps_acknack_final = '1') then
|
||||
-- Next Stage
|
||||
stage_next <= ACKNACK_1;
|
||||
else
|
||||
-- Skip Submessage
|
||||
stage_next <= SKIP_SUB;
|
||||
end if;
|
||||
when SID_PAD =>
|
||||
when SID_HEARTBEAT =>
|
||||
when SID_GAP =>
|
||||
when SID_INFO_TS => --state
|
||||
when SID_INFO_SRC => --state
|
||||
when SID_INFO_REPLY_IP4 =>
|
||||
when SID_INFO_DST => --state
|
||||
when SID_INFO_REPLY => --state
|
||||
when SID_NACK_FRAG =>
|
||||
when SID_HEARTBEAT_FRAG =>
|
||||
when SID_DATA =>
|
||||
when SID_DATA_FRAG =>
|
||||
-- Unknown ID, skip submessage
|
||||
when others =>
|
||||
stage_next <= SKIP_SUB;
|
||||
end case;
|
||||
-- Checksum Calculation
|
||||
add_a <= data_in;
|
||||
add_b <= add_res;
|
||||
add_cin <= add_cout;
|
||||
-- Store Submessage Length
|
||||
-- TODO: The below conditional +1 adder should be solved with a carry-in
|
||||
sub_length_next <= packet_length + unsigned(normalize_length(rtps_sub_length));
|
||||
-- Store Byte offset of next Header
|
||||
offset_latch_next <= unsigned(align_offset) + unsigned(rtps_sub_length(1 downto 0));
|
||||
-- Next Stage
|
||||
align_sig_next <= data_in(23 downto 0);
|
||||
else
|
||||
-- Hold Checksum Value
|
||||
add_a <= add_res;
|
||||
end if;
|
||||
when ACKNACK_1 =>
|
||||
if (empty = '0') then
|
||||
rd_sig <= '1';
|
||||
--TODO
|
||||
-- Checksum Calculation
|
||||
add_a <= data_in;
|
||||
add_b <= add_res;
|
||||
add_cin <= add_cout;
|
||||
-- Next Stage
|
||||
align_sig_next <= data_in(23 downto 0);
|
||||
else
|
||||
-- Hold Checksum Value
|
||||
add_a <= add_res;
|
||||
end if;
|
||||
when SKIP_PACKET =>
|
||||
if (empty = '0') then
|
||||
rd_sig <= '1';
|
||||
-- End of Packet
|
||||
if (read_cnt = packet_length) then
|
||||
-- Continue parsing next packet
|
||||
stage_next <= SRC_ADDR;
|
||||
end if;
|
||||
end if;
|
||||
when SKIP_SUB =>
|
||||
if (empty = '0') then
|
||||
rd_sig <= '1';
|
||||
-- End of Packet (No further Submessages)
|
||||
if (read_cnt = packet_length) then
|
||||
-- Continue parsing next packet
|
||||
stage_next <= SRC_ADDR;
|
||||
-- End of Submessage
|
||||
elsif (read_cnt = sub_length) then
|
||||
-- Begin parsing of next submessage
|
||||
stage_next <= RTPS_SUB_HEADER;
|
||||
-- Fix alignement
|
||||
align_offset <= offset_latch;
|
||||
end if;
|
||||
end if;
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
end process;
|
||||
|
||||
-- Process responsible for counting read words
|
||||
-- This process uses the actual FIFO read signals to determine reads
|
||||
word_counter_prc : process(clk, reset)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
-- Reset Read counter
|
||||
if (reset = '1' or reset_read_cnt = '1') then
|
||||
read_cnt <= to_unsigned(1, read_cnt'length);
|
||||
-- Increment read counter each time rd is high
|
||||
elsif (rd_sig = '1' or buffer_ren = '1') then
|
||||
read_cnt <= read_cnt + to_unsigned(1, read_cnt'length);
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end architecture;
|
||||
@ -10,7 +10,7 @@ package rtps_package is
|
||||
|
||||
--*****USER CONFIG*****
|
||||
-- Unicast IPv4 Address used by all RTPS Entities [Default 192.168.0.80]
|
||||
constant IPv4_UNICAST_ADDRESS : std_logic_vector(31 downto 0) := x"C0A80080";
|
||||
constant DEFAULT_IPv4_ADDRESS : std_logic_vector(31 downto 0) := x"C0A80080";
|
||||
-- Number of RTPS Writer Endpoints
|
||||
constant NUM_WRITERS : natural := 0;
|
||||
-- Number of RTPS Reader Endpoints
|
||||
@ -142,7 +142,7 @@ package rtps_package is
|
||||
--*****DDSI-RTPS 2.3*****
|
||||
|
||||
-- Default Multicast Ipv4 Address (239.255.0.1)
|
||||
constant DEFAULT_IPv4_MULTICAST_ADDRESS : std_logic_vector(31 downto 0) := x"EFFF0001";
|
||||
constant DEFAULT_IPv4_META_ADDRESS : std_logic_vector(31 downto 0) := x"EFFF0001";
|
||||
|
||||
constant GUIDPREFIX_WIDTH : natural := 96;
|
||||
constant PROTOCOLVERSION_WIDTH : natural := 16;
|
||||
@ -369,6 +369,10 @@ package rtps_package is
|
||||
length : natural;
|
||||
end record;
|
||||
|
||||
-- TODO: Use this everywhere
|
||||
-- Marks the Reader Endpoint in the Endpoint Array
|
||||
constant ENDPOINT_READERS : std_logic_vector(0 to MAX_ENDPOINTS-1) := (0 to NUM_READERS-1 => '1', others => '0');
|
||||
|
||||
constant READER_ENDPOINT_DATA : OUTPUT_DATA_TYPE; --Deferred to package body
|
||||
constant WRITER_ENDPOINT_DATA : OUTPUT_DATA_TYPE; --Deferred to package body
|
||||
constant PARTICIPANT_DATA : OUTPUT_DATA_TYPE; --Deferred to package body
|
||||
@ -403,6 +407,10 @@ package rtps_package is
|
||||
function min(L, R : DOUBLE_WORD_ARRAY) return DOUBLE_WORD_ARRAY;
|
||||
function max(L, R : DOUBLE_WORD_ARRAY) return DOUBLE_WORD_ARRAY;
|
||||
|
||||
function endian_swap(endianness : std_logic; data : std_logic_vector) return std_logic_vector;
|
||||
function endian_swap(endianness : std_logic; data : unsigned) return unsigned;
|
||||
|
||||
|
||||
end package;
|
||||
|
||||
package body rtps_package is
|
||||
@ -910,7 +918,7 @@ package body rtps_package is
|
||||
len := len + 1;
|
||||
ret.data(ind+len) := (others => '0');
|
||||
len := len + 1;
|
||||
ret.data(ind+len) := DEFAULT_IPv4_MULTICAST_ADDRESS;
|
||||
ret.data(ind+len) := DEFAULT_IPv4_META_ADDRESS;
|
||||
-- METATRAFFIC MULTICAST LOCATOR
|
||||
len := len + 1;
|
||||
ret.data(ind+len) := PID_METATRAFFIC_MULTICAST_LOCATOR & std_logic_vector(to_unsigned(24, 16));
|
||||
@ -926,7 +934,7 @@ package body rtps_package is
|
||||
len := len + 1;
|
||||
ret.data(ind+len) := (others => '0');
|
||||
len := len + 1;
|
||||
ret.data(ind+len) := DEFAULT_IPv4_MULTICAST_ADDRESS;
|
||||
ret.data(ind+len) := DEFAULT_IPv4_META_ADDRESS;
|
||||
-- DEFAULT UNICAST LOCATOR
|
||||
len := len + 1;
|
||||
ret.data(ind+len) := PID_DEFAULT_UNICAST_LOCATOR & std_logic_vector(to_unsigned(24, 16));
|
||||
@ -942,7 +950,7 @@ package body rtps_package is
|
||||
len := len + 1;
|
||||
ret.data(ind+len) := (others => '0');
|
||||
len := len + 1;
|
||||
ret.data(ind+len) := DEFAULT_IPv4_MULTICAST_ADDRESS;
|
||||
ret.data(ind+len) := DEFAULT_IPv4_META_ADDRESS;
|
||||
-- DEFAULT MULTICAST LOCATOR
|
||||
len := len + 1;
|
||||
ret.data(ind+len) := PID_METATRAFFIC_MULTICAST_LOCATOR & std_logic_vector(to_unsigned(24, 16));
|
||||
@ -958,7 +966,7 @@ package body rtps_package is
|
||||
len := len + 1;
|
||||
ret.data(ind+len) := (others => '0');
|
||||
len := len + 1;
|
||||
ret.data(ind+len) := DEFAULT_IPv4_MULTICAST_ADDRESS;
|
||||
ret.data(ind+len) := DEFAULT_IPv4_META_ADDRESS;
|
||||
-- LEASE DURATION
|
||||
if (PARTICIPANT_LEASE_DURATION /= DEFAULT_PARTICIPANT_LEASE_DURATION) then
|
||||
len := len + 1;
|
||||
@ -1155,4 +1163,31 @@ package body rtps_package is
|
||||
return ret;
|
||||
end function;
|
||||
|
||||
-- Returns the 'data' argument either as is, or with reversed Byte order, depending on the
|
||||
-- 'endianness' argument.
|
||||
function endian_swap(endianness : std_logic; data : std_logic_vector) return std_logic_vector is
|
||||
variable ret : std_logic_vector(data'range);
|
||||
begin
|
||||
-- Assert that Data Signal is Byte aligned
|
||||
assert (data'length mod 8 = 0) severity failure;
|
||||
-- Little Endian
|
||||
if (endianness = '1') then
|
||||
-- Reverse byte Order
|
||||
for i in 0 to (data'length/8)-1 loop
|
||||
ret(i*8+8-1 downto i*8) := data(((data'length/8)-1-i)*8+8-1 downto ((data'length/8)-1-i)*8);
|
||||
end loop;
|
||||
-- Big Endian
|
||||
else
|
||||
ret := data;
|
||||
end if;
|
||||
return ret;
|
||||
end function;
|
||||
|
||||
-- Returns the 'data' argument either as is, or with reversed Byte order, depending on the
|
||||
-- 'endianness' argument.
|
||||
function endian_swap(endianness : std_logic; data : unsigned) return unsigned is
|
||||
begin
|
||||
return unsigned(endian_swap(endianness, std_logic_vector(data)));
|
||||
end function;
|
||||
|
||||
end package body;
|
||||
|
||||
41
src/test.vhd
41
src/test.vhd
@ -13,41 +13,32 @@ entity test is
|
||||
port (
|
||||
clk : in std_logic; -- Input Clock
|
||||
reset : in std_logic; -- Synchronous Reset
|
||||
input : in std_logic_vector(1 downto 0);
|
||||
cnt : in natural range 0 to 12;
|
||||
output : out unsigned(5 downto 0)
|
||||
input : in std_logic_vector(31 downto 0);
|
||||
cnt : out natural range 0 to MAX_ENDPOINTS
|
||||
);
|
||||
end entity;
|
||||
|
||||
architecture arch of test is
|
||||
|
||||
constant BUILD : std_logic := '0';
|
||||
|
||||
signal output_sig : unsigned(5 downto 0) := (others => '0');
|
||||
-- Compares argument 'ref' with every element of 'ar', and returns the index of the last match.
|
||||
-- If no match is found, array length is returned.
|
||||
function match_id_endpoint (ref : std_logic_vector(ENTITYID_WIDTH-1 downto 0); ar : ENTITYID_TYPE) return natural is
|
||||
variable id : natural := 0;
|
||||
begin
|
||||
id := ar'length;
|
||||
for i in 0 to ar'length-1 loop
|
||||
if(ref = ar(i)) then
|
||||
id := i;
|
||||
end if;
|
||||
end loop;
|
||||
return id;
|
||||
end function;
|
||||
|
||||
begin
|
||||
output <= output_sig;
|
||||
|
||||
process(all)
|
||||
begin
|
||||
output_sig <= (others => '0');
|
||||
|
||||
if (cnt < PARTICIPANT_DATA.length) then
|
||||
output_sig <= unsigned(PARTICIPANT_DATA.data(cnt))(5 downto 0);
|
||||
end if;
|
||||
|
||||
-- case (input) is
|
||||
-- when "00" =>
|
||||
-- output_sig <= to_unsigned(1,6);
|
||||
-- when "01" =>
|
||||
-- output_sig <= to_unsigned(2,6);
|
||||
-- when "10" =>
|
||||
-- output_sig <= to_unsigned(3,6);
|
||||
-- when "11" =>
|
||||
-- if (BUILD = '1') then
|
||||
-- output_sig <= to_unsigned(1,6) + cnt;
|
||||
-- end if;
|
||||
-- end case;
|
||||
cnt <= match_id_endpoint(input, ENTITYID);
|
||||
end process;
|
||||
|
||||
|
||||
|
||||
@ -38,7 +38,7 @@
|
||||
|
||||
set_global_assignment -name FAMILY "Cyclone V"
|
||||
set_global_assignment -name DEVICE 5CSEBA6U23I7
|
||||
set_global_assignment -name TOP_LEVEL_ENTITY rtps_builtin_endpoint
|
||||
set_global_assignment -name TOP_LEVEL_ENTITY test
|
||||
set_global_assignment -name ORIGINAL_QUARTUS_VERSION 18.1.0
|
||||
set_global_assignment -name PROJECT_CREATION_TIME_DATE "12:05:11 MAY 29, 2020"
|
||||
set_global_assignment -name LAST_QUARTUS_VERSION "18.1.0 Lite Edition"
|
||||
@ -48,13 +48,14 @@ set_global_assignment -name MAX_CORE_JUNCTION_TEMP 100
|
||||
set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR 256
|
||||
set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "23 MM HEAT SINK WITH 200 LFPM AIRFLOW"
|
||||
set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)"
|
||||
set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
|
||||
set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top
|
||||
set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
|
||||
set_global_assignment -name VHDL_FILE ../../src/rtps_handler.vhd -hdl_version VHDL_2008
|
||||
set_global_assignment -name VHDL_FILE ../../src/single_port_ram.vhd -hdl_version VHDL_2008
|
||||
set_global_assignment -name VHDL_FILE ../../src/rtps_builtin_endpoint.vhd -hdl_version VHDL_2008
|
||||
set_global_assignment -name VHDL_FILE ../../src/rtps_package.vhd -hdl_version VHDL_2008
|
||||
set_global_assignment -name VHDL_FILE ../../src/test_package.vhd -hdl_version VHDL_2008
|
||||
set_global_assignment -name VHDL_FILE ../../src/test.vhd -hdl_version VHDL_2008
|
||||
set_global_assignment -name VHDL_FILE ../../src/math_pkg.vhd -hdl_version VHDL_2008
|
||||
set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
|
||||
set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top
|
||||
set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
|
||||
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
|
||||
Loading…
Reference in New Issue
Block a user