R
Rhydian
Hi,
I'm trying to debug a Cyclone design which writes values taken from a
lookup table to the address inputs of a crosspoint analog switch. The
problem is that everything looks OK in the Quartus simulator, but when
I test the design on the target hardware it seems to be pulling the
wrong values out of the LUT. I have tried enabling SignalTap and
probing the output pins during the write operation, SignalTap reports
correct operation but the outputs, as measured on a real logic
analyser, are wrong.
E.g. for CHANNEL=1, eeprom_en='0', path=0 I should get 0,0,0,0,B,A,
3,2, I actually get 0,0,0,0,9,8,3,2
The lookup table is implemented thus:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity xpswitch is
generic(PLL_CLK_FREQ : integer;
CHANNEL : integer);
port(
pll_clk : in std_logic;
sys_rst : in std_logic;
path_index : in integer range 0 to 7;
eeprom_en : in std_logic;
go : in std_logic;
busy : out std_logic;
AX : out std_logic_vector(3 downto 0);
AY : out std_logic_vector(2 downto 0);
CS : out std_logic;
DAT : buffer std_logic;
RST : out std_logic;
STRB : out std_logic
);
end xpswitch;
architecture rtl of xpswitch is
type t_ax_lut is array(0 to 7) of std_logic_vector(3 downto 0);
signal ax_lut : t_ax_lut;
signal ay_count : integer range 0 to 7;
begin
p_lut : process(eeprom_en, path_index) begin
case CHANNEL is
when 1 =>
if(eeprom_en = '1') then
case path_index is
when 0 => ax_lut <= (x"7", x"6", x"8", x"9", x"B", x"A", x"3",
x"2");
when 1 => ax_lut <= (x"7", x"6", x"8", x"9", x"0", x"0", x"0",
x"0");
when 2 => ax_lut <= (x"7", x"6", x"8", x"9", x"4", x"5", x"E",
x"F");
when 3 => ax_lut <= (x"7", x"6", x"8", x"9", x"0", x"0", x"0",
x"0");
when 4 => ax_lut <= (x"7", x"6", x"8", x"9", x"3", x"2", x"B",
x"A");
when 5 => ax_lut <= (x"7", x"6", x"8", x"9", x"0", x"0", x"0",
x"0");
when 6 => ax_lut <= (x"7", x"6", x"8", x"9", x"E", x"F", x"4",
x"5");
when 7 => ax_lut <= (x"7", x"6", x"8", x"9", x"0", x"0", x"0",
x"0");
end case;
else
case path_index is
when 0 => ax_lut <= (x"0", x"0", x"0", x"0", x"B", x"A", x"3",
x"2");
when 1 => ax_lut <= (x"0", x"0", x"0", x"0", x"9", x"8", x"6",
x"7");
when 2 => ax_lut <= (x"0", x"0", x"0", x"0", x"4", x"5", x"E",
x"F");
when 3 => ax_lut <= (x"0", x"0", x"0", x"0", x"6", x"7", x"9",
x"8");
when 4 => ax_lut <= (x"0", x"0", x"0", x"0", x"3", x"2", x"B",
x"A");
when 5 => ax_lut <= (x"0", x"0", x"0", x"0", x"9", x"8", x"6",
x"7");
when 6 => ax_lut <= (x"0", x"0", x"0", x"0", x"E", x"F", x"4",
x"5");
when 7 => ax_lut <= (x"0", x"0", x"0", x"0", x"6", x"7", x"9",
x"8");
end case;
end if;
when 2 =>
if(eeprom_en = '1') then
case path_index is
when 0 => ax_lut <= (x"3", x"2", x"A", x"B", x"8", x"9", x"7",
x"6");
when 1 => ax_lut <= (x"0", x"0", x"0", x"0", x"8", x"9", x"7",
x"6");
when 2 => ax_lut <= (x"E", x"F", x"5", x"4", x"8", x"9", x"7",
x"6");
when 3 => ax_lut <= (x"0", x"0", x"0", x"0", x"8", x"9", x"7",
x"6");
when 4 => ax_lut <= (x"B", x"A", x"2", x"3", x"8", x"9", x"7",
x"6");
when 5 => ax_lut <= (x"0", x"0", x"0", x"0", x"8", x"9", x"7",
x"6");
when 6 => ax_lut <= (x"4", x"5", x"F", x"E", x"8", x"9", x"7",
x"6");
when 7 => ax_lut <= (x"0", x"0", x"0", x"0", x"8", x"9", x"7",
x"6");
end case;
else
case path_index is
when 0 => ax_lut <= (x"3", x"2", x"A", x"B", x"0", x"0", x"0",
x"0");
when 1 => ax_lut <= (x"6", x"7", x"8", x"9", x"0", x"0", x"0",
x"0");
when 2 => ax_lut <= (x"E", x"F", x"5", x"4", x"0", x"0", x"0",
x"0");
when 3 => ax_lut <= (x"9", x"8", x"7", x"6", x"0", x"0", x"0",
x"0");
when 4 => ax_lut <= (x"B", x"A", x"2", x"3", x"0", x"0", x"0",
x"0");
when 5 => ax_lut <= (x"6", x"7", x"8", x"9", x"0", x"0", x"0",
x"0");
when 6 => ax_lut <= (x"4", x"5", x"F", x"E", x"0", x"0", x"0",
x"0");
when 7 => ax_lut <= (x"9", x"8", x"7", x"6", x"0", x"0", x"0",
x"0");
end case;
end if;
when 3 =>
if(eeprom_en = '1') then
case path_index is
when 0 => ax_lut <= (x"B", x"A", x"6", x"7", x"4", x"5", x"3",
x"2");
when 1 => ax_lut <= (x"0", x"0", x"0", x"0", x"4", x"5", x"3",
x"2");
when 2 => ax_lut <= (x"8", x"9", x"F", x"E", x"4", x"5", x"3",
x"2");
when 3 => ax_lut <= (x"0", x"0", x"0", x"0", x"4", x"5", x"3",
x"2");
when 4 => ax_lut <= (x"7", x"6", x"A", x"B", x"4", x"5", x"3",
x"2");
when 5 => ax_lut <= (x"0", x"0", x"0", x"0", x"4", x"5", x"3",
x"2");
when 6 => ax_lut <= (x"E", x"F", x"9", x"8", x"4", x"5", x"3",
x"2");
when 7 => ax_lut <= (x"0", x"0", x"0", x"0", x"4", x"5", x"3",
x"2");
end case;
else
case path_index is
when 0 => ax_lut <= (x"B", x"A", x"6", x"7", x"0", x"0", x"0",
x"0");
when 1 => ax_lut <= (x"5", x"4", x"3", x"2", x"0", x"0", x"0",
x"0");
when 2 => ax_lut <= (x"8", x"9", x"F", x"E", x"0", x"0", x"0",
x"0");
when 3 => ax_lut <= (x"2", x"3", x"4", x"5", x"0", x"0", x"0",
x"0");
when 4 => ax_lut <= (x"7", x"6", x"A", x"B", x"0", x"0", x"0",
x"0");
when 5 => ax_lut <= (x"5", x"4", x"3", x"2", x"0", x"0", x"0",
x"0");
when 6 => ax_lut <= (x"E", x"F", x"9", x"8", x"0", x"0", x"0",
x"0");
when 7 => ax_lut <= (x"2", x"3", x"4", x"5", x"0", x"0", x"0",
x"0");
end case;
end if;
when others =>
end case;
end process;
AX <= ax_lut(ay_count);
There are 3 instances of this code in the design, with different
switch mappings selected by the CHANNEL parameter. They all show the
same problem, 'B','A' is consistently replaced by '9','8'.
I can't resolve this discrepancy I'm seeing between what the tools are
telling me and the behaviour when running on the target. The internal
PLL is being used to generate a 57.6 MHz global clock; Quartus timing
analysis shows f_max as about 85 MHz so i don't think it is a timing
issue. I have checked the pin assignments by driving the AX outputs
with a 4-bit counter which cycles continuously, this works correctly
as seen on the simulator and the external logic analyser.
Any ideas? I have raised a support case with Altera, no response as
yet.
TIA
R.
I'm trying to debug a Cyclone design which writes values taken from a
lookup table to the address inputs of a crosspoint analog switch. The
problem is that everything looks OK in the Quartus simulator, but when
I test the design on the target hardware it seems to be pulling the
wrong values out of the LUT. I have tried enabling SignalTap and
probing the output pins during the write operation, SignalTap reports
correct operation but the outputs, as measured on a real logic
analyser, are wrong.
E.g. for CHANNEL=1, eeprom_en='0', path=0 I should get 0,0,0,0,B,A,
3,2, I actually get 0,0,0,0,9,8,3,2
The lookup table is implemented thus:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity xpswitch is
generic(PLL_CLK_FREQ : integer;
CHANNEL : integer);
port(
pll_clk : in std_logic;
sys_rst : in std_logic;
path_index : in integer range 0 to 7;
eeprom_en : in std_logic;
go : in std_logic;
busy : out std_logic;
AX : out std_logic_vector(3 downto 0);
AY : out std_logic_vector(2 downto 0);
CS : out std_logic;
DAT : buffer std_logic;
RST : out std_logic;
STRB : out std_logic
);
end xpswitch;
architecture rtl of xpswitch is
type t_ax_lut is array(0 to 7) of std_logic_vector(3 downto 0);
signal ax_lut : t_ax_lut;
signal ay_count : integer range 0 to 7;
begin
p_lut : process(eeprom_en, path_index) begin
case CHANNEL is
when 1 =>
if(eeprom_en = '1') then
case path_index is
when 0 => ax_lut <= (x"7", x"6", x"8", x"9", x"B", x"A", x"3",
x"2");
when 1 => ax_lut <= (x"7", x"6", x"8", x"9", x"0", x"0", x"0",
x"0");
when 2 => ax_lut <= (x"7", x"6", x"8", x"9", x"4", x"5", x"E",
x"F");
when 3 => ax_lut <= (x"7", x"6", x"8", x"9", x"0", x"0", x"0",
x"0");
when 4 => ax_lut <= (x"7", x"6", x"8", x"9", x"3", x"2", x"B",
x"A");
when 5 => ax_lut <= (x"7", x"6", x"8", x"9", x"0", x"0", x"0",
x"0");
when 6 => ax_lut <= (x"7", x"6", x"8", x"9", x"E", x"F", x"4",
x"5");
when 7 => ax_lut <= (x"7", x"6", x"8", x"9", x"0", x"0", x"0",
x"0");
end case;
else
case path_index is
when 0 => ax_lut <= (x"0", x"0", x"0", x"0", x"B", x"A", x"3",
x"2");
when 1 => ax_lut <= (x"0", x"0", x"0", x"0", x"9", x"8", x"6",
x"7");
when 2 => ax_lut <= (x"0", x"0", x"0", x"0", x"4", x"5", x"E",
x"F");
when 3 => ax_lut <= (x"0", x"0", x"0", x"0", x"6", x"7", x"9",
x"8");
when 4 => ax_lut <= (x"0", x"0", x"0", x"0", x"3", x"2", x"B",
x"A");
when 5 => ax_lut <= (x"0", x"0", x"0", x"0", x"9", x"8", x"6",
x"7");
when 6 => ax_lut <= (x"0", x"0", x"0", x"0", x"E", x"F", x"4",
x"5");
when 7 => ax_lut <= (x"0", x"0", x"0", x"0", x"6", x"7", x"9",
x"8");
end case;
end if;
when 2 =>
if(eeprom_en = '1') then
case path_index is
when 0 => ax_lut <= (x"3", x"2", x"A", x"B", x"8", x"9", x"7",
x"6");
when 1 => ax_lut <= (x"0", x"0", x"0", x"0", x"8", x"9", x"7",
x"6");
when 2 => ax_lut <= (x"E", x"F", x"5", x"4", x"8", x"9", x"7",
x"6");
when 3 => ax_lut <= (x"0", x"0", x"0", x"0", x"8", x"9", x"7",
x"6");
when 4 => ax_lut <= (x"B", x"A", x"2", x"3", x"8", x"9", x"7",
x"6");
when 5 => ax_lut <= (x"0", x"0", x"0", x"0", x"8", x"9", x"7",
x"6");
when 6 => ax_lut <= (x"4", x"5", x"F", x"E", x"8", x"9", x"7",
x"6");
when 7 => ax_lut <= (x"0", x"0", x"0", x"0", x"8", x"9", x"7",
x"6");
end case;
else
case path_index is
when 0 => ax_lut <= (x"3", x"2", x"A", x"B", x"0", x"0", x"0",
x"0");
when 1 => ax_lut <= (x"6", x"7", x"8", x"9", x"0", x"0", x"0",
x"0");
when 2 => ax_lut <= (x"E", x"F", x"5", x"4", x"0", x"0", x"0",
x"0");
when 3 => ax_lut <= (x"9", x"8", x"7", x"6", x"0", x"0", x"0",
x"0");
when 4 => ax_lut <= (x"B", x"A", x"2", x"3", x"0", x"0", x"0",
x"0");
when 5 => ax_lut <= (x"6", x"7", x"8", x"9", x"0", x"0", x"0",
x"0");
when 6 => ax_lut <= (x"4", x"5", x"F", x"E", x"0", x"0", x"0",
x"0");
when 7 => ax_lut <= (x"9", x"8", x"7", x"6", x"0", x"0", x"0",
x"0");
end case;
end if;
when 3 =>
if(eeprom_en = '1') then
case path_index is
when 0 => ax_lut <= (x"B", x"A", x"6", x"7", x"4", x"5", x"3",
x"2");
when 1 => ax_lut <= (x"0", x"0", x"0", x"0", x"4", x"5", x"3",
x"2");
when 2 => ax_lut <= (x"8", x"9", x"F", x"E", x"4", x"5", x"3",
x"2");
when 3 => ax_lut <= (x"0", x"0", x"0", x"0", x"4", x"5", x"3",
x"2");
when 4 => ax_lut <= (x"7", x"6", x"A", x"B", x"4", x"5", x"3",
x"2");
when 5 => ax_lut <= (x"0", x"0", x"0", x"0", x"4", x"5", x"3",
x"2");
when 6 => ax_lut <= (x"E", x"F", x"9", x"8", x"4", x"5", x"3",
x"2");
when 7 => ax_lut <= (x"0", x"0", x"0", x"0", x"4", x"5", x"3",
x"2");
end case;
else
case path_index is
when 0 => ax_lut <= (x"B", x"A", x"6", x"7", x"0", x"0", x"0",
x"0");
when 1 => ax_lut <= (x"5", x"4", x"3", x"2", x"0", x"0", x"0",
x"0");
when 2 => ax_lut <= (x"8", x"9", x"F", x"E", x"0", x"0", x"0",
x"0");
when 3 => ax_lut <= (x"2", x"3", x"4", x"5", x"0", x"0", x"0",
x"0");
when 4 => ax_lut <= (x"7", x"6", x"A", x"B", x"0", x"0", x"0",
x"0");
when 5 => ax_lut <= (x"5", x"4", x"3", x"2", x"0", x"0", x"0",
x"0");
when 6 => ax_lut <= (x"E", x"F", x"9", x"8", x"0", x"0", x"0",
x"0");
when 7 => ax_lut <= (x"2", x"3", x"4", x"5", x"0", x"0", x"0",
x"0");
end case;
end if;
when others =>
end case;
end process;
AX <= ax_lut(ay_count);
There are 3 instances of this code in the design, with different
switch mappings selected by the CHANNEL parameter. They all show the
same problem, 'B','A' is consistently replaced by '9','8'.
I can't resolve this discrepancy I'm seeing between what the tools are
telling me and the behaviour when running on the target. The internal
PLL is being used to generate a 57.6 MHz global clock; Quartus timing
analysis shows f_max as about 85 MHz so i don't think it is a timing
issue. I have checked the pin assignments by driving the AX outputs
with a 4-bit counter which cycles continuously, this works correctly
as seen on the simulator and the external logic analyser.
Any ideas? I have raised a support case with Altera, no response as
yet.
TIA
R.