1

I'm trying to generate a vhdl code using the HDL code generator in Matlab.

I have a matlab function and its test bench.

This is the matlab function:

function [received_signal_real, received_signal_imag, error_rate] = hdl_compatible_code(n, channel_type)
    % Constants
    aircraft_altitude = fi(45000,1,32,10); % Altitude of the aircraft in feet
    distance_km = fi(350,1,32,10); % Distance between aircraft and base station in kilometers
    speed_of_light = fi(3e8,1,32,10); % Speed of light in m/s
    n = 100;
    % Pathloss model - Free Space Path Loss (FSPL)
    fc = fi(1.5e9,1,32,10); % Carrier frequency in Hz (1.5GHz)
    lambda = speed_of_light / fc; % Wavelength
    path_loss_dB = 20 *log10_approx(fi(4 * pi * distance_km * 1e3 / lambda,1,32,10)); % Path loss in dB
    % AWGN
    SNR_dB_awgn = fi(10,1,32,10); % Signal to noise ratio in dB for AWGN channel
    SNR_awgn = fi(fi(10)^(SNR_dB_awgn / 10),1,32,10); % Convert SNR to linear scale for AWGN channel
    tx_power_awgn = fi(1,1,32,10); % Initial guess for transmit power for AWGN channel
    noise_power_awgn = tx_power_awgn / SNR_awgn; % Noise power based on SNR for AWGN channel
    % Doppler spread
    aircraft_speed = fi(660,1,32,10); % Average aircraft speed in meters per second
    fd_max = fi(((aircraft_speed * fi(0.51444,1,32,10) * fc) / speed_of_light),1,32,10); % Doppler frequency shift
    % Modulation using lookup table
    % Precompute constellation points (Scalar approach)
    constellation_points = [fi(1,1,16,10), fi(1i,1,16,10),fi(-1,1,16,10), fi(-1i,1,16,10)];
    % Modulation
    data = lfsr_data(n); % Generate random bits
    qpsk_symbols = constellation_points(data + 1); % QPSK modulation: symbol mapping to complex constellation points
    % Generate doppler effect using lookup table
    two_pi_fd_max = fi(2*pi*fd_max,1,128,10);
    t = fi((0:n-1) /n,1,32,10); % Time vector
    doppler_shift = cos_lookup(fi((2 * pi * fd_max * t),1,32,10));
    % Channel simulation
    if channel_type == 0 % AWGN channel
        noise_real = sqrt(noise_power_awgn / 2) * lfsr_noise(n); % Generate noise for real part
        noise_imag = sqrt(noise_power_awgn / 2) * lfsr_noise(n); % Generate noise for imaginary part
        received_signal = (qpsk_symbols .* doppler_shift) + noise_real + fi(1i,1,16,10) * noise_imag; % Received signal in AWGN channel
    elseif channel_type == 1 % Rician fading channel
        % Rician channel parameters
        K =fi( 5,1,32,10); % Rician factor
        LOS_power_dB =fi( -10,1,32,10); % Line of sight power in dB
        LOS_power_linear = pow2(fi(10,1,32,10),LOS_power_dB/10); % Convert LOS power to linear scale
        K_linear = pow2(fi(10,1,32,10),K/10); % Convert Rician factor to linear scale
        % Generate fading coefficients
        LOS = sqrt(LOS_power_linear / (2 * (1 + 1 / K_linear))) * ones(1, n,'like',fi(0,1,16,10)); % LOS component
        scattering = sqrt(LOS_power_linear / (2 * (1 + K_linear))) * (lfsr_noise(n) +fi( 1i,1,16,10) * lfsr_noise(n)); % Scattering component
        fading_coefficient = LOS + scattering; % Rician fading coefficients
        received_signal = (qpsk_symbols .* fading_coefficient .* doppler_shift); % Apply fading to the transmitted signal
        % Add noise to the received signal in Rician channel
        noise_real_rician = sqrt(noise_power_awgn / 2) * lfsr_noise(n); % Generate noise for real part
        noise_imag_rician = sqrt(noise_power_awgn / 2) * lfsr_noise(n); % Generate noise for imaginary part
        received_signal = fi((received_signal + noise_real_rician + fi(1i,1,16,10) * noise_imag_rician),1,49,20); % Add noise
    else
        error('hdl_compatible_code:UnknownChannelType', 'Unknown channel type');
    end
    % QPSK demodulation
    % Hard decision demodulation
    % Decision regions
    decision_regions = [fi(-1-1i,1,16,10), fi(-1+1i,1,16,10), fi(1-1i,1,16,10), fi(1+1i,1,16,10)];
    % Initialize demodulated symbols
    demodulated_symbols = zeros(1, n,'uint8');
    for i = 1:n
        %Seperate real and imaginary part of received_signal and
        %decision_regions 
        received_real = real(received_signal(i));
        received_imag = imag(received_signal(i));
        decision_real = real(decision_regions);
        decision_imag = imag(decision_regions);
        %Compute the absolute difference for real and imaginary parts
        %seperately 
        diff_real =  received_real - decision_real;
        diff_imag = received_imag - decision_imag;
       %Compute the absolute value using Pythagorean theorem
        abs_diff = sqrt(diff_real.^2+diff_imag.^2);
        %Find the index corresponding to the minimum absoloute difference 
        [~,~]=min(abs_diff);
    end
    % Calculate the error rate
    errors = sum(bitxor(fi((data),0,8,0), fi((demodulated_symbols),0,8,0))); % Count errors
    % Extract real and imaginary parts
    received_signal_real = real(received_signal);
    received_signal_imag = imag(received_signal);
    error_rate = errors / n; % Calculate error rate
