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

📄 c_16450_vhd.htm

📁 altra下载线资料。max7000系列
💻 HTM
📖 第 1 页 / 共 4 页
字号:
					OVERRUN_ERROR <= RHR_FULL;
				end if;
			end if;
		end if;
	end process;

	RHR_WRITE_ENABLE <= NEXT_STATE and RECEIVING_STOP_BIT;

	process(CLK, RESET)
	begin
		if (RESET = '0') then
			RECEIVER_HOLDING_REGISTER <= "00000000";
		elsif (rising_edge(CLK)) then
			if ((CE = '1') and (RHR_WRITE_ENABLE = '1')) then
				RECEIVER_HOLDING_REGISTER <= SHIFT_REGISTER;
			end if;
		end if;
	end process;

	RHR_OUT <= RECEIVER_HOLDING_REGISTER;

	process(CLK, RESET, RHR_FULL_RESET)
	begin
		if (RESET = '0' or RHR_FULL_RESET = '1') then
			RHR_FULL <= '0';
		elsif (rising_edge(CLK)) then
			if ((CE = '1') and (RHR_WRITE_ENABLE = '1')) then
				RHR_FULL <= '1';
			end if;
		end if;
	end process;

	RECEIVER_INTERRUPT <= RHR_FULL;

	process(RD, RESET, RHR_FULL)
	begin
		if ((RHR_FULL = '0') or (RESET = '0')) then
			RHR_FULL_RESET <= '0';
		elsif (rising_edge(RD)) then
			RHR_FULL_RESET <= RHR_EN;
		end if;
	end process;

	CALCULATED_PARITY <= (not PARITY_EVEN_nODD) xor (SHIFT_REGISTER(7) xor SHIFT_REGISTER(6) xor
					SHIFT_REGISTER(5) xor SHIFT_REGISTER(4) xor SHIFT_REGISTER(3) xor
					SHIFT_REGISTER(2) xor SHIFT_REGISTER(1) xor SHIFT_REGISTER(0))
					when STICK_PARITY = '0' else not PARITY_EVEN_nODD;

	PARITY_OK <= not (PARITY_REGISTER xor CALCULATED_PARITY) or not PARITY_ENABLE;

	process(RD, RESET, PARITY_ERROR)
	begin
		if ((PARITY_ERROR = '0') or (RESET = '0')) then
			RESET_PARITY_ERROR <= '0';
		elsif (rising_edge(RD)) then
			RESET_PARITY_ERROR <= LSR_EN;
		end if;
	end process;

	process(CLK, RESET, RESET_PARITY_ERROR)
	begin
		if ((RESET = '0') or (RESET_PARITY_ERROR = '1')) then
			PARITY_ERROR <= '0';
		elsif (rising_edge(CLK)) then
			if (CE = '1') then
				if (RHR_WRITE_ENABLE = '1') then
					PARITY_ERROR <= not PARITY_OK;
				end if;
			end if;
		end if;
	end process;

	RELOAD_COUNTER <= RECEIVER_IDLE;

	process(CLK, RESET)
	begin
		if (RESET = '0') then
			CLOCK_DIVIDER <= "0000";
		elsif (rising_edge(CLK)) then
			if (CE = '1') then
				if (RELOAD_COUNTER = '1') then
					CLOCK_DIVIDER <= "0000";
				else
					CLOCK_DIVIDER <= CLOCK_DIVIDER + 1;
				end if;
			end if;
		end if;
	end process;

	NEXT_STATE <= CE when (CLOCK_DIVIDER = "1111") or (CLOCK_DIVIDER = "1110" and RECEIVING_STOP_BIT = '1') or (RECEIVER_IDLE_BREAK = '1') else '0';
	CATCH_ENABLE <= CE when (CLOCK_DIVIDER = "0111") else '0';

	process(CLK, RESET)
	begin
		if (RESET = '0') then
			RECEIVER_STATE <= IDLE_STATE;
		elsif (rising_edge(CLK)) then
			if (NEXT_STATE = '1') then
				case RECEIVER_STATE is
					when IDLE_STATE =>
								if (SERIAL_IN = '0') then
									RECEIVER_STATE <= START_STATE;
								end if;
					when START_STATE =>
								if (START_CONFIRMED = '1') then
									RECEIVER_STATE <= BIT0_STATE;
								else
									RECEIVER_STATE <= IDLE_STATE;
								end if;
					when BIT0_STATE =>
								RECEIVER_STATE <= BIT1_STATE;
					when BIT1_STATE =>
								RECEIVER_STATE <= BIT2_STATE;
					when BIT2_STATE =>
								RECEIVER_STATE <= BIT3_STATE;
					when BIT3_STATE =>
								RECEIVER_STATE <= BIT4_STATE;
					when BIT4_STATE =>
								if (BITS_COUNT = "00") then
									if (PARITY_ENABLE = '1') then
										RECEIVER_STATE <= PARITY_STATE;
									else
										RECEIVER_STATE <= STOP_STATE;
									end if;
								else
									RECEIVER_STATE <= BIT5_STATE;
								end if;
					when BIT5_STATE =>
								if (BITS_COUNT(1) = '0') then
									if (PARITY_ENABLE = '1') then
										RECEIVER_STATE <= PARITY_STATE;
									else
										RECEIVER_STATE <= STOP_STATE;
									end if;
								else
									RECEIVER_STATE <= BIT6_STATE;
								end if;
					when BIT6_STATE =>
								if (BITS_COUNT(0) = '0') then
									if (PARITY_ENABLE = '1') then
										RECEIVER_STATE <= PARITY_STATE;
									else
										RECEIVER_STATE <= STOP_STATE;
									end if;
								else
									RECEIVER_STATE <= BIT7_STATE;
								end if;
					when BIT7_STATE =>
								if (PARITY_ENABLE = '1') then
									RECEIVER_STATE <= PARITY_STATE;
								else
									RECEIVER_STATE <= STOP_STATE;
								end if;
					when PARITY_STATE =>
								RECEIVER_STATE <= STOP_STATE;
					when STOP_STATE =>
								if ((BREAK_DETECTOR = '0') and (STOP_BIT = '0') and (PARITY_REGISTER = '0')) then
									RECEIVER_STATE <= BREAK_STATE;
								else
									RECEIVER_STATE <= IDLE_STATE;
								end if;
					when BREAK_STATE =>
								if (SERIAL_IN = '1') then
									RECEIVER_STATE <= IDLE_STATE;
								end if;
					when others =>
								RECEIVER_STATE <= IDLE_STATE;
				end case;
			end if;
		end if;
	end process;

	LINE_STATUS_INTERRUPT <= BREAK_DETECTED or FRAME_ERROR or OVERRUN_ERROR or PARITY_ERROR;
	LSR_OUT <= BREAK_DETECTED & FRAME_ERROR & PARITY_ERROR & OVERRUN_ERROR & RHR_FULL;

