summaryrefslogtreecommitdiff
path: root/nandgame/hack_alu.sv
blob: 6d66a085a7cf0626fe3d84c6c986f29d8376afee (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
70
71
72
73
74
75
// HACK / nand2tetris ALU

`timescale 1us/1us

`ifndef HACK_ALU
`define HACK_ALU

// See fig. 2.6 in book
module  alu #(
  parameter DATA_WIDTH = 16
) (
  // "X" operand
  input [(DATA_WIDTH-1):0] X_in,
  // "Y" operand
  input [(DATA_WIDTH-1):0] Y_in,

  // zero X
  input zx,
  // negate X
  input nx,
  // zero Y
  input zy,
  // negate Y
  input ny,

  // "u" flag. 1=add, 0=and
  input logic f_arith_nlogic_in,

  // negate output
  input logic neg_out,

  // result of operation
  output logic [(DATA_WIDTH-1):0] result_out,
  // Result is zero
  output logic zero_out,
  // result is negative
  output logic negate_out
);

logic [(DATA_WIDTH-1):0] x1, x2, y1, y2, res1, res2 /* verilator public */;

// logic [(DATA_WIDTH-1):0] int_result_arith;
// logic [(DATA_WIDTH-1):0] int_result_logic;

// bit-wise negation
assign x1 = zx ? 0 : X_in;
assign y1 = zy ? 0 : Y_in;
assign x2 = nx ? ~x1 : x1;
assign y2 = ny ? ~y1 : y1;
assign res1 = f_arith_nlogic_in ? (x2 + y2) : (x2 & y2);
assign res2 = neg_out ? ~res1 : res1;
assign result_out = res2;
assign zero_out = result_out == 0;
assign negate_out = result_out[DATA_WIDTH-1] == 1;
// assign y1 = sw_in ? X_in : Y_in;

// arith_unit au (
//   .X_in(x1),
//   .Y_in(y1),
//   .result_out(int_result_arith),
//   .arith_operation_in(ArithCode'(opcode_in))
// );

// logic_unit lu (
//   .X_in(x1),
//   .Y_in(y1),
//   .result_out(int_result_logic),
//   .logic_operation_in(LogicCode'(opcode_in))
// );

// assign result_out = u_arith_nlogic_in ? int_result_arith : int_result_logic;

endmodule

`endif