Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)

Help with Bit Extraction

Altera_Forum
Honored Contributor II
1,366 Views

I have a basic question about the following: 

 

MIN_GAIN : unsigned(13 downto 0) := b"10000000000000"; -- 0x2000 

 

gain_in : in std_logic_vector(13 downto 0); 

 

val : unsigned(13 downto 0); -- 14 bits 

gain : std_logic_vector(15 downto 0); -- 16 bits 

 

IN MY CODE I HAVE: 

 

1.) val <= unsigned(gain_in)-MIN_GAIN; 

 

2.) gain(13 downto 0) <= std_logic_vector((b"000"&x"00"& val(13 downto 11)) + 1); -- concatenation 

 

How do you get rid of the second assignment? It seems reasonable that one should be able to  

extract the bits in the first assignment statement. However I get an error when I do the following: 

 

val <= (unsigned(gain_in-MIN_GAIN)(13 downto 11); 

 

The code is subtracting a value MIN_GAIN and then shifting right by 11. One should be able to 

do that shift in the first statement so that the second statement is not needed. The goal is to get 

rid of that second statement and do the entire operation with one statement. 

 

Anyone know what I'm doing wrong? 

 

 

Thanks.
0 Kudos
7 Replies
Altera_Forum
Honored Contributor II
580 Views

 

--- Quote Start ---  

I have a basic question about the following: 

 

MIN_GAIN : unsigned(13 downto 0) := b"10000000000000"; -- 0x2000 

 

gain_in : in std_logic_vector(13 downto 0); 

 

val : unsigned(13 downto 0); -- 14 bits 

gain : std_logic_vector(15 downto 0); -- 16 bits 

 

IN MY CODE I HAVE: 

 

1.) val <= unsigned(gain_in)-MIN_GAIN; 

 

2.) gain(13 downto 0) <= std_logic_vector((b"000"&x"00"& val(13 downto 11)) + 1); -- concatenation 

 

How do you get rid of the second assignment? It seems reasonable that one should be able to  

extract the bits in the first assignment statement. However I get an error when I do the following: 

 

