OpenCores
URL https://opencores.org/ocsvn/amber/amber/trunk

Subversion Repositories amber

[/] [amber/] [trunk/] [hw/] [vlog/] [amber25/] [a25_shifter.v] - Blame information for rev 88

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 35 csantifort
//////////////////////////////////////////////////////////////////
2
//                                                              //
3
//  Barrel Shifter for Amber 25 Core                            //
4
//                                                              //
5
//  This file is part of the Amber project                      //
6
//  http://www.opencores.org/project,amber                      //
7
//                                                              //
8
//  Description                                                 //
9
//  Provides 32-bit shifts LSL, LSR, ASR and ROR                //
10
//                                                              //
11
//  Author(s):                                                  //
12
//      - Conor Santifort, csantifort.amber@gmail.com           //
13
//                                                              //
14
//////////////////////////////////////////////////////////////////
15
//                                                              //
16
// Copyright (C) 2011 Authors and OPENCORES.ORG                 //
17
//                                                              //
18
// This source file may be used and distributed without         //
19
// restriction provided that this copyright statement is not    //
20
// removed from the file and that any derivative work contains  //
21
// the original copyright notice and the associated disclaimer. //
22
//                                                              //
23
// This source file is free software; you can redistribute it   //
24
// and/or modify it under the terms of the GNU Lesser General   //
25
// Public License as published by the Free Software Foundation; //
26
// either version 2.1 of the License, or (at your option) any   //
27
// later version.                                               //
28
//                                                              //
29
// This source is distributed in the hope that it will be       //
30
// useful, but WITHOUT ANY WARRANTY; without even the implied   //
31
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
32
// PURPOSE.  See the GNU Lesser General Public License for more //
33
// details.                                                     //
34
//                                                              //
35
// You should have received a copy of the GNU Lesser General    //
36
// Public License along with this source; if not, download it   //
37
// from http://www.opencores.org/lgpl.shtml                     //
38
//                                                              //
39
//////////////////////////////////////////////////////////////////
40
 
41
 
42
module a25_shifter #(
43
parameter FULL_BARREL = 1
44
)(
45
 
46
input       [31:0]          i_in,
47
input                       i_carry_in,
48
input       [7:0]           i_shift_amount,     // uses 8 LSBs of Rs, or a 5 bit immediate constant
49
input                       i_shift_imm_zero,   // high when immediate shift value of zero selected
50
input       [1:0]           i_function,
51
 
52
output      [31:0]          o_out,
53
output                      o_carry_out
54
 
55
);
56
 
