08-16-2009 02:23 PM
Dear Community,
in a VHDL design I'm using the sfixed (signed fixed point) data type from the floatfixlib (part of VHDL 2008 standard and part of the ieee_proposed library delivered with ISE). In order to have a nice and proper coding style and to enable a parametrizable design, I'm using arrays of sfixed. In RTL simulation verification is passed perfectly, however, when mapping the design onto an FPGA board (V2P100) for prototyping, the behavior is wrong. After tidious sessions with logic-analyzers, post-place&route and post-synthesis simulation, I've been able to narrow the issues down to a set of testcass which seem to indicate that XST is interpreting the elements of an array of sfixed as unsigned values in "some" cases. Unfortunately, I could not find any hint on this issue in the internet/xilinx forums and ARs.
I hope, the information provided here is suitable to reproduce the problem on other systems. It would be really great if someone could provide a solution/workaround to get a correct synthesis result for V2P100 devices and ISE <= 10.1sp3 (unfortunately we are limited to this device/tools combination) without modifying existing code too much.
All necessary information/source code can be found below and in the attached zip archive. If there is any question left open, please do not hesitate to concat me.
With best regards and thanks in advance,
Martin Witte
Summary:
Under many circumstances, Xilinx XST seems to handle signed sfixed
array signals as unsigned values. This is a serious problem with
comparisons and bitwidth increasing multiplications/additions/...
XST seems to generate incorrect logic, making FPGA prototype
implementations fail badly which are using the floatfixlib library
as part of the VHDL 2008 standard.
Files provided:
* fixedpt_test.vhd : entity with test cases
* pack.vhd : package with type definitions and constants
* fixedpt_test_synthesis.vhd : example synthesis result
(post-synthesis simulation model)
for a V2P100 device, ISE 10.1 SP3
Test Case Project Setup
To synthesize this test case, you need the following steps:
* Create a new ISE project for your favourite FPGA type and
add the files "fixedpt_test.vhd" and "pack.vhd" to the
project (library "work")
* Create a library called "ieee_proposed" and add the file
<path-to-ise>/vhdl/src/ieee_proposed/fixed_pkg_c.vhd
Default settings should be fine for the project. I tried to
switch off / change various synthesis settings without any
difference in the synthesis result.
Tested Tools/Versions/Settings
* ISE 9.2 SP4, Linux, 32 bit, Virtex 2 Pro 100
* ISE 10.1 SP3, Linux, 64 bit, Virtex 2 Pro 100
* ISE 11.1 Linux, 64 bit, Virtex4 SX35
* floatfixlib provided by Xilinx
(<path-to-ise>/vhdl/src/ieee_proposed/fixed_pkg_c.vhd)
* floatfixlib provided by David Bishop
How to check for (in)correctness?
* Run the synthesis
* Generate a post-synthesis simulation model. You'll find the
generated file under
<ise-project-dir>/netgen/synthesis/fixedpt_test_synthesis.vhd
* Instead spending effort to set up a simulation project, I
recommend to have a look into the file "fixedpt_test_synthesis.vhd".
You can already observe the issues by watching out for hard wired
inputs for the output buffer cells of the cmp_res signals (would not
be hard wired if synthesized correctly). Furthermore, depending on
the FPGA architecture, you can easily detect the wrong wiring of the
MSBs of the multiplieres synthesized incorrectly (hard wired to Gnd
instead of sign extended) - particularly easy for V2P devices.
Test Cases:
* Comparisons x < 0
Of course, for this particular sign check, we could simply use the MSB.
However, these test cases are used to have an easy verification
flow to analyze the general problem XST has with the signedness of
sfixed array elements. If synthesized correctly, the outputs of the
cmp_res signals are not constant, otherwise they are typically wired to
'1'/VCC. This can easily be observed without simulation by just looking
at the post-synthesis VHDL model (see above).
The following tests have been implemented:
cmp_res( 4) passed: non-array sfixed port
cmp_res( 5) passed: SIGNED array element
cmp_res( 0) FAILED: sfixed array element
cmp_res( 1) FAILED: sfixed array element with explicite type cast
to sfixed by function call
cmp_res( 9) FAILED: sfixed array element with explicite type cast
to sfixed by inlined conversions
BUT: onyl fails if (see cmp_res(15))
"recast_sig2 <= fsfixed(test_sfixed_array(1))"
cmp_res( 9) passed: sfixed array element with explicite type cast
to sfixed by inlined conversions
BUT: onyl passed if (see cmp_res(15))
"recast_sig2 <= test_sfixed_array(1)"
cmp_res( 3) passed: sfixed array element with explicite type cast
to sfixed (temporary signal) by function call
cmp_res(15) passed: sfixed array element assignment to sfixed
temporary signal
BUT: This line influences cmp_res(14)!!!
(for details, please look at the comments in the
code)
cmp_res( 6) FAILED: sfixed array element with assignment to sfixed
temporary variable (in process)
cmp_res(14) passed: sfixed array element with explicite type cast
to sfixed variable by function call (in process)
BUT: onyl passed if (see cmp_res(15))
"recast_sig2 <= test_sfixed_array(1)"
cmp_res(14) FAILED: sfixed array element with explicite type cast
to sfixed variable by function call (in process)
BUT: onyl fails if (see cmp_res(15))
"recast_sig2 <= fsfixed(test_sfixed_array(1))"
cmp_res( 2) FAILED: sfixed array element (port array copied to
local array)
cmp_res( 7) passed: sfixed array element assigned to shared sfixed
variable
cmp_res( 8) FAILED: sfixed array assigned to shared sfixed
array variable
cmp_res(10) passed: neg. sfixed constant array element
cmp_res(11) passed: pos. sfixed constant array element
cmp_res(12) FAILED: local sfixed array element (result of addition)
The adder inputs are non-array std_logic_vector
ports casted to sfixed
cmp_res(13) FAILED: local sfixed array element (result of subtraction)
The adder inputs are non-array std_logic_vector
ports casted to sfixed
* Multiplication tests
mul_res1 FAILED: plain multiplication of sfixed(6 downto -6) array
elements. The wiring of the 18x18multiplier has
top 6 MSBs set to '0' which results in an unsigned
multiplication.
Bonus Package: ISE 10.1sp3 synthesis fails with
internal error if array elements 2 and 3 are
multiplied:
"Xst:1709 - Edge <l_ext_index0000>, from block <fixedpt_test>, has no source"
mul_res2 passed: multiplication of local sfixed signal with sfixed
array port element. Uses only MSBs of 18x18mul
without the need for explicit sign extension.
mul_res3 (FAILED/passed): Multiplication with helper-workaround-function
The sfixed array elements are manually sign-extended
to the result bitwidth. Therefore, the numerical
result is correct though if it is still handled as
unsigned multiplication: The operands are aligned
with the LSBs of the 18x18mul inputs and explicitly
sign extended.
08-19-2009 01:48 AM
Hi all,
no solution yet, but at least the urgency solving this specific XST problem has been relaxed - we are in the lucky situation to have also lics for Synplify which synthesizes correct logic. Since this switch to the Synplicity tool flow, our prototype is up and running perfectly now.
Anyway, I believe, that the issue posted here is still worth being investigated in order to improve XST.
Best regards,
Martin