📄 rs_encoder.vhd
字号:
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_16X1 IS 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -