⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rs_encoder.vhd

📁 一个很不错RS编码
💻 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 + -