// (C) 2001-2025 Altera Corporation. All rights reserved.
// Your use of Altera Corporation's design tools, logic functions and other 
// software and tools, and its AMPP partner logic functions, and any output 
// files from any of the foregoing (including device programming or simulation 
// files), and any associated documentation or information are expressly subject 
// to the terms and conditions of the Altera Program License Subscription 
// Agreement, Altera IP License Agreement, or other applicable 
// license agreement, including, without limitation, that your use is for the 
// sole purpose of programming logic devices manufactured by Altera and sold by 
// Altera or its authorized distributors.  Please refer to the applicable 
// agreement for further details.


`default_nettype none
module intel_vvp_vtiming_cpu
#(
  parameter C_BUILD_VRR                             = 1,
  parameter C_BUILD_HARD_FRAME_LOCK                 = 1,
  parameter C_BUILD_SOFT_FRAME_LOCK                 = 1,

  parameter C_CPU_OFFSET                            = 16,
  parameter C_NUM_PULSES                            = 2,
  parameter C_USE_CPU                               = 1,
  parameter C_OUTPUT_IS_CV                          = 1,
  parameter C_CV_NUM_PLANES                         = 3,
  parameter C_CV_NUM_PIXELS                         = 1,
  parameter C_CV_BIT_DEPTH                          = 10,
  parameter C_HSIZE                                 = 14, // max 16k pixels
  parameter C_VSIZE                                 = 14, // max 16k lines

  parameter C_CPU_CLK_FREQ_HZ                       = 100000000,

  parameter C_DEFAULT_OUT_IS_BLANK                  = 0,
  parameter C_DEFAULT_BLACK_0                       = 0,
  parameter C_DEFAULT_BLACK_1                       = 0,
  parameter C_DEFAULT_BLACK_2                       = 0,
  parameter C_DEFAULT_BLACK_3                       = 0,
  parameter C_DEFAULT_ENABLE_FRAME_LOCK             = 0,
  parameter C_DEFAULT_ENABLE_SOFT_LOCK              = 0,
  parameter C_DEFAULT_ENABLE_VARIABLE_REFRESH_RATE  = 0,
  parameter C_DEFAULT_ENABLE_VRR_LINEMODE           = 0,
  parameter C_DEFAULT_FRAME_START_PULSE             = 0,        // 1=frame start is a once-per-frame toggle. 0=frame start is a pulse once per frame.
  parameter C_DEFAULT_FRAME_START_MAX_JITTER        = 15,       // number of pixels of jitter allowed to create the "legal" window in which the start pulse can arrive
  parameter C_DEFAULT_FRAME_ADJ_IGNORE_LINES        = 3,        // number of lines for the +/- window that does not change the total_v
  parameter C_DEFAULT_FRAME_ADJ_WINDOW_LINES        = 6,        // number of lines start/end of the window that adjusts the total_v
  
  // default timing parameters
  parameter C_TIM_HRESET            = 1,        // H Total
  parameter C_TIM_VRESET            = 1,        // V Total
  parameter C_TIM_HTOTAL            = 2200,     // H Total
  parameter C_TIM_VTOTAL            = 1125,     // V Total
  parameter C_TIM_HB_END            = 280,      // H-Active Start
  parameter C_TIM_V1B_START         = 1122,     // V1-Blank Start
  parameter C_TIM_V1B_END           = 44,       // V1-Blank End
  parameter C_TIM_V2B_START         = 9999,     // V2-Blank Start
  parameter C_TIM_V2B_END           = 9999,     // V2-Blank End
  parameter C_TIM_F1_START          = 1,        // F1-Start
  parameter C_TIM_F2_START          = 9999,     // F2-Start
  parameter C_TIM_HS_START          = 5,        // HSync Start Pos
  parameter C_TIM_HS_END            = 10,       // HSync End Pos
  parameter C_TIM_V1S_VSTART        = 5,        // V1Sync Start Line
  parameter C_TIM_V1S_HSTART        = 4,        // V1Sync Start HPos
  parameter C_TIM_V1S_VEND          = 6,        // V1Sync End Line
  parameter C_TIM_V1S_HEND          = 10,       // V1Sync End HPos
  parameter C_TIM_V2S_VSTART        = 7,        // V2Sync Start Line
  parameter C_TIM_V2S_HSTART        = 1,        // V2Sync Start HPos
  parameter C_TIM_V2S_VEND          = 8,        // V2Sync End Line
  parameter C_TIM_V2S_HEND          = 10,       // V2Sync End HPos
  parameter C_TIM_PULSE0_VSTART     = 1,        // Line in which to generate pulse 0 (SOF_EARLY)
  parameter C_TIM_PULSE0_HSTART     = 1,        // Pixel in which to generate pulse 0 (SOF_EARLY)
  parameter C_TIM_PULSE0_VEND       = 1,        // Line in which to end pulse 0 (SOF_EARLY)
  parameter C_TIM_PULSE0_HEND       = 1,        // Pixel in which to end pulse 0 (SOF_EARLY)
  parameter C_TIM_PULSE1_VSTART     = 5,        // Line in which to generate pulse 1 (SOF)
  parameter C_TIM_PULSE1_HSTART     = 1,        // Pixel in which to generate pulse 1 (SOF)
  parameter C_TIM_PULSE1_VEND       = 5,        // Line in which to end pulse 1 (SOF)
  parameter C_TIM_PULSE1_HEND       = 1,        // Pixel in which to end pulse 1 (SOF)
  parameter C_TIM_PULSE2_VSTART     = 9999,     // Line in which to generate pulse 2
  parameter C_TIM_PULSE2_HSTART     = 9999,     // Pixel in which to generate pulse 2
  parameter C_TIM_PULSE2_VEND       = 9999,     // Line in which to end pulse 2
  parameter C_TIM_PULSE2_HEND       = 9999,     // Pixel in which to end pulse 2
  parameter C_TIM_PULSE3_VSTART     = 9999,     // Line in which to generate pulse 3
  parameter C_TIM_PULSE3_HSTART     = 9999,     // Pixel in which to generate pulse 3
  parameter C_TIM_PULSE3_VEND       = 9999,     // Line in which to end pulse 3
  parameter C_TIM_PULSE3_HEND       = 9999,     // Pixel in which to end pulse 3
  parameter C_TIM_PULSE4_VSTART     = 9999,     // Line in which to generate pulse 4
  parameter C_TIM_PULSE4_HSTART     = 9999,     // Pixel in which to generate pulse 4
  parameter C_TIM_PULSE4_VEND       = 9999,     // Line in which to end pulse 4
  parameter C_TIM_PULSE4_HEND       = 9999,     // Pixel in which to end pulse 4
  parameter C_TIM_PULSE5_VSTART     = 9999,     // Line in which to generate pulse 5
  parameter C_TIM_PULSE5_HSTART     = 9999,     // Pixel in which to generate pulse 5
  parameter C_TIM_PULSE5_VEND       = 9999,     // Line in which to end pulse 5
  parameter C_TIM_PULSE5_HEND       = 9999,     // Pixel in which to end pulse 5
  parameter C_TIM_PULSE6_VSTART     = 9999,     // Line in which to generate pulse 6
  parameter C_TIM_PULSE6_HSTART     = 9999,     // Pixel in which to generate pulse 6
  parameter C_TIM_PULSE6_VEND       = 9999,     // Line in which to end pulse 6
  parameter C_TIM_PULSE6_HEND       = 9999,     // Pixel in which to end pulse 6
  parameter C_TIM_PULSE7_VSTART     = 9999,     // Line in which to generate pulse 7
  parameter C_TIM_PULSE7_HSTART     = 9999,     // Pixel in which to generate pulse 7
  parameter C_TIM_PULSE7_VEND       = 9999,     // Line in which to end pulse 7
  parameter C_TIM_PULSE7_HEND       = 9999      // Pixel in which to end pulse 7

)
(
  cpu_clk,
  cpu_rst,

  av_address,
  av_read,
  av_readdata,
  av_readdatavalid,
  av_waitrequest,
  av_write,
  av_writedata,
  av_byteenable,

  vid_clk,
  vid_rst,

  frame_start,
  r_pixel_00,

  // cpu defined regs
  r_vid_frame_start_pulse  ,
  r_vid_tim_hreset         ,
  r_vid_tim_vreset         ,

  r_vid_tim_htotal         ,
  r_vid_tim_vtotal         ,
  r_vid_tim_hb_end         ,
  r_vid_tim_v1b_start      ,
  r_vid_tim_v1b_end        ,
  r_vid_tim_v2b_start      ,
  r_vid_tim_v2b_end        ,
  r_vid_tim_f1_start       ,
  r_vid_tim_f2_start       ,
  r_vid_tim_hs_start       ,
  r_vid_tim_hs_end         ,
  r_vid_tim_v1s_vstart     ,
  r_vid_tim_v1s_hstart     ,
  r_vid_tim_v1s_vend       ,
  r_vid_tim_v1s_hend       ,
  r_vid_tim_v2s_vstart     ,
  r_vid_tim_v2s_hstart     ,
  r_vid_tim_v2s_vend       ,
  r_vid_tim_v2s_hend       ,

  r_vid_tim_pulse0_vstart  ,
  r_vid_tim_pulse0_hstart  ,
  r_vid_tim_pulse0_vend    ,
  r_vid_tim_pulse0_hend    ,
  r_vid_tim_pulse1_vstart  ,
  r_vid_tim_pulse1_hstart  ,
  r_vid_tim_pulse1_vend    ,
  r_vid_tim_pulse1_hend    ,
  r_vid_tim_pulse2_vstart  ,
  r_vid_tim_pulse2_hstart  ,
  r_vid_tim_pulse2_vend    ,
  r_vid_tim_pulse2_hend    ,
  r_vid_tim_pulse3_vstart  ,
  r_vid_tim_pulse3_hstart  ,
  r_vid_tim_pulse3_vend    ,
  r_vid_tim_pulse3_hend    ,
  r_vid_tim_pulse4_vstart  ,
  r_vid_tim_pulse4_hstart  ,
  r_vid_tim_pulse4_vend    ,
  r_vid_tim_pulse4_hend    ,
  r_vid_tim_pulse5_vstart  ,
  r_vid_tim_pulse5_hstart  ,
  r_vid_tim_pulse5_vend    ,
  r_vid_tim_pulse5_hend    ,
  r_vid_tim_pulse6_vstart  ,
  r_vid_tim_pulse6_hstart  ,
  r_vid_tim_pulse6_vend    ,
  r_vid_tim_pulse6_hend    ,
  r_vid_tim_pulse7_vstart  ,
  r_vid_tim_pulse7_hstart  ,
  r_vid_tim_pulse7_vend    ,
  r_vid_tim_pulse7_hend    ,
  r_vid_allow_hv_reset     ,
  r_vid_out_is_blank       ,
  r_vid_black              ,
  r_vid_use_soft_reset     ,
  r_vid_vrr                ,
  r_vid_vrr_linemode       ,


  r_vid_start_counter      ,
  r_vid_frame_count        ,


  r_vid_frame_start_jitter ,
  r_vid_frame_adj_ignore   ,
  r_vid_frame_adj_window   ,
  // data for cpu to read
  r_actual_pixels_latched  ,
  r_vid_tim_vtotal_latched ,
   
  r_vid_hv_reset_count,
  
  vid_inc_count    ,
  vid_dec_count    ,
  vid_stable_count   
);
// calculate localparams needed for the interface.
localparam C_AXIS_PIXEL_BYTES = ((C_CV_NUM_PLANES+1)*C_CV_BIT_DEPTH+7)/8;
localparam C_AXIS_WIDTH       = C_AXIS_PIXEL_BYTES*C_CV_NUM_PIXELS*8;
localparam C_TUSER_WIDTH      = C_AXIS_PIXEL_BYTES*C_CV_NUM_PIXELS;
localparam C_CV_PIXEL_BITS    = C_CV_NUM_PLANES * C_CV_BIT_DEPTH;
localparam C_CV_WIDTH         = C_CV_NUM_PIXELS * C_CV_PIXEL_BITS;

localparam C_VID_CLK_TIMEOUT  = 128;
input  logic                         cpu_clk;
input  logic                         cpu_rst;
input  logic [ 5:0]                  av_address;
input  logic                         av_read;
output logic [31:0]                  av_readdata;
output logic                         av_readdatavalid;
output logic                         av_waitrequest;
input  logic                         av_write;
input  logic [31:0]                  av_writedata;
input  logic [ 3:0]                  av_byteenable;

input  logic                         vid_clk;
input  logic                         vid_rst;

input  logic                         frame_start;
input  logic                         r_pixel_00;

output logic               r_vid_frame_start_pulse;
output logic [C_HSIZE-1:0] r_vid_tim_hreset       ;
output logic [C_VSIZE-1:0] r_vid_tim_vreset       ;

output logic [C_HSIZE-1:0] r_vid_tim_htotal       ;
output logic [C_VSIZE-1:0] r_vid_tim_vtotal       ;
output logic [C_HSIZE-1:0] r_vid_tim_hb_end       ;
output logic [C_VSIZE-1:0] r_vid_tim_v1b_start    ;
output logic [C_VSIZE-1:0] r_vid_tim_v1b_end      ;
output logic [C_VSIZE-1:0] r_vid_tim_v2b_start    ;
output logic [C_VSIZE-1:0] r_vid_tim_v2b_end      ;
output logic [C_VSIZE-1:0] r_vid_tim_f1_start     ;
output logic [C_VSIZE-1:0] r_vid_tim_f2_start     ;
output logic [C_HSIZE-1:0] r_vid_tim_hs_start     ;
output logic [C_HSIZE-1:0] r_vid_tim_hs_end       ;
output logic [C_VSIZE-1:0] r_vid_tim_v1s_vstart   ;
output logic [C_HSIZE-1:0] r_vid_tim_v1s_hstart   ;
output logic [C_VSIZE-1:0] r_vid_tim_v1s_vend     ;
output logic [C_HSIZE-1:0] r_vid_tim_v1s_hend     ;
output logic [C_VSIZE-1:0] r_vid_tim_v2s_vstart   ;
output logic [C_HSIZE-1:0] r_vid_tim_v2s_hstart   ;
output logic [C_VSIZE-1:0] r_vid_tim_v2s_vend     ;
output logic [C_HSIZE-1:0] r_vid_tim_v2s_hend     ;

output logic [C_VSIZE-1:0] r_vid_tim_pulse0_vstart;
output logic [C_HSIZE-1:0] r_vid_tim_pulse0_hstart;
output logic [C_VSIZE-1:0] r_vid_tim_pulse0_vend  ;
output logic [C_HSIZE-1:0] r_vid_tim_pulse0_hend  ;
output logic [C_VSIZE-1:0] r_vid_tim_pulse1_vstart;
output logic [C_HSIZE-1:0] r_vid_tim_pulse1_hstart;
output logic [C_VSIZE-1:0] r_vid_tim_pulse1_vend  ;
output logic [C_HSIZE-1:0] r_vid_tim_pulse1_hend  ;
output logic [C_VSIZE-1:0] r_vid_tim_pulse2_vstart;
output logic [C_HSIZE-1:0] r_vid_tim_pulse2_hstart;
output logic [C_VSIZE-1:0] r_vid_tim_pulse2_vend  ;
output logic [C_HSIZE-1:0] r_vid_tim_pulse2_hend  ;
output logic [C_VSIZE-1:0] r_vid_tim_pulse3_vstart;
output logic [C_HSIZE-1:0] r_vid_tim_pulse3_hstart;
output logic [C_VSIZE-1:0] r_vid_tim_pulse3_vend  ;
output logic [C_HSIZE-1:0] r_vid_tim_pulse3_hend  ;
output logic [C_VSIZE-1:0] r_vid_tim_pulse4_vstart;
output logic [C_HSIZE-1:0] r_vid_tim_pulse4_hstart;
output logic [C_VSIZE-1:0] r_vid_tim_pulse4_vend  ;
output logic [C_HSIZE-1:0] r_vid_tim_pulse4_hend  ;
output logic [C_VSIZE-1:0] r_vid_tim_pulse5_vstart;
output logic [C_HSIZE-1:0] r_vid_tim_pulse5_hstart;
output logic [C_VSIZE-1:0] r_vid_tim_pulse5_vend  ;
output logic [C_HSIZE-1:0] r_vid_tim_pulse5_hend  ;
output logic [C_VSIZE-1:0] r_vid_tim_pulse6_vstart;
output logic [C_HSIZE-1:0] r_vid_tim_pulse6_hstart;
output logic [C_VSIZE-1:0] r_vid_tim_pulse6_vend  ;
output logic [C_HSIZE-1:0] r_vid_tim_pulse6_hend  ;
output logic [C_VSIZE-1:0] r_vid_tim_pulse7_vstart;
output logic [C_HSIZE-1:0] r_vid_tim_pulse7_hstart;
output logic [C_VSIZE-1:0] r_vid_tim_pulse7_vend  ;
output logic [C_HSIZE-1:0] r_vid_tim_pulse7_hend  ;
output logic               r_vid_allow_hv_reset   ;
output logic               r_vid_out_is_blank     ;
output logic [C_CV_PIXEL_BITS-1:0] r_vid_black    ;
output logic               r_vid_use_soft_reset   ;
output logic               r_vid_vrr              ;
output logic               r_vid_vrr_linemode     ;

output logic [        7:0] r_vid_frame_start_jitter;
output logic [        7:0] r_vid_frame_adj_ignore  ;
output logic [        7:0] r_vid_frame_adj_window  ;

  // data for cpu to read
input  logic [15:0]                       r_vid_start_counter;
input  logic [15:0]                       r_vid_frame_count;
input  logic [C_VSIZE-1 : 0]              r_vid_tim_vtotal_latched ;
input  logic [C_HSIZE + C_VSIZE - 1  : 0] r_actual_pixels_latched;

input  logic [15:0]                       r_vid_hv_reset_count;

input  logic [15:0]                       vid_inc_count    ;
input  logic [15:0]                       vid_dec_count    ;
input  logic [15:0]                       vid_stable_count ;


///////////////////////////////////////////////////////////////////////////////
//
// localparams
//

// useful localparams

// register cpu i/f
logic [ 5:0]                  r_av_address;
logic                         r_av_read;
logic                         r_av_write;
logic [31:0]                  r_av_writedata;
logic [ 3:0]                  r_av_byteenable;
always_ff @(posedge cpu_clk)
begin:a_reg_cpu_if
  if (cpu_rst) begin
    r_av_address    <= 6'b0;
  end
  else begin
    if (av_read || av_write) begin
      r_av_address      <= av_address;
    end
  end

  r_av_read         <= av_read;
  r_av_write        <= av_write;
  r_av_writedata    <= av_writedata;
  r_av_byteenable   <= av_byteenable;
end  
//////////////////////////////////////////////////////////////////////////////
//
// Setup config registers, and decode CPU is required
//
logic               r_cpu_vid_clk_running;
logic               r_vid_update_timing_request;
logic               r_cpu_update_timing_request;
logic               r_cpu_update_timing;
logic               r2_cpu_update_timing;
logic               r_cpu_update_timing_toggle;
logic               r_cpu_frame_start_pulse;
logic [C_HSIZE-1:0] r_cpu_tim_hreset       ;
logic [C_VSIZE-1:0] r_cpu_tim_vreset       ;

logic [C_HSIZE-1:0] r_cpu_tim_htotal       ;
logic [C_VSIZE-1:0] r_cpu_tim_vtotal       ;
logic [C_HSIZE-1:0] r_cpu_tim_hb_end       ;
logic [C_VSIZE-1:0] r_cpu_tim_v1b_start    ;
logic [C_VSIZE-1:0] r_cpu_tim_v1b_end      ;
logic [C_VSIZE-1:0] r_cpu_tim_v2b_start    ;
logic [C_VSIZE-1:0] r_cpu_tim_v2b_end      ;
logic [C_VSIZE-1:0] r_cpu_tim_f1_start     ;
logic [C_VSIZE-1:0] r_cpu_tim_f2_start     ;
logic [C_HSIZE-1:0] r_cpu_tim_hs_start     ;
logic [C_HSIZE-1:0] r_cpu_tim_hs_end       ;
logic [C_VSIZE-1:0] r_cpu_tim_v1s_vstart   ;
logic [C_HSIZE-1:0] r_cpu_tim_v1s_hstart   ;
logic [C_VSIZE-1:0] r_cpu_tim_v1s_vend     ;
logic [C_HSIZE-1:0] r_cpu_tim_v1s_hend     ;
logic [C_VSIZE-1:0] r_cpu_tim_v2s_vstart   ;
logic [C_HSIZE-1:0] r_cpu_tim_v2s_hstart   ;
logic [C_VSIZE-1:0] r_cpu_tim_v2s_vend     ;
logic [C_HSIZE-1:0] r_cpu_tim_v2s_hend     ;

logic [C_VSIZE-1:0] r_cpu_tim_pulse0_vstart;
logic [C_HSIZE-1:0] r_cpu_tim_pulse0_hstart;
logic [C_VSIZE-1:0] r_cpu_tim_pulse0_vend  ;
logic [C_HSIZE-1:0] r_cpu_tim_pulse0_hend  ;
logic [C_VSIZE-1:0] r_cpu_tim_pulse1_vstart;
logic [C_HSIZE-1:0] r_cpu_tim_pulse1_hstart;
logic [C_VSIZE-1:0] r_cpu_tim_pulse1_vend  ;
logic [C_HSIZE-1:0] r_cpu_tim_pulse1_hend  ;
logic [C_VSIZE-1:0] r_cpu_tim_pulse2_vstart;
logic [C_HSIZE-1:0] r_cpu_tim_pulse2_hstart;
logic [C_VSIZE-1:0] r_cpu_tim_pulse2_vend  ;
logic [C_HSIZE-1:0] r_cpu_tim_pulse2_hend  ;
logic [C_VSIZE-1:0] r_cpu_tim_pulse3_vstart;
logic [C_HSIZE-1:0] r_cpu_tim_pulse3_hstart;
logic [C_VSIZE-1:0] r_cpu_tim_pulse3_vend  ;
logic [C_HSIZE-1:0] r_cpu_tim_pulse3_hend  ;
logic [C_VSIZE-1:0] r_cpu_tim_pulse4_vstart;
logic [C_HSIZE-1:0] r_cpu_tim_pulse4_hstart;
logic [C_VSIZE-1:0] r_cpu_tim_pulse4_vend  ;
logic [C_HSIZE-1:0] r_cpu_tim_pulse4_hend  ;
logic [C_VSIZE-1:0] r_cpu_tim_pulse5_vstart;
logic [C_HSIZE-1:0] r_cpu_tim_pulse5_hstart;
logic [C_VSIZE-1:0] r_cpu_tim_pulse5_vend  ;
logic [C_HSIZE-1:0] r_cpu_tim_pulse5_hend  ;
logic [C_VSIZE-1:0] r_cpu_tim_pulse6_vstart;
logic [C_HSIZE-1:0] r_cpu_tim_pulse6_hstart;
logic [C_VSIZE-1:0] r_cpu_tim_pulse6_vend  ;
logic [C_HSIZE-1:0] r_cpu_tim_pulse6_hend  ;
logic [C_VSIZE-1:0] r_cpu_tim_pulse7_vstart;
logic [C_HSIZE-1:0] r_cpu_tim_pulse7_hstart;
logic [C_VSIZE-1:0] r_cpu_tim_pulse7_vend  ;
logic [C_HSIZE-1:0] r_cpu_tim_pulse7_hend  ;
logic               r_cpu_allow_hv_reset   ;
logic               r_cpu_out_is_blank     ;
logic [C_CV_PIXEL_BITS-1:0] r_cpu_black    ;
logic               r_cpu_use_soft_reset   ;
logic               r_cpu_vrr              ;
logic               r_cpu_vrr_linemode     ;
logic [31:0] r_cpu_1_second_ltchd;

logic [        7:0] r_cpu_frame_start_jitter;
logic [        7:0] r_cpu_frame_adj_ignore  ;
logic [        7:0] r_cpu_frame_adj_window  ;

logic [15:0]                       r_cpu_start_counter;
logic [15:0]                       r_cpu_frame_count;
logic [C_VSIZE-1 : 0]              r_cpu_tim_vtotal_latched ;
logic [C_HSIZE + C_VSIZE - 1  : 0] r_cpu_actual_pixels_latched;

logic [15:0]                       r_cpu_hv_reset_count;

logic [15:0]                       r_cpu_inc_count     ;
logic [15:0]                       r_cpu_dec_count     ;
logic [15:0]                       r_cpu_stable_count  ;

intel_vvp_clock_crosser #( .DATA_WIDTH  ( 16                ),  .NUM_CC_REG  ( 3 ), .INPUT_REG   ( 1 )) i_cdc_rd_0 (  .in_clk  (vid_clk),  .in_data (r_vid_start_counter      ),  .out_clk (cpu_clk),  .out_data(r_cpu_start_counter        ));
intel_vvp_clock_crosser #( .DATA_WIDTH  ( 16                ),  .NUM_CC_REG  ( 3 ), .INPUT_REG   ( 1 )) i_cdc_rd_1 (  .in_clk  (vid_clk),  .in_data (r_vid_frame_count        ),  .out_clk (cpu_clk),  .out_data(r_cpu_frame_count          ));
intel_vvp_clock_crosser #( .DATA_WIDTH  ( C_VSIZE           ),  .NUM_CC_REG  ( 3 ), .INPUT_REG   ( 1 )) i_cdc_rd_2 (  .in_clk  (vid_clk),  .in_data (r_vid_tim_vtotal_latched ),  .out_clk (cpu_clk),  .out_data(r_cpu_tim_vtotal_latched   ));
intel_vvp_clock_crosser #( .DATA_WIDTH  ( C_HSIZE + C_VSIZE ),  .NUM_CC_REG  ( 3 ), .INPUT_REG   ( 1 )) i_cdc_rd_3 (  .in_clk  (vid_clk),  .in_data (r_actual_pixels_latched  ),  .out_clk (cpu_clk),  .out_data(r_cpu_actual_pixels_latched));
                                                                                                                                                     
intel_vvp_clock_crosser #( .DATA_WIDTH  ( 16                ),  .NUM_CC_REG  ( 3 ), .INPUT_REG   ( 1 )) i_cdc_rd_4 (  .in_clk  (vid_clk),  .in_data (r_vid_hv_reset_count     ),  .out_clk (cpu_clk),  .out_data(r_cpu_hv_reset_count       ));
                                                                                                                                                     
intel_vvp_clock_crosser #( .DATA_WIDTH  ( 16                ),  .NUM_CC_REG  ( 3 ), .INPUT_REG   ( 1 )) i_cdc_rd_5 (  .in_clk  (vid_clk),  .in_data (vid_inc_count            ),  .out_clk (cpu_clk),  .out_data(r_cpu_inc_count            ));
intel_vvp_clock_crosser #( .DATA_WIDTH  ( 16                ),  .NUM_CC_REG  ( 3 ), .INPUT_REG   ( 1 )) i_cdc_rd_6 (  .in_clk  (vid_clk),  .in_data (vid_dec_count            ),  .out_clk (cpu_clk),  .out_data(r_cpu_dec_count            ));
intel_vvp_clock_crosser #( .DATA_WIDTH  ( 16                ),  .NUM_CC_REG  ( 3 ), .INPUT_REG   ( 1 )) i_cdc_rd_7 (  .in_clk  (vid_clk),  .in_data (vid_stable_count         ),  .out_clk (cpu_clk),  .out_data(r_cpu_stable_count         ));

                                           
task t_cpu_write;
  input av_write;
  input [ 3:0] av_byteenable;
  input [31:0] av_writedata;
  inout [31:0] r_some_reg32;
  if (av_write)
  begin
    if (av_byteenable[0])
      r_some_reg32[ 7: 0] = av_writedata[ 7: 0];
    if (av_byteenable[1])
      r_some_reg32[15: 8] = av_writedata[15: 8];
    if (av_byteenable[2])
      r_some_reg32[23:16] = av_writedata[23:16];
    if (av_byteenable[3])
      r_some_reg32[31:24] = av_writedata[31:24];
  end
endtask

localparam C_REG_STATUS         = C_CPU_OFFSET +  0;
localparam C_REG_COMMIT         = C_CPU_OFFSET +  1;
localparam C_REG_MODE           = C_CPU_OFFSET +  2;
localparam C_REG_RESET_POS      = C_CPU_OFFSET +  3;
localparam C_REG_TOTALS         = C_CPU_OFFSET +  4;
localparam C_REG_HB_END         = C_CPU_OFFSET +  5;
localparam C_REG_V1B_POS        = C_CPU_OFFSET +  6;
localparam C_REG_V2B_POS        = C_CPU_OFFSET +  7;
localparam C_REG_FIELD_STARTS   = C_CPU_OFFSET +  8;
localparam C_REG_HS_POS         = C_CPU_OFFSET +  9;
localparam C_REG_V1S_START      = C_CPU_OFFSET + 10;
localparam C_REG_V1S_END        = C_CPU_OFFSET + 11;
localparam C_REG_V2S_START      = C_CPU_OFFSET + 12;
localparam C_REG_V2S_END        = C_CPU_OFFSET + 13;
localparam C_REG_JITTER_CONT    = C_CPU_OFFSET + 14;
localparam C_REG_BLACK_0        = C_CPU_OFFSET + 15;
localparam C_REG_BLACK_1        = C_CPU_OFFSET + 16;
localparam C_REG_BLACK_2        = C_CPU_OFFSET + 17;
localparam C_REG_BLACK_3        = C_CPU_OFFSET + 18;
localparam C_REG_FRAME_COUNTS   = C_CPU_OFFSET + 19; //ro
localparam C_REG_FRAME_LENGTH   = C_CPU_OFFSET + 20; //ro
localparam C_REG_VTOTAL_ADJ     = C_CPU_OFFSET + 21; //ro
localparam C_REG_VID_FREQ       = C_CPU_OFFSET + 22; //ro
localparam C_REG_GENLOCK_STATS0 = C_CPU_OFFSET + 23; //ro
localparam C_REG_GENLOCK_STATS1 = C_CPU_OFFSET + 24; //ro

localparam C_REG_PULSE0_START   = C_CPU_OFFSET + 32;
localparam C_REG_PULSE0_END     = C_CPU_OFFSET + 33;
localparam C_REG_PULSE1_START   = C_CPU_OFFSET + 34;
localparam C_REG_PULSE1_END     = C_CPU_OFFSET + 35;
localparam C_REG_PULSE2_START   = C_CPU_OFFSET + 36;
localparam C_REG_PULSE2_END     = C_CPU_OFFSET + 37;
localparam C_REG_PULSE3_START   = C_CPU_OFFSET + 38;
localparam C_REG_PULSE3_END     = C_CPU_OFFSET + 39;
localparam C_REG_PULSE4_START   = C_CPU_OFFSET + 40;
localparam C_REG_PULSE4_END     = C_CPU_OFFSET + 41;
localparam C_REG_PULSE5_START   = C_CPU_OFFSET + 42;
localparam C_REG_PULSE5_END     = C_CPU_OFFSET + 43;
localparam C_REG_PULSE6_START   = C_CPU_OFFSET + 44;
localparam C_REG_PULSE6_END     = C_CPU_OFFSET + 45;
localparam C_REG_PULSE7_START   = C_CPU_OFFSET + 46;
localparam C_REG_PULSE7_END     = C_CPU_OFFSET + 47;

localparam [4*C_CV_BIT_DEPTH-1:0] C_DEFAULT_BLACK = {
  C_DEFAULT_BLACK_3[C_CV_BIT_DEPTH-1:0],
  C_DEFAULT_BLACK_2[C_CV_BIT_DEPTH-1:0],
  C_DEFAULT_BLACK_1[C_CV_BIT_DEPTH-1:0],
  C_DEFAULT_BLACK_0[C_CV_BIT_DEPTH-1:0]
};
 
intel_vvp_clock_crosser
#(
  .DATA_WIDTH  ( 1 ),
  .NUM_CC_REG  ( 3 ),  // 2 minimum, 3 recommended for Hyperflex
  .INPUT_REG   ( 1 )   // 1 to register the input first
) i_cdc_timing_request (
  .in_clk  (vid_clk),
  .in_data (r_vid_update_timing_request),
  .out_clk (cpu_clk),
  .out_data(r_cpu_update_timing_request)
);


 
always_ff @(posedge cpu_clk)
begin:a_make_cpu_regs
  logic [31:0] nb_local_reg32;
  if (cpu_rst) 
  begin
    r_cpu_update_timing       <= 1'b0;
    r2_cpu_update_timing      <= 1'b0;
    r_cpu_update_timing_toggle<= 1'b0;
    r_cpu_frame_start_pulse   <= C_DEFAULT_FRAME_START_PULSE    ; 
    r_cpu_out_is_blank        <= C_DEFAULT_OUT_IS_BLANK ;
    r_cpu_black               <= C_DEFAULT_BLACK[C_CV_PIXEL_BITS-1:0];
    r_cpu_allow_hv_reset      <= C_DEFAULT_ENABLE_FRAME_LOCK;
    r_cpu_use_soft_reset      <= C_DEFAULT_ENABLE_SOFT_LOCK;
    r_cpu_vrr                 <= C_DEFAULT_ENABLE_VARIABLE_REFRESH_RATE;
    r_cpu_vrr_linemode        <= C_DEFAULT_ENABLE_VRR_LINEMODE;
    r_cpu_frame_start_jitter  <= C_DEFAULT_FRAME_START_MAX_JITTER;
    r_cpu_frame_adj_ignore    <= C_DEFAULT_FRAME_ADJ_IGNORE_LINES;
    r_cpu_frame_adj_window    <= C_DEFAULT_FRAME_ADJ_WINDOW_LINES;
    
    r_cpu_tim_hreset          <= C_TIM_HRESET           ;
    r_cpu_tim_vreset          <= C_TIM_VRESET           ;

    r_cpu_tim_htotal          <= C_TIM_HTOTAL           ; 
    r_cpu_tim_vtotal          <= C_TIM_VTOTAL           ; 
    r_cpu_tim_hb_end          <= C_TIM_HB_END           ; 
    r_cpu_tim_v1b_start       <= C_TIM_V1B_START        ; 
    r_cpu_tim_v1b_end         <= C_TIM_V1B_END          ; 
    r_cpu_tim_v2b_start       <= C_TIM_V2B_START        ; 
    r_cpu_tim_v2b_end         <= C_TIM_V2B_END          ; 
    r_cpu_tim_f1_start        <= C_TIM_F1_START         ; 
    r_cpu_tim_f2_start        <= C_TIM_F2_START         ; 
    r_cpu_tim_hs_start        <= C_TIM_HS_START         ; 
    r_cpu_tim_hs_end          <= C_TIM_HS_END           ; 
    r_cpu_tim_v1s_vstart      <= C_TIM_V1S_VSTART       ; 
    r_cpu_tim_v1s_hstart      <= C_TIM_V1S_HSTART       ; 
    r_cpu_tim_v1s_vend        <= C_TIM_V1S_VEND         ; 
    r_cpu_tim_v1s_hend        <= C_TIM_V1S_HEND         ; 
    r_cpu_tim_v2s_vstart      <= C_TIM_V2S_VSTART       ; 
    r_cpu_tim_v2s_hstart      <= C_TIM_V2S_HSTART       ; 
    r_cpu_tim_v2s_vend        <= C_TIM_V2S_VEND         ; 
    r_cpu_tim_v2s_hend        <= C_TIM_V2S_HEND         ; 
    
    r_cpu_tim_pulse0_vstart   <= C_TIM_PULSE0_VSTART    ; 
    r_cpu_tim_pulse0_hstart   <= C_TIM_PULSE0_HSTART    ; 
    r_cpu_tim_pulse0_vend     <= C_TIM_PULSE0_VEND      ; 
    r_cpu_tim_pulse0_hend     <= C_TIM_PULSE0_HEND      ; 
    r_cpu_tim_pulse1_vstart   <= C_TIM_PULSE1_VSTART    ; 
    r_cpu_tim_pulse1_hstart   <= C_TIM_PULSE1_HSTART    ; 
    r_cpu_tim_pulse1_vend     <= C_TIM_PULSE1_VEND      ; 
    r_cpu_tim_pulse1_hend     <= C_TIM_PULSE1_HEND      ; 
    r_cpu_tim_pulse2_vstart   <= C_TIM_PULSE2_VSTART    ; 
    r_cpu_tim_pulse2_hstart   <= C_TIM_PULSE2_HSTART    ; 
    r_cpu_tim_pulse2_vend     <= C_TIM_PULSE2_VEND      ; 
    r_cpu_tim_pulse2_hend     <= C_TIM_PULSE2_HEND      ; 
    r_cpu_tim_pulse3_vstart   <= C_TIM_PULSE3_VSTART    ; 
    r_cpu_tim_pulse3_hstart   <= C_TIM_PULSE3_HSTART    ; 
    r_cpu_tim_pulse3_vend     <= C_TIM_PULSE3_VEND      ; 
    r_cpu_tim_pulse3_hend     <= C_TIM_PULSE3_HEND      ; 
    r_cpu_tim_pulse4_vstart   <= C_TIM_PULSE4_VSTART    ; 
    r_cpu_tim_pulse4_hstart   <= C_TIM_PULSE4_HSTART    ; 
    r_cpu_tim_pulse4_vend     <= C_TIM_PULSE4_VEND      ; 
    r_cpu_tim_pulse4_hend     <= C_TIM_PULSE4_HEND      ; 
    r_cpu_tim_pulse5_vstart   <= C_TIM_PULSE5_VSTART    ; 
    r_cpu_tim_pulse5_hstart   <= C_TIM_PULSE5_HSTART    ; 
    r_cpu_tim_pulse5_vend     <= C_TIM_PULSE5_VEND      ; 
    r_cpu_tim_pulse5_hend     <= C_TIM_PULSE5_HEND      ; 
    r_cpu_tim_pulse6_vstart   <= C_TIM_PULSE6_VSTART    ; 
    r_cpu_tim_pulse6_hstart   <= C_TIM_PULSE6_HSTART    ; 
    r_cpu_tim_pulse6_vend     <= C_TIM_PULSE6_VEND      ; 
    r_cpu_tim_pulse6_hend     <= C_TIM_PULSE6_HEND      ; 
    r_cpu_tim_pulse7_vstart   <= C_TIM_PULSE7_VSTART    ; 
    r_cpu_tim_pulse7_hstart   <= C_TIM_PULSE7_HSTART    ; 
    r_cpu_tim_pulse7_vend     <= C_TIM_PULSE7_VEND      ; 
    r_cpu_tim_pulse7_hend     <= C_TIM_PULSE7_HEND      ; 
    
    // cpu sigs
    av_waitrequest            <= 1'b1;
    av_readdata               <= 32'b0;
    av_readdatavalid          <= 1'b0;
  end
  else
  begin
    av_waitrequest            <= 1'b0;
    r_cpu_update_timing       <= 1'b0;
    r2_cpu_update_timing      <= r_cpu_update_timing;
    
    if (!r_cpu_update_timing && r2_cpu_update_timing)
    begin
      r_cpu_update_timing_toggle  <= ~r_cpu_update_timing_toggle;
    end
    
    if (C_USE_CPU)
    begin
      av_readdatavalid    <= r_av_read;
      av_readdata         <= 32'b0;
      nb_local_reg32     = 32'b0;
      case (r_av_address)
        C_REG_STATUS        : begin
                                av_readdata               <= nb_local_reg32;
                              end
        C_REG_COMMIT        : begin
                                nb_local_reg32[1]        = r_cpu_vid_clk_running;
                                nb_local_reg32[2]        = r_cpu_update_timing_request;
                                av_readdata               <= nb_local_reg32;
                                t_cpu_write(r_av_write , r_av_byteenable , r_av_writedata , nb_local_reg32);
                                r_cpu_update_timing     <= nb_local_reg32[0] & r_av_write;
                              end
        C_REG_MODE          : begin
                                nb_local_reg32[0]        = r_cpu_frame_start_pulse;
                                nb_local_reg32[1]        = r_cpu_out_is_blank;     
                                nb_local_reg32[2]        = r_cpu_allow_hv_reset;   
                                nb_local_reg32[3]        = r_cpu_use_soft_reset;
                                nb_local_reg32[4]        = r_cpu_vrr;              
                                nb_local_reg32[5]        = r_cpu_vrr_linemode;     
                                av_readdata               <= nb_local_reg32;
                                t_cpu_write(r_av_write , r_av_byteenable , r_av_writedata , nb_local_reg32);
                                r_cpu_frame_start_pulse <= nb_local_reg32[0];
                                r_cpu_out_is_blank      <= nb_local_reg32[1];
                                r_cpu_allow_hv_reset    <= nb_local_reg32[2];
                                r_cpu_use_soft_reset    <= nb_local_reg32[3] && (C_BUILD_SOFT_FRAME_LOCK == 1);
                                r_cpu_vrr               <= nb_local_reg32[4] && (C_BUILD_VRR == 1);
                                r_cpu_vrr_linemode      <= nb_local_reg32[5] && (C_BUILD_VRR == 1);
                              end
        C_REG_RESET_POS     : begin
                                nb_local_reg32[0 +: C_HSIZE] = r_cpu_tim_hreset;
                                nb_local_reg32[16+: C_VSIZE] = r_cpu_tim_vreset;
                                av_readdata               <= nb_local_reg32;
                                t_cpu_write(r_av_write , r_av_byteenable , r_av_writedata , nb_local_reg32);
                                r_cpu_tim_hreset  <= nb_local_reg32[0 +: C_HSIZE];
                                r_cpu_tim_vreset  <= nb_local_reg32[16+: C_VSIZE];
                              end
        C_REG_TOTALS        : begin
                                nb_local_reg32[0 +: C_HSIZE] = r_cpu_tim_htotal;
                                nb_local_reg32[16+: C_VSIZE] = r_cpu_tim_vtotal;
                                av_readdata               <= nb_local_reg32;
                                t_cpu_write(r_av_write , r_av_byteenable , r_av_writedata , nb_local_reg32);
                                r_cpu_tim_htotal  <= nb_local_reg32[0 +: C_HSIZE];
                                r_cpu_tim_vtotal  <= nb_local_reg32[16+: C_VSIZE];
                              end
        C_REG_HB_END        : begin
                                nb_local_reg32[0 +: C_HSIZE] = r_cpu_tim_hb_end;
                                av_readdata               <= nb_local_reg32;
                                t_cpu_write(r_av_write , r_av_byteenable , r_av_writedata , nb_local_reg32);
                                r_cpu_tim_hb_end  <= nb_local_reg32[0 +: C_HSIZE];
                              end
        C_REG_V1B_POS       : begin
                                nb_local_reg32[0 +: C_VSIZE] = r_cpu_tim_v1b_start;
                                nb_local_reg32[16+: C_VSIZE] = r_cpu_tim_v1b_end;
                                av_readdata               <= nb_local_reg32;
                                t_cpu_write(r_av_write , r_av_byteenable , r_av_writedata , nb_local_reg32);
                                r_cpu_tim_v1b_start <= nb_local_reg32[0 +: C_VSIZE];
                                r_cpu_tim_v1b_end   <= nb_local_reg32[16+: C_VSIZE];
                              end
        C_REG_V2B_POS       : begin
                                nb_local_reg32[0 +: C_VSIZE] = r_cpu_tim_v2b_start;
                                nb_local_reg32[16+: C_VSIZE] = r_cpu_tim_v2b_end;
                                av_readdata               <= nb_local_reg32;
                                t_cpu_write(r_av_write , r_av_byteenable , r_av_writedata , nb_local_reg32);
                                r_cpu_tim_v2b_start <= nb_local_reg32[0 +: C_VSIZE];
                                r_cpu_tim_v2b_end   <= nb_local_reg32[16+: C_VSIZE];
                              end
        C_REG_FIELD_STARTS  : begin
                                nb_local_reg32[0 +: C_VSIZE] = r_cpu_tim_f1_start;
                                nb_local_reg32[16+: C_VSIZE] = r_cpu_tim_f2_start;
                                av_readdata               <= nb_local_reg32;
                                t_cpu_write(r_av_write , r_av_byteenable , r_av_writedata , nb_local_reg32);
                                r_cpu_tim_f1_start  <= nb_local_reg32[0 +: C_VSIZE];
                                r_cpu_tim_f2_start  <= nb_local_reg32[16+: C_VSIZE];
                              end
        C_REG_HS_POS        : begin
                                nb_local_reg32[0 +: C_HSIZE] = r_cpu_tim_hs_start;
                                nb_local_reg32[16+: C_HSIZE] = r_cpu_tim_hs_end;
                                av_readdata               <= nb_local_reg32;
                                t_cpu_write(r_av_write , r_av_byteenable , r_av_writedata , nb_local_reg32);
                                r_cpu_tim_hs_start  <= nb_local_reg32[0 +: C_HSIZE];
                                r_cpu_tim_hs_end    <= nb_local_reg32[16+: C_HSIZE];
                              end
        C_REG_V1S_START     : begin
                                nb_local_reg32[0 +: C_HSIZE] = r_cpu_tim_v1s_hstart;
                                nb_local_reg32[16+: C_VSIZE] = r_cpu_tim_v1s_vstart;
                                av_readdata               <= nb_local_reg32;
                                t_cpu_write(r_av_write , r_av_byteenable , r_av_writedata , nb_local_reg32);
                                r_cpu_tim_v1s_hstart    <= nb_local_reg32[0 +: C_HSIZE];
                                r_cpu_tim_v1s_vstart    <= nb_local_reg32[16+: C_VSIZE];
                              end
        C_REG_V1S_END       : begin
                                nb_local_reg32[0 +: C_HSIZE] = r_cpu_tim_v1s_hend;
                                nb_local_reg32[16+: C_VSIZE] = r_cpu_tim_v1s_vend;
                                av_readdata               <= nb_local_reg32;
                                t_cpu_write(r_av_write , r_av_byteenable , r_av_writedata , nb_local_reg32);
                                r_cpu_tim_v1s_hend    <= nb_local_reg32[0 +: C_HSIZE];
                                r_cpu_tim_v1s_vend    <= nb_local_reg32[16+: C_VSIZE];
                              end
        C_REG_V2S_START     : begin
                                nb_local_reg32[0 +: C_HSIZE] = r_cpu_tim_v2s_hstart;
                                nb_local_reg32[16+: C_VSIZE] = r_cpu_tim_v2s_vstart;
                                av_readdata               <= nb_local_reg32;
                                t_cpu_write(r_av_write , r_av_byteenable , r_av_writedata , nb_local_reg32);
                                r_cpu_tim_v2s_hstart    <= nb_local_reg32[0 +: C_HSIZE];
                                r_cpu_tim_v2s_vstart    <= nb_local_reg32[16+: C_VSIZE];
                              end
        C_REG_V2S_END       : begin
                                nb_local_reg32[0 +: C_HSIZE] = r_cpu_tim_v2s_hend;
                                nb_local_reg32[16+: C_VSIZE] = r_cpu_tim_v2s_vend;
                                av_readdata               <= nb_local_reg32;
                                t_cpu_write(r_av_write , r_av_byteenable , r_av_writedata , nb_local_reg32);
                                r_cpu_tim_v2s_hend    <= nb_local_reg32[0 +: C_HSIZE];
                                r_cpu_tim_v2s_vend    <= nb_local_reg32[16+: C_VSIZE];
                              end
        C_REG_JITTER_CONT   : begin
                                nb_local_reg32[ 7: 0] = r_cpu_frame_start_jitter;
                                nb_local_reg32[15: 8] = r_cpu_frame_adj_ignore;
                                nb_local_reg32[23:16] = r_cpu_frame_adj_window;
                                av_readdata               <= nb_local_reg32;
                                t_cpu_write(r_av_write , r_av_byteenable , r_av_writedata , nb_local_reg32);
                                r_cpu_frame_start_jitter  <= nb_local_reg32[ 7: 0];
                                r_cpu_frame_adj_ignore    <= nb_local_reg32[15: 8];
                                r_cpu_frame_adj_window    <= nb_local_reg32[23:16];
                              end
        C_REG_BLACK_0       : begin
                                nb_local_reg32[C_CV_BIT_DEPTH-1:0] = r_cpu_black[C_CV_BIT_DEPTH*0+:C_CV_BIT_DEPTH];
                                av_readdata            <= nb_local_reg32;
                                t_cpu_write(r_av_write , r_av_byteenable , r_av_writedata , nb_local_reg32);
                                r_cpu_black[C_CV_BIT_DEPTH*0+:C_CV_BIT_DEPTH] <= nb_local_reg32[C_CV_BIT_DEPTH-1:0];
                              end
        C_REG_BLACK_1       : begin
                                if (C_CV_NUM_PLANES > 1) begin
                                  nb_local_reg32[C_CV_BIT_DEPTH-1:0] = r_cpu_black[C_CV_BIT_DEPTH*1+:C_CV_BIT_DEPTH];
                                  av_readdata            <= nb_local_reg32;
                                  t_cpu_write(r_av_write , r_av_byteenable , r_av_writedata , nb_local_reg32);
                                  r_cpu_black[C_CV_BIT_DEPTH*1+:C_CV_BIT_DEPTH] <= nb_local_reg32[C_CV_BIT_DEPTH-1:0];
                                end
                                else begin
                                  av_readdata   <= 32'h1234_ABCD;
                                end
                              end
        C_REG_BLACK_2       : begin
                                if (C_CV_NUM_PLANES > 2) begin
                                  nb_local_reg32[C_CV_BIT_DEPTH-1:0] = r_cpu_black[C_CV_BIT_DEPTH*2+:C_CV_BIT_DEPTH];
                                  av_readdata            <= nb_local_reg32;
                                  t_cpu_write(r_av_write , r_av_byteenable , r_av_writedata , nb_local_reg32);
                                  r_cpu_black[C_CV_BIT_DEPTH*2+:C_CV_BIT_DEPTH] <= nb_local_reg32[C_CV_BIT_DEPTH-1:0];
                                end
                                else begin
                                  av_readdata   <= 32'h1234_ABCD;
                                end
                              end
        C_REG_BLACK_3       : begin
                                if (C_CV_NUM_PLANES > 3) begin
                                  nb_local_reg32[C_CV_BIT_DEPTH-1:0] = r_cpu_black[C_CV_BIT_DEPTH*3+:C_CV_BIT_DEPTH];
                                  av_readdata            <= nb_local_reg32;
                                  t_cpu_write(r_av_write , r_av_byteenable , r_av_writedata , nb_local_reg32);
                                  r_cpu_black[C_CV_BIT_DEPTH*3+:C_CV_BIT_DEPTH] <= nb_local_reg32[C_CV_BIT_DEPTH-1:0];
                                end
                                else begin
                                  av_readdata   <= 32'h1234_ABCD;
                                end
                              end
        C_REG_FRAME_COUNTS  : begin
                                nb_local_reg32[15: 0] = r_cpu_start_counter;
                                nb_local_reg32[31:16] = r_cpu_frame_count;
                                av_readdata               <= nb_local_reg32;
                              end
        C_REG_FRAME_LENGTH  : begin
                                nb_local_reg32[0 +: C_HSIZE + C_VSIZE] = r_cpu_actual_pixels_latched;
                                av_readdata               <= nb_local_reg32;
                              end
        C_REG_VTOTAL_ADJ    : begin
                                nb_local_reg32[0 +: C_VSIZE] = r_cpu_tim_vtotal_latched;
                                av_readdata               <= nb_local_reg32;
                              end
        C_REG_VID_FREQ      : begin
                                av_readdata   <= r_cpu_1_second_ltchd;
                              end
        C_REG_PULSE0_START  : begin
                                if (C_NUM_PULSES>0) 
                                begin
                                  nb_local_reg32[0 +: C_HSIZE] = r_cpu_tim_pulse0_hstart;
                                  nb_local_reg32[16+: C_VSIZE] = r_cpu_tim_pulse0_vstart;
                                  av_readdata               <= nb_local_reg32;
                                  t_cpu_write(r_av_write , r_av_byteenable , r_av_writedata , nb_local_reg32);
                                  r_cpu_tim_pulse0_hstart    <= nb_local_reg32[0 +: C_HSIZE];
                                  r_cpu_tim_pulse0_vstart    <= nb_local_reg32[16+: C_VSIZE];
                                end
                                else begin
                                  av_readdata   <= 32'h1234_ABCD;
                                end
                              end
        C_REG_PULSE0_END    : begin
                                if (C_NUM_PULSES>0) 
                                begin
                                  nb_local_reg32[0 +: C_HSIZE] = r_cpu_tim_pulse0_hend;
                                  nb_local_reg32[16+: C_VSIZE] = r_cpu_tim_pulse0_vend;
                                  av_readdata               <= nb_local_reg32;
                                  t_cpu_write(r_av_write , r_av_byteenable , r_av_writedata , nb_local_reg32);
                                  r_cpu_tim_pulse0_hend    <= nb_local_reg32[0 +: C_HSIZE];
                                  r_cpu_tim_pulse0_vend    <= nb_local_reg32[16+: C_VSIZE];
                                end
                                else begin
                                  av_readdata   <= 32'h1234_ABCD;
                                end
                              end
        C_REG_PULSE1_START  : begin
                                if (C_NUM_PULSES>1) 
                                begin
                                  nb_local_reg32[0 +: C_HSIZE] = r_cpu_tim_pulse1_hstart;
                                  nb_local_reg32[16+: C_VSIZE] = r_cpu_tim_pulse1_vstart;
                                  av_readdata               <= nb_local_reg32;
                                  t_cpu_write(r_av_write , r_av_byteenable , r_av_writedata , nb_local_reg32);
                                  r_cpu_tim_pulse1_hstart    <= nb_local_reg32[0 +: C_HSIZE];
                                  r_cpu_tim_pulse1_vstart    <= nb_local_reg32[16+: C_VSIZE];
                                end
                                else begin
                                  av_readdata   <= 32'h1234_ABCD;
                                end
                              end
        C_REG_PULSE1_END    : begin
                                if (C_NUM_PULSES>1) 
                                begin
                                  nb_local_reg32[0 +: C_HSIZE] = r_cpu_tim_pulse1_hend;
                                  nb_local_reg32[16+: C_VSIZE] = r_cpu_tim_pulse1_vend;
                                  av_readdata               <= nb_local_reg32;
                                  t_cpu_write(r_av_write , r_av_byteenable , r_av_writedata , nb_local_reg32);
                                  r_cpu_tim_pulse1_hend    <= nb_local_reg32[0 +: C_HSIZE];
                                  r_cpu_tim_pulse1_vend    <= nb_local_reg32[16+: C_VSIZE];
                                end
                                else begin
                                  av_readdata   <= 32'h1234_ABCD;
                                end
                              end
        C_REG_PULSE2_START  : begin
                                if (C_NUM_PULSES>2)
                                begin
                                  nb_local_reg32[0 +: C_HSIZE] = r_cpu_tim_pulse2_hstart;
                                  nb_local_reg32[16+: C_VSIZE] = r_cpu_tim_pulse2_vstart;
                                  av_readdata               <= nb_local_reg32;
                                  t_cpu_write(r_av_write , r_av_byteenable , r_av_writedata , nb_local_reg32);
                                  r_cpu_tim_pulse2_hstart    <= nb_local_reg32[0 +: C_HSIZE];
                                  r_cpu_tim_pulse2_vstart    <= nb_local_reg32[16+: C_VSIZE];
                                end
                                else begin
                                  av_readdata   <= 32'h1234_ABCD;
                                end
                              end
        C_REG_PULSE2_END    : begin
                                if (C_NUM_PULSES>2)
                                begin
                                  nb_local_reg32[0 +: C_HSIZE] = r_cpu_tim_pulse2_hend;
                                  nb_local_reg32[16+: C_VSIZE] = r_cpu_tim_pulse2_vend;
                                  av_readdata               <= nb_local_reg32;
                                  t_cpu_write(r_av_write , r_av_byteenable , r_av_writedata , nb_local_reg32);
                                  r_cpu_tim_pulse2_hend    <= nb_local_reg32[0 +: C_HSIZE];
                                  r_cpu_tim_pulse2_vend    <= nb_local_reg32[16+: C_VSIZE];
                                end
                                else begin
                                  av_readdata   <= 32'h1234_ABCD;
                                end
                              end
        C_REG_PULSE3_START  : begin
                                if (C_NUM_PULSES>3) 
                                begin
                                  nb_local_reg32[0 +: C_HSIZE] = r_cpu_tim_pulse3_hstart;
                                  nb_local_reg32[16+: C_VSIZE] = r_cpu_tim_pulse3_vstart;
                                  av_readdata               <= nb_local_reg32;
                                  t_cpu_write(r_av_write , r_av_byteenable , r_av_writedata , nb_local_reg32);
                                  r_cpu_tim_pulse3_hstart    <= nb_local_reg32[0 +: C_HSIZE];
                                  r_cpu_tim_pulse3_vstart    <= nb_local_reg32[16+: C_VSIZE];
                                end
                                else begin
                                  av_readdata   <= 32'h1234_ABCD;
                                end
                              end
        C_REG_PULSE3_END    : begin
                                if (C_NUM_PULSES>3) 
                                begin
                                  nb_local_reg32[0 +: C_HSIZE] = r_cpu_tim_pulse3_hend;
                                  nb_local_reg32[16+: C_VSIZE] = r_cpu_tim_pulse3_vend;
                                  av_readdata               <= nb_local_reg32;
                                  t_cpu_write(r_av_write , r_av_byteenable , r_av_writedata , nb_local_reg32);
                                  r_cpu_tim_pulse3_hend    <= nb_local_reg32[0 +: C_HSIZE];
                                  r_cpu_tim_pulse3_vend    <= nb_local_reg32[16+: C_VSIZE];
                                end
                                else begin
                                  av_readdata   <= 32'h1234_ABCD;
                                end
                              end
        C_REG_PULSE4_START  : begin
                                if (C_NUM_PULSES>4) 
                                begin
                                  nb_local_reg32[0 +: C_HSIZE] = r_cpu_tim_pulse4_hstart;
                                  nb_local_reg32[16+: C_VSIZE] = r_cpu_tim_pulse4_vstart;
                                  av_readdata               <= nb_local_reg32;
                                  t_cpu_write(r_av_write , r_av_byteenable , r_av_writedata , nb_local_reg32);
                                  r_cpu_tim_pulse4_hstart    <= nb_local_reg32[0 +: C_HSIZE];
                                  r_cpu_tim_pulse4_vstart    <= nb_local_reg32[16+: C_VSIZE];
                                end
                                else begin
                                  av_readdata   <= 32'h1234_ABCD;
                                end
                              end
        C_REG_PULSE4_END    : begin
                                if (C_NUM_PULSES>4) 
                                begin
                                  nb_local_reg32[0 +: C_HSIZE] = r_cpu_tim_pulse4_hend;
                                  nb_local_reg32[16+: C_VSIZE] = r_cpu_tim_pulse4_vend;
                                  av_readdata               <= nb_local_reg32;
                                  t_cpu_write(r_av_write , r_av_byteenable , r_av_writedata , nb_local_reg32);
                                  r_cpu_tim_pulse4_hend    <= nb_local_reg32[0 +: C_HSIZE];
                                  r_cpu_tim_pulse4_vend    <= nb_local_reg32[16+: C_VSIZE];
                                end
                                else begin
                                  av_readdata   <= 32'h1234_ABCD;
                                end
                              end
        C_REG_PULSE5_START  : begin
                                if (C_NUM_PULSES>5) 
                                begin
                                  nb_local_reg32[0 +: C_HSIZE] = r_cpu_tim_pulse5_hstart;
                                  nb_local_reg32[16+: C_VSIZE] = r_cpu_tim_pulse5_vstart;
                                  av_readdata               <= nb_local_reg32;
                                  t_cpu_write(r_av_write , r_av_byteenable , r_av_writedata , nb_local_reg32);
                                  r_cpu_tim_pulse5_hstart    <= nb_local_reg32[0 +: C_HSIZE];
                                  r_cpu_tim_pulse5_vstart    <= nb_local_reg32[16+: C_VSIZE];
                                end
                                else begin
                                  av_readdata   <= 32'h1234_ABCD;
                                end
                              end
        C_REG_PULSE5_END    : begin
                                if (C_NUM_PULSES>5) 
                                begin
                                  nb_local_reg32[0 +: C_HSIZE] = r_cpu_tim_pulse5_hend;
                                  nb_local_reg32[16+: C_VSIZE] = r_cpu_tim_pulse5_vend;
                                  av_readdata               <= nb_local_reg32;
                                  t_cpu_write(r_av_write , r_av_byteenable , r_av_writedata , nb_local_reg32);
                                  r_cpu_tim_pulse5_hend    <= nb_local_reg32[0 +: C_HSIZE];
                                  r_cpu_tim_pulse5_vend    <= nb_local_reg32[16+: C_VSIZE];
                                end
                                else begin
                                  av_readdata   <= 32'h1234_ABCD;
                                end
                              end
        C_REG_PULSE6_START  : begin
                                if (C_NUM_PULSES>6) 
                                begin
                                  nb_local_reg32[0 +: C_HSIZE] = r_cpu_tim_pulse6_hstart;
                                  nb_local_reg32[16+: C_VSIZE] = r_cpu_tim_pulse6_vstart;
                                  av_readdata               <= nb_local_reg32;
                                  t_cpu_write(r_av_write , r_av_byteenable , r_av_writedata , nb_local_reg32);
                                  r_cpu_tim_pulse6_hstart    <= nb_local_reg32[0 +: C_HSIZE];
                                  r_cpu_tim_pulse6_vstart    <= nb_local_reg32[16+: C_VSIZE];
                                end
                                else begin
                                  av_readdata   <= 32'h1234_ABCD;
                                end
                              end
        C_REG_PULSE6_END    : begin
                                if (C_NUM_PULSES>6) 
                                begin
                                  nb_local_reg32[0 +: C_HSIZE] = r_cpu_tim_pulse6_hend;
                                  nb_local_reg32[16+: C_VSIZE] = r_cpu_tim_pulse6_vend;
                                  av_readdata               <= nb_local_reg32;
                                  t_cpu_write(r_av_write , r_av_byteenable , r_av_writedata , nb_local_reg32);
                                  r_cpu_tim_pulse6_hend    <= nb_local_reg32[0 +: C_HSIZE];
                                  r_cpu_tim_pulse6_vend    <= nb_local_reg32[16+: C_VSIZE];
                                end
                                else begin
                                  av_readdata   <= 32'h1234_ABCD;
                                end
                              end
        C_REG_PULSE7_START  : begin
                                if (C_NUM_PULSES>7) 
                                begin
                                  nb_local_reg32[0 +: C_HSIZE] = r_cpu_tim_pulse7_hstart;
                                  nb_local_reg32[16+: C_VSIZE] = r_cpu_tim_pulse7_vstart;
                                  av_readdata               <= nb_local_reg32;
                                  t_cpu_write(r_av_write , r_av_byteenable , r_av_writedata , nb_local_reg32);
                                  r_cpu_tim_pulse7_hstart    <= nb_local_reg32[0 +: C_HSIZE];
                                  r_cpu_tim_pulse7_vstart    <= nb_local_reg32[16+: C_VSIZE];
                                end
                                else begin
                                  av_readdata   <= 32'h1234_ABCD;
                                end
                              end
        C_REG_PULSE7_END    : begin
                                if (C_NUM_PULSES>7) 
                                begin
                                  nb_local_reg32[0 +: C_HSIZE] = r_cpu_tim_pulse7_hend;
                                  nb_local_reg32[16+: C_VSIZE] = r_cpu_tim_pulse7_vend;
                                  av_readdata               <= nb_local_reg32;
                                  t_cpu_write(r_av_write , r_av_byteenable , r_av_writedata , nb_local_reg32);
                                  r_cpu_tim_pulse7_hend    <= nb_local_reg32[0 +: C_HSIZE];
                                  r_cpu_tim_pulse7_vend    <= nb_local_reg32[16+: C_VSIZE];
                                end
                                else begin
                                  av_readdata   <= 32'h1234_ABCD;
                                end
                              end

        C_REG_GENLOCK_STATS0: begin
                                nb_local_reg32[15: 0] = r_cpu_hv_reset_count;
                                nb_local_reg32[31:16] = r_cpu_stable_count;
                                av_readdata               <= nb_local_reg32;
                              end

        C_REG_GENLOCK_STATS1: begin
                                nb_local_reg32[15: 0] = r_cpu_inc_count;
                                nb_local_reg32[31:16] = r_cpu_dec_count;
                                av_readdata               <= nb_local_reg32;
                              end
                              
        default             : begin // Address out of range
                                av_readdata   <= 32'h1234_ABCD;
        end
      endcase
    end
  end
end

//////////////////////////////////////////////////////////////////////////////
//
// Copy CPU settings to video domain
//
logic               r_vid_update_timing_safe; 
logic               r2_vid_update_timing_safe;
logic               r_vid_update_regs;

intel_vvp_clock_crosser
#(
  .DATA_WIDTH  ( 1 ),
  .NUM_CC_REG  ( 3 ),  // 2 minimum, 3 recommended for Hyperflex
  .INPUT_REG   ( 1 )   // 1 to register the input first
) i_cdc_timing_toggle (
  .in_clk  (cpu_clk),
  .in_data (r_cpu_update_timing_toggle),
  .out_clk (vid_clk),
  .out_data(r_vid_update_timing_safe)
);
localparam C_ALL_CPU_REGS = 6 + 8*3 + C_CV_PIXEL_BITS + C_HSIZE*25 + C_VSIZE*28;
logic [C_ALL_CPU_REGS-1:0] cpu_regs_cdc_in;
logic [C_ALL_CPU_REGS-1:0] cpu_regs_cdc_out;
localparam [C_ALL_CPU_REGS-1:0] CPU_REGS_CDC_RESET = {|C_DEFAULT_FRAME_START_PULSE,
                                                      |C_DEFAULT_OUT_IS_BLANK,
                                                      C_DEFAULT_BLACK[C_CV_PIXEL_BITS-1:0],
                                                      |C_DEFAULT_ENABLE_FRAME_LOCK,
                                                      |C_DEFAULT_ENABLE_SOFT_LOCK,
                                                      |C_DEFAULT_ENABLE_VARIABLE_REFRESH_RATE,
                                                      |C_DEFAULT_ENABLE_VRR_LINEMODE,

                                                      C_DEFAULT_FRAME_START_MAX_JITTER[7:0],
                                                      C_DEFAULT_FRAME_ADJ_IGNORE_LINES[7:0],
                                                      C_DEFAULT_FRAME_ADJ_WINDOW_LINES[7:0],

                                                      C_TIM_HRESET[C_HSIZE-1:0],
                                                      C_TIM_VRESET[C_VSIZE-1:0],

                                                      C_TIM_HTOTAL[C_HSIZE-1:0],
                                                      C_TIM_VTOTAL[C_VSIZE-1:0],
                                                      C_TIM_HB_END[C_HSIZE-1:0],
                                                      C_TIM_V1B_START[C_VSIZE-1:0],
                                                      C_TIM_V1B_END[C_VSIZE-1:0],
                                                      C_TIM_V2B_START[C_VSIZE-1:0],
                                                      C_TIM_V2B_END[C_VSIZE-1:0],
                                                      C_TIM_F1_START[C_VSIZE-1:0],
                                                      C_TIM_F2_START[C_VSIZE-1:0],
                                                      C_TIM_HS_START[C_HSIZE-1:0],
                                                      C_TIM_HS_END[C_HSIZE-1:0],
                                                      C_TIM_V1S_VSTART[C_VSIZE-1:0],
                                                      C_TIM_V1S_HSTART[C_HSIZE-1:0],
                                                      C_TIM_V1S_VEND[C_VSIZE-1:0],
                                                      C_TIM_V1S_HEND[C_HSIZE-1:0],
                                                      C_TIM_V2S_VSTART[C_VSIZE-1:0],
                                                      C_TIM_V2S_HSTART[C_HSIZE-1:0],
                                                      C_TIM_V2S_VEND[C_VSIZE-1:0],
                                                      C_TIM_V2S_HEND[C_HSIZE-1:0],

                                                      C_TIM_PULSE0_VSTART[C_VSIZE-1:0],
                                                      C_TIM_PULSE0_HSTART[C_HSIZE-1:0],
                                                      C_TIM_PULSE0_VEND[C_VSIZE-1:0],
                                                      C_TIM_PULSE0_HEND[C_HSIZE-1:0],
                                                      C_TIM_PULSE1_VSTART[C_VSIZE-1:0],
                                                      C_TIM_PULSE1_HSTART[C_HSIZE-1:0],
                                                      C_TIM_PULSE1_VEND[C_VSIZE-1:0],
                                                      C_TIM_PULSE1_HEND[C_HSIZE-1:0],
                                                      C_TIM_PULSE2_VSTART[C_VSIZE-1:0],
                                                      C_TIM_PULSE2_HSTART[C_HSIZE-1:0],
                                                      C_TIM_PULSE2_VEND[C_VSIZE-1:0],
                                                      C_TIM_PULSE2_HEND[C_HSIZE-1:0],
                                                      C_TIM_PULSE3_VSTART[C_VSIZE-1:0],
                                                      C_TIM_PULSE3_HSTART[C_HSIZE-1:0],
                                                      C_TIM_PULSE3_VEND[C_VSIZE-1:0],
                                                      C_TIM_PULSE3_HEND[C_HSIZE-1:0],
                                                      C_TIM_PULSE4_VSTART[C_VSIZE-1:0],
                                                      C_TIM_PULSE4_HSTART[C_HSIZE-1:0],
                                                      C_TIM_PULSE4_VEND[C_VSIZE-1:0],
                                                      C_TIM_PULSE4_HEND[C_HSIZE-1:0],
                                                      C_TIM_PULSE5_VSTART[C_VSIZE-1:0],
                                                      C_TIM_PULSE5_HSTART[C_HSIZE-1:0],
                                                      C_TIM_PULSE5_VEND[C_VSIZE-1:0],
                                                      C_TIM_PULSE5_HEND[C_HSIZE-1:0],
                                                      C_TIM_PULSE6_VSTART[C_VSIZE-1:0],
                                                      C_TIM_PULSE6_HSTART[C_HSIZE-1:0],
                                                      C_TIM_PULSE6_VEND[C_VSIZE-1:0],
                                                      C_TIM_PULSE6_HEND[C_HSIZE-1:0],
                                                      C_TIM_PULSE7_VSTART[C_VSIZE-1:0],
                                                      C_TIM_PULSE7_HSTART[C_HSIZE-1:0],
                                                      C_TIM_PULSE7_VEND[C_VSIZE-1:0],
                                                      C_TIM_PULSE7_HEND[C_HSIZE-1:0]};
                                                      
// Free-running register to facilitate timing closure
always_ff @(posedge cpu_clk) 
begin
  cpu_regs_cdc_in <= {r_cpu_frame_start_pulse    ,
                            r_cpu_out_is_blank         ,
                            r_cpu_black                ,
                            r_cpu_allow_hv_reset       ,
                            r_cpu_use_soft_reset       ,
                            r_cpu_vrr                  ,
                            r_cpu_vrr_linemode         ,

                            r_cpu_frame_start_jitter   ,
                            r_cpu_frame_adj_ignore     ,
                            r_cpu_frame_adj_window     ,

                            r_cpu_tim_hreset           ,
                            r_cpu_tim_vreset           ,

                            r_cpu_tim_htotal           ,
                            r_cpu_tim_vtotal           ,
                            r_cpu_tim_hb_end           ,
                            r_cpu_tim_v1b_start        ,
                            r_cpu_tim_v1b_end          ,
                            r_cpu_tim_v2b_start        ,
                            r_cpu_tim_v2b_end          ,
                            r_cpu_tim_f1_start         ,
                            r_cpu_tim_f2_start         ,
                            r_cpu_tim_hs_start         ,
                            r_cpu_tim_hs_end           ,
                            r_cpu_tim_v1s_vstart       ,
                            r_cpu_tim_v1s_hstart       ,
                            r_cpu_tim_v1s_vend         ,
                            r_cpu_tim_v1s_hend         ,
                            r_cpu_tim_v2s_vstart       ,
                            r_cpu_tim_v2s_hstart       ,
                            r_cpu_tim_v2s_vend         ,
                            r_cpu_tim_v2s_hend         ,

                            r_cpu_tim_pulse0_vstart    ,
                            r_cpu_tim_pulse0_hstart    ,
                            r_cpu_tim_pulse0_vend      ,
                            r_cpu_tim_pulse0_hend      ,
                            r_cpu_tim_pulse1_vstart    ,
                            r_cpu_tim_pulse1_hstart    ,
                            r_cpu_tim_pulse1_vend      ,
                            r_cpu_tim_pulse1_hend      ,
                            r_cpu_tim_pulse2_vstart    ,
                            r_cpu_tim_pulse2_hstart    ,
                            r_cpu_tim_pulse2_vend      ,
                            r_cpu_tim_pulse2_hend      ,
                            r_cpu_tim_pulse3_vstart    ,
                            r_cpu_tim_pulse3_hstart    ,
                            r_cpu_tim_pulse3_vend      ,
                            r_cpu_tim_pulse3_hend      ,
                            r_cpu_tim_pulse4_vstart    ,
                            r_cpu_tim_pulse4_hstart    ,
                            r_cpu_tim_pulse4_vend      ,
                            r_cpu_tim_pulse4_hend      ,
                            r_cpu_tim_pulse5_vstart    ,
                            r_cpu_tim_pulse5_hstart    ,
                            r_cpu_tim_pulse5_vend      ,
                            r_cpu_tim_pulse5_hend      ,
                            r_cpu_tim_pulse6_vstart    ,
                            r_cpu_tim_pulse6_hstart    ,
                            r_cpu_tim_pulse6_vend      ,
                            r_cpu_tim_pulse6_hend      ,
                            r_cpu_tim_pulse7_vstart    ,
                            r_cpu_tim_pulse7_hstart    ,
                            r_cpu_tim_pulse7_vend      ,
                            r_cpu_tim_pulse7_hend
                          };
end                          

if (C_USE_CPU == 1)
  intel_vvp_flop_enable_reset_primitive
  #(
    .WIDTH        ( C_ALL_CPU_REGS     ),  
    .INIT_VALUE   ( CPU_REGS_CDC_RESET )

  ) i_cpu_reg_cdc
  (
    .clk    ( vid_clk ),
    .rst    ( 1'b0    ), // can't use reset because Quartus merges it into the logic in the middle of the CDC!

    .in_data   ( cpu_regs_cdc_in  ),
    .out_data  ( cpu_regs_cdc_out ),

    .in_enable ( r_vid_update_regs)

  );
else if (C_USE_CPU == 0)
  assign cpu_regs_cdc_out = CPU_REGS_CDC_RESET;


assign {r_vid_frame_start_pulse ,         
        r_vid_out_is_blank      ,
        r_vid_black             ,
        r_vid_allow_hv_reset    ,
        r_vid_use_soft_reset    ,
        r_vid_vrr               ,
        r_vid_vrr_linemode      ,

        r_vid_frame_start_jitter,
        r_vid_frame_adj_ignore  ,
        r_vid_frame_adj_window  ,

        r_vid_tim_hreset        ,
        r_vid_tim_vreset        ,

        r_vid_tim_htotal        ,
        r_vid_tim_vtotal        ,
        r_vid_tim_hb_end        ,
        r_vid_tim_v1b_start     ,
        r_vid_tim_v1b_end       ,
        r_vid_tim_v2b_start     ,
        r_vid_tim_v2b_end       ,
        r_vid_tim_f1_start      ,
        r_vid_tim_f2_start      ,
        r_vid_tim_hs_start      ,
        r_vid_tim_hs_end        ,
        r_vid_tim_v1s_vstart    ,
        r_vid_tim_v1s_hstart    ,
        r_vid_tim_v1s_vend      ,
        r_vid_tim_v1s_hend      ,
        r_vid_tim_v2s_vstart    ,
        r_vid_tim_v2s_hstart    ,
        r_vid_tim_v2s_vend      ,
        r_vid_tim_v2s_hend      ,

        r_vid_tim_pulse0_vstart ,
        r_vid_tim_pulse0_hstart ,
        r_vid_tim_pulse0_vend   ,
        r_vid_tim_pulse0_hend   ,
        r_vid_tim_pulse1_vstart ,
        r_vid_tim_pulse1_hstart ,
        r_vid_tim_pulse1_vend   ,
        r_vid_tim_pulse1_hend   ,
        r_vid_tim_pulse2_vstart ,
        r_vid_tim_pulse2_hstart ,
        r_vid_tim_pulse2_vend   ,
        r_vid_tim_pulse2_hend   ,
        r_vid_tim_pulse3_vstart ,
        r_vid_tim_pulse3_hstart ,
        r_vid_tim_pulse3_vend   ,
        r_vid_tim_pulse3_hend   ,
        r_vid_tim_pulse4_vstart ,
        r_vid_tim_pulse4_hstart ,
        r_vid_tim_pulse4_vend   ,
        r_vid_tim_pulse4_hend   ,
        r_vid_tim_pulse5_vstart ,
        r_vid_tim_pulse5_hstart ,
        r_vid_tim_pulse5_vend   ,
        r_vid_tim_pulse5_hend   ,
        r_vid_tim_pulse6_vstart ,
        r_vid_tim_pulse6_hstart ,
        r_vid_tim_pulse6_vend   ,
        r_vid_tim_pulse6_hend   ,
        r_vid_tim_pulse7_vstart ,
        r_vid_tim_pulse7_hstart ,
        r_vid_tim_pulse7_vend   ,
        r_vid_tim_pulse7_hend    } = cpu_regs_cdc_out;


always_ff @(posedge vid_clk)
begin
  if (vid_rst)
  begin
    r_vid_update_timing_request <= 1'b1;
    r2_vid_update_timing_safe   <= 1'b0;
  end
  else
  begin
    r2_vid_update_timing_safe <= r_vid_update_timing_safe;

    if (r2_vid_update_timing_safe ^ r_vid_update_timing_safe) 
      r_vid_update_timing_request  <= 1'b1;
    else if (r_pixel_00)
      r_vid_update_timing_request  <= 1'b0;
      
  end

end

assign r_vid_update_regs = r_vid_update_timing_request && r_pixel_00;

//////////////////////////////////////////////////////////////////////////
//
// Calculate video clock freq
//
logic [31:0] r_cpu_1_second_cnt;
logic        r_cpu_1_second_tgl;
logic [31:0] r_vid_1_second_ltchd;
logic [31:0] r_cpu_1_second_ltchd_safe;

logic r1_cpu_1_second_tgl;
logic r2_cpu_1_second_xor;
logic [31:0] r_vid_1_second_ltchd_shadow;

always_ff @(posedge cpu_clk)
begin:a_make_1second
  if (cpu_rst)
  begin
    r_cpu_1_second_cnt  <= 32'b001;
    r_cpu_1_second_tgl  <= 1'b0;
  end
  else
  begin
    r_cpu_1_second_cnt  <= r_cpu_1_second_cnt + 1'b1;
    if (r_cpu_1_second_cnt == C_CPU_CLK_FREQ_HZ)
    begin
      r_cpu_1_second_cnt    <= 32'b001;
      r_cpu_1_second_ltchd  <= r_cpu_1_second_ltchd_safe;
      r_cpu_1_second_tgl    <= ~r_cpu_1_second_tgl;
    end
  end
end

logic r_vid_1_second_tgl_safe;
logic r1_vid_1_second_tgl;
logic r2_vid_1_second_tgl;
logic r_vid_1_second_tgl;
logic r_cpu_1_second_tgl_safe;
logic r_vid_1_second_tgl_reg;
logic vid_1_second_tgl_xor;
logic [31:0] r_vid_1_second_cnt;
 
intel_vvp_clock_crosser
#(
  .DATA_WIDTH  ( 1 ),
  .NUM_CC_REG  ( 3 ),  // 2 minimum, 3 recommended for Hyperflex
  .INPUT_REG   ( 1 )   // 1 to register the input first
) i_cdc_1_second (
  .in_clk  (cpu_clk),
  .in_data (r_cpu_1_second_tgl),
  .out_clk (vid_clk),
  .out_data(r_vid_1_second_tgl_safe)
);


always_ff @(posedge vid_clk)
begin:a_count_vid_clks
  if (vid_rst)
  begin
    r_vid_1_second_cnt      <= 32'b001;
    r_vid_1_second_ltchd    <= 32'b001;
    r1_vid_1_second_tgl     <= 1'b0;
    r2_vid_1_second_tgl     <= 1'b0;
    r_vid_1_second_tgl      <= 1'b0;
  end
  else
  begin
    r1_vid_1_second_tgl     <= r_vid_1_second_tgl_safe;
    r2_vid_1_second_tgl     <= r1_vid_1_second_tgl;
                           
    r_vid_1_second_cnt  <= r_vid_1_second_cnt + 1'b1;
    if (r2_vid_1_second_tgl != r1_vid_1_second_tgl)
    begin
      r_vid_1_second_cnt    <= 32'b001;
      r_vid_1_second_ltchd  <= r_vid_1_second_cnt;
      r_vid_1_second_tgl    <= ~r_vid_1_second_tgl;
    end
  end
end

// Here we latch the 1_second counter, which is still in the vid_clk domain
always_ff @(posedge vid_clk)
begin
  r_vid_1_second_tgl_reg   <= r_vid_1_second_tgl;
  vid_1_second_tgl_xor     <= r_vid_1_second_tgl ^ r_vid_1_second_tgl_reg;
end

always_ff @(posedge vid_clk)
begin                       
  if (vid_1_second_tgl_xor)
    begin
      r_vid_1_second_ltchd_shadow  <= r_vid_1_second_ltchd;
  end
end

// We use a toggle signal to transfer the 1_second counter to the cpu_clk domain
intel_vvp_clock_crosser
#(
  .DATA_WIDTH  ( 1 ),
  .NUM_CC_REG  ( 3 ),  // 2 minimum, 3 recommended for Hyperflex
  .INPUT_REG   ( 1 )   // 1 to register the input first
) i_cdc_1_second_vid2cpu (
  .in_clk  (vid_clk),
  .in_data (r_vid_1_second_tgl),
  .out_clk (cpu_clk),
  .out_data(r_cpu_1_second_tgl_safe)
);

// Here we actually to the jump from vid_clk to cpu_clk 
// The r_cpu_1_second_ltchd_safe can now be used in the cpu_clk domain
always_ff @(posedge cpu_clk)
begin
  r1_cpu_1_second_tgl     <= r_cpu_1_second_tgl_safe;
  r2_cpu_1_second_xor     <= r_cpu_1_second_tgl_safe ^ r1_cpu_1_second_tgl;
end

intel_vvp_flop_enable_reset_primitive
 #(
   .WIDTH        ( 32     ),  
   .INIT_VALUE   ( 32'b0 )

 ) i_cpu_1second_cdc
 (
   .clk    ( cpu_clk ),
   .rst    ( 1'b0    ), // can't use reset because Quartus merges it into the logic in the middle of the CDC!

   .in_data   ( r_vid_1_second_ltchd_shadow  ),
   .out_data  ( r_cpu_1_second_ltchd_safe ),

   .in_enable ( r2_cpu_1_second_xor)
 );

//////////////////////////////////////////////////////////////////////////
//
// Check vid clock is running
//
logic r_cpu_1_second_tgl_return;
logic r2_cpu_1_second_tgl_return;

intel_vvp_clock_crosser
#(
  .DATA_WIDTH  ( 1 ),
  .NUM_CC_REG  ( 3 ),  // 2 minimum, 3 recommended for Hyperflex
  .INPUT_REG   ( 1 )   // 1 to register the input first
) i_cdc_1_second_return (
  .in_clk  (vid_clk),
  .in_data (r1_vid_1_second_tgl),
  .out_clk (cpu_clk),
  .out_data(r_cpu_1_second_tgl_return)
);


always_ff @(posedge cpu_clk)
begin
  if (cpu_rst)
  begin
    r_cpu_vid_clk_running   <= 1'b0;
    r2_cpu_1_second_tgl_return  <= 1'b0;
  end
  else
  begin

    if (r_cpu_1_second_cnt == C_VID_CLK_TIMEOUT)
    begin
      r2_cpu_1_second_tgl_return  <= r_cpu_1_second_tgl_return;
      if ((r_cpu_1_second_tgl == r_cpu_1_second_tgl_return) && (r_cpu_1_second_tgl == ~r2_cpu_1_second_tgl_return))
        r_cpu_vid_clk_running   <= 1'b1;
      else
        r_cpu_vid_clk_running   <= 1'b0;
    end
  end
end

endmodule
`default_nettype wire

