/*
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 "odin_types.h"
#include "odin_globals.h"
#include "memories.h"
#include "hard_blocks.h"
#include "implicit_memory.h"
#include "node_creation_library.h"
#include "netlist_utils.h"
#include "odin_util.h"
#include "vtr_util.h"
#include "vtr_memory.h"

#include <unordered_map>

// Hashes the implicit memory name to the implicit_memory structure.
std::unordered_map<std::string,implicit_memory *> implicit_memories;
// Hashes the implicit memory input name to the implicit_memory structure.
std::unordered_map<std::string,implicit_memory *>  implicit_memory_inputs;

void finalize_implicit_memory(implicit_memory *memory);
void add_dummy_output_port_to_implicit_memory(implicit_memory *memory, int size, const char *port_name);
void add_dummy_input_port_to_implicit_memory(implicit_memory *memory, int size, const char *port_name);
void collapse_implicit_memory_to_single_port_ram(implicit_memory *memory);
implicit_memory *lookup_implicit_memory(char *instance_name_prefix, char *identifier);

/*
 * Initialises hashtables to lookup memories based on inputs and names.
 */
void init_implicit_memory_index()
{
	implicit_memories = std::unordered_map<std::string,implicit_memory *>();
	implicit_memory_inputs = std::unordered_map<std::string,implicit_memory *>();
}

/*
 * Looks up an implicit memory by identifier name in the implicit memory lookup table.
 */
implicit_memory *lookup_implicit_memory(char *instance_name_prefix, char *identifier)
{
	char *memory_string = make_full_ref_name(instance_name_prefix, NULL, NULL, identifier, -1);

	std::unordered_map<std::string,implicit_memory *>::const_iterator mem_out = implicit_memories.find(std::string(memory_string));

	vtr::free(memory_string);

	if ( mem_out == implicit_memories.end() )
		return NULL;
	else
		return mem_out->second;
}

/*
 * Looks up an implicit memory by ast reference in the implicit memory lookup table.
 */
implicit_memory *lookup_implicit_memory_reference_ast(char *instance_name_prefix, ast_node_t *node)
{
	if (node && node->num_children == 2 && node->type == ARRAY_REF)
		return lookup_implicit_memory(instance_name_prefix, node->children[0]->types.identifier);
	else if (node && node->num_children == 3 && node->type == ARRAY_REF)
		return lookup_implicit_memory(instance_name_prefix, node->children[0]->types.identifier);
	else if (node && node->type == IDENTIFIERS)
		return lookup_implicit_memory(instance_name_prefix, node->types.identifier);
	else
		return NULL;
}

/*
 * Determines if the given implicit memory reference mode is supported.
 */
char is_valid_implicit_memory_reference_ast(char *instance_name_prefix, ast_node_t *node)
{
	if (node && node->num_children == 2 && node->type == ARRAY_REF
			&& lookup_implicit_memory_reference_ast(instance_name_prefix, node))
		return true;
	else if (node && node->num_children == 3 && node->type == ARRAY_REF
			&& lookup_implicit_memory_reference_ast(instance_name_prefix, node))
		return true;
	else
		return false;
}

/*
 * Creates an implicit memory block with the given depth and data width, and the given name and prefix.
 */
implicit_memory *create_implicit_memory_block(int data_width, long memory_depth, char *name, char *instance_name_prefix)
{
	char implicit_string[] = "implicit_ram";

	oassert(memory_depth > 0
		&& "implicit memory depth must be greater than 0");

	//find closest power of 2 from memory depth.
	long addr_width = 0;
	long real_memory_depth = 1;
	while (real_memory_depth < memory_depth)
	{
		addr_width += 1;
		real_memory_depth = shift_left_value_with_overflow_check(real_memory_depth, 0x1);
	}

	//verify if it is a power of two (only one bit set)
	if((memory_depth != real_memory_depth))
	{
		warning_message(NETLIST_ERROR, -1, -1, "Rounding memory <%s> of size <%ld> to closest power of two: %ld.", name, memory_depth, real_memory_depth);
		memory_depth = real_memory_depth;
	}

	nnode_t *node = allocate_nnode();
	node->type = MEMORY;
	node->name = hard_node_name(node, instance_name_prefix, implicit_string, name);

	// Create a fake ast node.
	node->related_ast_node = (ast_node_t *)vtr::calloc(1, sizeof(ast_node_t));
	node->related_ast_node->children = (ast_node_t **)vtr::calloc(1,sizeof(ast_node_t *));
	node->related_ast_node->children[0] = (ast_node_t *)vtr::calloc(1, sizeof(ast_node_t));
	node->related_ast_node->children[0]->types.identifier = vtr::strdup(DUAL_PORT_RAM_string);

	char *full_name = make_full_ref_name(instance_name_prefix, NULL, NULL, name, -1);

	implicit_memory *memory = (implicit_memory *)vtr::malloc(sizeof(implicit_memory));
	memory->node = node;
	memory->addr_width = addr_width;
	memory->memory_depth = memory_depth;
	memory->data_width = data_width;
	memory->clock_added = false;
	memory->output_added = false;
	memory->name = full_name;

	implicit_memories.insert({std::string(full_name), memory});

	return memory;
}

