yosys-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
proc_init.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/sigtools.h"
22 #include "kernel/log.h"
23 #include <stdlib.h>
24 #include <stdio.h>
25 
28 
30 {
31  log_assert(rule.compare.size() == 0);
32 
33  while (1) {
34  RTLIL::SigSpec tmp = sig;
35  for (auto &it : rule.actions)
36  tmp.replace(it.first, it.second);
37  if (tmp == sig)
38  break;
39  sig = tmp;
40  }
41 }
42 
44 {
45  bool found_init = false;
46 
47  for (auto &sync : proc->syncs)
48  if (sync->type == RTLIL::SyncType::STi)
49  {
50  found_init = true;
51  log("Found init rule in `%s.%s'.\n", mod->name.c_str(), proc->name.c_str());
52 
53  for (auto &action : sync->actions)
54  {
55  RTLIL::SigSpec lhs = action.first;
56  RTLIL::SigSpec rhs = action.second;
57 
58  proc_get_const(rhs, proc->root_case);
59 
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));
62 
63  int offset = 0;
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();
71  }
72  offset += lhs_c.width;
73  }
74  }
75  }
76 
77  if (found_init) {
78  std::vector<RTLIL::SyncRule*> new_syncs;
79  for (auto &sync : proc->syncs)
80  if (sync->type == RTLIL::SyncType::STi)
81  delete sync;
82  else
83  new_syncs.push_back(sync);
84  proc->syncs.swap(new_syncs);
85  }
86 }
87 
88 struct ProcInitPass : public Pass {
89  ProcInitPass() : Pass("proc_init", "convert initial block to init attributes") { }
90  virtual void help()
91  {
92  // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
93  log("\n");
94  log(" proc_init [selection]\n");
95  log("\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");
99  log("\n");
100  }
101  virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
102  {
103  log_header("Executing PROC_INIT pass (extract init attributes).\n");
104 
105  extra_args(args, 1, design);
106 
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);
112  }
113 } ProcInitPass;
114 
const char * c_str() const
Definition: rtlil.h:178
bool selected(T1 *module) const
Definition: rtlil.h:551
void log_header(const char *format,...)
Definition: log.cc:188
RTLIL::Const as_const() const
Definition: rtlil.cc:2857
const char * log_signal(const RTLIL::SigSpec &sig, bool autoint)
Definition: log.cc:269
int size() const
Definition: rtlil.h:1019
USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN void proc_get_const(RTLIL::SigSpec &sig, RTLIL::CaseRule &rule)
Definition: proc_init.cc:29
std::vector< RTLIL::SigSpec > compare
Definition: rtlil.h:1119
#define PRIVATE_NAMESPACE_BEGIN
Definition: yosys.h:97
#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
virtual void help()
Definition: proc_init.cc:90
#define PRIVATE_NAMESPACE_END
Definition: yosys.h:98
Definition: register.h:27
void log_cmd_error(const char *format,...)
Definition: log.cc:211
RTLIL::IdString name
Definition: rtlil.h:1154
#define USING_YOSYS_NAMESPACE
Definition: yosys.h:102
RTLIL::ObjRange< RTLIL::Module * > modules()
Definition: rtlil.cc:249
void proc_init(RTLIL::Module *mod, RTLIL::Process *proc)
Definition: proc_init.cc:43
void replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with)
Definition: rtlil.cc:2297
virtual void execute(std::vector< std::string > args, RTLIL::Design *design)
Definition: proc_init.cc:101
#define NULL
void log(const char *format,...)
Definition: log.cc:180
std::vector< RTLIL::SyncRule * > syncs
Definition: rtlil.h:1157
ProcInitPass ProcInitPass
RTLIL::SigSpec extract(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec *other=NULL) const
Definition: rtlil.cc:2414
std::vector< RTLIL::SigSig > actions
Definition: rtlil.h:1120
void extra_args(std::vector< std::string > args, size_t argidx, RTLIL::Design *design, bool select=true)
Definition: register.cc:128
const std::vector< RTLIL::SigChunk > & chunks() const
Definition: rtlil.h:1016
RTLIL_ATTRIBUTE_MEMBERS RTLIL::CaseRule root_case
Definition: rtlil.h:1156