aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXiretza <xiretza@xiretza.xyz>2020-04-08 22:29:46 +0200
committertgingold <tgingold@users.noreply.github.com>2020-05-30 19:20:32 +0200
commitd216549165da5496da30ce0a28fcf5c2a36a3278 (patch)
tree70bfd9e8011f58f9a90df3a488871229901fd7d2
parent0b687cd21c5dc7bad4fe49f7d2554d1ddc542d17 (diff)
downloadghdl-yosys-plugin-d216549165da5496da30ce0a28fcf5c2a36a3278.tar.gz
ghdl-yosys-plugin-d216549165da5496da30ce0a28fcf5c2a36a3278.tar.bz2
ghdl-yosys-plugin-d216549165da5496da30ce0a28fcf5c2a36a3278.zip
Fix signed modulo behaviour
Yosys' $mod cell is the modulo of truncating division, known as "rem" in VHDL. The new $modfloor cell is the modulo of flooring division, known as "mod" in VHDL. "mod" now synthesizes correctly for negative numbers.
-rw-r--r--src/ghdl.cc9
1 files changed, 5 insertions, 4 deletions
diff --git a/src/ghdl.cc b/src/ghdl.cc
index d1e5cd8..becce24 100644
--- a/src/ghdl.cc
+++ b/src/ghdl.cc
@@ -883,13 +883,14 @@ static void import_module(RTLIL::Design *design, GhdlSynth::Module m)
module->addDiv(to_str(iname), IN(0), IN(1), OUT(0), false);
break;
case Id_Srem:
- case Id_Smod:
- // Yosys modulus uses Verilogs *remainder* behavior
- // there is no signed modulus operator in Yosys
+ // Id_Urem would be the same as Id_Umod, so only the latter exists
+ // $mod: modulo of truncating division, "rem" in VHDL
module->addMod(to_str(iname), IN(0), IN(1), OUT(0), true);
break;
+ case Id_Smod:
case Id_Umod:
- module->addMod(to_str(iname), IN(0), IN(1), OUT(0), false);
+ // $modfloor: modulo of flooring division, "mod" in VHDL
+ module->addModFloor(to_str(iname), IN(0), IN(1), OUT(0), id == Id_Smod);
break;
case Id_Mux2:
module->addMux(to_str(iname), IN(1), IN(2), IN(0), OUT(0));