EmbDev.net

Forum: FPGA, VHDL & Verilog VHDL problem


von Keyslav (Guest)


Rate this post
useful
not useful
Hello everyone!

Im trying  to make a entity for a N entrances AND, using LOG2 and 
geometric progression sum, like below...

Example for N = 8

    aux(1 to N) <= entrance;

    aux(9)  <= aux(1) AND aux(2)
    aux(10) <= aux(3) AND aux(4)
    aux(11) <= aux(5) AND aux(6)
    aux(12) <= aux(7) AND aux(8)

    aux(13) <= aux(9) AND aux(10)
    aux(14) <= aux(11) AND aux(12)

    aux(15) <= aux(13) AND aux(14)

This is what I hope to be produced using the code below...


    entity and_gate_Nbits_LOG is

      -- Definição do valor de N
      generic (
        N  :  natural := 4 -- Número de entradas do AND_GATE
      );

      -- Lista de Entradas e Saídas da Entidade
      port(
        entrada    :  in    bit_vector ( 1 to N );
        saida      :  out  bit
      );

    -- Fim da Entidade
    end entity;


    -- Definição da Arquitetura do AND_GATE de N entradas
    architecture main of and_gate_Nbits_LOG is

      -- Sinal Auxiliar que armazenará os resultados parciais dos ANDs 
entre as entradas
      signal aux : bit_vector ( 1 to 2*N );

      -- Função que calcula o Logarítmo na base 2 de um número natual X
      function LOG_2 ( x : natural ) return natural is
        variable temp   : natural := x;
        variable result  : natural := 0;
      begin
        -- Loop que fatora X em 2
        while temp > 1 loop
          temp   := temp / 2;
          result   := result + 1;
        end loop;

        -- Retorna o Log2(X)
        return result;
      end function LOG_2 ;

    -- Início da descrição da Arquitetura do AND_GATE de N entradas
    begin

      -- Sinal aux replica a entrada
      aux(1 to N) <= entrada;

      -- Estrutura de repetição que percorre os níveis de AND's
      and_Nbits: for i in 1 to LOG_2(N) generate

        -- Estrutura de repetição que gera todos os AND's de cada nível
        ands_nivel: for j in (1+(N-(N/(2**(i-1))))) to (N-N/(2**(i))) 
generate

          -- Auxiliar do próximo nível recebe o AND do nível atual
          aux(2*(N-N/(2**(i))+1)+(j-(1+(N-(N/(2**(i-1))))))) <= 
aux(2*j-1) and aux(2*j);

        -- Fim do FOR
        end generate ands_nivel;

      -- Fim do FOR
      end generate and_Nbits;


      -- Saída recebe o resultado do último AND
      saida <= aux(2*N-1);


    -- Fim da Arquitetura do AND_GATE de N entradas
    end architecture;

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

But the simulation in ModelSIm is doing

    aux(6) <= aux(1) and aux(2)

instead

    aux(5) <= aux(1) and aux(2)

The simulation skip 1 aux in every "for j" and I couldnt know why.

Ive tested the math of the code in others languages and everything work 
as expected.

I need help! Please someone!

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
useful
not useful
Keyslav wrote:
> The simulation skip 1 aux in every "for j"
How do you see that?
Whats your testbench like?

> Ive tested the math of the code in others languages and everything work
> as expected.
I assume, the problem here is, that VHDL is not a "top down" language 
like other languages are.

Keyslav wrote:
> trying  to make a entity for a N entrances AND, using LOG2 and
> geometric progression sum, like below...
Must you do it in that progrssion style or can you solve the problem in 
a more simple way?

If so: why don't you use the and_reduce() function in the std_logic_misc 
package?

http://www1.pldworld.com/@xilinx/html/technote/tool/manual/15i_doc/fndtn/vhd/vhd10_3.htm

The code of the and_reduce is not that hard to understand. I swapped the 
std_logic to bit:
1
    function AND_REDUCE(ARG: bit_vector) return bit is
2
  variable result: bit := '1';
3
    begin
4
  for i in ARG'range loop
5
      result := result and ARG(i);
6
  end loop;
7
        return result;
8
    end;
The trick is passing an unconstrained vector ARG as an argument and 
using the 'range attribute...

In VHDL 2008 you are allowed to do things like this (v is a vector, b is 
a single bit):
1
b <= and v;

BTW1:
1 to N is a very strange bit order.
1
entrada    :  in    bit_vector ( 1 to N );
Usually the leftmost bit in a vector is the most significant bit and the 
rightmost bit is bit 0:
1
entrada    :  in    bit_vector ( N-1 downto 0 );


BTW2:
Why do you use bit and bit_vector despite of the whole world using 
std_logic and st_logic_vector?

BTW3:
You should add a check for N being a power of 2. And indicate an error 
when its not...

: Edited by Moderator
Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.