Combinational Loop?

A

ALuPin

Hi everybody,

when trying to compile the following VHDL code with
Altera QuartusII v.4.1 I get the following warning:

signal or variable l_data may not be assigned a new value in every
possible path through the Process statement.

Signal or variable l_data holds its previous value in every path with
no new value assignment, which may create
a combinational loop in the current design

I cannot understand what goes wrong.

Any hint is appreciated.

Kind regards

Andre

signal pos : integer range 0 to 2;
type matr is array(0 to 3) of std_logic_vector(7 downto 0);
signal l_data : matr;

process(Reset, Clk_fast)
variable var_buffer : std_logic_vector(7 downto 0);
variable var_buffer2 : std_logic_vector(7 downto 0);
variable data : matr;

begin
if Reset='1' then
l_valid <= '0';
l_pid <= (others => '0');
l_frame <= (others => '0');
l_addr <= (others => '0');
l_ep <= (others => '0');
pos <= 0;
l_data <= (others => (others => '0'));
l_buffer <= (others => '0');
l_buffer2 <= (others => '0');
l_host_has_acked <= '0';
l_handshake_pid <= '0';
l_token_pid <= '0';
l_data_pid <= '0';
l_data_pid_flag <= '0';
l_valid_ini_read <= '0';

l_sof <= '0';
l_sof_flag <= '0';

l_setup <= '0';
l_setup_flag <= '0';

elsif rising_edge(Clk_fast) then
l_valid <= '0';
l_pid <= l_pid;
l_frame <= l_frame;
l_addr <= l_addr;
l_ep <= l_ep;

pos <= pos;
l_data <= l_data;
data := l_data;
l_buffer <= l_buffer;
var_buffer := l_buffer;
l_buffer2 <= l_buffer2;
var_buffer2 := l_buffer2;

l_host_has_acked <= '0';
l_handshake_pid <= '0';
l_token_pid <= '0';
l_data_pid <= '0';
l_data_pid_flag <= l_data_pid_flag;
l_valid_ini_read <= '0';

l_sof <= '0';
l_sof_flag <= l_sof_flag;

l_setup <= '0';
l_setup_flag <= l_setup_flag;

if Enable_highspeed='1' then


if l_writing_hs='1' then

if pos=0 then
data(0) := Highspeed_data(7 downto 0);
var_buffer := data(0);
l_pid(3 downto 0) <= var_buffer(3 downto 0);
--if (var_buffer(3 downto 0) = (not var_buffer(7
downto 4)) ) then
-- l_valid_ini_read <= '1';
--end if;

if var_buffer(3 downto 0)="0010" then
l_host_has_acked <= '1';
end if;

if var_buffer(3 downto 0)="0101" then
l_sof <= '1';
l_sof_flag <= '1';
end if;
if var_buffer(3 downto 0)="1101" then
l_setup <= '1';
l_setup_flag <= '1';
end if;

if (var_buffer(3 downto 0)="1010") -- NAK
(1010)
or (var_buffer(3 downto 0)="0010") then -- ACK
(0010)
l_handshake_pid <= '1';
end if;

if (var_buffer(3 downto 0)="0001") -- OUT
(0001)
or (var_buffer(3 downto 0)="1001") -- IN
(1001)
or (var_buffer(3 downto 0)="0101") -- SOF
(0101)
or (var_buffer(3 downto 0)="1101") then -- SETUP
(1101)
l_token_pid <= '1';
end if;

if (var_buffer(3 downto 0)="0011") -- DATA0
(0011)
or (var_buffer(3 downto 0)="1011") -- DATA1
(1011)
or (var_buffer(3 downto 0)="0111") -- DATA2
(0111)
or (var_buffer(3 downto 0)="1111") then -- MDATA
(1111)
l_data_pid <= '1';
l_data_pid_flag <= '1'; -
end if;

elsif pos=1 then
data(1) := Highspeed_data(15 downto 8);
if (var_buffer(3 downto 0) = (not var_buffer(7 downto 4))
) then
l_valid_ini_read <= '1';
end if;

elsif pos=2 then
data(2) := Highspeed_data(7 downto 0);
var_buffer2 := data(1);
l_data_pid_flag <= '0';
l_sof_flag <= '0';
l_setup_flag <= '0';

if (var_buffer(3 downto 0) = (not var_buffer(7 downto 4))
) then
if ( (l_data_pid_flag='0') and (l_sof_flag='0') and
(l_setup_flag='0') ) then
l_valid <= '1';
end if;
end if;

l_frame(7 downto 0) <= var_buffer2(7 downto 0);
l_ep(0) <= var_buffer2(7);
l_addr(6 downto 0) <= var_buffer2(6 downto 0);

---------------
var_buffer2 := data(2);
---------------

l_frame(10 downto 8) <= var_buffer2(2 downto 0);
l_ep(3 downto 1) <= var_buffer2(2 downto 0);
end if;


if pos=2 then
pos <= 0;
else
pos <= pos + 1;
end if;

end if;

end if;

l_buffer <= var_buffer;
l_buffer2 <= var_buffer2;
l_data <= data;
end if;
end process;
 
P

Pieter Hulshoff

ALuPin said:
signal or variable l_data may not be assigned a new value in every
possible path through the Process statement.
Signal or variable l_data holds its previous value in every path with
no new value assignment, which may create
a combinational loop in the current design

Ok, here's your problem:
signal pos : integer range 0 to 2;
type matr is array(0 to 3) of std_logic_vector(7 downto 0);
signal l_data : matr;

l_data is 4*8 bits.
l_data <= l_data;
data := l_data;

data gets the value of l_data
data(0) := Highspeed_data(7 downto 0);

data(0) gets a value
data(1) := Highspeed_data(15 downto 8);

data(1) gets a value
data(2) := Highspeed_data(7 downto 0);

data(2) gets a value

l_data <= data;

and l_data gets filled with data.

Result: l_data(3)(7 DOWNTO 0) never gets updated, and as such always keeps
its current value. Though I don't see this as a reason for the compiler to
stop working, I doubt it was what you intended either.

Regards,

Pieter Hulshoff
 
M

Mike Treseler

ALuPin said:
when trying to compile the following VHDL code with
Altera QuartusII v.4.1 I get the following warning:

signal or variable l_data may not be assigned a new value in every
possible path through the Process statement.

Signal or variable l_data holds its previous value in every path with
no new value assignment, which may create
a combinational loop in the current design

Quartus is probably concerned about

l_data <= l_data;

because this statement doesn't do anything.
If you take this line out out, the warning may go away.

When posting code for comments, you can
improve your odds of getting a reply by
including a complete entity with library and USE statements,
and a matching architecture with all declarations.

-- Mike Treseler
 
A

ALuPin

Quartus is probably concerned about

l_data <= l_data;

because this statement doesn't do anything.
If you take this line out out, the warning may go away.

When posting code for comments, you can
improve your odds of getting a reply by
including a complete entity with library and USE statements,
and a matching architecture with all declarations.

-- Mike Treseler

Dear Mr Treseler,

I have taken the line out but the warning still occurs.

Here is the complete code:

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;

entity pid_check_8bit_hs is
port( Clk_fast : in std_logic;
Reset : in std_logic;

Highspeed_data : in std_logic_vector(15 downto 0);
RX_valid : in std_logic;
Enable_highspeed : in std_logic;

RX_Last_byte : in std_logic;
RX_BS_error : in std_logic;

Data_out : out std_logic_vector(7 downto 0);
Data_valid : out std_logic;

Error_out : out std_logic;
Last_byte_odd : out std_logic;
Last_byte_even : out std_logic;
Eop_hs_detected : out std_logic;
Sync_recog_hs : out std_logic;

Token_pid : out std_logic;
Host_has_acked : out std_logic;
Handshake_pid : out std_logic;
Data_pid : out std_logic;

Sof_hs : out std_logic;
Setup_hs : out std_logic;

Valid : out std_logic;
Valid_ini_read : out std_logic;

Pid : out std_logic_vector(3 downto 0);
Frame : out std_logic_vector(10 downto 0);
Addr : out std_logic_vector(6 downto 0);
Ep : out std_logic_vector(3 downto 0)
);
end pid_check_8bit_hs;

