yosys-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
fsm_export.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  * Copyright (C) 2012 Martin Schmölzer <martin@schmoelzer.at>
6  *
7  * Permission to use, copy, modify, and/or distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  *
19  */
20 
21 #include "kernel/log.h"
22 #include "kernel/register.h"
23 #include "kernel/sigtools.h"
24 #include "kernel/consteval.h"
25 #include "kernel/celltypes.h"
26 #include "fsmdata.h"
27 #include <string>
28 #include <iostream>
29 #include <fstream>
30 
33 
34 /**
35  * Convert a signal into a KISS-compatible textual representation.
36  */
37 std::string kiss_convert_signal(const RTLIL::SigSpec &sig) {
39  return sig.as_const().as_string();
40 }
41 
42 /**
43  * Create a KISS2 file from a cell.
44  *
45  * The destination file name is taken from the fsm_export attribute if present,
46  * e.g. (* fsm_export="filename.kiss2" *). If this attribute is not present,
47  * the file name will be assembled from the module and cell names.
48  *
49  * @param module pointer to module which contains the FSM cell.
50  * @param cell pointer to the FSM cell which should be exported.
51  */
52 void write_kiss2(struct RTLIL::Module *module, struct RTLIL::Cell *cell, std::string filename, bool origenc) {
53  std::map<RTLIL::IdString, RTLIL::Const>::iterator attr_it;
54  FsmData fsm_data;
56  std::ofstream kiss_file;
57  std::string kiss_name;
58  size_t i;
59 
60  attr_it = cell->attributes.find("\\fsm_export");
61  if (!filename.empty()) {
62  kiss_name.assign(filename);
63  } else if (attr_it != cell->attributes.end() && attr_it->second.decode_string() != "") {
64  kiss_name.assign(attr_it->second.decode_string());
65  }
66  else {
67  kiss_name.assign(log_id(module) + std::string("-") + log_id(cell) + ".kiss2");
68  }
69 
70  log("\n");
71  log("Exporting FSM `%s' from module `%s' to file `%s'.\n",
72  cell->name.c_str(),
73  module->name.c_str(),
74  kiss_name.c_str());
75 
76  kiss_file.open(kiss_name, std::ios::out | std::ios::trunc);
77 
78  if (!kiss_file.is_open()) {
79  log_error("Could not open file \"%s\" with write access.\n", kiss_name.c_str());
80  }
81 
82  fsm_data.copy_from_cell(cell);
83 
84  kiss_file << ".i " << std::dec << fsm_data.num_inputs << std::endl;
85  kiss_file << ".o " << std::dec << fsm_data.num_outputs << std::endl;
86  kiss_file << ".p " << std::dec << fsm_data.transition_table.size() << std::endl;
87  kiss_file << ".s " << std::dec << fsm_data.state_table.size() << std::endl;
88  if (origenc) {
89  kiss_file << ".r " << kiss_convert_signal(fsm_data.state_table[fsm_data.reset_state]) << std::endl;
90  } else {
91  kiss_file << ".r s" << std::dec << fsm_data.reset_state << std::endl;
92  }
93 
94  for (i = 0; i < fsm_data.transition_table.size(); i++) {
95  tr = fsm_data.transition_table[i];
96 
97  try {
98  kiss_file << kiss_convert_signal(tr.ctrl_in) << ' ';
99  if (origenc) {
100  kiss_file << kiss_convert_signal(fsm_data.state_table[tr.state_in]) << ' ';
101  kiss_file << kiss_convert_signal(fsm_data.state_table[tr.state_out]) << ' ';
102  } else {
103  kiss_file << 's' << tr.state_in << ' ';
104  kiss_file << 's' << tr.state_out << ' ';
105  }
106  kiss_file << kiss_convert_signal(tr.ctrl_out) << std::endl;
107  }
108  catch (int) {
109  kiss_file.close();
110  log_error("exporting an FSM input or output signal failed.\n");
111  }
112  }
113 
114  kiss_file.close();
115 }
116 
117 /**
118  * Exports Finite State Machines in the design to one file per FSM. Currently,
119  * only the KISS2 file format is supported.
120  */
121 struct FsmExportPass : public Pass {
122  FsmExportPass() : Pass("fsm_export", "exporting FSMs to KISS2 files") { }
123  virtual void help()
124  {
125  // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
126  log("\n");
127  log(" fsm_export [-noauto] [-o filename] [-origenc] [selection]\n");
128  log("\n");
129  log("This pass creates a KISS2 file for every selected FSM. For FSMs with the\n");
130  log("'fsm_export' attribute set, the attribute value is used as filename, otherwise\n");
131  log("the module and cell name is used as filename. If the parameter '-o' is given,\n");
132  log("the first exported FSM is written to the specified filename. This overwrites\n");
133  log("the setting as specified with the 'fsm_export' attribute. All other FSMs are\n");
134  log("exported to the default name as mentioned above.\n");
135  log("\n");
136  log(" -noauto\n");
137  log(" only export FSMs that have the 'fsm_export' attribute set\n");
138  log("\n");
139  log(" -o filename\n");
140  log(" filename of the first exported FSM\n");
141  log("\n");
142  log(" -origenc\n");
143  log(" use binary state encoding as state names instead of s0, s1, ...\n");
144  log("\n");
145  }
146  virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
147  {
148  std::map<RTLIL::IdString, RTLIL::Const>::iterator attr_it;
149  std::string arg;
150  bool flag_noauto = false;
151  std::string filename;
152  bool flag_origenc = false;
153  size_t argidx;
154 
155  log_header("Executing FSM_EXPORT pass (exporting FSMs in KISS2 file format).\n");
156 
157  for (argidx = 1; argidx < args.size(); argidx++) {
158  arg = args[argidx];
159  if (arg == "-noauto") {
160  flag_noauto = true;
161  continue;
162  }
163  if (arg == "-o") {
164  argidx++;
165  filename = args[argidx];
166  continue;
167  }
168  if (arg == "-origenc") {
169  flag_origenc = true;
170  continue;
171  }
172  break;
173  }
174  extra_args(args, argidx, design);
175 
176  for (auto &mod_it : design->modules_)
177  if (design->selected(mod_it.second))
178  for (auto &cell_it : mod_it.second->cells_)
179  if (cell_it.second->type == "$fsm" && design->selected(mod_it.second, cell_it.second)) {
180  attr_it = cell_it.second->attributes.find("\\fsm_export");
181  if (!flag_noauto || (attr_it != cell_it.second->attributes.end())) {
182  write_kiss2(mod_it.second, cell_it.second, filename, flag_origenc);
183  filename.clear();
184  }
185  }
186  }
187 } FsmExportPass;
188 
const char * c_str() const
Definition: rtlil.h:178
bool selected(T1 *module) const
Definition: rtlil.h:551
void write_kiss2(struct RTLIL::Module *module, struct RTLIL::Cell *cell, std::string filename, bool origenc)
Definition: fsm_export.cc:52
virtual void help()
Definition: fsm_export.cc:123
std::vector< transition_t > transition_table
Definition: fsmdata.h:31
virtual void execute(std::vector< std::string > args, RTLIL::Design *design)
Definition: fsm_export.cc:146
FsmExportPass FsmExportPass
void log_header(const char *format,...)
Definition: log.cc:188
RTLIL::Const as_const() const
Definition: rtlil.cc:2857
RTLIL::IdString name
Definition: rtlil.h:853
void log_error(const char *format,...)
Definition: log.cc:204
RTLIL::Module * module
Definition: abc.cc:94
RTLIL::Const ctrl_out
Definition: fsmdata.h:30
USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN std::string kiss_convert_signal(const RTLIL::SigSpec &sig)
Definition: fsm_export.cc:37
RTLIL::Const ctrl_in
Definition: fsmdata.h:30
std::string as_string() const
Definition: rtlil.cc:116
#define PRIVATE_NAMESPACE_BEGIN
Definition: yosys.h:97
int num_inputs
Definition: fsmdata.h:29
#define log_assert(_assert_expr_)
Definition: log.h:85
bool is_fully_const() const
Definition: rtlil.cc:2763
RTLIL::IdString name
Definition: rtlil.h:599
#define PRIVATE_NAMESPACE_END
Definition: yosys.h:98
Definition: register.h:27
#define USING_YOSYS_NAMESPACE
Definition: yosys.h:102
std::map< RTLIL::IdString, RTLIL::Module * > modules_
Definition: rtlil.h:507
std::vector< RTLIL::Const > state_table
Definition: fsmdata.h:32
void log(const char *format,...)
Definition: log.cc:180
void copy_from_cell(RTLIL::Cell *cell)
Definition: fsmdata.h:79
int num_outputs
Definition: fsmdata.h:29
void extra_args(std::vector< std::string > args, size_t argidx, RTLIL::Design *design, bool select=true)
Definition: register.cc:128
int reset_state
Definition: fsmdata.h:29
const char * log_id(RTLIL::IdString str)
Definition: log.cc:283