(完整版)FPGA查找表法sin函数的实现

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

实验一Sin(x)函数的计算一、实验要求1、系统可以根据输入的角度(或弧度)x,显示相应的sin(x)数值,保证角度精度≤0.1度。2、编辑测试激励文件,进行相关测试,注意测试的完备性。3、根据DE2板资源,设计下载测试方案,并且完成硬件下载测试。二、实验方案本实验要求用FPGA实现角度(0度~360度)的Sin函数的计算,角度的分辨率小于等于0.1度。考虑到实现的简便性,本实验采用查表法实现Sin函数的计算。首先我们用Matlab计算出Sin函数值,然后生成.mif文件。用Matlab生成的.mif文件在Quartus中配置FPGA的Rom。跟具输入的角度值得到其Sin函数值存储的Rom地址,然后根据地址取出Rom中存储的Sin函数值,最后显示在数码管上,从而实现Sin函数的计算。三、实验过程及代码1.Matlab中.mif文件的生成由于输入的角度值为0度~360度,所以计算出的Sin函数值至少有3600个,但由于Sin函数值的对称性,所以实际上存储在FPGA的Rom中的值只需要900个。因此在Matlab中我们设置depth=1024,在这里我们对Sin函数值做了扩大10000倍后四舍五入取整的处理,以便于在Rom中存储,所以在这里我们设置width=14。Matlab中的程序如下:clearall;closeall;clc;t=[0:0.1:90];%角度x=pi*t/180;%弧度数sin_val=sin(x);%sin函数值fid=fopen('sine.mif','wt');%以wt格式打开文件sine.miffprintf(fid,'width=14;\r\n');%设置width=14fprintf(fid,'depth=1024;\n');%设置depth=1024fprintf(fid,'address_radix=uns;\n');fprintf(fid,'data_radix=dec;\n');fprintf(fid,'contentbegin\n');forj=1:901i=j-1;fprintf(fid,'%d:%d;\n',i,round(sin_val(j)*10000));endfprintf(fid,'end;\n');fclose(fid);然后利用宏功能模块编制LPM_ROM存放上面的数据,取名sin_rom.v,用上面编写的sine.mif初始化这个模块,自动生成的Verilog代码。2、顶层模块顶层模块采用VerilogHDL语言编写,保存为sinx.v。输入信号包括一个时钟信号clk,一个复位信号rst_n,一个9位的输入角度的整数部分a,一个4位的输入角度的小数部分b,输出信号包括6个7位的数码管显示信号。由于在Rom中只存储了900个Sin函数值,所以需要对输入的角度进行转换,然后根据转换后的地址对Rom寻址,得在其函数值,在顶层模块中对得到的函数值进行为的的分离,得到函数值的每一位,用于数码管的显示。代码如下:modulesinx(clk,rst_n,a,b,hex0,hex1,hex2,hex3,hex4,hex5);inputclk,rst_n;input[8:0]a;input[3:0]b;output[6:0]hex0,hex1,hex2,hex3,hex4,hex5;reg[3:0]data1,data2,data3,data4,data5;wire[3:0]data0;wire[13:0]q;wire[9:0]addr;reg[13:0]qr;jiaoduU(.clk(clk),.a(a),.b(b),.addr(addr),.fh(data0));sin_romsin_rom_inst(.address(addr),.clock(clk),.q(q));reg[2:0]num;always@(posedgeclkornegedgerst_n)beginif(!rst_n)beginnum=3'd0;qr=14'd0;endelsebeginqr=q;num=num+1'b1;case(num)3'd1:data1=qr%4'd10;3'd2:data2=(qr/4'd10)%4'd10;3'd3:data3=(qr/8'd100)%4'd10;3'd4:data4=(qr/10'd1000)%4'd10;3'd5:data5=(qr/10'd10000);default:;endcaseif(num==3'd6)num=3'd0;endendledled0(rst_n,data0,hex0);ledled1(rst_n,data1,hex1);ledled2(rst_n,data2,hex2);ledled3(rst_n,data3,hex3);ledled4(rst_n,data4,hex4);ledled5(rst_n,data5,hex5);endmodule3、输入角度的转换由于在Rom中只存储了900个Sin函数值,所以需要对输入的角度根据其所在的象限得到其Sin函数值的Rom地址,同时给出Sin函数值的符号。在这里输入的角度值分为整数和小数部分,整数部分从0~360共360个值,所以在这里输入的整数部分a定义9位,用9个开关输入。小数部分从0~9共10个值,在这里输入的小数部分b定义4位,用4个开关输入。程序中addr是Sin函数值2的储存地址,fh代表的函数值的符号。modulejiaodu(clk,a,b,addr,fh);inputclk;input[8:0]a;input[3:0]b;output[9:0]addr;output[3:0]fh;reg[3:0]fh;reg[9:0]addr;reg[12:0]c;always@(posedgeclk)beginc=a*4'd10+b;if(2700c=3600)beginaddr=3600-c;fh=4'ha;endelseif(1800c=2700)beginaddr=c-1800;fh=4'ha;endelseif(900c=1800)beginaddr=1800-c;fh=4'hb;endelsebeginaddr=c;fh=4'hb;endendendmodule4、数码管显示根据输入的data_in的值别对sm_db赋值用于数码管的显示。moduleled(rst_n,data_in,sm_db);inputrst_n;input[3:0]data_in;output[6:0]sm_db;reg[6:0]sm_db;always@(data_inorrst_n)beginif(!rst_n)sm_db=7'b1000000;elsebegincase(data_in)4'h0:sm_db=7'b1000000;4'h1:sm_db=7'b1111001;4'h2:sm_db=7'b0100100;4'h3:sm_db=7'b0110000;4'h4:sm_db=7'b0011001;4'h5:sm_db=7'b0010010;4'h6:sm_db=7'b0000010;4'h7:sm_db=7'b1111000;4'h8:sm_db=7'b0000000;4'h9:sm_db=7'b0011000;4'ha:sm_db=7'b0111111;4'hb:sm_db=7'b1111111;default:;endcaseendendendmodule四、实验体会通过此次实验,我系统的了解了FPGA系统设计的全过程。学会了用verilog语言描述电路,学会了利用宏功能模块编制LPM_ROM存放数据,并用编写的.mif文件初始化这个模块。在这过程中我遇到了一些问题,但通过努力解决了。这让我明白了我们要有随时面对突发问题的心理准备。

1 / 6
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功