2 * yosys -- Yosys Open SYnthesis Suite
4 * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
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.
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.
20 #include "kernel/register.h"
21 #include "kernel/sigtools.h"
22 #include "kernel/log.h"
27 PRIVATE_NAMESPACE_BEGIN
29 void proc_get_const(RTLIL::SigSpec
&sig
, RTLIL::CaseRule
&rule
)
31 log_assert(rule
.compare
.size() == 0);
34 RTLIL::SigSpec tmp
= sig
;
35 for (auto &it
: rule
.actions
)
36 tmp
.replace(it
.first
, it
.second
);
43 void proc_init(RTLIL::Module
*mod
, RTLIL::Process
*proc
)
45 bool found_init
= false;
47 for (auto &sync
: proc
->syncs
)
48 if (sync
->type
== RTLIL::SyncType::STi
)
51 log("Found init rule in `%s.%s'.\n", mod
->name
.c_str(), proc
->name
.c_str());
53 for (auto &action
: sync
->actions
)
55 RTLIL::SigSpec lhs
= action
.first
;
56 RTLIL::SigSpec rhs
= action
.second
;
58 proc_get_const(rhs
, proc
->root_case
);
60 if (!rhs
.is_fully_const())
61 log_cmd_error("Failed to get a constant init value for %s: %s\n", log_signal(lhs
), log_signal(rhs
));
64 for (auto &lhs_c
: lhs
.chunks()) {
65 if (lhs_c
.wire
!= NULL
) {
66 RTLIL::SigSpec value
= rhs
.extract(offset
, lhs_c
.width
);
67 if (value
.size() != lhs_c
.wire
->width
)
68 log_cmd_error("Init value is not for the entire wire: %s = %s\n", log_signal(lhs_c
), log_signal(value
));
69 log(" Setting init value: %s = %s\n", log_signal(lhs_c
.wire
), log_signal(value
));
70 lhs_c
.wire
->attributes
["\\init"] = value
.as_const();
72 offset
+= lhs_c
.width
;
78 std::vector
<RTLIL::SyncRule
*> new_syncs
;
79 for (auto &sync
: proc
->syncs
)
80 if (sync
->type
== RTLIL::SyncType::STi
)
83 new_syncs
.push_back(sync
);
84 proc
->syncs
.swap(new_syncs
);
88 struct ProcInitPass
: public Pass
{
89 ProcInitPass() : Pass("proc_init", "convert initial block to init attributes") { }
92 // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
94 log(" proc_init [selection]\n");
96 log("This pass extracts the 'init' actions from processes (generated from verilog\n");
97 log("'initial' blocks) and sets the initial value to the 'init' attribute on the\n");
98 log("respective wire.\n");
101 virtual void execute(std::vector
<std::string
> args
, RTLIL::Design
*design
)
103 log_header("Executing PROC_INIT pass (extract init attributes).\n");
105 extra_args(args
, 1, design
);
107 for (auto mod
: design
->modules())
108 if (design
->selected(mod
))
109 for (auto &proc_it
: mod
->processes
)
110 if (design
->selected(mod
, proc_it
.second
))
111 proc_init(mod
, proc_it
.second
);
115 PRIVATE_NAMESPACE_END