原创 培训五(DDS信号源)

2011-7-26 21:03 2273 9 9 分类: FPGA/CPLD

/*DDS信号源
U1:key_code  port map(clk,rst,key,seg_data,sel,addr);
U2:add32     port map(clk,rst,addr,sum_out);
U3:rom1      port map((sel & sum_out(31 downto 24)),clk,q_out);
U4:sram      port map(clk,rst,q_out,seg_data,qo);
U5:seg       port map(clk,rst,seg_data,s1,s2,scan,data_out,a,b,c);
 项目:使用两个双口RAM模拟SRAM,实现两个双口RAM的切换控制。
      
    功能:从ROM里读出数据,切换着存到两个RAM里,然后再切换把RAM里的数据读出,显示在数码管上显示看是否正确
       所需知识:① IP核:ROM,RAM的使用
                ②状态机
                ③时序设计能力(本项目是锻炼时序设计能力的一个最好练习)
      
项目一:DDS信号源
实现的功能:
①产生频率分别为10MHZ,  5MHZ,  1MHZ的正弦波
②产生频率为100KHZ的三角波,200KHZ的锯齿波,300KHZ的方波
③用按键选择输出波形,并将频率显示在数码管上
④用signaltapII观察输出的波形
二.   要求:
DDS中的相位累加器使用32位的加法器,使用4级流水线操作技术完成。
*/

顶层模块:
dds_project:模块例化
input:
clk,rst_n,key [3:0],
output:
dig_en[7:0],dig_data[7:0];数码管用来显示波形的频率

底层模块:

 


一:key_code模块:


里面包括频率控制字M的应用


掌握状态机
input clk,rst,key[3:0]
output seg_data[2:0],sel[2:0],addr[31:0].


其中按键是状态跳转控制
3位的seg_data是送到sram模块来控制读写状态的转换
3位的sel是送到ROM来和32位相位累加器最后送出来的数一起控制输出的波形,sel控制波形
相位累加器位数越高,分辨率越高


ROM地址11bits=sel & sum_out(31 downto 24)  2^8==256刚好是一个波形


根据mif(8*2048)文件中的数据可以得出,当sel=:
000:方波  10mhz
001:      100k
010:      200k
011:      300k
100:
addr是频率控制字,直接赋值

难题:频率控制字具体是怎么控制频率的

二。32位累加器模块

将算出的频率控制字M进行累加,最后取高8位(0-255)

流水线的操作
分成四步加法,每步中用8位加法器(从低位到高位),
第一位:加法器输入:cin,dataa,datab...输出:cout,sum
---------------------one_step_add------------------------------
U1: ad2  port map('0',addr(7 downto 0),one_back(7 downto 0),one_cout,one_result);
U2: reg2 port map(clk,(one_cout & one_result),one_back);
U3: reg1 port map(clk,one_back(7 downto 0),one_reg1);
U4: reg1 port map(clk,one_reg1,one_reg2);
U5: reg1 port map(clk,one_reg2,sum(7 downto 0));
---------------------two_step_add------------------------------
U6: reg1 port map(clk,addr(15 downto 8),two_reg1);
U7: ad2  port map(one_back(8),two_reg1,two_back(7 downto 0),two_cout,two_result);
U8: reg2 port map(clk,(two_cout & two_result),two_back);
U9: reg1 port map(clk,two_back(7 downto 0),two_reg2);
U10: reg1 port map(clk,two_reg2,sum(15 downto 8));
---------------------three_step_add----------------------------
U11:reg1 port map(clk,addr(23 downto 16),three_reg1);
U12:reg1 port map(clk,three_reg1,three_reg2);
U13:ad2  port map(two_back(8),three_reg2,three_back(7 downto 0),three_cout,three_result);
U14:reg2 port map(clk,(three_cout & three_result),three_back);
U15:reg1 port map(clk,three_back(7 downto 0),sum(23 downto 16));
---------------------four_step_add-----------------------------
U16:reg1 port map(clk,addr(31 downto 24),four_reg1);
U17:reg1 port map(clk,four_reg1,four_reg2);
U18:reg1 port map(clk,four_reg2,four_reg3);
U19:ad2  port map(three_back(8),four_reg3,sum(31 downto 24),four_cout,four_result);
U20:reg1 port map(clk,four_result,sum(31 downto 24));
sum_out<=sum;

三.rom模块

U3:rom1      port map((sel & sum_out(31 downto 24)),clk,q_out);
q_out送到SRAM模块,按键控制RAM读写,来控制输出波形[sram其实可以不要]

四.sram模块

seg-data 状态控制
  
   1: 1写
   2: 1读 2写
   3. 1写 2读
五、seg数码管显示

显示频率

四五先不写。。。。。。。。。先把前面的测试完

 

总结1:

单纯的采用和VHDL一样的消抖方法,会有一点问题,复位键长按才能起作用,其他按键正常

最后采用新学的verilog消抖方法,效果还是比较好,但是按某些键会造成蜂鸣器跟着响。。。(可

能是板子的设计问题)

当然,还有一个缺点是这个方法比VHDL的繁琐多了,从code的长度就可以看出来

(个人感觉代码只是次要,应该思路一样都可以达到相同的效果,但是反复检查了第一种方法的verilog没有找出问题,这个以后再试试)


 

文章评论0条评论)

登录后参与讨论
我要评论
0
9
关闭 站长推荐上一条 /2 下一条