-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathALU.sv
More file actions
112 lines (109 loc) · 3.75 KB
/
ALU.sv
File metadata and controls
112 lines (109 loc) · 3.75 KB
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
107
108
109
110
111
112
//-----------------------------------------------------------------------------
//
// Title : Arithmetic & Logic Unit
// Author : vinod sake <vinosake@pdx.edu>
// Company : Student
//
//-----------------------------------------------------------------------------
//
// File : ALU.sv
// Generated : 12 Nov 2016
// Last Updated: 15 Dec 2016
//-----------------------------------------------------------------------------
//
// Description : Arithmetic & Logic Unit is used to perform Arthematic &
// logical operations.
//-----------------------------------------------------------------------------
`include "constants.sv"
module alu(
input reset, // Asynchronous Rest
input [7:0]primary_operand, // output of GP register (register operand)
input [7:0]secondary_operand, // operand from data bus
input [3:0]cmnd, // cmnd code from control signal translator
output logic [15:0]result, // ALU result
output logic [2:0]flags // Zero, carry & Negative flags
);
always_comb begin
if(reset == 1'b0) begin
result[15:0] = 0;
flags[2:0] = 0;
end
else begin
//result[15:0] = 0; // To avoid latch creation ??????????
case(cmnd)
`ALU_PASSTHROUGH: begin // when opcode is MOVE, data from secondary operand is directly latched.
result[7:0] = secondary_operand;
flags[`CARRY_FLAG] = 1'b0; // There is no carry on PASSTHROUGH cmnd
flags[`NEG_FLAG] = result[7];
end
`ALU_ADD: begin
result[8:0] = primary_operand + secondary_operand;
flags[`CARRY_FLAG] = result[8]; // check if carry is generated
flags[`NEG_FLAG] = result[7];
end
`ALU_SUBTRACT: begin
result[8:0] = primary_operand - secondary_operand;
flags[`CARRY_FLAG] = result[8]; // if bit is 1, then borrow is done
flags[`NEG_FLAG] = result[7];
end
`ALU_MULTIPLY: begin
result[15:0] = primary_operand * secondary_operand;
flags[`CARRY_FLAG] = 1'b0;
flags[`NEG_FLAG] = result[15];
end
`ALU_AND: begin
result[7:0] = primary_operand & secondary_operand;
flags[`CARRY_FLAG] = 1'b0;
flags[`NEG_FLAG] = result[7];
end
`ALU_OR: begin
result[7:0] = primary_operand | secondary_operand;
flags[`CARRY_FLAG] = 1'b0;
flags[`NEG_FLAG] = result[7];
end
`ALU_LOGICAL_SHIFT_RIGHT: begin // zero is added at MSB
result[7:0] = primary_operand >> 1;
flags[`CARRY_FLAG] = primary_operand[0];
flags[`NEG_FLAG] = result[7];
end
`ALU_LOGICAL_SHIFT_LEFT: begin // Zero is added at LSB
result[7:0] = primary_operand << 1;
flags[`CARRY_FLAG] = primary_operand[7]; // carry is set to be MSB
flags[`NEG_FLAG] = result[7];
end
`ALU_ARITH_SHIFT_RIGHT: begin // MSB remains same and all other lower bits shifts right
result[7:0] = primary_operand >>> 1;
flags[`CARRY_FLAG] = primary_operand[0]; // carry is set to be LSB
flags[`NEG_FLAG] = result[7];
end
`ALU_ARITH_SHIFT_LEFT: begin // LSB remains same and all other higher bits shifts left
result[7:0] = primary_operand <<< 1;
flags[`CARRY_FLAG] = primary_operand[7]; // carry is set to be MSB
flags[`NEG_FLAG] = result[7];
end
`ALU_TWOS_COMPLEMENT: begin
result[7:0] = ~primary_operand; // Complement
result[7:0] = result[7:0] + 8'd1; // add one
flags[`CARRY_FLAG] = 1'b0;
flags[`NEG_FLAG] = result[7];
end
`ALU_COMPLEMENT: begin // complement
result[7:0] = ~primary_operand;
flags[`CARRY_FLAG] = 1'b0;
flags[`NEG_FLAG] = result[7];
end
default: begin
result[15:0] = 16'd0;
flags[`CARRY_FLAG] = 1'b0;
flags[`NEG_FLAG] = 1'b0;
end
endcase
end
if(cmnd == `ALU_MULTIPLY) begin
flags[`ZERO_FLAG] = (result[15:0] == 16'd0) ? 1'b1 : 1'b0;
end
else begin
flags[`ZERO_FLAG] = (result[7:0] == 8'd0) ? 1'b1 : 1'b0;
end
end
endmodule