diff --git a/rtl/ide_disk.v b/rtl/ide_disk.v index bf4f2b7..96234ef 100644 --- a/rtl/ide_disk.v +++ b/rtl/ide_disk.v @@ -161,8 +161,10 @@ module ide_disk(clk, reset, //$display("ide_state %d", ide_state_next); end - always @(ide_state or lba or start or - ata_done or ata_out) + always @(ide_state or ide_write_req or ide_read_req or + lba or offset or wc or start or + ata_done or ata_out or + buffer_in) begin ide_state_next = ide_state; diff --git a/rtl/pdp8.v b/rtl/pdp8.v index 8721f19..1664db3 100644 --- a/rtl/pdp8.v +++ b/rtl/pdp8.v @@ -426,6 +426,8 @@ module pdp8(clk, reset, // // ram // + wire is_index_reg; + assign ram_rd = (state == F0) || (state == D0) || (state == E0) || @@ -465,7 +467,6 @@ module pdp8(clk, reset, if (state == D3) ea <= { (ir_i_flag && (!jmp && !jms)) ? DF : IF, mb }; - wire is_index_reg; assign is_index_reg = ea[11:3] == 9'o001; // diff --git a/rtl/pdp8_kw.v b/rtl/pdp8_kw.v index e164867..cad917b 100644 --- a/rtl/pdp8_kw.v +++ b/rtl/pdp8_kw.v @@ -28,7 +28,7 @@ module pdp8_kw(clk, reset, iot, state, mb, reg [1:0] kw_src_ctr; reg kw_src_clk; - reg [11:0] kw_clk; + reg [11:0] kw_ctr; reg kw_int_en; reg kw_clk_en; reg kw_flag; @@ -38,7 +38,7 @@ module pdp8_kw(clk, reset, iot, state, mb, assign io_interrupt = kw_int_en && kw_flag; // combinatorial - always @(state or iot or io_select or kw_flag) + always @(state or iot or io_select or kw_flag or mb) begin // sampled during f1 io_skip = 1'b0; @@ -124,28 +124,28 @@ module pdp8_kw(clk, reset, iot, state, mb, endcase // case(state) - assign assert_kw_flag = kw_clk == 0; + assign assert_kw_flag = kw_ctr == 0; // - always @(posedge kw_src_clk or reset) + always @(posedge kw_src_clk or posedge reset) if (reset) - kw_clk <= 0; + kw_ctr <= 0; else if (kw_clk_en) - kw_clk <= kw_clk + 1; + kw_ctr <= kw_ctr + 1; // source clock - divide down cpu clock always @(posedge clk) if (reset) begin kw_src_ctr <= 0; - kw_src_clk <= 0; + kw_src_clk <= 1'b0; end else begin kw_src_ctr <= kw_src_ctr + 1; if (kw_src_ctr == 0) - kw_src_clk = ~kw_src_clk; + kw_src_clk <= ~kw_src_clk; end endmodule // pdp8_kw diff --git a/rtl/pdp8_rf.v b/rtl/pdp8_rf.v index b27ec7d..87cf273 100644 --- a/rtl/pdp8_rf.v +++ b/rtl/pdp8_rf.v @@ -509,11 +509,13 @@ module pdp8_rf(clk, reset, iot, state, mb, wire ide_buffer_wr; // ide sector buffer - ram_256x12 buffer(.A(buff_addr), - .DI(buff_in), - .DO(buff_out), - .CE_N(~(buff_rd | buff_wr)), - .WE_N(~buff_wr)); + ram_256x12 buffer(.clk(clk), + .reset(reset), + .a(buff_addr), + .din(buff_in), + .dout(buff_out), + .ce(buff_rd | buff_wr), + .we(buff_wr)); assign ide_buffer_in = buff_out; @@ -572,7 +574,7 @@ module pdp8_rf(clk, reset, iot, state, mb, dma_start = 1'b1; $display("rf: go! disk_addr %o", disk_addr); end - 3'o3: // DMAW + 3'o5: // DMAW begin io_data_out = 0; dma_start = 1'b1; diff --git a/rtl/pdp8_tt.v b/rtl/pdp8_tt.v index d2027fc..b36f1fb 100644 --- a/rtl/pdp8_tt.v +++ b/rtl/pdp8_tt.v @@ -1,11 +1,12 @@ // PDP8 console emulation // brad@heeltoe.com -`define sim_time +//`define sim_time `define debug_tt_int 1 //`define debug_tt_reg 1 //`define debug_tt_state 1 +`define debug_tt_data 1 module pdp8_tt(clk, brgclk, reset, iot, state, mb, @@ -71,6 +72,7 @@ module pdp8_tt(clk, brgclk, reset, .tx_baud_clk(uart_tx_clk), .rx_baud_clk(uart_rx_clk)); +`ifdef sim_time // fake_uart tt_uart(.clk(clk), .reset(reset), @@ -86,6 +88,23 @@ module pdp8_tt(clk, brgclk, reset, .rx_ack(rx_ack), .rx_empty(rx_empty), .rx_data(rx_data[7:0])); +`else + // + 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_data(rx_data[7:0]), + .rx_empty(rx_empty)); +`endif // interrupt output assign io_interrupt = rx_int || tx_int; @@ -119,7 +138,9 @@ module pdp8_tt(clk, brgclk, reset, if (mb[2]) begin io_data_out = rx_data; +`ifdef debug_tt_data $display("xxx rx_data %o", rx_data); +`endif end else io_data_out = 12'b0; @@ -179,12 +200,16 @@ module pdp8_tt(clk, brgclk, reset, tx_int <= 1'b1; else tx_int <= 1'b0; +`ifdef debug_tt_in $display("xxx reset tx_int"); +`endif end if (mb[2]) begin tx_data <= io_data_in; +`ifdef debug_tt_data $display("xxx tx_data %o", io_data_in); +`endif end end // case: 6'o04 endcase @@ -193,7 +218,9 @@ module pdp8_tt(clk, brgclk, reset, begin if (assert_tx_int) begin +`ifdef debug_tt_int $display("xxx set tx_int"); +`endif tx_int <= 1; end if (assert_rx_int) diff --git a/rtl/ram_256x12.v b/rtl/ram_256x12.v index d93eeda..9d37bb5 100644 --- a/rtl/ram_256x12.v +++ b/rtl/ram_256x12.v @@ -1,37 +1,43 @@ /* 256x12 static ram */ -module ram_256x12(A, DI, DO, CE_N, WE_N); +module ram_256x12(clk, reset, a, din, dout, ce, we); - input [7:0] A; - input [11:0] DI; - input CE_N, WE_N; - output [11:0] DO; + input clk; + input reset; + + input [7:0] a; + input [11:0] din; + input ce, we; + output [11:0] dout; reg [11:0] ram [0:255]; + + // synthesis translate_off integer i; - + initial begin for (i = 0; i < 256; i=i+1) ram[i] = 12'b0; end + // synthesis translate_on - always @(WE_N or CE_N or A or DI) + always @(posedge clk) begin - if (WE_N == 0 && CE_N == 0) + if (we && ce) begin `ifdef debug_ram - $display("rf: buffer ram write [%o] <- %o", A, DI); + $display("rf: buffer ram write [%o] <- %o", a, din); `endif - ram[ A ] = DI; + ram[a] = din; end `ifdef debug_ram - if (WE_N == 1 && CE_N == 0) - $display("rf: buffer ram read [%o] -> %o", A, ram[A]); + if (we == 0 && ce == 1) + $display("rf: buffer ram read [%o] -> %o", a, ram[a]); `endif end - assign DO = ram[ A ]; + assign dout = ram[a]; endmodule diff --git a/rtl/ram_32kx12.v b/rtl/ram_32kx12.v index 0dbb9d9..3d9c3d5 100644 --- a/rtl/ram_32kx12.v +++ b/rtl/ram_32kx12.v @@ -7,9 +7,9 @@ module ram_32kx12(A, DI, DO, CE_N, WE_N); output[11:0] DO; reg[11:0] ram [0:32767]; - integer i; // synthesis translate_off + integer i; reg [11:0] v; integer file; reg [1023:0] str; @@ -51,6 +51,7 @@ module ram_32kx12(A, DI, DO, CE_N, WE_N); $fclose(file); end end + // synthesis translate_on always @(WE_N or CE_N or A or DI) diff --git a/rtl/uart.v b/rtl/uart.v new file mode 100644 index 0000000..44b376d --- /dev/null +++ b/rtl/uart.v @@ -0,0 +1,246 @@ +// uart.v +// simple low speed async uart for RS-232 +// brad@heeltoe.com 2009-2010 + +module uart(clk, reset, + tx_clk, tx_req, tx_ack, tx_data, tx_empty, + rx_clk, rx_req, rx_ack, rx_data, rx_empty/*,*/ + /*rx_in, tx_out*/); + + input clk; + input reset; + input tx_clk; + input tx_req; + output tx_ack; + input [7:0] tx_data; +// input tx_enable; +// output tx_out; + output tx_empty; + input rx_clk; + input rx_req; + output rx_ack; + output [7:0] rx_data; +// input rx_enable; +// input rx_in; +wire rx_in; + output rx_empty; + + reg tx_ack; + reg rx_ack; + + reg [7:0] tx_reg; + reg tx_empty; + reg tx_over_run; + reg [3:0] tx_cnt; + reg tx_out; + reg [7:0] rx_reg; + reg [7:0] rx_data; + reg [3:0] rx_sample_cnt; + reg [3:0] rx_cnt; + reg rx_frame_err; + reg rx_over_run; + reg rx_empty; + reg rx_d1; + reg rx_d2; + reg rx_busy; + + reg [1:0] rx_uld; + reg [1:0] rx_uld_next; + + reg [1:0] tx_ld; + reg [1:0] tx_ld_next; + + // require rx_req to deassert before sending next char + always @(posedge rx_clk or posedge reset) + if (reset) + rx_uld <= 2'b00; + else + rx_uld <= rx_uld_next; + + always @(rx_req or rx_uld) + begin + rx_uld_next = rx_uld; + rx_ack = 0; + case (rx_uld) + 2'b00: if (rx_req) rx_uld_next = 2'b01; + 2'b01: begin + rx_ack = 1; + rx_uld_next = 2'b10; + end + 2'b10: begin + rx_ack = 1; + if (~rx_req) rx_uld_next = 2'b00; + end + default: rx_uld_next = 2'b00; + endcase + end + + wire uld_rx_data; + assign uld_rx_data = rx_uld == 2'b01; + + // require tx_ld_req to deassert before accepting next char + always @(posedge tx_clk or posedge reset) + if (reset) + tx_ld <= 2'b00; + else + tx_ld <= tx_ld_next; + + always @(tx_req or tx_ld) + begin + tx_ld_next = tx_ld; + tx_ack = 0; + case (tx_ld) + 2'b00: if (tx_req) tx_ld_next = 2'b01; + 2'b01: begin + tx_ack = 1; + tx_ld_next = 2'b10; + end + 2'b10: begin + tx_ack = 1; + if (~tx_req) tx_ld_next = 2'b00; + end + default: tx_ld_next = 2'b00; + endcase + end + + wire ld_tx_data; + assign ld_tx_data = tx_ld == 2'b01; + + + // uart rx + always @(posedge rx_clk or posedge reset) + if (reset) + begin + rx_reg <= 0; + rx_data <= 0; + rx_sample_cnt <= 0; + rx_cnt <= 0; + rx_frame_err <= 0; + rx_over_run <= 0; + rx_empty <= 1; + rx_d1 <= 1; + rx_d2 <= 1; + rx_busy <= 0; + end + else + begin + // synchronize the asynch signal + rx_d1 <= rx_in; + rx_d2 <= rx_d1; + + // uload the rx data + if (uld_rx_data && ~rx_empty) + begin + rx_data <= rx_reg; + rx_empty <= 1; + end + + // receive data only when rx is enabled + if (1/*rx_enable*/) + begin + // check if just received start of frame + if (!rx_busy && !rx_d2) + begin + rx_busy <= 1; + rx_sample_cnt <= 1; + rx_cnt <= 0; + end + + // start of frame detected + if (rx_busy) + begin + rx_sample_cnt <= rx_sample_cnt + 4'd1; + + // sample at middle of data + if (rx_sample_cnt == 7) + begin + if ((rx_d2 == 1) && (rx_cnt == 0)) + rx_busy <= 0; + else + begin + rx_cnt <= rx_cnt + 4'd1; + + // start storing the rx data + if (rx_cnt > 0 && rx_cnt < 9) + rx_reg[rx_cnt - 1] <= rx_d2; + + if (rx_cnt == 4'd9) + begin + //$display("rx_cnt %d, rx_reg %o", + // rx_cnt, rx_reg); + + rx_busy <= 0; + + // check if end of frame received correctly + if (rx_d2 == 0) + rx_frame_err <= 1; + else + begin + rx_empty <= 0; + rx_frame_err <= 0; + + // check for overrun + rx_over_run <= (rx_empty) ? + 1'b0 : 1'b1; + end + end + end + end + end + end + +// if (!rx_enable) +// rx_busy <= 0; + end + + // uart tx + always @ (posedge tx_clk or posedge reset) + if (reset) + begin + tx_empty <= 1'b1; + tx_out <= 1'b1; + tx_cnt <= 4'b0; + + tx_reg <= 0; + tx_over_run <= 0; + end + else + begin + if (ld_tx_data) + begin + if (!tx_empty) + tx_over_run <= 1; + else + begin + tx_reg <= tx_data; + tx_empty <= 0; + end + end + + if (/*tx_enable &&*/!tx_empty) + begin + tx_cnt <= tx_cnt + 4'b1; + + case (tx_cnt) + 4'd0: tx_out <= 0; + 4'd1: tx_out <= tx_reg[0]; + 4'd2: tx_out <= tx_reg[1]; + 4'd3: tx_out <= tx_reg[2]; + 4'd4: tx_out <= tx_reg[3]; + 4'd5: tx_out <= tx_reg[4]; + 4'd6: tx_out <= tx_reg[5]; + 4'd7: tx_out <= tx_reg[6]; + 4'd8: tx_out <= tx_reg[7]; + 4'd9: begin + tx_out <= 1; + tx_cnt <= 0; + tx_empty <= 1; + end + endcase + end + +// if (!tx_enable) +// tx_cnt <= 0; + end + +endmodule