val <= (unsigned(gain_in-MIN_GAIN)(2 downto 0); 

 

The code is subtracting a value MIN_GAIN and then shifting right by 11. One should be able to 

do that shift in the first statement so that the second statement is not needed. The goal is to get 

rid of that second statement and do the entire operation with one statement. 

 

Anyone know what I'm doing wrong? 

 

 

Thanks. 

--- Quote End ---  

 

 

your topic and discussion is not helpful. 

 

It seems you want this 

result <= unsigned(gain_in) - MIN_GAIN; -- ok 

final_result <= result(13 downto 11);  

 

but you are adding 1 as well.  

Note that 2 bits + 1 needs 3 bits yet your final output is 14 bits???
0 Kudos
Altera_Forum
Honored Contributor II
580 Views

 

--- Quote Start ---  

your topic and discussion is not helpful. 

 

It seems you want this 

result <= unsigned(gain_in) - MIN_GAIN; -- ok 

final_result <= result(13 downto 11);  

 

but you are adding 1 as well.  

Note that 2 bits + 1 needs 3 bits yet your final output is 14 bits??? 

--- Quote End ---  

 

 

 

Yes. I may have put the wrong bit numbers. I'll check that 

 

After the subtraction the result is shifted 11 bits. So bits 

13, 12, and 11 get moved into bit positions 2 ,1 and 0. 

 

This is then concatenated 

with 0's to get a final 14 bit vector. Thus, I have: 

final_result <= b"000" & x"00" & val(13 downto 11) + 1; 

 

I have two statements that accomplish this but would like to have only 

one statement because it's clocked and the second statement is 

one clock later. 

 

It seems to me that I should be able to do this entire operation in one statement as: 

gain = (b"000" & x"00" & (unsigned(gain_in) - MIN_GAIN)) + 1; 

 

So my question is how can I keep bits 13, 12, and 11 from the statement 

(unsigned(gain_in) - MIN_GAIN) ? 

Doing something like (unsigned(gain_in)-MIN_GAIN)(13 downto 11) doesn't work. 

Right now this temporary variable "val" has to be used which I'm trying to get rid of 

because it's off by 1 clock. 

 

Is there something one would prefix or postifx to ??? (unsigned(gain_in)-MIN_GAIN) ??? 

to get just those bits 13, 12 and 11? I have had no luck finding it. 

 

So, the single equation looks like: bits 13, 12, and 11 only 

final_result <= (b"000" & x"00" & (unsigned(gain_in) - MIN_GAIN) ) + 1; 

This statement as it stands doesn't tell me what bits the subtraction will keep! 

 

Thank you for you reply.
0 Kudos
Altera_Forum
Honored Contributor II
580 Views

You have two stages: 

subtraction followed by addition of 1 to those 3 bits 

 

first: it doesn't make much sense as you lose a lot of bits (11 bits set permanently to zero) 

second: if you want subtraction and addition in one clock then you might just put one of them outside the clocked process 

since either way it implies one clock period for both operations.
0 Kudos
Altera_Forum
Honored Contributor II
580 Views

 

--- Quote Start ---  

You have two stages: 

subtraction followed by addition of 1 to those 3 bits 

 

first: it doesn't make much sense as you lose a lot of bits (11 bits set permanently to zero) 

second: if you want subtraction and addition in one clock then you might just put one of them outside the clocked process 

since either way it implies one clock period for both operations. 

--- Quote End ---  

 

 

 

You mean: 

 

Put this outside in a concurrent statement: 

val = (unsigned(gain_in) - MIN_GAIN; 

 

Then, in the clocked process put: 

gain = b"000" & x"00" & val(13 downto 11); 

 

I did this a little while ago and it appears to work. 

 

The question is: Will the output of val be ready by the time the 

clock pulse comes? The clock is 40 MHz in a Virtex 4. That gives 25 ns 

to get through the subtractor logic to the gain register. 

 

Cadence simulations shows it's working OK. 

 

But isn't there a way to say you want only some particular 

bits in an expression like the above and do it in the clocked  

process? (A-B) is an expression giving a result of so many bits. 

What's wrong with (A-B)(13 downto 11) meaning that only bits 

13 to 11 will be used after the subtraction. Why does it have to 

be assigned to some signal? 

 

Thanks, 

PWS
0 Kudos
Altera_Forum
Honored Contributor II
580 Views

 

--- Quote Start ---  

You mean: 

 

Put this outside in a concurrent statement: 

val = (unsigned(gain_in) - MIN_GAIN; 

 

Then, in the clocked process put: 

gain = b"000" & x"00" & val(13 downto 11); 

 

 

--- Quote End ---  

 

 

yes that is what I meant. It should be ok on 40MHz speed (usually). 

 

However, I don't get what you are aiming at. It will help if you tell us what you are trying to achieve in terms of concept (not code). 

Normally gain word is multiplied by signal and result is then truncated say by 11 bits.
0 Kudos
Altera_Forum
Honored Contributor II
580 Views

 

--- Quote Start ---  

yes that is what I meant. It should be ok on 40MHz speed (usually). 

 

However, I don't get what you are aiming at. It will help if you tell us what you are trying to achieve in terms of concept (not code). 

Normally gain word is multiplied by signal and result is then truncated say by 11 bits. 

--- Quote End ---  

 

 

I really don't know.. I'm just given the equation. You have a 14 bit input and subtract that 14-bit input 

from 8192. Then you divide (right shift) by 2^11. Thus, one is essentially subtracting and only keeping 

bits 13, 12, 11.  

 

You know, in 'C you can write a statement and then use it as a pointer. You don't have to have 

the variable name. You can use an expression. So, it seemed reasonable to me that one could 

do the same thing in VHDL. I guess not. 

 

((unsigned(gain_in) - MIN_GAIN) This expression is 14 bits. So why can't one just extract what bits 

one wants instead assigning it to a signal name? That way one can avoid using the concurrent 

statement altogether. 

 

As I mentioned before. Something like (unsigned(gain_in)-MIN_GAIN)(13 downto 11). 

The synthesizer should interpret this as perform the subtraction and from the result take bits 

13, 12 and 11. Unfortunately,, ISE doesn't do that. It gives and ERROR. So does Cadence. 

 

But in 'C' one can do something similar.
0 Kudos
Altera_Forum
Honored Contributor II
580 Views

 

--- Quote Start ---  

yes that is what I meant. It should be ok on 40MHz speed (usually). 

 

However, I don't get what you are aiming at. It will help if you tell us what you are trying to achieve in terms of concept (not code). 

Normally gain word is multiplied by signal and result is then truncated say by 11 bits. 

--- Quote End ---  

 

 

Thanks again for your suggestion.
0 Kudos
Reply