01-20-2019 02:03 AM
Hi,
I've got a design in ISE where I'm comparing std_logic_vector with string literal. The string literal and the vector are of same size and I think I've made no syntax errors, but I still get the following error:
found '0' definitions of operator "=", cannot determine exact overloaded matching definition for "="
for every line where I try to find the equality of signal of type std_logic_vector to some string literal. For example, ISE complains about the following:
FIFO_WR <= (state = "101");
I've included the NUMERIC package and signal state contains exactly three elements.
Following is the full code:
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; --use IEEE.std_logic_unsigned.all; entity interface is Port ( FX2_CLK : in STD_LOGIC; FX2_PA_7 : in STD_LOGIC; FX2_flags : in STD_LOGIC_VECTOR(2 downto 0); FX2_FD : inout STD_LOGIC_VECTOR(7 downto 0); FX2_SLRD : out STD_LOGIC; FX2_SLWR : out STD_LOGIC; FX2_PA_2 : out STD_LOGIC; FX2_PA_3 : out STD_LOGIC; FX2_PA_4 : out STD_LOGIC; FX2_PA_5 : out STD_LOGIC; FX2_PA_6 : out STD_LOGIC; LED : out STD_LOGIC); end interface; architecture Behavioral of interface is -- signals for converting FX2 inputs/outputs to active-high logic and more meaningful names signal FIFO_data_in, FIFO_data_out : STD_LOGIC_VECTOR (7 downto 0) := (others => '0'); signal FIFO_pktend, FIFO_datain_oe, FIFO_dataout_oe : STD_LOGIC := '0'; signal FIFO_addr : STD_LOGIC_VECTOR (1 downto 0) := "00"; -- by default FIFO2 selected signal FIFO2_empty, FIFO2_data_available : STD_LOGIC := '0'; signal FIFO3_empty, FIFO3_data_available : STD_LOGIC := '0'; signal FIFO4_full, FIFO4_ready_to_accept_data : STD_LOGIC := '0'; signal FIFO5_full, FIFO5_ready_to_accept_data : STD_LOGIC := '0'; signal FIFO_RD, FIFO_WR : STD_LOGIC := '0'; signal CLK : STD_LOGIC := '0'; -- signals for module logic signal state : STD_LOGIC_VECTOR (2 downto 0) := "000"; signal read_byte : STD_LOGIC := '0'; signal cnt : STD_LOGIC_VECTOR(7 downto 0) := (others => '0'); begin LED<= '1'; -- convert logic FX2_PA_3 <= '1'; -- disables reset or some timer?? CLK <= FX2_CLK; FIFO2_empty <= not FX2_flags(0); FIFO3_empty <= not FX2_flags(1); FIFO4_full <= not FX2_flags(2); FIFO5_full <= not FX2_PA_7; FIFO2_data_available <= FX2_flags(0); FIFO3_data_available <= FX2_flags(1); FIFO4_ready_to_accept_data <= FX2_flags(2); FIFO5_ready_to_accept_data <= FX2_PA_7; FX2_SLRD <= not FIFO_RD; FX2_SLWR <= not FIFO_WR; FX2_PA_6 <= not FIFO_pktend; FX2_PA_2 <= not FIFO_datain_oe; (FX2_PA_5, FX2_PA_4) <= FIFO_addr; FIFO_data_in <= FX2_FD; FX2_FD <= FIFO_data_out when (FIFO_dataout_oe = '1') else "ZZZZZZZZ"; main : process (CLK) is begin if (rising_edge(CLK)) then case state is when "000" => -- idle state, wait for data to become available in FIFOs if (FIFO2_data_available = '1') then state <= "001"; end if; when "001" => -- read state, read data until FIFO is empty if (FIFO2_data_available = '0') then state <= "100"; end if; when "100" => -- cross-over state, allow one clock cycle for the FX2 bi-directional data bus to re-configure state <= "101"; when "101" => -- writing state, write the data into FIFO 4 state <= "110"; when "110" => -- packet frame ending state, signal that packet can be sent over USB line state <= "000"; when others => -- catch all state state <= "000"; end case; end if; end process main; FIFO_addr <= state(2) & '0'; -- FIFO2 or FIFO4 FIFO_RD <= (state = "001"); -- read until there is data to be read read_byte <= (state = "001") and FIFO2_data_available; -- read a byte until there is data available and in "reading" state (guarantees that the last read byte is also read althought FIFO is already empty byte_counter : process (CLK) is begin if (rising_edge(CLK)) then if (read_byte = '1') then cnt <= STD_LOGIC_VECTOR(unsigned(cnt)+1); --increment counter every time there is data to be read end if; end if; end process byte_counter; FIFO_data_out <= cnt; -- write the count of bytes received so far FIFO_WR <= (state = "101"); -- when in "writing" state FIFO_pktend <= (state = "110"); -- data has been written tot he FIFO, packte is complete and ready to be sent FIFO_datain_oe <= not state (2); -- FX2 will drive the bi-directional data bus when idle or reading FIFO_dataout_oe <= (state = "101"); -- FPGA will drive the bi-directional data bus only when in writing state end Behavioral;
Can someone please explain to me what exactly ISE does not like?
01-20-2019 06:26 AM
well done for not falling into the trap of using
std_logic_unsigned
that way lies madness.
What your experiencing is the joy of a very strongly typed language such as VHDL.
VHDL expects you to say exactly what you want to do, so
FIFO_RD <= (state = "001")
You have a logical answer being assigned to a std_logic.
logical can be true or false and std_logic can be 0,1,H,L,X,Z,- , so the system does not know how you want to assign the the true false to the std_logic.
The answer is to be explicit, as already mentioned,
You have a few of these to sort out,
I'd also look at
(FX2_PA_5, FX2_PA_4) <= FIFO_addr;
Not normal VHDL construct.
01-20-2019 05:00 AM - edited 01-20-2019 05:01 AM
It appears that you are trying to do what VHDL calls a conditional assignment statement.
Instead of your code:
FIFO_WR <= (state = "101");
..try the following:
FIFO_WR <= '1' when (state = "101") else '0';
Cheers,
Mark
01-20-2019 06:26 AM
well done for not falling into the trap of using
std_logic_unsigned
that way lies madness.
What your experiencing is the joy of a very strongly typed language such as VHDL.
VHDL expects you to say exactly what you want to do, so
FIFO_RD <= (state = "001")
You have a logical answer being assigned to a std_logic.
logical can be true or false and std_logic can be 0,1,H,L,X,Z,- , so the system does not know how you want to assign the the true false to the std_logic.
The answer is to be explicit, as already mentioned,
You have a few of these to sort out,
I'd also look at
(FX2_PA_5, FX2_PA_4) <= FIFO_addr;
Not normal VHDL construct.
01-20-2019 06:55 AM
Thank you guyts for the help, that solved my issue. Also thanks for the thorough explanations drjohnsmith!
Could you maybe explain more why the part
(FX2_PA_5, FX2_PA_4) <= FIFO_addr;
is not normal VHDL construct? Will it not do what I expect it to do?
I actually verified from Ashedens book (page 102) that this should be allowed in VHDL. He does however mention about not using sub-arrays and that types must be of same types on both sides for earlier VHDL version ('93 and '02), but still this should be allowed. Can you please explain more?
01-20-2019 07:28 AM
std_logic_unsigned - that way lies madness
But numeric_std_unsigned is perfectly good :)
FIFO_RD <= (state = "001")
Returns a boolean type (no such thing as logical type in VHDL)
Also this:
(FX2_PA_5, FX2_PA_4) <= FIFO_addr;
Is legal VHDL 2008. But that wont work with ISE.
01-20-2019 09:47 AM
Hi, thanks for clarifying.
Will the construct not work in ISE as it won't synthesize or it won't do what expected?
I've actually managed to synthesize the design and it's working on my board however as I'm not really changing FIFO address in this design and the default one ("00") is actually the correct one then I'm not sure if it actually is okay or not.
01-20-2019 09:50 AM
I made a mistake in my last post, I do actually change the FIFO address. So as it works on my board it should actually be okay with ISE 14.7, I suppose.
01-20-2019 04:09 PM - edited 01-21-2019 05:36 PM
(FX2_PA_5, FX2_PA_4) <= FIFO_addr;
Will the construct not work in ISE as it won't synthesize or it won't do what expected?
If ISE synthesis is not complaining about the assignment statement then you should be fine. I don’t use ISE anymore, but I find that synthesis and simulation in Vivado v2018.2 recognize the above assignment statement as valid for VHDL-1993 – and it simulates properly. I suspect that ISE is using VHDL-1993. -see UG626 for more information on ISE synthesis.
Also, I want to remind you that the VHDL conditional assignment:
FIFO_WR <= '1' when (state = "101") else '0';
is equivalent to:
p1: process(state) begin if (state = “101”) then FIFO_WR <= '1'; else FIFO_WR <= '0'; end if: end process p1;
but, is not equivalent to:
p2: process(clk1) begin if rising_edge(clk1) then if (state = “101”) then FIFO_WR <= '1'; else FIFO_WR <= '0'; end if: end if; end process p2;
That is, the first two create combinational logic whereas the third creates the combinational logic and a register called FIFO_WR.
Since your code uses,
FIFO_WR <= '1' when (state = "101") else '0'; FX2_SLWR <= not FIFO_WR;
then the output, FX2_SLWR, of your component, interface, will not be registered (ie. the output, FX2_SLWR, is connected to combinational logic). Sometimes, not registering your signal outputs can be a problem. For example, in the top-level component of your design, you must register signals before sending them out of the FPGA. If you instead send a signal directly from combinational logic out of the FPGA then you could also be sending glitch pulses out of the FPGA. Another example is that you must register signals before sending them to a synchronizer - otherwise you can "break" the synchronizer.
My point is, be careful using VHDL conditional assignment statements (which you seem to like) since you may inadvertently end up passing glitches around your design.
Cheers,
Mark
01-20-2019 10:43 PM
I see, thank you for the heads up. I didn't realize it myself, but I will try to keep that in mind.