<commit_before>/***********************************************************************************************************************
 * Copyright (C) 2016 <NAME> and contributors                                                                *
 *                                                                                                                     *
 * This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General   *
 * Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) *
 * any later version.                                                                                                  *
 *                                                                                                                     *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied  *
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for     *
 * more details.                                                                                                       *
 *                                                                                                                     *
 * You should have received a copy of the GNU Lesser General Public License along with this program; if not, you may   *
 * find one here:                                                                                                      *
 * https://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt                                                              *
 * or you may search the http://www.gnu.org website for the version 2.1 license, or you may write to the Free Software *
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA                                      *
 **********************************************************************************************************************/
 
#include "gp4par.h"
#include <math.h>

using namespace std;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Construction / destruction

Greenpak4PAREngine::Greenpak4PAREngine(PARGraph* netlist, PARGraph* device, labelmap& lmap)
	: PAREngine(netlist, device)
	, m_lmap(lmap)
{
	
}

Greenpak4PAREngine::~Greenpak4PAREngine()
{
	
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Initial placement

void Greenpak4PAREngine::InitialPlacement_core()
{
	//Make a map of all nodes to their names
	map<string, Greenpak4BitstreamEntity*> nmap;
	for(size_t i=0; i<m_device->GetNumNodes(); i++)
	{
		auto entity = static_cast<Greenpak4BitstreamEntity*>(m_device->GetNodeByIndex(i)->GetData());
		nmap[entity->GetDescription()] = entity;
	}
	
	//Go over the netlist nodes, see if any have LOC constraints.
	//If so, place those at the constrained locations
	for(size_t i=0; i<m_netlist->GetNumNodes(); i++)
	{
		auto node = m_netlist->GetNodeByIndex(i);
		auto entity = static_cast<Greenpak4NetlistEntity*>(node->GetData());
		auto cell = dynamic_cast<Greenpak4NetlistCell*>(entity);
		if(cell == NULL)
		{
			LogFatal("Cell in netlist is not a Greenpak4NetlistCell\n");
		}
			
		//Search for a LOC constraint, if there is one
		cell->FindLOC();
		if(!cell->HasLOC())
			continue;
		string loc = cell->GetLOC();
			
		//Verify that the constrained location exists
		if(nmap.find(loc) == nmap.end())
		{
			LogError("Cell %s has invalid LOC constraint %s (no matching site in device)\n",
				cell->m_name.c_str(), loc.c_str());
			cell->ClearLOC();
			exit(-1);
		}
		
		//If it exists, is it a legal site?
		auto site = nmap[loc];
		auto spnode = site->GetPARNode();
		if(!spnode->MatchesLabel(node->GetLabel()))
		{
			LogError(
				"Cell %s has invalid LOC constraint %s (site is of type %s, instance is of type %s)\n",
				cell->m_name.c_str(),
				loc.c_str(),
				m_lmap[site->GetPARNode()->GetLabel()].c_str(),
				m_lmap[node->GetLabel()].c_str()
				);
			exit(-1);
		}
		
		//The site exists, is valid, and we're constrained to it.
		//Verify that there's not already something constrained to that site
		if(spnode->GetMate() != NULL)
		{
			LogError(
				"Cell %s has invalid LOC constraint %s (another instance is already constrained there)\n",
				cell->m_name.c_str(), loc.c_str());
			cell->ClearLOC();
			exit(-1);
		}
		
		//Everything is good, apply the constraint
		LogVerbose("    Applying LOC constraint %s to cell %s\n", loc.c_str(), cell->m_name.c_str());
		node->MateWith(spnode);
	}
	
	//For each label, mate each node in the netlist with the first legal mate in the device.
	//Simple and deterministic.
	uint32_t nmax_net = m_netlist->GetMaxLabel();
	for(uint32_t label = 0; label <= nmax_net; label ++)
	{
		uint32_t nnet = m_netlist->GetNumNodesWithLabel(label);
		uint32_t nsites = m_device->GetNumNodesWithLabel(label);
		
		uint32_t nsite = 0;
		for(uint32_t net = 0; net<nnet; net++)
		{
			PARGraphNode* netnode = m_netlist->GetNodeByLabelAndIndex(label, net);
			
			//If the netlist node is already constrained, don't auto-place it
			if(netnode->GetMate() != NULL)
				continue;
			
			//Try to find a legal site
			bool found = false;
			while(nsite < nsites)
			{
				PARGraphNode* devnode = m_device->GetNodeByLabelAndIndex(label, nsite);
				nsite ++;
				
				//If the site is used, we don't want to disturb what's already there
				//because it was probably LOC'd
				if(devnode->GetMate() != NULL)				
					continue;
				
				//Site is unused, mate with it
				netnode->MateWith(devnode);
				found = true;
				break;
			}
			
			//This can happen in rare cases
			//(for example, we constrained all of the 8-bit counters to COUNT14 sites and now have a COUNT14).
			if(!found)
			{
				auto cell = static_cast<Greenpak4NetlistEntity*>(netnode->GetData());
				
				LogError(
					"Could not place netlist cell \"%s\" because we ran out of sites with type \"%s\"\n"
					"       This can happen if you have overly restrictive LOC constraints.",
					cell->m_name.c_str(),
					m_lmap[label].c_str()
					);
				exit(1);
			}
		}<commit_msg>Fix a missing newline.<commit_after>/***********************************************************************************************************************
 * Copyright (C) 2016 <NAME> and contributors                                                                *
 *                                                                                                                     *
 * This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General   *
 * Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) *
 * any later version.                                                                                                  *
 *                                                                                                                     *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied  *
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for     *
 * more details.                                                                                                       *
 *                                                                                                                     *
 * You should have received a copy of the GNU Lesser General Public License along with this program; if not, you may   *
 * find one here:                                                                                                      *
 * https://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt                                                              *
 * or you may search the http://www.gnu.org website for the version 2.1 license, or you may write to the Free Software *
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA                                      *
 **********************************************************************************************************************/
 
#include "gp4par.h"
#include <math.h>

using namespace std;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Construction / destruction

Greenpak4PAREngine::Greenpak4PAREngine(PARGraph* netlist, PARGraph* device, labelmap& lmap)
	: PAREngine(netlist, device)
	, m_lmap(lmap)
{
	
}

Greenpak4PAREngine::~Greenpak4PAREngine()
{
	
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Initial placement

void Greenpak4PAREngine::InitialPlacement_core()
{
	//Make a map of all nodes to their names
	map<string, Greenpak4BitstreamEntity*> nmap;
	for(size_t i=0; i<m_device->GetNumNodes(); i++)
	{
		auto entity = static_cast<Greenpak4BitstreamEntity*>(m_device->GetNodeByIndex(i)->GetData());
		nmap[entity->GetDescription()] = entity;
	}
	
	//Go over the netlist nodes, see if any have LOC constraints.
	//If so, place those at the constrained locations
	for(size_t i=0; i<m_netlist->GetNumNodes(); i++)
	{
		auto node = m_netlist->GetNodeByIndex(i);
		auto entity = static_cast<Greenpak4NetlistEntity*>(node->GetData());
		auto cell = dynamic_cast<Greenpak4NetlistCell*>(entity);
		if(cell == NULL)
		{
			LogFatal("Cell in netlist is not a Greenpak4NetlistCell\n");
		}
			
		//Search for a LOC constraint, if there is one
		cell->FindLOC();
		if(!cell->HasLOC())
			continue;
		string loc = cell->GetLOC();
			
		//Verify that the constrained location exists
		if(nmap.find(loc) == nmap.end())
		{
			LogError("Cell %s has invalid LOC constraint %s (no matching site in device)\n",
				cell->m_name.c_str(), loc.c_str());
			cell->ClearLOC();
			exit(-1);
		}
		
		//If it exists, is it a legal site?
		auto site = nmap[loc];
		auto spnode = site->GetPARNode();
		if(!spnode->MatchesLabel(node->GetLabel()))
		{
			LogError(
				"Cell %s has invalid LOC constraint %s (site is of type %s, instance is of type %s)\n",
				cell->m_name.c_str(),
				loc.c_str(),
				m_lmap[site->GetPARNode()->GetLabel()].c_str(),
				m_lmap[node->GetLabel()].c_str()
				);
			exit(-1);
		}
		
		//The site exists, is valid, and we're constrained to it.
		//Verify that there's not already something constrained to that site
		if(spnode->GetMate() != NULL)
		{
			LogError(
				"Cell %s has invalid LOC constraint %s (another instance is already constrained there)\n",
				cell->m_name.c_str(), loc.c_str());
			cell->ClearLOC();
			exit(-1);
		}
		
		//Everything is good, apply the constraint
		LogVerbose("    Applying LOC constraint %s to cell %s\n", loc.c_str(), cell->m_name.c_str());
		node->MateWith(spnode);
	}
	
	//For each label, mate each node in the netlist with the first legal mate in the device.
	//Simple and deterministic.
	uint32_t nmax_net = m_netlist->GetMaxLabel();
	for(uint32_t label = 0; label <= nmax_net; label ++)
	{
		uint32_t nnet = m_netlist->GetNumNodesWithLabel(label);
		uint32_t nsites = m_device->GetNumNodesWithLabel(label);
		
		uint32_t nsite = 0;
		for(uint32_t net = 0; net<nnet; net++)
		{
			PARGraphNode* netnode = m_netlist->GetNodeByLabelAndIndex(label, net);
			
			//If the netlist node is already constrained, don't auto-place it
			if(netnode->GetMate() != NULL)
				continue;
			
			//Try to find a legal site
			bool found = false;
			while(nsite < nsites)
			{
				PARGraphNode* devnode = m_device->GetNodeByLabelAndIndex(label, nsite);
				nsite ++;
				
				//If the site is used, we don't want to disturb what's already there
				//because it was probably LOC'd
				if(devnode->GetMate() != NULL)				
					continue;
				
				//Site is unused, mate with it
				netnode->MateWith(devnode);
				found = true;
				break;
			}
			
			//This can happen in rare cases
			//(for example, we constrained all of the 8-bit counters to COUNT14 sites and now have a COUNT14).
			if(!found)
			{
				auto cell = static_cast<Greenpak4NetlistEntity*>(netnode->GetData());
				
				LogError(
					"Could not place netlist cell \"%s\" because we ran out of sites with type \"%s\"\n"
					"       This can happen if you have overly restrictive LOC constraints.\n",
					cell->m_name.c_str(),
					m_lmap[label].c_str()
					);
				exit(1);
			}
		}
{'fraction_non_alphanumeric': 0.17427913257605845, 'fraction_numerical': 0.009373262371911986, 'mean_word_length': 1.8796889295516925, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 85, 'https://': 2, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 64, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3608643', 'n_tokens_mistral': 3885, 'n_tokens_neox': 3297, 'n_words': 1055}