-
Notifications
You must be signed in to change notification settings - Fork 3
/
alu.v
69 lines (54 loc) · 1.28 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
`ifndef ALU_V
`define ALU_V
`define OP_NOP 2'h0
`define OP_ADD 2'h1
`define OP_SUB 2'h2
// Simple single cycle adder
module alu(
input clk,
input reset,
input [31:0] i_a, // 1st operand
input [31:0] i_b, // 2nd operand
input [1:0] i_cmd, // command
output [31:0] o_result,
output o_valid, // result is valid
output o_ready // ready to take input
);
reg [31:0] reg_result;
reg reg_valid = 1'b0;
// ALU state machine macros
`define ST_RESET 2'h0
`define ST_READY 2'h1
`define ST_BUSY 2'h2
// begin in reset state
reg [1:0] reg_status = `ST_RESET;
// Synchronous reset
always @(posedge clk && reset) begin
reg_status <= `ST_READY;
end
// Assign outputs
assign o_ready = ((reg_status == `ST_READY) && !reset);
assign o_valid = (reg_valid && (reg_status == `ST_READY));
assign o_result = o_valid ? reg_result : 32'hx; // Ternary operator
// Main processing loop
always @(posedge clk && !reset) begin
case (reg_status)
`ST_READY: begin
reg_status <= `ST_BUSY;
if (i_cmd == `OP_ADD) begin
reg_result = i_a + i_b;
end
// TODO: add OP_SUB
end
`ST_BUSY: begin
reg_valid <= 1'b1;
reg_status <= `ST_READY;
end
default: begin
$display("should not happen");
$finish;
end
endcase
end
endmodule
`endif