polar编码是UCI大于12bit的编码,PUCCH和PUSCH传输UCI使用的都是polar编码
1.cb块分段和crc添加
cb块分段
if (A>=1013) || (A>=360 && Euci>=1088) % Use Euci here
C = 2;
Aprime = ceil(A/C)*C;
paddedUCI = zeros(Aprime,1,typeIn);
if Aprime~=A
% prepend filler bit
paddedUCI(2:end) = uciBits;
else
% no filler bit
paddedUCI = uciBits;
end
uciCBs = reshape(paddedUCI,[],C);
Lcrc = '11';
else % no segmentation
C = 1;
uciCBs = uciBits;
if A<=19
Lcrc = '6';
else
Lcrc = '11';
end
end
if isempty(coder.target) % Simulation path
% Initialize CRC encoder system objects for each NR polynomial
if isempty(encoders)
encoders = cell(1,6);
polyCell = {[1 1 0 0 0 0 1]', ... % '6'
[1 1 1 0 0 0 1 0 0 0 0 1]', ... % '11'
[1 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 1]', .... % '16'
[1 1 0 0 0 0 1 1 0 0 1 0 0 1 1 0 0 1 1 1 1 1 0 1 1]', ... % '24A'
[1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1]', ... % '24B'
[1 1 0 1 1 0 0 1 0 1 0 1 1 0 0 0 1 0 0 0 1 0 1 1 1]'}; % '24C'
for i = 1:6
encoders{i} = comm.CRCGenerator('Polynomial',polyCell{i});
%这块把求CRC封装起来了,后面把具体的细节再补充上。
end
end
encoder = encoders{polyIndex};
for i = 1:numCodeBlocks
blkcrcL(:,i) = encoder(blkL(:,i));
end
如何求CRC这个特殊说明一下:
CRC24A =[1 1 0 0 0 0 1 1 0 0 1 0 0 1 1 0 0 1 1 1 1 1 0 1 1];
CRC24B =[1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1];
CRC24C =[1 1 0 1 1 0 0 1 0 1 0 1 1 0 0 0 1 0 0 0 1 0 1 1 1];
CRC16 =[1 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 1];
CRC11 = [1 1 1 0 0 0 1 0 0 0 0 1];
CRC6 = [1 1 0 0 0 0 1];
input = [1 1 1 1 0 1 0 0 1 1 0 1 1];
type = 6;
switch type
case 240
CRC_G=CRC24A;
case 241
CRC_G=CRC24B;
case 242
CRC_G=CRC24C;
case 16
CRC_G=CRC16;
case 11
CRC_G=CRC16;
case 8
CRC_G=CRC8;
case 6
CRC_G=CRC6;
end %***end switch******
Input_Length = length(input);
Crc_Length = length(CRC_G);
Add_Crc_Bit = zeros(1,Crc_Length-1);
Uncode_Sequence = [input Add_Crc_Bit];
Crc_Register= Uncode_Sequence(1:Crc_Length);
% Crc_Register= fliplr(Uncode_Sequence(1:Crc_Length));
for k=1:1:Input_Length
if Crc_Register(1)==1
Crc_Register=bitxor(Crc_Register,CRC_G);
if (k~= Input_Length)
Crc_Register=[ Crc_Register(2:Crc_Length) Uncode_Sequence(k+Crc_Length)];
end
else
if (k~= Input_Length)
Crc_Register=[ Crc_Register(2:Crc_Length) Uncode_Sequence(k+Crc_Length) ];
end
end
end
2.UCI polar编码
这个是针对每个cb块进行的。
nMax = 10;
iIL = false;
% Check and set PC-Polar parameters
if (K>=18 && K<=25) % for PC-Polar, Section 6.3.1.3.1
nPC = 3;
if (E-K > 189)
nPCwm = 1;
else
nPCwm = 0;
end
else % for CA-Polar
nPC = 0;
nPCwm = 0;
end
1 .计算n,得到N
% Get n, N, Section 5.3.1
cl2e = ceil(log2(E));
if (E <= (9/8) * 2^(cl2e-1)) && (K/E < 9/16)
n1 = cl2e-1;
else
n1 = cl2e;
end
rmin = 1/8;
n2 = ceil(log2(K/rmin));
nMin = 5;
n = max(min([n1 n2 nMax]),nMin);
N = 2^n;
end
2 .交织 :UCI的时候没有做交织。dl的时候使用了。
if iIL
pi = nr5g.internal.polar.interleaveMap(K);
inIntr = in(pi+1);
else
inIntr = in;
end
%虽然再uci的时候没有用交织,还是把交织的过程做一下介绍,
Kilmax = 164;
pat = getPattern();
pi = zeros(K,1);
k = 0;
for m = 0:Kilmax-1
if pat(m+1) >= Kilmax-K
pi(k+1) = pat(m+1)-(Kilmax-K);
k = k+1;
end
end
end
3.polar编码
3.1此处只是求交织的顺序,不是真正做交织,对于这个交织的特点后续进一步补充,为了确定 Q_N_F和 Q_N_I
% Get sequence for N, ascending ordered, Section 5.3.1.2
s10 = nr5g.internal.polar.sequence; % for nMax=10
idx = (s10 < N);
qSeq = s10(idx); % 0-based 求出N,对应的
%polar序列的子集
% Get frozen, information bit indices sets, qF, qI 求冻结bit和信息bit索引集合
jn = nr5g.internal.polar.subblockInterleaveMap(N); % 0-based
qFtmp = [];
if E < N
if K/E <= 7/16 % puncturing
for i = 0:(N-E-1)
qFtmp = [qFtmp; jn(i+1)]; %#ok
end
if E >= 3*N/4
uLim = ceil(3*N/4-E/2);
qFtmp = [qFtmp; (0:uLim-1).'];
else
uLim = ceil(9*N/16-E/4);
qFtmp = [qFtmp; (0:uLim-1).'];
end
qFtmp = unique(qFtmp);
else % shortening
for i = E:N-1
qFtmp = [qFtmp; jn(i+1)]; %#ok
end
end
end
3.2 求出qPC的位置,包括有nPCwn和不包括两种
% PC-Polar
qPC = zeros(nPC,1);
if nPC > 0
qPC(1:(nPC-nPCwm),1) = qI(end-(nPC-nPCwm)+1:end); % least reliable
%本身qI里面就是从稳定性从高到低放着
if nPCwm>0 % assumes ==1, if >0. %nPCwm再E-K>189的时候会是1
% Get G, nth Kronecker power of kernel
n = log2(N);
ak0 = [1 0; 1 1]; % Arikan's kernel
allG = cell(n,1); % Initialize cells
for i = 1:n
allG{i} = zeros(2^i,2^i);
end
allG{1} = ak0; % Assign cells
for i = 1:n-1 %这是一种比较简单的方式,可以直接以此累计求,那个计算工作量就大了,后续专门出一个节专门介绍一下。
allG{i+1} = kron(allG{i},ak0);
end
G = allG{n};
wg = sum(G,2); % row weight
qtildeI = qI(1:end-nPC,1); %
wt_qtildeI = wg(qtildeI+1);
minwt = min(wt_qtildeI); % minimum weight 得到最小的权值
allminwtIdx = find(wt_qtildeI==minwt); %找到最小权值对应的位置,有可能有多个
% most reliable, minimum row weight is first value
qPC(nPC,1) = qtildeI(allminwtIdx(1));%多个权值一样中第一个就是最稳定的位置。
end
end
end
3.3 求出u 这时候还没有做子块交织。
% Generate u
u = zeros(N,1); % doubles only
if nPC > 0
% Parity-Check Polar (PC-Polar)
y0 = 0; y1 = 0; y2 = 0; y3 = 0; y4 = 0;
k = 1;
for idx = 1:N
yt = y0; y0 = y1; y1 = y2; y2 = y3; y3 = y4; y4 = yt;
if F(idx) % frozen bits 如果是冻结字节,就置零
u(idx) = 0;
else % info bits 如果是信息bit
if any(idx==(qPC+1)) 如果是qPC,赋值校验bit
u(idx) = y0;
else
u(idx) = inIntr(k); % Set information bits (interleaved)
k = k+1;
y0 = double(xor(y0,u(idx))); %求出校验bit y0
end
end
end
else
% CRC-Aided Polar (CA-Polar)
u(F==0) = inIntr; % Set information bits (interleaved)
end
% Get G, nth Kronecker power of kernel 求出n阶克罗内克积
n = log2(N);
ak0 = [1 0; 1 1]; % Arikan's kernel
allG = cell(n,1); % Initialize cells
for i = 1:n
allG{i} = zeros(2^i,2^i);
end
allG{1} = ak0; % Assign cells
for i = 1:n-1
allG{i+1} = kron(allG{i},ak0);
end
G = allG{n};
% Encode using matrix multiplication
outd = mod(u'*G,2)';
out = cast(outd,class(in));
3.4 速率匹配之子块交织
根据3.1求出的交织顺序进行重新排序。根据固定表格交织
out = in(jn+1);
3.5 速率匹配之bit选择
% Bit selection, Section 5.4.1.2
N = length(in);
outE = zeros(E,1,class(in));
if E >= N
% Bit repetition
for k = 0:E-1
outE(k+1) = y(mod(k,N)+1);
end
else
if K/E <= 7/16
% puncturing (take from the end)
outE = y(end-E+1:end);
else
% shortening (take from the start)
outE = y(1:E);
end
end
3.6 编码bit的交织—三角交织
实现的就是按照行进行存放到做上三角矩阵上,然后再按照列依次提取,实现的交织。实现的是行存列取。
到这个地方一个cb块的整个polar编码已经全部完成。
3.cb块链接
这个很简单,就是将cb块拼接到g就完事了。