項目簡述
滑動累加器在算法的實現過程中經常碰見,最典型的就是均值濾波。相信大家對滑動累加的概念已經有了不錯的掌握,其實就是給原始數據加一個窗然後求這個窗裏面所有數據之和。本次實驗我們先使用MATLAB實現滑動累加器,然後使用VIVADO實現滑動累加器,最後將兩組生成的數據在MATLAB中對比從而相互驗證我們實驗的正確性。
本次實驗所用到的軟硬件環境如下:
1、VIVADO 2019.1
2、Modelsim 10.7
3、MATLAB 2015b
MATLAB代碼
因爲這次的項目沒有任何算法的成分在裏面,所以我們不再對理論部分多加贅述,這裏直接給出相應的代碼。
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函數一步生成。
FPGA代碼
FPGA邏輯代碼
因爲過程比較簡單,我們這裏直接給出相應的代碼:
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
代碼的核心模塊是下面的部分,大家只需要把這一部分搞透徹那麼整個邏輯便非常簡單。
FPGA測試代碼
上面邏輯代碼的測試代碼如下:
`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測試代碼
我們將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]、電子發燒友學院
總結
創作不易,認爲文章有幫助的同學們可以關注、點贊、轉發支持。爲行業貢獻及其微小的一部分。或者對文章有什麼看法或者需要更近一步交流的同學,可以加入下面的羣: