R
rickman
Guest
Here is some code showing a problem I am having with Quartus. Seems
using a type cast with an aggregate throws it all off. This is just a
simple test case which uses a 16 bit bidir bus to write to an 8 bit
register and read it back.
-- VHDL created by Rick Collins
Library ieee;
Use ieee.std_logic_1164.all;
Use ieee.numeric_std.all;
ENTITY Test1 is
PORT (
Data : INOUT STD_LOGIC_VECTOR (15 DOWNTO 0);
Addr : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
CSN : IN STD_LOGIC;
RDN : IN STD_LOGIC;
WRN : IN STD_LOGIC;
LED : OUT STD_LOGIC;
Reset : IN STD_LOGIC;
SysClk : IN STD_LOGIC); -- 50 MHz Clock
END Test1;
ARCHITECTURE behavior OF Test1 IS
constant SysClkRate : real := 50000.0; -- Rate in KHz
signal ScratchReg : STD_LOGIC_VECTOR (7 downto 0);
signal DataOut : STD_LOGIC_VECTOR (15 downto 0);
signal ReadScratchReg : STD_LOGIC;
BEGIN
ReadScratchReg <= (not RDN) WHEN (Addr="00001000") and (CSN='0')
ELSE '0';
-- VERSION 1
-- These lines work correctly
-- Data (15 downto 8) <= (others => '0') WHEN (ReadScratchReg = '1')
-- ELSE (others => 'Z');
-- Data (7 downto 0) <= ScratchReg WHEN (ReadScratchReg = '1')
-- ELSE (others => 'Z');
-- VERSION 2
-- This line fails by disabling the tristate buffers
-- Data <= STD_LOGIC_VECTOR (15 downto 8)'(others => '0') &
ScratchReg WHEN (ReadScratchReg = '1')
-- ELSE (others => 'Z');
-- The difference seems to be the use of the type cast.
-- Using a type cast with the (others => aggregate seems to fail in
other cases as well.
-- VERSION 3
-- This version produces open drain outputs
Data <= DataOut WHEN (ReadScratchReg = '1')
ELSE (others => 'Z');
-- This seems to work ok
-- DataOut <= "00000000" & ScratchReg;
-- This produces no register and open drain drivers
DataOut <= STD_LOGIC_VECTOR (15 downto 8)'(others => '0') &
ScratchReg;
ScratchRegister: process (SysClk, Reset) begin
if (Reset = '1') then
ScratchReg <= (others => '0');
elsif (rising_edge(SysClk)) then
if (Addr = "00001000") THEN
if (WRN = '0' and CSN = '0') THEN
ScratchReg <= Data (7 downto 0);
end if;
end if;
end if;
end process ScratchRegister;
LED <= ScratchReg(0) AND ReadScratchReg;
END behavior;
As seen under VERSION 3, using the type cast on an aggregate produces a
design with the register not driving the bidir output pins. I don't see
any messages saying the registers were deleted, but the only bit that
remains is the zero bit which drives the LED output. All of the DataOut
nets are listed as undriven and tied to ground.
Using a fixed size vector seems to work ok. It also works ok if I
separate the two halves of the bus and don't use a type cast on the
aggregates. Is this a Quartus bug?
I tried contacting Altera support, but after waiting on hold to talk to
someone, I got put on hold again and then cut off.
--
Rick "rickman" Collins
rick.collins@XYarius.com
Ignore the reply address. To email me use the above address with the XY
removed.
Arius - A Signal Processing Solutions Company
Specializing in DSP and FPGA design URL http://www.arius.com
4 King Ave 301-682-7772 Voice
Frederick, MD 21701-3110 301-682-7666 FAX
using a type cast with an aggregate throws it all off. This is just a
simple test case which uses a 16 bit bidir bus to write to an 8 bit
register and read it back.
-- VHDL created by Rick Collins
Library ieee;
Use ieee.std_logic_1164.all;
Use ieee.numeric_std.all;
ENTITY Test1 is
PORT (
Data : INOUT STD_LOGIC_VECTOR (15 DOWNTO 0);
Addr : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
CSN : IN STD_LOGIC;
RDN : IN STD_LOGIC;
WRN : IN STD_LOGIC;
LED : OUT STD_LOGIC;
Reset : IN STD_LOGIC;
SysClk : IN STD_LOGIC); -- 50 MHz Clock
END Test1;
ARCHITECTURE behavior OF Test1 IS
constant SysClkRate : real := 50000.0; -- Rate in KHz
signal ScratchReg : STD_LOGIC_VECTOR (7 downto 0);
signal DataOut : STD_LOGIC_VECTOR (15 downto 0);
signal ReadScratchReg : STD_LOGIC;
BEGIN
ReadScratchReg <= (not RDN) WHEN (Addr="00001000") and (CSN='0')
ELSE '0';
-- VERSION 1
-- These lines work correctly
-- Data (15 downto 8) <= (others => '0') WHEN (ReadScratchReg = '1')
-- ELSE (others => 'Z');
-- Data (7 downto 0) <= ScratchReg WHEN (ReadScratchReg = '1')
-- ELSE (others => 'Z');
-- VERSION 2
-- This line fails by disabling the tristate buffers
-- Data <= STD_LOGIC_VECTOR (15 downto 8)'(others => '0') &
ScratchReg WHEN (ReadScratchReg = '1')
-- ELSE (others => 'Z');
-- The difference seems to be the use of the type cast.
-- Using a type cast with the (others => aggregate seems to fail in
other cases as well.
-- VERSION 3
-- This version produces open drain outputs
Data <= DataOut WHEN (ReadScratchReg = '1')
ELSE (others => 'Z');
-- This seems to work ok
-- DataOut <= "00000000" & ScratchReg;
-- This produces no register and open drain drivers
DataOut <= STD_LOGIC_VECTOR (15 downto 8)'(others => '0') &
ScratchReg;
ScratchRegister: process (SysClk, Reset) begin
if (Reset = '1') then
ScratchReg <= (others => '0');
elsif (rising_edge(SysClk)) then
if (Addr = "00001000") THEN
if (WRN = '0' and CSN = '0') THEN
ScratchReg <= Data (7 downto 0);
end if;
end if;
end if;
end process ScratchRegister;
LED <= ScratchReg(0) AND ReadScratchReg;
END behavior;
As seen under VERSION 3, using the type cast on an aggregate produces a
design with the register not driving the bidir output pins. I don't see
any messages saying the registers were deleted, but the only bit that
remains is the zero bit which drives the LED output. All of the DataOut
nets are listed as undriven and tied to ground.
Using a fixed size vector seems to work ok. It also works ok if I
separate the two halves of the bus and don't use a type cast on the
aggregates. Is this a Quartus bug?
I tried contacting Altera support, but after waiting on hold to talk to
someone, I got put on hold again and then cut off.
--
Rick "rickman" Collins
rick.collins@XYarius.com
Ignore the reply address. To email me use the above address with the XY
removed.
Arius - A Signal Processing Solutions Company
Specializing in DSP and FPGA design URL http://www.arius.com
4 King Ave 301-682-7772 Voice
Frederick, MD 21701-3110 301-682-7666 FAX