There is a more elegant way to multiplie and divide 12 bit values in my code? (vhdl)

Status
Not open for further replies.

Kepsz

Member level 1
Joined
Feb 7, 2012
Messages
32
Helped
1
Reputation
2
Reaction score
1
Trophy points
1,288
Activity points
1,521
My input is a 12bit value form a DAC output. (0..4095 in decimal) I'm using 4 seven segment display, where i willing to see voltage in this form: x.yyy where X is the integer part, yyy is the fraction. In Xilinx ISE, there is problems with fixed / floating points package, so i had to work with integer values only. (see my project in youtube for easyer understanding: Digilent Basys2 starter kit - 0 to 3.3V digital voltage meter with multiplexed BCD display - YouTube )

My solution:
Because of 0..4095 = 0..3,3V, output = input * 3300 / 4096, thats written in the code below. For Example 2097 from input results 1689 in the output, wich means 1.689V in display.


Code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;

entity math is
	port (
		CLK_in:		in std_logic;
		INPUT1:		in	std_logic_vector( 11 downto 0 );
		OUTPUT:		out std_logic_vector ( 11 downto 0 ));
end math;

architecture Behavioral of math is
begin
	Process(CLK_in, INPUT1)
		variable temp0: unsigned (35 downto 0);
	begin
		if (rising_edge(CLK_in)) then
			temp0(35 downto 0) := unsigned("000000000000" & INPUT1 & "000000000000" );
			temp0 := temp0 * "11001110001"; -- * 3300 (1000 * 3,3V)
			temp0 := temp0 / "1000000000000"; -- /4096 (power of 2)
			OUTPUT(11 downto 0) <= std_logic_vector(temp0(11 downto 0));
		end if;
	end process;
end Behavioral;

This code works in my starter kit, but ISE gaves some erro:
Code:
Width mismatch. <temp0> has a width of 36 bits but assigned expression is 47-bit wide.

The problem is with the temp0 := temp0 * "11001110001"; line. For example multiplication of 111111111111 (4095) with 11001110001 (3300) gaves the value of 11001110000100110001111 (6752655) in temp0 from 22 downto 0. If i dont put this & "000000000000" after "000000000000" & INPUT1, right half of the 11001110000100110001111 bits goes to trash. If i write only this: temp0(23 downto 0) := unsigned(INPUT1 & "000000000000" );, it works in simulator, but not in my starter kit.

I tryd using to instead of downto in math, it's also worked well in simulator, giving correct values, but also dont worked in my starter kit.

So if there is a more better solution, please help me.
 

Whats wrong with fixed point packages? there is a Xilinx version here:
**broken link removed**

But whats wrong with this code?

Code:
temp0 := resize(Input1, temp0'length) * 2**12;
temp0 := temp0 * 3300;
output <= temp0(23 downto 12);
 


is there a reason you cant make output an unsigned rather than std_logic_vector? otherwise:

output <= std_logic_vector( temp0(23 downto 12) );
 

I got this errors:

Code:
			temp0 := resize(Input1, temp0'length) * 2**12;
			temp0 := temp0 * 3300;
			output <= temp0(23 downto 12);

ERROR:HDLCompiler:432 - "D:/Store/DAC_teszt/math.vhd" Line 22: Formal has no actual or default value.
ERROR:HDLCompiler:540 - "D:/Store/DAC_teszt/math.vhd" Line 22: Indexed name prefix type signed expects 1 dimensions
ERROR:HDLCompiler:539 - "D:/Store/DAC_teszt/math.vhd" Line 24: Indexed name is not a std_logic_vector



Code:
			temp0 := resize(Input1, temp0'length) * 2**12;
			temp0 := temp0 * 3300;
			output <= std_logic_vector(temp0(23 downto 12));

ERROR:HDLCompiler:432 - "D:/Store/DAC_teszt/math.vhd" Line 22: Formal has no actual or default value.
ERROR:HDLCompiler:540 - "D:/Store/DAC_teszt/math.vhd" Line 22: Indexed name prefix type signed expects 1 dimensions
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…