architecture rtl of pid_check_8bit_hs is

signal pos : integer range 0 to 2;
type matr is array(0 to 3) of std_logic_vector(7 downto 0);
signal l_data : matr;

signal l_valid : std_logic;
signal l_valid_ini_read : std_logic;

signal l_pid : std_logic_vector(3 downto 0);
signal l_frame : std_logic_vector(10 downto 0);
signal l_addr : std_logic_vector(6 downto 0);
signal l_ep : std_logic_vector(3 downto 0);
signal l_buffer : std_logic_vector(7 downto 0);
signal l_buffer2 : std_logic_vector(7 downto 0);
signal l_host_has_acked : std_logic;
signal l_handshake_pid : std_logic;
signal l_token_pid : std_logic;
signal l_data_pid : std_logic;
signal l_data_pid_flag : std_logic;

signal l_sof : std_logic;
signal l_sof_flag : std_logic;
signal l_setup : std_logic;
signal l_setup_flag : std_logic;

signal l_writing_hs : std_logic;
signal l_rx_valid_reg : std_logic;

signal l_pass_data : std_logic;
signal l_count_hs : integer range 0 to 2;
signal l_data_to_pass : std_logic_vector(7 downto 0);
signal l_data_valid : std_logic;
signal l_last_byte_odd : std_logic;
signal l_last_byte_even : std_logic;
signal l_error_out : std_logic;
signal l_reg_error : std_logic;

signal l_eop_hs_detected : std_logic;
signal l_sync_recog_hs : std_logic;
signal l_sync_help1 : std_logic;
signal l_sync_help2 : std_logic;
signal l_sync_help3 : std_logic;


begin

-- Abbildung intern --> extern
Valid <= l_valid;
Valid_ini_read <= l_valid_ini_read;

Pid <= l_pid;
Frame <= l_frame;
Addr <= l_addr;
Ep <= l_ep;
Token_pid <= l_token_pid;
Host_has_acked <= l_host_has_acked;
Handshake_pid <= l_handshake_pid;
Data_pid <= l_data_pid;

Sof_hs <= l_sof;
Setup_hs <= l_setup;

Data_out <= l_data_to_pass;
Data_valid <= l_data_valid;
Error_out <= l_error_out;
Last_byte_odd <= l_last_byte_odd;
Last_byte_even <= l_last_byte_even;
Eop_hs_detected <= l_eop_hs_detected;

l_sync_recog_hs <= l_sync_help2 and (not l_sync_help3);
Sync_recog_hs <= l_sync_recog_hs;

l_last_byte_even <= (RX_BS_error and (not l_reg_error)) when
((RX_valid='0') and (Highspeed_data(7 downto 0)="11111110")) else '0';



----------------------------------------------------------
----------------------------------------------------------
-- Prozess zur Bestimmung des PID-Überprüfungszeitraumes HS
process(Reset, Clk_fast)
begin
if Reset='1' then
l_writing_hs <= '0';
l_rx_valid_reg <= '0';

elsif rising_edge(Clk_fast) then
l_writing_hs <= l_writing_hs;
l_rx_valid_reg <= RX_valid;
if ( (RX_valid='1') and (l_rx_valid_reg='0') ) then
l_writing_hs <= '1';
elsif pos=2 then
l_writing_hs <= '0';
end if;
end if;

end process;
----------------------------------------------------------
----------------------------------------------------------
-- Prozess zur PID-Überprüfung
process(Reset, Clk_fast)
variable var_buffer : std_logic_vector(7 downto 0);
variable var_buffer2 : std_logic_vector(7 downto 0);
-- variable data : matr;

