diff --git a/rtl/NOTES.txt b/rtl/NOTES.txt new file mode 100644 index 0000000..1272f0a --- /dev/null +++ b/rtl/NOTES.txt @@ -0,0 +1,88 @@ +DEC-8I-H8NA-D KT8/I Time-Sharing Option Functional Description +DEC-8I-HOCA-D KE8/I Extended Arithmetic Element + +interrupt occurs here + + 510 00516 7141 CLL CIA + 511 00517 1155 TAD LASTV + 512 00520 7630 SZL CLA + 513 00521 4526 ERROR /STORAGE FILLED BY PUSHDOWN LIST + + +6000 PWS The contents of the AC register are loaded into the SW +register. This instruction performs no operation if the IM +flag is 1. + +6001 ION The IE flag is set to 1, enabling interrupts, after a one +instruction delay. + +6002 IOF The IE flag is set to 0, disabling interrupts. + +6003 PSI Skip if the IE flag is 1. This instruction performs no +operation if the IM flag is 1. + +6004 PAI The contents of the IB register are loaded into the IF +register, and the II flag is set to 0, just as if a JMP or +JMS was executed when the IM flag is 1. This instruction +performs no operation if the IM flag is 1. + +6005 PAS The contents of the DF register are loaded into bits +[03..05] of the SF register, and the contents of the IF +register are loaded into bits [00..02] of the SF register, +just as they would be loaded on an interrupt. This +instruction performs no operation of the IM flag is 1. + +6006 PDX The DM flag is set to 1 for the execution of the next +instruction. This instruction executes normally if IM is 1, +but since DM is 1 anytime IM is 1, it effectively performs +no operation. + +6007 PEX The IM flag is set to 1, switching the CPU into normal mode, +after a one instruction delay. This instruction executes +notmally if IM is 1, but effectively performs no operation. + +62x1 CDF Bits [06..08] of the instruction are loaded into the DF +register. +62x2 CIF Bits [06..08] of the instruction are loaded into the IB +register, and the II flag is set to 1. The contents of the +IB register will be loaded into the IF register, and the II +flag will be set to 0, when the next JMP or JMS instruction +is executed. The reload happens after any instruction and/or +indirect address words are read, but before the JMS writes +its return address; the return address is written to the new +instruction field. The II flag blocks interrupts between the +CIF and the JMP/JMS (page 53 of the 1970 small computer +handbook describes the effect of the II flag, even though +the flag itself is not described clearly). + +6214 RDF The contents of the DF register are logically ORed into +bits [06..08] of the AC register. + +6224 RIF The contents of the IF register are logically ORed into +bits [06..08] of the AC register. + +6234 RIB The contents of the SF register are logically ORed into +bits [06..11] of the AC register; if the AC register is +initially 0, then bits [09..11] of the AC register get the +value which was in the DF register at the time of the last +interrupt, and bits [06..08] of the AC register get the +value which was in the IF register at the time of the last +interrupt. + +6244 RMF Bits [03..05] of the SF register are loaded into the DF +register, bits [00..02] of the SF register are loaded into +the IB register, and the II flag is set to 1. The next JMP +or JMS instruction completes the restore. + +----- + +rf08 + +photocell +DCIM - turn off photocell +DIML - turn on photocell + +DMAR, DMAW - schedule work; delta to new location in time + +transfer in bursts + diff --git a/rtl/pdp8.v b/rtl/pdp8.v index 1a80a36..9450298 100644 --- a/rtl/pdp8.v +++ b/rtl/pdp8.v @@ -71,31 +71,77 @@ // // cpu states // -// F0 fetch +// F0 fetch ram[IF,pc] // F1 incr pc -// F2 write +// F2 ? // F3 dispatch // -// E0 read -// E1 decode -// E2 write -// E3 load +// then +// +// E0 read ram[ea] +// E1 decode +// E2 write ram +// E3 load // // or // -// D0 read -// D1 wait -// D2 write -// D3 load +// D0 read ram[ea] +// D1 wait +// D2 write ram +// D3 load // // H0 halted // // ------ +// Rules for address calculation +// 0 and +// 1 tad +// 2 isz +// 3 dca +// +// // 11 +// 109876543210 +// cccIZooooooo +// +// bit 8 - indirect +// bit 7 - page 0 +// bits 6:0 offset +// +// if 8:7 == 2'b00 +// ea = IF, pc[11:7], offset[6:0] ;; current page +// if 8:7 == 2'b01 +// ea = IF, 5'b0, offset[6:0] ;; page 0 +// if 8:7 == 2'b10 +// ea = (DF, MA( IF, pc[11:7], offset[6:0] )) ;; *(current page) +// if 8:7 == 2'b11 +// ea = (DF, MA( IF, 5'b0, offset[6:0] )) ;; *(page 0) + +// 4 jms +// 5 jmp // +// ------ +// +// ea <= if Z +// if I +// {DF, 5'b0, mb[6:0]}; +// else +// {IF, 5'b0, mb[6:0]}; +// else +// if I +// {DF, pc[11:7], mb[6:0]}; +// else +// {IF, pc[11:7], mb[6:0]}; +// +// ------ + // F0 fetch +// ma = {IF,pc} // check for interrupt // // F1 incr pc +// ma = 0 +// ea <= { IF, ir_z_flag ? pc[11:7] : 5'b0, mb[6:0] }; +// // if opr // group 1 processing // group 2 processing @@ -104,28 +150,39 @@ // // incr pc or skip (incr pc by 2) // -// F2 write -// ma <= pc +// F2 ?? +// ma = pc // // F3 dispatch +// ma = ea // if opr // group1 processing // // if !opr && !iot // possible defer // -// // D0 -// mb <= memory +// ma = ea +// mb <= ram[ma] // D1 -// D2 +// ma = 0 +// D2 write index reg +// ma = index reg ? ea : {DF,mb} +// ram_wr = 1 // D3 +// ea <= mb +// ma = 0 // // E0 -// mb <= memory +// ma = ea +// mb <= ram[ma] // E1 -// E2 write isz value +// ma = 0 +// E2 write isz value, dca value, jms return +// ma = ea +// ram_wr = 1 // E3 +// ma = ea + 1 (only bottom 12 bits) // // @@ -187,6 +244,9 @@ module pdp8(clk, reset, // instruction register reg [2:0] ir; + reg ir_z_flag; + reg ir_i_flag; + // extended memory - instruction field & data field reg [2:0] IF; @@ -317,6 +377,8 @@ module pdp8(clk, reset, assign next_state = state == F0 ? F1 : state == F1 && (~iot | (iot & io_data_avail)) ? F2 : +// xxx fix this +// state == F1 && (iot & ~io_data_avail) ? F1 : state == F2 ? F3 : state == F3 ? (~run ? H0 : next_is_F0 ? F0 : @@ -343,10 +405,11 @@ module pdp8(clk, reset, pc <= 0; else begin -if (state == F1) $display("pc_skip %b", pc_skip); + //if (state == F1) + // $display("pc_incr %b pc_skip %b", pc_incr, pc_skip); //if (state == F1 || state == D3 || state == E3) - //$display(" pc <- %o", pc_mux); - pc <= pc_mux; + //$display(" pc <- %o", pc_mux); + pc <= pc_mux; end assign pc_mux = (state == F1 && pc_skip) ? (pc + 12'd2) : @@ -383,13 +446,13 @@ if (state == F1) $display("pc_skip %b", pc_skip); ea <= 0; else if (state == F1) - ea <= {DF, mb[7] ? pc[11:7] : 5'b0, mb[6:0]}; + ea <= { IF, ir_z_flag ? pc[11:7] : 5'b0, mb[6:0] }; else if (state == D3) - ea <= mb; + ea <= { (ir_i_flag && (!jmp && !jms)) ? DF : IF, mb }; wire is_index_reg; - assign is_index_reg = ea[11:3] == 8'h01; + assign is_index_reg = ea[11:3] == 9'o001; // // ma @@ -412,7 +475,8 @@ if (state == F1) $display("pc_skip %b", pc_skip); reg interrupt_inhibit_ion; assign interrupt_inhibit = interrupt_inhibit_delay[0] | - interrupt_inhibit_delay[1]; + interrupt_inhibit_delay[1] | + interrupt_inhibit_ion; always @(posedge clk) if (reset) @@ -457,7 +521,11 @@ if (state == F1) $display("pc_skip %b", pc_skip); ac <= 0; mq <= 0; l <= 0; - ir <= 0; + + ir <= 3'b000; + ir_z_flag <= 1'b0; + ir_i_flag <= 1'b0; + run <= 1; interrupt_enable <= 0; interrupt_cycle <= 0; @@ -477,12 +545,16 @@ if (state == F1) $display("pc_skip %b", pc_skip); F0: begin interrupt_skip <= 0; + interrupt_inhibit_ion = 1'b0; if (interrupt && interrupt_enable && !interrupt_inhibit && !interrupt_cycle) begin - $display("xxx interrupt, pc %o; %b %b %b", - pc, interrupt, interrupt_enable, interrupt_cycle); + if (0) + $display("xxx interrupt, pc %o; %b %b %b; %b %b", + pc, + interrupt, interrupt_enable, interrupt_cycle, + interrupt_inhibit, interrupt_inhibit_delay); interrupt_cycle <= 1; interrupt <= 0; interrupt_enable <= 0; @@ -490,6 +562,8 @@ if (state == F1) $display("pc_skip %b", pc_skip); // simulate a jsr to 0 mb <= 12'o4000; ir <= 3'o4; + ir_i_flag <= 1'b0; + ir_z_flag <= 1'b0; SF <= {UF,IF,DF}; IF <= 3'b000; DF <= 3'b000; @@ -498,9 +572,11 @@ if (state == F1) $display("pc_skip %b", pc_skip); begin interrupt_cycle <= 0; - //$display("read ram [%o] -> %o", ram_addr, ram_data_in); + if (0) $display("read ram [%o] -> %o", ram_addr, ram_data_in); mb <= ram_data_in; ir <= ram_data_in[11:9]; + ir_i_flag <= ram_data_in[8]; + ir_z_flag <= ram_data_in[7]; end end @@ -527,13 +603,25 @@ if (state == F1) $display("pc_skip %b", pc_skip); end if (opr) - case ({mb[8],mb[0]}) + casex ({mb[8],mb[0]}) 2'b0x: // group 1 begin - if (mb[7]) ac <= 0; - if (mb[6]) l <= 0; - if (mb[5]) ac <= ~ac; - if (mb[4]) l <= ~l; + case ({mb[7],mb[5]}) + 2'b01: ac <= ~ac; + 2'b10: ac <= 12'o0; + 2'b11: ac <= 12'o7777; + endcase + + case ({mb[6],mb[4]}) + 2'b01: l <= ~l; + 2'b10: l <= 1'b0; + 2'b11: l <= 1'b1; + endcase + +// if (mb[7]) ac <= 0; +// if (mb[6]) l <= 0; +// if (mb[5]) ac <= ~ac; +// if (mb[4]) l <= ~l; end 2'b10: // group 2 @@ -554,7 +642,7 @@ if (state == F1) $display("pc_skip %b", pc_skip); if (iot) begin - case (io_select) + casex (io_select) 6'b000000: // ION, IOF case (mb[2:0]) 3'b001: @@ -583,9 +671,9 @@ if (state == F1) $display("pc_skip %b", pc_skip); case (io_select[2:0]) 3'b000: UI <= 0; // CINT - 3'b001: ac <= { 6'b0, DF, 3'b0 }; // RDF - 3'b010: ac <= { 6'b0, IF, 3'b0 }; // RIF - 3'b011: ac <= { 5'b0, SF }; // RIB + 3'b001: ac <= ac | { 6'b0, DF, 3'b0 }; // RDF + 3'b010: ac <= ac | { 6'b0, IF, 3'b0 }; // RIF + 3'b011: ac <= ac | { 5'b0, SF }; // RIB 3'b100: begin // RMF UB <= SF[6]; IB <= SF[5:3]; @@ -626,7 +714,19 @@ if (state == F1) $display("pc_skip %b", pc_skip); end // if (iot) if (io_interrupt) - interrupt <= 1; + begin + if (0) + $display("F1 - set interrupt; (%b %b %b, %b %b %b)", + interrupt_enable, + interrupt_inhibit, + interrupt_cycle, + IB_pending, UB_pending, + interrupt_inhibit_delay); + + interrupt <= 1; + end + else + interrupt <= 0; end // case: F1 @@ -634,6 +734,10 @@ if (state == F1) $display("pc_skip %b", pc_skip); begin if (opr) begin + // group 1 + if (!mb[8] && mb[0]) /* IAC */ + {l,ac} <= {l,ac} + 13'o00001; + // group 3 if (mb[8] & mb[0]) case ({mb[6:4]}) @@ -657,8 +761,8 @@ if (state == F1) $display("pc_skip %b", pc_skip); // group 1 if (!mb[8]) begin - if (mb[0]) // IAC - {l,ac} <= {l,ac} + 1'b1; +// if (mb[0]) // IAC +// {l,ac} <= {l,ac} + 13'o00001; case (mb[3:1]) 3'b001: // BSW {l,ac} <= {l,ac[5:0],ac[11:6]}; @@ -736,7 +840,7 @@ if (state == F1) $display("pc_skip %b", pc_skip); D0: begin - $display("read ram [%o] -> %o", ram_addr, ram_data_in); + if (0) $display("read ram [%o] -> %o", ram_addr, ram_data_in); mb <= ram_data_in; end @@ -750,7 +854,8 @@ if (state == F1) $display("pc_skip %b", pc_skip); D2: begin // write ram - $display("write ram [%o] <- %o", ram_addr, ram_data_out); + if (ram_wr) + if (0) $display("write ram [%o] <- %o", ram_addr, ram_data_out); end D3: @@ -772,7 +877,7 @@ if (state == F1) $display("pc_skip %b", pc_skip); E0: begin - $display("read ram [%o] -> %o", ram_addr, ram_data_in); + if (0) $display("read ram [%o] -> %o", ram_addr, ram_data_in); mb <= ram_data_in; end @@ -795,7 +900,9 @@ if (state == F1) $display("pc_skip %b", pc_skip); E2: begin // write ram - $display("write ram [%o] <- %o", ram_addr, ram_data_out); + if (ram_wr) + if (0) $display("write ram [%o] <- %o (pc %o)", + ram_addr, ram_data_out, pc); end E3: diff --git a/rtl/pdp8_io.v b/rtl/pdp8_io.v index 138a36a..6652310 100644 --- a/rtl/pdp8_io.v +++ b/rtl/pdp8_io.v @@ -71,10 +71,7 @@ module pdp8_io(clk, reset, iot, state, mb, rf_io_selected ? rf_io_data_avail : 1'b0; - assign io_interrupt = - tt_io_selected ? tt_io_interrupt : - rf_io_selected ? rf_io_interrupt : - 1'b0; + assign io_interrupt = tt_io_interrupt | rf_io_selected; assign io_skip = tt_io_selected ? tt_io_skip : diff --git a/rtl/pdp8_ram.v b/rtl/pdp8_ram.v index b5c5404..57763f5 100644 --- a/rtl/pdp8_ram.v +++ b/rtl/pdp8_ram.v @@ -1,7 +1,5 @@ // -`include "ram_32kx12.v" - module pdp8_ram(clk, reset, addr, data_in, data_out, rd, wr); input clk; diff --git a/rtl/pdp8_rf.v b/rtl/pdp8_rf.v index 8b1ad3e..4e012a1 100644 --- a/rtl/pdp8_rf.v +++ b/rtl/pdp8_rf.v @@ -1,4 +1,3 @@ - /* RF08 @@ -123,16 +122,18 @@ usually through the program interrupt facility. An interrupt is requested when the data transfer is completed and the service routine will process the information. - xxx: - if (databreak_req) - begin - databreak_done <= 0; - next_state <= DB0; - end - ----------- ----------- ----------- ----------- + external signals: + + ma_out + ram_write_req + ram_read_req + ram_done + mb_in + mb_out + DISK STATE MACHINE: // setup @@ -144,20 +145,76 @@ will process the information. ide_block = {1'b0, track, 3'b0} + {8'b0, dma[11:8]} ide_block_index = dma[7:0]; - read_block: - read block - start dma - write block - if dma-stopped-at-end-of-block - goto read_block - - // read block into buffer - DR0: - read[ - if (db_eob) - dr_next_state = + idle + + start-xfer + read wc + read addr + if read + goto check-xfer-read + else + goto begin-xfer-write + + check-xfer-read + if disk-addr-page == memory-buffer-addr-page + read memory-buffer-page[offset] + goto next-xfer-read + else + if memory-buffer-dirty == 0 + goto read-new-page + else + goto write-old-page + + next-xfer-read + write M[addr] + goto next-xfer-incr + + next-xfer-incr + incr addr + incr wc + if wc == 0 + goto done-xfer + if read + goto check-xfer-read + else + goto begin-xfer-write + + begin-xfer-write + read data from memory + goto check-xfer-write + check-xfer-write + if disk-addr-page == memory-buffer-addr-page + write memory-buffer-page[offset] + set memory-buffer-dirty = 1 + goto next-xfer-incr + else + if memory-buffer-dirty == 0 + goto read-new-page + else + goto write-old-page + + done-xfer + write addr + write wc + set done/interrupt + goto idle + + read-new-page + read block from ide + set memory-buffer-addr-page + set memory-buffer-dirty = 0 + if read + goto check-xfer-read + else + goto check-xfer-write + + write-old-page + write block to ide + set memory-buffer-dirty = 0 + goto read-new-page + ----------- ----------- ----------- ----------- DMA STATE MACHINE: @@ -189,57 +246,113 @@ will process the information. databreak_notdone_req = 0; // idle - DB0: + DB_idle: // read word count - DB1: + DB_start_xfer1: ma_out = wc-address; - databreak_notdone_req = 1; - db_next_state = DB2; + ram_read_req = 1; + if ram_done db_next_state = DB_start_xfer2; - // write word count + 1 - DB2: - mb_out = mb_in + 1; - ram_write = 1; - if (mb_in == 12'o7777) - databreak_done_req = 1; - db_next_state = DB3; - - // finish write - DB3: - db_next_state = DB4; - - // read current address - DB4: + // read addr + DB_start_xfer2: + wc = mb_in; ma_out = wc-address | 1; - db_next_state = DB5; + ram_read_req = 1; + db_next_state = DB_start_xfer3; + + DB_start_xfer3: + ram_addr = mb_in + db_next_state = DB_check_xfer_read; - // write current address + 1 - DB5: - mb_out = mb_in + 1; - ram_write = 1; - db_next_state = DB6; + // read buffer + DB_check_xfer_read: + buffer_addr = disk_addr_offset + if disk-addr-page == memory-buffer-addr-page + db_next_state = DB_next_xfer_read; + else + if buffer_dirty == 0 + db_next_state = DB_read_new_page; + else + db_next_state = DB_write_old_page; - // finish write - DB6: - db_next_state = DB7; + // advance + DB_next_xfer_read: + ma_out = ram_addr + mb_out = buffer_out + ram_write_req = 1 + if ram_done db_next_state = DB_next_xfer_incr; + + DB_next_xfer_incr: + disk_addr <= disk_addr + 1 + new_da = {ema, dma} + 19'b1; - // set up read/write address - DB7: - ma_out = mb_in; - db_next_state = DB8; + ram_addr <= ram_addr + 1 + wc <= wc + 1 + done = wc == 07777 + if done + db_next_state = DB_done_xfer; + else + if read + db_next_state = DB_check_xfer_read; + else + db_next_state = DB_begin_xfer_write; - // do read or start write - DB8: - if (databreak_write) - disk_buffer[disk_buffer_index] = memory_bus; - else - begin - mb_out = disk_buffer[disk_buffer_index]; - ram_write = 1; - end - db_next_state = DB9; + // write to ram + DB7_begin_xfer_write: + ma_out = ram_addr + mb_out = buffer_out + ram_read_req = 1 + if ram_done db_next_state = DB_check_xfer_write; + // read buffer + DB_check_xfer_write: + buffer_addr = disk_addr_offset + if disk-addr-page == memory-buffer-addr-page + buffer_wr = 1 + buffer-dirty <= 1 + db_next_state = DB_next_xfer_incr; + else + if buffer-dirty == 0 + db_next_state = DB_read_new_page + else + db_next_state = DB_write_old_page + + // done + DB_done_xfer: + ma_out = wc-address; + mb_out = ram_addr + ram_write_req = 1; + if ram_done db_next_state = DB_start_xfer1; + + DB_done_xfer1: + ma_out = wc-address | 1; + mb_out = wc + ram_write_req = 1; + if ram_done db_next_state = DB_done_xfer2; + + DB_done_xfer2: + set done/interrupt + db_next_state = DB_idle + + DB_read_new_page: + read block from ide + set memory-buffer-addr-page + buffer-dirty <= 0 + if read + db_next_state = DB_check_xfer_read + else + db_next_state = DB_check_xfer_write + + DB_write_old_page: + write block to ide + buffer-dirty <= 0 + db_next_state = DB_read-new-page + + + +------ + // finish read/write DB9: disk_buffer_index = disk_buffer_index + 1; @@ -249,12 +362,12 @@ will process the information. if (databreak_done) begin db_done = 1; - db_next_state = DB0; + db_next_state = DB_idle; end else if (disk_buffer_index == 8'b0) begin - db_next_state = DB0; + db_next_state = DB_idle; db_eob = 1; end else @@ -276,7 +389,7 @@ module pdp8_rf(clk, reset, iot, state, mb, output reg io_selected; output reg [11:0] io_data_out; output reg io_data_avail; - output reg io_interrupt; + output io_interrupt; output reg io_skip; parameter F0 = 4'b0000; @@ -307,8 +420,7 @@ module pdp8_rf(clk, reset, iot, state, mb, assign DCF = 1'b0; assign ADC = DMA == /*DWA??*/0; - parameter IDLE = 4'b1111; - parameter DB0 = 4'b0000; + parameter DB_idle = 4'b0000; parameter DB1 = 4'b0001; parameter DB2 = 4'b0010; parameter DB3 = 4'b0011; @@ -322,7 +434,10 @@ module pdp8_rf(clk, reset, iot, state, mb, wire [3:0] db_next_state; reg [3:0] db_state; reg dma_start; - + + // + assign io_interrupt = 1'b0; + // combinatorial always @(state or ADC or DRL or PER or WLS or NXD or DCF) @@ -340,12 +455,12 @@ module pdp8_rf(clk, reset, iot, state, mb, begin io_selected = 1'b1; case (mb[2:0]) - 3'o03: // DMAR + 6'o03: // DMAR begin io_data_out = 0; dma_start = 1; end - 3'o03: // DMAW + 6'o03: // DMAW begin io_data_out = 0; dma_start = 1; @@ -451,13 +566,14 @@ module pdp8_rf(clk, reset, iot, state, mb, F1: if (iot) begin + if (io_select == 6'o60 || io_select == 6'o64) $display("iot2 %t, state %b, mb %o, io_select %o", $time, state, mb, io_select); case (io_select) 6'o60: case (mb[2:0]) - 3'o03: // DMAR + 6'o03: // DMAR begin // clear ac DMA <= io_data_in; @@ -465,7 +581,7 @@ module pdp8_rf(clk, reset, iot, state, mb, rf08_rw <= 0; end - 3'o03: // DMAW + 6'o03: // DMAW begin // clear ac DMA <= io_data_in; @@ -487,25 +603,25 @@ module pdp8_rf(clk, reset, iot, state, mb, end // if (iot) - F2: - begin - if (io_interrupt) - $display("iot2 %t, reset io_interrupt", $time); - - // sampled during f0 - io_interrupt <= 0; - end +// F2: +// begin +// if (io_interrupt) +// $display("iot2 %t, reset io_interrupt", $time); +// +// // sampled during f0 +// io_interrupt <= 0; +// end endcase // case(state) // assign db_next_state = - dma_start ? DB0 : - IDLE; + dma_start ? DB1 : + DB_idle; always @(posedge clk) if (reset) - db_state <= IDLE; + db_state <= DB_idle; else db_state <= db_next_state; diff --git a/rtl/pdp8_tt.v b/rtl/pdp8_tt.v index fbcce2c..cb30b80 100644 --- a/rtl/pdp8_tt.v +++ b/rtl/pdp8_tt.v @@ -12,7 +12,7 @@ module pdp8_tt(clk, reset, iot, state, mb, output reg io_selected; output reg [11:0] io_data_out; output reg io_data_avail; - output reg io_interrupt; + output io_interrupt; output reg io_skip; @@ -26,17 +26,21 @@ integer tx_delay; parameter F2 = 4'b0010; parameter F3 = 4'b0011; - + // interrupt output + assign io_interrupt = rx_int || tx_int; + // combinatorial - always @(state or - rx_int or tx_int) + always @(state or rx_int or tx_int) begin // sampled during f1 io_skip = 1'b0; io_data_out = io_data_in; io_data_avail = 1'b1; io_selected = 1'b0; - + + //if (state == F1 && iot) + //$display("io_select %o", io_select); + if (state == F1 && iot) case (io_select) 6'o03: @@ -68,6 +72,7 @@ integer tx_delay; always @(posedge clk) if (reset) begin + tx_int <= 0; end else case (state) @@ -80,8 +85,9 @@ integer tx_delay; F1: if (iot) begin - $display("iot2 %t, state %b, mb %o, io_select %o", - $time, state, mb, io_select); + if (io_select == 6'o03 || io_select == 6'o04) + if (0) $display("iot2 %t, state %b, mb %o, io_select %o", + $time, state, mb, io_select); case (io_select) 6'o03: @@ -104,10 +110,9 @@ integer tx_delay; begin tx_data <= io_data_in; $display("xxx tx_data %o", io_data_in); - tx_int <= 1; tx_delaying <= 1; - tx_delay <= 98; - $display("xxx set tx_int"); +// tx_delay <= 98; +tx_delay <= 20; end end // case: 6'o04 @@ -115,15 +120,6 @@ integer tx_delay; end // if (iot) - F2: - begin - if (io_interrupt) - $display("iot2 %t, reset io_interrupt", $time); - - // sampled during f0 - io_interrupt <= 0; - end - F3: begin if (tx_delaying) @@ -132,9 +128,9 @@ integer tx_delay; //$display("xxx delay %d", tx_delay); if (tx_delay == 0) begin - $display("iot2 %t, xxx set io_interrupt", $time); + $display("xxx set tx_int"); tx_delaying <= 0; - io_interrupt <= 1; + tx_int <= 1; end end end diff --git a/rtl/ram_32kx12.v b/rtl/ram_32kx12.v index 3bf42f0..dab7727 100644 --- a/rtl/ram_32kx12.v +++ b/rtl/ram_32kx12.v @@ -1,4 +1,3 @@ - /* 32kx12 static ram */ module ram_32kx12(A, DI, DO, CE_N, WE_N); @@ -10,29 +9,50 @@ module ram_32kx12(A, DI, DO, CE_N, WE_N); reg[11:0] ram [0:32767]; integer i; + // synthesis translate_off + reg [11:0] v; + integer file; + reg [1023:0] str; + reg [1023:0] testfilename; + integer n; + initial begin for (i = 0; i < 32768; i=i+1) ram[i] = 12'b0; - ram[15'o0000] = 12'o5177; - ram[15'o0200] = 12'o7300; - ram[15'o0201] = 12'o1300; - ram[15'o0202] = 12'o1301; - ram[15'o0203] = 12'o3302; - ram[15'o0204] = 12'o7402; - ram[15'o0205] = 12'o5200; +`ifdef verilator + n = 0; +`endif -`include "focal.v" - ram[15'o0000] = 12'o5404; - ram[15'o0004] = 12'o0200; +`ifdef __ICARUS__ + n = $value$plusargs("test=%s", testfilename); +`endif + +`ifdef __CVER__ + n = $scan$plusargs("test=", testfilename); +`endif + if (n > 0) + begin + $display("ram: code filename: %s", testfilename); + file = $fopen(testfilename, "r"); + + while ($fscanf(file, "%o %o\n", i, v) > 0) + begin + //$display("ram[%o] <- %o", i, v); + ram[i] = v; + end + + $fclose(file); + end end + always @(WE_N or CE_N or A or DI) begin if (WE_N == 0 && CE_N == 0) begin - $display("ram: write [%o] <- %o", A, DI); + //$display("ram: write [%o] <- %o", A, DI); ram[ A ] = DI; end end diff --git a/rtl/top.v b/rtl/top.v index adc47e8..00f80be 100644 --- a/rtl/top.v +++ b/rtl/top.v @@ -3,13 +3,6 @@ // copyright Brad Parker 2009 // -`include "pdp8.v" -`include "pdp8_tt.v" -`include "pdp8_rf.v" -`include "pdp8_io.v" -`include "pdp8_ram.v" -`include "debounce.v" - `timescale 1ns / 1ns module top(rs232_txd, rs232_rxd, @@ -134,6 +127,7 @@ module top(rs232_txd, rs232_rxd, .io_data_avail(io_data_avail), .io_interrupt(io_interrupt), .io_skip(io_skip), + .io_clear_ac(io_clear_ac), .iot(iot), .mb(mb), .switches(switches)); @@ -148,7 +142,8 @@ module top(rs232_txd, rs232_rxd, .io_select(io_select), .io_data_avail(io_data_avail), .io_interrupt(io_interrupt), - .io_skip(io_skip)); + .io_skip(io_skip), + .io_clear_ac(io_clear_ac)); pdp8_ram ram(.clk(clk), .reset(reset),