滑动累加器在算法的实现过程中经常碰见,最典型的就是均值滤波。相信大家对滑动累加的概念已经有了不错的掌握,其实就是给原始数据加一个窗然后求这个窗里面所有数据之和。本次实验我们先使用MATLAB实现滑动累加器,然后使用VIVADO实现滑动累加器,最后将两组生成的数据在MATLAB中对比从而相互验证我们实验的正确性。
本次实验所用到的软硬件环境如下:
1、VIVADO 2019.1
2、Modelsim 10.7
3、MATLAB 2015b
因为这次的项目没有任何算法的成分在里面,所以我们不再对理论部分多加赘述,这里直接给出相应的代码。
clc;
clear all;
PATH_SPD_RANGE = 6;
fid1 = fopen('data_in_fix.txt','r');
DataIn = fscanf(fid1,'%d');
h_path_pow_fix = DataIn.';
h_path_pow_win = filter(ones(1,2*PATH_SPD_RANGE+1),1,h_path_pow_fix);
h_path_pow_win = h_path_pow_win(2*PATH_SPD_RANGE+1:end);
h_path_pow_win_fix = h_path_pow_win;
fid1 = fopen('mb_pow_win.txt','w');
fprintf(fid1,'%d\n',h_path_pow_win_fix);
代码就是如此简单,可以使用filter函数一步生成。
因为过程比较简单,我们这里直接给出相应的代码:
module pow_win
(
input sclk ,
input rst_n ,
input [15:0] POUT ,
input POUT_EN ,
output wire [19:0] pow_win_data ,
output reg pow_win_en
);
//========================================================================================\
//**************Define Parameter and Internal Signals**********************************
//========================================================================================/
parameter MAX_DATA = 13'd523 +4'd12;
reg [12:0] read_cnt ;
reg h_path_pow_fix_en ;
reg [15:0] shift_h_path_pow[12:0] ;
reg [19:0] sum_pow_win ;
reg [19:0] sum_pow_win_T ;
reg [15:0] pow_mid ;
reg [15:0] fix_h_path_pow ;
reg [15:0] fix_shift_h_path_pow_12 ;
integer j ;
//========================================================================================\
//************** Main Code **********************************
//========================================================================================/
assign pow_win_data = sum_pow_win;
always @(posedge sclk)
h_path_pow_fix_en <= POUT_EN;
always @(posedge sclk)
if(rst_n == 1'b0)
read_cnt <= MAX_DATA+3'd5;
else if(~h_path_pow_fix_en&&(POUT_EN))
read_cnt <= 13'd0;
else if(read_cnt==MAX_DATA+3'd5)
read_cnt <= read_cnt;
else
read_cnt <= read_cnt + 1'b1;
always @(posedge sclk)begin
shift_h_path_pow[0] <= POUT;
for (j=0; j<4'd12; j=j+1)
shift_h_path_pow[j+1] <= shift_h_path_pow[j];
end
always @(posedge sclk)
fix_h_path_pow <= POUT;
always @(posedge sclk)
fix_shift_h_path_pow_12 <= shift_h_path_pow[12];
always @(posedge sclk)
if(read_cnt<=13'd12&&h_path_pow_fix_en)
pow_mid <= {fix_h_path_pow};
else
pow_mid <= {fix_h_path_pow}-{fix_shift_h_path_pow_12};
always @(posedge sclk)
if(rst_n == 1'b0)
sum_pow_win_T <= 0;
else if(read_cnt == 13'd0)
sum_pow_win_T <= 0;
else
sum_pow_win_T <= sum_pow_win_T + {{4{pow_mid[15]}},pow_mid};
always @(posedge sclk)
if(rst_n == 1'b0)
sum_pow_win <= 0;
else if(sum_pow_win_T[19] == 1'b1)
sum_pow_win <= {1'b0,{(15){1'b1}}};
else
sum_pow_win <= sum_pow_win_T;
always @(posedge sclk)
if(read_cnt>=13'd14 && (read_cnt<=MAX_DATA-10))
pow_win_en <= 1'b1;
else
pow_win_en <= 1'b0;
endmodule
代码的核心模块是下面的部分,大家只需要把这一部分搞透彻那么整个逻辑便非常简单。
上面逻辑代码的测试代码如下:
`timescale 1ns / 1ps
module tb_pow_win;
reg sclk ;
reg rst_n ;
reg [15:0] POUT ;
reg POUT_EN ;
reg POUT_EN_delay1;
wire [19:0] pow_win_data;
wire pow_win_en;
initial begin
sclk =1'b0;
rst_n = 1'b0;
POUT_EN = 1'b0;
repeat(10) @(posedge sclk)#1;
rst_n = 1'b1;
POUT_EN = 1'b1;
repeat(524) @(posedge sclk)#1;
POUT_EN=1'b0;
end
always @(posedge sclk)
begin
POUT_EN_delay1 <= POUT_EN;
end
integer fid1;
initial
begin
fid1 = $fopen("data_in_fix.txt","r");
end
always@(posedge sclk)
begin
if(POUT_EN)
$fscanf(fid1,"%d",POUT);
end
integer fid4;
initial
begin
fid4 = $fopen("ms_pow_win.txt","w");
end
always@(posedge sclk)
begin
if(pow_win_en)
$fwrite(fid4,"%d\n",pow_win_data);
end
always #10 sclk = ~sclk;
pow_win uut(
.sclk (sclk ),
.rst_n (rst_n ),
.POUT (POUT ),
.POUT_EN (POUT_EN_delay1 ),
.pow_win_data (pow_win_data ),
.pow_win_en (pow_win_en )
);
endmodule
整个代码非常简单,大家直接学习代码即可,这里博主没什么多说的。
我们将MATLAB中的生成的代码与Modelsim中生成的代码相互对比,从而验证我们实验的正确性。代码如下:
clc;
clear all;
fid1 = fopen('mb_pow_win.txt','r');
DataIn = fscanf(fid1,'%d');
fid2 = fopen('ms_pow_win.txt','r');
Dataout = fscanf(fid2,'%d');
real_data_result = sum(abs(Dataout-DataIn));
运行结果如下:
上面的结果意味着MATLAB与Modelsim两者生成的数据完全一致,从而验证了我们实验的正确性。
[1]、电子发烧友学院
创作不易,认为文章有帮助的同学们可以关注、点赞、转发支持。为行业贡献及其微小的一部分。或者对文章有什么看法或者需要更近一步交流的同学,可以加入下面的群: