aboutsummaryrefslogtreecommitdiffstats
path: root/examples/ecp5_versa/uart.vhdl
diff options
context:
space:
mode:
Diffstat (limited to 'examples/ecp5_versa/uart.vhdl')
-rw-r--r--examples/ecp5_versa/uart.vhdl175
1 files changed, 175 insertions, 0 deletions
diff --git a/examples/ecp5_versa/uart.vhdl b/examples/ecp5_versa/uart.vhdl
new file mode 100644
index 0000000..c21ab49
--- /dev/null
+++ b/examples/ecp5_versa/uart.vhdl
@@ -0,0 +1,175 @@
+-- Simple UART core implementation
+--
+-- <hackfin@section5.ch>
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+library work;
+ use work.system_map.all;
+
+entity uart_core is
+ generic (
+ FIFO_DEPTH : natural := 6;
+ -- Note: Currently ineffective. See library/wrappers/bram.v
+ SYN_RAMTYPE : string := "distributed"
+ );
+ port (
+ tx : out std_logic;
+ rx : in std_logic;
+ rxirq : out std_logic;
+ ctrl : in uart_WritePort;
+ stat : out uart_ReadPort;
+ clk : in std_logic
+ );
+
+end uart_core;
+
+architecture behaviour of uart_core is
+
+ signal count16 : unsigned(4-1 downto 0) := (others => '0');
+ signal counter : unsigned(16-1 downto 0) := (others => '0');
+
+ signal strobe_rx : std_logic;
+ signal rxd : unsigned(7 downto 0);
+ signal txd : unsigned(7 downto 0);
+
+ signal rxfifo_data : unsigned(7 downto 0);
+
+ signal rxfifo_rden : std_logic;
+ signal txfifo_wren : std_logic;
+
+ signal rxdata_ready : std_logic;
+
+ signal txfifo_dready : std_logic;
+ signal txfifo_strobe : std_logic;
+
+ signal clk16_enable : std_logic;
+ signal txclk_enable : std_logic;
+
+ component FifoBuffer is
+ generic (
+ ADDR_W : natural := 6;
+ DATA_W : natural := 16;
+ EXTRA_REGISTER : boolean := false;
+ SYN_RAMTYPE : string := "block_ram"
+ );
+ port (
+ -- Write enable
+ wren : in std_logic;
+ idata : in unsigned(DATA_W-1 downto 0);
+ iready : out std_logic;
+ -- Data stream output:
+ odata : out unsigned(DATA_W-1 downto 0);
+ oready : out std_logic;
+ rden : in std_logic;
+ err : out std_logic;
+ -- debug : out unsigned(16-1 downto 0);
+ reset : in std_logic;
+ clk : in std_logic
+ );
+ end component FifoBuffer;
+
+
+begin
+
+-- Clock divider:
+clkdiv:
+ process (clk)
+ begin
+ if rising_edge(clk) then
+ clk16_enable <= '0';
+ txclk_enable <= '0';
+ -- Important to reset, otherwise, the counter might run away...
+ if ctrl.uart_reset = '1' then
+ counter <= (others => '0');
+ elsif counter = ctrl.uart_clkdiv then
+ counter <= (others => '0');
+ clk16_enable <= '1';
+ count16 <= count16 + 1;
+ if count16 = "1111" then
+ txclk_enable <= '1';
+ end if;
+ else
+ counter <= counter + 1;
+ end if;
+ end if;
+ end process;
+
+ rxfifo_rden <= ctrl.select_uart_rxr and rxdata_ready;
+ txfifo_wren <= ctrl.select_uart_txr;
+
+uart_rx: entity work.UARTrx
+ port map (
+ d_bitcount => stat.bitcount,
+ rx => rx,
+ -- Data
+ err_frame => stat.frerr,
+ data => rxd,
+ strobe => strobe_rx,
+ reset => ctrl.uart_reset,
+ clk16en => clk16_enable,
+ clk => clk
+ );
+
+uart_tx:
+ entity work.UARTtx
+ port map (
+ busy => stat.txbusy,
+ data => txd,
+ data_ready => txfifo_dready,
+ data_out_en => txfifo_strobe,
+ tx => tx,
+ reset => ctrl.uart_reset,
+ txclken => txclk_enable,
+ clk => clk
+ );
+
+
+rxfifo:
+ FifoBuffer
+ generic map (
+ DATA_W => 8,
+ ADDR_W => FIFO_DEPTH,
+ SYN_RAMTYPE => SYN_RAMTYPE
+ )
+ port map (
+ wren => strobe_rx,
+ idata => rxd,
+ iready => open,
+ odata => rxfifo_data,
+ oready => rxdata_ready,
+ rden => rxfifo_rden,
+ err => stat.rxovr,
+ reset => ctrl.uart_reset,
+ clk => clk
+ );
+
+ stat.rxdata <= rxfifo_data;
+ stat.dvalid <= rxdata_ready;
+ stat.rxready <= rxdata_ready;
+ rxirq <= rxdata_ready and ctrl.rx_irq_enable;
+
+txfifo:
+ FifoBuffer
+ generic map (
+ DATA_W => 8,
+ ADDR_W => FIFO_DEPTH,
+ SYN_RAMTYPE => SYN_RAMTYPE
+ )
+ port map (
+ wren => txfifo_wren,
+ idata => ctrl.uart_txr,
+ iready => stat.txready,
+ odata => txd,
+ oready => txfifo_dready,
+ rden => txfifo_strobe,
+ err => stat.txovr,
+ reset => ctrl.uart_reset,
+ clk => clk
+ );
+
+end behaviour;
+
+