设为首页 加入收藏

TOP

目标反射回波检测算法及其FPGA实现 之二:互相关/卷积/FIR电路的实现(二)
2019-08-24 00:06:57 】 浏览:277
Tags:目标 反射 检测 算法 及其 FPGA 实现 之二 相关 卷积 /FIR 电路
启动信号,下降启动一轮操作
8 output[3:0] coe_rom_addr;//参与卷积的固定信号rom地址信号 9 output[3:0] rd_data_dpram_addr;//读取双口RAM缓冲中数据的地址信号 10 output acc_clr; //累加器清零信号,高电平用于清除MAC电路的结果,准备下一次卷积计算 11 output wren; //写使能信号,每个start周期向下一个DPRAM的缓冲(本级的缓冲区也可以使用这个写入信号)里写入一个新数据的使能信号 12 output[3:0] wr_data_dpram_addr;//写入DPRAM缓冲区的新数据的地址线 13 output flag;//标志信号,表示卷积电路在工作 14 output mac_en;//乘加器的使能信号,为1时每个上升沿执行乘加 15 wire flag;//状态标志,为1时表示正在进行卷积操作,否则表示没有操作 16 reg[9:0] flag_cnt;//状态计数器,start信号到来后还是计数,当其大于一定值后切换标志 17 reg[3:0] current_pt;//当前位置指针,会在每次start到来卷积后加一,以指向下一次数据缓冲器的首地址 18 assign acc_clr = start; 19 assign mac_en = ((flag_cnt[9:0]>=10'd3)&(flag_cnt[9:0]<=10'd20))? 1'b1 : 1'b0;//只有当flag_cnt等于3时系数和dpram才能读出所需的数据,注意读锁存器造成的一个周期的延迟。 20 ///////向后续卷积节传递最老的一个数据的控制信号 21 assign wren = (flag_cnt[9:0] == 10'd20)? 1'b1 : 1'b0;//这里要看仿真时序图才能明白,flag_cnt=20的周期刚好读出本轮以后不再使用的数据 22 assign wr_data_dpram_addr[3:0] = current_pt[3:0]; 23 always @ (posedge start or negedge rst_n) 24 begin 25 if(!rst_n) 26 current_pt[3:0] <= 4'b1111;//复位后为最大值,第一个start脉冲使其从0开始 27 else 28 current_pt[3:0] <= current_pt[3:0] + 4'd1;//首地址缓冲器,会在每次采样(或start)信号到来后加一,为下次输入新数据移动缓冲器做好准备 29 end 30 assign flag = ((flag_cnt[9:0]>=10'd2)&(flag_cnt[9:0]<=10'd20))? 1'b1 : 1'b0; 31 always @ (negedge clk or posedge start)//注意为了让flag从clk下降沿开始,以上升沿为每个周期的中心,这里用用flag的下降沿计数 32 begin 33 if(start) 34 begin 35 flag_cnt[9:0] <= 10'd0; 36 end 37 else begin 38 if(flag_cnt[9:0] <= (10'd16 + 10'd1 + 10'd3)) 39 //计到15再加1,则一共1-16个脉冲;加1是为了留出第一个时钟周期作为dpram的地址潜伏期;加2是为了等待乘法器的潜伏期(潜伏期为3,但最后一个不用乘加) 40 begin 41 flag_cnt[9:0] <= flag_cnt[9:0] +1'd1; 42 end 43 else 44 begin 45 flag_cnt[9:0] <= flag_cnt[9:0]; 46 end 47 end 48 end 49 pset_addr_cnt i_rd_addr_cnt(//例化读缓冲当前地址计数器 50 .rst_n(rst_n), 51 .load(!flag),//每产生一个启动信号,就要重新对首地址置新值 52 .clk(clk), 53 .pre_value(current_pt), 54 .addr_cnt(rd_data_dpram_addr) 55 ); 56 addr_cnt i_coe_rom_addr_cnt(//例化系数地址产生计数器 57 .en(flag), 58 .clk(clk), 59 .addr_cnt(coe_rom_addr) 60 ); 61 endmodule 62 63 module addr_cnt(en,clk,addr_cnt); 64 //本模块产生4位计数值,作为地址产生器 65 input en;//高电平有效 66 input clk; 67 output[3:0] addr_cnt; 68 reg[3:0] addr_cnt; 69 always @ (negedge clk or negedge en)//为了使地址再时钟下降沿产生,上升沿位于数据中央,clk使用了下降沿 70 begin 71 if(!en) 72 addr_cnt[3:0] <= 4'd0; 73 else 74 addr_cnt[3:0] <= addr_cnt[3:0] + 4'd1; 75 end 76 endmodule 77 78 //带预置功能的地址计数器,4位 79 module pset_addr_cnt(rst_n,load,clk,pre_value,addr_cnt); 80 input rst_n; 81 input load;//load高电平时同步加载初值 82 input clk; 83 input[3:0] pre_value;//输入的预置初值 84 output[3:0] addr_cnt;//计数输出 85 reg[3:0] addr_cnt; 86 always @(negedge clk or negedge rst_n)//为了使地址再时钟下降沿产生,上升沿位于数据中央,clk使用了下降沿 87 begin 88 if(!rst_n) 89 addr_cnt[3:0] <= 4'd0;//pre_value[3:0]; 90 else begin 91 if(load == 1'b1) 92 addr_cnt[3:0] <= pre_value[3:0]; 93 else 94 addr_cnt[3:0] <= addr_cnt[3:0] + 4'd1; 95 end 96 end 97 endmodule View Code

    上述代码中,需要特别注意的是数据缓冲区“当前地址寄存器”current_pt[3:0],它会在每个采样点的计算卷积运算开始之前,在启动信号start驱动下自动加一,随后current_pt[3:0]作为初值加载给数据缓冲区读地址寄存器/计数器“rd_data_dpram_addr”,从而起到了修正环形队列首地址的目的。这一操作保证了数据缓冲区的首地址指针总是指向环形队列数据结构中最新的数据。

    另外,写使能信号wren是每个卷积节向后级的卷积节输出的控制信

首页 上一页 1 2 3 4 5 下一页 尾页 2/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇利用ZYNQ SOC快速打开算法验证通.. 下一篇接口与协议学习笔记-USB协议_USB2..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目