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

Subversion Repositories thor

[/] [thor/] [trunk/] [FT64v5/] [rtl/] [common/] [FT64_AMO_alu.v] - Blame information for rev 48

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 48 robfinch
// ============================================================================
2
//        __
3
//   \\__/ o\    (C) 2018  Robert Finch, Waterloo
4
//    \  __ /    All rights reserved.
5
//     \/_//     robfinch<remove>@finitron.ca
6
//       ||
7
//
8
//      FT64_AMO_alu.v
9
//
10
// This source file is free software: you can redistribute it and/or modify 
11
// it under the terms of the GNU Lesser General Public License as published 
12
// by the Free Software Foundation, either version 3 of the License, or     
13
// (at your option) any later version.                                      
14
//                                                                          
15
// This source file is distributed in the hope that it will be useful,      
16
// but WITHOUT ANY WARRANTY; without even the implied warranty of           
17
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            
18
// GNU General Public License for more details.                             
19
//                                                                          
20
// You should have received a copy of the GNU General Public License        
21
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
22
//
23
//
24
// ALU for atomic memory operations (AMO)
25
// AMO ops have their own limited ALU since they can't wait on the usual
26
// ALU.
27
// ============================================================================
28
//
29
`include "FT64_defines.vh"
30
 
31
module FT64_AMO_alu(instr, a, b, res);
32
input [31:0] instr;
33
input [63:0] a;
34
input [63:0] b;
35
output reg [63:0] res;
36
 
37
wire [4:0] op = instr[30:26];
38
 
39
always @*
40
case(instr[5:0])
41
`AMO:
42
        case(op)
43
        `AMO_SWAP:      res <= b;
44
        `AMO_ADD:       case(instr[23:21])
45
                                3'd0,3'd4:
46
                                        begin
47
                                                res[7:0] <= a[7:0] + b[7:0];
48
                                                res[15:8] <= a[15:8] + b[15:8];
49
                                                res[23:16] <= a[23:16] + b[23:16];
50
                                                res[31:24] <= a[31:24] + b[31:24];
51
                                                res[39:32] <= a[39:32] + b[39:32];
52
                                                res[47:40] <= a[47:40] + b[47:40];
53
                                                res[55:48] <= a[55:48] + b[55:48];
54
                                                res[63:56] <= a[63:56] + b[63:56];
55
                                        end
56
                                3'd1,3'd5:
57
                                        begin
58
                                                res[15:0] <= a[15:0] + b[15:0];
59
                                                res[31:16] <= a[31:16] + b[31:16];
60
                                                res[47:32] <= a[47:32] + b[47:32];
61
                                                res[63:48] <= a[63:48] + b[63:48];
62
                                        end
63
                                3'd2,3'd6:
64
                                        begin
65
                                                res[31:0] <= a[31:0] + b[31:0];
66
                                                res[63:32] <= a[63:32] + b[63:32];
67
                                        end
68
                                3'd3,3'd7:      res <= a + b;
69
                                endcase
70
        `AMO_AND:       res <= a & b;
71
        `AMO_OR:        res <= a | b;
72
        `AMO_XOR:       res <= a ^ b;
73
 
74
        `AMO_SHL:
75
                                case(instr[23:21])
76
                                3'd0,3'd4:
77
                                        begin
78
                                                res[7:0] <= a[7:0] << b[2:0];
79
                                                res[15:8] <= a[15:8] << b[2:0];
80
                                                res[23:16] <= a[23:16] << b[2:0];
81
                                                res[31:24] <= a[31:24] << b[2:0];
82
                                                res[39:32] <= a[39:32] << b[2:0];
83
                                                res[47:40] <= a[47:40] << b[2:0];
84
                                                res[55:48] <= a[55:48] << b[2:0];
85
                                                res[63:56] <= a[63:56] << b[2:0];
86
                                        end
87
                                3'd1,3'd5:
88
                                        begin
89
                                                res[15:0] <= a[15:0] << b[3:0];
90
                                                res[31:16] <= a[31:16] << b[3:0];
91
                                                res[47:32] <= a[47:32] << b[3:0];
92
                                                res[63:48] <= a[63:48] << b[3:0];
93
                                        end
94
                                3'd2,3'd6:
95
                                        begin
96
                                                res[31:0] <= a[31:0] << b[4:0];
97
                                                res[63:32] <= a[63:32] << b[4:0];
98
                                        end
99
                                3'd3,3'd7:      res <= a << b[5:0];
100
                                endcase
101
 
