Vivado is intensely frustrating

R

Rob Gaddi

Guest
So, the following ROM initialization code should be entirely
synthesizable. Not so, according to the latest version of Vivado,
which proudly declares "ignoring unsynthesizable construct:
non-synthesizable procedure call", zeros out my ROM, and then optimizes
it away.

And yes, I have ways to work around this (though they force me to carry
far too much of the policy from my VHDL back into my coefficient
generating code). I just wanted to call out, in a public forum, that
the inability to handle something as trivial as this points out how
fundamentally brain-damaged this software is. I'd submit a WebCase,
but the bean-counters at Xilinx have decided to no longer accept those
for fear that customers may want support, or worse yet report bugs.

----

function create_index(
filter : integer range 0 to 1;
phase : integer range 0 to 63;
tap : integer range 0 to 14
) return natural is
begin
return (filter * 1024) + (tap * 64) + phase;
end function create_index;

constant LONGFILTER : integer := 0;
constant SHORTFILTER : integer := 1;

type t_coef is record
c : signed(17 downto 0); -- S1.17
dc : signed(17 downto 0); -- S1.17
end record;
type t_coef_rom is array(0 to 2047) of t_coef;

impure function GetCoefROM return t_coef_rom is
-- Load up our filter coefficients from a file. The file format is
-- 960 lines of (c dc) pairs, all as real numbers.
--
variable rv : t_coef_rom;

procedure GetFilterData (
filename : string;
filter : integer
) is
file src : text open READ_MODE is filename;
variable ln : line;
variable c : integer range -(2**17) to (2**17)-1;
variable dc : integer range -(2**17) to (2**17)-1;
variable r : real;

variable phase : integer range 0 to 63 := 0;
variable tap : integer := 0;
variable idx : integer range rv'range;
variable lines : natural := 0;

begin
while not endfile(src) loop
readline(src, ln);
read(ln, r);
c := INTEGER(round(r * 2.0**17));
read(ln, r);
dc := INTEGER(round(r * 2.0**17));

idx := create_index(filter, phase, tap);
rv(idx).c := TO_SIGNED(c, 18);
rv(idx).dc := TO_SIGNED(dc, 18);

if phase = 63 then
phase := 0;
tap := tap + 1;
else
phase := phase + 1;
end if;
lines := lines + 1;
end loop;

