blob: 174e41a4baad93aea2801d4efabd33a636b49d68 [file] [log] [blame]
#include "simulator_bit_map.h"
#include "vtr_memory.h"
#include "vtr_util.h"
#include "odin_util.h"
#include <vector>
bit_map_values get_mapped_value(signed char value)
{
if(value == 0 || value == '0')
return _0;
else if(value == 1 || value == '1')
return _1;
else
return _x;
}
inline static bit_tree_map *bit_map_node()
{
bit_tree_map *node = (bit_tree_map *)vtr::malloc(sizeof(bit_tree_map));
for(int i=0; i<3; i++)
node->branch[i] = NULL;
return node;
}
inline static bit_tree_root *bit_map_root(const char *related_node_name, int depth)
{
bit_tree_root *root = (bit_tree_root *)vtr::malloc(sizeof(bit_tree_root));
root->depth = depth;
root->related_node_name = vtr::strdup(related_node_name);
root->branch[_0] = bit_map_node();
root->branch[_1] = bit_map_node();
return root;
}
inline static bit_tree_map *free_bit_branches(bit_tree_map *bit_map)
{
if(bit_map)
{
if(!bit_map->is_leaf)
{
bit_map->branch[_0] = free_bit_branches(bit_map->branch[_0]);
bit_map->branch[_1] = free_bit_branches(bit_map->branch[_1]);
bit_map->branch[_x] = free_bit_branches(bit_map->branch[_x]);
}
vtr::free(bit_map);
}
return NULL;
}
bit_tree_root *free_bit_tree(bit_tree_root *bit_map)
{
if(bit_map)
{
vtr::free(bit_map->related_node_name);
bit_map->branch[_0] = free_bit_branches(bit_map->branch[_0]);
bit_map->branch[_1] = free_bit_branches(bit_map->branch[_1]);
vtr::free(bit_map);
}
return NULL;
}
bit_tree_root *consume_bit_map_line(std::vector<std::string> lines, std::vector<char> results, const char *related_node_name)
{
if(lines.empty() || results.empty())
return NULL;
bit_tree_root *root = bit_map_root(related_node_name, lines[0].size());
for(int i=0; i < lines.size(); i++)
{
bit_map_values cur_trunk = get_mapped_value(results[i]);
bit_tree_map *cur_node = root->branch[cur_trunk];
if(lines[i].size() != lines[0].size())
error_message(SIMULATION_ERROR, -1, -1, "mismatched length in input lut @ line %d for node <%s>",i,root->related_node_name);
for(int j=0; j < lines[i].size(); j++)
{
bit_map_values cur_value = get_mapped_value(lines[i][j]);
if(!cur_node->branch[cur_value])
cur_node->branch[cur_value] = bit_map_node();
if(j+1 == lines[i].size())
cur_node->is_leaf = true;
}
}
return root;
}
static signed char explore_trunk(bit_tree_map *trunk, char result, const std::string& line, char set_to)
{
int end = line.size()-1;
bool error = false;
std::vector<bit_tree_map*> Q = {trunk};
std::vector<bit_tree_map*> new_Q;
for(int j=0; j <= end && !Q.empty() && !error; j++)
{
bit_map_values cur_value = get_mapped_value(line[j]);
for(int i=0; i < Q.size() && !error; i++)
{
bit_tree_map *bit_map = Q[i];
if(bit_map->is_leaf)
{
if(result)
{
error = true;
result = '!';
}
else
{
result = set_to;
}
}
else
{
if(bit_map->branch[cur_value])
new_Q.push_back(bit_map->branch[cur_value]);
//include unknown in defined search
if(cur_value != _x && bit_map->branch[_x])
new_Q.push_back(bit_map->branch[_x]);
}
}
Q.clear();
Q = new_Q;
new_Q.clear();
}
return result;
}
char find_result(bit_tree_root *root, std::string line)
{
if(!root)
error_message(SIMULATION_ERROR, -1, -1, "root bit_map is empty");
if(line == "")
return 3;
char result = 0;
if(root->depth > line.size())
error_message(SIMULATION_ERROR, -1, -1, "input missmatch: bit map length > input length ");
else if(root->depth < line.size())
error_message(SIMULATION_ERROR, -1, -1, "input missmatch: bit map length < input length ");
result = explore_trunk(root->branch[_0], result, line, '0');
result = explore_trunk(root->branch[_1], result, line, '1');
if(result == '!')
{
warning_message(SIMULATION_ERROR, -1, -1, "ambiguous bit map for .name <%s> with multiple, or no result for pattern", root->related_node_name);
result = 'x';
}
else if(!result)
{
result = 'x';
}
return result;
}