aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Stirling <opensource@mikestirling.co.uk>2011-09-18 09:58:23 +0100
committerMike Stirling <opensource@mikestirling.co.uk>2011-09-18 09:58:23 +0100
commit2527a408e2de09df5c343ddcef8b2e041b294ad3 (patch)
tree615710bb6ff662dd8919b17a7c828636d1b5bbed
parentb00930e680e420ee856d1497f4319ffaf96f5eb2 (diff)
downloadfpga-bbc-2527a408e2de09df5c343ddcef8b2e041b294ad3.tar.gz
fpga-bbc-2527a408e2de09df5c343ddcef8b2e041b294ad3.tar.bz2
fpga-bbc-2527a408e2de09df5c343ddcef8b2e041b294ad3.zip
Fixed synthesis options for shared pins. Removed test UART. Updated Flash addressing to match new scheme shared with Spectrum.
-rw-r--r--simple_uart.vhd233
1 files changed, 0 insertions, 233 deletions
diff --git a/simple_uart.vhd b/simple_uart.vhd
deleted file mode 100644
index dc14416..0000000
--- a/simple_uart.vhd
+++ /dev/null
@@ -1,233 +0,0 @@
--- Simple UART for debugging. Fixed baud rate, no handshaking or parity
---
--- (C) 2011 Mike Stirling
---
-
-library IEEE;
-use IEEE.STD_LOGIC_1164.ALL;
-use IEEE.NUMERIC_STD.ALL;
-
-entity simple_uart is
-generic (
- f_clock : natural := 50000000;
- baud_rate : natural := 115200
- );
-port (
- CLOCK : in std_logic;
- nRESET : in std_logic;
-
- ENABLE : in std_logic;
- -- Read not write
- R_nW : in std_logic;
- -- Data not status (address)
- S_nD : in std_logic;
- -- Data bus in
- DI : in std_logic_vector(7 downto 0);
- -- Data bus out
- DO : out std_logic_vector(7 downto 0);
-
- -- Port pins
- RXD : in std_logic;
- TXD : out std_logic
- );
-end entity;
-
--- FIXME: RX really should have some mechanism for syncing with
--- the middle of the bit. Currently it is just pot luck!
-
-architecture rtl of simple_uart is
-constant baud_const : natural := (f_clock / baud_rate) - 1;
-subtype baud_div_t is natural range 0 to baud_const;
-subtype bitcount_t is natural range 0 to 7;
-
-type state_t is (Idle, Sync, Start, Data, Stop);
-
--- Clock enables
-signal rx_clken : std_logic;
-signal tx_clken : std_logic;
--- Baud rate divider for receive side
-signal rx_baud_div : baud_div_t;
--- Baud rate divider for transmit side
-signal tx_baud_div: baud_div_t;
--- Receive holding register
-signal rx_reg : std_logic_vector(7 downto 0);
--- Receive holding register full flag
-signal rx_ready : std_logic;
--- Receive shift register
-signal rx_sreg : std_logic_vector(7 downto 0);
--- Receive state
-signal rx_state : state_t;
--- Receive bit count
-signal rx_bitcount : bitcount_t;
--- Latched rxd for falling edge detection
-signal rxd_latch : std_logic;
--- Transmit input register
-signal tx_reg : std_logic_vector(7 downto 0);
--- Transmit input register full flag
-signal tx_busy : std_logic;
--- Transmit shift register
-signal tx_sreg : std_logic_vector(7 downto 0);
--- Transmit state
-signal tx_state : state_t;
--- Transmit bit count
-signal tx_bitcount : bitcount_t;
--- Internal (async) representation of txd
-signal txd_i : std_logic;
--- Latched enable for rising edge detection
-signal enable_latch : std_logic;
-begin
- rx_clken <= '1' when rx_baud_div = 0 else '0';
- tx_clken <= '1' when tx_baud_div = 0 else '0';
-
- txd_i <=
- '0' when tx_state = Start else
- tx_sreg(0) when tx_state = Data else
- '1';
-
- process(CLOCK,nRESET)
- begin
- if nRESET = '0' then
- TXD <= '1';
- else
- -- Register TXD to output
- TXD <= txd_i;
- end if;
- end process;
-
- process(CLOCK,nRESET)
- begin
- if nRESET = '0' then
- rx_reg <= (others => '0');
- rx_sreg <= (others => '0');
- rx_ready <= '0';
- rx_state <= Idle;
- rx_bitcount <= 0;
-
- tx_reg <= (others => '0');
- tx_sreg <= (others => '0');
- tx_busy <= '0';
- tx_state <= Idle;
- tx_bitcount <= 0;
-
- rx_baud_div <= baud_const;
- tx_baud_div <= baud_const;
- enable_latch <= '0';
- DO <= (others => '0');
- elsif rising_edge(CLOCK) then
- -- Latch enable signal for edge detection
- enable_latch <= ENABLE;
- -- Latch rxd for falling edge (start) detection)
- rxd_latch <= RXD;
-
- -- Baud rate generation. Tx and Rx are done separately so that
- -- the receive counter can be adjusted when the falling edge of a
- -- start bit is detected
- if rx_baud_div = 0 then
- -- Reload
- rx_baud_div <= baud_const;
- else
- rx_baud_div <= rx_baud_div - 1;
- end if;
- if rx_state = Idle and RXD = '0' and rxd_latch = '1' then
- -- Reset rx baud divider to mid point when a start bit occurs
- rx_baud_div <= baud_const / 2;
- end if;
- if tx_baud_div = 0 then
- -- Reload
- tx_baud_div <= baud_const;
- else
- tx_baud_div <= tx_baud_div - 1;
- end if;
-
- -- Handle bus writes - edge triggered to avoid unintentionally
- -- re-transmitting the same character
- if ENABLE = '1' and enable_latch = '0' and R_nW = '0' then
- if S_nD = '0' and tx_busy = '0' then
- -- Write to data register and tx register is empty
- tx_reg <= DI;
- tx_busy <= '1';
- end if;
- -- All other writes are discarded
- end if;
- -- Handle bus reads - edge triggered so DO is held for the
- -- duration of ENABLE, but a subsequent read with !rx_ready
- -- will return 0
- if ENABLE = '1' and enable_latch = '0' and R_nW = '1' then
- if S_nD = '0' then
- -- Receive data register read
- if rx_ready = '1' then
- DO <= rx_reg;
- rx_ready <= '0';
- else
- DO <= (others => '0');
- end if;
- else
- -- Status register read
- -- bit 0 = TX busy
- -- bit 1 = RX ready
- DO <= "000000" & rx_ready & tx_busy;
- end if;
- end if;
-
- if tx_busy = '1' and (tx_state = Idle or tx_state = Stop) then
- -- Start a new transmit cycle. TXD remains idle until
- -- the start of the next baud period, hence the additional
- -- 'Sync' state.
- tx_sreg <= tx_reg;
- tx_busy <= '0';
- tx_state <= Sync;
- tx_bitcount <= 7;
- end if;
-
- -- Transmitter
- if tx_clken = '1' and not (tx_state = Idle) then
- case tx_state is
- when Sync =>
- tx_state <= Start;
- when Start =>
- tx_state <= Data;
- when Data =>
- tx_sreg <= '0' & tx_sreg(7 downto 1);
- if tx_bitcount = 0 then
- tx_state <= Stop;
- else
- tx_bitcount <= tx_bitcount - 1;
- end if;
- when others =>
- -- Return to idle
- tx_state <= Idle;
- end case;
- end if;
-
- -- Receiver
- if rx_clken = '1' then
- case rx_state is
- when Idle =>
- if RXD = '0' then
- -- Start bit detected - next bit is data, so we
- -- skip the start state on the rx side
- rx_state <= Data;
- rx_bitcount <= 7;
- end if;
- when Data =>
- rx_sreg <= RXD & rx_sreg(7 downto 1);
- if rx_bitcount = 0 then
- rx_state <= Stop;
- else
- rx_bitcount <= rx_bitcount - 1;
- end if;
- when others =>
- -- Only latch output if stop bit matches and the
- -- rx register is empty
- if RXD = '1' and rx_ready = '0' then
- rx_reg <= rx_sreg;
- rx_ready <= '1';
- end if;
- -- Return to idle
- rx_state <= Idle;
- end case;
- end if;
- end if;
- end process;
-
-end architecture;