debugged rf read side
This commit is contained in:
66
rtl/brg.v
Normal file
66
rtl/brg.v
Normal file
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
11
rtl/pdp8.v
11
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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
153
rtl/pdp8_kw.v
Normal file
153
rtl/pdp8_kw.v
Normal file
@@ -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
|
||||
|
||||
|
||||
119
rtl/pdp8_rf.v
119
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)
|
||||
|
||||
275
rtl/pdp8_tt.v
275
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
|
||||
|
||||
@@ -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 ];
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
11
rtl/top.v
11
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),
|
||||
|
||||
Reference in New Issue
Block a user