基于FPGA的正弦發生器
0.png (43 KB, 下載次數: 77)
下載附件
2018-10-16 17:20 上傳
JN$IL@~5SWBR5{{7A86}8MH.jpg (136.55 KB, 下載次數: 72)
下載附件
2018-10-16 17:10 上傳
verilog源程序如下:
- //sin_count_max=20,sin_f=1kz
- module sin(clk,rst,sin_A,sin_B,sin_C);
- input clk,rst;
- output reg [11:0] sin_A,sin_B,sin_C;
- reg [11:0] sin_A_r,sin_B_r,sin_C_r;
-
- //get sinusoid addriess
- reg [9:0] sin_add_A,sin_add_B,sin_add_C;
- reg [11:0] sin_add_A_r,sin_add_B_r,sin_add_C_r;
- reg sign_A,sign_B,sign_C; // 1 -- negtive; 0 -- positive
- reg [9:0] count; // change from B9 to B10
- //address of B/C phase delay after A phase //sinA = sin(wt)
- parameter ADD_B_delay = 12'd1667; //2500 * 2/3 //sinB = sin(wt-2*pi/3)
- parameter ADD_C_delay = 12'd833; //2500 * 1/3 //sinC = sin(wt+2*pi/3)
- parameter ADD_MEM_MAX = 12'd624; //range of memory lookup address is: 0 -- 624 for this memory table.
- parameter ADD_sin_1 = 12'd2499;//range of one sinusodal wave cycle address is: 0 -- 2499 for this memory table.
- parameter ADD_sin_2 = 12'd625;
- parameter ADD_sin_3 = 12'd1250;
- parameter ADD_sin_4 = 12'd1875;
- parameter DATA_MAX = 12'b111111111111; //max data value
- parameter NEG_1 = {12{1'b1}}; //-1
- always @ (posedge clk or negedge rst) begin
- if (rst == 1'b0) begin
- sin_add_A_r <= 12'b0;
- sin_add_B_r <= ADD_B_delay;
- sin_add_C_r <= ADD_C_delay;
- count <= 10'b1;
- sign_A <= 1'b0;
- sign_B <= 1'b0;
- sign_C <= 1'b0;
- end
- else begin
-
-
- //genarate address
- if ( count >= 20 ) begin
- count <= 10'b1;
- //update lookup table address
- sin_add_A_r <= sin_add_A_r + 1'b1 ;
- if (sin_add_A_r >= ADD_sin_1) begin
- sin_add_A_r <= sin_add_A_r - ADD_sin_1;
- end
- sin_add_B_r<= sin_add_B_r + 1'b1;
- if (sin_add_B_r >= ADD_sin_1) begin
- sin_add_B_r <= sin_add_B_r - ADD_sin_1;
- end
- sin_add_C_r<= sin_add_C_r + 1'b1 ;
- if (sin_add_C_r >= ADD_sin_1) begin
- sin_add_C_r <= sin_add_C_r - ADD_sin_1;
- end
-
- //generate address A
- if((sin_add_A_r >= 0) && (sin_add_A_r < ADD_sin_2))begin
- sin_add_A <= sin_add_A_r[9:0];
- sign_A <= 1'b0;
- end
- else if((sin_add_A_r>= ADD_sin_2) && (sin_add_A_r < ADD_sin_3)) begin
- sin_add_A <= ADD_sin_3 - sin_add_A_r - 1'b1;
- sign_A <= 1'b0;
- end
- else if((sin_add_A_r >= ADD_sin_3) && (sin_add_A_r < ADD_sin_4)) begin
- sin_add_A <= sin_add_A_r - ADD_sin_3;
- sign_A <= 1'b1;
- end
- else if((sin_add_A_r >= ADD_sin_4) && (sin_add_A_r <= ADD_sin_1))begin
- sin_add_A <= ADD_sin_1 - sin_add_A_r;
- sign_A <= 1'b1;
- end
- //get data A
- if(sign_A == 1'b1) begin
- sin_A <= ~sin_A_r + 1'b1 ;
- end
- else begin
- sin_A <= sin_A_r;
- end
-
- //generate address B
- if((sin_add_B_r >= 0) && (sin_add_B_r < ADD_sin_2))begin
- sin_add_B <= sin_add_B_r[9:0];
- sign_B <= 1'b0;
- end
- else if((sin_add_B_r >= ADD_sin_2) && (sin_add_B_r < ADD_sin_3)) begin
- sin_add_B <= ADD_sin_3 - sin_add_B_r - 1'b1;
- sign_B <= 1'b0;
- end
- else if((sin_add_B_r >= ADD_sin_3) && (sin_add_B_r < ADD_sin_4)) begin
- sin_add_B <= sin_add_B_r - ADD_sin_3;
- sign_B <= 1'b1;
- end
- else if((sin_add_B_r >= ADD_sin_4) && (sin_add_B_r <= ADD_sin_1))begin
- sin_add_B <= ADD_sin_1- sin_add_B_r;
- sign_B <= 1'b1;
- end
- //get data B
- if(sign_B == 1'b1) begin
- sin_B <= ~sin_B_r+ 1'b1 ;
- end
- else begin
- sin_B <= sin_B_r;
- end
-
- //generate address C
- if((sin_add_C_r >= 0) && (sin_add_C_r < ADD_sin_2))begin
- sin_add_C <= sin_add_C_r[9:0];
- sign_C <= 1'b0;
- end
- else if((sin_add_C_r >= ADD_sin_2) && (sin_add_C_r < ADD_sin_3)) begin
- sin_add_C <= ADD_sin_3 - sin_add_C_r - 1'b1;
- sign_C <= 1'b0;
- end
- else if((sin_add_C_r >= ADD_sin_3) && (sin_add_C_r < ADD_sin_4)) begin
- sin_add_C <= sin_add_C_r - ADD_sin_3;
- sign_C <= 1'b1;
- end
- else if((sin_add_C_r >= ADD_sin_4) && (sin_add_C_r<= ADD_sin_1))begin
- sin_add_C <= ADD_sin_1 - sin_add_C_r;
- sign_C <= 1'b1;
- end
- //get data C
- if(sign_C == 1'b1) begin
- sin_C <= ~sin_C_r + 1'b1 ;
- end
- else begin
- sin_C <= sin_C_r;
- end
-
- end
- else begin
- count <= count + 1'b1;
- end
- end
- end
- // Parallel to serial
- // use 3 phase pipeline
- reg [9:0] add;
- wire [11:0] sin;
- reg [2:0] sel;
- always @ ( posedge clk or negedge rst)begin
- if( rst == 1'b0 )begin
- sel <= 3'b001;
- sin_A_r <= 12'b0;
- sin_B_r <= 12'b0;
- sin_C_r <= 12'b0;
- add <= 10'b0;
- end
- else begin
- sel <= {sel[1],sel[0],sel[2]};
- case (sel)
- 3'b001: begin
- add <= sin_add_A;
- sin_A_r <= sin;
- end
- 3'b010: begin
- add <= sin_add_B;
- sin_B_r <= sin;
- end
- 3'b100: begin
- add <= sin_add_C;
- sin_C_r <= sin;
- end
- default: begin
- sel <= 3'b001;
- end
- endcase
-
- end
- end
- sintalbe625 sintalbe625A_inst (
- .address ( add ),
- .clock ( clk ),
- .q ( sin )
- );
- endmodule
復制代碼
所有資料51hei提供下載:
sin.zip
(2.28 MB, 下載次數: 50)
2018-10-16 17:07 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|