diff --git a/README.md b/README.md index 7233707..c358436 100644 --- a/README.md +++ b/README.md @@ -15,3 +15,5 @@ Jumpers: * VGA_SCART - no effect * SET_FK_IN - no effect * SET_FK_OUT - no effect + +**PCB modification:** to get this firmware working you need to bridge CPLD pin 90 and pin 83. diff --git a/clocks.sdc b/clocks.sdc index 3a89bc1..9766edc 100644 --- a/clocks.sdc +++ b/clocks.sdc @@ -1,2 +1,3 @@ create_clock -name F14 -period 14.1MHz [get_ports {F14}] create_generated_clock -name F14_2 -source [get_ports {F14}] -phase 45 [get_ports {F14_2}] +create_clock -name F28 -period 28.1MHz [get_ports {F28}] diff --git a/scandoubler.qsf b/scandoubler.qsf index 2c2c6e5..6f22e81 100644 --- a/scandoubler.qsf +++ b/scandoubler.qsf @@ -95,7 +95,8 @@ set_location_assignment PIN_68 -to G_VGA set_location_assignment PIN_70 -to B_VGA set_location_assignment PIN_71 -to VSYNC_VGA set_location_assignment PIN_72 -to HSYNC_VGA -set_location_assignment PIN_83 -to SYNC_VIDEO +set_location_assignment PIN_83 -to F28o +set_location_assignment PIN_90 -to F28 set_location_assignment PIN_84 -to SET_FK_OUT set_location_assignment PIN_85 -to SET_FK_IN set_location_assignment PIN_92 -to VGA_SCART diff --git a/scandoubler.v b/scandoubler.v index db0aff0..dba8a11 100644 --- a/scandoubler.v +++ b/scandoubler.v @@ -8,6 +8,8 @@ module scandoubler( input SSI_IN, input F14, input F14_2, + output F28o, + input F28, input INVERSE_RGBI, input INVERSE_KSI, @@ -17,33 +19,35 @@ module scandoubler( input SET_FK_IN, input SET_FK_OUT, - output R_VGA, - output G_VGA, - output B_VGA, - output [2:0] I_VGA, - output VSYNC_VGA, - output HSYNC_VGA, + output reg R_VGA, + output reg G_VGA, + output reg B_VGA, + output reg [2:0] I_VGA, + output reg VSYNC_VGA, + output reg HSYNC_VGA, output R_VIDEO, output G_VIDEO, output B_VIDEO, output [2:0] I_VIDEO, - output SYNC_VIDEO, + // output SYNC_VIDEO, output A17, - output [16:0] A, - output WE, + output reg [16:0] A, + output reg WE, + output reg UB, + output reg LB, output OE, - output UB, - output LB, inout [15:0] D ); +assign F28o = F14 ^ F14_2 ^ INVERSE_F14MHZ; reg ssi = 0, ksi0 = 0; wire ksi = ksi0 ^ ~KSI_IN; -reg [6:0] ssi_cnt = 0; -always @(posedge F14) begin +reg [7:0] ssi_cnt = 0; +reg [7:0] ssi_len = 0; +always @(posedge F28) begin if (SSI_IN == ksi0) begin ssi_cnt <= ssi_cnt + 1'b1; if (&ssi_cnt) @@ -51,6 +55,7 @@ always @(posedge F14) begin ssi <= 1'b0; end else if (|ssi_cnt) begin + ssi_len <= ssi_cnt; ssi_cnt <= 0; ssi <= 1'b1; end @@ -59,57 +64,66 @@ always @(posedge F14) begin end end -reg [10:0] hcnt = 0; -reg [10:0] hlen = 0; +reg [11:0] hcnt_in = 0; +reg [11:0] hlen = 0; reg even_line = 0; -always @(posedge F14) begin +always @(posedge F28) begin if (ssi) begin - even_line = !even_line; - hlen <= hcnt; - hcnt <= 0; + even_line <= !even_line; + hlen <= hcnt_in; + hcnt_in <= 0; end else begin - hcnt <= hcnt + 1'b1; + hcnt_in <= hcnt_in + 1'b1; end end -reg [9:0] hcnt_vga = 0; -always @(posedge F14) begin - if (hcnt_vga == hlen[10:1] || ssi) +reg [10:0] hcnt_vga = 0; +always @(posedge F28) begin + if (hcnt_vga == hlen[11:1] || ssi) hcnt_vga <= 0; else hcnt_vga <= hcnt_vga + 1'b1; end -assign VSYNC_VGA = ~INVERSE_KSI ^ ksi; -assign HSYNC_VGA = ~INVERSE_SSI ^ (hcnt_vga < 54); // ~3.85us - -assign OE = 1'b0; assign A17 = 1'b0; -wire write_screen = F14 ^ INVERSE_F14MHZ & !ssi; -assign WE = ~write_screen; -assign UB = write_screen? ~hcnt[0] : 1'b0; -assign LB = write_screen? hcnt[0] : 1'b0; -assign A[16:0] = write_screen? - {{6{1'b0}}, ~even_line, hcnt[10:1]} : - {{6{1'b0}}, even_line, hcnt_vga} ; +assign OE = 1'b0; +wire write_pixel = ~hcnt_in[0]; +reg [3:0] ibgr_reg1, ibgr_reg2, ibgr_in; +always @(posedge F28) begin + WE <= ~write_pixel; + LB <= write_pixel? hcnt_in[1] : 1'b0; + UB <= write_pixel? ~hcnt_in[1] : 1'b0; + A[16:0] <= write_pixel? + {{6{1'b0}}, ~even_line, hcnt_in[11:2]} : + {{6{1'b0}}, even_line, hcnt_vga[10:1]} ; -assign D[15:0] = write_screen? {{4{1'b0}}, I_IN, B_IN, G_IN, R_IN, {4{1'b0}}, I_IN, B_IN, G_IN, R_IN} : {16{1'bz}}; - -reg [3:0] ibgr_reg1, ibgr_reg2; -always @(posedge F14) begin - if (write_screen) begin + ibgr_in = {4{~INVERSE_RGBI}} ^ {I_IN, B_IN, G_IN, R_IN}; + if (write_pixel) begin ibgr_reg1 <= D[3:0]; ibgr_reg2 <= D[11:8]; end + else begin + ibgr_reg1 <= ibgr_reg2; + end end -assign R_VGA = (~INVERSE_RGBI) ^ (F14? ibgr_reg2[0] : ibgr_reg1[0]); -assign G_VGA = (~INVERSE_RGBI) ^ (F14? ibgr_reg2[1] : ibgr_reg1[1]); -assign B_VGA = (~INVERSE_RGBI) ^ (F14? ibgr_reg2[2] : ibgr_reg1[2]); -assign I_VGA[0] = (~INVERSE_RGBI) ^ (F14? ibgr_reg2[3] : ibgr_reg1[3]); -assign I_VGA[1] = (~INVERSE_RGBI) ^ (F14? ibgr_reg2[3] : ibgr_reg1[3]); -assign I_VGA[2] = (~INVERSE_RGBI) ^ (F14? ibgr_reg2[3] : ibgr_reg1[3]); +assign D[15:0] = !write_pixel? + {{4{1'b0}}, ibgr_in, {4{1'b0}}, ibgr_in} : + {16{1'bz}} ; + +wire HBLANK_VGA = (hcnt_vga < (ssi_len[7:1]+ssi_len[7:2])); +always @(posedge F28) begin + VSYNC_VGA <= ~INVERSE_KSI ^ ksi; + HSYNC_VGA <= ~INVERSE_SSI ^ (hcnt_vga < ssi_len[7:1]); + R_VGA <= !HBLANK_VGA && (ibgr_reg1[0] ); + G_VGA <= !HBLANK_VGA && (ibgr_reg1[1] ); + // G_VGA <= !HBLANK_VGA && hcnt_vga[1]; + B_VGA <= !HBLANK_VGA && (ibgr_reg1[2] ); + I_VGA[0] <= !HBLANK_VGA && (ibgr_reg1[0] & ibgr_reg1[3]); + I_VGA[1] <= !HBLANK_VGA && (ibgr_reg1[1] & ibgr_reg1[3]); + I_VGA[2] <= !HBLANK_VGA && (ibgr_reg1[2] & ibgr_reg1[3]); +end assign R_VIDEO = R_IN ^ ~INVERSE_RGBI; assign G_VIDEO = G_IN ^ ~INVERSE_RGBI; @@ -117,7 +131,7 @@ assign B_VIDEO = B_IN ^ ~INVERSE_RGBI; assign I_VIDEO[0] = I_IN ^ ~INVERSE_RGBI; assign I_VIDEO[1] = I_IN ^ ~INVERSE_RGBI; assign I_VIDEO[2] = I_IN ^ ~INVERSE_RGBI; -assign SYNC_VIDEO = ~((SSI_IN ^ ~INVERSE_SSI) ^ (KSI_IN ^ ~INVERSE_KSI)); +// assign SYNC_VIDEO = ~((SSI_IN ^ ~INVERSE_SSI) ^ (KSI_IN ^ ~INVERSE_KSI)); endmodule diff --git a/testbench_scandoubler.v b/testbench_scandoubler.v index d43662e..dba3b6e 100644 --- a/testbench_scandoubler.v +++ b/testbench_scandoubler.v @@ -53,6 +53,8 @@ initial begin end assign d = n_ramwr? ram_q0 : {16{1'bz}}; + +wire clk28; scandoubler scandoubler1( .R_IN(1'b1), .G_IN(1'b1), @@ -62,6 +64,8 @@ scandoubler scandoubler1( .SSI_IN(csync), .F14(clk14), .F14_2(clk14_2), + .F28o(clk28), + .F28(clk28), .INVERSE_RGBI(1'b1), .INVERSE_KSI(1'b1), .INVERSE_SSI(1'b1), @@ -79,7 +83,7 @@ scandoubler scandoubler1( .G_VIDEO(), .B_VIDEO(), .I_VIDEO(), - .SYNC_VIDEO(), + // .SYNC_VIDEO(), .A17(ram_addr_a[17]), .A(ram_addr_a[16:0]), .WE(n_ramwr), @@ -94,7 +98,7 @@ initial begin $dumpvars(); rst_n = 0; #5 rst_n = 1; - #2100000 $finish; + // #2100000 $finish; #21000000 $finish; end