Function [H_OUT,W_out,CKO_OUT] = shary_disp_posle_kv
(IN,CKOt,razr,Kh,M);
N = length(IN);
K = Kh/2;
Nh_ocenok = floor(N/Kh);
N_razr = 2^razr;
Wg = N_razr;
for k=1:Nh_ocenok
H_OUT(((k-1)*K+1):((k-1)*K+K),:) = hilb_tran
(floor(IN(((k-1)*Kh+1):(k-1)*Kh+Kh).*Wg./N_razr));
X = abs(H_OUT(((k-1)*K+1):((k-1)*K+K),1));
Y = abs(H_OUT(((k-1)*K+1):((k-1)*K+K),2));
CKO_out = floor(sum(X.^2+Y.^2)./Kh);
Xn = IN(((k-1)*Kh+1):((k-1)*Kh+Kh));
CKO_in = floor(sum(Xn.^2)./Kh) ;
Qm = floor(2*M*N_razr)*(CKOt.^2-CKO_out);
Qd = floor(Qm/CKO_in);
Wg = Wg + Qd;
CKO_OUT(k) = sqrt(sum(H_OUT(((k-1)*K+1):((k-1)*K+K),1).^2
+ H_OUT(((k-1)*K+1):((k-1)*K+K),2).^2)./Kh);
end
W_out=Wg / N_razr;
Приложение Б
Программный код модели, демонстрирующий работу системы ШАРУ
function shary_disp_demo
close all
% noise.txt содержит дискретные отсчеты шума в виде таблицы,
% в которой первый столбец - номер отсчета, второй - значение %шума.
IN = load('noise.txt');
NOISE = IN(:,2);
%параметры
razm = 15;
N_razm = 2^razm;
CKOt = 70;
K = 32;
M = 0.01;
% расчет СКО в процессе подстройки для 3х случаев
g=0;
for G = [0.5 1 2]
X = NOISE.*G; % при 1 cko примерно 70
g = g+1;
[Y(:,g), W_out, Wgp(:,g),CKO_OUT(:,g)] =
shary_disp_do_kv(X,CKOt,razm,K,M);
K_ocenok = floor(length(NOISE)/K);
for k=1:K_ocenok
D_S = ((k-1)*K+1):((k-1)*K+K);
CKO_SHUM_IN(k,g) = sqrt(sum(X(D_S).^2)/K);
end
end
%изменение шума в процессе подстройки для G=2
OUT(1:1999) = 2*NOISE(1:1999);
OUT(2000:2000+length (Y(:,3))-1) = Y(:,3);
OUT = OUT(1:8000);
figure (1)
plot( OUT)
grid on
% графики изменения СКО в процессе подстройки для 3х случаев
figure(2)
subplot(2,1,1)
plot(K:K:K_ocenok*K, CKO_SHUM_IN')
grid on
legend('CKO IN (IN*0.5)','CKO IN (IN*1)','CKO IN (IN*2)')
hold on
subplot(2,1,2)
plot(K:K:K_ocenok*K,CKO_OUT')
grid on
legend('CKO OUT (IN*0.5) ','CKO OUT (IN*1) ','CKO OUT (IN*2) ')
hold on
% функция моделирующая алгоритм работы ШАРУ
function [Y,W_out, Wgp, CKO_OUT] =
shary_disp_do_kv(X,CKOt,razr,K,M);
N = length(X);
N_ocenok = floor(N/K);
N_razr = 2^razr;
Wg = N_razr; % расчет необходимого G(целого)
Dt = CKOt^2;
for k=1:N_ocenok
Z(((k-1)*K+1):((k-1)*K+K)) = floor(X( ((k-1)*K+1):
((k-1)*K+K)).*Wg./N_razr);
Zn = Z(((k-1)*K+1):((k-1)*K+K));
Xn = X(((k-1)*K+1):((k-1)*K+K));
Dz = floor(sum(Zn.^2)/K) ;
Dx = floor(sum(Xn.^2)/K) ;
Qm = floor(2*M*N_razr)*(Dt-Dz);
Qd = floor(Qm/Dx);
Wg_new = Wg+Qd;
If Wg_new>N_razr*2
Wg = N_razr*2;
Elseif Wg_new<N_razr/2
Wg = N_razr/2;
else
Wg = Wg_new;
end
CKO_OUT(k) = floor(sqrt(floor(sum(Zn.^2)/K)));
Wgp(k) = Wg;
end
Y = Z;
W_out = Wg;
Приложение В
Функциональная схема ШАРУ
Рис.
Приложение Г
Программный код модуля ШАРУ
//n =15, TRANS_COEF[n+1] т.е. верхняя граница - усиление в 2 //раза.
// нижняя граница - 2^15/2=32768/2=16384=2^14 - ослабление в 2 //раза
module block_shary#( parameter
WIDTH= 12, //входное слово 11+знак в прямом коде
n= 15, //значение единичного коэффициента передачи
// т.е. W=1 -- Wq=2^n
k= 5, // кол-во усреднений 2^k
DISP_ET= 4900)// CКО=70, DISP=70^2
( input clk,
input enable,
input [WIDTH-1:0] IN,
output reg [WIDTH-1:0] OUT,
//transmission coefficient
output reg [n:0] TRANS_COEF
);
localparam N= 1 << n, //2^n;
K= 1 << k, //2^k;
SPEED_COEF= 2*N/100, //2*M*N, M=0.01
TRANS_COEF_min= 1 << (n-1),
TRANS_COEF_CORR_max=4096;
initial TRANS_COEF= N;
reg [k-1:0] i;
reg [3:0] j; //max(j)= Width-2
// т.е. 10, что умещается в 4 разряда.
wire clk_on;
reg accum;
reg [WIDTH-1:0] OUT_tmp;
reg [WIDTH+n:0] OUT_mod_tmp;
reg OUT_zn_tmp1,OUT_zn_tmp2,OUT_zn_tmp3,OUT_zn_tmp4;
reg [WIDTH+WIDTH-3:0] OUT_kv;
reg [WIDTH+WIDTH-3:0] IN_kv;
reg [WIDTH+WIDTH-3:0] DISP_IN; // Dispersion on input
reg [WIDTH+WIDTH-3:0] DISP_IN_tmp;
reg [WIDTH+WIDTH-3+k:0] DISP_IN_sum;
// Dispersion on output
(*preserve*)reg [WIDTH+WIDTH-3:0] DISP_OUT;
reg [WIDTH+WIDTH-3+k:0] DISP_OUT_sum;
reg [WIDTH+WIDTH-3:0] DISP_ERROR;
//numerator to find the correction
reg [WIDTH+WIDTH-3+n-6:0] NUM_TO_CORR;
//correction of the transmission coefficient
reg [n-1:0] TRANS_COEF_CORR;
reg TRANS_COEF_CORR_zn;
wire [n-1:0] TRANS_COEF_CORR_tmp;
reg [n+1:0] TRANS_COEF_tmp;
assign clk_on = enable ? clk : 1'b0;
//полечение выходных значений, задержка знака, проверка на //переполнение.
always @(posedge clk)
begin
OUT_zn_tmp1<= IN[WIDTH-1];
OUT_zn_tmp2<= OUT_zn_tmp1;
OUT_zn_tmp3<= OUT_zn_tmp2;
OUT_zn_tmp4<= OUT_zn_tmp3;
if( OUT_mod_tmp[WIDTH+n:WIDTH+n-1]==2'b00)
begin
OUT_tmp <= { OUT_zn_tmp4, OUT_mod_tmp[WIDTH-2+n:n] };
end
else
begin
for (j=0; j<=WIDTH-2; j= j+1)
begin
OUT_tmp[j] <= 1;
end
OUT_tmp[WIDTH-1] <= OUT_zn_tmp4;
end
end
// выдача результата по заднему фронту
always @(negedge clk)
begin
OUT <= OUT_tmp;
end
// подстройка TRANS_COEF при enable = 1
always @(posedge clk_on)
begin
i <= i+1;
//накопление дисперсий
if(!accum)
begin
DISP_IN_tmp <= DISP_IN_sum >> k;
DISP_IN_sum <= IN_kv;
DISP_OUT <= DISP_OUT_sum >> k;
DISP_OUT_sum <= OUT_kv;
end
else
begin
DISP_IN_sum <= DISP_IN_sum + IN_kv;
DISP_OUT_sum <= DISP_OUT_sum + OUT_kv;
end
case(i)
0: begin
accum <= 0;
end
1: begin
Accum <= 1;
//сигнал ошибки и знак корректировки
if(DISP_ET >= DISP_OUT)
begin
DISP_ERROR <= DISP_ET - DISP_OUT;
TRANS_COEF_CORR_zn <= 0;
end
else
begin
DISP_ERROR <= DISP_OUT - DISP_ET;
TRANS_COEF_CORR_zn <= 1;
end
end
4: begin // подача знаменателя на делитель
DISP_IN <= DISP_IN_tmp;
end
29: begin // ограничение корректировки сверху
if(TRANS_COEF_CORR_tmp < TRANS_COEF_CORR_max)
begin
TRANS_COEF_CORR <= TRANS_COEF_CORR_tmp;
end
else
begin
TRANS_COEF_CORR <= TRANS_COEF_CORR_max;
end
end
30: begin // рассчет коректировки
if(!TRANS_COEF_CORR_zn)
begin
TRANS_COEF_tmp <= TRANS_COEF + TRANS_COEF_CORR;
end
else
begin
TRANS_COEF_tmp <= TRANS_COEF - TRANS_COEF_CORR;
end
end
31: begin // проверка границ регулирования и введение
// корректировки
if(TRANS_COEF_tmp[n+1]||(TRANS_COEF_tmp<TRANS_COEF_min))
begin
TRANS_COEF <= TRANS_COEF ;
end
else
begin
TRANS_COEF <= TRANS_COEF_tmp;
end