shaiko
Advanced Member level 5
- Joined
- Aug 20, 2011
- Messages
- 2,644
- Helped
- 303
- Reputation
- 608
- Reaction score
- 297
- Trophy points
- 1,363
- Activity points
- 18,302
result <= some_data [COLOR="#FF0000"]rol[/COLOR] number_of_shifts ;
There is a thread on the Xilinx forum on this subject.
http://forums.xilinx.com/t5/Synthesis/ROL-logic-operator-library/td-p/126772
I wanted to verify it was synthesizable (recalled it was). As rcingham states what your implementing is a barrel shifter, which can become very resource expensive.
"result" is defined as an "unsigned" output port to the entity.Code:result <= some_data [COLOR="#FF0000"]rol[/COLOR] number_of_shifts ;
"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 ?
But then I cannot use the "rol" operator ?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.
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.But then I cannot use the "rol" operator ?
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!
mirrored_data := data ( top downto botton ) rol ( top - botton ) ;
(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.(10454)right bound of range must be a constant
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 ;
Well,
Short simulation shows the function works well - however, Quartus synthesis yeilds latches for all the bits of the "data" variable!
Please advice.
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 ;
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
variable mirrored_data : unsigned ( data ' range ) := data ;
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 ;
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?I cannot understand the difference between assigning it before the begin and after the begin
for index in data'range loop
if (index <= top) and (index >= bottom) then
mirrored_data ( index ) := data ( top - index + bottom ) ;
end if ;
end loop ;
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?