Skip to content
Snippets Groups Projects
Select Git revision
  • 9560fac9795746c14b55b5e65d5328a06ef41d92
  • master default protected
  • develop-viktor
  • develop-jonas
4 results

CMakeLists.txt

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    Tx.vhd 5.13 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;
        -- 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;
    	signal bit_to_send, ready_to_send: std_logic;
    
    	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 xor parity_bit;
    	end function;
    
    begin
    	p_bit_send: TxD <= bit_to_send;
    
    		process(clk, rst_n) is
    			begin
    			if rst_n = '0' then
    			--resetter systemet
    			--TxD <= '1';
    			bit_to_send <= '1';
    			Data_bus <= (others => 'Z');
    			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
    				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;
    						ready_to_send <= '1';
    						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;
    
    				case tx_state is
    					when IDLE =>
    						if ready_to_send = '1' then
    							tx_state <= START_BIT;
    							ready_to_send <= '0';
    						else
    							bit_to_send <= '1'; --UART er aktivt høy singal
    							tx_state <= IDLE;
    						end if;
    					when START_BIT =>
    						if baud_clk = '1' then
    							tx_state <= DATA_BITS;
    						else
    							bit_to_send <= '0';
    							tx_state <= START_BIT;
    						end if;
    					when DATA_BITS =>
    						if baud_clk = '1' then
    							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;
    						else
    							bit_to_send <= data_reg(bit_count);
    							tx_state <= DATA_BITS;
    						end if;
    					when PARITY_BIT =>
    						if baud_clk = '1' then
    							tx_state <= STOP_BIT;
    						else
    							bit_to_send <= calculate_parity(data_reg, parity_mode);
    							tx_state <= PARITY_BIT;
    						end if;
    					when STOP_BIT =>
    					    if baud_clk = '1' then
    							tx_state <= IDLE;
    						else
    							bit_to_send <= '1';
    							tx_state <= STOP_BIT;
    						end if;
    				end case;
    			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 tx_state /= IDLE 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;
    			  else
    			   baud_clk <= '0';
    			   baud_count <= 0; -- Nullstill teller i andre tilstander
    			  end if;
    			end if;
    		end process;
    end Behavioral;