/* * yosys -- Yosys Open SYnthesis Suite * * Copyright (C) 2012 Claire Xenia Wolf * Copyright (C) 2019 Dan Ravensloft * * 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/log.h" #include "kernel/register.h" #include "kernel/rtlil.h" USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN struct SynthIntelALMPass : public ScriptPass { SynthIntelALMPass() : ScriptPass("synth_intel_alm", "synthesis for ALM-based Intel (Altera) FPGAs.") {} void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); log(" synth_intel_alm [options]\n"); log("\n"); log("This command runs synthesis for ALM-based Intel FPGAs.\n"); log("\n"); log(" -top \n"); log(" use the specified module as top module\n"); log("\n"); log(" -family \n"); log(" target one of:\n"); log(" \"cyclonev\" - Cyclone V (default)\n"); log(" \"arriav\" - Arria V (non-GZ)"); log(" \"cyclone10gx\" - Cyclone 10GX\n"); log("\n"); log(" -vqm \n"); log(" write the design to the specified Verilog Quartus Mapping File. Writing of an\n"); log(" output file is omitted if this parameter is not specified. Implies -quartus.\n"); log("\n"); log(" -noflatten\n"); log(" do not flatten design before synthesis; useful for per-module area statistics\n"); log("\n"); log(" -quartus\n"); log(" output a netlist using Quartus cells instead of MISTRAL_* cells\n"); log("\n"); log(" -dff\n"); log(" pass DFFs to ABC to perform sequential logic optimisations (EXPERIMENTAL)\n"); log("\n"); log(" -run :\n"); log(" only run the commands between the labels (see below). an empty\n"); log(" from label is synonymous to 'begin', and empty to label is\n"); log(" synonymous to the end of the command list.\n"); log("\n"); log(" -nolutram\n"); log(" do not use LUT RAM cells in output netlist\n"); log("\n"); log(" -nobram\n"); log(" do not use block RAM cells in output netlist\n"); log("\n"); log(" -nodsp\n"); log(" do not map multipliers to MISTRAL_MUL cells\n"); log("\n"); log(" -noiopad\n"); log(" do not instantiate IO buffers\n"); log("\n"); log(" -noclkbuf\n"); log(" do not insert global clock buffers\n"); log("\n"); log("The following commands are executed by this synthesis command:\n"); help_script(); log("\n"); } string top_opt, family_opt, bram_type, vout_file; bool flatten, quartus, nolutram, nobram, dff, nodsp, noiopad, noclkbuf; void clear_flags() override { top_opt = "-auto-top"; family_opt = "cyclonev"; bram_type = "m10k"; vout_file = ""; flatten = true; quartus = false; nolutram = false; nobram = false; dff = false; nodsp = false; noiopad = false; noclkbuf = false; } void execute(std::vector args, RTLIL::Design *design) override { string run_from, run_to; clear_flags(); size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { if (args[argidx] == "-family" && argidx + 1 < args.size()) { family_opt = args[++argidx]; continue; } if (args[argidx] == "-top" && argidx + 1 < args.size()) { top_opt = "-top " + args[++argidx]; continue; } if (args[argidx] == "-vqm" && argidx + 1 < args.size()) { quartus = true; vout_file = args[++argidx]; continue; } if (args[argidx] == "-run" && argidx + 1 < args.size()) { size_t pos = args[argidx + 1].find(':'); if (pos == std::string::npos) break; run_from = args[++argidx].substr(0, pos); run_to = args[argidx].substr(pos + 1); continue; } if (args[argidx] == "-quartus") { quartus = true; continue; } if (args[argidx] == "-nolutram") { nolutram = true; continue; } if (args[argidx] == "-nobram") { nobram = true; continue; } if (args[argidx] == "-nodsp") { nodsp = true; continue; } if (args[argidx] == "-noflatten") { flatten = false; continue; } if (args[argidx] == "-dff") { dff = true; continue; } if (args[argidx] == "-noiopad") { noiopad = true; continue; } if (args[argidx] == "-noclkbuf") { noclkbuf = true; continue; } break; } extra_args(args, argidx, design); if (!design->full_selection()) log_cmd_error("This command only operates on fully selected designs!\n"); if (family_opt == "cyclonev" || family_opt == "arriav") { bram_type = "m10k"; } else if (family_opt == "cyclone10gx") { bram_type = "m20k"; } else if (family_opt == "arriva") { // I have typoed "arriav" as "arriva" (a local bus company) // so many times I thought it would be funny to have an easter egg. log_cmd_error("synth_intel_alm cannot synthesize for bus companies. (did you mean '-family arriav'?)\n"); } else { log_cmd_error("Invalid family specified: '%s'\n", family_opt.c_str()); } log_header(design, "Executing SYNTH_INTEL_ALM pass.\n"); log_push(); run_script(design, run_from, run_to); log_pop(); } void script() override { if (help_mode) { family_opt = ""; bram_type = ""; } if (check_label("begin")) { if (family_opt == "cyclonev") run(stringf("read_verilog -sv -lib +/intel_alm/%s/cells_sim.v", family_opt.c_str())); run(stringf("read_verilog -specify -lib -D %s +/intel_alm/common/alm_sim.v", family_opt.c_str())); run(stringf("read_verilog -specify -lib -D %s +/intel_alm/common/dff_sim.v", family_opt.c_str())
/**CFile****************************************************************

  FileName    [mvcDivisor.c]

  PackageName [MVSIS 2.0: Multi-valued logic synthesis system.]

  Synopsis    [Procedures for compute the quick divisor.]

  Author      [MVSIS Group]
  
  Affiliation [UC Berkeley]

  Date        [Ver. 1.0. Started - February 1, 2003.]

  Revision    [$Id: mvcDivisor.c,v 1.1 2003/04/03 15:34:08 alanmi Exp $]

***********************************************************************/

