Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

(VHDL) - can anyone please figure out where i am going wrong ?

Status
Not open for further replies.

startingvhdl

Newbie level 2
Joined
Apr 8, 2012
Messages
2
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,307
Hello everyone, this is my first post in this forum and i am a very beginner in VHDL, i have been working on a VHDL Serial receiver/transmitter assignment and i have been working on it for the past 1 week using help from different internet resources.

1. part 1 of my work was to send alphabets using hyper terminal to the ALTERA FGPA and it gets transmitted back to the Hyper terminal, this part is working fine in my code.

2. part 2 of my work includes that if i press a letter on the keyboard for example letter "z" , its ascii (in binary form obviously ) gets stored and using the case statement gets matched and binary of letter "M" is transmitter back to the PC - this is written in the transmitter process of my work.

part 1 is working perfectly fine but i have been trying for the past may days, cannot figure out where i am going wrong for the part 2 in the transmitter section of my code ( translating/decoding part)

Request: Pls dont criticize me, i am a beginner nor provide me links to opencores etc, i have been through almost everything i could find on this topic.


if you can help, i would be grateful. thanks.

Code:
library ieee;
use ieee.std_logic_1164.all;

entity uart22 is 
	generic
	(
		NUM_STAGES : natural := 8
	);
  
	port
	(
		UART_RXD  				: in std_logic; -- to receive bits in a serial 1 by 1 pattern from PC
		UART_TXD  				: out std_logic; -- to send bits in a serial 1 by 1 pattern to the PC
		LEDR  	            : out std_logic_vector(9 downto 0); -- to test the captured 10 bits through LED activity
		CLOCK_50  				: in std_logic -- clock input 50MHZ rising edge used to count to 162
	);
end entity;

architecture rtl of uart22 is
	--shift register array
	type sr_len is array ((NUM_STAGES-1) downto 0) of std_logic;
	--Declare the shift register signal
	signal shift_register: sr_len; -- signal shift_register is a array of type sr_len of 8 BITS length 
	signal LEDR_signal: std_logic_vector(9 downto 0);
	
	-- For use into the transmitter part, matching binary ascii
	signal temp2: std_logic_vector(9 downto 0);

	
	
begin
	RECEIVER : process (CLOCK_50)
	variable CLOCK_50_count : integer :=0;	
	variable bit_count : integer :=0;		 
	variable start : integer :=0;			 
	variable clear : integer :=0;	
	variable start_flag : integer :=0;
	begin
		if (rising_edge(CLOCK_50)) then
			--counting starts when receive line goes low (start bit).
			if (UART_RXD= '0') then
				--start_flag is used to start counting clock pulse
				start_flag:=1;
			end if;
			if (start_flag = 1) then
				--since start_flag is set, CLOCK_50_count continues counting
				--it will continue until start_flag is set to 0
				CLOCK_50_count:= CLOCK_50_count+1;
			end if;
			if(CLOCK_50_count = 162) then -- 162 for 19200 baud[change the count for different baud]
				--means time to sample 19200 serial data
				--at 162 times 50MHz clock cycle from the start of the start bit
				--the time is correct to sample at middle point of the received pulse
				if(bit_count < 10) then
					--the received data in 10 bit with start and stop bit
					--so only take first 10 samples from once the start_flag is set
					LEDR_signal(bit_count) <= UART_RXD;
					--after sampling bit_count is incremented
					bit_count:=bit_count+1;
				elsif(bit_count = 10) then
					--coupling data to output onall the 10 bits are captured
				    LEDR <= LEDR_signal;
					 temp2 <= LEDR_signal; -- CAPTURE THE 10 BITS IN THIS TEMP SIGNAL !!!!
					--once the 10 bits are captured, the start_flag is reset
					start_flag:=0;
					--bit_count is reset to 0
					bit_count:=0;
					--reseting CLOCK_50_count
					CLOCK_50_count:=0;
				end if;
				
			elsif(CLOCK_50_count = 162) then --162 for 19200 baud[change the count for different baud(2)]
				--162 clock pulse at 50MHz is the time for single serial pulse
				--the CLOCK_50_count is reset to start for the next serial pulse
				CLOCK_50_count:=0;
			end if;
	
				-- Shift data to the previous stage
				shift_register((NUM_STAGES-1) downto 1) <= shift_register((NUM_STAGES-2) downto 0);
				-- first stage of shift register will be the new data received
				shift_register(0) <= UART_RXD;
				-- output data from the final stage
--------------------------------------------------------------------------------------
		-- to be used in the transmitter process 
	--		UART_TXD <= shift_register(NUM_STAGES-1);
	--		end if;
		end if;
    end process;

	
TRANSMITTER : process (clock_50)
		--variables are declared in this space
		variable counter: integer:=0;
		variable i: integer :=0;
		variable temp: std_logic_vector(9 downto 0):="0000000000";
		variable x1: std_logic_vector(9 downto 0):= "0010011011"; -- binary of letter "M" is stored here along with start and stop bit
		
	begin
	
		temp := temp2; -- store the captured 10Bits from the receiver part to the temp variable 
		
if (rising_edge(CLOCK_50)) then
		counter:= counter+1;

		case temp is				-- to test is transmitter works on a trial basis as a DECODER
			when "0011110101" => -- these 10 bits check if small letter "z" is pressed on the keyboard, 
										-- if the condition is true, transmit letter "M", stored in variable X1 to the TXD 
				if(counter = 162) then
					if(i < 10) then
						UART_TXD <= x1(i);
						i:= i+1;
						counter:=0;
		end if;
	end if;
	
			when others => -- if there is some other binary stored in temp variable, transmit that to the PC (no changes)
				--if(counter = 162) then
					--if( i < 10 ) then
				UART_TXD <= shift_register(NUM_STAGES-1);
						--UART_TXD <= temp(i);
						--i:= i+1;
						--counter:=0;
					--end if;
				--end if;
		end case;
end if;
i:=0;
counter:=0;
end process;
end rtl;
 

some issues are apparent:
1.) rs232 is lsb first, so "z" will come up as 0 0101 1110 1.
2.) you appear to transmit "M" lsb first (correct), but the start/stop bits are swapped (incorrect). eg, x1(0) = '1' and x1(9) = '0'. Thus the framing will be incorrect. the receiver may see 11001001 as the data byte, which would be an extended ascii character. If a string of data is transmitted, it will be garbled due to the loss of sync.

also, 50E6/19200 is much greater than 162.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top