Transition to continuous assign, revealed equation problems.

But otherwise with problems fixed, simulation should be a lot faster.
This commit is contained in:
Andrew Makousky 2020-12-27 15:52:15 -06:00
parent 56dd957402
commit 92edcf0931
2 changed files with 98 additions and 80 deletions

View File

@ -48,38 +48,38 @@ module tsm(simclk, n_res,
input wire sysclk, pclk, s1, ramen, romen, as, uds, lds; input wire sysclk, pclk, s1, ramen, romen, as, uds, lds;
`power wire gnd; `power wire gnd;
input wire oe1; input wire oe1;
output `simwire casl, cash; output wire casl, cash;
output reg ras, vclk, q2, q1; output reg ras, vclk, q2, q1;
output `simwire s0, dtack; output wire s0, dtack;
`power wire vcc; `power wire vcc;
// We must implement RESET for simulation or else this will never // We must implement RESET for simulation or else this will never
// stabilize. // stabilize.
always @(negedge n_res) begin always @(negedge n_res) begin
casl <= 1; cash <= 1; s0 <= 1; dtack <= 1; // casl = 1; cash = 1; s0 = 1; dtack = 1;
ras <= 1; vclk <= 1; q2 <= 1; q1 <= 1; ras <= 1; vclk <= 1; q2 <= 1; q1 <= 1;
end end
// Simulate combinatorial logic sub-cycles. // Simulate combinatorial logic.
always @(posedge simclk) begin assign casl
if (n_res) begin = ~(~s0 & s1 & sysclk // video
casl <= ~(~s0 & s1 & sysclk // video | ~s0 & ~ramen & ~lds // processor
| ~s0 & ~ramen & ~lds // processor | ~s0 & ~casl & sysclk
| ~s0 & ~casl & sysclk | pclk & ~casl);
| pclk & ~casl); assign cash
cash <= ~(~s0 & s1 & sysclk // video = ~(~s0 & s1 & sysclk // video
| ~s0 & ~ramen & ~uds // processor | ~s0 & ~ramen & ~uds // processor
| ~s0 & ~cash & sysclk | ~s0 & ~cash & sysclk
| pclk & ~cash); | pclk & ~cash);
s0 <= ~(~ras & ~sysclk // 0 for `cas` and 1 for `ras` (counting with the delay of the PAL) assign s0
| ~ras & ~s0); = ~(~ras & ~sysclk // 0 for `cas` and 1 for `ras` (counting with the delay of the PAL)
dtack <= ~(~romen // if the ROM is 250 nS or SCC or IWM | ~ras & ~s0);
| ~ras & ~ramen & ~s1 // guarantees that it will be recognized on the falling edge of `pclk` in state `s5` assign dtack
| ~as & ~dtack & ramen // expects `as` to rise for disable = ~(~romen // if the ROM is 250 nS or SCC or IWM
| ~as & ~dtack & ~s1); // but avoid video cycles (WE) | ~ras & ~ramen & ~s1 // guarantees that it will be recognized on the falling edge of `pclk` in state `s5`
end | ~as & ~dtack & ramen // expects `as` to rise for disable
end | ~as & ~dtack & ~s1); // but avoid video cycles (WE)
// Simulate registered logic. // Simulate registered logic.
always @(posedge clk) begin always @(posedge clk) begin
@ -131,10 +131,6 @@ module lag(simclk, n_res,
snddma <= 1; reslin <= 1; resnyb <= 1; snddma <= 1; reslin <= 1; resnyb <= 1;
end end
// Simulate combinatorial logic sub-cycles.
always @(posedge simclk) begin
end
// Simulate registered logic. // Simulate registered logic.
always @(posedge sysclk) begin always @(posedge sysclk) begin
if (n_res) begin if (n_res) begin
@ -187,6 +183,8 @@ module lag(simclk, n_res,
// | ~viapb6 & vclk); // | ~viapb6 & vclk);
// TODO FIXME: This is incorrect, temporary equations in order // TODO FIXME: This is incorrect, temporary equations in order
// to get at least partial behavior for analysis. // to get at least partial behavior for analysis.
// TODO FIXME: Why this latches up and is broken, we should not
// use memory access to clock this to one sensitivity cycle.
viapb6 <= viapb6 <=
~(~hsync // 1 indicates horizontal retrace (pseudo VA6) ~(~hsync // 1 indicates horizontal retrace (pseudo VA6)
| ~viapb6 & p0q2 | ~viapb6 & p0q2
@ -279,37 +277,42 @@ module bmu1(simclk, n_res,
input wire va9, va8, va7, l15, va14, ovlay, a23, a22, a21; input wire va9, va8, va7, l15, va14, ovlay, a23, a22, a21;
`power wire gnd; `power wire gnd;
input wire as; input wire as;
output `simwire csiwm, rd, cescc, vpa, romen, ramen, io1, l28; output wire csiwm, rd, cescc, vpa, romen, ramen, io1, l28;
`power wire vcc; `power wire vcc;
// We must implement RESET for simulation or else this will never // We must implement RESET for simulation or else this will never
// stabilize. // stabilize.
always @(negedge n_res) begin always @(negedge n_res) begin
csiwm <= 1; rd <= 1; cescc <= 1; vpa <= 1; romen <= 1; // csiwm = 1; rd = 1; cescc = 1; vpa = 1; romen = 1;
ramen <= 1; io1 <= 1; l28 <= 1; // ramen = 1; io1 = 1; l28 = 1;
end end
// Simulate combinatorial logic sub-cycles. // Simulate combinatorial logic.
always @(posedge simclk) begin assign csiwm
if (n_res) begin = ~(a23 & a22 & ~a21 & ~as); // DFE1FF
csiwm <= ~(a23 & a22 & ~a21 & ~as); // DFE1FF assign rd
rd <= ~(a23 & ~a22 & ~a21 & ~as); // 9FFFF8 = ~(a23 & ~a22 & ~a21 & ~as); // 9FFFF8
cescc <= ~(a23 & ~a22 & ~as); // 9FFFF8(R) or BFFFF9(W) assign cescc
vpa <= ~(a23 & a22 & a21 & ~as); // above E00000 is synchronous = ~(a23 & ~a22 & ~as); // 9FFFF8(R) or BFFFF9(W)
romen <= ~(~a23 & a22 & ~a21 & ~as // 400000 assign vpa
| ~a23 & ~a22 & ~a21 & ~as & ovlay // (and 000000 with `ovlay`) = ~(a23 & a22 & a21 & ~as); // above E00000 is synchronous
| a23 & ~a22 & ~as assign romen
| a23 & ~a21 & ~as); // for generating DTACK (not accessing ROM: A20) = ~(~a23 & a22 & ~a21 & ~as // 400000
ramen <= ~(~a23 & ~a22 & ~a21 & ~as & ~ovlay // 000000 | ~a23 & ~a22 & ~a21 & ~as & ovlay // (and 000000 with `ovlay`)
| ~a23 & a22 & a21 & ~as & ovlay); // (600000 with `ovlay`) | a23 & ~a22 & ~as
io1 <= ~(0); // TODO this indicates we're >= line 28 | a23 & ~a21 & ~as); // for generating DTACK (not accessing ROM: A20)
l28 <= ~(~l15 & ~va9 & ~va8 & va7 // reached 370 or we don't pass line 28 assign ramen
| ~l28 & ~l15 = ~(~a23 & ~a22 & ~a21 & ~as & ~ovlay // 000000
| ~l28 & ~va9 | ~a23 & a22 & a21 & ~as & ovlay); // (600000 with `ovlay`)
| ~l28 & ~va8 assign io1
| ~l28 & va7); = ~(0); // TODO this indicates we're >= line 28
end assign l28
end = ~(~l15 & ~va9 & ~va8 & va7 // reached 370 or we don't pass line 28
| ~l28 & ~l15
| ~l28 & ~va9
| ~l28 & ~va8
| ~l28 & va7
| ~n_res); // SIMULATION ONLY: Else we never settle.
endmodule endmodule
// PAL3-16R4: Bus Management Unit 0 // PAL3-16R4: Bus Management Unit 0
@ -321,7 +324,7 @@ module bmu0(simclk, n_res,
input wire ramen, romen, va10, va11, va12, va13, va14, rw; input wire ramen, romen, va10, va11, va12, va13, va14, rw;
`power wire gnd; `power wire gnd;
input wire oe1; input wire oe1;
output `simwire g244, we; output wire g244, we;
output reg ava14, l15, vid, ava13; output reg ava14, l15, vid, ava13;
// N.B. Although this is nominally an output we can treat it as an // N.B. Although this is nominally an output we can treat it as an
// input? // input?
@ -331,20 +334,18 @@ module bmu0(simclk, n_res,
// We must implement RESET for simulation or else this will never // We must implement RESET for simulation or else this will never
// stabilize. // stabilize.
always @(negedge n_res) begin always @(negedge n_res) begin
g244 <= 1; we <= 1; // g244 = 1; we = 1;
ava14 <= 1; l15 <= 1; vid <= 1; ava13 <= 1; ava14 <= 1; l15 <= 1; vid <= 1; ava13 <= 1;
end end
// Simulate combinatorial logic sub-cycles. // Simulate combinatorial logic.
always @(posedge simclk) begin assign g244
if (n_res) begin = ~(~ramen & rw
g244 <= ~(~ramen & rw | ~g244 & ~ramen);
| ~g244 & ~ramen); assign we
we <= ~(~ramen & ~rw = ~(~ramen & ~rw
| ~we & ~dtack); // or `dtack` is shorter before the video cycle | ~we & ~dtack); // or `dtack` is shorter before the video cycle
end
end
// Simulate registered logic. // Simulate registered logic.
always @(posedge sysclk) begin always @(posedge sysclk) begin
@ -369,28 +370,26 @@ module tsg(simclk, n_res,
input wire vpa, a19, vclk, p0q1, e, keyclk, intscc, intvia; input wire vpa, a19, vclk, p0q1, e, keyclk, intscc, intvia;
`power wire gnd; `power wire gnd;
input wire oe3; input wire oe3;
output `simwire d0; output wire d0;
output reg q6, clkscc, q4, q3, viacb1, pclk; output reg q6, clkscc, q4, q3, viacb1, pclk;
output `simwire ipl0; output wire ipl0;
`power wire vcc; `power wire vcc;
// We must implement RESET for simulation or else this will never // We must implement RESET for simulation or else this will never
// stabilize. // stabilize.
always @(negedge n_res) begin always @(negedge n_res) begin
d0 <= 1; ipl0 <= 1; // d0 = 1; ipl0 = 1;
q6 <= 1; clkscc <= 1; q4 <= 1; q3 <= 1; viacb1 <= 1; q6 <= 1; clkscc <= 1; q4 <= 1; q3 <= 1; viacb1 <= 1;
pclk <= 1; pclk <= 1;
end end
// Simulate combinatorial logic sub-cycles. // Simulate combinatorial logic.
always @(posedge simclk) begin assign ipl0
if (n_res) begin = ~intscc | intvia; // CORRECTION
ipl0 <= ~intscc | intvia; // CORRECTION // assign ipl0 = ~(0); // ??? /M nanda
// ipl0 <= ~(0); // ??? /M nanda assign d0
d0 <= ~(~vpa & ~a19 & e); // F00000 sample the phase with 0 /n e' + usado = ~(~vpa & ~a19 & e); // F00000 sample the phase with 0 /n e' + usado
end
end
// Simulate registered logic. // Simulate registered logic.
always @(posedge sysclk) begin always @(posedge sysclk) begin
@ -513,8 +512,14 @@ module palcl(simclk, vcc, gnd, n_res, n_sysclk,
// from the 16MHz crystal oscillator. SND comes from the dual PWM // from the 16MHz crystal oscillator. SND comes from the dual PWM
// disk driver counters. // disk driver counters.
wire n_dmald; // *DMALD is generated by ASG. // *DMALD is generated by ASG. It's very similar to how *LDPS is
// generated.
// n_dmald <=
// ~(s1 & ~vclk & ~n_snddma);
wire n_dmald;
// u12f_tc is the carry propagation signal for the dual PWM sound
// counters.
wire c8mf, c16mf, c2m, 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 vmsh; // video mid-shift, connect two register chips together
@ -546,8 +551,10 @@ module palcl(simclk, vcc, gnd, n_res, n_sysclk,
assign bmu0_oe1 = gnd; assign bmu0_oe1 = gnd;
// TSEN1: 150 ohm resistor to GND for LAG. // TSEN1: 150 ohm resistor to GND for LAG.
assign lag_oe2 = gnd; assign lag_oe2 = gnd;
// TSG Output Enable is controlled by CAS on Macintosh Plus, // Pull-down resistor shared by TSG, ASG, and CAS (if present).
// otherwise just go straight to ground on Macintosh 128k. // TODO INVESTIGATE: Surely this is controlled by another switch
// related to the RAM data bus switches, otherwise D0 is
// unconditionally coerced for non-phase read accesses.
assign tsg_oe3 = gnd; assign tsg_oe3 = gnd;
// S5: Pull-up resistor. TODO FIXME: Should this be controlled by // S5: Pull-up resistor. TODO FIXME: Should this be controlled by
// another thing too? // another thing too?
@ -566,7 +573,9 @@ module palcl(simclk, vcc, gnd, n_res, n_sysclk,
// Inverters and 16MHz clock buffer // Inverters and 16MHz clock buffer
f04 u4d(n_sysclk, sysclk, n_snddma, snddma, a20, n_a20, gnd, f04 u4d(n_sysclk, sysclk, n_snddma, snddma, a20, n_a20, gnd,
n_sndres, sndres, n_snd, snd, wr, n_wr, vcc); n_sndres, sndres, n_snd, snd, wr, n_wr, vcc);
// Dual PWM disk drive counters // Dual PWM sound counters. The final carry-out is the PWM sound
// signal, and it is inverted and fed back to the sound counters to
// form a saturating counter.
ls161 u13e(n_sndres, c8mf, rdq12, rdq13, rdq14, rdq15, n_snd, gnd, ls161 u13e(n_sndres, c8mf, rdq12, rdq13, rdq14, rdq15, n_snd, gnd,
n_dmald, u12f_tc, , , , , snd, vcc); n_dmald, u12f_tc, , , , , snd, vcc);
ls161 u12f(n_sndres, c8mf, rdq8, rdq9, rdq10, rdq11, n_snd, gnd, ls161 u12f(n_sndres, c8mf, rdq8, rdq9, rdq10, rdq11, n_snd, gnd,
@ -620,6 +629,9 @@ module palcl(simclk, vcc, gnd, n_res, n_sysclk,
n_intvia, gnd, tsg_oe3, d0, q6, clkscc, q4, q3, viacb1, n_intvia, gnd, tsg_oe3, d0, q6, clkscc, q4, q3, viacb1,
pclk, n_ipl0, vcc); pclk, n_ipl0, vcc);
// N.B.: ASG as a "sound generator" is largely a misnomer, it is
// primarily a PWM disk speed generator.
// TODO FIXME: ASG not implemented. // TODO FIXME: ASG not implemented.
// asg u11e(c16mf, rdq0, rdq1, rdq2, rdq3, rdq4, rdq5, n_dma, vclk, gnd, // asg u11e(c16mf, rdq0, rdq1, rdq2, rdq3, rdq4, rdq5, n_dma, vclk, gnd,
// tsen2, n_dmald, pwm, , , , , , , vcc); // tsen2, n_dmald, pwm, , , , , , , vcc);

View File

@ -81,8 +81,14 @@ module test_palcl();
end end
// Sub-cycle simulator clock triggers as fast as possible. // Sub-cycle simulator clock triggers as fast as possible.
always
#1 simclk = ~simclk; // N.B.: This is now disabled as it has been vetted that Verilog is
// designed to simulate self-referential combinatorial logic
// equations just fine. Disabling this helps speed up the
// simulation.
// always
// #1 simclk = ~simclk;
// Initialize all other control inputs. // Initialize all other control inputs.
initial begin initial begin
@ -103,10 +109,10 @@ module test_mac128pal();
// Set simulation time limit. // Set simulation time limit.
initial begin initial begin
// #1920000 $finish; #1920000 $finish;
// PLEASE NOTE: We must simulate LOTS of cycles in order to see // PLEASE NOTE: We must simulate LOTS of cycles in order to see
// what the oscilloscope trace for one video frame looks like. // what the oscilloscope trace for one video frame looks like.
#30720000 $finish; // #30720000 $finish;
end end
// We can use `$display()` for printf-style messages and implement // We can use `$display()` for printf-style messages and implement