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.
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.