summaryrefslogtreecommitdiff
path: root/testsuite/gna/bug019/PoC/src/io
diff options
context:
space:
mode:
authorTristan Gingold2015-09-10 20:24:33 +0200
committerTristan Gingold2015-09-10 20:24:33 +0200
commita67ae38eeedd5d0ca5a75b8174aed201e5c801ad (patch)
tree9e24b723ab5c8d0d46041433bb3154ffed4527b4 /testsuite/gna/bug019/PoC/src/io
parent0e257fe7341a44f097ea282c0cbabda42f4ecc41 (diff)
downloadghdl-a67ae38eeedd5d0ca5a75b8174aed201e5c801ad.tar.gz
ghdl-a67ae38eeedd5d0ca5a75b8174aed201e5c801ad.tar.bz2
ghdl-a67ae38eeedd5d0ca5a75b8174aed201e5c801ad.zip
Add bug019 testcase.
Diffstat (limited to 'testsuite/gna/bug019/PoC/src/io')
-rw-r--r--testsuite/gna/bug019/PoC/src/io/uart/uart.pkg.vhdl155
-rw-r--r--testsuite/gna/bug019/PoC/src/io/uart/uart_bclk.vhdl108
-rw-r--r--testsuite/gna/bug019/PoC/src/io/uart/uart_fifo.vhdl320
-rw-r--r--testsuite/gna/bug019/PoC/src/io/uart/uart_rx.vhdl174
-rw-r--r--testsuite/gna/bug019/PoC/src/io/uart/uart_tx.vhdl140
5 files changed, 897 insertions, 0 deletions
diff --git a/testsuite/gna/bug019/PoC/src/io/uart/uart.pkg.vhdl b/testsuite/gna/bug019/PoC/src/io/uart/uart.pkg.vhdl
new file mode 100644
index 0000000..b5c3e9d
--- /dev/null
+++ b/testsuite/gna/bug019/PoC/src/io/uart/uart.pkg.vhdl
@@ -0,0 +1,155 @@
+-- EMACS settings: -*- tab-width: 2; indent-tabs-mode: t -*-
+-- vim: tabstop=2:shiftwidth=2:noexpandtab
+-- kate: tab-width 2; replace-tabs off; indent-width 2;
+--
+-- ============================================================================
+-- Authors: Martin Zabel
+-- Patrick Lehmann
+--
+-- Package: Component declarations for PoC.io.uart
+--
+-- Description:
+-- ------------------------------------
+-- TODO
+--
+-- License:
+-- ============================================================================
+-- Copyright 2008-2015 Technische Universitaet Dresden - Germany
+-- Chair for VLSI-Design, Diagnostics and Architecture
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+-- ============================================================================
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.numeric_std.all;
+
+library PoC;
+use PoC.utils.all;
+use PoC.physical.all;
+
+
+package uart is
+ type T_IO_UART_FLOWCONTROL_KIND is (
+ UART_FLOWCONTROL_NONE,
+ UART_FLOWCONTROL_XON_XOFF,
+ UART_FLOWCONTROL_RTS_CTS,
+ UART_FLOWCONTROL_RTR_CTS
+ );
+
+ constant C_IO_UART_TYPICAL_BAUDRATES : T_BAUDVEC := (
+ 0 => 300 Bd, 1 => 600 Bd, 2 => 1200 Bd, 3 => 1800 Bd, 4 => 2400 Bd,
+ 5 => 4000 Bd, 6 => 4800 Bd, 7 => 7200 Bd, 8 => 9600 Bd, 9 => 14400 Bd,
+ 10 => 16000 Bd, 11 => 19200 Bd, 12 => 28800 Bd, 13 => 38400 BD, 14 => 51200 Bd,
+ 15 => 56000 Bd, 16 => 57600 Bd, 17 => 64000 Bd, 18 => 76800 Bd, 19 => 115200 Bd,
+ 20 => 128000 Bd, 21 => 153600 Bd, 22 => 230400 Bd, 23 => 250000 Bd, 24 => 256000 BD,
+ 25 => 460800 Bd, 26 => 500000 Bd, 27 => 576000 Bd, 28 => 921600 Bd
+ );
+
+ function io_UART_IsTypicalBaudRate(br : BAUD) return BOOLEAN;
+
+ -- Bit clock generator
+ component uart_bclk is
+ generic (
+ CLOCK_FREQ : FREQ := 100 MHz;
+ BAUDRATE : BAUD := 115200 Bd
+ );
+ port (
+ clk : in std_logic;
+ rst : in std_logic;
+ bclk_r : out std_logic;
+ bclk_x8_r : out std_logic
+ );
+ end component;
+
+ -- Transmitter
+ component uart_tx is
+ port (
+ clk : in std_logic;
+ rst : in std_logic;
+ bclk_r : in std_logic;
+ stb : in std_logic;
+ din : in std_logic_vector(7 downto 0);
+ rdy : out std_logic;
+ txd : out std_logic
+ );
+ end component;
+
+ -- Receiver
+ component uart_rx is
+ generic (
+ OUT_REGS : boolean
+ );
+ port (
+ clk : in std_logic;
+ rst : in std_logic;
+ bclk_x8_r : in std_logic;
+ rxd : in std_logic;
+ dos : out std_logic;
+ dout : out std_logic_vector(7 downto 0)
+ );
+ end component;
+
+ -- Wrappers
+ -- ===========================================================================
+ -- UART with FIFOs and optional flow control
+ component uart_fifo is
+ generic (
+ CLOCK_FREQ : FREQ := 100 MHz;
+ BAUDRATE : BAUD := 115200 Bd;
+ FLOWCONTROL : T_IO_UART_FLOWCONTROL_KIND := UART_FLOWCONTROL_NONE;
+ TX_MIN_DEPTH : POSITIVE := 16;
+ TX_ESTATE_BITS : NATURAL := 1;
+ RX_MIN_DEPTH : POSITIVE := 16;
+ RX_FSTATE_BITS : NATURAL := 1;
+ RX_OUT_REGS : BOOLEAN := FALSE;
+
+ SWFC_XON_CHAR : std_logic_vector(7 downto 0) := x"11"; -- ^Q
+ SWFC_XON_TRIGGER : real := 0.0625;
+ SWFC_XOFF_CHAR : std_logic_vector(7 downto 0) := x"13"; -- ^S
+ SWFC_XOFF_TRIGGER : real := 0.75
+ );
+ port (
+ Clock : in std_logic;
+ Reset : in std_logic;
+
+ -- FIFO interface
+ TX_put : in STD_LOGIC;
+ TX_Data : in STD_LOGIC_VECTOR(7 downto 0);
+ TX_Full : out STD_LOGIC;
+ TX_EmptyState : out STD_LOGIC_VECTOR(TX_ESTATE_BITS - 1 downto 0);
+
+ RX_Valid : out STD_LOGIC;
+ RX_Data : out STD_LOGIC_VECTOR(7 downto 0);
+ RX_got : in STD_LOGIC;
+ RX_FullState : out STD_LOGIC_VECTOR(RX_FSTATE_BITS - 1 downto 0);
+ RX_Overflow : out std_logic;
+
+ -- External Pins
+ UART_RX : in std_logic;
+ UART_TX : out std_logic
+ );
+ end component;
+end package;
+
+
+package body uart is
+ function io_UART_IsTypicalBaudRate(br : BAUD) return BOOLEAN is
+ begin
+ for i in C_IO_UART_TYPICAL_BAUDRATES'range loop
+ next when (br /= C_IO_UART_TYPICAL_BAUDRATES(i));
+ return TRUE;
+ end loop;
+ return FALSE;
+ end function;
+end package body;
diff --git a/testsuite/gna/bug019/PoC/src/io/uart/uart_bclk.vhdl b/testsuite/gna/bug019/PoC/src/io/uart/uart_bclk.vhdl
new file mode 100644
index 0000000..da26785
--- /dev/null
+++ b/testsuite/gna/bug019/PoC/src/io/uart/uart_bclk.vhdl
@@ -0,0 +1,108 @@
+-- EMACS settings: -*- tab-width: 2; indent-tabs-mode: t -*-
+-- vim: tabstop=2:shiftwidth=2:noexpandtab
+-- kate: tab-width 2; replace-tabs off; indent-width 2;
+--
+-- ============================================================================
+-- Authors: Martin Zabel
+-- Patrick Lehmann
+--
+-- Module: UART bit clock / baud rate generator
+--
+-- Description:
+-- ------------------------------------
+-- TODO
+--
+-- old comments:
+-- UART BAUD rate generator
+-- bclk_r = bit clock is rising
+-- bclk_x8_r = bit clock times 8 is rising
+--
+--
+-- License:
+-- ============================================================================
+-- Copyright 2008-2015 Technische Universitaet Dresden - Germany
+-- Chair for VLSI-Design, Diagnostics and Architecture
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+-- ============================================================================
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.numeric_std.all;
+
+library PoC;
+use PoC.utils.all;
+use PoC.strings.all;
+use PoC.physical.all;
+use PoC.components.all;
+use PoC.uart.all;
+
+
+entity uart_bclk is
+ generic (
+ CLOCK_FREQ : FREQ := 100 MHz;
+ BAUDRATE : BAUD := 115200 Bd
+ );
+ port (
+ clk : in std_logic;
+ rst : in std_logic;
+ bclk : out std_logic;
+ bclk_x8 : out std_logic
+ );
+end entity;
+
+
+architecture rtl of uart_bclk is
+ constant UART_OVERSAMPLING_RATE : POSITIVE := 8;
+ constant TIME_UNIT_INTERVAL : TIME := 1 sec / (to_real(BAUDRATE, 1 Bd) * real(UART_OVERSAMPLING_RATE));
+ constant BAUDRATE_COUNTER_MAX : POSITIVE := TimingToCycles(TIME_UNIT_INTERVAL, CLOCK_FREQ);
+ constant BAUDRATE_COUNTER_BITS : POSITIVE := log2ceilnz(BAUDRATE_COUNTER_MAX + 1);
+
+ -- registers
+ signal x8_cnt : unsigned(BAUDRATE_COUNTER_BITS - 1 downto 0) := (others => '0');
+ signal x1_cnt : unsigned(2 downto 0) := (others => '0');
+
+ -- control signals
+ signal x8_cnt_done : std_logic;
+ signal x1_cnt_done : std_logic;
+
+ signal bclk_r : STD_LOGIC := '0';
+ signal bclk_x8_r : STD_LOGIC := '0';
+begin
+ assert FALSE -- LF works in QuartusII
+ report "uart_bclk:" & LF &
+ " CLOCK_FREQ=" & to_string(CLOCK_FREQ, 3) & LF &
+ " BAUDRATE=" & to_string(BAUDRATE, 3) & LF &
+ " COUNTER_MAX=" & INTEGER'image(BAUDRATE_COUNTER_MAX) & LF &
+ " COUNTER_BITS=" & INTEGER'image(BAUDRATE_COUNTER_BITS)
+ severity NOTE;
+
+ assert io_UART_IsTypicalBaudRate(BAUDRATE)
+ report "The baudrate " & to_string(BAUDRATE, 3) & " is not known to be a typical baudrate!"
+ severity WARNING;
+
+ x8_cnt <= upcounter_next(cnt => x8_cnt, rst => (rst or x8_cnt_done)) when rising_edge(clk);
+ x8_cnt_done <= upcounter_equal(cnt => x8_cnt, value => BAUDRATE_COUNTER_MAX - 1);
+
+ x1_cnt <= upcounter_next(cnt => x1_cnt, rst => rst, en => x8_cnt_done) when rising_edge(clk);
+ x1_cnt_done <= comp_allzero(x1_cnt);
+
+ -- outputs
+ -- ---------------------------------------------------------------------------
+ -- only x8_cnt_done is pulsed for one clock cycle!
+ bclk_r <= (x1_cnt_done and x8_cnt_done) when rising_edge(clk);
+ bclk_x8_r <= x8_cnt_done when rising_edge(clk);
+
+ bclk <= bclk_r;
+ bclk_x8 <= bclk_x8_r;
+end;
diff --git a/testsuite/gna/bug019/PoC/src/io/uart/uart_fifo.vhdl b/testsuite/gna/bug019/PoC/src/io/uart/uart_fifo.vhdl
new file mode 100644
index 0000000..e1c1c9e
--- /dev/null
+++ b/testsuite/gna/bug019/PoC/src/io/uart/uart_fifo.vhdl
@@ -0,0 +1,320 @@
+-- EMACS settings: -*- tab-width: 2; indent-tabs-mode: t -*-
+-- vim: tabstop=2:shiftwidth=2:noexpandtab
+-- kate: tab-width 2; replace-tabs off; indent-width 2;
+--
+-- ============================================================================
+-- Authors: Martin Zabel
+-- Patrick Lehmann
+--
+-- Module: UART Wrapper with Embedded FIFOs and Optional Flow Control
+--
+-- Description:
+-- ------------------------------------
+-- Small FIFOs are included in this module, if larger or asynchronous
+-- transmit / receive FIFOs are required, then they must be connected
+-- externally.
+--
+-- old comments:
+-- UART BAUD rate generator
+-- bclk = bit clock is rising
+-- bclk_x8 = bit clock times 8 is rising
+--
+--
+-- License:
+-- ============================================================================
+-- Copyright 2008-2015 Technische Universitaet Dresden - Germany
+-- Chair for VLSI-Design, Diagnostics and Architecture
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+-- ============================================================================
+
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+
+library PoC;
+use PoC.vectors.all;
+use PoC.physical.all;
+use PoC.components.all;
+use PoC.uart.all;
+
+
+entity uart_fifo is
+ generic (
+ CLOCK_FREQ : FREQ := 100 MHz;
+ BAUDRATE : BAUD := 115200 Bd;
+ FLOWCONTROL : T_IO_UART_FLOWCONTROL_KIND := UART_FLOWCONTROL_NONE;
+ TX_MIN_DEPTH : POSITIVE := 16;
+ TX_ESTATE_BITS : NATURAL := 1;
+ RX_MIN_DEPTH : POSITIVE := 16;
+ RX_FSTATE_BITS : NATURAL := 1;
+ RX_OUT_REGS : BOOLEAN := FALSE;
+ ADD_INPUT_SYNCHRONIZERS : BOOLEAN := TRUE;
+
+ SWFC_XON_CHAR : std_logic_vector(7 downto 0) := x"11"; -- ^Q
+ SWFC_XON_TRIGGER : real := 0.0625;
+ SWFC_XOFF_CHAR : std_logic_vector(7 downto 0) := x"13"; -- ^S
+ SWFC_XOFF_TRIGGER : real := 0.75
+ );
+ port (
+ Clock : in std_logic;
+ Reset : in std_logic;
+
+ -- FIFO interface
+ TX_put : in STD_LOGIC;
+ TX_Data : in STD_LOGIC_VECTOR(7 downto 0);
+ TX_Full : out STD_LOGIC;
+ TX_EmptyState : out STD_LOGIC_VECTOR(TX_ESTATE_BITS - 1 downto 0);
+
+ RX_Valid : out STD_LOGIC;
+ RX_Data : out STD_LOGIC_VECTOR(7 downto 0);
+ RX_got : in STD_LOGIC;
+ RX_FullState : out STD_LOGIC_VECTOR(RX_FSTATE_BITS - 1 downto 0);
+ RX_Overflow : out std_logic;
+
+ -- External pins
+ UART_TX : out std_logic;
+ UART_RX : in std_logic
+ );
+end entity;
+
+
+architecture rtl of uart_fifo is
+
+ signal FC_TX_Strobe : STD_LOGIC;
+ signal FC_TX_Data : T_SLV_8;
+ signal FC_TX_got : STD_LOGIC;
+ signal FC_RX_put : STD_LOGIC;
+ signal FC_RX_Data : T_SLV_8;
+
+ signal TXFIFO_Valid : STD_LOGIC;
+ signal TXFIFO_Data : T_SLV_8;
+
+ signal RXFIFO_Full : STD_LOGIC;
+
+ signal TXUART_Ready : STD_LOGIC;
+ signal RXUART_Strobe : STD_LOGIC;
+ signal RXUART_Data : T_SLV_8;
+
+ signal BitClock : STD_LOGIC;
+ signal BitClock_x8 : STD_LOGIC;
+
+ signal UART_RX_sync : STD_LOGIC;
+
+begin
+ assert FALSE report "uart_fifo: BAUDRATE=: " & to_string(BAUDRATE, 3) severity NOTE;
+
+ -- ===========================================================================
+ -- Transmit and Receive FIFOs
+ -- ===========================================================================
+ TXFIFO : entity PoC.fifo_cc_got
+ generic map (
+ D_BITS => 8, -- Data Width
+ MIN_DEPTH => TX_MIN_DEPTH, -- Minimum FIFO Depth
+ DATA_REG => TRUE, -- Store Data Content in Registers
+ STATE_REG => FALSE, -- Registered Full/Empty Indicators
+ OUTPUT_REG => FALSE, -- Registered FIFO Output
+ ESTATE_WR_BITS => TX_ESTATE_BITS, -- Empty State Bits
+ FSTATE_RD_BITS => 0 -- Full State Bits
+ )
+ port map (
+ rst => Reset,
+ clk => Clock,
+ put => TX_put,
+ din => TX_Data,
+ full => TX_Full,
+ estate_wr => TX_EmptyState,
+
+ valid => TXFIFO_Valid,
+ dout => TXFIFO_Data,
+ got => FC_TX_got,
+ fstate_rd => open
+ );
+
+ RXFIFO : entity PoC.fifo_cc_got
+ generic map (
+ D_BITS => 8, -- Data Width
+ MIN_DEPTH => RX_MIN_DEPTH, -- Minimum FIFO Depth
+ DATA_REG => TRUE, -- Store Data Content in Registers
+ STATE_REG => FALSE, -- Registered Full/Empty Indicators
+ OUTPUT_REG => FALSE, -- Registered FIFO Output
+ ESTATE_WR_BITS => 0, -- Empty State Bits
+ FSTATE_RD_BITS => RX_FSTATE_BITS -- Full State Bits
+ )
+ port map (
+ rst => Reset,
+ clk => Clock,
+ put => FC_RX_put,
+ din => FC_RX_Data,
+ full => RXFIFO_Full,
+ estate_wr => open,
+
+ valid => RX_Valid,
+ dout => RX_Data,
+ got => RX_got,
+ fstate_rd => RX_FullState
+ );
+
+ genNOFC : if (FLOWCONTROL = UART_FLOWCONTROL_NONE) generate
+ signal Overflow_r : std_logic := '0';
+ begin
+
+ FC_TX_Strobe <= TXFIFO_Valid and TXUART_Ready;
+ FC_TX_Data <= TXFIFO_Data;
+ FC_TX_got <= TXFIFO_Valid and TXUART_Ready;
+
+ FC_RX_put <= RXUART_Strobe;
+ FC_RX_Data <= RXUART_Data;
+
+ Overflow_r <= ffrs(q => Overflow_r, rst => Reset, set => (RXUART_Strobe and RXFIFO_Full)) when rising_edge(Clock);
+
+ RX_Overflow <= Overflow_r;
+ end generate;
+ -- ===========================================================================
+ -- Software Flow Control
+ -- ===========================================================================
+ genSWFC : if (FLOWCONTROL = UART_FLOWCONTROL_XON_XOFF) generate
+ constant XON : std_logic_vector(7 downto 0) := x"11"; -- ^Q
+ constant XOFF : std_logic_vector(7 downto 0) := x"13"; -- ^S
+
+ constant XON_TRIG : integer := integer(SWFC_XON_TRIGGER * real(2**RX_FSTATE_BITS));
+ constant XOFF_TRIG : integer := integer(SWFC_XOFF_TRIGGER * real(2**RX_FSTATE_BITS));
+
+ signal send_xoff : std_logic;
+ signal send_xon : std_logic;
+
+ signal set_xoff_transmitted : std_logic;
+ signal clr_xoff_transmitted : std_logic;
+ signal discard_user : std_logic;
+
+ signal set_overflow : std_logic;
+
+ -- registers
+ signal xoff_transmitted : std_logic;
+
+ begin
+-- -- send XOFF only once when fill state goes above trigger level
+-- send_xoff <= (not xoff_transmitted) when (rf_fs >= XOFF_TRIG) else '0';
+-- set_xoff_transmitted <= tx_rdy when (rf_fs >= XOFF_TRIG) else '0';
+--
+-- -- send XON only once when receive FIFO is almost empty
+-- send_xon <= xoff_transmitted when (rf_fs = XON_TRIG) else '0';
+-- clr_xoff_transmitted <= tx_rdy when (rf_fs = XON_TRIG) else '0';
+--
+-- -- discard any user supplied XON/XOFF
+-- discard_user <= '1' when (tf_dout = SWFC_XON_CHAR) or (tf_dout = SWFC_XOFF_CHAR) else '0';
+--
+-- -- tx / tf control
+-- tx_din <= SWFC_XOFF_CHAR when (send_xoff = '1') else
+-- SWFC_XON_CHAR when (send_xon = '1') else
+-- tf_dout;
+--
+-- tx_stb <= send_xoff or send_xon or (tf_valid and (not discard_user));
+-- tf_got <= (send_xoff nor send_xon) and
+-- tf_valid and tx_rdy; -- always check tf_valid
+--
+-- -- rx / rf control
+-- rf_put <= (not rf_full) and rx_dos; -- always check rf_full
+-- rf_din <= rx_dout;
+--
+-- set_overflow <= rf_full and rx_dos;
+--
+-- -- registers
+-- process (Clock)
+-- begin -- process
+-- if rising_edge(Clock) then
+-- if (rst or set_xoff_transmitted) = '1' then
+-- -- send a XON after reset
+-- xoff_transmitted <= '1';
+-- elsif clr_xoff_transmitted = '1' then
+-- xoff_transmitted <= '0';
+-- end if;
+--
+-- if rst = '1' then
+-- overflow <= '0';
+-- elsif set_overflow = '1' then
+-- overflow <= '1';
+-- end if;
+-- end if;
+-- end process;
+ end generate;
+ -- ===========================================================================
+ -- Hardware Flow Control
+ -- ===========================================================================
+ genHWFC1 : if (FLOWCONTROL = UART_FLOWCONTROL_RTS_CTS) generate
+
+ begin
+
+ end generate;
+ -- ===========================================================================
+ -- Hardware Flow Control
+ -- ===========================================================================
+ genHWFC2 : if (FLOWCONTROL = UART_FLOWCONTROL_RTR_CTS) generate
+
+ begin
+
+ end generate;
+
+ -- ===========================================================================
+ -- BitClock, Transmitter, Receiver
+ -- ===========================================================================
+ genNoSync : if (ADD_INPUT_SYNCHRONIZERS = FALSE) generate
+ UART_RX_sync <= UART_RX;
+ end generate;
+ genSync: if (ADD_INPUT_SYNCHRONIZERS = TRUE) generate
+ sync_i : entity PoC.sync_Bits
+ port map (
+ Clock => Clock, -- Clock to be synchronized to
+ Input(0) => UART_RX, -- Data to be synchronized
+ Output(0) => UART_RX_sync -- synchronised data
+ );
+ end generate;
+ -- ===========================================================================
+ -- BitClock, Transmitter, Receiver
+ -- ===========================================================================
+ bclk : entity PoC.uart_bclk
+ generic map (
+ CLOCK_FREQ => CLOCK_FREQ,
+ BAUDRATE => BAUDRATE
+ )
+ port map (
+ clk => Clock,
+ rst => Reset,
+ bclk => BitClock,
+ bclk_x8 => BitClock_x8
+ );
+
+ TX : entity PoC.uart_tx
+ port map (
+ clk => Clock,
+ rst => Reset,
+ bclk => BitClock,
+ stb => FC_TX_Strobe,
+ din => FC_TX_Data,
+ rdy => TXUART_Ready,
+ txd => UART_TX
+ );
+
+ RX : entity PoC.uart_rx
+ generic map (
+ OUT_REGS => RX_OUT_REGS
+ )
+ port map (
+ clk => Clock,
+ rst => Reset,
+ bclk_x8 => BitClock_x8,
+ dos => RXUART_Strobe,
+ dout => RXUART_Data,
+ rxd => UART_RX_sync
+ );
+end;
diff --git a/testsuite/gna/bug019/PoC/src/io/uart/uart_rx.vhdl b/testsuite/gna/bug019/PoC/src/io/uart/uart_rx.vhdl
new file mode 100644
index 0000000..01383ba
--- /dev/null
+++ b/testsuite/gna/bug019/PoC/src/io/uart/uart_rx.vhdl
@@ -0,0 +1,174 @@
+-- EMACS settings: -*- tab-width: 2; indent-tabs-mode: t -*-
+-- vim: tabstop=2:shiftwidth=2:noexpandtab
+-- kate: tab-width 2; replace-tabs off; indent-width 2;
+--
+-- ============================================================================
+-- Authors: Martin Zabel
+-- Patrick Lehmann
+--
+-- Module: UART Receiver
+--
+-- Description:
+-- ------------------------------------
+-- TODO
+--
+-- old comments:
+-- Serial configuration: 8 data bits, 1 stop bit, no parity
+--
+-- bclk_x8 = bit clock (defined by BAUD rate) times 8
+-- dos = data out strobe, signals that dout is valid, active high for one
+-- cycle
+-- dout = data out = received byte
+--
+-- OUT_REGS:
+-- If disabled, then dos is a combinatorial output. Further merging of logic is
+-- possible but timing constraints might fail. If enabled, 9 more registers are
+-- required. But now, dout toggles only after receiving of full byte.
+--
+--
+-- License:
+-- ============================================================================
+-- Copyright 2008-2015 Technische Universitaet Dresden - Germany
+-- Chair for VLSI-Design, Diagnostics and Architecture
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+-- ============================================================================
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.numeric_std.all;
+
+library PoC;
+use PoC.components.all;
+
+
+entity uart_rx is
+ generic (
+ OUT_REGS : boolean
+ );
+ port (
+ clk : in std_logic;
+ rst : in std_logic;
+ bclk_x8 : in std_logic;
+ rxd : in std_logic;
+ dos : out std_logic;
+ dout : out std_logic_vector(7 downto 0)
+ );
+end entity;
+
+
+architecture rtl of uart_rx is
+ type states is (IDLE, RDATA);
+ signal state : states := IDLE;
+ signal next_state : states;
+
+ -- registers
+ signal rxd_reg1 : std_logic := '1';
+ signal rxd_reg2 : std_logic := '1';
+ signal sr : std_logic_vector(7 downto 0) := (others => '0'); -- data only
+ signal bclk_cnt : unsigned(2 downto 0) := to_unsigned(4, 3);
+ signal shift_cnt : unsigned(3 downto 0) := (others => '0');
+
+ -- control signals
+ signal rxd_falling : std_logic;
+ signal bclk_rising : std_logic;
+ signal start_bclk : std_logic;
+ signal shift_sr : std_logic;
+ signal shift_done : std_logic;
+ signal put_data : std_logic;
+
+begin
+
+ rxd_falling <= (not rxd_reg1) and rxd_reg2;
+ bclk_rising <= bclk_x8 when (comp_allone(bclk_cnt) = '1') else '0';
+
+ -- shift_cnt count from 0 to 9 (1 start bit + 8 data bits)
+ shift_cnt <= upcounter_next(cnt => shift_cnt, rst => start_bclk, en => shift_sr) when rising_edge(clk);
+ shift_done <= upcounter_equal(cnt => shift_cnt, value => 9);
+
+ bclk_cnt <= upcounter_next(cnt => bclk_cnt, rst => start_bclk, en => bclk_x8, init => 4) when rising_edge(clk);
+
+ process (state, rxd_falling, bclk_x8, bclk_rising, shift_done)
+ begin
+ next_state <= state;
+ start_bclk <= '0';
+ shift_sr <= '0';
+ put_data <= '0';
+
+ case state is
+ when IDLE =>
+ -- wait for start bit
+ if (rxd_falling and bclk_x8) = '1' then
+ next_state <= RDATA;
+ start_bclk <= '1'; -- = rst_shift_cnt
+ end if;
+
+ when RDATA =>
+ if bclk_rising = '1' then
+ -- bit clock keeps running
+ if shift_done = '1' then
+ -- stop bit reached
+ put_data <= '1';
+ next_state <= IDLE;
+
+ else
+ -- TODO: check start bit?
+ shift_sr <= '1';
+ end if;
+ end if;
+
+ when others => null;
+ end case;
+ end process;
+
+ process (clk)
+ begin
+ if rising_edge(clk) then
+ if rst = '1' then
+ state <= IDLE;
+ else
+ state <= next_state;
+ end if;
+
+ rxd_reg1 <= rxd;
+
+ if bclk_x8 = '1' then
+ -- align to bclk_x8, so when we can easily check for
+ -- the falling edge of the start bit
+ rxd_reg2 <= rxd_reg1;
+ end if;
+
+ if shift_sr = '1' then
+ -- shift into MSB
+ sr <= rxd_reg2 & sr(sr'left downto 1);
+ end if;
+ end if;
+ end process;
+
+ -- output
+ gOutRegs: if OUT_REGS = true generate
+ process (clk)
+ begin
+ if rising_edge(clk) then
+ dos <= put_data and rxd_reg2; -- check stop bit
+ dout <= sr;
+ end if;
+ end process;
+ end generate gOutRegs;
+
+ gNoOutRegs: if OUT_REGS = false generate
+ dos <= put_data and rxd_reg2; -- check stop bit
+ dout <= sr;
+ end generate gNoOutRegs;
+
+end;
diff --git a/testsuite/gna/bug019/PoC/src/io/uart/uart_tx.vhdl b/testsuite/gna/bug019/PoC/src/io/uart/uart_tx.vhdl
new file mode 100644
index 0000000..fe329fa
--- /dev/null
+++ b/testsuite/gna/bug019/PoC/src/io/uart/uart_tx.vhdl
@@ -0,0 +1,140 @@
+-- EMACS settings: -*- tab-width: 2; indent-tabs-mode: t -*-
+-- vim: tabstop=2:shiftwidth=2:noexpandtab
+-- kate: tab-width 2; replace-tabs off; indent-width 2;
+--
+-- ============================================================================
+-- Authors: Martin Zabel
+-- Patrick Lehmann
+--
+-- Module: UART Transmitter
+--
+-- Description:
+-- ------------------------------------
+-- TODO
+--
+-- old comments:
+-- Serial configuration: 8 data bits, 1 stop bit, no parity
+--
+-- bclk = bit clk is rising
+-- stb = strobe, i.e. transmit byte @ din
+-- rdy = ready
+--
+--
+-- License:
+-- ============================================================================
+-- Copyright 2008-2015 Technische Universitaet Dresden - Germany
+-- Chair for VLSI-Design, Diagnostics and Architecture
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+-- ============================================================================
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.numeric_std.all;
+
+library PoC;
+use PoC.components.all;
+
+
+entity uart_tx is
+ port (
+ clk : in std_logic;
+ rst : in std_logic;
+ bclk : in std_logic;
+ stb : in std_logic;
+ din : in std_logic_vector(7 downto 0);
+ rdy : out std_logic;
+ txd : out std_logic
+ );
+end entity;
+
+
+architecture rtl of uart_tx is
+ type states is (IDLE, TDATA);
+ signal state : states := IDLE;
+ signal next_state : states;
+
+ -- register
+ signal sr : std_logic_vector(9 downto 1) := (others => '0');
+ signal sr0 : std_logic := '1'; -- current bit to transmit
+ signal shift_cnt : unsigned(3 downto 0) := (others => '0');
+ signal shift_done : STD_LOGIC;
+
+ -- control signals
+ signal start_tx : std_logic;
+ signal shift_sr : std_logic;
+
+begin
+
+ process (state, stb, bclk, shift_done)
+ begin
+ next_state <= state;
+ start_tx <= '0';
+ shift_sr <= '0';
+
+ case state is
+ when IDLE =>
+ if stb = '1' then
+ -- start_tx triggers register initialization
+ start_tx <= '1';
+ next_state <= TDATA;
+ end if;
+
+ when TDATA =>
+ if bclk = '1' then
+ -- also shift stop bit into sr0!
+ shift_sr <= '1';
+
+ if (shift_done = '1') then
+ -- condition is true at beginning of sending the stop-bit
+ -- synchronization to the bitclk ensures that stop-bit is
+ -- transmitted fully
+ next_state <= IDLE;
+ end if;
+ end if;
+ when others => null;
+ end case;
+ end process;
+
+ process (clk)
+ begin
+ if rising_edge(clk) then
+ if rst = '1' then
+ state <= IDLE;
+ else
+ state <= next_state;
+ end if;
+
+ if start_tx = '1' then
+ -- data, start bit
+ sr <= din & '0';
+ elsif shift_sr = '1' then
+ sr <= '1' & sr(sr'left downto sr'right+1);
+ end if;
+
+ if rst = '1' then
+ sr0 <= '1'; -- idle
+ elsif shift_sr = '1' then
+ sr0 <= sr(1);
+ end if;
+ end if;
+ end process;
+
+ shift_cnt <= upcounter_next(cnt => shift_cnt, rst => start_tx, en => shift_sr) when rising_edge(clk);
+ shift_done <= upcounter_equal(cnt => shift_cnt, value => 9);
+
+ -- outputs
+ txd <= sr0;
+ rdy <= '1' when state = IDLE else '0';
+
+end;