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.

fixed point to std_logic_vector conversion in vhdl

Status
Not open for further replies.

symlet

Member level 1
Member level 1
Joined
Oct 12, 2012
Messages
41
Helped
1
Reputation
2
Reaction score
1
Trophy points
1,288
Visit site
Activity points
1,616
Hai,

I have 4 constant value with fixed point values (0.123, 0.431,-0.871) and I want to build the ROM table for this constant. How to convert the fixed point value to std_logic_vector type?. Is it possible? If yes, how to do that? Thanks in advance
 

Yes. The floating point library at www.vhdl.org/fphdl has a to_slv function.

Hai TrickyDicky,

Thanks, I get it.:smile:

- - - Updated - - -

Hai,

I change my vhdl package as below:
Code:
library IEEE;
library ieee_proposed;
  use ieee_proposed.fixed_pkg.all;
  use IEEE.STD_LOGIC_1164.all;
  use ieee.numeric_std.all;
  
package MDWT_PKG is
  
  -- 2's complement numbers


	constant h0 : sfixed(3 downto -4)  := 0.483;
	constant h1 : sfixed(3 downto -4) := 0.837;
	constant h2 : sfixed(3 downto -4) := 0.224;
	constant h3 : sfixed(3 downto -4) := -0.129;
However I get this error : "Type sfixed does not match with the real literal". What my mistake? Thanks in advance
 
you need to use the to_sfixed function to convert the real number to an sfixed type.
 

you need to use the to_sfixed function to convert the real number to an sfixed type.

Hai TrickyDicky,

I do the to_sfixed at the vhdl package, whilst in the ROM I convert them to std_logic_vector using to_slv. Below is the vhdl package:
Code:
library IEEE;
library ieee_proposed;
  use ieee_proposed.fixed_pkg.all;
  use IEEE.STD_LOGIC_1164.all;
  use ieee.numeric_std.all;
  
package MDWT_PKG is
    
  signal n1 : sfixed(3 downto -4);
  signal n2 : sfixed(4 downto -4);
  -- 2's complement numbers

	constant h0 : sfixed(3 downto -4)  := to_sfixed(0.483,n1);
	constant h1 : sfixed(3 downto -4)  := to_sfixed(0.837,n1);
	constant h2 : sfixed(3 downto -4)  := to_sfixed(0.224,n1);
	constant h3 : sfixed(4 downto -4)  := to_sfixed(-0.129,n2);
However, the bits for all the constant values are not same. h0-h2 have 8bits (7 downto 0) and h3 have 9bits (8 downto 0). How to make them synchronize (same bits)? I think if I make ho-h2 to 9bits, it will change the original value. How to do this? Thanks in advance
 
Last edited:

Why have you decalred a signal in the package?
you can just specify the values in the other version of the to_sfixed(X, high, low) function:

constant h3 : sfixed(4 downto -4) := to_sfixed(-0.129, 4, -4);

having more bits for h0-2 will not affect the data value or the result value. You just get extra 0's at the front.
 

Hai TrickyDicky,