end architecture;

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;

entity TransmitterCore is
	port(
		CLK : in std_logic;
		CE : in std_logic;
		BREAK : in std_logic;
		LOOPBACK : in std_logic;
		RESET : in std_logic;
		DATA_IN : in std_logic_vector(7 downto 0);
		WR : in std_logic;
		RD : in std_logic;
		THR_EN : in std_logic;
		IID_EN : in std_logic;
		SERIAL_OUT : out std_logic;
		INTERNAL_SO : out std_logic;
		BITS_COUNT : in std_logic_vector(1 downto 0);
		PARITY_ENABLE : in std_logic;
		PARITY_EVEN_nODD : in std_logic;
		STICK_PARITY : in std_logic;
		TRANSMITTER_INTERRUPT_ACK : in std_logic;
		TRANSMITTER_INTERRUPT : out std_logic;
		LSR_MSB : out std_logic_vector(1 downto 0);
		STOP_BITS : in std_logic
	);
end entity;

architecture TransmitterCore_ARCH of TransmitterCore is
signal BITS_COUNTER : std_logic_vector(4 downto 0);
signal CLK_DIVIDER_BY_16 : std_logic_vector(3 downto 0);
signal CLK_8_CE, CLK_16_CE : std_logic;
signal BITS_TO_TRANSFER : std_logic_vector(4 downto 0);
signal DATA_TO_TRANSFER : std_logic_vector(9 downto 0);
signal SHIFT_REGISTER : std_logic_vector(9 downto 0);
signal TRANSMISSION_IN_PROGRESS : std_logic;
signal INTERNAL_START : std_logic;

