<commit_before>/*
 *  yosys -- Yosys Open SYnthesis Suite
 *
 *  Copyright (C) 2012  <NAME> <<EMAIL>>
 *  
 *  Permission to use, copy, modify, and/or distribute this software for any
 *  purpose with or without fee is hereby granted, provided that the above
 *  copyright notice and this permission notice appear in all copies.
 *  
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

// [[CITE]] Berkeley Logic Interchange Format (BLIF)
// University of California. Berkeley. July 28, 1992
// http://www.ece.cmu.edu/~ee760/760docs/blif.pdf

#include "kernel/rtlil.h"
#include "kernel/register.h"
#include "kernel/sigtools.h"
#include "kernel/celltypes.h"
#include "kernel/log.h"
#include <string>
#include <assert.h>

struct BlifDumperConfig
{
	bool icells_mode;
	bool conn_mode;
	bool impltf_mode;
	bool gates_mode;
	bool param_mode;

	std::string buf_type, buf_in, buf_out;
	std::string true_type, true_out, false_type, false_out;

	BlifDumperConfig() : icells_mode(false), conn_mode(false), impltf_mode(false), gates_mode(false), param_mode(false) { }
};

struct BlifDumper
{
	FILE *f;
	RTLIL::Module *module;
	RTLIL::Design *design;
	BlifDumperConfig *config;
	CellTypes ct;

	BlifDumper(FILE *f, RTLIL::Module *module, RTLIL::Design *design, BlifDumperConfig *config) :
			f(f), module(module), design(design), config(config), ct(design)
	{
	}

	std::vector<std::string> cstr_buf;

	const char *cstr(RTLIL::IdString id)
	{
		std::string str = RTLIL::unescape_id(id);
		for (size_t i = 0; i < str.size(); i++)
			if (str[i] == '#' || str[i] == '=')
				str[i] = '?';
		cstr_buf.push_back(str);
		return cstr_buf.back().c_str();
	}

	const char *cstr(RTLIL::SigSpec sig)
	{
		sig.optimize();
		log_assert(sig.width == 1);

		if (sig.chunks.at(0).wire == NULL)
			return sig.chunks.at(0).data.bits.at(0) == RTLIL::State::S1 ?  "$true" : "$false";

		std::string str = RTLIL::unescape_id(sig.chunks.at(0).wire->name);
		for (size_t i = 0; i < str.size(); i++)
			if (str[i] == '#' || str[i] == '=')
				str[i] = '?';

		if (sig.chunks.at(0).wire->width != 1)
			str += stringf("[%d]", sig.chunks.at(0).offset);

		cstr_buf.push_back(str);
		return cstr_buf.back().c_str();
	}

	const char *subckt_or_gate(std::string cell_type)
	{
		if (!config->gates_mode)
			return "subckt";
		if (!design->modules.count(RTLIL::escape_id(cell_type)))
			return "gate";
		if (design->modules.at(RTLIL::escape_id(cell_type))->get_bool_attribute("\\blackbox"))
			return "gate";
		return "subckt";
	}

	void dump()
	{
		fprintf(f, "\n");
		fprintf(f, ".model %s\n", cstr(module->name));

		std::map<int, RTLIL::Wire*> inputs, outputs;

		for (auto &wire_it : module->wires) {
			RTLIL::Wire *wire = wire_it.second;
			if (wire->port_input)
				inputs[wire->port_id] = wire;
			if (wire->port_output)
				outputs[wire->port_id] = wire;
		}

		fprintf(f, ".inputs");
		for (auto &it : inputs) {
			RTLIL::Wire *wire = it.second;
			for (int i = 0; i < wire->width; i++)
				fprintf(f, " %s", cstr(RTLIL::SigSpec(wire, 1, i)));
		}
		fprintf(f, "\n");

		fprintf(f, ".outputs");
		for (auto &it : outputs) {
			RTLIL::Wire *wire = it.second;
			for (int i = 0; i < wire->width; i++)
				fprintf(f, " %s", cstr(RTLIL::SigSpec(wire, 1, i)));
		}
		fprintf(f, "\n");

		if (!config->impltf_mode) {
			if (!config->false_type.empty())
				fprintf(f, ".%s %s %s=$false\n", subckt_or_gate(config->false_type),
						config->false_type.c_str(), config->false_out.c_str());
			else
				fprintf(f, ".names $false\n");
			if (!config->true_type.empty())
				fprintf(f, ".%s %s %s=$true\n", subckt_or_gate(config->true_type),
						config->true_type.c_str(), config->true_out.c_str());
			else
				fprintf(f, ".names $true\n1\n");
		}

		for (auto &cell_it : module->cells)
		{
			RTLIL::Cell *cell = cell_it.second;

			if (!config->icells_mode && cell->type == "$_INV_") {
				fprintf(f, ".names %s %s\n0 1\n",
						cstr(cell->connections.at("\\A")), cstr(cell->connections.at("\\Y")));
				continue;
			}

			if (!config->icells_mode && cell->type == "$_AND_") {
				fprintf(f, ".names %s %s %s\n11 1\n",
						cstr(cell->connections.at("\\A")), cstr(cell->connections.at("\\B")), cstr(cell->connections.at("\\Y")));
				continue;
			}

			if (!config->icells_mode && cell->type == "$_OR_") {
				fprintf(f, ".names %s %s %s\n1- 1\n-1 1\n",
						cstr(cell->connections.at("\\A")), cstr(cell->connections.at("\\B")), cstr(cell->connections.at("\\Y")));
				continue;
			}

			if (!config->icells_mode && cell->type == "$_XOR_") {
				fprintf(f, ".names %s %s %s\n10 1\n01 1\n",
						cstr(cell->connections.at("\\A")), cstr(cell->connections.at("\\B")), cstr(cell->connections.at("\\Y")));
				continue;
			}

			if (!config->icells_mode && cell->type == "$_MUX_") {
				fprintf(f, ".names %s %s %s %s\n1-0 1\n-11 1\n",
						cstr(cell->connections.at("\\A")), cstr(cell->connections.at("\\B")),
						cstr(cell->connections.at("\\S")), cstr(cell->connections.at("\\Y")));
				continue;
			}

			if (!config->icells_mode && cell->type == "$_DFF_N_") {
				fprintf(f, ".latch %s %s fe %s\n",
						cstr(cell->connections.at("\\D")), cstr(cell->connections.at("\\Q")), cstr(cell->connections.at("\\C")));
				continue;
			}

			if (!config->icells_mode && cell->type == "$_DFF_P_") {
				fprintf(f, ".latch %s %s re %s\n",
						cstr(cell->connections.at("\\D")), cstr(cell->connections.at("\\Q")), cstr(cell->connections.at("\\C")));
				continue;
			}

			fprintf(f, ".%s %s", subckt_or_gate(cell->type), cstr(cell->type));
			for (auto &conn : cell->connections)
			for (int i = 0; i < conn.second.width; i++) {
				if (conn.second.width == 1)
					fprintf(f, " %s", cstr(conn.first));
				else
					fprintf(f, " %s[%d]", cstr(conn.first), i);
				fprintf(f, "=%s", cstr(conn.second.extract(i, 1)));
			}
			fprintf(f, "\n");

			if (config->param_mode)
				for (auto &param : cell->parameters) {
					fprintf(f, ".param %s ", RTLIL::id2cstr(param.first));
					if (param.second.flags & RTLIL::CONST_FLAG_STRING) {
						std::string str = param.second.decode_string();
						fprintf(f, "\"");
						for (char ch : str)
							if (ch == '"' || ch == '\\')
								fprintf(f, "\\%c", ch);
							else if (ch < 32 || ch >= 127)
								fprintf(f, "\\%03o", ch);
							else
								fprintf(f, "%c", ch);
						fprintf(f, "\"\n");<commit_msg>Added $lut support to blif backend (by user eddiehung from reddit)<commit_after>/*
 *  yosys -- Yosys Open SYnthesis Suite
 *
 *  Copyright (C) 2012  <NAME> <<EMAIL>>
 *  
 *  Permission to use, copy, modify, and/or distribute this software for any
 *  purpose with or without fee is hereby granted, provided that the above
 *  copyright notice and this permission notice appear in all copies.
 *  
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

// [[CITE]] Berkeley Logic Interchange Format (BLIF)
// University of California. Berkeley. July 28, 1992
// http://www.ece.cmu.edu/~ee760/760docs/blif.pdf

#include "kernel/rtlil.h"
#include "kernel/register.h"
#include "kernel/sigtools.h"
#include "kernel/celltypes.h"
#include "kernel/log.h"
#include <string>
#include <assert.h>

struct BlifDumperConfig
{
	bool icells_mode;
	bool conn_mode;
	bool impltf_mode;
	bool gates_mode;
	bool param_mode;

	std::string buf_type, buf_in, buf_out;
	std::string true_type, true_out, false_type, false_out;

	BlifDumperConfig() : icells_mode(false), conn_mode(false), impltf_mode(false), gates_mode(false), param_mode(false) { }
};

struct BlifDumper
{
	FILE *f;
	RTLIL::Module *module;
	RTLIL::Design *design;
	BlifDumperConfig *config;
	CellTypes ct;

	BlifDumper(FILE *f, RTLIL::Module *module, RTLIL::Design *design, BlifDumperConfig *config) :
			f(f), module(module), design(design), config(config), ct(design)
	{
	}

	std::vector<std::string> cstr_buf;

	const char *cstr(RTLIL::IdString id)
	{
		std::string str = RTLIL::unescape_id(id);
		for (size_t i = 0; i < str.size(); i++)
			if (str[i] == '#' || str[i] == '=')
				str[i] = '?';
		cstr_buf.push_back(str);
		return cstr_buf.back().c_str();
	}

	const char *cstr(RTLIL::SigSpec sig)
	{
		sig.optimize();
		log_assert(sig.width == 1);

		if (sig.chunks.at(0).wire == NULL)
			return sig.chunks.at(0).data.bits.at(0) == RTLIL::State::S1 ?  "$true" : "$false";

		std::string str = RTLIL::unescape_id(sig.chunks.at(0).wire->name);
		for (size_t i = 0; i < str.size(); i++)
			if (str[i] == '#' || str[i] == '=')
				str[i] = '?';

		if (sig.chunks.at(0).wire->width != 1)
			str += stringf("[%d]", sig.chunks.at(0).offset);

		cstr_buf.push_back(str);
		return cstr_buf.back().c_str();
	}

	const char *subckt_or_gate(std::string cell_type)
	{
		if (!config->gates_mode)
			return "subckt";
		if (!design->modules.count(RTLIL::escape_id(cell_type)))
			return "gate";
		if (design->modules.at(RTLIL::escape_id(cell_type))->get_bool_attribute("\\blackbox"))
			return "gate";
		return "subckt";
	}

	void dump()
	{
		fprintf(f, "\n");
		fprintf(f, ".model %s\n", cstr(module->name));

		std::map<int, RTLIL::Wire*> inputs, outputs;

		for (auto &wire_it : module->wires) {
			RTLIL::Wire *wire = wire_it.second;
			if (wire->port_input)
				inputs[wire->port_id] = wire;
			if (wire->port_output)
				outputs[wire->port_id] = wire;
		}

		fprintf(f, ".inputs");
		for (auto &it : inputs) {
			RTLIL::Wire *wire = it.second;
			for (int i = 0; i < wire->width; i++)
				fprintf(f, " %s", cstr(RTLIL::SigSpec(wire, 1, i)));
		}
		fprintf(f, "\n");

		fprintf(f, ".outputs");
		for (auto &it : outputs) {
			RTLIL::Wire *wire = it.second;
			for (int i = 0; i < wire->width; i++)
				fprintf(f, " %s", cstr(RTLIL::SigSpec(wire, 1, i)));
		}
		fprintf(f, "\n");

		if (!config->impltf_mode) {
			if (!config->false_type.empty())
				fprintf(f, ".%s %s %s=$false\n", subckt_or_gate(config->false_type),
						config->false_type.c_str(), config->false_out.c_str());
			else
				fprintf(f, ".names $false\n");
			if (!config->true_type.empty())
				fprintf(f, ".%s %s %s=$true\n", subckt_or_gate(config->true_type),
						config->true_type.c_str(), config->true_out.c_str());
			else
				fprintf(f, ".names $true\n1\n");
		}

		for (auto &cell_it : module->cells)
		{
			RTLIL::Cell *cell = cell_it.second;

			if (!config->icells_mode && cell->type == "$_INV_") {
				fprintf(f, ".names %s %s\n0 1\n",
						cstr(cell->connections.at("\\A")), cstr(cell->connections.at("\\Y")));
				continue;
			}

			if (!config->icells_mode && cell->type == "$_AND_") {
				fprintf(f, ".names %s %s %s\n11 1\n",
						cstr(cell->connections.at("\\A")), cstr(cell->connections.at("\\B")), cstr(cell->connections.at("\\Y")));
				continue;
			}

			if (!config->icells_mode && cell->type == "$_OR_") {
				fprintf(f, ".names %s %s %s\n1- 1\n-1 1\n",
						cstr(cell->connections.at("\\A")), cstr(cell->connections.at("\\B")), cstr(cell->connections.at("\\Y")));
				continue;
			}

			if (!config->icells_mode && cell->type == "$_XOR_") {
				fprintf(f, ".names %s %s %s\n10 1\n01 1\n",
						cstr(cell->connections.at("\\A")), cstr(cell->connections.at("\\B")), cstr(cell->connections.at("\\Y")));
				continue;
			}

			if (!config->icells_mode && cell->type == "$_MUX_") {
				fprintf(f, ".names %s %s %s %s\n1-0 1\n-11 1\n",
						cstr(cell->connections.at("\\A")), cstr(cell->connections.at("\\B")),
						cstr(cell->connections.at("\\S")), cstr(cell->connections.at("\\Y")));
				continue;
			}

			if (!config->icells_mode && cell->type == "$_DFF_N_") {
				fprintf(f, ".latch %s %s fe %s\n",
						cstr(cell->connections.at("\\D")), cstr(cell->connections.at("\\Q")), cstr(cell->connections.at("\\C")));
				continue;
			}

			if (!config->icells_mode && cell->type == "$_DFF_P_") {
				fprintf(f, ".latch %s %s re %s\n",
						cstr(cell->connections.at("\\D")), cstr(cell->connections.at("\\Q")), cstr(cell->connections.at("\\C")));
				continue;
			}

			if (!config->icells_mode && cell->type == "$lut") {
				fprintf(f, ".names");
				auto &inputs = cell->connections.at("\\I");
				auto width = cell->parameters.at("\\WIDTH").as_int();
				log_assert(inputs.width == width);
				for (int i = 0; i < inputs.width; i++) {
					fprintf(f, " %s", cstr(inputs.extract(i, 1)));
				}
				auto &output = cell->connections.at("\\O");
				log_assert(output.width == 1);
				fprintf(f, " %s", cstr(output));
				fprintf(f, "\n");
				auto mask = cell->parameters.at("\\LUT").as_string();
				for (int i = 0; i < (1 << width); i++) {
					if (mask[i] == '0') continue;
					for (int j = width-1; j >= 0; j--) {
						fputc((i>>j)&1 ? '1' : '0', f);
					}
					fprintf(f, " %c\n", mask[i]);
				}
				continue;
			}

			fprintf(f, ".%s %s", subckt_or_gate(cell->type), cstr(cell->type));
			for (auto &conn : cell->connections)
			for (int i = 0; i < conn.second.width; i++) {
				if (conn.second.width == 1)
					fprintf(f, " %s", cstr(conn.first));
				else
					fprintf(f, " %s[%d]", cstr(conn.first), i);
				fprintf(f, "=%s", cstr(conn.second.extract(i, 1)));
			}
			fprintf(f, "\n");

			if (config->param_mode)
				for (auto &param : cell->parameters) {
					fprintf(f, ".param %s ", RTLIL::id2cstr(param.first));
					if (param.second.flags & RTLIL::CONST_FLAG_STRING) {
						std::string str = param.second.decode_string();
						fprintf(f, "\"");
						for (char ch : str)
							if (ch == '"' || ch == '\\')
								fprintf(f, "\\%c", ch);
							else if (ch < 32 || ch >= 127)
								fprintf(f, "\\%03o", ch);
							else
								fprintf(f, "%c", ch);
						fprintf(f, "\"\n");
{'fraction_non_alphanumeric': 0.2086230876216968, 'fraction_numerical': 0.009666203059805286, 'mean_word_length': 3.407293901317806, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 156, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6471920', 'n_tokens_mistral': 6450, 'n_tokens_neox': 5562, 'n_words': 1204}