1
0
mirror of https://github.com/livingcomputermuseum/cpus-pdp8.git synced 2026-01-13 07:29:24 +00:00

revamped pdp-8/i

This commit is contained in:
brad 2009-05-01 21:41:33 +00:00
parent 0adc80d5fd
commit 595692fe2b
5 changed files with 833 additions and 706 deletions

1155
cpu/pdp8.v

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
// PDP-8 i/o
// Based on descriptions in "Computer Engineering"
// Dev 2006 Brad Parker brad@heeltoe.com
//
// Revamp 2009 Brad Parker brad@heeltoe.com
/*
iot's touched by focal
@ -184,13 +184,12 @@ will process the information.
*/
module pdp8_io(clk, reset_n, iot, state, pc, ac, mb,
io_select,
io_data_out, io_data_avail, io_interrupt, io_skip, io_clear_ac);
module pdp8_io(clk, reset, iot, state, mb,
io_data_in, io_data_out, io_select,
io_data_avail, io_interrupt, io_skip);
input clk, reset_n, iot;
input [11:0] pc;
input [11:0] ac;
input clk, reset, iot;
input [11:0] io_data_in;
input [11:0] mb;
input [3:0] state;
input [5:0] io_select;
@ -199,7 +198,6 @@ module pdp8_io(clk, reset_n, iot, state, pc, ac, mb,
output reg io_data_avail;
output reg io_interrupt;
output reg io_skip;
output reg io_clear_ac;
reg rx_int, tx_int;
@ -223,89 +221,143 @@ module pdp8_io(clk, reset_n, iot, state, pc, ac, mb,
parameter E3 = 4'b1011;
parameter PCA = 12'o4000; // photocell status
parameter DRE = 12'o2000; // data req enable
parameter WLS = 12'o1000; // write lock status
parameter EIE = 12'o0400; // error int enable
parameter PIE = 12'o0200; // photocell int enb
parameter CIE = 12'o0100; // done int enable
parameter MEX = 12'o0070; // memory extension
parameter DRL = 12'o0004; // data late error
parameter NXD = 12'o0002; // non-existent disk
parameter PER = 12'o0001; // parity error
parameter PCA_bit = 12'o4000; // photocell status
parameter DRE_bit = 12'o2000; // data req enable
parameter WLS_bit = 12'o1000; // write lock status
parameter EIE_bit = 12'o0400; // error int enable
parameter PIE_bit = 12'o0200; // photocell int enb
parameter CIE_bit = 12'o0100; // done int enable
parameter MEX_bit = 12'o0070; // memory extension
parameter DRL_bit = 12'o0004; // data late error
parameter NXD_bit = 12'o0002; // non-existent disk
parameter PER_bit = 12'o0001; // parity error
wire ADC;
wire DCF;
reg [11:0] DMA;
reg [7:0] EMA;
reg PEF;
reg rf08_rw;
reg rf08_start_io;
reg CIE, DRE, DRL, EIE, MEX, NXD, PCA, PER, PIE, WLS;
assign DCF = 1'b0;
assign ADC = DMA == /*DWA??*/0;
always @(state)
// combinatorial
always @(state or
rx_int or tx_int or
ADC or DRL or PER or WLS or NXD or DCF)
begin
case (state)
// sampled during f1
io_skip = 0;
io_data_out = io_data_in;
io_data_avail = 1;
if (state == F0 && iot)
case (io_select)
6'o03:
begin
if (mb[0])
io_skip = rx_int;
if (mb[2])
io_data_out = rx_data;
end
6'o04:
if (mb[0])
io_skip = tx_int;
6'o60:
case (mb[2:0])
3'o03: // DMAR
io_data_out = 0;
3'o03: // DMAW
io_data_out = 0;
endcase
6'o61:
case (mb[2:0])
3'o2: // DSAC
if (ADC)
begin
io_skip = 1;
io_data_out = 0;
end
3'o6: // DIMA
io_data_out = { PCA, DRE,WLS,EIE, PIE,CIE,MEX, DRL,NXD,PER };
3'o5: // DIML
io_data_out = 0;
endcase
6'o62:
case (mb[2:0])
3'o1: // DFSE
if (DRL | PER | WLS | NXD)
io_skip = 1;
3'o2: // ???
if (DCF)
io_skip = 1;
3'o3: // DISK
if (DRL | PER | WLS | NXD | DCF)
io_skip = 1;
3'o6: // DMAC
io_data_out = DMA;
endcase
6'o64:
case (mb[2:0])
3: // DXAL
io_data_out = 0;
5: // DXAC
io_data_out = EMA;
endcase
endcase // case(io_select)
end
//
// registers
//
always @(posedge clk)
if (reset)
begin
end
else
case (state)
F0:
begin
// sampled during f1
io_skip <= 0;
io_data_avail <= 0;
io_clear_ac <= 0;
if (iot)
case (io_select)
6'o03:
if (mb[0])
io_skip <= rx_int;
6'o04:
if (mb[0])
begin
$display("tsf; tx_int %b, pc %o", tx_int, pc);
io_skip <= tx_int;
end
6'o60: // DCMA
if (mb[2:0] == 3'b001)
begin
DMA <= 0;
PEF < = 0;
PEF <= 0;
DRL <= 0;
end
6'o61:
case (mb[2:0])
n 3'o1: // DCIM
3'o1: // DCIM
begin
CIE <= 0;
EMA <= 0;
end
3'o2: // DSAC
// xxx
assign ADC = DMA == DWA;
begin
if (ADC)
begin
io_skip <= 1;
io_clear_ac <= 1;
end
end
3'o5: // DIML
begin
CIE <= AC[8];
EMA <= AC[7:0];
end
3'o6: // DIMA
begin
AC <= { PCA,DRE,WLS,EIE,PIE,CIE, MEX, DRL,NXD,PER };
CIE <= io_data_in[8];
EMA <= io_data_in[7:0];
end
endcase // case(mb[2:0])
6'o62:
case (mb[2:0])
3'o1: // DFSE
if (DRL | PER | WLS | NXD)
io_skip <= 1;
3'o2: // ???
if (DCF)
io_skip <= 1;
3'o3: // DISK
if (DRL | PER | WLS | NXD | DCF)
io_skip <= 1;
endcase
endcase
end
@ -320,11 +372,6 @@ assign ADC = DMA == DWA;
begin
if (mb[1])
rx_int <= 0;
if (mb[2])
begin
io_data_out <= rx_data;
io_data_avail <= 1;
end
end
6'o04:
@ -333,8 +380,7 @@ assign ADC = DMA == DWA;
tx_int <= 0;
if (mb[2])
begin
$display("tls; %o", ac);
tx_data <= ac;
tx_data <= io_data_in;
tx_int <= 1;
tx_delaying <= 1;
tx_delay <= 4'b1111;
@ -346,43 +392,28 @@ assign ADC = DMA == DWA;
case (mb[2:0])
3'o03: // DMAR
begin
DMA <= AC;
io_clear_ac <= 0;
// clear ac
DMA <= io_data_in;
rf08_start_io <= 1;
rf08_rw <= 0;
end
3'o03: // DMAW
begin
DMA <= AC;
io_clear_ac <= 0;
// clear ac
DMA <= io_data_in;
rf08_start_io <= 1;
rf08_rw <= 1;
end
endcase // case(mb[2:0])
6'o62:
case (mb[2:0])
6: // DMAC
begin
// io_clear_ac <= 1;
io_ac <= DMA;
end
endcase
6'o64:
case (mb[2:0])
1: // DCXA
EMA <= 0;
3: // DXAL
begin
EMA <= AC;
io_clean_ac <= 1;
end
5: // DXAC
begin
AC <= EMA;
end
// clear ac
EMA <= io_data_in;
endcase
endcase
@ -412,8 +443,6 @@ assign ADC = DMA == DWA;
end
end
endcase // case(state)
end
endcase // case(state)
endmodule

22
cpu/pdp8_ram.v Normal file
View File

@ -0,0 +1,22 @@
//
`include "ram_32kx12.v"
module pdp8_ram(clk, reset, addr, data_in, data_out, rd, wr);
input clk;
input reset;
input [14:0] addr;
input [11:0] data_in;
output [11:0] data_out;
input rd;
input wr;
ram_32kx12 ram(.A(addr),
.DI(data_in),
.DO(data_out),
.CE_N(1'b0),
.WE_N(~wr));
endmodule

49
cpu/ram_32kx12.v Normal file
View File

@ -0,0 +1,49 @@
/* 32kx12 static ram */
module ram_32kx12(A, DI, DO, CE_N, WE_N);
input[14:0] A;
input[11:0] DI;
input CE_N, WE_N;
output[11:0] DO;
reg[11:0] ram [0:32767];
integer i;
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;
`include "focal.v"
ram[15'o0000] = 12'o5404;
ram[15'o0004] = 12'o0200;
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);
ram[ A ] = DI;
end
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];
endmodule

View File

@ -1,14 +1,73 @@
// run.v
// testing top end for pdp8.v
//
`include "pdp8.v"
`include "pdp8_io.v"
`include "pdp8_ram.v"
`timescale 1ns / 1ns
module test;
reg clk, reset_n;
reg[11:0] switches;
reg clk, reset;
reg [11:0] switches;
wire [11:0] ram_data_in;
wire ram_rd;
wire ram_wr;
wire [11:0] ram_data_out;
wire [14:0] ram_addr;
wire [11:0] io_data_in;
wire [11:0] io_data_out;
wire [11:0] io_addr;
wire io_data_avail;
wire io_interrupt;
wire io_skip;
wire [5:0] io_select;
wire iot;
wire [3:0] state;
wire [11:0] mb;
pdp8 cpu(.clk(clk),
.reset(reset),
.ram_addr(ram_addr),
.ram_data_in(ram_data_out),
.ram_data_out(ram_data_in),
.ram_rd(ram_rd),
.ram_wr(ram_wr),
.state(state),
.io_select(io_select),
.io_data_in(io_data_in),
.io_data_out(io_data_out),
.io_data_avail(io_data_avail),
.io_interrupt(io_interrupt),
.io_skip(io_skip),
.iot(iot),
.mb(mb),
.switches(switches));
pdp8_io io(.clk(clk),
.reset(reset),
.iot(iot),
.state(state),
.mb(mb),
.io_data_in(io_data_out),
.io_data_out(io_data_in),
.io_select(io_select),
.io_data_avail(io_data_avail),
.io_interrupt(io_interrupt),
.io_skip(io_skip));
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));
pdp8 cpu(clk, reset_n, switches);
initial
begin
@ -21,24 +80,23 @@ module test;
initial
begin
clk = 0;
reset_n = 1;
reset = 0;
#1 begin
reset_n = 0;
reset = 1;
end
#100 begin
reset_n = 1;
#50 begin
reset = 0;
end
// #1500000 $finish;
#3000000 $finish;
end
always
begin
#100 clk = 0;
#100 clk = 1;
#10 clk = 0;
#10 clk = 1;
end
//----
@ -48,21 +106,19 @@ module test;
cycle = 0;
always @(posedge cpu.clk)
if (cpu.state == 4'b0000)
// if (cpu.state == 4'b0000)
begin
cycle = cycle + 1;
#1 $display("cycle %d, r%b, pc %o, ir%o, ma %o, mb %o, jmp %b, l%b ac %o, i%b/%b",
cycle, cpu.run, cpu.pc,
#1 $display("#%d, r%b s%d, pc %o ir%o ma %o mb %o j%b l%b ac %o, i%b/%b",
cycle, cpu.run, cpu.state, cpu.pc,
cpu.ir, cpu.ma, cpu.mb, cpu.jmp, cpu.l, cpu.ac,
cpu.interrupt_enable, cpu.interrupt);
end
//#1 $display(" io_data_in %o, io_data_out %o",
//io_data_in, io_data_out);
// always @(posedge cpu.clk)
// begin
// #1 $display("state %b, runs %b, pc %o, ir %o, ma %o mb %o, jmp %b, l %b ac %o",
// cpu.state, cpu.run, cpu.pc,
// cpu.ir, cpu.ma, cpu.mb, cpu.jmp, cpu.l, cpu.ac);
// end
if (state == 4'b1100)
$finish;
end
endmodule