Forum Discussion
signed/unsigned multipliers
I can't seem to find a way to instantiate a multiplier that will dynamically select between signed and unsigned multiplication. This is on a Cyclone II, but applies to other parts as well.
Reading the Cyclone II documentation it is clear that signa, signb inputs does what I want, but none of the multipliers created with the Wizzard exports that as an input signal. Trying to infer it with the code below doesn't work (bug in Quartus II?); it complains that no logic depends on input_sign. However looking at the RTL with Tools/Netlist Viewers/RTL Viewer clearly shows it being used, however the technology map viewer shows input_sign as disconnected and signa and signb hardwired to ground. This looks like a bug to me, but I could be doing something wrong.
module mult(input clock,
input input_sign,
input input_a,
input input_b,
output reg output_c);
reg a, b;
reg sign;
always @(posedge clock) begin
sign <= input_sign;
a <= input_a;
b <= input_b;
if (sign)
output_c <= $signed(a) * $signed(b);
else
output_c <= $unsigned(a) * $unsigned(b);
end
endmodule
42 Replies
- Altera_Forum
Honored Contributor
Just to clarify, have you tried FvM's solution using altmult_add? It's certainly there in Quartus 6.1 and although the symbol in the MegaWizard looks a bit mad at first, if you do as FvM says and set the number of multipliers to 1 it simplifies up a treat.
As a matter of interest, what was the workaround you chose in the end? - Altera_Forum
Honored Contributor
--- Quote Start --- Thanks Tricky. It does really work. So in principle you are doing what altera never tell us....as usual. To use unsigned, given a signed input: 1) double extend input width using sign extension 2) truncate output to double inputwidth Very useful discussion. --- Quote End --- IMO, Tricky side stepped the real issue. I already pointed out that the lower bits would be identical, so obviously widening the input would "solve" the problem, at a quadratic cost!! You (Kaz) provided an actual useful workaround. I'm still working with support to get the original bug fixed. Tommy - Altera_Forum
Honored Contributor
Hi SimKnutt,
We are not talking about conversion from natural binary to 2's (let alone 1's complement which is never used in practice). It is assumed that we are given ready-made input as either unsigned or signed and we want to pass it through one (unsigned) multiplier. The method described above does work as far as our limited testing indicates but may clash with compiler bitwidth issues regarding the dedicated multipliers. - Altera_Forum
Honored Contributor
Why are you comparing bit patterns of 11 and -5? The point is that 5 and -5 have different low order bits, so you cannot just sign extend. Assuming two's complement arithmetic, complement the binary value and add 1 to get the negative. for ones complement just complement (invert the bits). Look at an adder/subtractor. To subtract it does a complement and add. Sign extension is for right shifting to preserve the sign and magnitude of an operand because leading zeroes of a negative number appear as 1 bits. This is not true in the bits that represent the magnitude.
- Altera_Forum
Honored Contributor
--- Quote Start --- But, if you have spare bits on the input, you can simply sign extend. --- Quote End --- Yes, but it's 100% spare bits. I didn't want to suggest the solution for this reason. And you don't necessarily need the MegaWizard, but you have to understand various additional parameters of cycloneii_mac_mult then. - Altera_Forum
Honored Contributor
--- Quote Start --- So your method involves sign extending both 9 bit inputs to 18 bit? This means, you need four multiplier blocks instead of one, not a useful suggestion, to my opinion. I would rather use signed/unsigned inputs with altmult_add, as previously said. --- Quote End --- This discussion has been more about theory than practicalilty. In practice, if you need to use all the bits of the multiplier input, then you have to use the signa/b inputs on the megafunction. But, if you have spare bits on the input, you can simply sign extend and not need any more multipliers, and avoid using the wizard. - Altera_Forum
Honored Contributor
So your method involves sign extending both 9 bit inputs to 18 bit? This means, you need four multiplier blocks instead of one, not a useful suggestion, to my opinion. I would rather use signed/unsigned inputs with altmult_add, as previously said.
P.S.: O.K., it's only two instead of one block, still a waste of resources. - Altera_Forum
Honored Contributor
--- Quote Start --- So in principle you are doing what altera never tell us....as usual. --- Quote End --- I dont know. I did it all as part of my electronics degree.... - Altera_Forum
Honored Contributor
or, in VHDL, do the following:
its far far easier :) (try not to mix signed/unsigned logic)signal ina, inb : unsigned(8 downto 0); signal mult : unsigned(17 downto 0); begin process(clk) begin if rising_edge(clk) then mult <= ina * inb; end if; end process; - Altera_Forum
Honored Contributor
Thanks Tricky.
It does really work. So in principle you are doing what altera never tell us....as usual. To use unsigned, given a signed input: 1) double extend input width using sign extension 2) truncate output to double inputwidth Very useful discussion.