Imported Upstream version 3.0
[debian/gnuradio] / usrp / fpga / toplevel / mrfm / shifter.v
1 // -*- verilog -*-
2 //
3 //  USRP - Universal Software Radio Peripheral
4 //
5 //  Copyright (C) 2005,2006 Matt Ettus
6 //
7 //  This program is free software; you can redistribute it and/or modify
8 //  it under the terms of the GNU General Public License as published by
9 //  the Free Software Foundation; either version 2 of the License, or
10 //  (at your option) any later version.
11 //
12 //  This program is distributed in the hope that it will be useful,
13 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
14 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 //  GNU General Public License for more details.
16 //
17 //  You should have received a copy of the GNU General Public License
18 //  along with this program; if not, write to the Free Software
19 //  Foundation, Inc., 51 Franklin Street, Boston, MA  02110-1301  USA
20 //
21
22 module shifter(input wire [33:0] in, output wire [15:0] out, input wire [7:0] shift);
23    // Wish we could do  assign out = in[15+shift:shift];
24
25    reg [15:0] quotient, remainder;
26    wire [15:0] out_unclipped;
27    reg [18:0]  msbs;
28    wire        in_range;
29    
30    always @*
31      case(shift)
32        0 : quotient = in[15:0];
33        1 : quotient = in[16:1];
34        2 : quotient = in[17:2];
35        3 : quotient = in[18:3];
36        4 : quotient = in[19:4];
37        5 : quotient = in[20:5];
38        6 : quotient = in[21:6];
39        7 : quotient = in[22:7];
40        8 : quotient = in[23:8];
41        9 : quotient = in[24:9];
42        10 : quotient = in[25:10];
43        11 : quotient = in[26:11];
44        12 : quotient = in[27:12];
45        13 : quotient = in[28:13];
46        14 : quotient = in[29:14];
47        15 : quotient = in[30:15];
48        16 : quotient = in[31:16];
49        17 : quotient = in[32:17];
50        18 : quotient = in[33:18];
51        default : quotient = in[15:0];
52      endcase // case(shift)
53
54    always @*
55      case(shift)
56        0 : remainder = 16'b0;
57        1 : remainder = {in[0],15'b0};
58        2 : remainder = {in[1:0],14'b0};
59        3 : remainder = {in[2:0],13'b0};
60        4 : remainder = {in[3:0],12'b0};
61        5 : remainder = {in[4:0],11'b0};
62        6 : remainder = {in[5:0],10'b0};
63        7 : remainder = {in[6:0],9'b0};
64        8 : remainder = {in[7:0],8'b0};
65        9 : remainder = {in[8:0],7'b0};
66        10 : remainder = {in[9:0],6'b0};
67        11 : remainder = {in[10:0],5'b0};
68        12 : remainder = {in[11:0],4'b0};
69        13 : remainder = {in[12:0],3'b0};
70        14 : remainder = {in[13:0],2'b0};
71        15 : remainder = {in[14:0],1'b0};
72        16 : remainder = in[15:0];
73        17 : remainder = in[16:1];
74        18 : remainder = in[17:2];
75        default : remainder = 16'b0;
76      endcase // case(shift)
77
78    always @*
79      case(shift)
80        0 : msbs = in[33:15];
81        1 : msbs = {in[33],in[33:16]};
82        2 : msbs = {{2{in[33]}},in[33:17]};
83        3 : msbs = {{3{in[33]}},in[33:18]};
84        4 : msbs = {{4{in[33]}},in[33:19]};
85        5 : msbs = {{5{in[33]}},in[33:20]};
86        6 : msbs = {{6{in[33]}},in[33:21]};
87        7 : msbs = {{7{in[33]}},in[33:22]};
88        8 : msbs = {{8{in[33]}},in[33:23]};
89        9 : msbs = {{9{in[33]}},in[33:24]};
90        10 : msbs = {{10{in[33]}},in[33:25]};
91        11 : msbs = {{11{in[33]}},in[33:26]};
92        12 : msbs = {{12{in[33]}},in[33:27]};
93        13 : msbs = {{13{in[33]}},in[33:28]};
94        14 : msbs = {{14{in[33]}},in[33:29]};
95        15 : msbs = {{15{in[33]}},in[33:30]};
96        16 : msbs = {{16{in[33]}},in[33:31]};
97        17 : msbs = {{17{in[33]}},in[33:32]};
98        18 : msbs = {{18{in[33]}},in[33]};
99        default : msbs = in[33:15];
100      endcase // case(shift)
101
102    assign     in_range = &msbs | ~(|msbs);
103    assign     out_unclipped = quotient + (in[33] & |remainder);
104    assign     out = in_range ? out_unclipped : {in[33],{15{~in[33]}}};
105    
106 endmodule // shifter