阶段一:信号基础

🔄 第03课:Z变换

离散时间系统的频域分析工具——从时域到Z域的桥梁

1. Z变换的定义

Z变换是离散时间信号最重要的分析工具,将时域序列映射到复平面(Z平面),使得差分方程变为代数方程,卷积变为乘法。

X(z) = Z{x[n]} = Σ(n=-∞ to +∞) x[n] · z⁻ⁿ

其中 z = r·e^(jω) 是复变量。当 r=1 时(|z|=1),Z变换退化为DTFT(离散时间傅里叶变换)。

1.1 收敛域(ROC)

Z变换存在的z值范围称为收敛域。ROC是理解Z变换的关键:

序列类型ROC特点
有限长序列整个Z平面(可能除去z=0或z=∞)最广泛的ROC
右边序列|z| > 某值(圆外)因果系统的ROC
左边序列|z| < 某值(圆内)非因果系统
双边序列环形区域需要两端收敛
⚠️ 同一个X(z),不同的ROC,对应不同的x[n]!ROC必须与X(z)一起给出才有意义。

2. Z变换的重要性质

📋 Z变换性质一览

性质时域Z域ROC
线性a·x₁[n] + b·x₂[n]a·X₁(z) + b·X₂(z)R₁∩R₂
时移x[n-k]z⁻ᵏ·X(z)R(可能增减z=0,∞)
频移z₀ⁿ·x[n]X(z/z₀)|z₀|·R
反转x[-n]X(z⁻¹)1/R
共轭x*[n]X*(z*)R
卷积x[n]*h[n]X(z)·H(z)R₁∩R₂
Z域微分n·x[n]-z·dX(z)/dzR
初值定理x[0]lim(z→∞) X(z)因果序列
终值定理x[∞]lim(z→1) (z-1)·X(z)稳定系统

3. 逆Z变换

从X(z)恢复x[n]的方法有三种:

3.1 部分分式展开法

将X(z)分解为简单分式之和,查表得到各分式的逆变换,再利用线性叠加:

X(z) = B(z)/A(z) = Σ Cₖ/(1 - pₖ·z⁻¹) → x[n] = Σ Cₖ·pₖⁿ·u[n]

3.2 幂级数展开法(长除法)

通过多项式长除法将X(z)展开为z⁻¹的幂级数,系数即为x[n]:

X(z) = x[0] + x[1]z⁻¹ + x[2]z⁻² + ...

3.3 围线积分法

利用留数定理计算逆Z变换:

x[n] = (1/2πj) ∮ X(z)·zⁿ⁻¹ dz = Σ Res[X(z)·zⁿ⁻¹, z=pₖ]

4. 系统函数与零极点

LTI系统的系统函数定义为:H(z) = Y(z)/X(z)

对于差分方程 y[n] = Σbₖx[n-k] - Σaₖy[n-k]:

H(z) = (b₀ + b₁z⁻¹ + ... + b_Mz⁻ᴹ) / (1 + a₁z⁻¹ + ... + a_Nz⁻ᴺ) = B(z)/A(z)

分子B(z)=0的根为零点,分母A(z)=0的根为极点。零极点分布决定了系统的频率响应和稳定性。

📌 零极点与系统特性

5. Verilog实现:极点位置计算器

计算二阶系统的极点位置,判断系统稳定性:

