diff --git a/lib/uart/sim/tb_uart.fdo b/lib/uart/sim/tb_uart.fdo index c534a4b..f35116e 100644 --- a/lib/uart/sim/tb_uart.fdo +++ b/lib/uart/sim/tb_uart.fdo @@ -2,11 +2,13 @@ ## vlib work +vcom -explicit -93 "../uart_types.vhd" vcom -explicit -93 "../juart_tx.vhd" vcom -explicit -93 "../juart_rx.vhd" vcom -explicit -93 "../../misc/bbfifo.vhd" vcom -explicit -93 "../uart_tx.vhd" vcom -explicit -93 "../uart_rx.vhd" +vcom -explicit -93 "../uart.vhd" vcom -explicit -93 "../tb_uart.vhd" #restart -force diff --git a/lib/uart/sim/tb_uart.wdo b/lib/uart/sim/tb_uart.wdo index c8a5858..1311d50 100644 --- a/lib/uart/sim/tb_uart.wdo +++ b/lib/uart/sim/tb_uart.wdo @@ -4,23 +4,16 @@ add wave -noupdate -format Logic /tb_uart/rst add wave -noupdate -format Logic /tb_uart/clk add wave -noupdate -format Logic /tb_uart/en_16_x_baud add wave -noupdate -format Logic /tb_uart/tx_we -add wave -noupdate -format Logic /tb_uart/ser_out -add wave -noupdate -format Logic /tb_uart/tx_full -add wave -noupdate -format Logic /tb_uart/tx_half_full -add wave -noupdate -format Logic /tb_uart/rx_full -add wave -noupdate -format Logic /tb_uart/rx_half_full add wave -noupdate -format Literal -radix hexadecimal /tb_uart/tx_din -add wave -noupdate -format Logic /tb_uart/ser_in -add wave -noupdate -format Logic /tb_uart/rx_dout_vld add wave -noupdate -format Logic /tb_uart/rx_re add wave -noupdate -format Literal -radix hexadecimal /tb_uart/rx_dout -add wave -noupdate -format Literal -radix hexadecimal /tb_uart/baud_count -add wave -noupdate -format Literal -radix hexadecimal /tb_uart/baud_reg add wave -noupdate -format Literal -radix hexadecimal /tb_uart/data_rx add wave -noupdate -format Literal -radix hexadecimal /tb_uart/data_tx add wave -noupdate -format Literal /tb_uart/count_rx +add wave -noupdate -format Logic /tb_uart/tx_ser +add wave -noupdate -format Logic /tb_uart/rx_ser TreeUpdate [SetDefaultTree] -WaveRestoreCursors {{Cursor 1} {878977587 ps} 0} +WaveRestoreCursors {{Cursor 1} {10072550 ps} 0} configure wave -namecolwidth 150 configure wave -valuecolwidth 100 configure wave -justifyvalue left diff --git a/lib/uart/tb_uart.vhd b/lib/uart/tb_uart.vhd index 9314ce8..31717db 100644 --- a/lib/uart/tb_uart.vhd +++ b/lib/uart/tb_uart.vhd @@ -25,6 +25,9 @@ library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.numeric_std.ALL; +LIBRARY WORK; +USE WORK.uart_types.all; + entity tb_uart is end; @@ -38,58 +41,42 @@ architecture behave of tb_uart is signal rst : std_logic := '1'; signal clk : std_logic := '1'; signal en_16_x_baud : std_logic := '1'; + signal ctrl : ctrl_t; + signal status : status_t; -- TX signal tx_we : std_logic := '0'; - signal ser_out : std_logic; - signal tx_full : std_logic; - signal tx_half_full : std_logic; + signal tx_ser : std_logic; signal tx_din : unsigned(7 downto 0) := (others => '0'); -- RX - signal ser_in : std_logic := '1'; - signal rx_dout_vld : std_logic; - signal rx_full : std_logic; - signal rx_half_full : std_logic; - signal rx_dout : unsigned(7 downto 0); signal rx_re : std_logic := '0'; + signal rx_ser : std_logic := '1'; + signal rx_dout : unsigned(7 downto 0); -- Others - signal baud_count : unsigned(15 downto 0); - signal baud_reg : unsigned(15 downto 0) := to_unsigned(BAUD_DIV-1, baud_count'length); signal data_rx : unsigned(7 downto 0); signal data_tx : unsigned(7 downto 0); signal count_rx : natural; begin - ser_in <= ser_out; + rx_ser <= tx_ser; + ctrl.baudrate <= to_unsigned(BAUD_DIV-1, ctrl.baudrate'length); -inst_uart_tx : entity work.uart_tx +dut : entity work.uart PORT MAP ( rst => rst, clk => clk, we => tx_we, - din => tx_din, - en_16_x_baud => en_16_x_baud, - full => tx_full, - half_full => tx_half_full, - ser_out => ser_out - ); - -inst_uart_rx : entity work.uart_rx - PORT MAP - ( - rst => rst, - clk => clk, - en_16_x_baud => en_16_x_baud, - dout_vld => rx_dout_vld, - dout => rx_dout, re => rx_re, - full => rx_full, - half_full => rx_half_full, - ser_in => ser_in + din => tx_din, + dout => rx_dout, + ser_tx => tx_ser, + ser_rx => rx_ser, + ctrl => ctrl, + status => status ); CLK_GEN: process @@ -104,7 +91,7 @@ PROC_DATAREG_RX: if rising_edge(clk) then if rst = '1' then count_rx <= 0; - elsif rx_dout_vld = '1' and rx_re = '1' then + elsif status.rx_present = '1' and rx_re = '1' then -- assert rx_dout = count_rx report "Data mismatch" severity failure; data_rx <= rx_dout; count_rx <= count_rx + 1; @@ -115,7 +102,7 @@ PROC_DATAREG_RX: PROC_RX_RE: process begin wait for 10 us; - rx_re <= rx_dout_vld; + rx_re <= status.rx_present; end process; PROC_DATAREG_TX: process @@ -124,22 +111,6 @@ PROC_DATAREG_TX: process data_tx <= tx_din; end process; -baud_timer: -process(clk) -begin - if rising_edge(clk) then - en_16_x_baud <= '0'; - if rst = '1' then - baud_count <= (others => '0'); - elsif baud_count = baud_reg then - baud_count <= (others => '0'); - en_16_x_baud <= '1'; - else - baud_count <= baud_count + 1; - end if; - end if; -end process; - ------------------------------------------------------------------------------------------ STIMULUS: process @@ -156,7 +127,7 @@ STIMULUS: process wait until rising_edge(clk); tx_din <= to_unsigned(i, 8); tx_we <= '1'; - wait until rising_edge(clk) and tx_full = '0'; + wait until rising_edge(clk) and status.tx_full = '0'; tx_we <= '0'; end loop; wait; diff --git a/lib/uart/uart.vhd b/lib/uart/uart.vhd new file mode 100644 index 0000000..bb6894a --- /dev/null +++ b/lib/uart/uart.vhd @@ -0,0 +1,100 @@ +LIBRARY IEEE; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.NUMERIC_STD.ALL; + +LIBRARY WORK; +USE WORK.uart_types.all; + +------------------------------------------------------------------------------------ +ENTITY uart IS + Port + ( + clk : in STD_LOGIC; + rst : in STD_LOGIC; + we : in STD_LOGIC; + re : in STD_LOGIC; + din : in unsigned(7 downto 0); + dout : out unsigned(7 downto 0); + ser_rx : in std_logic; + ser_tx : out std_logic; + ctrl : in ctrl_t; + status : out status_t + ); +END uart; + +ARCHITECTURE rtl OF uart IS + +signal baud_count : unsigned(15 downto 0); +signal en_16_x_baud : std_logic; + +signal rx_dout_vld : std_logic; +signal rx_full : std_logic; +signal rx_half_full : std_logic; + +signal tx_complete : std_logic; +signal tx_empty : std_logic; +signal tx_full : std_logic; +signal tx_half_full : std_logic; + +begin + +baud_timer: +process(clk) +begin + if rising_edge(clk) then + en_16_x_baud <= '0'; + if rst = '1' then + baud_count <= (others => '0'); + elsif baud_count = ctrl.baudrate then + baud_count <= (others => '0'); + en_16_x_baud <= '1'; + else + baud_count <= baud_count + 1; + end if; + end if; +end process; + +inst_uart_tx : entity work.uart_tx + PORT MAP + ( + rst => rst, + clk => clk, + we => we, + din => din, + en_16_x_baud => en_16_x_baud, + full => tx_full, + half_full => tx_half_full, + tx_complete => tx_complete, + tx_empty => tx_empty, + ser_out => ser_tx + ); + +inst_uart_rx : entity work.uart_rx + PORT MAP + ( + rst => rst, + clk => clk, + en_16_x_baud => en_16_x_baud, + dout_vld => rx_dout_vld, + dout => dout, + re => re, + full => rx_full, + half_full => rx_half_full, + ser_in => ser_rx + ); + +-- Status +status.rx_present <= rx_dout_vld; +status.tx_complete <= tx_complete; +status.tx_empty <= tx_empty; +status.tx_full <= tx_full; + +end rtl; + +------------------------------------------------------------------------------------ +-- +-- END OF FILE UART_RX.VHD +-- +------------------------------------------------------------------------------------ + +