DNA2683
Advanced Member level 4
- Joined
- Sep 3, 2012
- Messages
- 106
- Helped
- 0
- Reputation
- 0
- Reaction score
- 0
- Trophy points
- 1,296
- Activity points
- 2,290
if you mean real type, you can use the built in functions of the new fixed_point packages:
signal a : sfixed(15 downto -16);
signal b : real;
b <= to_real(a);
If you give the fixed_point packages a go, you'll make your life a lot easier.
Otherwise you have to write a custom conversion function. There is no standard way to do it, as a std_logic_vector is not meant to be used to represent numbers.
1. sfixed is signed fixed, so already contains the sign bit. If your origional number was signed, you only need 15 downto -15. If it was origionally unsigned, use the ufixed (unsigned fixed) type.
2. Yes. If it is an IP core you may need to cast back to std_logic_vector first (there is a to_slv function for that). sfixed/ufixed and std_logic_vector are similar types as they are all arrays of std_logic (as are signed and unsigned).
1. The signed type is fine, you can convert it to sfixed using the function to_sfixed(X, nhigh, nlow), where nhigh is the MSB index, and nlow is LSB index (so would be 15 and -16 in your case, assuming a 32 bit number with 16 bit integer and 16 fraction.
2. yes you can, but the output must be 128 bits wide. You probably dont want output to be an sfixed type, because its now 4 numbers concatenated. A std_logic_vector would be more appropriate:
output <= to_slv(a&b&c&d);
3. Yes:
a <= b *c;
just make sure the bit sizings are correct:
signal a : sfixed(31 downto -32);
signal b,c : sfixed(15 downto -16);
or use the resize function.
why not just output the 4 values as sfixed? you can use sfixed on the ports (you can use any types you want).
Because your input widths are fixed, you can fix the output too (according to your specification).
according to your specs, output should be:
signal output : sfixed(19 downto -32);
PS. If the multiplier is between -3 to +3, you have the wrong size for you Mult1 and Mult 2. Currently they have a range -2 to 2-2^-16
I dont really understand the question. Have a go, and post some code, and I can fix the errors. You can pretty much write your equation in VHDL as it is, if you get the types right.
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 34 35 36 37 38 39 40 41 entity test is port( dudx : in sfixed(1 downto -16);--fixed numbers between -3 to 3 (for example 2.9311 or -1.5324) dvdx : in sfixed(1 downto -16);--fixed numbers between -3 to 3 (for example 2.9311 or -1.5324) u0 : in sfixed(10 downto -16);--fixed numbers between -640 to 640 (for example 533.9311 or -10.5324) dudy : in sfixed(1 downto -16);--fixed numbers between -3 to 3 (for example 2.9311 or -1.5324) dvdy : in sfixed(1 downto -16);--fixed numbers between -3 to 3 (for example 2.9311 or -1.5324) v0 : in sfixed(10 downto -16);--fixed numbers between -640 to 640 (for example 533.9311 or -10.5324) data_in : in std_logic_vector (19 downto 0); --input data a x&y coordinate(integers that are in 10 bit representation) values of x,y can be --negative or positive between -640 to 640 (10bit for x and 10 bit for y) data_out : out std_logic_vector (19 downto 0);--???? i d'ont know how to chose the size of the output??? clk : in std_logic; ); architecture behave of test is signal out _x : sfixed(10 downto -16);???? i d'ont know how to chose the size of this signal??? signal out_y : sfixed(10 downto -16); ???? i d'ont know how to chose the size of this signal??? signal in_x : integer range (640 to 0); signal in_y : integer range (640 to 0); begin in_x <= to_integer (data_in (9 downto 0)); in_y <= to_integer (data_in (19 downto 10)); process (clk) begin out _x<= dudx*x+dvdx*y+u0; out_y<= dudy*x+dvdy*y+u0; end process data_out <= to_slv(out _x) & to_slv(out _y); end behave;
ok. Lets start with
1. All the dud inputs are the wrong size. They currently only cover -2 to +2. You need (2 downto -16) to cover -4 to +
2. if all the other inputs are sfixed, why are data_in and data_out std_logic_vector?
3. Your process is not a clocked process.
4. To size the vectors, you need to follow these sizing rules:
signal X : sfixed(a downto b)
signal Y : sfixed(c downto d)
For addition, subtraction, op needs to be:
signal OP : sfixed( (larger of a or c) + 1 downto (smaller of b or d) );
for multiplication:
signal OP : sfixed( a + c + 1 downto b + d)
You always know the size of the calculation result as you know the size of the other vectcors. It doesnt matter what the current value is, it just matters what the max/min values are.
It's managed by fixed_pkg overload rules. The integer is automatically converted to a sfixed quantity of required size.4.1 can i do this?to multiply a sfixed with integer?
It's your job to define the maximum output number range and set the format respectively. Then perform a resize operation with overflow_style = fixed_saturate.4.2 i didn't understand how to define the out_x,out_y,data_out sizes can you tell me the code for it? base on my input(in_x,in_y can be
+/- 640 integer all du.. dv.. can be -/+ 3 sfixed
ok. Lets start with
1. All the dud inputs are the wrong size. They currently only cover -2 to +2. You need (2 downto -16) to cover -4 to +
2. if all the other inputs are sfixed, why are data_in and data_out std_logic_vector?
3. Your process is not a clocked process.
4. To size the vectors, you need to follow these sizing rules:
signal X : sfixed(a downto b)
signal Y : sfixed(c downto d)
For addition, subtraction, op needs to be:
signal OP : sfixed( (larger of a or c) + 1 downto (smaller of b or d) );
for multiplication:
signal OP : sfixed( a + c + 1 downto b + d)
You always know the size of the calculation result as you know the size of the other vectcors. It doesnt matter what the current value is, it just matters what the max/min values are.
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?