diff options
| -rw-r--r-- | atk16_fpga/cu.v | 374 | ||||
| -rw-r--r-- | atk16_fpga/cu_tb.v | 473 | ||||
| -rw-r--r-- | atk16_fpga/mem_fsm.v | 23 | ||||
| -rw-r--r-- | atk16_fpga/mem_fsm_tb.v | 32 |
4 files changed, 824 insertions, 78 deletions
diff --git a/atk16_fpga/cu.v b/atk16_fpga/cu.v index 915ce8e..13bc804 100644 --- a/atk16_fpga/cu.v +++ b/atk16_fpga/cu.v @@ -16,9 +16,10 @@ // R = right operand register select // I = immediate operand // S = ALU operation select +// F = flag select // A = absolute (1) / relative (0) addressing -// D = direct (1) / indirect (0) load -// M = immediate mode (1) / register mode (0) +// D = direct (1) / indirect (0) load/store +// X = unused // ALR (arithmetic-logic, register) // 0000 TTTL LLRR RSSS @@ -30,15 +31,41 @@ // 0010 TTTR RRXX XXAD `define OP_LDR 4'b0010 // STR (store to memory) -// 0011 XXXL LLRR RMAD +// 0011 XXXL LLRR RXAD `define OP_STR 4'b0011 // LDI (load by immediate) -// 0100 TTTD IIII IIII +// 0100 TTTI IIII IIAD `define OP_LDI 4'b0100 +// JPR (jump by register) +// 0101 ADRR RXXX XXXX +`define OP_JPR 4'b0101 +// JPI (jump by immediate) +// 0110 ADII IIII IIII +`define OP_JPI 4'b0110 +// BRR (branch by register) +// 0111 ADFF RRRX XXXX +`define OP_BRR 4'b0111 +// BRI (branch by immediate) +// 1000 ADFF IIII IIII +`define OP_BRI 4'b1000 +// LPC (load PC+1) +// 1001 TTTX XXXX XXXX +`define OP_LPC 4'b1001 +// RTI (return from interrupt) +// 1010 XXXX XXXX XXXX +`define OP_RTI 4'b1010 +`define OP_NOP1 4'b1011 +`define OP_NOP2 4'b1100 +`define OP_NOP3 4'b1101 +`define OP_NOP4 4'b1110 +// HLT (halt) +// 1111 XXXX XXXX XXXX +`define OP_HLT 4'b1111 module cu( input wire clk, - input wire rst + input wire rst, + input wire [3:0] int_lines ); reg [2:0] alu_sel; reg [15:0] alu_a; @@ -50,6 +77,12 @@ module cu( reg [2:0] phase = `PH_RESET; reg [15:0] pc; reg [15:0] ir; + reg halted = 0; + + // interrupts + reg [15:0] int_pc; + reg [3:0] int_line_regs; + reg int_en = 1; reg [15:0] mem_addr; reg [15:0] mem_data_in; @@ -85,11 +118,44 @@ module cu( assign rg = regbank[6]; assign rh = regbank[7]; + always @(posedge int_lines[0]) int_line_regs[0] <= int_lines[0]; + always @(posedge int_lines[1]) int_line_regs[1] <= int_lines[1]; + always @(posedge int_lines[2]) int_line_regs[2] <= int_lines[2]; + always @(posedge int_lines[3]) int_line_regs[3] <= int_lines[3]; + integer i; always @(posedge clk or posedge rst) begin // Handle reset button if (rst) begin - phase <= `PH_RESET; + phase <= `PH_RESET; + halted <= 0; + end + + else if (halted) begin + // Do nothing + end + + else if (int_en && int_line_regs != 4'b00) begin + int_en <= 0; + int_pc <= pc; + casez (int_line_regs) + 4'bzzz1: begin + pc <= 16'h10; + int_line_regs[0] <= 0; + end + 4'bzz1z: begin + pc <= 16'h11; + int_line_regs[1] <= 0; + end + 4'bz1zz: begin + pc <= 16'h12; + int_line_regs[2] <= 0; + end + 4'b1zzz: begin + pc <= 16'h13; + int_line_regs[3] <= 0; + end + endcase end else if (phase == `PH_RESET) begin @@ -107,57 +173,258 @@ module cu( // Fetch stage else if (phase == `PH_FETCH) begin mem_read_en <= 1; - mem_write_en <= 0; - mem_addr <= pc; + mem_addr <= pc; if (mem_done) begin mem_read_en <= 0; - mem_write_en <= 0; - ir <= mem_data_out; - phase <= `PH_DECODE; - pc <= pc + 16'd1; + ir <= mem_data_out; + phase <= `PH_DECODE; + pc <= pc + 16'd1; end end // Decode stage else if (phase == `PH_DECODE) begin - phase <= `PH_EXECUTE; - case (ir[15:12]) `OP_ALR: begin alu_sel <= ir[2:0]; // select ALU operation - alu_a <= regbank[ir[8:6]]; // read operand A - alu_b <= regbank[ir[5:3]]; // read operand B + alu_a <= regbank[ir[8:6]]; // read operand A + alu_b <= regbank[ir[5:3]]; // read operand B + phase <= `PH_EXECUTE; end `OP_ALI: begin alu_sel <= ir[2:0]; // select ALU operation - alu_a <= regbank[ir[8:6]]; // read operand A - alu_b <= ir[5:3]; // read immediate operand + alu_a <= regbank[ir[8:6]]; // read operand A + alu_b <= ir[5:3]; // read immediate operand + phase <= `PH_EXECUTE; end `OP_LDR: begin + // ir[1] = A = absolute (1) / relative (0) addressing + // ir[0] = D = direct (1) / indirect (0) store // set target reg value to address, dereference in execute phase - if (ir[1] == 1 && ir[0] == 1) // addressing mode: absolute, direct + if (ir[1] == 1 && ir[0] == 1) begin // addressing mode: absolute, direct decoded_tmp <= regbank[ir[8:6]]; - else if (ir[1] == 0 && ir[0] == 1) // addressing mode: pc relative, direct - decoded_tmp <= regbank[ir[8:6]] + pc - 1; - /*else if (ir[1] == 1 && ir[0] == 0) begin // addressing mode: absolute, indirect - bram_wr <= 0; - bram_rd <= 1; - bram_addr <= regbank[ir[8:6]]; - decoded_tmp <= bram_data_out; + phase <= `PH_EXECUTE; + end + else if (ir[1] == 0 && ir[0] == 1) begin // addressing mode: pc relative, direct + decoded_tmp <= pc + regbank[ir[8:6]] - 1; + phase <= `PH_EXECUTE; + end + else if (ir[1] == 1 && ir[0] == 0) begin // addressing mode: absolute, indirect + mem_read_en <= 1; + mem_addr <= regbank[ir[8:6]]; + + if (mem_done) begin + decoded_tmp <= mem_data_out; + mem_read_en <= 0; + phase <= `PH_EXECUTE; + end end else if (ir[1] == 0 && ir[0] == 0) begin // addressing mode: pc relative, indirect - bram_wr <= 0; - bram_rd <= 1; - bram_addr <= regbank[ir[8:6]] + pc - 1; - decoded_tmp <= bram_data_out; - end*/ + mem_read_en <= 1; + mem_addr <= pc + regbank[ir[8:6]] - 1; + + if (mem_done) begin + decoded_tmp <= mem_data_out; + mem_read_en <= 0; + phase <= `PH_EXECUTE; + end + end end `OP_STR: begin - // ir[2] = M = immediate mode (1) / register mode (0) + // ir[1] = A = absolute (1) / relative (0) addressing + // ir[0] = D = direct (1) / indirect (0) store + // ir[5:3] = data reg + // ir[8:6] = address reg + // decoded_tmp will be the address to write to + if (ir[1] == 1 && ir[0] == 1) begin // addressing mode: absolute, direct + decoded_tmp <= regbank[ir[8:6]]; + phase <= `PH_EXECUTE; + end + else if (ir[1] == 0 && ir[0] == 1) begin // addressing mode: pc relative, direct + decoded_tmp <= pc + regbank[ir[8:6]] - 1; + phase <= `PH_EXECUTE; + end + else if (ir[1] == 1 && ir[0] == 0) begin // addressing mode: absolute, indirect + mem_read_en <= 1; + mem_addr <= regbank[ir[8:6]]; + + if (mem_done) begin + decoded_tmp <= mem_data_out; + mem_read_en <= 0; + phase <= `PH_EXECUTE; + end + end + else if (ir[1] == 0 && ir[0] == 0) begin // addressing mode: pc relative, indirect + mem_read_en <= 1; + mem_addr <= pc + regbank[ir[8:6]] - 1; + + if (mem_done) begin + decoded_tmp <= mem_data_out; + mem_read_en <= 0; + phase <= `PH_EXECUTE; + end + end + end + `OP_LDI: begin // ir[1] = A = absolute (1) / relative (0) addressing // ir[0] = D = direct (1) / indirect (0) load - // TODO + // ir[8:2] = immediate + // ir[11:9] = target reg + if (ir[1] == 1) begin // addressing mode: absolute + decoded_tmp <= ir[8:2]; + end + else if (ir[1] == 0) begin // addressing mode: pc relative + decoded_tmp <= pc + {{9{ir[8]}}, ir[8:2]} - 1; + end + phase <= `PH_EXECUTE; + end + `OP_JPR: begin + // ir[11] = A = absolute (1) / relative (0) addressing + // ir[10] = D = direct (1) / indirect (0) load + // ir[9:6] = address reg + if (ir[11] == 1 && ir[10] == 1) begin // addressing mode: absolute, direct + pc <= regbank[ir[9:6]]; + phase <= `PH_FETCH; + end + else if (ir[11] == 0 && ir[10] == 1) begin // addressing mode: pc relative, direct + pc <= pc + regbank[ir[9:6]] - 1; + phase <= `PH_FETCH; + end + else if (ir[11] == 1 && ir[10] == 0) begin // addressing mode: absolute, indirect + mem_read_en <= 1; + mem_addr <= regbank[ir[9:6]]; + + if (mem_done) begin + pc <= mem_data_out; + mem_read_en <= 0; + phase <= `PH_FETCH; + end + end + else if (ir[11] == 0 && ir[10] == 0) begin // addressing mode: pc relative, indirect + mem_read_en <= 1; + mem_addr <= pc + regbank[ir[9:6]] - 1; + + if (mem_done) begin + pc <= mem_data_out; + mem_read_en <= 0; + phase <= `PH_FETCH; + end + end + end + `OP_JPI: begin + // ir[11] = A = absolute (1) / relative (0) addressing + // ir[10] = D = direct (1) / indirect (0) load + // ir[9:0] = immediate + if (ir[11] == 1 && ir[10] == 1) begin // addressing mode: absolute, direct + pc <= {6'd0, ir[9:0]}; + phase <= `PH_FETCH; + end + else if (ir[11] == 0 && ir[10] == 1) begin // addressing mode: pc relative, direct + pc <= pc + {{6{ir[9]}}, ir[9:0]} - 1; + phase <= `PH_FETCH; + end + else if (ir[11] == 1 && ir[10] == 0) begin // addressing mode: absolute, indirect + mem_read_en <= 1; + mem_addr <= {6'd0, ir[9:0]}; + + if (mem_done) begin + pc <= mem_data_out; + mem_read_en <= 0; + phase <= `PH_FETCH; + end + end + else if (ir[11] == 0 && ir[10] == 0) begin // addressing mode: pc relative, indirect + mem_read_en <= 1; + mem_addr <= pc + {{6{ir[9]}}, ir[9:0]} - 1; + + if (mem_done) begin + pc <= mem_data_out; + mem_read_en <= 0; + phase <= `PH_FETCH; + end + end + end + `OP_BRR: begin + // ir[11] = A = absolute (1) / relative (0) addressing + // ir[10] = direct (1) / indirect (0) branch + // ir[9:8] = flag select + // ir[7:5] = address reg + if (ir[11] == 1 && ir[10] == 1) begin // addressing mode: absolute, direct + decoded_tmp <= regbank[ir[7:5]]; + phase <= `PH_EXECUTE; + end + else if (ir[11] == 0 && ir[10] == 1) begin // addressing mode: pc relative, direct + decoded_tmp <= pc + regbank[ir[7:5]] - 1; + phase <= `PH_EXECUTE; + end + else if (ir[11] == 1 && ir[10] == 0) begin // addressing mode: absolute, indirect + mem_read_en <= 1; + mem_addr <= regbank[ir[7:5]]; + + if (mem_done) begin + decoded_tmp <= mem_data_out; + mem_read_en <= 0; + phase <= `PH_EXECUTE; + end + end + else if (ir[11] == 0 && ir[10] == 0) begin // addressing mode: pc relative, indirect + mem_read_en <= 1; + mem_addr <= pc + regbank[ir[7:5]] - 1; + + if (mem_done) begin + decoded_tmp <= mem_data_out; + mem_read_en <= 0; + phase <= `PH_EXECUTE; + end + end + end + `OP_BRI: begin + // ir[11] = A = absolute (1) / relative (0) addressing + // ir[10] = direct (1) / indirect (0) branch + // ir[9:8] = flag select + // ir[7:0] = immediate + if (ir[11] == 1 && ir[10] == 1) begin // addressing mode: absolute, direct + decoded_tmp <= {8'd0, ir[7:0]}; + phase <= `PH_EXECUTE; + end + else if (ir[11] == 0 && ir[10] == 1) begin // addressing mode: pc relative, direct + decoded_tmp <= pc + {{8{ir[7]}}, ir[7:0]} - 1; + phase <= `PH_EXECUTE; + end + else if (ir[11] == 1 && ir[10] == 0) begin // addressing mode: absolute, indirect + mem_read_en <= 1; + mem_addr <= {8'd0, ir[7:0]}; + + if (mem_done) begin + decoded_tmp <= mem_data_out; + mem_read_en <= 0; + phase <= `PH_EXECUTE; + end + end + else if (ir[11] == 0 && ir[10] == 0) begin // addressing mode: pc relative, indirect + mem_read_en <= 1; + mem_addr <= pc + {{8{ir[7]}}, ir[7:0]} - 1; + + if (mem_done) begin + decoded_tmp <= mem_data_out; + mem_read_en <= 0; + phase <= `PH_EXECUTE; + end + end + end + `OP_LPC: begin + // ir[11:9] = target reg + regbank[ir[11:9]] <= pc; + phase <= `PH_FETCH; + end + `OP_RTI: begin + pc <= int_pc; + int_en <= 1; + phase <= `PH_FETCH; + end + `OP_HLT: begin + halted <= 1; end default: begin `ifdef __SYNTHESIS__ @@ -175,20 +442,53 @@ module cu( phase <= `PH_FETCH; end `OP_LDR: begin - //$display("ir[11:9] %d, reg val: %d, mem_data_out: %d, mem_done: %d\n", ir[11:9], regbank[ir[11:9]], mem_data_out, mem_done); mem_read_en <= 1; - mem_write_en <= 0; mem_addr <= decoded_tmp; if (mem_done) begin regbank[ir[11:9]] <= mem_data_out; // dereference address mem_read_en <= 0; - mem_write_en <= 0; phase <= `PH_FETCH; end end `OP_STR: begin - // TODO + mem_write_en <= 1; + mem_addr <= decoded_tmp; + mem_data_in <= regbank[ir[5:3]]; + + if (mem_done) begin + mem_write_en <= 0; + phase <= `PH_FETCH; + end + end + `OP_LDI: begin + // ir[1] = A = absolute (1) / relative (0) addressing + // ir[0] = D = direct (1) / indirect (0) load + // ir[8:2] = immediate + // ir[11:9] = target reg + // decoded_tmp = immediate value that takes absolute/relative to account + if (ir[0] == 1) begin // direct + regbank[ir[11:9]] <= decoded_tmp; + phase <= `PH_FETCH; + end + else if (ir[0] == 0) begin // indirect + mem_read_en <= 1; + mem_addr <= decoded_tmp; + + if (mem_done) begin + regbank[ir[11:9]] <= mem_data_out; + mem_read_en <= 0; + phase <= `PH_FETCH; + end + end + end + `OP_BRR, `OP_BRI: begin + // ir[9:8] = flag select + // branch if selected flag (0..3) is set (i.e. when anded with flags is non-zero) + if ((1 << ir[9:8]) & alu_flags != 4'd0) begin + pc <= decoded_tmp; + end + phase <= `PH_FETCH; end default: begin `ifdef __SYNTHESIS__ diff --git a/atk16_fpga/cu_tb.v b/atk16_fpga/cu_tb.v index 18a9a37..ce4a21d 100644 --- a/atk16_fpga/cu_tb.v +++ b/atk16_fpga/cu_tb.v @@ -5,16 +5,19 @@ module cu_tb(); reg clk, rst; + reg [3:0] int_lines; cu dut( .clk(clk), - .rst(rst) + .rst(rst), + .int_lines(int_lines) ); // Clock generation always #5 clk = ~clk; // 100 MHz clock reg failed; + reg [15:0] expected; initial begin failed = 0; $dumpfile(`DUMPSTR(`VCD_OUTPUT)); @@ -22,18 +25,36 @@ module cu_tb(); clk = 0; rst = 0; + int_lines = 4'b0000; #10 // Wait for reset phase to finish + // set up halt instruction at PC = 1, used by all tests + dut.mem_fsm_inst.bram_inst.mem[1] = { 4'b1111, 12'd0 }; // HLT + // test ALR dut.regbank[0] = 16'd10; dut.regbank[1] = 16'd20; dut.mem_fsm_inst.bram_inst.mem[0] = { 4'b0000, 3'd2, 3'd0, 3'd1, 3'd0 }; // ALR RC, RA, RB, S=PLUS + expected = 16'd30; - #200 if (dut.regbank[2] == 16'd30) begin + #200 if (dut.regbank[2] == expected) begin $display("\033[0;32m[PASS]\033[0m ALR ok"); end else begin - $display("\033[0;31m[FAIL]\033[0m ALR not working, target reg contains %04h", dut.regbank[2]); + $display("\033[0;31m[FAIL]\033[0m ALR not working, target reg contains %04h, expected %04h", dut.regbank[2], expected); + failed = 1; + end + rst = 1; #10 rst = 0; #10 + + // test ALI + dut.regbank[0] = 16'd10; + dut.mem_fsm_inst.bram_inst.mem[0] = { 4'b0001, 3'd2, 3'd0, 3'd7, 3'd0 }; // ALI RC, RA, 7, S=PLUS + expected = 16'd17; + + #200 if (dut.regbank[2] == expected) begin + $display("\033[0;32m[PASS]\033[0m ALI ok"); + end else begin + $display("\033[0;31m[FAIL]\033[0m ALI not working, target reg contains %04h, expected %04h", dut.regbank[2], expected); failed = 1; end rst = 1; #10 rst = 0; #10 @@ -42,11 +63,12 @@ module cu_tb(); dut.mem_fsm_inst.bram_inst.mem[16'd100] = 16'hffff; dut.regbank[1] = 16'd100; dut.mem_fsm_inst.bram_inst.mem[16'd0] = { 4'b0010, 3'd0, 3'd1, 4'd0, 1'd1, 1'd1 }; // LDR RA, RB, absolute, direct + expected = 16'hffff; - #200 if (dut.regbank[0] == 16'hffff) begin - $display("\033[0;32m[PASS]\033[0m LDR absolute ok"); + #200 if (dut.regbank[0] == expected) begin + $display("\033[0;32m[PASS]\033[0m LDR direct absolute ok"); end else begin - $display("\033[0;31m[FAIL]\033[0m LDR absolute not working, target reg contains %04h", dut.regbank[0]); + $display("\033[0;31m[FAIL]\033[0m LDR direct absolute not working, target reg contains %04h, expected %04h", dut.regbank[0], expected); failed = 1; end rst = 1; #10 rst = 0; #10 @@ -55,16 +77,447 @@ module cu_tb(); dut.mem_fsm_inst.bram_inst.mem[16'd10] = 16'hffff; dut.regbank[1] = 16'd10; dut.mem_fsm_inst.bram_inst.mem[16'd0] = { 4'b0010, 3'd0, 3'd1, 4'd0, 1'd0, 1'd1 }; // LDR RA, RB, relative, direct + expected = 16'hffff; + + #200 if (dut.regbank[0] == expected) begin + $display("\033[0;32m[PASS]\033[0m LDR direct relative ok"); + end else begin + $display("\033[0;31m[FAIL]\033[0m LDR direct relative not working, target reg contains %04h, expected %04h", dut.regbank[0], expected); + failed = 1; + end + rst = 1; #10 rst = 0; #10 + + // test LDR, absolute addressing, indirect + dut.mem_fsm_inst.bram_inst.mem[16'd100] = 16'd200; + dut.mem_fsm_inst.bram_inst.mem[16'd200] = 16'hffff; + dut.regbank[1] = 16'd100; + dut.mem_fsm_inst.bram_inst.mem[16'd0] = { 4'b0010, 3'd0, 3'd1, 4'd0, 1'd1, 1'd0 }; // LDR RA, RB, absolute, indirect + expected = 16'hffff; + + #200 if (dut.regbank[0] == expected) begin + $display("\033[0;32m[PASS]\033[0m LDR indirect absolute ok"); + end else begin + $display("\033[0;31m[FAIL]\033[0m LDR indirect absolute not working, target reg contains %04h, expected %04h", dut.regbank[0], expected); + failed = 1; + end + rst = 1; #10 rst = 0; #10 + + // test LDR, relative addressing, indirect + dut.mem_fsm_inst.bram_inst.mem[16'd10] = 16'd20; + dut.mem_fsm_inst.bram_inst.mem[16'd20] = 16'hffff; + dut.regbank[1] = 16'd10; + dut.mem_fsm_inst.bram_inst.mem[16'd0] = { 4'b0010, 3'd0, 3'd1, 4'd0, 1'd0, 1'd0 }; // LDR RA, RB, relative, indirect + expected = 16'hffff; + + #200 if (dut.regbank[0] == expected) begin + $display("\033[0;32m[PASS]\033[0m LDR indirect relative ok"); + end else begin + $display("\033[0;31m[FAIL]\033[0m LDR indirect relative not working, target reg contains %04h, expected %04h", dut.regbank[0], expected); + failed = 1; + end + rst = 1; #10 rst = 0; #10 + + // test STR, absolute addressing, direct + dut.regbank[0] = 16'hfafa; + dut.regbank[1] = 16'd100; + dut.mem_fsm_inst.bram_inst.mem[16'd0] = { 4'b0011, 3'd0, 3'd1, 4'd0, 1'd1, 1'd1 }; // STR RB, RA, absolute, direct + expected = 16'hfafa; + + #200 if (dut.mem_fsm_inst.bram_inst.mem[16'd100] == expected) begin + $display("\033[0;32m[PASS]\033[0m STR direct absolute ok"); + end else begin + $display("\033[0;31m[FAIL]\033[0m STR direct absolute not working, memory location contains %04h, expected %04h", dut.mem_fsm_inst.bram_inst.mem[16'd100], expected); + failed = 1; + end + rst = 1; #10 rst = 0; #10 + + // test STR, relative addressing, direct + dut.regbank[0] = 16'hafaf; + dut.regbank[1] = 16'd10; + dut.mem_fsm_inst.bram_inst.mem[16'd0] = { 4'b0011, 3'd0, 3'd1, 4'd0, 1'd0, 1'd1 }; // STR RB, RA, relative, direct + expected = 16'hafaf; + + #200 if (dut.mem_fsm_inst.bram_inst.mem[16'd10] == expected) begin + $display("\033[0;32m[PASS]\033[0m STR direct relative ok"); + end else begin + $display("\033[0;31m[FAIL]\033[0m STR direct relative not working, memory location contains %04h, expected %04h", dut.mem_fsm_inst.bram_inst.mem[16'd10], expected); + failed = 1; + end + rst = 1; #10 rst = 0; #10 + + // test STR, absolute addressing, indirect + dut.regbank[0] = 16'hfafa; + dut.regbank[1] = 16'd100; + dut.mem_fsm_inst.bram_inst.mem[16'd100] = 16'd200; + dut.mem_fsm_inst.bram_inst.mem[16'd0] = { 4'b0011, 3'd0, 3'd1, 4'd0, 1'd1, 1'd0 }; // STR RB, RA, absolute, indirect + expected = 16'hfafa; + + #200 if (dut.mem_fsm_inst.bram_inst.mem[16'd200] == expected) begin + $display("\033[0;32m[PASS]\033[0m STR indirect absolute ok"); + end else begin + $display("\033[0;31m[FAIL]\033[0m STR indirect absolute not working, memory location contains %04h, expected %04h", dut.mem_fsm_inst.bram_inst.mem[16'd200], expected); + failed = 1; + end + rst = 1; #10 rst = 0; #10 + + // test STR, relative addressing, indirect + dut.regbank[0] = 16'hafaf; + dut.regbank[1] = -16'd10; + dut.mem_fsm_inst.bram_inst.mem[16'd10] = 16'd20; + dut.mem_fsm_inst.bram_inst.mem[16'd20] = { 4'b0011, 3'd0, 3'd1, 4'd0, 1'd0, 1'd0 }; // STR RB, RA, relative, indirect + dut.pc = 16'd20; + expected = 16'hafaf; + + #200 if (dut.mem_fsm_inst.bram_inst.mem[16'd20] == expected) begin + $display("\033[0;32m[PASS]\033[0m STR indirect relative ok"); + end else begin + $display("\033[0;31m[FAIL]\033[0m STR indirect relative not working, memory location contains %04h, expected %04h", dut.mem_fsm_inst.bram_inst.mem[16'd20], expected); + failed = 1; + end + rst = 1; #10 rst = 0; #10 + + // test LDI, absolute addressing, direct + dut.mem_fsm_inst.bram_inst.mem[16'd0] = { 4'b0100, 3'd0, 7'd123, 1'd1, 1'd1 }; // LDI RA, 1, absolute, direct + expected = 16'd123; + + #200 if (dut.regbank[0] == expected) begin + $display("\033[0;32m[PASS]\033[0m LDI direct absolute ok"); + end else begin + $display("\033[0;31m[FAIL]\033[0m LDI direct absolute not working, target reg contains %04h, expected %04h", dut.regbank[0], expected); + failed = 1; + end + rst = 1; #10 rst = 0; #10 + + // test LDI, relative addressing, direct + dut.mem_fsm_inst.bram_inst.mem[16'd150] = { 4'b0100, 3'd0, -7'd20, 1'd0, 1'd1 }; // LDI RA, 1, relative, direct + dut.pc = 16'd150; + expected = 16'd130; + + #200 if (dut.regbank[0] == expected) begin + $display("\033[0;32m[PASS]\033[0m LDI direct relative ok"); + end else begin + $display("\033[0;31m[FAIL]\033[0m LDI direct relative not working, target reg contains %04h, expected %04h", dut.regbank[0], expected); + failed = 1; + end + rst = 1; #10 rst = 0; #10 + + // test LDI, absolute addressing, indirect + dut.mem_fsm_inst.bram_inst.mem[16'd0] = { 4'b0100, 3'd0, 7'd50, 1'd1, 1'd0 }; // LDI RA, 1, absolute, indirect + dut.mem_fsm_inst.bram_inst.mem[16'd50] = 16'd123; + expected = 16'd123; + + #200 if (dut.regbank[0] == expected) begin + $display("\033[0;32m[PASS]\033[0m LDI indirect absolute ok"); + end else begin + $display("\033[0;31m[FAIL]\033[0m LDI indirect absolute not working, target reg contains %04h, expected %04h", dut.regbank[0], expected); + failed = 1; + end + rst = 1; #10 rst = 0; #10 + + // test LDI, relative addressing, indirect + dut.mem_fsm_inst.bram_inst.mem[16'd150] = { 4'b0100, 3'd0, -7'd20, 1'd0, 1'd0 }; // LDI RA, 1, relative, indirect + dut.mem_fsm_inst.bram_inst.mem[16'd130] = 16'd123; + dut.pc = 16'd150; + expected = 16'd123; + + #200 if (dut.regbank[0] == expected) begin + $display("\033[0;32m[PASS]\033[0m LDI indirect relative ok"); + end else begin + $display("\033[0;31m[FAIL]\033[0m LDI indirect relative not working, target reg contains %04h, expected %04h", dut.regbank[0], expected); + failed = 1; + end + rst = 1; #10 rst = 0; #10 + + // test JPR, absolute addressing, direct + dut.regbank[0] = 16'd100; + dut.mem_fsm_inst.bram_inst.mem[16'd0] = { 4'b0101, 1'd1, 1'd1, 3'd0, 7'd0 }; // JPR RA, absolute, direct + dut.mem_fsm_inst.bram_inst.mem[16'd100] = { 4'b1111, 12'd0 }; // HLT + expected = 16'd101; // PC ends up at &HLT + 1 + + #200 if (dut.pc == expected) begin + $display("\033[0;32m[PASS]\033[0m JPR direct absolute ok"); + end else begin + $display("\033[0;31m[FAIL]\033[0m JPR direct absolute not working, PC contains %04h, expected: %04h", dut.pc, expected); + failed = 1; + end + rst = 1; #10 rst = 0; #10 + + // test JPR, relative addressing, direct + dut.regbank[0] = 16'd50; + dut.mem_fsm_inst.bram_inst.mem[16'd0] = { 4'b0101, 1'd0, 1'd1, 3'd0, 7'd0 }; // JPR RA, relative, direct + dut.mem_fsm_inst.bram_inst.mem[16'd50] = { 4'b1111, 12'd0 }; // HLT + expected = 16'd51; // PC ends up at &HLT + 1 + + #200 if (dut.pc == expected) begin + $display("\033[0;32m[PASS]\033[0m JPR direct relative ok"); + end else begin + $display("\033[0;31m[FAIL]\033[0m JPR direct relative not working, PC contains %04h, expected: %04h", dut.pc, expected); + failed = 1; + end + rst = 1; #10 rst = 0; #10 + + // test JPR, absolute addressing, indirect + dut.regbank[0] = 16'd100; + dut.mem_fsm_inst.bram_inst.mem[16'd100] = 16'd200; + dut.mem_fsm_inst.bram_inst.mem[16'd0] = { 4'b0101, 1'd1, 1'd0, 3'd0, 7'd0 }; // JPR RA, absolute, indirect + dut.mem_fsm_inst.bram_inst.mem[16'd200] = { 4'b1111, 12'd0 }; // HLT + expected = 16'd201; // PC ends up at &HLT + 1 + + #200 if (dut.pc == expected) begin + $display("\033[0;32m[PASS]\033[0m JPR indirect absolute ok"); + end else begin + $display("\033[0;31m[FAIL]\033[0m JPR indirect absolute not working, PC contains %04h, expected: %04h", dut.pc, expected); + failed = 1; + end + rst = 1; #10 rst = 0; #10 + + // test JPR, relative addressing, indirect + dut.regbank[0] = 16'd50; + dut.mem_fsm_inst.bram_inst.mem[16'd60] = 16'd100; + dut.mem_fsm_inst.bram_inst.mem[16'd10] = { 4'b0101, 1'd0, 1'd0, 3'd0, 7'd0 }; // JPR RA, relative, indirect + dut.mem_fsm_inst.bram_inst.mem[16'd100] = { 4'b1111, 12'd0 }; // HLT + dut.pc = 16'd10; + expected = 16'd101; // PC ends up at &HLT + 1 + + #200 if (dut.pc == expected) begin + $display("\033[0;32m[PASS]\033[0m JPR indirect relative ok"); + end else begin + $display("\033[0;31m[FAIL]\033[0m JPR indirect relative not working, PC contains %04h, expected: %04h", dut.pc, expected); + failed = 1; + end + rst = 1; #10 rst = 0; #10 + + // test JPI, absolute addressing, direct + dut.mem_fsm_inst.bram_inst.mem[16'd0] = { 4'b0110, 1'd1, 1'd1, 10'd123 }; // JPI 123, absolute, direct + dut.mem_fsm_inst.bram_inst.mem[16'd123] = { 4'b1111, 12'd0 }; // HLT + expected = 16'd124; // PC ends up at &HLT + 1 + + #200 if (dut.pc == expected) begin + $display("\033[0;32m[PASS]\033[0m JPI direct absolute ok"); + end else begin + $display("\033[0;31m[FAIL]\033[0m JPI direct absolute not working, PC contains %04h, expected: %04h", dut.pc, expected); + failed = 1; + end + rst = 1; #10 rst = 0; #10 + + // test JPI, relative addressing, direct + dut.mem_fsm_inst.bram_inst.mem[16'd30] = { 4'b0110, 1'd0, 1'd1, -10'd20 }; // JPI -20, relative, direct + dut.mem_fsm_inst.bram_inst.mem[16'd10] = { 4'b1111, 12'd0 }; // HLT + dut.pc = 16'd30; + expected = 16'd11; // PC ends up at &HLT + 1 + + #200 if (dut.pc == expected) begin + $display("\033[0;32m[PASS]\033[0m JPI direct relative ok"); + end else begin + $display("\033[0;31m[FAIL]\033[0m JPI direct relative not working, PC contains %04h, expected: %04h", dut.pc, expected); + failed = 1; + end + rst = 1; #10 rst = 0; #10 + + // test JPI, absolute addressing, indirect + dut.mem_fsm_inst.bram_inst.mem[16'd10] = { 4'b0110, 1'd1, 1'd0, 10'd50 }; // JPI 50, absolute, indirect + dut.mem_fsm_inst.bram_inst.mem[16'd50] = 16'd123; + dut.mem_fsm_inst.bram_inst.mem[16'd123] = { 4'b1111, 12'd0 }; // HLT + dut.pc = 16'd10; + expected = 16'd124; // PC ends up at &HLT + 1 + + #200 if (dut.pc == expected) begin + $display("\033[0;32m[PASS]\033[0m JPI indirect absolute ok"); + end else begin + $display("\033[0;31m[FAIL]\033[0m JPI indirect absolute not working, PC contains %04h, expected: %04h", dut.pc, expected); + failed = 1; + end + rst = 1; #10 rst = 0; #10 + + // test JPI, relative addressing, indirect + dut.mem_fsm_inst.bram_inst.mem[16'd30] = { 4'b0110, 1'd0, 1'd0, -10'd20 }; // JPI -20, relative, indirect + dut.mem_fsm_inst.bram_inst.mem[16'd10] = 16'd50; + dut.mem_fsm_inst.bram_inst.mem[16'd50] = { 4'b1111, 12'd0 }; // HLT + dut.pc = 16'd30; + expected = 16'd51; // PC ends up at &HLT + 1 + + #200 if (dut.pc == expected) begin + $display("\033[0;32m[PASS]\033[0m JPI indirect relative ok"); + end else begin + $display("\033[0;31m[FAIL]\033[0m JPI indirect relative not working, PC contains %04h, expected: %04h", dut.pc, expected); + failed = 1; + end + rst = 1; #10 rst = 0; #10 + + // test BRR, absolute addressing, direct, true branch + dut.regbank[0] = 16'd100; + dut.regbank[2] = 16'd110; + dut.mem_fsm_inst.bram_inst.mem[16'd0] = { 4'b0000, 3'd1, 3'd0, 3'd0, 3'd1 }; // ALR RB, RA, RA, S=MINUS + dut.mem_fsm_inst.bram_inst.mem[16'd1] = { 4'b0111, 1'd1, 1'd1, 2'd0, 3'd2, 5'd0 }; // BRR RC, absolute, direct, F=ZERO + dut.mem_fsm_inst.bram_inst.mem[16'd2] = { 4'b1111, 12'd0 }; // HLT + dut.mem_fsm_inst.bram_inst.mem[16'd110] = { 4'b1111, 12'd0 }; // HLT + expected = 16'd111; // PC ends up at &HLT + 1 + + #200 if (dut.pc == expected) begin + $display("\033[0;32m[PASS]\033[0m BRR direct absolute true ok"); + end else begin + $display("\033[0;31m[FAIL]\033[0m BRR direct absolute true not working, PC contains %04h, expected: %04h", dut.pc, expected); + failed = 1; + end + rst = 1; #10 rst = 0; #10 + + // test BRR, absolute addressing, direct, false branch + dut.regbank[0] = 16'd100; + dut.regbank[2] = 16'd110; + dut.mem_fsm_inst.bram_inst.mem[16'd0] = { 4'b0000, 3'd1, 3'd0, 3'd0, 3'd1 }; // ALR RB, RA, RA, S=MINUS + dut.mem_fsm_inst.bram_inst.mem[16'd1] = { 4'b0111, 1'd1, 1'd1, 2'd1, 3'd2, 5'd0 }; // BRR RC, absolute, direct, F=NEGATIVE + dut.mem_fsm_inst.bram_inst.mem[16'd2] = { 4'b1111, 12'd0 }; // HLT + dut.mem_fsm_inst.bram_inst.mem[16'd110] = { 4'b1111, 12'd0 }; // HLT + expected = 16'd3; // PC ends up at &HLT + 1 + + #200 if (dut.pc == expected) begin + $display("\033[0;32m[PASS]\033[0m BRR direct absolute false ok"); + end else begin + $display("\033[0;31m[FAIL]\033[0m BRR direct absolute false not working, PC contains %04h, expected: %04h", dut.pc, expected); + failed = 1; + end + rst = 1; #10 rst = 0; #10 + + // test BRR, relative addressing, direct + dut.regbank[0] = 16'd100; + dut.regbank[2] = 16'd109; + dut.pc = 16'd10; + dut.mem_fsm_inst.bram_inst.mem[16'd10] = { 4'b0000, 3'd1, 3'd0, 3'd0, 3'd1 }; // ALR RB, RA, RA, S=MINUS + dut.mem_fsm_inst.bram_inst.mem[16'd11] = { 4'b0111, 1'd0, 1'd1, 2'd0, 3'd2, 5'd0 }; // BRR RC, relative, direct, F=ZERO + dut.mem_fsm_inst.bram_inst.mem[16'd12] = { 4'b1111, 12'd0 }; // HLT + dut.mem_fsm_inst.bram_inst.mem[16'd120] = { 4'b1111, 12'd0 }; // HLT + expected = 16'd121; // PC ends up at &HLT + 1 + + #200 if (dut.pc == expected) begin + $display("\033[0;32m[PASS]\033[0m BRR direct relative ok"); + end else begin + $display("\033[0;31m[FAIL]\033[0m BRR direct relative not working, PC contains %04h, expected: %04h", dut.pc, expected); + failed = 1; + end + rst = 1; #10 rst = 0; #10 + + // test BRR, absolute addressing, indirect + dut.regbank[0] = 16'd100; + dut.regbank[2] = 16'd110; + dut.mem_fsm_inst.bram_inst.mem[16'd110] = 16'd200; + dut.mem_fsm_inst.bram_inst.mem[16'd0] = { 4'b0000, 3'd1, 3'd0, 3'd0, 3'd1 }; // ALR RB, RA, RA, S=MINUS + dut.mem_fsm_inst.bram_inst.mem[16'd1] = { 4'b0111, 1'd1, 1'd0, 2'd0, 3'd2, 5'd0 }; // BRR RC, absolute, indirect, F=ZERO + dut.mem_fsm_inst.bram_inst.mem[16'd2] = { 4'b1111, 12'd0 }; // HLT + dut.mem_fsm_inst.bram_inst.mem[16'd200] = { 4'b1111, 12'd0 }; // HLT + expected = 16'd201; // PC ends up at &HLT + 1 + + #200 if (dut.pc == expected) begin + $display("\033[0;32m[PASS]\033[0m BRR indirect absolute ok"); + end else begin + $display("\033[0;31m[FAIL]\033[0m BRR indirect absolute not working, PC contains %04h, expected: %04h", dut.pc, expected); + failed = 1; + end + rst = 1; #10 rst = 0; #10 + + // test BRR, relative addressing, indirect + dut.regbank[0] = 16'd100; + dut.regbank[2] = 16'd109; + dut.pc = 16'd10; + dut.mem_fsm_inst.bram_inst.mem[16'd10] = { 4'b0000, 3'd1, 3'd0, 3'd0, 3'd1 }; // ALR RB, RA, RA, S=MINUS + dut.mem_fsm_inst.bram_inst.mem[16'd11] = { 4'b0111, 1'd0, 1'd0, 2'd0, 3'd2, 5'd0 }; // BRR RC, relative, indirect, F=ZERO + dut.mem_fsm_inst.bram_inst.mem[16'd12] = { 4'b1111, 12'd0 }; // HLT + dut.mem_fsm_inst.bram_inst.mem[16'd120] = 16'd130; + dut.mem_fsm_inst.bram_inst.mem[16'd130] = { 4'b1111, 12'd0 }; // HLT + expected = 16'd131; // PC ends up at &HLT + 1 + + #200 if (dut.pc == expected) begin + $display("\033[0;32m[PASS]\033[0m BRR indirect relative ok"); + end else begin + $display("\033[0;31m[FAIL]\033[0m BRR indirect relative not working, PC contains %04h, expected: %04h", dut.pc, expected); + failed = 1; + end + rst = 1; #10 rst = 0; #10 + + // test BRI, absolute addressing, direct, true branch + dut.regbank[0] = 16'd100; + dut.mem_fsm_inst.bram_inst.mem[16'd0] = { 4'b0000, 3'd1, 3'd0, 3'd0, 3'd1 }; // ALR RB, RA, RA, S=MINUS + dut.mem_fsm_inst.bram_inst.mem[16'd1] = { 4'b1000, 1'd1, 1'd1, 2'd0, 8'd100 }; // BRI 100, absolute, direct, F=ZERO + dut.mem_fsm_inst.bram_inst.mem[16'd2] = { 4'b1111, 12'd0 }; // HLT + dut.mem_fsm_inst.bram_inst.mem[16'd100] = { 4'b1111, 12'd0 }; // HLT + expected = 16'd101; // PC ends up at &HLT + 1 + + #200 if (dut.pc == expected) begin + $display("\033[0;32m[PASS]\033[0m BRI direct absolute true ok"); + end else begin + $display("\033[0;31m[FAIL]\033[0m BRI direct absolute true not working, PC contains %04h, expected: %04h", dut.pc, expected); + failed = 1; + end + rst = 1; #10 rst = 0; #10 + + // test BRI, absolute addressing, direct, false branch + dut.regbank[0] = 16'd100; + dut.mem_fsm_inst.bram_inst.mem[16'd0] = { 4'b0000, 3'd1, 3'd0, 3'd0, 3'd1 }; // ALR RB, RA, RA, S=MINUS + dut.mem_fsm_inst.bram_inst.mem[16'd1] = { 4'b1000, 1'd1, 1'd1, 2'd1, 8'd100 }; // BRI 100, absolute, direct, F=NEGATIVE + dut.mem_fsm_inst.bram_inst.mem[16'd2] = { 4'b1111, 12'd0 }; // HLT + dut.mem_fsm_inst.bram_inst.mem[16'd100] = { 4'b1111, 12'd0 }; // HLT + expected = 16'd3; // PC ends up at &HLT + 1 + + #200 if (dut.pc == expected) begin + $display("\033[0;32m[PASS]\033[0m BRI direct absolute false ok"); + end else begin + $display("\033[0;31m[FAIL]\033[0m BRI direct absolute false not working, PC contains %04h, expected: %04h", dut.pc, expected); + failed = 1; + end + rst = 1; #10 rst = 0; #10 + + // test BRI, relative addressing, direct + dut.regbank[0] = 16'd100; + dut.pc = 16'd10; + dut.mem_fsm_inst.bram_inst.mem[16'd10] = { 4'b0000, 3'd1, 3'd0, 3'd0, 3'd1 }; // ALR RB, RA, RA, S=MINUS + dut.mem_fsm_inst.bram_inst.mem[16'd11] = { 4'b1000, 1'd0, 1'd1, 2'd0, 8'd9 }; // BRI 9, relative, direct, F=ZERO + dut.mem_fsm_inst.bram_inst.mem[16'd12] = { 4'b1111, 12'd0 }; // HLT + dut.mem_fsm_inst.bram_inst.mem[16'd20] = { 4'b1111, 12'd0 }; // HLT + expected = 16'd21; // PC ends up at &HLT + 1 + + #200 if (dut.pc == expected) begin + $display("\033[0;32m[PASS]\033[0m BRI direct relative ok"); + end else begin + $display("\033[0;31m[FAIL]\033[0m BRI direct relative not working, PC contains %04h, expected: %04h", dut.pc, expected); + failed = 1; + end + rst = 1; #10 rst = 0; #10 + + // test BRI, absolute addressing, indirect + dut.regbank[0] = 16'd100; + dut.mem_fsm_inst.bram_inst.mem[16'd100] = 16'd200; + dut.mem_fsm_inst.bram_inst.mem[16'd0] = { 4'b0000, 3'd1, 3'd0, 3'd0, 3'd1 }; // ALR RB, RA, RA, S=MINUS + dut.mem_fsm_inst.bram_inst.mem[16'd1] = { 4'b1000, 1'd1, 1'd0, 2'd0, 8'd100 }; // BRI 100, absolute, indirect, F=ZERO + dut.mem_fsm_inst.bram_inst.mem[16'd2] = { 4'b1111, 12'd0 }; // HLT + dut.mem_fsm_inst.bram_inst.mem[16'd200] = { 4'b1111, 12'd0 }; // HLT + expected = 16'd201; // PC ends up at &HLT + 1 + + #200 if (dut.pc == expected) begin + $display("\033[0;32m[PASS]\033[0m BRI indirect absolute ok"); + end else begin + $display("\033[0;31m[FAIL]\033[0m BRI indirect absolute not working, PC contains %04h, expected: %04h", dut.pc, expected); + failed = 1; + end + rst = 1; #10 rst = 0; #10 + + // test BRI, relative addressing, indirect + dut.regbank[0] = 16'd100; + dut.pc = 16'd10; + dut.mem_fsm_inst.bram_inst.mem[16'd10] = { 4'b0000, 3'd1, 3'd0, 3'd0, 3'd1 }; // ALR RB, RA, RA, S=MINUS + dut.mem_fsm_inst.bram_inst.mem[16'd11] = { 4'b1000, 1'd0, 1'd0, 2'd0, 8'd9 }; // BRI 9, relative, indirect, F=ZERO + dut.mem_fsm_inst.bram_inst.mem[16'd12] = { 4'b1111, 12'd0 }; // HLT + dut.mem_fsm_inst.bram_inst.mem[16'd20] = 16'd130; + dut.mem_fsm_inst.bram_inst.mem[16'd130] = { 4'b1111, 12'd0 }; // HLT + expected = 16'd131; // PC ends up at &HLT + 1 - #200 if (dut.regbank[0] == 16'hffff) begin - $display("\033[0;32m[PASS]\033[0m LDR relative ok"); + #200 if (dut.pc == expected) begin + $display("\033[0;32m[PASS]\033[0m BRI indirect relative ok"); end else begin - $display("\033[0;31m[FAIL]\033[0m LDR relative not working, target reg contains %04h", dut.regbank[0]); + $display("\033[0;31m[FAIL]\033[0m BRI indirect relative not working, PC contains %04h, expected: %04h", dut.pc, expected); failed = 1; end rst = 1; #10 rst = 0; #10 - #5 + #200 if (failed) begin $display("🛑 \033[0;31mTest suite failed\033[0m"); //$fatal(1); diff --git a/atk16_fpga/mem_fsm.v b/atk16_fpga/mem_fsm.v index d5419c5..051705e 100644 --- a/atk16_fpga/mem_fsm.v +++ b/atk16_fpga/mem_fsm.v @@ -1,11 +1,8 @@ `default_nettype none `define ST_IDLE 3'd0 -`define ST_READ1 3'd1 -`define ST_READ2 3'd2 -`define ST_WRITE1 3'd4 -`define ST_WRITE2 3'd5 -`define ST_END 3'd7 +`define ST_READ 3'd1 +`define ST_WRITE 3'd2 module mem_fsm( input clk, @@ -23,7 +20,7 @@ module mem_fsm( bram bram_inst( .clk(clk), .addr(bram_addr), - .cs_n(0), + .cs_n(1'd0), .wr_n(~wr), .rd_n(~rd), .bram_data_in(data_in), @@ -35,29 +32,23 @@ module mem_fsm( `ST_IDLE: begin done <= 0; if (~done && read_en) begin - state <= `ST_READ1; + state <= `ST_READ; bram_addr <= addr; rd <= 1; wr <= 0; end else if (~done && write_en) begin - state <= `ST_WRITE1; + state <= `ST_WRITE; bram_addr <= addr; rd <= 0; wr <= 1; end end - `ST_READ1: begin - state <= `ST_READ2; - end - `ST_READ2: begin + `ST_READ: begin state <= `ST_IDLE; done <= 1; end - `ST_WRITE1: begin - state <= `ST_WRITE2; - end - `ST_WRITE2: begin + `ST_WRITE: begin state <= `ST_IDLE; done <= 1; end diff --git a/atk16_fpga/mem_fsm_tb.v b/atk16_fpga/mem_fsm_tb.v index 5c5029c..8460327 100644 --- a/atk16_fpga/mem_fsm_tb.v +++ b/atk16_fpga/mem_fsm_tb.v @@ -4,7 +4,7 @@ module mem_fsm_tb(); - reg clk, rst, start_read, start_write; + reg clk, rst, read_en, write_en; reg [15:0] addr, data_in; wire done; wire [15:0] data_out; @@ -13,8 +13,8 @@ module mem_fsm_tb(); .clk(clk), .addr(addr), .data_in(data_in), - .start_read(start_read), - .start_write(start_write), + .read_en(read_en), + .write_en(write_en), .data_out(data_out), .done(done) ); @@ -30,17 +30,18 @@ module mem_fsm_tb(); clk = 0; rst = 0; - start_read = 0; - start_write = 0; + read_en = 0; + write_en = 0; #10 // test read dut.bram_inst.mem[0] = 16'hffff; addr = 16'd0; - start_read = 1; - start_write = 0; + read_en = 1; + write_en = 0; + + while (!done) #10; - #40 if (data_out == 16'hffff && done == 1) begin $display("\033[0;32m[PASS]\033[0m Read: data is available and done is 1 as expected"); end else begin @@ -48,17 +49,18 @@ module mem_fsm_tb(); failed = 1; end - start_read = 0; - start_write = 0; + read_en = 0; + write_en = 0; #10 // test write addr = 16'd1; data_in = 16'hffff; - start_read = 0; - start_write = 1; + read_en = 0; + write_en = 1; + + while (!done) #10; - #40 if (dut.bram_inst.mem[1] == 16'hffff && done == 1) begin $display("\033[0;32m[PASS]\033[0m Write: data is available and done is 1 as expected"); end else begin @@ -66,8 +68,8 @@ module mem_fsm_tb(); failed = 1; end - start_read = 0; - start_write = 0; + read_en = 0; + write_en = 0; #5 if (failed) begin |
