📄 manchesterdecoder.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 + -