deallocate(ln);
write(ln, string'("Read "));
write(ln, lines);
write(ln, string'(" lines from "));
write(ln, filename);
writeline(OUTPUT, ln);

end procedure GetFilterData;

begin
for i in rv'range loop
rv(i) := (others => (others => '0'));
end loop;

GetFilterData("longfilter.txt", LONGFILTER);
GetFilterData("shortfilter.txt", SHORTFILTER);
return rv;
end function GetCoefROM;

-- Giant table of FIR coefficients.
signal coef_rom : t_coef_rom := GetCoefROM;

--
Rob Gaddi, Highland Technology -- www.highlandtechnology.com
Email address domain is currently out of order. See above to fix.
 
El martes, 27 de enero de 2015, 16:46:58 (UTC-3), Rob Gaddi escribió:
So, the following ROM initialization code should be entirely
synthesizable. Not so, according to the latest version of Vivado,
which proudly declares "ignoring unsynthesizable construct:
non-synthesizable procedure call", zeros out my ROM, and then optimizes
it away.

And yes, I have ways to work around this (though they force me to carry
far too much of the policy from my VHDL back into my coefficient
generating code). I just wanted to call out, in a public forum, that
the inability to handle something as trivial as this points out how
fundamentally brain-damaged this software is. I'd submit a WebCase,
but the bean-counters at Xilinx have decided to no longer accept those
for fear that customers may want support, or worse yet report bugs.

----

function create_index(
filter : integer range 0 to 1;
phase : integer range 0 to 63;
tap : integer range 0 to 14
) return natural is
begin
return (filter * 1024) + (tap * 64) + phase;
end function create_index;

constant LONGFILTER : integer := 0;
constant SHORTFILTER : integer := 1;

type t_coef is record
c : signed(17 downto 0); -- S1.17
dc : signed(17 downto 0); -- S1.17
end record;
type t_coef_rom is array(0 to 2047) of t_coef;

impure function GetCoefROM return t_coef_rom is
-- Load up our filter coefficients from a file. The file format is
-- 960 lines of (c dc) pairs, all as real numbers.
--
variable rv : t_coef_rom;

procedure GetFilterData (
filename : string;
filter : integer
) is
file src : text open READ_MODE is filename;
variable ln : line;
variable c : integer range -(2**17) to (2**17)-1;
variable dc : integer range -(2**17) to (2**17)-1;
variable r : real;

variable phase : integer range 0 to 63 := 0;
variable tap : integer := 0;
variable idx : integer range rv'range;
variable lines : natural := 0;

begin
while not endfile(src) loop
readline(src, ln);
read(ln, r);
c := INTEGER(round(r * 2.0**17));
read(ln, r);
dc := INTEGER(round(r * 2.0**17));

idx := create_index(filter, phase, tap);
rv(idx).c := TO_SIGNED(c, 18);
rv(idx).dc := TO_SIGNED(dc, 18);

if phase = 63 then
phase := 0;
tap := tap + 1;
else
phase := phase + 1;
end if;
lines := lines + 1;
end loop;

deallocate(ln);
write(ln, string'("Read "));
write(ln, lines);
write(ln, string'(" lines from "));
write(ln, filename);
writeline(OUTPUT, ln);

end procedure GetFilterData;

begin
for i in rv'range loop
rv(i) := (others => (others => '0'));
end loop;

GetFilterData("longfilter.txt", LONGFILTER);
GetFilterData("shortfilter.txt", SHORTFILTER);
return rv;
end function GetCoefROM;

-- Giant table of FIR coefficients.
signal coef_rom : t_coef_rom := GetCoefROM;

--
Rob Gaddi, Highland Technology -- www.highlandtechnology.com
Email address domain is currently out of order. See above to fix.

Feel your frustation. I had a code that inferred blockRAMs perfectly according to XST guidelines. Run it on Vivado, and then suddenly my design took the 400% of the FFs in the FPGA.

Also Vivado synthesis does not support dynamic loops, something like this is not allowed:

--a is a variable
for i in 0 to a-1 loop
....
end loop;

but this is allowed:

--i, a are variables, MAX should be a constant, for example the max binary ----value of an SLV

i:=0;
while i < MAX loop
....do something here
i:=i+1;
if i = a then exit; end if;
end loop;


Also...signals marked for debug do not have their name preserved at all times, gets very frustrating going into the post-synthesis debug mode to add/remove them...

I guess since it is very it is expected, but I wonder why they felt they should re-write XST from the beginning, and WHY, oh, WHY, leave Spartan6 out, there is a still a market for Spartan 6.
 
El martes, 27 de enero de 2015, 16:46:58 (UTC-3), Rob Gaddi escribió:
So, the following ROM initialization code should be entirely
synthesizable. Not so, according to the latest version of Vivado,
which proudly declares "ignoring unsynthesizable construct:
non-synthesizable procedure call", zeros out my ROM, and then optimizes
it away.

And yes, I have ways to work around this (though they force me to carry
far too much of the policy from my VHDL back into my coefficient
generating code). I just wanted to call out, in a public forum, that
the inability to handle something as trivial as this points out how
fundamentally brain-damaged this software is. I'd submit a WebCase,
but the bean-counters at Xilinx have decided to no longer accept those
for fear that customers may want support, or worse yet report bugs.

----

function create_index(
filter : integer range 0 to 1;
phase : integer range 0 to 63;
tap : integer range 0 to 14
) return natural is
begin
return (filter * 1024) + (tap * 64) + phase;
end function create_index;

constant LONGFILTER : integer := 0;
constant SHORTFILTER : integer := 1;

type t_coef is record
c : signed(17 downto 0); -- S1.17
dc : signed(17 downto 0); -- S1.17
end record;
type t_coef_rom is array(0 to 2047) of t_coef;

impure function GetCoefROM return t_coef_rom is
-- Load up our filter coefficients from a file. The file format is
-- 960 lines of (c dc) pairs, all as real numbers.
--
variable rv : t_coef_rom;

procedure GetFilterData (
filename : string;
filter : integer
) is
file src : text open READ_MODE is filename;
variable ln : line;
variable c : integer range -(2**17) to (2**17)-1;
variable dc : integer range -(2**17) to (2**17)-1;
variable r : real;

variable phase : integer range 0 to 63 := 0;
variable tap : integer := 0;
variable idx : integer range rv'range;
variable lines : natural := 0;

begin
while not endfile(src) loop
readline(src, ln);
read(ln, r);
c := INTEGER(round(r * 2.0**17));
read(ln, r);
dc := INTEGER(round(r * 2.0**17));

idx := create_index(filter, phase, tap);
rv(idx).c := TO_SIGNED(c, 18);
rv(idx).dc := TO_SIGNED(dc, 18);

if phase = 63 then
phase := 0;
tap := tap + 1;
else
phase := phase + 1;
end if;
lines := lines + 1;
end loop;

deallocate(ln);
write(ln, string'("Read "));
write(ln, lines);
write(ln, string'(" lines from "));
write(ln, filename);
writeline(OUTPUT, ln);

end procedure GetFilterData;

begin
for i in rv'range loop
rv(i) := (others => (others => '0'));
end loop;

GetFilterData("longfilter.txt", LONGFILTER);
GetFilterData("shortfilter.txt", SHORTFILTER);
return rv;
end function GetCoefROM;

-- Giant table of FIR coefficients.
signal coef_rom : t_coef_rom := GetCoefROM;

--
Rob Gaddi, Highland Technology -- www.highlandtechnology.com
Email address domain is currently out of order. See above to fix.

Also, maybe someone could shed some light on this post: http://forums.xilinx.com/t5/Synthesis/Different-Synthesis-Results/td-p/558576
 
On Tue, 27 Jan 2015 11:46:56 -0800
Rob Gaddi <rgaddi@technologyhighland.invalid> wrote:

So, the following ROM initialization code should be entirely
synthesizable. Not so, according to the latest version of Vivado,
which proudly declares "ignoring unsynthesizable construct:
non-synthesizable procedure call", zeros out my ROM, and then optimizes
it away.

And yes, I have ways to work around this (though they force me to carry
far too much of the policy from my VHDL back into my coefficient
generating code). I just wanted to call out, in a public forum, that
the inability to handle something as trivial as this points out how
fundamentally brain-damaged this software is. I'd submit a WebCase,
but the bean-counters at Xilinx have decided to no longer accept those
for fear that customers may want support, or worse yet report bugs.

[snip]

Follow up for using textio under Vivado. Not only can't it read reals
from a file, but it can't read integers either. Not only that, but if
you actually bother to use the 3 argument form with the GOOD output, it
will always set GOOD to true even when it can't read anything.

Just sloppy. A working textio for all the types defined in std has
been a part of the spec for a LONG time.

--
Rob Gaddi, Highland Technology -- www.highlandtechnology.com
Email address domain is currently out of order. See above to fix.
 

Welcome to EDABoard.com

Sponsor

Back
Top