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:
parent
0adc80d5fd
commit
595692fe2b
1155
cpu/pdp8.v
1155
cpu/pdp8.v
File diff suppressed because it is too large
Load Diff
217
cpu/pdp8_io.v
217
cpu/pdp8_io.v
@ -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
22
cpu/pdp8_ram.v
Normal 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
49
cpu/ram_32kx12.v
Normal 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
|
||||
|
||||
96
cpu/run.v
96
cpu/run.v
@ -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
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user