├── noc.png ├── examples ├── noc2d.png ├── setenv.sh ├── nocpad_ACE_4m-2s_1stage │ ├── ace_main.cpp │ ├── Makefile │ └── go_hls_ic.tcl ├── nocpad_2m-2s_2d-mesh_reorder │ ├── axi_main.cpp │ ├── Makefile │ ├── go_hls_ic.tcl │ └── ic_top_2d.h ├── nocpad_ACE-lite_2m-2mlite-2s_1stage │ ├── ace_main.cpp │ ├── Makefile │ └── go_hls_ic.tcl ├── nocpad_2m-2s_2d-mesh_basic-order │ ├── axi_main.cpp │ ├── Makefile │ ├── go_hls_ic.tcl │ └── ic_top_2d.h ├── nocpad_2m-2s_2d-mesh_id-order │ ├── axi_main.cpp │ ├── Makefile │ ├── go_hls_ic.tcl │ └── ic_top_2d.h ├── nocpad_2m-2s_2d-mesh_vc-req-resp_id-order │ ├── axi_main.cpp │ ├── Makefile │ └── go_hls_ic.tcl └── README.md ├── tb ├── helper_non_synth.h ├── README.md ├── tb_wrap.h └── tb_axi_con │ └── axi_slave.h ├── LICENSE ├── src ├── include │ ├── rc.h │ ├── axi4_configs_extra.h │ ├── dnp20_axi.h │ ├── fifo_queue_oh.h │ ├── dnp_ace_v0.h │ ├── onehot.h │ ├── flit_axi.h │ ├── arbiters.h │ ├── flit_ace.h │ └── ace.h ├── README.md ├── router_wh.h ├── router_vc.h └── ace │ └── ace_home.h └── README.md /noc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ic-lab-duth/NoCpad/HEAD/noc.png -------------------------------------------------------------------------------- /examples/noc2d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ic-lab-duth/NoCpad/HEAD/examples/noc2d.png -------------------------------------------------------------------------------- /examples/setenv.sh: -------------------------------------------------------------------------------- 1 | export CATAPULT_HOME=/opt/mentor/catapult_10.5a/ 2 | export SYSTEMC_HOME=/opt/lib/systemc 3 | export BOOST_HOME=/opt/lib/boost 4 | export MATCHLIB_HOME=/opt/lib/matchlib/matchlib-master 5 | 6 | #Although Matchlib connections included in Catapult 7 | export CONNECTIONS_HOME=/opt/lib/connections 8 | -------------------------------------------------------------------------------- /tb/helper_non_synth.h: -------------------------------------------------------------------------------- 1 | #ifndef __DUTH_HELPER_NON_SYNTH__ 2 | #define __DUTH_HELPER_NON_SYNTH__ 3 | 4 | unsigned int my_log2c(unsigned int val) { 5 | /// ceil(log2) integer calculation. Returns -1 for log2(0) 6 | unsigned int ret = -1; 7 | while (val != 0) { 8 | val >>= 1; 9 | ret++; 10 | } 11 | return ret; 12 | } 13 | 14 | 15 | #endif // __DUTH_HELPER_NON_SYNTH__ 16 | -------------------------------------------------------------------------------- /examples/nocpad_ACE_4m-2s_1stage/ace_main.cpp: -------------------------------------------------------------------------------- 1 | #include "./ic_top.h" 2 | #include "../../tb/tb_ace/harness.h" 3 | 4 | sc_trace_file* trace_file_ptr; 5 | 6 | int sc_main(int argc, char *argv[]) { 7 | 8 | trace_file_ptr = sc_create_vcd_trace_file("trace"); 9 | 10 | harness the_harness("the_harness"); 11 | sc_start(); 12 | 13 | return (0); 14 | 15 | }; // End of main 16 | -------------------------------------------------------------------------------- /examples/nocpad_2m-2s_2d-mesh_reorder/axi_main.cpp: -------------------------------------------------------------------------------- 1 | #include "./ic_top_2d.h" 2 | #include "../../tb/tb_axi_con/harness.h" 3 | 4 | sc_trace_file* trace_file_ptr; 5 | 6 | int sc_main(int argc, char *argv[]) { 7 | 8 | trace_file_ptr = sc_create_vcd_trace_file("trace"); 9 | 10 | harness the_harness("the_harness"); 11 | sc_start(); 12 | 13 | return (0); 14 | 15 | }; // End of main 16 | -------------------------------------------------------------------------------- /examples/nocpad_ACE-lite_2m-2mlite-2s_1stage/ace_main.cpp: -------------------------------------------------------------------------------- 1 | #include "./ic_top.h" 2 | #include "../../tb/tb_ace/harness.h" 3 | 4 | sc_trace_file* trace_file_ptr; 5 | 6 | int sc_main(int argc, char *argv[]) { 7 | 8 | trace_file_ptr = sc_create_vcd_trace_file("trace"); 9 | 10 | harness the_harness("the_harness"); 11 | sc_start(); 12 | 13 | return (0); 14 | 15 | }; // End of main 16 | -------------------------------------------------------------------------------- /examples/nocpad_2m-2s_2d-mesh_basic-order/axi_main.cpp: -------------------------------------------------------------------------------- 1 | #include "./ic_top_2d.h" 2 | #include "../../tb/tb_axi_con/harness.h" 3 | 4 | sc_trace_file* trace_file_ptr; 5 | 6 | int sc_main(int argc, char *argv[]) { 7 | 8 | trace_file_ptr = sc_create_vcd_trace_file("trace"); 9 | 10 | harness the_harness("the_harness"); 11 | sc_start(); 12 | 13 | return (0); 14 | 15 | }; // End of main 16 | -------------------------------------------------------------------------------- /examples/nocpad_2m-2s_2d-mesh_id-order/axi_main.cpp: -------------------------------------------------------------------------------- 1 | #include "./ic_top_2d.h" 2 | #include "../../tb/tb_axi_con/harness.h" 3 | 4 | sc_trace_file* trace_file_ptr; 5 | 6 | int sc_main(int argc, char *argv[]) { 7 | 8 | trace_file_ptr = sc_create_vcd_trace_file("trace"); 9 | 10 | harness the_harness("the_harness"); 11 | sc_start(); 12 | 13 | return (0); 14 | 15 | }; // End of main 16 | -------------------------------------------------------------------------------- /examples/nocpad_2m-2s_2d-mesh_vc-req-resp_id-order/axi_main.cpp: -------------------------------------------------------------------------------- 1 | #include "./ic_top_2d_1noc.h" 2 | #include "../../tb/tb_axi_con/harness.h" 3 | 4 | sc_trace_file* trace_file_ptr; 5 | 6 | int sc_main(int argc, char *argv[]) { 7 | 8 | trace_file_ptr = sc_create_vcd_trace_file("trace"); 9 | 10 | harness the_harness("the_harness"); 11 | sc_start(); 12 | 13 | return (0); 14 | 15 | }; // End of main 16 | -------------------------------------------------------------------------------- /tb/README.md: -------------------------------------------------------------------------------- 1 | - `tb/tb_axi_con/axi_master.h` Testbench component that generates diverse Requests and verifies the responses 2 | - `tb/tb_axi_con/axi_slave.h` Testbench component that consumes and verifies received AXI Requests and produces AXI responses 3 | - `tb/tb_axi_con/harness.h` Testbench component that parameterizes and setups the necessary testbench master-slave agents and connects the underlying DUT AXI interconnect. 4 | -------------------------------------------------------------------------------- /tb/tb_wrap.h: -------------------------------------------------------------------------------- 1 | #ifndef __TB_WRAP_H__ 2 | #define __TB_WRAP_H__ 3 | 4 | #include "systemc.h" 5 | #include "nvhls_connections.h" 6 | 7 | #ifndef __SYNTHESIS__ 8 | #include 9 | #include 10 | #endif 11 | 12 | 13 | template 14 | struct msg_tb_wrap { 15 | T dut_msg; 16 | 17 | sc_time time_gen; 18 | sc_time time_inj; 19 | 20 | sc_time time_ej; 21 | 22 | bool is_read = false; 23 | 24 | inline friend std::ostream& operator << ( std::ostream& os, const msg_tb_wrap& msg_tmp ) { 25 | os << msg_tmp.dut_msg; 26 | return os; 27 | } 28 | 29 | // Only for SystemC 30 | inline friend void sc_trace(sc_trace_file* tf, const msg_tb_wrap& msg, const std::string& name) { 31 | sc_trace(tf, msg.dut_msg, name); 32 | } 33 | 34 | }; 35 | 36 | #endif // __TB_WRAP_H__ 37 | 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Nocpad LICENSE 2 | 3 | Copyright (c) 2019-2020 Integrated Circuits Lab, Democritus University of Thrace, Greece. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/include/rc.h: -------------------------------------------------------------------------------- 1 | #ifndef __ROUTING_COMPUTATION_HEADER__ 2 | #define __ROUTING_COMPUTATION_HEADER__ 3 | 4 | #include 5 | #include "./dnp_ace_v0.h" 6 | 7 | enum rc_t {RC_DIRECT, RC_XY, RC_FIXED, RC_TYPE, RC_COMMON}; 8 | 9 | // Direct RC : The Dst Node is the Output port 10 | //template 11 | //inline unsigned char do_rc(T...params); 12 | 13 | template 14 | inline unsigned char do_rc(T...params); 15 | 16 | template<> 17 | inline unsigned char do_rc > (sc_uint destination) {return destination;}; 18 | 19 | // TYPE RC : Used for splitter/mergers. Routes RD to Out==0, and WR to Out==1 20 | template<> 21 | inline unsigned char do_rc > (sc_lv type) {return (type==dnp::PACK_TYPE__RD_REQ || type==dnp::PACK_TYPE__RD_RESP) ? 0 : 1;}; 22 | 23 | // Const RC : Used for mergers to always request port #0 24 | template<> 25 | inline unsigned char do_rc () {return 0;}; 26 | 27 | // Const RC : Used for mergers to always request port #0 28 | template<> 29 | inline unsigned char do_rc, sc_lv > (sc_lv destination, sc_lv type) { 30 | if (type==dnp::PACK_TYPE__RD_REQ || type==dnp::PACK_TYPE__RD_RESP) return destination.to_uint(); 31 | else return destination.to_uint()+2; 32 | }; 33 | // LUT RC : the Outport is selected from a LUT 34 | //inline unsigned char do_rc_lut (sc_lv dst) {return route_lut[dst];}; 35 | 36 | #endif // __ROUTING_COMPUTATION_HEADER__ 37 | -------------------------------------------------------------------------------- /src/include/axi4_configs_extra.h: -------------------------------------------------------------------------------- 1 | #ifndef __AXI_CONFIG_DUTH_H__ 2 | #define __AXI_CONFIG_DUTH_H__ 3 | 4 | namespace axi { 5 | 6 | // Extension of Matchlib AXI configuration 7 | namespace cfg { 8 | /** 9 | * \brief A standard AXI configuration with SIZE field. 10 | */ 11 | struct standard_duth { 12 | enum { 13 | useACE = 0, 14 | dataWidth = 64, 15 | useVariableBeatSize = 1, 16 | useMisalignedAddresses = 0, 17 | useLast = 1, 18 | useWriteStrobes = 1, 19 | useBurst = 1, useFixedBurst = 1, useWrapBurst = 0, maxBurstSize = 256, 20 | useQoS = 0, useLock = 0, useProt = 0, useCache = 0, useRegion = 0, 21 | aUserWidth = 0, wUserWidth = 0, bUserWidth = 0, rUserWidth = 0, 22 | addrWidth = 32, 23 | idWidth = 4, 24 | useWriteResponses = 1, 25 | }; 26 | }; 27 | 28 | struct standard_duth_128 { 29 | enum { 30 | useACE = 0, 31 | dataWidth = 128, 32 | useVariableBeatSize = 1, 33 | useMisalignedAddresses = 0, 34 | useLast = 1, 35 | useWriteStrobes = 1, 36 | useBurst = 1, useFixedBurst = 1, useWrapBurst = 0, maxBurstSize = 256, 37 | useQoS = 0, useLock = 0, useProt = 0, useCache = 0, useRegion = 0, 38 | aUserWidth = 0, wUserWidth = 0, bUserWidth = 0, rUserWidth = 0, 39 | addrWidth = 32, 40 | idWidth = 4, 41 | useWriteResponses = 1, 42 | }; 43 | }; 44 | /** 45 | * \brief ACE enabled, AXI configuration. 46 | */ 47 | struct ace { 48 | enum { 49 | useACE = 1, 50 | CacheLineWidth = 64, // bits 51 | dataWidth = 64, 52 | useVariableBeatSize = 1, 53 | useMisalignedAddresses = 0, 54 | useLast = 1, 55 | useWriteStrobes = 1, 56 | useBurst = 1, useFixedBurst = 1, useWrapBurst = 0, maxBurstSize = 256, 57 | useQoS = 0, useLock = 0, useProt = 0, useCache = 0, useRegion = 0, 58 | aUserWidth = 0, wUserWidth = 0, bUserWidth = 0, rUserWidth = 0, 59 | addrWidth = 32, 60 | idWidth = 4, 61 | useWriteResponses = 1, 62 | }; 63 | }; 64 | }; // namespace cfg 65 | }; // namespace axi 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /examples/nocpad_ACE_4m-2s_1stage/Makefile: -------------------------------------------------------------------------------- 1 | CC = g++ 2 | 3 | INCDIR ?= 4 | INCDIR += -I. -I$(SYSTEMC_HOME)/include -I$(BOOST_HOME)/include -I$(CATAPULT_HOME)/Mgc_home/shared/include -I$(MATCHLIB_HOME)/cmod/include 5 | 6 | 7 | LIBDIR ?= 8 | LIBDIR += -L. -L$(SYSTEMC_HOME)/lib-linux64 -L$(BOOST_HOME)/lib 9 | 10 | CFLAGS ?= 11 | CFLAGS += -Wall -Wno-unknown-pragmas $(INCDIR) $(LIBDIR) 12 | 13 | HLS_CATAPULT ?= 1 14 | ifeq ($(HLS_CATAPULT),1) 15 | CFLAGS += -DHLS_CATAPULT 16 | endif 17 | 18 | LIBS ?= 19 | LIBS += -lstdc++ -lsystemc -lm -lpthread -lboost_timer -lboost_chrono -lboost_system 20 | 21 | # SIM_MODE 22 | # 0 = Synthesis view of Connections port and combinational code. 23 | # This option can cause failed simulations due to SystemC's timing model. 24 | # 1 = Cycle-accurate view of Connections port and channel code, CONNECTIONS_ACCURATE_SIM. (default) 25 | # 2 = Faster TLM view of Connections port and channel code, CONNECTIONS_FAST_SIM. 26 | SIM_MODE ?= 1 27 | ifeq ($(SIM_MODE),1) 28 | USER_FLAGS += -DCONNECTIONS_ACCURATE_SIM -DSC_INCLUDE_DYNAMIC_PROCESSES 29 | endif 30 | ifeq ($(SIM_MODE),2) 31 | USER_FLAGS += -DCONNECTIONS_FAST_SIM -DSC_INCLUDE_DYNAMIC_PROCESSES 32 | endif 33 | 34 | # RAND_STALL 35 | # 0 = Random stall of ports and channels disabled (default) 36 | # 1 = Random stall of ports and channels enabled 37 | # This feature aids in latency insensitive design verication. 38 | # Note: Only valid if SIM_MODE = 1 (accurate) or 2 (fast) 39 | ifeq ($(RAND_STALL),1) 40 | USER_FLAGS += -DCONN_RAND_STALL 41 | endif 42 | 43 | .PHONY: Build 44 | Build: all 45 | 46 | 47 | 48 | CFLAGS += -O0 -g -std=c++11 49 | 50 | all: sim_sc 51 | 52 | LIBDIR += -L$(SYSTEMC_HOME)/lib -L$(BOOST_HOME)/stage/lib 53 | 54 | USER_FLAGS += -DSC_INCLUDE_DYNAMIC_PROCESSES -DCONNECTIONS_ACCURATE_SIM 55 | 56 | USER_FLAGS += -DUSE_ROUTER_ST_BUF 57 | 58 | run: 59 | ./sim_sc 60 | 61 | sim_sc: $(wildcard ../../src/include/*.h) $(wildcard ../../src/ace/*.h) $(wildcard ../../src/*.h) 62 | $(CC) -o sim_sc $(CFLAGS) $(USER_FLAGS) ./ace_main.cpp $(BOOSTLIBS) $(LIBS) 63 | 64 | clean: sim_clean 65 | 66 | sim_clean: 67 | rm -rf *.o sim_* out.wlf trace.vcd transcript Cata* design_check* *.vhd cata*log sim_* trace.vcd out.wlf transcript 68 | -------------------------------------------------------------------------------- /examples/nocpad_2m-2s_2d-mesh_id-order/Makefile: -------------------------------------------------------------------------------- 1 | CC = g++ 2 | 3 | INCDIR ?= 4 | INCDIR += -I. -I$(SYSTEMC_HOME)/include -I$(BOOST_HOME)/include -I$(CATAPULT_HOME)/Mgc_home/shared/include -I$(MATCHLIB_HOME)/cmod/include 5 | 6 | 7 | LIBDIR ?= 8 | LIBDIR += -L. -L$(SYSTEMC_HOME)/lib-linux64 -L$(BOOST_HOME)/lib 9 | 10 | CFLAGS ?= 11 | CFLAGS += -Wall -Wno-unknown-pragmas $(INCDIR) $(LIBDIR) 12 | 13 | HLS_CATAPULT ?= 1 14 | ifeq ($(HLS_CATAPULT),1) 15 | CFLAGS += -DHLS_CATAPULT 16 | endif 17 | 18 | LIBS ?= 19 | LIBS += -lstdc++ -lsystemc -lm -lpthread -lboost_timer -lboost_chrono -lboost_system 20 | 21 | # SIM_MODE 22 | # 0 = Synthesis view of Connections port and combinational code. 23 | # This option can cause failed simulations due to SystemC's timing model. 24 | # 1 = Cycle-accurate view of Connections port and channel code, CONNECTIONS_ACCURATE_SIM. (default) 25 | # 2 = Faster TLM view of Connections port and channel code, CONNECTIONS_FAST_SIM. 26 | SIM_MODE ?= 1 27 | ifeq ($(SIM_MODE),1) 28 | USER_FLAGS += -DCONNECTIONS_ACCURATE_SIM -DSC_INCLUDE_DYNAMIC_PROCESSES 29 | endif 30 | ifeq ($(SIM_MODE),2) 31 | USER_FLAGS += -DCONNECTIONS_FAST_SIM -DSC_INCLUDE_DYNAMIC_PROCESSES 32 | endif 33 | 34 | # RAND_STALL 35 | # 0 = Random stall of ports and channels disabled (default) 36 | # 1 = Random stall of ports and channels enabled 37 | # This feature aids in latency insensitive design verication. 38 | # Note: Only valid if SIM_MODE = 1 (accurate) or 2 (fast) 39 | ifeq ($(RAND_STALL),1) 40 | USER_FLAGS += -DCONN_RAND_STALL 41 | endif 42 | 43 | .PHONY: Build 44 | Build: all 45 | 46 | CFLAGS += -O0 -g -std=c++11 47 | 48 | all: sim_sc 49 | 50 | LIBDIR += -L$(SYSTEMC_HOME)/lib -L$(BOOST_HOME)/stage/lib 51 | 52 | USER_FLAGS += -DSC_INCLUDE_DYNAMIC_PROCESSES -DCONNECTIONS_ACCURATE_SIM 53 | 54 | USER_FLAGS += -DUSE_ROUTER_ST_BUF 55 | 56 | run: 57 | ./sim_sc 58 | 59 | sim_sc: $(wildcard ../../src/include/*.h) $(wildcard ../../src/axi_ifs/*.h) $(wildcard ../../src/routers/*.h) 60 | $(CC) -o sim_sc $(CFLAGS) $(USER_FLAGS) ./axi_main.cpp $(BOOSTLIBS) $(LIBS) 61 | 62 | clean: sim_clean 63 | 64 | sim_clean: 65 | rm -rf *.o sim_* out.wlf trace.vcd transcript Cata* design_check* *.vhd cata*log sim_* trace.vcd out.wlf transcript 66 | -------------------------------------------------------------------------------- /examples/nocpad_2m-2s_2d-mesh_basic-order/Makefile: -------------------------------------------------------------------------------- 1 | CC = g++ 2 | 3 | INCDIR ?= 4 | INCDIR += -I. -I$(SYSTEMC_HOME)/include -I$(BOOST_HOME)/include -I$(CATAPULT_HOME)/Mgc_home/shared/include -I$(MATCHLIB_HOME)/cmod/include 5 | 6 | 7 | LIBDIR ?= 8 | LIBDIR += -L. -L$(SYSTEMC_HOME)/lib-linux64 -L$(BOOST_HOME)/lib 9 | 10 | CFLAGS ?= 11 | CFLAGS += -Wall -Wno-unknown-pragmas $(INCDIR) $(LIBDIR) 12 | 13 | HLS_CATAPULT ?= 1 14 | ifeq ($(HLS_CATAPULT),1) 15 | CFLAGS += -DHLS_CATAPULT 16 | endif 17 | 18 | LIBS ?= 19 | LIBS += -lstdc++ -lsystemc -lm -lpthread -lboost_timer -lboost_chrono -lboost_system 20 | 21 | # SIM_MODE 22 | # 0 = Synthesis view of Connections port and combinational code. 23 | # This option can cause failed simulations due to SystemC's timing model. 24 | # 1 = Cycle-accurate view of Connections port and channel code, CONNECTIONS_ACCURATE_SIM. (default) 25 | # 2 = Faster TLM view of Connections port and channel code, CONNECTIONS_FAST_SIM. 26 | SIM_MODE ?= 1 27 | ifeq ($(SIM_MODE),1) 28 | USER_FLAGS += -DCONNECTIONS_ACCURATE_SIM -DSC_INCLUDE_DYNAMIC_PROCESSES 29 | endif 30 | ifeq ($(SIM_MODE),2) 31 | USER_FLAGS += -DCONNECTIONS_FAST_SIM -DSC_INCLUDE_DYNAMIC_PROCESSES 32 | endif 33 | 34 | # RAND_STALL 35 | # 0 = Random stall of ports and channels disabled (default) 36 | # 1 = Random stall of ports and channels enabled 37 | # This feature aids in latency insensitive design verication. 38 | # Note: Only valid if SIM_MODE = 1 (accurate) or 2 (fast) 39 | ifeq ($(RAND_STALL),1) 40 | USER_FLAGS += -DCONN_RAND_STALL 41 | endif 42 | 43 | .PHONY: Build 44 | Build: all 45 | 46 | 47 | CFLAGS += -O0 -g -std=c++11 48 | 49 | all: sim_sc 50 | 51 | LIBDIR += -L$(SYSTEMC_HOME)/lib -L$(BOOST_HOME)/stage/lib 52 | 53 | USER_FLAGS += -DSC_INCLUDE_DYNAMIC_PROCESSES -DCONNECTIONS_ACCURATE_SIM 54 | 55 | USER_FLAGS += -DUSE_ROUTER_ST_BUF 56 | 57 | run: 58 | ./sim_sc 59 | 60 | sim_sc: $(wildcard ../../src/include/*.h) $(wildcard ../../src/axi_ifs/*.h) $(wildcard ../../src/routers/*.h) 61 | $(CC) -o sim_sc $(CFLAGS) $(USER_FLAGS) ./axi_main.cpp $(BOOSTLIBS) $(LIBS) 62 | 63 | clean: sim_clean 64 | 65 | sim_clean: 66 | rm -rf *.o sim_* out.wlf trace.vcd transcript Cata* design_check* *.vhd cata*log sim_* trace.vcd out.wlf transcript 67 | -------------------------------------------------------------------------------- /examples/nocpad_ACE-lite_2m-2mlite-2s_1stage/Makefile: -------------------------------------------------------------------------------- 1 | CC = g++ 2 | 3 | INCDIR ?= 4 | INCDIR += -I. -I$(SYSTEMC_HOME)/include -I$(BOOST_HOME)/include -I$(CATAPULT_HOME)/Mgc_home/shared/include -I$(MATCHLIB_HOME)/cmod/include 5 | 6 | 7 | LIBDIR ?= 8 | LIBDIR += -L. -L$(SYSTEMC_HOME)/lib-linux64 -L$(BOOST_HOME)/lib 9 | 10 | CFLAGS ?= 11 | CFLAGS += -Wall -Wno-unknown-pragmas $(INCDIR) $(LIBDIR) 12 | 13 | HLS_CATAPULT ?= 1 14 | ifeq ($(HLS_CATAPULT),1) 15 | CFLAGS += -DHLS_CATAPULT 16 | endif 17 | 18 | LIBS ?= 19 | LIBS += -lstdc++ -lsystemc -lm -lpthread -lboost_timer -lboost_chrono -lboost_system 20 | 21 | # SIM_MODE 22 | # 0 = Synthesis view of Connections port and combinational code. 23 | # This option can cause failed simulations due to SystemC's timing model. 24 | # 1 = Cycle-accurate view of Connections port and channel code, CONNECTIONS_ACCURATE_SIM. (default) 25 | # 2 = Faster TLM view of Connections port and channel code, CONNECTIONS_FAST_SIM. 26 | SIM_MODE ?= 1 27 | ifeq ($(SIM_MODE),1) 28 | USER_FLAGS += -DCONNECTIONS_ACCURATE_SIM -DSC_INCLUDE_DYNAMIC_PROCESSES 29 | endif 30 | ifeq ($(SIM_MODE),2) 31 | USER_FLAGS += -DCONNECTIONS_FAST_SIM -DSC_INCLUDE_DYNAMIC_PROCESSES 32 | endif 33 | 34 | # RAND_STALL 35 | # 0 = Random stall of ports and channels disabled (default) 36 | # 1 = Random stall of ports and channels enabled 37 | # This feature aids in latency insensitive design verication. 38 | # Note: Only valid if SIM_MODE = 1 (accurate) or 2 (fast) 39 | ifeq ($(RAND_STALL),1) 40 | USER_FLAGS += -DCONN_RAND_STALL 41 | endif 42 | 43 | .PHONY: Build 44 | Build: all 45 | 46 | 47 | 48 | CFLAGS += -O0 -g -std=c++11 49 | 50 | all: sim_sc 51 | 52 | LIBDIR += -L$(SYSTEMC_HOME)/lib -L$(BOOST_HOME)/stage/lib 53 | 54 | USER_FLAGS += -DSC_INCLUDE_DYNAMIC_PROCESSES -DCONNECTIONS_ACCURATE_SIM 55 | 56 | USER_FLAGS += -DUSE_ROUTER_ST_BUF 57 | 58 | run: 59 | ./sim_sc 60 | 61 | sim_sc: $(wildcard ../../src/include/*.h) $(wildcard ../../src/ace/*.h) $(wildcard ../../src/*.h) 62 | $(CC) -o sim_sc $(CFLAGS) $(USER_FLAGS) ./ace_main.cpp $(BOOSTLIBS) $(LIBS) 63 | 64 | clean: sim_clean 65 | 66 | sim_clean: 67 | rm -rf *.o sim_* out.wlf trace.vcd transcript Cata* design_check* *.vhd cata*log sim_* trace.vcd out.wlf transcript 68 | -------------------------------------------------------------------------------- /examples/nocpad_2m-2s_2d-mesh_reorder/Makefile: -------------------------------------------------------------------------------- 1 | CC = g++ 2 | 3 | INCDIR ?= 4 | INCDIR += -I. -I$(SYSTEMC_HOME)/include -I$(BOOST_HOME)/include -I$(CATAPULT_HOME)/Mgc_home/shared/include -I$(MATCHLIB_HOME)/cmod/include 5 | 6 | 7 | LIBDIR ?= 8 | LIBDIR += -L. -L$(SYSTEMC_HOME)/lib-linux64 -L$(BOOST_HOME)/lib 9 | 10 | CFLAGS ?= 11 | CFLAGS += -Wall -Wno-unknown-pragmas $(INCDIR) $(LIBDIR) 12 | 13 | HLS_CATAPULT ?= 1 14 | ifeq ($(HLS_CATAPULT),1) 15 | CFLAGS += -DHLS_CATAPULT 16 | endif 17 | 18 | LIBS ?= 19 | LIBS += -lstdc++ -lsystemc -lm -lpthread -lboost_timer -lboost_chrono -lboost_system 20 | 21 | # SIM_MODE 22 | # 0 = Synthesis view of Connections port and combinational code. 23 | # This option can cause failed simulations due to SystemC's timing model. 24 | # 1 = Cycle-accurate view of Connections port and channel code, CONNECTIONS_ACCURATE_SIM. (default) 25 | # 2 = Faster TLM view of Connections port and channel code, CONNECTIONS_FAST_SIM. 26 | SIM_MODE ?= 1 27 | ifeq ($(SIM_MODE),1) 28 | USER_FLAGS += -DCONNECTIONS_ACCURATE_SIM -DSC_INCLUDE_DYNAMIC_PROCESSES 29 | endif 30 | ifeq ($(SIM_MODE),2) 31 | USER_FLAGS += -DCONNECTIONS_FAST_SIM -DSC_INCLUDE_DYNAMIC_PROCESSES 32 | endif 33 | 34 | # RAND_STALL 35 | # 0 = Random stall of ports and channels disabled (default) 36 | # 1 = Random stall of ports and channels enabled 37 | # This feature aids in latency insensitive design verication. 38 | # Note: Only valid if SIM_MODE = 1 (accurate) or 2 (fast) 39 | ifeq ($(RAND_STALL),1) 40 | USER_FLAGS += -DCONN_RAND_STALL 41 | endif 42 | 43 | .PHONY: Build 44 | Build: all 45 | 46 | 47 | 48 | CFLAGS += -O0 -g -std=c++11 49 | 50 | all: sim_sc 51 | 52 | LIBDIR += -L$(SYSTEMC_HOME)/lib -L$(BOOST_HOME)/stage/lib 53 | 54 | USER_FLAGS += -DSC_INCLUDE_DYNAMIC_PROCESSES -DCONNECTIONS_ACCURATE_SIM 55 | 56 | USER_FLAGS += -DUSE_ROUTER_ST_BUF 57 | 58 | run: 59 | ./sim_sc 60 | 61 | sim_sc: $(wildcard ../../src/include/*.h) $(wildcard ../../src/axi_ifs/*.h) $(wildcard ../../src/routers/*.h) 62 | $(CC) -o sim_sc $(CFLAGS) $(USER_FLAGS) ./axi_main.cpp $(BOOSTLIBS) $(LIBS) 63 | 64 | clean: sim_clean 65 | 66 | sim_clean: 67 | rm -rf *.o sim_* out.wlf trace.vcd transcript Cata* design_check* *.vhd cata*log sim_* trace.vcd out.wlf transcript 68 | -------------------------------------------------------------------------------- /examples/nocpad_2m-2s_2d-mesh_vc-req-resp_id-order/Makefile: -------------------------------------------------------------------------------- 1 | CC = g++ 2 | 3 | INCDIR ?= 4 | INCDIR += -I. -I$(SYSTEMC_HOME)/include -I$(BOOST_HOME)/include -I$(CATAPULT_HOME)/Mgc_home/shared/include -I$(MATCHLIB_HOME)/cmod/include 5 | 6 | 7 | LIBDIR ?= 8 | LIBDIR += -L. -L$(SYSTEMC_HOME)/lib-linux64 -L$(BOOST_HOME)/lib 9 | 10 | CFLAGS ?= 11 | CFLAGS += -Wall -Wno-unknown-pragmas $(INCDIR) $(LIBDIR) 12 | 13 | HLS_CATAPULT ?= 1 14 | ifeq ($(HLS_CATAPULT),1) 15 | CFLAGS += -DHLS_CATAPULT 16 | endif 17 | 18 | LIBS ?= 19 | LIBS += -lstdc++ -lsystemc -lm -lpthread -lboost_timer -lboost_chrono -lboost_system 20 | 21 | # SIM_MODE 22 | # 0 = Synthesis view of Connections port and combinational code. 23 | # This option can cause failed simulations due to SystemC's timing model. 24 | # 1 = Cycle-accurate view of Connections port and channel code, CONNECTIONS_ACCURATE_SIM. (default) 25 | # 2 = Faster TLM view of Connections port and channel code, CONNECTIONS_FAST_SIM. 26 | SIM_MODE ?= 1 27 | ifeq ($(SIM_MODE),1) 28 | USER_FLAGS += -DCONNECTIONS_ACCURATE_SIM -DSC_INCLUDE_DYNAMIC_PROCESSES 29 | endif 30 | ifeq ($(SIM_MODE),2) 31 | USER_FLAGS += -DCONNECTIONS_FAST_SIM -DSC_INCLUDE_DYNAMIC_PROCESSES 32 | endif 33 | 34 | # RAND_STALL 35 | # 0 = Random stall of ports and channels disabled (default) 36 | # 1 = Random stall of ports and channels enabled 37 | # This feature aids in latency insensitive design verication. 38 | # Note: Only valid if SIM_MODE = 1 (accurate) or 2 (fast) 39 | ifeq ($(RAND_STALL),1) 40 | USER_FLAGS += -DCONN_RAND_STALL 41 | endif 42 | 43 | .PHONY: Build 44 | Build: all 45 | 46 | 47 | 48 | CFLAGS += -O0 -g -std=c++11 49 | 50 | all: sim_sc 51 | 52 | LIBDIR += -L$(SYSTEMC_HOME)/lib -L$(BOOST_HOME)/stage/lib 53 | 54 | USER_FLAGS += -DSC_INCLUDE_DYNAMIC_PROCESSES -DCONNECTIONS_ACCURATE_SIM 55 | 56 | USER_FLAGS += -DUSE_ROUTER_ST_BUF 57 | 58 | run: 59 | ./sim_sc 60 | 61 | sim_sc: $(wildcard ../../src/include/*.h) $(wildcard ../../src/axi_ifs/*.h) $(wildcard ../../src/routers/*.h) 62 | $(CC) -o sim_sc $(CFLAGS) $(USER_FLAGS) ./axi_main.cpp $(BOOSTLIBS) $(LIBS) 63 | 64 | clean: sim_clean 65 | 66 | sim_clean: 67 | rm -rf *.o sim_* out.wlf trace.vcd transcript Cata* design_check* *.vhd cata*log sim_* trace.vcd out.wlf transcript 68 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | ![Homogeneous NoC with a 2D mesh topology](noc2d.png) 2 | 3 | ## Networks-on-Chip with AXI-4 interfaces 4 | 5 | `examples/nocpad_2m-2s_2d-mesh_basic-order/ic_top_2d.h` 6 | 2 Master-2 Slave 64bit AXI interconnect with two separate 2-D mesh Request-Response networks. 7 | The ordering scheme allows outstanding transaction only towards the same destination, 8 | to follow AXI transaction ordering requirements 9 | 10 | `examples/nocpad_2m-2s_2d-mesh_id-order/ic_top_2d.h` 11 | Same network architecture. The ordering scheme allows outstanding to multiple destinations for transactions of 12 | different IDs, following AXI ordering requirements. 13 | 14 | `examples/nocpad_2m-2s_2d-mesh_reorder/ic_top_2d.h` Same network architecture. 15 | The ordering scheme allows outstanding even where transaction reordering is possible, 16 | but utilizes a reordering buffer to guarantee AXI compatible ID order. 17 | 18 | `examples/nocpad_2m-2s_2d-mesh_vc-req-resp_id-order/ic_top_2d_1noc.h` 19 | 2 Master-2 Slave 64bit AXI interconnect with a single 2-D mesh with separate Virtual Channels for 20 | Requests and Responses to avoid deadlocks. The ordering scheme is that of multiple destinations. 21 | 22 | ## Cache-coherent Networks-on-Chip with ACE-4 and ACE4-lite interfaces 23 | 24 | `examples/nocpad_ACE-lite_2m-2mlite-2s_1stage/ic_top.h` 25 | 2 ACE Master,2 ACE-Lite Master and 2 Slave 64bit AXI interconnect with a single HOME node for coherency management. ACE Masters maintain cached data and are getting snooped in case of coherent transactions, whereas ACE-lite masters only participate to access data without an internal cache thus there is no need to get snooped. The internal NoC uses separate 1stage Networks for traffic isolation(e.g. requests, responses, snoops requests) to avoid deadlocks. The Read, Write and Snoop data channels are sized according to the chosen configuration parameter for the cache line width. 26 | 27 | `examples/nocpad_ACE_4m-2s_1stage/ic_top.h` 28 | 4 ACE Master - 2 Slave 64bit AXI interconnect with a single HOME node for coherency management. The configuration is to the previous example, but instead only ACE masters participate for cache coherency. 29 | 30 | `examples/*/axi_main.cpp` 31 | Simply matches the examples AXI architecture with the testbench harness 32 | 33 | `examples/*/ace_main.cpp` 34 | Simply matches the examples ACE architecture with the testbench harness 35 | -------------------------------------------------------------------------------- /src/include/dnp20_axi.h: -------------------------------------------------------------------------------- 1 | #ifndef __DNP20_V0_DEF__ 2 | #define __DNP20_V0_DEF__ 3 | 4 | 5 | // Definition of Duth Network Protocol. 6 | // Interconnect's internal packetization protocol 7 | namespace dnp { 8 | enum { 9 | PHIT_W = 24, // Phit Width 10 | 11 | V_W = 2, // Virtual Channel 12 | S_W = 4, // Source 13 | D_W = 4, // Destination 14 | Q_W = 3, // QoS 15 | T_W = 2, // Type 16 | 17 | V_PTR = 0, 18 | S_PTR = (V_PTR + V_W), 19 | D_PTR = (S_PTR + S_W), 20 | Q_PTR = (D_PTR + D_W), 21 | T_PTR = (Q_PTR + Q_W), 22 | 23 | // AXI RELATED WIDTHS 24 | ID_W = 4, // AXI Transaction ID 25 | BU_W = 2, // AXI Burst 26 | SZ_W = 3, // AXI Size 27 | LE_W = 8, // AXI Length 28 | AL_W = 16, // Address Low 29 | AH_W = 16, // Address High 30 | AP_W = 8, // Address part (for alignment) 31 | RE_W = 2, // AXI Write Responce 32 | REORD_W = 3, // Ticket for reorder buffer 33 | 34 | B_W = 8, // Byte Width ... 35 | E_W = 1, // Enable width 36 | LA_W = 1, // AXI Last 37 | }; 38 | 39 | // Read and Write Request field pointers 40 | struct req { 41 | enum { 42 | ID_PTR = T_PTR+T_W, 43 | REORD_PTR = ID_PTR+ID_W, 44 | 45 | AL_PTR = 0, 46 | LE_PTR = AL_PTR+AL_W, 47 | 48 | AH_PTR = 0, 49 | SZ_PTR = AH_PTR+AH_W, 50 | BU_PTR = SZ_PTR+SZ_W, 51 | }; 52 | }; 53 | 54 | // Write Responce field pointers 55 | struct wresp { 56 | enum { 57 | ID_PTR = T_PTR+T_W, 58 | REORD_PTR = ID_PTR+ID_W, 59 | RESP_PTR = REORD_PTR+REORD_W, 60 | }; 61 | }; 62 | 63 | // Read Responce field pointers 64 | struct rresp { 65 | enum { 66 | ID_PTR = T_PTR+T_W, 67 | REORD_PTR = ID_PTR+ID_W, 68 | BU_PTR = REORD_PTR+REORD_W, 69 | 70 | SZ_PTR = 0, 71 | LE_PTR = SZ_PTR+SZ_W, 72 | AP_PTR = LE_PTR+LE_W, 73 | }; 74 | }; 75 | 76 | // Write request Data field pointers 77 | struct wdata { 78 | enum { 79 | B0_PTR = 0, 80 | B1_PTR = B0_PTR+B_W, 81 | E0_PTR = B1_PTR+B_W, 82 | E1_PTR = E0_PTR+E_W, 83 | LA_PTR = E1_PTR+E_W, 84 | }; 85 | }; 86 | 87 | // Read response Data field pointers 88 | struct rdata { 89 | enum { 90 | B0_PTR = 0, 91 | B1_PTR = B0_PTR+B_W, 92 | RE_PTR = B1_PTR+B_W, 93 | LA_PTR = RE_PTR+RE_W, 94 | }; 95 | }; 96 | 97 | enum PACK_TYPE { 98 | PACK_TYPE__WR_REQ = 0, 99 | PACK_TYPE__WR_RESP = 1, 100 | PACK_TYPE__RD_REQ = 2, 101 | PACK_TYPE__RD_RESP = 3 102 | }; 103 | 104 | } 105 | 106 | #endif // __DNP20_V0_DEF__ 107 | -------------------------------------------------------------------------------- /src/include/fifo_queue_oh.h: -------------------------------------------------------------------------------- 1 | #ifndef __FIFO_QUEUE__ 2 | #define __FIFO_QUEUE__ 3 | 4 | #include "../include/duth_fun.h" 5 | #include "../include/nvhls_assert.h" 6 | 7 | template 8 | class fifo_queue { 9 | public : 10 | //typedef sc_uint< clog2::val > wb_depth_t; 11 | T mem[SIZE]; 12 | 13 | sc_uint push_ptr; 14 | sc_uint pop_ptr; 15 | 16 | sc_uint item_count; 17 | 18 | public : 19 | fifo_queue(){ 20 | reset(); 21 | }; 22 | 23 | void reset () { 24 | push_ptr = 1; // points [0] in one hot 25 | pop_ptr = 1; // points [0] in one hot 26 | 27 | item_count = 1; // empty buffer when item_count[0] 28 | // full buffer when item_count[SIZE] 29 | }; 30 | 31 | // Non Intrusive 32 | inline bool full() const {return (item_count[SIZE]);}; 33 | inline bool ready() const {return !full();}; 34 | 35 | inline bool empty() const {return (item_count[0]);}; 36 | inline bool valid() const {return !empty();}; 37 | 38 | inline T peek() const { 39 | //mem[pop_ptr]; 40 | return mux::mux_oh_case(pop_ptr, mem); 41 | //return mux::mux_oh_ao(pop_ptr, mem); 42 | }; 43 | 44 | inline void push_no_count_incr (T &push_val) { 45 | NVHLS_ASSERT_MSG(!full(), "Pushing on FULL!") 46 | #pragma hls_unroll yes 47 | for (int i=0; i>i) & 1; 49 | if (enable && !full()) mem[i] = push_val; 50 | } 51 | inc_push_ptr(); 52 | } 53 | 54 | inline void push(T &push_val) { 55 | NVHLS_ASSERT_MSG(!full(), "Pushing on FULL!") 56 | #pragma hls_unroll yes 57 | for (int i=0; i>i) & 1; 59 | if (enable && !full()) mem[i] = push_val; 60 | } 61 | //mem[push_ptr] = push_val; 62 | //switch (push_ptr) { 63 | // case 1 : mem[0] = push_val; 64 | // break; 65 | // case 2 : mem[1] = push_val; 66 | // break; 67 | // case 4 : mem[2] = push_val; 68 | // break; 69 | // default : ; 70 | // break; 71 | //} 72 | 73 | inc_push_ptr(); 74 | incr_count(); 75 | }; 76 | 77 | inline T pop() { 78 | NVHLS_ASSERT_MSG(!empty(), "Popping on EMPTY!") 79 | T mule = mux::mux_oh_case(pop_ptr, mem); 80 | inc_pop_ptr(); 81 | decr_count(); 82 | return mule; 83 | }; 84 | 85 | inline void try_push(bool pushed, T &push_val) { 86 | #pragma hls_unroll yes 87 | for (int i = 0; i < SIZE; ++i) { 88 | bool enable = ((push_ptr >> i) & 1) && pushed; // ToDo : for some reason catapult uses rshift mod/func instead of statically select the bit. 89 | if (enable) mem[i] = push_val; 90 | } 91 | if (pushed) inc_push_ptr(); 92 | }; 93 | 94 | inline void set_count(bool pushed, bool popped) { 95 | if ( pushed && !popped) item_count = (item_count << 1); 96 | else if (!pushed && popped) item_count = (item_count >> 1); 97 | } 98 | 99 | inline void inc_pop_ptr() { pop_ptr = (pop_ptr <<1) | ((pop_ptr >>(SIZE-1))&1);}; // maybe (pop_ptr<<1) | pop_ptr[SIZE]; would work equally, although not tested 100 | inline void inc_push_ptr() { push_ptr = (push_ptr<<1) | ((push_ptr>>(SIZE-1))&1);}; // maybe (push_ptr<<1) | push_ptr[SIZE]; would work equally, although not tested 101 | 102 | inline void incr_count() {item_count = (item_count << 1);}; 103 | inline void decr_count() {item_count = (item_count >> 1);}; 104 | 105 | }; 106 | 107 | #endif // #define __FIFO_QUEUE__ 108 | -------------------------------------------------------------------------------- /src/README.md: -------------------------------------------------------------------------------- 1 | ### Header files 2 | - `src/include/arbiters.h` HLS implementation of various arbitration schemes 3 | - `src/include/axi4_configs_extra.h` Expansion of Matclib's AXI configuration 4 | - `src/include/dnp20_axi.h` definitions of packetization structure 5 | - `src/include/duth_fun.h` helper low-level HLS functions commonly used 6 | - `src/include/flit_axi.h` Network flit class that transports AXI 7 | - `src/include/onehot.h` Onehot wrapped class to introduce onehot representation 8 | - `src/include/fifo_queue_oh.h` An onehot FIFO implementation 9 | 10 | ### Routers 11 | - `src/router_wh.h` Wormhole router implementation 12 | - `src/router_vc.h` Virtual Channel based router similar to combined allocation paradigm of [Microarchitecture of Network-on-Chip Routers](https://www.springer.com/gp/book/9781461443001) 13 | 14 | ### AMBA AXI4 Interfaces: 15 | - `src/axi_master_if.h` Master interface that connects the Master agent to the network, capable of multiple outstanding transactions under two schemes, towards the same transaction destination, and towards multiple detinations for transactions of different IDs 16 | - `src/axi_master_if_reord.h` Master interface that connects the Master agent to the network, with out-of-order outstanding requests and reordering capabilities to maintain AXI ordering 17 | - `src/axi_slave_if.h` Slave interface that connects the Slave agent to the network 18 | 19 | - `src/axi_master_if_vc.h` Master interface that connects the Master agent to the network, capable of multiple outstanding transactions under two schemes. Supports Virtual Channels. 20 | - `src/axi_master_if_vc_reord.h` Master interface that connects the Master agent to the network, with reordering capabilities and Virtual Channel based Network-on-Chip support. 21 | - `src/axi_slave_if_vc.h` Slave interface that connects the Slave agent to the network that supports Virtual Channel based Network-on-Chip 22 | 23 | ### AMBA ACE Interfaces: 24 | - `src/ace/ace_home.h` HOME node receives read and write coherent requests to be Serialized and impose a total ordering. When a request is received, it creates and sends the appropriate snoop requests to the necessary masters. Depending on the Snoop responses, either a reponse is sent to the initiator or data are requested from/to the main memory. 25 | - HOME node expects data in a single flit. Thus an entire cache line must fit in a flit. 26 | - Only a single coherent request is processed at any time. The next transaction starts after the ACK for the precious transaction is received. 27 | 28 | - `src/ace/ace_master_if.h` Master interface that connects a cached Master agent to the network. ACE master operates as a typical AXI interface and extends the requests with extra fields. Master interfaces routes any coherent transaction to the HOME node, to which also sends an ACK when a transaction has finished at its initiator. 29 | - The Snoop Data channel is sized to full cacheline. Thus only INCR bursts of length 0 are expected. 30 | - Barrier coherent requests are not implemented. 31 | 32 | Furthermore the ACE master interface implements the extra ACE channels which apply snoop requests to the Master cache (i.e. its cache controller) for data and privilege exchange, receive the appropriate response and optionally data and sends that snoop response to HOME for further handling. 33 | 34 | - `src/ace/acelite_master_if.h` Master interface that implements the ACE-Lite version of ACE, applicable to un-cached masters that need to access data within the shared region of the Full ACE Agents. 35 | 36 | - `src/ace/ace_slave_if.h` Slave interface is a typical AXI Slave interface with minimal changes to be able to handle ACE DNP flits. 37 | -------------------------------------------------------------------------------- /src/include/dnp_ace_v0.h: -------------------------------------------------------------------------------- 1 | #ifndef __DNP_ACE_DEF__ 2 | #define __DNP_ACE_DEF__ 3 | 4 | 5 | // Definition of Duth Network Protocol for ACE network. 6 | // Interconnect's internal packetization protocol 7 | namespace dnp { 8 | enum { 9 | // !!!! THIS MUST BE 24. 20 is temp for router synth!!! 10 | PHIT_W = 24, // Phit Width 11 | 12 | V_W = 2, // Virtual Channel 13 | S_W = 3, // Source 14 | D_W = 3, // Destination 15 | Q_W = 3, // QoS 16 | T_W = 3, // Type 17 | 18 | V_PTR = 0, 19 | S_PTR = (V_PTR + V_W), 20 | D_PTR = (S_PTR + S_W), 21 | Q_PTR = (D_PTR + D_W), 22 | T_PTR = (Q_PTR + Q_W), 23 | }; 24 | 25 | class ace { 26 | public: 27 | 28 | enum { 29 | // AXI RELATED WIDTHS 30 | ID_W = 4, // AXI Transaction ID 31 | BU_W = 2, // AXI Burst 32 | SZ_W = 3, // AXI Size 33 | LE_W = 8, // AXI Length 34 | AL_W = 16, // Address Low 35 | AH_W = 16, // Address High 36 | AP_W = 8, // Address part (for alignment) 37 | W_RE_W = 2, // AXI Write Response 38 | R_RE_W = 4, // ACE Read response 39 | 40 | B_W = 8, // Byte Width ... 41 | E_W = 1, // Enable width 42 | LA_W = 1, // AXI Last 43 | 44 | // ACE RELATED WIDTHS 45 | SNP_W = 4, 46 | DOM_W = 2, 47 | BAR_W = 2, 48 | UNQ_W = 1, 49 | 50 | C_PROT_W = 3, 51 | C_RESP_W = 5, 52 | C_HAS_DATA_W = 1, 53 | }; 54 | 55 | struct req { 56 | enum { 57 | // PHIT #0 58 | ID_PHIT = 0, 59 | DOM_PHIT = 0, 60 | SNP_PHIT = 0, 61 | 62 | ID_PTR = T_PTR+T_W, 63 | DOM_PTR = ID_PTR + ID_W, 64 | SNP_PTR = DOM_PTR + DOM_W, 65 | // PHIT #1 66 | AL_PHIT = 1, 67 | LE_PHIT = 1, 68 | 69 | AL_PTR = 0, 70 | LE_PTR = AL_PTR+AL_W, 71 | // PHIT #2 72 | AH_PHIT = 2, 73 | SZ_PHIT = 2, 74 | BU_PHIT = 2, 75 | BAR_PHIT = 2, 76 | UNQ_PHIT = 2, 77 | 78 | AH_PTR = 0, 79 | SZ_PTR = AH_PTR+AH_W, 80 | BU_PTR = SZ_PTR+SZ_W, 81 | BAR_PTR = BU_PTR+BU_W, 82 | UNQ_PTR = BAR_PTR+BAR_W, 83 | }; 84 | }; 85 | 86 | struct wresp { 87 | enum { 88 | // PHIT #0 89 | ID_PHIT = 0, 90 | RESP_PHIT = 0, 91 | 92 | ID_PTR = T_PTR+T_W, 93 | RESP_PTR = ID_PTR+ID_W, 94 | }; 95 | }; 96 | 97 | struct rresp { 98 | enum { 99 | // PHIT #0 100 | ID_PHIT = 0, 101 | BU_PHIT = 0, 102 | 103 | ID_PTR = T_PTR+T_W, 104 | BU_PTR = ID_PTR+ID_W, 105 | // PHIT #1 106 | SZ_PHIT = 1, 107 | LE_PHIT = 1, 108 | AP_PHIT = 1, 109 | 110 | SZ_PTR = 0, 111 | LE_PTR = SZ_PTR+SZ_W, 112 | AP_PTR = LE_PTR+LE_W, 113 | }; 114 | }; 115 | 116 | struct wdata { 117 | enum { 118 | B0_PTR = 0, 119 | B1_PTR = B0_PTR+B_W, 120 | LA_PTR = B1_PTR+B_W, 121 | E0_PTR = LA_PTR+LA_W, 122 | E1_PTR = E0_PTR+E_W, 123 | }; 124 | }; 125 | 126 | struct rdata { 127 | enum { 128 | B0_PTR = 0, 129 | B1_PTR = B0_PTR+B_W, 130 | LA_PTR = B1_PTR+B_W, 131 | RE_PTR = LA_PTR+LA_W, 132 | }; 133 | }; 134 | 135 | // ACE Extension 136 | struct creq { 137 | enum { 138 | // PHIT #1 139 | AL_PHIT = 1, 140 | SNP_PHIT = 1, 141 | 142 | AL_PTR = 0, 143 | SNP_PTR = AL_PTR+AL_W, 144 | // PHIT #2 145 | AH_PHIT = 2, 146 | C_PROT_PHIT = 2, 147 | 148 | AH_PTR = 0, 149 | C_PROT_PTR = AH_PTR+AH_W, 150 | }; 151 | }; 152 | 153 | struct cresp { 154 | enum { 155 | // PHIT #0 156 | C_RESP_PHIT = 0, 157 | C_HAS_DATA_PHIT = 0, 158 | 159 | C_RESP_PTR = T_PTR+T_W, 160 | C_HAS_DATA_PTR = C_RESP_PTR + C_RESP_W, 161 | }; 162 | }; 163 | }; // class ACE 164 | 165 | enum PACK_TYPE { 166 | PACK_TYPE__WR_REQ = 0, 167 | PACK_TYPE__WR_RESP = 1, 168 | PACK_TYPE__RD_REQ = 2, 169 | PACK_TYPE__RD_RESP = 3, 170 | PACK_TYPE__C_RD_REQ = 4, 171 | PACK_TYPE__C_RD_RESP = 5, 172 | PACK_TYPE__C_WR_REQ = 6, 173 | PACK_TYPE__C_WR_RESP = 7 174 | //PACK_TYPE__SNP_REQ = ? 175 | //PACK_TYPE__SNP_RESP = ? 176 | }; 177 | }; // namespace dnp 178 | 179 | #endif // __DNP_ACE_DEF__ 180 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NoCpad # 2 | 3 | ### AMBA AXI-4 Network on Chip designed for HLS ### 4 | 5 | NoCpad provides optimized HLS-ready SystemC models of all required Network-on-Chip components, such as network interfaces and routers (including virtual channels), in order to build a scalable AMBA-compliant SoC interconnect fabric. Quality of results in terms of networking performance as well as hardware PPA matches closely that of custom RTL. 6 | 7 | Network interfaces translate AMBA AXI-4 transactions to an internal versatible packetized protocol that is routed through a Network-on-Chip (NoC). Both *coherent* and *non-coherent* transactions are supported including AXI4, ACE network interfaces. Furthermore, ACE-Lite interfaces enable agents with no caches (such as DMA controllers or hardware accelerators) to access shareable data and participate in a mixed ACE and ACE-Lite interconnect. 8 | 9 | ![A network on chip connecting IP cores using network interfaces and routers](noc.png) 10 | 11 | Link-level communication between components is performed using Connection channels, included in Mentor's Catapult HLS [HLSLibs](https://github.com/hlslibs/matchlib_connections), and [MatchLib](https://github.com/NVlabs/matchlib) 12 | a SystemC/C++ library of commonly-used hardware functions and components. 13 | 14 | Why does it make sense to build a NoC using HLS? 15 | - NoC can change many times during design flow 16 | - Changes can be structural and/or architectural 17 | - Re-verification should be fast 18 | - SystemC/C++ models abstract enough to be highly configurable 19 | - Complex customizations can be easily architected 20 | - C++ simulation is faster 21 | - HLS constraints can produce the needed result 22 | - Or even lead to new unexplored alternatives 23 | - No need for re-verification 24 | 25 | NoCpad targets agile interconnect development. The designer of the network fabric can choose across non-coherent AXI-4 interfaces or coherent ACE interfaces to 26 | compose an efficent NoC. Data transfer is handled by NoC routers that support simple wormhole or virtual-channel flow control. In all cases, contention is resolved by arbiter modules chosen from a library of various arbiter architectures. 27 | 28 | AMBA-AXI4 interfaces : 29 | - AXI porotocol compatibility 30 | - All burst types 31 | - Multiple configurable transaction IDs 32 | - Arbitrary data lane widths, even under the same interconnect 33 | - Narrow and unaligned transactions 34 | - Internal packet based transport protocol 35 | - Arbitrary internal NoC widths 36 | - Matchlib AXI class definitions for easy interoperability 37 | 38 | AMBA-ACE, ACE-Lite interfaces : 39 | - ACE porotocol compatibility 40 | - Various cache line sizes 41 | - Interconnect's Data channels, are currenty sized depending the chosen cache line width 42 | - HOME-Node for transaction PoS (Point-of-Serialization) and protocol management 43 | - Multiple HOME nodes support for load balancing 44 | - ACE-Lite support for uncached agents 45 | - Support for the optional snoop data response 46 | - Mixed coherent and non-coherent traffic 47 | - Internal packet based transport protocol 48 | - Extends Matchlib definitions for ACE support, based on the AXI paradigm 49 | 50 | NoC Routers : 51 | - Configurable number of Input/Output ports 52 | - Various arbitration schemes 53 | - Able to form arbitrary network topologies 54 | - Two forms of link-level flow control 55 | * Wormhole routers with Ready-Valid flow controll using Connections 56 | * Virtual Channel based usin Connections and credit-based flow control 57 | 58 | Library of arbiter components: 59 | - Fixed Priority 60 | - Round Robin 61 | - Matrix arbiter 62 | - Weighted Round Robin 63 | - Deficit Round Robin 64 | - Merged arbiter multiplexers 65 | 66 | 67 | ## Getting Started ## 68 | 69 | ### Tool versions ### 70 | 71 | The codebase is based on Connections and MatchLib, and follows the similar tool/dependency versions: 72 | 73 | * `gcc` - 4.9.3 (with C++11) 74 | * `systemc` - 2.3.1 75 | * `boost` - 1.68.0 76 | * `catapult` - 10.5a 77 | * connections - included with catapult 78 | * `QuestaSim` - 2019.3_1 79 | 80 | ### Environment requirements 81 | 82 | Makefiles and synthesis scripts expect the following environment variables: 83 | (A sample bash script can be found in examples/setenv.sh) 84 | 85 | * `CATAPULT_HOME` 86 | * `SYSTEMC_HOME` 87 | * `BOOST_HOME` 88 | * `MATCHLIB_HOME` 89 | 90 | In addition, the boost and systemc library locations are expected to be in `LD_LIBRARY_PATH`. 91 | 92 | ### C++ compile and simulate 93 | cd examples/ 94 | make 95 | ./sim_sc 96 | 97 | ### Mentor Catapult synthesis 98 | cd examples/ 99 | catapult -file go_hls_ic.tcl 100 | 101 | ## Contributors 102 | Dimitris Konstantinou, Giorgos Dimitrakopoulos, Dionisis Filippas 103 | 104 | ## Pending additions 105 | - AMBA AHB5 network interfaces 106 | 107 | ## License 108 | NoCpad is licensed under the [MIT License](./LICENSE). 109 | 110 | -------------------------------------------------------------------------------- /src/include/onehot.h: -------------------------------------------------------------------------------- 1 | #ifndef __ONEHOT_CLASS__ 2 | #define __ONEHOT_CLASS__ 3 | 4 | #include 5 | #include "./duth_fun.h" 6 | 7 | //============================================================================// 8 | //============================== One-Hot Class ========================// 9 | //============================================================================// 10 | template 11 | class onehot { 12 | public: 13 | static const unsigned WIDTH = N; 14 | sc_uint val; 15 | 16 | onehot() {onehot(1);}; 17 | onehot(unsigned init_val) {val = init_val;}; 18 | 19 | // Only for SystemC 20 | inline friend void sc_trace(sc_trace_file* tf, const onehot& oh_val, const std::string& name) { 21 | sc_trace(tf, oh_val.val, name + ".val"); 22 | } 23 | 24 | template 25 | inline void set(T wb_val) { 26 | switch (wb_val) { 27 | case 0 : val = (1<<0); 28 | break; 29 | case 1 : val = (1<<1); 30 | break; 31 | case 2 : val = (1<<2); 32 | break; 33 | case 3 : val = (1<<3); 34 | break; 35 | case 4 : val = (1<<4); 36 | break; 37 | case 5 : val = (1<<5); 38 | break; 39 | case 6 : val = (1<<6); 40 | break; 41 | case 7 : val = (1<<7); 42 | break; 43 | default : val = (1<<0);; 44 | break; 45 | } 46 | }; //(1< 49 | inline void set(onehot oh_val) { val = oh_val.val;}; 50 | 51 | inline sc_uint get() {return val;}; 52 | 53 | inline bool is_ready() {return !val[0];}; 54 | inline bool or_reduce() {return val.or_reduce();}; 55 | 56 | inline onehot and_mask(bool bit) const { 57 | onehot mask(0); 58 | #pragma hls_unroll yes 59 | for(int i=0; i(val & mask.val); 62 | }; 63 | 64 | inline void increase() { val = (val << 1);}; 65 | inline void decrease() { val = (val >> 1);}; 66 | 67 | template 68 | T mux(const T data_i[N]); 69 | 70 | //inline bool operator[] (const unsigned pos) { 71 | // return ((val>>pos) & 1); 72 | //z}; 73 | 74 | sc_dt::sc_uint_bitref& operator [] ( unsigned pos) {return val[pos];}; 75 | const sc_dt::sc_uint_bitref_r& operator [] ( unsigned pos ) const {return val[pos];}; 76 | 77 | //template 78 | //bool operator== (const T &rhs) { 79 | // return (val==rhs); 80 | //}; 81 | 82 | template 83 | onehot& operator= (const T &rhs) { 84 | this->set(rhs); 85 | }; 86 | }; 87 | 88 | template<> 89 | template 90 | T onehot<2>::mux(const T data_i[2] ) { 91 | T selected; 92 | switch (val) { 93 | case 1 : selected = data_i[0]; 94 | break; 95 | case 2 : selected = data_i[1]; 96 | break; 97 | default : selected = data_i[0]; 98 | break; 99 | } 100 | return selected; 101 | }; 102 | 103 | template<> 104 | template 105 | T onehot<3>::mux(const T data_i[3] ) { 106 | T selected; 107 | switch (val) { 108 | case 1 : selected = data_i[0]; 109 | break; 110 | case 2 : selected = data_i[1]; 111 | break; 112 | case 4 : selected = data_i[2]; 113 | break; 114 | default : selected = data_i[0]; 115 | break; 116 | } 117 | return selected; 118 | }; 119 | 120 | template<> 121 | template 122 | T onehot<4>::mux(const T data_i[4] ) { 123 | T selected; 124 | switch (val) { 125 | case 1 : selected = data_i[0]; 126 | break; 127 | case 2 : selected = data_i[1]; 128 | break; 129 | case 4 : selected = data_i[2]; 130 | break; 131 | case 8 : selected = data_i[3]; 132 | break; 133 | default : selected = data_i[0]; 134 | break; 135 | } 136 | return selected; 137 | }; 138 | 139 | template<> 140 | template 141 | T onehot<5>::mux(const T data_i[5] ) { 142 | T selected; 143 | switch (val) { 144 | case 1 : selected = data_i[0]; 145 | break; 146 | case 2 : selected = data_i[1]; 147 | break; 148 | case 4 : selected = data_i[2]; 149 | break; 150 | case 8 : selected = data_i[3]; 151 | break; 152 | case 16 : selected = data_i[4]; 153 | break; 154 | default : selected = data_i[0]; 155 | break; 156 | } 157 | return selected; 158 | }; 159 | 160 | template<> 161 | template 162 | T onehot<6>::mux(const T data_i[6] ) { 163 | T selected; 164 | switch (val) { 165 | case 1 : selected = data_i[0]; 166 | break; 167 | case 2 : selected = data_i[1]; 168 | break; 169 | case 4 : selected = data_i[2]; 170 | break; 171 | case 8 : selected = data_i[3]; 172 | break; 173 | case 16 : selected = data_i[4]; 174 | break; 175 | case 32 : selected = data_i[5]; 176 | break; 177 | default : selected = data_i[0]; 178 | break; 179 | } 180 | return selected; 181 | }; 182 | 183 | #endif // __ONEHOT_CLASS__ 184 | -------------------------------------------------------------------------------- /examples/nocpad_ACE_4m-2s_1stage/go_hls_ic.tcl: -------------------------------------------------------------------------------- 1 | solution new -state initial 2 | solution options defaults 3 | flow package require /SCVerify 4 | solution options set /Output/PackageOutput false 5 | 6 | ## Use fsdb file for power flow - make sure your environment var $NOVAS_INST_DIR has been set before you launch Catapult. 7 | solution options set /Flows/LowPower/SWITCHING_ACTIVITY_TYPE fsdb 8 | ## SCVerify settings 9 | solution options set /Flows/SCVerify/USE_MSIM false 10 | solution options set /Flows/SCVerify/USE_OSCI false 11 | solution options set /Flows/SCVerify/USE_VCS true 12 | solution options set /Flows/VCS/VCS_HOME $env(VCS_HOME) 13 | if { [info exist env(VG_GNU_PACKAGE)] } { 14 | solution options set /Flows/VCS/VG_GNU_PACKAGE $env(VG_GNU_PACKAGE) 15 | } else { 16 | solution options set /Flows/VCS/VG_GNU_PACKAGE $env(VCS_HOME)/gnu/linux 17 | } 18 | solution options set /Flows/VCS/VG_ENV64_SCRIPT source_me.csh 19 | solution options set /Flows/VCS/SYSC_VERSION 2.3.1 20 | 21 | # Verilog/VHDL 22 | solution options set Output OutputVerilog true 23 | solution options set Output/OutputVHDL false 24 | # Reset FFs 25 | solution options set Architectural/DefaultResetClearsAllRegs yes 26 | 27 | # General constrains. Please refer to tool ref manual for detailed descriptions. 28 | directive set -DESIGN_GOAL area 29 | directive set -SPECULATE true 30 | directive set -MERGEABLE true 31 | directive set -REGISTER_THRESHOLD 256 32 | directive set -MEM_MAP_THRESHOLD 32 33 | directive set -FSM_ENCODING none 34 | directive set -REG_MAX_FANOUT 0 35 | directive set -NO_X_ASSIGNMENTS true 36 | directive set -SAFE_FSM false 37 | directive set -REGISTER_SHARING_LIMIT 0 38 | directive set -ASSIGN_OVERHEAD 0 39 | directive set -TIMING_CHECKS true 40 | directive set -MUXPATH true 41 | directive set -REALLOC true 42 | directive set -UNROLL no 43 | directive set -IO_MODE super 44 | directive set -REGISTER_IDLE_SIGNAL false 45 | directive set -IDLE_SIGNAL {} 46 | directive set -TRANSACTION_DONE_SIGNAL true 47 | directive set -DONE_FLAG {} 48 | directive set -START_FLAG {} 49 | directive set -BLOCK_SYNC none 50 | directive set -TRANSACTION_SYNC ready 51 | directive set -DATA_SYNC none 52 | directive set -RESET_CLEARS_ALL_REGS yes 53 | directive set -CLOCK_OVERHEAD 20.000000 54 | directive set -OPT_CONST_MULTS use_library 55 | directive set -CHARACTERIZE_ROM false 56 | directive set -PROTOTYPE_ROM true 57 | directive set -ROM_THRESHOLD 64 58 | directive set -CLUSTER_ADDTREE_IN_WIDTH_THRESHOLD 0 59 | directive set -CLUSTER_OPT_CONSTANT_INPUTS true 60 | directive set -CLUSTER_RTL_SYN false 61 | directive set -CLUSTER_FAST_MODE false 62 | directive set -CLUSTER_TYPE combinational 63 | directive set -COMPGRADE fast 64 | directive set -PIPELINE_RAMP_UP true 65 | 66 | 67 | solution options set /Flows/SCVerify/USE_VCS false 68 | solution options set /Flows/SCVerify/USE_MSIM true 69 | 70 | options set Input/SearchPath ". $env(MATCHLIB_HOME)/cmod $env(MATCHLIB_HOME)/cmod/include $env(BOOST_HOME)/include" 71 | options set Input/CppStandard c++11 72 | options set Architectural/DesignGoal latency 73 | 74 | #global variables across all steps 75 | set TOP_NAME "ic_top" 76 | set CLK_NAME clk 77 | set CLK_PERIOD 10 78 | set SRC_DIR "../../" 79 | 80 | set DESIGN_FILES [list ./ic_top.h] 81 | set TB_FILES [list ./ace_main.cpp] 82 | 83 | # Choose router 84 | set ROUTER_SELECT_FLAG "-DUSE_ROUTER_ST_BUF" 85 | 86 | if { [info exists env(HLS_CATAPULT)] && ($env(HLS_CATAPULT) eq "1") } { 87 | set HLS_CATAPULT_FLAG "-DHLS_CATAPULT" 88 | } else { 89 | set HLS_CATAPULT_FLAG "" 90 | } 91 | 92 | solution options set Input/TargetPlatform x86_64 93 | 94 | # Add your design here 95 | foreach design_file $DESIGN_FILES { 96 | solution file add $design_file -type SYSTEMC 97 | } 98 | foreach tb_file $TB_FILES { 99 | solution file add $tb_file -type SYSTEMC -exclude true 100 | } 101 | options set Input/CompilerFlags "-DHLS_CATAPULT -DSC_INCLUDE_DYNAMIC_PROCESSES -DCONNECTIONS_ACCURATE_SIM $HLS_CATAPULT_FLAG $ROUTER_SELECT_FLAG" 102 | go analyze 103 | solution library add nangate-45nm_beh -- -rtlsyntool OasysRTL -vendor Nangate -technology 045nm 104 | #solution library add mgc_sample-065nm-dw_beh_dc -- -rtlsyntool DesignCompiler -vendor Sample -technology 065nm -Designware Yes 105 | #solution library add ram_sample-065nm-singleport_beh_dc 106 | 107 | # Clock, interface constrain 108 | set CLK_PERIODby2 [expr $CLK_PERIOD/2] 109 | directive set -CLOCKS "$CLK_NAME \"-CLOCK_PERIOD $CLK_PERIOD -CLOCK_EDGE rising -CLOCK_UNCERTAINTY 0.0 -CLOCK_HIGH_TIME $CLK_PERIODby2 -RESET_SYNC_NAME rst -RESET_ASYNC_NAME arst_n -RESET_KIND sync -RESET_SYNC_ACTIVE high -RESET_ASYNC_ACTIVE low -ENABLE_NAME {} -ENABLE_ACTIVE high\" " 110 | directive set -CLOCK_NAME $CLK_NAME 111 | directive set GATE_REGISTERS false 112 | 113 | directive set -DESIGN_HIERARCHY "$TOP_NAME" 114 | 115 | go compile 116 | go libraries 117 | go assembly 118 | 119 | go architect 120 | go allocate 121 | go schedule 122 | go dpfsm 123 | go extract 124 | #flow run /OasysRTL/launch_tool ./concat_rtl.v.or v 125 | # go switching 126 | project save 127 | 128 | # exit 129 | -------------------------------------------------------------------------------- /examples/nocpad_2m-2s_2d-mesh_basic-order/go_hls_ic.tcl: -------------------------------------------------------------------------------- 1 | solution new -state initial 2 | solution options defaults 3 | flow package require /SCVerify 4 | solution options set /Output/PackageOutput false 5 | 6 | ## Use fsdb file for power flow - make sure your environment var $NOVAS_INST_DIR has been set before you launch Catapult. 7 | solution options set /Flows/LowPower/SWITCHING_ACTIVITY_TYPE fsdb 8 | ## SCVerify settings 9 | solution options set /Flows/SCVerify/USE_MSIM false 10 | solution options set /Flows/SCVerify/USE_OSCI false 11 | solution options set /Flows/SCVerify/USE_VCS true 12 | solution options set /Flows/VCS/VCS_HOME $env(VCS_HOME) 13 | if { [info exist env(VG_GNU_PACKAGE)] } { 14 | solution options set /Flows/VCS/VG_GNU_PACKAGE $env(VG_GNU_PACKAGE) 15 | } else { 16 | solution options set /Flows/VCS/VG_GNU_PACKAGE $env(VCS_HOME)/gnu/linux 17 | } 18 | solution options set /Flows/VCS/VG_ENV64_SCRIPT source_me.csh 19 | solution options set /Flows/VCS/SYSC_VERSION 2.3.1 20 | 21 | # Verilog/VHDL 22 | solution options set Output OutputVerilog true 23 | solution options set Output/OutputVHDL false 24 | # Reset FFs 25 | solution options set Architectural/DefaultResetClearsAllRegs yes 26 | 27 | # General constrains. Please refer to tool ref manual for detailed descriptions. 28 | directive set -DESIGN_GOAL area 29 | directive set -SPECULATE true 30 | directive set -MERGEABLE true 31 | directive set -REGISTER_THRESHOLD 256 32 | directive set -MEM_MAP_THRESHOLD 32 33 | directive set -FSM_ENCODING none 34 | directive set -REG_MAX_FANOUT 0 35 | directive set -NO_X_ASSIGNMENTS true 36 | directive set -SAFE_FSM false 37 | directive set -REGISTER_SHARING_LIMIT 0 38 | directive set -ASSIGN_OVERHEAD 0 39 | directive set -TIMING_CHECKS true 40 | directive set -MUXPATH true 41 | directive set -REALLOC true 42 | directive set -UNROLL no 43 | directive set -IO_MODE super 44 | directive set -REGISTER_IDLE_SIGNAL false 45 | directive set -IDLE_SIGNAL {} 46 | directive set -TRANSACTION_DONE_SIGNAL true 47 | directive set -DONE_FLAG {} 48 | directive set -START_FLAG {} 49 | directive set -BLOCK_SYNC none 50 | directive set -TRANSACTION_SYNC ready 51 | directive set -DATA_SYNC none 52 | directive set -RESET_CLEARS_ALL_REGS yes 53 | directive set -CLOCK_OVERHEAD 20.000000 54 | directive set -OPT_CONST_MULTS use_library 55 | directive set -CHARACTERIZE_ROM false 56 | directive set -PROTOTYPE_ROM true 57 | directive set -ROM_THRESHOLD 64 58 | directive set -CLUSTER_ADDTREE_IN_WIDTH_THRESHOLD 0 59 | directive set -CLUSTER_OPT_CONSTANT_INPUTS true 60 | directive set -CLUSTER_RTL_SYN false 61 | directive set -CLUSTER_FAST_MODE false 62 | directive set -CLUSTER_TYPE combinational 63 | directive set -COMPGRADE fast 64 | directive set -PIPELINE_RAMP_UP true 65 | 66 | 67 | solution options set /Flows/SCVerify/USE_VCS false 68 | solution options set /Flows/SCVerify/USE_MSIM true 69 | 70 | options set Input/SearchPath ". $env(MATCHLIB_HOME)/cmod $env(MATCHLIB_HOME)/cmod/include $env(BOOST_HOME)/include" 71 | options set Input/CppStandard c++11 72 | options set Architectural/DesignGoal latency 73 | 74 | #global variables across all steps 75 | set TOP_NAME "ic_top" 76 | set CLK_NAME clk 77 | set CLK_PERIOD 10 78 | set SRC_DIR "../../" 79 | 80 | set DESIGN_FILES [list ./ic_top_2d.h] 81 | set TB_FILES [list ./axi_main.cpp] 82 | 83 | # Choose router 84 | set ROUTER_SELECT_FLAG "-DUSE_ROUTER_ST_BUF" 85 | 86 | if { [info exists env(HLS_CATAPULT)] && ($env(HLS_CATAPULT) eq "1") } { 87 | set HLS_CATAPULT_FLAG "-DHLS_CATAPULT" 88 | } else { 89 | set HLS_CATAPULT_FLAG "" 90 | } 91 | 92 | solution options set Input/TargetPlatform x86_64 93 | 94 | # Add your design here 95 | foreach design_file $DESIGN_FILES { 96 | solution file add $design_file -type SYSTEMC 97 | } 98 | foreach tb_file $TB_FILES { 99 | solution file add $tb_file -type SYSTEMC -exclude true 100 | } 101 | options set Input/CompilerFlags "-DHLS_CATAPULT -DSC_INCLUDE_DYNAMIC_PROCESSES -DCONNECTIONS_ACCURATE_SIM $HLS_CATAPULT_FLAG $ROUTER_SELECT_FLAG" 102 | go analyze 103 | solution library add nangate-45nm_beh -- -rtlsyntool OasysRTL -vendor Nangate -technology 045nm 104 | #solution library add mgc_sample-065nm-dw_beh_dc -- -rtlsyntool DesignCompiler -vendor Sample -technology 065nm -Designware Yes 105 | #solution library add ram_sample-065nm-singleport_beh_dc 106 | 107 | # Clock, interface constrain 108 | set CLK_PERIODby2 [expr $CLK_PERIOD/2] 109 | directive set -CLOCKS "$CLK_NAME \"-CLOCK_PERIOD $CLK_PERIOD -CLOCK_EDGE rising -CLOCK_UNCERTAINTY 0.0 -CLOCK_HIGH_TIME $CLK_PERIODby2 -RESET_SYNC_NAME rst -RESET_ASYNC_NAME arst_n -RESET_KIND sync -RESET_SYNC_ACTIVE high -RESET_ASYNC_ACTIVE low -ENABLE_NAME {} -ENABLE_ACTIVE high\" " 110 | directive set -CLOCK_NAME $CLK_NAME 111 | directive set GATE_REGISTERS false 112 | 113 | directive set -DESIGN_HIERARCHY "$TOP_NAME" 114 | 115 | go compile 116 | go libraries 117 | go assembly 118 | 119 | go architect 120 | go allocate 121 | go schedule 122 | go dpfsm 123 | go extract 124 | #flow run /OasysRTL/launch_tool ./concat_rtl.v.or v 125 | # go switching 126 | project save 127 | 128 | # exit 129 | -------------------------------------------------------------------------------- /examples/nocpad_2m-2s_2d-mesh_id-order/go_hls_ic.tcl: -------------------------------------------------------------------------------- 1 | solution new -state initial 2 | solution options defaults 3 | flow package require /SCVerify 4 | solution options set /Output/PackageOutput false 5 | 6 | ## Use fsdb file for power flow - make sure your environment var $NOVAS_INST_DIR has been set before you launch Catapult. 7 | solution options set /Flows/LowPower/SWITCHING_ACTIVITY_TYPE fsdb 8 | ## SCVerify settings 9 | solution options set /Flows/SCVerify/USE_MSIM false 10 | solution options set /Flows/SCVerify/USE_OSCI false 11 | solution options set /Flows/SCVerify/USE_VCS true 12 | solution options set /Flows/VCS/VCS_HOME $env(VCS_HOME) 13 | if { [info exist env(VG_GNU_PACKAGE)] } { 14 | solution options set /Flows/VCS/VG_GNU_PACKAGE $env(VG_GNU_PACKAGE) 15 | } else { 16 | solution options set /Flows/VCS/VG_GNU_PACKAGE $env(VCS_HOME)/gnu/linux 17 | } 18 | solution options set /Flows/VCS/VG_ENV64_SCRIPT source_me.csh 19 | solution options set /Flows/VCS/SYSC_VERSION 2.3.1 20 | 21 | # Verilog/VHDL 22 | solution options set Output OutputVerilog true 23 | solution options set Output/OutputVHDL false 24 | # Reset FFs 25 | solution options set Architectural/DefaultResetClearsAllRegs yes 26 | 27 | # General constrains. Please refer to tool ref manual for detailed descriptions. 28 | directive set -DESIGN_GOAL area 29 | directive set -SPECULATE true 30 | directive set -MERGEABLE true 31 | directive set -REGISTER_THRESHOLD 256 32 | directive set -MEM_MAP_THRESHOLD 32 33 | directive set -FSM_ENCODING none 34 | directive set -REG_MAX_FANOUT 0 35 | directive set -NO_X_ASSIGNMENTS true 36 | directive set -SAFE_FSM false 37 | directive set -REGISTER_SHARING_LIMIT 0 38 | directive set -ASSIGN_OVERHEAD 0 39 | directive set -TIMING_CHECKS true 40 | directive set -MUXPATH true 41 | directive set -REALLOC true 42 | directive set -UNROLL no 43 | directive set -IO_MODE super 44 | directive set -REGISTER_IDLE_SIGNAL false 45 | directive set -IDLE_SIGNAL {} 46 | directive set -TRANSACTION_DONE_SIGNAL true 47 | directive set -DONE_FLAG {} 48 | directive set -START_FLAG {} 49 | directive set -BLOCK_SYNC none 50 | directive set -TRANSACTION_SYNC ready 51 | directive set -DATA_SYNC none 52 | directive set -RESET_CLEARS_ALL_REGS yes 53 | directive set -CLOCK_OVERHEAD 20.000000 54 | directive set -OPT_CONST_MULTS use_library 55 | directive set -CHARACTERIZE_ROM false 56 | directive set -PROTOTYPE_ROM true 57 | directive set -ROM_THRESHOLD 64 58 | directive set -CLUSTER_ADDTREE_IN_WIDTH_THRESHOLD 0 59 | directive set -CLUSTER_OPT_CONSTANT_INPUTS true 60 | directive set -CLUSTER_RTL_SYN false 61 | directive set -CLUSTER_FAST_MODE false 62 | directive set -CLUSTER_TYPE combinational 63 | directive set -COMPGRADE fast 64 | directive set -PIPELINE_RAMP_UP true 65 | 66 | 67 | solution options set /Flows/SCVerify/USE_VCS false 68 | solution options set /Flows/SCVerify/USE_MSIM true 69 | 70 | options set Input/SearchPath ". $env(MATCHLIB_HOME)/cmod $env(MATCHLIB_HOME)/cmod/include $env(BOOST_HOME)/include" 71 | options set Input/CppStandard c++11 72 | options set Architectural/DesignGoal latency 73 | 74 | #global variables across all steps 75 | set TOP_NAME "ic_top" 76 | set CLK_NAME clk 77 | set CLK_PERIOD 10 78 | set SRC_DIR "../../" 79 | 80 | set DESIGN_FILES [list ./ic_top_2d.h] 81 | set TB_FILES [list ./axi_main.cpp] 82 | 83 | # Choose router 84 | set ROUTER_SELECT_FLAG "-DUSE_ROUTER_ST_BUF" 85 | 86 | if { [info exists env(HLS_CATAPULT)] && ($env(HLS_CATAPULT) eq "1") } { 87 | set HLS_CATAPULT_FLAG "-DHLS_CATAPULT" 88 | } else { 89 | set HLS_CATAPULT_FLAG "" 90 | } 91 | 92 | solution options set Input/TargetPlatform x86_64 93 | 94 | # Add your design here 95 | foreach design_file $DESIGN_FILES { 96 | solution file add $design_file -type SYSTEMC 97 | } 98 | foreach tb_file $TB_FILES { 99 | solution file add $tb_file -type SYSTEMC -exclude true 100 | } 101 | options set Input/CompilerFlags "-DHLS_CATAPULT -DSC_INCLUDE_DYNAMIC_PROCESSES -DCONNECTIONS_ACCURATE_SIM $HLS_CATAPULT_FLAG $ROUTER_SELECT_FLAG" 102 | go analyze 103 | solution library add nangate-45nm_beh -- -rtlsyntool OasysRTL -vendor Nangate -technology 045nm 104 | #solution library add mgc_sample-065nm-dw_beh_dc -- -rtlsyntool DesignCompiler -vendor Sample -technology 065nm -Designware Yes 105 | #solution library add ram_sample-065nm-singleport_beh_dc 106 | 107 | # Clock, interface constrain 108 | set CLK_PERIODby2 [expr $CLK_PERIOD/2] 109 | directive set -CLOCKS "$CLK_NAME \"-CLOCK_PERIOD $CLK_PERIOD -CLOCK_EDGE rising -CLOCK_UNCERTAINTY 0.0 -CLOCK_HIGH_TIME $CLK_PERIODby2 -RESET_SYNC_NAME rst -RESET_ASYNC_NAME arst_n -RESET_KIND sync -RESET_SYNC_ACTIVE high -RESET_ASYNC_ACTIVE low -ENABLE_NAME {} -ENABLE_ACTIVE high\" " 110 | directive set -CLOCK_NAME $CLK_NAME 111 | directive set GATE_REGISTERS false 112 | 113 | directive set -DESIGN_HIERARCHY "$TOP_NAME" 114 | 115 | go compile 116 | go libraries 117 | go assembly 118 | 119 | go architect 120 | go allocate 121 | go schedule 122 | go dpfsm 123 | go extract 124 | #flow run /OasysRTL/launch_tool ./concat_rtl.v.or v 125 | # go switching 126 | project save 127 | 128 | # exit 129 | -------------------------------------------------------------------------------- /examples/nocpad_2m-2s_2d-mesh_reorder/go_hls_ic.tcl: -------------------------------------------------------------------------------- 1 | solution new -state initial 2 | solution options defaults 3 | flow package require /SCVerify 4 | solution options set /Output/PackageOutput false 5 | 6 | ## Use fsdb file for power flow - make sure your environment var $NOVAS_INST_DIR has been set before you launch Catapult. 7 | solution options set /Flows/LowPower/SWITCHING_ACTIVITY_TYPE fsdb 8 | ## SCVerify settings 9 | solution options set /Flows/SCVerify/USE_MSIM false 10 | solution options set /Flows/SCVerify/USE_OSCI false 11 | solution options set /Flows/SCVerify/USE_VCS true 12 | solution options set /Flows/VCS/VCS_HOME $env(VCS_HOME) 13 | if { [info exist env(VG_GNU_PACKAGE)] } { 14 | solution options set /Flows/VCS/VG_GNU_PACKAGE $env(VG_GNU_PACKAGE) 15 | } else { 16 | solution options set /Flows/VCS/VG_GNU_PACKAGE $env(VCS_HOME)/gnu/linux 17 | } 18 | solution options set /Flows/VCS/VG_ENV64_SCRIPT source_me.csh 19 | solution options set /Flows/VCS/SYSC_VERSION 2.3.1 20 | 21 | # Verilog/VHDL 22 | solution options set Output OutputVerilog true 23 | solution options set Output/OutputVHDL false 24 | # Reset FFs 25 | solution options set Architectural/DefaultResetClearsAllRegs yes 26 | 27 | # General constrains. Please refer to tool ref manual for detailed descriptions. 28 | directive set -DESIGN_GOAL area 29 | directive set -SPECULATE true 30 | directive set -MERGEABLE true 31 | directive set -REGISTER_THRESHOLD 256 32 | directive set -MEM_MAP_THRESHOLD 32 33 | directive set -FSM_ENCODING none 34 | directive set -REG_MAX_FANOUT 0 35 | directive set -NO_X_ASSIGNMENTS true 36 | directive set -SAFE_FSM false 37 | directive set -REGISTER_SHARING_LIMIT 0 38 | directive set -ASSIGN_OVERHEAD 0 39 | directive set -TIMING_CHECKS true 40 | directive set -MUXPATH true 41 | directive set -REALLOC true 42 | directive set -UNROLL no 43 | directive set -IO_MODE super 44 | directive set -REGISTER_IDLE_SIGNAL false 45 | directive set -IDLE_SIGNAL {} 46 | directive set -TRANSACTION_DONE_SIGNAL true 47 | directive set -DONE_FLAG {} 48 | directive set -START_FLAG {} 49 | directive set -BLOCK_SYNC none 50 | directive set -TRANSACTION_SYNC ready 51 | directive set -DATA_SYNC none 52 | directive set -RESET_CLEARS_ALL_REGS yes 53 | directive set -CLOCK_OVERHEAD 20.000000 54 | directive set -OPT_CONST_MULTS use_library 55 | directive set -CHARACTERIZE_ROM false 56 | directive set -PROTOTYPE_ROM true 57 | directive set -ROM_THRESHOLD 64 58 | directive set -CLUSTER_ADDTREE_IN_WIDTH_THRESHOLD 0 59 | directive set -CLUSTER_OPT_CONSTANT_INPUTS true 60 | directive set -CLUSTER_RTL_SYN false 61 | directive set -CLUSTER_FAST_MODE false 62 | directive set -CLUSTER_TYPE combinational 63 | directive set -COMPGRADE fast 64 | directive set -PIPELINE_RAMP_UP true 65 | 66 | 67 | solution options set /Flows/SCVerify/USE_VCS false 68 | solution options set /Flows/SCVerify/USE_MSIM true 69 | 70 | options set Input/SearchPath ". $env(MATCHLIB_HOME)/cmod $env(MATCHLIB_HOME)/cmod/include $env(BOOST_HOME)/include" 71 | options set Input/CppStandard c++11 72 | options set Architectural/DesignGoal latency 73 | 74 | #global variables across all steps 75 | set TOP_NAME "ic_top" 76 | set CLK_NAME clk 77 | set CLK_PERIOD 10 78 | set SRC_DIR "../../" 79 | 80 | set DESIGN_FILES [list ./ic_top_2d.h] 81 | set TB_FILES [list ./axi_main.cpp] 82 | 83 | # Choose router 84 | set ROUTER_SELECT_FLAG "-DUSE_ROUTER_ST_BUF" 85 | 86 | if { [info exists env(HLS_CATAPULT)] && ($env(HLS_CATAPULT) eq "1") } { 87 | set HLS_CATAPULT_FLAG "-DHLS_CATAPULT" 88 | } else { 89 | set HLS_CATAPULT_FLAG "" 90 | } 91 | 92 | solution options set Input/TargetPlatform x86_64 93 | 94 | # Add your design here 95 | foreach design_file $DESIGN_FILES { 96 | solution file add $design_file -type SYSTEMC 97 | } 98 | foreach tb_file $TB_FILES { 99 | solution file add $tb_file -type SYSTEMC -exclude true 100 | } 101 | options set Input/CompilerFlags "-DHLS_CATAPULT -DSC_INCLUDE_DYNAMIC_PROCESSES -DCONNECTIONS_ACCURATE_SIM $HLS_CATAPULT_FLAG $ROUTER_SELECT_FLAG" 102 | go analyze 103 | solution library add nangate-45nm_beh -- -rtlsyntool OasysRTL -vendor Nangate -technology 045nm 104 | #solution library add mgc_sample-065nm-dw_beh_dc -- -rtlsyntool DesignCompiler -vendor Sample -technology 065nm -Designware Yes 105 | #solution library add ram_sample-065nm-singleport_beh_dc 106 | 107 | # Clock, interface constrain 108 | set CLK_PERIODby2 [expr $CLK_PERIOD/2] 109 | directive set -CLOCKS "$CLK_NAME \"-CLOCK_PERIOD $CLK_PERIOD -CLOCK_EDGE rising -CLOCK_UNCERTAINTY 0.0 -CLOCK_HIGH_TIME $CLK_PERIODby2 -RESET_SYNC_NAME rst -RESET_ASYNC_NAME arst_n -RESET_KIND sync -RESET_SYNC_ACTIVE high -RESET_ASYNC_ACTIVE low -ENABLE_NAME {} -ENABLE_ACTIVE high\" " 110 | directive set -CLOCK_NAME $CLK_NAME 111 | directive set GATE_REGISTERS false 112 | 113 | directive set -DESIGN_HIERARCHY "$TOP_NAME" 114 | 115 | go compile 116 | go libraries 117 | go assembly 118 | 119 | go architect 120 | go allocate 121 | go schedule 122 | go dpfsm 123 | go extract 124 | #flow run /OasysRTL/launch_tool ./concat_rtl.v.or v 125 | # go switching 126 | project save 127 | 128 | # exit 129 | -------------------------------------------------------------------------------- /examples/nocpad_ACE-lite_2m-2mlite-2s_1stage/go_hls_ic.tcl: -------------------------------------------------------------------------------- 1 | solution new -state initial 2 | solution options defaults 3 | flow package require /SCVerify 4 | solution options set /Output/PackageOutput false 5 | 6 | ## Use fsdb file for power flow - make sure your environment var $NOVAS_INST_DIR has been set before you launch Catapult. 7 | solution options set /Flows/LowPower/SWITCHING_ACTIVITY_TYPE fsdb 8 | ## SCVerify settings 9 | solution options set /Flows/SCVerify/USE_MSIM false 10 | solution options set /Flows/SCVerify/USE_OSCI false 11 | solution options set /Flows/SCVerify/USE_VCS true 12 | solution options set /Flows/VCS/VCS_HOME $env(VCS_HOME) 13 | if { [info exist env(VG_GNU_PACKAGE)] } { 14 | solution options set /Flows/VCS/VG_GNU_PACKAGE $env(VG_GNU_PACKAGE) 15 | } else { 16 | solution options set /Flows/VCS/VG_GNU_PACKAGE $env(VCS_HOME)/gnu/linux 17 | } 18 | solution options set /Flows/VCS/VG_ENV64_SCRIPT source_me.csh 19 | solution options set /Flows/VCS/SYSC_VERSION 2.3.1 20 | 21 | # Verilog/VHDL 22 | solution options set Output OutputVerilog true 23 | solution options set Output/OutputVHDL false 24 | # Reset FFs 25 | solution options set Architectural/DefaultResetClearsAllRegs yes 26 | 27 | # General constrains. Please refer to tool ref manual for detailed descriptions. 28 | directive set -DESIGN_GOAL area 29 | directive set -SPECULATE true 30 | directive set -MERGEABLE true 31 | directive set -REGISTER_THRESHOLD 256 32 | directive set -MEM_MAP_THRESHOLD 32 33 | directive set -FSM_ENCODING none 34 | directive set -REG_MAX_FANOUT 0 35 | directive set -NO_X_ASSIGNMENTS true 36 | directive set -SAFE_FSM false 37 | directive set -REGISTER_SHARING_LIMIT 0 38 | directive set -ASSIGN_OVERHEAD 0 39 | directive set -TIMING_CHECKS true 40 | directive set -MUXPATH true 41 | directive set -REALLOC true 42 | directive set -UNROLL no 43 | directive set -IO_MODE super 44 | directive set -REGISTER_IDLE_SIGNAL false 45 | directive set -IDLE_SIGNAL {} 46 | directive set -TRANSACTION_DONE_SIGNAL true 47 | directive set -DONE_FLAG {} 48 | directive set -START_FLAG {} 49 | directive set -BLOCK_SYNC none 50 | directive set -TRANSACTION_SYNC ready 51 | directive set -DATA_SYNC none 52 | directive set -RESET_CLEARS_ALL_REGS yes 53 | directive set -CLOCK_OVERHEAD 20.000000 54 | directive set -OPT_CONST_MULTS use_library 55 | directive set -CHARACTERIZE_ROM false 56 | directive set -PROTOTYPE_ROM true 57 | directive set -ROM_THRESHOLD 64 58 | directive set -CLUSTER_ADDTREE_IN_WIDTH_THRESHOLD 0 59 | directive set -CLUSTER_OPT_CONSTANT_INPUTS true 60 | directive set -CLUSTER_RTL_SYN false 61 | directive set -CLUSTER_FAST_MODE false 62 | directive set -CLUSTER_TYPE combinational 63 | directive set -COMPGRADE fast 64 | directive set -PIPELINE_RAMP_UP true 65 | 66 | 67 | solution options set /Flows/SCVerify/USE_VCS false 68 | solution options set /Flows/SCVerify/USE_MSIM true 69 | 70 | options set Input/SearchPath ". $env(MATCHLIB_HOME)/cmod $env(MATCHLIB_HOME)/cmod/include $env(BOOST_HOME)/include" 71 | options set Input/CppStandard c++11 72 | options set Architectural/DesignGoal latency 73 | 74 | #global variables across all steps 75 | set TOP_NAME "ic_top" 76 | set CLK_NAME clk 77 | set CLK_PERIOD 10 78 | set SRC_DIR "../../" 79 | 80 | set DESIGN_FILES [list ./ic_top.h] 81 | set TB_FILES [list ./ace_main.cpp] 82 | 83 | # Choose router 84 | set ROUTER_SELECT_FLAG "-DUSE_ROUTER_ST_BUF" 85 | 86 | if { [info exists env(HLS_CATAPULT)] && ($env(HLS_CATAPULT) eq "1") } { 87 | set HLS_CATAPULT_FLAG "-DHLS_CATAPULT" 88 | } else { 89 | set HLS_CATAPULT_FLAG "" 90 | } 91 | 92 | solution options set Input/TargetPlatform x86_64 93 | 94 | # Add your design here 95 | foreach design_file $DESIGN_FILES { 96 | solution file add $design_file -type SYSTEMC 97 | } 98 | foreach tb_file $TB_FILES { 99 | solution file add $tb_file -type SYSTEMC -exclude true 100 | } 101 | options set Input/CompilerFlags "-DHLS_CATAPULT -DSC_INCLUDE_DYNAMIC_PROCESSES -DCONNECTIONS_ACCURATE_SIM $HLS_CATAPULT_FLAG $ROUTER_SELECT_FLAG" 102 | go analyze 103 | solution library add nangate-45nm_beh -- -rtlsyntool OasysRTL -vendor Nangate -technology 045nm 104 | #solution library add mgc_sample-065nm-dw_beh_dc -- -rtlsyntool DesignCompiler -vendor Sample -technology 065nm -Designware Yes 105 | #solution library add ram_sample-065nm-singleport_beh_dc 106 | 107 | # Clock, interface constrain 108 | set CLK_PERIODby2 [expr $CLK_PERIOD/2] 109 | directive set -CLOCKS "$CLK_NAME \"-CLOCK_PERIOD $CLK_PERIOD -CLOCK_EDGE rising -CLOCK_UNCERTAINTY 0.0 -CLOCK_HIGH_TIME $CLK_PERIODby2 -RESET_SYNC_NAME rst -RESET_ASYNC_NAME arst_n -RESET_KIND sync -RESET_SYNC_ACTIVE high -RESET_ASYNC_ACTIVE low -ENABLE_NAME {} -ENABLE_ACTIVE high\" " 110 | directive set -CLOCK_NAME $CLK_NAME 111 | directive set GATE_REGISTERS false 112 | 113 | directive set -DESIGN_HIERARCHY "$TOP_NAME" 114 | 115 | go compile 116 | go libraries 117 | go assembly 118 | 119 | go architect 120 | go allocate 121 | go schedule 122 | go dpfsm 123 | go extract 124 | #flow run /OasysRTL/launch_tool ./concat_rtl.v.or v 125 | # go switching 126 | project save 127 | 128 | # exit 129 | -------------------------------------------------------------------------------- /examples/nocpad_2m-2s_2d-mesh_vc-req-resp_id-order/go_hls_ic.tcl: -------------------------------------------------------------------------------- 1 | solution new -state initial 2 | solution options defaults 3 | flow package require /SCVerify 4 | solution options set /Output/PackageOutput false 5 | 6 | ## Use fsdb file for power flow - make sure your environment var $NOVAS_INST_DIR has been set before you launch Catapult. 7 | solution options set /Flows/LowPower/SWITCHING_ACTIVITY_TYPE fsdb 8 | ## SCVerify settings 9 | solution options set /Flows/SCVerify/USE_MSIM false 10 | solution options set /Flows/SCVerify/USE_OSCI false 11 | solution options set /Flows/SCVerify/USE_VCS true 12 | solution options set /Flows/VCS/VCS_HOME $env(VCS_HOME) 13 | if { [info exist env(VG_GNU_PACKAGE)] } { 14 | solution options set /Flows/VCS/VG_GNU_PACKAGE $env(VG_GNU_PACKAGE) 15 | } else { 16 | solution options set /Flows/VCS/VG_GNU_PACKAGE $env(VCS_HOME)/gnu/linux 17 | } 18 | solution options set /Flows/VCS/VG_ENV64_SCRIPT source_me.csh 19 | solution options set /Flows/VCS/SYSC_VERSION 2.3.1 20 | 21 | # Verilog/VHDL 22 | solution options set Output OutputVerilog true 23 | solution options set Output/OutputVHDL false 24 | # Reset FFs 25 | solution options set Architectural/DefaultResetClearsAllRegs yes 26 | 27 | # General constrains. Please refer to tool ref manual for detailed descriptions. 28 | directive set -DESIGN_GOAL area 29 | directive set -SPECULATE true 30 | directive set -MERGEABLE true 31 | directive set -REGISTER_THRESHOLD 256 32 | directive set -MEM_MAP_THRESHOLD 32 33 | directive set -FSM_ENCODING none 34 | directive set -REG_MAX_FANOUT 0 35 | directive set -NO_X_ASSIGNMENTS true 36 | directive set -SAFE_FSM false 37 | directive set -REGISTER_SHARING_LIMIT 0 38 | directive set -ASSIGN_OVERHEAD 0 39 | directive set -TIMING_CHECKS true 40 | directive set -MUXPATH true 41 | directive set -REALLOC true 42 | directive set -UNROLL no 43 | directive set -IO_MODE super 44 | directive set -REGISTER_IDLE_SIGNAL false 45 | directive set -IDLE_SIGNAL {} 46 | directive set -TRANSACTION_DONE_SIGNAL true 47 | directive set -DONE_FLAG {} 48 | directive set -START_FLAG {} 49 | directive set -BLOCK_SYNC none 50 | directive set -TRANSACTION_SYNC ready 51 | directive set -DATA_SYNC none 52 | directive set -RESET_CLEARS_ALL_REGS yes 53 | directive set -CLOCK_OVERHEAD 20.000000 54 | directive set -OPT_CONST_MULTS use_library 55 | directive set -CHARACTERIZE_ROM false 56 | directive set -PROTOTYPE_ROM true 57 | directive set -ROM_THRESHOLD 64 58 | directive set -CLUSTER_ADDTREE_IN_WIDTH_THRESHOLD 0 59 | directive set -CLUSTER_OPT_CONSTANT_INPUTS true 60 | directive set -CLUSTER_RTL_SYN false 61 | directive set -CLUSTER_FAST_MODE false 62 | directive set -CLUSTER_TYPE combinational 63 | directive set -COMPGRADE fast 64 | directive set -PIPELINE_RAMP_UP true 65 | 66 | 67 | solution options set /Flows/SCVerify/USE_VCS false 68 | solution options set /Flows/SCVerify/USE_MSIM true 69 | 70 | options set Input/SearchPath ". $env(MATCHLIB_HOME)/cmod $env(MATCHLIB_HOME)/cmod/include $env(BOOST_HOME)/include" 71 | options set Input/CppStandard c++11 72 | options set Architectural/DesignGoal latency 73 | 74 | #global variables across all steps 75 | set TOP_NAME "ic_top" 76 | set CLK_NAME clk 77 | set CLK_PERIOD 10 78 | set SRC_DIR "../../" 79 | 80 | set DESIGN_FILES [list ./ic_top_2d_1noc.h] 81 | set TB_FILES [list ./axi_main.cpp] 82 | 83 | # Choose router 84 | set ROUTER_SELECT_FLAG "-DUSE_ROUTER_ST_BUF" 85 | 86 | if { [info exists env(HLS_CATAPULT)] && ($env(HLS_CATAPULT) eq "1") } { 87 | set HLS_CATAPULT_FLAG "-DHLS_CATAPULT" 88 | } else { 89 | set HLS_CATAPULT_FLAG "" 90 | } 91 | 92 | solution options set Input/TargetPlatform x86_64 93 | 94 | # Add your design here 95 | foreach design_file $DESIGN_FILES { 96 | solution file add $design_file -type SYSTEMC 97 | } 98 | foreach tb_file $TB_FILES { 99 | solution file add $tb_file -type SYSTEMC -exclude true 100 | } 101 | options set Input/CompilerFlags "-DHLS_CATAPULT -DSC_INCLUDE_DYNAMIC_PROCESSES -DCONNECTIONS_ACCURATE_SIM $HLS_CATAPULT_FLAG $ROUTER_SELECT_FLAG" 102 | go analyze 103 | solution library add nangate-45nm_beh -- -rtlsyntool OasysRTL -vendor Nangate -technology 045nm 104 | #solution library add mgc_sample-065nm-dw_beh_dc -- -rtlsyntool DesignCompiler -vendor Sample -technology 065nm -Designware Yes 105 | #solution library add ram_sample-065nm-singleport_beh_dc 106 | 107 | # Clock, interface constrain 108 | set CLK_PERIODby2 [expr $CLK_PERIOD/2] 109 | directive set -CLOCKS "$CLK_NAME \"-CLOCK_PERIOD $CLK_PERIOD -CLOCK_EDGE rising -CLOCK_UNCERTAINTY 0.0 -CLOCK_HIGH_TIME $CLK_PERIODby2 -RESET_SYNC_NAME rst -RESET_ASYNC_NAME arst_n -RESET_KIND sync -RESET_SYNC_ACTIVE high -RESET_ASYNC_ACTIVE low -ENABLE_NAME {} -ENABLE_ACTIVE high\" " 110 | directive set -CLOCK_NAME $CLK_NAME 111 | directive set GATE_REGISTERS false 112 | 113 | directive set -DESIGN_HIERARCHY "$TOP_NAME" 114 | 115 | go compile 116 | go libraries 117 | go assembly 118 | 119 | go architect 120 | go allocate 121 | go schedule 122 | go dpfsm 123 | go extract 124 | #flow run /OasysRTL/launch_tool ./concat_rtl.v.or v 125 | # go switching 126 | project save 127 | 128 | # exit 129 | -------------------------------------------------------------------------------- /src/router_wh.h: -------------------------------------------------------------------------------- 1 | #ifndef WH_ROUTER_CON_ST_BUF_H 2 | #define WH_ROUTER_CON_ST_BUF_H 3 | 4 | #include "systemc.h" 5 | #include "./include/flit_axi.h" 6 | #include "./include/duth_fun.h" 7 | #include "./include/arbiters.h" 8 | 9 | #include "nvhls_connections.h" 10 | 11 | // Select In/Out Ports, the type of flit and the Routing Computation calculation function 12 | // For RC_METHOD: 0-> direct rc 1-> lut, 2-> type, ... , 4-> LUT based routing 13 | // IN_NUM : Number of inputs 14 | // OUT_NUM : Number of inputs 15 | // flit_t : The networks flit type 16 | // RC_METHOD : Routing Computation Algotrithm 17 | // - 0 : Direct RC 18 | // - 1 : Constant RC (for mergers) 19 | // - 2 : Packet type RC (for distinct routing of Writes and reads) 20 | // - 3 : For single stage NoCs 21 | // - 4 : LUT based RC 22 | // - 5 : XY routing with merged RD/WR Req-Resp 23 | // DIM_X : X Dimension of a 2-D mesh network. Used in XY routing 24 | // NODES : All possible target nodes of the network. Used in LUT routing 25 | // ARB_C : The arbiter type. Eg MATRIX, ROUND_ROBIN 26 | template > 27 | SC_MODULE(router_wh_top) { 28 | 29 | typedef sc_uint< clog2::val > port_w_t; 30 | 31 | sc_in_clk clk{"clk"}; 32 | sc_in rst_n{"rst_n"}; 33 | 34 | // LUT is passed as a signal for LUT based RC. Otherwise Not-Used 35 | sc_in< sc_uint > route_lut[NODES]; 36 | 37 | // id_x and id_y are the X,Y dimensions of the router in a 2-D mesh network. Otherwise Not-Used 38 | sc_in< sc_uint > id_x{"id_x"}; 39 | sc_in< sc_uint > id_y{"id_y"}; 40 | 41 | // Input channels 42 | Connections::InBuffered data_in[IN_NUM]; 43 | // Output channels 44 | Connections::OutBuffered data_out[OUT_NUM]; 45 | 46 | //Per input 47 | // Each input has a lock bit, meaning the required outport has been locked for this input 48 | bool out_lock[IN_NUM]; 49 | // Each input stores its required outport (for body/tail flits) 50 | port_w_t out_port[IN_NUM]; 51 | 52 | // Per Output 53 | // out available holds the availability of the corresponding output port 54 | bool out_available[OUT_NUM]; 55 | ARB_C arbiter[OUT_NUM]; 56 | 57 | // Constructor 58 | SC_HAS_PROCESS(router_wh_top); 59 | router_wh_top(sc_module_name name_="router_wh_top") 60 | : sc_module(name_) 61 | { 62 | SC_THREAD(router_job); 63 | sensitive << clk.pos(); 64 | async_reset_signal_is(rst_n, false); 65 | } 66 | 67 | void router_job (){ 68 | #pragma hls_unroll yes 69 | per_i_rst:for (unsigned char i=0; i req_per_i[IN_NUM]; 91 | sc_uint req_per_o[OUT_NUM]; 92 | 93 | sc_uint gnt_per_o[OUT_NUM]; 94 | sc_uint gnt_per_i[IN_NUM]; 95 | 96 | bool is_inp_granted[IN_NUM][OUT_NUM]; 97 | 98 | // Input logic, loops for each input to produce the required requests 99 | #pragma hls_unroll yes 100 | set_inp: for (int ip=0; ip port_req_oh = (1<(current_op);// (1<::mux_oh_case(port_req_oh, ready_outp); 136 | bool outp_avail = mux::mux_oh_case(port_req_oh, out_available); 137 | 138 | bool all_ok = (fifo_valid[ip] && outp_ready && (out_lock[ip] || (is_head_single && outp_avail))); 139 | req_per_i[ip] = all_ok ? port_req_oh : (sc_uint) 0; 140 | } // End of set_inp 141 | 142 | swap_dim< sc_uint, IN_NUM, sc_uint, OUT_NUM >( req_per_i, req_per_o ); 143 | 144 | // Loop each of the outputs, choosing an input to win the output using an arbitration scheme 145 | #pragma hls_unroll yes 146 | per_o:for (unsigned char op=0; op::mux_oh_case(gnt_per_o[op], hol_data); 154 | if(any_gnt) { 155 | data_out[op].Push(selected_flit); 156 | 157 | if (selected_flit.is_head()) out_available[op] = false; 158 | else if (selected_flit.is_tail()) out_available[op] = true; 159 | } 160 | } // End per_o 161 | 162 | swap_dim< sc_uint, OUT_NUM, sc_uint, IN_NUM >( gnt_per_o, gnt_per_i ); 163 | 164 | // Loop through each input to handle the case of actually winning the output 165 | #pragma hls_unroll yes 166 | popped_i:for (unsigned char ip=0; iplocks Tail->unlocks 170 | if (hol_data[ip].is_head()) out_lock[ip] = true; 171 | else if(hol_data[ip].is_tail()) out_lock[ip] = false; 172 | 173 | data_in[ip].Pop(); 174 | } 175 | } 176 | 177 | 178 | // Move flits from internal Buffer to Out Port 179 | #pragma hls_unroll yes 180 | for (unsigned char op=0; op destination) {return destination.to_uint();}; 195 | // TYPE RC : Used for splitter/mergers. Routes RD to Out==0, and WR to Out==1 196 | inline unsigned char do_rc_type (sc_lv type) {return (type==dnp::PACK_TYPE__RD_REQ || type==dnp::PACK_TYPE__RD_RESP) ? 0 : 1;}; 197 | // Const RC : Used for mergers to always request port #0 198 | inline unsigned char do_rc_const () {return 0;}; 199 | // For single stage NoCs 200 | inline unsigned char do_rc_common (sc_lv destination, sc_lv type) { 201 | if (type==dnp::PACK_TYPE__RD_REQ) return destination.to_uint(); 202 | else if (type==dnp::PACK_TYPE__RD_RESP) return destination.to_uint()-2; 203 | else if (type==dnp::PACK_TYPE__WR_REQ) return destination.to_uint()+2; 204 | else return destination.to_uint(); 205 | }; 206 | // LUT Based RC 207 | inline unsigned char do_rc_lut (sc_lv destination) { 208 | return route_lut[destination.to_uint()].read(); 209 | }; 210 | // XY merged RD/WR 211 | inline unsigned char do_rc_xy_merge (sc_uint destination, sc_uint type) { 212 | sc_uint this_id_x = id_x.read(); 213 | sc_uint this_id_y = id_y.read(); 214 | 215 | sc_uint dst_x = destination % DIM_X; 216 | sc_uint dst_y = destination / DIM_X; 217 | 218 | if (dst_x>this_id_x) { 219 | return 1; 220 | } else if (dst_xthis_id_y) { 224 | return 3; 225 | } else if (dst_y 11 | #include 12 | #endif 13 | 14 | //ToDo add this in thr flit class 15 | enum FLIT_TYPE {HEAD=0 , BODY=1, TAIL=3, SINGLE=2}; 16 | 17 | template 18 | struct flit_dnp { 19 | sc_uint<2> type; 20 | sc_uint<2> vc; 21 | //sc_uint<32> dbg_id; 22 | sc_uint data[PHIT_NUM]; 23 | 24 | static const int width = 2+2+(PHIT_NUM*dnp::PHIT_W); // Matchlib Marshaller requirement 25 | 26 | // helping functions to retrieve flit info (e.g. flit type, source, destination) 27 | inline bool performs_rc() { return ((type == HEAD) || (type == SINGLE)); } 28 | inline bool resets_states() { return (type == TAIL); } 29 | 30 | inline bool is_head() {return (type==HEAD);}; 31 | inline bool is_tail() {return (type==TAIL);}; 32 | inline bool is_body() {return (type==BODY);}; 33 | inline bool is_single() {return (type==SINGLE);}; 34 | 35 | // DNP fields set/getters 36 | inline sc_uint get_dst() const {return ((data[0] >> dnp::D_PTR) & ((1< get_src() const {return ((data[0] >> dnp::S_PTR) & ((1< get_type() const {return ((data[0] >> dnp::T_PTR) & ((1< get_vc() const {return vc;}; 40 | inline sc_uint get_qos() const {return ((data[0] >> dnp::Q_PTR) & ((1< dst ) { data[0] = (data[0].range(dnp::PHIT_W-1, dnp::D_PTR+dnp::D_W) << (dnp::D_PTR+dnp::D_W)) | 43 | (dst << dnp::D_PTR) | 44 | (data[0].range(dnp::D_PTR-1, 0)); 45 | }; 46 | inline void set_src(sc_uint src ) { data[0] = (data[0].range(dnp::PHIT_W-1, dnp::S_PTR+dnp::S_W) << (dnp::S_PTR+dnp::S_W)) | 47 | (src << dnp::S_PTR) | 48 | (data[0].range(dnp::S_PTR-1, 0)); 49 | }; 50 | inline void set_type(sc_uint type) { data[0] = (data[0].range(dnp::PHIT_W-1, dnp::T_PTR+dnp::T_W) << (dnp::T_PTR+dnp::T_W)) | 51 | (type << dnp::T_PTR) | 52 | (data[0].range(dnp::T_PTR-1, 0)); 53 | }; 54 | inline void set_vc(sc_uint vc_ ) { vc = vc_; }; 55 | inline void set_qos(sc_uint qos ) { data[0] = (data[0].range(dnp::PHIT_W-1, dnp::Q_PTR+dnp::Q_W) << (dnp::Q_PTR+dnp::Q_W)) | 56 | (qos << dnp::Q_PTR) | 57 | (data[0].range(dnp::Q_PTR-1, 0)); 58 | }; 59 | inline void set_network( 60 | sc_uint src, 61 | sc_uint dst, 62 | sc_uint vc, 63 | sc_uint type, 64 | sc_uint qos 65 | ) { 66 | set_vc(vc); 67 | data[0] = (data[0].range(dnp::PHIT_W-1, dnp::T_PTR+dnp::T_W) << (dnp::T_PTR+dnp::T_W)) | 68 | (type << dnp::T_PTR) | 69 | (qos << dnp::Q_PTR) | 70 | (dst << dnp::D_PTR) | 71 | (src << dnp::S_PTR) ; 72 | }; 73 | 74 | template 75 | inline void set_rd_req (const T& rd_req, sc_uint reord_tct) { 76 | this->data[0] = ((sc_uint) reord_tct << dnp::req::REORD_PTR) | 77 | ((sc_uint) rd_req.id << dnp::req::ID_PTR) | 78 | (sc_uint) this->data[0].range(dnp::T_PTR+dnp::T_W-1, 0); // Keep the network portion unaffected 79 | 80 | this->data[1] = ((sc_uint) rd_req.len << dnp::req::LE_PTR) | 81 | ((sc_uint)(rd_req.addr & 0xffff) << dnp::req::AL_PTR) ; 82 | 83 | this->data[2] = ((sc_uint) rd_req.burst << dnp::req::BU_PTR ) | 84 | ((sc_uint) rd_req.size << dnp::req::SZ_PTR ) | 85 | ((sc_uint)(rd_req.addr >> dnp::AL_W) << dnp::req::AH_PTR) ; 86 | }; 87 | 88 | template 89 | inline void set_wr_req (const T& wr_req, sc_uint reord_tct) {this->set_rd_req(wr_req, reord_tct);}; 90 | 91 | template 92 | inline void set_rd_resp (const T& rd_req, sc_uint reord_tct) { 93 | this->data[0] = ((sc_uint) rd_req.burst << dnp::rresp::BU_PTR) | 94 | ((sc_uint) reord_tct << dnp::rresp::REORD_PTR) | 95 | ((sc_uint) rd_req.id << dnp::rresp::ID_PTR) | 96 | (sc_uint) this->data[0].range(dnp::T_PTR+dnp::T_W-1, 0); // Keep the network portion unaffected 97 | 98 | this->data[1] = ((sc_uint) (rd_req.addr & ((1<) rd_req.len << dnp::rresp::LE_PTR ) | 100 | ((sc_uint) rd_req.size << dnp::rresp::SZ_PTR) ; 101 | }; 102 | 103 | template 104 | inline void get_rd_req (T& rd_req, sc_uint &reord_tct) const { 105 | reord_tct = (this->data[0] >> dnp::req::REORD_PTR) & ((1<data[0] >> dnp::req::ID_PTR) & ((1<data[1] >> dnp::req::LE_PTR) & ((1<data[2] >> dnp::req::SZ_PTR) & ((1<data[2] >> dnp::req::BU_PTR) & ((1<data[2]>>dnp::req::AH_PTR) & ((1<data[1]>>dnp::req::AL_PTR) & ((1< 115 | inline void get_wr_req (const T& wr_req, sc_uint &reord_tct) const {this->get_rd_req(wr_req, reord_tct);}; 116 | 117 | // Flit Constructors 118 | flit_dnp () { 119 | type = 0; 120 | vc = 0; 121 | #pragma hls_unroll yes 122 | for(int i=0; itype; 147 | vc = rhs->vc; 148 | //dbg_id = rhs->dbg_id; 149 | #pragma hls_unroll yes 150 | for(int i=0; idata[i]; 151 | 152 | return *this; 153 | }; 154 | 155 | inline bool operator==(const flit_dnp& rhs) const { 156 | bool eq = (rhs.type == type) && (rhs.vc == vc); 157 | for(int i=0; i mask = 0; 190 | 191 | #pragma hls_unroll yes 192 | for(int j=0; j=0; --i) os << std::hex << flit_tmp.data[i].to_uint() << "_"; 220 | 221 | #ifdef SYSTEMC_INCLUDED 222 | os << std::dec << "@" << sc_time_stamp(); 223 | #else 224 | os << std::dec << "@" << "no-timed"; 225 | #endif 226 | 227 | return os; 228 | } 229 | //#endif 230 | 231 | #ifdef SYSTEMC_INCLUDED 232 | // Only for SystemC 233 | inline friend void sc_trace(sc_trace_file* tf, const flit_dnp& flit, const std::string& name) { 234 | sc_trace(tf, flit.type, name + ".type"); 235 | sc_trace(tf, flit.vc, name + ".vc"); 236 | //sc_trace(tf, flit.dbg_id, name + ".dbg_id"); 237 | for(int i=0; i 244 | void Marshall(Marshaller& m) { 245 | //m& dbg_id; 246 | m& type; 247 | m& vc; 248 | #pragma hls_unroll yes 249 | for(int i=PHIT_NUM-1; i>=0; --i) m& data[i]; 250 | }; 251 | 252 | }; 253 | 254 | #endif // __FLIT_DNP_H__ 255 | 256 | -------------------------------------------------------------------------------- /examples/nocpad_2m-2s_2d-mesh_id-order/ic_top_2d.h: -------------------------------------------------------------------------------- 1 | #ifndef AXI4_TOP_IC_H 2 | #define AXI4_TOP_IC_H 3 | 4 | #pragma once 5 | 6 | #include "../../src/axi_master_if.h" 7 | #include "../../src/axi_slave_if.h" 8 | 9 | #include "../../src/router_wh.h" 10 | 11 | #include "systemc.h" 12 | #include "nvhls_connections.h" 13 | 14 | #pragma hls_design top 15 | 16 | // Bundle of configuration parameters 17 | template < 18 | unsigned char MASTER_NUM_ , unsigned char SLAVE_NUM_, 19 | unsigned char RD_LANES_ , unsigned char WR_LANES_, 20 | unsigned char RREQ_PHITS_ , unsigned char RRESP_PHITS_, 21 | unsigned char WREQ_PHITS_ , unsigned char WRESP_PHITS_, 22 | unsigned char ORD_SCHEME_ 23 | > 24 | struct cfg { 25 | static const unsigned char MASTER_NUM = MASTER_NUM_; 26 | static const unsigned char SLAVE_NUM = SLAVE_NUM_; 27 | static const unsigned char RD_LANES = RD_LANES_; 28 | static const unsigned char WR_LANES = WR_LANES_; 29 | static const unsigned char RREQ_PHITS = RREQ_PHITS_; 30 | static const unsigned char RRESP_PHITS = RRESP_PHITS_; 31 | static const unsigned char WREQ_PHITS = WREQ_PHITS_; 32 | static const unsigned char WRESP_PHITS = WRESP_PHITS_; 33 | static const unsigned char ORD_SCHEME = ORD_SCHEME_; 34 | }; 35 | 36 | // the used configuration. 2 Masters/Slaves, 64bit AXI, 2.4.4.1 phit flits 37 | typedef cfg<2, 2, 8, 8, 4, 4, 4, 4, 1> smpl_cfg; 38 | 39 | SC_MODULE(ic_top) { 40 | public: 41 | // typedef matchlib's axi with the "standard" configuration 42 | typedef typename axi::axi4 axi4_; 43 | 44 | // typedef the 4 kind of flits(RD/WR Req/Resp) depending their size 45 | typedef flit_dnp rreq_flit_t; 46 | typedef flit_dnp rresp_flit_t; 47 | typedef flit_dnp wreq_flit_t; 48 | typedef flit_dnp wresp_flit_t; 49 | 50 | static const unsigned DIM_X = 2; 51 | static const unsigned DIM_Y = 2; 52 | 53 | sc_in_clk clk; 54 | sc_in rst_n; 55 | 56 | // IC's Address map 57 | sc_in > addr_map[smpl_cfg::SLAVE_NUM][2]; // [SLAVE_NUM][0:begin, 1: End] 58 | 59 | sc_signal< sc_uint > route_lut[2][1]; 60 | 61 | // The Node IDs are passed to IFs as signals 62 | sc_signal< sc_uint > NODE_IDS_MASTER[smpl_cfg::MASTER_NUM]; 63 | sc_signal< sc_uint > NODE_IDS_SLAVE[smpl_cfg::SLAVE_NUM]; 64 | 65 | sc_signal< sc_uint > rtr_id_x_req[DIM_X]; 66 | sc_signal< sc_uint > rtr_id_y_req[DIM_Y]; 67 | 68 | sc_signal< sc_uint > rtr_id_x_resp[DIM_X]; 69 | sc_signal< sc_uint > rtr_id_y_resp[DIM_Y]; 70 | 71 | // MASTER Side AXI Channels 72 | Connections::In ar_in[smpl_cfg::MASTER_NUM]; 73 | Connections::Out r_out[smpl_cfg::MASTER_NUM]; 74 | 75 | Connections::In aw_in[smpl_cfg::MASTER_NUM]; 76 | Connections::In w_in[smpl_cfg::MASTER_NUM]; 77 | Connections::Out b_out[smpl_cfg::MASTER_NUM]; 78 | 79 | // SLAVE Side AXI Channels 80 | Connections::Out ar_out[smpl_cfg::SLAVE_NUM]; 81 | Connections::In r_in[smpl_cfg::SLAVE_NUM]; 82 | 83 | Connections::Out aw_out[smpl_cfg::SLAVE_NUM]; 84 | Connections::Out w_out[smpl_cfg::SLAVE_NUM]; 85 | Connections::In b_in[smpl_cfg::SLAVE_NUM]; 86 | 87 | //--- Internals ---// 88 | // --- Master/Slave IFs --- 89 | axi_master_if < smpl_cfg > *master_if[smpl_cfg::MASTER_NUM]; 90 | axi_slave_if < smpl_cfg > *slave_if[smpl_cfg::SLAVE_NUM]; 91 | 92 | // Master IF Channels 93 | // Read Req/Resp 94 | Connections::Combinational chan_rd_m2r[smpl_cfg::MASTER_NUM]; 95 | Connections::Combinational chan_rd_r2m[smpl_cfg::MASTER_NUM]; 96 | // Write Req/Resp 97 | Connections::Combinational chan_wr_m2r[smpl_cfg::MASTER_NUM]; 98 | Connections::Combinational chan_wr_r2m[smpl_cfg::MASTER_NUM]; 99 | 100 | // Slave IF 101 | // Read Req/Resp 102 | Connections::Combinational chan_rd_r2s[smpl_cfg::SLAVE_NUM]; 103 | Connections::Combinational chan_rd_s2r[smpl_cfg::SLAVE_NUM]; 104 | 105 | Connections::Combinational chan_wr_r2s[smpl_cfg::SLAVE_NUM]; 106 | Connections::Combinational chan_wr_s2r[smpl_cfg::SLAVE_NUM]; 107 | 108 | // --- NoC Channels --- 109 | // REQ Router + In/Out Channels 110 | router_wh_top< 4+2, 4+2, rreq_flit_t, 5, DIM_X> rtr_req[DIM_X][DIM_Y]; 111 | 112 | Connections::Combinational chan_hor_right_req[DIM_X+1][DIM_Y]; 113 | Connections::Combinational chan_hor_left_req[DIM_X+1][DIM_Y]; 114 | Connections::Combinational chan_ver_up_req[DIM_X][DIM_Y+1]; 115 | Connections::Combinational chan_ver_down_req[DIM_X][DIM_Y+1]; 116 | 117 | Connections::Combinational chan_inj_wreq[DIM_X][DIM_Y]; 118 | Connections::Combinational chan_inj_rreq[DIM_X][DIM_Y]; 119 | 120 | Connections::Combinational chan_ej_wreq[DIM_X][DIM_Y]; 121 | Connections::Combinational chan_ej_rreq[DIM_X][DIM_Y]; 122 | 123 | 124 | // RESP Router + In/Out Channels 125 | router_wh_top< 4+2, 4+2, rresp_flit_t, 5, DIM_X> *rtr_resp[DIM_X][DIM_Y]; 126 | 127 | Connections::Combinational chan_hor_right_resp[DIM_X+1][DIM_Y]; 128 | Connections::Combinational chan_hor_left_resp[DIM_X+1][DIM_Y]; 129 | Connections::Combinational chan_ver_up_resp[DIM_X][DIM_Y+1]; 130 | Connections::Combinational chan_ver_down_resp[DIM_X][DIM_Y+1]; 131 | 132 | 133 | Connections::Combinational chan_inj_wresp[DIM_X][DIM_Y]; 134 | Connections::Combinational chan_inj_rresp[DIM_X][DIM_Y]; 135 | 136 | Connections::Combinational chan_ej_wresp[DIM_X][DIM_Y]; 137 | Connections::Combinational chan_ej_rresp[DIM_X][DIM_Y]; 138 | 139 | 140 | SC_CTOR(ic_top) { 141 | 142 | route_lut[0][0] = 0; 143 | route_lut[1][0] = 0; 144 | 145 | // ----------------- // 146 | // --- SLAVE-IFs --- // 147 | // ----------------- // 148 | for(unsigned char j=0; j (sc_gen_unique_name("Slave-if")); 155 | slave_if[j]->clk(clk); 156 | slave_if[j]->rst_n(rst_n); 157 | 158 | slave_if[j]->THIS_ID(NODE_IDS_SLAVE[j]); 159 | slave_if[j]->slave_base_addr(addr_map[j][0]); 160 | // Read-NoC 161 | slave_if[j]->rd_flit_in(chan_ej_rreq[col][row]); 162 | slave_if[j]->rd_flit_out(chan_inj_rresp[col][row]); 163 | // Write-NoC 164 | slave_if[j]->wr_flit_in(chan_ej_wreq[col][row]); 165 | slave_if[j]->wr_flit_out(chan_inj_wresp[col][row]); 166 | // Slave-Side 167 | slave_if[j]->ar_out(ar_out[j]); 168 | slave_if[j]->r_in(r_in[j]); 169 | 170 | slave_if[j]->aw_out(aw_out[j]); 171 | slave_if[j]->w_out(w_out[j]); 172 | slave_if[j]->b_in(b_in[j]); 173 | } 174 | 175 | // ------------------------------ // 176 | // --- MASTER-IFs Connectivity--- // 177 | // ------------------------------ // 178 | for (int i=0; i (sc_gen_unique_name("Master-if")); 185 | master_if[i]->clk(clk); 186 | master_if[i]->rst_n(rst_n); 187 | // Pass the address Map 188 | for (int n=0; naddr_map[n][s](addr_map[n][s]); 191 | 192 | master_if[i]->THIS_ID(NODE_IDS_MASTER[i]); 193 | 194 | // Master-AXI-Side 195 | master_if[i]->ar_in(ar_in[i]); 196 | master_if[i]->r_out(r_out[i]); 197 | 198 | master_if[i]->aw_in(aw_in[i]); 199 | master_if[i]->w_in(w_in[i]); 200 | master_if[i]->b_out(b_out[i]); 201 | // Read-NoC 202 | master_if[i]->rd_flit_out(chan_inj_rreq[col][row]); 203 | master_if[i]->rd_flit_in(chan_ej_rresp[col][row]); 204 | // Write-NoC 205 | master_if[i]->wr_flit_out(chan_inj_wreq[col][row]); 206 | master_if[i]->wr_flit_in(chan_ej_wresp[col][row]); 207 | } 208 | // -o-o-o-o-o-o-o-o-o- // 209 | // -o-o-o-o-o-o-o-o-o- // 210 | 211 | for (int row=0; row (sc_gen_unique_name("Router-resp")); 250 | rtr_resp[col][row]->clk(clk); 251 | rtr_resp[col][row]->rst_n(rst_n); 252 | rtr_resp[col][row]->route_lut[0](route_lut[0][0]); 253 | rtr_resp[col][row]->id_x(rtr_id_x_resp[col]); 254 | rtr_resp[col][row]->id_y(rtr_id_y_resp[row]); 255 | 256 | rtr_resp[col][row]->data_in[0](chan_hor_right_resp[col][row]); 257 | rtr_resp[col][row]->data_out[0](chan_hor_left_resp[col][row]); 258 | 259 | rtr_resp[col][row]->data_in[1](chan_hor_left_resp[col+1][row]); 260 | rtr_resp[col][row]->data_out[1](chan_hor_right_resp[col+1][row]); 261 | 262 | rtr_resp[col][row]->data_in[2](chan_ver_up_resp[col][row]); 263 | rtr_resp[col][row]->data_out[2](chan_ver_down_resp[col][row]); 264 | 265 | rtr_resp[col][row]->data_in[3](chan_ver_down_resp[col][row+1]); 266 | rtr_resp[col][row]->data_out[3](chan_ver_up_resp[col][row+1]); 267 | 268 | rtr_resp[col][row]->data_in[4](chan_inj_rresp[col][row]); 269 | rtr_resp[col][row]->data_out[4](chan_ej_rresp[col][row]); 270 | 271 | rtr_resp[col][row]->data_in[5](chan_inj_wresp[col][row]); 272 | rtr_resp[col][row]->data_out[5](chan_ej_wresp[col][row]); 273 | } 274 | } 275 | }; // End of constructor 276 | 277 | private: 278 | }; // End of SC_MODULE 279 | 280 | #endif // AXI4_TOP_IC_H 281 | -------------------------------------------------------------------------------- /examples/nocpad_2m-2s_2d-mesh_basic-order/ic_top_2d.h: -------------------------------------------------------------------------------- 1 | #ifndef AXI4_TOP_IC_H 2 | #define AXI4_TOP_IC_H 3 | 4 | #pragma once 5 | 6 | #include "../../src/axi_master_if.h" 7 | #include "../../src/axi_slave_if.h" 8 | 9 | #include "../../src/router_wh.h" 10 | 11 | #include "systemc.h" 12 | #include "nvhls_connections.h" 13 | 14 | #pragma hls_design top 15 | 16 | // Bundle of configuration parameters 17 | template < 18 | unsigned char MASTER_NUM_ , unsigned char SLAVE_NUM_, 19 | unsigned char RD_LANES_ , unsigned char WR_LANES_, 20 | unsigned char RREQ_PHITS_ , unsigned char RRESP_PHITS_, 21 | unsigned char WREQ_PHITS_ , unsigned char WRESP_PHITS_, 22 | unsigned char ORD_SCHEME_ 23 | > 24 | struct cfg { 25 | static const unsigned char MASTER_NUM = MASTER_NUM_; 26 | static const unsigned char SLAVE_NUM = SLAVE_NUM_; 27 | static const unsigned char RD_LANES = RD_LANES_; 28 | static const unsigned char WR_LANES = WR_LANES_; 29 | static const unsigned char RREQ_PHITS = RREQ_PHITS_; 30 | static const unsigned char RRESP_PHITS = RRESP_PHITS_; 31 | static const unsigned char WREQ_PHITS = WREQ_PHITS_; 32 | static const unsigned char WRESP_PHITS = WRESP_PHITS_; 33 | static const unsigned char ORD_SCHEME = ORD_SCHEME_; 34 | }; 35 | 36 | // the used configuration. 2 Masters/Slaves, 64bit AXI, 2.4.4.1 phit flits 37 | typedef cfg<2, 2, 8, 8, 4, 4, 4, 4, 0> smpl_cfg; 38 | 39 | SC_MODULE(ic_top) { 40 | public: 41 | // typedef matchlib's axi with the "standard" configuration 42 | typedef typename axi::axi4 axi4_; 43 | 44 | // typedef the 4 kind of flits(RD/WR Req/Resp) depending their size 45 | typedef flit_dnp rreq_flit_t; 46 | typedef flit_dnp rresp_flit_t; 47 | typedef flit_dnp wreq_flit_t; 48 | typedef flit_dnp wresp_flit_t; 49 | 50 | static const unsigned DIM_X = 2; 51 | static const unsigned DIM_Y = 2; 52 | 53 | sc_in_clk clk; 54 | sc_in rst_n; 55 | 56 | // IC's Address map 57 | sc_in > addr_map[smpl_cfg::SLAVE_NUM][2]; // [SLAVE_NUM][0:begin, 1: End] 58 | 59 | sc_signal< sc_uint > route_lut[2][1]; 60 | 61 | // The Node IDs are passed to IFs as signals 62 | sc_signal< sc_uint > NODE_IDS_MASTER[smpl_cfg::MASTER_NUM]; 63 | sc_signal< sc_uint > NODE_IDS_SLAVE[smpl_cfg::SLAVE_NUM]; 64 | 65 | sc_signal< sc_uint > rtr_id_x_req[DIM_X]; 66 | sc_signal< sc_uint > rtr_id_y_req[DIM_Y]; 67 | 68 | sc_signal< sc_uint > rtr_id_x_resp[DIM_X]; 69 | sc_signal< sc_uint > rtr_id_y_resp[DIM_Y]; 70 | 71 | // MASTER Side AXI Channels 72 | Connections::In ar_in[smpl_cfg::MASTER_NUM]; 73 | Connections::Out r_out[smpl_cfg::MASTER_NUM]; 74 | 75 | Connections::In aw_in[smpl_cfg::MASTER_NUM]; 76 | Connections::In w_in[smpl_cfg::MASTER_NUM]; 77 | Connections::Out b_out[smpl_cfg::MASTER_NUM]; 78 | 79 | // SLAVE Side AXI Channels 80 | Connections::Out ar_out[smpl_cfg::SLAVE_NUM]; 81 | Connections::In r_in[smpl_cfg::SLAVE_NUM]; 82 | 83 | Connections::Out aw_out[smpl_cfg::SLAVE_NUM]; 84 | Connections::Out w_out[smpl_cfg::SLAVE_NUM]; 85 | Connections::In b_in[smpl_cfg::SLAVE_NUM]; 86 | 87 | //--- Internals ---// 88 | // --- Master/Slave IFs --- 89 | axi_master_if < smpl_cfg > *master_if[smpl_cfg::MASTER_NUM]; 90 | axi_slave_if < smpl_cfg > *slave_if[smpl_cfg::SLAVE_NUM]; 91 | 92 | // Master IF Channels 93 | // Read Req/Resp 94 | Connections::Combinational chan_rd_m2r[smpl_cfg::MASTER_NUM]; 95 | Connections::Combinational chan_rd_r2m[smpl_cfg::MASTER_NUM]; 96 | // Write Req/Resp 97 | Connections::Combinational chan_wr_m2r[smpl_cfg::MASTER_NUM]; 98 | Connections::Combinational chan_wr_r2m[smpl_cfg::MASTER_NUM]; 99 | 100 | // Slave IF 101 | // Read Req/Resp 102 | Connections::Combinational chan_rd_r2s[smpl_cfg::SLAVE_NUM]; 103 | Connections::Combinational chan_rd_s2r[smpl_cfg::SLAVE_NUM]; 104 | 105 | Connections::Combinational chan_wr_r2s[smpl_cfg::SLAVE_NUM]; 106 | Connections::Combinational chan_wr_s2r[smpl_cfg::SLAVE_NUM]; 107 | 108 | // --- NoC Channels --- 109 | // REQ Router + In/Out Channels 110 | router_wh_top< 4+2, 4+2, rreq_flit_t, 5, DIM_X> rtr_req[DIM_X][DIM_Y]; 111 | 112 | Connections::Combinational chan_hor_right_req[DIM_X+1][DIM_Y]; 113 | Connections::Combinational chan_hor_left_req[DIM_X+1][DIM_Y]; 114 | Connections::Combinational chan_ver_up_req[DIM_X][DIM_Y+1]; 115 | Connections::Combinational chan_ver_down_req[DIM_X][DIM_Y+1]; 116 | 117 | Connections::Combinational chan_inj_wreq[DIM_X][DIM_Y]; 118 | Connections::Combinational chan_inj_rreq[DIM_X][DIM_Y]; 119 | 120 | Connections::Combinational chan_ej_wreq[DIM_X][DIM_Y]; 121 | Connections::Combinational chan_ej_rreq[DIM_X][DIM_Y]; 122 | 123 | 124 | // RESP Router + In/Out Channels 125 | router_wh_top< 4+2, 4+2, rresp_flit_t, 5, DIM_X> *rtr_resp[DIM_X][DIM_Y]; 126 | 127 | Connections::Combinational chan_hor_right_resp[DIM_X+1][DIM_Y]; 128 | Connections::Combinational chan_hor_left_resp[DIM_X+1][DIM_Y]; 129 | Connections::Combinational chan_ver_up_resp[DIM_X][DIM_Y+1]; 130 | Connections::Combinational chan_ver_down_resp[DIM_X][DIM_Y+1]; 131 | 132 | 133 | Connections::Combinational chan_inj_wresp[DIM_X][DIM_Y]; 134 | Connections::Combinational chan_inj_rresp[DIM_X][DIM_Y]; 135 | 136 | Connections::Combinational chan_ej_wresp[DIM_X][DIM_Y]; 137 | Connections::Combinational chan_ej_rresp[DIM_X][DIM_Y]; 138 | 139 | 140 | SC_CTOR(ic_top) { 141 | 142 | route_lut[0][0] = 0; 143 | route_lut[1][0] = 0; 144 | 145 | // ----------------- // 146 | // --- SLAVE-IFs --- // 147 | // ----------------- // 148 | for(unsigned char j=0; j (sc_gen_unique_name("Slave-if")); 155 | slave_if[j]->clk(clk); 156 | slave_if[j]->rst_n(rst_n); 157 | 158 | slave_if[j]->THIS_ID(NODE_IDS_SLAVE[j]); 159 | slave_if[j]->slave_base_addr(addr_map[j][0]); 160 | // Read-NoC 161 | slave_if[j]->rd_flit_in(chan_ej_rreq[col][row]); 162 | slave_if[j]->rd_flit_out(chan_inj_rresp[col][row]); 163 | // Write-NoC 164 | slave_if[j]->wr_flit_in(chan_ej_wreq[col][row]); 165 | slave_if[j]->wr_flit_out(chan_inj_wresp[col][row]); 166 | // Slave-Side 167 | slave_if[j]->ar_out(ar_out[j]); 168 | slave_if[j]->r_in(r_in[j]); 169 | 170 | slave_if[j]->aw_out(aw_out[j]); 171 | slave_if[j]->w_out(w_out[j]); 172 | slave_if[j]->b_in(b_in[j]); 173 | } 174 | 175 | // ------------------------------ // 176 | // --- MASTER-IFs Connectivity--- // 177 | // ------------------------------ // 178 | for (int i=0; i (sc_gen_unique_name("Master-if")); 185 | master_if[i]->clk(clk); 186 | master_if[i]->rst_n(rst_n); 187 | // Pass the address Map 188 | for (int n=0; naddr_map[n][s](addr_map[n][s]); 191 | 192 | master_if[i]->THIS_ID(NODE_IDS_MASTER[i]); 193 | 194 | // Master-AXI-Side 195 | master_if[i]->ar_in(ar_in[i]); 196 | master_if[i]->r_out(r_out[i]); 197 | 198 | master_if[i]->aw_in(aw_in[i]); 199 | master_if[i]->w_in(w_in[i]); 200 | master_if[i]->b_out(b_out[i]); 201 | // Read-NoC 202 | master_if[i]->rd_flit_out(chan_inj_rreq[col][row]); 203 | master_if[i]->rd_flit_in(chan_ej_rresp[col][row]); 204 | // Write-NoC 205 | master_if[i]->wr_flit_out(chan_inj_wreq[col][row]); 206 | master_if[i]->wr_flit_in(chan_ej_wresp[col][row]); 207 | } 208 | // -o-o-o-o-o-o-o-o-o- // 209 | // -o-o-o-o-o-o-o-o-o- // 210 | 211 | for (int row=0; row (sc_gen_unique_name("Router-resp")); 250 | rtr_resp[col][row]->clk(clk); 251 | rtr_resp[col][row]->rst_n(rst_n); 252 | rtr_resp[col][row]->route_lut[0](route_lut[0][0]); 253 | rtr_resp[col][row]->id_x(rtr_id_x_resp[col]); 254 | rtr_resp[col][row]->id_y(rtr_id_y_resp[row]); 255 | 256 | rtr_resp[col][row]->data_in[0](chan_hor_right_resp[col][row]); 257 | rtr_resp[col][row]->data_out[0](chan_hor_left_resp[col][row]); 258 | 259 | rtr_resp[col][row]->data_in[1](chan_hor_left_resp[col+1][row]); 260 | rtr_resp[col][row]->data_out[1](chan_hor_right_resp[col+1][row]); 261 | 262 | rtr_resp[col][row]->data_in[2](chan_ver_up_resp[col][row]); 263 | rtr_resp[col][row]->data_out[2](chan_ver_down_resp[col][row]); 264 | 265 | rtr_resp[col][row]->data_in[3](chan_ver_down_resp[col][row+1]); 266 | rtr_resp[col][row]->data_out[3](chan_ver_up_resp[col][row+1]); 267 | 268 | rtr_resp[col][row]->data_in[4](chan_inj_rresp[col][row]); 269 | rtr_resp[col][row]->data_out[4](chan_ej_rresp[col][row]); 270 | 271 | rtr_resp[col][row]->data_in[5](chan_inj_wresp[col][row]); 272 | rtr_resp[col][row]->data_out[5](chan_ej_wresp[col][row]); 273 | } 274 | } 275 | }; // End of constructor 276 | 277 | private: 278 | }; // End of SC_MODULE 279 | 280 | #endif // AXI4_TOP_IC_H 281 | -------------------------------------------------------------------------------- /examples/nocpad_2m-2s_2d-mesh_reorder/ic_top_2d.h: -------------------------------------------------------------------------------- 1 | #ifndef AXI4_TOP_IC_H 2 | #define AXI4_TOP_IC_H 3 | 4 | #pragma once 5 | 6 | #include "../../src/axi_master_if_reord.h" 7 | #include "../../src/axi_slave_if.h" 8 | 9 | #include "../../src/router_wh.h" 10 | 11 | #include "systemc.h" 12 | #include "nvhls_connections.h" 13 | 14 | #pragma hls_design top 15 | 16 | // Bundle of configuration parameters 17 | template < 18 | unsigned char MASTER_NUM_ , unsigned char SLAVE_NUM_, 19 | unsigned char RD_LANES_ , unsigned char WR_LANES_, 20 | unsigned char RREQ_PHITS_ , unsigned char RRESP_PHITS_, 21 | unsigned char WREQ_PHITS_ , unsigned char WRESP_PHITS_, 22 | unsigned char ORD_SCHEME_ 23 | > 24 | struct cfg { 25 | static const unsigned char MASTER_NUM = MASTER_NUM_; 26 | static const unsigned char SLAVE_NUM = SLAVE_NUM_; 27 | static const unsigned char RD_LANES = RD_LANES_; 28 | static const unsigned char WR_LANES = WR_LANES_; 29 | static const unsigned char RREQ_PHITS = RREQ_PHITS_; 30 | static const unsigned char RRESP_PHITS = RRESP_PHITS_; 31 | static const unsigned char WREQ_PHITS = WREQ_PHITS_; 32 | static const unsigned char WRESP_PHITS = WRESP_PHITS_; 33 | static const unsigned char ORD_SCHEME = ORD_SCHEME_; 34 | }; 35 | 36 | // the used configuration. 2 Masters/Slaves, 64bit AXI, 2.4.4.1 phit flits 37 | typedef cfg<2, 2, 8, 8, 4, 4, 4, 4, 1> smpl_cfg; 38 | 39 | SC_MODULE(ic_top) { 40 | public: 41 | // typedef matchlib's axi with the "standard" configuration 42 | typedef typename axi::axi4 axi4_; 43 | 44 | // typedef the 4 kind of flits(RD/WR Req/Resp) depending their size 45 | typedef flit_dnp rreq_flit_t; 46 | typedef flit_dnp rresp_flit_t; 47 | typedef flit_dnp wreq_flit_t; 48 | typedef flit_dnp wresp_flit_t; 49 | 50 | static const unsigned DIM_X = 2; 51 | static const unsigned DIM_Y = 2; 52 | 53 | sc_in_clk clk; 54 | sc_in rst_n; 55 | 56 | // IC's Address map 57 | sc_in > addr_map[smpl_cfg::SLAVE_NUM][2]; // [SLAVE_NUM][0:begin, 1: End] 58 | 59 | sc_signal< sc_uint > route_lut[2][1]; 60 | 61 | // The Node IDs are passed to IFs as signals 62 | sc_signal< sc_uint > NODE_IDS_MASTER[smpl_cfg::MASTER_NUM]; 63 | sc_signal< sc_uint > NODE_IDS_SLAVE[smpl_cfg::SLAVE_NUM]; 64 | 65 | sc_signal< sc_uint > rtr_id_x_req[DIM_X]; 66 | sc_signal< sc_uint > rtr_id_y_req[DIM_Y]; 67 | 68 | sc_signal< sc_uint > rtr_id_x_resp[DIM_X]; 69 | sc_signal< sc_uint > rtr_id_y_resp[DIM_Y]; 70 | 71 | // MASTER Side AXI Channels 72 | Connections::In ar_in[smpl_cfg::MASTER_NUM]; 73 | Connections::Out r_out[smpl_cfg::MASTER_NUM]; 74 | 75 | Connections::In aw_in[smpl_cfg::MASTER_NUM]; 76 | Connections::In w_in[smpl_cfg::MASTER_NUM]; 77 | Connections::Out b_out[smpl_cfg::MASTER_NUM]; 78 | 79 | // SLAVE Side AXI Channels 80 | Connections::Out ar_out[smpl_cfg::SLAVE_NUM]; 81 | Connections::In r_in[smpl_cfg::SLAVE_NUM]; 82 | 83 | Connections::Out aw_out[smpl_cfg::SLAVE_NUM]; 84 | Connections::Out w_out[smpl_cfg::SLAVE_NUM]; 85 | Connections::In b_in[smpl_cfg::SLAVE_NUM]; 86 | 87 | //--- Internals ---// 88 | // --- Master/Slave IFs --- 89 | axi_master_if < smpl_cfg > *master_if[smpl_cfg::MASTER_NUM]; 90 | axi_slave_if < smpl_cfg > *slave_if[smpl_cfg::SLAVE_NUM]; 91 | 92 | // Master IF Channels 93 | // Read Req/Resp 94 | Connections::Combinational chan_rd_m2r[smpl_cfg::MASTER_NUM]; 95 | Connections::Combinational chan_rd_r2m[smpl_cfg::MASTER_NUM]; 96 | // Write Req/Resp 97 | Connections::Combinational chan_wr_m2r[smpl_cfg::MASTER_NUM]; 98 | Connections::Combinational chan_wr_r2m[smpl_cfg::MASTER_NUM]; 99 | 100 | // Slave IF 101 | // Read Req/Resp 102 | Connections::Combinational chan_rd_r2s[smpl_cfg::SLAVE_NUM]; 103 | Connections::Combinational chan_rd_s2r[smpl_cfg::SLAVE_NUM]; 104 | 105 | Connections::Combinational chan_wr_r2s[smpl_cfg::SLAVE_NUM]; 106 | Connections::Combinational chan_wr_s2r[smpl_cfg::SLAVE_NUM]; 107 | 108 | // --- NoC Channels --- 109 | // REQ Router + In/Out Channels 110 | router_wh_top< 4+2, 4+2, rreq_flit_t, 5, DIM_X> rtr_req[DIM_X][DIM_Y]; 111 | 112 | Connections::Combinational chan_hor_right_req[DIM_X+1][DIM_Y]; 113 | Connections::Combinational chan_hor_left_req[DIM_X+1][DIM_Y]; 114 | Connections::Combinational chan_ver_up_req[DIM_X][DIM_Y+1]; 115 | Connections::Combinational chan_ver_down_req[DIM_X][DIM_Y+1]; 116 | 117 | Connections::Combinational chan_inj_wreq[DIM_X][DIM_Y]; 118 | Connections::Combinational chan_inj_rreq[DIM_X][DIM_Y]; 119 | 120 | Connections::Combinational chan_ej_wreq[DIM_X][DIM_Y]; 121 | Connections::Combinational chan_ej_rreq[DIM_X][DIM_Y]; 122 | 123 | 124 | // RESP Router + In/Out Channels 125 | router_wh_top< 4+2, 4+2, rresp_flit_t, 5, DIM_X> *rtr_resp[DIM_X][DIM_Y]; 126 | 127 | Connections::Combinational chan_hor_right_resp[DIM_X+1][DIM_Y]; 128 | Connections::Combinational chan_hor_left_resp[DIM_X+1][DIM_Y]; 129 | Connections::Combinational chan_ver_up_resp[DIM_X][DIM_Y+1]; 130 | Connections::Combinational chan_ver_down_resp[DIM_X][DIM_Y+1]; 131 | 132 | 133 | Connections::Combinational chan_inj_wresp[DIM_X][DIM_Y]; 134 | Connections::Combinational chan_inj_rresp[DIM_X][DIM_Y]; 135 | 136 | Connections::Combinational chan_ej_wresp[DIM_X][DIM_Y]; 137 | Connections::Combinational chan_ej_rresp[DIM_X][DIM_Y]; 138 | 139 | 140 | SC_CTOR(ic_top) { 141 | 142 | route_lut[0][0] = 0; 143 | route_lut[1][0] = 0; 144 | 145 | // ----------------- // 146 | // --- SLAVE-IFs --- // 147 | // ----------------- // 148 | for(unsigned char j=0; j (sc_gen_unique_name("Slave-if")); 155 | slave_if[j]->clk(clk); 156 | slave_if[j]->rst_n(rst_n); 157 | 158 | slave_if[j]->THIS_ID(NODE_IDS_SLAVE[j]); 159 | slave_if[j]->slave_base_addr(addr_map[j][0]); 160 | // Read-NoC 161 | slave_if[j]->rd_flit_in(chan_ej_rreq[col][row]); 162 | slave_if[j]->rd_flit_out(chan_inj_rresp[col][row]); 163 | // Write-NoC 164 | slave_if[j]->wr_flit_in(chan_ej_wreq[col][row]); 165 | slave_if[j]->wr_flit_out(chan_inj_wresp[col][row]); 166 | // Slave-Side 167 | slave_if[j]->ar_out(ar_out[j]); 168 | slave_if[j]->r_in(r_in[j]); 169 | 170 | slave_if[j]->aw_out(aw_out[j]); 171 | slave_if[j]->w_out(w_out[j]); 172 | slave_if[j]->b_in(b_in[j]); 173 | } 174 | 175 | // ------------------------------ // 176 | // --- MASTER-IFs Connectivity--- // 177 | // ------------------------------ // 178 | for (int i=0; i (sc_gen_unique_name("Master-if")); 185 | master_if[i]->clk(clk); 186 | master_if[i]->rst_n(rst_n); 187 | // Pass the address Map 188 | for (int n=0; naddr_map[n][s](addr_map[n][s]); 191 | 192 | master_if[i]->THIS_ID(NODE_IDS_MASTER[i]); 193 | 194 | // Master-AXI-Side 195 | master_if[i]->ar_in(ar_in[i]); 196 | master_if[i]->r_out(r_out[i]); 197 | 198 | master_if[i]->aw_in(aw_in[i]); 199 | master_if[i]->w_in(w_in[i]); 200 | master_if[i]->b_out(b_out[i]); 201 | // Read-NoC 202 | master_if[i]->rd_flit_out(chan_inj_rreq[col][row]); 203 | master_if[i]->rd_flit_in(chan_ej_rresp[col][row]); 204 | // Write-NoC 205 | master_if[i]->wr_flit_out(chan_inj_wreq[col][row]); 206 | master_if[i]->wr_flit_in(chan_ej_wresp[col][row]); 207 | } 208 | // -o-o-o-o-o-o-o-o-o- // 209 | // -o-o-o-o-o-o-o-o-o- // 210 | 211 | for (int row=0; row (sc_gen_unique_name("Router-resp")); 250 | rtr_resp[col][row]->clk(clk); 251 | rtr_resp[col][row]->rst_n(rst_n); 252 | rtr_resp[col][row]->route_lut[0](route_lut[0][0]); 253 | rtr_resp[col][row]->id_x(rtr_id_x_resp[col]); 254 | rtr_resp[col][row]->id_y(rtr_id_y_resp[row]); 255 | 256 | rtr_resp[col][row]->data_in[0](chan_hor_right_resp[col][row]); 257 | rtr_resp[col][row]->data_out[0](chan_hor_left_resp[col][row]); 258 | 259 | rtr_resp[col][row]->data_in[1](chan_hor_left_resp[col+1][row]); 260 | rtr_resp[col][row]->data_out[1](chan_hor_right_resp[col+1][row]); 261 | 262 | rtr_resp[col][row]->data_in[2](chan_ver_up_resp[col][row]); 263 | rtr_resp[col][row]->data_out[2](chan_ver_down_resp[col][row]); 264 | 265 | rtr_resp[col][row]->data_in[3](chan_ver_down_resp[col][row+1]); 266 | rtr_resp[col][row]->data_out[3](chan_ver_up_resp[col][row+1]); 267 | 268 | rtr_resp[col][row]->data_in[4](chan_inj_rresp[col][row]); 269 | rtr_resp[col][row]->data_out[4](chan_ej_rresp[col][row]); 270 | 271 | rtr_resp[col][row]->data_in[5](chan_inj_wresp[col][row]); 272 | rtr_resp[col][row]->data_out[5](chan_ej_wresp[col][row]); 273 | } 274 | } 275 | }; // End of constructor 276 | 277 | private: 278 | }; // End of SC_MODULE 279 | 280 | #endif // AXI4_TOP_IC_H 281 | -------------------------------------------------------------------------------- /src/include/arbiters.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARBITERS_HEADER__ 2 | #define __ARBITERS_HEADER__ 3 | 4 | enum arb_type {FIXED, MATRIX, ROUND_ROBIN, WEIGHTED_RR, DEFICIT_RR, STRATIFIED_RR, PHASE}; 5 | 6 | 7 | template 8 | class arbiter { 9 | 10 | public: 11 | arbiter(); 12 | unsigned arbitrate(); 13 | }; 14 | 15 | 16 | /* FUNCTION: Fixed Priority Arbiter 17 | * INPUT: Array of bools 18 | * OUTPUT: Unsigned integer pointer to bit position 19 | * ----------------------------------------- 20 | * 21 | */ 22 | template 23 | class arbiter { 24 | private: 25 | 26 | public: 27 | arbiter(){ 28 | } 29 | 30 | unsigned arbitrate( bool inp[SIZE] ) { 31 | unsigned grants; 32 | bool found = false; 33 | 34 | #pragma hls_unroll yes 35 | for (int i=0; i 53 | class arbiter { 54 | private: 55 | unsigned priority; 56 | sc_uint priority_therm; 57 | 58 | public: 59 | arbiter() { 60 | priority = 0; 61 | priority_therm = 0; 62 | } 63 | 64 | //#pragma hls_design ccore 65 | //#pragma hls_ccore_type combinational 66 | unsigned arbitrate(bool inp[SIZE]) { 67 | 68 | bool found_hp = false; 69 | bool found_lp = false; 70 | 71 | unsigned grant_hp = 0; 72 | unsigned grant_lp = 0; 73 | unsigned grants = 0; 74 | 75 | #pragma hls_unroll yes 76 | for (int i = 0; i < SIZE; i++) { 77 | // split arbitration to keep for-loop bounds constant - HLS requirement 78 | // if requests belong to the high priority segment 79 | if (i >= priority) { 80 | if (inp[i] && !found_hp) { 81 | grant_hp = i; 82 | found_hp = true; 83 | } 84 | } else { // requests that belong to low priority 85 | if (inp[i] && !found_lp) { 86 | grant_lp = i; 87 | found_lp = true; 88 | } 89 | } 90 | } 91 | 92 | grants = (found_hp) ? grant_hp : grant_lp; 93 | if (found_hp || found_lp) { 94 | priority = ((grants + 1) == SIZE) ? 0 : (grants + 1); 95 | } 96 | 97 | return grants; 98 | }; 99 | 100 | 101 | //#pragma hls_design ccore 102 | //#pragma hls_ccore_type combinational 103 | //#pragma hls_map_to_operator le_arbiter 104 | bool arbitrate(const sc_uint reqs_i, sc_uint& grants_o) { 105 | sc_uint req_lp = reqs_i & (~priority_therm); 106 | sc_uint req_hp = reqs_i & priority_therm; 107 | 108 | sc_uint grants_lp = ((~req_lp) + 1) & req_lp; 109 | sc_uint grants_hp = ((~req_hp) + 1) & req_hp; 110 | 111 | bool anygrant = reqs_i.or_reduce(); 112 | grants_o = grants_hp.or_reduce() ? grants_hp : grants_lp; 113 | 114 | // OH to THERM 115 | if (anygrant) priority_therm = ~((grants_o << 1) - 1); 116 | 117 | return anygrant; 118 | }; 119 | 120 | 121 | }; 122 | 123 | /* FUNCTION: Matrix Arbiter 124 | * INPUT: Array of bools 125 | * OUTPUT: Unsigned integer pointer to bit position 126 | * ----------------------------------------- 127 | * 128 | */ 129 | template 130 | class arbiter { 131 | private: 132 | bool mat[SIZE][SIZE]; 133 | bool mat_v2[SIZE][SIZE]; 134 | //sc_uint matrix_reg[SIZE]; // a word reflects a vertical line of the matrix 135 | 136 | public: 137 | 138 | arbiter(){ 139 | 140 | #pragma hls_unroll yes 141 | for (int i=0; ij); 146 | 147 | if (i < j) { 148 | mat[i][j] = true; 149 | } 150 | } 151 | } 152 | } 153 | 154 | unsigned arbitrate( bool inp[SIZE] ) { 155 | 156 | bool found = false; 157 | 158 | unsigned grants = 0; 159 | 160 | #pragma hls_unroll yes 161 | for (int i=0; i j) && (mat[i][j] && inp[j])) { 171 | found = false; 172 | } 173 | } 174 | } 175 | if (found) { 176 | grants = i; 177 | } 178 | } 179 | } 180 | 181 | if (found) { 182 | // If a grants is given - change matrix values 183 | #pragma hls_unroll yes 184 | for (int i=0; i grants) { 186 | mat[grants][i] = false; 187 | } else { 188 | if (i < grants) { 189 | mat[i][grants] = true; 190 | } 191 | } 192 | } 193 | } 194 | 195 | return grants; 196 | }; 197 | 198 | bool arbitrate(const sc_uint reqs_i, sc_uint& grants_o) { 199 | #pragma hls_unroll yes 200 | for (int i=0; i vert_line; 202 | #pragma hls_unroll yes 203 | for (int j=0; j 236 | class arbiter { 237 | private: 238 | bool Weights[SIZE][SIZE]; 239 | bool unvisited[SIZE]; 240 | unsigned scanCycle; 241 | 242 | /* FUNCTION: Priority Enforcer 243 | * INPUT: Integer Value 244 | * OUTPUT: Pointer to the least significant 245 | * non zerob bit. 246 | * ----------------------------------------- 247 | * 248 | */ 249 | unsigned priorityEnforcer( unsigned inp ) { 250 | 251 | unsigned pbit=0; 252 | bool found = false; 253 | 254 | #pragma hls_unroll yes 255 | for (int i=0; i0) && !found ) { 257 | found = true; 258 | pbit = i; 259 | } 260 | } 261 | 262 | return pbit; 263 | } 264 | 265 | public: 266 | 267 | arbiter(){ 268 | 269 | scanCycle = 1; 270 | #pragma hls_unroll yes 271 | for (int i=0; i= ((1<= 100/(1<<(j+1))) { 373 | Weights[i][j] = true; 374 | tmp = tmp - 100/(1<<(j+1)); 375 | } else { 376 | Weights[i][j] = false; 377 | } 378 | } 379 | } 380 | } 381 | }; 382 | 383 | 384 | /* FUNCTION: Deficit Round Robin Arbiter 385 | * INPUT: Array of bools 386 | * OUTPUT: Unsigned integer pointer to bit position 387 | * ----------------------------------------- 388 | * 389 | */ 390 | template 391 | class arbiter { 392 | private: 393 | unsigned priority; 394 | 395 | struct flowQueue { 396 | unsigned packetSize[5]; 397 | unsigned maxIndex; 398 | }; 399 | unsigned D[SIZE]; 400 | unsigned Q[SIZE]; 401 | bool ActiveList[SIZE]; 402 | flowQueue F[SIZE]; 403 | 404 | public: 405 | arbiter(){ 406 | 407 | #pragma hls_unroll yes 408 | for (int i=0; i= priority) { 441 | if (F[i].packetSize[0]<=D[i] && ActiveList[i] && !found_hp) { 442 | 443 | grant_hp = i; 444 | found_hp = true; 445 | } 446 | } else { 447 | if (F[i].packetSize[0]<=D[i] && ActiveList[i] && !found_lp) { 448 | 449 | grant_lp = i; 450 | found_lp = true; 451 | } 452 | } 453 | } 454 | 455 | grants = (found_hp) ? grant_hp: grant_lp; 456 | 457 | // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 458 | 459 | // Update Queue and Deficit Counter for flow i 460 | D[grants] = D[grants] - F[grants].packetSize[0]; 461 | #pragma hls_unroll yes 462 | for (int i=0; i<4; i++) { 463 | F[grants].packetSize[i] = F[grants].packetSize[i+1]; 464 | } 465 | F[grants].maxIndex--; 466 | 467 | if ( F[grants].maxIndex == 0 ) { 468 | ActiveList[grants] = false; 469 | D[grants] = 0; 470 | } 471 | 472 | if (found_hp || found_lp && (D[grants] 5 | 6 | #include "./include/flit_axi.h" 7 | #include "./include/duth_fun.h" 8 | #include "./include/arbiters.h" 9 | #include "./include/fifo_queue_oh.h" 10 | 11 | #include "nvhls_connections.h" 12 | 13 | // Select In/Out Ports, the type of flit and the Routing Computation calculation function 14 | // For RC_METHOD: 0-> direct rc 1-> lut, 2-> type, ... , 4-> LUT based routing 15 | // IN_NUM : Number of inputs 16 | // OUT_NUM : Number of inputs 17 | // flit_t : The networks flit type 18 | // DIM_X : X Dimension of a 2-D mesh network. Used in XY routing 19 | // NODES : All possible target nodes of the network. Used in LUT routing 20 | // VCS : Number of Virtual Channels 21 | // BUFF_DEPTH : Input Buffer slots 22 | // RC_METHOD : Routing Computation Algotrithm 23 | // - 0 : Direct RC 24 | // - 1 : Constant RC (for mergers) 25 | // - 2 : Packet type RC (for distinct routing of Writes and reads) 26 | // - 3 : For single stage NoCs 27 | // - 4 : LUT based RC 28 | // - 5 : XY routing with merged RD/WR Req-Resp 29 | 30 | // ARB_C : The arbiter type. Eg MATRIX, ROUND_ROBIN 31 | template< unsigned int IN_NUM, unsigned int OUT_NUM, typename flit_t, int DIM_X=0, int NODES=1, unsigned VCS=2, unsigned BUFF_DEPTH=3, unsigned RC_METHOD=3, arb_type arbiter_t=MATRIX > 32 | SC_MODULE(rtr_vc) { 33 | public: 34 | typedef sc_uint< nvhls::log2_ceil::val > cr_t; 35 | 36 | sc_in_clk clk; 37 | sc_in rst_n; 38 | 39 | sc_in< sc_uint > route_lut[NODES]; 40 | sc_in< sc_uint > id_x{"id_x"}; 41 | sc_in< sc_uint > id_y{"id_y"}; 42 | 43 | // input channels 44 | Connections::In data_in[IN_NUM]; 45 | Connections::Out cr_out[IN_NUM]; 46 | // output channels 47 | Connections::Out data_out[OUT_NUM]; 48 | Connections::In cr_in[OUT_NUM]; 49 | 50 | // Internals 51 | fifo_queue fifo[IN_NUM][VCS]; 52 | bool out_lock[IN_NUM][VCS]; 53 | onehot out_port_locked[IN_NUM][VCS]; 54 | 55 | onehot credits[OUT_NUM][VCS]; 56 | onehot out_available[OUT_NUM]; 57 | arbiter arb_sa1[IN_NUM]; 58 | arbiter arb_sa2[OUT_NUM]; 59 | 60 | // Constructor 61 | SC_HAS_PROCESS(rtr_vc); 62 | 63 | rtr_vc(sc_module_name name_ = "rtr_vc") 64 | : 65 | sc_module(name_) 66 | { 67 | SC_THREAD(router_job); 68 | sensitive << clk.pos(); 69 | async_reset_signal_is(rst_n, false); 70 | } 71 | 72 | 73 | void router_job() { 74 | flit_t vc_hol_flit[IN_NUM][VCS]; 75 | onehot sa1_grants[IN_NUM]; 76 | 77 | flit_t flit_to_xbar[IN_NUM]; 78 | 79 | // The request and grants of the Inputs/Outputs 80 | onehot req_sa2_per_i[IN_NUM]; 81 | onehot req_sa2_per_o[OUT_NUM]; 82 | 83 | onehot gnt_sa2_per_o[OUT_NUM]; 84 | onehot gnt_sa2_per_i[IN_NUM]; 85 | 86 | // Reset per input state 87 | #pragma hls_unroll yes 88 | per_i_rst:for (unsigned char i=0; i(1< out_ready[OUT_NUM]; 130 | 131 | // Read all inputs 132 | #pragma hls_unroll yes 133 | for (int i=0; i req_sa1; 152 | onehot port_req_oh[VCS]; 153 | 154 | // prepare requests of each VC, to content in SA1 155 | #pragma hls_unroll yes 156 | vc_prep : for (unsigned v=0; v req_out_ready_vcs = mux, OUT_NUM>::mux_oh_case(port_req_oh[v], out_ready); 180 | onehot req_out_avail_vcs = mux, OUT_NUM>::mux_oh_case(port_req_oh[v], out_available); 181 | 182 | bool req_out_ready = req_out_ready_vcs[v]; 183 | bool req_out_avail = req_out_avail_vcs[v]; 184 | 185 | req_sa1[v] = (fifo[i][v].valid() && req_out_ready && (out_lock[i][v] || req_out_avail)); 186 | } 187 | 188 | // Arbitrate amonng the VCs and select the winner to access SA2 and output MUX 189 | bool any_sa1_gnt = arb_sa1[i].arbitrate(req_sa1.val, sa1_grants[i].val); 190 | 191 | flit_to_xbar[i] = mux::mux_oh_case(sa1_grants[i], vc_hol_flit[i]); 192 | req_sa2_per_i[i] = mux, VCS>::mux_oh_case(sa1_grants[i], port_req_oh).and_mask(any_sa1_gnt); 193 | } // End of set inputs 194 | 195 | // Per Output arbitration and multiplexing 196 | #pragma hls_unroll yes 197 | outp_route : for (unsigned char j = 0; j < OUT_NUM; ++j) { 198 | // Swap from per input to per output 199 | #pragma hls_unroll yes 200 | for(int i=0; i::mux_oh_case(gnt_sa2_per_o[j], flit_to_xbar); 207 | cr_t selected_vc = selected_flit.get_vc(); 208 | 209 | data_val_out[j] = any_gnt; 210 | data_data_out[j] = selected_flit; 211 | 212 | #pragma hls_unroll yes 213 | for (unsigned v=0; v destination) {return destination.to_uint();}; 285 | // TYPE RC : Used for splitter/mergers. Routes RD to Out==0, and WR to Out==1 286 | inline unsigned char do_rc_type (sc_uint type) {return (type==dnp::PACK_TYPE__RD_REQ || type==dnp::PACK_TYPE__RD_RESP) ? 0 : 1;}; 287 | // Const RC : Used for mergers to always request port #0 288 | inline unsigned char do_rc_const () {return 0;}; 289 | // Const RC : Used for mergers to always request port #0 290 | inline unsigned char do_rc_common (sc_uint destination, sc_uint type) { 291 | if (type==dnp::PACK_TYPE__RD_REQ) return destination.to_uint(); 292 | else if (type==dnp::PACK_TYPE__RD_RESP) return destination.to_uint()-2; 293 | else if (type==dnp::PACK_TYPE__WR_REQ) return destination.to_uint()+2; 294 | else return destination.to_uint(); 295 | }; 296 | inline unsigned char do_rc_lut (sc_uint destination) { 297 | return route_lut[destination.to_uint()].read(); 298 | }; 299 | 300 | inline unsigned char do_rc_xy_merge (sc_uint destination, sc_uint type) { 301 | sc_uint this_id_x = id_x.read(); 302 | sc_uint this_id_y = id_y.read(); 303 | 304 | sc_uint dst_x = destination % DIM_X; 305 | sc_uint dst_y = destination / DIM_X; 306 | 307 | if (dst_x>this_id_x) { 308 | return 1; 309 | } else if (dst_xthis_id_y) { 313 | return 3; 314 | } else if (dst_y 21 | SC_MODULE(ace_home) { 22 | typedef typename ace::ace5 ace5_; 23 | typedef typename ace::ACE_Encoding enc_; 24 | 25 | typedef flit_dnp rreq_flit_t; 26 | typedef flit_dnp rresp_flit_t; 27 | typedef flit_dnp wreq_flit_t; 28 | typedef flit_dnp wresp_flit_t; 29 | typedef flit_dnp creq_flit_t; 30 | typedef flit_dnp cresp_flit_t; 31 | 32 | typedef flit_ack ack_flit_t; 33 | 34 | typedef sc_uint< clog2::val > cnt_phit_rresp_t; 35 | typedef sc_uint< clog2::val > cnt_phit_wresp_t; 36 | 37 | const unsigned char LOG_RD_M_LANES = nvhls::log2_ceil::val; 38 | const unsigned char LOG_WR_M_LANES = nvhls::log2_ceil::val; 39 | 40 | sc_in_clk clk; 41 | sc_in rst_n; 42 | 43 | sc_in < sc_uint<(dnp::ace::AH_W+dnp::ace::AL_W)> > addr_map[cfg::SLAVE_NUM][2]; 44 | 45 | sc_in< sc_uint > THIS_ID; 46 | 47 | // NoC Side Channels 48 | Connections::Out INIT_S1(cache_req); 49 | Connections::In INIT_S1(cache_resp); 50 | 51 | Connections::In INIT_S1(rd_from_master); 52 | Connections::Out INIT_S1(rd_to_master); 53 | 54 | Connections::Out INIT_S1(rd_to_slave); 55 | Connections::In INIT_S1(rd_from_slave); 56 | 57 | Connections::In INIT_S1(wr_from_master); 58 | Connections::Out INIT_S1(wr_to_master); 59 | 60 | Connections::Out INIT_S1(wr_to_slave); 61 | Connections::In INIT_S1(wr_from_slave); 62 | 63 | Connections::In INIT_S1(ack_from_master); 64 | 65 | 66 | // Constructor 67 | SC_HAS_PROCESS(ace_home); 68 | ace_home(sc_module_name name_="ace_home") 69 | : 70 | sc_module (name_) 71 | { 72 | SC_THREAD(req_check); 73 | sensitive << clk.pos(); 74 | async_reset_signal_is(rst_n, false); 75 | } 76 | 77 | 78 | void req_check () { 79 | cache_req.Reset(); 80 | cache_resp.Reset(); 81 | rd_from_master.Reset(); 82 | rd_to_master.Reset(); 83 | rd_to_slave.Reset(); 84 | rd_from_slave.Reset(); 85 | 86 | wr_from_master.Reset(); 87 | wr_to_master.Reset(); 88 | wr_to_slave.Reset(); 89 | wr_from_slave.Reset(); 90 | 91 | //-- End of Reset ---// 92 | 93 | while(1) { 94 | wait(); 95 | // Initial Request 96 | // Wait until a read or write request is received 97 | rreq_flit_t flit_req_rcv; 98 | bool got_new_req = false; 99 | do { 100 | if (!got_new_req) got_new_req = wr_from_master.PopNB(flit_req_rcv); 101 | if (!got_new_req) got_new_req = rd_from_master.PopNB(flit_req_rcv); 102 | wait(); 103 | } while (!got_new_req); 104 | 105 | // Check who initiated the transaction the the type of transaction 106 | ace5_::AddrPayload cur_req; 107 | unsigned initiator = flit_req_rcv.get_src(); 108 | bool is_read = (flit_req_rcv.get_type() == dnp::PACK_TYPE__RD_REQ); 109 | bool is_write = (flit_req_rcv.get_type() == dnp::PACK_TYPE__WR_REQ); 110 | NVHLS_ASSERT_MSG(is_read ^ is_write , "ERROR : Home got request of wrong type."); 111 | flit_req_rcv.get_rd_req(cur_req); 112 | 113 | #ifndef __SYNTHESIS__ 114 | if(is_read) std::cout << "[HOME "<< THIS_ID <<"] Got RD from " << initiator << " : " << cur_req << " @" << sc_time_stamp() << "\n"; 115 | else std::cout << "[HOME "<< THIS_ID <<"] Got WR from " << initiator << " : " << cur_req << " @" << sc_time_stamp() << "\n"; 116 | #endif 117 | NVHLS_ASSERT_MSG(((flit_req_rcv.data[0].to_uint() >> dnp::D_PTR) & ((1<> dnp::ace::cresp::C_RESP_PTR) & ((1<)3) << dnp::ace::wdata::E0_PTR); 186 | } 187 | mem_upd_flit.type = TAIL; 188 | wr_to_slave.Push(mem_upd_flit); 189 | wr_from_slave.Pop(); // ToDo : Maybe error handling 190 | 191 | resp_accum = resp_accum & 0x1B; // Drop Pass Dirty bit as it got writen in Mem 192 | } 193 | 194 | if (is_read) { 195 | bool data_are_expected = req_expects_data(cur_req.snoop, is_read); 196 | // After responces are gathered, either respond to initiating master, or ask Main_mem/LLC 197 | if (data_are_expected) { 198 | // After responces are gathered, either respond to initiating master, or ask Main_mem/LLC 199 | if (!got_data) { // Didn't get data response, thus ask memory 200 | // Didn't get data response, thus ask memory 201 | unsigned mem_to_req = addr_lut(cur_req.addr); 202 | flit_req_rcv.set_network(THIS_ID, mem_to_req, 0, dnp::PACK_TYPE__C_RD_REQ, 0); 203 | 204 | rd_to_slave.Push(flit_req_rcv); 205 | 206 | rd_from_slave.Pop(); // Drop the header 207 | 208 | snoop_resp_data = rd_from_slave.Pop(); 209 | resp_accum = ((snoop_resp_data.data[0] >> dnp::ace::rdata::RE_PTR) & 0x3) | (resp_accum & 0xC); 210 | } else { 211 | resp_accum = resp_accum & 0xE; // MASK WasUnique and HasData. Easily creating the R resp from CR resp 212 | } 213 | #pragma hls_unroll yes 214 | for (int i=0; i)resp_accum) << dnp::ace::rdata::RE_PTR); 216 | } 217 | } else { 218 | // Master does not expect Data, thus build empty data+response And write any data received to Mem 219 | resp_accum = resp_accum & 0xE; // MASK WasUnique and HasData. Easily creating the R resp from CR resp 220 | #pragma hls_unroll yes 221 | for (int i=0; i) resp_accum) << dnp::ace::rdata::RE_PTR); 223 | } 224 | snoop_resp_data.type = TAIL; 225 | } 226 | // Build and send reponse packet 227 | rresp_flit_t flit_resp_to_init; 228 | flit_resp_to_init.type = HEAD; 229 | flit_resp_to_init.set_network(THIS_ID, initiator, 0, dnp::PACK_TYPE__C_RD_RESP, 0); 230 | flit_resp_to_init.set_rd_resp(cur_req); 231 | 232 | rd_to_master.Push(flit_resp_to_init); // Send Header flit 233 | rd_to_master.Push(snoop_resp_data); // Send Data. IsSHared and IsDirty are expected to be 0 234 | } else { 235 | // Init transaction is a Write thus resolbe Mem to write and send the Write transaction 236 | unsigned mem_to_write = addr_lut(cur_req.addr); 237 | flit_req_rcv.set_network(THIS_ID, mem_to_write, 0, dnp::PACK_TYPE__C_WR_REQ, 0); 238 | wr_to_slave.Push(flit_req_rcv); // Send Head 239 | 240 | wreq_flit_t data_to_update; 241 | while(!wr_from_master.PopNB(data_to_update)) { 242 | wait(); 243 | } 244 | wr_to_slave.Push(data_to_update); 245 | 246 | // transfer the response to the init Master 247 | wresp_flit_t mv_wr_resp = wr_from_slave.Pop(); 248 | mv_wr_resp.set_src(THIS_ID); // Set the HOME src to receive the response 249 | mv_wr_resp.set_dst(initiator); // Set the initiator as a recipient src to receive the response 250 | wr_to_master.Push(mv_wr_resp); 251 | } 252 | 253 | // Wait for the final ack from the Init Master that signifies that the cache has been completed the transaction 254 | // Only a Full Master responds with an Ack 255 | if (init_is_full) { 256 | ack_flit_t rcv_ack = ack_from_master.Pop(); 257 | NVHLS_ASSERT_MSG( (rcv_ack.is_rack()&&is_read) || (rcv_ack.is_wack()&&(!is_read)), "ACK does not match the responce (i.e. RD/WR)"); 258 | 259 | #ifndef __SYNTHESIS__ 260 | if(is_read) std::cout << "[HOME "<< THIS_ID <<"] Got RD ACK from " << rcv_ack.get_src() << " : " << cur_req << " @" << sc_time_stamp() << "\n"; 261 | else std::cout << "[HOME "<< THIS_ID <<"] Got WR AK from " << rcv_ack.get_src() << " : " << cur_req << " @" << sc_time_stamp() << "\n"; 262 | #endif 263 | } 264 | 265 | 266 | } // End of while(1) 267 | }; // End of HOME Node 268 | 269 | // Transactions that do not accept Dirty data, thus the interconnects is responsible for to handle them 270 | inline bool req_denies_dirty(NVUINTW(enc_::ARSNOOP::_WIDTH) &request_in, bool is_read ) { 271 | if (is_read) { 272 | if ((request_in == enc_::ARSNOOP::RD_ONCE) || 273 | (request_in == enc_::ARSNOOP::RD_CLEAN) || 274 | (request_in == enc_::ARSNOOP::RD_NOT_SHARED_DIRTY) || 275 | (request_in == enc_::ARSNOOP::CLEAN_UNIQUE) || 276 | (request_in == enc_::ARSNOOP::MAKE_UNIQUE) || 277 | (request_in == enc_::ARSNOOP::CLEAN_SHARED) || 278 | (request_in == enc_::ARSNOOP::CLEAN_INVALID) || 279 | (request_in == enc_::ARSNOOP::MAKE_INVALID) ) 280 | { 281 | return true; 282 | } 283 | } else { // request is a write, thus any dirty must be sent to Mem 284 | return true; 285 | } 286 | return false; 287 | }; 288 | 289 | // When data are required, HOME must access Mem when all snoops where missed 290 | inline bool req_expects_data(NVUINTW(enc_::ARSNOOP::_WIDTH) &request_in, bool is_read ) { 291 | if (is_read) { 292 | if ((request_in == enc_::ARSNOOP::RD_ONCE) || 293 | (request_in == enc_::ARSNOOP::RD_CLEAN) || 294 | (request_in == enc_::ARSNOOP::RD_NOT_SHARED_DIRTY) || 295 | (request_in == enc_::ARSNOOP::RD_SHARED) || 296 | (request_in == enc_::ARSNOOP::RD_UNIQUE) ) 297 | { 298 | return true; 299 | } 300 | } 301 | return false; 302 | }; 303 | 304 | // Memory map resolving 305 | inline unsigned char addr_lut(const ace5_::Addr addr) { 306 | for (int i=0; i<2; ++i) { 307 | if (addr>=addr_map[i][0].read() && addr <= addr_map[i][1].read()) return i; 308 | } 309 | return 0; // Or send 404 310 | }; 311 | }; // End of Home module 312 | 313 | #endif // _ACE_HOME_H_ 314 | -------------------------------------------------------------------------------- /src/include/flit_ace.h: -------------------------------------------------------------------------------- 1 | #ifndef __FLIT_DNP_H__ 2 | #define __FLIT_DNP_H__ 3 | 4 | #include "systemc.h" 5 | #include "nvhls_connections.h" 6 | 7 | #include "./dnp_ace_v0.h" 8 | 9 | #ifndef __SYNTHESIS__ 10 | #include 11 | #include 12 | #endif 13 | 14 | enum FLIT_TYPE {HEAD=0 , BODY=1, TAIL=3, SINGLE=2}; 15 | 16 | template 17 | struct flit_dnp { 18 | sc_uint<2> type; 19 | //sc_uint<32> dbg_id; 20 | sc_uint data[PHIT_NUM]; 21 | 22 | static const int width = 2+(PHIT_NUM*dnp::PHIT_W); // Matchlib Marshaller requirement 23 | 24 | // helping functions to retrieve flit info (e.g. flit type, source, destination) 25 | inline bool performs_rc() { return ((type == HEAD) || (type == SINGLE)); } 26 | inline bool resets_states() { return (type == TAIL); } 27 | 28 | inline bool is_head() {return (type==HEAD);}; 29 | inline bool is_tail() {return (type==TAIL);}; 30 | inline bool is_body() {return (type==BODY);}; 31 | inline bool is_single() {return (type==SINGLE);}; 32 | 33 | // DNP fields set/getters 34 | inline sc_uint get_dst() const {return ((data[0] >> dnp::D_PTR) & ((1< get_src() const {return ((data[0] >> dnp::S_PTR) & ((1< get_type() const {return ((data[0] >> dnp::T_PTR) & ((1< get_vc() const {return ((data[0] >> dnp::V_PTR) & ((1< get_qos() const {return ((data[0] >> dnp::Q_PTR) & ((1< dst ) { data[0] = (data[0].range(dnp::PHIT_W-1, dnp::D_PTR+dnp::D_W) << (dnp::D_PTR+dnp::D_W)) | 41 | (dst << dnp::D_PTR) | 42 | (data[0].range(dnp::D_PTR-1, 0)); 43 | }; 44 | inline void set_src(sc_uint src ) { data[0] = (data[0].range(dnp::PHIT_W-1, dnp::S_PTR+dnp::S_W) << (dnp::S_PTR+dnp::S_W)) | 45 | (src << dnp::S_PTR) | 46 | (data[0].range(dnp::S_PTR-1, 0)); 47 | }; 48 | inline void set_type(sc_uint type) { data[0] = (data[0].range(dnp::PHIT_W-1, dnp::T_PTR+dnp::T_W) << (dnp::T_PTR+dnp::T_W)) | 49 | (type << dnp::T_PTR) | 50 | (data[0].range(dnp::T_PTR-1, 0)); 51 | }; 52 | inline void set_vc(sc_uint vc ) { data[0] = (data[0].range(dnp::PHIT_W-1, dnp::V_PTR+dnp::V_W) << (dnp::V_PTR+dnp::V_W)) | 53 | (vc << dnp::V_PTR) ; 54 | //(data[0].range(dnp::V_PTR-1, 0)); 55 | }; 56 | inline void set_qos(sc_uint qos ) { data[0] = (data[0].range(dnp::PHIT_W-1, dnp::Q_PTR+dnp::Q_W) << (dnp::Q_PTR+dnp::Q_W)) | 57 | (qos << dnp::Q_PTR) | 58 | (data[0].range(dnp::Q_PTR-1, 0)); 59 | }; 60 | inline void set_network( 61 | sc_uint src, 62 | sc_uint dst, 63 | sc_uint vc, 64 | sc_uint type, 65 | sc_uint qos 66 | ) { 67 | data[0] = (data[0].range(dnp::PHIT_W-1, dnp::T_PTR+dnp::T_W) << (dnp::T_PTR+dnp::T_W)) | 68 | (type << dnp::T_PTR) | 69 | (qos << dnp::Q_PTR) | 70 | (dst << dnp::D_PTR) | 71 | (src << dnp::S_PTR) | 72 | (vc << dnp::V_PTR) ; 73 | }; 74 | 75 | template 76 | inline void set_rd_req (const T& rd_req) { 77 | this->data[0] = ((sc_uint) rd_req.snoop << dnp::ace::req::SNP_PTR) | 78 | ((sc_uint) rd_req.domain << dnp::ace::req::DOM_PTR) | 79 | ((sc_uint) rd_req.id << dnp::ace::req::ID_PTR) | 80 | (sc_uint) this->data[0].range(dnp::T_PTR+dnp::T_W-1, 0); // Keep the network portion unaffected 81 | 82 | this->data[1] = ((sc_uint) rd_req.len << dnp::ace::req::LE_PTR) | 83 | ((sc_uint)(rd_req.addr & 0xffff) << dnp::ace::req::AL_PTR) ; 84 | 85 | this->data[2] = ((sc_uint) rd_req.unique << dnp::ace::req::UNQ_PTR ) | 86 | ((sc_uint) rd_req.barrier << dnp::ace::req::BAR_PTR ) | 87 | ((sc_uint) rd_req.burst << dnp::ace::req::BU_PTR ) | 88 | ((sc_uint) rd_req.size << dnp::ace::req::SZ_PTR ) | 89 | ((sc_uint)(rd_req.addr >> dnp::ace::AL_W) << dnp::ace::req::AH_PTR) ; 90 | }; 91 | 92 | template 93 | inline void set_wr_req (const T& wr_req) {this->set_rd_req(wr_req);}; 94 | 95 | template 96 | inline void set_snoop_req (const T& snoop_req) { 97 | this->data[1] = ((sc_uint)snoop_req.snoop << dnp::ace::creq::SNP_PTR) | 98 | ((sc_uint)(snoop_req.addr & 0xffff) << dnp::ace::creq::AL_PTR) ; 99 | 100 | this->data[2] = ((sc_uint) snoop_req.prot << dnp::ace::creq::C_PROT_PTR ) | 101 | ((sc_uint)(snoop_req.addr >> dnp::ace::AL_W) << dnp::ace::creq::AH_PTR) ; 102 | }; 103 | 104 | template 105 | inline void set_rd_resp (const T& rd_req) { 106 | this->data[0] = ((sc_uint) rd_req.burst << dnp::ace::rresp::BU_PTR) | 107 | ((sc_uint) rd_req.id << dnp::ace::rresp::ID_PTR) | 108 | (sc_uint) this->data[0].range(dnp::T_PTR+dnp::T_W-1, 0); // Keep the network portion unaffected 109 | 110 | this->data[1] = ((sc_uint) (rd_req.addr & ((1<) rd_req.len << dnp::ace::rresp::LE_PTR ) | 112 | ((sc_uint) rd_req.size << dnp::ace::rresp::SZ_PTR) ; 113 | }; 114 | 115 | template 116 | inline void get_rd_req (T& rd_req) const { 117 | rd_req.id = (this->data[0] >> dnp::ace::req::ID_PTR) & ((1<data[1] >> dnp::ace::req::LE_PTR) & ((1<data[2] >> dnp::ace::req::SZ_PTR) & ((1<data[2] >> dnp::ace::req::BU_PTR) & ((1<data[2]>>dnp::ace::req::AH_PTR) & ((1<data[1]>>dnp::ace::req::AL_PTR) & ((1<data[0] >> dnp::ace::req::SNP_PTR) & ((1<data[0] >> dnp::ace::req::DOM_PTR) & ((1<data[2] >> dnp::ace::req::BAR_PTR) & ((1< 133 | inline void get_wr_req (const T& wr_req) const {this->get_rd_req(wr_req);}; 134 | 135 | template 136 | inline void get_snoop_req (T& snoop_req) const { 137 | snoop_req.snoop = (this->data[1] >> dnp::ace::creq::SNP_PTR) & ((1<data[2] >> dnp::ace::creq::C_PROT_PTR) & ((1<data[2]>>dnp::ace::creq::AH_PTR) & ((1<data[1]>>dnp::ace::creq::AL_PTR) & ((1<type; 170 | //dbg_id = rhs->dbg_id; 171 | #pragma hls_unroll yes 172 | for(int i=0; idata[i]; 173 | 174 | return *this; 175 | }; 176 | 177 | inline bool operator==(const flit_dnp& rhs) const { 178 | bool eq = (rhs.type == type); 179 | for(int i=0; i mask = 0; 210 | 211 | #pragma hls_unroll yes 212 | for(int j=0; j=0; --i) os << std::hex << flit_tmp.data[i].to_uint() << "_"; 239 | 240 | #ifdef SYSTEMC_INCLUDED 241 | os << std::dec << "@" << sc_time_stamp(); 242 | #else 243 | os << std::dec << "@" << "no-timed"; 244 | #endif 245 | 246 | return os; 247 | } 248 | //#endif 249 | 250 | #ifdef SYSTEMC_INCLUDED 251 | // Only for SystemC 252 | inline friend void sc_trace(sc_trace_file* tf, const flit_dnp& flit, const std::string& name) { 253 | sc_trace(tf, flit.type, name + ".type"); 254 | //sc_trace(tf, flit.dbg_id, name + ".dbg_id"); 255 | for(int i=0; i 262 | void Marshall(Marshaller& m) { 263 | //m& dbg_id; 264 | m& type; 265 | #pragma hls_unroll yes 266 | //for(int i=0; i=0; --i) m& data[i]; 268 | //m& src; 269 | //m& dst; 270 | }; 271 | 272 | }; 273 | 274 | 275 | struct flit_ack { 276 | sc_uint<2> type; 277 | sc_uint src; 278 | sc_uint dst; 279 | sc_uint<1> rack; 280 | sc_uint<1> wack; 281 | 282 | static const int width = 2+dnp::S_W+dnp::D_W+1+1; // Matchlib Marshaller requirement 283 | 284 | flit_ack(unsigned type_=0, unsigned src_=0, unsigned dst_=0, bool rack_=0, bool wack_=0) : 285 | type(type_), src(src_), dst(dst_), rack(rack_), wack(wack_) 286 | {}; 287 | 288 | // helping functions to retrieve flit info (e.g. flit type, source, destination) 289 | inline bool performs_rc() { return ((type == HEAD) || (type == SINGLE)); } 290 | inline bool resets_states() { return (type == TAIL); } 291 | 292 | inline bool is_head() {return (type==HEAD);}; 293 | inline bool is_tail() {return (type==TAIL);}; 294 | inline bool is_body() {return (type==BODY);}; 295 | inline bool is_single() {return (type==SINGLE);}; 296 | 297 | inline sc_uint get_dst() const {return dst;}; 298 | inline sc_uint get_src() const {return src;}; 299 | inline sc_uint get_type() const {return 0;}; 300 | 301 | inline bool is_rack() const {return rack;}; 302 | inline bool is_wack() const {return wack;}; 303 | 304 | 305 | // Non synthesizable functions. (printing, tracing) 306 | static std::string type_in_str(const flit_ack& flit_in) { 307 | if (flit_in.type==HEAD) return "H"; 308 | else if(flit_in.type==BODY) return "B"; 309 | else if(flit_in.type==TAIL) return "T"; 310 | else if(flit_in.type==SINGLE) return "S"; 311 | else return "X"; 312 | } 313 | 314 | inline friend std::ostream& operator << ( std::ostream& os, const flit_ack& flit_tmp ) { 315 | os << flit_ack::type_in_str(flit_tmp) <<"s" << flit_tmp.get_src() << "d" << flit_tmp.get_dst() << " rack: " << flit_tmp.is_rack() << " wack: " << flit_tmp.is_wack(); 316 | #ifdef SYSTEMC_INCLUDED 317 | os << std::dec << "@" << sc_time_stamp(); 318 | #else 319 | os << std::dec << "@" << "no-timed"; 320 | #endif 321 | 322 | return os; 323 | } 324 | 325 | #ifdef SYSTEMC_INCLUDED 326 | // Only for SystemC 327 | inline friend void sc_trace(sc_trace_file* tf, const flit_ack& flit, const std::string& name) { 328 | sc_trace(tf, flit.type, name + ".type"); 329 | sc_trace(tf, flit.src, name + ".src"); 330 | sc_trace(tf, flit.dst, name + ".dst"); 331 | 332 | sc_trace(tf, flit.rack, name + ".rack"); 333 | sc_trace(tf, flit.wack, name + ".wack"); 334 | } 335 | #endif 336 | 337 | // Matchlib Marshaller requirement 338 | template 339 | void Marshall(Marshaller& m) { 340 | m& type; 341 | m& src; 342 | m& dst; 343 | m& rack; 344 | m& wack; 345 | }; 346 | }; 347 | 348 | 349 | 350 | 351 | #endif // __FLIT_DNP_H__ 352 | 353 | -------------------------------------------------------------------------------- /src/include/ace.h: -------------------------------------------------------------------------------- 1 | #ifndef _AXI_ACE_H_ 2 | #define _AXI_ACE_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | #include "./axi_for_ace.h" 15 | 16 | /** 17 | * \brief The axi namespace contains classes and definitions related to the ACE standard. 18 | * \ingroup ACE 19 | */ 20 | namespace ace { 21 | 22 | /** 23 | * \brief The base ACE class extending AXI with cache coherence. 24 | * \ingroup ACE 25 | * 26 | * \tparam Cfg A valid AXI config. 27 | * 28 | * \par Overview 29 | * axi4 defines the AXI base class. Based on the provided Cfg, the bitwidths of 30 | * the various fields of the AXI specification are defined, and classes and 31 | * convenience functions can be used to instantiate AXI Connections, wire them 32 | * together, and use them to implement the AXI protocol. 33 | * - Each AXI signal is defined as a UIntOrEmpty of an appropriate width, allowing 34 | * for the presence of 0-width fields when they can be elided entirely. 35 | * - If useWriteResponses = 0, the B channel is not removed entirely (for 36 | * implementation convenience), but is reduced to minimum width. 37 | * - All AW and AR fields are identical, and are combined into a common 38 | * AddrPayload type. 39 | * 40 | */ 41 | 42 | template 43 | class ace5 : public ace::axi4 { 44 | public: 45 | 46 | enum { 47 | C_ADDR_WIDTH = Cfg::addrWidth, 48 | C_SNOOP_WIDTH = 4, 49 | C_PROT_WIDTH = 3, 50 | C_RESP_WIDTH = 5, 51 | C_CACHE_WIDTH = Cfg::CacheLineWidth, 52 | C_DATA_CHAN_WIDTH = Cfg::CacheLineWidth, 53 | }; 54 | 55 | typedef typename ace::axi4::Addr Addr; 56 | 57 | /** 58 | * \brief A struct for ACE Snoop Address channel fields 59 | */ 60 | struct AC : public nvhls_message { 61 | typedef NVUINTW(C_SNOOP_WIDTH) Snoop; 62 | typedef typename nvhls::UIntOrEmpty::T Prot; 63 | 64 | Addr addr; 65 | Snoop snoop; 66 | Prot prot; 67 | 68 | static const unsigned int width = C_ADDR_WIDTH + C_SNOOP_WIDTH + C_PROT_WIDTH; 69 | 70 | AC () { 71 | addr = 0; 72 | snoop = 0; 73 | if(C_PROT_WIDTH > 0) prot = 0; 74 | } 75 | 76 | template 77 | void Marshall(Marshaller &m) { 78 | m &addr; 79 | m &snoop; 80 | m &prot; 81 | } 82 | 83 | #ifdef CONNECTIONS_SIM_ONLY 84 | inline friend void sc_trace(sc_trace_file *tf, const AC& v, const std::string& NAME ) { 85 | sc_trace(tf,v.addr, NAME + ".addr"); 86 | sc_trace(tf,v.snoop, NAME + ".snoop"); 87 | if(C_PROT_WIDTH > 0) 88 | sc_trace(tf,v.prot, NAME + ".prot"); 89 | } 90 | 91 | inline friend std::ostream& operator<<(ostream& os, const AC& rhs) 92 | { 93 | #ifdef LOG_MSG_WIDTHS 94 | os << std::dec; 95 | os << "addr:" << rhs.addr.width << " "; 96 | os << "snoop:" << rhs.snoop.width << " "; 97 | if(C_PROT_WIDTH > 0) 98 | os << "prot:" << rhs.prot.width << " "; 99 | #else 100 | os << std::hex; 101 | os << "Addr:" << rhs.addr << " "; 102 | os << "Snp:" << rhs.snoop << " "; 103 | if(C_PROT_WIDTH > 0) 104 | os << "Prot:" << rhs.prot << " "; 105 | os << std::dec; 106 | #endif 107 | return os; 108 | } 109 | #endif 110 | }; 111 | 112 | 113 | /** 114 | * \brief A struct for ACE Snoop Response channel fields 115 | */ 116 | struct CR : public nvhls_message { 117 | typedef NVUINTW(C_RESP_WIDTH) Resp; 118 | 119 | Resp resp; 120 | 121 | static const unsigned int width = C_RESP_WIDTH; 122 | 123 | CR () { 124 | resp = 0; 125 | } 126 | 127 | template 128 | void Marshall(Marshaller &m) { 129 | m &resp; 130 | } 131 | 132 | #ifdef CONNECTIONS_SIM_ONLY 133 | inline friend void sc_trace(sc_trace_file *tf, const CR& v, const std::string& NAME ) { 134 | sc_trace(tf,v.resp, NAME + ".resp"); 135 | } 136 | 137 | inline friend std::ostream& operator<<(ostream& os, const CR& rhs) 138 | { 139 | #ifdef LOG_MSG_WIDTHS 140 | os << std::dec; 141 | os << "Resp:" << rhs.resp.width << " "; 142 | #else 143 | os << std::hex; 144 | os << "Resp:" << rhs.resp << " "; 145 | os << std::dec; 146 | #endif 147 | return os; 148 | } 149 | #endif 150 | }; 151 | 152 | 153 | /** 154 | * \brief A struct for ACE Snoop Data channel fields 155 | */ 156 | struct CD : public nvhls_message { 157 | typedef NVUINTW(C_DATA_CHAN_WIDTH) Data; 158 | typedef NVUINTW(1) Last; 159 | 160 | Data data; 161 | Last last; 162 | 163 | static const unsigned int width = C_DATA_CHAN_WIDTH + 1; 164 | 165 | CD () { 166 | data = 0; 167 | last = 0; 168 | } 169 | 170 | template 171 | void Marshall(Marshaller &m) { 172 | m &data; 173 | m &last; 174 | } 175 | 176 | #ifdef CONNECTIONS_SIM_ONLY 177 | inline friend void sc_trace(sc_trace_file *tf, const CD& v, const std::string& NAME ) { 178 | sc_trace(tf,v.data, NAME + ".data"); 179 | sc_trace(tf,v.last, NAME + ".last"); 180 | } 181 | 182 | inline friend std::ostream& operator<<(ostream& os, const CD& rhs) 183 | { 184 | #ifdef LOG_MSG_WIDTHS 185 | os << std::dec; 186 | os << "data:" << rhs.data.width << " "; 187 | os << "last:" << rhs.last.width << " "; 188 | #else 189 | os << std::hex; 190 | os << "Data:" << rhs.data << " "; 191 | os << "last:" << rhs.last << " "; 192 | os << std::dec; 193 | #endif 194 | return os; 195 | } 196 | #endif 197 | }; 198 | 199 | /** 200 | * \brief A struct for ACE Snoop ACK channels 201 | */ 202 | struct RACK : public nvhls_message { 203 | typedef NVUINTW(1) Rack; 204 | Rack rack; 205 | 206 | static const unsigned int width = 1; 207 | 208 | RACK () { 209 | rack = 0; 210 | } 211 | 212 | template 213 | void Marshall(Marshaller &m) { 214 | m &rack; 215 | } 216 | 217 | #ifdef CONNECTIONS_SIM_ONLY 218 | inline friend void sc_trace(sc_trace_file *tf, const RACK& v, const std::string& NAME ) { 219 | sc_trace(tf,v.rack, NAME + ".rack"); 220 | } 221 | 222 | inline friend std::ostream& operator<<(ostream& os, const RACK& rhs) 223 | { 224 | #ifdef LOG_MSG_WIDTHS 225 | os << std::dec; 226 | os << "rack:" << rhs.rack.width << " "; 227 | #else 228 | os << std::dec; 229 | os << "Rack:" << rhs.rack << " "; 230 | #endif 231 | return os; 232 | } 233 | #endif 234 | }; 235 | 236 | struct WACK : public nvhls_message { 237 | typedef NVUINTW(1) Wack; 238 | Wack wack; 239 | 240 | static const unsigned int width = 1; 241 | 242 | WACK () { 243 | wack = 0; 244 | } 245 | 246 | template 247 | void Marshall(Marshaller &m) { 248 | m &wack; 249 | } 250 | 251 | #ifdef CONNECTIONS_SIM_ONLY 252 | inline friend void sc_trace(sc_trace_file *tf, const WACK& v, const std::string& NAME ) { 253 | sc_trace(tf,v.wack, NAME + ".wack"); 254 | } 255 | 256 | inline friend std::ostream& operator<<(ostream& os, const WACK& rhs) 257 | { 258 | #ifdef LOG_MSG_WIDTHS 259 | os << std::dec; 260 | os << "wack:" << rhs.wack.width << " "; 261 | #else 262 | os << std::dec; 263 | os << "Wack:" << rhs.wack << " "; 264 | #endif 265 | return os; 266 | } 267 | #endif 268 | }; 269 | 270 | 271 | 272 | 273 | /** 274 | * \brief The ACE extension channels. 275 | * 276 | * Each Connections implementation contains two ready-valid interfaces, 277 | * AC for snoop address, CR for snoop response, CD for snoop data, ACK for acknowledgment 278 | */ 279 | class cache { 280 | public: 281 | /** 282 | * \brief The ACE cache channel, used for connecting Caching components. 283 | */ 284 | template 285 | class chan { 286 | public: 287 | typedef Connections::Combinational ACChan; 288 | typedef Connections::Combinational CRhan; 289 | typedef Connections::Combinational CDChan; 290 | //typedef Connections::Combinational ACKChan; 291 | 292 | ACChan ac; // IC to master (DIR to IC) 293 | CRhan cr; // master to IC (IC to DIR) 294 | CDChan cd; // master to IC (IC to DIR) 295 | //ACKChan ack; // Master to IC (IC to DIR???) 296 | 297 | chan(const char *name) 298 | : 299 | ac(nvhls_concat(name, "_ac")), 300 | cr(nvhls_concat(name, "_cr")), 301 | cd(nvhls_concat(name, "_cd")) 302 | //ack(nvhls_concat(name, "_ack")) 303 | {}; 304 | 305 | // TODO: Implement AXI protocol checker 306 | }; // read::chan 307 | 308 | /** 309 | * \brief The ACE cache master/IC port. This port has AC Snoop request as input and CR-CD-ACK channels as output. 310 | */ 311 | template 312 | class master { 313 | public: 314 | typedef Connections::In ACPort; 315 | typedef Connections::Out CRPort; 316 | typedef Connections::Out CDPort; 317 | //typedef Connections::Out ACKPort; 318 | 319 | ACPort ac; 320 | CRPort cr; 321 | CDPort cd; 322 | //ACKPort ack; 323 | 324 | master(const char *name) 325 | : 326 | ac(nvhls_concat(name, "_ac")), 327 | cr(nvhls_concat(name, "_cr")), 328 | cd(nvhls_concat(name, "_cd")) 329 | //ack(nvhls_concat(name, "_ack")) 330 | {} 331 | 332 | void reset() { 333 | ac.Reset(); 334 | cr.Reset(); 335 | cd.Reset(); 336 | //ack.Reset(); 337 | } 338 | 339 | AC snp_rcv() { return ac.Pop(); } 340 | bool snp_rcv_nb(AC &addr) { return ac.PopNB(addr); } 341 | 342 | void snp_resp(const CR &resp) { cr.Push(resp); } 343 | bool snp_resp_nb(const CR &resp) { return cr.PushNB(resp); } 344 | 345 | void snp_data(const CD &data) { cd.Push(data); } 346 | bool snp_data_nb(const CD &data) { return cd.PushNB(data); } 347 | 348 | //void snp_ack(const ACK &ack_r) { ack.Push(ack_r); } 349 | //bool snp_ack_nb(const ACK &ack_r) { return ack.PushNB(ack_r); } 350 | 351 | template 352 | void operator()(C &c) { 353 | ac(c.ac); 354 | cr(c.cr); 355 | cd(c.cd); 356 | //ack(c.ack); 357 | } 358 | }; // cache::master 359 | 360 | /** 361 | * \brief The ACE cache master/IC port. This port has AC Snoop request as output and CR-CD-ACK channels as input. 362 | */ 363 | template 364 | class dir { 365 | public: 366 | typedef Connections::Out ACPort; 367 | typedef Connections::In CRPort; 368 | typedef Connections::In CDPort; 369 | //typedef Connections::In ACKPort; 370 | 371 | ACPort ac; 372 | CRPort cr; 373 | CDPort cd; 374 | //ACKPort ack; 375 | 376 | dir(const char *name) 377 | : 378 | ac(nvhls_concat(name, "_ac")), 379 | cr(nvhls_concat(name, "_cr")), 380 | cd(nvhls_concat(name, "_cd")) 381 | //ack(nvhls_concat(name, "_ack")) 382 | {} 383 | 384 | void reset() { 385 | ac.Reset(); 386 | cr.Reset(); 387 | cd.Reset(); 388 | //ack.Reset(); 389 | } 390 | 391 | void snp_snd(AC &addr) { ac.Push(addr); } 392 | bool snp_snd_nb(AC &addr) { return ac.PushNB(addr); } 393 | 394 | CR snp_resp_rcv() { return cr.Pop(); } 395 | bool snp_resp_rcv_nb(const CR &resp) { return cr.PopNB(resp); } 396 | 397 | CD snp_data_rcv( ) { return cd.Pop(); } 398 | bool snp_data_rcv_nb(CD &data) { return cd.PopNB(data); } 399 | 400 | //ACK snp_ack_rcv( ) { return ack.Pop(); } 401 | //bool snp_ack_rcv_nb(ACK &ack_r) { return ack.PopNB(ack_r); } 402 | 403 | template 404 | void operator()(C &c) { 405 | ac(c.ac); 406 | cr(c.cr); 407 | cd(c.cd); 408 | //ack(c.ack); 409 | } 410 | }; // cache::dir 411 | }; // cache 412 | }; // ace5 413 | 414 | /** 415 | * \brief Hardcoded values associated with the ACE standard. 416 | * \ingroup ACE 417 | * 418 | * \par 419 | * These enumerated values are defined by the ACE standard and should not be modified. 420 | * 421 | */ 422 | class ACE_Encoding : public axi::AXI4_Encoding { 423 | public: 424 | /** 425 | * \brief Hardcoded values for the AxDOMAIN field. 426 | */ 427 | class AxDOMAIN { 428 | public: 429 | enum { 430 | _WIDTH = 2, // bits 431 | 432 | NON_SHARE = 0, 433 | INNER_SHARE = 1, 434 | OUTER_SHARE = 2, 435 | SYSTEM_SHARE = 3, 436 | }; 437 | }; // Domain 438 | 439 | class ARSNOOP { 440 | public: 441 | enum { 442 | _WIDTH = 4, // bits 443 | // Np-Snoop 444 | 445 | // Coherent 446 | RD_ONCE = 0x0, // Or Read NoSnoop if Domain is Non-Shared or System 447 | RD_SHARED = 0x1, 448 | RD_CLEAN = 0x2, 449 | RD_NOT_SHARED_DIRTY = 0x3, 450 | RD_UNIQUE = 0x7, 451 | CLEAN_UNIQUE = 0xB, 452 | MAKE_UNIQUE = 0xC, 453 | // Cache maintenance 454 | CLEAN_SHARED = 0x8, 455 | CLEAN_INVALID = 0x9, 456 | MAKE_INVALID = 0xD, 457 | }; 458 | }; // ARSNOOP 459 | 460 | class AWSNOOP { 461 | public: 462 | enum { 463 | _WIDTH = 3, // bits 464 | // Np-Snoop 465 | // Coherent 466 | WR_UNIQUE = 0, // Or Write NoSnoop id DOMAIN is Not-Shared or System 467 | WR_LINE_UNIQUE = 1, 468 | // Memory update 469 | WR_CLEAN = 2, 470 | WR_BACK = 3, // No-Snoop 471 | EVICT = 4, // No-Snoop 472 | WR_EVICT = 5, // No-Snoop 473 | }; 474 | }; // AWSNOOP 475 | 476 | class ACSNOOP { 477 | public: 478 | enum { 479 | _WIDTH = 4, // bits 480 | 481 | RD_ONCE = 0x0, 482 | RD_SHARED = 0x1, 483 | RD_CLEAN = 0x2, 484 | RD_NOT_SHARED_DIRTY = 0x3, 485 | RD_UNIQUE = 0x7, 486 | CLEAN_SHARED = 0x8, 487 | CLEAN_INVALID = 0x9, 488 | MAKE_INVALID = 0xD, 489 | DVM_COMPLETE = 0xE, 490 | DVM_MESSAGE = 0xF, 491 | }; 492 | }; // AWSNOOP 493 | }; // End of ACE_Encoding 494 | 495 | inline NVUINTW(ACE_Encoding::ACSNOOP::_WIDTH) rd_2_snoop (NVUINTW(ACE_Encoding::ARSNOOP::_WIDTH) &request_in) { 496 | if (request_in == ACE_Encoding::ARSNOOP::RD_ONCE) // 0 -> 0 497 | return ACE_Encoding::ACSNOOP::RD_ONCE; 498 | else if (request_in == ACE_Encoding::ARSNOOP::RD_CLEAN) // 2 -> 2 499 | return ACE_Encoding::ACSNOOP::RD_CLEAN; 500 | else if (request_in == ACE_Encoding::ARSNOOP::RD_NOT_SHARED_DIRTY) // 3 -> 3 501 | return ACE_Encoding::ACSNOOP::RD_NOT_SHARED_DIRTY; 502 | else if (request_in == ACE_Encoding::ARSNOOP::RD_SHARED) // 1-> 1 503 | return ACE_Encoding::ACSNOOP::RD_SHARED; 504 | else if (request_in == ACE_Encoding::ARSNOOP::RD_UNIQUE) // 7 -> 7 505 | return ACE_Encoding::ACSNOOP::RD_UNIQUE; 506 | else if ((request_in == ACE_Encoding::ARSNOOP::CLEAN_UNIQUE) || 507 | (request_in == ACE_Encoding::ARSNOOP::CLEAN_INVALID) ) // 11, 9 -> 9 508 | return ACE_Encoding::ACSNOOP::CLEAN_INVALID; 509 | else if ((request_in == ACE_Encoding::ARSNOOP::MAKE_UNIQUE) || 510 | (request_in == ACE_Encoding::ARSNOOP::MAKE_INVALID) ) // 12, 13 -> 13 511 | return ACE_Encoding::ACSNOOP::MAKE_INVALID; 512 | else if (request_in == ACE_Encoding::ARSNOOP::CLEAN_SHARED) // 8 -> 8 513 | return ACE_Encoding::ACSNOOP::CLEAN_SHARED; 514 | else { 515 | NVHLS_ASSERT_MSG(0, "Read coherent access is out of valid snoop values.") 516 | } 517 | return 0; 518 | }; // End of rd_2_snoop 519 | 520 | inline NVUINTW(ACE_Encoding::ACSNOOP::_WIDTH) wr_2_snoop (NVUINTW(ACE_Encoding::ARSNOOP::_WIDTH) &request_in) { 521 | if (request_in == ACE_Encoding::AWSNOOP::WR_UNIQUE) // 0 -> 9 522 | return ACE_Encoding::ACSNOOP::CLEAN_INVALID; 523 | else if (request_in == ACE_Encoding::AWSNOOP::WR_LINE_UNIQUE) // 1 -> 13 524 | return ACE_Encoding::ACSNOOP::MAKE_INVALID; 525 | else { 526 | NVHLS_ASSERT_MSG(0, "Coherent access does not match any expected at Home.") 527 | } 528 | return 0; 529 | }; // End of wr_2_snoop 530 | }; // ace 531 | 532 | 533 | #endif // _AXI_ACE_H_ 534 | -------------------------------------------------------------------------------- /tb/tb_axi_con/axi_slave.h: -------------------------------------------------------------------------------- 1 | #ifndef AXI_SLAVE_H 2 | #define AXI_SLAVE_H 3 | 4 | #include "systemc.h" 5 | 6 | #include "../../src/include/flit_axi.h" 7 | #include "../tb_wrap.h" 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | 18 | #define AXI_TID_NUM 5 19 | #define AXI_ADDR_MAX 0xffffffff 20 | 21 | template 22 | SC_MODULE(axi_slave) { 23 | typedef typename axi::axi4 axi4_; 24 | typedef typename axi::AXI4_Encoding enc_; 25 | 26 | sc_in_clk clk; 27 | sc_in rst_n; 28 | 29 | sc_in stop_gen; // Not Used 30 | 31 | sc_in< sc_uint<32> > addr_map[SLAVE_NUM][2]; 32 | 33 | Connections::In ar_in; 34 | Connections::Out r_out; 35 | 36 | Connections::In aw_in; 37 | Connections::In w_in; 38 | Connections::Out b_out; 39 | 40 | // Scoreboard 41 | sc_mutex *sb_lock; 42 | std::vector< std::deque< msg_tb_wrap > > *sb_rd_req_q; 43 | std::vector< std::deque< msg_tb_wrap > > *sb_rd_resp_q; // This is Sized to Master LANES 44 | 45 | std::vector< std::deque< msg_tb_wrap > > *sb_wr_req_q; 46 | std::vector< std::deque< msg_tb_wrap > > *sb_wr_data_q; 47 | std::vector< std::deque< msg_tb_wrap > > *sb_wr_resp_q; 48 | 49 | int SLAVE_ID = -1; 50 | unsigned int STALL_RATE_RD; 51 | unsigned int STALL_RATE_WR; 52 | // int FLOW_CTRL; // 0: READY-VALID 53 | // // 1: CREDITS 54 | // // 2: FIFO 55 | // // 3: Credits fifo based 56 | 57 | unsigned int total_cycles; 58 | 59 | sc_time clk_period; 60 | 61 | std::queue stored_rd_resp; 62 | std::queue stored_wr_resp; 63 | 64 | std::deque wr_to_get_resp; 65 | 66 | // Read Response Generator 67 | int rd_resp_val; 68 | int rd_resp_generated; 69 | int rd_resp_inj; 70 | 71 | int wr_resp_generated; 72 | int wr_resp_inj; 73 | 74 | // Read Req Sink 75 | int rd_req_ej; 76 | 77 | int wr_req_ej; 78 | int wr_data_ej; 79 | 80 | // Error 81 | int error_sb_rd_req_not_found; 82 | int error_sb_wr_req_not_found; 83 | int error_sb_wr_data_not_found; 84 | 85 | // Functions 86 | void do_cycle(); 87 | void gen_rd_resp(axi4_::AddrPayload &rcv_rd_req ); 88 | void gen_wr_resp(unsigned wr_initiator); 89 | 90 | bool verify_rd_req(axi4_::AddrPayload &rcv_rd_req); 91 | bool verify_wr_req(axi4_::AddrPayload &rcv_wr_req); 92 | bool verify_wr_data(axi4_::WritePayload &rcv_wr_data, unsigned &wr_initiator); 93 | 94 | 95 | bool eq_rd_req (axi4_::AddrPayload &rcv_rd_req , axi4_::AddrPayload &sb_rd_req); 96 | bool eq_wr_req (axi4_::AddrPayload &rcv_wr_req , axi4_::AddrPayload &sb_wr_req); 97 | bool eq_wr_data(axi4_::WritePayload &rcv_wr_data, axi4_::WritePayload &sb_wr_data); 98 | 99 | // Constructor 100 | SC_HAS_PROCESS(axi_slave); 101 | axi_slave(sc_module_name name_) : sc_module(name_) 102 | { 103 | SLAVE_ID = -1; 104 | STALL_RATE_RD = 0; 105 | STALL_RATE_WR = 0; 106 | 107 | SC_THREAD(do_cycle); 108 | sensitive << clk.pos(); 109 | async_reset_signal_is(rst_n, false); 110 | } 111 | }; 112 | 113 | 114 | // --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- // 115 | // --- --- --- --- --- --- IMPLEMENTATION --- --- --- --- --- --- --- --- // 116 | // --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- // 117 | 118 | 119 | 120 | #include "axi_slave.h" 121 | 122 | template 123 | void axi_slave::do_cycle () { 124 | total_cycles = 0; 125 | 126 | rd_resp_generated = 0; 127 | rd_resp_inj = 0; 128 | rd_req_ej = 0; 129 | 130 | wr_resp_generated = 0; 131 | wr_resp_inj = 0; 132 | 133 | wr_req_ej = 0; 134 | wr_data_ej = 0; 135 | 136 | rd_resp_val = 1; 137 | 138 | clk_period = (dynamic_cast(clk.get_interface()))->period(); 139 | 140 | // Error 141 | error_sb_rd_req_not_found = 0; 142 | error_sb_wr_req_not_found = 0; 143 | error_sb_wr_data_not_found = 0; 144 | 145 | while(1) { 146 | wait(); 147 | // READ REQUESTS 148 | // Sink/Verify Read Request + Create the appropriate response 149 | bool do_sink = (rand()%100) >= STALL_RATE_RD; 150 | if (do_sink) { 151 | axi4_::AddrPayload rcv_rd_req; 152 | if (ar_in.PopNB(rcv_rd_req)) { 153 | sc_time this_gen_time; 154 | verify_rd_req(rcv_rd_req); 155 | rd_req_ej++; 156 | 157 | gen_rd_resp(rcv_rd_req); 158 | } 159 | } 160 | 161 | // WRITE REQUESTS 162 | do_sink = (rand()%100) >= STALL_RATE_RD; 163 | if (do_sink) { 164 | axi4_::AddrPayload rcv_wr_req; 165 | if (aw_in.PopNB(rcv_wr_req)) { 166 | verify_wr_req(rcv_wr_req); 167 | wr_to_get_resp.push_back(rcv_wr_req); 168 | wr_req_ej++; 169 | } 170 | } 171 | 172 | do_sink = (rand()%100) >= STALL_RATE_WR; 173 | if (do_sink) { 174 | axi4_::WritePayload rcv_wr_data; 175 | if (w_in.PopNB(rcv_wr_data)) { 176 | unsigned wr_initiator = -1; 177 | verify_wr_data(rcv_wr_data, wr_initiator); 178 | wr_data_ej++; 179 | 180 | if (rcv_wr_data.last) gen_wr_resp(wr_initiator); 181 | } 182 | } 183 | 184 | // RESPONSES 185 | // Inject READ Responses 186 | bool do_push = (rand()%100) >= STALL_RATE_RD; 187 | if (do_push && !stored_rd_resp.empty()) { 188 | axi4_::ReadPayload temp_resp = stored_rd_resp.front(); 189 | if (r_out.PushNB(temp_resp)) { 190 | stored_rd_resp.pop(); 191 | std::cout<<"[Slave "<< SLAVE_ID << "] : PUSHED RD-Resp " << temp_resp << " @" << sc_time_stamp() << std::endl; 192 | rd_resp_inj++; 193 | } 194 | } 195 | 196 | // Inject WRITE Responses 197 | do_push = (rand()%100) >= STALL_RATE_WR; 198 | if (do_push && !stored_wr_resp.empty()) { 199 | axi4_::WRespPayload temp_resp = stored_wr_resp.front(); 200 | if (b_out.PushNB(temp_resp)) { 201 | stored_wr_resp.pop(); 202 | std::cout<<"[Slave "<< SLAVE_ID << "] : PUSHED WR-Resp " << temp_resp << " @" << sc_time_stamp() << std::endl; 203 | wr_resp_inj++; 204 | } 205 | } 206 | 207 | } // End of while(1) 208 | }; // End of do_cycle 209 | 210 | 211 | 212 | 213 | 214 | // --------------------------- // 215 | // --- GENERATOR Functions --- // 216 | // --------------------------- // 217 | template 218 | void axi_slave::gen_rd_resp(axi4_::AddrPayload &rcv_rd_req) { 219 | sb_lock->lock(); 220 | axi4_::ReadPayload cur_beat; // Sized for Slave 221 | axi4_::ReadPayload beat_at_master; // Sized for master 222 | 223 | cur_beat.id = rcv_rd_req.id; 224 | beat_at_master.id = rcv_rd_req.id; 225 | 226 | // Create Response 227 | unsigned long int bytes_total = ((rcv_rd_req.len+1)<unlock(); 253 | }; // End of Read generator 254 | 255 | template 256 | void axi_slave::gen_wr_resp(unsigned wr_initiator) { 257 | sb_lock->lock(); 258 | axi4_::AddrPayload rcv_wr_req = wr_to_get_resp.front(); 259 | wr_to_get_resp.pop_front(); 260 | 261 | // Create Response 262 | axi4_::WRespPayload temp_wr_resp; 263 | temp_wr_resp.id = rcv_wr_req.id; 264 | temp_wr_resp.resp = SLAVE_ID; 265 | 266 | stored_wr_resp.push(temp_wr_resp); // Send WR-Resp to DUT 267 | 268 | msg_tb_wrap temp_wr_resp_tb; 269 | temp_wr_resp_tb.dut_msg = temp_wr_resp; 270 | temp_wr_resp_tb.time_gen = sc_time_stamp(); 271 | 272 | (*sb_wr_resp_q)[wr_initiator].push_back(temp_wr_resp_tb); // Send Beat to ScoreBoard. 273 | wr_resp_generated++; 274 | sb_lock->unlock(); 275 | }; // End of Read generator 276 | 277 | 278 | 279 | 280 | // ------------------------ // 281 | // --- VERIFY Functions --- // 282 | // ------------------------ // 283 | template 284 | bool axi_slave::verify_rd_req (axi4_::AddrPayload &rcv_rd_req) { 285 | bool verified = true; 286 | sb_lock->lock(); 287 | bool found=false; 288 | unsigned int j=0; 289 | while (j<(*sb_rd_req_q)[SLAVE_ID].size()){ 290 | msg_tb_wrap< axi4_::AddrPayload > sb_req = (*sb_rd_req_q)[SLAVE_ID][j]; 291 | 292 | if ( eq_rd_req(rcv_rd_req, sb_req.dut_msg) ){ 293 | (*sb_rd_req_q)[SLAVE_ID].erase((*sb_rd_req_q)[SLAVE_ID].begin()+j); 294 | found = true; 295 | break; 296 | } 297 | j++; 298 | } 299 | 300 | if(!found){ 301 | std::cout << "ERR : [Slave " << SLAVE_ID <<"] " << "RD Request : "<< rcv_rd_req << " . NOT FOUND! @" << sc_time_stamp() << "\n"; 302 | std::cout << "ERR : [Slave " << SLAVE_ID <<"] " << "-SB_front - "<< (*sb_rd_req_q)[SLAVE_ID].front() << "\n"; 303 | error_sb_rd_req_not_found++; 304 | sc_assert(0); 305 | // sc_stop(); 306 | verified = false; 307 | } else { 308 | std::cout<< "[Slave " << SLAVE_ID <<"] " << "RD Req OK : << " << rcv_rd_req << " @" << sc_time_stamp() << "\n"; 309 | } 310 | std::cout.flush(); 311 | sb_lock->unlock(); 312 | return verified; 313 | }; // End of READ Req Verify 314 | 315 | template 316 | bool axi_slave::verify_wr_req (axi4_::AddrPayload &rcv_wr_req) { 317 | bool verified = true; 318 | sb_lock->lock(); 319 | bool found=false; 320 | unsigned int j=0; 321 | while (j<(*sb_wr_req_q)[SLAVE_ID].size()){ 322 | axi4_::AddrPayload sb_value = ((*sb_wr_req_q)[SLAVE_ID][j]).dut_msg; 323 | 324 | if (eq_wr_req(rcv_wr_req, sb_value)){ 325 | (*sb_wr_req_q)[SLAVE_ID].erase((*sb_wr_req_q)[SLAVE_ID].begin()+j); 326 | found = true; 327 | break; 328 | } 329 | j++; 330 | } 331 | 332 | if(!found){ 333 | std::cout << "\n"; 334 | std::cout << "ERR : [Slave " << SLAVE_ID <<"] " << "WR Request : "<< rcv_wr_req << " . NOT FOUND! @" << sc_time_stamp() << "\n"; 335 | std::cout << "ERR : [Slave " << SLAVE_ID <<"] " << "-SB_front - "<< (*sb_wr_req_q)[SLAVE_ID].front() << "\n"; 336 | error_sb_wr_req_not_found++; 337 | sc_assert(0); 338 | // sc_stop(); 339 | verified = false; 340 | } else { 341 | std::cout<< "[Slave " << SLAVE_ID <<"] " << "WR Req OK : << " << rcv_wr_req << "\n"; 342 | } 343 | std::cout.flush(); 344 | sb_lock->unlock(); 345 | return verified; 346 | }; // End of WRITE Req Verify 347 | 348 | template 349 | bool axi_slave::verify_wr_data (axi4_::WritePayload &rcv_wr_data, unsigned &wr_initiator) { 350 | bool verified = true; 351 | sb_lock->lock(); 352 | bool found=false; 353 | unsigned int j=0; 354 | while (j<(*sb_wr_data_q)[SLAVE_ID].size()){ 355 | axi4_::WritePayload sb_value = ((*sb_wr_data_q)[SLAVE_ID][j]).dut_msg; 356 | 357 | if (eq_wr_data(rcv_wr_data, sb_value)){ 358 | // The last byte of the last beat signals the initiator 359 | if (rcv_wr_data.last.to_uint()) { 360 | for (int i=WR_S_LANES-1; i>=0;--i) { 361 | if ( (rcv_wr_data.wstrb.to_uint() >> i) & 1 ) { 362 | wr_initiator = ((rcv_wr_data.data >> (i*8)) & 0xFF).to_uint(); 363 | break; 364 | } 365 | } 366 | } 367 | 368 | (*sb_wr_data_q)[SLAVE_ID].erase((*sb_wr_data_q)[SLAVE_ID].begin()+j); 369 | found = true; 370 | break; 371 | } 372 | j++; 373 | } 374 | 375 | if(!found){ 376 | std::cout << "ERR : [Slave " << SLAVE_ID <<"] " << "WR Data : "<< rcv_wr_data << " . NOT FOUND! @" << sc_time_stamp() << "\n"; 377 | std::cout << "ERR : [Slave " << SLAVE_ID <<"] " << "-SB_front - "<< (*sb_wr_data_q)[SLAVE_ID].front() << "\n"; 378 | error_sb_wr_data_not_found++; 379 | sc_assert(0); 380 | // sc_stop(); 381 | verified = false; 382 | } else { 383 | std::cout<< "[Slave " << SLAVE_ID <<"] " << "WR Data OK : << " << rcv_wr_data << "\n"; 384 | } 385 | std::cout.flush(); 386 | sb_lock->unlock(); 387 | return verified; 388 | }; // End of WRITE Data Verify 389 | 390 | 391 | template 392 | bool axi_slave::eq_rd_req (axi4_::AddrPayload &rcv_rd_req, axi4_::AddrPayload &sb_rd_req) { 393 | bool equal = true; 394 | unsigned tid_mask = (1< 409 | bool axi_slave::eq_wr_req (axi4_::AddrPayload &rcv_wr_req, axi4_::AddrPayload &sb_wr_req) { 410 | bool equal = true; 411 | unsigned tid_mask = (1< 426 | bool axi_slave::eq_wr_data (axi4_::WritePayload &rcv_wr_data, axi4_::WritePayload &sb_wr_data) { 427 | bool equal = true; 428 | unsigned tid_mask = (1<> i) & 1) == ((sb_wr_data.wstrb >> i) & 1)); 431 | if ((rcv_wr_data.wstrb >> i) & 1) { 432 | equal = equal && (((rcv_wr_data.data >> (8 * i)) & 0xFF) == ((sb_wr_data.data >> (8 * i)) & 0xFF)); 433 | } 434 | } 435 | return (equal && 436 | rcv_wr_data.last == sb_wr_data.last // && 437 | //rcv_wr_data.wuser == sb_wr_data.wuser 438 | ); 439 | }; 440 | 441 | 442 | #endif // AXI_SLAVE_H 443 | --------------------------------------------------------------------------------