设为首页 加入收藏

TOP

目标反射回波检测算法及其FPGA实现 之二:互相关/卷积/FIR电路的实现(三)
2019-08-24 00:06:57 】 浏览:288
Tags:目标 反射 检测 算法 及其 FPGA 实现 之二 相关 卷积 /FIR 电路
号——它在数据缓冲区读出最老数据的同时,使能后级卷积节数据缓冲区的写入功能,从而将前级卷积节中数据缓冲中最老数据作为最新信号存入后级卷积节数据缓冲区。 

三、卷积节中的两个存储以及乘加电路的实现

    正如我在本文第一部分“总体电路结构”中介绍的,每个卷积节中含有两个有M4K块实现的存储块:绿色部分是存储输入数据s[k]的缓冲区,和蓝色部分的卷积系数h[k]的存储器。分别采用Quartus-II中的MegaWizard实现,其结构如下图所示。

图2 双端口数据缓冲区的结构示意图

    数据宽度为16位,是由ADC的位数12bits决定的。地址宽度为4位则是由16(即N/L的值)决定的。值得注意点是该双口RAM的输入和输出端各有一级D触发器构成的缓冲器,在规划控制时序时需要注意它们造成的数据潜伏期的增加。 

 

图3 系数存储器的结构示意图

    系数存储器只要设计为单口ROM即可满足需要,但为了使系数的初始化更加方便,我将它设计为双口RAM结构。这将允许系统在FPGA上电后,执行一个系数存储器初始化过程,以将系数从双口RAM的写入端口分时写入各个卷积节中。系数初始化的过程和电路设计将在本博文的后面详述。

    每个卷积节中的乘加器,将在两次采样间隔间实现16(即N/L的值)次MAC操作,采用MageWizard实现的MAC结构如下所示。

 

图4 乘加器结构示意图

    为防止溢出,乘加器模块输出宽度取了40bits,实际上每个卷积节只执行16次乘加,只需36bits就可以保证不溢出。 

四、卷积节的顶层连接

   为了将上述卷积节控制电路、数据缓冲器、系数存储器和乘加器连接为图1中的一个完整卷积节,还需要一个顶层设计文件如下。

 1 module CONV_SER16(clk,a,en,coe_data_in16,wr_coe_addr,wr_coe_clk,wr_coe_en,start,shft_out_dp_data,s_latch);
 2 //本模块例化了一个乘加模块,采用串行方式实现16阶卷积/FIR运算,
 3 //由start信号启动,持续时间约为20个clk周期。a为不断送入的被卷积数据流信号,s为卷积后输出的数据流,这两个流信号都被start同步
 4 //在启动之前需要由系数配置模块向本节系数存储器配置系数,配置完成后通过en和start启动本模块滤波
 5 input clk;//外部送入的100M左右时钟
 6 input[15:0] a;//输入数据
 7 input en;//高电平使能,由系数初始化模块控制,初始化完成后使能所有计算模块
 8 input[15:0] coe_data_in16;//从本模块以外写入的配置系数
 9 input[3:0] wr_coe_addr;//从本模块以外写入的配置系数地址
10 input wr_coe_clk;//从本模块以外输入的系数配置时钟
11 input wr_coe_en;//从本模块以外输入的系数配置使能端
12 input start;
13 output[39:0] s_latch;//经过锁存的卷积/FIR结果数据
14 output[15:0] shft_out_dp_data;//从DPRAM中读取的数,在本模块中参与MAC,同时输出给下一个卷积节作为输入
15 wire[39:0] s;
16 wire[3:0] coe_rom_addr;//参与卷积的固定信号rom地址信号
17 wire[3:0] rd_data_dpram_addr;//读取双口RAM缓冲中数据的地址信号
18 wire[3:0] wr_data_dpram_addr;//写入DPROM缓冲的地址信号
19 wire[15:0] coe_value;//读取系数值的连线
20 wire[15:0] dp_rd_data;//从DPRAM中读取的准备参与乘加的被卷积数
21 wire acc_clr;        //累加器清零信号,高电平用于清除MAC电路的结果,准备下一次卷积计算
22 wire flag;    //标志信号,表示卷积电路在工作
23 wire wren;    //DPROM缓冲写使能,高电平使能
24 wire clk;//100M时钟
25 wire mac_en;//乘加器使能信号
26 assign shft_out_dp_data[15:0] = dp_rd_data[15:0];//从DPRAM中读取的数,在本模块中参与MAC,同时输出给下一个卷积节作为输入
27 
28 conv_ctlr i_conv_ctlr(
29                         .rst_n(en),//低电平复位信号,可以复位首地址指针
30                         .clk(clk),//工作时钟信号
31                         .start(start),//启动一次控制逻辑输出的启动信号,下降启动一轮操作
32                         .coe_rom_addr(coe_rom_addr),//参与卷积的固定信号rom地址信号
33                         .rd_data_dpram_addr(rd_data_dpram_addr),//读取双口RAM缓冲中数据的地址信号
34                         .acc_clr(acc_clr),        //累加器清零信号,高电平用于清除MAC电路的结果,准备下一次卷积计算
35                         .wren(wren),    //写使能信号,每个start周期向DPRAM的缓冲里写入一个新数据的使能信号
36                         .wr_data_dpram_addr(wr_data_dpram_addr),//写入DPRAM缓冲区的新数据的地址线
37                         .flag(flag),//标志信号,表示卷积电路在工作
38                         .mac_en(mac_en)
39                         );
40 MAC1616_40 i_mac(//例化乘加模块
41         .aclr3(acc_clr),
42         .clock0(!clk),//让乘加发生在flag为高电平阶段的clk的下降沿,因为读出数值发生在上升沿
43         .dataa(dp_rd_data),
44         .datab(coe_value),
45         .ena0(mac_en),//乘加使能信号
46         .result(s)
47         );
48 DUAL_PORT_BUFF i_dpram_buff(//例化存储缓冲区的PDRAOM
49                     .data(a),//输入数据
50                     .inclock(clk),
51                     .outclock(clk),
52                     .rdaddress(rd_data_dpram_addr),
53                     .wraddress(wr_data_dpram_addr),
54                     .wren(wren),
55                     .q(dp_rd_data)
56                     );        
57 coe_dpram    i_coe_dpram (//例化每一节的系数dpram,它负责在复位后接收系数池中初始化的数据
58 //这个例化对象的写入侧外接,用初始化器写入数据,读出端接在本模块中,负责向乘加器输出系数
59     .data ( coe_data_in16 ),//从本模块外部写入系数的写入端
60     .rdaddress ( coe_
首页 上一页 1 2 3 4 5 下一页 尾页 3/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇利用ZYNQ SOC快速打开算法验证通.. 下一篇接口与协议学习笔记-USB协议_USB2..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目