/** * The Hack CPU (Central Processing unit), consisting of an ALU, * two registers named A and D, and a program counter named PC. * The CPU is designed to fetch and execute instructions written in * the Hack machine language. In particular, functions as follows: * Executes the inputted instruction according to the Hack machine * language specification. The D and A in the language specification * refer to CPU-resident registers, while M refers to the external * memory location addressed by A, i.e. to Memory[A]. The inM input * holds the value of this location. If the current instruction needs * to write a value to M, the value is placed in outM, the address * of the target location is placed in the addressM output, and the * writeM control bit is asserted. (When writeM==0, any value may * appear in outM). The outM and writeM outputs are combinational: * they are affected instantaneously by the execution of the current * instruction. The addressM and pc outputs are clocked: although they * are affected by the execution of the current instruction, they commit * to their new values only in the next time step. If reset==1 then the * CPU jumps to address 0 (i.e. pc is set to 0 in next time step) rather * than to the address resulting from executing the current instruction. */ `default_nettype none module CPU( input clk, input [15:0] inM, // M value input (M = contents of RAM[A]) input [15:0] instruction, // Instruction for execution input reset, // Signals whether to re-start the current // program (reset==1) or continue executing // the current program (reset==0). output [15:0] outM, // M value output output writeM, // Write to M? output [15:0] addressM, // Address in data memory (of M) to read output [15:0] pc // address of next instruction ); // Put your code here: wire loadA; wire loadD; wire is_A; wire is_C; wire zr; wire ng; wire inc; wire load; wire jump; wire [15:0] toA; wire [15:0] toD; wire [15:0] toPC; wire [15:0] fromA; wire [15:0] fromD; wire [15:0] fromPC; wire [15:0] fromAorM; wire [15:0] fromALU; reg [15:0] tempM; reg [15:0] tempPC; assign is_C = instruction[15] & instruction[14] & instruction[13]; assign is_A = ~is_C; assign loadD = is_C & instruction[4]; assign loadA = (is_C & instruction[5]) || is_A; assign fromAorM = instruction[12] ? inM : fromA; assign toA = is_A ? instruction : outM; // jump if j1 bit set and ng bit set // jump if j2 bit set and zr bit set // jump if j3 bit set and zr, ng bit not set assign jump = is_C & ((instruction[2] & ng) || (instruction[1] & zr) || (instruction[0] & ~(zr | ng))); assign inc = ~jump; assign outM = fromALU; //assign toPC = jump? fromA : pc; //xxxx xxxx xxxx xxxx Register RegA(clk, toA, loadA, fromA); Register RegD(clk, fromALU, loadD, fromD); PC PC(clk, fromA, jump, inc, reset, pc); ALU ALU( fromD, fromAorM, instruction[11], instruction[10], instruction[9], instruction[8], instruction[7], instruction[6], fromALU, zr, ng ); assign addressM = fromA; assign writeM = is_C & instruction[3]; endmodule