Files
IPA/tb/data_cache/tb_histogram_ctrl.v
Core_kingdom 79dee10db1 cache module
2025-08-26 16:53:22 +08:00

208 lines
9.1 KiB
Verilog
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

`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数据有效像素值10、20、30、40、50
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:15、25、35G:45、55、65B:75、85、95
// 写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