summaryrefslogtreecommitdiff
path: root/alu.v
blob: 5fbb8ba0618bfef2a1e6b0dcf1b21a755c1c341d (plain)
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
module alu (
	input [3:0] op,
	input [15:0] x,
	input [15:0] y,
	output [15:0] result,
	output zero,
	output carry
);

// op:
//  0000: result = x + y
//  0001: result = x - y
//  0010: result = x * y
//  0011: result = x / y
//  0100: result = x & y
//  0101: result = x | y
//  0110: result = x ^ y
//  0111: result = x
//  1000: result = x << y (zero extend)
//  1001: result = x << y (one extend)
//  1010: result = x << y (extend with last bit)
//  1011: result = x << y (barrel shift)
//  1100: result = x >> y (zero extend)
//  1101: result = x >> y (one extend)
//  1110: result = x >> y (extend with sign bit)
//  1111: result = x >> y (barrel shift)

	wire [16:0] sum;
	wire [16:0] diff;
	wire [16:0] prod;
	wire [16:0] quot;
	wire [15:0] anded;
	wire [15:0] ored;
	wire [15:0] xored;
	wire [15:0] shifted;

	assign sum = x + y;
	assign diff = x - y;
	assign prod = x * y;
	assign quot = x / y;
	assign anded = x & y;
	assign ored = x | y;
	assign xored = x ^ y;

	shifter shifter_inst (
		.v(x),
		.by(y),
		.dir(op[2]),
		.extend(op[1:0]),
		.result(shifted)
	);

	assign result =
		op == 4'b0000 ? sum[15:0] :
		op == 4'b0001 ? diff[15:0] :
		op == 4'b0010 ? prod[15:0] :
		op == 4'b0011 ? quot[15:0] :
		op == 4'b0100 ? anded :
		op == 4'b0101 ? ored :
		op == 4'b0110 ? xored :
		op == 4'b0111 ? x :
		shifted;

	assign zero = ~(|result);
	assign carry =
		op == 4'b0000 ? sum[16] :
		op == 4'b0001 ? diff[16] : 1'b0;

endmodule