BBU: Add DRAM sim, almost done with mac128k.
This commit is contained in:
parent
600f120c85
commit
602a9b564d
|
@ -1,4 +1,4 @@
|
||||||
TARGETS = bbu.vvp test_stdlogic.vvp test_mac128pal.vvp
|
TARGETS = bbu.vvp test_stdlogic.vvp test_mac128pal.vvp dram.vvp
|
||||||
|
|
||||||
all: $(TARGETS)
|
all: $(TARGETS)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,126 @@
|
||||||
|
/* Simulate asynchronous DRAM using Verilog SRAM constructs.
|
||||||
|
|
||||||
|
Written in 2020 by Andrew Makousky
|
||||||
|
|
||||||
|
Public Domain Dedication:
|
||||||
|
|
||||||
|
To the extent possible under law, the author(s) have dedicated all
|
||||||
|
copyright and related and neighboring rights to this software to
|
||||||
|
the public domain worldwide. This software is distributed without
|
||||||
|
any warranty.
|
||||||
|
|
||||||
|
You should have received a copy of the CC0 Public Domain Dedication
|
||||||
|
along with this software. If not, see
|
||||||
|
<http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
`ifndef DRAM_V
|
||||||
|
`define DRAM_V
|
||||||
|
|
||||||
|
// NOTE: The reset and clock inputs are solely for simulation
|
||||||
|
// purposes, namely for implementing DRAM row expiry. WARNING: Row
|
||||||
|
// expiry will make simulation slow!
|
||||||
|
// `define ROW_EXPIRY
|
||||||
|
|
||||||
|
/* Important! Restrictions on real DRAM that are currently not
|
||||||
|
simulated:
|
||||||
|
|
||||||
|
* Minimum hold times on *RAS and *CAS
|
||||||
|
|
||||||
|
* Maximum hold times, though maximum hold time is somewhat
|
||||||
|
implemented by virtue of row expiry.
|
||||||
|
|
||||||
|
* Timing between asserting *RAS and *CAS.
|
||||||
|
|
||||||
|
* DRAM initialization pulses before use
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 64kbyte DRAM SIMM
|
||||||
|
module dram64kbyte(n_res, clk,
|
||||||
|
n_we, n_ras, n_cas,
|
||||||
|
ra, rdq);
|
||||||
|
parameter RASBITS = 8;
|
||||||
|
parameter ROWSIZE = 2**RASBITS;
|
||||||
|
parameter WORDBITS = 8;
|
||||||
|
|
||||||
|
// Used to replicate hardware constructs that simulate DRAM expiry.
|
||||||
|
integer i, j;
|
||||||
|
|
||||||
|
input wire n_res, clk;
|
||||||
|
input wire n_we, n_ras, n_cas;
|
||||||
|
input wire [RASBITS-1:0] ra;
|
||||||
|
inout wire [WORDBITS-1:0] rdq;
|
||||||
|
|
||||||
|
reg n_we_l; // Write-enable latched value
|
||||||
|
reg [RASBITS-1:0] rowaddr, coladdr;
|
||||||
|
|
||||||
|
reg [WORDBITS-1:0] rows[0:ROWSIZE-1][0:ROWSIZE-1];
|
||||||
|
`ifdef ROW_EXPIRY
|
||||||
|
reg [15:0] rowexpire[0:ROWSIZE-1];
|
||||||
|
`endif
|
||||||
|
|
||||||
|
assign rdq = (~n_ras & ~n_cas) ? rows[rowaddr][ra] : 'bz;
|
||||||
|
|
||||||
|
always @(negedge n_res) begin
|
||||||
|
// Initialize essential internal state to some sane values.
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(negedge n_ras) begin
|
||||||
|
rowaddr <= ra;
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(negedge n_cas) begin
|
||||||
|
coladdr <= ra;
|
||||||
|
n_we_l <= n_we;
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge n_cas) begin
|
||||||
|
if (~n_we_l)
|
||||||
|
rows[rowaddr][coladdr] <= rdq;
|
||||||
|
end
|
||||||
|
|
||||||
|
`ifdef ROW_EXPIRY
|
||||||
|
always @(posedge n_ras) begin
|
||||||
|
rowexpire[rowaddr] <= 65535;
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge clk) begin
|
||||||
|
for (i = 0; i <= ROWSIZE-1; i = i + 1) begin
|
||||||
|
rowexpire[i] <= rowexpire[i] - 1;
|
||||||
|
if (rowexpire[i] == 0) begin
|
||||||
|
for (j = 0; j <= ROWSIZE-1; j = j + 1)
|
||||||
|
rows[i][j] <= 0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
`endif // ROW_EXPIRY
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
// 256kbyte DRAM SIMM
|
||||||
|
module dram256kbyte(n_res, clk,
|
||||||
|
n_we, n_ras, n_cas,
|
||||||
|
ra, rdq);
|
||||||
|
input wire n_res, clk;
|
||||||
|
input wire n_we, n_ras, n_cas;
|
||||||
|
input wire [8:0] ra;
|
||||||
|
inout wire [7:0] rdq;
|
||||||
|
|
||||||
|
dram64kbyte #(9, 2**9)
|
||||||
|
u0(n_res, clk, n_we, n_ras, n_cas, ra, rdq);
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
// 1Mbyte DRAM SIMM
|
||||||
|
module dram1mbyte(n_res, clk,
|
||||||
|
n_we, n_ras, n_cas,
|
||||||
|
ra, rdq);
|
||||||
|
input wire n_res, clk;
|
||||||
|
input wire n_we, n_ras, n_cas;
|
||||||
|
input wire [9:0] ra;
|
||||||
|
inout wire [7:0] rdq;
|
||||||
|
|
||||||
|
dram64kbyte #(10, 2**10)
|
||||||
|
u0(n_res, clk, n_we, n_ras, n_cas, ra, rdq);
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
`endif // not DRAM_V
|
|
@ -279,17 +279,19 @@ module palcl();
|
||||||
// TODO: Also implement dual video address counter ICs as part of
|
// TODO: Also implement dual video address counter ICs as part of
|
||||||
// the PAL cluster.
|
// the PAL cluster.
|
||||||
// Video address signals, comes from video counter IC
|
// Video address signals, comes from video counter IC
|
||||||
input wire va14, va13, va12, va11, va10, va9, va8, va7,
|
wire va14, va13, va12, va11, va10, va9, va8, va7,
|
||||||
va4, va3, va2, va1;
|
va6, va5, va4, va3, va2, va1;
|
||||||
// Audio address signals?
|
// Audio address signals?
|
||||||
output wire ava14, ava13;
|
output wire ava14, ava13;
|
||||||
|
|
||||||
// Video control signals
|
// Video control signals
|
||||||
output wire n_vshft, n_vsync, n_hsync, n_snddma, vid;
|
output wire n_vsync, n_hsync, vid;
|
||||||
input wire servid;
|
|
||||||
|
|
||||||
// MC68000 CPU address signals
|
// MC68000 CPU address signals
|
||||||
input wire a23, a22, a21, a20, a19, a17, a9;
|
input wire a23, a22, a21, a20, a19, a17, a16,
|
||||||
|
a15, a14, a13, a12, a11, a10, a9,
|
||||||
|
a8, a7, a6, a5, a4, a3, a2, a1;
|
||||||
|
// not used: a18
|
||||||
input wire n_as, n_uds, n_lds;
|
input wire n_as, n_uds, n_lds;
|
||||||
output wire n_dtack;
|
output wire n_dtack;
|
||||||
input wire r_n_w;
|
input wire r_n_w;
|
||||||
|
@ -311,11 +313,15 @@ module palcl();
|
||||||
|
|
||||||
// DRAM signals
|
// DRAM signals
|
||||||
output wire casl, cash, ras, we;
|
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,
|
inout wire rdq0, rdq1, rdq2, rdq3, rdq4, rdq5, rdq6, rdq7,
|
||||||
rdq8, rdq9, rdq10, rdq11, rdq12, rdq13, rdq14, rdq15;
|
rdq8, rdq9, rdq10, rdq11, rdq12, rdq13, rdq14, rdq15;
|
||||||
|
|
||||||
|
// Internal video signals
|
||||||
|
wire n_vshft, n_snddma, servid;
|
||||||
|
|
||||||
// Address multiplexer signals?
|
// Address multiplexer signals?
|
||||||
output wire s0, s1, l28, l15, g244;
|
wire s0, s1, l28, l15, n_245oe;
|
||||||
|
|
||||||
// PAL chip-select and unknown "IO" signals
|
// PAL chip-select and unknown "IO" signals
|
||||||
wire tsm_oe1, lag_oe2, bmu0_oe1, tsg_oe3;
|
wire tsm_oe1, lag_oe2, bmu0_oe1, tsg_oe3;
|
||||||
|
@ -326,7 +332,6 @@ module palcl();
|
||||||
|
|
||||||
// Wires to/from standard logic chips.
|
// Wires to/from standard logic chips.
|
||||||
wire sysclk, snddma, n_a20, n_sndres, sndres, n_snd, snd, wr, n_wr;
|
wire sysclk, snddma, n_a20, n_sndres, sndres, n_snd, snd, wr, n_wr;
|
||||||
wire n_245oe;
|
|
||||||
|
|
||||||
// N.B.: *WR comes from IWM chip, WR goes to floppy drives. *A20
|
// N.B.: *WR comes from IWM chip, WR goes to floppy drives. *A20
|
||||||
// goes to VIA.CS1. *SNDDMA comes from the LAG. *SYSCLK comes
|
// goes to VIA.CS1. *SNDDMA comes from the LAG. *SYSCLK comes
|
||||||
|
@ -337,11 +342,14 @@ module palcl();
|
||||||
wire c8mf, c16mf, n_dmald, u12f_tc, ram_r_n_w_f;
|
wire c8mf, c16mf, n_dmald, 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
|
||||||
wire n_lermd; // ???
|
wire n_lermd; // ???
|
||||||
wire n_ldps;
|
wire n_ldps; // => n_vshft
|
||||||
wire s5;
|
wire s5;
|
||||||
wire ra8, ra9;
|
|
||||||
|
|
||||||
wire vid_n_a4; // ???
|
wire vid_n_a4; // => s1
|
||||||
|
// tc => vclk
|
||||||
|
wire l13, l12; // ???
|
||||||
|
wire n_sndpg2; // ???
|
||||||
|
wire n_vidpg2; // ???
|
||||||
|
|
||||||
// TODO FIXME! We're not using assign correctly! `assign` implies
|
// TODO FIXME! We're not using assign correctly! `assign` implies
|
||||||
// diode isolation between separate nets. We want to merge
|
// diode isolation between separate nets. We want to merge
|
||||||
|
@ -359,27 +367,46 @@ module palcl();
|
||||||
they could forgo it to allow for more I/O pins. Hence the
|
they could forgo it to allow for more I/O pins. Hence the
|
||||||
motivation to use software phase correction instead. */
|
motivation to use software phase correction instead. */
|
||||||
|
|
||||||
|
// 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
|
||||||
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,
|
||||||
n_dmald, n_sndres, , , , , u12f_tc, vcc);
|
n_dmald, n_sndres, , , , , u12f_tc, vcc);
|
||||||
|
// Dual video shift registers
|
||||||
ls166 u10f(vmsh, rdq8, rdq9, rdq10, rdq11, 1'b0, c16mf, gnd,
|
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_lermd, rdq15, n_ldps, vcc);
|
||||||
ls166 u11f(s5, rdq0, rdq1, rdq2, rdq3, 1'b0, c16mf, gnd,
|
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_ldps, vcc);
|
||||||
|
// Dual RAM data bus transceivers
|
||||||
ls245 u9e(ram_r_n_w_f, rdq0, rdq1, rdq2, rdq3, rdq4, rdq5, rdq6, rdq7,
|
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);
|
gnd, d7, d6, d5, d4, d3, d2, d1, d0, n_245oe, vcc);
|
||||||
ls245 u10e(ram_r_n_w_f, rdq8, rdq9, rdq10, rdq11, rdq12, rdq13, rdq14,
|
ls245 u10e(ram_r_n_w_f, rdq8, rdq9, rdq10, rdq11, rdq12, rdq13, rdq14,
|
||||||
rdq15, gnd, d15, d14, d13, d12, d11, d10, d9, d8,
|
rdq15, gnd, d15, d14, d13, d12, d11, d10, d9, d8,
|
||||||
n_245oe, vcc);
|
n_245oe, vcc);
|
||||||
f253 u10g(snddma, vid_n_a4, va7, s5, a9, a17, ra8, gnd,
|
// 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, p0q2/*c2m*/, 1'b0, vcc);
|
||||||
|
// Dual video address counters
|
||||||
// asg u11e(c16mf, rdq0, rdq1, rdq2, rdq3, rdq4, rdq5, n_dma, vclk, gnd,
|
ls393 u1f(vclk, resnyb, va1, va2, va3, va4, gnd,
|
||||||
// tsen2, n_dmald, pwm, , , , , , , vcc);
|
va8, va7, va6, va5, reslin, resnyb, vcc);
|
||||||
|
ls393 u1g(va8, reslin, va9, va10, va11, va12, gnd,
|
||||||
|
, , l13, l12, reslin, va12, vcc);
|
||||||
|
// RAM row/column video/CPU address multiplexers
|
||||||
|
f257 u2f(p0q2/*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,
|
||||||
|
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);
|
||||||
|
f253 u3g(snddma, s1, va5, va13, a5, a13, ra4, gnd,
|
||||||
|
ra5, a14, a6, va14, va6, p0q2/*c2m*/, snddma, vcc);
|
||||||
|
f253 u4f(snddma, s1, va1, s5, a1, a9, ra0, gnd,
|
||||||
|
ra1, a10, a2, va10, va2, p0q2/*c2m*/, snddma, vcc);
|
||||||
|
f253 u4g(snddma, s1, va7, n_vidpg2, a7, a15, ra6, gnd,
|
||||||
|
ra7, a16, a8, s5, va8, p0q2/*c2m*/, snddma, vcc);
|
||||||
|
|
||||||
tsm pal0(simclk, sysclk, sysclk, pclk, s1, n_ramen, n_romen, n_as, n_uds, n_lds,
|
tsm pal0(simclk, 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);
|
gnd, tsm_oe1, casl, cash, ras, vclk, p0q2, p0q1, s0, n_dtack, vcc);
|
||||||
|
@ -390,11 +417,15 @@ module palcl();
|
||||||
bmu1 pal2(simclk, va9, va8, va7, l15, va14, ovlay, a23, a22, a21, gnd,
|
bmu1 pal2(simclk, 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);
|
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, sysclk, n_ramen, n_romen, va10, va11, va12, va13, va14,
|
||||||
r_n_w, gnd, bmu0_oe1, g244, we, ava14, l15, vid, ava13,
|
r_n_w, gnd, bmu0_oe1, n_245oe, we, ava14, l15, vid, ava13,
|
||||||
servid, n_dtack, vcc);
|
servid, n_dtack, vcc);
|
||||||
tsg pal4(simclk, sysclk, n_vpa, a19, vclk, p0q1, e, keyclk, n_intscc,
|
tsg pal4(simclk, sysclk, n_vpa, a19, vclk, p0q1, e, keyclk, n_intscc,
|
||||||
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);
|
||||||
|
|
||||||
|
// TODO FIXME: ASG not implemented.
|
||||||
|
// asg u11e(c16mf, rdq0, rdq1, rdq2, rdq3, rdq4, rdq5, n_dma, vclk, gnd,
|
||||||
|
// tsen2, n_dmald, pwm, , , , , , , vcc);
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
`endif // not MAC128PAL_V
|
`endif // not MAC128PAL_V
|
||||||
|
|
Loading…
Reference in New Issue