02-08-2017 01:14 AM
Hi there,
I have googled the above question, and found that someone suggests avoiding using the Modulus % if you want to make the verilog code synthesizable.
Could someone specify it more? According to my understanding, the modulus could be synthesizable (e.g. m % n) if the n is an small integer and fixed.
Thanks in advance.
Regards
Alex
02-08-2017 01:50 AM - edited 02-08-2017 01:55 AM
It's essentially a question of whether the division can be done (if you can do the division, modulo is easy). Even if the modulo operator is not implemented, with division implemented it's trivial to implement your own modulo operator.
ISE - can do division for powers of 2 and can therefore (probably) do modulo for powers of 2. Of course, you can achieve the same thing with a bit-select operation or a bitwise AND. ISE cannot do division for anything other than a power of 2, and will not implement the modulo operator (even if the inputs are only tiny values).
Vivado - can do division with any divisor, but it'll take up an extremely large amount of space (and run extremely slowly) for large input widths (both divisor and dividend matter; a 64-bit value divided by 3 will be pretty expensive). I expect that it can do modulo too.
I suspect that for small, fixed divisors you can find a rule that defines whether a dividend is perfectly divisible. For example, for division by 3 you can use this trick. If you check a value X against that, and then check X+1 against that, then you know whether X%3 == 0 or X%3 == 1. If both fail, then clearly X%3 == 2.
Edit: with that said, I agree with the suggestion you found. While some tools (eg. Vivado) may be able to synthesize a small modulo operator (eg. 4-bit mod 2-bit), you can't rely on this. If you were to port the design to an older chip in ISE, it'd fail. I've got no idea whether Quartus (Altera) supports modulo, or whether Diamond (Lattice) does, or whether Microsemi's toolchain (I've forgotten its name) does. Better to just assume that it'd not synthesizable.
02-08-2017 01:50 AM - edited 02-08-2017 01:55 AM
It's essentially a question of whether the division can be done (if you can do the division, modulo is easy). Even if the modulo operator is not implemented, with division implemented it's trivial to implement your own modulo operator.
ISE - can do division for powers of 2 and can therefore (probably) do modulo for powers of 2. Of course, you can achieve the same thing with a bit-select operation or a bitwise AND. ISE cannot do division for anything other than a power of 2, and will not implement the modulo operator (even if the inputs are only tiny values).
Vivado - can do division with any divisor, but it'll take up an extremely large amount of space (and run extremely slowly) for large input widths (both divisor and dividend matter; a 64-bit value divided by 3 will be pretty expensive). I expect that it can do modulo too.
I suspect that for small, fixed divisors you can find a rule that defines whether a dividend is perfectly divisible. For example, for division by 3 you can use this trick. If you check a value X against that, and then check X+1 against that, then you know whether X%3 == 0 or X%3 == 1. If both fail, then clearly X%3 == 2.
Edit: with that said, I agree with the suggestion you found. While some tools (eg. Vivado) may be able to synthesize a small modulo operator (eg. 4-bit mod 2-bit), you can't rely on this. If you were to port the design to an older chip in ISE, it'd fail. I've got no idea whether Quartus (Altera) supports modulo, or whether Diamond (Lattice) does, or whether Microsemi's toolchain (I've forgotten its name) does. Better to just assume that it'd not synthesizable.
02-08-2017 02:30 AM
02-08-2017 03:43 AM
I have found with experience that using modulo counters (albeit in VHDL) are fully synthesisable, e.g.
if (condition) then
counter <= (counter + 1) mod VALUE;
end if;
this is, at least in part, due to the fact that it probably isn't doing any mod function atall, it's just checking whether or not the counter has reached VALUE or not. In other word, it is the same as something like
if (counter = VALUE) then
counter <= 0;
elsif (condition) then
counter <= counter + 1;
end if;
but takes less lines. I guess it depends on what your contextual use of the mod operator is (and now I see that a fuller, probably more applicable answer, has been given).
02-08-2017 04:21 AM
02-08-2017 04:29 AM
Possibly you are correct. The counter implementation seems fine for VHDL LRM defined integer values (31 bit).
I can't imagine a scenario where I would use an extremely large counter (1024 bit is a massive number - 1.79 x 10^308!).
02-08-2017 03:01 PM
Good find! I guess it makes a lot of sense in that case; it's a very common pattern (and so any reduction in code size will have a pretty big impact for a lot of people) and you can make assumptions (eg that the counter is initially less than the modulus).
Obviously it might be a bit slow with a 1024-bit counter, but a 1024-bit counter will be slow anyway.