//=============================================
// dsp_pole_analyzer.v
// 二阶系统极点分析与稳定性判定
// H(z) = b0 / (1 + a1*z^-1 + a2*z^-2)
// 极点:z^2 + a1*z + a2 = 0
// 判稳:|p| < 1 → 稳定
//=============================================
module dsp_pole_analyzer #(
    parameter COEFF_WIDTH = 16,
    parameter FRAC_BITS  = 15,       // 小数位宽(Q1.15格式)
    parameter OUT_WIDTH   = 32
)(
    input  wire                           clk,
    input  wire                           rst_n,
    input  wire                           start,
    input  wire signed [COEFF_WIDTH-1:0]  a1_coeff,    // a1系数
    input  wire signed [COEFF_WIDTH-1:0]  a2_coeff,    // a2系数
    output reg                            stable,       // 稳定标志
    output reg                            real_poles,   // 实数极点标志
    output reg  signed [OUT_WIDTH-1:0]    pole_r1,      // 极点1实部
    output reg  signed [OUT_WIDTH-1:0]    pole_i1,      // 极点1虚部
    output reg  signed [OUT_WIDTH-1:0]    pole_r2,      // 极点2实部
    output reg  signed [OUT_WIDTH-1:0]    pole_i2,      // 极点2虚部
    output reg                            done
);

    // 判别式 Δ = a1² - 4*a2
    // 对于z² + a1*z + a2 = 0
    // z = (-a1 ± √Δ) / 2

    reg signed [2*COEFF_WIDTH-1:0] a1_sq;
    reg signed [2*COEFF_WIDTH+1:0] four_a2;
    reg signed [2*COEFF_WIDTH+1:0] discriminant;
    reg signed [OUT_WIDTH-1:0]     neg_a1_half;

    // 状态机
    localparam IDLE  = 2'd0;
    localparam CALC  = 2'd1;
    localparam CHECK = 2'd2;
    localparam DONE  = 2'd3;

    reg [1:0] state;

    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            state <= IDLE;
            stable <= 1'b0;
            real_poles <= 1'b0;
            pole_r1 <= 0;
            pole_i1 <= 0;
            pole_r2 <= 0;
            pole_i2 <= 0;
            done <= 1'b0;
        end else begin
            case (state)
                IDLE: begin
                    done <= 1'b0;
                    if (start) begin
                        state <= CALC;
                        a1_sq <= a1_coeff * a1_coeff;
                        four_a2 <= 4 * (a2_coeff << FRAC_BITS);
                    end
                end

                CALC: begin
                    discriminant <= a1_sq - four_a2;
                    neg_a1_half <= -(a1_coeff << (FRAC_BITS-1));
                    state <= CHECK;
                end

                CHECK: begin
                    if (discriminant >= 0) begin
                        // 实数极点
                        real_poles <= 1'b1;
                        pole_r1 <= neg_a1_half;  // 简化:(-a1/2)
                        pole_i1 <= 0;
                        pole_r2 <= neg_a1_half;
                        pole_i2 <= 0;
                    end else begin
                        // 复数共轭极点
                        real_poles <= 1'b0;
                        pole_r1 <= neg_a1_half;
                        pole_i1 <= 1;  // 简化标记
                        pole_r2 <= neg_a1_half;
                        pole_i2 <= -1;
                    end

                    // 稳定性判断:|a2| < 1 (极点在单位圆内的必要条件)
                    // 对于二阶系统:稳定 ⟺ |a2| < 1 且 |a1| < 1 + a2
                    stable <= (a2_coeff > 0) && (a2_coeff < (1 << FRAC_BITS)) &&
                              (a1_coeff > -(1 << FRAC_BITS) + a2_coeff) &&
                              (a1_coeff < (1 << FRAC_BITS) + a2_coeff);

                    state <= DONE;
                end

                DONE: begin
                    done <= 1'b1;
                    state <= IDLE;
                end
            endcase
        end
    end

endmodule

6. Verilog实现:频率响应计算器

给定系统函数H(z)的系数,计算特定频率ω处的频率响应|H(e^jω)|:

