Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Variable length Correlation in VHDL

Status
Not open for further replies.

azwaa

Member level 1
Joined
May 21, 2014
Messages
32
Helped
0
Reputation
0
Reaction score
0
Trophy points
6
Activity points
197
i have here a programme that calculate the correlation of data bits with 8 bits as length in this case i will need for the calculation 4 stage the figure explain the program , so i want to do it with variable length 16 or n for length so can you help plz

Thank you in advance for your reponse

Code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity correla4bit is 

port ( 
         clk : in    std_logic ;
         rst : in    std_logic  ;
         data: in    std_logic_vector(11 downto 0)  ; 

         code: in    std_logic_vector(15 downto 0 )  ;
         Q   :out    std_logic_vector(17 downto 0) )  ;
         end entity ;

architecture arch of correla4bit  is 
       type RAM is array (0 to 3) of std_logic_vector(3 downto 0) ;
       type ram16 is array (0 to 3) of signed(15 downto 0) ;
        type Rom is array (0 to 3) of signed(11 downto 0) ;
    
        signal voie :Rom ;
        signal CD    : RAM;
        signal temp: ram16;
        signal sum0   :signed (16 downto 0) ;
        signal sum1   :signed (16 downto 0) ;
        signal AB     :signed (17 downto 0) ;
      begin
     
                                
                            
    CD(0) <= code(15 downto 12);
    CD(1) <= code(11 downto 8);
    CD(2) <= code(7 downto 4);
    CD(3) <= code(3 downto 0); 
    
     etalement:process(clk,rst)
         begin 
                  if(rst='1') then 
                     Q  <=(others=>'0');
                     
                      temp(0)<=x"0000";
                     temp(1)<=x"0000";
                     temp(2)<=x"0000";
                    temp(3)<=x"0000";
                    
                    elsif(clk'event and clk ='1') then 
                   
                        voie(0)<=signed(data) ;  
                        voie(1)<=voie(0);
                        voie(2)<=voie(1);
                        voie(3)<=voie(2);
                        
                        for i in 0 to 3 loop
                           temp(i) <= voie(i)*signed(CD(i));
                        end loop ;
                        
                        sum0<= resize(temp(0),17)+temp(1) ;
                         sum1<= resize(temp(2),17)+temp(3) ;
                          AB<=resize(sum0,18)+sum1 ;
                          Q<=std_logic_vector(AB) ;
                          
                   end if ;  
                                     
                        
                       
          end process ;
 end architecture ;
 

Attachments

  • 20140610_223529.jpg
    20140610_223529.jpg
    2 MB · Views: 105
  • 20140610_223843.jpg
    20140610_223843.jpg
    1.9 MB · Views: 136

This is just a standard N tap FIR.
First of all, I suggest you bring in all C co-efficients separately, not as a single bus.
Second, for N taps, you will probably need a package to create the array types to make the design generic.

I dont know why you have declared RAM and ROM types - there is no RAM or ROM in your drawings. They are just arrays of registers.

I would also suggest putting registers after each multiplier and adder stage, or the fmax is going to be very low.
 

This is just a standard N tap FIR.
First of all, I suggest you bring in all C co-efficients separately, not as a single bus.
Second, for N taps, you will probably need a package to create the array types to make the design generic.

I dont know why you have declared RAM and ROM types - there is no RAM or ROM in your drawings. They are just arrays of registers.

I would also suggest putting registers after each multiplier and adder stage, or the fmax is going to be very low.

RAM et ROM are just the variable .
like this :
Code:
 type ram16 is array (0 to longueur-1 ) of signed( 15 downto 0) ;
       type ram17 is array (0 to (longueur/2)-1 ) of signed( 16 downto 0) ;
       type ram18 is array (0 to (longueur/4)-1 ) of signed( 17 downto 0) ;
            signal temp: ram16;
            signal temp1: ram17;
            signal temp2: ram18;
*
Can you please help me to correct
 

I still dont really know what you want, other than write your code for you.
Apart from the poor choice of name, RAM, it looks ok..
 

Okey ; we can do it :

Code:
type Tem1 is array (0 to longueur-1 ) of signed( 15 downto 0) ;
       type Tem2 is array (0 to (longueur/2)-1 ) of signed( 16 downto 0) ;
       type Tem3 is array (0 to (longueur/4)-1 ) of signed( 17 downto 0) ;

        signal temp1: Tem1 ;
        signal temp2: Tem2 ;
        signal temp3: Tem3;

i will need for the calculation 4 stage the figure explain the program

- - - Updated - - -

Do you understood ?!

Thank you
 

I understand the diagram, I have written this structure in VHDL a few times (for 1D and 2D FIRs).

I understand your diagram perfectly. I dont understand what you are asking us to look at. The code you posted in the first post will only do the 4-tap FIR. Now you are poasting the variable length arrays that will also only cover the 4 (maybe the 8-tap)-tap FIR. To do it the way you want to (an N tap filter), the easiet way would be to define an array of tem1 type that you can extend the different layers of your adder tree. Many of the entries will be unused, but it gives a basic structure.
 

I understand the diagram, I have written this structure in VHDL a few times (for 1D and 2D FIRs).

I understand your diagram perfectly. I dont understand what you are asking us to look at. The code you posted in the first post will only do the 4-tap FIR. Now you are poasting the variable length arrays that will also only cover the 4 (maybe the 8-tap)-tap FIR. To do it the way you want to (an N tap filter), the easiet way would be to define an array of tem1 type that you can extend the different layers of your adder tree. Many of the entries will be unused, but it gives a basic structure.


Perfectly, the probléme it is because I owe every time when I increase Length == > increase floor === > increase the number of bit for every floor ?!! This is big problem !!!
 

For the easy option, you need to just make everything the output length from the beginning.

something like this:


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
type mult_array_t is array(0 to longueur-1) of signed(15 downto 0);
type adder_stage_t is array(0 to longueur/2-1) of signed(Q'length-1 downto 0);
 
type adder_tree_t is array(0 to log2(longueur)-1) of adder_stage_t;
 
signal mults : mult_array_t;
signal adders : adder_tree_t;
 
...
--multiplies:
 
mult_proc : process(clk)
begin
  if rising_edge(clk) then
    for i in mults'range loop
      mults(i) <= ip(i) * C(i);
    end loop;
    
    --initial adders:
    for i in adders(0)'range loop
      adders(0)(i) <= resize(mults(i*2), Q'length) + resize( mults(i*2 +1), Q'length);
    end loop;
    
    --other adder stages:
    for level in 1 to adders'high loop
      for i in 0 to longueur/ (2**(level+1)) loop
        adders(level)(i) <= adders(level-1)(i*2) + adders(level-1)(i*2 + 1);
      end loop
    end loop;
  end if;
end process;
 
Q <= adders(adders'high)(0);



- - - Updated - - -

Doing this, the synthesisor can trim any unused bits.
 

can you explain me more

Code:
(Q'length-1 downto 0);



 for level in 1 to adders'high loop


Q <= adders(adders'high)(0);


Thank you
 

Q is the output.
Q'length is the length of Q
adders'high is the highest array index of the adders array.

'length and 'high are attributes avaiable on all arrays in VHDL.

so my code just loops through the arrays
 

Q'length-1 downto 0 is the same of Q'longueur-1 downto 0 non ???
 

If you do not know about these attributes, you really need to go back to a VHDL tutorial, as they are very basic things.

- - - Updated - - -

no, Q'length returns the length of Q. Q'longueur is an error because there is no attribute called longueur defined in the VHDL language.

if you set:

Q : out signed(longueur-1 downto 0);

then

Q'length = longueur
 

In fact Yes ,

Thank you ,

- - - Updated - - -

Code:
generic  (
            longueur  : natural :=16 ;
            result := integer(ceil(log2(real(longueur))))) ;


    Q   :out    std_logic_vector(result-1 downto 0) )  ;


In this case there; I can to do it ?!

Thank you

- - - Updated - - -

like this :

can you help me to correct this code :

Code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use IEEE.math_real."ceil";
use IEEE.math_real."log2"; 

entity correla is 

generic  (
            longueur  : natural :=16 ;
            result := integer(ceil(log2(real(longueur))))) ;
            


port ( 
         clk : in    std_logic ;
         rst : in    std_logic  ;
         data: in    std_logic_vector(11 downto 0)  ; 

         
            code: in    std_logic_vector((4*longueur)-1 downto 0 )  ;
        
           
            Q   :out    std_logic_vector(result-1 downto 0) )  ;
      

end entity ;

architecture arch of correla  is 
       type RAM is array (0 to 3) of std_logic_vector(3 downto 0) ;
       type Rom is array (0 to longueur-1) of signed(11 downto 0) ;
       type mult_array_t is array (0 to longueur-1 ) of signed( 15 downto 0) ;
       type adder_stage_t is array(0 to longueur/2-1) of signed(Q'longueur-1 downto 0) ;
       type adder_tree_t is array(0 to result-1) of adder_stage_t;
       
      signal mults : mult_array_t;
      signal adders : adder_tree_t;
          
        signal voie :Rom ;
        signal CD    : RAM;
       
        signal temp: ram16;
      
        --signal AB     :signed (17 downto 0) ;
       

        
begin
     
                                
                            
  
    
     
     
        AY:for j in 0 to longueur-1 generate 
           
           CD(j)<=code(4*(longueur-j)-1 downto 4*(longueur-j)-4 );
      end generate AY ;
    
    
       
     etalement:process(clk,rst)
         
        begin 
                  if(rst='1') then 
                     Q  <=(others=>'0');
                     
                   F:for k in 0 to longueur-1 loop 
                      mults(k)<=(others=>'0');
                   end loop ;
                    

                   
                        elsif(clk'event and clk ='1') then 
                             voie(0)<=signed(data) ;
                              
                              
                             B:for L in 1 to longueur-1 loop
                                voie(L)<=voie(L-1);
                              end loop ;
                               
                              
                            
                                     
                                      
                                     for i in 0 to longueur-1 loop 
                                       mults(i) <= voie(i)*signed(CD(i));
                                      end loop ;
                                      
                                      --initial adders:
                                     for i in 0 to result-1 loop
                                        adders(0)(i) <= resize(mults(i*2), Q'length) + resize( mults(i*2 +1), Q'length);
                                     end loop;
                                     
                                     --other adder stages:
                                     
                                     for level in 1 to adders'high loop
                                           for i in 0 to longueur/ (2**(level+1)) loop
                                               adders(level)(i) <= adders(level-1)(i*2) + adders(level-1)(i*2 + 1);
                                         end loop
                                      end loop;
                                      
                                      
                     end if ;  
                                     
                        
                       
            end process ;
            Q <= adders(adders'high)(0);
 end architecture ;


Thank you

- - - Updated - - -

like this :

can you help me to correct this code :

Code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use IEEE.math_real."ceil";
use IEEE.math_real."log2"; 

entity correla is 

generic  (
            longueur  : natural :=16 ;
            result := integer(ceil(log2(real(longueur))))) ;
            


port ( 
         clk : in    std_logic ;
         rst : in    std_logic  ;
         data: in    std_logic_vector(11 downto 0)  ; 

         
            code: in    std_logic_vector((4*longueur)-1 downto 0 )  ;
        
           
            Q   :out    std_logic_vector(result-1 downto 0) )  ;
      

end entity ;

architecture arch of correla  is 
       type RAM is array (0 to 3) of std_logic_vector(3 downto 0) ;
       type Rom is array (0 to longueur-1) of signed(11 downto 0) ;
       type mult_array_t is array (0 to longueur-1 ) of signed( 15 downto 0) ;
       type adder_stage_t is array(0 to longueur/2-1) of signed(Q'longueur-1 downto 0) ;
       type adder_tree_t is array(0 to result-1) of adder_stage_t;
       
      signal mults : mult_array_t;
      signal adders : adder_tree_t;
          
        signal voie :Rom ;
        signal CD    : RAM;
       
        signal temp: ram16;
      
        --signal AB     :signed (17 downto 0) ;
       

        
begin
     
                                
                            
  
    
     
     
        AY:for j in 0 to longueur-1 generate 
           
           CD(j)<=code(4*(longueur-j)-1 downto 4*(longueur-j)-4 );
      end generate AY ;
    
    
       
     etalement:process(clk,rst)
         
        begin 
                  if(rst='1') then 
                     Q  <=(others=>'0');
                     
                   F:for k in 0 to longueur-1 loop 
                      mults(k)<=(others=>'0');
                   end loop ;
                    

                   
                        elsif(clk'event and clk ='1') then 
                             voie(0)<=signed(data) ;
                              
                              
                             B:for L in 1 to longueur-1 loop
                                voie(L)<=voie(L-1);
                              end loop ;
                               
                              
                            
                                     
                                      
                                     for i in 0 to longueur-1 loop 
                                       mults(i) <= voie(i)*signed(CD(i));
                                      end loop ;
                                      
                                      --initial adders:
                                     for i in 0 to result-1 loop
                                        adders(0)(i) <= resize(mults(i*2), Q'length) + resize( mults(i*2 +1), Q'length);
                                     end loop;
                                     
                                     --other adder stages:
                                     
                                     for level in 1 to adders'high loop
                                           for i in 0 to longueur/ (2**(level+1)) loop
                                               adders(level)(i) <= adders(level-1)(i*2) + adders(level-1)(i*2 + 1);
                                         end loop
                                      end loop;
                                      
                                      
                     end if ;  
                                     
                        
                       
            end process ;
            Q <= adders(adders'high)(0);
 end architecture ;


Thank you
 

error :Error (10500): VHDL syntax error at correla.vhd(14) near text ":="; expecting ":", or ","
Error (10523): Ignored construct correla at correla.vhd(9) due to previous errors


Code:
entity correla is
Code:
result:= integer(ceil(log2(real(longueur)))) 
) ;

Thank you

- - - Updated - - -

In fact , this is my big problem :

Code:
                        result:= integer(ceil(log2(real(longueur)))) ;
 

Yep, you cannot assign value inside a port or generic definition. I suggest you go back to your VHDL tutorial.
 

yes i see what you mean im just a beginner in vhdl but i need your help if you can suggest a solution because i know that it
shoud not be in generic but the Q have this relation with the length also we can not do this as a port cause it is not a input or output so any suggestion plz ??!!

Thank you !
 

why not try sticking the function inside the definition of Q?

Q : out std_logic_vector( integer(ceil(log2(real(longueur)))) downto 0);
 

Absolutely ;
Is this function existe ??!

Code:
use IEEE.math_real.all;

use IEEE.math_real."ceil";
use IEEE.math_real."log2";

- - - Updated - - -

because I have an error about this !!

error : Error (10594): VHDL Selected Name error at correla.vhd(6): object ""ceil"" isn't declared in scope "MATH_REAL"
Error (10594): VHDL Selected Name error at correla.vhd(7): object ""log2"" isn't declared in scope "MATH_REAL"
 

try writing your own log2 function (for integers) - its a standard one that most engineers have in a package somewhere.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top