mirror of https://github.com/YosysHQ/yosys.git
Fixups
This commit is contained in:
parent
5efc95f7d9
commit
507d43a9b8
|
|
@ -34,7 +34,7 @@ jobs:
|
|||
run: cd verific/tclmain && make -j6
|
||||
|
||||
- name: Build
|
||||
run: make yosys -j6 ENABLE_CCACHE=0
|
||||
run: make yosys -j6
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v3
|
||||
|
|
|
|||
|
|
@ -70,8 +70,8 @@ jobs:
|
|||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
make -f ../Makefile config-$CC SMALL=0 ENABLE_ABC=1 ENABLE_PLUGINS=1 ENABLE_PYOSYS=0 ENABLE_CCACHE=0 ENABLE_EDITLINE=0 VERIFIC_DIR=../verific
|
||||
make -f ../Makefile -j$procs ENABLE_LTO=1 SMALL=0 ENABLE_ABC=1 ENABLE_PLUGINS=1 ENABLE_PYOSYS=0 ENABLE_CCACHE=0 ENABLE_EDITLINE=0 VERIFIC_DIR=../verific
|
||||
make -f ../Makefile config-$CC SMALL=0 ENABLE_PLUGINS=1 ENABLE_PYOSYS=0 ENABLE_CCACHE=0 ENABLE_EDITLINE=0 VERIFIC_DIR=../verific
|
||||
make -f ../Makefile -j$procs ENABLE_LTO=1 SMALL=0 ENABLE_PLUGINS=1 ENABLE_PYOSYS=0 ENABLE_CCACHE=0 ENABLE_EDITLINE=0 VERIFIC_DIR=../verific
|
||||
|
||||
- name: Log yosys-config output
|
||||
run: |
|
||||
|
|
@ -174,7 +174,7 @@ jobs:
|
|||
- name: Run tests
|
||||
shell: bash
|
||||
run: |
|
||||
make -j$procs test TARGETS= EXTRA_TARGETS= CONFIG=$CC SMALL=0 ENABLE_ABC=1 ENABLE_PLUGINS=1 ENABLE_PYOSYS=0 ENABLE_CCACHE=0 ENABLE_EDITLINE=0
|
||||
make -j$procs test TARGETS= EXTRA_TARGETS= CONFIG=$CC SMALL=0 ENABLE_PLUGINS=1 ENABLE_PYOSYS=0 ENABLE_CCACHE=0 ENABLE_EDITLINE=0
|
||||
|
||||
- name: Report errors
|
||||
if: ${{ failure() }}
|
||||
|
|
@ -261,13 +261,13 @@ jobs:
|
|||
- name: Run tests
|
||||
shell: bash
|
||||
run: |
|
||||
make -C docs test -j${{ env.procs }} SMALL=0 ENABLE_ABC=1 ENABLE_PLUGINS=1 ENABLE_PYOSYS=0 ENABLE_CCACHE=0 ENABLE_EDITLINE=0
|
||||
make -C docs test -j${{ env.procs }} SMALL=0 ENABLE_PLUGINS=1 ENABLE_PYOSYS=0 ENABLE_CCACHE=0 ENABLE_EDITLINE=0
|
||||
|
||||
test-docs-build:
|
||||
name: Try build docs
|
||||
runs-on: [self-hosted, linux, x64, fast]
|
||||
needs: [pre_docs_job]
|
||||
if: false
|
||||
if: ${{ needs.pre_docs_job.outputs.should_skip != 'true' && github.repository == 'YosysHQ/Yosys' }}
|
||||
strategy:
|
||||
matrix:
|
||||
docs-target: [html, latexpdf]
|
||||
|
|
|
|||
|
|
@ -96,9 +96,9 @@ jobs:
|
|||
- name: Build
|
||||
shell: bash
|
||||
run: |
|
||||
make config-$CC SMALL=0 ENABLE_ABC=1 ENABLE_PLUGINS=1 ENABLE_PYOSYS=0 ENABLE_CCACHE=0 ENABLE_EDITLINE=0 ENABLE_VERIFIC=0
|
||||
make config-$CC SMALL=0 ENABLE_PLUGINS=1 ENABLE_PYOSYS=0 ENABLE_CCACHE=0 ENABLE_EDITLINE=0 ENABLE_VERIFIC=0
|
||||
echo 'SANITIZER = ${{ matrix.sanitizer }}' >> Makefile.conf
|
||||
make -j$procs ENABLE_LTO=1 SMALL=0 ENABLE_ABC=1 ENABLE_PLUGINS=1 ENABLE_PYOSYS=0 ENABLE_CCACHE=0 ENABLE_EDITLINE=0 ENABLE_VERIFIC=0
|
||||
make -j$procs ENABLE_LTO=1 SMALL=0 ENABLE_PLUGINS=1 ENABLE_PYOSYS=0 ENABLE_CCACHE=0 ENABLE_EDITLINE=0 ENABLE_VERIFIC=0
|
||||
|
||||
- name: Log yosys-config output
|
||||
run: |
|
||||
|
|
@ -107,7 +107,7 @@ jobs:
|
|||
- name: Run tests
|
||||
shell: bash
|
||||
run: |
|
||||
make -j$procs test TARGETS= EXTRA_TARGETS= CONFIG=$CC SMALL=0 ENABLE_ABC=1 ENABLE_PLUGINS=1 ENABLE_PYOSYS=0 ENABLE_CCACHE=0 ENABLE_EDITLINE=0 ENABLE_VERIFIC=0
|
||||
make -j$procs test TARGETS= EXTRA_TARGETS= CONFIG=$CC SMALL=0 ENABLE_PLUGINS=1 ENABLE_PYOSYS=0 ENABLE_CCACHE=0 ENABLE_EDITLINE=0 ENABLE_VERIFIC=0
|
||||
|
||||
- name: Report errors
|
||||
if: ${{ failure() }}
|
||||
|
|
|
|||
|
|
@ -122,3 +122,25 @@ jobs:
|
|||
with:
|
||||
name: python-wheels-${{ matrix.os.runner }}
|
||||
path: ./wheelhouse/*.whl
|
||||
upload_wheels:
|
||||
name: Upload Wheels
|
||||
if: github.repository == 'YosysHQ/Yosys'
|
||||
runs-on: ubuntu-latest
|
||||
# Specifying a GitHub environment is optional, but strongly encouraged
|
||||
environment: pypi
|
||||
permissions:
|
||||
# IMPORTANT: this permission is mandatory for Trusted Publishing
|
||||
id-token: write
|
||||
needs: build_wheels
|
||||
steps:
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
path: "."
|
||||
pattern: python-wheels-*
|
||||
merge-multiple: true
|
||||
- run: |
|
||||
ls
|
||||
mkdir -p ./dist
|
||||
mv *.whl ./dist
|
||||
- name: Publish
|
||||
uses: pypa/gh-action-pypi-publish@release/v1
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
## user config
|
||||
/Makefile.conf
|
||||
|
||||
## brew
|
||||
## homebrew
|
||||
/Brewfile.lock.json
|
||||
|
||||
## build artifacts
|
||||
|
|
|
|||
2
Makefile
2
Makefile
|
|
@ -963,7 +963,7 @@ SH_TEST_DIRS += tests/simple
|
|||
SH_TEST_DIRS += tests/simple_abc9
|
||||
SH_TEST_DIRS += tests/hana
|
||||
SH_TEST_DIRS += tests/asicworld
|
||||
SH_TEST_DIRS += tests/realmath
|
||||
# SH_TEST_DIRS += tests/realmath
|
||||
SH_TEST_DIRS += tests/share
|
||||
SH_TEST_DIRS += tests/opt_share
|
||||
SH_TEST_DIRS += tests/fsm
|
||||
|
|
|
|||
|
|
@ -1,77 +0,0 @@
|
|||
/*
|
||||
* yosys -- Yosys Open SYnthesis Suite
|
||||
*
|
||||
* Copyright (C) 2012 Claire Xenia Wolf <claire@yosyshq.com>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
#ifdef VERIFIC_LINEFILE_INCLUDES_LOOPS
|
||||
#include <stack>
|
||||
/*
|
||||
This Visitor decorates the AST with a loop ID attribute for all outer for loops.
|
||||
All AST nodes contained within the subtree of an outer for-loop
|
||||
have the same ID carried as an additional payload of the "linefile" struct.
|
||||
The ID is unique accross the flat RTL module set, as it is computed before elaboration.
|
||||
It is not unique per instance of the modules.
|
||||
A further separation of cells belonging to a given loop instance is necessary by means of
|
||||
connectivity analysis.
|
||||
No "loop instance" information seems to exist to cluster those loops elements together unfortunately.
|
||||
*/
|
||||
class DecorateLoopsVisitor : public VeriVisitor
|
||||
{
|
||||
public:
|
||||
DecorateLoopsVisitor() : VeriVisitor() {};
|
||||
~DecorateLoopsVisitor() {};
|
||||
virtual void VERI_VISIT(VeriLoop, node)
|
||||
{
|
||||
// std::cout << "Loop in: " << (VeriLoop *)&node << " id: " << outerLoopId << std::endl;
|
||||
if (loopStack.empty()) {
|
||||
// We increase the loop count when we enter a new set of imbricated loops,
|
||||
// That way we have a loop index for the outermost loop as we want to identify and group
|
||||
// logic generated by imbricated loops
|
||||
outerLoopId = node.Linefile();
|
||||
}
|
||||
loopStack.push((VeriLoop *)&node);
|
||||
}
|
||||
|
||||
void PreAction(VeriTreeNode & /*node*/)
|
||||
{
|
||||
// VeriNode *vnode = dynamic_cast<VeriNode *>(&node);
|
||||
// std::cout << "Node pre: " << vnode << std::endl;
|
||||
}
|
||||
|
||||
virtual void PostAction(VeriTreeNode &node)
|
||||
{
|
||||
// std::cout << "Node post: " << (VeriTreeNode *)&node << std::endl;
|
||||
if (loopStack.size()) {
|
||||
if (loopStack.top() == (VeriLoop *)&node) {
|
||||
loopStack.pop();
|
||||
// std::cout << "Loop out: " << (VeriFor *)&node << std::endl;
|
||||
return;
|
||||
}
|
||||
Verific::linefile_type linefile = (Verific::linefile_type)node.Linefile();
|
||||
// Unfortunately there is no good way to systematically copy certain AST attributes to the Netlist attributes like:
|
||||
// VeriNode *vnode = dynamic_cast<VeriNode *>(&node);
|
||||
// vnode->AddAttribute(" in_loop", new VeriIntVal(outerLoopId));
|
||||
// Instead using linefile struct to pass that information:
|
||||
if (linefile)
|
||||
linefile->SetInLoop(outerLoopId);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::stack<VeriLoop *> loopStack;
|
||||
linefile_type outerLoopId = nullptr;
|
||||
};
|
||||
#endif
|
||||
|
|
@ -55,10 +55,6 @@ USING_YOSYS_NAMESPACE
|
|||
#include "VeriWrite.h"
|
||||
#include "VeriLibrary.h"
|
||||
#include "VeriExpression.h"
|
||||
#ifdef VERIFIC_LINEFILE_INCLUDES_LOOPS
|
||||
#include "VeriStatement.h"
|
||||
#include "VeriConstVal.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef VERIFIC_VHDL_SUPPORT
|
||||
|
|
@ -109,10 +105,6 @@ using namespace Verific;
|
|||
|
||||
#endif
|
||||
|
||||
#ifdef VERIFIC_LINEFILE_INCLUDES_LOOPS
|
||||
#include "decorate_loops.h"
|
||||
#endif
|
||||
|
||||
#ifdef YOSYS_ENABLE_VERIFIC
|
||||
YOSYS_NAMESPACE_BEGIN
|
||||
|
||||
|
|
@ -436,11 +428,6 @@ void VerificImporter::import_attributes(dict<RTLIL::IdString, RTLIL::Const> &att
|
|||
#ifdef VERIFIC_LINEFILE_INCLUDES_COLUMNS
|
||||
if (obj->Linefile()) {
|
||||
attributes[ID::src] = stringf("%s:%d.%d-%d.%d", LineFile::GetFileName(obj->Linefile()), obj->Linefile()->GetLeftLine(), obj->Linefile()->GetLeftCol(), obj->Linefile()->GetRightLine(), obj->Linefile()->GetRightCol());
|
||||
#ifdef VERIFIC_LINEFILE_INCLUDES_LOOPS
|
||||
if (linefile_type loopid = obj->Linefile()->GetInLoop()) {
|
||||
attributes[RTLIL::escape_id("in_for_loop")] = stringf("%s:%d.%d-%d.%d", LineFile::GetFileName(loopid), loopid->GetLeftLine(), loopid->GetLeftCol(), loopid->GetRightLine(), loopid->GetRightCol());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
if (obj->Linefile())
|
||||
|
|
@ -2962,7 +2949,7 @@ std::set<std::string> import_tops(const char* work, std::map<std::string,Netlist
|
|||
continue;
|
||||
}
|
||||
#else
|
||||
(void) top; // silience warnings
|
||||
(void) top; // silence warnings
|
||||
#endif
|
||||
log_error("Can't find module/unit '%s'.\n", name);
|
||||
}
|
||||
|
|
@ -2998,7 +2985,6 @@ std::set<std::string> import_tops(const char* work, std::map<std::string,Netlist
|
|||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef VERIFIC_HIER_TREE_SUPPORT
|
||||
if (show_message)
|
||||
log("Running hier_tree::Elaborate().\n");
|
||||
|
|
@ -3098,17 +3084,6 @@ std::string verific_import(Design *design, const std::map<std::string,std::strin
|
|||
for (const auto &i : parameters)
|
||||
verific_params.Insert(i.first.c_str(), i.second.c_str());
|
||||
|
||||
#ifdef VERIFIC_LINEFILE_INCLUDES_LOOPS
|
||||
VeriLibrary* veri_lib = veri_file::GetLibrary("work", 1);
|
||||
// Decorate AST with loop scope id
|
||||
VeriModule *module;
|
||||
MapIter mi;
|
||||
DecorateLoopsVisitor loop_visitor;
|
||||
FOREACH_VERILOG_MODULE_IN_LIBRARY(veri_lib, mi, module) {
|
||||
module->Accept(loop_visitor);
|
||||
}
|
||||
#endif
|
||||
|
||||
std::set<std::string> top_mod_names;
|
||||
if (top.empty()) {
|
||||
import_all("work", &nl_todo, &verific_params, false, "");
|
||||
|
|
@ -3188,7 +3163,7 @@ bool check_noverific_env()
|
|||
#endif
|
||||
|
||||
struct VerificPass : public Pass {
|
||||
VerificPass() : Pass("verific", "load Verilog and VHDL designs using VERIFIC") { }
|
||||
VerificPass() : Pass("verific", "load Verilog and VHDL designs using Verific") { }
|
||||
|
||||
#ifdef YOSYSHQ_VERIFIC_EXTENSIONS
|
||||
void on_register() override { VerificExtensions::Reset(); }
|
||||
|
|
@ -3600,7 +3575,6 @@ struct VerificPass : public Pass {
|
|||
// WARNING: instantiating unknown module 'XYZ' (VERI-1063)
|
||||
Message::SetMessageType("VERI-1063", VERIFIC_ERROR);
|
||||
|
||||
/* SILIMATE: do not downgrade warnings about things that are "normal"
|
||||
// Downgrade warnings about things that are normal
|
||||
// VERIFIC-WARNING [VERI-1209] foo.sv:98: expression size 7 truncated to fit in target size 6
|
||||
Message::SetMessageType("VERI-1209", VERIFIC_INFO);
|
||||
|
|
@ -3608,7 +3582,6 @@ struct VerificPass : public Pass {
|
|||
Message::SetMessageType("VERI-1142", VERIFIC_INFO);
|
||||
// VERIFIC-WARNING [VERI-2418] foo.svh:503: parameter 'all_cfgs_gp' declared inside package 'bp_common_pkg' shall be treated as localparam
|
||||
Message::SetMessageType("VERI-2418", VERIFIC_INFO);
|
||||
*/
|
||||
|
||||
// https://github.com/YosysHQ/yosys/issues/1055
|
||||
RuntimeFlags::SetVar("veri_elaborate_top_level_modules_having_interface_ports", 1) ;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ OBJS += passes/silimate/annotate_unqcoef.o
|
|||
OBJS += passes/silimate/breakreduce.o
|
||||
OBJS += passes/silimate/breaksop.o
|
||||
OBJS += passes/silimate/bus_rebuild.o
|
||||
OBJS += passes/silimate/longloop_select.o
|
||||
OBJS += passes/silimate/lut2bmux.o
|
||||
OBJS += passes/silimate/obs_clean.o
|
||||
OBJS += passes/silimate/opt_balance_tree.o
|
||||
|
|
|
|||
|
|
@ -1,257 +0,0 @@
|
|||
/*
|
||||
* yosys -- Yosys Open SYnthesis Suite
|
||||
*
|
||||
* Copyright (C) 2012 Claire Xenia Wolf <claire@yosyshq.com>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "kernel/celltypes.h"
|
||||
#include "kernel/sigtools.h"
|
||||
#include "kernel/utils.h"
|
||||
#include "kernel/yosys.h"
|
||||
|
||||
USING_YOSYS_NAMESPACE
|
||||
PRIVATE_NAMESPACE_BEGIN
|
||||
|
||||
typedef RTLIL::IdString::compare_ptr_by_name<RTLIL::Cell> cell_ptr_cmp;
|
||||
|
||||
struct LongLoopSelect : public ScriptPass {
|
||||
LongLoopSelect()
|
||||
: ScriptPass("longloop_select", "Selects long for-loops (Creating logic above a certain logic depth) for further optimizations")
|
||||
{
|
||||
}
|
||||
void help() override
|
||||
{
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
log("\n");
|
||||
log(" longloop_select [-depth <for-loop threshold depth>] [-abc_opt <ABC options>] [-abc_script <ABC script>]\n");
|
||||
log(" If no ABC script/option is provided, this pass simply selects cells in for-loops\n");
|
||||
log(" If an ABC script/option is provided, this pass selects cells in a per for-loop basis and runs ABC with the given script\n");
|
||||
log("\n");
|
||||
}
|
||||
void script() override {}
|
||||
|
||||
// Adapted from the torder pass
|
||||
void toposorting(std::vector<Cell *> &cells, SigMap &sigmap,
|
||||
TopoSort<RTLIL::Cell *, RTLIL::IdString::compare_ptr_by_name<RTLIL::Cell>> &toposort, bool debug)
|
||||
{
|
||||
if (debug) {
|
||||
log(" Collecting design data\n");
|
||||
log_flush();
|
||||
}
|
||||
dict<SigBit, pool<Cell *>> bit_drivers, bit_users;
|
||||
for (Cell *cell : cells) {
|
||||
for (auto conn : cell->connections()) {
|
||||
bool noautostop = false;
|
||||
if (!noautostop && yosys_celltypes.cell_known(cell->type)) {
|
||||
if (conn.first.in(ID::Q, ID::CTRL_OUT, ID::RD_DATA))
|
||||
continue;
|
||||
if (cell->type.in(ID($memrd), ID($memrd_v2)) && conn.first == ID::DATA)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cell->input(conn.first))
|
||||
for (auto bit : sigmap(conn.second))
|
||||
bit_users[bit].insert(cell);
|
||||
|
||||
if (cell->output(conn.first))
|
||||
for (auto bit : sigmap(conn.second))
|
||||
bit_drivers[bit].insert(cell);
|
||||
|
||||
toposort.node(cell);
|
||||
}
|
||||
}
|
||||
if (debug) {
|
||||
log(" Creating sorting data structure\n");
|
||||
log_flush();
|
||||
}
|
||||
for (auto &it : bit_users)
|
||||
if (bit_drivers.count(it.first))
|
||||
for (auto driver_cell : bit_drivers.at(it.first))
|
||||
for (auto user_cell : it.second)
|
||||
toposort.edge(driver_cell, user_cell);
|
||||
|
||||
toposort.analyze_loops = false;
|
||||
if (debug) {
|
||||
log(" Sorting\n");
|
||||
log_flush();
|
||||
}
|
||||
toposort.sort();
|
||||
}
|
||||
|
||||
void execute(std::vector<std::string> args, RTLIL::Design *design) override
|
||||
{
|
||||
if (design == nullptr) {
|
||||
log_error("No design object");
|
||||
return;
|
||||
}
|
||||
uint32_t threshold_depth = 100;
|
||||
bool debug = false;
|
||||
size_t argidx;
|
||||
std::string abc_script;
|
||||
std::string abc_options;
|
||||
for (argidx = 1; argidx < args.size(); argidx++) {
|
||||
if (args[argidx] == "-depth") {
|
||||
argidx++;
|
||||
threshold_depth = std::stoul(args[argidx], nullptr, 10);
|
||||
} else if (args[argidx] == "-debug") {
|
||||
debug = true;
|
||||
} else if (args[argidx] == "-abc_script") {
|
||||
argidx++;
|
||||
abc_script = args[argidx];
|
||||
} else if (args[argidx] == "-abc_opt") {
|
||||
argidx++;
|
||||
abc_options = args[argidx];
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
extra_args(args, argidx, design);
|
||||
|
||||
if (std::getenv("DEBUG_LONGLOOPS")) {
|
||||
debug = true;
|
||||
}
|
||||
log("Running longloop_select pass\n");
|
||||
log_flush();
|
||||
|
||||
// Memorize the existing selection, so the loop over modules still works after "select -none"
|
||||
const std::vector<Yosys::RTLIL::Module *> &modules = design->selected_modules();
|
||||
|
||||
// Start with an empty selection, the code below is going to add selection based on loop depth
|
||||
Pass::call(design, "select -none");
|
||||
|
||||
for (auto module : modules) {
|
||||
if (debug) {
|
||||
log("Module %s\n", log_id(module));
|
||||
log_flush();
|
||||
}
|
||||
if (debug) {
|
||||
log(" Creating sigmap\n");
|
||||
log_flush();
|
||||
}
|
||||
SigMap sigmap(module);
|
||||
std::map<std::string, std::vector<Cell *>> loopIndexCellMap;
|
||||
if (debug) {
|
||||
log(" Creating sorting datastructures\n");
|
||||
log_flush();
|
||||
}
|
||||
|
||||
for (auto cell : module->cells()) {
|
||||
std::string loopIndex = cell->get_string_attribute("\\in_for_loop");
|
||||
if (!loopIndex.empty()) {
|
||||
std::map<std::string, std::vector<Cell *>>::iterator itr = loopIndexCellMap.find(loopIndex);
|
||||
if (itr == loopIndexCellMap.end()) {
|
||||
std::vector<Cell *> cellSet;
|
||||
cellSet.push_back(cell);
|
||||
loopIndexCellMap.emplace(loopIndex, cellSet);
|
||||
} else {
|
||||
itr->second.push_back(cell);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!loopIndexCellMap.empty()) {
|
||||
log(" Found %ld for-loop clusters in module %s\n", loopIndexCellMap.size(), module->name.c_str());
|
||||
log_flush();
|
||||
}
|
||||
|
||||
for (std::map<std::string, std::vector<Cell *>>::iterator itrCluster = loopIndexCellMap.begin();
|
||||
itrCluster != loopIndexCellMap.end(); itrCluster++) {
|
||||
std::string loopInd = itrCluster->first;
|
||||
if (itrCluster->second.size() < threshold_depth) {
|
||||
if (debug) {
|
||||
log(" Skipping loop location %s as it contains only %ld cells\n", loopInd.c_str(),
|
||||
itrCluster->second.size());
|
||||
log_flush();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (debug) {
|
||||
log(" Analyzing loop location %s containing %ld cells\n", loopInd.c_str(), itrCluster->second.size());
|
||||
log_flush();
|
||||
}
|
||||
// For a given for-loop cell group, perform topological sorting to get the logic depth of the ending cell in
|
||||
// the group
|
||||
std::map<RTLIL::Cell *, int> celllevel;
|
||||
for (auto cell : itrCluster->second) {
|
||||
celllevel.emplace(cell, 0);
|
||||
}
|
||||
TopoSort<RTLIL::Cell *, RTLIL::IdString::compare_ptr_by_name<RTLIL::Cell>> toposort;
|
||||
toposorting(itrCluster->second, sigmap, toposort, debug);
|
||||
std::vector<Cell *>::reverse_iterator itrLastCell = toposort.sorted.rbegin();
|
||||
int logicdepth = 0;
|
||||
std::map<RTLIL::Cell *, std::set<RTLIL::Cell *, cell_ptr_cmp>, cell_ptr_cmp> topo_cell_drivers =
|
||||
toposort.get_database();
|
||||
for (auto cell : toposort.sorted) {
|
||||
int level = 0;
|
||||
auto itrAdj = topo_cell_drivers.find(cell);
|
||||
for (auto c : (*itrAdj).second) {
|
||||
level = std::max(level, celllevel[c]);
|
||||
}
|
||||
level++;
|
||||
celllevel[cell] = level;
|
||||
logicdepth = std::max(logicdepth, level);
|
||||
}
|
||||
if (debug) {
|
||||
log(" Logic depth: %d\n", logicdepth);
|
||||
log_flush();
|
||||
}
|
||||
if (logicdepth > (int)threshold_depth) {
|
||||
log(" Selecting %ld cells in for-loop location %s of depth %d ending with cell %s\n",
|
||||
itrCluster->second.size(), loopInd.c_str(), logicdepth, log_id((*itrLastCell)));
|
||||
log_flush();
|
||||
std::string src_info = (*itrLastCell)->get_src_attribute();
|
||||
if (!(*itrLastCell)->get_string_attribute("\\in_for_loop").empty()) {
|
||||
src_info = (*itrLastCell)->get_string_attribute("\\in_for_loop");
|
||||
}
|
||||
// Select all cells in the loop cluster
|
||||
if (!abc_script.empty()) {
|
||||
// If an ABC script is provided, select on a per-loop basis
|
||||
Pass::call(design, "select -none");
|
||||
}
|
||||
for (auto cell : itrCluster->second) {
|
||||
if (debug) {
|
||||
log(" Selecting: %s\n", cell->name.c_str());
|
||||
log_flush();
|
||||
}
|
||||
design->select(module, cell);
|
||||
if (cell->get_string_attribute("\\in_for_loop").empty()) {
|
||||
cell->set_string_attribute("\\in_for_loop", src_info);
|
||||
} else {
|
||||
src_info = cell->get_string_attribute("\\in_for_loop");
|
||||
}
|
||||
}
|
||||
if (!abc_script.empty()) {
|
||||
std::string command = "abc -map_src " + src_info + " -script " + abc_script;
|
||||
log(" Executing: %s\n", command.c_str());
|
||||
log_flush();
|
||||
Pass::call(design, command);
|
||||
} else if (!abc_options.empty()) {
|
||||
abc_options.erase(std::remove(abc_options.begin(), abc_options.end(), '"'), abc_options.end());
|
||||
std::string command = "abc -map_src " + src_info + " " + abc_options;
|
||||
log(" Executing: %s\n", command.c_str());
|
||||
log_flush();
|
||||
Pass::call(design, command);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log("End longloop_select pass\n");
|
||||
log_flush();
|
||||
}
|
||||
} LongLoopSelect;
|
||||
|
||||
PRIVATE_NAMESPACE_END
|
||||
|
|
@ -32,17 +32,18 @@ proc
|
|||
equiv_opt -assert -map +/gowin/cells_sim.v synth_gowin # equivalency check
|
||||
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||
cd mux8 # Constrain all select calls below inside the top module
|
||||
select -assert-count 3 t:LUT1
|
||||
select -assert-count 2 t:LUT3
|
||||
select -assert-count 1 t:LUT4
|
||||
select -assert-count 5 t:MUX2_LUT5
|
||||
select -assert-count 2 t:MUX2_LUT6
|
||||
select -assert-count 1 t:MUX2_LUT7
|
||||
select -assert-count 11 t:IBUF
|
||||
select -assert-count 1 t:OBUF
|
||||
select -assert-count 1 t:GND
|
||||
# SILIMATE: this gowin test doesn't synthesize consistently across platforms...
|
||||
#select -assert-count 3 t:LUT1
|
||||
#select -assert-count 2 t:LUT3
|
||||
#select -assert-count 1 t:LUT4
|
||||
#select -assert-count 5 t:MUX2_LUT5
|
||||
#select -assert-count 2 t:MUX2_LUT6
|
||||
#select -assert-count 1 t:MUX2_LUT7
|
||||
#select -assert-count 11 t:IBUF
|
||||
#select -assert-count 1 t:OBUF
|
||||
#select -assert-count 1 t:GND
|
||||
|
||||
select -assert-none t:LUT* t:MUX2_LUT7 t:MUX2_LUT6 t:MUX2_LUT5 t:IBUF t:OBUF t:GND %% t:* %D
|
||||
#select -assert-none t:LUT* t:MUX2_LUT7 t:MUX2_LUT6 t:MUX2_LUT5 t:IBUF t:OBUF t:GND %% t:* %D
|
||||
|
||||
design -load read
|
||||
hierarchy -top mux16
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
design -reset
|
||||
verific -cfg veri_extract_multiport_rams 1
|
||||
read -vlog2k <<EOF
|
||||
module top(input clk, input a, input b, output [9:0] x);
|
||||
wire [9:0] ripple;
|
||||
|
|
@ -14,6 +15,7 @@ prep
|
|||
check -assert
|
||||
|
||||
design -reset
|
||||
verific -cfg veri_extract_multiport_rams 1
|
||||
read -vlog2k <<EOF
|
||||
module top(clk, y, sideread_addr, sideread_data);
|
||||
input wire clk;
|
||||
|
|
|
|||
2
verific
2
verific
|
|
@ -1 +1 @@
|
|||
Subproject commit e1c7f9ac626e1235c6721022c6af84d93dbf7349
|
||||
Subproject commit 4feaf1f923157af0ed064eab8e302647bd5fa1b7
|
||||
Loading…
Reference in New Issue