102
        `AMO_SHR:
103
                                case(instr[23:21])
104
                                3'd0,3'd4:
105
                                        begin
106
                                                res[7:0] <= a[7:0] >> b[2:0];
107
                                                res[15:8] <= a[15:8] >> b[2:0];
108
                                                res[23:16] <= a[23:16] >> b[2:0];
109
                                                res[31:24] <= a[31:24] >> b[2:0];
110
                                                res[39:32] <= a[39:32] >> b[2:0];
111
                                                res[47:40] <= a[47:40] >> b[2:0];
112
                                                res[55:48] <= a[55:48] >> b[2:0];
113
                                                res[63:56] <= a[63:56] >> b[2:0];
114
                                        end
115
                                3'd1,3'd5:
116
                                        begin
117
                                                res[15:0] <= a[15:0] >> b[3:0];
118
                                                res[31:16] <= a[31:16] >> b[3:0];
119
                                                res[47:32] <= a[47:32] >> b[3:0];
120
                                                res[63:48] <= a[63:48] >> b[3:0];
121
                                        end
122
                                3'd2,3'd6:
123
                                        begin
124
                                                res[31:0] <= a[31:0] >> b[4:0];
125
                                                res[63:32] <= a[63:32] >> b[4:0];
126
                                        end
127
                                3'd3,3'd7:      res <= a >> b[5:0];
128
                                endcase
129
 
130
        `AMO_MIN:
131
                                case(instr[23:21])
132
                                3'd0,3'd4:
133
                                        begin
134
                                                res[7:0] <= $signed(a[7:0]) < $signed(b[7:0]) ? a[7:0] : b[7:0];
135
                                                res[15:8] <= $signed(a[15:8]) < $signed(b[15:8]) ? a[15:8] : b[15:8];
136
                                                res[23:16] <= $signed(a[23:16]) < $signed(b[23:16]) ? a[23:16] : b[23:16];
137
                                                res[31:24] <= $signed(a[31:24]) < $signed(b[31:24]) ? a[31:24] : b[31:24];
138
                                                res[39:32] <= $signed(a[39:32]) < $signed(b[39:32]) ? a[39:32] : b[39:32];
139
                                                res[47:40] <= $signed(a[47:40]) < $signed(b[47:40]) ? a[47:40] : b[47:40];
140
                                                res[55:48] <= $signed(a[55:48]) < $signed(b[55:48]) ? a[55:48] : b[55:48];
141
                                                res[63:56] <= $signed(a[63:56]) < $signed(b[63:56]) ? a[63:56] : b[63:56];
142
                                        end
143
                                3'd1,3'd5:
144
                                        begin
145
                                                res[15:0] <= $signed(a[15:0]) < $signed(b[15:0]) ? a[15:0] : b[15:0];
146
                                                res[31:16] <= $signed(a[31:16]) < $signed(b[31:16]) ? a[31:16] : b[31:16];
147
                                                res[47:32] <= $signed(a[47:32]) < $signed(b[47:32]) ? a[47:32] : b[47:32];
148
                                                res[63:48] <= $signed(a[63:48]) < $signed(b[63:48]) ? a[63:48] : b[63:48];
149
                                        end
150
                                3'd2,3'd6:
151
                                        begin
152
                                                res[31:0] <= $signed(a[31:0]) < $signed(b[31:0]) ? a[31:0] : b[31:0];
153
                                                res[63:32] <= $signed(a[63:32]) < $signed(b[63:32]) ? a[63:32] : b[63:32];
154
                                        end
155
                                3'd3,3'd7:      res <= $signed(a) < $signed(b) ? a : b;
156
                                endcase
157
        `AMO_MAX:
158
                                case(instr[23:21])
159
                                3'd0,3'd4:
160
                                        begin
161
                                                res[7:0] <= $signed(a[7:0]) > $signed(b[7:0]) ? a[7:0] : b[7:0];
162
                                                res[15:8] <= $signed(a[15:8]) > $signed(b[15:8]) ? a[15:8] : b[15:8];
163
                                                res[23:16] <= $signed(a[23:16]) > $signed(b[23:16]) ? a[23:16] : b[23:16];
164
                                                res[31:24] <= $signed(a[31:24]) > $signed(b[31:24]) ? a[31:24] : b[31:24];
165
                                                res[39:32] <= $signed(a[39:32]) > $signed(b[39:32]) ? a[39:32] : b[39:32];
166
                                                res[47:40] <= $signed(a[47:40]) > $signed(b[47:40]) ? a[47:40] : b[47:40];
167
                                                res[55:48] <= $signed(a[55:48]) > $signed(b[55:48]) ? a[55:48] : b[55:48];
168
                                                res[63:56] <= $signed(a[63:56]) > $signed(b[63:56]) ? a[63:56] : b[63:56];
169
                                        end
170
                                3'd1,3'd5:
171
                                        begin
172
                                                res[15:0] <= $signed(a[15:0]) > $signed(b[15:0]) ? a[15:0] : b[15:0];
173
                                                res[31:16] <= $signed(a[31:16]) > $signed(b[31:16]) ? a[31:16] : b[31:16];
174
                                                res[47:32] <= $signed(a[47:32]) > $signed(b[47:32]) ? a[47:32] : b[47:32];
175
                                                res[63:48] <= $signed(a[63:48]) > $signed(b[63:48]) ? a[63:48] : b[63:48];
176
                                        end
177
                                3'd2,3'd6:
178
                                        begin
179
                                                res[31:0] <= $signed(a[31:0]) > $signed(b[31:0]) ? a[31:0] : b[31:0];
180
                                                res[63:32] <= $signed(a[63:32]) > $signed(b[63:32]) ? a[63:32] : b[63:32];
181
                                        end
182
                                3'd3,3'd7:      res <= $signed(a) > $signed(b) ? a : b;
183
                                endcase
184
        `AMO_MINU:
185
                                case(instr[23:21])
186
                                3'd0,3'd4:
187
                                        begin
188
                                                res[7:0] <= $unsigned(a[7:0]) < $unsigned(b[7:0]) ? a[7:0] : b[7:0];
189
                                                res[15:8] <= $unsigned(a[15:8]) < $unsigned(b[15:8]) ? a[15:8] : b[15:8];
190
                                                res[23:16] <= $unsigned(a[23:16]) < $unsigned(b[23:16]) ? a[23:16] : b[23:16];
191
                                                res[31:24] <= $unsigned(a[31:24]) < $unsigned(b[31:24]) ? a[31:24] : b[31:24];
192
                                                res[39:32] <= $unsigned(a[39:32]) < $unsigned(b[39:32]) ? a[39:32] : b[39:32];
193
                                                res[47:40] <= $unsigned(a[47:40]) < $unsigned(b[47:40]) ? a[47:40] : b[47:40];
194
                                                res[55:48] <= $unsigned(a[55:48]) < $unsigned(b[55:48]) ? a[55:48] : b[55:48];
195
                                                res[63:56] <= $unsigned(a[63:56]) < $unsigned(b[63:56]) ? a[63:56] : b[63:56];
196
                                        end
197
                                3'd1,3'd5:
198
                                        begin
199
                                                res[15:0] <= $unsigned(a[15:0]) < $unsigned(b[15:0]) ? a[15:0] : b[15:0];
200
                                                res[31:16] <= $unsigned(a[31:16]) < $unsigned(b[31:16]) ? a[31:16] : b[31:16];
201
                                                res[47:32] <= $unsigned(a[47:32]) < $unsigned(b[47:32]) ? a[47:32] : b[47:32];
202
                                                res[63:48] <= $unsigned(a[63:48]) < $unsigned(b[63:48]) ? a[63:48] : b[63:48];
203
                                        end
204
                                3'd2,3'd6:
205
                                        begin
206
                                                res[31:0] <= $unsigned(a[31:0]) < $unsigned(b[31:0]) ? a[31:0] : b[31:0];
207
                                                res[63:32] <= $unsigned(a[63:32]) < $unsigned(b[63:32]) ? a[63:32] : b[63:32];
208
                                        end
209
                                3'd3,3'd7:      res <= $unsigned(a) < $unsigned(b) ? a : b;
210
                                endcase
211
        `AMO_MAXU:
212
                                case(instr[23:21])
213
                                3'd0,3'd4:
214
                                        begin
215
                                                res[7:0] <= $unsigned(a[7:0]) > $unsigned(b[7:0]) ? a[7:0] : b[7:0];
216
                                                res[15:8] <= $unsigned(a[15:8]) > $unsigned(b[15:8]) ? a[15:8] : b[15:8];
217
                                                res[23:16] <= $unsigned(a[23:16]) > $unsigned(b[23:16]) ? a[23:16] : b[23:16];
218
                                                res[31:24] <= $unsigned(a[31:24]) > $unsigned(b[31:24]) ? a[31:24] : b[31:24];
219
                                                res[39:32] <= $unsigned(a[39:32]) > $unsigned(b[39:32]) ? a[39:32] : b[39:32];
220
                                                res[47:40] <= $unsigned(a[47:40]) > $unsigned(b[47:40]) ? a[47:40] : b[47:40];
221
                                                res[55:48] <= $unsigned(a[55:48]) > $unsigned(b[55:48]) ? a[55:48] : b[55:48];
222
                                                res[63:56] <= $unsigned(a[63:56]) > $unsigned(b[63:56]) ? a[63:56] : b[63:56];
223
                                        end
224
                                3'd1,3'd5:
225
                                        begin
226
                                                res[15:0] <= $unsigned(a[15:0]) > $unsigned(b[15:0]) ? a[15:0] : b[15:0];
227
                                                res[31:16] <= $unsigned(a[31:16]) > $unsigned(b[31:16]) ? a[31:16] : b[31:16];
228
                                                res[47:32] <= $unsigned(a[47:32]) > $unsigned(b[47:32]) ? a[47:32] : b[47:32];
229
                                                res[63:48] <= $unsigned(a[63:48]) > $unsigned(b[63:48]) ? a[63:48] : b[63:48];
230
                                        end
231
                                3'd2,3'd6:
232
                                        begin
233
                                                res[31:0] <= $unsigned(a[31:0]) > $unsigned(b[31:0]) ? a[31:0] : b[31:0];
234
                                                res[63:32] <= $unsigned(a[63:32]) > $unsigned(b[63:32]) ? a[63:32] : b[63:32];
235
                                        end
236
                                3'd3,3'd7:      res <= $unsigned(a) > $unsigned(b) ? a : b;
237
                                endcase
238
        default:        res <= 64'hDEADDEADDEADDEAD;
239
        endcase
240
`INC:           res <= a + b;
241
default:        res <= 64'hDEADDEADDEADDEAD;
242
endcase
243
 
244
endmodule

powered by: WebSVN 2.1.0

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