一. 模块功能与应用场景
模块功能:对输入信号进行降采样。
应用场景:
- 输入数据量太大,后级难以处理,需要减小信号量而不丢失关键信息
二. 模块框图与使用说明
参数DOWN_SAMPLING_TIME控制降采样倍数,参数DIN_WIDTH控制输入信号位宽。
注意:
- din与din_valid应对齐
- clk应就是din与din_valid产生的时钟,这是为了保证一个有效数据din_valid只持续一个时钟周期的高电平
三. 模块代码
/** @Author : Xu Dakang* @Email : XudaKang_up@qq.com* @Date : 2021-04-21 15:02:16* @LastEditors : Xu Dakang* @LastEditTime : 2021-05-05 15:44:39* @Filename : downSampling.sv* @Description : 降采样模块
*//*
* 思路: 对din_valid进行计数,到达DOWN_SAMPLING_TIME输出一次值
* 注意:1.din与din_valid应对齐2.clk应就是din与din_valid产生的时钟,这是为了保证一个有效数据din_valid只持续一个时钟周期的高电平
*/module downSampling
#(parameter DOWN_SAMPLING_TIME = 10, // 降采样倍数parameter DIN_WIDTH = 24
)(output logic [DIN_WIDTH-1 : 0] down_sampling_dout,output logic down_sampling_dout_valid,input logic [DIN_WIDTH-1 : 0] din,input logic din_valid,input logic clk,input logic rstn
);//< 输入数据同步 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
logic [DIN_WIDTH-1 : 0] din_r1;
logic [DIN_WIDTH-1 : 0] din_r2;
always_ff @(posedge clk) begindin_r1 <= din;din_r2 <= din_r1;
endlogic din_valid_r1;
logic din_valid_r2;
always_ff @(posedge clk) begindin_valid_r1 <= din_valid;din_valid_r2 <= din_valid_r1;
end
//< 输入数据同步 ------------------------------------------------------------//> 信号计数 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
logic [$clog2(DOWN_SAMPLING_TIME+1)-1 : 0] din_valid_cnt;
always_ff @(posedge clk, negedge rstn) beginif (~rstn)din_valid_cnt <= '0;else if (din_valid_r2)if (din_valid_cnt == DOWN_SAMPLING_TIME)din_valid_cnt <= 'd1;elsedin_valid_cnt <= din_valid_cnt + 1'b1;else if (din_valid_cnt == DOWN_SAMPLING_TIME)din_valid_cnt <= '0;elsedin_valid_cnt <= din_valid_cnt;
end
//> 信号计数 ------------------------------------------------------------//> 输出降采样值和有效信号 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
always_ff @(posedge clk, negedge rstn) beginif (~rstn)down_sampling_dout <= '0;else if (din_valid_cnt == DOWN_SAMPLING_TIME)down_sampling_dout <= din_r2;elsedown_sampling_dout <= down_sampling_dout;
endalways_ff @(posedge clk, negedge rstn) beginif (~rstn)down_sampling_dout_valid <= 1'b0;else if (din_valid_cnt == DOWN_SAMPLING_TIME)down_sampling_dout_valid <= 1'b1;elsedown_sampling_dout_valid <= 1'b0;
end
//> 输出降采样值和有效信号 ------------------------------------------------------------endmodule
四. testbench
/** @Author : Xu Dakang* @Email : XudaKang_up@qq.com* @Date : 2021-04-21 15:02:16* @LastEditors : Xu Dakang* @LastEditTime : 2021-05-05 22:12:07* @Filename : downSampling_tb.sv* @Description : testbench of downSampling
*/module downSampling_tb();timeunit 1ns;
timeprecision 10ps;localparam DOWN_SAMPLING_TIME = 10;
localparam DIN_WIDTH = 24;logic [DIN_WIDTH-1 : 0] down_sampling_dout;
logic down_sampling_dout_valid;logic [DIN_WIDTH-1 : 0] din;
logic din_valid;logic clk;
logic rstn;downSampling #(.DOWN_SAMPLING_TIME (DOWN_SAMPLING_TIME), // 降采样倍数.DIN_WIDTH (DIN_WIDTH)
) downSampling_inst(.*);// 导入输入波形文件
string din_path = "F:/OneDrive/VivadoPrj/downSampling/downSampling.srcs/sim_1/new/sinc.txt"; // 可选 sin exp_cos sinclocalparam DATA_NUM = 10000; // 数据量, 也就是txt文件的行数, 如果此参数大于数据行数, 读取到的内容为不定态
logic [DIN_WIDTH-1 : 0] din_wave_data [DATA_NUM]; // 读取输入波形数据initial begin$readmemb(din_path, din_wave_data, 0, DATA_NUM-1); // vivado读取txt文件
end// 生成时钟
localparam CLKT = 2;
initial beginclk = 0;forever #(CLKT / 2) clk = ~clk;
endinitial beginrstn = 0;din_valid = 0;#(CLKT * 10) rstn = 1;for (int i = 0; i < DATA_NUM; i++) begindin = din_wave_data[i];din_valid = 1;#(CLKT);end#(CLKT * 10) $stop;
endendmodule
五. 仿真验证
仿真工具:Vivado 2020.2 Simulator。
-
输入为sin信号:
-
输入为振荡信号:
-
输入为sinc信号:
六. 工程分享
downSampling 降采样模块 vivado 2020.2工程.7z。
欢迎大家关注我的公众号:徐晓康的博客,回复以下代码获取。
3659
建议复制过去不会码错字!

徐晓康的博客持续分享高质量硬件、FPGA与嵌入式知识,软件,工具等内容,欢迎大家关注。