some more fixup
diff --git a/ODIN_II/SRC/ast_util.cpp b/ODIN_II/SRC/ast_util.cpp
index 0cf3142..e2d4a40 100644
--- a/ODIN_II/SRC/ast_util.cpp
+++ b/ODIN_II/SRC/ast_util.cpp
@@ -1055,7 +1055,7 @@
* Make a unique name for a module based on its parameter list
* e.g. for a "mod #(0,1,2,3) a(b,c,d)" instantiation you get name___0_1_2_3
*/
-char *make_module_param_name(STRING_CACHE *defines_for_module_sc, ast_node_t *module_param_list, char *module_name)
+char *make_module_param_name(STRING_CACHE *defines_sc, ast_node_t *module_param_list, char *module_name)
{
char *module_param_name = (char*)vtr::malloc((strlen(module_name)+1024) * sizeof(char));
strcpy(module_param_name, module_name);
@@ -1069,7 +1069,7 @@
{
if (module_param_list->children[i]->children[5])
{
- ast_node_t *node = resolve_node(defines_for_module_sc, module_name, module_param_list->children[i]->children[5]);
+ ast_node_t *node = resolve_node(defines_sc, module_name, module_param_list->children[i]->children[5]);
oassert(node->type == NUMBERS);
odin_sprintf(module_param_name, "%s_%ld", module_param_name, module_param_list->children[i]->children[5]->types.number.value);
}
@@ -1472,18 +1472,18 @@
/*---------------------------------------------------------------------------------------------
* (function: node_is_ast_constant)
*-------------------------------------------------------------------------------------------*/
-ast_node_t *node_is_ast_constant(ast_node_t *node, STRING_CACHE *defines_for_module_sc){
+ast_node_t *node_is_ast_constant(ast_node_t *node, STRING_CACHE *defines_sc){
if (node && (node_is_constant(node)
|| (node->types.variable.is_parameter == TRUE)
- || (node->type == UNARY_OPERATION && node_is_ast_constant(node->children[0], defines_for_module_sc))
- || (node->type == BINARY_OPERATION && node_is_ast_constant(node->children[0], defines_for_module_sc) && node_is_ast_constant(node->children[1], defines_for_module_sc))))
+ || (node->type == UNARY_OPERATION && node_is_ast_constant(node->children[0], defines_sc))
+ || (node->type == BINARY_OPERATION && node_is_ast_constant(node->children[0], defines_sc) && node_is_ast_constant(node->children[1], defines_sc))))
{
return node;
}
else if (node && node->type == IDENTIFIERS) {
int sc_spot;
- if ((sc_spot = sc_lookup_string(defines_for_module_sc, node->types.identifier)) != -1
- && node_is_ast_constant((ast_node_t *)defines_for_module_sc->data[sc_spot]))
+ if ((sc_spot = sc_lookup_string(defines_sc, node->types.identifier)) != -1
+ && node_is_ast_constant((ast_node_t *)defines_sc->data[sc_spot]))
{
return node;
}
diff --git a/ODIN_II/SRC/enum_str.cpp b/ODIN_II/SRC/enum_str.cpp
index 7834365..cc67166 100644
--- a/ODIN_II/SRC/enum_str.cpp
+++ b/ODIN_II/SRC/enum_str.cpp
@@ -2,23 +2,26 @@
const char *file_extension_supported_STR[] =
{
- ".v"
+ ".v",
+ "file_extension_supported_END"
};
const char *signedness_STR[] =
{
"SIGNED",
- "UNSIGNED"
+ "UNSIGNED",
+ "signedness_END"
};
const char *edge_type_e_STR[] =
{
- "UNDEFINED_SENSITIVITY",
- "FALLING_EDGE_SENSITIVITY",
- "RISING_EDGE_SENSITIVITY",
- "ACTIVE_HIGH_SENSITIVITY",
- "ACTIVE_LOW_SENSITIVITY",
- "ASYNCHRONOUS_SENSITIVITY",
+ "undef",
+ "fe",
+ "re",
+ "ah",
+ "al",
+ "as",
+ "edge_type_e_END"
};
const char *_ZERO_GND_ZERO[] =
@@ -106,7 +109,7 @@
{"GENERIC", "GEN"}, /*added for the unknown node type */
{"FULLADDER", "FlADD"},
{"CLOG2", "CL2"}, // $clog2
- {"ERROR OOB", "OOB"} // should not reach this
+ {"operation_list_END", "operation_list_END"} // should not reach this
};
const char *ids_STR []=
diff --git a/ODIN_II/SRC/include/ast_util.h b/ODIN_II/SRC/include/ast_util.h
index 81b7127..442b916 100644
--- a/ODIN_II/SRC/include/ast_util.h
+++ b/ODIN_II/SRC/include/ast_util.h
@@ -22,7 +22,7 @@
ast_node_t *free_single_node(ast_node_t *node);
void free_assignement_of_node_keep_tree(ast_node_t *node);
-char *make_module_param_name(STRING_CACHE *defines_for_module_sc, ast_node_t *module_param_list, char *module_name);
+char *make_module_param_name(STRING_CACHE *defines_sc, ast_node_t *module_param_list, char *module_name);
void make_concat_into_list_of_strings(ast_node_t *concat_top, char *instance_name_prefix);
void change_to_number_node(ast_node_t *node, long number);
@@ -35,7 +35,7 @@
ast_node_t *resolve_ast_node(STRING_CACHE *local_param_table_sc, short initial, char *module_name, ast_node_t *node);
ast_node_t *node_is_constant(ast_node_t *node);
ast_node_t *node_is_ast_constant(ast_node_t *node);
-ast_node_t *node_is_ast_constant(ast_node_t *node, STRING_CACHE *defines_for_module_sc);
+ast_node_t *node_is_ast_constant(ast_node_t *node, STRING_CACHE *defines_sc);
ast_node_t * fold_binary(ast_node_t *node);
ast_node_t *fold_unary(ast_node_t *node);
diff --git a/ODIN_II/SRC/include/node_creation_library.h b/ODIN_II/SRC/include/node_creation_library.h
index 1c0faad..a9adbe1 100644
--- a/ODIN_II/SRC/include/node_creation_library.h
+++ b/ODIN_II/SRC/include/node_creation_library.h
@@ -19,6 +19,3 @@
char *node_name(nnode_t *node, char *instance_prefix_name);
char *hard_node_name(nnode_t *node, char *instance_name_prefix, char *hb_name, char *hb_inst);
nnode_t *make_mult_block(nnode_t *node, short mark);
-
-edge_type_e edge_type_blif_enum(std::string edge_kind_str);
-const char *edge_type_blif_str(nnode_t *node);
diff --git a/ODIN_II/SRC/include/odin_types.h b/ODIN_II/SRC/include/odin_types.h
index fc44b79..4dec063 100644
--- a/ODIN_II/SRC/include/odin_types.h
+++ b/ODIN_II/SRC/include/odin_types.h
@@ -169,8 +169,6 @@
/**
* defined in enum_str.cpp
*/
-extern const char *file_extension_supported_STR[];
-
extern const char *ZERO_GND_ZERO;
extern const char *ONE_VCC_CNS;
extern const char *ZERO_PAD_ZERO;
@@ -178,6 +176,7 @@
extern const char *SINGLE_PORT_RAM_string;
extern const char *DUAL_PORT_RAM_string;
+extern const char *file_extension_supported_STR[];
extern const char *signedness_STR[];
extern const char *edge_type_e_STR[];
extern const char *operation_list_STR[][2];
@@ -556,8 +555,6 @@
bool delay_cycle;
unsigned long coverage;
- bool is_default; // The pin is feeding a mux from logic representing an else or default.
- bool is_implied; // This signal is implied.
////////////////////
diff --git a/ODIN_II/SRC/include/odin_util.h b/ODIN_II/SRC/include/odin_util.h
index 9b55dcc..6031064 100644
--- a/ODIN_II/SRC/include/odin_util.h
+++ b/ODIN_II/SRC/include/odin_util.h
@@ -53,6 +53,11 @@
const char *node_name_based_on_op(nnode_t *node);
const char *name_based_on_op(operation_list op);
+operation_list op_based_on_name(const char *input);
+
+const char *name_based_on_edge(edge_type_e sensitivity_kind);
+const char *node_name_based_on_edge(nnode_t *node);
+edge_type_e edge_based_on_name(const char *input);
char *make_signal_name(char *signal_name, int bit);
char *make_full_ref_name(const char *previous, const char *module_name, const char *module_instance_name, const char *signal_name, long bit);
@@ -105,6 +110,7 @@
void trim_string(char* string, const char *chars);
bool only_one_is_true(std::vector<bool> tested);
int odin_sprintf (char *s, const char *format, ...);
+char *odin_strgen(const char *format, ...);
void passed_verify_i_o_availabilty(struct nnode_t_t *node, int expected_input_size, int expected_output_size, const char *current_src, int line_src);
diff --git a/ODIN_II/SRC/include/parse_making_ast.h b/ODIN_II/SRC/include/parse_making_ast.h
index c82e4db..98afd28 100644
--- a/ODIN_II/SRC/include/parse_making_ast.h
+++ b/ODIN_II/SRC/include/parse_making_ast.h
@@ -4,6 +4,7 @@
/* INITIALISATIONS */
void init_parser();
+void cleanup_parser();
void cleanup_hard_blocks();
diff --git a/ODIN_II/SRC/netlist_create_from_ast.cpp b/ODIN_II/SRC/netlist_create_from_ast.cpp
index 732785e..af827d8 100644
--- a/ODIN_II/SRC/netlist_create_from_ast.cpp
+++ b/ODIN_II/SRC/netlist_create_from_ast.cpp
@@ -70,9 +70,6 @@
ast_node_t** function_local_symbol_table = NULL;
int function_num_local_symbol_table = 0;
-signal_list_t *local_clock_list = NULL;
-int local_clock_idx = -1;
-
/* CONSTANT NET ELEMENTS */
char *one_string = NULL;
char *zero_string = NULL;
@@ -427,22 +424,6 @@
local_symbol_table_sc = sc_new_string_cache();
}
-void cleanup_local_clock_list()
-{
- if(local_clock_list)
- {
- free_signal_list(local_clock_list);
- local_clock_list = NULL;
- }
-
- local_clock_idx = -1;
-}
-
-void init_local_clock_list()
-{
- cleanup_local_clock_list();
-}
-
/*---------------------------------------------------------------------------------------------
* (function: create_netlist)
*--------------------------------------------------------------------------*/
@@ -790,6 +771,7 @@
short skip_children = FALSE; // skips the DFS completely if TRUE
signal_list_t *return_sig_list = NULL;
signal_list_t **children_signal_list = NULL;
+ signal_list_t *local_clock_list = NULL;
if (node == NULL)
{
@@ -969,9 +951,6 @@
}
/* ---------------------- */
case ASSIGN:
- /* combinational path */
- type_of_circuit = COMBINATIONAL;
- circuit_edge = UNDEFINED_SENSITIVITY;
break;
case BLOCKING_STATEMENT:
case NON_BLOCKING_STATEMENT:
@@ -984,6 +963,7 @@
case ALWAYS:
/* evaluate if this is a sensitivity list with posedges/negedges (=SEQUENTIAL) or none (=COMBINATIONAL) */
local_clock_list = evaluate_sensitivity_list(node->children[0], instance_name_prefix);
+ type_of_circuit = SEQUENTIAL;
child_skip_list[0] = TRUE;
break;
case CASE:
@@ -1102,10 +1082,11 @@
}
}
-
- cleanup_local_clock_list();
-
+ free_signal_list(local_clock_list);
+ type_of_circuit = COMBINATIONAL;
+ circuit_edge = UNDEFINED_SENSITIVITY;
break;
+
case BINARY_OPERATION:
oassert(node->num_children == 2);
return_sig_list = create_operation_node(node, children_signal_list, node->num_children, instance_name_prefix);
@@ -3746,74 +3727,67 @@
void terminate_registered_assignment(ast_node_t *always_node, signal_list_t* assignment, signal_list_t *potential_clocks, char * /*instance_name_prefix*/)
{
oassert(potential_clocks != NULL);
-
+
+ npin_t *local_clock_pin = NULL;
npin_t **list_dependence_pin = (npin_t **)vtr::calloc(assignment->count,sizeof(npin_t *));
ids *list_dependence_type = (ids *)vtr::calloc(assignment->count,sizeof(ids));
/* figure out which one is the clock */
- if (local_clock_idx < 0)
+
+ if(potential_clocks->count == 0)
{
- if(potential_clocks->count == 1)
- {
- /* If this element is the only item in the sensitivity list then its the clock */
- local_clock_idx = 0;
- }
- else
- {
- int i;
- for (i = 0; i < potential_clocks->count; i++)
- {
- nnet_t *temp_net;
- /* searching for the clock with no net */
- long sc_spot = sc_lookup_string(output_nets_sc, potential_clocks->pins[i]->name);
- if (sc_spot == -1)
- {
- sc_spot = sc_lookup_string(input_nets_sc, potential_clocks->pins[i]->name);
- if (sc_spot == -1)
- {
- error_message(NETLIST_ERROR, always_node->line_number, always_node->file_number,
- "Sensitivity list element (%s) is not a driver or net ... must be\n", potential_clocks->pins[i]->name);
- }
- temp_net = (nnet_t*)input_nets_sc->data[sc_spot];
- }
- else
- {
- temp_net = (nnet_t*)output_nets_sc->data[sc_spot];
- }
-
-
- if (
- (((temp_net->num_fanout_pins == 1) && (temp_net->fanout_pins[0]->node == NULL))
- || (temp_net->num_fanout_pins == 0))
- && (local_clock_idx >= 0))
- {
- error_message(NETLIST_ERROR, always_node->line_number, always_node->file_number,
- "Suspected second clock (%s). In a sequential sensitivity list, Odin expects the "
- "clock not to drive anything and any other signals in this list to drive stuff. "
- "For example, a reset in the sensitivy list has to be hooked up to something in the always block.\n",
- potential_clocks->pins[i]->name);
- }
- else if (temp_net->num_fanout_pins == 0)
- {
- /* If this element is in the sensitivity list and doesn't drive anything it's the clock */
- local_clock_idx = i;
- }
- else if ((temp_net->num_fanout_pins == 1) && (temp_net->fanout_pins[0]->node == NULL))
- {
- /* If this element is in the sensitivity list and doesn't drive anything it's the clock */
- local_clock_idx = i;
- }
- }
- }
+ error_message(NETLIST_ERROR, always_node->line_number, always_node->file_number,
+ "%s","Sensitivity list is empty, cannot find a driver for this always block\n");
}
-
- npin_t *local_clock_pin = NULL;
-
- if(local_clock_idx >= 0)
+ else if(potential_clocks->count == 1)
{
- local_clock_pin = potential_clocks->pins[local_clock_idx];
+ /* If this element is the only item in the sensitivity list then its the clock */
+ local_clock_pin = potential_clocks->pins[0];
}
else
{
+ /**
+ * multiple driver found for this block,
+ * we drive individual latch from each input and xor them together
+ * this will be the driver for an asynchronous latch.
+ * since we cannot synthesize propagation delay, the latch must be asynchronous
+ * as only with delay can we switch both edges into posedge triggers.
+ *
+ * Sadly this means that we cannot use implicit ram for these types of circuit
+ * If the user wants to make an implicit ram,
+ * it must be built using a single driver for the always block
+ * i.e. always @(posedge clk)
+ *
+ * always @(negedge rst, posedge clk)
+ * will always have to build circuitry and be evaluated using an async latch
+ */
+ int i;
+ for (i = 0; i < potential_clocks->count; i++)
+ {
+ // deal with all potential_clocks->pins[i]
+
+ /**
+ * Combining edges to build multi edge support
+ * Although latched circuits are bad, we need to support them
+ * as they synthesizable
+ *
+ * .--o<|---.
+ * | ____ |
+ * '--| |--'--.
+ * trigger ---|> | | (xor)
+ * ```` '``\\'',___ combined clock to async latch
+ * .--//,,'
+ * .--o<|---. |
+ * | ____ | |
+ * '--| |--'--'
+ * trigger ---|> |
+ * ````
+ */
+ }
+ }
+
+
+ if(local_clock_pin == NULL)
+ {
error_message(NETLIST_ERROR, always_node->line_number, always_node->file_number,
"%s\n", "No clock found"
);
@@ -3825,7 +3799,15 @@
for (i = 0; i < assignment->count; i++)
{
npin_t *pin = assignment->pins[i];
- implicit_memory *memory = lookup_implicit_memory_input(pin->name);
+ implicit_memory *memory = NULL;
+
+ /* implicit memories only when it is a rising edge and we only have one driver */
+ if( potential_clocks->count == 1
+ && local_clock_pin->sensitivity == RISING_EDGE_SENSITIVITY)
+ {
+ memory = lookup_implicit_memory_input(pin->name);
+ }
+
if (memory)
{
add_pin_to_signal_list(memory_inputs, pin);
@@ -3941,6 +3923,7 @@
}
}
}
+
vtr::free(list_dependence_pin);
vtr::free(list_dependence_type);
for (i = 0; i < memory_inputs->count; i++)
@@ -3971,6 +3954,7 @@
memory->clock_added = TRUE;
}
}
+
free_signal_list(memory_inputs);
free_signal_list(assignment);
@@ -4525,8 +4509,6 @@
return_sig_list = NULL;
}
- type_of_circuit = SEQUENTIAL;
-
return return_sig_list;
}
@@ -4662,10 +4644,6 @@
out_pin_list = make_output_pins_for_existing_node(not_node, 1);
oassert(out_pin_list->count == 1);
-
- // Mark the else condition for the simulator.
- out_pin_list->pins[0]->is_default = TRUE;
-
/* copy that output pin to be put into the default */
add_input_pin_to_node(if_node, out_pin_list->pins[0], 1);
@@ -4803,9 +4781,6 @@
default_node = make_1port_logic_gate_with_inputs(LOGICAL_NOR, case_list_of_items->num_children-1, other_expressions_pin_list, case_node, -1);
default_expression = make_output_pins_for_existing_node(default_node, 1);
- // Mark the "default" case for simulation.
- default_expression->pins[0]->is_default = TRUE;
-
/* copy that output pin to be put into the default */
add_input_pin_to_node(case_node, default_expression->pins[0], i);
@@ -4941,17 +4916,24 @@
}
else
{
+ /**
+ * TODO: This seems wrong, implie zero for implicit memories ?
+ * * also checking edges here makes little sense if we combined the top clocks
+ *
+ */
/* Don't match, so this signal is an IMPLIED SIGNAL !!! */
npin_t *pin = combined_lists->pins[i];
switch(circuit_edge)
{
- case RISING_EDGE_SENSITIVITY: //fallthrough
- case FALLING_EDGE_SENSITIVITY:
+ case RISING_EDGE_SENSITIVITY:
{
/* implied signal for mux */
if (lookup_implicit_memory_input(pin->name))
{
+ /**
+ * TODO: why ??
+ */
// If the mux feeds an implicit memory, imply zero.
add_input_pin_to_node(mux_node, get_zero_pin(verilog_netlist), pin_index);
}
@@ -4967,12 +4949,24 @@
}
break;
}
+ case FALLING_EDGE_SENSITIVITY:
+ {
+ /* lookup this driver name */
+ signal_list_t *this_pin_list = create_pins(NULL, pin->name, instance_name_prefix);
+ oassert(this_pin_list->count == 1);
+ //add_a_input_pin_to_node_spot_idx(mux_node, get_zero_pin(verilog_netlist), pin_index);
+ add_input_pin_to_node(mux_node, this_pin_list->pins[0], pin_index);
+ /* clean up */
+ free_signal_list(this_pin_list);
+ break;
+ }
case ASYNCHRONOUS_SENSITIVITY:
{
- /* DON'T CARE - so hookup zero */
+ /**
+ * DON'T CARE - - so hookup zero
+ * TODO: should'nt we ?
+ */
add_input_pin_to_node(mux_node, get_zero_pin(verilog_netlist), pin_index);
- // Allows the simulator to be aware of the implied nature of this signal.
- mux_node->input_pins[pin_index]->is_implied = TRUE;
break;
}
default:
diff --git a/ODIN_II/SRC/netlist_utils.cpp b/ODIN_II/SRC/netlist_utils.cpp
index 8919d8c..adc736b 100644
--- a/ODIN_II/SRC/netlist_utils.cpp
+++ b/ODIN_II/SRC/netlist_utils.cpp
@@ -218,9 +218,6 @@
new_pin->coverage = 0;
- new_pin->is_default = FALSE;
- new_pin->is_implied = FALSE;
-
new_pin->ace_info = NULL;
return new_pin;
@@ -254,7 +251,6 @@
new_pin->type = copy_pin->type;
new_pin->net = copy_pin->net;
new_pin->mapping = copy_pin->mapping;
- new_pin->is_default = copy_pin->is_default;
return new_pin;
}
@@ -270,7 +266,6 @@
new_pin->name = copy_pin->name?vtr::strdup(copy_pin->name):0;
new_pin->type = copy_pin->type;
new_pin->mapping = copy_pin->mapping?vtr::strdup(copy_pin->mapping):0;
- new_pin->is_default = copy_pin->is_default;
if (copy_pin->net != NULL)
{
add_fanout_pin_to_net(copy_pin->net, new_pin);
diff --git a/ODIN_II/SRC/node_creation_library.cpp b/ODIN_II/SRC/node_creation_library.cpp
index bcb3cf7..cdb4307 100644
--- a/ODIN_II/SRC/node_creation_library.cpp
+++ b/ODIN_II/SRC/node_creation_library.cpp
@@ -69,6 +69,31 @@
return one_fanout_pin;
}
+/*---------------------------------------------------------------------------------------------
+ * (function: make_nport_logic_gates)
+ * Make a n port gate with variable sizes. The first port will be input_pins index 0..width_port1.
+ *-------------------------------------------------------------------------------------------*/
+static nnode_t *generic_make_nport_gate(operation_list type, std::vector<int> widths, int width_output, nnode_t *node, short mark)
+{
+ int i;
+ nnode_t *logic_node = allocate_nnode();
+ logic_node->traverse_visited = mark;
+ logic_node->type = type;
+ logic_node->name = node_name(logic_node, node->name);
+ logic_node->related_ast_node = node->related_ast_node;
+
+ /* add the input ports as needed */
+ for(i = 0; i < widths.size(); i++) {
+ allocate_more_input_pins(logic_node, widths[i]);
+ add_input_port_information(logic_node, widths[i]);
+ }
+
+ /* add output */
+ allocate_more_output_pins(logic_node, width_output);
+ add_output_port_information(logic_node, width_output);
+
+ return logic_node;
+}
/*---------------------------------------------------------------------------------------------
* (function: make_not_gate_with_input)
@@ -76,9 +101,7 @@
*-------------------------------------------------------------------------------------------*/
nnode_t *make_not_gate_with_input(npin_t *input_pin, nnode_t *node, short mark)
{
- nnode_t *logic_node;
-
- logic_node = make_not_gate(node, mark);
+ nnode_t *logic_node = make_not_gate(node, mark);
/* add the input ports as needed */
add_input_pin_to_node(logic_node, input_pin, 0);
@@ -93,19 +116,7 @@
*-----------------------------------------------------------------------*/
nnode_t *make_not_gate(nnode_t *node, short mark)
{
- nnode_t *logic_node;
-
- logic_node = allocate_nnode();
- logic_node->traverse_visited = mark;
- logic_node->type = LOGICAL_NOT;
- logic_node->name = node_name(logic_node, node->name);
- logic_node->related_ast_node = node->related_ast_node;
-
- allocate_more_input_pins(logic_node, 1);
- allocate_more_output_pins(logic_node, 1);
-
- return logic_node;
-
+ return generic_make_nport_gate(LOGICAL_NOT, {1}, 1, node, mark);
}
/*---------------------------------------------------------------------------------------------
@@ -114,22 +125,7 @@
*-------------------------------------------------------------------------------------------*/
nnode_t *make_1port_gate(operation_list type, int width_input, int width_output, nnode_t *node, short mark)
{
- nnode_t *logic_node;
-
- logic_node = allocate_nnode();
- logic_node->traverse_visited = mark;
- logic_node->type = type;
- logic_node->name = node_name(logic_node, node->name);
- logic_node->related_ast_node = node->related_ast_node;
-
- /* add the input ports as needed */
- allocate_more_input_pins(logic_node, width_input);
- add_input_port_information(logic_node, width_input);
- /* add output */
- allocate_more_output_pins(logic_node, width_output);
- add_output_port_information(logic_node, width_output);
-
- return logic_node;
+ return generic_make_nport_gate(type, {width_input}, width_output, node, mark);
}
/*---------------------------------------------------------------------------------------------
* (function: make_1port_logic_gate)
@@ -137,9 +133,7 @@
*-------------------------------------------------------------------------------------------*/
nnode_t *make_1port_logic_gate(operation_list type, int width, nnode_t *node, short mark)
{
- nnode_t *logic_node = make_1port_gate(type, width, 1, node, mark);
-
- return logic_node;
+ return generic_make_nport_gate(type, {width}, 1, node, mark);
}
/*---------------------------------------------------------------------------------------------
@@ -148,13 +142,10 @@
*-------------------------------------------------------------------------------------------*/
nnode_t *make_1port_logic_gate_with_inputs(operation_list type, int width, signal_list_t *pin_list, nnode_t *node, short mark)
{
- nnode_t *logic_node;
- int i;
-
- logic_node = make_1port_gate(type, width, 1, node, mark);
+ nnode_t *logic_node = generic_make_nport_gate(type, {width}, 1, node, mark);
/* hookup all the pins */
- for (i = 0; i < width; i++)
+ for ( int i = 0; i < width; i++)
{
add_input_pin_to_node(logic_node, pin_list->pins[i], i);
}
@@ -163,54 +154,21 @@
}
/*---------------------------------------------------------------------------------------------
- * (function: make_3port_logic_gates)
- * Make a 3 port gate all variable port widths.
- *-------------------------------------------------------------------------------------------*/
-nnode_t *make_3port_gate(operation_list type, int width_port1, int width_port2, int width_port3, int width_output, nnode_t *node, short mark)
-{
- nnode_t *logic_node = allocate_nnode();
- logic_node->traverse_visited = mark;
- logic_node->type = type;
- logic_node->name = node_name(logic_node, node->name);
- logic_node->related_ast_node = node->related_ast_node;
-
- /* add the input ports as needed */
- allocate_more_input_pins(logic_node, width_port1);
- add_input_port_information(logic_node, width_port1);
- allocate_more_input_pins(logic_node, width_port2);
- add_input_port_information(logic_node, width_port2);
- allocate_more_input_pins(logic_node, width_port3);
- add_input_port_information(logic_node, width_port3);
- /* add output */
- allocate_more_output_pins(logic_node, width_output);
- add_output_port_information(logic_node, width_output);
-
- return logic_node;
-}
-
-
-/*---------------------------------------------------------------------------------------------
* (function: make_2port_logic_gates)
* Make a 2 port gate with variable sizes. The first port will be input_pins index 0..width_port1.
*-------------------------------------------------------------------------------------------*/
nnode_t *make_2port_gate(operation_list type, int width_port1, int width_port2, int width_output, nnode_t *node, short mark)
{
- nnode_t *logic_node = allocate_nnode();
- logic_node->traverse_visited = mark;
- logic_node->type = type;
- logic_node->name = node_name(logic_node, node->name);
- logic_node->related_ast_node = node->related_ast_node;
+ return generic_make_nport_gate(type, {width_port1, width_port2}, width_output, node, mark);
+}
- /* add the input ports as needed */
- allocate_more_input_pins(logic_node, width_port1);
- add_input_port_information(logic_node, width_port1);
- allocate_more_input_pins(logic_node, width_port2);
- add_input_port_information(logic_node, width_port2);
- /* add output */
- allocate_more_output_pins(logic_node, width_output);
- add_output_port_information(logic_node, width_output);
-
- return logic_node;
+/*---------------------------------------------------------------------------------------------
+ * (function: make_3port_logic_gates)
+ * Make a 3 port gate all variable port widths.
+ *-------------------------------------------------------------------------------------------*/
+nnode_t *make_3port_gate(operation_list type, int width_port1, int width_port2, int width_port3, int width_output, nnode_t *node, short mark)
+{
+ return generic_make_nport_gate(type, {width_port1, width_port2, width_port3}, width_output, node, mark);
}
/*---------------------------------------------------------------------------------------------
@@ -219,63 +177,7 @@
*-------------------------------------------------------------------------------------------*/
nnode_t *make_nport_gate(operation_list type, int port_sizes, int width, int width_output, nnode_t *node, short mark)
{
- int i;
- nnode_t *logic_node = allocate_nnode();
- logic_node->traverse_visited = mark;
- logic_node->type = type;
- logic_node->name = node_name(logic_node, node->name);
- logic_node->related_ast_node = node->related_ast_node;
-
- /* add the input ports as needed */
- for(i = 0; i < port_sizes; i++) {
- allocate_more_input_pins(logic_node, width);
- add_input_port_information(logic_node, width);
- }
- //allocate_more_input_pins(logic_node, width_port2);
- //add_input_port_information(logic_node, width_port2);
- /* add output */
- allocate_more_output_pins(logic_node, width_output);
- add_output_port_information(logic_node, width_output);
-
- return logic_node;
-}
-
-const char *edge_type_blif_str(nnode_t *node)
-{
-
- if(node->type != FF_NODE)
- return NULL;
-
- switch(node->edge_type)
- {
- case FALLING_EDGE_SENSITIVITY: return "fe";
- case RISING_EDGE_SENSITIVITY: return "re";
- case ACTIVE_HIGH_SENSITIVITY: return "ah";
- case ACTIVE_LOW_SENSITIVITY: return "al";
- case ASYNCHRONOUS_SENSITIVITY: return "as";
- default:
- error_message(NETLIST_ERROR, node->line_number, node->file_number,
- "undefined sensitivity kind for flip flop %s", edge_type_e_STR[node->edge_type]);
-
- return NULL;
- }
-}
-
-edge_type_e edge_type_blif_enum(std::string edge_kind_str)
-{
-
- if (edge_kind_str == "fe") return FALLING_EDGE_SENSITIVITY;
- else if (edge_kind_str == "re") return RISING_EDGE_SENSITIVITY;
- else if (edge_kind_str == "ah") return ACTIVE_HIGH_SENSITIVITY;
- else if (edge_kind_str == "al") return ACTIVE_LOW_SENSITIVITY;
- else if (edge_kind_str == "as") return ASYNCHRONOUS_SENSITIVITY;
- else
- {
- error_message(NETLIST_ERROR, -1, -1,
- "undefined sensitivity kind for flip flop %s", edge_kind_str.c_str());
-
- return UNDEFINED_SENSITIVITY;
- }
+ return generic_make_nport_gate(type, std::vector<int>(port_sizes, width), width_output, node, mark);;
}
/*----------------------------------------------------------------------------
@@ -287,6 +189,7 @@
char *return_node_name;
/* create the unique name for this node */
+ /* TODO: shouldn't we use the unique node name id? */
return_node_name = make_full_ref_name(instance_name_prefix, hb_name, hb_inst, NULL, -1);
unique_node_name_id ++;
diff --git a/ODIN_II/SRC/odin_util.cpp b/ODIN_II/SRC/odin_util.cpp
index 8ece26f..9f1f538 100644
--- a/ODIN_II/SRC/odin_util.cpp
+++ b/ODIN_II/SRC/odin_util.cpp
@@ -72,7 +72,17 @@
*-------------------------------------------------------------------------------------------*/
const char *name_based_on_op(operation_list op)
{
- return operation_list_STR[op][ODIN_STRING_TYPE];
+ if(op < operation_list_END)
+ {
+ return operation_list_STR[op][ODIN_STRING_TYPE];
+ }
+ else
+ {
+ error_message(PARSE_ERROR, -1, -1,
+ "%s", "Invalid operation type defined, unable to continue");
+
+ return NULL;
+ }
}
/*---------------------------------------------------------------------------------------------
@@ -84,6 +94,74 @@
return name_based_on_op(node->type);
}
+operation_list op_based_on_name(const char *input)
+{
+ operation_list my_op = NO_OP;
+ while( my_op < operation_list_END )
+ {
+ // we have to compare short form and long form
+ if( (0 == strcmp(operation_list_STR[my_op][0], input))
+ || (0 == strcmp(operation_list_STR[my_op][1], input)))
+ {
+ break;
+ }
+ else
+ {
+ my_op = (operation_list)(((int)my_op) + 1);
+ }
+
+ }
+ return my_op;
+}
+
+/*---------------------------------------------------------------------------------------------
+ * (function: node_name_based_on_op)
+ * Get the string version of a node
+ *-------------------------------------------------------------------------------------------*/
+const char *name_based_on_edge(edge_type_e sensitivity_kind)
+{
+ if(sensitivity_kind < edge_type_e_END)
+ {
+ return edge_type_e_STR[sensitivity_kind];
+ }
+ else
+ {
+ error_message(PARSE_ERROR, -1, -1,
+ "%s", "Invalid edge kind type defined, unable to continue");
+
+ return NULL;
+
+ }
+}
+
+/*---------------------------------------------------------------------------------------------
+ * (function: node_name_based_on_op)
+ * Get the string version of a node
+ *-------------------------------------------------------------------------------------------*/
+const char *node_name_based_on_edge(nnode_t *node)
+{
+ return name_based_on_edge(node->edge_type);
+}
+
+edge_type_e edge_based_on_name(const char *input)
+{
+ edge_type_e my_edge = UNDEFINED_SENSITIVITY;
+ while( my_edge < edge_type_e_END )
+ {
+ // we have to compare short form and long form
+ if(0 == strcmp(edge_type_e_STR[my_edge], input))
+ {
+ break;
+ }
+ else
+ {
+ my_edge = (edge_type_e)(((int)my_edge) + 1);
+ }
+ }
+ return my_edge;
+}
+
+
/*--------------------------------------------------------------------------
* (function: make_signal_name)
// return signal_name-bit
@@ -960,30 +1038,64 @@
*/
int odin_sprintf (char *s, const char *format, ...)
{
- va_list args, args_copy ;
- va_start( args, format ) ;
- va_copy( args_copy, args ) ;
+ if(s && format)
+ {
+ va_list args, args_copy ;
+ va_start( args, format ) ;
+ va_copy( args_copy, args ) ;
- const auto sz = std::vsnprintf( nullptr, 0, format, args ) + 1 ;
+ const auto sz = std::vsnprintf( nullptr, 0, format, args ) + 1 ;
- try
- {
- std::string temp( sz, ' ' ) ;
- std::vsnprintf( &temp.front(), sz, format, args_copy ) ;
- va_end(args_copy) ;
- va_end(args) ;
+ try
+ {
+ std::string temp( sz, ' ' ) ;
+ std::vsnprintf( &temp.front(), sz, format, args_copy ) ;
+ va_end(args_copy) ;
+ va_end(args) ;
- s = strncpy(s, temp.c_str(),temp.length());
+ s = strncpy(s, temp.c_str(),temp.length()+1);
- return temp.length();
+ return temp.length();
- }
- catch( const std::bad_alloc& )
- {
- va_end(args_copy) ;
- va_end(args) ;
- return -BUFFER_MAX_SIZE;
- }
+ }
+ catch( const std::bad_alloc& )
+ {
+ va_end(args_copy) ;
+ va_end(args) ;
+ }
+ }
+ return -BUFFER_MAX_SIZE;
}
+
+char *odin_strgen(const char *format, ...)
+{
+ if(format)
+ {
+ va_list args, args_copy ;
+ va_start( args, format ) ;
+ va_copy( args_copy, args ) ;
+
+ const auto sz = std::vsnprintf( nullptr, 0, format, args ) + 1 ;
+
+ try
+ {
+ std::string temp( sz, ' ' ) ;
+ std::vsnprintf( &temp.front(), sz, format, args_copy ) ;
+ va_end(args_copy) ;
+ va_end(args) ;
+
+ return strdup(temp.c_str());
+ }
+ catch( const std::bad_alloc& )
+ {
+ va_end(args_copy) ;
+ va_end(args) ;
+ }
+ }
+
+ return NULL;
+
+}
+
diff --git a/ODIN_II/SRC/output_blif.cpp b/ODIN_II/SRC/output_blif.cpp
index 179fcd6..738fb62 100644
--- a/ODIN_II/SRC/output_blif.cpp
+++ b/ODIN_II/SRC/output_blif.cpp
@@ -682,9 +682,6 @@
if(initial_value == -1)
initial_value = 3;
- // grab the edge sensitivity of the flip flop
- const char *edge_type_str = edge_type_blif_str(node);
-
std::string input;
std::string output;
std::string clock_driver;
@@ -718,7 +715,7 @@
/* clock */
- fprintf(out, "%s ", edge_type_str);
+ fprintf(out, "%s ", node_name_based_on_edge(node));
if(global_args.high_level_block != NULL)
{
fprintf(out, "%s^^%i-%i ",
diff --git a/ODIN_II/SRC/parse_making_ast.cpp b/ODIN_II/SRC/parse_making_ast.cpp
index 9f37b74..ab7e2c1 100644
--- a/ODIN_II/SRC/parse_making_ast.cpp
+++ b/ODIN_II/SRC/parse_making_ast.cpp
@@ -41,36 +41,40 @@
extern int yylineno;
//for module
-STRING_CACHE **defines_for_module_sc;
-STRING_CACHE *modules_inputs_sc;
-STRING_CACHE *modules_outputs_sc;
+STRING_CACHE **defines_for_module_sc = NULL;
+STRING_CACHE *modules_inputs_sc = NULL;
+STRING_CACHE *modules_outputs_sc = NULL;
//for function
-STRING_CACHE **defines_for_function_sc;
-STRING_CACHE *functions_inputs_sc;
-STRING_CACHE *functions_outputs_sc;
+STRING_CACHE **defines_for_function_sc = NULL;
+STRING_CACHE *functions_inputs_sc = NULL;
+STRING_CACHE *functions_outputs_sc = NULL;
-STRING_CACHE *module_names_to_idx;
+STRING_CACHE *module_names_to_idx = NULL;
-ast_node_t **block_instantiations_instance;
-int size_block_instantiations;
+ast_node_t **block_instantiations_instance = NULL;
+int size_block_instantiations = 0;
-ast_node_t **module_instantiations_instance;
-int size_module_instantiations;
-ast_node_t **module_variables_not_defined;
-int size_module_variables_not_defined;
-ast_node_t **function_instantiations_instance;
-int size_function_instantiations;
-ast_node_t **function_instantiations_instance_by_module;
-int size_function_instantiations_by_module;
+ast_node_t **module_instantiations_instance = NULL;
+int size_module_instantiations = 0;
-long num_modules;
-long num_instances;
-ast_node_t **ast_modules;
+ast_node_t **module_variables_not_defined = NULL;
+int size_module_variables_not_defined = 0;
-int num_functions;
-ast_node_t **ast_functions;
-ast_node_t **all_file_items_list;
-int size_all_file_items_list;
+ast_node_t **function_instantiations_instance = NULL;
+int size_function_instantiations = 0;
+
+ast_node_t **function_instantiations_instance_by_module = NULL;
+int size_function_instantiations_by_module = 0;
+
+ast_node_t **ast_modules = NULL;
+long num_modules = 0;
+long num_instances = 0;
+
+ast_node_t **ast_functions = NULL;
+int num_functions = 0;
+
+ast_node_t **all_file_items_list = NULL;
+int size_all_file_items_list = 0;
short to_view_parse;
@@ -174,12 +178,14 @@
/* parse next file */
yyparse();
+ cleanup_parser_for_file();
fclose(yyin);
current_parse_file++;
}
/* clean up all the structures in the parser */
cleanup_veri_preproc();
+ cleanup_parser();
/* for error messages - this is in case we use any of the parser functions after parsing (i.e. create_case_control_signals()) */
current_parse_file = -1;
@@ -261,9 +267,9 @@
long i;
/* frees all the defines for module string caches (used for parameters) */
- if (num_modules > 0)
+ if (num_modules >= 0)
{
- for (i = 0; i < num_modules; i++)
+ for (i = 0; i <= num_modules; i++)
{
sc_free_string_cache(defines_for_module_sc[i]);
}
@@ -294,10 +300,10 @@
void cleanup_parser_for_file()
{
/* create string caches to hookup PORTS with INPUT and OUTPUTs. This is made per module and will be cleaned and remade at next_module */
- modules_inputs_sc = sc_free_string_cache(modules_inputs_sc);
- modules_outputs_sc = sc_free_string_cache(modules_outputs_sc);
- functions_inputs_sc = sc_free_string_cache(functions_inputs_sc);
- functions_outputs_sc = sc_free_string_cache(functions_outputs_sc);
+ if(modules_inputs_sc) modules_inputs_sc = sc_free_string_cache(modules_inputs_sc);
+ if(modules_outputs_sc) modules_outputs_sc = sc_free_string_cache(modules_outputs_sc);
+ if(functions_inputs_sc) functions_inputs_sc = sc_free_string_cache(functions_inputs_sc);
+ if(functions_outputs_sc) functions_outputs_sc = sc_free_string_cache(functions_outputs_sc);
}
/*---------------------------------------------------------------------------------------------
diff --git a/ODIN_II/SRC/read_blif.cpp b/ODIN_II/SRC/read_blif.cpp
index b84c243..c2c4b93 100644
--- a/ODIN_II/SRC/read_blif.cpp
+++ b/ODIN_II/SRC/read_blif.cpp
@@ -339,7 +339,7 @@
nnode_t *new_node = allocate_nnode();
new_node->related_ast_node = NULL;
new_node->type = FF_NODE;
- new_node->edge_type = edge_type_blif_enum(names[2]);
+ new_node->edge_type = edge_based_on_name(names[2]);
/* Read in the initial value of the latch.
Possible values from a blif file are:
diff --git a/ODIN_II/SRC/simulate_blif.cpp b/ODIN_II/SRC/simulate_blif.cpp
index 29d2375..8a6c6f0 100644
--- a/ODIN_II/SRC/simulate_blif.cpp
+++ b/ODIN_II/SRC/simulate_blif.cpp
@@ -2534,13 +2534,6 @@
unknown = TRUE;
else if (value == 1 && select == -1) // Take the first selection only.
select = i;
-
- /*
- * If the pin comes from an "else" condition or a case "default" condition,
- * we favour it in the case where there are unknowns.
- */
- if (ast_node && pin->is_default && (ast_node->type == IF || ast_node->type == CASE))
- default_select = i;
}
// If there are unknowns and there is a default clause, select it.
@@ -2574,11 +2567,7 @@
npin_t *pin = node->input_pins[select + node->input_port_sizes[0]];
signed char value = get_pin_value(pin,cycle);
- // Drive implied drivers to unknown value.
- /*if (pin->is_implied && ast_node && (ast_node->type == CASE))
- update_pin_value(output_pin, -1, cycle);
- else*/
- update_pin_value(output_pin, value, cycle);
+ update_pin_value(output_pin, value, cycle);
}
}
diff --git a/ODIN_II/regression_test/benchmark/arch/both_ram.v b/ODIN_II/regression_test/benchmark/arch/both_ram.v
index 64f88f3..abdc9f1 100644
--- a/ODIN_II/regression_test/benchmark/arch/both_ram.v
+++ b/ODIN_II/regression_test/benchmark/arch/both_ram.v
@@ -17,10 +17,6 @@
dpram2_out2
);
-wafq
-
-;;;
-
// SIGNAL DECLARATIONS
input clock;