-
Notifications
You must be signed in to change notification settings - Fork 23
/
shifter.v
executable file
·106 lines (88 loc) · 2.92 KB
/
shifter.v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
//This is shifter module used for data processing instructions and some other instructions
module bshift(instr_bit_25,imm_value, Rm, Rs, operand2, cin, c_to_alu, direct_data, use_shifter);
parameter n=32;
input [n-1:0] direct_data;
input use_shifter;
input instr_bit_25; // bit no. 25 in the instr
input [11:0] imm_value; // bits 11-0 in instr
input [n-1:0] Rm;
input [n-1:0] Rs;
output [n-1:0] operand2; // operand 2 for ALU
input cin;
output reg c_to_alu;
wire instr_bit_25;
wire [11:0] imm_value;
reg [n-1:0] in;
reg [n-1:0] out;
reg [7:0] shiftby; // no. bits to be shifted
reg [n-1:0] junk;
assign operand2 =(use_shifter==1)?out:direct_data ;
always @* begin
if (instr_bit_25) begin
// right rotate 32 bit zero extended imm_value[7:0] by 2*(top 4 bits of imm_value)
in[n-1:8] = 0;
in[7:0] = imm_value[7:0];
shiftby[0]=0;
shiftby[7:4]=4'd0;
shiftby[4:1] = imm_value[11:8];
{junk,out} = {in,in} >> shiftby[7:0];
if(shiftby[7:0]==0) c_to_alu = cin;
else c_to_alu = out[31];
end
else begin // 10 cases here.
// logical shift left by Immediate. This one is for 2 cases.
if(imm_value[6:4] == 0) begin
in = Rm;
{c_to_alu,out} = {cin ,in} << imm_value[11:7];
// C flag
end
// logical shift left by register
if(imm_value[6:4] == 3'd1) begin
in = Rm;
shiftby[7:0] = Rs[7:0];
{c_to_alu,out} = {cin,in} << shiftby[7:0];
end
// logical shift right by immediate
if(imm_value[6:4] == 3'd2) begin
in = Rm;
{out, c_to_alu} = {in,cin} >> imm_value[11:7];
end
// logical shift right by register
if(imm_value[6:4] == 3'd3) begin
in = Rm;
shiftby[7:0] = Rs[7:0];
{out, c_to_alu} = {in,cin} >> shiftby[7:0];
end
//Arithmetic shift right by immediate
if(imm_value[6:4] == 3'd4) begin
in = Rm;
//out[7] = in[7]; // preserves sign
if(in[n-1]){junk,out, c_to_alu} = {32'hFFFFFFFF,in,cin} >> imm_value[11:7];
else {out, c_to_alu} = {in,cin} >> imm_value[11:7];
end
//Arithmetic Shift Right by Register
if(imm_value[6:4] == 3'd5) begin
in = Rm;
shiftby[7:0] = Rs[7:0];
if(in[n-1]) {junk,out, c_to_alu} = {32'hFFFFFFFF,in,cin} >> shiftby[7:0];
else {out,c_to_alu} = {in,cin} >> shiftby[7:0];
end
// Rotate Right by immediate
if((imm_value[6:4] == 3'd6)&&(imm_value[11:7]!=5'd0)) begin
in = Rm;
{junk,out,c_to_alu} = {in,in,cin} >> imm_value[11:7];
end
//Rotate Right by Register
if(imm_value[6:4] == 3'd7) begin
in=Rm;
shiftby[7:0] = Rs[7:0];
{junk,out,c_to_alu} = {in,in,cin} >> shiftby[4:0]; // [4:0] because.. if input is given as 100 it is enough to shift with 4 .. i.e 100mod 32
end
// RRX
if((imm_value[6:4] == 3'd6)&&(imm_value[11:7]==5'd0)) begin
in= Rm;
{out, c_to_alu} = {cin, in};
end
end
end
endmodule