1
0
mirror of synced 2026-01-11 23:53:00 +00:00
2010-06-02 15:19:36 +00:00

505 lines
9.7 KiB
Verilog

// run_rf.v
// testing top end for pdp8_rf.v
//
`define debug 1
`include "../rtl/pdp8_rf.v"
`include "../rtl/ide_disk.v"
`include "../rtl/ide.v"
`include "../rtl/ram_256x12.v"
`include "../verif/fake_ram.v"
`timescale 1ns / 1ns
`ifdef use_fake_ide
`include "../verif/fake_ide.v"
`endif
module test;
reg clk, reset;
wire [11:0] io_data_out;
wire io_data_avail;
wire io_interrupt;
wire io_skip;
wire ram_read_req;
wire ram_write_req;
wire ram_done;
wire [14:0] ram_ma;
wire [11:0] ram_out;
wire [11:0] ram_in;
reg [5:0] io_select;
reg [11:0] io_data_in;
reg iot;
reg [3:0] state;
reg [11:0] mb_in;
wire ide_dior;
wire ide_diow;
wire [1:0] ide_cs;
wire [2:0] ide_da;
wire [15:0] ide_data_bus;
`ifdef use_fake_ide
fake_ide ide(.ide_dior(ide_dior),
.ide_diow(ide_diow),
.ide_cs(ide_cs),
.ide_da(ide_da),
.ide_data_bus(ide_data_bus));
`endif
pdp8_rf rf(.clk(clk),
.reset(reset),
.iot(iot),
.state(state),
.mb(mb_in),
.io_data_in(io_data_in),
.io_data_out(io_data_out),
.io_select(io_select),
.io_selected(io_selected),
.io_data_avail(io_data_avail),
.io_interrupt(io_interrupt),
.io_skip(io_skip),
.io_clear_ac(io_clear_ac),
.ram_read_req(ram_read_req),
.ram_write_req(ram_write_req),
.ram_done(ram_done),
.ram_ma(ram_ma),
.ram_in(ram_in),
.ram_out(ram_out),
.ide_dior(ide_dior),
.ide_diow(ide_diow),
.ide_cs(ide_cs),
.ide_da(ide_da),
.ide_data_bus(ide_data_bus));
fake_ram ram(.clk(clk),
.reset(reset),
.ram_read_req(ram_read_req),
.ram_write_req(ram_write_req),
.ram_done(ram_done),
.ram_ma(ram_ma),
.ram_in(ram_out),
.ram_out(ram_in));
//
task write_ram;
input [14:0] addr;
input [11:0] data;
begin
@(posedge clk);
force ram_ma = addr;
force ram_out = data;
force ram_write_req = 1;
@(posedge clk);
force ram_write_req = 0;
@(posedge clk);
release ram_ma;
release ram_out;
release ram_write_req;
@(posedge clk);
end
endtask
//
task read_ram;
input [14:0] addr;
output [11:0] data;
begin
@(posedge clk);
force ram_ma = addr;
force ram_read_req = 1;
@(posedge clk);
begin
data = ram_in;
force ram_read_req = 0;
end
@(posedge clk);
release ram_ma;
release ram_read_req;
@(posedge clk);
end
endtask
//
task write_rf_reg;
input [11:0] isn;
input [11:0] data;
begin
@(posedge clk);
begin
state = 4'h0;
mb_in = isn;
io_select = isn[8:3];
io_data_in = data;
iot = 1;
end
#20 state = 4'h1;
#20 state = 4'h2;
#20 state = 4'h3;
#20 begin
state = 4'h0;
iot = 0;
end
end
endtask
//
task read_rf_reg;
input [11:0] isn;
output [11:0] data;
begin
@(posedge clk);
begin
state = 4'h0;
mb_in = isn;
io_select = isn[8:3];
io_data_in = 0;
iot = 1;
end
#20 state = 4'h1;
#20 begin
data = io_data_out;
state = 4'h2;
end
#20 state = 4'h3;
#20 begin
state = 4'h0;
iot = 0;
end
end
endtask
//
task read_rf_skip;
input [11:0] isn;
output skip;
begin
@(posedge clk);
begin
state = 4'h0;
mb_in = isn;
io_select = isn[8:3];
io_data_in = 0;
iot = 1;
end
@(posedge clk);
state = 4'h1;
@(posedge clk);
begin
skip = io_skip;
state = 4'h2;
end
@(posedge clk);
state = 4'h3;
@(posedge clk);
begin
state = 4'h0;
iot = 0;
end
end
endtask
//
task wait_for_rf;
begin
while (rf.DCF == 1'b0)
begin
@(posedge clk);
begin
state = 4'h0;
mb_in = 0;
io_select = 0;
io_data_in = 0;
iot = 0;
end
@(posedge clk);
state = 4'h1;
@(posedge clk);
state = 4'h2;
@(posedge clk);
state = 4'h3;
@(posedge clk);
state = 4'h0;
end
end
endtask
task clear_ram;
integer a;
begin
ram.ram_debug = 0;
for (a = 0; a <= 12'o7777; a = a + 1)
write_ram(a, 0);
//ram.ram_debug = 1;
end
endtask
task failure;
input [14:0] addr;
input [11:0] got;
input [11:0] expected;
begin
$display("FAILURE addr %o, read %o, expected %o",
addr, got, expected);
$finish;
end
endtask
task fill_ram;
input [14:0] addr;
input [11:0] value;
input count;
integer count;
integer a;
begin
for (a = addr; count > 0; a = a + 1)
begin
write_ram(a, value);
count = count - 1;
end
end
endtask
task check_ram;
input [14:0] addr;
input [11:0] value;
integer a;
reg [11:0] rv;
begin
read_ram(addr, rv);
$display("check_ram: %o %o @ %o", rv, value, addr);
if (rv != value)
failure(addr, rv, value);
end
endtask
task check_fill_ram;
input [14:0] addr;
input [11:0] value;
input count;
integer count;
integer a;
reg [11:0] rv;
begin
for (a = addr; count > 0; a = a + 1)
begin
read_ram(a, rv);
if (rv != value)
failure(a, rv, value);
count = count - 1;
end
end
endtask
task write_rf;
input [17:0] da;
input [14:0] ma;
input count;
integer count;
reg [11:0] cw;
begin
cw = -count;
write_ram(14'o07750, cw); // word count
write_ram(14'o07751, ma[11:0]-1); // current addr
write_rf_reg(12'o6615, {6'b0, ma[14:12], 3'b0}); // DIML
write_rf_reg(12'o6643, {6'b0, da[17:12]}); // DXAL
write_rf_reg(12'o6605, da[11:0]); // DMAW
wait_for_rf;
end
endtask
task read_rf;
input [17:0] da;
input [14:0] ma;
input count;
integer count;
reg [11:0] cw;
begin
cw = -count;
write_ram(14'o07750, cw);
write_ram(14'o07751, ma[11:0]-1);
write_rf_reg(12'o6615, {6'b0, ma[14:12], 3'b0}); // DIML
write_rf_reg(12'o6643, {6'b0, da[17:12]}); // DXAL
write_rf_reg(12'o6603, da[11:0]); // DMAR
wait_for_rf;
end
endtask
initial
begin
$timeformat(-9, 0, "ns", 7);
$dumpfile("pdp8_rf.vcd");
$dumpvars(0, test.rf);
end
reg [11:0] data;
integer a;
initial
begin
clk = 0;
reset = 0;
#1 reset = 1;
#50 reset = 0;
//---
$display("* sanity");
clear_ram;
fill_ram(14'o00000, 12'o1111, 8);
check_fill_ram(14'o00000, 12'o1111, 8);
check_fill_ram(14'o00010, 12'o0000, 512);
check_fill_ram(14'o01010, 12'o0000, 512);
`ifdef xxx
//---
$display("* prep");
clear_ram;
write_rf(18'o000000, 14'o00000, 4096);
write_rf(18'o010000, 14'o00000, 4096);
write_rf(18'o020000, 14'o00000, 4096);
write_rf(18'o030000, 14'o00000, 4096);
write_rf(18'o040000, 14'o00000, 4096);
write_rf(18'o050000, 14'o00000, 4096);
write_rf(18'o060000, 14'o00000, 4096);
write_rf(18'o070000, 14'o00000, 4096);
`endif
`ifdef xxx
//---
$display("* write 8 words; cached");
clear_ram;
fill_ram(14'o00000, 12'o1111, 8);
write_rf(18'o000000, 14'o00000, 8);
clear_ram;
read_rf (18'o000000, 14'o01000, 8);
check_fill_ram(14'o00000, 12'o0000, 512);
check_fill_ram(14'o01000, 12'o1111, 8);
check_fill_ram(14'o01010, 12'o0000, 512);
//---
$display("* write 8 words; force write");
clear_ram;
read_rf (18'o010000, 14'o00000, 8);
//---
$display("* write 8 words; cached");
clear_ram;
fill_ram(14'o00000, 12'o2222, 8);
write_rf(18'o010000, 14'o00000, 8);
clear_ram;
read_rf (18'o010000, 14'o00000, 8);
check_fill_ram(14'o00000, 12'o2222, 8);
check_fill_ram(14'o00010, 12'o0000, 512);
read_rf (18'o000000, 14'o00000, 8);
//----
$display("* read/write 2 fields");
clear_ram;
fill_ram(14'o10000, 12'o3333, 4096);
write_rf(18'o000000, 14'o10000, 4032);
write_rf(18'o010000, 14'o00000, 4096);
read_rf (18'o000000, 14'o00000, 4032);
read_rf (18'o010000, 14'o10000, 4096);
$display("** checking");
check_fill_ram(14'o00000, 12'o3333, 4032);
check_fill_ram(14'o10000, 12'o0000, 4096);
`endif
//----
$display("* read/write individual words");
clear_ram;
read_rf (18'o000000, 14'o00000, 256);
write_ram(14'o00200, 12'o0000);
write_ram(14'o00201, 12'o1010);
write_ram(14'o00202, 12'o2020);
write_ram(14'o00203, 12'o3030);
$display("** write 4");
// rf.buffer.ram_debug = 1;
write_rf(18'o000200, 14'o00200, 4);
// rf.buffer.ram_debug = 0;
$display("** read to flush");
read_rf (18'o010000, 14'o10000, 256);
$display("** checking");
clear_ram;
read_rf (18'o000000, 14'o00000, 512);
check_ram(14'o00200, 12'o0000);
check_ram(14'o00201, 12'o1010);
check_ram(14'o00202, 12'o2020);
check_ram(14'o00203, 12'o3030);
//----
$display("* read/write individual words");
clear_ram;
read_rf (18'o000000, 14'o00000, 4032);
write_ram(14'o00204, 12'o4040);
write_ram(14'o00205, 12'o5050);
write_ram(14'o00206, 12'o6060);
write_ram(14'o00207, 12'o7070);
write_rf(18'o000204, 14'o00204, 4);
read_rf (18'o010000, 14'o10000, 4096);
$display("** checking");
clear_ram;
read_rf (18'o000000, 14'o00000, 4032);
check_ram(14'o00200, 12'o0000);
check_ram(14'o00201, 12'o1010);
check_ram(14'o00202, 12'o2020);
check_ram(14'o00203, 12'o3030);
check_ram(14'o00204, 12'o4040);
check_ram(14'o00205, 12'o5050);
check_ram(14'o00206, 12'o6060);
check_ram(14'o00207, 12'o7070);
$finish;
end
`ifndef use_fake_ide
always @(posedge clk)
begin
$pli_ide(ide_data_bus, ide_dior, ide_diow, ide_cs, ide_da);
end
`endif
always
begin
#10 clk = 0;
#10 clk = 1;
end
//----
integer cycle;
initial
cycle = 0;
always @(posedge rf.clk)
begin
cycle = cycle + 1;
end
endmodule