Synthesis of Loops

B

Bochumfrau@gmx.de

Guest
Dear Sir or Madam,

I am trying to describe a module in VHDL which is capable of treating
incoming parallel 16 bits (data rate 30MHz).
An internal 90Mhz clock is used to nrzi-decode and to unstuff
the 16bit-words. Apart from that
the vector "gaps" (removed stuff bits) are bridged by shifting the
adjacent
bit positions up so that a complete 16bit word can be passed on to a
next
stage when all bit positions of the cleaned 16bit vector have a valid
value.
All this should be completed after 3 clock cylces (90MHz) so that the
next
16bit-word (30MHz)can be handled.

My question: (info: I use Altera QuartusII software)

I have written some VHDL code for that module.
Because of an error message I do not know if the timing of >=90MHz
is achieved.
The error message occurs in the state "s_unstuff" of the state_machine
when trying to define a loop border which is not static. Its value
comes from the former state where the value is calculated.
Is there a possibility to define such a loop (while-loop or for-loop)
?
I have tried both: "while" and "for" but there always is the error
message that
constants have to be used. What can I do about that?
Are there other alternatives?

Thank you for your help.

Regards
Eva

--------------------------------------------
--------------------------------------------

library ieee;

use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity Decode_destuff is
port ( Reset : in std_logic;
Clk : in std_logic;
In_rec_enable : in std_logic;
Data_in : in std_logic_vector(15 downto 0);
Out_flag : out std_logic;
Pos1 : out std_logic_vector(4 downto 0);
Pos2 : out std_logic_vector(4 downto 0);
Data_cleaned : out std_logic_vector(15 downto 0)
);
end Decode_destuff;


architecture behavior of Decode_destuff is

signal l_data_in_reg : std_logic_vector(15 downto 0);
signal l_unstuff_buffer : std_logic_vector(15 downto 0);

signal l_decoded_data : std_logic_vector(15 downto 0);
signal l_bit_position1 : integer range 0 to 15;
signal l_bit_position2 : integer range 0 to 15;
signal l_flag : std_logic;
signal l_bit_count : integer range 0 to 15;
signal l_mark_border : std_logic;
signal l_position1_valid : std_logic;
signal l_position2_valid : std_logic;

type type_treat is ( s_ini,
s_decode,
s_unstuff,
s_wait
);
signal state_treat : type_treat;

begin

Data_cleaned <= l_unstuff_buffer;
Out_flag <= l_flag;
Pos1 <= conv_std_logic_vector(l_bit_position1, 5);
Pos2 <= conv_std_logic_vector(l_bit_position2, 5);


process(Reset, Clk)
variable var_decoded_data : std_logic_vector(15 downto 0);
variable var_unstuffed_data : std_logic_vector(15 downto 0);
variable bit_count : integer range 0 to 15;
variable var_flag : std_logic;
variable wert : integer range 0 to 15;
variable index : integer range 0 to 15;
begin
if Reset='1' then
l_data_in_reg <= (others => '1');
l_decoded_data <= (others => '1');
state_treat <= s_ini;
l_bit_position1 <= 0;
l_bit_position2 <= 0;
l_flag <= '0';
l_bit_count <= 0;
l_mark_border <= '0';
l_unstuff_buffer <= (others => '0');
l_position1_valid <= '0';
l_position2_valid <= '0';

elsif rising_edge(Clk) then
l_data_in_reg <= l_data_in_reg;
l_decoded_data <= l_decoded_data;
var_decoded_data := l_decoded_data;
state_treat <= state_treat;
l_bit_position1 <= l_bit_position1;
l_bit_position2 <= l_bit_position2;
l_bit_count <= l_bit_count;
bit_count := l_bit_count;
l_flag <= l_flag;
var_flag := l_flag;
wert := 0;
l_mark_border <= l_mark_border;
l_unstuff_buffer <= l_unstuff_buffer;
var_unstuffed_data := l_unstuff_buffer;
l_position1_valid <= l_position1_valid;
l_position2_valid <= l_position2_valid;
case state_treat is

when s_ini =>

if In_rec_enable='1' then
state_treat <= s_decode;
end if;
---------------*---------------*---------------
when s_decode => -- NRZI-Dekodierung

if l_mark_border='1' then
l_mark_border <= '0';
end if;

for i in 15 downto 0 loop
wert := i;
if i < 15 then
if Data_in(i+1)=Data_in(i) then
var_decoded_data(i) := '1';
else
var_decoded_data(i) := '0';
end if;
else
if l_data_in_reg(0)= Data_in(15) then
var_decoded_data(i) := '1';
else
var_decoded_data(i) := '0';
end if;
end if;
---------------
if var_decoded_data(i)='1' then

bit_count := bit_count + 1;

if bit_count=15 then
bit_count := 0;
elsif bit_count=6 then
if i=0 then
l_mark_border <= '1';
else
if var_flag='0' then
var_flag := '1';
l_bit_position1 <= wert-1;
l_position1_valid<= '1';
else
var_flag := '0';
l_bit_position2 <= wert-1;
l_position2_valid <= '1';
end if;
end if;
end if;
else
bit_count := 0;
end if;

end loop;

state_treat <= s_unstuff;
l_data_in_reg <= Data_in;

-- Signale <= Variablen
l_decoded_data <= var_decoded_data;
l_bit_count <= bit_count;
l_flag <= var_flag;

