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

📄 decoding.vhd

📁 FPGA与ARM EPI通信,控制16路步进电机和12路DC马达 VHDL编写的
💻 VHD
字号:
----------------------------------------------------------------------------------
-- Company: 		Han'slaser
-- Engineer: 		Zhouj110624
-- Create Date:    08:53:15 09/22/2012 
-- Design Name: 	decoding
-- Module Name:    decoding - Behavioral 
-- Project Name: 	decoding
-- Target Devices: 
--功能说明:对输入的曼切斯特码进行解码,并将解码后的串行数据转换为并行数据	
--其中同步头由4个高电平的编码时钟组成(32个解码时钟)
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use work.PCK_CRC8_D1.ALL;

entity decoding is
    Port ( 	
				CLK								: in  STD_LOGIC;				DECODE_EN						: in  STD_LOGIC;				MANCHESTER_WITHOUT_HEADER	: in  STD_LOGIC;	--输入的曼切斯特码
				DECODE_ERROR					: out	STD_LOGIC;				DECODE_OUT						: out std_logic_vector( 20 downto 0)	--解码后的串行编码				);
end decoding;
 
architecture Behavioral of decoding is
----------------------------------------------------------------------------------
	signal crc8_data_reg 		:	std_logic_vector( 7 downto 0 ) := (others => '0');
	signal crc8_data				:	std_logic_vector( 7 downto 0 ) := (others => '0');
	signal manchester_data		:  std_logic_vector( 28 downto 0) := (others => '0');
	signal decode_reg1			:	std_logic := '0';
	signal decode_reg2			:	std_logic := '0';
	signal decode_coder			:	std_logic := '0';--输出串行码元内部信号
	signal coder_cnt				:	std_logic_vector( 2 downto 0 ) := (others => '0');--时钟计数
--	signal coder_high_cnt		:	std_logic_vector( 2 downto 0 ) := (others => '0');--时钟计数,用于判断码的‘0’‘1’状态
	signal manchester_cnt		:	std_logic_vector( 4 downto 0 ) := (others => '0');--串转并
	signal decoder_end			:	std_logic := '0';
	signal decoder_end_reg		:	std_logic := '0';
	signal decod_end_reg_cnt1	:	std_logic_vector(10 downto 0) := (others => '0');

begin
----------------------------------------------------------------------------------
--组合运算 
----------------------------------------------------------------------------------
--	DECODE_OUT	<= manchester_data(28 downto 8);
--	Pod_crc 		<= crc8_data;
----------------------------------------------------------------------------------
--曼切斯特码解码进程,通过计数器实现:整个曼切斯特码为8个解码时钟周期,而其高电平仅为4个时钟周期,
--码元‘1’:高电平在前,码元‘0’:低电平在前,所以在整个码前6个周期中,对码元高电平计数,若记得的数值
--小于3 则此码为:‘0’,若记得的数值大于等于3,则此码为:‘1’。
----------------------------------------------------------------------------------	
----------------------------------------------------------------------------------		
--对解码时钟计数,最大计数值为7					
----------------------------------------------------------------------------------
	Pr_cnt_CLK	:	
	process(CLK)
	begin
		if rising_edge(CLK) then
			if DECODE_EN = '0' then
				coder_cnt <= (others => '0');								
			else
				if coder_cnt < "111" then--7
					coder_cnt <= coder_cnt + 1; 
				else
					coder_cnt <= (others => '0');
				end if;
			end if;
		end if;
	end process;
