BBU: More analysis and insight.

This commit is contained in:
Andrew Makousky 2020-11-25 15:46:50 -06:00
parent 602a9b564d
commit c490406c81
4 changed files with 277 additions and 104 deletions

View File

@ -1496,6 +1496,10 @@ module avtimers ();
// point to ponder, this is an area of improvement where a
// different algorithm can generate better audio quality.
// Important! Main screen/sound buffers are selected when the VIA
// bit is one, alternate when the VIA bit is zero. These are
// treated as active low signals.
reg [15:0] snddsk_reg; // PCM sound sample and disk speed register
wire [23:0] snddsk_main_addr; // Address of main sound/disk buffer

View File

@ -40,9 +40,10 @@
`include "common.vh"
// PAL0-16R4: Timing State Machine
module tsm(simclk, clk, sysclk, pclk, s1, ramen, romen, as, uds, lds, gnd,
module tsm(simclk, n_res,
clk, sysclk, pclk, s1, ramen, romen, as, uds, lds, gnd,
oe1, casl, cash, ras, vclk, q2, q1, s0, dtack, vcc);
input `virtwire simclk;
input `virtwire simclk, n_res;
input wire clk;
input wire sysclk, pclk, s1, ramen, romen, as, uds, lds;
`power wire gnd;
@ -52,6 +53,14 @@ module tsm(simclk, clk, sysclk, pclk, s1, ramen, romen, as, uds, lds, gnd,
output `simwire s0, dtack;
`power wire vcc;
// We must implement RESET for simulation or else this will never
// stabilize.
always @(negedge n_res) begin
casl <= 0; cash <= 0; s0 <= 0; dtack <= 0;
ras <= 0; vclk <= 0; q2 <= 0; q1 <= 0;
end
// Simulate combinatorial logic sub-cycles.
always @(posedge simclk) begin
casl <= ~(~s0 & s1 & sysclk // video
@ -62,19 +71,19 @@ module tsm(simclk, clk, sysclk, pclk, s1, ramen, romen, as, uds, lds, gnd,
| ~s0 & ~ramen & ~uds // processor
| ~s0 & ~cash & sysclk
| pclk & ~cash);
s0 <= ~(~ras & ~sysclk // 0 for `cas` and 1 for `ras` (estamos contando com o atraso da PAL)
s0 <= ~(~ras & ~sysclk // 0 for `cas` and 1 for `ras` (counting with the delay of the PAL)
| ~ras & ~s0);
dtack <= ~(~romen // se a ROM for de 250 nS ou SCC ou IWM
| ~ras & ~ramen & ~s1 // garante que vai ser reconhecido na descida de `pclk` no estado `s5`
| ~as & ~dtack & ramen // espera `as` subir para desativar
| ~as & ~dtack & ~s1); // mas evite ciclas de video (WE)
dtack <= ~(~romen // if the ROM is 250 nS or SCC or IWM
| ~ras & ~ramen & ~s1 // guarantees that it will be recognized on the falling edge of `pclk` in state `s5`
| ~as & ~dtack & ramen // expects `as` to rise for disable
| ~as & ~dtack & ~s1); // but avoid video cycles (WE)
end
// Simulate registered logic.
always @(posedge clk) begin
ras <= ~(~pclk & q1 & s1 // video cycle
| ~pclk & q1 & ~ramen & dtack // processor cycle
| pclk & ~ras); // any other (?) (segura mais um ciclo) cycle
| pclk & ~ras); // any other cycle
vclk <= ~(~q1 & pclk & q2 & vclk // divide by 8 (1MHz)
| ~vclk & q1
| ~vclk & ~pclk
@ -95,10 +104,11 @@ endmodule
// cas of sound: pup|pup|pup|spg|pup|spg|spg|spg|3q1
// PAL1-16R8: Linear Address Generator
module lag(simclk, sysclk, p2io1, l28, va4, p0q2, vclk, va3, va2, va1,
module lag(simclk, n_res,
sysclk, p2io1, l28, va4, p0q2, vclk, va3, va2, va1,
gnd, oe2, vshft, vsync, hsync, s1, viapb6, snddma,
reslin, resnyb, vcc);
input `virtwire simclk;
input `virtwire simclk, n_res;
input wire sysclk;
input wire p2io1, l28, va4, p0q2, vclk, va3, va2, va1;
`power wire gnd;
@ -106,22 +116,29 @@ module lag(simclk, sysclk, p2io1, l28, va4, p0q2, vclk, va3, va2, va1,
output reg vshft, vsync, hsync, s1, viapb6, snddma, reslin, resnyb;
`power wire vcc;
// We must implement RESET for simulation or else this will never
// stabilize.
always @(negedge n_res) begin
vshft <= 0; vsync <= 0; hsync <= 0; s1 <= 0; viapb6 <= 0;
snddma <= 0; reslin <= 0; resnyb <= 0;
end
// Simulate combinatorial logic sub-cycles.
always @(posedge simclk) begin
end
// Simulate registered logic.
always @(posedge sysclk) begin
vshft <= ~(s1 & ~vclk & snddma); // um pulso depois da descida de `vclk`
vshft <= ~(s1 & ~vclk & snddma); // one pulse on the falling edge of `vclk`
vsync <= ~(reslin
| ~vsync & ~l28);
hsync <= ~(viapb6 & va4 & ~va3 & ~va2 & va1 // comec,a em29 (VA5)
hsync <= ~(viapb6 & va4 & ~va3 & ~va2 & va1 // begins in 29 (VA5)
| /*~ ???*/resnyb
| ~hsync & viapb6); // termina em 0F
| ~hsync & viapb6); // ends in 0F
s1 <= ~(~p0q2 // 0 for processor and 1 for video
| ~vclk
| ~vsync & hsync
| ~vsync & viapb6 // no vertical retrace s'o temos ciclos de som
| ~vsync & viapb6 // only in vertical retrace we have sound cycles
| ~viapb6 & hsync & ~va4 & ~va3 & ~va2
| ~viapb6 & ~hsync & (~va4 | va4 & ~va3 & ~va2 |
va4 & ~va3 & va2 & ~va1));
@ -131,10 +148,10 @@ module lag(simclk, sysclk, p2io1, l28, va4, p0q2, vclk, va3, va2, va1,
| ~hsync & ~viapb6
| resnyb & ~viapb6
| vshft & ~viapb6);
snddma <= ~(viapb6 & va4 & ~va3 & va2 & va1 & p0q2 & vclk & ~hsync // 0 nesta sa'ida
snddma <= ~(viapb6 & va4 & ~va3 & va2 & va1 & p0q2 & vclk & ~hsync // 0 in this output
| ~snddma & vclk); // ... indicates sound cycle
reslin <= ~(0); // ??? tentamos gerar linha 370
resnyb <= ~(vclk // incrementa VA5:VA14 em 0F e 2B
reslin <= ~(0); // ??? try to generate line 370
resnyb <= ~(vclk // increment VA5:VA14 in 0F and 2B
| viapb6 // ???
| va1
| va2
@ -146,37 +163,45 @@ module lag(simclk, sysclk, p2io1, l28, va4, p0q2, vclk, va3, va2, va1,
end
endmodule
// 32 ciclas atiuas par linha - UA6..UA1 = 0 to 1F
// 1 ciclos de som/pwm = 2B
// 11 ciclos de retrac,o = 20 to 2A
// 32 active cycles for line - UA6..UA1 = 0 to 1F
// 1 cycle for sound/PWM = 2B
// 11 cycles for retrace = 20 to 2A
// 342 linhas ativas - VA6..VA14 = 010011100 to 111110001
// 28 linhas de retrac,o = 010000000 to 010011011
// 342 active lines - VA6..VA14 = 010011100 to 111110001
// 28 retrace lines = 010000000 to 010011011
// PAL2-16L8: Bus Management Unit 1
module bmu1(simclk, va9, va8, va7, l15, va14, ovlay, a23, a22, a21, gnd,
module bmu1(simclk, n_res,
va9, va8, va7, l15, va14, ovlay, a23, a22, a21, gnd,
as, csiwm, rd, cescc, vpa, romen, ramen, io1, l28, vcc);
input `virtwire simclk;
input `virtwire simclk, n_res;
input wire va9, va8, va7, l15, va14, ovlay, a23, a22, a21;
`power wire gnd;
input wire as;
output `simwire csiwm, rd, cescc, vpa, romen, ramen, io1, l28;
`power wire vcc;
// We must implement RESET for simulation or else this will never
// stabilize.
always @(negedge n_res) begin
csiwm <= 0; rd <= 0; cescc <= 0; vpa <= 0; romen <= 0;
ramen <= 0; io1 <= 0; l28 <= 0;
end
// Simulate combinatorial logic sub-cycles.
always @(posedge simclk) begin
csiwm <= ~(a23 & a22 & ~a21 & ~as); // DFE1FF
rd <= ~(a23 & ~a22 & ~a21 & ~as); // 9FFFF8
cescc <= ~(a23 & ~a22 & ~as); // 9FFFF8(R) or BFFFF9(W)
vpa <= ~(a23 & a22 & a21 & ~as); // acima de E00000 'e s'incrano
vpa <= ~(a23 & a22 & a21 & ~as); // above E00000 is synchronous
romen <= ~(~a23 & a22 & ~a21 & ~as // 400000
| ~a23 & ~a22 & ~a21 & ~as & ovlay // (and 000000 with `ovlay`)
| a23 & ~a22 & ~as
| a23 & ~a21 & ~as); // para gerar DTACK (n~ao acessa ROM: A20)
| a23 & ~a21 & ~as); // for generating DTACK (not accessing ROM: A20)
ramen <= ~(~a23 & ~a22 & ~a21 & ~as & ~ovlay // 000000
| ~a23 & a22 & a21 & ~as & ovlay); // (600000 with `ovlay`)
io1 <= ~(0); // ???
l28 <= ~(~l15 & ~va9 & ~va8 & va7 // chegamos a 370 ou n~ao passamos da limha 28
l28 <= ~(~l15 & ~va9 & ~va8 & va7 // reached 370 or we don't pass line 28
| ~l28 & ~va9
| ~l28 & ~va8
| ~l28 & ~va7);
@ -184,9 +209,10 @@ module bmu1(simclk, va9, va8, va7, l15, va14, ovlay, a23, a22, a21, gnd,
endmodule
// PAL3-16R4: Bus Management Unit 0
module bmu0(simclk, sysclk, ramen, romen, va10, va11, va12, va13, va14, rw,
module bmu0(simclk, n_res,
sysclk, ramen, romen, va10, va11, va12, va13, va14, rw,
gnd, oe1, g244, we, ava14, l15, vid, ava13, servid, dtack, vcc);
input `virtwire simclk;
input `virtwire simclk, n_res;
input wire sysclk;
input wire ramen, romen, va10, va11, va12, va13, va14, rw;
`power wire gnd;
@ -198,28 +224,37 @@ module bmu0(simclk, sysclk, ramen, romen, va10, va11, va12, va13, va14, rw,
input wire servid, dtack;
`power wire vcc;
// We must implement RESET for simulation or else this will never
// stabilize.
always @(negedge n_res) begin
g244 <= 0; we <= 0;
ava14 <= 0; l15 <= 0; vid <= 0; ava13 <= 0;
end
// Simulate combinatorial logic sub-cycles.
always @(posedge simclk) begin
g244 <= ~(~ramen & rw
| ~g244 & ~ramen);
we <= ~(~ramen & ~rw
| ~we & ~dtack); // o dtack 'e mais curto antes de ciclo de video
| ~we & ~dtack); // or `dtack` is shorter before the video cycle
end
// Simulate registered logic.
always @(posedge sysclk) begin
ava14 <= ~(~va14 & ~va13); // + 1
l15 <= ~(~va14 & ~va13 & ~va12 & ~va11 & ~va10 // n~ao passamos da linha 15
| va14 & ~va13 & va12 & va11 & va10); // passamos de 368
vid <= ~(servid); // aqui estamos invertendo: blanking est'a em `vshft`
l15 <= ~(~va14 & ~va13 & ~va12 & ~va11 & ~va10 // we haven't passed line 15
| va14 & ~va13 & va12 & va11 & va10); // passed by 368
vid <= ~(servid); // here we invert: blanking is in `vshft`
ava13 <= ~(va13); // + 1
end
endmodule
// PAL4-16R6: Timing Signal Generator
module tsg(simclk, sysclk, vpa, a19, vclk, p0q1, e, keyclk, intscc, intvia,
module tsg(simclk, n_res,
sysclk, vpa, a19, vclk, p0q1, e, keyclk, intscc, intvia,
gnd, oe3, d0, q6, clkscc, q4, q3, viacb1, pclk, ipl0, vcc);
input `virtwire simclk;
input `virtwire simclk, n_res;
input wire sysclk;
input wire vpa, a19, vclk, p0q1, e, keyclk, intscc, intvia;
`power wire gnd;
@ -229,11 +264,20 @@ module tsg(simclk, sysclk, vpa, a19, vclk, p0q1, e, keyclk, intscc, intvia,
output `simwire ipl0;
`power wire vcc;
// We must implement RESET for simulation or else this will never
// stabilize.
always @(negedge n_res) begin
d0 <= 0; ipl0 <= 0;
q6 <= 0; clkscc <= 0; q4 <= 0; q3 <= 0; viacb1 <= 0;
pclk <= 0;
end
// Simulate combinatorial logic sub-cycles.
always @(posedge simclk) begin
ipl0 <= ~intscc | intvia; // CORRECTION
// ipl0 <= ~(0); // ??? /M nanda
d0 <= ~(~vpa & ~a19 & e); // F00000 amostra a fase como 0 /n e' + usado
d0 <= ~(~vpa & ~a19 & e); // F00000 sample the phase with 0 /n e' + usado
end
// Simulate registered logic.
@ -244,26 +288,42 @@ module tsg(simclk, sysclk, vpa, a19, vclk, p0q1, e, keyclk, intscc, intvia,
| clkscc & ~pclk & ~q3
| clkscc & ~pclk & vclk
| ~clkscc & pclk
| ~clkscc & q4 & q3 & ~vclk); // a cada 32 ciclos n~ao vira
| ~clkscc & q4 & q3 & ~vclk); // skip one inversion every 32 cycles
viacb1 <= ~(0); // ??? /M nanda
pclk <= ~(pclk); // divide SYSCLK por 2 (8MHz)
pclk <= ~(pclk); // divide SYSCLK by 2 (8MHz)
q3 <= ~(~vclk); // `sysclk` / 16
q4 <= ~(q4 & q3 & ~vclk // `sysclk` / 32
| ~q4 & ~q3 // } J p/gerar CLKSCC
| ~q4 & ~q3 // } J for generating CLKSCC
| ~q4 & vclk);
end
endmodule
/* TODO: Now in order to fully implement the Macintosh's custom board
/* Now in order to fully implement the Macintosh's custom board
capabilities, we must as a baseline have an implementation of some
standard logic chips that are found on the Macintosh Main Logic
Board. This is where we implement the modules. */
`include "stdlogic.v"
// Wire that PAL cluster together, along with supporting standard
// logic chip. Here, we try to better indicate active high and active
// low because we also need to stick in a hex inverter chip.
module palcl();
// logic chips. Here, we try to better indicate active high and
// active low because we also need to stick in a hex inverter chip.
module palcl(simclk, vcc, gnd, n_res, n_sysclk,
sysclk, pclk, p0q1, clkscc, p0q2, vclk, q3, q4,
e, keyclk,
a23, a22, a21, a20, a19, a18, a17, a16,
a15, a14, a13, a12, a11, a10, a9,
a8, a7, a6, a5, a4, a3, a2, a1,
n_as, n_uds, n_lds, n_dtack, r_n_w,
d0, d1, d2, d3, d4, d5, d6, d7,
d8, d9, d10, d11, d12, d13, d14, d15,
casl, cash, ras, we,
ra0, ra1, ra2, ra3, ra4, ra5, ra6, ra7, ra8, ra9,
rdq0, rdq1, rdq2, rdq3, rdq4, rdq5, rdq6, rdq7,
rdq8, rdq9, rdq10, rdq11, rdq12, rdq13, rdq14, rdq15,
n_intscc, n_intvia, n_ipl0,
n_ramen, n_romen, n_csiwm, n_sccrd, n_cescc, n_vpa,
viapb6, ovlay, viacb1, n_sndpg2, n_vidpg2,
n_vsync, n_hsync, vid);
input `virtwire simclk;
`power wire vcc;
`power wire gnd;
@ -272,23 +332,12 @@ module palcl();
// Clocks
// 8,4,3.686,2,1,1,0.5 MHz
output wire pclk, p0q1, clkscc, p0q2, vclk, q3, q4;
output wire sysclk, pclk, p0q1, clkscc, p0q2, vclk, q3, q4;
input wire e; // 6800 synchronous I/O "E" clock, ~1MHz
input wire keyclk;
// TODO: Also implement dual video address counter ICs as part of
// the PAL cluster.
// Video address signals, comes from video counter IC
wire va14, va13, va12, va11, va10, va9, va8, va7,
va6, va5, va4, va3, va2, va1;
// Audio address signals?
output wire ava14, ava13;
// Video control signals
output wire n_vsync, n_hsync, vid;
// MC68000 CPU address signals
input wire a23, a22, a21, a20, a19, a17, a16,
input wire a23, a22, a21, a20, a19, a18, a17, a16,
a15, a14, a13, a12, a11, a10, a9,
a8, a7, a6, a5, a4, a3, a2, a1;
// not used: a18
@ -298,27 +347,37 @@ module palcl();
inout wire d0, d1, d2, d3, d4, d5, d6, d7,
d8, d9, d10, d11, d12, d13, d14, d15;
// Chip enable signals
output wire n_ramen, n_romen, n_csiwm, n_sccrd, n_cescc, n_vpa;
// Interrupt signals
input wire n_intscc, n_intvia;
output wire n_ipl0;
// VIA signals
output wire viapb6; // horizontal blanking
input wire ovlay; // Boot-time overlay
output wire viacb1; // keyboard interrupt
// wire d0; // Video timing phase sense signal
// DRAM signals
output wire casl, cash, ras, we;
output wire ra0, ra1, ra2, ra3, ra4, ra5, ra6, ra7, ra8, ra9;
inout wire rdq0, rdq1, rdq2, rdq3, rdq4, rdq5, rdq6, rdq7,
rdq8, rdq9, rdq10, rdq11, rdq12, rdq13, rdq14, rdq15;
// Interrupt signals
input wire n_intscc, n_intvia;
output wire n_ipl0;
// Chip enable signals
output wire n_ramen, n_romen, n_csiwm, n_sccrd, n_cescc, n_vpa;
// VIA signals
output wire viapb6; // horizontal blanking
input wire ovlay; // Boot-time overlay
output wire viacb1; // keyboard interrupt
input wire n_sndpg2; // VIA PA3
input wire n_vidpg2; // VIA PA6
// wire d0; // Video timing phase sense signal
// Video control signals
output wire n_vsync, n_hsync, vid;
// Internal video address signals, comes from video counter IC
wire va14, va13, va12, va11, va10, va9, va8, va7,
va6, va5, va4, va3, va2, va1;
// Incremented high-order video address lines
wire ava14, ava13;
// Internal video signals
wire n_vshft, n_snddma, servid;
wire n_vshft, n_snddma, n_servid;
// Address multiplexer signals?
wire s0, s1, l28, l15, n_245oe;
@ -331,41 +390,54 @@ module palcl();
wire p2io1, q6;
// Wires to/from standard logic chips.
wire sysclk, snddma, n_a20, n_sndres, sndres, n_snd, snd, wr, n_wr;
wire snddma, n_a20, n_sndres, sndres, n_snd, snd, wr, n_wr;
// N.B.: *WR comes from IWM chip, WR goes to floppy drives. *A20
// goes to VIA.CS1. *SNDDMA comes from the LAG. *SYSCLK comes
// from the 16MHz crystal oscillator.
// from the 16MHz crystal oscillator. SND comes from the dual PWM
// disk driver counters.
// *DMALD is generated by ASG.
wire n_dmald; // *DMALD is generated by ASG.
wire c8mf, c16mf, n_dmald, u12f_tc, ram_r_n_w_f;
wire c8mf, c16mf, c2m, u12f_tc, ram_r_n_w_f;
wire vmsh; // video mid-shift, connect two register chips together
wire n_lermd; // ???
wire n_ldps; // => n_vshft
wire s5;
wire vid_n_a4; // => s1
wire s5; // Video shift register final output
// L12 => va13
// L13 => va14
// va12 => ava13
// va13 => ava14
// n_ldps => n_vshft
// VID/*u => s1
// tc => vclk
wire l13, l12; // ???
wire n_sndpg2; // ???
wire n_vidpg2; // ???
// TODO FIXME! We're not using assign correctly! `assign` implies
// diode isolation between separate nets. We want to merge
// multiple names together for the same net.
// N.B. on PCB, use c8mf for high-frequency signal
// filter/conditioning.
// filter/conditioning, we add a resistor.
assign c8mf = pclk;
assign c16mf = sysclk;
assign ram_r_n_w_f = we;
assign c2m = p0q2;
// TSEN0: 150 ohm resistor to GND for PAL for TSM and BMU0.
assign tsm_oe1 = gnd;
assign bmu0_oe1 = gnd;
// TSEN1: 150 ohm resistor to GND for LAG.
assign lag_oe2 = gnd;
// TSG Output Enable is controlled by CAS on Macintosh Plus,
// otherwise just go straight to ground on Macintosh 128k.
assign tsg_oe3 = gnd;
/* N.B. The reason why phase calibration is required in the
Macintosh is because the PALs do not have a RESET pin. It is
the logic designer's discretion to implement one explicitly, of
they could forgo it to allow for more I/O pins. Hence the
motivation to use software phase correction instead. */
Macintosh 128k/512k/Plus is because the PALs do not have a RESET
pin. It is the logic designer's discretion to implement one
explicitly, of they could forgo it to allow for more I/O pins.
Hence the motivation to use software phase correction
instead. */
// Inverters and 16MHz clock buffer
f04 u4d(n_sysclk, sysclk, n_snddma, snddma, a20, n_a20, gnd,
@ -377,9 +449,9 @@ module palcl();
n_dmald, n_sndres, , , , , u12f_tc, vcc);
// Dual video shift registers
ls166 u10f(vmsh, rdq8, rdq9, rdq10, rdq11, 1'b0, c16mf, gnd,
s5, rdq12, rdq13, rdq14, n_lermd, rdq15, n_ldps, vcc);
s5, rdq12, rdq13, rdq14, n_servid, rdq15, n_vshft, vcc);
ls166 u11f(s5, rdq0, rdq1, rdq2, rdq3, 1'b0, c16mf, gnd,
s5, rdq4, rdq5, rdq6, vmsh, rdq7, n_ldps, vcc);
s5, rdq4, rdq5, rdq6, vmsh, rdq7, n_vshft, vcc);
// Dual RAM data bus transceivers
ls245 u9e(ram_r_n_w_f, rdq0, rdq1, rdq2, rdq3, rdq4, rdq5, rdq6, rdq7,
gnd, d7, d6, d5, d4, d3, d2, d1, d0, n_245oe, vcc);
@ -388,38 +460,39 @@ module palcl();
n_245oe, vcc);
// RAM RA8/RA9 row/column video/CPU address multiplexer
f253 u10g(snddma, s1, va9, s5, a9, a17, ra8, gnd,
ra9, a20, a19, s5, s5, p0q2/*c2m*/, 1'b0, vcc);
ra9, a20, a19, s5, s5, c2m, 1'b0, vcc);
// Dual video address counters
ls393 u1f(vclk, resnyb, va1, va2, va3, va4, gnd,
va8, va7, va6, va5, reslin, resnyb, vcc);
ls393 u1g(va8, reslin, va9, va10, va11, va12, gnd,
, , l13, l12, reslin, va12, vcc);
, , va14, va13, reslin, va12, vcc);
// RAM row/column video/CPU address multiplexers
f257 u2f(p0q2/*c2m*/, s5, va6, ra0, n_snd, va7, ra1, gnd,
f257 u2f(c2m, s5, va6, ra0, n_snd, va7, ra1, gnd,
ra3/*???*/, va9, n_sndpg2, ra2, va8, n_sndpg2, n_snddma, vcc);
f257 u2g(p0q2/*c2m*/, s5, va10, ra4, n_sndpg2, va11, ra5, gnd,
f257 u2g(c2m, s5, va10, ra4, n_sndpg2, va11, ra5, gnd,
ra7, va13, s5, ra6, va12, s5, n_snddma, vcc);
f253 u3f(snddma, s1, va3, va11, a3, a11, ra2, gnd,
ra3, a12, a4, va12, va4, p0q2/*c2m*/, snddma, vcc);
ra3, a12, a4, va12, va4, c2m, snddma, vcc);
f253 u3g(snddma, s1, va5, va13, a5, a13, ra4, gnd,
ra5, a14, a6, va14, va6, p0q2/*c2m*/, snddma, vcc);
ra5, a14, a6, va14, va6, c2m, snddma, vcc);
f253 u4f(snddma, s1, va1, s5, a1, a9, ra0, gnd,
ra1, a10, a2, va10, va2, p0q2/*c2m*/, snddma, vcc);
ra1, a10, a2, va10, va2, c2m, snddma, vcc);
f253 u4g(snddma, s1, va7, n_vidpg2, a7, a15, ra6, gnd,
ra7, a16, a8, s5, va8, p0q2/*c2m*/, snddma, vcc);
ra7, a16, a8, s5, va8, c2m, snddma, vcc);
tsm pal0(simclk, sysclk, sysclk, pclk, s1, n_ramen, n_romen, n_as, n_uds, n_lds,
tsm pal0(simclk, n_res, sysclk, sysclk, pclk, s1, n_ramen, n_romen, n_as, n_uds, n_lds,
gnd, tsm_oe1, casl, cash, ras, vclk, p0q2, p0q1, s0, n_dtack, vcc);
lag pal1(simclk, sysclk, p2io1, l28, va4, p0q2, vclk, va3, va2, va1,
lag pal1(simclk, n_res, sysclk, p2io1, l28, va4, p0q2, vclk, va3, va2, va1,
gnd, lag_oe2, n_vshft, n_vsync, n_hsync, s1, viapb6,
n_snddma, reslin,
resnyb, vcc);
bmu1 pal2(simclk, va9, va8, va7, l15, va14, ovlay, a23, a22, a21, gnd,
bmu1 pal2(simclk, n_res, va9, va8, va7, l15, va14, ovlay, a23, a22, a21, gnd,
n_as, n_csiwm, n_sccrd, n_cescc, n_vpa, n_romen, n_ramen, p2io1, l28, vcc);
bmu0 pal3(simclk, sysclk, n_ramen, n_romen, va10, va11, va12, va13, va14,
bmu0 pal3(simclk, n_res, sysclk, n_ramen, n_romen, va10, va11, va12, va13, va14,
r_n_w, gnd, bmu0_oe1, n_245oe, we, ava14, l15, vid, ava13,
servid, n_dtack, vcc);
tsg pal4(simclk, sysclk, n_vpa, a19, vclk, p0q1, e, keyclk, n_intscc,
n_servid, n_dtack, vcc);
tsg pal4(simclk, n_res,
sysclk, n_vpa, a19, vclk, p0q1, e, keyclk, n_intscc,
n_intvia, gnd, tsg_oe3, d0, q6, clkscc, q4, q3, viacb1,
pclk, n_ipl0, vcc);

View File

@ -143,12 +143,18 @@ module ls161(n_clr, clk, a, b, c, d, enp, gnd,
assign rco = (outvec == 4'hf);
assign { q_d, q_c, q_b, q_a } = outvec;
// Clear is asynchronous, so it is not dependent on the clock.
always @(negedge n_clr) begin
if (~n_clr) outvec <= 0;
end
// N.B. As soon as the rising edge of the clock is detected under
// the proper conditions, we propagate the incremented value to the
// output pins. We do not wait until the next rising edge of the
// clock.
always @(posedge clk) begin
if (~n_clr) outvec <= 0;
if (~n_clr)
; // Nothing to be done.
else if (~n_load) outvec <= loadvec;
else if (enp & ent)
outvec <= outvec + 1;

View File

@ -4,16 +4,106 @@
`include "test_stdlogic.v"
module test_palcl();
wire vcc, gnd;
reg n_res;
reg clock;
reg simclk;
wire sysclk, pclk, p0q1, clkscc, p0q2, vclk, q3, q4;
reg e, keyclk;
reg [23:0] a;
reg n_as, n_uds, n_lds;
wire n_dtack;
reg r_n_w;
wire [15:0] d;
wire casl, cash, ras, we;
wire [9:0] ra;
wire [15:0] rdq;
reg n_intscc, n_intvia;
wire n_ipl0;
wire n_ramen, n_romen, n_csiwm, n_sccrd, n_cescc, n_vpa;
wire viapb6;
reg ovlay;
wire viacb1;
reg n_sndpg2, n_vidpg2;
wire n_vsync, n_hsync, vid;
assign vcc = 1;
assign gnd = 0;
palcl u0_palcl(simclk, vcc, gnd, n_res, clock,
sysclk, pclk, p0q1, clkscc, p0q2, vclk, q3, q4,
e, keyclk,
a[23], a[22], a[21], a[20], a[19], a[18], a[17], a[16],
a[15], a[14], a[13], a[12], a[11], a[10], a[9],
a[8], a[7], a[6], a[5], a[4], a[3], a[2], a[1],
n_as, n_uds, n_lds, n_dtack, r_n_w,
d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7],
d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15],
casl, cash, ras, we,
ra[0], ra[1], ra[2], ra[3], ra[4], ra[5], ra[6], ra[7],
ra[8], ra[9],
rdq[0], rdq[1], rdq[2], rdq[3], rdq[4], rdq[5], rdq[6],
rdq[7], rdq[8], rdq[9], rdq[10], rdq[11], rdq[12], rdq[13],
rdq[14], rdq[15],
n_intscc, n_intvia, n_ipl0,
n_ramen, n_romen, n_csiwm, n_sccrd, n_cescc, n_vpa,
viapb6, ovlay, viacb1, n_sndpg2, n_vidpg2,
n_vsync, n_hsync, vid);
// Trigger RESET at beginning of simulation. Make sure there is an
// initial falling edge.
initial begin
n_res = 1;
#2 n_res = 0;
#18 n_res = 1;
end
// Initialize clock.
initial begin
clock = 0;
simclk = 0;
e = 0;
keyclk = 0;
end
// 64 unit clock cycle (~16MHz).
always
#32 clock = ~clock;
// ~1MHz 6800 E clock
always begin
#768 e = 1; // 6 CPU clocks low
#512 e = 0; // 4 CPU clocks high
end
// Sub-cycle simulator clock triggers as fast as possible.
always
#1 simclk = ~simclk;
// Initialize all other control inputs.
initial begin
a <= 0;
n_as <= 1; n_uds <= 1; n_lds <= 1; r_n_w <= 1;
n_intscc <= 1; n_intvia <= 1; ovlay <= 1;
n_sndpg2 <= 1; n_vidpg2 <= 1;
end
endmodule
module test_mac128pal();
// Instantiate individual test modules.
test_ls161 tu0();
test_ls245 tu1();
test_palcl tu2();
// Perform the remainder of global configuration here.
// Set simulation time limit.
initial begin
#480 $finish;
#480000 $finish;
end
// We can use `$display()` for printf-style messages and implement