| |
| // test case taken from amber23 Verilog code |
| module a23_barrel_shift_fpga_rotate(i_in, direction, shift_amount, rot_prod); |
| |
| input [31:0] i_in; |
| input direction; |
| input [4:0] shift_amount; |
| output [31:0] rot_prod; |
| |
| // Generic rotate. Theoretical cost: 32x5 4-to-1 LUTs. |
| // Practically a bit higher due to high fanout of "direction". |
| generate |
| genvar i, j; |
| for (i = 0; i < 5; i = i + 1) |
| begin : netgen |
| wire [31:0] in; |
| reg [31:0] out; |
| for (j = 0; j < 32; j = j + 1) |
| begin : net |
| always @* |
| out[j] = in[j] & (~shift_amount[i] ^ direction) | |
| in[wrap(j, i)] & (shift_amount[i] ^ direction); |
| end |
| end |
| |
| // Order is reverted with respect to volatile shift_amount[0] |
| assign netgen[4].in = i_in; |
| for (i = 1; i < 5; i = i + 1) |
| begin : router |
| assign netgen[i-1].in = netgen[i].out; |
| end |
| endgenerate |
| |
| // Aliasing |
| assign rot_prod = netgen[0].out; |
| |
| function [4:0] wrap; |
| input integer pos; |
| input integer level; |
| integer out; |
| begin |
| out = pos - (1 << level); |
| wrap = out[4:0]; |
| end |
| endfunction |
| |
| endmodule |
| |