作者:桂。

时间:2018-05-10  2018-05-10  21:03:44

链接:http://www.cnblogs.com/xingshansi/p/9021919.html 


前言

主要记录常用的基本模块。

一、模块汇总

  • 17- 自相关操作xcorr

实现思路主要参考:工程应用中的自相关操作,根据推导可以看出,自相关操作涉及的基本操作有:复数相乘、递归【自回归,IIR等都需要该操作】。

涉及到具体模块:1)10- 共轭复数相乘模块; 2)11- 复数延拍模块; 3)递归 —> 1- 3个数组合加、减运算(分I\Q分别调用)。

路径:印象笔记:0019/015 

MATLAB仿真(实际操作中,N除不除->移位,差别不大):

clc;clear all;close all;
fs = 960e6;
f0 = 20e6;
t = [0:255]/fs;
sig = [zeros(1,384),exp(1j*(2*pi*t*f0+pi/4)),zeros(1,384)];
sig = awgn(sig,5);
%自相关
N = 64;
k = 1;
R = zeros(1,length(sig));
for i = N+1:length(sig)-k
    R(i) = R(i-k) + 1/N * (sig(i)*conj(sig(i+k)) - sig(i-N)*conj(sig(i-N+k)));
end
figure()
subplot 211
plot(abs(sig)/max(abs(sig)));
subplot 212
plot(abs(R)/max(abs(R)));

  Xilinx 常用模块汇总(verilog)【03】

verilog【给出完整分析、实现、仿真过程】

不失一般性,以k=1为例,

理论分析: 

Xilinx 常用模块汇总(verilog)【03】

用到的基本模块:1)10- 共轭相乘;2)11- 复数延拍;3)1- 3路加减运算

硬件实现

其中延拍,也可调用原语:SRL(移位链 )+ FDRE的思路:

//Shift:SRL[A3A2A1A0] + 2
parameter width = 16; //data width
genvar ii;

generate
    for(ii = 0; ii < width; ii++)
    begin:delay
        
//            (* HLUTNM = ii *)
        SRL16E #(
            .INIT(16'h0000) // Initial Value of Shift Register
            ) SRL16E_u1 (
            .Q(out_cache[ii]),       // SRL data output
            .A0(1'b0),     // Select[0] input
            .A1(1'b1),     // Select[1] input
            .A2(1'b1),     // Select[2] input
            .A3(1'b0),     // Select[3] input
            .CE(1'b1),     // Clock enable input
            .CLK(clk),   // Clock input
            .D(ddata[ii])        // SRL data input
            );    

FDRE #(
        .INIT(1'b0) // Initial value of register (1'b0 or 1'b1)
        ) FDRE_u1 (
        .Q(out[ii]),      // 1-bit Data output
        .C(clk),      // 1-bit Clock input
        .CE(1'b1),    // 1-bit Clock enable input
        .R(sclr),      // 1-bit Synchronous reset input
        .D(out_cache[ii])       // 1-bit Data input
        ); 
end
endgenerate

 细节可参考scm.pdf /hdl.pdf:

 Xilinx 常用模块汇总(verilog)【03】

功能仿真

 1)生成仿真数据:

clc;clear all;close all;
fs = 960e6;
f0 = 20e6;
t = [0:255]/fs;
sig = [zeros(1,384),sin(2*pi*t*f0+pi/4),zeros(1,384)];
sig = awgn(sig,10);
L = length(sig);
N = 17;
t0 = [0:L-1]/fs;
y_n = round(sig*(2^(N-2)-1));
%write data
fid = fopen('sig.txt','w');
for k=1:length(y_n)
    B_s=dec2bin(y_n(k)+((y_n(k))<0)*2^N,N);
    for j=1:N
        if B_s(j)=='1'
            tb=1;
        else
            tb=0;
        end
        fprintf(fid,'%d',tb);
    end
    fprintf(fid,'\r\n');
end

fprintf(fid,';');
fclose(fid);

  2)仿真结果:

MATLAB测试数据:

Xilinx 常用模块汇总(verilog)【03】

VIVADO输出结果:

  Xilinx 常用模块汇总(verilog)【03】 

从仿真结果可以看出,二者完全一致,Xcorr模块有效。【X点自相关,仅需要修改共轭相乘结果的延迟拍数即可,这便实现了参数化。】

代码路径:印象笔记0019/015Xcorr

  • 18- 数据速率转化模块

路径:印象笔记-1/0019/017

跨时钟域,对于moni-bit,可用打2拍的思路,即定义两级寄存器,以降低亚稳态概率;对于multi-bits,目前跨时钟域的数据传输,常用的两个基本思路是:1)异步FIFO;2)异步 dual port RAM 。(ug473.pdf)

1)FIFO(first in first out)

Xilinx 常用模块汇总(verilog)【03】

 更多细节可参考:印象笔记-3-FPGA/024-FIFO核使用,以及博文:基础003_V7-Memory Resources

要点1:最小深度计算

要点2:数据传输转换关系:输入的数据量理论上需要小于等于输出的数据量。

FIFO多与高速接口配合使用。

2)Dual port RAM

关于IP核的使用,可参考:印象笔记-3/FPGA/025-双端口RAM参数设置,双端口RAM与FIFO最大的区别在于存在读、写地址,如果数据存在偏移,可以很方便地修正偏移量。 

应用举例:现有两路数据存在偏移,希望将二者对齐,以Dual port RAM为例,调用XILINX 的 IP核,细节参考博文:DUAL PORT RAM应用实例 

  • 19- 卷积模块(convolution)

路径:1/0019/019

分析:卷积的理论细节及多种实现思路,可参考博文:信号处理——卷积(convolution)的实现

这里只给出一种普适的思路,且仅考虑实数情况:对于复数域C,拆解为实、虚部即可。定义序列h:

Xilinx 常用模块汇总(verilog)【03】

对应卷积原理:

Xilinx 常用模块汇总(verilog)【03】

实现的思路是:1)直接延拍+寄存器,2)累加操作(累加长度等于最短序列长度,此处为M),即可完成卷积。

延拍 + 寄存器

delay_all.sv

`timescale 1ns/1ps
/*
Function: DPRAM for data aligned
Author: Gui.
Data: 2018年5月14日16:31:09
*/
/*
 等价于: dout <= {dout[Num-2:0],din};  // SliceM without rst
*/
module delay_all(din, clk, sclr, dout);
parameter datwidth = 17;
parameter Num = 8;

input [datwidth-1:0] din;
input clk;
input sclr;
output [Num-1:0][datwidth-1:0] dout;
//
logic [Num-1:0][datwidth-1:0] dat;

genvar ii;
generate 
for (ii = 1;ii < Num; ii++)
begin:delayall
    delay #(
        .datwidth(datwidth)
    )
    u1(
        .din(dat[ii-1]),
        .clk(clk),
        .sclr(sclr),
        .dout(dat[ii])
    );
end
endgenerate

always @(posedge clk)
if(sclr)
begin
    dat <= 0;
end 
else
begin
    dat[0] <= din;
end 

assign dout = dat;

endmodule
View Code

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2019-07-05
  • 2022-12-23
  • 2022-12-23
  • 2021-11-26
猜你喜欢
  • 2021-10-24
  • 2022-12-23
  • 2022-12-23
  • 2021-10-02
  • 2021-11-21
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案