level 2
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; ENTITY rs_encoder IS GENERIC(C_SPEC:NATURAL:=0); PORT(CLK:IN STD_LOGIC; DATA_IN:IN STD_LOGIC_VECTOR(7 DOWNTO 0); ENABLE:IN STD_LOGIC; RESET:IN STD_LOGIC; START:IN STD_LOGIC; INFO:OUT STD_LOGIC; DATA_OUT:OUT STD_LOGIC_VECTOR(7 DOWNTO 0); FD:OUT STD_LOGIC; CLK_OUT:OUT STD_LOGIC; SYN_BLOCK:OUT STD_LOGIC); END rs_encoder; ARCHITECTURE BEHAVIORAL OF rs_encoder IS CONSTANT K:NATURAL:=188; CONSTANT N:NATURAL:=204; CONSTANT R:NATURAL:=16; CONSTANT OPTIMIZATION:NATURAL:=1; CONSTANT POLYNOMIAL:NATURAL:=0; CONSTANT SYMBOL_WIDTH:NATURAL:=8; TYPE ARRAY_INTEGER_254 IS ARRAY(0 TO 254)OF NATURAL RANGE 0 TO 255; TYPE ARRAY_INTEGER_255 IS ARRAY(0 TO 255)OF NATURAL RANGE 0 TO 255; FUNCTION FUN2(B:STD_LOGIC)RETURN STD_LOGIC IS--该函数主要是用来防止输入端产生‘X’,所以先 BEGIN --调用该函数进行判断输入端是否满足要求 CASE B IS WHEN '0'|'1'=>RETURN B; WHEN 'H'=>RETURN '1'; WHEN 'L'=>RETURN '0'; WHEN OTHERS=>RETURN 'X'; END CASE; END; FUNCTION FUN3(C:STD_LOGIC_VECTOR)RETURN BOOLEAN IS BEGIN FOR INT IN C'RANGE LOOP IF(FUN2(C(INT))='X')THEN RETURN TRUE; --若c(int)中只要有一位的值不是‘0’,‘1’,‘H’‘L’ END IF; --则返回true,否则c(int)中的值全部落在0,1,H,L范围内 END LOOP; --则此时返回false RETURN FALSE; END; FUNCTION FUN7(P1:IN NATURAL)RETURN STD_LOGIC_VECTOR IS --fun7 实现将输入正整数转化为8位矢量 VARIABLE TEMP1:NATURAL RANGE 0 TO 255; VARIABLE TEMP2:STD_LOGIC_VECTOR(7 DOWNTO 0); CONSTANT TEMP3:STD_LOGIC_VECTOR(0 TO 1):=(0=>'0',1=>'1'); --"10" BEGIN TEMP1:=P1; TEMP2:=(OTHERS=>'0'); FOR I IN TEMP2'REVERSE_RANGE LOOP TEMP2(I):=TEMP3(TEMP1 REM 2); TEMP1:=TEMP1/2; EXIT WHEN TEMP1=0; END LOOP; RETURN TEMP2; END; FUNCTION FUN9(P1,P2,P3:NATURAL)RETURN NATURAL IS VARIABLE TEMP1:NATURAL; VARIABLE TEMP2:NATURAL; VARIABLE TEMP3:NATURAL; VARIABLE TEMP4:NATURAL; VARIABLE TEMP5:NATURAL; VARIABLE TEMP6:NATURAL; VARIABLE TEMP7:NATURAL; BEGIN TEMP1:=P1; TEMP2:=P2; TEMP3:=0; TEMP4:=0; TEMP5:=1; TEMP6:=0; TEMP7:=0; FOR I IN 0 TO(P3-1)LOOP TEMP3:=TEMP1 REM 2; TEMP4:=TEMP2 REM 2; TEMP6:=TEMP3+TEMP4; IF(TEMP6=1)THEN TEMP7:=TEMP7+TEMP5; END IF; TEMP1:=TEMP1/2; TEMP2:=TEMP2/2; TEMP5:=TEMP5*2; END LOOP; RETURN TEMP7; END; FUNCTION FUN10(P:NATURAL)RETURN ARRAY_INTEGER_254 IS VARIABLE TEMP1:ARRAY_INTEGER_254; VARIABLE TEMP2:NATURAL; VARIABLE TEMP3:NATURAL; VARIABLE TEMP4:NATURAL; BEGIN TEMP2:=285; TEMP3:=1; TEMP4:=0; FOR I IN 0 TO 7 LOOP TEMP1(I):=TEMP3; TEMP3:=TEMP3*2; END LOOP; TEMP1(8):=TEMP2 REM 2**8; TEMP3:=TEMP3/2; FOR J IN(8+1)TO (2**8-2) LOOP IF(TEMP1(J-1)>=TEMP3)THEN TEMP4:=2*(TEMP1(J-1)-TEMP3); TEMP1(J):=FUN9(TEMP2,TEMP4,8); ELSE TEMP1(J):=TEMP1(J-1)*2; END IF; END LOOP; RETURN TEMP1; END; CONSTANT TEMP_ARRAY_254:ARRAY_INTEGER_254:=FUN10(0); --调用FUN10 FUNCTION FUN11(P:NATURAL)RETURN ARRAY_INTEGER_255 IS VARIABLE TEMP1:ARRAY_INTEGER_255; BEGIN FOR I IN 0 TO 255 LOOP TEMP1(I):=0; END LOOP; FOR J IN 0 TO 254 LOOP TEMP1(TEMP_ARRAY_254(J)):=J; END LOOP; RETURN TEMP1; END; CONSTANT TEMP_ARRAY_255:ARRAY_INTEGER_255:=FUN11(0);--调用FUN11 TYPE ARRAY_COEFFICIENT_16X1 IS ARRAY(0 TO 15)OF NATURAL; SUBTYPE STD_LOGIC_SYMBOL_WIDTH IS STD_LOGIC_VECTOR(7 DOWNTO 0); TYPE CHECK_SYMBOL_TYPE_16X8 IS ARRAY(0 TO 15)OF STD_LOGIC_SYMBOL_WIDTH; FUNCTION FUN12(P:NATURAL)RETURN NATURAL IS VARIABLE TEMP:NATURAL RANGE 0 TO 254; BEGIN IF(P>=0 AND P<255)THEN TEMP:=(P REM 2**8); ELSIF(P>255)THEN TEMP:=(P REM 2**8)+1; ELSIF(P=255 OR P=510)THEN TEMP:=0; END IF; RETURN TEMP; END; FUNCTION FUN14(P1:IN NATURAL;P2:IN NATURAL)RETURN STD_LOGIC_SYMBOL_WIDTH IS --实现GF乘法功能 VARIABLE TEMP1:NATURAL RANGE 0 TO 511; VARIABLE TEMP2:STD_LOGIC_SYMBOL_WIDTH; VARIABLE RESULT_MOD_255:NATURAL RANGE 0 TO 254; BEGIN TEMP1:=0; IF(P1=0 OR P2=0)THEN RETURN(OTHERS=>'0'); ELSE TEMP1:=(TEMP_ARRAY_255(P1)+TEMP_ARRAY_255(P2));--temp1的值不超过510 RESULT_MOD_255:=FUN12(TEMP1); TEMP2:=FUN7(TEMP_ARRAY_254(RESULT_MOD_255)); RETURN TEMP2; END IF; END; CONSTANT GF_MULT_COEFFICIENT_16X1:ARRAY_COEFFICIENT_16X1:=(0=>59,1=>36,2=>50,3=>98,4=>229,5=>41,6=>65,7=>163,8=>8,9=>30,10=>209,11=>68,12=>189,13=>104,14=>13,15=>59);-- ARRAY_COEFFICIENT_16X1IS ARRAY(0 TO 15)OF NATURAL,存放16个分支的乘法系数值 SIGNAL SIGNAL1:STD_LOGIC_SYMBOL_WIDTH; SIGNAL SIGNAL3:STD_LOGIC_SYMBOL_WIDTH; SIGNAL SIGNAL_BIT:STD_LOGIC; SIGNAL SIGNAL_VECTOR1:STD_LOGIC_VECTOR(SYMBOL_WIDTH-1 DOWNTO 0); SIGNAL SIGNAL_VECTOR2:STD_LOGIC_VECTOR(SYMBOL_WIDTH-1 DOWNTO 0); SIGNAL SIGNAL_BIT1:STD_LOGIC; SIGNAL SIGNAL_BIT2:STD_LOGIC; SIGNAL SIGNAL_SYN_BLOCK:STD_LOGIC; SIGNAL FD_REGISTER:STD_LOGIC; BEGIN DATA_OUT<=SIGNAL_VECTOR2; INFO<=SIGNAL_BIT2; IN_SEL:PROCESS(DATA_IN) --该进程判断输入数据是否为有效的,即是否为‘X’,若是则SIGNAL3为‘XXXXXXXX’ BEGIN IF FUN3(DATA_IN)THEN SIGNAL3<=(OTHERS=>'X'); ELSE SIGNAL3<=DATA_IN; --过程1中的SIGNAL3用来与最右边的寄存器进行异或,变成TEMP1,再与个分支系数相乘 END IF; END PROCESS; MAIN:PROCESS(CLK,RESET,ENABLE,START) VARIABLE TEMP1:NATURAL range 0 to 206; VARIABLE TEMP_WIDTH_8:STD_LOGIC_SYMBOL_WIDTH; --用来计算是否超过188字节,是一个计数变量 VARIABLE TEMP_CHECK_16X8:CHECK_SYMBOL_TYPE_16X8;--16 X 8(bits),16个8bits移位寄存器 VARIABLE OUTPUT_INFORMATION_CHECK:STD_LOGIC_SYMBOL_WIDTH;--std_logic_vector(7 downto 0) VARIABLE TEMP_INFO:STD_LOGIC; VARIABLE BLOCK_SYN_OUT:STD_LOGIC; VARIABLE COUNT:STD_LOGIC; VARIABLE FD_TEMP:STD_LOGIC; PROCEDURE PROCEDURE1 IS --该过程实现输入data_in与各个分支的系数进行GF乘法,然后移位寄存 VARIABLE TEMP1:STD_LOGIC_SYMBOL_WIDTH; VARIABLE TEMP2_NATURAL:NATURAL RANGE 0 TO 255; VARIABLE TEMP2:STD_LOGIC_SYMBOL_WIDTH; BEGIN TEMP1:=SIGNAL3 XOR TEMP_CHECK_16X8(15); TEMP2_NATURAL:=CONV_INTEGER(TEMP1);--利用fun6先将temp1转化为整数,因为fun14的两个参数都为integer FOR I IN 15 DOWNTO 1 LOOP TEMP2:=FUN14(GF_MULT_COEFFICIENT_16X1(I),TEMP2_NATURAL);--temp2是乘以系数完的结果,FUN14可能是乘法系数的计算公式,CORRELATE_CHECK_16X1的初始值 TEMP_CHECK_16X8(I):=TEMP_CHECK_16X8(I-1)XOR TEMP2; END LOOP; TEMP2:=FUN14(GF_MULT_COEFFICIENT_16X1(0),TEMP2_NATURAL); TEMP_CHECK_16X8(0):=TEMP2; --temp2是乘系数后的结果,该语句就是最左边的分支,即将temp2赋予最左边的寄存器temp_check_16X8(0) END; PROCEDURE PROCEDURE2 IS BEGIN TEMP_WIDTH_8:=(OTHERS=>'0'); FOR I IN 0 TO 15 LOOP TEMP_CHECK_16X8(I):=(OTHERS=>'0'); END LOOP; OUTPUT_INFORMATION_CHECK:=(OTHERS=>'0'); END; PROCEDURE PROCEDURE4 IS BEGIN TEMP_WIDTH_8:=(OTHERS=>'X'); FOR I IN 0 TO 15 LOOP TEMP_CHECK_16X8(I):=(OTHERS=>'X'); END LOOP; OUTPUT_INFORMATION_CHECK:=(OTHERS=>'X'); END; PROCEDURE PROCEDURE3 IS --该过程实现对输入数据的计数,若达到188字节,则输出校验字节 BEGIN TEMP1:=CONV_INTEGER(TEMP_WIDTH_8)+1; --FUN6实现将位矢量转换为整数,将计数加1完的计数变量TEMP1 TEMP_WIDTH_8:=FUN7(TEMP1);--又作为FUN7下次被调用的参量进行传递,然后再次赋给TEMP_WIDTH_8 END; BEGIN SIGNAL1<=OUTPUT_INFORMATION_CHECK; SIGNAL_BIT<=TEMP_INFO; IF RESET='1'THEN PROCEDURE2; TEMP_INFO:='0'; SIGNAL_SYN_BLOCK<='0'; COUNT:='0'; FD_REGISTER<='0'; ELSIF(CLK'EVENT AND CLK='1')THEN IF ENABLE='1'THEN --ENABLE='1' IF START='0'THEN --ENABLE='1' AND BYPASS='0' AND START='0' BLOCK_SYN_OUT:='0'; FD_TEMP:='0'; IF(FUN3(TEMP_WIDTH_8))THEN --TEMP_WIDTH_8 中有‘X’时,则FUN3为TURE;否则为FALSE PROCEDURE4; TEMP_INFO:='X'; ELSIF CONV_INTEGER(TEMP_WIDTH_8)<K THEN --输入字节数目小于188字节 PROCEDURE1; OUTPUT_INFORMATION_CHECK:=SIGNAL3; TEMP_INFO:='1'; PROCEDURE3; --调用该过程实现计数变量加1,对输入有效字节加1 ELSIF CONV_INTEGER(TEMP_WIDTH_8)<N THEN --计数变量超过188字节,但是小于204字节 OUTPUT_INFORMATION_CHECK:=TEMP_CHECK_16X8(N-1-CONV_INTEGER(TEMP_WIDTH_8)); --输出校验字节 TEMP_INFO:='0'; --INFO变成0 PROCEDURE3; ELSE --计数变量超过204字节 PROCEDURE2; TEMP_INFO:='0'; --此时INFO还是0 END IF; ELSIF START='1'THEN --ENABLE='1' AND BYPASS='0' AND START='1' PROCEDURE2; --调用过程2将TEMP_WIDTH_8清零,同时各个移位寄存器都清零,并且OUTPUT_INFORMATION_CHECK也清零 PROCEDURE1; OUTPUT_INFORMATION_CHECK:=SIGNAL3; BLOCK_SYN_OUT:='1'; TEMP_INFO:='1'; PROCEDURE3; IF(COUNT='0')THEN FD_TEMP:='1'; COUNT:='1'; ELSE FD_TEMP:='0'; END IF; ELSE --ENABLE='1' AND BYPASS='0' AND START='X' PROCEDURE4; TEMP_INFO:='X'; END IF; FD_REGISTER<=FD_TEMP; SIGNAL_SYN_BLOCK<=BLOCK_SYN_OUT; END IF; END IF; END PROCESS; OUTPUT_REGISTERS: PROCESS(CLK,RESET) BEGIN IF RESET='1'THEN SIGNAL_VECTOR1<=(OTHERS=>'0'); SIGNAL_BIT1<='0'; ELSIF(CLK'EVENT AND CLK='1')THEN SIGNAL_VECTOR1<=SIGNAL1; --SIGNAL1是存放输出数据(可能是输入原始数据,可能是校验数据)的临时信号 SIGNAL_BIT1<=SIGNAL_BIT; --SIGNAL_BIT是存放INFO的临时信号 END IF; END PROCESS; OUT_SEL: PROCESS(SIGNAL_VECTOR1,SIGNAL_BIT1) BEGIN SIGNAL_VECTOR2<=SIGNAL_VECTOR1; SIGNAL_BIT2<=SIGNAL_BIT1; END PROCESS; OUT_SYN_BLOCK: PROCESS(CLK,SIGNAL_SYN_BLOCK) BEGIN IF(CLK'EVENT AND CLK='1')THEN SYN_BLOCK<=SIGNAL_SYN_BLOCK; FD<=FD_REGISTER; END IF; END PROCESS; OUT_CLK: PROCESS(CLK) BEGIN CLK_OUT<=NOT CLK; END PROCESS; END BEHAVIORAL;
2013年05月17日 07点05分