summaryrefslogtreecommitdiff
path: root/2004/n/fpga/src/portserie/uart/txmit.vhd
diff options
context:
space:
mode:
Diffstat (limited to '2004/n/fpga/src/portserie/uart/txmit.vhd')
-rw-r--r--2004/n/fpga/src/portserie/uart/txmit.vhd139
1 files changed, 139 insertions, 0 deletions
diff --git a/2004/n/fpga/src/portserie/uart/txmit.vhd b/2004/n/fpga/src/portserie/uart/txmit.vhd
new file mode 100644
index 0000000..0088729
--- /dev/null
+++ b/2004/n/fpga/src/portserie/uart/txmit.vhd
@@ -0,0 +1,139 @@
+LIBRARY ieee;
+USE ieee.std_logic_1164.ALL;
+USE ieee.std_logic_unsigned.ALL;
+
+entity TXMIT is
+ port (
+ MCLKX16 : in std_logic;
+ WRITE : in std_logic;
+ RESET : in std_logic;
+ DATA : in std_logic_vector(7 downto 0);
+
+ TX : out std_logic;
+ TXRDY : out std_logic
+ );
+end TXMIT;
+
+architecture RTL of TXMIT is
+
+ signal WRITE1 : std_logic;
+ signal WRITE2 : std_logic;
+ signal TXDONE1 : std_logic;
+ signal TXDONE : std_logic;
+ signal THR : std_logic_vector(7 downto 0);
+ signal TSR : std_logic_vector(7 downto 0);
+ signal TAG1 : std_logic;
+ signal TAG2 : std_logic;
+ constant PARITYMODE : std_logic :='1';
+ signal TXPARITY : std_logic;
+ signal TXCLK : std_logic;
+ signal PARITYCYCLE : std_logic;
+ signal TXDATARDY : std_logic;
+ signal CNT : std_logic_vector(2 downto 0);
+
+
+begin
+
+ -- Paritycycle = 1 on next to last cycle, this means when tsr[1] gets tag2.
+
+ PARITYCYCLE <= TSR(1) and not (TAG2 or TAG1 or TSR(7) or TSR(6) or TSR(5)
+ or TSR(4) or TSR(3) or TSR(2));
+
+
+ -- txdone = 1 when done shifting, this means when tx gets tag2.
+
+ TXDONE <= not (TAG2 or TAG1 or TSR(7) or TSR(6) or TSR(5) or TSR(4) or TSR(3)
+ or TSR(2) or TSR(1) or TSR(0));
+
+
+ -- Ready for new date to be written, when no data is in transmit hold register.
+
+ TXRDY <= not TXDATARDY;
+
+
+ -- Latch data[7:0] into the transmit hold register at posedge of write.
+
+ THR_WRITE : process (RESET, WRITE)
+ begin
+ if (RESET = '1') then
+ THR <= "00000000";
+ elsif (WRITE'event and WRITE = '1') then
+ THR <= DATA;
+ end if;
+ end process;
+
+
+ -- Toggle txclk every 8 counts, which divides the clock by 16, to generate the baud clock
+
+ BAUD_CLOCK_GEN : process (MCLKX16, RESET)
+ begin
+ if (RESET = '1') then
+ TXCLK <= '0';
+ CNT <= "000";
+ elsif (MCLKX16'event and MCLKX16 = '1') then
+ if (CNT = "000") then
+ TXCLK <= not TXCLK;
+ end if;
+ CNT <= CNT + 1;
+ end if;
+ end process;
+
+
+ SHIFT_OUT : process (TXCLK, RESET)
+ begin
+ -- idle_reset;
+ if (RESET = '1') then
+ TSR <= (others => '0');
+ TAG2 <= '0';
+ TAG1 <= '0';
+ TXPARITY <= PARITYMODE;
+ TX <= '1';
+ elsif (TXCLK'event and TXCLK = '1') then
+ if (TXDONE = '1' and TXDATARDY = '1') then
+ -- load_data;
+ TSR <= THR;
+ TAG2 <= '1';
+ TAG1 <= '1';
+ TXPARITY <= PARITYMODE;
+ TX <= '0';
+ else
+ -- shift_data;
+ TSR <= '0'&tsr(7 downto 1);
+ TSR(7) <= TAG1;
+ TAG1 <= TAG2;
+ TAG2 <= '0';
+ TXPARITY <= TXPARITY xor TSR(0);
+
+ if (TXDONE = '1') then
+ TX <= '1';
+ elsif (PARITYCYCLE = '1') then
+ TX <= TXPARITY;
+ else
+ TX <= TSR(0);
+ end if;
+ end if;
+ end if;
+ end process;
+
+
+ process (MCLKX16, RESET)
+ begin
+ if (RESET = '1') then
+ TXDATARDY <= '0';
+ WRITE2 <= '1';
+ WRITE1 <= '1';
+ TXDONE1 <= '1';
+ elsif (MCLKX16'event and MCLKX16 = '1') then
+ if (WRITE1 = '1' and WRITE2 = '0') then
+ TXDATARDY <= '1';
+ elsif (TXDONE = '0' and TXDONE1 = '1') then
+ TXDATARDY <= '0';
+ end if;
+ WRITE2 <= WRITE1;
+ WRITE1 <= WRITE;
+ TXDONE1 <= TXDONE;
+ end if;
+ end process;
+
+end RTL;
+