`ifdef QUESTA_INTEL_OEM
`pragma questa_oem_00 "4c+3nmzOPVMW6eEuUZNGwsJWmgjPPXo+fxGujFidbwzDbbZJGAqLLP+GK1+dtcXM+PrpkjYVLDgGauv5zlFIZKtlY58uqq+veIdLMz61FcT7vI9J9CWvA8BAGJ+lhMlhBGGQqi4+ytKAvaXBIP4cxKm0TACtchuYCvaNZj8XwcTt2lEVIYE9miULt0k2+NoXToRWvXrlmKwPy8FswR3b7UdRkSE+9UgT6jxJC8ekSwxaTinRN9d6tC6CI6a0K+FDIBggTspBOWuNBfcqL4m83ALR33cny9SoRSlqS1rTwT3LRqEVF9dMYpKC/1SrR6Efzjde8gY4MNdhvgThVITLy+eGndD08011+Exu79Er0D3xO5krbfUUjOpvVwt22uA5g6i5RURbYNKCJ9mtpO3QvDsniPDkBJAUrNyouGKy/mj2t0UD73CwYMAxHcogT13+tUwaktjxfr9isNXA3cv2h26bDXXs3BvBpoie6AkXTwfWdXTzN1cETILsIm7HZOizDDh1VTPKrARcstOqDfnqBbWMC57NbwdC02DvrFNJVAtyXF2yqZVKw5YDMsNk2ycPyDK24QNs9WcFD3SpJnNErCrJMRlKIKZ0mrsjkuXx/D01EClTLyLbbUcm6Ul8s23XD7TUf5ISkq+Zhnn8bZ/ZH3Wa+IMBkjwh7sIOvgENTWIrD2vyWeVS/sU2yKj8dnZI9uhdnXJcXaL3OrFqCSCRpgLN90/VlqY6Zb/chUKwc8i/BhcoyW9glrfb+tel3tzOfTR1DHLPXAIl4d3iQmy3hgNRJHl6tDY9Qj+IyZO6CPYPptrzaYk8AwQvfKtkcYoPY+rtsitHnetk3XBa3OfDxWs9yqM8mNDR1IWdlOwKyno3l6GekPv7vCORgWnBKYrPoObvHL4qaTzJ04NyJVtkKLHB8hMmXCw0Av2zPY8zEOmEIzxMMn65jIdEkblXtcy27n/CWkTPAUUP3sOXjRLr+4I8XPR37l52lzYVCn5gXrhh0s6iBKCX64fdR1A8DVre"
`endif