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

bit shift and extract

Altera_Forum
Honored Contributor II
3,495 Views

Hi everyone! 

 

i want to shift a number 24 bit to the right (cut off), and extract the remaining 8 bit. how to do it in vhdl? 

a = b >>24 & 0xff; 

 

 

So far I tried to work with srl, shift_right(), '&' and 'and' operators - actually nothing worked out. Running everything within a procedure, I have the following declarations 

(...) variable temp: integer range 0 to 65535; variable d3: integer range 0 to 15; (...) -- and currently apply it the following way d3 := to_integer(shift_right(unsigned(temp), 24)) and "11111111";  

 

first I left away any "and" construction: d3 := to_integer(shift_right(unsigned(temp), 24)); 

Errors I obtain:Error: VHDL Use Clause error at increment_display.vhd(61): more than one Use Clause imports a declaration of simple name "unsigned" -- none of the declarations are directly visible 

...so I removed "unsigned()" 

 

Error: VHDL error at increment_display.vhd(61): can't determine type of object at or near identifier "shift_right" -- found 0 possible types 

...so I removed to_integer(), actually everything was already devined as integer, no? 

 

Error: VHDL Qualified Expression error at increment_display.vhd(61): SHIFT_RIGHT type specified in Qualified Expression must match integer type that is implied for expression by context 

...hum... 

 

Actually, I could not find much or any example snippets on shifting and extracting, is there a totally different way of doing this in VHDL?
0 Kudos
7 Replies
Altera_Forum
Honored Contributor II
2,256 Views

I'm not sure about the syntax, but this is the usual way to extract bits in HDL: 

variable tvect : std_logic_vector(7 downto 0); 

tvect := conv_std_logic_vector(temp); 

