HDL Implementation of AWGN Generator
This example shows how to implement an additive white Gaussian noise (AWGN) generator that is optimized for HDL code generation and hardware implementation. The hardware implementation of AWGN accelerates the performance evaluation of wireless communication systems using an AWGN channel. In this example, the Simulink® model accepts signal-to-noise ratio (SNR) values as inputs and generates Gaussian random noise along with valid signal. The example supports SNR input ranges from –20 to 31 dB in steps of 0.1 dB.
Modern wireless communication systems involve multiple simulation parameters such as channel bandwidth, modulation type, and coding rate. Evaluating system performance across these parameters is computationally intensive and often becomes a bottleneck. FPGA-based acceleration helps overcome this challenge by leveraging hardware parallelism, thereby substantially improving simulation efficiency.
Model Architecture
Run this command to open the whdlAWGNGenerator model.
modelname = 'whdlAWGNGenerator';
open_system(modelname);

This example uses the Box-Muller method for Gaussian noise generation, which is widely adopted due to its hardware-friendly architecture and constant output rate. The top-level structure of the model comprises these three subsystems:
SNR dB to Linear Scale Converter
Gaussian Noise Generator with Unit Variance
Gaussian Noise Generator with Required Variance
Run this command to open the subsystems inside AWGNGenerator model.
open_system([modelname '/AWGNGenerator']);
SNR dB to Linear Scale Converter
The dBtoLinearConverter subsystem receives an SNR value in dB as input and converts it to noise variance on a linear scale. The system then uses this noise power to multiply the output of the Gaussian noise with unit variance. Use the lookup table approach to convert the SNR value from dB to a noise power value on a linear scale, assuming a signal power of 1 during the conversion.
Gaussian Noise Generator with Unit Variance
The GaussianNoiseWithUnitVar subsystem uses the WGN Generator block with Noise variance 1. The block uses Box-Muller method to generate two normally distributed random variables through a series of logarithmic, square root, sine, and cosine operations.
Gaussian Noise Generator with Required Variance
The GaussianNoiseWithReqVar subsystem converts Gaussian noise with unit variance to Gaussian noise with required variance. This subsystem takes inputs from dBToLinearConverter and GaussianNoiseWithUnitVar subsystems. The linear noise variance obtained from dBToLinearConverter is multiplied with normally distributed random variables obtained from the GaussianNoiseWithUnitVar subsystem.
Results and Plots
Simulate the whdlAWGNGenerator.slx model to generate 10^6 valid AWGN samples for each SNR of 5 dB and 15 dB. The implementation is pipelined to maximize the synthesis frequency, generating AWGN with an initial latency of 60. Plot the probability density function (PDF) of the AWGN output.
snrdB = [5, 15]; % SNRs to compare (dB) numOfSamples = 1e6; % Per-SNR sample count for distribution/PSD Fs = 1; % Sample rate (Hz) samplingTime = 1/Fs; latency = 68; % Known pipeline latency of model (samples) rngSeed = 67; % Fixed seed for reproducibility (used by MATLAB HDL function) % ---- Derived ---- numSNRs = numel(snrdB); snrdBSimInput = repmat(snrdB(:).', numOfSamples, 1); % replicate rows snrdBSimInput = snrdBSimInput(:); % column vector [5,...,5,15,...,15] totalInputSamples = numel(snrdBSimInput); validIn = true(1,totalInputSamples); stopTime = (totalInputSamples + latency - 1) * samplingTime; % Simulate the model fprintf('--- Setup ---\n'); fprintf('SNRs : %s dB\n', mat2str(snrdB)); fprintf('Samples/SNR : %d\n', numOfSamples); fprintf('Fs : %.3f Hz\n', Fs); fprintf('Latency : %d samples\n', latency); fprintf('StopTime : %.6f s\n\n', stopTime); set_param(modelname,'SimulationMode','Accel'); fprintf('\nSimulating HDL AWGN Generator (Simulink)...\n'); outSimulink = sim(modelname, 'ReturnWorkspaceOutputs', 'on'); fprintf('Simulation complete.\n'); % Extract valid samples only awgnSimulink = outSimulink.awgnOut(outSimulink.validOut); validCount = numel(awgnSimulink); % Slice into per-SNR segments for ii = 1:length(snrdB) snr_seg(ii,:) = awgnSimulink(1+(ii-1)*numOfSamples:numOfSamples*ii); end
--- Setup --- SNRs : [5 15] dB Samples/SNR : 1000000 Fs : 1.000 Hz Latency : 68 samples StopTime : 2000067.000000 s Simulating HDL AWGN Generator (Simulink)... Simulation complete.
% Visualizations PDF (Real and Imag parts) figure('Name','PDF of AWGN (Real & Imag)','Color','w'); tiledlayout(1,2, 'TileSpacing','compact', 'Padding','compact'); % Real nexttile; hold on; for ii = 1:length(snrdB) histogram(real(snr_seg(ii,:)), 500, 'Normalization','pdf', 'BinLimits',[-2 2], ... 'EdgeColor','none', 'DisplayName',sprintf('%d dB SNR',snrdB(ii))); end title('PDF (Real Part)'); xlabel('Amplitude'); ylabel('PDF'); legend('Location','best'); grid on; % Imag nexttile; hold on; for ii = 1:length(snrdB) histogram(imag(snr_seg(ii,:)), 500, 'Normalization','pdf', 'BinLimits',[-2 2], ... 'EdgeColor','none', 'DisplayName',sprintf('%d dB SNR',snrdB(ii))); end title('PDF (Imag Part)'); xlabel('Amplitude'); ylabel('PDF'); legend('Location','best'); grid on;

Comparison of Simulink and MATLAB HDL AWGN Generator Outputs
Simulate the MATLAB HDL equivalent AWGN generator and compare its output with the Simulink AWGN generator output.
fprintf('\nSimulating MATLAB HDL AWGN Generator for comparison...\n'); % Simulating MATLAB HDL AWGN Generator for comparison awgnMatlab = hdlwgn(numOfSamples, snrdB(1), rngSeed, 'Complex'); fprintf('Simulation complete.\n'); % Reduce sample count for visualization clarity numVerify = 1e3; sim_verify = awgnSimulink(1:numVerify); sim_matlab = awgnMatlab(1:numVerify); % Real comparison figure('Name','MATLAB vs Simulink (Real)','Color','w'); plot(1:numVerify, real(sim_verify), 'LineWidth',1.5, 'DisplayName','Simulink'); hold on; plot(1:numVerify, real(sim_matlab), 'LineWidth',1.5, 'DisplayName','MATLAB HDL'); xlabel('Sample Index'); ylabel('Real Part'); title('Comparison of MATLAB and Simulink Output (Real Part)'); legend('Location','best'); grid on; % Imag comparison figure('Name','MATLAB vs Simulink (Imag)','Color','w'); plot(1:numVerify, imag(sim_verify), 'LineWidth',1.5, 'DisplayName','Simulink'); hold on; plot(1:numVerify, imag(sim_matlab), 'LineWidth',1.5, 'DisplayName','MATLAB HDL'); xlabel('Sample Index'); ylabel('Imaginary Part'); title('Comparison of MATLAB and Simulink Output (Imaginary Part)'); legend('Location','best'); grid on;
Simulating MATLAB HDL AWGN Generator for comparison... Simulation complete.


Compute signal-to-quantization-noise ratio (SQNR) by considering the MATLAB output as the reference signal and the difference of Simulink and MATLAB output as the quantization/error noise.
err = awgnSimulink(1:numOfSamples) - awgnMatlab; psig_real = mean(real(awgnMatlab).^2); perr_real = mean(real(err).^2); SQNR_real = 10*log10(psig_real / perr_real); psig_imag = mean(imag(awgnMatlab).^2); perr_imag = mean(imag(err).^2); SQNR_imag = 10*log10(psig_imag / perr_imag); fprintf('\n--- SQNR (Simulink vs MATLAB reference) ---\n'); fprintf('Real part SQNR: %.2f dB\n', SQNR_real); fprintf('Imag part SQNR: %.2f dB\n', SQNR_imag);
--- SQNR (Simulink vs MATLAB reference) --- Real part SQNR: 71.48 dB Imag part SQNR: 71.47 dB
HDL Code Generation
To check and generate the HDL code referenced in this example, you must have an HDL Coder™ license.
To generate the HDL code, enter this command at the MATLAB command prompt.
makehdl('whdlAWGNGenerator/AWGNGenerator')
To generate a test bench, enter this command at the MATLAB command prompt.
makehdltb('whdlAWGNGenerator/AWGNGenerator')
In this example, HDL code generated for the AWGNGenerator module is implemented for the AMD® Zynq®-7000 ZC706 board. The implementation results are shown in this table.
F = table(... categorical({'Slice Registers'; 'Slice LUT'; 'Block RAMs'; 'DSPs';'Max Frequency (MHz)'}),... categorical({'8477'; '4436'; '5';'2';'300'}),... 'VariableNames',... {'Resources','Usage'}); disp(F);
Resources Usage
___________________ _____
Slice Registers 8477
Slice LUT 4436
Block RAMs 5
DSPs 2
Max Frequency (MHz) 300
References
1. J.D. Lee, J.D. Villasenor, W. Luk, and P.H.W. Leong. “A Hardware Gaussian Noise Generator Using the Box-Muller Method and Its Error Analysis,” 659–71. IEEE, 2006. https://doi.org/10.1109/TC.2006.81.