![]() |
|
|
|||||||
![]() |
VHDL - Serial Port on Spartan 3 Starter Kit |
|
|
Thread Tools | Search this Thread |
|
|
#1 |
|
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( sr(9) <= sr( 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 |
|
|
|
|
#2 |
|
Posts: n/a
|
"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( > sr(9) <= sr( > 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 |
|
|
|
#3 |
|
Posts: n/a
|
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( >> sr(9) <= sr( >> 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 > > |
|
|
|
#4 |
|
Posts: n/a
|
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 |
|