找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3734|回复: 3
打印 上一主题 下一主题
收起左侧

基于FPGA的正弦发生器verilog源码

[复制链接]
跳转到指定楼层
楼主
基于FPGA的正弦发生器



verilog源程序如下:
  1. //sin_count_max=20,sin_f=1kz
  2. module sin(clk,rst,sin_A,sin_B,sin_C);
  3. input        clk,rst;

  4. output  reg         [11:0]        sin_A,sin_B,sin_C;
  5. reg                [11:0]        sin_A_r,sin_B_r,sin_C_r;
  6.                        
  7. //get sinusoid addriess
  8. reg         [9:0]        sin_add_A,sin_add_B,sin_add_C;
  9. reg         [11:0]        sin_add_A_r,sin_add_B_r,sin_add_C_r;
  10. reg                sign_A,sign_B,sign_C;        // 1 -- negtive; 0 -- positive
  11. reg                [9:0]        count;                // change from B9 to B10

  12.         //address of B/C phase delay after A phase                        //sinA = sin(wt)
  13.         parameter ADD_B_delay = 12'd1667;         //2500 * 2/3        //sinB = sin(wt-2*pi/3)
  14.         parameter ADD_C_delay = 12'd833;         //2500 * 1/3        //sinC = sin(wt+2*pi/3)
  15.         parameter ADD_MEM_MAX = 12'd624;        //range of memory lookup address is: 0 -- 624 for this memory table.
  16.         parameter ADD_sin_1 = 12'd2499;//range of one sinusodal wave cycle address is: 0 -- 2499 for this memory table.
  17.         parameter ADD_sin_2 = 12'd625;
  18.         parameter ADD_sin_3 = 12'd1250;
  19.         parameter ADD_sin_4 = 12'd1875;

  20. parameter DATA_MAX = 12'b111111111111;        //max data value
  21. parameter NEG_1 = {12{1'b1}}; //-1

  22. always @ (posedge clk or negedge rst) begin
  23.         if (rst == 1'b0) begin
  24.                 sin_add_A_r <= 12'b0;
  25.                 sin_add_B_r <= ADD_B_delay;
  26.                 sin_add_C_r <= ADD_C_delay;
  27.                 count <= 10'b1;
  28.                 sign_A <= 1'b0;
  29.                 sign_B <= 1'b0;
  30.                 sign_C <= 1'b0;
  31.         end
  32.         else begin
  33.                
  34.                
  35.                 //genarate address
  36.                 if ( count >= 20 ) begin
  37.                         count <= 10'b1;

  38.                         //update lookup table address
  39.                         sin_add_A_r <= sin_add_A_r + 1'b1 ;
  40.                         if (sin_add_A_r >= ADD_sin_1) begin
  41.                                 sin_add_A_r <= sin_add_A_r - ADD_sin_1;
  42.                         end
  43.                         sin_add_B_r<= sin_add_B_r + 1'b1;
  44.                         if (sin_add_B_r >= ADD_sin_1) begin
  45.                                 sin_add_B_r <= sin_add_B_r - ADD_sin_1;
  46.                         end
  47.                         sin_add_C_r<= sin_add_C_r + 1'b1 ;
  48.                         if (sin_add_C_r >= ADD_sin_1) begin
  49.                                 sin_add_C_r <= sin_add_C_r - ADD_sin_1;
  50.                         end
  51.                        
  52.                         //generate address A
  53.                         if((sin_add_A_r >= 0) && (sin_add_A_r < ADD_sin_2))begin
  54.                                  sin_add_A <= sin_add_A_r[9:0];
  55.                                 sign_A <= 1'b0;
  56.                         end
  57.                         else if((sin_add_A_r>= ADD_sin_2) && (sin_add_A_r < ADD_sin_3)) begin
  58.                                  sin_add_A <= ADD_sin_3 - sin_add_A_r - 1'b1;
  59.                                 sign_A <= 1'b0;
  60.                         end
  61.                         else if((sin_add_A_r >= ADD_sin_3) && (sin_add_A_r < ADD_sin_4)) begin
  62.                                  sin_add_A <=  sin_add_A_r - ADD_sin_3;
  63.                                 sign_A <= 1'b1;
  64.                         end
  65.                         else if((sin_add_A_r >= ADD_sin_4) && (sin_add_A_r <= ADD_sin_1))begin
  66.                                 sin_add_A <=  ADD_sin_1 - sin_add_A_r;
  67.                                 sign_A <= 1'b1;
  68.                         end
  69.                         //get data A
  70.                         if(sign_A == 1'b1) begin
  71.                                 sin_A <= ~sin_A_r + 1'b1 ;               
  72.                         end
  73.                         else begin
  74.                                 sin_A <= sin_A_r;               
  75.                         end
  76.                        
  77.                         //generate address B
  78.                         if((sin_add_B_r >= 0) && (sin_add_B_r < ADD_sin_2))begin
  79.                                  sin_add_B <= sin_add_B_r[9:0];
  80.                                 sign_B <= 1'b0;
  81.                         end
  82.                         else if((sin_add_B_r >= ADD_sin_2) && (sin_add_B_r < ADD_sin_3)) begin
  83.                                  sin_add_B <= ADD_sin_3 - sin_add_B_r - 1'b1;
  84.                                 sign_B <= 1'b0;
  85.                         end
  86.                         else if((sin_add_B_r >= ADD_sin_3) && (sin_add_B_r < ADD_sin_4)) begin
  87.                                  sin_add_B <=  sin_add_B_r - ADD_sin_3;
  88.                                 sign_B <= 1'b1;
  89.                         end
  90.                         else if((sin_add_B_r >= ADD_sin_4) && (sin_add_B_r <= ADD_sin_1))begin
  91.                                 sin_add_B <=  ADD_sin_1- sin_add_B_r;
  92.                                 sign_B <= 1'b1;
  93.                         end
  94.                         //get data B
  95.                         if(sign_B == 1'b1) begin
  96.                                 sin_B <= ~sin_B_r+ 1'b1 ;               
  97.                         end
  98.                         else begin
  99.                                 sin_B <= sin_B_r;               
  100.                         end
  101.                        
  102.                         //generate address C
  103.                         if((sin_add_C_r >= 0) && (sin_add_C_r < ADD_sin_2))begin
  104.                                  sin_add_C <= sin_add_C_r[9:0];
  105.                                 sign_C <= 1'b0;
  106.                         end
  107.                         else if((sin_add_C_r >= ADD_sin_2) && (sin_add_C_r < ADD_sin_3)) begin
  108.                                  sin_add_C <= ADD_sin_3 - sin_add_C_r - 1'b1;
  109.                                 sign_C <= 1'b0;
  110.                         end
  111.                         else if((sin_add_C_r >= ADD_sin_3) && (sin_add_C_r < ADD_sin_4)) begin
  112.                                  sin_add_C <=  sin_add_C_r - ADD_sin_3;
  113.                                 sign_C <= 1'b1;
  114.                         end
  115.                         else if((sin_add_C_r >= ADD_sin_4) && (sin_add_C_r<= ADD_sin_1))begin
  116.                                 sin_add_C <=  ADD_sin_1 - sin_add_C_r;
  117.                                 sign_C <= 1'b1;
  118.                         end
  119.                         //get data C
  120.                         if(sign_C == 1'b1) begin
  121.                                 sin_C <= ~sin_C_r + 1'b1 ;               
  122.                         end
  123.                         else begin
  124.                                 sin_C <= sin_C_r;               
  125.                         end
  126.                        
  127.                 end
  128.                 else begin
  129.                         count <= count + 1'b1;
  130.                 end
  131.         end
  132. end

  133. // Parallel to serial
  134. // use 3 phase pipeline
  135. reg         [9:0]         add;
  136. wire        [11:0]        sin;
  137. reg         [2:0]        sel;
  138. always @ ( posedge clk or negedge rst)begin
  139.         if( rst == 1'b0 )begin
  140.                 sel <= 3'b001;
  141.                 sin_A_r <= 12'b0;
  142.                 sin_B_r <= 12'b0;
  143.                 sin_C_r <= 12'b0;
  144.                 add <= 10'b0;
  145.         end
  146.         else begin
  147.                 sel <= {sel[1],sel[0],sel[2]};
  148.                 case (sel)
  149.                         3'b001: begin
  150.                                 add <= sin_add_A;
  151.                                 sin_A_r <= sin;
  152.                                 end
  153.                         3'b010: begin
  154.                                 add <= sin_add_B;
  155.                                 sin_B_r <= sin;
  156.                                 end
  157.                         3'b100: begin
  158.                                 add <= sin_add_C;
  159.                                 sin_C_r <= sin;
  160.                                 end
  161.                         default: begin
  162.                                 sel <= 3'b001;
  163.                                 end
  164.                 endcase
  165.                
  166.         end
  167. end
  168. sintalbe625 sintalbe625A_inst (
  169.                 .address ( add ),
  170.                 .clock ( clk ),
  171.                 .q ( sin )
  172.                 );

  173. endmodule


复制代码

所有资料51hei提供下载:
sin.zip (2.28 MB, 下载次数: 50)


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:105037 发表于 2019-5-31 13:09 | 只看该作者
十分感谢共享。
回复

使用道具 举报

板凳
ID:273087 发表于 2019-5-31 14:55 | 只看该作者
感谢分享,学习一下~~
回复

使用道具 举报

地板
ID:495974 发表于 2019-7-4 16:56 | 只看该作者
没有实物图吗

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表