1
0
SEm-Labos/Libs/RS232/hdl/serialPortTransmitter_rtl.vhd

128 lines
3.4 KiB
VHDL
Raw Permalink Normal View History

2024-02-23 13:01:05 +00:00
--===========================================================================--
-- 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;