HDB3编解码设计实验
一、预备知识
预习Altera公司Quartus软件的使用方法
预习FPGA的基本编程技术
复习通信原理中关于HDB3编解码部分知识
二、编码模块设计
要设计一个实用的编码模块,首先要深入研究其编码规则及其特点,然后根据其编码规则设计符合电路特性的编码流程。HDB3的编码的规则包括:(1)将消息代码变成AMI码,AMI码的编码的规则是对码中的非“0”符号进行正负交替;(2)检查AMI中的连零的情况,当连零的个数小于4个时,保持AMI的码形不变;当连零的个数达到或者超过4个的时候则将非零码后的第4个“0”,替换成V码,其中V码得极性与前一非零码(+1或-1)极性保持一致,例如,前面的非零码是+1,则V码记为+V码;(3)完成插V操作后,检查2个相邻的V码之间非零码的个数是不是偶数,若为偶数,则将2个相邻V码中后一个V码得前一非零码后的第一个“0”变成B码,B码的极性与前一非“0”码得极性相反,同时B码后面的非“0”码极性进行正负交替变换,保证极性交替反转特性。
编码规则中出现的V、B码只是作为标识符,最终的电路实现还是“0”和“1”这两种逻辑电平,因此需采用二进制编码对“1”、“0”、V、B进行编码,“00”表示“0”,“01”表示“1”,“10”表示B,“11”表示V。根据编码规则和利用FPGA实现的特点,将编码过程:首先插入V码,然后插入B码,最后是单双极性变换。如果按照编码规则的顺序设计,应该首先进行单双极性变换,再完成插V码和B码后,还需要根据编码规则变换当前B码之后的非零码的极性,这需要大量的寄存器来保存当前的数据的状态,导致电路非常的复杂,占用大量的FPGA内部的逻辑单元,实现难度大,且成本高。HDB3编码过程示意图如图1所示。
图3 HDB3编码过程示意图
1、插入V码的过程及代码
插入V码得过程是对消息代码的连零串进行检测,一旦出现4个连零串的时候,就把第4个“0”替换成破坏符V,其他情况下消息代码原样输出。输入
的代码经插V操作后全部变换成双相码,即“0”变换成“00”,“1”变换成“01”,V变换成“11”。图2是插入V码过程的流程,代码输入到插V模块后,如果输入时“1”,则输出为“01”,同时计数器清零,如果输入是“0”,则对“0”的个数进行计数,当计数器计数到第4个“0”时,输出“11”作为V码,同时计数器要清零用于下一轮检测;计数器未满4个“0”,则输出代码“00”。
图4 插入V码过程的流程
基带信息码加入V码代码如下:
module add_v(data_in,EN,CLK,data_out);
input data_in,EN;
input CLK;
output [1:0]data_out;
reg[1:0]data_out;
reg[1:0]counter;//0计数器,
always @(posedge CLK)
if(EN==1)
begin
if(data_in==1'b1)
begin
counter<=0;
data_out<=2'b01;//对于1编码01,且从此对0开始计数
end
else if(counter==2'b11)
begin
counter<=0;
data_out<=2'b11;//当过去3个0,再来时将0变为V码,V编码为11
end
else begin
counter<=counter+1;
data_out<=2'b00;//对于0编码00
end
end
else data_out<=2'b00;
Endmodule
2 插入B码的过程及代码
当相邻两个V码之间有偶数个非“0”码时,则把后一个V码之前的第1个非“0”码后面的“0”码变换成B码。该模块的设计难点是在于插入B码的过程中涉及一个由现在事件的状态去控制过去事件状态的问题,按照实时信号处理的理论,这是无法实现的,这里使用两组4位移位寄存器。采用4位移位寄存器是根据HDB3编码规则的特点确定,经插V码后,连零串中的第4个“0”变成V码,代码中连零个数最多是3个,而插入B码操作是把后一个V码之前的第一个非零码之后的“0”变成B码,这个长度不超过3个“0”,因此只需要4位移位寄存器就可以通过判断是否插入B码得流程,2组4位移位寄存器在时钟的作用下逐位将数据移出,在移出的同时还需对寄存器的最低位进行操作,即判断是否插入B码,这部分功能的实现设置一个检测当前V码状态的标志位flag。
基带信息码加入B代码如下:
module add_b(addv_in,addb_out,CLK);
input [1:0]addv_in;
input CLK;
output [1:0]addb_out;
reg flag,v_flag;
reg even;
reg [1:0]dff[3:0];
initial
v_flag=0;
assign addb_out=(flag==0)&&(even==0)&&(v_flag==1)&&(dff[0]==2'b11)?2'b10:dff[3]; //B码有三个条件,按上依次为偶数个1;两个V码之间,且当前输入为V码
//从此也可以看出,输出会比输入延时4个周期,这是由编码规则决定的
//当满足条件是就变为B码,用10编码;不满足则不变
always @(posedge CLK)
begin
dff[3]<=dff[2];
dff[2]<=dff[1];
dff[1]<=dff[0];
dff[0]<=addv_in;//移位寄存器
end
always @(posedge CLK)
begin
if(dff[3]==1)
flag=flag+1;//flag用来在两个v之间标志1的奇,偶.嘉?,奇为1
else if(dff[0]==2'b11)
flag=0;//当输入为V码时,表示又一轮计奇偶开始
end
always @(posedge CLK)
if(dff[0]==2'b11)//当当前输入的编码为11,即V码时,标志even=1
begin
even=1;
v_flag=1;
end
else even=0;//研究发现,B码一定在两个V码之间,用even=0标志
endmodule
3 、单双极性变换过程及代码
分析HDB3码的编码规则,发现V码的极性是正负交替的,余下的“1”和B码的极性也是正负交替的,且V码的极性与V码之间的非零码极性一致。因此可以将所有的“1”和B码取出来做正负交替变换,而V码的极性则根据“V 码的极性与V码之前的非零码极性一致”这一点进行正负交替变换。具体操作是设置一个标志位flag,通过检测判断标志位的状态来确定是否进行单双极性变换,标志位要交替变换以实现“1”和“B”正负交替,V码得极性也根据标志位变换,图4是单双极性变换过程的流程,“10”表示输出正电平,“01”表示输出负电平,“00”表示输出为零电平。
图7 单双极性变换示意图
基带信息码单双极性变换代码如下:
module polar(addb_out,EN,polar_out,CLK);
input [1:0]addb_out;
output [1:0]polar_out;
input CLK,EN;
reg [1:0]polar_out;
reg even;
//偶数为0,奇数为1;01: 正电压;11: 负电压;00: 0电压
always @(posedge CLK)
if(EN==1)
begin
if(addb_out==2'b11)
//当输入为V码时,就要判断前一个输出的电压正负了,其应与前保持相同
//而且之后的电压变化以此为基础进行变化,如果前一个输出为正,则even==1 //此时输出也为正,这样之后进入if(even==1),电压极性为负
begin
if(even==1)
polar_out<=2'b01;//正1;
else
polar_out<=2'b11;
end
else if(addb_out==2'b01||addb_out==2'b10)//当输入为1码或B码时
if(even==1)
begin
even<=0;
//当又来了一个非0码(偶数)时,将其电压设负,并清标记为even<=1,这样//方便下一次对奇数非0码变化电压极性,保证了正负极性交替
polar_out<=2'b11;//负1;
end
else begin
even<=1;
//当出现第一个(奇数)非0码时,将其电压设为正,并标记even<=1
polar_out<=2'b01;
end
else polar_out<=2'b00;//输入为0码时,编码为00
end
else polar_out<=2'b00;
endmodule
4 、HDB3编码顶层代码
module HDB3(clk,EN,data_in,data_out);
input clk,EN;//EN为1时开始进行转换,为0时清零
input data_in;
output[1:0] data_out;
wire[1:0]V_out,B_out;
add_v add_v1(.data_in(data_in),
.EN(EN),
.CLK(clk),
.data_out(V_out));
add_b add_b1(.addv_in(V_out),
.addb_out(B_out),
.CLK(clk));
polar polar1(.addb_out(B_out),
.EN(EN),
.polar_out(data_out),
.CLK(clk));
Endmodule
Endmodule
顶层代码仿真图如下:
图9 HDB3编码仿真图
从仿真图可以看到基带码进行HDB3规则编码的正确性。
三、HDB3解码模块设计
1、V码检测过程和V、B码解码过程及代码
V码检测的同时进行正V码检测和负V码的检测,这两个检测模块的设计思想类似,这里对正V码检测模块进行详细的说明。为了方便描述,假如从正整流电路输入的信号为+P(正脉冲),从负整流电路输入的信号为-N(负脉冲)。+V码检测模块是在-N的控制下,对输入的+P进行检测。其原理是:当+P的上升沿到来时,对输入的+P的脉冲进行计数,当计数到1时,输出一个脉冲作为+V脉冲,同时计数器清零,在计数期间,一旦检测到-N信号脉冲,计数器立即清零,计数器重新从零计数。这是因为在两个+P脉冲之间,存在一个-N脉冲,说明第2个+P脉冲不是+V码,只有在连续两个+P脉冲之间无-N脉冲,才能说明这两个P脉冲在HDB3码中是真正同极性的,才可以判断第2个P脉冲实际上是+V码,达到检测+V码的目的。-V码检测原理与正V码检测类似,所不同的是,-V码检测电路是在+P控制下,对-N信号进行计数、检测和判定。
检测V码后,根据HDB3编码规则,只需将V码及之前3位码全部置零就可以同时完成扣V和扣B操作。这就会涉及到一个由现在事件状态决定过去事件状态的情况,仍可以采用两组4位移位寄存器解决。根据编码规则,V码是取代连“0”串中的第4个“0”,而B码总是出现在V码之前,且只相隔2个“0”,当输入是V码后,只需要同时将4位移位寄存器置零,即可同时完成V码和B 码得解码过程。扣除V码和B码后,还需要将双相码变成单相码,即当输入是“00”时输出“0”,输入是“01”时输出“1”,至此便完成了HDB3解码。
检测V代码如下:
module check_v(hdb3_in,CLK,checkv_out);
input [1:0] hdb3_in;
input CLK;
output[1:0] checkv_out;
reg [1:0] checkv_out;
reg [1:0] dff[4:0];
reg[2:0]cout;
reg flag;
reg en;
initial
en=0;
always @(posedge CLK)//移位寄存器,确保当前输入为V码时,将其前三位置为0
begin
dff[3]<=dff[2];
dff[2]<=dff[1];
dff[1]<=dff[0];
dff[0]<=hdb3_in;
end
always @(posedge CLK)
begin
if (dff[0]!=0)
//此部分主要是检测V码,判断当前输入非0码是否与前一非0码同极性,若
//同极性则flag=1;并用dff[4]储存当前非0码,方便下一次判断。
//其中,当en=0时表示是第一个非0码,之后的再进行比较
begin
if(en==1)
begin
if(dff[0]==dff[4])
begin
flag=1;
dff[4]<=dff[0];
end
else dff[4]<=dff[0];
end
else
begin
dff[4]<=dff[0];
en<=1;
end
end
if(flag==1)
//此部分是根据前面的flag来对输出进行控制,flag=1时,输出四个0,并在最
//后一次输出时将flag置为0以及将cout置为0,方便下一次的判断,要说明一//点是flag 的值//必须要马上变化,这样才会使当前输出正确
begin
if(cout<=3)
begin
checkv_out<=2'b00;
cout=cout+1;
if(cout==4)
begin
flag=0;
cout=0;
end
end
end
else
begin
checkv_out<=dff[3];
cout=0;
end
end
endmodule
HDB3解码的顶层模块如下:
module HDB3_recode(data_in,EN,CLK,data_out);
input data_in,EN;
input CLK;
output
data_out;
wire[1:0]hdb3,checkv_out;
reg data_out;
HDB3 HDB3_code(.clk(CLK),
.EN(EN),
.data_in(data_in),
.data_out(hdb3));
check_v cheeck_v(.hdb3_in(hdb3),
.CLK(CLK),
.checkv_out(checkv_out));
always@(posedge CLK)
begin
if(checkv_out==0)data_out<=0;
else data_out<=1;
end
endmodule
HDB3解码的仿真图:
图14 HDB3解码仿真图
从仿真图可以看出,正确的解码出基带码,但是由于电路的延时,解出的基带码比输入的基带码延迟12个时钟周期,所以为了达到更好的编解码效果,四、设计总结
通过本次实验,让我受益匪浅。课设之初,我们认真查找、学习了关于HDB3编译码和Quartus Ⅱ软件的资料和文献作为课程设计的知识储备。经过我们的努力,在老师同学的帮助下,我们顺利完成了课程设计,也掌握了通信原理系统设计的基本方法,达到了预期的目的。