Serial Port on Spartan 3 Starter Kit

Discussion in 'VHDL' started by dev648237923, Jul 7, 2006.

  1. dev648237923

    dev648237923 Guest

    I am hobbiest.
    I have the Spartan 3 Starter Kit. I want to try to send data to my PC via
    Serial Port.
    I tried the following but the data is sporadic -- can anyone tell what is
    wrong.

    PC: Hyperteminal 8N1 Hardware Flow Control

    VHDL:
    I try to make a 10-bit shift register an dthen just send ascii "7" (hex 37)
    over and over. I have 0 as startbit and 1 as stop bit and the ox37 in the
    middle. I have counter to change clock from 50MHz to 9600Hz

    entity shifter2 is
    port (
    clock : in std_logic;
    enabled : in std_logic; --Spartan Board SW0
    txd : out std_logic --Spartan DB9 Connector TXD
    );
    end shifter2;

    architecture Behavioral of shifter2 is

    --The 50MHz clock is too fast so I will use this counter to
    --obtain a slower counting speed. I will increment count_int
    --each time this counter reaches back around to zero

    signal ctr : std_logic_vector(24 downto 0) := "0000000000000000000000000";
    signal sr: std_logic_vector(9 downto 0) := "0000000000";
    signal srout: std_logic := '0';

    begin

    process (clock)
    begin
    if clock'event and clock='1' then
    if (enabled='1') then
    if (ctr="0000000000000000000000000") then
    sr(0) <= sr(9);
    sr(1) <= sr(0);
    sr(2) <= sr(1);
    sr(3) <= sr(2);
    sr(4) <= sr(3);
    sr(5) <= sr(4);
    sr(6) <= sr(5);
    sr(7) <= sr(6);
    sr(8) <= sr(7);
    sr(9) <= sr(8);
    srout <= sr(9);
    end if;
    ctr <= ctr + "0000000000000000000000001";
    if (ctr > "0000000000001010001011000") then --9600Hz
    ctr <= "0000000000000000000000000";
    end if;
    end if;
    if (enabled='0') then
    ctr <= "0000000000000000000000000";
    srout <= '1';
    sr <= "0111011001";
    end if;
    end if;
    end process;

    txd <= srout;

    end Behavioral;

    Thank you!
     
    dev648237923, Jul 7, 2006
    #1
    1. Advertising

  2. dev648237923

    Dave Guest

    "dev648237923" <> wrote in message
    news:...
    >I am hobbiest.
    > I have the Spartan 3 Starter Kit. I want to try to send data to my PC via
    > Serial Port.
    > I tried the following but the data is sporadic -- can anyone tell what is
    > wrong.
    >
    > PC: Hyperteminal 8N1 Hardware Flow Control
    >
    > VHDL:
    > I try to make a 10-bit shift register an dthen just send ascii "7" (hex
    > 37) over and over. I have 0 as startbit and 1 as stop bit and the ox37 in
    > the middle. I have counter to change clock from 50MHz to 9600Hz
    >
    > entity shifter2 is
    > port (
    > clock : in std_logic;
    > enabled : in std_logic; --Spartan Board SW0
    > txd : out std_logic --Spartan DB9 Connector TXD
    > );
    > end shifter2;
    >
    > architecture Behavioral of shifter2 is
    >
    > --The 50MHz clock is too fast so I will use this counter to
    > --obtain a slower counting speed. I will increment count_int
    > --each time this counter reaches back around to zero
    >
    > signal ctr : std_logic_vector(24 downto 0) := "0000000000000000000000000";
    > signal sr: std_logic_vector(9 downto 0) := "0000000000";
    > signal srout: std_logic := '0';
    >
    > begin
    >
    > process (clock)
    > begin
    > if clock'event and clock='1' then
    > if (enabled='1') then
    > if (ctr="0000000000000000000000000") then
    > sr(0) <= sr(9);
    > sr(1) <= sr(0);
    > sr(2) <= sr(1);
    > sr(3) <= sr(2);
    > sr(4) <= sr(3);
    > sr(5) <= sr(4);
    > sr(6) <= sr(5);
    > sr(7) <= sr(6);
    > sr(8) <= sr(7);
    > sr(9) <= sr(8);
    > srout <= sr(9);
    > end if;
    > ctr <= ctr + "0000000000000000000000001";
    > if (ctr > "0000000000001010001011000") then --9600Hz
    > ctr <= "0000000000000000000000000";
    > end if;
    > end if;
    > if (enabled='0') then
    > ctr <= "0000000000000000000000000";
    > srout <= '1';
    > sr <= "0111011001";
    > end if;
    > end if;
    > end process;
    >
    > txd <= srout;
    >
    > end Behavioral;
    >
    > Thank you!
    >
    >


    I don't think the Spartan 3 Starter kit supports hardware handshake
    controls. Try to set the HyperTerminal to "none" for handshake control.

    So are you not getting any results?

    Dave
     
    Dave, Jul 7, 2006
    #2
    1. Advertising

  3. dev648237923

    dev648237923 Guest

    I was able to fix the problem. I will post here what I did.
    ***I am just hobbiest so please comment if better way to do this***

    1.) I changed to Flow Control: none as you suggested below.
    2.) I added a few bits of 1's to the shift register MSBs so that each time I
    would have the TXD high for a few bits prior to sending the startbit.
    So for example for sending a 0x37 I have a 12-bit shift register
    1110111011001:
    hold hig a few(111) startbit(0) 0x7reversed(1110) 0x3reversed(1100)
    stopbit(1)

    Below causes ASSCII "7" to feed to the PCs screen:

    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.STD_LOGIC_ARITH.ALL;
    use IEEE.STD_LOGIC_UNSIGNED.ALL;

    entity shifter2 is
    port (
    clock : in std_logic;
    enabled : in std_logic; --Spartan Board SW0
    txd : out std_logic --Spartan DB9 Connector TXD
    );
    end shifter2;

    architecture Behavioral of shifter2 is

    --The 50MHz clock is too fast so I will use this counter to
    --obtain a slower counting speed. I will increment count_int
    --each time this counter reaches back around to zero

    signal ctr : std_logic_vector(24 downto 0) := "0000000000000000000000000";
    signal sr: std_logic_vector(12 downto 0) := "0000000000000";
    signal tmp: std_logic := '1';
    begin

    process (clock)
    begin
    if clock'event and clock='1' then
    if (enabled='1') then
    if (ctr="0000000000000000000000000") then
    sr(0) <= sr(12);
    sr(12 downto 1) <= sr(11 downto 0);
    tmp <= sr(12);
    end if;
    ctr <= ctr + "0000000000000000000000001";
    if (ctr > "0000000000001010001011000") then --50M/9600=5208=0x1458
    ctr <= "0000000000000000000000000";
    end if;
    end if;
    if (enabled='0') then
    ctr <= "0000000000000000000000000";
    --sr <= "1110111011001"; --0x37 "7"
    --sr <= "1110000011001"; --0x30 "0"
    sr <= "1110110100101"; --0x4B "K" --reload sr
    tmp <= '1'; --keep txd high when not enabled
    end if;
    end if;
    end process;

    txd <= tmp;

    end Behavioral;



    "Dave" <starfire151 AT cableone DOT net> wrote in message
    news:...
    >
    > "dev648237923" <> wrote in message
    > news:...
    >>I am hobbiest.
    >> I have the Spartan 3 Starter Kit. I want to try to send data to my PC via
    >> Serial Port.
    >> I tried the following but the data is sporadic -- can anyone tell what is
    >> wrong.
    >>
    >> PC: Hyperteminal 8N1 Hardware Flow Control
    >>
    >> VHDL:
    >> I try to make a 10-bit shift register an dthen just send ascii "7" (hex
    >> 37) over and over. I have 0 as startbit and 1 as stop bit and the ox37 in
    >> the middle. I have counter to change clock from 50MHz to 9600Hz
    >>
    >> entity shifter2 is
    >> port (
    >> clock : in std_logic;
    >> enabled : in std_logic; --Spartan Board SW0
    >> txd : out std_logic --Spartan DB9 Connector TXD
    >> );
    >> end shifter2;
    >>
    >> architecture Behavioral of shifter2 is
    >>
    >> --The 50MHz clock is too fast so I will use this counter to
    >> --obtain a slower counting speed. I will increment count_int
    >> --each time this counter reaches back around to zero
    >>
    >> signal ctr : std_logic_vector(24 downto 0) :=
    >> "0000000000000000000000000";
    >> signal sr: std_logic_vector(9 downto 0) := "0000000000";
    >> signal srout: std_logic := '0';
    >>
    >> begin
    >>
    >> process (clock)
    >> begin
    >> if clock'event and clock='1' then
    >> if (enabled='1') then
    >> if (ctr="0000000000000000000000000") then
    >> sr(0) <= sr(9);
    >> sr(1) <= sr(0);
    >> sr(2) <= sr(1);
    >> sr(3) <= sr(2);
    >> sr(4) <= sr(3);
    >> sr(5) <= sr(4);
    >> sr(6) <= sr(5);
    >> sr(7) <= sr(6);
    >> sr(8) <= sr(7);
    >> sr(9) <= sr(8);
    >> srout <= sr(9);
    >> end if;
    >> ctr <= ctr + "0000000000000000000000001";
    >> if (ctr > "0000000000001010001011000") then --9600Hz
    >> ctr <= "0000000000000000000000000";
    >> end if;
    >> end if;
    >> if (enabled='0') then
    >> ctr <= "0000000000000000000000000";
    >> srout <= '1';
    >> sr <= "0111011001";
    >> end if;
    >> end if;
    >> end process;
    >>
    >> txd <= srout;
    >>
    >> end Behavioral;
    >>
    >> Thank you!
    >>
    >>

    >
    > I don't think the Spartan 3 Starter kit supports hardware handshake
    > controls. Try to set the HyperTerminal to "none" for handshake control.
    >
    > So are you not getting any results?
    >
    > Dave
    >
    >
     
    dev648237923, Jul 7, 2006
    #3
  4. dev648237923

    Frank Buss Guest

    dev648237923 wrote:

    > library IEEE;
    > use IEEE.STD_LOGIC_1164.ALL;
    > use IEEE.STD_LOGIC_ARITH.ALL;
    > use IEEE.STD_LOGIC_UNSIGNED.ALL;


    This is a nice pitfall. "IEEE.STD_LOGIC_ARITH.ALL" is not standard, see
    http://ghdl.free.fr/ghdl/IEEE-library-pitfalls.html and it causes all kinds
    of trouble.

    > signal ctr : std_logic_vector(24 downto 0) := "0000000000000000000000000";


    Use "unsigned(24 downto 0)" instead of std_logic_vector. Then you can
    compare it with naturals later instead of bit-patterns.

    > sr(0) <= sr(12);
    > sr(12 downto 1) <= sr(11 downto 0);


    you could use the rol command instead like this:

    sr <= sr rol 1;

    or you could use the concatenation operator:

    sr <= sr(11 downto 0) & sr(12);

    And for calculating the baud rate devisor you could write an extra entity,
    which you could instantiate multiple times, something like this:

    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.NUMERIC_STD.ALL;

    entity clock_generator is
    generic(clock_in_speed, clock_out_speed: integer);
    port(
    clock_in: in std_logic;
    clock_out: out std_logic);
    end entity clock_generator;

    architecture rtl of clock_generator is

    function num_bits(n: natural) return natural is
    begin
    if n > 0 then
    return 1 + num_bits(n / 2);
    else
    return 1;
    end if;
    end num_bits;

    constant max_counter: natural := clock_in_speed / clock_out_speed / 2;
    constant counter_bits: natural := num_bits(max_counter);

    signal counter: unsigned(counter_bits - 1 downto 0) := (others => '0');
    signal clock_signal: std_logic;

    begin
    update_counter: process(clock_in)
    begin
    if clock_in'event and clock_in = '1' then
    if counter = max_counter then
    counter <= to_unsigned(0, counter_bits);
    clock_signal <= not clock_signal;
    else
    counter <= counter + 1;
    end if;
    end if;
    end process;

    clock_out <= clock_signal;
    end architecture rtl;


    Then you could use it like this (which sends "Spartan", one character every
    second)


    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.NUMERIC_STD.ALL;

    entity test is
    port(
    clock: in std_logic;
    txd: out std_logic);
    end entity test;

    architecture rtl of test is
    constant system_speed: natural := 50e6;

    signal baudrate_clock, second_clock, old_second_clock: std_logic;
    signal bit_counter: unsigned(3 downto 0) := x"9";
    signal shift_register: unsigned(9 downto 0) := (others => '0');
    signal char_index: natural range 0 to 7;

    begin
    baudrate_generator: entity clock_generator
    generic map(clock_in_speed => system_speed, clock_out_speed => 9600)
    port map(
    clock_in => clock,
    clock_out => baudrate_clock);

    second_generator: entity clock_generator
    generic map(clock_in_speed => system_speed, clock_out_speed => 1)
    port map(
    clock_in => clock,
    clock_out => second_clock);

    send: process(baudrate_clock)
    begin
    if baudrate_clock'event and baudrate_clock = '1' then
    txd <= '1';
    if bit_counter = 9 then
    if second_clock /= old_second_clock then
    old_second_clock <= second_clock;
    if second_clock = '1' then
    bit_counter <= x"0";
    char_index <= char_index + 1;
    case char_index is
    when 0 =>
    shift_register <= b"1" & x"53" & b"0";
    when 1 =>
    shift_register <= b"1" & x"70" & b"0";
    when 2 =>
    shift_register <= b"1" & x"61" & b"0";
    when 3 =>
    shift_register <= b"1" & x"72" & b"0";
    when 4 =>
    shift_register <= b"1" & x"74" & b"0";
    when 5 =>
    shift_register <= b"1" & x"61" & b"0";
    when 6 =>
    shift_register <= b"1" & x"6e" & b"0";
    char_index <= 0;
    when others =>
    char_index <= 0;
    end case;
    end if;
    end if;
    else
    txd <= shift_register(0);
    bit_counter <= bit_counter + 1;
    shift_register <= shift_register ror 1;
    end if;
    end if;
    end process;

    end architecture rtl;

    --
    Frank Buss,
    http://www.frank-buss.de, http://www.it4-systems.de
     
    Frank Buss, Jul 7, 2006
    #4
    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. Leon Heller

    Spartan 3 Starter Kit group formed

    Leon Heller, Jun 6, 2005, in forum: VHDL
    Replies:
    0
    Views:
    545
    Leon Heller
    Jun 6, 2005
  2. mBird
    Replies:
    3
    Views:
    6,091
    mBird
    Feb 23, 2006
  3. Javi
    Replies:
    2
    Views:
    1,460
  4. TTX
    Replies:
    0
    Views:
    1,207
  5. Peak
    Replies:
    0
    Views:
    2,667
Loading...

Share This Page