end
function noise = lfsr_noise(n)
    % Linear feedback shift register (LFSR) for pseudo-random number generation
    % Initialize LFSR state
    lfsr_state = uint32(1);
    noise = zeros(1, n,'like',fi(0,1,16,10));
    for i = 1:n
        % Generate pseudo-random bit using xor feedback
        new_bit = bitxor(bitget(lfsr_state, 1), bitget(lfsr_state, 3));
        lfsr_state = bitshift(lfsr_state, -1);
        lfsr_state = bitset(lfsr_state, 32, new_bit);
        noise(i) = fi(lfsr_state,0,32,0) / fi(intmax('uint32'),1,16,10); % Scale [0,1]
    end
end
function data = lfsr_data(n)
    % Linear feedback shift register (LFSR) for generating random data
    % Initialize LFSR state
    lfsr_state = uint32(1);
    data = zeros(1, n, 'uint8');
    for i = 1:n
        % Generate pseudo-random bit using xor feedback
        new_bit = bitxor(bitget(lfsr_state, 1), bitget(lfsr_state, 3));
        lfsr_state = bitshift(lfsr_state, -1);
        lfsr_state = bitset(lfsr_state, 32, new_bit);
        data(i) = fi((mod(lfsr_state,4)),0,2,0); % Generate random values in the range [0, 3]
    end
end
function cos_value = cos_lookup(angle)
    % Precompute cosine values for a range of angles
    angles =fi( (0:0.01:2*pi),1,32,10); % Define the range of angles (adjust the step size as needed)
    cos_values = fi((cos(angles)),1,16,10); % Compute cosine values
    % Interpolate the cosine value for the given angle
    cos_value = fi((zeros(size(angle))),1,16,10);
    for i = 1:numel(angle)
        [~,idx]=min(abs(angles-angle(i)));
        cos_value(i)=cos_values(idx);
    end
end
function y = log2_approx(x)
%Fixed-point logarithm base 2 approximation
y = fi(0,1,32,10);%Initialize y as fixed-point format
one = fi(1,1,32,10);%Define one in the same fixed-point format 
sqrt2 = fi((sqrt(2)),1,32,10);%Define sqrt(2) in the same fixed -point format 
for i = 1:32 %Limiting the iterations to 32 to avoid infinite loop
    if x > one
        x = bitsra(x,1);
        y = fi((y + one),1,32,10);
    end
end 
frac = fi (0.5,1,32,10);
for i = 1:32
    if x < one 
        x = bitsll(x,1);
        y =fi( (y - one),1,32,10);
    end 
end 
frac = fi (0.5,1,32,10);
two_pow_neg32 = fi((2^-32),1,32,10);
for i = 1:32
    if x >= sqrt2
        x = divide(x,sqrt2);
        y =fi((y + frac) , 1,32,10);
    end 
frac = divide(frac,2);
end
end 
function y = log10_approx(x)
%Approximate log10 function using a fixed-point approach
y = log2_approx(x)/ log2_approx(fi(10,1,32,10));
end
function result = divide(a,b)
%custom fixed-point division function
result = a/b;
result = fi(result,a.Signed,a.WordLength,a.FractionLength);
end 

and this is the test bench

function test_modulation_channel()
   %Test 1:AWGN channel
   n=100;%Number of sampples
   channel_type = 0;%AWGN Channel
   hdl_compatible_code(n,channel_type);
   assert(true,'hdl_compatible_code should run without errors for AWGN channel');
   
   %Test 2:Rician Fading Channel
   n = 100; %Number of samples
   channel_type = 1; %Rician channel
   hdl_compatible_code(n,channel_type);
     assert(true,'hdl_compatible_code should run without errors for Rician channel');
   
   %Test 3:Invalid channel type
   n = 100;%Number of samples
   channel_type = 2; %Invalid channel type
   try
         hdl_compatible_code(n,channel_type);
        assert(false,'hdl_compatible_code should throw an error for invalid channel type');
   catch e
       assert(strcmp(e.identifier,'hdl_compatible_code:UnknownChannelType'),'hdl_compatible_code should throw an error with identifier ''hdl_compatible_code:UnknownChannelType''');
   end
   
   
    fprintf('All tests passed!\n');
       
   
end

But the workflow advisor is showing 1 error in the HSL conformance report, and in that, it says the function requiring attention is the 'fi' function that I've used. Can anyone fix my code so that it runs on the HDL coder and generates a VHDL code that can be uploaded onto any generic FPGA?

There's a high chance that this is an error within the version of Matlab that I'm using (2020a).

1
  • Recommend starting by posting in the Matlab help forum. Matlab and the coder tool are an expensive commercial tools, your company probably pays for support; maybe find your support person. If you are a student ask the prof. Commented Jun 17, 2024 at 23:09

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.