Serial Port on Spartan 3 Starter Kit

D

dev648237923

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!
 
D

Dave

dev648237923 said:
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
 
D

dev648237923

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;
 
F

Frank Buss

dev648237923 said:
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;
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top