Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added an initial support for binary based testbench. #93

Merged
merged 4 commits into from
Nov 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
16 changes: 9 additions & 7 deletions etc/scripts/test_panda.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,11 @@ def __call__(self, parser, namespace, values, option_string=None):
def GetChildren(parent_pid):
ret = set()
ps_command = subprocess.Popen(
"ps -o pid --ppid %d --noheaders" % parent_pid, shell=True, stdout=subprocess.PIPE)
ps_output = ps_command.stdout.read()
"ps --ppid %d -o pid=" % parent_pid, shell=True, stdout=subprocess.PIPE)
ps_command.wait()
for pid_str in ps_output.split("\n")[:-1]:
ret.add(int(pid_str))
ps_output = ps_command.stdout.read().decode()
for pid_str in ps_output.split('\n')[:-1]:
ret.add(int(pid_str, base=10))
return ret

# Kill a process than kill its children
Expand Down Expand Up @@ -1093,19 +1093,21 @@ def CreatePerfPublisherBody(directory, pp_file):
try:
# Wait threads
for thread_index in range(n_jobs):
while threads[thread_index].is_alive():
while threads[thread_index].isAlive():
threads[thread_index].join(100)
except KeyboardInterrupt:
logging.error("SIGINT received")
failure = True
with lock_creation_destruction:
failure = True
args.stop = True
for local_thread_index in range(n_jobs):
if children[local_thread_index] != None:
if children[local_thread_index].poll() == None:
try:
kill_proc_tree(children[local_thread_index].pid)
except OSError:
pass
sys.exit(1)
# sys.exit(1)

# Collect results
CollectResults(abs_path)
Expand Down
2 changes: 1 addition & 1 deletion panda_regressions/hls/bambu_specific_test2_list
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ bambu_specific_test2/port_swapping_test2.c --top-fname=function bambu_specific_t
bambu_specific_test2/complex_test.c --top-fname=sum --generate-tb=BENCHMARKS_ROOT/bambu_specific_test2/complex_test.xml --experimental-setup=BAMBU
bambu_specific_test2/multiarray.c --top-fname=fun2 --generate-tb=arr1="{{{3,0},{0,0}},{{8,3},{8,0}}}",arr2="{{{5,2},{0,1}},{{7,3},{5,0}}}",arr3="{{{3,0},{7,0}},{{3,5},{0,0}}}" --std=c99 --experimental-setup=BAMBU
bambu_specific_test2/test_without_c.c --top-fname=function --generate-tb=BENCHMARKS_ROOT/bambu_specific_test2/test_without_c.xml --experimental-setup=BAMBU-BALANCED-MP
bambu_specific_test2/mod_test.c --top-fname=test --generate-tb=BENCHMARKS_ROOT/bambu_specific_test2/mod_test_c.xml
bambu_specific_test2/mod_test.c --top-fname=test --generate-tb=BENCHMARKS_ROOT/bambu_specific_test2/mod_test_c.xml
Binary file not shown.
4 changes: 4 additions & 0 deletions panda_regressions/hls/bambu_specific_test6/bin_test.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0"?>
<function>
<testbench a_ptr:init_file="bin_test.dat"/>
</function>
12 changes: 12 additions & 0 deletions panda_regressions/hls/bambu_specific_test6/bin_testbench.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
typedef struct c_t {
unsigned nrow;
unsigned nnz;
float value[20];
unsigned cindex[20];
unsigned rowstart[20];
} complex_t;

unsigned kernel(complex_t*a_ptr)
{
return a_ptr->value[1];
}
2 changes: 2 additions & 0 deletions panda_regressions/hls/bambu_specific_test6_list
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,5 @@ bambu_specific_test6/insert_extract_element.ll --benchmark-name=insert_extract3
bambu_specific_test6/insert_extract_element.ll --benchmark-name=insert_extract3_output_c --top-fname=test3 --generate-tb="P0=1,P1=2,P2=3,P3=4,P4=5,P5=6,P6=7,P7=8" --pretty-print=output.c --max-transformations=0
bambu_specific_test6/insert_extract_element.ll --benchmark-name=insert_extract4 --top-fname=test3 --generate-tb="P0=1,P1=2,P2=3,P3=4,P4=5,P5=6,P6=7,P7=8"
bambu_specific_test6/insert_extract_element.ll --benchmark-name=insert_extract4_output_c --top-fname=test3 --generate-tb="P0=1,P1=2,P2=3,P3=4,P4=5,P5=6,P6=7,P7=8" --pretty-print=output.c