begin
if Reset='1' then
l_valid <= '0';
l_pid <= (others => '0');
l_frame <= (others => '0');
l_addr <= (others => '0');
l_ep <= (others => '0');
pos <= 0;
l_data <= (others => (others => '0'));
l_buffer <= (others => '0');
l_buffer2 <= (others => '0');
l_host_has_acked <= '0';
l_handshake_pid <= '0';
l_token_pid <= '0';
l_data_pid <= '0';
l_data_pid_flag <= '0';
l_valid_ini_read <= '0';

l_sof <= '0';
l_sof_flag <= '0';

l_setup <= '0';
l_setup_flag <= '0';

elsif rising_edge(Clk_fast) then
l_valid <= '0';
l_pid <= l_pid;
l_frame <= l_frame;
l_addr <= l_addr;
l_ep <= l_ep;

pos <= pos;
--data := l_data;
l_data <= l_data;

l_buffer <= l_buffer;
var_buffer := l_buffer;
l_buffer2 <= l_buffer2;
var_buffer2 := l_buffer2;

l_host_has_acked <= '0';
l_handshake_pid <= '0';
l_token_pid <= '0';
l_data_pid <= '0';
l_data_pid_flag <= l_data_pid_flag;
l_valid_ini_read <= '0';

l_sof <= '0';
l_sof_flag <= l_sof_flag;

l_setup <= '0';
l_setup_flag <= l_setup_flag;

if Enable_highspeed='1' then


if l_writing_hs='1' then

if pos=0 then
--data(0) := Highspeed_data(7 downto 0);
l_data(0) <= Highspeed_data(7 downto 0);
--var_buffer := data(0);
var_buffer := Highspeed_data(7 downto 0);
l_pid(3 downto 0) <= var_buffer(3 downto 0);


if var_buffer(3 downto 0)="0010" then
l_host_has_acked <= '1';
end if;

if var_buffer(3 downto 0)="0101" then
l_sof <= '1';
l_sof_flag <= '1';
end if;
if var_buffer(3 downto 0)="1101" then
l_setup <= '1';
l_setup_flag <= '1';
end if;

if (var_buffer(3 downto 0)="1010") -- NAK
(1010)
or (var_buffer(3 downto 0)="0010") then -- ACK
(0010)
l_handshake_pid <= '1';
end if;

if (var_buffer(3 downto 0)="0001") -- OUT
(0001)
or (var_buffer(3 downto 0)="1001") -- IN
(1001)
or (var_buffer(3 downto 0)="0101") -- SOF
(0101)
or (var_buffer(3 downto 0)="1101") then -- SETUP
(1101)
l_token_pid <= '1';
end if;

if (var_buffer(3 downto 0)="0011") -- DATA0
(0011)
or (var_buffer(3 downto 0)="1011") -- DATA1
(1011)
or (var_buffer(3 downto 0)="0111") -- DATA2
(0111)
or (var_buffer(3 downto 0)="1111") then -- MDATA
(1111)
l_data_pid <= '1';
l_data_pid_flag <= '1'; -- Somit
werden CAM-Einträge nur für Token-Pakete überprüft
end if;

elsif pos=1 then
--data(1) := Highspeed_data(15 downto 8);
l_data(1) <= Highspeed_data(15 downto 8);
if (var_buffer(3 downto 0) = (not var_buffer(7 downto 4))
) then -- im Vergleich zu FS einen Takt später, da sonst
gleichzeitig mit Sync_recog
l_valid_ini_read <= '1';
end if;

elsif pos=2 then
--data(2) := Highspeed_data(7 downto 0);
l_data(2) <= Highspeed_data(7 downto 0);
--var_buffer2 := data(1);
var_buffer2 := l_data(1);
l_data_pid_flag <= '0';
l_sof_flag <= '0';
l_setup_flag <= '0';

