DAY 56 时序数据的检验

作业:自行构造数据集,来检查是否符合这个要求。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from statsmodels.tsa.stattools import acf, pacf, adfuller, lbtest
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
from statsmodels.tsa.seasonal import seasonal_decompose

# 设置中文显示
plt.rcParams["font.family"] = ["SimHei", "WenQuanYi Micro Hei", "Heiti TC"]
plt.rcParams["axes.unicode_minus"] = False  # 解决负号显示问题

def generate_and_test_white_noise():
    """生成白噪声序列并进行检验"""
    # 生成白噪声序列(均值0,方差1的正态分布)
    np.random.seed(42)
    white_noise = np.random.normal(loc=0, scale=1, size=1000)
    white_noise_series = pd.Series(white_noise, name='白噪声序列')
    
    # 白噪声检验:Ljung-Box检验
    lb_test_result = lbtest(white_noise_series, nlags=10)
    print("===== 白噪声序列检验 =====")
    print(f"Ljung-Box检验P值列表:{lb_test_result.pvalues.round(4)}")
    print(f"是否全部P值>0.05:{np.all(lb_test_result.pvalues > 0.05)}")
    
    # 可视化ACF和PACF
    fig, axes = plt.subplots(1, 2, figsize=(12, 4))
    plot_acf(white_noise_series, lags=30, ax=axes[0])
    axes[0].set_title('白噪声ACF图')
    plot_pacf(white_noise_series, lags=30, ax=axes[1])
    axes[1].set_title('白噪声PACF图')
    plt.tight_layout()
    plt.savefig('white_noise_acf_pacf.png')
    plt.close()
    
    return white_noise_series

def generate_and_test_non_stationary():
    """生成非平稳序列并进行平稳性检验"""
    # 生成随机游走序列(非平稳)
    np.random.seed(42)
    random_walk = np.cumsum(np.random.normal(loc=0, scale=1, size=1000))
    random_walk_series = pd.Series(random_walk, name='随机游走序列')
    
    # 平稳性检验:ADF单位根检验
    adf_result = adfuller(random_walk_series)
    print("\n===== 随机游走序列平稳性检验 =====")
    print(f"ADF统计量:{adf_result[0]:.4f}")
    print(f"P值:{adf_result[1]:.4f}")
    print(f"1%临界值:{adf_result[4]['1%']:.4f}")
    print(f"是否拒绝原假设(非平稳):{adf_result[1] < 0.05}")
    
    # 可视化序列
    plt.figure(figsize=(10, 4))
    plt.plot(random_walk_series)
    plt.title('随机游走序列(非平稳)')
    plt.xlabel('时间')
    plt.ylabel('值')
    plt.tight_layout()
    plt.savefig('random_walk_series.png')
    plt.close()
    
    return random_walk_series

def generate_and_test_seasonal():
    """生成季节性序列并进行季节性检验"""
    # 生成带季节性的序列:趋势+季节性+白噪声
    np.random.seed(42)
    time = np.arange(0, 1000)
    trend = 0.01 * time  # 线性趋势
    seasonality = 5 * np.sin(2 * np.pi * time / 12)  # 周期为12的季节性
    noise = np.random.normal(loc=0, scale=1, size=1000)
    seasonal_series = pd.Series(trend + seasonality + noise, name='季节性序列')
    
    # 季节性检验:ACF检验
    acf_values = acf(seasonal_series, nlags=30)
    print("\n===== 季节性序列检验 =====")
    print(f"滞后12阶ACF值:{acf_values[12]:.4f}")
    
    # 可视化ACF和序列
    fig, axes = plt.subplots(2, 1, figsize=(10, 8))
    plot_acf(seasonal_series, lags=30, ax=axes[0])
    axes[0].set_title('季节性序列ACF图')
    axes[1].plot(seasonal_series)
    axes[1].set_title('季节性序列(趋势+周期+噪声)')
    plt.tight_layout()
    plt.savefig('seasonal_series.png')
    plt.close()
    
    # 序列分解
    decomposition = seasonal_decompose(seasonal_series, model='additive', period=12)
    trend = decomposition.trend
    seasonal = decomposition.seasonal
    residual = decomposition.resid
    
    # 可视化分解结果
    fig, axes = plt.subplots(4, 1, figsize=(10, 10))
    axes[0].plot(seasonal_series)
    axes[0].set_title('原始序列')
    axes[1].plot(trend)
    axes[1].set_title('趋势成分')
    axes[2].plot(seasonal)
    axes[2].set_title('季节性成分')
    axes[3].plot(residual)
    axes[3].set_title('残差成分')
    plt.tight_layout()
    plt.savefig('seasonal_decomposition.png')
    plt.close()
    
    return seasonal_series

