diff options
author | Xiretza <xiretza@xiretza.xyz> | 2020-04-08 22:29:46 +0200 |
---|---|---|
committer | tgingold <tgingold@users.noreply.github.com> | 2020-05-30 19:20:32 +0200 |
commit | d216549165da5496da30ce0a28fcf5c2a36a3278 (patch) | |
tree | 70bfd9e8011f58f9a90df3a488871229901fd7d2 | |
parent | 0b687cd21c5dc7bad4fe49f7d2554d1ddc542d17 (diff) | |
download | ghdl-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.cc | 9 |
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)); |