From 4f08c1f6fcc058eded54a7641bb922ecec0ef4c7 Mon Sep 17 00:00:00 2001 From: techav <76832805+techav-homebrew@users.noreply.github.com> Date: Wed, 4 Aug 2021 23:40:16 -0500 Subject: [PATCH] Start logic rebuild for XGA Ground-up rewrite of the video timing and output logic for XGA. Much simpler than the initial VGA logic. First draft, incomplete. --- se-vga.sv => old/se-vga.sv | 0 sevga.vwf => old/sevga.vwf | 0 vgacount.sv => old/vgacount.sv | 0 vgagen.sv => old/vgagen.sv | 0 vgaout.sv => old/vgaout.sv | 0 vgashiftout.sv => old/vgashiftout.sv | 0 vgatest.sv => old/vgatest.sv | 0 se-xga.sv | 187 +++++++++++++++++++++++++++ 8 files changed, 187 insertions(+) rename se-vga.sv => old/se-vga.sv (100%) rename sevga.vwf => old/sevga.vwf (100%) rename vgacount.sv => old/vgacount.sv (100%) rename vgagen.sv => old/vgagen.sv (100%) rename vgaout.sv => old/vgaout.sv (100%) rename vgashiftout.sv => old/vgashiftout.sv (100%) rename vgatest.sv => old/vgatest.sv (100%) create mode 100644 se-xga.sv diff --git a/se-vga.sv b/old/se-vga.sv similarity index 100% rename from se-vga.sv rename to old/se-vga.sv diff --git a/sevga.vwf b/old/sevga.vwf similarity index 100% rename from sevga.vwf rename to old/sevga.vwf diff --git a/vgacount.sv b/old/vgacount.sv similarity index 100% rename from vgacount.sv rename to old/vgacount.sv diff --git a/vgagen.sv b/old/vgagen.sv similarity index 100% rename from vgagen.sv rename to old/vgagen.sv diff --git a/vgaout.sv b/old/vgaout.sv similarity index 100% rename from vgaout.sv rename to old/vgaout.sv diff --git a/vgashiftout.sv b/old/vgashiftout.sv similarity index 100% rename from vgashiftout.sv rename to old/vgashiftout.sv diff --git a/vgatest.sv b/old/vgatest.sv similarity index 100% rename from vgatest.sv rename to old/vgatest.sv diff --git a/se-xga.sv b/se-xga.sv new file mode 100644 index 0000000..44eb0d7 --- /dev/null +++ b/se-xga.sv @@ -0,0 +1,187 @@ +/****************************************************************************** + * SE-VGA + * Top-level module + * techav + * 2021-08-04 + ****************************************************************************** + * Pulls together all the smaller modules to form the SE-VGA adapter + *****************************************************************************/ + +module sevga ( + input wire nReset, // System reset signal + input wire pixClk, // 25.175MHz pixel clock + output wire nhSync, // HSync signal + output wire nvSync, // VSync signal + output wire vidOut, // 1-bit Monochrome video signal + + output logic [14:0] vramAddr, // VRAM Address bus + inout logic [7:0] vramData, // VRAM Data bus + output wire nvramOE, // VRAM Read strobe + output wire nvramWE, // VRAM Write strobe + output wire nvramCE0, // VRAM Main chip select signal + output wire nvramCE1, // VRAM Alt chip select signal + + input logic [23:1] cpuAddr, // CPU Address bus + input logic [15:0] cpuData, // CPU Data bus + input wire ncpuAS, // CPU Address Strobe signal + input wire ncpuUDS, // CPU Upper Data Strobe signal + input wire ncpuLDS, // CPU Lower Data Strobe signal + input wire cpuRnW, // CPU Read/Write select signal + input logic [2:0] ramSize // Select installed RAM size +); + +/****************************************************************************** + * Initial Video Signal Timing + * The following four functions establish the basic XGA signal timing and + * assert the horizontal and vertical sync signals as appropriate. + * These functions are the minimum required for a signal presence detect test. + *****************************************************************************/ +logic [10:0] hCount; // 0..1343 +logic [9:0] vCount; // 0..805 + +// horizontal counter +always @(negedge pixClk or negedge nReset) begin + if(!nReset) hCount <= 0; + else begin + if(hCount < 1343) hCount <= hCount + 1; + else hCount <= 0; + end +end + +// vertical counter +always @(negedge pixClk or negedge nReset) begin + if(!nReset) vCount <= 0; + else begin + if(vCount < 805) vCount <= vCount + 1; + else vCount <= 0; + end +end + +// horizontal and vertical sync signals +always_comb begin + if(hCount >= 1049 && hCount < 1184) nhSync <= 0; + else nhSync <= 1; + + if(vCount >= 729 && vCount < 735) nvSync <= 0; + else nvSync <= 1; +end + +/****************************************************************************** + * Useful signals + * Here we break out a few useful signals, derived from the timing above, that + * will help us elsewhere. + *****************************************************************************/ +wire hActive, vActive; // active video signals. vidout black when negated +wire vidActive; // active when both hActive and vActive asserted +wire hLoad; // load pixel data from vram when asserted + +assign vidActive = hActive & vidActive; + +always_comb begin + if(hCount >= 1 && hCount < 1025) hActive <= 1; + else hActive <= 0; + + if(vCount >= 0 && vCount < 684) vActive <= 1; + else vActive <= 0; + + if(hCount >= 0 && hCount < 1024 && vActive) hLoad <= 1; + else hLoad <= 0; +end + +/****************************************************************************** + * Video Output Sequencing + * Here is the primary video output shift register sequencing. + * With these functions in place, it should be possible to strap the VRAM data + * signals and see the strapped pattern output on screen. + *****************************************************************************/ +logic [8:0] vidData; // the video data we are displaying +wire [2:0] vidSeq; // sequence counter, derived from hCount +wire tick, tock; // even/odd pulses of pixel clock divided by 2 + +assign vidSeq = hCount[3:1]; +assign tick = !hCount[0]; +assign tock = hCount[0]; + +always @(negedge pixClk or negedge nReset) begin + if(!nReset) vidData <= 0; + else + if(tock && hLoad && vidSeq == 0) begin + // store the VRAM data in vidData[8:1] + //vidData[0] <= vidData[1]; // this should actually have already been done + vidData[8:1] <= vramData; + end else if(tick && hLoad) begin + // shift vidData + vidData[7:0] <= vidData[8:1]; + vidData[8] <= 0; + end + end +end + +always_comb begin + // here is where the shifted video data actually gets output + if(vidActive) vidOut <= ~vidData[0]; + else vidOut <= 0; + + // vram read signal can be asserted here + if(vidActive && vidSeq == 0) nvramOE <= 0; + else nvramOE <= 1; +end + + +/****************************************************************************** + * CPU Bus Snooping + * Watch the CPU bus for writes to the video buffer regions of memory, cache + * the data internally until a write slot is available, then store in VRAM. + * This is the last step, and it's a big one. Once this is in place and + * operational, the adapter should be fully operational. + *****************************************************************************/ + +// to remember for later: +// vramCE[x] should be asserted when vidSeq == 0 +// vramOE should be asserted when vidSeq == 0 && vidActive +// vramWE should be asserted on tock pulses of write sequences + +/* +// link module that snoops cpu writes +cpusnoop cpusnp( + .nReset(nReset), + .pixClock(pixClk), + .seq(hCount[2:0]), + .cpuAddr(cpuAddr), + .cpuData(cpuData), + .ncpuAS(ncpuAS), + .ncpuUDS(ncpuUDS), + .ncpuLDS(ncpuLDS), + .cpuRnW(cpuRnW), + .cpuClk(cpuClk), + .vramAddr(cpuVramAddr), + .vramDataOut(cpuVramData), + .nvramWE(nvramWEpre), + .nvramCE0(nvramCE0pre), + .nvramCE1(nvramCE1pre), + .vidBufSelOut(vidBufSel), + .ramSize(ramSize) +); +*/ + +/* +cpusnoop cpusnp( + .nReset(nReset), + .pixClock(pixClk), + .seq(vidSeq), + .cpuAddr(cpuAddr), + .cpuData(cpuData), + .ncpuAS(ncpuAS), + .ncpuUDS(ncpuUDS), + .ncpuLDS(ncpuLDS), + .cpuRnW(cpuRnW), + .cpuClk(cpuClk), + .vramAddr(), + .vramDataOut(), + .nvramWE(), + .nvramCE0(), + .nvramCE1(), + .vidBufSelOut(), + .ramSize(ramSize) +); +*/ \ No newline at end of file