Is the following shift operation synthesizable

Status
Not open for further replies.

shaiko

Advanced Member level 5
Joined
Aug 20, 2011
Messages
2,644
Helped
303
Reputation
608
Reaction score
297
Trophy points
1,363
Visit site
Activity points
18,302
Code:
result <= some_data [COLOR="#FF0000"]rol[/COLOR] number_of_shifts ;
"result" is defined as an "unsigned" output port to the entity.
"some_data" is defined as an "unsigned" input port to the entity.
"number_of_shifts" is defined as an "integer" input port to the entity and serves as a control signal setting the required amout of shifts.

Will it synthesize ?
 

Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating

A logic expense that can be traded for with a latency expense by pipelining. If you can tolerate a latency of log2(max_possible_shift_value) clock cycles delay then the barrel shifter can be implemented with a cluster of 2-> 1 muxes (or 4->1 muxes) feeding a cluster of flops.

Kevin Jennings
 
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating

Another example where you could easily compile it and look for yourself.
 

But then I cannot use the "rol" operator ?
 

But then I cannot use the "rol" operator ?
You can't use 'rol' (or 'rotate_left' from ieee.numeric_std) if you want to pipeline the operation. Those functions and operators are defined to compute a result from inputs strictly as combinatorial logic. Depending on how you're using the result of the barrel shift you might have to have them computed and available on the same clock cycle in which case 'rol' should be synthesizable unless the tool doesn't yet support for some reason (in which case complain to the tool vendor). My point was that sometimes you can live with waiting for a few clock cycles of latency in which case the barrel shift operation can be completed with less logic and run at a much higher clock frequency. If you're trying to create a 32 bit wide barrel shifter with 'rol', each of those 32 bits will synthesize to a 32-->1 mux controlled by the five bits that select the amount of shifting. In an FPGA with 4-5 logic cell inputs, that will synthesize to something with several levels of logic.

Kevin Jennings
 
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
Thanks for the help K-J.

Another question:
I want to write a synthesizable function that receives input data, together with 2 bit positions (a total of 3 arguments)
The function shall "mirror" the bits within the boundries set by the 2 position bits.
I'll elaborate - with 3 examples:

Suppose the input data is - "00101111"
and the position bits are 5 and 0 - applying the function will yeild: "00111101"
Suppose the input data is - "00100111"
and the position bits are 2 and 0 - applying the function will yeild have no effect because the mirror image of bits "111" (2 downto 0) is the same as the original.
Suppose the input data is - "01100011"
and the position bits are 7 and 0 - applying the function will yeild a complete mirror image yeilding: "11000110".

Any help is much appriciated.
 

I would expect that you write a behavioral description of the intended operation.

You didn't mention clocked operation, so I assume you want completely combinational logic, referring to a larger number of multiplexers, as discussed for the shift without optional mirror operation. I don't see a particular problem invoved with the question.
 
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
I indeed want it to be a complete combinatorial description.
I thougt about something like this:
Code:
function mirror ( data : unsigned ; top : integer ; botton : integer ) return unsigned is
variable mirrored_data : unsigned ( data ' range ) ;
begin
   mirrored_data := data ( top downto botton ) rol ( top - botton ) ;
   return mirrored_data ;
end function mirror ;
But I don't think it'd synthesize. Please help me correct it to a synthesizable form.
 

Why not try and synthesise it first!

I tried it - Quartus fails it in this line:
Code:
mirrored_data := data ( top downto botton ) rol ( top - botton ) ;
with the following (too familiar) error message:
(10454)right bound of range must be a constant

- - - Updated - - -

Do you think I did something wrong?
Do you think it should synthesize?
 

(10454)right bound of range must be a constant
This is a requirement of the VHDL specification, I think. As discussed in other threads, there are ways to implement variable array bounds, particularly using iterations. It's just VHDL craftsmanship, I think.
 
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
Well,
This is the product my VHDL craftsmanship's:
Code:
function mirror ( data : unsigned ; top : integer ; bottom : integer ) return unsigned is
variable mirrored_data : unsigned ( data ' range ) := data ;
variable temp : unsigned ( data ' range ) := data ;	
begin
   for index in 0 to data ' length - 1
   loop
      if index <= top and index >= bottom  then
         temp ( index ) := data ( top - index ) ;
         mirrored_data ( top - index ) := data ( index ) ;
         mirrored_data ( index ) := temp ( index ) ;
      end if ;
   end loop ;	
   return mirrored_data ;
end function mirror ;
Short simulation shows the function works well - however, Quartus synthesis yeilds latches for all the bits of the "data" variable!
Please advice.
 

Well,
Short simulation shows the function works well - however, Quartus synthesis yeilds latches for all the bits of the "data" variable!
Please advice.

The latches are because you are not assigning when the following 'if' statement is not true

if index <= top and index >= bottom then
...
end if;

Kevin
 
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
Changed it as follows:
Code:
function mirror ( data : unsigned ; top : integer ; bottom : integer ) return unsigned is
variable mirrored_data : unsigned ( data ' range ) := data ;
variable temp : unsigned ( data ' range ) := data ;	
begin
	for index in 0 to data ' length - 1
	loop
		if index <= top and index >= bottom  then
			temp ( index ) := data ( top - index ) ;
			mirrored_data ( top - index ) := data ( index ) ;
			mirrored_data ( index ) := temp ( index ) ;
		else
			mirrored_data ( top - index ) := '0' ;
			mirrored_data ( index ) := '0' ;
			temp ( index ) := '0' ;			
		end if ;
	end loop ;	
	return mirrored_data ;
end function mirror ;
and applied the function like this :
Code:
y <= mirror ( x , a , b ) ; 
-- y is defined as an unsigned output port
-- x is defined as an unsigned input port
-- a is defined as an integer input port
-- b is defined as an integer input port
The latches still appear.
What did I do wrong? How should I rewrite the function?
 

There seems to be a problem with the initialization statement. It causes output latch inference if the the output isn't registered.
Code:
variable mirrored_data : unsigned ( data ' range ) := data ;

Apart from this problem, the shown code doesn't correspond to the functional specification, I think. I suggest the below code:
Code:
function mirror ( data : unsigned ; top : integer ; bottom : integer ) return unsigned is
variable mirrored_data : unsigned ( data ' range );
begin
  mirrored_data := data;
  for index in 0 to data ' length - 1
  loop
    if (index <= top) and (index >= bottom) then
      mirrored_data ( index ) := data ( top - index + bottom ) ;
    end if ;
  end loop ;	
  return mirrored_data ;
end function mirror ;
 
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
Great, the latches are gone!
But even though it works, I cannot understand the difference between assigning it before the begin and after the begin (as you suggested)...
 

I cannot understand the difference between assigning it before the begin and after the begin
I assume a Quartus bug. According to my understanding of the VHDL specification, there's no principle difference between an initial value expression in the variable declaration and an assignment at the function begin. Or does anyone know better?
 
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
Can you please help me rewrite the code with the range attribute instead of length - so the function would be able to handle any vectors (not just "x downto 0")
 
Last edited:

You can use either range or low and high attributes. Both assume, that top and bottom are referring to the actual index rather than the relative bit position.
Code:
for index in data'range loop
  if (index <= top) and (index >= bottom) then
    mirrored_data ( index ) := data ( top - index + bottom ) ;
  end if ;
end loop ;

P.S.: I thought, there should be an offset data'low added to the expression, but that's apparently wrong. You should be able to figure it out.
 
Last edited:
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…