57 82 csantifort
`include "a25_localparams.vh"
58 35 csantifort
 
59
  // MSB is carry out
60
wire [32:0] lsl_out;
61
wire [32:0] lsr_out;
62
wire [32:0] asr_out;
63
wire [32:0] ror_out;
64
 
65
 
66
// Logical shift right zero is redundant as it is the same as logical shift left zero, so
67
// the assembler will convert LSR #0 (and ASR #0 and ROR #0) into LSL #0, and allow
68
// lsr #32 to be specified.
69
 
70
// lsl #0 is a special case, where the shifter carry out is the old value of the status flags
71
// C flag. The contents of Rm are used directly as the second operand.
72
 
73
generate
74
if (FULL_BARREL == 1) begin : full_lsl
75
 
76
    assign lsl_out = i_shift_imm_zero         ? {i_carry_in, i_in              } :  // fall through case 
77
 
78
                     i_shift_amount == 8'd 0  ? {i_carry_in, i_in              } :  // fall through case
79
                     i_shift_amount == 8'd 1  ? {i_in[31],   i_in[30: 0],  1'd0} :
80
                     i_shift_amount == 8'd 2  ? {i_in[30],   i_in[29: 0],  2'd0} :
81
                     i_shift_amount == 8'd 3  ? {i_in[29],   i_in[28: 0],  3'd0} :
82
                     i_shift_amount == 8'd 4  ? {i_in[28],   i_in[27: 0],  4'd0} :
83
                     i_shift_amount == 8'd 5  ? {i_in[27],   i_in[26: 0],  5'd0} :
84
                     i_shift_amount == 8'd 6  ? {i_in[26],   i_in[25: 0],  6'd0} :
85
                     i_shift_amount == 8'd 7  ? {i_in[25],   i_in[24: 0],  7'd0} :
86
                     i_shift_amount == 8'd 8  ? {i_in[24],   i_in[23: 0],  8'd0} :
87
                     i_shift_amount == 8'd 9  ? {i_in[23],   i_in[22: 0],  9'd0} :
88
                     i_shift_amount == 8'd10  ? {i_in[22],   i_in[21: 0], 10'd0} :
89
                     i_shift_amount == 8'd11  ? {i_in[21],   i_in[20: 0], 11'd0} :
90
 
91
                     i_shift_amount == 8'd12  ? {i_in[20],   i_in[19: 0], 12'd0} :
92
                     i_shift_amount == 8'd13  ? {i_in[19],   i_in[18: 0], 13'd0} :
93
                     i_shift_amount == 8'd14  ? {i_in[18],   i_in[17: 0], 14'd0} :
94
                     i_shift_amount == 8'd15  ? {i_in[17],   i_in[16: 0], 15'd0} :
95
                     i_shift_amount == 8'd16  ? {i_in[16],   i_in[15: 0], 16'd0} :
96
                     i_shift_amount == 8'd17  ? {i_in[15],   i_in[14: 0], 17'd0} :
97
                     i_shift_amount == 8'd18  ? {i_in[14],   i_in[13: 0], 18'd0} :
98
                     i_shift_amount == 8'd19  ? {i_in[13],   i_in[12: 0], 19'd0} :
99
                     i_shift_amount == 8'd20  ? {i_in[12],   i_in[11: 0], 20'd0} :
100
                     i_shift_amount == 8'd21  ? {i_in[11],   i_in[10: 0], 21'd0} :
101
 
102
                     i_shift_amount == 8'd22  ? {i_in[10],   i_in[ 9: 0], 22'd0} :
103
                     i_shift_amount == 8'd23  ? {i_in[ 9],   i_in[ 8: 0], 23'd0} :
104
                     i_shift_amount == 8'd24  ? {i_in[ 8],   i_in[ 7: 0], 24'd0} :
105
                     i_shift_amount == 8'd25  ? {i_in[ 7],   i_in[ 6: 0], 25'd0} :
106
                     i_shift_amount == 8'd26  ? {i_in[ 6],   i_in[ 5: 0], 26'd0} :
107
                     i_shift_amount == 8'd27  ? {i_in[ 5],   i_in[ 4: 0], 27'd0} :
108
                     i_shift_amount == 8'd28  ? {i_in[ 4],   i_in[ 3: 0], 28'd0} :
109
                     i_shift_amount == 8'd29  ? {i_in[ 3],   i_in[ 2: 0], 29'd0} :
110
                     i_shift_amount == 8'd30  ? {i_in[ 2],   i_in[ 1: 0], 30'd0} :
111
                     i_shift_amount == 8'd31  ? {i_in[ 1],   i_in[ 0: 0], 31'd0} :
112
                     i_shift_amount == 8'd32  ? {i_in[ 0],   32'd0             } :  // 32
113
                                                {1'd0,       32'd0             } ;  // > 32
114
 
115
end
116
else begin : quick_lsl
117
 
118
    // only gives the correct result if the shift value is < 4
119
    assign lsl_out = i_shift_imm_zero        ? {i_carry_in, i_in              } : // fall through case 
120
                     i_shift_amount == 2'd0  ? {i_carry_in, i_in              } : // fall through case
121
                     i_shift_amount == 2'd1  ? {i_in[31],   i_in[30: 0],  1'd0} :
122
                     i_shift_amount == 2'd2  ? {i_in[30],   i_in[29: 0],  2'd0} :
123
                                               {i_in[29],   i_in[28: 0],  3'd0} ; // 3
124
 
125
end
126
endgenerate
127
 
128
 
129
// The form of the shift field which might be expected to correspond to LSR #0 is used
130
// to encode LSR #32, which has a zero result with bit 31 of Rm as the carry output. 
131
generate
132
if (FULL_BARREL == 1) begin : full_lsr
133
 
134
                                               // carry out, < -------- out ---------->
135
    assign lsr_out = i_shift_imm_zero         ? {i_in[31], 32'd0             } :
136
                     i_shift_amount == 8'd 0  ? {i_carry_in, i_in            } :  // fall through case
137
                     i_shift_amount == 8'd 1  ? {i_in[ 0],  1'd0, i_in[31: 1]} :
138
                     i_shift_amount == 8'd 2  ? {i_in[ 1],  2'd0, i_in[31: 2]} :
139
                     i_shift_amount == 8'd 3  ? {i_in[ 2],  3'd0, i_in[31: 3]} :
140
                     i_shift_amount == 8'd 4  ? {i_in[ 3],  4'd0, i_in[31: 4]} :
141
                     i_shift_amount == 8'd 5  ? {i_in[ 4],  5'd0, i_in[31: 5]} :
142
                     i_shift_amount == 8'd 6  ? {i_in[ 5],  6'd0, i_in[31: 6]} :
143
                     i_shift_amount == 8'd 7  ? {i_in[ 6],  7'd0, i_in[31: 7]} :
144
                     i_shift_amount == 8'd 8  ? {i_in[ 7],  8'd0, i_in[31: 8]} :
145
                     i_shift_amount == 8'd 9  ? {i_in[ 8],  9'd0, i_in[31: 9]} :
146
 
147
                     i_shift_amount == 8'd10  ? {i_in[ 9], 10'd0, i_in[31:10]} :
148
                     i_shift_amount == 8'd11  ? {i_in[10], 11'd0, i_in[31:11]} :
149
                     i_shift_amount == 8'd12  ? {i_in[11], 12'd0, i_in[31:12]} :
150
                     i_shift_amount == 8'd13  ? {i_in[12], 13'd0, i_in[31:13]} :
151
                     i_shift_amount == 8'd14  ? {i_in[13], 14'd0, i_in[31:14]} :
152
                     i_shift_amount == 8'd15  ? {i_in[14], 15'd0, i_in[31:15]} :
153
                     i_shift_amount == 8'd16  ? {i_in[15], 16'd0, i_in[31:16]} :
154
                     i_shift_amount == 8'd17  ? {i_in[16], 17'd0, i_in[31:17]} :
155
                     i_shift_amount == 8'd18  ? {i_in[17], 18'd0, i_in[31:18]} :
156
                     i_shift_amount == 8'd19  ? {i_in[18], 19'd0, i_in[31:19]} :
157
 
158
                     i_shift_amount == 8'd20  ? {i_in[19], 20'd0, i_in[31:20]} :
159
                     i_shift_amount == 8'd21  ? {i_in[20], 21'd0, i_in[31:21]} :
160
                     i_shift_amount == 8'd22  ? {i_in[21], 22'd0, i_in[31:22]} :
161
                     i_shift_amount == 8'd23  ? {i_in[22], 23'd0, i_in[31:23]} :
162
                     i_shift_amount == 8'd24  ? {i_in[23], 24'd0, i_in[31:24]} :
163
                     i_shift_amount == 8'd25  ? {i_in[24], 25'd0, i_in[31:25]} :
164
                     i_shift_amount == 8'd26  ? {i_in[25], 26'd0, i_in[31:26]} :
165
                     i_shift_amount == 8'd27  ? {i_in[26], 27'd0, i_in[31:27]} :
166
                     i_shift_amount == 8'd28  ? {i_in[27], 28'd0, i_in[31:28]} :
167
                     i_shift_amount == 8'd29  ? {i_in[28], 29'd0, i_in[31:29]} :
168
 
169
                     i_shift_amount == 8'd30  ? {i_in[29], 30'd0, i_in[31:30]} :
170
                     i_shift_amount == 8'd31  ? {i_in[30], 31'd0, i_in[31   ]} :
171
                     i_shift_amount == 8'd32  ? {i_in[31], 32'd0             } :
172
                                                {1'd0,     32'd0             } ;  // > 32
173
 
174
end
175
else begin : quick_lsr
176
 
177
    // only gives the correct result if the shift value is < 4
178
    assign lsr_out = i_shift_imm_zero             ? {i_in[31], 32'd0             } :
179
                     i_shift_amount[1:0] == 2'd0  ? {i_carry_in, i_in            } :  // fall through case
180
                     i_shift_amount[1:0] == 2'd1  ? {i_in[ 0],  1'd0, i_in[31: 1]} :
181
                     i_shift_amount[1:0] == 2'd2  ? {i_in[ 1],  2'd0, i_in[31: 2]} :
182
                                                    {i_in[ 2],  3'd0, i_in[31: 3]} ; // 3
183
 
184
end
185
endgenerate
186
 
187
// The form of the shift field which might be expected to give ASR #0 is used to encode
188
// ASR #32. Bit 31 of Rm is again used as the carry output, and each bit of operand 2 is
189
// also equal to bit 31 of Rm. The result is therefore all ones or all zeros, according to
190
// the value of bit 31 of Rm.
191
 
192
generate
193
if (FULL_BARREL == 1) begin : full_asr
194
 
195
                                              // carry out, < -------- out ---------->
196
    assign asr_out = i_shift_imm_zero         ? {i_in[31], {32{i_in[31]}}             } :
197
                     i_shift_amount == 8'd 0  ? {i_carry_in, i_in                     } :  // fall through case
198
                     i_shift_amount == 8'd 1  ? {i_in[ 0], { 2{i_in[31]}}, i_in[30: 1]} :
199
                     i_shift_amount == 8'd 2  ? {i_in[ 1], { 3{i_in[31]}}, i_in[30: 2]} :
200
                     i_shift_amount == 8'd 3  ? {i_in[ 2], { 4{i_in[31]}}, i_in[30: 3]} :
201
                     i_shift_amount == 8'd 4  ? {i_in[ 3], { 5{i_in[31]}}, i_in[30: 4]} :
202
                     i_shift_amount == 8'd 5  ? {i_in[ 4], { 6{i_in[31]}}, i_in[30: 5]} :
203
                     i_shift_amount == 8'd 6  ? {i_in[ 5], { 7{i_in[31]}}, i_in[30: 6]} :
204
                     i_shift_amount == 8'd 7  ? {i_in[ 6], { 8{i_in[31]}}, i_in[30: 7]} :
205
                     i_shift_amount == 8'd 8  ? {i_in[ 7], { 9{i_in[31]}}, i_in[30: 8]} :
206
                     i_shift_amount == 8'd 9  ? {i_in[ 8], {10{i_in[31]}}, i_in[30: 9]} :
207
 
208
                     i_shift_amount == 8'd10  ? {i_in[ 9], {11{i_in[31]}}, i_in[30:10]} :
209
                     i_shift_amount == 8'd11  ? {i_in[10], {12{i_in[31]}}, i_in[30:11]} :
210
                     i_shift_amount == 8'd12  ? {i_in[11], {13{i_in[31]}}, i_in[30:12]} :
211
                     i_shift_amount == 8'd13  ? {i_in[12], {14{i_in[31]}}, i_in[30:13]} :
212
                     i_shift_amount == 8'd14  ? {i_in[13], {15{i_in[31]}}, i_in[30:14]} :
213
                     i_shift_amount == 8'd15  ? {i_in[14], {16{i_in[31]}}, i_in[30:15]} :
214
                     i_shift_amount == 8'd16  ? {i_in[15], {17{i_in[31]}}, i_in[30:16]} :
215
                     i_shift_amount == 8'd17  ? {i_in[16], {18{i_in[31]}}, i_in[30:17]} :
216
                     i_shift_amount == 8'd18  ? {i_in[17], {19{i_in[31]}}, i_in[30:18]} :
217
                     i_shift_amount == 8'd19  ? {i_in[18], {20{i_in[31]}}, i_in[30:19]} :
218
 
219
                     i_shift_amount == 8'd20  ? {i_in[19], {21{i_in[31]}}, i_in[30:20]} :
220
                     i_shift_amount == 8'd21  ? {i_in[20], {22{i_in[31]}}, i_in[30:21]} :
221
                     i_shift_amount == 8'd22  ? {i_in[21], {23{i_in[31]}}, i_in[30:22]} :
222
                     i_shift_amount == 8'd23  ? {i_in[22], {24{i_in[31]}}, i_in[30:23]} :
223
                     i_shift_amount == 8'd24  ? {i_in[23], {25{i_in[31]}}, i_in[30:24]} :
224
                     i_shift_amount == 8'd25  ? {i_in[24], {26{i_in[31]}}, i_in[30:25]} :
225
                     i_shift_amount == 8'd26  ? {i_in[25], {27{i_in[31]}}, i_in[30:26]} :
226
                     i_shift_amount == 8'd27  ? {i_in[26], {28{i_in[31]}}, i_in[30:27]} :
227
                     i_shift_amount == 8'd28  ? {i_in[27], {29{i_in[31]}}, i_in[30:28]} :
228
                     i_shift_amount == 8'd29  ? {i_in[28], {30{i_in[31]}}, i_in[30:29]} :
229
                     i_shift_amount == 8'd30  ? {i_in[29], {31{i_in[31]}}, i_in[30   ]} :
230
                     i_shift_amount == 8'd31  ? {i_in[30], {32{i_in[31]}}             } :
231
                                                {i_in[31], {32{i_in[31]}}             } ; // >= 32
232
 
233
end
234
else begin : quick_asr
235
 
236
    // only gives the correct result if the shift value is < 4
237
    assign asr_out = i_shift_imm_zero             ? {i_in[31], {32{i_in[31]}}             } :
238
                     i_shift_amount[1:0] == 2'd0  ? {i_carry_in, i_in                     } :  // fall through case
239
                     i_shift_amount[1:0] == 2'd1  ? {i_in[ 0], { 2{i_in[31]}}, i_in[30: 1]} :
240
                     i_shift_amount[1:0] == 2'd2  ? {i_in[ 1], { 3{i_in[31]}}, i_in[30: 2]} :
241
                                                    {i_in[ 2], { 4{i_in[31]}}, i_in[30: 3]} ; // 3
242
 
243
end
244
endgenerate
245
 
246
 
247
generate
248
if (FULL_BARREL == 1) begin : full_ror
249
 
250
                                                  // carry out, < ------- out --------->
251
    assign ror_out = i_shift_imm_zero              ? {i_in[ 0], i_carry_in,  i_in[31: 1]} :  // RXR, (ROR w/ imm 0)
252
 
253
                     i_shift_amount[7:0] == 8'd 0  ? {i_carry_in, i_in                  } :  // fall through case
254
 
255
                     i_shift_amount[4:0] == 5'd 0  ? {i_in[31], i_in                    } :  // Rs > 31
256
                     i_shift_amount[4:0] == 5'd 1  ? {i_in[ 0], i_in[    0], i_in[31: 1]} :
257
                     i_shift_amount[4:0] == 5'd 2  ? {i_in[ 1], i_in[ 1: 0], i_in[31: 2]} :
258
                     i_shift_amount[4:0] == 5'd 3  ? {i_in[ 2], i_in[ 2: 0], i_in[31: 3]} :
259
                     i_shift_amount[4:0] == 5'd 4  ? {i_in[ 3], i_in[ 3: 0], i_in[31: 4]} :
260
                     i_shift_amount[4:0] == 5'd 5  ? {i_in[ 4], i_in[ 4: 0], i_in[31: 5]} :
261
                     i_shift_amount[4:0] == 5'd 6  ? {i_in[ 5], i_in[ 5: 0], i_in[31: 6]} :
262
                     i_shift_amount[4:0] == 5'd 7  ? {i_in[ 6], i_in[ 6: 0], i_in[31: 7]} :
263
                     i_shift_amount[4:0] == 5'd 8  ? {i_in[ 7], i_in[ 7: 0], i_in[31: 8]} :
264
                     i_shift_amount[4:0] == 5'd 9  ? {i_in[ 8], i_in[ 8: 0], i_in[31: 9]} :
265
 
266
                     i_shift_amount[4:0] == 5'd10  ? {i_in[ 9], i_in[ 9: 0], i_in[31:10]} :
267
                     i_shift_amount[4:0] == 5'd11  ? {i_in[10], i_in[10: 0], i_in[31:11]} :
268
                     i_shift_amount[4:0] == 5'd12  ? {i_in[11], i_in[11: 0], i_in[31:12]} :
269
                     i_shift_amount[4:0] == 5'd13  ? {i_in[12], i_in[12: 0], i_in[31:13]} :
270
                     i_shift_amount[4:0] == 5'd14  ? {i_in[13], i_in[13: 0], i_in[31:14]} :
271
                     i_shift_amount[4:0] == 5'd15  ? {i_in[14], i_in[14: 0], i_in[31:15]} :
272
                     i_shift_amount[4:0] == 5'd16  ? {i_in[15], i_in[15: 0], i_in[31:16]} :
273
                     i_shift_amount[4:0] == 5'd17  ? {i_in[16], i_in[16: 0], i_in[31:17]} :
274
                     i_shift_amount[4:0] == 5'd18  ? {i_in[17], i_in[17: 0], i_in[31:18]} :
275
                     i_shift_amount[4:0] == 5'd19  ? {i_in[18], i_in[18: 0], i_in[31:19]} :
276
 
277
                     i_shift_amount[4:0] == 5'd20  ? {i_in[19], i_in[19: 0], i_in[31:20]} :
278
                     i_shift_amount[4:0] == 5'd21  ? {i_in[20], i_in[20: 0], i_in[31:21]} :
279
                     i_shift_amount[4:0] == 5'd22  ? {i_in[21], i_in[21: 0], i_in[31:22]} :
280
                     i_shift_amount[4:0] == 5'd23  ? {i_in[22], i_in[22: 0], i_in[31:23]} :
281
                     i_shift_amount[4:0] == 5'd24  ? {i_in[23], i_in[23: 0], i_in[31:24]} :
282
                     i_shift_amount[4:0] == 5'd25  ? {i_in[24], i_in[24: 0], i_in[31:25]} :
283
                     i_shift_amount[4:0] == 5'd26  ? {i_in[25], i_in[25: 0], i_in[31:26]} :
284
                     i_shift_amount[4:0] == 5'd27  ? {i_in[26], i_in[26: 0], i_in[31:27]} :
285
                     i_shift_amount[4:0] == 5'd28  ? {i_in[27], i_in[27: 0], i_in[31:28]} :
286
                     i_shift_amount[4:0] == 5'd29  ? {i_in[28], i_in[28: 0], i_in[31:29]} :
287
 
288
                     i_shift_amount[4:0] == 5'd30  ? {i_in[29], i_in[29: 0], i_in[31:30]} :
289
                                                     {i_in[30], i_in[30: 0], i_in[31:31]} ;
290
 
291
end
292
else begin : quick_ror
293
    // only gives the correct result if the shift value is < 4
294
    assign ror_out = i_shift_imm_zero             ? {i_in[ 0], i_carry_in,  i_in[31: 1]} :  // RXR, (ROR w/ imm 0)
295
                     i_shift_amount[1:0] == 2'd0  ? {i_carry_in, i_in                  } :  // fall through case
296
                     i_shift_amount[1:0] == 2'd1  ? {i_in[ 0], i_in[    0], i_in[31: 1]} :
297
                     i_shift_amount[1:0] == 2'd2  ? {i_in[ 1], i_in[ 1: 0], i_in[31: 2]} :
298
                                                    {i_in[ 2], i_in[ 2: 0], i_in[31: 3]} ; // 3
299
 
300
end
301
endgenerate
302
 
303
assign {o_carry_out, o_out} = i_function == LSL ? lsl_out :
304
                              i_function == LSR ? lsr_out :
305
                              i_function == ASR ? asr_out :
306
                                                  ror_out ;
307
 
308
endmodule
309
 
310
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.