yosys-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
synth_xilinx.cc
Go to the documentation of this file.
1 /*
2  * yosys -- Yosys Open SYnthesis Suite
3  *
4  * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
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 
27 
28 bool check_label(bool &active, std::string run_from, std::string run_to, std::string label)
29 {
30  if (label == run_from)
31  active = true;
32  if (label == run_to)
33  active = false;
34  return active;
35 }
36 
37 struct SynthXilinxPass : public Pass {
38  SynthXilinxPass() : Pass("synth_xilinx", "synthesis for Xilinx FPGAs") { }
39  virtual void help()
40  {
41  // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
42  log("\n");
43  log(" synth_xilinx [options]\n");
44  log("\n");
45  log("This command runs synthesis for Xilinx FPGAs. This command does not operate on\n");
46  log("partly selected designs.\n");
47  log("\n");
48  log(" -top <module>\n");
49  log(" use the specified module as top module (default='top')\n");
50  log("\n");
51  log(" -arch <arch>\n");
52  log(" select architecture. the following architectures are supported:\n");
53  log(" spartan6 (default), artix7, kintex7, virtex7, zynq7000\n");
54  log(" (this parameter is not used by the command at the moment)\n");
55  log("\n");
56  log(" -edif <file>\n");
57  log(" write the design to the specified edif file. writing of an output file\n");
58  log(" is omitted if this parameter is not specified.\n");
59  log("\n");
60  log(" -run <from_label>:<to_label>\n");
61  log(" only run the commands between the labels (see below). an empty\n");
62  log(" from label is synonymous to 'begin', and empty to label is\n");
63  log(" synonymous to the end of the command list.\n");
64  log("\n");
65  log("\n");
66  log("The following commands are executed by this synthesis command:\n");
67  log("\n");
68  log(" begin:\n");
69  log(" hierarchy -check -top <top>\n");
70  log("\n");
71  log(" coarse:\n");
72  log(" proc\n");
73  log(" opt\n");
74  log(" memory\n");
75  log(" clean\n");
76  log(" fsm\n");
77  log(" opt\n");
78  log("\n");
79  log(" fine:\n");
80  log(" techmap\n");
81  log(" opt\n");
82  log("\n");
83  log(" map_luts:\n");
84  log(" abc -lut 6\n");
85  log(" clean\n");
86  log("\n");
87  log(" map_cells:\n");
88  log(" techmap -share_map xilinx/cells.v\n");
89  log(" clean\n");
90  log("\n");
91  log(" clkbuf:\n");
92  log(" select -set xilinx_clocks <top>/t:FDRE %%x:+FDRE[C] <top>/t:FDRE %%d\n");
93  log(" iopadmap -inpad BUFGP O:I @xilinx_clocks\n");
94  log("\n");
95  log(" iobuf:\n");
96  log(" select -set xilinx_nonclocks <top>/w:* <top>/t:BUFGP %%x:+BUFGP[I] %%d\n");
97  log(" iopadmap -outpad OBUF I:O -inpad IBUF O:I @xilinx_nonclocks\n");
98  log("\n");
99  log(" edif:\n");
100  log(" write_edif synth.edif\n");
101  log("\n");
102  }
103  virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
104  {
105  std::string top_module = "top";
106  std::string arch_name = "spartan6";
107  std::string edif_file;
108  std::string run_from, run_to;
109 
110  size_t argidx;
111  for (argidx = 1; argidx < args.size(); argidx++)
112  {
113  if (args[argidx] == "-top" && argidx+1 < args.size()) {
114  top_module = args[++argidx];
115  continue;
116  }
117  if (args[argidx] == "-arch" && argidx+1 < args.size()) {
118  arch_name = args[++argidx];
119  continue;
120  }
121  if (args[argidx] == "-edif" && argidx+1 < args.size()) {
122  edif_file = args[++argidx];
123  continue;
124  }
125  if (args[argidx] == "-run" && argidx+1 < args.size()) {
126  size_t pos = args[argidx+1].find(':');
127  if (pos == std::string::npos)
128  break;
129  run_from = args[++argidx].substr(0, pos);
130  run_to = args[argidx].substr(pos+1);
131  continue;
132  }
133  break;
134  }
135  extra_args(args, argidx, design);
136 
137  if (!design->full_selection())
138  log_cmd_error("This comannd only operates on fully selected designs!\n");
139 
140  if (arch_name == "spartan6") {
141  /* set flags */
142  } else
143  if (arch_name == "artix7") {
144  /* set flags */
145  } else
146  if (arch_name == "kintex7") {
147  /* set flags */
148  } else
149  if (arch_name == "zynq7000") {
150  /* set flags */
151  } else
152  log_cmd_error("Architecture '%s' is not supported!\n", arch_name.c_str());
153 
154  bool active = run_from.empty();
155 
156  log_header("Executing SYNTH_XILINX pass.\n");
157  log_push();
158 
159  if (check_label(active, run_from, run_to, "begin"))
160  {
161  Pass::call(design, stringf("hierarchy -check -top %s", top_module.c_str()));
162  }
163 
164  if (check_label(active, run_from, run_to, "coarse"))
165  {
166  Pass::call(design, "proc");
167  Pass::call(design, "opt");
168  Pass::call(design, "memory");
169  Pass::call(design, "clean");
170  Pass::call(design, "fsm");
171  Pass::call(design, "opt");
172  }
173 
174  if (check_label(active, run_from, run_to, "fine"))
175  {
176  Pass::call(design, "techmap");
177  Pass::call(design, "opt");
178  }
179 
180  if (check_label(active, run_from, run_to, "map_luts"))
181  {
182  Pass::call(design, "abc -lut 6");
183  Pass::call(design, "clean");
184  }
185 
186  if (check_label(active, run_from, run_to, "map_cells"))
187  {
188  Pass::call(design, "techmap -share_map xilinx/cells.v");
189  Pass::call(design, "clean");
190  }
191 
192  if (check_label(active, run_from, run_to, "clkbuf"))
193  {
194  Pass::call(design, stringf("select -set xilinx_clocks %s/t:FDRE %%x:+FDRE[C] %s/t:FDRE %%d", top_module.c_str(), top_module.c_str()));
195  Pass::call(design, "iopadmap -inpad BUFGP O:I @xilinx_clocks");
196  }
197 
198  if (check_label(active, run_from, run_to, "iobuf"))
199  {
200  Pass::call(design, stringf("select -set xilinx_nonclocks %s/w:* %s/t:BUFGP %%x:+BUFGP[I] %%d", top_module.c_str(), top_module.c_str()));
201  Pass::call(design, "iopadmap -outpad OBUF I:O -inpad IBUF O:I @xilinx_nonclocks");
202  }
203 
204  if (check_label(active, run_from, run_to, "edif"))
205  {
206  if (!edif_file.empty())
207  Pass::call(design, stringf("write_edif %s", edif_file.c_str()));
208  }
209 
210  log_pop();
211  }
213 
std::string stringf(const char *fmt,...)
Definition: yosys.cc:58
USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN bool check_label(bool &active, std::string run_from, std::string run_to, std::string label)
Definition: synth_xilinx.cc:28
void log_header(const char *format,...)
Definition: log.cc:188
virtual void help()
Definition: synth_xilinx.cc:39
SynthXilinxPass SynthXilinxPass
void log_pop()
Definition: log.cc:237
bool full_selection() const
Definition: rtlil.h:547
#define PRIVATE_NAMESPACE_BEGIN
Definition: yosys.h:97
#define PRIVATE_NAMESPACE_END
Definition: yosys.h:98
Definition: register.h:27
void log_cmd_error(const char *format,...)
Definition: log.cc:211
#define USING_YOSYS_NAMESPACE
Definition: yosys.h:102
void log(const char *format,...)
Definition: log.cc:180
void log_push()
Definition: log.cc:232
void extra_args(std::vector< std::string > args, size_t argidx, RTLIL::Design *design, bool select=true)
Definition: register.cc:128
static void call(RTLIL::Design *design, std::string command)
Definition: register.cc:146
virtual void execute(std::vector< std::string > args, RTLIL::Design *design)