diff --git a/cores/archie/fpga/mist/archimedes_mist_top.qsf b/cores/archie/fpga/mist/archimedes_mist_top.qsf index 72e217f..8ae1996 100644 --- a/cores/archie/fpga/mist/archimedes_mist_top.qsf +++ b/cores/archie/fpga/mist/archimedes_mist_top.qsf @@ -136,7 +136,7 @@ set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_* set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to DRAM_* set_global_assignment -name ENABLE_SIGNALTAP OFF -set_global_assignment -name USE_SIGNALTAP_FILE output_files/ide.stp +set_global_assignment -name USE_SIGNALTAP_FILE output_files/dio.stp set_global_assignment -name STRATIX_DEVICE_IO_STANDARD "3.3-V LVTTL" set_global_assignment -name ENABLE_CONFIGURATION_PINS OFF set_global_assignment -name ENABLE_NCE_PIN OFF @@ -181,13 +181,15 @@ set_global_assignment -name PHYSICAL_SYNTHESIS_EFFORT EXTRA set_global_assignment -name PRE_MAPPING_RESYNTHESIS ON set_global_assignment -name REMOVE_REDUNDANT_LOGIC_CELLS ON set_global_assignment -name VERILOG_FILE archimedes_mist_top.v -set_global_assignment -name SYSTEMVERILOG_FILE rgb2ypbpr.sv -set_global_assignment -name VERILOG_FILE scandoubler.v +set_global_assignment -name VERILOG_FILE "../../../../mist-modules/mist_video.v" +set_global_assignment -name SYSTEMVERILOG_FILE "../../../../mist-modules/cofi.sv" +set_global_assignment -name VERILOG_FILE "../../../../mist-modules/scandoubler.v" +set_global_assignment -name SYSTEMVERILOG_FILE "../../../../mist-modules/rgb2ypbpr.sv" +set_global_assignment -name VERILOG_FILE "../../../../mist-modules/osd.v" set_global_assignment -name VERILOG_FILE sigma_delta_dac.v set_global_assignment -name VERILOG_FILE audio.v set_global_assignment -name VERILOG_FILE data_io.v set_global_assignment -name VERILOG_FILE user_io.v -set_global_assignment -name VERILOG_FILE osd.v set_global_assignment -name VERILOG_FILE sram_line_en.v set_global_assignment -name VERILOG_FILE sram_byte_en.v set_global_assignment -name QIP_FILE clockgen.qip @@ -229,6 +231,4 @@ set_global_assignment -name QIP_FILE rom_reconfig_25.qip set_global_assignment -name QIP_FILE pll_reconfig.qip set_global_assignment -name QIP_FILE rom_reconfig_36.qip set_global_assignment -name QIP_FILE pll_vidc.qip -set_global_assignment -name SIGNALTAP_FILE output_files/vidc.stp -set_global_assignment -name SIGNALTAP_FILE output_files/sd.stp set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/cores/archie/fpga/mist/archimedes_mist_top.v b/cores/archie/fpga/mist/archimedes_mist_top.v index 56abe6a..208e153 100644 --- a/cores/archie/fpga/mist/archimedes_mist_top.v +++ b/cores/archie/fpga/mist/archimedes_mist_top.v @@ -103,6 +103,7 @@ wire [1:0] buttons; wire [1:0] switches; wire scandoubler_disable; wire ypbpr; +wire no_csync; // the top file should generate the correct clocks for the machine @@ -258,74 +259,48 @@ always @(posedge clk_pix) begin { r_adj, g_adj, b_adj } <= 12'h0; end -wire [5:0] sd_r, sd_g, sd_b; -wire sd_hs; -wire sd_vs; - -scandoubler #(11, 4) scandoubler -( - .clk_sys ( clk_pix ), - .scanlines ( 2'b00 ), - .ce_divider ( 1'b1 ), - .hs_in ( hs_adj ), - .vs_in ( vs_adj ), - .r_in ( r_adj ), - .g_in ( g_adj ), - .b_in ( b_adj ), - .hs_out ( sd_hs ), - .vs_out ( sd_vs ), - .r_out ( sd_r ), - .g_out ( sd_g ), - .b_out ( sd_b ) -); - -wire vs = scandoubler_en ? sd_vs : core_vs; -wire hs = scandoubler_en ? sd_hs : core_hs; -wire [5:0] r = scandoubler_en ? sd_r : { r_adj, r_adj[3:2] }; -wire [5:0] g = scandoubler_en ? sd_g : { g_adj, g_adj[3:2] }; -wire [5:0] b = scandoubler_en ? sd_b : { b_adj, b_adj[3:2] }; - -wire [5:0] osd_r_o, osd_g_o, osd_b_o; - -osd #(10'd0,10'd0,4) OSD ( - .clk_sys ( clk_pix ), - - // spi for OSD - .SPI_DI ( SPI_DI ), - .SPI_SCK ( SPI_SCK ), - .SPI_SS3 ( SPI_SS3 ), - - .R_in ( r ), - .G_in ( g ), - .B_in ( b ), - .HSync ( hs ), - .VSync ( vs ), - - .R_out ( osd_r_o ), - .G_out ( osd_g_o ), - .B_out ( osd_b_o ) -); - -wire [5:0] Y, Pb, Pr; - -rgb2ypbpr rgb2ypbpr -( - .red ( osd_r_o ), - .green ( osd_g_o ), - .blue ( osd_b_o ), - .y ( Y ), - .pb ( Pb ), - .pr ( Pr ) -); - wire scandoubler_en = ~scandoubler_disable && pixbaseclk_select[0] == pixbaseclk_select[1]; -assign VGA_R = ypbpr?Pr:osd_r_o; -assign VGA_G = ypbpr? Y:osd_g_o; -assign VGA_B = ypbpr?Pb:osd_b_o; -wire CSync = ~(hs ^ vs); -//24 MHz modes get composite sync automatically -assign VGA_HS = ((pixbaseclk_select[0] == pixbaseclk_select[1] && scandoubler_disable) | ypbpr) ? CSync : hs; -assign VGA_VS = ((pixbaseclk_select[0] == pixbaseclk_select[1] && scandoubler_disable) | ypbpr) ? 1'b1 : vs; + +mist_video #(.COLOR_DEPTH(4), .SD_HCNT_WIDTH(10)) mist_video ( + .clk_sys ( clk_pix ), + + // OSD SPI interface + .SPI_SCK ( SPI_SCK ), + .SPI_SS3 ( SPI_SS3 ), + .SPI_DI ( SPI_DI ), + + // scanlines (00-none 01-25% 10-50% 11-75%) + .scanlines ( 2'b00 ), + + // non-scandoubled pixel clock divider 0 - clk_sys/4, 1 - clk_sys/2 + .ce_divider ( 1'b0 ), + + // 0 = HVSync 31KHz, 1 = CSync 15KHz + .scandoubler_disable ( ~scandoubler_en ), + // disable csync without scandoubler + .no_csync ( no_csync ), + // YPbPr always uses composite sync + .ypbpr ( ypbpr ), + // Rotate OSD [0] - rotate [1] - left or right + .rotate ( 2'b00 ), + // composite-like blending + .blend ( 1'b0 ), + + // video in + .R ( r_adj ), + .G ( g_adj ), + .B ( b_adj ), + + .HSync ( hs_adj ), + .VSync ( vs_adj ), + + // MiST video output signals + .VGA_R ( VGA_R ), + .VGA_G ( VGA_G ), + .VGA_B ( VGA_B ), + .VGA_VS ( VGA_VS ), + .VGA_HS ( VGA_HS ) +); wire [31:0] sd_lba; wire [1:0] sd_rd; @@ -358,6 +333,7 @@ user_io user_io( .BUTTONS ( buttons ), .scandoubler_disable(scandoubler_disable), .ypbpr ( ypbpr ), + .no_csync ( no_csync ), .JOY0 ( joyA ), .JOY1 ( joyB ), diff --git a/cores/archie/fpga/mist/osd.v b/cores/archie/fpga/mist/osd.v deleted file mode 100644 index bc3ade8..0000000 --- a/cores/archie/fpga/mist/osd.v +++ /dev/null @@ -1,179 +0,0 @@ -// A simple OSD implementation. Can be hooked up between a cores -// VGA output and the physical VGA pins - -module osd ( - // OSDs pixel clock, should be synchronous to cores pixel clock to - // avoid jitter. - input clk_sys, - - // SPI interface - input SPI_SCK, - input SPI_SS3, - input SPI_DI, - - // VGA signals coming from core - input [5:0] R_in, - input [5:0] G_in, - input [5:0] B_in, - input HSync, - input VSync, - - // VGA signals going to video connector - output [5:0] R_out, - output [5:0] G_out, - output [5:0] B_out -); - -parameter OSD_X_OFFSET = 10'd0; -parameter OSD_Y_OFFSET = 10'd0; -parameter OSD_COLOR = 3'd0; - -localparam OSD_WIDTH = 10'd256; -localparam OSD_HEIGHT = 10'd128; - -// ********************************************************************************* -// spi client -// ********************************************************************************* - -// this core supports only the display related OSD commands -// of the minimig -reg osd_enable; -(* ramstyle = "no_rw_check" *) reg [7:0] osd_buffer[2047:0]; // the OSD buffer itself - -// the OSD has its own SPI interface to the io controller -always@(posedge SPI_SCK, posedge SPI_SS3) begin - reg [4:0] cnt; - reg [10:0] bcnt; - reg [7:0] sbuf; - reg [7:0] cmd; - - if(SPI_SS3) begin - cnt <= 0; - bcnt <= 0; - end else begin - sbuf <= {sbuf[6:0], SPI_DI}; - - // 0:7 is command, rest payload - if(cnt < 15) cnt <= cnt + 1'd1; - else cnt <= 8; - - if(cnt == 7) begin - cmd <= {sbuf[6:0], SPI_DI}; - - // lower three command bits are line address - bcnt <= {sbuf[1:0], SPI_DI, 8'h00}; - - // command 0x40: OSDCMDENABLE, OSDCMDDISABLE - if(sbuf[6:3] == 4'b0100) osd_enable <= SPI_DI; - end - - // command 0x20: OSDCMDWRITE - if((cmd[7:3] == 5'b00100) && (cnt == 15)) begin - osd_buffer[bcnt] <= {sbuf[6:0], SPI_DI}; - bcnt <= bcnt + 1'd1; - end - end -end - -// ********************************************************************************* -// video timing and sync polarity anaylsis -// ********************************************************************************* - -// horizontal counter -reg [9:0] h_cnt; -reg [9:0] hs_low, hs_high; -wire hs_pol = hs_high < hs_low; -wire [9:0] dsp_width = hs_pol ? hs_low : hs_high; - -// vertical counter -reg [9:0] v_cnt; -reg [9:0] vs_low, vs_high; -wire vs_pol = vs_high < vs_low; -wire [9:0] dsp_height = vs_pol ? vs_low : vs_high; - -wire doublescan = (dsp_height>350); - -reg ce_pix; -always @(negedge clk_sys) begin - integer cnt = 0; - integer pixsz, pixcnt; - reg hs; - - cnt <= cnt + 1; - hs <= HSync; - - pixcnt <= pixcnt + 1; - if(pixcnt == pixsz) pixcnt <= 0; - ce_pix <= !pixcnt; - - if(hs && ~HSync) begin - cnt <= 0; - pixsz <= (cnt >> 9) - 1; - pixcnt <= 0; - ce_pix <= 1; - end -end - -always @(posedge clk_sys) begin - reg hsD, hsD2; - reg vsD, vsD2; - - if(ce_pix) begin - // bring hsync into local clock domain - hsD <= HSync; - hsD2 <= hsD; - - // falling edge of HSync - if(!hsD && hsD2) begin - h_cnt <= 0; - hs_high <= h_cnt; - end - - // rising edge of HSync - else if(hsD && !hsD2) begin - h_cnt <= 0; - hs_low <= h_cnt; - v_cnt <= v_cnt + 1'd1; - end else begin - h_cnt <= h_cnt + 1'd1; - end - - vsD <= VSync; - vsD2 <= vsD; - - // falling edge of VSync - if(!vsD && vsD2) begin - v_cnt <= 0; - vs_high <= v_cnt; - end - - // rising edge of VSync - else if(vsD && !vsD2) begin - v_cnt <= 0; - vs_low <= v_cnt; - end - end -end - -// area in which OSD is being displayed -wire [9:0] h_osd_start = ((dsp_width - OSD_WIDTH)>> 1) + OSD_X_OFFSET; -wire [9:0] h_osd_end = h_osd_start + OSD_WIDTH; -wire [9:0] v_osd_start = ((dsp_height- (OSD_HEIGHT<> 1) + OSD_Y_OFFSET; -wire [9:0] v_osd_end = v_osd_start + (OSD_HEIGHT<= h_osd_start) && (h_cnt < h_osd_end) && - (VSync != vs_pol) && (v_cnt >= v_osd_start) && (v_cnt < v_osd_end); - -reg [7:0] osd_byte; -always @(posedge clk_sys) if(ce_pix) osd_byte <= osd_buffer[{doublescan ? osd_vcnt[7:5] : osd_vcnt[6:4], osd_hcnt[7:0]}]; - -wire osd_pixel = osd_byte[doublescan ? osd_vcnt[4:2] : osd_vcnt[3:1]]; - -assign R_out = !osd_de ? R_in : {osd_pixel, osd_pixel, OSD_COLOR[2], R_in[5:3]}; -assign G_out = !osd_de ? G_in : {osd_pixel, osd_pixel, OSD_COLOR[1], G_in[5:3]}; -assign B_out = !osd_de ? B_in : {osd_pixel, osd_pixel, OSD_COLOR[0], B_in[5:3]}; - -endmodule diff --git a/cores/archie/fpga/mist/rgb2ypbpr.sv b/cores/archie/fpga/mist/rgb2ypbpr.sv deleted file mode 100644 index 1e1662e..0000000 --- a/cores/archie/fpga/mist/rgb2ypbpr.sv +++ /dev/null @@ -1,55 +0,0 @@ -module rgb2ypbpr ( - input [5:0] red, - input [5:0] green, - input [5:0] blue, - - output [5:0] y, - output [5:0] pb, - output [5:0] pr -); - -wire [5:0] yuv_full[225] = '{ - 6'd0, 6'd0, 6'd0, 6'd0, 6'd1, 6'd1, 6'd1, 6'd1, - 6'd2, 6'd2, 6'd2, 6'd3, 6'd3, 6'd3, 6'd3, 6'd4, - 6'd4, 6'd4, 6'd5, 6'd5, 6'd5, 6'd5, 6'd6, 6'd6, - 6'd6, 6'd7, 6'd7, 6'd7, 6'd7, 6'd8, 6'd8, 6'd8, - 6'd9, 6'd9, 6'd9, 6'd9, 6'd10, 6'd10, 6'd10, 6'd11, - 6'd11, 6'd11, 6'd11, 6'd12, 6'd12, 6'd12, 6'd13, 6'd13, - 6'd13, 6'd13, 6'd14, 6'd14, 6'd14, 6'd15, 6'd15, 6'd15, - 6'd15, 6'd16, 6'd16, 6'd16, 6'd17, 6'd17, 6'd17, 6'd17, - 6'd18, 6'd18, 6'd18, 6'd19, 6'd19, 6'd19, 6'd19, 6'd20, - 6'd20, 6'd20, 6'd21, 6'd21, 6'd21, 6'd21, 6'd22, 6'd22, - 6'd22, 6'd23, 6'd23, 6'd23, 6'd23, 6'd24, 6'd24, 6'd24, - 6'd25, 6'd25, 6'd25, 6'd25, 6'd26, 6'd26, 6'd26, 6'd27, - 6'd27, 6'd27, 6'd27, 6'd28, 6'd28, 6'd28, 6'd29, 6'd29, - 6'd29, 6'd29, 6'd30, 6'd30, 6'd30, 6'd31, 6'd31, 6'd31, - 6'd31, 6'd32, 6'd32, 6'd32, 6'd33, 6'd33, 6'd33, 6'd33, - 6'd34, 6'd34, 6'd34, 6'd35, 6'd35, 6'd35, 6'd35, 6'd36, - 6'd36, 6'd36, 6'd36, 6'd37, 6'd37, 6'd37, 6'd38, 6'd38, - 6'd38, 6'd38, 6'd39, 6'd39, 6'd39, 6'd40, 6'd40, 6'd40, - 6'd40, 6'd41, 6'd41, 6'd41, 6'd42, 6'd42, 6'd42, 6'd42, - 6'd43, 6'd43, 6'd43, 6'd44, 6'd44, 6'd44, 6'd44, 6'd45, - 6'd45, 6'd45, 6'd46, 6'd46, 6'd46, 6'd46, 6'd47, 6'd47, - 6'd47, 6'd48, 6'd48, 6'd48, 6'd48, 6'd49, 6'd49, 6'd49, - 6'd50, 6'd50, 6'd50, 6'd50, 6'd51, 6'd51, 6'd51, 6'd52, - 6'd52, 6'd52, 6'd52, 6'd53, 6'd53, 6'd53, 6'd54, 6'd54, - 6'd54, 6'd54, 6'd55, 6'd55, 6'd55, 6'd56, 6'd56, 6'd56, - 6'd56, 6'd57, 6'd57, 6'd57, 6'd58, 6'd58, 6'd58, 6'd58, - 6'd59, 6'd59, 6'd59, 6'd60, 6'd60, 6'd60, 6'd60, 6'd61, - 6'd61, 6'd61, 6'd62, 6'd62, 6'd62, 6'd62, 6'd63, 6'd63, - 6'd63 -}; - -wire [18:0] y_8 = 19'd04096 + ({red, 8'd0} + {red, 3'd0}) + ({green, 9'd0} + {green, 2'd0}) + ({blue, 6'd0} + {blue, 5'd0} + {blue, 2'd0}); -wire [18:0] pb_8 = 19'd32768 - ({red, 7'd0} + {red, 4'd0} + {red, 3'd0}) - ({green, 8'd0} + {green, 5'd0} + {green, 3'd0}) + ({blue, 8'd0} + {blue, 7'd0} + {blue, 6'd0}); -wire [18:0] pr_8 = 19'd32768 + ({red, 8'd0} + {red, 7'd0} + {red, 6'd0}) - ({green, 8'd0} + {green, 6'd0} + {green, 5'd0} + {green, 4'd0} + {green, 3'd0}) - ({blue, 6'd0} + {blue , 3'd0}); - -wire [7:0] y_i = ( y_8[17:8] < 16) ? 8'd16 : ( y_8[17:8] > 235) ? 8'd235 : y_8[15:8]; -wire [7:0] pb_i = (pb_8[17:8] < 16) ? 8'd16 : (pb_8[17:8] > 240) ? 8'd240 : pb_8[15:8]; -wire [7:0] pr_i = (pr_8[17:8] < 16) ? 8'd16 : (pr_8[17:8] > 240) ? 8'd240 : pr_8[15:8]; - -assign pr = yuv_full[pr_i - 8'd16]; -assign y = yuv_full[y_i - 8'd16]; -assign pb = yuv_full[pb_i - 8'd16]; - -endmodule diff --git a/cores/archie/fpga/mist/scandoubler.v b/cores/archie/fpga/mist/scandoubler.v deleted file mode 100644 index fab0f83..0000000 --- a/cores/archie/fpga/mist/scandoubler.v +++ /dev/null @@ -1,216 +0,0 @@ -// -// scandoubler.v -// -// Copyright (c) 2015 Till Harbaum -// -// This source file is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published -// by the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This source file is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -// TODO: Delay vsync one line - -module scandoubler -( - // system interface - input clk_sys, - - // scanlines (00-none 01-25% 10-50% 11-75%) - input [1:0] scanlines, - input ce_divider, // 0 - 4, 1 - 2 - - // shifter video interface - input hs_in, - input vs_in, - input [COLOR_DEPTH-1:0] r_in, - input [COLOR_DEPTH-1:0] g_in, - input [COLOR_DEPTH-1:0] b_in, - - // output interface - output reg hs_out, - output reg vs_out, - output reg [5:0] r_out, - output reg [5:0] g_out, - output reg [5:0] b_out -); - -parameter HCNT_WIDTH = 9; -parameter COLOR_DEPTH = 6; - -// try to detect changes in input signal and lock input clock gate -// it - -reg [1:0] i_div; - -reg ce_x1, ce_x2; - -always @(*) begin - if (!ce_divider) begin - ce_x1 = (i_div == 2'b01); - ce_x2 = i_div[0]; - end else begin - ce_x1 = ~i_div[0]; - ce_x2 = 1'b1; - end -end - -always @(posedge clk_sys) begin - reg last_hs_in; - last_hs_in <= hs_in; - if(last_hs_in & !hs_in) begin - i_div <= 2'b00; - end else begin - i_div <= i_div + 2'd1; - end -end - - -// --------------------- create output signals ----------------- -// latch everything once more to make it glitch free and apply scanline effect -reg scanline; -reg [5:0] r; -reg [5:0] g; -reg [5:0] b; - -always @(*) begin - if (COLOR_DEPTH == 6) begin - b = sd_out[5:0]; - g = sd_out[11:6]; - r = sd_out[17:12]; - end else if (COLOR_DEPTH == 2) begin - b = {3{sd_out[1:0]}}; - g = {3{sd_out[3:2]}}; - r = {3{sd_out[5:4]}}; - end else if (COLOR_DEPTH == 1) begin - b = {6{sd_out[0]}}; - g = {6{sd_out[1]}}; - r = {6{sd_out[2]}}; - end else begin - b = { sd_out[COLOR_DEPTH-1:0], sd_out[COLOR_DEPTH-1 -:(6-COLOR_DEPTH)] }; - g = { sd_out[COLOR_DEPTH*2-1:COLOR_DEPTH], sd_out[COLOR_DEPTH*2-1 -:(6-COLOR_DEPTH)] }; - r = { sd_out[COLOR_DEPTH*3-1:COLOR_DEPTH*2], sd_out[COLOR_DEPTH*3-1 -:(6-COLOR_DEPTH)] }; - end -end - -always @(posedge clk_sys) begin - if(ce_x2) begin - hs_out <= hs_sd; - vs_out <= vs_in; - - // reset scanlines at every new screen - if(vs_out != vs_in) scanline <= 0; - - // toggle scanlines at begin of every hsync - if(hs_out && !hs_sd) scanline <= !scanline; - - // if no scanlines or not a scanline - if(!scanline || !scanlines) begin - r_out <= r; - g_out <= g; - b_out <= b; - end else begin - case(scanlines) - 1: begin // reduce 25% = 1/2 + 1/4 - r_out <= {1'b0, r[5:1]} + {2'b00, r[5:2] }; - g_out <= {1'b0, g[5:1]} + {2'b00, g[5:2] }; - b_out <= {1'b0, b[5:1]} + {2'b00, b[5:2] }; - end - - 2: begin // reduce 50% = 1/2 - r_out <= {1'b0, r[5:1]}; - g_out <= {1'b0, g[5:1]}; - b_out <= {1'b0, b[5:1]}; - end - - 3: begin // reduce 75% = 1/4 - r_out <= {2'b00, r[5:2]}; - g_out <= {2'b00, g[5:2]}; - b_out <= {2'b00, b[5:2]}; - end - endcase - end - end -end - -// scan doubler output register -reg [COLOR_DEPTH*3-1:0] sd_out; - -// ================================================================== -// ======================== the line buffers ======================== -// ================================================================== - -// 2 lines of 2**HCNT_WIDTH pixels 3*COLOR_DEPTH bit RGB -(* ramstyle = "no_rw_check" *) reg [COLOR_DEPTH*3-1:0] sd_buffer[2*2**HCNT_WIDTH]; - -// use alternating sd_buffers when storing/reading data -reg line_toggle; - -// total hsync time (in 16MHz cycles), hs_total reaches 1024 -reg [HCNT_WIDTH-1:0] hs_max; -reg [HCNT_WIDTH-1:0] hs_rise; -reg [HCNT_WIDTH-1:0] hcnt; - -always @(posedge clk_sys) begin - reg hsD, vsD; - - if(ce_x1) begin - hsD <= hs_in; - - // falling edge of hsync indicates start of line - if(hsD && !hs_in) begin - hs_max <= hcnt; - hcnt <= 0; - end else begin - hcnt <= hcnt + 1'd1; - end - - // save position of rising edge - if(!hsD && hs_in) hs_rise <= hcnt; - - vsD <= vs_in; - if(vsD != vs_in) line_toggle <= 0; - - // begin of incoming hsync - if(hsD && !hs_in) line_toggle <= !line_toggle; - - sd_buffer[{line_toggle, hcnt}] <= {r_in, g_in, b_in}; - end -end - -// ================================================================== -// ==================== output timing generation ==================== -// ================================================================== - -reg [HCNT_WIDTH-1:0] sd_hcnt; -reg hs_sd; - -// timing generation runs 32 MHz (twice the input signal analysis speed) -always @(posedge clk_sys) begin - reg hsD; - - if(ce_x2) begin - hsD <= hs_in; - - // output counter synchronous to input and at twice the rate - sd_hcnt <= sd_hcnt + 1'd1; - if(hsD && !hs_in) sd_hcnt <= hs_max; - if(sd_hcnt == hs_max) sd_hcnt <= 0; - - // replicate horizontal sync at twice the speed - if(sd_hcnt == hs_max) hs_sd <= 0; - if(sd_hcnt == hs_rise) hs_sd <= 1; - - // read data from line sd_buffer - sd_out <= sd_buffer[{~line_toggle, sd_hcnt}]; - end -end - -endmodule diff --git a/cores/archie/fpga/mist/user_io.v b/cores/archie/fpga/mist/user_io.v index e148090..4176cb3 100644 --- a/cores/archie/fpga/mist/user_io.v +++ b/cores/archie/fpga/mist/user_io.v @@ -33,6 +33,7 @@ module user_io ( output [7:0] JOY1, output scandoubler_disable, output ypbpr, + output no_csync, input [7:0] kbd_out_data, input kbd_out_strobe, @@ -80,6 +81,7 @@ assign BUTTONS = but_sw[1:0]; assign SWITCHES = but_sw[3:2]; assign scandoubler_disable = but_sw[4]; assign ypbpr = but_sw[5]; +assign no_csync = but_sw[6]; // this variant of user_io is for the achie core (type == a6) only wire [7:0] core_type = 8'ha6;