-- GHDL Run Time (GRT) - misc subprograms. -- Copyright (C) 2002 - 2014 Tristan Gingold -- -- GHDL is free software; you can redistribute it and/or modify it under -- the terms of the GNU General Public License as published by the Free -- Software Foundation; either version 2, or (at your option) any later -- version. -- -- GHDL is distributed in the hope that it will be useful, but WITHOUT ANY -- WARRANTY; without even the implied warranty of MERCHANTABILITY or -- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- for more details. -- -- You should have received a copy of the GNU General Public License -- along with GCC; see the file COPYING. If not, write to the Free -- Software Foundation, 59 Temple Place - Suite 330, Boston, MA -- 02111-1307, USA. -- -- As a special exception, if other files instantiate generics from this -- unit, or you link this unit with other files to produce an executable, -- this unit does not by itself cause the resulting executable to be -- covered by the GNU General Public License. This exception does not -- however invalidate any other reasons why the executable file might be -- covered by the GNU Public License. with Grt.Errors; use Grt.Errors; with Grt.Options; package body Grt.Lib is --procedure Memcpy (Dst : Address; Src : Address; Size : Size_T); --pragma Import (C, Memcpy); procedure Ghdl_Memcpy (Dest : Ghdl_Ptr; Src : Ghdl_Ptr; Size : Ghdl_Index_Type) is procedure Memmove (Dest : Ghdl_Ptr; Src : Ghdl_Ptr; Size : Ghdl_Index_Type); pragma Import (C, Memmove); begin Memmove (Dest, Src, Size); end Ghdl_Memcpy; procedure Do_Report (Msg : String; Str : Std_String_Ptr; Default_Str : String; Severity : Integer; Loc : Ghdl_Location_Ptr) is Level : constant Integer := Severity mod 256; Bt : Backtrace_Addrs; begin Report_H; Report_C (Loc.Filename); Report_C (":"); Report_C (Loc.Line); Report_C (":"); Report_C (Loc.Col); Report_C (":@"); Report_Now_C; Report_C (":("); Report_C (Msg); Report_C (" "); case Level is when Note_Severity => Report_C ("note"); when Warning_Severity => Report_C ("warning"); when Error_Severity => Report_C ("error"); when Failure_Severity => Report_C ("failure"); when others => Report_C ("???"); end case; Report_C ("): "); if Str /= null then Report_E (Str); else Report_E (Default_Str); end if; if Level >= Grt.Options.Severity_Level then Save_Backtrace (Bt, 2); Error_C (Msg); Error_C (" failed"); Error_E_Call_Stack (Bt); end if; end Do_Report; procedure Ghdl_Assert_Failed (Str : Std_String_Ptr; Severity : Integer; Loc : Ghdl_Location_Ptr) is begin Do_Report ("assertion", Str, "Assertion violation", Severity, Loc); end Ghdl_Assert_Failed; procedure Ghdl_Ieee_Assert_Failed (Str : Std_String_Ptr; Severity : Integer; Loc : Ghdl_Location_Ptr) is use Grt.Options; begin if Ieee_Asserts = Disable_Asserts or else (Ieee_Asserts = Disable_Asserts_At_Time_0 and Current_Time = 0) then return; else Do_Report ("assertion", Str, "Assertion violation", Severity, Loc); end if; end Ghdl_Ieee_Assert_Failed; procedure Ghdl_Psl_Assert_Failed (Str : Std_String_Ptr; Severity : Integer; Loc : Ghdl_Location_Ptr) is begin Do_Report ("psl assertion", Str, "Assertion violation", Severity, Loc); end Ghdl_Psl_Assert_Failed; procedure Ghdl_Psl_Cover (Str : Std_String_Ptr; Severity : Integer; Loc : Ghdl_Location_Ptr) is begin Do_Report ("psl cover", Str, "sequence covered", Severity, Loc); end Ghdl_Psl_Cover; procedure Ghdl_Psl_Cover_Failed (Str : Std_String_Ptr; Severity : Integer; Loc : Ghdl_Location_Ptr) is begin Do_Report ("psl cover failure", Str, "sequence not covered", Severity, Loc); end Ghdl_Psl_Cover_Failed; procedure Ghdl_Report (Str : Std_String_Ptr; Severity : Integer; Loc : Ghdl_Location_Ptr) is begin Do_Report ("report", Str, "Assertion violation", Severity, Loc); end Ghdl_Report; procedure Ghdl_Program_Error (Filename : Ghdl_C_String; Line : Ghdl_I32; Code : Ghdl_Index_Type) is begin case Code is when 1 => Error_C ("missing return in function"); when 2 => Error_C ("block already configured"); when 3 => Error_C ("bad configuration"); when others => Error_C ("unknown error code "); Error_C (Integer (Code)); end case; Error_C (" at "); if Filename = null then Error_C ("*unknown*"); else Error_C (Filename); end if; Error_C (":"); Error_C (Integer(Line)); Error_E (""); end Ghdl_Program_Error; procedure Ghdl_Bound_Check_Failed_L1 (Filename : Ghdl_C_String; Line: Ghdl_I32) is Bt : Backtrace_Addrs; begin Save_Backtrace (Bt, 1); Error_C ("bound check failure at "); Error_C (Filename); Error_C (":"); Error_C (Integer (Line)); Error_E_Call_Stack (Bt); end Ghdl_Bound_Check_Failed_L1; function Ghdl_Integer_Exp (V : Ghdl_I32; E : Ghdl_I32) return Ghdl_I32 is pragma Suppress (Overflow_Check); R : Ghdl_I32; Res : Ghdl_I32; P : Ghdl_I32; T : Ghdl_I64; begin if E < 0 then Error ("negative exponent"); end if; Res := 1; P := V; R := E; loop if R mod 2 = 1 then T := Ghdl_I64 (Res) * Ghdl_I64 (P); Res := Ghdl_I32 (T); if Ghdl_I64 (Res) /= T then Error ("overflow in exponentiation"); end if; end if; R := R / 2; exit when R = 0; P := P * P; end loop; return Res; end Ghdl_Integer_Exp; function C_Malloc (Size : Ghdl_Index_Type) return Ghdl_Ptr; pragma Import (C, C_Malloc, "malloc"); function Ghdl_Malloc (Size : Ghdl_Index_Type) return Ghdl_Ptr is begin return C_Malloc (Size); end Ghdl_Malloc; function Ghdl_Malloc0 (Size : Ghdl_Index_Type) return Ghdl_Ptr is procedure Memset (Ptr : Ghdl_Ptr; C : Integer; Size : Ghdl_Index_Type); pragma Import (C, Memset); Res : Ghdl_Ptr; begin Res := C_Malloc (Size); Memset (Res, 0, Size); return Res; end Ghdl_Malloc0; procedure Ghdl_Deallocate (Ptr : Ghdl_Ptr) is procedure C_Free (Ptr : Ghdl_Ptr); pragma Import (C, C_Free, "free"); begin C_Free (Ptr); end Ghdl_Deallocate; function Ghdl_Real_Exp (X : Ghdl_Real; Exp : Ghdl_I32) return Ghdl_Real is R : Ghdl_I32; Res : Ghdl_Real; P : Ghdl_Real; begin Res := 1.0; P := X; R := Exp; if R >= 0 then loop if R mod 2 = 1 then Res := Res * P; end if; R := R / 2; exit when R = 0; P := P * P; end loop; return Res; else R := -R; loop if R mod 2 = 1 then Res := Res * P; end if; R := R / 2; exit when R = 0; P := P * P; end loop; if Res = 0.0 then Error ("division per 0.0"); return 0.0; end if; return 1.0 / Res; end if; end Ghdl_Real_Exp; function Ghdl_Get_Resolution_Limit return Std_Time is begin return 1; end Ghdl_Get_Resolution_Limit; procedure Ghdl_Control_Simulation (Stop : Ghdl_B1; Has_Status : Ghdl_B1; Status : Std_Integer) is begin Report_H; -- Report_C (Grt.Options.Progname); Report_C ("simulation "); if Stop then Report_C ("stopped"); else Report_C ("finished"); end if; Report_C (" @"); Report_Now_C; if Has_Status then Report_C (" with status "); Report_C (Integer (Status)); end if; Report_E (""); if Has_Status then Exit_Status := Integer (Status); end if; Exit_Simulation; end Ghdl_Control_Simulation; end Grt.Lib; 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245
/*
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2018 Miodrag Milanovic <micko@yosyshq.com>
* Copyright (C) 2018 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/register.h"
#include "kernel/celltypes.h"
#include "kernel/rtlil.h"
#include "kernel/log.h"
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
struct SynthAnlogicPass : public ScriptPass
{
SynthAnlogicPass() : ScriptPass("synth_anlogic", "synthesis for Anlogic FPGAs") { }
void help() override
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
log(" synth_anlogic [options]\n");
log("\n");
log("This command runs synthesis for Anlogic FPGAs.\n");
log("\n");
log(" -top <module>\n");
log(" use the specified module as top module\n");
log("\n");
log(" -edif <file>\n");
log(" write the design to the specified EDIF file. writing of an output file\n");
log(" is omitted if this parameter is not specified.\n");
log("\n");
log(" -json <file>\n");
log(" write the design to the specified JSON file. writing of an output file\n");
log(" is omitted if this parameter is not specified.\n");
log("\n");
log(" -run <from_label>:<to_label>\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(" -noflatten\n");
log(" do not flatten design before synthesis\n");
log("\n");
log(" -retime\n");
log(" run 'abc' with '-dff -D 1' options\n");
log("\n");
log(" -nolutram\n");
log(" do not use EG_LOGIC_DRAM16X4 cells in output netlist\n");
log("\n");
log(" -nobram\n");
log(" do not use EG_PHY_BRAM or EG_PHY_BRAM32K cells in output netlist\n");
log("\n");
log("\n");
log("The following commands are executed by this synthesis command:\n");
help_script();
log("\n");
}
string top_opt, edif_file, json_file;
bool flatten, retime, nolutram, nobram;
void clear_flags() override
{
top_opt = "-auto-top";
edif_file = "";
json_file = "";
flatten = true;
retime = false;
nolutram = false;
nobram = false;
}
void execute(std::vector<std::string> 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] == "-top" && argidx+1 < args.size()) {
top_opt = "-top " + args[++argidx];
continue;
}
if (args[argidx] == "-edif" && argidx+1 < args.size()) {
edif_file = args[++argidx];
continue;
}
if (args[argidx] == "-json" && argidx+1 < args.size()) {
json_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] == "-noflatten") {
flatten = false;
continue;
}
if (args[argidx] == "-nolutram") {
nolutram = true;
continue;
}
if (args[argidx] == "-nobram") {
nobram = true;
continue;
}
if (args[argidx] == "-retime") {
retime = true;
continue;
}
break;
}
extra_args(args, argidx, design);
if (!design->full_selection())
log_cmd_error("This command only operates on fully selected designs!\n");
log_header(design, "Executing SYNTH_ANLOGIC pass.\n");
log_push();
run_script(design, run_from, run_to);
log_pop();
}
void script() override
{
if (check_label("begin"))
{
run("read_verilog -lib +/anlogic/cells_sim.v +/anlogic/eagle_bb.v");
run(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str()));
}
if (flatten && check_label("flatten", "(unless -noflatten)"))
{
run("proc");
run("flatten");
run("tribuf -logic");
run("deminout");
}
if (check_label("coarse"))
{
run("synth -run coarse");
}
if (check_label("map_ram"))
{
std::string args = "";
if (nobram)
args += " -no-auto-block";
if (nolutram)
args += " -no-auto-distributed";
if (help_mode)
args += " [-no-auto-block] [-no-auto-distributed]";
run("memory_libmap -lib +/anlogic/lutrams.txt -lib +/anlogic/brams.txt" + args, "(-no-auto-block if -nobram, -no-auto-distributed if -nolutram)");
run("techmap -map +/anlogic/lutrams_map.v -map +/anlogic/brams_map.v");
}
if (check_label("map_ffram"))
{
run("opt -fast -mux_undef -undriven -fine");
run("memory_map");
run("opt -undriven -fine");
}
if (check_label("map_gates"))
{
run("techmap -map +/techmap.v -map +/anlogic/arith_map.v");
run("opt -fast");
if (retime || help_mode)
run("abc -dff -D 1", "(only if -retime)");
}
if (check_label("map_ffs"))
{
run("dfflegalize -cell $_DFFE_P??P_ r -cell $_SDFFE_P??P_ r -cell $_DLATCH_N??_ r");
run("techmap -D NO_LUT -map +/anlogic/cells_map.v");
run("opt_expr -mux_undef");
run("simplemap");
}
if (check_label("map_luts"))
{
run("abc -lut 4:6");
run("clean");
}
if (check_label("map_cells"))
{
run("techmap -map +/anlogic/cells_map.v");
run("clean");
}
if (check_label("map_anlogic"))
{
run("anlogic_fixcarry");
run("anlogic_eqn");
}
if (check_label("check"))
{
run("hierarchy -check");
run("stat");
run("check -noinit");
run("blackbox =A:whitebox");
}
if (check_label("edif"))
{
if (!edif_file.empty() || help_mode)
run(stringf("write_edif %s", help_mode ? "<file-name>" : edif_file.c_str()));
}
if (check_label("json"))
{
if (!json_file.empty() || help_mode)
run(stringf("write_json %s", help_mode ? "<file-name>" : json_file.c_str()));
}
}
} SynthAnlogicPass;
PRIVATE_NAMESPACE_END