CPU Cycle Improvements 2

This commit is contained in:
techav 2021-04-18 12:07:42 -05:00
parent 3b00823d6c
commit c4bc1c4be5
6 changed files with 514 additions and 351 deletions

View File

@ -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

View File

@ -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

View File

@ -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

413
sevga.vwf
View File

@ -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;
}
}

View File

@ -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

69
vgashiftout.sv Normal file
View File

@ -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