├── test ├── layers │ ├── __init__.py │ ├── relu │ │ ├── config │ │ │ ├── config_10.json │ │ │ ├── config_0.json │ │ │ ├── config_6.json │ │ │ ├── config_7.json │ │ │ ├── config_9.json │ │ │ ├── config_2.json │ │ │ ├── config_3.json │ │ │ ├── config_8.json │ │ │ ├── config_5.json │ │ │ ├── config_1.json │ │ │ └── config_4.json │ │ ├── tb │ │ │ ├── relu_layer_tb.hpp │ │ │ └── relu_layer_tb.cpp │ │ ├── src │ │ │ └── relu_layer_top.cpp │ │ └── gen_layer.py │ ├── squeeze │ │ ├── config │ │ │ ├── config_3.json │ │ │ ├── config_1.json │ │ │ ├── config_2.json │ │ │ └── config_0.json │ │ ├── tb │ │ │ └── squeeze_layer_tb.hpp │ │ └── src │ │ │ └── squeeze_layer_top.cpp │ ├── clean_reports.sh │ ├── global_pooling │ │ ├── config │ │ │ └── config_0.json │ │ ├── tb │ │ │ └── global_pooling_layer_tb.hpp │ │ └── src │ │ │ └── global_pooling_layer_top.cpp │ ├── split │ │ ├── config │ │ │ └── config_0.json │ │ ├── tb │ │ │ └── split_layer_tb.hpp │ │ ├── src │ │ │ └── split_layer_top.cpp │ │ └── gen_layer.py │ ├── elementwise_add │ │ ├── config │ │ │ └── config_0.json │ │ ├── tb │ │ │ └── elementwise_add_layer_tb.hpp │ │ └── src │ │ │ └── elementwise_add_layer_top.cpp │ ├── elementwise_mul │ │ ├── config │ │ │ └── config_0.json │ │ ├── tb │ │ │ └── elementwise_mul_layer_tb.hpp │ │ └── src │ │ │ └── elementwise_mul_layer_top.cpp │ ├── pooling │ │ ├── config │ │ │ ├── config_10.json │ │ │ ├── config_11.json │ │ │ ├── config_12.json │ │ │ ├── config_0.json │ │ │ ├── config_1.json │ │ │ ├── config_6.json │ │ │ ├── config_8.json │ │ │ ├── config_2.json │ │ │ ├── config_3.json │ │ │ ├── config_7.json │ │ │ ├── config_5.json │ │ │ ├── config_4.json │ │ │ └── config_9.json │ │ ├── tb │ │ │ └── pooling_layer_tb.hpp │ │ └── src │ │ │ └── pooling_layer_top.cpp │ ├── batch_norm │ │ ├── tb │ │ │ ├── batch_norm_layer_tb.hpp │ │ │ └── batch_norm_layer_tb.cpp │ │ ├── config │ │ │ ├── config_3.json │ │ │ ├── config_4.json │ │ │ ├── config_2.json │ │ │ ├── config_5.json │ │ │ ├── config_6.json │ │ │ ├── config_7.json │ │ │ ├── config_8.json │ │ │ ├── config_9.json │ │ │ ├── config_0.json │ │ │ └── config_1.json │ │ └── src │ │ │ └── batch_norm_layer_top.cpp │ ├── avg_pooling │ │ ├── tb │ │ │ └── avg_pooling_layer_tb.hpp │ │ ├── config │ │ │ └── config_0.json │ │ └── src │ │ │ └── avg_pooling_layer_top.cpp │ ├── inner_product │ │ ├── config │ │ │ ├── config_10.json │ │ │ ├── config_8.json │ │ │ ├── config_4.json │ │ │ ├── config_7.json │ │ │ ├── config_2.json │ │ │ ├── config_3.json │ │ │ ├── config_5.json │ │ │ ├── config_6.json │ │ │ ├── config_9.json │ │ │ ├── config_1.json │ │ │ └── config_0.json │ │ ├── tb │ │ │ └── inner_product_layer_tb.hpp │ │ └── src │ │ │ └── inner_product_layer_top.cpp │ ├── convolution │ │ ├── tb │ │ │ └── convolution_layer_tb.hpp │ │ ├── config │ │ │ ├── config_3.json │ │ │ ├── config_4.json │ │ │ ├── config_5.json │ │ │ ├── config_2.json │ │ │ ├── config_1.json │ │ │ ├── config_6.json │ │ │ ├── config_7.json │ │ │ └── config_0.json │ │ └── src │ │ │ └── convolution_layer_top.cpp │ └── README.md ├── modules │ ├── __init__.py │ ├── relu │ │ ├── run.sh │ │ ├── config │ │ │ ├── config_0.json │ │ │ ├── config_6.json │ │ │ ├── config_8.json │ │ │ ├── config_5.json │ │ │ ├── config_2.json │ │ │ ├── config_4.json │ │ │ ├── config_3.json │ │ │ ├── config_7.json │ │ │ ├── config_9.json │ │ │ └── config_1.json │ │ ├── tb │ │ │ ├── relu_tb.hpp │ │ │ └── relu_tb.cpp │ │ ├── src │ │ │ └── relu.cpp │ │ ├── run_test.tcl │ │ └── gen_data.py │ ├── mem_read │ │ ├── config │ │ │ ├── config_2.json │ │ │ ├── config_3.json │ │ │ ├── config_0.json │ │ │ └── config_1.json │ │ ├── tb │ │ │ ├── mem_read_tb.hpp │ │ │ └── mem_read_tb.cpp │ │ ├── gen_data.py │ │ └── src │ │ │ └── mem_read.cpp │ ├── mem_write │ │ ├── config │ │ │ ├── config_3.json │ │ │ ├── config_0.json │ │ │ ├── config_1.json │ │ │ └── config_2.json │ │ ├── tb │ │ │ └── mem_write_tb.hpp │ │ ├── gen_data.py │ │ └── src │ │ │ └── mem_write.cpp │ ├── global_pool │ │ ├── config │ │ │ └── config_0.json │ │ ├── src │ │ │ └── global_pool.cpp │ │ ├── tb │ │ │ ├── global_pool_tb.hpp │ │ │ └── global_pool_tb.cpp │ │ └── gen_data.py │ ├── accum │ │ ├── config │ │ │ ├── config_5.json │ │ │ ├── config_3.json │ │ │ ├── config_2.json │ │ │ ├── config_4.json │ │ │ ├── config_0.json │ │ │ └── config_1.json │ │ ├── tb │ │ │ ├── accum_tb.hpp │ │ │ └── accum_tb.cpp │ │ ├── src │ │ │ └── accum.cpp │ │ └── gen_data.py │ ├── bias │ │ ├── config │ │ │ └── config_0.json │ │ ├── src │ │ │ └── bias.cpp │ │ ├── tb │ │ │ ├── bias_tb.hpp │ │ │ └── bias_tb.cpp │ │ └── gen_data.py │ ├── elementwise_add │ │ ├── config │ │ │ ├── config_0.json │ │ │ ├── config_2.json │ │ │ ├── config_3.json │ │ │ ├── config_4.json │ │ │ ├── config_5.json │ │ │ ├── config_6.json │ │ │ ├── config_7.json │ │ │ ├── config_9.json │ │ │ ├── config_8.json │ │ │ └── config_1.json │ │ ├── tb │ │ │ └── elementwise_add_tb.hpp │ │ └── src │ │ │ └── elementwise_add.cpp │ ├── elementwise_mul │ │ ├── config │ │ │ ├── config_0.json │ │ │ ├── config_2.json │ │ │ ├── config_3.json │ │ │ ├── config_4.json │ │ │ ├── config_5.json │ │ │ ├── config_6.json │ │ │ ├── config_7.json │ │ │ ├── config_9.json │ │ │ ├── config_8.json │ │ │ └── config_1.json │ │ ├── tb │ │ │ └── elementwise_mul_tb.hpp │ │ └── src │ │ │ └── elementwise_mul.cpp │ ├── avg_pool │ │ ├── config │ │ │ └── config_0.json │ │ ├── tb │ │ │ ├── avg_pool_tb.hpp │ │ │ └── avg_pool_tb.cpp │ │ ├── src │ │ │ └── avg_pool.cpp │ │ └── gen_data.py │ ├── conv │ │ ├── config │ │ │ ├── config_2.json │ │ │ ├── config_1.json │ │ │ ├── config_3.json │ │ │ ├── config_0.json │ │ │ ├── config_5.json │ │ │ ├── config_4.json │ │ │ ├── config_6.json │ │ │ ├── config_10.json │ │ │ ├── config_11.json │ │ │ ├── config_7.json │ │ │ ├── config_8.json │ │ │ ├── config_9.json │ │ │ └── config_12.json │ │ ├── tb │ │ │ └── conv_tb.hpp │ │ └── src │ │ │ └── conv.cpp │ ├── pool │ │ ├── config │ │ │ ├── config_11.json │ │ │ ├── config_7.json │ │ │ ├── config_3.json │ │ │ ├── config_5.json │ │ │ ├── config_6.json │ │ │ ├── config_8.json │ │ │ ├── config_9.json │ │ │ ├── config_4.json │ │ │ ├── config_0.json │ │ │ ├── config_10.json │ │ │ ├── config_1.json │ │ │ └── config_2.json │ │ ├── tb │ │ │ ├── pool_tb.hpp │ │ │ └── pool_tb.cpp │ │ ├── src │ │ │ └── pool.cpp │ │ └── gen_data.py │ ├── run_all_tests.sh │ ├── squeeze │ │ ├── config │ │ │ ├── config_2.json │ │ │ ├── config_3.json │ │ │ ├── config_0.json │ │ │ └── config_1.json │ │ ├── tb │ │ │ ├── squeeze_tb.hpp │ │ │ └── squeeze_tb.cpp │ │ └── src │ │ │ └── squeeze.cpp │ ├── fork │ │ ├── config │ │ │ ├── config_0.json │ │ │ ├── config_6.json │ │ │ ├── config_8.json │ │ │ ├── config_1.json │ │ │ ├── config_2.json │ │ │ ├── config_3.json │ │ │ ├── config_4.json │ │ │ ├── config_5.json │ │ │ ├── config_7.json │ │ │ └── config_9.json │ │ ├── tb │ │ │ └── fork_tb.hpp │ │ ├── src │ │ │ └── fork.cpp │ │ └── gen_data.py │ ├── glue │ │ ├── config │ │ │ ├── config_7.json │ │ │ ├── config_0.json │ │ │ ├── config_4.json │ │ │ ├── config_5.json │ │ │ ├── config_2.json │ │ │ ├── config_3.json │ │ │ ├── config_6.json │ │ │ ├── config_8.json │ │ │ ├── config_1.json │ │ │ └── config_9.json │ │ ├── tb │ │ │ ├── glue_tb.hpp │ │ │ └── glue_tb.cpp │ │ ├── src │ │ │ └── glue.cpp │ │ └── gen_data.py │ ├── sliding_window │ │ ├── config │ │ │ ├── config_0.json │ │ │ ├── config_8.json │ │ │ ├── config_10.json │ │ │ ├── config_9.json │ │ │ ├── config_4.json │ │ │ ├── config_1.json │ │ │ ├── config_2.json │ │ │ ├── config_3.json │ │ │ ├── config_5.json │ │ │ ├── config_6.json │ │ │ └── config_7.json │ │ ├── tb │ │ │ └── sliding_window_tb.hpp │ │ ├── src │ │ │ └── sliding_window.cpp │ │ └── gen_data.py │ ├── clean_reports.sh │ ├── README.md │ └── run_tests.sh ├── networks │ ├── mnist_example.png │ ├── imagenet_example.jpeg │ ├── tfc │ │ └── run_test.py │ └── single_layer │ │ └── run_test.py ├── partitions │ └── single_layer │ │ └── run_test.py └── display_configs.py ├── fpgaconvnet └── hls │ ├── tools │ ├── __init__.py │ ├── array_init.py │ └── vivado_hls_wrapper.py │ ├── scripts │ └── hls │ │ ├── common.tcl │ │ ├── tcl_getopt.tcl │ │ ├── run_csynth.tcl │ │ ├── export_design.tcl │ │ ├── run_implementation.tcl │ │ ├── run_csim.tcl │ │ ├── run_cosim.tcl │ │ └── create_partition_project.tcl │ ├── generate │ ├── layers │ │ └── __init__.py │ ├── modules │ │ ├── __init__.py │ │ ├── relu.py │ │ ├── global_pool.py │ │ ├── accum.py │ │ ├── pool.py │ │ ├── squeeze.py │ │ ├── avg_pool.py │ │ ├── bias.py │ │ ├── glue.py │ │ ├── elementwise_add.py │ │ ├── elementwise_mul.py │ │ ├── sliding_window.py │ │ ├── module.py │ │ └── conv.py │ └── __init__.py │ ├── __init__.py │ └── hardware │ ├── elementwise_mul.hpp │ ├── elementwise_add.hpp │ ├── fifo.hpp │ ├── batch_norm.hpp │ ├── avg_pool.hpp │ ├── relu.hpp │ ├── bias.hpp │ └── common.hpp ├── MANIFEST.in ├── .gitmodules ├── .github └── workflows │ └── publish.yml ├── .gitignore └── README.md /test/layers/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/modules/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /fpgaconvnet/hls/tools/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /fpgaconvnet/hls/scripts/hls/common.tcl: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /fpgaconvnet/hls/generate/layers/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /fpgaconvnet/hls/generate/modules/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/modules/relu/run.sh: -------------------------------------------------------------------------------- 1 | # TEST 1 2 | python3 gen_relu.py -c config/config_0.json #-o ../../../test/relu/data/data_1.yaml 3 | -------------------------------------------------------------------------------- /test/networks/mnist_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexMontgomerie/fpgaconvnet-hls/HEAD/test/networks/mnist_example.png -------------------------------------------------------------------------------- /test/networks/imagenet_example.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexMontgomerie/fpgaconvnet-hls/HEAD/test/networks/imagenet_example.jpeg -------------------------------------------------------------------------------- /fpgaconvnet/hls/generate/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | This part of the code contains wrappers for generating and executing the HLS 3 | IP blocks. 4 | """ 5 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include fpgaconvnet/hls/scripts/hls/*.tcl 2 | include fpgaconvnet/hls/hardware/*.hpp 3 | graft fpgaconvnet/hls/hardware/hlslib/include 4 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "fpgaconvnet/hls/hardware/hlslib"] 2 | path = fpgaconvnet/hls/hardware/hlslib 3 | url = https://github.com/definelicht/hlslib.git 4 | -------------------------------------------------------------------------------- /test/modules/mem_read/config/config_2.json: -------------------------------------------------------------------------------- 1 | { 2 | "rows" : 2, 3 | "cols" : 2, 4 | "channels" : 4, 5 | "ports_hw" : 1, 6 | "ports" : 3, 7 | "description" : "" 8 | } 9 | -------------------------------------------------------------------------------- /test/modules/mem_read/config/config_3.json: -------------------------------------------------------------------------------- 1 | { 2 | "rows" : 2, 3 | "cols" : 2, 4 | "channels" : 4, 5 | "ports_hw" : 1, 6 | "ports" : 4, 7 | "description" : "" 8 | } 9 | -------------------------------------------------------------------------------- /test/modules/mem_write/config/config_3.json: -------------------------------------------------------------------------------- 1 | { 2 | "rows" : 2, 3 | "cols" : 2, 4 | "channels" : 1, 5 | "ports_hw" : 1, 6 | "ports" : 4, 7 | "description" : "" 8 | } 9 | -------------------------------------------------------------------------------- /test/modules/global_pool/config/config_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "GLOBAL_POOL", 3 | "rows": 40, 4 | "cols": 40, 5 | "channels": 4, 6 | "batch_size": 1, 7 | "description": "module name: global_pool" 8 | } 9 | -------------------------------------------------------------------------------- /test/modules/accum/config/config_5.json: -------------------------------------------------------------------------------- 1 | { 2 | "rows": 1, 3 | "cols": 1, 4 | "channels": 800, 5 | "filters": 500, 6 | "groups": 1, 7 | "batch_size": 1, 8 | "description": "ip1 for lenet" 9 | } 10 | -------------------------------------------------------------------------------- /test/modules/bias/config/config_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "batch_size": 1, 3 | "rows": 2, 4 | "cols": 2, 5 | "channels":1, 6 | "groups":1, 7 | "filters":2, 8 | "description": "bias module basic" 9 | } 10 | -------------------------------------------------------------------------------- /test/modules/accum/config/config_3.json: -------------------------------------------------------------------------------- 1 | { 2 | "rows": 28, 3 | "cols": 28, 4 | "channels": 4, 5 | "filters": 8, 6 | "groups": 2, 7 | "batch_size": 1, 8 | "description": "2 groups, 1 filter" 9 | } 10 | -------------------------------------------------------------------------------- /test/modules/accum/config/config_2.json: -------------------------------------------------------------------------------- 1 | { 2 | "rows": 10, 3 | "cols": 10, 4 | "channels": 1, 5 | "filters": 64, 6 | "groups": 1, 7 | "batch_size": 1, 8 | "description": "multi filter, 1 channel" 9 | } 10 | -------------------------------------------------------------------------------- /test/layers/relu/config/config_10.json: -------------------------------------------------------------------------------- 1 | { 2 | "rows": 26, 3 | "cols": 26, 4 | "channels": 32, 5 | "coarse": 1, 6 | "coarse_in": 1, 7 | "coarse_out": 1, 8 | "batch_size": 1, 9 | "description": "f" 10 | } 11 | -------------------------------------------------------------------------------- /test/modules/accum/config/config_4.json: -------------------------------------------------------------------------------- 1 | { 2 | "rows": 56, 3 | "cols": 56, 4 | "channels": 512, 5 | "filters": 32, 6 | "groups": 4, 7 | "batch_size": 1, 8 | "description": "4 groups, many channels and filters" 9 | } 10 | -------------------------------------------------------------------------------- /test/modules/elementwise_add/config/config_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "EltWiseADD", 3 | "rows": 14, 4 | "cols": 14, 5 | "channels": 64, 6 | "batch_size": 1, 7 | "description": "module name: elementwise_add, layer name: , net name: " 8 | } 9 | -------------------------------------------------------------------------------- /test/modules/elementwise_mul/config/config_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "EltWiseMUL", 3 | "rows": 14, 4 | "cols": 14, 5 | "channels": 64, 6 | "batch_size": 1, 7 | "description": "module name: elementwise_add, layer name: , net name: " 8 | } 9 | -------------------------------------------------------------------------------- /test/modules/relu/config/config_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "RELU", 3 | "rows": 14, 4 | "cols": 14, 5 | "channels": 64, 6 | "batch_size": 1, 7 | "description": "module name: relu, layer name: res3c_branch2a_relu, net name: resnet.prototxt" 8 | } 9 | -------------------------------------------------------------------------------- /test/modules/mem_read/config/config_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "batch_size" : 1, 3 | "rows_in" : 5, 4 | "cols_in" : 5, 5 | "channels_in" : 5, 6 | "streams_in" : 1, 7 | "ports_in" : 1, 8 | "description" : "" 9 | } 10 | -------------------------------------------------------------------------------- /test/modules/avg_pool/config/config_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "POOL", 3 | "rows": 1, 4 | "cols": 1, 5 | "channels": 4, 6 | "pool_type": 1, 7 | "kernel_size": [3,3], 8 | "batch_size": 1, 9 | "description": "module name: avg_pool" 10 | } 11 | -------------------------------------------------------------------------------- /test/modules/mem_read/config/config_1.json: -------------------------------------------------------------------------------- 1 | { 2 | "batch_size" : 1, 3 | "rows_in" : 10, 4 | "cols_in" : 10, 5 | "channels_in" : 160, 6 | "streams_in" : 5, 7 | "ports_in" : 2, 8 | "description" : "" 9 | } 10 | -------------------------------------------------------------------------------- /fpgaconvnet/hls/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | This part of the repo contains code used for generating the HLS code that 3 | corresponds to a given configuration. The top level 4 | `fpgaconvnet.hls.generate.Network` class is what generates HLS from a 5 | protobuf description file. 6 | """ 7 | -------------------------------------------------------------------------------- /test/modules/conv/config/config_2.json: -------------------------------------------------------------------------------- 1 | { 2 | "rows": 4, 3 | "cols": 4, 4 | "channels": 2, 5 | "filters": 1, 6 | "group": 1, 7 | "fine": 4, 8 | "kernel_size": [3,3], 9 | "batch_size": 1, 10 | "description": "single filter, 3x3" 11 | } 12 | -------------------------------------------------------------------------------- /test/modules/conv/config/config_1.json: -------------------------------------------------------------------------------- 1 | { 2 | "rows": 28, 3 | "cols": 28, 4 | "channels": 256, 5 | "filters": 2, 6 | "groups": 1, 7 | "fine": 1, 8 | "kernel_size": [1,1], 9 | "batch_size": 1, 10 | "description": "single filter, 1x1" 11 | } 12 | -------------------------------------------------------------------------------- /test/modules/pool/config/config_11.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "POOL", 3 | "rows": 28, 4 | "cols": 28, 5 | "channels": 32, 6 | "pool_type": 0, 7 | "kernel_size": [3,3], 8 | "batch_size": 1, 9 | "description": "googlenet: pool_3x3_s2 pool module" 10 | } 11 | -------------------------------------------------------------------------------- /test/modules/run_all_tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ./run_tests.sh -m accum 3 | ./run_tests.sh -m conv 4 | ./run_tests.sh -m glue 5 | ./run_tests.sh -m fork 6 | ./run_tests.sh -m pool 7 | ./run_tests.sh -m sliding_window 8 | ./run_tests.sh -m squeeze 9 | ./run_tests.sh -m relu 10 | 11 | -------------------------------------------------------------------------------- /test/modules/conv/config/config_3.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "CONV", 3 | "rows": 14, 4 | "cols": 14, 5 | "channels": 64, 6 | "filters": 16, 7 | "group": 1, 8 | "fine": 1, 9 | "kernel_size": [1,1], 10 | "batch_size": 1, 11 | "description": "1x1" 12 | } 13 | -------------------------------------------------------------------------------- /test/modules/conv/config/config_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "batch_size": 1, 3 | "rows": 16, 4 | "cols": 16, 5 | "channels":64, 6 | "filters":32, 7 | "groups": 1, 8 | "fine": 1, 9 | "kernel_size": [2,2], 10 | "description": "single channel, single filter, 1x1" 11 | } 12 | -------------------------------------------------------------------------------- /test/modules/conv/config/config_5.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "CONV", 3 | "rows": 28, 4 | "cols": 28, 5 | "channels": 16, 6 | "filters": 32, 7 | "group": 1, 8 | "fine": 1, 9 | "kernel_size": [3,3], 10 | "batch_size": 1, 11 | "description": "fine=1" 12 | } 13 | -------------------------------------------------------------------------------- /test/modules/squeeze/config/config_2.json: -------------------------------------------------------------------------------- 1 | { 2 | "rows": 1, 3 | "cols": 1, 4 | "channels": 250, 5 | "coarse_in": 1, 6 | "coarse_out": 10, 7 | "batch_size": 2, 8 | "description": "module name: fork, layer name: res4f_branch2a, net name: resnet.prototxt" 9 | } 10 | -------------------------------------------------------------------------------- /test/modules/squeeze/config/config_3.json: -------------------------------------------------------------------------------- 1 | { 2 | "rows": 10, 3 | "cols": 10, 4 | "channels": 10, 5 | "coarse_in": 1, 6 | "coarse_out": 1, 7 | "batch_size": 2, 8 | "description": "module name: fork, layer name: res4f_branch2a, net name: resnet.prototxt" 9 | } 10 | -------------------------------------------------------------------------------- /test/modules/accum/config/config_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "rows": 10, 3 | "cols": 10, 4 | "channels": 10, 5 | "filters": 2, 6 | "groups": 1, 7 | "batch_size": 1, 8 | "data_width": 30, 9 | "data_int_width": 16, 10 | "description": "multi channel, multi filter" 11 | } 12 | -------------------------------------------------------------------------------- /test/modules/conv/config/config_4.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "CONV", 3 | "rows": 28, 4 | "cols": 28, 5 | "channels": 1, 6 | "filters": 32, 7 | "group": 1, 8 | "fine": 1, 9 | "kernel_size": [3,3], 10 | "batch_size": 1, 11 | "description": "1 channel, 3x3" 12 | } 13 | -------------------------------------------------------------------------------- /test/modules/conv/config/config_6.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "CONV", 3 | "rows": 56, 4 | "cols": 56, 5 | "channels": 16, 6 | "filters": 16, 7 | "group": 1, 8 | "fine": 3, 9 | "kernel_size": [3,3], 10 | "batch_size": 1, 11 | "description": "fine=kernel size" 12 | } 13 | -------------------------------------------------------------------------------- /test/modules/mem_write/config/config_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "batch_size" : 1, 3 | "rows_out" : 10, 4 | "cols_out" : 10, 5 | "channels_out" : 10, 6 | "streams_out" : 1, 7 | "ports_out" : 1, 8 | "weights_reloading_factor" : 1, 9 | "description" : "" 10 | } 11 | -------------------------------------------------------------------------------- /test/modules/mem_write/config/config_1.json: -------------------------------------------------------------------------------- 1 | { 2 | "batch_size" : 1, 3 | "rows_out" : 10, 4 | "cols_out" : 10, 5 | "channels_out" : 80, 6 | "streams_out" : 8, 7 | "ports_out" : 1, 8 | "weights_reloading_factor" : 1, 9 | "description" : "" 10 | } 11 | -------------------------------------------------------------------------------- /test/modules/mem_write/config/config_2.json: -------------------------------------------------------------------------------- 1 | { 2 | "batch_size" : 1, 3 | "rows_out" : 10, 4 | "cols_out" : 10, 5 | "channels_out" : 80, 6 | "streams_out" : 2, 7 | "ports_out" : 1, 8 | "weights_reloading_factor" : 2, 9 | "description" : "" 10 | } 11 | -------------------------------------------------------------------------------- /test/modules/pool/config/config_7.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "POOL", 3 | "rows": 4, 4 | "cols": 4, 5 | "channels": 1, 6 | "pool_type": 0, 7 | "kernel_size": [2,2], 8 | "batch_size": 1, 9 | "description": "module name: pool, layer name: pool2, net name: lenet.prototxt" 10 | } 11 | -------------------------------------------------------------------------------- /test/modules/pool/config/config_3.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "POOL", 3 | "rows": 56, 4 | "cols": 56, 5 | "channels": 16, 6 | "pool_type": 0, 7 | "kernel_size": [3,3], 8 | "batch_size": 1, 9 | "description": "module name: pool, layer name: pool1, net name: resnet.prototxt" 10 | } 11 | -------------------------------------------------------------------------------- /test/modules/pool/config/config_5.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "POOL", 3 | "rows": 7, 4 | "cols": 7, 5 | "channels": 32, 6 | "pool_type": 0, 7 | "kernel_size": [2,2], 8 | "batch_size": 1, 9 | "description": "module name: pool, layer name: pool5, net name: vgg16.prototxt" 10 | } 11 | -------------------------------------------------------------------------------- /test/modules/pool/config/config_6.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "POOL", 3 | "rows": 12, 4 | "cols": 12, 5 | "channels": 10, 6 | "pool_type": 0, 7 | "kernel_size": [2,2], 8 | "batch_size": 1, 9 | "description": "module name: pool, layer name: pool1, net name: lenet.prototxt" 10 | } 11 | -------------------------------------------------------------------------------- /test/modules/pool/config/config_8.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "POOL", 3 | "rows": 1, 4 | "cols": 1, 5 | "channels": 4, 6 | "pool_type": 0, 7 | "kernel_size": [7,7], 8 | "batch_size": 1, 9 | "description": "module name: pool, layer name: pool5, net name: resnet.prototxt" 10 | } 11 | -------------------------------------------------------------------------------- /test/modules/pool/config/config_9.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "POOL", 3 | "rows": 112, 4 | "cols": 112, 5 | "channels": 4, 6 | "pool_type": 0, 7 | "kernel_size": [2,2], 8 | "batch_size": 1, 9 | "description": "module name: pool, layer name: pool1, net name: vgg16.prototxt" 10 | } 11 | -------------------------------------------------------------------------------- /test/layers/squeeze/config/config_3.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "SQUEEZE", 3 | "rows_in": 12, 4 | "cols_in": 12, 5 | "channels_in": 20, 6 | "coarse_in": 20, 7 | "coarse_out": 1, 8 | "batch_size": 1, 9 | "buffer_depth": 1, 10 | "data_width": 16, 11 | "description": "" 12 | } 13 | -------------------------------------------------------------------------------- /test/modules/fork/config/config_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "FORK", 3 | "rows": 14, 4 | "cols": 14, 5 | "channels": 32, 6 | "coarse": 8, 7 | "kernel_size": [1,1], 8 | "batch_size": 1, 9 | "description": "module name: fork, layer name: res4f_branch2a, net name: resnet.prototxt" 10 | } 11 | -------------------------------------------------------------------------------- /test/layers/clean_reports.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | function clean_prj { 4 | if [ $1 ]; then 5 | rm ${1}/rpt/* 6 | rm -rf ${1}/data/* 7 | rm -rf ${1}/${1}_hls_prj/* 8 | fi 9 | } 10 | 11 | clean_prj concat 12 | clean_prj relu 13 | clean_prj convolution 14 | clean_prj pooling 15 | 16 | -------------------------------------------------------------------------------- /test/modules/accum/config/config_1.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "ACCUM", 3 | "rows": 28, 4 | "cols": 28, 5 | "channels": 8, 6 | "filters": 1, 7 | "groups": 1, 8 | "batch_size": 1, 9 | "data_width": 16, 10 | "data_int_width": 8, 11 | "description": "mutli channel, 1 filter" 12 | } 13 | -------------------------------------------------------------------------------- /test/modules/glue/config/config_7.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "GLUE", 3 | "rows": 28, 4 | "cols": 28, 5 | "filters": 64, 6 | "coarse_in": 4, 7 | "coarse_out": 4, 8 | "batch_size": 1, 9 | "description": "module name: glue, layer name: inception_3a/1x1, net name: googlenet.prototxt" 10 | } 11 | -------------------------------------------------------------------------------- /test/modules/pool/config/config_4.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "POOL", 3 | "rows": 28, 4 | "cols": 28, 5 | "channels": 2, 6 | "pool_type": 0, 7 | "kernel_size": [3,3], 8 | "batch_size": 1, 9 | "description": "module name: pool, layer name: pool2/3x3_s2, net name: googlenet.prototxt" 10 | } 11 | -------------------------------------------------------------------------------- /test/modules/squeeze/config/config_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "SQUEEZE", 3 | "rows": 12, 4 | "cols": 12, 5 | "channels": 20, 6 | "coarse_in": 2, 7 | "coarse_out": 5, 8 | "batch_size": 1, 9 | "description": "module name: fork, layer name: res4f_branch2a, net name: resnet.prototxt" 10 | } 11 | -------------------------------------------------------------------------------- /test/modules/squeeze/config/config_1.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "FORK", 3 | "rows": 12, 4 | "cols": 12, 5 | "channels": 20, 6 | "coarse_in": 10, 7 | "coarse_out": 20, 8 | "batch_size": 1, 9 | "description": "module name: fork, layer name: res4f_branch2a, net name: resnet.prototxt" 10 | } 11 | -------------------------------------------------------------------------------- /test/modules/pool/config/config_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "POOL", 3 | "rows": 1, 4 | "cols": 1, 5 | "channels": 4, 6 | "pool_type": 0, 7 | "kernel_size": [3,3], 8 | "batch_size": 1, 9 | "description": "module name: pool, layer name: inception_3a/pool, net name: googlenet.prototxt" 10 | } 11 | -------------------------------------------------------------------------------- /test/modules/pool/config/config_10.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "POOL", 3 | "rows": 28, 4 | "cols": 28, 5 | "channels": 32, 6 | "pool_type": 0, 7 | "kernel_size": [2,2], 8 | "batch_size": 1, 9 | "description": "module name: pool, layer name: inception_5a/pool, net name: googlenet.prototxt" 10 | } 11 | -------------------------------------------------------------------------------- /test/modules/relu/config/config_6.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "RELU", 3 | "rows": 14, 4 | "cols": 14, 5 | "channels": 8, 6 | "rows_out": 14, 7 | "cols_out": 14, 8 | "channels_out": 8, 9 | "batch_size": 1, 10 | "description": "module name: relu, layer name: relu5_2, net name: vgg16.prototxt" 11 | } -------------------------------------------------------------------------------- /test/layers/squeeze/config/config_1.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "FORK", 3 | "rows_in": 12, 4 | "cols_in": 12, 5 | "channels_in": 20, 6 | "coarse_in": 10, 7 | "coarse_out": 20, 8 | "batch_size": 1, 9 | "description": "module name: fork, layer name: res4f_branch2a, net name: resnet.prototxt" 10 | } 11 | -------------------------------------------------------------------------------- /test/modules/conv/config/config_10.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "CONV", 3 | "rows": 1, 4 | "cols": 1, 5 | "channels": 800, 6 | "filters": 500, 7 | "group": 1, 8 | "fine": 1, 9 | "kernel_size": [1,1], 10 | "batch_size": 1, 11 | "description": "module name: conv, layer name: ip1 (lenet)" 12 | } 13 | -------------------------------------------------------------------------------- /test/modules/conv/config/config_11.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "CONV", 3 | "rows": 2, 4 | "cols": 2, 5 | "channels": 2, 6 | "filters": 2, 7 | "groups": 1, 8 | "fine": 1, 9 | "kernel_size": [1,1], 10 | "batch_size": 1, 11 | "description": "module name: conv, layer name: ip1 (lenet)" 12 | } 13 | -------------------------------------------------------------------------------- /test/modules/relu/config/config_8.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "RELU", 3 | "rows": 28, 4 | "cols": 28, 5 | "channels": 512, 6 | "rows_out": 28, 7 | "cols_out": 28, 8 | "channels_out": 512, 9 | "batch_size": 1, 10 | "description": "module name: relu, layer name: relu4_1, net name: vgg16.prototxt" 11 | } -------------------------------------------------------------------------------- /test/modules/elementwise_add/config/config_2.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "EltWiseADD", 3 | "rows": 14, 4 | "cols": 14, 5 | "channels": 64, 6 | "rows_out": 14, 7 | "cols_out": 14, 8 | "channels_out": 64, 9 | "batch_size": 1, 10 | "description": "module name: elementwise_add, layer name: , net name: " 11 | } -------------------------------------------------------------------------------- /test/modules/elementwise_add/config/config_3.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "EltWiseADD", 3 | "rows": 28, 4 | "cols": 28, 5 | "channels": 8, 6 | "rows_out": 28, 7 | "cols_out": 28, 8 | "channels_out": 8, 9 | "batch_size": 1, 10 | "description": "module name: elementwise_add, layer name: , net name: " 11 | } -------------------------------------------------------------------------------- /test/modules/elementwise_add/config/config_4.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "EltWiseADD", 3 | "rows": 56, 4 | "cols": 56, 5 | "channels": 1, 6 | "rows_out": 56, 7 | "cols_out": 56, 8 | "channels_out": 1, 9 | "batch_size": 1, 10 | "description": "module name: elementwise_add, layer name: , net name: " 11 | } -------------------------------------------------------------------------------- /test/modules/elementwise_add/config/config_5.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "EltWiseADD", 3 | "rows": 56, 4 | "cols": 56, 5 | "channels": 16, 6 | "rows_out": 56, 7 | "cols_out": 56, 8 | "channels_out": 16, 9 | "batch_size": 1, 10 | "description": "module name: elementwise_add, layer name: , net name: " 11 | } -------------------------------------------------------------------------------- /test/modules/elementwise_add/config/config_6.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "EltWiseADD", 3 | "rows": 14, 4 | "cols": 14, 5 | "channels": 8, 6 | "rows_out": 14, 7 | "cols_out": 14, 8 | "channels_out": 8, 9 | "batch_size": 1, 10 | "description": "module name: elementwise_add, layer name: , net name: " 11 | } -------------------------------------------------------------------------------- /test/modules/elementwise_add/config/config_7.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "EltWiseADD", 3 | "rows": 28, 4 | "cols": 28, 5 | "channels": 1, 6 | "rows_out": 28, 7 | "cols_out": 28, 8 | "channels_out": 1, 9 | "batch_size": 1, 10 | "description": "module name: elementwise_add, layer name: , net name: " 11 | } -------------------------------------------------------------------------------- /test/modules/elementwise_add/config/config_9.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "EltWiseADD", 3 | "rows": 28, 4 | "cols": 28, 5 | "channels": 32, 6 | "rows_out": 28, 7 | "cols_out": 28, 8 | "channels_out": 32, 9 | "batch_size": 1, 10 | "description": "module name: elementwise_add, layer name: , net name: " 11 | } -------------------------------------------------------------------------------- /test/modules/elementwise_mul/config/config_2.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "EltWiseMUL", 3 | "rows": 14, 4 | "cols": 14, 5 | "channels": 64, 6 | "rows_out": 14, 7 | "cols_out": 14, 8 | "channels_out": 64, 9 | "batch_size": 1, 10 | "description": "module name: elementwise_add, layer name: , net name: " 11 | } -------------------------------------------------------------------------------- /test/modules/elementwise_mul/config/config_3.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "EltWiseMUL", 3 | "rows": 28, 4 | "cols": 28, 5 | "channels": 8, 6 | "rows_out": 28, 7 | "cols_out": 28, 8 | "channels_out": 8, 9 | "batch_size": 1, 10 | "description": "module name: elementwise_add, layer name: , net name: " 11 | } -------------------------------------------------------------------------------- /test/modules/elementwise_mul/config/config_4.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "EltWiseMUL", 3 | "rows": 56, 4 | "cols": 56, 5 | "channels": 1, 6 | "rows_out": 56, 7 | "cols_out": 56, 8 | "channels_out": 1, 9 | "batch_size": 1, 10 | "description": "module name: elementwise_add, layer name: , net name: " 11 | } -------------------------------------------------------------------------------- /test/modules/elementwise_mul/config/config_5.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "EltWiseMUL", 3 | "rows": 56, 4 | "cols": 56, 5 | "channels": 16, 6 | "rows_out": 56, 7 | "cols_out": 56, 8 | "channels_out": 16, 9 | "batch_size": 1, 10 | "description": "module name: elementwise_add, layer name: , net name: " 11 | } -------------------------------------------------------------------------------- /test/modules/elementwise_mul/config/config_6.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "EltWiseMUL", 3 | "rows": 14, 4 | "cols": 14, 5 | "channels": 8, 6 | "rows_out": 14, 7 | "cols_out": 14, 8 | "channels_out": 8, 9 | "batch_size": 1, 10 | "description": "module name: elementwise_add, layer name: , net name: " 11 | } -------------------------------------------------------------------------------- /test/modules/elementwise_mul/config/config_7.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "EltWiseMUL", 3 | "rows": 28, 4 | "cols": 28, 5 | "channels": 1, 6 | "rows_out": 28, 7 | "cols_out": 28, 8 | "channels_out": 1, 9 | "batch_size": 1, 10 | "description": "module name: elementwise_add, layer name: , net name: " 11 | } -------------------------------------------------------------------------------- /test/modules/elementwise_mul/config/config_9.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "EltWiseMUL", 3 | "rows": 28, 4 | "cols": 28, 5 | "channels": 32, 6 | "rows_out": 28, 7 | "cols_out": 28, 8 | "channels_out": 32, 9 | "batch_size": 1, 10 | "description": "module name: elementwise_add, layer name: , net name: " 11 | } -------------------------------------------------------------------------------- /test/modules/relu/config/config_5.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "RELU", 3 | "rows": 56, 4 | "cols": 56, 5 | "channels": 16, 6 | "rows_out": 56, 7 | "cols_out": 56, 8 | "channels_out": 16, 9 | "batch_size": 1, 10 | "description": "module name: relu, layer name: res2a_relu, net name: resnet.prototxt" 11 | } -------------------------------------------------------------------------------- /test/modules/elementwise_add/config/config_8.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "EltWiseADD", 3 | "rows": 28, 4 | "cols": 28, 5 | "channels": 512, 6 | "rows_out": 28, 7 | "cols_out": 28, 8 | "channels_out": 512, 9 | "batch_size": 1, 10 | "description": "module name: elementwise_add, layer name: , net name: " 11 | } -------------------------------------------------------------------------------- /test/modules/elementwise_mul/config/config_8.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "EltWiseMUL", 3 | "rows": 28, 4 | "cols": 28, 5 | "channels": 512, 6 | "rows_out": 28, 7 | "cols_out": 28, 8 | "channels_out": 512, 9 | "batch_size": 1, 10 | "description": "module name: elementwise_add, layer name: , net name: " 11 | } -------------------------------------------------------------------------------- /test/modules/relu/config/config_2.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "RELU", 3 | "rows": 14, 4 | "cols": 14, 5 | "channels": 64, 6 | "rows_out": 14, 7 | "cols_out": 14, 8 | "channels_out": 64, 9 | "batch_size": 1, 10 | "description": "module name: relu, layer name: res4d_branch2b_relu, net name: resnet.prototxt" 11 | } -------------------------------------------------------------------------------- /test/modules/relu/config/config_4.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "RELU", 3 | "rows": 56, 4 | "cols": 56, 5 | "channels": 1, 6 | "rows_out": 56, 7 | "cols_out": 56, 8 | "channels_out": 1, 9 | "batch_size": 1, 10 | "description": "module name: relu, layer name: res2c_branch2a_relu, net name: resnet.prototxt" 11 | } -------------------------------------------------------------------------------- /test/modules/relu/config/config_3.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "RELU", 3 | "rows": 28, 4 | "cols": 28, 5 | "channels": 8, 6 | "rows_out": 28, 7 | "cols_out": 28, 8 | "channels_out": 8, 9 | "batch_size": 1, 10 | "description": "module name: relu, layer name: inception_3b/relu_5x5_reduce, net name: googlenet.prototxt" 11 | } -------------------------------------------------------------------------------- /test/modules/relu/config/config_7.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "RELU", 3 | "rows": 28, 4 | "cols": 28, 5 | "channels": 1, 6 | "rows_out": 28, 7 | "cols_out": 28, 8 | "channels_out": 1, 9 | "batch_size": 1, 10 | "description": "module name: relu, layer name: inception_3a/relu_5x5_reduce, net name: googlenet.prototxt" 11 | } -------------------------------------------------------------------------------- /test/modules/glue/config/config_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "GLUE", 3 | "rows": 8, 4 | "cols": 8, 5 | "channels": 50, 6 | "filters": 50, 7 | "coarse_in": 1, 8 | "coarse_out": 1, 9 | "coarse_group": 1, 10 | "batch_size": 1, 11 | "description": "module name: glue, layer name: conv2, net name: lenet.prototxt" 12 | } 13 | -------------------------------------------------------------------------------- /test/modules/relu/config/config_9.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "RELU", 3 | "rows": 28, 4 | "cols": 28, 5 | "channels": 32, 6 | "rows_out": 28, 7 | "cols_out": 28, 8 | "channels_out": 32, 9 | "batch_size": 1, 10 | "description": "module name: relu, layer name: inception_3a/relu_3x3_reduce, net name: googlenet.prototxt" 11 | } -------------------------------------------------------------------------------- /test/modules/sliding_window/config/config_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "batch_size" : 1, 3 | "rows" : 28, 4 | "cols" : 28, 5 | "channels" : 1, 6 | "pad_top" : 0, 7 | "pad_right" : 0, 8 | "pad_bottom" : 0, 9 | "pad_left" : 0, 10 | "stride" : [1,1], 11 | "kernel_size" : [5,5], 12 | "description" : "lenet (conv1)" 13 | } 14 | -------------------------------------------------------------------------------- /test/modules/sliding_window/config/config_8.json: -------------------------------------------------------------------------------- 1 | { 2 | "batch_size" : 1, 3 | "rows" : 64, 4 | "cols" : 64, 5 | "channels" : 8, 6 | "pad_top" : 0, 7 | "pad_right" : 0, 8 | "pad_bottom" : 0, 9 | "pad_left" : 0, 10 | "stride" : [8,8], 11 | "kernel_size" : [8,8], 12 | "description" : "dct example" 13 | } 14 | -------------------------------------------------------------------------------- /test/layers/global_pooling/config/config_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "GLOBAL_POOLING", 3 | "rows_in": 8, 4 | "cols_in": 8, 5 | "channels_in": 32, 6 | "coarse": 1, 7 | "coarse_in": 1, 8 | "coarse_out": 1, 9 | "batch_size": 1, 10 | "data_width": 16, 11 | "description": "layer name: pool1, net name: resnet.prototxt" 12 | } 13 | -------------------------------------------------------------------------------- /test/layers/squeeze/config/config_2.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "SQUEEZE", 3 | "rows_in": 23, 4 | "cols_in": 24, 5 | "channels_in": 20, 6 | "coarse_in": 5, 7 | "coarse_out": 20, 8 | "batch_size": 1, 9 | "buffer_depth": 1, 10 | "data_width": 16, 11 | "description": "example squeeze from LeNet (deadlock detected)" 12 | } 13 | -------------------------------------------------------------------------------- /test/modules/conv/config/config_7.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "CONV", 3 | "rows": 28, 4 | "cols": 28, 5 | "channels": 2, 6 | "filters": 1, 7 | "group": 1, 8 | "fine": 1, 9 | "kernel_size": [1,1], 10 | "batch_size": 1, 11 | "description": "module name: conv, layer name: res3c_branch2c, net name: resnet.prototxt" 12 | } 13 | -------------------------------------------------------------------------------- /test/modules/conv/config/config_8.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "CONV", 3 | "rows": 56, 4 | "cols": 56, 5 | "channels": 16, 6 | "filters": 4, 7 | "group": 1, 8 | "fine": 9, 9 | "kernel_size": [3,3], 10 | "batch_size": 1, 11 | "description": "module name: conv, layer name: res2a_branch2b, net name: resnet.prototxt" 12 | } 13 | -------------------------------------------------------------------------------- /test/modules/elementwise_add/config/config_1.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "EltWiseADD", 3 | "rows": 7, 4 | "cols": 7, 5 | "channels": 64, 6 | "rows_out": 28, 7 | "cols_out": 28, 8 | "channels_out": 64, 9 | "batch_size": 1, 10 | "wordlength":16, 11 | "description": "module name: elementwise_add, layer name: , net name: " 12 | } -------------------------------------------------------------------------------- /test/modules/elementwise_mul/config/config_1.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "EltWiseMUL", 3 | "rows": 7, 4 | "cols": 7, 5 | "channels": 64, 6 | "rows_out": 28, 7 | "cols_out": 28, 8 | "channels_out": 64, 9 | "batch_size": 1, 10 | "wordlength":16, 11 | "description": "module name: elementwise_add, layer name: , net name: " 12 | } -------------------------------------------------------------------------------- /test/modules/relu/config/config_1.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "RELU", 3 | "rows": 7, 4 | "cols": 7, 5 | "channels": 64, 6 | "rows_out": 28, 7 | "cols_out": 28, 8 | "channels_out": 64, 9 | "batch_size": 1, 10 | "wordlength":16 11 | "description": "module name: relu, layer name: res3c_branch2a_relu, net name: resnet.prototxt" -------------------------------------------------------------------------------- /test/modules/sliding_window/config/config_10.json: -------------------------------------------------------------------------------- 1 | { 2 | "batch_size" : 1, 3 | "rows" : 28, 4 | "cols" : 28, 5 | "channels" : 1, 6 | "pad_top" : 0, 7 | "pad_right" : 0, 8 | "pad_bottom" : 0, 9 | "pad_left" : 0, 10 | "stride" : [1,1], 11 | "kernel_size" : [5,1], 12 | "description" : "vertical window" 13 | } 14 | -------------------------------------------------------------------------------- /test/modules/conv/config/config_9.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "CONV", 3 | "rows": 28, 4 | "cols": 28, 5 | "channels": 48, 6 | "filters": 8, 7 | "group": 1, 8 | "fine": 1, 9 | "kernel_size": [3,3], 10 | "batch_size": 1, 11 | "description": "module name: conv, layer name: inception_3a/3x3, net name: googlenet.prototxt" 12 | } 13 | -------------------------------------------------------------------------------- /test/modules/sliding_window/config/config_9.json: -------------------------------------------------------------------------------- 1 | { 2 | "batch_size" : 1, 3 | "rows" : 28, 4 | "cols" : 28, 5 | "channels" : 1, 6 | "pad_top" : 0, 7 | "pad_right" : 0, 8 | "pad_bottom" : 0, 9 | "pad_left" : 0, 10 | "stride" : [1,1], 11 | "kernel_size" : [1,5], 12 | "description" : "horizontal sliding window" 13 | } 14 | -------------------------------------------------------------------------------- /test/layers/relu/config/config_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "RELU", 3 | "rows_in": 28, 4 | "cols_in": 28, 5 | "channels_in": 64, 6 | "coarse": 4, 7 | "coarse_in": 4, 8 | "coarse_out": 4, 9 | "batch_size": 1, 10 | "data_width": 16, 11 | "description": "layer name: inception_3b/relu_pool_proj, net name: googlenet.prototxt" 12 | } 13 | -------------------------------------------------------------------------------- /test/layers/split/config/config_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "RELU", 3 | "rows_in": 28, 4 | "cols_in": 28, 5 | "channels_in": 64, 6 | "coarse": 4, 7 | "coarse_in": 4, 8 | "coarse_out": 4, 9 | "batch_size": 1, 10 | "data_width": 16, 11 | "description": "layer name: inception_3b/relu_pool_proj, net name: googlenet.prototxt" 12 | } 13 | -------------------------------------------------------------------------------- /test/modules/fork/config/config_6.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "FORK", 3 | "rows": 4, 4 | "cols": 4, 5 | "channels": 8, 6 | "coarse": 1, 7 | "kernel_size": 2, 8 | "rows_out": 14, 9 | "cols_out": 14, 10 | "channels_out": 2, 11 | "batch_size": 1, 12 | "description": "module name: fork, layer name: res4c_branch2a, net name: resnet.prototxt" 13 | } -------------------------------------------------------------------------------- /test/modules/fork/config/config_8.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "FORK", 3 | "rows": 14, 4 | "cols": 14, 5 | "channels": 1, 6 | "coarse": 512, 7 | "kernel_size": 3, 8 | "rows_out": 14, 9 | "cols_out": 14, 10 | "channels_out": 1, 11 | "batch_size": 1, 12 | "description": "module name: fork, layer name: conv5_3, net name: vgg16.prototxt" 13 | } -------------------------------------------------------------------------------- /test/layers/elementwise_add/config/config_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "ELTWISE_ADD", 3 | "rows_in": 28, 4 | "cols_in": 28, 5 | "channels_in": 64, 6 | "coarse": 4, 7 | "coarse_in": 4, 8 | "coarse_out": 4, 9 | "batch_size": 1, 10 | "data_width": 16, 11 | "description": "layer name: inception_3b/relu_pool_proj, net name: googlenet.prototxt" 12 | } 13 | -------------------------------------------------------------------------------- /test/layers/elementwise_mul/config/config_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "ELTWISE_MUL", 3 | "rows_in": 28, 4 | "cols_in": 28, 5 | "channels_in": 64, 6 | "coarse": 4, 7 | "coarse_in": 4, 8 | "coarse_out": 4, 9 | "batch_size": 1, 10 | "data_width": 16, 11 | "description": "layer name: inception_3b/relu_pool_proj, net name: googlenet.prototxt" 12 | } 13 | -------------------------------------------------------------------------------- /test/modules/fork/config/config_1.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "FORK", 3 | "rows": 64, 4 | "cols": 64, 5 | "channels": 128, 6 | "coarse": 1, 7 | "kernel_size": 2, 8 | "rows_out": 14, 9 | "cols_out": 14, 10 | "channels_out": 2, 11 | "batch_size": 1, 12 | "description": "module name: fork, layer name: res4c_branch2a, net name: resnet.prototxt" 13 | } -------------------------------------------------------------------------------- /test/modules/fork/config/config_2.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "FORK", 3 | "rows": 64, 4 | "cols": 64, 5 | "channels": 128, 6 | "coarse": 1, 7 | "kernel_size": 3, 8 | "rows_out": 14, 9 | "cols_out": 14, 10 | "channels_out": 2, 11 | "batch_size": 1, 12 | "description": "module name: fork, layer name: res4c_branch2a, net name: resnet.prototxt" 13 | } -------------------------------------------------------------------------------- /test/modules/fork/config/config_3.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "FORK", 3 | "rows": 64, 4 | "cols": 64, 5 | "channels": 128, 6 | "coarse": 2, 7 | "kernel_size": 1, 8 | "rows_out": 14, 9 | "cols_out": 14, 10 | "channels_out": 2, 11 | "batch_size": 1, 12 | "description": "module name: fork, layer name: res4c_branch2a, net name: resnet.prototxt" 13 | } -------------------------------------------------------------------------------- /test/modules/fork/config/config_4.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "FORK", 3 | "rows": 64, 4 | "cols": 64, 5 | "channels": 128, 6 | "coarse": 2, 7 | "kernel_size": 2, 8 | "rows_out": 14, 9 | "cols_out": 14, 10 | "channels_out": 2, 11 | "batch_size": 1, 12 | "description": "module name: fork, layer name: res4c_branch2a, net name: resnet.prototxt" 13 | } -------------------------------------------------------------------------------- /test/modules/fork/config/config_5.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "FORK", 3 | "rows": 64, 4 | "cols": 64, 5 | "channels": 128, 6 | "coarse": 2, 7 | "kernel_size": 3, 8 | "rows_out": 14, 9 | "cols_out": 14, 10 | "channels_out": 2, 11 | "batch_size": 1, 12 | "description": "module name: fork, layer name: res4c_branch2a, net name: resnet.prototxt" 13 | } -------------------------------------------------------------------------------- /test/modules/fork/config/config_7.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "FORK", 3 | "rows": 14, 4 | "cols": 14, 5 | "channels": 4, 6 | "coarse": 128, 7 | "kernel_size": 3, 8 | "rows_out": 14, 9 | "cols_out": 14, 10 | "channels_out": 4, 11 | "batch_size": 1, 12 | "description": "module name: fork, layer name: res4c_branch2b, net name: resnet.prototxt" 13 | } -------------------------------------------------------------------------------- /test/modules/fork/config/config_9.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "FORK", 3 | "rows": 28, 4 | "cols": 28, 5 | "channels": 2, 6 | "coarse": 128, 7 | "kernel_size": 1, 8 | "rows_out": 28, 9 | "cols_out": 28, 10 | "channels_out": 2, 11 | "batch_size": 1, 12 | "description": "module name: fork, layer name: res3a_branch1, net name: resnet.prototxt" 13 | } -------------------------------------------------------------------------------- /test/modules/sliding_window/config/config_4.json: -------------------------------------------------------------------------------- 1 | { 2 | "batch_size" : 1, 3 | "rows" : 8, 4 | "cols" : 8, 5 | "channels" : 20, 6 | "pad_top" : 0, 7 | "pad_right" : 0, 8 | "pad_bottom" : 0, 9 | "pad_left" : 0, 10 | "stride" : [2,2], 11 | "kernel_size" : [2,2], 12 | "description" : "lenet (pool2)" 13 | } 14 | -------------------------------------------------------------------------------- /test/layers/pooling/config/config_10.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "POOLING", 3 | "rows": 20, 4 | "cols": 20, 5 | "channels": 5, 6 | "kernel_size": 2, 7 | "stride": 2, 8 | "pad": 0, 9 | "coarse": 1, 10 | "coarse_in": 1, 11 | "coarse_out": 1, 12 | "fine": 4, 13 | "pool_type": "max", 14 | "batch_size": 1, 15 | "description": "a" 16 | } 17 | -------------------------------------------------------------------------------- /test/layers/relu/tb/relu_layer_tb.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RELU_LAYER_TB_HPP_ 2 | #define RELU_LAYER_TB_HPP_ 3 | 4 | #include "common.hpp" 5 | #include "relu_layer.hpp" 6 | #include "relu_layer_param.hpp" 7 | 8 | void relu_layer_top( 9 | stream_t(relu_layer_data_t) in[RELU_LAYER_COARSE], 10 | stream_t(relu_layer_data_t) out[RELU_LAYER_COARSE], 11 | int mode 12 | ); 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /test/layers/squeeze/config/config_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "SQUEEZE", 3 | "rows_in": 12, 4 | "cols_in": 12, 5 | "channels_in": 1024, 6 | "coarse_in": 64, 7 | "coarse_out": 8, 8 | "batch_size": 1, 9 | "buffer_depth": 10, 10 | "data_width": 16, 11 | "description": "module name: fork, layer name: res4f_branch2a, net name: resnet.prototxt" 12 | } 13 | -------------------------------------------------------------------------------- /test/modules/sliding_window/config/config_1.json: -------------------------------------------------------------------------------- 1 | { 2 | "batch_size" : 1, 3 | "rows" : 28, 4 | "cols" : 28, 5 | "channels" : 20, 6 | "pad_top" : 0, 7 | "pad_right" : 0, 8 | "pad_bottom" : 0, 9 | "pad_left" : 0, 10 | "stride" : [2,2], 11 | "kernel_size" : [2,2], 12 | "description" : "lenet (pool1)" 13 | } 14 | -------------------------------------------------------------------------------- /test/modules/sliding_window/config/config_2.json: -------------------------------------------------------------------------------- 1 | { 2 | "batch_size" : 1, 3 | "rows" : 224, 4 | "cols" : 224, 5 | "channels" : 3, 6 | "pad_top" : 3, 7 | "pad_right" : 3, 8 | "pad_bottom" : 3, 9 | "pad_left" : 3, 10 | "stride" : [2,2], 11 | "kernel_size" : [7,7], 12 | "description" : "resnet (conv1)" 13 | } 14 | -------------------------------------------------------------------------------- /test/modules/sliding_window/config/config_3.json: -------------------------------------------------------------------------------- 1 | { 2 | "batch_size" : 1, 3 | "rows" : 55, 4 | "cols" : 55, 5 | "channels" : 8, 6 | "pad_top" : 0, 7 | "pad_right" : 0, 8 | "pad_bottom" : 0, 9 | "pad_left" : 0, 10 | "stride" : [2,2], 11 | "kernel_size" : [3,3], 12 | "description" : "alexnet (pool1)" 13 | } 14 | -------------------------------------------------------------------------------- /test/modules/relu/tb/relu_tb.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RELU_TB_HPP_ 2 | #define RELU_TB_HPP_ 3 | 4 | #include "common.hpp" 5 | #include "relu_param.hpp" 6 | 7 | // define the type based on the test configuration 8 | typedef ap_fixed relu_t; 9 | 10 | void relu_top( 11 | stream_t(relu_t) &in, 12 | stream_t(relu_t) &out 13 | ); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /test/modules/sliding_window/config/config_5.json: -------------------------------------------------------------------------------- 1 | { 2 | "batch_size" : 1, 3 | "rows" : 227, 4 | "cols" : 227, 5 | "channels" : 3, 6 | "pad_top" : 0, 7 | "pad_right" : 0, 8 | "pad_bottom" : 0, 9 | "pad_left" : 0, 10 | "stride" : [4,4], 11 | "kernel_size" : [11,11], 12 | "description" : "alexnet (conv1)" 13 | } 14 | -------------------------------------------------------------------------------- /test/modules/sliding_window/config/config_6.json: -------------------------------------------------------------------------------- 1 | { 2 | "batch_size" : 1, 3 | "rows" : 56, 4 | "cols" : 56, 5 | "channels" : 64, 6 | "pad_top" : 1, 7 | "pad_right" : 1, 8 | "pad_bottom" : 1, 9 | "pad_left" : 1, 10 | "stride" : [1,1], 11 | "kernel_size" : [3,3], 12 | "description" : "resnet (first branch)" 13 | } 14 | -------------------------------------------------------------------------------- /test/layers/pooling/config/config_11.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "POOLING", 3 | "rows": 56, 4 | "cols": 56, 5 | "channels": 192, 6 | "kernel_size": 3, 7 | "stride": 2, 8 | "pad": 0, 9 | "coarse": 1, 10 | "coarse_in": 1, 11 | "coarse_out": 1, 12 | "fine": 9, 13 | "pool_type": "max", 14 | "batch_size": 1, 15 | "description": "pool2_3x3_s2" 16 | } 17 | -------------------------------------------------------------------------------- /test/layers/pooling/config/config_12.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "POOLING", 3 | "rows": 28, 4 | "cols": 28, 5 | "channels": 192, 6 | "kernel_size": 3, 7 | "stride": 1, 8 | "pad": 1, 9 | "coarse": 1, 10 | "coarse_in": 1, 11 | "coarse_out": 1, 12 | "fine": 9, 13 | "pool_type": "max", 14 | "batch_size": 1, 15 | "description": "googlenet: pool" 16 | } 17 | -------------------------------------------------------------------------------- /test/modules/accum/tb/accum_tb.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ACCUM_TB_HPP_ 2 | #define ACCUM_TB_HPP_ 3 | 4 | #include "common.hpp" 5 | #include "accum_param.hpp" 6 | 7 | // define the type based on the test configuration 8 | typedef ap_fixed test_accum_t; 9 | 10 | void accum_top( 11 | stream_t(test_accum_t) &in, 12 | stream_t(test_accum_t) &out 13 | ); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /test/modules/glue/config/config_4.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "GLUE", 3 | "rows": 7, 4 | "cols": 7, 5 | "channels": 512, 6 | "filters": 512, 7 | "coarse_in": 1, 8 | "coarse_out": 1, 9 | "rows_out": 7, 10 | "cols_out": 7, 11 | "channels_out": 512, 12 | "batch_size": 1, 13 | "description": "module name: glue, layer name: res5a_branch2b, net name: resnet.prototxt" 14 | } -------------------------------------------------------------------------------- /test/modules/glue/config/config_5.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "GLUE", 3 | "rows": 112, 4 | "cols": 112, 5 | "channels": 128, 6 | "filters": 128, 7 | "coarse_in": 1, 8 | "coarse_out": 1, 9 | "rows_out": 112, 10 | "cols_out": 112, 11 | "channels_out": 128, 12 | "batch_size": 1, 13 | "description": "module name: glue, layer name: conv2_2, net name: vgg16.prototxt" 14 | } -------------------------------------------------------------------------------- /test/modules/relu/src/relu.cpp: -------------------------------------------------------------------------------- 1 | #include "relu_tb.hpp" 2 | #include "relu.hpp" 3 | 4 | void relu_top( 5 | stream_t(relu_t) &in, 6 | stream_t(relu_t) &out 7 | ) 8 | { 9 | 10 | #pragma HLS DATAFLOW 11 | 12 | // DUT 13 | relu< 14 | RELU_BATCH_SIZE, 15 | RELU_ROWS, 16 | RELU_COLS, 17 | RELU_CHANNELS, 18 | relu_t 19 | >(in,out); 20 | 21 | } 22 | -------------------------------------------------------------------------------- /test/modules/glue/config/config_2.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "GLUE", 3 | "rows": 7, 4 | "cols": 7, 5 | "channels": 512, 6 | "filters": 512, 7 | "coarse_in": 1, 8 | "coarse_out": 1, 9 | "rows_out": 7, 10 | "cols_out": 7, 11 | "channels_out": 512, 12 | "batch_size": 1, 13 | "description": "module name: glue, layer name: res5c_branch2b, net name: resnet.prototxt" 14 | } 15 | -------------------------------------------------------------------------------- /test/modules/glue/config/config_3.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "GLUE", 3 | "rows": 14, 4 | "cols": 14, 5 | "channels": 256, 6 | "filters": 256, 7 | "coarse_in": 1, 8 | "coarse_out": 1, 9 | "rows_out": 14, 10 | "cols_out": 14, 11 | "channels_out": 256, 12 | "batch_size": 1, 13 | "description": "module name: glue, layer name: res4f_branch2b, net name: resnet.prototxt" 14 | } -------------------------------------------------------------------------------- /test/modules/glue/config/config_6.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "GLUE", 3 | "rows": 28, 4 | "cols": 28, 5 | "channels": 128, 6 | "filters": 128, 7 | "coarse_in": 1, 8 | "coarse_out": 1, 9 | "rows_out": 28, 10 | "cols_out": 28, 11 | "channels_out": 128, 12 | "batch_size": 1, 13 | "description": "module name: glue, layer name: res3a_branch2b, net name: resnet.prototxt" 14 | } -------------------------------------------------------------------------------- /test/modules/glue/config/config_8.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "GLUE", 3 | "rows": 56, 4 | "cols": 56, 5 | "channels": 256, 6 | "filters": 256, 7 | "coarse_in": 1, 8 | "coarse_out": 1, 9 | "rows_out": 56, 10 | "cols_out": 56, 11 | "channels_out": 256, 12 | "batch_size": 1, 13 | "description": "module name: glue, layer name: res2c_branch2c, net name: resnet.prototxt" 14 | } -------------------------------------------------------------------------------- /test/layers/batch_norm/tb/batch_norm_layer_tb.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BATCH_NORM_LAYER_TB_HPP_ 2 | #define BATCH_NORM_LAYER_TB_HPP_ 3 | 4 | #include "common.hpp" 5 | #include "batch_norm_layer.hpp" 6 | #include "batch_norm_layer_param.hpp" 7 | 8 | void batch_norm_layer_top( 9 | stream_t(data_t) in[BATCH_NORM_LAYER_COARSE], 10 | stream_t(data_t) out[BATCH_NORM_LAYER_COARSE], 11 | int mode 12 | ); 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /test/layers/pooling/tb/pooling_layer_tb.hpp: -------------------------------------------------------------------------------- 1 | #ifndef POOLING_LAYER_TB_HPP_ 2 | #define POOLING_LAYER_TB_HPP_ 3 | 4 | #include "common.hpp" 5 | #include "pooling_layer.hpp" 6 | #include "pooling_layer_param.hpp" 7 | 8 | void pooling_layer_top( 9 | stream_t(pooling_layer_data_t) in[POOLING_LAYER_COARSE], 10 | stream_t(pooling_layer_data_t) out[POOLING_LAYER_COARSE], 11 | int mode 12 | ); 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /test/modules/sliding_window/config/config_7.json: -------------------------------------------------------------------------------- 1 | { 2 | "batch_size" : 1, 3 | "rows" : 56, 4 | "cols" : 56, 5 | "channels" : 2, 6 | "pad_top" : 1, 7 | "pad_right" : 1, 8 | "pad_bottom" : 0, 9 | "pad_left" : 0, 10 | "stride" : [2,2], 11 | "kernel_size" : [3,3], 12 | "description" : "googlenet: pool_3x3_s2 sliding window module" 13 | } 14 | -------------------------------------------------------------------------------- /test/modules/clean_reports.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | function clean_prj { 4 | if [ $1 ]; then 5 | rm ${1}/rpt/* 6 | rm -rf ${1}/data/* 7 | rm -rf ${1}/${1}_hls_prj/* 8 | rm -rf ${1}/${1}_test_prj/* 9 | fi 10 | } 11 | 12 | clean_prj accum 13 | clean_prj conv 14 | clean_prj fork 15 | clean_prj glue 16 | clean_prj split 17 | clean_prj relu 18 | clean_prj sliding_window 19 | 20 | -------------------------------------------------------------------------------- /test/layers/squeeze/tb/squeeze_layer_tb.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SQUEEZE_LAYER_TB_HPP_ 2 | #define SQUEEZE_LAYER_TB_HPP_ 3 | 4 | #include "common.hpp" 5 | #include "squeeze_layer.hpp" 6 | #include "squeeze_layer_param.hpp" 7 | 8 | void squeeze_layer_top( 9 | stream_t(squeeze_layer_data_t) in[SQUEEZE_LAYER_COARSE_IN], 10 | stream_t(squeeze_layer_data_t) out[SQUEEZE_LAYER_COARSE_OUT], 11 | int mode 12 | ); 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /test/modules/conv/config/config_12.json: -------------------------------------------------------------------------------- 1 | { 2 | "rows": 28, 3 | "cols": 28, 4 | "channels": 1, 5 | "filters": 1, 6 | "kernel_size": [5,5], 7 | "groups": 1, 8 | "fine": 25, 9 | "batch_size": 1, 10 | "input_width": 16, 11 | "data_width": 16, 12 | "acc_width": 16, 13 | "weight_width": 16, 14 | "description": "layer name: conv1, net name: brchy lenet bb, NO BIAS" 15 | } 16 | 17 | -------------------------------------------------------------------------------- /test/modules/glue/config/config_1.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "GLUE", 3 | "rows": 8, 4 | "cols": 8, 5 | "channels": 50, 6 | "filters": 50, 7 | "coarse_in": 1, 8 | "coarse_out": 1, 9 | "rows_out": 8, 10 | "cols_out": 8, 11 | "channels_out": 50, 12 | "batch_size": 1, 13 | "datawordlength":8 14 | "description": "module name: glue, layer name: conv2, net name: lenet.prototxt" 15 | } 16 | -------------------------------------------------------------------------------- /test/modules/glue/config/config_9.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "GLUE", 3 | "rows": 28, 4 | "cols": 28, 5 | "channels": 96, 6 | "filters": 96, 7 | "coarse_in": 96, 8 | "coarse_out": 96, 9 | "rows_out": 28, 10 | "cols_out": 28, 11 | "channels_out": 96, 12 | "batch_size": 1, 13 | "description": "module name: glue, layer name: inception_3a/3x3_reduce, net name: googlenet.prototxt" 14 | } 15 | -------------------------------------------------------------------------------- /test/layers/relu/config/config_6.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "RELU", 3 | "rows": 28, 4 | "cols": 28, 5 | "channels": 512, 6 | "coarse": 8, 7 | "coarse_in": 8, 8 | "coarse_out": 8, 9 | "size_in": 401408, 10 | "size_out": 401408, 11 | "rows_out": 28, 12 | "cols_out": 28, 13 | "channels_out": 512, 14 | "batch_size": 1, 15 | "description": "layer name: relu4_2, net name: vgg16.prototxt" 16 | } -------------------------------------------------------------------------------- /test/modules/pool/tb/pool_tb.hpp: -------------------------------------------------------------------------------- 1 | #ifndef POOL_TB_HPP_ 2 | #define POOL_TB_HPP_ 3 | 4 | #include "common.hpp" 5 | #include "pool_param.hpp" 6 | 7 | // define the type based on the test configuration 8 | typedef ap_fixed pool_t; 9 | 10 | void pool_top( 11 | stream_t(pool_t) in[POOL_KERNEL_SIZE_0][POOL_KERNEL_SIZE_1], 12 | stream_t(pool_t) &out 13 | ); 14 | 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /test/layers/relu/config/config_7.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "RELU", 3 | "rows": 7, 4 | "cols": 7, 5 | "channels": 2048, 6 | "coarse": 64, 7 | "coarse_in": 64, 8 | "coarse_out": 64, 9 | "size_in": 100352, 10 | "size_out": 100352, 11 | "rows_out": 7, 12 | "cols_out": 7, 13 | "channels_out": 2048, 14 | "batch_size": 1, 15 | "description": "layer name: res5c_relu, net name: resnet.prototxt" 16 | } -------------------------------------------------------------------------------- /test/layers/relu/config/config_9.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "RELU", 3 | "rows": 56, 4 | "cols": 56, 5 | "channels": 256, 6 | "coarse": 128, 7 | "coarse_in": 128, 8 | "coarse_out": 128, 9 | "size_in": 802816, 10 | "size_out": 802816, 11 | "rows_out": 56, 12 | "cols_out": 56, 13 | "channels_out": 256, 14 | "batch_size": 1, 15 | "description": "layer name: relu3_3, net name: vgg16.prototxt" 16 | } -------------------------------------------------------------------------------- /test/layers/relu/config/config_2.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "RELU", 3 | "rows": 56, 4 | "cols": 56, 5 | "channels": 64, 6 | "coarse": 2, 7 | "coarse_in": 2, 8 | "coarse_out": 2, 9 | "size_in": 200704, 10 | "size_out": 200704, 11 | "rows_out": 56, 12 | "cols_out": 56, 13 | "channels_out": 64, 14 | "batch_size": 1, 15 | "description": "layer name: res2c_branch2a_relu, net name: resnet.prototxt" 16 | } -------------------------------------------------------------------------------- /test/layers/relu/config/config_3.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "RELU", 3 | "rows": 7, 4 | "cols": 7, 5 | "channels": 512, 6 | "coarse": 32, 7 | "coarse_in": 32, 8 | "coarse_out": 32, 9 | "size_in": 25088, 10 | "size_out": 25088, 11 | "rows_out": 7, 12 | "cols_out": 7, 13 | "channels_out": 512, 14 | "batch_size": 1, 15 | "description": "layer name: res5b_branch2a_relu, net name: resnet.prototxt" 16 | } -------------------------------------------------------------------------------- /test/layers/relu/config/config_8.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "RELU", 3 | "rows": 14, 4 | "cols": 14, 5 | "channels": 256, 6 | "coarse": 4, 7 | "coarse_in": 4, 8 | "coarse_out": 4, 9 | "size_in": 50176, 10 | "size_out": 50176, 11 | "rows_out": 14, 12 | "cols_out": 14, 13 | "channels_out": 256, 14 | "batch_size": 1, 15 | "description": "layer name: res4d_branch2a_relu, net name: resnet.prototxt" 16 | } -------------------------------------------------------------------------------- /test/layers/avg_pooling/tb/avg_pooling_layer_tb.hpp: -------------------------------------------------------------------------------- 1 | #ifndef AVG_POOLING_LAYER_TB_HPP 2 | #define AVG_POOLING_LAYER_TB_HPP 3 | 4 | #include "common.hpp" 5 | #include "avg_pooling_layer.hpp" 6 | #include "avg_pooling_layer_param.hpp" 7 | 8 | void avg_pooling_layer_top( 9 | stream_t(avg_pooling_layer_data_t) in[AVG_POOLING_LAYER_COARSE], 10 | stream_t(avg_pooling_layer_data_t) out[AVG_POOLING_LAYER_COARSE], 11 | int mode 12 | ); 13 | 14 | #endif -------------------------------------------------------------------------------- /test/layers/relu/config/config_5.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "RELU", 3 | "rows": 14, 4 | "cols": 14, 5 | "channels": 1024, 6 | "coarse": 256, 7 | "coarse_in": 256, 8 | "coarse_out": 256, 9 | "size_in": 200704, 10 | "size_out": 200704, 11 | "rows_out": 14, 12 | "cols_out": 14, 13 | "channels_out": 1024, 14 | "batch_size": 1, 15 | "description": "layer name: res4b_relu, net name: resnet.prototxt" 16 | } -------------------------------------------------------------------------------- /test/layers/inner_product/config/config_10.json: -------------------------------------------------------------------------------- 1 | { 2 | "buffer_depth": 1, 3 | "rows_in": 1, 4 | "cols_in": 1, 5 | "channels_in": 32, 6 | "filters": 32, 7 | "coarse_in": 1, 8 | "coarse_out": 32, 9 | "fine": 1, 10 | "batch_size": 1, 11 | "input_width": 16, 12 | "acc_width": 30, 13 | "weight_width": 8, 14 | "output_width": 16, 15 | "description": "layer name: ip2, net name: lenet.prototxt" 16 | } 17 | -------------------------------------------------------------------------------- /test/layers/relu/config/config_1.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "RELU", 3 | "rows_in": 28, 4 | "cols_in": 28, 5 | "channels_in": 512, 6 | "coarse": 2, 7 | "coarse_in": 2, 8 | "coarse_out": 2, 9 | "size_in": 401408, 10 | "size_out": 401408, 11 | "rows_out": 28, 12 | "cols_out": 28, 13 | "channels_out": 512, 14 | "batch_size": 1, 15 | "description": "layer name: res3a_relu, net name: resnet.prototxt" 16 | } 17 | -------------------------------------------------------------------------------- /test/layers/relu/config/config_4.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "RELU", 3 | "rows": 28, 4 | "cols": 28, 5 | "channels": 64, 6 | "coarse": 64, 7 | "coarse_in": 64, 8 | "coarse_out": 64, 9 | "size_in": 50176, 10 | "size_out": 50176, 11 | "rows_out": 28, 12 | "cols_out": 28, 13 | "channels_out": 64, 14 | "batch_size": 1, 15 | "description": "layer name: inception_3a/relu_1x1, net name: googlenet.prototxt" 16 | } -------------------------------------------------------------------------------- /test/layers/split/tb/split_layer_tb.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SPLIT_LAYER_TB_HPP_ 2 | #define SPLIT_LAYER_TB_HPP_ 3 | 4 | #include "common.hpp" 5 | #include "split_layer.hpp" 6 | #include "split_layer_param.hpp" 7 | 8 | void split_layer_top( 9 | stream_t(split_layer_data_t) in[SPLIT_LAYER_COARSE], 10 | stream_t(split_layer_data_t) out_1[SPLIT_LAYER_COARSE], 11 | stream_t(split_layer_data_t) out_2[SPLIT_LAYER_COARSE], 12 | int mode 13 | ); 14 | 15 | #endif -------------------------------------------------------------------------------- /test/layers/inner_product/config/config_8.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "CONVOLUTION", 3 | "rows": 1, 4 | "cols": 1, 5 | "channels": 4096, 6 | "filters": 5, 7 | "coarse_in": 1024, 8 | "coarse_out": 1, 9 | "fine": 1, 10 | "size_in": 4096, 11 | "size_out": 5, 12 | "rows_out": 1, 13 | "cols_out": 1, 14 | "channels_out": 5, 15 | "batch_size": 1, 16 | "description": "layer name: fc8, net name: vgg16.prototxt" 17 | } -------------------------------------------------------------------------------- /test/layers/pooling/config/config_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "POOLING", 3 | "rows_in": 56, 4 | "cols_in": 56, 5 | "channels_in": 32, 6 | "kernel_size": 2, 7 | "stride": 2, 8 | "pad": 0, 9 | "coarse": 1, 10 | "coarse_in": 1, 11 | "coarse_out": 1, 12 | "fine": 1, 13 | "pool_type": "max", 14 | "batch_size": 1, 15 | "data_width": 16, 16 | "description": "layer name: pool1, net name: resnet.prototxt" 17 | } 18 | -------------------------------------------------------------------------------- /test/layers/inner_product/config/config_4.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "CONVOLUTION", 3 | "rows": 1, 4 | "cols": 1, 5 | "channels": 4096, 6 | "filters": 5, 7 | "coarse_in": 1, 8 | "coarse_out": 5, 9 | "fine": 1, 10 | "size_in": 4096, 11 | "size_out": 5, 12 | "rows_out": 1, 13 | "cols_out": 1, 14 | "channels_out": 5, 15 | "batch_size": 1, 16 | "description": "layer name: fc8_sbt, net name: alexnet.prototxt" 17 | } -------------------------------------------------------------------------------- /test/layers/inner_product/config/config_7.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "CONVOLUTION", 3 | "rows": 1, 4 | "cols": 1, 5 | "channels": 4096, 6 | "filters": 4096, 7 | "coarse_in": 4, 8 | "coarse_out": 16, 9 | "fine": 1, 10 | "size_in": 4096, 11 | "size_out": 4096, 12 | "rows_out": 1, 13 | "cols_out": 1, 14 | "channels_out": 4096, 15 | "batch_size": 1, 16 | "description": "layer name: fc7, net name: vgg16.prototxt" 17 | } -------------------------------------------------------------------------------- /test/modules/global_pool/src/global_pool.cpp: -------------------------------------------------------------------------------- 1 | #include "global_pool_tb.hpp" 2 | #include "global_pool.hpp" 3 | 4 | void global_pool_top( 5 | stream_t(global_pool_t) &in, 6 | stream_t(global_pool_t) &out 7 | ) 8 | { 9 | #pragma HLS DATAFLOW 10 | 11 | global_pool< 12 | GLOBAL_POOL_BATCH_SIZE, 13 | GLOBAL_POOL_ROWS, 14 | GLOBAL_POOL_COLS, 15 | GLOBAL_POOL_CHANNELS, 16 | global_pool_t 17 | >(in,out); 18 | 19 | } -------------------------------------------------------------------------------- /test/modules/squeeze/tb/squeeze_tb.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SQUEEZE_TB_HPP_ 2 | #define SQUEEZE_TB_HPP_ 3 | 4 | #include "common.hpp" 5 | #include "squeeze_param.hpp" 6 | 7 | // define the type based on the test configuration 8 | typedef ap_fixed squeeze_t; 9 | 10 | void squeeze_top( 11 | stream_t(squeeze_t) in[SQUEEZE_COARSE_IN], 12 | stream_t(squeeze_t) out[SQUEEZE_COARSE_OUT] 13 | ); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /test/layers/avg_pooling/config/config_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "AVG_POOLING", 3 | "rows_in": 56, 4 | "cols_in": 56, 5 | "channels_in": 32, 6 | "kernel_size": 2, 7 | "stride": 2, 8 | "pad": 0, 9 | "coarse": 1, 10 | "coarse_in": 1, 11 | "coarse_out": 1, 12 | "fine": 1, 13 | "pool_type": "avg", 14 | "batch_size": 1, 15 | "data_width": 16, 16 | "description": "layer name: pool1, net name: resnet.prototxt" 17 | } 18 | -------------------------------------------------------------------------------- /test/layers/inner_product/config/config_2.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "CONVOLUTION", 3 | "rows": 6, 4 | "cols": 6, 5 | "channels": 256, 6 | "filters": 4096, 7 | "coarse_in": 2, 8 | "coarse_out": 64, 9 | "fine": 2, 10 | "size_in": 9216, 11 | "size_out": 4096, 12 | "rows_out": 1, 13 | "cols_out": 1, 14 | "channels_out": 4096, 15 | "batch_size": 1, 16 | "description": "layer name: fc6, net name: alexnet.prototxt" 17 | } -------------------------------------------------------------------------------- /test/layers/inner_product/config/config_3.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "CONVOLUTION", 3 | "rows": 1, 4 | "cols": 1, 5 | "channels": 4096, 6 | "filters": 4096, 7 | "coarse_in": 2, 8 | "coarse_out": 512, 9 | "fine": 1, 10 | "size_in": 4096, 11 | "size_out": 4096, 12 | "rows_out": 1, 13 | "cols_out": 1, 14 | "channels_out": 4096, 15 | "batch_size": 1, 16 | "description": "layer name: fc7, net name: alexnet.prototxt" 17 | } -------------------------------------------------------------------------------- /test/layers/inner_product/config/config_5.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "CONVOLUTION", 3 | "rows": 1, 4 | "cols": 1, 5 | "channels": 2048, 6 | "filters": 1000, 7 | "coarse_in": 4, 8 | "coarse_out": 200, 9 | "fine": 1, 10 | "size_in": 2048, 11 | "size_out": 1000, 12 | "rows_out": 1, 13 | "cols_out": 1, 14 | "channels_out": 1000, 15 | "batch_size": 1, 16 | "description": "layer name: fc1000, net name: resnet.prototxt" 17 | } -------------------------------------------------------------------------------- /test/layers/inner_product/config/config_6.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "CONVOLUTION", 3 | "rows": 7, 4 | "cols": 7, 5 | "channels": 512, 6 | "filters": 4096, 7 | "coarse_in": 4, 8 | "coarse_out": 256, 9 | "fine": 49, 10 | "size_in": 25088, 11 | "size_out": 4096, 12 | "rows_out": 1, 13 | "cols_out": 1, 14 | "channels_out": 4096, 15 | "batch_size": 1, 16 | "description": "layer name: fc6, net name: vgg16.prototxt" 17 | } -------------------------------------------------------------------------------- /test/layers/inner_product/config/config_9.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "CONVOLUTION", 3 | "rows": 6, 4 | "cols": 6, 5 | "channels": 256, 6 | "filters": 4096, 7 | "coarse_in": 16, 8 | "coarse_out": 4, 9 | "fine": 1, 10 | "size_in": 9216, 11 | "size_out": 4096, 12 | "rows_out": 1, 13 | "cols_out": 1, 14 | "channels_out": 4096, 15 | "batch_size": 1, 16 | "description": "layer name: fc6, net name: alexnet.prototxt" 17 | } -------------------------------------------------------------------------------- /test/modules/global_pool/tb/global_pool_tb.hpp: -------------------------------------------------------------------------------- 1 | #ifndef GLOBAL_POOL_TB_HPP_ 2 | #define GLOBAL_POOL_TB_HPP_ 3 | 4 | #include "common.hpp" 5 | #include "global_pool_param.hpp" 6 | 7 | // define the type based on the test configuration 8 | typedef ap_fixed global_pool_t; 9 | 10 | void global_pool_top( 11 | stream_t(global_pool_t) &in, 12 | stream_t(global_pool_t) &out 13 | ); 14 | 15 | #endif -------------------------------------------------------------------------------- /test/modules/bias/src/bias.cpp: -------------------------------------------------------------------------------- 1 | #include "bias_tb.hpp" 2 | #include "bias.hpp" 3 | 4 | void bias_top( 5 | stream_t(bias_data_t) &in, 6 | bias_biases_t biases[BIAS_FILTERS], 7 | stream_t(bias_data_t) &out 8 | ) 9 | { 10 | 11 | #pragma HLS DATAFLOW 12 | 13 | bias< 14 | BIAS_BATCH_SIZE, 15 | BIAS_ROWS, 16 | BIAS_COLS, 17 | BIAS_FILTERS, 18 | bias_data_t, 19 | bias_biases_t 20 | >(in,biases,out); 21 | } 22 | -------------------------------------------------------------------------------- /test/modules/avg_pool/tb/avg_pool_tb.hpp: -------------------------------------------------------------------------------- 1 | #ifndef AVG_POOL_TB_HPP_ 2 | #define AVG_POOL_TB_HPP_ 3 | 4 | #include "common.hpp" 5 | #include "avg_pool_param.hpp" 6 | 7 | // define the type based on the test configuration 8 | typedef ap_fixed avg_pool_t; 9 | 10 | void avg_pool_top( 11 | stream_t(avg_pool_t) in[AVG_POOL_KERNEL_SIZE_0][AVG_POOL_KERNEL_SIZE_1], 12 | stream_t(avg_pool_t) &out 13 | ); 14 | 15 | #endif -------------------------------------------------------------------------------- /test/layers/batch_norm/config/config_3.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "BATCH NORM", 3 | "buffer_depth" : 0, 4 | "rows": 7, 5 | "cols": 7, 6 | "channels": 512, 7 | "coarse": 2, 8 | "coarse_in": 2, 9 | "coarse_out": 2, 10 | "size_in": 25088, 11 | "size_out": 25088, 12 | "rows_out": 7, 13 | "cols_out": 7, 14 | "channels_out": 512, 15 | "batch_size": 1, 16 | "description": "layer name: bn5a_branch2b, net name: resnet.prototxt" 17 | } 18 | -------------------------------------------------------------------------------- /test/layers/batch_norm/config/config_4.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "BATCH NORM", 3 | "buffer_depth" : 0, 4 | "rows": 7, 5 | "cols": 7, 6 | "channels": 512, 7 | "coarse": 4, 8 | "coarse_in": 4, 9 | "coarse_out": 4, 10 | "size_in": 25088, 11 | "size_out": 25088, 12 | "rows_out": 7, 13 | "cols_out": 7, 14 | "channels_out": 512, 15 | "batch_size": 1, 16 | "description": "layer name: bn5c_branch2b, net name: resnet.prototxt" 17 | } 18 | -------------------------------------------------------------------------------- /test/layers/global_pooling/tb/global_pooling_layer_tb.hpp: -------------------------------------------------------------------------------- 1 | #ifndef GLOBAL_POOLING_LAYER_TB_HPP 2 | #define GLOBAL_POOLING_LAYER_TB_HPP 3 | 4 | #include "common.hpp" 5 | #include "global_pooling_layer.hpp" 6 | #include "global_pooling_layer_param.hpp" 7 | 8 | void global_pooling_layer_top( 9 | stream_t(global_pooling_layer_data_t) in[GLOBAL_POOLING_LAYER_COARSE], 10 | stream_t(global_pooling_layer_data_t) out[GLOBAL_POOLING_LAYER_COARSE], 11 | int mode 12 | ); 13 | 14 | #endif -------------------------------------------------------------------------------- /test/modules/bias/tb/bias_tb.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BIAS_TB_HPP_ 2 | #define BIAS_TB_HPP_ 3 | 4 | #include "common.hpp" 5 | #include "bias_param.hpp" 6 | 7 | typedef ap_fixed bias_data_t; 8 | typedef ap_fixed bias_biases_t; 9 | 10 | void bias_top( 11 | stream_t(bias_data_t) &in, 12 | bias_biases_t biases[BIAS_FILTERS], 13 | stream_t(bias_data_t) &out 14 | ); 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /test/modules/pool/src/pool.cpp: -------------------------------------------------------------------------------- 1 | #include "pool_tb.hpp" 2 | #include "pool.hpp" 3 | 4 | void pool_top( 5 | stream_t(pool_t) in[POOL_KERNEL_SIZE_0][POOL_KERNEL_SIZE_1], 6 | stream_t(pool_t) &out 7 | ) 8 | { 9 | 10 | #pragma HLS DATAFLOW 11 | 12 | pool< 13 | POOL_BATCH_SIZE, 14 | POOL_ROWS, 15 | POOL_COLS, 16 | POOL_CHANNELS, 17 | POOL_KERNEL_SIZE_0, 18 | POOL_KERNEL_SIZE_1, 19 | pool_t 20 | >(in,out); 21 | 22 | } 23 | -------------------------------------------------------------------------------- /test/layers/batch_norm/config/config_2.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "BATCH NORM", 3 | "buffer_depth" : 0, 4 | "rows": 28, 5 | "cols": 28, 6 | "channels": 512, 7 | "coarse": 1, 8 | "coarse_in": 1, 9 | "coarse_out": 1, 10 | "size_in": 401408, 11 | "size_out": 401408, 12 | "rows_out": 28, 13 | "cols_out": 28, 14 | "channels_out": 512, 15 | "batch_size": 1, 16 | "description": "layer name: bn3d_branch2c, net name: resnet.prototxt" 17 | } 18 | -------------------------------------------------------------------------------- /test/layers/batch_norm/config/config_5.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "BATCH NORM", 3 | "buffer_depth" : 0, 4 | "rows": 28, 5 | "cols": 28, 6 | "channels": 512, 7 | "coarse": 8, 8 | "coarse_in": 8, 9 | "coarse_out": 8, 10 | "size_in": 401408, 11 | "size_out": 401408, 12 | "rows_out": 28, 13 | "cols_out": 28, 14 | "channels_out": 512, 15 | "batch_size": 1, 16 | "description": "layer name: bn3b_branch2c, net name: resnet.prototxt" 17 | } 18 | -------------------------------------------------------------------------------- /test/layers/batch_norm/config/config_6.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "BATCH NORM", 3 | "buffer_depth" : 0, 4 | "rows": 56, 5 | "cols": 56, 6 | "channels": 64, 7 | "coarse": 4, 8 | "coarse_in": 4, 9 | "coarse_out": 4, 10 | "size_in": 200704, 11 | "size_out": 200704, 12 | "rows_out": 56, 13 | "cols_out": 56, 14 | "channels_out": 64, 15 | "batch_size": 1, 16 | "description": "layer name: bn2a_branch2a, net name: resnet.prototxt" 17 | } 18 | -------------------------------------------------------------------------------- /test/layers/batch_norm/config/config_7.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "BATCH NORM", 3 | "buffer_depth" : 0, 4 | "rows": 28, 5 | "cols": 28, 6 | "channels": 128, 7 | "coarse": 8, 8 | "coarse_in": 8, 9 | "coarse_out": 8, 10 | "size_in": 100352, 11 | "size_out": 100352, 12 | "rows_out": 28, 13 | "cols_out": 28, 14 | "channels_out": 128, 15 | "batch_size": 1, 16 | "description": "layer name: bn3b_branch2b, net name: resnet.prototxt" 17 | } 18 | -------------------------------------------------------------------------------- /test/layers/batch_norm/config/config_8.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "BATCH NORM", 3 | "buffer_depth" : 0, 4 | "rows": 56, 5 | "cols": 56, 6 | "channels": 64, 7 | "coarse": 8, 8 | "coarse_in": 8, 9 | "coarse_out": 8, 10 | "size_in": 200704, 11 | "size_out": 200704, 12 | "rows_out": 56, 13 | "cols_out": 56, 14 | "channels_out": 64, 15 | "batch_size": 1, 16 | "description": "layer name: bn2c_branch2b, net name: resnet.prototxt" 17 | } 18 | -------------------------------------------------------------------------------- /test/layers/batch_norm/config/config_9.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "BATCH NORM", 3 | "buffer_depth" : 0, 4 | "rows": 14, 5 | "cols": 14, 6 | "channels": 256, 7 | "coarse": 32, 8 | "coarse_in": 32, 9 | "coarse_out": 32, 10 | "size_in": 50176, 11 | "size_out": 50176, 12 | "rows_out": 14, 13 | "cols_out": 14, 14 | "channels_out": 256, 15 | "batch_size": 1, 16 | "description": "layer name: bn4c_branch2b, net name: resnet.prototxt" 17 | } 18 | -------------------------------------------------------------------------------- /test/layers/inner_product/tb/inner_product_layer_tb.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INNER_PRODUCT_LAYER_TB_HPP_ 2 | #define INNER_PRODUCT_LAYER_TB_HPP_ 3 | 4 | #include "common.hpp" 5 | #include "inner_product_layer.hpp" 6 | #include "inner_product_layer_param.hpp" 7 | 8 | void inner_product_layer_top( 9 | stream_t(inner_product_layer_input_t) in[INNER_PRODUCT_LAYER_COARSE_IN], 10 | stream_t(inner_product_layer_output_t) out[INNER_PRODUCT_LAYER_COARSE_OUT], 11 | int mode 12 | ); 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /test/layers/batch_norm/config/config_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "BATCH NORM", 3 | "buffer_depth" : 0, 4 | "rows": 28, 5 | "cols": 28, 6 | "channels": 128, 7 | "coarse": 32, 8 | "coarse_in": 32, 9 | "coarse_out": 32, 10 | "size_in": 100352, 11 | "size_out": 100352, 12 | "rows_out": 28, 13 | "cols_out": 28, 14 | "channels_out": 128, 15 | "batch_size": 1, 16 | "description": "layer name: bn3b_branch2a, net name: resnet.prototxt" 17 | } 18 | -------------------------------------------------------------------------------- /test/layers/batch_norm/config/config_1.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "BATCH NORM", 3 | "buffer_depth" : 0, 4 | "rows": 28, 5 | "cols": 28, 6 | "channels": 128, 7 | "coarse": 128, 8 | "coarse_in": 128, 9 | "coarse_out": 128, 10 | "size_in": 100352, 11 | "size_out": 100352, 12 | "rows_out": 28, 13 | "cols_out": 28, 14 | "channels_out": 128, 15 | "batch_size": 1, 16 | "description": "layer name: bn3c_branch2a, net name: resnet.prototxt" 17 | } 18 | -------------------------------------------------------------------------------- /test/layers/inner_product/config/config_1.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "CONVOLUTION", 3 | "buffer_depth": 2, 4 | "rows_in": 1, 5 | "cols_in": 1, 6 | "channels_in": 500, 7 | "filters": 10, 8 | "coarse_in": 50, 9 | "coarse_out": 2, 10 | "fine": 1, 11 | "size_in": 500, 12 | "size_out": 10, 13 | "rows_out": 1, 14 | "cols_out": 1, 15 | "channels_out": 10, 16 | "batch_size": 1, 17 | "description": "layer name: ip2, net name: lenet.prototxt" 18 | } 19 | -------------------------------------------------------------------------------- /test/layers/inner_product/config/config_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "INNER_PRODUCT", 3 | "buffer_depth" : 0, 4 | "rows_in": 1, 5 | "cols_in": 1, 6 | "channels_in": 64, 7 | "filters": 10, 8 | "coarse_in": 2, 9 | "coarse_out": 5, 10 | "fine": 1, 11 | "batch_size": 1, 12 | "wr_factor" : 1, 13 | "input_width": 16, 14 | "acc_width": 30, 15 | "weight_width": 8, 16 | "biases_width": 8, 17 | "output_width": 16, 18 | "has_bias": 1, 19 | "description": " " 20 | } 21 | -------------------------------------------------------------------------------- /test/modules/squeeze/src/squeeze.cpp: -------------------------------------------------------------------------------- 1 | #include "squeeze_tb.hpp" 2 | #include "squeeze.hpp" 3 | 4 | void squeeze_top( 5 | stream_t(squeeze_t) in[SQUEEZE_COARSE_IN], 6 | stream_t(squeeze_t) out[SQUEEZE_COARSE_OUT] 7 | ) 8 | { 9 | 10 | #pragma HLS DATAFLOW 11 | squeeze< 12 | SQUEEZE_BATCH_SIZE, 13 | SQUEEZE_ROWS, 14 | SQUEEZE_COLS, 15 | SQUEEZE_CHANNELS, 16 | SQUEEZE_COARSE_IN, 17 | SQUEEZE_COARSE_OUT, 18 | squeeze_t 19 | >(in,out); 20 | 21 | } 22 | -------------------------------------------------------------------------------- /test/layers/convolution/tb/convolution_layer_tb.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CONVOLUTION_LAYER_TB_HPP_ 2 | #define CONVOLUTION_LAYER_TB_HPP_ 3 | 4 | #include "common.hpp" 5 | #include "convolution_layer.hpp" 6 | #include "convolution_layer_param.hpp" 7 | 8 | void convolution_layer_top( 9 | stream_t(convolution_layer_input_t) in[CONVOLUTION_LAYER_COARSE_IN*CONVOLUTION_LAYER_COARSE_GROUP], 10 | stream_t(convolution_layer_output_t) out[CONVOLUTION_LAYER_COARSE_OUT*CONVOLUTION_LAYER_COARSE_GROUP], 11 | int mode 12 | ); 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /fpgaconvnet/hls/scripts/hls/tcl_getopt.tcl: -------------------------------------------------------------------------------- 1 | proc getopt {_argv name {_var ""} {default ""}} { 2 | upvar 1 $_argv argv $_var var 3 | set pos [lsearch -regexp $_argv ^$name] 4 | if {$pos>=0} { 5 | set to $pos 6 | if {$_var ne ""} { 7 | set var [lindex $_argv [incr to]] 8 | } 9 | set _argv [lreplace $_argv $pos $to] 10 | return 1 11 | } else { 12 | if {[llength [info level 0]] == 5} {set var $default} 13 | return 0 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test/modules/glue/tb/glue_tb.hpp: -------------------------------------------------------------------------------- 1 | #ifndef GLUE_TB_HPP_ 2 | #define GLUE_TB_HPP_ 3 | 4 | #include "common.hpp" 5 | #include "glue_param.hpp" 6 | 7 | // define the type based on the test configuration 8 | typedef ap_fixed glue_data_t; 9 | typedef ap_fixed glue_acc_t; 10 | 11 | void glue_top( 12 | stream_t(glue_acc_t) in[GLUE_COARSE_IN][GLUE_COARSE_OUT], 13 | stream_t(glue_data_t) out[GLUE_COARSE_OUT] 14 | ); 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /test/layers/avg_pooling/src/avg_pooling_layer_top.cpp: -------------------------------------------------------------------------------- 1 | #include "avg_pooling_layer_tb.hpp" 2 | #include "avg_pooling_layer.hpp" 3 | 4 | void avg_pooling_layer_top( 5 | stream_t(avg_pooling_layer_data_t) in[AVG_POOLING_LAYER_COARSE], 6 | stream_t(avg_pooling_layer_data_t) out[AVG_POOLING_LAYER_COARSE], 7 | int mode 8 | ) 9 | { 10 | #pragma HLS DATAFLOW 11 | #pragma HLS INTERFACE ap_ctrl_chain port=return 12 | 13 | #pragma HLS STREAM variable=in 14 | #pragma HLS STREAM variable=out 15 | 16 | avg_pooling_layer(in,out,mode); 17 | 18 | } -------------------------------------------------------------------------------- /test/modules/glue/src/glue.cpp: -------------------------------------------------------------------------------- 1 | #include "glue_tb.hpp" 2 | #include "glue.hpp" 3 | 4 | void glue_top( 5 | stream_t(glue_acc_t) in[GLUE_COARSE_IN][GLUE_COARSE_OUT], 6 | stream_t(glue_data_t) out[GLUE_COARSE_OUT] 7 | ) 8 | { 9 | 10 | #pragma HLS DATAFLOW 11 | 12 | glue< 13 | GLUE_BATCH_SIZE, 14 | GLUE_ROWS, 15 | GLUE_COLS, 16 | GLUE_FILTERS, 17 | GLUE_COARSE_IN, 18 | GLUE_COARSE_OUT, 19 | 1, 20 | glue_acc_t, 21 | glue_data_t 22 | >(in,out); 23 | 24 | } 25 | -------------------------------------------------------------------------------- /test/layers/pooling/config/config_1.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "POOLING", 3 | "rows": 14, 4 | "cols": 14, 5 | "channels": 512, 6 | "kernel_size": 2, 7 | "stride": 2, 8 | "pad": 0, 9 | "coarse": 64, 10 | "coarse_in": 64, 11 | "coarse_out": 64, 12 | "fine": 4, 13 | "pool_type": "max", 14 | "size_in": 100352, 15 | "size_out": 25088, 16 | "rows_out": 7, 17 | "cols_out": 7, 18 | "channels_out": 512, 19 | "batch_size": 1, 20 | "description": "layer name: pool5, net name: vgg16.prototxt" 21 | } -------------------------------------------------------------------------------- /test/layers/pooling/config/config_6.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "POOLING", 3 | "rows": 24, 4 | "cols": 24, 5 | "channels": 20, 6 | "kernel_size": 2, 7 | "stride": 2, 8 | "pad": 0, 9 | "coarse": 20, 10 | "coarse_in": 20, 11 | "coarse_out": 20, 12 | "fine": 4, 13 | "pool_type": "max", 14 | "size_in": 11520, 15 | "size_out": 2880, 16 | "rows_out": 12, 17 | "cols_out": 12, 18 | "channels_out": 20, 19 | "batch_size": 1, 20 | "description": "layer name: pool1, net name: lenet.prototxt" 21 | } -------------------------------------------------------------------------------- /test/layers/pooling/config/config_8.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "POOLING", 3 | "rows": 28, 4 | "cols": 28, 5 | "channels": 512, 6 | "kernel_size": 2, 7 | "stride": 2, 8 | "pad": 0, 9 | "coarse": 4, 10 | "coarse_in": 4, 11 | "coarse_out": 4, 12 | "fine": 4, 13 | "pool_type": "max", 14 | "size_in": 401408, 15 | "size_out": 100352, 16 | "rows_out": 14, 17 | "cols_out": 14, 18 | "channels_out": 512, 19 | "batch_size": 1, 20 | "description": "layer name: pool4, net name: vgg16.prototxt" 21 | } -------------------------------------------------------------------------------- /test/modules/avg_pool/src/avg_pool.cpp: -------------------------------------------------------------------------------- 1 | #include "avg_pool_tb.hpp" 2 | #include "avg_pool.hpp" 3 | 4 | void avg_pool_top( 5 | stream_t(avg_pool_t) in[AVG_POOL_KERNEL_SIZE_0][AVG_POOL_KERNEL_SIZE_1], 6 | stream_t(avg_pool_t) &out 7 | ) 8 | { 9 | 10 | #pragma HLS DATAFLOW 11 | 12 | avg_pool< 13 | AVG_POOL_BATCH_SIZE, 14 | AVG_POOL_ROWS, 15 | AVG_POOL_COLS, 16 | AVG_POOL_CHANNELS, 17 | AVG_POOL_KERNEL_SIZE_0, 18 | AVG_POOL_KERNEL_SIZE_1, 19 | avg_pool_t 20 | >(in,out); 21 | 22 | } -------------------------------------------------------------------------------- /test/modules/elementwise_add/tb/elementwise_add_tb.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ELEMENTWISE_ADD_TB_HPP_ 2 | #define ELEMENTWISE_ADD_TB_HPP_ 3 | 4 | #include "common.hpp" 5 | #include "elementwise_add_param.hpp" 6 | 7 | // define the type based on the test configuration 8 | typedef ap_fixed elementwise_add_t; 9 | 10 | void elementwise_add_top( 11 | stream_t(elementwise_add_t) &in1, 12 | stream_t(elementwise_add_t) &in2, 13 | stream_t(elementwise_add_t) &out 14 | ); 15 | 16 | #endif -------------------------------------------------------------------------------- /test/modules/elementwise_mul/tb/elementwise_mul_tb.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ELEMENTWISE_MUL_TB_HPP_ 2 | #define ELEMENTWISE_MUL_TB_HPP_ 3 | 4 | #include "common.hpp" 5 | #include "elementwise_mul_param.hpp" 6 | 7 | // define the type based on the test configuration 8 | typedef ap_fixed elementwise_mul_t; 9 | 10 | void elementwise_mul_top( 11 | stream_t(elementwise_mul_t) &in1, 12 | stream_t(elementwise_mul_t) &in2, 13 | stream_t(elementwise_mul_t) &out 14 | ); 15 | 16 | #endif -------------------------------------------------------------------------------- /test/layers/pooling/config/config_2.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "POOLING", 3 | "rows": 7, 4 | "cols": 7, 5 | "channels": 2048, 6 | "kernel_size": 7, 7 | "stride": 1, 8 | "pad": 0, 9 | "coarse": 512, 10 | "coarse_in": 512, 11 | "coarse_out": 512, 12 | "fine": 49, 13 | "pool_type": "max", 14 | "size_in": 100352, 15 | "size_out": 2048, 16 | "rows_out": 1, 17 | "cols_out": 1, 18 | "channels_out": 2048, 19 | "batch_size": 1, 20 | "description": "layer name: pool5, net name: resnet.prototxt" 21 | } -------------------------------------------------------------------------------- /test/layers/pooling/config/config_3.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "POOLING", 3 | "rows": 13, 4 | "cols": 13, 5 | "channels": 256, 6 | "kernel_size": 3, 7 | "stride": 2, 8 | "pad": 0, 9 | "coarse": 256, 10 | "coarse_in": 256, 11 | "coarse_out": 256, 12 | "fine": 9, 13 | "pool_type": "max", 14 | "size_in": 43264, 15 | "size_out": 9216, 16 | "rows_out": 6, 17 | "cols_out": 6, 18 | "channels_out": 256, 19 | "batch_size": 1, 20 | "description": "layer name: pool5, net name: alexnet.prototxt" 21 | } -------------------------------------------------------------------------------- /test/layers/pooling/config/config_7.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "POOLING", 3 | "rows": 224, 4 | "cols": 224, 5 | "channels": 64, 6 | "kernel_size": 2, 7 | "stride": 2, 8 | "pad": 0, 9 | "coarse": 2, 10 | "coarse_in": 2, 11 | "coarse_out": 2, 12 | "fine": 4, 13 | "pool_type": "max", 14 | "size_in": 3211264, 15 | "size_out": 802816, 16 | "rows_out": 112, 17 | "cols_out": 112, 18 | "channels_out": 64, 19 | "batch_size": 1, 20 | "description": "layer name: pool1, net name: vgg16.prototxt" 21 | } -------------------------------------------------------------------------------- /test/layers/pooling/config/config_5.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "POOLING", 3 | "rows": 56, 4 | "cols": 56, 5 | "channels": 192, 6 | "kernel_size": 3, 7 | "stride": 2, 8 | "pad": 0, 9 | "coarse": 1, 10 | "coarse_in": 1, 11 | "coarse_out": 1, 12 | "fine": 9, 13 | "pool_type": "max", 14 | "size_in": 602112, 15 | "size_out": 150528, 16 | "rows_out": 28, 17 | "cols_out": 28, 18 | "channels_out": 192, 19 | "batch_size": 1, 20 | "description": "layer name: pool2/3x3_s2, net name: googlenet.prototxt" 21 | } -------------------------------------------------------------------------------- /fpgaconvnet/hls/scripts/hls/run_csynth.tcl: -------------------------------------------------------------------------------- 1 | # get the root directory 2 | variable fpgaconvnet_root [file dirname [file dirname [file dirname [file normalize [info script]]]]] 3 | 4 | # load getopt script 5 | source ${fpgaconvnet_root}/scripts/hls/tcl_getopt.tcl 6 | 7 | # get input arguments 8 | set hls_arg [ lindex $argv 2 ] 9 | 10 | # get arguments 11 | getopt $hls_arg -prj project_path 12 | 13 | # open project 14 | open_project ${project_path} 15 | 16 | # open solution 17 | open_solution "solution" 18 | 19 | # run c-synthesis 20 | csynth_design 21 | 22 | exit 23 | -------------------------------------------------------------------------------- /test/layers/pooling/config/config_4.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "POOLING", 3 | "rows": 28, 4 | "cols": 28, 5 | "channels": 256, 6 | "kernel_size": 3, 7 | "stride": 1, 8 | "pad": 1, 9 | "coarse": 1, 10 | "coarse_in": 1, 11 | "coarse_out": 1, 12 | "fine": 9, 13 | "pool_type": "max", 14 | "size_in": 200704, 15 | "size_out": 200704, 16 | "rows_out": 28, 17 | "cols_out": 28, 18 | "channels_out": 256, 19 | "batch_size": 1, 20 | "description": "layer name: inception_3b/pool, net name: googlenet.prototxt" 21 | } -------------------------------------------------------------------------------- /test/layers/pooling/config/config_9.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "POOLING", 3 | "rows": 28, 4 | "cols": 28, 5 | "channels": 480, 6 | "kernel_size": 3, 7 | "stride": 2, 8 | "pad": 0, 9 | "coarse": 480, 10 | "coarse_in": 480, 11 | "coarse_out": 480, 12 | "fine": 9, 13 | "pool_type": "max", 14 | "size_in": 376320, 15 | "size_out": 94080, 16 | "rows_out": 14, 17 | "cols_out": 14, 18 | "channels_out": 480, 19 | "batch_size": 1, 20 | "description": "layer name: pool3/3x3_s2, net name: googlenet.prototxt" 21 | } -------------------------------------------------------------------------------- /test/layers/relu/src/relu_layer_top.cpp: -------------------------------------------------------------------------------- 1 | #include "relu_layer_tb.hpp" 2 | #include "relu_layer.hpp" 3 | 4 | void relu_layer_top( 5 | stream_t(relu_layer_data_t) in[RELU_LAYER_COARSE], 6 | stream_t(relu_layer_data_t) out[RELU_LAYER_COARSE], 7 | int mode 8 | ) 9 | { 10 | 11 | #pragma HLS DATAFLOW 12 | #pragma HLS INTERFACE ap_ctrl_chain port=return 13 | 14 | //#pragma HLS INTERFACE axis port=in 15 | //#pragma HLS INTERFACE axis port=out 16 | #pragma HLS STREAM variable=in 17 | #pragma HLS STREAM variable=out 18 | 19 | relu_layer(in,out,mode); 20 | 21 | } 22 | -------------------------------------------------------------------------------- /test/layers/elementwise_add/tb/elementwise_add_layer_tb.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ELEMENTWISE_ADD_LAYER_TB_HPP_ 2 | #define ELEMENTWISE_ADD_LAYER_TB_HPP_ 3 | 4 | #include "common.hpp" 5 | #include "elementwise_add_layer.hpp" 6 | #include "elementwise_add_layer_param.hpp" 7 | 8 | void elementwise_add_layer_top( 9 | stream_t(elementwise_add_layer_data_t) in1[ELEMENTWISE_ADD_LAYER_COARSE], 10 | stream_t(elementwise_add_layer_data_t) in2[ELEMENTWISE_ADD_LAYER_COARSE], 11 | stream_t(elementwise_add_layer_data_t) out[ELEMENTWISE_ADD_LAYER_COARSE], 12 | int mode 13 | ); 14 | 15 | #endif -------------------------------------------------------------------------------- /test/layers/elementwise_mul/tb/elementwise_mul_layer_tb.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ELEMENTWISE_MUL_LAYER_TB_HPP_ 2 | #define ELEMENTWISE_MUL_LAYER_TB_HPP_ 3 | 4 | #include "common.hpp" 5 | #include "elementwise_mul_layer.hpp" 6 | #include "elementwise_mul_layer_param.hpp" 7 | 8 | void elementwise_mul_layer_top( 9 | stream_t(elementwise_mul_layer_data_t) in1[ELEMENTWISE_MUL_LAYER_COARSE], 10 | stream_t(elementwise_mul_layer_data_t) in2[ELEMENTWISE_MUL_LAYER_COARSE], 11 | stream_t(elementwise_mul_layer_data_t) out[ELEMENTWISE_MUL_LAYER_COARSE], 12 | int mode 13 | ); 14 | 15 | #endif -------------------------------------------------------------------------------- /test/layers/global_pooling/src/global_pooling_layer_top.cpp: -------------------------------------------------------------------------------- 1 | #include "global_pooling_layer_tb.hpp" 2 | #include "global_pooling_layer.hpp" 3 | 4 | void global_pooling_layer_top( 5 | stream_t(global_pooling_layer_data_t) in[GLOBAL_POOLING_LAYER_COARSE], 6 | stream_t(global_pooling_layer_data_t) out[GLOBAL_POOLING_LAYER_COARSE], 7 | int mode 8 | ) 9 | { 10 | #pragma HLS DATAFLOW 11 | #pragma HLS INTERFACE ap_ctrl_chain port=return 12 | 13 | #pragma HLS STREAM variable=in 14 | #pragma HLS STREAM variable=out 15 | 16 | global_pooling_layer(in,out,mode); 17 | 18 | } -------------------------------------------------------------------------------- /test/layers/convolution/config/config_3.json: -------------------------------------------------------------------------------- 1 | { 2 | "buffer_depth": 0, 3 | "rows_in": 10, 4 | "cols_in": 10, 5 | "channels_in": 10, 6 | "filters": 10, 7 | "kernel_size": 1, 8 | "stride": 1, 9 | "groups": 1, 10 | "pad": 0, 11 | "coarse_in": 1, 12 | "coarse_out": 1, 13 | "coarse_group": 1, 14 | "fine": 1, 15 | "wr_factor": 1, 16 | "batch_size": 1, 17 | "input_width": 16, 18 | "acc_width": 30, 19 | "weight_width": 16, 20 | "output_width": 16, 21 | "description": "No parallelism. Kernel Size =1" 22 | } 23 | -------------------------------------------------------------------------------- /test/modules/accum/src/accum.cpp: -------------------------------------------------------------------------------- 1 | #include "accum_tb.hpp" 2 | #include "accum.hpp" 3 | 4 | void accum_top( 5 | stream_t(test_accum_t) &in, 6 | stream_t(test_accum_t) &out 7 | ) 8 | { 9 | 10 | #pragma HLS INTERFACE axis port=in 11 | #pragma HLS INTERFACE axis port=out 12 | 13 | #pragma HLS DATAFLOW 14 | 15 | // DUT 16 | accum< 17 | ACCUM_BATCH_SIZE, 18 | ACCUM_ROWS, 19 | ACCUM_COLS, 20 | ACCUM_CHANNELS, 21 | ACCUM_FILTERS, 22 | ACCUM_GROUPS, 23 | test_accum_t 24 | >(in,out); 25 | 26 | } 27 | 28 | -------------------------------------------------------------------------------- /test/modules/elementwise_mul/src/elementwise_mul.cpp: -------------------------------------------------------------------------------- 1 | #include "elementwise_mul_tb.hpp" 2 | #include "elementwise_mul.hpp" 3 | 4 | void elementwise_mul_top( 5 | stream_t(elementwise_mul_t) &in1, 6 | stream_t(elementwise_mul_t) &in2, 7 | stream_t(elementwise_mul_t) &out 8 | ) 9 | { 10 | 11 | #pragma HLS DATAFLOW 12 | 13 | // DUT 14 | elementwise_mul< 15 | ELEMENTWISE_MUL_BATCH_SIZE, 16 | ELEMENTWISE_MUL_ROWS, 17 | ELEMENTWISE_MUL_COLS, 18 | ELEMENTWISE_MUL_CHANNELS, 19 | elementwise_mul_t 20 | >(in1,in2,out); 21 | 22 | } -------------------------------------------------------------------------------- /test/layers/convolution/config/config_4.json: -------------------------------------------------------------------------------- 1 | { 2 | "buffer_depth": 0, 3 | "rows_in": 10, 4 | "cols_in": 10, 5 | "channels_in": 1, 6 | "filters": 10, 7 | "kernel_size": 1, 8 | "stride": 1, 9 | "groups": 1, 10 | "pad": 0, 11 | "coarse_in": 1, 12 | "coarse_out": 1, 13 | "coarse_group": 1, 14 | "fine": 1, 15 | "wr_factor": 1, 16 | "batch_size": 1, 17 | "input_width": 16, 18 | "acc_width": 30, 19 | "weight_width": 16, 20 | "output_width": 16, 21 | "description": "no channels, No parallelism. Kernel Size =1" 22 | } 23 | -------------------------------------------------------------------------------- /test/layers/convolution/config/config_5.json: -------------------------------------------------------------------------------- 1 | { 2 | "buffer_depth": 0, 3 | "rows_in": 10, 4 | "cols_in": 10, 5 | "channels_in": 10, 6 | "filters": 1, 7 | "kernel_size": 1, 8 | "stride": 1, 9 | "groups": 1, 10 | "pad": 0, 11 | "coarse_in": 1, 12 | "coarse_out": 1, 13 | "coarse_group": 1, 14 | "fine": 1, 15 | "wr_factor": 1, 16 | "batch_size": 1, 17 | "input_width": 16, 18 | "acc_width": 30, 19 | "weight_width": 16, 20 | "output_width": 16, 21 | "description": "no filters, No parallelism. Kernel Size =1" 22 | } 23 | -------------------------------------------------------------------------------- /test/modules/elementwise_add/src/elementwise_add.cpp: -------------------------------------------------------------------------------- 1 | #include "elementwise_add_tb.hpp" 2 | #include "elementwise_add.hpp" 3 | 4 | void elementwise_add_top( 5 | stream_t(elementwise_add_t) &in1, 6 | stream_t(elementwise_add_t) &in2, 7 | stream_t(elementwise_add_t) &out 8 | ) 9 | { 10 | 11 | #pragma HLS DATAFLOW 12 | 13 | // DUT 14 | elementwise_add< 15 | ELEMENTWISE_ADD_BATCH_SIZE, 16 | ELEMENTWISE_ADD_ROWS, 17 | ELEMENTWISE_ADD_COLS, 18 | ELEMENTWISE_ADD_CHANNELS, 19 | elementwise_add_t 20 | >(in1,in2,out); 21 | 22 | } 23 | -------------------------------------------------------------------------------- /test/layers/convolution/config/config_2.json: -------------------------------------------------------------------------------- 1 | { 2 | "buffer_depth": 0, 3 | "rows_in": 1, 4 | "cols_in": 1, 5 | "channels_in": 10, 6 | "filters": 10, 7 | "kernel_size": 1, 8 | "stride": 1, 9 | "groups": 1, 10 | "pad": 0, 11 | "coarse_in": 1, 12 | "coarse_out": 1, 13 | "coarse_group": 1, 14 | "fine": 1, 15 | "wr_factor": 1, 16 | "batch_size": 1, 17 | "input_width": 16, 18 | "acc_width": 30, 19 | "weight_width": 16, 20 | "output_width": 16, 21 | "description": "no spatial dim. No parallelism. Kernel Size =1" 22 | } 23 | -------------------------------------------------------------------------------- /test/layers/pooling/src/pooling_layer_top.cpp: -------------------------------------------------------------------------------- 1 | #include "pooling_layer_tb.hpp" 2 | #include "pooling_layer.hpp" 3 | 4 | void pooling_layer_top( 5 | stream_t(pooling_layer_data_t) in[POOLING_LAYER_COARSE], 6 | stream_t(pooling_layer_data_t) out[POOLING_LAYER_COARSE], 7 | int mode 8 | ) 9 | { 10 | #pragma HLS DATAFLOW 11 | #pragma HLS INTERFACE ap_ctrl_chain port=return 12 | 13 | //#pragma HLS INTERFACE axis port=in 14 | //#pragma HLS INTERFACE axis port=out 15 | #pragma HLS STREAM variable=in 16 | #pragma HLS STREAM variable=out 17 | 18 | pooling_layer(in,out,mode); 19 | 20 | } 21 | -------------------------------------------------------------------------------- /test/modules/pool/config/config_1.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "POOL", 3 | "rows": 1, 4 | "cols": 1, 5 | "channels": 4, 6 | "pool_type": 0, 7 | <<<<<<< HEAD 8 | "kernel_size": 2, 9 | "rows_out": 56, 10 | "cols_out": 56, 11 | "channels_out": 3, 12 | "batch_size": 1, 13 | "description": "module name: pool, layer name: inception_3a/pool, net name: googlenet.prototxt" 14 | } 15 | ======= 16 | "kernel_size": [2,2], 17 | "batch_size": 1, 18 | "description": "module name: pool, layer name: pool2, net name: vgg16.prototxt" 19 | } 20 | >>>>>>> dev-alex 21 | -------------------------------------------------------------------------------- /test/modules/pool/config/config_2.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "POOL", 3 | "rows": 1, 4 | "cols": 1, 5 | "channels": 4, 6 | "pool_type": 0, 7 | <<<<<<< HEAD 8 | "kernel_size": 4, 9 | "rows_out": 56, 10 | "cols_out": 56, 11 | "channels_out": 3, 12 | "batch_size": 1, 13 | "description": "module name: pool, layer name: inception_3a/pool, net name: googlenet.prototxt" 14 | } 15 | ======= 16 | "kernel_size": [3,3], 17 | "batch_size": 1, 18 | "description": "module name: pool, layer name: pool5, net name: alexnet.prototxt" 19 | } 20 | >>>>>>> dev-alex 21 | -------------------------------------------------------------------------------- /test/layers/convolution/config/config_1.json: -------------------------------------------------------------------------------- 1 | { 2 | "buffer_depth": 0, 3 | "rows_in": 1, 4 | "cols_in": 1, 5 | "channels_in": 1, 6 | "filters": 10, 7 | "kernel_size": 1, 8 | "stride": 1, 9 | "groups": 1, 10 | "pad": 0, 11 | "coarse_in": 1, 12 | "coarse_out": 1, 13 | "coarse_group": 1, 14 | "fine": 1, 15 | "wr_factor": 1, 16 | "batch_size": 1, 17 | "input_width": 16, 18 | "acc_width": 30, 19 | "weight_width": 16, 20 | "output_width": 16, 21 | "description": "no spatial dim, no channels. No parallelism. Kernel Size =1" 22 | } 23 | -------------------------------------------------------------------------------- /test/layers/split/src/split_layer_top.cpp: -------------------------------------------------------------------------------- 1 | #include "split_layer_tb.hpp" 2 | #include "split_layer.hpp" 3 | 4 | void split_layer_top( 5 | stream_t(split_layer_data_t) in[SPLIT_LAYER_COARSE], 6 | stream_t(split_layer_data_t) out_1[SPLIT_LAYER_COARSE], 7 | stream_t(split_layer_data_t) out_2[SPLIT_LAYER_COARSE], 8 | int mode 9 | ) 10 | { 11 | 12 | #pragma HLS DATAFLOW 13 | #pragma HLS INTERFACE ap_ctrl_chain port=return 14 | 15 | #pragma HLS STREAM variable=in 16 | #pragma HLS STREAM variable=out_1 17 | #pragma HLS STREAM variable=out_2 18 | 19 | split_layer(in,out_1,out_2,mode); 20 | 21 | } -------------------------------------------------------------------------------- /test/layers/squeeze/src/squeeze_layer_top.cpp: -------------------------------------------------------------------------------- 1 | #include "squeeze_layer_tb.hpp" 2 | #include "squeeze_layer.hpp" 3 | 4 | void squeeze_layer_top( 5 | stream_t(squeeze_layer_data_t) in[SQUEEZE_LAYER_COARSE_IN], 6 | stream_t(squeeze_layer_data_t) out[SQUEEZE_LAYER_COARSE_OUT], 7 | int mode 8 | ) 9 | { 10 | 11 | #pragma HLS DATAFLOW 12 | #pragma HLS INTERFACE ap_ctrl_chain port=return 13 | 14 | //#pragma HLS INTERFACE axis port=in 15 | //#pragma HLS INTERFACE axis port=out 16 | #pragma HLS STREAM variable=in 17 | #pragma HLS STREAM variable=out 18 | 19 | squeeze_layer(in,out,mode); 20 | 21 | } 22 | -------------------------------------------------------------------------------- /fpgaconvnet/hls/scripts/hls/export_design.tcl: -------------------------------------------------------------------------------- 1 | # get the root directory 2 | variable fpgaconvnet_root [file dirname [file dirname [file dirname [file normalize [info script]]]]] 3 | 4 | # load getopt script 5 | source ${fpgaconvnet_root}/scripts/hls/tcl_getopt.tcl 6 | 7 | # get input arguments 8 | set hls_arg [ lindex $argv 2 ] 9 | 10 | # get arguments 11 | getopt $hls_arg -prj project_path 12 | 13 | # open project 14 | open_project ${project_path} 15 | 16 | # open solution 17 | open_solution "solution" 18 | 19 | # run export design 20 | export_design -rtl verilog -format ip_catalog 21 | 22 | exit 23 | -------------------------------------------------------------------------------- /test/modules/sliding_window/tb/sliding_window_tb.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SLIDING_WINDOW_TB_HPP_ 2 | #define SLIDING_WINDOW_TB_HPP_ 3 | 4 | #include "common.hpp" 5 | #include "sliding_window_param.hpp" 6 | 7 | // define the type based on the test configuration 8 | typedef ap_fixed sliding_window_t; 9 | 10 | void sliding_window_top( 11 | stream_t(sliding_window_t) &in, 12 | stream_t(sliding_window_t) out[SLIDING_WINDOW_KERNEL_SIZE_0][SLIDING_WINDOW_KERNEL_SIZE_1] 13 | ); 14 | 15 | ////////////////////////////////////////// 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /fpgaconvnet/hls/scripts/hls/run_implementation.tcl: -------------------------------------------------------------------------------- 1 | # get the root directory 2 | variable fpgaconvnet_root [file dirname [file dirname [file dirname [file normalize [info script]]]]] 3 | 4 | # load getopt script 5 | source ${fpgaconvnet_root}/scripts/hls/tcl_getopt.tcl 6 | 7 | # get input arguments 8 | set hls_arg [ lindex $argv 2 ] 9 | 10 | # get arguments 11 | getopt $hls_arg -prj project_path 12 | 13 | # open project 14 | open_project ${project_path} 15 | 16 | # open solution 17 | open_solution "solution" 18 | 19 | # run implementation 20 | export_design -flow impl -rtl verilog -format ip_catalog 21 | 22 | exit 23 | -------------------------------------------------------------------------------- /test/modules/fork/tb/fork_tb.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FORK_TB_HPP_ 2 | #define FORK_TB_HPP_ 3 | 4 | #include "common.hpp" 5 | #include "fork_param.hpp" 6 | 7 | // define the type based on the test configuration 8 | typedef ap_fixed fork_t; 9 | 10 | void fork_top( 11 | #if (FORK_KERNEL_SIZE_0 > 1) || (FORK_KERNEL_SIZE_1 > 1) 12 | stream_t(fork_t) in[FORK_KERNEL_SIZE_0][FORK_KERNEL_SIZE_1], 13 | stream_t(fork_t) out[FORK_COARSE][FORK_KERNEL_SIZE_0][FORK_KERNEL_SIZE_1] 14 | #else 15 | stream_t(fork_t) &in, 16 | stream_t(fork_t) out[FORK_COARSE] 17 | #endif 18 | ); 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /test/layers/convolution/config/config_6.json: -------------------------------------------------------------------------------- 1 | { 2 | "buffer_depth": 0, 3 | "rows_in": 10, 4 | "cols_in": 10, 5 | "channels_in": 10, 6 | "filters": 2, 7 | "kernel_size": 2, 8 | "stride": 1, 9 | "groups": 1, 10 | "pad": 0, 11 | "coarse_in": 1, 12 | "coarse_out": 1, 13 | "coarse_group": 1, 14 | "fine": 1, 15 | "wr_factor": 1, 16 | "batch_size": 1, 17 | "input_width": 16, 18 | "acc_width": 30, 19 | "weight_width": 16, 20 | "biases_width": 16, 21 | "output_width": 16, 22 | "has_bias": 1, 23 | "description": "no filters, No parallelism. Kernel Size =2" 24 | } 25 | -------------------------------------------------------------------------------- /test/modules/mem_read/tb/mem_read_tb.hpp: -------------------------------------------------------------------------------- 1 | #ifndef MEM_READ_TB_HPP_ 2 | #define MEM_READ_TB_HPP_ 3 | 4 | #include "common.hpp" 5 | #include "mem_read_param.hpp" 6 | 7 | #define MEM_READ_DMA_WIDTH 64 8 | #define MEM_READ_DATA_WIDTH 16 9 | #define MEM_READ_BIT_MASK ((1<<(MEM_READ_DATA_WIDTH))-1) 10 | 11 | ///////////////////////////////// 12 | 13 | void mem_read_top( 14 | volatile mem_int in_hw[MEM_READ_PORTS_IN][MEM_READ_BATCH_SIZE*MEM_READ_ROWS_IN*MEM_READ_COLS_IN*DIVIDE(MEM_READ_CHANNELS_IN,MEM_READ_STREAMS_IN)], 15 | stream_t(data_t) in[MEM_READ_STREAMS_IN] 16 | ); 17 | 18 | ///////////////////////////////// 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /fpgaconvnet/hls/generate/modules/relu.py: -------------------------------------------------------------------------------- 1 | relu_template = """ 2 | {indent}relu< 3 | {indent} {NAME}_BATCH_SIZE, 4 | {indent} {NAME}_ROWS, 5 | {indent} {NAME}_COLS, 6 | {indent} {NAME}_CHANNELS, 7 | {indent} {relu_t} 8 | {indent}>({input_stream},{output_stream}); 9 | """ 10 | 11 | def gen_relu_module(name,input_stream,output_stream, 12 | relu_t="data_t",indent=0): 13 | return relu_template.format( 14 | NAME =name.upper(), 15 | input_stream =input_stream, 16 | output_stream =output_stream, 17 | relu_t =relu_t, 18 | indent =" "*indent 19 | ) 20 | 21 | -------------------------------------------------------------------------------- /fpgaconvnet/hls/scripts/hls/run_csim.tcl: -------------------------------------------------------------------------------- 1 | # get the root directory 2 | variable fpgaconvnet_root [file dirname [file dirname [file dirname [file normalize [info script]]]]] 3 | 4 | # load getopt script 5 | source ${fpgaconvnet_root}/scripts/hls/tcl_getopt.tcl 6 | 7 | # get input arguments 8 | set hls_arg [ lindex $argv 2 ] 9 | 10 | # get arguments 11 | getopt $hls_arg -prj project_path 12 | 13 | # open project 14 | open_project ${project_path} 15 | 16 | # add any data files 17 | add_files -tb [ glob ${project_path}/data/*.dat ] 18 | 19 | # open solution 20 | open_solution "solution" 21 | 22 | # run c-simulation 23 | csim_design 24 | 25 | exit 26 | -------------------------------------------------------------------------------- /fpgaconvnet/hls/scripts/hls/run_cosim.tcl: -------------------------------------------------------------------------------- 1 | # get the root directory 2 | variable fpgaconvnet_root [file dirname [file dirname [file dirname [file normalize [info script]]]]] 3 | 4 | # load getopt script 5 | source ${fpgaconvnet_root}/scripts/hls/tcl_getopt.tcl 6 | 7 | # get input arguments 8 | set hls_arg [ lindex $argv 2 ] 9 | 10 | # get arguments 11 | getopt $hls_arg -prj project_path 12 | 13 | # open project 14 | open_project ${project_path} 15 | 16 | # add any data files 17 | add_files -tb [ glob ${project_path}/data/*.dat ] 18 | 19 | # open solution 20 | open_solution "solution" 21 | 22 | # run co-simulation 23 | cosim_design -rtl verilog -trace_level all 24 | 25 | exit 26 | -------------------------------------------------------------------------------- /fpgaconvnet/hls/generate/modules/global_pool.py: -------------------------------------------------------------------------------- 1 | global_pool_template=""" 2 | {indent}global_pool< 3 | {indent} {NAME}_BATCH_SIZE, 4 | {indent} {NAME}_ROWS, 5 | {indent} {NAME}_COLS, 6 | {indent} {NAME}_CHANNELS, 7 | {indent} {global_pool_t} 8 | {indent}>({input_stream},{output_stream}); 9 | """ 10 | 11 | def gen_global_pool_module(name,input_stream,output_stream, 12 | global_pool_t="data_t",indent=0): 13 | return global_pool_template.format( 14 | NAME =name.upper(), 15 | input_stream =input_stream, 16 | output_stream =output_stream, 17 | global_pool_t =global_pool_t, 18 | indent =" "*indent 19 | ) -------------------------------------------------------------------------------- /test/modules/conv/tb/conv_tb.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CONV_TB_HPP_ 2 | #define CONV_TB_HPP_ 3 | 4 | #include "common.hpp" 5 | #include "conv_param.hpp" 6 | 7 | typedef ap_fixed conv_data_t; 8 | typedef ap_fixed conv_weight_t; 9 | typedef ap_fixed conv_acc_t; 10 | 11 | void conv_top( 12 | stream_t(conv_data_t) in[CONV_KERNEL_SIZE_0][CONV_KERNEL_SIZE_1], 13 | conv_weight_t weights[CONV_CHANNELS*DIVIDE(CONV_FILTERS,CONV_GROUPS)][CONV_KERNEL_SIZE_0][CONV_KERNEL_SIZE_1], 14 | stream_t(conv_acc_t) &out 15 | ); 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /test/layers/elementwise_add/src/elementwise_add_layer_top.cpp: -------------------------------------------------------------------------------- 1 | #include "elementwise_add_layer_tb.hpp" 2 | #include "elementwise_add_layer.hpp" 3 | 4 | void elementwise_add_layer_top( 5 | stream_t(elementwise_add_layer_data_t) in1[ELEMENTWISE_ADD_LAYER_COARSE], 6 | stream_t(elementwise_add_layer_data_t) in2[ELEMENTWISE_ADD_LAYER_COARSE], 7 | stream_t(elementwise_add_layer_data_t) out[ELEMENTWISE_ADD_LAYER_COARSE], 8 | int mode 9 | ) 10 | { 11 | 12 | #pragma HLS DATAFLOW 13 | #pragma HLS INTERFACE ap_ctrl_chain port=return 14 | 15 | #pragma HLS STREAM variable=in1 16 | #pragma HLS STREAM variable=in2 17 | #pragma HLS STREAM variable=out 18 | 19 | elementwise_add_layer(in1,in2,out,mode); 20 | 21 | } -------------------------------------------------------------------------------- /test/layers/elementwise_mul/src/elementwise_mul_layer_top.cpp: -------------------------------------------------------------------------------- 1 | #include "elementwise_mul_layer_tb.hpp" 2 | #include "elementwise_mul_layer.hpp" 3 | 4 | void elementwise_mul_layer_top( 5 | stream_t(elementwise_mul_layer_data_t) in1[ELEMENTWISE_MUL_LAYER_COARSE], 6 | stream_t(elementwise_mul_layer_data_t) in2[ELEMENTWISE_MUL_LAYER_COARSE], 7 | stream_t(elementwise_mul_layer_data_t) out[ELEMENTWISE_MUL_LAYER_COARSE], 8 | int mode 9 | ) 10 | { 11 | 12 | #pragma HLS DATAFLOW 13 | #pragma HLS INTERFACE ap_ctrl_chain port=return 14 | 15 | #pragma HLS STREAM variable=in1 16 | #pragma HLS STREAM variable=in2 17 | #pragma HLS STREAM variable=out 18 | 19 | elementwise_mul_layer(in1,in2,out,mode); 20 | 21 | } -------------------------------------------------------------------------------- /fpgaconvnet/hls/generate/modules/accum.py: -------------------------------------------------------------------------------- 1 | accum_template = """ 2 | {indent}accum< 3 | {indent} {NAME}_BATCH_SIZE, 4 | {indent} {NAME}_ROWS, 5 | {indent} {NAME}_COLS, 6 | {indent} {NAME}_CHANNELS, 7 | {indent} {NAME}_FILTERS, 8 | {indent} {NAME}_GROUPS, 9 | {indent} {accum_t} 10 | {indent}>({input_stream},{output_stream}); 11 | """ 12 | 13 | def gen_accum_module(name,input_stream,output_stream, 14 | accum_t="data_t",indent=0): 15 | return accum_template.format( 16 | NAME =name.upper(), 17 | input_stream =input_stream, 18 | output_stream =output_stream, 19 | accum_t =accum_t, 20 | indent =" "*indent 21 | ) 22 | -------------------------------------------------------------------------------- /fpgaconvnet/hls/generate/modules/pool.py: -------------------------------------------------------------------------------- 1 | pool_template=""" 2 | {indent}pool< 3 | {indent} {NAME}_BATCH_SIZE, 4 | {indent} {NAME}_ROWS, 5 | {indent} {NAME}_COLS, 6 | {indent} {NAME}_CHANNELS, 7 | {indent} {NAME}_KERNEL_SIZE_X, 8 | {indent} {NAME}_KERNEL_SIZE_Y, 9 | {indent} {pool_t} 10 | {indent}>({input_stream},{output_stream}); 11 | """ 12 | 13 | def gen_pool_module(name,input_stream,output_stream, 14 | pool_t="data_t",indent=0): 15 | return pool_template.format( 16 | NAME =name.upper(), 17 | input_stream =input_stream, 18 | output_stream =output_stream, 19 | pool_t =pool_t, 20 | indent =" "*indent 21 | ) 22 | -------------------------------------------------------------------------------- /test/layers/convolution/config/config_7.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "CONVOLUTION", 3 | "buffer_depth": 0, 4 | "rows_in": 28, 5 | "cols_in": 28, 6 | "channels_in": 1, 7 | "filters": 5, 8 | "kernel_size": [5,5], 9 | "stride": [1,1], 10 | "groups": 1, 11 | "coarse_in": 1, 12 | "coarse_out": 5, 13 | "coarse_group": 1, 14 | "fine": 25, 15 | "pad": 4, 16 | "wr_factor": 1, 17 | "batch_size": 1, 18 | "input_width": 16, 19 | "data_width": 16, 20 | "acc_width": 16, 21 | "weight_width": 16, 22 | "has_bias": 1, 23 | "biases_width": 16, 24 | "output_width": 16, 25 | "description": "layer name: conv1, net name: brchy lenet bb, NO BIAS" 26 | } 27 | 28 | -------------------------------------------------------------------------------- /fpgaconvnet/hls/generate/modules/squeeze.py: -------------------------------------------------------------------------------- 1 | squeeze_template = """ 2 | {indent}squeeze< 3 | {indent} {NAME}_BATCH_SIZE, 4 | {indent} {NAME}_ROWS, 5 | {indent} {NAME}_COLS, 6 | {indent} {NAME}_CHANNELS, 7 | {indent} {NAME}_COARSE_IN, 8 | {indent} {NAME}_COARSE_OUT, 9 | {indent} {squeeze_t} 10 | {indent}>({input_stream},{output_stream}); 11 | """ 12 | 13 | def gen_squeeze_module(name,input_stream,output_stream, 14 | squeeze_t="data_t",indent=0): 15 | return squeeze_template.format( 16 | NAME =name.upper(), 17 | input_stream =input_stream, 18 | output_stream =output_stream, 19 | squeeze_t =squeeze_t, 20 | indent =" "*indent 21 | ) 22 | -------------------------------------------------------------------------------- /test/modules/mem_write/tb/mem_write_tb.hpp: -------------------------------------------------------------------------------- 1 | #ifndef MEM_WRITE_TB_HPP_ 2 | #define MEM_WRITE_TB_HPP_ 3 | 4 | #include "common.hpp" 5 | 6 | #include "mem_write_param.hpp" 7 | 8 | #define MEM_WRITE_DMA_WIDTH 64 9 | #define MEM_WRITE_DATA_WIDTH 16 10 | #define MEM_WRITE_BIT_MASK ((1<<(MEM_WRITE_DATA_WIDTH))-1) 11 | 12 | ///////////////////////////////// 13 | 14 | void mem_write_top( 15 | int weights_reloading_index, 16 | stream_t(data_t) out[MEM_WRITE_STREAMS_OUT], 17 | volatile mem_int out_hw[MEM_WRITE_PORTS_OUT][MEM_WRITE_BATCH_SIZE*MEM_WRITE_ROWS_OUT*MEM_WRITE_COLS_OUT*DIVIDE(MEM_WRITE_CHANNELS_OUT,MEM_WRITE_STREAMS_OUT)*MEM_WRITE_WEIGHTS_RELOADING_FACTOR] 18 | ); 19 | 20 | ///////////////////////////////// 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /fpgaconvnet/hls/generate/modules/avg_pool.py: -------------------------------------------------------------------------------- 1 | avg_pool_template=""" 2 | {indent}avg_pool< 3 | {indent} {NAME}_BATCH_SIZE, 4 | {indent} {NAME}_ROWS, 5 | {indent} {NAME}_COLS, 6 | {indent} {NAME}_CHANNELS, 7 | {indent} {NAME}_KERNEL_SIZE_X, 8 | {indent} {NAME}_KERNEL_SIZE_Y, 9 | {indent} {avg_pool_t} 10 | {indent}>({input_stream},{output_stream}); 11 | """ 12 | 13 | def gen_avg_pool_module(name,input_stream,output_stream, 14 | avg_pool_t="data_t",indent=0): 15 | return avg_pool_template.format( 16 | NAME =name.upper(), 17 | input_stream =input_stream, 18 | output_stream =output_stream, 19 | avg_pool_t =avg_pool_t, 20 | indent =" "*indent 21 | ) 22 | -------------------------------------------------------------------------------- /fpgaconvnet/hls/tools/array_init.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | def array_init(arr): 4 | """ 5 | helper function to format an arbitrary shaped array into the content of 6 | a C++ array initialisation. 7 | """ 8 | prev = arr 9 | for i in range(len(arr.shape)-1): 10 | curr = np.zeros((prev.shape[0:-1]),dtype='object') 11 | for index,_ in np.ndenumerate(curr): 12 | if i==0: 13 | curr[index] ="\t"*len(curr.shape) + "{" + ",".join([ str(val) for val in prev[index]]) +"}" 14 | else: 15 | curr[index] ="\t"*len(curr.shape) + "{\n" + ",\n".join([ str(val) for val in prev[index]]) + "\n" + "\t"*len(curr.shape) + "}" 16 | prev = curr 17 | return ",\n".join([i for i in prev]) 18 | -------------------------------------------------------------------------------- /fpgaconvnet/hls/generate/modules/bias.py: -------------------------------------------------------------------------------- 1 | bias_template=""" 2 | {indent}bias< 3 | {indent} {NAME}_BATCH_SIZE, 4 | {indent} {NAME}_ROWS, 5 | {indent} {NAME}_COLS, 6 | {indent} {NAME}_FILTERS, 7 | {indent} {data_t}, 8 | {indent} {biases_t} 9 | {indent}>({input_stream},{biases},{output_stream}); 10 | """ 11 | 12 | def gen_bias_module(name, input_stream, biases, output_stream, 13 | data_t="data_t",biases_t="data_t",indent=0): 14 | return bias_template.format( 15 | NAME =name.upper(), 16 | input_stream =input_stream, 17 | biases =biases, 18 | output_stream =output_stream, 19 | data_t =data_t, 20 | biases_t =biases_t, 21 | indent =" "*indent 22 | ) 23 | -------------------------------------------------------------------------------- /test/modules/fork/src/fork.cpp: -------------------------------------------------------------------------------- 1 | #include "fork_tb.hpp" 2 | #include "fork.hpp" 3 | 4 | void fork_top( 5 | #if (FORK_KERNEL_SIZE_0 > 1) || (FORK_KERNEL_SIZE_1 > 1) 6 | stream_t(fork_t) in[FORK_KERNEL_SIZE_0][FORK_KERNEL_SIZE_1], 7 | stream_t(fork_t) out[FORK_COARSE][FORK_KERNEL_SIZE_0][FORK_KERNEL_SIZE_1] 8 | #else 9 | stream_t(fork_t) &in, 10 | stream_t(fork_t) out[FORK_COARSE] 11 | #endif 12 | ) 13 | { 14 | 15 | #pragma HLS DATAFLOW 16 | 17 | fork< 18 | FORK_BATCH_SIZE, 19 | FORK_ROWS, 20 | FORK_COLS, 21 | FORK_CHANNELS, 22 | FORK_COARSE, 23 | #if (FORK_KERNEL_SIZE_0 > 1) || (FORK_KERNEL_SIZE_1 > 1) 24 | FORK_KERNEL_SIZE_0, 25 | FORK_KERNEL_SIZE_1, 26 | #endif 27 | fork_t 28 | >(in,out); 29 | 30 | } 31 | -------------------------------------------------------------------------------- /fpgaconvnet/hls/generate/modules/glue.py: -------------------------------------------------------------------------------- 1 | glue_template=""" 2 | {indent}glue< 3 | {indent} {NAME}_BATCH_SIZE, 4 | {indent} {NAME}_ROWS, 5 | {indent} {NAME}_COLS, 6 | {indent} {NAME}_FILTERS, 7 | {indent} {NAME}_COARSE_IN, 8 | {indent} {NAME}_COARSE_OUT, 9 | {indent} {NAME}_COARSE_GROUP, 10 | {indent} {acc_t}, 11 | {indent} {data_t} 12 | {indent}>({input_stream},{output_stream}); 13 | """ 14 | 15 | def gen_glue_module(name,input_stream,output_stream, 16 | acc_t="acc_t",data_t="data_t",indent=0): 17 | return glue_template.format( 18 | NAME =name.upper(), 19 | input_stream =input_stream, 20 | output_stream =output_stream, 21 | acc_t =acc_t, 22 | data_t =data_t, 23 | indent =" "*indent 24 | ) 25 | -------------------------------------------------------------------------------- /fpgaconvnet/hls/generate/modules/elementwise_add.py: -------------------------------------------------------------------------------- 1 | elementwise_add_template = """ 2 | {indent}elementwise_add< 3 | {indent} {NAME}_BATCH_SIZE, 4 | {indent} {NAME}_ROWS, 5 | {indent} {NAME}_COLS, 6 | {indent} {NAME}_CHANNELS, 7 | {indent} {elementwise_add_t} 8 | {indent}>({input_stream_1},{input_stream_2},{output_stream}); 9 | """ 10 | 11 | def gen_elementwise_add_module(name,input_stream_1,input_stream_2,output_stream, 12 | elementwise_add_t="data_t",indent=0): 13 | return elementwise_add_template.format( 14 | NAME =name.upper(), 15 | input_stream_1 =input_stream_1, 16 | input_stream_2 =input_stream_2, 17 | output_stream =output_stream, 18 | elementwise_add_t =elementwise_add_t, 19 | indent =" "*indent 20 | ) -------------------------------------------------------------------------------- /fpgaconvnet/hls/generate/modules/elementwise_mul.py: -------------------------------------------------------------------------------- 1 | elementwise_mul_template = """ 2 | {indent}elementwise_mul< 3 | {indent} {NAME}_BATCH_SIZE, 4 | {indent} {NAME}_ROWS, 5 | {indent} {NAME}_COLS, 6 | {indent} {NAME}_CHANNELS, 7 | {indent} {elementwise_mul_t} 8 | {indent}>({input_stream_1},{input_stream_2},{output_stream}); 9 | """ 10 | 11 | def gen_elementwise_mul_module(name,input_stream_1,input_stream_2,output_stream, 12 | elementwise_mul_t="data_t",indent=0): 13 | return elementwise_mul_template.format( 14 | NAME =name.upper(), 15 | input_stream_1 =input_stream_1, 16 | input_stream_2 =input_stream_2, 17 | output_stream =output_stream, 18 | elementwise_mul_t =elementwise_mul_t, 19 | indent =" "*indent 20 | ) -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish package 2 | 3 | on: 4 | push: 5 | branchs: 6 | - main 7 | 8 | jobs: 9 | deploy: 10 | runs-on: ubuntu-20.04 11 | steps: 12 | - uses: actions/checkout@main 13 | - name: Set up Python 3.10 14 | uses: actions/setup-python@v3 15 | with: 16 | python-version: "3.10" 17 | - name: Install pypa/build 18 | run: >- 19 | python -m 20 | pip install 21 | build 22 | --user 23 | - name: Build a binary wheel and a source tarball 24 | run: >- 25 | python -m 26 | build 27 | --sdist 28 | --wheel 29 | --outdir dist/ 30 | . 31 | - name: publish 32 | uses: pypa/gh-action-pypi-publish@release/v1 33 | with: 34 | password: ${{ secrets.PYPI_API_TOKEN }} 35 | -------------------------------------------------------------------------------- /test/modules/sliding_window/src/sliding_window.cpp: -------------------------------------------------------------------------------- 1 | #include "sliding_window_tb.hpp" 2 | #include "sliding_window.hpp" 3 | 4 | void sliding_window_top( 5 | stream_t(sliding_window_t) &in, 6 | stream_t(sliding_window_t) out[SLIDING_WINDOW_KERNEL_SIZE_0][SLIDING_WINDOW_KERNEL_SIZE_1] 7 | ) 8 | { 9 | #pragma HLS ARRAY_PARTITION variable=out complete dim=0 10 | #pragma HLS DATAFLOW 11 | 12 | sliding_window< 13 | SLIDING_WINDOW_BATCH_SIZE, 14 | SLIDING_WINDOW_ROWS, 15 | SLIDING_WINDOW_COLS, 16 | SLIDING_WINDOW_CHANNELS, 17 | SLIDING_WINDOW_PAD_TOP, 18 | SLIDING_WINDOW_PAD_RIGHT, 19 | SLIDING_WINDOW_PAD_BOTTOM, 20 | SLIDING_WINDOW_PAD_LEFT, 21 | SLIDING_WINDOW_STRIDE_0, 22 | SLIDING_WINDOW_STRIDE_1, 23 | SLIDING_WINDOW_KERNEL_SIZE_0, 24 | SLIDING_WINDOW_KERNEL_SIZE_1, 25 | sliding_window_t 26 | >(in,out); 27 | 28 | } 29 | -------------------------------------------------------------------------------- /fpgaconvnet/hls/generate/modules/sliding_window.py: -------------------------------------------------------------------------------- 1 | sliding_window_template = """ 2 | {indent}sliding_window< 3 | {indent} {NAME}_BATCH_SIZE, 4 | {indent} {NAME}_ROWS, 5 | {indent} {NAME}_COLS, 6 | {indent} {NAME}_CHANNELS, 7 | {indent} {NAME}_PAD_TOP, 8 | {indent} {NAME}_PAD_RIGHT, 9 | {indent} {NAME}_PAD_BOTTOM, 10 | {indent} {NAME}_PAD_LEFT, 11 | {indent} {NAME}_STRIDE_X, 12 | {indent} {NAME}_STRIDE_Y, 13 | {indent} {NAME}_KERNEL_SIZE_X, 14 | {indent} {NAME}_KERNEL_SIZE_Y, 15 | {indent} {sliding_window_t} 16 | {indent}>({input_stream},{output_stream}); 17 | """ 18 | def gen_sliding_window_module(name,input_stream,output_stream, 19 | sliding_window_t="data_t",indent=0): 20 | return sliding_window_template.format( 21 | NAME =name.upper(), 22 | input_stream =input_stream, 23 | output_stream =output_stream, 24 | sliding_window_t=sliding_window_t, 25 | indent =" "*indent 26 | ) 27 | 28 | -------------------------------------------------------------------------------- /test/modules/conv/src/conv.cpp: -------------------------------------------------------------------------------- 1 | #include "conv_tb.hpp" 2 | #include "conv.hpp" 3 | 4 | void conv_top( 5 | stream_t(conv_data_t) in[CONV_KERNEL_SIZE_0][CONV_KERNEL_SIZE_1], 6 | conv_weight_t weights[CONV_CHANNELS*DIVIDE(CONV_FILTERS,CONV_GROUPS)][CONV_KERNEL_SIZE_0][CONV_KERNEL_SIZE_1], 7 | stream_t(conv_acc_t) &out 8 | ) 9 | { 10 | 11 | #pragma HLS DATAFLOW 12 | #pragma HLS RESOURCE variable=weights core=ROM_2P_BRAM 13 | 14 | conv< 15 | CONV_BATCH_SIZE, 16 | CONV_ROWS, 17 | CONV_COLS, 18 | CONV_CHANNELS, 19 | CONV_FILTERS, 20 | CONV_GROUPS, 21 | #if (CONV_KERNEL_SIZE_0 > 1) || (CONV_KERNEL_SIZE_1 > 1) 22 | CONV_FINE, 23 | CONV_KERNEL_SIZE_0, 24 | CONV_KERNEL_SIZE_1, 25 | #endif 26 | conv_data_t, 27 | conv_weight_t, 28 | conv_acc_t 29 | #if (CONV_KERNEL_SIZE_0 == 1) && (CONV_KERNEL_SIZE_1 == 1) 30 | >(in[0][0],weights,out); 31 | #else 32 | >(in,weights,out); 33 | #endif 34 | 35 | } 36 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | **/*.log 3 | **/*.init.h 4 | **/*.config.h 5 | **/__pycache__/ 6 | **.pyc 7 | .vscode/ 8 | **.jou 9 | **.onnx 10 | **.str 11 | **.egg-info/ 12 | 13 | **/*_prj/ 14 | _prj/ 15 | 16 | data/ 17 | **.bin 18 | **.csv 19 | **.yaml 20 | rpt/ 21 | 22 | runs/**/logs/ 23 | runs/**.json 24 | runs/**/*_param.hpp 25 | 26 | outputs/ 27 | data/inputs/ 28 | data/weights/ 29 | 30 | test/modules/**/tb/*_param.hpp 31 | 32 | test/layers/**/src/*_layer.cpp 33 | test/layers/**/include/* 34 | test/layers/**/tb/*_param.hpp 35 | 36 | test/networks/**/partition_* 37 | 38 | host/.metadata 39 | host/.sdk 40 | host/fpgaconvnet_bsp/ps7_cortexa9_0 41 | 42 | onnx/ 43 | 44 | **REPORT.md 45 | 46 | include/system.hpp 47 | 48 | examples/**/outputs/ 49 | examples/**/partition_*/ 50 | 51 | test/partitions/**/outputs/ 52 | test/partitions/**/partition_*/ 53 | test/partitions/**/*.onnx 54 | 55 | sd_card/ 56 | partition_*/ 57 | 58 | fpgaconvnet/hls/hardware/system.hpp 59 | **/build/** 60 | /test/**/*.json 61 | /test/**/*.toml 62 | -------------------------------------------------------------------------------- /fpgaconvnet/hls/generate/modules/module.py: -------------------------------------------------------------------------------- 1 | 2 | class GenerateModule: 3 | 4 | def create_top_includes(self): 5 | includes = [ 6 | f"#define {self.name.upper()}_{var.upper()} {self.__dict__[var]}" \ 7 | for var in self.__dict__ ] 8 | return includes 9 | 10 | def create_top_function(self, io, module): 11 | # create arguments for top level source 12 | args = [] 13 | for name in io: 14 | if len(io[name]) == 0: 15 | args += [f"stream_t(data_t) &{name}"] 16 | else: 17 | dim = "][".join(io[name]) 18 | args += [f"stream_t(data_t) {name}[{dim}]"] 19 | args = ",\n\t".join(args) 20 | 21 | # interface pragma 22 | interface_pragma = "\n".join([ 23 | f"\t#pragma HLS INTERFACE axis port={name}" for name in io]) 24 | 25 | # create function 26 | return f""" 27 | void {self.name}_top( 28 | \t{args} 29 | ) {{ 30 | 31 | {interface_pragma} 32 | 33 | \t#pragma HLS DATAFLOW 34 | 35 | {module} 36 | 37 | }} 38 | """ 39 | -------------------------------------------------------------------------------- /test/modules/mem_read/gen_data.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import numpy as np 3 | import math 4 | 5 | sys.path.append('..') 6 | 7 | from Data import Data 8 | 9 | class MemReadTB(Data): 10 | def __init__(self): 11 | Data.__init__(self,'mem_read') 12 | 13 | # update stimulus generation 14 | def gen_stimulus(self): 15 | # data in 16 | data_in = self.gen_data([ 17 | self.param['rows_in'], 18 | self.param['cols_in'], 19 | self.param['channels_in'] 20 | ]) 21 | # latency 22 | latency = self.param['rows_in']*self.param['cols_in']*int(self.param['channels_in']/self.param["streams_in"]) 23 | # return data 24 | data = { 25 | 'data' : data_in.reshape(-1).tolist(), 26 | } 27 | # resource and latency model 28 | model = { 29 | 'latency' : latency, 30 | 'resources' : {"BRAM" : 0, "DSP" : 0, "LUT" : 0, "FF" : 0} 31 | } 32 | return data, model 33 | 34 | if __name__ == '__main__': 35 | mem_read_tb = MemReadTB() 36 | mem_read_tb.main(sys.argv[1:]) 37 | 38 | -------------------------------------------------------------------------------- /test/networks/tfc/run_test.py: -------------------------------------------------------------------------------- 1 | import onnx 2 | import numpy as np 3 | from PIL import Image 4 | 5 | from fpgaconvnet.hls.generate.network import GenerateNetwork 6 | 7 | import fpgaconvnet.tools.onnx_helper as onnx_helper 8 | 9 | # create instance of the network 10 | net = GenerateNetwork("tfc", "tfc.json", "tfc.onnx") 11 | 12 | # load test data 13 | input_image = Image.open("../mnist_example.png") 14 | 15 | # transform image 16 | # input_image = input_image.resize((224, 224), Image.ANTIALIAS) 17 | 18 | # to a numpy array 19 | input_image = np.array(input_image, dtype=np.float32) 20 | 21 | # flatten to 1 dimension 22 | input_image = input_image.flatten() 23 | 24 | # normalise 25 | input_image = input_image/np.linalg.norm(input_image) 26 | 27 | # duplicate across batch size 28 | input_image = np.stack([input_image for _ in range(1)], axis=0 ) 29 | 30 | # create project for first partition 31 | net.create_partition_project(0) 32 | 33 | # run the partition's testbench 34 | net.run_testbench(0, input_image) 35 | 36 | # generate hardware 37 | net.generate_partition_hardware(0) 38 | 39 | # run co-simulation 40 | net.run_cosimulation(0, input_image) 41 | -------------------------------------------------------------------------------- /test/layers/batch_norm/src/batch_norm_layer_top.cpp: -------------------------------------------------------------------------------- 1 | #include "batch_norm_layer_tb.hpp" 2 | #include "batch_norm_layer.hpp" 3 | 4 | const static data_t scale[BATCH_NORM_LAYER_COARSE][CHANNELS_3D(BATCH_NORM_LAYER_CHANNELS,BATCH_NORM_LAYER_COARSE)] = { 5 | #include "scale.csv" 6 | }; 7 | 8 | const static data_t shift[BATCH_NORM_LAYER_COARSE][CHANNELS_3D(BATCH_NORM_LAYER_CHANNELS,BATCH_NORM_LAYER_COARSE)] = { 9 | #include "shift.csv" 10 | }; 11 | 12 | void batch_norm_layer_top( 13 | stream_t(data_t) in[BATCH_NORM_LAYER_COARSE_IN], 14 | stream_t(data_t) out[BATCH_NORM_LAYER_COARSE_OUT], 15 | int mode 16 | ) 17 | { 18 | #pragma HLS DATAFLOW 19 | 20 | //#pragma HLS INTERFACE axis port=in 21 | //#pragma HLS INTERFACE axis port=out 22 | #pragma HLS STREAM variable=in 23 | #pragma HLS STREAM variable=out 24 | 25 | DO_PRAGMA(HLS ARRAY_PARTITION variable=scale block factor=BATCH_NORM_LAYER_COARSE dim=1) 26 | #pragma HLS RESOURCE variable=scale core=RAM_2P_BRAM 27 | 28 | DO_PRAGMA(HLS ARRAY_PARTITION variable=shift block factor=BATCH_NORM_LAYER_COARSE dim=1) 29 | #pragma HLS RESOURCE variable=shift core=RAM_2P_BRAM 30 | 31 | batch_norm_layer(in,scale,shift,out,mode); 32 | 33 | } 34 | -------------------------------------------------------------------------------- /test/modules/mem_write/gen_data.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import numpy as np 3 | import math 4 | 5 | sys.path.append('..') 6 | 7 | from Data import Data 8 | 9 | class MemWriteTB(Data): 10 | def __init__(self): 11 | Data.__init__(self,'mem_write') 12 | 13 | # update stimulus generation 14 | def gen_stimulus(self): 15 | # data in 16 | data_out = self.gen_data([ 17 | self.param['weights_reloading_factor'], 18 | self.param['rows_out'], 19 | self.param['cols_out'], 20 | self.param['channels_out'] 21 | ]) 22 | # latency 23 | latency = self.param['rows_out']*self.param['cols_out']*int(self.param['channels_out']/self.param["streams_out"]) 24 | # return data 25 | data = { 26 | 'data' : data_out.reshape(-1).tolist(), 27 | } 28 | # resource and latency model 29 | model = { 30 | 'latency' : latency, 31 | 'resources' : {"BRAM" : 0, "DSP" : 0, "LUT" : 0, "FF" : 0} 32 | } 33 | return data, model 34 | 35 | if __name__ == '__main__': 36 | mem_write_tb = MemWriteTB() 37 | mem_write_tb.main(sys.argv[1:]) 38 | 39 | -------------------------------------------------------------------------------- /fpgaconvnet/hls/hardware/elementwise_mul.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ELEMENTWISE_MUL_HPP_ 2 | #define ELEMENTWISE_MUL_HPP_ 3 | 4 | #include "common.hpp" 5 | 6 | /** 7 | * ELEMENTWISE MUL FUNCTION 8 | */ 9 | template< 10 | unsigned int BATCH_SIZE, 11 | unsigned int ROWS, 12 | unsigned int COLS, 13 | unsigned int CHANNELS, 14 | typename elementwise_mul_t 15 | > 16 | void elementwise_mul( 17 | stream_t(elementwise_mul_t) &in1, 18 | stream_t(elementwise_mul_t) &in2, 19 | stream_t(elementwise_mul_t) &out 20 | ) 21 | { 22 | #pragma HLS INLINE OFF 23 | 24 | const unsigned int batch_size = BATCH_SIZE; 25 | const unsigned int rows = ROWS; 26 | const unsigned int cols = COLS; 27 | const unsigned int channels = CHANNELS; 28 | 29 | #pragma HLS STREAM variable=in1 30 | #pragma HLS STREAM variable=in2 31 | #pragma HLS STREAM variable=out 32 | 33 | for(unsigned long pixel_index=0 ; pixel_index < batch_size*rows*cols*channels ; pixel_index++) { 34 | #pragma HLS PIPELINE II=1 rewind 35 | elementwise_mul_t tmp1 = in1.read(); 36 | elementwise_mul_t tmp2 = in2.read(); 37 | out.write(tmp1 * tmp2); 38 | } 39 | } 40 | 41 | #endif -------------------------------------------------------------------------------- /fpgaconvnet/hls/hardware/elementwise_add.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ELEMENTWISE_ADD_HPP_ 2 | #define ELEMENTWISE_ADD_HPP_ 3 | 4 | #include "common.hpp" 5 | 6 | /** 7 | * ELEMENTWISE ADD FUNCTION 8 | */ 9 | template< 10 | unsigned int BATCH_SIZE, 11 | unsigned int ROWS, 12 | unsigned int COLS, 13 | unsigned int CHANNELS, 14 | typename elementwise_add_t 15 | > 16 | void elementwise_add( 17 | stream_t(elementwise_add_t) &in1, 18 | stream_t(elementwise_add_t) &in2, 19 | stream_t(elementwise_add_t) &out 20 | ) 21 | { 22 | 23 | #pragma HLS INLINE OFF 24 | 25 | const unsigned int batch_size = BATCH_SIZE; 26 | const unsigned int rows = ROWS; 27 | const unsigned int cols = COLS; 28 | const unsigned int channels = CHANNELS; 29 | 30 | #pragma HLS STREAM variable=in1 31 | #pragma HLS STREAM variable=in2 32 | #pragma HLS STREAM variable=out 33 | 34 | for(unsigned long pixel_index=0 ; pixel_index < batch_size*rows*cols*channels ; pixel_index++) { 35 | #pragma HLS PIPELINE II=1 rewind 36 | elementwise_add_t tmp1 = in1.read(); 37 | elementwise_add_t tmp2 = in2.read(); 38 | out.write(tmp1 + tmp2); 39 | } 40 | } 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /test/modules/mem_write/src/mem_write.cpp: -------------------------------------------------------------------------------- 1 | #include "mem_write_tb.hpp" 2 | #include "mem_write.hpp" 3 | 4 | void mem_write_top( 5 | int weights_reloading_index, 6 | stream_t(data_t) out[MEM_WRITE_STREAMS_OUT], 7 | volatile mem_int out_hw[MEM_WRITE_PORTS_OUT][MEM_WRITE_BATCH_SIZE*MEM_WRITE_ROWS_OUT*MEM_WRITE_COLS_OUT*DIVIDE(MEM_WRITE_CHANNELS_OUT,MEM_WRITE_STREAMS_OUT)*MEM_WRITE_WEIGHTS_RELOADING_FACTOR] 8 | ) 9 | { 10 | #pragma HLS INTERFACE axis port=out 11 | 12 | const unsigned size_out = MEM_WRITE_BATCH_SIZE*MEM_WRITE_ROWS_OUT*MEM_WRITE_COLS_OUT*DIVIDE(MEM_WRITE_CHANNELS_OUT,MEM_WRITE_STREAMS_OUT)*MEM_WRITE_WEIGHTS_RELOADING_FACTOR; 13 | DO_PRAGMA( HLS INTERFACE m_axi port=out_hw depth=size_out num_write_outstanding=1 max_write_burst_length=256) 14 | #pragma HLS ARRAY_PARTITION variable=out_hw complete dim=1 15 | 16 | #pragma HLS DATAFLOW 17 | mem_write< 18 | MEM_WRITE_BATCH_SIZE, 19 | MEM_WRITE_ROWS_OUT, 20 | MEM_WRITE_COLS_OUT, 21 | MEM_WRITE_CHANNELS_OUT, 22 | MEM_WRITE_PORTS_OUT, 23 | MEM_WRITE_STREAMS_OUT, 24 | MEM_WRITE_WEIGHTS_RELOADING_FACTOR, 25 | data_t 26 | >(weights_reloading_index, out, out_hw); 27 | } 28 | 29 | -------------------------------------------------------------------------------- /test/partitions/single_layer/run_test.py: -------------------------------------------------------------------------------- 1 | from google.protobuf import json_format 2 | 3 | import fpgaconvnet.proto.fpgaconvnet_pb2 4 | import fpgaconvnet.tools.onnx_helper as onnx_helper 5 | 6 | from fpgaconvnet.hls.generate.partition import GeneratePartition 7 | from fpgaconvnet.hls.tools.onnx_data import ONNXData 8 | 9 | # load partition info 10 | partitions = fpgaconvnet.proto.fpgaconvnet_pb2.partitions() 11 | with open("single_layer.json", "r") as f: 12 | json_format.Parse(f.read(), partitions) 13 | partition = partitions.partition[0] 14 | 15 | # load onnx_data for this partition 16 | onnx_data = ONNXData(partition, "single_layer.onnx") 17 | 18 | # create partition generator 19 | single_layer = GeneratePartition("single_layer", partition, onnx_data, "partition_0") 20 | 21 | # generate each part of the partition 22 | single_layer.generate_layers() 23 | single_layer.generate_weights() 24 | single_layer.generate_streams() 25 | single_layer.generate_include() 26 | single_layer.generate_source() 27 | single_layer.generate_testbench() 28 | 29 | # create HLS project 30 | single_layer.create_vivado_hls_project() 31 | 32 | # run c-synthesis 33 | single_layer.run_csynth() 34 | 35 | # export design 36 | single_layer.export_design() 37 | 38 | -------------------------------------------------------------------------------- /test/networks/single_layer/run_test.py: -------------------------------------------------------------------------------- 1 | import onnx 2 | import numpy as np 3 | from PIL import Image 4 | 5 | from fpgaconvnet.hls.generate.network import GenerateNetwork 6 | 7 | from fpgaconvnet.parser import Parser 8 | import fpgaconvnet.parser.onnx.helper as onnx_helper 9 | 10 | 11 | # create instance of the network 12 | net = GenerateNetwork("single_layer", "single_layer.json", "single_layer.onnx") 13 | 14 | # load test data 15 | input_image = Image.open("../mnist_example.png") 16 | 17 | # transform image 18 | # input_image = input_image.resize((224, 224), Image.ANTIALIAS) 19 | 20 | # to a numpy array 21 | input_image = np.array(input_image, dtype=np.float32) 22 | 23 | # add channel dimension 24 | input_image = np.expand_dims(input_image, axis=0) 25 | 26 | # normalise 27 | input_image = input_image/np.linalg.norm(input_image) 28 | 29 | # duplicate across batch size 30 | input_image = np.stack([input_image for _ in range(1)], axis=0 ) 31 | 32 | # create project for first partition 33 | net.create_partition_project(0) 34 | 35 | # # run the partition's testbench 36 | # net.run_testbench(0, input_image) 37 | 38 | # generate hardware 39 | net.generate_partition_hardware(0) 40 | 41 | # run co-simulation 42 | net.run_cosimulation(0, input_image) 43 | -------------------------------------------------------------------------------- /fpgaconvnet/hls/hardware/fifo.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FIFO_HPP_ 2 | #define FIFO_HPP_ 3 | 4 | #include "common.hpp" 5 | 6 | template< 7 | unsigned int COARSE, 8 | unsigned int DEPTH 9 | > 10 | void fifo( 11 | stream_t(data_t) in[COARSE], 12 | stream_t(data_t) out[COARSE] 13 | ) 14 | { 15 | 16 | #pragma HLS INLINE OFF 17 | #pragma HLS DATAFLOW 18 | 19 | const unsigned int coarse = COARSE; 20 | const unsigned int fifo_depth = DEPTH; 21 | 22 | #pragma HLS STREAM variable=in depth=1 23 | #pragma HLS STREAM variable=out depth=1 24 | 25 | #pragma HLS ARRAY_PARTITION variable=in complete dim=0 26 | #pragma HLS ARRAY_PARTITION variable=out complete dim=0 27 | 28 | stream_t(data_t) stream_fifo[coarse]; 29 | DO_PRAGMA(HLS STREAM variable=stream_fifo depth=fifo_depth) 30 | #pragma HLS ARRAY_PARTITION variable=stream_fifo complete dim=0 31 | 32 | 33 | in_loop: for (unsigned int in_index = 0; in_index < coarse; in_index++) { 34 | #pragma HLS unroll 35 | stream_fifo[in_index].write(in[in_index].read()); 36 | } 37 | 38 | out_loop: for (unsigned int out_index = 0; out_index < coarse; out_index++) { 39 | #pragma HLS unroll 40 | out[out_index].write(stream_fifo[out_index].read()); 41 | } 42 | } 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /test/modules/relu/run_test.tcl: -------------------------------------------------------------------------------- 1 | open_project -reset relu_test_prj 2 | 3 | if { $argc < 3 } { 4 | 5 | puts "ERROR: need to specify test" 6 | exit 7 | 8 | } else { 9 | 10 | set TEST [lindex $argv 2] 11 | 12 | exec python3 gen_relu.py -c config/config_$TEST.json 13 | 14 | puts "TEST $TEST chosen" 15 | set_top relu_top 16 | add_files src/relu.cpp -cflags "-I../../include -I./tb" 17 | add_files -tb tb/relu_tb.cpp -cflags "-I../../include -I./tb -lyaml-cpp" 18 | 19 | open_solution -reset "solution1" 20 | set_part {xc7z020clg484-1} -tool vivado 21 | create_clock -period 20 -name default 22 | 23 | if { [lindex $argv 3] == "sim" } { 24 | 25 | csim_design -compiler gcc 26 | exit 27 | 28 | } elseif { [lindex $argv 3] == "synth" } { 29 | 30 | csim_design -compiler gcc 31 | csynth_design 32 | exit 33 | 34 | } elseif { [lindex $argv 3] == "cosim" } { 35 | 36 | csim_design -compiler gcc 37 | csynth_design 38 | cosim_design 39 | exit 40 | 41 | } else { 42 | 43 | csim_design -compiler gcc 44 | csynth_design 45 | cosim_design 46 | export_design -flow syn -rtl verilog -format ip_catalog 47 | exit 48 | 49 | } 50 | 51 | } 52 | 53 | exit 54 | -------------------------------------------------------------------------------- /test/modules/relu/tb/relu_tb.cpp: -------------------------------------------------------------------------------- 1 | #include "common_tb.hpp" 2 | #include "relu_tb.hpp" 3 | 4 | int main() 5 | { 6 | 7 | int err = 0; 8 | std::string input_path = std::string(DATA_DIR)+"/input.dat"; 9 | std::string output_path = std::string(DATA_DIR)+"/output.dat"; 10 | 11 | // in/out streams 12 | stream_t(relu_t) in; 13 | stream_t(relu_t) out; 14 | stream_t(relu_t) out_valid; 15 | 16 | // test inputs data 17 | static relu_t test_in[RELU_ROWS*RELU_COLS*RELU_CHANNELS]; 18 | static relu_t test_out[RELU_ROWS*RELU_COLS*RELU_CHANNELS]; 19 | 20 | // load data_in 21 | load_data< 22 | RELU_ROWS*RELU_COLS*RELU_CHANNELS, 23 | relu_t 24 | >(input_path,test_in); 25 | 26 | // load data_out 27 | load_data< 28 | RELU_ROWS*RELU_COLS*RELU_CHANNELS, 29 | relu_t 30 | >(output_path,test_out); 31 | 32 | // convert input stream 33 | to_stream< 34 | RELU_ROWS*RELU_COLS*RELU_CHANNELS, 35 | relu_t 36 | >(test_in,in); 37 | 38 | // convert to out valid stream 39 | to_stream< 40 | RELU_ROWS*RELU_COLS*RELU_CHANNELS, 41 | relu_t 42 | >(test_out,out_valid); 43 | 44 | // run relu 45 | relu_top(in,out); 46 | 47 | err += checkStreamEqual(out,out_valid,false); 48 | 49 | return err; 50 | } 51 | -------------------------------------------------------------------------------- /fpgaconvnet/hls/hardware/batch_norm.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BATCH_NORM_HPP_ 2 | #define BATCH_NORM_HPP_ 3 | 4 | #include "common.hpp" 5 | 6 | /** 7 | * BATCH NORMALIZATION + SCALE FUNCTION 8 | */ 9 | 10 | template 11 | void NAME_SUB(name,_batch_norm)( 12 | stream_t(data_t) &in, 13 | const data_t scale[NAME_SUB(MODULE_NAME,_CHANNELS)], 14 | const data_t shift[NAME_SUB(MODULE_NAME,_CHANNELS)], 15 | stream_t(data_t) &out 16 | ) 17 | { 18 | 19 | #pragma HLS INLINE OFF 20 | 21 | const unsigned batch_size = NAME_SUB(MODULE_NAME,_BATCH_SIZE); 22 | const unsigned rows = NAME_SUB(MODULE_NAME,_ROWS); 23 | const unsigned cols = NAME_SUB(MODULE_NAME,_COLS); 24 | const unsigned channels = NAME_SUB(MODULE_NAME,_CHANNELS); 25 | 26 | #pragma HLS STREAM variable=in 27 | #pragma HLS STREAM variable=out 28 | 29 | pixel_loop: for(unsigned pixel_index=0;pixel_index=3.8) 12 | 13 | Once these programs are installed, you can setup the project from pypi: 14 | 15 | ``` 16 | python -m pip install fpgaconvnet-hls 17 | ``` 18 | 19 | ## Usage 20 | 21 | You can see example usage in the `tests/networks` folder as well as in the [fpgaconvnet-tutorial](https://github.com/AlexMontgomerie/fpgaconvnet-tutorial) repository. Below is a quick example of how a configuration can be loaded and used to generate and test hardware. 22 | 23 | ```python 24 | from fpgaconvnet.hls.generate.network import GenerateNetwork 25 | 26 | # create instance of the network 27 | gen_net = GenerateNetwork("model-name", "model-config.json", "model.onnx") 28 | 29 | # generate hardware and create HLS project for partition 0 30 | gen_net.create_partition_project(0) 31 | 32 | # run HLS synthesis for partition 0 33 | gen_net.generate_partition_hardware(0) 34 | ``` 35 | 36 | --- 37 | 38 | Please feel free to ask questions or post any issues! 39 | -------------------------------------------------------------------------------- /test/modules/mem_read/src/mem_read.cpp: -------------------------------------------------------------------------------- 1 | #include "mem_read_tb.hpp" 2 | #include "mem_read.hpp" 3 | 4 | void mem_read_top( 5 | volatile mem_int in_hw[MEM_READ_PORTS_IN][MEM_READ_BATCH_SIZE*MEM_READ_ROWS_IN*MEM_READ_COLS_IN*DIVIDE(MEM_READ_CHANNELS_IN,MEM_READ_STREAMS_IN)], 6 | stream_t(data_t) in[MEM_READ_STREAMS_IN] 7 | ) 8 | { 9 | const int size_in = MEM_READ_BATCH_SIZE*MEM_READ_ROWS_IN*MEM_READ_COLS_IN*DIVIDE(MEM_READ_CHANNELS_IN,MEM_READ_STREAMS_IN); 10 | //DO_PRAGMA( HLS INTERFACE m_axi port=in_hw[0] depth=size_in num_read_outstanding=1 max_read_burst_length=256) 11 | DO_PRAGMA( HLS INTERFACE m_axi port=in_hw depth=size_in num_read_outstanding=1 max_read_burst_length=256) 12 | #pragma HLS ARRAY_PARTITION variable=in_hw complete dim=1 13 | //DO_PRAGMA( HLS INTERFACE m_axi port=in_hw_1 depth=size_in num_read_outstanding=1 max_read_burst_length=256) 14 | //DO_PRAGMA( HLS INTERFACE m_axi port=in_hw_2 depth=size_in num_read_outstanding=1 max_read_burst_length=256) 15 | //DO_PRAGMA( HLS INTERFACE m_axi port=in_hw_3 depth=size_in num_read_outstanding=1 max_read_burst_length=256) 16 | #pragma HLS INTERFACE axis port=in 17 | 18 | #pragma HLS DATAFLOW 19 | mem_read< 20 | MEM_READ_BATCH_SIZE, 21 | MEM_READ_ROWS_IN, 22 | MEM_READ_COLS_IN, 23 | MEM_READ_CHANNELS_IN, 24 | MEM_READ_PORTS_IN, 25 | MEM_READ_STREAMS_IN, 26 | data_t 27 | >(in_hw,in); 28 | } 29 | 30 | -------------------------------------------------------------------------------- /test/modules/relu/gen_data.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | 4 | sys.path.append('..') 5 | 6 | from fpgaconvnet.models.modules.ReLU import ReLU 7 | from Data import Data 8 | 9 | class ReLUTB(Data): 10 | def __init__(self): 11 | Data.__init__(self,'relu') 12 | 13 | # update stimulus generation 14 | def gen_stimulus(self): 15 | 16 | # Init Module 17 | relu = ReLU( 18 | self.param['rows'], 19 | self.param['cols'], 20 | self.param['channels'] 21 | ) 22 | 23 | # add parameters 24 | self.param['data_width'] = relu.data_width 25 | self.param['data_int_width'] = relu.data_width//2 26 | 27 | # data in 28 | data_in = self.gen_data([ 29 | self.param['rows'], 30 | self.param['cols'], 31 | self.param['channels'] 32 | ]) 33 | 34 | # data out 35 | data_out = relu.functional_model(data_in) 36 | 37 | # return data 38 | data = { 39 | 'input' : data_in.reshape(-1).tolist(), 40 | 'output' : data_out.reshape(-1).tolist() 41 | } 42 | 43 | # resource and latency model 44 | model = { 45 | 'latency' : relu.latency(), 46 | 'resources' : relu.rsc() 47 | } 48 | 49 | return data, model 50 | 51 | if __name__ == '__main__': 52 | relu_tb = ReLUTB() 53 | relu_tb.main(sys.argv[1:]) 54 | 55 | -------------------------------------------------------------------------------- /test/modules/accum/tb/accum_tb.cpp: -------------------------------------------------------------------------------- 1 | #include "common_tb.hpp" 2 | #include "accum_tb.hpp" 3 | 4 | int main() 5 | { 6 | int err = 0; 7 | 8 | std::string input_path = std::string(DATA_DIR)+"/input.dat"; 9 | std::string output_path = std::string(DATA_DIR)+"/output.dat"; 10 | 11 | stream_t(test_accum_t) in; 12 | stream_t(test_accum_t) out; 13 | 14 | stream_t(test_accum_t) out_valid; 15 | 16 | static test_accum_t test_in[(int)(ACCUM_ROWS*ACCUM_COLS*ACCUM_CHANNELS*ACCUM_FILTERS/ACCUM_GROUPS)]; 17 | static test_accum_t test_out[ACCUM_ROWS*ACCUM_COLS*ACCUM_FILTERS]; 18 | 19 | // load data_in 20 | load_data< 21 | (int)(ACCUM_ROWS*ACCUM_COLS*ACCUM_CHANNELS*ACCUM_FILTERS/ACCUM_GROUPS), 22 | test_accum_t 23 | >(input_path,test_in); 24 | 25 | // load data_out 26 | load_data< 27 | ACCUM_ROWS*ACCUM_COLS*ACCUM_FILTERS, 28 | test_accum_t 29 | >(output_path,test_out); 30 | 31 | // convert input stream 32 | to_stream< 33 | (int)(ACCUM_ROWS*ACCUM_COLS*ACCUM_CHANNELS*ACCUM_FILTERS/ACCUM_GROUPS), 34 | test_accum_t 35 | >(test_in,in); 36 | 37 | // convert to out valid stream 38 | to_stream< 39 | ACCUM_ROWS*ACCUM_COLS*ACCUM_FILTERS, 40 | test_accum_t 41 | >(test_out,out_valid); 42 | 43 | // run conv 44 | accum_top(in,out); 45 | 46 | // check output 47 | err += checkStreamEqual(out,out_valid); 48 | 49 | return err; 50 | } 51 | -------------------------------------------------------------------------------- /test/modules/global_pool/tb/global_pool_tb.cpp: -------------------------------------------------------------------------------- 1 | #include "common_tb.hpp" 2 | #include "global_pool_tb.hpp" 3 | 4 | int main() 5 | { 6 | int err = 0; 7 | 8 | // file paths 9 | std::string input_path = std::string(DATA_DIR)+"/input.dat"; 10 | std::string output_path = std::string(DATA_DIR)+"/output.dat"; 11 | 12 | // in/out streams 13 | stream_t(global_pool_t) in; 14 | stream_t(global_pool_t) out; 15 | stream_t(global_pool_t) out_valid; 16 | 17 | static global_pool_t test_in[GLOBAL_POOL_ROWS*GLOBAL_POOL_COLS*GLOBAL_POOL_CHANNELS]; 18 | static global_pool_t test_out[GLOBAL_POOL_CHANNELS]; 19 | 20 | // load data_in 21 | load_data< 22 | GLOBAL_POOL_ROWS*GLOBAL_POOL_COLS*GLOBAL_POOL_CHANNELS, 23 | global_pool_t 24 | >(input_path,test_in); 25 | 26 | // load data_out 27 | load_data< 28 | GLOBAL_POOL_CHANNELS, 29 | global_pool_t 30 | >(output_path,test_out); 31 | 32 | // convert input stream 33 | to_stream< 34 | GLOBAL_POOL_ROWS*GLOBAL_POOL_COLS*GLOBAL_POOL_CHANNELS, 35 | global_pool_t 36 | >(test_in,in); 37 | 38 | // convert to out valid stream 39 | to_stream< 40 | GLOBAL_POOL_CHANNELS, 41 | global_pool_t 42 | >(test_out,out_valid); 43 | 44 | // run global_pool 45 | global_pool_top(in,out); 46 | 47 | // check the stream is correct 48 | err += checkStreamEqual(out,out_valid,false); 49 | 50 | return err; 51 | } -------------------------------------------------------------------------------- /test/layers/convolution/src/convolution_layer_top.cpp: -------------------------------------------------------------------------------- 1 | #include "convolution_layer_tb.hpp" 2 | #include "convolution_layer.hpp" 3 | 4 | void convolution_layer_top( 5 | stream_t(convolution_layer_input_t) in[CONVOLUTION_LAYER_COARSE_IN], 6 | stream_t(convolution_layer_output_t) out[CONVOLUTION_LAYER_COARSE_OUT], 7 | int mode 8 | ) 9 | { 10 | #pragma HLS DATAFLOW 11 | const static convolution_layer_weight_t weights[CONVOLUTION_LAYER_COARSE_IN][CONVOLUTION_LAYER_COARSE_OUT][DIVIDE(CONVOLUTION_LAYER_CHANNELS,CONVOLUTION_LAYER_COARSE_IN)*DIVIDE(CONVOLUTION_LAYER_FILTERS,CONVOLUTION_LAYER_COARSE_OUT*CONVOLUTION_LAYER_GROUPS)][CONVOLUTION_LAYER_KERNEL_SIZE_X][CONVOLUTION_LAYER_KERNEL_SIZE_Y] = { 12 | #include "weights.csv" 13 | }; 14 | 15 | const static convolution_layer_biases_t biases[CONVOLUTION_LAYER_COARSE_OUT][DIVIDE(CONVOLUTION_LAYER_FILTERS,CONVOLUTION_LAYER_COARSE_OUT)] = { 16 | #include "biases.csv" 17 | }; 18 | 19 | 20 | #pragma HLS STREAM variable=in 21 | #pragma HLS STREAM variable=out 22 | 23 | #pragma HLS ARRAY_PARTITION variable=weights complete dim=1 24 | #pragma HLS ARRAY_PARTITION variable=weights complete dim=2 25 | #pragma HLS RESOURCE variable=weights core=RAM 26 | #pragma HLS STABLE variable=weights 27 | 28 | #pragma HLS ARRAY_PARTITION variable=biases complete dim=1 29 | #pragma HLS RESOURCE variable=biases core=RAM 30 | #pragma HLS STABLE variable=biases 31 | 32 | convolution_layer(weights,biases,in,out,mode); 33 | 34 | } 35 | -------------------------------------------------------------------------------- /test/layers/inner_product/src/inner_product_layer_top.cpp: -------------------------------------------------------------------------------- 1 | #include "inner_product_layer_tb.hpp" 2 | #include "inner_product_layer.hpp" 3 | 4 | void inner_product_layer_top( 5 | stream_t(inner_product_layer_input_t) in[INNER_PRODUCT_LAYER_COARSE_IN], 6 | stream_t(inner_product_layer_output_t) out[INNER_PRODUCT_LAYER_COARSE_OUT], 7 | int mode 8 | ) 9 | { 10 | #pragma HLS DATAFLOW 11 | 12 | #pragma HLS STREAM variable=in 13 | #pragma HLS STREAM variable=out 14 | 15 | const static inner_product_layer_weight_t weights[INNER_PRODUCT_LAYER_COARSE_IN][INNER_PRODUCT_LAYER_COARSE_OUT][DIVIDE(INNER_PRODUCT_LAYER_ROWS*INNER_PRODUCT_LAYER_COLS*INNER_PRODUCT_LAYER_CHANNELS,INNER_PRODUCT_LAYER_COARSE_IN)*DIVIDE(INNER_PRODUCT_LAYER_FILTERS,INNER_PRODUCT_LAYER_COARSE_OUT)][1][1] = { 16 | #include "weights.csv" 17 | }; 18 | 19 | #pragma HLS ARRAY_PARTITION variable=weights complete dim=1 20 | #pragma HLS ARRAY_PARTITION variable=weights complete dim=2 21 | #pragma HLS RESOURCE variable=weights core=RAM 22 | 23 | #if INNER_PRODUCT_LAYER_HAS_BIAS == 1 24 | const static inner_product_layer_biases_t biases[INNER_PRODUCT_LAYER_COARSE_OUT][DIVIDE(INNER_PRODUCT_LAYER_FILTERS, INNER_PRODUCT_LAYER_COARSE_OUT)] = { 25 | #include "biases.csv" 26 | }; 27 | 28 | #pragma HLS ARRAY_PARTITION variable=biases complete dim=1 29 | #pragma HLS RESOURCE variable=biases core=RAM 30 | #endif 31 | 32 | inner_product_layer( 33 | weights, 34 | #if INNER_PRODUCT_LAYER_HAS_BIAS == 1 35 | biases, 36 | #endif 37 | in,out,mode); 38 | 39 | } 40 | -------------------------------------------------------------------------------- /test/modules/global_pool/gen_data.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | sys.path.append('..') 4 | 5 | from fpgaconvnet.models.modules.GlobalPool import GlobalPool 6 | from Data import Data 7 | 8 | class GlobalPoolTB(Data): 9 | def __init__(self): 10 | Data.__init__(self,'global_pool') 11 | 12 | # update stimulus generation 13 | def gen_stimulus(self): 14 | 15 | # Init Module 16 | global_pool = GlobalPool( 17 | self.param['rows'], 18 | self.param['cols'], 19 | self.param['channels'] 20 | ) 21 | 22 | # add parameters 23 | self.param['data_width'] = global_pool.data_width 24 | self.param['data_int_width'] = global_pool.data_width//2 25 | 26 | # data in 27 | data_in = self.gen_data([ 28 | self.param['rows'], 29 | self.param['cols'], 30 | self.param['channels'] 31 | ]) 32 | 33 | data_out = global_pool.functional_model(data_in) 34 | 35 | # return data 36 | data = { 37 | 'input' : data_in.reshape(-1).tolist(), 38 | 'output' : data_out.reshape(-1).tolist() 39 | } 40 | 41 | # resource and latency model 42 | model = { 43 | 'latency' : global_pool.latency(), 44 | 'resources' : global_pool.rsc() 45 | } 46 | 47 | return data, model 48 | 49 | if __name__ == '__main__': 50 | global_pool_tb = GlobalPoolTB() 51 | global_pool_tb.main(sys.argv[1:]) -------------------------------------------------------------------------------- /fpgaconvnet/hls/scripts/hls/create_partition_project.tcl: -------------------------------------------------------------------------------- 1 | # get the root directory 2 | variable fpgaconvnet_root [file dirname [file dirname [file dirname [file normalize [info script]]]]] 3 | 4 | # load getopt script 5 | source ${fpgaconvnet_root}/scripts/hls/tcl_getopt.tcl 6 | 7 | # get input arguments 8 | set hls_arg [ lindex $argv 2 ] 9 | 10 | # get arguments (arg) (variable) (defaults) 11 | getopt $hls_arg -prj project_path "" 12 | getopt $hls_arg -fpga fpga "xc7z045ffg900-2" 13 | getopt $hls_arg -clk clk_period "5" 14 | 15 | puts "project: ${project_path}" 16 | 17 | # default cflags 18 | set default_cflags "-std=c++11 -fexceptions -I${project_path}/include -I${project_path}/data \ 19 | -I${fpgaconvnet_root}/hardware -I${fpgaconvnet_root}/hardware/hlslib/include" 20 | 21 | # create open project 22 | open_project ${project_path} 23 | 24 | # set top function 25 | set_top fpgaconvnet_ip 26 | 27 | # add files to the project 28 | add_files [ glob ${project_path}/src/*.cpp ] -cflags "${default_cflags}" 29 | 30 | # add testbench file to the project 31 | add_files -tb [ glob ${project_path}/tb/*.cpp ] -cflags "${default_cflags}" 32 | 33 | # add any data files 34 | add_files -tb [ glob ${project_path}/data/*.dat ] 35 | 36 | # create the solution 37 | open_solution "solution" 38 | 39 | # set FPGA part 40 | set_part $fpga -tool vivado 41 | 42 | # set clock period 43 | create_clock -period $clk_period -name default 44 | 45 | # increase fifo depth 46 | config_dataflow -default_channel fifo -fifo_depth 2 47 | config_dataflow -strict_mode warning 48 | 49 | exit 50 | -------------------------------------------------------------------------------- /test/modules/pool/tb/pool_tb.cpp: -------------------------------------------------------------------------------- 1 | #include "common_tb.hpp" 2 | #include "pool_tb.hpp" 3 | 4 | int main() 5 | { 6 | 7 | int err = 0; 8 | 9 | // file paths 10 | std::string input_path = std::string(DATA_DIR)+"/input.dat"; 11 | std::string output_path = std::string(DATA_DIR)+"/output.dat"; 12 | 13 | // in/out streams 14 | stream_t(pool_t) in[POOL_KERNEL_SIZE_0][POOL_KERNEL_SIZE_1]; 15 | stream_t(pool_t) out; 16 | stream_t(pool_t) out_valid; 17 | 18 | // test inputs data 19 | static pool_t test_in[POOL_ROWS*POOL_COLS*POOL_CHANNELS][POOL_KERNEL_SIZE_0][POOL_KERNEL_SIZE_1]; 20 | static pool_t test_out[POOL_ROWS*POOL_COLS*POOL_CHANNELS]; 21 | 22 | // load data_in 23 | load_data< 24 | POOL_ROWS*POOL_COLS*POOL_CHANNELS, 25 | POOL_KERNEL_SIZE_0, 26 | POOL_KERNEL_SIZE_1, 27 | pool_t 28 | >(input_path,test_in); 29 | 30 | // load data_out 31 | load_data< 32 | POOL_ROWS*POOL_COLS*POOL_CHANNELS, 33 | pool_t 34 | >(output_path,test_out); 35 | 36 | // convert input stream 37 | to_stream< 38 | POOL_ROWS*POOL_COLS*POOL_CHANNELS, 39 | POOL_KERNEL_SIZE_0, 40 | POOL_KERNEL_SIZE_1, 41 | pool_t 42 | >(test_in,in); 43 | 44 | // convert to out valid stream 45 | to_stream< 46 | POOL_ROWS*POOL_COLS*POOL_CHANNELS, 47 | pool_t 48 | >(test_out,out_valid); 49 | 50 | // run pool 51 | pool_top(in,out); 52 | 53 | // check the stream is correct 54 | err += checkStreamEqual(out,out_valid,false); 55 | 56 | return err; 57 | } 58 | -------------------------------------------------------------------------------- /test/modules/fork/gen_data.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | 4 | sys.path.append('..') 5 | 6 | from fpgaconvnet.models.modules.Fork import Fork 7 | from Data import Data 8 | 9 | class ForkTB(Data): 10 | def __init__(self): 11 | Data.__init__(self,'fork') 12 | 13 | # update stimulus generation 14 | def gen_stimulus(self): 15 | 16 | # Init Module 17 | fork = Fork( 18 | self.param['rows'], 19 | self.param['cols'], 20 | self.param['channels'], 21 | self.param['kernel_size'], 22 | self.param['coarse'] 23 | ) 24 | 25 | # add parameters 26 | self.param['data_width'] = fork.data_width 27 | self.param['data_int_width'] = fork.data_width//2 28 | 29 | # data in 30 | data_in = self.gen_data([ 31 | self.param['rows'], 32 | self.param['cols'], 33 | self.param['channels'], 34 | self.param['kernel_size'][0], 35 | self.param['kernel_size'][1] 36 | ]) 37 | 38 | # data out 39 | data_out = fork.functional_model(data_in) 40 | 41 | # return data 42 | data = { 43 | 'input' : data_in.reshape(-1).tolist(), 44 | 'output' : data_out.reshape(-1).tolist() 45 | } 46 | 47 | # resource and latency model 48 | model = { 49 | 'latency' : fork.latency(), 50 | 'resources' : fork.rsc() 51 | } 52 | 53 | return data, model 54 | 55 | if __name__ == '__main__': 56 | fork_tb = ForkTB() 57 | fork_tb.main(sys.argv[1:]) 58 | 59 | -------------------------------------------------------------------------------- /test/layers/convolution/config/config_0.json: -------------------------------------------------------------------------------- 1 | { 2 | "batch_size": 1, 3 | "rows_in": 32, 4 | "cols_in": 32, 5 | "channels_in": 16, 6 | "rows_out": 16, 7 | "cols_out": 16, 8 | "channels_out": 32, 9 | "coarse_in": 16, 10 | "coarse_out": 8, 11 | "coarse_group": 1, 12 | "groups": 1, 13 | "fine": 1, 14 | "filters": 32, 15 | "pad_top": 0, 16 | "pad_right": 0, 17 | "pad_bottom": 0, 18 | "pad_left": 0, 19 | "kernel_rows": 1, 20 | "kernel_cols": 1, 21 | "kernel_size": [ 22 | 1, 23 | 1 24 | ], 25 | "stride_rows": 2, 26 | "stride_cols": 2, 27 | "stride": [ 28 | 2, 29 | 2 30 | ], 31 | "mem_bw_in": 100.0, 32 | "mem_bw_out": 100.0, 33 | "data_t": {}, 34 | "weight_t": { 35 | "width": 16, 36 | "binary_point": 15 37 | }, 38 | "acc_t": { 39 | "width": 30, 40 | "binary_point": 23 41 | }, 42 | "input_t": { 43 | "width": 16, 44 | "binary_point": 8 45 | }, 46 | "output_t": { 47 | "width": 16, 48 | "binary_point": 8 49 | }, 50 | "has_bias": 1, 51 | "use_uram": false, 52 | "block_floating_point": false, 53 | "on_chip_addr_range": 4, 54 | "off_chip_buffer_size": 0, 55 | "off_chip_interval": -1, 56 | "stream_weights": 0, 57 | "stream_inputs": [ 58 | false 59 | ], 60 | "stream_outputs": [ 61 | false 62 | ], 63 | "input_compression_ratio": [ 64 | 1.0, 65 | 1.0, 66 | 1.0 67 | ], 68 | "output_compression_ratio": [ 69 | 1.0 70 | ], 71 | "weight_compression_ratio": [ 72 | 1.0 73 | ] 74 | } -------------------------------------------------------------------------------- /test/display_configs.py: -------------------------------------------------------------------------------- 1 | from tabulate import tabulate 2 | import argparse 3 | import os 4 | import json 5 | import re 6 | 7 | def main(): 8 | # parse layer to load configs for 9 | parser = argparse.ArgumentParser() 10 | parser.add_argument("-p","--path", 11 | required=True, help="layer/config path") 12 | args = parser.parse_args() 13 | 14 | # iterate over configs for layer 15 | configs = {} 16 | for filepath in os.listdir(os.path.join(args.path, "config")): 17 | # get config number 18 | num = int(re.search("([0-9]+)", filepath).group(1)) 19 | # load configs 20 | with open(os.path.join(args.path, "config", filepath), "r") as f: 21 | configs[num] = json.load(f) 22 | print(configs) 23 | 24 | # get the table headers 25 | headers = ["configuration", "description"] 26 | config_header = list(configs[0].keys()) # build header of of first config 27 | config_header.remove("description") 28 | headers.extend(config_header) 29 | 30 | # create the table 31 | table = [] 32 | for config in configs: 33 | row = [config, configs[config]["description"]] 34 | for header in headers[2:]: 35 | try: 36 | row.append(configs[config][header]) 37 | except KeyError: 38 | print(f"WARNING: configration {config} does not have parameter {header}") 39 | row.append("-") 40 | table.append(row) 41 | 42 | # sort the table rows 43 | table.sort(key=lambda row: row[0]) 44 | 45 | # display the table 46 | print(tabulate(table, headers=headers)) 47 | 48 | if __name__ == "__main__": 49 | main() 50 | -------------------------------------------------------------------------------- /test/modules/mem_read/tb/mem_read_tb.cpp: -------------------------------------------------------------------------------- 1 | #include "common_tb.hpp" 2 | #include "mem_read_tb.hpp" 3 | 4 | int main() 5 | { 6 | 7 | int err = 0; 8 | std::string data_path = std::string(DATA_DIR)+"/data.dat"; 9 | 10 | const int size_in = MEM_READ_BATCH_SIZE*MEM_READ_ROWS_IN*MEM_READ_COLS_IN*DIVIDE(MEM_READ_CHANNELS_IN,MEM_READ_STREAMS_IN); 11 | 12 | // in/out streams 13 | stream_t(data_t) out[MEM_READ_STREAMS_IN]; 14 | stream_t(data_t) out_valid[MEM_READ_STREAMS_IN]; 15 | 16 | // test inputs data 17 | static mem_int test_in[MEM_READ_PORTS_IN][size_in] = {0}; 18 | static data_t test_stream[size_in][MEM_READ_STREAMS_IN]; 19 | 20 | // load test stream 21 | load_data< 22 | size_in, 23 | MEM_READ_STREAMS_IN, 24 | data_t 25 | >(data_path,test_stream); 26 | 27 | // get number of dma channels 28 | int dma_channels = DIVIDE(MEM_READ_DMA_WIDTH,MEM_READ_DATA_WIDTH); 29 | 30 | // convert test stream to mem_int 31 | for(int i=0;i(test_stream,out_valid); 44 | 45 | // run mem read 46 | mem_read_top(test_in,out); 47 | 48 | // check for errors 49 | for(int i=0;i(out[i],out_valid[i],false); 51 | } 52 | 53 | return err; 54 | } 55 | -------------------------------------------------------------------------------- /test/modules/avg_pool/tb/avg_pool_tb.cpp: -------------------------------------------------------------------------------- 1 | #include "common_tb.hpp" 2 | #include "avg_pool_tb.hpp" 3 | 4 | int main() 5 | { 6 | int err = 0; 7 | 8 | // file paths 9 | std::string input_path = std::string(DATA_DIR)+"/input.dat"; 10 | std::string output_path = std::string(DATA_DIR)+"/output.dat"; 11 | 12 | // in/out streams 13 | stream_t(avg_pool_t) in[AVG_POOL_KERNEL_SIZE_0][AVG_POOL_KERNEL_SIZE_1]; 14 | stream_t(avg_pool_t) out; 15 | stream_t(avg_pool_t) out_valid; 16 | 17 | static avg_pool_t test_in[AVG_POOL_ROWS*AVG_POOL_COLS*AVG_POOL_CHANNELS][AVG_POOL_KERNEL_SIZE_0][AVG_POOL_KERNEL_SIZE_1]; 18 | static avg_pool_t test_out[AVG_POOL_ROWS*AVG_POOL_COLS*AVG_POOL_CHANNELS]; 19 | 20 | // load data_in 21 | load_data< 22 | AVG_POOL_ROWS*AVG_POOL_COLS*AVG_POOL_CHANNELS, 23 | AVG_POOL_KERNEL_SIZE_0, 24 | AVG_POOL_KERNEL_SIZE_1, 25 | avg_pool_t 26 | >(input_path,test_in); 27 | 28 | // load data_out 29 | load_data< 30 | AVG_POOL_ROWS*AVG_POOL_COLS*AVG_POOL_CHANNELS, 31 | avg_pool_t 32 | >(output_path,test_out); 33 | 34 | // convert input stream 35 | to_stream< 36 | AVG_POOL_ROWS*AVG_POOL_COLS*AVG_POOL_CHANNELS, 37 | AVG_POOL_KERNEL_SIZE_0, 38 | AVG_POOL_KERNEL_SIZE_1, 39 | avg_pool_t 40 | >(test_in,in); 41 | 42 | // convert to out valid stream 43 | to_stream< 44 | AVG_POOL_ROWS*AVG_POOL_COLS*AVG_POOL_CHANNELS, 45 | avg_pool_t 46 | >(test_out,out_valid); 47 | 48 | // run avg_pool 49 | avg_pool_top(in,out); 50 | 51 | // check the stream is correct 52 | err += checkStreamEqual(out,out_valid,false); 53 | 54 | return err; 55 | 56 | } -------------------------------------------------------------------------------- /fpgaconvnet/hls/hardware/avg_pool.hpp: -------------------------------------------------------------------------------- 1 | #ifndef AVG_POOL_HPP_ 2 | #define AVG_POOL_HPP_ 3 | 4 | #include "common.hpp" 5 | 6 | /** 7 | * AVG_POOL 8 | */ 9 | 10 | template < 11 | unsigned int BATCH_SIZE, 12 | unsigned int ROWS, 13 | unsigned int COLS, 14 | unsigned int CHANNELS, 15 | unsigned int KERNEL_SIZE_X, 16 | unsigned int KERNEL_SIZE_Y, 17 | typename avg_pool_t 18 | > 19 | void avg_pool( 20 | stream_t(avg_pool_t) in[KERNEL_SIZE_X][KERNEL_SIZE_Y], 21 | stream_t(avg_pool_t) &out 22 | ) 23 | { 24 | 25 | #pragma HLS INLINE OFF 26 | 27 | const unsigned int batch_size = BATCH_SIZE; 28 | const unsigned int rows = ROWS; 29 | const unsigned int cols = COLS; 30 | const unsigned int channels = CHANNELS; 31 | const unsigned int kernel_size_x = KERNEL_SIZE_X; 32 | const unsigned int kernel_size_y = KERNEL_SIZE_Y; 33 | 34 | #pragma HLS STREAM variable=in 35 | #pragma HLS STREAM variable=out 36 | #pragma HLS ARRAY_PARTITION variable=in complete dim=0 37 | 38 | avg_pool_t accum_value; 39 | unsigned long pool_area = kernel_size_x * kernel_size_y; 40 | #pragma HLS DEPENDENCE variable=accum_value RAW intra true 41 | 42 | pixel_loop: for (unsigned long pixel_index = 0; pixel_index < batch_size*rows*cols*channels; pixel_index++) { 43 | accum_value = 0; 44 | #pragma HLS PIPELINE II=1 rewind 45 | 46 | pool_loop_1: for (unsigned char k1 = 0; k1 < kernel_size_x; k1++) { 47 | pool_loop_2: for (unsigned char k2 = 0; k2 < kernel_size_y; k2++) { 48 | accum_value += in[k1][k2].read(); 49 | } 50 | } 51 | 52 | out.write(accum_value/pool_area); 53 | } 54 | } 55 | 56 | #endif -------------------------------------------------------------------------------- /test/modules/bias/gen_data.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | 4 | sys.path.append('..') 5 | 6 | from fpgaconvnet.models.modules.Bias import Bias 7 | from Data import Data 8 | 9 | class BiasTB(Data): 10 | def __init__(self): 11 | Data.__init__(self,'bias') 12 | 13 | # update stimulus generation 14 | def gen_stimulus(self): 15 | 16 | # Init Module 17 | bias = Bias( 18 | self.param['rows'], 19 | self.param['cols'], 20 | self.param['channels'], 21 | self.param['filters'] 22 | ) 23 | 24 | # add parameters 25 | self.param['data_width'] = bias.data_width 26 | self.param['data_int_width'] = bias.data_width//2 27 | self.param['biases_width'] = bias.biases_width 28 | self.param['biases_int_width'] = bias.biases_width//2 29 | 30 | data_in = self.gen_data([ 31 | self.param['rows'], 32 | self.param['cols'], 33 | self.param['filters'] 34 | ]) 35 | # biases 36 | biases = self.gen_data([ 37 | self.param['filters'] 38 | ]) 39 | 40 | # data out 41 | data_out = bias.functional_model(data_in, biases) 42 | 43 | # return data 44 | data = { 45 | 'input' : data_in.reshape(-1).tolist(), 46 | 'biases' : biases.reshape(-1).tolist(), 47 | 'output' : data_out.reshape(-1).tolist() 48 | } 49 | 50 | # resource and latency model 51 | model = { 52 | 'latency' : bias.latency(), 53 | 'resources' : bias.rsc() 54 | } 55 | return data, model 56 | 57 | if __name__ == '__main__': 58 | bias_tb = BiasTB() 59 | bias_tb.main(sys.argv[1:]) 60 | -------------------------------------------------------------------------------- /test/modules/pool/gen_data.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | 4 | sys.path.append('..') 5 | 6 | from fpgaconvnet.models.modules.Pool import Pool 7 | from Data import Data 8 | 9 | class PoolTB(Data): 10 | def __init__(self): 11 | Data.__init__(self,'pool') 12 | 13 | # update stimulus generation 14 | def gen_stimulus(self): 15 | 16 | # Init Module 17 | if self.param['pool_type'] == 0: 18 | pool_type = 'max' 19 | if self.param['pool_type'] == 1: 20 | pool_type = 'avg' 21 | pool = Pool( 22 | self.param['rows'], 23 | self.param['cols'], 24 | self.param['channels'], 25 | self.param['kernel_size'], 26 | pool_type 27 | ) 28 | 29 | # add parameters 30 | self.param['data_width'] = pool.data_width 31 | self.param['data_int_width'] = pool.data_width//2 32 | 33 | # data in 34 | data_in = self.gen_data([ 35 | self.param['rows'], 36 | self.param['cols'], 37 | self.param['channels'], 38 | self.param['kernel_size'][0], 39 | self.param['kernel_size'][1] 40 | ]) 41 | 42 | # data out 43 | data_out = pool.functional_model(data_in) 44 | 45 | # return data 46 | data = { 47 | 'input' : data_in.reshape(-1).tolist(), 48 | 'output' : data_out.reshape(-1).tolist() 49 | } 50 | 51 | # resource and latency model 52 | model = { 53 | 'latency' : pool.latency(), 54 | 'resources' : pool.rsc() 55 | } 56 | 57 | return data, model 58 | 59 | if __name__ == '__main__': 60 | pool_tb = PoolTB() 61 | pool_tb.main(sys.argv[1:]) 62 | 63 | -------------------------------------------------------------------------------- /test/modules/glue/gen_data.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | 4 | sys.path.append('..') 5 | 6 | from fpgaconvnet.models.modules.Glue import Glue 7 | from Data import Data 8 | 9 | class GlueTB(Data): 10 | def __init__(self): 11 | Data.__init__(self,'glue') 12 | 13 | # update stimulus generation 14 | def gen_stimulus(self): 15 | 16 | # Init Module 17 | glue = Glue( 18 | self.param['rows'], 19 | self.param['cols'], 20 | 1, 21 | self.param['filters'], 22 | self.param['coarse_in'], 23 | self.param['coarse_out'] 24 | ) 25 | 26 | # add parameters 27 | self.param['data_width'] = glue.data_width 28 | self.param['data_int_width'] = glue.data_width//2 29 | self.param['acc_width'] = glue.acc_width 30 | self.param['acc_int_width'] = glue.acc_width//2 31 | 32 | # data in 33 | data_in = self.gen_data([ 34 | self.param['rows'], 35 | self.param['cols'], 36 | int(self.param['filters']/self.param['coarse_out']), 37 | self.param['coarse_in'], 38 | self.param['coarse_out'] 39 | ]) 40 | 41 | # data out 42 | data_out = glue.functional_model(data_in) 43 | 44 | # return data 45 | data = { 46 | 'input' : data_in.reshape(-1).tolist(), 47 | 'output' : data_out.reshape(-1).tolist() 48 | } 49 | 50 | # resource and latency model 51 | model = { 52 | 'latency' : glue.latency(), 53 | 'resources' : glue.rsc() 54 | } 55 | 56 | return data, model 57 | 58 | if __name__ == '__main__': 59 | glue_tb = GlueTB() 60 | glue_tb.main(sys.argv[1:]) 61 | 62 | -------------------------------------------------------------------------------- /test/modules/accum/gen_data.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | 4 | sys.path.append('..') 5 | 6 | from fpgaconvnet.models.modules.Accum import Accum 7 | from Data import Data 8 | 9 | class AccumTB(Data): 10 | def __init__(self): 11 | Data.__init__(self,'accum') 12 | 13 | # update stimulus generation 14 | def gen_stimulus(self): 15 | 16 | self.param['channels_per_group'] = int(self.param['channels']/self.param['groups']) 17 | self.param['filters_per_group'] = int(self.param['filters'] /self.param['groups']) 18 | 19 | # Init Module 20 | accum = Accum( 21 | self.param['rows'], 22 | self.param['cols'], 23 | self.param['channels'], 24 | self.param['filters'], 25 | self.param['groups'] 26 | ) 27 | 28 | # data in 29 | data_in = self.gen_data([ 30 | self.param['rows'], 31 | self.param['cols'], 32 | self.param['channels'], 33 | self.param['filters_per_group'] 34 | ]) 35 | 36 | # add parameters 37 | self.param['data_width'] = accum.data_width 38 | self.param['data_int_width'] = accum.data_width//2 39 | 40 | # data out 41 | data_out = accum.functional_model(data_in) 42 | 43 | # return data 44 | data = { 45 | 'input' : data_in.reshape(-1).tolist(), 46 | 'output' : data_out.reshape(-1).tolist() 47 | } 48 | 49 | # resource and latency model 50 | model = { 51 | 'latency' : accum.latency(), 52 | 'resources' : accum.rsc() 53 | } 54 | 55 | return data, model 56 | 57 | if __name__ == '__main__': 58 | accum_tb = AccumTB() 59 | accum_tb.main(sys.argv[1:]) 60 | 61 | -------------------------------------------------------------------------------- /fpgaconvnet/hls/tools/vivado_hls_wrapper.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | 3 | class VivadoHLSWrapper: 4 | 5 | def __init__(self, name, project_path): 6 | self.session = subprocess.call(["vivado_hls", "-i"], stdin=subprocess.PIPE, 7 | stdout=subprocess.PIPE) 8 | self.wait_for_command() 9 | 10 | def wait_for_command(self): 11 | out = self.session.stdout.readline().decode() 12 | while out != "vivado_hls>": 13 | out = self.session.stdout.readline().decode() 14 | print(out) 15 | print(self.session.stdout.read().decode()) 16 | 17 | def open_project(self, project_path, reset=True): 18 | if reset: 19 | self.session.communicate(input=f"open_project -reset {project_path}\n".encode()) 20 | else: 21 | self.session.communicate(input=f"open_project {project_path}\n".encode()) 22 | 23 | def set_top(self, top): 24 | self.session.communicate(input=f"set_top {top}\n".encode()) 25 | 26 | def open_solution(self, solution, reset=True): 27 | if reset: 28 | self.session.communicate(input=f"open_solution -reset '{solution}'\n".encode()) 29 | else: 30 | self.session.communicate(input=f"open_solution '{solution}'\n".encode()) 31 | 32 | def run_csynth(self): 33 | self.session.communicate(input='csynth_design\n'.encode()) 34 | 35 | def exit(self): 36 | self.session.communicate(input='exit\n'.encode()) 37 | 38 | def __del__(self): 39 | self.exit() 40 | self.session.terminate() 41 | 42 | if __name__ == "__main__": 43 | tmp = VivadoHLSWrapper() 44 | tmp.open_project("fork_hls_prj", reset=False) 45 | tmp.set_top("fork_top") 46 | tmp.open_solution("solution0", reset=False) 47 | tmp.run_csynth() 48 | -------------------------------------------------------------------------------- /test/modules/avg_pool/gen_data.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | 4 | sys.path.append('..') 5 | 6 | from fpgaconvnet.models.modules.Pool import Pool 7 | from Data import Data 8 | 9 | class AvgPoolTB(Data): 10 | def __init__(self): 11 | Data.__init__(self,'avg_pool') 12 | 13 | # update stimulus generation 14 | def gen_stimulus(self): 15 | 16 | # Init Module 17 | if self.param['pool_type'] == 0: 18 | pool_type = 'max' 19 | if self.param['pool_type'] == 1: 20 | pool_type = 'avg' 21 | avg_pool = Pool( 22 | self.param['rows'], 23 | self.param['cols'], 24 | self.param['channels'], 25 | self.param['kernel_size'], 26 | pool_type 27 | ) 28 | 29 | # add parameters 30 | self.param['data_width'] = avg_pool.data_width 31 | self.param['data_int_width'] = avg_pool.data_width//2 32 | 33 | # data in 34 | data_in = self.gen_data([ 35 | self.param['rows'], 36 | self.param['cols'], 37 | self.param['channels'], 38 | self.param['kernel_size'][0], 39 | self.param['kernel_size'][1] 40 | ]) 41 | 42 | # data out 43 | data_out = avg_pool.functional_model(data_in) 44 | 45 | # return data 46 | data = { 47 | 'input' : data_in.reshape(-1).tolist(), 48 | 'output' : data_out.reshape(-1).tolist() 49 | } 50 | 51 | # resource and latency model 52 | model = { 53 | 'latency' : avg_pool.latency(), 54 | 'resources' : avg_pool.rsc() 55 | } 56 | 57 | return data, model 58 | 59 | if __name__ == '__main__': 60 | pool_tb = AvgPoolTB() 61 | pool_tb.main(sys.argv[1:]) 62 | 63 | -------------------------------------------------------------------------------- /fpgaconvnet/hls/hardware/relu.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2022 Alexander Montgomerie-Corcoran 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef RELU_HPP_ 19 | #define RELU_HPP_ 20 | 21 | #include "common.hpp" 22 | 23 | /** 24 | * RECTIFIED LINEAR UNIT (RELU) FUNCTION 25 | */ 26 | template< 27 | unsigned int BATCH_SIZE, 28 | unsigned int ROWS, 29 | unsigned int COLS, 30 | unsigned int CHANNELS, 31 | typename relu_t 32 | > 33 | void relu( 34 | stream_t(relu_t) &in, 35 | stream_t(relu_t) &out 36 | ) 37 | { 38 | 39 | #pragma HLS INLINE OFF 40 | 41 | const unsigned int batch_size = BATCH_SIZE; 42 | const unsigned int rows = ROWS; 43 | const unsigned int cols = COLS; 44 | const unsigned int channels = CHANNELS; 45 | 46 | #pragma HLS STREAM variable=in 47 | #pragma HLS STREAM variable=out 48 | 49 | for(unsigned long pixel_index=0 ; pixel_index < batch_size*rows*cols*channels ; pixel_index++) { 50 | #pragma HLS PIPELINE II=1 rewind 51 | relu_t tmp = in.read(); 52 | if(tmp < 0.0) 53 | out.write(0.0); 54 | else 55 | out.write(tmp); 56 | } 57 | } 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /test/modules/glue/tb/glue_tb.cpp: -------------------------------------------------------------------------------- 1 | #include "common_tb.hpp" 2 | #include "glue_tb.hpp" 3 | 4 | int main() 5 | { 6 | 7 | int err = 0; 8 | 9 | // file paths 10 | std::string input_path = std::string(DATA_DIR)+"/input.dat"; 11 | std::string output_path = std::string(DATA_DIR)+"/output.dat"; 12 | 13 | // in/out streams 14 | stream_t(glue_acc_t) in[GLUE_COARSE_IN][GLUE_COARSE_OUT]; 15 | stream_t(glue_data_t) out[GLUE_COARSE_OUT]; 16 | stream_t(glue_data_t) out_valid[GLUE_COARSE_OUT]; 17 | 18 | // test inputs data 19 | static glue_acc_t test_in[GLUE_ROWS*GLUE_COLS*DIVIDE(GLUE_FILTERS,GLUE_COARSE_OUT)][GLUE_COARSE_IN][GLUE_COARSE_OUT]; 20 | static glue_data_t test_out[GLUE_ROWS*GLUE_COLS*DIVIDE(GLUE_FILTERS,GLUE_COARSE_OUT)][GLUE_COARSE_OUT]; 21 | 22 | // load data_in 23 | load_data< 24 | GLUE_ROWS*GLUE_COLS*DIVIDE(GLUE_FILTERS,GLUE_COARSE_OUT), 25 | GLUE_COARSE_IN, 26 | GLUE_COARSE_OUT, 27 | glue_acc_t 28 | >(input_path,test_in); 29 | 30 | // load data_out 31 | load_data< 32 | GLUE_ROWS*GLUE_COLS*DIVIDE(GLUE_FILTERS,GLUE_COARSE_OUT), 33 | GLUE_COARSE_OUT, 34 | glue_data_t 35 | >(output_path,test_out); 36 | 37 | // convert input stream 38 | to_stream< 39 | GLUE_ROWS*GLUE_COLS*DIVIDE(GLUE_FILTERS,GLUE_COARSE_OUT), 40 | GLUE_COARSE_IN, 41 | GLUE_COARSE_OUT, 42 | glue_acc_t 43 | >(test_in,in); 44 | 45 | // convert to out valid stream 46 | to_stream< 47 | GLUE_ROWS*GLUE_COLS*DIVIDE(GLUE_FILTERS,GLUE_COARSE_OUT), 48 | GLUE_COARSE_OUT, 49 | glue_data_t 50 | >(test_out,out_valid); 51 | 52 | // run glue 53 | glue_top(in,out); 54 | 55 | for(int j=0;j(out[j],out_valid[j]); 57 | } 58 | 59 | return err; 60 | } 61 | -------------------------------------------------------------------------------- /test/modules/README.md: -------------------------------------------------------------------------------- 1 | # Module Testing 2 | 3 | To run a module test, use the `run_test.sh` script using the following arguments: 4 | 5 | ``` 6 | run_test.sh [-m (module)] [-n (test number)] [-c,-s,-e,-i] 7 | ``` 8 | 9 | The final flags correspond to the following: 10 | - `-c` = C simulation 11 | - `-s` = Synthesis 12 | - `-e` = Co-simulation 13 | - `-i` = Implementation 14 | 15 | To run c-simulation for the 0th test of the __fork__ module for example, you would run `./run_test.sh -m fork -n 0 -c`. 16 | 17 | For more details on what the `run_test.sh` script is calling, look at the `scripts/run_hls.tcl` script, which Vivado HLS calls. 18 | 19 | The general file structure for each module test is as follows: 20 | 21 | ```bash 22 | module/ 23 | ├── config 24 | │   └── config_n.json # file containing parameters for test n 25 | ├── data 26 | │   └── test_n 27 | │   └── data.yaml # data generated by gen_data.py script for the HLS testbench 28 | ├── module_hls_prj/ 29 | ├── gen_data.py # generates data.yaml file from config_n.json 30 | ├── rpt 31 | │   └── test_n.json # a report generated which gives usage and performance for module 32 | ├── src 33 | │   └── module.cpp # main DUT file, where the module is called 34 | └── tb 35 | ├── module_param.hpp # header file containing config_n.json parameters as C++ macros 36 | ├── module_tb.cpp # module testbench 37 | └── module_tb.hpp # header file for DUT and testbench 38 | ``` 39 | 40 | For each module, a functional model is needed to generate reference test data. These models can be found in the `models/modules/` folder. The `gen_data.py` script calls this model for the given parameters. 41 | 42 | The data is then loaded into the testbench using the `load_data` function from the `include/common_tb.cpp` folder. This function is overloaded for data of different dimensionality. This is then converted to a hls stream using the `to_stream` function. 43 | 44 | 45 | -------------------------------------------------------------------------------- /test/modules/run_tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | TEST_TYPE=all 3 | 4 | FPGACONVNET_HLS_PATH=$PWD/../../fpgaconvnet/hls 5 | 6 | while getopts ":m:n:cseih" opt; do 7 | case ${opt} in 8 | m ) 9 | MODULE=$OPTARG 10 | ;; 11 | n ) 12 | TEST_NUM=$OPTARG 13 | ;; 14 | c ) 15 | # c simulation 16 | TEST_TYPE=sim 17 | ;; 18 | s ) 19 | # synthesis 20 | TEST_TYPE=synth 21 | ;; 22 | e ) 23 | # co-simulation 24 | TEST_TYPE=cosim 25 | ;; 26 | i ) 27 | # implementation 28 | TEST_TYPE=impl 29 | ;; 30 | h ) 31 | echo "USAGE: run_test.sh [-m (module)] [-n (test number)] [-c,-s,-e,-i]" 32 | echo " -c = C simulation" 33 | echo " -s = Synthesis" 34 | echo " -e = Co-simulation" 35 | echo " -i = Implementation" 36 | exit 37 | ;; 38 | esac 39 | done 40 | shift $((OPTIND -1)) 41 | 42 | function run_test { 43 | echo "RUNNING TEST ${1}" 44 | # GENERATE INPUTS 45 | mkdir -p data/test_${1} 46 | python gen_data.py -c config/config_${1}.json -o $PWD/data/test_${1} -h tb 47 | # RUN TEST 48 | vivado_hls -f ../run_module_hls.tcl "_ -num ${1} -type ${TEST_TYPE} -name ${MODULE}" 49 | 50 | } 51 | 52 | # move to folder 53 | cd $MODULE 54 | 55 | if [ $TEST_NUM ]; then 56 | 57 | # run the test 58 | run_test $TEST_NUM 59 | 60 | # generate reports 61 | python ../report.py -m $MODULE -n $TEST_NUM 62 | 63 | else 64 | 65 | # number of tests 66 | NUM_TEST="$(ls config/ -1U | wc -l)" 67 | # iterate over tests 68 | for i in $( seq 0 $(($NUM_TEST-1)) ); do 69 | 70 | # run the test 71 | run_test $i 72 | 73 | done 74 | 75 | # generate reports 76 | python ../report.py -m $MODULE 77 | 78 | fi 79 | -------------------------------------------------------------------------------- /test/modules/bias/tb/bias_tb.cpp: -------------------------------------------------------------------------------- 1 | #include "common_tb.hpp" 2 | #include "bias_tb.hpp" 3 | 4 | int main() 5 | { 6 | int err = 0; 7 | 8 | std::string input_path = std::string(DATA_DIR)+"/input.dat"; 9 | std::string output_path = std::string(DATA_DIR)+"/output.dat"; 10 | std::string biases_path = std::string(DATA_DIR)+"/biases.dat"; 11 | 12 | // biases 13 | //bias_weight_t biases[BIAS_CHANNELS*DIVIDE(BIAS_FILTERS,BIAS_GROUPS)]; 14 | //const unsigned int f_per_cout = DIVIDE(BIAS_FILTERS,BIAS_COARSE_OUT); 15 | bias_biases_t biases[BIAS_FILTERS]; 16 | 17 | stream_t(bias_data_t) in("in"); 18 | stream_t(bias_data_t) out("out"); 19 | stream_t(bias_data_t) out_valid("out_valid"); 20 | 21 | // test inputs data 22 | static bias_data_t test_in[BIAS_ROWS*BIAS_COLS*BIAS_FILTERS]; 23 | static bias_data_t test_out[BIAS_ROWS*BIAS_COLS*BIAS_FILTERS]; //TODO check 24 | 25 | // load biases 26 | load_data< 27 | BIAS_FILTERS, 28 | bias_biases_t 29 | >(biases_path,biases); 30 | 31 | // load data_in 32 | load_data< 33 | BIAS_ROWS*BIAS_COLS*BIAS_FILTERS, 34 | bias_data_t 35 | >(input_path,test_in); 36 | 37 | // load data_out 38 | load_data< 39 | BIAS_ROWS*BIAS_COLS*BIAS_FILTERS, 40 | bias_data_t 41 | >(output_path,test_out); 42 | 43 | // convert input stream 44 | to_stream< 45 | BIAS_ROWS*BIAS_COLS*BIAS_FILTERS, 46 | bias_data_t 47 | >(test_in,in); 48 | 49 | // convert to out valid stream 50 | to_stream< 51 | BIAS_ROWS*BIAS_COLS*BIAS_FILTERS, 52 | bias_data_t 53 | >(test_out,out_valid); 54 | 55 | // run bias 56 | bias_top(in,biases,out); 57 | 58 | // check output 59 | //for(int j=0;j(out[j],out_valid[j]); 61 | //} 62 | err += checkStreamEqual(out,out_valid); 63 | 64 | return err; 65 | } 66 | -------------------------------------------------------------------------------- /test/modules/squeeze/tb/squeeze_tb.cpp: -------------------------------------------------------------------------------- 1 | #include "common_tb.hpp" 2 | #include "squeeze_tb.hpp" 3 | 4 | int main() 5 | { 6 | 7 | int err = 0; 8 | std::string input_path = std::string(DATA_DIR)+"/input.dat"; 9 | std::string output_path = std::string(DATA_DIR)+"/output.dat"; 10 | 11 | // in/out streams 12 | stream_t(squeeze_t) in[SQUEEZE_COARSE_IN]; 13 | stream_t(squeeze_t) out[SQUEEZE_COARSE_OUT]; 14 | stream_t(squeeze_t) out_valid[SQUEEZE_COARSE_OUT]; 15 | 16 | // test inputs data 17 | static squeeze_t test_in[SQUEEZE_BATCH_SIZE*SQUEEZE_ROWS*SQUEEZE_COLS*DIVIDE(SQUEEZE_CHANNELS,SQUEEZE_COARSE_IN)][SQUEEZE_COARSE_IN]; 18 | static squeeze_t test_out[SQUEEZE_BATCH_SIZE*SQUEEZE_ROWS*SQUEEZE_COLS*DIVIDE(SQUEEZE_CHANNELS,SQUEEZE_COARSE_OUT)][SQUEEZE_COARSE_OUT]; 19 | 20 | // load data_in 21 | load_data< 22 | SQUEEZE_BATCH_SIZE*SQUEEZE_ROWS*SQUEEZE_COLS*DIVIDE(SQUEEZE_CHANNELS,SQUEEZE_COARSE_IN), 23 | SQUEEZE_COARSE_IN, 24 | squeeze_t 25 | >(input_path,test_in); 26 | 27 | // load data_out 28 | load_data< 29 | SQUEEZE_BATCH_SIZE*SQUEEZE_ROWS*SQUEEZE_COLS*DIVIDE(SQUEEZE_CHANNELS,SQUEEZE_COARSE_OUT), 30 | SQUEEZE_COARSE_OUT, 31 | squeeze_t 32 | >(output_path,test_out); 33 | 34 | // convert input stream 35 | to_stream< 36 | SQUEEZE_BATCH_SIZE*SQUEEZE_ROWS*SQUEEZE_COLS*DIVIDE(SQUEEZE_CHANNELS,SQUEEZE_COARSE_IN), 37 | SQUEEZE_COARSE_IN, 38 | squeeze_t 39 | >(test_in,in); 40 | 41 | // convert to out valid stream 42 | to_stream< 43 | SQUEEZE_BATCH_SIZE*SQUEEZE_ROWS*SQUEEZE_COLS*DIVIDE(SQUEEZE_CHANNELS,SQUEEZE_COARSE_OUT), 44 | SQUEEZE_COARSE_OUT, 45 | squeeze_t 46 | >(test_out,out_valid); 47 | 48 | // run squeeze 49 | squeeze_top(in,out); 50 | 51 | for(int j=0;j(out[j],out_valid[j], false); 53 | } 54 | 55 | return err; 56 | } 57 | -------------------------------------------------------------------------------- /test/modules/sliding_window/gen_data.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | 4 | sys.path.append('..') 5 | 6 | from fpgaconvnet.models.modules.SlidingWindow import SlidingWindow 7 | from Data import Data 8 | 9 | class SlidingWindowTB(Data): 10 | def __init__(self): 11 | Data.__init__(self,'sliding_window') 12 | 13 | # update stimulus generation 14 | def gen_stimulus(self): 15 | # Init Module 16 | sliding_window = SlidingWindow( 17 | self.param['rows'], 18 | self.param['cols'], 19 | self.param['channels'], 20 | self.param['kernel_size'], 21 | self.param['stride'], 22 | self.param['pad_top'], 23 | self.param['pad_right'], 24 | self.param['pad_bottom'], 25 | self.param['pad_left'] 26 | ) 27 | 28 | # add parameters 29 | self.param['data_width'] = sliding_window.data_width 30 | self.param['data_int_width'] = sliding_window.data_width//2 31 | 32 | # output dimensions 33 | self.param['rows_out'] = sliding_window.rows_out() 34 | self.param['cols_out'] = sliding_window.cols_out() 35 | 36 | # data in 37 | data_in = self.gen_data([ 38 | self.param['batch_size'], 39 | self.param['rows'], 40 | self.param['cols'], 41 | self.param['channels'] 42 | ]) 43 | # data out 44 | data_out = sliding_window.functional_model(data_in) 45 | # return data 46 | data = { 47 | 'input' : data_in.reshape(-1).tolist(), 48 | 'output' : data_out.reshape(-1).tolist() 49 | } 50 | # resource and latency model 51 | model = { 52 | 'latency' : sliding_window.latency(), 53 | 'resources' : sliding_window.rsc() 54 | } 55 | return data, model 56 | 57 | if __name__ == '__main__': 58 | sliding_window_tb = SlidingWindowTB() 59 | sliding_window_tb.main(sys.argv[1:]) 60 | 61 | -------------------------------------------------------------------------------- /test/layers/relu/tb/relu_layer_tb.cpp: -------------------------------------------------------------------------------- 1 | #include "common_tb.hpp" 2 | #include "relu_layer_tb.hpp" 3 | 4 | int main() 5 | { 6 | int err = 0; 7 | std::string input_path = std::string(DATA_DIR)+"/input.dat"; 8 | std::string output_path = std::string(DATA_DIR)+"/output.dat"; 9 | 10 | stream_t(relu_layer_data_t) in[RELU_LAYER_COARSE]; 11 | stream_t(relu_layer_data_t) out[RELU_LAYER_COARSE]; 12 | stream_t(relu_layer_data_t) out_correct[RELU_LAYER_COARSE]; 13 | 14 | // test images 15 | static relu_layer_data_t test_in[DIVIDE(RELU_LAYER_CHANNELS,RELU_LAYER_COARSE)*RELU_LAYER_ROWS*RELU_LAYER_COLS][RELU_LAYER_COARSE]; 16 | static relu_layer_data_t test_out[DIVIDE(RELU_LAYER_CHANNELS,RELU_LAYER_COARSE)*RELU_LAYER_ROWS_OUT*RELU_LAYER_COLS_OUT][RELU_LAYER_COARSE]; 17 | 18 | // load input 19 | load_data< 20 | DIVIDE(RELU_LAYER_CHANNELS,RELU_LAYER_COARSE)*RELU_LAYER_ROWS*RELU_LAYER_COLS, 21 | RELU_LAYER_COARSE, 22 | relu_layer_data_t 23 | >(input_path,test_in); 24 | 25 | // load output 26 | load_data< 27 | DIVIDE(RELU_LAYER_CHANNELS,RELU_LAYER_COARSE)*RELU_LAYER_ROWS_OUT*RELU_LAYER_COLS_OUT, 28 | RELU_LAYER_COARSE, 29 | relu_layer_data_t 30 | >(output_path,test_out); 31 | 32 | // convert to streams 33 | to_stream< 34 | DIVIDE(RELU_LAYER_CHANNELS,RELU_LAYER_COARSE)*RELU_LAYER_ROWS*RELU_LAYER_COLS, 35 | RELU_LAYER_COARSE, 36 | relu_layer_data_t 37 | >(test_in,in); 38 | 39 | to_stream< 40 | DIVIDE(RELU_LAYER_CHANNELS,RELU_LAYER_COARSE)*RELU_LAYER_ROWS_OUT*RELU_LAYER_COLS_OUT, 41 | RELU_LAYER_COARSE, 42 | relu_layer_data_t 43 | >(test_out,out_correct); 44 | 45 | relu_layer_top(in,out,0); 46 | 47 | for(int i=0;i(out[i],out_correct[i]); 51 | printf("%s\n",(err==0) ? "passed" : "failed"); 52 | } 53 | 54 | return err; 55 | } 56 | -------------------------------------------------------------------------------- /fpgaconvnet/hls/generate/modules/conv.py: -------------------------------------------------------------------------------- 1 | conv_template = """ 2 | {indent}conv< 3 | {indent} {NAME}_BATCH_SIZE, 4 | {indent} {NAME}_ROWS, 5 | {indent} {NAME}_COLS, 6 | {indent} {NAME}_CHANNELS, 7 | {indent} {NAME}_FILTERS, 8 | {indent} {NAME}_GROUPS, 9 | {_if} ({NAME}_KERNEL_SIZE_X > 1) || ({NAME}_KERNEL_SIZE_Y > 1) 10 | {_if_conv} ({NAME}_KERNEL_SIZE_X > 1) || ({NAME}_KERNEL_SIZE_Y > 1) || ({LAYER_NAME}_STRIDE_X > 1) || ({LAYER_NAME}_STRIDE_Y > 1) 11 | {indent} {NAME}_FINE, 12 | {indent} {NAME}_KERNEL_SIZE_X, 13 | {indent} {NAME}_KERNEL_SIZE_Y, 14 | #endif 15 | {indent} {data_t}, 16 | {indent} {weight_t}, 17 | {indent} {acc_t} 18 | {indent}>({input_stream},{weights_stream},{output_stream}); 19 | """ 20 | 21 | def gen_conv_module(name,input_stream,weights_stream,output_stream, 22 | data_t="data_t",weight_t="weight_t",acc_t="acc_t",indent=0): 23 | return conv_template.format( 24 | LAYER_NAME =name.upper(), 25 | NAME =name.upper(), 26 | input_stream =input_stream, 27 | weights_stream =weights_stream, 28 | output_stream =output_stream, 29 | data_t =data_t, 30 | weight_t =weight_t, 31 | acc_t =acc_t, 32 | _if ="#if", 33 | _if_conv ="//", 34 | indent =" "*indent 35 | ) 36 | 37 | def gen_convolution_conv_module(layer_name,name,input_stream,weights_stream,output_stream, 38 | data_t="data_t",weight_t="weight_t",acc_t="acc_t",indent=0): 39 | return conv_template.format( 40 | LAYER_NAME =layer_name.upper(), 41 | NAME =name.upper(), 42 | input_stream =input_stream, 43 | weights_stream =weights_stream, 44 | output_stream =output_stream, 45 | data_t =data_t, 46 | weight_t =weight_t, 47 | acc_t =acc_t, 48 | _if ="//", 49 | _if_conv ="#if", 50 | indent =" "*indent 51 | ) 52 | 53 | -------------------------------------------------------------------------------- /fpgaconvnet/hls/hardware/bias.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2022 Alexander Montgomerie-Corcoran and Benjamin Biggs 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef BIAS_HPP_ 19 | #define BIAS_HPP_ 20 | 21 | #include "common.hpp" 22 | 23 | /** 24 | * BIAS FUNCTION 25 | */ 26 | 27 | template< 28 | unsigned int BATCH_SIZE, 29 | unsigned int ROWS, 30 | unsigned int COLS, 31 | unsigned int FILTERS, 32 | typename bias_data_t, 33 | typename bias_biases_t 34 | > 35 | void bias( 36 | stream_t(bias_data_t) &in, 37 | const bias_biases_t bias[FILTERS], 38 | stream_t(bias_data_t) &out 39 | ) 40 | { 41 | 42 | #pragma HLS INLINE OFF 43 | 44 | const unsigned int batch_size = BATCH_SIZE; 45 | const unsigned int rows = ROWS; 46 | const unsigned int cols = COLS; 47 | const unsigned int filters = FILTERS; 48 | 49 | #pragma HLS STREAM variable=in 50 | #pragma HLS STREAM variable=out 51 | 52 | // loops 53 | auto loops = hlslib::ConstFlatten< 54 | 0, batch_size*rows*cols, 1, // pixel loop 55 | 0, filters, 1 // filter loop 56 | >(); 57 | 58 | pixel_filter_loop: for (size_t i = 0; i < loops.size(); ++i, ++loops) { 59 | #pragma HLS PIPELINE II=1 rewind 60 | auto filter_index = loops[1]; 61 | out.write(in.read() + bias[filter_index]); 62 | } 63 | 64 | } 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /test/layers/README.md: -------------------------------------------------------------------------------- 1 | # Layer Testing 2 | 3 | To run a layer test, use the `run_test.sh` script using the following arguments: 4 | 5 | ``` 6 | run_test.sh [-l (layer)] [-n (test number)] [-c,-s,-e,-i] 7 | ``` 8 | 9 | The final flags correspond to the following: 10 | - `-c` = C simulation 11 | - `-s` = Synthesis 12 | - `-e` = Co-simulation 13 | - `-i` = Implementation 14 | 15 | To run c-simulation for the 0th test of the __convolution__ layer for example, you would run `./run_test.sh -l convolution -n 0 -c`. 16 | 17 | For more details on what the `run_test.sh` script is calling, look at the `scripts/run_hls.tcl` script, which Vivado HLS calls. 18 | 19 | The general file structure for each module test is as follows: 20 | 21 | ```bash 22 | module/ 23 | ├── config 24 | │   └── config_n.json # file containing parameters for test n 25 | ├── data 26 | │   └── test_n # data generated by gen_data.py script for the HLS testbench 27 | │   ├── input.dat 28 | │   └── output.dat 29 | ├── layer_hls_prj/ 30 | ├── gen_data.py # generates data.yaml file from config_n.json 31 | ├── rpt 32 | │   └── test_n.json # a report generated which gives usage and performance for module 33 | ├── include 34 | │   └── layer.hpp # generated header file for the layer instance 35 | ├── src 36 | │   ├── layer.cpp # generated source file for the layer instance 37 | │   └── layer_top.cpp # where the DUT is instantiated 38 | └── tb 39 | ├── layer_tb.cpp # layer testbench 40 | └── layer_tb.hpp # layer file for DUT and testbench 41 | ``` 42 | 43 | For each layer, a functional model is needed to generate reference test data. These models can be found in the `models/layers/` folder of the fpgaconvnet-optimiser repository. The `gen_data.py` script calls this model for the given parameters. 44 | 45 | The data is then loaded into the testbench using the `load_data` function from the `include/common_tb.cpp` folder. This function is overloaded for data of different dimensionality. This is then converted to a hls stream using the `to_stream` function. 46 | 47 | -------------------------------------------------------------------------------- /test/layers/batch_norm/tb/batch_norm_layer_tb.cpp: -------------------------------------------------------------------------------- 1 | #include "common_tb.hpp" 2 | #include "batch_norm_layer_tb.hpp" 3 | 4 | int main() 5 | { 6 | int err = 0; 7 | std::string input_path = std::string(DATA_DIR)+"/input.dat"; 8 | std::string output_path = std::string(DATA_DIR)+"/output.dat"; 9 | 10 | stream_t(data_t) in[BATCH_NORM_LAYER_COARSE]; 11 | stream_t(data_t) out[BATCH_NORM_LAYER_COARSE]; 12 | stream_t(data_t) out_correct[BATCH_NORM_LAYER_COARSE]; 13 | 14 | // test images 15 | static data_t test_in[CHANNELS_3D(BATCH_NORM_LAYER_CHANNELS,BATCH_NORM_LAYER_COARSE)*BATCH_NORM_LAYER_ROWS*BATCH_NORM_LAYER_COLS][BATCH_NORM_LAYER_COARSE]; 16 | static data_t test_out[CHANNELS_3D(BATCH_NORM_LAYER_CHANNELS,BATCH_NORM_LAYER_COARSE)*BATCH_NORM_LAYER_ROWS*BATCH_NORM_LAYER_COLS][BATCH_NORM_LAYER_COARSE]; 17 | 18 | // load input 19 | load_data< 20 | CHANNELS_3D(BATCH_NORM_LAYER_CHANNELS,BATCH_NORM_LAYER_COARSE)*BATCH_NORM_LAYER_ROWS*BATCH_NORM_LAYER_COLS, 21 | BATCH_NORM_LAYER_COARSE 22 | >(data_path,test_in); 23 | 24 | // load output 25 | load_data< 26 | CHANNELS_3D(BATCH_NORM_LAYER_CHANNELS,BATCH_NORM_LAYER_COARSE)*BATCH_NORM_LAYER_ROWS*BATCH_NORM_LAYER_COLS, 27 | BATCH_NORM_LAYER_COARSE 28 | >(data_path,test_out); 29 | 30 | // convert to streams 31 | to_stream< 32 | CHANNELS_3D(BATCH_NORM_LAYER_CHANNELS,BATCH_NORM_LAYER_COARSE)*BATCH_NORM_LAYER_ROWS*BATCH_NORM_LAYER_COLS, 33 | BATCH_NORM_LAYER_COARSE 34 | >(test_in,in); 35 | 36 | // convert to streams 37 | to_stream< 38 | CHANNELS_3D(BATCH_NORM_LAYER_CHANNELS,BATCH_NORM_LAYER_COARSE)*BATCH_NORM_LAYER_ROWS*BATCH_NORM_LAYER_COLS, 39 | BATCH_NORM_LAYER_COARSE 40 | >(test_out,out_correct); 41 | 42 | batch_norm_layer_top(in,out,0); 43 | 44 | for(int i=0;i(out[i],out_correct[i]); 48 | printf("%s\n",(err==0) ? "passed" : "failed"); 49 | } 50 | 51 | return err; 52 | } 53 | -------------------------------------------------------------------------------- /fpgaconvnet/hls/hardware/common.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2022 Alexander Montgomerie-Corcoran 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef COMMON_HPP_ 19 | #define COMMON_HPP_ 20 | 21 | #include 22 | #include 23 | #include "hls_stream.h" 24 | #include "hls_math.h" 25 | #include "ap_axi_sdata.h" 26 | #include "stdint.h" 27 | #include 28 | #include 29 | #include 30 | 31 | #ifdef SYSTEM_HPP_ 32 | #include "system.hpp" 33 | #endif 34 | 35 | // hlslib imports 36 | #include "hlslib/xilinx/Flatten.h" 37 | 38 | #define ERROR_TOLERANCE 0.2 39 | 40 | // macro for template variable pragmas 41 | #define PRAGMA_SUB(x) _Pragma (#x) 42 | #define DO_PRAGMA(x) PRAGMA_SUB(x) 43 | 44 | // macro for integer division 45 | #define DIVIDE(a,b) ((const unsigned int) ((a)/(b))) 46 | 47 | // macro for evaluating min and max 48 | #define MAX(a,b) (((a)>(b))?(a):(b)) 49 | #define MIN(a,b) (((a)<(b))?(a):(b)) 50 | 51 | // macro for stream wrapper 52 | #define stream_t(x) hls::stream 53 | /* #define stream_t(x) hlslib::Stream */ 54 | 55 | // default data types 56 | typedef ap_uint<64> mem_int; 57 | typedef ap_axis<64,1,1,1> axi_stream_t; 58 | typedef hls::stream axi_stream_hw_t; 59 | 60 | // 61 | typedef ap_fixed<16, 8,AP_RND> data_t; 62 | typedef ap_fixed<30,16,AP_RND> acc_t; 63 | typedef ap_fixed<16, 8,AP_RND> weight_t; 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /test/layers/split/gen_layer.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | import numpy as np 4 | 5 | sys.path.append("..") 6 | from Layer import Layer 7 | 8 | from fpgaconvnet.models.layers.SplitLayer import SplitLayer 9 | import fpgaconvnet.hls.generate.layers.split as split 10 | 11 | class SplitLayerTB(Layer): 12 | def __init__(self): 13 | self.name = 'split_layer' 14 | Layer.__init__(self,self.name) 15 | 16 | # update stimulus generation 17 | def gen_stimulus(self): 18 | # Init Module 19 | layer = SplitLayer( 20 | self.param['rows_in'], 21 | self.param['cols_in'], 22 | self.param['channels_in'], 23 | coarse=self.param['coarse'] 24 | ) 25 | 26 | # data in 27 | data_in = self.gen_data([ 28 | self.param['rows_in'], 29 | self.param['cols_in'], 30 | self.param['channels_in'] 31 | ],data_range=[-1,1]) 32 | # data out 33 | data_out = layer.functional_model(data_in)[0] 34 | 35 | # add output dimensions 36 | self.param['rows_out'] = layer.rows_out() 37 | self.param['cols_out'] = layer.cols_out() 38 | self.param['channels_out'] = layer.channels_out() 39 | # return data 40 | data = { 41 | 'input' : data_in.reshape(-1).tolist(), 42 | 'output' : data_out.reshape(-1).tolist() 43 | } 44 | # resource and latency model 45 | model = { 46 | 'latency' : layer.latency(), 47 | 'resources' : layer.resource() 48 | } 49 | return data, model 50 | 51 | # update layer generation 52 | def gen_layer(self,src_path,header_path): 53 | split.gen_split_layer( 54 | self.name, 55 | self.param, 56 | os.path.join(src_path,'{}.cpp'.format(self.name)), 57 | os.path.join(header_path,'{}.hpp'.format(self.name)) 58 | ) 59 | 60 | if __name__ == '__main__': 61 | split_layer_tb = SplitLayerTB() 62 | split_layer_tb.main(sys.argv[1:]) -------------------------------------------------------------------------------- /test/layers/relu/gen_layer.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | import numpy as np 4 | 5 | sys.path.append("..") 6 | from Layer import Layer 7 | 8 | from fpgaconvnet.models.layers.ReLULayer import ReLULayer 9 | import fpgaconvnet.hls.generate.layers.relu as relu 10 | 11 | class ReLULayerTB(Layer): 12 | def __init__(self): 13 | self.name = 'relu_layer' 14 | Layer.__init__(self,self.name) 15 | 16 | # update stimulus generation 17 | def gen_stimulus(self): 18 | # Init Module 19 | layer = ReLULayer( 20 | self.param['rows_in'], 21 | self.param['cols_in'], 22 | self.param['channels_in'], 23 | coarse=self.param['coarse'] 24 | ) 25 | 26 | # data in 27 | data_in = self.gen_data([ 28 | self.param['rows_in'], 29 | self.param['cols_in'], 30 | self.param['channels_in'] 31 | ],data_range=[-1,1]) 32 | # data out 33 | data_out = layer.functional_model(data_in)[0] 34 | data_out = np.moveaxis(data_out,0,-1) 35 | 36 | # add output dimensions 37 | self.param['rows_out'] = layer.rows_out() 38 | self.param['cols_out'] = layer.cols_out() 39 | self.param['channels_out'] = layer.channels_out() 40 | # return data 41 | data = { 42 | 'input' : data_in.reshape(-1).tolist(), 43 | 'output' : data_out.reshape(-1).tolist() 44 | } 45 | # resource and latency model 46 | model = { 47 | 'latency' : layer.latency(), 48 | 'resources' : layer.resource() 49 | } 50 | return data, model 51 | 52 | # update layer generation 53 | def gen_layer(self,src_path,header_path): 54 | relu.gen_relu_layer( 55 | self.name, 56 | self.param, 57 | os.path.join(src_path,'{}.cpp'.format(self.name)), 58 | os.path.join(header_path,'{}.hpp'.format(self.name)) 59 | ) 60 | 61 | if __name__ == '__main__': 62 | relu_layer_tb = ReLULayerTB() 63 | relu_layer_tb.main(sys.argv[1:]) 64 | --------------------------------------------------------------------------------