Reputation: 41
In VHDL '93 the compiler told me it found 0 possible definitions for operator "=". It causes an error with the following error message:
Error (10327): VHDL error at mst_fifo_fsm.vhd(171): can't determine definition of operator ""="" -- found 0 possible definitions
Line 171 is at the first assignment of ifsm_cond(0):
process(clk, rst_n)
begin
if (rst_n = '0') then
ifsm_cond <= "0000";
elsif (rising_edge(clk)) then
if (mltcn = '0') then
ifsm_cond(0) <= (cur_stap1 = IDLE) AND (not imst_rd_n(0)) AND (not rxf_n) AND (not ibuf_ful(0));
ifsm_cond(1) <= (cur_state = MTRD) AND ( imst_rd_n(0) OR (rxf_n AND (not rxf_n_p1)) OR ibuf_ful(0)) ;
ifsm_cond(2) <= (cur_state = MDLE) AND (not imst_wr_n(0)) AND (not txe_n)& (ibuf_nep(0) OR stren OR w_1byte) AND (not w_1flag);
ifsm_cond(3) <= (cur_stap3 = MTWR) AND ( imst_wr_n(0) OR (txe_n AND (not txe_n_p1)) OR r_oobe OR ((not ififonempt(0)) AND (not stren) AND (not prefnempt(0))));
else
ifsm_cond(0) <= (not imst_rd_n(conv_integer(ichannel))) AND (not irxf_n(conv_integer(ichannel))) AND (not ibuf_ful(conv_integer(ichannel))) AND (cur_stap3 = IDLE);
ifsm_cond(1) <= ( imst_rd_n(conv_integer(ichannel)) OR (rxf_n & (not rxf_n_p1)) OR ibuf_ful(conv_integer(ichannel))) AND (cur_state = MTRD);
ifsm_cond(2) <= (not imst_wr_n(conv_integer(ichannel))) AND (not itxe_n(conv_integer(ichannel))) AND (ibuf_nep(conv_integer(ichannel)) OR stren) AND (cur_stap3 = MDLE);
ifsm_cond(2) <= (not imst_wr_n(conv_integer(ichannel))) AND (not itxe_n(conv_integer(ichannel))) AND (ibuf_nep(conv_integer(ichannel)) OR stren) AND (cur_stap3 = MDLE);
ifsm_cond(3) <= ( imst_wr_n(conv_integer(ichannel)) OR (rxf_n AND
(not rxf_n_p1)) OR ((not ififonempt(conv_integer(ichannel)) AND (not stren)
AND (not prefnempt(conv_integer(ichannel)))))) AND (cur_stap3 = MTWR);
end if;
end if;
end process;
I guess it is at the statement (cur_stap1 = IDLE).
cur_stap1 is a user defined signal with the following declaration:
type states is (IDLE, MTRD, MDLE, MTWR);
signal cur_state, next_statem, cur_stap1, cur_stap2, cur_stap3, cur_stap4 :
states;
I thougt of one possible solution to clarify first in a conditional concurrent signal assignment if cur_stap1 is IDLE and assign this to a signal which replaces (cur_stap1 = IDLE). But I have some more lines with other statements like this.
Is there a better solution to solve this issue? This concurrent signal assignment is done in a process. Should I rather try an IF ELSIF END IF statement for the whole line?
Thank you in advance.
Upvotes: 1
Views: 2853
Reputation: 11261
The problem is that not imst_rd_n(0)
returns a std_logic
type, while cur_stap1 = IDLE
returns a boolean
type. There is no and
operator that accepts both types, thus the compiler tries to solve it another way: by looking for an =
operator defined for your custom type (state) that returns a std_logic
, which there isn't. Hence the error.
Instead of not imst_rd_n(0)
, you should write imst_rd_n(0)='0'
and so on. This returns a boolean
and a boolean
and
operator is defined. Imho it's also better for readability.
You should then write your assignment in an if
statement.
If [boolean expression] then
[Signal] <= '1';
Else
[Signal] <= '0';
End if;
Also try to design a state machine with a simple output:
Case [current_state] is
When [state 1] =>
If ....
When ....
End case;
You can work with default assignment. Example:
if rising_edge(clk) then
ifsm_cond <= (others => '0'); -- default assignment
case cur_state is
when IDLE =>
if imst_rd_n(0)='0' AND rxf_n='0' AND ibuf_ful='0' then
ifsm_cond(0) <= '1';
end if;
when MTRD =>
if imst_rd_n(0)='1' OR (rxf_n='1' AND rxf_n_p1='0') OR ibuf_ful(0)='1' then
ifsm_cond(1) <= '1';
end if;
etc.
I would not write a function for operator =
for two input's type states
that returns a std_logic
, as that could lead to other unwanted conflicts. I would instead propose to make a casting function from boolean
to std_logic
. E.g.:
function to_std_logic(input : boolean) return std_ulogic is
begin
if input then
return '1';
end if;
return '0';
end function;
Usage example: ifsm_cond(0) <= to_std_logic(cur_stap1 = IDLE) AND (not imst_rd_n(0)) AND (not rxf_n) AND (not ibuf_ful(0));
Upvotes: 2