diff --git a/verif/Makefile b/verif/Makefile index 2f5dc75..757f748 100644 --- a/verif/Makefile +++ b/verif/Makefile @@ -1,18 +1,33 @@ -#CVER_FLAGS = +loadvpi=../pli/ide/pli_ide.so:vpi_compat_bootstrap -CVER_FLAGS = + +CVER_FLAGS = +loadvpi=../pli/ide/pli_ide.so:vpi_compat_bootstrap +#CVER_FLAGS = RTESTS = test_tt test_rf test_io RTL = \ ../rtl/pdp8_tt.v ../rtl/pdp8_rf.v ../rtl/pdp8_io.v \ + ../rtl/pdp8_ram.v ../rtl/ram_32kx12.v ../rtl/ram_256x12.v \ + ../rtl/ide_disk.v ../rtl/ide.v \ + ../rtl/top.v \ ../rtl/pdp8.v +all: regress + #--------------------------------------------------------------------- +#cver +showpc +test=../tests/diags/MAINDEX-08-D1GB.mem +pc=0326 +switches=7777 +cycles=20 test_pdp8.v + +#cver +test=../tests/diags/MAINDEC-8I-D01C.mem +pc=0200 +switches=7777 +cycles=2000000 test_pdp8.v + +#cver +test=tss8_init.mem +pc=24200 +loadvpi=../pli/ide/pli_ide.so:vpi_compat_bootstrap test_pdp8.v + +#cver +showpc +cycles=5000 +test=tss8_init.mem +pc=24200 +cycles=2000000 +loadvpi=../pli/ide/pli_ide.so:vpi_compat_bootstrap test_pdp8.v + define runone_verilog_regression cver $(CVER_FLAGS) $(1) >$(2); @if grep -q ERROR $(2); then exit 1; fi; @if grep -q FAILURE $(2); then exit 1; fi; + @echo success endef RTEST_LOGS = $(addsuffix .log,$(RTESTS)) @@ -28,10 +43,11 @@ test_tt: test_tt.v test_rf: test_rf.v $(call runone_verilog_regression,$<,$@) + echo ok test_io: test_io.v $(call runone_verilog_regression,$<,$@) - + echo ok # clean: diff --git a/verif/fake_uart.v b/verif/fake_uart.v new file mode 100644 index 0000000..0e68e21 --- /dev/null +++ b/verif/fake_uart.v @@ -0,0 +1,123 @@ +// + +module fake_uart(clk, reset, + tx_clk, tx_req, tx_ack, tx_data, tx_empty, + rx_clk, rx_req, rx_ack, rx_empty, rx_data); + + input clk; + input reset; + + input tx_clk; + input tx_req; + input [7:0] tx_data; + + input rx_clk; + input rx_req; + + output tx_ack; + output tx_empty; + + output rx_ack; + output rx_empty; + output reg [7:0] rx_data; + + // + reg [1:0] t_state; + wire [1:0] t_state_next; + + reg [1:0] r_state; + wire [1:0] r_state_next; + + integer t_delay; + reg t_done; + + // + assign t_state_next = + (t_state == 0 && tx_req) ? 1 : + t_state == 1 ? 2 : + (t_state == 2 && t_done) ? 0 : + t_state; + + assign tx_ack = t_state == 1; + assign tx_empty = t_delay == 0; + + initial + t_delay = 0; + + always @(posedge clk) + begin + if (t_state == 1) + t_delay = 20; + if (t_delay > 0) + begin + t_delay = t_delay - 1; + if (t_delay == 0) + t_done = 1; + if (0) $display("t_state %d t_delay %d", t_state, t_delay); + end + if (t_state == 0) + t_done = 0; + end + + + // + assign r_state_next = + r_state == 0 && rx_req ? 1 : + r_state == 1 ? 2 : + r_state == 2 ? 0 : + r_state; + + + assign rx_ack = r_state == 1; + + integer r_index, r_count; + + assign rx_empty = r_index == r_count; + + initial + begin + r_index= 0; + r_count = 6; + end + + reg [7:0] rdata[5:0]; + + initial + begin + rdata[0] = "S"; + rdata[1] = "T"; + rdata[2] = "A"; + rdata[3] = "R"; + rdata[4] = "T"; + rdata[5] = "\015"; + + rx_data = 0; + end + + + always @(*) + begin + if (r_state == 2) + begin + $display("xxx dispense %0d %o", r_index, rdata[r_index]); + rx_data = rdata[r_index]; + r_index = r_index + 1; + end + end + + + // + always @(posedge clk) + if (reset) + t_state <= 0; + else + t_state <= t_state_next; + + always @(posedge clk) + if (reset) + r_state <= 0; + else + r_state <= r_state_next; + +endmodule + diff --git a/verif/test_io.v b/verif/test_io.v index 77a5e7a..3b2cbb2 100644 --- a/verif/test_io.v +++ b/verif/test_io.v @@ -6,6 +6,12 @@ `include "../rtl/pdp8_rf.v" `include "../rtl/pdp8_io.v" +`include "../verif/fake_uart.v" +`include "../rtl/brg.v" +`include "../rtl/ide_disk.v" +`include "../rtl/ide.v" +`include "../rtl/ram_256x12.v" + `timescale 1ns / 1ns @@ -25,6 +31,18 @@ module test; wire [3:0] state; wire [11:0] mb; + wire ext_ram_read_req; + wire ext_ram_write_req; + wire [14:0] ext_ram_ma; + wire [11:0] ext_ram_in; + wire ext_ram_done; + wire [11:0] ext_ram_out; + + wire [15:0] ide_data_bus; + wire ide_dior, ide_diow; + wire [1:0] ide_cs; + wire [2:0] ide_da; + pdp8_io io(.clk(clk), .reset(reset), .iot(iot), @@ -36,7 +54,18 @@ module test; .io_data_avail(io_data_avail), .io_interrupt(io_interrupt), .io_skip(io_skip), - .io_clear_ac(io_clear_ac)); + .io_clear_ac(io_clear_ac), + .io_ram_read_req(ext_ram_read_req), + .io_ram_write_req(ext_ram_write_req), + .io_ram_done(ext_ram_done), + .io_ram_ma(ext_ram_ma), + .io_ram_in(ext_ram_in), + .io_ram_out(ext_ram_out), + .ide_dior(ide_dior), + .ide_diow(ide_diow), + .ide_cs(ide_cs), + .ide_da(ide_da), + .ide_data_bus(ide_data_bus)); initial begin diff --git a/verif/test_pdp8.v b/verif/test_pdp8.v index 7688390..e2ae969 100644 --- a/verif/test_pdp8.v +++ b/verif/test_pdp8.v @@ -43,6 +43,11 @@ module test; wire ext_ram_done; wire [11:0] ext_ram_out; + wire [15:0] ide_data_bus; + wire ide_dior, ide_diow; + wire [1:0] ide_cs; + wire [2:0] ide_da; + pdp8 cpu(.clk(clk), .reset(reset), .ram_addr(ram_addr), @@ -85,7 +90,12 @@ module test; .io_ram_done(ext_ram_done), .io_ram_ma(ext_ram_ma), .io_ram_in(ext_ram_in), - .io_ram_out(ext_ram_out)); + .io_ram_out(ext_ram_out), + .ide_dior(ide_dior), + .ide_diow(ide_diow), + .ide_cs(ide_cs), + .ide_da(ide_da), + .ide_data_bus(ide_data_bus)); pdp8_ram ram(.clk(clk), .reset(reset), @@ -95,7 +105,7 @@ module test; .rd(ram_rd), .wr(ram_wr)); - reg [11:0] starting_pc; + reg [14:0] starting_pc; reg [1023:0] arg; integer n; @@ -104,7 +114,7 @@ module test; begin $timeformat(-9, 0, "ns", 7); - $dumpfile("pdp8.vcd"); + $dumpfile("test_pdp8.vcd"); $dumpvars(0, test.cpu); end @@ -117,9 +127,24 @@ module test; max_cycles = 0; max_cycles = 100; - starting_pc = 12'o0200; + starting_pc = 15'o00200; + + show_pc = 0; + show_state = 0; + + if (0) show_pc = 1; + if (0) show_state = 1; + `ifdef __ICARUS__ + n = $value$plusargs("showpc=%d", arg); + if (n > 0) + show_pc = 1; + + n = $value$plusargs("showstate=%d", arg); + if (n > 0) + show_state = 1; + n = $value$plusargs("pc=%o", arg); if (n > 0) begin @@ -143,6 +168,14 @@ module test; `endif `ifdef __CVER__ + n = $scan$plusargs("showpc", arg); + if (n > 0) + show_pc = 1; + + n = $scan$plusargs("showstate", arg); + if (n > 0) + show_state = 1; + n = $scan$plusargs("pc=", arg); if (n > 0) begin @@ -173,7 +206,8 @@ module test; reset = 0; end - cpu.pc = starting_pc; + cpu.pc = starting_pc[11:0]; + cpu.IF = starting_pc[14:12]; // #5000000 $finish; end @@ -189,14 +223,13 @@ module test; integer max_cycles; integer sample; integer show_pc; + integer show_one_pc; integer show_state; initial begin cycle = 0; sample = 0; - show_pc = 0; - show_state = 0; end always @(posedge cpu.clk) @@ -204,27 +237,27 @@ module test; if (cpu.state == 4'b0000) begin sample = sample + 1; - if (sample >= 50000) + if (sample >= 5000/*50000*/) begin sample = 0; - show_pc = 1; + show_one_pc = 1; end - if (1) show_pc = 1; - if (0) show_state = 1; - + if (show_pc) + show_one_pc = 1; + cycle = cycle + 1; if (max_cycles > 0 && cycle >= max_cycles) $finish; - if (show_pc) + if (show_one_pc) #1 $display("pc %o ir %o l%b ac %o ion %o (IF%o DF%o UF%o SF%o IB%o UB%o) %b", cpu.pc, cpu.mb, cpu.l, cpu.ac, cpu.interrupt_enable, cpu.IF, cpu.DF, cpu.UF, cpu.SF, cpu.IB, cpu.UB, cpu.interrupt_inhibit_delay); - show_pc = 0; + show_one_pc = 0; end if (cpu.state == 4'b1100) @@ -258,5 +291,10 @@ module test; end end + always @(posedge clk) + begin + $pli_ide(ide_data_bus, ide_dior, ide_diow, ide_cs, ide_da); + end + endmodule diff --git a/verif/test_top.v b/verif/test_top.v index 238ff1c..337b8c2 100644 --- a/verif/test_top.v +++ b/verif/test_top.v @@ -2,6 +2,8 @@ // testing top end for pdp8.v // +`include "../rtl/ide.v" +`include "../rtl/ide_disk.v" `include "../rtl/pdp8_tt.v" `include "../rtl/pdp8_rf.v" `include "../rtl/pdp8_io.v" diff --git a/verif/test_tt.v b/verif/test_tt.v index 85e2a70..97ad766 100644 --- a/verif/test_tt.v +++ b/verif/test_tt.v @@ -2,67 +2,212 @@ // testing top end for pdp8_tt.v // +`include "../verif/fake_uart.v" +`include "../rtl/brg.v" `include "../rtl/pdp8_tt.v" - `timescale 1ns / 1ns -module test; +module test_tt; - reg clk, reset; + reg clk, brgclk; + reg reset; - wire [11:0] io_data_in; + reg [11:0] io_data_in; wire [11:0] io_data_out; wire io_data_avail; wire io_interrupt; wire io_skip; - wire [5:0] io_select; + reg [5:0] io_select; - wire iot; - wire [3:0] state; - wire [11:0] mb; + reg iot; + reg [3:0] state; + reg [11:0] mb_in; pdp8_tt tt(.clk(clk), + .brgclk(brgclk), .reset(reset), + .iot(iot), .state(state), - .mb(mb), - .io_data_in(io_data_out), - .io_data_out(io_data_in), + .mb(mb_in), + + .io_data_in(io_data_in), + .io_data_out(io_data_out), .io_select(io_select), + .io_selected(io_selected), + .io_data_avail(io_data_avail), .io_interrupt(io_interrupt), .io_skip(io_skip)); - initial - begin - $timeformat(-9, 0, "ns", 7); + reg [11:0] data; + reg sample_skip; + + // + task write_tt_reg; + input [11:0] isn; + input [11:0] data; - $dumpfile("pdp8_tt.vcd"); - $dumpvars(0, test.tt); - end + begin + @(posedge clk); + begin + state = 4'h0; + mb_in = isn; + io_select = isn[8:3]; + io_data_in = data; + iot = 1; + end + #20 state = 4'h1; + #20 state = 4'h2; + #20 state = 4'h3; + #20 begin + state = 4'h0; + iot = 0; + end + end + endtask + + // + task read_tt_reg; + input [11:0] isn; + output [11:0] data; + + begin + @(posedge clk); + begin + state = 4'h0; + mb_in = isn; + io_select = isn[8:3]; + io_data_in = 0; + iot = 1; + end + #10 state = 4'h1; + #10 sample_skip = io_skip; + #20 begin + data = io_data_out; + state = 4'h2; + end + #20 state = 4'h3; + #20 begin + state = 4'h0; + iot = 0; + end + end + endtask + + integer w; + + task failure; + input [15:0] addr; + input [15:0] got; + input [15:0] wanted; + + begin + $display("FAILURE addr %o, read %x, desired %x", + addr, got, wanted); + end + endtask + + + // + task wait_for_tto; + begin + sample_skip = 0; + w = 0; + + while (sample_skip == 0) + begin + read_tt_reg(12'o6041, data); + w = w + 1; + if (w > 100) + begin + $display("FAILURE - waiting for tti"); + $finish; + end + end + end + endtask + + // + task wait_for_tti; + begin + sample_skip = 0; + w = 0; + + while (sample_skip == 0) + begin + read_tt_reg(12'o6031, data); + w = w + 1; + if (w > 100) + begin + $display("FAILURE - waiting for tto"); + $finish; + end + end + end + endtask + + initial + begin + $timeformat(-9, 0, "ns", 7); + + $dumpfile("pdp8_tt.vcd"); + $dumpvars(0, test_tt.tt); + end initial begin - clk = 0; - reset = 0; + clk = 0; + brgclk = 0; + reset = 0; - #1 begin - reset = 1; + #1 begin + reset = 1; end - #50 begin - reset = 0; + #50 begin + reset = 0; end + + // + write_tt_reg(12'o6000, 12'o0000); + + wait_for_tti; + read_tt_reg(12'o6036, data); + + wait_for_tti; + read_tt_reg(12'o6036, data); + + wait_for_tti; + read_tt_reg(12'o6036, data); + + // + write_tt_reg(12'o6000, 12'o0000); + + wait_for_tto; + write_tt_reg(12'o6046, 12'o0207); + + wait_for_tto; + write_tt_reg(12'o6046, 12'o0215); + + wait_for_tto; + write_tt_reg(12'o6000, 12'o0000); - #3000 $finish; + #40000 $finish; end - always - begin - #10 clk = 0; - #10 clk = 1; - end + always + begin + #10 clk = 0; + #10 clk = 1; + end + + always + begin + #10 brgclk = 0; + #10 brgclk = 1; + end //---- integer cycle;