Implementing a variable-width barrel rotator?

A

alan

Guest
I need to implement a (synthesizable) variable-width rotate.

My first instinct is to do something like:

module barrel_rotate
#(parameter
width_sel = 3,
//localparam
width = 1 << width_sel)
(
input [width-1:0] in,
input [width_sel-1:0] shift,
output [width-1:0] out);

wire [width*2-1:0] internal = {in, in};
wire [width-1:0] out = internal >> shift;

endmodule

Is this correct? Simulation suggests it works, but is it
synthesizable?

Or is my gut feeling - that my client's synthesizer is what I should
be asking anyway - correct? In short, for new enough synthesizers, it
will be synthesizable, but for old synthesizers it won't?

And then there's this implementation:
http://groups.google.com/group/comp.lang.verilog/browse_thread/thread/45e1696a42e6e856/09b7e32f0ce9e982?lnk=gst&q=barrel+shifter&rnum=2#09b7e32f0ce9e982
It's for an arithmetic shifter, but the pattern of how to transform it
to a logical shifter is obvious enough.

If my code above won't synthesize on my client's synthesizer, how do I
go about transforming it to the form in the post I linked above, while
retaining the variable-width parameter? Generate statements? Perl,
if my client's synth tool is that sucky???
 
alan wrote:
I need to implement a (synthesizable) variable-width rotate.

My first instinct is to do something like:

module barrel_rotate
#(parameter
width_sel = 3,
//localparam
width = 1 << width_sel)
(
input [width-1:0] in,
input [width_sel-1:0] shift,
output [width-1:0] out);

wire [width*2-1:0] internal = {in, in};
wire [width-1:0] out = internal >> shift;

endmodule

Is this correct? Simulation suggests it works, but is it
synthesizable?
I would expect it to work in tools that support Verilog-2001.

It does have the issue that the instantiation could override the
value of width, independent of width_sel. As your commented-
out line indicates, you cannot declare localparams in the
ANSI-C-style module header. If you want to avoid overrides
of width, there are a couple of things you could do.

You could revert to a Verilog-1995 style module header. This
then allows declaring a localparam in the module body before
the declarations of the ports.

Or you could replace width with (1 << width_sel) at both places
it is used in the module header. It is a little ugly, but should
work.
Then you can define width as a localparam in the module body,
for use in the remaining references.
 
alan wrote:
I need to implement a (synthesizable) variable-width rotate.
Here's how I do a generic width.
It's a shift, not a rotate.

http://home.comcast.net/~mike_treseler/barrel.v
http://home.comcast.net/~mike_treseler/barrel_v.pdf

-- Mike Treseler
 
On Apr 17, 2:54 am, s...@cadence.com wrote:
alan wrote:
I need to implement a (synthesizable) variable-width rotate.

My first instinct is to do something like:

module barrel_rotate
#(parameter
width_sel = 3,
//localparam
width = 1 << width_sel)
(
input [width-1:0] in,
input [width_sel-1:0] shift,
output [width-1:0] out);

wire [width*2-1:0] internal = {in, in};
wire [width-1:0] out = internal >> shift;

endmodule

Is this correct? Simulation suggests it works, but is it
synthesizable?

I would expect it to work in tools that support Verilog-2001.

It does have the issue that the instantiation could override the
value of width, independent of width_sel. As your commented-
out line indicates, you cannot declare localparams in the
ANSI-C-style module header.
LOL in my code, I do:
//localparam - Do not use these in module instantiation or I
will hire someone to kill you
I'll probably remove the "or I will hire..." part before releasing it
to the client, though.

If you want to avoid overrides
of width, there are a couple of things you could do.

You could revert to a Verilog-1995 style module header. This
then allows declaring a localparam in the module body before
the declarations of the ports.
Oof.
In my draft guidelines I recommended doing something like:
module foo(
input /**/ sig,
output /**/ out,
input clk,
input reset_n);

parameter width_sel = 5;
localparam width = 1 << width_sel;

wire [bar-1:0] sig;
....
....
reg [bar-1:0] out;

Still, I prefer the #(parameter ) syntax... too bad it won't allow
localparams.

Anyway, just in the worst case: suppose my client has a really, really
bad synthesizer (and I'm forced to port all of my code back to V-95,
and the synthesizer can't figure out how to synthesize foo << bar).
How do I go about describing a synthesizable barrel shifter? Perl?
Threaten to resign unless they get a better synthesis tool (I'm
arrogant enough to think this will actually work)?
 
On 16 Apr 2007 18:02:36 -0700, alan <almkglor@gmail.com> wrote:
On Apr 17, 2:54 am, s...@cadence.com wrote:
alan wrote:
I need to implement a (synthesizable) variable-width rotate.

My first instinct is to do something like:

module barrel_rotate
#(parameter
width_sel = 3,
//localparam
width = 1 << width_sel)
(
input [width-1:0] in,
input [width_sel-1:0] shift,
output [width-1:0] out);

wire [width*2-1:0] internal = {in, in};
wire [width-1:0] out = internal >> shift;

endmodule

Is this correct? Simulation suggests it works, but is it
synthesizable?


Anyway, just in the worst case: suppose my client has a really, really
bad synthesizer (and I'm forced to port all of my code back to V-95,
and the synthesizer can't figure out how to synthesize foo << bar).
How do I go about describing a synthesizable barrel shifter? Perl?
Threaten to resign unless they get a better synthesis tool (I'm
arrogant enough to think this will actually work)?
case(shift)
3'h0: out = in;
3'h1: out = {1'b0, in[7:1]};
3'h2: out = {2'b0, in[7:2]};
....
 

Welcome to EDABoard.com

Sponsor

Back
Top