diff --git a/rtl/pdp8_ram.v b/rtl/pdp8_ram.v index 57763f5..766668c 100644 --- a/rtl/pdp8_ram.v +++ b/rtl/pdp8_ram.v @@ -1,6 +1,16 @@ // +// interface to async sram +// used on s3board +// +// multiplexes between to high speed SRAMs +// -module pdp8_ram(clk, reset, addr, data_in, data_out, rd, wr); +//`define use_sim_model 1 + +module pdp8_ram(clk, reset, addr, data_in, data_out, rd, wr, + sram_a, sram_oe_n, sram_we_n, + sram1_io, sram1_ce_n, sram1_ub_n, sram1_lb_n, + sram2_io, sram2_ce_n, sram2_ub_n, sram2_lb_n); input clk; input reset; @@ -10,11 +20,48 @@ module pdp8_ram(clk, reset, addr, data_in, data_out, rd, wr); input rd; input wr; + output [17:0] sram_a; + output sram_oe_n, sram_we_n; + inout [15:0] sram1_io; + output sram1_ce_n, sram1_ub_n, sram1_lb_n; + inout [15:0] sram2_io; + output sram2_ce_n, sram2_ub_n, sram2_lb_n; + +`ifdef use_sim_model ram_32kx12 ram(.A(addr), .DI(data_in), .DO(data_out), .CE_N(1'b0), .WE_N(~wr)); +`else + wire [15:0] ram1_io; + + // + wire sram1_ub, sram1_lb; + + // common + assign sram_a = {3'b0, addr}; + assign sram_oe_n = ~rd; + assign sram_we_n = ~wr; + + // sram1 + assign sram1_ub = 1'b1; + assign sram1_lb = 1'b1; + + assign sram1_ce_n = 1'b0; + assign sram1_ub_n = ~sram1_ub; + assign sram1_lb_n = ~sram1_lb; + + assign data_out = sram1_io[11:0]; + assign sram1_io = ~sram_oe_n ? 16'bz : {4'b0, data_in}; + + // sram2 not used + assign sram2_io = 16'b0; + assign sram2_ce_n = 1'b1; + assign sram2_ub_n = 1'b1; + assign sram2_lb_n = 1'b1; +`endif endmodule + diff --git a/rtl/pdp8_rf.v b/rtl/pdp8_rf.v index 87cf273..cd82a91 100644 --- a/rtl/pdp8_rf.v +++ b/rtl/pdp8_rf.v @@ -697,7 +697,7 @@ $display("rf: DCIM"); case (io_select) 6'o60: case (mb[2:0]) - 6'o03: // DMAR + 3'o3: // DMAR begin // clear ac DMA <= io_data_in; @@ -705,11 +705,13 @@ $display("rf: DCIM"); DCF <= 1'b0; end - 6'o03: // DMAW + 3'o5: // DMAW begin // clear ac DMA <= io_data_in; - is_write <= 1'b1; +// is_write <= 1'b1; +//debug +is_read <= 1'b1; DCF <= 1'b0; end endcase // case(mb[2:0]) diff --git a/rtl/top.v b/rtl/top.v index 5518865..4240bf0 100644 --- a/rtl/top.v +++ b/rtl/top.v @@ -9,9 +9,9 @@ module top(rs232_txd, rs232_rxd, button, led, sysclk, sevenseg, sevenseg_an, slideswitch, - ram_a, ram_oe_n, ram_we_n, - ram1_io, ram1_ce_n, ram1_ub_n, ram1_lb_n, - ram2_io, ram2_ce_n, ram2_ub_n, ram2_lb_n, + sram_a, sram_oe_n, sram_we_n, + sram1_io, sram1_ce_n, sram1_ub_n, sram1_lb_n, + sram2_io, sram2_ce_n, sram2_ub_n, sram2_lb_n, ide_data_bus, ide_dior, ide_diow, ide_cs, ide_da); output rs232_txd; @@ -27,22 +27,23 @@ module top(rs232_txd, rs232_rxd, input [7:0] slideswitch; - output [17:0] ram_a; - output ram_oe_n; - output ram_we_n; + output [17:0] sram_a; + output sram_oe_n; + output sram_we_n; - inout [15:0] ram1_io; - output ram1_ce_n; - output ram1_ub_n; - output ram1_lb_n; + inout [15:0] sram1_io; + output sram1_ce_n; + output sram1_ub_n; + output sram1_lb_n; - inout [15:0] ram2_io; - output ram2_ce_n; - output ram2_ub_n; - output ram2_lb_n; + inout [15:0] sram2_io; + output sram2_ce_n; + output sram2_ub_n; + output sram2_lb_n; inout [15:0] ide_data_bus; - output ide_dior, ide_diow; + output ide_dior; + output ide_diow; output [1:0] ide_cs; output [2:0] ide_da; @@ -170,12 +171,21 @@ module top(rs232_txd, rs232_rxd, .ide_data_bus(ide_data_bus)); pdp8_ram ram(.clk(clk), - .reset(reset), - .addr(ram_addr), - .data_in(ram_data_in), - .data_out(ram_data_out), - .rd(ram_rd), - .wr(ram_wr)); + .reset(reset), + .addr(ram_addr), + .data_in(ram_data_in), + .data_out(ram_data_out), + .rd(ram_rd), + .wr(ram_wr), + + .sram_a(sram_a), + .sram_oe_n(sram_oe_n), .sram_we_n(sram_we_n), + + .sram1_io(sram1_io), .sram1_ce_n(sram1_ce_n), + .sram1_ub_n(sram1_ub_n), .sram1_lb_n(sram1_lb_n), + + .sram2_io(sram2_io), .sram2_ce_n(sram2_ce_n), + .sram2_ub_n(sram2_ub_n), .sram2_lb_n(sram2_lb_n)); endmodule diff --git a/rtl/uart.v b/rtl/uart.v index 44b376d..a22e0fc 100644 --- a/rtl/uart.v +++ b/rtl/uart.v @@ -1,246 +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 +// 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