HDB3 译码器
一、HDB3译码方案一:
插入V/B的情况是有两种,两个或三个零两端同极性,也就是要把代码二进制表示的“+1 0 0 0 +1”或“-1 0 0 0 -1”变成“1 0 0 0”,把“+1 0 0 +1”或“-1 0 0 -1”变成“0 0 0 0”,最后再把两位二进制表示的+1和-1都变成‘1’,两位二进制表示的0都变成一位二进制表示的‘0’就可以了。
方案一代码:
--hdb3译码 --译码对应的是两位二进制表示的hdb3编码,10表示-1;01表示+1;00表示0 library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY hdb3_decoder IS PORT( clk : IN STD_LOGIC; h : INOUT STD_LOGIC_VECTOR(1 downto 0) ; coderout : out STD_LOGIC ); END ENTITY hdb3_decoder ; ARCHITECTURE decoder OF hdb3_decoder IS SIGNAL reg0 : STD_LOGIC_VECTOR(4 downto 0); --两个五位寄存器 SIGNAL reg1 : STD_LOGIC_VECTOR(4 downto 0); BEGIN process (clk,h,reg0,reg1) BEGIN if(clk'EVENT AND clk = '1') then reg0 <= h(0) & reg0(4 downto 1); reg1 <= h(1) & reg1(4 downto 1); if (h(0)='1' and h(1)='0' and reg0(4 downto 1)="0001"and reg1(4 downto 1)="0000") -- +1000+1 译码10000 then reg0 <= "00001"; reg1 <= "00000"; elsif (h(0)='0' and h(1)='1' and reg0(4 downto 1)="0000"and reg1(4 downto 1)="0001") -- -1000-1 译码10000 then reg0 <= "00001"; reg1 <= "00000"; elsif (h(0)='0' and h(1)='1' and reg0(4 downto 2)="000"and reg1(4 downto 2)="001") -- -100-1 译码0000 then reg0 <= "0000" & reg0(1); reg1 <= "0000" & reg1(1); elsif ( h(0)='1' and h(1)='0' and reg0(4 downto 2)="001" and reg1(4 downto 2)="000") -- +00+1 译码0000 then reg0 <= "0000" & reg0(1); reg1 <= "0000" & reg1(1); end if; end if; end process; process(clk) begin if (clk'EVENT AND clk = '1') then if reg0(0)='1' or reg1(0)='1' then --把+1(01)、11(-1)译码成一位 1 coderout<='1'; --elsif reg0(0)='1' and reg1(0)='0' -- then coderout<='1'; else coderout<='0'; -- 00 译码为 0 end if; end if; end process;
二、HDB3译码方案二:
对输入的H+和H-分别设立一个五级缓存移位寄存器,每一拍都判断是否存在10001,或1001X;若存在分别改成00001,或0000X。再将H+和H-相或输出。
方案二代码:
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY hdb3_decoder IS PORT( clk : inout STD_LOGIC; --h : in STD_LOGIC_VECTOR(1 downto 0); hp : in STD_LOGIC; hn : in STD_LOGIC; clkout :out STD_LOGIC; outcoder : out STD_LOGIC ); END ENTITY hdb3_decoder ; ARCHITECTURE decoder OF hdb3_decoder IS SIGNAL reg0 : STD_LOGIC_VECTOR(4 downto 0); --两个五位寄存器 SIGNAL reg1 : STD_LOGIC_VECTOR(4 downto 0); SIGNAL hh : STD_LOGIC_VECTOR(4 downto 0); --两个五位寄存器 SIGNAL hl : STD_LOGIC_VECTOR(4 downto 0); BEGIN clkout <= clk; PROCESS (clk,reg0,reg1) BEGIN if(clk'EVENT AND clk = '1') then --上升沿 reg0 <= hn & reg0(4 downto 1); reg1 <= hp & reg1(4 downto 1); if(reg0 = "10001") then reg0 <= "10000"; elsif (reg0 = "10010" or reg0 = "10011") then reg0 <= "0000" & hn; end if; if(reg1 = "10001") then reg1 <= "10000"; elsif (reg1 = "10010" or reg1 = "10011") then reg1 <= "0000" & hp; end if; end if; hl <= reg0; hh <= reg1; end PROCESS; outcoder <= (hh(4) or hl(4)); end decoder;
说明:译码因为仿真时需要每个符号需要赋值两位比较麻烦,我在确认HDB3编码没问题的基础之下,把编码和译码在Quartus II 中封装起来,用原理图连接起来,若输入和输出是一样的,则译码没有问题。我已调试过,上面两个程序都可以,在最终时分多路数字电话基带传输系统的设计中译码选用的是方案一。
电路原理连接如下:
仿真图:
1、输入随机数码
2、 输入全0码
3、输入全1码
感悟:
以前写的大多是顺序语句,这次利用VHDL语言完成课程设计的过程中,进一步熟悉和利用VHDL里的并行语句,例如进程等进件层次的使用。VHDL是一种硬件描述语言,用来描述硬件系统。硬件系统中的电路是由很多元器件构成的,从上电那一时刻起,硬件系统中所有的电路模块(元器件)将会同时开始工作,没有先后顺序,可以用VHDL中的并行语句实现。因此,结构体中的所有语句都须是“并行语句”,每个并行语句描述一个电路模块。并行语句之间没有先后顺序,可按任意顺序书写。这就像画电路图,先画哪个电路模块是没有关系的,只要最终画完的硬件系统电路图是正确的就行。然而,人们描述一个系统的“行为”却是按照“因果”关系来描述的,例如,“因为...所以...”(IF...THEN...)。这种描述方式称之为”行为描述“,描述行为的语句是顺序语句。顺序语句不符合硬件的并行工作状态,因此不能直接置于结构体中。为了遵循结构体中的语句都是并行语句这一语法规则,将一系列顺序语句构成的行为描述看成是一个电路模块,将其包装成一个并行语句“PROCESS BEGIN....END PROCESS;”,相当于在c语言中给这段行为描述加了一对括号,左括号是PROCESS BEGIN,右括号是END PROCESS。任意两个PROCESS语句之间也是并行关系,书写的先后顺序可以任意,与其他并行语句的书写顺序也可以任意。如果用顺序语句来描述硬件,就要给顺序语句加上“外包装“——”PROCESS BEGIN....END PROCESS;”。