bambu_specific_test6/bin_testbench.c --top-fname=kernel --generate-tb=BENCHMARKS_ROOT/bambu_specific_test6/bin_test.xml --experimental-setup=BAMBU-BALANCED-MP --file-input-data=BENCHMARKS_ROOT/bambu_specific_test6/bin_test.dat
10 changes: 4 additions & 6 deletions src/HLS/simulation/testbench_generation_base_step.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -539,8 +539,7 @@ void TestbenchGenerationBaseStep::write_output_checks(const tree_managerConstRef
auto InterfaceType = GetPointer<port_o>(portInst)->get_port_interface();
if(InterfaceType == port_o::port_interface::PI_DOUT)
{
const auto manage_pidout = [&](const std::string& portID)
{
const auto manage_pidout = [&](const std::string& portID) {
auto port_name = portInst->get_id();
auto terminate = port_name.size() > 3 ? port_name.size() - std::string("_d" + portID).size() : 0;
THROW_ASSERT(port_name.substr(terminate) == "_d" + portID, "inconsistent interface");
Expand Down Expand Up @@ -640,8 +639,7 @@ void TestbenchGenerationBaseStep::write_output_checks(const tree_managerConstRef
auto InterfaceType = GetPointer<port_o>(portInst)->get_port_interface();
if(InterfaceType == port_o::port_interface::PI_DIN)
{
const auto manage_pidin = [&](const std::string& portID)
{
const auto manage_pidin = [&](const std::string& portID) {
auto port_name = portInst->get_id();
auto terminate = port_name.size() > 3 ? port_name.size() - std::string("_q" + portID).size() : 0;
THROW_ASSERT(port_name.substr(terminate) == "_q" + portID, "inconsistent interface");
Expand Down Expand Up @@ -896,7 +894,7 @@ void TestbenchGenerationBaseStep::write_output_checks(const tree_managerConstRef
{
if(output_level >= OUTPUT_LEVEL_VERY_PEDANTIC)
{
writer->write("$display(\" comparision = %b " + nonescaped_name +
writer->write("$display(\" comparison = %b " + nonescaped_name +
" = %d "
" _bambu_testbench_mem_[" +
nonescaped_name + " + %d - base_addr] = %20.20f expected = %20.20f \", ");
Expand Down Expand Up @@ -1619,7 +1617,7 @@ void TestbenchGenerationBaseStep::write_output_checks(const tree_managerConstRef
{
if(output_level > OUTPUT_LEVEL_MINIMUM)
{
writer->write("$display(\" comparision = %b " + nonescaped_name +
writer->write("$display(\" comparison%b " + nonescaped_name +
" = %d "
" _bambu_testbench_mem_[" +
nonescaped_name + " + %d - base_addr] = %20.20f expected = %20.20f \", ");
Expand Down
7 changes: 6 additions & 1 deletion src/HLS/simulation/testbench_memory_allocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,12 @@ void TestbenchMemoryAllocation::AllocTestbenchMemory(void) const
if(tree_helper::IsPointerType(lnode) && !is_memory)
{
const auto pt_node = tree_helper::CGetType(lnode);
if(flag_cpp)
if(test_v.size() > 4 && test_v.substr(test_v.size() - 4) == ".dat")
{
std::ifstream in(test_v, std::ifstream::ate | std::ifstream::binary);
reserved_bytes = static_cast<unsigned>(in.tellg());
}
else if(flag_cpp)
{
tree_nodeConstRef ptd_base_type;
if(GET_CONST_NODE(pt_node)->get_kind() == pointer_type_K)
Expand Down
4 changes: 2 additions & 2 deletions src/HLS/simulation/testbench_values_xml_generation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ DesignFlowStep_Status TestbenchValuesXMLGeneration::Exec()
}
else
{
/// Call the parser to translate C initialization to verilog initialization
/// Call the parser to translate C initialization to Verilog initialization
const CInitializationParserFunctorRef c_initialization_parser_functor =
CInitializationParserFunctorRef(new MemoryInitializationWriter(
output_stream, TM, behavioral_helper, reserved_mem_bytes, TM->CGetTreeReindex(l),
Expand All @@ -309,7 +309,7 @@ DesignFlowStep_Status TestbenchValuesXMLGeneration::Exec()
output_stream << "m00000000" << std::endl;
}
}
INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "<--Cosidered parameter '" + param + "'");
INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "<--Considered parameter '" + param + "'");
}
++v_idx;
INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "<--Considered vector");
Expand Down
107 changes: 71 additions & 36 deletions src/design_flows/backend/ToC/source_code_writers/hls_c_writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,7 @@ void HLSCWriter::WriteParamInitialization(const BehavioralHelperConstRef behavio
"_size, " + fp + ") != " + param + "_size)\n");
indented_output_stream->Append("{\n");
indented_output_stream->Append("fclose(" + fp + ");\n");
indented_output_stream->Append("printf(\"Unable to read " + test_v + " to initialise parameter " + param +
indented_output_stream->Append("printf(\"Unable to read " + test_v + " to initialize parameter " + param +
"\");\n");
indented_output_stream->Append("exit(-1);\n");
indented_output_stream->Append("}\n");
Expand Down Expand Up @@ -892,7 +892,7 @@ void HLSCWriter::WriteExpectedResults(const BehavioralHelperConstRef behavioral_
indented_output_stream->Append("{\n");
}
WriteParamInMemory(behavioral_helper, param + (reference_type_p ? "" : "[i0]"),
pointedType_node->index, 1, false);
pointedType_node->index, 1, false, false);
if(num_elements > 1 || !reference_type_p)
{
indented_output_stream->Append("}\n");
Expand Down Expand Up @@ -947,14 +947,14 @@ void HLSCWriter::WriteExpectedResults(const BehavioralHelperConstRef behavioral_
const auto num_elements = reserved_mem_bytes / element_size;
THROW_ASSERT(num_elements, STR(reserved_mem_bytes) + "/" + STR(element_size));
indented_output_stream->Append("{\n");
indented_output_stream->Append("int i0;\n");
indented_output_stream->Append("int i0=0;\n");
if(num_elements > 1 || !reference_type_p)
{
indented_output_stream->Append("for(i0 = 0; i0 < " + STR(num_elements) + "; i0++)\n");
indented_output_stream->Append("{\n");
}
WriteParamInMemory(behavioral_helper, param + (reference_type_p ? "" : "[i0]"), pointedType_node->index, 1,
false);
false, false);
if(num_elements > 1 || !reference_type_p)
{
indented_output_stream->Append("}\n");
Expand Down Expand Up @@ -1066,6 +1066,7 @@ void HLSCWriter::WriteSimulatorInitMemory(const unsigned int function_id)

bool is_memory = false;
std::string test_v;
bool binary_test_v = false;
if(mem_vars.find(l) != mem_vars.end() && !is_interface)
{
is_memory = true;
Expand All @@ -1079,34 +1080,41 @@ void HLSCWriter::WriteSimulatorInitMemory(const unsigned int function_id)
else if(curr_test_vector.find(param) != curr_test_vector.end())
{
test_v = curr_test_vector.find(param)->second;
if(flag_cpp)
if(test_v.size() < 4 || test_v.substr(test_v.size() - 4) != ".dat")
{
/// Remove leading spaces
test_v.erase(0, test_v.find_first_not_of(" \t"));
/// Remove trailing spaces
auto last_character = test_v.find_last_not_of(" \t");
if(std::string::npos != last_character)
if(flag_cpp)
{
test_v.erase(last_character + 1);
}
/// Remove first {
if(test_v.front() == '{')
{
test_v.erase(0, 1);
/// Remove leading spaces
test_v.erase(0, test_v.find_first_not_of(" \t"));
/// Remove trailing spaces
auto last_character = test_v.find_last_not_of(" \t");
if(std::string::npos != last_character)
{
test_v.erase(last_character + 1);
}
/// Remove first {
if(test_v.front() == '{')
{
test_v.erase(0, 1);
}
/// Remove last }
if(test_v.back() == '}')
{
test_v.pop_back();
}
}
/// Remove last }
if(test_v.back() == '}')
else
{
test_v.pop_back();
if(test_v.front() != '{' && test_v.back() != '}')
{
test_v = std::string("{") + test_v;
test_v = test_v + "}";
}
}
}
else
{
if(test_v.front() != '{' && test_v.back() != '}')
{
test_v = std::string("{") + test_v;
test_v = test_v + "}";
}
binary_test_v = true;
}
}
else if(flag_cpp)
Expand All @@ -1125,8 +1133,7 @@ void HLSCWriter::WriteSimulatorInitMemory(const unsigned int function_id)
}

/// Retrieve the space to be reserved in memory
const auto reserved_mem_bytes = [&]() -> size_t
{
const auto reserved_mem_bytes = [&]() -> size_t {
if(is_memory)
{
const auto ret_value = tree_helper::Size(TM->CGetTreeReindex(l)) / 8;
Expand All @@ -1143,15 +1150,41 @@ void HLSCWriter::WriteSimulatorInitMemory(const unsigned int function_id)
"---Symbol: " + param + " Reserved memory " + STR(reserved_mem_bytes) + " - Test vector is " +
test_v);

/// FIXME: for c++ code the old code is still used
if(flag_cpp || is_memory)
if(binary_test_v)
{
const auto fp = param + "_fp_local";
indented_output_stream->Append("FILE* " + fp + " = fopen(\"" + test_v + "\", \"rb\");\n");
indented_output_stream->Append("fseek(" + fp + ", 0, SEEK_END);\n");
indented_output_stream->Append("size_t " + param + "_size = ftell(" + fp + ");\n");
indented_output_stream->Append("fseek(" + fp + ", 0, SEEK_SET);\n");
indented_output_stream->Append("unsigned char* " + param + "_buf_local = (unsigned char*)malloc(" + param +
"_size);\n");
indented_output_stream->Append("if(fread(" + param + "_buf_local, sizeof *" + param + "_buf_local, " +
param + "_size, " + fp + ") != " + param + "_size)\n");
indented_output_stream->Append("{\n");
indented_output_stream->Append("fclose(" + fp + ");\n");
indented_output_stream->Append("printf(\"Unable to read " + test_v + " to initialize parameter " + param +
"\");\n");
indented_output_stream->Append("exit(-1);\n");
indented_output_stream->Append("}\n");
indented_output_stream->Append("fclose(" + fp + ");\n");
indented_output_stream->Append(
"for (__testbench_index = 0; "
"__testbench_index < " +
param + "_size; " +
"++__testbench_index){\n fprintf(__bambu_testbench_fp, \"m\");\n _Dec2Bin_(__bambu_testbench_fp," +
param + "_buf_local[__testbench_index], 8);\n");
indented_output_stream->Append("}\n");
INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level,
"---Using a binary file for " + param + " - " + test_v);
}
else if(flag_cpp || is_memory) /// FIXME: for c++ code the old code is still used
{
size_t printed_bytes = 0;
std::string bits_offset = "";
std::vector<std::string> splitted = SplitString(test_v, ",");
INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---Processing c++ init " + test_v);
const auto isAllZero = [&]() -> bool
{
const auto isAllZero = [&]() -> bool {
if(splitted.size() == 0)
{
return false;
Expand Down Expand Up @@ -1635,7 +1668,8 @@ void HLSCWriter::WriteBuiltinWaitCall()
}

void HLSCWriter::WriteParamInMemory(const BehavioralHelperConstRef behavioral_helper, const std::string& param,
const unsigned int type_index, const unsigned int nesting_level, bool input)
const unsigned int type_index, const unsigned int nesting_level, bool input,
bool is_struct_or_union)
{
const auto type = TM->CGetTreeNode(type_index);
switch(type->get_kind())
Expand All @@ -1646,12 +1680,13 @@ void HLSCWriter::WriteParamInMemory(const BehavioralHelperConstRef behavioral_he
indented_output_stream->Append("fprintf(__bambu_testbench_fp, \"//expected value for output: " + param +
"\\n\");\n");
const auto size = tree_helper::Size(type);
if(input)
if(input || is_struct_or_union) // Checking ULP on expected floating point fields is not possible
{
const auto byte_size = tree_helper::Size(type) / 8;
for(size_t byte = 0; byte < byte_size; byte++)
{
indented_output_stream->Append("fprintf(__bambu_testbench_fp, \"m\");\n");
indented_output_stream->Append("fprintf(__bambu_testbench_fp, \"" + std::string(input ? "m" : "o") +
"\");\n");
indented_output_stream->Append("_Ptd2Bin_(__bambu_testbench_fp, ((unsigned char *)&(" + param + ")) + " +
STR(byte) + ", 8);\n");
indented_output_stream->Append("fprintf(__bambu_testbench_fp, \"\\n\");\n");
Expand Down Expand Up @@ -1689,7 +1724,7 @@ void HLSCWriter::WriteParamInMemory(const BehavioralHelperConstRef behavioral_he
{
const auto field_param = param + "." + behavioral_helper->PrintVariable(field->index);
WriteParamInMemory(behavioral_helper, field_param, tree_helper::get_type_index(TM, field->index),
nesting_level + 1, input);
nesting_level + 1, input, true);
}
break;
}
Expand All @@ -1700,7 +1735,7 @@ void HLSCWriter::WriteParamInMemory(const BehavioralHelperConstRef behavioral_he
{
const auto field_param = param + "." + behavioral_helper->PrintVariable(field->index);
WriteParamInMemory(behavioral_helper, field_param, tree_helper::get_type_index(TM, field->index),
nesting_level + 1, input);
nesting_level + 1, input, true);
break; // only the first field will be considered
}
break;
Expand All @@ -1723,7 +1758,7 @@ void HLSCWriter::WriteParamInMemory(const BehavioralHelperConstRef behavioral_he
"; " + variable_name + "++)\n");
indented_output_stream->Append("{\n");
WriteParamInMemory(behavioral_helper, param + "[" + variable_name + "]", array_t->index, nesting_level + 1,
input);
input, is_struct_or_union);
indented_output_stream->Append("}\n");
indented_output_stream->Append("}\n");
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ class HLSCWriter : public CWriter
* @param input specifies if the input syntax must be used
*/
void WriteParamInMemory(const BehavioralHelperConstRef behavioral_helper, const std::string& param,
const unsigned int type, const unsigned int nesting_level, bool input);
const unsigned int type, const unsigned int nesting_level, bool input, bool is_struct_or_union);

public:
/**
Expand Down