#include "mvc.h"

ABC_NAMESPACE_IMPL_START


////////////////////////////////////////////////////////////////////////
///                        DECLARATIONS                              ///
////////////////////////////////////////////////////////////////////////

static void  Mvc_CoverDivisorZeroKernel( Mvc_Cover_t * pCover );

////////////////////////////////////////////////////////////////////////
///                     FUNCTION DEFINITIONS                         ///
////////////////////////////////////////////////////////////////////////

/**Function*************************************************************

  Synopsis    [Returns the quick divisor of the cover.]

  Description [Returns NULL, if there is not divisor other than
  trivial.]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Mvc_Cover_t * Mvc_CoverDivisor( Mvc_Cover_t * pCover )
{
    Mvc_Cover_t * pKernel;
    if ( Mvc_CoverReadCubeNum(pCover) <= 1 )
        return NULL;
    // allocate the literal array and count literals
    if ( Mvc_CoverAnyLiteral( pCover, NULL ) == -1 )
        return NULL;
    // duplicate the cover
    pKernel = Mvc_CoverDup(pCover);
    // perform the kerneling
    Mvc_CoverDivisorZeroKernel( pKernel );
    assert( Mvc_CoverReadCubeNum(pKernel) );
    return pKernel;
}

/**Function*************************************************************

  Synopsis    [Computes a level-zero kernel.]

  Description [Modifies the cover to contain one level-zero kernel.]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Mvc_CoverDivisorZeroKernel( Mvc_Cover_t * pCover )
{
    int iLit;
    // find any literal that occurs at least two times
//    iLit = Mvc_CoverAnyLiteral( pCover, NULL );
    iLit = Mvc_CoverWorstLiteral( pCover, NULL );
//    iLit = Mvc_CoverBestLiteral( pCover, NULL );
    if ( iLit == -1 )
        return;
    // derive the cube-free quotient
    Mvc_CoverDivideByLiteralQuo( pCover, iLit ); // the same cover
    Mvc_CoverMakeCubeFree( pCover );             // the same cover
    // call recursively
    Mvc_CoverDivisorZeroKernel( pCover );              // the same cover
}

////////////////////////////////////////////////////////////////////////
///                       END OF FILE                                ///
////////////////////////////////////////////////////////////////////////


ABC_NAMESPACE_IMPL_END