From e5953e3cb9f6612d755c4b22d17ab25ae1598a28 Mon Sep 17 00:00:00 2001 From: brad Date: Tue, 13 Apr 2010 13:56:55 +0000 Subject: [PATCH] debugged rf read side --- rtl/brg.v | 66 ++++++++++++ rtl/ide_disk.v | 31 +++--- rtl/pdp8.v | 11 +- rtl/pdp8_io.v | 45 ++++++-- rtl/pdp8_kw.v | 153 ++++++++++++++++++++++++++ rtl/pdp8_rf.v | 119 +++++++++++++------- rtl/pdp8_tt.v | 275 +++++++++++++++++++++++++++++++++++------------ rtl/ram_256x12.v | 8 ++ rtl/ram_32kx12.v | 18 ++-- rtl/top.v | 11 +- 10 files changed, 590 insertions(+), 147 deletions(-) create mode 100644 rtl/brg.v create mode 100644 rtl/pdp8_kw.v diff --git a/rtl/brg.v b/rtl/brg.v new file mode 100644 index 0000000..0fc722f --- /dev/null +++ b/rtl/brg.v @@ -0,0 +1,66 @@ +// brg.v +// baud rate generator for uart + +module brg(clk, reset, tx_baud_clk, rx_baud_clk); + + input clk; + input reset; + output tx_baud_clk; + output rx_baud_clk; + + parameter SYS_CLK = 26'd50000000; + parameter BAUD = 16'd9600; + +`ifdef sim_time + parameter RX_CLK_DIV = 13'd2; + parameter TX_CLK_DIV = 13'd2; +`else + parameter RX_CLK_DIV = SYS_CLK / (BAUD * 16 * 2); + parameter TX_CLK_DIV = SYS_CLK / (BAUD * 2); +`endif + + reg [12:0] rx_clk_div; + reg [12:0] tx_clk_div; + reg tx_baud_clk; + reg rx_baud_clk; + + + always @(posedge clk or posedge reset) + if (reset) + begin + rx_clk_div <= 0; + rx_baud_clk <= 0; + end + else + if (rx_clk_div == RX_CLK_DIV) + begin + rx_clk_div <= 0; + rx_baud_clk <= ~rx_baud_clk; + end + else + begin + rx_clk_div <= rx_clk_div + 13'b1; + rx_baud_clk <= rx_baud_clk; + end + + always @(posedge clk or posedge reset) + if (reset) + begin + tx_clk_div <= 0; + tx_baud_clk <= 0; + end + else + if (tx_clk_div == TX_CLK_DIV) + begin + tx_clk_div <= 0; + tx_baud_clk <= ~tx_baud_clk; + end + else + begin + tx_clk_div <= tx_clk_div + 13'b1; + tx_baud_clk <= tx_baud_clk; + end + +endmodule + + diff --git a/rtl/ide_disk.v b/rtl/ide_disk.v index c6493ab..e906147 100644 --- a/rtl/ide_disk.v +++ b/rtl/ide_disk.v @@ -20,10 +20,10 @@ module ide_disk(clk, reset, output ide_done; output reg [7:0] buffer_addr; - output reg buffer_rd; - output reg buffer_wr; + output reg buffer_rd; + output reg buffer_wr; output reg [11:0] buffer_out; - output [11:0] buffer_in; + input [11:0] buffer_in; parameter [4:0] ready = 5'd0, @@ -124,8 +124,8 @@ module ide_disk(clk, reset, begin err <= 1'b0; done <= 1'b0; - offset <= 0; - wc <= 0; + offset <= 8'b0; + wc <= 8'b0; end else begin @@ -143,8 +143,8 @@ module ide_disk(clk, reset, if (inc_offset) begin - offset <= offset + 1; - wc <= wc + 1; + offset <= offset + 8'h01; + wc <= wc + 8'h01; end end @@ -162,8 +162,7 @@ module ide_disk(clk, reset, end always @(ide_state or lba or start or - ata_done or ata_out or - dma_data_in or dma_ack) + ata_done or ata_out) begin ide_state_next = ide_state; @@ -220,7 +219,6 @@ module ide_disk(clk, reset, // cnt = 1; // if (cnt_rdy) ide_state_next = init2; - //$display("ide_disk: XXX wait0"); end init2: @@ -340,10 +338,7 @@ module ide_disk(clk, reset, ata_addr = ATA_DATA; if (ata_done) - begin - inc_offset = 1; - ide_state_next = read1; - end + ide_state_next = read1; end read1: @@ -352,11 +347,11 @@ module ide_disk(clk, reset, buffer_addr = offset; buffer_out = ata_out[11:0]; - if (0) $display("read1: XXX ata_out %o, buffer_addr %o", - ata_out, buffer_addr); + if (0) $display("ide_disk: buffer_addr %o, buffer_out %o", + buffer_addr, buffer_out); buffer_wr = 1; -// inc_offset = 1; + inc_offset = 1; if (wc == 8'hff) ide_state_next = last0; @@ -380,7 +375,7 @@ module ide_disk(clk, reset, write1: begin - if (wc == 9'hff) + if (wc == 8'hff) ide_state_next = last0; else // if (wc == 16'hff00) diff --git a/rtl/pdp8.v b/rtl/pdp8.v index ce67254..8721f19 100644 --- a/rtl/pdp8.v +++ b/rtl/pdp8.v @@ -437,13 +437,15 @@ module pdp8(clk, reset, /* peripherals get ram access during F2 */ wire ext_ram_req; + wire ext_ram_grant; assign ext_ram_req = ext_ram_read_req | ext_ram_write_req; assign ext_ram_done = state == F2 && ext_ram_req; + assign ext_ram_grant = state == F2 && ext_ram_req; assign ext_ram_out = ext_ram_req ? ram_data_in : 12'b0; - assign ram_addr = ext_ram_req ? ext_ram_ma : ma; - assign ram_data_out = ext_ram_req ? ext_ram_in : mb; + assign ram_addr = ext_ram_grant ? ext_ram_ma : ma; + assign ram_data_out = ext_ram_grant ? ext_ram_in : mb; assign io_select = mb[8:3]; assign io_data_out = ac; @@ -792,7 +794,10 @@ module pdp8(clk, reset, if (mb[2]) ac <= ac | switches; if (mb[1]) - run <= 0; + begin + $display("HLT! %o", mb); + run <= 0; + end end end diff --git a/rtl/pdp8_io.v b/rtl/pdp8_io.v index b38e017..7bb44a7 100644 --- a/rtl/pdp8_io.v +++ b/rtl/pdp8_io.v @@ -7,7 +7,8 @@ module pdp8_io(clk, reset, iot, state, mb, io_data_in, io_data_out, io_select, io_data_avail, io_interrupt, io_skip, io_clear_ac, io_ram_read_req, io_ram_write_req, io_ram_done, - io_ram_ma, io_ram_in, io_ram_out); + io_ram_ma, io_ram_in, io_ram_out, + ide_dior, ide_diow, ide_cs, ide_da, ide_data_bus); input clk, reset, iot; input [11:0] io_data_in; @@ -27,6 +28,10 @@ module pdp8_io(clk, reset, iot, state, mb, output wire io_ram_write_req; output wire [14:0] io_ram_ma; output wire [11:0] io_ram_out; + + wire kw_io_selected; + wire kw_io_interrupt; + wire kw_io_skip; wire tt_io_selected; wire [11:0] tt_io_data_out; @@ -42,7 +47,26 @@ module pdp8_io(clk, reset, iot, state, mb, wire rf_io_skip; wire rf_io_clear_ac; + output ide_dior; + output ide_diow; + output [1:0] ide_cs; + output [2:0] ide_da; + inout [15:0] ide_data_bus; + + + pdp8_kw kw(.clk(clk), + .reset(reset), + .iot(iot), + .state(state), + .mb(mb), + .io_select(io_select), + + .io_selected(kw_io_selected), + .io_interrupt(kw_io_interrupt), + .io_skip(kw_io_skip)); + pdp8_tt tt(.clk(clk), + .brgclk(/*brgclk*/clk), .reset(reset), .iot(iot), .state(state), @@ -75,7 +99,13 @@ module pdp8_io(clk, reset, iot, state, mb, .ram_done(io_ram_done), .ram_ma(io_ram_ma), .ram_in(io_ram_in), - .ram_out(io_ram_out)); + .ram_out(io_ram_out), + + .ide_dior(ide_dior), + .ide_diow(ide_diow), + .ide_cs(ide_cs), + .ide_da(ide_da), + .ide_data_bus(ide_data_bus)); assign io_data_out = tt_io_selected ? tt_io_data_out : @@ -87,16 +117,19 @@ module pdp8_io(clk, reset, iot, state, mb, rf_io_selected ? rf_io_data_avail : 1'b0; - assign io_interrupt = tt_io_interrupt | rf_io_selected; + assign io_interrupt = kw_io_interrupt | + tt_io_interrupt | + rf_io_interrupt; assign io_skip = + kw_io_selected ? kw_io_skip : tt_io_selected ? tt_io_skip : rf_io_selected ? rf_io_skip : 1'b0; assign io_clear_ac = - tt_io_selected ? tt_io_clear_ac : - rf_io_selected ? rf_io_clear_ac : - 1'b0; + tt_io_selected ? tt_io_clear_ac : + rf_io_selected ? rf_io_clear_ac : + 1'b0; endmodule diff --git a/rtl/pdp8_kw.v b/rtl/pdp8_kw.v new file mode 100644 index 0000000..e164867 --- /dev/null +++ b/rtl/pdp8_kw.v @@ -0,0 +1,153 @@ +// KW8/I emulation +// brad@heeltoe.com + +module pdp8_kw(clk, reset, iot, state, mb, + io_select, io_selected, io_interrupt, io_skip); + + input clk; + input reset; + input iot; + + input [3:0] state; + input [11:0] mb; + input [5:0] io_select; + + output reg io_selected; + output io_interrupt; + output reg io_skip; + + // cpu states + parameter + F0 = 4'b0000, + F1 = 4'b0001, + F2 = 4'b0010, + F3 = 4'b0011; + + // state +// reg [7:0] kw_src_ctr; + reg [1:0] kw_src_ctr; + reg kw_src_clk; + + reg [11:0] kw_clk; + reg kw_int_en; + reg kw_clk_en; + reg kw_flag; + + wire assert_kw_flag; + + assign io_interrupt = kw_int_en && kw_flag; + + // combinatorial + always @(state or iot or io_select or kw_flag) + begin + // sampled during f1 + io_skip = 1'b0; + io_selected = 1'b0; + + if (state == F1 && iot) + case (io_select) + 6'o13: + begin + io_selected = 1'b1; + + case (mb[2:0] ) + 3'o3: + if (kw_flag) + io_skip = 1; + endcase + + end + endcase // case(io_select) + end + + + // + // registers + // + always @(posedge clk) + if (reset) + begin + kw_clk_en <= 1'b0; + kw_int_en <= 1'b0; + kw_flag <= 1'b0; + end + else + case (state) + F0: + begin + end + + F1: + begin + if (iot && io_select == 6'o13) + case (mb[2:0]) + 3'o1: + begin + kw_int_en <= 1'b1; + kw_clk_en <= 1'b1; + $display("kw8i: clocks on!"); + end + 3'o2: + begin + $display("CCFF"); + kw_flag <= 1'b0; + kw_clk_en <= 1'b0; + kw_int_en <= 1'b0; + end + 3'o3: + begin + $display("CSCF"); + kw_flag <= 1'b0; + end + 3'o6: + begin + $display("CCEC"); + kw_clk_en <= 1; + end + 3'o7: + begin + $display("CECI"); + kw_clk_en <= 1; + kw_int_en <= 1; + end + endcase + end + + F3: + begin + if (assert_kw_flag) + begin + kw_flag <= 1; + if (kw_flag == 0) $display("kw8i: set kw_flag!\n"); + end + end + + endcase // case(state) + + assign assert_kw_flag = kw_clk == 0; + + // + always @(posedge kw_src_clk or reset) + if (reset) + kw_clk <= 0; + else + if (kw_clk_en) + kw_clk <= kw_clk + 1; + + // source clock - divide down cpu clock + always @(posedge clk) + if (reset) + begin + kw_src_ctr <= 0; + kw_src_clk <= 0; + end + else + begin + kw_src_ctr <= kw_src_ctr + 1; + if (kw_src_ctr == 0) + kw_src_clk = ~kw_src_clk; + end + +endmodule // pdp8_kw + + diff --git a/rtl/pdp8_rf.v b/rtl/pdp8_rf.v index 9a28866..b27ec7d 100644 --- a/rtl/pdp8_rf.v +++ b/rtl/pdp8_rf.v @@ -1,6 +1,7 @@ -/* - RF08 Emulation using IDE disk +// RF08 Emulation using IDE disk +// brad@heeltoe.com +/* RF08 Sizes: 2048 words/track 11 bits @@ -415,7 +416,6 @@ module pdp8_rf(clk, reset, iot, state, mb, parameter CA_ADDR = 15'o07751; wire ADC; - wire DCF; wire PCA; wire DRE; wire DRL; @@ -423,8 +423,10 @@ module pdp8_rf(clk, reset, iot, state, mb, reg [11:0] DMA; reg [7:0] EMA; + reg DCF; reg PEF; - reg CIE, EIE, MEX, NXD, PIE, WLS; + reg CIE, EIE, NXD, PIE, WLS; + reg [2:0] MEX; assign DRL = 1'b0; assign PER = 1'b0; @@ -459,7 +461,7 @@ module pdp8_rf(clk, reset, iot, state, mb, reg db_done; wire dma_done; - reg [15:0] dma_addr; + reg [14:0] dma_addr; reg [11:0] dma_wc; reg [19:0] disk_addr; @@ -469,7 +471,6 @@ module pdp8_rf(clk, reset, iot, state, mb, reg buffer_dirty; reg [11:0] buffer_hold; - wire [11:0] buffer_out; wire buffer_matches_DMA; wire buffer_rd; @@ -481,7 +482,7 @@ module pdp8_rf(clk, reset, iot, state, mb, wire ide_error; // - assign io_interrupt = (CIE & db_done) || + assign io_interrupt = (CIE & DCF) || (PIE & PCA) || (EIE & (WLS | DRL | NXD | PER)); @@ -504,19 +505,22 @@ module pdp8_rf(clk, reset, iot, state, mb, wire [23:0] ide_block_number; wire [11:0] ide_buffer_in; wire [11:0] ide_buffer_out; + wire ide_buffer_rd; + wire ide_buffer_wr; // ide sector buffer ram_256x12 buffer(.A(buff_addr), .DI(buff_in), .DO(buff_out), - .CE_N(~buff_rd), + .CE_N(~(buff_rd | buff_wr)), .WE_N(~buff_wr)); + assign ide_buffer_in = buff_out; + assign ide_active = ide_read_req | ide_write_req; assign buff_addr = ide_active ? ide_buffer_addr : buffer_addr; assign buff_in = ide_active ? ide_buffer_out : buffer_hold; - assign buff_out = ide_active ? ide_buffer_in : buffer_out; assign buff_rd = ide_active ? ide_buffer_rd : 1'b1; assign buff_wr = ide_active ? ide_buffer_wr : buffer_wr; @@ -566,6 +570,7 @@ module pdp8_rf(clk, reset, iot, state, mb, begin io_data_out = 0; dma_start = 1'b1; + $display("rf: go! disk_addr %o", disk_addr); end 3'o3: // DMAW begin @@ -586,9 +591,9 @@ module pdp8_rf(clk, reset, iot, state, mb, io_data_out = 0; end 3'o6: // DIMA - io_data_out = { PCA, - DRE,WLS,EIE, - PIE,CIE,MEX, + io_data_out = { PCA, DRE,WLS, + EIE, PIE,CIE, + MEX, DRL,NXD,PER }; 3'o5: // DIML io_data_out = 0; @@ -637,10 +642,12 @@ module pdp8_rf(clk, reset, iot, state, mb, is_read <= 1'b0; is_write <= 1'b0; - EMA <= 0; - DMA <= 0; - PEF <= 0; - CIE <= 0; + EMA <= 1'b0; + DMA <= 1'b0; + PEF <= 1'b0; + CIE <= 1'b0; + DCF <= 1'b1; + NXD <= 1'b0; end else case (state) @@ -651,27 +658,27 @@ module pdp8_rf(clk, reset, iot, state, mb, 6'o60: // DCMA if (mb[2:0] == 3'b001) begin +$display("rf: DCMA"); DMA <= 0; - PEF <= 0; + PEF <= 1'b0; + NXD <= 1'b0; + DCF <= 1'b0; end 6'o61: case (mb[2:0]) 3'o1: // DCIM begin - MEX <= 0; - CIE <= 0; - PIE <= 0; - EIE <= 0; + EIE <= 1'b0; + PIE <= 1'b0; + CIE <= 1'b0; + MEX <= 3'b0; +$display("rf: DCIM"); end 3'o2: // DSAC begin end 3'o5: // DIML - begin - EIE <= io_data_in[8]; - PIE <= io_data_in[7]; - CIE <= io_data_in[6]; - MEX <= io_data_in[5:3]; + begin end endcase // case(mb[2:0]) endcase @@ -680,10 +687,11 @@ module pdp8_rf(clk, reset, iot, state, mb, F1: if (iot) begin +`ifdef debug_rf if (io_select == 6'o60 || io_select == 6'o64) $display("iot2 %t, state %b, mb %o, io_select %o", $time, state, mb, io_select); - +`endif case (io_select) 6'o60: case (mb[2:0]) @@ -692,6 +700,7 @@ module pdp8_rf(clk, reset, iot, state, mb, // clear ac DMA <= io_data_in; is_read <= 1'b1; + DCF <= 1'b0; end 6'o03: // DMAW @@ -699,9 +708,22 @@ module pdp8_rf(clk, reset, iot, state, mb, // clear ac DMA <= io_data_in; is_write <= 1'b1; + DCF <= 1'b0; end endcase // case(mb[2:0]) + 6'o61: + case (mb[2:0]) + 3'o5: // DIML + begin + EIE <= io_data_in[8]; + PIE <= io_data_in[7]; + CIE <= io_data_in[6]; + MEX <= io_data_in[5:3]; +$display("rf: DIML %o", io_data_in); + end + endcase // case(mb[2:0]) + 6'o64: case (mb[2:0]) 1: // DCXA @@ -729,6 +751,8 @@ module pdp8_rf(clk, reset, iot, state, mb, DMA <= disk_addr[11:0]; is_read <= 1'b0; is_write <= 1'b0; +$display("rf: set DCF (CIE %b)", CIE); + DCF <= 1'b1; end endcase // case(state) @@ -805,7 +829,7 @@ module pdp8_rf(clk, reset, iot, state, mb, else db_state <= db_next_state; - assign dma_done = dma_wc == 12'o7777; + assign dma_done = dma_wc == 12'o0000; // general state always @(posedge clk) @@ -813,7 +837,7 @@ module pdp8_rf(clk, reset, iot, state, mb, begin db_done <= 1'b1; dma_wc <= 12'b0; - dma_addr <= 15'b0; + dma_addr <= 14'b0; disk_addr <= 20'b0; @@ -827,17 +851,19 @@ module pdp8_rf(clk, reset, iot, state, mb, DB_idle: begin disk_addr <= {EMA, DMA}; - db_done <= 0; end DB_start_xfer1: begin - dma_wc <= ram_in; + dma_wc <= ram_in + 12'o0001; + db_done <= 0; + if (ram_done) $display("rf: read wc %o", ram_in); end DB_start_xfer2: begin - dma_addr <= ram_in; + dma_addr <= { MEX, ram_in + 12'o0001 }; + if (ram_done) $display("rf: read ca %o", ram_in); end DB_start_xfer3: @@ -853,15 +879,33 @@ module pdp8_rf(clk, reset, iot, state, mb, DB_next_xfer_incr: begin disk_addr <= disk_addr + 20'b1; - dma_addr <= dma_addr + 15'b1; + dma_addr <= dma_addr + 14'o00001; dma_wc <= dma_wc + 12'b1; +`ifdef debug_rf + $display("dma_wc %o dma_addr %o MEX %o",dma_wc,dma_addr,MEX); +`endif end +`ifdef debug_rf + DB_next_xfer_read: + if (ram_done) + $display("rf: buffer read[%o] = %o", buff_addr, buff_out); +`endif + DB_check_xfer_write: buffer_dirty <= 1; + DB_done_xfer: + if (ram_done) $display("rf: write wc %o", dma_wc); + + DB_done_xfer1: + if (ram_done) $display("rf: write ca %o", dma_addr); + DB_done_xfer2: - db_done <= 1; + begin + $display("rf: done"); + db_done <= 1; + end DB_read_new_page: begin @@ -900,10 +944,10 @@ module pdp8_rf(clk, reset, iot, state, mb, (db_state == DB_done_xfer1); assign ram_out = - db_state == DB_next_xfer_read ? buffer_hold : + db_state == DB_next_xfer_read ? buff_out : db_state == DB_begin_xfer_write ? buffer_hold : - db_state == DB_done_xfer ? dma_addr : - db_state == DB_done_xfer1 ? dma_wc : + db_state == DB_done_xfer ? dma_wc : + db_state == DB_done_xfer1 ? dma_addr : 12'b0; assign buffer_rd = db_state == DB_check_xfer_read && buffer_matches_DMA; @@ -926,7 +970,6 @@ module pdp8_rf(clk, reset, iot, state, mb, assign PCA = photocell_counter == 0; assign DRE = PCA; - assign DCF = db_done; /* we don't support write lock */ always @(posedge clk) diff --git a/rtl/pdp8_tt.v b/rtl/pdp8_tt.v index 0686ae7..d2027fc 100644 --- a/rtl/pdp8_tt.v +++ b/rtl/pdp8_tt.v @@ -1,35 +1,98 @@ +// PDP8 console emulation +// brad@heeltoe.com -module pdp8_tt(clk, reset, iot, state, mb, +`define sim_time + +`define debug_tt_int 1 +//`define debug_tt_reg 1 +//`define debug_tt_state 1 + +module pdp8_tt(clk, brgclk, reset, + iot, state, mb, io_data_in, io_data_out, io_select, io_selected, io_data_avail, io_interrupt, io_skip); - input clk, reset, iot; + input clk; + input brgclk; + input reset; + input iot; + + input [3:0] state; + input [11:0] mb; input [11:0] io_data_in; - input [11:0] mb; - input [3:0] state; - input [5:0] io_select; + input [5:0] io_select; - output reg io_selected; output reg [11:0] io_data_out; + output reg io_selected; output io_data_avail; output io_interrupt; output reg io_skip; + // internal state + reg [11:0] tx_data; + reg tx_int; + wire tx_empty; + wire tx_ack; + + wire [11:0] rx_data; + reg rx_int; + wire rx_empty; + wire rx_ack; + + wire assert_tx_int; + wire assert_rx_int; + + // interface to uart + reg [1:0] tto_state; + wire [1:0] tto_state_next; + wire tto_empty; + wire tto_req; + reg tto_write; - reg rx_int, tx_int; - reg [12:0] rx_data, tx_data; - reg tx_delaying; -integer tx_delay; + reg [1:0] tti_state; + wire [1:0] tti_state_next; + wire tti_full; + wire tti_req; + reg tti_read; + + wire uart_tx_clk; + wire uart_rx_clk; - parameter F0 = 4'b0000; - parameter F1 = 4'b0001; - parameter F2 = 4'b0010; - parameter F3 = 4'b0011; + // cpu states + parameter [3:0] + F0 = 4'b0000, + F1 = 4'b0001, + F2 = 4'b0010, + F3 = 4'b0011; + // + brg baud_rate_generator(.clk(brgclk), + .reset(reset), + .tx_baud_clk(uart_tx_clk), + .rx_baud_clk(uart_rx_clk)); + + // + fake_uart tt_uart(.clk(clk), + .reset(reset), + + .tx_clk(uart_tx_clk), + .tx_req(tto_req), + .tx_ack(tx_ack), + .tx_data(tx_data[7:0]), + .tx_empty(tx_empty), + + .rx_clk(uart_rx_clk), + .rx_req(tti_req), + .rx_ack(rx_ack), + .rx_empty(rx_empty), + .rx_data(rx_data[7:0])); + // interrupt output assign io_interrupt = rx_int || tx_int; assign io_data_avail = 1'b1; + + assign rx_data[11:8] = 4'b0; // combinatorial always @(state or rx_int or tx_int) @@ -39,9 +102,9 @@ integer tx_delay; io_data_out = io_data_in; io_selected = 1'b0; - //if (state == F1 && iot) - //$display("io_select %o", io_select); - + tti_read = 0; + tto_write = 0; + if (state == F1 && iot) case (io_select) 6'o03: @@ -50,8 +113,17 @@ integer tx_delay; if (mb[0]) io_skip = rx_int; + if (mb[1]) + tti_read = 1; + if (mb[2]) - io_data_out = rx_data; + begin + io_data_out = rx_data; + $display("xxx rx_data %o", rx_data); + end + else + io_data_out = 12'b0; + end 6'o04: @@ -60,8 +132,10 @@ integer tx_delay; if (mb[0]) begin io_skip = tx_int; - $display("xxx io_skip %b", tx_int); + //$display("xxx io_skip %b", tx_int); end + if (mb[2]) + tto_write = 1; end endcase // case(io_select) end @@ -73,67 +147,126 @@ integer tx_delay; always @(posedge clk) if (reset) begin + rx_int <= 0; tx_int <= 0; + + tx_data <= 0; end else - case (state) - F0: + begin + if (iot && state == F1) begin - end +`ifdef debug_tt_reg + if (io_select == 6'o03 || io_select == 6'o04) + $display("iot2 %t, state %b, mb %o, io_select %o", + $time, state, mb, io_select); +`endif + case (io_select) + 6'o03: + begin + if (mb[1]) + rx_int <= 1'b0; + end - F1: - if (iot) - begin - 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: - begin - if (mb[1]) - rx_int <= 0; - end - - 6'o04: - begin - if (mb[0]) - begin - end - if (mb[1]) - begin - tx_int <= 0; - $display("xxx reset tx_int"); - end - if (mb[2]) - begin - tx_data <= io_data_in; - $display("xxx tx_data %o", io_data_in); - tx_delaying <= 1; -// tx_delay <= 98; -tx_delay <= 20; - end - end // case: 6'o04 - - endcase - - end // if (iot) - - F3: + 6'o04: + begin + if (mb[0]) + begin + end + if (mb[1]) + begin + if (assert_tx_int) + tx_int <= 1'b1; + else + tx_int <= 1'b0; + $display("xxx reset tx_int"); + end + if (mb[2]) + begin + tx_data <= io_data_in; + $display("xxx tx_data %o", io_data_in); + end + end // case: 6'o04 + endcase + end // if (iot && state == F1) + else begin - if (tx_delaying) + if (assert_tx_int) begin - tx_delay <= tx_delay - 1; - //$display("xxx delay %d", tx_delay); - if (tx_delay == 0) - begin - $display("xxx set tx_int"); - tx_delaying <= 0; - tx_int <= 1; - end + $display("xxx set tx_int"); + tx_int <= 1; + end + if (assert_rx_int) + begin + //$display("xxx set rx_int"); + rx_int <= 1; end end + end // else: !if(reset) + - endcase // case(state) + // tto state machine + // assert tx_req until uart catches up + // hold off cpu until tx_empty does full transition + // state 0 - idle; wait for iot write to data + // state 1 - wait for tx_ack to assert + // state 2 - wait for tx_ack to deassert + // state 3 - wait for tx_empty to assert + + always @(posedge clk) + if (reset) + tto_state <= 0; + else + tto_state <= tto_state_next; + + assign tto_req = tto_state == 1; + assign tto_empty = tto_state == 0; + + assign tto_state_next = (tto_state == 0 && tto_write) ? 1 : + (tto_state == 1 && tx_ack) ? 2 : + (tto_state == 2 && ~tx_ack) ? 3 : + (tto_state == 3 && tx_empty) ? 0 : + tto_state; + + assign assert_tx_int = tto_state == 3 && tto_state_next == 0; +// assign assert_tx_int = tto_empty; + +`ifdef debug_tt_int + always @(posedge clk) + if (assert_tx_int) + $display("xxx assert_tx_int"); +`endif + +`ifdef debug_tt_state + always @(posedge clk) if (tto_state) $display("tto_state %d", tto_state); +`endif + + // tti state machine + // don't become ready until we've clock data out of uart holding reg + // state 0 - idle; wait for rx_empty to deassert + // state 1 - wait for rx_empty to assert + // state 2 - wait for rx_empty to deassert + // state 3 - wait for iot read of uart (tti) + + always @(posedge clk) + if (reset) + tti_state <= 0; + else + tti_state <= tti_state_next; + + assign tti_req = tti_state == 1; + assign tti_full = tti_state == 3; + + assign tti_state_next = (tti_state == 0 && ~rx_empty) ? 1 : + (tti_state == 1 && rx_ack) ? 2 : + (tti_state == 2 && ~rx_ack) ? 3 : + (tti_state == 3 && tti_read) ? 0 : + tti_state; + + assign assert_rx_int = tti_full; + +`ifdef debug_tt_state + always @(posedge clk) if (tti_state) $display("tti_state %d", tti_state); +`endif endmodule diff --git a/rtl/ram_256x12.v b/rtl/ram_256x12.v index f1fcded..c26cad1 100644 --- a/rtl/ram_256x12.v +++ b/rtl/ram_256x12.v @@ -19,8 +19,16 @@ module ram_256x12(A, DI, DO, CE_N, WE_N); begin if (WE_N == 0 && CE_N == 0) begin +`ifdef debug_ram + $display("rf: buffer ram write [%o] <- %o", A, DI); +`endif ram[ A ] = DI; end + +`ifdef debug_ram + if (WE_N == 1 && CE_N == 0) + $display("rf: buffer ram read [%o] -> %o", A, ram[A]); +`endif end assign DO = ram[ A ]; diff --git a/rtl/ram_32kx12.v b/rtl/ram_32kx12.v index 333c86c..0dbb9d9 100644 --- a/rtl/ram_32kx12.v +++ b/rtl/ram_32kx12.v @@ -57,18 +57,20 @@ module ram_32kx12(A, DI, DO, CE_N, WE_N); begin if (WE_N == 0 && CE_N == 0) begin - //$display("ram: write [%o] <- %o", A, DI); +`ifdef debug_ram + $display("ram: write [%o] <- %o", A, DI); +`endif ram[ A ] = DI; end + +`ifdef debug_ram + if (WE_N == 1 && CE_N == 0) + $display("ram: read [%o] -> %o", A, ram[A]); +`endif end -//always @(A) -// begin -// $display("ram: ce %b, we %b [%o] -> %o", CE_N, WE_N, A, ram[A]); -// end - -// assign DO = ram[ A ]; -assign DO = (^A === 1'bX || A === 1'bz) ? ram[0] : ram[A]; + assign DO = ram[ A ]; +// assign DO = (^A === 1'bX || A === 1'bz) ? ram[0] : ram[A]; endmodule diff --git a/rtl/top.v b/rtl/top.v index 3377b04..5518865 100644 --- a/rtl/top.v +++ b/rtl/top.v @@ -139,7 +139,7 @@ module top(rs232_txd, rs232_rxd, .mb(mb), .switches(switches), .ext_ram_read_req(ext_ram_read_req), - .ext_ram_write(ext_ram_write_req), + .ext_ram_write_req(ext_ram_write_req), .ext_ram_done(ext_ram_done), .ext_ram_ma(ext_ram_ma), .ext_ram_in(ext_ram_out), @@ -158,11 +158,16 @@ module top(rs232_txd, rs232_rxd, .io_skip(io_skip), .io_clear_ac(io_clear_ac), .io_ram_read_req(ext_ram_read_req), - .io_ram_write(ext_ram_write_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)); + .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),