summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nandgame/instruction_decode.sv58
1 files changed, 58 insertions, 0 deletions
diff --git a/nandgame/instruction_decode.sv b/nandgame/instruction_decode.sv
new file mode 100644
index 0000000..eafd90c
--- /dev/null
+++ b/nandgame/instruction_decode.sv
@@ -0,0 +1,58 @@
+`timescale 1us/1us
+
+`include "alu.sv"
+`include "cond_check.sv"
+
+module instruction_decode #(
+ parameter DATA_WIDTH = 16
+) (
+ input [15:0] instruction,
+
+ input [(DATA_WIDTH-1):0] A_i,
+ input [(DATA_WIDTH-1):0] D_i,
+ input [(DATA_WIDTH-1):0] pA_i,
+
+ output [(DATA_WIDTH-1):0] RES,
+ output do_jump,
+
+ output dst_a,
+ output dst_d,
+ output dst_pa
+);
+
+assign dst_a = instruction[5];
+assign dst_d = instruction[4];
+assign dst_pa = instruction[3];
+
+wire use_pointer_a_for_alu;
+wire [(DATA_WIDTH-1):0] alu_y;
+assign use_pointer_a_for_alu = instruction[12];
+assign alu_y = use_pointer_a_for_alu ? pA_i : A_i;
+
+wire [(DATA_WIDTH-1):0] alu_res;
+
+alu #(
+ .DATA_WIDTH(DATA_WIDTH)
+) my_alu (
+ .X(D_i),
+ .Y(alu_y),
+ .u(instruction[10]),
+ .opcode(instruction[9:8]),
+ .zx(instruction[7]),
+ .sw(instruction[6]),
+ .RES(alu_res)
+);
+
+cond_check #(
+ .DATA_WIDTH(DATA_WIDTH)
+) my_cond (
+ .X(alu_res),
+ .ltz(instruction[2]),
+ .eqz(instruction[1]),
+ .gtz(instruction[0]),
+ .res(do_jump)
+);
+
+assign RES = alu_res;
+
+endmodule