├── .clang-format ├── .github ├── labeler.yml └── workflows │ ├── ccpp.yml │ └── label.yml ├── .gitignore ├── .gitmodules ├── Documentation ├── arch.png ├── asplos-ae.md ├── compile.md ├── debug.md ├── legomem_system.pdf ├── repo-org-fpga.png ├── repo-org-host.png ├── repo-org.png ├── run.md ├── testbed.png ├── testbed2.png └── vivado-screenshot.png ├── LICENSE ├── Makefile ├── README.md ├── board ├── fpga │ ├── .gitignore │ ├── Makefile │ ├── Makefile.mk │ ├── README.md │ ├── build.sbt │ ├── net_reliable │ │ ├── Makefile │ │ ├── README.md │ │ ├── broadcast_filter │ │ │ ├── Makefile │ │ │ ├── filter_64.hpp │ │ │ ├── filter_64_top.cpp │ │ │ └── run_hls.tcl │ │ ├── dummy_setup │ │ │ ├── Makefile │ │ │ ├── dummy_setup.cpp │ │ │ └── run_hls.tcl │ │ ├── generate_hls.sh │ │ ├── hls_rx │ │ │ ├── Makefile │ │ │ ├── run_hls.tcl │ │ │ ├── rx_64.hpp │ │ │ ├── rx_64_top.cpp │ │ │ └── tb.cpp │ │ ├── hls_timer │ │ │ ├── Makefile │ │ │ ├── run_hls.tcl │ │ │ ├── tb.cpp │ │ │ ├── timer.hpp │ │ │ └── timer_top.cpp │ │ ├── hls_tx │ │ │ ├── Makefile │ │ │ ├── run_hls.tcl │ │ │ ├── tb.cpp │ │ │ ├── tx_64.hpp │ │ │ └── tx_64_top.cpp │ │ ├── lib │ │ ├── rtl │ │ ├── run_vivado.tcl │ │ ├── setup_manager │ │ │ ├── Makefile │ │ │ ├── run_hls.tcl │ │ │ ├── setup_manager.hpp │ │ │ └── setup_manager_top.cpp │ │ ├── state_table │ │ │ ├── Makefile │ │ │ ├── run_hls.tcl │ │ │ ├── statetable_64.hpp │ │ │ ├── statetable_64_top.cpp │ │ │ └── tb.cpp │ │ ├── test_onboard.c │ │ ├── tx_arbiter │ │ │ ├── Makefile │ │ │ ├── arbiter_64.hpp │ │ │ ├── arbiter_64_top.cpp │ │ │ ├── run_hls.tcl │ │ │ └── tb.cpp │ │ └── unacked_buffer │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ ├── run_hls.tcl │ │ │ ├── tb.cpp │ │ │ ├── unacked_buffer.hpp │ │ │ └── unacked_buffer_top.cpp │ ├── scripts │ │ ├── create_ip.tcl │ │ ├── create_monitor_read.tcl │ │ ├── create_monitor_write.tcl │ │ ├── create_pingpong.tcl │ │ └── create_system.tcl │ ├── src │ │ ├── lib │ │ │ └── verilog │ │ │ │ ├── MonitorRegistersRead.v │ │ │ │ ├── MonitorRegistersWrite.v │ │ │ │ └── legomem_system_lib.v │ │ └── main │ │ │ └── scala │ │ │ └── wuklab │ │ │ ├── Axi4.scala │ │ │ ├── Axi4ChannelFactory.scala │ │ │ ├── AxiStream.scala │ │ │ ├── AxiStreamDMA.scala │ │ │ ├── CoreMem.scala │ │ │ ├── ExtendedProcessor.scala │ │ │ ├── Generate.scala │ │ │ ├── IDPool.scala │ │ │ ├── LegoMemDMA.scala │ │ │ ├── LegoMemMultiEndpoint.scala │ │ │ ├── LegoMemSystem.scala │ │ │ ├── Lookup3.scala │ │ │ ├── LookupTable.scala │ │ │ ├── MemoryAccess.scala │ │ │ ├── NetworkAdapter.scala │ │ │ ├── Replicator.scala │ │ │ ├── Sequencer.scala │ │ │ ├── Types.scala │ │ │ ├── Utils.scala │ │ │ ├── Verification.scala │ │ │ ├── kv │ │ │ ├── Allocator.scala │ │ │ ├── KeyValueController.scala │ │ │ ├── KeyValueEndpoint.scala │ │ │ ├── KeyValueEngine.scala │ │ │ ├── Misc.scala │ │ │ └── Types.scala │ │ │ ├── monitor │ │ │ ├── AxiSimpleDMA.scala │ │ │ ├── AxiStreamProtocolChecker.scala │ │ │ └── MonitorRegisters.scala │ │ │ ├── sim │ │ │ ├── AxiSlaveRam.scala │ │ │ ├── Drivers.scala │ │ │ └── Types.scala │ │ │ └── test │ │ │ ├── CoreMemDelayedSim.scala │ │ │ ├── CoreMemSim.scala │ │ │ ├── KeyValuePhysicalEndPointSim.scala │ │ │ ├── KeyValueVirtualEndpointSim.scala │ │ │ ├── LegoMemSystem512Sim.scala │ │ │ ├── LegoMemSystemCtrlSim.scala │ │ │ ├── LegoMemSystemSim.scala │ │ │ ├── NetworkProtocolCheckerSim.scala │ │ │ └── Simulation.scala │ └── top │ │ ├── Makefile │ │ ├── lib │ │ ├── arp_64.v │ │ ├── arp_cache.v │ │ ├── arp_eth_rx_64.v │ │ ├── arp_eth_tx_64.v │ │ ├── axis │ │ │ ├── arbiter.v │ │ │ ├── axis_async_fifo.v │ │ │ ├── axis_async_fifo_adapter.v │ │ │ ├── axis_fifo.v │ │ │ ├── priority_encoder.v │ │ │ └── syn │ │ │ │ └── axis_async_fifo.tcl │ │ ├── axis_xgmii_rx_64.v │ │ ├── axis_xgmii_tx_64.v │ │ ├── eth_arb_mux.v │ │ ├── eth_axis_rx_64.v │ │ ├── eth_axis_tx_64.v │ │ ├── eth_mac_10g.v │ │ ├── eth_mac_10g_fifo.v │ │ ├── eth_phy_10g.v │ │ ├── eth_phy_10g_rx.v │ │ ├── eth_phy_10g_rx_ber_mon.v │ │ ├── eth_phy_10g_rx_frame_sync.v │ │ ├── eth_phy_10g_rx_if.v │ │ ├── eth_phy_10g_tx.v │ │ ├── eth_phy_10g_tx_if.v │ │ ├── ip_64.v │ │ ├── ip_arb_mux.v │ │ ├── ip_complete_64.v │ │ ├── ip_eth_rx_64.v │ │ ├── ip_eth_tx_64.v │ │ ├── lfsr.v │ │ ├── syn │ │ │ └── eth_mac_fifo.tcl │ │ ├── udp_64.v │ │ ├── udp_checksum_gen_64.v │ │ ├── udp_complete_64.v │ │ ├── udp_ip_rx_64.v │ │ ├── udp_ip_tx_64.v │ │ ├── xgmii_baser_dec_64.v │ │ └── xgmii_baser_enc_64.v │ │ ├── rtl │ │ ├── fpga.v │ │ ├── fpga.xdc │ │ ├── fpga_core.v │ │ ├── ip │ │ │ └── gtwizard_ultrascale_0.xci │ │ ├── sync_reset.v │ │ ├── sync_signal.v │ │ └── tb │ │ │ ├── host_stack.v │ │ │ ├── tb_intg.sv │ │ │ ├── tb_rt.sv │ │ │ ├── tb_rx.sv │ │ │ └── tb_tx.sv │ │ └── scripts │ │ ├── legomem_system.tcl │ │ ├── legomem_system_kv_virtual.tcl │ │ ├── legomem_system_no_relnet.tcl │ │ ├── legomem_system_release.tcl │ │ └── run_vivado.tcl └── soc │ ├── core │ ├── Makefile │ ├── axidma_ioctl.h │ ├── board.c │ ├── buddy.c │ ├── buddy.h │ ├── core.c │ ├── core.h │ ├── ctrl.c │ ├── dma.c │ ├── dma.h │ ├── drf.c │ ├── external.h │ ├── handler.c │ ├── include │ ├── libaxidma.c │ ├── libaxidma.h │ ├── log_ratio_1_pg_1.csv │ ├── log_ratio_1_pg_2.csv │ ├── log_ratio_2_pg_1.csv │ ├── log_ratio_2_pg_10.csv │ ├── log_ratio_2_pg_100.csv │ ├── log_ratio_2_pg_2.csv │ ├── log_ratio_2_pg_3.csv │ ├── page_fifo.c │ ├── pgtable.c │ ├── pgtable.h │ ├── rbtree.c │ ├── run.sh │ ├── scale1_pg1.csv │ ├── sched.c │ ├── session.c │ ├── shadow_pgtable.c │ ├── stat.c │ ├── test │ │ ├── test_buddy.c │ │ ├── test_clear_page.c │ │ ├── test_pgtable_access.c │ │ ├── test_vm_conflict.c │ │ └── test_vm_latency.c │ ├── tlbflush.c │ ├── util.c │ └── vm.c │ ├── lib │ └── axidma │ │ ├── LICENSE │ │ ├── Makefile │ │ ├── README.md │ │ ├── config_template.mk │ │ ├── driver │ │ ├── Kbuild │ │ ├── axi_dma.c │ │ ├── axidma.h │ │ ├── axidma_chrdev.c │ │ ├── axidma_dma.c │ │ ├── axidma_of.c │ │ └── driver.mk │ │ ├── examples │ │ ├── axidma_benchmark.c │ │ ├── axidma_display_image.c │ │ ├── axidma_transfer.c │ │ ├── conversion.h │ │ ├── examples.mk │ │ ├── util.c │ │ └── util.h │ │ ├── include │ │ ├── axidma_ioctl.h │ │ └── libaxidma.h │ │ ├── libaxidma.dox │ │ ├── library │ │ ├── libaxidma.c │ │ └── library.mk │ │ └── module │ │ ├── README │ │ ├── files │ │ ├── COPYING │ │ ├── Makefile │ │ ├── axi_dma.c │ │ ├── axidma.h │ │ ├── axidma_chrdev.c │ │ ├── axidma_dma.c │ │ ├── axidma_ioctl.h │ │ └── axidma_of.c │ │ └── xilinx-axidma.bb │ ├── linux │ └── golden │ │ ├── .gitignore │ │ ├── Makefile │ │ ├── README │ │ ├── README.hw │ │ ├── config.project │ │ └── project-spec │ │ ├── attributes │ │ ├── configs │ │ ├── config │ │ └── rootfs_config │ │ ├── hw-description │ │ ├── design_1_wrapper.mmi │ │ ├── metadata │ │ ├── psu_init.c │ │ ├── psu_init.h │ │ ├── psu_init.html │ │ ├── psu_init.tcl │ │ ├── psu_init_gpl.c │ │ ├── psu_init_gpl.h │ │ └── system.hdf │ │ └── meta-user │ │ ├── COPYING.MIT │ │ ├── README │ │ ├── conf │ │ ├── layer.conf │ │ └── petalinuxbsp.conf │ │ ├── recipes-apps │ │ ├── gpio-demo │ │ │ ├── files │ │ │ │ ├── Makefile │ │ │ │ └── gpio-demo.c │ │ │ └── gpio-demo.bb │ │ └── peekpoke │ │ │ ├── files │ │ │ ├── Makefile │ │ │ ├── peek.c │ │ │ └── poke.c │ │ │ └── peekpoke.bb │ │ ├── recipes-bsp │ │ ├── device-tree │ │ │ ├── device-tree.bbappend │ │ │ └── files │ │ │ │ ├── multi-arch │ │ │ │ ├── zynqmp-qemu-multiarch-arm.dts │ │ │ │ └── zynqmp-qemu-multiarch-pmu.dts │ │ │ │ ├── openamp.dtsi │ │ │ │ ├── system-user.dtsi │ │ │ │ ├── xen-qemu.dtsi │ │ │ │ ├── xen.dtsi │ │ │ │ └── zynqmp-qemu-arm.dts │ │ └── u-boot │ │ │ ├── files │ │ │ ├── bsp.cfg │ │ │ └── platform-top.h │ │ │ └── u-boot-xlnx_%.bbappend │ │ ├── recipes-core │ │ └── images │ │ │ └── petalinux-image-full.bbappend │ │ └── recipes-kernel │ │ └── linux │ │ ├── linux-xlnx │ │ ├── bsp.cfg │ │ └── user_2019-11-23-13-00-00.cfg │ │ └── linux-xlnx_%.bbappend │ └── scripts │ ├── copy_golden.sh │ └── rst.tcl ├── host ├── .gitignore ├── Makefile ├── README.md ├── api.c ├── api.h ├── api_kvs.c ├── api_kvs.h ├── api_mv.c ├── board.c ├── board_emulator │ ├── buddy.c │ ├── buddy.h │ ├── core.h │ ├── external.h │ ├── handler.c │ ├── pgtable.c │ ├── pgtable.h │ ├── rbtree.c │ ├── sched.c │ └── vm.c ├── common.c ├── config.h ├── context.c ├── core.h ├── cpu.c ├── lib │ └── bitmap.c ├── main_board.c ├── main_host.c ├── main_monitor.c ├── memory_model.c ├── net │ ├── core.c │ ├── net.h │ ├── raw_socket.c │ ├── raw_udp_socket.c │ ├── raw_verbs.c │ ├── transport_bypass.c │ ├── transport_gbn.c │ └── transport_rpc.c ├── pp.c ├── prepare.sh ├── rsrync.sh ├── scripts │ ├── test_alloc_free.sh │ ├── test_board.sh │ ├── test_conn.sh │ ├── test_data_frame.sh │ ├── test_jpeg.sh │ ├── test_kvs_simple.sh │ ├── test_migration.sh │ ├── test_pingpong_soc.sh │ ├── test_pointer_chasing.sh │ ├── test_pte.sh │ ├── test_raw_net.sh │ ├── test_read.sh │ ├── test_rel_net_mgmt.sh │ ├── test_rel_net_normal.sh │ ├── test_rw_presetup.sh │ ├── test_rw_processes.sh │ ├── test_rw_pte_mr.sh │ ├── test_rw_threads.sh │ ├── test_session.sh │ └── test_ycsb.sh ├── session.c ├── stat.h ├── test.sh ├── test │ ├── jpeg │ │ ├── Makefile │ │ ├── README.md │ │ ├── arrayclient.c │ │ ├── arrayserver.c │ │ ├── client.c │ │ ├── common.c │ │ ├── config.c │ │ ├── net-nng.c │ │ ├── net.c │ │ ├── rarray.c │ │ ├── rarray.h │ │ ├── rmem-legomem.c │ │ ├── rmem-rdma.c │ │ ├── rmem.h │ │ └── test.h │ ├── test_alloc.c │ ├── test_board.c │ ├── test_conn.c │ ├── test_context.c │ ├── test_data_frame.c │ ├── test_kvs_simple.c │ ├── test_kvs_ycsb.c │ ├── test_legomem_pte.c │ ├── test_memcpy.c │ ├── test_migration.c │ ├── test_pingpong_soc.c │ ├── test_pointer_chasing.c │ ├── test_raw_net.c │ ├── test_rdma_mr.c │ ├── test_rel_net_mgmt.c │ ├── test_rel_net_normal.c │ ├── test_rw_fault.c │ ├── test_rw_inline.c │ ├── test_rw_multiboard.c │ ├── test_rw_presetup.c │ ├── test_rw_processes.c │ ├── test_rw_pte_mr.c │ ├── test_rw_threads.c │ ├── test_rw_tlb.c │ ├── test_session.c │ ├── test_soc.c │ └── ycsb_datasets │ │ ├── workloada_parsed │ │ ├── workloadb_parsed │ │ └── workloadc_parsed ├── util.c └── watchdog.c ├── include ├── fpga │ ├── axis_internal.h │ ├── axis_net.h │ ├── fpga_memory_map.h │ ├── kernel.h │ ├── lego_mem_ctrl.h │ ├── lookup3.h │ ├── pgtable.h │ └── zynq_regmap.h └── uapi │ ├── bitmap.h │ ├── bitops.h │ ├── bitops_asm_generic.h │ ├── bitops_x86.h │ ├── compiler.h │ ├── err.h │ ├── gbn.h │ ├── hash.h │ ├── hashtable.h │ ├── lego_mem.h │ ├── list.h │ ├── log2.h │ ├── net_header.h │ ├── net_session.h │ ├── opcode.h │ ├── opcode_types.h │ ├── page.h │ ├── profile_point.h │ ├── rbtree.h │ ├── sched.h │ ├── stat.h │ ├── stringify.h │ ├── thpool.h │ ├── tlb.h │ └── vregion.h └── tests └── scripts ├── activate ├── clio-reconfig └── clio-test /.github/labeler.yml: -------------------------------------------------------------------------------- 1 | # Details: https://github.com/actions/labeler/blob/master/README.md 2 | 3 | host_net: 4 | - host/net/* 5 | 6 | host: 7 | - host/* 8 | 9 | monitor: 10 | - monitor/* 11 | 12 | board_fpga: 13 | - board/fpga/* 14 | 15 | board_soc: 16 | - board/soc/* 17 | -------------------------------------------------------------------------------- /.github/workflows/ccpp.yml: -------------------------------------------------------------------------------- 1 | # 2 | # This workflow will compile the code and report compiling errors 3 | # 4 | name: C CI 5 | on: [pull_request] 6 | 7 | jobs: 8 | build: 9 | 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - uses: actions/checkout@v2 14 | - name: prepare 15 | run: sudo apt-get -y install rdma-core libibverbs1 libibverbs-dev 16 | - name: make_host_monitor 17 | run: cd host && make 18 | -------------------------------------------------------------------------------- /.github/workflows/label.yml: -------------------------------------------------------------------------------- 1 | # This workflow will triage pull requests and apply a label based on the 2 | # paths that are modified in the pull request. 3 | # 4 | # To use this workflow, you will need to set up a .github/labeler.yml 5 | # file with configuration. For more information, see: 6 | # https://github.com/actions/labeler/blob/master/README.md 7 | 8 | name: Labeler 9 | on: [pull_request] 10 | 11 | jobs: 12 | label: 13 | 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - uses: actions/labeler@v2 18 | with: 19 | repo-token: "${{ secrets.GITHUB_TOKEN }}" 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | *.log 3 | *.bak 4 | 5 | # sbt specific 6 | .cache/ 7 | .history/ 8 | .lib/ 9 | dist/* 10 | target 11 | lib_managed/ 12 | src_managed/ 13 | project/boot/ 14 | project/plugins/project/ 15 | 16 | # Scala-IDE specific 17 | .scala_dependencies 18 | .worksheet 19 | 20 | .idea 21 | out 22 | 23 | # Eclipse 24 | bin/ 25 | .classpath 26 | .project 27 | .settings 28 | .cache-main 29 | 30 | #User 31 | /*.vhd 32 | /*.v 33 | *.cf 34 | *.json 35 | *.vcd 36 | !tester/src/test/resources/*.vhd 37 | 38 | 39 | simWorkspace/ 40 | tmp/ 41 | 42 | 43 | .* 44 | *.o 45 | *.out 46 | 47 | # Vivado Related 48 | *.log 49 | *.jou 50 | *.str 51 | *.mcs 52 | *.prm 53 | *.bit 54 | 55 | # Bitstream Related 56 | *.bin 57 | *.bit 58 | *.ll 59 | *.ltx 60 | 61 | # Generated HLS project folder 62 | # Listed in template file as well 63 | generated_hls_project/ 64 | generated_vivado_project/ 65 | relnet_512/ 66 | sdk_project/ 67 | *.backup/ 68 | 69 | # Generated IP repositories 70 | generated_ip/ 71 | 72 | # Linux Kernel Related 73 | *.symvers 74 | *.ko 75 | *.order 76 | *.mod.c 77 | 78 | # AWS Specific 79 | awsver.txt 80 | 81 | tags 82 | 83 | !.github/ 84 | !.gitignore 85 | !.clang-format 86 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "board/fpga/src/lib/verilog/verilog-axi"] 2 | path = board/fpga/src/lib/verilog/verilog-axi 3 | url = https://github.com/alexforencich/verilog-axi 4 | [submodule "board/fpga/src/lib/verilog/verilog-axis"] 5 | path = board/fpga/src/lib/verilog/verilog-axis 6 | url = https://github.com/alexforencich/verilog-axis.git 7 | -------------------------------------------------------------------------------- /Documentation/arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WukLab/Clio/7908c3a022fd356cd54616630fcddf59f7f3fd95/Documentation/arch.png -------------------------------------------------------------------------------- /Documentation/debug.md: -------------------------------------------------------------------------------- 1 | # Clio Debugging 2 | 3 | ## FPGA ARM 4 | 5 | Copy paste the following code snippt on the ARM Linux. 6 | Run `bash fpga_counter_reg.sh` to dump real time counters. 7 | 8 | ```bash 9 | cat > fpga_counter_reg.sh < 17 | ``` 18 | -------------------------------------------------------------------------------- /Documentation/testbed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WukLab/Clio/7908c3a022fd356cd54616630fcddf59f7f3fd95/Documentation/testbed.png -------------------------------------------------------------------------------- /Documentation/testbed2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WukLab/Clio/7908c3a022fd356cd54616630fcddf59f7f3fd95/Documentation/testbed2.png -------------------------------------------------------------------------------- /Documentation/vivado-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WukLab/Clio/7908c3a022fd356cd54616630fcddf59f7f3fd95/Documentation/vivado-screenshot.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 WukLab 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. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Clio System 2 | 3 | Clio is a disaggregated memory system that virtualizes, 4 | protects, and manages disaggregated memory at hardware-based 5 | memory nodes. More details in our ASPLOS'22 paper [here](https://arxiv.org/pdf/2108.03492.pdf). 6 | 7 | This repo contains Clio's FPGA hardware design, host side software, and testing program. 8 | 9 | ## System Architetcure 10 | 11 | The Clio hardware includes a new virtual memory 12 | system, a customized network system, and a framework for computation offloading 13 | 14 | drawing 15 | 16 | ## Documentation 17 | 18 | Clio system has three major parts: the FPGA bitstream part, the ARM SoC part, and the host-side software. 19 | 20 | To compile Clio, see [Documentation/compile.md](./Documentation/compile.md). 21 | 22 | To run Clio, see [Documentation/run.md](./Documentation/run.md). 23 | 24 | To debug Clio, see [Documentation/debug.md](./Documentation/debug.md). 25 | 26 | **ASPLOS'22 Artifact Evaluators, please see [Documentation/asplos-ae.md](./Documentation/asplos-ae.md).** 27 | 28 | ## Repo Layout 29 | 30 | High-level layout: 31 | 32 | drawing 33 | 34 | FPGA side stack layout: 35 | 36 | drawing 37 | 38 | Host side stack layout: 39 | 40 | drawing 41 | 42 | 43 | ## License 44 | 45 | MIT 46 | 47 | ## Disclaimer 48 | 49 | This is a research prototype. Use at your own risk. 50 | 51 | ## Help 52 | 53 | Please use [Github Issues](https://github.com/WukLab/Clio/issues). 54 | -------------------------------------------------------------------------------- /board/fpga/.gitignore: -------------------------------------------------------------------------------- 1 | project/ 2 | 3 | generated_ip/ 4 | generated_rtl/ 5 | 6 | LegoMemSystemLib.v 7 | -------------------------------------------------------------------------------- /board/fpga/Makefile.mk: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2020-2021, Wuklab, UCSD. 3 | # 4 | 5 | # 6 | # We use 2019.1 for both HLS and Vivado projects. 7 | # 8 | 9 | VIVADO = /tools/Xilinx/Vivado/2019.1/bin/vivado 10 | -------------------------------------------------------------------------------- /board/fpga/README.md: -------------------------------------------------------------------------------- 1 | # LegoMem FPGA 2 | 3 | ## Code Layout 4 | 5 | - `generated_ip/`: collects all generated IPs throughout the project. 6 | - `net_reliable/`: our reliable go-back-n network layer, exporting a single big `relnet` IP. 7 | - `top/`: including both Alex's original eth/ip/udp stack and legomem core BD. 8 | This is the top-level design. 9 | -------------------------------------------------------------------------------- /board/fpga/build.sbt: -------------------------------------------------------------------------------- 1 | name := "SpinalTemplateSbt" 2 | 3 | version := "1.0" 4 | 5 | scalaVersion := "2.11.12" 6 | 7 | libraryDependencies ++= Seq( 8 | "com.github.spinalhdl" % "spinalhdl-core_2.11" % "1.3.8", 9 | "com.github.spinalhdl" % "spinalhdl-lib_2.11" % "1.3.8", 10 | "org.scodec" %% "scodec-bits" % "1.1.12", 11 | "org.scodec" %% "scodec-core" % "1.11.4", 12 | "com.lihaoyi" %% "pprint" % "0.5.4" 13 | ) 14 | 15 | fork := true 16 | -------------------------------------------------------------------------------- /board/fpga/net_reliable/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2020, Wuklab, UCSD. 3 | # 4 | 5 | include ../Makefile.mk 6 | 7 | GCC = gcc 8 | 9 | HLS_IP_CORES := hls_rx,hls_tx,state_table,setup_manager,hls_timer,tx_arbiter,unacked_buffer,broadcast_filter 10 | 11 | all: 12 | $(Q)./generate_hls.sh $(HLS_IP_CORES) 13 | $(VIVADO) -mode tcl -source run_vivado.tcl 14 | 15 | test: 16 | $(GCC) test_onboard.c -I../../../include -o test_onboard.out 17 | 18 | hls: 19 | $(Q)./generate_hls.sh $(HLS_IP_CORES) 20 | 21 | g: 22 | $(VIVADO) generated_vivado_project/generated_vivado_project.xpr & 23 | 24 | clean: 25 | find ./ -name "generated_hls_project" | xargs rm -rf 26 | find ./ -name "generated_vivado_project" | xargs rm -rf 27 | find ./ -name "*.log" | xargs rm -rf 28 | find ./ -name "*.jou" | xargs rm -rf 29 | find ./ -name "*.str" | xargs rm -rf 30 | find ./ -name ".Xil" | xargs rm -rf 31 | find ./ -name "awsver.txt" | xargs rm -rf 32 | -------------------------------------------------------------------------------- /board/fpga/net_reliable/README.md: -------------------------------------------------------------------------------- 1 | # Go-Back-N Reliable Network 2 | Last Updated: Mar 26, 2020 3 | 4 | Note that we will export a final big IP to the shared `generated_ip/` folder. 5 | The IP folder name is described by the last line of `run_vivado.tcl`: 6 | 7 | ``` 8 | ipx::package_project -root_dir ../generated_ip/net_top_relnet_zcu106 -vendor wuklab -library user -taxonomy UserIP -module relnet -import_files 9 | ``` 10 | 11 | ## Introduction 12 | This is a Go-Back-N based reliable network built on top of UDP network stack. It consists of several parts. Their functions are described as below. 13 | 14 | ### Reliable receiver 15 | - Receive data packet, send gbn header to state table for seqnum checking, deliever to onboard pipeline according to check result. 16 | - Receive ack/nack packet, send to state table for dequeue. 17 | 18 | ### Reliable sender 19 | - Get data from onboard pipeline, check with state table to get the seqnum. 20 | - Append seqnum, send out to network and store it in unacked packet buffer. 21 | 22 | ### Net session state table 23 | #### State table 24 | - Check seqnum of received data packets and send ACK/NACK response accordingly. 25 | - Check seqnum of received ack/nack packets and perform dequeue and issue retransmission requests accordingly. 26 | - Check if buffer for certain session is full and tell sender the seqnum to sent. 27 | #### Timer 28 | - Store the timeout for every net session 29 | - Reset/stop timer for certain session according to request 30 | - Generate timeout signal upon timeout event 31 | #### Setup manager 32 | - Accept connection open/close request and set the session state and timer 33 | 34 | ### Unacked packets buffer 35 | - Store sent out packets into dram 36 | - Retransmit unacked packet upon receiving retransmission request. 37 | 38 | ### Send arbiter 39 | - Arbitrate between response packet, normal send-out packet and retransmission packets 40 | - Priority: rsp > retrans > normal 41 | 42 | ## Configuration 43 | There are a few configurations in `include/uapi/gbn.h` 44 | - `MAX_PACKET_SIZE`: The size in byte of the largest packet that can be stored in the unacked packet queue. Default value is 9216(9 kb) 45 | - `WINDOW_SIZE`: The max num of packets that can be sent out without acknowledgement. Default value is 128. 46 | - `NR_MAX_SESSIONS_PER_NODE`: Maximum number of connection, default value is 1024. 47 | - `RETRANS_TIMEOUT_CYCLE`: Retransmission timeout in clock cycles. Default is 100000000 cycles(4ms). 48 | -------------------------------------------------------------------------------- /board/fpga/net_reliable/broadcast_filter/Makefile: -------------------------------------------------------------------------------- 1 | # DO NOT CHANGE THIS. This is coded through the repo 2 | project_path=generated_hls_project 3 | 4 | VIVADO_HLS = vivado_hls 5 | 6 | ifeq ($(TARGET_BOARD), ) 7 | TARGET_BOARD = zcu106 8 | endif 9 | 10 | all: 11 | $(VIVADO_HLS) -f run_hls.tcl -tclargs $(TARGET_BOARD) 12 | 13 | g: 14 | $(VIVADO_HLS) -p $(project_path) & 15 | 16 | clean: 17 | rm -rf $(project_path) 18 | find ./ -name "*.log" | xargs rm -rf 19 | find ./ -name "*.jou" | xargs rm -rf 20 | find ./ -name "*.str" | xargs rm -rf 21 | find ./ -name ".Xil" | xargs rm -rf 22 | 23 | help: 24 | @echo "Help" 25 | @echo " # make <- Compile projects" 26 | @echo " # make g <- Open GUI" 27 | -------------------------------------------------------------------------------- /board/fpga/net_reliable/broadcast_filter/filter_64.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RELNET_FILTER64_H_ 2 | #define _RELNET_FILTER64_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using hls::stream; 10 | 11 | void filter_64(stream *rx_header, 12 | stream *rx_payload, 13 | stream *usr_rx_header, 14 | stream *usr_rx_payload); 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /board/fpga/net_reliable/broadcast_filter/filter_64_top.cpp: -------------------------------------------------------------------------------- 1 | #include "filter_64.hpp" 2 | 3 | enum rx_status { 4 | RX_STATE_UDP_HEADER, 5 | RX_STATE_DELIVER_DATA 6 | }; 7 | 8 | void filter_64(stream *rx_header, 9 | stream *rx_payload, 10 | stream *usr_rx_header, 11 | stream *usr_rx_payload) 12 | { 13 | #pragma HLS INTERFACE axis both port=rx_header 14 | #pragma HLS INTERFACE axis both port=rx_payload 15 | #pragma HLS INTERFACE axis both port=usr_rx_header 16 | #pragma HLS INTERFACE axis both port=usr_rx_payload 17 | 18 | #pragma HLS DATA_PACK variable=rx_header 19 | #pragma HLS DATA_PACK variable=usr_rx_header 20 | 21 | #pragma HLS INTERFACE ap_ctrl_none port=return 22 | #pragma HLS PIPELINE 23 | 24 | static enum rx_status state = RX_STATE_UDP_HEADER; 25 | 26 | static struct net_axis_64 recv_pkt; 27 | static struct udp_info recv_udp_info; 28 | static bool deliver_data = false; 29 | 30 | switch (state) { 31 | case RX_STATE_UDP_HEADER: 32 | if (rx_header->empty() || rx_payload->empty()) 33 | break; 34 | recv_udp_info = rx_header->read(); 35 | 36 | if (recv_udp_info.dest_ip(7, 0) == 0xff) { 37 | deliver_data = false; 38 | state = RX_STATE_DELIVER_DATA; 39 | break; 40 | } 41 | 42 | deliver_data = true; 43 | usr_rx_header->write(recv_udp_info); 44 | state = RX_STATE_DELIVER_DATA; 45 | break; 46 | case RX_STATE_DELIVER_DATA: 47 | if (rx_payload->empty()) 48 | break; 49 | 50 | recv_pkt = rx_payload->read(); 51 | 52 | if (deliver_data) 53 | usr_rx_payload->write(recv_pkt); 54 | if (recv_pkt.last == 1) { 55 | state = RX_STATE_UDP_HEADER; 56 | deliver_data = false; 57 | } 58 | break; 59 | default: 60 | break; 61 | } 62 | } 63 | 64 | -------------------------------------------------------------------------------- /board/fpga/net_reliable/broadcast_filter/run_hls.tcl: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2020, Wuklab, UCSD. 3 | # 4 | 5 | # If the script is run in this way: 6 | # vivado_hls -f run_hls.tcl -tclargs $(TARGET_BOARD) 7 | set board "[lindex $argv 2]" 8 | 9 | # Create a project 10 | open_project -reset generated_hls_project 11 | 12 | add_files filter_64_top.cpp -cflags -I../../../../include/ 13 | #add_files -tb tb.cpp -cflags -I../../../../include/ 14 | 15 | # Specify the top-level function for synthesis 16 | set_top filter_64 17 | 18 | ########################### 19 | # Solution settings 20 | 21 | # Create solution1 22 | open_solution -reset solution1 23 | 24 | # Specify a Xilinx device and clock period 25 | # 26 | # VCU118: xcvu9p-flga2104-1-i 27 | # VCU108: xcvu095-ffva2104-2-e 28 | # ZCU106: xczu7ev-ffvc1156-2-e 29 | # ArtyA7: xc7a100tcsg324-1 30 | switch $board { 31 | vcu118 { 32 | set_part {xcvu9p-flga2104-1-i} 33 | } 34 | vcu108 { 35 | set_part {xcvu095-ffva2104-2-e} 36 | } 37 | zcu106 { 38 | set_part {xczu7ev-ffvc1156-2-e} 39 | } 40 | default { 41 | puts "Unknown board: $board" 42 | exit 43 | } 44 | } 45 | create_clock -period 4.00 -name default 46 | set_clock_uncertainty 0.25 47 | 48 | # UG902: Resets all registers and memories in the design. 49 | # Any static or global variable variables initialized in the C 50 | # code is reset to its initialized value. 51 | config_rtl -reset all -reset_async 52 | 53 | # Simulate the C code 54 | #csim_design 55 | 56 | # Synthesis the C code 57 | csynth_design 58 | 59 | # Export IP block 60 | export_design -format ip_catalog -display_name "broadcast_filter" -description "filter broadcast packet" -vendor "Wuklab.UCSD" -version "1.0" 61 | 62 | # Do not perform any other steps 63 | # - The basic project will be opened in the GUI 64 | exit 65 | -------------------------------------------------------------------------------- /board/fpga/net_reliable/dummy_setup/Makefile: -------------------------------------------------------------------------------- 1 | # DO NOT CHANGE THIS. This is coded through the repo 2 | project_path=generated_hls_project 3 | 4 | VIVADO_HLS = vivado_hls 5 | 6 | ifeq ($(TARGET_BOARD), ) 7 | TARGET_BOARD = zcu106 8 | endif 9 | 10 | all: 11 | $(VIVADO_HLS) -f run_hls.tcl -tclargs $(TARGET_BOARD) 12 | 13 | g: 14 | $(VIVADO_HLS) -p $(project_path) & 15 | 16 | clean: 17 | rm -rf $(project_path) 18 | find ./ -name "*.log" | xargs rm -rf 19 | find ./ -name "*.jou" | xargs rm -rf 20 | find ./ -name "*.str" | xargs rm -rf 21 | find ./ -name ".Xil" | xargs rm -rf 22 | 23 | help: 24 | @echo "Help" 25 | @echo " # make <- Compile projects" 26 | @echo " # make g <- Open GUI" 27 | -------------------------------------------------------------------------------- /board/fpga/net_reliable/dummy_setup/run_hls.tcl: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2020, Wuklab, UCSD. 3 | # 4 | 5 | # If the script is run in this way: 6 | # vivado_hls -f run_hls.tcl -tclargs $(TARGET_BOARD) 7 | set board "[lindex $argv 2]" 8 | 9 | # Create a project 10 | open_project -reset generated_hls_project 11 | 12 | add_files dummy_setup.cpp -cflags -I../../../../include/ 13 | 14 | # Specify the top-level function for synthesis 15 | set_top dummy_setup 16 | 17 | ########################### 18 | # Solution settings 19 | 20 | # Create solution1 21 | open_solution -reset solution1 22 | 23 | # Specify a Xilinx device and clock period 24 | # 25 | # VCU118: xcvu9p-flga2104-1-i 26 | # VCU108: xcvu095-ffva2104-2-e 27 | # ZCU106: xczu7ev-ffvc1156-2-e 28 | # ArtyA7: xc7a100tcsg324-1 29 | switch $board { 30 | vcu118 { 31 | set_part {xcvu9p-flga2104-1-i} 32 | } 33 | vcu108 { 34 | set_part {xcvu095-ffva2104-2-e} 35 | } 36 | zcu106 { 37 | set_part {xczu7ev-ffvc1156-2-e} 38 | } 39 | default { 40 | puts "Unknown board: $board" 41 | exit 42 | } 43 | } 44 | create_clock -period 4.00 -name default 45 | set_clock_uncertainty 0.25 46 | 47 | # UG902: Resets all registers and memories in the design. 48 | # Any static or global variable variables initialized in the C 49 | # code is reset to its initialized value. 50 | config_rtl -reset all -reset_async 51 | 52 | # Simulate the C code 53 | #csim_design 54 | 55 | # Synthesis the C code 56 | csynth_design 57 | 58 | # Export IP block 59 | export_design -format ip_catalog -display_name "dummy_setup_hls" -description "" -vendor "Wuklab.UCSD" -version "1.0" 60 | 61 | # Do not perform any other steps 62 | # - The basic project will be opened in the GUI 63 | exit 64 | -------------------------------------------------------------------------------- /board/fpga/net_reliable/generate_hls.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2020, Wuklab, UCSD 4 | # 5 | # This script automate the process of creating multiple HLS projects. 6 | # It should be a level higher than run_hls.tcl. This is used to run 7 | # multiple run_hls.tcl scripts. 8 | # 9 | # To customize 10 | # 1) Modify HLS_IP_CORES list 11 | # 2) Modify GENERATED_IP_FOLDER to reflect the path 12 | # 3) Modify the PREFIX of generated IP folders 13 | 14 | TARGET_BOARD=zcu106 15 | HLS_IP=$1 16 | 17 | # Change the absolute path to your own one. 18 | VIVADO_HLS=' /tools/Xilinx/Vivado/2019.1/bin/vivado_hls' 19 | 20 | # Hardcoded through projects 21 | GENERATED_HLS_PROJECT="generated_hls_project" 22 | HLS_DIR="$PWD" 23 | 24 | # Customize: relative path 25 | GENERATED_IP_FOLDER="${HLS_DIR}/../generated_ip" 26 | 27 | # Customize: new IP folder prefix 28 | PREFIX=net 29 | 30 | # Check if the shared IP repo exists 31 | if [ ! -d "$GENERATED_IP_FOLDER" ]; then 32 | mkdir "$GENERATED_IP_FOLDER" 33 | fi 34 | 35 | IFS=',' read -r -a HLS_IP_CORES <<< "$HLS_IP" 36 | # Rolling for each HLS IP in this directory 37 | for ip in "${HLS_IP_CORES[@]}"; do 38 | NEW_IP_REPO="${GENERATED_IP_FOLDER}/${PREFIX}_${ip}_${TARGET_BOARD}" 39 | eval cd ${HLS_DIR}/${ip} 40 | 41 | # Run the HLS script accoding to board 42 | eval ${VIVADO_HLS} -f run_hls.tcl -tclargs ${TARGET_BOARD} 43 | 44 | if [ ! -d ${NEW_IP_REPO} ]; then 45 | mkdir ${NEW_IP_REPO} 46 | fi 47 | 48 | zipname=`ls ${GENERATED_HLS_PROJECT}/solution1/impl/ip/*.zip` 49 | zipname=$(basename ${zipname}) 50 | zipnamelen=${#zipname} 51 | 52 | # Skip the suffix ".zip" 53 | zipdir=${zipname:0:${zipnamelen}-4} 54 | 55 | # Copy the IP archive into shared IP repo 56 | eval cp ${GENERATED_HLS_PROJECT}/solution1/impl/ip/${zipname} ${NEW_IP_REPO}/ 57 | unzip -o ${NEW_IP_REPO}/${zipname} -d ${NEW_IP_REPO}/${zipdir} 58 | done 59 | -------------------------------------------------------------------------------- /board/fpga/net_reliable/hls_rx/Makefile: -------------------------------------------------------------------------------- 1 | # DO NOT CHANGE THIS. This is coded through the repo 2 | project_path=generated_hls_project 3 | 4 | VIVADO_HLS = vivado_hls 5 | 6 | ifeq ($(TARGET_BOARD), ) 7 | TARGET_BOARD = zcu106 8 | endif 9 | 10 | all: 11 | $(VIVADO_HLS) -f run_hls.tcl -tclargs $(TARGET_BOARD) 12 | 13 | g: 14 | $(VIVADO_HLS) -p $(project_path) & 15 | 16 | clean: 17 | rm -rf $(project_path) 18 | find ./ -name "*.log" | xargs rm -rf 19 | find ./ -name "*.jou" | xargs rm -rf 20 | find ./ -name "*.str" | xargs rm -rf 21 | find ./ -name ".Xil" | xargs rm -rf 22 | 23 | help: 24 | @echo "Help" 25 | @echo " # make <- Compile projects" 26 | @echo " # make g <- Open GUI" 27 | -------------------------------------------------------------------------------- /board/fpga/net_reliable/hls_rx/run_hls.tcl: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2020, Wuklab, UCSD. 3 | # 4 | 5 | # If the script is run in this way: 6 | # vivado_hls -f run_hls.tcl -tclargs $(TARGET_BOARD) 7 | set board "[lindex $argv 2]" 8 | 9 | # Create a project 10 | open_project -reset generated_hls_project 11 | 12 | add_files rx_64_top.cpp -cflags -I../../../../include/ 13 | add_files -tb tb.cpp -cflags -I../../../../include/ 14 | 15 | # Specify the top-level function for synthesis 16 | set_top rx_64 17 | 18 | ########################### 19 | # Solution settings 20 | 21 | # Create solution1 22 | open_solution -reset solution1 23 | 24 | # Specify a Xilinx device and clock period 25 | # 26 | # VCU118: xcvu9p-flga2104-1-i 27 | # VCU108: xcvu095-ffva2104-2-e 28 | # ZCU106: xczu7ev-ffvc1156-2-e 29 | # ArtyA7: xc7a100tcsg324-1 30 | switch $board { 31 | vcu118 { 32 | set_part {xcvu9p-flga2104-1-i} 33 | } 34 | vcu108 { 35 | set_part {xcvu095-ffva2104-2-e} 36 | } 37 | zcu106 { 38 | set_part {xczu7ev-ffvc1156-2-e} 39 | } 40 | default { 41 | puts "Unknown board: $board" 42 | exit 43 | } 44 | } 45 | create_clock -period 4.00 -name default 46 | set_clock_uncertainty 0.25 47 | 48 | # UG902: Resets all registers and memories in the design. 49 | # Any static or global variable variables initialized in the C 50 | # code is reset to its initialized value. 51 | config_rtl -reset all -reset_async 52 | 53 | # Simulate the C code 54 | #csim_design 55 | 56 | # Synthesis the C code 57 | csynth_design 58 | 59 | # Export IP block 60 | export_design -format ip_catalog -display_name "relnet_rx_hls" -description "reliable network receiver HLS" -vendor "Wuklab.UCSD" -version "1.0" 61 | 62 | # Do not perform any other steps 63 | # - The basic project will be opened in the GUI 64 | exit 65 | -------------------------------------------------------------------------------- /board/fpga/net_reliable/hls_rx/rx_64.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RELNET_RX64_H_ 2 | #define _RELNET_RX64_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | using hls::stream; 11 | 12 | void rx_64(stream *rx_header, 13 | stream *rx_payload, 14 | stream *state_query_req, 15 | stream *state_query_rsp, 16 | stream *usr_rx_header, 17 | stream *usr_rx_payload); 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /board/fpga/net_reliable/hls_timer/Makefile: -------------------------------------------------------------------------------- 1 | # DO NOT CHANGE THIS. This is coded through the repo 2 | project_path=generated_hls_project 3 | 4 | VIVADO_HLS = vivado_hls 5 | 6 | ifeq ($(TARGET_BOARD), ) 7 | TARGET_BOARD = zcu106 8 | endif 9 | 10 | all: 11 | $(VIVADO_HLS) -f run_hls.tcl -tclargs $(TARGET_BOARD) 12 | 13 | g: 14 | $(VIVADO_HLS) -p $(project_path) & 15 | 16 | clean: 17 | rm -rf $(project_path) 18 | find ./ -name "*.log" | xargs rm -rf 19 | find ./ -name "*.jou" | xargs rm -rf 20 | find ./ -name "*.str" | xargs rm -rf 21 | find ./ -name ".Xil" | xargs rm -rf 22 | 23 | help: 24 | @echo "Help" 25 | @echo " # make <- Compile projects" 26 | @echo " # make g <- Open GUI" 27 | -------------------------------------------------------------------------------- /board/fpga/net_reliable/hls_timer/run_hls.tcl: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2020, Wuklab, UCSD. 3 | # 4 | 5 | # If the script is run in this way: 6 | # vivado_hls -f run_hls.tcl -tclargs $(TARGET_BOARD) 7 | set board "[lindex $argv 2]" 8 | 9 | # Create a project 10 | open_project -reset generated_hls_project 11 | 12 | add_files timer_top.cpp -cflags -I../../../../include/ 13 | add_files -tb tb.cpp -cflags -I../../../../include/ 14 | 15 | # Specify the top-level function for synthesis 16 | set_top retrans_timer 17 | 18 | ########################### 19 | # Solution settings 20 | 21 | # Create solution1 22 | open_solution -reset solution1 23 | 24 | # Specify a Xilinx device and clock period 25 | # 26 | # VCU118: xcvu9p-flga2104-1-i 27 | # VCU108: xcvu095-ffva2104-2-e 28 | # ZCU106: xczu7ev-ffvc1156-2-e 29 | # ArtyA7: xc7a100tcsg324-1 30 | switch $board { 31 | vcu118 { 32 | set_part {xcvu9p-flga2104-1-i} 33 | } 34 | vcu108 { 35 | set_part {xcvu095-ffva2104-2-e} 36 | } 37 | zcu106 { 38 | set_part {xczu7ev-ffvc1156-2-e} 39 | } 40 | default { 41 | puts "Unknown board: $board" 42 | exit 43 | } 44 | } 45 | create_clock -period 4.00 -name default 46 | set_clock_uncertainty 0.25 47 | 48 | # UG902: Resets all registers and memories in the design. 49 | # Any static or global variable variables initialized in the C 50 | # code is reset to its initialized value. 51 | config_rtl -reset all -reset_async 52 | 53 | # Simulate the C code 54 | #csim_design 55 | 56 | # Synthesis the C code 57 | csynth_design 58 | 59 | # Export IP block 60 | export_design -format ip_catalog -display_name "relnet_timer" -description "reliable network retransmission timer HLS" -vendor "Wuklab.UCSD" -version "1.0" 61 | 62 | # Do not perform any other steps 63 | # - The basic project will be opened in the GUI 64 | exit 65 | -------------------------------------------------------------------------------- /board/fpga/net_reliable/hls_timer/tb.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020,Wuklab, UCSD. 3 | */ 4 | #define RETRANS_TIMEOUT_CYCLE 2 5 | 6 | #include "timer.hpp" 7 | 8 | int main() 9 | { 10 | stream timer_rst_req; 11 | stream > rt_timeout_sig; 12 | 13 | struct timer_req set_req; 14 | set_req.rst_type = timer_rst_type_reset; 15 | set_req.slotid = 42; 16 | timer_rst_req.write(set_req); 17 | 18 | for (int i = 0; i < (NR_MAX_SESSIONS_PER_NODE * (RETRANS_TIMEOUT_CYCLE + 1)); i++) { 19 | retrans_timer(&timer_rst_req, &rt_timeout_sig); 20 | 21 | if (!rt_timeout_sig.empty()) { 22 | ap_uint slotid = rt_timeout_sig.read(); 23 | dph("slot %d timeout\n", slotid.to_ushort()); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /board/fpga/net_reliable/hls_timer/timer.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RELNET_TIMER_H_ 2 | #define _RELNET_TIMER_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "../state_table/statetable_64.hpp" 9 | 10 | using hls::stream; 11 | 12 | void retrans_timer(stream *timer_rst_req, 13 | stream > *rt_timeout_sig); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /board/fpga/net_reliable/hls_tx/Makefile: -------------------------------------------------------------------------------- 1 | # DO NOT CHANGE THIS. This is coded through the repo 2 | project_path=generated_hls_project 3 | 4 | VIVADO_HLS = vivado_hls 5 | 6 | ifeq ($(TARGET_BOARD), ) 7 | TARGET_BOARD = zcu106 8 | endif 9 | 10 | all: 11 | $(VIVADO_HLS) -f run_hls.tcl -tclargs $(TARGET_BOARD) 12 | 13 | g: 14 | $(VIVADO_HLS) -p $(project_path) & 15 | 16 | clean: 17 | rm -rf $(project_path) 18 | find ./ -name "*.log" | xargs rm -rf 19 | find ./ -name "*.jou" | xargs rm -rf 20 | find ./ -name "*.str" | xargs rm -rf 21 | find ./ -name ".Xil" | xargs rm -rf 22 | 23 | help: 24 | @echo "Help" 25 | @echo " # make <- Compile projects" 26 | @echo " # make g <- Open GUI" 27 | -------------------------------------------------------------------------------- /board/fpga/net_reliable/hls_tx/run_hls.tcl: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2020, Wuklab, UCSD. 3 | # 4 | 5 | # If the script is run in this way: 6 | # vivado_hls -f run_hls.tcl -tclargs $(TARGET_BOARD) 7 | set board "[lindex $argv 2]" 8 | 9 | # Create a project 10 | open_project -reset generated_hls_project 11 | 12 | add_files tx_64_top.cpp -cflags -I../../../../include/ 13 | add_files -tb tb.cpp -cflags -I../../../../include/ 14 | 15 | # Specify the top-level function for synthesis 16 | set_top tx_64 17 | 18 | ########################### 19 | # Solution settings 20 | 21 | # Create solution1 22 | open_solution -reset solution1 23 | 24 | # Specify a Xilinx device and clock period 25 | # 26 | # VCU118: xcvu9p-flga2104-1-i 27 | # VCU108: xcvu095-ffva2104-2-e 28 | # ZCU106: xczu7ev-ffvc1156-2-e 29 | # ArtyA7: xc7a100tcsg324-1 30 | switch $board { 31 | vcu118 { 32 | set_part {xcvu9p-flga2104-1-i} 33 | } 34 | vcu108 { 35 | set_part {xcvu095-ffva2104-2-e} 36 | } 37 | zcu106 { 38 | set_part {xczu7ev-ffvc1156-2-e} 39 | } 40 | default { 41 | puts "Unknown board: $board" 42 | exit 43 | } 44 | } 45 | create_clock -period 4.00 -name default 46 | set_clock_uncertainty 0.25 47 | 48 | # UG902: Resets all registers and memories in the design. 49 | # Any static or global variable variables initialized in the C 50 | # code is reset to its initialized value. 51 | config_rtl -reset all -reset_async 52 | 53 | # Simulate the C code 54 | #csim_design 55 | 56 | # Synthesis the C code 57 | csynth_design 58 | 59 | # Export IP block 60 | export_design -format ip_catalog -display_name "relnet_tx_hls" -description "reliable network sender HLS" -vendor "Wuklab.UCSD" -version "1.0" 61 | 62 | # Do not perform any other steps 63 | # - The basic project will be opened in the GUI 64 | exit 65 | -------------------------------------------------------------------------------- /board/fpga/net_reliable/hls_tx/tx_64.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RELNET_TX64_H_ 2 | #define _RELNET_TX64_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | using hls::stream; 11 | 12 | void tx_64(stream *tx_header, 13 | stream *tx_payload, 14 | stream *usr_tx_header, 15 | stream *usr_tx_payload, 16 | stream > *check_full_req, 17 | stream > *check_full_rsp, 18 | stream *tx_finish_sig, 19 | stream *tx_buff_payload, 20 | stream *tx_buff_route_info); 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /board/fpga/net_reliable/lib: -------------------------------------------------------------------------------- 1 | ../top/lib/ -------------------------------------------------------------------------------- /board/fpga/net_reliable/rtl: -------------------------------------------------------------------------------- 1 | ../top/rtl/ -------------------------------------------------------------------------------- /board/fpga/net_reliable/setup_manager/Makefile: -------------------------------------------------------------------------------- 1 | # DO NOT CHANGE THIS. This is coded through the repo 2 | project_path=generated_hls_project 3 | 4 | VIVADO_HLS = vivado_hls 5 | 6 | ifeq ($(TARGET_BOARD), ) 7 | TARGET_BOARD = zcu106 8 | endif 9 | 10 | all: 11 | $(VIVADO_HLS) -f run_hls.tcl -tclargs $(TARGET_BOARD) 12 | 13 | g: 14 | $(VIVADO_HLS) -p $(project_path) & 15 | 16 | clean: 17 | rm -rf $(project_path) 18 | find ./ -name "*.log" | xargs rm -rf 19 | find ./ -name "*.jou" | xargs rm -rf 20 | find ./ -name "*.str" | xargs rm -rf 21 | find ./ -name ".Xil" | xargs rm -rf 22 | 23 | help: 24 | @echo "Help" 25 | @echo " # make <- Compile projects" 26 | @echo " # make g <- Open GUI" 27 | -------------------------------------------------------------------------------- /board/fpga/net_reliable/setup_manager/run_hls.tcl: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2020, Wuklab, UCSD. 3 | # 4 | 5 | # If the script is run in this way: 6 | # vivado_hls -f run_hls.tcl -tclargs $(TARGET_BOARD) 7 | set board "[lindex $argv 2]" 8 | 9 | # Create a project 10 | open_project -reset generated_hls_project 11 | 12 | add_files setup_manager_top.cpp -cflags -I../../../../include/ 13 | 14 | # Specify the top-level function for synthesis 15 | set_top setup_manager 16 | 17 | ########################### 18 | # Solution settings 19 | 20 | # Create solution1 21 | open_solution -reset solution1 22 | 23 | # Specify a Xilinx device and clock period 24 | # 25 | # VCU118: xcvu9p-flga2104-1-i 26 | # VCU108: xcvu095-ffva2104-2-e 27 | # ZCU106: xczu7ev-ffvc1156-2-e 28 | # ArtyA7: xc7a100tcsg324-1 29 | switch $board { 30 | vcu118 { 31 | set_part {xcvu9p-flga2104-1-i} 32 | } 33 | vcu108 { 34 | set_part {xcvu095-ffva2104-2-e} 35 | } 36 | zcu106 { 37 | set_part {xczu7ev-ffvc1156-2-e} 38 | } 39 | default { 40 | puts "Unknown board: $board" 41 | exit 42 | } 43 | } 44 | create_clock -period 4.00 -name default 45 | set_clock_uncertainty 0.25 46 | 47 | # UG902: Resets all registers and memories in the design. 48 | # Any static or global variable variables initialized in the C 49 | # code is reset to its initialized value. 50 | config_rtl -reset all -reset_async 51 | 52 | # Simulate the C code 53 | #csim_design 54 | 55 | # Synthesis the C code 56 | csynth_design 57 | 58 | # Export IP block 59 | export_design -format ip_catalog -display_name "setup_manager_hls" -description "manage connection setup and close signal" -vendor "Wuklab.UCSD" -version "1.0" 60 | 61 | # Do not perform any other steps 62 | # - The basic project will be opened in the GUI 63 | exit 64 | -------------------------------------------------------------------------------- /board/fpga/net_reliable/setup_manager/setup_manager.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RELNET_SETUP_MANAGER_H_ 2 | #define _RELNET_SETUP_MANAGER_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | using hls::stream; 11 | 12 | void setup_manager(stream *init_req, 13 | stream *conn_set_req, 14 | stream *timer_rst_req); 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /board/fpga/net_reliable/setup_manager/setup_manager_top.cpp: -------------------------------------------------------------------------------- 1 | #include "setup_manager.hpp" 2 | 3 | /* 4 | * @init_req: session open/close request from SoC 5 | * @conn_set_req: session states setup request to state table 6 | * @timer_rst_req: timer set request to timer 7 | * 8 | * setup_manager is the gate between GBN and SoC: 9 | * it accepts control requests from SoC, such as open/close session. 10 | * 11 | * Upon receiving a open request, we will send a request to state_table via @init_req 12 | * to 1) reset seqnum, 2) set it valid. We will also send request to timer to setup. 13 | * 14 | * Upon receiving a close request, we will send a request to state_table via @init_req 15 | * to set it invalid. We will also send request to timer to disable it. 16 | */ 17 | void setup_manager(stream *init_req, 18 | stream *conn_set_req, 19 | stream *timer_rst_req) 20 | { 21 | #pragma HLS INTERFACE axis both port=init_req 22 | #pragma HLS INTERFACE axis both port=conn_set_req 23 | #pragma HLS INTERFACE axis both port=timer_rst_req 24 | 25 | #pragma HLS DATA_PACK variable=conn_set_req 26 | #pragma HLS DATA_PACK variable=timer_rst_req 27 | #pragma HLS DATA_PACK variable=init_req 28 | 29 | #pragma HLS INTERFACE ap_ctrl_none port=return 30 | #pragma HLS PIPELINE 31 | 32 | struct conn_mgmt_req conn_req; 33 | struct timer_req rst_timer_req; 34 | 35 | if (!conn_set_req->empty()) { 36 | conn_req = conn_set_req->read(); 37 | if (conn_req.set_type == GBN_SOC2FPGA_SET_TYPE_OPEN || 38 | conn_req.set_type == GBN_SOC2FPGA_SET_TYPE_CLOSE) { 39 | /* forward the request to state table */ 40 | init_req->write(conn_req); 41 | /* at both open and close session, deactive timeout */ 42 | rst_timer_req.rst_type = timer_rst_type_stop; 43 | rst_timer_req.slotid = conn_req.slotid; 44 | timer_rst_req->write(rst_timer_req); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /board/fpga/net_reliable/state_table/Makefile: -------------------------------------------------------------------------------- 1 | # DO NOT CHANGE THIS. This is coded through the repo 2 | project_path=generated_hls_project 3 | 4 | VIVADO_HLS = vivado_hls 5 | 6 | ifeq ($(TARGET_BOARD), ) 7 | TARGET_BOARD = zcu106 8 | endif 9 | 10 | all: 11 | $(VIVADO_HLS) -f run_hls.tcl -tclargs $(TARGET_BOARD) 12 | 13 | g: 14 | $(VIVADO_HLS) -p $(project_path) & 15 | 16 | clean: 17 | rm -rf $(project_path) 18 | find ./ -name "*.log" | xargs rm -rf 19 | find ./ -name "*.jou" | xargs rm -rf 20 | find ./ -name "*.str" | xargs rm -rf 21 | find ./ -name ".Xil" | xargs rm -rf 22 | 23 | help: 24 | @echo "Help" 25 | @echo " # make <- Compile projects" 26 | @echo " # make g <- Open GUI" 27 | -------------------------------------------------------------------------------- /board/fpga/net_reliable/state_table/run_hls.tcl: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2020, Wuklab, UCSD. 3 | # 4 | 5 | # If the script is run in this way: 6 | # vivado_hls -f run_hls.tcl -tclargs $(TARGET_BOARD) 7 | set board "[lindex $argv 2]" 8 | 9 | # Create a project 10 | open_project -reset generated_hls_project 11 | 12 | add_files statetable_64_top.cpp -cflags -I../../../../include/ 13 | add_files -tb tb.cpp -cflags -I../../../../include/ 14 | 15 | # Specify the top-level function for synthesis 16 | set_top state_table_64 17 | 18 | ########################### 19 | # Solution settings 20 | 21 | # Create solution1 22 | open_solution -reset solution1 23 | 24 | # Specify a Xilinx device and clock period 25 | # 26 | # VCU118: xcvu9p-flga2104-1-i 27 | # VCU108: xcvu095-ffva2104-2-e 28 | # ZCU106: xczu7ev-ffvc1156-2-e 29 | # ArtyA7: xc7a100tcsg324-1 30 | switch $board { 31 | vcu118 { 32 | set_part {xcvu9p-flga2104-1-i} 33 | } 34 | vcu108 { 35 | set_part {xcvu095-ffva2104-2-e} 36 | } 37 | zcu106 { 38 | set_part {xczu7ev-ffvc1156-2-e} 39 | } 40 | default { 41 | puts "Unknown board: $board" 42 | exit 43 | } 44 | } 45 | create_clock -period 4.00 -name default 46 | set_clock_uncertainty 0.25 47 | 48 | # UG902: Resets all registers and memories in the design. 49 | # Any static or global variable variables initialized in the C 50 | # code is reset to its initialized value. 51 | config_rtl -reset all -reset_async 52 | 53 | # Simulate the C code 54 | #csim_design 55 | 56 | # Synthesis the C code 57 | csynth_design 58 | 59 | # Export IP block 60 | export_design -format ip_catalog -display_name "state_table_hls" -description "reliable network conection state table" -vendor "Wuklab.UCSD" -version "1.0" 61 | 62 | # Do not perform any other steps 63 | # - The basic project will be opened in the GUI 64 | exit 65 | -------------------------------------------------------------------------------- /board/fpga/net_reliable/state_table/statetable_64.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RELNET_STATE_TAB64_H_ 2 | #define _RELNET_STATE_TAB64_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | using hls::stream; 11 | 12 | void state_table_64(stream *rsp_header, 13 | stream *rsp_payload, 14 | stream *state_query_req, 15 | stream *state_query_rsp, 16 | stream *gbn_retrans_req, 17 | stream *timer_rst_req, 18 | stream > *rt_timeout_sig, 19 | stream *tx_finish_sig, 20 | stream > *check_full_req, 21 | stream > *check_full_rsp, 22 | stream *init_req); 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /board/fpga/net_reliable/tx_arbiter/Makefile: -------------------------------------------------------------------------------- 1 | # DO NOT CHANGE THIS. This is coded through the repo 2 | project_path=generated_hls_project 3 | 4 | VIVADO_HLS = vivado_hls 5 | 6 | ifeq ($(TARGET_BOARD), ) 7 | TARGET_BOARD = zcu106 8 | endif 9 | 10 | all: 11 | $(VIVADO_HLS) -f run_hls.tcl -tclargs $(TARGET_BOARD) 12 | 13 | g: 14 | $(VIVADO_HLS) -p $(project_path) & 15 | 16 | clean: 17 | rm -rf $(project_path) 18 | find ./ -name "*.log" | xargs rm -rf 19 | find ./ -name "*.jou" | xargs rm -rf 20 | find ./ -name "*.str" | xargs rm -rf 21 | find ./ -name ".Xil" | xargs rm -rf 22 | 23 | help: 24 | @echo "Help" 25 | @echo " # make <- Compile projects" 26 | @echo " # make g <- Open GUI" 27 | -------------------------------------------------------------------------------- /board/fpga/net_reliable/tx_arbiter/arbiter_64.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RELNET_ARBITER64_H_ 2 | #define _RELNET_ARBITER64_H_ 3 | 4 | // #include 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace hls; 10 | 11 | void arbiter_64(stream *rsp_header, 12 | stream *rsp_payload, 13 | stream *tx_header, 14 | stream *tx_payload, 15 | stream *rt_header, 16 | stream *rt_payload, 17 | stream *out_header, 18 | stream *out_payload); 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /board/fpga/net_reliable/tx_arbiter/run_hls.tcl: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2020, Wuklab, UCSD. 3 | # 4 | 5 | # If the script is run in this way: 6 | # vivado_hls -f run_hls.tcl -tclargs $(TARGET_BOARD) 7 | set board "[lindex $argv 2]" 8 | 9 | # Create a project 10 | open_project -reset generated_hls_project 11 | 12 | add_files arbiter_64_top.cpp -cflags -I../../../../include/ 13 | add_files -tb tb.cpp -cflags -I../../../../include/ 14 | 15 | # Specify the top-level function for synthesis 16 | set_top arbiter_64 17 | 18 | ########################### 19 | # Solution settings 20 | 21 | # Create solution1 22 | open_solution -reset solution1 23 | 24 | # Specify a Xilinx device and clock period 25 | # 26 | # VCU118: xcvu9p-flga2104-1-i 27 | # VCU108: xcvu095-ffva2104-2-e 28 | # ZCU106: xczu7ev-ffvc1156-2-e 29 | # ArtyA7: xc7a100tcsg324-1 30 | switch $board { 31 | vcu118 { 32 | set_part {xcvu9p-flga2104-1-i} 33 | } 34 | vcu108 { 35 | set_part {xcvu095-ffva2104-2-e} 36 | } 37 | zcu106 { 38 | set_part {xczu7ev-ffvc1156-2-e} 39 | } 40 | default { 41 | puts "Unknown board: $board" 42 | exit 43 | } 44 | } 45 | create_clock -period 4.00 -name default 46 | set_clock_uncertainty 0.25 47 | 48 | # UG902: Resets all registers and memories in the design. 49 | # Any static or global variable variables initialized in the C 50 | # code is reset to its initialized value. 51 | config_rtl -reset all -reset_async 52 | 53 | # Simulate the C code 54 | #csim_design 55 | 56 | # Synthesis the C code 57 | csynth_design 58 | 59 | # Export IP block 60 | export_design -format ip_catalog -display_name "relnet_tx_arbiter" -description "reliable network sender arbiter HLS" -vendor "Wuklab.UCSD" -version "1.0" 61 | 62 | # Do not perform any other steps 63 | # - The basic project will be opened in the GUI 64 | exit 65 | -------------------------------------------------------------------------------- /board/fpga/net_reliable/tx_arbiter/tb.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020,Wuklab, UCSD. 3 | */ 4 | 5 | #include "arbiter_64.hpp" 6 | #include 7 | #define MAX_CYCLE 50 8 | 9 | struct net_axis_64 build_gbn_header(ap_uint<8> type, ap_uint seqnum, 10 | ap_uint<1> last) 11 | { 12 | struct net_axis_64 pkt; 13 | pkt.data(7, 0) = type; 14 | pkt.data(8 + SEQ_WIDTH - 1, 8) = seqnum; 15 | pkt.data(63, 8 + SEQ_WIDTH) = 0; 16 | pkt.keep = 0xff; 17 | pkt.last = last; 18 | pkt.user = 0; 19 | return pkt; 20 | } 21 | 22 | int main() { 23 | stream rsp_header, rt_header, tx_header, out_header; 24 | stream rsp_payload, rt_payload, tx_payload, 25 | out_payload; 26 | 27 | struct udp_info test_header; 28 | struct net_axis_64 test_payload; 29 | 30 | test_header.src_ip = 0xc0a80181; // 192.168.1.129 31 | test_header.dest_ip = 0xc0a80180; // 192.168.1.128 32 | test_header.src_port = 1234; 33 | test_header.dest_port = 2345; 34 | 35 | rsp_header.write(test_header); 36 | test_payload = build_gbn_header(GBN_PKT_ACK, 1, 1); 37 | rsp_payload.write(test_payload); 38 | 39 | test_payload.keep = 0xff; 40 | test_payload.user = 0; 41 | 42 | rt_header.write(test_header); 43 | for (int j = 0; j < 10; j++) { 44 | test_payload.data = 0x0f0f0f0f0f0f0f0f; 45 | test_payload.last = 0; 46 | rt_payload.write(test_payload); 47 | } 48 | test_payload.data = 0x0f0f0f0f0f0f0f0f; 49 | test_payload.last = 1; 50 | rt_payload.write(test_payload); 51 | 52 | tx_header.write(test_header); 53 | for (int j = 0; j < 10; j++) { 54 | test_payload.data = 0x0101010101010101; 55 | test_payload.last = 0; 56 | tx_payload.write(test_payload); 57 | } 58 | test_payload.data = 0x0101010101010101; 59 | test_payload.last = 1; 60 | tx_payload.write(test_payload); 61 | 62 | for (int cycle = 0; cycle < MAX_CYCLE; cycle++) { 63 | arbiter_64(&rsp_header, &rsp_payload, &tx_header, &tx_payload, 64 | &rt_header, &rt_payload, &out_header, &out_payload); 65 | 66 | struct udp_info recv_hd; 67 | struct net_axis_64 recv_data; 68 | 69 | if (out_header.read_nb(recv_hd)) { 70 | dph("[cycle %2d] send data to net %x:%d -> %x:%d\n", 71 | cycle, recv_hd.src_ip.to_uint(), 72 | recv_hd.src_port.to_uint(), 73 | recv_hd.dest_ip.to_uint(), 74 | recv_hd.dest_port.to_uint()); 75 | } 76 | 77 | if (out_payload.read_nb(recv_data)) { 78 | dph("[cycle %2d] send data to net %llx, ", cycle, 79 | recv_data.data.to_uint64()); 80 | ap_uint<8> type = recv_data.data(7, 0); 81 | ap_uint seqnum = 82 | recv_data.data(8 + SEQ_WIDTH - 1, 8); 83 | dph("if gbn header [type %d, seq %lld]\n", 84 | type.to_ushort(), seqnum.to_uint64()); 85 | } 86 | } 87 | } -------------------------------------------------------------------------------- /board/fpga/net_reliable/unacked_buffer/Makefile: -------------------------------------------------------------------------------- 1 | # DO NOT CHANGE THIS. This is coded through the repo 2 | project_path=generated_hls_project 3 | 4 | VIVADO_HLS = vivado_hls 5 | 6 | ifeq ($(TARGET_BOARD), ) 7 | TARGET_BOARD = zcu106 8 | endif 9 | 10 | all: 11 | $(VIVADO_HLS) -f run_hls.tcl -tclargs $(TARGET_BOARD) 12 | 13 | g: 14 | $(VIVADO_HLS) -p $(project_path) & 15 | 16 | clean: 17 | rm -rf $(project_path) 18 | find ./ -name "*.log" | xargs rm -rf 19 | find ./ -name "*.jou" | xargs rm -rf 20 | find ./ -name "*.str" | xargs rm -rf 21 | find ./ -name ".Xil" | xargs rm -rf 22 | 23 | help: 24 | @echo "Help" 25 | @echo " # make <- Compile projects" 26 | @echo " # make g <- Open GUI" 27 | -------------------------------------------------------------------------------- /board/fpga/net_reliable/unacked_buffer/README.md: -------------------------------------------------------------------------------- 1 | # Unacknowledged Packet Buffer Controller 2 | Last Updated: Mar 26, 2020 3 | 4 | ## Introduction 5 | This is the controller of unacked packet buffer. It use a datamover to read and write the buffer in dram. For every packet it receives, it writes the whole packet to dram and only stores the routing info on chip. This simplifies the management. 6 | 7 | To be able to retrive the packet we stored, we need to know its address and length. Address can be calculated from the session id and seqnum. However, length has to be stored somewhere. Storing the length for every packet onchip consumes too much resources, so they are stored together with each packet. 8 | 9 | ## Memory Layout 10 | The buffer is made up of small slots stored in a matrix style. Each slot stores one packet, the size of each slot is defined by `MAX_PACKET_SIZE`. Each session has `WINDOW_SIZE` slots, the slots in the same session are stored consecutively. And the per session slot groups are also stored consecutively. The whole buffer is stored at the offset `BUFF_ADDRESS_START` defined in `unacked_buffer.hpp`. 11 | ``` 12 | 0 N * MAX_PACKET_SIZE 13 | +------+------+-----+------+ 14 | session 0| 00 | 01 | ... | 0N | 15 | +------+------+-----+------+ 16 | session 1| 10 | 11 | ... | 1N | 17 | +------+------+-----+------+ 18 | | ... | ... | ... | ... | 19 | +------+------+-----+------+ 20 | session M| M0 | M1 | ... | MN | 21 | +------+------+-----+------+ 22 | ``` 23 | 24 | In the first 8 bytes of each slot stores the lenth of the packet stored in that slot. Every time we want to read out a packet, we need to first read out the length, then we are able to read out the packet contents. 25 | ``` 26 | 0 8 MAX_PACKET_SIZE 27 | +--------+--------------+ 28 | | length | packet data | 29 | +--------+--------------+ 30 | ``` 31 | 32 | The buffer stores the ip route info of every session in BRAM. 33 | 34 | ## TODO 35 | Maybe we need to store the address of every packet onboard and avoid writting everything back to dram. 36 | -------------------------------------------------------------------------------- /board/fpga/net_reliable/unacked_buffer/run_hls.tcl: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2020, Wuklab, UCSD. 3 | # 4 | 5 | # If the script is run in this way: 6 | # vivado_hls -f run_hls.tcl -tclargs $(TARGET_BOARD) 7 | set board "[lindex $argv 2]" 8 | 9 | # Create a project 10 | open_project -reset generated_hls_project 11 | 12 | add_files unacked_buffer_top.cpp -cflags -I../../../../include/ 13 | add_files -tb tb.cpp -cflags -I../../../../include/ 14 | 15 | # Specify the top-level function for synthesis 16 | set_top unacked_buffer 17 | 18 | ########################### 19 | # Solution settings 20 | 21 | # Create solution1 22 | open_solution -reset solution1 23 | 24 | # Specify a Xilinx device and clock period 25 | # 26 | # VCU118: xcvu9p-flga2104-1-i 27 | # VCU108: xcvu095-ffva2104-2-e 28 | # ZCU106: xczu7ev-ffvc1156-2-e 29 | # ArtyA7: xc7a100tcsg324-1 30 | switch $board { 31 | vcu118 { 32 | set_part {xcvu9p-flga2104-1-i} 33 | } 34 | vcu108 { 35 | set_part {xcvu095-ffva2104-2-e} 36 | } 37 | zcu106 { 38 | set_part {xczu7ev-ffvc1156-2-e} 39 | } 40 | default { 41 | puts "Unknown board: $board" 42 | exit 43 | } 44 | } 45 | create_clock -period 4.00 -name default 46 | set_clock_uncertainty 0.25 47 | 48 | # UG902: Resets all registers and memories in the design. 49 | # Any static or global variable variables initialized in the C 50 | # code is reset to its initialized value. 51 | config_rtl -reset all -reset_async 52 | 53 | # Simulate the C code 54 | #csim_design 55 | 56 | # Synthesis the C code 57 | csynth_design 58 | 59 | # Export IP block 60 | export_design -format ip_catalog -display_name "unacked_buffer_hls" -description "unacknowledged buffer" -vendor "Wuklab.UCSD" -version "1.0" 61 | 62 | # Do not perform any other steps 63 | # - The basic project will be opened in the GUI 64 | exit 65 | -------------------------------------------------------------------------------- /board/fpga/net_reliable/unacked_buffer/unacked_buffer.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RELNET_UNACKED_BUFFER_H_ 2 | #define _RELNET_UNACKED_BUFFER_H_ 3 | 4 | #define AP_INT_MAX_W (2048) 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | using hls::stream; 13 | 14 | /* 15 | * This is the command word sent over to Datamover. 16 | * Defined at PG022 Figure 2-1 Command Word Layout. 17 | * NOTE: when you configure the Datamover, make btt 23 bits. 18 | */ 19 | #define DM_CMD_TYPE_FIXED 0 20 | #define DM_CMD_TYPE_INCR 1 21 | struct dm_cmd { 22 | ap_uint<23> btt; 23 | ap_uint<1> type; 24 | ap_uint<6> dsa; 25 | ap_uint<1> eof; 26 | ap_uint<1> drr; 27 | ap_uint<40> start_address; 28 | ap_uint<4> tag; 29 | ap_uint<4> rsvd; 30 | }; 31 | 32 | void unacked_buffer(stream *timer_rst_req, 33 | stream *tx_buff_payload, 34 | stream *tx_buff_route_info, 35 | stream *gbn_retrans_req, 36 | stream *rt_payload, 37 | stream *rt_header, 38 | stream *dm_rd_cmd_1, 39 | stream *dm_rd_cmd_2, 40 | stream *dm_rd_data, 41 | stream *dm_wr_cmd, 42 | stream *dm_wr_data); 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /board/fpga/scripts/create_ip.tcl: -------------------------------------------------------------------------------- 1 | set IP_FOLDER generated_ip 2 | set PROJECT_NAME package_[lindex $argv 0] 3 | set PROJECT_FOLDER ${IP_FOLDER}/$PROJECT_NAME 4 | 5 | # Script for packaging IP from RTL sources 6 | create_project ${PROJECT_NAME} ${PROJECT_FOLDER} -part xczu7ev-ffvc1156-2-e -force 7 | 8 | foreach f [lassign $argv _] { 9 | add_files -norecurse $f 10 | } 11 | 12 | import_files -force -norecurse 13 | update_compile_order -fileset sources_1 14 | update_compile_order -fileset sim_1 15 | 16 | ipx::package_project -root_dir ${PROJECT_FOLDER} 17 | set_property library {user} [ipx::current_core] 18 | set_property vendor_display_name {Wuklab} [ipx::current_core] 19 | set_property company_url {http://www.wuklab.io} [ipx::current_core] 20 | set_property vendor {wuklab.io} [ipx::current_core] 21 | set_property taxonomy {{/LegoMem}} [ipx::current_core] 22 | ipx::check_integrity [ipx::current_core] 23 | close_project 24 | exit 25 | -------------------------------------------------------------------------------- /board/fpga/scripts/create_monitor_read.tcl: -------------------------------------------------------------------------------- 1 | set IP_FOLDER generated_ip 2 | set PROJECT_NAME package_monitor_registers_read 3 | set PROJECT_FOLDER ${IP_FOLDER}/${PROJECT_NAME} 4 | 5 | create_project ${PROJECT_NAME} ${PROJECT_FOLDER} -part xczu7ev-ffvc1156-2-e -force 6 | 7 | add_files -norecurse src/lib/verilog/MonitorRegistersRead.v 8 | import_files -force -norecurse 9 | update_compile_order -fileset sources_1 10 | update_compile_order -fileset sim_1 11 | 12 | ipx::package_project -root_dir ${PROJECT_FOLDER} 13 | set_property library {user} [ipx::current_core] 14 | set_property vendor_display_name {Wuklab} [ipx::current_core] 15 | set_property company_url {http://www.wuklab.io} [ipx::current_core] 16 | set_property vendor {wuklab.io} [ipx::current_core] 17 | set_property taxonomy {{/LegoMem}} [ipx::current_core] 18 | ipx::check_integrity [ipx::current_core] 19 | close_project 20 | exit 21 | -------------------------------------------------------------------------------- /board/fpga/scripts/create_monitor_write.tcl: -------------------------------------------------------------------------------- 1 | set IP_FOLDER generated_ip 2 | set PROJECT_NAME package_monitor_registers_write 3 | set PROJECT_FOLDER ${IP_FOLDER}/${PROJECT_NAME} 4 | 5 | create_project ${PROJECT_NAME} ${PROJECT_FOLDER} -part xczu7ev-ffvc1156-2-e -force 6 | 7 | add_files -norecurse src/lib/verilog/MonitorRegistersWrite.v 8 | import_files -force -norecurse 9 | update_compile_order -fileset sources_1 10 | update_compile_order -fileset sim_1 11 | 12 | ipx::package_project -root_dir ${PROJECT_FOLDER} 13 | set_property library {user} [ipx::current_core] 14 | set_property vendor_display_name {Wuklab} [ipx::current_core] 15 | set_property company_url {http://www.wuklab.io} [ipx::current_core] 16 | set_property vendor {wuklab.io} [ipx::current_core] 17 | set_property taxonomy {{/LegoMem}} [ipx::current_core] 18 | ipx::check_integrity [ipx::current_core] 19 | close_project 20 | exit 21 | -------------------------------------------------------------------------------- /board/fpga/scripts/create_pingpong.tcl: -------------------------------------------------------------------------------- 1 | set IP_FOLDER generated_ip 2 | set PROJECT_NAME package_legomem_pingpong 3 | set PROJECT_FOLDER ${IP_FOLDER}/${PROJECT_NAME} 4 | 5 | create_project ${PROJECT_NAME} ${PROJECT_FOLDER} -part xczu7ev-ffvc1156-2-e -force 6 | 7 | add_files -norecurse generated_rtl/PingPong.v 8 | 9 | import_files -force -norecurse 10 | update_compile_order -fileset sources_1 11 | update_compile_order -fileset sim_1 12 | 13 | ipx::package_project -root_dir ${PROJECT_FOLDER} 14 | set_property library {user} [ipx::current_core] 15 | set_property vendor_display_name {Wuklab} [ipx::current_core] 16 | set_property company_url {http://www.wuklab.io} [ipx::current_core] 17 | set_property vendor {wuklab.io} [ipx::current_core] 18 | set_property taxonomy {{/LegoMem}} [ipx::current_core] 19 | ipx::check_integrity [ipx::current_core] 20 | close_project 21 | exit 22 | -------------------------------------------------------------------------------- /board/fpga/scripts/create_system.tcl: -------------------------------------------------------------------------------- 1 | set IP_FOLDER generated_ip 2 | set PROJECT_FOLDER ${IP_FOLDER}/package_core_mem 3 | 4 | set SOURCE { 5 | src/lib/verilog/legomem_system_lib.v 6 | generated_rtl/LegoMemSystem.v 7 | } 8 | 9 | create_project package_core_mem ${PROJECT_FOLDER} -part xczu7ev-ffvc1156-2-e -force 10 | 11 | add_files -norecurse ${SOURCE} 12 | import_files -force -norecurse 13 | 14 | update_compile_order -fileset sources_1 15 | update_compile_order -fileset sim_1 16 | 17 | ipx::package_project -root_dir ${PROJECT_FOLDER} 18 | set_property library {user} [ipx::current_core] 19 | set_property vendor_display_name {Wuklab} [ipx::current_core] 20 | set_property company_url {http://www.wuklab.io} [ipx::current_core] 21 | set_property vendor {wuklab.io} [ipx::current_core] 22 | set_property taxonomy {{/LegoMem}} [ipx::current_core] 23 | ipx::check_integrity [ipx::current_core] 24 | 25 | close_project 26 | exit 27 | -------------------------------------------------------------------------------- /board/fpga/src/main/scala/wuklab/Axi4.scala: -------------------------------------------------------------------------------- 1 | package wuklab 2 | 3 | import spinal.lib._ 4 | import spinal.core._ 5 | import spinal.lib.bus.amba4.axi._ 6 | 7 | case class Axi4WriteOnlyNonBurstUpsizer(inputConfig : Axi4Config, outputConfig : Axi4Config) extends Component { 8 | val io = new Bundle { 9 | val input = slave(Axi4WriteOnly(inputConfig)) 10 | val output = master(Axi4WriteOnly(outputConfig)) 11 | } 12 | 13 | // This use a narrow burst 14 | val (cmd, data) = StreamFork2(io.input.writeCmd) 15 | cmd drive io.output.writeCmd 16 | io.output.writeRsp drive io.input.writeRsp 17 | 18 | val dataCtrl = new Area { 19 | val sink = io.output.writeData 20 | val stream = io.input.writeData 21 | 22 | // get the shift width 23 | val shiftWidth = data.addr & ((1 << outputConfig.bytePerWord) - 1) 24 | 25 | sink.arbitrationFrom(StreamJoin.arg(data, stream)) 26 | sink.data := stream.data.resize(sink.data.getWidth) |<< shiftWidth 27 | Axi4Priv.driveWeak(stream,sink,stream.strb,sink.strb,() => B(sink.strb.range -> true),true,false) 28 | Axi4Priv.driveWeak(stream,sink,stream.user,sink.user,() => B(sink.user.range -> false),true,true) 29 | // Since this is a non-burst, this is always a last 30 | Axi4Priv.driveWeak(stream,sink,stream.last,sink.last,() => True,false,true) 31 | 32 | } 33 | 34 | } -------------------------------------------------------------------------------- /board/fpga/src/main/scala/wuklab/ExtendedProcessor.scala: -------------------------------------------------------------------------------- 1 | package wuklab 2 | 3 | import spinal.core._ 4 | import spinal.lib._ 5 | 6 | import Utils._ 7 | 8 | // class ExtendedProcessor extends Component { 9 | // 10 | // val selectionQueue = Stream(UInt(8 bits)) 11 | // 12 | // } 13 | // 14 | // // Require data? or not 15 | // trait ExtendedFunction[T <: Data] { 16 | // // This function have a timing constrain : finish in 1 cycle 17 | // def opcode : UInt 18 | // def processData(bitsIn : Bits, bitsOut : Bits) : Unit 19 | // } 20 | // 21 | // class TestAndSet extends ExtendedFunction[NoData] { 22 | // override def opcode = LegoMem.RequestType.READ_DEREF_READ 23 | // 24 | // override def processData(headerIn: Stream[LegoMemHeader], headerOut: Stream[LegoMemHeader], dataIn: Stream[Bits], dataOut: Stream[Bits]): Unit = { 25 | // 26 | // } 27 | // } 28 | 29 | class PingPong(dataLength : Int)(implicit config : CoreMemConfig) extends Component with XilinxAXI4Toplevel { 30 | require(dataLength <= (config.epDataAxisConfig.dataBytes - LegoMemHeader.headerBytes)) 31 | 32 | val io = new Bundle { 33 | val ep = LegoMemEndPoint(config.epDataAxisConfig, config.epCtrlAxisConfig) 34 | } 35 | 36 | val bridge = new RawInterfaceEndpoint 37 | bridge.io.ep <> io.ep 38 | 39 | bridge.io.raw.disableCtrl 40 | bridge.io.raw.dataOut.translateFrom (bridge.io.raw.dataIn.takeFirst) { (newData, oldData) => 41 | val assignF = LegoMemHeader.assignToBitsOperation { header => 42 | header.cont := U"16'h0" 43 | header.size := LegoMemHeader.headerBytes + dataLength 44 | } 45 | 46 | newData.fragment := assignF(oldData.fragment) 47 | newData.last := True 48 | } 49 | 50 | addPrePopTask(renameIO) 51 | } 52 | 53 | -------------------------------------------------------------------------------- /board/fpga/src/main/scala/wuklab/IDPool.scala: -------------------------------------------------------------------------------- 1 | package wuklab 2 | 3 | import wuklab.Utils._ 4 | import spinal.core._ 5 | import spinal.lib._ 6 | 7 | class IDPool(numIds: Int) extends Component { 8 | require (numIds > 0) 9 | val idWidth = log2Up(numIds) 10 | 11 | val io = new Bundle { 12 | val free = slave Flow UInt(idWidth bits) 13 | val alloc = master Stream UInt(idWidth bits) 14 | } 15 | 16 | // True indicates that the id is available 17 | val bitmap = Reg(UInt(numIds bits)) init UInt(numIds bits).setAll() 18 | val select = Reg(UInt(idWidth bits)) init 0 19 | val valid = Reg(Bool) init True 20 | 21 | io.alloc.valid := valid 22 | io.alloc.payload := select 23 | 24 | val taken = io.alloc.ready.asUInt(numIds bits) |<< io.alloc.payload 25 | val given = io.free.valid.asUInt(numIds bits) |<< io.free.payload 26 | val bitmap1 = (bitmap & ~taken) | given 27 | val select1 = OHToUInt(~leftOR(bitmap1, numIds) & bitmap1) 28 | val valid1 = bitmap1.orR 29 | 30 | // Clock gate the bitmap 31 | when (io.alloc.ready || io.free.valid) { 32 | bitmap := bitmap1 33 | valid := valid1 34 | } 35 | 36 | // Make select irrevocable 37 | when (io.alloc.ready || (!io.alloc.valid && io.free.valid)) { 38 | select := select1 39 | } 40 | 41 | // No double freeing 42 | assert (!io.free.valid || !(bitmap & ~taken)(io.free.payload), "Double freeing IDPool") 43 | } 44 | -------------------------------------------------------------------------------- /board/fpga/src/main/scala/wuklab/LegoMemMultiEndpoint.scala: -------------------------------------------------------------------------------- 1 | package wuklab 2 | 3 | import spinal.core._ 4 | import spinal.lib._ 5 | 6 | import Utils._ 7 | 8 | // TODO: only take highest bit on match function 9 | class LegoMemMultiDataInterface(operations : Seq[UInt => Bool])(implicit config : LegoMemConfig) extends Component { 10 | val numPorts = operations.size 11 | val io = new Bundle { 12 | val in = slave (LegoMemRawDataInterface()) 13 | val out = Vec(master (LegoMemRawDataInterface()), numPorts) 14 | } 15 | 16 | // data dispatch 17 | val nextPort = RegNextWhenBypass(LegoMemHeader(io.in.dataIn.fragment).reqType |> getDemuxPort, io.in.dataIn.first) 18 | val inPorts = StreamDemux(io.in.dataIn, nextPort, numPorts) 19 | (io.out, inPorts).zipped map (_.dataIn <-< _) 20 | 21 | // data arbitrate 22 | // TODO: check the stage here 23 | io.in.dataOut << StreamArbiterFactory.lowerFirst.fragmentLock.on(io.out.map(_.dataOut.stage())) 24 | 25 | def getDemuxPort(opCode : UInt) = OHToUInt(Vec(operations.map(_(opCode)))) 26 | } 27 | 28 | class LegoMemMultiControlEndpoint(addrs : Seq[UInt => Bool]) extends Component { 29 | val numPorts = addrs.size 30 | val io = new Bundle { 31 | val in = slave (LegoMemControlEndpoint()) 32 | val out = Vec (master (LegoMemControlEndpoint()), numPorts) 33 | } 34 | 35 | // input path 36 | val validVec = addrs.map(_(io.in.in.addr)) 37 | val valid = validVec.reduce(_ || _) 38 | val inPorts = StreamDemux(io.in.in.takeWhen(valid), OHToUInt(validVec), numPorts) 39 | (io.out, inPorts).zipped map (_.in <-< _) 40 | 41 | // output path 42 | io.in.out <-< StreamArbiterFactory.roundRobin.on(io.out.map(_.out)) 43 | } -------------------------------------------------------------------------------- /board/fpga/src/main/scala/wuklab/Lookup3.scala: -------------------------------------------------------------------------------- 1 | package wuklab 2 | 3 | import spinal.lib._ 4 | import spinal.core._ 5 | import Utils._ 6 | 7 | // Lookup3 hash function, require dataWidth <= 96 8 | class Lookup3(key : Int)(dataWidth : Int, hashWidth : Int) extends Component { 9 | 10 | require(dataWidth <= 96, "DataWidth should be with in 96 bits") 11 | require(hashWidth <= 32, "OutputWidth should be less than 32 bits") 12 | 13 | type LoopVar = (UInt, UInt, UInt) 14 | type Selector = LoopVar => UInt 15 | 16 | val io = new Bundle { 17 | val enable = in Bool 18 | val data = in UInt (dataWidth bits) 19 | val hash = out UInt (hashWidth bits) 20 | } 21 | 22 | val lastPair = initPair(io.data) |> finalMix 23 | io.hash := lastPair._3.resize(hashWidth) 24 | 25 | def initPair(data : UInt) : LoopVar = { 26 | // TODO: check this with CPU alignment 27 | val fullData = data.resize(96) 28 | val a = U"32'hdeadbeef" + (dataWidth / 32) + fullData(31 downto 0) 29 | val b = U"32'hdeadbeef" + (dataWidth / 32) + fullData(63 downto 32) 30 | val c = U"32'hdeadbeef" + (dataWidth / 32) + fullData(95 downto 64) 31 | (a, b, c) 32 | } 33 | 34 | def finalMix(pair : LoopVar) : LoopVar = { 35 | // ref impl 36 | // c ^= b; c -= rot(b,14); 37 | // a ^= c; a -= rot(c,11); 38 | // b ^= a; b -= rot(a,25); 39 | // c ^= b; c -= rot(b,16); 40 | // a ^= c; a -= rot(c,4); 41 | // b ^= a; b -= rot(a,14); 42 | // c ^= b; c -= rot(b,24); 43 | 44 | val a : Selector = _._1 45 | val b : Selector = _._2 46 | val c : Selector = _._3 47 | 48 | // Scala Magic! 49 | (pair 50 | |> finalR(c, b, 14) 51 | |> finalR(a, c, 11) 52 | |> regPair(io.enable) 53 | |> finalR(b ,a, 25) 54 | |> finalR(c, b, 16) 55 | |> regPair(io.enable) 56 | |> finalR(a, c, 4) 57 | |> finalR(b, a, 14) 58 | |> regPair(io.enable) 59 | |> finalR(c, b, 24) 60 | ) 61 | } 62 | 63 | def nextPair (pair : LoopVar) : LoopVar = { 64 | val next = ( cloneOf(pair._1), cloneOf(pair._2), cloneOf(pair._3) ) 65 | next._1 := pair._1 66 | next._2 := pair._2 67 | next._3 := pair._3 68 | next._1.allowOverride 69 | next._2.allowOverride 70 | next._3.allowOverride 71 | next 72 | } 73 | 74 | def regPair (enable : Bool)(pair : LoopVar) : LoopVar = 75 | ( RegNextWhen(pair._1, enable), RegNextWhen(pair._2, enable), RegNextWhen(pair._3, enable) ) 76 | 77 | def finalR(s1 : Selector, s2 : Selector, rot : Int)(pair : LoopVar) : LoopVar = { 78 | val next = nextPair(pair) 79 | s1(next) := (s1(pair) ^ s2(pair)) - s2(pair).rotateRight(rot) 80 | next 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /board/fpga/src/main/scala/wuklab/Replicator.scala: -------------------------------------------------------------------------------- 1 | package wuklab 2 | 3 | import spinal.core._ 4 | import spinal.lib._ 5 | import spinal.lib.bus.amba4.axilite._ 6 | 7 | // endpoint pipes: pipes 8 | import Utils._ 9 | 10 | class ReplicatorEndPointPipe(implicit config: LegoMemConfig) extends Component { 11 | val replyQueueSize = 32 12 | val sendQueueSize = 32 13 | 14 | val io = new Bundle { 15 | val epIn = LegoMemEndPoint(config.epDataAxisConfig, config.epCtrlAxisConfig) 16 | val epOut = LegoMemEndPoint(config.epDataAxisConfig, config.epCtrlAxisConfig).flip() 17 | 18 | val regBus = slave (AxiLite4(AxiLite4Config(8, 32))) 19 | } 20 | 21 | val firstIp = Reg (UInt(32 bits)) init 0 22 | val firstSess = Reg (UInt(32 bits)) init 0 23 | val secondIp = Reg (UInt(32 bits)) init 0 24 | val secondSess = Reg (UInt(32 bits)) init 0 25 | val regs = new AxiLite4SlaveFactory(io.regBus) 26 | regs.readAndWrite(firstIp, 0) 27 | regs.readAndWrite(firstSess, 4) 28 | regs.readAndWrite(secondIp, 8) 29 | regs.readAndWrite(secondSess, 12) 30 | 31 | // forward Ctrl 32 | io.epIn.ctrlIn >> io.epOut.ctrlIn 33 | io.epIn.ctrlOut << io.epOut.ctrlOut 34 | 35 | // Data In 36 | val receiveCtrl = new Area { 37 | val Seq(replyMessage, sendMessageF, forwardMessage) = StreamFork(io.epIn.dataIn, 3) 38 | // TODO: filter the keep Message 39 | // Reply PAth 40 | val Seq(replyFirstF, replySecondF) = StreamFork(replyMessage.stage(), 2) 41 | val replyFirst = replyFirstF.takeFirst.takeBy(isReplicatedReply).queue(replyQueueSize) 42 | val replySecond = replySecondF.takeFirst.takeBy(isReplicatedReply).queue(replyQueueSize) 43 | 44 | // Send path 45 | 46 | } 47 | 48 | // Data Out 49 | val sendPath = new Area { 50 | val (replySelfF, forwardOutF) = StreamFork2(io.epOut.dataOut) 51 | val replySelf = replySelfF.takeFirst.takeBy(isReplicatedReply).queue(replyQueueSize) 52 | val replyStream = replySelf <* receiveCtrl.replyFirst <* receiveCtrl.replySecond 53 | 54 | val forwardOut = forwardOutF.takeBy(!isReplicatedReply(_)) 55 | 56 | io.epIn.dataOut << StreamArbiterFactory.lowerFirst.fragmentLock 57 | .onArgs(replyStream.stage(), forwardOut.stage()) 58 | } 59 | 60 | def isReplicatedWrite(header : Fragment[AxiStreamPayload]) : Bool = True 61 | def isReplicatedReply(header : Fragment[AxiStreamPayload]) : Bool = True 62 | def sendReplicatedWrite(ip : UInt, sess : UInt)(header : AxiStreamPayload) : Unit = { 63 | 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /board/fpga/src/main/scala/wuklab/kv/Allocator.scala: -------------------------------------------------------------------------------- 1 | package wuklab.kv 2 | 3 | import spinal.core._ 4 | import spinal.lib._ 5 | import wuklab._ 6 | 7 | // Also need: pid & HTE Base addr 8 | import Utils._ 9 | 10 | // TODO we NEED a tag here 11 | case class AllocationRequest(reqWidth : Int) extends Bundle { 12 | val size = UInt(reqWidth bits) 13 | val cmd = UInt(4 bits) 14 | } 15 | case class AllocationInterface(reqWidth : Int, addrWidth : Int, numResponses : Int) extends Bundle with IMasterSlave { 16 | val request = Stream(AllocationRequest(reqWidth)) 17 | val response = Vec (Stream (UInt(addrWidth bits)), numResponses) 18 | 19 | override def asMaster(): Unit = { 20 | master (request) 21 | response.foreach (slave (_)) 22 | } 23 | 24 | def << (other : AllocationInterface) : Unit = { 25 | request << other.request 26 | (response, other.response).zipped map (_ >> _) 27 | } 28 | def >> (other : AllocationInterface) : Unit = other << this 29 | } 30 | 31 | // TODO: a high level abstraction: merger 32 | class KeyValueVirtualAllocator(numPorts : Int)(implicit config : KeyValueConfig) extends Component { 33 | val fifoLength = 32 34 | val io = new Bundle { 35 | val ctrl = slave (LegoMemControlEndpoint()) 36 | // Allocation interface? 37 | val allocs = slave (config.allocInterfaceType) 38 | } 39 | 40 | io.ctrl.out.translateFrom (io.allocs.request) { (cmd, size) => 41 | cmd.epid := config.allocEp 42 | cmd.addr := config.allocAddr 43 | cmd.cmd := size.cmd 44 | cmd.beats := 0 45 | cmd.assignParam(size.size) 46 | } 47 | 48 | // 0 -> PTE alloc 49 | // 1 -> ENTRY ALLOC 50 | val returnPorts = StreamDemux( 51 | io.ctrl.in.fmap(_.resizeParam(config.addrWidth)), 52 | io.ctrl.in.addr(log2Up(numPorts)-1 downto 0), 53 | numPorts) 54 | (returnPorts, io.allocs.response).zipped map (_.queue(fifoLength) >> _) 55 | 56 | // arbiter 57 | // TODO: save this for later other usage! 58 | // val arbiter = StreamArbiterFactory.lowerFirst.fragmentLock.build(config.allocInterfaceType.request.payload, numPorts) 59 | // 60 | // val (output, routeF) = StreamFork2(arbiter.io.output) 61 | // val route = routeF.translateWith(arbiter.io.chosen).queueLowLatency(config.allocLatency) 62 | // 63 | // io.ctrl.out.translateFrom (output) { (cmd, size) => 64 | // cmd.epid := config.allocEp 65 | // cmd.addr := config.allocAddr 66 | // cmd.cmd := config.allocCmd 67 | // cmd.assignParam(size) 68 | // } 69 | // 70 | // val returnPorts = StreamDemux(route *> io.ctrl.in.fmap(_.resizeParam(config.addrWidth)), route.payload, numPorts) 71 | // (returnPorts, io.allocs).zipped map (_ >> _.response) 72 | } 73 | -------------------------------------------------------------------------------- /board/fpga/src/main/scala/wuklab/monitor/AxiSimpleDMA.scala: -------------------------------------------------------------------------------- 1 | package wuklab 2 | 3 | import spinal.core._ 4 | import spinal.lib._ 5 | import spinal.lib.bus.amba4.axi.Axi4 6 | 7 | import Utils._ 8 | 9 | class AxiSimpleDMAReadOnly(implicit config : CoreMemConfig) extends Component { 10 | val lenWidth = widthOf(config.accessAxi4Config.lenType) 11 | val io = new Bundle { 12 | val bus = master (Axi4(config.accessAxi4Config)) 13 | val dma = slave ( 14 | AxiStreamDMAInterface(AxiStreamDMAConfig(config.dmaAxisConfig, config.physicalAddrWidth, config.dmaLengthWidth)) 15 | ) 16 | } 17 | 18 | // Let Write free run 19 | io.dma.write.data.freeRun() 20 | io.dma.write.cmd.freeRun() 21 | io.bus.aw.disable 22 | io.bus.w.disable 23 | io.bus.b.freeRun() 24 | 25 | // Read DMA 26 | io.bus.ar.translateFrom (io.dma.read.cmd) { (axi, axis) => 27 | // val addr = UInt(config.addressWidth bits) 28 | // val id = if(config.useId) UInt(config.idWidth bits) else null 29 | // val region = if(config.useRegion) Bits(4 bits) else null 30 | // val len = if(config.useLen) UInt(8 bits) else null 31 | // val size = if(config.useSize) UInt(3 bits) else null 32 | // val burst = if(config.useBurst) Bits(2 bits) else null 33 | // val lock = if(config.useLock) Bits(1 bits) else null 34 | // val cache = if(config.useCache) Bits(4 bits) else null 35 | // val qos = if(config.useQos) Bits(4 bits) else null 36 | // val user = if(userWidth >= 0) Bits(userWidth bits) else null 37 | // val prot = if(config.useProt) Bits(3 bits) else null 38 | 39 | axi.addr := axis.addr.resized 40 | axi.size := Axi4.size.BYTE_64.asUInt 41 | axi.len := ((axis.len >> 6) - 1).resized 42 | axi.lock := Axi4.lock.NORMAL 43 | axi.cache := B"0000" 44 | axi.prot := B"010" 45 | axi.setBurstINCR() 46 | } 47 | 48 | io.dma.read.data.translateFrom (io.bus.r) { (axis, axi) => 49 | axis.fragment := axi.data 50 | axis.last := axi.last 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /board/fpga/src/main/scala/wuklab/monitor/MonitorRegisters.scala: -------------------------------------------------------------------------------- 1 | package wuklab.monitor 2 | 3 | import wuklab._ 4 | import spinal.core._ 5 | import spinal.core.internals.Operator 6 | import spinal.lib._ 7 | import spinal.lib.bus.amba4.axilite.{AxiLite4, AxiLite4Config, AxiLite4SlaveFactory} 8 | 9 | // TODO: generate Reg MAP 10 | 11 | class MonitorRegisters(numInputs : Int, numOutputs : Int, baseAddr : BigInt) extends Component with XilinxAXI4Toplevel { 12 | 13 | def enableInputs = numInputs > 0 14 | def enableOutputs = numOutputs > 0 15 | def offset(i : Int) = baseAddr + BigInt(i * 4) 16 | 17 | val io = new Bundle { 18 | // Debug Interfaces 19 | val inputRegs = if (enableInputs) in Vec(UInt(32 bits), numInputs) else null 20 | val outputRegs = if (enableOutputs) out Vec(UInt(32 bits), numOutputs) else null 21 | 22 | val regBus = slave (AxiLite4(AxiLite4Config(32, 32))) 23 | } 24 | 25 | val regs = new AxiLite4SlaveFactory(io.regBus) 26 | if (enableOutputs) io.outputRegs.zipWithIndex.map { case (out, i) => 27 | val reg = Reg (UInt(32 bits)) init 0xdead 28 | regs.readAndWrite(reg, offset(i)) 29 | out := reg 30 | } 31 | if (enableInputs) io.inputRegs .zipWithIndex.map { case (reg, i) => regs.read(reg, offset(numOutputs + i)) } 32 | 33 | addPrePopTask(renameIO) 34 | } 35 | -------------------------------------------------------------------------------- /board/fpga/src/main/scala/wuklab/test/LegoMemSystemCtrlSim.scala: -------------------------------------------------------------------------------- 1 | package wuklab.test 2 | 3 | import spinal.core._ 4 | import spinal.core.sim._ 5 | 6 | import wuklab._ 7 | import wuklab.sim._ 8 | 9 | import CoreMemSimContext._ 10 | 11 | object LegoMemSystemCtrlSim { 12 | import SimConversions._ 13 | def main(args: Array[String]): Unit = { 14 | LegoMemSimConfig.doSim( 15 | new LegoMemSystem 16 | ) {dut => { 17 | dut.clockDomain.forkStimulus(5) 18 | 19 | val xbar = new LegoMemEndPointInterconnect(dut.clockDomain) 20 | xbar.=# (0) (dut.io.eps.seq) 21 | xbar.=# (1) (dut.io.eps.mem) 22 | xbar.=# (2) (dut.io.eps.soc) 23 | 24 | // Connect Interfaces to Memories 25 | val mem = new DictMemoryDriver(dut.clockDomain) 26 | mem =# dut.io.bus.access 27 | mem =# dut.io.bus.lookup 28 | val socCtrlStream = new StreamDriver(dut.io.soc.ctrlOut, dut.clockDomain) 29 | 30 | dut.clockDomain.assertReset() 31 | dut.clockDomain.waitRisingEdge(5) 32 | dut.clockDomain.deassertReset() 33 | 34 | dut.clockDomain.waitRisingEdge(10) 35 | println("Initializtion finish") 36 | 37 | dut.clockDomain.waitRisingEdge(80) 38 | }} 39 | 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /board/fpga/src/main/scala/wuklab/test/NetworkProtocolCheckerSim.scala: -------------------------------------------------------------------------------- 1 | package wuklab.test 2 | 3 | import scodec.bits.ByteVector 4 | import spinal.core._ 5 | import spinal.core.sim._ 6 | import wuklab.monitor._ 7 | import wuklab.sim._ 8 | import wuklab.test.CoreMemSimContext.{LegoMemSimConfig, config} 9 | 10 | import scala.util.Random 11 | 12 | object NetworkProtocolCheckerSim { 13 | import SimConversions._ 14 | def main(args: Array[String]): Unit = { 15 | LegoMemSimConfig.doSim( 16 | new NetworkProtocolChecker(BigInt("A000D000", 16)) 17 | ) {dut => { 18 | dut.clockDomain.forkStimulus(5) 19 | 20 | val dataStream = new StreamDriver(dut.io.dataIn, dut.clockDomain) 21 | val headerStream = new StreamDriver(dut.io.headerIn, dut.clockDomain) 22 | dut.io.dataOut.ready #= true 23 | dut.io.headerOut.ready #= true 24 | 25 | println("Initializtion finish") 26 | config.printConfig 27 | 28 | dut.clockDomain.assertReset() 29 | dut.clockDomain.waitRisingEdge(5) 30 | dut.clockDomain.deassertReset() 31 | 32 | dut.clockDomain.waitRisingEdge(10) 33 | 34 | def wr_cmd(seq : Int, data : Seq[Byte]) = legoMemAccessMsgCodec.encode( 35 | (LegoMemHeaderSim(pid = 0x0001, tag = 0, reqType = 0x50, cont = 0x4321, seqId = seq, size = 28 + data.size), 36 | 0x7e000000, data.size, ByteVector(data)) 37 | ).require 38 | 39 | // Start Simulation 40 | val numPackets = 256 41 | val headerFlow = fork { 42 | for (i <- 0 until numPackets) { 43 | val totalBytes = 0x10 + i + 28 44 | headerStream #= SeqDataGen(UDPHeaderSim(totalBytes, 1, 2, 3, 4)) 45 | println(f"Header finish $i with $totalBytes bytes") 46 | } 47 | } 48 | val dataFlow = fork { 49 | var total_data = 0 50 | for (i <- 0 until numPackets) { 51 | val dataBytes = 0x10 + i 52 | dataStream #= BitAxisDataGen(wr_cmd(i % 256, (0 until dataBytes).map(_.toByte))) 53 | println(f"Data finish $i with $dataBytes bytes") 54 | total_data += dataBytes + 28 55 | } 56 | println(s"Total Data Bytes sent $total_data%X") 57 | } 58 | 59 | headerFlow.join() 60 | dataFlow.join() 61 | 62 | dut.clockDomain.waitRisingEdge(80) 63 | }} 64 | 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /board/fpga/top/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2020-2021, Wuklab, UCSD. 3 | # 4 | 5 | include ../Makefile.mk 6 | 7 | .DEFAULT_GOAL := all 8 | 9 | all: 10 | $(VIVADO) -nojournal -nolog -mode tcl -source scripts/run_vivado.tcl 11 | 12 | g: 13 | $(VIVADO) -nojournal -nolog generated_vivado_project/generated_vivado_project.xpr & 14 | 15 | clean: 16 | find ./ -name "generated_hls_project" | xargs rm -rf 17 | find ./ -name "generated_vivado_project" | xargs rm -rf 18 | find ./ -name "*.log" | xargs rm -rf 19 | find ./ -name "*.jou" | xargs rm -rf 20 | find ./ -name "*.str" | xargs rm -rf 21 | find ./ -name ".Xil" | xargs rm -rf 22 | find ./ -name "awsver.txt" | xargs rm -rf 23 | -------------------------------------------------------------------------------- /board/fpga/top/rtl/sync_reset.v: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright (c) 2014-2018 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 1 ns / 1 ps 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 | parameter N=2 // depth of synchronizer 35 | )( 36 | input wire clk, 37 | input wire rst, 38 | output wire sync_reset_out 39 | ); 40 | 41 | reg [N-1:0] sync_reg = {N{1'b1}}; 42 | 43 | assign sync_reset_out = sync_reg[N-1]; 44 | 45 | always @(posedge clk or posedge rst) begin 46 | if (rst) 47 | sync_reg <= {N{1'b1}}; 48 | else 49 | sync_reg <= {sync_reg[N-2:0], 1'b0}; 50 | end 51 | 52 | endmodule 53 | -------------------------------------------------------------------------------- /board/fpga/top/rtl/sync_signal.v: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright (c) 2014-2018 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 1 ns / 1 ps 28 | 29 | /* 30 | * Synchronizes an asyncronous signal to a given clock by using a pipeline of 31 | * two registers. 32 | */ 33 | module sync_signal #( 34 | parameter WIDTH=1, // width of the input and output signals 35 | parameter N=2 // depth of synchronizer 36 | )( 37 | input wire clk, 38 | input wire [WIDTH-1:0] in, 39 | output wire [WIDTH-1:0] out 40 | ); 41 | 42 | reg [WIDTH-1:0] sync_reg[N-1:0]; 43 | 44 | /* 45 | * The synchronized output is the last register in the pipeline. 46 | */ 47 | assign out = sync_reg[N-1]; 48 | 49 | integer k; 50 | 51 | always @(posedge clk) begin 52 | sync_reg[0] <= in; 53 | for (k = 1; k < N; k = k + 1) begin 54 | sync_reg[k] <= sync_reg[k-1]; 55 | end 56 | end 57 | 58 | endmodule 59 | -------------------------------------------------------------------------------- /board/soc/core/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2020, Wuklab, UCSD. All rights reserved. 3 | # 4 | INCLUDE := -I../../../include/ 5 | 6 | CFLAGS := -Wno-stringop-truncation 7 | CFLAGS += -DCONFIG_ZCU106_SOC -DCONFIG_ARCH_ARM64 8 | #CFLAGS += -DCONFIG_ARCH_X86 9 | CFLAGS += -rdynamic 10 | 11 | SRCS := $(wildcard *.c) 12 | SRCS += $(wildcard test/*.c) 13 | 14 | CC := aarch64-linux-gnu-gcc 15 | #CC := gcc 16 | 17 | all: $(SRCS) 18 | $(CC) -O2 -Wall -o core.o $(CFLAGS) $(INCLUDE) $(SRCS) -lpthread 19 | 20 | clean: 21 | find ./ -name "*.o" | xargs rm -rf 22 | -------------------------------------------------------------------------------- /board/soc/core/axidma_ioctl.h: -------------------------------------------------------------------------------- 1 | ../lib/axidma/include/axidma_ioctl.h -------------------------------------------------------------------------------- /board/soc/core/dma.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020. Wuklab. All rights reserved. 3 | */ 4 | 5 | #ifndef _SOC_DMA_H_ 6 | #define _SOC_DMA_H_ 7 | 8 | #include "libaxidma.h" 9 | #include 10 | #include 11 | 12 | #define CTRL_BUFFER_SIZE (128) 13 | 14 | #define DATA_SEND_CHANNEL 0 15 | #define DATA_RECV_CHANNEL 1 16 | #define CTRL_SEND_CHANNEL 2 17 | #define CTRL_RECV_CHANNEL 3 18 | 19 | /* 20 | * A convenient structure to carry information around 21 | * about the transfer 22 | */ 23 | struct dma_transfer { 24 | int ctrl_channel; // The channel used to send the data 25 | int data_channel; // The channel used to send the data 26 | void *input_buf; // The buffer to hold the input data 27 | }; 28 | 29 | struct dma_info { 30 | axidma_dev_t dev; 31 | const array_t *tx; 32 | const array_t *rx; 33 | }; 34 | 35 | extern struct dma_info legomem_dma_info; 36 | extern pthread_spinlock_t send_data_lock; 37 | extern pthread_spinlock_t send_ctrl_lock; 38 | 39 | static inline int dma_recv_blocking(void *buf, size_t len) 40 | { 41 | axidma_dev_t dev; 42 | 43 | dev = legomem_dma_info.dev; 44 | return axidma_oneway_transfer(dev, DATA_RECV_CHANNEL, buf, len, true); 45 | } 46 | 47 | static inline int dma_recv_nonblocking(void *buf, size_t len) 48 | { 49 | axidma_dev_t dev; 50 | 51 | dev = legomem_dma_info.dev; 52 | return axidma_oneway_transfer(dev, DATA_RECV_CHANNEL, buf, len, false); 53 | } 54 | 55 | static inline int dma_send(void *buf, size_t len) 56 | { 57 | axidma_dev_t dev; 58 | int ret; 59 | 60 | dev = legomem_dma_info.dev; 61 | 62 | pthread_spin_lock(&send_data_lock); 63 | ret = axidma_oneway_transfer(dev, DATA_SEND_CHANNEL, buf, len, true); 64 | pthread_spin_unlock(&send_data_lock); 65 | return ret; 66 | } 67 | 68 | static inline int dma_ctrl_send(void *buf, size_t len) 69 | { 70 | axidma_dev_t dev; 71 | int ret; 72 | 73 | dev = legomem_dma_info.dev; 74 | 75 | pthread_spin_lock(&send_ctrl_lock); 76 | ret = axidma_oneway_transfer(dev, CTRL_SEND_CHANNEL, buf, len, true); 77 | pthread_spin_unlock(&send_ctrl_lock); 78 | return ret; 79 | } 80 | 81 | static inline int dma_ctrl_recv_blocking(void *buf, size_t len) 82 | { 83 | axidma_dev_t dev; 84 | 85 | dev = legomem_dma_info.dev; 86 | return axidma_oneway_transfer(dev, CTRL_RECV_CHANNEL, buf, len, true); 87 | } 88 | 89 | int init_dma(void); 90 | int dma_thpool_alloc_cb(struct thpool_buffer *tb); 91 | 92 | #endif /* _SOC_DMA_H_ */ 93 | -------------------------------------------------------------------------------- /board/soc/core/external.h: -------------------------------------------------------------------------------- 1 | #ifndef _LEGOPGA_BOARD_SOC_EXTERNAL_H_ 2 | #define _LEGOPGA_BOARD_SOC_EXTERNAL_H_ 3 | 4 | #include 5 | #include 6 | 7 | void board_soc_handle_alloc_free(struct thpool_buffer *tb, bool is_alloc); 8 | void board_soc_handle_migration_send(struct thpool_buffer *tb); 9 | void board_soc_handle_migration_recv(struct thpool_buffer *tb); 10 | void board_soc_handle_migration_recv_cancel(struct thpool_buffer *tb); 11 | 12 | #endif /* _LEGOPGA_BOARD_SOC_EXTERNAL_H_ */ 13 | -------------------------------------------------------------------------------- /board/soc/core/include: -------------------------------------------------------------------------------- 1 | ../../../include -------------------------------------------------------------------------------- /board/soc/core/libaxidma.c: -------------------------------------------------------------------------------- 1 | ../lib/axidma/library/libaxidma.c -------------------------------------------------------------------------------- /board/soc/core/libaxidma.h: -------------------------------------------------------------------------------- 1 | ../lib/axidma/include/libaxidma.h -------------------------------------------------------------------------------- /board/soc/core/log_ratio_1_pg_1.csv: -------------------------------------------------------------------------------- 1 | 1,0 2 | 2,0 3 | 3,0 4 | 4,0 5 | 5,0 6 | 6,0 7 | 7,0 8 | 8,0 9 | 9,0 10 | 10,0 11 | 11,0 12 | 12,0 13 | 13,0 14 | 14,0 15 | 15,0 16 | 16,0 17 | 17,0 18 | 18,0 19 | 19,0 20 | 20,0 21 | 21,0 22 | 22,0 23 | 23,0 24 | 24,0 25 | 25,0 26 | 26,0 27 | 27,0 28 | 28,0 29 | 29,0 30 | 30,0 31 | 31,0 32 | 32,0 33 | 33,1 34 | 34,1 35 | 35,2 36 | 36,0 37 | 37,1 38 | 38,3 39 | 39,2 40 | 40,5 41 | 41,0 42 | 42,6 43 | 43,6 44 | 44,8 45 | 45,4 46 | 46,9 47 | 47,5 48 | 48,16 49 | 49,18 50 | 50,22 51 | 51,21 52 | 52,38 53 | 53,48 54 | 54,51 55 | 55,49 56 | 56,52 57 | 57,73 58 | 58,75 59 | 59,88 60 | 60,98 61 | 61,117 62 | 62,146 63 | 63,167 64 | 64,178 65 | 65,197 66 | 66,214 67 | 67,244 68 | 68,252 69 | 69,285 70 | 70,356 71 | 71,391 72 | 72,425 73 | 73,477 74 | 74,553 75 | 75,579 76 | 76,716 77 | 77,734 78 | 78,832 79 | 79,855 80 | 80,989 81 | 81,1020 82 | 82,1283 83 | 83,1406 84 | 84,1629 85 | 85,1837 86 | 86,1913 87 | 87,2147 88 | 88,2463 89 | 89,2877 90 | 90,3052 91 | 91,3824 92 | 92,4362 93 | 93,5305 94 | 94,6347 95 | 95,7943 96 | 96,10273 97 | 97,15485 98 | 98,24311 99 | 99,235712 100 | -------------------------------------------------------------------------------- /board/soc/core/log_ratio_1_pg_2.csv: -------------------------------------------------------------------------------- 1 | 1,0 2 | 2,0 3 | 3,0 4 | 4,0 5 | 5,0 6 | 6,0 7 | 7,0 8 | 8,0 9 | 9,0 10 | 10,0 11 | 11,0 12 | 12,0 13 | 13,0 14 | 14,0 15 | 15,0 16 | 16,0 17 | 17,0 18 | 18,0 19 | 19,0 20 | 20,0 21 | 21,0 22 | 22,0 23 | 23,0 24 | 24,0 25 | 25,0 26 | 26,0 27 | 27,0 28 | 28,0 29 | 29,0 30 | 30,0 31 | 31,0 32 | 32,0 33 | 33,1 34 | 34,1 35 | 35,2 36 | 36,0 37 | 37,1 38 | 38,3 39 | 39,2 40 | 40,5 41 | 41,1 42 | 42,5 43 | 43,6 44 | 44,8 45 | 45,4 46 | 46,9 47 | 47,5 48 | 48,16 49 | 49,18 50 | 50,21 51 | 51,21 52 | 52,42 53 | 53,45 54 | 54,50 55 | 55,51 56 | 56,53 57 | 57,73 58 | 58,75 59 | 59,83 60 | 60,101 61 | 61,128 62 | 62,133 63 | 63,156 64 | 64,197 65 | 65,192 66 | 66,228 67 | 67,227 68 | 68,267 69 | 69,303 70 | 70,354 71 | 71,386 72 | 72,416 73 | 73,511 74 | 74,545 75 | 75,652 76 | 76,695 77 | 77,777 78 | 78,852 79 | 79,827 80 | 80,1059 81 | 81,1234 82 | 82,1367 83 | 83,1561 84 | 84,1634 85 | 85,1829 86 | 86,2254 87 | 87,2391 88 | 88,2704 89 | 89,3422 90 | 90,3888 91 | 91,4865 92 | 92,5531 93 | 93,7559 94 | 94,9407 95 | 95,13009 96 | 96,20078 97 | 97,34047 98 | 98,84201 99 | -------------------------------------------------------------------------------- /board/soc/core/log_ratio_2_pg_1.csv: -------------------------------------------------------------------------------- 1 | 1,0 2 | 2,0 3 | 3,0 4 | 4,0 5 | 5,0 6 | 6,0 7 | 7,0 8 | 8,0 9 | 9,0 10 | 10,0 11 | 11,0 12 | 12,0 13 | 13,0 14 | 14,0 15 | 15,0 16 | 16,0 17 | 17,0 18 | 18,0 19 | 19,0 20 | 20,0 21 | 21,0 22 | 22,0 23 | 23,0 24 | 24,0 25 | 25,0 26 | 26,0 27 | 27,0 28 | 28,0 29 | 29,0 30 | 30,0 31 | 31,0 32 | 32,0 33 | 33,0 34 | 34,0 35 | 35,1 36 | 36,2 37 | 37,2 38 | 38,2 39 | 39,7 40 | 40,3 41 | 41,5 42 | 42,13 43 | 43,19 44 | 44,12 45 | 45,21 46 | 46,40 47 | 47,37 48 | 48,43 49 | 49,47 50 | 50,51 51 | 51,55 52 | 52,68 53 | 53,70 54 | 54,84 55 | 55,120 56 | 56,143 57 | 57,151 58 | 58,171 59 | 59,176 60 | 60,196 61 | 61,238 62 | 62,266 63 | 63,307 64 | 64,372 65 | 65,393 66 | 66,424 67 | 67,479 68 | 68,548 69 | 69,611 70 | 70,652 71 | 71,779 72 | 72,855 73 | 73,993 74 | 74,1054 75 | 75,1222 76 | 76,1342 77 | 77,1491 78 | 78,1706 79 | 79,1795 80 | 80,2043 81 | 81,2338 82 | 82,2459 83 | 83,2840 84 | 84,3074 85 | 85,3355 86 | 86,4006 87 | 87,4337 88 | 88,4798 89 | 89,5723 90 | 90,6186 91 | 91,7275 92 | 92,8647 93 | 93,10346 94 | 94,12361 95 | 95,15724 96 | 96,20679 97 | 97,29463 98 | 98,49744 99 | 99,430916 100 | -------------------------------------------------------------------------------- /board/soc/core/log_ratio_2_pg_10.csv: -------------------------------------------------------------------------------- 1 | 1,0 2 | 2,0 3 | 3,0 4 | 4,0 5 | 5,0 6 | 6,0 7 | 7,0 8 | 8,0 9 | 9,0 10 | 10,0 11 | 11,0 12 | 12,0 13 | 13,0 14 | 14,0 15 | 15,0 16 | 16,0 17 | 17,0 18 | 18,0 19 | 19,0 20 | 20,0 21 | 21,0 22 | 22,0 23 | 23,0 24 | 24,0 25 | 25,0 26 | 26,0 27 | 27,0 28 | 28,0 29 | 29,0 30 | 30,0 31 | 31,0 32 | 32,0 33 | 33,0 34 | 34,0 35 | 35,0 36 | 36,2 37 | 37,1 38 | 38,6 39 | 39,2 40 | 40,5 41 | 41,9 42 | 42,15 43 | 43,10 44 | 44,22 45 | 45,34 46 | 46,29 47 | 47,33 48 | 48,48 49 | 49,35 50 | 50,49 51 | 51,58 52 | 52,49 53 | 53,101 54 | 54,107 55 | 55,118 56 | 56,132 57 | 57,144 58 | 58,164 59 | 59,186 60 | 60,218 61 | 61,281 62 | 62,270 63 | 63,298 64 | 64,325 65 | 65,408 66 | 66,458 67 | 67,600 68 | 68,658 69 | 69,734 70 | 70,939 71 | 71,993 72 | 72,1111 73 | 73,1285 74 | 74,1605 75 | 75,1944 76 | 76,2369 77 | 77,2627 78 | 78,3280 79 | 79,3881 80 | 80,5435 81 | 81,6820 82 | 82,9144 83 | 83,12940 84 | 84,15919 85 | 85,23665 86 | 86,37798 87 | 87,57523 88 | 88,89373 89 | 89,159229 90 | 90,301286 91 | 91,708552 92 | 92,1626464 93 | 93,4513080 94 | -------------------------------------------------------------------------------- /board/soc/core/log_ratio_2_pg_100.csv: -------------------------------------------------------------------------------- 1 | 1,0 2 | 2,0 3 | 3,0 4 | 4,0 5 | 5,0 6 | 6,0 7 | 7,0 8 | 8,0 9 | 9,0 10 | 10,0 11 | 11,0 12 | 12,0 13 | 13,0 14 | 14,0 15 | 15,0 16 | 16,0 17 | 17,0 18 | 18,0 19 | 19,0 20 | 20,0 21 | 21,0 22 | 22,0 23 | 23,0 24 | 24,0 25 | 25,0 26 | 26,0 27 | 27,0 28 | 28,0 29 | 29,0 30 | 30,2 31 | 31,0 32 | 32,1 33 | 33,0 34 | 34,1 35 | 35,0 36 | 36,2 37 | 37,3 38 | 38,2 39 | 39,7 40 | 40,4 41 | 41,7 42 | 42,10 43 | 43,11 44 | 44,20 45 | 45,12 46 | 46,21 47 | 47,21 48 | 48,34 49 | 49,58 50 | 50,59 51 | 51,59 52 | 52,68 53 | 53,90 54 | 54,144 55 | 55,187 56 | 56,186 57 | 57,375 58 | 58,341 59 | 59,594 60 | 60,897 61 | 61,1643 62 | 62,2475 63 | 63,4569 64 | 64,8803 65 | 65,16084 66 | 66,37528 67 | 67,81367 68 | 68,151321 69 | 69,508935 70 | -------------------------------------------------------------------------------- /board/soc/core/log_ratio_2_pg_2.csv: -------------------------------------------------------------------------------- 1 | 1,0 2 | 2,0 3 | 3,0 4 | 4,0 5 | 5,0 6 | 6,0 7 | 7,0 8 | 8,0 9 | 9,0 10 | 10,0 11 | 11,0 12 | 12,0 13 | 13,0 14 | 14,0 15 | 15,0 16 | 16,0 17 | 17,0 18 | 18,0 19 | 19,0 20 | 20,0 21 | 21,0 22 | 22,0 23 | 23,0 24 | 24,0 25 | 25,0 26 | 26,0 27 | 27,0 28 | 28,0 29 | 29,0 30 | 30,0 31 | 31,0 32 | 32,0 33 | 33,0 34 | 34,0 35 | 35,1 36 | 36,2 37 | 37,2 38 | 38,2 39 | 39,7 40 | 40,3 41 | 41,5 42 | 42,13 43 | 43,19 44 | 44,12 45 | 45,21 46 | 46,41 47 | 47,37 48 | 48,41 49 | 49,50 50 | 50,50 51 | 51,56 52 | 52,64 53 | 53,70 54 | 54,83 55 | 55,124 56 | 56,140 57 | 57,157 58 | 58,161 59 | 59,180 60 | 60,200 61 | 61,238 62 | 62,269 63 | 63,311 64 | 64,353 65 | 65,389 66 | 66,429 67 | 67,489 68 | 68,518 69 | 69,603 70 | 70,684 71 | 71,797 72 | 72,871 73 | 73,968 74 | 74,1113 75 | 75,1217 76 | 76,1384 77 | 77,1605 78 | 78,1660 79 | 79,1968 80 | 80,2159 81 | 81,2337 82 | 82,2635 83 | 83,2891 84 | 84,3516 85 | 85,3740 86 | 86,4422 87 | 87,4800 88 | 88,5602 89 | 89,6512 90 | 90,7972 91 | 91,9527 92 | 92,11531 93 | 93,14949 94 | 94,19525 95 | 95,25237 96 | 96,38276 97 | 97,68522 98 | 98,164556 99 | -------------------------------------------------------------------------------- /board/soc/core/log_ratio_2_pg_3.csv: -------------------------------------------------------------------------------- 1 | 1,0 2 | 2,0 3 | 3,0 4 | 4,0 5 | 5,0 6 | 6,0 7 | 7,0 8 | 8,0 9 | 9,0 10 | 10,0 11 | 11,0 12 | 12,0 13 | 13,0 14 | 14,0 15 | 15,0 16 | 16,0 17 | 17,0 18 | 18,0 19 | 19,0 20 | 20,0 21 | 21,0 22 | 22,0 23 | 23,0 24 | 24,0 25 | 25,0 26 | 26,0 27 | 27,0 28 | 28,0 29 | 29,0 30 | 30,0 31 | 31,0 32 | 32,0 33 | 33,0 34 | 34,0 35 | 35,1 36 | 36,2 37 | 37,4 38 | 38,1 39 | 39,6 40 | 40,4 41 | 41,7 42 | 42,15 43 | 43,14 44 | 44,12 45 | 45,26 46 | 46,38 47 | 47,38 48 | 48,35 49 | 49,54 50 | 50,41 51 | 51,63 52 | 52,65 53 | 53,69 54 | 54,95 55 | 55,126 56 | 56,140 57 | 57,171 58 | 58,149 59 | 59,173 60 | 60,207 61 | 61,241 62 | 62,263 63 | 63,324 64 | 64,346 65 | 65,400 66 | 66,428 67 | 67,496 68 | 68,522 69 | 69,617 70 | 70,712 71 | 71,792 72 | 72,907 73 | 73,986 74 | 74,1109 75 | 75,1294 76 | 76,1449 77 | 77,1577 78 | 78,1830 79 | 79,1938 80 | 80,2282 81 | 81,2556 82 | 82,2875 83 | 83,3250 84 | 84,3869 85 | 85,4355 86 | 86,4912 87 | 87,5617 88 | 88,6963 89 | 89,8299 90 | 90,10616 91 | 91,13891 92 | 92,17187 93 | 93,24396 94 | 94,33792 95 | 95,51862 96 | 96,93300 97 | 97,207262 98 | 98,857377 99 | -------------------------------------------------------------------------------- /board/soc/core/run.sh: -------------------------------------------------------------------------------- 1 | set -x 2 | set -e 3 | 4 | sed -i /0\.22/d ~/.ssh/known_hosts 5 | sed -i /0\.23/d ~/.ssh/known_hosts 6 | sed -i /0\.24/d ~/.ssh/known_hosts 7 | sed -i /0\.25/d ~/.ssh/known_hosts 8 | sed -i /0\.26/d ~/.ssh/known_hosts 9 | 10 | #scp -o StrictHostKeyChecking=no core.o root@192.168.0.22: 11 | #scp -o StrictHostKeyChecking=no core.o root@192.168.0.23: 12 | #scp -o StrictHostKeyChecking=no core.o root@192.168.0.24: 13 | #scp -o StrictHostKeyChecking=no core.o root@192.168.0.25: 14 | scp -o StrictHostKeyChecking=no core.o root@192.168.0.26: 15 | -------------------------------------------------------------------------------- /board/soc/core/scale1_pg1.csv: -------------------------------------------------------------------------------- 1 | 1,0 2 | 2,0 3 | 3,0 4 | 4,0 5 | 5,0 6 | 6,0 7 | 7,0 8 | 8,0 9 | 9,0 10 | 10,0 11 | 11,0 12 | 12,0 13 | 13,0 14 | 14,0 15 | 15,0 16 | 16,0 17 | 17,0 18 | 18,0 19 | 19,0 20 | 20,0 21 | 21,0 22 | 22,0 23 | 23,0 24 | 24,0 25 | 25,0 26 | 26,0 27 | 27,0 28 | 28,0 29 | 29,0 30 | 30,0 31 | 31,0 32 | 32,0 33 | 33,1 34 | 34,1 35 | 35,2 36 | 36,0 37 | 37,1 38 | 38,3 39 | 39,2 40 | 40,5 41 | 41,1 42 | 42,5 43 | 43,6 44 | 44,8 45 | 45,4 46 | 46,9 47 | 47,5 48 | 48,16 49 | 49,18 50 | 50,21 51 | 51,21 52 | 52,42 53 | 53,45 54 | 54,50 55 | 55,51 56 | 56,53 57 | 57,73 58 | 58,75 59 | 59,83 60 | 60,101 61 | 61,128 62 | 62,133 63 | 63,156 64 | 64,197 65 | 65,192 66 | 66,228 67 | 67,227 68 | 68,267 69 | 69,303 70 | 70,354 71 | 71,386 72 | 72,416 73 | 73,511 74 | 74,545 75 | 75,652 76 | 76,695 77 | 77,777 78 | 78,852 79 | 79,827 80 | 80,1059 81 | 81,1234 82 | 82,1367 83 | 83,1561 84 | 84,1634 85 | 85,1829 86 | 86,2254 87 | 87,2391 88 | 88,2704 89 | 89,3422 90 | 90,3888 91 | 91,4865 92 | 92,5531 93 | 93,7559 94 | 94,9407 95 | 95,13009 96 | 96,20078 97 | 97,34047 98 | 98,84201 99 | -------------------------------------------------------------------------------- /board/soc/core/stat.c: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright (c) 2020. Wuklab. All rights reserved. 4 | * 5 | * This file describes the SoC side thpool workers and buffers: 6 | * they bridge SoC and FPGA together. 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include "dma.h" 29 | #include "core.h" 30 | 31 | void *devmem_stat_base; 32 | 33 | void init_stat_mapping(void) 34 | { 35 | void *p; 36 | size_t size; 37 | 38 | size = SOC_REGMAP_STAT_END - SOC_REGMAP_STAT_START, 39 | 40 | p = mmap(0, size, 41 | PROT_READ | PROT_WRITE, 42 | MAP_SHARED, devmem_fd, 43 | SOC_REGMAP_STAT_START); 44 | if (p == MAP_FAILED) { 45 | dprintf_ERROR("Fail to mmap stat regmap. %d", errno); 46 | exit(0); 47 | } 48 | 49 | devmem_stat_base = p; 50 | dprintf_INFO("regmap stat mapped @[%#lx-%#lx] -> [%#lx-%#lx]\n", 51 | (u64)devmem_stat_base, (u64)devmem_stat_base + size, 52 | SOC_REGMAP_STAT_START, SOC_REGMAP_STAT_END); 53 | } 54 | -------------------------------------------------------------------------------- /board/soc/core/test/test_buddy.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Eval buddy perf 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include "../buddy.h" 15 | #include "../core.h" 16 | 17 | void test_buddy(void) 18 | { 19 | unsigned long nr_pages; 20 | int i; 21 | struct timespec s, e; 22 | struct page *page; 23 | double diff_ns; 24 | 25 | nr_pages = (fpga_mem_end - fpga_mem_start) >> PAGE_SHIFT; 26 | nr_pages >>= 1; 27 | 28 | dprintf_INFO("NR_PAGES: %lu\n", nr_pages); 29 | 30 | clock_gettime(CLOCK_MONOTONIC, &s); 31 | for (i = 0; i < nr_pages; i++) { 32 | page = alloc_page(0); 33 | if (!page) { 34 | dprintf_ERROR("Failed at %d th page alloc\n", i); 35 | exit(0); 36 | } 37 | } 38 | clock_gettime(CLOCK_MONOTONIC, &e); 39 | 40 | diff_ns = (e.tv_sec * NSEC_PER_SEC + e.tv_nsec) - 41 | (s.tv_sec * NSEC_PER_SEC + s.tv_nsec); 42 | 43 | dprintf_INFO("nr_pages: %lu, allocated %d pages (order 0), avg latency: %lf ns\n", 44 | nr_pages, i, diff_ns / i); 45 | } 46 | -------------------------------------------------------------------------------- /board/soc/core/test/test_clear_page.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Eval buddy perf 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include "../buddy.h" 15 | #include "../core.h" 16 | 17 | void test_clear_page(void) 18 | { 19 | unsigned long nr_pages; 20 | int i; 21 | struct timespec s, e; 22 | double diff_ns; 23 | void *soc_va; 24 | unsigned long pfn; 25 | 26 | nr_pages = MAX_PFN - START_PFN; 27 | 28 | dprintf_INFO("NR_PAGES: %lu\n", nr_pages); 29 | 30 | clock_gettime(CLOCK_MONOTONIC, &s); 31 | for (i = 0; i < nr_pages; i++) { 32 | /* 33 | * It's okay to use unallocated pages 34 | * we directly write into the page itself 35 | * none buddy metadata is touched 36 | */ 37 | pfn = i + START_PFN; 38 | soc_va = (void *)pfn_to_soc_va(pfn); 39 | 40 | #if 0 41 | dprintf_INFO("i %d pfn %lu soc_va %#lx\n", i, pfn, (u64)soc_va); 42 | #endif 43 | 44 | clear_fpga_page(soc_va, PAGE_SIZE); 45 | } 46 | clock_gettime(CLOCK_MONOTONIC, &e); 47 | 48 | diff_ns = (e.tv_sec * NSEC_PER_SEC + e.tv_nsec) - 49 | (s.tv_sec * NSEC_PER_SEC + s.tv_nsec); 50 | 51 | dprintf_INFO("nr_pages: %lu, page_size: %lx avg latency: %lf ns\n", 52 | nr_pages, PAGE_SIZE, diff_ns / i); 53 | } 54 | -------------------------------------------------------------------------------- /board/soc/core/test/test_vm_latency.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020. Wuklab. All rights reserved. 3 | */ 4 | 5 | /* 6 | * This test will mainly test alloc_va_vregion and free_va_vregion, both of them 7 | * operate with a single vRegion. We will get the average latency of them. 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #include "../core.h" 23 | 24 | #define ALLOC_SIZE_4M (1<<22) 25 | #define ALLOC_SIZE_16M (1<<24) 26 | #define ALLOC_SIZE_64M (1<<26) 27 | 28 | void test_vm(void) 29 | { 30 | unsigned long *addr; 31 | struct vregion_info *vi; 32 | struct proc_info *pi; 33 | unsigned int pid; 34 | int nr_allocs_per_vregion; 35 | int i, j; 36 | int alloc_size; 37 | struct timespec s, e; 38 | double diff_ns; 39 | 40 | pid = 100; 41 | 42 | pi = alloc_proc(pid, "proc_1", 0); 43 | if (!pi) { 44 | printf("fail to create the test pi\n"); 45 | return; 46 | } 47 | dump_procs(); 48 | 49 | alloc_size = ALLOC_SIZE_4M; 50 | nr_allocs_per_vregion = VREGION_SIZE / alloc_size; 51 | 52 | addr = malloc(sizeof(*addr) * NR_VREGIONS * nr_allocs_per_vregion); 53 | 54 | /* Test alloc_va_vregion latency */ 55 | clock_gettime(CLOCK_MONOTONIC, &s); 56 | for (i = 0; i < NR_VREGIONS; i++) { 57 | vi = pi->vregion + i; 58 | for (j = 0; j < nr_allocs_per_vregion; j++) { 59 | int idx; 60 | 61 | idx = i * nr_allocs_per_vregion + j; 62 | addr[idx] = alloc_va_vregion(pi, vi, alloc_size, 0, NULL); 63 | if (!addr[idx]) { 64 | dprintf_DEBUG("i %d j %d failed\n", i, j); 65 | exit(0); 66 | } 67 | } 68 | } 69 | clock_gettime(CLOCK_MONOTONIC, &e); 70 | 71 | diff_ns = (e.tv_sec * NSEC_PER_SEC + e.tv_nsec) - 72 | (s.tv_sec * NSEC_PER_SEC + s.tv_nsec); 73 | 74 | dprintf_INFO("alloc_size %d MB #nr_alloc=%d avg_ns=%lf\n", 75 | alloc_size >> 20, i * j, (diff_ns / i / j)); 76 | 77 | /* Test free_va_vregion latency */ 78 | clock_gettime(CLOCK_MONOTONIC, &s); 79 | for (i = 0; i < NR_VREGIONS; i++) { 80 | vi = pi->vregion + i; 81 | for (j = 0; j < nr_allocs_per_vregion; j++) { 82 | int idx; 83 | 84 | idx = i * nr_allocs_per_vregion + j; 85 | free_va_vregion(pi, vi, addr[idx], alloc_size); 86 | } 87 | } 88 | clock_gettime(CLOCK_MONOTONIC, &e); 89 | 90 | diff_ns = (e.tv_sec * NSEC_PER_SEC + e.tv_nsec) - 91 | (s.tv_sec * NSEC_PER_SEC + s.tv_nsec); 92 | 93 | dprintf_INFO("free_size %d MB #nr_free=%d avg_ns=%lf\n", 94 | alloc_size >> 20, i * j, (diff_ns / i / j)); 95 | } 96 | -------------------------------------------------------------------------------- /board/soc/core/tlbflush.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020. Wuklab. All rights reserved. 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #include "core.h" 22 | 23 | #include "dma.h" 24 | 25 | 26 | void *global_tlbflush_req; 27 | 28 | /* 29 | * This is not SMP safe. 30 | * But we are using INLINE handling now, its okay. 31 | */ 32 | static inline void *get_tlbflush_req(void) 33 | { 34 | BUG_ON(!global_tlbflush_req); 35 | return global_tlbflush_req; 36 | } 37 | 38 | void init_tlbflush_setup(void) 39 | { 40 | axidma_dev_t dev; 41 | void *p; 42 | 43 | dev = legomem_dma_info.dev; 44 | p = axidma_malloc(dev, THPOOL_BUFFER_SIZE); 45 | if (!p) { 46 | dprintf_ERROR("Fail to alloc the dma reqbuf for tlbflush. %d\n", errno); 47 | exit(0); 48 | } 49 | global_tlbflush_req = p; 50 | } 51 | 52 | /* 53 | * Send a TLB cache flush to coremem cached BRAM pgtable. 54 | * Simple semantic, just as you know it. 55 | */ 56 | void tlb_flush(struct proc_info *pi, unsigned long va, unsigned long size) 57 | { 58 | struct __packed { 59 | struct lego_header lego_header; 60 | struct op_cache_flush op; 61 | } *req; 62 | 63 | req = get_tlbflush_req(); 64 | 65 | req->lego_header.pid = pi->pid; 66 | req->lego_header.opcode = OP_REQ_CACHE_INVALID; 67 | req->lego_header.cont = MAKE_CONT(LEGOMEM_CONT_MEM, LEGOMEM_CONT_NONE, 68 | LEGOMEM_CONT_NONE, LEGOMEM_CONT_NONE); 69 | req->lego_header.size = sizeof(*req); 70 | 71 | req->op.va = va; 72 | req->op.size = size; 73 | dma_send(req, sizeof(*req)); 74 | 75 | dprintf_DEBUG("PID: %u TLB FLUSH VA @[%#lx - %#lx] size %#lx\n", 76 | pi->pid, va, va + size, size); 77 | } 78 | -------------------------------------------------------------------------------- /board/soc/core/util.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Wuklab, UCSD. All rights reserved. 3 | * Some misc helper functions used by everyone, anywhere they want. 4 | */ 5 | 6 | #define _GNU_SOURCE 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include "core.h" 18 | 19 | int pin_cpu(int cpu_id) 20 | { 21 | cpu_set_t cpu_set; 22 | 23 | CPU_ZERO(&cpu_set); 24 | CPU_SET(cpu_id, &cpu_set); 25 | return pthread_setaffinity_np(pthread_self(), sizeof(cpu_set), &cpu_set); 26 | } 27 | 28 | void legomem_getcpu(int *cpu, int *node) 29 | { 30 | syscall(SYS_getcpu, cpu, node, NULL); 31 | } 32 | 33 | int parse_ip_str(const char *ip_str) 34 | { 35 | int ip; 36 | int ip1, ip2, ip3, ip4; 37 | 38 | sscanf(ip_str, "%u.%u.%u.%u", &ip1, &ip2, &ip3, &ip4); 39 | ip = ip1 << 24 | ip2 << 16 | ip3 << 8 | ip4; 40 | return ip; 41 | } 42 | -------------------------------------------------------------------------------- /board/soc/lib/axidma/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015-2016 Brandon Perez 4 | Copyright (c) 2015-2016 Jared Choi 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /board/soc/lib/axidma/driver/Kbuild: -------------------------------------------------------------------------------- 1 | # Kbuild 2 | # 3 | # Date: March 21, 2017 4 | # Author: Brandon Perez 5 | # Author: Jared Choi 6 | # 7 | # The build file for compiling the AXI DMA driver against the kernel. This is 8 | # used by the kernel to determine how to compile the driver. 9 | 10 | # Indicate that this module should be compiled to the kernel Makefile, and the 11 | # files to use to compile it. 12 | $(AXIDMA_MODULE_NAME)-objs = $(patsubst %.c,%.o,$(filter %.c,$(AXIDMA_FILES))) 13 | obj-m += $(AXIDMA_MODULE_NAME).o 14 | 15 | # Set the CFLAGS for compiling the module, adding the include flags. Note that 16 | # the src variable points to the module's directory. 17 | INC_FLAGS = $(addprefix -I ,$(AXIDMA_INC_DIRS)) 18 | ccflags-y = $(INC_FLAGS) -Werror -ggdb 19 | 20 | # If specified, define the macro to fixup the path for the Xilinx DMA include. 21 | # In some 4.x Xilinx kernels, the file is still in the old path from 3.x. 22 | ifneq ($(origin XILINX_DMA_INCLUDE_PATH_FIXUP),undefined) 23 | ccflags-y += -DXILINX_DMA_INCLUDE_PATH_FIXUP 24 | endif 25 | -------------------------------------------------------------------------------- /board/soc/lib/axidma/examples/conversion.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file conversion.h 3 | * @date Sunday, December 06, 2015 at 03:29:47 AM EST 4 | * @author Brandon Perez (bmperez) 5 | * @author Jared Choi (jaewonch) 6 | * 7 | * Contains some basic macros for converting between different types. 8 | * 9 | * @bug No known bugs. 10 | **/ 11 | 12 | #ifndef CONVERSION_H_ 13 | #define CONVERSION_H_ 14 | 15 | #include // Timing functions and definitions 16 | 17 | // Converts a tval struct to a double value of the time in seconds 18 | #define TVAL_TO_SEC(tval) \ 19 | (((double)(tval).tv_sec) + (((double)(tval).tv_usec) / 1000000.0)) 20 | 21 | // Converts a byte (integral) value to mebibytes (floating-point) 22 | #define BYTE_TO_MIB(size) (((double)(size)) / (1024.0 * 1024.0)) 23 | 24 | // Converts a mebibyte (floating-point) value to bytes (integral) 25 | #define MIB_TO_BYTE(size) ((size_t)((size) * 1024.0 * 1024.0)) 26 | 27 | #endif /* CONVERSION_H_ */ 28 | -------------------------------------------------------------------------------- /board/soc/lib/axidma/examples/util.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file util.c 3 | * @date Sunday, December 06, 2015 at 01:10:08 AM EST 4 | * @author Brandon Perez (bmperez) 5 | * @author Jared Choi (jaewonch) 6 | * 7 | * This file contains miscalaneous utilities for out system. 8 | * 9 | * @bug No known bugs. 10 | **/ 11 | 12 | #ifndef UTIL_H_ 13 | #define UTIL_H_ 14 | 15 | // Command-line parsing utilities 16 | int parse_int(char option, char *arg_str, int *data); 17 | int parse_double(char option, char *arg_str, double *data); 18 | int parse_resolution(char option, char *arg_str, int *height, int *width, 19 | int *depth); 20 | 21 | // File operation utilities 22 | int robust_read(int fd, char *buf, int buf_size); 23 | int robust_write(int fd, char *buf, int buf_size); 24 | 25 | #endif /* UTIL_H_ */ 26 | -------------------------------------------------------------------------------- /board/soc/lib/axidma/library/library.mk: -------------------------------------------------------------------------------- 1 | # library.mk 2 | # 3 | # Date: July 28, 2016 4 | # Author: Brandon Perez 5 | # Author: Jared Choi 6 | # 7 | # The Makefile for building the AXI DMA library. 8 | 9 | # Include guard for the Makefile 10 | ifndef LIBAXIDMA_MAKEFILE_ 11 | LIBAXIDMA_MAKEFILE_=included 12 | 13 | ################################################################################ 14 | # Configuration 15 | ################################################################################ 16 | 17 | # The flags for compiling the library 18 | LIBAXIDMA_CFLAGS = $(GLOBAL_CFLAGS) -fPIC -shared \ 19 | -Wno-missing-field-initializers 20 | 21 | # The files that makeup the AXI DMA library 22 | LIBAXIDMA_DIR = library 23 | LIBAXIDMA_FILES = libaxidma.c 24 | LIBAXIDMA = $(addprefix $(LIBAXIDMA_DIR)/,$(LIBAXIDMA_FILES)) 25 | 26 | # The header files for the AXI DMA library interface 27 | LIBAXIDMA_INC_DIRS = include 28 | LIBAXIDMA_INC_FILES = libaxidma.h axidma_ioctl.h 29 | LIBAXIDMA_INC = $(addprefix $(LIBAXIDMA_INC_DIRS)/,$(LIBAXIDMA_INC_FILES)) 30 | LIBAXIDMA_INC_FLAGS = $(addprefix -I ,$(LIBAXIDMA_INC_DIRS)) 31 | 32 | # The shared library files generated by compilation 33 | LIBAXIDMA_NAME = axidma 34 | LIBAXIDMA_LIBRARY = $(LIBAXIDMA_DIR)/lib$(LIBAXIDMA_NAME).so 35 | LIBAXIDMA_OUTPUT_LIBRARY = $(OUTPUT_DIR)/lib$(LIBAXIDMA_NAME).so 36 | 37 | # The Doxygen configuration file and generated libaxidma documentation file 38 | LIBAXIDMA_DOC_CONFIG = libaxidma.dox 39 | LIBAXIDMA_DOC = $(DOC_DIR)/html/index.html 40 | 41 | ################################################################################ 42 | # Targets 43 | ################################################################################ 44 | 45 | .PHONY: library library library_docs library_clean 46 | 47 | # User-facing targets for compiling the library 48 | library: $(LIBAXIDMA_OUTPUT_LIBRARY) 49 | 50 | # Compile the library into a shared library file 51 | $(LIBAXIDMA_LIBRARY): $(LIBAXIDMA) $(LIBAXIDMA_INC) | cross_compiler_check 52 | $(CC) $(LIBAXIDMA_CFLAGS) $(LIBAXIDMA_INC_FLAGS) $(filter %.c,$^) -o $@ 53 | 54 | # Copy the compiled shared library object to the specified output directory 55 | $(LIBAXIDMA_OUTPUT_LIBRARY): $(LIBAXIDMA_LIBRARY) $(OUTPUT_DIR) 56 | @cp $< $@ 57 | 58 | # Geneate the Doxygen documentation for the library 59 | library_docs: 60 | doxygen $(LIBAXIDMA_DOC_CONFIG) &> /dev/null 61 | firefox $(LIBAXIDMA_DOC) & 62 | 63 | # Clean up all the files generated by compiling the library 64 | library_clean: 65 | rm -f $(LIBAXIDMA_OUTPUT_LIBRARY) $(LIBAXIDMA_LIBRARY) 66 | 67 | endif # LIBAXIDMA_MAKEFILE_ 68 | -------------------------------------------------------------------------------- /board/soc/lib/axidma/module/files/Makefile: -------------------------------------------------------------------------------- 1 | DRIVER_NAME = xilinx-axidma 2 | $(DRIVER_NAME)-objs = axi_dma.o axidma_chrdev.o axidma_dma.o axidma_of.o 3 | obj-m := $(DRIVER_NAME).o 4 | 5 | SRC := $(shell pwd) 6 | 7 | all: 8 | $(MAKE) -C $(KERNEL_SRC) M=$(SRC) 9 | 10 | modules_install: 11 | $(MAKE) -C $(KERNEL_SRC) M=$(SRC) modules_install 12 | 13 | clean: 14 | rm -f *.o *~ core .depend .*.cmd *.ko *.mod.c 15 | rm -f Module.markers Module.symvers modules.order 16 | rm -rf .tmp_versions Modules.symvers 17 | -------------------------------------------------------------------------------- /board/soc/lib/axidma/module/xilinx-axidma.bb: -------------------------------------------------------------------------------- 1 | SUMMARY = "Recipe for build an external xilinx-axidma Linux kernel module" 2 | SECTION = "PETALINUX/modules" 3 | LICENSE = "GPLv2" 4 | LIC_FILES_CHKSUM = "file://COPYING;md5=12f884d2ae1ff87c09e5b7ccc2c4ca7e" 5 | 6 | inherit module 7 | 8 | SRC_URI = "file://Makefile \ 9 | file://axi_dma.c \ 10 | file://axidma_chrdev.c \ 11 | file://axidma_dma.c \ 12 | file://axidma_of.c \ 13 | file://axidma.h \ 14 | file://axidma_ioctl.h \ 15 | file://COPYING \ 16 | " 17 | 18 | S = "${WORKDIR}" 19 | 20 | # The inherit of module.bbclass will automatically name module packages with 21 | # "kernel-module-" prefix as required by the oe-core build environment. 22 | -------------------------------------------------------------------------------- /board/soc/linux/golden/.gitignore: -------------------------------------------------------------------------------- 1 | */*/config.old 2 | */*/rootfs_config.old 3 | hardware/ 4 | build/ 5 | images/linux/ 6 | pre-built/linux/ 7 | .petalinux/* 8 | !.petalinux/metadata 9 | *.o 10 | *.jou 11 | *.log 12 | project-spec/meta-plnx-generated/ 13 | /components/plnx_workspace 14 | -------------------------------------------------------------------------------- /board/soc/linux/golden/Makefile: -------------------------------------------------------------------------------- 1 | include config.mk 2 | 3 | RESET_SCRIPT = ../../scripts/rst.tcl 4 | BITSTREAM = $(HARDWARE_DIR)/pl.bit 5 | 6 | # import files 7 | FILE_USER_DEVICETREE = project-spec/meta-user/recipes-bsp/device-tree/files/system-user.dtsi 8 | FILE_PL_DEVICETREE = 9 | 10 | .PHONY: reset boot config 11 | 12 | boot: reset 13 | petalinux-boot --jtag --u-boot --fpga --bitstream $(BITSTREAM) 14 | 15 | reset: 16 | /tools/Xilinx/SDK/2019.1/bin/xsdb $(RESET_SCRIPT) 17 | 18 | config: 19 | petalinux-config --get-hw-description=$(HARDWARE_DIR) --silentconfig 20 | -------------------------------------------------------------------------------- /board/soc/linux/golden/config.project: -------------------------------------------------------------------------------- 1 | # 2 | # Automatically generated file; DO NOT EDIT. 3 | # PetaLinux SDK Project Configuration 4 | # 5 | CONFIG_PROJECT_ADDITIONAL_COMPONENTS_SEARCH_PATH="" 6 | 7 | # 8 | # Subsystems of the project 9 | # 10 | CONFIG_PROJECT_SUBSYSTEM_LINUX_INSTANCE_LINUX=y 11 | CONFIG_PROJECT_SUBSYSTEMS=y 12 | -------------------------------------------------------------------------------- /board/soc/linux/golden/project-spec/attributes: -------------------------------------------------------------------------------- 1 | #Virtual Providers 2 | 3 | 4 | 5 | #defconfigs 6 | 7 | UBOOT_DEFAULT_DEFCONFIG="xilinx_zynqmp_zcu102_revB_defconfig" 8 | -------------------------------------------------------------------------------- /board/soc/linux/golden/project-spec/hw-description/metadata: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WukLab/Clio/7908c3a022fd356cd54616630fcddf59f7f3fd95/board/soc/linux/golden/project-spec/hw-description/metadata -------------------------------------------------------------------------------- /board/soc/linux/golden/project-spec/hw-description/system.hdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WukLab/Clio/7908c3a022fd356cd54616630fcddf59f7f3fd95/board/soc/linux/golden/project-spec/hw-description/system.hdf -------------------------------------------------------------------------------- /board/soc/linux/golden/project-spec/meta-user/COPYING.MIT: -------------------------------------------------------------------------------- 1 | Permission is hereby granted, free of charge, to any person obtaining a copy 2 | of this software and associated documentation files (the "Software"), to deal 3 | in the Software without restriction, including without limitation the rights 4 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 5 | copies of the Software, and to permit persons to whom the Software is 6 | furnished to do so, subject to the following conditions: 7 | 8 | The above copyright notice and this permission notice shall be included in 9 | all copies or substantial portions of the Software. 10 | 11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 12 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 13 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 14 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 15 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 16 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 17 | THE SOFTWARE. 18 | -------------------------------------------------------------------------------- /board/soc/linux/golden/project-spec/meta-user/README: -------------------------------------------------------------------------------- 1 | This README file contains information on the contents of the 2 | meta-user layer. 3 | 4 | Please see the corresponding sections below for details. 5 | 6 | 7 | Dependencies 8 | ============ 9 | 10 | This layer depends on: 11 | 12 | URI: git://git.openembedded.org/bitbake 13 | branch: master 14 | 15 | URI: git://git.openembedded.org/openembedded-core 16 | layers: meta 17 | branch: master 18 | 19 | URI: git://git.yoctoproject.org/xxxx 20 | layers: xxxx 21 | branch: master 22 | 23 | 24 | Patches 25 | ======= 26 | 27 | Please submit any patches against the meta-user layer to the 28 | xxxx mailing list (xxxx@zzzz.org) and cc: the maintainer: 29 | 30 | Maintainer: XXX YYYYYY 31 | 32 | 33 | Table of Contents 34 | ================= 35 | 36 | I. Adding the meta-user layer to your build 37 | II. Misc 38 | 39 | 40 | I. Adding the meta-user layer to your build 41 | ================================================= 42 | 43 | --- replace with specific instructions for the meta-user layer --- 44 | 45 | In order to use this layer, you need to make the build system aware of 46 | it. 47 | 48 | Assuming the meta-user layer exists at the top-level of your 49 | yocto build tree, you can add it to the build system by adding the 50 | location of the meta-user layer to bblayers.conf, along with any 51 | other layers needed. e.g.: 52 | 53 | BBLAYERS ?= " \ 54 | /path/to/yocto/meta \ 55 | /path/to/yocto/meta-poky \ 56 | /path/to/yocto/meta-yocto-bsp \ 57 | /path/to/yocto/meta-meta-user \ 58 | " 59 | 60 | 61 | II. Misc 62 | ======== 63 | 64 | --- replace with specific information about the meta-user layer --- 65 | -------------------------------------------------------------------------------- /board/soc/linux/golden/project-spec/meta-user/conf/layer.conf: -------------------------------------------------------------------------------- 1 | # We have a conf and classes directory, add to BBPATH 2 | BBPATH .= ":${LAYERDIR}" 3 | 4 | # We have recipes-* directories, add to BBFILES 5 | BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \ 6 | ${LAYERDIR}/recipes-*/*/*.bbappend" 7 | 8 | BBFILE_COLLECTIONS += "meta-user" 9 | BBFILE_PATTERN_meta-user = "^${LAYERDIR}/" 10 | BBFILE_PRIORITY_meta-user = "6" 11 | LAYERSERIES_COMPAT_meta-user = "thud" 12 | -------------------------------------------------------------------------------- /board/soc/linux/golden/project-spec/meta-user/conf/petalinuxbsp.conf: -------------------------------------------------------------------------------- 1 | #User Configuration 2 | 3 | #OE_TERMINAL = "tmux" 4 | 5 | # Add EXTRA_IMAGEDEPENDS default components 6 | EXTRA_IMAGEDEPENDS_append_versal = " virtual/psm-firmware virtual/plm arm-trusted-firmware u-boot-zynq-scr" 7 | EXTRA_IMAGEDEPENDS_append_zynqmp = " virtual/fsbl virtual/pmu-firmware arm-trusted-firmware" 8 | EXTRA_IMAGEDEPENDS_append_zynq = " virtual/fsbl" 9 | EXTRA_IMAGEDEPENDS_append_microblaze = " virtual/fsboot virtual/elfrealloc" 10 | 11 | # prevent U-Boot from deploying the boot.bin 12 | SPL_BINARY = "" 13 | 14 | #Remove all qemu contents 15 | IMAGE_CLASSES_remove = "image-types-xilinx-qemu qemuboot-xilinx" 16 | IMAGE_FSTYPES_remove = "wic.qemu-sd" 17 | 18 | EXTRA_IMAGEDEPENDS_remove = "qemu-helper-native virtual/boot-bin" 19 | SIGGEN_UNLOCKED_RECIPES_append_versal = " initscripts" 20 | -------------------------------------------------------------------------------- /board/soc/linux/golden/project-spec/meta-user/recipes-apps/gpio-demo/files/Makefile: -------------------------------------------------------------------------------- 1 | APP = gpio-demo 2 | 3 | # Add any other object files to this list below 4 | APP_OBJS = gpio-demo.o 5 | 6 | all: $(APP) 7 | 8 | $(APP): $(APP_OBJS) 9 | $(CC) $(LDFLAGS) -o $@ $(APP_OBJS) $(LDLIBS) 10 | 11 | clean: 12 | -rm -f $(APP) *.elf *.gdb *.o 13 | 14 | 15 | -------------------------------------------------------------------------------- /board/soc/linux/golden/project-spec/meta-user/recipes-apps/gpio-demo/gpio-demo.bb: -------------------------------------------------------------------------------- 1 | # 2 | # This is the GPIO-DEMO apllication recipe 3 | # 4 | # 5 | 6 | SUMMARY = "gpio-demo application" 7 | SECTION = "PETALINUX/apps" 8 | LICENSE = "MIT" 9 | LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302" 10 | SRC_URI = "file://gpio-demo.c \ 11 | file://Makefile \ 12 | " 13 | S = "${WORKDIR}" 14 | CFLAGS_prepend = "-I ${S}/include" 15 | do_compile() { 16 | oe_runmake 17 | } 18 | do_install() { 19 | install -d ${D}${bindir} 20 | install -m 0755 ${S}/gpio-demo ${D}${bindir} 21 | 22 | } 23 | 24 | -------------------------------------------------------------------------------- /board/soc/linux/golden/project-spec/meta-user/recipes-apps/peekpoke/files/Makefile: -------------------------------------------------------------------------------- 1 | PEEK = peek 2 | POKE = poke 3 | 4 | # Add any other object files to this list below 5 | PEEK_OBJS = peek.o 6 | POKE_OBJS = poke.o 7 | 8 | all: $(PEEK) $(POKE) 9 | 10 | $(POKE): $(POKE_OBJS) 11 | $(CC) $(LDFLAGS) -o $@ $(POKE_OBJS) $(LDLIBS) 12 | 13 | $(PEEK): $(PEEK_OBJS) 14 | $(CC) $(LDFLAGS) -o $@ $(PEEK_OBJS) $(LDLIBS) 15 | 16 | clean: 17 | -rm -f $(POKE) $(PEEK) *.elf *.gdb *.o 18 | 19 | 20 | -------------------------------------------------------------------------------- /board/soc/linux/golden/project-spec/meta-user/recipes-apps/peekpoke/files/peek.c: -------------------------------------------------------------------------------- 1 | /* 2 | * peek utility - for those who remember the good old days! 3 | * 4 | * 5 | * Copyright (C) 2013 - 2016 Xilinx, Inc. All rights reserved. 6 | * 7 | * Permission is hereby granted, free of charge, to any person 8 | * obtaining a copy of this software and associated documentation 9 | * files (the "Software"), to deal in the Software without restriction, 10 | * including without limitation the rights to use, copy, modify, merge, 11 | * publish, distribute, sublicense, and/or sell copies of the Software, 12 | * and to permit persons to whom the Software is furnished to do so, 13 | * subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included 16 | * in all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21 | * IN NO EVENT SHALL XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 23 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | * 25 | * Except as contained in this notice, the name of the Xilinx shall not be used 26 | * in advertising or otherwise to promote the sale, use or other dealings in this 27 | * Software without prior written authorization from Xilinx. 28 | * 29 | */ 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | void usage(char *prog) 38 | { 39 | printf("usage: %s ADDR\n",prog); 40 | printf("\n"); 41 | printf("ADDR may be specified as hex values\n"); 42 | } 43 | 44 | 45 | int main(int argc, char *argv[]) 46 | { 47 | int fd; 48 | void *ptr; 49 | unsigned addr, page_addr, page_offset; 50 | unsigned page_size=sysconf(_SC_PAGESIZE); 51 | 52 | if(argc!=2) { 53 | usage(argv[0]); 54 | exit(-1); 55 | } 56 | 57 | fd=open("/dev/mem",O_RDONLY); 58 | if(fd<1) { 59 | perror(argv[0]); 60 | exit(-1); 61 | } 62 | 63 | addr=strtoul(argv[1],NULL,0); 64 | page_addr=(addr & ~(page_size-1)); 65 | page_offset=addr-page_addr; 66 | 67 | ptr=mmap(NULL,page_size,PROT_READ,MAP_SHARED,fd,(addr & ~(page_size-1))); 68 | if((int)ptr==-1) { 69 | perror(argv[0]); 70 | exit(-1); 71 | } 72 | 73 | printf("0x%08x\n",*((unsigned *)(ptr+page_offset))); 74 | return 0; 75 | } 76 | 77 | 78 | -------------------------------------------------------------------------------- /board/soc/linux/golden/project-spec/meta-user/recipes-apps/peekpoke/files/poke.c: -------------------------------------------------------------------------------- 1 | /* 2 | * poke utility - for those who remember the good old days! 3 | * 4 | 5 | * Copyright (C) 2013 - 2016 Xilinx, Inc. All rights reserved. 6 | * 7 | * Permission is hereby granted, free of charge, to any person 8 | * obtaining a copy of this software and associated documentation 9 | * files (the "Software"), to deal in the Software without restriction, 10 | * including without limitation the rights to use, copy, modify, merge, 11 | * publish, distribute, sublicense, and/or sell copies of the Software, 12 | * and to permit persons to whom the Software is furnished to do so, 13 | * subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included 16 | * in all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21 | * IN NO EVENT SHALL XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 23 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | * 25 | * Except as contained in this notice, the name of the Xilinx shall not be used 26 | * in advertising or otherwise to promote the sale, use or other dealings in this 27 | * Software without prior written authorization from Xilinx. 28 | * 29 | */ 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | void usage(char *prog) 38 | { 39 | printf("usage: %s ADDR VAL\n",prog); 40 | printf("\n"); 41 | printf("ADDR and VAL may be specified as hex values\n"); 42 | } 43 | 44 | int main(int argc, char *argv[]) 45 | { 46 | int fd; 47 | void *ptr; 48 | unsigned val; 49 | unsigned addr, page_addr, page_offset; 50 | unsigned page_size=sysconf(_SC_PAGESIZE); 51 | 52 | fd=open("/dev/mem",O_RDWR); 53 | if(fd<1) { 54 | perror(argv[0]); 55 | exit(-1); 56 | } 57 | 58 | if(argc!=3) { 59 | usage(argv[0]); 60 | exit(-1); 61 | } 62 | 63 | addr=strtoul(argv[1],NULL,0); 64 | val=strtoul(argv[2],NULL,0); 65 | 66 | page_addr=(addr & ~(page_size-1)); 67 | page_offset=addr-page_addr; 68 | 69 | ptr=mmap(NULL,page_size,PROT_READ|PROT_WRITE,MAP_SHARED,fd,(addr & ~(page_size-1))); 70 | if((int)ptr==-1) { 71 | perror(argv[0]); 72 | exit(-1); 73 | } 74 | 75 | *((unsigned *)(ptr+page_offset))=val; 76 | return 0; 77 | } 78 | -------------------------------------------------------------------------------- /board/soc/linux/golden/project-spec/meta-user/recipes-apps/peekpoke/peekpoke.bb: -------------------------------------------------------------------------------- 1 | # 2 | # This is the peekpoke apllication recipe 3 | # 4 | # 5 | 6 | SUMMARY = "peekpoke application" 7 | SECTION = "PETALINUX/apps" 8 | LICENSE = "MIT" 9 | LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302" 10 | SRC_URI = "file://peek.c \ 11 | file://poke.c \ 12 | file://Makefile \ 13 | " 14 | S = "${WORKDIR}" 15 | CFLAGS_prepend = "-I ${S}/include" 16 | do_compile() { 17 | oe_runmake 18 | } 19 | do_install() { 20 | install -d ${D}${bindir} 21 | install -m 0755 ${S}/peek ${D}${bindir} 22 | install -m 0755 ${S}/poke ${D}${bindir} 23 | 24 | } 25 | 26 | -------------------------------------------------------------------------------- /board/soc/linux/golden/project-spec/meta-user/recipes-bsp/device-tree/device-tree.bbappend: -------------------------------------------------------------------------------- 1 | FILESEXTRAPATHS_prepend := "${THISDIR}/files:" 2 | 3 | SRC_URI += "file://system-user.dtsi" 4 | -------------------------------------------------------------------------------- /board/soc/linux/golden/project-spec/meta-user/recipes-bsp/device-tree/files/openamp.dtsi: -------------------------------------------------------------------------------- 1 | / { 2 | reserved-memory { 3 | #address-cells = <2>; 4 | #size-cells = <2>; 5 | ranges; 6 | rproc_0_dma: rproc@3ed400000 { 7 | no-map; 8 | compatible = "shared-dma-pool"; 9 | reg = <0x0 0x3ed40000 0x0 0x100000>; 10 | }; 11 | rproc_0_reserved: rproc@3ed000000 { 12 | no-map; 13 | reg = <0x0 0x3ed00000 0x0 0x40000>; 14 | }; 15 | }; 16 | 17 | zynqmp-rpu { 18 | compatible = "xlnx,zynqmp-r5-remoteproc-1.0"; 19 | #address-cells = <2>; 20 | #size-cells = <2>; 21 | ranges; 22 | core_conf = "split"; 23 | r5_0: r5@0 { 24 | #address-cells = <2>; 25 | #size-cells = <2>; 26 | ranges; 27 | memory-region = <&rproc_0_reserved>, <&rproc_0_dma>; 28 | pnode-id = <0x7>; 29 | mboxes = <&ipi_mailbox_rpu0 0>, <&ipi_mailbox_rpu0 1>; 30 | mbox-names = "tx", "rx"; 31 | tcm_0_a: tcm_0@0 { 32 | reg = <0x0 0xFFE00000 0x0 0x10000>; 33 | pnode-id = <0xf>; 34 | }; 35 | tcm_0_b: tcm_0@1 { 36 | reg = <0x0 0xFFE20000 0x0 0x10000>; 37 | pnode-id = <0x10>; 38 | }; 39 | }; 40 | }; 41 | 42 | 43 | zynqmp_ipi1 { 44 | compatible = "xlnx,zynqmp-ipi-mailbox"; 45 | interrupt-parent = <&gic>; 46 | interrupts = <0 29 4>; 47 | xlnx,ipi-id = <7>; 48 | #address-cells = <1>; 49 | #size-cells = <1>; 50 | ranges; 51 | 52 | /* APU<->RPU0 IPI mailbox controller */ 53 | ipi_mailbox_rpu0: mailbox@ff90000 { 54 | reg = <0xff990600 0x20>, 55 | <0xff990620 0x20>, 56 | <0xff9900c0 0x20>, 57 | <0xff9900e0 0x20>; 58 | reg-names = "local_request_region", 59 | "local_response_region", 60 | "remote_request_region", 61 | "remote_response_region"; 62 | #mbox-cells = <1>; 63 | xlnx,ipi-id = <1>; 64 | }; 65 | }; 66 | }; 67 | -------------------------------------------------------------------------------- /board/soc/linux/golden/project-spec/meta-user/recipes-bsp/device-tree/files/system-user.dtsi: -------------------------------------------------------------------------------- 1 | /include/ "system-conf.dtsi" 2 | / { 3 | }; 4 | -------------------------------------------------------------------------------- /board/soc/linux/golden/project-spec/meta-user/recipes-bsp/device-tree/files/xen-qemu.dtsi: -------------------------------------------------------------------------------- 1 | / { 2 | cpus { 3 | cpu@1 { 4 | //compatible = "disabled"; 5 | device_type = "none"; 6 | }; 7 | cpu@2 { 8 | //compatible = "disabled"; 9 | device_type = "none"; 10 | }; 11 | cpu@3 { 12 | //compatible = "disabled"; 13 | device_type = "none"; 14 | }; 15 | }; 16 | }; 17 | -------------------------------------------------------------------------------- /board/soc/linux/golden/project-spec/meta-user/recipes-bsp/device-tree/files/xen.dtsi: -------------------------------------------------------------------------------- 1 | / { 2 | chosen { 3 | #address-cells = <2>; 4 | #size-cells = <1>; 5 | 6 | xen,xen-bootargs = "console=dtuart dtuart=serial0 dom0_mem=1G bootscrub=0 maxcpus=1 timer_slop=0"; 7 | xen,dom0-bootargs = "console=hvc0 earlycon=xen earlyprintk=xen maxcpus=1 clk_ignore_unused"; 8 | 9 | dom0 { 10 | compatible = "xen,linux-zimage", "xen,multiboot-module"; 11 | reg = <0x0 0x80000 0x3100000>; 12 | }; 13 | }; 14 | 15 | }; 16 | 17 | &smmu { 18 | status = "okay"; 19 | mmu-masters = < &gem0 0x874 20 | &gem1 0x875 21 | &gem2 0x876 22 | &gem3 0x877 23 | &dwc3_0 0x860 24 | &dwc3_1 0x861 25 | &qspi 0x873 26 | &lpd_dma_chan1 0x868 27 | &lpd_dma_chan2 0x869 28 | &lpd_dma_chan3 0x86a 29 | &lpd_dma_chan4 0x86b 30 | &lpd_dma_chan5 0x86c 31 | &lpd_dma_chan6 0x86d 32 | &lpd_dma_chan7 0x86e 33 | &lpd_dma_chan8 0x86f 34 | &fpd_dma_chan1 0x14e8 35 | &fpd_dma_chan2 0x14e9 36 | &fpd_dma_chan3 0x14ea 37 | &fpd_dma_chan4 0x14eb 38 | &fpd_dma_chan5 0x14ec 39 | &fpd_dma_chan6 0x14ed 40 | &fpd_dma_chan7 0x14ee 41 | &fpd_dma_chan8 0x14ef 42 | &sdhci0 0x870 43 | &sdhci1 0x871 44 | &nand0 0x872>; 45 | }; 46 | -------------------------------------------------------------------------------- /board/soc/linux/golden/project-spec/meta-user/recipes-bsp/u-boot/files/bsp.cfg: -------------------------------------------------------------------------------- 1 | CONFIG_I2C_EEPROM=y 2 | CONFIG_SYS_I2C_EEPROM_ADDR=0x0 3 | CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW=0x0 4 | CONFIG_SYS_TEXT_BASE=0x10080000 5 | CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET=0x20 6 | -------------------------------------------------------------------------------- /board/soc/linux/golden/project-spec/meta-user/recipes-bsp/u-boot/files/platform-top.h: -------------------------------------------------------------------------------- 1 | #include 2 | #define CONFIG_SYS_BOOTM_LEN 0xF000000 3 | 4 | #define DFU_ALT_INFO_RAM \ 5 | "dfu_ram_info=" \ 6 | "setenv dfu_alt_info " \ 7 | "image.ub ram $netstart 0x1e00000\0" \ 8 | "dfu_ram=run dfu_ram_info && dfu 0 ram 0\0" \ 9 | "thor_ram=run dfu_ram_info && thordown 0 ram 0\0" 10 | 11 | #define DFU_ALT_INFO_MMC \ 12 | "dfu_mmc_info=" \ 13 | "set dfu_alt_info " \ 14 | "${kernel_image} fat 0 1\\\\;" \ 15 | "dfu_mmc=run dfu_mmc_info && dfu 0 mmc 0\0" \ 16 | "thor_mmc=run dfu_mmc_info && thordown 0 mmc 0\0" 17 | 18 | /*Required for uartless designs */ 19 | #ifndef CONFIG_BAUDRATE 20 | #define CONFIG_BAUDRATE 115200 21 | #ifdef CONFIG_DEBUG_UART 22 | #undef CONFIG_DEBUG_UART 23 | 24 | /* Use define BOOTCOMMAND */ 25 | #define CONFIG_BOOTCOMMAND "run netboot" 26 | 27 | #endif 28 | #endif 29 | -------------------------------------------------------------------------------- /board/soc/linux/golden/project-spec/meta-user/recipes-bsp/u-boot/u-boot-xlnx_%.bbappend: -------------------------------------------------------------------------------- 1 | SRC_URI_append = " file://platform-top.h" 2 | SRC_URI += "file://bsp.cfg" 3 | 4 | FILESEXTRAPATHS_prepend := "${THISDIR}/files:" 5 | -------------------------------------------------------------------------------- /board/soc/linux/golden/project-spec/meta-user/recipes-core/images/petalinux-image-full.bbappend: -------------------------------------------------------------------------------- 1 | #Note: Mention Each package in individual line 2 | # cascaded representation with line breaks are not valid in this file. 3 | IMAGE_INSTALL_append = " peekpoke" 4 | IMAGE_INSTALL_append = " gpio-demo" 5 | IMAGE_INSTALL_append = " gstreamer-vcu-examples" 6 | IMAGE_INSTALL_append = " packagegroup-petalinux-v4lutils" 7 | IMAGE_INSTALL_append = " packagegroup-petalinux-audio" 8 | -------------------------------------------------------------------------------- /board/soc/linux/golden/project-spec/meta-user/recipes-kernel/linux/linux-xlnx/bsp.cfg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WukLab/Clio/7908c3a022fd356cd54616630fcddf59f7f3fd95/board/soc/linux/golden/project-spec/meta-user/recipes-kernel/linux/linux-xlnx/bsp.cfg -------------------------------------------------------------------------------- /board/soc/linux/golden/project-spec/meta-user/recipes-kernel/linux/linux-xlnx/user_2019-11-23-13-00-00.cfg: -------------------------------------------------------------------------------- 1 | # CONFIG_CPU_IDLE is not set 2 | CONFIG_EDAC_CORTEX_ARM64=y 3 | -------------------------------------------------------------------------------- /board/soc/linux/golden/project-spec/meta-user/recipes-kernel/linux/linux-xlnx_%.bbappend: -------------------------------------------------------------------------------- 1 | SRC_URI += "file://bsp.cfg \ 2 | file://user_2019-11-23-13-00-00.cfg \ 3 | " 4 | 5 | FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" 6 | -------------------------------------------------------------------------------- /board/soc/scripts/copy_golden.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Parameter check 4 | if [ -z "$1" ]; then 5 | echo "$0 - Setup Petalinux Project, copy default configs and scripts" 6 | echo "Usage: $0 HARDWARE_DIRECTORY" 7 | fi 8 | 9 | # config 10 | cp ../golden/project-spec/configs/config project-spec/configs 11 | cp ../golden/project-spec/configs/config.old project-spec/configs 12 | cp ../golden/project-spec/configs/rootfs_config project-spec/configs 13 | cp ../golden/project-spec/configs/rootfs_config.old project-spec/configs 14 | 15 | # u-boot startup file 16 | cp ../golden/project-spec/meta-user/recipes-bsp/u-boot/files/platform-top.h project-spec/meta-user/recipes-bsp/u-boot/files 17 | 18 | # Makefile 19 | cp ../golden/Makefile . 20 | echo "HARDWARE_DIR = $1" > config.mk 21 | 22 | 23 | -------------------------------------------------------------------------------- /board/soc/scripts/rst.tcl: -------------------------------------------------------------------------------- 1 | connect 2 | after 2000 3 | target 10 4 | rst -processor 5 | after 300 6 | target 2 7 | rst -srst 8 | -------------------------------------------------------------------------------- /host/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WukLab/Clio/7908c3a022fd356cd54616630fcddf59f7f3fd95/host/.gitignore -------------------------------------------------------------------------------- /host/api_kvs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Wuklab, UCSD. All rights reserved. 3 | */ 4 | #ifndef _HOST_API_KVS_H_ 5 | #define _HOST_API_KVS_H_ 6 | 7 | #include 8 | #include 9 | #include 10 | #include "net/net.h" 11 | 12 | #define MAX_KEY_SIZE 8 13 | 14 | int legomem_kvs_create(struct legomem_context *ctx, struct session_net *ses, uint16_t key_size, 15 | char *key, uint16_t value_size, void *value); 16 | int legomem_kvs_update(struct legomem_context *ctx, struct session_net *ses, uint16_t key_size, 17 | char *key, uint16_t value_size, void *value); 18 | int legomem_kvs_read(struct legomem_context *ctx, struct session_net *ses, uint16_t key_size, 19 | char *key, uint16_t value_size, void *value); 20 | int legomem_kvs_delete(struct legomem_context *ctx, struct session_net *ses, uint16_t key_size, 21 | char *key); 22 | 23 | #endif /* _HOST_API_KVS_H_ */ 24 | -------------------------------------------------------------------------------- /host/api_mv.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Wuklab, UCSD. All rights reserved. 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include "core.h" 15 | #include "net/net.h" 16 | 17 | /* 18 | * Request/Response Packet Layout: 19 | * [ETH/IP/UDP/GBN/Lego/op_mvobj/.../] 20 | * 21 | * TODO 22 | * Figrue out struct layout, opcode position. 23 | * Build APIs etc. 24 | */ 25 | -------------------------------------------------------------------------------- /host/board_emulator/buddy.c: -------------------------------------------------------------------------------- 1 | ../../board/soc/core/buddy.c -------------------------------------------------------------------------------- /host/board_emulator/buddy.h: -------------------------------------------------------------------------------- 1 | ../../board/soc/core/buddy.h -------------------------------------------------------------------------------- /host/board_emulator/core.h: -------------------------------------------------------------------------------- 1 | ../../board/soc/core/core.h -------------------------------------------------------------------------------- /host/board_emulator/external.h: -------------------------------------------------------------------------------- 1 | ../../board/soc/core/external.h -------------------------------------------------------------------------------- /host/board_emulator/handler.c: -------------------------------------------------------------------------------- 1 | ../../board/soc/core/handler.c -------------------------------------------------------------------------------- /host/board_emulator/pgtable.c: -------------------------------------------------------------------------------- 1 | ../../board/soc/core/pgtable.c -------------------------------------------------------------------------------- /host/board_emulator/pgtable.h: -------------------------------------------------------------------------------- 1 | ../../board/soc/core/pgtable.h -------------------------------------------------------------------------------- /host/board_emulator/rbtree.c: -------------------------------------------------------------------------------- 1 | ../../board/soc/core/rbtree.c -------------------------------------------------------------------------------- /host/board_emulator/sched.c: -------------------------------------------------------------------------------- 1 | ../../board/soc/core/sched.c -------------------------------------------------------------------------------- /host/board_emulator/vm.c: -------------------------------------------------------------------------------- 1 | ../../board/soc/core/vm.c -------------------------------------------------------------------------------- /host/config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Wuklab, UCSD. All rights reserved. 3 | */ 4 | 5 | #ifndef _HOST_CONFIG_H_ 6 | #define _HOST_CONFIG_H_ 7 | 8 | #if 0 9 | # define LEGOMEM_DEBUG 10 | #endif 11 | 12 | /* 13 | * Once enabled, the system will dump all transmitted/received packets. 14 | * Use git grep to find where they are used. 15 | */ 16 | #if 0 17 | # define CONFIG_NETWORK_DUMP_TX 18 | #endif 19 | #if 0 20 | # define CONFIG_NETWORK_DUMP_RX 21 | #endif 22 | 23 | /* 24 | * Choose which transport layer to use. 25 | * GBN: go-back-n ack-based retranmission, no CC 26 | * RPC: RPC-style, no ack, with an AIMD CC. 27 | */ 28 | #if 0 29 | # define CONFIG_TRANSPORT_GBN 30 | #else 31 | # define CONFIG_TRANSPORT_RPC 32 | #endif 33 | 34 | /* 35 | * Once enabled, we will track the read/write dependency. 36 | * If current access address is depedent on a prior in-flight access, 37 | * the current acess will be blocked until the prior request has finished. 38 | * 39 | * This is not controlly memory consistency model. 40 | * It could be used along side weak consistency model. 41 | */ 42 | #if 0 43 | #define CONFIG_MEMORY_MODEL_ENABLE_DEPENDENCY_TRACKING 44 | #endif 45 | 46 | /* 47 | * Once enabled, the client side will track the number of outstanding 48 | * reads and writes. And fence will use those numbers. 49 | * 50 | * Tracking has a cost, each operation is an atomic operation. 51 | * That's why we make this optional. 52 | */ 53 | #if 0 54 | #define CONFIG_ENABLE_FENCE 55 | #endif 56 | 57 | #endif /* _HOST_CONFIG_H_ */ 58 | -------------------------------------------------------------------------------- /host/cpu.c: -------------------------------------------------------------------------------- 1 | int gbn_polling_thread_cpu = 0; 2 | int mgmt_dispatcher_thread_cpu = 1; 3 | -------------------------------------------------------------------------------- /host/memory_model.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Wuklab, UCSD. All rights reserved. 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include "core.h" 18 | #include "net/net.h" 19 | 20 | #ifdef CONFIG_MEMORY_MODEL_ENABLE_DEPENDENCY_TRACKING 21 | void mc_wait_and_set_dependency(struct session_net *ses, 22 | unsigned long __remote addr, size_t total_size, int op) 23 | { 24 | unsigned long start_index, nr_pages; 25 | 26 | start_index = addr >> PAGE_SHIFT; 27 | nr_pages = PAGE_ALIGN(total_size) >> PAGE_SHIFT; 28 | 29 | /* 30 | * TODO 31 | * add checking and wait logic. 32 | * actually some sort of lock is needed. those bitmap 33 | * operations are not atomic. a session can be used by multiple threads. 34 | */ 35 | 36 | switch (op) { 37 | case MEMORY_MODEL_OP_READ: 38 | bitmap_set(ses->outstanding_reads_map, start_index, nr_pages); 39 | break; 40 | case MEMORY_MODEL_OP_WRITE: 41 | bitmap_set(ses->outstanding_writes_map, start_index, nr_pages); 42 | break; 43 | default: 44 | BUG(); 45 | } 46 | } 47 | 48 | void mc_clear_dependency(struct session_net *ses, unsigned long __remote addr, 49 | size_t total_size, int op) 50 | { 51 | unsigned long start_index, nr_pages; 52 | 53 | start_index = addr >> PAGE_SHIFT; 54 | nr_pages = PAGE_ALIGN(total_size) >> PAGE_SHIFT; 55 | 56 | switch (op) { 57 | case MEMORY_MODEL_OP_READ: 58 | bitmap_clear(ses->outstanding_reads_map, start_index, nr_pages); 59 | break; 60 | case MEMORY_MODEL_OP_WRITE: 61 | bitmap_clear(ses->outstanding_writes_map, start_index, nr_pages); 62 | break; 63 | default: 64 | BUG(); 65 | } 66 | } 67 | #else 68 | void mc_wait_and_set_dependency(struct session_net *ses, 69 | unsigned long __remote addr, size_t total_size, int op) 70 | { } 71 | 72 | void mc_clear_dependency(struct session_net *ses, unsigned long __remote addr, 73 | size_t total_size, int op) 74 | { } 75 | #endif 76 | -------------------------------------------------------------------------------- /host/net/net.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Wuklab, UCSD. All rights reserved. 3 | */ 4 | #ifndef _HOST_NET_NET_H_ 5 | #define _HOST_NET_NET_H_ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | extern int sysctl_link_mtu; 24 | 25 | int init_net(struct endpoint_info *local_ei); 26 | void dump_packet_headers(void *packet, char *str_buf); 27 | void __dump_packet_headers(void *packet, char *str_buf); 28 | 29 | struct session_net *net_open_session(struct endpoint_info *local_ei, 30 | struct endpoint_info *remote_ei); 31 | int net_close_session(struct session_net *ses); 32 | 33 | struct session_raw_socket { 34 | int sockfd; 35 | struct ifreq if_idx; 36 | struct ifreq if_mac; 37 | struct sockaddr_ll saddr; 38 | } ____cacheline_aligned; 39 | 40 | struct session_udp_socket { 41 | int sockfd; 42 | struct sockaddr_in remote_addr; 43 | } ____cacheline_aligned; 44 | 45 | 46 | /* 47 | * Raw Verbs 48 | */ 49 | #define BUFFER_SIZE (2048) /* maximum size of each send buffer */ 50 | #define NR_BUFFER_DEPTH (1024) 51 | #define MAX_RECV_BUFFER_SIZE (BUFFER_SIZE * NR_BUFFER_DEPTH) 52 | #define NR_MAX_OUTSTANDING_SEND_WR (32) 53 | #define NR_BATCH_POST_RECV (32) 54 | #define NR_MAX_RECV_BATCH (32) 55 | 56 | struct session_raw_verbs { 57 | struct ibv_pd *pd; 58 | struct ibv_qp *qp; 59 | 60 | struct ibv_cq *send_cq; 61 | unsigned long nr_post_send; 62 | 63 | struct ibv_cq *recv_cq; 64 | struct ibv_mr *recv_mr; 65 | void *recv_buf; 66 | 67 | struct ibv_mr *send_mr; 68 | void *send_buf; 69 | size_t send_buf_size; 70 | 71 | struct ibv_flow *eth_flow; 72 | unsigned int rx_udp_port; 73 | 74 | struct ibv_wc send_wc[NR_MAX_OUTSTANDING_SEND_WR]; 75 | 76 | struct ibv_sge recv_sge[NR_BUFFER_DEPTH]; 77 | struct ibv_recv_wr recv_wr[NR_BUFFER_DEPTH]; 78 | struct ibv_wc recv_wc[NR_MAX_RECV_BATCH]; 79 | 80 | int recv_head; 81 | int nr_delayed_recvs; 82 | } ____cacheline_aligned; 83 | 84 | void dump_gbn_session(struct session_net *net, bool dump_rx_ring); 85 | struct ibv_mr *raw_verbs_reg_mr(void *buf, size_t buf_size); 86 | 87 | #endif /* _HOST_NET_NET_H_ */ 88 | -------------------------------------------------------------------------------- /host/net/transport_bypass.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Wuklab, UCSD. All rights reserved. 3 | * 4 | * Dummy transport layer that uses raw net directly. 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | #include "net.h" 19 | #include "../core.h" 20 | 21 | static inline int bypass_send_one(struct session_net *net, 22 | void *buf, size_t buf_size, void *route) 23 | { 24 | return raw_net_send(net, buf, buf_size, route); 25 | } 26 | 27 | static inline int bypass_receive_one(struct session_net *net, 28 | void *buf, size_t buf_size) 29 | { 30 | return raw_net_receive(net, buf, buf_size); 31 | } 32 | 33 | static inline int bypass_receive_one_zerocopy(struct session_net *net, 34 | void **buf, size_t *buf_size) 35 | { 36 | return raw_net_receive_zerocopy(net, buf, buf_size); 37 | } 38 | 39 | static inline int bypass_receive_one_zerocopy_nb(struct session_net *net, 40 | void **buf, size_t *buf_size) 41 | { 42 | return raw_net_receive_zerocopy(net, buf, buf_size); 43 | } 44 | 45 | static inline int bypass_receive_one_nb(struct session_net *net, 46 | void *buf, size_t buf_size) 47 | { 48 | return raw_net_receive_nb(net, buf, buf_size); 49 | } 50 | 51 | static inline int 52 | bypass_open_session(struct session_net *ses, struct endpoint_info *local_ei, 53 | struct endpoint_info *remote_ei) 54 | { 55 | return 0; 56 | } 57 | 58 | static inline int 59 | bypass_close_session(struct session_net *ses) 60 | { 61 | return 0; 62 | } 63 | 64 | static inline int bypass_init_once(struct endpoint_info *local_ei) 65 | { 66 | return 0; 67 | } 68 | 69 | static inline void bypass_exit(void) 70 | { 71 | return; 72 | } 73 | 74 | struct transport_net_ops transport_bypass_ops = { 75 | .name = "transport_bypass", 76 | 77 | .init_once = bypass_init_once, 78 | .exit = bypass_exit, 79 | 80 | .open_session = bypass_open_session, 81 | .close_session = bypass_close_session, 82 | 83 | .send_one = bypass_send_one, 84 | .receive_one = bypass_receive_one, 85 | .receive_one_nb = bypass_receive_one_nb, 86 | .receive_one_zerocopy = bypass_receive_one_zerocopy, 87 | .receive_one_zerocopy_nb= bypass_receive_one_zerocopy_nb, 88 | 89 | .reg_send_buf = default_transport_reg_send_buf, 90 | }; 91 | -------------------------------------------------------------------------------- /host/pp.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020. Wuklab. All rights reserved. 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include "core.h" 24 | 25 | /* 26 | * This is automatically generated by linker. 27 | * Oddly, unlike the kernel building with customized linker script, 28 | * here we need to use pointer of pointer to get the address. 29 | */ 30 | extern struct profile_point *__start_profile_point, *__stop_profile_point; 31 | 32 | DEFINE_PROFILE_POINT(unused); 33 | 34 | /* 35 | * TODO 36 | */ 37 | static inline unsigned long cycle2ns(unsigned long cycles) 38 | { 39 | return cycles / 1; 40 | } 41 | 42 | void print_profile_point(struct profile_point *pp) 43 | { 44 | struct timespec ts = {0, 0}; 45 | unsigned long nr = 0, avg_ns = 0, time_ns = 0; 46 | 47 | nr = pp->nr; 48 | if (nr == 0) 49 | return; 50 | 51 | time_ns = cycle2ns(pp->time_cycles); 52 | ts.tv_sec = time_ns / NSEC_PER_SEC; 53 | ts.tv_nsec = time_ns % NSEC_PER_SEC; 54 | 55 | avg_ns = DIV_ROUND_UP(time_ns, nr); 56 | 57 | printf("%-s %-35s %-6ld.%09ld %-16ld %-16ld\n", 58 | pp->enabled? " on" : " off", 59 | pp->pp_name, 60 | (long)ts.tv_sec, (long)ts.tv_nsec, 61 | nr, 62 | avg_ns); 63 | } 64 | 65 | void print_profile_points(void) 66 | { 67 | struct profile_point *pp; 68 | int count = 0; 69 | 70 | printf("\n"); 71 | printf("LegoMem Profile Points\n"); 72 | printf("Status Name Total(cycles) NR Avg(cycles)\n"); 73 | printf("------- ----------------------------------- ---------------- ---------------- ----------------\n"); 74 | for (pp = (struct profile_point *)&__start_profile_point; 75 | pp < (struct profile_point *)&__stop_profile_point; pp++) { 76 | print_profile_point(pp); 77 | count++; 78 | } 79 | printf("------- ----------------------------------- ---------------- ---------------- ----------------\n"); 80 | printf("\n"); 81 | } 82 | -------------------------------------------------------------------------------- /host/prepare.sh: -------------------------------------------------------------------------------- 1 | # 2 | # This simple script will setup the hugepage. 3 | # You should adjust the following numbers according to your system setting. 4 | # 5 | 6 | NR_2MB_PAGES=1024 7 | NR_1GB_PAGES=8 8 | 9 | # 2MB page 10 | echo $NR_2MB_PAGES > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages 11 | 12 | # 1GB page 13 | echo $NR_1GB_PAGES > /sys/devices/system/node/node0/hugepages/hugepages-1048576kB/nr_hugepages 14 | -------------------------------------------------------------------------------- /host/rsrync.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | src="ys@wuklab-02.sysnet.ucsd.edu:~/legomem/lego-mem/host/*" 4 | rsync -a --exclude ".git" --exclude "*.o" -e "ssh -p 456" $src ./ 5 | -------------------------------------------------------------------------------- /host/scripts/test_alloc_free.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Run test/test_alloc 4 | # 5 | # You must have started a monitor, a board, and this host. 6 | # Because the board will not join the cluster at this point. 7 | # we need to manually add it. Change IP for your testing. 8 | # 9 | # My testing model 10 | # - run both monitor and host on wuklab02 11 | # $ ./script/test_alloc_free.sh 1 12 | # $ ./script/test_alloc_free.sh 2 13 | # 14 | 15 | set -x 16 | set -e 17 | 18 | # Knob 19 | # Make sure board is already up and running 20 | board_ip="192.168.1.23:1234" 21 | 22 | monitor_port=1234 23 | monitor_ip="192.168.1.3" 24 | 25 | if [ "$1" == "1" ]; then 26 | if true; then 27 | #if false; then 28 | ./monitor.o \ 29 | --dev=p4p1 \ 30 | --port=$monitor_port \ 31 | --add_board=$board_ip 32 | else 33 | ./monitor.o \ 34 | --dev=p4p1 \ 35 | --port=$monitor_port 36 | fi 37 | elif [ "$1" == "2" ]; then 38 | ./host.o \ 39 | --monitor=$monitor_ip:$monitor_port \ 40 | --dev=p4p1 \ 41 | --port=1234 \ 42 | --run_test=alloc_free 43 | elif [ "$1" == "3" ]; then 44 | ./board_emulator.o \ 45 | --monitor=$monitor_ip:$monitor_port \ 46 | --d=p4p1 \ 47 | --port=9998 48 | fi 49 | -------------------------------------------------------------------------------- /host/scripts/test_board.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -x 4 | set -e 5 | 6 | # Single board, no monitor setting 7 | 8 | # Note 9 | # 1) You don't need to start a monitor, the address below is just for setup purpose. 10 | # 2) --add_board needs to be the real board's IP and port, make sure it's running beforehand. 11 | # Also make sure the board has ARP protocol up and running. 12 | # 3) Use the --dev accordingly, make sure you use the Mellanox NIC. 13 | # Usually it is p4p1 or ens4 14 | # 4) At this point (Mar 28), you have to use `--add_board` to manually add a remote board. 15 | # Because the board has no join_cluster feature. 16 | # 5) we now only supports 1 added board. It's possible to have more. Upon request. 17 | # 18 | # And without monitor, you can not use the following legomem APIs because they will 19 | # try to contact monitor by default: 20 | # - legomem_open/close_context 21 | # - legomem_alloc/free 22 | 23 | ./host.o --monitor=127.0.0.1:8888 --skip_join \ 24 | --port=1234 --dev=p4p1 \ 25 | --net_trans_ops=gbn \ 26 | --run_test --add_board="192.168.1.31:1234" 27 | -------------------------------------------------------------------------------- /host/scripts/test_conn.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -x 4 | set -e 5 | 6 | # Make sure board is already up and running 7 | board_ip="192.168.1.23:1234" 8 | 9 | monitor_port=10000 10 | monitor_ip="192.168.1.5" 11 | 12 | if [ "$1" == "1" ]; then 13 | ./monitor.o \ 14 | --dev=p4p1 \ 15 | --port=$monitor_port \ 16 | --add_board=$board_ip 17 | elif [ "$1" == "2" ]; then 18 | ./host.o \ 19 | --monitor=$monitor_ip:$monitor_port \ 20 | --dev=ens4 \ 21 | --port=10000 \ 22 | --run_test=rw_same 23 | fi 24 | -------------------------------------------------------------------------------- /host/scripts/test_data_frame.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -x 4 | set -e 5 | 6 | # Make sure board is already up and running 7 | board_ip="192.168.1.23:1234" 8 | 9 | monitor_port=15000 10 | monitor_ip="192.168.1.5" 11 | 12 | if [ "$1" == "1" ]; then 13 | ./monitor.o \ 14 | --dev=ens4 \ 15 | --port=$monitor_port \ 16 | --add_board=$board_ip 17 | elif [ "$1" == "2" ]; then 18 | ./host.o \ 19 | --monitor=$monitor_ip:$monitor_port \ 20 | --dev=ens4 \ 21 | --port=20000 \ 22 | --run_test=test_dataframe 23 | fi 24 | -------------------------------------------------------------------------------- /host/scripts/test_jpeg.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -x 4 | set -e 5 | 6 | # Make sure board is already up and running 7 | board_ip="192.168.1.23:1234" 8 | 9 | monitor_port=10000 10 | monitor_ip="192.168.1.5" 11 | 12 | if [ "$1" == "1" ]; then 13 | ./monitor.o \ 14 | --dev=ens4 \ 15 | --port=$monitor_port \ 16 | --add_board=$board_ip 17 | elif [ "$1" == "2" ]; then 18 | ./host.o \ 19 | --monitor=$monitor_ip:$monitor_port \ 20 | --dev=ens4 \ 21 | --port=10000 \ 22 | --run_test=test_jpeg 23 | fi 24 | -------------------------------------------------------------------------------- /host/scripts/test_kvs_simple.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | set -x 4 | 5 | BOARD_IP=192.168.255.4:1234 6 | 7 | sudo ./host.o -m 192.168.1.2:20000 --skip_join -p 10000 -d ens5f0 --run_test=kvs_simple --add_board=$BOARD_IP 8 | -------------------------------------------------------------------------------- /host/scripts/test_migration.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # For test/test_migration.c 3 | 4 | set -x 5 | 6 | board_ip="192.168.1.9:1234" 7 | 8 | if [ "$1" == "1" ]; then 9 | ./monitor.o -d ens4 -p 1234 --add_board=$board_ip 10 | elif [ "$1" == "2" ]; then 11 | # 12 | # We need at least two board instances to test migration. 13 | # 14 | # We can skip this if we have two real boards 15 | # 16 | ./board_emulator.o -d lo -p 9998 -m 127.0.0.1:9999 & 17 | ./board_emulator.o -d lo -p 9997 -m 127.0.0.1:9999 18 | elif [ "$1" == "3" ]; then 19 | ./host.o \ 20 | -d ens4 \ 21 | -p 40000 \ 22 | -m 192.168.1.2:20000 \ 23 | --run_test=migration 24 | elif [ "$1" == "4" ]; then 25 | pkill -f monitor.o 26 | pkill -f host.o 27 | pkill -f board_emulator.o 28 | fi 29 | -------------------------------------------------------------------------------- /host/scripts/test_pingpong_soc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Run test/test_pingpong_soc.c 3 | 4 | set -x 5 | set -e 6 | 7 | ./host.o --monitor=127.0.0.1:8888 --skip_join \ 8 | --net_trans_ops=gbn \ 9 | --run_test=pingpong_soc \ 10 | --port=1234 \ 11 | --dev=p4p1 \ 12 | --add_board="192.168.1.31:1234" 13 | -------------------------------------------------------------------------------- /host/scripts/test_pointer_chasing.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | set -x 4 | 5 | TEST_NAME=pointer_chasing 6 | 7 | # Change -m, -p, -d accordingly 8 | ./host.o -m 192.168.1.3:10000 -p 10000 -d ens4 --run_test=$TEST_NAME 9 | -------------------------------------------------------------------------------- /host/scripts/test_pte.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ./host.o --monitor=127.0.0.1:8888 --skip_join \ 4 | --port=1234 --dev=p4p1 \ 5 | --run_test=test_pte --add_board="192.168.1.31:1234" 6 | -------------------------------------------------------------------------------- /host/scripts/test_raw_net.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This script shows how to run test_raw_net.c 4 | # 5 | # This test case is not straightforward to setup because the current stack 6 | # is already a bit complex and integrated with the GBN. Nontherless, we have 7 | # added enough tuning options to make it possible to test via command line options. 8 | # 9 | # 1. The requirement is that we must skip the GBN stack by passing: 10 | # `--net_trans_ops=bypass` 11 | # 2. Using any of the raw net ops is fine. 12 | # 3. For host side, we need to pass `--skip_join` otherwise host will send msg 13 | # to host and wait for reply. This won't work because we need to further disable 14 | # host side mgmt polling thread. We cannot have another caller use `raw_net_receive`. 15 | # 4. Last, we need to change the code a bit to disable the polling thread, 16 | # add this line to host's dispatcher(): 17 | # `while (1) ;` 18 | # 19 | # The following two lines show a possible setup: 20 | # - At 02, run monitor. 21 | # - At 05, run host. 22 | # 23 | # 24 | # This test will use test_raw_net.c 25 | # And it will report the RTT 26 | 27 | usage() { 28 | echo "Usage:" 29 | echo " $ ./test_raw_net.sh 1 (Run monitor image)" 30 | echo " $ ./test_raw_net.sh 2 (Run host image)" 31 | echo "Please change the IPs in the command" 32 | } 33 | 34 | set -x 35 | set -e 36 | 37 | if [ "$1" == "1" ]; then 38 | ./monitor.o --dev p4p1 --port=8888 --net_trans_ops=bypass --net_raw_ops=raw_verbs 39 | elif [ "$1" == "2" ]; then 40 | ./host.o -m 127.0.0.1:8888 -p 8880 -d ens4 --skip_join --net_trans_ops=bypass --net_raw_ops=raw_verbs --run_test --add_board=192.168.1.2:8888 41 | else 42 | usage 43 | fi 44 | -------------------------------------------------------------------------------- /host/scripts/test_read.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Run test/test_read_write 4 | # 5 | # You must have started a monitor, a board, and this host. 6 | # Because the board will not join the cluster at this point. 7 | # we need to manually add it. Change IP for your testing. 8 | # 9 | # testing model 10 | # $ ./script/test_alloc_free.sh 1 e.g., on wuklab03 11 | # $ ./script/test_alloc_free.sh 2 e.g., on wuklab02 12 | # 13 | 14 | set -x 15 | set -e 16 | 17 | # Knob 18 | # Make sure board is already up and running 19 | board_ip="192.168.1.23:1234" 20 | 21 | monitor_port=20000 22 | monitor_ip="192.168.1.2" 23 | 24 | if [ "$1" == "1" ]; then 25 | if true; then 26 | # 27 | # FAT NOTE 28 | # 29 | # Please tune the nr of boards 30 | # 31 | ./monitor.o \ 32 | --dev=p4p1 \ 33 | --port=$monitor_port \ 34 | --add_board=192.168.1.23:1234 \ 35 | --add_board=192.168.1.22:1234 36 | else 37 | ./monitor.o \ 38 | --dev=p4p1 \ 39 | --port=$monitor_port 40 | fi 41 | elif [ "$1" == "2" ]; then 42 | # 43 | # FAT NOTE 44 | # 45 | # Choose your --run_test. 46 | # 47 | ./host.o \ 48 | --monitor=$monitor_ip:$monitor_port \ 49 | --dev=ens4 \ 50 | --port=8888 \ 51 | --run_test=rw_multiboard 52 | 53 | #--run_test=rw_inline 54 | #--run_test=rw_fault 55 | #--run_test=rw_tlb 56 | #--run_test=rw_same 57 | #--run_test=rw_multiboard 58 | 59 | elif [ "$1" == "3" ]; then 60 | ./board_emulator.o \ 61 | --monitor=$monitor_ip:$monitor_port \ 62 | --d=p4p1 \ 63 | --port=9998 64 | fi 65 | -------------------------------------------------------------------------------- /host/scripts/test_rel_net_mgmt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -x 4 | set -e 5 | 6 | # 7 | # The tests run between a host and a monitor, 8 | # the file is test_rel_net_mgmt.c 9 | # 10 | # The test commands are nothing special but normal args. 11 | # 12 | # 13 | # REMEMBER to change dev name and ports accordingly 14 | # 15 | 16 | # monitor side 17 | #./monitor.o --dev ens4 --port 8888 18 | 19 | # 20 | # FAT NOTE 21 | # 22 | # If you are testing against a real board, 23 | # you do NOT need to start soc code. 24 | # 25 | ./host.o --monitor=127.0.0.1:8888 --skip_join \ 26 | --port=8888 --dev=p4p1 \ 27 | --run_test=relnet_mgmt --add_board="192.168.1.23:1234" 28 | -------------------------------------------------------------------------------- /host/scripts/test_rel_net_normal.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Run test/test_rel_net_normal.c 4 | # Mode 1: between host and board 5 | # Mode 2: between host and monitor 6 | # 7 | 8 | set -x 9 | set -e 10 | 11 | # Mode 1 12 | if [ 1 ]; then 13 | 14 | # 15 | # FAT NOTE 16 | # 17 | # You need to start soc ./core.o 18 | # coz we need to open normal session 19 | # 20 | ./host.o --monitor=127.0.0.1:8888 --skip_join \ 21 | --port=1234 --dev=p4p1 \ 22 | --run_test=relnet_normal --add_board="192.168.1.23:1234" 23 | 24 | else 25 | 26 | # Mode 2 27 | # monitor side 28 | ./monitor.o --dev ens4 --port 8888 29 | 30 | # host side 31 | ./host.o -m 192.168.1.5:8888 -p 7777 -d p4p1 --run_test=relnet_normal 32 | 33 | fi 34 | -------------------------------------------------------------------------------- /host/scripts/test_rw_presetup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | set -x 4 | 5 | NETDEV=p4p1 6 | TEST_NAME=rw_presetup 7 | 8 | # TUNE ME during test 9 | BOARD_IP=192.168.1.26:1234 10 | 11 | # No monitor required! 12 | sudo ./host.o -m 192.168.1.3:10000 --skip_join -p 10000 \ 13 | -d $NETDEV \ 14 | --run_test=$TEST_NAME \ 15 | --add_board=$BOARD_IP 16 | 17 | #--net_raw_ops=raw_socket \ 18 | -------------------------------------------------------------------------------- /host/scripts/test_rw_processes.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | set -x 4 | 5 | NETDEV=p4p1 6 | TEST_NAME=rw_processes 7 | 8 | # TUNE ME during test 9 | BOARD_IP=192.168.1.26:1234 10 | 11 | # No monitor required! 12 | sudo ./host.o -m 192.168.1.3:10000 --skip_join -p 10000 \ 13 | -d $NETDEV \ 14 | --run_test=$TEST_NAME \ 15 | --add_board=$BOARD_IP 16 | 17 | #--net_raw_ops=raw_socket \ 18 | -------------------------------------------------------------------------------- /host/scripts/test_rw_pte_mr.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | set -x 4 | 5 | NETDEV=p4p1 6 | TEST_NAME=rw_pte_mr 7 | 8 | # TUNE ME during test 9 | BOARD_IP=192.168.1.26:1234 10 | 11 | # No monitor required! 12 | sudo ./host.o -m 192.168.1.3:10000 --skip_join -p 10000 \ 13 | -d $NETDEV \ 14 | --run_test=$TEST_NAME \ 15 | --add_board=$BOARD_IP 16 | 17 | #--net_raw_ops=raw_socket \ 18 | -------------------------------------------------------------------------------- /host/scripts/test_rw_threads.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | set -x 4 | 5 | NETDEV=p4p1 6 | TEST_NAME=rw_threads 7 | 8 | # TUNE ME during test 9 | BOARD_IP=192.168.1.26:1234 10 | 11 | # No monitor required! 12 | sudo ./host.o -m 192.168.1.3:10000 --skip_join -p 10000 \ 13 | -d $NETDEV \ 14 | --run_test=$TEST_NAME \ 15 | --add_board=$BOARD_IP 16 | 17 | #--net_raw_ops=raw_socket \ 18 | -------------------------------------------------------------------------------- /host/scripts/test_session.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Run test/test_session.c 4 | # Mode 1: between host and board 5 | # Mode 2: between host and monitor 6 | # 7 | 8 | set -x 9 | set -e 10 | 11 | # Mode 1 12 | if [ 1 ]; then 13 | ./host.o --monitor=127.0.0.1:8888 --skip_join \ 14 | --port=1234 --dev=p4p1 --net_trans_ops=gbn \ 15 | --run_test=session --add_board="192.168.1.31:1234" 16 | 17 | else 18 | 19 | # Mode 2 20 | # You also need to start a monitor 21 | ./host.o --monitor=127.0.0.1:8888 \ 22 | --port=1234 --dev=p4p1 --net_trans_ops=gbn \ 23 | --run_test=session 24 | fi 25 | -------------------------------------------------------------------------------- /host/scripts/test_ycsb.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | set -x 4 | 5 | BOARD_IP=192.168.255.4:1234 6 | 7 | sudo ./host.o -m 192.168.1.2:20000 --skip_join -p 10000 -d ens5f0 --run_test=kvs_ycsb --add_board=$BOARD_IP 8 | -------------------------------------------------------------------------------- /host/stat.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Wuklab, UCSD. All rights reserved. 3 | */ 4 | #ifndef _HOST_STAT_H_ 5 | #define _HOST_STAT_H_ 6 | 7 | /* 8 | * Stat counting is not free. We are using one single global variable 9 | * with atomic inc. The overhead is not trivial. Thus we are having 10 | * an option to disable it. 11 | */ 12 | #ifdef CONFIG_DEBUG_STAT 13 | static __always_inline void inc_stat(enum STAT_TYPES item) 14 | { 15 | asm volatile("lock; incq %0" 16 | : "=m" (default_local_bi->stat[item]) 17 | : "m" (default_local_bi->stat[item])); 18 | } 19 | 20 | static inline void __dump_stats(unsigned long *stat) 21 | { 22 | int i; 23 | 24 | for (i = 0; i < NR_STAT_TYPES; i++) { 25 | printf("%-40s %10lu\n", 26 | stat_type_string(i), 27 | stat[i]); 28 | } 29 | } 30 | 31 | static inline void dump_stats(void) 32 | { 33 | __dump_stats(default_local_bi->stat); 34 | } 35 | #else 36 | static inline void inc_stat(enum STAT_TYPES item) { } 37 | static inline void __dump_stats(unsigned long *stat) { } 38 | static inline void dump_stats(void) { } 39 | #endif 40 | 41 | #endif /* _HOST_STAT_H_ */ 42 | -------------------------------------------------------------------------------- /host/test.sh: -------------------------------------------------------------------------------- 1 | ip addr del 192.168.0.10/24 dev eth0 2 | ip addr add 192.168.0.22/24 dev eth0 3 | insmod /lib/modules/4.19.0/extra/xilinx-axidma.ko 4 | # Change IP 192.168.1.232 5 | devmem 0xA000C000 32 0xC0A80116 6 | devmem 0xA000C004 32 0xfabeec16 7 | -------------------------------------------------------------------------------- /host/test/jpeg/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: clean 2 | 3 | # NETLIB ?= net-nng.o 4 | RMEMIMPL ?= rmem-legomem.c 5 | 6 | CFLAGS := -Werror -g -I../../../include -DCONFIG_ARCH_X86 -O2 7 | LD := gcc 8 | LDLIBS := ${LDLIBS} -libverbs -lpthread -ljpeg 9 | 10 | APPS := arrayclient arrayserver 11 | COMMON := config.o common.o rarray.o $(NETLIB) $(RMEMIMPL) 12 | 13 | TP:=../.. 14 | CLIOSRCS := $(TP)/board.c \ 15 | $(TP)/cpu.c \ 16 | $(TP)/util.c \ 17 | $(TP)/api.c \ 18 | $(TP)/context.c \ 19 | $(TP)/session.c \ 20 | $(TP)/common.c \ 21 | $(TP)/watchdog.c \ 22 | $(TP)/net/core.c \ 23 | $(TP)/net/raw_verbs.c \ 24 | $(TP)/net/transport_bypass.c \ 25 | $(TP)/net/transport_gbn.c \ 26 | $(TP)/net/transport_rpc.c \ 27 | $(TP)/api_kvs.c \ 28 | $(TP)/memory_model.c \ 29 | $(TP)/lib/bitmap.c 30 | 31 | all: ${APPS} 32 | 33 | arrayclient: arrayclient.c $(COMMON) 34 | ${LD} ${CFLAGS} -o $@ $^ ${LDLIBS} 35 | 36 | arrayserver: arrayserver.c $(CLIOSRCS) $(COMMON) 37 | ${LD} ${CFLAGS} -o $@ $^ ${LDLIBS} 38 | 39 | clean: 40 | rm -f *.o ${APPS} 41 | 42 | -------------------------------------------------------------------------------- /host/test/jpeg/README.md: -------------------------------------------------------------------------------- 1 | # requirements 2 | 3 | common: libnng-dev 4 | jpeg: libjpeg-dev 5 | -------------------------------------------------------------------------------- /host/test/jpeg/arrayserver.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "test.h" 6 | #include 7 | 8 | static struct rdma_conn static_conn; 9 | 10 | int server() { 11 | 12 | struct rdma_conn conn; 13 | memset(&conn, 0, sizeof(struct rdma_conn)); 14 | conn.port = config.server.port; 15 | 16 | // TODO: goto common 17 | create_context(&config.server, &conn); 18 | 19 | // Create PD 20 | conn.pd = ibv_alloc_pd(conn.context); 21 | if (conn.pd == NULL) { 22 | printf("iDIE"); 23 | return -1; 24 | } 25 | 26 | // Create CQ 27 | conn.cq = ibv_create_cq(conn.context, config.cq_size, NULL, NULL, 0); 28 | 29 | // Create QP 30 | create_qp(&conn); 31 | 32 | // create MRs 33 | int access = IBV_ACCESS_LOCAL_WRITE | IBV_ACCESS_REMOTE_WRITE | IBV_ACCESS_REMOTE_READ; 34 | if (config.server_enable_odp) 35 | access |= IBV_ACCESS_ON_DEMAND; 36 | for (int i = 0; i < config.server_num_mr; i++) 37 | create_mr(&conn, config.server_mr_size, access); 38 | 39 | // DO Extra job 40 | if (config.program != NULL) { 41 | 42 | 43 | if (strcmp("array-jpg", config.program) == 0) { 44 | printf("Do server job %s ...\n", config.program); 45 | int jpg_size = config.jpg_size; 46 | 47 | int cells = config.server_mr_size / config.array_cell_size; 48 | 49 | void * jpg = malloc(config.array_cell_size); 50 | char * buf = conn.mr[0].addr; 51 | 52 | FILE *jpg_file = fopen("./data/cat.jpg", "r"); 53 | fread(jpg, 1, jpg_size, jpg_file); 54 | fclose(jpg_file); 55 | 56 | for (int i = 0; i < cells; i++) { 57 | memcpy(buf, jpg, jpg_size); 58 | buf += config.array_cell_size; 59 | } 60 | } 61 | } 62 | 63 | // Exchange with server 64 | server_exchange_info(&conn, config.server_listen_url); 65 | 66 | // Enable QP, server only need to get to RTR 67 | qp_stm_reset_to_init(&conn); 68 | qp_stm_init_to_rtr(&conn); 69 | 70 | return 0; 71 | } 72 | 73 | int main(int argc, char *argv[]) { 74 | parse_config(argc, argv); 75 | int num_server = 0; 76 | do { 77 | server(); 78 | printf("Finish server %d setup.\n", num_server++); 79 | } while (config.server_multi_conn); 80 | 81 | // Serve here 82 | for (;;) ; 83 | return 0; 84 | } 85 | -------------------------------------------------------------------------------- /host/test/jpeg/config.c: -------------------------------------------------------------------------------- 1 | #include "test.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | struct config config; 8 | 9 | int parse_config(int argc, char *argv[]) { 10 | // fill in config here 11 | memset(&config, 0, sizeof(struct config)); 12 | 13 | config.cq_size = 16; 14 | // for ib servers, use 0 15 | config.use_roce = 0; 16 | config.gid_idx = 0; 17 | 18 | config.client_mr_size = 1024 * 1024 * 64; 19 | // config.server_num_mr = 1024 * 512; 20 | // config.server_mr_size = 4096 * 8; 21 | 22 | config.server_num_mr = 16; 23 | config.server_mr_size = (size_t)1024 * 1024 * 1024; 24 | 25 | // set ib info 26 | config.server.num_devices = 2; 27 | config.server.port = 1; 28 | config.server.device_name = "mlx5_1"; 29 | 30 | config.client.num_devices = 2; 31 | config.client.port = 1; 32 | config.client.device_name = "mlx5_1"; 33 | 34 | // test parameters 35 | config.request_size = 64; 36 | config.server_url = "tcp://wuklab-01.ucsd.edu:2345"; 37 | config.server_listen_url = "tcp://*:2345"; 38 | 39 | config.server_enable_odp = 0; 40 | config.server_multi_conn = 1; 41 | 42 | // application 43 | config.server_rdma_read_url = "tcp://wuklab-01.ucsd.edu:5300"; 44 | config.server_rdma_write_url = "tcp://wuklab-01.ucsd.edu:5301"; 45 | 46 | config.array_cell_size = 1024 * 1024; 47 | config.jpg_size = 20116; 48 | //config.jpg_size = 1024; 49 | 50 | // parse arg 51 | int opt; 52 | while ((opt = getopt(argc, argv, "m:s:p:l:")) != -1) { 53 | switch(opt) { 54 | case 'l': 55 | config.server_listen_url = optarg; 56 | printf("set server_listen_url = %s\n", config.server_listen_url); 57 | break; 58 | case 'm': 59 | config.server_num_mr = atoi(optarg); 60 | printf("set server_num_mr = %d\n", config.server_num_mr); 61 | break; 62 | case 's': 63 | config.server_mr_size = atoi(optarg); 64 | printf("set server_mr_size = %lu\n", config.server_mr_size); 65 | break; 66 | case 'p': 67 | config.program = optarg; 68 | printf("set program = %s\n", config.program); 69 | break; 70 | default: 71 | printf("read config.c for ali opts.\n"); 72 | return -1; 73 | } 74 | } 75 | 76 | 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /host/test/jpeg/rarray.c: -------------------------------------------------------------------------------- 1 | #include "rarray.h" 2 | #include "rmem.h" 3 | #include "test.h" 4 | 5 | int rarray_read(struct remote_mem *mem, void * lbuf, uint64_t index, size_t size, int buffer_index, int thread_id) 6 | { 7 | int cell_size = config.array_cell_size; 8 | size_t realsize = (size == RARRAY_SZ_CELL) ? cell_size : size; 9 | return rread(mem, lbuf, index * cell_size, realsize, buffer_index, thread_id); 10 | } 11 | 12 | int rarray_write(struct remote_mem *mem, void * lbuf, size_t index, size_t size, int buffer_index, int thread_id) 13 | { 14 | int cell_size = config.array_cell_size; 15 | size_t realsize = (size == RARRAY_SZ_CELL) ? cell_size : size; 16 | return rwrite(mem, lbuf, index * cell_size, realsize, buffer_index, thread_id); 17 | } 18 | -------------------------------------------------------------------------------- /host/test/jpeg/rarray.h: -------------------------------------------------------------------------------- 1 | #ifndef _RARRAY_H_ 2 | #define _RARRAY_H_ 3 | 4 | #include "rmem.h" 5 | 6 | // array apis 7 | #define RARRAY_SZ_CELL 0 8 | 9 | int rarray_read(struct remote_mem *mem, void * lbuf, size_t index, size_t size, int buffer_index, int thread_id); 10 | int rarray_write(struct remote_mem *mem, void * lbuf, size_t index, size_t size, int buffer_index, int thread_id); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /host/test/jpeg/rmem.h: -------------------------------------------------------------------------------- 1 | #ifndef _RMEM_H_ 2 | #define _RMEM_H_ 3 | 4 | #include 5 | #include 6 | 7 | // remote_mem api 8 | 9 | #define RMEM_ACCESS_READ (1) 10 | #define RMEM_ACCESS_WRITE (2) 11 | 12 | struct remote_mem { 13 | void * meta; 14 | int access; 15 | }; 16 | 17 | // remote APIs 18 | struct remote_mem * rinit(int access, size_t size, void *args); 19 | int rclose(struct remote_mem * rmem); 20 | 21 | void * rcreatebuf (struct remote_mem * rmem, size_t size, int thread_id); 22 | int rread (struct remote_mem * rmem, void *buf, uint64_t addr, size_t size, int buffer_index, int thread_id); 23 | int rwrite (struct remote_mem * rmem, void *buf, uint64_t addr, size_t size, int buffer_index, int thread_id); 24 | int ralloc (struct remote_mem * rmem, void *buf, uint64_t addr, size_t size, int thread_id); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /host/test/jpeg/test.h: -------------------------------------------------------------------------------- 1 | #ifndef _TEST_H_ 2 | #define _TEST_H_ 3 | 4 | #include 5 | 6 | // For gid 7 | #define RDMA_PROTOCOL_IB (0) 8 | 9 | struct rdma_conn { 10 | struct ibv_context* context; 11 | struct ibv_pd* pd; 12 | struct ibv_cq* cq; 13 | struct ibv_qp* qp; 14 | 15 | int num_mr; 16 | struct ibv_mr* mr; 17 | 18 | int port; 19 | int gid; 20 | struct conn_info* peerinfo; 21 | }; 22 | 23 | struct conn_info { 24 | int port; 25 | uint32_t local_id; 26 | uint16_t qp_number; 27 | 28 | int num_mr; 29 | union ibv_gid gid; 30 | struct ibv_mr mr[0]; 31 | }; 32 | 33 | struct epinfo { 34 | int num_devices; 35 | int port; 36 | char * device_name; 37 | }; 38 | 39 | struct config { 40 | int cq_size; 41 | 42 | // gloabl config 43 | int use_roce; 44 | int gid_idx; 45 | 46 | // Memory region 47 | size_t client_mr_size; 48 | 49 | int server_num_mr; 50 | size_t server_mr_size; 51 | 52 | int share_mr; 53 | 54 | struct epinfo server, client; 55 | 56 | // test 57 | int request_size; 58 | char * server_url; 59 | char * server_listen_url; 60 | 61 | int server_enable_odp; 62 | int server_multi_conn; 63 | 64 | char * program; 65 | 66 | // application test 67 | size_t array_cell_size; 68 | 69 | char *server_rdma_read_url; 70 | char *server_rdma_write_url; 71 | 72 | int jpg_size; 73 | int legomem; 74 | }; 75 | 76 | extern struct config config; 77 | 78 | // network exchange info 79 | int client_exchange_info(struct rdma_conn *conn, char * url); 80 | int server_exchange_info(struct rdma_conn *conn, char * url); 81 | 82 | // test_config 83 | int parse_config(int argc, char *argv[]); 84 | 85 | // common helper for rdma, may move to common.h later 86 | int create_context(struct epinfo *ep, struct rdma_conn *conn); 87 | int create_qp(struct rdma_conn *conn); 88 | int create_mr(struct rdma_conn *conn, size_t size, int access); 89 | // QP state mahine functions 90 | int qp_stm_reset_to_init(struct rdma_conn *conn); 91 | int qp_stm_init_to_rtr(struct rdma_conn *conn); 92 | int qp_stm_rtr_to_rts(struct rdma_conn *conn); 93 | // network communication 94 | int extract_info(struct rdma_conn *conn, void **buf); 95 | 96 | #endif 97 | -------------------------------------------------------------------------------- /host/test/test_context.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Wuklab, UCSD. All rights reserved. 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include "../core.h" 16 | 17 | #define NR_CONTEXT 128 18 | 19 | int test_legomem_context(char *_unused) 20 | { 21 | struct legomem_context **ctx; 22 | struct timespec ts, te; 23 | int i; 24 | 25 | printf("%s(): Running open/close test\n", __func__); 26 | 27 | ctx = malloc(sizeof(*ctx) * NR_CONTEXT); 28 | if (!ctx) 29 | return -ENOMEM; 30 | 31 | clock_gettime(CLOCK_MONOTONIC, &ts); 32 | for (i = 0; i < NR_CONTEXT; i++) { 33 | ctx[i] = legomem_open_context(); 34 | if (!ctx[i]) { 35 | dprintf_ERROR("Fail to open contxt i=%d", i); 36 | return -EPERM; 37 | } 38 | } 39 | clock_gettime(CLOCK_MONOTONIC, &te); 40 | 41 | printf("open_context avg %f ns (#%d tests)\n", 42 | (((double)te.tv_sec*1.0e9 + te.tv_nsec) - 43 | ((double)ts.tv_sec*1.0e9 + ts.tv_nsec)) / NR_CONTEXT, NR_CONTEXT); 44 | 45 | clock_gettime(CLOCK_MONOTONIC, &ts); 46 | for (i = 0; i < NR_CONTEXT; i++) { 47 | legomem_close_context(ctx[i]); 48 | } 49 | clock_gettime(CLOCK_MONOTONIC, &te); 50 | 51 | printf("close_context avg %f ns (#%d tests)\n", 52 | (((double)te.tv_sec*1.0e9 + te.tv_nsec) - 53 | ((double)ts.tv_sec*1.0e9 + ts.tv_nsec)) / NR_CONTEXT, NR_CONTEXT); 54 | 55 | free(ctx); 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /host/test/test_legomem_pte.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Wuklab, UCSD. All rights reserved. 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | #include "../core.h" 17 | 18 | int test_legomem_pte(char *board_ip_port_str) 19 | { 20 | struct board_info *remote_board; 21 | struct session_net *remote_mgmt_session; 22 | unsigned int ip, port; 23 | unsigned int ip1, ip2, ip3, ip4; 24 | 25 | printf("%s(): test board %s\n", __func__, board_ip_port_str); 26 | 27 | sscanf(board_ip_port_str, "%u.%u.%u.%u:%d", &ip1, &ip2, &ip3, &ip4, &port); 28 | ip = ip1 << 24 | ip2 << 16 | ip3 << 8 | ip4; 29 | 30 | remote_board = find_board(ip, port); 31 | if (!remote_board) { 32 | dprintf_ERROR("Couldn't find the board_info for %s\n", 33 | board_ip_port_str); 34 | dump_boards(); 35 | return -1; 36 | } 37 | printf("%s(): Using board %s\n", __func__, remote_board->name); 38 | 39 | /* Get our local endpoint for remote board's mgmt session */ 40 | remote_mgmt_session = get_board_mgmt_session(remote_board); 41 | BUG_ON(!remote_mgmt_session); 42 | 43 | struct legomem_common_headers resp; 44 | struct legomem_test_pte req; 45 | struct op_test_pte *op; 46 | struct lego_header *lego_header; 47 | 48 | lego_header = to_lego_header(&req); 49 | lego_header->opcode = OP_REQ_TEST_PTE; 50 | 51 | op = &req.op; 52 | 53 | op->op = OP_REQ_TEST_PTE; 54 | op->pid = 1; 55 | op->start = 1<<22; 56 | op->end = 2<<22; 57 | 58 | net_send_and_receive(remote_mgmt_session, &req, sizeof(req), 59 | &resp, sizeof(resp)); 60 | 61 | return 0; 62 | } 63 | 64 | -------------------------------------------------------------------------------- /host/test/test_memcpy.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Wuklab, UCSD. All rights reserved. 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | static int test_size[] = { 4, 16, 64, 256, 512, 1024, 2048, 4096 }; 14 | 15 | int main(void) 16 | { 17 | int i, j, nr_run; 18 | char *src, *dst; 19 | struct timespec s, e; 20 | double lat; 21 | 22 | src = malloc(10000); 23 | dst = malloc(10000); 24 | memset(src, 0, 10000); 25 | memset(dst, 0, 10000); 26 | 27 | nr_run = 100000000; 28 | 29 | for (i = 0; i < ARRAY_SIZE(test_size); i++) { 30 | 31 | clock_gettime(CLOCK_MONOTONIC, &s); 32 | for (j = 0; j < nr_run; j++) { 33 | memcpy(dst, src, test_size[i]); 34 | } 35 | clock_gettime(CLOCK_MONOTONIC, &e); 36 | 37 | 38 | lat = (e.tv_sec * NSEC_PER_SEC + e.tv_nsec) - (s.tv_sec * NSEC_PER_SEC + s.tv_nsec); 39 | printf("test_size %d nr_run %d avg %lf ns\n", 40 | test_size[i], nr_run, lat / nr_run); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /host/test/test_migration.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Wuklab, UCSD. All rights reserved. 3 | * 4 | * Testing 5 | * - legomem_migration 6 | * 7 | * Scripts 8 | * - scripts/test_migration.sh 9 | * 10 | * You need at least a monitor, a host running test case, 11 | * and either a real board or board emulator instance. 12 | * 13 | * legomem_migration is not an simple API, its perf varies depends on scenarios. 14 | * So, be careful. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include "../core.h" 28 | 29 | #define NR_TESTS 1 30 | 31 | int test_legomem_migration(char *_unused) 32 | { 33 | struct legomem_context *ctx; 34 | struct timespec s, e; 35 | struct board_info *dst_bi; 36 | int i; 37 | unsigned long __remote addr[NR_TESTS]; 38 | unsigned int ip, port; 39 | unsigned int ip1, ip2, ip3, ip4; 40 | double lat_ns; 41 | unsigned int alloc_size; 42 | 43 | char board_ip_port_str[] = "192.168.1.22:1234"; 44 | sscanf(board_ip_port_str, "%u.%u.%u.%u:%d", &ip1, &ip2, &ip3, &ip4, &port); 45 | ip = ip1 << 24 | ip2 << 16 | ip3 << 8 | ip4; 46 | 47 | dst_bi = find_board(ip, port); 48 | if (!dst_bi) { 49 | dprintf_ERROR("Couldn't find board: %s\n", board_ip_port_str); 50 | return 0; 51 | } 52 | 53 | dprintf_INFO("Running migration test. Migration dest board: %s\n", dst_bi->name); 54 | 55 | ctx = legomem_open_context(); 56 | 57 | alloc_size = VREGION_SIZE; 58 | 59 | i = 0; 60 | addr[i] = legomem_alloc(ctx, alloc_size, LEGOMEM_VM_FLAGS_POPULATE); 61 | if (!addr[i]) 62 | dprintf_ERROR("alloc failed %d\n", 0); 63 | 64 | dprintf_INFO(" alloc i=%3d addr=%#18lx vregion_idx=%u\n", 65 | i, addr[i], va_to_vregion_index(addr[i])); 66 | 67 | dprintf_INFO(" migrate i=%3d addr=%#18lx vregion_idx=%u\n", 68 | i, addr[i], va_to_vregion_index(addr[i])); 69 | 70 | legomem_migration(ctx, dst_bi, addr[i], 128); 71 | exit(0); 72 | 73 | clock_gettime(CLOCK_MONOTONIC, &e); 74 | 75 | lat_ns = (e.tv_sec * NSEC_PER_SEC + e.tv_nsec) - 76 | (s.tv_sec * NSEC_PER_SEC + s.tv_nsec); 77 | lat_ns /= (NR_TESTS); 78 | 79 | dprintf_INFO("#nr_migration: %d, #avg_latency_ns: %lf\n", 80 | NR_TESTS, lat_ns); 81 | 82 | legomem_close_context(ctx); 83 | return 0; 84 | } 85 | -------------------------------------------------------------------------------- /host/test/test_session.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Wuklab, UCSD. All rights reserved. 3 | * 4 | * Testing 5 | * - legomem_open_session 6 | * - legomem_close_session 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include "../core.h" 20 | 21 | #define NR_SESSION (128) 22 | 23 | /* 24 | * If @board_ip_port_str is NULL, we wil 25 | */ 26 | int test_legomem_session(char *board_ip_port_str) 27 | { 28 | struct legomem_context *ctx; 29 | struct board_info *remote_board; 30 | struct session_net **ses_net; 31 | int i; 32 | struct timespec ts, te; 33 | 34 | if (board_ip_port_str) { 35 | unsigned int ip, port; 36 | unsigned int ip1, ip2, ip3, ip4; 37 | 38 | sscanf(board_ip_port_str, "%u.%u.%u.%u:%d", &ip1, &ip2, &ip3, &ip4, &port); 39 | ip = ip1 << 24 | ip2 << 16 | ip3 << 8 | ip4; 40 | 41 | remote_board = find_board(ip, port); 42 | if (!remote_board) { 43 | dprintf_ERROR("Couldn't find the board_info for %s\n", 44 | board_ip_port_str); 45 | dump_boards(); 46 | return -1; 47 | } 48 | } else { 49 | remote_board = monitor_bi; 50 | } 51 | 52 | dprintf_INFO("Running session test. Remote Party: %s\n", remote_board->name); 53 | 54 | /* 55 | * It's okay to have a NULL ctx 56 | * just for testing purpose. 57 | */ 58 | ctx = NULL; 59 | 60 | ses_net = malloc(NR_SESSION * sizeof(*ses_net)); 61 | if (!ses_net) 62 | return -1; 63 | memset(ses_net, 0, NR_SESSION * sizeof(*ses_net)); 64 | 65 | clock_gettime(CLOCK_MONOTONIC, &ts); 66 | for (i = 0; i < NR_SESSION; i++) { 67 | ses_net[i] = legomem_open_session(ctx, remote_board); 68 | if (!ses_net[i]) { 69 | dprintf_ERROR("Fail to created the %dth session\n", i); 70 | exit(1); 71 | } 72 | } 73 | clock_gettime(CLOCK_MONOTONIC, &te); 74 | 75 | dprintf_INFO("open_session avg %f ns (#%d tests)\n", 76 | (((double)te.tv_sec*1.0e9 + te.tv_nsec) - 77 | ((double)ts.tv_sec*1.0e9 + ts.tv_nsec)) / NR_SESSION, NR_SESSION); 78 | 79 | 80 | clock_gettime(CLOCK_MONOTONIC, &ts); 81 | for (i = 0; i < NR_SESSION; i++) { 82 | legomem_close_session(ctx, ses_net[i]); 83 | } 84 | clock_gettime(CLOCK_MONOTONIC, &te); 85 | 86 | dprintf_INFO("close_session avg %f ns (#%d tests)\n", 87 | (((double)te.tv_sec*1.0e9 + te.tv_nsec) - 88 | ((double)ts.tv_sec*1.0e9 + ts.tv_nsec)) / NR_SESSION, NR_SESSION); 89 | 90 | legomem_close_context(ctx); 91 | return 0; 92 | } 93 | -------------------------------------------------------------------------------- /host/test/test_soc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include "../core.h" 14 | 15 | #define DEFAULT_TEST_SESSION 4 16 | 17 | int test_legomem_soc(char *board_ip_port_str) 18 | { 19 | struct board_info *remote_board; 20 | struct session_net *ses_net; 21 | struct session_net *remote_mgmt_session; 22 | unsigned int ip, port; 23 | unsigned int ip1, ip2, ip3, ip4; 24 | 25 | printf("%s(): test soc %s\n", __func__, board_ip_port_str); 26 | 27 | sscanf(board_ip_port_str, "%u.%u.%u.%u:%d", &ip1, &ip2, &ip3, &ip4, &port); 28 | ip = ip1 << 24 | ip2 << 16 | ip3 << 8 | ip4; 29 | 30 | /* 31 | * Step II 32 | * Find the testing board 33 | */ 34 | remote_board = find_board(ip, port); 35 | if (!remote_board) { 36 | dprintf_ERROR("Couldn't find the board_info for %s\n", 37 | board_ip_port_str); 38 | dump_boards(); 39 | return -1; 40 | } 41 | printf("%s(): Using board %s\n", __func__, remote_board->name); 42 | 43 | /* Get our local endpoint for remote board's mgmt session */ 44 | remote_mgmt_session = get_board_mgmt_session(remote_board); 45 | BUG_ON(!remote_mgmt_session); 46 | 47 | ses_net = net_open_session(&remote_board->local_ei, 48 | &remote_board->remote_ei); 49 | 50 | ses_net->board_ip = remote_board->board_ip; 51 | ses_net->udp_port = remote_board->udp_port; 52 | ses_net->board_info = remote_board; 53 | ses_net->tid = syscall(SYS_gettid); 54 | 55 | set_local_session_id(ses_net, DEFAULT_TEST_SESSION); 56 | set_remote_session_id(ses_net, DEFAULT_TEST_SESSION); 57 | 58 | //add_net_session(ses_net); 59 | board_add_session(remote_board, ses_net); 60 | 61 | struct msg { 62 | struct legomem_common_headers header; 63 | long cnt[50]; 64 | long i; 65 | } __packed; 66 | struct msg *buf = (struct msg *)malloc(sizeof(struct msg) + 100); 67 | while (1) { 68 | net_receive(ses_net, buf, sizeof(struct msg) + 100); 69 | printf("%lu\n", buf->i); 70 | } 71 | 72 | return 0; 73 | } 74 | -------------------------------------------------------------------------------- /host/watchdog.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020. Wuklab. All rights reserved. 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include "core.h" 22 | 23 | __used static void *watchdog_func(void *_unused) 24 | { 25 | while (1) { 26 | sleep(10); 27 | dump_stats(); 28 | } 29 | return NULL; 30 | } 31 | 32 | #ifdef CONFIG_DEBUG_WATCHDOG 33 | int create_watchdog_thread(void) 34 | { 35 | pthread_t t; 36 | int ret; 37 | 38 | ret = pthread_create(&t, NULL, watchdog_func, NULL); 39 | if (ret) { 40 | dprintf_ERROR("Fail to create watchdog thread%d\n", errno); 41 | exit(-1); 42 | } 43 | return 0; 44 | } 45 | #else 46 | int create_watchdog_thread(void) 47 | { 48 | return 0; 49 | } 50 | #endif 51 | -------------------------------------------------------------------------------- /include/fpga/axis_internal.h: -------------------------------------------------------------------------------- 1 | #ifndef _LEGO_MEM_AXIS_INTERNAL_ 2 | #define _LEGO_MEM_AXIS_INTERNAL_ 3 | 4 | #include 5 | #include 6 | 7 | enum timer_rst_type { 8 | timer_rst_type_reset = 1, 9 | timer_rst_type_stop 10 | }; 11 | 12 | struct query_req { 13 | ap_uint<64> gbn_header; 14 | ap_uint<32> src_ip; 15 | ap_uint<32> dest_ip; 16 | }; 17 | 18 | struct route_info { 19 | ap_uint<32> dest_ip; 20 | ap_uint<16> length; 21 | }; 22 | 23 | struct retrans_req { 24 | ap_uint slotid; 25 | ap_uint seq_start; 26 | ap_uint seq_end; 27 | }; 28 | 29 | struct timer_req { 30 | ap_uint slotid; 31 | ap_uint<16 - SLOT_ID_WIDTH> rst_type; 32 | }; 33 | 34 | struct conn_mgmt_req { 35 | ap_uint slotid; 36 | ap_uint<16 - SLOT_ID_WIDTH> set_type; 37 | }; 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /include/fpga/axis_net.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020,Wuklab, UCSD. 3 | */ 4 | 5 | /* 6 | * This file descirbes network interfaces used by FPGA IPs. 7 | * This file is supposed to be used by FPGA code only. 8 | */ 9 | 10 | #ifndef _LEGO_MEM_AXIS_NET_ 11 | #define _LEGO_MEM_AXIS_NET_ 12 | 13 | #include 14 | #include 15 | 16 | #define NR_BYTES_AXIS_64 (8) 17 | #define NR_BYTES_AXIS_256 (32) 18 | #define NR_BYTES_AXIS_512 (64) 19 | 20 | struct net_axis_64 { 21 | ap_uint<64> data; 22 | ap_uint<1> last; 23 | ap_uint keep; 24 | ap_uint<1> user; 25 | }; 26 | 27 | /* 28 | * For 256b version, we will have this header format: 29 | * | Eth Header | App Header | 30 | * 0 112 31 | * There will not be other headers. 32 | */ 33 | struct net_axis_256 { 34 | ap_uint<256> data; 35 | ap_uint<1> last; 36 | ap_uint keep; 37 | ap_uint<1> user; 38 | }; 39 | 40 | struct net_axis_512 { 41 | ap_uint<512> data; 42 | ap_uint<1> last; 43 | ap_uint keep; 44 | ap_uint<1> user; 45 | }; 46 | 47 | struct udp_info { 48 | ap_uint<32> src_ip; 49 | ap_uint<32> dest_ip; 50 | ap_uint<16> src_port; 51 | ap_uint<16> dest_port; 52 | ap_uint<16> length; 53 | }; 54 | 55 | #endif /* _LEGO_MEM_AXIS_NET_ */ 56 | -------------------------------------------------------------------------------- /include/fpga/fpga_memory_map.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020,Wuklab, UCSD. 3 | */ 4 | 5 | #ifndef _FPGA_MEMORY_MAP_H_ 6 | #define _FPGA_MEMORY_MAP_H_ 7 | 8 | /* 9 | * Current legomem memory map: 10 | * 0-512M -> network cache 11 | * 512M - 1G -> pgtable 12 | * 1G - 2G -> data 13 | */ 14 | #define FPGA_MEMORY_MAP_MAPPING_BASE (0x500000000UL) 15 | #define _FPGA_MEMORY_MAP_NETCACHE_START ( 0x00000000UL) 16 | #define _FPGA_MEMORY_MAP_NETCACHE_END ( 0x20000000UL) 17 | #define _FPGA_MEMORY_MAP_PGTABLE_START ( 0x20000000UL) 18 | #define _FPGA_MEMORY_MAP_PGTABLE_END ( 0x40000000UL) 19 | #define _FPGA_MEMORY_MAP_DATA_START ( 0x40000000UL) 20 | #define _FPGA_MEMORY_MAP_DATA_END ( 0x80000000UL) 21 | 22 | #define FPGA_MEMORY_MAP_PGTABLE_START (FPGA_MEMORY_MAP_MAPPING_BASE + \ 23 | _FPGA_MEMORY_MAP_PGTABLE_START) 24 | #define FPGA_MEMORY_MAP_PGTABLE_END (FPGA_MEMORY_MAP_MAPPING_BASE + \ 25 | _FPGA_MEMORY_MAP_PGTABLE_END) 26 | 27 | #define FPGA_MEMORY_MAP_PGTABLE_SIZE (FPGA_MEMORY_MAP_PGTABLE_END - \ 28 | FPGA_MEMORY_MAP_PGTABLE_START) 29 | 30 | #define FPGA_MEMORY_MAP_DATA_START (FPGA_MEMORY_MAP_MAPPING_BASE + \ 31 | _FPGA_MEMORY_MAP_DATA_START) 32 | #define FPGA_MEMORY_MAP_DATA_END (FPGA_MEMORY_MAP_MAPPING_BASE + \ 33 | _FPGA_MEMORY_MAP_DATA_END) 34 | 35 | #endif /* _FPGA_MEMORY_MAP_H_ */ 36 | -------------------------------------------------------------------------------- /include/fpga/kernel.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020,Wuklab, UCSD. 3 | */ 4 | 5 | #ifndef _LEGO_MEM_KERNEL_H_ 6 | #define _LEGO_MEM_KERNEL_H_ 7 | 8 | #ifdef __SYNTHESIS__ 9 | # define PR(fmt, ...) do { } while (0) 10 | #else 11 | # ifdef ENABLE_PR 12 | # define PR(fmt, ...) printf("[%s:%d] " fmt, __func__, __LINE__, ##__VA_ARGS__) 13 | # else 14 | # define PR(fmt, ...) do { } while (0) 15 | # endif 16 | #endif 17 | 18 | // highlight display 19 | #define dph(fmt, ...) \ 20 | do { \ 21 | printf("\033[0;32m"); \ 22 | printf(fmt, ##__VA_ARGS__); \ 23 | printf("\033[0m"); \ 24 | } while (0) 25 | 26 | #define HLS_BUG() \ 27 | do { \ 28 | } while (0) 29 | 30 | #endif /* _LEGO_MEM_KERNEL_H_ */ 31 | -------------------------------------------------------------------------------- /include/fpga/lego_mem_ctrl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020,Wuklab, UCSD. 3 | */ 4 | 5 | #ifndef _LEGO_MEM_CTRL_ 6 | #define _LEGO_MEM_CTRL_ 7 | 8 | #include 9 | #include 10 | 11 | /* 12 | * CMDs for lego_mem_ctrl->cmd 13 | */ 14 | enum { 15 | CMD_LEGOMEM_CTRL_CREATE_PROC = 0, 16 | CMD_LEGOMEM_CTRL_ALLOC, 17 | CMD_LEGOMEM_CTRL_FREE, 18 | 19 | 20 | CMD_LEGOMEM_KVS_ALLOC = 8, 21 | CMD_LEGOMEM_KVS_ALLOC_BOTH = 9, 22 | }; 23 | 24 | struct lego_mem_ctrl { 25 | uint32_t param32; 26 | uint8_t param8; 27 | uint8_t beats : 4; 28 | uint8_t cmd : 4; 29 | uint8_t addr; 30 | uint8_t epid; 31 | } __packed; 32 | 33 | /* 34 | * On-chip ADDR distribution 35 | * Each on-chip sender has its own ADDR. 36 | */ 37 | #define LEGOMEM_CTRL_ADDR_FREEPAGE_0 (0) 38 | #define LEGOMEM_CTRL_ADDR_FREEPAGE_1 (1) 39 | #define LEGOMEM_CTRL_ADDR_FREEPAGE_2 (2) 40 | 41 | #endif /* _LEGO_MEM_CTRL_ */ 42 | -------------------------------------------------------------------------------- /include/fpga/pgtable.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020,Wuklab, UCSD. 3 | */ 4 | 5 | #ifndef _FPGA_PGTABLE_H_ 6 | #define _FPGA_PGTABLE_H_ 7 | 8 | #include 9 | 10 | #define FPGA_TAG_OFFSET (20) 11 | #define FPGA_BUCKET_OFFSET (8) 12 | 13 | /* 1TB */ 14 | #define PHYSICAL_MEM_SIZE_BITS (40) 15 | #define PHYSICAL_MEM_SIZE (1UL< 9 | 10 | /* 11 | * The address of a block returned by malloc or realloc in GNU 12 | * systems is always a multiple of eight (or sixteen on 64-bit systems). 13 | * 14 | * Thus we may encode error number in low bits. 15 | */ 16 | #define MAX_ERRNO 4095 17 | 18 | #define IS_ERR_VALUE(x) unlikely((x) >= (unsigned long)-MAX_ERRNO) 19 | 20 | static inline void *ERR_PTR(long error) 21 | { 22 | return (void *)error; 23 | } 24 | 25 | static inline long PTR_ERR(const void *ptr) 26 | { 27 | return (long)ptr; 28 | } 29 | 30 | static inline long IS_ERR(const void *ptr) 31 | { 32 | return IS_ERR_VALUE((unsigned long)ptr); 33 | } 34 | 35 | static inline long IS_ERR_OR_NULL(const void *ptr) 36 | { 37 | return !ptr || IS_ERR_VALUE((unsigned long)ptr); 38 | } 39 | 40 | static inline void *ERR_CAST(const void *ptr) 41 | { 42 | /* cast away the const */ 43 | return (void *)ptr; 44 | } 45 | 46 | static inline int PTR_RET(const void *ptr) 47 | { 48 | if (IS_ERR(ptr)) 49 | return PTR_ERR(ptr); 50 | else 51 | return 0; 52 | } 53 | 54 | #endif /* _LEGOMEM_UAPI_ERR_H_ */ 55 | -------------------------------------------------------------------------------- /include/uapi/lego_mem.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020,Wuklab, UCSD. 3 | */ 4 | 5 | #ifndef _UAPI_LEGO_MEM_H_ 6 | #define _UAPI_LEGO_MEM_H_ 7 | 8 | #include 9 | #include 10 | 11 | #define LEGOMEM_CONT_NONE (0) 12 | #define LEGOMEM_CONT_NET (0) 13 | #define LEGOMEM_CONT_MEM (1) 14 | #define LEGOMEM_CONT_SOC (2) 15 | 16 | struct lego_mem_access_header { 17 | struct lego_header header; 18 | uint32_t length; 19 | uint64_t va; 20 | } __packed; 21 | 22 | #define LEGOMEM_ACCESS_HEADER_SIZE (sizeof(struct lego_mem_access_header)) 23 | 24 | // Utils 25 | #define MAKE_CONT(c1,c2,c3,c4) (((c1) & 0xF) | (((c2) & 0xF) << 4) | (((c3) & 0xF) << 8) | (((c4) & 0xF) << 12)) 26 | 27 | #if 0 28 | // Lego mem request type definations 29 | #define LEGOMEM_REQ_INVALID (0x00) 30 | #define LEGOMEM_REQ_READ (0x01) 31 | #define LEGOMEM_REQ_READ_RESP (0x02) 32 | #define LEGOMEM_REQ_WRITE (0x03) 33 | #define LEGOMEM_REQ_WRITE_RESP (0x04) 34 | #define LEGOMEM_REQ_ALLOC (0x05) 35 | #define LEGOMEM_REQ_ALLOC_RESP (0x06) 36 | #define LEGOMEM_REQ_FREE (0x07) 37 | #define LEGOMEM_REQ_FREE_RESP (0x08) 38 | // internal mgnt API, designed to be sent from SoC 39 | #define LEGOMEM_REQ_CACHE_SHOOTDOWN (0xF0) 40 | 41 | #define LEGOMEM_STATUS_OKAY (0x00) 42 | #define LEGOMEM_STATUS_ERR_INVALID (0x01) 43 | #define LEGOMEM_STATUS_ERR_WRITE_PERM (0x02) 44 | #define LEGOMEM_STATUS_ERR_READ_PERM (0x03) 45 | #endif 46 | 47 | #endif /* _UAPI_LEGO_MEM_H_*/ 48 | -------------------------------------------------------------------------------- /include/uapi/page.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020. Wuklab. All rights reserved. 3 | */ 4 | 5 | /* 6 | * This file describes the page size and its friends. 7 | * Please only put macros and very generic stuff here. 8 | * This file maybe included by various parties. 9 | */ 10 | 11 | #ifndef _LEGOFPGA_UAPI_H_ 12 | #define _LEGOFPGA_UAPI_H_ 13 | 14 | #include 15 | 16 | /* 17 | * Parameter: virtual address space width in number of bits 18 | */ 19 | #define VIRTUAL_ADDR_SHIFT (50) 20 | 21 | /* 22 | * Current smallest page size is 4M 23 | */ 24 | #define PAGE_SHIFT (22) 25 | #define PAGE_SIZE (1UL << PAGE_SHIFT) 26 | #define PAGE_MASK (~(PAGE_SIZE-1)) 27 | 28 | #define PFN_ALIGN(x) (((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK) 29 | #define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT) 30 | #define PFN_DOWN(x) ((x) >> PAGE_SHIFT) 31 | #define PFN_PHYS(x) ((unsigned long)(x) << PAGE_SHIFT) 32 | #define PHYS_PFN(x) ((unsigned long)((x) >> PAGE_SHIFT)) 33 | 34 | /* to align the pointer to the (next) page boundary */ 35 | #define PAGE_ALIGN(addr) ALIGN(addr, PAGE_SIZE) 36 | 37 | /* test whether an address is aligned to PAGE_SIZE */ 38 | #define PAGE_ALIGNED(addr) IS_ALIGNED((unsigned long)(addr), PAGE_SIZE) 39 | 40 | #define NR_VIRTUAL_PAGES (unsigned long)((1UL) << (VIRTUAL_ADDR_SHIFT - PAGE_SHIFT)) 41 | 42 | #endif /* _LEGOFPGA_UAPI_H_ */ 43 | -------------------------------------------------------------------------------- /include/uapi/profile_point.h: -------------------------------------------------------------------------------- 1 | #ifndef _LEGOMEM_UAPI_PROFILE_POINT_H_ 2 | #define _LEGOMEM_UAPI_PROFILE_POINT_H_ 3 | 4 | #include 5 | #include 6 | 7 | struct profile_point { 8 | bool enabled; 9 | char pp_name[64]; 10 | atomic_long nr; 11 | atomic_long time_cycles; 12 | } __aligned(64); 13 | 14 | #define __profile_point __section(profile_point) 15 | 16 | static inline unsigned long rdtsc(void) 17 | { 18 | unsigned long var; 19 | unsigned int hi, lo; 20 | 21 | asm volatile ("rdtsc" : "=a" (lo), "=d" (hi)); 22 | 23 | var = ((unsigned long)hi << 32) | lo; 24 | return var; 25 | } 26 | 27 | #ifdef CONFIG_PROFILING_POINTS 28 | 29 | #define _PP_TIME(name) __profilepoint_start_ns_##name 30 | #define _PP_NAME(name) __profilepoint_##name 31 | 32 | /* 33 | * Define a profile point 34 | * It is ON by default. 35 | */ 36 | #define DEFINE_PROFILE_POINT(name) \ 37 | struct profile_point _PP_NAME(name) __profile_point = { \ 38 | .enabled = true, \ 39 | .pp_name = __stringify(name), \ 40 | }; 41 | 42 | /* 43 | * This is just a solution if per-cpu is not used. 44 | * Stack is per-thread, thus SMP safe. 45 | */ 46 | #define PROFILE_POINT_TIME_STACK(name) \ 47 | unsigned long _PP_TIME(name) __maybe_unused; 48 | 49 | #define PROFILE_START(name) \ 50 | do { \ 51 | _PP_TIME(name) = rdtsc(); \ 52 | } while (0) 53 | 54 | #define PROFILE_LEAVE(name) \ 55 | do { \ 56 | unsigned long __PP_end_time; \ 57 | unsigned long __PP_diff_time; \ 58 | __PP_end_time = rdtsc(); \ 59 | __PP_diff_time = __PP_end_time - _PP_TIME(name); \ 60 | atomic_fetch_add(&(_PP_NAME(name).nr), 1); \ 61 | atomic_fetch_add(&(_PP_NAME(name).time_cycles), __PP_diff_time); \ 62 | } while (0) 63 | 64 | void print_profile_point(struct profile_point *pp); 65 | void print_profile_points(void); 66 | 67 | #else 68 | 69 | #define DEFINE_PROFILE_POINT(name) 70 | #define PROFILE_POINT_TIME_STACK(name) 71 | #define PROFILE_START(name) do { } while (0) 72 | #define PROFILE_LEAVE(name) do { } while (0) 73 | 74 | static inline void print_profile_point(struct profile_point *pp) { } 75 | static inline void print_profile_points(void) { } 76 | #endif /* CONFIG_PROFILING_POINTS */ 77 | 78 | #endif /* _LEGOMEM_UAPI_PROFILE_POINT_H_ */ 79 | -------------------------------------------------------------------------------- /include/uapi/stat.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Wuklab, UCSD. All rights reserved. 3 | */ 4 | #ifndef _UAPI_STAT_H_ 5 | #define _UAPI_STAT_H_ 6 | 7 | #include 8 | 9 | /* 10 | * Each counter is 8B long. 11 | */ 12 | enum STAT_TYPES { 13 | __START_COMMON_STATS, 14 | 15 | /* 16 | * Core legomem group 17 | */ 18 | STAT_LEGOMEM_NR_READ, 19 | STAT_LEGOMEM_NR_WRITE, 20 | STAT_LEGOMEM_NR_ALLOC, 21 | STAT_LEGOMEM_NR_FREE, 22 | STAT_LEGOMEM_NR_OPEN_SESSION_TX, 23 | STAT_LEGOMEM_NR_OPEN_SESSION_RX, 24 | STAT_LEGOMEM_NR_CLOSE_SESSION_TX, 25 | STAT_LEGOMEM_NR_CLOSE_SESSION_RX, 26 | STAT_LEGOMEM_NR_MIGRATION_TX, 27 | STAT_LEGOMEM_NR_MIGRATION_RX, 28 | 29 | __START_HOST_STATS, 30 | 31 | /* 32 | * Host-side specific 33 | */ 34 | 35 | STAT_NR_MIGRATED_VREGION, 36 | 37 | /* Reliable go-back-N layer */ 38 | STAT_NET_GBN_NR_RX, 39 | STAT_NET_GBN_NR_RX_ERROR_NO_SESSION, 40 | STAT_NET_GBN_NR_RX_ERROR_UNKNOWN_TYPE, 41 | STAT_NET_GBN_NR_RX_ACK, 42 | STAT_NET_GBN_NR_RX_NACK, 43 | STAT_NET_GBN_NR_RX_DATA, 44 | STAT_NET_GBN_NR_TX_ACK, 45 | STAT_NET_GBN_NR_TX_NACK, 46 | STAT_NET_GBN_NR_TX_DATA, 47 | 48 | /* raw verbs layer */ 49 | STAT_NET_RAW_VERBS_NR_TX, 50 | STAT_NET_RAW_VERBS_NR_RX, 51 | STAT_NET_RAW_VERBS_NR_RX_ZEROCOPY, 52 | STAT_NET_RAW_VERBS_NR_POST_RECVS, 53 | 54 | NR_STAT_TYPES, 55 | }; 56 | 57 | /* This is.. stupid? */ 58 | static inline char *stat_type_string(enum STAT_TYPES item) 59 | { 60 | #define S(_OP) \ 61 | case _OP: return __stringify(_OP) 62 | 63 | switch (item) { 64 | S(__START_COMMON_STATS); 65 | S(STAT_LEGOMEM_NR_READ); 66 | S(STAT_LEGOMEM_NR_WRITE); 67 | S(STAT_LEGOMEM_NR_ALLOC); 68 | S(STAT_LEGOMEM_NR_FREE); 69 | S(STAT_LEGOMEM_NR_OPEN_SESSION_TX); 70 | S(STAT_LEGOMEM_NR_OPEN_SESSION_RX); 71 | S(STAT_LEGOMEM_NR_CLOSE_SESSION_TX); 72 | S(STAT_LEGOMEM_NR_CLOSE_SESSION_RX); 73 | S(STAT_LEGOMEM_NR_MIGRATION_TX); 74 | S(STAT_LEGOMEM_NR_MIGRATION_RX); 75 | 76 | S(__START_HOST_STATS); 77 | S(STAT_NR_MIGRATED_VREGION); 78 | S(STAT_NET_GBN_NR_RX); 79 | S(STAT_NET_GBN_NR_RX_ERROR_NO_SESSION); 80 | S(STAT_NET_GBN_NR_RX_ERROR_UNKNOWN_TYPE); 81 | S(STAT_NET_GBN_NR_RX_ACK); 82 | S(STAT_NET_GBN_NR_RX_NACK); 83 | S(STAT_NET_GBN_NR_RX_DATA); 84 | S(STAT_NET_GBN_NR_TX_ACK); 85 | S(STAT_NET_GBN_NR_TX_NACK); 86 | S(STAT_NET_GBN_NR_TX_DATA); 87 | 88 | S(STAT_NET_RAW_VERBS_NR_TX); 89 | S(STAT_NET_RAW_VERBS_NR_RX); 90 | S(STAT_NET_RAW_VERBS_NR_RX_ZEROCOPY); 91 | S(STAT_NET_RAW_VERBS_NR_POST_RECVS); 92 | 93 | default: 94 | return "invalid"; 95 | } 96 | return "invalid"; 97 | } 98 | 99 | #endif /* _UAPI_STAT_H_ */ 100 | -------------------------------------------------------------------------------- /include/uapi/stringify.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020,Wuklab, UCSD. 3 | */ 4 | 5 | #ifndef _UAPI_STRINGIFY_H_ 6 | #define _UAPI_STRINGIFY_H_ 7 | 8 | /* 9 | * Indirect stringification. 10 | * Doing two levels allows the parameter to be a macro itself. 11 | */ 12 | 13 | #define __stringify_1(x...) #x 14 | #define __stringify(x...) __stringify_1(x) 15 | 16 | #endif /* _UAPI_STRINGIFY_H_ */ 17 | -------------------------------------------------------------------------------- /include/uapi/tlb.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020. Wuklab. All rights reserved. 3 | */ 4 | 5 | #ifndef _LEGOFPGA_UAPI_TLB_H_ 6 | #define _LEGOFPGA_UAPI_TLB_H_ 7 | 8 | #include 9 | 10 | #define LEGOMEM_NR_TLB_ENTRIES (128) 11 | 12 | /* 13 | * Default is FIFO. 14 | */ 15 | enum tlb_eviction_policy { 16 | LEGOMEM_TLB_EVICTION_RANDOM, 17 | LEGOMEM_TLB_EVICTION_FIFO, 18 | LEGOMEM_TLB_EVICTION_LRU, 19 | }; 20 | 21 | #endif /* _LEGOFPGA_UAPI_TLB_H_ */ 22 | -------------------------------------------------------------------------------- /include/uapi/vregion.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Wuklab, UCSD. All rights reserved. 3 | */ 4 | #ifndef _INCLUDE_UAPI_VREGION_ 5 | #define _INCLUDE_UAPI_VREGION_ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Parameter: vRegion size in number of bits 12 | */ 13 | #define VREGION_SIZE_SHIFT (30) 14 | #define VREGION_SIZE (1 << VREGION_SIZE_SHIFT) 15 | #define VREGION_MASK (~(VREGION_SIZE - 1)) 16 | 17 | #define NR_VREGIONS_SHIFT (VIRTUAL_ADDR_SHIFT-VREGION_SIZE_SHIFT) 18 | #define NR_VREGIONS ((unsigned long)1 << (unsigned long)NR_VREGIONS_SHIFT) 19 | 20 | #endif /* _INCLUDE_UAPI_VREGION_ */ 21 | -------------------------------------------------------------------------------- /tests/scripts/activate: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | source /tools/Xilinx/petalinux/2019.1/settings.sh 4 | 5 | SCRIPT=`realpath ${BASH_SOURCE[0]}` 6 | SCRIPTPATH=`dirname $SCRIPT` 7 | 8 | export PATH=$SCRIPTPATH:$PATH 9 | export CLIO_PETAPATH=/data/petalinux/freq-250 10 | 11 | -------------------------------------------------------------------------------- /tests/scripts/clio-reconfig: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SCRIPT=`realpath ${BASH_SOURCE[0]}` 4 | SCRIPTPATH=`dirname $SCRIPT` 5 | ARTIFACTS=~/artifacts 6 | 7 | if [ -z "$1" ]; then 8 | echo "usage: $0 " 9 | echo "reconfig FPGA board for clio" 10 | echo "ERROR: parameter artifact-config missing" 11 | exit 1 12 | fi 13 | 14 | COREO=$ARTIFACTS/$1/core.o 15 | FPGABIT=$ARTIFACTS/$1/fpga.bit 16 | 17 | # copy the core.o 18 | cp $COREO /tftpboot 19 | 20 | # reconfig the bitstream 21 | BITSTREAM=$FPGABIT make -C $CLIO_PETAPATH 22 | bash $CLIO_PETAPATH/board_init.sh 23 | -------------------------------------------------------------------------------- /tests/scripts/clio-test: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo " ___ ___ ___ " 4 | echo " /\ \ /\__\ ___ /\ \ " 5 | echo " /::\ \ /:/ / /\ \ /::\ \ " 6 | echo " /:/\:\ \ /:/ / \:\ \ /:/\:\ \ " 7 | echo " /:/ \:\ \ /:/ / /::\__\ /:/ \:\ \ " 8 | echo " /:/__/ \:\__\ /:/__/ __/:/\/__/ /:/__/ \:\__\ " 9 | echo " \:\ \ \/__/ \:\ \ /\/:/ / \:\ \ /:/ / " 10 | echo " \:\ \ \:\ \ \::/__/ \:\ /:/ / " 11 | echo " \:\ \ \:\ \ \:\__\ \:\/:/ / " 12 | echo " \:\__\ \:\__\ \/__/ \::/ / " 13 | echo " \/__/ \/__/ \/__/ " 14 | echo "" 15 | echo "Clio testing script." 16 | echo "===================================================" 17 | 18 | 19 | if [ -z "$1" ]; then 20 | echo "usage: $0 " 21 | echo "" 22 | echo "avaliable tests:" 23 | echo "1. Read Test" 24 | echo "2. Write Latency Test" 25 | echo "ERROR: test id missing!" 26 | exit 1 27 | fi 28 | 29 | echo "running test $1" 30 | echo "===================================================" 31 | 32 | case $1 in 33 | 1) 34 | clio-reconfig default 35 | ;; 36 | 2) 37 | clio-reconfig default 38 | ;; 39 | esac 40 | --------------------------------------------------------------------------------