VBP 期间只保留一个 HSYNC 脉冲的实现

vbp期间如果只允许有一个hsync脉冲,sv激励中如何实现呢?这个脉冲应该靠近vsync还是应该靠近hact?

一、直接回答:应该靠近 HACT(放在 VBP 的最后一行)

复制代码
                 VBP(共29行)
        |--------------------------------|
                                        
VSYNC: ‾‾|____|‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
         ←VSW→ ← VBP行0~27 → ←VBP行28→ ←VACT第0行→
                                    ___        
HSYNC: ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾|   |‾‾‾‾‾‾‾‾‾‾‾
                                    ↑            
                        唯一的HSYNC脉冲 ★靠近HACT   
                                   ←HBP→          
DE:    ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾|███████|‾‾‾
                                      ↑
                                   第一个HACT

为什么不能靠近 VSYNC?

上一个问题我们已经确立了不变式:任何 HACT 之前必须是 HSYNC → HBP。这个脉冲就是第一个 HACT 的"行开始标志":

  1. 功能上是第一行的行同步 :接收端靠"脉冲结束沿 + HBP 计数"确定行数据起点,参考必须是最新
  2. 放在 VSYNC 附近 = 无效:脉冲之后隔着 28 行死区,接收端无法推算第一个 HACT 的相位,等于没发
  3. VSYNC 已承担帧同步职责:VBP 开头的信息已由 VSYNC 脉冲携带,HSYNC 放那里没有增量价值

精确定位

采用行尾同步约定(HACT → HFP → HSYNC → HBP → 下一行HACT):

复制代码
脉冲位置 = 最后一个VBP行内
脉冲结束沿 = 第一个HACT开始前 HBP 个时钟
脉冲起始沿 = 脉冲结束沿 - HSW

二、SV 实现方式一:计数器风格(RTL/可综合)

复制代码
localparam int HACT=800, HFP=40, HSW=48, HBP=40;
localparam int HTOTAL = HACT+HFP+HSW+HBP;          // 928
localparam int VACT=480, VFP=13, VSW=3, VBP=29;
localparam int VTOTAL = VACT+VFP+VSW+VBP;          // 525

logic [15:0] hcnt, vcnt;   // 行内像素计数 / 帧内行计数

// 行内布局(行尾同步约定):
// [0,HACT)有效数据  [HACT,+HFP)前肩  [+HSW)同步脉冲  [+HBP)后肩
wire hsync_window = (hcnt >= HACT+HFP) && (hcnt < HACT+HFP+HSW);

// 场区域判断
wire in_vbp      = (vcnt >= VSW) && (vcnt < VSW+VBP);
wire vbp_last_ln = (vcnt == VSW+VBP-1);   // ★ VBP最后一行

// ★ 核心:VBP期间屏蔽所有脉冲,只放行最后一行的那个
assign hsync = (hsync_window && (!in_vbp || vbp_last_ln)) ? 1'b0 : 1'b1;

关键就一行逻辑:(!in_vbp || vbp_last_ln) ------ 非 VBP 区正常出脉冲;VBP 区只在最后一行出脉冲。


三、SV 实现方式二:激励 task(UVM/Testbench 风格)

复制代码
task automatic drive_vbp_single_hsync();
    // 以VBP起点为0的绝对时钟位置(单位:pclk)
    // 脉冲结束沿必须落在第一个HACT之前恰好 HBP 处
    int pulse_start = VBP*HTOTAL - HBP - HSW;  // 脉冲拉低起点
    int pulse_end   = VBP*HTOTAL - HBP;        // 脉冲拉高终点

    for (int i = 0; i < VBP*HTOTAL; i++) begin
        @(posedge vif.pclk);
        if (i >= pulse_start && i < pulse_end)
            vif.hsync <= 1'b0;      // 低有效脉冲
        else
            vif.hsync <= 1'b1;      // 其余全部保持空闲电平
        vif.de   <= 1'b0;
        vif.data <= '0;
    end
endtask

四、验证自查要点

检查项 期望值
脉冲在帧内的绝对位置 vcnt == VSW+VBP-1hcnt ∈ [HACT+HFP, HACT+HFP+HSW)
脉冲结束沿 → 第一个HACT 恰好 HBP 个 pclk
脉冲宽度 恰好 HSW 个 pclk
VBP 其余行 hsync 全程空闲电平,无毛刺
第一行之后 恢复正常逐行脉冲

五、记忆要点

  • ★ 唯一的 VBP 脉冲必须放在 VBP 最后一行(靠近 HACT),它是第一行有效数据的行同步基准
  • ★ 核心不变式:脉冲结束沿 → HBP → HACT 起点,这个距离一个时钟都不能错
  • ★ 实现核心是一个屏蔽条件:脉冲窗口 && (非VBP || VBP最后一行)
  • ★ 激励写法用绝对位置计算VBP*HTOTAL - HBP - HSW)最不容易出错