cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Visitor
Visitor
929 Views
Registered: ‎11-27-2017

uart reception/transmission between pc and fpga problem

hi,

 

i want to write a code in vhdl about sending data from my pc to my nexys video, and then transmit it back, the data should be about 128 bits,i wrote the first code to test with just one data of 128 bits, in simulation using vivado 2017.4 it works, but when i want to test in on hardwere it doesn't, i use hercule/tera term as a terminal, here is the code and the constraint file too, i should be missing something, can anyone give me a clue please. 

 

0 Kudos
Reply
2 Replies
Scholar
Scholar
837 Views
Registered: ‎06-20-2017

I am not sure, but here are some constructive comments.

 

In general, your indentation and naming conventions are above average.   However, it is best to have a consistent naming convention.  Sometimes you use it, other times you don't.  For example, in the same file you have:

 

type t_SM_Main is (
  s_Idle, 
  s_TX_Start_Bit, 
  s_TX_Data_Bits,
  s_TX_Stop_Bit, 
  s_Cleanup
);
type state is (
  idle, 
  rec, 
  store, 
  trans
);

I liked your first method better.

 

Also, set your editor to use spaces when you hit the tab key.  Indenting with tabs will result in odd alignment when others look at your code with a different editor with different tab stops.  Converting all of your tabs to spaces will prevent that.

 

Next, when using UARTs, it is important to not mix TX and RX.  But in your design, you, or another engineer later, may get confused with your use of UART_TX being and input, and UART_RXD being an output.  UARTs drive TX and receive on RX.  I'd recommend sticking to the de facto convention, instead of yours.

 

Now, I don't think this is related to your problem, but it will eventually become a problem in your designs if you keep doing this.  In your "tx controle" process, you have used a synchronous reset, but have only used it on "etate".  In the else of the reset conditional, you assign to many other signals that will infer registers.  But they have no reset.  Based on the way synthesizers infer synchronous resets and data enables, your code tells the synthesizer to use the signal "reset" as a data enable on all of those other signals.  Specifically, you did not reset index, index1, i_TX_DV, data, or i_TX_BYTE.    What this will do is something called CE inference, and by CE, I mean data enable.  In your case, it doesn't use the CE pin of DFFs, but instead creates a CE using a LUT.

 

You can avoid future problems due to the unnecessary data enable by making sure that everything on the left hand side after the else of the reset conditional is also reset, like so:

 

-- tx controle ----------------------------------------------------
process(clk)
begin
if rising_edge(clk) then
  if reset = '1' then
    etat      <= idle;
    -- Beware CE inference
    index     <= 0;
    index1    <= 0;
    i_TX_DV   <= '0';
    data      <= (others=> (others => '0'));
    i_TX_Byte <= (others=> '0');
  else
    case etat is 
      when idle =>
        index     <= 0;
        index1    <= 0;
        i_TX_DV   <= '0';
        data      <= (others=> (others => '0'));
        i_TX_Byte <= (others=> '0');
        etat      <= rec;

Avoiding CE inference will avoid unnecessary timing paths, routing, and congestion.  Again, I don't think that is your problem, but since it seems you're learning, I thought I'd mention it.

 

Next, back to your "tx controle"  FSM.  You have defined an enumerated type for your states (good), but you have only specifically enumerated three out of the four in your case statement.  Your "when others =>" picks up the store state.  That is probably not what you intended.  If it is, a comment indicating as much will help the next person who has to look at your code.

 

Likewise, in your other state machine, you used an enumerated type for your states (good), but this time you have also fully enumerated all of the defined states in your case statement.  Consequently:

 

        -- Stay here 1 clock
        when s_Cleanup =>
          o_TX_Active <= '0';
          r_TX_Done   <= '1';
          r_SM_Main   <= s_Idle;
           
             
        when others => -- this does nothing for most synthesizers
          r_SM_Main <= s_Idle;

If you're trying to code a safe state machine with your use of "when others =>" above, you should instead take a look at UG901 (assuming you're using Vivado's synthesizer), or the user guide for the synthesizer you are using if you're using a third party synthesizer.  Some professors don't understand this, and incorrectly advise their students to use a when others with fully enumerated types to build a safe state machine.

 

If you're not trying to code a safe state machine, the above code is unreachable in simulation, and ignore in synthesis.

 

 

Lastly, how fast is your clock?  Depending on the frequency of your clock, and the baud rate of your UARTs, your code may not work.  I was unable to look at functionality due to you not providing a testbench. 

 

All in all, though, you're doing well.  Keep your chin up as you continue to troubleshoot your design.

 

0 Kudos
Reply
Moderator
Moderator
818 Views
Registered: ‎07-21-2014

@aamre3

 

As mentioned in your post that you are able to run behavioral simulation successfully, can you try to use same testbench for post-implementation timing simulation simulation and post-synthesis simulation? 

 

This way you will get to know if some logic got optimized from the design in synthesis/implementation phase.

 

Thanks

Anusheel

0 Kudos
Reply