aboutsummaryrefslogtreecommitdiffstats
path: root/testsuite/gna
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2018-08-15 06:43:27 +0200
committerTristan Gingold <tgingold@free.fr>2018-08-15 06:43:27 +0200
commite279ecb9b8ee7376b2f5f606a86b6daceda33a1e (patch)
tree1ffdde265376eebcd5465cedaa1ee4e8cf3d2749 /testsuite/gna
parent1335093885b3c416b70e3baccace84f01d9e7bb3 (diff)
downloadghdl-e279ecb9b8ee7376b2f5f606a86b6daceda33a1e.tar.gz
ghdl-e279ecb9b8ee7376b2f5f606a86b6daceda33a1e.tar.bz2
ghdl-e279ecb9b8ee7376b2f5f606a86b6daceda33a1e.zip
Add testcase for #632
Diffstat (limited to 'testsuite/gna')
-rw-r--r--testsuite/gna/issue632/bug.vhdl249
-rwxr-xr-xtestsuite/gna/issue632/testsuite.sh10
2 files changed, 259 insertions, 0 deletions
diff --git a/testsuite/gna/issue632/bug.vhdl b/testsuite/gna/issue632/bug.vhdl
new file mode 100644
index 000000000..1e1ffbbdd
--- /dev/null
+++ b/testsuite/gna/issue632/bug.vhdl
@@ -0,0 +1,249 @@
+----------------------------------------------------------------------------------
+-- Author: Stefan Lohse
+----------------------------------------------------------------------------------
+library IEEE;
+use IEEE.std_logic_1164.all;
+
+package utilities_pkg is
+ type t_frequency is range 0 to natural'high units
+ Hz; -- primary unit
+ kHz = 1000 Hz; -- secondary unit
+ MHz = 1000 kHz; -- secondary unit
+ GHz = 1000 MHz; -- secondary unit
+ end units;
+
+ function to_period(b: t_frequency) return time;
+ function log2_ceil(a : integer) return natural;
+ function isSimulation return boolean;
+
+ -- ite = if-then-else
+ function ite( cond: boolean; A: integer; B : integer) return integer;
+
+ constant SIMULATION : boolean; -- deferred constant declaration
+end package;
+
+package body utilities_pkg is
+ function to_period(b: t_frequency) return time is
+ constant result : real := 1.0/real(t_frequency'pos(B));
+ begin
+ return result * 1 sec;
+ end function;
+
+ function log2_ceil(a : integer) return natural is
+ variable pow2 : natural; -- equivalent zu := natural'left
+ begin
+ if a = 0 then
+ return 1;
+ end if;
+
+ for i in 0 to 31 loop
+ pow2 := 2**i;
+ if pow2 > a then
+ return i;
+ end if;
+ end loop;
+ end function;
+
+ function isSimulation return boolean is
+ begin
+ return is_x('X');
+ end function;
+
+ constant SIMULATION : boolean := isSimulation;
+
+ function ite( cond: boolean; A: integer; B : integer) return integer is
+ begin
+ if cond then
+ return A;
+ else
+ return B;
+ end if;
+ end function;
+end package body;
+
+
+library IEEE;
+use IEEE.STD_LOGIC_1164.ALL;
+use IEEE.MATH_REAL.ALL;
+
+use work.utilities_pkg.all;
+
+package uart_pkg is
+ type t_baudrate is range 0 to natural'high units -- oder (natural'low to natural'high) oder (1 to 1000000)
+ Bd;
+ kBd = 1000 Bd;
+ MBd = 1000 kBd;
+ end units;
+
+ function to_period(b: t_baudrate) return time;
+ function timing_to_cycles(period: time; frequency: t_frequency) return integer;
+ function ite( cond: boolean; A: t_baudrate; B : t_baudrate) return t_baudrate;
+end package;
+
+package body uart_pkg is
+ function to_period(b: t_baudrate) return time is
+ constant result : real := 1.0/real(t_baudrate'pos(B));
+ begin
+ return result * 1 sec;
+ end function;
+
+ function timing_to_cycles(period: time; frequency: t_frequency) return integer is
+ variable res_real : real;
+ begin
+ res_real := real(time'pos(period)) / 1.0E12;
+ res_real := real(t_frequency'pos(frequency)) * res_real;
+
+ return integer(ceil(res_real));
+ end function;
+
+ function ite( cond: boolean; A: t_baudrate; B : t_baudrate) return t_baudrate is
+ begin
+ if cond then
+ return A;
+ else
+ return B;
+ end if;
+ end function;
+end package body;
+
+
+library IEEE;
+use IEEE.STD_LOGIC_1164.ALL;
+use IEEE.NUMERIC_STD.ALL;
+
+use work.uart_pkg.ALL;
+use work.utilities_pkg.all;
+
+entity uart is
+ generic (
+ uart_oversampling : positive := 16;
+ num_of_databits : positive := 8
+ );
+ port (
+ clk : in STD_LOGIC;
+ rst : in STD_LOGIC;
+ rx : in STD_LOGIC;
+ valid : out STD_LOGIC;
+ error : out STD_LOGIC;
+ data : out STD_LOGIC_VECTOR(num_of_databits-1 downto 0);
+ uart_strobe : in STD_LOGIC
+ );
+end entity;
+
+architecture rtl of uart is
+ signal shift_reg : std_logic_vector(num_of_databits-1 downto 0);
+ signal shift_en : std_logic;
+
+ signal cntbit_value : unsigned(log2ceil(num_of_databits) downto 0);
+ signal cntbit_en : std_logic;
+ signal cntbit_rst : std_logic;
+
+ signal cntsamp_value : unsigned(log2ceil(num_of_databits) downto 0);
+ signal cntsamp_en : std_logic;
+ signal cntsamp_rst : std_logic;
+
+ type t_state is (s_idle, s_startbit, s_receive, s_stopbit, s_error);
+ signal current_state : t_state := s_idle;
+ signal next_state : t_state;
+
+begin
+ shift: process(clk)
+ begin
+ if rising_edge(clk) then
+ if rst = '1' then
+ shift_reg <= (others => '0');
+ elsif shift_en = '1' then
+ shift_reg <= rx & shift_reg(shift_reg'right downto 1);
+ end if;
+ end if;
+ end process;
+ data <= shift_reg;
+
+ cntbit: process(clk)
+ begin
+ if rising_edge(clk) then
+ if cntbit_rst = '1' then
+ cntbit_value <= (others => '0');
+ elsif cntbit_en = '1' then
+ cntbit_value <= cntbit_value + 1;
+ end if;
+ end if;
+ end process;
+
+ cntsamp: process(clk)
+ begin
+ if rising_edge(clk) then
+ if cntsamp_rst = '1' then
+ cntsamp_value <= (others => '0');
+ elsif cntsamp_en = '1' then
+ cntsamp_value <= cntsamp_value + 1;
+ end if;
+ end if;
+ end process;
+
+ -- FSM
+ fsmreg: process(clk)
+ begin
+ if rising_edge(clk) then
+ if rst = '1' then
+ current_state <= s_idle;
+ else
+ current_state <= next_state;
+ end if;
+ end if;
+ end process;
+
+ fsmcomb: process(current_state, uart_strobe, rx, cntbit_value, cntsamp_value)
+ begin
+ -- default values;
+ next_state <= current_state;
+ valid <= '0';
+ error <= '0';
+ cntbit_en <= '0';
+ cntbit_rst <= '0';
+ cntsamp_en <= '0';
+ cntsamp_rst <= '0';
+
+ case current_state is
+ when s_idle =>
+ cntsamp_rst <= '1';
+ cntbit_rst <= '1';
+ if rx = '0' then
+ next_state <= s_startbit;
+ end if;
+
+ when s_startbit =>
+ cntsamp_en <= uart_strobe;
+ if cntsamp_value = (uart_oversampling/2)-1 then
+ cntsamp_rst <= '1';
+ next_state <= s_receive;
+ end if;
+
+ when s_receive =>
+ cntsamp_en <= uart_strobe;
+ if cntsamp_value = uart_oversampling-1 then
+ cntsamp_rst <= '1';
+ cntbit_en <= '1';
+ shift_en <= '1';
+ end if;
+ if cntbit_value = num_of_databits then
+ cntsamp_rst <= '1';
+ next_state <= s_stopbit;
+ end if;
+
+ when s_stopbit =>
+ cntsamp_en <= uart_strobe;
+ valid <= '1';
+ if (cntsamp_value = 15) and rx = '1' then
+ next_state <= s_idle;
+ elsif (cntsamp_value = 15) and rx = '0' then
+ next_state <= s_error;
+ end if;
+
+ when s_error =>
+ error <= '1';
+ end case;
+ end process;
+end architecture;
+
+
diff --git a/testsuite/gna/issue632/testsuite.sh b/testsuite/gna/issue632/testsuite.sh
new file mode 100755
index 000000000..ca85f3d73
--- /dev/null
+++ b/testsuite/gna/issue632/testsuite.sh
@@ -0,0 +1,10 @@
+#! /bin/sh
+
+. ../../testenv.sh
+
+export GHDL_STD_FLAGS=--std=08
+analyze_failure bug.vhdl
+
+clean
+
+echo "Test successful"