2 * yosys -- Yosys Open SYnthesis Suite
4 * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
5 * Copyright (C) 2012 Martin Schmölzer <martin@schmoelzer.at>
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.
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.
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"
32 * Convert a signal into a KISS-compatible textual representation.
34 std::string
kiss_convert_signal(const RTLIL::SigSpec
&sig
) {
35 if (!sig
.is_fully_const()) {
39 return sig
.as_const().as_string();
43 * Create a KISS2 file from a cell.
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.
49 * @param module pointer to module which contains the FSM cell.
50 * @param cell pointer to the FSM cell which should be exported.
52 void write_kiss2(struct RTLIL::Module
*module
, struct RTLIL::Cell
*cell
) {
53 std::map
<RTLIL::IdString
, RTLIL::Const
>::iterator attr_it
;
55 FsmData::transition_t tr
;
56 std::ofstream kiss_file
;
57 std::string kiss_name
;
60 attr_it
= cell
->attributes
.find("\\fsm_export");
61 if (attr_it
!= cell
->attributes
.end() && attr_it
->second
.str
!= "") {
62 kiss_name
.assign(attr_it
->second
.str
);
65 kiss_name
.assign(module
->name
);
66 kiss_name
.append('-' + cell
->name
+ ".kiss2");
70 log("Exporting FSM `%s' from module `%s' to file `%s'.\n",
75 kiss_file
.open(kiss_name
, std::ios::out
| std::ios::trunc
);
77 if (!kiss_file
.is_open()) {
78 log_error("Could not open file \"%s\" with write access.\n", kiss_name
.c_str());
81 fsm_data
.copy_from_cell(cell
);
83 kiss_file
<< ".start_kiss" << std::endl
;
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
<< ".r s" << std::dec
<< fsm_data
.reset_state
<< std::endl
;
88 for (i
= 0; i
< fsm_data
.transition_table
.size(); i
++) {
89 tr
= fsm_data
.transition_table
[i
];
92 kiss_file
<< kiss_convert_signal(tr
.ctrl_in
) << ' ';
93 kiss_file
<< 's' << tr
.state_in
<< ' ';
94 kiss_file
<< 's' << tr
.state_out
<< ' ';
95 kiss_file
<< kiss_convert_signal(tr
.ctrl_out
) << std::endl
;
99 log_error("exporting an FSM input or output signal failed.\n");
103 kiss_file
<< ".end_kiss" << std::endl
<< ".end" << std::endl
;
108 * Exports Finite State Machines in the design to one file per FSM. Currently,
109 * only the KISS2 file format is supported.
111 struct FsmExportPass
: public Pass
{
112 FsmExportPass() : Pass("fsm_export") {
115 virtual void execute(std::vector
<std::string
> args
, RTLIL::Design
*design
)
117 std::map
<RTLIL::IdString
, RTLIL::Const
>::iterator attr_it
;
119 bool flag_noauto
= false;
122 log_header("Executing FSM_EXPORT pass (exporting FSMs in KISS2 file format).\n");
124 for (argidx
= 1; argidx
< args
.size(); argidx
++) {
126 if (arg
== "-noauto") {
132 extra_args(args
, argidx
, design
);
134 for (auto &mod_it
: design
->modules
)
135 for (auto &cell_it
: mod_it
.second
->cells
)
136 if (cell_it
.second
->type
== "$fsm") {
137 attr_it
= cell_it
.second
->attributes
.find("\\fsm_export");
138 if (!flag_noauto
|| (attr_it
!= cell_it
.second
->attributes
.end())) {
139 write_kiss2(mod_it
.second
, cell_it
.second
);