/* * yosys -- Yosys Open SYnthesis Suite * * Copyright (C) 2012 Clifford Wolf * * 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/yosys.h" #include "kernel/sigtools.h" #include "passes/techmap/simplemap.h" #include #include USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN static SigBit get_bit_or_zero(const SigSpec &sig) { if (GetSize(sig) == 0) return State::S0; return sig[0]; } static void run_ice40_opts(Module *module) { pool optimized_co; vector sb_lut_cells; SigMap sigmap(module); for (auto cell : module->selected_cells()) { if (!cell->type.in(ID(SB_LUT4), ID(SB_CARRY), ID($__ICE40_CARRY_WRAPPER))) continue; if (cell->has_keep_attr()) continue; if (cell->type == ID(SB_LUT4)) { sb_lut_cells.push_back(cell); continue; } if (cell->type == ID(SB_CARRY)) { SigSpec non_const_inputs, replacement_output; int count_zeros = 0, count_ones = 0; SigBit inbit[3] = { get_bit_or_zero(cell->getPort(ID(I0))), get_bit_or_zero(cell->getPort(ID(I1))), get_bit_or_zero(cell->getPort(ID::CI)) }; for (int i = 0; i < 3; i++) if (inbit[i].wire == nullptr) { if (inbit[i] == State::S1) count_ones++; else count_zeros++; } else non_const_inputs.append(inbit[i]); if (count_zeros >= 2) replacement_output = State::S0; else if (count_ones >= 2) replacement_output = State::S1; else if (GetSize(non_const_inputs) == 1) replacement_output = non_const_inputs; if (GetSize(replacement_output)) { optimized_co.insert(sigmap(cell->getPort(ID::CO)[0])); module->connect(cell->getPort(ID::CO)[0], replacement_output); module->design->scratchpad_set_bool("opt.did_something", true); log("Optimized away SB_CARRY cell %s.%s: CO=%s\n", log_id(module), log_id(cell), log_signal(replacement_output)); module->remove(cell); } continue; } if (cell->type == ID($__ICE40_CARRY_WRAPPER)) { SigSpec non_const_inputs, replacement_output; int count_zeros = 0, count_ones = 0; SigBit inbit[3] = { cell->getPort(ID::A), cell->getPort(ID::B), cell->getPort(ID::CI) }; for (int i = 0; i < 3; i++) if (inbit[i].wire == nullptr) { if (inbit[i] == State::S1) count_ones++; else count_zeros++; } else non_const_inputs.append(inbit[i]); if (count_zeros >= 2) replacement_output = State::S0; else if (count_ones >= 2) replacement_output = State::S1; else if (GetSize(non_const_inputs) == 1) replacement_output = non_const_inputs; if (GetSize(replacement_output)) { optimized_co.insert(sigmap(cell->getPort(ID::CO)[0])); auto it = cell->attributes.find(ID(SB_LUT4.name)); if (it != cell->attributes.end()) { module->rename(cell, it->second.decode_string()); decltype(Cell::attributes) new_attr; for (const auto &a : cell->attributes) if (a.first.begins_with("\\SB_LUT4.\\")) new_attr[a.first.c_str() + strlen("\\SB_LUT4.")] = a.second; else if (a.first == ID::src) new_attr.insert(std::make_pair(a.first, a.second)); else if (a.first.in(ID(SB_LUT4.name), ID::keep, ID::module_not_derived)) continue; else if (a.first.begins_with("\\SB_CARRY.\\")) continue; else log_abort(); cell->attributes = std::move(new_attr); } module->connect(cell->getPort(ID::CO)[0], replacement_output); module->design->scratchpad_set_bool("opt.did_something", true); log("Optimized $__ICE40_CARRY_WRAPPER cell back to logic (without SB_CARRY) %s.%s: CO=%s\n", log_id(module), log_id(cell), log_signal(replacement_output)); cell->type = ID($lut); auto I3 = get_bit_or_zero(cell->getPort(cell->getParam(ID(I3_IS_CI)).as_bool() ? ID::CI : ID(I3))); cell->setPort(ID::A, { I3, inbit[1], inbit[0], get_bit_or_zero(cell->getPort(ID(I0))) }); cell->setPort(ID::Y, cell->getPort(ID::O)); cell->unsetPort(ID::B); cell->unsetPort(ID::CI); cell->unsetPort(ID(I0)); cell->unsetPort(ID(I3)); cell->unsetPort(ID::CO); cell->unsetPort(ID::O); cell->setParam(ID::WIDTH, 4); cell->unsetParam(ID(I3_IS_CI)); } continue; } } for (auto cell : sb_lut_cells) { SigSpec inbits; inbits.append(get_bit_or_zero(cell->g
/*
 *  yosys -- Yosys Open SYnthesis Suite
 *
 *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
 *
 *  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.
 *
 */
module VCC (output V);
   assign V = 1'b1;
endmodule // VCC

module GND (output G);
   assign G = 1'b0;
endmodule // GND

/* Altera Arria 10 GX devices Input Buffer Primitive */
module twentynm_io_ibuf (output o, input i, input ibar);
   assign ibar = ibar;
   assign o    = i;
endmodule // twentynm_io_ibuf

/* Altera Arria 10 GX  devices Output Buffer Primitive */
module twentynm_io_obuf (output o, input i, input oe);
   assign o  = i;
   assign oe = oe;
endmodule // twentynm_io_obuf

/* Altera Arria 10 GX  LUT Primitive */
module twentynm_lcell_comb (output combout, cout, sumout,
                            input  dataa, datab, datac, datad,
                            input  datae, dataf, datag, cin,
                            input  sharein);

parameter lut_mask      = 64'hFFFFFFFFFFFFFFFF;
parameter dont_touch    = "off";
parameter lpm_type      = "twentynm_lcell_comb";
parameter shared_arith  = "off";
parameter extended_lut  = "off";

// TODO: This is still WIP
initial begin
  $display("Simulation model is still under investigation\n");
end

endmodule // twentynm_lcell_comb