Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

std_logic_vector divide

Status
Not open for further replies.

naraic

Technical User
Aug 12, 2003
45
IE
Is there any operator to divide a
Code:
std_logic_vector[\code], either by another [code]std_logic_vector[\code] or by an [code]integer[\code]?

I am using the following code at the moment

[code]temp := CONV_INTEGER(buf2) / q ;
ZRLOut <= CONV_STD_LOGIC_VECTOR(temp,11);[\code]

where [code]buf2[\code] and [code]ZRLOut[\code] are signals of type [code]std_logic_vector[\code], [code]temp[\code] is a variable of type [code]integer[\code], and [code]q[\code] is a signal of type [code]integer[\code].

Thanks
Ciarán Hughes

This works fine in behavioural simulation, but when I run a post translate simulation, the division seems to be ignored, i.e. [code]ZRLOut[\code] is equal [code]buf2[\code]. It is like the division can't be synthesised, and is ignored (like the [code]after[\code] statement).
 
The divisor operator for any data type is the same '/'. However, the only limitation in most synthesis tools when it comes to division is, the divisor ( ...in your case, the 'q'), has to be a constant, and a power-of-2.

If you find that division is not performed in your code, then check if there is some optimizations. Before that, check if you have declared the range on the integer signals appropriately.

Is it possible to get the complete code, if you feel everything is alright in the design?
 
I won't post the complete code, as it is over 200 lines, and is part of a larger project. The code is

Code:
architecture logic of secondPass is
type mem is array(63 downto 0) of STD_LOGIC_VECTOR(10 downto 0);
type zzTable is array(63 downto 0) of INTEGER range 63 downto 0;
type qTable is array(63 downto 0) of INTEGER range 255 downto 1; 

constant zz: zzTable := (63, 62, 55, 47, 54, 61, 60, 53, 46, 39, 31, 38, 45, 52, 59, 58, 51, 
						 	44, 37, 30, 23, 15, 22, 29, 36, 43, 50, 57, 56, 49, 42, 35, 28, 21,
						 	14,  7,  6, 13, 20, 27, 34, 41, 48, 40, 33, 26, 19, 12,  5,  4, 11,
						 	18, 25, 32, 24, 17, 10,  3,  2,  9, 16,  8,  1,  0 );
constant q: qTable := ( 99, 103, 101, 92, 120, 100, 112, 121, 113, 77, 62, 103, 104, 103,
							98, 95, 87, 81, 109, 80, 56, 55, 69, 87, 68, 64, 78, 92, 72, 64, 55,
							56, 51, 57, 60, 61, 51, 58, 40, 29, 37, 35, 49, 24, 22, 22, 24, 26,
							40, 24, 19, 16, 17, 18, 14, 13, 14, 16, 10, 12, 14, 12, 11, 16 );

signal buf2: mem;
signal count4: INTEGER range 0 to 64;
......
begin
......
zigZagOutput: process(clk,rst,count4,buf2)
variable temp: INTEGER range -1024 to 1023;
begin
  if rst = '1' then
  ......
  elsif clk'event and clk = '1' then
  ......
 
I won't post the complete code, as it is over 200 lines, and is part of a larger project. The code is

Code:
architecture logic of secondPass is
type mem is array(63 downto 0) of STD_LOGIC_VECTOR(10 downto 0);
type zzTable is array(63 downto 0) of INTEGER range 63 downto 0;
type qTable is array(63 downto 0) of INTEGER range 255 downto 1; 

constant zz: zzTable := (63, 62, 55, 47, 54, 61, 60, 53, 46, 39, 31, 38, 45, 52, 59, 58, 51, 
						 	44, 37, 30, 23, 15, 22, 29, 36, 43, 50, 57, 56, 49, 42, 35, 28, 21,
						 	14,  7,  6, 13, 20, 27, 34, 41, 48, 40, 33, 26, 19, 12,  5,  4, 11,
						 	18, 25, 32, 24, 17, 10,  3,  2,  9, 16,  8,  1,  0 );
constant q: qTable := ( 99, 103, 101, 92, 120, 100, 112, 121, 113, 77, 62, 103, 104, 103,
							98, 95, 87, 81, 109, 80, 56, 55, 69, 87, 68, 64, 78, 92, 72, 64, 55,
							56, 51, 57, 60, 61, 51, 58, 40, 29, 37, 35, 49, 24, 22, 22, 24, 26,
							40, 24, 19, 16, 17, 18, 14, 13, 14, 16, 10, 12, 14, 12, 11, 16 );

signal buf2: mem;
signal count4: INTEGER range 0 to 64;
......
begin
  ......
  zigZagOutput: process(clk,rst,count4,buf2)
  variable temp: INTEGER range -1024 to 1023;
  begin
    if rst = '1' then
      ......
    elsif clk'event and clk = '1' then
      ......
      if go = '1' then
        temp := CONV_INTEGER(buf2(zz(count4))) / q(count4);
        ZRLOut <= CONV_STD_LOGIC_VECTOR(temp,11);
        count4 <= count4_int + 1;
      end if;
    end if;
  end process zigZagOutput;
  ......
end architecture logic;[\code]

Basically, each clock cycle, the appropriate value in buf2 is divide by the appropriate value in q, and output to ZRLOut. I don't think there is anything wrong with the ranges, and the compiler doesn't report any warning (I have the check for synthesis option turned on)

Thanks
Ciaran
 
Sorry about that mistake post.

Also, the divisor is a constant, but they are not powers of two.

Thanks
 
Ok. I know that most synthesis tools don't support dividion like I want here.

So my problem is how to do this division. I want a signed by unsigned divider. Anybody know where I could find VHDL code for such, or how I could implement such a design?

Thanks
Ciarán
 
How about converting to unsigned, assuming that you have declared a library with an unsigned division overload.

ie
ZRLOut <= std_logic_vector(unsigned(buf2) / unsigned(q));

of course your synthesis tool may not like that either, but its another possibility.

Note: Don't declare two libraries with unsigned at once within one design - it can cause strange problems that are really hard to find. (for example numeric_std and std_logic_arith)
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top