前言
在之前的几篇文章中提到了HDB3编码和译码的课题,首先是使用MATLAB来实现了HDB3的编码和译码。感兴趣的可以前去了解一下HDB3 的编码与译码 ①(MATLAB 实现)随后又是在FPGA中实现了HDB3的编码,使用了Verilog语言,感兴趣的可以前去了解一下HDB3 的编码 ②(Verilog 语言实现)同时在上一篇文章中也给出了编码所参考的资料,其中也给出相应的解码过程,但是太过于复杂,并且和我的思路有所不一样,所以本篇文章主要还是介绍了自己的思路以及实现的流程,其中有几个步骤的关键节点也是卡了好长时间,参考了通信原理—FPGA—HDB3译码这篇文章才得以解决,同时这个大佬也写了很多有关于FPGA的知识,感兴趣的可以去大佬首页看一下。
一、HDB3译码
译码所采用的思路就是百度百科所给出的思路。
1、把原来的取代节(4个连零)找到,若3连“0”前后非零脉冲同极性,则将最后一个非零元素译为零,如+1000+1 就应该译成“10000”,否则不用改动;若2连 “0”前后非零脉冲极性相同,则两零前后都译为零,如-100-1,就应该译为0000,否则也不用改动.
2、再将所有的-1变换成+1后,就可以得到原消息码。
大题思路不需要做太多的变化,这其中最关键的就是将思路转换到FPGA的编程思路上来。
1.实现代码以及仿真结果
1.代码实现
编程的整体思路还是一步一步来,首先来看第一步。
要检测取代节并且要对照前后的数据这样还是需要移位寄存器,这次需要检测的是10001这样的结点,所以需要一个五位的移位寄存器。但这次不同的是,这次移位寄存器的数值不仅仅来进行判断,同时还要进行修改。又因为同一个寄存器不能在连个always中进行修改,所以这次的设计要将移位寄存器和修改代码放到一个always中。
实现代码:
module decode
(
Clk,Rstn_,
DataIn,DataO,DataOut_p
);
input Clk;
input Rstn_;
input [1:0] DataIn;
output DataO;
output [1:0] DataOut_p;
/****************取代节替换的设计************************/
reg [1:0] Data[4:0];
reg [1:0] count; //连 0 计数器
//reg [1:0] DataOut_p;
always @ (posedge Clk or negedge Rstn_)
if (!Rstn_)
begin
end
else
begin
Data[4] <= Data[3];
Data[3] <= Data[2];
Data[2] <= Data[1];
Data[1] <= Data[0];
Data[0] <= DataIn;
if(DataIn == 2'b00)
begin
count <= count + 1'b1;
//DataOut_p <= Data[4];
end
else //非零信号输入
begin
if(count == 2'd3)
begin
if(DataIn == Data[3])
Data[0] <= 2'b0; // 根据 <= 的滞后性 修改后一位
end
else if(count == 2'd2)
begin
if(DataIn == Data[2])
begin
Data[0] <= 2'b0; // 根据 <= 的滞后性 修改后一位
Data[3] <= 2'b0; // 进行这次判断之前 Data[2] 的数据已经移步到 Data[3]了 所以在此处修改Data[3]的值
end
end
count <= 2'b0;
// DataOut_p <= Data[4];
end
end
/****************信号输出************************/
assign DataOut_p = Data[4];
这其中的要注意众多的小细节,
第一个就是将数据往后打五拍,那么输出的信号自然就是打完最后一拍。
第二个就是 <= 非阻塞 赋值与时序问题。将移位寄存器和执行代码放到同一个always中,Data[0] 相对于 DataIn 就会落后一拍,所以在进行判断是使用的是 DataIn,在进行修改以及进行二次判断也就是连续两个或者三个0前后符号是否一致的判断是要仔细考虑一下,自己也是在这里卡了很长时间,这里需要特别注意下。尤其是连0等于2的情况,判断需要的值是Data[2] 和DataIn的值,修改的确实Data[3]的值,那是因为在这个always中前面的移位寄存器中, Data[2] 已经将自身的值给到了Data[3]但是他们两者这个时刻的值还没变。给了但没完全给。这个还是要自己多体会,多写在下一次自然也就会注意到。
第二步就相对简单一点。
只需要对输出的信号进行一个判断,然后在进行脉冲输出即可。由于这个输出是另外开的一个端口,所以可以放到另一个always中。
实现代码:
/****************极性修改************************/
reg DataO;
always @ (posedge Clk or negedge Rstn_)
if (!Rstn_)
begin
end
else
begin
if(DataOut_p == 2'b00) //输出信号时0 就输出低电平
DataO <= 1'b0;
else //输出信号是其他值也就是±1, 就输出高电平
DataO <= 1'b1;
end
2.仿真结果
这里可以看到输出的波形和原始波形一样。同时也给出前几个步骤的仿真结果。
总结
通过这次完成对HDB3编码和译码的过程,了解到自身的缺陷还是很多,比如MATLAB使用的不充分,不爱用MATLAB是一个很严重的弊端。在FPGA的编程上还是不知道如何出手,使用状态机和不使用状态机的情况分不清楚。切入点找不到。一些仿真工具还不会使用,这就是一个致命的缺陷。同时还有时序问题,很自然而然的就将串行编程的思维靠到并行编程的思维上了,考虑问题还不够仔细。不过通过这一个小课题使得自己能够全面的认识到问题的所在,就还好,养成一个良好的编程习惯,养成使用新工具的习惯。这个课题结束了,希望自己下一个课题能够有所进步。