Cocotb tests.
diff --git a/cocotb_tests/Makefile b/cocotb_tests/Makefile new file mode 100644 index 0000000..63d8c80 --- /dev/null +++ b/cocotb_tests/Makefile
@@ -0,0 +1,13 @@ +SIM ?= icarus +TOPLEVEL_LANG ?= verilog + +# normal simulation +VERILOG_SOURCES += $(PWD)/tb.v $(PWD)/synthesized.v + +# TOPLEVEL is the name of the toplevel module in your Verilog or VHDL file +TOPLEVEL = tb + +# MODULE is the basename of the Python test file +MODULE = test + +include $(shell cocotb-config --makefiles)/Makefile.sim
diff --git a/cocotb_tests/as2650.v b/cocotb_tests/as2650.v new file mode 120000 index 0000000..be03868 --- /dev/null +++ b/cocotb_tests/as2650.v
@@ -0,0 +1 @@ +../verilog/rtl/as2650.v \ No newline at end of file
diff --git a/cocotb_tests/synth.sh b/cocotb_tests/synth.sh new file mode 100644 index 0000000..5595d8d --- /dev/null +++ b/cocotb_tests/synth.sh
@@ -0,0 +1 @@ +./yosys_e -p "read_verilog as2650.v; synth -top as2650; write_verilog synthesized.v;" && clear
diff --git a/cocotb_tests/tb.v b/cocotb_tests/tb.v new file mode 100644 index 0000000..59914c9 --- /dev/null +++ b/cocotb_tests/tb.v
@@ -0,0 +1,43 @@ +`default_nettype none +`timescale 1ns/1ps + +module tb ( + input reset, + input clk, + input sense, + + output [12:0] adr, + output rw, + output opreq, + output m_io, + output d_c, + output flag, + output wrp, + + input [7:0] dbus_in, + output [7:0] dbus_out, + output oeb + ); + + initial begin + $dumpfile ("tb.vcd"); + $dumpvars (0, tb); + #1; + end + + as2650 as2650 ( + .reset(reset), + .clk(clk), + .sense(sense), + .adr(adr), + .rw(rw), + .opreq(opreq), + .m_io(m_io), + .d_c(d_c), + .flag(flag), + .dbus_in(dbus_in), + .dbus_out(dbus_out), + .oeb(oeb), + .wrp(wrp) + ); +endmodule
diff --git a/cocotb_tests/test.asm b/cocotb_tests/test.asm new file mode 100644 index 0000000..3bf4a03 --- /dev/null +++ b/cocotb_tests/test.asm
@@ -0,0 +1,409 @@ +PSL_CC1 equ 0b10000000 +PSL_CC0 equ 0b01000000 +PSL_IDC equ 0b00100000 +PSL_BANK equ 0b00010000 +PSL_WITH_CARRY equ 0b00001000 +PSL_OVERFLOW equ 0b00000100 +PSL_LOGICAL_COMP equ 0b00000010 +PSL_CARRY_FLAG equ 0b00000001 + +mem_end equ 8191 + +org 0 +programentry: + lodi,r0 0x16 + strz,r1 + + stra,r1 mem_end + + lodi,r3 0xFF + stra,r3 mem_end-1 + + lodi,r2 2 + stra,r0 mem_end-4,r2 + + lodi,r0 data>>8%256 + stra,r0 mem_end-6 + lodi,r0 data%256 + stra,r0 mem_end-5 + loda,r2 *mem_end-6 + lodz,r2 + lodi,r1 4 + stra,r0 mem_end-10,r1- + lodz,r1 + stra,r0 mem_end-10,r1- + eorz,r0 + strz,r3 + loda,r0 *mem_end-6,r3+ + strz,r1 + stra,r1 mem_end-9 + +relative_data_0: + nop + nop + lodi,r1 66 + strr,r1 relative_data_0 + eorz r0 + lodr,r3 relative_data_0 + stra,r3 mem_end-10 + + lodi,r0 data+2>>8%256 + strr,r0 relative_data_0 + lodi,r0 data+2%256 + strr,r0 relative_data_0+1 + lodr,r3 *relative_data_0 + stra,r3 mem_end-11 + + lodi,r0 0xFF + eora,r0 data+3 + stra,r0 mem_end-12 + + lodi,r3 0b10001010 + iori,r3 0b10000101 + stra,r3 mem_end-13 + +relative_data_1: + nop + lodi,r0 16 + strr,r0 relative_data_1 + lodi,r2 8 + addr,r2 relative_data_1 + stra,r2 mem_end-14 + + lodi,r1 0xFF + addi,r1 3 + stra,r1 mem_end-15 + eorz,r0 + addi,r0 1 + stra,r0 mem_end-16 + + ppsl PSL_WITH_CARRY + lodi,r1 0xFF + addi,r1 3 + stra,r1 mem_end-17 + eorz,r0 + addi,r0 1 + stra,r0 mem_end-18 + cpsl PSL_WITH_CARRY + lodi,r1 0xFF + addi,r1 3 + stra,r1 mem_end-19 + eorz,r0 + addi,r0 1 + stra,r0 mem_end-20 + + lodi,r0 16 + suba,r0 data+4 + stra,r0 mem_end-21 + + lodi,r3 5 + subi,r3 8 + stra,r3 mem_end-22 + lodi,r0 15 + lodi,r1 0 + subz,r1 + stra,r0 mem_end-23 + + ppsl PSL_WITH_CARRY + ppsl PSL_CARRY_FLAG + lodi,r3 5 + subi,r3 8 + stra,r3 mem_end-24 + lodi,r0 15 + lodi,r1 0 + subz,r1 + stra,r0 mem_end-25 + + cpsl PSL_CARRY_FLAG + lodi,r0 5 + addi,r0 5 + stra,r0 mem_end-26 + addz,r0 + stra,r0 mem_end-27 + cpsl PSL_WITH_CARRY + + redd,r0 + redd,r1 + redd,r2 + redd,r3 + addz,r1 + addz,r2 + addz,r3 + + stra,r0 mem_end-28 + + lodi,r0 100 + redc,r3 + redc,r3 + redc,r3 + subz,r3 + + stra,r0 mem_end-29 + + lodi,r1 55 + lodi,r2 66 + lodi,r3 10 + wrtd,r1 + wrtd,r2 + wrtd,r3 + + lodi,r1 12 + lodi,r2 38 + lodi,r3 33 + wrtc,r1 + wrtc,r2 + wrtc,r3 + + lodi,r0 0b00001111 + rrr,r0 + stra,r0 mem_end-30 + rrl,r0 + stra,r0 mem_end-31 + + ppsl PSL_WITH_CARRY + cpsl PSL_CARRY_FLAG + rrr,r0 + stra,r0 mem_end-32 + rrr,r0 + stra,r0 mem_end-33 + eorz,r0 + rrl,r0 + stra,r0 mem_end-34 + rrl,r0 + stra,r0 mem_end-35 + + lodi,r1 128 + rrl,r1 + spsl + stra,r0 mem_end-36 + strz,r2 + andi,r0 0b11110110 + lpsl + spsl + stra,r0 mem_end-37 + lodz,r2 + lpsl + tpsl 0b00001001 + spsl + andi,r0 0b11000000 + stra,r0 mem_end-38 + tpsl 2 + spsl + andi,r0 0b11000000 + stra,r0 mem_end-39 + cpsl PSL_WITH_CARRY + + lodi,r0 0b00001011 + strz,r1 + strz,r2 + db 0xF6 ; tmi,r2 (not recognized by my assembler yet) + db 0b00000001 + spsl + andi,r0 0b11000000 + stra,r0 mem_end-40 + db 0xF5 ; tmi,r1 (not recognized by my assembler yet) + db 0b11100001 + spsl + andi,r0 0b11000000 + stra,r0 mem_end-41 + + lodi,r0 55 + bctr,un skip_1 + eorz,r0 +skip_1: + stra,r0 mem_end-42 + + lodi,r1 6 + stra,r0 mem_end-444,r1- + stra,r1 mem_end-43 + stra,r0 mem_end-444,r1- + stra,r1 mem_end-44 + stra,r0 mem_end-444,r1- + stra,r1 mem_end-45 +loop: + stra,r0 mem_end-444,r1- + brnr,r1 loop + + lodi,r3 2 + lodi,r0 55 +back_1: + bcfa,1 skip_2 + lodi,r0 103 +skip_2: + stra,r0 mem_end-47,r3- + lodi,r0 180 + brna,r3 back_1 + + lodi,r3 99 + lodi,r0 200 + subz,r3 + spsl + andi,r0 0b11000000 + stra,r0 mem_end-48 + + lodi,r2 120 + adda,r2 data+7 + bcta,2 skip_3 + lodi,r2 0 +skip_3: + stra,r2 mem_end-49 + + lodi,r0 5 + lodi,r3 0 +loop_2: + addi,r3 1 + bdra,r0 loop_2 + stra,r3 mem_end-50 + + lodi,r1 248 + lodi,r2 0 +loop_3: + addi,r2 1 + bira,r1 loop_3 + stra,r2 mem_end-51 + + lodi,r0 5 + lodi,r3 0 +loop_4: + addi,r3 1 + bdrr,r0 loop_4 + stra,r3 mem_end-52 + + lodi,r1 248 + lodi,r2 0 +loop_5: + addi,r2 1 + birr,r1 loop_5 + stra,r2 mem_end-53 + + lodi,r2 55 + comi,r2 55 + spsl + andi,r0 0b11000000 + stra,r0 mem_end-54 + + lodi,r3 7 + coma,r3 data+8 + spsl + andi,r0 0b11000000 + stra,r0 mem_end-55 + + ppsl PSL_LOGICAL_COMP + lodi,r3 7 + coma,r3 data+8 + spsl + andi,r0 0b11000000 + stra,r0 mem_end-56 + cpsl PSL_LOGICAL_COMP + + loda,r2 data+8 + eorz,r0 + comz,r2 + spsl + andi,r0 0b11000000 + stra,r0 mem_end-57 + + ppsl PSL_LOGICAL_COMP + comz,r2 + spsl + andi,r0 0b11000000 + stra,r0 mem_end-58 + + lodz,r2 + comz,r2 + spsl + andi,r0 0b11000000 + stra,r0 mem_end-59 + cpsl PSL_LOGICAL_COMP + + lodi,r1 1 + lodi,r2 2 + lodi,r3 3 + ppsl PSL_BANK + lodi,r1 4 + lodi,r2 5 + lodi,r3 6 + cpsl PSL_BANK + + stra,r1 mem_end-60 + stra,r2 mem_end-61 + stra,r3 mem_end-62 + ppsl PSL_BANK + stra,r1 mem_end-63 + stra,r2 mem_end-64 + stra,r3 mem_end-65 + cpsl PSL_BANK + + bcta,un sub_1_end +a_subroutine_1: + lodi,r0 5 + addi,r0 10 + addz,r1 + retc,un +sub_1_end: + lodi,r1 1 + bstr,un a_subroutine_1 + stra,r0 mem_end-66 + eorz,r0 + strz,r1 + bsta,un a_subroutine_1 + stra,r0 mem_end-67 + bctr,un sub_2_end +a_subroutine_2: + lodi,r3 6 + comi,r2 0 + retc,eq + lodi,r3 7 + retc,un +sub_2_end: + lodi,r2 5 + bstr,un a_subroutine_2 + stra,r3 mem_end-68 + lodi,r2 0 + bsta,un a_subroutine_2 + stra,r3 mem_end-69 + + lodi,r2 5 + lodi,r3 8 + bsta,un mul_8x8_8 + stra,r0 mem_end-70 + + lodi,r0 5 + lodi,r1 8 + db 0x90 + stra,r2 mem_end-71 + + halt + +mul_8x8_8: + spsl + lodi,r1 8 + eorz r0 + ppsl PSL_WITH_CARRY +mul_8x8_8_loop: + rrr,r2 + ;tpsl PSL_CARRY_FLAG + db 183 ;Same instruction, but alternative encoding + db 1 + bcfr,0 mul_8x8_8_no_carry + cpsl PSL_CARRY_FLAG + addz r3 +mul_8x8_8_no_carry: + rrl,r3 + andi,r3 254 + bdrr,r1 mul_8x8_8_loop + strz r1 + lpsl + lodz r1 + retc,un + +data: + db 70 + db 6 + db 11 + db 0xAA + db 8 + db 0 + db 0 + db 100 + db 200
diff --git a/cocotb_tests/test.py b/cocotb_tests/test.py new file mode 100644 index 0000000..166666f --- /dev/null +++ b/cocotb_tests/test.py
@@ -0,0 +1,132 @@ +import cocotb +import random +from cocotb.clock import Clock +from cocotb.triggers import Timer, ClockCycles + +@cocotb.test() +async def test_cpu(dut): + dut._log.info("start") + + memory = [0] * 8192 + + with open("test.bin", mode='rb') as file: + for i in range(0, 8192): + a = file.read(1) + if len(a) > 0: + memory[i] = a[0] + + dut.sense.value = 0 + dut.dbus_in.value = 0 + dut.reset.value = 1 + clock = Clock(dut.clk, 1, units="us") + cocotb.start_soon(clock.start()) + await ClockCycles(dut.clk, 3) + dut.reset.value = 0 + + d_counter = 0 + c_counter = 0 + expected_io_out_d = [55, 66, 10] + expected_io_out_c = [12, 38, 33] + d_out_counter = 0 + c_out_counter = 0 + tt = 0 + while dut.as2650.halted == 0: + await Timer(0.25, units="us") + tt += 1 + dut.dbus_in.value = 0 + if dut.oeb.value == 0: + if dut.rw.value == 1 and dut.opreq.value == 1 and dut.wrp.value == 1: + if dut.m_io == 1: + memory[dut.adr.value] = dut.dbus_out.value + else: + if dut.wrp.value == 1: + if dut.d_c.value == 1: + assert dut.dbus_out.value == expected_io_out_d[d_out_counter] + if tt % 5 == 4: + d_out_counter += 1 + else: + assert dut.dbus_out.value == expected_io_out_c[c_out_counter] + if tt % 5 == 4: + c_out_counter += 1 + else: + if dut.rw.value == 0 and dut.opreq.value == 1: + if dut.m_io.value == 1: + dut.dbus_in.value = memory[dut.adr.value] + else: + if dut.d_c.value == 1: + dut.dbus_in.value = d_counter + if tt % 4 == 3: + d_counter += 1 + else: + dut.dbus_in.value = c_counter + if tt % 4 == 3: + c_counter += 2 + + assert memory[8191] == 0x16 + assert memory[8190] == 0xFF + assert memory[8189] == 0x16 + assert memory[8191-7] == 70 + assert memory[8191-8] == 3 + assert memory[8191-9] == 6 + assert memory[8191-10] == 66 + assert memory[8191-11] == 11 + assert memory[8191-12] == 0b01010101 + assert memory[8191-13] == 0b10001111 + assert memory[8191-14] == 24 + assert memory[8191-15] == 2 + assert memory[8191-16] == 1 + assert memory[8191-17] == 2 + assert memory[8191-18] == 2 + assert memory[8191-19] == 2 + assert memory[8191-20] == 1 + assert memory[8191-21] == 8 + assert memory[8191-22] == 0b11111101 + assert memory[8191-23] == 15 + assert memory[8191-24] == 0b11111101 + assert memory[8191-25] == 14 + assert memory[8191-26] == 10 + assert memory[8191-27] == 20 + assert memory[8191-28] == 6 + assert memory[8191-29] == 96 + assert memory[8191-30] == 0b10000111 + assert memory[8191-31] == 0b00001111 + assert memory[8191-32] == 0b00000111 + assert memory[8191-33] == 0b10000011 + assert memory[8191-34] == 0b00000001 + assert memory[8191-35] == 0b00000010 + assert memory[8191-36] == 0b00001001 + assert memory[8191-37] == 0 + assert memory[8191-38] == 0 + assert memory[8191-39] == 0b10000000 + assert memory[8191-40] == 0 + assert memory[8191-41] == 0b10000000 + assert memory[8191-42] == 55 + assert memory[8191-43] == 5 + assert memory[8191-44] == 4 + assert memory[8191-45] == 3 + assert memory[8191-46] == 103 + assert memory[8191-47] == 180 + assert memory[8191-48] == 0b01000000 + assert memory[8191-49] == 220 + assert memory[8191-50] == 5 + assert memory[8191-51] == 8 + assert memory[8191-52] == 5 + assert memory[8191-53] == 8 + assert memory[8191-54] == 0 + assert memory[8191-55] == 0b01000000 + assert memory[8191-56] == 0b10000000 + assert memory[8191-57] == 0b01000000 + assert memory[8191-58] == 0b10000000 + assert memory[8191-59] == 0 + assert memory[8191-60] == 1 + assert memory[8191-61] == 2 + assert memory[8191-62] == 3 + assert memory[8191-63] == 4 + assert memory[8191-64] == 5 + assert memory[8191-65] == 6 + assert memory[8191-66] == 16 + assert memory[8191-67] == 15 + assert memory[8191-68] == 7 + assert memory[8191-69] == 6 + assert memory[8191-70] == 40 + assert memory[8191-71] == 40
diff --git a/cocotb_tests/test.sh b/cocotb_tests/test.sh new file mode 100644 index 0000000..4554b4a --- /dev/null +++ b/cocotb_tests/test.sh
@@ -0,0 +1 @@ +./2650Tools asm test.asm && make
diff --git a/verilog/rtl/as2650.v b/verilog/rtl/as2650.v index acb2d3d..052f562 100644 --- a/verilog/rtl/as2650.v +++ b/verilog/rtl/as2650.v
@@ -332,7 +332,7 @@ * Misc instructions */ if(cycle == 2) begin - if(ins_reg == 'h90 || ins_reg == 'h91) begin //Hijacking undocumented opcodes to add a multiply instruction + if(ins_reg == 'h90 || ins_reg == 'h91) begin //Using undocumented opcodes to add a multiply instruction //(psl[4] ? r123_2[2] : r123[2]); if(psl[4]) begin r123_2[1] <= r0 * r123_2[0];