diff --git a/hdl/combpm_packet_filter.vhd b/hdl/combpm_packet_filter.vhd new file mode 100644 index 0000000000000000000000000000000000000000..6bcdf53de238f4d3d97aa7fd15061237946a4c37 --- /dev/null +++ b/hdl/combpm_packet_filter.vhd @@ -0,0 +1,259 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +use work.pkg_combpm_stream.all; + +entity combpm_packet_filter is + generic( + G_B_ADDR_W : natural := 14 + ); + 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(G_B_ADDR_W-1 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(G_B_ADDR_W-1 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(G_B_ADDR_W-1 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(G_B_ADDR_W-1 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(G_B_ADDR_W-1 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(G_B_ADDR_W-3 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(G_B_ADDR_W-1 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(G_B_ADDR_W-3 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(resize(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(1 downto 0) => open, + bram_addr_a(G_B_ADDR_W-1 downto 2) => 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(G_B_ADDR_W-1 downto 0), + dinb => (others => '0'), + doutb => table_data + ); + +end architecture rtl; diff --git a/hdl/combpm_protocol_electron.vhd b/hdl/combpm_protocol_electron.vhd index 8a383f9173a851a0e9695a28cd586f5c10e706bb..ee7c9b150153de2a174b16c5bec5e3d5b23e278c 100644 --- a/hdl/combpm_protocol_electron.vhd +++ b/hdl/combpm_protocol_electron.vhd @@ -3,6 +3,8 @@ library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; +use work.pkg_combpm_stream.all; + entity combpm_protocol_electron is port( rst_n : in std_logic; @@ -29,10 +31,10 @@ entity combpm_protocol_electron is -- Status and control interface soft_reset : in std_logic; frame_seq_cnt : out std_logic_vector(15 downto 0); - frame_valid_cnt : out std_logic_vector(15 downto 0); - frame_invalid_cnt : out std_logic_vector(15 downto 0); - frame_valid_rate : out std_logic_vector(15 downto 0); - frame_invalid_rate : out std_logic_vector(15 downto 0); + frame_valid_cnt : out std_logic_vector(31 downto 0); + frame_invalid_cnt : out std_logic_vector(31 downto 0); + frame_valid_rate : out std_logic_vector(31 downto 0); + frame_invalid_rate : out std_logic_vector(31 downto 0); cnt_seq_mismatch : out std_logic; seq_discontinuity : out std_logic; frame_error : out std_logic @@ -83,10 +85,12 @@ architecture rtl of combpm_protocol_electron is signal last_cnt_seq_r : unsigned(15 downto 0); signal cnt_frame_seq_r : unsigned(15 downto 0); - signal cnt_valid_r : unsigned(15 downto 0); - signal cnt_invalid_r : unsigned(15 downto 0); - signal rate_valid_r : unsigned(15 downto 0); - signal rate_invalid_r : unsigned(15 downto 0); + signal cnt_valid_r : unsigned(31 downto 0); + signal cnt_invalid_r : unsigned(31 downto 0); + signal rate_valid_r : unsigned(31 downto 0); + signal rate_invalid_r : unsigned(31 downto 0); + + signal packet : t_combpm_axis_packet; begin @@ -244,11 +248,12 @@ begin m_axi_tid <= "0"; m_axi_tuser <= "0"; m_axi_tlast <= '1'; -- One transfer is One packet. + m_axi_tdata <= combpmpacket2slv(packet); p_axis:process(clk, rst_n) begin if rst_n = '0' then - m_axi_tdata <= (others => '0'); + packet <= C_PACKET_ZERO; m_axi_tvalid <= '0'; m_axi_tdest <= (others => '0'); @@ -256,11 +261,12 @@ begin if flag_all = '1' then -- Make AXIS packet - m_axi_tdata(31 downto 0) <= packet_ypos; - m_axi_tdata(63 downto 32) <= packet_xpos; - m_axi_tdata(103 downto 64) <= mc_time; - m_axi_tdata(111 downto 104) <= packet_timestamp(7 downto 0); - m_axi_tdata(127 downto 112) <= "000000" & packet_bpmid; + packet.pos_x <= packet_xpos; + packet.pos_y <= packet_ypos; + packet.bpm_id <= "000000" & packet_bpmid; + packet.mc_timestamp <= mc_time; + packet.fa_seq <= packet_timestamp(7 downto 0); + -- AXIS ancillary data m_axi_tdest <= packet_bpmid; diff --git a/hdl/pkg_combpm_stream.vhd b/hdl/pkg_combpm_stream.vhd new file mode 100644 index 0000000000000000000000000000000000000000..1a923b268f30c89414c4e1ee9360301c827ed796 --- /dev/null +++ b/hdl/pkg_combpm_stream.vhd @@ -0,0 +1,92 @@ +library ieee; +use ieee.std_logic_1164.all; + +package pkg_bpmframe_stream is + + ---------------------- + -- MACRO PARAMETERS -- + ---------------------- + constant C_TDEST_W : natural := 7; + constant C_TDATA_W : natural := 128; + + --------------------------------- + -- AXIS MASTER/SLAVE INTERFACE -- + --------------------------------- + type t_bpmframe_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_bpmframe_axis_m2s; + + type t_bpmframe_axis_s2m is record + tready : std_logic; + end record t_bpmframe_axis_s2m; + + subtype t_bpmframe_m_axis_out is t_bpmframe_axis_m2s; + subtype t_bpmframe_s_axis_in is t_bpmframe_axis_m2s; + subtype t_bpmframe_m_axis_in is t_bpmframe_axis_s2m; + subtype t_bpmframe_s_axis_out is t_bpmframe_axis_s2m; + + ------------------------ + -- AXIS STREAM PACKET -- + ------------------------ + type t_bpmframe 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_bpmframe; + + constant C_BPMFRAME_ZERO : t_bpmframe := ( + pos_x => (others => '0'), + pos_y => (others => '0'), + bpm_id => (others => '0'), + mc_timestamp => (others => '0'), + fa_seq => (others => '0') + ); + + function slv2bpmframe( + signal tdata : std_logic_vector(C_TDATA_W-1 downto 0) + ) + return t_bpmframe; + + function bpmframe2slv( + signal packet : t_bpmframe + ) + return std_logic_vector; + + +end package; + +package body pkg_bpmframe_stream is + + + function slv2bpmframe( + signal tdata : std_logic_vector(C_TDATA_W-1 downto 0) + ) + return t_bpmframe is + variable packet : t_bpmframe; + 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 bpmframe2slv( + signal packet : t_bpmframe + ) + 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/hdl/top_combpm_electron.vhd b/hdl/top_combpm_electron.vhd index cc8f1ce320c0c27b413c5856af1596d52bcd95ed..9b3d79edcb0b8103ef7a7309a2886a1e8dab722e 100644 --- a/hdl/top_combpm_electron.vhd +++ b/hdl/top_combpm_electron.vhd @@ -154,10 +154,10 @@ architecture struct of top_combpm_electron is signal rst : std_logic; signal frame_seq_cnt : std_logic_vector(15 downto 0); - signal frame_valid_cnt : std_logic_vector(15 downto 0); - signal frame_invalid_cnt : std_logic_vector(15 downto 0); - signal frame_valid_rate : std_logic_vector(15 downto 0); - signal frame_invalid_rate : std_logic_vector(15 downto 0); + signal frame_valid_cnt : std_logic_vector(31 downto 0); + signal frame_invalid_cnt : std_logic_vector(31 downto 0); + signal frame_valid_rate : std_logic_vector(31 downto 0); + signal frame_invalid_rate : std_logic_vector(31 downto 0); signal cnt_seq_mismatch : std_logic; signal seq_discontinuity : std_logic; signal frame_error : std_logic; diff --git a/rdl/COMBPM.rdl b/rdl/COMBPM.rdl index daea66370d6458109ed82cd1e2da7842cc2e1d2c..83b33285b9aa80bc33c5f74b3148c322fceb7d40 100644 --- a/rdl/COMBPM.rdl +++ b/rdl/COMBPM.rdl @@ -127,13 +127,15 @@ addrmap COMBPM { field { desc="Valid frame counter"; hw=w;sw=r; - } VALIDFRAMECNT[16]; + } CNT[32]; + } VALIDFRAMECNT; + reg { field { desc="Invalid frame counter"; hw=w;sw=r; - } INVALIDFRAMECNT[16]; - } FRAMECNT; + } CNT[32]; + } INVALIDFRAMECNT; reg { name="Protocol frame rate"; @@ -141,13 +143,15 @@ addrmap COMBPM { field { desc="Valid frame rate"; hw=w;sw=r; - } VALIDFRAMERATE[16]; + } RATE[32]; + } VALIDFRAMERATE; + reg { field { desc="Invalid frame rate"; hw=w;sw=r; - } INVALIDFRAMERATE[16]; - } FRAMERATE; + } RATE[32]; + } INVALIDFRAMERATE; reg { name="Protocol frame sequence"; diff --git a/tcl/generate_combpm_packet_filter_ip.tcl b/tcl/generate_combpm_packet_filter_ip.tcl new file mode 100644 index 0000000000000000000000000000000000000000..a3bf011864655735de7077586fa38ea5e2e739a3 --- /dev/null +++ b/tcl/generate_combpm_packet_filter_ip.tcl @@ -0,0 +1,49 @@ + +# Address width, on logic side (8 bits data access) +set b_addr_w 14 + +# Address width on AXI MM side (32 bits access) +set a_addr_w [expr $b_addr_w-2] + +set a_depth [expr 1<<$a_addr_w] +set b_depth [expr 1<<$b_addr_w] + +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.USE_ECC {0} \ + CONFIG.BMG_INSTANCE {EXTERNAL} \ + CONFIG.MEM_DEPTH $a_depth \ + CONFIG.CLKIF.FREQ_HZ 250000000 \ + CONFIG.DATA_WIDTH 32 \ + ] [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 $a_depth \ + 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]