EmbDev.net

Forum: FPGA, VHDL & Verilog Receiving UART


Author: Michelle Nu (nojman)
Posted on:

Rate this post
0 useful
not useful
Hi!

I have a assignment to write a receiving part of a UART circuit. I have 
got this code but how can rewrite it so it's the receiving part?
I tried to take away all the "tx" rows (transmission) but then i could 
not get pas the test bench.

Would be really glad for any help.

The code.

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;
    signal tx_cnt         :std_logic_vector (3 downto 0);
    signal rx_reg         :std_logic_vector (7 downto 0);
    signal rx_sample_cnt  :std_logic_vector (3 downto 0);
    signal rx_cnt         :std_logic_vector (3 downto 0);
    signal rx_frame_err   :std_logic;
    signal rx_over_run    :std_logic;
    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
Michael Nu wrote:
> I tried to take away all the "tx" rows (transmission) but then i could
> not get pas the test bench.
Why not? Which test bench? Did you get some error messages? Maybe you 
have to adapt the test bench also?

> I tried to take away all the "tx" rows (transmission) but then i could
> not get pas the test bench.
Maybe copy&cut&paste&delete is not enough here. Did you start thinking 
one minute about your homework?

Author: Michelle Nu (nojman)
Posted on:

Rate this post
0 useful
not useful
Thanks for your reply. I'm new in programing and vhdl and have a hard 
time to understanding and remembering how to procced and solve the task 
we are getting.
I get this error messege on my test bench.


Parsing VHDL file "/nfs/home/neuman/UART2/uart_test2.vhd" into library 
isim_temp
ERROR:HDLCompiler:806 - "/nfs/home/neuman/UART2/uart_test2.vhd" Line 13: 
Syntax error near "<".
ERROR:HDLCompiler:806 - "/nfs/home/neuman/UART2/uart_test2.vhd" Line 22: 
Syntax error near "<".
ERROR:HDLCompiler:806 - "/nfs/home/neuman/UART2/uart_test2.vhd" Line 28: 
Syntax error near "<".


The test bench:

12 -- Component Declaration
13          COMPONENT <component name>
14          PORT(
15                  <port1> : IN std_logic;
16                  <port2> : IN std_logic_vector(3 downto 0);
17                  <port3> : OUT std_logic_vector(3 downto 0)
18                  );
19          END COMPONENT;
20
21          SIGNAL <signal1> :  std_logic;
22          SIGNAL <signal2> :  std_logic_vector(3 downto 0);
23
24
25  BEGIN
26
27  -- Component Instantiation
28          uut: <component name> PORT MAP(
29                  <port1> => <signal1>,
30                  <port3> => <signal2>



I tried to change the "name" to uart but that did not help.
Tell me if you need something more to help me.

Author: PittyJ (Guest)
Posted on:

Rate this post
0 useful
not useful
You should read a book about the basics of VHDL. Perhaps the one from 
Peter Ashenden. It contains a chapter about test benches.

Author: williwilliwallawalla (Guest)
Posted on:

Rate this post
0 useful
not useful
What you show us is a "template" rather than functional code.

These mysterious "<" and ">" signs delimit the positions where the 
"real" signal and entity names shall be placed by you.

It's sound that you first have to study the language and some example 
code.

Author: Michelle Nu (nojman)
Posted on:

Rate this post
0 useful
not useful
Thanks for your replies.
My teacher asked me after a hardware course if I wanted to take a course 
where you work with a Basys2 and showed it to me. He asked me if I had 
some programing languish experience and I told him that I only have a 
little bit of Phyton experience, but not much. And know I'm getting this 
hard assignment and just falling more and more behind... :/

But I will get that book from Peter Ashenden you recommended and reed it 
PittyJ :)

I will try to change the names to my signals and my entity name, thanks 
williwilliwallawalla :)

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.