I have correct the package and ROM vhdl codes. I set all the constant h0-h3 : sfixed(9 downto -4), I set to 14bits/elements. Then at the ROM I convert the like:
Code:
type ROM_TYPE is array (0 to (2**ROMADDR_W)-1) 
            of STD_LOGIC_VECTOR(13 downto 0);
  constant rom : ROM_TYPE := 
    (                --error occur at this line
    (others => '0'),                
     to_slv( h0 ),         
     to_slv( h1 ),         
     to_slv( h0+h1 ),      
     to_slv( h2 ),         
     to_slv( h2+h0 ),      
     to_slv( h2+h1),      
     to_slv( h2+h1+h0 ),   
     to_slv( h3 ),         
     to_slv( h3+h0),      
     to_slv( h3+h1),      
     to_slv( h3+h1+h0 ),   
     to_slv( h3+h2),      
     to_slv( h3+h2+h0 ),   
     to_slv( h3+h2+h1 ),   
     to_slv( h3+h2+h1+h0),

However, when I compile the project I get this error: "Expression has 15 elements ; expected 14". What my mistake? Thanks in advance
 

Well, you didnt say where the error is pointing, but Id have thought the error was quite obvious. The value has 15 bits, but the entries in the rom are only 14 bits according to your type.

- - - Updated - - -

If you declared h0-h3 as sfixed, you need to know that h0 + h1 will produce a result that is 1 bit larger. You need to resize the result with the resize function.
 

If you declared h0-h3 as sfixed, you need to know that h0 + h1 will produce a result that is 1 bit larger. You need to resize the result with the resize function.

In the ROM entries, I set the bits to 14bits. But, how to resize the results in the ROM? Is it I need to do the addition operations first (outside the ROM) before take the results into the ROM? Thanks in advance
 

It doesnt matter where you do them. You can easily use the resize function on the result, either inside or outside the constant (it is not a ROM yet, it is just a constant definition).
 

Hai TrickyDicky,

I don't know how to use resize function,but I try to do like this:
Code:
type ROM_TYPE is array (0 to (2**ROMADDR_W)-1) 
            of STD_LOGIC_VECTOR(13 downto 0);
  constant rom : ROM_TYPE := 
    (
    (others => '0'),                
     to_slv( h0 ),         
     to_slv( h1 ),
	  STD_LOGIC_VECTOR(RESIZE(RESIZE(SIGNED(to_slv( h0)),ROMDATA_W))+(RESIZE(SIGNED(to_slv(h1))),ROMDATA_W)),      
     to_slv( h2 ),

Unfortunately, I get errors:
ERROR:HDLCompiler:620 - "J:\MyResearch\Xilinx_Project\discretewavelettransform\MDWT4\DWT\ROM.vhd" Line 50: Near signed ; type conversion does not match type unresolved_sfixed
ERROR:HDLCompiler:1728 - "J:\MyResearch\Xilinx_Project\discretewavelettransform\MDWT4\DWT\ROM.vhd" Line 50: Type error near romdata_w ; current type integer; expected type unresolved_sfixed
ERROR:HDLCompiler:432 - "J:\MyResearch\Xilinx_Project\discretewavelettransform\MDWT4\DWT\ROM.vhd" Line 50: Formal <size_res> has no actual or default value.
ERROR:HDLCompiler:841 - "J:\MyResearch\Xilinx_Project\discretewavelettransform\MDWT4\DWT\ROM.vhd" Line 50: Expecting type std_ulogic for <resize>.
ERROR:HDLCompiler:854 - "J:\MyResearch\Xilinx_Project\discretewavelettransform\MDWT4\DWT\ROM.vhd" Line 41: Unit <rtl> ignored due to previous errors.

Can you give hint how to make the resize function? Thank in advance
 

Thats probably the most overcomplicated attempt Ive ever seen...

all you need is:
to_slv( resize( H0 + H1, H0'high, H0'low) ),

- - - Updated - - -

wouldnt it just be easier to declare H0 etc as real types and then do the conversion when you need them? then you dont need the resize functions:

Code:
CONSTANT H0 : real := 0.483;
....etc

CONSTANT H0_FP : sfixed(3 downto -4) := to_sfixed(H0, 3, -4);
..etc

...in the ROM Constant
to_slv( to_sfixed( H0 + H1, H0'high, H0'low) ),
--etc

- - - Updated - - -

Or even better, why not just declare the ROM as an array of sfixed?
 
  • Like
Reactions: symlet

    symlet

    Points: 2
    Helpful Answer Positive Rating
Hai TrickyDicky,

There are many ways to do the conversion in vhdl right,interesting. I will try to do your suggestions. Btw,thanks for your helps, I really appreciate it.
 

Hai TrickyDicky,

I do your second method,but get this error:
Line 50: Prefix of attribute high is not a type mark
Line 50: Formal <arg> has no actual or default value.
Line 50: Indexed name prefix type unresolved_sfixed expects 1 d

Code:
type ROM_TYPE is array (0 to (2**ROMADDR_W)-1) 
            of STD_LOGIC_VECTOR(13 downto 0);
  constant rom : ROM_TYPE := 
    (
    (others => '0'),                
     to_slv( h0_FP ),         
     to_slv( h1_FP ),         
     to_slv(to_sfixed(h0+h1,h0'high,h0'low )),      
     to_slv( h2_FP ),         
     to_slv(to_sfixed(h2+h0,h2'high,h2'low)),

Why the error occur and what my mistake? Thanks in advance

- - - Updated - - -

I change the code and they run successfully.
Code:
to_slv(to_sfixed(h0+h1,h0_FP'high,h0_FP'low )),
 

thats because 'high and 'low attributes can only be used on array types, not on real types.
 
  • Like
Reactions: symlet

    symlet

    Points: 2
    Helpful Answer Positive Rating
Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top