EmbDev.net

Forum: FPGA, VHDL & Verilog help writing testbench for uart


Author: mike (Guest)
Posted on:

Rate this post
0 useful
not useful
hi! i am kind a new in the business i have problem to write a testbench 
to the next uart code. any help will be appreciated
(this uart code was found in the web)

library ieee;
    use ieee.std_logic_1164.all;
    use ieee.std_logic_unsigned.all;

entity uart is
    port (
        reset       :in  std_logic;
        txclk       :in  std_logic;
        ld_tx_data  :in  std_logic;
        tx_data     :in  std_logic_vector (7 downto 0);
        tx_enable   :in  std_logic;
        tx_out      :out std_logic;
        tx_empty    :out std_logic;
        rxclk       :in  std_logic;
        uld_rx_data :in  std_logic;
        rx_data     :out std_logic_vector (7 downto 0);
        rx_enable   :in  std_logic;
        rx_in       :in  std_logic;
        rx_empty    :out std_logic
    );
end entity;
architecture rtl of uart is
    -- Internal Variables
    signal tx_reg         :std_logic_vector (7 downto 0);
    signal tx_over_run    :std_logic; -- counter that check that we transmit all the data bits.
    signal tx_cnt         :std_logic_vector (3 downto 0);--the counter that check that we transmit all the data bits.
    signal rx_reg         :std_logic_vector (7 downto 0);
    signal rx_sample_cnt  :std_logic_vector (3 downto 0);-- the counter that check that we run half of the bit transmit.
    signal rx_cnt         :std_logic_vector (3 downto 0);-- the counter that check that we recive all the data bits.
    signal rx_frame_err   :std_logic;
    signal rx_over_run    :std_logic;--the flag that check that we recive all the data bits.
    signal rx_d1          :std_logic;
    signal rx_d2          :std_logic;
    signal rx_busy        :std_logic;
    signal rx_is_empty    :std_logic;
    signal tx_is_empty    :std_logic;
begin
    -- UART RX Logic
    process (rxclk, reset) begin
        if (reset = '1') then
            rx_reg        <= (others=>'0');
            rx_data       <= (others=>'0');
            rx_sample_cnt <= (others=>'0');
            rx_cnt        <= (others=>'0');
            rx_frame_err  <= '0';
            rx_over_run   <= '0';
            rx_is_empty   <= '1';
            rx_d1         <= '1';
            rx_d2         <= '1';
            rx_busy       <= '0';
        elsif (rising_edge(rxclk)) then
            -- Synchronize the asynch signal
            rx_d1 <= rx_in;
            rx_d2 <= rx_d1;
            -- Uload the rx data
            if (uld_rx_data = '1') then
                rx_data  <= rx_reg;
                rx_is_empty <= '1';
            end if;
            -- Receive data only when rx is enabled
            if (rx_enable = '1') then
                -- Check if just received start of frame
                if (rx_busy = '0' and rx_d2 = '0') then
                    rx_busy       <= '1';
                    rx_sample_cnt <= X"1";
                    rx_cnt        <= X"0";
                end if;
                -- Start of frame detected, Proceed with rest of data
                if (rx_busy = '1') then
                    rx_sample_cnt <= rx_sample_cnt + 1;
                    -- Logic to sample at middle of data
                    if (rx_sample_cnt = 7) then
                        if ((rx_d2 = '1') and (rx_cnt = 0)) then
                            rx_busy <= '0';
                        else
                            rx_cnt <= rx_cnt + 1;
                            -- Start storing the rx data
                            if (rx_cnt > 0 and rx_cnt < 9) then
                                rx_reg(conv_integer(rx_cnt) - 1) <= rx_d2;
                            end if;
                            if (rx_cnt = 9) then
                                rx_busy <= '0';
                                -- Check if End of frame received correctly
                                if (rx_d2 = '0') then
                                    rx_frame_err <= '1';
                                else
                                    rx_is_empty  <= '0';
                                    rx_frame_err <= '0';
                                    -- Check if last rx data was not unloaded,
                                    if (rx_is_empty = '1') then
                                        rx_over_run  <= '0';
                                    else
                                        rx_over_run  <= '1';
                                    end if;
                                end if;
                            end if;
                        end if;
                    end if;
                end if;
            end if;
            if (rx_enable = '0') then
                rx_busy <= '0';
            end if;
        end if;
    end process;
    rx_empty <= rx_is_empty;
    
    -- UART TX Logic
    process (txclk, reset) begin
        if (reset = '1') then
            tx_reg        <= (others=>'0');
            tx_is_empty   <= '1';
            tx_over_run   <= '0';
            tx_out        <= '1';
            tx_cnt        <= (others=>'0');
        elsif (rising_edge(txclk)) then

            if (ld_tx_data = '1') then
                if (tx_is_empty = '0') then
                    tx_over_run <= '0';
                else
                    tx_reg   <= tx_data;
                    tx_is_empty <= '0';
                end if;
            end if;
            if (tx_enable = '1' and tx_is_empty = '0') then
                tx_cnt <= tx_cnt + 1;
                if (tx_cnt = 0) then
                    tx_out <= '0';
                end if;
                if (tx_cnt > 0 and tx_cnt < 9) then
                    tx_out <= tx_reg(conv_integer(tx_cnt) -1);
                end if;
                if (tx_cnt = 9) then
                    tx_out <= '1';
                    tx_cnt <= X"0";
                    tx_is_empty <= '1';
                end if;
            end if;
            if (tx_enable = '0') then
                tx_cnt <= X"0";
            end if;
        end if;
    end process;
    tx_empty <= tx_is_empty;