---------------*---------------*---------------*--------
when s_unstuff =>
var_unstuffed_data := l_decoded_data;
index:=15;
if l_mark_border='1' then
var_unstuffed_data(15 downto 1) := l_decoded_data(14
downto 0);
end if;
if l_position1_valid='1' then
while (index /= l_bit_position1) loop
var_unstuffed_data(index) :=
var_unstuffed_data(index-1);
index := index - 1;
end loop;
end if;
if l_position2_valid='1' then
var_unstuffed_data(l_bit_position2 downto 1) :=
l_decoded_data(l_bit_position2-1 downto 0);
end if;
state_treat <= s_wait;

l_unstuff_buffer <= var_unstuffed_data;

---------------*---------------*---------------*---------
when s_wait =>
state_treat <= s_decode;
l_position1_valid <= '0';
l_position2_valid <= '0';
l_flag <= '0';

---------------*---------------*---------------*----------
when OTHERS => NULL;

end case;


end if;

end process;


end behavior;
 
<Bochumfrau@gmx.de> wrote in message
news:17b83bf3.0401210507.364a8ac2@posting.google.com...

[...]
I have written some VHDL code for that module.
The error message occurs in the state "s_unstuff" of the state_machine
when trying to define a loop border which is not static. Its value
comes from the former state where the value is calculated.
Is there a possibility to define such a loop (while-loop or for-loop)
?
I have tried both: "while" and "for" but there always is the error
message that
constants have to be used. What can I do about that?
Are there other alternatives?
Use a "for" loop that scans over the whole array, and
inside the loop, use an if statement to determine whether
the action should take place in that iteration.

Most synthesis tools can't handle loops with variable
bounds.

Some, however, can deal correctly with a for loop
with constant bounds but having an "exit" statement;
in this way you can make the loop terminate after
a variable number of iterations.

One minor point:

library ieee;

use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
Best to avoid this. std_logic_unsigned is not pretty.
std_logic_arith or numeric_std will do a better and
clearer job for anything you are likely to need.

I haven't looked at your code (too many lines, too
little time) so I can't comment on whether what you
are trying to do is otherwise reasonable.
--

Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * Perl * Tcl/Tk * Verification * Project Services

Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, Hampshire, BH24 1AW, UK
Tel: +44 (0)1425 471223 mail: jonathan.bromley@doulos.com
Fax: +44 (0)1425 471573 Web: http://www.doulos.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
Dear Mr,

Why is it better to avoid the unsigned library?
Is there a special reason ?
Is the use compiler dependant "bad" ?


Let's assume the following assignment:

i := conv_integer(l_vector);

....

When I do not include the unsigned library I get the error message:
"Object cannot be indexed because it has integer type rather than
array type".

So how can I make the same assignment when only using
the 1164 and arith library?

Rgds
Eva

One minor point:

library ieee;

use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

Best to avoid this. std_logic_unsigned is not pretty.
std_logic_arith or numeric_std will do a better and
clearer job for anything you are likely to need.
 
<Bochumfrau@gmx.de> wrote in message
news:17b83bf3.0401220306.3bfbe0ed@posting.google.com...

Why is it better to avoid the unsigned library?
std_logic_vector is simply a collection of std_logic
bits. The std_logic_unsigned package gives std_logic_vector
a new meaning (unsigned binary) that can be confusing, and
if you want to use signed numbers in the same design it
will become very difficult.

On the other hand, std_logic_arith defines two new data
types SIGNED and UNSIGNED, with the *same definition* as
std_logic_vector. Using this, you can be very clear about
what you are trying to do. numeric_std is even better,
because it is properly standardised by IEEE and it has a
more complete set of functions and operators.

Let's assume the following assignment:

i := conv_integer(l_vector);

...

When I do not include the unsigned library I get the error message:
"Object cannot be indexed because it has integer type rather than
array type".
i := conv_integer( unsigned(l_vector) );

std_logic_vector and unsigned have the same definition, so they
are "closely related" and you can convert from one to the
other by using the type name as if it were a conversion function.
The vector<->integer conversions work between integer and
SIGNED or UNSIGNED data.
--
Jonathan Bromley
 
Hi Jonathan,
Your post (and a subsequent trawl of comp.lang.vhdl) just lifted a
veil from my vision of VHDL arithmetic; thank you very much! No longer
will I rely on the library 'blunderbuss' technique! You should get a
job at a training company, you show some promise... ;-)
Thanks again mate, Syms.

<jonathan.bromley@doulos.com> wrote in message news:<buop5a$jcl$1$8300dec7@news.demon.co.uk>...
Bochumfrau@gmx.de> wrote in message
news:17b83bf3.0401220306.3bfbe0ed@posting.google.com...

Why is it better to avoid the unsigned library?

std_logic_vector is simply a collection of std_logic
bits. The std_logic_unsigned package gives std_logic_vector
a new meaning (unsigned binary) that can be confusing, and
if you want to use signed numbers in the same design it
will become very difficult.

On the other hand, std_logic_arith defines two new data
types SIGNED and UNSIGNED, with the *same definition* as
std_logic_vector. Using this, you can be very clear about
what you are trying to do. numeric_std is even better,
because it is properly standardised by IEEE and it has a
more complete set of functions and operators.

Let's assume the following assignment:

i := conv_integer(l_vector);

...

When I do not include the unsigned library I get the error message:
"Object cannot be indexed because it has integer type rather than
array type".

i := conv_integer( unsigned(l_vector) );

std_logic_vector and unsigned have the same definition, so they
are "closely related" and you can convert from one to the
other by using the type name as if it were a conversion function.
The vector<->integer conversions work between integer and
SIGNED or UNSIGNED data.
 

Welcome to EDABoard.com

Sponsor

Back
Top