/*
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
#include "simulate_blif.h"

/*
 * Performs simulation. 
 */ 
void simulate_netlist(netlist_t *netlist)
{
	printf("Beginning simulation.\n"); fflush(stdout);

	// Create and verify the lines.
	lines_t *input_lines = create_lines(netlist, INPUT);
	if (!verify_lines(input_lines))
		error_message(SIMULATION_ERROR, 0, -1, "Input lines could not be assigned.");

	lines_t *output_lines = create_lines(netlist, OUTPUT);
	if (!verify_lines(output_lines))
		error_message(SIMULATION_ERROR, 0, -1, "Output lines could not be assigned.");

	// Open the output vector file.
	FILE *out = fopen(OUTPUT_VECTOR_FILE_NAME, "w");
	if (!out)
		error_message(SIMULATION_ERROR, 0, -1, "Could not open output vector file.");

	// Open the input vector file.
	FILE *in_out  = fopen( INPUT_VECTOR_FILE_NAME, "w");
	if (!in_out)
		error_message(SIMULATION_ERROR, 0, -1, "Could not open input vector file.");

	// Open the modelsim vector file.
	FILE *modelsim_out = fopen("test.do", "w");
	if (!modelsim_out)
		error_message(SIMULATION_ERROR, 0, -1, "Could not open modelsim output file.");

	FILE *in  = NULL;
	int num_vectors;
	// Passed via the -t option.
	char *input_vector_file  = global_args.sim_vector_input_file;

	// Input vectors can either come from a file or be randomly generated.
	if (input_vector_file)
	{
		in = fopen(input_vector_file, "r");
		if (!in)
			error_message(SIMULATION_ERROR, 0, -1, "Could not open vector input file: %s", input_vector_file);

		num_vectors = count_test_vectors(in);

		// Read the vector headers and check to make sure they match the lines.
		if (!verify_test_vector_headers(in, input_lines))
			error_message(SIMULATION_ERROR, 0, -1, "Invalid vector header format in %s.", input_vector_file);

		printf("Simulating %d existing vectors from \"%s\".\n", num_vectors, input_vector_file); fflush(stdout);
	}
	else
	{
		// Passed via the -g option.
		num_vectors = global_args.sim_num_test_vectors;
		printf("Simulating %d new vectors.\n", num_vectors); fflush(stdout);
	}

	// Determine which edge(s) we are outputting.
	int output_edge;
	if      (global_args.sim_output_both_edges ) output_edge = -1; // Both edges
	else if (global_args.sim_output_rising_edge) output_edge =  1; // Rising edge only
	else                                         output_edge =  0; // Falling edge only

	if (!num_vectors)
	{
		error_message(SIMULATION_ERROR, 0, -1, "No vectors to simulate.");
	}
	else
	{
		printf("\n");

		int       progress_bar_position = -1;
		const int progress_bar_length   = 50;

		double total_time      = 0; // Includes I/O
		double simulation_time = 0; // Does not include I/O

		stages *stages = 0;

		// Parse -L and -H options containing lists of pins to hold high or low during random vector generation.
		pin_names *hold_high = parse_pin_name_list(global_args.sim_hold_high);
		pin_names *hold_low  = parse_pin_name_list(global_args.sim_hold_low);
		hashtable_t *hold_high_index = index_pin_name_list(hold_high);
		hashtable_t *hold_low_index  = index_pin_name_list(hold_low);

		/*
		 * Simulation is done in "waves" of SIM_WAVE_LENGTH cycles at a time.
		 * Every second cycle gets a input new vector.
		 */
		int  num_cycles = num_vectors * 2;
		int  num_waves = ceil(num_cycles / (double)SIM_WAVE_LENGTH);
		int  wave;
		test_vector *v = 0;
		for (wave = 0; wave < num_waves; wave++)
		{
			double wave_start_time = wall_time();

			int cycle_offset = SIM_WAVE_LENGTH * wave;
			int wave_length  = (wave < (num_waves-1))?SIM_WAVE_LENGTH:(num_cycles - cycle_offset);

			// Assign vectors to lines, either by reading or generating them.
			// Every second cycle gets a new vector.
			int cycle;
			for (cycle = cycle_offset; cycle < cycle_offset + wave_length; cycle++)
			{
				if (is_even_cycle(cycle))
				{
					if (input_vector_file)
					{
						char buffer[BUFFER_MAX_SIZE];

						if (!get_next_vector(in, buffer))
							error_message(SIMULATION_ERROR, 0, -1, "Could not read next vector.");

						v = parse_test_vector(buffer);
					}
					else
					{
						v = generate_random_test_vector(input_lines, cycle, hold_high_index, hold_low_index);
					}
				}

				add_test_vector_to_lines(v, input_lines, cycle);

				if (!is_even_cycle(cycle))
					free_test_vector(v);
			}

			// Record the input vectors we are using.
			write_wave_to_file(input_lines, in_out, cycle_offset, wave_length, 1);
			// Write ModelSim script.
			write_wave_to_modelsim_file(netlist, input_lines, modelsim_out, cycle_offset, wave_length);

			double simulation_start_time = wall_time();

			// Perform simulation
			for (cycle = cycle_offset; cycle < cycle_offset + wave_length; cycle++)
			{
				//original_simulate_cycle(netlist, cycle);

				if (cycle)
				{
					simulate_cycle(cycle, stages);
				}
				else
				{
					// The first cycle produces the stages, and adds additional
					// lines as specified by the -p option.
					pin_names *p = parse_pin_name_list(global_args.sim_additional_pins);
					stages = simulate_first_cycle(netlist, cycle, p, output_lines);
					free_pin_name_list(p);
					// Make sure the output lines are still OK after adding custom lines.
					if (!verify_lines(output_lines))
						error_message(SIMULATION_ERROR, 0, -1,
								"Problem detected with the output lines after the first cycle.");
				}
			}

			simulation_time += wall_time() - simulation_start_time;

			// Write the result of this wave to the output vector file.
			write_wave_to_file(output_lines, out, cycle_offset, wave_length, output_edge);

			total_time += wall_time() - wave_start_time;

			// Print netlist-specific statistics.
			if (!cycle_offset)
				print_netlist_stats(stages, num_vectors);

			// Delay drawing of the progress bar until the second wave to improve the accuracy of the ETA.
			if ((num_waves == 1) || cycle_offset)
				progress_bar_position = print_progress_bar(
						cycle/(double)num_cycles, progress_bar_position, progress_bar_length, total_time);
		}

		free_pin_name_list(hold_high);
		free_pin_name_list(hold_low);
		hold_high_index->destroy_free_items(hold_high_index);
		hold_low_index ->destroy_free_items(hold_low_index);

		fflush(out); 
		fprintf(modelsim_out, "run %d\n", num_vectors*100);

		printf("\n");
		// If a second output vector file was given via the -T option, verify that it matches.
		char *output_vector_file = global_args.sim_vector_output_file;
		if (output_vector_file)
		{
			if (verify_output_vectors(output_vector_file, num_vectors))
				printf("Vector file \"%s\" matches output\n", output_vector_file);
			else
				error_message(SIMULATION_ERROR, 0, -1, "Vector files differ.");
			printf("\n");
		}

		// Print statistics.
		print_simulation_stats(stages, num_vectors, total_time, simulation_time);

		free_stages(stages);
	}

	free_lines(output_lines);
	free_lines(input_lines);

	fclose(modelsim_out);
	fclose(in_out);
	if (input_vector_file)
		fclose(in);
	fclose(out);
}

/*
 * This simulates a single cycle using the stages generated
 * during the first cycle. Simulates in parallel if OpenMP is enabled.
 *
 * OpenMP simulation computes a small number of cycles sequentially and
 * a small number in parallel. The minimum parallel and sequential time is
 * taken for each stage, and that stage is computed in parallel for all subsequent
 * cycles if speedup is observed.
 */
void simulate_cycle(int cycle, stages *s)
{
	#ifdef _OPENMP
	// -1 for cycle 0, -1 for the last cycle in the wave.
	const int test_cycles = SIM_WAVE_LENGTH - 2;

	const int st_length = test_cycles/2;
	const int st_start = 1;
	const int st_end = st_start + (st_length-1);

	const int pt_length = test_cycles - st_length;
	const int pt_start = st_end + 1;
	const int pt_end = pt_start + (pt_length-1);

	if (test_cycles < 2)
		error_message(SIMULATION_ERROR, -1, -1, "SIM_WAVE_LENGTH is too small.");

	// Range of cycles over which to test the sequential run times of each stage.
	char sequential_test = (cycle >= st_start && cycle <= st_end);
	// Range of cycles over which to test the parallel run times of each stage.
	char parallel_test   = (cycle >= pt_start && cycle <= pt_end);
	#endif

	int i;
	for(i = 0; i < s->count; i++)
	{
		int j;
		#ifdef _OPENMP
		double time = 0.0;
		if (sequential_test || parallel_test)
			time = wall_time();

		// Compute in parallel if we are profiling or if this stage is known to be faster in parallel.
		char compute_in_parallel = parallel_test
				|| (!sequential_test && !parallel_test && s->sequential_times[i] > s->parallel_times[i]);

		if (compute_in_parallel)
		{	// Compute the stage in parallel.
			#pragma omp parallel for schedule(static)
			for (j = 0; j < s->counts[i]; j++)
				compute_and_store_value(s->stages[i][j], cycle);
		}
		else
		{
		#endif

			// Compute the stage sequentially.
			for (j = 0; j < s->counts[i]; j++)
				compute_and_store_value(s->stages[i][j], cycle);

		#ifdef _OPENMP
		}

		if (sequential_test)
		{
			// Take the minimum sequential time.
			time = wall_time() - time;
			if (s->sequential_times[i] == 0 || time < s->sequential_times[i])
				s->sequential_times[i] = time;
		}
		else if (parallel_test)
		{
			// Take the minimum parallel time.
			time = wall_time() - time;
			if (s->parallel_times[i] == 0 || time < s->parallel_times[i])
				s->parallel_times[i] = time;
		}

		if (cycle == pt_end + 1)
		{
			//printf("%.10f\t %.10f\t %.10f\t %d\t %d\t %f\n", s->sequential_times[i], s->parallel_times[i], s->sequential_times[i]/s->parallel_times[i], s->counts[i], compute_in_parallel, s->num_children[i]/(double)s->counts[i]);
			//printf("%d %d %d %d %d %d\n", st_length, pt_length, st_start, st_end, pt_start, pt_end);

			// Record the number of nodes in parallelizable stages.
			if (compute_in_parallel)
				s->num_parallel_nodes += s->counts[i];
		}
		#endif
	}
}

void original_simulate_cycle(netlist_t *netlist, int cycle)
{
	queue_t *queue = create_queue();

	// Enqueue top input nodes
	int i;
	for (i = 0; i < netlist->num_top_input_nodes; i++)
		enqueue_node_if_ready(queue,netlist->top_input_nodes[i],cycle);

	// Enqueue constant nodes.
	nnode_t *constant_nodes[] = {netlist->gnd_node, netlist->vcc_node, netlist->pad_node};
	int num_constant_nodes = 3;
	for (i = 0; i < num_constant_nodes; i++)
		enqueue_node_if_ready(queue,constant_nodes[i],cycle);

	nnode_t *node;
	while ((node = queue->remove(queue)))
	{
		compute_and_store_value(node, cycle);

		// Enqueue child nodes which are ready, not already queued, and not already complete.
		int num_children = 0;
		nnode_t **children = get_children_of(node, &num_children);

		for (i = 0; i < num_children; i++)
		{
			nnode_t* node = children[i];

			if (!node->in_queue && is_node_ready(node, cycle) && !is_node_complete(node, cycle))
			{
				node->in_queue = TRUE;
				queue->add(queue,node);
			}
		}
		free(children);

		node->in_queue = FALSE;
	}
	queue->destroy(queue);
}

/*
 * Simulates the first cycle by traversing the netlist and returns
 * the nodes organised into parallelizable stages. Also adds lines to
 * custom pins and nodes as requested via the -p option.
 */
stages *simulate_first_cycle(netlist_t *netlist, int cycle, pin_names *p, lines_t *l)
{
	queue_t *queue = create_queue();
	// Enqueue top input nodes
	int i;
	for (i = 0; i < netlist->num_top_input_nodes; i++)
		enqueue_node_if_ready(queue,netlist->top_input_nodes[i],cycle);

	// Enqueue constant nodes.
	nnode_t *constant_nodes[] = {netlist->gnd_node, netlist->vcc_node, netlist->pad_node};
	int num_constant_nodes = 3;
	for (i = 0; i < num_constant_nodes; i++)
		enqueue_node_if_ready(queue,constant_nodes[i],cycle);

	nnode_t **ordered_nodes = 0;
	int   num_ordered_nodes = 0;

	nnode_t *node;
	while ((node = queue->remove(queue)))
	{
		compute_and_store_value(node, cycle);

		// Match node for items passed via -p and add to lines if there's a match.
		add_additional_items_to_lines(node, p, l);

		// Enqueue child nodes which are ready, not already queued, and not already complete.
		int num_children = 0;
		nnode_t **children = get_children_of(node, &num_children);

		for (i = 0; i < num_children; i++)
		{
			nnode_t* node = children[i];

			if (!node->in_queue && is_node_ready(node, cycle) && !is_node_complete(node, cycle))
			{
				node->in_queue = TRUE;
				queue->add(queue,node);
			}
		}
		free(children);

		node->in_queue = FALSE;

		// Add the node to the ordered nodes array.
		ordered_nodes = realloc(ordered_nodes, sizeof(nnode_t *) * (num_ordered_nodes + 1));
		ordered_nodes[num_ordered_nodes++] = node;
	}
	queue->destroy(queue);

	// Reorganise the ordered nodes into stages for parallel computation.
	stages *s = stage_ordered_nodes(ordered_nodes, num_ordered_nodes);
	free(ordered_nodes);

	return s;
}

/*
 * Puts the ordered nodes in stages, each of which can be computed in parallel.
 */
stages *stage_ordered_nodes(nnode_t **ordered_nodes, int num_ordered_nodes) {
	stages *s = malloc(sizeof(stages));
	s->stages = calloc(1,sizeof(nnode_t**));
	s->counts = calloc(1,sizeof(int));
	s->num_children = calloc(1,sizeof(int));
	s->count  = 1;
	s->num_connections = 0;
	s->num_nodes = num_ordered_nodes;
	s->num_parallel_nodes = 0;

	const int index_table_size = (num_ordered_nodes/100)+10;

	// Hash tables index the nodes in the current stage, as well as their children.
	hashtable_t *stage_children = create_hashtable(index_table_size);
	hashtable_t *stage_nodes    = create_hashtable(index_table_size);

	int i;
	for (i = 0; i < num_ordered_nodes; i++)
	{
		nnode_t* node = ordered_nodes[i];
		int stage = s->count-1;

		// Get the node's children for dependency checks.
		int num_children;
		nnode_t **children = get_children_of(node, &num_children);

		// Determine if the node is a child of any node in the current stage.
		int is_child_of_stage = stage_children->get(stage_children, node, sizeof(nnode_t*))?1:0;

		// Determine if any node in the current stage is a child of this node.
		int is_stage_child_of = FALSE;
		int j;
		if (!is_child_of_stage)
			for (j = 0; j < num_children; j++)
				if ((is_stage_child_of = stage_nodes->get(stage_nodes, children[j], sizeof(nnode_t*))?1:0))
					break;

		// Start a new stage if this node is related to any node in the current stage.
		if (is_child_of_stage || is_stage_child_of)
		{
			s->stages       = realloc(s->stages, sizeof(nnode_t**) * (s->count+1));
			s->counts       = realloc(s->counts, sizeof(int)       * (s->count+1));
			s->num_children = realloc(s->num_children, sizeof(int) * (s->count+1));
			stage = s->count++;
			s->stages[stage] = 0;
			s->counts[stage] = 0;
			s->num_children[stage] = 0;

			stage_children->destroy(stage_children);
			stage_nodes   ->destroy(stage_nodes);

			stage_children = create_hashtable(index_table_size);
			stage_nodes    = create_hashtable(index_table_size);
		}

		// Add the node to the current stage.
		s->stages[stage] = realloc(s->stages[stage],sizeof(nnode_t*) * (s->counts[stage]+1));
		s->stages[stage][s->counts[stage]++] = node;

		// Index the node.
		stage_nodes->add(stage_nodes, node, sizeof(nnode_t*), node);

		// Index its children.
		for (j = 0; j < num_children; j++)
			stage_children->add(stage_children, children[j], sizeof(nnode_t*), children[j]);

		// Record the number of children for computing the degree.
		s->num_connections += num_children;

		s->num_children[stage] += num_children;

		free(children);
	}
	stage_children->destroy(stage_children);
	stage_nodes   ->destroy(stage_nodes);

	s->sequential_times = calloc(s->count, sizeof(double));
	s->parallel_times   = calloc(s->count, sizeof(double));

	return s;
}

/*
 * Given a node, this function will simulate that node's new outputs,
 * and updates those pins.
 */
void compute_and_store_value(nnode_t *node, int cycle)
{
	update_undriven_input_pins(node,cycle);

	operation_list type = is_clock_node(node)?CLOCK_NODE:node->type;

	switch(type)
	{
		case MUX_2:
			compute_mux_2_node(node, cycle);
			break;
		case FF_NODE:
			compute_flipflop_node(node, cycle);
			break;
		case MEMORY:
			compute_memory_node(node, cycle);
			break;
		case MULTIPLY:
			compute_multiply_node(node, cycle);
			break;
		case LOGICAL_AND: // &&
		{
			oassert(node->num_output_pins == 1);
			char unknown = FALSE;
			char zero    = FALSE;
			int i;
			for (i = 0; i < node->num_input_pins; i++)
			{
				signed char pin = get_pin_value(node->input_pins[i], cycle);

				if      (pin <  0) { unknown = TRUE; }
				else if (pin == 0) { zero    = TRUE; break; }
			}
			if      (zero)    update_pin_value(node->output_pins[0],  0, cycle);
			else if (unknown) update_pin_value(node->output_pins[0], -1, cycle);
			else              update_pin_value(node->output_pins[0],  1, cycle);
			break;
		}
		case LOGICAL_OR:
		{	// ||
			oassert(node->num_output_pins == 1);
			char unknown = FALSE;
			char one     = FALSE;
			int i;
			for (i = 0; i < node->num_input_pins; i++)
			{
				signed char pin = get_pin_value(node->input_pins[i], cycle);

				if      (pin <  0) { unknown = TRUE; }
				else if (pin == 1) { one     = TRUE; break; }
			}
			if      (one)     update_pin_value(node->output_pins[0],  1, cycle);
			else if (unknown) update_pin_value(node->output_pins[0], -1, cycle);
			else              update_pin_value(node->output_pins[0],  0, cycle);
			break;
		}
		case LOGICAL_NAND:
		{	// !&&
			oassert(node->num_output_pins == 1);
			char unknown = FALSE;
			char one     = FALSE;
			int i;
			for (i = 0; i < node->num_input_pins; i++)
			{
				signed char pin = get_pin_value(node->input_pins[i], cycle);

				if      (pin <  0) { unknown = TRUE; }
				else if (pin == 0) { one     = TRUE; break; }
			}
			if      (one)     update_pin_value(node->output_pins[0],  1, cycle);
			else if (unknown) update_pin_value(node->output_pins[0], -1, cycle);
			else              update_pin_value(node->output_pins[0],  0, cycle);
			break;
		}
		case LOGICAL_NOT: // !
		case LOGICAL_NOR: // !|
		{
			oassert(node->num_output_pins == 1);
			char unknown = FALSE;
			char zero    = FALSE;
			int i;
			for (i = 0; i < node->num_input_pins; i++)
			{
				signed char pin = get_pin_value(node->input_pins[i], cycle);

				if      (pin <  0) { unknown = TRUE; }
				else if (pin == 1) { zero    = TRUE; break; }
			}
			if      (zero)    update_pin_value(node->output_pins[0],  0, cycle);
			else if (unknown) update_pin_value(node->output_pins[0], -1, cycle);
			else              update_pin_value(node->output_pins[0],  1, cycle);
			break;
		}
		case LT: // < 010 1
		{
			oassert(node->num_input_port_sizes == 3);
			oassert(node->num_output_port_sizes == 1);

			signed char pin0 = get_pin_value(node->input_pins[0],cycle);
			signed char pin1 = get_pin_value(node->input_pins[1],cycle);
			signed char pin2 = get_pin_value(node->input_pins[2],cycle);

			if      (pin0  < 0 || pin1  < 0 || pin2  < 0)
				update_pin_value(node->output_pins[0], -1, cycle);
			else if (pin0 == 0 && pin1 == 1 && pin2 == 0)
				update_pin_value(node->output_pins[0],  1, cycle);
			else
				update_pin_value(node->output_pins[0],  0, cycle);

			break;
		}
		case GT: // > 100 1
		{
			oassert(node->num_input_port_sizes == 3);
			oassert(node->num_output_port_sizes == 1);

			signed char pin0 = get_pin_value(node->input_pins[0],cycle);
			signed char pin1 = get_pin_value(node->input_pins[1],cycle);
			signed char pin2 = get_pin_value(node->input_pins[2],cycle);

			if      (pin0  < 0 || pin1  < 0 || pin2  < 0)
				update_pin_value(node->output_pins[0], -1, cycle);
			else if (pin0 == 1 && pin1 == 0 && pin2 == 0)
				update_pin_value(node->output_pins[0],  1, cycle);
			else
				update_pin_value(node->output_pins[0],  0, cycle);

			break;
		}
		case ADDER_FUNC: // 001 1\n010 1\n100 1\n111 1
		{
			oassert(node->num_input_port_sizes == 3);
			oassert(node->num_output_port_sizes == 1);

			signed char pin0 = get_pin_value(node->input_pins[0],cycle);
			signed char pin1 = get_pin_value(node->input_pins[1],cycle);
			signed char pin2 = get_pin_value(node->input_pins[2],cycle);

			if (pin0 < 0 || pin1 < 0 || pin2 < 0)
				update_pin_value(node->output_pins[0], -1, cycle);
			else if (
					   (pin0 == 0 && pin1 == 0 && pin2 == 1)
					|| (pin0 == 0 && pin1 == 1 && pin2 == 0)
					|| (pin0 == 1 && pin1 == 0 && pin2 == 0)
					|| (pin0 == 1 && pin1 == 1 && pin2 == 1)
			)
				update_pin_value(node->output_pins[0], 1, cycle);
			else
				update_pin_value(node->output_pins[0], 0, cycle);

			break;
		}
		case CARRY_FUNC: // 011 1\n100 1\n110 1\n111 1
		{
			oassert(node->num_input_port_sizes == 3);
			oassert(node->num_output_port_sizes == 1);

			signed char pin0 = get_pin_value(node->input_pins[0],cycle);
			signed char pin1 = get_pin_value(node->input_pins[1],cycle);
			signed char pin2 = get_pin_value(node->input_pins[2],cycle);

			if (pin0 < 0 || pin1 < 0 || pin2 < 0)
				update_pin_value(node->output_pins[0], -1, cycle);
			else if (
				   (pin0 == 1 && (pin1 == 1 || pin2 == 1))
				|| (pin1 == 1 && pin2 == 1)
			)
				update_pin_value(node->output_pins[0], 1, cycle);
			else
				update_pin_value(node->output_pins[0], 0, cycle);

			break;
		}
		case NOT_EQUAL:	  // !=
		case LOGICAL_XOR: // ^
		{
			oassert(node->num_output_pins == 1);
			char unknown = FALSE;
			int ones     = 0;
			int i;
			for (i = 0; i < node->num_input_pins; i++)
			{
				signed char pin = get_pin_value(node->input_pins[i], cycle);

				if      (pin <  0) { unknown = TRUE; break; }
				else if (pin == 1) { ones++; }
			}
			if      (unknown)         update_pin_value(node->output_pins[0], -1, cycle);
			else if ((ones % 2) == 1) update_pin_value(node->output_pins[0],  1, cycle);
			else                      update_pin_value(node->output_pins[0],  0, cycle);
			break;
		}
		case LOGICAL_EQUAL:	// ==
		case LOGICAL_XNOR:  // !^
		{
			oassert(node->num_output_pins == 1);
			char unknown = FALSE;
			int ones = 0;
			int i;
			for (i = 0; i < node->num_input_pins; i++)
			{
				signed char pin = get_pin_value(node->input_pins[i], cycle);

				if (pin <  0) { unknown = TRUE; break; }
				if (pin == 1) { ones++; }
			}
			if      (unknown)         update_pin_value(node->output_pins[0], -1, cycle);
			else if ((ones % 2) == 1) update_pin_value(node->output_pins[0],  0, cycle);
			else                      update_pin_value(node->output_pins[0],  1, cycle);
			break;
		}
		case BITWISE_NOT:
		{
			oassert(node->num_input_pins == 1);
			oassert(node->num_output_pins == 1);

			signed char pin = get_pin_value(node->input_pins[0], cycle);

			if      (pin  < 0) update_pin_value(node->output_pins[0], -1, cycle);
			else if (pin == 1) update_pin_value(node->output_pins[0],  0, cycle);
			else               update_pin_value(node->output_pins[0],  1, cycle);
			break;
		}
		case CLOCK_NODE:
		{
			int i;
			for (i = 0; i < node->num_output_pins; i++)
				update_pin_value(node->output_pins[i], is_even_cycle(cycle)?0:1, cycle);
			break;
		}
		case GND_NODE:
			oassert(node->num_output_pins == 1);
			update_pin_value(node->output_pins[0], 0, cycle);
			break;
		case VCC_NODE:
			oassert(node->num_output_pins == 1);
			update_pin_value(node->output_pins[0], 1, cycle);
			break;
		case PAD_NODE:
			oassert(node->num_output_pins == 1);
			update_pin_value(node->output_pins[0], 0, cycle);
			break;
		case INPUT_NODE:
			break;
		case OUTPUT_NODE:
			oassert(node->num_output_pins == 1);
			oassert(node->num_input_pins  == 1);
			update_pin_value(node->output_pins[0], get_pin_value(node->input_pins[0],cycle), cycle);
			break;
		case HARD_IP:
			compute_hard_ip_node(node,cycle);
			break;
		case GENERIC :
			compute_generic_node(node,cycle);
			break;
		/* These should have already been converted to softer versions. */
		case BITWISE_AND:
		case BITWISE_NAND:
		case BITWISE_NOR:
		case BITWISE_XNOR:
		case BITWISE_XOR:
		case BITWISE_OR:
		case BUF_NODE:
		case MULTI_PORT_MUX:
		case SL:
		case SR:
		case CASE_EQUAL:
		case CASE_NOT_EQUAL:
		case DIVIDE:
		case MODULO:
		case GTE:
		case LTE:
		case ADD:
		case MINUS:
		default:
			error_message(SIMULATION_ERROR, 0, -1, "Node should have been converted to softer version: %s", node->name);
			break;
	}

	// Record coverage on any output pins that have changed.
	{
		int i;
		for (i = 0; i < node->num_output_pins; i++)
			if(get_pin_value(node->output_pins[i],cycle-1) != get_pin_value(node->output_pins[i],cycle))
				node->output_pins[i]->coverage++;
	}
}

/*
 * Updates all pins which have been flagged as undriven
 * to -1 for the given cycle.
 *
 * Also checks that other pins have been updated
 * by cycle 3 and throws an error if they haven't been.
 *
 * This function is called when each node is updated as a
 * safeguard.
 */
void update_undriven_input_pins(nnode_t *node, int cycle)
{
	int i;
	for (i = 0; i < node->num_undriven_pins; i++)
	{
		npin_t *pin = node->undriven_pins[i];
		update_pin_value(pin, -1, cycle);
	}

	// By the third cycle everything in the netlist should have been updated.
	if (cycle == 3)
	{
		for (i = 0; i < node->num_input_pins; i++)
		{
			npin_t *pin = node->input_pins[i];
			if (get_pin_cycle(pin) < cycle-1)
			#ifdef _OPENMP
			// Can't have multiple threads trying to error out at the same time.
			#pragma omp critical
			#endif
			{
				char *node_name              = node->name;
				char *pin_name               = pin->name;

				// Print the trace.
				nnode_t *root = print_update_trace(node, cycle);

				// Throw an error.
				error_message(SIMULATION_ERROR,0,-1,"Odin has detected that an input pin attached to %s isn't being updated.\n"
						"\tPin name: %s\n"
						"\tRoot node: %s\n"
						"\tSee the trace immediately above this message for details.\n",
						node_name, pin_name, root?root->name:"N/A"
				);
			}
		}
	}
}

/*
 * Flags any inputs pins which are undriven and have
 * not already been flagged.
 */
void flag_undriven_input_pins(nnode_t *node)
{
	int i;
	for (i = 0; i < node->num_input_pins; i++)
	{
		npin_t *pin = node->input_pins[i];

		if (!pin->net || !pin->net->driver_pin || !pin->net->driver_pin->node)
		{
			int already_flagged = FALSE;
			int j;
			for (j = 0; j < node->num_undriven_pins; j++)
			{
				if (node->undriven_pins[j] == pin)
					already_flagged = TRUE;
			}

			if (!already_flagged)
			{
				node->undriven_pins = realloc(node->undriven_pins, sizeof(npin_t *) * (node->num_undriven_pins + 1));
				node->undriven_pins[node->num_undriven_pins++] = pin;

				warning_message(SIMULATION_ERROR,0,-1,"A node (%s) has an undriven input pin.", node->name);
			}
		}
	}
}

/*
 * Gets the number of nodes whose output pins have been sufficiently covered.
 */
int get_num_covered_nodes(stages *s)
{
	int covered_nodes = 0;
	int i;
	for(i = 0; i < s->count; i++)
	{
		int j;
		for (j = 0; j < s->counts[i]; j++)
		{	/*
			 * To count as being covered, every pin should resolve, and
			 * make at least one transition from one binary value to another
			 * and back. (That's three transitions total.)
			 */
			nnode_t *node = s->stages[i][j];
			int k;
			int covered = TRUE;
			for (k = 0; k < node->num_output_pins; k++)
			{
				if (node->output_pins[k]->coverage < 3)
				{
					covered = FALSE;
					break;
				}
			}

			if (covered)
				covered_nodes++;
		}
	}
	return covered_nodes;
}

/*
 * Enqueues the node in the given queue if is_node_ready returns TRUE.
 */
int enqueue_node_if_ready(queue_t* queue, nnode_t* node, int cycle)
{
	if (is_node_ready(node, cycle))
	{
		node->in_queue = TRUE;
		queue->add(queue, node);
		return TRUE;
	}
	else
	{
		return FALSE;
	}
}

/*
 * Determines if the given node has been simulated for the given cycle.
 */
int is_node_complete(nnode_t* node, int cycle)
{
	int i;
	for (i = 0; i < node->num_output_pins; i++)
		if (node->output_pins[i] && (get_pin_cycle(node->output_pins[i]) < cycle))
			return FALSE;

	return TRUE;
}

/*
 * Checks to see if the node is ready to be simulated for the given cycle.
 */
int is_node_ready(nnode_t* node, int cycle)
{
	if (!cycle)
	{
		flag_undriven_input_pins(node);
		update_undriven_input_pins(node, cycle);
	}

	if (node->type == FF_NODE)
	{
		npin_t *D_pin     = node->input_pins[0];
		npin_t *clock_pin = node->input_pins[1];
		// Flip-flops depend on the D input from the previous cycle and the clock from this cycle.
		if
		(
			   (get_pin_cycle(D_pin    ) < cycle-1)
			|| (get_pin_cycle(clock_pin) < cycle  )
		)
			return FALSE;
	}
	else if (node->type == MEMORY)
	{
		int i;
		for (i = 0; i < node->num_input_pins; i++)
		{
			npin_t *pin = node->input_pins[i];
			// The clock relies on the current cycle. All other memory pins use the previous cycle.
			if (!strcmp(pin->mapping, "clk"))
			{
				if (get_pin_cycle(pin) < cycle)
					return FALSE;
			}
			else
			{
				if (get_pin_cycle(pin) < cycle-1)
					return FALSE;
			}
		}
	}
	else
	{
		int i;
		for (i = 0; i < node->num_input_pins; i++)
			if (get_pin_cycle(node->input_pins[i]) < cycle)
				return FALSE;
	}
	return TRUE;
}

/*
 * Gets the children of the given node. Returns the number of
 * children via the num_children parameter. Throws warnings
 * or errors if invalid connection patterns are detected.
 */
nnode_t **get_children_of(nnode_t *node, int *num_children)
{
	nnode_t **children = 0;
	int count = 0;
	int i;
	for (i = 0; i < node->num_output_pins; i++)
	{
		npin_t *pin = node->output_pins[i];
		nnet_t *net = pin->net;
		if (net)
		{
			/*
			 *  Detects a net that may be being driven by two
			 *  or more pins or has an incorrect driver pin assignment.
			 */
			if (net->driver_pin != pin && global_args.all_warnings)
			{
				char *pin_name  = get_pin_name(pin->name);
				char *node_name = get_pin_name(node->name);
				char *net_name  = get_pin_name(net->name);

				warning_message(SIMULATION_ERROR, -1, -1,
						"Found output pin \"%s\" (%ld) on node \"%s\" (%ld)\n"
						"             which is mapped to a net \"%s\" (%ld) whose driver pin is \"%s\" (%ld) \n",
						pin_name,
						pin->unique_id,
						node_name,
						node->unique_id,
						net_name,
						net->unique_id,
						net->driver_pin->name,
						net->driver_pin->unique_id
				);

				free(net_name);
				free(pin_name);
				free(node_name);
			}

			int j;
			for (j = 0; j < net->num_fanout_pins; j++)
			{
				npin_t *fanout_pin = net->fanout_pins[j];
				if (fanout_pin && fanout_pin->type == INPUT && fanout_pin->node)
				{
					nnode_t *child_node = fanout_pin->node;

					// Check linkage for inconsistencies.
					if (fanout_pin->net != net)
					{
						print_ancestry(child_node, 0);
						error_message(SIMULATION_ERROR, -1, -1, "Found mismapped node %s", node->name);
					}
					else if (fanout_pin->net->driver_pin->net != net)
					{
						print_ancestry(child_node, 0);
						error_message(SIMULATION_ERROR, -1, -1, "Found mismapped node %s", node->name);
					}

					else if (fanout_pin->net->driver_pin->node != node)
					{
						print_ancestry(child_node, 0);
						error_message(SIMULATION_ERROR, -1, -1, "Found mismapped node %s", node->name);
					}
					else
					{
						// Add child.
						children = realloc(children, sizeof(nnode_t*) * (count + 1));
						children[count++] = child_node;
					}
				}
			}
		}
	}
	*num_children = count;
	return children;
}

/*
 * Updates the value of a pin and its cycle. Pins should be updated using
 * only this function.
 *
 * Initializes the pin if need be.
 */
void update_pin_value(npin_t *pin, signed char value, int cycle)
{
	if (!pin->values)
		initialize_pin(pin);

	pin->values[get_values_offset(cycle)] = value;
	set_pin_cycle(pin, cycle);
}

/*
 * Gets the value of a pin. Pins should be checked using this function only.
 */
signed char get_pin_value(npin_t *pin, int cycle)
{
	if (!pin->values || cycle < 0)
		return -1;
	return pin->values[get_values_offset(cycle)];
}

/*
 * Calculates the index in the values array for the given cycle.
 */
inline int get_values_offset(int cycle)
{
	return (((cycle) + (SIM_WAVE_LENGTH)) % (SIM_WAVE_LENGTH));
}

/*
 * Gets the cycle of the given pin
 */
inline int get_pin_cycle(npin_t *pin)
{
	if (!pin->cycle)
		return -1;
	else
		return *(pin->cycle);
}

/*
 * Sets the cycle of the given pin.
 *
 * Only called from update_pin_value.
 */
inline void set_pin_cycle(npin_t *pin, int cycle)
{
	*(pin->cycle) = cycle;
}

/*
 * Returns FALSE if the cycle is odd.
 */
inline int is_even_cycle(int cycle)
{
	return !((cycle + 2) % 2);
}

/*
 * Allocates memory for the pin's value and cycle.
 *
 * Checks to see if this pin's net has a different driver, and
 * initialises that pin too.
 *
 * Fanout pins will share the same memory locations for cycle
 * and values so that the values don't have to be propagated
 * through the net.
 */
void initialize_pin(npin_t *pin)
{
	// Initialise the driver pin if this pin is not the driver.
	if (pin->net && pin->net->driver_pin && pin->net->driver_pin != pin)
		initialize_pin(pin->net->driver_pin);

	// If initialising the driver initialised this pin, we're OK to return.
	if (pin->cycle || pin->values)
		return;

	if (pin->net)
	{
		pin->values = pin->net->values;
		pin->cycle  = &(pin->net->cycle);

		int i;
		for (i = 0; i < pin->net->num_fanout_pins; i++)
		{
			npin_t *fanout_pin = pin->net->fanout_pins[i];
			if (fanout_pin)
			{
				fanout_pin->values = pin->net->values;
				fanout_pin->cycle  = &(pin->net->cycle);
			}
		}
	}
	else
	{
		pin->values = malloc(SIM_WAVE_LENGTH * sizeof(signed char));
		pin->cycle  = malloc(sizeof(int));
	}

	int i;
	for (i = 0; i < SIM_WAVE_LENGTH; i++)
		pin->values[i] = -1;

	set_pin_cycle(pin, -1);
}

/*
 * Returns FALSE if the node is not a clock.
 */
inline int is_clock_node(nnode_t *node)
{
	return (
		   (node->type == CLOCK_NODE)
		|| !strcmp(node->name,"top^clk") // Strictly for memories.
	);
}

/*
 * Returns TRUE if the pin's value for this
 * cycle is 1 and the value for the previous cycle
 * was not 1. Otherwise returns FALSE.
 */
int is_posedge(npin_t *pin, int cycle)
{
	if (get_pin_value(pin,cycle) == 1 && get_pin_value(pin,cycle-1) != 1)
		return TRUE;
	else
		return FALSE;
}

/*
 * Computes a node of type FF_NODE for the given cycle.
 */
void compute_flipflop_node(nnode_t *node, int cycle)
{
	oassert(node->num_output_pins == 1);
	oassert(node->num_input_pins  == 2);

	npin_t *D_pin      = node->input_pins[0];
	npin_t *clock_pin  = node->input_pins[1];
	npin_t *output_pin = node->output_pins[0];

	// Rising edge: update the flip-flop from the input value of the previous cycle.
	if (is_posedge(clock_pin, cycle))
		update_pin_value(output_pin, get_pin_value(D_pin, cycle-1), cycle);
	// Falling edge: maintain the flip-flop value.
	else
		update_pin_value(output_pin, get_pin_value(output_pin,cycle-1), cycle);
}

/*
 * Computes a node of type MUX_2 for the given cycle.
 */
void compute_mux_2_node(nnode_t *node, int cycle)
{
	oassert(node->num_output_pins == 1);
	oassert(node->num_input_port_sizes >= 2);
	oassert(node->input_port_sizes[0] == node->input_port_sizes[1]);

	ast_node_t *ast_node = node->related_ast_node;

	// Figure out which pin is being selected.
	char unknown = FALSE;
	int select = -1;
	int default_select = -1;
	int i;
	for (i = 0; i < node->input_port_sizes[0]; i++)
	{
		npin_t *pin = node->input_pins[i];
		signed char value = get_pin_value(pin, cycle);

		if      (value  < 0)
			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.
	if (unknown && default_select >= 0)
	{
		unknown = FALSE;
		select = default_select;
	}

	npin_t *output_pin = node->output_pins[0];

	// If any select pin is unknown (and we don't have a default), we take the value from the previous cycle.
	if (unknown)
	{
		/*
		 *  Conform to ModelSim's behaviour where in-line ifs are concerned. If the
		 *  condition is unknown, the inline if's output is unknown.
		 */
		if (ast_node && ast_node->type == IF_Q)
			update_pin_value(output_pin, -1, cycle);
		else
			update_pin_value(output_pin, get_pin_value(output_pin, cycle-1), cycle);
	}
	// If no selection is made (all 0) we output x.
	else if (select < 0)
	{
		update_pin_value(output_pin, -1, cycle);
	}
	else
	{
		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);
	}
}



// TODO: Needs to be verified.
void compute_hard_ip_node(nnode_t *node, int cycle)
{
	oassert(node->input_port_sizes[0] > 0);
	oassert(node->output_port_sizes[0] > 0);

	int *input_pins = malloc(sizeof(int)*node->num_input_pins);
	int *output_pins = malloc(sizeof(int)*node->num_output_pins);

	if (!node->simulate_block_cycle)
	{
		char *filename = malloc(sizeof(char)*strlen(node->name));

		if (!index(node->name, '.'))
			error_message(SIMULATION_ERROR, 0, -1,
					"Couldn't extract the name of a shared library for hard-block simulation");

		snprintf(filename, sizeof(char)*strlen(node->name), "%s.so", index(node->name, '.')+1);

		void *handle = dlopen(filename, RTLD_LAZY);

		if (!handle)
			error_message(SIMULATION_ERROR, 0, -1,
					"Couldn't open a shared library for hard-block simulation: %s", dlerror());

		dlerror();

		void (*func_pointer)(int, int, int*, int, int*) =
				(void(*)(int, int, int*, int, int*))dlsym(handle, "simulate_block_cycle");

		char *error = dlerror();
		if (error)
			error_message(SIMULATION_ERROR, 0, -1,
					"Couldn't load a shared library method for hard-block simulation: %s", error);

		node->simulate_block_cycle = func_pointer;

		free(filename);
	}

	int i;
	for (i = 0; i < node->num_input_pins; i++)
		input_pins[i] = get_pin_value(node->input_pins[i],cycle);

	(node->simulate_block_cycle)
			(cycle, node->num_input_pins, input_pins, node->num_output_pins, output_pins);

	for (i = 0; i < node->num_output_pins; i++)
		update_pin_value(node->output_pins[i], output_pins[i], cycle);

	free(input_pins);
	free(output_pins);
}

/*
 * Computes the given multiply node for the given cycle.
 */
void compute_multiply_node(nnode_t *node, int cycle)
{
	oassert(node->num_input_port_sizes == 2);
	oassert(node->num_output_port_sizes == 1);

	int i;
	char unknown = FALSE;
	for (i = 0; i < node->input_port_sizes[0] + node->input_port_sizes[1]; i++)
	{
		signed char pin = get_pin_value(node->input_pins[i],cycle);
		if (pin < 0)
		{
			unknown = TRUE;
			break;
		}
	}

	if (unknown)
	{
		for (i = 0; i < node->num_output_pins; i++)
			update_pin_value(node->output_pins[i], -1, cycle);
	}
	else
	{
		int *a = malloc(sizeof(int)*node->input_port_sizes[0]);
		int *b = malloc(sizeof(int)*node->input_port_sizes[1]);

		for (i = 0; i < node->input_port_sizes[0]; i++)
			a[i] = get_pin_value(node->input_pins[i],cycle);

		for (i = 0; i < node->input_port_sizes[1]; i++)
			b[i] = get_pin_value(node->input_pins[node->input_port_sizes[0] + i],cycle);

		int *result = multiply_arrays(a, node->input_port_sizes[0], b, node->input_port_sizes[1]);

		for (i = 0; i < node->num_output_pins; i++)
			update_pin_value(node->output_pins[i], result[i], cycle);

		free(result);
		free(a);
		free(b);
	}

}

// TODO: Needs to be verified.
void compute_generic_node(nnode_t *node, int cycle)
{
	int line_count_bitmap = node->bit_map_line_count;
	char **bit_map = node->bit_map;

	int lut_size  = 0;
	while (bit_map[0][lut_size] != 0)
		lut_size++;

	int found = 0;
	int i;
	for (i = 0; i < line_count_bitmap && (!found); i++)
	{
		int j;
		for (j = 0; j < lut_size; j++)
		{
			if (get_pin_value(node->input_pins[j],cycle) < 0)
			{
				update_pin_value(node->output_pins[0], -1, cycle);
				return;
			}

			if ((bit_map[i][j] != '-') && (bit_map[i][j]-'0' != get_pin_value(node->input_pins[j],cycle)))
				break;
		}

		if (j == lut_size) found = TRUE;
	}

	if (found) update_pin_value(node->output_pins[0], 1, cycle);
	else       update_pin_value(node->output_pins[0], 0, cycle);
}

/*
 * Takes two arrays of integers (1's and 0's) and returns an array
 * of integers (1's and 0's) that represent their product. The
 * length of the returned array is twice that of the two parameters.
 *
 * This array will need to be freed later!
 */
int *multiply_arrays(int *a, int a_length, int *b, int b_length)
{
	int result_size = a_length + b_length;
	int *result = calloc(sizeof(int), result_size);

	int i;
	for (i = 0; i < a_length; i++)
	{
		if (a[i] == 1)
		{
			int j;
			for (j = 0; j < b_length; j++)
				result[i+j] += b[j];
		}
	}
	for (i = 0; i < result_size; i++)
	{
		while (result[i] > 1)
		{
			result[i] -= 2;
			result[i+1]++;
		}
	}
	return result;
}

/*
 * Computes the given memory node.
 */
void compute_memory_node(nnode_t *node, int cycle)
{
	ast_node_t *ast_node = node->related_ast_node;
	char *identifier = ast_node->children[0]->types.identifier;

	if (!strcmp(identifier, SINGLE_PORT_MEMORY_NAME))
	{
		int posedge = 0;
		int we = 0;
		int data_width = 0;
		int addr_width = 0;
		npin_t **addr = NULL;
		npin_t **data = NULL;
		npin_t **out = NULL;

		int i;
		for (i = 0; i < node->num_input_pins; i++)
		{
			npin_t *pin = node->input_pins[i];
			npin_t **pin_p = &node->input_pins[i];

			if (!strcmp(pin->mapping, "we"))
			{
				we = get_pin_value(pin, cycle-1);
			}
			else if (!strcmp(pin->mapping, "addr"))
			{
				if (!addr) addr = pin_p;
				addr_width++;
			}
			else if (!strcmp(pin->mapping, "data"))
			{
				if (!data) data = pin_p;
				data_width++;
			}
			else if (!strcmp(pin->mapping, "clk"))
			{
				posedge = is_posedge(pin, cycle);
			}
		}

		out = node->output_pins;

		if (!node->memory_data)
			instantiate_memory(node, data_width, addr_width);

		compute_single_port_memory(
			node,
			data,
			out,
			data_width,
			addr,
			addr_width,
			we,
			posedge,
			cycle
		);
	}
	else if (!strcmp(identifier, DUAL_PORT_MEMORY_NAME))
	{
		int posedge = 0;
		int we1 = 0;
		int data_width1 = 0;
		int addr_width1 = 0;
		int we2 = 0;
		int data_width2 = 0;
		int addr_width2 = 0;

		npin_t **addr1 = NULL;
		npin_t **data1 = NULL;
		npin_t **out1  = NULL;
		npin_t **addr2 = NULL;
		npin_t **data2 = NULL;
		npin_t **out2  = NULL;

		int i;
		for (i = 0; i < node->num_input_pins; i++)
		{
			npin_t *pin = node->input_pins[i];
			npin_t **pin_p = &node->input_pins[i];

			if (!strcmp(pin->mapping, "we1"))
			{
				we1 = get_pin_value(pin, cycle-1);
			}
			else if (!strcmp(pin->mapping, "we2"))
			{
				we2 = get_pin_value(pin, cycle-1);
			}
			else if (!strcmp(pin->mapping, "addr1") )
			{
				if (!addr1) addr1 = pin_p;
				addr_width1++;
			}
			else if (!strcmp(pin->mapping, "addr2"))
			{
				if (!addr2) addr2 = pin_p;
				addr_width2++;
			}
			else if (!strcmp(pin->mapping, "data1"))
			{
				if (!data1) data1 = pin_p;
				data_width1++;
			}
			else if (!strcmp(pin->mapping, "data2"))
			{
				if (!data2) data2 = pin_p;
				data_width2++;
			}
			else if (!strcmp(pin->mapping, "clk"))
			{
				posedge = is_posedge(pin, cycle);
			}
		}

		for (i = 0; i < node->num_output_pins; i++)
		{
			npin_t *pin = node->output_pins[i];
			npin_t **pin_p = &node->output_pins[i];

			if      (!strcmp(pin->mapping, "out1") && !out1) out1 = pin_p;
			else if (!strcmp(pin->mapping, "out2") && !out2) out2 = pin_p;
		}

		if (addr_width1 != addr_width2)
			error_message(SIMULATION_ERROR, 0, -1, "Dual port memory addresses are not the same width.");

		if (data_width1 != data_width2)
			error_message(SIMULATION_ERROR, 0, -1, "Dual port memory data ports are not the same width.");

		if (!node->memory_data)
			instantiate_memory(node, data_width2, addr_width2);

		compute_dual_port_memory(
			node,
			data1,
			data2,
			out1,
			out2,
			data_width1,
			addr1,
			addr2,
			addr_width1,
			we1,
			we2,
			posedge,
			cycle
		);
	}
	else
	{
		error_message(SIMULATION_ERROR, 0, -1,
				"Could not resolve memory hard block %s to a valid type.", node->name);
	}
}

/*
 * Computes single port memory.
 */
void compute_single_port_memory(
	nnode_t *node,
	npin_t **data,
	npin_t **out,
	int data_width,
	npin_t **addr,
	int addr_width,
	int we,
	int posedge,
	int cycle
)
{
	// On the rising edge, compute the memory.
	if (posedge)
	{
		long address = compute_memory_address(out, data_width, addr, addr_width, cycle-1);
		char address_ok = (address != -1)?1:0;

		int i;
		for (i = 0; i < data_width; i++)
		{
			// Compute which bit we are addressing.
			long bit_address = address_ok?(i + (address * data_width)):-1;

			// Update the output.
			if (address_ok)
				update_pin_value(out[i], node->memory_data[bit_address], cycle);
			else
				update_pin_value(out[i], -1, cycle);

			// If write is enabled, copy the input to memory.
			if (address_ok && we)
				node->memory_data[bit_address] = get_pin_value(data[i],cycle-1);
		}
	}
	else
	{
		// On falling edge, we hold the previous value.
		int i;
		for (i = 0; i < data_width; i++)
			update_pin_value(out[i], get_pin_value(out[i],cycle-1), cycle);
	}
}

/*
 * Computes dual port memory.
 */
void compute_dual_port_memory(
	nnode_t *node,
	npin_t **data1,
	npin_t **data2,
	npin_t **out1,
	npin_t **out2,
	int data_width,
	npin_t **addr1,
	npin_t **addr2,
	int addr_width,
	int we1,
	int we2,
	int posedge,
	int cycle
)
{
	// On the rising edge, we compute the memory.
	if (posedge)
	{
		long address1 = compute_memory_address(out1, data_width, addr1, addr_width, cycle-1);
		long address2 = compute_memory_address(out2, data_width, addr2, addr_width, cycle-1);

		char port1 = (address1 != -1)?1:0;
		char port2 = (address2 != -1)?1:0;

		// Read (and write if we) data to memory.
		int i;
		for (i = 0; i < data_width; i++)
		{
			// Compute which bit we are addressing.
			long bit_address1 = port1?(i + (address1 * data_width)):-1;
			long bit_address2 = port2?(i + (address2 * data_width)):-1;

			// Read the memory bit
			if (port1)
				update_pin_value(out1[i], node->memory_data[bit_address1], cycle);
			else
				update_pin_value(out1[i], -1, cycle);

			if (port2)
				update_pin_value(out2[i], node->memory_data[bit_address2], cycle);
			else
				update_pin_value(out2[i], -1, cycle);

			// Write to the memory
			if (port1 && we1)
				node->memory_data[bit_address1] = get_pin_value(data1[i],cycle-1);
			if (port2 && we2)
				node->memory_data[bit_address2] = get_pin_value(data2[i],cycle-1);
		}
	}
	else
	{
		// On falling edge, we hold the previous value.
		int i;
		for (i = 0; i < data_width; i++)
		{
			update_pin_value(out1[i], get_pin_value(out1[i],cycle-1), cycle);
			update_pin_value(out2[i], get_pin_value(out2[i],cycle-1), cycle);
		}
	}
}

/*
 * Calculates the memory address. Updates the output to -1's and returns
 * -1 if the address is unknown.
 */
long compute_memory_address(npin_t **out, int data_width, npin_t **addr, int addr_width, int cycle)
{
	long address = 0;
	int i;
	for (i = 0; i < addr_width; i++)
	{
		// If any address pins are x's, write x's we return -1.
		if (get_pin_value(addr[i],cycle) < 0)
			return -1;

		address += get_pin_value(addr[i],cycle) << (i);
	}

	return address;
}

/*
 * Initialises memory using a memory information file (mif). If not
 * file is found, it is initialised to x's.
 */
// TODO: This obviously won't work with mif files, as it doesn't even write the values to the memory.
void instantiate_memory(nnode_t *node, int data_width, int addr_width)
{
	long max_address = 1 << addr_width;
	node->memory_data = malloc(sizeof(signed char) * max_address * data_width);

	// Initialise the memory to -1.
	int i;
	for (i = 0; i < max_address * data_width; i++)
		node->memory_data[i] = -1;

	char *filename = get_mif_filename(node);
	FILE *mif = fopen(filename, "r");
	if (mif)
	{
		error_message(SIMULATION_ERROR, 0, -1, "MIF file support is current broken and needs developer attention.");

		char input[BUFFER_MAX_SIZE];
		while (fgets(input, BUFFER_MAX_SIZE, mif))
			if (strcmp(input, "Content\n") == 0)
				break;

		while (fgets(input, BUFFER_MAX_SIZE, mif))
		{
			char *addr = malloc(sizeof(char)*BUFFER_MAX_SIZE);
			char *data = malloc(sizeof(char)*BUFFER_MAX_SIZE);

			if (!(strcmp(input, "Begin\n") == 0 || strcmp(input, "End;") == 0 || strcmp(input, "End;\n") == 0))
			{
				char *colon = strchr(input, ':');

				strncpy(addr, input, (colon-input));
				colon += 2;

				char *semicolon = strchr(input, ';');
				strncpy(data, colon, (semicolon-colon));

				long addr_val = strtol(addr, 0, 10);
				long data_val = strtol(data, 0, 16);

				int i;
				for (i = 0; i < data_width; i++)
				{
					int mask = (1 << ((data_width - 1) - i));
					signed char val = (mask & data_val) > 0 ? 1 : 0;
					int write_address = i + (addr_val * data_width);
					// TODO: This is obviously incorrect, as it's writing the value to a small char buffer which isn't connected to the memory.
					data[write_address] = val;
				}
			}
		}
		fclose(mif);
	}
	free(filename);
}

/*
 * Assigns the given node to its corresponding line in the given array of line.
 * Assumes the line has already been created.
 */
void assign_node_to_line(nnode_t *node, lines_t *l, int type, int single_pin)
{
	// Make sure the node has an output pin.
	if (!node->num_output_pins)
	{
		npin_t *pin = allocate_npin();
		allocate_more_node_output_pins(node, 1);
		add_a_output_pin_to_node_spot_idx(node, pin, 0);
	}

	// Parse the node name into a pin number and a port name.
	int pin_number = get_pin_number(node->name);
	char *port_name;
	if (pin_number != -1 && !single_pin) {
		port_name = get_port_name(node->name);
	}
	else {
		port_name = get_pin_name(node->name);
		single_pin = TRUE;
	}
	// Search the lines for the port name.
	int j = find_portname_in_lines(port_name, l);
	free(port_name);

	if (single_pin)
	{
		if (j == -1)
		{
			warning_message(SIMULATION_ERROR, 0, -1,
					"Could not map single-bit node '%s' line", node->name);
		}
		else
		{
			pin_number = (pin_number == -1)?0:pin_number;
			int already_added = l->lines[j]->number_of_pins >= 1;
			if (!already_added)
				insert_pin_into_line(node->output_pins[0], pin_number, l->lines[j], type);
		}
	}
	else
	{
		if (j == -1)
			warning_message(SIMULATION_ERROR, 0, -1,
					"Could not map multi-bit node '%s' to line", node->name);
		else
			insert_pin_into_line(node->output_pins[0], pin_number, l->lines[j], type);
	}
}

/*
 * Inserts the given pin according to its pin number into the given line.
 */
void insert_pin_into_line(npin_t *pin, int pin_number, line_t *line, int type)
{
	// Allocate memory for the new pin.
	line->pins        = realloc(line->pins,        sizeof(npin_t*) * (line->number_of_pins + 1));
	line->pin_numbers = realloc(line->pin_numbers, sizeof(npin_t*) * (line->number_of_pins + 1));

	// Find the proper place to insert this pin, and make room for it.
	int i;
	for (i = 0; i < line->number_of_pins; i++)
	{
		if (line->pin_numbers[i] > pin_number)
		{
			// Move other pins to the right to make room.
			int j;
			for (j = line->number_of_pins; j > i; j--)
			{
				line->pins[j] = line->pins[j-1];
				line->pin_numbers[j] = line->pin_numbers[j-1];
			}
			break;
		}
	}
	// Add the new pin.
	line->pins[i] = pin;
	line->pin_numbers[i] = pin_number;
	line->type = type;
	line->number_of_pins++;
}

/*
 * Given a netlist, this function maps the top_input_nodes
 * or top_output_nodes depending on the value of type
 * (INPUT or OUTPUT) to a line_t each. It stores them in a
 * lines_t struct and returns a pointer to it.
 */
lines_t *create_lines(netlist_t *netlist, int type)
{
	lines_t *l = malloc(sizeof(lines_t));
	l->lines = 0;
	l->count = 0;

	int num_nodes   = (type == INPUT)?netlist->num_top_input_nodes:netlist->num_top_output_nodes;
	nnode_t **nodes = (type == INPUT)?netlist->top_input_nodes    :netlist->top_output_nodes;

	int i;
	for (i = 0; i < num_nodes; i++)
	{
		nnode_t *node = nodes[i];
		char *port_name = get_port_name(node->name);

		if (type == OUTPUT || !is_clock_node(node))
		{
			if (find_portname_in_lines(port_name, l) == -1)
			{
				line_t *line = create_line(port_name);
				l->lines = realloc(l->lines, sizeof(line_t *)*(l->count + 1));
				l->lines[l->count++] = line;
			}
			assign_node_to_line(node, l, type, 0);
		}
		free(port_name);
	}
	return l;
}

/*
 * Creates a vector file header from the given lines,
 * and writes it to the given file.
 */
void write_vector_headers(FILE *file, lines_t *l)
{
	char* headers = generate_vector_header(l);
	fprintf(file, "%s", headers);
	free(headers);
	fflush(file);
}

/*
 * Parses the first line of the given file and compares it to the
 * given lines for identity. If there is any difference, a warning is printed,
 * and FALSE is returned. If there are no differences, the file pointer is left
 * at the start of the second line, and TRUE is returned.
 */
int verify_test_vector_headers(FILE *in, lines_t *l)
{
	int current_line = 0;
	int buffer_length = 0;

	// Read the header from the vector file.
	char read_buffer [BUFFER_MAX_SIZE];
	rewind(in);
	if (!get_next_vector(in, read_buffer))
		error_message(SIMULATION_ERROR, 0, -1, "Failed to read vector headers.");

	// Parse the header, checking each entity against the corresponding line.
	char buffer [BUFFER_MAX_SIZE];
	buffer[0] = '\0';
	int i;
	for (i = 0; i < strlen(read_buffer) && i < BUFFER_MAX_SIZE; i++)
	{
		char next = read_buffer[i];

		if (next == EOF)
		{
			warning_message(SIMULATION_ERROR, 0, -1, "Hit end of file.");
			return FALSE;
		}
		else if (next == ' ' || next == '\t' || next == '\n')
		{
			if (buffer_length)
			{
				if(strcmp(l->lines[current_line]->name,buffer))
				{
					char *expected_header = generate_vector_header(l);
					warning_message(SIMULATION_ERROR, 0, -1,
							"Vector header mismatch: \n "
							"  Found:    %s "
							"  Expected: %s", read_buffer, expected_header);
					free(expected_header);
					return FALSE;
				}
				else
				{
					buffer_length = 0;
					current_line++;
				}
			}

			if (next == '\n')
				break;
		}
		else
		{
			buffer[buffer_length++] = next;			
			buffer[buffer_length] = '\0';
		}		
	}
	return TRUE;
}

/* 
 * Verifies that no lines have null pins.
 */
int verify_lines (lines_t *l)
{
	int i; 
	for (i = 0; i < l->count; i++)
	{
		int j;
		for (j = 0; j < l->lines[i]->number_of_pins; j++)
		{
			if (!l->lines[i]->pins[j])
			{
				warning_message(SIMULATION_ERROR, 0, -1, "A line %d:(%s) has a NULL pin. ", j, l->lines[i]->name);
				return FALSE; 
			}
		}
	}
	return TRUE; 
}

/*
 * Searches for a line with the given name in the lines. Returns the index
 * or -1 if no such line was found.
 */
int find_portname_in_lines(char* port_name, lines_t *l)
{
	int j;
	for (j = 0; j < l->count; j++)
		if (!strcmp(l->lines[j]->name, port_name))
			return  j;

	return -1;
}

/*
 * allocates memory for and initialises a line_t struct
 */
line_t *create_line(char *name)
{
	line_t *line = malloc(sizeof(line_t));

	line->number_of_pins = 0;
	line->pins = 0;
	line->pin_numbers = 0;
	line->type = -1;
	line->name = malloc(sizeof(char)*(strlen(name)+1));

	strcpy(line->name, name);

	return line;
}

/*
 * Generates the appropriate vector headers based on the given lines.
 */
char *generate_vector_header(lines_t *l)
{
	char *header = calloc(BUFFER_MAX_SIZE, sizeof(char));
	if (l->count)
	{
		int j;
		for (j = 0; j < l->count; j++)
		{
			// "+ 2" for null and newline/space.
			if ((strlen(header) + strlen(l->lines[j]->name) + 2) > BUFFER_MAX_SIZE)
				error_message(SIMULATION_ERROR, 0, -1, "Buffer overflow anticipated while generating vector header.");

			strcat(header,l->lines[j]->name);
			strcat(header," ");
		}
		header[strlen(header)-1] = '\n';
	}
	else
	{
		header[0] = '\n';
	}
	header = realloc(header, sizeof(char)*(strlen(header)+1));
	return header;
}

/*
 * Stores the given test vector in the given lines, with some sanity checking to ensure that it
 * has a compatible geometry.
 */
void add_test_vector_to_lines(test_vector *v, lines_t *l, int cycle)
{
	if (l->count < v->count) 
		error_message(SIMULATION_ERROR, 0, -1, "Fewer lines (%d) than values (%d).", l->count, v->count);
	if (l->count > v->count) 
		error_message(SIMULATION_ERROR, 0, -1, "More lines (%d) than values (%d).", l->count, v->count);

	int i;
	for (i = 0; i < v->count; i++)
	{
		line_t *line = l->lines[i];

		if (line->number_of_pins < 1)
			error_message(SIMULATION_ERROR, 0, -1, "Found a line '%s' with no pins.", line->name);

		int j;
		for (j = 0; j < line->number_of_pins; j++)
		{
			if (j < v->counts[i]) update_pin_value(line->pins[j], v->values[i][j], cycle);
			else                  update_pin_value(line->pins[j], 0, cycle);
		}
	}
}

/*
 * Compares two test vectors for numerical and geometric identity. Returns FALSE if
 * they are found to be different, and TRUE otherwise.
 */
int compare_test_vectors(test_vector *v1, test_vector *v2)
{
	if (v1->count != v2->count)
	{
		warning_message(SIMULATION_ERROR, 0, -1, "Vector lengths differ.");
		return FALSE;
	}

	int l;
	for (l = 0; l < v1->count; l++)
	{	// Compare bit by bit.
		int i;
		for (i = 0; i < v1->counts[l] && i < v2->counts[l]; i++)
			if (v1->values[l][i] != v2->values[l][i])
				return FALSE;

		/*
		 *  If one value has more bits than the other, they are still
		 *  equivalent as long as the higher order bits of the longer
		 *  one are zero.
		 */
		if (v1->counts[l] != v2->counts[l])
		{
			test_vector *v = v1->counts[l] < v2->counts[l] ? v2 : v1;
			int j;
			for (j = i; j < v->counts[l]; j++)
				if (v->values[l][j] != 0)
					return FALSE;
		}
	}
	return TRUE;
}

/*
 * Parses the given line from a test vector file into a
 * test_vector data structure.
 */
test_vector *parse_test_vector(char *buffer)
{
	buffer = strdup(buffer);
	test_vector *v = malloc(sizeof(test_vector));
	v->values = 0;
	v->counts = 0;
	v->count  = 0;

	trim_string(buffer,"\r\n");

	const char *delim = " \t";
	char *token = strtok(buffer, delim);
	while (token)
	{
		v->values = realloc(v->values, sizeof(signed char *) * (v->count + 1));
		v->counts = realloc(v->counts, sizeof(int) * (v->count + 1));
		v->values[v->count] = 0;
		v->counts[v->count] = 0;

		if (token[0] == '0' && (token[1] == 'x' || token[1] == 'X'))
		{	// Value is hex.
			token += 2;
			int token_length = strlen(token);
			reverse_string(token, token_length);
			int i;
			for (i = 0; i < token_length; i++)
			{
				char temp[] = {token[i],'\0'};

				int value = strtol(temp, NULL, 16);
				int k;
				for (k = 0; k < 4; k++)
				{
						signed char bit = 0;
						if (value > 0)
						{
							bit = value % 2;
							value /= 2;
						}
						v->values[v->count] = realloc(v->values[v->count], sizeof(signed char) * (v->counts[v->count] + 1));
						v->values[v->count][v->counts[v->count]++] = bit;
				}
			}
		}
		else
		{	// Value is binary.
			int i;
			for (i = strlen(token) - 1; i >= 0; i--)
			{
				signed char value = -1;
				if      (token[i] == '0') value = 0;
				else if (token[i] == '1') value = 1;

				v->values[v->count] = realloc(v->values[v->count], sizeof(signed char) * (v->counts[v->count] + 1));
				v->values[v->count][v->counts[v->count]++] = value;
			}
		}
		v->count++;
		token = strtok(NULL, delim);
	}
	free(buffer);
	return v;
}

/*
 * Generates a "random" test_vector structure based on the geometry of the given lines.
 *
 * If you want better randomness, call srand at some point.
 */
test_vector *generate_random_test_vector(lines_t *l, int cycle, hashtable_t *hold_high_index, hashtable_t *hold_low_index)
{
	test_vector *v = malloc(sizeof(test_vector));
	v->values = 0;
	v->counts = 0;
	v->count = 0;

	int i;
	for (i = 0; i < l->count; i++)
	{
		v->values = realloc(v->values, sizeof(signed char *) * (v->count + 1));
		v->counts = realloc(v->counts, sizeof(int) * (v->count + 1));
		v->values[v->count] = 0;
		v->counts[v->count] = 0;

		int j;
		for (j = 0; j < l->lines[i]->number_of_pins; j++)
		{
			char *name = l->lines[i]->name;
			signed char value;
			if      (hold_high_index->count && hold_high_index->get(hold_high_index,name,sizeof(char)*strlen(name)))
			{
				if (!cycle) value = 0;
				else        value = 1;
			}
			else if (hold_low_index->count  && hold_low_index->get(hold_low_index,name,sizeof(char)*strlen(name)))
			{
				if (!cycle) value = 1;
				else        value = 0;
			}
			else
			{
				// Passed via the -3 option.
				if (global_args.sim_generate_three_valued_logic)
					value = (rand() % 3) - 1;
				else
					value = (rand() % 2);
			}

			v->values[v->count] = realloc(v->values[v->count], sizeof(signed char) * (v->counts[v->count] + 1));		
			v->values[v->count][v->counts[v->count]++] = value;
		}
		v->count++;
	}
	return v;
}

/*
 * Writes a wave of vectors to the given file. Writes the headers
 * prior to cycle 0.
 *
 * When edge is -1, both edges of the clock are written. When edge is 0,
 * the falling edge is written. When edge is 1, the rising edge is written.
 */ 
void write_wave_to_file(lines_t *l, FILE* file, int cycle_offset, int wave_length, int edge)
{
	if (!cycle_offset)
		write_vector_headers(file, l);

	int cycle;
	for (cycle = cycle_offset; cycle < (cycle_offset + wave_length); cycle++)
	{
		if (edge == -1 || (edge ==  0 &&  is_even_cycle(cycle)) || (edge ==  1 && !is_even_cycle(cycle)))
			write_vector_to_file(l, file, cycle);
	}
}

/*
 * Writes all values in the given lines to a line in the given file
 * for the given cycle.
 */
void write_vector_to_file(lines_t *l, FILE *file, int cycle)
{
	char buffer[BUFFER_MAX_SIZE];
	int i; 
	for (i = 0; i < l->count; i++)
	{
		line_t *line = l->lines[i];
		int num_pins = line->number_of_pins;

		if (line_has_unknown_pin(line, cycle) || num_pins == 1)
		{
			if ((num_pins + 1) > BUFFER_MAX_SIZE)
				error_message(SIMULATION_ERROR, 0, -1, "Buffer overflow anticipated while writing vector for line %s.", line->name);

			buffer[0] = 0;

			int j;
			int known_values = 0;
			for (j = num_pins - 1; j >= 0 ; j--)
			{
				signed char value = get_line_pin_value(line, j, cycle);

				if (value > 1)
					error_message(SIMULATION_ERROR, 0, -1, "Invalid logic value of %d read from line %s.", value, line->name);

				if (value < 0)
				{
					strcat(buffer, "x");
				}
				else
				{	known_values++;
					sprintf(buffer, "%s%d", buffer, value);
				}
			}
			// If there are no known values, print a single capital X.
			// (Only for testing. Breaks machine readability.)
			//if (!known_values && num_pins > 1)
			//	sprintf(buffer, "X");
		}
		else
		{	
			// +1 for ceiling, +1 for null, +2 for "OX"
			if ((num_pins/4 + 1 + 1 + 2) > BUFFER_MAX_SIZE)
				error_message(SIMULATION_ERROR, 0, -1, "Buffer overflow anticipated while writing vector for line %s.", line->name);

			sprintf(buffer, "0X");

			int hex_digit = 0;				
			int j;
			for (j = num_pins - 1; j >= 0; j--)
			{
				signed char value = get_line_pin_value(line,j,cycle);

				if (value > 1)
					error_message(SIMULATION_ERROR, 0, -1, "Invalid logic value of %d read from line %s.", value, line->name);

				hex_digit += value << j % 4;
				
				if (!(j % 4))
				{
					sprintf(buffer, "%s%X", buffer, hex_digit);
					hex_digit = 0;
				}
			}
		}

		// Expand the value to fill to space under the header. (Gets ugly sometimes.)
		//while (strlen(buffer) < strlen(l->lines[i]->name))
		//	strcat(buffer," ");

		fprintf(file,"%s ",buffer);
	}
	fprintf(file, "\n");
}

/*
 * Writes a wave of vectors to the given modelsim out file.
 */
void write_wave_to_modelsim_file(netlist_t *netlist, lines_t *l, FILE* modelsim_out, int cycle_offset, int wave_length)
{
	if (!cycle_offset)
	{
		fprintf(modelsim_out, "add wave *\n");

		// Add clocks to the output file.
		int i;
		for (i = 0; i < netlist->num_top_input_nodes; i++)
		{
			nnode_t *node = netlist->top_input_nodes[i];
			if (is_clock_node(node))
			{
				char *port_name = get_port_name(node->name);
				fprintf(modelsim_out, "force %s 0 0, 1 50 -repeat 100\n", port_name);
				free(port_name);
			}
		}
	}

	int cycle;
	for (cycle = cycle_offset; cycle < (cycle_offset + wave_length); cycle ++)
	{
		if (!is_even_cycle(cycle))
			write_vector_to_modelsim_file(l, modelsim_out, cycle);
	}
}

/*
 * Writes a vector to the given modelsim out file.
 */
void write_vector_to_modelsim_file(lines_t *l, FILE *modelsim_out, int cycle)
{
	int i;
	for (i = 0; i < l->count; i++)
	{
		if (line_has_unknown_pin(l->lines[i], cycle) || l->lines[i]->number_of_pins == 1)
		{
			fprintf(modelsim_out, "force %s ",l->lines[i]->name);
			int j;

			for (j = l->lines[i]->number_of_pins - 1; j >= 0 ; j--)
			{
				int value = get_line_pin_value(l->lines[i],j,cycle);

				if (value < 0)  fprintf(modelsim_out, "%s", "x");
				else 		fprintf(modelsim_out, "%d", value);
			}
			fprintf(modelsim_out, " %d\n", cycle/2 * 100);
		}
		else
		{
			int value = 0;
			fprintf(modelsim_out, "force %s 16#", l->lines[i]->name);

			int j;
			for (j = l->lines[i]->number_of_pins - 1; j >= 0; j--)
			{
				if (get_line_pin_value(l->lines[i],j,cycle) > 0)
					value += my_power(2, j % 4);

				if (j % 4 == 0)
				{
					fprintf(modelsim_out, "%X", value);
					value = 0;
				}
			}
			fprintf(modelsim_out, " %d\n", cycle/2 * 100);
		}

	}
}

/*
 * Verify that the given output vector file is identical (numerically)
 * to the one written by the current simulation. This is done by parsing each
 * file vector by vector and comparing them. Also verifies that the headers are identical.
 *
 * Prints appropriate warning messages when differences are found.
 *
 * Returns false if the files differ and true if they are identical, with the exception of
 * number format.
 */
int verify_output_vectors(char* output_vector_file, int num_vectors)
{
	if (global_args.sim_output_both_edges)
		num_vectors *= 2;

	int error = FALSE;

	// The filename cannot be the same as our default output file.
	if (!strcmp(output_vector_file,OUTPUT_VECTOR_FILE_NAME))
	{
		error = TRUE;
		warning_message(SIMULATION_ERROR,0,-1,
				"Vector file \"%s\" given for verification "
				"is the same as the default output file \"%s\". "
				"Ignoring.", output_vector_file, OUTPUT_VECTOR_FILE_NAME);
	}
	else
	{
		// The file being verified against.
		FILE *existing_out = fopen(output_vector_file, "r");
		if (!existing_out) error_message(SIMULATION_ERROR, 0, -1, "Could not open vector output file: %s", output_vector_file);

		// Our current output vectors. (Just produced.)
		FILE *current_out  = fopen(OUTPUT_VECTOR_FILE_NAME, "r");
		if (!current_out) error_message(SIMULATION_ERROR, 0, -1, "Could not open output vector file.");

		int cycle;
		char buffer1[BUFFER_MAX_SIZE];
		char buffer2[BUFFER_MAX_SIZE];
		// Start at cycle -1 to check the headers.
		for (cycle = -1; cycle < num_vectors; cycle++)
		{
			if (!get_next_vector(existing_out, buffer1))
			{
				error = TRUE;
				warning_message(SIMULATION_ERROR, 0, -1,"Too few vectors in %s \n", output_vector_file);
				break;
			}
			else if (!get_next_vector(current_out, buffer2))
			{
				error = TRUE;
				warning_message(SIMULATION_ERROR, 0, -1,"Simulation produced fewer than %d vectors. \n", num_vectors);
				break;
			}
			// The headers differ.
			else if ((cycle == -1) && strcmp(buffer1,buffer2))
			{
				error = TRUE;
				warning_message(SIMULATION_ERROR, 0, -1, "Vector headers do not match: \n"
						"\t%s"
						"in %s does not match\n"
						"\t%s"
						"in %s.\n\n",
						buffer2, OUTPUT_VECTOR_FILE_NAME, buffer1, output_vector_file
				);
				break;
			}
			else
			{
				// Parse both vectors.
				test_vector *v1 = parse_test_vector(buffer1);
				test_vector *v2 = parse_test_vector(buffer2);

				// Compare them and print an appropriate message if they differ.
				if (!compare_test_vectors(v1,v2))
				{
					trim_string(buffer1, "\n\t");
					trim_string(buffer2, "\n\t");
					error = TRUE;
					warning_message(SIMULATION_ERROR, 0, -1, "Vector %d mismatch:\n"
							"\t%s in %s\n"
							"\t%s in %s\n",
							cycle, buffer2, OUTPUT_VECTOR_FILE_NAME, buffer1, output_vector_file
					);
				}
				free_test_vector(v1);
				free_test_vector(v2);
			}
		}

		// If the file we're checking against is longer than the current output, print an appropriate warning.
		if (!error && get_next_vector(existing_out, buffer1))
		{
			error = TRUE;
			warning_message(SIMULATION_ERROR, 0, -1,"%s contains more than %d vectors.\n", output_vector_file, num_vectors);
		}

		fclose(existing_out);
		fclose(current_out);
	}
	return !error;
}

/*
 * Creates a hastable_t index of the given pin names list
 * of the form pin name hashes to pin name array index.
 */
hashtable_t *index_pin_name_list(pin_names *list)
{
	hashtable_t *index = create_hashtable(list->count * 2+1);
	int i;
	for (i = 0; i < list->count; i++)
	{
		int *id = malloc(sizeof(int));
		*id = i;
		index->add(index, list->pins[i], sizeof(char)*strlen(list->pins[i]), id);
	}
	return index;
}

/*
 * Parses the given comma separated list into a
 * pin_names struct. If the list is empty or null
 * an empty struct is returned.
 */
pin_names *parse_pin_name_list(char *list)
{
	pin_names *p = malloc(sizeof(pin_names));
	p->pins  = 0;
	p->count = 0;

	// Parse the list of additional pins passed via the -p option.
	if (list)
	{
		char *pin_list = strdup(list);
		char *token    = strtok(pin_list, ",");
		while (token)
		{
			p->pins = realloc(p->pins, sizeof(char *) * (p->count + 1));
			p->pins[p->count++] = strdup(token);
			token = strtok(NULL, ",");
		}
		free(pin_list);
	}
	return p;
}

/*
 * If the given node matches one of the additional names (passed via -p),
 * it's added to the lines. (Matches on output pin names, net names, and node names).
 */
void add_additional_items_to_lines(nnode_t *node, pin_names *p, lines_t *l)
{
	if (p->count)
	{
		int add = FALSE;
		int j, k = 0;

		// Search the output pin names for each user-defined item.
		for (j = 0; j < node->num_output_pins; j++)
		{
			npin_t *pin = node->output_pins[j];

			if (pin->name)
			{
				for (k = 0; k < p->count; k++)
				{
					if (strstr(pin->name, p->pins[k]))
					{
						add = TRUE;
						break;
					}
				}
				if (add) break;
			}

			if (pin->net && pin->net->name)
			{
				for (k = 0; k < p->count; k++)
				{
					if (strstr(pin->net->name, p->pins[k]))
					{
						add = TRUE;
						break;
					}
				}
				if (add) break;
			}
		}

		// Search the node name for each user defined item.
		if (!add && node->name && strlen(node->name) && strchr(node->name, '^'))
		{
			for (k = 0; k < p->count; k++)
			{
				if (strstr(node->name, p->pins[k]))
				{
					add = TRUE;
					break;
				}
			}
		}

		if (add)
		{
			int single_pin = strchr(p->pins[k], '~')?1:0;

			if (strchr(node->name, '^'))
			{
				char *port_name;
				if (single_pin)
					port_name = get_pin_name(node->name);
				else
					port_name = get_port_name(node->name);

				if (find_portname_in_lines(port_name, l) == -1)
				{
					line_t *line = create_line(port_name);
					l->lines = realloc(l->lines, sizeof(line_t *)*((l->count)+1));
					l->lines[l->count++] = line;
				}
				assign_node_to_line(node, l, OUTPUT, single_pin);
				free(port_name);
			}
		}
	}
}

/*
 * Parses the given (memory) node name into a corresponding
 * mif file name.
 */
char *get_mif_filename(nnode_t *node)
{
	char buffer[BUFFER_MAX_SIZE];
	buffer[0] = 0;
	strcat(buffer, node->name);

	char *filename = strrchr(buffer, '+');
	if (filename) filename += 1;
	else          filename = buffer;

	strcat(filename, ".mif");

	filename = strdup(filename);
	return filename;
}

/*
 * Trims characters in the given "chars" string
 * from the end of the given string.
 */
void trim_string(char* string, char *chars)
{
	int length;
	while((length = strlen(string)))
	{	int trimmed = FALSE;
		int i;
		for (i = 0; i < strlen(chars); i++)
		{
			if (string[length-1] == chars[i])
			{
				trimmed = TRUE;
				string[length-1] = '\0';
				break;
			}
		}

		if (!trimmed)
			break;
	}
}

/*
 * Returns TRUE if the given line has a pin for
 * the given cycle whose value is -1.
 */
int line_has_unknown_pin(line_t *line, int cycle)
{
	int unknown = FALSE;
	int j;
	for (j = line->number_of_pins - 1; j >= 0; j--)
	{
		if (get_line_pin_value(line, j, cycle) < 0)
		{
			unknown = TRUE;
			break;
		}
	}
	return unknown;
}

/*
 * Gets the value of the pin given pin within the given line
 * for the given cycle.
 */
signed char get_line_pin_value(line_t *line, int pin_num, int cycle)
{
	return get_pin_value(line->pins[pin_num],cycle);
}

/*
 * Returns a value from a test_vectors struct in hex. Works
 * for the values arrays in pins as well.
 */
char *vector_value_to_hex(signed char *value, int length)
{
	char *tmp;
	char *string = calloc((length + 1),sizeof(char));
	int j;
	for (j = 0; j < length; j++)
		string[j] = value[j] + '0';

	reverse_string(string,strlen(string));

	char *hex_string = malloc(sizeof(char) * ((length/4 + 1) + 1));

	sprintf(hex_string, "%X ", (unsigned int)strtol(string, &tmp, 2));

	free(string);

	return hex_string;
}

/*
 * Counts the number of vectors in the given file. 
 */
int count_test_vectors(FILE *in)
{
	rewind(in);

	int count = 0;
	char buffer[BUFFER_MAX_SIZE];
	while (get_next_vector(in, buffer))
		count++;

	if (count) // Don't count the headers.
		count--;

	rewind(in);

	return count;
}

/*
 * A given line is a vector if it contains one or more
 * non-whitespace characters and does not being with a #.
 */
int is_vector(char *buffer)
{
	char *line = strdup(buffer);
	trim_string(line," \t\r\n");

	if (line[0] != '#' && strlen(line))
	{
		free(line);
		return TRUE;
	}
	else
	{
		free(line);
		return FALSE;
	}
}

/*
 * Gets the next line from the given file that
 * passes the is_vector() test and places it in
 * the buffer. Returns TRUE if a vector was found,
 * and FALSE if no vector was found.
 */
int get_next_vector(FILE *file, char *buffer)
{
	while (fgets(buffer, BUFFER_MAX_SIZE, file))
		if (is_vector(buffer))
			return TRUE;
	
	return FALSE;
}

/*
 * Free each element in lines[] and the array itself
 */
void free_lines(lines_t *l)
{
	int i;
	for (i = 0; i < l->count; i++)
	{
		free(l->lines[i]->name);
		free(l->lines[i]->pins);
		free(l->lines[i]);
	}

	free(l->lines);
	free(l);
}

/*
 * Free stages.
 */
void free_stages(stages *s)
{
	while (s->count--)
		free(s->stages[s->count]);
	free(s->stages);
	free(s->counts);
	free(s);
}

/*
 * Free the given test_vector.
 */
void free_test_vector(test_vector* v)
{
	while (v->count--)
			free(v->values[v->count]);
	free(v->values);
	free(v->counts);
	free(v);
}

/*
 * Frees pin_names struct.
 */
void free_pin_name_list(pin_names *p)
{
	while (p->count--)
		free(p->pins[p->count]);

	free(p->pins);
	free(p);
}

/*
 * Prints/updates an ASCII progress bar of length "length" to position length * completion
 * from previous position "position". Updates ETA based on the elapsed time "time".
 * Returns the new position. If the position is unchanged the bar is not redrawn.
 *
 * Call with position = -1 to draw for the first time. Returns the new
 * position, calculated based on completion.
 */
int print_progress_bar(double completion, int position, int length, double time)
{
	if (position == -1 || ((int)(completion * length)) > position)
	{
		printf("%3.0f%%|", completion * (double)100);

		position = completion * length;

		int i;
		for (i = 0; i < position; i++)
			printf("=");

		printf(">");

		for (; i < length; i++)
			printf("-");

		if (completion < 1.0)
		{
			printf("| Remaining: ");
			double remaining_time = time/(double)completion - time;
			print_time(remaining_time);
		}
		else
		{
			printf("| Total time: ");
			print_time(time);
		}

		printf("    \r");

		if (position == length)
			printf("\n");

		fflush(stdout);
	}
	return position;
}

/*
 * Prints information about the netlist we are simulating.
 */
void print_netlist_stats(stages *stages, int num_vectors)
{
	printf("%s:\n", get_circuit_filename());

	printf("  Nodes:           %d\n",    stages->num_nodes);
	printf("  Connections:     %d\n",    stages->num_connections);
	printf("  Degree:          %3.2f\n", stages->num_connections/(float)stages->num_nodes);
	printf("  Stages:          %d\n",    stages->count);
	#ifdef _OPENMP
	printf("  Parallel nodes:  %d (%4.1f%%)\n", stages->num_parallel_nodes, (stages->num_parallel_nodes/(double)stages->num_nodes) * 100);
	#endif
	printf("\n");

}

/*
 * Prints statistics. (Coverage and times.)
 */
void print_simulation_stats(stages *stages, int num_vectors, double total_time, double simulation_time)
{
	int covered_nodes = get_num_covered_nodes(stages);
	printf("Simulation time:   ");
	print_time(simulation_time);
	printf("\n");
	printf("Elapsed time:      ");
	print_time(total_time);
	printf("\n");
	printf("Coverage:          "
			"%d (%4.1f%%)\n", covered_nodes, (covered_nodes/(double)stages->num_nodes) * 100);
}

/*
 * Prints the time in appropriate units.
 */
void print_time(double time)
{
	if      (time > 24*3600) printf("%.1fd",  time/(24*3600.0));
	else if (time > 3600)    printf("%.1fh",  time/3600.0);
	else if (time > 60)      printf("%.1fm",  time/60.0);
	else if (time > 1)       printf("%.1fs",  time);
	else                     printf("%.1fms", time*1000);
}

/*
 * Prints n ancestors of the given node, complete
 * with their parents, ids, etc.
 */
void print_ancestry(nnode_t *bottom_node, int n)
{
	if (!n) n = 10;

	queue_t *queue = create_queue();
	queue->add(queue, bottom_node);
	nnode_t *node;
	printf(  "  ------------\n");
	printf(  "  BACKTRACE\n");
	printf(  "  ------------\n");

	while (n-- && (node = queue->remove(queue)))
	{
		char *name = get_pin_name(node->name);
		printf("  %s (%ld):\n", name, node->unique_id);
		free(name);
		int i;
		for (i = 0; i < node->num_input_pins; i++)
		{
			npin_t *pin = node->input_pins[i];
			nnet_t *net = pin->net;
			nnode_t *node = net->driver_pin->node;
			queue->add(queue, node);
			char *name = get_pin_name(node->name);
			printf("\t%s %s (%ld)\n", pin->mapping, name, node->unique_id);fflush(stdout);
			free(name);
		}

		/*int count = 0;
		{
			printf(  "  ------------\n");
			printf(  "  CHILDREN    \n");
			printf(  "  ------------\n");
			printf(  "  O: %d\n", node->num_output_pins);fflush(stdout);
			for (i = 0; i < node->num_output_pins; i++)
			{
				npin_t *pin = node->output_pins[i];
				if (pin)
				{
					nnet_t *net = pin->net;
					if (net)
					{
						int j;
						for (j = 0; j < net->num_fanout_pins; j++)
						{
							npin_t  *pin  = net->fanout_pins[j];
							if (pin)
							{
								nnode_t *node = pin->node;
								if (node)
								{
									char *name = get_pin_name(node->name);
									printf("\t%s %s (%ld)\n", pin->mapping, name, node->unique_id);fflush(stdout);
									free(name);
								}
								else
								{
									printf("  Null node %d\n", ++count);fflush(stdout);
								}
							}
							else
							{
								printf("  Null fanout pin\n");fflush(stdout);
							}
						}
					}
					else
					{
						printf("  Null net\n");fflush(stdout);
					}
				}
			}
		}*/
		printf(  "  ------------\n");

	}
	queue->destroy(queue);

	printf(  "  END OF TRACE\n");
	printf(  "  ------------\n");
}

/*
 * Traces an node which is failing to update back to parent of
 * the earliest node in the net list with an unupdated pin.
 * (Pin whose cycle is less than cycle-1). Prints all nodes
 * traversed during the trace with the original node printed
 * first, and the root of the issue printed last.
 *
 * Returns the root node for inspection.
 */
nnode_t *print_update_trace(nnode_t *bottom_node, int cycle)
{
	// Limit the length of the trace. 0 for unlimited.
	const int max_depth = 0;
	printf(
			"  --------------------------------------------------------------------------\n"
			"  --------------------------------------------------------------------------\n"
			"  BACKTRACE:\n"
			"\tFormat: Each node is listed followed by its parents. The parent \n"
			"\twhich is not updating is indicated with an astrisk. (*)\n"
			"\tEach node is listed in the form:\n"
			"\t\t(<mapping>) <Name> (<Unique ID>) <# of Parents> <# of Children> \n"
			"  --------------------------------------------------------------------------\n"
	);

	nnode_t *root_node = NULL;

	// Used to detect cycles. Based table size of max depth. If unlimited, set to something big.
	hashtable_t *index = create_hashtable(max_depth?(max_depth * 2):100000);

	queue_t *queue = create_queue();
	queue->add(queue, bottom_node);
	nnode_t *node;
	int depth = 0;
	// Traverse the netlist in reverse, starting with our current location.
	while ((node = queue->remove(queue)))
	{
		int found_undriven_pin = FALSE;
		int is_duplicate = index->get(index, &node->unique_id, sizeof(long))?1:0;
		if (!is_duplicate)
		{
			depth++;
			index->add(index, &node->unique_id, sizeof(long), (void *)1);
			char *name = get_pin_name(node->name);
			printf("  %s (%ld) %d %d\n", name, node->unique_id, node->num_input_pins, node->num_output_pins);
			free(name);

			int i;
			for (i = 0; i < node->num_input_pins; i++)
			{
				npin_t *pin = node->input_pins[i];
				nnet_t *net = pin->net;
				nnode_t *node = net->driver_pin->node;

				// If an input is found which hasn't been updated since before cycle-1, traverse it.
				int is_undriven = FALSE;
				if (get_pin_cycle(pin) < cycle-1)
				{
					// Only add each node for traversal once.
					if (!found_undriven_pin)
					{
						found_undriven_pin = TRUE;
						queue->add(queue, node);
					}
					is_undriven = TRUE;
				}
				char *name = get_pin_name(node->name);
				printf("\t(%s) %s (%ld) %d %d %s \n", pin->mapping, name, node->unique_id, node->num_input_pins, node->num_output_pins, is_undriven?"*":"");
				free(name);
			}
			printf("  ------------\n");
		}
		else {
			printf("  CYCLE DETECTED AFTER %d NODES.\n", depth);
			printf("  ------------\n");
			break;
		}

		if (!found_undriven_pin)
		{
			printf("  TOP OF TRACE\n");
			printf("  ------------\n");
			root_node = node;
			break;
		}
		else if (max_depth && depth >=max_depth)
		{
			printf("  TRACE TRUNCATED AT %d NODES.\n", max_depth);
			printf("  ------------\n");
			break;
		}
	}
	index->destroy(index);
	queue->destroy(queue);
	return root_node;
}

/*
 * Gets the current time in seconds.
 */
inline double wall_time()
{
	struct timeval tv;
	gettimeofday(&tv, 0);
	return (1000000*tv.tv_sec+tv.tv_usec)/1.0e6;
}

/*
 * Gets the name of the file we are simulating as passed by the -b or -V option.
 */
char *get_circuit_filename()
{
	return global_args.verilog_file?global_args.verilog_file:global_args.blif_file;
}