----------------------------------------------------------------------------------
--判断电平
----------------------------------------------------------------------------------
--	Pr_cnt_hgih	:	
--	process(CLK)
--	begin
--		if rising_edge(CLK) then
--			if DECODE_EN = '0' then	
--				coder_high_cnt <= (others => '0');	
--				DECODE_ERROR <= '0';
--			else
--				if coder_cnt < "101" then--6
--					DECODE_ERROR <= '0';
--					if MANCHESTER_WITHOUT_HEADER = '1' then
--						coder_high_cnt <= coder_high_cnt + 1;
--					else
--						coder_high_cnt <= coder_high_cnt;
--					end if;
--				elsif coder_cnt = "100" then--5
--					--小于3,即前4个时钟为低电平
--					if coder_high_cnt < "010" then--4
--						DECODE_ERROR <= '0';
--						decode_coder <= '0';
--					--大于等于,即前4个时钟为高电平
--					elsif coder_high_cnt < "100" then--5
--						DECODE_ERROR <= '0';
--						decode_coder <= '1';
--					else
--						DECODE_ERROR <= '1';
--					end if;
--				else
--					DECODE_ERROR <= '0';
--					coder_high_cnt <= (others => '0');
--				end if;
--			end if;
--		end if;
--	end process;
--	decode_reg1 <= '0' when coder_cnt = "010" and MANCHESTER_WITHOUT_HEADER = '0' else
--						'1' when coder_cnt = "010" and MANCHESTER_WITHOUT_HEADER = '1' else
--						decode_reg1;
--	decode_reg2 <= '0' when coder_cnt = "101" and MANCHESTER_WITHOUT_HEADER = '0' else
--						'1' when coder_cnt = "101" and MANCHESTER_WITHOUT_HEADER = '1' else
--						decode_reg2;					
	Pr_just	:	process(CLK)
						begin
							if rising_edge(CLK) then
								if DECODE_EN = '0' then
									decode_reg1 <= '0';
									decode_reg2 <= '0';
								else
									if (coder_cnt > "001") and (coder_cnt < "011") then--1-3
										if MANCHESTER_WITHOUT_HEADER = '0' then
											decode_reg1 <= '0';
										else
											decode_reg1 <= '1';
										end if;
									elsif (coder_cnt > "100") and (coder_cnt < "110") then--4-6
										if MANCHESTER_WITHOUT_HEADER = '0' then
											decode_reg2 <= '0';
										else
											decode_reg2 <= '1';
										end if;
									else
										null;
									end if;
								end if;
							end if;
						end process;
	Pr_decode	:	process(CLK)
						begin
							if rising_edge(CLK) then
								if DECODE_EN = '0' then
									DECODE_ERROR <= '0';
									decode_coder <= '0';
								else
									if coder_cnt = "110" then
										if decode_reg1 = '0' and decode_reg2 = '1' then
											decode_coder <= '0';
											DECODE_ERROR <= '0';
										elsif decode_reg1 = '1' and decode_reg2 = '0' then
											decode_coder <= '1';
											DECODE_ERROR <= '0';
										else
											DECODE_ERROR <= '1';
										end if;
									else
										DECODE_ERROR <= '0';
									end if;
								end if;
							end if;
						end process;
										
											
----------------------------------------------------------------------------------	
--串转并处理和CRC8校验
----------------------------------------------------------------------------------				
	Pr_tran	:	
	process(CLK)
	begin
		if rising_edge(CLK) then
			if DECODE_EN = '0' then
				manchester_cnt <= (others => '0');
				crc8_data_reg <= (others => '0');
				decoder_end <= '0';
			else
				if coder_cnt < "111" then--7
					manchester_cnt <= manchester_cnt;
				else
					manchester_cnt <= manchester_cnt + 1;
					manchester_data ( 28 - conv_integer( manchester_cnt ) ) <= decode_coder;--以串行码开头作为高位
					if manchester_cnt < "10101" then--21
						decoder_end <= '0';
						crc8_data_reg <= nextCRC8_D1( decode_coder, crc8_data_reg);
					elsif manchester_cnt < "11100" then--28
						decoder_end <= '0';
					else
						decoder_end <= '1';
--						DECODE_OUT	<= manchester_data(28 downto 8);
						crc8_data <= crc8_data_reg;
					end if;
				end if;
			end if;
		end if;
	end process;
----------------------------------------------------------------------------------
--输出标志位
----------------------------------------------------------------------------------
	Pr_d	:		process(CLK)	begin		if rising_edge(CLK) then			decod_end_reg_cnt1(0) 				<= decoder_end;			decod_end_reg_cnt1(10 downto 1) 	<= decod_end_reg_cnt1(9 downto 0);			decoder_end_reg 						<= decod_end_reg_cnt1(10);		end if;	end process;
	
	Pr_mark	:	
	process(CLK)
	begin
		if rising_edge(CLK) then
			if ( crc8_data = manchester_data(7 downto 0) )and ( decoder_end_reg = '1' ) then
				DECODE_OUT	<= manchester_data(28 downto 8);
			else
				null;
			end if;
		end if;
	end process;
end Behavioral; 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -