0
\$\begingroup\$

I'm trying to connect my FPGA Cylone IV (CoreEP4CE6) with Raspberry Pi 3 for communication through UART. The process (uart_rx) for receiving data is working fine, however, when I place another process (uart_tx) for transmitting data both process fail. I don't know why, in simulation everything works fine. Can I connect the Raspberry pins tx and rx directly to FPGA in/out pins?

library ieee;

use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity uart is
generic(
    freq: integer := 433 -- 50000000/115200
);

port(
    rx: in std_logic;
    tx: out std_logic := '1';
    data: out std_logic_vector(7 downto 0);     
    clk: in std_logic
);
end uart;

architecture uart_arch of uart is
begin
-- uart rx process
-- receive bytes through rx port
uart_rx: process(rx, clk)
    variable start_recv: bit := '0';
    variable timeout: integer := 0;
    variable count: integer := 0;
begin
    if rising_edge(clk) then
        if rx = '0' and start_recv = '0' then
            start_recv := '1';
            count := 0;
            timeout := 0;
        elsif start_recv = '1' then
            if count >= freq then
                count := 0;
                timeout := timeout + 1;
                if timeout <= 8 then
                    data(timeout-1) <= rx;
                elsif rx = '1' then -- wait for idle
                    timeout := 0;
                    start_recv := '0';
                end if;
            end if;
            count := count + 1;
        end if;
    end if;
end process;

uart_tx: process(clk)
    variable start_send: bit := '0';
    variable timeout: integer := 0;
    variable count: integer := 0;

    constant message: string(1 to 5) := "hello";
    variable buff: std_logic_vector(7 downto 0);
    variable p: integer := 1;
begin
    if rising_edge(clk) then
        if start_send = '0' and count >= freq then
            if p > message'Length then
                p := 1;
            end if;

            tx <= '0';
            buff := std_logic_vector(
                        to_unsigned(character'pos(message(p)), 8)); 
            start_send := '1';

            count := 0;
            timeout := 0;
        elsif start_send = '1' then
            if count >= freq then
                count := 0;
                timeout := timeout + 1;
                if timeout <= 8 then
                    tx <= buff(timeout-1);
                else
                    tx <= '1'; -- put in idle
                    p := p + 1; -- next char

                    timeout := 0;
                    start_send := '0';
                end if;
            end if;
        end if;
        count := count + 1;
    end if;
end process;
end uart_arch;
\$\endgroup\$
  • 1
    \$\begingroup\$ Without even bothering to look at your code beyond noticing that it is too incomplete to see how it interacts with I/O, consider basic debugging steps - for example, first prove you can toggle an output. Then prove you can send the same character over and over automatically. Only then consider sending meaningful data. Look at the output with a scope, or failing that drop the baud rate well into the audio range and couple it into a soundcard with a small series capacitor. \$\endgroup\$ – Chris Stratton Dec 20 '18 at 19:00
  • \$\begingroup\$ @ChrisStratton that's all the code. It receives new data through port rx and send through port tx. I assign this two ports to FPGA pins 52 and 53 and connected them to raspberry pi on tx and rx ports. \$\endgroup\$ – Alpha0 Dec 20 '18 at 19:37
  • \$\begingroup\$ Not sure if it will fix your problem, but you don't need to have rx in the sensitivity list for the process since you only use it on the rising edge of clk. \$\endgroup\$ – crj11 Dec 20 '18 at 19:51
  • \$\begingroup\$ If I remove the second process (tx_uart) the rx works fine. Why i'm having this behavior? \$\endgroup\$ – Alpha0 Dec 20 '18 at 21:05
  • \$\begingroup\$ If you don't have the "generate post-PAR netlist" switch "on" in your synthesis script, turn it on, and then compile the resulting netlist and load it in your simulation. it should just be a pointer change to the library you compile the netlist in versus your RTL library. If not using scripts, you can do it in the GUI too I am sure... just be careful about compiling to the same library. Sim it, and see if it does as you expect. I recommend you output a verilog netlist if you have the right licenses, as VHDL netlists are more painful to deal with. Look in command ref for switch \$\endgroup\$ – CapnJJ Dec 20 '18 at 21:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.