Synthesis of Loops

Do you have a question? Post it now! No Registration Necessary

Translate This Thread From English to

Threaded View
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 >90%MHz
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_count15% 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;

Re: Synthesis of Loops

[...]
Quoted text here. Click to load it

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:

Quoted text here. Click to load it

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
We've slightly trimmed the long signature. Click to see the full one.
Re: Synthesis of Loops
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

Quoted text here. Click to load it

Re: Synthesis of Loops

Quoted text here. Click to load it

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.

Quoted text here. Click to load it

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




Re: Synthesis of Loops
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.

Quoted text here. Click to load it

Site Timeline