diff --git a/src/common/hdl/oh_fifo_async.v b/src/common/hdl/oh_fifo_async.v index 5303bc82..fecd8811 100644 --- a/src/common/hdl/oh_fifo_async.v +++ b/src/common/hdl/oh_fifo_async.v @@ -67,7 +67,29 @@ module oh_fifo_async # (parameter DW = 104, //FIFO width .din (din[DW-1:0]), .rd_en (rd_en)); end // if ((DW==104) & (DEPTH==32)) - end // block: xilinx + else if((DW==128) & (DEPTH==32)) + begin + fifo_async_128x32 + fifo ( + // Outputs + .full (full), + .prog_full (prog_full), + .dout (dout[DW-1:0]), + .empty (empty), + .rd_data_count (rd_count[AW-1:0]), + // Inputs + .rst (~nreset), + .wr_clk (wr_clk), + .rd_clk (rd_clk), + .wr_en (wr_en), + .din (din[DW-1:0]), + .rd_en (rd_en)); + end // if ((DW==128) & (DEPTH==32)) + else + _INVALID_PARAMETERS_ invalid_parameters(); + end // block: xilinx + else + _INVALID_TARGET_ invalid_target(); endgenerate endmodule // oh_fifo_async diff --git a/src/mio/dv/dut_mio.v b/src/mio/dv/dut_mio.v index 1af51248..0337aee9 100644 --- a/src/mio/dv/dut_mio.v +++ b/src/mio/dv/dut_mio.v @@ -41,15 +41,18 @@ module dut(/*AUTOARG*/ //######################################## //wires - wire reg_access_in; + wire reg_access_in; wire [PW-1:0] reg_packet_in; wire reg_wait_in; wire mio_access_in; - + wire [PW-1:0] mio_packet_out; + wire mio_wait_in; + /*AUTOINPUT*/ - // End of automatics + /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) + wire mio_access_out; // From mio of mio.v wire reg_access_out; // From mio of mio.v wire [PW-1:0] reg_packet_out; // From mio of mio.v wire reg_wait_out; // From mio of mio.v @@ -73,6 +76,19 @@ module dut(/*AUTOARG*/ assign reg_packet_in = packet_in; assign reg_wait_in = wait_in; + + emesh_mux #(.N(2),.AW(AW)) + mux2(// Outputs + .wait_out ({reg_wait_in, mio_wait_in}), + .access_out (access_out), + .packet_out (packet_out[PW-1:0]), + // Inputs + .access_in ({reg_access_out, mio_access_out}), + .packet_in ({reg_packet_out[PW-1:0], mio_packet_out[PW-1:0]}), + .wait_in (wait_in) + ); + + //######################################## //# DUT: MIO IN LOOPBACK //######################################## @@ -86,6 +102,10 @@ module dut(/*AUTOARG*/ .tx_packet (tx_packet[NMIO-1:0]), .tx_wait (rx_wait), .access_in (mio_access_in), + .access_out (mio_access_out), + .packet_out (mio_packet_out[]), + .wait_in (mio_wait_in), + ); */ @@ -100,8 +120,8 @@ module dut(/*AUTOARG*/ .tx_packet (tx_packet[NMIO-1:0]), // Templated .rx_wait (rx_wait), .wait_out (wait_out), - .access_out (access_out), - .packet_out (packet_out[PW-1:0]), + .access_out (mio_access_out), // Templated + .packet_out (mio_packet_out[PW-1:0]), // Templated .reg_wait_out (reg_wait_out), .reg_access_out (reg_access_out), .reg_packet_out (reg_packet_out[PW-1:0]), @@ -114,7 +134,7 @@ module dut(/*AUTOARG*/ .rx_packet (tx_packet[NMIO-1:0]), // Templated .access_in (mio_access_in), // Templated .packet_in (packet_in[PW-1:0]), - .wait_in (wait_in), + .wait_in (mio_wait_in), // Templated .reg_access_in (reg_access_in), .reg_packet_in (reg_packet_in[PW-1:0]), .reg_wait_in (reg_wait_in)); diff --git a/src/mio/dv/tests/test_reg_read.emf b/src/mio/dv/tests/test_reg_read.emf new file mode 100644 index 00000000..b2215cf5 --- /dev/null +++ b/src/mio/dv/tests/test_reg_read.emf @@ -0,0 +1,20 @@ +FFEEDDCC_BBAA9988_77665544_05_0080 //EMESH 32 BIT WRITE (DEFAULT) +DEADBEEF_00000000_00000004_05_0000 //WRITE STATUS +810d0000_00000000_00000004_04_0000 //READ STATUS +DEADBEEF_00001048_00000000_05_0000 //CONFIG(AMODE,MSB,DDR,SIZE="64") +810d0004_00000000_00000000_04_0000 //READ CONFIG (not supported) +DEADBEEF_00000000_00000004_05_0000 //WRITE STATUS +DEADBEEF_00000007_00000008_05_0000 //WRITE CLKDIV +DEADBEEF_06020400_0000000c_05_0000 //WRITE CLKPHASE +DEADBEEF_80800000_00000018_05_0000 //WRITE ADDR0 +DEADBEEF_00000000_0000001c_05_0080 //WRITE ADDR1 +22222222_11111111_FFF00000_00_0200 //AMODE 64 BIT WRITE +810d0000_00000000_00000004_04_0000 //READ STATUS +44444444_33333333_FFF00000_00_0000 //AMODE 64 BIT WRITE +66666666_55555555_FFF00000_00_0000 //AMODE 64 BIT WRITE +88888888_77777777_FFF00000_00_0000 //AMODE 64 BIT WRITE +aaaaaaaa_99999999_FFF00000_00_0000 //AMODE 64 BIT WRITE +810d0008_00000000_00000004_04_0100 //READ STATUS +810d000c_00000000_00000004_04_0100 //READ STATUS + + diff --git a/src/mio/fpga/axi_mio_timing.xdc b/src/mio/fpga/axi_mio_timing.xdc new file mode 100644 index 00000000..733cafb9 --- /dev/null +++ b/src/mio/fpga/axi_mio_timing.xdc @@ -0,0 +1,32 @@ +# Use numbers from here: +# https://en.wikipedia.org/wiki/Propagation_delay +# Assume wires are shorter than < 30cm (12") + +# slave +create_clock -period 30.000 -name mio_s_sclk -waveform {0.000 15.000} [get_ports {gpio_p[3]}] +# assign mio_s_mosi = gpio_in[8]; +set_input_delay -clock mio_s_sclk -max 2.000 [get_ports {gpio_n[4]}] +# assign mio_s_miso = gpio_out[9]; +set_output_delay -clock mio_s_sclk -max -add_delay 2.000 [get_ports {gpio_n[5]}] +# assign mio_s_ss = gpio_in[10]; +set_input_delay -clock mio_s_sclk -max 2.000 [get_ports {gpio_p[4]}] + +#master +# assign mio_m_sclk = gpio_out[3]; +# just misses timing for 100 MHz +create_clock -period 20.000 -name mio_m_sclk -waveform {0.000 10.000} [get_ports {gpio_p[1]}] +# assign mio_m_mosi = gpio_out[4]; +set_output_delay -clock mio_m_sclk -max -add_delay 2.000 [get_ports {gpio_n[2]}] +# assign mio_m_miso = gpio_in[5]; +set_input_delay -clock mio_m_sclk -max 2.000 [get_ports {gpio_n[3]}] +# assign mio_m_ss = gpio_out[6]; +set_output_delay -clock mio_m_sclk -max -add_delay 2.000 [get_ports {gpio_p[2]}] + +set_false_path -from [get_clocks clk_fpga_0] -to [get_clocks mio_m_sclk] + +# pgpio.v pin mapping +# for(m=0; m and is being run in <$current_vivado_version> of Vivado. Please run the script in Vivado <$scripts_vivado_version> then open the design in Vivado <$current_vivado_version>. Upgrade the design by running \"Tools => Report => Report IP Status...\", then run write_bd_tcl to create an updated script." + + return 1 +} + +################################################################ +# START +################################################################ + +# To test this script, run the following commands from Vivado Tcl console: +# source system_script.tcl + +# If you do not already have a project created, +# you can create a project using the following command: +# create_project project_1 myproj -part xc7z020clg400-1 + +# CHECKING IF PROJECT EXISTS +if { [get_projects -quiet] eq "" } { + puts "ERROR: Please open or create a project!" + return 1 +} + + + +# CHANGE DESIGN NAME HERE +set design_name system + +# If you do not already have an existing IP Integrator design open, +# you can create a design using the following command: +# create_bd_design $design_name + +# Creating design if needed +set errMsg "" +set nRet 0 + +set cur_design [current_bd_design -quiet] +set list_cells [get_bd_cells -quiet] + +if { ${design_name} eq "" } { + # USE CASES: + # 1) Design_name not set + + set errMsg "ERROR: Please set the variable to a non-empty value." + set nRet 1 + +} elseif { ${cur_design} ne "" && ${list_cells} eq "" } { + # USE CASES: + # 2): Current design opened AND is empty AND names same. + # 3): Current design opened AND is empty AND names diff; design_name NOT in project. + # 4): Current design opened AND is empty AND names diff; design_name exists in project. + + if { $cur_design ne $design_name } { + puts "INFO: Changing value of from <$design_name> to <$cur_design> since current design is empty." + set design_name [get_property NAME $cur_design] + } + puts "INFO: Constructing design in IPI design <$cur_design>..." + +} elseif { ${cur_design} ne "" && $list_cells ne "" && $cur_design eq $design_name } { + # USE CASES: + # 5) Current design opened AND has components AND same names. + + set errMsg "ERROR: Design <$design_name> already exists in your project, please set the variable to another value." + set nRet 1 +} elseif { [get_files -quiet ${design_name}.bd] ne "" } { + # USE CASES: + # 6) Current opened design, has components, but diff names, design_name exists in project. + # 7) No opened design, design_name exists in project. + + set errMsg "ERROR: Design <$design_name> already exists in your project, please set the variable to another value." + set nRet 2 + +} else { + # USE CASES: + # 8) No opened design, design_name not in project. + # 9) Current opened design, has components, but diff names, design_name not in project. + + puts "INFO: Currently there is no design <$design_name> in project, so creating one..." + + create_bd_design $design_name + + puts "INFO: Making design <$design_name> as current_bd_design." + current_bd_design $design_name + +} + +puts "INFO: Currently the variable is equal to \"$design_name\"." + +if { $nRet != 0 } { + puts $errMsg + return $nRet +} + +################################################################## +# DESIGN PROCs +################################################################## + + + +# Procedure to create entire design; Provide argument to make +# procedure reusable. If parentCell is "", will use root. +proc create_root_design { parentCell } { + + if { $parentCell eq "" } { + set parentCell [get_bd_cells /] + } + + # Get object for parentCell + set parentObj [get_bd_cells $parentCell] + if { $parentObj == "" } { + puts "ERROR: Unable to find parent cell <$parentCell>!" + return + } + + # Make sure parentObj is hier blk + set parentType [get_property TYPE $parentObj] + if { $parentType ne "hier" } { + puts "ERROR: Parent <$parentObj> has TYPE = <$parentType>. Expected to be ." + return + } + + # Save current instance; Restore later + set oldCurInst [current_bd_instance .] + + # Set parent object as current + current_bd_instance $parentObj + + + # Create interface ports + + # Create ports + set gpio_n [ create_bd_port -dir IO -from 23 -to 0 gpio_n ] + set gpio_p [ create_bd_port -dir IO -from 23 -to 0 gpio_p ] + + # Create instance: axi_mem_intercon, and set properties + set axi_mem_intercon [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect:2.1 axi_mem_intercon ] + set_property -dict [ list CONFIG.NUM_MI {1} ] $axi_mem_intercon + + # Create instance: parallella_mio_0, and set properties + set parallella_mio_0 [ create_bd_cell -type ip -vlnv www.parallella.org:user:parallella_mio:1.0 parallella_mio_0 ] + + # Create instance: proc_sys_reset_0, and set properties + set proc_sys_reset_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:proc_sys_reset:5.0 proc_sys_reset_0 ] + + # Create instance: processing_system7_0, and set properties + set processing_system7_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:processing_system7:5.5 processing_system7_0 ] + set_property -dict [ list CONFIG.PCW_CORE0_FIQ_INTR {0} \ +CONFIG.PCW_ENET0_ENET0_IO {MIO 16 .. 27} CONFIG.PCW_ENET0_GRP_MDIO_ENABLE {1} \ +CONFIG.PCW_ENET0_PERIPHERAL_ENABLE {1} CONFIG.PCW_ENET1_PERIPHERAL_ENABLE {0} \ +CONFIG.PCW_EN_CLK3_PORT {1} CONFIG.PCW_FPGA0_PERIPHERAL_FREQMHZ {100} \ +CONFIG.PCW_FPGA3_PERIPHERAL_FREQMHZ {100} CONFIG.PCW_GPIO_EMIO_GPIO_ENABLE {1} \ +CONFIG.PCW_GPIO_MIO_GPIO_ENABLE {1} CONFIG.PCW_GPIO_MIO_GPIO_IO {MIO} \ +CONFIG.PCW_I2C0_I2C0_IO {EMIO} CONFIG.PCW_I2C0_PERIPHERAL_ENABLE {1} \ +CONFIG.PCW_I2C0_RESET_ENABLE {0} CONFIG.PCW_IRQ_F2P_INTR {0} \ +CONFIG.PCW_IRQ_F2P_MODE {DIRECT} CONFIG.PCW_PRESET_BANK1_VOLTAGE {LVCMOS 1.8V} \ +CONFIG.PCW_QSPI_GRP_SINGLE_SS_ENABLE {1} CONFIG.PCW_QSPI_PERIPHERAL_ENABLE {1} \ +CONFIG.PCW_SD1_PERIPHERAL_ENABLE {1} CONFIG.PCW_SD1_SD1_IO {MIO 10 .. 15} \ +CONFIG.PCW_SDIO_PERIPHERAL_FREQMHZ {50} CONFIG.PCW_UART1_PERIPHERAL_ENABLE {1} \ +CONFIG.PCW_UART1_UART1_IO {MIO 8 .. 9} CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY0 {0.434} \ +CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY1 {0.398} CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY2 {0.410} \ +CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY3 {0.455} CONFIG.PCW_UIPARAM_DDR_CL {9} \ +CONFIG.PCW_UIPARAM_DDR_CWL {9} CONFIG.PCW_UIPARAM_DDR_DEVICE_CAPACITY {8192 MBits} \ +CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_0 {0.315} CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_1 {0.391} \ +CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_2 {0.374} CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_3 {0.271} \ +CONFIG.PCW_UIPARAM_DDR_DRAM_WIDTH {32 Bits} CONFIG.PCW_UIPARAM_DDR_FREQ_MHZ {400.00} \ +CONFIG.PCW_UIPARAM_DDR_PARTNO {Custom} CONFIG.PCW_UIPARAM_DDR_T_FAW {50} \ +CONFIG.PCW_UIPARAM_DDR_T_RAS_MIN {40} CONFIG.PCW_UIPARAM_DDR_T_RC {60} \ +CONFIG.PCW_UIPARAM_DDR_T_RCD {9} CONFIG.PCW_UIPARAM_DDR_T_RP {9} \ +CONFIG.PCW_UIPARAM_DDR_USE_INTERNAL_VREF {1} CONFIG.PCW_USB0_PERIPHERAL_ENABLE {1} \ +CONFIG.PCW_USB0_RESET_ENABLE {0} CONFIG.PCW_USB1_PERIPHERAL_ENABLE {1} \ +CONFIG.PCW_USE_FABRIC_INTERRUPT {1} CONFIG.PCW_USE_M_AXI_GP1 {1} \ +CONFIG.PCW_USE_S_AXI_HP0 {1} ] $processing_system7_0 + + # Create instance: processing_system7_0_axi_periph, and set properties + set processing_system7_0_axi_periph [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect:2.1 processing_system7_0_axi_periph ] + set_property -dict [ list CONFIG.NUM_MI {1} ] $processing_system7_0_axi_periph + + # Create interface connections + connect_bd_intf_net -intf_net axi_mem_intercon_M00_AXI [get_bd_intf_pins axi_mem_intercon/M00_AXI] [get_bd_intf_pins processing_system7_0/S_AXI_HP0] + connect_bd_intf_net -intf_net parallella_mio_0_m_axi [get_bd_intf_pins axi_mem_intercon/S00_AXI] [get_bd_intf_pins parallella_mio_0/m_axi] + connect_bd_intf_net -intf_net processing_system7_0_M_AXI_GP0 [get_bd_intf_pins processing_system7_0/M_AXI_GP0] [get_bd_intf_pins processing_system7_0_axi_periph/S00_AXI] + connect_bd_intf_net -intf_net processing_system7_0_axi_periph_M00_AXI [get_bd_intf_pins parallella_mio_0/s_axi] [get_bd_intf_pins processing_system7_0_axi_periph/M00_AXI] + + # Create port connections + connect_bd_net -net parallella_mio_0_gpio_n [get_bd_ports gpio_n] [get_bd_pins parallella_mio_0/gpio_n] + connect_bd_net -net parallella_mio_0_gpio_p [get_bd_ports gpio_p] [get_bd_pins parallella_mio_0/gpio_p] + connect_bd_net -net proc_sys_reset_0_interconnect_aresetn [get_bd_pins axi_mem_intercon/ARESETN] [get_bd_pins proc_sys_reset_0/interconnect_aresetn] [get_bd_pins processing_system7_0_axi_periph/ARESETN] + connect_bd_net -net proc_sys_reset_0_peripheral_aresetn [get_bd_pins axi_mem_intercon/M00_ARESETN] [get_bd_pins axi_mem_intercon/S00_ARESETN] [get_bd_pins parallella_mio_0/m_axi_aresetn] [get_bd_pins parallella_mio_0/s_axi_aresetn] [get_bd_pins parallella_mio_0/sys_nreset] [get_bd_pins proc_sys_reset_0/peripheral_aresetn] [get_bd_pins processing_system7_0_axi_periph/M00_ARESETN] [get_bd_pins processing_system7_0_axi_periph/S00_ARESETN] + connect_bd_net -net processing_system7_0_FCLK_CLK0 [get_bd_pins axi_mem_intercon/ACLK] [get_bd_pins axi_mem_intercon/M00_ACLK] [get_bd_pins axi_mem_intercon/S00_ACLK] [get_bd_pins parallella_mio_0/sys_clk] [get_bd_pins proc_sys_reset_0/slowest_sync_clk] [get_bd_pins processing_system7_0/FCLK_CLK0] [get_bd_pins processing_system7_0/M_AXI_GP0_ACLK] [get_bd_pins processing_system7_0/M_AXI_GP1_ACLK] [get_bd_pins processing_system7_0/S_AXI_HP0_ACLK] [get_bd_pins processing_system7_0_axi_periph/ACLK] [get_bd_pins processing_system7_0_axi_periph/M00_ACLK] [get_bd_pins processing_system7_0_axi_periph/S00_ACLK] + connect_bd_net -net processing_system7_0_FCLK_RESET0_N [get_bd_pins proc_sys_reset_0/ext_reset_in] [get_bd_pins processing_system7_0/FCLK_RESET0_N] + + # Create address segments + create_bd_addr_seg -range 0x40000000 -offset 0x0 [get_bd_addr_spaces parallella_mio_0/m_axi] [get_bd_addr_segs processing_system7_0/S_AXI_HP0/HP0_DDR_LOWOCM] SEG_processing_system7_0_HP0_DDR_LOWOCM + create_bd_addr_seg -range 0x40000000 -offset 0x40000000 [get_bd_addr_spaces processing_system7_0/Data] [get_bd_addr_segs parallella_mio_0/s_axi/axi_lite] SEG_parallella_mio_0_axi_lite + + + # Restore current instance + current_bd_instance $oldCurInst + + save_bd_design +} +# End of create_root_design() + + +################################################################## +# MAIN FLOW +################################################################## + +create_root_design "" + + diff --git a/src/mio/fpga/system_params.tcl b/src/mio/fpga/system_params.tcl new file mode 100644 index 00000000..91f69aa7 --- /dev/null +++ b/src/mio/fpga/system_params.tcl @@ -0,0 +1,33 @@ +# NOTE: See UG1118 for more information + +######################################### +# VARIABLES +######################################### +set design axi_mio +set projdir ./ +set root "../.." +set partname "xc7z020clg400-1" + +set hdl_files [list \ + $root/mio/hdl \ + $root/common/hdl/ \ + $root/emesh/hdl \ + $root/emmu/hdl \ + $root/axi/hdl \ + $root/emailbox/hdl \ + $root/edma/hdl \ + $root/elink/hdl \ + $root/parallella/hdl \ + ] + +set ip_files [list \ + $root/xilibs/ip/fifo_async_104x32/fifo_async_104x32.xci \ + $root/xilibs/ip/fifo_async_128x32/fifo_async_128x32.xci \ + ] + +set constraints_files [list \ + ../../parallella/fpga/parallella_io.xdc \ + ../../parallella/fpga/parallella_7020_io.xdc \ + ./axi_mio_timing.xdc \ + ] + diff --git a/src/mio/hdl/axi_mio.v b/src/mio/hdl/axi_mio.v new file mode 100644 index 00000000..39569662 --- /dev/null +++ b/src/mio/hdl/axi_mio.v @@ -0,0 +1,535 @@ +//############################################################################# +//# Purpose: AXI MIO module # +//############################################################################# +//# Author: Ola Jeppsson # +//# SPDX-License-Identifier: MIT # +//############################################################################# + +module axi_mio(/*AUTOARG*/ + // Outputs + s_axi_wready, s_axi_rvalid, s_axi_rresp, s_axi_rlast, s_axi_rid, + s_axi_rdata, s_axi_bvalid, s_axi_bresp, s_axi_bid, s_axi_awready, + s_axi_arready, m_axi_wvalid, m_axi_wstrb, m_axi_wlast, m_axi_wid, + m_axi_wdata, m_axi_rready, m_axi_bready, m_axi_awvalid, + m_axi_awsize, m_axi_awqos, m_axi_awprot, m_axi_awlock, m_axi_awlen, + m_axi_awid, m_axi_awcache, m_axi_awburst, m_axi_awaddr, + m_axi_arvalid, m_axi_arsize, m_axi_arqos, m_axi_arprot, + m_axi_arlock, m_axi_arlen, m_axi_arid, m_axi_arcache, + m_axi_arburst, m_axi_araddr, + // Inputs + mio_tx_wait, mio_rx_packet, mio_rx_clk, mio_rx_access, + s_axi_wvalid, s_axi_wstrb, s_axi_wlast, s_axi_wid, s_axi_wdata, + s_axi_rready, s_axi_bready, s_axi_awvalid, s_axi_awsize, + s_axi_awqos, s_axi_awprot, s_axi_awlock, s_axi_awlen, s_axi_awid, + s_axi_awcache, s_axi_awburst, s_axi_awaddr, s_axi_arvalid, + s_axi_arsize, s_axi_arqos, s_axi_arprot, s_axi_arlock, s_axi_arlen, + s_axi_arid, s_axi_aresetn, s_axi_arcache, s_axi_arburst, + s_axi_araddr, m_axi_wready, m_axi_rvalid, m_axi_rresp, m_axi_rlast, + m_axi_rid, m_axi_rdata, m_axi_bvalid, m_axi_bresp, m_axi_bid, + m_axi_awready, m_axi_arready, m_axi_aresetn, sys_nreset, sys_clk + ); + + //######################################################## + // INTERFACE + //######################################################## + parameter AW = 32; // address width + parameter PW = 2*AW+40; // packet width + parameter ID = 12'h7FD; // addr[31:20] id + parameter REMAPID = 12'h3E0; // AXI slave addr[31:20] out + parameter S_IDW = 12; // ID width for S_AXI + parameter M_IDW = 6; // ID width for S_AXI + parameter TARGET = "GENERIC"; // XILINX,ALTERA,GENERIC,ASIC + parameter EGROUP_RR = 4'hD; + parameter EGROUP_CFG = 4'h0; + parameter RETURN_ADDR = {ID, EGROUP_RR, 16'b0}; // axi return addr + parameter NMIO = 8; // MIO IO packet width + + //clk, reset + input sys_nreset; // active low async reset + input sys_clk; // system clock for AXI + + // AXI slave + wire [PW-1:0] s_wr_packet; + wire s_wr_access; + wire s_wr_wait; + + wire [PW-1:0] s_rd_packet; + wire s_rd_access; + wire s_rd_wait; + + wire [PW-1:0] s_rr_packet; + wire s_rr_access; + wire s_rr_wait; + + // AXI master + wire [PW-1:0] m_wr_packet; + wire m_wr_access; + wire m_wr_wait; + + wire [PW-1:0] m_rd_packet; + wire m_rd_access; + wire m_rd_wait; + + wire [PW-1:0] m_rr_packet; + wire m_rr_access; + wire m_rr_wait; + + + // MIO + wire [PW-1:0] mio_packet_in; + wire mio_access_in; + wire mio_wait_out; + + wire [PW-1:0] mio_packet_out; + wire mio_access_out; + wire mio_wait_in; + + // MIO regs + wire [PW-1:0] reg_packet_in; + wire reg_access_in; + wire reg_wait_out; + + wire [PW-1:0] reg_packet_out; + wire reg_access_out; + wire reg_wait_in; + + //############################################################## + //AUTOS + //############################################################## + + /*AUTOINPUT("^[ms]_axi_")*/ + // Beginning of automatic inputs (from unused autoinst inputs) + input m_axi_aresetn; // To emaxi of emaxi.v + input m_axi_arready; // To emaxi of emaxi.v + input m_axi_awready; // To emaxi of emaxi.v + input [M_IDW-1:0] m_axi_bid; // To emaxi of emaxi.v + input [1:0] m_axi_bresp; // To emaxi of emaxi.v + input m_axi_bvalid; // To emaxi of emaxi.v + input [63:0] m_axi_rdata; // To emaxi of emaxi.v + input [M_IDW-1:0] m_axi_rid; // To emaxi of emaxi.v + input m_axi_rlast; // To emaxi of emaxi.v + input [1:0] m_axi_rresp; // To emaxi of emaxi.v + input m_axi_rvalid; // To emaxi of emaxi.v + input m_axi_wready; // To emaxi of emaxi.v + input [31:0] s_axi_araddr; // To esaxi of esaxi.v + input [1:0] s_axi_arburst; // To esaxi of esaxi.v + input [3:0] s_axi_arcache; // To esaxi of esaxi.v + input s_axi_aresetn; // To esaxi of esaxi.v + input [S_IDW-1:0] s_axi_arid; // To esaxi of esaxi.v + input [7:0] s_axi_arlen; // To esaxi of esaxi.v + input s_axi_arlock; // To esaxi of esaxi.v + input [2:0] s_axi_arprot; // To esaxi of esaxi.v + input [3:0] s_axi_arqos; // To esaxi of esaxi.v + input [2:0] s_axi_arsize; // To esaxi of esaxi.v + input s_axi_arvalid; // To esaxi of esaxi.v + input [31:0] s_axi_awaddr; // To esaxi of esaxi.v + input [1:0] s_axi_awburst; // To esaxi of esaxi.v + input [3:0] s_axi_awcache; // To esaxi of esaxi.v + input [S_IDW-1:0] s_axi_awid; // To esaxi of esaxi.v + input [7:0] s_axi_awlen; // To esaxi of esaxi.v + input s_axi_awlock; // To esaxi of esaxi.v + input [2:0] s_axi_awprot; // To esaxi of esaxi.v + input [3:0] s_axi_awqos; // To esaxi of esaxi.v + input [2:0] s_axi_awsize; // To esaxi of esaxi.v + input s_axi_awvalid; // To esaxi of esaxi.v + input s_axi_bready; // To esaxi of esaxi.v + input s_axi_rready; // To esaxi of esaxi.v + input [31:0] s_axi_wdata; // To esaxi of esaxi.v + input [S_IDW-1:0] s_axi_wid; // To esaxi of esaxi.v + input s_axi_wlast; // To esaxi of esaxi.v + input [3:0] s_axi_wstrb; // To esaxi of esaxi.v + input s_axi_wvalid; // To esaxi of esaxi.v + // End of automatics + + /*AUTOINPUT("^mio_")*/ + // Beginning of automatic inputs (from unused autoinst inputs) + input mio_rx_access; // To mio of mio.v + input mio_rx_clk; // To mio of mio.v + input [NMIO-1:0] mio_rx_packet; // To mio of mio.v + input mio_tx_wait; // To mio of mio.v + // End of automatics + + /*AUTOOUTPUT("^[ms]_axi_")*/ + // Beginning of automatic outputs (from unused autoinst outputs) + output [31:0] m_axi_araddr; // From emaxi of emaxi.v + output [1:0] m_axi_arburst; // From emaxi of emaxi.v + output [3:0] m_axi_arcache; // From emaxi of emaxi.v + output [M_IDW-1:0] m_axi_arid; // From emaxi of emaxi.v + output [7:0] m_axi_arlen; // From emaxi of emaxi.v + output m_axi_arlock; // From emaxi of emaxi.v + output [2:0] m_axi_arprot; // From emaxi of emaxi.v + output [3:0] m_axi_arqos; // From emaxi of emaxi.v + output [2:0] m_axi_arsize; // From emaxi of emaxi.v + output m_axi_arvalid; // From emaxi of emaxi.v + output [31:0] m_axi_awaddr; // From emaxi of emaxi.v + output [1:0] m_axi_awburst; // From emaxi of emaxi.v + output [3:0] m_axi_awcache; // From emaxi of emaxi.v + output [M_IDW-1:0] m_axi_awid; // From emaxi of emaxi.v + output [7:0] m_axi_awlen; // From emaxi of emaxi.v + output m_axi_awlock; // From emaxi of emaxi.v + output [2:0] m_axi_awprot; // From emaxi of emaxi.v + output [3:0] m_axi_awqos; // From emaxi of emaxi.v + output [2:0] m_axi_awsize; // From emaxi of emaxi.v + output m_axi_awvalid; // From emaxi of emaxi.v + output m_axi_bready; // From emaxi of emaxi.v + output m_axi_rready; // From emaxi of emaxi.v + output [63:0] m_axi_wdata; // From emaxi of emaxi.v + output [M_IDW-1:0] m_axi_wid; // From emaxi of emaxi.v + output m_axi_wlast; // From emaxi of emaxi.v + output [7:0] m_axi_wstrb; // From emaxi of emaxi.v + output m_axi_wvalid; // From emaxi of emaxi.v + output s_axi_arready; // From esaxi of esaxi.v + output s_axi_awready; // From esaxi of esaxi.v + output [S_IDW-1:0] s_axi_bid; // From esaxi of esaxi.v + output [1:0] s_axi_bresp; // From esaxi of esaxi.v + output s_axi_bvalid; // From esaxi of esaxi.v + output [31:0] s_axi_rdata; // From esaxi of esaxi.v + output [S_IDW-1:0] s_axi_rid; // From esaxi of esaxi.v + output s_axi_rlast; // From esaxi of esaxi.v + output [1:0] s_axi_rresp; // From esaxi of esaxi.v + output s_axi_rvalid; // From esaxi of esaxi.v + output s_axi_wready; // From esaxi of esaxi.v + // End of automatics + + /*AUTOOUTPUT("^mio_[rt]_")*/ + + /*AUTOWIRE*/ + // Beginning of automatic wires (for undeclared instantiated-module outputs) + wire mio_rx_wait; // From mio of mio.v + wire mio_tx_access; // From mio of mio.v + wire mio_tx_clk; // From mio of mio.v + wire [NMIO-1:0] mio_tx_packet; // From mio of mio.v + // End of automatics + + //######################################################## + //Switchboard logic + //######################################################## + + /* Packet decode */ + + wire s_wr_write; + wire [AW-1:0] s_wr_dstaddr; + wire [1:0] s_wr_datamode; + wire [4:0] s_wr_ctrlmode; + wire [AW-1:0] s_wr_srcaddr; + wire [AW-1:0] s_wr_data; + packet2emesh #(.AW(AW), .PW(PW)) + s_wr_p2e (// Inputs + .packet_in (s_wr_packet[PW-1:0]), + // Output + .write_in (s_wr_write), + .dstaddr_in (s_wr_dstaddr[AW-1:0]), + .datamode_in (s_wr_datamode[1:0]), + .ctrlmode_in (s_wr_ctrlmode[4:0]), + .srcaddr_in (s_wr_srcaddr[AW-1:0]), + .data_in (s_wr_data[AW-1:0])); + + wire s_rd_write; + wire [AW-1:0] s_rd_dstaddr; + wire [1:0] s_rd_datamode; + wire [4:0] s_rd_ctrlmode; + wire [AW-1:0] s_rd_srcaddr; + wire [AW-1:0] s_rd_data; + packet2emesh #(.AW(AW), .PW(PW)) + s_rd_p2e (// Inputs + .packet_in (s_rd_packet[PW-1:0]), + // Output + .write_in (s_rd_write), + .dstaddr_in (s_rd_dstaddr[AW-1:0]), + .datamode_in (s_rd_datamode[1:0]), + .ctrlmode_in (s_rd_ctrlmode[4:0]), + .srcaddr_in (s_rd_srcaddr[AW-1:0]), + .data_in (s_rd_data[AW-1:0])); + + wire mio_out_write; + wire [AW-1:0] mio_out_dstaddr; + wire [1:0] mio_out_datamode; + wire [4:0] mio_out_ctrlmode; + wire [AW-1:0] mio_out_srcaddr; + wire [AW-1:0] mio_out_data; + packet2emesh #(.AW(AW), .PW(PW)) + mio_out_p2e (// Inputs + .packet_in (mio_packet_out[PW-1:0]), + // Output + .write_in (mio_out_write), + .dstaddr_in (mio_out_dstaddr[AW-1:0]), + .datamode_in (mio_out_datamode[1:0]), + .ctrlmode_in (mio_out_ctrlmode[4:0]), + .srcaddr_in (mio_out_srcaddr[AW-1:0]), + .data_in (mio_out_data[AW-1:0])); + + + /* AXI slave address remap */ + + wire [PW-1:0] s_wr_remapped_packet; + emesh2packet #(.AW(AW), .PW(PW)) + s_wr_remap_e2p (// Outputs + .packet_out (s_wr_remapped_packet[PW-1:0]), + // Inputs + .write_out (s_wr_write), + .datamode_out (s_wr_datamode[1:0]), + .ctrlmode_out (s_wr_ctrlmode[4:0]), + .dstaddr_out ({REMAPID, s_wr_dstaddr[19:0]}), + .data_out (s_wr_data[AW-1:0]), + .srcaddr_out (s_wr_srcaddr[AW-1:0])); + + wire [PW-1:0] s_rd_remapped_packet; + emesh2packet #(.AW(AW), .PW(PW)) + s_rd_remap_e2p (// Outputs + .packet_out (s_rd_remapped_packet[PW-1:0]), + // Inputs + .write_out (s_rd_write), + .datamode_out (s_rd_datamode[1:0]), + .ctrlmode_out (s_rd_ctrlmode[4:0]), + .dstaddr_out ({REMAPID, s_rd_dstaddr[19:0]}), + .data_out (s_rd_data[AW-1:0]), + .srcaddr_out (s_rd_srcaddr[AW-1:0])); + + + /* Destination matching */ + + wire s_wr_reg_match = (s_wr_dstaddr[31:20] == ID) & + (s_wr_dstaddr[19:16] == EGROUP_CFG); + wire s_rd_reg_match = (s_rd_dstaddr[31:20] == ID) & + (s_rd_dstaddr[19:16] == EGROUP_CFG); + + wire mio_out_s_rr_match = (mio_out_dstaddr[31:20] == ID) & + (mio_out_dstaddr[19:16] == EGROUP_RR); + + wire mio_out_m_wr_match = ~mio_out_s_rr_match & mio_out_write; + wire mio_out_m_rd_match = ~mio_out_s_rr_match & ~mio_out_write; + + + /* MUX stage */ + + wire s_rd_reg_in_wait; + wire s_wr_reg_in_wait; + emesh_mux #(.N(2),.AW(AW)) + reg_in_mux (// Outputs + .packet_out (reg_packet_in[PW-1:0]), + .access_out (reg_access_in), + .wait_out ({s_rd_reg_in_wait, s_wr_reg_in_wait}), + // Inputs + .access_in ({s_rd_reg_match & s_rd_access, + s_wr_reg_match & s_wr_access}), + .packet_in ({s_rd_packet[PW-1:0], s_wr_packet[PW-1:0]}), + .wait_in (reg_wait_out)); + + wire s_rd_mio_in_wait; + wire s_wr_mio_in_wait; + emesh_mux #(.N(3),.AW(AW)) + mio_in_mux(// Outputs + .packet_out (mio_packet_in[PW-1:0]), + .access_out (mio_access_in), + .wait_out ({s_rd_mio_in_wait, s_wr_mio_in_wait, m_rr_wait}), + // Inputs + .access_in ({~s_rd_reg_match & s_rd_access, + ~s_wr_reg_match & s_wr_access, + m_rr_access}), + .packet_in ({s_rd_remapped_packet[PW-1:0], + s_wr_remapped_packet[PW-1:0], + m_rr_packet[PW-1:0]}), + .wait_in (mio_wait_out)); + + wire reg_out_s_rr_wait; + wire mio_out_s_rr_wait; + emesh_mux #(.N(2),.AW(AW)) + s_rr_mux (// Outputs + .packet_out (s_rr_packet[PW-1:0]), + .access_out (s_rr_access), + .wait_out ({reg_out_s_rr_wait, mio_out_s_rr_wait}), + // Inputs + .access_in ({reg_access_out, + mio_access_out & mio_out_s_rr_match}), + .packet_in ({reg_packet_out[PW-1:0], mio_packet_out[PW-1:0]}), + .wait_in (s_rr_wait)); + + assign m_wr_packet[PW-1:0] = mio_packet_out[PW-1:0]; + assign m_wr_access = mio_access_out & mio_out_m_wr_match; + + assign m_rd_packet[PW-1:0] = mio_packet_out[PW-1:0]; + assign m_rd_access = mio_access_out & mio_out_m_rd_match; + + + /* Wait signals */ + + assign s_wr_wait = s_wr_reg_in_wait | s_wr_mio_in_wait; + assign s_rd_wait = s_rd_reg_in_wait | s_rd_mio_in_wait; + assign reg_wait_in = reg_out_s_rr_wait; + assign mio_wait_in = mio_out_s_rr_wait | + (mio_out_m_wr_match & m_wr_wait) | + (mio_out_m_rd_match & m_rd_wait); + + + //######################################################## + //MIO + //######################################################## + + /* + mio AUTO_TEMPLATE + (.clk (sys_clk), + .nreset (sys_nreset), + .reg_\(.*\) (reg_\1[]), + .\(.*\) (mio_\1[])); */ + mio #(.AW(AW), .DEF_CFG(20'h1070), .DEF_CLK(50), .TARGET(TARGET), .NMIO(NMIO)) + mio (/*AUTOINST*/ + // Outputs + .tx_clk (mio_tx_clk), // Templated + .tx_access (mio_tx_access), // Templated + .tx_packet (mio_tx_packet[NMIO-1:0]), // Templated + .rx_wait (mio_rx_wait), // Templated + .wait_out (mio_wait_out), // Templated + .access_out (mio_access_out), // Templated + .packet_out (mio_packet_out[PW-1:0]), // Templated + .reg_wait_out (reg_wait_out), // Templated + .reg_access_out (reg_access_out), // Templated + .reg_packet_out (reg_packet_out[PW-1:0]), // Templated + // Inputs + .clk (sys_clk), // Templated + .nreset (sys_nreset), // Templated + .tx_wait (mio_tx_wait), // Templated + .rx_clk (mio_rx_clk), // Templated + .rx_access (mio_rx_access), // Templated + .rx_packet (mio_rx_packet[NMIO-1:0]), // Templated + .access_in (mio_access_in), // Templated + .packet_in (mio_packet_in[PW-1:0]), // Templated + .wait_in (mio_wait_in), // Templated + .reg_access_in (reg_access_in), // Templated + .reg_packet_in (reg_packet_in[PW-1:0]), // Templated + .reg_wait_in (reg_wait_in)); // Templated + + //######################################################## + //AXI SLAVE + //######################################################## + + /* + esaxi AUTO_TEMPLATE + (.rr_\(.*\) (s_rr_\1[]), + .rr_\(.*\) (s_rr_\1[]), + .rd_\(.*\) (s_rd_\1[]), + .wr_\(.*\) (s_wr_\1[]), + .s_axi_aclk (sys_clk)); */ + + esaxi #(.S_IDW(S_IDW), .RETURN_ADDR(RETURN_ADDR)) + esaxi (/*AUTOINST*/ + // Outputs + .wr_access (s_wr_access), // Templated + .wr_packet (s_wr_packet[PW-1:0]), // Templated + .rd_access (s_rd_access), // Templated + .rd_packet (s_rd_packet[PW-1:0]), // Templated + .rr_wait (s_rr_wait), // Templated + .s_axi_arready (s_axi_arready), + .s_axi_awready (s_axi_awready), + .s_axi_bid (s_axi_bid[S_IDW-1:0]), + .s_axi_bresp (s_axi_bresp[1:0]), + .s_axi_bvalid (s_axi_bvalid), + .s_axi_rid (s_axi_rid[S_IDW-1:0]), + .s_axi_rdata (s_axi_rdata[31:0]), + .s_axi_rlast (s_axi_rlast), + .s_axi_rresp (s_axi_rresp[1:0]), + .s_axi_rvalid (s_axi_rvalid), + .s_axi_wready (s_axi_wready), + // Inputs + .wr_wait (s_wr_wait), // Templated + .rd_wait (s_rd_wait), // Templated + .rr_access (s_rr_access), // Templated + .rr_packet (s_rr_packet[PW-1:0]), // Templated + .s_axi_aclk (sys_clk), // Templated + .s_axi_aresetn (s_axi_aresetn), + .s_axi_arid (s_axi_arid[S_IDW-1:0]), + .s_axi_araddr (s_axi_araddr[31:0]), + .s_axi_arburst (s_axi_arburst[1:0]), + .s_axi_arcache (s_axi_arcache[3:0]), + .s_axi_arlock (s_axi_arlock), + .s_axi_arlen (s_axi_arlen[7:0]), + .s_axi_arprot (s_axi_arprot[2:0]), + .s_axi_arqos (s_axi_arqos[3:0]), + .s_axi_arsize (s_axi_arsize[2:0]), + .s_axi_arvalid (s_axi_arvalid), + .s_axi_awid (s_axi_awid[S_IDW-1:0]), + .s_axi_awaddr (s_axi_awaddr[31:0]), + .s_axi_awburst (s_axi_awburst[1:0]), + .s_axi_awcache (s_axi_awcache[3:0]), + .s_axi_awlock (s_axi_awlock), + .s_axi_awlen (s_axi_awlen[7:0]), + .s_axi_awprot (s_axi_awprot[2:0]), + .s_axi_awqos (s_axi_awqos[3:0]), + .s_axi_awsize (s_axi_awsize[2:0]), + .s_axi_awvalid (s_axi_awvalid), + .s_axi_bready (s_axi_bready), + .s_axi_rready (s_axi_rready), + .s_axi_wid (s_axi_wid[S_IDW-1:0]), + .s_axi_wdata (s_axi_wdata[31:0]), + .s_axi_wlast (s_axi_wlast), + .s_axi_wstrb (s_axi_wstrb[3:0]), + .s_axi_wvalid (s_axi_wvalid)); + + + //######################################################## + //AXI MASTER + //######################################################## + + /* + emaxi AUTO_TEMPLATE + (.rr_\(.*\) (m_rr_\1[]), + .rd_\(.*\) (m_rd_\1[]), + .wr_\(.*\) (m_wr_\1[]), + .m_axi_aclk (sys_clk)); */ + emaxi #(.M_IDW(M_IDW)) + emaxi (/*AUTOINST*/ + // Outputs + .wr_wait (m_wr_wait), // Templated + .rd_wait (m_rd_wait), // Templated + .rr_access (m_rr_access), // Templated + .rr_packet (m_rr_packet[PW-1:0]), // Templated + .m_axi_awid (m_axi_awid[M_IDW-1:0]), + .m_axi_awaddr (m_axi_awaddr[31:0]), + .m_axi_awlen (m_axi_awlen[7:0]), + .m_axi_awsize (m_axi_awsize[2:0]), + .m_axi_awburst (m_axi_awburst[1:0]), + .m_axi_awlock (m_axi_awlock), + .m_axi_awcache (m_axi_awcache[3:0]), + .m_axi_awprot (m_axi_awprot[2:0]), + .m_axi_awqos (m_axi_awqos[3:0]), + .m_axi_awvalid (m_axi_awvalid), + .m_axi_wid (m_axi_wid[M_IDW-1:0]), + .m_axi_wdata (m_axi_wdata[63:0]), + .m_axi_wstrb (m_axi_wstrb[7:0]), + .m_axi_wlast (m_axi_wlast), + .m_axi_wvalid (m_axi_wvalid), + .m_axi_bready (m_axi_bready), + .m_axi_arid (m_axi_arid[M_IDW-1:0]), + .m_axi_araddr (m_axi_araddr[31:0]), + .m_axi_arlen (m_axi_arlen[7:0]), + .m_axi_arsize (m_axi_arsize[2:0]), + .m_axi_arburst (m_axi_arburst[1:0]), + .m_axi_arlock (m_axi_arlock), + .m_axi_arcache (m_axi_arcache[3:0]), + .m_axi_arprot (m_axi_arprot[2:0]), + .m_axi_arqos (m_axi_arqos[3:0]), + .m_axi_arvalid (m_axi_arvalid), + .m_axi_rready (m_axi_rready), + // Inputs + .wr_access (m_wr_access), // Templated + .wr_packet (m_wr_packet[PW-1:0]), // Templated + .rd_access (m_rd_access), // Templated + .rd_packet (m_rd_packet[PW-1:0]), // Templated + .rr_wait (m_rr_wait), // Templated + .m_axi_aclk (sys_clk), // Templated + .m_axi_aresetn (m_axi_aresetn), + .m_axi_awready (m_axi_awready), + .m_axi_wready (m_axi_wready), + .m_axi_bid (m_axi_bid[M_IDW-1:0]), + .m_axi_bresp (m_axi_bresp[1:0]), + .m_axi_bvalid (m_axi_bvalid), + .m_axi_arready (m_axi_arready), + .m_axi_rid (m_axi_rid[M_IDW-1:0]), + .m_axi_rdata (m_axi_rdata[63:0]), + .m_axi_rresp (m_axi_rresp[1:0]), + .m_axi_rlast (m_axi_rlast), + .m_axi_rvalid (m_axi_rvalid)); + +endmodule // axi_mio +// Local Variables: +// verilog-library-directories:("." "../../axi/hdl" "../../common/hdl" "../../emesh/hdl") +// End: diff --git a/src/mio/hdl/mio_dp.v b/src/mio/hdl/mio_dp.v index 5df8d1e0..45501144 100644 --- a/src/mio/hdl/mio_dp.v +++ b/src/mio/hdl/mio_dp.v @@ -61,7 +61,8 @@ module mio_dp (/*AUTOARG*/ /*AUTOWIRE*/ mtx #(.NMIO(NMIO), - .PW(PW)) + .PW(PW), + .TARGET(TARGET)) mtx (/*AUTOINST*/ // Outputs .tx_empty (tx_empty), @@ -83,7 +84,8 @@ module mio_dp (/*AUTOARG*/ .tx_wait (tx_wait)); mrx #(.NMIO(NMIO), - .PW(PW)) + .PW(PW), + .TARGET(TARGET)) mrx (/*AUTOINST*/ // Outputs .rx_empty (rx_empty), diff --git a/src/mio/hdl/mio_regs.v b/src/mio/hdl/mio_regs.v index 89af6ef4..181e2433 100644 --- a/src/mio/hdl/mio_regs.v +++ b/src/mio/hdl/mio_regs.v @@ -77,9 +77,9 @@ module mio_regs (/*AUTOARG*/ // End of automatics //regs - reg [18:0] config_reg; - reg [7:0] status_reg; - wire [7:0] status_in; + reg [20:0] config_reg; + reg [15:0] status_reg; + wire [7:0] status_in; reg [31:0] clkdiv_reg; reg [63:0] addr_reg; reg [31:0] clkphase_reg; @@ -120,10 +120,10 @@ module mio_regs (/*AUTOARG*/ always @ (posedge clk or negedge nreset) if(!nreset) begin - config_reg[18:0] <= DEF_CFG; + config_reg[20:0] <= DEF_CFG; end else if(config_write) - config_reg[18:0] <= data_in[18:0]; + config_reg[20:0] <= data_in[20:0]; assign tx_en = ~config_reg[0]; // tx disable assign rx_en = ~config_reg[1]; // rx disable @@ -134,6 +134,7 @@ module mio_regs (/*AUTOARG*/ assign ddr_mode = config_reg[12]; // dual data rate mode assign lsbfirst = config_reg[13]; // lsb-first transmit assign framepol = config_reg[14]; // frame polarity + // config_reg[15] is reserved ??? assign ctrlmode[4:0] = config_reg[20:16]; // ctrlmode //############################### @@ -150,11 +151,11 @@ module mio_regs (/*AUTOARG*/ always @ (posedge clk or negedge nreset) if(!nreset) - status_reg[7:0] <= 'b0; + status_reg[15:0] <= 'b0; else if(status_write) - status_reg[7:0] <= data_in[7:0]; + status_reg[15:0] <= data_in[15:0]; else - status_reg[7:0] <= {(status_reg[15:8] | status_in[7:0]), // sticky bits + status_reg[15:0] <= {(status_reg[15:8] | status_in[7:0]), // sticky bits status_in[7:0]}; // immediate bits //############################### @@ -199,9 +200,32 @@ module mio_regs (/*AUTOARG*/ //############################### //# READBACK //################################ - assign access_out ='b0; - assign wait_out ='b0; - assign packet_out ='b0; + + wire reg_read = ~write_in & access_in; + reg [63:0] read_data; + + always @(posedge clk) + if(reg_read) + case(dstaddr_in[5:2]) + `MIO_STATUS : read_data[63:0] <= {{(48){1'b0}}, + status_reg[15:0]}; + default : read_data[63:0] <= 'b0; + endcase + + emesh_readback #(.AW(AW), + .PW(PW)) + emesh_readback (/*AUTOINST*/ + // Outputs + .wait_out (wait_out), + .access_out (access_out), + .packet_out (packet_out[PW-1:0]), + // Inputs + .nreset (nreset), + .clk (clk), + .access_in (access_in), + .packet_in (packet_in[PW-1:0]), + .read_data (read_data[63:0]), + .wait_in (wait_in)); endmodule // Local Variables: diff --git a/src/mio/hdl/mrx_io.v b/src/mio/hdl/mrx_io.v index 8600eb7a..7c217ff5 100644 --- a/src/mio/hdl/mrx_io.v +++ b/src/mio/hdl/mrx_io.v @@ -40,16 +40,6 @@ module mrx_io (/*AUTOARG*/ reg [2*NMIO-1:0] sdr_data; reg byte0_sel; - //######################################## - //# CLOCK, RESET - //######################################## - - //synchronize reset to rx_clk - oh_rsync oh_rsync(.nrst_out (io_nreset), - .clk (rx_clk), - .nrst_in (nreset) - ); - //######################################## //# SELECT FRAME POLARITY //######################################## @@ -60,7 +50,7 @@ module mrx_io (/*AUTOARG*/ //# ACCESS (SDR) //######################################## - always @ (posedge rx_clk or negedge io_nreset) + always @ (posedge rx_clk or negedge nreset) if(!nreset) io_access <= 1'b0; else diff --git a/src/mio/hdl/parallella_mio.v b/src/mio/hdl/parallella_mio.v new file mode 100644 index 00000000..872e84b2 --- /dev/null +++ b/src/mio/hdl/parallella_mio.v @@ -0,0 +1,298 @@ +//############################################################################# +//# Purpose: Parallella MIO top # +//############################################################################# +//# Author: Ola Jeppsson # +//# SPDX-License-Identifier: MIT # +//############################################################################# + +module parallella_mio(/*AUTOARG*/ + // Outputs + s_axi_wready, s_axi_rvalid, s_axi_rresp, s_axi_rlast, s_axi_rid, + s_axi_rdata, s_axi_bvalid, s_axi_bresp, s_axi_bid, s_axi_awready, + s_axi_arready, m_axi_wvalid, m_axi_wstrb, m_axi_wlast, m_axi_wid, + m_axi_wdata, m_axi_rready, m_axi_bready, m_axi_awvalid, + m_axi_awsize, m_axi_awqos, m_axi_awprot, m_axi_awlock, m_axi_awlen, + m_axi_awid, m_axi_awcache, m_axi_awburst, m_axi_awaddr, + m_axi_arvalid, m_axi_arsize, m_axi_arqos, m_axi_arprot, + m_axi_arlock, m_axi_arlen, m_axi_arid, m_axi_arcache, + m_axi_arburst, m_axi_araddr, constant_zero, constant_one, + // Inouts + gpio_n, gpio_p, + // Inputs + s_axi_wvalid, s_axi_wstrb, s_axi_wlast, s_axi_wid, s_axi_wdata, + s_axi_rready, s_axi_bready, s_axi_awvalid, s_axi_awsize, + s_axi_awqos, s_axi_awprot, s_axi_awlock, s_axi_awlen, s_axi_awid, + s_axi_awcache, s_axi_awburst, s_axi_awaddr, s_axi_arvalid, + s_axi_arsize, s_axi_arqos, s_axi_arprot, s_axi_arlock, s_axi_arlen, + s_axi_arid, s_axi_aresetn, s_axi_arcache, s_axi_arburst, + s_axi_araddr, m_axi_wready, m_axi_rvalid, m_axi_rresp, m_axi_rlast, + m_axi_rid, m_axi_rdata, m_axi_bvalid, m_axi_bresp, m_axi_bid, + m_axi_awready, m_axi_arready, m_axi_aresetn, sys_nreset, sys_clk + ); + + //######################################################## + // INTERFACE + //######################################################## + parameter AW = 32; // address width + parameter DW = 32; + parameter PW = 2*AW+40; // packet width + parameter ID = 12'h7fd; // addr[31:20] id + parameter REMAPID = 12'h3e0; // addr[31:20] id + parameter S_IDW = 12; // ID width for S_AXI + parameter M_IDW = 6; // ID width for M_AXI + parameter NGPIO = 24; // number of gpio pins + parameter NMIO = 8; // MIO IO packet width + parameter TARGET = "XILINX"; // XILINX,ALTERA,GENERIC,ASIC + + // constants + output constant_zero; // Always 0 + output constant_one; // Always 1 + + //clk, reset + input sys_nreset; // active low async reset + input sys_clk; // system clock for AXI + + // gpio pins + inout [NGPIO-1:0] gpio_n; // physical mio pins + inout [NGPIO-1:0] gpio_p; // physical mio pins + wire [NGPIO-1:0] gpio_in; // out gpio pins + wire [NGPIO-1:0] gpio_out; // in gpio pins + wire [NGPIO-1:0] gpio_dir; // gpio pin direction + + // mio io signals + wire mio_tx_wait; + wire mio_tx_access; + wire mio_tx_clk; + wire [NMIO-1:0] mio_tx_packet; + wire mio_rx_access; + wire mio_rx_clk; + wire [NMIO-1:0] mio_rx_packet; + wire mio_rx_wait; + + //############################################################## + //AUTOS + //############################################################## + + /*AUTOINPUT*/ + // Beginning of automatic inputs (from unused autoinst inputs) + input m_axi_aresetn; // To axi_mio of axi_mio.v + input m_axi_arready; // To axi_mio of axi_mio.v + input m_axi_awready; // To axi_mio of axi_mio.v + input [M_IDW-1:0] m_axi_bid; // To axi_mio of axi_mio.v + input [1:0] m_axi_bresp; // To axi_mio of axi_mio.v + input m_axi_bvalid; // To axi_mio of axi_mio.v + input [63:0] m_axi_rdata; // To axi_mio of axi_mio.v + input [M_IDW-1:0] m_axi_rid; // To axi_mio of axi_mio.v + input m_axi_rlast; // To axi_mio of axi_mio.v + input [1:0] m_axi_rresp; // To axi_mio of axi_mio.v + input m_axi_rvalid; // To axi_mio of axi_mio.v + input m_axi_wready; // To axi_mio of axi_mio.v + input [31:0] s_axi_araddr; // To axi_mio of axi_mio.v + input [1:0] s_axi_arburst; // To axi_mio of axi_mio.v + input [3:0] s_axi_arcache; // To axi_mio of axi_mio.v + input s_axi_aresetn; // To axi_mio of axi_mio.v + input [S_IDW-1:0] s_axi_arid; // To axi_mio of axi_mio.v + input [7:0] s_axi_arlen; // To axi_mio of axi_mio.v + input s_axi_arlock; // To axi_mio of axi_mio.v + input [2:0] s_axi_arprot; // To axi_mio of axi_mio.v + input [3:0] s_axi_arqos; // To axi_mio of axi_mio.v + input [2:0] s_axi_arsize; // To axi_mio of axi_mio.v + input s_axi_arvalid; // To axi_mio of axi_mio.v + input [31:0] s_axi_awaddr; // To axi_mio of axi_mio.v + input [1:0] s_axi_awburst; // To axi_mio of axi_mio.v + input [3:0] s_axi_awcache; // To axi_mio of axi_mio.v + input [S_IDW-1:0] s_axi_awid; // To axi_mio of axi_mio.v + input [7:0] s_axi_awlen; // To axi_mio of axi_mio.v + input s_axi_awlock; // To axi_mio of axi_mio.v + input [2:0] s_axi_awprot; // To axi_mio of axi_mio.v + input [3:0] s_axi_awqos; // To axi_mio of axi_mio.v + input [2:0] s_axi_awsize; // To axi_mio of axi_mio.v + input s_axi_awvalid; // To axi_mio of axi_mio.v + input s_axi_bready; // To axi_mio of axi_mio.v + input s_axi_rready; // To axi_mio of axi_mio.v + input [31:0] s_axi_wdata; // To axi_mio of axi_mio.v + input [S_IDW-1:0] s_axi_wid; // To axi_mio of axi_mio.v + input s_axi_wlast; // To axi_mio of axi_mio.v + input [3:0] s_axi_wstrb; // To axi_mio of axi_mio.v + input s_axi_wvalid; // To axi_mio of axi_mio.v + // End of automatics + + /*AUTOINPUT("^[ms]_axi_")*/ + + /*AUTOOUTPUT("^[ms]_axi_")*/ + // Beginning of automatic outputs (from unused autoinst outputs) + output [31:0] m_axi_araddr; // From axi_mio of axi_mio.v + output [1:0] m_axi_arburst; // From axi_mio of axi_mio.v + output [3:0] m_axi_arcache; // From axi_mio of axi_mio.v + output [M_IDW-1:0] m_axi_arid; // From axi_mio of axi_mio.v + output [7:0] m_axi_arlen; // From axi_mio of axi_mio.v + output m_axi_arlock; // From axi_mio of axi_mio.v + output [2:0] m_axi_arprot; // From axi_mio of axi_mio.v + output [3:0] m_axi_arqos; // From axi_mio of axi_mio.v + output [2:0] m_axi_arsize; // From axi_mio of axi_mio.v + output m_axi_arvalid; // From axi_mio of axi_mio.v + output [31:0] m_axi_awaddr; // From axi_mio of axi_mio.v + output [1:0] m_axi_awburst; // From axi_mio of axi_mio.v + output [3:0] m_axi_awcache; // From axi_mio of axi_mio.v + output [M_IDW-1:0] m_axi_awid; // From axi_mio of axi_mio.v + output [7:0] m_axi_awlen; // From axi_mio of axi_mio.v + output m_axi_awlock; // From axi_mio of axi_mio.v + output [2:0] m_axi_awprot; // From axi_mio of axi_mio.v + output [3:0] m_axi_awqos; // From axi_mio of axi_mio.v + output [2:0] m_axi_awsize; // From axi_mio of axi_mio.v + output m_axi_awvalid; // From axi_mio of axi_mio.v + output m_axi_bready; // From axi_mio of axi_mio.v + output m_axi_rready; // From axi_mio of axi_mio.v + output [63:0] m_axi_wdata; // From axi_mio of axi_mio.v + output [M_IDW-1:0] m_axi_wid; // From axi_mio of axi_mio.v + output m_axi_wlast; // From axi_mio of axi_mio.v + output [7:0] m_axi_wstrb; // From axi_mio of axi_mio.v + output m_axi_wvalid; // From axi_mio of axi_mio.v + output s_axi_arready; // From axi_mio of axi_mio.v + output s_axi_awready; // From axi_mio of axi_mio.v + output [S_IDW-1:0] s_axi_bid; // From axi_mio of axi_mio.v + output [1:0] s_axi_bresp; // From axi_mio of axi_mio.v + output s_axi_bvalid; // From axi_mio of axi_mio.v + output [31:0] s_axi_rdata; // From axi_mio of axi_mio.v + output [S_IDW-1:0] s_axi_rid; // From axi_mio of axi_mio.v + output s_axi_rlast; // From axi_mio of axi_mio.v + output [1:0] s_axi_rresp; // From axi_mio of axi_mio.v + output s_axi_rvalid; // From axi_mio of axi_mio.v + output s_axi_wready; // From axi_mio of axi_mio.v + // End of automatics + + /*AUTOWIRE*/ + + //############################################################## + //GPIO + //############################################################## + + // assign mio_s_ss = gpio_in[10]; + // assign mio_s_miso = gpio_out[9]; + // assign mio_s_mosi = gpio_in[8]; + // assign mio_rx_clk = gpio_in[7]; /* Must map to a MRCC/SRCC pin */ + // assign mio_m_ss = gpio_out[6]; + // assign mio_m_miso = gpio_in[5]; + // assign mio_m_mosi = gpio_out[4]; + // assign mio_m_sclk = gpio_out[3]; + + /* NOTE: 0 = in, 1 = out */ + assign gpio_dir[NGPIO-1:0] = {{(NGPIO-11){1'b0}}, 8'b01001011, 3'b000}; + + assign constant_zero = 1'b0; + assign constant_one = 1'b1; + + pgpio #(.NGPIO(NGPIO),.NPS(NGPIO),.SLEW("FAST")) + pgpio (.ps_gpio_i (gpio_in[NGPIO-1:0]), + .ps_gpio_o (gpio_out[NGPIO-1:0]), + .ps_gpio_t (~gpio_dir[NGPIO-1:0]), + /*AUTOINST*/ + // Inouts + .gpio_p (gpio_p[NGPIO-1:0]), + .gpio_n (gpio_n[NGPIO-1:0])); + + + //############################################################## + //AXI + //############################################################## + axi_mio #(.S_IDW(S_IDW), + .M_IDW(M_IDW), + .AW(AW), + .ID(ID), + .REMAPID(REMAPID), + .TARGET(TARGET), + .NMIO(NMIO)) + axi_mio ( + /* HACK: connect to GPIO pins later */ + .mio_rx_access (mio_tx_access), + .mio_rx_clk (mio_tx_clk), + .mio_rx_packet (mio_tx_packet[NMIO-1:0]), + .mio_tx_wait (mio_rx_wait), + /*AUTOINST*/ + // Outputs + .m_axi_araddr (m_axi_araddr[31:0]), + .m_axi_arburst (m_axi_arburst[1:0]), + .m_axi_arcache (m_axi_arcache[3:0]), + .m_axi_arid (m_axi_arid[M_IDW-1:0]), + .m_axi_arlen (m_axi_arlen[7:0]), + .m_axi_arlock (m_axi_arlock), + .m_axi_arprot (m_axi_arprot[2:0]), + .m_axi_arqos (m_axi_arqos[3:0]), + .m_axi_arsize (m_axi_arsize[2:0]), + .m_axi_arvalid (m_axi_arvalid), + .m_axi_awaddr (m_axi_awaddr[31:0]), + .m_axi_awburst (m_axi_awburst[1:0]), + .m_axi_awcache (m_axi_awcache[3:0]), + .m_axi_awid (m_axi_awid[M_IDW-1:0]), + .m_axi_awlen (m_axi_awlen[7:0]), + .m_axi_awlock (m_axi_awlock), + .m_axi_awprot (m_axi_awprot[2:0]), + .m_axi_awqos (m_axi_awqos[3:0]), + .m_axi_awsize (m_axi_awsize[2:0]), + .m_axi_awvalid (m_axi_awvalid), + .m_axi_bready (m_axi_bready), + .m_axi_rready (m_axi_rready), + .m_axi_wdata (m_axi_wdata[63:0]), + .m_axi_wid (m_axi_wid[M_IDW-1:0]), + .m_axi_wlast (m_axi_wlast), + .m_axi_wstrb (m_axi_wstrb[7:0]), + .m_axi_wvalid (m_axi_wvalid), + .s_axi_arready (s_axi_arready), + .s_axi_awready (s_axi_awready), + .s_axi_bid (s_axi_bid[S_IDW-1:0]), + .s_axi_bresp (s_axi_bresp[1:0]), + .s_axi_bvalid (s_axi_bvalid), + .s_axi_rdata (s_axi_rdata[31:0]), + .s_axi_rid (s_axi_rid[S_IDW-1:0]), + .s_axi_rlast (s_axi_rlast), + .s_axi_rresp (s_axi_rresp[1:0]), + .s_axi_rvalid (s_axi_rvalid), + .s_axi_wready (s_axi_wready), + // Inputs + .sys_nreset (sys_nreset), + .sys_clk (sys_clk), + .m_axi_aresetn (m_axi_aresetn), + .m_axi_arready (m_axi_arready), + .m_axi_awready (m_axi_awready), + .m_axi_bid (m_axi_bid[M_IDW-1:0]), + .m_axi_bresp (m_axi_bresp[1:0]), + .m_axi_bvalid (m_axi_bvalid), + .m_axi_rdata (m_axi_rdata[63:0]), + .m_axi_rid (m_axi_rid[M_IDW-1:0]), + .m_axi_rlast (m_axi_rlast), + .m_axi_rresp (m_axi_rresp[1:0]), + .m_axi_rvalid (m_axi_rvalid), + .m_axi_wready (m_axi_wready), + .s_axi_araddr (s_axi_araddr[31:0]), + .s_axi_arburst (s_axi_arburst[1:0]), + .s_axi_arcache (s_axi_arcache[3:0]), + .s_axi_aresetn (s_axi_aresetn), + .s_axi_arid (s_axi_arid[S_IDW-1:0]), + .s_axi_arlen (s_axi_arlen[7:0]), + .s_axi_arlock (s_axi_arlock), + .s_axi_arprot (s_axi_arprot[2:0]), + .s_axi_arqos (s_axi_arqos[3:0]), + .s_axi_arsize (s_axi_arsize[2:0]), + .s_axi_arvalid (s_axi_arvalid), + .s_axi_awaddr (s_axi_awaddr[31:0]), + .s_axi_awburst (s_axi_awburst[1:0]), + .s_axi_awcache (s_axi_awcache[3:0]), + .s_axi_awid (s_axi_awid[S_IDW-1:0]), + .s_axi_awlen (s_axi_awlen[7:0]), + .s_axi_awlock (s_axi_awlock), + .s_axi_awprot (s_axi_awprot[2:0]), + .s_axi_awqos (s_axi_awqos[3:0]), + .s_axi_awsize (s_axi_awsize[2:0]), + .s_axi_awvalid (s_axi_awvalid), + .s_axi_bready (s_axi_bready), + .s_axi_rready (s_axi_rready), + .s_axi_wdata (s_axi_wdata[31:0]), + .s_axi_wid (s_axi_wid[S_IDW-1:0]), + .s_axi_wlast (s_axi_wlast), + .s_axi_wstrb (s_axi_wstrb[3:0]), + .s_axi_wvalid (s_axi_wvalid)); + +endmodule // parallella_mio +// Local Variables: +// verilog-library-directories:("." "../../axi/hdl" "../../common/hdl" "../../emesh/hdl" "../../parallella/hdl") +// End: diff --git a/src/parallella/fpga/parallella_accelerator/system_params.tcl b/src/parallella/fpga/parallella_accelerator/system_params.tcl index 5256e6a3..eb71c94a 100644 --- a/src/parallella/fpga/parallella_accelerator/system_params.tcl +++ b/src/parallella/fpga/parallella_accelerator/system_params.tcl @@ -22,7 +22,7 @@ set hdl_files [list \ ] set ip_files [list \ - $root/xilibs/ip/fifo_async_104x32.xci \ + $root/xilibs/ip/fifo_async_104x32/fifo_async_104x32.xci \ ] set constraints_files [] diff --git a/src/parallella/fpga/parallella_base/system_params.tcl b/src/parallella/fpga/parallella_base/system_params.tcl index af2ec8ae..770db358 100644 --- a/src/parallella/fpga/parallella_base/system_params.tcl +++ b/src/parallella/fpga/parallella_base/system_params.tcl @@ -20,7 +20,7 @@ set hdl_files [list \ ] set ip_files [list \ - $root/xilibs/ip/fifo_async_104x32.xci \ + $root/xilibs/ip/fifo_async_104x32/fifo_async_104x32.xci \ ] set constraints_files [] diff --git a/src/spi/fpga/ip_params.tcl b/src/spi/fpga/ip_params.tcl index 77a4bf9a..48233033 100644 --- a/src/spi/fpga/ip_params.tcl +++ b/src/spi/fpga/ip_params.tcl @@ -17,7 +17,9 @@ set hdl_files [list \ $root/parallella/hdl \ ] -set ip_files [] +set ip_files [list \ + $root/xilibs/ip/fifo_async_104x32/fifo_async_104x32.xci \ + ] set constraints_files [] diff --git a/src/spi/fpga/system_params.tcl b/src/spi/fpga/system_params.tcl index 3f042e9f..83aeef60 100644 --- a/src/spi/fpga/system_params.tcl +++ b/src/spi/fpga/system_params.tcl @@ -20,7 +20,9 @@ set hdl_files [list \ $root/parallella/hdl \ ] -set ip_files [] +set ip_files [list \ + $root/xilibs/ip/fifo_async_104x32/fifo_async_104x32.xci \ + ] set constraints_files [list \ ../../parallella/fpga/parallella_io.xdc \ diff --git a/src/xilibs/hdl/fifo_async_128x32.v b/src/xilibs/hdl/fifo_async_128x32.v new file mode 100644 index 00000000..5a203fb8 --- /dev/null +++ b/src/xilibs/hdl/fifo_async_128x32.v @@ -0,0 +1,522 @@ +// (c) Copyright 1995-2016 Xilinx, Inc. All rights reserved. +// +// This file contains confidential and proprietary information +// of Xilinx, Inc. and is protected under U.S. and +// international copyright and other intellectual property +// laws. +// +// DISCLAIMER +// This disclaimer is not a license and does not grant any +// rights to the materials distributed herewith. Except as +// otherwise provided in a valid license issued to you by +// Xilinx, and to the maximum extent permitted by applicable +// law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND +// WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES +// AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING +// BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON- +// INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and +// (2) Xilinx shall not be liable (whether in contract or tort, +// including negligence, or under any other theory of +// liability) for any loss or damage of any kind or nature +// related to, arising under or in connection with these +// materials, including for any direct, or any indirect, +// special, incidental, or consequential loss or damage +// (including loss of data, profits, goodwill, or any type of +// loss or damage suffered as a result of any action brought +// by a third party) even if such damage or loss was +// reasonably foreseeable or Xilinx had been advised of the +// possibility of the same. +// +// CRITICAL APPLICATIONS +// Xilinx products are not designed or intended to be fail- +// safe, or for use in any application requiring fail-safe +// performance, such as life-support or safety devices or +// systems, Class III medical devices, nuclear facilities, +// applications related to the deployment of airbags, or any +// other applications that could lead to death, personal +// injury, or severe property or environmental damage +// (individually and collectively, "Critical +// Applications"). Customer assumes the sole risk and +// liability of any use of Xilinx products in Critical +// Applications, subject only to applicable laws and +// regulations governing limitations on product liability. +// +// THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS +// PART OF THIS FILE AT ALL TIMES. +// +// DO NOT MODIFY THIS FILE. + + +// IP VLNV: xilinx.com:ip:fifo_generator:12.0 +// IP Revision: 4 + +(* DowngradeIPIdentifiedWarnings = "yes" *) +module fifo_async_128x32 ( + rst, + wr_clk, + rd_clk, + din, + wr_en, + rd_en, + dout, + full, + empty, + rd_data_count, + prog_full +); + +input wire rst; +(* X_INTERFACE_INFO = "xilinx.com:signal:clock:1.0 write_clk CLK" *) +input wire wr_clk; +(* X_INTERFACE_INFO = "xilinx.com:signal:clock:1.0 read_clk CLK" *) +input wire rd_clk; +(* X_INTERFACE_INFO = "xilinx.com:interface:fifo_write:1.0 FIFO_WRITE WR_DATA" *) +input wire [127 : 0] din; +(* X_INTERFACE_INFO = "xilinx.com:interface:fifo_write:1.0 FIFO_WRITE WR_EN" *) +input wire wr_en; +(* X_INTERFACE_INFO = "xilinx.com:interface:fifo_read:1.0 FIFO_READ RD_EN" *) +input wire rd_en; +(* X_INTERFACE_INFO = "xilinx.com:interface:fifo_read:1.0 FIFO_READ RD_DATA" *) +output wire [127 : 0] dout; +(* X_INTERFACE_INFO = "xilinx.com:interface:fifo_write:1.0 FIFO_WRITE FULL" *) +output wire full; +(* X_INTERFACE_INFO = "xilinx.com:interface:fifo_read:1.0 FIFO_READ EMPTY" *) +output wire empty; +output wire [4 : 0] rd_data_count; +output wire prog_full; + + fifo_generator_vlog_beh #( + .C_COMMON_CLOCK(0), + .C_COUNT_TYPE(0), + .C_DATA_COUNT_WIDTH(5), + .C_DEFAULT_VALUE("BlankString"), + .C_DIN_WIDTH(128), + .C_DOUT_RST_VAL("0"), + .C_DOUT_WIDTH(128), + .C_ENABLE_RLOCS(0), + .C_FAMILY("zynq"), + .C_FULL_FLAGS_RST_VAL(0), + .C_HAS_ALMOST_EMPTY(0), + .C_HAS_ALMOST_FULL(0), + .C_HAS_BACKUP(0), + .C_HAS_DATA_COUNT(0), + .C_HAS_INT_CLK(0), + .C_HAS_MEMINIT_FILE(0), + .C_HAS_OVERFLOW(0), + .C_HAS_RD_DATA_COUNT(1), + .C_HAS_RD_RST(0), + .C_HAS_RST(1), + .C_HAS_SRST(0), + .C_HAS_UNDERFLOW(0), + .C_HAS_VALID(0), + .C_HAS_WR_ACK(0), + .C_HAS_WR_DATA_COUNT(0), + .C_HAS_WR_RST(0), + .C_IMPLEMENTATION_TYPE(2), + .C_INIT_WR_PNTR_VAL(0), + .C_MEMORY_TYPE(2), + .C_MIF_FILE_NAME("BlankString"), + .C_OPTIMIZATION_MODE(0), + .C_OVERFLOW_LOW(0), + .C_PRELOAD_LATENCY(1), + .C_PRELOAD_REGS(0), + .C_PRIM_FIFO_TYPE("512x72"), + .C_PROG_EMPTY_THRESH_ASSERT_VAL(2), + .C_PROG_EMPTY_THRESH_NEGATE_VAL(3), + .C_PROG_EMPTY_TYPE(0), + .C_PROG_FULL_THRESH_ASSERT_VAL(16), + .C_PROG_FULL_THRESH_NEGATE_VAL(15), + .C_PROG_FULL_TYPE(1), + .C_RD_DATA_COUNT_WIDTH(5), + .C_RD_DEPTH(32), + .C_RD_FREQ(1), + .C_RD_PNTR_WIDTH(5), + .C_UNDERFLOW_LOW(0), + .C_USE_DOUT_RST(1), + .C_USE_ECC(0), + .C_USE_EMBEDDED_REG(0), + .C_USE_PIPELINE_REG(0), + .C_POWER_SAVING_MODE(0), + .C_USE_FIFO16_FLAGS(0), + .C_USE_FWFT_DATA_COUNT(0), + .C_VALID_LOW(0), + .C_WR_ACK_LOW(0), + .C_WR_DATA_COUNT_WIDTH(5), + .C_WR_DEPTH(32), + .C_WR_FREQ(1), + .C_WR_PNTR_WIDTH(5), + .C_WR_RESPONSE_LATENCY(1), + .C_MSGON_VAL(1), + .C_ENABLE_RST_SYNC(1), + .C_ERROR_INJECTION_TYPE(0), + .C_SYNCHRONIZER_STAGE(2), + .C_INTERFACE_TYPE(0), + .C_AXI_TYPE(1), + .C_HAS_AXI_WR_CHANNEL(1), + .C_HAS_AXI_RD_CHANNEL(1), + .C_HAS_SLAVE_CE(0), + .C_HAS_MASTER_CE(0), + .C_ADD_NGC_CONSTRAINT(0), + .C_USE_COMMON_OVERFLOW(0), + .C_USE_COMMON_UNDERFLOW(0), + .C_USE_DEFAULT_SETTINGS(0), + .C_AXI_ID_WIDTH(1), + .C_AXI_ADDR_WIDTH(32), + .C_AXI_DATA_WIDTH(64), + .C_AXI_LEN_WIDTH(8), + .C_AXI_LOCK_WIDTH(1), + .C_HAS_AXI_ID(0), + .C_HAS_AXI_AWUSER(0), + .C_HAS_AXI_WUSER(0), + .C_HAS_AXI_BUSER(0), + .C_HAS_AXI_ARUSER(0), + .C_HAS_AXI_RUSER(0), + .C_AXI_ARUSER_WIDTH(1), + .C_AXI_AWUSER_WIDTH(1), + .C_AXI_WUSER_WIDTH(1), + .C_AXI_BUSER_WIDTH(1), + .C_AXI_RUSER_WIDTH(1), + .C_HAS_AXIS_TDATA(1), + .C_HAS_AXIS_TID(0), + .C_HAS_AXIS_TDEST(0), + .C_HAS_AXIS_TUSER(1), + .C_HAS_AXIS_TREADY(1), + .C_HAS_AXIS_TLAST(0), + .C_HAS_AXIS_TSTRB(0), + .C_HAS_AXIS_TKEEP(0), + .C_AXIS_TDATA_WIDTH(8), + .C_AXIS_TID_WIDTH(1), + .C_AXIS_TDEST_WIDTH(1), + .C_AXIS_TUSER_WIDTH(4), + .C_AXIS_TSTRB_WIDTH(1), + .C_AXIS_TKEEP_WIDTH(1), + .C_WACH_TYPE(0), + .C_WDCH_TYPE(0), + .C_WRCH_TYPE(0), + .C_RACH_TYPE(0), + .C_RDCH_TYPE(0), + .C_AXIS_TYPE(0), + .C_IMPLEMENTATION_TYPE_WACH(1), + .C_IMPLEMENTATION_TYPE_WDCH(1), + .C_IMPLEMENTATION_TYPE_WRCH(1), + .C_IMPLEMENTATION_TYPE_RACH(1), + .C_IMPLEMENTATION_TYPE_RDCH(1), + .C_IMPLEMENTATION_TYPE_AXIS(1), + .C_APPLICATION_TYPE_WACH(0), + .C_APPLICATION_TYPE_WDCH(0), + .C_APPLICATION_TYPE_WRCH(0), + .C_APPLICATION_TYPE_RACH(0), + .C_APPLICATION_TYPE_RDCH(0), + .C_APPLICATION_TYPE_AXIS(0), + .C_PRIM_FIFO_TYPE_WACH("512x36"), + .C_PRIM_FIFO_TYPE_WDCH("1kx36"), + .C_PRIM_FIFO_TYPE_WRCH("512x36"), + .C_PRIM_FIFO_TYPE_RACH("512x36"), + .C_PRIM_FIFO_TYPE_RDCH("1kx36"), + .C_PRIM_FIFO_TYPE_AXIS("1kx18"), + .C_USE_ECC_WACH(0), + .C_USE_ECC_WDCH(0), + .C_USE_ECC_WRCH(0), + .C_USE_ECC_RACH(0), + .C_USE_ECC_RDCH(0), + .C_USE_ECC_AXIS(0), + .C_ERROR_INJECTION_TYPE_WACH(0), + .C_ERROR_INJECTION_TYPE_WDCH(0), + .C_ERROR_INJECTION_TYPE_WRCH(0), + .C_ERROR_INJECTION_TYPE_RACH(0), + .C_ERROR_INJECTION_TYPE_RDCH(0), + .C_ERROR_INJECTION_TYPE_AXIS(0), + .C_DIN_WIDTH_WACH(32), + .C_DIN_WIDTH_WDCH(64), + .C_DIN_WIDTH_WRCH(2), + .C_DIN_WIDTH_RACH(32), + .C_DIN_WIDTH_RDCH(64), + .C_DIN_WIDTH_AXIS(1), + .C_WR_DEPTH_WACH(16), + .C_WR_DEPTH_WDCH(1024), + .C_WR_DEPTH_WRCH(16), + .C_WR_DEPTH_RACH(16), + .C_WR_DEPTH_RDCH(1024), + .C_WR_DEPTH_AXIS(1024), + .C_WR_PNTR_WIDTH_WACH(4), + .C_WR_PNTR_WIDTH_WDCH(10), + .C_WR_PNTR_WIDTH_WRCH(4), + .C_WR_PNTR_WIDTH_RACH(4), + .C_WR_PNTR_WIDTH_RDCH(10), + .C_WR_PNTR_WIDTH_AXIS(10), + .C_HAS_DATA_COUNTS_WACH(0), + .C_HAS_DATA_COUNTS_WDCH(0), + .C_HAS_DATA_COUNTS_WRCH(0), + .C_HAS_DATA_COUNTS_RACH(0), + .C_HAS_DATA_COUNTS_RDCH(0), + .C_HAS_DATA_COUNTS_AXIS(0), + .C_HAS_PROG_FLAGS_WACH(0), + .C_HAS_PROG_FLAGS_WDCH(0), + .C_HAS_PROG_FLAGS_WRCH(0), + .C_HAS_PROG_FLAGS_RACH(0), + .C_HAS_PROG_FLAGS_RDCH(0), + .C_HAS_PROG_FLAGS_AXIS(0), + .C_PROG_FULL_TYPE_WACH(0), + .C_PROG_FULL_TYPE_WDCH(0), + .C_PROG_FULL_TYPE_WRCH(0), + .C_PROG_FULL_TYPE_RACH(0), + .C_PROG_FULL_TYPE_RDCH(0), + .C_PROG_FULL_TYPE_AXIS(0), + .C_PROG_FULL_THRESH_ASSERT_VAL_WACH(1023), + .C_PROG_FULL_THRESH_ASSERT_VAL_WDCH(1023), + .C_PROG_FULL_THRESH_ASSERT_VAL_WRCH(1023), + .C_PROG_FULL_THRESH_ASSERT_VAL_RACH(1023), + .C_PROG_FULL_THRESH_ASSERT_VAL_RDCH(1023), + .C_PROG_FULL_THRESH_ASSERT_VAL_AXIS(1023), + .C_PROG_EMPTY_TYPE_WACH(0), + .C_PROG_EMPTY_TYPE_WDCH(0), + .C_PROG_EMPTY_TYPE_WRCH(0), + .C_PROG_EMPTY_TYPE_RACH(0), + .C_PROG_EMPTY_TYPE_RDCH(0), + .C_PROG_EMPTY_TYPE_AXIS(0), + .C_PROG_EMPTY_THRESH_ASSERT_VAL_WACH(1022), + .C_PROG_EMPTY_THRESH_ASSERT_VAL_WDCH(1022), + .C_PROG_EMPTY_THRESH_ASSERT_VAL_WRCH(1022), + .C_PROG_EMPTY_THRESH_ASSERT_VAL_RACH(1022), + .C_PROG_EMPTY_THRESH_ASSERT_VAL_RDCH(1022), + .C_PROG_EMPTY_THRESH_ASSERT_VAL_AXIS(1022), + .C_REG_SLICE_MODE_WACH(0), + .C_REG_SLICE_MODE_WDCH(0), + .C_REG_SLICE_MODE_WRCH(0), + .C_REG_SLICE_MODE_RACH(0), + .C_REG_SLICE_MODE_RDCH(0), + .C_REG_SLICE_MODE_AXIS(0) + ) inst ( + .backup(1'D0), + .backup_marker(1'D0), + .clk(1'D0), + .rst(rst), + .srst(1'D0), + .wr_clk(wr_clk), + .wr_rst(1'D0), + .rd_clk(rd_clk), + .rd_rst(1'D0), + .din(din), + .wr_en(wr_en), + .rd_en(rd_en), + .prog_empty_thresh(5'B0), + .prog_empty_thresh_assert(5'B0), + .prog_empty_thresh_negate(5'B0), + .prog_full_thresh(5'B0), + .prog_full_thresh_assert(5'B0), + .prog_full_thresh_negate(5'B0), + .int_clk(1'D0), + .injectdbiterr(1'D0), + .injectsbiterr(1'D0), + .sleep(1'D0), + .dout(dout), + .full(full), + .almost_full(), + .wr_ack(), + .overflow(), + .empty(empty), + .almost_empty(), + .valid(), + .underflow(), + .data_count(), + .rd_data_count(rd_data_count), + .wr_data_count(), + .prog_full(prog_full), + .prog_empty(), + .sbiterr(), + .dbiterr(), + .wr_rst_busy(), + .rd_rst_busy(), + .m_aclk(1'D0), + .s_aclk(1'D0), + .s_aresetn(1'D0), + .m_aclk_en(1'D0), + .s_aclk_en(1'D0), + .s_axi_awid(1'B0), + .s_axi_awaddr(32'B0), + .s_axi_awlen(8'B0), + .s_axi_awsize(3'B0), + .s_axi_awburst(2'B0), + .s_axi_awlock(1'B0), + .s_axi_awcache(4'B0), + .s_axi_awprot(3'B0), + .s_axi_awqos(4'B0), + .s_axi_awregion(4'B0), + .s_axi_awuser(1'B0), + .s_axi_awvalid(1'D0), + .s_axi_awready(), + .s_axi_wid(1'B0), + .s_axi_wdata(64'B0), + .s_axi_wstrb(8'B0), + .s_axi_wlast(1'D0), + .s_axi_wuser(1'B0), + .s_axi_wvalid(1'D0), + .s_axi_wready(), + .s_axi_bid(), + .s_axi_bresp(), + .s_axi_buser(), + .s_axi_bvalid(), + .s_axi_bready(1'D0), + .m_axi_awid(), + .m_axi_awaddr(), + .m_axi_awlen(), + .m_axi_awsize(), + .m_axi_awburst(), + .m_axi_awlock(), + .m_axi_awcache(), + .m_axi_awprot(), + .m_axi_awqos(), + .m_axi_awregion(), + .m_axi_awuser(), + .m_axi_awvalid(), + .m_axi_awready(1'D0), + .m_axi_wid(), + .m_axi_wdata(), + .m_axi_wstrb(), + .m_axi_wlast(), + .m_axi_wuser(), + .m_axi_wvalid(), + .m_axi_wready(1'D0), + .m_axi_bid(1'B0), + .m_axi_bresp(2'B0), + .m_axi_buser(1'B0), + .m_axi_bvalid(1'D0), + .m_axi_bready(), + .s_axi_arid(1'B0), + .s_axi_araddr(32'B0), + .s_axi_arlen(8'B0), + .s_axi_arsize(3'B0), + .s_axi_arburst(2'B0), + .s_axi_arlock(1'B0), + .s_axi_arcache(4'B0), + .s_axi_arprot(3'B0), + .s_axi_arqos(4'B0), + .s_axi_arregion(4'B0), + .s_axi_aruser(1'B0), + .s_axi_arvalid(1'D0), + .s_axi_arready(), + .s_axi_rid(), + .s_axi_rdata(), + .s_axi_rresp(), + .s_axi_rlast(), + .s_axi_ruser(), + .s_axi_rvalid(), + .s_axi_rready(1'D0), + .m_axi_arid(), + .m_axi_araddr(), + .m_axi_arlen(), + .m_axi_arsize(), + .m_axi_arburst(), + .m_axi_arlock(), + .m_axi_arcache(), + .m_axi_arprot(), + .m_axi_arqos(), + .m_axi_arregion(), + .m_axi_aruser(), + .m_axi_arvalid(), + .m_axi_arready(1'D0), + .m_axi_rid(1'B0), + .m_axi_rdata(64'B0), + .m_axi_rresp(2'B0), + .m_axi_rlast(1'D0), + .m_axi_ruser(1'B0), + .m_axi_rvalid(1'D0), + .m_axi_rready(), + .s_axis_tvalid(1'D0), + .s_axis_tready(), + .s_axis_tdata(8'B0), + .s_axis_tstrb(1'B0), + .s_axis_tkeep(1'B0), + .s_axis_tlast(1'D0), + .s_axis_tid(1'B0), + .s_axis_tdest(1'B0), + .s_axis_tuser(4'B0), + .m_axis_tvalid(), + .m_axis_tready(1'D0), + .m_axis_tdata(), + .m_axis_tstrb(), + .m_axis_tkeep(), + .m_axis_tlast(), + .m_axis_tid(), + .m_axis_tdest(), + .m_axis_tuser(), + .axi_aw_injectsbiterr(1'D0), + .axi_aw_injectdbiterr(1'D0), + .axi_aw_prog_full_thresh(4'B0), + .axi_aw_prog_empty_thresh(4'B0), + .axi_aw_data_count(), + .axi_aw_wr_data_count(), + .axi_aw_rd_data_count(), + .axi_aw_sbiterr(), + .axi_aw_dbiterr(), + .axi_aw_overflow(), + .axi_aw_underflow(), + .axi_aw_prog_full(), + .axi_aw_prog_empty(), + .axi_w_injectsbiterr(1'D0), + .axi_w_injectdbiterr(1'D0), + .axi_w_prog_full_thresh(10'B0), + .axi_w_prog_empty_thresh(10'B0), + .axi_w_data_count(), + .axi_w_wr_data_count(), + .axi_w_rd_data_count(), + .axi_w_sbiterr(), + .axi_w_dbiterr(), + .axi_w_overflow(), + .axi_w_underflow(), + .axi_w_prog_full(), + .axi_w_prog_empty(), + .axi_b_injectsbiterr(1'D0), + .axi_b_injectdbiterr(1'D0), + .axi_b_prog_full_thresh(4'B0), + .axi_b_prog_empty_thresh(4'B0), + .axi_b_data_count(), + .axi_b_wr_data_count(), + .axi_b_rd_data_count(), + .axi_b_sbiterr(), + .axi_b_dbiterr(), + .axi_b_overflow(), + .axi_b_underflow(), + .axi_b_prog_full(), + .axi_b_prog_empty(), + .axi_ar_injectsbiterr(1'D0), + .axi_ar_injectdbiterr(1'D0), + .axi_ar_prog_full_thresh(4'B0), + .axi_ar_prog_empty_thresh(4'B0), + .axi_ar_data_count(), + .axi_ar_wr_data_count(), + .axi_ar_rd_data_count(), + .axi_ar_sbiterr(), + .axi_ar_dbiterr(), + .axi_ar_overflow(), + .axi_ar_underflow(), + .axi_ar_prog_full(), + .axi_ar_prog_empty(), + .axi_r_injectsbiterr(1'D0), + .axi_r_injectdbiterr(1'D0), + .axi_r_prog_full_thresh(10'B0), + .axi_r_prog_empty_thresh(10'B0), + .axi_r_data_count(), + .axi_r_wr_data_count(), + .axi_r_rd_data_count(), + .axi_r_sbiterr(), + .axi_r_dbiterr(), + .axi_r_overflow(), + .axi_r_underflow(), + .axi_r_prog_full(), + .axi_r_prog_empty(), + .axis_injectsbiterr(1'D0), + .axis_injectdbiterr(1'D0), + .axis_prog_full_thresh(10'B0), + .axis_prog_empty_thresh(10'B0), + .axis_data_count(), + .axis_wr_data_count(), + .axis_rd_data_count(), + .axis_sbiterr(), + .axis_dbiterr(), + .axis_overflow(), + .axis_underflow(), + .axis_prog_full(), + .axis_prog_empty() + ); +endmodule diff --git a/src/xilibs/ip/fifo_async_104x32.xci b/src/xilibs/ip/fifo_async_104x32/fifo_async_104x32.xci similarity index 100% rename from src/xilibs/ip/fifo_async_104x32.xci rename to src/xilibs/ip/fifo_async_104x32/fifo_async_104x32.xci diff --git a/src/xilibs/ip/fifo_async_128x32/fifo_async_128x32.xci b/src/xilibs/ip/fifo_async_128x32/fifo_async_128x32.xci new file mode 100644 index 00000000..ed62f4e3 --- /dev/null +++ b/src/xilibs/ip/fifo_async_128x32/fifo_async_128x32.xci @@ -0,0 +1,413 @@ + + + xilinx.com + xci + unknown + 1.0 + + + fifo_async_128x32 + + + fifo_async_128x32 + Independent_Clocks_Distributed_RAM + 2 + 2 + Native + Standard_FIFO + false + 128 + 32 + 128 + 32 + false + false + true + true + Asynchronous_Reset + 0 + true + 0 + false + false + false + false + Active_High + false + Active_High + false + Active_High + false + Active_High + false + false + false + false + false + 5 + false + 5 + true + 5 + false + 1 + 1 + Single_Programmable_Full_Threshold_Constant + 16 + 15 + No_Programmable_Empty_Threshold + 2 + 3 + AXI4 + Common_Clock + false + Slave_Interface_Clock_Enable + READ_WRITE + 0 + 32 + 64 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 4 + true + false + false + 1 + false + 1 + FIFO + Common_Clock_Block_RAM + Data_FIFO + false + false + false + 16 + false + No_Programmable_Full_Threshold + 1023 + No_Programmable_Empty_Threshold + 1022 + FIFO + Common_Clock_Block_RAM + Data_FIFO + false + false + false + 1024 + false + No_Programmable_Full_Threshold + 1023 + No_Programmable_Empty_Threshold + 1022 + FIFO + Common_Clock_Block_RAM + Data_FIFO + false + false + false + 16 + false + No_Programmable_Full_Threshold + 1023 + No_Programmable_Empty_Threshold + 1022 + FIFO + Common_Clock_Block_RAM + Data_FIFO + false + false + false + 16 + false + No_Programmable_Full_Threshold + 1023 + No_Programmable_Empty_Threshold + 1022 + FIFO + Common_Clock_Block_RAM + Data_FIFO + false + false + false + 1024 + false + No_Programmable_Full_Threshold + 1023 + No_Programmable_Empty_Threshold + 1022 + FIFO + Common_Clock_Block_RAM + Data_FIFO + false + false + false + 1024 + false + No_Programmable_Full_Threshold + 1023 + No_Programmable_Empty_Threshold + 1022 + Fully_Registered + Fully_Registered + Fully_Registered + Fully_Registered + Fully_Registered + Fully_Registered + false + Active_High + false + Active_High + false + false + false + false + false + false + false + false + false + true + 0 + 0 + 5 + BlankString + 128 + 0 + 128 + 0 + zynq + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 2 + 0 + 2 + BlankString + 0 + 0 + 1 + 0 + 512x72 + 2 + 3 + 0 + 16 + 15 + 1 + 5 + 32 + 1 + 5 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 5 + 32 + 1 + 5 + 1 + 1 + 1 + 0 + 2 + 0 + 1 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 32 + 64 + 8 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 8 + 1 + 1 + 4 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 512x36 + 1kx36 + 512x36 + 512x36 + 1kx36 + 1kx18 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 32 + 64 + 2 + 32 + 64 + 1 + 16 + 1024 + 16 + 16 + 1024 + 1024 + 4 + 10 + 4 + 4 + 10 + 10 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1023 + 1023 + 1023 + 1023 + 1023 + 1023 + 0 + 0 + 0 + 0 + 0 + 0 + 1022 + 1022 + 1022 + 1022 + 1022 + 1022 + 0 + 0 + 0 + 0 + 0 + 0 + 100000000 + 100000000 + 100000000 + 100000000 + 100000000 + zynq + xc7z020 + clg400 + -1 + C + + VERILOG + MIXED + TRUE + TRUE + + TRUE + 2015.2 + 4 + OUT_OF_CONTEXT + + . + . + IP_Flow + + + + + + + + + + + + + +