mirror of
https://github.com/MiSTer-devel/InputTest_MiSTer.git
synced 2026-04-19 03:04:18 +00:00
Video stuffs
This commit is contained in:
@@ -3,7 +3,6 @@ set_global_assignment -name QIP_FILE rtl/T80/t80.qip
|
||||
set_global_assignment -name QIP_FILE rtl/tv80/TV80.qip
|
||||
set_global_assignment -name CDF_FILE jtag.cdf
|
||||
set_global_assignment -name QIP_FILE sys/sys.qip
|
||||
set_global_assignment -name VERILOG_FILE rtl/video.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/JTFRAME/jtframe_vtimer.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/soc.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/dpram.v
|
||||
|
||||
@@ -34,9 +34,7 @@
|
||||
module jtframe_vtimer(
|
||||
input clk,
|
||||
input pxl_cen,
|
||||
output reg [8:0] vdump,
|
||||
output reg [8:0] vrender,
|
||||
output reg [8:0] vrender1,
|
||||
output reg [8:0] V,
|
||||
output reg [8:0] H,
|
||||
output reg Hinit,
|
||||
output reg Vinit,
|
||||
@@ -46,28 +44,22 @@ module jtframe_vtimer(
|
||||
output reg VS
|
||||
);
|
||||
|
||||
reg LVBL2, LVBL1;
|
||||
|
||||
`ifdef SIMULATION
|
||||
initial begin
|
||||
Hinit = 0;
|
||||
Vinit = 0;
|
||||
LHBL = 0;
|
||||
LVBL = 1;
|
||||
LVBL1 = 1;
|
||||
LVBL2 = 1;
|
||||
HS = 0;
|
||||
VS = 0;
|
||||
H = 0;
|
||||
vrender1 = 0;
|
||||
vrender = 0;
|
||||
vdump = 0;
|
||||
V = 0;
|
||||
end
|
||||
`endif
|
||||
|
||||
// Default values suit Contra arcade
|
||||
parameter [8:0] V_START = 9'd0,
|
||||
VB_START = 9'd239,
|
||||
parameter [8:0] VCNT_START = 9'd0,
|
||||
VB_START = 9'd240,
|
||||
VB_END = 9'd255,
|
||||
VCNT_END = VB_END,
|
||||
VS_START = 9'd244,
|
||||
@@ -86,35 +78,39 @@ parameter [8:0] V_START = 9'd0,
|
||||
// H counter
|
||||
always @(posedge clk) if(pxl_cen) begin
|
||||
Hinit <= H == HINIT;
|
||||
H <= H == HCNT_END ? HCNT_START : (H+9'd1);
|
||||
H <= H == HCNT_END ? HCNT_START : (H + 9'd1);
|
||||
end
|
||||
|
||||
always @(posedge clk) if(pxl_cen) begin
|
||||
if( H == H_VNEXT ) begin
|
||||
Vinit <= vdump==VB_END;
|
||||
vrender1 <= vrender1==VCNT_END ? V_START : vrender1 + 9'd1;
|
||||
vrender <= vrender1;
|
||||
vdump <= vrender;
|
||||
if(H==H_VNEXT) begin
|
||||
Vinit <= V == VB_END;
|
||||
V <= V == VCNT_END ? VCNT_START : (V + 9'd1);
|
||||
end
|
||||
|
||||
if( H == HB_START ) begin
|
||||
if(H==HB_START)
|
||||
begin
|
||||
LHBL <= 0;
|
||||
end else if( H == HB_END ) LHBL <= 1;
|
||||
if( H == H_VB ) begin
|
||||
{ LVBL, LVBL1 } <= { LVBL1, LVBL2 };
|
||||
case( vrender1 )
|
||||
VB_START: LVBL2 <= 0;
|
||||
VB_END: LVBL2 <= 1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if( H == HB_END ) LHBL <= 1;
|
||||
end
|
||||
|
||||
if(H==H_VB) begin
|
||||
case(V)
|
||||
VB_START: LVBL <= 0;
|
||||
VB_END: LVBL <= 1;
|
||||
default:;
|
||||
endcase // vdump
|
||||
endcase
|
||||
end
|
||||
|
||||
if (H==HS_START) begin
|
||||
HS <= 1;
|
||||
end
|
||||
|
||||
if( H==H_VS ) begin
|
||||
if (vdump==VS_START) VS <= 1;
|
||||
if (vdump==VS_END ) VS <= 0;
|
||||
if (V==VS_START) VS <= 1;
|
||||
if (V==VS_END ) VS <= 0;
|
||||
end
|
||||
|
||||
if (H==HS_END) HS <= 0;
|
||||
|
||||
40
rtl/soc.v
40
rtl/soc.v
@@ -17,36 +17,50 @@ module soc (
|
||||
output VGA_VB
|
||||
);
|
||||
|
||||
wire _hblank;
|
||||
wire _vblank;
|
||||
assign VGA_HB = ~_hblank;
|
||||
assign VGA_VB = ~_vblank;
|
||||
wire _hb;
|
||||
wire _vb;
|
||||
assign VGA_HB = ~_hb;
|
||||
assign VGA_VB = ~_vb;
|
||||
|
||||
wire [8:0] hcnt;
|
||||
wire [8:0] vcnt;
|
||||
wire hinit;
|
||||
wire vinit;
|
||||
|
||||
// Display timing module from JTFRAME
|
||||
jtframe_vtimer #(
|
||||
.HB_START(9'd320)
|
||||
.HB_START(9'd320),
|
||||
.VB_START(9'd240)
|
||||
) vtimer
|
||||
(
|
||||
.clk(clk_sys),
|
||||
.pxl_cen(clk_pix),
|
||||
.vdump(vcnt),
|
||||
.vrender(),
|
||||
.vrender1(),
|
||||
.V(vcnt),
|
||||
.H(hcnt),
|
||||
.Hinit(),
|
||||
.Vinit(),
|
||||
.LHBL(_hblank),
|
||||
.LVBL(_vblank),
|
||||
.Hinit(hinit),
|
||||
.Vinit(vinit),
|
||||
.LHBL(_hb),
|
||||
.LVBL(_vb),
|
||||
.HS(VGA_HS),
|
||||
.VS(VGA_VS)
|
||||
);
|
||||
|
||||
// DEBUG OUTPUT
|
||||
assign VGA_R = hcnt[7:0];
|
||||
assign VGA_B = vcnt[7:0];
|
||||
assign VGA_G = vcnt[7:0];
|
||||
assign VGA_B = voff;
|
||||
|
||||
// reg [7:0] hoff;
|
||||
reg [7:0] voff;
|
||||
|
||||
always @(posedge clk_sys)
|
||||
begin
|
||||
if(vinit == 1'b1) voff <= voff + 8'b1;
|
||||
// //if(hinit == 1'b1) hoff <= hoff + 8'b1;
|
||||
// $display("%d %d", vrender, vrender1);
|
||||
end
|
||||
|
||||
|
||||
|
||||
// CPU control signals
|
||||
wire [15:0] cpu_addr;
|
||||
|
||||
@@ -192,8 +192,8 @@ SimVideo::SimVideo(int width, int height, int rotate)
|
||||
old_time = 0;
|
||||
stats_frameTime = 0;
|
||||
stats_fps = 0.0;
|
||||
stats_xMax = -100;
|
||||
stats_yMax = -100;
|
||||
stats_xMax = -1000;
|
||||
stats_yMax = -1000;
|
||||
stats_xMin = 1000;
|
||||
stats_yMin = 1000;
|
||||
}
|
||||
@@ -345,7 +345,7 @@ void SimVideo::UpdateTexture() {
|
||||
g_pd3dDeviceContext->OMSetRenderTargets(1, &g_mainRenderTargetView, NULL);
|
||||
g_pd3dDeviceContext->ClearRenderTargetView(g_mainRenderTargetView, (float*)&clear_color);
|
||||
ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
|
||||
g_pSwapChain->Present(0, 0); // Present without vsync
|
||||
g_pSwapChain->Present(1, 0); // Present without vsync
|
||||
#else
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, output_width, output_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, output_ptr);
|
||||
@@ -399,13 +399,46 @@ void SimVideo::StartFrame() {
|
||||
|
||||
void SimVideo::Clock(bool hblank, bool vblank, bool hsync, bool vsync, uint32_t colour) {
|
||||
|
||||
bool de = !(hblank || vblank);
|
||||
|
||||
// Next line on rising hsync
|
||||
if (!vblank) {
|
||||
if (last_hsync && !hsync) {
|
||||
// Increment line and reset pixel count
|
||||
count_line++;
|
||||
count_pixel = 0;
|
||||
}
|
||||
else {
|
||||
// Increment pixel counter when not blanked
|
||||
if (de) {
|
||||
count_pixel++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Reset on rising vsync
|
||||
if (last_vsync && !vsync) {
|
||||
count_frame++;
|
||||
count_line = 0;
|
||||
|
||||
#ifdef WIN32
|
||||
GetSystemTime(&actualtime);
|
||||
time_ms = (actualtime.wSecond * 1000) + actualtime.wMilliseconds;
|
||||
#else
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
time_ms = (tv.tv_sec) * 1000 + (tv.tv_usec) / 1000; // convert tv_sec & tv_usec to millisecond
|
||||
#endif
|
||||
stats_frameTime = time_ms - old_time;
|
||||
old_time = time_ms;
|
||||
stats_fps = (float)(1000.0 / stats_frameTime);
|
||||
}
|
||||
|
||||
// Only draw outside of blanks
|
||||
if (!(hblank || vblank)) {
|
||||
|
||||
//int ox = count_pixel + 1;
|
||||
int ox = count_pixel;
|
||||
int oy = count_line;
|
||||
if (de) {
|
||||
|
||||
int ox = count_pixel - 1;
|
||||
int oy = count_line - 1;
|
||||
int x = ox, xs = output_width, y = oy;
|
||||
|
||||
if (output_rotate == -1) {
|
||||
@@ -437,45 +470,13 @@ void SimVideo::Clock(bool hblank, bool vblank, bool hsync, bool vsync, uint32_t
|
||||
// Write pixel to texture
|
||||
output_ptr[vga_addr] = colour;
|
||||
|
||||
// Track bounds (debug)
|
||||
if (x > stats_xMax) { stats_xMax = x; }
|
||||
if (y > stats_yMax) { stats_yMax = y; }
|
||||
if (x < stats_xMin) { stats_xMin = x; }
|
||||
if (y < stats_yMin) { stats_yMin = y; }
|
||||
|
||||
}
|
||||
|
||||
// Increment pixel counter when not blanked
|
||||
if (!(hblank || vblank)) {
|
||||
count_pixel++;
|
||||
}
|
||||
|
||||
// Next line on rising hsync
|
||||
if (last_hsync && !hsync) {
|
||||
// Increment line and reset pixel count
|
||||
count_line++;
|
||||
count_pixel = 0;
|
||||
}
|
||||
|
||||
// Reset on rising vsync
|
||||
if (last_vsync && !vsync) {
|
||||
count_frame++;
|
||||
count_line = 0;
|
||||
|
||||
#ifdef WIN32
|
||||
GetSystemTime(&actualtime);
|
||||
time_ms = (actualtime.wSecond * 1000) + actualtime.wMilliseconds;
|
||||
#else
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
time_ms = (tv.tv_sec) * 1000 + (tv.tv_usec) / 1000; // convert tv_sec & tv_usec to millisecond
|
||||
#endif
|
||||
stats_frameTime = time_ms - old_time;
|
||||
old_time = time_ms;
|
||||
stats_fps = (float)(1000.0 / stats_frameTime);
|
||||
|
||||
}
|
||||
|
||||
// Track bounds (debug)
|
||||
if (count_pixel > stats_xMax) { stats_xMax = count_pixel; }
|
||||
if (count_line > stats_yMax) { stats_yMax = count_line; }
|
||||
if (count_pixel < stats_xMin) { stats_xMin = count_pixel; }
|
||||
if (count_line < stats_yMin) { stats_yMin = count_line; }
|
||||
|
||||
last_hblank = hblank;
|
||||
last_vblank = vblank;
|
||||
|
||||
@@ -50,8 +50,8 @@ const int input_pause = 11;
|
||||
|
||||
// Video
|
||||
// -----
|
||||
#define VGA_WIDTH 640
|
||||
#define VGA_HEIGHT 400
|
||||
#define VGA_WIDTH 400
|
||||
#define VGA_HEIGHT 300
|
||||
#define VGA_ROTATE 0 // 90 degrees anti-clockwise
|
||||
SimVideo video(VGA_WIDTH, VGA_HEIGHT, VGA_ROTATE);
|
||||
|
||||
@@ -59,7 +59,7 @@ SimVideo video(VGA_WIDTH, VGA_HEIGHT, VGA_ROTATE);
|
||||
// ------------------
|
||||
int initialReset = 48;
|
||||
bool run_enable = 1;
|
||||
int batchSize = 250000 / 100;
|
||||
int batchSize = 2500000 / 1000;
|
||||
bool single_step = 0;
|
||||
bool multi_step = 0;
|
||||
int multi_step_amount = 1024;
|
||||
@@ -221,7 +221,7 @@ int main(int argc, char** argv, char** env) {
|
||||
if (ImGui::Button("START")) { run_enable = 1; } ImGui::SameLine();
|
||||
if (ImGui::Button("STOP")) { run_enable = 0; } ImGui::SameLine();
|
||||
ImGui::Checkbox("RUN", &run_enable);
|
||||
ImGui::SliderInt("Batch size", &batchSize, 1, 100000);
|
||||
ImGui::SliderInt("Batch size", &batchSize, 1, 250000);
|
||||
|
||||
if (single_step == 1) { single_step = 0; }
|
||||
if (ImGui::Button("Single Step")) { run_enable = 0; single_step = 1; }
|
||||
@@ -239,7 +239,7 @@ int main(int argc, char** argv, char** env) {
|
||||
ImGui::Text("minx: %d maxx: %d miny: %d maxy: %d", video.stats_xMin, video.stats_xMax, video.stats_yMin, video.stats_yMax);
|
||||
|
||||
// Draw VGA output
|
||||
float m = 1.0;
|
||||
float m = 2.0;
|
||||
ImGui::Image(video.texture_id, ImVec2(video.output_width * m, video.output_height * m));
|
||||
ImGui::End();
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#verilator -cc -exe --public --compiler msvc --converge-limit 2000 -Wno-WIDTH -Wno-IMPLICIT -Wno-MODDUP -Wno-UNSIGNED -Wno-CASEINCOMPLETE -Wno-CASEX -Wno-SYMRSVDWORD -Wno-COMBDLY -Wno-INITIALDLY -Wno-BLKANDNBLK -Wno-UNOPTFLAT -Wno-SELRANGE -Wno-CMPCONST -Wno-CASEOVERLAP -Wno-PINMISSING --top-module top sim.v \
|
||||
verilator -cc -exe --public --compiler msvc +define+SIMULATION=1 --converge-limit 2000 --top-module top sim.v \
|
||||
verilator -cc -exe --public --compiler msvc +define+SIMULATION=1 +define+SIMULATION_VTIMER=1 --converge-limit 2000 --top-module top sim.v \
|
||||
../rtl/dpram.v \
|
||||
../rtl/spram.v \
|
||||
../rtl/JTFRAME/jtframe_vtimer.v \
|
||||
|
||||
Reference in New Issue
Block a user