Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
12 years ago

UART and MODELSIM ALTERA (code attached)

Hi dears.

I am trying to use a (slightly) modified version of the UART explained in a tutorial I've found, after reading some theory about.

There is one UART entity which has two components - TX and RX, which in turn, operate with 9600bps in transmition and reception of bytes.

The UART has two serial ports and two "parallel" ports for doing serial<->parallel conversion.

The simulation results (for RX) can be visualized here: http://puu.sh/6tnpq/db6251b4ec.png

My doubt: I am writing one byte 11111111 in the parallel_tx sign and I expect it to be passed to UART_RXD (not occurring in simulation).

All the right sided signals are included in the sensitive list of all process as taught me here (the original code had not).

I can't see any syntax erro on the codes (I had not noted any appointment in the comments where I took it from (Toni Axe, youtube)).

note: I see that the RX and TX codes are written just with one process, with IFs operating as states (not using switch as I usually do).

Any help will be appreciated (I created this post after 3 days trying to do it "by my self" in my DE2).

thanks.

PS: I am using 20000 ps clock period.

29 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Thank Tricky, I will try it but, as soon as I am modeling the uart through Flip-Flops,

    and using two signals to do in this way, I am thinking witch is the best practice to implement it.

    As a beginner Is it suggested to do it in the sequential logic process......or in the combinational part, outside the process?

    sequential logic process:

    entity

    ...

    port( rx: in std_logic );

    ...

    archtecture

    ...

    -- two signals representing the Next State Logic register for a byte comming in port rx.

    signal b_reg, b_next: std_logic_vector(7 downto 0);

    -- other two signals representing the other register

    signal other_b_reg, other_b_next: std_logic_vector(7 downto 0);

    ...

    process(clk, reset)

    ...

    -- next state logic for b and...

    b_reg <= b_next;

    -- ...the other register.

    other_b_next <= b_reg;

    other_b_reg <= other_b_next;

    combinational logic:

    ...

    process(clk,rst)

    ...

    end process;

    ...

    process(sensitivity list)

    ....

    end process;

    ...

    --outside the process.

    b_reg <= b_next;

    other_b_next <= b_reg;

    other_b_reg <= other_b_next;

    or even do i need another case statment in the finite state machine process just to pass the value from one signal to the other?

    It seems that we have a hot topic here (Views: >1,218).

    Thanks,
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    just register them directly:

    
    signal rd_r : std_logic_vector(1 downto 0);
    signal serial_rx_r : std_logic_vector(1 downto 0);
    process(clk)
    begin
      if rising_edge(clk) then
        serial_rx_r <= serial_rx_r(0) & serial_rx;
        rd_r <= rd_r(0) & rd;
      end if;
    end if;
    

    Then use rd_r(1) instead of the origional input "rd" and the same for serial_rx
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    just register them directly:

    
    signal rd_r : std_logic_vector(1 downto 0);
    signal serial_rx_r : std_logic_vector(1 downto 0);
    process(clk)
    begin
      if rising_edge(clk) then
        serial_rx_r <= serial_rx_r(0) & serial_rx;
        rd_r <= rd_r(0) & rd;
      end if;
    end if;
    

    Then use rd_r(1) instead of the origional input "rd" and the same for serial_rx

    --- Quote End ---

    Hi tricky, I am doing this already, for example, in the line 110 from the rx_uart.vhd:

    -- left concatenate the new bit, assuming the bits are sent LSB to MSB
                      byte_next <= rx & byte_reg(7 downto 1);

    Maybe the problem is with the FIFO megafunction?

    I am using the SCFIFO from altera. So, the input "rd" from this SCFIFO is connected with the output "rx_done_tick" from rx_uart.vhd.

    Maybe I should use the DCFIFO, which I read that it is better for deal with metastability.

    I noted too that the counter from mod_27.vhdl does not flash the leds to indicate that the counter inside is working.

    The outputs in this vhdl file are in this way:

    	-- output logic
    	q <= std_logic_vector(r_reg);
    	max_tick <= '1' when r_reg=(M-1) else '0';

    I think it should be corrected as you said. I'll try to double register these two outputs and test the counter first.

    Then I ll increment the circuitry with uart, then with the FIFO, and see if it works.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    Hi tricky, I am doing this already, for example, in the line 110 from the rx_uart.vhd:

    -- left concatenate the new bit, assuming the bits are sent LSB to MSB
                      byte_next <= rx & byte_reg(7 downto 1);

    --- Quote End ---

    THis assumes that the rx input is already synchronised which it isnt. You need the double register BEFORE this to ensure you get real values, not a meta stable one inside the byte(0) register.

    The problem will not be the DCFIFO. THat also requires synchronised inputs.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    just register them directly:

    
    signal rd_r : std_logic_vector(1 downto 0);
    signal serial_rx_r : std_logic_vector(1 downto 0);
    process(clk)
    begin
      if rising_edge(clk) then
        serial_rx_r <= serial_rx_r(0) & serial_rx;
        rd_r <= rd_r(0) & rd;
      end if;
    end if;
    

    Then use rd_r(1) instead of the origional input "rd" and the same for serial_rx

    --- Quote End ---

    I know it is a lot of questions but:

    I noted that you coded inside the reset process. I am doing this "shifting register" in another process where I've implemented the FSM.

    I have a process for clock and reset, and another process for FSM.

    Should I implement the double register in the clock/reset process? Not in the FSM process?

    This is causing to me some confusion.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Yes, it is. You have separated out all of your combinatorial logic into one process, and then registered it in another.

    Aslong as they are placed in a clocked process that uses the correct clock, then its fine.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    Yes, it is. You have separated out all of your combinatorial logic into one process, and then registered it in another.

    Aslong as they are placed in a clocked process that uses the correct clock, then its fine.

    --- Quote End ---

       
    -- register byte_reg syncronized;
    process(clk, reset)       begin
          if (reset = '1') then
             state_reg <= idle;
             baud_cnt_reg <= (others => '0');
             bits_cnt_reg <= (others => '0');
             byte_reg <= (others => '0');
          elsif (clk'event and clk='1') then
             state_reg <= state_next;
             baud_cnt_reg <= baud_cnt_next; 
             bits_cnt_reg <= bits_cnt_next; 
             byte_reg <= byte_next;
          end if;
       end process;
    ...
    -- left concatenate the new bit, assuming the bits are sent LSB to MSB
    -- other process (FSM).
     byte_next <= rx & byte_reg(7 downto 1);
    ...
    -- out of any process, combinatorial logic.
    -- Put the byte read on the output bus.
       dout <= byte_reg; 
    
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    IT WORKED! I LOVE YOU TRICKY :D \o/

    --- Quote End ---

    hi friend, i need uart_rx , uart_tx , uart_testbench ; code for modelsim

    can you send it for me as soon AS possible?

    my mail: m.aghajani0000@gmail.com

    thanks alot