// Instruction decoder of Nandgame // corresponds to levels // - control selector // - control unit `timescale 1us/1us `include "alu.sv" `include "cond_check.sv" `ifndef NANDGAME_INS_DECODE `define NANDGAME_INS_DECODE module instruction_decode #( parameter DATA_WIDTH = 16 ) ( // instruction to decode input [15:0] instruction_in, // value of A register input [(DATA_WIDTH-1):0] A_in, // value of D register input [(DATA_WIDTH-1):0] D_in, // content of memory at address in A register input [(DATA_WIDTH-1):0] pA_in, // result of operation output [(DATA_WIDTH-1):0] result_out, // whether a jump should occur output do_jump_out, // whether result should be stored to A output dst_A_out, // whether result should be stored to D output dst_D_out, // whether result should be stored in memory at address in A register output dst_pA_out, // Invalid instruction output invalid_ins ); wire is_immediate_int; // bit 15 set = ALU instruction_in // bit 15 unset = immediate assign is_immediate_int = !instruction_in[15]; // bit 14 must be 1 assign invalid_ins = instruction_in[15] == 1 && instruction_in[14] == 0; assign dst_A_out = is_immediate_int || instruction_in[5]; assign dst_D_out = !is_immediate_int && instruction_in[4]; assign dst_pA_out = !is_immediate_int && instruction_in[3]; wire use_pA_for_alu_op_int; wire [(DATA_WIDTH-1):0] alu_operand_Y_int; assign use_pA_for_alu_op_int = instruction_in[12]; assign alu_operand_Y_int = use_pA_for_alu_op_int ? pA_in : A_in; wire [(DATA_WIDTH-1):0] alu_result_int; alu #( .DATA_WIDTH(DATA_WIDTH) ) my_alu ( .X_in(D_in), .Y_in(alu_operand_Y_int), .u_arith_nlogic_in(instruction_in[10]), .opcode_in(instruction_in[9:8]), .zx_in(instruction_in[7]), .sw_in(instruction_in[6]), .result_out(alu_result_int) ); wire jump_result_int; cond_check #( .DATA_WIDTH(DATA_WIDTH) ) my_cond ( .X_in(alu_result_int), .check_ltz_in(instruction_in[2]), .check_eqz_in(instruction_in[1]), .check_gtz_in(instruction_in[0]), .result_out(jump_result_int) ); assign do_jump_out = is_immediate_int ? 0 : jump_result_int; assign result_out = is_immediate_int ? // technically not needed, since bit is 0 anyway... { 1'b0, instruction_in[(DATA_WIDTH-2):0] } : alu_result_int; endmodule `endif