//=============================================
// dsp_freq_response.v
// 频率响应计算器
// H(e^jω) = Σ b[k]*e^(-jkω) / Σ a[k]*e^(-jkω)
//=============================================
module dsp_freq_response #(
    parameter DATA_WIDTH = 16,
    parameter COEFF_WIDTH = 16,
    parameter ORDER = 8,                // 最大阶数
    parameter PHASE_WIDTH = 16          // 相位位宽
)(
    input  wire                          clk,
    input  wire                          rst_n,
    input  wire                          start,
    input  wire [PHASE_WIDTH-1:0]        omega,      // 数字角频率
    input  wire signed [COEFF_WIDTH-1:0] b_coeffs [0:ORDER-1],
    input  wire signed [COEFF_WIDTH-1:0] a_coeffs [0:ORDER-1],
    output reg  signed [DATA_WIDTH-1:0]  h_real,     // H的实部
    output reg  signed [DATA_WIDTH-1:0]  h_imag,     // H的虚部
    output reg  [DATA_WIDTH-1:0]         h_mag,      // |H|
    output reg                           done
);

    // CORDIC旋转器用于计算e^(-jkω)
    reg signed [DATA_WIDTH-1:0] cos_out, sin_out;
    reg signed [2*DATA_WIDTH-1:0] num_real_acc, num_imag_acc;
    reg signed [2*DATA_WIDTH-1:0] den_real_acc, den_imag_acc;

    reg [$clog2(ORDER+1)-1:0] k;
    reg running;

    // 简化的CORDIC cos/sin查表
    reg signed [DATA_WIDTH-1:0] cos_table [0:255];
    reg signed [DATA_WIDTH-1:0] sin_table [0:255];

    initial begin
        integer i;
        for (i = 0; i < 256; i = i + 1) begin
            cos_table[i] = $rtoi((2.0**(DATA_WIDTH-1)-1) * $cos(2.0*3.14159265*i/256));
            sin_table[i] = $rtoi((2.0**(DATA_WIDTH-1)-1) * $sin(2.0*3.14159265*i/256));
        end
    end

    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            running <= 1'b0;
            k <= 0;
            h_real <= 0;
            h_imag <= 0;
            h_mag <= 0;
            done <= 1'b0;
        end else if (start && !running) begin
            running <= 1'b1;
            k <= 0;
            num_real_acc <= 0;
            num_imag_acc <= 0;
            den_real_acc <= 0;
            den_imag_acc <= 0;
        end else if (running) begin
            // 计算e^(-jkω)的查表地址
            // 使用k*omega的高8位作为查表索引
            cos_out <= cos_table[(k * omega[PHASE_WIDTH-1:PHASE_WIDTH-8]) & 8'hFF];
            sin_out <= sin_table[(k * omega[PHASE_WIDTH-1:PHASE_WIDTH-8]) & 8'hFF];

            // 累加分子:b[k] * e^(-jkω)
            num_real_acc <= num_real_acc + b_coeffs[k] * cos_out;
            num_imag_acc <= num_imag_acc - b_coeffs[k] * sin_out;

            // 累加分母:a[k] * e^(-jkω)
            den_real_acc <= den_real_acc + a_coeffs[k] * cos_out;
            den_imag_acc <= den_imag_acc - a_coeffs[k] * sin_out;

            if (k == ORDER - 1) begin
                running <= 1'b0;
                done <= 1'b1;
                // 简化输出(实际应做复数除法)
                h_real <= num_real_acc[2*DATA_WIDTH-1:DATA_WIDTH];
                h_imag <= num_imag_acc[2*DATA_WIDTH-1:DATA_WIDTH];
                h_mag <= num_real_acc[2*DATA_WIDTH-1:DATA_WIDTH]; // 简化
            end else begin
                k <= k + 1'b1;
            end
        end
    end

endmodule

7. 常见信号的Z变换对

时域 x[n]Z域 X(z)ROC
δ[n]1全部z
u[n]1/(1-z⁻¹)|z|>1
aⁿu[n]1/(1-az⁻¹)|z|>|a|
n·aⁿu[n]az⁻¹/(1-az⁻¹)²|z|>|a|
cos(ω₀n)u[n](1-cos(ω₀)z⁻¹)/(1-2cos(ω₀)z⁻¹+z⁻²)|z|>1
sin(ω₀n)u[n]sin(ω₀)z⁻¹/(1-2cos(ω₀)z⁻¹+z⁻²)|z|>1
aⁿcos(ω₀n)u[n](1-a·cos(ω₀)z⁻¹)/(1-2a·cos(ω₀)z⁻¹+a²z⁻²)|z|>|a|

8. 练习

📝 练习1:求Z变换

求以下信号的Z变换及其ROC:

  1. x[n] = (0.5)ⁿu[n] + (0.3)ⁿu[n]
  2. x[n] = (2)ⁿu[n] - (3)ⁿu[-n-1]
  3. x[n] = n·(0.5)ⁿu[n]

📝 练习2:逆Z变换

X(z) = z² / [(z-0.5)(z-0.25)],分别求以下ROC对应的x[n]:

  1. |z| > 0.5
  2. 0.25 < |z| < 0.5
  3. |z| < 0.25

📝 练习3:稳定性验证

修改 dsp_pole_analyzer.v,添加对三阶系统 H(z) = 1/(1 + a₁z⁻¹ + a₂z⁻² + a₃z⁻³) 的稳定性判断。

📝 练习4:零极点设计

设计一个二阶系统H(z),使其在ω=π/4处有峰值(极点),在ω=π/2处有零点。写出系统函数并验证。

🏆 成就解锁:Z域探索者

✅ 掌握了Z变换的定义、ROC概念

✅ 理解了Z变换的十大性质

✅ 学会了三种逆Z变换方法

✅ 实现了极点位置分析器(Verilog)

✅ 实现了频率响应计算器(Verilog)

11. 补充:Z变换的进阶主题

Z变换在进阶应用中还有以下重要主题值得深入研究:

📚 进阶研究方向

12. 与前后课程的关联

本课内容在整个DSP课程体系中处于承上启下的位置:

🔗 课程关联图

13. 设计经验总结

在实际工程中,Z变换的设计经验总结如下:(1)始终从系统级需求出发,不要过早陷入实现细节;(2)先用浮点仿真验证算法正确性,再转为定点;(3)系数量化后必须重新验证频率响应;(4)硬件实现前用C/MATLAB模型作为参考;(5)综合后检查时序和资源是否符合预期;(6)板级验证时用已知的测试信号对比参考输出。每一步验证都是必要的,跳过任何一步都可能导致最终的调试时间成倍增加。

📌 关键设计检查清单

13. 设计经验总结

在实际工程中,Z变换的设计经验总结如下:(1)始终从系统级需求出发,不要过早陷入实现细节;(2)先用浮点仿真验证算法正确性,再转为定点;(3)系数量化后必须重新验证频率响应;(4)硬件实现前用C/MATLAB模型作为参考;(5)综合后检查时序和资源是否符合预期;(6)板级验证时用已知的测试信号对比参考输出。每一步验证都是必要的,跳过任何一步都可能导致最终的调试时间成倍增加。

📌 关键设计检查清单