通信原理---FPGA---HDB3译码
参考我的上两篇HDB3编码,给出HDB3译码的Verilog实现
https://blog.****.net/dengfenglai123/article/details/79674063(编码)
https://blog.****.net/dengfenglai123/article/details/79675933(编码--续)
译码规则主要参考下面的资料
https://baike.baidu.com/item/HDB3%E7%A0%81/3815309?fr=aladdin(译码主要参考资料)
(1)若3连“0”前后非零脉冲同极性,则将最后一个非零元素译为零,如+1000+1 就应该译成“10000;若2连 “0”前后非零脉冲极性相同,则两零前后都译为零,如-100-1应译为0000
(2)将-1、+1变成1,0就输出0,即输入为“10”或“01”时输出“1”,输入为“00”时输出“0”
在判断过程中需要对正在判断的码的前面的码进行操作,需要使用移位寄存器(否则前面的码已经输出,无法更改),在判断时需要特别注意在比较3连“0”或2连“0”时的前后脉冲极性时,要找准当前的codein和谁比,在3连“0”时要和buffer3(前面第4个数)比,在在2连“0”时要和buffer2(前面第3个数)比,这部分涉及时序的问题,和非阻塞赋值“<=”有关,大家如果弄不清楚可以画个移位寄存器的图或者波形图,我在这地方耗费了不少时间,最后画个图就清楚自己错在哪了
此外,还有一个Verilog的语法问题以前没有注意到,这次编程遇到了,记录一下,作为我的学习笔记,也希望大家不要犯这种错误。
Error (10028): Can't resolve multiple constant drivers for net "buffer1[0]" at decode.v(47)
原本移位寄存器写在一个单独的always里面的,这样在判断到需要将原来的V和B变为0时,因为是并行的,就会有两个信号同时要操作buffer0(或者buffer3),那么就没有办法判断到底该接收哪一个的赋值,这是不允许的,所以将移位寄存器和对buffer的操作放在了一个always里,这时候,对于“<=”来说,若有多个赋值,会接收最后一个赋值的信号。
always @ ( posedge clk or negedge rst_n )
begin
if( !rst_n ) begin
count0 <= 0;
end
else begin
buffer0 <= codein; //移位寄存器延时
buffer1 <= buffer0;
buffer2 <= buffer1;
buffer3 <= buffer2;
buffer4 <= buffer3;
if( codein == 2'b01 || codein == 2'b10 ) begin //输入1
if( count0 == 2'b10 ) begin
if( codein == buffer2 ) begin //此处非常关键
buffer0 <= 2'b00;
buffer3 <= 2'b00;
end
end
else if( count0 == 2'b11 ) begin
if( codein == buffer3 ) //此处非常关键
buffer0 <= 2'b00;
end
count0 <= 0;
codeout_2 <= buffer4;
end
else if( codein == 2'b00 ) begin //0
count0 <= count0 + 1;
codeout_2 <= buffer4;
end
end
end
always @ ( posedge clk )
begin
if( codeout_2 == 2'b00 ) begin
codeout <= 1'b0;
end
else if( codeout_2 == 2'b10 || codeout_2 == 2'b01 ) begin
codeout <= 1'b1;
end
end
原输入:
消息码: 1 0 0 1 1 0 0 0 0 1 0 1 1 0 1 0 0 0 0 1 1 1 1 0
AMI码: +1 0 0 -1 +1 0 0 0 0 -1 0 +1 -1 0 +1 0 0 0 0 -1 +1 -1 +1 0
加V : +1 0 0 -1 +1 0 0 0 +V -1 0 +1 -1 0 +1 0 0 0 +V-1 +1 -1 +1 0
加B : +1 0 0 -1 +1 0 0 0 +V -1 0 +1 -1 0 +1 -B 0 0 -V -1 +1 -1 +1 0