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

Subversion Repositories thor

[/] [thor/] [trunk/] [FT64/] [rtl/] [common/] [FT64_AMO_alu.v] - Blame information for rev 43

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 43 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(op)
41
`AMO_SWAP:      res <= b;
42
`AMO_ADD:       case(instr[23:21])
43
                        3'd0,3'd4:
44
                                begin
45
                                        res[7:0] <= a[7:0] + b[7:0];
46
                                        res[15:8] <= a[15:8] + b[15:8];
47
                                        res[23:16] <= a[23:16] + b[23:16];
48
                                        res[31:24] <= a[31:24] + b[31:24];
49
                                        res[39:32] <= a[39:32] + b[39:32];
50
                                        res[47:40] <= a[47:40] + b[47:40];
51
                                        res[55:48] <= a[55:48] + b[55:48];
52
                                        res[63:56] <= a[63:56] + b[63:56];
53
                                end
54
                        3'd1,3'd5:
55
                                begin
56
                                        res[15:0] <= a[15:0] + b[15:0];
57
                                        res[31:16] <= a[31:16] + b[31:16];
58
                                        res[47:32] <= a[47:32] + b[47:32];
59
                                        res[63:48] <= a[63:48] + b[63:48];
60
                                end
61
                        3'd2,3'd6:
62
                                begin
63
                                        res[31:0] <= a[31:0] + b[31:0];
64
                                        res[63:32] <= a[63:32] + b[63:32];
65
                                end
66
                        3'd3,3'd7:      res <= a + b;
67
                        endcase
68
`AMO_AND:       res <= a & b;
69
`AMO_OR:        res <= a | b;
70
`AMO_XOR:       res <= a ^ b;
71
 
72
`AMO_SHL:
73
                        case(instr[23:21])
74
                        3'd0,3'd4:
75
                                begin
76
                                        res[7:0] <= a[7:0] << b[2:0];
77
                                        res[15:8] <= a[15:8] << b[2:0];
78
                                        res[23:16] <= a[23:16] << b[2:0];
79
                                        res[31:24] <= a[31:24] << b[2:0];
80
                                        res[39:32] <= a[39:32] << b[2:0];
81
                                        res[47:40] <= a[47:40] << b[2:0];
82
                                        res[55:48] <= a[55:48] << b[2:0];
83
                                        res[63:56] <= a[63:56] << b[2:0];
84
                                end
85
                        3'd1,3'd5:
86
                                begin
87
                                        res[15:0] <= a[15:0] << b[3:0];
88
                                        res[31:16] <= a[31:16] << b[3:0];
89
                                        res[47:32] <= a[47:32] << b[3:0];
90
                                        res[63:48] <= a[63:48] << b[3:0];
91
                                end
92
                        3'd2,3'd6:
93
                                begin
94
                                        res[31:0] <= a[31:0] << b[4:0];
95
                                        res[63:32] <= a[63:32] << b[4:0];
96
                                end
97
                        3'd3,3'd7:      res <= a << b[5:0];
98
                        endcase
99
 
100
`AMO_SHR:
101
                        case(instr[23:21])
102
                        3'd0,3'd4:
103
                                begin
104
                                        res[7:0] <= a[7:0] >> b[2:0];
105
                                        res[15:8] <= a[15:8] >> b[2:0];
106
                                        res[23:16] <= a[23:16] >> b[2:0];
107
                                        res[31:24] <= a[31:24] >> b[2:0];
108
                                        res[39:32] <= a[39:32] >> b[2:0];
109
                                        res[47:40] <= a[47:40] >> b[2:0];
110
                                        res[55:48] <= a[55:48] >> b[2:0];
111
                                        res[63:56] <= a[63:56] >> b[2:0];
112
                                end
113
                        3'd1,3'd5:
114
                                begin
115
                                        res[15:0] <= a[15:0] >> b[3:0];
116
                                        res[31:16] <= a[31:16] >> b[3:0];
117
                                        res[47:32] <= a[47:32] >> b[3:0];
118
                                        res[63:48] <= a[63:48] >> b[3:0];
119
                                end
120
                        3'd2,3'd6:
121
                                begin
122
                                        res[31:0] <= a[31:0] >> b[4:0];
123
                                        res[63:32] <= a[63:32] >> b[4:0];
124
                                end
125
                        3'd3,3'd7:      res <= a >> b[5:0];
126
                        endcase
127
 
128
`AMO_MIN:
129
                        case(instr[23:21])
130
                        3'd0,3'd4:
131
                                begin
132
                                        res[7:0] <= $signed(a[7:0]) < $signed(b[7:0]) ? a[7:0] : b[7:0];
133
                                        res[15:8] <= $signed(a[15:8]) < $signed(b[15:8]) ? a[15:8] : b[15:8];
134
                                        res[23:16] <= $signed(a[23:16]) < $signed(b[23:16]) ? a[23:16] : b[23:16];
135
                                        res[31:24] <= $signed(a[31:24]) < $signed(b[31:24]) ? a[31:24] : b[31:24];
136
                                        res[39:32] <= $signed(a[39:32]) < $signed(b[39:32]) ? a[39:32] : b[39:32];
137
                                        res[47:40] <= $signed(a[47:40]) < $signed(b[47:40]) ? a[47:40] : b[47:40];
138
                                        res[55:48] <= $signed(a[55:48]) < $signed(b[55:48]) ? a[55:48] : b[55:48];
139
                                        res[63:56] <= $signed(a[63:56]) < $signed(b[63:56]) ? a[63:56] : b[63:56];
140
                                end
141
                        3'd1,3'd5:
142
                                begin
143
                                        res[15:0] <= $signed(a[15:0]) < $signed(b[15:0]) ? a[15:0] : b[15:0];
144
                                        res[31:16] <= $signed(a[31:16]) < $signed(b[31:16]) ? a[31:16] : b[31:16];
145
                                        res[47:32] <= $signed(a[47:32]) < $signed(b[47:32]) ? a[47:32] : b[47:32];
146
                                        res[63:48] <= $signed(a[63:48]) < $signed(b[63:48]) ? a[63:48] : b[63:48];
147
                                end
148
                        3'd2,3'd6:
149
                                begin
150
                                        res[31:0] <= $signed(a[31:0]) < $signed(b[31:0]) ? a[31:0] : b[31:0];
151
                                        res[63:32] <= $signed(a[63:32]) < $signed(b[63:32]) ? a[63:32] : b[63:32];
152
                                end
153
                        3'd3,3'd7:      res <= $signed(a) < $signed(b) ? a : b;
154
                        endcase
155
`AMO_MAX:
156
                        case(instr[23:21])
157
                        3'd0,3'd4:
158
                                begin
159
                                        res[7:0] <= $signed(a[7:0]) > $signed(b[7:0]) ? a[7:0] : b[7:0];
160
                                        res[15:8] <= $signed(a[15:8]) > $signed(b[15:8]) ? a[15:8] : b[15:8];
161
                                        res[23:16] <= $signed(a[23:16]) > $signed(b[23:16]) ? a[23:16] : b[23:16];
162
                                        res[31:24] <= $signed(a[31:24]) > $signed(b[31:24]) ? a[31:24] : b[31:24];
163
                                        res[39:32] <= $signed(a[39:32]) > $signed(b[39:32]) ? a[39:32] : b[39:32];
164
                                        res[47:40] <= $signed(a[47:40]) > $signed(b[47:40]) ? a[47:40] : b[47:40];
165
                                        res[55:48] <= $signed(a[55:48]) > $signed(b[55:48]) ? a[55:48] : b[55:48];
166
                                        res[63:56] <= $signed(a[63:56]) > $signed(b[63:56]) ? a[63:56] : b[63:56];
167
                                end
168
                        3'd1,3'd5:
169
                                begin
170
                                        res[15:0] <= $signed(a[15:0]) > $signed(b[15:0]) ? a[15:0] : b[15:0];
171
                                        res[31:16] <= $signed(a[31:16]) > $signed(b[31:16]) ? a[31:16] : b[31:16];
172
                                        res[47:32] <= $signed(a[47:32]) > $signed(b[47:32]) ? a[47:32] : b[47:32];
173
                                        res[63:48] <= $signed(a[63:48]) > $signed(b[63:48]) ? a[63:48] : b[63:48];
174
                                end
175
                        3'd2,3'd6:
176
                                begin
177
                                        res[31:0] <= $signed(a[31:0]) > $signed(b[31:0]) ? a[31:0] : b[31:0];
178
                                        res[63:32] <= $signed(a[63:32]) > $signed(b[63:32]) ? a[63:32] : b[63:32];
179
                                end
180
                        3'd3,3'd7:      res <= $signed(a) > $signed(b) ? a : b;
181
                        endcase
182
`AMO_MINU:
183
                        case(instr[23:21])
184
                        3'd0,3'd4:
185
                                begin
186
                                        res[7:0] <= $unsigned(a[7:0]) < $unsigned(b[7:0]) ? a[7:0] : b[7:0];
