首页 > 编程知识 正文

verilog 数组,verilog是什么

时间:2023-05-03 13:02:14 阅读:141992 作者:900

我的另一个博客: Verilog功能模块——滑动平均值(使用寄存器组) ) ) ) ) ) ) ) )。

两者用不同的方法实现相同的功能,

适用于使用FIFO时寄存器资源少,值n大的情况。

使用寄存器组不需要额外的IP,更简单,但适用于消耗寄存器资源多、值n小(一般为1024以下)的情况。

一.模块功能和应用场景模块功能:对输入信号取滑动平均值。

滑动平均值:又名移动平均值,基于简单的平均值,通过按顺序每次增加新的数据,减去旧的数据求出移动平均值,消除偶然的变动因素。

参考百度百科:滑动平均法

应用场景:

在对平均值发生变化但变化速度慢的信号求出平均值的数字滤波器中,表示利用去除信号的直流偏移的2 .框图和说明参数n求出n点的平均值,参数DIN_WIDTH控制输入信号位宽。

注意:

din和din_valid相对应的clk应当是din和din_valid生成的时钟。 这是为了确保,有效数据din_valid只有一个时钟周期的高电平n是2的n次方。 例如,128(27 )、256 (28 )、512 )、29 )通常,比2~3个信号周期大的分数,这里的ac_signal为din - moving_avg,为无DC偏置的交流信号该模块需要与贯穿前缀的单时钟FIFO组合使用,该FIFO的时钟需要与该模块时钟相同的FIFO深度和位宽,分别与模块参数n和DIN_WIDTH一致

模块IP参数配置接口:

3 .模块代码/* * @ author : xudakang * @ email : xudakang _ up @ QQ.com * @ date :2021-04-1416336014336046 * @ lassasasang @ last edit time :2021-05-1922336034336024 * @ filename : getmovingavg.SV * @ description 3:是带符号的切片模块功能:求出n个带符号数的滑动平均值*思路:1。 求出n个数之和,除以n,得到n个数的平均值2。 N 1个数到来后,从总和中除去第1个再加上N 1个,求出平均值就是第1~N 1个数的平均值。 这样,求*/modulegetmovingavg # (parameter n=1024,//) n个平均值,n必须等于2的n次方,例如512,1024。 参数din _ width=24//输入数据的位宽(outputlogicsigned (din _ width-1: ) moving_avg,outputlogicsigned output logic ac_signal_valid、inputlogicsigned [ din _ width-1: ] din、input logic din_valid、inputlogicsigned output logic fwft_fifo_rd_en,inputlogicfwft _ fif ft outputlogicsigned [ din _ width-1: ] fwft _ FIFO _ din,din logic signed [ din _ width-1: ] din _ R2; always_ff @(posedge clk ) begin din_r1=din; din_r2=din_r1; endlogic din_valid_r1; logic din_valid_r2; always_ff @(posedge clk ) begin din_valid_r1=din_valid; din_valid_r2=din_valid_r1; end//信号同步-------信号同步

储N个数 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++logic [$clog2(N) : 0] din_cnt;always_ff @(posedge clk) begin // FIFO写入计数 if (~rstn) din_cnt <= '0; else if (din_valid_r2 && din_cnt[$clog2(N)] != 1) din_cnt <= din_cnt + 1'b1; else din_cnt <= din_cnt;end// fwft FIFO输出always_comb begin fwft_fifo_din = din_r2; fwft_fifo_wr_en = din_valid_r2; fwft_fifo_rd_en = din_cnt[$clog2(N)] == 1 && din_valid_r2;end//> FWFT FIFO存储N个数 ------------------------------------------------------------//< 求和 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++logic signed [$clog2(N)+DIN_WIDTH-1 : 0] sum;always_ff @(posedge clk) begin if (~rstn) sum <= '0; else if (din_valid_r2) if (din_cnt[$clog2(N)] != 1) sum <= din_r2 + sum; // 先减再加,没有位宽溢出的风险 else sum <= (din_r2 - fwft_fifo_dout) + sum; else sum <= sum;end//< 求和 ------------------------------------------------------------//> 输出平均值 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++always_ff @(posedge clk) begin if (~rstn) moving_avg <= '0; else moving_avg <= sum[$clog2(N)+DIN_WIDTH-1 : $clog2(N)]; // 取高数据位end//> 输出平均值 ------------------------------------------------------------//< 求AC信号 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++always_ff @(posedge clk) begin if (~rstn) ac_signal <= '0; else if (din_valid_r2) ac_signal <= din_r2 - moving_avg; else ac_signal <= ac_signal;endalways_ff @(posedge clk) begin if (~rstn) ac_signal_valid <= '0; else ac_signal_valid <= din_valid_r2;end//< 求AC信号 ------------------------------------------------------------endmodule 四. testbench /* * @Author : Xu Dakang * @Email : XudaKang_up@qq.com * @Date : 2021-04-21 14:29:04 * @LastEditors : Xu Dakang * @LastEditTime : 2021-05-20 00:32:15 * @Filename : getMovingAvg_tb.sv * @Description : testbench of getMovingAvg*/module getMovingAvg_tb;timeunit 1ns;timeprecision 1ps;localparam DIN_WIDTH = 24;logic [DIN_WIDTH-1 : 0] ac_signal;logic ac_signal_valid;logic [DIN_WIDTH-1 : 0] din;logic din_valid;logic [DIN_WIDTH-1 : 0] moving_avg;logic clk;logic rstn;getMovingAvg_system_wrapper getMovingAvg_system_wrapper_inst (.*);// 生成时钟localparam CLKT = 2;initial begin clk = 0; forever #(CLKT / 2) clk = ~clk;end// 导入输入波形文件 Vivado只能识别绝对路径 注意修改!!!string din_path = "F:/OneDrive/VivadoPrj/getMovingAvg_useFIFO/getMovingAvg_useFIFO.srcs/sim_1/new/sin+0.5.txt"; // 可选 sin sin+0.5 sin-0.5 sin+1.0 sin-1.0localparam DATA_NUM = 10240; // 数据量, 也就是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文件endint cnt;initial begin rstn = 0; din_valid = 0; #(CLKT * 10) rstn = 1; for (int i = 0; i < DATA_NUM; i++) begin din = din_wave_data[i]; cnt++; din_valid = 1; #(CLKT); // din_valid = 0; // #(CLKT * ({$random} % 12)); end din_valid = 0; #(CLKT * 10) $stop;endendmodule 五. 仿真验证

仿真工具:Vivado 2020.2 Simulator。

lock Design如下图,注意:

模块的参数N与FIFO深度保持一致模块数据位宽与FIFO数据位宽保持一致FIFO必须是FWFT类型的

输入为(sinx + 0.5)信号:

输入为(sinx - 0.5)信号:

输入为(sinx + 1.0)信号:

输入为(sinx - 1.0)信号:

六. 工程分享

getMovingAvg_useFIFO 取滑动平均值模块(使用FIFO) vivado 2020.2工程.7z

链接:https://pan.baidu.com/s/1YL0q2i2UfWdlCGSN7GOgnQ
提取码:uxxn

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。