signal PARITY : std_logic;

signal THR : std_logic_vector(7 downto 0);
signal START, START_RESET:std_logic;

constant STOP_BIT_VALUE : std_logic := '1';
constant START_BIT_VALUE : std_logic := '0';
constant BREAK_VALUE : std_logic := '0';

signal INTERRUPT_TEMP : std_logic;
signal INTERRUPT_RESET1 : std_logic;
signal INTERRUPT_RESET2 : std_logic;

begin

	process(RD, RESET, INTERRUPT_TEMP)
	begin
		if ((RESET = '0') or (INTERRUPT_TEMP = '0')) then
			INTERRUPT_RESET1 <= '0';
		elsif (rising_edge(RD)) then
			if (IID_EN = '1') then
				INTERRUPT_RESET1 <= TRANSMITTER_INTERRUPT_ACK;
			end if;
		end if;
	end process;

	process(WR, RESET, INTERRUPT_TEMP)
	begin
		if ((RESET = '0') or (INTERRUPT_TEMP = '0')) then
			INTERRUPT_RESET2 <= '0';
		elsif (rising_edge(WR)) then
			if (THR_EN = '1') then
				INTERRUPT_RESET2 <= '1';
			end if;
		end if;
	end process;

	process(CLK, INTERRUPT_RESET1, INTERRUPT_RESET2, RESET)
	begin
		if ((RESET = '0') or (INTERRUPT_RESET1 = '1') or (INTERRUPT_RESET2 = '1')) then
			INTERRUPT_TEMP <= '0';
		elsif (rising_edge(CLK)) then
			if (CE = '1') then
				if (INTERNAL_START = '1') then
					INTERRUPT_TEMP <= '1';
				end if;
			end if;
		end if;
	end process;

	TRANSMITTER_INTERRUPT <= INTERRUPT_TEMP;

	process(WR, RESET)
	begin
		if (RESET = '0') then
			THR <= "00000000";
		elsif (rising_edge(WR)) then
			if (THR_EN = '1') then
				THR <= DATA_IN;
			end if;
		end if;
	end process;

	process(WR, RESET, START_RESET)
	begin
		if (RESET = '0' or START_RESET = '1') then
			START <= '0';
		elsif (rising_edge(WR)) then
			if (THR_EN = '1') then
				START <= '1';
			end if;
		end if;
	end process;

	process(CLK, RESET, START)
	begin
		if (START = '0' or RESET = '0') then
			START_RESET <= '0';
		elsif (rising_edge(CLK)) then
			if (CE = '1') then
				START_RESET <= INTERNAL_START;
			end if;
		end if;
	end process;

	process(THR, PARITY_EVEN_nODD, STICK_PARITY, BITS_COUNT)
	VARIABLE TEMP:STD_LOGIC;
	VARIABLE THR_TEMP:STD_LOGIC_VECTOR(2 downto 0);
	begin
		THR_TEMP(0) := (THR(5) and (BITS_COUNT(0) or BITS_COUNT(1)));
		THR_TEMP(1) := (THR(6) and BITS_COUNT(1));
		THR_TEMP(2) := (THR(7) and BITS_COUNT(1) and BITS_COUNT(0));

		TEMP := THR(0) xor THR(1) xor THR(2) xor THR(3) xor THR(4) xor THR_TEMP(0) xor THR_TEMP(1) xor THR_TEMP(2);

		if (STICK_PARITY = '1')  then
			PARITY <= not PARITY_EVEN_nODD;
		else
			PARITY <= not PARITY_EVEN_nODD xor TEMP;
		end if;
	end process;

	process(CLK, RESET)
	begin
		if (RESET = '0') then
			CLK_DIVIDER_BY_16 <= "0000";
		elsif (rising_edge(CLK)) then
			if (CE = '1') then
				if (INTERNAL_START = '1') then
					CLK_DIVIDER_BY_16 <= "0000";
				else
					CLK_DIVIDER_BY_16 <= CLK_DIVIDER_BY_16 + 1;
				end if;
			end if;
		end if;
	end process;

	CLK_8_CE <= '1' when CLK_DIVIDER_BY_16(2 downto 0) = "111" else '0';
	CLK_16_CE <= '1' when CLK_DIVIDER_BY_16 = "1111" else '0';

	process(BITS_COUNT, PARITY_ENABLE, STOP_BITS)
	variable TEMP : STD_LOGIC_VECTOR(3 downto 0);
	begin
		TEMP := BITS_COUNT & PARITY_ENABLE & STOP_BITS;
		case TEMP is
			when "0000" => BITS_TO_TRANSFER <= "01110";
			when "0001" => BITS_TO_TRANSFER <= "01111";
			when "0010" => BITS_TO_TRANSFER <= "10000";
			when "0011" => BITS_TO_TRANSFER <= "10001";
			when "0100" => BITS_TO_TRANSFER <= "10000";
			when "0101" => BITS_TO_TRANSFER <= "10010";
			when "0110" => BITS_TO_TRANSFER <= "10010";
			when "0111" => BITS_TO_TRANSFER <= "10100";
			when "1000" => BITS_TO_TRANSFER <= "10010";
			when "1001" => BITS_TO_TRANSFER <= "10100";
			when "1010" => BITS_TO_TRANSFER <= "10100";
			when "1011" => BITS_TO_TRANSFER <= "10110";
			when "1100" => BITS_TO_TRANSFER <= "10100";
			when "1101" => BITS_TO_TRANSFER <= "10110";
			when "1110" => BITS_TO_TRANSFER <= "10110";
			when "1111" => BITS_TO_TRANSFER <= "11000";
			when others => NULL;
		end case;
	end process;

	process(CLK, RESET)
	begin
		if (RESET = '0') then
			BITS_COUNTER <= "00000";
		elsif (rising_edge(CLK)) then
			if (CE = '1') then
				if (INTERNAL_START = '1') then
					BITS_COUNTER <= BITS_TO_TRANSFER;
				else
					if (CLK_8_CE = '1') then
						BITS_COUNTER <= BITS_COUNTER - 1;
					end if;
				end if;
			end if;
		end if;
	end process;

	process(CLK, RESET)
	begin
		if (RESET = '0') then
			INTERNAL_START <= '0';
		elsif (rising_edge(CLK)) then
			if (CE = '1') then
				if ((START = '1' and INTERNAL_START = '0') and (TRANSMISSION_IN_PROGRESS = '0' or (BITS_COUNTER(4 downto 1) = "0000" and CLK_DIVIDER_BY_16(2 downto 0) = "110"))) then
					INTERNAL_START <= '1';
				else
					INTERNAL_START <= '0';
				end if;
			end if;
		end if;
	end process;

	DATA_TO_TRANSFER(9) <= START_BIT_VALUE;
	DATA_TO_TRANSFER(8 downto 4) <= THR(0) & THR(1) & THR(2) & THR(3) & THR(4);

	process(BITS_COUNT, PARITY_ENABLE, THR, PARITY)
	variable TEMP:STD_LOGIC_VECTOR(3 downto 0);
	begin
		TEMP := (others => STOP_BIT_VALUE);
		case BITS_COUNT is
			when "00" =>
				if (PARITY_ENABLE = '1') then
					TEMP(3) := PARITY;
				end if;
			when "01" =>
				TEMP(3) := THR(5);
				if (PARITY_ENABLE = '1') then
					TEMP(2) := PARITY;
				end if;
			when "10" =>
				TEMP(3 downto 2) := THR(5) & THR(6);
				if (PARITY_ENABLE = '1') then 
					TEMP(1) := PARITY;
				end if;
			when "11" =>
				TEMP(3 downto 1) := THR(5) & THR(6) & THR(7);
				if (PARITY_ENABLE = '1') then
					TEMP(0) := PARITY;
				end if;
			when others	=>	NULL;
		end case;
		DATA_TO_TRANSFER(3 downto 0) <= TEMP;

⌨️ 快捷键说明

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