From 8ce40e27d1ec5eb53b871fc2e7aca1526a5993d8 Mon Sep 17 00:00:00 2001 From: sg05060 Date: Sat, 5 Oct 2024 19:33:50 +0900 Subject: [PATCH] update sim --- .gitignore | 1 + actions/sim_vivado/sim_vivado.tcl | 15 +- design/sverilog/VPU_PKG.svh | 2 +- env.source | 1 + sim/sverilog/VPU_TOP_TB.sv | 211 ++++++++++++--------- sim/sverilog/temp/VPU_TOP_TB.sv | 300 ++++++++++++++++++++++++++++++ 6 files changed, 436 insertions(+), 94 deletions(-) create mode 100644 sim/sverilog/temp/VPU_TOP_TB.sv diff --git a/.gitignore b/.gitignore index 390cc03..6255d2d 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ vivado/ actions/sim_vivado/*.jou actions/sim_vivado/*.log +*.str \ No newline at end of file diff --git a/actions/sim_vivado/sim_vivado.tcl b/actions/sim_vivado/sim_vivado.tcl index 03f4a24..5cfc8f0 100644 --- a/actions/sim_vivado/sim_vivado.tcl +++ b/actions/sim_vivado/sim_vivado.tcl @@ -72,16 +72,23 @@ add_files -fileset sim_1 [get_filename_arr $sim_filelists $env_map] update_compile_order -fileset sim_1 +set vpu_home $env(VPU_HOME) +set sv_root_path "$env(VPU_HOME)/sw/C/DPI/xsim.dir/work/xsc/" +set inputfile_path "/home/rhgksdma/VPU_Design/inputfile/bf16_numbers.txt" # set_property SOURCE_SET sources_1 [get_filesets sim_1] set_property include_dirs $search_path [get_filesets sim_1] set_property top VPU_TOP_TB [get_filesets sim_1] set_property -name {xsim.compile.xvlog.more_options} -value {-L uvm} -objects [get_filesets sim_1] set_property -name {xsim.elaborate.xelab.more_options} -value {-L uvm} -objects [get_filesets sim_1] -set_property -name {xsim.elaborate.xelab.more_options} -value {-L uvm} -objects [get_filesets sim_1] - -set_property -name {xsim.simulate.xsim.more_options} -value {-testplusarg "OPCODE=1 TESTVECTOR=/home/rhgksdma/VPU_Design/inputfile/bf16_numbers.txt GOLDEN_FILE=/home/rhgksdma/VPU_Design/inputfile/add_out.txt"} -objects [get_filesets sim_1] -# launch_simulation +#set_property -name {xsim.elaborate.xelab.more_options} -value {-L uvm} -objects [get_filesets sim_1] +#set_property -name {xsim.elaborate.xelab.more_options} -value {-sv_root $vpu_home/sw/C/DPI/xsim.dir/work/xsc/ -sv_lib dpi} -objects [get_filesets sim_1] +#set_property -name {xsim.elaborate.xelab.more_options} -value {-sv_root [eval $vpu_home/sw/C/DPI/xsim.dir/work/xsc/] -sv_lib dpi} -objects [get_filesets sim_1] +set_property -name {xsim.elaborate.xelab.more_options} -value "-sv_root $sv_root_path -sv_lib dpi" -objects [get_filesets sim_1] +#set_property -name {xsim.simulate.xsim.more_options} -value {-testplusarg "OPCODE=1 TESTVECTOR=/home/rhgksdma/VPU_Design/inputfile/bf16_numbers.txt GOLDEN_FILE=/home/rhgksdma/VPU_Design/inputfile/add_out.txt"} -objects [get_filesets sim_1] +#set_property -name {xsim.simulate.xsim.more_options} -value "-testplusarg " -objects [get_filesets sim_1] + +launch_simulation # set_property -name {xsim.simulate.xsim.more_options} -value {-testplusarg "OPCODE=2 TESTVECTOR=/home/rhgksdma/VPU_Design/inputfile/bf16_numbers.txt GOLDEN_FILE=/home/rhgksdma/VPU_Design/inputfile/sub_out.txt"} -objects [get_filesets sim_1] # launch_simulation diff --git a/design/sverilog/VPU_PKG.svh b/design/sverilog/VPU_PKG.svh index 5850b32..779ac0d 100644 --- a/design/sverilog/VPU_PKG.svh +++ b/design/sverilog/VPU_PKG.svh @@ -13,7 +13,7 @@ package VPU_PKG; /* VPU Instruction Config */ localparam INSTR_WIDTH = 136; - localparam INSTR_NUM = 12; + localparam INSTR_NUM = 14; localparam OPCODE_WIDTH = 8; localparam OPERAND_WIDTH = ELEM_WIDTH; localparam OPERAND_ADDR_WIDTH = 32; diff --git a/env.source b/env.source index f68c59d..b7adaaa 100644 --- a/env.source +++ b/env.source @@ -9,5 +9,6 @@ export ${IP_NAME}_HOME=${WORKING_DIR} export DESIGN_TOP=VPU_TOP_WRAPPER export DESIGN_FILELIST=${WORKING_DIR}/design/filelist.f export TB_FILELIST=${WORKING_DIR}/sim/filelist.f +export TB_TESTVECTOR=${WORKING_DIR}/sim/testvector export ACTION_HOME=${WORKING_DIR}/actions export PATH=${ACTION_HOME}:${HOME}/.local/bin:$PATH \ No newline at end of file diff --git a/sim/sverilog/VPU_TOP_TB.sv b/sim/sverilog/VPU_TOP_TB.sv index a588b10..1ff7071 100644 --- a/sim/sverilog/VPU_TOP_TB.sv +++ b/sim/sverilog/VPU_TOP_TB.sv @@ -3,6 +3,8 @@ `define MEM_DEPTH 10 `define RANDOM_SEED 12123344 +import "DPI-C" context function string get_env_var(input string var_name); + module VPU_TOP_TB (); import VPU_PKG::*; @@ -10,7 +12,9 @@ module VPU_TOP_TB (); reg rst_n; localparam REQ_CNT = `MEM_DEPTH; - + string testvector_path; + string sub_path; + string path; typedef struct { bit [VPU_PKG::DIM_SIZE-1:0] operand; } operand_t; @@ -19,10 +23,12 @@ module VPU_TOP_TB (); int opcode_value; string test_vector_f; string golden_ref_f; + bit done; + int cnt =0; // Data Structure - //VPU_PKG::vpu_h2d_req_opcode_t opcode_queue[$]; - - VPU_PKG::vpu_h2d_req_opcode_t opcode = 'h0D; + VPU_PKG::vpu_h2d_req_opcode_t opcode_queue[$]; + VPU_PKG::vpu_h2d_req_opcode_t c_opcode; + VPU_PKG::vpu_h2d_req_instr_t instr_queue[$]; typedef operand_t src_queue[$]; typedef operand_t dst_queue[$]; @@ -39,36 +45,10 @@ module VPU_TOP_TB (); $finish; end - // opcode generation - initial begin - if ($value$plusargs("OPCODE=%d", opcode_value)) begin - //opcode = vpu_h2d_req_opcode_t'(opcode_value & {8{1'b1}}); - $display("OPCODE : %05d", opcode_value); - //opcode = vpu_h2d_req_opcode_t'(opcode_value); - end else begin - $display("OPCODE Not Found"); - end - end - - // opcode generation - initial begin - if ($value$plusargs("TESTVECTOR=%s", test_vector_f)) begin - $display("TESTVECTOR : %s", test_vector_f); - //opcode = vpu_h2d_req_opcode_t'(opcode_value); - end else begin - $display("TESTVECTOR Not Found"); - end - end - //w - - // opcode generation + // Search Directory Path initial begin - if ($value$plusargs("GOLDEN_FILE=%s", golden_ref_f)) begin - $display("GOLDEN_FILE : %s", golden_ref_f); - //opcode = vpu_h2d_req_opcode_t'(opcode_value); - end else begin - $display("GOLDEN_FILE Not Found"); - end + testvector_path = get_env_var("TB_TESTVECTOR"); + $display("TESTVECTOR : %s", testvector_path); end // clock generation @@ -133,31 +113,37 @@ module VPU_TOP_TB (); vpu_src2_port_if.init(); vpu_dst0_port_if.init(); - $display("Loading Data..."); - $readmemh(test_vector_f,mem_dump); - - $display("Loading Golden Ref..."); - $readmemh(golden_ref_f,golden_ref_dump); - + $display("Loading Data[%s]...",{testvector_path,sub_path}); + sub_path = "/bf16_numbers.txt"; + $readmemh({testvector_path,sub_path},mem_dump); + + fill_opcode(); @(posedge rst_n); repeat (10) @(posedge clk); endtask + task fill_opcode(); + VPU_PKG::vpu_h2d_req_opcode_t opcode; + for(int i = 1; i <= VPU_PKG::INSTR_NUM; i++) begin + opcode = vpu_h2d_req_opcode_t'(i & {8{1'b1}}); + opcode_queue.push_back(opcode); + end + endtask - task gen_instr(); + task gen_instr(VPU_PKG::vpu_h2d_req_opcode_t _opcode); VPU_PKG::vpu_h2d_req_instr_t instr; for(int i = 0; i < REQ_CNT; i++) begin - instr.opcode = vpu_h2d_req_opcode_t'(opcode_value & {8{1'b1}}); - $write("Gen Opcode...%1d\n", instr.opcode); + instr.opcode = _opcode; + //$write("Gen Opcode...%1d\n", instr.opcode); instr.src2 = $random & {VPU_PKG::OPERAND_ADDR_WIDTH{1'b1}}; instr.src1 = $random & {VPU_PKG::OPERAND_ADDR_WIDTH{1'b1}}; instr.src0 = $random & {VPU_PKG::OPERAND_ADDR_WIDTH{1'b1}}; instr.dst0 = $random & {VPU_PKG::OPERAND_ADDR_WIDTH{1'b1}}; instr_queue.push_back(instr); - $write("Gen Instr...%1d\n", i); + //$write("Gen Instr...%1d\n", i); end - $write("Finish Gen Instr...\n"); + //$write("Finish Gen Instr...\n"); endtask task fill_src_operand_queue(); @@ -168,7 +154,7 @@ module VPU_TOP_TB (); operand.operand[(k*VPU_PKG::OPERAND_WIDTH)+:VPU_PKG::OPERAND_WIDTH] = mem_dump[((i*VPU_PKG::ELEM_PER_DIM_CNT*VPU_PKG::SRAM_R_PORT_CNT)+(j)*(VPU_PKG::ELEM_PER_DIM_CNT))+k]; end tot_src_queue[j].push_back(operand); - $write("src[%d]port | answer : [0x%08h]\n", j, operand.operand); + //$write("src[%d]port | answer : [0x%08h]\n", j, operand.operand); end end repeat (3) @(posedge clk); @@ -180,32 +166,89 @@ module VPU_TOP_TB (); end repeat (3) @(posedge clk); endtask + + task clear_src_operand_queue(); + for(int i = 0; i < SRAM_R_PORT_CNT; i++) begin + tot_src_queue[i].delete(); + end + repeat (3) @(posedge clk); + endtask + + task fill_golden_ref_mem(VPU_PKG::vpu_h2d_req_opcode_t _opcode); + if(_opcode == VPU_PKG::VPU_H2D_REQ_OPCODE_FADD) begin + sub_path = "/add_out.txt"; + end else if(_opcode == VPU_PKG::VPU_H2D_REQ_OPCODE_FSUB) begin + sub_path = "/sub_out.txt"; + end else if(_opcode == VPU_PKG::VPU_H2D_REQ_OPCODE_FMUL) begin + sub_path = "/mul_out.txt"; + end else if(_opcode == VPU_PKG::VPU_H2D_REQ_OPCODE_FDIV) begin + sub_path = "/div_out.txt"; + end else if(_opcode == VPU_PKG::VPU_H2D_REQ_OPCODE_FADD3) begin + sub_path = "/add3_out.txt"; + end else if(_opcode == VPU_PKG::VPU_H2D_REQ_OPCODE_FSUM) begin + sub_path = "/redsum_out.txt"; + end else if(_opcode == VPU_PKG::VPU_H2D_REQ_OPCODE_FMAX) begin + sub_path = "/redmax_out.txt"; + end else if(_opcode == VPU_PKG::VPU_H2D_REQ_OPCODE_FMAX2) begin + sub_path = "/max_out.txt"; + end else if(_opcode == VPU_PKG::VPU_H2D_REQ_OPCODE_FMAX3) begin + sub_path = "/max3_out.txt"; + end else if(_opcode == VPU_PKG::VPU_H2D_REQ_OPCODE_FAVG2) begin + sub_path = "/avg_out.txt"; + end else if(_opcode == VPU_PKG::VPU_H2D_REQ_OPCODE_FAVG3) begin + sub_path = "/avg3_out.txt"; + end else if(_opcode == VPU_PKG::VPU_H2D_REQ_OPCODE_FEXP) begin + sub_path = "/exp_out.txt"; + end else if(_opcode == VPU_PKG::VPU_H2D_REQ_OPCODE_FSQRT) begin + sub_path = "/sqrt_out.txt"; + end else if(_opcode == VPU_PKG::VPU_H2D_REQ_OPCODE_FRECIP) begin + sub_path = "/rec_out.txt"; + end else begin + sub_path = ""; + end + $readmemh({testvector_path,sub_path},golden_ref_dump); + $display("Loading GL Data[%s]...",{testvector_path,sub_path}); + endtask - task build_test(); + task build_test(VPU_PKG::vpu_h2d_req_opcode_t _opcode); + clear_src_operand_queue(); fill_src_operand_queue(); - clear_dst_operand_queue(); - gen_instr(); + clear_dst_operand_queue(); + fill_golden_ref_mem(_opcode); + gen_instr(_opcode); endtask - task run(); - fork + task run_test(); + done = 1'b0; + fork: fork_1 driver_req(); - driver_src0; - driver_src1; - driver_src2; - //driver_dst0; + driver_src0(); + driver_src1(); + driver_src2(); oMonitor(); - join + join_any: fork_1 + wait(done); + @(posedge clk); + //done = 1'b0; + disable fork_1; + //$write("Iter Pass..."); endtask - task run_test(); - run(); + task run(); + while (opcode_queue.size()!=0) begin + c_opcode = opcode_queue.pop_front(); + build_test(c_opcode); + @(posedge clk); + run_test(); + //$write("Run_Test Pass : %05d\n",done); + @(posedge clk); + end endtask - + task driver_req(); VPU_PKG::vpu_h2d_req_instr_t instr; while (instr_queue.size()!=0) begin - $write("Push Instr...%1d\n", instr_queue.size()); + //$write("Push Instr...%1d\n", instr_queue.size()); instr = instr_queue.pop_front(); // pop a request from the queue vpu_req_if.gen_request(instr); // drive to DUT end @@ -217,8 +260,10 @@ module VPU_TOP_TB (); while (tot_src_queue[0].size()!=0) begin operand = tot_src_queue[0].pop_front(); vpu_src0_port_if.sram_read_transaction(operand.operand); - $write("Read0 trans finish...%1d\n", tot_src_queue[0].size()); + //$write("Read0 trans finish...%1d\n", tot_src_queue[0].size()); end + //$write("diver_src0 finish...\n"); + endtask task driver_src1(); @@ -226,8 +271,10 @@ module VPU_TOP_TB (); while (tot_src_queue[1].size()!=0) begin operand = tot_src_queue[1].pop_front(); vpu_src1_port_if.sram_read_transaction(operand.operand); - $write("Read1 trans finish...%1d\n", tot_src_queue[1].size()); + //$write("Read1 trans finish...%1d\n", tot_src_queue[1].size()); end + //$write("diver_src1 finish...\n"); + endtask task driver_src2(); @@ -235,47 +282,34 @@ module VPU_TOP_TB (); while (tot_src_queue[2].size()!=0) begin operand = tot_src_queue[2].pop_front(); vpu_src2_port_if.sram_read_transaction(operand.operand); - $write("Read2 trans finish...%1d\n", tot_src_queue[2].size()); - end - endtask - - /* - task driver_dst0(); - operand_t operand; - while (tot_dst_queue[0].size() < `MEM_DEPTH) begin - vpu_dst0_port_if.sram_write_transaction(operand.operand); - tot_dst_queue[0].push_back(operand); - $write("Write trans finish...%1d\n", tot_dst_queue[0].size()); + //$write("Read2 trans finish...%1d\n", tot_src_queue[2].size()); end + //$write("diver_src2 finish...\n"); + endtask - */ - task oMonitor(); operand_t result; operand_t answer; - int cnt = 0; - while (1) begin - if( cnt >= REQ_CNT) begin - $write("<< All Pass!!! %1d : ", cnt); - $finish; - end - + cnt = 0; + while (cnt < REQ_CNT) begin vpu_dst0_port_if.sram_write_transaction(result.operand); for(int i = 0; i < ELEM_PER_DIM_CNT; i++) begin answer.operand[(i*VPU_PKG::OPERAND_WIDTH)+:(VPU_PKG::OPERAND_WIDTH)] = golden_ref_dump[((cnt)*(VPU_PKG::ELEM_PER_DIM_CNT))+i]; end if(result != answer) begin - $write("<< %5dth request [Error][Incorrect] (OPCODE %1d) : ", cnt, opcode); + $write("<< %5dth request [Error][Incorrect] (OPCODE %1d) : ", cnt, c_opcode); $write("result [0x%08h] | answer : [0x%08h]\n", result.operand, answer.operand); - @(posedge clk); - $finish; + //@(posedge clk); + //$finish; end else begin - $write("<< %5dth request [Correct] (OPCODE %1d) : ", cnt, opcode); + $write("<< %5dth request [Correct] (OPCODE %1d) : ", cnt, c_opcode); $write("result [0x%08h] | answer : [0x%08h]\n", result.operand, answer.operand); end cnt++; end + $write("<< All Pass!!! %1d : \n", c_opcode); + done = 1'b1; endtask @@ -283,10 +317,9 @@ module VPU_TOP_TB (); $display("====================Start Simulation!===================="); test_init(); - build_test(); - //fork - run_test(); - //join + + run(); + $display("====================Simulation Done!===================="); $finish; end diff --git a/sim/sverilog/temp/VPU_TOP_TB.sv b/sim/sverilog/temp/VPU_TOP_TB.sv new file mode 100644 index 0000000..ac5e729 --- /dev/null +++ b/sim/sverilog/temp/VPU_TOP_TB.sv @@ -0,0 +1,300 @@ +`include "VPU_PKG.svh" +`define TIMEOUT_DELAY 100000000 +`define MEM_DEPTH 10 +`define RANDOM_SEED 12123344 + +import "DPI-C" context function string get_env_var(input string var_name); + +module VPU_TOP_TB (); + + import VPU_PKG::*; + reg clk; + reg rst_n; + + localparam REQ_CNT = `MEM_DEPTH; + string vpu_home; + typedef struct { + bit [VPU_PKG::DIM_SIZE-1:0] operand; + } operand_t; + + // Input Argument + int opcode_value; + string test_vector_f; + string golden_ref_f; + // Data Structure + //VPU_PKG::vpu_h2d_req_opcode_t opcode_queue[$]; + + VPU_PKG::vpu_h2d_req_opcode_t opcode = 'h0D; + VPU_PKG::vpu_h2d_req_instr_t instr_queue[$]; + typedef operand_t src_queue[$]; + typedef operand_t dst_queue[$]; + src_queue tot_src_queue[VPU_PKG::SRAM_R_PORT_CNT]; + dst_queue tot_dst_queue[VPU_PKG::SRAM_W_PORT_CNT]; + + reg [VPU_PKG::OPERAND_WIDTH-1:0] mem_dump[VPU_PKG::ELEM_PER_DIM_CNT * VPU_PKG::SRAM_R_PORT_CNT * `MEM_DEPTH]; + reg [VPU_PKG::OPERAND_WIDTH-1:0] golden_ref_dump[VPU_PKG::ELEM_PER_DIM_CNT * REQ_CNT]; + + + // timeout + initial begin + #`TIMEOUT_DELAY $display("Timeout!"); + $finish; + end + + // opcode generation + initial begin + if ($value$plusargs("OPCODE=%d", opcode_value)) begin + //opcode = vpu_h2d_req_opcode_t'(opcode_value & {8{1'b1}}); + $display("OPCODE : %05d", opcode_value); + //opcode = vpu_h2d_req_opcode_t'(opcode_value); + end else begin + $display("OPCODE Not Found"); + end + end + + // opcode generation + initial begin + if ($value$plusargs("TESTVECTOR=%s", test_vector_f)) begin + $display("TESTVECTOR : %s", test_vector_f); + vpu_home = get_env_var("VPU_HOME"); + $display("TESTVECTOR : %s", vpu_home); + //opcode = vpu_h2d_req_opcode_t'(opcode_value); + end else begin + $display("TESTVECTOR Not Found"); + vpu_home = get_env_var("VPU_HOME"); + $display("TESTVECTOR : %s", vpu_home); + end + end + //w + + // opcode generation + initial begin + if ($value$plusargs("GOLDEN_FILE=%s", golden_ref_f)) begin + $display("GOLDEN_FILE : %s", golden_ref_f); + //opcode = vpu_h2d_req_opcode_t'(opcode_value); + end else begin + $display("GOLDEN_FILE Not Found"); + end + end + + // clock generation + initial begin + clk = 1'b0; + + forever #10 clk = !clk; + end + + // reset generation + initial begin + rst_n = 1'b0; // active at time 0 + + repeat (3) @(posedge clk); // after 3 cycles, + rst_n = 1'b1; // release the reset + end + + //timeout + initial begin + #`TIMEOUT_DELAY $display("Timeout!"); + $finish; + end + + // inject random seed + initial begin + $srandom(`RANDOM_SEED); + end + + //---------------------------------------------------------- + // Connection between DUT and test modules + //---------------------------------------------------------- + + VPU_REQ_IF vpu_req_if (.clk(clk), .rst_n(rst_n)); + VPU_SRC_PORT_IF vpu_src0_port_if (.clk(clk), .rst_n(rst_n)); + VPU_SRC_PORT_IF vpu_src1_port_if (.clk(clk), .rst_n(rst_n)); + VPU_SRC_PORT_IF vpu_src2_port_if (.clk(clk), .rst_n(rst_n)); + VPU_DST_PORT_IF vpu_dst0_port_if (.clk(clk), .rst_n(rst_n)); + + VPU_TOP #( + //... + ) u_DUT ( + .clk (clk), + .rst_n (rst_n), + + .vpu_req_if (vpu_req_if), + .vpu_src0_port_if (vpu_src0_port_if), + .vpu_src1_port_if (vpu_src1_port_if), + .vpu_src2_port_if (vpu_src2_port_if), + .vpu_dst0_port_if (vpu_dst0_port_if) + ); + + // enable waveform dump + initial begin + $dumpvars(0, u_DUT); + $dumpfile("dump.vcd"); + end + + task test_init(); + vpu_req_if.init(); + vpu_src0_port_if.init(); + vpu_src1_port_if.init(); + vpu_src2_port_if.init(); + vpu_dst0_port_if.init(); + + $display("Loading Data..."); + $readmemh(test_vector_f,mem_dump); + + $display("Loading Golden Ref..."); + $readmemh(golden_ref_f,golden_ref_dump); + + @(posedge rst_n); + repeat (10) @(posedge clk); + endtask + + + task gen_instr(); + VPU_PKG::vpu_h2d_req_instr_t instr; + for(int i = 0; i < REQ_CNT; i++) begin + instr.opcode = vpu_h2d_req_opcode_t'(opcode_value & {8{1'b1}}); + $write("Gen Opcode...%1d\n", instr.opcode); + instr.src2 = $random & {VPU_PKG::OPERAND_ADDR_WIDTH{1'b1}}; + instr.src1 = $random & {VPU_PKG::OPERAND_ADDR_WIDTH{1'b1}}; + instr.src0 = $random & {VPU_PKG::OPERAND_ADDR_WIDTH{1'b1}}; + instr.dst0 = $random & {VPU_PKG::OPERAND_ADDR_WIDTH{1'b1}}; + + instr_queue.push_back(instr); + $write("Gen Instr...%1d\n", i); + end + $write("Finish Gen Instr...\n"); + endtask + + task fill_src_operand_queue(); + operand_t operand; + for(int i = 0; i < `MEM_DEPTH; i++) begin + for(int j = 0; j < SRAM_R_PORT_CNT; j++) begin + for(int k = 0; k < ELEM_PER_DIM_CNT; k++) begin + operand.operand[(k*VPU_PKG::OPERAND_WIDTH)+:VPU_PKG::OPERAND_WIDTH] = mem_dump[((i*VPU_PKG::ELEM_PER_DIM_CNT*VPU_PKG::SRAM_R_PORT_CNT)+(j)*(VPU_PKG::ELEM_PER_DIM_CNT))+k]; + end + tot_src_queue[j].push_back(operand); + $write("src[%d]port | answer : [0x%08h]\n", j, operand.operand); + end + end + repeat (3) @(posedge clk); + endtask + + task clear_dst_operand_queue(); + for(int i = 0; i < SRAM_W_PORT_CNT; i++) begin + tot_dst_queue[i].delete(); + end + repeat (3) @(posedge clk); + endtask + + task build_test(); + fill_src_operand_queue(); + clear_dst_operand_queue(); + gen_instr(); + endtask + + task run(); + fork + driver_req(); + driver_src0; + driver_src1; + driver_src2; + //driver_dst0; + oMonitor(); + join + endtask + + task run_test(); + run(); + endtask + + task driver_req(); + VPU_PKG::vpu_h2d_req_instr_t instr; + while (instr_queue.size()!=0) begin + $write("Push Instr...%1d\n", instr_queue.size()); + instr = instr_queue.pop_front(); // pop a request from the queue + vpu_req_if.gen_request(instr); // drive to DUT + end + + endtask + + task driver_src0(); + operand_t operand; + while (tot_src_queue[0].size()!=0) begin + operand = tot_src_queue[0].pop_front(); + vpu_src0_port_if.sram_read_transaction(operand.operand); + $write("Read0 trans finish...%1d\n", tot_src_queue[0].size()); + end + endtask + + task driver_src1(); + operand_t operand; + while (tot_src_queue[1].size()!=0) begin + operand = tot_src_queue[1].pop_front(); + vpu_src1_port_if.sram_read_transaction(operand.operand); + $write("Read1 trans finish...%1d\n", tot_src_queue[1].size()); + end + endtask + + task driver_src2(); + operand_t operand; + while (tot_src_queue[2].size()!=0) begin + operand = tot_src_queue[2].pop_front(); + vpu_src2_port_if.sram_read_transaction(operand.operand); + $write("Read2 trans finish...%1d\n", tot_src_queue[2].size()); + end + endtask + + /* + task driver_dst0(); + operand_t operand; + while (tot_dst_queue[0].size() < `MEM_DEPTH) begin + vpu_dst0_port_if.sram_write_transaction(operand.operand); + tot_dst_queue[0].push_back(operand); + $write("Write trans finish...%1d\n", tot_dst_queue[0].size()); + end + endtask + */ + + + task oMonitor(); + operand_t result; + operand_t answer; + int cnt = 0; + while (1) begin + if( cnt >= REQ_CNT) begin + $write("<< All Pass!!! %1d : ", cnt); + $finish; + end + + vpu_dst0_port_if.sram_write_transaction(result.operand); + for(int i = 0; i < ELEM_PER_DIM_CNT; i++) begin + answer.operand[(i*VPU_PKG::OPERAND_WIDTH)+:(VPU_PKG::OPERAND_WIDTH)] = golden_ref_dump[((cnt)*(VPU_PKG::ELEM_PER_DIM_CNT))+i]; + end + if(result != answer) begin + $write("<< %5dth request [Error][Incorrect] (OPCODE %1d) : ", cnt, opcode); + $write("result [0x%08h] | answer : [0x%08h]\n", result.operand, answer.operand); + @(posedge clk); + $finish; + end else begin + $write("<< %5dth request [Correct] (OPCODE %1d) : ", cnt, opcode); + $write("result [0x%08h] | answer : [0x%08h]\n", result.operand, answer.operand); + end + cnt++; + end + endtask + + + initial begin + $display("====================Start Simulation!===================="); + + test_init(); + build_test(); + //fork + run_test(); + //join + $display("====================Simulation Done!===================="); + $finish; + end + +endmodule \ No newline at end of file