Skip to content
Snippets Groups Projects
Select Git revision
  • d6b87ede8429245d3ec3d73975ca3a72826c7af0
  • master default protected
  • Eilerts_branch
  • Karins_branch
  • Mads_branch
5 results

InputPopUpWindow.class

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    Tx.vhd 4.60 KiB
    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.NUMERIC_STD.ALL;
    
    entity Tx is
        Port (
            clk, rst_n        : in  std_logic;
    		adresse : in std_logic_vector(2 downto 0);
            Data_bus : inout std_logic_vector(7 downto 0);
            TxD			 : out std_logic;
    		Rd_sig, Wr_sig: in std_logic
        );
    end Tx;
    
    architecture Behavioral of Tx is
    	
    	-- Baudrate signaler
        type baud_type is (b9600, b19200, b38400, b57600, b115200);
        signal baud_rate : baud_type;
    	signal baud_count : natural range 0 to 5208;
    	signal baud_clk : std_logic;
    	signal last_baud_clk : std_logic;
        -- Parity type
        type parity_type is (no_parity, even_parity, odd_parity);
        signal parity_mode : parity_type;
    
    	-- TX tilstandsmaskin
        type tx_state_type is (IDLE, START_BIT, DATA_BITS, PARITY_BIT, STOP_BIT);
        signal tx_state : tx_state_type;
    	
    	--ovrige signaler
    	signal data_reg : std_logic_vector(7 downto 0);
    	signal bit_count : natural range 0 to 7; --er den riktig? teller det opp mellom data_reg? eller ned?
    
    	function select_baud(baud: std_logic_vector(2 downto 0)) return baud_type is
    		begin
    			case baud is
    				when "000" => return b115200;
    				when "001" => return b57600;
    				when "010" => return b38400;
    				when "011" => return b19200;
    				when "100" => return b9600;
    				when others => return b115200;
    			end case;
    		end function;
    
    	function select_parity(par: std_logic_vector(1 downto 0)) return parity_type is
    		begin
    			case par is
    				when "00" => return no_parity;
    				when "10" => return even_parity;
    				when "11" => return odd_parity;
    				when others => return no_parity;
    			end case;
    		end function;
    
    	function division_factor(rate : baud_type) return natural is
    		begin
    			case rate is
    				when b9600    => return 5208;
    				when b19200   => return 2604;
    				when b38400   => return 1302;
    				when b57600   => return 868;
    				when b115200  => return 434;
    				when others   => return 434; -- standard til 115200 om det er ukjent verdi
    			end case;
    	end function;
    
    	function calculate_parity(data : std_logic_vector(7 downto 0);
    							  mode : parity_type) 
    							  return std_logic is
    		variable tmp : std_logic := '0';
    		variable parity_bit : std_logic;
    		begin
    			case mode is
    				when even_parity => parity_bit := '0';
    				when odd_parity => parity_bit := '1';
    				when others => parity_bit := '0';
    			end case;
    
    			for i in data'range loop
    				tmp := tmp xor data(i);
    			end loop;
    			return tmp xnor parity_bit;
    	end function;
    
    begin
    		process(clk, rst_n) is
    			begin
    			if rst_n = '0' then
    			--resetter systemet
    			TxD <= '1';
    			Data_bus <= (others => 'Z');
    			last_baud_clk <= '0';
    			baud_rate <= baud_type'right;
                parity_mode <= parity_type'left;
    			tx_state <= tx_state_type'left;
    			bit_count <= 0;
    			data_reg <= (others => '0');
    			elsif rising_edge(clk) then
    				last_baud_clk <= baud_clk;
    				case adresse is
    					when "000" => -- Konfigurasjonsinnstillinger
    						if Wr_sig = '1' then
    							baud_rate <= select_baud(Data_bus(2 downto 0));
    							parity_mode <= select_parity(Data_bus(4 downto 3));
    						else null;
    						end if;
    					when "001" => --Initilaiserer transmisjon
    						if tx_state = IDLE and Wr_sig = '1' then
    						data_reg <= Data_bus;
    						tx_state <= START_BIT;
    						else null;
    						end if;
    					when "010" =>  -- busy
    						if Rd_sig = '1' then
    							if tx_state = IDLE then
    								Data_bus <= (others => '0');
    							else
    								Data_bus <= (others => '0');
    								Data_bus(0) <= '1'; -- Sett LSB til 1 når ikke IDLE
    							end if;
    						else null;
    						end if;
    					when others => null;
    				end case;
    
    				if (baud_clk = '1' and last_baud_clk = '0') then
    				case tx_state is
    					when IDLE =>
    						TxD <= '1'; --UART er høy singal når det ikke sendes noe
    					when START_BIT =>
    						TxD <= '0';
    						tx_state <= DATA_BITS;
    					when DATA_BITS =>
    						TxD <= data_reg(bit_count);
    						if bit_count = 7 then
    							bit_count <= 0;
    							if parity_mode = no_parity then
    								tx_state <= STOP_BIT;
    							else
    								tx_state <= PARITY_BIT;
    							end if;
    						else
    							bit_count <= bit_count + 1;
    						end if;
    					when PARITY_BIT =>
    						TxD <= calculate_parity(data_reg, parity_mode);
    						tx_state <= STOP_BIT;
    					when STOP_BIT =>
    						TxD <= '1';
    						tx_state <= IDLE;
    				end case;
    			end if;
    			end if;
    		end process;
    
    		-- baud_rate Generator Process
    		process(clk, rst_n)
    		begin
    			if rst_n = '0' then
    				baud_count <= 0;
    				baud_clk <= '0';
    			elsif rising_edge(clk) then
    				if baud_count = division_factor(baud_rate) - 1 then
    					baud_clk <= '1';
    					baud_count <= 0;
    				else
    					baud_clk <= '0';
    					baud_count <= baud_count + 1;
    				end if;
    			end if;
    		end process;
    end Behavioral;