blob: 9a798fff1eafe838633453d37af8783214377beb [file] [log] [blame]
/// Copyright by Syntacore LLC © 2016-2020. See LICENSE for details
/// @file <scr1_top_tb_runtests.sv>
/// @brief SCR1 testbench run tests
///
//-------------------------------------------------------------------------------
// Run tests
//-------------------------------------------------------------------------------
initial begin
//$value$plusargs("imem_pattern=%h", imem_req_ack_stall);
//$value$plusargs("dmem_pattern=%h", dmem_req_ack_stall);
//$display("imem_pattern:%x",imem_req_ack_stall);
//$display("dmem_pattern:%x",dmem_req_ack_stall);
`ifdef SIGNATURE_OUT
$value$plusargs("test_name=%s", s_testname);
b_single_run_flag = 1;
`else // SIGNATURE_OUT
$value$plusargs("test_info=%s", s_info);
$value$plusargs("test_results=%s", s_results);
f_info = $fopen(s_info, "r");
f_results = $fopen(s_results, "a");
`endif // SIGNATURE_OUT
end
/***
// Debug message - dinesh A
logic [`SCR1_DMEM_AWIDTH-1:0] core2imem_addr_o_r; // DMEM address
logic [`SCR1_DMEM_AWIDTH-1:0] core2dmem_addr_o_r; // DMEM address
logic core2dmem_cmd_o_r;
`define RISC_CORE i_top.i_core_top_0
always@(posedge `RISC_CORE.clk) begin
if(`RISC_CORE.imem2core_req_ack_i && `RISC_CORE.core2imem_req_o)
core2imem_addr_o_r <= `RISC_CORE.core2imem_addr_o;
if(`RISC_CORE.dmem2core_req_ack_i && `RISC_CORE.core2dmem_req_o) begin
core2dmem_addr_o_r <= `RISC_CORE.core2dmem_addr_o;
core2dmem_cmd_o_r <= `RISC_CORE.core2dmem_cmd_o;
end
if(`RISC_CORE.imem2core_resp_i !=0)
$display("RISCV-DEBUG => IMEM ADDRESS: %x Read Data : %x Resonse: %x", core2imem_addr_o_r,`RISC_CORE.imem2core_rdata_i,`RISC_CORE.imem2core_resp_i);
if((`RISC_CORE.dmem2core_resp_i !=0) && core2dmem_cmd_o_r)
$display("RISCV-DEBUG => DMEM ADDRESS: %x Write Data: %x Resonse: %x", core2dmem_addr_o_r,`RISC_CORE.core2dmem_wdata_o,`RISC_CORE.dmem2core_resp_i);
if((`RISC_CORE.dmem2core_resp_i !=0) && !core2dmem_cmd_o_r)
$display("RISCV-DEBUG => DMEM ADDRESS: %x READ Data : %x Resonse: %x", core2dmem_addr_o_r,`RISC_CORE.dmem2core_rdata_i,`RISC_CORE.dmem2core_resp_i);
end
**/
/***
logic [31:0] test_count;
`define RISC_CORE u_top.u_riscv_top.i_core_top_0
`define RISC_EXU u_top.u_riscv_top.i_core_top.i_pipe_top.i_pipe_exu
initial begin
test_count = 0;
end
always@(posedge `RISC_CORE.clk) begin
if(`RISC_EXU.pc_curr_upd) begin
$display("RISCV-DEBUG => Cnt: %x PC: %x", test_count,`RISC_EXU.pc_curr_ff);
test_count <= test_count+1;
end
end
***/
wire [31:0] pc_curr_ff = (d_risc_id == 0) ? u_top.u_riscv_top.i_core_top_0.i_pipe_top.i_pipe_exu.pc_curr_ff : u_top.u_riscv_top.i_core_top_1.i_pipe_top.i_pipe_exu.pc_curr_ff;
wire [31:0] exu2pipe_pc_curr_o = (d_risc_id == 0) ? u_top.u_riscv_top.i_core_top_0.i_pipe_top.i_pipe_exu.exu2pipe_pc_curr_o : u_top.u_riscv_top.i_core_top_1.i_pipe_top.i_pipe_exu.exu2pipe_pc_curr_o;
wire [31:0] mprf_int_10 = (d_risc_id == 0) ? u_top.u_riscv_top.i_core_top_0.i_pipe_top.i_pipe_mprf.mprf_int[10] : u_top.u_riscv_top.i_core_top_1.i_pipe_top.i_pipe_mprf.mprf_int[10];
always @(posedge clk) begin
bit test_pass;
int unsigned f_test;
int unsigned f_test_ram;
if (test_running) begin
test_pass = 1;
rst_init <= 1'b0;
if(pc_curr_ff === 32'hxxxx_xxxx) begin
$display("ERROR: CURRENT PC Counter State is Known");
$finish;
end
if ((exu2pipe_pc_curr_o == YCR1_SIM_EXIT_ADDR) & ~rst_init & &rst_cnt) begin
`ifdef VERILATOR
logic [255:0] full_filename;
full_filename = test_file;
`else // VERILATOR
string full_filename;
full_filename = test_file;
`endif // VERILATOR
if (is_compliance(test_file)) begin
logic [31:0] tmpv, start, stop, ref_data, test_data;
integer fd;
`ifdef VERILATOR
logic [2047:0] tmpstr;
`else // VERILATOR
string tmpstr;
`endif // VERILATOR
// Flush the content of dcache for signature validation at app
// memory
force u_top.u_riscv_top.u_mintf.u_intf.u_dcache.cfg_force_flush = 1'b1;
wait(u_top.u_riscv_top.u_mintf.u_intf.u_dcache.force_flush_done == 1'b1);
release u_top.u_riscv_top.u_mintf.u_intf.u_dcache.cfg_force_flush;
repeat (2000) @(posedge clock); // wait data to flush in pipe
$display("STATUS: Checking Complaince Test Status .... ");
test_running <= 1'b0;
test_pass = 1;
$sformat(tmpstr, "riscv64-unknown-elf-readelf -s %s | grep 'begin_signature\\|end_signature' | awk '{print $2}' > elfinfo", get_filename(test_file));
fd = $fopen("script.sh", "w");
if (fd == 0) begin
$write("Can't open script.sh\n");
$display("ERRIR:Can't open script.sh\n");
test_pass = 0;
end
$fwrite(fd, "%s", tmpstr);
$fclose(fd);
$system("sh script.sh");
fd = $fopen("elfinfo", "r");
if (fd == 0) begin
$write("Can't open elfinfo\n");
$display("ERROR: Can't open elfinfo\n");
test_pass = 0;
end
if ($fscanf(fd,"%h\n%h", start, stop) != 2) begin
$write("Wrong elfinfo data\n");
$display("ERROR:Wrong elfinfo data: start: %x stop: %x\n",start,stop);
test_pass = 0;
end
if (start > stop) begin
tmpv = start;
start = stop;
stop = tmpv;
end
$fclose(fd);
start = start & 32'h07FF_FFFF;
stop = stop & 32'h07FF_FFFF;
$display("Complaince Signature Start Address: %x End Address:%x",start,stop);
//if((start & 32'h1FFF) > 512)
// $display("ERROR: Start address is more than 512, Start: %x",start & 32'h1FFF);
//if((stop & 32'h1FFF) > 512)
// $display("ERROR: Stop address is more than 512, Start: %x",stop & 32'h1FFF);
`ifdef SIGNATURE_OUT
$sformat(tmpstr, "%s.signature.output", s_testname);
`ifdef VERILATOR
tmpstr = remove_trailing_whitespaces(tmpstr);
`endif
fd = $fopen(tmpstr, "w");
while ((start != stop)) begin
//test_data = u_top.u_sram0_2kb.mem[(start & 32'h1FFF)];
test_data = {u_sram.memory[start+3], u_sram.memory[start+2], u_sram.memory[start+1], u_sram.memory[start]};
$fwrite(fd, "%x", test_data);
$fwrite(fd, "%s", "\n");
start += 4;
end
$fclose(fd);
`else //SIGNATURE_OUT
$sformat(tmpstr, "riscv_compliance/ref_data/%s", get_ref_filename(test_file));
`ifdef VERILATOR
tmpstr = remove_trailing_whitespaces(tmpstr);
`endif
fd = $fopen(tmpstr,"r");
if (fd == 0) begin
$write("Can't open reference_data file: %s\n", tmpstr);
$display("ERROR: Can't open reference_data file: %s\n", tmpstr);
test_pass = 0;
end
while (!$feof(fd) && (start != stop)) begin
$fscanf(fd, "0x%h,\n", ref_data);
//----------------------------------------------------
// Assumed all signaure are with-in first 512 location of memory,
// other-wise need to switch bank
// --------------------------------------------------
//$writememh("sram0_out.hex",u_top.u_tsram0_2kb.mem,0,511);
//test_data = u_top.u_sram0_2kb.mem[((start >> 2) & 32'h1FFF)];
test_data = {u_sram.memory[start+3], u_sram.memory[start+2], u_sram.memory[start+1], u_sram.memory[start]};
//$display("Compare Addr: %x ref_data : %x, test_data: %x",start,ref_data,test_data);
test_pass &= (ref_data == test_data);
if(ref_data != test_data)
$display("ERROR: Compare Addr: %x Mem Addr: %x ref_data : %x, test_data: %x",start,start & 32'h1FFF,ref_data,test_data);
else
$display("STATUS: Compare Addr: %x Mem Addr: %x ref_data : %x",start,start & 32'h1FFF,ref_data);
start += 4;
end
$fclose(fd);
tests_total += 1;
tests_passed += test_pass;
if (test_pass) begin
$write("\033[0;32mTest passed\033[0m\n");
end else begin
$write("\033[0;31mTest failed-2\033[0m\n");
end
`endif // SIGNATURE_OUT
end else begin // Non compliance mode
test_running <= 1'b0;
if(mprf_int_10 != 0)
$display("ERROR: mprf_int[10]: %x not zero",mprf_int_10);
test_pass = (mprf_int_10 == 0);
tests_total += 1;
tests_passed += test_pass;
`ifndef SIGNATURE_OUT
if (test_pass) begin
$write("\033[0;32mTest passed\033[0m\n");
end else begin
$write("\033[0;31mTest failed\033[0m\n");
end
`endif //SIGNATURE_OUT
end
$fwrite(f_results, "%s\t\t%s\t%s\n", test_file, "OK" , (test_pass ? "PASS" : "__FAIL"));
end
end else begin
`ifdef VERILATOR
`ifdef SIGNATURE_OUT
if ((s_testname.len() != 0) && (b_single_run_flag)) begin
$sformat(test_file, "%s.bin", s_testname);
`else //SIGNATURE_OUT
if ($fgets(test_file,f_info)) begin
test_file = test_file >> 8; // < Removing trailing LF symbol ('\n')
`endif //SIGNATURE_OUT
`else // VERILATOR
if (!$feof(f_info)) begin
$fscanf(f_info, "%s\n", test_file);
`endif // VERILATOR
f_test = $fopen(test_file,"r");
if (f_test != 0) begin
// Launch new test
`ifdef YCR1_TRACE_LOG_EN
if(d_risc_id == 0)
u_top.u_riscv_top.i_core_top_0.i_pipe_top.i_tracelog.test_name = test_file;
else
u_top.u_riscv_top.i_core_top_1.i_pipe_top.i_tracelog.test_name = test_file;
`endif // SCR1_TRACE_LOG_EN
//i_memory_tb.test_file = test_file;
//i_memory_tb.test_file_init = 1'b1;
`ifndef SIGNATURE_OUT
$write("\033[0;34m---Test: %s\033[0m\n", test_file);
`endif //SIGNATURE_OUT
test_running <= 1'b1;
rst_init <= 1'b1;
`ifdef SIGNATURE_OUT
b_single_run_flag = 0;
`endif
end else begin
$fwrite(f_results, "%s\t\t%s\t%s\n", test_file, "__FAIL", "--------");
end
end else begin
// Exit
`ifndef SIGNATURE_OUT
$display("\n#--------------------------------------");
$display("# Summary: %0d/%0d tests passed", tests_passed, tests_total);
$display("#--------------------------------------\n");
$fclose(f_info);
$fclose(f_results);
`endif
$finish();
end
end
end
`ifdef VERILATOR
function bit is_compliance (logic [255:0] testname);
bit res;
logic [79:0] pattern;
begin
pattern = 80'h636f6d706c69616e6365; // compliance
res = 0;
for (int i = 0; i<= 176; i++) begin
if(testname[i+:80] == pattern) begin
return ~res;
end
end
`ifdef SIGNATURE_OUT
return ~res;
`else
return res;
`endif
end
endfunction : is_compliance
function logic [255:0] get_filename (logic [255:0] testname);
logic [255:0] res;
int i, j;
begin
testname[7:0] = 8'h66;
testname[15:8] = 8'h6C;
testname[23:16] = 8'h65;
for (i = 0; i <= 248; i += 8) begin
if (testname[i+:8] == 0) begin
break;
end
end
i -= 8;
for (j = 255; i >= 0;i -= 8) begin
res[j-:8] = testname[i+:8];
j -= 8;
end
for (; j >= 0;j -= 8) begin
res[j-:8] = 0;
end
return res;
end
endfunction : get_filename
function logic [255:0] get_ref_filename (logic [255:0] testname);
logic [255:0] res;
int i, j;
logic [79:0] pattern;
begin
pattern = 80'h636f6d706c69616e6365; // compliance
for(int i = 0; i <= 176; i++) begin
if(testname[i+:80] == pattern) begin
testname[(i-8)+:88] = 0;
break;
end
end
for(i = 32; i <= 248; i += 8) begin
if(testname[i+:8] == 0) break;
end
i -= 8;
for(j = 255; i > 24; i -= 8) begin
res[j-:8] = testname[i+:8];
j -= 8;
end
for(; j >=0;j -= 8) begin
res[j-:8] = 0;
end
return res;
end
endfunction : get_ref_filename
function logic [2047:0] remove_trailing_whitespaces (logic [2047:0] str);
int i;
begin
for (i = 0; i <= 2040; i += 8) begin
if (str[i+:8] != 8'h20) begin
break;
end
end
str = str >> i;
return str;
end
endfunction: remove_trailing_whitespaces
`else // VERILATOR
function bit is_compliance (string testname);
begin
return (testname.substr(0, 9) == "compliance");
end
endfunction : is_compliance
function string get_filename (string testname);
int length;
begin
length = testname.len();
testname[length-1] = "f";
testname[length-2] = "l";
testname[length-3] = "e";
return testname;
end
endfunction : get_filename
function string get_ref_filename (string testname);
begin
return testname.substr(11, testname.len() - 5);
end
endfunction : get_ref_filename
`endif // VERILATOR