/*
 * Adds an input port to the given implicit memory.
 */
void add_input_port_to_implicit_memory(implicit_memory *memory, signal_list_t *signals, const char *port_name)
{
	nnode_t *node = memory->node;

	add_input_port_to_memory(node, signals, port_name);
}

/*
 * Add an output port to the given implicit memory.
 */
void add_output_port_to_implicit_memory(implicit_memory *memory, signal_list_t *signals, const char *port_name)
{
	nnode_t *node = memory->node;

	add_output_port_to_memory(node, signals, port_name);
}

/*
 * Looks up an implicit memory based on the given name.
 */
implicit_memory *lookup_implicit_memory_input(char *name)
{

	std::unordered_map<std::string,implicit_memory *>::const_iterator mem_out = implicit_memory_inputs.find(std::string(name));

	if ( mem_out == implicit_memory_inputs.end() )
		return NULL;
	else
		return mem_out->second;

}

/*
 * Registers the given input name so that the given memory can be looked up based on
 * it.
 */
void register_implicit_memory_input(char *name, implicit_memory *memory)
{
	if (!lookup_implicit_memory_input(name))
		implicit_memory_inputs.insert({std::string(name), memory});
	else
		error_message(NETLIST_ERROR, -1, -1, "Attempted to re-register implicit memory output %s.", name);
}

/*
 * Frees memory used for indexing implicit memories. Finalises each
 * memory, making sure it has the right ports, and collapsing
 * the memory if possible.
 */
void free_implicit_memory_index_and_finalize_memories()
{

	implicit_memory_inputs.clear();

	if (!implicit_memories.empty())
	{
		for (auto mem_it : implicit_memories) 
		{
			finalize_implicit_memory(mem_it.second);
			vtr::free(mem_it.second->name);
			vtr::free(mem_it.second);
		}
	}
	implicit_memories.clear();
}

/*
 * Adds a zeroed input port with to the given implicit memory
 * with the given size and port name (mapping)
 */
void add_dummy_input_port_to_implicit_memory(implicit_memory *memory, int size, const char *port_name)
{
	signal_list_t *signals = init_signal_list();
	int i;
	for (i = 0; i < size; i++)
		add_pin_to_signal_list(signals, get_zero_pin(verilog_netlist));

	add_input_port_to_implicit_memory(memory, signals, port_name);

	free_signal_list(signals);
}

/*
 * Adds an unconnected output port with to the given implicit memory
 * with the given size and port name (mapping)
 */
void add_dummy_output_port_to_implicit_memory(implicit_memory *memory, int size, const char *port_name)
{
	signal_list_t *signals = init_signal_list();
	static int dummy_output_pin_number = 0;
	int i;
	for (i = 0; i < size; i++)
	{
		npin_t *dummy_pin = allocate_npin();
		// Pad outputs with a unique and descriptive name to avoid collisions.
		dummy_pin->name = append_string("", "dummy_implicit_memory_output~%d", dummy_output_pin_number++);
		add_pin_to_signal_list(signals, dummy_pin);
	}

	add_output_port_to_implicit_memory(memory, signals, port_name);

	free_signal_list(signals);
}

/*
 * Makes sure the given implicit memory has all necessary ports,
 * and adds any ports which may be missing. Collapses the memory to
 * a single port ram if one port is unused.
 */
