First compile

This commit is contained in:
techav 2021-04-11 23:46:29 -05:00
parent 0e5df6ce76
commit 89040b43b4
7 changed files with 2551 additions and 70 deletions

View File

@ -11,34 +11,75 @@
module cpusnoop ( module cpusnoop (
input wire nReset, // System Reset signal input wire nReset, // System Reset signal
input wire pixClock, // 25.175MHz Pixel Clock input wire pixClock, // 25.175MHz Pixel Clock
input logic [2:0] sequence, // Sequence count (low 3 bits of hCount) input logic [2:0] seq, // Sequence count (low 3 bits of hCount)
input logic [23:1] cpuAddr, // CPU Address bus input logic [22:0] cpuAddr, // CPU Address bus
input logic [15:0] cpuData, // CPU Data bus input logic [15:0] cpuData, // CPU Data bus
input wire ncpuAS, // CPU Address Strobe signal input wire ncpuAS, // CPU Address Strobe signal
input wire ncpuUDS, // CPU Upper Data Strobe signal input wire ncpuUDS, // CPU Upper Data Strobe signal
input wire ncpuLDS, // CPU Lower Data Strobe signal input wire ncpuLDS, // CPU Lower Data Strobe signal
input wire cpuRnW, // CPU Read/Write select signal input wire cpuRnW, // CPU Read/Write select signal
input wire cpuClk, // CPU Clock input wire cpuClk, // CPU Clock
output logic [12:0] vramAddr, // VRAM Address Bus output logic [14:0] vramAddr, // VRAM Address Bus
inout logic [7:0] vramData, // VRAM Data Bus output logic [7:0] vramDataOut,// VRAM Data Bus Output
output wire nvramWE, // VRAM Write strobe output wire nvramWE, // VRAM Write strobe
input logic [2:0] ramSize // CPU RAM size selection
); );
// framebuffer address (with 4MB RAM installed): 0x3FA700 - 0x3FFFFF /* framebuffer starts $5900 below the top of RAM
* ramSize is used to mask the cpuAddr bits [21:9] to select the amount
* of memory installed in the computer. Not all possible ramSize selections
* are valid memory sizes when using 30-pin SIMMs in the Mac SE.
* They may be possible using PDS RAM expansion cards.
* ramSize bufferStart ramTop+1 ramSize Valid? Installed SIMMs
* $7 $3fa700 $400000 4.0MB Y [ 1MB 1MB ][ 1MB 1MB ]
* $6 $37a700 $380000 3.5MB N
* $5 $2fa700 $300000 3.0MB N
* $4 $27a700 $280000 2.5MB Y [ 1MB 1MB ][256kB 256kB]
* $3 $1fa700 $200000 2.0MB Y [ 1MB 1MB ][ --- --- ]
* $2 $17a700 $180000 1.5MB N
* $1 $0fa700 $100000 1.0MB Y [256kB 256kB][256kB 256kB]
* $0 $07a700 $080000 0.5MB Y [256kB 256kB][ --- --- ]
*/
wire pendWriteLo; // low byte write to VRAM pending wire pendWriteLo; // low byte write to VRAM pending
wire pendWriteHi; // high byte write to VRAM pending wire pendWriteHi; // high byte write to VRAM pending
logic [12:1] addrCache; // store address for cpu writes to framebuffer logic [13:0] addrCache; // store address for cpu writes to framebuffer
logic [7:0] dataCacheLo; // store data for cpu writes to low byte logic [7:0] dataCacheLo; // store data for cpu writes to low byte
logic [7:0] dataCacheHi; // store data for cpu writes to high byte logic [7:0] dataCacheHi; // store data for cpu writes to high byte
wire cpuBufSel; // is CPU accessing frame buffer?
// when cpu addresses the framebuffer, set our enable signal
always_comb begin
if(ramSize == cpuAddr[20:18] && cpuAddr[22:21] == 2'b00 && cpuAddr[17:14] == 4'b1111) begin
cpuBufSel <= 1'b1;
end else begin
cpuBufSel <= 1'b0;
end
end
// when cpu addresses the framebuffer, save the address // when cpu addresses the framebuffer, save the address
always @(negedge ncpuAS or negedge nReset) begin always @(negedge ncpuAS or negedge nReset) begin
if(nReset == 1'b0) begin if(nReset == 1'b0) begin
addrCache <= 16'h0; addrCache <= 0;
end else begin end else begin
if(cpuAddr >= 24'h3FA700 && cpuAddr < 24'h400000) begin // here we match our ramSize jumpers and constants to confirm
addrCache[12:0] <= cpuAddr - 16'hA700; // the CPU is accessing the primary frame buffer
if(cpuBufSel == 1'b1) begin
// We have a match, so subtract constant $1380 from the
// cpu address and store the result in addrCache register.
// Constant $1380 corresponds to $2700 shifted right by 1.
// Once the selection bits above are masked out, we're left
// with buffer addresses starting with $2700
// e.g. with 4MB of RAM, fram buffer starts at $3FA700
// buffer address: 0011 1111 1010 0111 0000 0000 = $3FA700
// vram addr mask: 0000 0000 0011 1111 1111 1111 - $003FFF
// vram address: 0000 0000 0010 0111 0000 0000 = $002700
// Since CPU is 16-bit and does not provide A0, our cpuAddr
// signals are shifted right by one, so we need to do the same
// to our offset before subtracting it from cpuAddr
// offset: 0000 0000 0010 0111 0000 0000 = $002700
// shifted offset: 0000 0000 0001 0011 1000 0000 = $001380
addrCache <= cpuAddr[13:0] - 14'h1380;
end end
end end
end end
@ -48,18 +89,18 @@ module cpusnoop (
if(nReset == 1'b0) begin if(nReset == 1'b0) begin
dataCacheHi <= 8'h0; dataCacheHi <= 8'h0;
end else begin end else begin
if(cpuAddr >= 24'h3FA700 && cpuAddr < 24'h400000 && cpuRnW == 1'b0) begin if(cpuBufSel == 1'b1 && cpuRnW == 1'b0) begin
dataCacheHi <= cpuData[15:8]; dataCacheHi <= cpuData[15:8];
end end
end end
end end
// when cpu addresses the framebuffer, save low byte // when cpu addresses the framebuffer, save low byte
always @(negedge ncpuUDS or negedge nReset) begin always @(negedge ncpuLDS or negedge nReset) begin
if(nReset == 1'b0) begin if(nReset == 1'b0) begin
dataCacheLo <= 8'h0; dataCacheLo <= 8'h0;
end else begin end else begin
if(cpuAddr >= 24'h3FA700 && cpuAddr < 24'h400000 && cpuRnW == 1'b0) begin if(cpuBufSel == 1'b1 && cpuRnW == 1'b0) begin
dataCacheLo <= cpuData[7:0]; dataCacheLo <= cpuData[7:0];
end end
end end
@ -71,7 +112,7 @@ module cpusnoop (
pendWriteLo <= 1'b0; pendWriteLo <= 1'b0;
pendWriteHi <= 1'b0; pendWriteHi <= 1'b0;
end else begin end else begin
if(cpuAddr >= 24'h3FA700 && cpuAddr < 24'h400000 && cpuRnW == 1'b0) begin if(cpuBufSel == 1'b1 && cpuRnW == 1'b0) begin
if(ncpuUDS == 1'b0) begin if(ncpuUDS == 1'b0) begin
pendWriteHi <= 1'b1; pendWriteHi <= 1'b1;
end end
@ -79,10 +120,10 @@ module cpusnoop (
pendWriteLo <= 1'b1; pendWriteLo <= 1'b1;
end end
end else begin end else begin
if(sequence == 3'h1) begin if(seq == 3'h1) begin
pendWriteLo <= 1'b0; pendWriteLo <= 1'b0;
end end
if(sequence == 3'h2) begin if(seq == 3'h2) begin
pendWriteHi <= 1'b0; pendWriteHi <= 1'b0;
end end
end end
@ -90,19 +131,19 @@ module cpusnoop (
end end
always_comb begin always_comb begin
vramAddr[12:1] <= addrCache[12:1]; vramAddr[14:1] <= addrCache[13:0];
if(pendWriteLo == 1'b1 && sequence == 3'h1) begin if(pendWriteLo == 1'b1 && seq == 3'h1) begin
vramAddr[0] <= 1'b0; vramAddr[0] <= 1'b0;
nvramWE <= 1'b0; nvramWE <= 1'b0;
vramData <= dataCacheLo; vramDataOut <= dataCacheLo;
end else if(pendWriteHi == 1'b1 && sequence = 3'h2) begin end else if(pendWriteHi == 1'b1 && seq == 3'h2) begin
vramAddr[0] <= 1'b1; vramAddr[0] <= 1'b1;
nvramWE <= 1'b0; nvramWE <= 1'b0;
vramData <= dataCacheHi; vramDataOut <= dataCacheHi;
end else begin end else begin
vramAddr[0] <= 1'b0; vramAddr[0] <= 1'b0;
nvramWE <= 1'b1; nvramWE <= 1'b1;
vramData <= 8'bZ; vramDataOut <= 8'h0;
end end
end end
endmodule endmodule

View File

@ -7,14 +7,17 @@
* Basic modules to be used elsewhere * Basic modules to be used elsewhere
*****************************************************************************/ *****************************************************************************/
`ifndef PRIMS
`define PRIMS
// basic d-flipflop // basic d-flipflop
module dff ( module myDff (
input wire nReset, input wire nReset,
input wire clk, input wire clk,
input wire d, input wire d,
output reg q output reg q
); );
always @(posedge clock or negedge nReset) begin always @(posedge clk or negedge nReset) begin
if(nReset == 1'b0) begin if(nReset == 1'b0) begin
q <= 1'b0; q <= 1'b0;
end else begin end else begin
@ -45,7 +48,7 @@ module mux8x1 (
input logic[2:0] select, input logic[2:0] select,
output wire out output wire out
); );
assign out <= in[select]; assign out = in[select];
endmodule endmodule
// basic 8-to-1 mux with transparent output latch // basic 8-to-1 mux with transparent output latch
@ -62,11 +65,13 @@ module mux8x1latch (
// transparent latch -- when clock is low, output will // transparent latch -- when clock is low, output will
// follow the output of the mux. When clock is high, // follow the output of the mux. When clock is high,
// output will hold its last value. // output will hold its last value.
always @(clock or nReset or muxOut) begin always @(clock or nReset or muxOut or out) begin
if(nReset == 1'b0) begin if(nReset == 1'b0) begin
out <= 1'b0; out = 1'b0;
end else if(clock == 1'b0) begin end else if(clock == 1'b0) begin
out <= muxOut; out = muxOut;
end else begin
out = out;
end end
end end
endmodule endmodule
@ -84,14 +89,16 @@ module piso8 (
logic [7:0] muxOuts; logic [7:0] muxOuts;
mux8 loader(muxIns[7:0],parIn[7:0],load,muxOuts[7:0]); mux8 loader(muxIns[7:0],parIn[7:0],load,muxOuts[7:0]);
dff u0(nReset,clk,muxOuts[0],muxIns[1]); myDff u0(nReset,clk,muxOuts[0],muxIns[1]);
dff u1(nReset,clk,muxOuts[1],muxIns[2]); myDff u1(nReset,clk,muxOuts[1],muxIns[2]);
dff u2(nReset,clk,muxOuts[2],muxIns[3]); myDff u2(nReset,clk,muxOuts[2],muxIns[3]);
dff u3(nReset,clk,muxOuts[3],muxIns[4]); myDff u3(nReset,clk,muxOuts[3],muxIns[4]);
dff u4(nReset,clk,muxOuts[4],muxIns[5]); myDff u4(nReset,clk,muxOuts[4],muxIns[5]);
dff u5(nReset,clk,muxOuts[5],muxIns[6]); myDff u5(nReset,clk,muxOuts[5],muxIns[6]);
dff u6(nReset,clk,muxOuts[6],muxIns[7]); myDff u6(nReset,clk,muxOuts[6],muxIns[7]);
dff u7(nReset,clk,muxOuts[7],muxIns[0]); myDff u7(nReset,clk,muxOuts[7],muxIns[0]);
out <= muxIns[0]; assign out = muxIns[0];
endmodule endmodule
`endif

View File

@ -7,14 +7,14 @@
* Pulls together all the smaller modules to form the SE-VGA adapter * Pulls together all the smaller modules to form the SE-VGA adapter
*****************************************************************************/ *****************************************************************************/
module design sevga ( module sevga (
input wire nReset, // System reset signal input wire nReset, // System reset signal
input wire pixClk, // 25.175MHz pixel clock input wire pixClk, // 25.175MHz pixel clock
output wire nhSync, // HSync signal output wire nhSync, // HSync signal
output wire nvSync, // VSync signal output wire nvSync, // VSync signal
output wire vidOut, // 1-bit Monochrome video signal output wire vidOut, // 1-bit Monochrome video signal
output logic [12:0] vramAddr, // VRAM Address bus output logic [14:0] vramAddr, // VRAM Address bus
inout logic [7:0] vramData, // VRAM Data bus inout logic [7:0] vramData, // VRAM Data bus
output wire nvramOE, // VRAM Read strobe output wire nvramOE, // VRAM Read strobe
output wire nvramWE, // VRAM Write strobe output wire nvramWE, // VRAM Write strobe
@ -25,19 +25,21 @@ module design sevga (
input wire ncpuUDS, // CPU Upper Data Strobe signal input wire ncpuUDS, // CPU Upper Data Strobe signal
input wire ncpuLDS, // CPU Lower Data Strobe signal input wire ncpuLDS, // CPU Lower Data Strobe signal
input wire cpuRnW, // CPU Read/Write select signal input wire cpuRnW, // CPU Read/Write select signal
input wire cpuClk // CPU Clock //input wire cpuClk, // CPU Clock (probably not needed)
input logic [2:0] ramSize // Select installed RAM size
); );
logic [9:0] hCount; logic [9:0] hCount;
logic [9:0] vCount; logic [9:0] vCount;
wire hActive; wire hActive;
wire hSEActive; wire hSEActive;
wire vActive;
wire vSEActive;
//logic [7:0] vidVramData; logic [14:0] vidVramAddr;
logic [12:0] vidVramAddr; logic [14:0] cpuVramAddr;
//logic [7:0] cpuVramData; logic [7:0] vidVramData;
logic [12:0] cpuVramAddr; wire [7:0] cpuVramData;
// link module that generates all our timing signals // link module that generates all our timing signals
vgagen vgatiming( vgagen vgatiming(
@ -61,7 +63,7 @@ vgaout vidvram(
.vCount(vCount), .vCount(vCount),
.hSEActive(hSEActive), .hSEActive(hSEActive),
.vSEActive(vSEActive), .vSEActive(vSEActive),
.vramData(vramData), .vramData(vidVramData),
.vramAddr(vidVramAddr), .vramAddr(vidVramAddr),
.nvramOE(nvramOE), .nvramOE(nvramOE),
.vidOut(vidOut) .vidOut(vidOut)
@ -71,7 +73,7 @@ vgaout vidvram(
cpusnoop cpusnp( cpusnoop cpusnp(
.nReset(nReset), .nReset(nReset),
.pixClock(pixClk), .pixClock(pixClk),
.sequence(hCount[2:0]), .seq(hCount[2:0]),
.cpuAddr(cpuAddr), .cpuAddr(cpuAddr),
.cpuData(cpuData), .cpuData(cpuData),
.ncpuAS(ncpuAS), .ncpuAS(ncpuAS),
@ -79,18 +81,28 @@ cpusnoop cpusnp(
.ncpuLDS(ncpuLDS), .ncpuLDS(ncpuLDS),
.cpuRnW(cpuRnW), .cpuRnW(cpuRnW),
.cpuClk(cpuClk), .cpuClk(cpuClk),
.vramAddr(vramAddr), .vramAddr(cpuVramAddr),
.vramData(cpuVramData), .vramDataOut(cpuVramData),
.nvramWE(nvramWE) .nvramWE(nvramWE),
.ramSize(ramSize)
); );
always_comb begin always_comb begin
// vramAddr muxing // vramAddr muxing
if(.nvramWE == 1'b0) begin if(nvramWE == 1'b0) begin
vramAddr <= cpuVramAddr; vramAddr <= cpuVramAddr;
end else begin end else begin
vramAddr <= vidVramData; vramAddr <= vidVramAddr;
end end
end end
always_comb begin
if(nvramWE == 1'b0) begin
vramData <= cpuVramData;
end else begin
vramData <= 8'bZZZZZZZZ;
end
vidVramData <= vramData;
end
endmodule endmodule

2411
sevga.vwf Normal file

File diff suppressed because it is too large Load Diff

View File

@ -7,10 +7,13 @@
* Low-level VGA signal counter * Low-level VGA signal counter
*****************************************************************************/ *****************************************************************************/
`ifndef VGACOUNT
`define VGACOUNT
module vgacount ( module vgacount (
input wire nReset, // system reset signal input wire nReset, // system reset signal
input wire clock, // counter increment clock input wire clock, // counter increment clock
output logic [9:0] count, // count output output logic [9:0] count, // count output
output wire nSync, // sync pulse output wire nSync, // sync pulse
output wire activeVid, // active video signal output wire activeVid, // active video signal
output wire activeSE // secondary active video signal (SE) output wire activeSE // secondary active video signal (SE)
@ -45,23 +48,25 @@ always_comb begin
count <= counter; count <= counter;
// Sync pulse // Sync pulse
if(hCount >= SYNCBEGIN && hCount < SYNCEND) begin if(count >= SYNCBEGIN && count < SYNCEND) begin
nhSync <= 1'b0; nSync <= 1'b0;
end else begin end else begin
nhSync <= 1'b1; nSync <= 1'b1;
end end
if(hCount >= ACTBEGIN && hCount < ACTEND) begin if(count >= ACTBEGIN && count < ACTEND) begin
hActive <= 1'b0; activeVid <= 1'b0;
end else begin end else begin
hActive <= 1'b1; activeVid <= 1'b1;
end end
if(hCount >= SEACTBEGIN) begin if(count >= SEACTBEGIN) begin
hSEActive <= 1'b0; activeSE <= 1'b0;
end else begin end else begin
hSEActive <= 1'b1; activeSE <= 1'b1;
end end
end end
endmodule endmodule
`endif

View File

@ -7,6 +7,9 @@
* Generates VGA timing signals & counters * Generates VGA timing signals & counters
*****************************************************************************/ *****************************************************************************/
`ifndef VGAGEN
`define VGAGEN
`include "vgacount.sv" `include "vgacount.sv"
module vgagen ( module vgagen (
@ -25,4 +28,6 @@ module vgagen (
vgacount #(800,592,688,576,736,512) hoz(nReset,pixClk,hCount,nhSync,hActive,hSEActive); vgacount #(800,592,688,576,736,512) hoz(nReset,pixClk,hCount,nhSync,hActive,hSEActive);
vgacount #(525,421,423,411,456,342) ver(nReset,nhSync,vCount,nvSync,vActive,vSEActive); vgacount #(525,421,423,411,456,342) ver(nReset,nhSync,vCount,nvSync,vActive,vSEActive);
endmodule endmodule
`endif

View File

@ -7,7 +7,7 @@
* Fetches video data from VRAM and shifts out * Fetches video data from VRAM and shifts out
*****************************************************************************/ *****************************************************************************/
`include "primitives.sv" `include "primitives/primitives.sv"
module vgaout ( module vgaout (
input wire pixClock, input wire pixClock,
@ -16,8 +16,8 @@ module vgaout (
input logic [9:0] vCount, input logic [9:0] vCount,
input wire hSEActive, input wire hSEActive,
input wire vSEActive, input wire vSEActive,
inout logic [7:0] vramData, input logic [7:0] vramData,
output logic [12:0] vramAddr, output logic [14:0] vramAddr,
output wire nvramOE, output wire nvramOE,
output wire vidOut output wire vidOut
); );
@ -50,7 +50,7 @@ always @(posedge pixClock or negedge nReset) begin
if(nReset == 1'b0) begin if(nReset == 1'b0) begin
rVid <= 8'h0; rVid <= 8'h0;
end else begin end else begin
if(hCount[2:0] == 3'b7) begin if(hCount[2:0] == 3'h7) begin
rVid <= vramData; rVid <= vramData;
end end
end end
@ -72,7 +72,7 @@ always_comb begin
end end
// vram read signal // vram read signal
if(vidActive == 1'b1 && hCount[2:0] == 3'b7) begin if(vidActive == 1'b1 && hCount[2:0] == 3'h7) begin
nvramOE <= 1'b0; nvramOE <= 1'b0;
end else begin end else begin
nvramOE <= 1'b1; nvramOE <= 1'b1;
@ -80,7 +80,7 @@ always_comb begin
// vram address signals // vram address signals
// these will be mux'd with cpu addresses externally // these will be mux'd with cpu addresses externally
vramAddr[12:6] <= vCount[6:0]; vramAddr[14:6] <= vCount[8:0];
vramAddr[5:0] <= hCount[8:3]; vramAddr[5:0] <= hCount[8:3];
end end