187
                                        res[15:8] <= $unsigned(a[15:8]) < $unsigned(b[15:8]) ? a[15:8] : b[15:8];
188
                                        res[23:16] <= $unsigned(a[23:16]) < $unsigned(b[23:16]) ? a[23:16] : b[23:16];
189
                                        res[31:24] <= $unsigned(a[31:24]) < $unsigned(b[31:24]) ? a[31:24] : b[31:24];
190
                                        res[39:32] <= $unsigned(a[39:32]) < $unsigned(b[39:32]) ? a[39:32] : b[39:32];
191
                                        res[47:40] <= $unsigned(a[47:40]) < $unsigned(b[47:40]) ? a[47:40] : b[47:40];
192
                                        res[55:48] <= $unsigned(a[55:48]) < $unsigned(b[55:48]) ? a[55:48] : b[55:48];
193
                                        res[63:56] <= $unsigned(a[63:56]) < $unsigned(b[63:56]) ? a[63:56] : b[63:56];
194
                                end
195
                        3'd1,3'd5:
196
                                begin
197
                                        res[15:0] <= $unsigned(a[15:0]) < $unsigned(b[15:0]) ? a[15:0] : b[15:0];
198
                                        res[31:16] <= $unsigned(a[31:16]) < $unsigned(b[31:16]) ? a[31:16] : b[31:16];
199
                                        res[47:32] <= $unsigned(a[47:32]) < $unsigned(b[47:32]) ? a[47:32] : b[47:32];
200
                                        res[63:48] <= $unsigned(a[63:48]) < $unsigned(b[63:48]) ? a[63:48] : b[63:48];
201
                                end
202
                        3'd2,3'd6:
203
                                begin
204
                                        res[31:0] <= $unsigned(a[31:0]) < $unsigned(b[31:0]) ? a[31:0] : b[31:0];
205
                                        res[63:32] <= $unsigned(a[63:32]) < $unsigned(b[63:32]) ? a[63:32] : b[63:32];
206
                                end
207
                        3'd3,3'd7:      res <= $unsigned(a) < $unsigned(b) ? a : b;
208
                        endcase
209
`AMO_MAXU:
210
                        case(instr[23:21])
211
                        3'd0,3'd4:
212
                                begin
213
                                        res[7:0] <= $unsigned(a[7:0]) > $unsigned(b[7:0]) ? a[7:0] : b[7:0];
214
                                        res[15:8] <= $unsigned(a[15:8]) > $unsigned(b[15:8]) ? a[15:8] : b[15:8];
215
                                        res[23:16] <= $unsigned(a[23:16]) > $unsigned(b[23:16]) ? a[23:16] : b[23:16];
216
                                        res[31:24] <= $unsigned(a[31:24]) > $unsigned(b[31:24]) ? a[31:24] : b[31:24];
217
                                        res[39:32] <= $unsigned(a[39:32]) > $unsigned(b[39:32]) ? a[39:32] : b[39:32];
218
                                        res[47:40] <= $unsigned(a[47:40]) > $unsigned(b[47:40]) ? a[47:40] : b[47:40];
219
                                        res[55:48] <= $unsigned(a[55:48]) > $unsigned(b[55:48]) ? a[55:48] : b[55:48];
220
                                        res[63:56] <= $unsigned(a[63:56]) > $unsigned(b[63:56]) ? a[63:56] : b[63:56];
221
                                end
222
                        3'd1,3'd5:
223
                                begin
224
                                        res[15:0] <= $unsigned(a[15:0]) > $unsigned(b[15:0]) ? a[15:0] : b[15:0];
225
                                        res[31:16] <= $unsigned(a[31:16]) > $unsigned(b[31:16]) ? a[31:16] : b[31:16];
226
                                        res[47:32] <= $unsigned(a[47:32]) > $unsigned(b[47:32]) ? a[47:32] : b[47:32];
227
                                        res[63:48] <= $unsigned(a[63:48]) > $unsigned(b[63:48]) ? a[63:48] : b[63:48];
228
                                end
229
                        3'd2,3'd6:
230
                                begin
231
                                        res[31:0] <= $unsigned(a[31:0]) > $unsigned(b[31:0]) ? a[31:0] : b[31:0];
232
                                        res[63:32] <= $unsigned(a[63:32]) > $unsigned(b[63:32]) ? a[63:32] : b[63:32];
233
                                end
234
                        3'd3,3'd7:      res <= $unsigned(a) > $unsigned(b) ? a : b;
235
                        endcase
236
default:        res <= 64'hDEADDEADDEADDEAD;
237
endcase
238
 
239
 
240
endmodule

powered by: WebSVN 2.1.0

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