ive been trying to generate vhdl code using hdl code genrator on matlab 2020a but its showing error regarding the use of fi in my code , can someone fix it for me ? thankyou
3 views (last 30 days)
Show older comments
this is my code : 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
0 Comments
Answers (1)
Kiran Kintali
on 15 Jun 2024
Edited: Kiran Kintali
on 16 Jun 2024
Please review MATLAB design patterns here.
You need to break your design into MATLAB DUT design.m (which becomes the chip) a testbench testbench.m (tests the chip). You are required to use MATLAB to HDL code generation subset in the design.m file. Please share a runme.m file that uses codegen commands.
Try a sample example
>> mlhdlc_demo_setup('heq')
another example here
>> mlhdlc_demo_setup('fft')
a comms data packet example can be found with this commd
>> mlhdlc_demo_setup('comms')
If you can share the original MATLAB design and testbench and the hdlcoder project file or a runme file with the codegen commands that would be very helpful.
The file you have shared seems to be an intermediate file auto generated in the integrated MATLAB float to fixed conversion.
Thanks
2 Comments
See Also
Categories
Find more on Modulation in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!