VHDL model of a RS 232 transmitter

Discussion in 'VHDL' started by fpgawizz, Mar 24, 2005.

  1. fpgawizz

    fpgawizz Guest

    I am working on a project where I send serial data from my PC to an FPGA
    which samples it, captures it and puts it in an external memory.
    In order to test this using a test bench, I need a model for the RS 232
    transmitter - a model that mimics sending 8 bits of RS 232 data at 9600
    Hz. I got the model of the memory from the vendor.Where can I get a model
    of the RS 232 to use for my test bench?

    thanks
     
    fpgawizz, Mar 24, 2005
    #1
    1. Advertising

  2. fpgawizz

    Bert Cuzeau Guest

    If it's for educational use, you can have our UART IP for free.
    It also includes behavioral models (with cool file I/O) for RS232
    send/receive.
    Otherwise, it's very simple. I think I gave the code snippets
    in a conference.
    http://www.alse-fr.com/English/conferences.html

    Best regards,

    Bert Cuzeau


    fpgawizz wrote:

    > I am working on a project where I send serial data from my PC to an FPGA
    > which samples it, captures it and puts it in an external memory.
    > In order to test this using a test bench, I need a model for the RS 232
    > transmitter - a model that mimics sending 8 bits of RS 232 data at 9600
    > Hz. I got the model of the memory from the vendor.Where can I get a model
    > of the RS 232 to use for my test bench?
    >
    > thanks
    >
     
    Bert Cuzeau, Mar 24, 2005
    #2
    1. Advertising

  3. On Thu, 24 Mar 2005 09:52:17 -0500, "fpgawizz"
    <> wrote:

    >I am working on a project where I send serial data from my PC to an FPGA
    >which samples it, captures it and puts it in an external memory.
    >In order to test this using a test bench, I need a model for the RS 232
    >transmitter - a model that mimics sending 8 bits of RS 232 data at 9600
    >Hz. I got the model of the memory from the vendor.Where can I get a model
    >of the RS 232 to use for my test bench?



    Bert has given you a link to a synthesisable UART IP block, but for
    a test bench it is really very simple. Just write a procedure, and
    put the procedure in a package. Code below. It's left as a trivial
    exercise for the student to add parity, variable numbers of stop
    bits, and suchlike extra goodies. Make sure you know what you're
    doing about the line signal levels - I've assumed the line marks
    at '1' and spaces at '0', which is usually correct in the core
    logic, but the RS-232 line discipline uses negative voltage for
    marking and positive for spacing. The line transceiver chips
    do the necessary level shifting and inversion for you, so you
    don't normally need to worry about it in the FPGA.

    It is somewhat trickier to write a behavioural model of a
    UART receiver, but even that isn't too mind-bending.

    Enjoy writing and using behavioural models!

    Take my package here and use it as you see fit - I've
    checked that it works, but as usual on Usenet you get
    no commercial guarantee of reliability or fitness for
    purpose. The little entity/architecture at the end is
    a very quick demonstration of how to use the package.

    ------------------------------------------------------ package ---

    library IEEE;
    use IEEE.std_logic_1164.all;

    package UART_behavioural_model is

    procedure UART_tx (

    -- The signal that is to be driven by this model...
    signal tx_line: out std_logic;

    -- Inputs to control how to send one character:
    data: in std_logic_vector; -- usually 8 bits
    baud_rate:in integer -- e.g. 9600
    );

    end package UART_behavioural_model;

    --------------------------------------------------- package body ---

    package body UART_behavioural_model is

    procedure UART_tx (

    -- The signal that is to be driven by this model...
    signal tx_line: out std_logic;

    -- Inputs to control how to send one character:
    data: in std_logic_vector; -- usually 8 bits
    baud_rate:in integer -- e.g. 9600
    ) is

    constant bit_time: time := 1 sec / baud_rate;

    begin

    -- Send the start bit
    tx_line <= '0';
    wait for bit_time;

    -- Send the data bits, least significant first
    for i in data'reverse_range loop
    tx_line <= data(i);
    wait for bit_time;
    end loop;

    -- Send the stop bit
    tx_line <= '1';
    wait for bit_time;

    end; -- procedure UART_tx

    end package body UART_behavioural_model;

    ---------------------------------------------- a simple test ---

    library IEEE;
    use IEEE.std_logic_1164.all;

    -- Import our UART tester package
    use work.UART_behavioural_model.all;

    entity try_the_UART is end;

    architecture A of try_the_UART is

    -- A signal for the tester to drive, initialised to "marking"
    signal serial_line: std_logic := '1';

    begin

    Testing: process

    constant My_Baud_Rate: integer := 9600;
    -- Make a jacket procedure around UART_tx, for convenience
    procedure send (data: in std_logic_vector) is
    begin
    UART_tx(
    tx_line => serial_line,
    data => data,
    baud_rate => My_Baud_Rate
    );
    end;

    variable D: std_logic_vector(7 downto 0);

    begin

    -- Idle awhile
    wait for 1 ms;

    -- Send an 8-bit character as a test
    send("10001110");

    -- Idle some more
    wait for 1 ms;

    -- Some more characters - use a walking-ones pattern:
    for i in D'range loop
    D := (others => '0');
    D(i) := '1';
    send(D);
    end loop;

    -- And finally, just for fun, send a 10-bit character:
    send("1111100000");

    wait; -- That's All Folks
    end process;

    end;


    --
    Jonathan Bromley, Consultant

    DOULOS - Developing Design Know-how
    VHDL, Verilog, SystemC, Perl, Tcl/Tk, Verification, Project Services

    Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, BH24 1AW, UK
    Tel: +44 (0)1425 471223 mail:
    Fax: +44 (0)1425 471573 Web: http://www.doulos.com

    The contents of this message may contain personal views which
    are not the views of Doulos Ltd., unless specifically stated.
     
    Jonathan Bromley, Mar 24, 2005
    #3
  4. fpgawizz

    info_ Guest

    VHDL behavioral model of a RS 232 receiver

    The behavioral receiver (and transmitter) were on the conference page 16
    even with a few comments in that smell croissant and baguette... ;-)

    Our UART IP also includes behavioral models, as well as a console model which reads &
    writes data from/to text files and interprets special commands including a "pause".
    This helps emulate the behavior of a console.

    Here comes the receiver. You can strip the parity if you don't need it,
    and remove the debug printing after everything works.
    And the variable for the received word still smells baguette.

    I think some call this code a no-brainer ?


    -- -----------------------------
    -- Serial Receive (behavioral)
    -- -----------------------------
    process
    variable L : line;
    variable MOT : std_logic_vector (7 downto 0);
    variable ParityBit : std_logic;
    begin
    -- nothing to initialize
    loop
    ParityBit := '0';

    wait until TX = '0'; -- get falling edge

    wait for (0.5 * BITperiod); -- move to Middle of Start bit
    assert TX = '0'
    report "Error during Start Bit ???" severity warning;

    wait for BITperiod; -- move to First Data Bit
    for i in 0 to 7 loop -- Get word in a loop
    MOT(i) := TX;
    ParityBit := ParityBit xor TX;
    wait for BITperiod;
    end loop;

    if Parity then
    if not Even then
    ParityBit := not ParityBit;
    end if;
    if ParityBit /= TX then
    report "Error during Parity Bit" severity warning;
    end if;
    wait for BITperiod;
    end if;

    wait for BITperiod; -- Stop bit
    assert TX = '1'
    report "Error during Stop bit ???" severity warning;

    -- debug printing
    write (L,string'("Character received (hex) = "));
    hwrite (L,MOT); -- trace
    write (L,string'(" - '" & character'val(to_integer(unsigned(MOT))) & "'" ));
    writeline (output,L); -- write to simulation transcript
    end loop;
    end process;
     
    info_, Mar 26, 2005
    #4
  5. Re: VHDL behavioral model of a RS 232 receiver

    On Sat, 26 Mar 2005 17:20:26 +0100, "info_"
    <"info_"@\\nospam_no_underscore_alse-fr.com> wrote:

    >
    >The behavioral receiver (and transmitter) were on the conference page 16
    >even with a few comments in that smell croissant and baguette... ;-)


    Sorry Bert. I missed them there, until I took a closer look some
    time later.

    Anyhow, it's nice to see that we agree about how to do it - and
    it's very important that you should know that there is a truly
    excellent patisserie only 400m from my home, where the French
    proprietor makes viennoiserie as good as all but the very
    best in France :)
    --
    Jonathan Bromley

    --
    Jonathan Bromley
     
    Jonathan Bromley, Mar 28, 2005
    #5
  6. fpgawizz

    info_ Guest

    Re: VHDL behavioral model of a RS 232 receiver

    Sweet tooth ?

    > where the French proprietor makes viennoiserie as good as all
    > but the very best in France


    I knew the Eurostar would spoil you ;-)
     
    info_, Mar 28, 2005
    #6
  7. fpgawizz

    fpgawizz Guest

    Jonathan
    I tried using the package procedure as you advised. I had some
    problems..firstly the tool complains that i cannot have "Wait for" state
    ments in a package. How do i fix this?
    thanks
     
    fpgawizz, Apr 2, 2005
    #7
  8. On Sat, 02 Apr 2005 14:51:54 -0500, "fpgawizz"
    <> wrote:

    >Jonathan
    >I tried using the package procedure as you advised. I had some
    >problems..firstly the tool complains that i cannot have "Wait for" state
    >ments in a package. How do i fix this?


    (1) If, as I suspect, you are trying to put my code through a
    synthesis tool such as XST, then DON'T. It's for simulation only.

    (2) If it's a simulator giving the error, throw it away and
    get one that works.

    --
    Jonathan Bromley
     
    Jonathan Bromley, Apr 2, 2005
    #8
  9. fpgawizz

    fpgawizz Guest

    Jonathan:
    I used ur procedure..I have an entity with input ports "Din" ( serial in)
    and a clock that i generate. I am generating a 6 us clock which is approx.
    16 times faster than 9600 Hz. And i am connecting the serial_line signal
    to my Din input as i need my serial data on that line.But all my signals
    except the serial_line signal are undefined "UUUUUUUU".
    Any idea why even my clock signal is not coming through?

    thanks


    my testbench code is as follows.

    LIBRARY ieee,toplevelib;
    USE ieee.std_logic_1164.ALL;
    USE ieee.numeric_std.ALL;
    use toplevelib.uart_model.all;

    ENTITY datacomm_tb1_vhd_tb IS
    END datacomm_tb1_vhd_tb;

    ARCHITECTURE behavior OF datacomm_tb1_vhd_tb IS

    COMPONENT datacomm
    PORT(
    clk : IN std_logic;
    Din : IN std_logic;
    DATABUS : INOUT std_logic_vector(7 downto 0);
    LD : OUT std_logic_vector(7 downto 0);
    SRAMADDRUpper : OUT std_logic_vector(9 downto 0);
    SRAMADDR : OUT std_logic_vector(7 downto 0);
    OE : OUT std_logic;
    WE : OUT std_logic;
    LB : OUT std_logic;
    UB : OUT std_logic;
    CE1 : OUT std_logic;
    CE2 : OUT std_logic;
    data_out : OUT std_logic_vector(7 downto 0);
    AN : OUT std_logic_vector(3 downto 0);
    Seven_seg : OUT std_logic_vector(6 downto 0)
    );
    END COMPONENT;

    SIGNAL clk : std_logic;
    SIGNAL Din : std_logic;
    SIGNAL LD : std_logic_vector(7 downto 0);
    SIGNAL SRAMADDRUpper : std_logic_vector(9 downto 0);
    SIGNAL SRAMADDR : std_logic_vector(7 downto 0);
    SIGNAL DATABUS : std_logic_vector(7 downto 0);
    SIGNAL OE : std_logic;
    SIGNAL WE : std_logic;
    SIGNAL LB : std_logic;
    SIGNAL UB : std_logic;
    SIGNAL CE1 : std_logic;
    SIGNAL CE2 : std_logic;
    SIGNAL data_out : std_logic_vector(7 downto 0);
    SIGNAL AN : std_logic_vector(3 downto 0);
    SIGNAL Seven_seg : std_logic_vector(6 downto 0);

    -- A signal for the tester to drive, initialised to "marking"
    signal serial_line: std_logic := '1';
    BEGIN

    uut: datacomm PORT MAP(
    clk => clk,
    Din => serial_line,
    LD => LD,
    SRAMADDRUpper => SRAMADDRUpper,
    SRAMADDR => SRAMADDR,
    DATABUS => DATABUS,
    OE => OE,
    WE => WE,
    LB => LB,
    UB => UB,
    CE1 => CE1,
    CE2 => CE2,
    data_out => data_out,
    AN => AN,
    Seven_seg => Seven_seg
    );


    -- *** Test Bench - User Defined Section ***

    clk <= not clk after 6 us;

    tb : PROCESS
    constant My_Baud_Rate: integer := 9600;

    -- Make a jacket procedure around UART_tx, for convenience
    procedure send (data: in std_logic_vector) is
    begin
    UART_tx(
    tx_line => serial_line,
    data => data,
    baud_rate => My_Baud_Rate
    );
    end;

    variable D: std_logic_vector(7 downto 0);
    BEGIN

    -- Idle awhile
    wait for 1 ms;

    -- Send an 8-bit character as a test
    send("10001110");

    -- Idle some more
    wait for 1 ms;

    wait; -- will wait forever
    END PROCESS;
    -- *** End Test Bench - User Defined Section ***

    END;
     
    fpgawizz, Apr 3, 2005
    #9
  10. fpgawizz

    fpgawizz Guest

    Jonathan:
    I used ur procedure..I have an entity with input ports "Din" ( serial in)
    and a clock that i generate. I am generating a 6 us clock which is approx.
    16 times faster than 9600 Hz. And i am connecting the serial_line signal
    to my Din input as i need my serial data on that line.But all my signals
    except the serial_line signal are undefined "UUUUUUUU".
    Any idea why even my clock signal is not coming through?

    thanks


    my testbench code is as follows.

    LIBRARY ieee,toplevelib;
    USE ieee.std_logic_1164.ALL;
    USE ieee.numeric_std.ALL;
    use toplevelib.uart_model.all;

    ENTITY datacomm_tb1_vhd_tb IS
    END datacomm_tb1_vhd_tb;

    ARCHITECTURE behavior OF datacomm_tb1_vhd_tb IS

    COMPONENT datacomm
    PORT(
    clk : IN std_logic;
    Din : IN std_logic;
    DATABUS : INOUT std_logic_vector(7 downto 0);
    LD : OUT std_logic_vector(7 downto 0);
    SRAMADDRUpper : OUT std_logic_vector(9 downto 0);
    SRAMADDR : OUT std_logic_vector(7 downto 0);
    OE : OUT std_logic;
    WE : OUT std_logic;
    LB : OUT std_logic;
    UB : OUT std_logic;
    CE1 : OUT std_logic;
    CE2 : OUT std_logic;
    data_out : OUT std_logic_vector(7 downto 0);
    AN : OUT std_logic_vector(3 downto 0);
    Seven_seg : OUT std_logic_vector(6 downto 0)
    );
    END COMPONENT;

    SIGNAL clk : std_logic;
    SIGNAL Din : std_logic;
    SIGNAL LD : std_logic_vector(7 downto 0);
    SIGNAL SRAMADDRUpper : std_logic_vector(9 downto 0);
    SIGNAL SRAMADDR : std_logic_vector(7 downto 0);
    SIGNAL DATABUS : std_logic_vector(7 downto 0);
    SIGNAL OE : std_logic;
    SIGNAL WE : std_logic;
    SIGNAL LB : std_logic;
    SIGNAL UB : std_logic;
    SIGNAL CE1 : std_logic;
    SIGNAL CE2 : std_logic;
    SIGNAL data_out : std_logic_vector(7 downto 0);
    SIGNAL AN : std_logic_vector(3 downto 0);
    SIGNAL Seven_seg : std_logic_vector(6 downto 0);

    -- A signal for the tester to drive, initialised to "marking"
    signal serial_line: std_logic := '1';
    BEGIN

    uut: datacomm PORT MAP(
    clk => clk,
    Din => serial_line,
    LD => LD,
    SRAMADDRUpper => SRAMADDRUpper,
    SRAMADDR => SRAMADDR,
    DATABUS => DATABUS,
    OE => OE,
    WE => WE,
    LB => LB,
    UB => UB,
    CE1 => CE1,
    CE2 => CE2,
    data_out => data_out,
    AN => AN,
    Seven_seg => Seven_seg
    );


    -- *** Test Bench - User Defined Section ***

    clk <= not clk after 6 us;

    tb : PROCESS
    constant My_Baud_Rate: integer := 9600;

    -- Make a jacket procedure around UART_tx, for convenience
    procedure send (data: in std_logic_vector) is
    begin
    UART_tx(
    tx_line => serial_line,
    data => data,
    baud_rate => My_Baud_Rate
    );
    end;

    variable D: std_logic_vector(7 downto 0);
    BEGIN

    -- Idle awhile
    wait for 1 ms;

    -- Send an 8-bit character as a test
    send("10001110");

    -- Idle some more
    wait for 1 ms;

    wait; -- will wait forever
    END PROCESS;
    -- *** End Test Bench - User Defined Section ***

    END;
     
    fpgawizz, Apr 3, 2005
    #10
  11. fpgawizz

    info_ Guest

    initialize your clock signal one way or another !

    signal clk : std_logic := '0';
    should improve your simulation.

    BTW : you can use constants :
    const BitPeriod : time := 1 sec / 9600;
    will do the math for you, accurately (at your current simulator's resolution).

    And I still don't think it's agood idea to have your clock domain set
    to 16x the baudrate... but it's a design issue.


    Bert Cuzeau



    fpgawizz wrote:
    > Jonathan:
    > I used ur procedure..I have an entity with input ports "Din" ( serial in)
    > and a clock that i generate. I am generating a 6 us clock which is approx.
    > 16 times faster than 9600 Hz. And i am connecting the serial_line signal
    > to my Din input as i need my serial data on that line.But all my signals
    > except the serial_line signal are undefined "UUUUUUUU".
    > Any idea why even my clock signal is not coming through?
    >
     
    info_, Apr 3, 2005
    #11
  12. fpgawizz

    fpgawizz Guest

    Bert
    Why is having a 16X clock not a good idea? What would you have the clock
    rate set to if you were designing it? Just trying to learn some thing
    here..your thoughts would be appreciated.
     
    fpgawizz, Apr 3, 2005
    #12
  13. fpgawizz

    fpgawizz Guest

    Bert
    Why is having a 16X clock not a good idea? What would you have the clock
    rate set to if you were designing it? Just trying to learn some thing
    here..your thoughts would be appreciated.
     
    fpgawizz, Apr 3, 2005
    #13
  14. fpgawizz

    info_ Guest

    fpgawizz wrote:

    > Bert
    > Why is having a 16X clock not a good idea? What would you have the clock
    > rate set to if you were designing it? Just trying to learn some thing
    > here..your thoughts would be appreciated.
    >



    My guess is that you didn't get this idea of 16x clock by yourself : you were
    influenced by what has been done by others with different constraints or agenda.
    But that's my opinion, you're free not to share it.

    The other more concrete reasons I don't like that are :
    - this scheme wont work well if you want to do 921k bauds transmission with
    a 25 MHz (or any other "standard" value) oscillator.
    (A user of our UART IP used it at this baud rate wihtout any problem.)
    - You would need a special frequency oscillator or sacrify a PLL for this.
    - Your description tends to make me believe you will end up with
    several clock domains ! A uart is not a good enough reason to go
    into the problems you will very likely meet if you're not
    used to edaling with clock domains crossings.

    The "good" clock, to me, is your board's oscilator one and only clock
    unless you have reasons to do otherwise (SDram controller, camera
    or video interface, etc... are usually valid reasons for extra clock domains)

    Bert Cuzeau
     
    info_, Apr 4, 2005
    #14
  15. fpgawizz

    lenux56

    Joined:
    Jun 3, 2010
    Messages:
    1
    help me please

    hello,
    Please help me!!!!!!!!!!
    Could you help me. I am a student, write a diploma "Simulation and Design of microcontroller based on the processor dp 32" and for the protection I need a code Ewart (full + test) to work with the PC processor 232.
    Do you have desired me to code? It is very important and very urgent)))
    Thank
    Lena
     
    lenux56, Jun 3, 2010
    #15
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Patrick
    Replies:
    1
    Views:
    1,226
    Jerzy
    Nov 30, 2004
  2. BALAS009
    Replies:
    0
    Views:
    618
    BALAS009
    Oct 9, 2006
  3. Andrew
    Replies:
    2
    Views:
    810
    Andrew
    Dec 31, 2006
  4. jasperng
    Replies:
    0
    Views:
    1,753
    jasperng
    Nov 2, 2008
  5. Seph
    Replies:
    6
    Views:
    2,892
    Bert_Paris
    Mar 31, 2009
Loading...

Share This Page