end architecture;

: Edited by Moderator
Author: Lothar Miller (lkmiller) (Moderator)
Posted on:

Rate this post
0 useful
not useful
Your only work up to now was to copy some piece of VHDL code from 
somewhere from the internet, and now you want somebody else writing a 
test bench for it. Did I figure out that correctly?

I suggest, that YOU start writing this test bench and if there's a 
specific problem you can ask a question.

BTW: wrap the tags [ vhdl ] and [ /vhdl ] without the spaces around your 
VHDL code and you will see a little kind of magic...

BTW2: the code above is not a good one. Its a lousy style to use a 
std_logic_vector for calculating and counting...

: Edited by Moderator
Author: Hector I. (hector_i)
Posted on:

Rate this post
0 useful
not useful
Respected Sir,
I am doing UART as my project.

please elaborate more on your tips.

BTW: wrap the tags [ vhdl ] and [ /vhdl ] without the spaces around your
VHDL code and you will see a little kind of magic...

(where to write this..)

BTW2: the code above is not a good one. Its a lousy style to use a
std_logic_vector for calculating and counting...

(sir, please tell me if this will be lousy , what will be the nice 
idea.?)

Author: Lothar Miller (lkmiller) (Moderator)
Posted on:

Rate this post
0 useful
not useful
Hector I. wrote:
> BTW: wrap the tags [ vhdl ] and [ /vhdl ] without the spaces around your
> VHDL code and you will see a little kind of magic...
> (where to write this..)
Do it this way:
[vhdl]
  -- your vhdl code
[/vhdl]
And you will get this neatly formated view:
  -- your vhdl code

> BTW2: the code above is not a good one. Its a lousy style to use a
> std_logic_vector for calculating and counting...
>
> (sir, please tell me if this will be lousy , what will be the nice
> idea.?)
Use the numeric_std package and the signed/unsigned vectors for 
calculations. Or use an integer for calculations. But don't use 
std_logic_vector for calculations.

For a good working UART look there (its German, try Google translator):
http://www.lothar-miller.de/s9y/categories/42-RS232

Author: FPGA advisor (Guest)
Posted on:

Rate this post
0 useful
not useful
The most appreciated way to get a testbench for P2P-systems like UARt, 
I2C, SPI and such is to join two complementary modules interfacing each 
other vice versa.

Just place your UART against itself and write a CODE to be transmitted 
into it. See if it transmits, if the counter part receives correctly and 
be ready and have done.

Reply

Entering an e-mail address is optional. If you want to receive reply notifications by e-mail, please log in.

Rules — please read before posting

  • Post long source code as attachment, not in the text
  • Posting advertisements is forbidden.

Formatting options

  • [c]C code[/c]
  • [avrasm]AVR assembler code[/avrasm]
  • [vhdl]VHDL code[/vhdl]
  • [code]code in other languages, ASCII drawings[/code]
  • [math]formula (LaTeX syntax)[/math]




Bild automatisch verkleinern, falls nötig
Note: the original post is older than 6 months. Please don't ask any new questions in this thread, but start a new one.