generated from MiSTer-devel/Template_MiSTer
-
Notifications
You must be signed in to change notification settings - Fork 1
/
ALU.v
83 lines (70 loc) · 2.78 KB
/
ALU.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
//============================================================================
//
// This program is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 of the License, or (at your option)
// any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
//============================================================================
// Implementation: the ALU manipulates the x and y
// inputs and then operates on the resulting values,
// as follows:
// if (zx == 1) sets x = 0 // 16-bit constant
// if (nx == 1) sets x = ~x // bitwise "not"
// if (zy == 1) sets y = 0 // 16-bit constant
// if (ny == 1) sets y = ~y // bitwise "not"
// if (f == 1) sets out = x + y // integer 2's-complement addition
// if (f == 0) sets out = x & y // bitwise And
// if (no == 1) sets out = ~out // bitwise Not
// if (out == 0) sets zr = 1
// if (out < 0) sets ng = 1
module c_ALU
(
input [15:0] x, y,
input zx, nx,
input zy, ny,
input f, no,
output [15:0] out,
output zr, ng
);
// zx
wire [15:0] x1, x2, notx1;
c_Mux16 MuxZX ( .a(x), .b(16'b0000000000000000), .sel(zx), .out(x1) );
// nx
c_Not16 Not16NX ( .in(x1), .out(notx1) );
c_Mux16 MuxNX ( .a(x1), .b(notx1), .sel(nx), .out(x2) );
// zy
wire [15:0] y1, y2, noty1;
c_Mux16 MuxZY ( .a(y), .b(16'b0000000000000000), .sel(zy), .out(y1) );
// ny
c_Not16 Not16NY ( .in(y1), .out(noty1) );
c_Mux16 MuxNY ( .a(y1), .b(noty1), .sel(ny), .out(y2) );
// f
wire [15:0] and16, add16, func16;
c_And16 And16f ( .a(x2), .b(y2), .out(and16) );
c_Add16 Add16f ( .a(x2), .b(y2), .out(add16) );
c_Mux16 Mux16f ( .a(and16), .b(add16), .sel(f), .out(func16) );
// no
wire [15:0] notfunc16, noOut16;
c_Not16 Not16no ( .in(func16), .out(notfunc16) );
c_Mux16 Mux16no ( .a(func16), .b(notfunc16), .sel(no), .out(noOut16) );
// out
assign out = noOut16;
// ng
assign ng = noOut16[15];
// zr
wire or1, or2, or_fin;
c_Or8Way Or8Wayzr1 ( .in(noOut16[ 7:0]), .out(or1) );
c_Or8Way Or8Wayzr2 ( .in(noOut16[15:8]), .out(or2) );
g_OR Orzr ( .a(or1), .b(or2), .out(or_fin) );
g_NOT Notzr ( .in(or_fin), .out(zr) );
endmodule