From 4947e56791f88b3ad7504a9508fcd0733a364551 Mon Sep 17 00:00:00 2001 From: Romain Broucquart <romain.broucquart@synchrotron-soleil.fr> Date: Wed, 27 Apr 2022 18:41:40 +0200 Subject: [PATCH] Add a packet filter module --- hdl/combpm_packet_filter.vhd | 255 +++++++++++++++++++++++ hdl/pkg_combpm_stream.vhd | 82 ++++++++ tcl/generate_combpm_packet_filter_ip.tcl | 36 ++++ 3 files changed, 373 insertions(+) create mode 100644 hdl/combpm_packet_filter.vhd create mode 100644 hdl/pkg_combpm_stream.vhd create mode 100644 tcl/generate_combpm_packet_filter_ip.tcl diff --git a/hdl/combpm_packet_filter.vhd b/hdl/combpm_packet_filter.vhd new file mode 100644 index 0000000..922b7a0 --- /dev/null +++ b/hdl/combpm_packet_filter.vhd @@ -0,0 +1,255 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +use work.pkg_combpm_stream.all; + +entity combpm_packet_filter is + port( + axis_clk : in std_logic; + axi_clk : in std_logic; + axis_rst_n : in std_logic; + axi_rst_n : in std_logic; + + -- AXIS SLAVE INTERFACE + s_axis_tdest : in std_logic_vector(C_TDEST_W-1 downto 0); + s_axis_tdata : in std_logic_vector(C_TDATA_W-1 downto 0); + s_axis_tlast : in std_logic; + s_axis_tvalid : in std_logic; + s_axis_tready : out std_logic; + + -- AXIS SLAVE INTERFACE + m_axis_tdest : out std_logic_vector(C_TDEST_W-1 downto 0); + m_axis_tdata : out std_logic_vector(C_TDATA_W-1 downto 0); + m_axis_tlast : out std_logic; + m_axis_tvalid : out std_logic; + m_axis_tready : in std_logic; + + -- AXI bus interface + s_axi_awaddr : IN STD_LOGIC_VECTOR(11 DOWNTO 0); + s_axi_awlen : IN STD_LOGIC_VECTOR(7 DOWNTO 0); + s_axi_awsize : IN STD_LOGIC_VECTOR(2 DOWNTO 0); + s_axi_awburst : IN STD_LOGIC_VECTOR(1 DOWNTO 0); + s_axi_awlock : IN STD_LOGIC; + s_axi_awcache : IN STD_LOGIC_VECTOR(3 DOWNTO 0); + s_axi_awprot : IN STD_LOGIC_VECTOR(2 DOWNTO 0); + s_axi_awvalid : IN STD_LOGIC; + s_axi_awready : OUT STD_LOGIC; + s_axi_wdata : IN STD_LOGIC_VECTOR(31 DOWNTO 0); + s_axi_wstrb : IN STD_LOGIC_VECTOR(3 DOWNTO 0); + s_axi_wlast : IN STD_LOGIC; + s_axi_wvalid : IN STD_LOGIC; + s_axi_wready : OUT STD_LOGIC; + s_axi_bresp : OUT STD_LOGIC_VECTOR(1 DOWNTO 0); + s_axi_bvalid : OUT STD_LOGIC; + s_axi_bready : IN STD_LOGIC; + s_axi_araddr : IN STD_LOGIC_VECTOR(11 DOWNTO 0); + s_axi_arlen : IN STD_LOGIC_VECTOR(7 DOWNTO 0); + s_axi_arsize : IN STD_LOGIC_VECTOR(2 DOWNTO 0); + s_axi_arburst : IN STD_LOGIC_VECTOR(1 DOWNTO 0); + s_axi_arlock : IN STD_LOGIC; + s_axi_arcache : IN STD_LOGIC_VECTOR(3 DOWNTO 0); + s_axi_arprot : IN STD_LOGIC_VECTOR(2 DOWNTO 0); + s_axi_arvalid : IN STD_LOGIC; + s_axi_arready : OUT STD_LOGIC; + s_axi_rdata : OUT STD_LOGIC_VECTOR(31 DOWNTO 0); + s_axi_rresp : OUT STD_LOGIC_VECTOR(1 DOWNTO 0); + s_axi_rlast : OUT STD_LOGIC; + s_axi_rvalid : OUT STD_LOGIC; + s_axi_rready : IN STD_LOGIC + ); +end combpm_packet_filter; + + +architecture rtl of combpm_packet_filter is + + --------------------------- + -- COMPONENT DECLARATION -- + --------------------------- + COMPONENT combpm_packet_filter_axi_bram_ctrl + PORT ( + s_axi_aclk : IN STD_LOGIC; + s_axi_aresetn : IN STD_LOGIC; + s_axi_awaddr : IN STD_LOGIC_VECTOR(11 DOWNTO 0); + s_axi_awlen : IN STD_LOGIC_VECTOR(7 DOWNTO 0); + s_axi_awsize : IN STD_LOGIC_VECTOR(2 DOWNTO 0); + s_axi_awburst : IN STD_LOGIC_VECTOR(1 DOWNTO 0); + s_axi_awlock : IN STD_LOGIC; + s_axi_awcache : IN STD_LOGIC_VECTOR(3 DOWNTO 0); + s_axi_awprot : IN STD_LOGIC_VECTOR(2 DOWNTO 0); + s_axi_awvalid : IN STD_LOGIC; + s_axi_awready : OUT STD_LOGIC; + s_axi_wdata : IN STD_LOGIC_VECTOR(31 DOWNTO 0); + s_axi_wstrb : IN STD_LOGIC_VECTOR(3 DOWNTO 0); + s_axi_wlast : IN STD_LOGIC; + s_axi_wvalid : IN STD_LOGIC; + s_axi_wready : OUT STD_LOGIC; + s_axi_bresp : OUT STD_LOGIC_VECTOR(1 DOWNTO 0); + s_axi_bvalid : OUT STD_LOGIC; + s_axi_bready : IN STD_LOGIC; + s_axi_araddr : IN STD_LOGIC_VECTOR(11 DOWNTO 0); + s_axi_arlen : IN STD_LOGIC_VECTOR(7 DOWNTO 0); + s_axi_arsize : IN STD_LOGIC_VECTOR(2 DOWNTO 0); + s_axi_arburst : IN STD_LOGIC_VECTOR(1 DOWNTO 0); + s_axi_arlock : IN STD_LOGIC; + s_axi_arcache : IN STD_LOGIC_VECTOR(3 DOWNTO 0); + s_axi_arprot : IN STD_LOGIC_VECTOR(2 DOWNTO 0); + s_axi_arvalid : IN STD_LOGIC; + s_axi_arready : OUT STD_LOGIC; + s_axi_rdata : OUT STD_LOGIC_VECTOR(31 DOWNTO 0); + s_axi_rresp : OUT STD_LOGIC_VECTOR(1 DOWNTO 0); + s_axi_rlast : OUT STD_LOGIC; + s_axi_rvalid : OUT STD_LOGIC; + s_axi_rready : IN STD_LOGIC; + bram_rst_a : OUT STD_LOGIC; + bram_clk_a : OUT STD_LOGIC; + bram_en_a : OUT STD_LOGIC; + bram_we_a : OUT STD_LOGIC_VECTOR(3 DOWNTO 0); + bram_addr_a : OUT STD_LOGIC_VECTOR(7 DOWNTO 0); + bram_wrdata_a : OUT STD_LOGIC_VECTOR(31 DOWNTO 0); + bram_rddata_a : IN STD_LOGIC_VECTOR(31 DOWNTO 0) + ); + END COMPONENT; + + COMPONENT combpm_packet_filter_blk_mem + PORT ( + clka : IN STD_LOGIC; + ena : IN STD_LOGIC; + wea : IN STD_LOGIC_VECTOR(3 DOWNTO 0); + addra : IN STD_LOGIC_VECTOR(7 DOWNTO 0); + dina : IN STD_LOGIC_VECTOR(31 DOWNTO 0); + douta : OUT STD_LOGIC_VECTOR(31 DOWNTO 0); + clkb : IN STD_LOGIC; + enb : IN STD_LOGIC; + web : IN STD_LOGIC_VECTOR(0 DOWNTO 0); + addrb : IN STD_LOGIC_VECTOR(9 DOWNTO 0); + dinb : IN STD_LOGIC_VECTOR(7 DOWNTO 0); + doutb : OUT STD_LOGIC_VECTOR(7 DOWNTO 0) + ); + END COMPONENT; + + ------------------------ + -- SIGNAL DECLARATION -- + ------------------------ + signal in_packet : t_combpm_axis_packet; + signal out_packet : t_combpm_axis_packet; + + signal bram_clk_a : STD_LOGIC; + signal bram_en_a : STD_LOGIC; + signal bram_we_a : STD_LOGIC_VECTOR(3 DOWNTO 0); + signal bram_addr_a : STD_LOGIC_VECTOR(7 DOWNTO 0); + signal bram_wrdata_a : STD_LOGIC_VECTOR(31 DOWNTO 0); + signal bram_rddata_a : STD_LOGIC_VECTOR(31 DOWNTO 0); + + signal table_data : std_logic_vector(7 downto 0); + + signal tvalid_r : std_logic_vector(1 downto 0); + signal zero_packet : std_logic_vector(C_TDATA_W-1 downto 0); + +begin + + zero_packet <= (others => '0'); + + -- always ready + s_axis_tready <= '1'; + + ---------------------- + -- STREAM REGISTERS -- + ---------------------- + p_main: process(axis_clk, axis_rst_n) + begin + if axis_rst_n = '0' then + in_packet <= slv2combpmpacket(zero_packet); + out_packet <= slv2combpmpacket(zero_packet); + + elsif rising_edge(axis_clk) then + -- Register input packet + if s_axis_tvalid = '1' then + in_packet <= slv2combpmpacket(s_axis_tdata); + end if; + + tvalid_r(tvalid_r'left downto 1) <= tvalid_r(tvalid_r'left-1 downto 0); + tvalid_r(0) <= s_axis_tvalid; + + out_packet <= in_packet; + + end if; + end process; + + ----------------- + -- AXIS OUTPUT -- + ----------------- + m_axis_tdest <= std_logic_vector(risize(unsigned(table_data(6 downto 0)), C_TDEST_W)); + m_axis_tdata <= combpmpacket2slv(out_packet); + m_axis_tlast <= '1'; -- Packet is one tdata only + m_axis_tvalid <= tvalid_r(tvalid_r'left) and table_data(7); + + --------------------- + -- BRAM CONTROLLER -- + --------------------- + inst_bram_ctrl : combpm_packet_filter_axi_bram_ctrl + port map ( + s_axi_aclk => axi_clk, + s_axi_aresetn => axi_rst_n, + + s_axi_awaddr => s_axi_awaddr, + s_axi_awlen => s_axi_awlen, + s_axi_awsize => s_axi_awsize, + s_axi_awburst => s_axi_awburst, + s_axi_awlock => s_axi_awlock, + s_axi_awcache => s_axi_awcache, + s_axi_awprot => s_axi_awprot, + s_axi_awvalid => s_axi_awvalid, + s_axi_awready => s_axi_awready, + s_axi_wdata => s_axi_wdata, + s_axi_wstrb => s_axi_wstrb, + s_axi_wlast => s_axi_wlast, + s_axi_wvalid => s_axi_wvalid, + s_axi_wready => s_axi_wready, + s_axi_bresp => s_axi_bresp, + s_axi_bvalid => s_axi_bvalid, + s_axi_bready => s_axi_bready, + s_axi_araddr => s_axi_araddr, + s_axi_arlen => s_axi_arlen, + s_axi_arsize => s_axi_arsize, + s_axi_arburst => s_axi_arburst, + s_axi_arlock => s_axi_arlock, + s_axi_arcache => s_axi_arcache, + s_axi_arprot => s_axi_arprot, + s_axi_arvalid => s_axi_arvalid, + s_axi_arready => s_axi_arready, + s_axi_rdata => s_axi_rdata, + s_axi_rresp => s_axi_rresp, + s_axi_rlast => s_axi_rlast, + s_axi_rvalid => s_axi_rvalid, + s_axi_rready => s_axi_rready, + + bram_rst_a => open, + bram_clk_a => bram_clk_a, + bram_en_a => bram_en_a, + bram_we_a => bram_we_a, + bram_addr_a => bram_addr_a, + bram_wrdata_a => bram_wrdata_a, + bram_rddata_a => bram_rddata_a + ); + + ------------------- + -- BRAM INSTANCE -- + ------------------- + inst_bram : combpm_packet_filter_blk_mem + port map( + clka => bram_clk_a, + ena => bram_en_a, + wea => bram_we_a, + addra => bram_addr_a, + dina => bram_wrdata_a, + douta => bram_rddata_a, + clkb => axis_clk, + enb => '1', + web => '0', + addrb => in_packet.bpm_id(9 downto 0), + dinb => (others => '0'), + doutb => table_data + ); + +end architecture rtl; diff --git a/hdl/pkg_combpm_stream.vhd b/hdl/pkg_combpm_stream.vhd new file mode 100644 index 0000000..5d09617 --- /dev/null +++ b/hdl/pkg_combpm_stream.vhd @@ -0,0 +1,82 @@ +library ieee; +use ieee.std_logic_1164.all; + +package pkg_combpm_stream is + + -- CONSTANT + constant C_TDEST_W : natural := 7; + constant C_TDATA_W : natural := 128; + + --------------------------------- + -- AXIS MASTER/SLAVE INTERFACE -- + --------------------------------- + type t_combpm_axis_m2s is record + tdest : std_logic_vector(C_TDEST_W-1 downto 0); + tdata : std_logic_vector(C_TDATA_W-1 downto 0); + tlast : std_logic; + tvalid : std_logic; + ---tid : std_logic_vector(0 downto 0); + --tuser : std_logic_vector(0 downto 0); + --tstrb : std_logic_vector(15 downto 0); + --tkeep : std_logic_vector(15 downto 0); + end record t_combpm_axis_m2s; + + type t_combpm_axis_s2m is record + tready : std_logic; + end record t_combpm_axis_s2m; + + subtype t_combpm_m_axis_out is t_combpm_axis_m2s; + subtype t_combpm_s_axis_in is t_combpm_axis_m2s; + subtype t_combpm_m_axis_in is t_combpm_axis_s2m; + subtype t_combpm_s_axis_out is t_combpm_axis_s2m; + + ------------------------ + -- AXIS STREAM PACKET -- + ------------------------ + type t_combpm_axis_packet is record + pos_x : std_logic_vector(31 downto 0); + pos_y : std_logic_vector(31 downto 0); + bpm_id : std_logic_vector(15 downto 0); + mc_timestamp : std_logic_vector(39 downto 0); + fa_seq : std_logic_vector(7 downto 0); + end record t_combpm_axis_packet; + + function slv2combpmpacket( + signal tdata : std_logic_vector(C_TDATA_W-1 downto 0) + ) + return t_combpm_axis_packet; + + function combpmpacket2slv( + signal packet : t_combpm_axis_packet + ) + return std_logic_vector; + + +end package; + +package body pkg_combpm_stream is + + + function slv2combpmpacket( + signal tdata : std_logic_vector(C_TDATA_W-1 downto 0) + ) + return t_combpm_axis_packet is + variable packet : t_combpm_axis_packet; + begin + packet.pos_x := tdata(31 downto 0); + packet.pos_y := tdata(63 downto 32); + packet.bpm_id := tdata(79 downto 64); + packet.mc_timestamp := tdata(119 downto 80); + packet.fa_seq := tdata(127 downto 120); + return packet; + end function; + + function combpmpacket2slv( + signal packet : t_combpm_axis_packet + ) + return std_logic_vector is + begin + return packet.fa_seq & packet.mc_timestamp & packet.bpm_id & packet.pos_y & packet.pos_x; + end function; + +end package body; diff --git a/tcl/generate_combpm_packet_filter_ip.tcl b/tcl/generate_combpm_packet_filter_ip.tcl new file mode 100644 index 0000000..12d935a --- /dev/null +++ b/tcl/generate_combpm_packet_filter_ip.tcl @@ -0,0 +1,36 @@ +set xcipath [create_ip -name axi_bram_ctrl -vendor xilinx.com -library ip -version 4.1 -module_name combpm_packet_filter_axi_bram_ctrl] + +set_property -dict [list \ + CONFIG.PROTOCOL {AXI4} \ + CONFIG.SUPPORTS_NARROW_BURST {0} \ + CONFIG.SINGLE_PORT_BRAM {1} \ + CONFIG.ECC_TYPE {0} \ + CONFIG.BMG_INSTANCE {EXTERNAL} \ + CONFIG.MEM_DEPTH {16384} \ + ] [get_ips combpm_packet_filter_axi_bram_ctrl] + +set_property GENERATE_SYNTH_CHECKPOINT 0 [get_files $xcipath] + +set xcipath [create_ip -name blk_mem_gen -vendor xilinx.com -library ip -version 8.4 -module_name combpm_packet_filter_blk_mem] + +set_property -dict [list \ + CONFIG.Memory_Type {True_Dual_Port_RAM} \ + CONFIG.Use_Byte_Write_Enable {true} \ + CONFIG.Byte_Size {8} \ + CONFIG.Write_Width_A {32} \ + CONFIG.Write_Depth_A {16384} \ + CONFIG.Read_Width_A {32} \ + CONFIG.Operating_Mode_A {WRITE_FIRST} \ + CONFIG.Write_Width_B {8} \ + CONFIG.Read_Width_B {8} \ + CONFIG.Operating_Mode_B {WRITE_FIRST} \ + CONFIG.Enable_B {Use_ENB_Pin} \ + CONFIG.Register_PortA_Output_of_Memory_Primitives {false} \ + CONFIG.Register_PortA_Output_of_Memory_Core {false} \ + CONFIG.Register_PortB_Output_of_Memory_Primitives {false} \ + CONFIG.Port_B_Clock {250} \ + CONFIG.Port_B_Write_Rate {0} \ + CONFIG.Port_B_Enable_Rate {100} \ + ] [get_ips combpm_packet_filter_blk_mem] + +set_property GENERATE_SYNTH_CHECKPOINT 0 [get_files $xcipath] -- GitLab