-- -- VHDL -- -- Entity: UAT (ha ha.. Universal Asynchronous Transmitter) -- -- Purpose: Given our 9.2416MHz/8 system clock and a BAUD clk, -- accept a byte and stream it out at the baud rate. -- Insert start and stop bits -- -- Inputs: CLK is the 9.2416MHz/8 clock which drives the process -- RESET resets the counter, forces output LO. -- START indicates input byte is present. -- BAUDCLK defines the baud rate. -- -- Outputs: SOUT is the serial output. -- DONE is HI when transmission is complete. -- library synth; use synth.stdsynth.ALL; entity UAT is port ( clk : in vlbit; baudclk : in vlbit; din : in vlbit_1d (7 downto 0); start : in vlbit; busy : out vlbit; sout : out vlbit); end UAT; architecture first of UAT is signal txregister : vlbit_1d(11 downto 0) := ('0', '0','0','0','0','0','0','0','0','0','0','0'); -- Byte to transmit signal cnt : vlbit_1d(4 downto 0) := ('0','0','0','0','0'); -- Bit Counter signal started : vlbit := '0'; -- Indicates transmission in progress signal sentbit : vlbit := '0'; -- Bit sent for this bit window begin -- *** Concurrent Assignments *** -- -- Force output to MARK level whenever we are idle, otherwise, output -- is the MSB (bit 10) of the txregister. -- sout <= txregister(11) when started = '1' else '1'; -- UAT is 'busy' whenever it is 'started' busy <= started; -- *** End Concurrent Assignments *** DoIt: process (clk) begin if (prising(clk)) then -- Use state of whether we are 'started' or not to drive operation. -- First, see if we are already in the midst of sending something. -- if started = '1' then -- turn sentbit off again once baudclk goes back low. now seeking baudclk HI if sentbit = '1' AND baudclk = '0' then sentbit <= '0'; -- if we're sending, we haven't sent bit yet, and baudclk goes HI, send bit! elsif sentbit = '0' AND baudclk = '1' then -- Check bit count to see if we are done if v1d2int(cnt) = 11 then -- All done! started <= '0'; else -- time to send next bit sentbit <= '1'; -- Shift databyte left txregister <= shiftlum(txregister, 1); -- increment the bit counter cnt <= addum (cnt(3 downto 0), "0001"); end if; end if; else -- Check START signal if start = '1' then -- Bits are reversed: ASYNC ASCII says you must transmit -- LSB first, immediately after the start bit. -- txregister(8) <= din(0); -- data bits txregister(7) <= din(1); txregister(6) <= din(2); txregister(5) <= din(3); txregister(4) <= din(4); txregister(3) <= din(5); txregister(2) <= din(6); txregister(1) <= din(7); txregister(11 downto 9) <= "110"; -- Idle bit and start bit txregister(0) <= '1'; -- Stop bit started <= '1'; sentbit <= '0'; cnt <= "00000"; end if; end if; end if; end process; end first;