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

📄 manchesterdecoder.vhd

📁 曼彻斯特编码
💻 VHD
字号:
--====================================================
--ManchesterII Decoder 
--====================================================
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;

entity ManchesterDecoder is
port(
	reset       : in    std_logic;
	--clkx100     : in    std_logic;
	clkx16      : in    std_logic;
	
	din         : in    std_logic;
	
	cmnd        : out   std_logic;
	rxrdyn      : out   std_logic;
	dout        : out   std_logic_vector(15 downto 0)
	);
end ManchesterDecoder;

architecture behav of ManchesterDecoder is

--Digital PLL
component DigPll is
	port(
		reset     : in  std_logic;
		clkx16    : in  std_logic;
	--	clkx100   : in  std_logic;
		din       : in  std_logic;
		clkx2     : out std_logic);
end component DigPll;

--Clock Generator
component ClockGenerator is
	port(
		reset            : in  std_logic;
		clkx16           : in  std_logic;
		decode_start     : in  std_logic;
		transmit_start     : in  std_logic;
		pll_clkx2        : in  std_logic;
		det_clkx2        : out std_logic;
		pll_clkx1        : out std_logic;
		tra_clkx1        : out std_logic);
end component ClockGenerator;

signal pll_start         : std_logic;
signal pll_clkx2         : std_logic;
signal det_clkx2         : std_logic;
signal dec_clkx1         : std_logic;
signal tra_clkx1         : std_logic;

--data transmit register
signal transmit_start      : std_logic;
--signal decode_tail       : std_logic;
--decode suceessully signal 
signal decode_suc        : std_logic;
--data output control signal
signal data_out_en       : std_logic;
--data output counter
signal data_out_cnt      : std_logic_vector(4 downto 0);
--data output register
signal dout_r            : std_logic_vector(15 downto 0);

--synchornize bits valid signal 
signal sync_valid        : std_logic;
--signal sync_det_tail     : std_logic;
--detect '0' counter
signal sync_det0_cnt     : std_logic_vector(2 downto 0);
--detect '1' counter
signal sync_det1_cnt     : std_logic_vector(2 downto 0);

--data decoded with decode clock
signal data_with_ipl     : std_logic;
--data filtered with 2M clock
signal data_without_ipl  : std_logic;

--data shift counter
signal data_shift_cnt    : std_logic_vector(4 downto 0);
--data shift temp
signal data_shift_temp   : std_logic_vector(15 downto 0);

--parity registers
signal parity_r          : std_logic;   
signal parity_decode     : std_logic;          
signal parity_cnt        : std_logic_vector(1 downto 0);

--
signal cmnd_s            : std_logic;
signal cmnd_r            : std_logic;

--state machine type
type state_type is(idle,sync_detect,decode,parity,output);
signal decode_state      : state_type;

begin
	U1 : DigPll port map(
						reset     => pll_start,
						clkx16    => clkx16,
					--	clkx100   => clkx100,
						din       => din,
						clkx2     => pll_clkx2 );
	
	U2 : ClockGenerator port map(
								reset         => reset,
								clkx16        => clkx16,
								decode_start  => pll_start,
								transmit_start=> transmit_start,
								pll_clkx2     => pll_clkx2,
								det_clkx2     => det_clkx2,
								pll_clkx1     => dec_clkx1,
								tra_clkx1     => tra_clkx1);

--synchornize bits detect process 								
	sync_detect_process : process(det_clkx2)
	begin
		if det_clkx2'event and det_clkx2 = '1' then
			if sync_valid = '0' then
				if din = '1' then
					sync_det1_cnt <= sync_det1_cnt + "001";
					sync_det0_cnt <= "000";
				elsif din = '0' then
					sync_det0_cnt <= sync_det0_cnt + "001";
					sync_det1_cnt <= "000";
				end if;
				if sync_det0_cnt = "011" or sync_det1_cnt = "011" then
					sync_valid <= '1';
					pll_start  <= '1';
				end if;
			elsif sync_valid = '1' then
				if din = '1' then
					sync_det1_cnt <= sync_det1_cnt + "001";
					sync_det0_cnt <= "000";
				elsif din = '0' then
					sync_det0_cnt <= sync_det0_cnt + "001";
					sync_det1_cnt <= "000";
				end if;
				
				if sync_det0_cnt = "010" or sync_det1_cnt = "010" then
					pll_start     <= '0';
				end if; 
				if sync_det0_cnt = "011" or sync_det1_cnt = "011" then
					sync_valid    <= '0';
				end if;
			end if;
		end if;
	end process sync_detect_process;

--data decode 	
	data_with_ipl <= (din xor dec_clkx1) when decode_state = decode  else
					 '0'; 

--data filter	
	filter_process : process(reset,pll_clkx2)
	begin
		if reset = '1' then
			data_without_ipl <= '0';
		elsif pll_clkx2'event and pll_clkx2 = '0' then
			data_without_ipl <= data_with_ipl;
		end if;
	end process filter_process;

--data shift process	
	decode_process : process(reset,tra_clkx1,data_without_ipl)
	begin
		if reset = '1' then
			data_shift_cnt  <= "00000";
			data_shift_temp <= X"0000";
			parity_r        <= '1';
		elsif tra_clkx1'event and tra_clkx1 = '1' then
			if decode_state = sync_detect  then
				data_shift_cnt  <= "00000";
				data_shift_temp <= X"0000";
				parity_r        <= '1';
			--data begin to shift
			elsif decode_state = decode and data_shift_cnt <= "10001" then
				data_shift_cnt  <= data_shift_cnt + "00001";
				if data_shift_cnt <= "01111" then
					data_shift_temp <= data_shift_temp(14 downto 0) & data_with_ipl;
				--odd parity check
					parity_r        <= parity_r xor data_with_ipl;
				end if;
			end if;
		end if;
	end process decode_process;

--Data output process	
	output_process : process(det_clkx2,data_shift_temp,decode_suc)
	begin
		if det_clkx2'event and det_clkx2 = '1' then
			if decode_suc = '1' then
				data_out_en      <= '1';
			elsif data_out_en = '1' then
				if data_out_cnt <= "11101" then
					if data_out_cnt = "00000" then
						dout_r   <= data_shift_temp;
						cmnd_r   <= cmnd_s;
					end if;	
					rxrdyn       <= '0';
					data_out_cnt <= data_out_cnt + "00001";
				else
					data_out_en  <= '0';
					data_out_cnt <= "00000";
					rxrdyn  	 <= '1';
					dout_r		 <= X"0000";
					cmnd_r   	 <= '0';
				end if;
			else
				data_out_cnt <= "00000";
				dout_r 		 <= X"0000";
				cmnd_r    	 <= '0';
				rxrdyn  	 <= '1';
			end if;
		end if;
	end process output_process;

	dout <= dout_r;
	cmnd <= cmnd_r;

--state machine 	
	control_machine : process(det_clkx2)
	begin
		if det_clkx2'event and det_clkx2 = '1' then	
			case decode_state is
				when idle         =>	decode_suc	<= '0';
										if sync_valid = '1' then
											decode_state <= sync_detect;
										end if;
				when sync_detect  =>	if sync_det0_cnt = "011" or sync_det1_cnt = "011" then
											if sync_det0_cnt = "011" then
												cmnd_s <= '1';
											elsif sync_det1_cnt = "011" then
												cmnd_s <= '0';
											else
												cmnd_s <= '0';
											end if;
											transmit_start <= '1';
											decode_state <= decode;
										end if;
				when decode       =>	transmit_start <= '0';
										if data_shift_cnt = "10001" then
											decode_state <= parity;
											parity_decode <= data_without_ipl;
										end if;
				when parity		  =>	parity_cnt <= parity_cnt + "01";
										if parity_cnt = "01" then
											if parity_r = parity_decode then
												decode_suc	<= '1';
											end if;
										elsif parity_cnt = "10" then
											parity_cnt <= "00";
											decode_state <= output;
										end if;
				when output 	  => 	decode_state <= idle;
				when others       =>	decode_state <= idle;
			end case;	
		end if;
	end process control_machine;
	
end behav;

⌨️ 快捷键说明

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