void finalize_implicit_memory(implicit_memory *memory)
{
	nnode_t *node = memory->node;

	bool has_addr1 = false;
	bool has_addr2 = false;
	bool has_data1 = false;
	bool has_data2 = false;
	bool has_we1   = false;
	bool has_we2   = false;
	bool has_clk   = false;
	bool has_out1  = false;
	bool has_out2  = false;

	// Determine which input ports are present.
	int i;
	for (i = 0; i < node->num_input_pins; i++)
	{
		npin_t *pin = node->input_pins[i];
		if (!strcmp(pin->mapping, "addr1"))
			has_addr1 = true;
		else if (!strcmp(pin->mapping, "addr2"))
			has_addr2 = true;
		else if (!strcmp(pin->mapping, "data1"))
			has_data1 = true;
		else if (!strcmp(pin->mapping, "data2"))
			has_data2 = true;
		else if (!strcmp(pin->mapping, "we1"))
			has_we1 = true;
		else if (!strcmp(pin->mapping, "we2"))
			has_we2 = true;
		else if (!strcmp(pin->mapping, "clk"))
			has_clk = true;
	}

	// Determine which output ports are present.
	for (i = 0; i < node->num_output_pins; i++)
	{
		npin_t *pin = node->output_pins[i];
		if (!strcmp(pin->mapping, "out1"))
			has_out1 = true;
		else if (!strcmp(pin->mapping, "out2"))
			has_out2 = true;
	}

	if (!has_clk)
	{
		add_dummy_input_port_to_implicit_memory(memory, 1, "clk");
		warning_message(NETLIST_ERROR, -1, -1, "Implicit memory %s is not clocked. Padding clock pin.", memory->name);
	}

	char has_port1 = has_addr1 || has_data1 || has_we1 || has_out1;
	char has_port2 = has_addr2 || has_data2 || has_we2 || has_out2;

	if (has_port1)
	{
		if (!has_addr1) add_dummy_input_port_to_implicit_memory(memory, memory->addr_width, "addr1");
		if (!has_data1) add_dummy_input_port_to_implicit_memory(memory, memory->data_width, "data1");
		if (!has_we1)   add_dummy_input_port_to_implicit_memory(memory, 1, "we1");
		if (!has_out1)  add_dummy_output_port_to_implicit_memory(memory, memory->data_width, "out1");
	}

	if (has_port2)
	{
		if (!has_addr2) add_dummy_input_port_to_implicit_memory (memory, memory->addr_width, "addr2");
		if (!has_data2) add_dummy_input_port_to_implicit_memory (memory, memory->data_width, "data2");
		if (!has_we2)   add_dummy_input_port_to_implicit_memory (memory, 1, "we2");
		if (!has_out2)  add_dummy_output_port_to_implicit_memory(memory, memory->data_width, "out2");
	}

	if (!has_port1 || !has_port2)
		collapse_implicit_memory_to_single_port_ram(memory);

	if (!has_port1 && !has_port2)
	{
		warning_message(NETLIST_ERROR, -1, -1, "Implicit memory %s has no ports...", memory->name);
	}
	else
	{
		/*
		*  If this hard block is supported, register it globally and mark
		*  it as used. (For splitting and BLIF output.)
		*
		*  If it isn't supported, it will be automagically blown out
		*  into soft logic during the partial map.
		*/
		ast_node_t *ast_node = node->related_ast_node;
		char *hard_block_identifier = ast_node->children[0]->types.identifier;
		t_model *hb_model = find_hard_block(hard_block_identifier);
		if (hb_model)
		{
			hb_model->used = 1;
			if (!strcmp(hard_block_identifier, SINGLE_PORT_RAM_string))
				sp_memory_list = insert_in_vptr_list(sp_memory_list, node);
			else
				dp_memory_list = insert_in_vptr_list(dp_memory_list, node);
		}
	}
}

/*
 * Turns the given implicit memory into a single port ram from the
 * default dual port ram. This is a useful optimisation when one port is unused.
 *
 * All implicit memories are constructed initially as
 * dual port rams.
 */
void collapse_implicit_memory_to_single_port_ram(implicit_memory *memory)
{
	nnode_t *node = memory->node;

	// Change the inputs to single port ram mappings by removing
	// the port numbers (1 or 2) from the mappings. (last char)
	int i;
	for (i = 0; i < node->num_input_pins; i++)
	{
		npin_t *pin = node->input_pins[i];
		if (strcmp(pin->mapping, "clk"))
			pin->mapping[strlen(pin->mapping)-1] = 0;
	}

	// Change the outputs to single port ram mappings by removing
	// the port numbers. (last char)
	for (i = 0; i < node->num_output_pins; i++)
	{
		npin_t *pin = node->output_pins[i];
		pin->mapping[strlen(pin->mapping)-1] = 0;
	}

	ast_node_t *ast_node = node->related_ast_node;
	vtr::free(ast_node->children[0]->types.identifier);
	ast_node->children[0]->types.identifier = vtr::strdup(SINGLE_PORT_RAM_string);
}