d3 := conv_integer(treg(31 downto 24);
0 Kudos
Altera_Forum
Honored Contributor II
2,256 Views

 

--- Quote Start ---  

Hi everyone! 

 

i want to shift a number 24 bit to the right (cut off), and extract the remaining 8 bit. how to do it in vhdl? 

a = b >>24 & 0xff; 

 

 

--- Quote End ---  

 

 

I dont think you quite understand VHDL is not a programming language. As such, you can easily just pull out the bits you want: 

 

signal a : std_logic_vector(31 downto 0); --pull out some bits output <= a(19 downto 12);  

 

 

--- Quote Start ---  

 

So far I tried to work with srl, shift_right(), '&' and 'and' operators - actually nothing worked out. Running everything within a procedure, I have the following declarations 

 

--- Quote End ---  

 

 

Why are you in a procedure? is this behavioural code? or are you trying to synthesise? please post the whole code so we can see what you're actually trying to do 

 

 

--- Quote Start ---  

 

(...) variable temp: integer range 0 to 65535; variable d3: integer range 0 to 15; (...) -- and currently apply it the following way d3 := to_integer(shift_right(unsigned(temp), 24)) and "11111111";  

 

--- Quote End ---  

 

 

In VHDL, an integer is not type with individual bits - you need to convert it to a more appropriate type like signed or unsigned to access bits or concatenate bits. The code snippet you posted doesnt make any sense. 

 

 

 

--- Quote Start ---  

 

first I left away any "and" construction: d3 := to_integer(shift_right(unsigned(temp), 24)); 

Errors I obtain:Error: VHDL Use Clause error at increment_display.vhd(61): more than one Use Clause imports a declaration of simple name "unsigned" -- none of the declarations are directly visible 

...so I removed "unsigned()" 

 

Error: VHDL error at increment_display.vhd(61): can't determine type of object at or near identifier "shift_right" -- found 0 possible types 

...so I removed to_integer(), actually everything was already devined as integer, no? 

 

Error: VHDL Qualified Expression error at increment_display.vhd(61): SHIFT_RIGHT type specified in Qualified Expression must match integer type that is implied for expression by context 

...hum... 

 

--- Quote End ---  

 

 

This is because you have used both ieee.std_logic_arith and ieee.numeric_std in your file. You need to delete the non-standard std_logic_arith from the use clauses and these errors will go away. 

Actually, I could not find much or any example snippets on shifting and extracting, is there a totally different way of doing this in VHDL? 

 

 

--- Quote Start ---  

 

I'm not sure about the syntax, but this is the usual way to extract bits in HDL: 

variable tvect : std_logic_vector(7 downto 0); 

tvect := conv_std_logic_vector(temp); 

d3 := conv_integer(treg(31 downto 24); 

 

--- Quote End ---  

 

 

THis is non-standard VHDL.
0 Kudos
Altera_Forum
Honored Contributor II
2,256 Views

Thank you dear Moderator! Thank you Cris72!!! First, you're absolutely right, I'm absolutely rather fighting with VHDL than understanding what I'm doing. Thus I really appreciate your answers!! I appologize, but please be patient with guys like me :) 

 

So, for my beginner's project I'm trying to play with the 7-seg display of my DE1-SoC (Terasic) board. I recycled two example codes I did so far: 

One that counts and uses actually a package ("package is..") implementation for displaying a 4-digit decimal number. Another one I use as "behavioral" (the thing with "architecture is..", right?). I imported the display and package into QSYS and did a top level .vhd. In order to obtain input from Linux via an AVALON MM interface. For decimal, the setup worked fine. But now I want to print hex numbers on the 7-seg display instead of decimal. Actually I now see that by AVALON MM I already obtain an std_logic_vector which I convert into integer, so this is probably then not even necessary!? 

 

Perhaps best is I post the specific "package" as working original, with some comments.. My idea actually is instead of separating thousands, houndreds, tens and ones, to separate into the 4-tuple of 32 bit values for my hex display. Later I'd like to print by switch setting the first, second or... 4-tuple of bigger hex numbers as well. 

library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; package my is -- function declaration: has one return value function int_to7seg(a:integer) return std_logic_vector; -- procedure declaration: has several return values procedure seg_ctrl(signal number: in integer; signal digit1, digit2, digit3, digit4: out integer range 0 to 9); end my; package body my is function int_to7seg(a:integer) return std_logic_vector is variable result: std_logic_vector(6 downto 0); begin case a is -- since segments are active when LOW(0), the function must return 1111001 for '1' when 0 => result := "1000000"; -- display 0 when 1 => result := "1111001"; when 2 => result := "0100100"; when 3 => result := "0110000"; when 4 => result := "0011001"; when 5 => result := "0010010"; when 6 => result := "0000010"; when 7 => result := "1111000"; when 8 => result := "0000000"; when 9 => result := "0010000"; -- extend for values up to 15 when others => result:=(others=>'0'); -- rest all to '0' end case; return result; end int_to7seg; -- split the number, if the number is bigger than e.g. 999, -- divide it by 1000, the result is the number of the 4th -- 7-seg-display procedure seg_ctrl(signal number: in integer; signal digit1, digit2, digit3, digit4: out integer range 0 to 9) is variable temp: integer range 0 to 9999; -- I changed this to a different limit variable d1: integer range 0 to 9;-- I changed this to a different limit variable d2: integer range 0 to 9;-- I changed this to a different limit variable d3: integer range 0 to 9;-- I changed this to a different limit variable d4: integer range 0 to 9;-- I changed this to a different limit begin temp:= number; -- thousands if(temp>999)then -- TODO for this position (I renamed d3, starting from d0), I'd like to cut out the specific bits d4 := temp/1000; temp := temp-d4*1000; else d4 := 0; end if; -- houndreds if(temp>99)then d3 := temp/100; temp := temp-d3*100; else d3 := 0; end if; -- tens if(temp>9)then d2 := temp/10; temp := temp-d2*10; else d2 := 0; end if; -- ones d1 := temp; -- translate to digits digit1 <= d1; digit2 <= d2; digit3 <= d3; digit4 <= d4; end seg_ctrl; end my;  

 

what would be the "standard" way to perform this in vhdl?
0 Kudos
Altera_Forum
Honored Contributor II
2,256 Views

This code looks exactly like someone who is trying to write VHDL as if it was a programming language, rather than a hardware description language. 

 

I highly suggest you take a step back and start again. Before you write any code, draw, on a peice of paper, the circuit you are trying to create. Once you are pretty confident of this, only then come back and write the VHDL. VHDL is a Hardware Description Language, and unless you know what circuit you want, how do you expect to describe it? 

 

You may want to find a book on Digital logic design using VHDL - those one is highly recommended  

http://www.amazon.com/designers-guide-edition-systems-silicon/dp/0120887851
0 Kudos
Altera_Forum
Honored Contributor II
2,256 Views

Hi again, 

 

Well, I think I see your point - especially at the decomposition of the number. I really appreciate your recommendation of literature. Actually some months ago I was looking for a book. I did not find anything usefull and I ended up with rather a bunch of tutorials. Now, I'm already (very) short on time and reading an 850 pages book for having a simple hex display run by the weekend does not seem to be very realistic. I'll keep the book marked, though.  

 

Can it be that it makes a bit of a difference in the approach, coming from software or from hardware? E.g. for me, coming from software, what you say sound like I should first develop a statemachine for my software. Then translate it into hardware circuits / elements / digital logic and then translate the circuits finally into VHDL. Clearly from what I saw, people coming from hardware are taking this approach, starting in the forelast step: the circuits which to them is more intuitive, and then simply convert them into VHDL.  

 

Do I really have to go the way through the hardware circuits here? So far it sounds to me like rather: Forget the number decomposition! Take the std_logic_vector input from the AVALON interface directly. At most buffer it somewhere. Cut out the bits you need (switch/case) and print them hex (switch/case). That's it. It's much easier, it's not a state machine at all, and it absolutely does not require any gatelevel logic?! Am I doing wrong? It would go towards the answer of Cris72 even. You mentioned it was not "standard VHDL" - so, could you tell me please, at least in words, what would be the standard way for it? How then a style-correct implementation (probably, even shorter than 3 lines) would look like? If it was longer, what was the gain or what is the risk in writing the above three lines? Could you give me an example? Input would be std_logic_vector, output needs to be an extracted number.
0 Kudos
Altera_Forum
Honored Contributor II
2,256 Views

IF all you want is to display a number directly out of avalon, then yes, all you need is a bit extract and it probably wont use a lot of logic (you'll need some to do the hex display decode). 

State machines are only required when you need to control dataflow over time - so not appropriate here. 

 

For this, all you need is something like this: 

 

case av_ip(31 downto 24) is when x"00" => seven_seg <= x"80"; when x"01" => seven_seg <= x"F1"; --etc  

 

This would be inside a PROCESS, as it is processes that get converted to logic. Procedures and functions must be called from a process, so why not put the code in a process. 

 

You really MUST learn about digital logic, otherwise it's very easy to write code that either creates a really really bad circuit, or just will not compile at all. You MUST start from digital basics.
0 Kudos
Altera_Forum
Honored Contributor II
2,256 Views

I will convert the package procedure into a process. Actually, for the more complicated things I'm trying to work with state machines. I understood that digital logic is absolutely essential. For other beginners projects, actually I tried to work this way. I'll keep on learning digital logic, but better try to apply it in practice, for sure! Thank you very much!

0 Kudos
Reply