diff --git a/cpusnoop.sv b/cpusnoop.sv index 123d810..ad8fbdc 100644 --- a/cpusnoop.sv +++ b/cpusnoop.sv @@ -36,12 +36,12 @@ module cpusnoop ( // define state machine states parameter - S0 = 3'h0, - S1 = 3'h1, - S2 = 3'h2, - S3 = 3'h3, - S4 = 3'h4, - S5 = 3'h5; + S0 = 0, + //S1 = 3'h1, + S2 = 2, + S3 = 3, + S4 = 4, + S5 = 5; // when cpu addresses the framebuffer, set our enable signal /* framebuffer starts $5900 below the top of RAM @@ -89,28 +89,11 @@ module cpusnoop ( case (cycleState) S0 : begin // idle state, wait for valid address and ncpuAS asserted - if(ncpuAS == 0 && cpuBufSel == 1 && cpuRnW == 0) begin - cycleState <= S1; - end else begin - cycleState <= S0; - end - end - S1 : begin - // wait for either ncpuUDS or ncpuLDS to assert - // if ncpuAS negates first, then abort back to S0 - if(ncpuAS == 1) begin - // cpu aborted cycle - cycleState <= S0; - end else if(ncpuUDS == 0 || ncpuLDS == 0) begin - if (ncpuUDS == 0) begin - pendWriteHi <= 1; - dataCacheHi <= cpuData[15:8]; - end - if (ncpuLDS == 0) begin - pendWriteLo <= 1; - dataCacheLo <= cpuData[7:0]; - end - + if(ncpuAS == 0 && cpuBufSel == 1 && cpuRnW == 0 && (ncpuLDS == 0 || ncpuUDS == 0)) begin + pendWriteHi <= !ncpuUDS; + pendWriteLo <= !ncpuLDS; + dataCacheHi <= cpuData[15:8]; + dataCacheLo <= cpuData[7:0]; // Valid CPU-VRAM cycle, so subtract constant $1380 from the // cpu address and store the result in addrCache register. // Constant $1380 corresponds to $2700 shifted right by 1. @@ -126,27 +109,39 @@ module cpusnoop ( // offset: 0000 0000 0010 0111 0000 0000 = $002700 // shifted offset: 0000 0000 0001 0011 1000 0000 = $001380 addrCache <= cpuAddr[13:0] - 14'h1380; - + cycleState <= S2; end else begin - cycleState <= S1; + cycleState <= S0; end end S2 : begin // wait for sequence - if(pendWriteHi == 1 && pendWriteLo == 1 && seq < 5) begin - // we have enough time to write both before the next VRAM read - cycleState <= S3; - end else if(seq < 6) begin - // we have enough time to write the one pending before next VRAM read - if(pendWriteLo == 0) begin - cycleState <= S4; - end else begin + if(pendWriteHi == 1 && pendWriteLo == 1) begin + if(seq < 5) begin + // we have enough time to write both before the next VRAM read cycleState <= S3; + end else begin + // we don't have enough time to write both. hold for now + cycleState <= S2; + end + end else if(pendWriteHi == 1 || pendWriteLo == 1) begin + if(seq < 6) begin + // we have enough time for the pending write + if(pendWriteLo == 0) begin + // move on to write high byte + cycleState <= S4; + end else begin + // move on to write low byte + cycleState <= S3; + end + end else begin + // not enough time for a write cycle. hold for now + cycleState <= S2; end end else begin - // no time for a write sequence, wait - cycleState <= S2; + // we shouldn't be here. Somehow we have slipped through without setting flags. + cycleState <= S0; end end S3 : begin @@ -165,7 +160,6 @@ module cpusnoop ( end S5 : begin // wait for CPU to negate both ncpuUDS and ncpuLDS - //if(ncpuUDS == 1 && ncpuLDS == 1) begin if(cpuCycleEnded == 1) begin cycleState <= S0; end else begin @@ -183,9 +177,9 @@ module cpusnoop ( always_comb begin vramAddr[14:1] <= addrCache[13:0]; if(cycleState == S4) begin - vramAddr[0] <= 1; - end else begin vramAddr[0] <= 0; + end else begin + vramAddr[0] <= 1; end if(cycleState == S3 || cycleState == S4) begin @@ -203,99 +197,4 @@ module cpusnoop ( end end -/* - - - // when cpu addresses the framebuffer, save the address - always @(negedge ncpuAS or negedge nReset) begin - if(nReset == 1'b0) begin - addrCache <= 0; - end else begin - // here we match our ramSize jumpers and constants to confirm - // the CPU is accessing the primary frame buffer - //if(cpuBufSel == 1'b1) begin - if(ramSize == cpuAddr[20:18] && cpuAddr[22:21] == 2'b00 && cpuAddr[17:14] == 4'b1111) 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 - - // when cpu addresses the framebuffer, save high byte - always @(negedge ncpuUDS or negedge nReset) begin - if(nReset == 1'b0) begin - dataCacheHi <= 8'h0; - end else begin - if(cpuBufSel == 1'b1 && cpuRnW == 1'b0) begin - dataCacheHi <= cpuData[15:8]; - end - end - end - - // when cpu addresses the framebuffer, save low byte - always @(negedge ncpuLDS or negedge nReset) begin - if(nReset == 1'b0) begin - dataCacheLo <= 8'h0; - end else begin - if(cpuBufSel == 1'b1 && cpuRnW == 1'b0) begin - dataCacheLo <= cpuData[7:0]; - end - end - end - - // set pending flags for cpu accesses & clear when that cycle comes back around - /*always @(negedge pixClock or negedge nReset) begin - if(nReset == 1'b0) begin - pendWriteLo <= 1'b0; - pendWriteHi <= 1'b0; - end else begin - if(cpuBufSel == 1'b1 && cpuRnW == 1'b0) begin - if(ncpuUDS == 1'b0) begin - pendWriteHi <= 1'b1; - end - if(ncpuLDS == 1'b0) begin - pendWriteLo <= 1'b1; - end - end else begin - if(seq == 1 || seq == 3 || seq == 5) begin - pendWriteLo <= 1'b0; - end - if(seq == 2 || seq == 4 || seq == 6) begin - pendWriteHi <= 1'b0; - end - end - end - end*/ -/* - - always_comb begin - vramAddr[14:1] <= addrCache[13:0]; - if(pendWriteLo == 1'b1 && (seq == 1 || seq == 3 || seq == 5)) begin - vramAddr[0] <= 1'b0; - nvramWE <= 1'b0; - vramDataOut <= dataCacheLo; - end else if(pendWriteHi == 1'b1 && (seq == 2 || seq == 4 || seq == 6)) begin - vramAddr[0] <= 1'b1; - nvramWE <= 1'b0; - vramDataOut <= dataCacheHi; - end else begin - vramAddr[0] <= 1'b0; - nvramWE <= 1'b1; - vramDataOut <= 8'h0; - end - end -*/ endmodule \ No newline at end of file diff --git a/primitives/primitives.sv b/primitives/primitives.sv deleted file mode 100644 index 3c51e82..0000000 --- a/primitives/primitives.sv +++ /dev/null @@ -1,157 +0,0 @@ -/****************************************************************************** - * SE-VGA - * Primitives - * techav - * 2021-04-06 - ****************************************************************************** - * Basic modules to be used elsewhere - *****************************************************************************/ - -`ifndef PRIMS - `define PRIMS - -/* -// basic d-flipflop -module myDff ( - input wire nReset, - input wire clk, - input wire d, - output reg q -); - always @(posedge clk or negedge nReset) begin - if(nReset == 1'b0) begin - q <= 1'b0; - end else begin - q <= d; - end - end -endmodule -*/ - -/* -// basic 8-bit mux -module mux8 ( - input logic [7:0] inA, - input logic [7:0] inB, - input wire select, - output logic [7:0] out -); - always_comb begin - if(select == 1'b0) begin - out <= inA; - end else begin - out <= inB; - end - end -endmodule -*/ - -/* -// basic 8-to-1 mux -module mux8x1 ( - input logic[7:0] in, - input logic[2:0] select, - output wire out -); - assign out = in[select]; -endmodule -*/ - -/* -// basic 8-to-1 mux with transparent output latch -module mux8x1latch ( - input logic[7:0] in, - input logic[2:0] select, - input wire clock, - input wire nReset, - output reg out -); - wire muxOut; - mux8x1 mux (in,select,muxOut); - - // transparent latch -- when clock is low, output will - // follow the output of the mux. When clock is high, - // output will hold its last value. - always @(clock or nReset or muxOut or out) begin - if(nReset == 1'b0) begin - out = 1'b0; - end else if(clock == 1'b0) begin - out = muxOut; - end else begin - out = out; - end - end -endmodule -*/ - -/* -// basic 8-bit PISO shift register -module piso8 ( - input wire nReset, - input wire clk, - input wire load, - input logic [7:0] parIn, - output wire out -); - - logic [7:0] muxIns; - logic [7:0] muxOuts; - - mux8 loader(muxIns[7:0],parIn[7:0],load,muxOuts[7:0]); - myDff u0(nReset,clk,muxOuts[0],muxIns[1]); - myDff u1(nReset,clk,muxOuts[1],muxIns[2]); - myDff u2(nReset,clk,muxOuts[2],muxIns[3]); - myDff u3(nReset,clk,muxOuts[3],muxIns[4]); - myDff u4(nReset,clk,muxOuts[4],muxIns[5]); - myDff u5(nReset,clk,muxOuts[5],muxIns[6]); - myDff u6(nReset,clk,muxOuts[6],muxIns[7]); - myDff u7(nReset,clk,muxOuts[7],muxIns[0]); - - assign out = muxIns[0]; -endmodule -*/ - -module vidShiftOut ( - input wire nReset, - input wire clk, - input wire vidActive, - input logic [2:0] seq, - input logic [7:0] parIn, - output wire out -); - /* Shift register functioning similar to a 74597, with 8-bit input latch - * and 8-bit PISO shift register output stage. - * In sequence 7 new data is loaded from VRAM into the input stage, and in - * sequence 0 the input stage is copied to the output stage to be shifted. - */ - reg [7:0] inReg; - reg [7:0] outReg; - - always @(negedge clk or negedge nReset) begin - if(nReset == 1'b0) begin - inReg <= 0; - outReg <= 0; - end else begin - if(vidActive == 1'b1) begin - if(seq == 0) begin - outReg <= inReg; - end else begin - outReg[7] <= outReg[6]; - outReg[6] <= outReg[5]; - outReg[5] <= outReg[4]; - outReg[4] <= outReg[3]; - outReg[3] <= outReg[2]; - outReg[2] <= outReg[1]; - outReg[1] <= outReg[0]; - outReg[0] <= 1'b0; - end - if(seq == 7) begin - inReg <= parIn; - end - end - end - end - assign out = outReg[7]; -endmodule - -`endif \ No newline at end of file diff --git a/se-vga.sv b/se-vga.sv index acba970..abea33c 100644 --- a/se-vga.sv +++ b/se-vga.sv @@ -70,7 +70,7 @@ vgaout vidvram( .vidOut(vidOut) ); -// link module that handles cpu writes +// link module that snoops cpu writes cpusnoop cpusnp( .nReset(nReset), .pixClock(pixClk), @@ -92,8 +92,10 @@ always_comb begin // vramAddr muxing if(nvramWEpre == 1'b0) begin vramAddr <= cpuVramAddr; - end else begin + end else if(nvramOE == 0) begin vramAddr <= vidVramAddr; + end else begin + vramAddr <= 0; end end diff --git a/sevga.vwf b/sevga.vwf index d6084e2..e966246 100644 --- a/sevga.vwf +++ b/sevga.vwf @@ -1961,7 +1961,55 @@ TRANSITION_LIST("vramData[7]") LEVEL 0 FOR 80.0; LEVEL Z FOR 240.0; LEVEL 0 FOR 80.0; - LEVEL Z FOR 32000.0; + LEVEL Z FOR 280.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 2880.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 960.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 960.0; + LEVEL 1 FOR 1920.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 960.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 1280.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 960.0; + LEVEL 0 FOR 1920.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 1280.0; + LEVEL 1 FOR 1280.0; + LEVEL 0 FOR 960.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 40.0; } } @@ -1976,7 +2024,55 @@ TRANSITION_LIST("vramData[6]") LEVEL 1 FOR 80.0; LEVEL Z FOR 240.0; LEVEL 0 FOR 80.0; - LEVEL Z FOR 32000.0; + LEVEL Z FOR 280.0; + LEVEL 0 FOR 960.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 960.0; + LEVEL 0 FOR 1600.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 960.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 1280.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 1280.0; + LEVEL 1 FOR 1280.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 1280.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 1280.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 1280.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 1280.0; + LEVEL 1 FOR 960.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 1280.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 1600.0; + LEVEL 1 FOR 40.0; } } @@ -1986,12 +2082,62 @@ TRANSITION_LIST("vramData[5]") { REPEAT = 1; LEVEL Z FOR 280.0; - LEVEL 1 FOR 80.0; + LEVEL 0 FOR 80.0; LEVEL Z FOR 240.0; LEVEL 0 FOR 80.0; LEVEL Z FOR 240.0; LEVEL 1 FOR 80.0; - LEVEL Z FOR 32000.0; + LEVEL Z FOR 280.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 1600.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 960.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 960.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 1280.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 960.0; + LEVEL 1 FOR 1280.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 1600.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 960.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 1600.0; + LEVEL 0 FOR 960.0; + LEVEL 1 FOR 960.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 1600.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 1280.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 1280.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 40.0; } } @@ -2006,7 +2152,54 @@ TRANSITION_LIST("vramData[4]") LEVEL 1 FOR 80.0; LEVEL Z FOR 240.0; LEVEL 1 FOR 80.0; - LEVEL Z FOR 32000.0; + LEVEL Z FOR 280.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 1600.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 1920.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 960.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 960.0; + LEVEL 0 FOR 960.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 1280.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 960.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 1600.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 2560.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 960.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 1280.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 1600.0; + LEVEL 1 FOR 40.0; } } @@ -2016,12 +2209,63 @@ TRANSITION_LIST("vramData[3]") { REPEAT = 1; LEVEL Z FOR 280.0; - LEVEL 1 FOR 80.0; + LEVEL 0 FOR 80.0; LEVEL Z FOR 240.0; LEVEL 0 FOR 80.0; LEVEL Z FOR 240.0; LEVEL 1 FOR 80.0; - LEVEL Z FOR 32000.0; + LEVEL Z FOR 280.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 960.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 960.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 960.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 1280.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 1280.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 960.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 1280.0; + LEVEL 1 FOR 2560.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 960.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 960.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 1600.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 40.0; } } @@ -2036,7 +2280,57 @@ TRANSITION_LIST("vramData[2]") LEVEL 1 FOR 80.0; LEVEL Z FOR 240.0; LEVEL 1 FOR 80.0; - LEVEL Z FOR 32000.0; + LEVEL Z FOR 280.0; + LEVEL 1 FOR 960.0; + LEVEL 0 FOR 960.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 960.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 960.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 960.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 960.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 1920.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 1600.0; + LEVEL 0 FOR 1280.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 960.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 960.0; + LEVEL 1 FOR 960.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 960.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 960.0; + LEVEL 0 FOR 1600.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 40.0; } } @@ -2051,7 +2345,59 @@ TRANSITION_LIST("vramData[1]") LEVEL 0 FOR 80.0; LEVEL Z FOR 240.0; LEVEL 0 FOR 80.0; - LEVEL Z FOR 32000.0; + LEVEL Z FOR 280.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 960.0; + LEVEL 0 FOR 960.0; + LEVEL 1 FOR 960.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 960.0; + LEVEL 0 FOR 960.0; + LEVEL 1 FOR 2240.0; + LEVEL 0 FOR 960.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 960.0; + LEVEL 1 FOR 1920.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 960.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 960.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 960.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 960.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 1280.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 40.0; } } @@ -2061,12 +2407,57 @@ TRANSITION_LIST("vramData[0]") { REPEAT = 1; LEVEL Z FOR 280.0; - LEVEL 0 FOR 80.0; + LEVEL 1 FOR 80.0; LEVEL Z FOR 240.0; LEVEL 1 FOR 80.0; LEVEL Z FOR 240.0; LEVEL 0 FOR 80.0; - LEVEL Z FOR 32000.0; + LEVEL Z FOR 280.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 960.0; + LEVEL 0 FOR 960.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 960.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 960.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 960.0; + LEVEL 0 FOR 1920.0; + LEVEL 1 FOR 2240.0; + LEVEL 0 FOR 960.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 960.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 320.0; + LEVEL 1 FOR 640.0; + LEVEL 0 FOR 1920.0; + LEVEL 1 FOR 1920.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 640.0; + LEVEL 1 FOR 1280.0; + LEVEL 0 FOR 2240.0; + LEVEL 1 FOR 320.0; + LEVEL 0 FOR 360.0; } } diff --git a/vgaout.sv b/vgaout.sv index 644fee5..d0decb8 100644 --- a/vgaout.sv +++ b/vgaout.sv @@ -7,7 +7,7 @@ * Fetches video data from VRAM and shifts out *****************************************************************************/ -`include "primitives/primitives.sv" +`include "vgashiftout.sv" module vgaout ( input wire pixClock, @@ -26,7 +26,7 @@ module vgaout ( wire vidMuxOut; wire vidActive; // combined active video signal -vidShiftOut vOut( +vgaShiftOut vOut( .nReset(nReset), .clk(pixClock), .vidActive(vidActive), @@ -35,47 +35,6 @@ vidShiftOut vOut( .out(vidMuxOut) ); -/*module vidShiftOut ( - input wire nReset, - input wire clk, - input logic [2:0] seq, - input logic [7:0] parIn, - output wire out, -);*/ - -/* -wire vidMuxClk; // latch mux output just before updating rVid - -// select bits 0..7 from the vram data in rVid, and latch if -// vidMuxClk goes high -mux8x1latch vidOutMux(rVid,hCount[2:0],vidMuxClk,nReset,vidMuxOut); - -// vidMuxClk should be low during sequence 0..6, and high for 7 -// this may lead to a race condition trying to change the mux -// before the output is latched. The alternative is to latch on -// the rising edge of pixClock during sequence 7, but then we may -// have a race condition with the data coming in from VRAM. -// What we really need is a half clock delay :-/ -always_comb begin - if(hCount[2:0] == 3'd7) begin - vidMuxClk <= 1'b1; - end else begin - vidMuxClk <= 1'b0; - end -end -*/ - -// latch incoming vram data on rising clock and sequence 7 -/*always @(posedge pixClock or negedge nReset) begin - if(nReset == 1'b0) begin - rVid <= 8'h0; - end else begin - if(hCount[2:0] == 3'h7) begin - rVid <= vramData; - end - end -end*/ - always_comb begin // combined video active signal if(hSEActive == 1'b1 && vSEActive == 1'b1) begin diff --git a/vgashiftout.sv b/vgashiftout.sv new file mode 100644 index 0000000..6aaa916 --- /dev/null +++ b/vgashiftout.sv @@ -0,0 +1,69 @@ +/****************************************************************************** + * SE-VGA + * VGA Shift Out + * techav + * 2021-04-06 + ****************************************************************************** + * 2-stage shift register for storing & shifting out pixel data + *****************************************************************************/ + +`ifndef VGASHIFTOUT + `define VGASHIFTOUT + +module vgaShiftOut ( + input wire nReset, + input wire clk, + input wire vidActive, + input logic [2:0] seq, + input logic [7:0] parIn, + output wire out +); + /* Shift register functioning similar to a 74597, with 8-bit input latch + * and 8-bit PISO shift register output stage. + * In sequence 7 new data is loaded from VRAM into the input stage, and in + * sequence 0 the input stage is copied to the output stage to be shifted. + */ + reg [7:0] inReg; + reg [7:0] outReg; + + // to meet VRAM timing requirements, data from VRAM has to be clocked into + // our input register on the rising edge of the pixel clock + always @(posedge clk or negedge nReset) begin + if(nReset == 0) begin + inReg <= 0; + end else begin + if(seq == 7) begin + inReg <= parIn; + end + end + end + + // pixels are shifted out on the falling edge of the pixel clock + always @(negedge clk or negedge nReset) begin + if(nReset == 1'b0) begin + //inReg <= 0; + outReg <= 0; + end else begin + if(vidActive == 1'b1) begin + if(seq == 0) begin + outReg <= inReg; + end else begin + outReg[7] <= outReg[6]; + outReg[6] <= outReg[5]; + outReg[5] <= outReg[4]; + outReg[4] <= outReg[3]; + outReg[3] <= outReg[2]; + outReg[2] <= outReg[1]; + outReg[1] <= outReg[0]; + outReg[0] <= 1'b0; + end + /*if(seq == 7) begin + inReg <= parIn; + end*/ + end + end + end + assign out = outReg[7]; +endmodule + +`endif \ No newline at end of file