Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Yosys modulus operator has remainder semantics #1523

Closed
pepijndevos opened this issue Nov 24, 2019 · 1 comment · Fixed by #1885
Closed

Yosys modulus operator has remainder semantics #1523

pepijndevos opened this issue Nov 24, 2019 · 1 comment · Fixed by #1885

Comments

@pepijndevos
Copy link
Member

As per Wikipedia, usually modulus has the sign of the divisor, while remainder has the sign of the dividend. In languages that only have one % operator, you can get either behavior. https://en.wikipedia.org/wiki/Modulo_operation#In_programming_languages

However, VHDL is a language that has both a mod and a rem operator, where rem has the behavior of Yosys/Verilog $mod/%, and there is no way to represent actual VHDL mod.

Below is a program that when synthesized with GHDL currently throws an error. When using Verific, both statements result in a $mod operator, which is clearly incorrect.

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity lut2 is
    port (a: in integer;
          b: in integer;
          y: out integer;
          z: out integer);
end lut2;

architecture synth of lut2 is
begin
  y <= a mod b;
  z <= a rem b;
end synth;

yosys_show
Here is the offending Verific code:

if (inst->Type() == OPER_MODULO) {
cell = module->addMod(inst_name, IN1, IN2, OUT, SIGNED);
import_attributes(cell->attributes, inst);
return true;
}

@whitequark
Copy link
Member

I have the same problem in nMigen, which follows Python semantics and so uses a modulo operator. IMO the $mod cell should be renamed to $rem, and a new $mod (or perhaps $mod2) cell should be added with the correct semantics, so that it can be used by VHDL and nMigen.

Xiretza referenced this issue in ghdl/ghdl-yosys-plugin Apr 8, 2020
Xiretza added a commit to Xiretza/yosys that referenced this issue Apr 8, 2020
Many languages have both modulo and remainder operations. They perform
the same basic task (remainder of an integer division), but the sign of
the output changes:
- The result of a remainder operation has the sign of the numerator (dividend)
- The result of a modulo operation has the sign of the denominator (divisor)

The $mod cell, being targeted for the Verilog `%` operator, used
remainder semantics, making it hard to add a cell for actual modulo
operations. $mod was renamed to $rem, and a new $mod2 cell that
performs denominator-signed modulo was added.

Fixes YosysHQ#1523.
Xiretza added a commit to Xiretza/yosys that referenced this issue Apr 8, 2020
Many languages have both modulo and remainder operations. They perform
the same basic task (remainder of an integer division), but the sign of
the output changes:
- The result of a remainder operation has the sign of the numerator (dividend)
- The result of a modulo operation has the sign of the denominator (divisor)

The $mod cell, being targeted at the Verilog `%` operator, used
remainder semantics, making it hard to add a cell for actual modulo
operations. $mod was renamed to $rem, and a new $mod2 cell that
performs denominator-signed modulo was added.

Fixes YosysHQ#1523.
Xiretza added a commit to Xiretza/yosys that referenced this issue Apr 11, 2020
Many languages have both modulo and remainder operations. They perform
the same basic task (remainder of an integer division), but the sign of
the output changes:
- The result of a remainder operation has the sign of the numerator (dividend)
- The result of a modulo operation has the sign of the denominator (divisor)

The $mod cell, being targeted at the Verilog `%` operator, uses
remainder semantics. To maximise backwards compatibility, it was decided
to keep the ill-named $mod cell and to add a separate $mod2 cell which
performs actual modulo.

Fixes YosysHQ#1523.
Xiretza added a commit to Xiretza/yosys that referenced this issue Apr 20, 2020
Many languages have both modulo and remainder operations. They perform
the same basic task (remainder of an integer division), but the sign of
the output changes:
- The result of a remainder operation has the sign of the numerator (dividend)
- The result of a modulo operation has the sign of the denominator (divisor)

The $mod cell, being targeted at the Verilog `%` operator, uses
remainder semantics. To maximise backwards compatibility, it was decided
to keep the ill-named $mod cell and to add a separate $mod2 cell which
performs actual modulo.

Fixes YosysHQ#1523.
Xiretza added a commit to Xiretza/yosys that referenced this issue Apr 20, 2020
The $div and $mod cells use truncating division semantics (rounding
towards 0), as defined by e.g. Verilog. Another rounding mode, flooring
(rounding towards negative infinity), is used by e.g. VHDL. The
$modfloor cell provides this flooring modulo (also known as "remainder"
in several languages, but this name is ambiguous).

Fixes YosysHQ#1523.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants