Files
IPA/tb/data_cache/tb_histogram_ctrl.v

208 lines
9.1 KiB
Coq
Raw Normal View History

2025-08-26 16:53:22 +08:00
`timescale 1ns/1ps
// 直方图控制模块Testbench修复标识符未声明问题
module tb_histogram_ctrl();
// -------------------------- 1. 参数定义与待测试模块匹配 --------------------------
parameter HIST_RAM_DEPTH = 256; // 直方图RAM深度像素值0~255
parameter HIST_RAM_DATA_W = 1; // 直方图RAM数据位宽1bit标记像素存在
parameter CLK_PERIOD = 10; // 时钟周期10ns = 100MHz
parameter RAM_CLEAR_CYCLES = 256; // 直方图复位需遍历256个地址256个时钟周期
// -------------------------- 2. 信号定义仅含模块接口信号无内部信号引用 --------------------------
reg clk; // 时钟
reg rst_n; // 全局复位低有效
reg hist_rst; // 直方图复位
reg input_pixel_type; // 像素类型0=Gray1=RGB
// CH0 写信号Gray模式有效/RGB模式R通道
reg hist_wr_en_ch0; // CH0写使能
reg [7:0] hist_wr_addr_ch0; // CH0写地址像素值0~255
// CH1 写信号仅RGB模式G通道
reg hist_wr_en_ch1; // CH1写使能
reg [7:0] hist_wr_addr_ch1; // CH1写地址
// CH2 写信号仅RGB模式B通道
reg hist_wr_en_ch2; // CH2写使能
reg [7:0] hist_wr_addr_ch2; // CH2写地址
// min/max计算配置
reg [15:0] histogram_low_num; // 低位数第N个有效像素作为min
reg [15:0] histogram_high_num; // 高位数第N个有效像素作为max
reg calc_en; // 计算使能
// 输出信号
wire calc_done; // 计算完成
wire [7:0] dwidth_conv_min_ch0;// CH0 min结果
wire [7:0] dwidth_conv_max_ch0;// CH0 max结果
wire [7:0] dwidth_conv_min_ch1;// CH1 min结果
wire [7:0] dwidth_conv_max_ch1;// CH1 max结果
wire [7:0] dwidth_conv_min_ch2;// CH2 min结果
wire [7:0] dwidth_conv_max_ch2;// CH2 max结果
// -------------------------- 3. 生成时钟 --------------------------
initial begin
clk = 1'b0;
forever #(CLK_PERIOD/2) clk = ~clk; // 5ns翻转100MHz时钟
end
// -------------------------- 4. 实例化待测试模块 --------------------------
histogram_ctrl #(
.HIST_RAM_DEPTH (HIST_RAM_DEPTH),
.HIST_RAM_DATA_W (HIST_RAM_DATA_W)
) u_histogram_ctrl (
.clk (clk),
.rst_n (rst_n),
.hist_rst (hist_rst),
.input_pixel_type (input_pixel_type),
.hist_wr_en_ch0 (hist_wr_en_ch0),
.hist_wr_addr_ch0 (hist_wr_addr_ch0),
.hist_wr_en_ch1 (hist_wr_en_ch1),
.hist_wr_addr_ch1 (hist_wr_addr_ch1),
.hist_wr_en_ch2 (hist_wr_en_ch2),
.hist_wr_addr_ch2 (hist_wr_addr_ch2),
.histogram_low_num (histogram_low_num),
.histogram_high_num (histogram_high_num),
.calc_en (calc_en),
.calc_done (calc_done),
.dwidth_conv_min_ch0 (dwidth_conv_min_ch0),
.dwidth_conv_max_ch0 (dwidth_conv_max_ch0),
.dwidth_conv_min_ch1 (dwidth_conv_min_ch1),
.dwidth_conv_max_ch1 (dwidth_conv_max_ch1),
.dwidth_conv_min_ch2 (dwidth_conv_min_ch2),
.dwidth_conv_max_ch2 (dwidth_conv_max_ch2)
);
// -------------------------- 5. 生成FSDB波形文件Verdi可查看 --------------------------
initial begin
$fsdbDumpfile("tb.fsdb"); // 波形文件命名为tb.fsdb
$fsdbDumpvars(0, tb_histogram_ctrl); // Dump顶层及所有子模块信号
$fsdbDumpMDA(0, tb_histogram_ctrl); // Dump内部RAMhist_ram_ch0/1/2内容
end
// -------------------------- 6. 核心测试场景无内部信号引用 --------------------------
initial begin
// --------------- 步骤1初始复位清除不定态 ---------------
rst_n = 1'b0;
hist_rst = 1'b0;
input_pixel_type = 1'b0;
hist_wr_en_ch0 = 1'b0;
hist_wr_addr_ch0 = 8'd0;
hist_wr_en_ch1 = 1'b0;
hist_wr_addr_ch1 = 8'd0;
hist_wr_en_ch2 = 1'b0;
hist_wr_addr_ch2 = 8'd0;
histogram_low_num = 16'd2; // 找第2个有效像素作为min跳过1个噪声点
histogram_high_num = 16'd2; // 找第2个有效像素作为max跳过1个噪声点
calc_en = 1'b0;
#(CLK_PERIOD * 5); // 复位保持5个时钟周期
rst_n = 1'b1; // 释放全局复位
#(CLK_PERIOD * 2); // 等待稳定
// --------------- 步骤2测试直方图复位替代原状态判断 ---------------
$display("[%0t] Test 1: Histogram Reset", $time);
hist_rst = 1'b1; // 触发直方图复位
#(CLK_PERIOD); // 保持1个时钟周期确保状态切换
hist_rst = 1'b0; // 释放复位
#(CLK_PERIOD * RAM_CLEAR_CYCLES); // 等待复位完成遍历256个地址
#(CLK_PERIOD * 2); // 额外等待2个周期稳定
$display("[%0t] Test 1 Done: Histogram RAM Cleared", $time);
// --------------- 步骤3灰度模式Gray写入与min/max计算 ---------------
$display("[%0t] Test 2: Gray Mode (Write + Calc min/max)", $time);
input_pixel_type = 1'b0; // 切换为Gray模式仅CH0有效
// 3.1 写入Gray数据有效像素值1020304050
hist_wr_en_ch0 = 1'b1;#(CLK_PERIOD);
hist_wr_addr_ch0 = 8'd10; #(CLK_PERIOD);
hist_wr_addr_ch0 = 8'd20; #(CLK_PERIOD);
hist_wr_addr_ch0 = 8'd30; #(CLK_PERIOD);
hist_wr_addr_ch0 = 8'd40; #(CLK_PERIOD);
hist_wr_addr_ch0 = 8'd50; #(CLK_PERIOD);
hist_wr_en_ch0 = 1'b0; // 关闭写使能
#(CLK_PERIOD * 2);
// 3.2 触发min/max计算找第2个min=20第2个max=40
calc_en = 1'b1;
#(CLK_PERIOD);
calc_en = 1'b0; // 释放计算使能
wait(calc_done == 1'b1); // 用输出信号判断计算完成无需内部状态
#(CLK_PERIOD);
// 打印结果预期min_ch0=20max_ch0=40
$display("[%0t] Gray Mode Result: min_ch0=%0d, max_ch0=%0d (Expected: 20, 40)",
$time, dwidth_conv_min_ch0, dwidth_conv_max_ch0);
#(CLK_PERIOD * 2);
// --------------- 步骤4RGB模式写入与min/max计算 ---------------
$display("[%0t] Test 3: RGB Mode (Write + Calc min/max)", $time);
// 直方图复位用时间等待替代状态判断
hist_rst = 1'b1;
#(CLK_PERIOD);
hist_rst = 1'b0;
#(CLK_PERIOD * RAM_CLEAR_CYCLES); // 等待复位完成
input_pixel_type = 1'b1; // 切换为RGB模式CH0=RCH1=GCH2=B
#(CLK_PERIOD * 2);
// 4.1 写入RGB数据R:152535G:455565B:758595
// 写R通道CH0
hist_wr_en_ch0 = 1'b1;#(CLK_PERIOD);
hist_wr_addr_ch0 = 8'd15; #(CLK_PERIOD);
hist_wr_addr_ch0 = 8'd25; #(CLK_PERIOD);
hist_wr_addr_ch0 = 8'd35; #(CLK_PERIOD);
hist_wr_en_ch0 = 1'b0;
// 写G通道CH1
hist_wr_en_ch1 = 1'b1;#(CLK_PERIOD);
hist_wr_addr_ch1 = 8'd45; #(CLK_PERIOD);
hist_wr_addr_ch1 = 8'd55; #(CLK_PERIOD);
hist_wr_addr_ch1 = 8'd65; #(CLK_PERIOD);
hist_wr_en_ch1 = 1'b0;
// 写B通道CH2
hist_wr_en_ch2 = 1'b1;#(CLK_PERIOD);
hist_wr_addr_ch2 = 8'd75; #(CLK_PERIOD);
hist_wr_addr_ch2 = 8'd85; #(CLK_PERIOD);
hist_wr_addr_ch2 = 8'd95; #(CLK_PERIOD);
hist_wr_en_ch2 = 1'b0;
#(CLK_PERIOD * 2);
// 4.2 触发RGB模式计算预期R=25/25G=55/55B=85/85
calc_en = 1'b1;
#(CLK_PERIOD);
calc_en = 1'b0;
wait(calc_done == 1'b1); // 用输出信号判断完成
#(CLK_PERIOD);
// 打印RGB结果
$display("[%0t] RGB Mode Result: R(min=%0d, max=%0d), G(min=%0d, max=%0d), B(min=%0d, max=%0d) (Expected: R=25/25, G=55/55, B=85/85)",
$time, dwidth_conv_min_ch0, dwidth_conv_max_ch0,
dwidth_conv_min_ch1, dwidth_conv_max_ch1,
dwidth_conv_min_ch2, dwidth_conv_max_ch2);
#(CLK_PERIOD * 2);
// --------------- 步骤5测试+计算并行触发 ---------------
$display("[%0t] Test 4: Trigger Write and Calc Simultaneously", $time);
// 直方图复位
hist_rst = 1'b1;
#(CLK_PERIOD);
hist_rst = 1'b0;
#(CLK_PERIOD * RAM_CLEAR_CYCLES);
input_pixel_type = 1'b0; // 回到Gray模式
#(CLK_PERIOD * 2);
// 先写1个数据再并行触发+计算
hist_wr_en_ch0 = 1'b1;
hist_wr_addr_ch0 = 8'd5; #(CLK_PERIOD);
calc_en = 1'b1; // 同时触发计算
hist_wr_addr_ch0 = 8'd15; #(CLK_PERIOD);
hist_wr_en_ch0 = 1'b0;
calc_en = 1'b0;
wait(calc_done == 1'b1); // 用输出信号判断完成
#(CLK_PERIOD);
$display("[%0t] Test 4 Done: Simultaneous Trigger OK", $time);
// --------------- 步骤6测试完成结束仿真 ---------------
#(CLK_PERIOD * 5);
$display("[%0t] All Tests Completed!", $time);
$finish; // 结束仿真
end
endmodule