2009-06-14
评论9
楼主 2009/6/14 16:42:27
具体分频的VHDL 的实现如下:
PROCESS(clk,clr)
BEGIN
IF(clk'EVENT AND clk='1') THEN —原始时钟
IF(clr='1' or count2=''11'')THEN —清零
count2 < = ''00'';
ELSE
count2﹤=count2+''01''; —计数,上升沿加l
END IF ;
END IF ;
END PROCESS ;
clk1x﹤=clk ; —生成clklx , clk2x
clk2x<=count2(0) ;
楼主 2009/6/14 16:42:56
设计一个40 计数器来控制信号各部分的封装。其VHDL 源程序如下:
PROCESS (clk1x , clr , en)
BEGIN
IF ( clr= 'l') THEN
count40<= "000000"; —清零
ELSIF ( clklx'EVENT AND clklx ='l ' ) THEN
IF (count40 = "100111") THEN
count40<="000000";
ELSIF (en ='1') THEN
count40<=count40+'l'; —计数0-39
END IF ;
END IF ;
END PROCESS ;
楼主 2009/6/14 16:43:13
由于要在数据的开始加入同步字头,因此在开始的3位数据会丢失,需要设计一个移位寄存器来保存由于同步字头加入的数据丢失,即将数据整体往后延时6个clk1x时钟周期。其VHDL 源程序如下:
PROCESS(clk2x,d,en) —en为编码使能信号,d为输入信号BEGIN
IF(clk2x'EVENT AND clk2x='l')THEN —clk2x 上升沿
IF(en='l')THEN
reg3<=d;
reg2<=reg3;
regl<=reg2; —3位移位寄存器
END IF;
din<=reg1;
END IF;
END PROCESS ;
楼主 2009/6/14 16:43:31
奇校验的VHDL 源程序如下:
PROCESS (din,count40,clk2x,en) —count40 为40 计数
BEGIN
IF(clk2x'EVENT AND clk2x = 'l') THEN
IF(count40>="000110"AND count40<="100101") THEN
jo<=jo XOR din;
—在计数6-37时,即16位数据输入时进行奇校验
ELSIF(count40>="000000"AND count40<="000101") THEN
jo<='0';
—在0-5时不进行校验,可用来清零,否则下次校验可能出错END IF ;
END IF ;
END PROCESS ;
楼主 2009/6/14 16:44:24
编码两种方案的VHDL 源程序具体如下:
方案一:PROCESS ( clk , clr )
BEGIN
IF(clr='l')THEN
ql<='0';
ELSE
ql<= NOT(clk XOR d ); —ql为同或编码
END IF;
END PROCESS ;
方案二:PROCESS ( clk,clr)
BEGIN
IF(clk'EVENT AND clk='l') THEN
dl<=d; —dl为d,d2为d的非,待二选一输入d2<= NOT d ;
END IF;
IF(clr='1') THEN
q2<='0';
ELSIF(clk='0') THEN
q2<=d2;
ELSIF(c1k='l') THEN — 二选一选择器
q2<=dl ;
ENDIF ;
END PROCESS
帧封装模块的VHDL 源程序如下:
PROCESS(din,en,clr,jo,cnmd,clk2x,clklx,count40)
—din通过3位寄存器的数据
BEGIN
IF(count40>="000000"AND count40<="000010")THEN
—0-2生成同步字头前3位
mo<=cnmd ;
ELSIF(count40>="000011"AND count40<="000101")THEN
—3-5生成同步字头后3位
mo<=NOT cnmd ;
ELSIF(count40>="000110"AND count40<="100101")THEN
—6-37同或生成曼码
mo<=NOT(din XOR clk2x) ;
ELSIF(count40>="100110"AND count40<="100111") THEN
—38-39 异或生成奇校验曼码
mo<=(jo XOR clk2x); — 如果同或则为偶校验
ELSE
mo<=' 0';
END IF ;
IF(clr='l')THEN
q<='0';
ELSIF(clklx'EVENT AND clklx='l') THEN —去毛刺
q<=mo;
END IF ;
END PROCESS ;
解码使用的计数器是基于clk2x 的M17 计数器。其VHDL源程序如下:
PROCESS (clk2x, clr, den)
BEGIN
IF(clr='l') THEN — 清零
countl7<="00000";
ELSlF (clk2x'EVENT AND clk2x='1') THEN —clk2x 上升沿
IF(count17<= "10000") THEN
countl7<="00000"; —计数 0-16即17 计数ELSIF(den='l')THEN
countl7<=countl7 +'l';
END IF ;
END IF;
END PROCESS;
楼主 2009/6/14 16:45:58
检测到同步字后产生一个持续16 个clk2x周期的数据输出信号sentdata 。VHDL 程序核心部分如下:
IF(clklx 'EVENT AND clkl='l')THEN
regl<=d;reg2<=reg1;reg3 <=reg2; —6 位移位寄存器
reg4<=reg3;reg5<=reg4;reg6<=reg5;
IF(clr='l')THEN
cd<='0';
ELSIF((regl='l' AND reg2='l' AND reg3='1')AND(reg4='0' AND reg5 ='0' AND reg6='0'))THEN
cd<='0';
ELSIF((regl='0' AND reg2='0' AND reg3='0')AND(reg4='l' AND reg5 ='l' AND reg6='l'))THEN
cd<='1'; —判别数据类型
END IF;
END IF;
IF(clklx'EVENT AND clklx='l')THEN —计0,1个数
IF(clr='l' OR ctl="111" OR ct0 ="111")THEN
ctl<="000"; ct0<="000";
ELSIF(d='l')THEN
ct0<="000";
ctl<=ctl+"001"; —出现l,ctl加1,ct0清零
ELSIF(d='0')THEN
ctl<="000";
ct0<=ct0+"001"; —出现0,ct1清零,ct0加1
END IF;
END IF;
IF(clr='l' OR count17="10000")THEN
sc<='0';
ELSIF (ct0="010")THEN
sc<='1' ;
END IF;
IF(clr='1' OR count17="10000") THEN
sd<='0';
ELSIF(ctl="010")THEN
sd<='1'; —sc,sd分别为ct0,ct1计数到3个的0或1产生的信号END IF;
IF(clr='1' OR count17="10000") THEN
den<='0';
ELSIF(sc='1' AND sd='l')THEN
—sc=1, sd="1"说明出现了111000或000111的数据
den<='1'; 一信号den为高表示解码周期开始
ELSE
den<='0';
END IF;
IF(countl7>="00000" AND count17<="01111") THEN
sentd<='l' AND den; —生成sentd 信号,后面再将其输出到sentdata
ELSE
sentd<='0';
END IF ;
如果输出为高则说明数据出错,为低则说明没有错误。具体VHDL 语句如下:
IF(clr='1')THEN
data<='0';
END IF ;
data<=NOT(clk2x XOR d); —解码
IF(countl7="10000")THEN
jo<=data; —jo为编码的奇校验
ELSE
jo<='0';
END IF;
IF(clk2x'EVENT AND clk2x='1')THEN
IF(sentd='1')THEN
jojy<=jojy XOR d; —jojy为解码输出数据的奇校验
ELSE
jojy<='0';
END IF ;
END IF ;
IF(clr='l')THEN
f<='0';
ELSIF(count17="10000")THEN
f<=jo XOR jojy; —判断数据是否有错误
ELSE
f<='0';
END IF;
楼主 2009/6/14 17:31:37
楼主 2009/6/14 17:31:58
楼主 2009/6/14 17:44:23
我光电子的,就是学的不好