if (var_buffer(3 downto 0) = (not var_buffer(7 downto 4))
) then
if ( (l_data_pid_flag='0') and (l_sof_flag='0') and
(l_setup_flag='0') ) then
l_valid <= '1';
end if;
end if;

l_frame(7 downto 0) <= var_buffer2(7 downto 0);
l_ep(0) <= var_buffer2(7);
l_addr(6 downto 0) <= var_buffer2(6 downto 0);

---------------
--var_buffer2 := data(2);
var_buffer2 := Highspeed_data(7 downto 0);
---------------

l_frame(10 downto 8) <= var_buffer2(2 downto 0);
l_ep(3 downto 1) <= var_buffer2(2 downto 0);
end if;


if pos=2 then
pos <= 0;
else
pos <= pos + 1;
end if;

end if;

end if;

l_buffer <= var_buffer; -- Zuweisung Signal <= Variable
(für Synthese)
l_buffer2 <= var_buffer2;
--l_data <= data; -- Zuweisung Signal <=
Variable (für Synthese)
end if;
end process;
----------------------------------------------------------
----------------------------------------------------------
-- Prozess um die Highspeed-Daten in 8bit-Paketen weiterzureichen
process(Reset, Clk_fast)
begin
if Reset='1' then
l_pass_data <= '0';
l_count_hs <= 0;
l_data_to_pass <= (others => '0');
l_data_valid <= '0';
l_last_byte_odd <= '0';
l_error_out <= '0';
l_reg_error <= '0';

elsif rising_edge(Clk_fast) then
l_pass_data <= l_pass_data;
l_count_hs <= l_count_hs;
l_data_to_pass <= l_data_to_pass;
l_data_valid <= '0';
l_last_byte_odd <= '0';
l_error_out <= '0';
l_reg_error <= RX_BS_error;

if ( (RX_valid='1') and (l_rx_valid_reg='0') ) then
l_pass_data <= '1';
elsif ( (RX_valid='0') and (l_rx_valid_reg='1') ) then
l_pass_data <= '0';
end if;



if l_pass_data='1' then

if l_count_hs=2 then
l_count_hs <= 0;
else
l_count_hs <= l_count_hs + 1;
end if;

if l_count_hs=0 then
l_data_to_pass <= Highspeed_data(7 downto 0);
l_data_valid <= '1';
if ((RX_Last_byte='1') and (RX_Valid='1')) then
if Highspeed_data(15 downto 8)="11111110" then -- xFEH
l_last_byte_odd <= '1';
end if;
end if;
elsif ( (l_count_hs=1) and (not(RX_Last_byte='1' and
RX_valid='1')) ) then
l_data_to_pass <= Highspeed_data(15 downto 8);
l_data_valid <= '1';
end if;
end if;
if RX_BS_error='1' then
if RX_valid='1' then
l_error_out <= '1';
end if;
end if;
end if;
end process;
----------------------------------------------------------
----------------------------------------------------------
process(Reset, Clk_fast)
begin
if Reset='1' then
l_eop_hs_detected <= '0';
l_sync_help1 <= '0';
l_sync_help2 <= '0';
l_sync_help3 <= '0';
elsif rising_edge(Clk_fast) then
l_eop_hs_detected <= (l_last_byte_odd or l_last_byte_even);
l_sync_help1 <= RX_valid;
l_sync_help2 <= l_sync_help1;
l_sync_help3 <= l_sync_help2;

end if;
end process;
 
M

Mike Treseler

ALuPin wrote
I have taken the line out but the warning still occurs.

Leo synthesizes your entity without error or warnings.
Consider running a sim to make sure your code
processes data as you expect, before you worry
about any more synthesis messages.

-- Mike Treseler
 
K

Ken Smith

Mike Treseler said:
Quartus is probably concerned about

l_data <= l_data;

because this statement doesn't do anything.

Actually it does seem to do something in Quartus and Quartus seems to like
it just fine. Quartus takes it to mean that l_data keeps its value
through here.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,040
Latest member
papereejit

Latest Threads

Top