From e7d5d8b098d46a7422904d665c2dd02f14c967d2 Mon Sep 17 00:00:00 2001 From: Gyorgy Szombathelyi Date: Thu, 30 Aug 2018 01:49:47 +0200 Subject: [PATCH] C16: get rid of generated clocks because of the OSD --- cores/c16/c16_mist.v | 19 ++++++---- cores/c16/osd.v | 87 ++++++++++++++++++++++++-------------------- 2 files changed, 60 insertions(+), 46 deletions(-) diff --git a/cores/c16/c16_mist.v b/cores/c16/c16_mist.v index 0cc1840..82b5be5 100644 --- a/cores/c16/c16_mist.v +++ b/cores/c16/c16_mist.v @@ -412,11 +412,12 @@ wire [5:0] osd_b_in = tv15khz?{c16_b, 2'b00}:video_b; wire osd_hs_in = tv15khz?!c16_hs:video_hs; wire osd_vs_in = tv15khz?!c16_vs:video_vs; -wire osd_clk = tv15khz?clk7:clk28; +wire osd_clk = tv15khz?clk7:clk14; // include the on screen display osd #(11,0,5) osd ( - .pclk ( osd_clk ), + .clk_sys ( clk28 ), + .ce_pix ( osd_clk ), // spi for OSD .sdi ( SPI_DI ), @@ -560,12 +561,16 @@ wire pll_locked = pll_pal_locked && pll_ntsc_locked; // tv15hkz has quarter the pixel rate, so we need a 7mhz clock for the OSD reg clk7; -always @(posedge clk14) - clk7 <= !clk7; - reg clk14; -always @(posedge clk28) - clk14 <= !clk14; + +always @(posedge clk28) begin + + reg [1:0] counter; + + counter <= counter + 1'd1; + clk7 <= !counter; + clk14 <= !counter[0]; +end // A PLL to derive the system clock from the MiSTs 27MHz wire clk32; diff --git a/cores/c16/osd.v b/cores/c16/osd.v index 3c5ba47..63c7367 100644 --- a/cores/c16/osd.v +++ b/cores/c16/osd.v @@ -26,7 +26,8 @@ module osd ( // OSDs pixel clock, should be synchronous to cores pixel clock to // avoid jitter. - input pclk, + input clk_sys, + input ce_pix, // SPI interface input sck, @@ -114,25 +115,27 @@ wire hs_pol = hs_high < hs_low; wire [9:0] h_dsp_width = hs_pol?hs_low:hs_high; wire [9:0] h_dsp_ctr = { 1'b0, h_dsp_width[9:1] }; -always @(posedge pclk) begin - // bring hsync into local clock domain - hsD <= hs_in; - hsD2 <= hsD; +always @(posedge clk_sys) begin + if (ce_pix) begin + // bring hsync into local clock domain + hsD <= hs_in; + hsD2 <= hsD; - // falling edge of hs_in - if(!hsD && hsD2) begin - h_cnt <= 10'd0; - hs_high <= h_cnt; + // falling edge of hs_in + if(!hsD && hsD2) begin + h_cnt <= 10'd0; + hs_high <= h_cnt; + end + + // rising edge of hs_in + else if(hsD && !hsD2) begin + h_cnt <= 10'd0; + hs_low <= h_cnt; + end + + else + h_cnt <= h_cnt + 10'd1; end - - // rising edge of hs_in - else if(hsD && !hsD2) begin - h_cnt <= 10'd0; - hs_low <= h_cnt; - end - - else - h_cnt <= h_cnt + 10'd1; end // vertical counter @@ -143,25 +146,31 @@ wire vs_pol = vs_high < vs_low; wire [9:0] v_dsp_width = vs_pol?vs_low:vs_high; wire [9:0] v_dsp_ctr = { 1'b0, v_dsp_width[9:1] }; -always @(posedge hs_in) begin - // bring vsync into local clock domain - vsD <= vs_in; - vsD2 <= vsD; - - // falling edge of vs_in - if(!vsD && vsD2) begin - v_cnt <= 10'd0; - vs_high <= v_cnt; - end - - // rising edge of vs_in - else if(vsD && !vsD2) begin - v_cnt <= 10'd0; - vs_low <= v_cnt; - end +always @(posedge clk_sys) begin + reg hsD; - else - v_cnt <= v_cnt + 10'd1; + hsD <= hs_in; + + if (~hsD & hs_in) begin + // bring vsync into local clock domain + vsD <= vs_in; + vsD2 <= vsD; + + // falling edge of vs_in + if(!vsD && vsD2) begin + v_cnt <= 10'd0; + vs_high <= v_cnt; + end + + // rising edge of vs_in + else if(vsD && !vsD2) begin + v_cnt <= 10'd0; + vs_low <= v_cnt; + end + + else + v_cnt <= v_cnt + 10'd1; + end end // area in which OSD is being displayed @@ -171,7 +180,7 @@ wire [9:0] v_osd_start = v_dsp_ctr + OSD_Y_OFFSET - (OSD_HEIGHT >> 1); wire [9:0] v_osd_end = v_dsp_ctr + OSD_Y_OFFSET + (OSD_HEIGHT >> 1) - 1; reg h_osd_active, v_osd_active; -always @(posedge pclk) begin +always @(posedge clk_sys) begin if(hs_in != hs_pol) begin if(h_cnt == h_osd_start) h_osd_active <= 1'b1; if(h_cnt == h_osd_end) h_osd_active <= 1'b0; @@ -190,8 +199,8 @@ wire [6:0] osd_vcnt = v_cnt - v_osd_start; wire osd_pixel = osd_byte[osd_vcnt[3:1]]; reg [7:0] osd_byte; -always @(posedge pclk) - osd_byte <= osd_buffer[{osd_vcnt[6:4], osd_hcnt}]; +always @(posedge clk_sys) + if (ce_pix) osd_byte <= osd_buffer[{osd_vcnt[6:4], osd_hcnt}]; wire [2:0] osd_color = OSD_COLOR; assign red_out = !osd_de?red_in: {osd_pixel, osd_pixel, osd_color[2], red_in[5:3] };