2018-07-21 01:41:18 -05:00
|
|
|
/* -*- c++ -*-
|
2013-01-05 04:13:26 -06:00
|
|
|
* yosys -- Yosys Open SYnthesis Suite
|
|
|
|
*
|
2021-06-07 17:39:36 -05:00
|
|
|
* Copyright (C) 2012 Claire Xenia Wolf <claire@yosyshq.com>
|
2015-07-02 04:14:30 -05:00
|
|
|
*
|
2013-01-05 04:13:26 -06:00
|
|
|
* Permission to use, copy, modify, and/or distribute this software for any
|
|
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
|
|
* copyright notice and this permission notice appear in all copies.
|
2015-07-02 04:14:30 -05:00
|
|
|
*
|
2013-01-05 04:13:26 -06:00
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
|
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
|
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
|
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
|
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
|
|
*
|
|
|
|
* ---
|
|
|
|
*
|
|
|
|
* This is the AST frontend library.
|
|
|
|
*
|
|
|
|
* The AST frontend library is not a frontend on it's own but provides a
|
|
|
|
* generic abstract syntax tree (AST) abstraction for HDL code and can be
|
|
|
|
* used by HDL frontends. See "ast.h" for an overview of the API and the
|
|
|
|
* Verilog frontend for an usage example.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef AST_H
|
|
|
|
#define AST_H
|
|
|
|
|
|
|
|
#include "kernel/rtlil.h"
|
2020-11-29 02:57:07 -06:00
|
|
|
#include "kernel/fmt.h"
|
2013-01-05 04:13:26 -06:00
|
|
|
#include <stdint.h>
|
|
|
|
#include <set>
|
|
|
|
|
2014-07-31 06:19:47 -05:00
|
|
|
YOSYS_NAMESPACE_BEGIN
|
|
|
|
|
2013-01-05 04:13:26 -06:00
|
|
|
namespace AST
|
|
|
|
{
|
|
|
|
// all node types, type2str() must be extended
|
|
|
|
// whenever a new node type is added here
|
|
|
|
enum AstNodeType
|
|
|
|
{
|
|
|
|
AST_NONE,
|
|
|
|
AST_DESIGN,
|
|
|
|
AST_MODULE,
|
|
|
|
AST_TASK,
|
|
|
|
AST_FUNCTION,
|
2014-08-21 05:43:51 -05:00
|
|
|
AST_DPI_FUNCTION,
|
2013-01-05 04:13:26 -06:00
|
|
|
|
|
|
|
AST_WIRE,
|
|
|
|
AST_MEMORY,
|
|
|
|
AST_AUTOWIRE,
|
|
|
|
AST_PARAMETER,
|
|
|
|
AST_LOCALPARAM,
|
2013-07-04 07:12:33 -05:00
|
|
|
AST_DEFPARAM,
|
2013-01-05 04:13:26 -06:00
|
|
|
AST_PARASET,
|
|
|
|
AST_ARGUMENT,
|
|
|
|
AST_RANGE,
|
2014-08-06 08:43:46 -05:00
|
|
|
AST_MULTIRANGE,
|
2013-01-05 04:13:26 -06:00
|
|
|
AST_CONSTANT,
|
2014-06-13 04:29:23 -05:00
|
|
|
AST_REALVALUE,
|
2013-01-05 04:13:26 -06:00
|
|
|
AST_CELLTYPE,
|
|
|
|
AST_IDENTIFIER,
|
2013-02-26 06:18:22 -06:00
|
|
|
AST_PREFIX,
|
2014-01-18 21:18:22 -06:00
|
|
|
AST_ASSERT,
|
2015-02-26 11:47:39 -06:00
|
|
|
AST_ASSUME,
|
2017-02-25 03:36:39 -06:00
|
|
|
AST_LIVE,
|
|
|
|
AST_FAIR,
|
2017-02-04 07:14:26 -06:00
|
|
|
AST_COVER,
|
2018-03-09 06:47:11 -06:00
|
|
|
AST_ENUM,
|
|
|
|
AST_ENUM_ITEM,
|
2013-01-05 04:13:26 -06:00
|
|
|
|
|
|
|
AST_FCALL,
|
2014-02-01 06:50:23 -06:00
|
|
|
AST_TO_BITS,
|
2013-01-05 04:13:26 -06:00
|
|
|
AST_TO_SIGNED,
|
|
|
|
AST_TO_UNSIGNED,
|
2020-04-29 07:28:04 -05:00
|
|
|
AST_SELFSZ,
|
2020-06-14 17:15:59 -05:00
|
|
|
AST_CAST_SIZE,
|
2013-01-05 04:13:26 -06:00
|
|
|
AST_CONCAT,
|
|
|
|
AST_REPLICATE,
|
|
|
|
AST_BIT_NOT,
|
|
|
|
AST_BIT_AND,
|
|
|
|
AST_BIT_OR,
|
|
|
|
AST_BIT_XOR,
|
|
|
|
AST_BIT_XNOR,
|
|
|
|
AST_REDUCE_AND,
|
|
|
|
AST_REDUCE_OR,
|
|
|
|
AST_REDUCE_XOR,
|
|
|
|
AST_REDUCE_XNOR,
|
|
|
|
AST_REDUCE_BOOL,
|
|
|
|
AST_SHIFT_LEFT,
|
|
|
|
AST_SHIFT_RIGHT,
|
|
|
|
AST_SHIFT_SLEFT,
|
|
|
|
AST_SHIFT_SRIGHT,
|
2020-04-27 10:04:47 -05:00
|
|
|
AST_SHIFTX,
|
|
|
|
AST_SHIFT,
|
2013-01-05 04:13:26 -06:00
|
|
|
AST_LT,
|
|
|
|
AST_LE,
|
|
|
|
AST_EQ,
|
|
|
|
AST_NE,
|
2013-12-27 06:50:08 -06:00
|
|
|
AST_EQX,
|
|
|
|
AST_NEX,
|
2013-01-05 04:13:26 -06:00
|
|
|
AST_GE,
|
|
|
|
AST_GT,
|
|
|
|
AST_ADD,
|
|
|
|
AST_SUB,
|
|
|
|
AST_MUL,
|
|
|
|
AST_DIV,
|
|
|
|
AST_MOD,
|
|
|
|
AST_POW,
|
|
|
|
AST_POS,
|
|
|
|
AST_NEG,
|
|
|
|
AST_LOGIC_AND,
|
|
|
|
AST_LOGIC_OR,
|
|
|
|
AST_LOGIC_NOT,
|
|
|
|
AST_TERNARY,
|
|
|
|
AST_MEMRD,
|
|
|
|
AST_MEMWR,
|
2015-02-14 03:49:30 -06:00
|
|
|
AST_MEMINIT,
|
2013-01-05 04:13:26 -06:00
|
|
|
|
|
|
|
AST_TCALL,
|
|
|
|
AST_ASSIGN,
|
|
|
|
AST_CELL,
|
|
|
|
AST_PRIMITIVE,
|
2014-06-07 04:48:50 -05:00
|
|
|
AST_CELLARRAY,
|
2013-01-05 04:13:26 -06:00
|
|
|
AST_ALWAYS,
|
2013-03-31 04:19:11 -05:00
|
|
|
AST_INITIAL,
|
2013-01-05 04:13:26 -06:00
|
|
|
AST_BLOCK,
|
|
|
|
AST_ASSIGN_EQ,
|
|
|
|
AST_ASSIGN_LE,
|
|
|
|
AST_CASE,
|
|
|
|
AST_COND,
|
2016-04-21 08:31:54 -05:00
|
|
|
AST_CONDX,
|
|
|
|
AST_CONDZ,
|
2013-01-05 04:13:26 -06:00
|
|
|
AST_DEFAULT,
|
|
|
|
AST_FOR,
|
2014-02-14 13:33:22 -06:00
|
|
|
AST_WHILE,
|
2014-06-06 10:40:04 -05:00
|
|
|
AST_REPEAT,
|
2013-01-05 04:13:26 -06:00
|
|
|
|
|
|
|
AST_GENVAR,
|
|
|
|
AST_GENFOR,
|
|
|
|
AST_GENIF,
|
2013-12-04 14:06:54 -06:00
|
|
|
AST_GENCASE,
|
2013-01-05 04:13:26 -06:00
|
|
|
AST_GENBLOCK,
|
2019-05-02 19:10:43 -05:00
|
|
|
AST_TECALL,
|
2020-05-08 08:40:49 -05:00
|
|
|
|
2013-01-05 04:13:26 -06:00
|
|
|
AST_POSEDGE,
|
|
|
|
AST_NEGEDGE,
|
2016-06-18 03:24:21 -05:00
|
|
|
AST_EDGE,
|
|
|
|
|
2018-10-11 16:33:31 -05:00
|
|
|
AST_INTERFACE,
|
|
|
|
AST_INTERFACEPORT,
|
|
|
|
AST_INTERFACEPORTTYPE,
|
2018-10-12 13:58:37 -05:00
|
|
|
AST_MODPORT,
|
|
|
|
AST_MODPORTMEMBER,
|
2019-09-19 14:43:13 -05:00
|
|
|
AST_PACKAGE,
|
|
|
|
|
|
|
|
AST_WIRETYPE,
|
2020-05-08 08:40:49 -05:00
|
|
|
AST_TYPEDEF,
|
|
|
|
AST_STRUCT,
|
2020-05-12 08:25:33 -05:00
|
|
|
AST_UNION,
|
2020-05-21 11:36:29 -05:00
|
|
|
AST_STRUCT_ITEM,
|
|
|
|
AST_BIND
|
2013-01-05 04:13:26 -06:00
|
|
|
};
|
|
|
|
|
2020-02-23 01:19:52 -06:00
|
|
|
struct AstSrcLocType {
|
|
|
|
unsigned int first_line, last_line;
|
|
|
|
unsigned int first_column, last_column;
|
|
|
|
AstSrcLocType() : first_line(0), last_line(0), first_column(0), last_column(0) {}
|
|
|
|
AstSrcLocType(int _first_line, int _first_column, int _last_line, int _last_column) : first_line(_first_line), last_line(_last_line), first_column(_first_column), last_column(_last_column) {}
|
|
|
|
};
|
|
|
|
|
2013-01-05 04:13:26 -06:00
|
|
|
// convert an node type to a string (e.g. for debug output)
|
|
|
|
std::string type2str(AstNodeType type);
|
|
|
|
|
|
|
|
// The AST is built using instances of this struct
|
|
|
|
struct AstNode
|
|
|
|
{
|
2014-12-28 20:11:50 -06:00
|
|
|
// for dict<> and pool<>
|
|
|
|
unsigned int hashidx_;
|
|
|
|
unsigned int hash() const { return hashidx_; }
|
|
|
|
|
2013-01-05 04:13:26 -06:00
|
|
|
// this nodes type
|
|
|
|
AstNodeType type;
|
|
|
|
|
|
|
|
// the list of child nodes for this node
|
|
|
|
std::vector<AstNode*> children;
|
|
|
|
|
|
|
|
// the list of attributes assigned to this node
|
|
|
|
std::map<RTLIL::IdString, AstNode*> attributes;
|
2013-10-24 04:20:13 -05:00
|
|
|
bool get_bool_attribute(RTLIL::IdString id);
|
2013-01-05 04:13:26 -06:00
|
|
|
|
|
|
|
// node content - most of it is unused in most node types
|
|
|
|
std::string str;
|
|
|
|
std::vector<RTLIL::State> bits;
|
2019-09-19 14:43:13 -05:00
|
|
|
bool is_input, is_output, is_reg, is_logic, is_signed, is_string, is_wand, is_wor, range_valid, range_swapped, was_checked, is_unsized, is_custom_type;
|
2013-01-05 04:13:26 -06:00
|
|
|
int port_id, range_left, range_right;
|
|
|
|
uint32_t integer;
|
2014-06-13 04:29:23 -05:00
|
|
|
double realvalue;
|
2018-03-09 06:47:11 -06:00
|
|
|
// set for IDs typed to an enumeration, not used
|
|
|
|
bool is_enum;
|
2013-01-05 04:13:26 -06:00
|
|
|
|
2024-01-25 00:28:15 -06:00
|
|
|
// Declared range for array dimension.
|
|
|
|
struct dimension_t {
|
|
|
|
int range_right; // lsb in [msb:lsb]
|
|
|
|
int range_width; // msb - lsb + 1
|
|
|
|
bool range_swapped; // if the declared msb < lsb, msb and lsb above are swapped
|
|
|
|
};
|
|
|
|
// Packed and unpacked dimensions for arrays.
|
|
|
|
// Unpacked dimensions go first, to follow the order of indexing.
|
|
|
|
std::vector<dimension_t> dimensions;
|
|
|
|
// Number of unpacked dimensions.
|
|
|
|
int unpacked_dimensions;
|
2014-08-06 08:43:46 -05:00
|
|
|
|
2013-01-05 04:13:26 -06:00
|
|
|
// this is set by simplify and used during RTLIL generation
|
|
|
|
AstNode *id2ast;
|
|
|
|
|
2014-01-20 13:25:20 -06:00
|
|
|
// this is used by simplify to detect if basic analysis has been performed already on the node
|
|
|
|
bool basic_prep;
|
|
|
|
|
2020-04-15 13:36:40 -05:00
|
|
|
// this is used for ID references in RHS expressions that should use the "new" value for non-blocking assignments
|
|
|
|
bool lookahead;
|
|
|
|
|
2013-01-05 04:13:26 -06:00
|
|
|
// this is the original sourcecode location that resulted in this AST node
|
|
|
|
// it is automatically set by the constructor using AST::current_filename and
|
|
|
|
// the AST::get_line_num() callback function.
|
|
|
|
std::string filename;
|
2020-02-23 01:19:52 -06:00
|
|
|
AstSrcLocType location;
|
2013-01-05 04:13:26 -06:00
|
|
|
|
2023-04-05 04:00:07 -05:00
|
|
|
// are we embedded in an lvalue, param?
|
|
|
|
// (see fixup_hierarchy_flags)
|
|
|
|
bool in_lvalue;
|
|
|
|
bool in_param;
|
|
|
|
bool in_lvalue_from_above;
|
|
|
|
bool in_param_from_above;
|
|
|
|
|
2013-01-05 04:13:26 -06:00
|
|
|
// creating and deleting nodes
|
2021-05-20 19:27:06 -05:00
|
|
|
AstNode(AstNodeType type = AST_NONE, AstNode *child1 = nullptr, AstNode *child2 = nullptr, AstNode *child3 = nullptr, AstNode *child4 = nullptr);
|
2017-09-29 23:37:38 -05:00
|
|
|
AstNode *clone() const;
|
|
|
|
void cloneInto(AstNode *other) const;
|
2013-01-05 04:13:26 -06:00
|
|
|
void delete_children();
|
|
|
|
~AstNode();
|
|
|
|
|
2013-11-21 06:49:00 -06:00
|
|
|
enum mem2reg_flags
|
|
|
|
{
|
|
|
|
/* status flags */
|
|
|
|
MEM2REG_FL_ALL = 0x00000001,
|
|
|
|
MEM2REG_FL_ASYNC = 0x00000002,
|
|
|
|
MEM2REG_FL_INIT = 0x00000004,
|
|
|
|
|
|
|
|
/* candidate flags */
|
|
|
|
MEM2REG_FL_FORCED = 0x00000100,
|
|
|
|
MEM2REG_FL_SET_INIT = 0x00000200,
|
|
|
|
MEM2REG_FL_SET_ELSE = 0x00000400,
|
|
|
|
MEM2REG_FL_SET_ASYNC = 0x00000800,
|
|
|
|
MEM2REG_FL_EQ2 = 0x00001000,
|
2014-06-17 14:39:25 -05:00
|
|
|
MEM2REG_FL_CMPLX_LHS = 0x00002000,
|
2019-03-01 15:35:09 -06:00
|
|
|
MEM2REG_FL_CONST_LHS = 0x00004000,
|
|
|
|
MEM2REG_FL_VAR_LHS = 0x00008000,
|
2013-11-21 06:49:00 -06:00
|
|
|
|
|
|
|
/* proc flags */
|
|
|
|
MEM2REG_FL_EQ1 = 0x01000000,
|
|
|
|
};
|
|
|
|
|
2013-01-05 04:13:26 -06:00
|
|
|
// simplify() creates a simpler AST by unrolling for-loops, expanding generate blocks, etc.
|
|
|
|
// it also sets the id2ast pointers so that identifier lookups are fast in genRTLIL()
|
2023-04-04 15:59:44 -05:00
|
|
|
bool simplify(bool const_fold, int stage, int width_hint, bool sign_hint);
|
2020-12-31 18:23:36 -06:00
|
|
|
void replace_result_wire_name_in_function(const std::string &from, const std::string &to);
|
2015-07-31 03:40:09 -05:00
|
|
|
AstNode *readmem(bool is_readmemh, std::string mem_filename, AstNode *memory, int start_addr, int finish_addr, bool unconditional_init);
|
verilog: significant block scoping improvements
This change set contains a number of bug fixes and improvements related to
scoping and resolution in generate and procedural blocks. While many of the
frontend changes are interdependent, it may be possible bring the techmap
changes in under a separate PR.
Declarations within unnamed generate blocks previously encountered issues
because the data declarations were left un-prefixed, breaking proper scoping.
The LRM outlines behavior for generating names for unnamed generate blocks. The
original goal was to add this implicit labelling, but doing so exposed a number
of issues downstream. Additional testing highlighted other closely related scope
resolution issues, which have been fixed. This change also adds support for
block item declarations within unnamed blocks in SystemVerilog mode.
1. Unlabled generate blocks are now implicitly named according to the LRM in
`label_genblks`, which is invoked at the beginning of module elaboration
2. The Verilog parser no longer wraps explicitly named generate blocks in a
synthetic unnamed generate block to avoid creating extra hierarchy levels
where they should not exist
3. The techmap phase now allows special control identifiers to be used outside
of the topmost scope, which is necessary because such wires and cells often
appear in unlabeled generate blocks, which now prefix the declarations within
4. Some techlibs required modifications because they relied on the previous
invalid scope resolution behavior
5. `expand_genblock` has been simplified, now only expanding the outermost
scope, completely deferring the inspection and elaboration of nested scopes;
names are now resolved by looking in the innermost scope and stepping outward
6. Loop variables now always become localparams during unrolling, allowing them
to be resolved and shadowed like any other identifier
7. Identifiers in synthetic function call scopes are now prefixed and resolved
in largely the same manner as other blocks
before: `$func$\func_01$tests/simple/scopes.blk.v:60$5$\blk\x`
after: `\func_01$func$tests/simple/scopes.v:60$5.blk.x`
8. Support identifiers referencing a local generate scope nested more
than 1 level deep, i.e. `B.C.x` while within generate scope `A`, or using a
prefix of a current or parent scope, i.e. `B.C.D.x` while in `A.B`, `A.B.C`,
or `A.B.C.D`
9. Variables can now be declared within unnamed blocks in SystemVerilog mode
Addresses the following issues: 656, 2423, 2493
2021-01-27 12:30:22 -06:00
|
|
|
void expand_genblock(const std::string &prefix);
|
|
|
|
void label_genblks(std::set<std::string>& existing, int &counter);
|
2014-12-28 20:11:50 -06:00
|
|
|
void mem2reg_as_needed_pass1(dict<AstNode*, pool<std::string>> &mem2reg_places,
|
|
|
|
dict<AstNode*, uint32_t> &mem2reg_flags, dict<AstNode*, uint32_t> &proc_flags, uint32_t &status_flags);
|
2016-08-21 06:23:58 -05:00
|
|
|
bool mem2reg_as_needed_pass2(pool<AstNode*> &mem2reg_set, AstNode *mod, AstNode *block, AstNode *&async_block);
|
2014-12-28 20:11:50 -06:00
|
|
|
bool mem2reg_check(pool<AstNode*> &mem2reg_set);
|
2016-05-27 10:25:33 -05:00
|
|
|
void mem2reg_remove(pool<AstNode*> &mem2reg_set, vector<AstNode*> &delnodes);
|
2013-01-05 04:13:26 -06:00
|
|
|
void meminfo(int &mem_width, int &mem_size, int &addr_bits);
|
2020-06-04 16:10:03 -05:00
|
|
|
bool detect_latch(const std::string &var);
|
2021-10-19 19:46:26 -05:00
|
|
|
const RTLIL::Module* lookup_cell_module();
|
2013-01-05 04:13:26 -06:00
|
|
|
|
2014-02-14 12:56:44 -06:00
|
|
|
// additional functionality for evaluating constant functions
|
2021-02-21 13:45:21 -06:00
|
|
|
struct varinfo_t {
|
|
|
|
RTLIL::Const val;
|
|
|
|
int offset;
|
2022-01-12 00:51:08 -06:00
|
|
|
bool range_swapped;
|
2021-02-21 13:45:21 -06:00
|
|
|
bool is_signed;
|
|
|
|
AstNode *arg = nullptr;
|
|
|
|
bool explicitly_sized;
|
|
|
|
};
|
2021-01-27 12:21:13 -06:00
|
|
|
bool has_const_only_constructs();
|
|
|
|
bool replace_variables(std::map<std::string, varinfo_t> &variables, AstNode *fcall, bool must_succeed);
|
|
|
|
AstNode *eval_const_function(AstNode *fcall, bool must_succeed);
|
2019-03-02 14:36:46 -06:00
|
|
|
bool is_simple_const_expr();
|
2020-11-29 08:34:17 -06:00
|
|
|
|
|
|
|
// helper for parsing format strings
|
2023-09-22 10:56:34 -05:00
|
|
|
Fmt processFormat(int stage, bool sformat_like, int default_base = 10, size_t first_arg_at = 0, bool may_fail = false);
|
2014-02-14 12:56:44 -06:00
|
|
|
|
2021-02-12 13:25:34 -06:00
|
|
|
bool is_recursive_function() const;
|
|
|
|
std::pair<AstNode*, AstNode*> get_tern_choice();
|
|
|
|
|
2013-01-05 04:13:26 -06:00
|
|
|
// create a human-readable text representation of the AST (for debugging)
|
2017-09-29 23:37:38 -05:00
|
|
|
void dumpAst(FILE *f, std::string indent) const;
|
|
|
|
void dumpVlog(FILE *f, std::string indent) const;
|
2013-01-05 04:13:26 -06:00
|
|
|
|
2020-04-20 10:06:53 -05:00
|
|
|
// Generate RTLIL for a bind construct
|
|
|
|
std::vector<RTLIL::Binding *> genBindings() const;
|
|
|
|
|
2013-07-09 07:31:57 -05:00
|
|
|
// used by genRTLIL() for detecting expression width and sign
|
2014-06-16 08:00:57 -05:00
|
|
|
void detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *found_real = NULL);
|
|
|
|
void detectSignWidth(int &width_hint, bool &sign_hint, bool *found_real = NULL);
|
2013-07-09 07:31:57 -05:00
|
|
|
|
2013-01-05 04:13:26 -06:00
|
|
|
// create RTLIL code for this AST node
|
|
|
|
// for expressions the resulting signal vector is returned
|
|
|
|
// all generated cell instances, etc. are written to the RTLIL::Module pointed to by AST_INTERNAL::current_module
|
2013-07-09 07:31:57 -05:00
|
|
|
RTLIL::SigSpec genRTLIL(int width_hint = -1, bool sign_hint = false);
|
2021-03-25 13:06:05 -05:00
|
|
|
RTLIL::SigSpec genWidthRTLIL(int width, bool sgn, const dict<RTLIL::SigBit, RTLIL::SigBit> *new_subst_ptr = NULL);
|
2013-01-05 04:13:26 -06:00
|
|
|
|
|
|
|
// compare AST nodes
|
|
|
|
bool operator==(const AstNode &other) const;
|
|
|
|
bool operator!=(const AstNode &other) const;
|
|
|
|
bool contains(const AstNode *other) const;
|
|
|
|
|
|
|
|
// helper functions for creating AST nodes for constants
|
|
|
|
static AstNode *mkconst_int(uint32_t v, bool is_signed, int width = 32);
|
2019-05-27 04:42:10 -05:00
|
|
|
static AstNode *mkconst_bits(const std::vector<RTLIL::State> &v, bool is_signed, bool is_unsized);
|
2013-01-05 04:13:26 -06:00
|
|
|
static AstNode *mkconst_bits(const std::vector<RTLIL::State> &v, bool is_signed);
|
2013-12-05 06:26:17 -06:00
|
|
|
static AstNode *mkconst_str(const std::vector<RTLIL::State> &v);
|
2013-12-05 05:53:49 -06:00
|
|
|
static AstNode *mkconst_str(const std::string &str);
|
2013-11-02 07:00:17 -05:00
|
|
|
|
2023-12-08 13:47:43 -06:00
|
|
|
// helper function to create an AST node for a temporary register
|
|
|
|
AstNode *mktemp_logic(const std::string &name, AstNode *mod, bool nosync, int range_left, int range_right, bool is_signed);
|
|
|
|
|
2013-11-02 07:00:17 -05:00
|
|
|
// helper function for creating sign-extended const objects
|
|
|
|
RTLIL::Const bitsAsConst(int width, bool is_signed);
|
|
|
|
RTLIL::Const bitsAsConst(int width = -1);
|
2019-05-27 04:42:10 -05:00
|
|
|
RTLIL::Const bitsAsUnsizedConst(int width);
|
2021-10-19 19:46:26 -05:00
|
|
|
RTLIL::Const asAttrConst() const;
|
|
|
|
RTLIL::Const asParaConst() const;
|
2014-08-21 10:11:51 -05:00
|
|
|
uint64_t asInt(bool is_signed);
|
2017-09-29 23:37:38 -05:00
|
|
|
bool bits_only_01() const;
|
|
|
|
bool asBool() const;
|
2014-06-14 01:51:22 -05:00
|
|
|
|
|
|
|
// helper functions for real valued const eval
|
2017-09-29 23:37:38 -05:00
|
|
|
int isConst() const; // return '1' for AST_CONSTANT and '2' for AST_REALVALUE
|
2014-06-14 01:51:22 -05:00
|
|
|
double asReal(bool is_signed);
|
2014-06-14 13:38:05 -05:00
|
|
|
RTLIL::Const realAsConst(int width);
|
2018-03-09 06:47:11 -06:00
|
|
|
|
|
|
|
// helpers for enum
|
|
|
|
void allocateDefaultEnumValues();
|
2020-05-08 08:40:49 -05:00
|
|
|
void annotateTypedEnums(AstNode *template_node);
|
2021-02-23 12:22:53 -06:00
|
|
|
|
|
|
|
// helpers for locations
|
|
|
|
std::string loc_string() const;
|
2021-06-05 15:21:09 -05:00
|
|
|
|
|
|
|
// Helper for looking up identifiers which are prefixed with the current module name
|
|
|
|
std::string try_pop_module_prefix() const;
|
2023-04-04 04:53:50 -05:00
|
|
|
|
2023-06-21 06:45:42 -05:00
|
|
|
// helper to clone the node with some of its subexpressions replaced with zero (this is used
|
|
|
|
// to evaluate widths of dynamic ranges)
|
|
|
|
AstNode *clone_at_zero();
|
|
|
|
|
2023-04-05 04:00:07 -05:00
|
|
|
void set_attribute(RTLIL::IdString key, AstNode *node)
|
|
|
|
{
|
|
|
|
attributes[key] = node;
|
|
|
|
node->set_in_param_flag(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
// helper to set in_lvalue/in_param flags from the hierarchy context (the actual flag
|
|
|
|
// can be overridden based on the intrinsic properties of this node, i.e. based on its type)
|
|
|
|
void set_in_lvalue_flag(bool flag, bool no_descend = false);
|
|
|
|
void set_in_param_flag(bool flag, bool no_descend = false);
|
|
|
|
|
|
|
|
// fix up the hierarchy flags (in_lvalue/in_param) of this node and its children
|
|
|
|
//
|
|
|
|
// to keep the flags in sync, fixup_hierarchy_flags(true) needs to be called once after
|
|
|
|
// parsing the AST to walk the full tree, then plain fixup_hierarchy_flags() performs
|
|
|
|
// localized fixups after modifying children/attributes of a particular node
|
|
|
|
void fixup_hierarchy_flags(bool force_descend = false);
|
|
|
|
|
2024-01-25 00:28:15 -06:00
|
|
|
// helpers for indexing
|
|
|
|
AstNode *make_index_range(AstNode *node, bool unpacked_range = false);
|
|
|
|
AstNode *get_struct_member() const;
|
|
|
|
|
2023-04-04 04:53:50 -05:00
|
|
|
// helper to print errors from simplify/genrtlil code
|
|
|
|
[[noreturn]] void input_error(const char *format, ...) const YS_ATTRIBUTE(format(printf, 2, 3));
|
2013-01-05 04:13:26 -06:00
|
|
|
};
|
|
|
|
|
|
|
|
// process an AST tree (ast must point to an AST_DESIGN node) and generate RTLIL code
|
2024-01-11 03:32:44 -06:00
|
|
|
void process(RTLIL::Design *design, AstNode *ast, bool nodisplay, bool dump_ast1, bool dump_ast2, bool no_dump_ptr, bool dump_vlog1, bool dump_vlog2, bool dump_rtlil, bool nolatches, bool nomeminit,
|
2019-06-19 07:38:50 -05:00
|
|
|
bool nomem2reg, bool mem2reg, bool noblackbox, bool lib, bool nowb, bool noopt, bool icells, bool pwires, bool nooverwrite, bool overwrite, bool defer, bool autowire);
|
2013-01-05 04:13:26 -06:00
|
|
|
|
|
|
|
// parametric modules are supported directly by the AST library
|
2015-08-14 03:56:05 -05:00
|
|
|
// therefore we need our own derivate of RTLIL::Module with overloaded virtual functions
|
2013-01-05 04:13:26 -06:00
|
|
|
struct AstModule : RTLIL::Module {
|
|
|
|
AstNode *ast;
|
2019-06-19 07:38:50 -05:00
|
|
|
bool nolatches, nomeminit, nomem2reg, mem2reg, noblackbox, lib, nowb, noopt, icells, pwires, autowire;
|
2020-06-18 18:34:52 -05:00
|
|
|
~AstModule() override;
|
|
|
|
RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, bool mayfail) override;
|
|
|
|
RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, const dict<RTLIL::IdString, RTLIL::Module*> &interfaces, const dict<RTLIL::IdString, RTLIL::IdString> &modports, bool mayfail) override;
|
2020-03-18 13:21:53 -05:00
|
|
|
std::string derive_common(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, AstNode **new_ast_out, bool quiet = false);
|
2021-10-19 19:43:30 -05:00
|
|
|
void expand_interfaces(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Module *> &local_interfaces) override;
|
2021-10-19 19:46:26 -05:00
|
|
|
bool reprocess_if_necessary(RTLIL::Design *design) override;
|
2020-06-18 18:34:52 -05:00
|
|
|
RTLIL::Module *clone() const override;
|
2019-09-20 05:16:20 -05:00
|
|
|
void loadconfig() const;
|
2013-01-05 04:13:26 -06:00
|
|
|
};
|
|
|
|
|
|
|
|
// this must be set by the language frontend before parsing the sources
|
|
|
|
// the AstNode constructor then uses current_filename and get_line_num()
|
|
|
|
// to initialize the filename and linenum properties of new nodes
|
|
|
|
extern std::string current_filename;
|
|
|
|
extern void (*set_line_num)(int);
|
|
|
|
extern int (*get_line_num)();
|
|
|
|
|
2013-11-24 10:29:11 -06:00
|
|
|
// set set_line_num and get_line_num to internal dummy functions (done by simplify() and AstModule::derive
|
|
|
|
// to control the filename and linenum properties of new nodes not generated by a frontend parser)
|
2013-01-05 04:13:26 -06:00
|
|
|
void use_internal_line_num();
|
2014-08-21 05:43:51 -05:00
|
|
|
|
|
|
|
// call a DPI function
|
|
|
|
AstNode *dpi_call(const std::string &rtype, const std::string &fname, const std::vector<std::string> &argtypes, const std::vector<AstNode*> &args);
|
2018-10-20 05:45:51 -05:00
|
|
|
|
|
|
|
// Helper functions related to handling SystemVerilog interfaces
|
|
|
|
std::pair<std::string,std::string> split_modport_from_type(std::string name_type);
|
|
|
|
AstNode * find_modport(AstNode *intf, std::string name);
|
|
|
|
void explode_interface_port(AstNode *module_ast, RTLIL::Module * intfmodule, std::string intfname, AstNode *modport);
|
2021-02-23 12:22:53 -06:00
|
|
|
|
|
|
|
// Helper for setting the src attribute.
|
|
|
|
void set_src_attr(RTLIL::AttrObject *obj, const AstNode *ast);
|
2021-06-22 09:39:57 -05:00
|
|
|
|
2021-10-19 19:46:26 -05:00
|
|
|
// generate standard $paramod... derived module name; parameters should be
|
|
|
|
// in the order they are declared in the instantiated module
|
|
|
|
std::string derived_module_name(std::string stripped_name, const std::vector<std::pair<RTLIL::IdString, RTLIL::Const>> ¶meters);
|
|
|
|
|
|
|
|
// used to provide simplify() access to the current design for looking up
|
|
|
|
// modules, ports, wires, etc.
|
|
|
|
void set_simplify_design_context(const RTLIL::Design *design);
|
2013-01-05 04:13:26 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
namespace AST_INTERNAL
|
|
|
|
{
|
|
|
|
// internal state variables
|
2024-01-11 03:32:44 -06:00
|
|
|
extern bool flag_nodisplay, flag_dump_ast1, flag_dump_ast2, flag_no_dump_ptr, flag_dump_rtlil, flag_nolatches, flag_nomeminit;
|
2019-06-19 07:38:50 -05:00
|
|
|
extern bool flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells, flag_pwires, flag_autowire;
|
2013-01-05 04:13:26 -06:00
|
|
|
extern AST::AstNode *current_ast, *current_ast_mod;
|
|
|
|
extern std::map<std::string, AST::AstNode*> current_scope;
|
2014-12-28 12:24:24 -06:00
|
|
|
extern const dict<RTLIL::SigBit, RTLIL::SigBit> *genRTLIL_subst_ptr;
|
2014-08-14 16:02:07 -05:00
|
|
|
extern RTLIL::SigSpec ignoreThisSignalsInInitial;
|
2015-02-14 03:49:30 -06:00
|
|
|
extern AST::AstNode *current_always, *current_top_block, *current_block, *current_block_child;
|
2020-04-20 08:41:55 -05:00
|
|
|
extern RTLIL::Module *current_module;
|
2016-09-06 10:34:42 -05:00
|
|
|
extern bool current_always_clocked;
|
2021-02-23 09:48:29 -06:00
|
|
|
extern dict<std::string, int> current_memwr_count;
|
|
|
|
extern dict<std::string, pool<int>> current_memwr_visible;
|
2020-04-15 13:36:40 -05:00
|
|
|
struct LookaheadRewriter;
|
2013-01-05 04:13:26 -06:00
|
|
|
struct ProcessGenerator;
|
2021-10-19 19:43:30 -05:00
|
|
|
|
|
|
|
// Create and add a new AstModule from new_ast, then use it to replace
|
|
|
|
// old_module in design, renaming old_module to move it out of the way.
|
|
|
|
// Return the new module.
|
|
|
|
//
|
|
|
|
// If original_ast is not null, it will be used as the AST node for the
|
|
|
|
// new module. Otherwise, new_ast will be used.
|
|
|
|
RTLIL::Module *
|
|
|
|
process_and_replace_module(RTLIL::Design *design,
|
|
|
|
RTLIL::Module *old_module,
|
|
|
|
AST::AstNode *new_ast,
|
|
|
|
AST::AstNode *original_ast = nullptr);
|
2013-01-05 04:13:26 -06:00
|
|
|
}
|
|
|
|
|
2014-07-31 06:19:47 -05:00
|
|
|
YOSYS_NAMESPACE_END
|
|
|
|
|
2013-01-05 04:13:26 -06:00
|
|
|
#endif
|