152 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			VHDL
		
	
	
	
	
	
			
		
		
	
	
			152 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			VHDL
		
	
	
	
	
	
| --===========================================================================--
 | |
| --  Design units : CoCa.serialPortReceiver.rtl
 | |
| --
 | |
| --  File name : serialPortReceiver_rtl.vhd
 | |
| --
 | |
| --  Purpose : Decode data from UART into words
 | |
| --
 | |
| --  Input : serial line data
 | |
| --
 | |
| --  Output : 
 | |
| --      dataOut : word of data
 | |
| --      dataValid : active when a new word of data is available
 | |
| --
 | |
| --
 | |
| --  Limitations : 
 | |
| --  
 | |
| --  
 | |
| --
 | |
| --  Errors: : None known
 | |
| --
 | |
| --  Library : Common
 | |
| --
 | |
| --  Dependencies : None
 | |
| --
 | |
| --  Author : 
 | |
| --  Haute école d'ingénierie (HEI/HES-SO)
 | |
| --  Institut systèmes industriels (ISI)
 | |
| --  Rue de l'industrie 23
 | |
| --  1950 Sion
 | |
| --  Switzerland (CH)
 | |
| --
 | |
| --  Simulator : Mentor ModelSim V10.7c
 | |
| ------------------------------------------------
 | |
| --  Revision list
 | |
| --  Version Author Date Changes
 | |
| --
 | |
| --  V1.0 04.04.2022 - First version
 | |
| --===========================================================================--
 | |
| 
 | |
| library Common;
 | |
|   use Common.CommonLib.all;
 | |
| 
 | |
| architecture RTL of serialPortReceiver is
 | |
| 
 | |
|   signal dividerCounter: unsigned(requiredBitNb(baudRateDivide-1)-1 downto 0);
 | |
|   signal dividerCounterReset: std_uLogic;
 | |
|   signal rxDelayed: std_uLogic;
 | |
|   signal dividerCounterSynchronize: std_uLogic;
 | |
|   signal rxSample: std_uLogic;
 | |
|   signal rxShiftReg: std_ulogic_vector(dataBitNb-1 downto 0);
 | |
|   signal rxReceiving: std_uLogic;
 | |
|   signal rxDataValid: std_uLogic;
 | |
|   signal rxCounter: unsigned(requiredBitNb(dataBitNb)-1 downto 0);
 | |
| 
 | |
| begin
 | |
| 
 | |
|   divide: process(reset, clock)
 | |
|   begin
 | |
|     if reset = '1' then
 | |
|       dividerCounter <= (others => '0');
 | |
|     elsif rising_edge(clock) then
 | |
|       if dividerCounterSynchronize = '1' then
 | |
|         dividerCounter <= to_unsigned(baudRateDivide/2, dividerCounter'length);
 | |
|       elsif dividerCounterReset = '1' then
 | |
|         dividerCounter <= (others => '0');
 | |
|       else
 | |
|         dividerCounter <= dividerCounter + 1;
 | |
|       end if;
 | |
|     end if;
 | |
|   end process divide;
 | |
| 
 | |
|   endOfCount: process(dividerCounter)
 | |
|   begin
 | |
|     if dividerCounter = baudRateDivide-1 then
 | |
|       dividerCounterReset <= '1';
 | |
|     else
 | |
|       dividerCounterReset <= '0';
 | |
|     end if;
 | |
|   end process endOfCount;
 | |
| 
 | |
|   delayRx: process(reset, clock)
 | |
|   begin
 | |
|     if reset = '1' then
 | |
|       rxDelayed <= '0';
 | |
|     elsif rising_edge(clock) then
 | |
|       rxDelayed <= RxD;
 | |
|     end if;
 | |
|   end process delayRx;
 | |
| 
 | |
|   rxSynchronize: process(RxD, rxDelayed)
 | |
|   begin
 | |
|     if RxD /= rxDelayed then
 | |
|       dividerCounterSynchronize <= '1';
 | |
|     else
 | |
|       dividerCounterSynchronize <= '0';
 | |
|     end if;
 | |
|   end process rxSynchronize;
 | |
| 
 | |
|   rxSample <= dividerCounterReset and not dividerCounterSynchronize;
 | |
| 
 | |
|   shiftReg: process(reset, clock)
 | |
|   begin
 | |
|     if reset = '1' then
 | |
|       rxShiftReg <= (others => '0');
 | |
|     elsif rising_edge(clock) then
 | |
|       if rxSample = '1' then
 | |
|         rxShiftReg(rxShiftReg'high-1 downto 0) <= rxShiftReg(rxShiftReg'high downto 1);
 | |
|         rxShiftReg(rxShiftReg'high) <= RxD;
 | |
|       end if;
 | |
|     end if;
 | |
|   end process shiftReg;
 | |
| 
 | |
|   detectReceive: process(reset, clock)
 | |
|   begin
 | |
|     if reset = '1' then
 | |
|       rxReceiving <= '0';
 | |
|       rxDataValid <= '0';
 | |
|     elsif rising_edge(clock) then
 | |
|       if rxSample = '1' then
 | |
|         if rxCounter = dataBitNb-1 then
 | |
|           rxDataValid <= '1';
 | |
|         elsif RxD = '0' then
 | |
|           rxReceiving <= '1';
 | |
|         end if;
 | |
|       elsif rxDataValid = '1' then
 | |
|         rxReceiving <= '0';
 | |
|         rxDataValid <= '0';
 | |
|       end if;
 | |
|     end if;
 | |
|   end process detectReceive;
 | |
| 
 | |
|   countRxBitNb: process(reset, clock)
 | |
|   begin
 | |
|     if reset = '1' then
 | |
|       rxCounter <= (others => '0');
 | |
|     elsif rising_edge(clock) then
 | |
|       if rxSample = '1' then
 | |
|         if rxReceiving = '1' then
 | |
|           rxCounter <= rxCounter + 1;
 | |
|         else
 | |
|           rxCounter <= (others => '0');
 | |
|         end if;
 | |
|       end if;
 | |
|     end if;
 | |
|   end process countRxBitNb;
 | |
| 
 | |
|   dataOut <= rxShiftReg;
 | |
|   dataValid <= rxDataValid;
 | |
| 
 | |
| end RTL;
 | |
| 
 |