initial commit for open source NoC IP
This commit is contained in:
40
tb/Makefile
Normal file
40
tb/Makefile
Normal file
@@ -0,0 +1,40 @@
|
||||
CUR_MAKEFILE_PATH:=$(abspath $(lastword $(MAKEFILE_LIST)))
|
||||
CUR_PATH:=$(patsubst %/,%, $(dir $(CUR_MAKEFILE_PATH)))
|
||||
SRC_PATH:=$(CUR_PATH)/../rtl
|
||||
|
||||
ELFIO_PATH:=$(CUR_PATH)/../../utils/elfio
|
||||
|
||||
SIMULATOR_PATH:=$(CUR_PATH)/../../utils/dromajo
|
||||
SIMULATOR_INC:=$(SIMULATOR_PATH)/include
|
||||
SIMULATOR_BUILD_PATH:=$(SIMULATOR_PATH)/build
|
||||
|
||||
RRVTB_PATH:=$(CUR_PATH)/../../utils/rrvtb
|
||||
|
||||
default: mesh
|
||||
|
||||
single_router:
|
||||
vcs +vcs+lic+wait +vcs+loopreport -sverilog -kdb +vc -f flist_single_router.f $(DW_FILES) -top tb_single_router \
|
||||
+error+1 \
|
||||
+define+SIMULATION \
|
||||
+incdir+$(SRC_PATH) \
|
||||
+lint=TFIPC-L \
|
||||
-CFLAGS "-I$(SIMULATOR_INC) -I$(SIMULATOR_BUILD_PATH) -I$(ELFIO_PATH) -I$(RRVTB_PATH) -g -pthread -O3 -DGOLDMEM_INORDER" \
|
||||
-debug_access+all -full64 +vpi
|
||||
|
||||
mesh:
|
||||
vcs-2020.03-kgf vcs +vcs+lic+wait +vcs+loopreport -sverilog -kdb +vc -f flist_mesh.f $(DW_FILES) -top tb_mesh \
|
||||
+error+1 \
|
||||
+define+SIMULATION \
|
||||
+incdir+$(SRC_PATH) \
|
||||
+lint=TFIPC-L \
|
||||
-CFLAGS "-I$(SIMULATOR_INC) -I$(SIMULATOR_BUILD_PATH) -I$(ELFIO_PATH) -I$(RRVTB_PATH) -g -pthread -O3 -DGOLDMEM_INORDER" \
|
||||
-debug_access+all -full64 +vpi
|
||||
|
||||
run:
|
||||
./simv +vcs+loopreport 2>&1 | tee run.log
|
||||
|
||||
run_regression:
|
||||
time ./simv +vcs+loopreport +dumpon=0 +self_finish=0
|
||||
|
||||
clean:
|
||||
rm -rf simv* csrc Verdi* novas* ucli.key
|
||||
59
tb/flist_mesh.f
Normal file
59
tb/flist_mesh.f
Normal file
@@ -0,0 +1,59 @@
|
||||
+incdir+$PROJ_ROOT/rtl/include
|
||||
+incdir+$PROJ_ROOT/tb
|
||||
|
||||
$PROJ_ROOT/rtl/include/rvh_noc_pkg.sv
|
||||
$PROJ_ROOT/tb/v_noc_pkg.sv
|
||||
|
||||
$PROJ_ROOT/rtl/model/cells/std_dffe.sv
|
||||
$PROJ_ROOT/rtl/model/cells/std_dffr.sv
|
||||
$PROJ_ROOT/rtl/model/cells/std_dffre.sv
|
||||
$PROJ_ROOT/rtl/model/cells/std_dffrve.sv
|
||||
|
||||
$PROJ_ROOT/rtl/util/usage_manager.sv
|
||||
$PROJ_ROOT/rtl/util/mp_fifo.sv
|
||||
$PROJ_ROOT/rtl/util/mp_fifo_ptr_output.sv
|
||||
$PROJ_ROOT/rtl/util/sp_fifo_dat_vld_output.sv
|
||||
$PROJ_ROOT/rtl/util/one_counter.sv
|
||||
$PROJ_ROOT/rtl/util/priority_encoder.sv
|
||||
$PROJ_ROOT/rtl/util/onehot_mux.sv
|
||||
$PROJ_ROOT/rtl/util/one_hot_priority_encoder.sv
|
||||
$PROJ_ROOT/rtl/util/left_circular_rotate.sv
|
||||
$PROJ_ROOT/rtl/util/oh2idx.sv
|
||||
$PROJ_ROOT/rtl/util/one_hot_rr_arb.sv
|
||||
$PROJ_ROOT/rtl/util/select_two_from_n_valid.sv
|
||||
$PROJ_ROOT/rtl/util/freelist.sv
|
||||
|
||||
$PROJ_ROOT/rtl/util/commoncell/src/Basic/hw/MuxOH.v
|
||||
$PROJ_ROOT/rtl/util/commoncell/src/Queue/hw/AgeMatrixSelector.v
|
||||
|
||||
// TODO: need to change to compiled dpsram
|
||||
$PROJ_ROOT/rtl/model/simple_dual_one_clock.v
|
||||
|
||||
$PROJ_ROOT/rtl/input_port.sv
|
||||
$PROJ_ROOT/rtl/look_adead_routing.sv
|
||||
$PROJ_ROOT/rtl/output_port_vc_selection.sv
|
||||
$PROJ_ROOT/rtl/input_port_vc.sv
|
||||
$PROJ_ROOT/rtl/output_port_vc_assignment.sv
|
||||
$PROJ_ROOT/rtl/priority_req_select.sv
|
||||
$PROJ_ROOT/rtl/sa_global.sv
|
||||
$PROJ_ROOT/rtl/switch.sv
|
||||
$PROJ_ROOT/rtl/input_port_flit_decoder.sv
|
||||
$PROJ_ROOT/rtl/input_to_output.sv
|
||||
$PROJ_ROOT/rtl/output_port_vc_credit_counter.sv
|
||||
$PROJ_ROOT/rtl/sa_local.sv
|
||||
$PROJ_ROOT/rtl/performance_monitor.sv
|
||||
$PROJ_ROOT/rtl/vnet_router.sv
|
||||
|
||||
$PROJ_ROOT/rtl/ruby/ut_lib.sv
|
||||
|
||||
$PROJ_ROOT/rtl/local_port_look_adead_routing.sv
|
||||
$PROJ_ROOT/rtl/local_port_couple_module.sv
|
||||
|
||||
$PROJ_ROOT/tb/v_receiver.sv
|
||||
$PROJ_ROOT/tb/v_scoreboard.sv
|
||||
$PROJ_ROOT/tb/v_sender.sv
|
||||
$PROJ_ROOT/tb/v_test_generator.sv
|
||||
|
||||
|
||||
$PROJ_ROOT/tb/tb_mesh.sv
|
||||
// $PROJ_ROOT/tb/testbench.sv
|
||||
47
tb/flist_mesh.syn.f
Normal file
47
tb/flist_mesh.syn.f
Normal file
@@ -0,0 +1,47 @@
|
||||
+incdir+$PROJ_ROOT/rtl/include
|
||||
+incdir+$PROJ_ROOT/tb
|
||||
|
||||
$PROJ_ROOT/rtl/include/rvh_noc_pkg.sv
|
||||
|
||||
$PROJ_ROOT/rtl/model/cells/std_dffe.sv
|
||||
$PROJ_ROOT/rtl/model/cells/std_dffr.sv
|
||||
$PROJ_ROOT/rtl/model/cells/std_dffre.sv
|
||||
$PROJ_ROOT/rtl/model/cells/std_dffrve.sv
|
||||
|
||||
$PROJ_ROOT/rtl/util/usage_manager.sv
|
||||
$PROJ_ROOT/rtl/util/mp_fifo.sv
|
||||
$PROJ_ROOT/rtl/util/mp_fifo_ptr_output.sv
|
||||
$PROJ_ROOT/rtl/util/sp_fifo_dat_vld_output.sv
|
||||
$PROJ_ROOT/rtl/util/one_counter.sv
|
||||
$PROJ_ROOT/rtl/util/priority_encoder.sv
|
||||
$PROJ_ROOT/rtl/util/onehot_mux.sv
|
||||
$PROJ_ROOT/rtl/util/one_hot_priority_encoder.sv
|
||||
$PROJ_ROOT/rtl/util/left_circular_rotate.sv
|
||||
$PROJ_ROOT/rtl/util/oh2idx.sv
|
||||
$PROJ_ROOT/rtl/util/one_hot_rr_arb.sv
|
||||
$PROJ_ROOT/rtl/util/select_two_from_n_valid.sv
|
||||
$PROJ_ROOT/rtl/util/freelist.sv
|
||||
|
||||
$PROJ_ROOT/rtl/util/commoncell/src/Basic/hw/MuxOH.v
|
||||
$PROJ_ROOT/rtl/util/commoncell/src/Queue/hw/AgeMatrixSelector.v
|
||||
|
||||
// TODO: need to change to compiled dpsram
|
||||
$PROJ_ROOT/rtl/rtl/model/simple_dual_one_clock.v
|
||||
|
||||
$PROJ_ROOT/rtl/input_port.sv
|
||||
$PROJ_ROOT/rtl/look_adead_routing.sv
|
||||
$PROJ_ROOT/rtl/output_port_vc_selection.sv
|
||||
$PROJ_ROOT/rtl/input_port_vc.sv
|
||||
$PROJ_ROOT/rtl/output_port_vc_assignment.sv
|
||||
$PROJ_ROOT/rtl/priority_req_select.sv
|
||||
$PROJ_ROOT/rtl/sa_global.sv
|
||||
$PROJ_ROOT/rtl/switch.sv
|
||||
$PROJ_ROOT/rtl/input_port_flit_decoder.sv
|
||||
$PROJ_ROOT/rtl/input_to_output.sv
|
||||
$PROJ_ROOT/rtl/output_port_vc_credit_counter.sv
|
||||
$PROJ_ROOT/rtl/sa_local.sv
|
||||
$PROJ_ROOT/rtl/performance_monitor.sv
|
||||
$PROJ_ROOT/rtl/vnet_router.sv
|
||||
|
||||
$PROJ_ROOT/tb/top_mesh_syn.sv
|
||||
// $PROJ_ROOT/tb/testbench.sv
|
||||
59
tb/flist_single_router.f
Normal file
59
tb/flist_single_router.f
Normal file
@@ -0,0 +1,59 @@
|
||||
+incdir+$PROJ_ROOT/rtl/include
|
||||
+incdir+$PROJ_ROOT/tb
|
||||
|
||||
$PROJ_ROOT/rtl/include/rvh_noc_pkg.sv
|
||||
|
||||
$PROJ_ROOT/rtl/model/cells/std_dffe.sv
|
||||
$PROJ_ROOT/rtl/model/cells/std_dffr.sv
|
||||
$PROJ_ROOT/rtl/model/cells/std_dffre.sv
|
||||
$PROJ_ROOT/rtl/model/cells/std_dffrve.sv
|
||||
|
||||
$PROJ_ROOT/rtl/util/usage_manager.sv
|
||||
$PROJ_ROOT/rtl/util/mp_fifo.sv
|
||||
$PROJ_ROOT/rtl/util/mp_fifo_ptr_output.sv
|
||||
$PROJ_ROOT/rtl/util/sp_fifo_dat_vld_output.sv
|
||||
$PROJ_ROOT/rtl/util/one_counter.sv
|
||||
$PROJ_ROOT/rtl/util/priority_encoder.sv
|
||||
$PROJ_ROOT/rtl/util/onehot_mux.sv
|
||||
$PROJ_ROOT/rtl/util/one_hot_priority_encoder.sv
|
||||
$PROJ_ROOT/rtl/util/left_circular_rotate.sv
|
||||
$PROJ_ROOT/rtl/util/oh2idx.sv
|
||||
$PROJ_ROOT/rtl/util/one_hot_rr_arb.sv
|
||||
$PROJ_ROOT/rtl/util/select_two_from_n_valid.sv
|
||||
$PROJ_ROOT/rtl/util/freelist.sv
|
||||
|
||||
$PROJ_ROOT/rtl/util/commoncell/src/Basic/hw/MuxOH.v
|
||||
$PROJ_ROOT/rtl/util/commoncell/src/Queue/hw/AgeMatrixSelector.v
|
||||
|
||||
// TODO: need to change to compiled dpsram
|
||||
$PROJ_ROOT/rtl/rtl/model/simple_dual_one_clock.v
|
||||
|
||||
$PROJ_ROOT/rtl/input_port.sv
|
||||
$PROJ_ROOT/rtl/look_adead_routing.sv
|
||||
$PROJ_ROOT/rtl/output_port_vc_selection.sv
|
||||
$PROJ_ROOT/rtl/input_port_vc.sv
|
||||
$PROJ_ROOT/rtl/output_port_vc_assignment.sv
|
||||
$PROJ_ROOT/rtl/priority_req_select.sv
|
||||
$PROJ_ROOT/rtl/sa_global.sv
|
||||
$PROJ_ROOT/rtl/switch.sv
|
||||
$PROJ_ROOT/rtl/input_port_flit_decoder.sv
|
||||
$PROJ_ROOT/rtl/input_to_output.sv
|
||||
$PROJ_ROOT/rtl/output_port_vc_credit_counter.sv
|
||||
$PROJ_ROOT/rtl/sa_local.sv
|
||||
$PROJ_ROOT/rtl/performance_monitor.sv
|
||||
$PROJ_ROOT/rtl/vnet_router.sv
|
||||
|
||||
$PROJ_ROOT/tb/v_noc_pkg.sv
|
||||
$PROJ_ROOT/rtl/rvh_l1d/ruby/ut_lib.sv
|
||||
|
||||
$PROJ_ROOT/rtl/local_port_look_adead_routing.sv
|
||||
$PROJ_ROOT/rtl/local_port_couple_module.sv
|
||||
|
||||
$PROJ_ROOT/tb/v_receiver.sv
|
||||
$PROJ_ROOT/tb/v_scoreboard.sv
|
||||
$PROJ_ROOT/tb/v_sender.sv
|
||||
$PROJ_ROOT/tb/v_test_generator.sv
|
||||
|
||||
|
||||
$PROJ_ROOT/tb/tb_single_router.sv
|
||||
// $PROJ_ROOT/tb/testbench.sv
|
||||
47
tb/flist_single_router.syn.f
Normal file
47
tb/flist_single_router.syn.f
Normal file
@@ -0,0 +1,47 @@
|
||||
+incdir+$PROJ_ROOT/rtl/include
|
||||
+incdir+$PROJ_ROOT/tb
|
||||
|
||||
$PROJ_ROOT/rtl/include/rvh_noc_pkg.sv
|
||||
|
||||
$PROJ_ROOT/rtl/model/cells/std_dffe.sv
|
||||
$PROJ_ROOT/rtl/model/cells/std_dffr.sv
|
||||
$PROJ_ROOT/rtl/model/cells/std_dffre.sv
|
||||
$PROJ_ROOT/rtl/model/cells/std_dffrve.sv
|
||||
|
||||
$PROJ_ROOT/rtl/util/usage_manager.sv
|
||||
$PROJ_ROOT/rtl/util/mp_fifo.sv
|
||||
$PROJ_ROOT/rtl/util/mp_fifo_ptr_output.sv
|
||||
$PROJ_ROOT/rtl/util/sp_fifo_dat_vld_output.sv
|
||||
$PROJ_ROOT/rtl/util/one_counter.sv
|
||||
$PROJ_ROOT/rtl/util/priority_encoder.sv
|
||||
$PROJ_ROOT/rtl/util/onehot_mux.sv
|
||||
$PROJ_ROOT/rtl/util/one_hot_priority_encoder.sv
|
||||
$PROJ_ROOT/rtl/util/left_circular_rotate.sv
|
||||
$PROJ_ROOT/rtl/util/oh2idx.sv
|
||||
$PROJ_ROOT/rtl/util/one_hot_rr_arb.sv
|
||||
$PROJ_ROOT/rtl/util/select_two_from_n_valid.sv
|
||||
$PROJ_ROOT/rtl/util/freelist.sv
|
||||
|
||||
$PROJ_ROOT/rtl/util/commoncell/src/Basic/hw/MuxOH.v
|
||||
$PROJ_ROOT/rtl/util/commoncell/src/Queue/hw/AgeMatrixSelector.v
|
||||
|
||||
// TODO: need to change to compiled dpsram
|
||||
$PROJ_ROOT/rtl/rtl/model/simple_dual_one_clock.v
|
||||
|
||||
$PROJ_ROOT/rtl/input_port.sv
|
||||
$PROJ_ROOT/rtl/look_adead_routing.sv
|
||||
$PROJ_ROOT/rtl/output_port_vc_selection.sv
|
||||
$PROJ_ROOT/rtl/input_port_vc.sv
|
||||
$PROJ_ROOT/rtl/output_port_vc_assignment.sv
|
||||
$PROJ_ROOT/rtl/priority_req_select.sv
|
||||
$PROJ_ROOT/rtl/sa_global.sv
|
||||
$PROJ_ROOT/rtl/switch.sv
|
||||
$PROJ_ROOT/rtl/input_port_flit_decoder.sv
|
||||
$PROJ_ROOT/rtl/input_to_output.sv
|
||||
$PROJ_ROOT/rtl/output_port_vc_credit_counter.sv
|
||||
$PROJ_ROOT/rtl/sa_local.sv
|
||||
$PROJ_ROOT/rtl/performance_monitor.sv
|
||||
$PROJ_ROOT/rtl/vnet_router.sv
|
||||
|
||||
$PROJ_ROOT/tb/top_single_router_syn.sv
|
||||
// $PROJ_ROOT/tb/testbench.sv
|
||||
567
tb/tb_mesh.sv
Normal file
567
tb/tb_mesh.sv
Normal file
@@ -0,0 +1,567 @@
|
||||
module tb_mesh
|
||||
import rvh_noc_pkg::*;
|
||||
import v_noc_pkg::*;
|
||||
#(
|
||||
// mesh parameters
|
||||
parameter NODE_NUM_X_DIMESION = 3,
|
||||
parameter NODE_NUM_Y_DIMESION = 3,
|
||||
|
||||
// router parameters
|
||||
parameter INPUT_PORT_NUM = INPUT_PORT_NUMBER,
|
||||
parameter OUTPUT_PORT_NUM = OUTPUT_PORT_NUMBER,
|
||||
parameter LOCAL_PORT_NUM = INPUT_PORT_NUM-4,
|
||||
parameter type flit_payload_t = logic[FLIT_LENGTH-1:0],
|
||||
|
||||
// parameter QOS_VC_NUM_PER_INPUT = QOS_VC_NUM_PER_INPUT,
|
||||
|
||||
parameter VC_NUM_INPUT_N = 1+LOCAL_PORT_NUM+QOS_VC_NUM_PER_INPUT,
|
||||
parameter VC_NUM_INPUT_S = 1+LOCAL_PORT_NUM+QOS_VC_NUM_PER_INPUT,
|
||||
parameter VC_NUM_INPUT_E = 3+LOCAL_PORT_NUM+QOS_VC_NUM_PER_INPUT,
|
||||
parameter VC_NUM_INPUT_W = 3+LOCAL_PORT_NUM+QOS_VC_NUM_PER_INPUT,
|
||||
`ifdef ALLOW_SAME_ROUTER_L2L_TRANSFER
|
||||
parameter VC_NUM_INPUT_L = 4+LOCAL_PORT_NUM-1+QOS_VC_NUM_PER_INPUT,
|
||||
`else
|
||||
parameter VC_NUM_INPUT_L = 4+QOS_VC_NUM_PER_INPUT,
|
||||
`endif
|
||||
parameter SA_GLOBAL_INPUT_NUM_N = 3+LOCAL_PORT_NUM,
|
||||
parameter SA_GLOBAL_INPUT_NUM_S = 3+LOCAL_PORT_NUM,
|
||||
parameter SA_GLOBAL_INPUT_NUM_E = 1+LOCAL_PORT_NUM,
|
||||
parameter SA_GLOBAL_INPUT_NUM_W = 1+LOCAL_PORT_NUM,
|
||||
`ifdef ALLOW_SAME_ROUTER_L2L_TRANSFER
|
||||
parameter SA_GLOBAL_INPUT_NUM_L = 4+LOCAL_PORT_NUM-1,
|
||||
`else
|
||||
parameter SA_GLOBAL_INPUT_NUM_L = 4,
|
||||
`endif
|
||||
parameter VC_NUM_OUTPUT_N = 1+LOCAL_PORT_NUM+QOS_VC_NUM_PER_INPUT,
|
||||
parameter VC_NUM_OUTPUT_S = 1+LOCAL_PORT_NUM+QOS_VC_NUM_PER_INPUT,
|
||||
parameter VC_NUM_OUTPUT_E = 3+LOCAL_PORT_NUM+QOS_VC_NUM_PER_INPUT,
|
||||
parameter VC_NUM_OUTPUT_W = 3+LOCAL_PORT_NUM+QOS_VC_NUM_PER_INPUT,
|
||||
parameter VC_NUM_OUTPUT_L = 1,
|
||||
parameter VC_DEPTH_INPUT_N = VC_DEPTH_MAX,
|
||||
parameter VC_DEPTH_INPUT_S = VC_DEPTH_MAX,
|
||||
parameter VC_DEPTH_INPUT_E = VC_DEPTH_MAX,
|
||||
parameter VC_DEPTH_INPUT_W = VC_DEPTH_MAX,
|
||||
parameter VC_DEPTH_INPUT_L = VC_DEPTH_MAX,
|
||||
|
||||
parameter int V_CPU_DATA_REQ_NUM_PER_CORE_PER_CYCLE = 3,
|
||||
parameter int V_CPU_INST_REQ_NUM_PER_CORE_PER_CYCLE = 1,
|
||||
parameter real V_L1D_MISS_RATE = 10, // %
|
||||
parameter real V_L1I_MISS_RATE = 10, // %
|
||||
parameter real V_L2_MISS_RATE = 100, // %
|
||||
parameter int V_CORE_NUM = NODE_NUM_X_DIMESION * NODE_NUM_Y_DIMESION * LOCAL_PORT_NUM,
|
||||
parameter int V_CACHE_MISS_ALL_CORE_PER_CYCLE = V_CORE_NUM,
|
||||
// parameter int V_CACHE_MISS_ALL_CORE_PER_CYCLE = ((V_CPU_DATA_REQ_NUM_PER_CORE_PER_CYCLE * V_CORE_NUM) * V_L1D_MISS_RATE +
|
||||
// (V_CPU_INST_REQ_NUM_PER_CORE_PER_CYCLE * V_CORE_NUM) * V_L1I_MISS_RATE) *
|
||||
// V_L2_MISS_RATE / 100 / 100,
|
||||
|
||||
|
||||
// test_generator parameters
|
||||
parameter TEST_CASE_MESH_RANDOM = 1, // random sender and receiver
|
||||
parameter TEST_CASE_MESH_DIAGONAL = !TEST_CASE_MESH_RANDOM, // from (0,0) to (NODE_NUM_X_DIMESION-1, NODE_NUM_Y_DIMESION-1)
|
||||
|
||||
parameter RANDOM_BIT_NUM = 168, // 32,64,80,128,168
|
||||
|
||||
parameter SCOREBOARD_TIMEOUT_EN = !TEST_CASE_MESH_DIAGONAL,
|
||||
parameter SCOREBOARD_TIMEOUT_THRESHOLD = 16384,
|
||||
|
||||
parameter TEST_CASE_NUM_PER_CYCLE = RANDOM_BIT_NUM/3,
|
||||
// parameter TEST_CASE_NUM_PER_CYCLE = V_CACHE_MISS_ALL_CORE_PER_CYCLE < 1 ? 1 :
|
||||
// V_CACHE_MISS_ALL_CORE_PER_CYCLE > RANDOM_BIT_NUM/3 ? RANDOM_BIT_NUM/3 : // no more than RANDOM_BIT_NUM/3
|
||||
// V_CACHE_MISS_ALL_CORE_PER_CYCLE,
|
||||
|
||||
// scoreboard parameters
|
||||
parameter SCOREBOARD_ENTRY_NUM_PER_SENDER = 64,
|
||||
|
||||
// sender parameters
|
||||
parameter SENDER_NUM = NODE_NUM_X_DIMESION*NODE_NUM_Y_DIMESION*LOCAL_PORT_NUM,
|
||||
parameter SENDER_FLIT_BUFFER_DEPTH = 512,
|
||||
|
||||
parameter SENDER_TIMEOUT_EN = !TEST_CASE_MESH_DIAGONAL,
|
||||
parameter SENDER_TIMEOUT_THRESHOLD = 16384,
|
||||
|
||||
// receiver parameters
|
||||
parameter RECEIVER_NUM = SENDER_NUM,
|
||||
|
||||
// overall longest test cycle
|
||||
parameter LONGEST_TEST_CYCLE = 100000
|
||||
)
|
||||
(
|
||||
|
||||
);
|
||||
|
||||
genvar i, j, k;
|
||||
|
||||
// Ports
|
||||
logic [NODE_NUM_X_DIMESION-1:0][NODE_NUM_Y_DIMESION-1:0][OUTPUT_PORT_NUM-1:0] tx_flit_pend;
|
||||
logic [NODE_NUM_X_DIMESION-1:0][NODE_NUM_Y_DIMESION-1:0][OUTPUT_PORT_NUM-1:0] tx_flit_v;
|
||||
flit_payload_t [NODE_NUM_X_DIMESION-1:0][NODE_NUM_Y_DIMESION-1:0][OUTPUT_PORT_NUM-1:0] tx_flit;
|
||||
logic [NODE_NUM_X_DIMESION-1:0][NODE_NUM_Y_DIMESION-1:0][OUTPUT_PORT_NUM-1:0][VC_ID_NUM_MAX_W-1:0] tx_flit_vc_id;
|
||||
io_port_t [NODE_NUM_X_DIMESION-1:0][NODE_NUM_Y_DIMESION-1:0][OUTPUT_PORT_NUM-1:0] tx_flit_look_ahead_routing;
|
||||
|
||||
logic [NODE_NUM_X_DIMESION-1:0][NODE_NUM_Y_DIMESION-1:0][OUTPUT_PORT_NUM-1:0] rx_flit_pend;
|
||||
logic [NODE_NUM_X_DIMESION-1:0][NODE_NUM_Y_DIMESION-1:0][OUTPUT_PORT_NUM-1:0] rx_flit_v;
|
||||
flit_payload_t [NODE_NUM_X_DIMESION-1:0][NODE_NUM_Y_DIMESION-1:0][OUTPUT_PORT_NUM-1:0] rx_flit;
|
||||
logic [NODE_NUM_X_DIMESION-1:0][NODE_NUM_Y_DIMESION-1:0][OUTPUT_PORT_NUM-1:0][VC_ID_NUM_MAX_W-1:0] rx_flit_vc_id;
|
||||
io_port_t [NODE_NUM_X_DIMESION-1:0][NODE_NUM_Y_DIMESION-1:0][OUTPUT_PORT_NUM-1:0] rx_flit_look_ahead_routing;
|
||||
|
||||
logic [NODE_NUM_X_DIMESION-1:0][NODE_NUM_Y_DIMESION-1:0][INPUT_PORT_NUM-1:0] tx_lcrd_v;
|
||||
logic [NODE_NUM_X_DIMESION-1:0][NODE_NUM_Y_DIMESION-1:0][INPUT_PORT_NUM-1:0][VC_ID_NUM_MAX_W-1:0] tx_lcrd_id;
|
||||
|
||||
logic [NODE_NUM_X_DIMESION-1:0][NODE_NUM_Y_DIMESION-1:0][INPUT_PORT_NUM-1:0] rx_lcrd_v;
|
||||
logic [NODE_NUM_X_DIMESION-1:0][NODE_NUM_Y_DIMESION-1:0][INPUT_PORT_NUM-1:0][VC_ID_NUM_MAX_W-1:0] rx_lcrd_id;
|
||||
|
||||
|
||||
logic [NODE_NUM_X_DIMESION-1:0][NODE_NUM_Y_DIMESION-1:0][NodeID_X_Width-1:0] node_id_x;
|
||||
logic [NODE_NUM_X_DIMESION-1:0][NODE_NUM_Y_DIMESION-1:0][NodeID_Y_Width-1:0] node_id_y;
|
||||
|
||||
logic clk;
|
||||
logic rstn;
|
||||
|
||||
|
||||
// generate mesh routers
|
||||
generate
|
||||
for(i = 0; i < NODE_NUM_X_DIMESION; i++) begin: gen_mesh_routers_x_dimesion
|
||||
for(j = 0; j < NODE_NUM_Y_DIMESION; j++) begin: gen_mesh_routers_y_dimesion
|
||||
vnet_router
|
||||
#(
|
||||
.INPUT_PORT_NUM(INPUT_PORT_NUM ),
|
||||
.OUTPUT_PORT_NUM(OUTPUT_PORT_NUM ),
|
||||
.flit_payload_t(flit_payload_t),
|
||||
.QOS_VC_NUM_PER_INPUT(QOS_VC_NUM_PER_INPUT),
|
||||
.VC_NUM_INPUT_N(VC_NUM_INPUT_N ),
|
||||
.VC_NUM_INPUT_S(VC_NUM_INPUT_S ),
|
||||
.VC_NUM_INPUT_E(VC_NUM_INPUT_E ),
|
||||
.VC_NUM_INPUT_W(VC_NUM_INPUT_W ),
|
||||
.VC_NUM_INPUT_L(VC_NUM_INPUT_L ),
|
||||
.SA_GLOBAL_INPUT_NUM_N(SA_GLOBAL_INPUT_NUM_N ),
|
||||
.SA_GLOBAL_INPUT_NUM_S(SA_GLOBAL_INPUT_NUM_S ),
|
||||
.SA_GLOBAL_INPUT_NUM_E(SA_GLOBAL_INPUT_NUM_E ),
|
||||
.SA_GLOBAL_INPUT_NUM_W(SA_GLOBAL_INPUT_NUM_W ),
|
||||
.SA_GLOBAL_INPUT_NUM_L(SA_GLOBAL_INPUT_NUM_L ),
|
||||
.VC_NUM_OUTPUT_N(VC_NUM_OUTPUT_N ),
|
||||
.VC_NUM_OUTPUT_S(VC_NUM_OUTPUT_S ),
|
||||
.VC_NUM_OUTPUT_E(VC_NUM_OUTPUT_E ),
|
||||
.VC_NUM_OUTPUT_W(VC_NUM_OUTPUT_W ),
|
||||
.VC_NUM_OUTPUT_L(VC_NUM_OUTPUT_L ),
|
||||
.VC_DEPTH_INPUT_N(VC_DEPTH_INPUT_N ),
|
||||
.VC_DEPTH_INPUT_S(VC_DEPTH_INPUT_S ),
|
||||
.VC_DEPTH_INPUT_E(VC_DEPTH_INPUT_E ),
|
||||
.VC_DEPTH_INPUT_W(VC_DEPTH_INPUT_W ),
|
||||
.VC_DEPTH_INPUT_L(VC_DEPTH_INPUT_L )
|
||||
)
|
||||
vnet_router_dut (
|
||||
.rx_flit_pend_i (rx_flit_pend [i][j] ),
|
||||
.rx_flit_v_i (rx_flit_v [i][j] ),
|
||||
.rx_flit_i (rx_flit [i][j] ),
|
||||
.rx_flit_vc_id_i (rx_flit_vc_id [i][j] ),
|
||||
.rx_flit_look_ahead_routing_i (rx_flit_look_ahead_routing [i][j] ),
|
||||
|
||||
.tx_flit_pend_o (tx_flit_pend [i][j] ),
|
||||
.tx_flit_v_o (tx_flit_v [i][j] ),
|
||||
.tx_flit_o (tx_flit [i][j] ),
|
||||
.tx_flit_vc_id_o (tx_flit_vc_id [i][j] ),
|
||||
.tx_flit_look_ahead_routing_o (tx_flit_look_ahead_routing [i][j] ),
|
||||
|
||||
.rx_lcrd_v_o (rx_lcrd_v [i][j] ),
|
||||
.rx_lcrd_id_o (rx_lcrd_id [i][j] ),
|
||||
|
||||
.tx_lcrd_v_i (tx_lcrd_v [i][j] ),
|
||||
.tx_lcrd_id_i (tx_lcrd_id [i][j] ),
|
||||
|
||||
.node_id_x_ths_hop_i (node_id_x [i][j] ),
|
||||
.node_id_y_ths_hop_i (node_id_y [i][j] ),
|
||||
|
||||
.clk (clk ),
|
||||
.rstn (rstn)
|
||||
);
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// assign node id to each router
|
||||
generate
|
||||
for(i = 0; i < NODE_NUM_X_DIMESION; i++) begin: gen_node_id_x_x_dimesion
|
||||
for(j = 0; j < NODE_NUM_Y_DIMESION; j++) begin: gen_node_id_x_y_dimesion
|
||||
assign node_id_x [i][j] = i;
|
||||
end
|
||||
end
|
||||
for(i = 0; i < NODE_NUM_Y_DIMESION; i++) begin: gen_node_id_y_y_dimesion
|
||||
for(j = 0; j < NODE_NUM_X_DIMESION; j++) begin: gen_node_id_y_x_dimesion
|
||||
assign node_id_y [j][i] = i;
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// connect each router together
|
||||
generate
|
||||
for(i = 0; i < NODE_NUM_X_DIMESION; i++) begin: gen_connect_routers_ns_x_dimesion
|
||||
for(j = 0; j < NODE_NUM_Y_DIMESION-1; j++) begin: gen_connect_routers_ns_y_dimesion
|
||||
// connect N inport to S outport
|
||||
assign rx_flit_pend [i][j][0] = tx_flit_pend [i][j+1][1];
|
||||
assign rx_flit_v [i][j][0] = tx_flit_v [i][j+1][1];
|
||||
assign rx_flit [i][j][0] = tx_flit [i][j+1][1];
|
||||
assign rx_flit_vc_id [i][j][0] = tx_flit_vc_id [i][j+1][1];
|
||||
assign rx_flit_look_ahead_routing [i][j][0] = tx_flit_look_ahead_routing [i][j+1][1];
|
||||
|
||||
assign tx_lcrd_v [i][j][0] = rx_lcrd_v [i][j+1][1];
|
||||
assign tx_lcrd_id [i][j][0] = rx_lcrd_id [i][j+1][1];
|
||||
|
||||
// connect S inport to N outport
|
||||
assign rx_flit_pend [i][j+1][1] = tx_flit_pend [i][j][0];
|
||||
assign rx_flit_v [i][j+1][1] = tx_flit_v [i][j][0];
|
||||
assign rx_flit [i][j+1][1] = tx_flit [i][j][0];
|
||||
assign rx_flit_vc_id [i][j+1][1] = tx_flit_vc_id [i][j][0];
|
||||
assign rx_flit_look_ahead_routing [i][j+1][1] = tx_flit_look_ahead_routing [i][j][0];
|
||||
|
||||
assign tx_lcrd_v [i][j+1][1] = rx_lcrd_v [i][j][0];
|
||||
assign tx_lcrd_id [i][j+1][1] = rx_lcrd_id [i][j][0];
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
for(i = 0; i < NODE_NUM_Y_DIMESION; i++) begin: gen_connect_routers_ew_x_dimesion
|
||||
for(j = 0; j < NODE_NUM_X_DIMESION-1; j++) begin: gen_connect_routers_ew_y_dimesion
|
||||
// connect E inport to W outport
|
||||
assign rx_flit_pend [j][i][2] = tx_flit_pend [j+1][i][3];
|
||||
assign rx_flit_v [j][i][2] = tx_flit_v [j+1][i][3];
|
||||
assign rx_flit [j][i][2] = tx_flit [j+1][i][3];
|
||||
assign rx_flit_vc_id [j][i][2] = tx_flit_vc_id [j+1][i][3];
|
||||
assign rx_flit_look_ahead_routing [j][i][2] = tx_flit_look_ahead_routing [j+1][i][3];
|
||||
|
||||
assign tx_lcrd_v [j][i][2] = rx_lcrd_v [j+1][i][3];
|
||||
assign tx_lcrd_id [j][i][2] = rx_lcrd_id [j+1][i][3];
|
||||
|
||||
// connect W inport to E outport
|
||||
assign rx_flit_pend [j+1][i][3] = tx_flit_pend [j][i][2];
|
||||
assign rx_flit_v [j+1][i][3] = tx_flit_v [j][i][2];
|
||||
assign rx_flit [j+1][i][3] = tx_flit [j][i][2];
|
||||
assign rx_flit_vc_id [j+1][i][3] = tx_flit_vc_id [j][i][2];
|
||||
assign rx_flit_look_ahead_routing [j+1][i][3] = tx_flit_look_ahead_routing [j][i][2];
|
||||
|
||||
assign tx_lcrd_v [j+1][i][3] = rx_lcrd_v [j][i][2];
|
||||
assign tx_lcrd_id [j+1][i][3] = rx_lcrd_id [j][i][2];
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// other unused non-local ports, assign router rx to 0
|
||||
generate
|
||||
for(i = 0; i < NODE_NUM_X_DIMESION; i++) begin: gen_unused_non_local_ports_x_dimesion
|
||||
assign rx_flit_pend [i][NODE_NUM_Y_DIMESION-1][0] = '0;
|
||||
assign rx_flit_v [i][NODE_NUM_Y_DIMESION-1][0] = '0;
|
||||
assign rx_flit [i][NODE_NUM_Y_DIMESION-1][0] = '0;
|
||||
assign rx_flit_vc_id [i][NODE_NUM_Y_DIMESION-1][0] = '0;
|
||||
assign rx_flit_look_ahead_routing [i][NODE_NUM_Y_DIMESION-1][0] = '0;
|
||||
|
||||
assign tx_lcrd_v [i][NODE_NUM_Y_DIMESION-1][0] = '0;
|
||||
assign tx_lcrd_id [i][NODE_NUM_Y_DIMESION-1][0] = '0;
|
||||
|
||||
|
||||
assign rx_flit_pend [i][0][1] = '0;
|
||||
assign rx_flit_v [i][0][1] = '0;
|
||||
assign rx_flit [i][0][1] = '0;
|
||||
assign rx_flit_vc_id [i][0][1] = '0;
|
||||
assign rx_flit_look_ahead_routing [i][0][1] = '0;
|
||||
|
||||
assign tx_lcrd_v [i][0][1] = '0;
|
||||
assign tx_lcrd_id [i][0][1] = '0;
|
||||
end
|
||||
|
||||
for(i = 0; i < NODE_NUM_Y_DIMESION; i++) begin: gen_unused_non_local_ports_y_dimesion
|
||||
// connect E inport to W outport
|
||||
assign rx_flit_pend [NODE_NUM_X_DIMESION-1][i][2] = '0;
|
||||
assign rx_flit_v [NODE_NUM_X_DIMESION-1][i][2] = '0;
|
||||
assign rx_flit [NODE_NUM_X_DIMESION-1][i][2] = '0;
|
||||
assign rx_flit_vc_id [NODE_NUM_X_DIMESION-1][i][2] = '0;
|
||||
assign rx_flit_look_ahead_routing [NODE_NUM_X_DIMESION-1][i][2] = '0;
|
||||
|
||||
assign tx_lcrd_v [NODE_NUM_X_DIMESION-1][i][2] = '0;
|
||||
assign tx_lcrd_id [NODE_NUM_X_DIMESION-1][i][2] = '0;
|
||||
|
||||
// connect W inport to E outport
|
||||
assign rx_flit_pend [0][i][3] = '0;
|
||||
assign rx_flit_v [0][i][3] = '0;
|
||||
assign rx_flit [0][i][3] = '0;
|
||||
assign rx_flit_vc_id [0][i][3] = '0;
|
||||
assign rx_flit_look_ahead_routing [0][i][3] = '0;
|
||||
|
||||
assign tx_lcrd_v [0][i][3] = '0;
|
||||
assign tx_lcrd_id [0][i][3] = '0;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
||||
// test generate
|
||||
logic [64-1:0] mcycle;
|
||||
node_id_t target_node;
|
||||
|
||||
int longest_test_cycle = LONGEST_TEST_CYCLE;
|
||||
int self_finish = 1;
|
||||
|
||||
initial begin
|
||||
$value$plusargs("longest_test_cycle=%d", longest_test_cycle);
|
||||
$value$plusargs("self_finish=%d", self_finish);
|
||||
end
|
||||
|
||||
always_ff @(posedge clk or negedge rstn) begin
|
||||
if(~rstn) begin
|
||||
mcycle <= '0;
|
||||
end else begin
|
||||
mcycle <= mcycle + 1;
|
||||
if(self_finish > 0) begin
|
||||
if(mcycle == longest_test_cycle) begin
|
||||
$finish();
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
logic [32-1:0] src_id_lfsr_seed;
|
||||
logic [32-1:0] tgt_id_lfsr_seed;
|
||||
logic [SENDER_NUM-1:0] new_test_vld;
|
||||
test_case_t [SENDER_NUM-1:0] new_test;
|
||||
logic [SENDER_NUM-1:0] new_test_rdy;
|
||||
|
||||
assign src_id_lfsr_seed = 32'hdeadbeef;
|
||||
assign tgt_id_lfsr_seed = 32'hbaadf00d;
|
||||
|
||||
v_test_generator
|
||||
#(
|
||||
.SENDER_NUM (SENDER_NUM ),
|
||||
.RANDOM_BIT_NUM (RANDOM_BIT_NUM ),
|
||||
.SCOREBOARD_TIMEOUT_EN (SCOREBOARD_TIMEOUT_EN ),
|
||||
.SCOREBOARD_TIMEOUT_THRESHOLD (SCOREBOARD_TIMEOUT_THRESHOLD ),
|
||||
.TEST_CASE_NUM_PER_CYCLE(TEST_CASE_NUM_PER_CYCLE ),
|
||||
.TEST_CASE_MESH_RANDOM (TEST_CASE_MESH_RANDOM ),
|
||||
.TEST_CASE_MESH_DIAGONAL(TEST_CASE_MESH_DIAGONAL ),
|
||||
.NODE_NUM_X_DIMESION (NODE_NUM_X_DIMESION ),
|
||||
.NODE_NUM_Y_DIMESION (NODE_NUM_Y_DIMESION ),
|
||||
.LOCAL_PORT_NUM (LOCAL_PORT_NUM ),
|
||||
|
||||
.ASSUMED_SYSTEM_FREQUENCY((1<<30) )
|
||||
)
|
||||
v_test_generator_u (
|
||||
.new_test_vld_o (new_test_vld ),
|
||||
.new_test_o (new_test ),
|
||||
.new_test_rdy_i (new_test_rdy ),
|
||||
.src_id_lfsr_seed_i (src_id_lfsr_seed ^ mcycle[16+:32]),
|
||||
.tgt_id_lfsr_seed_i (tgt_id_lfsr_seed ^ mcycle[20+:32] ),
|
||||
.lfsr_update_en_i (&mcycle[16-1:0]),
|
||||
.mcycle_i (mcycle),
|
||||
.clk (clk ),
|
||||
.rstn (rstn)
|
||||
);
|
||||
|
||||
logic [SENDER_NUM-1:0] new_scoreboard_entry_vld;
|
||||
scoreboard_entry_t [SENDER_NUM-1:0] new_scoreboard_entry;
|
||||
logic [SENDER_NUM-1:0] new_scoreboard_entry_rdy;
|
||||
node_id_t [SENDER_NUM-1:0] sender_node_id;
|
||||
|
||||
|
||||
// local port map to sender number
|
||||
// sender id = x_posotion*(NODE_NUM_Y_DIMESION*LOCAL_PORT_NUM) + y_posotion*LOCAL_PORT_NUM + local_port_id
|
||||
// 7 8 17 16
|
||||
// \ | | /
|
||||
// 6 - (0,2) -- (1,2) - 15
|
||||
// 5 | | 14
|
||||
// \ | | /
|
||||
// 4 - (0,1) -- (1,1) - 13
|
||||
// / | | \
|
||||
// 3 | | 12
|
||||
// 2 - (0,0) -- (1,0) - 11
|
||||
// / | | \
|
||||
// 1 0 9 10
|
||||
|
||||
generate
|
||||
for(i = 0; i < NODE_NUM_X_DIMESION; i++) begin: gen_sender_node_id_x_dimesion
|
||||
for(j = 0; j < NODE_NUM_Y_DIMESION; j++) begin: gen_sender_node_id_y_dimesion
|
||||
for(k = 0; k < LOCAL_PORT_NUM; k++) begin: gen_sender_node_id_device_port
|
||||
assign sender_node_id[i*(NODE_NUM_Y_DIMESION*LOCAL_PORT_NUM) + j*LOCAL_PORT_NUM + k].x_position = i;
|
||||
assign sender_node_id[i*(NODE_NUM_Y_DIMESION*LOCAL_PORT_NUM) + j*LOCAL_PORT_NUM + k].y_position = j;
|
||||
assign sender_node_id[i*(NODE_NUM_Y_DIMESION*LOCAL_PORT_NUM) + j*LOCAL_PORT_NUM + k].device_port = k;
|
||||
assign sender_node_id[i*(NODE_NUM_Y_DIMESION*LOCAL_PORT_NUM) + j*LOCAL_PORT_NUM + k].device_id = '0;
|
||||
end
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
||||
generate
|
||||
for(i = 0; i < NODE_NUM_X_DIMESION; i++) begin: gen_v_sender_x_dimesion
|
||||
for(j = 0; j < NODE_NUM_Y_DIMESION; j++) begin: gen_v_sender_y_dimesion
|
||||
for(k = 0; k < LOCAL_PORT_NUM; k++) begin: gen_v_sender_device_port
|
||||
v_sender
|
||||
#(
|
||||
.FLIT_BUFFER_DEPTH (SENDER_FLIT_BUFFER_DEPTH),
|
||||
.flit_payload_t (flit_payload_t ),
|
||||
.VC_NUM_OUTPORT (VC_NUM_INPUT_L),
|
||||
.VC_DEPTH_OUTPORT (VC_DEPTH_INPUT_L ),
|
||||
|
||||
.SENDER_TIMEOUT_EN (SENDER_TIMEOUT_EN ),
|
||||
.SENDER_TIMEOUT_THRESHOLD (SENDER_TIMEOUT_THRESHOLD),
|
||||
|
||||
.OUTPUT_TO_L (1)
|
||||
)
|
||||
v_sender_toL_u (
|
||||
.tx_flit_pend_o (rx_flit_pend [i][j][4+k] ),
|
||||
.tx_flit_v_o (rx_flit_v [i][j][4+k] ),
|
||||
.tx_flit_o (rx_flit [i][j][4+k] ),
|
||||
.tx_flit_vc_id_o (rx_flit_vc_id [i][j][4+k] ),
|
||||
.tx_flit_look_ahead_routing_o (rx_flit_look_ahead_routing [i][j][4+k] ),
|
||||
|
||||
.tx_lcrd_v_i (rx_lcrd_v [i][j][4+k] ),
|
||||
.tx_lcrd_id_i (rx_lcrd_id [i][j][4+k] ),
|
||||
|
||||
// sender id = x_posotion*(NODE_NUM_Y_DIMESION*LOCAL_PORT_NUM) + y_posotion*LOCAL_PORT_NUM + local_port_id
|
||||
.new_test_vld_i (new_test_vld [i*(NODE_NUM_Y_DIMESION*LOCAL_PORT_NUM) + j*LOCAL_PORT_NUM + k] ),
|
||||
.new_test_i (new_test [i*(NODE_NUM_Y_DIMESION*LOCAL_PORT_NUM) + j*LOCAL_PORT_NUM + k] ),
|
||||
.new_test_rdy_o (new_test_rdy [i*(NODE_NUM_Y_DIMESION*LOCAL_PORT_NUM) + j*LOCAL_PORT_NUM + k] ),
|
||||
|
||||
.new_scoreboard_entry_vld_o (new_scoreboard_entry_vld [i*(NODE_NUM_Y_DIMESION*LOCAL_PORT_NUM) + j*LOCAL_PORT_NUM + k] ),
|
||||
.new_scoreboard_entry_o (new_scoreboard_entry [i*(NODE_NUM_Y_DIMESION*LOCAL_PORT_NUM) + j*LOCAL_PORT_NUM + k] ),
|
||||
.new_scoreboard_entry_rdy_i (new_scoreboard_entry_rdy [i*(NODE_NUM_Y_DIMESION*LOCAL_PORT_NUM) + j*LOCAL_PORT_NUM + k] ),
|
||||
|
||||
.node_id_i (sender_node_id [i*(NODE_NUM_Y_DIMESION*LOCAL_PORT_NUM) + j*LOCAL_PORT_NUM + k] ),
|
||||
|
||||
.mcycle_i (mcycle),
|
||||
|
||||
.clk (clk ),
|
||||
.rstn (rstn)
|
||||
);
|
||||
end
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
||||
logic [RECEIVER_NUM-1:0] check_scoreboard_vld;
|
||||
receiver_info_t [RECEIVER_NUM-1:0] check_scoreboard;
|
||||
logic [RECEIVER_NUM-1:0] check_scoreboard_rdy;
|
||||
node_id_t [RECEIVER_NUM-1:0] receiver_node_id;
|
||||
|
||||
// local port map to receiver number
|
||||
// receiver id = x_posotion*(NODE_NUM_Y_DIMESION*LOCAL_PORT_NUM) + y_posotion*LOCAL_PORT_NUM + local_port_id
|
||||
// 7 8 17 16
|
||||
// \ | | /
|
||||
// 6 - (0,2) -- (1,2) - 15
|
||||
// 5 | | 14
|
||||
// \ | | /
|
||||
// 4 - (0,1) -- (1,1) - 13
|
||||
// / | | \
|
||||
// 3 | | 12
|
||||
// 2 - (0,0) -- (1,0) - 11
|
||||
// / | | \
|
||||
// 1 0 9 10
|
||||
|
||||
generate
|
||||
for(i = 0; i < NODE_NUM_X_DIMESION; i++) begin: gen_receiver_node_id_x_dimesion
|
||||
for(j = 0; j < NODE_NUM_Y_DIMESION; j++) begin: gen_receiver_node_id_y_dimesion
|
||||
for(k = 0; k < LOCAL_PORT_NUM; k++) begin: gen_receiver_node_id_device_port
|
||||
assign receiver_node_id[i*(NODE_NUM_Y_DIMESION*LOCAL_PORT_NUM) + j*LOCAL_PORT_NUM + k].x_position = i;
|
||||
assign receiver_node_id[i*(NODE_NUM_Y_DIMESION*LOCAL_PORT_NUM) + j*LOCAL_PORT_NUM + k].y_position = j;
|
||||
assign receiver_node_id[i*(NODE_NUM_Y_DIMESION*LOCAL_PORT_NUM) + j*LOCAL_PORT_NUM + k].device_port = k;
|
||||
assign receiver_node_id[i*(NODE_NUM_Y_DIMESION*LOCAL_PORT_NUM) + j*LOCAL_PORT_NUM + k].device_id = '0;
|
||||
end
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
for(i = 0; i < NODE_NUM_X_DIMESION; i++) begin: gen_v_receiver_x_dimesion
|
||||
for(j = 0; j < NODE_NUM_Y_DIMESION; j++) begin: gen_v_receiver_y_dimesion
|
||||
for(k = 0; k < LOCAL_PORT_NUM; k++) begin: gen_v_sender_device_port
|
||||
v_receiver
|
||||
#(
|
||||
.flit_payload_t (flit_payload_t )
|
||||
)
|
||||
v_receiver_u (
|
||||
.rx_flit_pend_i (tx_flit_pend [i][j][4+k] ),
|
||||
.rx_flit_v_i (tx_flit_v [i][j][4+k] ),
|
||||
.rx_flit_i (tx_flit [i][j][4+k] ),
|
||||
.rx_flit_vc_id_i (tx_flit_vc_id [i][j][4+k] ),
|
||||
.rx_flit_look_ahead_routing_i (tx_flit_look_ahead_routing [i][j][4+k] ),
|
||||
|
||||
.rx_lcrd_v_o (tx_lcrd_v [i][j][4+k] ),
|
||||
.rx_lcrd_id_o (tx_lcrd_id [i][j][4+k] ),
|
||||
|
||||
// receiver id = x_posotion*(NODE_NUM_Y_DIMESION*LOCAL_PORT_NUM) + y_posotion*LOCAL_PORT_NUM + local_port_id
|
||||
.check_scoreboard_vld_o (check_scoreboard_vld [i*(NODE_NUM_Y_DIMESION*LOCAL_PORT_NUM) + j*LOCAL_PORT_NUM + k] ),
|
||||
.check_scoreboard_o (check_scoreboard [i*(NODE_NUM_Y_DIMESION*LOCAL_PORT_NUM) + j*LOCAL_PORT_NUM + k] ),
|
||||
.check_scoreboard_rdy_i (check_scoreboard_rdy [i*(NODE_NUM_Y_DIMESION*LOCAL_PORT_NUM) + j*LOCAL_PORT_NUM + k] ),
|
||||
|
||||
.node_id_i (receiver_node_id [i*(NODE_NUM_Y_DIMESION*LOCAL_PORT_NUM) + j*LOCAL_PORT_NUM + k] ),
|
||||
|
||||
.clk (clk ),
|
||||
.rstn (rstn)
|
||||
);
|
||||
end
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
||||
v_scoreboard
|
||||
#(
|
||||
.SCOREBOARD_ENTRY_NUM_PER_SENDER (SCOREBOARD_ENTRY_NUM_PER_SENDER ),
|
||||
.SENDER_NUM (SENDER_NUM ),
|
||||
.RECEIVER_NUM (RECEIVER_NUM ),
|
||||
|
||||
.NODE_NUM_X_DIMESION (NODE_NUM_X_DIMESION ),
|
||||
.NODE_NUM_Y_DIMESION (NODE_NUM_Y_DIMESION ),
|
||||
.LOCAL_PORT_NUM (LOCAL_PORT_NUM ),
|
||||
|
||||
.ASSUMED_SYSTEM_FREQUENCY ((1<<30) )
|
||||
)
|
||||
v_scoreboard_u (
|
||||
.new_scoreboard_entry_vld_i (new_scoreboard_entry_vld ),
|
||||
.new_scoreboard_entry_i (new_scoreboard_entry ),
|
||||
.new_scoreboard_entry_rdy_o (new_scoreboard_entry_rdy ),
|
||||
|
||||
.check_scoreboard_vld_i (check_scoreboard_vld ),
|
||||
.check_scoreboard_i (check_scoreboard ),
|
||||
.check_scoreboard_rdy_o (check_scoreboard_rdy ),
|
||||
|
||||
.mcycle_i (mcycle ),
|
||||
|
||||
.clk (clk ),
|
||||
.rstn (rstn)
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//clock generate
|
||||
initial begin
|
||||
clk = 1'b0;
|
||||
forever #5 clk = ~clk;
|
||||
end
|
||||
|
||||
//reset generate
|
||||
initial begin
|
||||
rstn = 1'b0;
|
||||
#30;
|
||||
rstn = 1'b1;
|
||||
end
|
||||
|
||||
initial begin
|
||||
int dumpon = 1;
|
||||
int vcdplus = 0;
|
||||
$value$plusargs("dumpon=%d", dumpon);
|
||||
$value$plusargs("vcdplus=%d", vcdplus);
|
||||
|
||||
if (dumpon > 0) begin
|
||||
// $fsdbDumpvars(0, tb_mesh);
|
||||
// $fsdbDumpvars("+struct");
|
||||
// $fsdbDumpvars("+mda");
|
||||
// $fsdbDumpvars("+all");
|
||||
// $fsdbDumpon;
|
||||
$vcdpluson();
|
||||
end
|
||||
if (vcdplus > 0) begin
|
||||
$vcdpluson();
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
559
tb/tb_single_router.sv
Normal file
559
tb/tb_single_router.sv
Normal file
@@ -0,0 +1,559 @@
|
||||
module tb_single_router
|
||||
import rvh_noc_pkg::*;
|
||||
import v_noc_pkg::*;
|
||||
#(
|
||||
// router parameters
|
||||
parameter INPUT_PORT_NUM = INPUT_PORT_NUMBER,
|
||||
parameter OUTPUT_PORT_NUM = OUTPUT_PORT_NUMBER,
|
||||
parameter LOCAL_PORT_NUM = INPUT_PORT_NUM-4,
|
||||
parameter type flit_payload_t = logic[FLIT_LENGTH-1:0],
|
||||
parameter VC_NUM_INPUT_N = 1+LOCAL_PORT_NUM,
|
||||
parameter VC_NUM_INPUT_S = 1+LOCAL_PORT_NUM,
|
||||
parameter VC_NUM_INPUT_E = 3+LOCAL_PORT_NUM,
|
||||
parameter VC_NUM_INPUT_W = 3+LOCAL_PORT_NUM,
|
||||
`ifdef ALLOW_SAME_ROUTER_L2L_TRANSFER
|
||||
parameter VC_NUM_INPUT_L = 4+LOCAL_PORT_NUM-1,
|
||||
`else
|
||||
parameter VC_NUM_INPUT_L = 4,
|
||||
`endif
|
||||
parameter SA_GLOBAL_INPUT_NUM_N = 3+LOCAL_PORT_NUM,
|
||||
parameter SA_GLOBAL_INPUT_NUM_S = 3+LOCAL_PORT_NUM,
|
||||
parameter SA_GLOBAL_INPUT_NUM_E = 1+LOCAL_PORT_NUM,
|
||||
parameter SA_GLOBAL_INPUT_NUM_W = 1+LOCAL_PORT_NUM,
|
||||
`ifdef ALLOW_SAME_ROUTER_L2L_TRANSFER
|
||||
parameter SA_GLOBAL_INPUT_NUM_L = 4+LOCAL_PORT_NUM-1,
|
||||
`else
|
||||
parameter SA_GLOBAL_INPUT_NUM_L = 4,
|
||||
`endif
|
||||
parameter VC_NUM_OUTPUT_N = 1+LOCAL_PORT_NUM,
|
||||
parameter VC_NUM_OUTPUT_S = 1+LOCAL_PORT_NUM,
|
||||
parameter VC_NUM_OUTPUT_E = 3+LOCAL_PORT_NUM,
|
||||
parameter VC_NUM_OUTPUT_W = 3+LOCAL_PORT_NUM,
|
||||
parameter VC_NUM_OUTPUT_L = 1,
|
||||
parameter VC_DEPTH_INPUT_N = VC_DEPTH_MAX,
|
||||
parameter VC_DEPTH_INPUT_S = VC_DEPTH_MAX,
|
||||
parameter VC_DEPTH_INPUT_E = VC_DEPTH_MAX,
|
||||
parameter VC_DEPTH_INPUT_W = VC_DEPTH_MAX,
|
||||
parameter VC_DEPTH_INPUT_L = VC_DEPTH_MAX,
|
||||
|
||||
// test_generator parameters
|
||||
parameter RANDOM_BIT_NUM = 32,
|
||||
|
||||
parameter SCOREBOARD_TIMEOUT_EN = 1,
|
||||
parameter SCOREBOARD_TIMEOUT_THRESHOLD = 256,
|
||||
|
||||
parameter TEST_CASE_NUM_PER_CYCLE = 10,
|
||||
|
||||
// scoreboard parameters
|
||||
parameter SCOREBOARD_ENTRY_NUM_PER_SENDER = 64,
|
||||
|
||||
// sender parameters
|
||||
parameter SENDER_TIMEOUT_EN = 1,
|
||||
parameter SENDER_TIMEOUT_THRESHOLD = 256,
|
||||
|
||||
// overall longest test cycle
|
||||
parameter LONGEST_TEST_CYCLE = 10000
|
||||
)
|
||||
(
|
||||
|
||||
);
|
||||
|
||||
genvar i;
|
||||
|
||||
// Ports
|
||||
logic [INPUT_PORT_NUM-1:0] rx_flit_pend_i;
|
||||
logic [INPUT_PORT_NUM-1:0] rx_flit_v_i;
|
||||
flit_payload_t [INPUT_PORT_NUM-1:0] rx_flit_i;
|
||||
logic [INPUT_PORT_NUM-1:0] [VC_ID_NUM_MAX_W-1:0] rx_flit_vc_id_i;
|
||||
io_port_t [INPUT_PORT_NUM-1:0] rx_flit_look_ahead_routing_i;
|
||||
|
||||
logic [OUTPUT_PORT_NUM-1:0] tx_flit_pend_o;
|
||||
logic [OUTPUT_PORT_NUM-1:0] tx_flit_v_o;
|
||||
flit_payload_t [OUTPUT_PORT_NUM-1:0] tx_flit_o;
|
||||
logic [OUTPUT_PORT_NUM-1:0][VC_ID_NUM_MAX_W-1:0] tx_flit_vc_id_o;
|
||||
io_port_t [OUTPUT_PORT_NUM-1:0] tx_flit_look_ahead_routing_o;
|
||||
|
||||
logic [INPUT_PORT_NUM-1:0] rx_lcrd_v_o;
|
||||
logic [INPUT_PORT_NUM-1:0][VC_ID_NUM_MAX_W-1:0] rx_lcrd_id_o;
|
||||
|
||||
logic [OUTPUT_PORT_NUM-1:0] tx_lcrd_v_i;
|
||||
logic [OUTPUT_PORT_NUM-1:0][VC_ID_NUM_MAX_W-1:0] tx_lcrd_id_i;
|
||||
|
||||
logic [NodeID_X_Width-1:0] node_id_x_ths_hop_i;
|
||||
logic [NodeID_Y_Width-1:0] node_id_y_ths_hop_i;
|
||||
|
||||
logic clk;
|
||||
logic rstn;
|
||||
|
||||
assign node_id_x_ths_hop_i = 2'b01;
|
||||
assign node_id_y_ths_hop_i = 2'b01;
|
||||
|
||||
vnet_router
|
||||
#(
|
||||
.INPUT_PORT_NUM(INPUT_PORT_NUM ),
|
||||
.OUTPUT_PORT_NUM(OUTPUT_PORT_NUM ),
|
||||
.flit_payload_t(flit_payload_t),
|
||||
.VC_NUM_INPUT_N(VC_NUM_INPUT_N ),
|
||||
.VC_NUM_INPUT_S(VC_NUM_INPUT_S ),
|
||||
.VC_NUM_INPUT_E(VC_NUM_INPUT_E ),
|
||||
.VC_NUM_INPUT_W(VC_NUM_INPUT_W ),
|
||||
.VC_NUM_INPUT_L(VC_NUM_INPUT_L ),
|
||||
.SA_GLOBAL_INPUT_NUM_N(SA_GLOBAL_INPUT_NUM_N ),
|
||||
.SA_GLOBAL_INPUT_NUM_S(SA_GLOBAL_INPUT_NUM_S ),
|
||||
.SA_GLOBAL_INPUT_NUM_E(SA_GLOBAL_INPUT_NUM_E ),
|
||||
.SA_GLOBAL_INPUT_NUM_W(SA_GLOBAL_INPUT_NUM_W ),
|
||||
.SA_GLOBAL_INPUT_NUM_L(SA_GLOBAL_INPUT_NUM_L ),
|
||||
.VC_NUM_OUTPUT_N(VC_NUM_OUTPUT_N ),
|
||||
.VC_NUM_OUTPUT_S(VC_NUM_OUTPUT_S ),
|
||||
.VC_NUM_OUTPUT_E(VC_NUM_OUTPUT_E ),
|
||||
.VC_NUM_OUTPUT_W(VC_NUM_OUTPUT_W ),
|
||||
.VC_NUM_OUTPUT_L(VC_NUM_OUTPUT_L ),
|
||||
.VC_DEPTH_INPUT_N(VC_DEPTH_INPUT_N ),
|
||||
.VC_DEPTH_INPUT_S(VC_DEPTH_INPUT_S ),
|
||||
.VC_DEPTH_INPUT_E(VC_DEPTH_INPUT_E ),
|
||||
.VC_DEPTH_INPUT_W(VC_DEPTH_INPUT_W ),
|
||||
.VC_DEPTH_INPUT_L(VC_DEPTH_INPUT_L )
|
||||
)
|
||||
vnet_router_dut (
|
||||
.rx_flit_pend_i (rx_flit_pend_i ),
|
||||
.rx_flit_v_i (rx_flit_v_i ),
|
||||
.rx_flit_i (rx_flit_i ),
|
||||
.rx_flit_vc_id_i (rx_flit_vc_id_i ),
|
||||
.rx_flit_look_ahead_routing_i (rx_flit_look_ahead_routing_i ),
|
||||
.tx_flit_pend_o (tx_flit_pend_o ),
|
||||
.tx_flit_v_o (tx_flit_v_o ),
|
||||
.tx_flit_o (tx_flit_o ),
|
||||
.tx_flit_vc_id_o (tx_flit_vc_id_o ),
|
||||
.tx_flit_look_ahead_routing_o (tx_flit_look_ahead_routing_o ),
|
||||
.rx_lcrd_v_o (rx_lcrd_v_o ),
|
||||
.rx_lcrd_id_o (rx_lcrd_id_o ),
|
||||
.tx_lcrd_v_i (tx_lcrd_v_i ),
|
||||
.tx_lcrd_id_i (tx_lcrd_id_i ),
|
||||
.node_id_x_ths_hop_i (node_id_x_ths_hop_i ),
|
||||
.node_id_y_ths_hop_i (node_id_y_ths_hop_i ),
|
||||
.clk (clk ),
|
||||
.rstn (rstn)
|
||||
);
|
||||
|
||||
// test generate
|
||||
logic [64-1:0] mcycle;
|
||||
node_id_t target_node;
|
||||
|
||||
int longest_test_cycle = LONGEST_TEST_CYCLE;
|
||||
int self_finish = 1;
|
||||
|
||||
initial begin
|
||||
$value$plusargs("longest_test_cycle=%d", longest_test_cycle);
|
||||
$value$plusargs("self_finish=%d", self_finish);
|
||||
end
|
||||
|
||||
always_ff @(posedge clk or negedge rstn) begin
|
||||
if(~rstn) begin
|
||||
mcycle <= '0;
|
||||
end else begin
|
||||
mcycle <= mcycle + 1;
|
||||
if(self_finish > 0) begin
|
||||
if(mcycle == longest_test_cycle) begin
|
||||
$finish();
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
logic [32-1:0] src_id_lfsr_seed;
|
||||
logic [32-1:0] tgt_id_lfsr_seed;
|
||||
logic [INPUT_PORT_NUM-1:0] new_test_vld;
|
||||
test_case_t [INPUT_PORT_NUM-1:0] new_test;
|
||||
logic [INPUT_PORT_NUM-1:0] new_test_rdy;
|
||||
|
||||
assign src_id_lfsr_seed = 32'hdeadbeef;
|
||||
assign tgt_id_lfsr_seed = 32'hbaadf00d;
|
||||
|
||||
v_test_generator
|
||||
#(
|
||||
.SENDER_NUM (INPUT_PORT_NUM ),
|
||||
.RANDOM_BIT_NUM (RANDOM_BIT_NUM ),
|
||||
.SCOREBOARD_TIMEOUT_EN (SCOREBOARD_TIMEOUT_EN ),
|
||||
.SCOREBOARD_TIMEOUT_THRESHOLD (SCOREBOARD_TIMEOUT_THRESHOLD ),
|
||||
.TEST_CASE_NUM_PER_CYCLE(TEST_CASE_NUM_PER_CYCLE ),
|
||||
.TEST_CASE_SINGLE_ROUTER(1 ),
|
||||
|
||||
.ASSUMED_SYSTEM_FREQUENCY((1<<30) )
|
||||
)
|
||||
v_test_generator_u (
|
||||
.new_test_vld_o (new_test_vld ),
|
||||
.new_test_o (new_test ),
|
||||
.new_test_rdy_i (new_test_rdy ),
|
||||
.src_id_lfsr_seed_i (src_id_lfsr_seed ^ mcycle[16+:32]),
|
||||
.tgt_id_lfsr_seed_i (tgt_id_lfsr_seed ^ mcycle[20+:32] ),
|
||||
.lfsr_update_en_i (&mcycle[16-1:0]),
|
||||
.mcycle_i (mcycle),
|
||||
.clk (clk ),
|
||||
.rstn (rstn)
|
||||
);
|
||||
|
||||
logic [INPUT_PORT_NUM-1:0] new_scoreboard_entry_vld;
|
||||
scoreboard_entry_t [INPUT_PORT_NUM-1:0] new_scoreboard_entry;
|
||||
logic [INPUT_PORT_NUM-1:0] new_scoreboard_entry_rdy;
|
||||
node_id_t [OUTPUT_PORT_NUM-1:0] sender_node_id;
|
||||
|
||||
// sender0 (1,2)
|
||||
// |
|
||||
// sender3 (0,1) - (1,1) - (2,1) sender2
|
||||
// | \
|
||||
// sender1 (1,0) (local) sender4
|
||||
|
||||
assign sender_node_id[0].x_position = 1;
|
||||
assign sender_node_id[0].y_position = 2;
|
||||
assign sender_node_id[0].device_port = '0;
|
||||
assign sender_node_id[0].device_id = '0;
|
||||
assign sender_node_id[1].x_position = 1;
|
||||
assign sender_node_id[1].y_position = 0;
|
||||
assign sender_node_id[1].device_port = '0;
|
||||
assign sender_node_id[1].device_id = '0;
|
||||
assign sender_node_id[2].x_position = 2;
|
||||
assign sender_node_id[2].y_position = 1;
|
||||
assign sender_node_id[2].device_port = '0;
|
||||
assign sender_node_id[2].device_id = '0;
|
||||
assign sender_node_id[3].x_position = 0;
|
||||
assign sender_node_id[3].y_position = 1;
|
||||
assign sender_node_id[3].device_port = '0;
|
||||
assign sender_node_id[3].device_id = '0;
|
||||
generate
|
||||
if(LOCAL_PORT_NUM > 0) begin: gen_have_local_sender_node_id
|
||||
for(i = 0; i < LOCAL_PORT_NUM; i++) begin: gen_local_sender_node_id
|
||||
assign sender_node_id[4+i].x_position = 1;
|
||||
assign sender_node_id[4+i].y_position = 1;
|
||||
assign sender_node_id[4+i].device_port = i;
|
||||
assign sender_node_id[4+i].device_id = '0;
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
v_sender
|
||||
#(
|
||||
.FLIT_BUFFER_DEPTH (8 ),
|
||||
.flit_payload_t (flit_payload_t ),
|
||||
.VC_NUM_OUTPORT (VC_NUM_INPUT_N),
|
||||
.VC_DEPTH_OUTPORT (VC_DEPTH_INPUT_N ),
|
||||
|
||||
.SENDER_TIMEOUT_EN (SENDER_TIMEOUT_EN ),
|
||||
.SENDER_TIMEOUT_THRESHOLD (SENDER_TIMEOUT_THRESHOLD),
|
||||
|
||||
.OUTPUT_TO_N (1)
|
||||
)
|
||||
v_sender_toN_u (
|
||||
.tx_flit_pend_o (rx_flit_pend_i [0] ),
|
||||
.tx_flit_v_o (rx_flit_v_i [0] ),
|
||||
.tx_flit_o (rx_flit_i [0] ),
|
||||
.tx_flit_vc_id_o (rx_flit_vc_id_i [0] ),
|
||||
.tx_flit_look_ahead_routing_o (rx_flit_look_ahead_routing_i [0] ),
|
||||
|
||||
.tx_lcrd_v_i (rx_lcrd_v_o [0] ),
|
||||
.tx_lcrd_id_i (rx_lcrd_id_o [0] ),
|
||||
|
||||
.new_test_vld_i (new_test_vld [0] ),
|
||||
.new_test_i (new_test [0] ),
|
||||
.new_test_rdy_o (new_test_rdy [0] ),
|
||||
|
||||
.new_scoreboard_entry_vld_o (new_scoreboard_entry_vld [0] ),
|
||||
.new_scoreboard_entry_o (new_scoreboard_entry [0] ),
|
||||
.new_scoreboard_entry_rdy_i (new_scoreboard_entry_rdy [0] ),
|
||||
|
||||
.node_id_i (sender_node_id [0] ),
|
||||
|
||||
.mcycle_i (mcycle),
|
||||
|
||||
.clk (clk ),
|
||||
.rstn (rstn)
|
||||
);
|
||||
|
||||
v_sender
|
||||
#(
|
||||
.FLIT_BUFFER_DEPTH (8 ),
|
||||
.flit_payload_t (flit_payload_t ),
|
||||
.VC_NUM_OUTPORT (VC_NUM_INPUT_S),
|
||||
.VC_DEPTH_OUTPORT (VC_DEPTH_INPUT_S ),
|
||||
|
||||
.SENDER_TIMEOUT_EN (SENDER_TIMEOUT_EN ),
|
||||
.SENDER_TIMEOUT_THRESHOLD (SENDER_TIMEOUT_THRESHOLD),
|
||||
|
||||
.OUTPUT_TO_S (1)
|
||||
)
|
||||
v_sender_toS_u (
|
||||
.tx_flit_pend_o (rx_flit_pend_i [1] ),
|
||||
.tx_flit_v_o (rx_flit_v_i [1] ),
|
||||
.tx_flit_o (rx_flit_i [1] ),
|
||||
.tx_flit_vc_id_o (rx_flit_vc_id_i [1] ),
|
||||
.tx_flit_look_ahead_routing_o (rx_flit_look_ahead_routing_i [1] ),
|
||||
|
||||
.tx_lcrd_v_i (rx_lcrd_v_o [1] ),
|
||||
.tx_lcrd_id_i (rx_lcrd_id_o [1] ),
|
||||
|
||||
.new_test_vld_i (new_test_vld [1] ),
|
||||
.new_test_i (new_test [1] ),
|
||||
.new_test_rdy_o (new_test_rdy [1] ),
|
||||
|
||||
.new_scoreboard_entry_vld_o (new_scoreboard_entry_vld [1] ),
|
||||
.new_scoreboard_entry_o (new_scoreboard_entry [1] ),
|
||||
.new_scoreboard_entry_rdy_i (new_scoreboard_entry_rdy [1] ),
|
||||
|
||||
.node_id_i (sender_node_id [1] ),
|
||||
|
||||
.mcycle_i (mcycle),
|
||||
|
||||
.clk (clk ),
|
||||
.rstn (rstn)
|
||||
);
|
||||
|
||||
v_sender
|
||||
#(
|
||||
.FLIT_BUFFER_DEPTH (8 ),
|
||||
.flit_payload_t (flit_payload_t ),
|
||||
.VC_NUM_OUTPORT (VC_NUM_INPUT_E),
|
||||
.VC_DEPTH_OUTPORT (VC_DEPTH_INPUT_E ),
|
||||
|
||||
.SENDER_TIMEOUT_EN (SENDER_TIMEOUT_EN ),
|
||||
.SENDER_TIMEOUT_THRESHOLD (SENDER_TIMEOUT_THRESHOLD),
|
||||
|
||||
.OUTPUT_TO_E (1)
|
||||
)
|
||||
v_sender_toE_u (
|
||||
.tx_flit_pend_o (rx_flit_pend_i [2] ),
|
||||
.tx_flit_v_o (rx_flit_v_i [2] ),
|
||||
.tx_flit_o (rx_flit_i [2] ),
|
||||
.tx_flit_vc_id_o (rx_flit_vc_id_i [2] ),
|
||||
.tx_flit_look_ahead_routing_o (rx_flit_look_ahead_routing_i [2] ),
|
||||
|
||||
.tx_lcrd_v_i (rx_lcrd_v_o [2] ),
|
||||
.tx_lcrd_id_i (rx_lcrd_id_o [2] ),
|
||||
|
||||
.new_test_vld_i (new_test_vld [2] ),
|
||||
.new_test_i (new_test [2] ),
|
||||
.new_test_rdy_o (new_test_rdy [2] ),
|
||||
|
||||
.new_scoreboard_entry_vld_o (new_scoreboard_entry_vld [2] ),
|
||||
.new_scoreboard_entry_o (new_scoreboard_entry [2] ),
|
||||
.new_scoreboard_entry_rdy_i (new_scoreboard_entry_rdy [2] ),
|
||||
|
||||
.node_id_i (sender_node_id [2] ),
|
||||
|
||||
.mcycle_i (mcycle),
|
||||
|
||||
.clk (clk ),
|
||||
.rstn (rstn)
|
||||
);
|
||||
|
||||
v_sender
|
||||
#(
|
||||
.FLIT_BUFFER_DEPTH (8 ),
|
||||
.flit_payload_t (flit_payload_t ),
|
||||
.VC_NUM_OUTPORT (VC_NUM_INPUT_W),
|
||||
.VC_DEPTH_OUTPORT (VC_DEPTH_INPUT_W ),
|
||||
|
||||
.SENDER_TIMEOUT_EN (SENDER_TIMEOUT_EN ),
|
||||
.SENDER_TIMEOUT_THRESHOLD (SENDER_TIMEOUT_THRESHOLD),
|
||||
|
||||
.OUTPUT_TO_W (1)
|
||||
)
|
||||
v_sender_toW_u (
|
||||
.tx_flit_pend_o (rx_flit_pend_i [3] ),
|
||||
.tx_flit_v_o (rx_flit_v_i [3] ),
|
||||
.tx_flit_o (rx_flit_i [3] ),
|
||||
.tx_flit_vc_id_o (rx_flit_vc_id_i [3] ),
|
||||
.tx_flit_look_ahead_routing_o (rx_flit_look_ahead_routing_i [3] ),
|
||||
|
||||
.tx_lcrd_v_i (rx_lcrd_v_o [3] ),
|
||||
.tx_lcrd_id_i (rx_lcrd_id_o [3] ),
|
||||
|
||||
.new_test_vld_i (new_test_vld [3] ),
|
||||
.new_test_i (new_test [3] ),
|
||||
.new_test_rdy_o (new_test_rdy [3] ),
|
||||
|
||||
.new_scoreboard_entry_vld_o (new_scoreboard_entry_vld [3] ),
|
||||
.new_scoreboard_entry_o (new_scoreboard_entry [3] ),
|
||||
.new_scoreboard_entry_rdy_i (new_scoreboard_entry_rdy [3] ),
|
||||
|
||||
.node_id_i (sender_node_id [3] ),
|
||||
|
||||
.mcycle_i (mcycle),
|
||||
|
||||
.clk (clk ),
|
||||
.rstn (rstn)
|
||||
);
|
||||
|
||||
generate
|
||||
for(i = 0; i < LOCAL_PORT_NUM; i++) begin
|
||||
v_sender
|
||||
#(
|
||||
.FLIT_BUFFER_DEPTH (8 ),
|
||||
.flit_payload_t (flit_payload_t ),
|
||||
.VC_NUM_OUTPORT (VC_NUM_INPUT_L),
|
||||
.VC_DEPTH_OUTPORT (VC_DEPTH_INPUT_L ),
|
||||
|
||||
.SENDER_TIMEOUT_EN (SENDER_TIMEOUT_EN ),
|
||||
.SENDER_TIMEOUT_THRESHOLD (SENDER_TIMEOUT_THRESHOLD),
|
||||
|
||||
.OUTPUT_TO_L (1)
|
||||
)
|
||||
v_sender_toL_u (
|
||||
.tx_flit_pend_o (rx_flit_pend_i [4+i] ),
|
||||
.tx_flit_v_o (rx_flit_v_i [4+i] ),
|
||||
.tx_flit_o (rx_flit_i [4+i] ),
|
||||
.tx_flit_vc_id_o (rx_flit_vc_id_i [4+i] ),
|
||||
.tx_flit_look_ahead_routing_o (rx_flit_look_ahead_routing_i [4+i] ),
|
||||
|
||||
.tx_lcrd_v_i (rx_lcrd_v_o [4+i] ),
|
||||
.tx_lcrd_id_i (rx_lcrd_id_o [4+i] ),
|
||||
|
||||
.new_test_vld_i (new_test_vld [4+i] ),
|
||||
.new_test_i (new_test [4+i] ),
|
||||
.new_test_rdy_o (new_test_rdy [4+i] ),
|
||||
|
||||
.new_scoreboard_entry_vld_o (new_scoreboard_entry_vld [4+i] ),
|
||||
.new_scoreboard_entry_o (new_scoreboard_entry [4+i] ),
|
||||
.new_scoreboard_entry_rdy_i (new_scoreboard_entry_rdy [4+i] ),
|
||||
|
||||
.node_id_i (sender_node_id [4+i] ),
|
||||
|
||||
.mcycle_i (mcycle),
|
||||
|
||||
.clk (clk ),
|
||||
.rstn (rstn)
|
||||
);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
||||
logic [OUTPUT_PORT_NUM-1:0] check_scoreboard_vld;
|
||||
receiver_info_t [OUTPUT_PORT_NUM-1:0] check_scoreboard;
|
||||
logic [OUTPUT_PORT_NUM-1:0] check_scoreboard_rdy;
|
||||
node_id_t [OUTPUT_PORT_NUM-1:0] receiver_node_id;
|
||||
|
||||
// receiver0 (1,2)
|
||||
// |
|
||||
// receiver3 (0,1) - (1,1) - (2,1) receiver2
|
||||
// | \
|
||||
// receiver1 (1,0) (local) receiver4
|
||||
|
||||
assign receiver_node_id[0].x_position = 1;
|
||||
assign receiver_node_id[0].y_position = 2;
|
||||
assign receiver_node_id[0].device_port = '0;
|
||||
assign receiver_node_id[0].device_id = '0;
|
||||
assign receiver_node_id[1].x_position = 1;
|
||||
assign receiver_node_id[1].y_position = 0;
|
||||
assign receiver_node_id[1].device_port = '0;
|
||||
assign receiver_node_id[1].device_id = '0;
|
||||
assign receiver_node_id[2].x_position = 2;
|
||||
assign receiver_node_id[2].y_position = 1;
|
||||
assign receiver_node_id[2].device_port = '0;
|
||||
assign receiver_node_id[2].device_id = '0;
|
||||
assign receiver_node_id[3].x_position = 0;
|
||||
assign receiver_node_id[3].y_position = 1;
|
||||
assign receiver_node_id[3].device_port = '0;
|
||||
assign receiver_node_id[3].device_id = '0;
|
||||
generate
|
||||
if(LOCAL_PORT_NUM > 0) begin: gen_have_local_receiver_node_id
|
||||
for(i = 0; i < LOCAL_PORT_NUM; i++) begin: gen_local_receiver_node_id
|
||||
assign receiver_node_id[4+i].x_position = 1;
|
||||
assign receiver_node_id[4+i].y_position = 1;
|
||||
assign receiver_node_id[4+i].device_port = i;
|
||||
assign receiver_node_id[4+i].device_id = '0;
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
for(i = 0; i < OUTPUT_PORT_NUM; i++) begin: gen_v_receiver
|
||||
v_receiver
|
||||
#(
|
||||
.flit_payload_t (flit_payload_t )
|
||||
)
|
||||
v_receiver_u (
|
||||
.rx_flit_pend_i (tx_flit_pend_o [i] ),
|
||||
.rx_flit_v_i (tx_flit_v_o [i] ),
|
||||
.rx_flit_i (tx_flit_o [i] ),
|
||||
.rx_flit_vc_id_i (tx_flit_vc_id_o [i] ),
|
||||
.rx_flit_look_ahead_routing_i (tx_flit_look_ahead_routing_o [i] ),
|
||||
|
||||
.rx_lcrd_v_o (tx_lcrd_v_i [i] ),
|
||||
.rx_lcrd_id_o (tx_lcrd_id_i [i] ),
|
||||
|
||||
.check_scoreboard_vld_o (check_scoreboard_vld [i] ),
|
||||
.check_scoreboard_o (check_scoreboard [i] ),
|
||||
.check_scoreboard_rdy_i (check_scoreboard_rdy [i] ),
|
||||
|
||||
.node_id_i (receiver_node_id [i] ),
|
||||
|
||||
.clk (clk ),
|
||||
.rstn (rstn)
|
||||
);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
||||
v_scoreboard
|
||||
#(
|
||||
.SCOREBOARD_ENTRY_NUM_PER_SENDER (SCOREBOARD_ENTRY_NUM_PER_SENDER ),
|
||||
.SENDER_NUM (INPUT_PORT_NUM ),
|
||||
.RECEIVER_NUM (OUTPUT_PORT_NUM ),
|
||||
|
||||
.NODE_NUM_X_DIMESION (NODE_NUM_X_DIMESION ),
|
||||
.NODE_NUM_Y_DIMESION (NODE_NUM_Y_DIMESION ),
|
||||
.LOCAL_PORT_NUM (LOCAL_PORT_NUM ),
|
||||
|
||||
.TEST_CASE_SINGLE_ROUTER (1),
|
||||
|
||||
.ASSUMED_SYSTEM_FREQUENCY ((1<<30) )
|
||||
)
|
||||
v_scoreboard_u (
|
||||
.new_scoreboard_entry_vld_i (new_scoreboard_entry_vld ),
|
||||
.new_scoreboard_entry_i (new_scoreboard_entry ),
|
||||
.new_scoreboard_entry_rdy_o (new_scoreboard_entry_rdy ),
|
||||
|
||||
.check_scoreboard_vld_i (check_scoreboard_vld ),
|
||||
.check_scoreboard_i (check_scoreboard ),
|
||||
.check_scoreboard_rdy_o (check_scoreboard_rdy ),
|
||||
|
||||
.mcycle_i (mcycle ),
|
||||
|
||||
.clk (clk ),
|
||||
.rstn (rstn)
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//clock generate
|
||||
initial begin
|
||||
clk = 1'b0;
|
||||
forever #5 clk = ~clk;
|
||||
end
|
||||
|
||||
//reset generate
|
||||
initial begin
|
||||
rstn = 1'b0;
|
||||
#30;
|
||||
rstn = 1'b1;
|
||||
end
|
||||
|
||||
initial begin
|
||||
int dumpon = 1;
|
||||
int vcdplus = 0;
|
||||
$value$plusargs("dumpon=%d", dumpon);
|
||||
$value$plusargs("vcdplus=%d", vcdplus);
|
||||
|
||||
if (dumpon > 0) begin
|
||||
$fsdbDumpvars(0, tb_single_router);
|
||||
$fsdbDumpvars("+struct");
|
||||
$fsdbDumpvars("+mda");
|
||||
$fsdbDumpvars("+all");
|
||||
$fsdbDumpon;
|
||||
end
|
||||
if (vcdplus > 0) begin
|
||||
$vcdpluson();
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
174
tb/testbench.sv
Normal file
174
tb/testbench.sv
Normal file
@@ -0,0 +1,174 @@
|
||||
module testbench
|
||||
import rvh_noc_pkg::*;
|
||||
#(
|
||||
// Parameters
|
||||
parameter INPUT_PORT_NUM = 5,
|
||||
parameter OUTPUT_PORT_NUM = 5,
|
||||
parameter type flit_payload_t = logic[FLIT_LENGTH-1:0],
|
||||
parameter VC_NUM_INPUT_N = 2,
|
||||
parameter VC_NUM_INPUT_S = 2,
|
||||
parameter VC_NUM_INPUT_E = 4,
|
||||
parameter VC_NUM_INPUT_W = 4,
|
||||
parameter VC_NUM_INPUT_L = 4,
|
||||
parameter SA_GLOBAL_INPUT_NUM_N = 4,
|
||||
parameter SA_GLOBAL_INPUT_NUM_S = 4,
|
||||
parameter SA_GLOBAL_INPUT_NUM_E = 2,
|
||||
parameter SA_GLOBAL_INPUT_NUM_W = 2,
|
||||
parameter SA_GLOBAL_INPUT_NUM_L = 4,
|
||||
parameter VC_NUM_OUTPUT_N = 2,
|
||||
parameter VC_NUM_OUTPUT_S = 2,
|
||||
parameter VC_NUM_OUTPUT_E = 4,
|
||||
parameter VC_NUM_OUTPUT_W = 4,
|
||||
parameter VC_NUM_OUTPUT_L = 1,
|
||||
parameter VC_DEPTH_INPUT_N = 2,
|
||||
parameter VC_DEPTH_INPUT_S = 2,
|
||||
parameter VC_DEPTH_INPUT_E = 2,
|
||||
parameter VC_DEPTH_INPUT_W = 2,
|
||||
parameter VC_DEPTH_INPUT_L = 2
|
||||
)
|
||||
(
|
||||
|
||||
);
|
||||
|
||||
// Ports
|
||||
logic [INPUT_PORT_NUM-1:0] rx_flit_pend_i;
|
||||
logic [INPUT_PORT_NUM-1:0] rx_flit_v_i;
|
||||
flit_payload_t [INPUT_PORT_NUM-1:0] rx_flit_i;
|
||||
io_port_t [INPUT_PORT_NUM-1:0] rx_flit_vc_id_i;
|
||||
io_port_t [INPUT_PORT_NUM-1:0] rx_flit_look_ahead_routing_i;
|
||||
|
||||
logic [OUTPUT_PORT_NUM-1:0] tx_flit_pend_o;
|
||||
logic [OUTPUT_PORT_NUM-1:0] tx_flit_v_o;
|
||||
flit_payload_t [OUTPUT_PORT_NUM-1:0] tx_flit_o;
|
||||
io_port_t [OUTPUT_PORT_NUM-1:0] tx_flit_vc_id_o;
|
||||
io_port_t [OUTPUT_PORT_NUM-1:0] tx_flit_look_ahead_routing_o;
|
||||
|
||||
logic [INPUT_PORT_NUM-1:0] rx_lcrd_v_o;
|
||||
logic [INPUT_PORT_NUM-1:0][VC_ID_NUM_MAX_W-1:0] rx_lcrd_id_o;
|
||||
|
||||
logic [OUTPUT_PORT_NUM-1:0] tx_lcrd_v_i;
|
||||
logic [OUTPUT_PORT_NUM-1:0][VC_ID_NUM_MAX_W-1:0] tx_lcrd_id_i;
|
||||
|
||||
logic [NodeID_X_Width-1:0] node_id_x_ths_hop_i;
|
||||
logic [NodeID_Y_Width-1:0] node_id_y_ths_hop_i;
|
||||
|
||||
logic clk;
|
||||
logic rstn;
|
||||
|
||||
vnet_router
|
||||
#(
|
||||
.INPUT_PORT_NUM(INPUT_PORT_NUM ),
|
||||
.OUTPUT_PORT_NUM(OUTPUT_PORT_NUM ),
|
||||
.flit_payload_t(flit_payload_t),
|
||||
.VC_NUM_INPUT_N(VC_NUM_INPUT_N ),
|
||||
.VC_NUM_INPUT_S(VC_NUM_INPUT_S ),
|
||||
.VC_NUM_INPUT_E(VC_NUM_INPUT_E ),
|
||||
.VC_NUM_INPUT_W(VC_NUM_INPUT_W ),
|
||||
.VC_NUM_INPUT_L(VC_NUM_INPUT_L ),
|
||||
.SA_GLOBAL_INPUT_NUM_N(SA_GLOBAL_INPUT_NUM_N ),
|
||||
.SA_GLOBAL_INPUT_NUM_S(SA_GLOBAL_INPUT_NUM_S ),
|
||||
.SA_GLOBAL_INPUT_NUM_E(SA_GLOBAL_INPUT_NUM_E ),
|
||||
.SA_GLOBAL_INPUT_NUM_W(SA_GLOBAL_INPUT_NUM_W ),
|
||||
.SA_GLOBAL_INPUT_NUM_L(SA_GLOBAL_INPUT_NUM_L ),
|
||||
.VC_NUM_OUTPUT_N(VC_NUM_OUTPUT_N ),
|
||||
.VC_NUM_OUTPUT_S(VC_NUM_OUTPUT_S ),
|
||||
.VC_NUM_OUTPUT_E(VC_NUM_OUTPUT_E ),
|
||||
.VC_NUM_OUTPUT_W(VC_NUM_OUTPUT_W ),
|
||||
.VC_NUM_OUTPUT_L(VC_NUM_OUTPUT_L ),
|
||||
.VC_DEPTH_INPUT_N(VC_DEPTH_INPUT_N ),
|
||||
.VC_DEPTH_INPUT_S(VC_DEPTH_INPUT_S ),
|
||||
.VC_DEPTH_INPUT_E(VC_DEPTH_INPUT_E ),
|
||||
.VC_DEPTH_INPUT_W(VC_DEPTH_INPUT_W ),
|
||||
.VC_DEPTH_INPUT_L(VC_DEPTH_INPUT_L )
|
||||
)
|
||||
vnet_router_dut (
|
||||
.rx_flit_pend_i (rx_flit_pend_i ),
|
||||
.rx_flit_v_i (rx_flit_v_i ),
|
||||
.rx_flit_i (rx_flit_i ),
|
||||
.rx_flit_vc_id_i (rx_flit_vc_id_i ),
|
||||
.rx_flit_look_ahead_routing_i (rx_flit_look_ahead_routing_i ),
|
||||
.tx_flit_pend_o (tx_flit_pend_o ),
|
||||
.tx_flit_v_o (tx_flit_v_o ),
|
||||
.tx_flit_o (tx_flit_o ),
|
||||
.tx_flit_vc_id_o (tx_flit_vc_id_o ),
|
||||
.tx_flit_look_ahead_routing_o (tx_flit_look_ahead_routing_o ),
|
||||
.rx_lcrd_v_o (rx_lcrd_v_o ),
|
||||
.rx_lcrd_id_o (rx_lcrd_id_o ),
|
||||
.tx_lcrd_v_i (tx_lcrd_v_i ),
|
||||
.tx_lcrd_id_i (tx_lcrd_id_i ),
|
||||
.node_id_x_ths_hop_i (node_id_x_ths_hop_i ),
|
||||
.node_id_y_ths_hop_i (node_id_y_ths_hop_i ),
|
||||
.clk (clk ),
|
||||
.rstn (rstn)
|
||||
);
|
||||
|
||||
// test generate
|
||||
flit_payload_t counter;
|
||||
node_id_t target_node;
|
||||
always_ff @(posedge clk or negedge rstn) begin
|
||||
if(~rstn) begin
|
||||
counter <= '0;
|
||||
end else begin
|
||||
counter <= counter + 1;
|
||||
if(counter == 'd1000) begin
|
||||
$finish();
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign node_id_x_ths_hop_i = 2'b01;
|
||||
assign node_id_y_ths_hop_i = 2'b01;
|
||||
|
||||
assign target_node.x_position = 1;
|
||||
assign target_node.y_position = 2;
|
||||
assign target_node.device_port = 0;
|
||||
assign target_node.device_id = 0;
|
||||
|
||||
always_comb begin
|
||||
rx_flit_pend_i = '1;
|
||||
rx_flit_v_i = '0;
|
||||
rx_flit_i = '0;
|
||||
rx_flit_vc_id_i = '0;
|
||||
rx_flit_look_ahead_routing_i = '0;
|
||||
if(counter[5:0] == '1) begin
|
||||
rx_flit_v_i [2] = 1'b1;
|
||||
rx_flit_i [2] = {{(128-7-4){1'b0}}, target_node, {4'b0}}; // x=1,y=2
|
||||
rx_flit_vc_id_i [2][1:0] = counter[7:6] ^ counter[9:8];
|
||||
rx_flit_look_ahead_routing_i[2] = N;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
//clock generate
|
||||
initial begin
|
||||
clk = 1'b0;
|
||||
forever #5 clk = ~clk;
|
||||
end
|
||||
|
||||
//reset generate
|
||||
initial begin
|
||||
rstn = 1'b0;
|
||||
#30;
|
||||
rstn = 1'b1;
|
||||
end
|
||||
|
||||
initial begin
|
||||
int dumpon = 1;
|
||||
int vcdplus = 0;
|
||||
$value$plusargs("dumpon=%d", dumpon);
|
||||
$value$plusargs("vcdplus=%d", vcdplus);
|
||||
|
||||
if (dumpon > 0) begin
|
||||
$fsdbDumpvars(0, testbench);
|
||||
$fsdbDumpvars("+struct");
|
||||
$fsdbDumpvars("+mda");
|
||||
$fsdbDumpvars("+all");
|
||||
$fsdbDumpon;
|
||||
end
|
||||
if (vcdplus > 0) begin
|
||||
$vcdpluson();
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
307
tb/top_mesh_syn.sv
Normal file
307
tb/top_mesh_syn.sv
Normal file
@@ -0,0 +1,307 @@
|
||||
module top_mesh_syn
|
||||
import rvh_noc_pkg::*;
|
||||
// import v_noc_pkg::*;
|
||||
#(
|
||||
// mesh parameters
|
||||
parameter NODE_NUM_X_DIMESION = 3,
|
||||
parameter NODE_NUM_Y_DIMESION = 3,
|
||||
|
||||
// router parameters
|
||||
parameter INPUT_PORT_NUM = INPUT_PORT_NUMBER,
|
||||
parameter OUTPUT_PORT_NUM = OUTPUT_PORT_NUMBER,
|
||||
parameter LOCAL_PORT_NUM = INPUT_PORT_NUM-4,
|
||||
parameter type flit_payload_t = logic[FLIT_LENGTH-1:0],
|
||||
parameter VC_NUM_INPUT_N = 1+LOCAL_PORT_NUM+QOS_VC_NUM_PER_INPUT,
|
||||
parameter VC_NUM_INPUT_S = 1+LOCAL_PORT_NUM+QOS_VC_NUM_PER_INPUT,
|
||||
parameter VC_NUM_INPUT_E = 3+LOCAL_PORT_NUM+QOS_VC_NUM_PER_INPUT,
|
||||
parameter VC_NUM_INPUT_W = 3+LOCAL_PORT_NUM+QOS_VC_NUM_PER_INPUT,
|
||||
`ifdef ALLOW_SAME_ROUTER_L2L_TRANSFER
|
||||
parameter VC_NUM_INPUT_L = 4+LOCAL_PORT_NUM-1+QOS_VC_NUM_PER_INPUT,
|
||||
`else
|
||||
parameter VC_NUM_INPUT_L = 4+QOS_VC_NUM_PER_INPUT,
|
||||
`endif
|
||||
parameter SA_GLOBAL_INPUT_NUM_N = 3+LOCAL_PORT_NUM,
|
||||
parameter SA_GLOBAL_INPUT_NUM_S = 3+LOCAL_PORT_NUM,
|
||||
parameter SA_GLOBAL_INPUT_NUM_E = 1+LOCAL_PORT_NUM,
|
||||
parameter SA_GLOBAL_INPUT_NUM_W = 1+LOCAL_PORT_NUM,
|
||||
`ifdef ALLOW_SAME_ROUTER_L2L_TRANSFER
|
||||
parameter SA_GLOBAL_INPUT_NUM_L = 4+LOCAL_PORT_NUM-1,
|
||||
`else
|
||||
parameter SA_GLOBAL_INPUT_NUM_L = 4,
|
||||
`endif
|
||||
parameter VC_NUM_OUTPUT_N = 1+LOCAL_PORT_NUM+QOS_VC_NUM_PER_INPUT,
|
||||
parameter VC_NUM_OUTPUT_S = 1+LOCAL_PORT_NUM+QOS_VC_NUM_PER_INPUT,
|
||||
parameter VC_NUM_OUTPUT_E = 3+LOCAL_PORT_NUM+QOS_VC_NUM_PER_INPUT,
|
||||
parameter VC_NUM_OUTPUT_W = 3+LOCAL_PORT_NUM+QOS_VC_NUM_PER_INPUT,
|
||||
parameter VC_NUM_OUTPUT_L = 1,
|
||||
parameter VC_DEPTH_INPUT_N = VC_DEPTH_MAX,
|
||||
parameter VC_DEPTH_INPUT_S = VC_DEPTH_MAX,
|
||||
parameter VC_DEPTH_INPUT_E = VC_DEPTH_MAX,
|
||||
parameter VC_DEPTH_INPUT_W = VC_DEPTH_MAX,
|
||||
parameter VC_DEPTH_INPUT_L = VC_DEPTH_MAX
|
||||
)
|
||||
(
|
||||
output logic [NODE_NUM_X_DIMESION-1:0][NODE_NUM_Y_DIMESION-1:0][LOCAL_PORT_NUM-1:0] tx_flit_pend_o,
|
||||
output logic [NODE_NUM_X_DIMESION-1:0][NODE_NUM_Y_DIMESION-1:0][LOCAL_PORT_NUM-1:0] tx_flit_v_o,
|
||||
output flit_payload_t [NODE_NUM_X_DIMESION-1:0][NODE_NUM_Y_DIMESION-1:0][LOCAL_PORT_NUM-1:0] tx_flit_o,
|
||||
output logic [NODE_NUM_X_DIMESION-1:0][NODE_NUM_Y_DIMESION-1:0][LOCAL_PORT_NUM-1:0][VC_ID_NUM_MAX_W-1:0] tx_flit_vc_id_o,
|
||||
output io_port_t [NODE_NUM_X_DIMESION-1:0][NODE_NUM_Y_DIMESION-1:0][LOCAL_PORT_NUM-1:0] tx_flit_look_ahead_routing_o,
|
||||
|
||||
input logic [NODE_NUM_X_DIMESION-1:0][NODE_NUM_Y_DIMESION-1:0][LOCAL_PORT_NUM-1:0] rx_flit_pend_i,
|
||||
input logic [NODE_NUM_X_DIMESION-1:0][NODE_NUM_Y_DIMESION-1:0][LOCAL_PORT_NUM-1:0] rx_flit_v_i,
|
||||
input flit_payload_t [NODE_NUM_X_DIMESION-1:0][NODE_NUM_Y_DIMESION-1:0][LOCAL_PORT_NUM-1:0] rx_flit_i,
|
||||
input logic [NODE_NUM_X_DIMESION-1:0][NODE_NUM_Y_DIMESION-1:0][LOCAL_PORT_NUM-1:0][VC_ID_NUM_MAX_W-1:0] rx_flit_vc_id_i,
|
||||
input io_port_t [NODE_NUM_X_DIMESION-1:0][NODE_NUM_Y_DIMESION-1:0][LOCAL_PORT_NUM-1:0] rx_flit_look_ahead_routing_i,
|
||||
|
||||
input logic [NODE_NUM_X_DIMESION-1:0][NODE_NUM_Y_DIMESION-1:0][LOCAL_PORT_NUM-1:0] tx_lcrd_v_i,
|
||||
input logic [NODE_NUM_X_DIMESION-1:0][NODE_NUM_Y_DIMESION-1:0][LOCAL_PORT_NUM-1:0][VC_ID_NUM_MAX_W-1:0] tx_lcrd_id_i,
|
||||
|
||||
output logic [NODE_NUM_X_DIMESION-1:0][NODE_NUM_Y_DIMESION-1:0][LOCAL_PORT_NUM-1:0] rx_lcrd_v_o,
|
||||
output logic [NODE_NUM_X_DIMESION-1:0][NODE_NUM_Y_DIMESION-1:0][LOCAL_PORT_NUM-1:0][VC_ID_NUM_MAX_W-1:0] rx_lcrd_id_o,
|
||||
|
||||
input logic clk,
|
||||
input logic rst
|
||||
|
||||
);
|
||||
|
||||
genvar i, j, k;
|
||||
|
||||
// Ports
|
||||
logic [NODE_NUM_X_DIMESION-1:0][NODE_NUM_Y_DIMESION-1:0][OUTPUT_PORT_NUM-1:0] tx_flit_pend;
|
||||
logic [NODE_NUM_X_DIMESION-1:0][NODE_NUM_Y_DIMESION-1:0][OUTPUT_PORT_NUM-1:0] tx_flit_v;
|
||||
flit_payload_t [NODE_NUM_X_DIMESION-1:0][NODE_NUM_Y_DIMESION-1:0][OUTPUT_PORT_NUM-1:0] tx_flit;
|
||||
logic [NODE_NUM_X_DIMESION-1:0][NODE_NUM_Y_DIMESION-1:0][OUTPUT_PORT_NUM-1:0][VC_ID_NUM_MAX_W-1:0] tx_flit_vc_id;
|
||||
io_port_t [NODE_NUM_X_DIMESION-1:0][NODE_NUM_Y_DIMESION-1:0][OUTPUT_PORT_NUM-1:0] tx_flit_look_ahead_routing;
|
||||
|
||||
logic [NODE_NUM_X_DIMESION-1:0][NODE_NUM_Y_DIMESION-1:0][OUTPUT_PORT_NUM-1:0] rx_flit_pend;
|
||||
logic [NODE_NUM_X_DIMESION-1:0][NODE_NUM_Y_DIMESION-1:0][OUTPUT_PORT_NUM-1:0] rx_flit_v;
|
||||
flit_payload_t [NODE_NUM_X_DIMESION-1:0][NODE_NUM_Y_DIMESION-1:0][OUTPUT_PORT_NUM-1:0] rx_flit;
|
||||
logic [NODE_NUM_X_DIMESION-1:0][NODE_NUM_Y_DIMESION-1:0][OUTPUT_PORT_NUM-1:0][VC_ID_NUM_MAX_W-1:0] rx_flit_vc_id;
|
||||
io_port_t [NODE_NUM_X_DIMESION-1:0][NODE_NUM_Y_DIMESION-1:0][OUTPUT_PORT_NUM-1:0] rx_flit_look_ahead_routing;
|
||||
|
||||
logic [NODE_NUM_X_DIMESION-1:0][NODE_NUM_Y_DIMESION-1:0][INPUT_PORT_NUM-1:0] tx_lcrd_v;
|
||||
logic [NODE_NUM_X_DIMESION-1:0][NODE_NUM_Y_DIMESION-1:0][INPUT_PORT_NUM-1:0][VC_ID_NUM_MAX_W-1:0] tx_lcrd_id;
|
||||
|
||||
logic [NODE_NUM_X_DIMESION-1:0][NODE_NUM_Y_DIMESION-1:0][INPUT_PORT_NUM-1:0] rx_lcrd_v;
|
||||
logic [NODE_NUM_X_DIMESION-1:0][NODE_NUM_Y_DIMESION-1:0][INPUT_PORT_NUM-1:0][VC_ID_NUM_MAX_W-1:0] rx_lcrd_id;
|
||||
|
||||
|
||||
logic [NODE_NUM_X_DIMESION-1:0][NODE_NUM_Y_DIMESION-1:0][NodeID_X_Width-1:0] node_id_x;
|
||||
logic [NODE_NUM_X_DIMESION-1:0][NODE_NUM_Y_DIMESION-1:0][NodeID_Y_Width-1:0] node_id_y;
|
||||
|
||||
|
||||
|
||||
|
||||
// generate mesh routers
|
||||
generate
|
||||
for(i = 0; i < NODE_NUM_X_DIMESION; i++) begin: gen_mesh_routers_x_dimesion
|
||||
for(j = 0; j < NODE_NUM_Y_DIMESION; j++) begin: gen_mesh_routers_y_dimesion
|
||||
vnet_router
|
||||
#(
|
||||
.INPUT_PORT_NUM(INPUT_PORT_NUM ),
|
||||
.OUTPUT_PORT_NUM(OUTPUT_PORT_NUM ),
|
||||
.flit_payload_t(flit_payload_t),
|
||||
.QOS_VC_NUM_PER_INPUT(QOS_VC_NUM_PER_INPUT),
|
||||
.VC_NUM_INPUT_N(VC_NUM_INPUT_N ),
|
||||
.VC_NUM_INPUT_S(VC_NUM_INPUT_S ),
|
||||
.VC_NUM_INPUT_E(VC_NUM_INPUT_E ),
|
||||
.VC_NUM_INPUT_W(VC_NUM_INPUT_W ),
|
||||
.VC_NUM_INPUT_L(VC_NUM_INPUT_L ),
|
||||
.SA_GLOBAL_INPUT_NUM_N(SA_GLOBAL_INPUT_NUM_N ),
|
||||
.SA_GLOBAL_INPUT_NUM_S(SA_GLOBAL_INPUT_NUM_S ),
|
||||
.SA_GLOBAL_INPUT_NUM_E(SA_GLOBAL_INPUT_NUM_E ),
|
||||
.SA_GLOBAL_INPUT_NUM_W(SA_GLOBAL_INPUT_NUM_W ),
|
||||
.SA_GLOBAL_INPUT_NUM_L(SA_GLOBAL_INPUT_NUM_L ),
|
||||
.VC_NUM_OUTPUT_N(VC_NUM_OUTPUT_N ),
|
||||
.VC_NUM_OUTPUT_S(VC_NUM_OUTPUT_S ),
|
||||
.VC_NUM_OUTPUT_E(VC_NUM_OUTPUT_E ),
|
||||
.VC_NUM_OUTPUT_W(VC_NUM_OUTPUT_W ),
|
||||
.VC_NUM_OUTPUT_L(VC_NUM_OUTPUT_L ),
|
||||
.VC_DEPTH_INPUT_N(VC_DEPTH_INPUT_N ),
|
||||
.VC_DEPTH_INPUT_S(VC_DEPTH_INPUT_S ),
|
||||
.VC_DEPTH_INPUT_E(VC_DEPTH_INPUT_E ),
|
||||
.VC_DEPTH_INPUT_W(VC_DEPTH_INPUT_W ),
|
||||
.VC_DEPTH_INPUT_L(VC_DEPTH_INPUT_L )
|
||||
)
|
||||
vnet_router_dut (
|
||||
.rx_flit_pend_i (rx_flit_pend [i][j] ),
|
||||
.rx_flit_v_i (rx_flit_v [i][j] ),
|
||||
.rx_flit_i (rx_flit [i][j] ),
|
||||
.rx_flit_vc_id_i (rx_flit_vc_id [i][j] ),
|
||||
.rx_flit_look_ahead_routing_i (rx_flit_look_ahead_routing [i][j] ),
|
||||
|
||||
.tx_flit_pend_o (tx_flit_pend [i][j] ),
|
||||
.tx_flit_v_o (tx_flit_v [i][j] ),
|
||||
.tx_flit_o (tx_flit [i][j] ),
|
||||
.tx_flit_vc_id_o (tx_flit_vc_id [i][j] ),
|
||||
.tx_flit_look_ahead_routing_o (tx_flit_look_ahead_routing [i][j] ),
|
||||
|
||||
.rx_lcrd_v_o (rx_lcrd_v [i][j] ),
|
||||
.rx_lcrd_id_o (rx_lcrd_id [i][j] ),
|
||||
|
||||
.tx_lcrd_v_i (tx_lcrd_v [i][j] ),
|
||||
.tx_lcrd_id_i (tx_lcrd_id [i][j] ),
|
||||
|
||||
.node_id_x_ths_hop_i (node_id_x [i][j] ),
|
||||
.node_id_y_ths_hop_i (node_id_y [i][j] ),
|
||||
|
||||
.clk (clk ),
|
||||
.rstn (rst)
|
||||
);
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// assign node id to each router
|
||||
generate
|
||||
for(i = 0; i < NODE_NUM_X_DIMESION; i++) begin: gen_node_id_x_x_dimesion
|
||||
for(j = 0; j < NODE_NUM_Y_DIMESION; j++) begin: gen_node_id_x_y_dimesion
|
||||
assign node_id_x [i][j] = i;
|
||||
end
|
||||
end
|
||||
for(i = 0; i < NODE_NUM_Y_DIMESION; i++) begin: gen_node_id_y_y_dimesion
|
||||
for(j = 0; j < NODE_NUM_X_DIMESION; j++) begin: gen_node_id_y_x_dimesion
|
||||
assign node_id_y [j][i] = i;
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// connect each router together
|
||||
generate
|
||||
for(i = 0; i < NODE_NUM_X_DIMESION; i++) begin: gen_connect_routers_ns_x_dimesion
|
||||
for(j = 0; j < NODE_NUM_Y_DIMESION-1; j++) begin: gen_connect_routers_ns_y_dimesion
|
||||
// connect N inport to S outport
|
||||
assign rx_flit_pend [i][j][0] = tx_flit_pend [i][j+1][1];
|
||||
assign rx_flit_v [i][j][0] = tx_flit_v [i][j+1][1];
|
||||
assign rx_flit [i][j][0] = tx_flit [i][j+1][1];
|
||||
assign rx_flit_vc_id [i][j][0] = tx_flit_vc_id [i][j+1][1];
|
||||
assign rx_flit_look_ahead_routing [i][j][0] = tx_flit_look_ahead_routing [i][j+1][1];
|
||||
|
||||
assign tx_lcrd_v [i][j][0] = rx_lcrd_v [i][j+1][1];
|
||||
assign tx_lcrd_id [i][j][0] = rx_lcrd_id [i][j+1][1];
|
||||
|
||||
// connect S inport to N outport
|
||||
assign rx_flit_pend [i][j+1][1] = tx_flit_pend [i][j][0];
|
||||
assign rx_flit_v [i][j+1][1] = tx_flit_v [i][j][0];
|
||||
assign rx_flit [i][j+1][1] = tx_flit [i][j][0];
|
||||
assign rx_flit_vc_id [i][j+1][1] = tx_flit_vc_id [i][j][0];
|
||||
assign rx_flit_look_ahead_routing [i][j+1][1] = tx_flit_look_ahead_routing [i][j][0];
|
||||
|
||||
assign tx_lcrd_v [i][j+1][1] = rx_lcrd_v [i][j][0];
|
||||
assign tx_lcrd_id [i][j+1][1] = rx_lcrd_id [i][j][0];
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
for(i = 0; i < NODE_NUM_Y_DIMESION; i++) begin: gen_connect_routers_ew_x_dimesion
|
||||
for(j = 0; j < NODE_NUM_X_DIMESION-1; j++) begin: gen_connect_routers_ew_y_dimesion
|
||||
// connect E inport to W outport
|
||||
assign rx_flit_pend [j][i][2] = tx_flit_pend [j+1][i][3];
|
||||
assign rx_flit_v [j][i][2] = tx_flit_v [j+1][i][3];
|
||||
assign rx_flit [j][i][2] = tx_flit [j+1][i][3];
|
||||
assign rx_flit_vc_id [j][i][2] = tx_flit_vc_id [j+1][i][3];
|
||||
assign rx_flit_look_ahead_routing [j][i][2] = tx_flit_look_ahead_routing [j+1][i][3];
|
||||
|
||||
assign tx_lcrd_v [j][i][2] = rx_lcrd_v [j+1][i][3];
|
||||
assign tx_lcrd_id [j][i][2] = rx_lcrd_id [j+1][i][3];
|
||||
|
||||
// connect W inport to E outport
|
||||
assign rx_flit_pend [j+1][i][3] = tx_flit_pend [j][i][2];
|
||||
assign rx_flit_v [j+1][i][3] = tx_flit_v [j][i][2];
|
||||
assign rx_flit [j+1][i][3] = tx_flit [j][i][2];
|
||||
assign rx_flit_vc_id [j+1][i][3] = tx_flit_vc_id [j][i][2];
|
||||
assign rx_flit_look_ahead_routing [j+1][i][3] = tx_flit_look_ahead_routing [j][i][2];
|
||||
|
||||
assign tx_lcrd_v [j+1][i][3] = rx_lcrd_v [j][i][2];
|
||||
assign tx_lcrd_id [j+1][i][3] = rx_lcrd_id [j][i][2];
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// other unused non-local ports, assign router rx to 0
|
||||
generate
|
||||
for(i = 0; i < NODE_NUM_X_DIMESION; i++) begin: gen_unused_non_local_ports_x_dimesion
|
||||
assign rx_flit_pend [i][NODE_NUM_Y_DIMESION-1][0] = '0;
|
||||
assign rx_flit_v [i][NODE_NUM_Y_DIMESION-1][0] = '0;
|
||||
assign rx_flit [i][NODE_NUM_Y_DIMESION-1][0] = '0;
|
||||
assign rx_flit_vc_id [i][NODE_NUM_Y_DIMESION-1][0] = '0;
|
||||
assign rx_flit_look_ahead_routing [i][NODE_NUM_Y_DIMESION-1][0] = '0;
|
||||
|
||||
assign tx_lcrd_v [i][NODE_NUM_Y_DIMESION-1][0] = '0;
|
||||
assign tx_lcrd_id [i][NODE_NUM_Y_DIMESION-1][0] = '0;
|
||||
|
||||
|
||||
assign rx_flit_pend [i][0][1] = '0;
|
||||
assign rx_flit_v [i][0][1] = '0;
|
||||
assign rx_flit [i][0][1] = '0;
|
||||
assign rx_flit_vc_id [i][0][1] = '0;
|
||||
assign rx_flit_look_ahead_routing [i][0][1] = '0;
|
||||
|
||||
assign tx_lcrd_v [i][0][1] = '0;
|
||||
assign tx_lcrd_id [i][0][1] = '0;
|
||||
end
|
||||
|
||||
for(i = 0; i < NODE_NUM_Y_DIMESION; i++) begin: gen_unused_non_local_ports_y_dimesion
|
||||
// connect E inport to W outport
|
||||
assign rx_flit_pend [NODE_NUM_X_DIMESION-1][i][2] = '0;
|
||||
assign rx_flit_v [NODE_NUM_X_DIMESION-1][i][2] = '0;
|
||||
assign rx_flit [NODE_NUM_X_DIMESION-1][i][2] = '0;
|
||||
assign rx_flit_vc_id [NODE_NUM_X_DIMESION-1][i][2] = '0;
|
||||
assign rx_flit_look_ahead_routing [NODE_NUM_X_DIMESION-1][i][2] = '0;
|
||||
|
||||
assign tx_lcrd_v [NODE_NUM_X_DIMESION-1][i][2] = '0;
|
||||
assign tx_lcrd_id [NODE_NUM_X_DIMESION-1][i][2] = '0;
|
||||
|
||||
// connect W inport to E outport
|
||||
assign rx_flit_pend [0][i][3] = '0;
|
||||
assign rx_flit_v [0][i][3] = '0;
|
||||
assign rx_flit [0][i][3] = '0;
|
||||
assign rx_flit_vc_id [0][i][3] = '0;
|
||||
assign rx_flit_look_ahead_routing [0][i][3] = '0;
|
||||
|
||||
assign tx_lcrd_v [0][i][3] = '0;
|
||||
assign tx_lcrd_id [0][i][3] = '0;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
||||
|
||||
generate
|
||||
for(i = 0; i < NODE_NUM_X_DIMESION; i++) begin: gen_v_sender_x_dimesion
|
||||
for(j = 0; j < NODE_NUM_Y_DIMESION; j++) begin: gen_v_sender_y_dimesion
|
||||
for(k = 0; k < LOCAL_PORT_NUM; k++) begin: gen_v_sender_device_port
|
||||
assign rx_flit_pend [i][j][4+k] = rx_flit_pend_i [i][j][k];
|
||||
assign rx_flit_v [i][j][4+k] = rx_flit_v_i [i][j][k];
|
||||
assign rx_flit [i][j][4+k] = rx_flit_i [i][j][k];
|
||||
assign rx_flit_vc_id [i][j][4+k] = rx_flit_vc_id_i [i][j][k];
|
||||
assign rx_flit_look_ahead_routing [i][j][4+k] = rx_flit_look_ahead_routing_i [i][j][k];
|
||||
|
||||
assign rx_lcrd_v_o [i][j][k] = rx_lcrd_v [i][j][4+k];
|
||||
assign rx_lcrd_id_o [i][j][k] = rx_lcrd_id [i][j][4+k];
|
||||
end
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
||||
generate
|
||||
for(i = 0; i < NODE_NUM_X_DIMESION; i++) begin: gen_v_receiver_x_dimesion
|
||||
for(j = 0; j < NODE_NUM_Y_DIMESION; j++) begin: gen_v_receiver_y_dimesion
|
||||
for(k = 0; k < LOCAL_PORT_NUM; k++) begin: gen_v_sender_device_port
|
||||
assign tx_flit_pend_o [i][j][k] = tx_flit_pend [i][j][4+k];
|
||||
assign tx_flit_v_o [i][j][k] = tx_flit_v [i][j][4+k];
|
||||
assign tx_flit_o [i][j][k] = tx_flit [i][j][4+k];
|
||||
assign tx_flit_vc_id_o [i][j][k] = tx_flit_vc_id [i][j][4+k];
|
||||
assign tx_flit_look_ahead_routing_o [i][j][k] = tx_flit_look_ahead_routing [i][j][4+k];
|
||||
|
||||
assign tx_lcrd_v [i][j][4+k] = tx_lcrd_v_i [i][j][k];
|
||||
assign tx_lcrd_id [i][j][4+k] = tx_lcrd_id_i [i][j][k];
|
||||
end
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
||||
|
||||
endmodule
|
||||
121
tb/top_single_router_syn.sv
Normal file
121
tb/top_single_router_syn.sv
Normal file
@@ -0,0 +1,121 @@
|
||||
module top_single_router_syn
|
||||
import rvh_noc_pkg::*;
|
||||
// import v_noc_pkg::*;
|
||||
#(
|
||||
// mesh parameters
|
||||
parameter NODE_NUM_X_DIMESION = 3,
|
||||
parameter NODE_NUM_Y_DIMESION = 3,
|
||||
|
||||
// router parameters
|
||||
parameter INPUT_PORT_NUM = INPUT_PORT_NUMBER,
|
||||
parameter OUTPUT_PORT_NUM = OUTPUT_PORT_NUMBER,
|
||||
parameter LOCAL_PORT_NUM = INPUT_PORT_NUM-4,
|
||||
parameter type flit_payload_t = logic[FLIT_LENGTH-1:0],
|
||||
parameter VC_NUM_INPUT_N = 1+LOCAL_PORT_NUM+QOS_VC_NUM_PER_INPUT,
|
||||
parameter VC_NUM_INPUT_S = 1+LOCAL_PORT_NUM+QOS_VC_NUM_PER_INPUT,
|
||||
parameter VC_NUM_INPUT_E = 3+LOCAL_PORT_NUM+QOS_VC_NUM_PER_INPUT,
|
||||
parameter VC_NUM_INPUT_W = 3+LOCAL_PORT_NUM+QOS_VC_NUM_PER_INPUT,
|
||||
`ifdef ALLOW_SAME_ROUTER_L2L_TRANSFER
|
||||
parameter VC_NUM_INPUT_L = 4+LOCAL_PORT_NUM-1+QOS_VC_NUM_PER_INPUT,
|
||||
`else
|
||||
parameter VC_NUM_INPUT_L = 4+QOS_VC_NUM_PER_INPUT,
|
||||
`endif
|
||||
parameter SA_GLOBAL_INPUT_NUM_N = 3+LOCAL_PORT_NUM,
|
||||
parameter SA_GLOBAL_INPUT_NUM_S = 3+LOCAL_PORT_NUM,
|
||||
parameter SA_GLOBAL_INPUT_NUM_E = 1+LOCAL_PORT_NUM,
|
||||
parameter SA_GLOBAL_INPUT_NUM_W = 1+LOCAL_PORT_NUM,
|
||||
`ifdef ALLOW_SAME_ROUTER_L2L_TRANSFER
|
||||
parameter SA_GLOBAL_INPUT_NUM_L = 4+LOCAL_PORT_NUM-1,
|
||||
`else
|
||||
parameter SA_GLOBAL_INPUT_NUM_L = 4,
|
||||
`endif
|
||||
parameter VC_NUM_OUTPUT_N = 1+LOCAL_PORT_NUM+QOS_VC_NUM_PER_INPUT,
|
||||
parameter VC_NUM_OUTPUT_S = 1+LOCAL_PORT_NUM+QOS_VC_NUM_PER_INPUT,
|
||||
parameter VC_NUM_OUTPUT_E = 3+LOCAL_PORT_NUM+QOS_VC_NUM_PER_INPUT,
|
||||
parameter VC_NUM_OUTPUT_W = 3+LOCAL_PORT_NUM+QOS_VC_NUM_PER_INPUT,
|
||||
parameter VC_NUM_OUTPUT_L = 1,
|
||||
parameter VC_DEPTH_INPUT_N = VC_DEPTH_MAX,
|
||||
parameter VC_DEPTH_INPUT_S = VC_DEPTH_MAX,
|
||||
parameter VC_DEPTH_INPUT_E = VC_DEPTH_MAX,
|
||||
parameter VC_DEPTH_INPUT_W = VC_DEPTH_MAX,
|
||||
parameter VC_DEPTH_INPUT_L = VC_DEPTH_MAX
|
||||
)
|
||||
(
|
||||
output logic [OUTPUT_PORT_NUM-1:0] tx_flit_pend_o,
|
||||
output logic [OUTPUT_PORT_NUM-1:0] tx_flit_v_o,
|
||||
output flit_payload_t [OUTPUT_PORT_NUM-1:0] tx_flit_o,
|
||||
output logic [OUTPUT_PORT_NUM-1:0][VC_ID_NUM_MAX_W-1:0] tx_flit_vc_id_o,
|
||||
output io_port_t [OUTPUT_PORT_NUM-1:0] tx_flit_look_ahead_routing_o,
|
||||
|
||||
input logic [INPUT_PORT_NUM-1:0] rx_flit_pend_i,
|
||||
input logic [INPUT_PORT_NUM-1:0] rx_flit_v_i,
|
||||
input flit_payload_t [INPUT_PORT_NUM-1:0] rx_flit_i,
|
||||
input logic [INPUT_PORT_NUM-1:0][VC_ID_NUM_MAX_W-1:0] rx_flit_vc_id_i,
|
||||
input io_port_t [INPUT_PORT_NUM-1:0] rx_flit_look_ahead_routing_i,
|
||||
|
||||
input logic [OUTPUT_PORT_NUM-1:0] tx_lcrd_v_i,
|
||||
input logic [OUTPUT_PORT_NUM-1:0][VC_ID_NUM_MAX_W-1:0] tx_lcrd_id_i,
|
||||
|
||||
output logic [INPUT_PORT_NUM-1:0] rx_lcrd_v_o,
|
||||
output logic [INPUT_PORT_NUM-1:0][VC_ID_NUM_MAX_W-1:0] rx_lcrd_id_o,
|
||||
|
||||
input logic clk,
|
||||
input logic rst
|
||||
|
||||
);
|
||||
|
||||
// router
|
||||
vnet_router
|
||||
#(
|
||||
.INPUT_PORT_NUM(INPUT_PORT_NUM ),
|
||||
.OUTPUT_PORT_NUM(OUTPUT_PORT_NUM ),
|
||||
.flit_payload_t(flit_payload_t),
|
||||
.QOS_VC_NUM_PER_INPUT(QOS_VC_NUM_PER_INPUT),
|
||||
.VC_NUM_INPUT_N(VC_NUM_INPUT_N ),
|
||||
.VC_NUM_INPUT_S(VC_NUM_INPUT_S ),
|
||||
.VC_NUM_INPUT_E(VC_NUM_INPUT_E ),
|
||||
.VC_NUM_INPUT_W(VC_NUM_INPUT_W ),
|
||||
.VC_NUM_INPUT_L(VC_NUM_INPUT_L ),
|
||||
.SA_GLOBAL_INPUT_NUM_N(SA_GLOBAL_INPUT_NUM_N ),
|
||||
.SA_GLOBAL_INPUT_NUM_S(SA_GLOBAL_INPUT_NUM_S ),
|
||||
.SA_GLOBAL_INPUT_NUM_E(SA_GLOBAL_INPUT_NUM_E ),
|
||||
.SA_GLOBAL_INPUT_NUM_W(SA_GLOBAL_INPUT_NUM_W ),
|
||||
.SA_GLOBAL_INPUT_NUM_L(SA_GLOBAL_INPUT_NUM_L ),
|
||||
.VC_NUM_OUTPUT_N(VC_NUM_OUTPUT_N ),
|
||||
.VC_NUM_OUTPUT_S(VC_NUM_OUTPUT_S ),
|
||||
.VC_NUM_OUTPUT_E(VC_NUM_OUTPUT_E ),
|
||||
.VC_NUM_OUTPUT_W(VC_NUM_OUTPUT_W ),
|
||||
.VC_NUM_OUTPUT_L(VC_NUM_OUTPUT_L ),
|
||||
.VC_DEPTH_INPUT_N(VC_DEPTH_INPUT_N ),
|
||||
.VC_DEPTH_INPUT_S(VC_DEPTH_INPUT_S ),
|
||||
.VC_DEPTH_INPUT_E(VC_DEPTH_INPUT_E ),
|
||||
.VC_DEPTH_INPUT_W(VC_DEPTH_INPUT_W ),
|
||||
.VC_DEPTH_INPUT_L(VC_DEPTH_INPUT_L )
|
||||
)
|
||||
vnet_router_dut (
|
||||
.rx_flit_pend_i (rx_flit_pend_i ),
|
||||
.rx_flit_v_i (rx_flit_v_i ),
|
||||
.rx_flit_i (rx_flit_i ),
|
||||
.rx_flit_vc_id_i (rx_flit_vc_id_i ),
|
||||
.rx_flit_look_ahead_routing_i (rx_flit_look_ahead_routing_i ),
|
||||
|
||||
.tx_flit_pend_o (tx_flit_pend_o ),
|
||||
.tx_flit_v_o (tx_flit_v_o ),
|
||||
.tx_flit_o (tx_flit_o ),
|
||||
.tx_flit_vc_id_o (tx_flit_vc_id_o ),
|
||||
.tx_flit_look_ahead_routing_o (tx_flit_look_ahead_routing_o ),
|
||||
|
||||
.rx_lcrd_v_o (rx_lcrd_v_o ),
|
||||
.rx_lcrd_id_o (rx_lcrd_id_o ),
|
||||
|
||||
.tx_lcrd_v_i (tx_lcrd_v_i ),
|
||||
.tx_lcrd_id_i (tx_lcrd_id_i ),
|
||||
|
||||
.node_id_x_ths_hop_i ('0 ),
|
||||
.node_id_y_ths_hop_i ('0 ),
|
||||
|
||||
.clk (clk ),
|
||||
.rstn (rst)
|
||||
);
|
||||
|
||||
endmodule
|
||||
53
tb/v_noc_pkg.sv
Normal file
53
tb/v_noc_pkg.sv
Normal file
@@ -0,0 +1,53 @@
|
||||
`ifndef __V_NOC_PKG_SV__
|
||||
`define __V_NOC_PKG_SV__
|
||||
|
||||
// `define V_ROUTER_PM_PRINT_EN
|
||||
`define V_INPORT_PRINT_EN
|
||||
|
||||
package v_noc_pkg;
|
||||
import rvh_noc_pkg::*;
|
||||
|
||||
localparam SCOREBOARD_TIMEOUT_W = 15;
|
||||
localparam SENDER_TIMEOUT_W = 15;
|
||||
localparam FLIT_DATA_LENGTH = FLIT_LENGTH-QoS_Value_Width-$bits(node_id_t)*2-TxnID_Width;
|
||||
|
||||
typedef struct packed {
|
||||
logic [FLIT_DATA_LENGTH-1:0] flit_data;
|
||||
flit_dec_t flit_head;
|
||||
logic [SCOREBOARD_TIMEOUT_W-1:0] timeout_threshold;
|
||||
logic [64-1:0] mcycle_when_generated; // the cycle when the test case is generated
|
||||
logic [QoS_Value_Width-1:0] qos_value;
|
||||
} test_case_t;
|
||||
|
||||
typedef struct packed {
|
||||
node_id_t tgt_id; // target id
|
||||
node_id_t src_id; // source id
|
||||
logic [TxnID_Width-1:0] txn_id; // transaction id
|
||||
logic [SCOREBOARD_TIMEOUT_W-1:0] timeout_threshold;
|
||||
io_port_t look_ahead_routing;
|
||||
logic [VC_ID_NUM_MAX_W-1:0] inport_vc_id;
|
||||
logic [64-1:0] generated_mcycle; // when it geerated by test generate
|
||||
logic [64-1:0] sent_mcycle; // when it inject into noc
|
||||
logic [FLIT_DATA_LENGTH-1:0] flit_data;
|
||||
logic [QoS_Value_Width-1:0] qos_value;
|
||||
|
||||
// TODO: routing path
|
||||
} scoreboard_entry_t;
|
||||
|
||||
typedef struct packed {
|
||||
logic [SCOREBOARD_TIMEOUT_W-1:0] timeout_counter;
|
||||
} scoreboard_timer_t;
|
||||
|
||||
typedef struct packed {
|
||||
logic [SENDER_TIMEOUT_W-1:0] timeout_counter;
|
||||
} sender_timer_t;
|
||||
|
||||
typedef struct packed {
|
||||
node_id_t rec_id; // receiver id (should be the same as tgt_id)
|
||||
node_id_t src_id; // source id
|
||||
logic [TxnID_Width-1:0] txn_id; // transaction id
|
||||
logic [FLIT_DATA_LENGTH-1:0] flit_data;
|
||||
} receiver_info_t;
|
||||
|
||||
endpackage
|
||||
`endif
|
||||
56
tb/v_receiver.sv
Normal file
56
tb/v_receiver.sv
Normal file
@@ -0,0 +1,56 @@
|
||||
module v_receiver
|
||||
import rvh_noc_pkg::*;
|
||||
import v_noc_pkg::*;
|
||||
#(
|
||||
parameter type flit_payload_t = logic[256-1:0]
|
||||
)
|
||||
(
|
||||
// intf with dut
|
||||
// input from one of dut router's outports // N,S,E,W,L
|
||||
input logic rx_flit_pend_i,
|
||||
input logic rx_flit_v_i,
|
||||
input flit_payload_t rx_flit_i,
|
||||
input logic [VC_ID_NUM_MAX_W-1:0] rx_flit_vc_id_i,
|
||||
input io_port_t rx_flit_look_ahead_routing_i,
|
||||
|
||||
// free vc credit from dut
|
||||
output logic rx_lcrd_v_o,
|
||||
output logic [VC_ID_NUM_MAX_W-1:0] rx_lcrd_id_o,
|
||||
|
||||
// intf with scoreboard
|
||||
output logic check_scoreboard_vld_o,
|
||||
output receiver_info_t check_scoreboard_o,
|
||||
input logic check_scoreboard_rdy_i,
|
||||
|
||||
// node id
|
||||
input node_id_t node_id_i,
|
||||
|
||||
input logic clk,
|
||||
input logic rstn
|
||||
);
|
||||
|
||||
flit_dec_t flit_ctrl_info;
|
||||
|
||||
input_port_flit_decoder
|
||||
#(
|
||||
.flit_payload_t (flit_payload_t)
|
||||
)
|
||||
receiver_flit_decoder_u
|
||||
(
|
||||
.flit_v_i (rx_flit_v_i ),
|
||||
.flit_i (rx_flit_i ),
|
||||
.flit_look_ahead_routing_i(rx_flit_look_ahead_routing_i),
|
||||
|
||||
.flit_dec_o (flit_ctrl_info )
|
||||
);
|
||||
|
||||
assign check_scoreboard_vld_o = rx_flit_v_i;
|
||||
assign check_scoreboard_o.rec_id = node_id_i;
|
||||
assign check_scoreboard_o.src_id = flit_ctrl_info.src_id;
|
||||
assign check_scoreboard_o.txn_id = flit_ctrl_info.txn_id;
|
||||
assign check_scoreboard_o.flit_data = rx_flit_i[FLIT_LENGTH-1-:FLIT_DATA_LENGTH];
|
||||
|
||||
assign rx_lcrd_v_o = rx_flit_v_i;
|
||||
assign rx_lcrd_id_o = rx_flit_vc_id_i;
|
||||
|
||||
endmodule
|
||||
467
tb/v_scoreboard.sv
Normal file
467
tb/v_scoreboard.sv
Normal file
@@ -0,0 +1,467 @@
|
||||
module v_scoreboard
|
||||
import rvh_noc_pkg::*;
|
||||
import v_noc_pkg::*;
|
||||
#(
|
||||
parameter SCOREBOARD_ENTRY_NUM_PER_SENDER = 8, // size of scoreboard per sender, should be able to hold all inflight transaction, or the verification coverage would be degraged
|
||||
parameter SCOREBOARD_ENTRY_NUM_PER_SENDER_IDX_W = SCOREBOARD_ENTRY_NUM_PER_SENDER > 1 ? $clog2(SCOREBOARD_ENTRY_NUM_PER_SENDER) : 1,
|
||||
parameter SENDER_NUM = 1,
|
||||
parameter RECEIVER_NUM = 1,
|
||||
|
||||
parameter NODE_NUM_X_DIMESION = 2, // only used in non TEST_CASE_SINGLE_ROUTER mode
|
||||
parameter NODE_NUM_Y_DIMESION = 3, // only used in non TEST_CASE_SINGLE_ROUTER mode
|
||||
parameter LOCAL_PORT_NUM = 1, // only used in non TEST_CASE_SINGLE_ROUTER mode
|
||||
|
||||
parameter TEST_CASE_SINGLE_ROUTER = 0,
|
||||
|
||||
parameter ASSUMED_SYSTEM_FREQUENCY = (1<<30) // 1GHz
|
||||
)
|
||||
(
|
||||
// intf with sender
|
||||
input logic [SENDER_NUM-1:0] new_scoreboard_entry_vld_i,
|
||||
input scoreboard_entry_t [SENDER_NUM-1:0] new_scoreboard_entry_i,
|
||||
output logic [SENDER_NUM-1:0] new_scoreboard_entry_rdy_o,
|
||||
|
||||
// intf with receiver
|
||||
input logic [RECEIVER_NUM-1:0] check_scoreboard_vld_i,
|
||||
input receiver_info_t [RECEIVER_NUM-1:0] check_scoreboard_i,
|
||||
output logic [RECEIVER_NUM-1:0] check_scoreboard_rdy_o,
|
||||
|
||||
// current system cycle
|
||||
input logic [64-1:0] mcycle_i,
|
||||
|
||||
input logic clk,
|
||||
input logic rstn
|
||||
);
|
||||
|
||||
genvar i, j;
|
||||
|
||||
logic [SENDER_NUM-1:0][SCOREBOARD_ENTRY_NUM_PER_SENDER-1:0] scoreboard_entry_vld_d, scoreboard_entry_vld_q;
|
||||
logic [SENDER_NUM-1:0][SCOREBOARD_ENTRY_NUM_PER_SENDER-1:0] scoreboard_entry_vld_ena;
|
||||
logic [SENDER_NUM-1:0][SCOREBOARD_ENTRY_NUM_PER_SENDER-1:0] scoreboard_entry_vld_set, scoreboard_entry_vld_clr;
|
||||
|
||||
scoreboard_entry_t [SENDER_NUM-1:0][SCOREBOARD_ENTRY_NUM_PER_SENDER-1:0] scoreboard_entry_d, scoreboard_entry_q;
|
||||
logic [SENDER_NUM-1:0][SCOREBOARD_ENTRY_NUM_PER_SENDER-1:0] scoreboard_entry_ena;
|
||||
|
||||
scoreboard_timer_t [SENDER_NUM-1:0][SCOREBOARD_ENTRY_NUM_PER_SENDER-1:0] scoreboard_timer_d, scoreboard_timer_q;
|
||||
logic [SENDER_NUM-1:0][SCOREBOARD_ENTRY_NUM_PER_SENDER-1:0] scoreboard_timer_ena;
|
||||
|
||||
// if at least one scoreboard entry is non valid, the new entry can find a slot to place
|
||||
generate
|
||||
for(i = 0; i < SENDER_NUM; i++) begin: gen_new_scoreboard_entry_rdy_o
|
||||
assign new_scoreboard_entry_rdy_o[i] = ~(&(scoreboard_entry_vld_q[i]));
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// scoreboard allocate new entry
|
||||
logic [SENDER_NUM-1:0][SCOREBOARD_ENTRY_NUM_PER_SENDER_IDX_W-1:0] sel_sb_ent_idx;
|
||||
generate
|
||||
for(i = 0; i < SENDER_NUM; i++) begin: gen_set_scoreboard_entry
|
||||
always_comb begin
|
||||
sel_sb_ent_idx[i] = 0;
|
||||
scoreboard_entry_vld_set[i] = '0;
|
||||
scoreboard_entry_d [i] = '0;
|
||||
if(new_scoreboard_entry_vld_i[i]) begin// new
|
||||
for(int j = SCOREBOARD_ENTRY_NUM_PER_SENDER-1; j >= 0; j--) begin
|
||||
if(~scoreboard_entry_vld_q[i][j] & ~scoreboard_entry_vld_set[i][j]) begin
|
||||
sel_sb_ent_idx[i] = j;
|
||||
end
|
||||
end
|
||||
|
||||
scoreboard_entry_d[i][sel_sb_ent_idx[i]] = new_scoreboard_entry_i[i];
|
||||
|
||||
if(~scoreboard_entry_vld_q[i][sel_sb_ent_idx[i]]) begin
|
||||
scoreboard_entry_vld_set[i][sel_sb_ent_idx[i]] = 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// scoreboard deallocate old entry
|
||||
always_comb begin
|
||||
scoreboard_entry_vld_clr = '0;
|
||||
for(int i = 0; i < RECEIVER_NUM; i++) begin: gen_clr_scoreboard_entry
|
||||
if(check_scoreboard_vld_i[i]) begin// new
|
||||
for(int j = 0; j < SENDER_NUM; j++) begin
|
||||
for(int k = 0; k < SCOREBOARD_ENTRY_NUM_PER_SENDER; k++) begin
|
||||
if(scoreboard_entry_vld_q[j][k]) begin
|
||||
if(
|
||||
(scoreboard_entry_q[j][k].txn_id == check_scoreboard_i[i].txn_id) &
|
||||
(scoreboard_entry_q[j][k].src_id == check_scoreboard_i[i].src_id) &
|
||||
(scoreboard_entry_q[j][k].tgt_id == check_scoreboard_i[i].rec_id) &
|
||||
(scoreboard_entry_q[j][k].flit_data == check_scoreboard_i[i].flit_data)
|
||||
) begin
|
||||
scoreboard_entry_vld_clr[j][k] = 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// scoreboard timer
|
||||
generate
|
||||
for(i = 0; i < SENDER_NUM; i++) begin: gen_scoreboard_timer_d_i
|
||||
for(j = 0; j < SCOREBOARD_ENTRY_NUM_PER_SENDER; j++) begin:gen_scoreboard_timer_d_j
|
||||
assign scoreboard_timer_d [i][j] = scoreboard_entry_vld_set[i][j] ? 0 : scoreboard_timer_q[i][j] + 1;
|
||||
assign scoreboard_timer_ena[i][j] = scoreboard_entry_vld_set[i][j] | (scoreboard_entry_vld_q[i][j] & ~scoreboard_entry_vld_clr[i][j]);
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// scoreboard entry change
|
||||
generate
|
||||
for(i = 0; i < SENDER_NUM; i++) begin: gen_scoreboard_entry_vld_d_i
|
||||
for(j = 0; j < SCOREBOARD_ENTRY_NUM_PER_SENDER; j++) begin:gen_scoreboard_entry_vld_d_j
|
||||
assign scoreboard_entry_vld_ena[i][j] = scoreboard_entry_vld_set[i][j] | scoreboard_entry_vld_clr[i][j];
|
||||
assign scoreboard_entry_vld_d [i][j] = scoreboard_entry_vld_set[i][j] & ~scoreboard_entry_vld_clr[i][j];
|
||||
assign scoreboard_entry_ena [i][j] = scoreboard_entry_vld_set[i][j];
|
||||
end
|
||||
end
|
||||
|
||||
endgenerate
|
||||
|
||||
`ifndef SYNTHESIS
|
||||
assert property(@(posedge clk)disable iff(~rstn) ((scoreboard_entry_vld_set & scoreboard_entry_vld_clr) == '0))
|
||||
else $fatal("v_scoreboard: set and clr scoreboard_entry_vld at the same cycle");
|
||||
`endif
|
||||
|
||||
// registers
|
||||
generate
|
||||
for(i = 0; i < SENDER_NUM; i++) begin: gen_scoreboard_entry_i
|
||||
for(j = 0; j < SCOREBOARD_ENTRY_NUM_PER_SENDER; j++) begin:gen_scoreboard_entry_j
|
||||
std_dffre
|
||||
#(.WIDTH(1))
|
||||
U_STA_SCOREBOARD_ENTRY_VLD_REG
|
||||
(
|
||||
.clk(clk),
|
||||
.rstn(rstn),
|
||||
.en(scoreboard_entry_vld_ena[i][j]),
|
||||
.d (scoreboard_entry_vld_d [i][j]),
|
||||
.q (scoreboard_entry_vld_q [i][j])
|
||||
);
|
||||
|
||||
std_dffe
|
||||
#(.WIDTH($bits(scoreboard_entry_t)))
|
||||
U_DAT_SCOREBOARD_ENTRY_REG
|
||||
(
|
||||
.clk(clk),
|
||||
.en(scoreboard_entry_ena[i][j]),
|
||||
.d (scoreboard_entry_d [i][j]),
|
||||
.q (scoreboard_entry_q [i][j])
|
||||
);
|
||||
|
||||
std_dffe
|
||||
#(.WIDTH($bits(scoreboard_timer_t)))
|
||||
U_DAT_SCOREBOARD_TIMER_REG
|
||||
(
|
||||
.clk(clk),
|
||||
.en(scoreboard_timer_ena[i][j]),
|
||||
.d (scoreboard_timer_d [i][j]),
|
||||
.q (scoreboard_timer_q [i][j])
|
||||
);
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// check for receiver 1.target error; 2.data error
|
||||
logic [RECEIVER_NUM-1:0] find_entry;
|
||||
always_ff @(posedge clk) begin
|
||||
find_entry = '0;
|
||||
for(int i = 0; i < RECEIVER_NUM; i++) begin
|
||||
if(check_scoreboard_vld_i[i]) begin
|
||||
for(int j = 0; j < SENDER_NUM; j++) begin
|
||||
for(int k = 0; k < SCOREBOARD_ENTRY_NUM_PER_SENDER; k++) begin
|
||||
if(scoreboard_entry_vld_q[j][k]) begin
|
||||
if((scoreboard_entry_q[j][k].src_id == check_scoreboard_i[i].src_id) &&
|
||||
(scoreboard_entry_q[j][k].txn_id == check_scoreboard_i[i].txn_id) &&
|
||||
(TEST_CASE_SINGLE_ROUTER ||
|
||||
(scoreboard_entry_q[j][k].tgt_id == check_scoreboard_i[i].rec_id) &&
|
||||
(scoreboard_entry_q[j][k].flit_data == check_scoreboard_i[i].flit_data)
|
||||
)
|
||||
) begin // found the entry
|
||||
find_entry[i] = 1'b1;
|
||||
// check target position
|
||||
if((scoreboard_entry_q[j][k].tgt_id.x_position != check_scoreboard_i[i].rec_id.x_position) |
|
||||
(scoreboard_entry_q[j][k].tgt_id.y_position != check_scoreboard_i[i].rec_id.y_position)
|
||||
) begin
|
||||
$display("[%16d] error: receiver position mismatch", $time());
|
||||
$display("txn_id: 0x%h, sender: %2d (%d,%d), receiver: %d (%d,%d)",
|
||||
check_scoreboard_i[i].txn_id,
|
||||
j, check_scoreboard_i[i].src_id.x_position, check_scoreboard_i[i].src_id.y_position,
|
||||
i, check_scoreboard_i[i].rec_id.x_position, check_scoreboard_i[i].rec_id.y_position);
|
||||
$display("tgt_id: (%d,%d), tgt_local_port: %d, look_ahead_routing: %d, send_time: %d",
|
||||
scoreboard_entry_q[j][k].tgt_id.x_position, scoreboard_entry_q[j][k].tgt_id.y_position, scoreboard_entry_q[j][k].tgt_id.device_port,
|
||||
scoreboard_entry_q[j][k].look_ahead_routing, scoreboard_entry_q[j][k].sent_mcycle);
|
||||
$finish();
|
||||
end
|
||||
|
||||
// check port id if tgt is (one of) the local port(s) of the dut router
|
||||
if(((check_scoreboard_i[i].rec_id.x_position == 1) &&
|
||||
(check_scoreboard_i[i].rec_id.y_position == 1)) || // assume the dut is (1,1) for single router mode
|
||||
!TEST_CASE_SINGLE_ROUTER // always check if is mesh mode
|
||||
) begin
|
||||
if(scoreboard_entry_q[j][k].tgt_id.device_port != check_scoreboard_i[i].rec_id.device_port) begin
|
||||
$display("[%16d] error: receiver local_port_id mismatch", $time());
|
||||
$display("txn_id: 0x%h, sender: %2d (%d,%d), sender_local_port: %d; receiver: %d (%d,%d), receiver_local_port: %d",
|
||||
check_scoreboard_i[i].txn_id,
|
||||
j, check_scoreboard_i[i].src_id.x_position, check_scoreboard_i[i].src_id.y_position,
|
||||
check_scoreboard_i[i].src_id.device_port,
|
||||
i, check_scoreboard_i[i].rec_id.x_position, check_scoreboard_i[i].rec_id.y_position,
|
||||
check_scoreboard_i[i].rec_id.device_port);
|
||||
$display("tgt_id: (%d,%d), tgt_local_port: %d, look_ahead_routing: %d, send_time: %d",
|
||||
scoreboard_entry_q[j][k].tgt_id.x_position, scoreboard_entry_q[j][k].tgt_id.y_position, scoreboard_entry_q[j][k].tgt_id.device_port,
|
||||
scoreboard_entry_q[j][k].look_ahead_routing, scoreboard_entry_q[j][k].sent_mcycle);
|
||||
$finish();
|
||||
end
|
||||
end
|
||||
|
||||
// check data
|
||||
if(scoreboard_entry_q[j][k].flit_data != check_scoreboard_i[i].flit_data) begin
|
||||
$display("[%16d] error: data mismatch", $time());
|
||||
$display("txn_id: 0x%h, sender: %2d (%d,%d), receiver: %d (%d,%d), received_data: %h",
|
||||
check_scoreboard_i[i].txn_id,
|
||||
j, check_scoreboard_i[i].src_id.x_position, check_scoreboard_i[i].src_id.y_position,
|
||||
i, check_scoreboard_i[i].rec_id.x_position, check_scoreboard_i[i].rec_id.y_position,
|
||||
check_scoreboard_i[i].flit_data);
|
||||
$display("tgt_id: (%d,%d), tgt_local_port: %d, look_ahead_routing: %d, send_time: %d, sent_data: %h",
|
||||
scoreboard_entry_q[j][k].tgt_id.x_position, scoreboard_entry_q[j][k].tgt_id.y_position, scoreboard_entry_q[j][k].tgt_id.device_port,
|
||||
scoreboard_entry_q[j][k].look_ahead_routing, scoreboard_entry_q[j][k].sent_mcycle,
|
||||
scoreboard_entry_q[j][k].flit_data);
|
||||
$finish();
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if(find_entry[i] == 1'b0) begin
|
||||
$display("[%16d] error: scoreboard failed to find the entry, txn_id: 0x%h, sender: (%d,%d), receiver: (%d,%d)",
|
||||
$time(), check_scoreboard_i[i].txn_id,
|
||||
check_scoreboard_i[i].src_id.x_position, check_scoreboard_i[i].src_id.y_position,
|
||||
check_scoreboard_i[i].rec_id.x_position, check_scoreboard_i[i].rec_id.y_position);
|
||||
$finish();
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// check for scoreboard timeout
|
||||
always_ff @(posedge clk) begin
|
||||
for(int i = 0; i < SENDER_NUM; i++) begin
|
||||
for(int j = 0; j < SCOREBOARD_ENTRY_NUM_PER_SENDER; j++) begin
|
||||
if(scoreboard_entry_vld_q[i][j]) begin
|
||||
if((scoreboard_timer_q[i][j].timeout_counter >= scoreboard_entry_q[i][j].timeout_threshold)
|
||||
&& (scoreboard_entry_q[i][j].timeout_threshold != '0)) begin
|
||||
$display("[%16d] error: scoreboard entry timeout, timeout_threshold: %d",
|
||||
$time(), scoreboard_entry_q[i][j].timeout_threshold);
|
||||
$display("txn_id: 0x%h, sender: %2d (%d,%d), sender_local_port: %d, qos_value = %d",
|
||||
scoreboard_entry_q[i][j].txn_id,
|
||||
i, scoreboard_entry_q[i][j].src_id.x_position, scoreboard_entry_q[i][j].src_id.y_position,
|
||||
scoreboard_entry_q[i][j].src_id.device_port,
|
||||
scoreboard_entry_q[i][j].qos_value);
|
||||
$display("tgt_id: (%d,%d), tgt_local_port: %d, look_ahead_routing: %d, send_time: %d",
|
||||
scoreboard_entry_q[i][j].tgt_id.x_position, scoreboard_entry_q[i][j].tgt_id.y_position, scoreboard_entry_q[i][j].tgt_id.device_port,
|
||||
scoreboard_entry_q[i][j].look_ahead_routing, scoreboard_entry_q[i][j].sent_mcycle);
|
||||
if(!((scoreboard_entry_q[i][j].qos_value == '1) && QOS_VC_NUM_PER_INPUT)) begin // if rt flit, don't finish, as its timeout_threshold is too tight
|
||||
$finish();
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// average cycle per flit
|
||||
logic [64-1:0] flit_num_counter_d, flit_num_counter_q;
|
||||
logic flit_num_counter_ena;
|
||||
logic [64-1:0] flit_noc_latency_counter_d, flit_noc_latency_counter_q;
|
||||
logic flit_noc_latency_counter_ena;
|
||||
logic [64-1:0] flit_app_latency_counter_d, flit_app_latency_counter_q;
|
||||
logic flit_app_latency_counter_ena;
|
||||
|
||||
// port usage counter
|
||||
logic [64-1:0] allocate_port_counter_d, allocate_port_counter_q;
|
||||
logic allocate_port_counter_ena;
|
||||
logic [64-1:0] deallocate_port_counter_all_d, deallocate_port_counter_all_q;
|
||||
logic deallocate_port_counter_all_ena;
|
||||
logic [RECEIVER_NUM-1:0][64-1:0] deallocate_port_counter_d, deallocate_port_counter_q;
|
||||
logic [RECEIVER_NUM-1:0] deallocate_port_counter_ena;
|
||||
|
||||
std_dffre
|
||||
#(.WIDTH(64))
|
||||
U_DAT_FLIT_NUM_COUNTER
|
||||
(
|
||||
.clk(clk),
|
||||
.rstn(rstn),
|
||||
.en(flit_num_counter_ena),
|
||||
.d(flit_num_counter_d),
|
||||
.q(flit_num_counter_q)
|
||||
);
|
||||
|
||||
std_dffre
|
||||
#(.WIDTH(64))
|
||||
U_DAT_FLIT_NOC_LATENCY_COUNTER
|
||||
(
|
||||
.clk(clk),
|
||||
.rstn(rstn),
|
||||
.en(flit_noc_latency_counter_ena),
|
||||
.d(flit_noc_latency_counter_d),
|
||||
.q(flit_noc_latency_counter_q)
|
||||
);
|
||||
|
||||
std_dffre
|
||||
#(.WIDTH(64))
|
||||
U_DAT_FLIT_APP_LATENCY_COUNTER
|
||||
(
|
||||
.clk(clk),
|
||||
.rstn(rstn),
|
||||
.en(flit_app_latency_counter_ena),
|
||||
.d(flit_app_latency_counter_d),
|
||||
.q(flit_app_latency_counter_q)
|
||||
);
|
||||
|
||||
std_dffre
|
||||
#(.WIDTH(64))
|
||||
U_DAT_ALLOCATE_PORT_COUNTER
|
||||
(
|
||||
.clk(clk),
|
||||
.rstn(rstn),
|
||||
.en(allocate_port_counter_ena),
|
||||
.d(allocate_port_counter_d),
|
||||
.q(allocate_port_counter_q)
|
||||
);
|
||||
|
||||
std_dffre
|
||||
#(.WIDTH(64))
|
||||
U_DAT_DEALLOCATE_PORT_COUNTER_ALL
|
||||
(
|
||||
.clk(clk),
|
||||
.rstn(rstn),
|
||||
.en(deallocate_port_counter_all_ena),
|
||||
.d(deallocate_port_counter_all_d),
|
||||
.q(deallocate_port_counter_all_q)
|
||||
);
|
||||
|
||||
generate
|
||||
for(i = 0; i < RECEIVER_NUM; i++) begin
|
||||
std_dffre
|
||||
#(.WIDTH(64))
|
||||
U_DAT_DEALLOCATE_PORT_COUNTER
|
||||
(
|
||||
.clk(clk),
|
||||
.rstn(rstn),
|
||||
.en(deallocate_port_counter_ena[i]),
|
||||
.d (deallocate_port_counter_d [i]),
|
||||
.q (deallocate_port_counter_q [i])
|
||||
);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
||||
// display allocate and deallocate scoreboard entry
|
||||
real flit_noc_latency_counter;
|
||||
real flit_app_latency_counter;
|
||||
real flit_num_counter;
|
||||
|
||||
real allocate_port_counter;
|
||||
real deallocate_port_counter_all;
|
||||
real deallocate_port_counter[RECEIVER_NUM-1:0];
|
||||
|
||||
real mcycle;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
flit_num_counter_d = flit_num_counter_q;
|
||||
flit_num_counter_ena = 1'b0;
|
||||
flit_noc_latency_counter_d = flit_noc_latency_counter_q;
|
||||
flit_noc_latency_counter_ena = 1'b0;
|
||||
flit_app_latency_counter_d = flit_app_latency_counter_q;
|
||||
flit_app_latency_counter_ena = 1'b0;
|
||||
mcycle = mcycle_i;
|
||||
|
||||
allocate_port_counter_d = allocate_port_counter_q;
|
||||
allocate_port_counter_ena = 1'b0;
|
||||
deallocate_port_counter_all_d = deallocate_port_counter_all_q;
|
||||
deallocate_port_counter_all_ena = 1'b0;
|
||||
|
||||
flit_noc_latency_counter = flit_noc_latency_counter_q;
|
||||
flit_app_latency_counter = flit_app_latency_counter_q;
|
||||
flit_num_counter = flit_num_counter_q;
|
||||
|
||||
deallocate_port_counter_d = deallocate_port_counter_q;
|
||||
deallocate_port_counter_ena = '0;
|
||||
|
||||
allocate_port_counter = allocate_port_counter_q;
|
||||
deallocate_port_counter_all = deallocate_port_counter_all_q;
|
||||
|
||||
for(int i = 0; i < RECEIVER_NUM; i++) begin
|
||||
deallocate_port_counter[i] = deallocate_port_counter_q[i];
|
||||
end
|
||||
|
||||
for(int i = 0; i < SENDER_NUM; i++) begin
|
||||
for(int j = 0; j < SCOREBOARD_ENTRY_NUM_PER_SENDER; j++) begin
|
||||
if(scoreboard_entry_vld_set[i][j]) begin
|
||||
$display("[%16d] info: scoreboard allocate entry, sender: %2d (%d,%d), txn_id: 0x%h, QoS = %d, inport_vc_id:%d, tgt_id: (%d,%d), tgt_local_port: %d, look_ahead_routing: %d, send_data: %h",
|
||||
$time(), i,
|
||||
scoreboard_entry_d[i][j].src_id.x_position, scoreboard_entry_d[i][j].src_id.y_position,
|
||||
scoreboard_entry_d[i][j].txn_id,
|
||||
scoreboard_entry_d[i][j].qos_value,
|
||||
scoreboard_entry_d[i][j].inport_vc_id,
|
||||
scoreboard_entry_d[i][j].tgt_id.x_position, scoreboard_entry_d[i][j].tgt_id.y_position, scoreboard_entry_d[i][j].tgt_id.device_port,
|
||||
scoreboard_entry_d[i][j].look_ahead_routing,
|
||||
scoreboard_entry_d[i][j].flit_data);
|
||||
|
||||
allocate_port_counter_d = allocate_port_counter_d + 1;
|
||||
allocate_port_counter_ena = 1'b1;
|
||||
end
|
||||
|
||||
if(scoreboard_entry_vld_clr[i][j]) begin
|
||||
$display("[%16d] info: scoreboard deallocate entry, sender: %2d (%d,%d), txn_id: 0x%h, QoS = %d, inport_vc_id:%d, tgt_id: (%d,%d), tgt_local_port: %d, send_data: %h, [noc_latency: %4d], [app_latency: %4d], [receiver (%d,%d) port %d average_noc_bandwidth: %fGBps])",
|
||||
$time(), i,
|
||||
scoreboard_entry_q[i][j].src_id.x_position, scoreboard_entry_q[i][j].src_id.y_position,
|
||||
scoreboard_entry_q[i][j].txn_id,
|
||||
scoreboard_entry_q[i][j].qos_value,
|
||||
scoreboard_entry_q[i][j].inport_vc_id,
|
||||
scoreboard_entry_q[i][j].tgt_id.x_position, scoreboard_entry_q[i][j].tgt_id.y_position, scoreboard_entry_q[i][j].tgt_id.device_port,
|
||||
scoreboard_entry_q[i][j].flit_data,
|
||||
mcycle_i - scoreboard_entry_q[i][j].sent_mcycle,
|
||||
mcycle_i - scoreboard_entry_q[i][j].generated_mcycle,
|
||||
|
||||
scoreboard_entry_q[i][j].tgt_id.x_position, scoreboard_entry_q[i][j].tgt_id.y_position, scoreboard_entry_q[i][j].tgt_id.device_port,
|
||||
((deallocate_port_counter[scoreboard_entry_q[i][j].tgt_id.x_position*(NODE_NUM_Y_DIMESION*LOCAL_PORT_NUM) +
|
||||
scoreboard_entry_q[i][j].tgt_id.y_position*LOCAL_PORT_NUM +
|
||||
scoreboard_entry_q[i][j].tgt_id.device_port] *
|
||||
FLIT_LENGTH /8/1024/1024/1024) / (mcycle / ASSUMED_SYSTEM_FREQUENCY))
|
||||
);
|
||||
|
||||
flit_num_counter_d = flit_num_counter_d + 1;
|
||||
flit_num_counter_ena = 1'b1;
|
||||
flit_noc_latency_counter_d = flit_noc_latency_counter_d + (mcycle_i - scoreboard_entry_q[i][j].sent_mcycle);
|
||||
flit_noc_latency_counter_ena = 1'b1;
|
||||
flit_app_latency_counter_d = flit_app_latency_counter_d + (mcycle_i - scoreboard_entry_q[i][j].generated_mcycle);
|
||||
flit_app_latency_counter_ena = 1'b1;
|
||||
|
||||
deallocate_port_counter_all_d = deallocate_port_counter_all_d + 1;
|
||||
deallocate_port_counter_all_ena = 1'b1;
|
||||
|
||||
// receiver id = x_posotion*(NODE_NUM_Y_DIMESION*LOCAL_PORT_NUM) + y_posotion*LOCAL_PORT_NUM + local_port_id
|
||||
deallocate_port_counter_d [scoreboard_entry_q[i][j].tgt_id.x_position*(NODE_NUM_Y_DIMESION*LOCAL_PORT_NUM) +
|
||||
scoreboard_entry_q[i][j].tgt_id.y_position*LOCAL_PORT_NUM +
|
||||
scoreboard_entry_q[i][j].tgt_id.device_port] += 1;
|
||||
deallocate_port_counter_ena[scoreboard_entry_q[i][j].tgt_id.x_position*(NODE_NUM_Y_DIMESION*LOCAL_PORT_NUM) +
|
||||
scoreboard_entry_q[i][j].tgt_id.y_position*LOCAL_PORT_NUM +
|
||||
scoreboard_entry_q[i][j].tgt_id.device_port] = 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
if(|scoreboard_entry_vld_clr) begin
|
||||
$display("[%16d] info: scoreboard deallocate entry, receiver:all, [average_noc_latency: %f], [average_app_latency: %f], [average_noc_bandwidth: %fGBps]",
|
||||
$time(),
|
||||
(flit_noc_latency_counter)/(flit_num_counter),
|
||||
(flit_app_latency_counter)/(flit_num_counter),
|
||||
((deallocate_port_counter_all * FLIT_LENGTH /8/1024/1024/1024) / (mcycle / ASSUMED_SYSTEM_FREQUENCY)));
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
||||
198
tb/v_sender.sv
Normal file
198
tb/v_sender.sv
Normal file
@@ -0,0 +1,198 @@
|
||||
module v_sender
|
||||
import rvh_noc_pkg::*;
|
||||
import v_noc_pkg::*;
|
||||
#(
|
||||
parameter FLIT_BUFFER_DEPTH = 8,
|
||||
parameter type flit_payload_t = logic[256-1:0],
|
||||
|
||||
parameter VC_NUM_OUTPORT = 2,
|
||||
parameter VC_NUM_OUTPORT_IDX_W = VC_NUM_OUTPORT > 1 ? $clog2(VC_NUM_OUTPORT) : 1,
|
||||
parameter VC_DEPTH_OUTPORT = 2,
|
||||
parameter VC_DEPTH_OUTPORT_COUNTER_W = $clog2(VC_DEPTH_OUTPORT + 1),
|
||||
|
||||
parameter SENDER_TIMEOUT_EN = 1,
|
||||
parameter SENDER_TIMEOUT_THRESHOLD = 64,
|
||||
|
||||
parameter OUTPUT_TO_N = 0,
|
||||
parameter OUTPUT_TO_S = 0,
|
||||
parameter OUTPUT_TO_E = 0,
|
||||
parameter OUTPUT_TO_W = 0,
|
||||
parameter OUTPUT_TO_L = 0
|
||||
)
|
||||
(
|
||||
// intf with dut
|
||||
// output to one of dut router's inports // N,S,E,W,L
|
||||
output logic tx_flit_pend_o,
|
||||
output logic tx_flit_v_o,
|
||||
output flit_payload_t tx_flit_o,
|
||||
output logic [VC_ID_NUM_MAX_W-1:0] tx_flit_vc_id_o,
|
||||
output io_port_t tx_flit_look_ahead_routing_o,
|
||||
|
||||
// free vc credit from dut
|
||||
input logic tx_lcrd_v_i,
|
||||
input logic [VC_ID_NUM_MAX_W-1:0] tx_lcrd_id_i,
|
||||
|
||||
// intf with test generator
|
||||
input logic new_test_vld_i,
|
||||
input test_case_t new_test_i,
|
||||
output logic new_test_rdy_o,
|
||||
|
||||
// intf with scoreboard
|
||||
output logic new_scoreboard_entry_vld_o,
|
||||
output scoreboard_entry_t new_scoreboard_entry_o,
|
||||
input logic new_scoreboard_entry_rdy_i,
|
||||
|
||||
// node id
|
||||
input node_id_t node_id_i,
|
||||
|
||||
// system cycle counter
|
||||
input logic [64-1:0] mcycle_i,
|
||||
|
||||
|
||||
input logic clk,
|
||||
input logic rstn
|
||||
);
|
||||
|
||||
genvar i;
|
||||
|
||||
|
||||
// to send flit buffer
|
||||
logic flit_buffer_head_vld;
|
||||
test_case_t flit_buffer_head;
|
||||
|
||||
logic flit_buffer_dequeue_vld;
|
||||
|
||||
mp_fifo
|
||||
#(
|
||||
.payload_t (test_case_t),
|
||||
.ENQUEUE_WIDTH (1),
|
||||
.DEQUEUE_WIDTH (1),
|
||||
.DEPTH (FLIT_BUFFER_DEPTH),
|
||||
.MUST_TAKEN_ALL (1)
|
||||
)
|
||||
FLIT_BUFFER_U
|
||||
(
|
||||
// Enqueue
|
||||
.enqueue_vld_i (new_test_vld_i ),
|
||||
.enqueue_payload_i (new_test_i ),
|
||||
.enqueue_rdy_o (new_test_rdy_o ),
|
||||
// Dequeue
|
||||
.dequeue_vld_o (flit_buffer_head_vld ),
|
||||
.dequeue_payload_o (flit_buffer_head ),
|
||||
.dequeue_rdy_i (flit_buffer_dequeue_vld ),
|
||||
|
||||
.flush_i (1'b0 ),
|
||||
|
||||
.clk (clk),
|
||||
.rst (~rstn)
|
||||
);
|
||||
|
||||
|
||||
// credit based flow control
|
||||
io_port_t look_ahead_routing_test;
|
||||
logic free_credit_vld;
|
||||
logic [VC_NUM_OUTPORT_IDX_W-1:0] free_credit_vc_id;
|
||||
logic flit_vld;
|
||||
|
||||
assign flit_vld = flit_buffer_head_vld & new_scoreboard_entry_rdy_i;
|
||||
|
||||
local_port_couple_module
|
||||
#(
|
||||
.VC_NUM_OUTPORT (VC_NUM_OUTPORT ),
|
||||
.VC_DEPTH_OUTPORT (VC_DEPTH_OUTPORT ),
|
||||
|
||||
.OUTPUT_TO_N (OUTPUT_TO_N),
|
||||
.OUTPUT_TO_S (OUTPUT_TO_S),
|
||||
.OUTPUT_TO_E (OUTPUT_TO_E),
|
||||
.OUTPUT_TO_W (OUTPUT_TO_W),
|
||||
.OUTPUT_TO_L (OUTPUT_TO_L)
|
||||
)
|
||||
local_port_couple_module_u (
|
||||
// input vc head to calculate next routing
|
||||
.node_id_x_tgt_i (flit_buffer_head.flit_head.tgt_id.x_position ),
|
||||
.node_id_y_tgt_i (flit_buffer_head.flit_head.tgt_id.y_position ),
|
||||
`ifdef ALLOW_SAME_ROUTER_L2L_TRANSFER
|
||||
.device_port_tgt_i (flit_buffer_head.flit_head.tgt_id.device_port),
|
||||
`endif
|
||||
// input this hop xy addr
|
||||
.node_id_x_src_i (flit_buffer_head.flit_head.src_id.x_position ),
|
||||
.node_id_y_src_i (flit_buffer_head.flit_head.src_id.y_position ),
|
||||
// output look ahead routing result
|
||||
.look_ahead_routing_o (look_ahead_routing_test ),
|
||||
|
||||
// free credit in from router
|
||||
.tx_lcrd_v_i (tx_lcrd_v_i ),
|
||||
.tx_lcrd_id_i (tx_lcrd_id_i ),
|
||||
// consume credit
|
||||
.flit_vld_i (flit_vld ),
|
||||
.flit_qos_value_i (flit_buffer_head.qos_value ),
|
||||
.free_credit_vld_o (free_credit_vld ),
|
||||
.free_credit_vc_id_o (free_credit_vc_id),
|
||||
|
||||
.clk (clk ),
|
||||
.rstn (rstn)
|
||||
);
|
||||
|
||||
`ifndef SYNTHESIS
|
||||
assert property(@(posedge clk)disable iff(~rstn) ((flit_vld) |-> (look_ahead_routing_test == tx_flit_look_ahead_routing_o)))
|
||||
else $fatal("look_ahead_routing_test not equal");
|
||||
`endif
|
||||
|
||||
assign flit_buffer_dequeue_vld = free_credit_vld & flit_vld;
|
||||
|
||||
// output to dut
|
||||
assign tx_flit_pend_o = 1'b1;
|
||||
assign tx_flit_v_o = flit_buffer_dequeue_vld;
|
||||
assign tx_flit_o = {flit_buffer_head.flit_data,
|
||||
flit_buffer_head.flit_head.txn_id,
|
||||
flit_buffer_head.flit_head.src_id,
|
||||
flit_buffer_head.flit_head.tgt_id,
|
||||
flit_buffer_head.qos_value};
|
||||
assign tx_flit_vc_id_o = {{(VC_ID_NUM_MAX_W-VC_NUM_OUTPORT_IDX_W){1'b0}}, free_credit_vc_id};
|
||||
assign tx_flit_look_ahead_routing_o = flit_buffer_head.flit_head.look_ahead_routing;
|
||||
|
||||
// output to scoreboard
|
||||
assign new_scoreboard_entry_vld_o = tx_flit_v_o;
|
||||
assign new_scoreboard_entry_o.tgt_id = flit_buffer_head.flit_head.tgt_id;
|
||||
assign new_scoreboard_entry_o.src_id = flit_buffer_head.flit_head.src_id;
|
||||
assign new_scoreboard_entry_o.txn_id = flit_buffer_head.flit_head.txn_id;
|
||||
assign new_scoreboard_entry_o.timeout_threshold = flit_buffer_head.timeout_threshold;
|
||||
assign new_scoreboard_entry_o.look_ahead_routing = flit_buffer_head.flit_head.look_ahead_routing;
|
||||
assign new_scoreboard_entry_o.inport_vc_id = tx_flit_vc_id_o;
|
||||
assign new_scoreboard_entry_o.generated_mcycle = flit_buffer_head.mcycle_when_generated;
|
||||
assign new_scoreboard_entry_o.sent_mcycle = mcycle_i;
|
||||
assign new_scoreboard_entry_o.flit_data = flit_buffer_head.flit_data;
|
||||
assign new_scoreboard_entry_o.qos_value = flit_buffer_head.qos_value;
|
||||
|
||||
// check for sender timeout
|
||||
sender_timer_t sender_timer_d, sender_timer_q;
|
||||
logic sender_timer_ena;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if((sender_timer_q.timeout_counter >= SENDER_TIMEOUT_THRESHOLD) && SENDER_TIMEOUT_EN) begin
|
||||
$display("[%d] error: sender timeout, sender: (%d,%d), sender_local_device_port: %d, timeout_threshold: %d",
|
||||
$time(),
|
||||
node_id_i.x_position, node_id_i.y_position, node_id_i.device_port,
|
||||
SENDER_TIMEOUT_THRESHOLD);
|
||||
$finish();
|
||||
end
|
||||
end
|
||||
|
||||
assign sender_timer_d.timeout_counter = tx_flit_v_o ? '0 :
|
||||
sender_timer_q.timeout_counter + 1;
|
||||
|
||||
assign sender_timer_ena = 1'b1;
|
||||
|
||||
std_dffre
|
||||
#(.WIDTH($bits(scoreboard_timer_t)))
|
||||
U_DAT_SENDER_TIMER_REG
|
||||
(
|
||||
.clk(clk),
|
||||
.rstn(rstn),
|
||||
.en(sender_timer_ena),
|
||||
.d (sender_timer_d ),
|
||||
.q (sender_timer_q )
|
||||
);
|
||||
|
||||
|
||||
endmodule
|
||||
642
tb/v_test_generator.sv
Normal file
642
tb/v_test_generator.sv
Normal file
@@ -0,0 +1,642 @@
|
||||
module v_test_generator
|
||||
import rvh_noc_pkg::*;
|
||||
import v_noc_pkg::*;
|
||||
#(
|
||||
parameter SENDER_NUM = 1,
|
||||
parameter LOCAL_PORT_SENDER_NUM = SENDER_NUM-4,
|
||||
parameter RANDOM_BIT_NUM = 32, // 1 to 32, at least TEST_CASE_NUM_PER_CYCLE*3
|
||||
parameter SCOREBOARD_TIMEOUT_EN = 1,
|
||||
parameter SCOREBOARD_TIMEOUT_THRESHOLD = 64,
|
||||
|
||||
parameter TEST_CASE_NUM_PER_CYCLE = 1,
|
||||
|
||||
parameter TEST_CASE_SINGLE_ROUTER = 0, // assume the dut router posetion is (1,1)
|
||||
// its adjacent routers are:
|
||||
// sender0 (1,2)
|
||||
// |
|
||||
// sender3 (0,1) - (1,1) - (2,1) sender2
|
||||
// | \
|
||||
// sender1 (1,0) (local) sender4
|
||||
parameter TEST_CASE_MESH_RANDOM = 0, // random sender and receiver
|
||||
parameter TEST_CASE_MESH_DIAGONAL = 0, // from (0,0) to (NODE_NUM_X_DIMESION-1, NODE_NUM_Y_DIMESION-1)
|
||||
parameter NODE_NUM_X_DIMESION = 2, // only used in TEST_CASE_MESH_* mode
|
||||
parameter NODE_NUM_Y_DIMESION = 3, // only used in TEST_CASE_MESH_* mode
|
||||
parameter LOCAL_PORT_NUM = 1, // only used in TEST_CASE_MESH_* mode
|
||||
|
||||
parameter ASSUMED_SYSTEM_FREQUENCY = (1<<30) // 1GHz
|
||||
|
||||
)
|
||||
(
|
||||
// intf with sender
|
||||
output logic [SENDER_NUM-1:0] new_test_vld_o,
|
||||
output test_case_t [SENDER_NUM-1:0] new_test_o,
|
||||
input logic [SENDER_NUM-1:0] new_test_rdy_i,
|
||||
|
||||
// random seeds
|
||||
input logic [RANDOM_BIT_NUM-1:0] src_id_lfsr_seed_i,
|
||||
input logic [RANDOM_BIT_NUM-1:0] tgt_id_lfsr_seed_i,
|
||||
input logic lfsr_update_en_i,
|
||||
|
||||
input logic [64-1:0] mcycle_i,
|
||||
|
||||
input logic clk,
|
||||
input logic rstn
|
||||
);
|
||||
|
||||
genvar i;
|
||||
|
||||
logic [RANDOM_BIT_NUM-1:0] src_id_lfsr_data;
|
||||
logic [RANDOM_BIT_NUM-1:0] tgt_id_lfsr_data;
|
||||
|
||||
logic [TxnID_Width-1:0] txn_counter;
|
||||
|
||||
logic [TEST_CASE_NUM_PER_CYCLE-1:0] new_test_vld;
|
||||
test_case_t [TEST_CASE_NUM_PER_CYCLE-1:0] new_test;
|
||||
|
||||
// map new test case to different sender
|
||||
generate
|
||||
if(TEST_CASE_SINGLE_ROUTER) begin: gen_map_test_case_single_router
|
||||
always_comb begin
|
||||
new_test_vld_o = '0;
|
||||
new_test_o = '0;
|
||||
for(int i = 0; i < TEST_CASE_NUM_PER_CYCLE; i++) begin
|
||||
unique case({new_test[i].flit_head.src_id.x_position, new_test[i].flit_head.src_id.y_position})
|
||||
4'b0110: begin // sender0 (1,2)
|
||||
new_test_vld_o[0] = new_test_vld[i];
|
||||
new_test_o [0] = new_test[i];
|
||||
end
|
||||
4'b0100: begin // sender1 (1,0)
|
||||
new_test_vld_o[1] = new_test_vld[i];
|
||||
new_test_o [1] = new_test[i];
|
||||
end
|
||||
4'b1001: begin // sender2 (2,1)
|
||||
new_test_vld_o[2] = new_test_vld[i];
|
||||
new_test_o [2] = new_test[i];
|
||||
end
|
||||
4'b0001: begin // sender3 (0,1)
|
||||
new_test_vld_o[3] = new_test_vld[i];
|
||||
new_test_o [3] = new_test[i];
|
||||
end
|
||||
4'b0101: begin // sender4 (1,1)
|
||||
new_test_vld_o[4+new_test[i].flit_head.src_id.device_port] = new_test_vld[i];
|
||||
new_test_o [4+new_test[i].flit_head.src_id.device_port] = new_test[i];
|
||||
end
|
||||
default:begin
|
||||
$fatal("test generator source id error");
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
else if(TEST_CASE_MESH_RANDOM || TEST_CASE_MESH_DIAGONAL) begin: gen_map_test_case_mesh_x
|
||||
// sender id = x_posotion*(NODE_NUM_Y_DIMESION*LOCAL_PORT_NUM) + y_posotion*LOCAL_PORT_NUM + local_port_id
|
||||
always_comb begin
|
||||
new_test_vld_o = '0;
|
||||
new_test_o = '0;
|
||||
for(int i = 0; i < TEST_CASE_NUM_PER_CYCLE; i++) begin
|
||||
new_test_vld_o[new_test[i].flit_head.src_id.x_position*(NODE_NUM_Y_DIMESION*LOCAL_PORT_NUM) +
|
||||
new_test[i].flit_head.src_id.y_position*LOCAL_PORT_NUM +
|
||||
new_test[i].flit_head.src_id.device_port] = new_test_vld[i];
|
||||
new_test_o [new_test[i].flit_head.src_id.x_position*(NODE_NUM_Y_DIMESION*LOCAL_PORT_NUM) +
|
||||
new_test[i].flit_head.src_id.y_position*LOCAL_PORT_NUM +
|
||||
new_test[i].flit_head.src_id.device_port] = new_test[i];
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// generate new test case
|
||||
generate
|
||||
if(TEST_CASE_SINGLE_ROUTER) begin: gen_test_case_single_router
|
||||
for(i = 0; i < TEST_CASE_NUM_PER_CYCLE; i++) begin: gen_new_test
|
||||
always_comb begin
|
||||
unique case(src_id_lfsr_data[i*3+:3])
|
||||
3'b000: begin // from N
|
||||
new_test[i].flit_head.src_id.x_position = 1;
|
||||
new_test[i].flit_head.src_id.y_position = 2;
|
||||
unique case(tgt_id_lfsr_data[i])
|
||||
1'b0: begin // to S
|
||||
new_test[i].flit_head.tgt_id.x_position = 1;
|
||||
new_test[i].flit_head.tgt_id.y_position = 0;
|
||||
end
|
||||
default: begin // to L
|
||||
new_test[i].flit_head.tgt_id.x_position = 1;
|
||||
new_test[i].flit_head.tgt_id.y_position = 1;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
3'b001: begin // from S
|
||||
new_test[i].flit_head.src_id.x_position = 1;
|
||||
new_test[i].flit_head.src_id.y_position = 0;
|
||||
unique case(tgt_id_lfsr_data[i])
|
||||
1'b0: begin // to N
|
||||
new_test[i].flit_head.tgt_id.x_position = 1;
|
||||
new_test[i].flit_head.tgt_id.y_position = 2;
|
||||
end
|
||||
default: begin // to L
|
||||
new_test[i].flit_head.tgt_id.x_position = 1;
|
||||
new_test[i].flit_head.tgt_id.y_position = 1;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
3'b010: begin // from E
|
||||
new_test[i].flit_head.src_id.x_position = 2;
|
||||
new_test[i].flit_head.src_id.y_position = 1;
|
||||
unique case(tgt_id_lfsr_data[i*2+:2])
|
||||
2'b00: begin // to N
|
||||
new_test[i].flit_head.tgt_id.x_position = 1;
|
||||
new_test[i].flit_head.tgt_id.y_position = 2;
|
||||
end
|
||||
2'b01: begin // to S
|
||||
new_test[i].flit_head.tgt_id.x_position = 1;
|
||||
new_test[i].flit_head.tgt_id.y_position = 0;
|
||||
end
|
||||
2'b10: begin // to W
|
||||
new_test[i].flit_head.tgt_id.x_position = 0;
|
||||
new_test[i].flit_head.tgt_id.y_position = 1;
|
||||
end
|
||||
default: begin // to L
|
||||
new_test[i].flit_head.tgt_id.x_position = 1;
|
||||
new_test[i].flit_head.tgt_id.y_position = 1;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
3'b011: begin // from W
|
||||
new_test[i].flit_head.src_id.x_position = 0;
|
||||
new_test[i].flit_head.src_id.y_position = 1;
|
||||
unique case(tgt_id_lfsr_data[i*2+:2])
|
||||
2'b00: begin // to N
|
||||
new_test[i].flit_head.tgt_id.x_position = 1;
|
||||
new_test[i].flit_head.tgt_id.y_position = 2;
|
||||
end
|
||||
2'b01: begin // to S
|
||||
new_test[i].flit_head.tgt_id.x_position = 1;
|
||||
new_test[i].flit_head.tgt_id.y_position = 0;
|
||||
end
|
||||
2'b10: begin // to E
|
||||
new_test[i].flit_head.tgt_id.x_position = 2;
|
||||
new_test[i].flit_head.tgt_id.y_position = 1;
|
||||
end
|
||||
default: begin // to L
|
||||
new_test[i].flit_head.tgt_id.x_position = 1;
|
||||
new_test[i].flit_head.tgt_id.y_position = 1;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
default: begin // from L
|
||||
new_test[i].flit_head.src_id.x_position = 1;
|
||||
new_test[i].flit_head.src_id.y_position = 1;
|
||||
unique case(tgt_id_lfsr_data[i*2+:2])
|
||||
2'b00: begin // to N
|
||||
new_test[i].flit_head.tgt_id.x_position = 1;
|
||||
new_test[i].flit_head.tgt_id.y_position = 2;
|
||||
end
|
||||
2'b01: begin // to S
|
||||
new_test[i].flit_head.tgt_id.x_position = 1;
|
||||
new_test[i].flit_head.tgt_id.y_position = 0;
|
||||
end
|
||||
2'b10: begin // to E
|
||||
new_test[i].flit_head.tgt_id.x_position = 2;
|
||||
new_test[i].flit_head.tgt_id.y_position = 1;
|
||||
end
|
||||
default: begin // to W
|
||||
new_test[i].flit_head.tgt_id.x_position = 0;
|
||||
new_test[i].flit_head.tgt_id.y_position = 1;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
logic [FLIT_DATA_LENGTH-1:0] flit_data_mask;
|
||||
always_comb begin
|
||||
flit_data_mask = ~({RANDOM_BIT_NUM{1'b1}} << tgt_id_lfsr_data[$clog2(FLIT_DATA_LENGTH-RANDOM_BIT_NUM)-1:0]);
|
||||
new_test[i].flit_data = '1;
|
||||
new_test[i].flit_data = ((src_id_lfsr_data[RANDOM_BIT_NUM-1:0] ^ i) << tgt_id_lfsr_data[$clog2(FLIT_DATA_LENGTH-RANDOM_BIT_NUM)-1:0]) | flit_data_mask;
|
||||
end
|
||||
|
||||
assign new_test[i].flit_head.txn_id = txn_counter + i;
|
||||
|
||||
assign new_test[i].timeout_threshold = SCOREBOARD_TIMEOUT_EN ? SCOREBOARD_TIMEOUT_THRESHOLD : '0; // 0 means no timeout error
|
||||
|
||||
assign new_test[i].mcycle_when_generated = mcycle_i;
|
||||
|
||||
logic [TEST_CASE_NUM_PER_CYCLE-1:0][2-1:0] random_device_port;
|
||||
assign random_device_port[i] = src_id_lfsr_data[i*2+:2] ^ tgt_id_lfsr_data[i*2+:2];
|
||||
always_comb begin
|
||||
new_test[i].flit_head.src_id.device_port = '0;
|
||||
new_test[i].flit_head.src_id.device_id = '0;
|
||||
new_test[i].flit_head.tgt_id.device_port = '0;
|
||||
new_test[i].flit_head.tgt_id.device_id = '0;
|
||||
|
||||
unique case(random_device_port[i]) // chooose which local port to route from/to(single router mode doesn't have local to local case)
|
||||
2'd0: begin
|
||||
new_test[i].flit_head.src_id.device_port = 0;
|
||||
new_test[i].flit_head.tgt_id.device_port = 0;
|
||||
end
|
||||
`ifdef LOCAL_PORT_NUM_2
|
||||
2'd1: begin
|
||||
new_test[i].flit_head.src_id.device_port = 1;
|
||||
new_test[i].flit_head.tgt_id.device_port = 1;
|
||||
end
|
||||
`endif
|
||||
`ifdef LOCAL_PORT_NUM_3
|
||||
2'd2: begin
|
||||
if(LOCAL_PORT_SENDER_NUM >= 3) begin
|
||||
new_test[i].flit_head.src_id.device_port = 2;
|
||||
new_test[i].flit_head.tgt_id.device_port = 2;
|
||||
end else begin
|
||||
new_test[i].flit_head.src_id.device_port = 1;
|
||||
new_test[i].flit_head.tgt_id.device_port = 1;
|
||||
end
|
||||
end
|
||||
`endif
|
||||
`ifdef LOCAL_PORT_NUM_4
|
||||
2'd3: begin
|
||||
new_test[i].flit_head.src_id.device_port = 3;
|
||||
new_test[i].flit_head.tgt_id.device_port = 3;
|
||||
end
|
||||
`endif
|
||||
default: begin
|
||||
new_test[i].flit_head.src_id.device_port = 0;
|
||||
new_test[i].flit_head.tgt_id.device_port = 0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
else if(TEST_CASE_MESH_RANDOM) begin: gen_test_case_mesh_random
|
||||
for(i = 0; i < TEST_CASE_NUM_PER_CYCLE; i++) begin: gen_new_test
|
||||
always_comb begin
|
||||
new_test[i].flit_head.src_id.x_position = src_id_lfsr_data[i*3+:3] % NODE_NUM_X_DIMESION;
|
||||
new_test[i].flit_head.src_id.y_position = src_id_lfsr_data[RANDOM_BIT_NUM-1-i*3-:3] % NODE_NUM_Y_DIMESION;
|
||||
|
||||
new_test[i].flit_head.tgt_id.x_position = tgt_id_lfsr_data[i*3+:3] % NODE_NUM_X_DIMESION;
|
||||
new_test[i].flit_head.tgt_id.y_position = tgt_id_lfsr_data[RANDOM_BIT_NUM-1-i*3-:3] % NODE_NUM_Y_DIMESION;
|
||||
end
|
||||
|
||||
|
||||
logic [FLIT_DATA_LENGTH-1:0] flit_data_mask;
|
||||
always_comb begin
|
||||
flit_data_mask = ~({RANDOM_BIT_NUM{1'b1}} << tgt_id_lfsr_data[$clog2(FLIT_DATA_LENGTH-RANDOM_BIT_NUM)-1:0]);
|
||||
new_test[i].flit_data = '1;
|
||||
new_test[i].flit_data = ((src_id_lfsr_data[RANDOM_BIT_NUM-1:0] ^ i) << tgt_id_lfsr_data[$clog2(FLIT_DATA_LENGTH-RANDOM_BIT_NUM)-1:0]) | flit_data_mask;
|
||||
end
|
||||
|
||||
assign new_test[i].flit_head.txn_id = txn_counter + i;
|
||||
|
||||
`ifdef COMMON_QOS_EXTRA_RT_VC
|
||||
assign new_test[i].timeout_threshold = (new_test[i].qos_value == '1) ? 2 * (NODE_NUM_X_DIMESION + NODE_NUM_Y_DIMESION - 1) :
|
||||
SCOREBOARD_TIMEOUT_EN ? SCOREBOARD_TIMEOUT_THRESHOLD : '0;
|
||||
`else
|
||||
assign new_test[i].timeout_threshold = SCOREBOARD_TIMEOUT_EN ? SCOREBOARD_TIMEOUT_THRESHOLD : '0;
|
||||
`endif
|
||||
|
||||
assign new_test[i].mcycle_when_generated = mcycle_i;
|
||||
|
||||
assign new_test[i].flit_head.src_id.device_id = '0;
|
||||
assign new_test[i].flit_head.tgt_id.device_id = '0;
|
||||
|
||||
assign new_test[i].flit_head.src_id.device_port = (src_id_lfsr_data[i*2+:2] ^ tgt_id_lfsr_data[RANDOM_BIT_NUM-1-i*2-:2]) % LOCAL_PORT_NUM;
|
||||
assign new_test[i].flit_head.tgt_id.device_port = (src_id_lfsr_data[RANDOM_BIT_NUM-1-i*2-:2] ^ tgt_id_lfsr_data[i*2+:2]) % LOCAL_PORT_NUM;
|
||||
end
|
||||
end
|
||||
|
||||
else if(TEST_CASE_MESH_DIAGONAL) begin: gen_test_case_mesh_diagonal
|
||||
for(i = 0; i < TEST_CASE_NUM_PER_CYCLE; i++) begin: gen_new_test
|
||||
always_comb begin
|
||||
new_test[i].flit_head.src_id.x_position = 0;
|
||||
new_test[i].flit_head.src_id.y_position = 0;
|
||||
|
||||
new_test[i].flit_head.tgt_id.x_position = NODE_NUM_X_DIMESION - 1;
|
||||
new_test[i].flit_head.tgt_id.y_position = NODE_NUM_Y_DIMESION - 1;
|
||||
end
|
||||
|
||||
|
||||
logic [FLIT_DATA_LENGTH-1:0] flit_data_mask;
|
||||
always_comb begin
|
||||
flit_data_mask = ~({RANDOM_BIT_NUM{1'b1}} << tgt_id_lfsr_data[$clog2(FLIT_DATA_LENGTH-RANDOM_BIT_NUM)-1:0]);
|
||||
new_test[i].flit_data = '1;
|
||||
new_test[i].flit_data = ((src_id_lfsr_data[RANDOM_BIT_NUM-1:0] ^ i) << tgt_id_lfsr_data[$clog2(FLIT_DATA_LENGTH-RANDOM_BIT_NUM)-1:0]) | flit_data_mask;
|
||||
end
|
||||
|
||||
assign new_test[i].flit_head.txn_id = txn_counter + i;
|
||||
|
||||
assign new_test[i].timeout_threshold = SCOREBOARD_TIMEOUT_EN ? SCOREBOARD_TIMEOUT_THRESHOLD : '0;
|
||||
|
||||
assign new_test[i].mcycle_when_generated = mcycle_i;
|
||||
|
||||
assign new_test[i].flit_head.src_id.device_id = '0;
|
||||
assign new_test[i].flit_head.tgt_id.device_id = '0;
|
||||
|
||||
assign new_test[i].flit_head.src_id.device_port = 0;
|
||||
assign new_test[i].flit_head.tgt_id.device_port = 0;
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
||||
generate
|
||||
if(TEST_CASE_SINGLE_ROUTER) begin: gen_test_case_look_ahead_routing_single_router // the dut router is assume to be (1,1)
|
||||
for(i = 0; i < TEST_CASE_NUM_PER_CYCLE; i++) begin: gen_new_test_look_ahead_routing
|
||||
always_comb begin
|
||||
if(new_test[i].flit_head.tgt_id.x_position > 1) begin
|
||||
new_test[i].flit_head.look_ahead_routing = E;
|
||||
end else if(new_test[i].flit_head.tgt_id.x_position < 1) begin
|
||||
new_test[i].flit_head.look_ahead_routing = W;
|
||||
end else if(new_test[i].flit_head.tgt_id.y_position > 1) begin
|
||||
new_test[i].flit_head.look_ahead_routing = N;
|
||||
end else if(new_test[i].flit_head.tgt_id.y_position < 1) begin
|
||||
new_test[i].flit_head.look_ahead_routing = S;
|
||||
end else begin
|
||||
unique case(new_test[i].flit_head.tgt_id.device_port) // chooose which local port to route to
|
||||
0: begin
|
||||
new_test[i].flit_head.look_ahead_routing = L0;
|
||||
end
|
||||
`ifdef LOCAL_PORT_NUM_2
|
||||
1: begin
|
||||
new_test[i].flit_head.look_ahead_routing = L1;
|
||||
end
|
||||
`endif
|
||||
`ifdef LOCAL_PORT_NUM_3
|
||||
2: begin
|
||||
new_test[i].flit_head.look_ahead_routing = L2;
|
||||
end
|
||||
`endif
|
||||
`ifdef LOCAL_PORT_NUM_4
|
||||
3: begin
|
||||
new_test[i].flit_head.look_ahead_routing = L3;
|
||||
end
|
||||
`endif
|
||||
default: begin
|
||||
new_test[i].flit_head.look_ahead_routing = L0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
else if(TEST_CASE_MESH_RANDOM || TEST_CASE_MESH_DIAGONAL) begin: gen_test_case_look_ahead_routing_mesh_x
|
||||
for(i = 0; i < TEST_CASE_NUM_PER_CYCLE; i++) begin: gen_new_test_look_ahead_routing
|
||||
always_comb begin
|
||||
if(new_test[i].flit_head.tgt_id.x_position > new_test[i].flit_head.src_id.x_position) begin
|
||||
new_test[i].flit_head.look_ahead_routing = E;
|
||||
end else if(new_test[i].flit_head.tgt_id.x_position < new_test[i].flit_head.src_id.x_position) begin
|
||||
new_test[i].flit_head.look_ahead_routing = W;
|
||||
end else if(new_test[i].flit_head.tgt_id.y_position > new_test[i].flit_head.src_id.y_position) begin
|
||||
new_test[i].flit_head.look_ahead_routing = N;
|
||||
end else if(new_test[i].flit_head.tgt_id.y_position < new_test[i].flit_head.src_id.y_position) begin
|
||||
new_test[i].flit_head.look_ahead_routing = S;
|
||||
end else begin
|
||||
unique case(new_test[i].flit_head.tgt_id.device_port) // chooose which local port to route to
|
||||
0: begin
|
||||
new_test[i].flit_head.look_ahead_routing = L0;
|
||||
end
|
||||
`ifdef LOCAL_PORT_NUM_2
|
||||
1: begin
|
||||
new_test[i].flit_head.look_ahead_routing = L1;
|
||||
end
|
||||
`endif
|
||||
`ifdef LOCAL_PORT_NUM_3
|
||||
2: begin
|
||||
new_test[i].flit_head.look_ahead_routing = L2;
|
||||
end
|
||||
`endif
|
||||
`ifdef LOCAL_PORT_NUM_4
|
||||
3: begin
|
||||
new_test[i].flit_head.look_ahead_routing = L3;
|
||||
end
|
||||
`endif
|
||||
default: begin
|
||||
new_test[i].flit_head.look_ahead_routing = L0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
logic [TEST_CASE_NUM_PER_CYCLE-1:0][3-1:0] random_qos;
|
||||
generate
|
||||
for(i = 0; i < TEST_CASE_NUM_PER_CYCLE; i++) begin: gen_new_test_qos_value
|
||||
assign random_qos[i] = src_id_lfsr_data[i*3+:3] ^~ tgt_id_lfsr_data[i*3+:3];
|
||||
`ifdef USE_QOS_VALUE
|
||||
always_comb begin
|
||||
unique case(random_qos[i])
|
||||
0, 1: begin
|
||||
new_test[i].qos_value = 4;
|
||||
new_test[i].flit_head.qos_value = 4;
|
||||
end
|
||||
2, 3: begin
|
||||
new_test[i].qos_value = 8;
|
||||
new_test[i].flit_head.qos_value = 8;
|
||||
end
|
||||
4: begin
|
||||
new_test[i].qos_value = 15;
|
||||
new_test[i].flit_head.qos_value = 15;
|
||||
end
|
||||
default: begin
|
||||
new_test[i].qos_value = '0;
|
||||
new_test[i].flit_head.qos_value = '0;
|
||||
end
|
||||
endcase
|
||||
|
||||
// if((new_test[i].flit_head.src_id.x_position == 0) &&
|
||||
// (new_test[i].flit_head.src_id.y_position == 0) &&
|
||||
// (new_test[i].flit_head.src_id.device_port == 0)) begin
|
||||
// new_test[i].qos_value = '1;
|
||||
// new_test[i].flit_head.qos_value = '1;
|
||||
// end
|
||||
end
|
||||
`else
|
||||
assign new_test[i].qos_value = '0;
|
||||
`endif
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
||||
|
||||
generate
|
||||
for(i = 0; i < TEST_CASE_NUM_PER_CYCLE; i++) begin: gen_new_test_vld
|
||||
`ifdef ALLOW_SAME_ROUTER_L2L_TRANSFER
|
||||
assign new_test_vld[i] = ~((new_test[i].flit_head.src_id.x_position == new_test[i].flit_head.tgt_id.x_position) &&
|
||||
(new_test[i].flit_head.src_id.y_position == new_test[i].flit_head.tgt_id.y_position) &&
|
||||
(new_test[i].flit_head.src_id.device_port == new_test[i].flit_head.tgt_id.device_port)
|
||||
);
|
||||
`else
|
||||
assign new_test_vld[i] = (new_test[i].flit_head.src_id.x_position != new_test[i].flit_head.tgt_id.x_position) |
|
||||
(new_test[i].flit_head.src_id.y_position != new_test[i].flit_head.tgt_id.y_position);
|
||||
`endif
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
||||
|
||||
LFSR #(.NUM_BITS(RANDOM_BIT_NUM)) src_id_gen_u (
|
||||
.i_Clk (clk),
|
||||
.i_Enable (rstn),
|
||||
.i_Seed_DV (lfsr_update_en_i ),
|
||||
.i_Seed_Data (src_id_lfsr_seed_i),
|
||||
.o_LFSR_Data (src_id_lfsr_data),
|
||||
.o_LFSR_Done ()
|
||||
);
|
||||
|
||||
LFSR #(.NUM_BITS(RANDOM_BIT_NUM)) tgt_id_gen_u (
|
||||
.i_Clk (clk),
|
||||
.i_Enable (rstn),
|
||||
.i_Seed_DV (lfsr_update_en_i ),
|
||||
.i_Seed_Data (tgt_id_lfsr_seed_i),
|
||||
.o_LFSR_Data (tgt_id_lfsr_data),
|
||||
.o_LFSR_Done ()
|
||||
);
|
||||
|
||||
always_ff @(posedge clk or negedge rstn ) begin
|
||||
if(~rstn) begin
|
||||
txn_counter <= '0;
|
||||
end else if(|new_test_vld) begin
|
||||
txn_counter <= txn_counter + TEST_CASE_NUM_PER_CYCLE;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// display app throughput
|
||||
|
||||
logic [SENDER_NUM-1:0][64-1:0] flit_num_counter_d, flit_num_counter_q; // sent
|
||||
logic [SENDER_NUM-1:0] flit_num_counter_ena;
|
||||
logic [64-1:0] flit_num_counter_all_d, flit_num_counter_all_q;
|
||||
logic flit_num_counter_all_ena;
|
||||
|
||||
logic [SENDER_NUM-1:0][64-1:0] flit_num_gened_counter_d, flit_num_gened_counter_q; // generated, no matter whether it is sent
|
||||
logic [SENDER_NUM-1:0] flit_num_gened_counter_ena;
|
||||
logic [64-1:0] flit_num_gened_counter_all_d, flit_num_gened_counter_all_q;
|
||||
logic flit_num_gened_counter_all_ena;
|
||||
|
||||
|
||||
generate
|
||||
for(i = 0; i < SENDER_NUM; i++) begin: gen_flit_num_counter_q
|
||||
std_dffre
|
||||
#(.WIDTH(64))
|
||||
U_DAT_FLIT_NUM_COUNTER
|
||||
(
|
||||
.clk(clk),
|
||||
.rstn(rstn),
|
||||
.en(flit_num_counter_ena[i]),
|
||||
.d (flit_num_counter_d [i]),
|
||||
.q (flit_num_counter_q [i])
|
||||
);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
std_dffre
|
||||
#(.WIDTH(64))
|
||||
U_DAT_FLIT_NUM_ALL_COUNTER
|
||||
(
|
||||
.clk(clk),
|
||||
.rstn(rstn),
|
||||
.en(flit_num_counter_all_ena),
|
||||
.d (flit_num_counter_all_d ),
|
||||
.q (flit_num_counter_all_q )
|
||||
);
|
||||
|
||||
generate
|
||||
for(i = 0; i < SENDER_NUM; i++) begin: gen_flit_gened_num_counter_q
|
||||
std_dffre
|
||||
#(.WIDTH(64))
|
||||
U_DAT_FLIT_GENED_NUM_COUNTER
|
||||
(
|
||||
.clk(clk),
|
||||
.rstn(rstn),
|
||||
.en(flit_num_gened_counter_ena[i]),
|
||||
.d (flit_num_gened_counter_d [i]),
|
||||
.q (flit_num_gened_counter_q [i])
|
||||
);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
std_dffre
|
||||
#(.WIDTH(64))
|
||||
U_DAT_FLIT_GENED_NUM_ALL_COUNTER
|
||||
(
|
||||
.clk(clk),
|
||||
.rstn(rstn),
|
||||
.en(flit_num_gened_counter_all_ena),
|
||||
.d (flit_num_gened_counter_all_d ),
|
||||
.q (flit_num_gened_counter_all_q )
|
||||
);
|
||||
|
||||
real flit_num_counter[SENDER_NUM-1:0];
|
||||
real flit_num_counter_all;
|
||||
real flit_num_gened_counter[SENDER_NUM-1:0];
|
||||
real flit_num_gened_counter_all;
|
||||
real mcycle;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
flit_num_counter_all_d = flit_num_counter_all_q;
|
||||
flit_num_counter_all_ena = 1'b0;
|
||||
|
||||
flit_num_gened_counter_all_d = flit_num_gened_counter_all_q;
|
||||
flit_num_gened_counter_all_ena = 1'b0;
|
||||
|
||||
mcycle = mcycle_i;
|
||||
flit_num_counter_all = flit_num_counter_all_q;
|
||||
flit_num_gened_counter_all = flit_num_gened_counter_all_q;
|
||||
|
||||
for(int i = 0; i < SENDER_NUM; i++) begin
|
||||
flit_num_counter_d [i] = flit_num_counter_q[i];
|
||||
flit_num_counter_ena[i] = 1'b0;
|
||||
|
||||
flit_num_gened_counter_d [i] = flit_num_gened_counter_q[i];
|
||||
flit_num_gened_counter_ena[i] = 1'b0;
|
||||
|
||||
flit_num_counter[i] = flit_num_counter_q[i];
|
||||
flit_num_gened_counter[i] = flit_num_gened_counter_q[i];
|
||||
|
||||
if(new_test_vld_o[i]) begin
|
||||
flit_num_gened_counter_d [i] = flit_num_gened_counter_q[i] + 1;
|
||||
flit_num_gened_counter_ena[i] = 1'b1;
|
||||
|
||||
flit_num_gened_counter_all_d = flit_num_gened_counter_all_d + 1;
|
||||
flit_num_gened_counter_all_ena = 1'b1;
|
||||
|
||||
if(new_test_rdy_i[i]) begin
|
||||
$display("[%16d] info: test_generator gen case to sender: %2d, [average_app_gen_bandwidth: %fGBps], [average_app_bandwidth: %fGBps]",
|
||||
$time(), i,
|
||||
((flit_num_gened_counter[i] * FLIT_LENGTH /8/1024/1024/1024) / (mcycle / ASSUMED_SYSTEM_FREQUENCY)),
|
||||
((flit_num_counter[i] * FLIT_LENGTH /8/1024/1024/1024) / (mcycle / ASSUMED_SYSTEM_FREQUENCY)));
|
||||
|
||||
flit_num_counter_d [i] = flit_num_counter_q[i] + 1;
|
||||
flit_num_counter_ena[i] = 1'b1;
|
||||
|
||||
flit_num_counter_all_d = flit_num_counter_all_d + 1;
|
||||
flit_num_counter_all_ena = 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
if(|(new_test_vld_o & new_test_rdy_i)) begin
|
||||
$display("[%16d] info: test_generator gen case to sender:all, [average_app_gen_bandwidth: %fGBps], [average_app_bandwidth: %fGBps]",
|
||||
$time(),
|
||||
((flit_num_gened_counter_all * FLIT_LENGTH /8/1024/1024/1024) / (mcycle / ASSUMED_SYSTEM_FREQUENCY)),
|
||||
((flit_num_counter_all * FLIT_LENGTH /8/1024/1024/1024) / (mcycle / ASSUMED_SYSTEM_FREQUENCY)));
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
||||
Reference in New Issue
Block a user