def main():
    """主函数:执行所有检验并汇总结果"""
    print("===== 时间序列假设检验演示 =====")
    
    # 1. 检验白噪声
    white_noise = generate_and_test_white_noise()
    
    # 2. 检验非平稳序列
    non_stationary = generate_and_test_non_stationary()
    
    # 3. 检验季节性序列
    seasonal = generate_and_test_seasonal()
    
    print("\n===== 假设检验结论 =====")
    print("1. 白噪声序列:Ljung-Box检验P值全部>0.05,不拒绝‘白噪声’原假设")
    print("2. 随机游走序列:ADF检验P值>0.05,不拒绝‘非平稳’原假设")
    print("3. 季节性序列:ACF滞后12阶显著(接近1),存在季节性")
    
    print("\n可视化图表已保存至当前目录:")
    print("- white_noise_acf_pacf.png")
    print("- random_walk_series.png")
    print("- seasonal_series.png")
    print("- seasonal_decomposition.png")

if __name__ == "__main__":
    main()    

module b ( input clk, input rst_n, input ex_bcode_signal, output reg [3:0] miao_gewei, output reg [2:0] miao_shiwei, output reg [3:0] fen_gewei, output reg [2:0] fen_shiwei, output reg [3:0] shi_gewei, output reg [1:0] shi_shiwei, output reg [3:0] day_gewei, output reg [3:0] day_shiwei, output reg [1:0] day_baiwei, output reg [3:0] year_gewei, output reg [3:0] year_shiwei ); // 参数定义(保持不变) localparam CLK_PERIOD = 8; localparam MS10_CYCLES = 1250000; localparam MS2_CYCLES = 250000; localparam MS5_CYCLES = 625000; localparam MS8_CYCLES = 1000000; // 状态定义(保持不变) localparam IDLE = 4'd0; localparam START_DETECT = 4'd1; localparam PULSE_MEASURE = 4'd2; localparam SYNC_SEARCH = 4'd3; localparam DATA_DECODE = 4'd4; localparam PARSE_TIME = 4'd5; reg [3:0] cstate, nstate; reg [31:0] pulse_width_cnt; reg [7:0] symbol_cnt; reg [0:99] data_buffer; reg [1:0] symbol_type; reg [1:0] prev_symbol_type; reg sync_found; reg pos_edge_detected, neg_edge_detected; reg [5:0] ex_bcode_end; reg [20:0] ms10_timer; reg symbol_timer_en; // 边沿检测(保持不变) always @(posedge clk or negedge rst_n) begin if (~rst_n) begin ex_bcode_end <= 6'b000000; pos_edge_detected <= 1'b0; neg_edge_detected <= 1'b0; end else begin ex_bcode_end[0] <= ex_bcode_signal; ex_bcode_end[5:1] <= ex_bcode_end[4:0]; pos_edge_detected <= (ex_bcode_end[4] == 1'b1 && ex_bcode_end[5] == 1'b0); neg_edge_detected <= (ex_bcode_end[4] == 1'b0 && ex_bcode_end[5] == 1'b1); end end // 状态寄存器更新(保持不变) always @(posedge clk or negedge rst_n) begin if (~rst_n) cstate <= IDLE; else cstate <= nstate; end // 状态转移逻辑(修正) always @(*) begin nstate = cstate; case (cstate) IDLE: if (pos_edge_detected) nstate = START_DETECT; START_DETECT: if (neg_edge_detected) nstate = PULSE_MEASURE; else if (pulse_width_cnt > MS10_CYCLES * 2) nstate = IDLE; PULSE_MEASURE: if (ms10_timer >= MS10_CYCLES) begin if (sync_found) nstate = DATA_DECODE; else nstate = SYNC_SEARCH; end SYNC_SEARCH: if (symbol_cnt >= 100) nstate = IDLE; else if (pos_edge_detected) nstate = START_DETECT; DATA_DECODE: if (symbol_cnt >= 100) nstate = PARSE_TIME; else if (pos_edge_detected) nstate = START_DETECT; PARSE_TIME: nstate = IDLE; default: nstate = IDLE; endcase end // 数据处理逻辑(修正) always @(posedge clk or negedge rst_n) begin if (~rst_n) begin pulse_width_cnt <= 0; symbol_cnt <= 0; sync_found <= 1'b0; symbol_timer_en <= 1'b0; ms10_timer <= 0; symbol_type <= 2'b00; prev_symbol_type <= 2'b00; data_buffer <= 100'b0; // 输出清零 {miao_gewei, miao_shiwei, fen_gewei, fen_shiwei, shi_gewei, shi_shiwei, day_gewei, day_shiwei, day_baiwei, year_gewei, year_shiwei} <= 0; end else begin case (cstate) IDLE: begin pulse_width_cnt <= 0; symbol_cnt <= 0; sync_found <= 1'b0; symbol_timer_en <= 1'b0; ms10_timer <= 0; symbol_type <= 2'b00; prev_symbol_type <= 2'b00; end START_DETECT: begin if (ex_bcode_signal) pulse_width_cnt <= pulse_width_cnt + 1; else if (neg_edge_detected) begin // 检测脉冲宽度并分类 if (pulse_width_cnt >= MS8_CYCLES - 1000 && pulse_width_cnt <= MS8_CYCLES + 1000) begin symbol_type <= 2'b10; // 同步头符号 if (prev_symbol_type == 2'b10) sync_found <= 1'b1; prev_symbol_type <= 2'b10; end else if (pulse_width_cnt >= MS5_CYCLES - 1000 && pulse_width_cnt <= MS5_CYCLES + 1000) begin symbol_type <= 2'b01; // 数据位 '1' end else if (pulse_width_cnt >= MS2_CYCLES - 1000 && pulse_width_cnt <= MS2_CYCLES + 1000) begin symbol_type <= 2'b00; // 数据位 '0' end pulse_width_cnt <= 0; symbol_timer_en <= 1'b1; ms10_timer <= 0; end end PULSE_MEASURE: begin if (symbol_timer_en) begin ms10_timer <= ms10_timer + 1; if (ms10_timer >= MS10_CYCLES - 1) begin symbol_timer_en <= 1'b0; if (symbol_type == 2'b10) begin if (!sync_found) prev_symbol_type <= 2'b10; // 更新同步头检测状态 end else begin // 存储数据位到缓冲区 if (symbol_cnt < 100) begin data_buffer[symbol_cnt] <= symbol_type[0]; symbol_cnt <= symbol_cnt + 1; end end end end end SYNC_SEARCH: begin // 同步搜索期间不操作数据缓冲区,仅等待下一个同步头 symbol_type <= 2'b00; end DATA_DECODE: begin // 数据解码状态(可扩展校验逻辑) if (symbol_cnt >= 100) begin // 假设数据已完整接收,进入PARSE_TIME nstate <= PARSE_TIME; end end PARSE_TIME: begin // 解析缓冲区数据到输出(示例:秒个位) miao_gewei <= {data_buffer[3], data_buffer[2], data_buffer[1], data_buffer[0]}; miao_shiwei <= {data_buffer[7], data_buffer[6], data_buffer[5]}; fen_gewei <= {data_buffer[12], data_buffer[11], data_buffer[10], data_buffer[9]}; fen_shiwei <= {data_buffer[16], data_buffer[15], data_buffer[14]}; shi_gewei <= {data_buffer[22], data_buffer[21], data_buffer[20], data_buffer[19]}; shi_shiwei <= {data_buffer[25], data_buffer[24]}; day_gewei <= {data_buffer[32], data_buffer[31], data_buffer[30], data_buffer[29]}; day_shiwei <= {data_buffer[37], data_buffer[36], data_buffer[35], data_buffer[34]}; day_baiwei <= {data_buffer[40], data_buffer[39]}; year_gewei <= {data_buffer[52], data_buffer[51], data_buffer[50], data_buffer[49]}; year_shiwei <= {data_buffer[57], data_buffer[56], data_buffer[55], data_buffer[54]}; end endcase end end endmodule 写出这个代码的tb文件,文件名b_tb,时间为03年12月3日18时23分34秒,要求能在modelsim看到数值
11-25
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值