From 873cc68869f365f759aa36026cf2ae9ff48dd86f Mon Sep 17 00:00:00 2001 From: codecyang Date: Fri, 19 Jun 2020 20:48:13 +0800 Subject: [PATCH] Integrate ALU into CPU. --- src/verilog/Computer.v | 35 ++++++++++++++++++++++++++++------- src/verilog/README.md | 10 ---------- src/verilog/alu.v | 36 ------------------------------------ src/verilog/tb_alu.v | 39 --------------------------------------- 4 files changed, 28 insertions(+), 92 deletions(-) delete mode 100644 src/verilog/alu.v delete mode 100644 src/verilog/tb_alu.v diff --git a/src/verilog/Computer.v b/src/verilog/Computer.v index cc50cbe..bd2679f 100644 --- a/src/verilog/Computer.v +++ b/src/verilog/Computer.v @@ -2,10 +2,8 @@ * Changed from: https://github.com/cccbook/co/blob/master/code/verilog/nand2tetris/computer.v */ -`include "alu.v" - module CPU(output writeM, output[15:0] outM, output[14:0] addressM,pc, input clk,reset, input[15:0] inM,I); - wire[15:0] Ain, Aout, AorM, ALUout, Dout, addressMOut; + wire[15:0] Aout, AorM, ALUout, Dout; reg[15:0] A, D, pcReg; assign Aout = A; @@ -24,7 +22,31 @@ module CPU(output writeM, output[15:0] outM, output[14:0] addressM,pc, input clk // 16-bit ALU. assign AorM = I[12] ? inM : Aout; - ALU16 alu(ALUout, zr, ng, Dout, AorM, I[11], I[10], I[9], I[8], I[7], I[6]); + // I[11], x = 0 + wire[15:0] zx = I[11] ? 16'b0 : Dout; + + // I[10], x = ~x + wire[15:0] nx = I[10] ? ~zx : zx; + + // I[9], y = 0 + wire[15:0] zy = I[9] ? 16'b0 : AorM; + + // I[8], y = !y + wire[15:0] ny = I[8] ? ~zy : zy; + + // I[7] = 0, ALUout = x & y + // I[7] = 1, ALUout = x + y + wire[15:0] f = I[7] ? nx + ny : nx & ny; + + // I[6] = 0, ALUout = f + // I[6] = 1, ALUout = ~f + assign ALUout = I[6] ? ~f : f; + + // ALUout = 0, zr = 1 + wire zr = ALUout == 0; + + // ALUout < 0, ng = 1 + wire ng = ALUout[15]; // output assign addressM = Aout[14:0]; @@ -35,14 +57,13 @@ module CPU(output writeM, output[15:0] outM, output[14:0] addressM,pc, input clk wire Atype = ~I[15]; // A-instruction wire AluToA = I[15] & I[5]; // AluToA = I[15] & d1 wire Aload = Atype | AluToA; // A-instruction or data load to A-register - assign Ain = AluToA ? ALUout : I; // Data register. wire Dload = I[15] & I[4]; // Dload = I[15] & d2 always @ (posedge clk) begin // Registers - if(Aload) A = Ain; + if(Aload) A = AluToA ? ALUout : I; if(Dload) D = ALUout; // Program Counter. @@ -73,7 +94,7 @@ module Computer(input clk, reset); wire[15:0] inM, outM, I; wire[14:0] addressM, pc; - Memory ram(inM, clk, writeM, outM, addressM); ROM32K rom(I, pc); CPU cpu(writeM, outM, addressM,pc, clk,reset, inM,I); + Memory ram(inM, clk, writeM, outM, addressM); endmodule // Computer. diff --git a/src/verilog/README.md b/src/verilog/README.md index 08e974e..729c3ce 100644 --- a/src/verilog/README.md +++ b/src/verilog/README.md @@ -3,7 +3,6 @@ Here are some shortcut to test the chip component. * [Compile & Test](#compile--test) -* [ALU (16-bit)](#alu-16-bit) * [CPU (Central Processing Unit)](#cpu-central-processing-unit) * [Memory](#memory) * [ROM32K](#rom32k) @@ -28,15 +27,6 @@ gtkwave tb_sample.vcd # See graphical wave output. Under "src/verilog" directory. -### ALU (16-bit) - -``` -iverilog -o tb_alu.vvp tb_alu.v -vvp tb_alu.vvp -gtkwave tb_alu.vcd -``` - - ### CPU (Central Processing Unit) > Reference from [cccbook](https://github.com/cccbook/co/blob/1c86da267d19d5e2ec1b5e2dfcb6f53cac2cf74e/code/verilog/nand2tetris/computer.v#L18) diff --git a/src/verilog/alu.v b/src/verilog/alu.v deleted file mode 100644 index fe72feb..0000000 --- a/src/verilog/alu.v +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 16-bit ALU. - */ -module ALU16(output[15:0] out, output zr,ng, input[15:0] x,y, input zx,nx,zy,ny,f,no); - // zx, x = 0 - wire[15:0] zx_out; - assign zx_out = zx ? 16'b0 : x; - - // nx, x = !x - wire[15:0] nx_out; - assign nx_out = nx ? ~zx_out : zx_out; - - // zy, y = 0 - wire[15:0] zy_out; - assign zy_out = zy ? 16'b0 : y; - - // ny, y = !y - wire[15:0] ny_out; - assign ny_out = ny ? ~zy_out : zy_out; - - // f = 0, out = x & y - // f = 1, out = x + y - wire[15:0] f_out; - assign f_out = f ? nx_out + ny_out : nx_out & ny_out; - - // no = 0, out = out - // no = 1, out = !out - wire[15:0] nf_out; - assign out = no ? ~f_out : f_out; - - // out = 0, zr = 1 - assign zr = out == 0; - - // out < 0, ng = 1 - assign ng = out[15] & 1'b1; -endmodule // 16-bit ALU. diff --git a/src/verilog/tb_alu.v b/src/verilog/tb_alu.v deleted file mode 100644 index 883881c..0000000 --- a/src/verilog/tb_alu.v +++ /dev/null @@ -1,39 +0,0 @@ -`include "alu.v" - -module tb_alu; - reg[5:0] ins; // zx, nx, zy, ny, f, no; - reg[15:0] x, y; - wire[15:0] out; - wire zr, ng; - - ALU16 g0(out, zr, ng, x, y, ins[5], ins[4], ins[3], ins[2], ins[1], ins[0]); - - initial begin - $dumpfile("tb_alu.vcd"); - $dumpvars(0, g0); - $monitor("%4dns x = %d, y = %d, out = %d, zr = %b, ng = %b", $stime, x, y, out, zr, ng); - - x = 100; - y = 3; - - #1 ins = 6'b101010; // 0 - #1 ins = 6'b111111; // 1 - #1 ins = 6'b111010; // -1 - #1 ins = 6'b001100; // x - #1 ins = 6'b110000; // y - #1 ins = 6'b001101; // !x - #1 ins = 6'b110001; // !y - #1 ins = 6'b001111; // -x - #1 ins = 6'b110011; // -y - #1 ins = 6'b011111; // x + 1; - #1 ins = 6'b110111; // y + 1; - #1 ins = 6'b001110; // x - 1; - #1 ins = 6'b110010; // y - 1; - #1 ins = 6'b000010; // x + y - #1 ins = 6'b010011; // x - y - #1 ins = 6'b000111; // y - x - #1 ins = 6'b000000; // x & y - #1 ins = 6'b010101; // x | y - #1 $finish; - end -endmodule // tb_alu.