├── lib ├── CMakeLists.txt └── ep2 │ ├── MakefileHelpers │ └── netronome.suffix │ ├── AtomAnalysis.cpp │ ├── HandlerInOutAnalysis.cpp │ ├── StructUpdatePropagationPass.cpp │ ├── TableAnalysis.cpp │ ├── Passes │ ├── Mapping │ │ └── PipeliningPass.cpp │ └── GlobalToPartitionPass.cpp │ ├── ControllerAnalysis.cpp.bk │ └── CMakeLists.txt ├── include ├── ep2 │ ├── CMakeLists.txt │ ├── dialect │ │ ├── CMakeLists.txt │ │ ├── MLIRGen.h │ │ └── Dialect.h │ ├── Utilities.h │ └── passes │ │ └── LiftUtils.h ├── CMakeLists.txt └── Standalone │ ├── CMakeLists.txt │ ├── StandaloneTypes.h │ ├── StandaloneDialect.h │ ├── StandaloneOps.h │ ├── StandalonePasses.h │ ├── StandalonePasses.td │ ├── StandaloneTypes.td │ ├── StandaloneOps.td │ └── StandaloneDialect.td ├── runtime_lib ├── netronome_runtime │ ├── .gitignore │ ├── lib │ │ ├── extern │ │ │ ├── extern_net.c │ │ │ └── extern_net_meta.h │ │ └── lmem_lookup.h │ ├── microc │ │ ├── lib │ │ │ ├── std │ │ │ │ ├── reorder.h │ │ │ │ ├── _c │ │ │ │ │ └── reorder.c │ │ │ │ └── libstd.c │ │ │ ├── nfp │ │ │ │ ├── ctm.h │ │ │ │ ├── libnfp.c │ │ │ │ ├── tmq.h │ │ │ │ ├── mac_csr_synch.h │ │ │ │ └── _c │ │ │ │ │ └── mac_csr_synch.c │ │ │ ├── lu │ │ │ │ └── liblu.c │ │ │ └── net │ │ │ │ ├── libnet.c │ │ │ │ ├── esp.h │ │ │ │ ├── ah.h │ │ │ │ ├── vxlan.h │ │ │ │ ├── mpls.h │ │ │ │ ├── udp.h │ │ │ │ ├── arp.h │ │ │ │ ├── sctp.h │ │ │ │ └── gre.h │ │ ├── COPYING │ │ ├── blocks │ │ │ ├── gro │ │ │ │ ├── Makefile.netro │ │ │ │ ├── _uc │ │ │ │ │ └── gro_internal.uc │ │ │ │ └── scripts │ │ │ │ │ ├── grodump.sh │ │ │ │ │ └── ucverify.py │ │ │ └── init │ │ │ │ ├── init_main.uc │ │ │ │ └── _uc │ │ │ │ ├── init_nbi_pc_csr.uc │ │ │ │ ├── init_nbi.uc │ │ │ │ └── init_nbi_pc.uc │ │ └── include │ │ │ ├── types.h │ │ │ ├── nfcc_compatibility.h │ │ │ └── stdint.h │ ├── README.md │ ├── include │ │ ├── nfp6000 │ │ │ ├── nfp_xpb.h │ │ │ └── nfp6000.h │ │ ├── nfp-common │ │ │ └── nfp_platform.h │ │ ├── common.h │ │ ├── rte │ │ │ └── branch_prediction.h │ │ ├── params.h │ │ ├── fp_mem.h │ │ ├── connect.h │ │ ├── fp_debug.h │ │ └── fp_app_if.h │ ├── COPYING │ └── scripts │ │ ├── Makefile.debug │ │ └── Makefile.nfp.config └── fpga_runtime │ ├── rtl_lib │ ├── verilog-cam │ │ ├── README │ │ ├── AUTHORS │ │ ├── .gitignore │ │ ├── README.md │ │ ├── COPYING │ │ └── tb │ │ │ └── test_priority_encoder.v │ ├── axi │ │ ├── AUTHORS │ │ ├── .gitignore │ │ └── COPYING │ ├── axis │ │ ├── AUTHORS │ │ ├── .gitignore │ │ ├── .travis.yml │ │ ├── COPYING │ │ └── rtl │ │ │ └── sync_reset.v │ ├── clk.xdc │ └── ep2 │ │ ├── reg.sv │ │ ├── ram.sv │ │ ├── barrier.sv │ │ ├── atom_cam.sv │ │ ├── ctrl_dispatcher.sv │ │ ├── barrier_queue.sv │ │ └── alu.sv │ └── src │ └── flextoemini_src │ └── __ep2top.sv ├── tests ├── output │ ├── fpga │ │ ├── flextoemini │ │ │ ├── __handler_OoO_DETECT_ooo_detect.sv │ │ │ └── __ep2top.sv │ │ ├── l2_echo │ │ │ └── __handler_NET_SEND.sv │ │ ├── ipsec │ │ │ └── __handler_DECRYPT_REQ_crypto.sv │ │ └── ids │ │ │ └── runfpga.sh │ ├── ifelse.opt.mlir │ ├── table_test.mlir │ ├── ifelse.mlir │ ├── cmp.mlir │ ├── ctx_assign_type.mlir │ ├── buf_to_value.buffer_to_value.mlir │ ├── buf_to_value.context_to_argument.mlir │ └── l2_echo.opt.mlir ├── global.ep2 ├── cmp.ep2 ├── ctx_assign_type.ep2 ├── ifelse.ep2 ├── cse.ep2 ├── experiments_c │ ├── generic_handlers.h │ ├── struct_split.c │ ├── l2_echo.c │ └── alkali.h ├── no_buf_table_test.txt ├── c_demo │ ├── generic_handlers.h │ ├── l2_echo.c │ └── alkali.h ├── ifelse_nested.ep2 ├── table_test.txt ├── specs │ └── fpga.json ├── buf_to_value.ep2 ├── example.ep2 ├── experiments │ └── l2_echo.ep2.txt └── pipeline_test │ └── nopipeline_small.mlir ├── .clang-format ├── example_outputs └── outs-netronome │ ├── out-netronome-ids │ └── cmd.sh │ ├── out-netronome-cpu_load │ ├── cmd.sh │ ├── prog_hdr.h │ └── process_packet_1.c │ ├── out-netronome-example │ ├── cmd.sh │ ├── process_desc.c │ ├── receive_desc.c │ ├── prog_hdr.h │ ├── canon.mlir │ └── example.mlir │ ├── out-netronome-l2_echo │ ├── cmd.sh │ ├── canon.mlir │ ├── prog_hdr.h │ ├── main_recv.c │ └── l2_echo.mlir │ └── out-netronome-transport_rx │ └── cmd.sh ├── .gitmodules ├── scripts ├── partition.sh ├── alkalic ├── run_llvm.sh ├── fpga_compile.sh ├── run_c.sh ├── netronome_compile.sh └── extract_struct_def.py ├── runtime-llvm ├── Makefile ├── extern.h ├── runtime.h ├── main.c └── externs.c ├── ep2c-opt └── CMakeLists.txt ├── ep2c └── CMakeLists.txt ├── LICENSE ├── CMakeLists.txt ├── .clang-tidy └── .gitignore /lib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(ep2) 2 | -------------------------------------------------------------------------------- /include/ep2/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(dialect) -------------------------------------------------------------------------------- /runtime_lib/netronome_runtime/.gitignore: -------------------------------------------------------------------------------- 1 | **/.vscode 2 | -------------------------------------------------------------------------------- /runtime_lib/fpga_runtime/rtl_lib/verilog-cam/README: -------------------------------------------------------------------------------- 1 | README.md -------------------------------------------------------------------------------- /tests/output/fpga/flextoemini/__handler_OoO_DETECT_ooo_detect.sv: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: LLVM 2 | AlwaysBreakTemplateDeclarations: Yes 3 | -------------------------------------------------------------------------------- /example_outputs/outs-netronome/out-netronome-ids/cmd.sh: -------------------------------------------------------------------------------- 1 | ./netronome.sh ids.ep2 2 | -------------------------------------------------------------------------------- /include/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(Standalone) 2 | add_subdirectory(ep2) 3 | -------------------------------------------------------------------------------- /runtime_lib/fpga_runtime/rtl_lib/axi/AUTHORS: -------------------------------------------------------------------------------- 1 | Alex Forencich 2 | -------------------------------------------------------------------------------- /example_outputs/outs-netronome/out-netronome-cpu_load/cmd.sh: -------------------------------------------------------------------------------- 1 | ./netronome.sh cpu_load.ep2 2 | -------------------------------------------------------------------------------- /example_outputs/outs-netronome/out-netronome-example/cmd.sh: -------------------------------------------------------------------------------- 1 | ./netronome.sh example.ep2 2 | -------------------------------------------------------------------------------- /example_outputs/outs-netronome/out-netronome-l2_echo/cmd.sh: -------------------------------------------------------------------------------- 1 | ./netronome.sh l2_echo.ep2 2 | -------------------------------------------------------------------------------- /runtime_lib/fpga_runtime/rtl_lib/axis/AUTHORS: -------------------------------------------------------------------------------- 1 | Alex Forencich 2 | -------------------------------------------------------------------------------- /runtime_lib/fpga_runtime/rtl_lib/verilog-cam/AUTHORS: -------------------------------------------------------------------------------- 1 | Alex Forencich 2 | -------------------------------------------------------------------------------- /example_outputs/outs-netronome/out-netronome-transport_rx/cmd.sh: -------------------------------------------------------------------------------- 1 | ./netronome.sh transport_rx.ep2 2 | -------------------------------------------------------------------------------- /runtime_lib/fpga_runtime/rtl_lib/axi/.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.lxt 3 | *.pyc 4 | *.vvp 5 | *.kate-swp 6 | 7 | -------------------------------------------------------------------------------- /runtime_lib/fpga_runtime/rtl_lib/axis/.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.lxt 3 | *.pyc 4 | *.vvp 5 | *.kate-swp 6 | 7 | -------------------------------------------------------------------------------- /runtime_lib/fpga_runtime/rtl_lib/verilog-cam/.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.lxt 3 | *.pyc 4 | *.vvp 5 | *.kate-swp 6 | 7 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "llvm-project"] 2 | path = llvm-project 3 | url = https://github.com/llvm/llvm-project 4 | -------------------------------------------------------------------------------- /runtime_lib/netronome_runtime/lib/extern/extern_net.c: -------------------------------------------------------------------------------- 1 | // This is the external function that receives newwork packets and gives it to the processing pipeline 2 | #include "nfplib.h" 3 | 4 | 5 | -------------------------------------------------------------------------------- /runtime_lib/fpga_runtime/rtl_lib/verilog-cam/README.md: -------------------------------------------------------------------------------- 1 | # Verilog CAM Readme 2 | 3 | For more information and updates: http://alexforencich.com/wiki/en/verilog/cam/start 4 | 5 | GitHub repository: https://github.com/alexforencich/verilog-cam 6 | 7 | ## Introduction 8 | 9 | FPGA-independent content addressable memory module. 10 | 11 | -------------------------------------------------------------------------------- /tests/output/fpga/l2_echo/__handler_NET_SEND.sv: -------------------------------------------------------------------------------- 1 | module __handler_NET_SEND#() 2 | ( 3 | input wire clk, 4 | input wire rst, 5 | //input ports BUF 6 | input wire [512-1:0] arg1_tdata , 7 | input wire [64-1:0] arg1_tkeep , 8 | input wire arg1_tlast , 9 | input wire arg1_tvalid , 10 | output wire arg1_tready 11 | ); 12 | 13 | endmodule 14 | -------------------------------------------------------------------------------- /tests/global.ep2: -------------------------------------------------------------------------------- 1 | scope scope_1 [flow_id]; 2 | [sync=scope_1] global bits<32> global_var; 3 | 4 | event MY_EVENT { 5 | atom at; 6 | context ctx; 7 | } 8 | 9 | [sync=scope_1] controller MY_EVENT() { 10 | } 11 | 12 | [sync=scope_1] handler MY_EVENT:my_handler_event (context ctx) { 13 | bits<32> result; 14 | result = global_var + 4; 15 | } -------------------------------------------------------------------------------- /scripts/partition.sh: -------------------------------------------------------------------------------- 1 | 2 | #!/bin/bash 3 | 4 | set -e 5 | 6 | cd llvm-project && ninja -C build/ && cd - 7 | ninja -C build/ 8 | 9 | ./build/bin/ep2c-opt -ep2-pipeline-handler -o /dev/null out.mlir 2>&1 | tee partition.log 10 | #./build/bin/ep2c-opt -ep2-pipeline-handler -o /dev/null tests/pipeline_test/nopipeline.mlir 2>&1 | tee partition.log 11 | dot -Tpng cut.dot > cut.png 12 | -------------------------------------------------------------------------------- /include/Standalone/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_mlir_dialect(StandaloneOps standalone) 2 | add_mlir_doc(StandaloneDialect StandaloneDialect Standalone/ -gen-dialect-doc) 3 | add_mlir_doc(StandaloneOps StandaloneOps Standalone/ -gen-op-doc) 4 | 5 | set(LLVM_TARGET_DEFINITIONS StandalonePasses.td) 6 | mlir_tablegen(StandalonePasses.h.inc --gen-pass-decls) 7 | add_public_tablegen_target(MLIRStandalonePassesIncGen) 8 | -------------------------------------------------------------------------------- /tests/cmp.ep2: -------------------------------------------------------------------------------- 1 | event MY_EVENT { 2 | atom at; 3 | context ctx; 4 | } 5 | 6 | handler MY_EVENT:my_handler_event (context ctx) { 7 | bits<32> a; 8 | bits<32> b; 9 | 10 | a = 1; 11 | b = 2; 12 | 13 | if (a > b) { 14 | ctx.a = a; 15 | } 16 | if (a < b) { 17 | ctx.a = a; 18 | } 19 | if (a >= b) { 20 | ctx.a = a; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /runtime_lib/fpga_runtime/rtl_lib/clk.xdc: -------------------------------------------------------------------------------- 1 | 2 | set_property -dict {LOC AR15} [get_ports refclk_1_p] ; 3 | set_property -dict {LOC AR14} [get_ports refclk_1_n] ; 4 | set_property -dict {LOC BH26 IOSTANDARD LVCMOS18 PULLUP true} [get_ports reset_n] ; 5 | 6 | 7 | create_clock -period 4 -name mgt_refclk_1 [get_ports refclk_1_p] 8 | 9 | set_false_path -from [get_ports {pcie_reset_n}] 10 | set_input_delay 0 [get_ports {pcie_reset_n}] -------------------------------------------------------------------------------- /tests/ctx_assign_type.ep2: -------------------------------------------------------------------------------- 1 | event A { 2 | atom at; 3 | context ctx; 4 | } 5 | 6 | event B { 7 | atom at; 8 | context ctx; 9 | } 10 | 11 | handler A:a (context ctx) { 12 | bits<48> t1; 13 | buf t2; 14 | ctx.t1 = t1; 15 | ctx.t2 = t2; 16 | generate B{ctx}; 17 | } 18 | 19 | 20 | handler B:b (context ctx) { 21 | bits<48> t1; 22 | buf out; 23 | t1 = ctx.t1; 24 | out.emit(ctx.t2); 25 | } -------------------------------------------------------------------------------- /runtime_lib/netronome_runtime/microc/lib/std/reorder.h: -------------------------------------------------------------------------------- 1 | #ifndef _STD__REORDER_H_ 2 | #define _STD__REORDER_H_ 3 | 4 | #include 5 | 6 | __intrinsic void reorder_start(unsigned int start_ctx, SIGNAL* sig); 7 | 8 | __intrinsic void reorder_signal(unsigned int next_ctx, SIGNAL* sig); 9 | 10 | __intrinsic void reorder_signal_next(SIGNAL* sig); 11 | 12 | __intrinsic void reorder_self(SIGNAL* sig); 13 | 14 | #endif /* _STD__REORDER_H_ */ 15 | -------------------------------------------------------------------------------- /tests/ifelse.ep2: -------------------------------------------------------------------------------- 1 | event MY_EVENT { 2 | atom at; 3 | context ctx; 4 | } 5 | 6 | handler MY_EVENT:my_handler_event (context ctx) { 7 | bits<1> cond; 8 | bits<32> result; 9 | result = 1; 10 | cond = 0; 11 | if (cond) { 12 | cond = 0; 13 | } else { 14 | result = 233; 15 | } 16 | 17 | if (cond) { 18 | ctx.const = 2; 19 | ctx.name = result; 20 | } 21 | result = result + 2; 22 | cond = cond + 1; 23 | } -------------------------------------------------------------------------------- /tests/cse.ep2: -------------------------------------------------------------------------------- 1 | # Specify the functionality of the target archiecture 2 | ############## main program ########### 3 | 4 | event LOAD_TABLE { 5 | context ctx; 6 | } 7 | 8 | struct eth_header_t { 9 | bits<48> dst_mac; 10 | bits<48> src_mac; 11 | bits<16> ether_type; 12 | } 13 | 14 | handler LOAD_TABLE:load_table (context ctx) { 15 | eth_header_t eth_header; 16 | eth_header.dst_mac = 0; 17 | 18 | ctx.a = eth_header.dst_mac; 19 | ctx.b = eth_header.dst_mac; 20 | } 21 | -------------------------------------------------------------------------------- /tests/experiments_c/generic_handlers.h: -------------------------------------------------------------------------------- 1 | #ifndef ALKALI_GENERIC_HANDLERS_H 2 | #define ALKALI_GENERIC_HANDLERS_H 3 | 4 | #include "alkali.h" 5 | 6 | void EXT__NET_SEND__net_send(buf_t packet); 7 | void EXT__DMA_WRITE_REQ__dma_write(buf_t packet, void *dma_cmd); 8 | 9 | #ifndef ALKALI_GENERIC_HANDLERS_NO_IMPL 10 | void EXT__NET_SEND__net_send(buf_t packet) { } 11 | void EXT__DMA_WRITE_REQ__dma_write(buf_t packet, void *dma_cmd) { } 12 | #endif // ALKALI_GENERIC_HANDLERS_NO_IMPL 13 | 14 | #endif // ALKALI_GENERIC_HANDLERS_H -------------------------------------------------------------------------------- /tests/no_buf_table_test.txt: -------------------------------------------------------------------------------- 1 | # Specify the functionality of the target archiecture 2 | ############## main program ########### 3 | 4 | event LOAD_TABLE { 5 | context ctx; 6 | } 7 | 8 | struct eth_header_t { 9 | bits<48> dst_mac; 10 | bits<48> src_mac; 11 | bits<16> ether_type; 12 | } 13 | 14 | handler LOAD_TABLE:load_table (context ctx) { 15 | table, bits<32>, 16> table1; 16 | 17 | table1.update(10, 11); 18 | table1.update(4, 3); 19 | table1.lookup(10); 20 | table1.lookup(4); 21 | 22 | } 23 | -------------------------------------------------------------------------------- /runtime_lib/fpga_runtime/rtl_lib/axis/.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | python: 3 | - "3.6" 4 | before_install: 5 | - export d=`pwd` 6 | - export PYTHON_EXE=`which python` 7 | - sudo apt-get update -qq 8 | - sudo apt-get install -y iverilog 9 | - git clone https://github.com/jandecaluwe/myhdl.git 10 | - cd $d/myhdl && sudo $PYTHON_EXE setup.py install 11 | - cd $d/myhdl/cosimulation/icarus && make && sudo install -m 0755 -D ./myhdl.vpi /usr/lib/x86_64-linux-gnu/ivl/myhdl.vpi 12 | - cd $d 13 | script: 14 | - cd tb && IVERILOG_DUMPER=none py.test 15 | 16 | -------------------------------------------------------------------------------- /tests/c_demo/generic_handlers.h: -------------------------------------------------------------------------------- 1 | #ifndef ALKALI_GENERIC_HANDLERS_H 2 | #define ALKALI_GENERIC_HANDLERS_H 3 | 4 | #include "alkali.h" 5 | 6 | void NET_RECV__process_packet(buf_t packet); 7 | void EXT__NET_SEND__net_send(buf_t packet); 8 | void EXT__DMA_WRITE_REQ__dma_write(buf_t packet, void *dma_cmd); 9 | 10 | #ifndef ALKALI_GENERIC_HANDLERS_NO_IMPL 11 | void EXT__NET_SEND__net_send(buf_t packet) { } 12 | void EXT__DMA_WRITE_REQ__dma_write(buf_t packet, void *dma_cmd) { } 13 | #endif // ALKALI_GENERIC_HANDLERS_NO_IMPL 14 | 15 | #endif // ALKALI_GENERIC_HANDLERS_H 16 | 17 | -------------------------------------------------------------------------------- /runtime-llvm/Makefile: -------------------------------------------------------------------------------- 1 | CLANG_BIN := /home/depctg/EP2-MLIR/llvm-project/build/bin 2 | CC := $(CLANG_BIN)/clang 3 | 4 | LDFLAGS = $(shell pkgconf -libs glib-2.0) -lpthread -target $(TARGET) 5 | CFLAGS = -O2 $(shell pkgconf --cflags glib-2.0) -gdwarf-4 -target $(TARGET) 6 | 7 | OBJECTS = runtime.o driver.o externs.o ep2.o ep2.inc.o 8 | BIN = runep2 9 | 10 | all : $(BIN) 11 | 12 | runep2 : $(OBJECTS) 13 | $(CC) -gdwarf-4 -o $@ $^ $(LDFLAGS) 14 | 15 | # already generated 16 | ep2.o : ; 17 | 18 | %.o : %.c 19 | $(CC) $(CFLAGS) -c -o $@ $< 20 | 21 | clean : 22 | rm -f *.o *.inc.* $(BIN) 23 | -------------------------------------------------------------------------------- /tests/ifelse_nested.ep2: -------------------------------------------------------------------------------- 1 | event MY_EVENT { 2 | atom at; 3 | context ctx; 4 | } 5 | 6 | handler MY_EVENT:my_handler_event (context ctx) { 7 | bits<1> cond; 8 | bits<32> result; 9 | bits<64> name; 10 | result = 1; 11 | cond = 0; 12 | if (cond) { 13 | cond = 0; 14 | if (cond) { 15 | ctx.const = 2; 16 | ctx.name = result; 17 | result = 566; 18 | name = 12341412; 19 | } 20 | } else { 21 | result = 233; 22 | } 23 | 24 | result = result + 2; 25 | cond = cond + 1; 26 | } 27 | -------------------------------------------------------------------------------- /runtime-llvm/extern.h: -------------------------------------------------------------------------------- 1 | #ifndef _EP2_RUNTIME_EXTERN_H_ 2 | #define _EP2_RUNTIME_EXTERN_H_ 3 | 4 | #include "runtime.h" 5 | 6 | struct event_NET_SEND { 7 | void *ctx; 8 | buf_t buf; 9 | }; 10 | 11 | struct event_NET_RECV { 12 | void *ctx; 13 | buf_t buf; 14 | }; 15 | 16 | typedef void * (*pthread_worker_t)(void *); 17 | void * __extern_source_NET_RECV(extern_worker_t *worker); 18 | void * __extern_sink_NET_SEND(extern_worker_t *worker); 19 | 20 | void __handler_DMA_WRITE_REQ_dma_write(void *, void *); 21 | void __handler_DMA_SEND_dma_send(void *, void *); 22 | void __handler_NET_SEND_net_send(void *); 23 | 24 | #endif // _EP2_RUNTIME_EXTERN_H_ -------------------------------------------------------------------------------- /tests/table_test.txt: -------------------------------------------------------------------------------- 1 | # Specify the functionality of the target archiecture 2 | ############## main program ########### 3 | 4 | event LOAD_TABLE { 5 | context ctx; 6 | } 7 | 8 | struct eth_header_t { 9 | bits<48> dst_mac; 10 | bits<48> src_mac; 11 | bits<16> ether_type; 12 | } 13 | 14 | handler LOAD_TABLE:load_table (context ctx) { 15 | table, bits<32>, 16> table1; 16 | table table2; 17 | 18 | eth_header_t tmp; 19 | tmp.dst_mac = 2; 20 | 21 | table1.update(10, 11); 22 | table1.update(tmp, 12); 23 | 24 | ctx.a = table1.lookup(10); 25 | ctx.b = table2.lookup(tmp); 26 | } 27 | -------------------------------------------------------------------------------- /runtime_lib/netronome_runtime/microc/lib/nfp/ctm.h: -------------------------------------------------------------------------------- 1 | #ifndef _NFP__CTM_H_ 2 | #define _NFP__CTM_H_ 3 | 4 | #include 5 | #include 6 | 7 | __intrinsic void ctm_ring_setup(unsigned int rnum, __ctm40 void* base, size_t size); 8 | __intrinsic void ctm_ring_get(unsigned int isl, unsigned int rnum, 9 | __xread void* data, size_t size, 10 | sync_t sync, SIGNAL* sig); 11 | __intrinsic void ctm_ring_put(unsigned int isl, unsigned int rnum, 12 | __xwrite void* data, size_t size, 13 | sync_t sync, SIGNAL* sig); 14 | 15 | #endif /* _NFP__CTM_H_ */ 16 | -------------------------------------------------------------------------------- /include/ep2/dialect/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # add the attr definitions 2 | set(LLVM_TARGET_DEFINITIONS EP2Ops.td) 3 | mlir_tablegen(EP2OpsAttrDefs.h.inc -gen-attrdef-decls 4 | -attrdefs-dialect=ep2) 5 | mlir_tablegen(EP2OpsAttrDefs.cpp.inc -gen-attrdef-defs 6 | -attrdefs-dialect=ep2) 7 | add_public_tablegen_target(EP2OpsAttrDefsIncGen) 8 | 9 | # get the rest of the definitions 10 | add_mlir_dialect(EP2Ops ep2) 11 | 12 | # set(LLVM_TARGET_DEFINITIONS Ops.td) 13 | # mlir_tablegen(StandalonePasses.h.inc --gen-pass-decls) 14 | # add_public_tablegen_target(MLIRStandalonePassesIncGen) 15 | 16 | # Most dialects should use add_mlir_dialect(). See examples/standalone. 17 | -------------------------------------------------------------------------------- /include/Standalone/StandaloneTypes.h: -------------------------------------------------------------------------------- 1 | //===- StandaloneTypes.h - Standalone dialect types -------------*- C++ -*-===// 2 | // 3 | // This file is licensed under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | #ifndef STANDALONE_STANDALONETYPES_H 10 | #define STANDALONE_STANDALONETYPES_H 11 | 12 | #include "mlir/IR/BuiltinTypes.h" 13 | 14 | #define GET_TYPEDEF_CLASSES 15 | #include "Standalone/StandaloneOpsTypes.h.inc" 16 | 17 | #endif // STANDALONE_STANDALONETYPES_H 18 | -------------------------------------------------------------------------------- /include/Standalone/StandaloneDialect.h: -------------------------------------------------------------------------------- 1 | //===- StandaloneDialect.h - Standalone dialect -----------------*- C++ -*-===// 2 | // 3 | // This file is licensed under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | #ifndef STANDALONE_STANDALONEDIALECT_H 10 | #define STANDALONE_STANDALONEDIALECT_H 11 | 12 | #include "mlir/Bytecode/BytecodeOpInterface.h" 13 | #include "mlir/IR/Dialect.h" 14 | 15 | #include "Standalone/StandaloneOpsDialect.h.inc" 16 | 17 | #endif // STANDALONE_STANDALONEDIALECT_H 18 | -------------------------------------------------------------------------------- /tests/specs/fpga.json: -------------------------------------------------------------------------------- 1 | { 2 | "computeUnits": [ 3 | { "id": "cu1", "mem": 0, "cpu": 0 }, 4 | { "id": "cu2", "mem": 0, "cpu": 0 }, 5 | { "id": "cu3", "mem": 0, "cpu": 0 }, 6 | { "id": "cu4", "mem": 0, "cpu": 0 }, 7 | { "id": "cu5", "mem": 0, "cpu": 0 }, 8 | { "id": "cu6", "mem": 0, "cpu": 0 } 9 | ], 10 | "memoryUnits": [ 11 | { "id": "sram", "mem": 0} 12 | ], 13 | "communicationMatrix": [ 14 | [0, 0, 0, 0, 0, 0], 15 | [0, 0, 0, 0, 0, 0], 16 | [0, 0, 0, 0, 0, 0], 17 | [0, 0, 0, 0, 0, 0], 18 | [0, 0, 0, 0, 0, 0], 19 | [0, 0, 0, 0, 0, 0] 20 | ], 21 | "memoryMatrix": [ 22 | [0], [0], [0], [0], [0], [0] 23 | ] 24 | } -------------------------------------------------------------------------------- /lib/ep2/MakefileHelpers/netronome.suffix: -------------------------------------------------------------------------------- 1 | 2 | # 3 | # Help 4 | # 5 | .PHONY : app_mlir_help 6 | app_mlir_help: 7 | @echo "Build Options:" 8 | @echo " Q unset to print compiler output" 9 | @echo "" 10 | @echo "Path Settings:" 11 | @echo " NFP_SDK_DIR SDK installation directory" 12 | @echo "" 13 | @echo "Targets:" 14 | @echo " help this text" 15 | @echo " clean removes compiled binaries" 16 | @echo "" 17 | @echo " wire.fw wire application (default)" 18 | @echo " mlir_dbg.fw wire application with single app ME" 19 | @echo "" 20 | 21 | all: core.fw 22 | 23 | clean: 24 | rm -f *.list 25 | rm -f *.uci 26 | rm -f *.ucp 27 | rm -f *.obj 28 | rm -f *.fw 29 | 30 | distclean: clean 31 | -------------------------------------------------------------------------------- /include/ep2/Utilities.h: -------------------------------------------------------------------------------- 1 | #ifndef _EP2_UTILITIES_H_ 2 | #define _EP2_UTILITIES_H_ 3 | 4 | #include 5 | 6 | #include "mlir/IR/BuiltinOps.h" 7 | 8 | namespace mlir { 9 | namespace ep2 { 10 | 11 | struct OperatorRemoveGuard { 12 | std::vector ops{}; 13 | ~OperatorRemoveGuard() { clear(); } 14 | bool clear() { 15 | auto empty = ops.empty(); 16 | for (auto op : ops) 17 | op->erase(); 18 | ops.clear(); 19 | return !empty; 20 | } 21 | void add(Operation *op) { ops.push_back(op); } 22 | template 23 | static void until(F &&f) { 24 | OperatorRemoveGuard guard; 25 | do { f(guard); } while (guard.clear()); 26 | } 27 | }; 28 | 29 | } // namespace ep2 30 | } // namespace mlir 31 | 32 | #endif // _EP2_UTILITIES_H_ -------------------------------------------------------------------------------- /runtime_lib/netronome_runtime/README.md: -------------------------------------------------------------------------------- 1 | # Netronome Backend Library 2 | 3 | ## Code Structure 4 | ```bash 5 | ./src # Code that generated by the Alkali compiler should be placed into this folder 6 | ./lib # Library functions for Netronome backend 7 | ./microc # Netronome micro C libaray 8 | ``` 9 | ## Build 10 | ```bash 11 | cd src 12 | make 13 | ``` 14 | 15 | ## Run it in Simulator 16 | ``` 17 | After make, ./core.fw will be generated under ./src. 18 | Follow instruction in [this link](https://wikis.utexas.edu/pages/viewpage.action?spaceKey=utns&title=Netronome+NIC+Simulator) to submit the binary to submit ./core.fw to the simulator. 19 | 20 | Will soon provide a detailed instruction of how to verify the program output in the netronome simulator. 21 | ``` 22 | -------------------------------------------------------------------------------- /runtime_lib/netronome_runtime/lib/extern/extern_net_meta.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _EXTERN_NET_META_H_ 3 | #define _EXTERN_NET_META_H_ 4 | 5 | struct recv_meta_t { 6 | union { 7 | struct { 8 | unsigned int seq:16; /**< Packet number of the packet */ 9 | unsigned int len:16; /**< Length of the packet in bytes 10 | (includes possible MAC prepend bytes) */ 11 | }; 12 | }; 13 | }; 14 | 15 | struct send_meta_t { 16 | union { 17 | struct { 18 | unsigned int seq:16; /**< Packet number of the packet */ 19 | unsigned int len:16; /**< Length of the packet in bytes 20 | (includes possible MAC prepend bytes) */ 21 | }; 22 | }; 23 | }; 24 | 25 | #endif 26 | 27 | -------------------------------------------------------------------------------- /runtime_lib/netronome_runtime/include/nfp6000/nfp_xpb.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: BSD-3-Clause 2 | * Copyright(c) 2018 Netronome Systems, Inc. 3 | * All rights reserved. 4 | */ 5 | 6 | #ifndef __NFP_XPB_H__ 7 | #define __NFP_XPB_H__ 8 | 9 | /* 10 | * For use with NFP6000 Databook "XPB Addressing" section 11 | */ 12 | #define NFP_XPB_OVERLAY(island) (((island) & 0x3f) << 24) 13 | 14 | #define NFP_XPB_ISLAND(island) (NFP_XPB_OVERLAY(island) + 0x60000) 15 | 16 | #define NFP_XPB_ISLAND_of(offset) (((offset) >> 24) & 0x3F) 17 | 18 | /* 19 | * For use with NFP6000 Databook "XPB Island and Device IDs" chapter 20 | */ 21 | #define NFP_XPB_DEVICE(island, slave, device) \ 22 | (NFP_XPB_OVERLAY(island) | \ 23 | (((slave) & 3) << 22) | \ 24 | (((device) & 0x3f) << 16)) 25 | 26 | #endif /* NFP_XPB_H */ 27 | -------------------------------------------------------------------------------- /include/Standalone/StandaloneOps.h: -------------------------------------------------------------------------------- 1 | //===- StandaloneOps.h - Standalone dialect ops -----------------*- C++ -*-===// 2 | // 3 | // This file is licensed under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | #ifndef STANDALONE_STANDALONEOPS_H 10 | #define STANDALONE_STANDALONEOPS_H 11 | 12 | #include "mlir/IR/BuiltinTypes.h" 13 | #include "mlir/IR/Dialect.h" 14 | #include "mlir/IR/OpDefinition.h" 15 | #include "mlir/Interfaces/InferTypeOpInterface.h" 16 | #include "mlir/Interfaces/SideEffectInterfaces.h" 17 | 18 | #define GET_OP_CLASSES 19 | #include "Standalone/StandaloneOps.h.inc" 20 | 21 | #endif // STANDALONE_STANDALONEOPS_H 22 | -------------------------------------------------------------------------------- /tests/buf_to_value.ep2: -------------------------------------------------------------------------------- 1 | event MY_EVENT { 2 | atom at; 3 | context ctx; 4 | buf b; 5 | bits<32> a; 6 | } 7 | 8 | event MY_EVENT_OUT { 9 | atom at; 10 | context ctx; 11 | buf b; 12 | bits<32> a; 13 | } 14 | 15 | struct header { 16 | bits<32> field_a; 17 | bits<32> field_b; 18 | } 19 | 20 | handler MY_EVENT:my_handler_event (context ctx, buf b, int a) { 21 | int x; 22 | int y; 23 | int c; 24 | int z; 25 | header hdr; 26 | 27 | x = 1; 28 | y = 2; 29 | z = 4; 30 | b.extract(hdr); 31 | b.emit(hdr); 32 | # insert this here to test separation 33 | ctx.test = hdr.field_a; 34 | c = ctx.test; 35 | # if else test 36 | if (x < a) { 37 | ctx.test = z; 38 | ctx.bench = z; 39 | } else { 40 | ctx.test = y; 41 | } 42 | generate MY_EVENT_OUT:my_handler_event {ctx, b, c}; 43 | } -------------------------------------------------------------------------------- /runtime_lib/netronome_runtime/microc/lib/std/_c/reorder.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | __intrinsic 5 | void reorder_start(unsigned int start_ctx, SIGNAL* sig) 6 | { 7 | ctassert(__is_ct_const(start_ctx)); 8 | 9 | signal_ctx(start_ctx, __signal_number(sig)); 10 | __implicit_write(sig); 11 | } 12 | 13 | __intrinsic 14 | void reorder_signal(unsigned int next_ctx, SIGNAL* sig) 15 | { 16 | ctassert(__is_ct_const(next_ctx)); 17 | 18 | signal_ctx(next_ctx, __signal_number(sig)); 19 | __implicit_write(sig); 20 | } 21 | 22 | __intrinsic 23 | void reorder_signal_next(SIGNAL* sig) 24 | { 25 | signal_next_ctx(__signal_number(sig)); 26 | __implicit_write(sig); 27 | } 28 | 29 | __intrinsic void reorder_self(SIGNAL* sig) 30 | { 31 | unsigned int ctx; 32 | 33 | ctx = ctx(); 34 | signal_ctx(ctx, __signal_number(sig)); 35 | __implicit_write(sig); 36 | } 37 | -------------------------------------------------------------------------------- /tests/output/fpga/ipsec/__handler_DECRYPT_REQ_crypto.sv: -------------------------------------------------------------------------------- 1 | module __handler_DECRYPT_REQ_crypto#() 2 | ( 3 | input wire clk, 4 | input wire rst, 5 | //input ports BUF 6 | input wire [512-1:0] arg_0_tdata , 7 | input wire [64-1:0] arg_0_tkeep , 8 | input wire arg_0_tlast , 9 | input wire arg_0_tvalid , 10 | output wire arg_0_tready, 11 | //input ports STRUCT 12 | input wire [272-1:0] arg_1_tdata , 13 | input wire arg_1_tvalid , 14 | output wire arg_1_tready, 15 | //input ports STRUCT 16 | input wire [184-1:0] arg_2_tdata , 17 | input wire arg_2_tvalid , 18 | output wire arg_2_tready, 19 | //input ports STRUCT 20 | input wire [112-1:0] arg_3_tdata , 21 | input wire arg_3_tvalid , 22 | output wire arg_3_tready, 23 | //input ports STRUCT 24 | input wire [64-1:0] arg_4_tdata , 25 | input wire arg_4_tvalid , 26 | output wire arg_4_tready 27 | ); 28 | 29 | endmodule 30 | -------------------------------------------------------------------------------- /runtime_lib/netronome_runtime/COPYING: -------------------------------------------------------------------------------- 1 | This file is a summary of the licensing of files in this distribution. 2 | Some files may be marked specifically with a different license, in 3 | which case that license applies to the file in question. 4 | 5 | Most files are licensed under the Apache License, Version 2.0: 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at: 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | 19 | -------------------------------------------------------------------------------- /runtime_lib/netronome_runtime/microc/COPYING: -------------------------------------------------------------------------------- 1 | This file is a summary of the licensing of files in this distribution. 2 | Some files may be marked specifically with a different license, in 3 | which case that license applies to the file in question. 4 | 5 | Most files are licensed under the Apache License, Version 2.0: 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at: 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | 19 | -------------------------------------------------------------------------------- /tests/experiments_c/struct_split.c: -------------------------------------------------------------------------------- 1 | struct buf_t { 2 | char *data; 3 | short len; 4 | }; 5 | typedef struct buf_t buf_t; 6 | 7 | struct table_t { 8 | char *table; 9 | short size; 10 | }; 11 | typedef struct table_t table_t; 12 | 13 | struct pkt_info_t { 14 | int a,b,c,d,e,f; 15 | }; 16 | 17 | extern void send_packet(buf_t packet); 18 | extern void bufextract(buf_t packet, void *extracted_data); 19 | extern void bufemit(buf_t packet, void *extracted_data); 20 | 21 | void _packet_event_handler(buf_t packet) { 22 | struct pkt_info_t x,y,z; 23 | struct pkt_info_t s; 24 | 25 | bufextract(packet, (void *)&x); 26 | bufextract(packet, (void *)&y); 27 | bufextract(packet, (void *)&z); 28 | 29 | s.a = x.a + y.a + z.a; 30 | s.b = x.b + y.b + z.b; 31 | s.c = x.c + y.c + z.c; 32 | s.d = x.d + y.d + z.d; 33 | 34 | bufemit(packet, (void *)&s); 35 | send_packet(packet); 36 | } 37 | 38 | int main(){ 39 | return 0; 40 | } -------------------------------------------------------------------------------- /runtime_lib/netronome_runtime/microc/blocks/gro/Makefile.netro: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2018, Netronome Systems, Inc. All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | # @file me/blocks/gro/Makefile.netro 17 | # 18 | gro_reldir := $(SRCDIR_REL) 19 | gro_absdir := $(SRCDIR_ABS) 20 | 21 | gro-me_reldir := $(gro_reldir)/me 22 | gro-me_absdir := $(gro_absdir)/me 23 | 24 | -------------------------------------------------------------------------------- /include/Standalone/StandalonePasses.h: -------------------------------------------------------------------------------- 1 | //===- StandalonePasses.h - Standalone passes ------------------*- C++ -*-===// 2 | // 3 | // This file is licensed under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | #ifndef STANDALONE_STANDALONEPASSES_H 9 | #define STANDALONE_STANDALONEPASSES_H 10 | 11 | #include "Standalone/StandaloneDialect.h" 12 | #include "Standalone/StandaloneOps.h" 13 | #include "mlir/Pass/Pass.h" 14 | #include 15 | 16 | namespace mlir { 17 | namespace standalone { 18 | #define GEN_PASS_DECL 19 | #include "Standalone/StandalonePasses.h.inc" 20 | 21 | #define GEN_PASS_REGISTRATION 22 | #include "Standalone/StandalonePasses.h.inc" 23 | } // namespace standalone 24 | } // namespace mlir 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /lib/ep2/AtomAnalysis.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "ep2/dialect/Dialect.h" 3 | #include "ep2/dialect/Passes.h" 4 | 5 | #include "mlir/Pass/Pass.h" 6 | #include "mlir/IR/BuiltinOps.h" 7 | #include "mlir/IR/Visitors.h" 8 | #include "llvm/ADT/StringMap.h" 9 | #include "llvm/ADT/EquivalenceClasses.h" 10 | 11 | using namespace mlir; 12 | using namespace llvm; 13 | 14 | namespace mlir { 15 | namespace ep2 { 16 | 17 | AtomAnalysis::AtomAnalysis(Operation* module, AnalysisManager& am) { 18 | auto& m = this->atomToNum; 19 | size_t atomCtr = 0; 20 | module->walk([&](FuncOp op) { 21 | if (op->hasAttr("atom")) { 22 | llvm::StringRef k = op->getAttr("atom").cast().getValue(); 23 | llvm::StringRef event = op->getAttr("event").cast().getValue(); 24 | if (m.find(k) == m.end()) { 25 | m.try_emplace(k, std::pair{event.str(), atomCtr++}); 26 | } 27 | } 28 | }); 29 | } 30 | 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /tests/c_demo/l2_echo.c: -------------------------------------------------------------------------------- 1 | #include "alkali.h" 2 | #include "generic_handlers.h" 3 | 4 | struct eth_header_t { 5 | BITS_FIELD(48, dst_mac); 6 | BITS_FIELD(48, src_mac); 7 | BITS_FIELD(16, ether_type); 8 | }; 9 | 10 | void NET_RECV__process_packet(buf_t packet) { 11 | struct eth_header_t old_eth_header; 12 | struct eth_header_t new_eth_header; 13 | 14 | // extract ethernet header from the RX packet 15 | bufextract(packet, (void *)&old_eth_header); 16 | 17 | // create a new ethernet header for the TX packet 18 | new_eth_header.dst_mac = old_eth_header.src_mac; 19 | new_eth_header.src_mac = old_eth_header.dst_mac; 20 | new_eth_header.ether_type = old_eth_header.ether_type; 21 | 22 | // create the TX packet 23 | buf_t packet_out = bufinit(); 24 | bufemit(packet_out, &new_eth_header); 25 | bufemit(packet_out, packet); 26 | 27 | // send the TX packet 28 | EXT__NET_SEND__net_send(packet_out); 29 | } 30 | 31 | -------------------------------------------------------------------------------- /tests/experiments_c/l2_echo.c: -------------------------------------------------------------------------------- 1 | #include "alkali.h" 2 | #include "generic_handlers.h" 3 | 4 | struct eth_header_t { 5 | BITS_FIELD(48, dst_mac); 6 | BITS_FIELD(48, src_mac); 7 | BITS_FIELD(16, ether_type); 8 | }; 9 | 10 | void NET_RECV__process_packet(buf_t packet) { 11 | struct eth_header_t old_eth_header; 12 | struct eth_header_t new_eth_header; 13 | 14 | // extract ethernet header from the RX packet 15 | bufextract(packet, (void *)&old_eth_header); 16 | 17 | // create a new ethernet header for the TX packet 18 | new_eth_header.dst_mac = old_eth_header.src_mac; 19 | new_eth_header.src_mac = old_eth_header.dst_mac; 20 | new_eth_header.ether_type = old_eth_header.ether_type; 21 | 22 | // create the TX packet 23 | buf_t packet_out = bufinit(); 24 | bufemit(packet_out, &new_eth_header); 25 | bufemit(packet_out, packet); 26 | 27 | // send the TX packet 28 | EXT__NET_SEND__net_send(packet_out); 29 | } 30 | 31 | -------------------------------------------------------------------------------- /runtime_lib/netronome_runtime/include/nfp-common/nfp_platform.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: BSD-3-Clause 2 | * Copyright(c) 2018 Netronome Systems, Inc. 3 | * All rights reserved. 4 | */ 5 | 6 | #ifndef __NFP_PLATFORM_H__ 7 | #define __NFP_PLATFORM_H__ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #ifndef BIT_ULL 21 | #define BIT(x) (1 << (x)) 22 | #define BIT_ULL(x) (1ULL << (x)) 23 | #endif 24 | 25 | #ifndef ARRAY_SIZE 26 | #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 27 | #endif 28 | 29 | #define NFP_ERRNO(err) (errno = (err), -1) 30 | #define NFP_ERRNO_RET(err, ret) (errno = (err), (ret)) 31 | #define NFP_NOERR(errv) (errno) 32 | #define NFP_ERRPTR(err) (errno = (err), NULL) 33 | #define NFP_PTRERR(errv) (errno) 34 | 35 | #endif /* __NFP_PLATFORM_H__ */ 36 | -------------------------------------------------------------------------------- /example_outputs/outs-netronome/out-netronome-example/process_desc.c: -------------------------------------------------------------------------------- 1 | #include "nfplib.h" 2 | #include "prog_hdr.h" 3 | #include "extern/extern_dma.h" 4 | #include "extern/extern_net.h" 5 | 6 | __declspec(aligned(4)) struct event_param_USER_EVENT1 work; 7 | __xrw struct event_param_USER_EVENT1 work_ref; 8 | 9 | __forceinline 10 | void __event___handler_USER_EVENT1_process_desc() { 11 | __declspec(aligned(4)) struct event_param_USER_EVENT1* v1; 12 | __xrw struct event_param_USER_EVENT1* v2; 13 | struct context_chain_1_t* v3; 14 | int32_t v4; 15 | v1 = &work; 16 | v2 = &work_ref; 17 | cls_workq_add_thread(WORKQ_ID_USER_EVENT1, v2, sizeof(*v2)); 18 | *(v1) = *(v2); 19 | v3 = v1->ctx; 20 | v4 = v1->f0; 21 | v3->f1 = v4; 22 | return; 23 | } 24 | 25 | 26 | int main(void) { 27 | init_recv_event_workq(WORKQ_ID_USER_EVENT1, workq_USER_EVENT1, WORKQ_TYPE_USER_EVENT1, WORKQ_SIZE_USER_EVENT1, 8); 28 | for (;;) { 29 | __event___handler_USER_EVENT1_process_desc(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /include/ep2/passes/LiftUtils.h: -------------------------------------------------------------------------------- 1 | #ifndef EP2_PASSES_LIFTUTILS_H 2 | #define EP2_PASSES_LIFTUTILS_H 3 | 4 | #include "ep2/dialect/Dialect.h" 5 | 6 | #include "mlir/IR/Types.h" 7 | #include "mlir/IR/BuiltinOps.h" 8 | #include 9 | 10 | namespace mlir { 11 | namespace ep2 { 12 | 13 | std::optional stripMemRefType(OpBuilder &builder, Type type); 14 | Type liftLLVMType(OpBuilder &builder, Type type); 15 | 16 | std::pair functionSplitter(ep2::FuncOp funcOp, llvm::DenseSet &sinkOps, llvm::DenseSet &sinkArgs); 17 | // functions for creating generate 18 | std::pair createGenerate(OpBuilder &builder, mlir::Location loc, StringRef name, ArrayRef values); 19 | std::pair createGenerate(OpBuilder &builder, mlir::Location loc, StringRef event, StringRef atom, ArrayRef values); 20 | 21 | } // namespace ep2 22 | } // namespace mlir 23 | 24 | 25 | #endif // EP2_PASSES_LIFTUTILS_H -------------------------------------------------------------------------------- /ep2c-opt/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(LLVM_LINK_COMPONENTS 2 | Support 3 | ) 4 | 5 | get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS) 6 | get_property(conversion_libs GLOBAL PROPERTY MLIR_CONVERSION_LIBS) 7 | get_property(extension_libs GLOBAL PROPERTY MLIR_EXTENSION_LIBS) 8 | set(MLIR_LINK_COMPONENTS 9 | ${dialect_libs} 10 | ${conversion_libs} 11 | ${translation_libs} 12 | ${extension_libs} 13 | 14 | MLIRAnalysis 15 | MLIRArithDialect 16 | MLIRBuiltinToLLVMIRTranslation 17 | MLIRCallInterfaces 18 | MLIRCastInterfaces 19 | MLIRFunctionInterfaces 20 | MLIRIR 21 | MLIRLLVMCommonConversion 22 | MLIRLLVMToLLVMIRTranslation 23 | MLIRMemRefDialect 24 | MLIRParser 25 | MLIRPass 26 | MLIRSideEffectInterfaces 27 | MLIRTargetLLVMIRExport 28 | MLIRTransforms 29 | MLIROptLib 30 | ) 31 | 32 | add_llvm_executable(ep2c-opt 33 | ep2c-opt.cpp 34 | 35 | DEPENDS 36 | MLIREP2 37 | ) 38 | llvm_update_compile_flags(ep2c-opt) 39 | target_link_libraries(ep2c-opt PRIVATE ${MLIR_LINK_COMPONENTS}) 40 | -------------------------------------------------------------------------------- /include/Standalone/StandalonePasses.td: -------------------------------------------------------------------------------- 1 | //===- StandalonePsss.td - Standalone dialect passes -------*- tablegen -*-===// 2 | // 3 | // This file is licensed under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | #ifndef STANDALONE_PASS 10 | #define STANDALONE_PASS 11 | 12 | include "mlir/Pass/PassBase.td" 13 | 14 | def StandaloneSwitchBarFoo: Pass<"standalone-switch-bar-foo", "::mlir::ModuleOp"> { 15 | let summary = "Switches the name of a FuncOp named `bar` to `foo` and folds."; 16 | let description = [{ 17 | Switches the name of a FuncOp named `bar` to `foo` and folds. 18 | ``` 19 | func.func @bar() { 20 | return 21 | } 22 | // Gets transformed to: 23 | func.func @foo() { 24 | return 25 | } 26 | ``` 27 | }]; 28 | } 29 | 30 | #endif // STANDALONE_PASS 31 | -------------------------------------------------------------------------------- /runtime_lib/netronome_runtime/include/common.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: BSD 3-Clause License */ 2 | /* Copyright (c) 2022, University of Washington, Max Planck Institute for Software Systems, and The University of Texas at Austin */ 3 | 4 | #ifndef _FLEXTOE_COMMON_H_ 5 | #define _FLEXTOE_COMMON_H_ 6 | 7 | #include "params.h" 8 | 9 | #if defined(__NFP_LANG_MICROC) 10 | #define FIRMWARE 1 11 | #else 12 | #define FIRMWARE 0 13 | #endif 14 | 15 | #if FIRMWARE 16 | #define PACKED_STRUCT(name) __packed struct name 17 | #define PACKED_ALIGN_STRUCT(name, align) __packed __align##align struct name 18 | #define PACKED_UNION(name) __packed union name 19 | #else 20 | #define PACKED_STRUCT(name) struct __attribute__((packed)) name 21 | #define PACKED_ALIGN_STRUCT(name, align) struct __attribute__((packed, aligned(align))) name 22 | #define PACKED_UNION(name) union __attribute__((packed)) name 23 | #endif 24 | 25 | #endif /* _FLEXTOE_COMMON_H_ */ 26 | -------------------------------------------------------------------------------- /runtime_lib/netronome_runtime/include/rte/branch_prediction.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: BSD-3-Clause 2 | * Copyright(c) 2010-2014 Intel Corporation 3 | */ 4 | 5 | /** 6 | * @file 7 | * Branch Prediction Helpers in RTE 8 | */ 9 | 10 | #ifndef _RTE_BRANCH_PREDICTION_H_ 11 | #define _RTE_BRANCH_PREDICTION_H_ 12 | 13 | /** 14 | * Check if a branch is likely to be taken. 15 | * 16 | * This compiler builtin allows the developer to indicate if a branch is 17 | * likely to be taken. Example: 18 | * 19 | * if (likely(x > 1)) 20 | * do_stuff(); 21 | * 22 | */ 23 | #ifndef likely 24 | #define likely(x) __builtin_expect(!!(x), 1) 25 | #endif /* likely */ 26 | 27 | /** 28 | * Check if a branch is unlikely to be taken. 29 | * 30 | * This compiler builtin allows the developer to indicate if a branch is 31 | * unlikely to be taken. Example: 32 | * 33 | * if (unlikely(x < 1)) 34 | * do_stuff(); 35 | * 36 | */ 37 | #ifndef unlikely 38 | #define unlikely(x) __builtin_expect(!!(x), 0) 39 | #endif /* unlikely */ 40 | 41 | #endif /* _RTE_BRANCH_PREDICTION_H_ */ 42 | -------------------------------------------------------------------------------- /ep2c/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(LLVM_LINK_COMPONENTS 2 | Support 3 | ) 4 | 5 | get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS) 6 | get_property(conversion_libs GLOBAL PROPERTY MLIR_CONVERSION_LIBS) 7 | get_property(extension_libs GLOBAL PROPERTY MLIR_EXTENSION_LIBS) 8 | set(MLIR_LINK_COMPONENTS 9 | ${dialect_libs} 10 | ${conversion_libs} 11 | ${translation_libs} 12 | ${extension_libs} 13 | 14 | MLIRAnalysis 15 | MLIRArithDialect 16 | MLIRBuiltinToLLVMIRTranslation 17 | MLIRCallInterfaces 18 | MLIRCastInterfaces 19 | MLIRExecutionEngine 20 | MLIRFunctionInterfaces 21 | MLIRIR 22 | MLIRLLVMCommonConversion 23 | MLIRLLVMToLLVMIRTranslation 24 | MLIRMemRefDialect 25 | MLIRParser 26 | MLIRPass 27 | MLIRSideEffectInterfaces 28 | MLIRTargetLLVMIRExport 29 | MLIRTransforms 30 | MLIROptLib 31 | ) 32 | 33 | # ep2c 34 | add_llvm_executable(ep2c 35 | ep2c.cpp 36 | AST.cpp 37 | MLIRGen.cpp 38 | 39 | DEPENDS 40 | MLIREP2 41 | ) 42 | llvm_update_compile_flags(ep2c) 43 | target_link_libraries(ep2c PRIVATE ${MLIR_LINK_COMPONENTS}) 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /tests/output/ifelse.opt.mlir: -------------------------------------------------------------------------------- 1 | module { 2 | ep2.func private @__handler_MY_EVENT_my_handler_event(%arg0: !ep2.context) attributes {atom = "my_handler_event", event = "MY_EVENT", type = "handler"} { 3 | %false = arith.constant false 4 | %0 = "ep2.constant"() <{value = 1 : i64}> : () -> i32 5 | %1 = "ep2.constant"() <{value = 0 : i64}> : () -> i1 6 | %2:2 = scf.if %1 -> (i1, i32) { 7 | %3 = "ep2.constant"() <{value = 0 : i64}> : () -> i1 8 | scf.yield %3, %0 : i1, i32 9 | } else { 10 | %3 = "ep2.constant"() <{value = 233 : i64}> : () -> i32 11 | scf.yield %false, %3 : i1, i32 12 | } 13 | scf.if %2#0 { 14 | %3 = "ep2.context_ref"(%arg0) <{name = "const"}> : (!ep2.context) -> !ep2.conref 15 | %4 = "ep2.constant"() <{value = 2 : i64}> : () -> i64 16 | "ep2.store"(%3, %4) : (!ep2.conref, i64) -> () 17 | %5 = "ep2.context_ref"(%arg0) <{name = "name"}> : (!ep2.context) -> !ep2.conref 18 | "ep2.store"(%5, %2#1) : (!ep2.conref, i32) -> () 19 | } 20 | "ep2.terminate"() : () -> () 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /runtime_lib/netronome_runtime/microc/include/types.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2015, Netronome Systems, Inc. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | * @file include/types.h 17 | * @brief Standard types 18 | */ 19 | #ifndef _NFP__TYPES_H_ 20 | #define _NFP__TYPES_H_ 21 | 22 | #if defined(__NFP_LANG_MICROC) 23 | 24 | typedef unsigned int size_t; 25 | typedef int ssize_t; 26 | 27 | 28 | #endif /* __NFP_LANG_MICROC */ 29 | 30 | #endif /* !_NFP__TYPES_H_ */ 31 | -------------------------------------------------------------------------------- /tests/example.ep2: -------------------------------------------------------------------------------- 1 | struct Desc_Hdr { 2 | long data_addr; 3 | int size; 4 | } 5 | 6 | event USER_EVENT1 { 7 | atom at; 8 | context ctx; 9 | int val; 10 | } 11 | 12 | event DMA_RECV_CMPL { 13 | atom at; 14 | context ctx; 15 | buf data; 16 | } 17 | 18 | controller DMA_RECV_CMPL() { 19 | # queue_length=100, batch=1, qos_class_num=1 20 | Queue(256, 1, 1); 21 | } 22 | 23 | controller USER_EVENT1() { 24 | # queue_length=100, batch=1, qos_class_num=1 25 | Queue(256, 1, 1); 26 | } 27 | 28 | # constrian -- only one handler can handle extern event 29 | handler DMA_RECV_CMPL:receive_desc (context ctx, buf data) { 30 | recv_desc_t desc; 31 | data.extract(desc); 32 | ctx.flow_id = desc.flow_id; 33 | ctx.bump_seq = desc.bump_seq; 34 | ctx.flags = desc.flags; 35 | ctx.flow_grp = desc.flow_grp; 36 | 37 | generate USER_EVENT1:process_desc {ctx, 100}; 38 | } 39 | 40 | handler DMA_READ_REQ:receive_payload_1 (context ctx, long addr, int size) { 41 | bits<16> narrow; 42 | narrow = 32; 43 | ctx.desc_addr = ctx.desc_addr + addr; 44 | } 45 | 46 | 47 | -------------------------------------------------------------------------------- /runtime_lib/netronome_runtime/scripts/Makefile.debug: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2015-2018, Netronome Systems, Inc. All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | # @file scripts/Makefile.debug 17 | # @brief Makefile 18 | # 19 | 20 | fw_unload: 21 | nfp-nffw unload 22 | 23 | fw_start: 24 | nfp-nffw start 25 | 26 | i32me0: 27 | nfp-reg mecsr:i32.me0.Mailbox0 mecsr:i32.me0.Mailbox1 mecsr:i32.me0.Mailbox2 mecsr:i32.me0.Mailbox3 28 | 29 | i33me0: 30 | nfp-reg mecsr:i33.me0.Mailbox0 mecsr:i33.me0.Mailbox1 mecsr:i33.me0.Mailbox2 mecsr:i33.me0.Mailbox3 -------------------------------------------------------------------------------- /runtime_lib/fpga_runtime/rtl_lib/ep2/reg.sv: -------------------------------------------------------------------------------- 1 | // module reg_validdata # 2 | // ( 3 | // parameter DATA_WIDTH = 16, 4 | // parameter IF_KEEP = 0, 5 | // parameter IF_LAST = 0, 6 | // ) 7 | // ( 8 | // input wire clk, 9 | // input wire rst, 10 | 11 | // input wire [DATA_WIDTH-1:0] s_axis_tdata, 12 | // input wire s_axis_tvalid, 13 | // output reg s_axis_tready, 14 | 15 | // output reg [DATA_WIDTH-1:0] m_axis_tdata, 16 | // output reg m_axis_tvalid, 17 | // input wire m_axis_tready 18 | // ); 19 | 20 | 21 | // // valid path 22 | // always @(posedge clk) begin 23 | // // if (m_axis_tvalid && m_axis_tready) begin 24 | // if (m_axis_tvalid && s_axis_tready) begin 25 | // m_axis_tdata <= s_axis_tdata; 26 | // m_axis_tvalid <= s_axis_tvalid; 27 | // end 28 | // end 29 | 30 | 31 | // // ready path 32 | // always @* begin 33 | // s_axis_tready = m_axis_tready; 34 | // end 35 | 36 | 37 | 38 | // endmodule -------------------------------------------------------------------------------- /runtime_lib/netronome_runtime/microc/blocks/gro/_uc/gro_internal.uc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018, Netronome Systems, Inc. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | * @file me/blocks/gro/_uc/gro_internal.h 17 | */ 18 | 19 | #ifndef __GRO_INTERNAL_UC 20 | #define __GRO_INTERNAL_UC 21 | 22 | #include 23 | 24 | #define GRO_NN_CTX_shf 2 25 | #define GRO_NN_CTX_msk ((GRO_ROCTX_PER_BLOCK - 1) << GRO_NN_CTX_shf) 26 | #define GRO_NN_NREL_shf 16 27 | #define GRO_NN_NREL_msk (GRO_MAX_REL_PER_MSG - 1) 28 | 29 | 30 | 31 | #endif /* __GRO_INTERNAL_UC */ 32 | -------------------------------------------------------------------------------- /runtime_lib/fpga_runtime/rtl_lib/axi/COPYING: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018 Alex Forencich 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Zhiyuan Guo, Jiaxin Lin, Mihir Shah 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /runtime_lib/fpga_runtime/rtl_lib/axis/COPYING: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014-2018 Alex Forencich 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /runtime_lib/netronome_runtime/microc/lib/lu/liblu.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012-2015 Netronome, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | * @file me/lu/liblu.c 17 | * @brief Library for Look-Up data structures 18 | */ 19 | 20 | #ifndef _LU__LIBLU_C_ 21 | #define _LU__LIBLU_C_ 22 | 23 | #if defined(__NFP_LANG_MICROC) 24 | 25 | /* 26 | * The following files implement all the funcitonality in . 27 | */ 28 | #include "_c/cam_hash.c" 29 | 30 | #endif /* __NFP_LANG_MICROC */ 31 | 32 | #endif /* !_LU__LIBLU_C_ */ 33 | 34 | /* -*- Mode:C; c-basic-offset:4; tab-width:4 -*- */ 35 | -------------------------------------------------------------------------------- /lib/ep2/HandlerInOutAnalysis.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "ep2/dialect/Dialect.h" 3 | #include "ep2/dialect/Passes.h" 4 | #include "mlir/IR/BuiltinDialect.h" 5 | 6 | #include "mlir/IR/BuiltinOps.h" 7 | #include "mlir/IR/Visitors.h" 8 | #include "mlir/Pass/Pass.h" 9 | #include "llvm/ADT/StringMap.h" 10 | 11 | using namespace mlir; 12 | 13 | namespace mlir { 14 | namespace ep2 { 15 | 16 | HandlerInOutAnalysis::HandlerInOutAnalysis(Operation *module) { 17 | // walk through and find all function targets. 18 | module->walk([&](FuncOp funcOp) { 19 | if (funcOp->getAttr("type").cast().getValue() == "handler") { 20 | auto args = funcOp.getArguments(); 21 | handler_in_arg_list[funcOp] = args; 22 | 23 | mlir::SmallVector returnops; 24 | funcOp->walk([&](ep2::ReturnOp op) { 25 | if (op.getNumOperands() != 0) { 26 | assert(op.getNumOperands() == 1); 27 | returnops.push_back(op.getOperand(0)); 28 | } 29 | }); 30 | handler_returnop_list[funcOp] = returnops; 31 | printf("add return ops: %d\n", returnops.size()); 32 | } 33 | }); 34 | } 35 | } // namespace ep2 36 | } // namespace mlir 37 | -------------------------------------------------------------------------------- /runtime_lib/fpga_runtime/rtl_lib/verilog-cam/COPYING: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015-2016 Alex Forencich 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /runtime_lib/netronome_runtime/microc/blocks/init/init_main.uc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-2015, Netronome Systems, Inc. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | * @file: init_main.uc 17 | * @brief: Global NFP initialisation settings 18 | * 19 | * @note The list file output of this source file is not intended to be 20 | * loaded on any particular ME. During the build process the 21 | * application can (via the NFCC -L flag) link/load this 22 | * instruction-less list file. 23 | * 24 | */ 25 | #include "_uc/init_nbi.uc" 26 | 27 | .begin 28 | nbi_init() 29 | .end 30 | -------------------------------------------------------------------------------- /tests/output/fpga/flextoemini/__ep2top.sv: -------------------------------------------------------------------------------- 1 | module ep2top#() 2 | ( 3 | input wire clk, 4 | input wire rst, 5 | //input ports BUF 6 | input wire [512-1:0] NET_RECV_1_tdata , 7 | input wire [64-1:0] NET_RECV_1_tkeep , 8 | input wire NET_RECV_1_tlast , 9 | input wire NET_RECV_1_tvalid , 10 | output wire NET_RECV_1_tready 11 | ); 12 | __handler_NET_RECV_process_packet#( 13 | )__handler_NET_RECV_process_packet( 14 | .clk(clk), 15 | .rst(rst) , 16 | // 17 | .NET_RECV_1_tdata({NET_RECV_1_tdata}), 18 | .NET_RECV_1_tkeep({NET_RECV_1_tkeep}), 19 | .NET_RECV_1_tlast({NET_RECV_1_tlast}), 20 | .NET_RECV_1_tvalid({NET_RECV_1_tvalid}), 21 | .NET_RECV_1_tready({NET_RECV_1_tready}), 22 | // 23 | .outport_3_2_tdata({arg_19_tdata}), 24 | .outport_3_2_tvalid({arg_19_tvalid}), 25 | .outport_3_2_tready({arg_19_tready}) 26 | ); 27 | 28 | // 29 | wire [96-1:0] arg_19_tdata; 30 | wire arg_19_tvalid; 31 | wire arg_19_tready; 32 | 33 | __handler_OoO_DETECT_ooo_detect#( 34 | )__handler_OoO_DETECT_ooo_detect( 35 | .clk(clk), 36 | .rst(rst) , 37 | // 38 | .arg_19_tdata({arg_19_tdata}), 39 | .arg_19_tvalid({arg_19_tvalid}), 40 | .arg_19_tready({arg_19_tready}) 41 | ); 42 | 43 | 44 | endmodule 45 | -------------------------------------------------------------------------------- /runtime_lib/fpga_runtime/src/flextoemini_src/__ep2top.sv: -------------------------------------------------------------------------------- 1 | module ep2top#() 2 | ( 3 | input wire clk, 4 | input wire rst, 5 | //input ports BUF 6 | input wire [512-1:0] NET_RECV_1_tdata , 7 | input wire [64-1:0] NET_RECV_1_tkeep , 8 | input wire NET_RECV_1_tlast , 9 | input wire NET_RECV_1_tvalid , 10 | output wire NET_RECV_1_tready 11 | ); 12 | __handler_NET_RECV_process_packet#( 13 | )__handler_NET_RECV_process_packet( 14 | .clk(clk), 15 | .rst(rst) , 16 | // 17 | .NET_RECV_1_tdata({NET_RECV_1_tdata}), 18 | .NET_RECV_1_tkeep({NET_RECV_1_tkeep}), 19 | .NET_RECV_1_tlast({NET_RECV_1_tlast}), 20 | .NET_RECV_1_tvalid({NET_RECV_1_tvalid}), 21 | .NET_RECV_1_tready({NET_RECV_1_tready}), 22 | // 23 | .outport_3_2_tdata({arg_19_tdata}), 24 | .outport_3_2_tvalid({arg_19_tvalid}), 25 | .outport_3_2_tready({arg_19_tready}) 26 | ); 27 | 28 | // 29 | wire [96-1:0] arg_19_tdata; 30 | wire arg_19_tvalid; 31 | wire arg_19_tready; 32 | 33 | __handler_OoO_DETECT_ooo_detect#( 34 | )__handler_OoO_DETECT_ooo_detect( 35 | .clk(clk), 36 | .rst(rst) , 37 | // 38 | .arg_19_tdata({arg_19_tdata}), 39 | .arg_19_tvalid({arg_19_tvalid}), 40 | .arg_19_tready({arg_19_tready}) 41 | ); 42 | 43 | 44 | endmodule 45 | -------------------------------------------------------------------------------- /scripts/alkalic: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Usage: 4 | # alkalic --target 5 | # 6 | 7 | set -e 8 | 9 | # Resolve this script's directory to an absolute path 10 | SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 11 | 12 | # Check arguments 13 | if [[ $# -lt 3 ]]; then 14 | echo "Usage: $0 --target " 15 | exit 1 16 | fi 17 | 18 | INPUT_FILE="$1" 19 | shift 20 | 21 | # Parse --target argument 22 | TARGET="" 23 | while [[ $# -gt 0 ]]; do 24 | case "$1" in 25 | --target) 26 | TARGET="$2" 27 | shift 2 28 | ;; 29 | *) 30 | echo "Unknown argument: $1" 31 | exit 1 32 | ;; 33 | esac 34 | done 35 | 36 | if [[ -z "$TARGET" ]]; then 37 | echo "Error: --target option is required" 38 | exit 1 39 | fi 40 | 41 | # Step 1: Run run_c.sh 42 | "${SCRIPT_DIR}/run_c.sh" "$INPUT_FILE" 43 | 44 | # Step 2: Conditional compile 45 | if [[ "$TARGET" == "netronome" ]]; then 46 | "${SCRIPT_DIR}/netronome_compile.sh" "out.mlir" 47 | elif [[ "$TARGET" == "rtl" ]]; then 48 | "${SCRIPT_DIR}/fpga_compile.sh" "out.mlir" 49 | else 50 | echo "Error: Unknown target '$TARGET'. Expected 'netronome' or 'rtl'." 51 | exit 1 52 | fi 53 | 54 | -------------------------------------------------------------------------------- /tests/output/fpga/ids/runfpga.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | set -x 5 | 6 | OUT_FILE_NAME="out-${1%.*}" 7 | 8 | ninja -C build/ 9 | ./build/bin/ep2c $1 --emit=mlir -o "./tmp.mlir" 10 | #./build/bin/ep2c-opt -canonicalize -cse --ep2-context-infer --ep2-context-to-argument -ep2-buffer-to-value -canonicalize -cse -canonicalize -ep2-linearize -ep2-emit-fpga tmp.mlir -o tmpopt.mlir 11 | #./build/bin/ep2c-opt -canonicalize -cse --ep2-context-infer --ep2-context-to-argument -ep2-buffer-to-value -canonicalize -cse -canonicalize -ep2-linearize tmp.mlir -o tmpopt.mlir 12 | # 13 | #./build/bin/ep2c-opt -canonicalize -cse --ep2-context-infer --ep2-context-to-argument -ep2-buffer-to-value -canonicalize -cse -canonicalize -cf-to-pred -canonicalize -cse -canonicalize -ep2-emit-fpga tmp.mlir -o tmpopt.mlir 14 | #./build/bin/ep2c-opt --ep2-context-infer --ep2-context-to-argument -ep2-buffer-to-value -canonicalize -cse -canonicalize -ep2-atomic-id -canonicalize -cse -canonicalize -ep2-linearize tmp.mlir -o tmpopt.mlir 15 | ./build/bin/ep2c-opt --ep2-context-infer --ep2-context-to-argument -ep2-buffer-to-value -canonicalize -cse -canonicalize -ep2-atomic-id -canonicalize -cse -canonicalize -ep2-linearize -ep2-emit-fpga tmp.mlir -o tmpopt.mlir 16 | -------------------------------------------------------------------------------- /lib/ep2/StructUpdatePropagationPass.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "mlir/IR/BuiltinDialect.h" 3 | 4 | #include "mlir/Dialect/LLVMIR/LLVMDialect.h" 5 | #include "ep2/dialect/Dialect.h" 6 | #include "ep2/dialect/Passes.h" 7 | 8 | #include "mlir/Pass/Pass.h" 9 | #include "mlir/IR/BuiltinOps.h" 10 | #include "mlir/Transforms/DialectConversion.h" 11 | #include "mlir/Transforms/GreedyPatternRewriteDriver.h" 12 | 13 | #include "mlir/Transforms/Passes.h" 14 | #include "mlir/Conversion/Passes.h" 15 | 16 | using namespace mlir; 17 | 18 | namespace mlir { 19 | namespace ep2 { 20 | 21 | void StructUpdatePropagationPass::runOnOperation() { 22 | auto followStructUpdates = [&](mlir::Value v) { 23 | mlir::Operation* op = v.getDefiningOp(); 24 | while (op != nullptr && isa(op) && cast(op).getCallee() == "__ep2_intrin_struct_write") { 25 | v = op->getOperand(1); 26 | op = op->getOperand(1).getDefiningOp(); 27 | } 28 | return v; 29 | }; 30 | 31 | getOperation()->walk([&](mlir::Operation* op) { 32 | for (int i = 0; igetOperands().size(); ++i) { 33 | op->setOperand(i, followStructUpdates(op->getOperand(i))); 34 | } 35 | }); 36 | } 37 | 38 | } // namespace ep2 39 | } // namespace mlir 40 | -------------------------------------------------------------------------------- /runtime_lib/netronome_runtime/microc/lib/std/libstd.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2015, Netronome Systems, Inc. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | * @file lib/std/libstd.c 17 | * @brief Standard library for MicroC 18 | */ 19 | 20 | #ifndef _STD__LIBSTD_C_ 21 | #define _STD__LIBSTD_C_ 22 | 23 | /* 24 | * The following files implement all the functionality in . 25 | */ 26 | #include "_c/cntrs.c" 27 | #include "_c/event.c" 28 | #include "_c/hash.c" 29 | #include "_c/reg_utils.c" 30 | #include "_c/synch.c" 31 | #include "_c/write_alert.c" 32 | #include "_c/reorder.c" 33 | 34 | #endif /* !_STD__LIBSTD_C_ */ 35 | 36 | -------------------------------------------------------------------------------- /include/ep2/dialect/MLIRGen.h: -------------------------------------------------------------------------------- 1 | //===- MLIRGen.h - MLIR Generation from a Toy AST -------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file declares a simple interface to perform IR generation targeting MLIR 10 | // from a Module AST for the Toy language. 11 | // 12 | //===----------------------------------------------------------------------===// 13 | 14 | #ifndef EP2_MLIRGEN_H 15 | #define EP2_MLIRGEN_H 16 | 17 | #include 18 | 19 | namespace mlir { 20 | class MLIRContext; 21 | template 22 | class OwningOpRef; 23 | class ModuleOp; 24 | } // namespace mlir 25 | 26 | namespace ep2 { 27 | class ModuleAST; 28 | 29 | /// Emit IR for the given Toy moduleAST, returns a newly created MLIR module 30 | /// or nullptr on failure. 31 | mlir::OwningOpRef mlirGen(mlir::MLIRContext &context, 32 | ModuleAST &moduleAST); 33 | } // namespace toy 34 | 35 | #endif // TOY_MLIRGEN_H 36 | -------------------------------------------------------------------------------- /runtime_lib/netronome_runtime/include/params.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: BSD 3-Clause License */ 2 | /* Copyright (c) 2022, University of Washington, Max Planck Institute for Software Systems, and The University of Texas at Austin */ 3 | 4 | #ifndef FLEXTOE_PARAMS_H_ 5 | #define FLEXTOE_PARAMS_H_ 6 | 7 | /** Flow state parameters */ 8 | #define FLEXNIC_PL_APPST_NUM 8 9 | #define FLEXNIC_PL_APPST_CTX_NUM 31 10 | #define FLEXNIC_PL_APPCTX_NUM 32 11 | #define FLEXNIC_PL_FLOWST_NUM 16384 12 | #define FLEXNIC_PL_FLOWHT_ENTRIES (FLEXNIC_PL_FLOWST_NUM * 2) 13 | 14 | /** 15 | * NOTE: 16 | * Developed for: Beryllium Agilio CX 2x40 17 | * Untested on other platforms 18 | */ 19 | /** Platform definition */ 20 | #define NS_PLATFORM_TYPE 7 // NS_PLATFORM_BERYLLIUM 21 | #define PORT_IN_USE 1 22 | #include "platform.h" 23 | 24 | /** Debug configuration */ 25 | #define PKTBUF_SIZE 2048 26 | #define LOGBUF_SIZE 4096 27 | #define STATBUF_SIZE 128 28 | #define PROFBUF_SIZE 128 29 | #define JOURNAL_SIZE (4 * 1024 * 1024) // 4M 30 | 31 | #define FP_LOG_ENABLE 0 32 | #define FP_STAT_ENABLE 0 33 | #define FP_PROF_ENABLE 0 34 | #define FP_JRNL_ENABLE 0 35 | 36 | #endif /* FLEXTOE_PARAMS_H_ */ 37 | -------------------------------------------------------------------------------- /tests/c_demo/alkali.h: -------------------------------------------------------------------------------- 1 | #ifndef ALKALI_H 2 | #define ALKALI_H 3 | 4 | struct buf_tag { 5 | int buf_tag; 6 | }; 7 | typedef struct buf_tag * buf_t; 8 | 9 | /* optional types */ 10 | #define BITS_FIELD(N,name) \ 11 | int name 12 | 13 | /* BITS for defining non-field data */ 14 | #define BITS(N) BITS ## _ ## N 15 | 16 | #define BITS_32 int 17 | #define BITS_16 short 18 | 19 | /* options used by ak_TABLE */ 20 | #define anno_MAX_REPLICA(num) float anno_rep[num]; 21 | 22 | /* Use type level information to tag a special structure - doubles wont be using anywhere */ 23 | #define ak_TABLE(size,kt,vt,...) \ 24 | struct { \ 25 | kt key; \ 26 | vt value; \ 27 | char cap[size]; \ 28 | __VA_ARGS__ \ 29 | } 30 | 31 | /* function prototypes */ 32 | extern void send_packet(buf_t packet); 33 | extern buf_t bufinit(); 34 | extern void bufextract(buf_t packet, void *extracted_data); 35 | extern void bufemit(buf_t packet, void *extracted_data); 36 | 37 | extern void table_lookup(void *tab, void *key, void *value); 38 | extern void table_update(void *tab, void *key, void *value); 39 | 40 | extern void generate(const char * target, buf_t packet); 41 | 42 | /* dummy main function to make the compiler happy */ 43 | int main() { return 0; } 44 | 45 | #endif // ALKALI_H -------------------------------------------------------------------------------- /tests/experiments_c/alkali.h: -------------------------------------------------------------------------------- 1 | #ifndef ALKALI_H 2 | #define ALKALI_H 3 | 4 | struct buf_tag { 5 | int buf_tag; 6 | }; 7 | typedef struct buf_tag * buf_t; 8 | 9 | /* optional types */ 10 | #define BITS_FIELD(N,name) \ 11 | int name 12 | 13 | /* BITS for defining non-field data */ 14 | #define BITS(N) BITS ## _ ## N 15 | 16 | #define BITS_32 int 17 | #define BITS_16 short 18 | 19 | /* options used by ak_TABLE */ 20 | #define anno_MAX_REPLICA(num) float anno_rep[num]; 21 | 22 | /* Use type level information to tag a special structure - doubles wont be using anywhere */ 23 | #define ak_TABLE(size,kt,vt,...) \ 24 | struct { \ 25 | kt key; \ 26 | vt value; \ 27 | char cap[size]; \ 28 | __VA_ARGS__ \ 29 | } 30 | 31 | /* function prototypes */ 32 | extern void send_packet(buf_t packet); 33 | extern buf_t bufinit(); 34 | extern void bufextract(buf_t packet, void *extracted_data); 35 | extern void bufemit(buf_t packet, void *extracted_data); 36 | 37 | extern void table_lookup(void *tab, void *key, void *value); 38 | extern void table_update(void *tab, void *key, void *value); 39 | 40 | extern void generate(const char * target, buf_t packet); 41 | 42 | /* dummy main function to make the compiler happy */ 43 | int main() { return 0; } 44 | 45 | #endif // ALKALI_H 46 | -------------------------------------------------------------------------------- /runtime_lib/netronome_runtime/microc/lib/net/libnet.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012-2015 Netronome, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | * @file lib/net/libnet.c 17 | * @brief Network protocol related functions 18 | */ 19 | 20 | #ifndef _LIB_NET_C_ 21 | #define _LIB_NET_C_ 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | #include 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | #include "_c/csum.c" 38 | #include "_c/hdr_ext.c" 39 | 40 | #endif /* _LIB_NET_C_ */ 41 | 42 | /* -*- Mode:C; c-basic-offset:4; tab-width:4 -*- */ 43 | -------------------------------------------------------------------------------- /include/Standalone/StandaloneTypes.td: -------------------------------------------------------------------------------- 1 | //===- StandaloneTypes.td - Standalone dialect types -------*- tablegen -*-===// 2 | // 3 | // This file is licensed under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | #ifndef STANDALONE_TYPES 10 | #define STANDALONE_TYPES 11 | 12 | include "mlir/IR/AttrTypeBase.td" 13 | include "Standalone/StandaloneDialect.td" 14 | 15 | //===----------------------------------------------------------------------===// 16 | // Standalone type definitions 17 | //===----------------------------------------------------------------------===// 18 | 19 | class Standalone_Type traits = []> 20 | : TypeDef { 21 | let mnemonic = typeMnemonic; 22 | } 23 | 24 | def Standalone_CustomType : Standalone_Type<"Custom", "custom"> { 25 | let summary = "Standalone custom type"; 26 | let description = "Custom type in standalone dialect"; 27 | let parameters = (ins StringRefParameter<"the custom value">:$value); 28 | let assemblyFormat = "`<` $value `>`"; 29 | } 30 | 31 | #endif // STANDALONE_TYPES 32 | -------------------------------------------------------------------------------- /runtime_lib/netronome_runtime/include/fp_mem.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: BSD 3-Clause License */ 2 | /* Copyright (c) 2022, University of Washington, Max Planck Institute for Software Systems, and The University of Texas at Austin */ 3 | 4 | #ifndef FLEXTOE_MEMIF_H_ 5 | #define FLEXTOE_MEMIF_H_ 6 | 7 | #include 8 | 9 | #include "common.h" 10 | #include "fp_sp_if.h" 11 | #include "fp_app_if.h" 12 | #include "flow_state.h" 13 | 14 | /******************************************************************************/ 15 | PACKED_ALIGN_STRUCT(flextcp_pl_mem, 64) 16 | { 17 | /* registers for application context queues */ 18 | struct flextcp_pl_appctx_t appctx[FLEXNIC_PL_APPCTX_NUM]; 19 | 20 | /* registers for flow state */ 21 | struct flowst_tcp_t flows_tcp_state[FLEXNIC_PL_FLOWST_NUM]; 22 | struct flowst_conn_t flows_conn_info[FLEXNIC_PL_FLOWST_NUM]; 23 | struct flowst_mem_t flows_mem_info[FLEXNIC_PL_FLOWST_NUM]; 24 | struct flowst_cc_t flows_cc_info[FLEXNIC_PL_FLOWST_NUM]; 25 | 26 | /* sp context queues */ 27 | struct flextcp_pl_spctx_t spctx; 28 | 29 | /* registers for application state */ 30 | struct flextcp_pl_appst_t appst[FLEXNIC_PL_APPST_NUM]; 31 | 32 | /* registers for fastpath configuration */ 33 | struct flextcp_pl_config cfg; 34 | }; 35 | 36 | #endif /* FLEXTOE_MEMIF_H_ */ 37 | -------------------------------------------------------------------------------- /tests/output/table_test.mlir: -------------------------------------------------------------------------------- 1 | module { 2 | ep2.func private @__handler_LOAD_TABLE_load_table(%arg0: !ep2.context) attributes {atom = "load_table", event = "LOAD_TABLE", type = "handler"} { 3 | %0 = "ep2.init"() : () -> !ep2.table 4 | %1 = "ep2.init"() : () -> !ep2.table, !ep2.buf, 16> 5 | %2 = "ep2.init"() : () -> !ep2.struct<"eth_header_t" : isEvent = false, elementTypes = i48, i48, i16> 6 | %3 = "ep2.constant"() <{value = 10 : i64}> : () -> i64 7 | %4 = "ep2.constant"() <{value = 11 : i64}> : () -> i64 8 | "ep2.update"(%0, %3, %4) : (!ep2.table, i64, i64) -> () 9 | %5 = "ep2.nop"() : () -> none 10 | %6 = "ep2.constant"() <{value = 12 : i64}> : () -> i64 11 | "ep2.update"(%0, %2, %6) : (!ep2.table, !ep2.struct<"eth_header_t" : isEvent = false, elementTypes = i48, i48, i16>, i64) -> () 12 | %7 = "ep2.nop"() : () -> none 13 | %8 = "ep2.constant"() <{value = 10 : i64}> : () -> i64 14 | %9 = "ep2.lookup"(%0, %8) : (!ep2.table, i64) -> i32 15 | %10 = "ep2.lookup"(%1, %2) : (!ep2.table, !ep2.buf, 16>, !ep2.struct<"eth_header_t" : isEvent = false, elementTypes = i48, i48, i16>) -> !ep2.buf 16 | ep2.return 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /runtime_lib/netronome_runtime/microc/lib/net/esp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017, Netronome Systems, Inc. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | * @file lib/net/esp.h 17 | * @brief Definitions for ESP header parsing 18 | * 19 | * Incomplete, new definitions will be added as/when needed 20 | */ 21 | 22 | #ifndef _NET_ESP_H_ 23 | #define _NET_ESP_H_ 24 | 25 | /** 26 | * ESP type definitions 27 | */ 28 | 29 | #if defined(__NFP_LANG_MICROC) 30 | 31 | #include 32 | #include 33 | 34 | /** 35 | * ESP Header structure 36 | */ 37 | __packed struct esp_hdr { 38 | uint32_t spi; /** Security Parameters Index */ 39 | uint32_t seq; /** Sequence Number */ 40 | }; 41 | 42 | #endif /* __NFP_LANG_MICROC */ 43 | 44 | #endif /* _NET_ESP_H_ */ 45 | 46 | /* -*- Mode:C; c-basic-offset:4; tab-width:4 -*- */ 47 | -------------------------------------------------------------------------------- /tests/output/ifelse.mlir: -------------------------------------------------------------------------------- 1 | module { 2 | ep2.func private @__handler_MY_EVENT_my_handler_event(%arg0: !ep2.context) attributes {atom = "my_handler_event", event = "MY_EVENT", type = "handler"} { 3 | %0 = "ep2.init"() : () -> i1 4 | %1 = "ep2.init"() : () -> i32 5 | %2 = "ep2.constant"() <{value = 1 : i64}> : () -> i32 6 | %3 = "ep2.constant"() <{value = 0 : i64}> : () -> i1 7 | %4:2 = scf.if %3 -> (i1, i32) { 8 | %9 = "ep2.constant"() <{value = 0 : i64}> : () -> i1 9 | scf.yield %9, %2 : i1, i32 10 | } else { 11 | %9 = "ep2.constant"() <{value = 233 : i64}> : () -> i32 12 | scf.yield %3, %9 : i1, i32 13 | } 14 | scf.if %4#0 { 15 | %9 = "ep2.context_ref"(%arg0) <{name = "const"}> : (!ep2.context) -> !ep2.conref 16 | %10 = "ep2.constant"() <{value = 2 : i64}> : () -> i64 17 | "ep2.store"(%9, %10) : (!ep2.conref, i64) -> () 18 | %11 = "ep2.nop"() : () -> none 19 | %12 = "ep2.context_ref"(%arg0) <{name = "name"}> : (!ep2.context) -> !ep2.conref 20 | "ep2.store"(%12, %4#1) : (!ep2.conref, i32) -> () 21 | %13 = "ep2.nop"() : () -> none 22 | } 23 | %5 = "ep2.constant"() <{value = 2 : i64}> : () -> i64 24 | %6 = "ep2.add"(%4#1, %5) : (i32, i64) -> i32 25 | %7 = "ep2.constant"() <{value = 1 : i64}> : () -> i64 26 | %8 = "ep2.add"(%4#0, %7) : (i1, i64) -> i1 27 | "ep2.terminate"() : () -> () 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /tests/output/cmp.mlir: -------------------------------------------------------------------------------- 1 | module { 2 | ep2.func private @__handler_MY_EVENT_my_handler_event(%arg0: !ep2.context) attributes {atom = "my_handler_event", event = "MY_EVENT", type = "handler"} { 3 | %0 = "ep2.init"() : () -> i32 4 | %1 = "ep2.init"() : () -> i32 5 | %2 = "ep2.constant"() <{value = 1 : i64}> : () -> i64 6 | %3 = "ep2.bitcast"(%2) : (i64) -> i32 7 | %4 = "ep2.constant"() <{value = 2 : i64}> : () -> i64 8 | %5 = "ep2.bitcast"(%4) : (i64) -> i32 9 | %6 = "ep2.cmp"(%3, %5) <{predicate = 62 : i16}> : (i32, i32) -> i1 10 | scf.if %6 { 11 | %9 = "ep2.context_ref"(%arg0) <{name = "a"}> : (!ep2.context) -> !ep2.conref 12 | "ep2.store"(%9, %3) : (!ep2.conref, i32) -> () 13 | %10 = "ep2.nop"() : () -> none 14 | } 15 | %7 = "ep2.cmp"(%3, %5) <{predicate = 60 : i16}> : (i32, i32) -> i1 16 | scf.if %7 { 17 | %9 = "ep2.context_ref"(%arg0) <{name = "a"}> : (!ep2.context) -> !ep2.conref 18 | "ep2.store"(%9, %3) : (!ep2.conref, i32) -> () 19 | %10 = "ep2.nop"() : () -> none 20 | } 21 | %8 = "ep2.cmp"(%3, %5) <{predicate = 42 : i16}> : (i32, i32) -> i1 22 | scf.if %8 { 23 | %9 = "ep2.context_ref"(%arg0) <{name = "a"}> : (!ep2.context) -> !ep2.conref 24 | "ep2.store"(%9, %3) : (!ep2.conref, i32) -> () 25 | %10 = "ep2.nop"() : () -> none 26 | } 27 | "ep2.terminate"() : () -> () 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /scripts/run_llvm.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | EP2_BINS=./build/bin 4 | LLVM_BINS=./llvm-project/build/bin 5 | 6 | TARGET=${1:-x86_64}-unknown-linux-gnu 7 | EP2_SOURCE=${2:-tests/experiments/transport_rx.ep2.txt} 8 | 9 | MARCH="" 10 | if [ $1 = "aarch64" ] ; then 11 | MARCH="-march=armv8-a+simd -mcpu=cortex-a72" 12 | elif [ $1 = "x86_64" ] ; then 13 | MARCH="-march=native" 14 | fi 15 | 16 | set -x 17 | set -e 18 | 19 | $EP2_BINS/ep2c $EP2_SOURCE -o tmp.mlir 20 | make TARGET=$TARGET -C runtime-llvm clean 21 | 22 | ./build/bin/ep2c-opt --ep2-emit-llvm-header="dir=runtime-llvm" tmp.mlir > /dev/null 23 | # only use when running ipsec 24 | $EP2_BINS/ep2c-opt --ep2-context-infer --ep2-context-to-argument -canonicalize -cse -canonicalize \ 25 | tmp.mlir -o final.mlir 26 | 27 | # $EP2_BINS/ep2c-opt --ep2-context-infer --ep2-context-to-argument -canonicalize -cse -canonicalize \ 28 | # -ep2-buffer-reuse -ep2-dfe -ep2-dpe -ep2-canon -canonicalize -cse \ 29 | # -ep2-dpe -canonicalize -cse tmp.mlir -o final.mlir 30 | 31 | 32 | # $EP2_BINS/ep2c-opt -ep2-lower-llvm='generate=raw inline=false' -convert-cf-to-llvm final.mlir -o final_inline.mlir 33 | $EP2_BINS/ep2c-opt -ep2-lower-llvm='generate=raw' -convert-cf-to-llvm final.mlir -o final_inline.mlir 34 | $LLVM_BINS/mlir-translate -mlir-to-llvmir final_inline.mlir -o final.ll 35 | $LLVM_BINS/clang -O3 -target $TARGET $MARCH -c final.ll -o runtime-llvm/ep2.o 36 | 37 | make TARGET=$TARGET -C runtime-llvm all 38 | -------------------------------------------------------------------------------- /runtime_lib/netronome_runtime/include/nfp6000/nfp6000.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: BSD-3-Clause 2 | * Copyright(c) 2018 Netronome Systems, Inc. 3 | * All rights reserved. 4 | */ 5 | 6 | #ifndef __NFP_NFP6000_H__ 7 | #define __NFP_NFP6000_H__ 8 | 9 | /* CPP Target IDs */ 10 | #define NFP_CPP_TARGET_INVALID 0 11 | #define NFP_CPP_TARGET_NBI 1 12 | #define NFP_CPP_TARGET_QDR 2 13 | #define NFP_CPP_TARGET_ILA 6 14 | #define NFP_CPP_TARGET_MU 7 15 | #define NFP_CPP_TARGET_PCIE 9 16 | #define NFP_CPP_TARGET_ARM 10 17 | #define NFP_CPP_TARGET_CRYPTO 12 18 | #define NFP_CPP_TARGET_ISLAND_XPB 14 /* Shared with CAP */ 19 | #define NFP_CPP_TARGET_ISLAND_CAP 14 /* Shared with XPB */ 20 | #define NFP_CPP_TARGET_CT_XPB 14 21 | #define NFP_CPP_TARGET_LOCAL_SCRATCH 15 22 | #define NFP_CPP_TARGET_CLS NFP_CPP_TARGET_LOCAL_SCRATCH 23 | 24 | #define NFP_ISL_EMEM0 24 25 | 26 | #define NFP_MU_ADDR_ACCESS_TYPE_MASK 3ULL 27 | #define NFP_MU_ADDR_ACCESS_TYPE_DIRECT 2ULL 28 | 29 | #include "nfp6000/nfp_cls.h" 30 | #include "nfp6000/nfp_ctm.h" 31 | #include "nfp6000/nfp_event.h" 32 | #include "nfp6000/nfp_mac_csr_synch.h" 33 | #include "nfp6000/nfp_mac.h" 34 | #include "nfp6000/nfp_me.h" 35 | #include "nfp6000/nfp_nbi_pc.h" 36 | #include "nfp6000/nfp_nbi_tm.h" 37 | #include "nfp6000/nfp_pcie.h" 38 | #include "nfp6000/nfp_qc.h" 39 | 40 | #endif /* NFP_NFP6000_H */ 41 | -------------------------------------------------------------------------------- /tests/experiments/l2_echo.ep2.txt: -------------------------------------------------------------------------------- 1 | # Specify the functionality of the target archiecture 2 | 3 | 4 | extern event NET_RECV {context ctx; buf packet;} 5 | extern event NET_SEND{context ctx; buf packet;} 6 | 7 | extern handler NET_SEND (context ctx, buf packet) { 8 | } 9 | 10 | ############## main program ########### 11 | 12 | struct eth_header_t { 13 | bits<48> dst_mac; 14 | bits<48> src_mac; 15 | bits<16> ether_type; 16 | } 17 | 18 | # Totoal 24 bytes 19 | struct ip_header_t { 20 | # Version (4), IHL (4), DSCP (6), ECN(2) 21 | bits<8> misc; 22 | bits<16> length; 23 | bits<16> identification; 24 | # Flags (3), Fragment Offset (13) 25 | bits<16> fragment_offset; 26 | 27 | # TTL (8), Transport Protocol (8) 28 | bits<16> TTL_transport; 29 | bits<16> checksum; 30 | bits<32> source_ip; 31 | bits<32> dst_ip; 32 | bits<32> options; 33 | } 34 | 35 | [in_hw_event] handler NET_RECV:process_packet (context ctx, buf packet) { 36 | eth_header_t eth_header; 37 | bits<48> tmp_mac; 38 | ip_header_t ip_header; 39 | buf packet_out; 40 | 41 | packet.extract(eth_header); 42 | packet.extract(ip_header); 43 | 44 | # swap src and dst mac 45 | tmp_mac = eth_header.src_mac; 46 | eth_header.src_mac = eth_header.dst_mac; 47 | eth_header.dst_mac = tmp_mac; 48 | 49 | packet_out.emit(eth_header); 50 | packet_out.emit(ip_header); 51 | packet_out.emit(packet); 52 | 53 | generate NET_SEND:net_send{ctx, new_buffer}; 54 | } -------------------------------------------------------------------------------- /runtime_lib/fpga_runtime/rtl_lib/ep2/ram.sv: -------------------------------------------------------------------------------- 1 | module ram #( 2 | parameter ADDR_WIDTH = 8, 3 | parameter DATA_WIDTH = 8, 4 | parameter USER_WIDTH = 8, 5 | parameter RAM_STYLE = "block" 6 | ) 7 | ( 8 | input wire clk, 9 | input wire rst, 10 | input wire [DATA_WIDTH-1:0] s_write_data, 11 | input wire [ADDR_WIDTH-1:0] s_write_addr, 12 | input wire s_write_valid, 13 | output wire s_write_ready, 14 | 15 | input wire [ADDR_WIDTH-1:0] s_read_addr, 16 | input wire [USER_WIDTH-1:0] s_read_user, 17 | input wire s_read_valid, 18 | output reg s_read_ready, 19 | output reg [DATA_WIDTH-1:0] m_read_data, 20 | output reg m_read_valid, 21 | output reg [USER_WIDTH-1:0] m_read_user, 22 | input wire m_read_ready 23 | 24 | ); 25 | 26 | (* ram_style = RAM_STYLE *) 27 | reg [DATA_WIDTH-1:0]ram[2**ADDR_WIDTH-1:0]; 28 | integer i; 29 | 30 | initial begin 31 | for (i = 0; i < 2**ADDR_WIDTH; i = i + 1) begin 32 | ram[i] = 0; 33 | end 34 | end 35 | 36 | assign s_write_ready = 1; 37 | always @(posedge clk) begin 38 | if (s_write_valid && s_write_ready) begin 39 | ram[s_write_addr] <= s_write_data; 40 | end 41 | 42 | s_read_ready <= m_read_ready; 43 | 44 | if(s_read_ready && s_read_valid) begin 45 | m_read_data <= ram[s_read_addr]; 46 | m_read_user <= s_read_user; 47 | m_read_valid <= s_read_valid && s_read_ready; 48 | end 49 | else begin 50 | m_read_data <= 0; 51 | m_read_user <= 0; 52 | m_read_valid <= 0; 53 | end 54 | end 55 | 56 | endmodule -------------------------------------------------------------------------------- /tests/output/ctx_assign_type.mlir: -------------------------------------------------------------------------------- 1 | // ep2c --emit=mlir tests/ctx_assign_type.ep2 2 | 3 | module { 4 | ep2.func private @__handler_A_a(%arg0: !ep2.context) -> !ep2.struct<"B" : isEvent = true, elementTypes = !ep2.atom, !ep2.context> attributes {atom = "a", event = "A", type = "handler"} { 5 | %0 = "ep2.init"() : () -> i48 6 | %1 = "ep2.init"() : () -> !ep2.buf 7 | %2 = "ep2.context_ref"(%arg0) <{name = "t1"}> : (!ep2.context) -> !ep2.conref 8 | "ep2.store"(%2, %0) : (!ep2.conref, i48) -> () 9 | %3 = "ep2.nop"() : () -> none 10 | %4 = "ep2.context_ref"(%arg0) <{name = "t2"}> : (!ep2.context) -> !ep2.conref 11 | "ep2.store"(%4, %1) : (!ep2.conref, !ep2.buf) -> () 12 | %5 = "ep2.nop"() : () -> none 13 | %6 = "ep2.init"(%arg0) : (!ep2.context) -> !ep2.struct<"B" : isEvent = true, elementTypes = !ep2.atom, !ep2.context> 14 | ep2.return %6 : !ep2.struct<"B" : isEvent = true, elementTypes = !ep2.atom, !ep2.context> 15 | } 16 | ep2.func private @__handler_B_b(%arg0: !ep2.context) attributes {atom = "b", event = "B", type = "handler"} { 17 | %0 = "ep2.init"() : () -> i48 18 | %1 = "ep2.init"() : () -> !ep2.buf 19 | %2 = "ep2.context_ref"(%arg0) <{name = "t1"}> : (!ep2.context) -> !ep2.conref 20 | %3 = "ep2.load"(%2) : (!ep2.conref) -> i48 21 | %4 = "ep2.context_ref"(%arg0) <{name = "t2"}> : (!ep2.context) -> !ep2.conref 22 | "ep2.emit"(%1, %4) : (!ep2.buf, !ep2.conref) -> () 23 | %5 = "ep2.nop"() : () -> none 24 | ep2.return 25 | } 26 | } -------------------------------------------------------------------------------- /runtime_lib/netronome_runtime/microc/include/nfcc_compatibility.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018, Netronome Systems, Inc. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | * @file include/nfcc_compatibility.h 17 | * @brief Fixed width memory address definitions 18 | */ 19 | 20 | #ifndef _NFCC_COMPATIBILITY_H_ 21 | #define _NFCC_COMPATIBILITY_H_ 22 | 23 | #include 24 | 25 | #ifndef __mem32 26 | #define __mem32 __declspec(addr32 mem) 27 | #endif 28 | 29 | #ifndef __mem40 30 | #define __mem40 __declspec(addr40 mem) 31 | #endif 32 | 33 | #ifndef __cls32 34 | #define __cls32 __declspec(addr32 cls) 35 | #endif 36 | 37 | #ifndef __cls40 38 | #define __cls40 __declspec(addr40 cls) 39 | #endif 40 | 41 | #ifndef __ctm32 42 | #define __ctm32 __declspec(addr32 ctm) 43 | #endif 44 | 45 | #ifndef __ctm40 46 | #define __ctm40 __declspec(addr40 ctm) 47 | #endif 48 | 49 | 50 | #endif /* END _NFCC_COMPATIBILITY_H_*/ 51 | -------------------------------------------------------------------------------- /include/Standalone/StandaloneOps.td: -------------------------------------------------------------------------------- 1 | //===- StandaloneOps.td - Standalone dialect ops -----------*- tablegen -*-===// 2 | // 3 | // This file is licensed under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | #ifndef STANDALONE_OPS 10 | #define STANDALONE_OPS 11 | 12 | include "Standalone/StandaloneTypes.td" 13 | include "mlir/Interfaces/InferTypeOpInterface.td" 14 | include "mlir/Interfaces/SideEffectInterfaces.td" 15 | 16 | def Standalone_FooOp : Standalone_Op<"foo", [Pure, 17 | SameOperandsAndResultType]> { 18 | let summary = "Illustrates how to define an operation."; 19 | let description = [{ 20 | The `standalone.foo` operation illustrates how to define a new 21 | operation in a dialect. It uses an operation trait to declare that it 22 | has no side effects. 23 | 24 | This operation takes an integer argument and returns an integer. 25 | 26 | Example: 27 | 28 | ```mlir 29 | %0 = arith.constant 2 : i32 30 | // Apply the foo operation to %0 31 | %1 = standalone.foo %0 : i32 32 | ``` 33 | }]; 34 | 35 | let arguments = (ins I32:$input); 36 | let results = (outs I32:$res); 37 | 38 | let assemblyFormat = [{ 39 | $input attr-dict `:` type($input) 40 | }]; 41 | } 42 | 43 | #endif // STANDALONE_OPS 44 | -------------------------------------------------------------------------------- /scripts/fpga_compile.sh: -------------------------------------------------------------------------------- 1 | set +x 2 | ninja -C build/ -j 32 3 | 4 | rm -rf ./fpga_out 5 | mkdir -p ./fpga_out 6 | 7 | file="$1" 8 | # Extract the extension from the filename 9 | extension="${file##*.}" 10 | BASE_NAME="${1%.*}" 11 | 12 | # whether disable cut 13 | disable_cut="$2" 14 | # whether disable mapping 15 | disable_map="$3" 16 | 17 | case "$extension" in 18 | ep2) 19 | ./build/bin/ep2c $1 -o "fpga_out/$BASE_NAME.mlir" 20 | ;; 21 | mlir) 22 | cp $1 "fpga_out/$BASE_NAME.mlir" 23 | ;; 24 | *) 25 | echo "Unsupported file extension: .$extension" 26 | exit 1 27 | ;; 28 | esac 29 | 30 | # Common Optimizations 31 | ./build/bin/ep2c-opt "fpga_out/$BASE_NAME.mlir" -ep2-context-infer --ep2-context-to-argument -ep2-buffer-to-value -canonicalize -cse -canonicalize -ep2-atomic-id -canonicalize -cse -canonicalize -ep2-linearize -o fpga_out/commonopt.mlir 32 | 33 | # Cut-Mapping Optimization 34 | if [ "$disable_cut" != "disable_cut" ]; then 35 | ./build/bin/ep2c-opt "fpga_out/commonopt.mlir" --ep2-pipeline-handler="mode=loop target=fpga" -o "fpga_out/cut.mlir" 36 | else 37 | echo "Warning: cut optimization is disabled, skipping cut optimization" 38 | cp "fpga_out/commonopt.mlir" "fpga_out/cut.mlir" 39 | fi 40 | 41 | 42 | 43 | # Backend Codegen 44 | ./build/bin/ep2c-opt --ep2-pipeline-canon="inline-table=true" -ep2-handler-repl -ep2-global-to-partition "fpga_out/cut.mlir" -o "fpga_out/mapped.mlir" 45 | ./build/bin/ep2c-opt -ep2-emit-fpga "fpga_out/mapped.mlir" -o "fpga_out/emit.mlir" 46 | 47 | 48 | cp ./__*.sv ./fpga_out/ 49 | rm ./__*.sv 50 | -------------------------------------------------------------------------------- /runtime_lib/netronome_runtime/microc/lib/net/ah.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017, Netronome Systems, Inc. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | * @file lib/net/ah.h 17 | * @brief Definitions for AH header parsing 18 | * 19 | * Incomplete, new definitions will be added as/when needed 20 | */ 21 | 22 | #ifndef _NET_AH_H_ 23 | #define _NET_AH_H_ 24 | 25 | /** 26 | * AH type definitions 27 | */ 28 | 29 | #if defined(__NFP_LANG_MICROC) 30 | 31 | #include 32 | #include 33 | 34 | /** 35 | * AH Header structure 36 | */ 37 | __packed struct ah_hdr { 38 | uint8_t nh; /** Next Header */ 39 | uint8_t pay_len; /** Payload length */ 40 | uint16_t rsvd; /** Reserved */ 41 | uint32_t spi; /** Security Parameters Index */ 42 | uint32_t seq; /** Sequence Number */ 43 | }; 44 | 45 | #endif /* __NFP_LANG_MICROC */ 46 | 47 | #endif /* _NET_AH_H_ */ 48 | 49 | /* -*- Mode:C; c-basic-offset:4; tab-width:4 -*- */ 50 | -------------------------------------------------------------------------------- /tests/pipeline_test/nopipeline_small.mlir: -------------------------------------------------------------------------------- 1 | // ./build/bin/ep2c-opt -canonicalize -cse -canonicalize -ep2-buffer-to-value nopipeline.mlir -o opt.mlir 2 | 3 | module { 4 | ep2.func private @__handler_NET_RECV_process_packet(%arg0: !ep2.context, %arg1: !ep2.buf) attributes {atom = "process_packet", event = "NET_RECV", instances = ["i1cu2", "i1cu3", "i1cu4", "i1cu5"], type = "handler"} { 5 | %0 = "ep2.constant"() <{value = "net_send"}> : () -> !ep2.atom 6 | %1, %output = "ep2.extract_value"(%arg1) : (!ep2.buf) -> (!ep2.buf, !ep2.struct<"pkt_info_t" : isEvent = false, elementTypes = i64, i64, i64, i64>) 7 | %23 = ep2.struct_access %output[0] : <"pkt_info_t" : isEvent = false, elementTypes = i64, i64, i64, i64> -> i64 8 | %24 = ep2.struct_access %output[1] : <"pkt_info_t" : isEvent = false, elementTypes = i64, i64, i64, i64> -> i64 9 | %25 = "ep2.add"(%23, %24) : (i64, i64) -> i64 10 | %73 = "ep2.struct_update"(%output, %25) <{index = 3 : i64}> : (!ep2.struct<"pkt_info_t" : isEvent = false, elementTypes = i64, i64, i64, i64>, i64) -> !ep2.struct<"pkt_info_t" : isEvent = false, elementTypes = i64, i64, i64, i64> 11 | %74 = "ep2.emit_value"(%1, %73) : (!ep2.buf, !ep2.struct<"pkt_info_t" : isEvent = false, elementTypes = i64, i64, i64, i64>) -> !ep2.buf 12 | %75 = "ep2.init"(%0, %arg0, %74) : (!ep2.atom, !ep2.context, !ep2.buf) -> !ep2.struct<"NET_SEND" : isEvent = true, elementTypes = !ep2.context, !ep2.buf> 13 | ep2.return %75 : !ep2.struct<"NET_SEND" : isEvent = true, elementTypes = !ep2.context, !ep2.buf> 14 | "ep2.terminate"() : () -> () 15 | } 16 | } 17 | 18 | -------------------------------------------------------------------------------- /runtime_lib/fpga_runtime/rtl_lib/ep2/barrier.sv: -------------------------------------------------------------------------------- 1 | module ctrl_barrier#( 2 | parameter PORT_COUNT = 2 3 | ) 4 | ( 5 | input wire clk, 6 | input wire rst, 7 | 8 | input wire [PORT_COUNT-1:0] s_inc, 9 | 10 | input wire [PORT_COUNT-1:0] s_dec, 11 | 12 | output wire [PORT_COUNT:0] ctrl_barrier 13 | ); 14 | 15 | 16 | integer j, c; 17 | 18 | reg [15:0] incount_array [PORT_COUNT-1:0]; 19 | reg [15:0] outcount_array [PORT_COUNT-1:0]; 20 | initial begin 21 | for (j = 0; j < PORT_COUNT; j = j + 1) begin 22 | incount_array[j] = 0; 23 | outcount_array[j] = 0; 24 | end 25 | end 26 | 27 | reg[15:0] min_incount; 28 | always @(*) begin 29 | min_incount = incount_array[0]; 30 | for (c = 0; c <= PORT_COUNT; c++) 31 | begin 32 | if (incount_array[c] < min_incount) 33 | begin 34 | min_incount = incount_array[c]; 35 | end 36 | end 37 | end 38 | 39 | genvar rid; 40 | generate 41 | for (rid=0; rid 30 | #include 31 | 32 | /** 33 | * VXLAN header structure 34 | */ 35 | __packed struct vxlan_hdr { 36 | unsigned int reserved1:4; 37 | unsigned int i:1; /* Indicates valid VNI */ 38 | unsigned int reserved2:3; 39 | unsigned int reserved3:24; 40 | 41 | unsigned int vni:24; /* VXLAN Network Identifier */ 42 | unsigned int reserved4:8; 43 | }; 44 | #endif /* __NFP_LANG_MICROC */ 45 | 46 | #endif /* _NET_VXLAN_H_ */ 47 | 48 | /* -*- Mode:C; c-basic-offset:4; tab-width:4 -*- */ 49 | -------------------------------------------------------------------------------- /tests/output/buf_to_value.buffer_to_value.mlir: -------------------------------------------------------------------------------- 1 | // ./build/bin/ep2c-opt --canonicalize -cse --ep2-context-infer --ep2-context-to-argument -ep2-buffer-to-value tmp.mlir > tests/output/buf_to_value.buffer_to_value.mlir 2 | module { 3 | ep2.func private @__handler_MY_EVENT_my_handler_event(%arg0: !ep2.buf, %arg1: i32, %arg2: i32 {ep2.context_name = "test"}, %arg3: i32 {ep2.context_name = "bench"}) attributes {atom = "my_handler_event", event = "MY_EVENT", type = "handler"} { 4 | %0 = "ep2.constant"() <{value = 4 : i32}> : () -> i32 5 | %1 = "ep2.constant"() <{value = 2 : i32}> : () -> i32 6 | %2 = "ep2.constant"() <{value = 1 : i32}> : () -> i32 7 | %3 = "ep2.constant"() <{value = "my_handler_event"}> : () -> !ep2.atom 8 | %4, %output = "ep2.extract_value"(%arg0) : (!ep2.buf) -> (!ep2.buf, !ep2.struct<"header" : isEvent = false, elementTypes = i32, i32>) 9 | %5 = "ep2.emit_value"(%4, %output) : (!ep2.buf, !ep2.struct<"header" : isEvent = false, elementTypes = i32, i32>) -> !ep2.buf 10 | %6 = ep2.struct_access %output[0] : <"header" : isEvent = false, elementTypes = i32, i32> -> i32 11 | %7 = "ep2.cmp"(%2, %arg1) <{predicate = 60 : i16}> : (i32, i32) -> i1 12 | %8 = arith.select %7, %0, %arg3 : i32 13 | %9 = arith.select %7, %0, %1 : i32 14 | %10 = "ep2.init"(%3, %5, %6, %9, %8) : (!ep2.atom, !ep2.buf, i32, i32, i32) -> !ep2.struct<"MY_EVENT_OUT" : isEvent = true, elementTypes = !ep2.atom, !ep2.buf, i32, i32, i32> 15 | ep2.return %10 : !ep2.struct<"MY_EVENT_OUT" : isEvent = true, elementTypes = !ep2.atom, !ep2.buf, i32, i32, i32> 16 | "ep2.terminate"() : () -> () 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /lib/ep2/TableAnalysis.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "ep2/dialect/Dialect.h" 3 | #include "ep2/dialect/Passes.h" 4 | #include "mlir/IR/BuiltinDialect.h" 5 | 6 | #include "mlir/IR/BuiltinOps.h" 7 | #include "mlir/IR/Visitors.h" 8 | #include "mlir/Pass/Pass.h" 9 | #include "llvm/ADT/StringMap.h" 10 | 11 | using namespace mlir; 12 | 13 | namespace mlir { 14 | namespace ep2 { 15 | 16 | TableAnalysis::TableAnalysis(Operation *module) { 17 | // walk through and find all function targets. 18 | 19 | module->walk([&](InitOp initop) { 20 | if (isa(initop.getResult().getType())) { 21 | auto table = initop.getResult(); 22 | int update_index = 0; 23 | int lookup_index = 0; 24 | mlir::SmallVector tmp_lookup_v; 25 | mlir::SmallVector tmp_update_v; 26 | for (auto table_use : table.getUsers()) { 27 | if(isa(table_use)){ 28 | auto updateop = cast(table_use); 29 | tmp_update_v.push_back(updateop); 30 | access_index[updateop] = update_index++; 31 | }else if (isa(table_use)) { 32 | auto lookupop = cast(table_use); 33 | tmp_lookup_v.push_back(lookupop); 34 | access_index[lookupop] = lookup_index++; 35 | } else{ 36 | table_use->dump(); 37 | assert(false); 38 | } 39 | } 40 | 41 | table_update_uses[table] = tmp_update_v; 42 | table_lookup_uses[table] = tmp_lookup_v; 43 | } 44 | }); 45 | 46 | 47 | } 48 | } // namespace ep2 49 | } // namespace mlir 50 | -------------------------------------------------------------------------------- /runtime-llvm/runtime.h: -------------------------------------------------------------------------------- 1 | #ifndef _EP2_LLVM_RUNTIME_H_ 2 | #define _EP2_LLVM_RUNTIME_H_ 3 | 4 | #include 5 | #include "glib.h" 6 | 7 | // Queues. 8 | extern GAsyncQueue **queues; 9 | 10 | // thread workers 11 | typedef void * (*handler_worker_t)(void *); 12 | #define WORKER_FUNCTION(tag,handler_func) \ 13 | void * __thread ## handler_func (void * tid) { \ 14 | while (1) { \ 15 | void * event = g_async_queue_pop(queues[tag]); \ 16 | printf("[thread %s][%lu][qid: %d] got event %p\n", #handler_func, (uintptr_t)tid, tag, event); \ 17 | handler_func(event); \ 18 | } \ 19 | pthread_exit(NULL); \ 20 | } 21 | 22 | typedef struct { 23 | const char * name; 24 | int num_ins, num_outs; 25 | int ins[16]; 26 | int outs[16]; 27 | } extern_worker_t; 28 | 29 | typedef struct { 30 | char *data; 31 | int size; 32 | int offset; 33 | } buf_t; 34 | 35 | void __rt_generate(int tag, int size, void *data); 36 | void __rt_buf_init(buf_t *buf); 37 | void __rt_buf_free(void *buf); 38 | void * __rt_buf_extract(buf_t *buf, int size); 39 | void __rt_buf_emit(buf_t *buf, int size, void *data); 40 | void __rt_buf_concat(buf_t *buf, buf_t *other); 41 | 42 | // Standard libs 43 | typedef struct { 44 | int vsize; 45 | void * el; 46 | } table_t; 47 | 48 | void __rt_table_init(table_t * table, int vsize); 49 | void * __rt_table_alloc(int vsize); 50 | void * __rt_table_lookup(table_t * table, int key); 51 | void __rt_table_update(table_t * table, int key, void * value); 52 | 53 | void __rt_pthread_mutex_init(pthread_mutex_t * mutex); 54 | 55 | 56 | #endif // _EP2_LLVM_RUNTIME_H_ -------------------------------------------------------------------------------- /tests/output/buf_to_value.context_to_argument.mlir: -------------------------------------------------------------------------------- 1 | // ./build/bin/ep2c-opt --canonicalize -cse --ep2-context-infer --ep2-context-to-argument tmp.mlir > tests/output/buf_to_value.buffer_to_value.mlir 2 | module { 3 | ep2.func private @__handler_MY_EVENT_my_handler_event(%arg0: !ep2.buf, %arg1: i32, %arg2: i32 {ep2.context_name = "test"}, %arg3: i32 {ep2.context_name = "bench"}) attributes {atom = "my_handler_event", event = "MY_EVENT", type = "handler"} { 4 | %0 = "ep2.constant"() <{value = "my_handler_event"}> : () -> !ep2.atom 5 | %1 = "ep2.constant"() <{value = 1 : i32}> : () -> i32 6 | %2 = "ep2.constant"() <{value = 2 : i32}> : () -> i32 7 | %3 = "ep2.constant"() <{value = 4 : i32}> : () -> i32 8 | %4 = "ep2.extract"(%arg0) : (!ep2.buf) -> !ep2.struct<"header" : isEvent = false, elementTypes = i32, i32> 9 | "ep2.emit"(%arg0, %4) : (!ep2.buf, !ep2.struct<"header" : isEvent = false, elementTypes = i32, i32>) -> () 10 | %5 = ep2.struct_access %4[0] : <"header" : isEvent = false, elementTypes = i32, i32> -> i32 11 | %6 = "ep2.cmp"(%1, %arg1) <{predicate = 60 : i16}> : (i32, i32) -> i1 12 | cf.cond_br %6, ^bb1(%3, %3 : i32, i32), ^bb1(%arg3, %2 : i32, i32) 13 | ^bb1(%7: i32, %8: i32): // 2 preds: ^bb0, ^bb0 14 | cf.br ^bb2(%7, %8 : i32, i32) 15 | ^bb2(%9: i32, %10: i32): // pred: ^bb1 16 | %11 = "ep2.init"(%0, %arg0, %5, %10, %9) : (!ep2.atom, !ep2.buf, i32, i32, i32) -> !ep2.struct<"MY_EVENT_OUT" : isEvent = true, elementTypes = !ep2.atom, !ep2.buf, i32, i32, i32> 17 | ep2.return %11 : !ep2.struct<"MY_EVENT_OUT" : isEvent = true, elementTypes = !ep2.atom, !ep2.buf, i32, i32, i32> 18 | "ep2.terminate"() : () -> () 19 | } 20 | } 21 | 22 | -------------------------------------------------------------------------------- /include/Standalone/StandaloneDialect.td: -------------------------------------------------------------------------------- 1 | //===- StandaloneDialect.td - Standalone dialect -----------*- tablegen -*-===// 2 | // 3 | // This file is licensed under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | #ifndef STANDALONE_DIALECT 10 | #define STANDALONE_DIALECT 11 | 12 | include "mlir/IR/OpBase.td" 13 | 14 | //===----------------------------------------------------------------------===// 15 | // Standalone dialect definition. 16 | //===----------------------------------------------------------------------===// 17 | 18 | def Standalone_Dialect : Dialect { 19 | let name = "standalone"; 20 | let summary = "A standalone out-of-tree MLIR dialect."; 21 | let description = [{ 22 | This dialect is an example of an out-of-tree MLIR dialect designed to 23 | illustrate the basic setup required to develop MLIR-based tools without 24 | working inside of the LLVM source tree. 25 | }]; 26 | let cppNamespace = "::mlir::standalone"; 27 | 28 | let useDefaultTypePrinterParser = 1; 29 | let extraClassDeclaration = [{ 30 | void registerTypes(); 31 | }]; 32 | } 33 | 34 | //===----------------------------------------------------------------------===// 35 | // Base standalone operation definition. 36 | //===----------------------------------------------------------------------===// 37 | 38 | class Standalone_Op traits = []> : 39 | Op; 40 | 41 | #endif // STANDALONE_DIALECT 42 | -------------------------------------------------------------------------------- /lib/ep2/Passes/Mapping/PipeliningPass.cpp: -------------------------------------------------------------------------------- 1 | #include "ep2/passes/Mapping.h" 2 | #include "ep2/dialect/Passes.h" 3 | 4 | #include 5 | 6 | namespace mlir { 7 | namespace ep2 { 8 | 9 | 10 | // The main optimization loop 11 | void optimizationLoop(FuncOp funcOp, PipelineMapper &mapper, PipelineCutExplorer &explorer) { 12 | std::queue pipelines; 13 | pipelines.push({funcOp}); 14 | 15 | int numNonOpts = 0; 16 | size_t optPerformance = 0; 17 | 18 | while (!pipelines.empty()) { 19 | auto &pipeline = pipelines.front(); 20 | auto [updated, result] = mapper.tryMap(pipeline); 21 | 22 | llvm::errs() << "Searching Pipeline size: " + std::to_string(pipeline.size()) + "\n"; 23 | for (auto &funcOp : pipeline) { 24 | llvm::errs() << funcOp.getName() << " "; 25 | } 26 | llvm::errs() << "Result Latency: " << result.latency << "\n"; 27 | llvm::errs() << "Result Mapping: \n"; 28 | for (auto [index, unit] : result.unitMap) { 29 | llvm::errs() << "Function: " << pipeline[index].getName() << " Unit: "; 30 | for (auto &u : unit) { 31 | llvm::errs() << u << " "; 32 | } 33 | llvm::errs() << "\n"; 34 | } 35 | 36 | if (updated) 37 | numNonOpts = 0; 38 | else 39 | numNonOpts++; 40 | 41 | if (numNonOpts >= PIPELINE_EXTRA_SEARCH) 42 | break; 43 | 44 | // cleanup 45 | auto nexts = explorer.next(pipeline, result.bottleneckIndex); 46 | for (auto &next : nexts) 47 | pipelines.push(std::move(next)); 48 | 49 | pipelines.pop(); 50 | } 51 | } 52 | 53 | } // namespace mlir 54 | } // namespace ep2 -------------------------------------------------------------------------------- /runtime_lib/netronome_runtime/microc/include/stdint.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2015, Netronome Systems, Inc. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | * @file stdint.h 17 | * @brief C99 Integer types 18 | */ 19 | 20 | #ifndef _STDINT_H_ 21 | #define _STDINT_H_ 22 | 23 | /* Integral types */ 24 | typedef signed char int8_t; 25 | typedef short int int16_t; 26 | typedef int int32_t; 27 | typedef long long int int64_t; 28 | 29 | typedef unsigned char uint8_t; 30 | typedef unsigned short int uint16_t; 31 | typedef unsigned int uint32_t; 32 | typedef unsigned long long int uint64_t; 33 | 34 | /* Limits of integral types */ 35 | #define INT8_MIN (-128) 36 | #define INT16_MIN (-32767-1) 37 | #define INT32_MIN (-2147483647-1) 38 | 39 | #define INT8_MAX (127) 40 | #define INT16_MAX (32767) 41 | #define INT32_MAX (2147483647) 42 | 43 | #define UINT8_MAX (255) 44 | #define UINT16_MAX (65535) 45 | #define UINT32_MAX (4294967295U) 46 | 47 | #endif /* _STDINT_H_ */ 48 | -------------------------------------------------------------------------------- /scripts/run_c.sh: -------------------------------------------------------------------------------- 1 | C_INPUT_DIR=./ 2 | C_PREPROCESS=cpre.c 3 | C_LLVM_FILE=cinput.ll 4 | C_MLIR_FILE=cinput.mlir 5 | OUT_FILE=out.mlir 6 | 7 | IS_SPLIT=false 8 | OPTIONS= 9 | 10 | while getopts ":dlo:s" opt; do 11 | case $opt in 12 | l) 13 | echo "Listing of example files:" 14 | ls $C_INPUT_DIR 15 | exit 0 16 | ;; 17 | o) 18 | OUT_FILE=${OPTARG} 19 | ;; 20 | d) OPTIONS="--debug-only=ep2-lift-llvm,dialect-conversion --mlir-print-ir-after-failure" 21 | ;; 22 | s) 23 | IS_SPLIT=true 24 | ;; 25 | ?) 26 | echo "INVALID OPT" 27 | exit 1 28 | ;; 29 | esac 30 | done 31 | shift $((OPTIND-1)) 32 | 33 | C_INPUT_FILE=$C_INPUT_DIR/${1:-pipeline.c} 34 | echo "Compile ${C_INPUT_FILE} to ${C_MLIR_FILE}" 35 | 36 | BIN_DIR=build/bin 37 | CLANG_BIN_DIR=llvm-project/build/bin 38 | EXTRACT_PY=./scripts/extract_struct_def.py 39 | 40 | cc -E $C_INPUT_FILE -o $C_PREPROCESS 41 | python3 $EXTRACT_PY $C_INPUT_FILE -o cinput.struct.json 42 | $CLANG_BIN_DIR/clang -S -emit-llvm $C_PREPROCESS -o $C_LLVM_FILE 43 | $CLANG_BIN_DIR/mlir-translate --import-llvm $C_LLVM_FILE -o $C_MLIR_FILE 44 | $BIN_DIR/ep2c-opt $C_MLIR_FILE --convert-scf-to-cf -cse -o cinput2.mlir 45 | 46 | $BIN_DIR/ep2c-opt cinput2.mlir --ep2-lift-llvm="struct-desc=cinput.struct.json" $OPTIONS -cse -cse -canonicalize --ep2-context-to-mem="transform-extern=true" -o $OUT_FILE 47 | 48 | echo "Generation of IR success. Saved to $OUT_FILE" 49 | 50 | if [ "$IS_SPLIT" = true ]; then 51 | echo "Split $OUT_FILE" 52 | $BIN_DIR/ep2c-opt $OUT_FILE -ep2-buffer-to-value --ep2-pipeline-handler --mlir-print-ir-after-failure -o split.mlir 2> debug.mlir 53 | fi 54 | -------------------------------------------------------------------------------- /runtime_lib/fpga_runtime/rtl_lib/ep2/atom_cam.sv: -------------------------------------------------------------------------------- 1 | // Generator : SpinalHDL v1.10.0 git head : 270018552577f3bb8e5339ee2583c9c22d324215 2 | // Component : CAM 3 | // Git hash : 3a6304c32f02162848fb56753fa73afb0c4afdc2 4 | 5 | `timescale 1ns/1ps 6 | 7 | module atom_CAM ( 8 | input wire s_lookup_req_valid, 9 | output wire s_lookup_req_ready, 10 | input wire [7:0] s_lookup_req_index, 11 | output wire s_lookup_value_valid, 12 | input wire s_lookup_value_ready, 13 | output reg [31:0] s_lookup_value_data, 14 | input wire s_update_req_index_valid, 15 | output wire s_update_req_index_ready, 16 | input wire [7:0] s_update_req_index, 17 | input wire s_update_req_data_valid, 18 | output wire s_update_req_data_ready, 19 | input wire [31:0] s_update_req_data, 20 | input wire clk, 21 | input wire rst 22 | ); 23 | 24 | CAM #() CAMinst ( 25 | .io_readRequest_valid(s_lookup_req_valid), 26 | .io_readRequest_ready(s_lookup_req_ready), 27 | .io_readRequest_payload(s_lookup_req_index), 28 | .io_readResponse_valid(s_lookup_value_valid), 29 | .io_readResponse_ready(s_lookup_value_ready), 30 | .io_readResponse_payload(s_lookup_value_data), 31 | .io_writeRequest_key_valid(s_update_req_index_valid), 32 | .io_writeRequest_key_ready(s_update_req_index_ready), 33 | .io_writeRequest_key_payload(s_update_req_index), 34 | .io_writeRequest_value_valid(s_update_req_data_valid), 35 | .io_writeRequest_value_ready(s_update_req_data_ready), 36 | .io_writeRequest_value_payload(s_update_req_data), 37 | .io_writeRequest_op_valid(1), 38 | .io_writeRequest_op_ready(), 39 | .io_writeRequest_op_payload(1), 40 | .clk(clk), 41 | .reset(rst) 42 | ); 43 | 44 | endmodule 45 | 46 | -------------------------------------------------------------------------------- /runtime_lib/netronome_runtime/microc/lib/net/mpls.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015, Netronome Systems, Inc. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | * @file lib/net/mpls.h 17 | * @brief Definitions for MPLS header parsing 18 | * 19 | */ 20 | 21 | #ifndef _NET_MPLS_H_ 22 | #define _NET_MPLS_H_ 23 | 24 | /* MPLS RFC 5462 is the latest but basic RFC was RFC 3032 */ 25 | 26 | /** 27 | * default MPLS UDP destination port number as per RFC 7510 28 | */ 29 | #define NET_MPLS_PORT 6635 30 | 31 | #if defined(__NFP_LANG_MICROC) 32 | 33 | #include 34 | #include 35 | 36 | /** 37 | * MPLS header structure 38 | */ 39 | __packed struct mpls_hdr { 40 | union { 41 | struct { 42 | unsigned int label:20; /** Label */ 43 | unsigned int tc:3; /** Traffic Class */ 44 | unsigned int s:1; /** Bottom of Stack */ 45 | unsigned int ttl:8; /** Time to Live */ 46 | }; 47 | unsigned int __raw; 48 | }; 49 | }; 50 | 51 | #endif /* __NFP_LANG_MICROC */ 52 | 53 | #endif /* _NET_MPLS_H_ */ 54 | 55 | /* -*- Mode:C; c-basic-offset:4; tab-width:4 -*- */ 56 | -------------------------------------------------------------------------------- /runtime_lib/netronome_runtime/microc/lib/net/udp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2015, Netronome Systems, Inc. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | * @file lib/net/udp.h 17 | * @brief Definitions for UDP header parsing 18 | * 19 | * Incomplete, new definitions will be added as/when needed 20 | */ 21 | 22 | #ifndef _NET_UDP_H_ 23 | #define _NET_UDP_H_ 24 | 25 | /** 26 | * Header length definitions 27 | * @NET_UDP_LEN Length of UDP header 28 | * @NET_UDP_LEN32 Length of UDP header (32bit words) 29 | */ 30 | #define NET_UDP_LEN 8 31 | #define NET_UDP_LEN32 (NET_UDP_LEN / 4) 32 | 33 | 34 | #if defined(__NFP_LANG_MICROC) 35 | 36 | #include 37 | #include 38 | 39 | /** 40 | * UDP Header structure 41 | */ 42 | __packed struct udp_hdr { 43 | uint16_t sport; /** Source port */ 44 | uint16_t dport; /** Destination port */ 45 | 46 | uint16_t len; /** Length */ 47 | uint16_t sum; /** Checksum */ 48 | }; 49 | #endif /* __NFP_LANG_MICROC */ 50 | 51 | #endif /* _NET_UDP_H_ */ 52 | 53 | /* -*- Mode:C; c-basic-offset:4; tab-width:4 -*- */ 54 | -------------------------------------------------------------------------------- /runtime_lib/netronome_runtime/lib/lmem_lookup.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: BSD 3-Clause License */ 2 | /* Copyright (c) 2022, University of Washington, Max Planck Institute for Software Systems, and The University of Texas at Austin */ 3 | 4 | #ifndef LMEM_FLOW_LOOKUP_H_ 5 | #define LMEM_FLOW_LOOKUP_H_ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include "fp_mem.h" 16 | #include "nfplib.h" 17 | 18 | #define INVALID_FLOWID ((uint32_t) -1) 19 | 20 | struct flow_key_t { 21 | uint32_t key; 22 | }; 23 | 24 | struct flowht_entry_t { 25 | struct flow_key_t key; 26 | uint32_t flow_id; 27 | }; 28 | 29 | __intrinsic int lmem_flow_insert(__lmem struct flowht_entry_t* tb, __gpr struct flowht_entry_t* entry, int size) 30 | { 31 | __gpr uint64_t b_idx; 32 | b_idx = lmem_flow_hash(&(entry->key)); 33 | b_idx = CAMHT_BUCKET_IDX(b_idx, size); 34 | tb[b_idx] = *entry; 35 | } 36 | 37 | 38 | __intrinsic uint64_t lmem_flow_hash(__gpr struct flow_key_t* key) 39 | { 40 | struct camht_hash_t hash; 41 | camht_hash((void*) key, sizeof(struct flow_key_t), &hash); 42 | 43 | return hash.__raw; 44 | } 45 | 46 | __intrinsic int lmem_flow_lookup(__lmem struct flowht_entry_t* tb, __gpr struct flow_key_t* key, int size) 47 | { 48 | __gpr struct flowht_entry_t entry; 49 | __gpr uint64_t b_idx; 50 | __gpr int result; 51 | b_idx = lmem_flow_hash(key); 52 | b_idx = CAMHT_BUCKET_IDX(b_idx, size); 53 | result = tb[b_idx].flow_id; 54 | if (!reg_eq(&entry, (void*) key, sizeof(struct flow_key_t))) 55 | goto out; 56 | 57 | return result; 58 | 59 | out: 60 | return -1; 61 | } 62 | 63 | #endif /* LMEM_FLOW_LOOKUP_H_ */ -------------------------------------------------------------------------------- /example_outputs/outs-netronome/out-netronome-l2_echo/canon.mlir: -------------------------------------------------------------------------------- 1 | module { 2 | ep2.func private @__handler_NET_SEND_main_send(%arg0: !ep2.context, %arg1: !ep2.buf) attributes {atom = "main_send", event = "NET_SEND", extern = true, type = "handler"} { 3 | "ep2.terminate"() : () -> () 4 | } 5 | ep2.func private @__handler_NET_RECV_main_recv(%arg0: !ep2.context, %arg1: !ep2.buf) attributes {atom = "main_recv", event = "NET_RECV", type = "handler"} { 6 | %0 = "ep2.constant"() <{value = "main_send"}> : () -> !ep2.atom 7 | %1 = "ep2.init"() : () -> !ep2.buf 8 | %2 = "ep2.extract"(%arg1) : (!ep2.buf) -> !ep2.struct<"eth_header_t" : isEvent = false, elementTypes = i48, i48, i16> 9 | %3 = ep2.struct_access %2[1] : <"eth_header_t" : isEvent = false, elementTypes = i48, i48, i16> -> i48 10 | %4 = ep2.struct_access %2[0] : <"eth_header_t" : isEvent = false, elementTypes = i48, i48, i16> -> i48 11 | %5 = "ep2.struct_update"(%2, %4) <{index = 1 : i64}> : (!ep2.struct<"eth_header_t" : isEvent = false, elementTypes = i48, i48, i16>, i48) -> !ep2.struct<"eth_header_t" : isEvent = false, elementTypes = i48, i48, i16> 12 | %6 = "ep2.struct_update"(%5, %3) <{index = 0 : i64}> : (!ep2.struct<"eth_header_t" : isEvent = false, elementTypes = i48, i48, i16>, i48) -> !ep2.struct<"eth_header_t" : isEvent = false, elementTypes = i48, i48, i16> 13 | "ep2.emit"(%1, %6) : (!ep2.buf, !ep2.struct<"eth_header_t" : isEvent = false, elementTypes = i48, i48, i16>) -> () 14 | "ep2.emit"(%1, %arg1) : (!ep2.buf, !ep2.buf) -> () 15 | %7 = "ep2.init"(%0, %arg0, %1) : (!ep2.atom, !ep2.context, !ep2.buf) -> !ep2.struct<"NET_SEND" : isEvent = true, elementTypes = !ep2.context, !ep2.buf> 16 | ep2.return %7 : !ep2.struct<"NET_SEND" : isEvent = true, elementTypes = !ep2.context, !ep2.buf> 17 | "ep2.terminate"() : () -> () 18 | } 19 | } 20 | 21 | -------------------------------------------------------------------------------- /runtime_lib/netronome_runtime/microc/lib/net/arp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015, Netronome Systems, Inc. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | * @file lib/net/arp.h 17 | * @brief Definitions for ARP header parsing 18 | * 19 | */ 20 | 21 | #ifndef _NET_ARP_H_ 22 | #define _NET_ARP_H_ 23 | 24 | #define NET_ARP_HA_LEN 6 25 | 26 | #if defined(__NFP_LANG_MICROC) 27 | 28 | #include 29 | #include 30 | 31 | /** 32 | * ARP header structure 33 | */ 34 | __packed struct arp_hdr { 35 | unsigned int htype:16; /* hardware type */ 36 | unsigned int ptype:16; /* protocol type */ 37 | 38 | unsigned int hlen:8; /* hardware length */ 39 | unsigned int plen:8; /* protocol length */ 40 | unsigned int proto:16; /* operation (1=request, 2=reply) */ 41 | 42 | uint8_t sha[NET_ARP_HA_LEN]; /* sender hardware address */ 43 | 44 | unsigned int spa; /* sender protocol address */ 45 | 46 | uint8_t tha[NET_ARP_HA_LEN]; /* target hardware address */ 47 | 48 | unsigned int tpa; /* target protocol address */ 49 | }; 50 | #endif /* __NFP_LANG_MICROC */ 51 | 52 | #endif /* _NET_ARP_H_ */ 53 | 54 | /* -*- Mode:C; c-basic-offset:4; tab-width:4 -*- */ 55 | -------------------------------------------------------------------------------- /runtime_lib/netronome_runtime/microc/lib/net/sctp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016, Netronome Systems, Inc. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | * @file lib/net/sctp.h 17 | * @brief Definitions for SCTP header parsing 18 | * 19 | * Incomplete, new definitions will be added as/when needed 20 | */ 21 | 22 | #ifndef _NET_SCTP_H_ 23 | #define _NET_SCTP_H_ 24 | 25 | /** 26 | * Header length definitions 27 | * @NET_SCTP_LEN Length of SCTP header 28 | * @NET_SCTP_LEN32 Length of SCTP header (32bit words) 29 | */ 30 | #define NET_SCTP_LEN 12 31 | #define NET_SCTP_LEN32 (NET_SCTP_LEN / 4) 32 | 33 | /** 34 | * SCTP type definitions 35 | */ 36 | 37 | #if defined(__NFP_LANG_MICROC) 38 | 39 | #include 40 | #include 41 | 42 | /** 43 | * SCTP Header structure 44 | */ 45 | __packed struct sctp_hdr { 46 | uint16_t sport; /** Source port */ 47 | uint16_t dport; /** Destination port */ 48 | 49 | uint32_t ver; /** Verification tag */ 50 | 51 | uint32_t sum; /** Checksum */ 52 | }; 53 | 54 | #endif /* __NFP_LANG_MICROC */ 55 | 56 | #endif /* _NET_SCTP_H_ */ 57 | 58 | /* -*- Mode:C; c-basic-offset:4; tab-width:4 -*- */ 59 | -------------------------------------------------------------------------------- /runtime_lib/fpga_runtime/rtl_lib/ep2/ctrl_dispatcher.sv: -------------------------------------------------------------------------------- 1 | module ctrl_dispatcher#( 2 | parameter D_COUNT = 2, 3 | parameter DISPATCH_WIDTH = $clog2(D_COUNT), 4 | parameter REPLICATED_OUT_NUM = 3 5 | ) 6 | ( 7 | input wire clk, 8 | input wire rst, 9 | 10 | 11 | output wire [REPLICATED_OUT_NUM*DISPATCH_WIDTH-1:0] m_dispatcher_tdata, 12 | output wire [REPLICATED_OUT_NUM-1:0] m_dispatcher_tvalid, 13 | input wire [REPLICATED_OUT_NUM-1:0] m_dispatcher_tready 14 | ); 15 | 16 | reg [9:0] rr_counter; 17 | reg replicate_selector_tvalid; 18 | 19 | always @(posedge clk) begin 20 | if(rst) begin 21 | rr_counter <= 0; 22 | end 23 | else begin 24 | replicate_selector_tvalid <= 1; 25 | if (replicate_selector_tvalid && replicate_selector_tready) begin 26 | if(rr_counter == (D_COUNT-1)) begin 27 | rr_counter <= 0; 28 | end 29 | else begin 30 | rr_counter <= rr_counter + 1; 31 | end 32 | end 33 | end 34 | end 35 | 36 | wire [DISPATCH_WIDTH-1:0] replicate_selector_tdata; 37 | wire replicate_selector_tvalid; 38 | wire replicate_selector_tready; 39 | 40 | assign replicate_selector_tdata = rr_counter; 41 | 42 | axis_replication#( 43 | .DATA_WIDTH(DISPATCH_WIDTH), 44 | .IF_STREAM(0), 45 | .REAPLICA_COUNT(REPLICATED_OUT_NUM) 46 | )axis_replication_6( 47 | .clk(clk), 48 | .rst(rst) , 49 | // 50 | .s_axis_in_tdata(replicate_selector_tdata), 51 | .s_axis_in_tvalid(replicate_selector_tvalid), 52 | .s_axis_in_tready(replicate_selector_tready), 53 | // 54 | .m_axis_out_tdata(m_dispatcher_tdata), 55 | .m_axis_out_tvalid(m_dispatcher_tvalid), 56 | .m_axis_out_tready(m_dispatcher_tready) 57 | ); 58 | endmodule -------------------------------------------------------------------------------- /runtime_lib/fpga_runtime/rtl_lib/axis/rtl/sync_reset.v: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright (c) 2014-2020 Alex Forencich 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | */ 24 | 25 | // Language: Verilog-2001 26 | 27 | `timescale 1ns / 1ps 28 | 29 | /* 30 | * Synchronizes an active-high asynchronous reset signal to a given clock by 31 | * using a pipeline of N registers. 32 | */ 33 | module sync_reset # 34 | ( 35 | // depth of synchronizer 36 | parameter N = 2 37 | ) 38 | ( 39 | input wire clk, 40 | input wire rst, 41 | output wire out 42 | ); 43 | 44 | (* srl_style = "register" *) 45 | reg [N-1:0] sync_reg = {N{1'b1}}; 46 | 47 | assign out = sync_reg[N-1]; 48 | 49 | always @(posedge clk or posedge rst) begin 50 | if (rst) begin 51 | sync_reg <= {N{1'b1}}; 52 | end else begin 53 | sync_reg <= {sync_reg[N-2:0], 1'b0}; 54 | end 55 | end 56 | 57 | endmodule 58 | -------------------------------------------------------------------------------- /scripts/netronome_compile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | EXTRA_OPT="" 6 | ninja -C build/ -j 32 7 | shift $((OPTIND-1)) 8 | 9 | BASE_NAME="${1%.*}" 10 | rm -rf "netronome_out" 11 | mkdir -p "netronome_out" 12 | 13 | set -x 14 | 15 | file="$1" 16 | # Extract the extension from the filename 17 | extension="${file##*.}" 18 | 19 | # whether disable cut 20 | disable_cut="$2" 21 | # whether disable mapping 22 | disable_map="$3" 23 | 24 | 25 | case "$extension" in 26 | ep2) 27 | ./build/bin/ep2c $1 --emit=mlir -o "netronome_out/$BASE_NAME.mlir" 28 | echo "Running base command for .ep2 file..." 29 | ;; 30 | mlir) 31 | cp $1 "netronome_out/$BASE_NAME.mlir" 32 | ;; 33 | *) 34 | echo "Unsupported file extension: .$extension" 35 | exit 1 36 | ;; 37 | esac 38 | 39 | # Common Optimizations 40 | ./build/bin/ep2c-opt "netronome_out/$BASE_NAME.mlir" -ep2-context-infer -canonicalize -ep2-buffer-to-value --ep2-context-to-argument -canonicalize -cse -canonicalize -o netronome_out/commonopt.mlir 41 | 42 | 43 | # Cut-Mapping Optimization 44 | if [ "$disable_cut" != "disable_cut" ]; then 45 | ./build/bin/ep2c-opt -ep2-pipeline-handler="mode=loop target=netronome" \ 46 | "netronome_out/commonopt.mlir" -o "netronome_out/cut.mlir" 47 | else 48 | echo "Warning: cut optimization is disabled, skipping cut optimization" 49 | cp "netronome_out/commonopt.mlir" "netronome_out/cut.mlir" 50 | fi 51 | 52 | # Mapping Optimization 53 | ./build/bin/ep2c-opt -ep2-pipeline-canon="mode=netronome" -cse \ 54 | -ep2-context-to-mem -ep2-global-to-partition \ 55 | "netronome_out/cut.mlir" -o "netronome_out/mapped.mlir" 56 | 57 | # Backend Codegen 58 | ./build/bin/ep2c-opt -ep2-repack -ep2-handler-repl -ep2-collect-header -ep2-lower-emitc -ep2-lower-memcpy -ep2-update-ppg -ep2-lower-noctxswap -ep2-gpr-promote -ep2-emit-netronome="basePath=netronome_out" "netronome_out/mapped.mlir" -o /dev/null 59 | 60 | echo "Generated files in netronome_out" 61 | -------------------------------------------------------------------------------- /example_outputs/outs-netronome/out-netronome-cpu_load/prog_hdr.h: -------------------------------------------------------------------------------- 1 | #ifndef _PROG_HDR_H_ 2 | #define _PROG_HDR_H_ 3 | 4 | #include "nfplib.h" 5 | #include 6 | #include "extern/extern_net_meta.h" 7 | 8 | __packed struct __buf_t { 9 | char* buf; 10 | unsigned offs; 11 | unsigned sz; 12 | }; 13 | 14 | __packed struct coremap_t { 15 | uint16_t f0; 16 | uint16_t f1; 17 | uint16_t f2; 18 | uint16_t f3; 19 | }; 20 | 21 | __packed struct context_chain_1_t { 22 | }; 23 | 24 | __packed struct event_param_NET_RECV { 25 | struct __buf_t f0; 26 | struct recv_meta_t meta; 27 | __shared __cls struct context_chain_1_t* ctx; 28 | }; 29 | 30 | __packed struct event_param_LOAD_TABLE_ADD { 31 | uint16_t f0; 32 | uint16_t f1; 33 | __shared __cls struct context_chain_1_t* ctx; 34 | }; 35 | 36 | #define WORKQ_SIZE_LOAD_TABLE_ADD 128 37 | #define WORKQ_TYPE_LOAD_TABLE_ADD MEM_TYEP_CLS 38 | #define WORKQ_ID_LOAD_TABLE_ADD_1 10 39 | CLS_WORKQ_DECLARE(workq_LOAD_TABLE_ADD_1, WORKQ_SIZE_LOAD_TABLE_ADD); 40 | 41 | __packed struct table_i32_coremap_t_16_t { 42 | struct coremap_t table[16]; 43 | }; 44 | __export __shared __cls struct table_i32_coremap_t_16_t service_load; 45 | 46 | CLS_CONTEXTQ_DECLARE(context_chain_1_t, context_chain_pool, 128); 47 | #ifdef DO_CTXQ_INIT 48 | __export __shared __cls int context_chain_ring_qHead = 0; 49 | #else 50 | __import __shared __cls int context_chain_ring_qHead; 51 | #endif 52 | 53 | __forceinline static __shared __cls struct context_chain_1_t* alloc_context_chain_ring_entry() { 54 | __xrw int context_idx = 1; 55 | cls_test_add(&context_idx, &context_chain_ring_qHead, sizeof(context_idx)); 56 | return &context_chain_pool[context_idx & 127]; 57 | } 58 | 59 | __forceinline static struct __buf_t alloc_packet_buf() { 60 | struct __buf_t buf; 61 | buf.buf = alloc_packet_buffer(); 62 | buf.offs = 0; 63 | buf.sz = 0; 64 | return buf; 65 | } 66 | 67 | __forceinline static int hash(int x) { 68 | return x; 69 | } 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /example_outputs/outs-netronome/out-netronome-example/receive_desc.c: -------------------------------------------------------------------------------- 1 | #include "nfplib.h" 2 | #include "prog_hdr.h" 3 | #include "extern/extern_dma.h" 4 | #include "extern/extern_net.h" 5 | 6 | struct recv_desc_t _loc_buf_0; 7 | __xrw struct recv_desc_t _loc_buf_0_xfer; 8 | __declspec(aligned(4)) struct event_param_DMA_RECV_CMPL work; 9 | __xrw struct event_param_DMA_RECV_CMPL work_ref; 10 | __declspec(aligned(4)) struct event_param_USER_EVENT1 next_work_USER_EVENT1; 11 | __xrw struct event_param_USER_EVENT1 next_work_ref_USER_EVENT1; 12 | 13 | __forceinline 14 | void __event___handler_DMA_RECV_CMPL_receive_desc() { 15 | int32_t v1; 16 | int64_t v2; 17 | __declspec(aligned(4)) struct event_param_DMA_RECV_CMPL* v3; 18 | __xrw struct event_param_DMA_RECV_CMPL* v4; 19 | struct context_chain_1_t* v5; 20 | struct context_chain_1_t* v6; 21 | struct __buf_t v7; 22 | struct recv_desc_t* v8; 23 | __xrw struct recv_desc_t* v9; 24 | __declspec(aligned(4)) struct event_param_USER_EVENT1* v10; 25 | __xrw struct event_param_USER_EVENT1* v11; 26 | v1 = 1; 27 | v2 = 100; 28 | v3 = &work; 29 | v4 = &work_ref; 30 | cls_workq_add_thread(WORKQ_ID_DMA_RECV_CMPL, v4, sizeof(*v4)); 31 | *(v3) = *(v4); 32 | v5 = alloc_context_chain_ring_entry(); 33 | v3->ctx = v5; 34 | v6 = v3->ctx; 35 | v7 = v3->f0; 36 | v8 = &_loc_buf_0; 37 | v9 = &_loc_buf_0_xfer; 38 | mem_read32(&v9->f0, v7.buf + v7.offs, 16); 39 | v7.offs += 16; 40 | *(v8) = *(v9); 41 | v6->f0 = *v8; 42 | v10 = &next_work_USER_EVENT1; 43 | v10->ctx = v6; 44 | v10->f0 = v2; 45 | v11 = &next_work_ref_USER_EVENT1; 46 | *(v11) = *(v10); 47 | cls_workq_add_work(WORKQ_ID_USER_EVENT1, v11, sizeof(*v11)); 48 | return; 49 | } 50 | 51 | 52 | int main(void) { 53 | init_context_chain_ring(); 54 | init_recv_event_workq(WORKQ_ID_DMA_RECV_CMPL, workq_DMA_RECV_CMPL, WORKQ_TYPE_DMA_RECV_CMPL, WORKQ_SIZE_DMA_RECV_CMPL, 8); 55 | for (;;) { 56 | __event___handler_DMA_RECV_CMPL_receive_desc(); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /runtime-llvm/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | #include "runtime.h" 9 | #include "extern.h" 10 | 11 | #include "ep2_defs.inc.h" 12 | 13 | int main() { 14 | // init queues 15 | queues = malloc(sizeof(GAsyncQueue *) * NUM_QUEUES); 16 | for (int i = 0; i < NUM_QUEUES; i++) { 17 | queues[i] = g_async_queue_new(); 18 | } 19 | printf("Queues inited\n"); 20 | 21 | // enable worker threads 22 | // for now, each hander have n hreads. merge later 23 | int num_threads = 0; 24 | pthread_t threads[NUM_INSTANCES]; 25 | for (int i = 0; i < NUM_HANDLERS; i++) { 26 | for (int j = 0; j < handler_replications[i]; j++) { 27 | uintptr_t cur_thread = num_threads++; 28 | pthread_create(&threads[cur_thread], NULL, handler_workers[i], (void *)(cur_thread)); 29 | printf("worker inited %d %d\n", i, j); 30 | } 31 | } 32 | 33 | // enable externs. for now, each extern have 1 thread. merge later 34 | // runtime could do what ever it wants here 35 | for (int i = 0; i < NUM_EXTERNS; i++) { 36 | extern_worker_t *worker = &extern_workers[i]; 37 | if (strcmp(worker->name, "source_NET_RECV") == 0) { 38 | pthread_t thread; 39 | pthread_create(&thread, NULL, (pthread_worker_t)__extern_source_NET_RECV, 40 | (void *)worker); 41 | printf("NET RECV Created, QID[%d]\n", worker->outs[0]); 42 | } else if (strcmp(worker->name, "sink_NET_SEND") == 0) { 43 | pthread_t thread; 44 | pthread_create(&thread, NULL, (pthread_worker_t)__extern_sink_NET_SEND, 45 | (void *)worker); 46 | printf("NET SEND Created, QID[%d]\n", worker->ins[0]); 47 | } else { 48 | assert("unknown extern"); 49 | } 50 | } 51 | 52 | // wait here for all threads to finish 53 | for (int i = 0; i < NUM_INSTANCES; i++) { 54 | pthread_join(threads[i], NULL); 55 | } 56 | assert("should not reach here"); 57 | } -------------------------------------------------------------------------------- /runtime_lib/netronome_runtime/microc/lib/nfp/libnfp.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2017, Netronome Systems, Inc. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | * @file lib/nfp/libnfp.c 17 | * @brief Standard library for NFP 18 | */ 19 | 20 | 21 | #include 22 | #include 23 | 24 | #include 25 | 26 | /* 27 | * The following files implement all the functionality in . 28 | * They may only have dependencies on and the other include 29 | * files in . They are not protected by header guards and 30 | * should not be included elsewhere. 31 | */ 32 | #include "_c/cls.c" 33 | #include "_c/macstats.c" 34 | #include "_c/me.c" 35 | #include "_c/mem_atomic.c" 36 | #include "_c/mem_bulk.c" 37 | #include "_c/mem_cam.c" 38 | #include "_c/mem_lkup.c" 39 | #include "_c/mem_pe.c" 40 | #include "_c/mem_ring.c" 41 | #include "_c/pcie.c" 42 | #include "_c/remote_me.c" 43 | #include "_c/tmq.c" 44 | #include "_c/xpb.c" 45 | #include "_c/tm_config.c" 46 | #include "_c/mac_csr_synch.c" 47 | #include "_c/ctm.c" 48 | 49 | /* 50 | * The following code implements all the functionality in . It 51 | * should not have any external dependencies (including dependencies 52 | * on include files). 53 | */ 54 | __intrinsic void 55 | ___rt_assert(void *addr) 56 | { 57 | local_csr_write(local_csr_mailbox_1, (unsigned int) addr); 58 | local_csr_write(local_csr_mailbox_0, 0); 59 | __asm ctx_arb[bpt]; 60 | } 61 | -------------------------------------------------------------------------------- /tests/output/l2_echo.opt.mlir: -------------------------------------------------------------------------------- 1 | // ep2c-opt l2_echo.mlir --canonicalize -o l2_echo.opt.mlir 2 | 3 | module { 4 | ep2.func private @__handler_NET_SEND(%arg0: !ep2.context, %arg1: !ep2.buf) attributes {event = "NET_SEND", type = "handler"} { 5 | ep2.return 6 | } 7 | ep2.func private @__handler_NET_RECV_process_packet(%arg0: !ep2.context, %arg1: !ep2.buf) -> !ep2.struct<"NET_SEND" : isEvent = true, elementTypes = !ep2.context, !ep2.buf> attributes {atom = "process_packet", event = "NET_RECV", type = "handler"} { 8 | %0 = "ep2.init"() : () -> !ep2.buf 9 | %1 = "ep2.extract"(%arg1) : (!ep2.buf) -> !ep2.struct<"eth_header_t" : isEvent = false, elementTypes = i48, i48, i16> 10 | %2 = "ep2.extract"(%arg1) : (!ep2.buf) -> !ep2.struct<"ip_header_t" : isEvent = false, elementTypes = i8, i16, i16, i16, i16, i16, i32, i32, i32> 11 | %3 = ep2.struct_access %1[1] : <"eth_header_t" : isEvent = false, elementTypes = i48, i48, i16> -> i48 12 | %4 = ep2.struct_access %1[0] : <"eth_header_t" : isEvent = false, elementTypes = i48, i48, i16> -> i48 13 | %5 = "ep2.struct_update"(%1, %4) <{index = 1 : i64}> : (!ep2.struct<"eth_header_t" : isEvent = false, elementTypes = i48, i48, i16>, i48) -> !ep2.struct<"eth_header_t" : isEvent = false, elementTypes = i48, i48, i16> 14 | %6 = "ep2.struct_update"(%5, %3) <{index = 0 : i64}> : (!ep2.struct<"eth_header_t" : isEvent = false, elementTypes = i48, i48, i16>, i48) -> !ep2.struct<"eth_header_t" : isEvent = false, elementTypes = i48, i48, i16> 15 | "ep2.emit"(%0, %6) : (!ep2.buf, !ep2.struct<"eth_header_t" : isEvent = false, elementTypes = i48, i48, i16>) -> () 16 | "ep2.emit"(%0, %2) : (!ep2.buf, !ep2.struct<"ip_header_t" : isEvent = false, elementTypes = i8, i16, i16, i16, i16, i16, i32, i32, i32>) -> () 17 | "ep2.emit"(%0, %arg1) : (!ep2.buf, !ep2.buf) -> () 18 | %7 = "ep2.init"(%arg0, %0) : (!ep2.context, !ep2.buf) -> !ep2.struct<"NET_SEND" : isEvent = true, elementTypes = !ep2.context, !ep2.buf> 19 | ep2.return %7 : !ep2.struct<"NET_SEND" : isEvent = true, elementTypes = !ep2.context, !ep2.buf> 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /runtime_lib/netronome_runtime/include/connect.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: BSD 3-Clause License */ 2 | /* Copyright (c) 2022, University of Washington, Max Planck Institute for Software Systems, and The University of Texas at Austin */ 3 | 4 | #ifndef _FLEXTOE_CONNECT_H_ 5 | #define _FLEXTOE_CONNECT_H_ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include "common.h" 12 | 13 | /** Info struct: layout of info shared memory region */ 14 | PACKED_STRUCT(flexnic_info_t) 15 | { 16 | uint64_t flags; /*> Flags: see FLEXNIC_FLAG_* */ 17 | uint64_t dma_mem_size; /*> Size of flexnic dma memory in bytes. */ 18 | uint64_t internal_mem_size; /*> Size of internal flexnic memory in bytes. */ 19 | uint64_t mac_address; /*> export mac address */ 20 | uint64_t poll_cycle_app; /*> Cycles to poll before blocking for application */ 21 | uint32_t cores_num; /*> Number of cores in flexnic emulator */ 22 | char bar_resource_path[PATH_MAX]; /*> MMIO resource path */ 23 | off_t internal_mem_offset; /*> Internal memory offset in bar resource */ 24 | }; 25 | 26 | #define FLEXNIC_FLAG_READY (1 << 0) /*> Flexnic is done initializing */ 27 | #define FLEXNIC_FLAG_HUGEPAGES (1 << 1) /*> Huge pages should be used for the internal and dma memory */ 28 | 29 | /** Connect parameters */ 30 | #define FLEXNIC_SHM_PREFIX "/dev/shm" /*> Shared memory mount point */ 31 | #define FLEXNIC_HUGE_PREFIX "/dev/hugepages-1048576kB" /*> Hugepages mount point */ 32 | #define FLEXNIC_NAME_INFO "flextoe_info" /*> Name for the info shared memory region */ 33 | #define FLEXNIC_NAME_DMA_MEM "flextoe_memory" /*> Name for flexnic dma shared memory region */ 34 | #define FLEXNIC_INFO_BYTES 0x4000 /*> Size of the info shared memory region */ 35 | 36 | /** Unix socket for initialization with application */ 37 | #define FLEXNIC_SOCKET_PATH "\0flexnic_os" 38 | #define FLEXNIC_UXSOCK_MAXQ 8 39 | 40 | #endif /* _FLEXTOE_CONNECT_H_ */ 41 | -------------------------------------------------------------------------------- /runtime_lib/netronome_runtime/microc/blocks/gro/scripts/grodump.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 4 | # Copyright (C) 2018, Netronome Systems, Inc. All rights reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # @file me/blocks/gro/scripts/grodump.sh 19 | # 20 | 21 | NETRONOME_DIR=${NETRONOME_DIR:-/opt/netronome} 22 | NETRONOME_BIN=${NETRONOME_BIN:-${NETRONOME_DIR}/bin} 23 | 24 | [ $# -lt 1 -o "$1" = "-h" ] && echo usage $0 GRO_CTX >&2 && exit 1 25 | 26 | BLKS=`$NETRONOME_BIN/nfp-rtsym _gro_global_config | awk '{print $2}'` 27 | BLKS=$(printf "%d" $BLKS) 28 | CPB=`$NETRONOME_BIN/nfp-rtsym _gro_global_config | awk '{print $3}'` 29 | CPB=$(printf "%d" $CPB) 30 | 31 | echo GRO has $BLKS blocks and $CPB contexts per block 32 | 33 | B=$(($1 / $CPB)) 34 | C=$(($1 % $CPB)) 35 | 36 | echo Context $1 is GRO context $B.$C 37 | 38 | CBASE=$(($1 * 16)) 39 | 40 | EHI=$($NETRONOME_BIN/nfp-rtsym -l 4 _gro_cli_cntrs:$(($CBASE + 4)) | awk '{print $2}') 41 | ELO=$($NETRONOME_BIN/nfp-rtsym -l 4 _gro_cli_cntrs:$(($CBASE + 0)) | awk '{print $2}') 42 | ENQ=$(($EHI << 32 | $ELO)) 43 | 44 | 45 | RHI=$($NETRONOME_BIN/nfp-rtsym -l 4 _gro_cli_cntrs:$(($CBASE + 12)) | awk '{print $2}') 46 | RLO=$($NETRONOME_BIN/nfp-rtsym -l 4 _gro_cli_cntrs:$(($CBASE + 8)) | awk '{print $2}') 47 | REL=$(($RHI << 32 | $RLO)) 48 | 49 | echo MEs have enqueued $ENQ packets and released $REL packets on context $1 50 | 51 | echo Bitmap for context $1: 52 | $NETRONOME_BIN/nfp-rtsym _gro_bm_${B}_${C} 53 | 54 | echo Queue for context $1: 55 | $NETRONOME_BIN/nfp-rtsym _gro_q_${B}_${C} 56 | -------------------------------------------------------------------------------- /runtime_lib/netronome_runtime/microc/blocks/init/_uc/init_nbi_pc_csr.uc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-2015, Netronome Systems, Inc. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | * @file: init_nbi_pc_csr.uc 17 | * @brief: Contains macros to initialise the NBI Packet Pre-Classifier 18 | */ 19 | 20 | #ifndef _INIT_NBI_PC_CSR_UC_ 21 | #define _INIT_NBI_PC_CSR_UC_ 22 | 23 | /** Nbi_PktPreclassifier_Characterization_PortCfg 24 | * 25 | * NBI Pre-Classifier Port configuration. See the NFP-6xxx Databook section on 26 | * the NBI Packet Pre classifier 27 | * 28 | * @param NBI_ID The NBI number, can be 0 or 1 29 | * @param PORT The port number 30 | * @param VALUE Method of interpreting the SRAM data read, to 31 | * produce a result for the lookup 32 | */ 33 | #macro Nbi_PktPreclassifier_Characterization_PortCfg(NBI_ID,PORT,VALUE) 34 | .init_csr xpb:Nbi/**/NBI_ID/**/IsldXpbMap.NbiTopXpbMap.PktPreclassifier.Characterization.PortCfg/**/PORT VALUE const 35 | #endm 36 | 37 | 38 | /** Nbi_PktPreclassifier_Characterization_PortCfg 39 | * 40 | * NBI Pre-Classifier Work-around values for the following bugs: 41 | * NFPBSP-1226 42 | * NFPBSP-1179 43 | * 44 | * @param NBI_ID The NBI number, can be 0 or 1 45 | */ 46 | #macro Nbi_PktPreclassifier_NFPBSP_1179(NBI_ID) 47 | #if (NBI_ID == 0) 48 | .init_csr xpbm:0x0048290000 0x32ff0000 32 const 49 | #else 50 | .init_csr xpbm:0x0049290000 0x32ff0000 32 const 51 | #endif 52 | #endm 53 | 54 | #endif /* _INIT_NBI_PC_CSR_UC_ */ 55 | -------------------------------------------------------------------------------- /example_outputs/outs-netronome/out-netronome-l2_echo/prog_hdr.h: -------------------------------------------------------------------------------- 1 | #ifndef _PROG_HDR_H_ 2 | #define _PROG_HDR_H_ 3 | 4 | #include "nfplib.h" 5 | #include 6 | #include "extern/extern_net_meta.h" 7 | 8 | typedef __packed struct __int48 { 9 | int8_t storage[6]; 10 | } int48_t; 11 | 12 | __packed struct __wrapper_arg_t { 13 | int32_t f0; 14 | char* f1; 15 | }; 16 | 17 | __packed struct __buf_t { 18 | char* buf; 19 | unsigned offs; 20 | }; 21 | 22 | __packed struct eth_header_t { 23 | int48_t f0; 24 | int48_t f1; 25 | int16_t f2; 26 | int8_t pad0[2]; 27 | }; 28 | 29 | __packed struct context_chain_1_t { 30 | int32_t ctx_id; 31 | }; 32 | 33 | __packed struct event_param_NET_RECV { 34 | struct __buf_t f0; 35 | struct recv_meta_t meta; 36 | struct context_chain_1_t* ctx; 37 | }; 38 | 39 | __packed struct event_param_NET_SEND { 40 | struct __buf_t f0; 41 | struct send_meta_t meta; 42 | struct context_chain_1_t* ctx; 43 | }; 44 | 45 | EMEM_CONTEXTQ_DECLARE(context_chain_1_t, context_chain_pool, 2048); 46 | MEM_RING_INIT(context_chain_ring, 2048); 47 | 48 | __forceinline static void init_context_chain_ring() { 49 | unsigned int idx, rnum, raddr_hi, init_range; 50 | init_range = IF_SIMULATION ? 10 : 2048; 51 | if (ctx() == 0) { 52 | rnum = MEM_RING_GET_NUM(context_chain_ring); 53 | raddr_hi = MEM_RING_GET_MEMADDR(context_chain_ring); 54 | for (idx=1; idxctx = v3; 34 | v4 = v2->ctx; 35 | v5 = v2->f0; 36 | v6 = alloc_packet_buf(); 37 | v7 = &_loc_buf_0; 38 | v8 = &_loc_buf_0_xfer; 39 | mem_read32(&v8->f0, v5.buf + v5.offs, 12); 40 | v5.offs += 12; 41 | mem_read8(&v8->f2, v5.buf + v5.offs, 2); 42 | v5.offs += 2; 43 | *(v7) = *(v8); 44 | v9 = v7->f1; 45 | v10 = v7->f0; 46 | v7->f1 = v10; 47 | v7->f0 = v9; 48 | v13 = &_loc_buf_0_xfer; 49 | *(v13) = *(v7); 50 | mem_write32(&v13->f0, v6.buf + v6.offs, 12); 51 | v6.offs += 12; 52 | mem_write8(&v13->f2, v6.buf + v6.offs, 2); 53 | v6.offs += 2; 54 | bulk_memcpy(v6.buf + v6.offs, v5.buf + v5.offs, work.meta.len - v5.offs); 55 | v6.offs += work.meta.len - v5.offs; 56 | v14 = &next_work_NET_SEND; 57 | v14->ctx = v4; 58 | v14->f0 = v6; 59 | next_work_NET_SEND.meta.len = next_work_NET_SEND.f0.offs; 60 | inlined_net_send(v14); 61 | return; 62 | } 63 | 64 | 65 | int main(void) { 66 | init_context_chain_ring(); 67 | for (;;) { 68 | __event___handler_NET_RECV_main_recv(); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /example_outputs/outs-netronome/out-netronome-example/prog_hdr.h: -------------------------------------------------------------------------------- 1 | #ifndef _PROG_HDR_H_ 2 | #define _PROG_HDR_H_ 3 | 4 | #include "nfplib.h" 5 | #include 6 | #include "extern/extern_net_meta.h" 7 | 8 | __packed struct __wrapper_arg_t { 9 | int32_t f0; 10 | char* f1; 11 | }; 12 | 13 | __packed struct __buf_t { 14 | char* buf; 15 | unsigned offs; 16 | }; 17 | 18 | __packed struct recv_desc_t { 19 | int32_t f0; 20 | int32_t f1; 21 | int32_t f2; 22 | int32_t f3; 23 | }; 24 | 25 | __packed struct context_chain_1_t { 26 | struct recv_desc_t f0; 27 | int32_t f1; 28 | int32_t ctx_id; 29 | }; 30 | 31 | __packed struct event_param_DMA_RECV_CMPL { 32 | struct __buf_t f0; 33 | struct context_chain_1_t* ctx; 34 | }; 35 | 36 | __packed struct event_param_USER_EVENT1 { 37 | int32_t f0; 38 | struct context_chain_1_t* ctx; 39 | }; 40 | 41 | #define WORKQ_SIZE_USER_EVENT1 256 42 | #define WORKQ_ID_USER_EVENT1 10 43 | #define WORKQ_TYPE_USER_EVENT1 MEM_TYEP_CLS 44 | CLS_WORKQ_DECLARE(workq_USER_EVENT1, WORKQ_SIZE_USER_EVENT1); 45 | 46 | EMEM_CONTEXTQ_DECLARE(context_chain_1_t, context_chain_pool, 2048); 47 | MEM_RING_INIT(context_chain_ring, 2048); 48 | 49 | __forceinline static void init_context_chain_ring() { 50 | unsigned int idx, rnum, raddr_hi, init_range; 51 | init_range = IF_SIMULATION ? 10 : 2048; 52 | if (ctx() == 0) { 53 | rnum = MEM_RING_GET_NUM(context_chain_ring); 54 | raddr_hi = MEM_RING_GET_MEMADDR(context_chain_ring); 55 | for (idx=1; idx 24 | #include 25 | 26 | /** 27 | * Reads, and optionally clears, a single queue drop counter. 28 | * @param nbi NBI to read from (0/1) 29 | * @param counter Read value (if no error) 30 | * @param qnum Queue number (0-1023) 31 | * @param clear Clear on read flag 32 | * @return 0 on success, -1 on error 33 | */ 34 | __intrinsic int tmq_cnt_read(uint32_t nbi, __gpr uint32_t *counter, 35 | uint32_t qnum, int clear); 36 | 37 | /** 38 | * Reads the status of one or a series of TM queues. 39 | * @param status Pointer to local read transfer register for the status 40 | * @param nbi NBI to read from (0/1) 41 | * @param qnum Queue number (0-1023) 42 | * @param num_qs Number of consecutive queues to read (up to 16) 43 | * @param sync Type of synchronization (sig_done or ctx_swap) 44 | * @param sig Signal to use 45 | * @return 0 on success, -1 on error 46 | */ 47 | __intrinsic void __tmq_status_read(__xread void *status, uint32_t nbi, 48 | uint32_t qnum, unsigned int num_qs, 49 | sync_t sync, SIGNAL *sig); 50 | 51 | __intrinsic void tmq_status_read(__xread void *status, uint32_t nbi, 52 | uint32_t qnum, unsigned int num_qs); 53 | 54 | #endif /* !_NFP__TMQ_H_ */ 55 | -------------------------------------------------------------------------------- /lib/ep2/ControllerAnalysis.cpp.bk: -------------------------------------------------------------------------------- 1 | 2 | // #include "ep2/dialect/Dialect.h" 3 | // #include "ep2/dialect/Passes.h" 4 | // #include "mlir/IR/BuiltinDialect.h" 5 | 6 | // #include "mlir/IR/BuiltinOps.h" 7 | // #include "mlir/IR/Visitors.h" 8 | // #include "mlir/Pass/Pass.h" 9 | // #include "llvm/ADT/StringMap.h" 10 | 11 | // using namespace mlir; 12 | 13 | // namespace mlir { 14 | // namespace ep2 { 15 | 16 | // FuncOp ControllerAnalysis::findTargetHanlder(FuncOp funcOp) { 17 | 18 | // FuncOp targetfunc = nullptr; 19 | // for (auto &block : funcOp.getBody().getBlocks()) { 20 | // std::string targetEvent = 21 | // funcOp->getAttr("event").cast().getValue().str(); 22 | // auto &dependency = getAnalysis(); 23 | // funcOp->walk([&](ConstantOp constantOp) { 24 | // if (auto portType = constantOp.getType().dyn_cast()) { 25 | // auto value = constantOp.getResult(); 26 | // auto portAttr = constantOp.getValue().cast(); 27 | // HandlerDependencyAnalysis::HandlerFullName fullname{ 28 | // portAttr.getHandler().str(), portAttr.getAtom().str()}; 29 | 30 | // FuncOp funcOp = dependency.handlersMap[fullname]; 31 | 32 | // int instance = portAttr.getInstance(); 33 | 34 | // if (!portType.getIn() && portType.getOut()) { 35 | // if (!targetfunc) 36 | // targetfunc = funcOp; 37 | // else if (targetfunc != funcOp) { 38 | // printf("Error: multiple target func for %s\n", targetEvent.c_str()); 39 | // assert(false); 40 | // } 41 | // } 42 | // } 43 | // }); 44 | // } 45 | // return targetfunc; 46 | // } 47 | 48 | // ControllerAnalysis::ControllerAnalysis(Operation *module) { 49 | // // walk through and find all function targets. 50 | // module->walk([&](FuncOp funcOp) { 51 | // if (funcOp->getAttr("type").cast().getValue() == "controller") { 52 | // auto targetfunc = findTargetHanlder(funcOp); 53 | // ctrl_func_to_target_handler[funcOp] = targetfunc; 54 | // target_handler_to_ctrl_func[targetfunc] = funcOp; 55 | // } 56 | // }); 57 | // } 58 | // } // namespace ep2 59 | // } // namespace mlir 60 | -------------------------------------------------------------------------------- /example_outputs/outs-netronome/out-netronome-l2_echo/l2_echo.mlir: -------------------------------------------------------------------------------- 1 | module { 2 | ep2.func private @__handler_NET_SEND_main_send(%arg0: !ep2.context, %arg1: !ep2.buf) attributes {atom = "main_send", event = "NET_SEND", extern = true, type = "handler"} { 3 | "ep2.terminate"() : () -> () 4 | } 5 | ep2.func private @__handler_NET_RECV_main_recv(%arg0: !ep2.context, %arg1: !ep2.buf) attributes {atom = "main_recv", event = "NET_RECV", type = "handler"} { 6 | %0 = "ep2.init"() : () -> !ep2.struct<"eth_header_t" : isEvent = false, elementTypes = i48, i48, i16> 7 | %1 = "ep2.init"() : () -> i48 8 | %2 = "ep2.init"() : () -> !ep2.buf 9 | %3 = "ep2.extract"(%arg1) : (!ep2.buf) -> !ep2.struct<"eth_header_t" : isEvent = false, elementTypes = i48, i48, i16> 10 | %4 = ep2.struct_access %3[1] : <"eth_header_t" : isEvent = false, elementTypes = i48, i48, i16> -> i48 11 | %5 = ep2.struct_access %3[1] : <"eth_header_t" : isEvent = false, elementTypes = i48, i48, i16> -> i48 12 | %6 = ep2.struct_access %3[0] : <"eth_header_t" : isEvent = false, elementTypes = i48, i48, i16> -> i48 13 | %7 = "ep2.struct_update"(%3, %6) <{index = 1 : i64}> : (!ep2.struct<"eth_header_t" : isEvent = false, elementTypes = i48, i48, i16>, i48) -> !ep2.struct<"eth_header_t" : isEvent = false, elementTypes = i48, i48, i16> 14 | %8 = ep2.struct_access %7[0] : <"eth_header_t" : isEvent = false, elementTypes = i48, i48, i16> -> i48 15 | %9 = "ep2.struct_update"(%7, %4) <{index = 0 : i64}> : (!ep2.struct<"eth_header_t" : isEvent = false, elementTypes = i48, i48, i16>, i48) -> !ep2.struct<"eth_header_t" : isEvent = false, elementTypes = i48, i48, i16> 16 | "ep2.emit"(%2, %9) : (!ep2.buf, !ep2.struct<"eth_header_t" : isEvent = false, elementTypes = i48, i48, i16>) -> () 17 | %10 = "ep2.nop"() : () -> none 18 | "ep2.emit"(%2, %arg1) : (!ep2.buf, !ep2.buf) -> () 19 | %11 = "ep2.nop"() : () -> none 20 | %12 = "ep2.constant"() <{value = "main_send"}> : () -> !ep2.atom 21 | %13 = "ep2.init"(%12, %arg0, %2) : (!ep2.atom, !ep2.context, !ep2.buf) -> !ep2.struct<"NET_SEND" : isEvent = true, elementTypes = !ep2.context, !ep2.buf> 22 | ep2.return %13 : !ep2.struct<"NET_SEND" : isEvent = true, elementTypes = !ep2.context, !ep2.buf> 23 | "ep2.terminate"() : () -> () 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /example_outputs/outs-netronome/out-netronome-example/canon.mlir: -------------------------------------------------------------------------------- 1 | module { 2 | ep2.func private @__controller_DMA_RECV_CMPL() attributes {event = "DMA_RECV_CMPL", extern = true, type = "controller"} { 3 | %0 = "ep2.constant"() <{value = 256 : i64}> : () -> i64 4 | %1 = "ep2.constant"() <{value = 1 : i64}> : () -> i64 5 | %2 = ep2.call @Queue(%0, %1, %1) : (i64, i64, i64) -> i64 6 | "ep2.terminate"() : () -> () 7 | } 8 | ep2.func private @__controller_USER_EVENT1() attributes {event = "USER_EVENT1", type = "controller"} { 9 | %0 = "ep2.constant"() <{value = 256 : i64}> : () -> i64 10 | %1 = "ep2.constant"() <{value = 1 : i64}> : () -> i64 11 | %2 = ep2.call @Queue(%0, %1, %1) : (i64, i64, i64) -> i64 12 | "ep2.terminate"() : () -> () 13 | } 14 | ep2.func private @__handler_DMA_RECV_CMPL_receive_desc(%arg0: !ep2.context, %arg1: !ep2.buf) attributes {atom = "receive_desc", event = "DMA_RECV_CMPL", type = "handler"} { 15 | %0 = "ep2.constant"() <{value = 100 : i64}> : () -> i64 16 | %1 = "ep2.constant"() <{value = "process_desc"}> : () -> !ep2.atom 17 | %2 = "ep2.extract"(%arg1) : (!ep2.buf) -> !ep2.struct<"recv_desc_t" : isEvent = false, elementTypes = i32, i32, i32, i32> 18 | %3 = "ep2.context_ref"(%arg0) <{name = "desc"}> : (!ep2.context) -> !ep2.conref> 19 | "ep2.store"(%3, %2) : (!ep2.conref>, !ep2.struct<"recv_desc_t" : isEvent = false, elementTypes = i32, i32, i32, i32>) -> () 20 | %4 = "ep2.init"(%1, %arg0, %0) : (!ep2.atom, !ep2.context, i64) -> !ep2.struct<"USER_EVENT1" : isEvent = true, elementTypes = !ep2.atom, !ep2.context, i32> 21 | ep2.return %4 : !ep2.struct<"USER_EVENT1" : isEvent = true, elementTypes = !ep2.atom, !ep2.context, i32> 22 | "ep2.terminate"() : () -> () 23 | } 24 | ep2.func private @__handler_USER_EVENT1_process_desc(%arg0: !ep2.context, %arg1: i32) attributes {atom = "process_desc", event = "USER_EVENT1", type = "handler"} { 25 | %0 = "ep2.context_ref"(%arg0) <{name = "flow_grp"}> : (!ep2.context) -> !ep2.conref 26 | "ep2.store"(%0, %arg1) : (!ep2.conref, i32) -> () 27 | "ep2.terminate"() : () -> () 28 | } 29 | } 30 | 31 | -------------------------------------------------------------------------------- /runtime-llvm/externs.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include "runtime.h" 5 | #include "glib.h" 6 | #include "extern.h" 7 | #include "stdint.h" 8 | 9 | // built in source/sink/handlers 10 | void * __extern_source_NET_RECV(extern_worker_t *worker) { 11 | int tag = worker->outs[0]; 12 | while (1) { 13 | struct event_NET_RECV *event = malloc(sizeof(struct event_NET_RECV)); 14 | __rt_buf_init(&(event->buf)); 15 | // TODO: fill in some source 16 | // dprintf("[sink %d]: event %p, with buf %p\n", tag, event, event->buf.data); 17 | g_async_queue_push(queues[tag], (void *)event); 18 | } 19 | pthread_exit(NULL); 20 | } 21 | 22 | void * __extern_sink_NET_SEND(extern_worker_t *worker) { 23 | int tag = worker->ins[0]; 24 | static int counter = 0; 25 | while (1) { 26 | struct event_NET_SEND * event = (struct event_NET_SEND *)g_async_queue_pop(queues[tag]); 27 | __rt_buf_free(&(event->buf)); 28 | free(event); 29 | // dprintf("[sink %d]: packet %d, with buf %p\n", tag, counter ++, event->buf.data); 30 | } 31 | pthread_exit(NULL); 32 | } 33 | 34 | // empty implementation 35 | void __handler_DMA_WRITE_REQ_dma_write(void * buf, void *dma) { 36 | 37 | } 38 | void __wrapper____handler_DMA_WRITE_REQ_dma_write(void * buf, void *dma) { 39 | 40 | } 41 | 42 | void __handler_DMA_SEND_dma_send(void * buf, void *dma) { 43 | 44 | } 45 | 46 | void __wrapper____handler_NET_SEND_net_send(void *buf) { 47 | __handler_NET_SEND_net_send(buf); 48 | } 49 | void __handler_NET_SEND_net_send(void *buf) { 50 | buf_t * buf1 = (buf_t *)buf; 51 | printf("* A PACKET SEND: %p: [%p,%d,%d] \n", buf, buf1->data, buf1->size, buf1->offset); 52 | for (int i = 0 ; i < 60; i++) { 53 | printf("%02x ", (uint8_t)(buf1->data)[i]); 54 | } 55 | printf("\n"); 56 | } 57 | 58 | void __handler_DECRYPT_CMPL_decrypt(void *, void *, void *, void *); 59 | void __handler_DECRYPT_REQ_decrypt(void *buf, void *key, void *ip, void *eth, void *dsp) { 60 | buf_t * buf1 = (buf_t *)buf; 61 | printf("* A PACKET DECRYPT: %p: [%p,%d,%d] \n", buf, buf1->data, buf1->size, buf1->offset); 62 | for (int i = 0 ; i < 60; i++) { 63 | printf("%02x ", (uint8_t)(buf1->data)[i]); 64 | } 65 | printf("\n"); 66 | // __handler_DECRYPT_CMPL_decrypt(buf, ip, eth, dsp); 67 | } 68 | 69 | -------------------------------------------------------------------------------- /runtime_lib/fpga_runtime/rtl_lib/verilog-cam/tb/test_priority_encoder.v: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright (c) 2014-2016 Alex Forencich 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | */ 24 | 25 | // Language: Verilog 2001 26 | 27 | `timescale 1ns / 1ps 28 | 29 | /* 30 | * Testbench for priority_encoder 31 | */ 32 | module test_priority_encoder; 33 | 34 | // Parameters 35 | localparam WIDTH = 32; 36 | 37 | // Inputs 38 | reg clk = 0; 39 | reg rst = 0; 40 | reg [7:0] current_test = 0; 41 | 42 | reg [WIDTH-1:0] input_unencoded = 0; 43 | 44 | // Outputs 45 | wire output_valid; 46 | wire [$clog2(WIDTH)-1:0] output_encoded; 47 | wire [WIDTH-1:0] output_unencoded; 48 | 49 | initial begin 50 | // myhdl integration 51 | $from_myhdl( 52 | clk, 53 | rst, 54 | current_test, 55 | input_unencoded 56 | ); 57 | $to_myhdl( 58 | output_valid, 59 | output_encoded, 60 | output_unencoded 61 | ); 62 | 63 | // dump file 64 | $dumpfile("test_priority_encoder.lxt"); 65 | $dumpvars(0, test_priority_encoder); 66 | end 67 | 68 | priority_encoder #( 69 | .WIDTH(WIDTH) 70 | ) 71 | UUT ( 72 | .input_unencoded(input_unencoded), 73 | .output_valid(output_valid), 74 | .output_encoded(output_encoded), 75 | .output_unencoded(output_unencoded) 76 | ); 77 | 78 | endmodule 79 | -------------------------------------------------------------------------------- /runtime_lib/netronome_runtime/microc/lib/nfp/mac_csr_synch.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017, Netronome Systems, Inc. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | * @file lib/nfp/mac_csr_synch.h 17 | * @brief Prototypes for MAC ethernet config arbiter command. The 18 | * EthCmdConfig arbiter controls access to the EthCmdConfig MAC 19 | * register for every port. 20 | * During a soft reset the EthCmdConfig arbiter is disabled. The 21 | * application should restart the arbiter when required. 22 | * The application should take care to only write to EthCmdConfig 23 | * arbiter when a value has changed as not to overflow the ring. 24 | */ 25 | 26 | #ifndef _NFP__MAC_CSR_SYNCH_H_ 27 | #define _NFP__MAC_CSR_SYNCH_H_ 28 | 29 | 30 | /** 31 | * Set the MacEthCmdCfg register in a controlled manner by use of the 32 | * arbiter ring. 33 | * 34 | * @param nbi The nbi to configure (0/1) 35 | * @param core The MAC core to configure (0/1) 36 | * @param port The MAC port to configure (0..63) 37 | * @param cmd The ARB_CODE_ETH_CMD_CFG_x command to configure 38 | * (see nfp_mac_csr_synch.h) 39 | * @param sync Type of synchronization (sig_done or ctx_swap) 40 | * @param sig Signal to use 41 | * 42 | */ 43 | __intrinsic void __mac_eth_cmd_config(unsigned int nbi, unsigned int core, 44 | unsigned int port, 45 | unsigned int cmd, 46 | sync_t sync, SIGNAL *sig); 47 | 48 | __intrinsic void mac_eth_cmd_config(unsigned int nbi, unsigned int core, 49 | unsigned int port, 50 | unsigned int cmd); 51 | 52 | #endif /* _NFP__MAC_CSR_SYNCH_H_ */ 53 | -------------------------------------------------------------------------------- /lib/ep2/Passes/GlobalToPartitionPass.cpp: -------------------------------------------------------------------------------- 1 | #include "mlir/IR/BuiltinDialect.h" 2 | 3 | #include "ep2/dialect/Dialect.h" 4 | #include "ep2/dialect/Passes.h" 5 | #include "mlir/Dialect/LLVMIR/LLVMDialect.h" 6 | #include "mlir/Dialect/MemRef/IR/MemRef.h" 7 | 8 | #include "mlir/IR/BuiltinOps.h" 9 | #include "mlir/Pass/Pass.h" 10 | #include "mlir/Transforms/DialectConversion.h" 11 | #include "mlir/Transforms/GreedyPatternRewriteDriver.h" 12 | 13 | #include "mlir/Conversion/Passes.h" 14 | #include "mlir/Transforms/Passes.h" 15 | 16 | namespace mlir { 17 | namespace ep2 { 18 | 19 | namespace { 20 | 21 | GlobalOp findGlobalOf(ModuleOp module, StringRef name) { 22 | for (auto global : module.getOps()) { 23 | if (global.getName() == name) 24 | return global; 25 | } 26 | return nullptr; 27 | } 28 | 29 | class GlobalImportPattern : public OpRewritePattern { 30 | using OpRewritePattern::OpRewritePattern; 31 | LogicalResult matchAndRewrite(GlobalImportOp refOp, 32 | PatternRewriter &rewriter) const final { 33 | auto globalName = refOp.getName(); 34 | auto globalAttrName = "instances_" + globalName.str(); 35 | 36 | if (!refOp->getParentOfType()->hasAttr(globalAttrName)) 37 | return rewriter.notifyMatchFailure(refOp, "the global variable is not partitioned"); 38 | 39 | auto global = findGlobalOf(refOp->getParentOfType(), globalName); 40 | assert(global != nullptr); 41 | 42 | rewriter.replaceOpWithNewOp(refOp, global.getType()); 43 | } 44 | }; 45 | } // rewrite pattern 46 | 47 | void GlobalToPartitionPass::runOnOperation() { 48 | auto moduleOp = getOperation(); 49 | 50 | RewritePatternSet patterns(&getContext()); 51 | patterns.add(&getContext()); 52 | FrozenRewritePatternSet frozenPatterns(std::move(patterns)); 53 | 54 | if (failed(applyPatternsAndFoldGreedily(moduleOp, frozenPatterns))) 55 | return signalPassFailure(); 56 | 57 | // remove global op if possible if necessary 58 | for (auto global : moduleOp.getOps()) { 59 | bool hasUse = false; 60 | moduleOp->walk([&](GlobalImportOp refOp) { 61 | if (refOp.getName() == global.getName()) 62 | hasUse = true; 63 | }); 64 | 65 | if (!hasUse) 66 | global.erase(); 67 | } 68 | } 69 | 70 | } // namespace ep2 71 | } // namespace mlir -------------------------------------------------------------------------------- /example_outputs/outs-netronome/out-netronome-example/example.mlir: -------------------------------------------------------------------------------- 1 | module { 2 | ep2.func private @__controller_DMA_RECV_CMPL() attributes {event = "DMA_RECV_CMPL", extern = true, type = "controller"} { 3 | %0 = "ep2.constant"() <{value = 256 : i64}> : () -> i64 4 | %1 = "ep2.constant"() <{value = 1 : i64}> : () -> i64 5 | %2 = "ep2.constant"() <{value = 1 : i64}> : () -> i64 6 | %3 = ep2.call @Queue(%0, %1, %2) : (i64, i64, i64) -> i64 7 | "ep2.terminate"() : () -> () 8 | } 9 | ep2.func private @__controller_USER_EVENT1() attributes {event = "USER_EVENT1", type = "controller"} { 10 | %0 = "ep2.constant"() <{value = 256 : i64}> : () -> i64 11 | %1 = "ep2.constant"() <{value = 1 : i64}> : () -> i64 12 | %2 = "ep2.constant"() <{value = 1 : i64}> : () -> i64 13 | %3 = ep2.call @Queue(%0, %1, %2) : (i64, i64, i64) -> i64 14 | "ep2.terminate"() : () -> () 15 | } 16 | ep2.func private @__handler_DMA_RECV_CMPL_receive_desc(%arg0: !ep2.context, %arg1: !ep2.buf) attributes {atom = "receive_desc", event = "DMA_RECV_CMPL", type = "handler"} { 17 | %0 = "ep2.init"() : () -> !ep2.struct<"recv_desc_t" : isEvent = false, elementTypes = i32, i32, i32, i32> 18 | %1 = "ep2.extract"(%arg1) : (!ep2.buf) -> !ep2.struct<"recv_desc_t" : isEvent = false, elementTypes = i32, i32, i32, i32> 19 | %2 = "ep2.context_ref"(%arg0) <{name = "desc"}> : (!ep2.context) -> !ep2.conref 20 | "ep2.store"(%2, %1) : (!ep2.conref, !ep2.struct<"recv_desc_t" : isEvent = false, elementTypes = i32, i32, i32, i32>) -> () 21 | %3 = "ep2.nop"() : () -> none 22 | %4 = "ep2.constant"() <{value = "process_desc"}> : () -> !ep2.atom 23 | %5 = "ep2.constant"() <{value = 100 : i64}> : () -> i64 24 | %6 = "ep2.init"(%4, %arg0, %5) : (!ep2.atom, !ep2.context, i64) -> !ep2.struct<"USER_EVENT1" : isEvent = true, elementTypes = !ep2.atom, !ep2.context, i32> 25 | ep2.return %6 : !ep2.struct<"USER_EVENT1" : isEvent = true, elementTypes = !ep2.atom, !ep2.context, i32> 26 | "ep2.terminate"() : () -> () 27 | } 28 | ep2.func private @__handler_USER_EVENT1_process_desc(%arg0: !ep2.context, %arg1: i32) attributes {atom = "process_desc", event = "USER_EVENT1", type = "handler"} { 29 | %0 = "ep2.context_ref"(%arg0) <{name = "flow_grp"}> : (!ep2.context) -> !ep2.conref 30 | "ep2.store"(%0, %arg1) : (!ep2.conref, i32) -> () 31 | %1 = "ep2.nop"() : () -> none 32 | "ep2.terminate"() : () -> () 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /runtime_lib/fpga_runtime/rtl_lib/ep2/barrier_queue.sv: -------------------------------------------------------------------------------- 1 | module barrier_queue # 2 | ( 3 | parameter DATA_WIDTH = 16, 4 | parameter KEEP_ENABLE = 1, 5 | parameter KEEP_WIDTH = (DATA_WIDTH/8), 6 | parameter FIFO_SIZE = 16 7 | ) 8 | ( 9 | input wire clk, 10 | input wire rst, 11 | 12 | input wire [DATA_WIDTH-1:0] s_in_tdata, 13 | input wire [KEEP_WIDTH-1:0] s_in_tkeep, 14 | input wire s_in_tlast, 15 | input wire s_in_tvalid, 16 | output reg s_in_tready, 17 | 18 | input wire barrier, 19 | 20 | output wire [DATA_WIDTH-1:0] m_out_tdata, 21 | output wire [KEEP_WIDTH-1:0] m_out_tkeep, 22 | output wire m_out_tlast, 23 | output wire m_out_tvalid, 24 | input wire m_out_tready 25 | ); 26 | 27 | logic [DATA_WIDTH-1:0] fifo_axis_out_tdata; 28 | logic [KEEP_WIDTH-1:0] fifo_axis_out_tkeep; 29 | logic fifo_axis_out_tvalid; 30 | logic fifo_axis_out_tlast; 31 | logic fifo_axis_out_tready; 32 | 33 | localparam FIFO_FRAME_SIZE = KEEP_ENABLE ? (FIFO_SIZE * KEEP_WIDTH) : FIFO_SIZE; 34 | axis_fifo #( 35 | .DEPTH(FIFO_FRAME_SIZE), 36 | .DATA_WIDTH(DATA_WIDTH), 37 | .KEEP_ENABLE(KEEP_ENABLE), 38 | .KEEP_WIDTH(KEEP_WIDTH), 39 | .LAST_ENABLE(KEEP_ENABLE), 40 | .ID_ENABLE(0), 41 | .DEST_ENABLE(0), 42 | .USER_ENABLE(0), 43 | .FRAME_FIFO(0) 44 | ) 45 | fifo ( 46 | .clk(clk), 47 | .rst(rst), 48 | // AXI input 49 | .s_axis_tdata(s_in_tdata), 50 | .s_axis_tkeep(s_in_tkeep), 51 | .s_axis_tlast(s_in_tlast), 52 | .s_axis_tvalid(s_in_tvalid), 53 | .s_axis_tready(s_in_tready), 54 | 55 | // AXI output 56 | .m_axis_tdata(fifo_axis_out_tdata), 57 | .m_axis_tkeep(fifo_axis_out_tkeep), 58 | .m_axis_tlast(fifo_axis_out_tlast), 59 | .m_axis_tvalid(fifo_axis_out_tvalid), 60 | .m_axis_tready(fifo_axis_out_tready) 61 | ); 62 | 63 | assign m_out_tdata = fifo_axis_out_tdata; 64 | assign m_out_tkeep = fifo_axis_out_tkeep; 65 | assign m_out_tlast = fifo_axis_out_tlast; 66 | assign m_out_tvalid = fifo_axis_out_tvalid && barrier; 67 | assign fifo_axis_out_tready = m_out_tready && barrier; 68 | 69 | endmodule -------------------------------------------------------------------------------- /runtime_lib/netronome_runtime/include/fp_debug.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: BSD 3-Clause License */ 2 | /* Copyright (c) 2022, University of Washington, Max Planck Institute for Software Systems, and The University of Texas at Austin */ 3 | 4 | #ifndef FLEXTOE_FP_DEBUG_H_ 5 | #define FLEXTOE_FP_DEBUG_H_ 6 | 7 | #include 8 | #include "common.h" 9 | 10 | /* Log Modules */ 11 | enum fp_modules_e { 12 | FP_MOD_RX, 13 | FP_MOD_SP, 14 | FP_MOD_AC, 15 | FP_MOD_QM, 16 | FP_MOD_TX, 17 | FP_MOD_ATX, 18 | FP_MOD_ARX, 19 | }; 20 | 21 | /* Statistics */ 22 | enum fp_stats_e { 23 | FP_STAT_RX_TOTAL, 24 | FP_STAT_TX_TOTAL, 25 | FP_STAT_AC_TOTAL, 26 | FP_STAT_RETX_TOTAL, 27 | FP_STAT_GRP0, 28 | FP_STAT_GRP1, 29 | FP_STAT_GRP2, 30 | FP_STAT_GRP3, 31 | FP_STAT_RX_SP, 32 | FP_STAT_RX_PROC, 33 | FP_STAT_TX_PROC, 34 | FP_STAT_AC_PROC, 35 | FP_STAT_RETX_PROC, 36 | FP_STAT_RX_POSTPROC_IN, 37 | FP_STAT_TX_POSTPROC_IN, 38 | FP_STAT_AC_POSTPROC_IN, 39 | FP_STAT_RETX_POSTPROC_IN, 40 | FP_STAT_DMA_RX_PAYLOAD_ISSUE, 41 | FP_STAT_DMA_RX_FWD_ACK, 42 | FP_STAT_DMA_RX_FWD_DROP, 43 | FP_STAT_DMA_RX_FWD_ARX, 44 | FP_STAT_DMA_TX_PAYLOAD_ISSUE, 45 | FP_STAT_DMA_TX_FWD_SEG, 46 | FP_STAT_DMA_TX_FWD_DROP, 47 | FP_STAT_DMA_ARX_DESC_ISSUE, 48 | FP_STAT_DMA_ARX_DESC_FWD_FREE, 49 | FP_STAT_DMA_ATX_DESC_ISSUE, 50 | FP_STAT_DMA_ATX_DESC_FWD_AC, 51 | FP_STAT_ARX, 52 | FP_STAT_ATX, 53 | FP_STAT_ATX_NODESC, 54 | FP_STAT_PROC_CACHE_MISS, 55 | FP_STAT_PROC_EMEM_CACHE_MISS, 56 | FP_STAT_QM_SCHEDULE, 57 | FP_STAT_SP_FWD, 58 | }; 59 | 60 | /* Profiling sections */ 61 | enum fp_prof_e { 62 | FP_PROF_PROC_RX, 63 | FP_PROF_PROC_TX, 64 | FP_PROF_PROC_AC, 65 | FP_PROF_PROC_RETX, 66 | FP_PROF_PROC_ACK, 67 | }; 68 | 69 | 70 | PACKED_STRUCT(flextcp_pl_debug) 71 | { 72 | /* Configuration space */ 73 | uint32_t log_tail_idx; /*> Incremented by the device */ 74 | uint32_t __pad1[63]; /*> Ensure 256 byte alignment */ 75 | 76 | /* Log buffer */ 77 | uint32_t log_buffer[LOGBUF_SIZE]; 78 | 79 | /* Stats buffer */ 80 | /* 256 byte aligned */ 81 | uint64_t stats_buffer[STATBUF_SIZE]; 82 | 83 | /* Profiling buffer */ 84 | /* 256 byte aligned */ 85 | uint64_t prof_cycles[PROFBUF_SIZE]; /*> Number of cycles per section */ 86 | uint64_t prof_count[PROFBUF_SIZE]; /*> Count of hits on section */ 87 | 88 | /* Padding */ 89 | uint64_t __pad2[PROFBUF_SIZE * 4]; 90 | }; 91 | 92 | #endif /* FLEXTOE_FP_DEBUG_H_ */ 93 | -------------------------------------------------------------------------------- /runtime_lib/netronome_runtime/microc/lib/net/gre.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2015, Netronome Systems, Inc. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | * @file lib/net/gre.h 17 | * @brief Definitions for GRE header parsing 18 | * 19 | */ 20 | 21 | #ifndef _NET_GRE_H_ 22 | #define _NET_GRE_H_ 23 | 24 | /** 25 | * GRE has several forms depending on the RFC (1701, 2784, DRAFT NVGRE 26 | * or 2890. Here we focus on DRAFT NVGRE and 2890. 27 | * NVGRE has flags C=0, S=0 and K=1. Proto=0x6558 (ethernet bridging) 28 | * NVGRE is a particular case of of 2890 29 | */ 30 | 31 | /** 32 | * GRE Flags 33 | */ 34 | #define NET_GRE_FLAGS_SEQ_PRESENT 0x1 35 | #define NET_GRE_FLAGS_KEY_PRESENT 0x2 36 | #define NET_GRE_FLAGS_CSUM_PRESENT 0x8 37 | 38 | /** 39 | * Convenience macro to determine if a GRE header is NVGRE 40 | * (assumming proto is NET_ETH_TYPE_TEB) 41 | */ 42 | #define NET_GRE_IS_NVGRE(flags) \ 43 | ((!(flags & NET_GRE_FLAGS_CSUM_PRESENT) && \ 44 | !(flags & NET_GRE_FLAGS_SEQ_PRESENT) && \ 45 | (flags & NET_GRE_FLAGS_KEY_PRESENT)) \ 46 | ? 1 : 0) 47 | 48 | #if defined(__NFP_LANG_MICROC) 49 | 50 | #include 51 | #include 52 | 53 | /** 54 | * GRE header structure 55 | */ 56 | __packed struct gre_hdr { 57 | unsigned int flags:4; /** Flags */ 58 | unsigned int reserved0:9; /** Reserved bits */ 59 | unsigned int version:3; /** Version */ 60 | uint16_t proto; /** Protocol */ 61 | }; 62 | 63 | __packed struct nvgre_ext_hdr { 64 | unsigned int vsid:24; /** Virtual subnet ID */ 65 | unsigned int flowID:8; /** Flow ID */ 66 | }; 67 | #endif /* __NFP_LANG_MICROC */ 68 | 69 | #endif /* _NET_GRE_H_ */ 70 | 71 | /* -*- Mode:C; c-basic-offset:4; tab-width:4 -*- */ 72 | -------------------------------------------------------------------------------- /runtime_lib/netronome_runtime/microc/blocks/init/_uc/init_nbi_pc.uc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-2015, Netronome Systems, Inc. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | * @file: init_nbi_tm.uc 17 | * @brief: Intermediate Pre-Classifier setup 18 | * 19 | */ 20 | 21 | #ifndef _INIT_NBI_PC_UC_ 22 | #define _INIT_NBI_PC_UC_ 23 | 24 | #ifndef NBI_PKT_PREPEND_BYTES 25 | #error "NBI_PKT_PREPEND_BYTES is not defined" 26 | #endif 27 | 28 | #include "init_nbi_pc_csr.uc" 29 | 30 | /** Nbi_PreClassifier_Init 31 | * 32 | * Pre-Classifier initialisation 33 | * 34 | * @param NBI_ID NBI number, can be 0 or 1 35 | */ 36 | #macro Nbi_PreClassifier_Init(NBI_ID) 37 | #if (NBI_ID < 0) || (NBI_ID > 1) 38 | #error "NBI_ID can only be 0 or 1" 39 | #endif 40 | 41 | /* NBI Packet Classifier Work around for A0 bug 42 | NFPBSP-1226 43 | NFPBSP-1179 44 | */ 45 | #if ((__REVISION_MIN == __REVISION_A0) || \ 46 | (__REVISION_MIN == __REVISION_A1)) 47 | Nbi_PktPreclassifier_NFPBSP_1179(NBI_ID) 48 | #endif 49 | 50 | /* The PortCfg register is write-only, hence we must configure its 51 | fields in one write 52 | */ 53 | #if (NBI_PKT_PREPEND_BYTES>0) 54 | #define_eval PORT_CFG_SKIP (NBI_PKT_PREPEND_BYTES/2) 55 | #else 56 | #define PORT_CFG_SKIP 0 57 | #endif 58 | #define ANALYSIS 1 59 | #define_eval PORT_CFG_VAL ((PORT_CFG_SKIP << 2) | (ANALYSIS)) 60 | #define_eval PORT_CFG_LOOP (127) 61 | #while (PORT_CFG_LOOP >= 0) 62 | Nbi_PktPreclassifier_Characterization_PortCfg(NBI_ID,PORT_CFG_LOOP, 63 | PORT_CFG_VAL) 64 | #define_eval PORT_CFG_LOOP (PORT_CFG_LOOP-1) 65 | 66 | #endloop 67 | #undef ANALYSIS 68 | #undef PORT_CFG_SKIP 69 | #undef PORT_CFG_VAL 70 | #undef PORT_CFG_LOOP 71 | 72 | #endm 73 | 74 | #endif /* _INIT_NBI_PC_UC_ */ 75 | -------------------------------------------------------------------------------- /scripts/extract_struct_def.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import re 3 | import json 4 | import sys 5 | import argparse 6 | 7 | def parse_c_file(file_content): 8 | """ 9 | Parse the provided C file content to extract struct definitions 10 | that contain BITS_FIELD macros. For each such struct, extract the 11 | integer values from the first parameter of BITS_FIELD. 12 | 13 | Args: 14 | file_content (str): The content of the C file. 15 | 16 | Returns: 17 | dict: A dictionary where keys are struct names and values are 18 | lists of integer values extracted from BITS_FIELD. 19 | """ 20 | # Regex to capture struct definitions: struct { ... }; 21 | struct_pattern = re.compile(r'struct\s+(\w+)\s*\{(.*?)\};', re.DOTALL) 22 | # Regex to capture BITS_FIELD(integer, field_name) 23 | bits_field_pattern = re.compile(r'BITS_FIELD\s*\(\s*(\d+)\s*,\s*\w+\s*\)') 24 | 25 | result = {} 26 | for struct_match in struct_pattern.finditer(file_content): 27 | struct_name = struct_match.group(1) 28 | struct_body = struct_match.group(2) 29 | 30 | # Find all occurrences of BITS_FIELD in the struct body 31 | numbers = [int(num) for num in bits_field_pattern.findall(struct_body)] 32 | if numbers: 33 | result[struct_name] = numbers 34 | return result 35 | 36 | def main(): 37 | parser = argparse.ArgumentParser( 38 | description="Convert C file struct BITS_FIELD definitions to a JSON dictionary." 39 | ) 40 | parser.add_argument("input_file", help="Path to the input C file") 41 | parser.add_argument( 42 | "-o", "--output", help="Path to the output JSON file (default: stdout)", default=None 43 | ) 44 | args = parser.parse_args() 45 | 46 | try: 47 | with open(args.input_file, "r") as f: 48 | file_content = f.read() 49 | except Exception as e: 50 | print(f"Error reading file: {e}") 51 | sys.exit(1) 52 | 53 | parsed_data = parse_c_file(file_content) 54 | json_output = json.dumps(parsed_data, indent=4) 55 | 56 | if args.output: 57 | try: 58 | with open(args.output, "w") as f: 59 | f.write(json_output) 60 | except Exception as e: 61 | print(f"Error writing output file: {e}") 62 | sys.exit(1) 63 | else: 64 | print(json_output) 65 | 66 | if __name__ == "__main__": 67 | main() 68 | 69 | -------------------------------------------------------------------------------- /include/ep2/dialect/Dialect.h: -------------------------------------------------------------------------------- 1 | //===- Dialect.h - Dialect definition for the Toy IR ----------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file implements the IR Dialect for the Toy language. 10 | // See docs/Tutorials/Toy/Ch-2.md for more information. 11 | // 12 | //===----------------------------------------------------------------------===// 13 | 14 | #ifndef EP2_DIALECT_H_ 15 | #define EP2_DIALECT_H_ 16 | 17 | #include "mlir/Bytecode/BytecodeOpInterface.h" 18 | #include "mlir/IR/BuiltinTypes.h" 19 | #include "mlir/IR/Dialect.h" 20 | #include "mlir/IR/SymbolTable.h" 21 | #include "mlir/Interfaces/CallInterfaces.h" 22 | #include "mlir/Interfaces/CastInterfaces.h" 23 | #include "mlir/Interfaces/FunctionInterfaces.h" 24 | #include "mlir/Interfaces/SideEffectInterfaces.h" 25 | #include "mlir/Interfaces/MemorySlotInterfaces.h" 26 | #include "llvm/ADT/TypeSwitch.h" 27 | 28 | #include "mlir/Dialect/SCF/IR/SCF.h" 29 | 30 | namespace mlir { 31 | namespace ep2 { 32 | namespace detail { 33 | struct StructTypeStorage; 34 | } // namespace detail 35 | } // namespace toy 36 | } // namespace mlir 37 | 38 | /// Include the auto-generated header file containing the declaration of the toy 39 | /// dialect. 40 | #include "ep2/dialect/EP2OpsDialect.h.inc" 41 | 42 | //===----------------------------------------------------------------------===// 43 | // EP2 Types 44 | //===----------------------------------------------------------------------===// 45 | 46 | #define GET_TYPEDEF_CLASSES 47 | #include "ep2/dialect/EP2OpsTypes.h.inc" 48 | 49 | //===----------------------------------------------------------------------===// 50 | // EP2 Attrs 51 | //===----------------------------------------------------------------------===// 52 | 53 | #define GET_ATTRDEF_CLASSES 54 | #include "ep2/dialect/EP2OpsAttrDefs.h.inc" 55 | 56 | //===----------------------------------------------------------------------===// 57 | // Toy Operations 58 | //===----------------------------------------------------------------------===// 59 | 60 | /// Include the auto-generated header file containing the declarations of the 61 | /// toy operations. 62 | #define GET_OP_CLASSES 63 | #include "ep2/dialect/EP2Ops.h.inc" 64 | 65 | #endif // EP2_DIALECT_H_ 66 | -------------------------------------------------------------------------------- /.clang-tidy: -------------------------------------------------------------------------------- 1 | InheritParentConfig: true 2 | Checks: > 3 | -misc-const-correctness, 4 | bugprone-argument-comment, 5 | bugprone-assert-side-effect, 6 | bugprone-branch-clone, 7 | bugprone-copy-constructor-init, 8 | bugprone-dangling-handle, 9 | bugprone-dynamic-static-initializers, 10 | bugprone-macro-parentheses, 11 | bugprone-macro-repeated-side-effects, 12 | bugprone-misplaced-widening-cast, 13 | bugprone-move-forwarding-reference, 14 | bugprone-multiple-statement-macro, 15 | bugprone-suspicious-semicolon, 16 | bugprone-swapped-arguments, 17 | bugprone-terminating-continue, 18 | bugprone-unused-raii, 19 | bugprone-unused-return-value, 20 | misc-redundant-expression, 21 | misc-static-assert, 22 | misc-unused-using-decls, 23 | modernize-use-bool-literals, 24 | modernize-loop-convert, 25 | modernize-make-unique, 26 | modernize-raw-string-literal, 27 | modernize-use-equals-default, 28 | modernize-use-default-member-init, 29 | modernize-use-emplace, 30 | modernize-use-nullptr, 31 | modernize-use-override, 32 | modernize-use-using, 33 | performance-for-range-copy, 34 | performance-implicit-conversion-in-loop, 35 | performance-inefficient-algorithm, 36 | performance-inefficient-vector-operation, 37 | performance-move-const-arg, 38 | performance-no-automatic-move, 39 | performance-trivially-destructible, 40 | performance-unnecessary-copy-initialization, 41 | performance-unnecessary-value-param, 42 | readability-avoid-const-params-in-decls, 43 | readability-const-return-type, 44 | readability-container-size-empty, 45 | readability-inconsistent-declaration-parameter-name, 46 | readability-misleading-indentation, 47 | readability-redundant-control-flow, 48 | readability-redundant-smartptr-get, 49 | readability-simplify-boolean-expr, 50 | readability-simplify-subscript-expr, 51 | readability-use-anyofallof 52 | 53 | 54 | CheckOptions: 55 | - key: readability-identifier-naming.MemberCase 56 | value: camelBack 57 | - key: readability-identifier-naming.ParameterCase 58 | value: camelBack 59 | - key: readability-identifier-naming.VariableCase 60 | value: camelBack 61 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | #==============================================================================# 2 | # This file specifies intentionally untracked files that git should ignore. 3 | # See: http://www.kernel.org/pub/software/scm/git/docs/gitignore.html 4 | # 5 | # This file is intentionally different from the output of `git svn show-ignore`, 6 | # as most of those are useless. 7 | #==============================================================================# 8 | 9 | #==============================================================================# 10 | # File extensions to be ignored anywhere in the tree. 11 | #==============================================================================# 12 | # Temp files created by most text editors. 13 | *~ 14 | # Merge files created by git. 15 | *.orig 16 | # Reject files created by patch. 17 | *.rej 18 | # Byte compiled python modules. 19 | *.pyc 20 | # vim swap files 21 | .*.sw? 22 | .sw? 23 | #OS X specific files. 24 | .DS_store 25 | 26 | # Ignore the user specified CMake presets in subproject directories. 27 | /*/CMakeUserPresets.json 28 | 29 | # Nested build directory 30 | /build* 31 | # generated fires 32 | #*.sv 33 | 34 | #==============================================================================# 35 | # Explicit files to ignore (only matches one). 36 | #==============================================================================# 37 | # Various tag programs 38 | /tags 39 | /TAGS 40 | /GPATH 41 | /GRTAGS 42 | /GSYMS 43 | /GTAGS 44 | /ID 45 | .gitusers 46 | autom4te.cache 47 | cscope.files 48 | cscope.out 49 | autoconf/aclocal.m4 50 | autoconf/autom4te.cache 51 | /compile_commands.json 52 | # Visual Studio built-in CMake configuration 53 | /CMakeSettings.json 54 | # CLion project configuration 55 | /.idea 56 | 57 | #==============================================================================# 58 | # Directories to ignore (do not add trailing '/'s, they skip symlinks). 59 | #==============================================================================# 60 | # VS2017 and VSCode config files. 61 | .vscode 62 | .vs 63 | # pythonenv for github Codespaces 64 | pythonenv* 65 | # clangd index. (".clangd" is a config file now, thus trailing slash) 66 | .clangd/ 67 | .cache 68 | # static analyzer regression testing project files 69 | /clang/utils/analyzer/projects/*/CachedSource 70 | /clang/utils/analyzer/projects/*/PatchedSource 71 | /clang/utils/analyzer/projects/*/ScanBuildResults 72 | /clang/utils/analyzer/projects/*/RefScanBuildResults 73 | # automodapi puts generated documentation files here. 74 | /lldb/docs/python_api/ 75 | -------------------------------------------------------------------------------- /runtime_lib/netronome_runtime/scripts/Makefile.nfp.config: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2015-2018, Netronome Systems, Inc. All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | # @file apps/wire/Makefile 17 | # @brief Makefile for the ME cut-through wire app 18 | # 19 | 20 | # Configuration 21 | NFP_SDK_DIR ?= /opt/netronome 22 | NFP_STD_LIB ?= $(NFP_SDK_DIR)/components/standardlibrary 23 | PICO_CODE ?= $(NFP_STD_LIB)/picocode/nfp6000/catamaran/catamaran.npfw 24 | Q ?= @ 25 | 26 | NFAS ?= $(NFP_SDK_DIR)/bin/nfas 27 | NFCC ?= $(NFP_SDK_DIR)/bin/nfcc 28 | NFLD ?= $(NFP_SDK_DIR)/bin/nfld 29 | 30 | CHIP ?= nfp-4xxx-b0 31 | 32 | # Default nfas flags 33 | # -t => terse output 34 | # -W3 => warning level 3 35 | # -R => require register declarations 36 | # -lm 0 => define start of local memory allocation to be byte 0 37 | # -C => enable case sensitivity 38 | # -chip => build for the specified CHIP 39 | NFASFLAGS ?= -t -W3 -R -lm 0 -C -chip $(CHIP) 40 | 41 | NFLDFLAGS ?= -chip $(CHIP) 42 | 43 | # Default nfas flags 44 | # -W3 => warning level 3 45 | # -Gx6000 => specify NFP-6xxx target architecture, add -D__NFP_IS_6000 46 | # -Qspill=7 => no register spilling 47 | # -Qnn_mode=1 => next neighbor registers are self accessible (not neighbor accessible) 48 | # -Qno_decl_volatile => make all C declarations nonvolatile unless explicitly specified to be volatile 49 | # -single_dram_signal => use standard approach of bulk memory transactions use a single signal 50 | NFCCFLAGS ?= -W3 -chip $(CHIP) -Qspill=7 -Qnn_mode=1 \ 51 | -Qno_decl_volatile -single_dram_signal \ 52 | -Qnctx_mode=8 53 | 54 | FW_BUILD := $(app_src_dir) 55 | FW_FW := $(app_src_dir) 56 | FIRMWARE_DIR := $(base_dir)/microc 57 | NFCC_BASE_INC := -I. -I$(base_dir)/microc/include -I$(base_dir)/microc/lib 58 | NFAS_BASE_FLAGS := $(NFASFLAGS) 59 | NFLD_BASE_FLAGS := $(NFLDFLAGS) 60 | NFAS_BASE_INC := -I. -I$(microc_blocks_dir) -I$(microc_libs_dir) -I$(microc_inc_dir) -I$(NFP_STD_LIB)/microcode/src -I$(NFP_STD_LIB)/include 61 | 62 | -------------------------------------------------------------------------------- /example_outputs/outs-netronome/out-netronome-cpu_load/process_packet_1.c: -------------------------------------------------------------------------------- 1 | #define DO_CTXQ_INIT 2 | 3 | #include "nfplib.h" 4 | #include "prog_hdr.h" 5 | #include "extern/extern_dma.h" 6 | #include "extern/extern_net.h" 7 | 8 | static struct coremap_t _loc_buf_0; 9 | __xrw static struct coremap_t _loc_buf_0_xfer; 10 | static int rr_ctr = 0; 11 | __declspec(aligned(4)) struct event_param_NET_RECV work; 12 | __xrw struct event_param_NET_RECV work_ref; 13 | __declspec(aligned(4)) struct event_param_LOAD_TABLE_ADD next_work_LOAD_TABLE_ADD; 14 | __xrw struct event_param_LOAD_TABLE_ADD next_work_ref_LOAD_TABLE_ADD; 15 | 16 | __forceinline 17 | void __event___handler_NET_RECV_process_packet_1() { 18 | uint32_t v1; 19 | uint16_t v2; 20 | uint16_t v3; 21 | uint16_t v4; 22 | uint16_t v5; 23 | uint16_t v6; 24 | uint32_t v7; 25 | __declspec(aligned(4)) struct event_param_NET_RECV* v8; 26 | __shared __cls struct context_chain_1_t* v9; 27 | __shared __cls struct context_chain_1_t* v10; 28 | struct __buf_t v11; 29 | __export __shared __cls struct table_i32_coremap_t_16_t* v12; 30 | struct coremap_t* v13; 31 | uint16_t v14; 32 | uint16_t v15; 33 | char v16; 34 | uint16_t v17; 35 | uint16_t v18; 36 | uint32_t v19; 37 | uint16_t v20; 38 | uint16_t v21; 39 | char v22; 40 | uint16_t v23; 41 | uint32_t v24; 42 | char v25; 43 | uint16_t v26; 44 | __declspec(aligned(4)) struct event_param_LOAD_TABLE_ADD* v27; 45 | __xrw struct event_param_LOAD_TABLE_ADD* v28; 46 | v1 = 3; 47 | v2 = 4; 48 | v3 = 3; 49 | v4 = 2; 50 | v5 = 1; 51 | v6 = 0; 52 | v7 = 0; 53 | v8 = &work; 54 | inlined_net_recv(v8); 55 | v9 = alloc_context_chain_ring_entry(); 56 | v8->ctx = v9; 57 | v10 = v8->ctx; 58 | v11 = v8->f0; 59 | v12 = &service_load; 60 | v13 = &_loc_buf_0; 61 | *v13 = v12->table[me_cam_lookup(v7)]; 62 | v14 = v13->f0; 63 | v15 = v13->f1; 64 | v16 = v14 < v15; 65 | v17 = (v16 ? v5 : v4); 66 | v18 = (v16 ? v14 : v15); 67 | v19 = (uint32_t) v18; 68 | v20 = v13->f2; 69 | v21 = v13->f3; 70 | v22 = v20 < v21; 71 | v23 = (v22 ? v3 : v2); 72 | v24 = (uint32_t) v21; 73 | v25 = v19 < v24; 74 | v26 = (v25 ? v17 : v23); 75 | v27 = &next_work_LOAD_TABLE_ADD; 76 | v27->ctx = v10; 77 | v27->f0 = v6; 78 | v27->f1 = v26; 79 | v28 = &next_work_ref_LOAD_TABLE_ADD; 80 | *(v28) = *(v27); 81 | cls_workq_add_work(WORKQ_ID_LOAD_TABLE_ADD_1, v28, sizeof(*v28)); 82 | return; 83 | } 84 | 85 | 86 | int main(void) { 87 | init_me_cam(16); 88 | wait_global_start_(); 89 | for (;;) { 90 | __event___handler_NET_RECV_process_packet_1(); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /runtime_lib/netronome_runtime/microc/lib/nfp/_c/mac_csr_synch.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Netronome, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | * @file lib/nfp/_c/mac_csr_synch.c 17 | * @brief Sets the MAC ethernet config command using arbiter (ring). 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | /* Do not force recache */ 26 | #ifndef MAC_FORCE_RECACHE 27 | #define MAC_FORCE_RECACHE 0 28 | #endif 29 | 30 | /* an arbitrary number to insert as the arbiter source value */ 31 | #ifndef MAC_ARB_SRC_APP 32 | #define MAC_ARB_SRC_APP 4 33 | #endif 34 | 35 | __intrinsic void 36 | __mac_eth_cmd_config(unsigned int nbi, unsigned int core, unsigned int port, 37 | unsigned int cmd, sync_t sync, SIGNAL *sig) 38 | { 39 | __gpr uint32_t ring_num = (ARB_CLS_RING_NUM <<2); 40 | __gpr uint32_t ring_isl = ARB_CLS_BASE_ADDR_Hi32; 41 | __xwrite uint32_t xfr_flush; 42 | 43 | try_ctassert(nbi < NFP_MAC_MAX_ISLANDS_PER_NFP); 44 | try_ctassert(core < NFP_MAX_MAC_CORES_PER_MAC_ISL); 45 | try_ctassert(port < NFP_MAX_ETH_PORTS_PER_MAC_CORE); 46 | try_ctassert(cmd <= ARB_CODE_MAX); 47 | ctassert(__is_ct_const(sync)); 48 | ctassert(sync == sig_done || sync == ctx_swap); 49 | 50 | xfr_flush = ARB_SOURCE(MAC_ARB_SRC_APP) | ARB_RECACHE(MAC_FORCE_RECACHE) | 51 | ARB_NBI(nbi) | ARB_PORT(port) | ARB_CORE(core) | ARB_CMD(cmd); 52 | 53 | if (sync == sig_done) { 54 | __asm cls[ring_workq_add_work, xfr_flush, ring_isl, <<8, ring_num, 1],\ 55 | sig_done[*sig] 56 | } else { 57 | __asm cls[ring_workq_add_work, xfr_flush, ring_isl, <<8, ring_num, 1],\ 58 | ctx_swap[*sig]; 59 | } 60 | } 61 | 62 | 63 | __intrinsic void 64 | mac_eth_cmd_config(unsigned int nbi, unsigned int core, unsigned int port, 65 | unsigned int cmd) 66 | { 67 | SIGNAL sig; 68 | __mac_eth_cmd_config(nbi, core, port, cmd, ctx_swap, &sig); 69 | } -------------------------------------------------------------------------------- /runtime_lib/netronome_runtime/include/fp_app_if.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: BSD 3-Clause License */ 2 | /* Copyright (c) 2022, University of Washington, Max Planck Institute for Software Systems, and The University of Texas at Austin */ 3 | 4 | #ifndef FP_APP_IF_H_ 5 | #define FP_APP_IF_H_ 6 | 7 | #include 8 | #include "common.h" 9 | 10 | /** App RX queue */ 11 | enum { 12 | FLEXTCP_PL_ARX_INVALID = 0, 13 | FLEXTCP_PL_ARX_CONNUPDATE, 14 | FLEXTCP_PL_ARX_DUMMY, 15 | }; 16 | 17 | /** Application RX queue entry */ 18 | PACKED_STRUCT(flextcp_pl_arx_t) 19 | { 20 | PACKED_UNION() 21 | { 22 | PACKED_STRUCT() 23 | { 24 | uint64_t opaque; 25 | uint32_t rx_bump; 26 | uint32_t tx_bump; 27 | uint32_t flags; 28 | } connupdate; 29 | uint32_t raw[7]; 30 | } msg; 31 | uint32_t type; 32 | }; 33 | 34 | /* Flags */ 35 | #define FLEXTCP_PL_ARX_FLRXDONE 0x2 36 | 37 | 38 | /** App TX queue */ 39 | enum { 40 | FLEXTCP_PL_ATX_INVALID = 0, 41 | FLEXTCP_PL_ATX_CONNUPDATE, 42 | }; 43 | 44 | /** Application TX queue entry */ 45 | PACKED_STRUCT(flextcp_pl_atx_t) 46 | { 47 | PACKED_UNION() 48 | { 49 | PACKED_STRUCT() { 50 | uint32_t rx_bump; 51 | uint32_t tx_bump; 52 | uint32_t flow_id; 53 | uint32_t flow_grp; 54 | uint16_t bump_seq; 55 | uint8_t flags; 56 | } connupdate; 57 | uint32_t raw[7]; 58 | } msg; 59 | uint32_t type; 60 | }; 61 | 62 | /* Flags */ 63 | #define FLEXTCP_PL_ATX_FLTXDONE (1 << 0) 64 | #define FLEXTCP_PL_ATX_DUMMY (1 << 1) 65 | 66 | /** Application context queue state */ 67 | PACKED_STRUCT(flextcp_pl_appctx_queue_t) 68 | { 69 | PACKED_UNION() 70 | { 71 | PACKED_STRUCT() 72 | { 73 | uint32_t base_lo; 74 | uint32_t len; 75 | uint32_t p_idx; 76 | uint32_t c_idx; 77 | }; 78 | uint32_t __raw[4]; 79 | }; 80 | }; 81 | 82 | /** Application context registers */ 83 | PACKED_STRUCT(flextcp_pl_appctx_t) 84 | { 85 | struct flextcp_pl_appctx_queue_t rx; 86 | struct flextcp_pl_appctx_queue_t tx; 87 | uint64_t last_ts; 88 | uint32_t appst_id; 89 | uint32_t __pad[5]; 90 | }; 91 | 92 | /** Application state */ 93 | PACKED_STRUCT(flextcp_pl_appst_t) 94 | { 95 | uint16_t ctx_num; /*> Number of contexts */ 96 | uint16_t __pad[31]; /*> Padding */ 97 | uint16_t ctx_ids[FLEXNIC_PL_APPCTX_NUM]; /*> IDs of contexts */ 98 | }; 99 | 100 | /* FIXME: Add STATIC asserts on struct sizes */ 101 | 102 | #endif /* FP_APPIF_H_ */ 103 | -------------------------------------------------------------------------------- /lib/ep2/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_mlir_dialect_library(MLIREP2 2 | Dialect/Dialect.cpp 3 | Dialect/MemorySlotInstance.cpp 4 | 5 | # Analysis 6 | LowerStructAnalysis.cpp 7 | HandlerDependencyAnalysis.cpp 8 | ContextBufferizationAnalysis.cpp 9 | HandlerInOutAnalysis.cpp 10 | TableAnalysis.cpp 11 | AtomAnalysis.cpp 12 | BufferAnalysis.cpp 13 | 14 | # Passes 15 | ArchMappingPass.cpp 16 | ContextToArgumentPass.cpp 17 | CFToPredPass.cpp 18 | BufferToValuePass.cpp 19 | EmitFPGAHelper.cpp 20 | EmitFPGAController.cpp 21 | EmitFPGA.cpp 22 | EmitFPGATop.cpp 23 | HandlerInOutAnalysis.cpp 24 | TableAnalysis.cpp 25 | AtomAnalysis.cpp 26 | ContextTypeInferencePass.cpp 27 | LowerEmitcPass.cpp 28 | CollectHeaderPass.cpp 29 | EmitNetronomePass.cpp 30 | EP2LinearizePass.cpp 31 | LowerMemcpyPass.cpp 32 | AtomAnalysis.cpp 33 | StructUpdatePropagationPass.cpp 34 | LocalAllocAnalysis.cpp 35 | LowerLLVMPass.cpp 36 | EmitLLVMHeaderPass.cpp 37 | HandlerReplicationPass.cpp 38 | LowerNoctxswapPass.cpp 39 | RepackStructTypesPass.cpp 40 | GprPromotionPass.cpp 41 | PipelineHandlerPass.cpp 42 | 43 | Passes/ContextToMemPass.cpp 44 | Passes/BufferReusePass.cpp 45 | Passes/DeadFieldEliminatePass.cpp 46 | Passes/DeadParameterEliminatePass.cpp 47 | Passes/CanonicalizePass.cpp 48 | Passes/AtomicIdentificationPass.cpp 49 | Passes/FPGABufferToStoragePass.cpp 50 | Passes/ControllerGenerationPass.cpp 51 | Passes/GlobalToPartitionPass.cpp 52 | 53 | # conversion and frontend 54 | Passes/Conversion/LiftLLVMPass.cpp 55 | Passes/Conversion/SplitFunction.cpp 56 | Passes/Conversion/LiftUtils.cpp 57 | 58 | Passes/Mapping/PerformanceModel.cpp 59 | Passes/Mapping/MappingUtils.cpp 60 | Passes/Mapping/PipelineCanonicalizePass.cpp 61 | Passes/Mapping/PipeliningPass.cpp 62 | 63 | DEPENDS 64 | MLIREP2OpsIncGen 65 | EP2OpsAttrDefsIncGen 66 | 67 | LINK_LIBS PUBLIC 68 | MLIRIR 69 | MLIRTranslateLib 70 | MLIREmitCDialect 71 | MLIRTargetCpp 72 | MLIRFuncDialect 73 | ) 74 | 75 | # link to z3 libs 76 | target_include_directories(MLIREP2 PRIVATE ${Z3_CXX_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}) 77 | target_link_libraries(MLIREP2 PRIVATE ${Z3_LIBRARIES}) 78 | target_compile_options(MLIREP2 PRIVATE ${Z3_COMPONENT_CXX_FLAGS}) 79 | -------------------------------------------------------------------------------- /runtime_lib/netronome_runtime/microc/blocks/gro/scripts/ucverify.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # 4 | # Copyright (C) 2018, Netronome Systems, Inc. All rights reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # @file me/blocks/gro/scripts/ucverify.py 19 | # 20 | 21 | import sys 22 | import re 23 | 24 | instr_pat = re.compile('^\.(\d+)') 25 | ref_pat = re.compile('\.macro_ref\s+(\w+)') 26 | endref_pat = re.compile('\.end_macro_ref\s+(\w+)') 27 | verify_pat = re.compile(';\s*VERIFY:\s*icount\s+(\w+)\s+(\d+)') 28 | 29 | cur_instr = 0 30 | live_macros = [] 31 | tracked_macros = { } 32 | lineno = 0 33 | rc = 0 34 | 35 | def expected_len(name): 36 | if tracked_macros.has_key(name): 37 | return tracked_macros[name] 38 | else: 39 | return -1 40 | 41 | f = open(sys.argv[1]) 42 | for line in f.readlines(): 43 | lineno += 1 44 | instr = instr_pat.search(line) 45 | if instr: 46 | cur_instr = int(instr.group(1)) 47 | continue 48 | 49 | ref = ref_pat.search(line) 50 | if ref: 51 | macro = ref.group(1) 52 | live_macros.append((macro, lineno, cur_instr, expected_len(macro))) 53 | continue 54 | 55 | endref = endref_pat.search(line) 56 | if endref: 57 | macro = endref.group(1) 58 | (lastm, start_line, start_instr, expected) = live_macros.pop() 59 | if lastm != macro: 60 | raise Exception("macro mismatch: '%s' expected, '%s' found" % (last, macro)) 61 | if expected > 0 and cur_instr - start_instr != expected: 62 | print "Macro '%s' on line %d' is supposed to be '%d' instructions but is actually '%d'" % \ 63 | (macro, start_line, expected, cur_instr - start_instr) 64 | rc += 1 65 | continue 66 | 67 | verify = verify_pat.search(line) 68 | if verify: 69 | tracked_macros[verify.group(1)] = int(verify.group(2)) 70 | continue 71 | 72 | 73 | if rc: 74 | print "%s: %d macros had invalid lengths" % (sys.argv[1], rc) 75 | sys.exit(1) 76 | else: 77 | print "%s: All macros verified correctly" % sys.argv[1] 78 | -------------------------------------------------------------------------------- /runtime_lib/fpga_runtime/rtl_lib/ep2/alu.sv: -------------------------------------------------------------------------------- 1 | module ALU # 2 | ( 3 | parameter LVAL_SIZE = 16, 4 | parameter RVAL_SIZE = 16, 5 | parameter RESULT_SIZE = 32, 6 | parameter OPID = 0 // 0 SUB, 1 ADD, 2 AND, 3, LT, 4 GT, 5 EQ, 6 LE, 7 GE 7 | ) 8 | ( 9 | input wire clk, 10 | input wire rst, 11 | 12 | input wire [LVAL_SIZE-1:0] s_lval_axis_tdata, 13 | input wire s_lval_axis_tvalid, 14 | output reg s_lval_axis_tready, 15 | 16 | input wire [RVAL_SIZE-1:0] s_rval_axis_tdata, 17 | input wire s_rval_axis_tvalid, 18 | output reg s_rval_axis_tready, 19 | 20 | output reg [RESULT_SIZE-1:0] m_val_axis_tdata, 21 | output reg m_val_axis_tvalid, 22 | input wire m_val_axis_tready 23 | ); 24 | 25 | always @* begin 26 | m_val_axis_tvalid = 0; 27 | s_lval_axis_tready = s_rval_axis_tvalid && m_val_axis_tready; 28 | s_rval_axis_tready = s_lval_axis_tvalid && m_val_axis_tready; 29 | m_val_axis_tvalid = s_lval_axis_tvalid && s_rval_axis_tvalid; 30 | end 31 | 32 | generate 33 | if (OPID == 0) begin 34 | always @* begin 35 | m_val_axis_tdata = s_lval_axis_tdata - s_rval_axis_tdata; 36 | end 37 | end 38 | else if (OPID == 1) begin 39 | always @* begin 40 | m_val_axis_tdata = s_lval_axis_tdata + s_rval_axis_tdata; 41 | end 42 | end 43 | else if(OPID == 2) begin 44 | always @* begin 45 | m_val_axis_tdata = s_lval_axis_tdata && s_rval_axis_tdata; 46 | end 47 | end 48 | else if(OPID == 3) begin 49 | always @* begin 50 | m_val_axis_tdata = (s_lval_axis_tdata < s_rval_axis_tdata) ? 1 : 0; 51 | end 52 | end 53 | else if(OPID == 4) begin 54 | always @* begin 55 | m_val_axis_tdata = (s_lval_axis_tdata > s_rval_axis_tdata) ? 1 : 0; 56 | end 57 | end 58 | else if(OPID == 5) begin 59 | always @* begin 60 | m_val_axis_tdata = (s_lval_axis_tdata == s_rval_axis_tdata) ? 1 : 0; 61 | end 62 | end 63 | else if(OPID == 6) begin 64 | always @* begin 65 | m_val_axis_tdata = (s_lval_axis_tdata <= s_rval_axis_tdata) ? 1 : 0; 66 | end 67 | end 68 | else if(OPID == 7) begin 69 | always @* begin 70 | m_val_axis_tdata = (s_lval_axis_tdata >= s_rval_axis_tdata) ? 1 : 0; 71 | end 72 | end 73 | endgenerate 74 | 75 | endmodule --------------------------------------------------------------------------------