我是靠谱客的博主 稳重百褶裙,这篇文章主要介绍FPGA如何利用查表法得到某角度所对应的正弦值、余弦值1 实现思路2 具体实现步骤3 结果4 工程文件,现在分享给大家,希望可以做个参考。

FPGA如何利用查表法得到某角度所对应的正弦值、余弦值

  • 1 实现思路
  • 2 具体实现步骤
    • 2.1 MATLAB生成sin.coe文件和cos.coe文件
    • 2.2 将sin.coe和cos.coe文件分别写入ROM核
    • 2.3添加ILA
    • 2.4 新建源文件top,编写源文件
    • 2.5 新建约束文件,编写约束文件
  • 3 结果
    • 3.1 结构图
    • 3.2结果分析
  • 4 工程文件

1 实现思路

1、MATLAB生成不同角度的正弦值sin.coe文件和余弦值cos.coe文件;
2、将sin.coe和cos.coe文件分别写入ROM核;
3、查表得到角度所对应的正弦值、余弦值。

2 具体实现步骤

2.1 MATLAB生成sin.coe文件和cos.coe文件

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
close all; clear all; clc; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % 参数定义 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % L=90; % 采样点数 Quantify_bit=16; % 量化位数 fc=10e6; % 信号频率 fs=65e6; % 采样频率 yinzi=100; % 缩减因子,避免出现 D 必须为小于 flintmax 的非负整数。 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % 产生信号 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% theta=0:1:360; % 度 L=length(theta); % 采样点数 y=cosd(theta); % y=st/max(abs(st)); % 归一化 % y=st/yinzi; yt=round(y*(2^(Quantify_bit-1)-1)); % 12bit量化 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % MATLAB生成coe文件 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %.coe文件中 % 第一行为定义数据格式, 2代表 ROM 的数据格式为二进制。 % 从第 3 行开始到第最后一行,是这个 L(数据长度为1024* ADC_bit(16bit) 大小 ROM 的初始化数据。 % 第一行到倒数第二行的数字后面用逗号,最后一行数字结束用分号。 fid=fopen('cos.coe','w'); % w表示write fprintf(fid,'Memory_Initialization_Radix = 2;rn'); % 二进制 fprintf(fid,'Memory_Initialization_Vector = rn'); for p=1:L B_s=dec2bin(yt(p)+(yt(p)<0)*2^Quantify_bit,Quantify_bit); for q=1:Quantify_bit % 12位,依次判断这12位的数值 if B_s(q)=='1' data=1; else data=0; end fprintf(fid,'%d',data); end % 下面if语句的目的 % 每行数字后面用逗号(,),最后一行数字结束用分号(;) if (p<L) fprintf(fid,',rn'); else fprintf(fid,';rn'); % 分号(;) 结束标志位 end end fclose(fid); figure(1); plot(theta,y);hold on; figure(2); plot(theta,yt);hold on; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % 信号幅度估计 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ST_FFT=fftshift(fft(y)); % 傅里叶变换 P_ST=abs(ST_FFT)/L; % 幅度谱 u_st=max(P_ST); % 得到波束1接收到的信号的幅度值 fprintf('u_st信号的幅度值为%gn',u_st); Y_FFT=fft(y,L); % 傅里叶变换 P_Y=abs(Y_FFT)/L; % 幅度谱 u_y=max(P_Y); % 得到波束1接收到的信号的幅度值 fprintf('u_y信号的幅度值为%gn',u_y); YT_FFT=fft(yt,L); % 傅里叶变换 P_YT=abs(YT_FFT)/L; % 幅度谱 u_yt=max(P_YT); % 得到波束1接收到的信号的幅度值 fprintf('u_yt信号的幅度值为%gn',u_yt); AM=u_yt*yinzi/u_st; % 扩大了2^11次方倍

2.2 将sin.coe和cos.coe文件分别写入ROM核

添加Block Memory Generator,并进行ROM IP核配置
在这里插入图片描述

在这里插入图片描述
port A width表示位宽,选择的是16位;
port A depth表示数据的个数,0度到360度,一度步进,所以有361个数据。

在这里插入图片描述

2.3添加ILA

2.4 新建源文件top,编写源文件

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
`timescale 1ns / 1ps module top( input sys_clk, //50MHz时钟 input rst_n //复位,低电平有效 ); /* 函数功能: 产生余弦值 */ wire [15:0] cos_value; //ROM读出数据 每个数据有12bit reg [8:0] cos_addr; //ROM输入地址 361个数据,需要2^9个地址 //产生ROM地址读取数据 always @ (posedge sys_clk or negedge rst_n) begin if(!rst_n) cos_addr <= 10'd0; else cos_addr <= cos_addr+1'b1; end //实例化ROM rom_cos rom_cos_inst ( .clka (sys_clk ), //inoput clka .addra (cos_addr ), // input wire [8 : 0] addra 361个数据,需要2^9个地址 .douta (cos_value ) // output wire [15 : 0] douta ); /* 函数功能: 产生正弦值 */ wire [15:0] sin_value; //ROM读出数据 每个数据有12bit reg [8:0] sin_addr; //ROM输入地址 1024个数据,需要2^10个地址 //产生ROM地址读取数据 always @ (posedge sys_clk or negedge rst_n) begin if(!rst_n) sin_addr <= 10'd0; else sin_addr <= sin_addr+1'b1; end //实例化ROM rom_sin rom_sin_inst ( .clka (sys_clk ), //inoput clka .addra (sin_addr ), // input wire [8 : 0] addra 361个数据,需要2^9个地址 .douta (sin_value ) // output wire [15 : 0] douta ); /* 函数功能: 查表计算某角度的正弦值、余弦值 */ wire [15:0] data_value_sin; wire [15:0] data_value_cos; wire [8:0] theta; assign theta=9'd300;// 角度 //查表得到余弦值 rom_cos rom_cos_data_inst ( .clka (sys_clk ), //inoput clka .addra (theta ), // input wire [8 : 0] addra 361个数据,需要2^9个地址 .douta (data_value_cos ) // output wire [15 : 0] douta ); //查表得到正弦值 rom_sin rom_sin_data_inst ( .clka (sys_clk ), //inoput clka .addra (theta ), // input wire [8 : 0] addra 361个数据,需要2^9个地址 .douta (data_value_sin ) // output wire [15 : 0] douta ); //实例化逻辑分析仪 ila_0 ila_0_inst ( .clk(sys_clk), // input wire clk .probe0(cos_addr ), // input wire [8:0] probe0 .probe1(cos_value), // input wire [15:0] probe1 .probe2(sin_addr ), // input wire [8:0] probe2 .probe3(sin_value), // input wire [15:0] probe3 .probe4(data_value_sin), // input wire [`15:0] probe4 .probe5(data_value_cos) // input wire [15:0] probe5 ); endmodule

2.5 新建约束文件,编写约束文件

复制代码
1
2
3
4
5
6
7
############## clock and reset define################## create_clock -period 20 [get_ports sys_clk] set_property IOSTANDARD LVCMOS33 [get_ports {sys_clk}] set_property PACKAGE_PIN U18 [get_ports {sys_clk}] set_property IOSTANDARD LVCMOS33 [get_ports {rst_n}] set_property PACKAGE_PIN N15 [get_ports {rst_n}]

3 结果

3.1 结构图

在这里插入图片描述

3.2结果分析

1、ila触发条件
在这里插入图片描述
2、ila结果

在这里插入图片描述需要注意的是:cos_value和sin_value中,不是曲线的点的值都为0。为什么不是完整的正弦波,目标还不知道为什么,但结果应该是正确的。

在这里插入图片描述

3、MATLAB仿真结果
300度的余弦值为16383,正弦值为-28377.(已经量化)。
余弦结果:
在这里插入图片描述
正弦结果:
在这里插入图片描述

为什么看的是序号为301的值,有一个0度,所以是300度对应的是301。

4、结果表明,实验成功。

4 工程文件

工程文件

最后

以上就是稳重百褶裙最近收集整理的关于FPGA如何利用查表法得到某角度所对应的正弦值、余弦值1 实现思路2 具体实现步骤3 结果4 工程文件的全部内容,更多相关FPGA如何利用查表法得到某角度所对应的正弦值、余弦值1内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(110)

评论列表共有 0 条评论

立即
投稿
返回
顶部