本文章主要讨论高斯白噪声的FPGA实现。简单的方法可以采用在Matlab中产生服从一定均值和方差的I、Q两路噪声信号。然后将两组数据存在FPGA中进行回放,以此来产生高斯白噪声。这种方法优点是产生方法简单占用FPGA资源少,但是他只能保证在回放噪声的一段数据是满足不相关特性的,段与段之间的数据是相关的。为了使整个过程中的噪声都满足不相关特性,可以通过LSFR序列的交错异或,得到均匀分布的伪随机信号,采用在一个ROM中存储sin函数值另一个ROM中存储log函数值。通过产生随机读地址的方式随机读取两个ROM中的数据,将两组随机的函数值相乘得到高斯白噪声。模块功能框图如下图。
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////子模块1
module rand_gen(
input wire clk100,
input wire rst,
output reg [10:0] orbit_sin_addr, //rand number for sin ROM addr, [10:]
output reg [9:0] orbit_log_addr //rand number for log ROM addr, [9:0]
);
wire resetup; // asynchronous clear, high active
wire [10:0] orbit_1;
wire [10:0] orbit_2;
wire [9:0] orbit_3;
wire [9:0] orbit_4;
parameter initval_1=24'b010110010010110111110001,
initval_2=24'b100000111100010111010001,
initval_3=24'b001101000001010010010001,
initval_4=24'b111010100110010011110001;
// 交错异或子模块
inter_feedback_rand_1 inter_feedback_rand_1_inst (
.orbit(orbit_1), //[10:0]
.clk(clk100),
.resetup(resetup),
.initval(initval_1) //[23:0]
);
//////////////////////////////////////////////////////////////////////////////////
inter_feedback_rand_2 inter_feedback_rand_2_inst (
.orbit(orbit_2), //[10:0]
.clk(clk100),
.resetup(resetup),
.initval(initval_2) //[23:0]
);
//////////////////////////////////////////////////////////////////////////////////
inter_feedback_rand_3 inter_feedback_rand_3_inst (
.orbit(orbit_3), //[9:0]
.clk(clk100),
.resetup(resetup),
.initval(initval_3) //[23:0]
);
//////////////////////////////////////////////////////////////////////////////////
inter_feedback_rand_4 inter_feedback_rand_4_inst (
.orbit(orbit_4), //[9:0]
.clk(clk100),
.resetup(resetup),
.initval(initval_4) //[23:0]
);
//////////////////////////////////////////////////////////////////////////////////
// orbit_sin_addr [10:0] //
//////////////////////////////////////////////////////////////////////////////////
always @ (posedge clk100 or posedge rst) begin
if(rst) begin
orbit_sin_addr <= 11'b0;
end
else
orbit_sin_addr <= orbit_1 ^ orbit_2;
end
//////////////////////////////////////////////////////////////////////////////////
// orbit_log_addr [9:0 ] //
//////////////////////////////////////////////////////////////////////////////////
always @ (posedge clk100 or posedge rst) begin
if(rst) begin
orbit_log_addr <= 10'b0;
end
else
orbit_log_addr <= orbit_3 ^ orbit_4;
end
//////////////////////////////////////////////////////////////////////////////////
// resetup //
//////////////////////////////////////////////////////////////////////////////////
reg resetup_r = 1'b0;
assign resetup = resetup_r;
always @ (posedge clk100 or posedge rst) begin
if(rst)
resetup_r <= 1'd1;
else
resetup_r <= 1'd0;
end
endmodule
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////子模块2
module noise_gen(
input wire clk100,
input wire rst,