aboutsummaryrefslogtreecommitdiffstats
path: root/tests/asicworld/code_hdl_models_misc1.v
blob: e3d9d5d64305928952802339fb2f19e65d5a75df (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
module misc1 (a,b,c,d,y);
input a, b,c,d;
output y;

wire net1,net2,net3;

supply1 vdd;
supply0 vss;

// y = !((a+b+c).d)

pmos p1 (vdd,net1,a);
pmos p2 (net1,net2,b);
pmos p3 (net2,y,c);
pmos p4 (vdd,y,d);

nmos n1 (vss,net3,a);
nmos n2 (vss,net3,b);
nmos n3 (vss,net3,c);
nmos n4 (net3,y,d);

endmodule
uiltin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
/*
 *  yosys -- Yosys Open SYnthesis Suite
 *
 *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
 *
 *  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.
 *
 */

#include "kernel/yosys.h"
#include "kernel/sigtools.h"

USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN

void dffsr_worker(SigMap &sigmap, Module *module, Cell *cell)
{
	if (cell->type == "$dffsr")
	{
		int width = cell->getParam("\\WIDTH").as_int();
		bool setpol = cell->getParam("\\SET_POLARITY").as_bool();
		bool clrpol = cell->getParam("\\CLR_POLARITY").as_bool();

		SigBit setunused = setpol ? State::S0 : State::S1;
		SigBit clrunused = clrpol ? State::S0 : State::S1;

		SigSpec setsig = sigmap(cell->getPort("\\SET"));
		SigSpec clrsig = sigmap(cell->getPort("\\CLR"));

		Const reset_val;
		SigSpec setctrl, clrctrl;

		for (int i = 0; i < width; i++)
		{
			SigBit setbit = setsig[i], clrbit = clrsig[i];

			if (setbit == setunused) {
				clrctrl.append(clrbit);
				reset_val.bits.push_back(State::S0);
				continue;
			}

			if (clrbit == clrunused) {
				setctrl.append(setbit);
				reset_val.bits.push_back(State::S1);
				continue;
			}

			return;
		}

		setctrl.sort_and_unify();
		clrctrl.sort_and_unify();

		if (GetSize(setctrl) > 1 || GetSize(clrctrl) > 1)
			return;

		if (GetSize(setctrl) == 0 && GetSize(clrctrl) == 0)
			return;

		if (GetSize(setctrl) == 1 && GetSize(clrctrl) == 1) {
			if (setpol != clrpol)
				return;
			if (setctrl != clrctrl)
				return;
		}

		log("Converting %s cell %s.%s to $adff.\n", log_id(cell->type), log_id(module), log_id(cell));

		if (GetSize(setctrl) == 1) {
			cell->setPort("\\ARST", setctrl);
			cell->setParam("\\ARST_POLARITY", setpol);
		} else {
			cell->setPort("\\ARST", clrctrl);
			cell->setParam("\\ARST_POLARITY", clrpol);
		}

		cell->type = "$adff";
		cell->unsetPort("\\SET");
		cell->unsetPort("\\CLR");
		cell->setParam("\\ARST_VALUE", reset_val);
		cell->unsetParam("\\SET_POLARITY");
		cell->unsetParam("\\CLR_POLARITY");

		return;
	}

	if (cell->type.in("$_DFFSR_NNN_", "$_DFFSR_NNP_", "$_DFFSR_NPN_", "$_DFFSR_NPP_",
			"$_DFFSR_PNN_", "$_DFFSR_PNP_", "$_DFFSR_PPN_", "$_DFFSR_PPP_"))
	{
		char clkpol = cell->type.c_str()[8];
		char setpol = cell->type.c_str()[9];
		char clrpol = cell->type.c_str()[10];

		SigBit setbit = sigmap(cell->getPort("\\S"));
		SigBit clrbit = sigmap(cell->getPort("\\R"));

		SigBit setunused = setpol == 'P' ? State::S0 : State::S1;
		SigBit clrunused = clrpol == 'P' ? State::S0 : State::S1;

		IdString oldtype = cell->type;

		if (setbit == setunused) {
			cell->type = stringf("$_DFF_%c%c0_", clkpol, clrpol);
			cell->unsetPort("\\S");
			goto converted_gate;
		}

		if (clrbit == clrunused) {
			cell->type = stringf("$_DFF_%c%c1_", clkpol, setpol);
			cell->setPort("\\R", cell->getPort("\\S"));
			cell->unsetPort("\\S");
			goto converted_gate;
		}

		return;

	converted_gate:
		log("Converting %s cell %s.%s to %s.\n", log_id(oldtype), log_id(module), log_id(cell), log_id(cell->type));
		return;
	}
}

void adff_worker(SigMap &sigmap, Module *module, Cell *cell)
{
	if (cell->type == "$adff")
	{
		bool rstpol = cell->getParam("\\ARST_POLARITY").as_bool();
		SigBit rstunused = rstpol ? State::S0 : State::S1;
		SigSpec rstsig = sigmap(cell->getPort("\\ARST"));

		if (rstsig != rstunused)
			return;

		log("Converting %s cell %s.%s to $dff.\n", log_id(cell->type), log_id(module), log_id(cell));

		cell->type = "$dff";
		cell->unsetPort("\\ARST");
		cell->unsetParam("\\ARST_VALUE");
		cell->unsetParam("\\ARST_POLARITY");

		return;
	}

	if (cell->type.in("$_DFF_NN0_", "$_DFF_NN1_", "$_DFF_NP0_", "$_DFF_NP1_",
			"$_DFF_PN0_", "$_DFF_PN1_", "$_DFF_PP0_", "$_DFF_PP1_"))
	{
		char clkpol = cell->type.c_str()[6];
		char rstpol = cell->type.c_str()[7];

		SigBit rstbit = sigmap(cell->getPort("\\R"));
		SigBit rstunused = rstpol == 'P' ? State::S0 : State::S1;

		if (rstbit != rstunused)
			return;

		IdString newtype = stringf("$_DFF_%c_", clkpol);
		log("Converting %s cell %s.%s to %s.\n", log_id(cell->type), log_id(module), log_id(cell), log_id(newtype));

		cell->type = newtype;
		cell->unsetPort("\\R");

		return;
	}
}

struct Dffsr2dffPass : public Pass {
	Dffsr2dffPass() : Pass("dffsr2dff", "convert DFFSR cells to simpler FF cell types") { }
	void help() YS_OVERRIDE
	{
		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
		log("\n");
		log("    dffsr2dff [options] [selection]\n");
		log("\n");
		log("This pass converts DFFSR cells ($dffsr, $_DFFSR_???_) and ADFF cells ($adff,\n");
		log("$_DFF_???_) to simpler FF cell types when any of the set/reset inputs is unused.\n");
		log("\n");
	}
	void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
	{
		log_header(design, "Executing DFFSR2DFF pass (mapping DFFSR cells to simpler FFs).\n");

		size_t argidx;
		for (argidx = 1; argidx < args.size(); argidx++)
		{
			// if (args[argidx] == "-v") {
			// 	continue;
			// }
			break;
		}
		extra_args(args, argidx, design);

		for (auto module : design->selected_modules()) {
			SigMap sigmap(module);
			for (auto cell : module->selected_cells()) {
				dffsr_worker(sigmap, module, cell);
				adff_worker(sigmap, module, cell);
			}
		}
	}
} Dffsr2dffPass;

PRIVATE_NAMESPACE_END