128 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			VHDL
		
	
	
	
	
	
			
		
		
	
	
			128 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			VHDL
		
	
	
	
	
	
| --===========================================================================--
 | |
| --  Design units : CoCa.serialPortTransmitter.rtl
 | |
| --
 | |
| --  File name : serialPortTransmitter.vhd
 | |
| --
 | |
| --  Purpose : Transmit a 8 bit data word over a serial line
 | |
| --            add start and stop bits
 | |
| --
 | |
| --  Parameters : dataBitNb : number of data bits
 | |
| --               stopBitNb : number of stop bits
 | |
| --
 | |
| --  
 | |
| --
 | |
| --  Errors: : None known
 | |
| --
 | |
| --  Library : Common
 | |
| --
 | |
| --  Dependencies : None
 | |
| --
 | |
| --  Author : 
 | |
| --  Haute ecole d'ingenierie (HEI/HES-SO)
 | |
| --  Institut systemes 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 serialPortTransmitter is
 | |
| 
 | |
|   signal dividerCounter: unsigned(requiredBitNb(baudRateDivide)-1 downto 0);
 | |
|   signal dividerCounterReset: std_uLogic;
 | |
|   signal txData: unsigned(dataBitNb-1 downto 0);
 | |
|   signal send1: std_uLogic;
 | |
|   signal txShiftEnable: std_uLogic;
 | |
|   signal txShiftReg: unsigned(dataBitNb+stopBitNb downto 0);
 | |
|   signal txSendingByte: std_uLogic;
 | |
|   signal txSendingByteAndStop: std_uLogic;
 | |
| 
 | |
| begin
 | |
| 
 | |
|   divide: process(reset, clock)
 | |
|   begin
 | |
|     if reset = '1' then
 | |
|       dividerCounter <= (others => '0');
 | |
|     elsif rising_edge(clock) then
 | |
|       if dividerCounterReset = '1' then
 | |
|         dividerCounter <= to_unsigned(1, dividerCounter'length);
 | |
|       else
 | |
|         dividerCounter <= dividerCounter + 1;
 | |
|       end if;
 | |
|     end if;
 | |
|   end process divide;
 | |
| 
 | |
|   endOfCount: process(dividerCounter, send1)
 | |
|   begin
 | |
|     if dividerCounter = baudRateDivide then
 | |
|       dividerCounterReset <= '1';
 | |
|     elsif send1 = '1' then
 | |
|       dividerCounterReset <= '1';
 | |
|     else
 | |
|       dividerCounterReset <= '0';
 | |
|     end if;
 | |
|   end process endOfCount;
 | |
| 
 | |
|   txShiftEnable <= dividerCounterReset;
 | |
| 
 | |
|   storeData: process(reset, clock)
 | |
|   begin
 | |
|     if reset = '1' then
 | |
|       txData <= (others => '1');
 | |
|     elsif rising_edge(clock) then
 | |
|       if send = '1' then
 | |
|         txData <= unsigned(dataIn);
 | |
|       end if;
 | |
|     end if;
 | |
|   end process storeData;
 | |
| 
 | |
|   delaySend: process(reset, clock)
 | |
|   begin
 | |
|     if reset = '1' then
 | |
|       send1 <= '0';
 | |
|     elsif rising_edge(clock) then
 | |
|       send1 <= send;
 | |
|     end if;
 | |
|   end process delaySend;
 | |
| 
 | |
|   shiftReg: process(reset, clock)
 | |
|   begin
 | |
|     if reset = '1' then
 | |
|       txShiftReg <= (others => '1');
 | |
|     elsif rising_edge(clock) then
 | |
|       if txShiftEnable = '1' then
 | |
|         if send1 = '1' then
 | |
|           txShiftReg <= (others => '1');                 -- stop bits
 | |
|           txShiftReg(0) <= '0';                          -- start bit
 | |
|           txShiftReg(txData'high+1 downto 1) <= txData;  -- data
 | |
|           txShiftReg(txShiftReg'high) <= '0';            -- end flag
 | |
|         else
 | |
|           txShiftReg <= shift_right(txShiftReg, 1);
 | |
|           txShiftReg(txShiftReg'high) <= '1';
 | |
|         end if;
 | |
|       end if;
 | |
|     end if;
 | |
|   end process shiftReg;
 | |
| 
 | |
|   txSendingByte <= '1' when
 | |
|     (txShiftReg(txShiftReg'high downto 1) /= (txShiftReg'high downto 1 => '1'))
 | |
|     else '0';
 | |
| 
 | |
|   txSendingByteAndStop <= '1' when
 | |
|     txShiftReg /= (txShiftReg'high downto 0 => '1')
 | |
|     else '0';
 | |
| 
 | |
|   TxD <= txShiftReg(0) when txSendingByte = '1' else '1';
 | |
|   busy <= txSendingByteAndStop or send1 or send;
 | |
| 
 | |
| end RTL;
 |