📄 卷积码c源码.txt
字号:
int i, j, p;
int ReadBit = 0;
int WriteByte = 0;
int OutBit = 0;
int Now_States = 0;
int Temp_d, Temp_Hm, Temp_Lm;
unsigned char NowCod;
//表示处理非连续卷积码编码数据或者连续卷积码编码数据的第一个缓存
if((Star_Mode == 0) | (First_Use == 1)){
//初始化幸存路径结构
for(i=0; i<Path_Num; i++){
Survivor_Save[i].Sum_d = 0;
Survivor_Save[i].H_m32 = 0;
Survivor_Save[i].L_m32 = 0;
}
//首先:将幸存路径存储缓存装载满
for(i=0,j=1; i<Init_Num; i++){
//每个时刻输出2比特,和接收序列对应时刻的码组比较汉明距离
NowCod = InBuf[ReadBit/8] >> (6-ReadBit%8);//从接收序列中取出一个码组
NowCod = NowCod & 0x03;
ReadBit += 2;
//累加器:进行距离累加
for(p=0; p<j; p++){
Survivor_Save[p].Sum_d = Survivor_Temp[p].Sum_d;
Survivor_Save[p].H_m32 = Survivor_Temp[p].H_m32;
Survivor_Save[p].L_m32 = Survivor_Temp[p].L_m32;
Now_States = char(Survivor_Save[p].L_m32 & 0x3f);
Survivor_Temp[p].Sum_d = Survivor_Save[p].Sum_d +
WeightInt(NowCod ^ Branch_Tab[Now_States][0]);
Survivor_Temp[p].L_m32 = (Survivor_Save[p].L_m32<<1) | 0;
Survivor_Temp[p+j].Sum_d = Survivor_Save[p].Sum_d +
WeightInt(NowCod ^ Branch_Tab[Now_States][1]);
Survivor_Temp[p+j].L_m32 = (Survivor_Save[p].L_m32<<1) | 1;
}
j = 2 * j;
for(p=0; p<j; p++){
Survivor_Save[p].Sum_d = Survivor_Temp[p].Sum_d;
Survivor_Save[p].H_m32 = Survivor_Temp[p].H_m32;
Survivor_Save[p].L_m32 = Survivor_Temp[p].L_m32;
}
}
//用选择法对Survivor_Save[].Sum_d按由小到大排序
//在此可以不排序,但是排序后效果更好,可以减少Path_Num的个数
/*for(i=0; i<Path_Num-1; i++){
for(j=i+1; j<Path_Num; j++){
if(Survivor_Save[j].Sum_d < Survivor_Save[i].Sum_d){
Temp_d = Survivor_Save[i].Sum_d;
Temp_Hm = Survivor_Save[i].H_m32;
Temp_Lm = Survivor_Save[i].L_m32;
Survivor_Save[i].Sum_d = Survivor_Save[j].Sum_d;
Survivor_Save[i].H_m32 = Survivor_Save[j].H_m32;
Survivor_Save[i].L_m32 = Survivor_Save[j].L_m32;
Survivor_Save[j].Sum_d = Temp_d;
Survivor_Save[j].H_m32 = Temp_Hm;
Survivor_Save[j].L_m32 = Temp_Lm;
}
}
}//*/
OutBit = Init_Num;
First_Use = 0;
}
//第二步:对数据进行纠错译码
for( ; ReadBit<InLength*8; ){
//判决器:输出汉明距离最小的幸存路径的高32比特,有多个最小时输出任意一个
if(OutBit == Path_Length){
//输出最小路径的高32比特信息序列
OutBuf[WriteByte++] = char(Survivor_Save[0].H_m32>>24);
OutBuf[WriteByte++] = char(Survivor_Save[0].H_m32>>16);
OutBuf[WriteByte++] = char(Survivor_Save[0].H_m32>>8);
OutBuf[WriteByte++] = char(Survivor_Save[0].H_m32);
OutBit = 32;
}
//接收序列各个时刻的循环
//每个时刻输出2比特,和接收序列对应时刻的码组比较得到汉明距离
NowCod = InBuf[ReadBit/8] >> (6-ReadBit%8);//从接收序列中取出一个码组
NowCod = NowCod & 0x03;
ReadBit += 2;
//累加器:进行距离累加
for(j=0; j<Path_Num; j++){
Now_States = char(Survivor_Save[j].L_m32 & 0x3f);
Survivor_Temp[j].Sum_d = Survivor_Save[j].Sum_d +
WeightInt(NowCod ^ Branch_Tab[Now_States][0]);
Survivor_Temp[j].H_m32 = Survivor_Save[j].H_m32<<1 |
Survivor_Save[j].L_m32>>31;
Survivor_Temp[j].L_m32 = Survivor_Save[j].L_m32<<1;
Survivor_Temp[j+Path_Num].Sum_d = Survivor_Save[j].Sum_d +
WeightInt(NowCod ^ Branch_Tab[Now_States][1]);
Survivor_Temp[j+Path_Num].H_m32 = Survivor_Save[j].H_m32<<1 |
Survivor_Save[j].L_m32>>31;
Survivor_Temp[j+Path_Num].L_m32 = (Survivor_Save[j].L_m32<<1) | 1;
}
//比较器:比较各条路径的距离,保留相对较小的Path_Num条
//用选择法对Survivor_Temp[].Sum_d按由小到大排序
for(i=0; i<Path_Num; i++){
for(j=i+1; j<2*Path_Num; j++){
if(Survivor_Temp[j].Sum_d < Survivor_Temp[i].Sum_d){
Temp_d = Survivor_Temp[i].Sum_d;
Temp_Hm = Survivor_Temp[i].H_m32;
Temp_Lm = Survivor_Temp[i].L_m32;
Survivor_Temp[i].Sum_d = Survivor_Temp[j].Sum_d;
Survivor_Temp[i].H_m32 = Survivor_Temp[j].H_m32;
Survivor_Temp[i].L_m32 = Survivor_Temp[j].L_m32;
Survivor_Temp[j].Sum_d = Temp_d;
Survivor_Temp[j].H_m32 = Temp_Hm;
Survivor_Temp[j].L_m32 = Temp_Lm;
}
}
}
//将较小的Path_Num条存入幸存路径结构缓存
for(i=0; i<Path_Num; i++){
Survivor_Save[i].Sum_d = Survivor_Temp[i].Sum_d;
Survivor_Save[i].H_m32 = Survivor_Temp[i].H_m32;
Survivor_Save[i].L_m32 = Survivor_Temp[i].L_m32;
}
OutBit++;
}
//第三步:对数据尾部的处理,
//输出汉明距离最小的幸存路径的OutBit个比特(位权较低的OutBit个),有多个最小的输出任意一个
if(OutBit == 64){
OutBuf[WriteByte++] = char(Survivor_Save[0].H_m32>>24);
OutBuf[WriteByte++] = char(Survivor_Save[0].H_m32>>16);
OutBuf[WriteByte++] = char(Survivor_Save[0].H_m32>>8);
OutBuf[WriteByte++] = char(Survivor_Save[0].H_m32);
OutBuf[WriteByte++] = char(Survivor_Save[0].L_m32>>24);
OutBuf[WriteByte++] = char(Survivor_Save[0].L_m32>>16);
OutBuf[WriteByte++] = char(Survivor_Save[0].L_m32>>8);
OutBuf[WriteByte++] = char(Survivor_Save[0].L_m32);
}
else{
if(OutBit > 32){
Temp_Hm = (Survivor_Save[0].H_m32<<(64-OutBit)) | (Survivor_Save[0].L_m32>>(OutBit-32));
OutBuf[WriteByte++] = char(Temp_Hm>>24);
OutBuf[WriteByte++] = char(Temp_Hm>>16);
OutBuf[WriteByte++] = char(Temp_Hm>>8);
OutBuf[WriteByte++] = char(Temp_Hm);
OutBit -= 32;
}
Temp_Lm = Survivor_Save[0].L_m32 << (32-OutBit);
while(OutBit > 0){
OutBuf[WriteByte++] = char(Temp_Lm>>24);
Temp_Lm = Temp_Lm << 8;
OutBit -= 8;
}
}
//第四步:如果处理的是连续数据,要将较小幸存路径的汉明距离缩小,避免溢出
/*for(i=1; i<Path_Num; i++){
if((Survivor_Save[i].Sum_d - Survivor_Save[0].Sum_d) > Path_Length)
Survivor_Save[i].Sum_d = Path_Length;
else
Survivor_Save[i].Sum_d -= Survivor_Save[0].Sum_d;
}
Survivor_Save[0].Sum_d = 0;
//*/
//维特比译码结束
return WriteByte;
}
//---------------------------------------------------------------------------
int CViterbi_216::Encode_216(unsigned char * InBuf, int InLength, unsigned char * OutBuf, int Now_State)
{
int ReadBit;
int ReadByte;
int WriteBit;
unsigned char Now_m;
unsigned char Now_Encode;
for(ReadByte=0,WriteBit=0; ReadByte<InLength; ReadByte++){
for(ReadBit=0; ReadBit<8; ReadBit++){
Now_m = InBuf[ReadByte]>>(7-ReadBit);
Now_m = Now_m & 0x01;
Now_Encode = Branch_Tab[Now_State][Now_m];
Now_State = Now_State<<1 | Now_m;
Now_State = Now_State & 0x3f;
OutBuf[WriteBit/8] = (OutBuf[WriteBit/8]<<2) | Now_Encode;
WriteBit += 2;
}
}
if(WriteBit != 2*8*InLength)
return 0xff;
return Now_State;
}
//---------------------------------------------------------------------------
//文件名:WeightInt.h
//作 用:统计 int 数在二进制时“1”的个数
//作 者:蒋岩
//时 间:2005.6.1
//版 本:C--1.0
//---------------------------------------------------------------------------
int WeightInt(int x)
{
int countx = 0;
while(x)
{
countx ++;
x = x&(x-1);
}
return countx;
}
//每次将最低位的“1”去掉
//---------------------------------------------------------------------------
--格雷码计数器
module g_counter(clock,reset,qout);
input clock,reset;
ouput[1:0] qout;
reg [1:0] count,next_count;
always @(count)
case(count)
2'b00: next_count = 2'b01;
2'b01: next_count = 2'b11;
2'b11: next_count = 2'b10;
2'b10: next_count = 2'b00;
endcase
always @(posedge clock or negedge reset)
if(~reset)
count <= 2'h0;
else
count <= next_count;
assign qout = next_count;
endmodule
--格雷码计数器
1.【数字信号的发送和接收】:设计一个5位数字信号的发送和接收电路,把并行码变为串行码或把串行码变为并行码,串行偶校验检测器可通过异或实现。在数据接收端,只有在代码传送无误后,才把数据代码并行输出。数据传送的格式采用异步串行通信的格式,包含起始位、数据位、校验位、停止位和空闲位。
数据发送模块:将并行数据加上起始位、偶校验位和停止位,以串行方式发送出去。
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity send is
port(start:in std_logic;
a: in std_logic_vector(4 downto 0);
clk: in std_logic;
but std_logic);
end send;
architecture rt1 of send is
begin
process(clk,a)
variable temp:std_logic_vector(6 downto 0);
variable tmp,m:std_logic;
variable tmp1:integer range 0 to 7;
begin
if(clk even and clk='1')then
if(m='0')then --发送空闲位
tmp:='1';
end if;
if(start='0')then --start键有效
m:='1';
temp(5 downto 1):=a(4 downto 0); --数据位
temp(6):=a(4)xor a(3) xor a(2) xor a(1) xor a(0); --偶校验位
temp(0):='0'; --起始位
elsif(m='1') then
tmp:=temp(0); --发送数据
temp:='1'&temp(6 downto 1);
if(tmp1<7)then --一次发送8位数据,在最后加上停止位‘1’
temp:=temp1+1;
else
m:='0';
temp:="0000000";
tmp1:=0;
end if;
end if;
end if;
b<=tmp;
end process;
end rt1;
数据接收模块,当检测到起始位时,将数据位和校验位取出,若校验无误,则并行送出,若有误则报警。
library ieee;
use ieee.std_logic_1164.all;
entity rcv is
port(clk,re:in std_logic;
imput std_logic_vector(4 downto 0);
almut std_logic);
end rcv;
architecture rcv_arc of rcv is
begin
process(clk)
variable a:std_logic;
variable cnt:integer range 0 to 6;
variable shift:std_logic_vector(5 downto 0);
begin
if clk'event and clk='1' then
if a='0' then
if re='0' then --检测起始位
a:='1';
alm<='0';
end if;
else
if cnt<6 then
shift:=shift(4 downto 0)&re; --取出数据位和校验位
cnt:=cnt+1;
else
cnt:=0;
a:='0';
if(shift(0) xor shift(1) xor shift(2) xor shift(3) xor shift(4) xor shift(5)='0' then
imp<=shift(5 downto 1); --若校验无误,则送出
else
alm<='1'; --检测到错误则报警
end if;
end if;
end if;
end if;
end process;
end rcv_arc;
-------------------------------------------------
------------------------------------------------
G.703 E1的(crc-4)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -