diff --git a/Rx.vhd b/Rx.vhd index f0057e77b5ff3414f704d1afc5b6445c7a9c951b..1e6c9a6ab98118f52f38b084ae0fa6ce03ff5334 100644 --- a/Rx.vhd +++ b/Rx.vhd @@ -1,6 +1,9 @@ library IEEE; use IEEE.STD_LOGIC_1164.ALL; +library Files; +use Files.fifo; + entity Rx is generic( F_CLK_115k: integer:= 54; @@ -41,6 +44,10 @@ architecture Behavioral of Rx is signal fifofull: std_logic := '0'; signal fifo_ut: std_logic_vector(7 downto 0); signal fifotom: std_logic := '1'; + signal fifo_rst: std_logic := '0'; + signal fifo_rd_req: std_logic:= '0'; + signal fifo_wr_req: std_logic:= '0'; + -------------------------------------------------------------------------------------------------------------------------------- --Funksjoner -------------------------------------------------------------------------------------------------------------------------------- @@ -156,6 +163,22 @@ architecture Behavioral of Rx is end case; end function; begin + + -------------------------------------------------------------------------------------------------------------------------------- + --component fifo + -------------------------------------------------------------------------------------------------------------------------------- + fifo: entity Files.fifo + Port map( + clock => clk, + data => fifo_inn, + empty => fifotom, + full => fifofull, + q => fifo_ut, + sclr => fifo_rst, + rdreq => fifo_rd_req, + wrreq => fifo_wr_req + ); + ------------------------------------------------------------------------------------------------------------------------------- --Prosesser ------------------------------------------------------------------------------------------------------------------------------- @@ -193,6 +216,7 @@ begin elsif rising_edge(clk) and datalest(10) = '0' then if parity_checker(parity_check,datalest) = true then + fifo_wr_req <= '1'; case parity_check is when ingen => fifo_inn <= datalest(9 downto 2); @@ -206,12 +230,14 @@ begin paritetsfeil <= '1'; end if; else + fifo_wr_req <= '0'; --sette inn logikk end if; end process; kommunikasjon: process(clk, rst_n) is begin + fifo_rd_req <= '0'; if rst_n = '0' then elsif rising_edge(clk) then case adresse is @@ -221,6 +247,7 @@ begin when "101" => if Rd_sig = '1' then Data_bus <= fifo_ut; + fifo_rd_req <= '1'; else null; end if; diff --git a/Rx_tb.vhd b/Rx_tb.vhd new file mode 100644 index 0000000000000000000000000000000000000000..737767ed5ef07ccc7e11559b8313027ff32fa1f9 --- /dev/null +++ b/Rx_tb.vhd @@ -0,0 +1,100 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.STD_LOGIC_ARITH.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; + +entity Rx_tb is +end Rx_tb; + +architecture Behavioral of Rx_tb is + + -- Testbenkens signaler + signal clk : std_logic := '0'; + signal rst_n : std_logic := '0'; + signal RxD : std_logic := '1'; + signal Data_bus : std_logic_vector(7 downto 0) := (others => 'Z'); + signal Rd_sig : std_logic := '0'; + signal Wr_sig : std_logic := '0'; + signal adresse : std_logic_vector(2 downto 0) := "000"; + + -- Instans av Rx-komponenten + component Rx + generic( + F_CLK_115k : integer := 54; + F_CLK_576 : integer := 109; + F_CLK_384 : integer := 162; + F_CLK_192 : integer := 325; + F_CLK_096 : integer := 650 + ); + port( + clk : in std_logic; + rst_n : in std_logic; + RxD : in std_logic; + Data_bus : inout std_logic_vector(7 downto 0); + Rd_sig : in std_logic; + Wr_sig : in std_logic; + adresse : in std_logic_vector(2 downto 0) + ); + end component; + +begin + + -- Instansiering av Rx-enheten + uut: Rx + port map ( + clk => clk, + rst_n => rst_n, + RxD => RxD, + Data_bus => Data_bus, + Rd_sig => Rd_sig, + Wr_sig => Wr_sig, + adresse => adresse + ); + + -- Klokkeprosessen genererer et 50 MHz klokkesignal + clk_process: process + begin + while true loop + clk <= '0'; + wait for 10 ns; + clk <= '1'; + wait for 10 ns; + end loop; + end process; + + -- Stimuli for reset og testoperasjoner + stimulus: process + begin + -- Reset og initiering + rst_n <= '0'; + wait for 50 ns; + rst_n <= '1'; + + -- Konfigurering av paritetssjekk og baud rate + adresse <= "100"; -- Adresse for konfigurasjon + Wr_sig <= '1'; -- Skriveoperasjon + Data_bus <= "00001011"; -- Konfigurer for oddetall paritet og baud rate B576 + wait for 20 ns; + Wr_sig <= '0'; + Data_bus <= (others => 'Z'); -- Sett Data_bus tilbake til Z etter skriving + + -- Test av datastrøm + wait for 100 ns; + adresse <= "101"; -- Adresse for lesing av data fra FIFO + Rd_sig <= '1'; + wait for 20 ns; + Rd_sig <= '0'; + + -- Test av FIFO-status + wait for 100 ns; + adresse <= "110"; -- Adresse for lesing av status + Wr_sig <= '1'; + wait for 20 ns; + Wr_sig <= '0'; + + -- Flere tester kan settes opp her + -- Slutt på simuleringen + wait; + end process; + +end Behavioral; diff --git a/Tx.vhd b/Tx.vhd index f75d60233af25ad6b77927cfe31e9f4df5b0f13b..e7a24e97ba6156506f0ed2d8e208d290d2aba721 100644 --- a/Tx.vhd +++ b/Tx.vhd @@ -19,7 +19,6 @@ architecture Behavioral of Tx is 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; @@ -30,7 +29,8 @@ architecture Behavioral of Tx is --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? + 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 @@ -81,24 +81,25 @@ architecture Behavioral of Tx is for i in data'range loop tmp := tmp xor data(i); end loop; - return tmp xnor parity_bit; + 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'; + --TxD <= '1'; + bit_to_send <= '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 @@ -109,7 +110,7 @@ begin when "001" => --Initilaiserer transmisjon if tx_state = IDLE and Wr_sig = '1' then data_reg <= Data_bus; - tx_state <= START_BIT; + ready_to_send <= '1'; else null; end if; when "010" => -- busy @@ -125,35 +126,54 @@ begin when others => null; end case; - -- WIP skal sende når den får write av controller - if (baud_clk = '1' and last_baud_clk = '0') or (baud_clk = '0' and last_baud_clk = '1') then case tx_state is when IDLE => - TxD <= '1'; --UART er høy singal når det ikke sendes noe + 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 => - TxD <= '0'; - tx_state <= DATA_BITS; + if baud_clk = '1' then + tx_state <= DATA_BITS; + else + bit_to_send <= '0'; + tx_state <= START_BIT; + end if; 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; + 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 - tx_state <= PARITY_BIT; + bit_count <= bit_count + 1; end if; else - bit_count <= bit_count + 1; + bit_to_send <= data_reg(bit_count); + tx_state <= DATA_BITS; end if; when PARITY_BIT => - TxD <= calculate_parity(data_reg, parity_mode); - tx_state <= STOP_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 => - TxD <= '1'; - tx_state <= IDLE; + if baud_clk = '1' then + tx_state <= IDLE; + else + bit_to_send <= '1'; + tx_state <= STOP_BIT; + end if; end case; end if; - end if; end process; -- baud_rate Generator Process @@ -163,12 +183,18 @@ begin 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 <= not baud_clk; + 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; diff --git a/Tx_tb.vhd b/Tx_tb.vhd new file mode 100644 index 0000000000000000000000000000000000000000..784d121dff127440d3116983346776d57305635a --- /dev/null +++ b/Tx_tb.vhd @@ -0,0 +1,128 @@ +-- Testbench of Tx +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.NUMERIC_STD.ALL; + +-- Entity of testbench (empty) +entity Tx_tb is +end Tx_tb; + +architecture SimulationModel of Tx_tb is + + -- Constant declaration + constant CLK_PERIOD : time := 20 ns; -- 50 MHz klokke + + -- Component declarasion + component Tx + Port ( + clk : in std_logic; + rst_n : in std_logic; + Rd_sig : in std_logic; + Wr_sig : in std_logic; + adresse : in std_logic_vector(2 downto 0); + Data_bus : inout std_logic_vector(7 downto 0); + TxD : out std_logic + ); + end component; + + -- Signal declaration + signal clk : std_logic := '0'; + signal rst_n : std_logic := '1'; + signal adresse : std_logic_vector(2 downto 0); + signal Data_bus : std_logic_vector(7 downto 0); + signal TxD : std_logic; + signal Rd_sig : std_logic; + signal Wr_sig : std_logic; + +begin + + -- Component instantiations UART TX-modul (DUT) + DUT: component Tx + Port Map ( + clk => clk, + rst_n => rst_n, + adresse => adresse, + Data_bus => Data_bus, + TxD => TxD, + Rd_sig => Rd_sig, + Wr_sig => Wr_sig + ); + + -- Generation of clock + p_clk: process is + begin + clk <= '0'; + wait for CLK_PERIOD / 2; + clk <= '1'; + wait for CLK_PERIOD / 2; + end process; + + --Generation of resetN + p_rst_n: process is + begin + rst_n <= '0'; + wait for 2.2*CLK_PERIOD; + rst_n <= '1'; + wait; + end process; + + -- Test procedure + p_test_procedure: process + + -- Initialisation of testbench + procedure tb_init is + begin + adresse <= (others => 'Z'); + Data_bus <= (others => 'Z'); + Wr_sig <= '0'; + Rd_sig <= '0'; + wait until rst_n = '1'; + wait for 100 ns; + wait until rising_edge(clk); + wait for 1 ns; + end tb_init; + + -- Test Case 1: Konfigurasjon av baud rate og paritet + procedure config is + begin + Wr_sig <= '1'; + adresse <= "000"; -- Konfigurer baud rate og paritet + Data_bus <= "00000001"; -- Sett baud rate til 57600 (001) og ingen paritet (00) + wait for CLK_PERIOD; + Wr_sig <= '0'; + wait for CLK_PERIOD; + end config; + + procedure send is + begin + Wr_sig <= '1'; + adresse <= "001"; -- Sender data til Tx + Data_bus <= "10101010"; -- data + wait for CLK_PERIOD; + Wr_sig <= '0'; + wait for 20*CLK_PERIOD; + wait for 0.18 ms; + end send; + + procedure test_busy is + begin + Rd_sig <= '1'; + adresse <= "010"; -- Konfigurer Ber om status + wait for 2*CLK_PERIOD; + Rd_sig <= '0'; + wait for CLK_PERIOD; + wait for 0.1 ms; + end test_busy; + + + begin + tb_init; + config; + send; + test_busy; + + wait for 100 ns; + assert false report "Testbench finished" severity failure; + end process; + +end architecture SimulationModel; diff --git a/fifo.cmp b/fifo.cmp new file mode 100644 index 0000000000000000000000000000000000000000..abc023baaef843bd302ba350d4178a776c58c211 --- /dev/null +++ b/fifo.cmp @@ -0,0 +1,29 @@ +--Copyright (C) 2020 Intel Corporation. All rights reserved. +--Your use of Intel Corporation's design tools, logic functions +--and other software and tools, and any partner logic +--functions, and any output files from any of the foregoing +--(including device programming or simulation files), and any +--associated documentation or information are expressly subject +--to the terms and conditions of the Intel Program License +--Subscription Agreement, the Intel Quartus Prime License Agreement, +--the Intel FPGA IP License Agreement, or other applicable license +--agreement, including, without limitation, that your use is for +--the sole purpose of programming logic devices manufactured by +--Intel and sold by Intel or its authorized distributors. Please +--refer to the applicable agreement for further details, at +--https://fpgasoftware.intel.com/eula. + + +component fifo + PORT + ( + clock : IN STD_LOGIC ; + data : IN STD_LOGIC_VECTOR (7 DOWNTO 0); + rdreq : IN STD_LOGIC ; + sclr : IN STD_LOGIC ; + wrreq : IN STD_LOGIC ; + empty : OUT STD_LOGIC ; + full : OUT STD_LOGIC ; + q : OUT STD_LOGIC_VECTOR (7 DOWNTO 0) + ); +end component; diff --git a/fifo.qip b/fifo.qip new file mode 100644 index 0000000000000000000000000000000000000000..c5008f00460250e78f63a8b90b3488d11dc9b391 --- /dev/null +++ b/fifo.qip @@ -0,0 +1,5 @@ +set_global_assignment -name IP_TOOL_NAME "FIFO" +set_global_assignment -name IP_TOOL_VERSION "20.1" +set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{MAX 10}" +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "fifo.vhd"] +set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "fifo.cmp"]