1 /*
2  *  yosys -- Yosys Open SYnthesis Suite
3  *
4  *  Copyright (C) 2012  Claire Xenia Wolf <claire@yosyshq.com>
5  *
6  *  Permission to use, copy, modify, and/or distribute this software for any
7  *  purpose with or without fee is hereby granted, provided that the above
8  *  copyright notice and this permission notice appear in all copies.
9  *
10  *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  *
18  */
19 
20 #include "kernel/register.h"
21 #include "kernel/celltypes.h"
22 #include "kernel/rtlil.h"
23 #include "kernel/log.h"
24 
25 USING_YOSYS_NAMESPACE
26 PRIVATE_NAMESPACE_BEGIN
27 
28 struct SynthEasicPass : public ScriptPass
29 {
SynthEasicPassSynthEasicPass30 	SynthEasicPass() : ScriptPass("synth_easic", "synthesis for eASIC platform") { }
31 
helpSynthEasicPass32 	void help() override
33 	{
34 		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
35 		log("\n");
36 		log("    synth_easic [options]\n");
37 		log("\n");
38 		log("This command runs synthesis for eASIC platform.\n");
39 		log("\n");
40 		log("    -top <module>\n");
41 		log("        use the specified module as top module\n");
42 		log("\n");
43 		log("    -vlog <file>\n");
44 		log("        write the design to the specified structural Verilog file. writing of\n");
45 		log("        an output file is omitted if this parameter is not specified.\n");
46 		log("\n");
47 		log("    -etools <path>\n");
48 		log("        set path to the eTools installation. (default=/opt/eTools)\n");
49 		log("\n");
50 		log("    -run <from_label>:<to_label>\n");
51 		log("        only run the commands between the labels (see below). an empty\n");
52 		log("        from label is synonymous to 'begin', and empty to label is\n");
53 		log("        synonymous to the end of the command list.\n");
54 		log("\n");
55 		log("    -noflatten\n");
56 		log("        do not flatten design before synthesis\n");
57 		log("\n");
58 		log("    -retime\n");
59 		log("        run 'abc' with '-dff -D 1' options\n");
60 		log("\n");
61 		log("\n");
62 		log("The following commands are executed by this synthesis command:\n");
63 		help_script();
64 		log("\n");
65 	}
66 
67 	string top_opt, vlog_file, etools_path;
68 	bool flatten, retime;
69 
clear_flagsSynthEasicPass70 	void clear_flags() override
71 	{
72 		top_opt = "-auto-top";
73 		vlog_file = "";
74 		etools_path = "/opt/eTools";
75 		flatten = true;
76 		retime = false;
77 	}
78 
executeSynthEasicPass79 	void execute(std::vector<std::string> args, RTLIL::Design *design) override
80 	{
81 		string run_from, run_to;
82 		clear_flags();
83 
84 		size_t argidx;
85 		for (argidx = 1; argidx < args.size(); argidx++)
86 		{
87 			if (args[argidx] == "-top" && argidx+1 < args.size()) {
88 				top_opt = "-top " + args[++argidx];
89 				continue;
90 			}
91 			if (args[argidx] == "-vlog" && argidx+1 < args.size()) {
92 				vlog_file = args[++argidx];
93 				continue;
94 			}
95 			if (args[argidx] == "-etools" && argidx+1 < args.size()) {
96 				etools_path = args[++argidx];
97 				continue;
98 			}
99 			if (args[argidx] == "-run" && argidx+1 < args.size()) {
100 				size_t pos = args[argidx+1].find(':');
101 				if (pos == std::string::npos)
102 					break;
103 				run_from = args[++argidx].substr(0, pos);
104 				run_to = args[argidx].substr(pos+1);
105 				continue;
106 			}
107 			if (args[argidx] == "-noflatten") {
108 				flatten = false;
109 				continue;
110 			}
111 			if (args[argidx] == "-retime") {
112 				retime = true;
113 				continue;
114 			}
115 			break;
116 		}
117 		extra_args(args, argidx, design);
118 
119 		if (!design->full_selection())
120 			log_cmd_error("This command only operates on fully selected designs!\n");
121 
122 		log_header(design, "Executing SYNTH_EASIC pass.\n");
123 		log_push();
124 
125 		run_script(design, run_from, run_to);
126 
127 		log_pop();
128 	}
129 
scriptSynthEasicPass130 	void script() override
131 	{
132 		string phys_clk_lib = stringf("%s/data_ruby28/design_libs/logical/timing/gp/n3x_phys_clk_0v893ff125c.lib", etools_path.c_str());
133 		string logic_lut_lib = stringf("%s/data_ruby28/design_libs/logical/timing/gp/n3x_logic_lut_0v893ff125c.lib", etools_path.c_str());
134 
135 		if (check_label("begin"))
136 		{
137 			run(stringf("read_liberty -lib %s", help_mode ? "<etools_phys_clk_lib>" : phys_clk_lib.c_str()));
138 			run(stringf("read_liberty -lib %s", help_mode ? "<etools_logic_lut_lib>" : logic_lut_lib.c_str()));
139 			run(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str()));
140 		}
141 
142 		if (flatten && check_label("flatten", "(unless -noflatten)"))
143 		{
144 			run("proc");
145 			run("flatten");
146 		}
147 
148 		if (check_label("coarse"))
149 		{
150 			run("synth -run coarse");
151 		}
152 
153 		if (check_label("fine"))
154 		{
155 			run("opt -fast -mux_undef -undriven -fine");
156 			run("memory_map");
157 			run("opt -undriven -fine");
158 			run("techmap");
159 			run("opt -fast");
160 			if (retime || help_mode) {
161 				run("abc -dff -D 1", " (only if -retime)");
162 				run("opt_clean", "(only if -retime)");
163 			}
164 		}
165 
166 		if (check_label("map"))
167 		{
168 			run(stringf("dfflibmap -liberty %s", help_mode ? "<etools_phys_clk_lib>" : phys_clk_lib.c_str()));
169 			run(stringf("abc -liberty %s", help_mode ? "<etools_logic_lut_lib>" : logic_lut_lib.c_str()));
170 			run("opt_clean");
171 		}
172 
173 		if (check_label("check"))
174 		{
175 			run("hierarchy -check");
176 			run("stat");
177 			run("check -noinit");
178 			run("blackbox =A:whitebox");
179 		}
180 
181 		if (check_label("vlog"))
182 		{
183 			if (!vlog_file.empty() || help_mode)
184 				run(stringf("write_verilog -noexpr -attr2comment %s", help_mode ? "<file-name>" : vlog_file.c_str()));
185 		}
186 	}
187 } SynthEasicPass;
188 
189 PRIVATE_NAMESPACE_END
190