Перейти к содержанию
    

stealthisname

Участник
  • Постов

    54
  • Зарегистрирован

  • Посещение

Весь контент stealthisname


  1. я попробовал обработать сигнал по вашему описанию, и появились вопросики вот сигнал на 256 отсчётов n = 256; f0 = 13.47/n; t = 0:n-1; s = exp(1i*2*pi*f0*t)+0.1*randn(1,n); plot(t,real(s),t,imag(s)); grid on; title('signal'); xlabel('time'); вот его БПФ f = t/n; stem(f,abs(fft(s))); grid on; title('fft'); xlabel('freq'); Какой бин в этом БПФ считать максимальным? что и как тут обнулять? что именно должно показывать ОБПФ в таком случае?
  2. информация в выложенных файлах и выложенный код позволяют построить и посмотреть АХ и КХ plot(K); hold on; plot(Kcorr); hold off; grid on; legend K K\_corr; если внимательно приглядеться к АХ, то можно увидеть участки, которые действительно не просто скомпенсировать предыскажением, так как для подобной функции не существует однозначной обратной функции у КХ есть участок, который, как будто бы вносит только больше искажений в сигнал, чем что-то корректирует. На сколько хорошо такая КХ работала на модулированном ВЧ-сигнале? в функции, вычисляющей прохождение сигнала через АХ и КХ (useCharacteristic), после поиска значений по таблице, результат ограничивается значениями [32767] и [-32768] plot(K); hold on; plot(Kcorr); plot(xlim,[32767,32767]); hold off; grid on; legend K K\_corr limit; если посмотреть этот предел на графиках, то можно увидеть что тактая функция (useCharacteristic) будет ограничивать значения у сигналов с полным размахом (в тесте используется именно сигнал с полным размахом), что вносит дополнительные искажения в сигнал
  3. 1) к сожалению, не удалось повторить такую ошибку у себя, но для эксперимента можно попробовать проверить что возвращают функции показывающие текущий путь (рабочую папку), при открытии приложения на ноутбуке из разных мест, например содержащие кириллицу в пути к файлу и без кириллицы, с пробелами в пути и без например такие currpath = cd currpath = pwd [~,currpath] = system('cd') [~,currpath] = system('pwd') если каким-то образом удастся получить текущую (рабочую) папку, то вызывать uigetfile({'*.bin;*.dat'}, 'Select a file with data...', currpath); 2) так как приложение не правильно определяет рабочую папку и поэтому не правильно работает с относительными путями, указать полный путь до файла [file, path] = uigetfile({'*.bin;*.dat'}, 'Select a file with data...'); name_file = fullfile(path, file); idat = read_bin_file(name_file,nsymbol);
  4. если изменять в данном фильтре только один коэффициент (который 0.375), то можно посмотреть как будет меняться АЧХ например, для коэффициентов кратных 1/8 k = (2:6)/8; % набор коэфициентов для построения c = {}; for i = 1:numel(k) b = [k(i),1,1,k(i)]/2; % коэфф числителя передаточной (numerator) a = [1,0,k(i)]; % коэфф знамениателя передаточной (denominator) c = [c,{b,a}]; % набор коэфф для fvtool end fvtool(c{:}); legend(compose('k = %g',k)); видно, что полоса по уровню минус 3дБ не изменяется при изменении коэффициента если считать что фильтр маленький, и если для проекта в котором он используется, всего 240 LC и ни одного DSP - это мелочь, то можно попробовать поставить несколько таких фильтров каскадом например выбрав коэффициент 1/2 (это даст ещё меньше сумматоров в схеме) n = 4; % максимум рассчитываемых каскадов k = 1/2; % выбранный коэффициент % коэфф одного звена b0 = [k,1,1,k]/2; a0 = [1,0,k]; b = b0; a = a0; c = {b,a}; for i = 1:n-1 % коэфф каскадного подключения b = conv(b,b0); a = conv(a,a0); c = [c,{b,a}]; % набор коэфф для fvtool end fvtool(c{:}) legend(compose('%d',1:n)) видно, что в таком случае частота среза будет потихоньку смещаться влево, при этом АЧХ не будет разваливаться, и даже подавление в полосе задержания будет расти если требуется подвинуть частоту среза намного сильнее, то такой способ не очень подойдёт, всё таки придётся копать в сторону использования других схем и других фильтров
  5. Pulse Generator и Pulse Generator 1 работают на разных частотах дискретизации Pulse Generator работает на указанном Fixed-step size = 0.05 в параметрах модели, Stop time равняется 10 секундам, или 200 отсчётам при Sample time = 0.05 Pulse Generator 1 работает на указанном Sample time = 1 в параметрах блока, Stop time равняется 10 секундам, или 10 отсчётам при Sample time = 1
  6. для элементов меню, которые являются непосредственно дочерними для окна , под функцией вызова подразумевается действие, которое должно выполняться при разворачивании списка подпунктов меню поэтому это действие может выполняться, если при наведении должен был развернуться список подпунктов меню, даже если никаких подпунктов там нет проблема должна решиться, если добавить единственный подпункт и уже на него назначить необходимое действие придётся делать лишний клик каждый раз при выборе файла, но это может оказаться лучше, чем неожиданные срабатывания когда не надо
  7. подойдёт ли для Ваших целей, с учётом необходимости зарегистрить для реализации в FPGA, вот такой фильтр? с передаточной функцией H(z) = (1 - z^-2) / (1 - K*z^-2); и такой АЧХ K1 = 1-1/10; K2 = 1-1/100; b1 = [1,0,-1]; a1 = [1,0,-K1]; b2 = [1,0,-1]; a2 = [1,0,-K2]; fvtool(b1,a1,b2,a2); или нужен именно ФВЧ и способ зарегистрить именно исходный ФВЧ?
  8. если частота сигнала меняется с течением времени, то действительно, построение спектра сигнала "в упор" не подойдёт, так как в таком построении будет упущена информация об изменении частоты сигнала во времени, поэтому для определения изменения частоты сигнала во времени, можно воспользоваться построением спектрограммы вот пример построения спектра "в упор" для определённого сигнала и построение спектрограммы для этого же определённого сигнала по спектрограмме в таком случае можно оценить изменение частоты сигнала во времени, и на основе такой обработки сигнала можно строить алгоритм определения частоты сигнала с течением времени
  9. может подойти что-то вроде такой схемы первый график - сигнал и порог, второй график - моменты превышения порога, третий график - с учётом игнорирования всех дальнейших значений исходного сигнала
  10. при использовании блока Goto с указанием global в параметре Tag visability, сигнал со входа блока Goto становится глобальным для всей модели, и его можно использовать в других местах этой модели с помощью соответствующего блока From например можно передать таким образом сигнал между блоками, которые даже не соединены
  11. можно начать c описывания и проверки упрощенной версии Вашего модуля например, если дать возможность пользователю блока самому выбирать режим работы с помощью входного порта Load, то без внутреннего состояния State, логика выхода в зависимости от выбранного режима будет предельно простой always @(*) //Логика автомата case (Load) parall_out: Q = D; //Параллельный вывод logic_shft_left: Q = D << M; //Логический сдвиг влево на М разрадов logic_shft_right: Q = D >> M; //Логический сдвиг вправо на М разрадов ring_shft_left: Q = {D[WIDTH-1:0], D[WIDTH]}; // Кольцевой сдвиг влево ring_shft_right: Q = {D[0], D[WIDTH:1]}; // Кольцевой сдвиг вправо serial_out: Q = qQ[0];// Выводим младший разряд входного числа default: Q = D; //Параллельный вывод endcase и не придётся использовать выход Q в описании работы с промежуточной переменной qQ при последовательном выводе // Логика для последовательного вывода always @ (posedge clk, negedge res) // По приходу тактового импульса, в выходную переменную будет записываться [0] разряд входного числа if (!res) qQ <= 0; else if ((Load == serial_out) && (enable == 1)) // enable служит для разрешения записи входного числа в промежуточную REG переменную qQ qQ <= D; else if ((Load == serial_out) && (enable == 0)) begin qQ <= {qQ[0], qQ[WIDTH:1]}; // Сдвигаем входное число вправо для передачи следующего разряда end весь модуль будет выглядеть так module Universal_Shift_Register #(parameter WIDTH = 5) // параметр позволяет быстро менять разрядность входного числа (clk, res, D, Load, M, enable, out_state); localparam parall_out = 1, logic_shft_left = 2, logic_shft_right = 3, ring_shft_left = 4, ring_shft_right = 5, serial_out = 6; input res, clk; input [WIDTH:0] D; //Входное число input [2:0] Load; //Выбор действия input [WIDTH:0] M; //Количество сдвигаемых разрядов input enable; output [WIDTH:0] out_state; reg [WIDTH:0] Q; //Результат reg [WIDTH:0]qQ; //Промежуточная переменная always @(*) //Логика автомата case (Load) parall_out: Q = D; //Параллельный вывод logic_shft_left: Q = D << M; //Логический сдвиг влево на М разрадов logic_shft_right: Q = D >> M; //Логический сдвиг вправо на М разрадов ring_shft_left: Q = {D[WIDTH-1:0], D[WIDTH]}; // Кольцевой сдвиг влево ring_shft_right: Q = {D[0], D[WIDTH:1]}; // Кольцевой сдвиг вправо serial_out: Q = qQ[0];// Выводим младший разряд входного числа default: Q = D; //Параллельный вывод endcase // Логика для последовательного вывода always @ (posedge clk, negedge res) // По приходу тактового импульса, в выходную переменную будет записываться [0] разряд входного числа if (!res) qQ <= 0; else if ((Load == serial_out) && (enable == 1)) // enable служит для разрешения записи входного числа в промежуточную REG переменную qQ qQ <= D; else if ((Load == serial_out) && (enable == 0)) begin qQ <= {qQ[0], qQ[WIDTH:1]}; // Сдвигаем входное число вправо для передачи следующего разряда end // Логика для реализации передачи результата assign out_state = Q; endmodule такая упрощенная версия модуля работает корректно во всех шести режимах для проверки использовался такой тестбенч: так как тут нет конфликта с выходом Q, то такая упрощенная версия модуля синтезируется
  12. берём данные из файла и определяем количество отсчетов на символ в записанном сигнале load('DataEtalonGenerator.mat'); y0 = Y; sps0 = (12.8/1.023); % 12.5122 % старый sps задаемся необходимым целым количеством отсчетов на символ и передискретизирем сигнал в новой тактовой sps = 20; % новый sps t0 = (0:numel(Y)-1).'; % старая шкала времени t = (0:(sps0/sps):numel(Y)-1).'; % новая шкала времени y = interp1(t0,y0,t,'spline'); % % plot(t0,y0,t,y); data_out_struct.time = []; data_out_struct.signals.values = y; data_out_struct.signals.dimentions = 1; в блоке Eye Diagram задаем указанное новое количество отсчетов на символ глаз диаграмма точно стала лучше на вид, по ней видно, с каких точек можно строить созвездие, период известен, так как мы сами задали количество отсчетов на символ в передискретизированном сигнале так как Вам точнее известна частота дискретизации записанного сигнала, Вы можете точнее передискретизировать записанный сигнал, а значит и получить лучший результат
  13. если ключом является начальное состояние регистра ПСП, то заданы два заранее не известных 256-разрядных числа: начальное состояние регистра ПСП (r) и номер определённой точки (n), в которой необходимо вычислить значение ПСП алгоритм получается следующим если в нулевом бите n ( в n[0]) единица, то вычисляем сдвиг ПСП на 2^0, если в n[1] единица, то вычисляем сдвиг ПСП на 2^1, если в n[2] единица, то вычисляем сдвиг ПСП на 2^2, и так далее, пока не дойдём до n[255] в конце вычислений ПСП будет сдвинута ровно на заданное n как уже было сказано выше в теме, матрицу для вычисления сдвига ПСП на заданное число можно посчитать заранее, всего придётся заранее вычислить 256 матриц для такой реализации алгоритма с каждым новым шагом понадобится регистрить вычисления на всё большее количество тактов, поэтому результирующая задержка на весь расчёт будет больше 256 тактов, но всё ещё намного меньше, чем расчёт рекурсивным алгоритмом
  14. что является ключом? начальное состояние регистра ПСП или полином обратной связи?
  15. процесс перехода от исходный четырёх информационных бит к кодовому слову из 4B12B - это не систематическое кодирование, а процесс перехода от первых двух триплетов к кодовому слову из 4B12B - это систематическое кодирование можно говорить о систематическом кодировании в конструкции кода, если разбить процесс получения кодовых слов вот так:
  16. в коде (24,12) размер кодируемого слова равен 12 бит, кодового слова - 24 бита количество вариантов выбора первого кодового слова равно (2^24) во всех этих вариантах выбора первого слова, вариантов выбора второго кодового слова уже (2^24 - 1), ведь повторяющихся кодовых слов не должно быть для третьего кодового слова (2^24 - 2), для четвертого - (2^24 - 3) и так далее всего кодовых слов (2^12) и всего вариантов кодовой конструкции (2^24)*(2^24 - 1)*(2^24 - 2)* ... *(2^24 - (2^12 - 1)) примерный расчёт в матлабе N = 0; for i = 0:(2^12 - 1) N = N + log2(2^24 - i); % disp(24 - log2(2^24 - i)) end disp(floor(N)) выдаёт, что для таких кодовых конструкций N равно примерно 98303 если я не ошибаюсь в расчетах и не учитываю лишние варианты, перебор которых можно избежать, то количество перебираемых вариантов для таких кодовых конструкций равно примерно что-то порядка 1.72E29592
  17. ели при поиске кодов достаточно перебрать 2^N вариантов, то чему в таком случае равно N для перебора, в котором можно будет обнаружить код Голея (24,12,8)? будут ли в таком случае перебраны все возможные кодовые конструкции с параметрами кода (24,12)?
  18. я так и не нашел утверждения напрямую, что это невозможно, но очень похоже на то, что это основа языка - в выражениях функции выдают только один выходной аргумент, в общем случае такое никак не провернуть выражение с = 3*real(c)+1i*imag(c); делает тоже самое, или в общем случае с = U(real(c),imag(c))+1i*V(real(c),imag(c)); тоже, что и x0 = real(c); y0 = imag(c); x = U(x0,y0); y = V(x0,y0); с = complex(x,y);
  19. конкретно для перехода из полярных координат к комплексному числу, есть способ записать в одну строчку без промежуточных переменных С = rho.*exp(1i*theta); после некоторого времени работы с комплексными вычислениями в matlab это выглядит и красиво и наглядно вариант через pol2cart и complex очевиден даже без комментариев, по справке к этим функциям промежуточные переменные в данном случае не выглядят как костыли и не мешают, напротив, дают дополнительную информацию при отладке в случае, когда идёт обработка больших массивов данных и потеря памяти на промежуточные переменные не допустима, выражение [x,y] = pol2cart(theta,rho); С = complex(x,y); clear x y; является полным аналогом того, что Вам необходимо по функционалу (но не по количеству строчек кода)
  20. пробуем работу Вашей функции pvec на неудобных данных (Y много больше X ) x = [3.2, 1, 2.5, 7.123456, 3, 2]; y = [2.1, 3, 6, 4, 3.5, 2]*100; [xVec, yVec] = pvec(x,y); plot(xVec,yVec); grid on; for i = 1:numel(x) text(x(i),y(i),num2str(i)); end явно не то, что хотелось, и чем больше разница по масштабу у осей - тем страшнее результат идём другим путём строим исходный график без стрелочек, для вычисления масштабов plot(x,y); если на результирующей картинке этот график не единственный, то добавляем другие построения, если они могут изменить размеры осей вычисляем отношение масштабов для нашего графика norm_coef = diff(xlim)/diff(ylim); компенсируем разницу в масштабах if(norm_coef<0) x_norm = x/norm_coef; y_norm = y; [xVec, yVec] = pvec(x_norm,y_norm); xVec = xVec*norm_coef; yVec = yVec; else x_norm = x; y_norm = y*norm_coef; [xVec, yVec] = pvec(x_norm,y_norm); xVec = xVec; yVec = yVec/norm_coef; end выводим график со стрелочками plot(xVec,yVec); grid on; for i = 1:numel(x) text(x(i),y(i),num2str(i)); end проверяем, что всё работает при другом отношении масштабов (X много больше Y ) x = [3.2, 1, 2.5, 7.123456, 3, 2]*123; y = [2.1, 3, 6, 4, 3.5, 2]; plot(x,y); norm_coef = diff(xlim)/diff(ylim); if(norm_coef<0) x_norm = x/norm_coef; y_norm = y; [xVec, yVec] = pvec(x_norm,y_norm); xVec = xVec*norm_coef; yVec = yVec; else x_norm = x; y_norm = y*norm_coef; [xVec, yVec] = pvec(x_norm,y_norm); xVec = xVec; yVec = yVec/norm_coef; end plot(xVec,yVec); grid on; for i = 1:numel(x) text(x(i),y(i),num2str(i)); end
  21. в справке матлаба, в разделе MATLAB Compiler описаны способы создания исполняемого файла и при использовании функции mcc результат "does not include MATLAB Runtime or an installer" при использовании Application Compiler (можно вызвать командой applicationCompiler или deploytool) визард предложит варианты установки MATLAB Runtime нужные библиотеки в исполняемый файл упаковываться не будут, но после установки MATLAB Runtime на компьютер без самого матлаба, ваши приложения будут запускаться и работать используя библиотеки из MATLAB Runtime после установки MATLAB Runtime нужной версии на компьютере пользователя, можно будет генерить это и другие приложения функцией mcc на Вашем компьютере, уже без лишних установок и не упаковывая библиотеки в исполняемый файл
  22. результат умножения 0x6CD * 0x3F = 0x1AC73 весь регистр P равен 0x00000001AC73 выбранные в настройках 32 разряда - это старшие разряды, они равны 0x00000001
  23. при объявлении аккумуляторов, указываем напрямую, что необходимо использовать блоки DSP (* use_dsp48="yes" *) reg [31:0] sig_B_dsp [0:3]; добавляем к нужному аккумулятору в соответствии с индексом integer i; always @(posedge clk) begin for (i = 0; i < 4; i = i + 1) begin if (reset) begin sig_B_dsp[i] <= 0; end else begin if (sig_ind == i) begin sig_B_dsp[i] <= sig_B_dsp[i] + sig_A; end end end end в результатах синтеза, проверяем, что сгенерились именно DSP без использования регистров логики я проверял на вот таком модуле:
  24. вектора значений X и Y известны x = [3.2, 1, 2.5, 7.123456, 3, 2]; y = [2.1, 3, 6, 4, 3.5, 2]; вычисляем значения, необходимые для функции quiver dx = diff(x); dy = diff(y); выводим график со стрелочками quiver(x(1:end-1),y(1:end-1),dx,dy,0); grid on; xlim([0;10]); ylim([0;10]); выводим очерёдность for i = 1:numel(x) text(x(i),y(i),num2str(i)); end как вариант можно вывести направление переходов по середине отрезков dx = diff(x); dy = diff(y); quiver(x(1:end-1),y(1:end-1),dx/2,dy/2,0); hold on; plot(x,y,'.-'); hold off; grid on; xlim([0;10]); ylim([0;10]); for i = 1:numel(x) text(x(i),y(i),num2str(i)); end в некоторых случаях так нагляднее
  25. по спецификации AMBA AXI Protocol Specification для AXI (mm): "the data bus, that can be 8, 16, 32, 64, 128, 256, 512, or 1024 bits wide" данные действительно могут иметь отличную от 32 или 64 разрядов ширину данных для AXI и AXIS для AXI Lite данные могут иметь ширину только 32 или 64 разрядов "Two options for data bus width are supported, either 32-bit or 64-bit."
×
×
  • Создать...