From 6c1db8cded8b8bb1c4d31a840f7dd9dddb8bbf7d Mon Sep 17 00:00:00 2001 From: uvok Date: Fri, 2 Jan 2026 19:36:30 +0100 Subject: Rename variables to be more clear, document --- nandgame/alu.sv | 55 ++++++----- nandgame/alu_tb.sv | 190 +++++++++++++++++++------------------- nandgame/arith_unit.sv | 26 +++--- nandgame/arith_unit_tb.sv | 64 ++++++------- nandgame/comb_mem.sv | 53 ++++++----- nandgame/comb_mem_tb.sv | 52 +++++------ nandgame/computer.sv | 68 +++++++------- nandgame/cond_check.sv | 30 +++--- nandgame/cond_check_tb.sv | 88 +++++++++--------- nandgame/counter.sv | 43 ++++----- nandgame/counter_tb.sv | 40 ++++---- nandgame/instruction_decode.sv | 83 +++++++++-------- nandgame/instruction_decode_tb.sv | 47 ++++++++++ nandgame/instruction_decode_tb.v | 37 -------- nandgame/logic_unit.sv | 34 ++++--- nandgame/logic_unit_tb.sv | 45 +++++---- 16 files changed, 502 insertions(+), 453 deletions(-) create mode 100644 nandgame/instruction_decode_tb.sv delete mode 100644 nandgame/instruction_decode_tb.v diff --git a/nandgame/alu.sv b/nandgame/alu.sv index 6aef925..f452d32 100644 --- a/nandgame/alu.sv +++ b/nandgame/alu.sv @@ -12,41 +12,48 @@ module alu #( parameter DATA_WIDTH = 16 ) ( - input [(DATA_WIDTH-1):0] X, - input [(DATA_WIDTH-1):0] Y, - input logic u, - input logic [1:0] opcode, - input logic zx, - input logic sw, - - output logic [(DATA_WIDTH-1):0] RES + // "X" operand + input [(DATA_WIDTH-1):0] X_in, + // "Y" operand + input [(DATA_WIDTH-1):0] Y_in, + // "u" flag. 1=arithmetic, 0=logic operation + input logic u_arith_nlogic_in, + // opcode, see ArithCode / LogicCode + input logic [1:0] opcode_in, + // zero the "X" operand + input logic zx_in, + // swap "X" and "Y" operands + input logic sw_in, + + // result of operation + output logic [(DATA_WIDTH-1):0] result_out ); -logic [(DATA_WIDTH-1):0] MyX; +logic [(DATA_WIDTH-1):0] int_op_x; +logic [(DATA_WIDTH-1):0] int_op_y; -logic [(DATA_WIDTH-1):0] MyY; -logic [(DATA_WIDTH-1):0] MyResA; -logic [(DATA_WIDTH-1):0] MyResL; +logic [(DATA_WIDTH-1):0] int_result_arith; +logic [(DATA_WIDTH-1):0] int_result_logic; -assign MyX = zx ? 0 : sw ? Y : X; -assign MyY = sw ? X : Y; +assign int_op_x = zx_in ? 0 + : (sw_in ? Y_in : X_in); +assign int_op_y = sw_in ? X_in : Y_in; arith_unit au ( - .X(MyX), - .Y(MyY), - .RES(MyResA), - .operation(opcode) + .X_in(int_op_x), + .Y_in(int_op_y), + .result_out(int_result_arith), + .arith_operation_in(ArithCode'(opcode_in)) ); logic_unit lu ( - .X(MyX), - .Y(MyY), - .RES(MyResL), - .operation(opcode) + .X_in(int_op_x), + .Y_in(int_op_y), + .result_out(int_result_logic), + .logic_operation_in(LogicCode'(opcode_in)) ); -assign RES = u ? MyResA : MyResL; - +assign result_out = u_arith_nlogic_in ? int_result_arith : int_result_logic; endmodule diff --git a/nandgame/alu_tb.sv b/nandgame/alu_tb.sv index cb5bfa5..1b05401 100644 --- a/nandgame/alu_tb.sv +++ b/nandgame/alu_tb.sv @@ -4,20 +4,20 @@ module alu_tb; -logic [15:0] in1; -logic [15:0] in2; -logic [1:0] opcode; -logic [15:0] result; -logic u, zx, sw; +logic [15:0] tst_in1; +logic [15:0] tst_in2; +logic [1:0] tst_opcode; +logic [15:0] tst_result; +logic tst_is_arith_nlogic, tst_zero_x, tst_swap_operands; alu uut ( - .X(in1), - .Y(in2), - .opcode(opcode), - .RES(result), - .u(u), - .zx(zx), - .sw(sw) + .X_in(tst_in1), + .Y_in(tst_in2), + .opcode_in(tst_opcode), + .result_out(tst_result), + .u_arith_nlogic_in(tst_is_arith_nlogic), + .zx_in(tst_zero_x), + .sw_in(tst_swap_operands) ); string filename; @@ -31,130 +31,130 @@ initial begin end initial begin - zx = 0; - sw = 0; + tst_zero_x = 0; + tst_swap_operands = 0; // Arith tests - u = 1; - in1 = 13; - in2 = 17; - opcode = ARITH_PLUS; + tst_is_arith_nlogic = 1; + tst_in1 = 13; + tst_in2 = 17; + tst_opcode = ARITH_PLUS; #1 - assert(result == 30) - else $error("Expected: 30, got: %d", result); + assert(tst_result == 30) + else $error("Expected: 30, got: %d", tst_result); #1 - in1 = 12; - in2 = 4; - opcode = ARITH_MINUS; + tst_in1 = 12; + tst_in2 = 4; + tst_opcode = ARITH_MINUS; #1 - assert(result == 8) - else $error("Expected: 8, got: %d", result); + assert(tst_result == 8) + else $error("Expected: 8, got: %d", tst_result); #1 - in1 = 12; - in2 = 13; - opcode = ARITH_MINUS; + tst_in1 = 12; + tst_in2 = 13; + tst_opcode = ARITH_MINUS; #1 - assert(result == 16'hffff) - else $error("Expected: 16'hffff, got: %d", result); + assert(tst_result == 16'hffff) + else $error("Expected: 16'hffff, got: %d", tst_result); #1 - in1 = 13; - in2 = 17; - opcode = ARITH_INC; + tst_in1 = 13; + tst_in2 = 17; + tst_opcode = ARITH_INC; #1 - assert(result == 14) - else $error("Expected: 14, got: %d", result); + assert(tst_result == 14) + else $error("Expected: 14, got: %d", tst_result); #1 - in1 = 13; - in2 = 17; - opcode = ARITH_DEC; + tst_in1 = 13; + tst_in2 = 17; + tst_opcode = ARITH_DEC; #1 - assert(result == 12) - else $error("Expected: 12, got: %d", result); + assert(tst_result == 12) + else $error("Expected: 12, got: %d", tst_result); #1 - in1 = 0; - in2 = 17; - opcode = ARITH_DEC; + tst_in1 = 0; + tst_in2 = 17; + tst_opcode = ARITH_DEC; #1 - assert(result == 16'hffff) - else $error("Expected: 16'hffff, got: %d", result); + assert(tst_result == 16'hffff) + else $error("Expected: 16'hffff, got: %d", tst_result); #1 // logic tests - u = 0; - in1 = 16'b1010; - in2 = 16'b1100; - opcode = LOGIC_AND; + tst_is_arith_nlogic = 0; + tst_in1 = 16'b1010; + tst_in2 = 16'b1100; + tst_opcode = LOGIC_AND; #1 - assert(result == 16'b1000) - else $error("Expected: 16'b1000, got: %d", result); + assert(tst_result == 16'b1000) + else $error("Expected: 16'b1000, got: %d", tst_result); #1 - in1 = 16'b1010; - in2 = 16'b1100; - opcode = LOGIC_OR; + tst_in1 = 16'b1010; + tst_in2 = 16'b1100; + tst_opcode = LOGIC_OR; #1 - assert(result == 16'b1110) - else $error("Expected: 16'b1110, got: %d", result); + assert(tst_result == 16'b1110) + else $error("Expected: 16'b1110, got: %d", tst_result); #1 - in1 = 16'b1010; - in2 = 16'b1100; - opcode = LOGIC_XOR; + tst_in1 = 16'b1010; + tst_in2 = 16'b1100; + tst_opcode = LOGIC_XOR; #1 - assert(result == 16'b0110) - else $error("Expected: 16'b0110, got: %d", result); + assert(tst_result == 16'b0110) + else $error("Expected: 16'b0110, got: %d", tst_result); #1 - in1 = 16'b1010101010101010; - opcode = LOGIC_NEGT; + tst_in1 = 16'b1010101010101010; + tst_opcode = LOGIC_NEGT; #1 - assert(result == 16'b0101010101010101) - else $error("Expected: 16'b0101010101010101, got: %d", result); + assert(tst_result == 16'b0101010101010101) + else $error("Expected: 16'b0101010101010101, got: %d", tst_result); #1 // zero - tests - zx = 1; - sw = 0; + tst_zero_x = 1; + tst_swap_operands = 0; // back to logic - u = 0; - in1 = 2; - in2 = 4; - opcode = LOGIC_OR; + tst_is_arith_nlogic = 0; + tst_in1 = 2; + tst_in2 = 4; + tst_opcode = LOGIC_OR; #1 - assert(result == 4) - else $error("Expected 4, got %d", result); + assert(tst_result == 4) + else $error("Expected 4, got %d", tst_result); #1 // back to arith - u = 1; - in1 = 2; - in2 = 4; - opcode = ARITH_PLUS; + tst_is_arith_nlogic = 1; + tst_in1 = 2; + tst_in2 = 4; + tst_opcode = ARITH_PLUS; #1 - assert(result == 4) - else $error("Expected 4, got %d", result); + assert(tst_result == 4) + else $error("Expected 4, got %d", tst_result); #1 // swap tests - zx = 0; - sw = 1; - u = 1; - in1 = 2; - in2 = 3; - opcode = ARITH_MINUS; + tst_zero_x = 0; + tst_swap_operands = 1; + tst_is_arith_nlogic = 1; + tst_in1 = 2; + tst_in2 = 3; + tst_opcode = ARITH_MINUS; #1 // 3 - 2 - assert(result == 1) - else $error("Expected 1, got %d", result); + assert(tst_result == 1) + else $error("Expected 1, got %d", tst_result); // zero-swap - zx = 1; - sw = 1; - u = 1; - in1 = 2; - in2 = 3; - opcode = ARITH_PLUS; + tst_zero_x = 1; + tst_swap_operands = 1; + tst_is_arith_nlogic = 1; + tst_in1 = 2; + tst_in2 = 3; + tst_opcode = ARITH_PLUS; #1 // 2 + 0 - assert(result == 2) - else $error("Expected 2, got %d", result); + assert(tst_result == 2) + else $error("Expected 2, got %d", tst_result); $finish(); end diff --git a/nandgame/arith_unit.sv b/nandgame/arith_unit.sv index e0254aa..53ea17e 100644 --- a/nandgame/arith_unit.sv +++ b/nandgame/arith_unit.sv @@ -10,20 +10,24 @@ module arith_unit #( parameter DATA_WIDTH = 16 ) ( - input [(DATA_WIDTH-1):0] X, - input [(DATA_WIDTH-1):0] Y, - input ArithCode operation, - - output logic [(DATA_WIDTH-1):0] RES + // first operand + input [(DATA_WIDTH-1):0] X_in, + // second operand + input [(DATA_WIDTH-1):0] Y_in, + // opcode, see ArithCode + input ArithCode arith_operation_in, + + // result of operation + output logic [(DATA_WIDTH-1):0] result_out ); always_comb begin - case (operation) - ARITH_PLUS: RES = X + Y; - ARITH_MINUS: RES = X - Y; - ARITH_INC: RES = X + 1; - ARITH_DEC: RES = X - 1; - default: RES = 0; + case (arith_operation_in) + ARITH_PLUS: result_out = X_in + Y_in; + ARITH_MINUS: result_out = X_in - Y_in; + ARITH_INC: result_out = X_in + 1; + ARITH_DEC: result_out = X_in - 1; + default: result_out = 0; endcase end diff --git a/nandgame/arith_unit_tb.sv b/nandgame/arith_unit_tb.sv index 917a113..4c2a588 100644 --- a/nandgame/arith_unit_tb.sv +++ b/nandgame/arith_unit_tb.sv @@ -4,16 +4,16 @@ module arith_unit_tb; -logic [15:0] in1; -logic [15:0] in2; -ArithCode opcode; -logic [15:0] result; +logic [15:0] tst_in1; +logic [15:0] tst_in2; +ArithCode tst_opcode; +logic [15:0] tst_result; arith_unit uut ( - .X(in1), - .Y(in2), - .operation(opcode), - .RES(result) + .X_in(tst_in1), + .Y_in(tst_in2), + .arith_operation_in(tst_opcode), + .result_out(tst_result) ); string filename; @@ -28,41 +28,41 @@ initial begin end initial begin - in1 = 13; - in2 = 17; - opcode = ARITH_PLUS; + tst_in1 = 13; + tst_in2 = 17; + tst_opcode = ARITH_PLUS; #1 - assert(result == 30); + assert(tst_result == 30); #1 - in1 = 12; - in2 = 4; - opcode = ARITH_MINUS; + tst_in1 = 12; + tst_in2 = 4; + tst_opcode = ARITH_MINUS; #1 - assert(result == 8); + assert(tst_result == 8); #1 - in1 = 12; - in2 = 13; - opcode = ARITH_MINUS; + tst_in1 = 12; + tst_in2 = 13; + tst_opcode = ARITH_MINUS; #1 - assert(result == 16'hffff); + assert(tst_result == 16'hffff); #1 - in1 = 13; - in2 = 17; - opcode = ARITH_INC; + tst_in1 = 13; + tst_in2 = 17; + tst_opcode = ARITH_INC; #1 - assert(result == 14); + assert(tst_result == 14); #1 - in1 = 13; - in2 = 17; - opcode = ARITH_DEC; + tst_in1 = 13; + tst_in2 = 17; + tst_opcode = ARITH_DEC; #1 - assert(result == 12); + assert(tst_result == 12); #1 - in1 = 0; - in2 = 17; - opcode = ARITH_DEC; + tst_in1 = 0; + tst_in2 = 17; + tst_opcode = ARITH_DEC; #1 - assert(result == 16'hffff); + assert(tst_result == 16'hffff); #1 $finish(); end diff --git a/nandgame/comb_mem.sv b/nandgame/comb_mem.sv index dcda331..c7fda32 100644 --- a/nandgame/comb_mem.sv +++ b/nandgame/comb_mem.sv @@ -10,51 +10,54 @@ module comb_mem #( parameter DATA_WIDTH = 16 ) ( // store to A register - input a_i, + input store_to_a_in, // store to D register - input d_i, + input store_to_d_in, // store to address in memory pointed to by A (currently) - input pa_i, + input store_to_pa_in, // value to store - input [(DATA_WIDTH-1):0] X, - // nandgame updates on falling edge - input wire cl, - - output reg [(DATA_WIDTH-1):0] A_o, - output reg [(DATA_WIDTH-1):0] D_o, - output reg [(DATA_WIDTH-1):0] pA_o + input [(DATA_WIDTH-1):0] X_in, + // output registers updated on falling edge + input wire clk_in, + + // content of A register + output reg [(DATA_WIDTH-1):0] reg_A_out, + // content of D register + output reg [(DATA_WIDTH-1):0] reg_D_out, + // content memory pointed to by A register + output reg [(DATA_WIDTH-1):0] reg_pA_out ); -wire inv_clk; +wire inv_clk_int; // my hw uses posedge, nandgame uses negedge. -assign inv_clk = ~cl; +assign inv_clk_int = ~clk_in; my_mem #( .DATA_WIDTH(DATA_WIDTH), // limit memory .DATA_DEPTH(1024) ) nand_memory ( - .clk_i(inv_clk), - .write_en_i(pa_i), + .clk_i(inv_clk_int), + .write_en_i(store_to_pa_in), .read_en_i(1'b1), - .r_read_addr(A_o), - .r_write_addr(A_o), - .data_o(pA_o), - .data_i(X) + .r_read_addr(reg_A_out), + .r_write_addr(reg_A_out), + .data_o(reg_pA_out), + .data_i(X_in) ); initial begin - A_o = 0; - D_o = 0; + reg_A_out = 0; + reg_D_out = 0; end -always @(negedge cl) begin - if (a_i) - A_o <= X; +always @(negedge clk_in) begin + if (store_to_a_in) + reg_A_out <= X_in; - if (d_i) - D_o <= X; + if (store_to_d_in) + reg_D_out <= X_in; end endmodule diff --git a/nandgame/comb_mem_tb.sv b/nandgame/comb_mem_tb.sv index 66a5e64..a5646b8 100644 --- a/nandgame/comb_mem_tb.sv +++ b/nandgame/comb_mem_tb.sv @@ -2,20 +2,20 @@ module comb_mem_tb; -reg clk_i; -logic wa, wd, wpa; -logic [15:0] o_a, o_d, o_pa; -logic [15:0] X; +reg tst_clk; +logic tst_write_A, tst_write_D, tst_write_pA; +logic [15:0] tst_reg_A, tst_reg_D, tst_reg_pA; +logic [15:0] tst_X; comb_mem uut ( - .cl(clk_i), - .a_i(wa), - .d_i(wd), - .pa_i(wpa), - .A_o(o_a), - .D_o(o_d), - .pA_o(o_pa), - .X(X) + .clk_in(tst_clk), + .store_to_a_in(tst_write_A), + .store_to_d_in(tst_write_D), + .store_to_pa_in(tst_write_pA), + .reg_A_out(tst_reg_A), + .reg_D_out(tst_reg_D), + .reg_pA_out(tst_reg_pA), + .X_in(tst_X) ); string filename; @@ -27,25 +27,25 @@ initial begin `endif $dumpfile(filename); $dumpvars(); - clk_i = 0; - wa = 0; wd = 0; wpa = 0; - X = 16'h55; + tst_clk = 0; + tst_write_A = 0; tst_write_D = 0; tst_write_pA = 0; + tst_X = 16'h55; end -always #10 clk_i = ~clk_i; +always #10 tst_clk = ~tst_clk; initial begin - repeat(3) @(posedge clk_i); - wa = 1; - repeat(3) @(posedge clk_i); - wa = 0; - wd = 1; - repeat(3) @(posedge clk_i); - wd = 0; - wpa = 1; - X = 16'haa; - repeat(3) @(posedge clk_i); + repeat(3) @(posedge tst_clk); + tst_write_A = 1; + repeat(3) @(posedge tst_clk); + tst_write_A = 0; + tst_write_D = 1; + repeat(3) @(posedge tst_clk); + tst_write_D = 0; + tst_write_pA = 1; + tst_X = 16'haa; + repeat(3) @(posedge tst_clk); $finish(); end diff --git a/nandgame/computer.sv b/nandgame/computer.sv index acb9bbd..0be2a11 100644 --- a/nandgame/computer.sv +++ b/nandgame/computer.sv @@ -1,3 +1,5 @@ +// represents the final nandgame computer + `timescale 1us/1us `include "../my_mem.v" @@ -6,69 +8,69 @@ `include "counter.sv" module computer ( - input clk_i + input clk_in ); -wire nclk; -assign nclk = ~clk_i; +wire nclk_int; +assign nclk_int = ~clk_in; -logic [15:0] PC_addr; -logic [15:0] PC_content; +logic [15:0] PC_addr_int; +logic [15:0] PC_content_int; my_mem #( .DATA_WIDTH(16) ) ROM ( - .clk_i(nclk), + .clk_i(nclk_int), .write_en_i(0), .read_en_i(1), - .r_read_addr(PC_addr), + .r_read_addr(PC_addr_int), .r_write_addr(0), .data_i(0), - .data_o(PC_content) + .data_o(PC_content_int) ); -logic [15:0] out_A, out_D, out_pA; -logic in_store_A, in_store_D, in_store_pA; -logic [15:0] CPU_RES; +logic [15:0] reg_A_int, reg_D_int, reg_pA_int; +logic store_to_A_int, store_to_D_int, store_to_pA_int; +logic [15:0] result_int; comb_mem #( .DATA_WIDTH(16) ) RAM ( - .cl(clk_i), + .clk_in(clk_in), - .A_o(out_A), - .D_o(out_D), - .pA_o(out_pA), + .reg_A_out(reg_A_int), + .reg_D_out(reg_D_int), + .reg_pA_out(reg_pA_int), - .a_i(in_store_A), - .d_i(in_store_D), - .pa_i(in_store_pA), + .store_to_a_in(store_to_A_int), + .store_to_d_in(store_to_D_int), + .store_to_pa_in(store_to_pA_int), - .X(CPU_RES) + .X_in(result_int) ); -logic cpu_jump; +logic cpu_do_jump_int; instruction_decode CPU ( - .instruction(PC_content), - .do_jump(cpu_jump), + .instruction_in(PC_content_int), + .do_jump_out(cpu_do_jump_int), - .dst_a(in_store_A), - .dst_d(in_store_D), - .dst_pa(in_store_pA), + .dst_A_out(store_to_A_int), + .dst_D_out(store_to_D_int), + .dst_pA_out(store_to_pA_int), - .A_i(out_A), - .D_i(out_D), - .pA_i(out_pA), + .A_in(reg_A_int), + .D_in(reg_D_int), + .pA_in(reg_pA_int), - .RES(CPU_RES) + .result_out(result_int) ); counter PC ( - .cl(clk_i), - .count(PC_addr), - .X(out_A), - .st(cpu_jump) + .clk_in(clk_in), + .counter_out(PC_addr_int), + .X_in(reg_A_int), + .st_store_X_in(cpu_do_jump_int) ); endmodule diff --git a/nandgame/cond_check.sv b/nandgame/cond_check.sv index d5344ba..3961313 100644 --- a/nandgame/cond_check.sv +++ b/nandgame/cond_check.sv @@ -8,20 +8,28 @@ module cond_check #( parameter DATA_WIDTH = 16 ) ( - input [(DATA_WIDTH-1):0] X, - input wire ltz, - input wire eqz, - input wire gtz, - output wire res + // operand + input [(DATA_WIDTH-1):0] X_in, + // check whether operand < 0 + input wire check_ltz_in, + // check whether operand == 0 + input wire check_eqz_in, + // check whether operand > 0 + input wire check_gtz_in, + + // result of check + output wire result_out ); -wire ltr, eqr, gtr, greater_zero; -assign greater_zero = X[(DATA_WIDTH - 1)] == 0; -assign ltr = ltz && !greater_zero; -assign gtr = gtz && greater_zero && !(X == 0); -assign eqr = eqz && (X == 0); +wire is_neg_int; +assign is_neg_int = X_in[(DATA_WIDTH - 1)] == 1; + +wire ltz_result_int, eqz_result_int, gtz_result_int; +assign ltz_result_int = check_ltz_in && is_neg_int; +assign gtz_result_int = check_gtz_in && !is_neg_int && !(X_in == 0); +assign eqz_result_int = check_eqz_in && (X_in == 0); -assign res = ltr || gtr || eqr; +assign result_out = ltz_result_int || gtz_result_int || eqz_result_int; endmodule diff --git a/nandgame/cond_check_tb.sv b/nandgame/cond_check_tb.sv index a7a22dc..e38bd44 100644 --- a/nandgame/cond_check_tb.sv +++ b/nandgame/cond_check_tb.sv @@ -4,16 +4,16 @@ module cond_check_tb; -logic [15:0] in1; -logic ltz, gtz, eqz; -logic res; +logic [15:0] tst_in1; +logic tst_check_ltz, tst_check_gtz, tst_check_eqz; +logic tst_result; cond_check uut ( - .X(in1), - .ltz(ltz), - .gtz(gtz), - .eqz(eqz), - .res(res) + .X_in(tst_in1), + .check_ltz_in(tst_check_ltz), + .check_gtz_in(tst_check_gtz), + .check_eqz_in(tst_check_eqz), + .result_out(tst_result) ); string filename; @@ -29,88 +29,88 @@ end bit exp_res; initial begin - eqz = 0; gtz = 0; ltz = 0; in1 = 0; + tst_check_eqz = 0; tst_check_gtz = 0; tst_check_ltz = 0; tst_in1 = 0; #1 exp_res = 0; - assert(res == exp_res) - else $error("Expected %d, but got %d", exp_res, res); + assert(tst_result == exp_res) + else $error("Expected %d, but got %d", exp_res, tst_result); #1 - eqz = 0; gtz = 0; ltz = 1; in1 = 0; + tst_check_eqz = 0; tst_check_gtz = 0; tst_check_ltz = 1; tst_in1 = 0; #1 exp_res = 0; - assert(res == exp_res) - else $error("Expected %d, but got %d", exp_res, res); + assert(tst_result == exp_res) + else $error("Expected %d, but got %d", exp_res, tst_result); #1 - eqz = 0; gtz = 1; ltz = 0; in1 = 0; + tst_check_eqz = 0; tst_check_gtz = 1; tst_check_ltz = 0; tst_in1 = 0; #1 exp_res = 0; - assert(res == exp_res) - else $error("Expected %d, but got %d", exp_res, res); + assert(tst_result == exp_res) + else $error("Expected %d, but got %d", exp_res, tst_result); #1 - eqz = 1; gtz = 0; ltz = 0; in1 = 0; + tst_check_eqz = 1; tst_check_gtz = 0; tst_check_ltz = 0; tst_in1 = 0; #1 exp_res = 1; - assert(res == exp_res) - else $error("Expected %d, but got %d", exp_res, res); + assert(tst_result == exp_res) + else $error("Expected %d, but got %d", exp_res, tst_result); #1 - eqz = 0; gtz = 0; ltz = 0; in1 = 1; + tst_check_eqz = 0; tst_check_gtz = 0; tst_check_ltz = 0; tst_in1 = 1; #1 exp_res = 0; - assert(res == exp_res) - else $error("Expected %d, but got %d", exp_res, res); + assert(tst_result == exp_res) + else $error("Expected %d, but got %d", exp_res, tst_result); #1 - eqz = 0; gtz = 0; ltz = 1; in1 = 1; + tst_check_eqz = 0; tst_check_gtz = 0; tst_check_ltz = 1; tst_in1 = 1; #1 exp_res = 0; - assert(res == exp_res) - else $error("Expected %d, but got %d", exp_res, res); + assert(tst_result == exp_res) + else $error("Expected %d, but got %d", exp_res, tst_result); #1 - eqz = 0; gtz = 1; ltz = 0; in1 = 1; + tst_check_eqz = 0; tst_check_gtz = 1; tst_check_ltz = 0; tst_in1 = 1; #1 exp_res = 1; - assert(res == exp_res) - else $error("Expected %d, but got %d", exp_res, res); + assert(tst_result == exp_res) + else $error("Expected %d, but got %d", exp_res, tst_result); #1 - eqz = 1; gtz = 0; ltz = 0; in1 = 1; + tst_check_eqz = 1; tst_check_gtz = 0; tst_check_ltz = 0; tst_in1 = 1; #1 exp_res = 0; - assert(res == exp_res) - else $error("Expected %d, but got %d", exp_res, res); + assert(tst_result == exp_res) + else $error("Expected %d, but got %d", exp_res, tst_result); #1 - eqz = 0; gtz = 0; ltz = 0; in1 = -1; + tst_check_eqz = 0; tst_check_gtz = 0; tst_check_ltz = 0; tst_in1 = -1; #1 exp_res = 0; - assert(res == exp_res) - else $error("Expected %d, but got %d", exp_res, res); + assert(tst_result == exp_res) + else $error("Expected %d, but got %d", exp_res, tst_result); #1 - eqz = 0; gtz = 0; ltz = 1; in1 = -1; + tst_check_eqz = 0; tst_check_gtz = 0; tst_check_ltz = 1; tst_in1 = -1; #1 exp_res = 1; - assert(res == exp_res) - else $error("Expected %d, but got %d", exp_res, res); + assert(tst_result == exp_res) + else $error("Expected %d, but got %d", exp_res, tst_result); #1 - eqz = 0; gtz = 1; ltz = 0; in1 = -1; + tst_check_eqz = 0; tst_check_gtz = 1; tst_check_ltz = 0; tst_in1 = -1; #1 exp_res = 0; - assert(res == exp_res) - else $error("Expected %d, but got %d", exp_res, res); + assert(tst_result == exp_res) + else $error("Expected %d, but got %d", exp_res, tst_result); #1 - eqz = 1; gtz = 0; ltz = 0; in1 = -1; + tst_check_eqz = 1; tst_check_gtz = 0; tst_check_ltz = 0; tst_in1 = -1; #1 exp_res = 0; - assert(res == exp_res) - else $error("Expected %d, but got %d", exp_res, res); + assert(tst_result == exp_res) + else $error("Expected %d, but got %d", exp_res, tst_result); #1 $finish(); diff --git a/nandgame/counter.sv b/nandgame/counter.sv index 78f054e..988d123 100644 --- a/nandgame/counter.sv +++ b/nandgame/counter.sv @@ -5,46 +5,47 @@ module counter #( parameter DATA_WIDTH = 16 ) ( - input [(DATA_WIDTH-1):0] X, - input wire st, - // probably opposed to nandgame, - // which "stores" on rising clock - // and "outputs" on falling clock, - // use "regular" stuff??? - input wire cl, - output wire [(DATA_WIDTH-1):0] count + // input / value to store in counter + input [(DATA_WIDTH-1):0] X_in, + // whether to store input (else increment) + input wire st_store_X_in, + // clock + input wire clk_in, + + // counter value + output wire [(DATA_WIDTH-1):0] counter_out ); /* A counter component increments a 16-bit number for each clock cycle. -If st (store) is 1, then the input value X is used as the new counter value. +If st_store_X_in (store) is 1, then the input value X_in is used as the new counter value. -If st is 0, then the previous counter value is incremented by 1. +If st_store_X_in is 0, then the previous counter value is incremented by 1. -The counter output changes when cl (clock signal) changes to 0. +The counter output changes when clk_in (clock signal) changes to 0. Input Effect -st cl +st_store_X_in clk_in 0 0 set next to output + 1 -1 0 set next to X +1 0 set next to X_in -output is the current output of the component. next becomes the current output when cl changes to 0. +output is the current output of the component. next becomes the current output when clk_in changes to 0. */ -reg [(DATA_WIDTH-1):0] r_ctr; +reg [(DATA_WIDTH-1):0] counter_int; initial begin - r_ctr = 0; + counter_int = 0; end -always @(negedge cl) begin - if (st) - r_ctr <= X; +always @(negedge clk_in) begin + if (st_store_X_in) + counter_int <= X_in; else - r_ctr <= r_ctr + 1; + counter_int <= counter_int + 1; end -assign count = r_ctr; +assign counter_out = counter_int; endmodule diff --git a/nandgame/counter_tb.sv b/nandgame/counter_tb.sv index a7fab85..1603a31 100644 --- a/nandgame/counter_tb.sv +++ b/nandgame/counter_tb.sv @@ -2,14 +2,14 @@ module counter_tb; -logic clk_i, store; -logic [15:0] in, res; +logic tst_clk, tst_store_X; +logic [15:0] tst_in_X, tst_result; counter uut ( - .cl(clk_i), - .X(in), - .count(res), - .st(store) + .clk_in(tst_clk), + .X_in(tst_in_X), + .counter_out(tst_result), + .st_store_X_in(tst_store_X) ); string filename; @@ -20,27 +20,27 @@ initial begin filename="counter.lxt2"; `endif $dumpfile(filename); $dumpvars(); - clk_i = 0; - store = 0; - in = 0; + tst_clk = 0; + tst_store_X = 0; + tst_in_X = 0; end -always #10 clk_i = ~clk_i; +always #10 tst_clk = ~tst_clk; initial begin #200 - @(posedge clk_i); - store = 1; - in = 16'd834; + @(posedge tst_clk); + tst_store_X = 1; + tst_in_X = 16'd834; repeat(3) begin - @(posedge clk_i); - assert (res == 834) - else $error("Expected 834, got %d", res); + @(posedge tst_clk); + assert (tst_result == 834) + else $error("Expected 834, got %d", tst_result); end - store = 0; - @(posedge clk_i); - assert (res == 835) - else $error("Expected 835, got %d", res); + tst_store_X = 0; + @(posedge tst_clk); + assert (tst_result == 835) + else $error("Expected 835, got %d", tst_result); #30 $finish(); diff --git a/nandgame/instruction_decode.sv b/nandgame/instruction_decode.sv index 5bf4b02..25c3185 100644 --- a/nandgame/instruction_decode.sv +++ b/nandgame/instruction_decode.sv @@ -11,62 +11,73 @@ module instruction_decode #( parameter DATA_WIDTH = 16 ) ( - input [15:0] instruction, + // instruction to decode + input [15:0] instruction_in, - input [(DATA_WIDTH-1):0] A_i, - input [(DATA_WIDTH-1):0] D_i, - input [(DATA_WIDTH-1):0] pA_i, + // 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, - output [(DATA_WIDTH-1):0] RES, - output do_jump, + // result of operation + output [(DATA_WIDTH-1):0] result_out, + // whether a jump should occur + output do_jump_out, - output dst_a, - output dst_d, - output dst_pa + // 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 ); -wire is_immediate; -// bit 15 set = ALU instruction +wire is_immediate_int; +// bit 15 set = ALU instruction_in // bit 15 unset = immediate -assign is_immediate = !instruction[15]; +assign is_immediate_int = !instruction_in[15]; -assign dst_a = is_immediate || instruction[5]; -assign dst_d = !is_immediate && instruction[4]; -assign dst_pa = !is_immediate && instruction[3]; +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_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 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_res; +wire [(DATA_WIDTH-1):0] alu_result_int; 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) + .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 result_jump; +wire jump_result_int; cond_check #( .DATA_WIDTH(DATA_WIDTH) ) my_cond ( - .X(alu_res), - .ltz(instruction[2]), - .eqz(instruction[1]), - .gtz(instruction[0]), - .res(result_jump) + .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 = is_immediate ? 0 : result_jump; - -assign RES = is_immediate ? instruction : alu_res; +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 diff --git a/nandgame/instruction_decode_tb.sv b/nandgame/instruction_decode_tb.sv new file mode 100644 index 0000000..8f5cfc6 --- /dev/null +++ b/nandgame/instruction_decode_tb.sv @@ -0,0 +1,47 @@ +`timescale 1us/1us + +module instruction_decode_tb; + +logic [15:0] tst_instruction, tst_result; +logic tst_destination_A, tst_destination_D, tst_destination_pA; +logic [15:0] tst_data_A, tst_data_D, tst_data_pA; +logic tst_should_jump; + +instruction_decode uut ( + .instruction_in(tst_instruction), + .dst_A_out(tst_destination_A), + .dst_D_out(tst_destination_D), + .dst_pA_out(tst_destination_pA), + .A_in(tst_data_A), + .D_in(tst_data_D), + .pA_in(tst_data_pA), + .result_out(tst_result), + .do_jump_out(tst_should_jump) +); + +string filename; +initial begin +`ifdef DUMP_FILE_NAME + filename=`DUMP_FILE_NAME; +`else + filename="instruction_decode.lxt2"; +`endif + $dumpfile(filename); $dumpvars(); +end + +initial begin + #10 + tst_instruction = 0; + tst_data_A = 0; + tst_data_D = 0; + tst_data_pA = 0; + #1 + assert(tst_result==0); + assert(tst_destination_A == 0); + assert(tst_destination_D == 0); + assert(tst_destination_pA == 0); + assert(tst_should_jump == 0); + $finish(); +end + +endmodule diff --git a/nandgame/instruction_decode_tb.v b/nandgame/instruction_decode_tb.v deleted file mode 100644 index e68d63b..0000000 --- a/nandgame/instruction_decode_tb.v +++ /dev/null @@ -1,37 +0,0 @@ -`timescale 1us/1us - -module instruction_decode_tb; - -logic [15:0] INS, RES; -logic dst_A, dst_D, dst_pA; -logic [15:0] data_A, data_D, data_pA; -logic do_jump; - -instruction_decode uut ( - .instruction(INS), - .dst_a(dst_A), - .dst_d(dst_D), - .dst_pa(dst_pA), - .A_i(data_A), - .D_i(data_D), - .pA_i(data_pA), - .RES(RES), - .do_jump(do_jump) -); - -string filename; -initial begin -`ifdef DUMP_FILE_NAME - filename=`DUMP_FILE_NAME; -`else - filename="instruction_decode.lxt2"; -`endif - $dumpfile(filename); $dumpvars(); -end - -initial begin - #10 - $finish(); -end - -endmodule diff --git a/nandgame/logic_unit.sv b/nandgame/logic_unit.sv index 89fe8fb..68f5c23 100644 --- a/nandgame/logic_unit.sv +++ b/nandgame/logic_unit.sv @@ -10,28 +10,32 @@ module logic_unit #( parameter DATA_WIDTH = 16 ) ( - input [(DATA_WIDTH-1):0] X, - input [(DATA_WIDTH-1):0] Y, - input LogicCode operation, - - output logic [(DATA_WIDTH-1):0] RES + // first operand + input [(DATA_WIDTH-1):0] X_in, + // second operand + input [(DATA_WIDTH-1):0] Y_in, + // opcode, see LogicCode + input LogicCode logic_operation_in, + + // result of operation + output logic [(DATA_WIDTH-1):0] result_out ); // learning: instead of this nested ternary... -// assign RES = operation == LOGIC_AND ? (X & Y) : -// operation == LOGIC_OR ? (X | Y) : -// operation == LOGIC_XOR ? (X ^ Y) : -// operation == LOGIC_NEGT ? (~X) : 0; +// assign result_out = logic_operation_in == LOGIC_AND ? (X_in & Y_in) : +// logic_operation_in == LOGIC_OR ? (X_in | Y_in) : +// logic_operation_in == LOGIC_XOR ? (X_in ^ Y_in) : +// logic_operation_in == LOGIC_NEGT ? (~X_in) : 0; // ... you can do this: always_comb begin - case (operation) - LOGIC_AND: RES = X & Y; - LOGIC_OR: RES = X | Y; - LOGIC_XOR: RES = X ^ Y; - LOGIC_NEGT: RES = ~X; - default: RES = 0; + case (logic_operation_in) + LOGIC_AND: result_out = X_in & Y_in; + LOGIC_OR: result_out = X_in | Y_in; + LOGIC_XOR: result_out = X_in ^ Y_in; + LOGIC_NEGT: result_out = ~X_in; + default: result_out = 0; endcase end diff --git a/nandgame/logic_unit_tb.sv b/nandgame/logic_unit_tb.sv index 3f50ce2..95211c1 100644 --- a/nandgame/logic_unit_tb.sv +++ b/nandgame/logic_unit_tb.sv @@ -4,16 +4,15 @@ module logic_unit_tb; -logic [15:0] in1; -logic [15:0] in2; -LogicCode opcode; -logic [15:0] result; +logic [15:0] tst_in1, tst_in2; +LogicCode tst_opcode; +logic [15:0] tst_result; logic_unit uut ( - .X(in1), - .Y(in2), - .operation(opcode), - .RES(result) + .X_in(tst_in1), + .Y_in(tst_in2), + .logic_operation_in(tst_opcode), + .result_out(tst_result) ); string filename; @@ -28,28 +27,28 @@ initial begin end initial begin - in1 = 16'b1010; - in2 = 16'b1100; - opcode = LOGIC_AND; + tst_in1 = 16'b1010; + tst_in2 = 16'b1100; + tst_opcode = LOGIC_AND; #1 - assert(result == 16'b1000); + assert(tst_result == 16'b1000); #1 - in1 = 16'b1010; - in2 = 16'b1100; - opcode = LOGIC_OR; + tst_in1 = 16'b1010; + tst_in2 = 16'b1100; + tst_opcode = LOGIC_OR; #1 - assert(result == 16'b1110); + assert(tst_result == 16'b1110); #1 - in1 = 16'b1010; - in2 = 16'b1100; - opcode = LOGIC_XOR; + tst_in1 = 16'b1010; + tst_in2 = 16'b1100; + tst_opcode = LOGIC_XOR; #1 - assert(result == 16'b0110); + assert(tst_result == 16'b0110); #1 - in1 = 16'b1010101010101010; - opcode = LOGIC_NEGT; + tst_in1 = 16'b1010101010101010; + tst_opcode = LOGIC_NEGT; #1 - assert(result == 16'b0101010101010101); + assert(tst_result == 16'b0101010101010101); #1 $finish(); end -- cgit v1.2.3