В этом примере показано, как сгенерировать HDL-код из проекта MATLAB® что packetizes последовательность передачи.
В радиосвязи системы получают данные, сверхдискретизирован во фронтэнде РФ. Это служит нескольким целям, включая обеспечение достаточных уровней выборки для получают фильтрацию.
% However, one of the most important % functions is to provide multiple sampling points on the received % waveform such that data can be sampled near the maximum amplitude point % in the received waveform. This example illustrates a basic lead-lag time % offset estimation core, operating recursively. % The generated hardware core for this design operates at 1/os_rate % where os_rate is the oversampled rate. That is, for 8 oversampled clock cycles % this core iterates once. The output is at the symbol rate. design_name = 'mlhdlc_comms_data_packet'; testbench_name = 'mlhdlc_comms_data_packet_tb';
Давайте смотреть на проект MATLAB.
type(design_name);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% MATLAB design: Data packetization
%
% Introduction:
%
% This core is meant to illustrate packetization of a transmit sequence.
% There is a "pad" data section, which allows for the transmit amplifier to
% settle. This is then followed by a 65-bit training sequence. This is
% followed by the number of symbols beginning encoded into two bytes or
% 16-bits. This is then followed by a variable length data sequence and a
% CRC. All bits can optionally be differentially encoded.
%
% Key design pattern covered in this example:
% (1) Design illustrates the us of binary operands, such as bitxor
% (2) Shows how to properly segment persistent variables for register an
% BRAM access
% (3) Illustrates the use of fi math
% (4) Shows how to properly format and store ROM data, e.g., padData
% Copyright 2011-2015 The MathWorks, Inc.
%#codegen
function [symbolOut, reByte] = ...
mlhdlc_comms_data_packet(emptyFlag, byteValue, numberSymbols, diffOn, Nts, Npad)
persistent trainBits1 padData
persistent valueCRC crcVector bitPrev
persistent inPacketFlag bitOfByteIndex symbolCount
fm = hdlfimath;
if isempty(symbolCount)
symbolCount = 1;
inPacketFlag = 0;
valueCRC = fi(1, 0,16,0, fm);
bitOfByteIndex = 1;
bitPrev = fi(1, 0,1,0, fm);
crcVector = zeros(1,16);
end
if isempty(trainBits1)
% data-set already exists
trainBits1 = TRAIN_DATA;
padData = PAD_DATA;
end
%genPoly = 69665;
genPoly = fi(65535, 0,16,0, fm);
byteUint8 = uint8(byteValue);
reByte = 0;
symbolOut = fi(0, 0,1,0, fm);
%the first condition is whether or not we're currently processing a packet
if inPacketFlag == 1
bitOut = fi(0, 0,1,0, fm);
if symbolCount <= Npad
bitOut(:) = padData(symbolCount);
elseif symbolCount <= Npad+Nts
bitOut(:) = trainBits1(symbolCount-Npad);
elseif symbolCount <= Npad+Nts+numberSymbols
bitOut(:) = bitget(byteUint8,9-bitOfByteIndex);
bitOfByteIndex = bitOfByteIndex + 1;
if bitOfByteIndex == 9 && symbolCount < Npad+Nts+numberSymbols
bitOfByteIndex = 1;
reByte = 1; % we've exhausted this one so pop new one off
end
elseif symbolCount <= Npad+Nts+numberSymbols+16
bitOut(:) = 0;
elseif symbolCount <= Npad+Nts+numberSymbols+32
bitOut(:) = crcVector(symbolCount-(Npad+Nts+numberSymbols+16));
else
inPacketFlag = 0; %we're done
end
%leadValue = 0;
% here we have the bit going out so if past Nts+Npad then form CRC.
% Note that we throw 16 zeros on the end in order to flush the CRC
if symbolCount > Npad+Nts && symbolCount <= Npad+Nts+numberSymbols+16
valueCRCsh1 = bitsll(valueCRC, 1);
valueCRCadd1 = bitor(valueCRCsh1, fi(bitOut, 0,16,0, fm));
leadValue = bitget(valueCRCadd1,16);
if leadValue == 1
valueCRCxor = bitxor(valueCRCadd1, genPoly);
else
valueCRCxor = valueCRCadd1;
end
valueCRC = valueCRCxor;
if symbolCount == Npad+Nts+numberSymbols+16
crcVector(:) = bitget( valueCRC, 16:-1:1);
end
end
if diffOn == 0 || symbolCount <= Npad+Nts
symbolOut(:) = bitOut;
else
if bitPrev == bitOut
symbolOut(:) = 1;
else
symbolOut(:) = 0;
end
end
bitPrev(:) = symbolOut;
symbolCount = symbolCount + 1; %total number of symbols transmitted
else
% we're not processing a packet and waiting for a new packet to arrive
if emptyFlag == 0
% reset everything
inPacketFlag = 1;
% toggle re to grab data
reByte = 1;
symbolCount = 1;
bitOfByteIndex = 1;
valueCRC(:) = 65535;
bitPrev(:) = 0;
end
end
end
type(testbench_name);
function mlhdlc_comms_data_packet_tb
%
% Copyright 2011-2015 The MathWorks, Inc.
% generate transmit data, note the first two bytes are the data length
numberBytes = 8; % this is total number of symbols
numberSymbols = numberBytes*8;
rng(1); % always default to known state
data = [floor(numberBytes/2^8) mod(numberBytes,2^8) ...
round(rand(1,numberBytes-2)*255)];
% generate training data helper function
make_train_data('TRAIN_DATA');
% make sure training data is generated
pause(2)
[~] = which('TRAIN_DATA');
trainBits1 = TRAIN_DATA;
Nts = length(trainBits1);
make_pad_data('PAD_DATA');
pause(2)
[~] = which('PAD_DATA');
Npad = 2^9;
% Give number of samples, where the start of the sequence flag will be
% (indicated by a zero), as well as an output buffer for generated symbols
Nsamp = 1000;
Noffset = 20;
emptyFlagHold = ones(1,Nsamp); emptyFlagHold(Noffset) = 0;
symbolOutHold = zeros(1,Nsamp);
dataIndex = 1;
byteValue = 0;
diffOn = 1; % 0 - regular encoding, 1 - differential encoding
for i1 = 1:Nsamp
emptyFlag = emptyFlagHold(i1);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Call to the design
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
[symbolOut, reByte] = ...
mlhdlc_comms_data_packet(emptyFlag, byteValue, numberSymbols, diffOn, Nts, Npad);
% This set of code emulates the external FIFO interface
if reByte == 1 % when high, pop a value off the input FIFO
byteValue = data(dataIndex);
dataIndex = dataIndex + 1;
end
symbolOutHold(i1) = symbolOut;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% This is all code to verify we did the encoding properly
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% grad training data - not differentially encoded
symbolTrain = symbolOutHold(1+Noffset+Npad:Noffset+Npad+Nts);
% grab user data and decode if necessary
symbolEst = zeros(1,numberSymbols);
symbolPrev = trainBits1(end);
if diffOn == 0
symbolData = ...
symbolOutHold(1+Noffset+Npad+Nts:Noffset+Npad+Nts+numberSymbols); %#ok<NASGU>
else
% decoding is simply comparing adjacent received symbols
symbolTemp = ...
symbolOutHold(1+Noffset+Npad+Nts:Noffset+Npad+Nts+numberSymbols+32);
for i1 = 1:length(symbolTemp)
if symbolTemp(i1) == symbolPrev
symbolEst(i1) = 1;
else
symbolEst(i1) = 0;
end
symbolPrev = symbolTemp(i1);
end
end
% training data
trainDataEst = symbolTrain(1:Nts);
trainDiff = abs(trainDataEst-trainBits1');
% user data
userDataEst = symbolEst(1:numberSymbols);
dataEst = zeros(1,numberBytes);
for i1 = 1:numberBytes
y = userDataEst((i1-1)*8+1:i1*8);
dataEst(i1) = bin2dec(char(y+48));
end
userDiff = abs(dataEst-data);
disp(['Training Difference: ',num2str(sum(trainDiff)), ...
' User Data Difference: ',num2str(sum(userDiff))]);
% run it through and check CRC
genPoly = 69665;
c = symbolEst;
cEst = c(1,:);
cEst2 = [cEst(1:end-32) cEst(end-15:end)];
cEst = cEst2;
valueCRCc = 65535;
for i1 = 1:length(cEst)
valueCRCsh1 = bitsll(uint16(valueCRCc), 1);
valueCRCadd1 = bitor(uint16(valueCRCsh1), cEst(i1));
leadValue = bitget( valueCRCadd1, 16);
if (leadValue == 1)
valueCRCxor = bitxor(uint16(valueCRCadd1), uint16(genPoly));
else
valueCRCxor = bitxor(uint16(valueCRCadd1), 0);
end
valueCRCc = valueCRCxor;
end
if valueCRCc == 0
disp('CRC decoded correctly');
else
disp('CRC check failed');
end
function make_train_data(filename)
x = load('mlhdlc_dpack_train_data.txt');
fid = fopen([filename,'.m'],'w+');
fprintf(fid,['function y = ' filename '\n']);
fprintf(fid,'%%#codegen\n');
fprintf(fid,'y = [\n');
fprintf(fid,'%1.0e\n',x);
fprintf(fid,'];\n');
fclose(fid);
function make_pad_data(filename)
rng(1);
x = round(rand(1,2^9));
fid = fopen([filename,'.m'],'w+');
fprintf(fid,['function y = ' filename '\n']);
fprintf(fid,'%%#codegen\n');
fprintf(fid,'y = [\n');
fprintf(fid,'%1.0e\n',x);
fprintf(fid,'];\n');
fclose(fid);
Выполните следующие строки кода, чтобы скопировать необходимые файлы в качестве примера во временную папку.
mlhdlc_demo_dir = fullfile(matlabroot, 'toolbox', 'hdlcoder', 'hdlcoderdemos', 'matlabhdlcoderdemos'); mlhdlc_temp_dir = [tempdir 'mlhdlc_dpack']; % Create a temporary folder and copy the MATLAB files. cd(tempdir); [~, ~, ~] = rmdir(mlhdlc_temp_dir, 's'); mkdir(mlhdlc_temp_dir); cd(mlhdlc_temp_dir); copyfile(fullfile(mlhdlc_demo_dir, [design_name,'.m*']), mlhdlc_temp_dir); copyfile(fullfile(mlhdlc_demo_dir, [testbench_name,'.m*']), mlhdlc_temp_dir);
Это всегда - хорошая практика, чтобы симулировать проект с испытательным стендом до генерации кода, чтобы убедиться, что нет никаких ошибок периода выполнения.
mlhdlc_comms_data_packet_tb
Training Difference: 0 User Data Difference: 0 CRC decoded correctly
coder -hdlcoder -new mlhdlc_dpack
Затем добавьте файл 'mlhdlc_comms_data_packet.m' в проект как функция MATLAB и 'mlhdlc_comms_data_packet_tb.m' как Испытательный стенд MATLAB.
Можно обратиться к Началу работы с MATLAB к примеру по Рабочему процессу HDL для более полного примера при создании и заполнении проектов HDL Coder MATLAB.
Запустите Советника по вопросам Рабочего процесса от вкладки Build, и щелчок правой кнопкой по 'Генерации кода' продвигаются и выбирают опцию, 'Запущенную к выбранной задаче', чтобы запустить все шаги с начала через генерацию HDL-кода.
Исследуйте сгенерированный HDL-код путем нажатия на гиперссылки в окне Code Generation Log.
Можно запустить следующие команды, чтобы очистить временную папку проекта.
mlhdlc_demo_dir = fullfile(matlabroot, 'toolbox', 'hdlcoder', 'hdlcoderdemos', 'matlabhdlcoderdemos'); mlhdlc_temp_dir = [tempdir 'mlhdlc_dpack']; clear mex; cd (mlhdlc_demo_dir); rmdir(mlhdlc_temp_dir, 's');