diff options
-rw-r--r-- | testsuite/synth/issue1080/repro2.vhdl | 100 | ||||
-rw-r--r-- | testsuite/synth/issue1080/repro2_1.vhdl | 63 | ||||
-rwxr-xr-x | testsuite/synth/issue1080/testsuite.sh | 2 |
3 files changed, 164 insertions, 1 deletions
diff --git a/testsuite/synth/issue1080/repro2.vhdl b/testsuite/synth/issue1080/repro2.vhdl new file mode 100644 index 000000000..5d7ed6800 --- /dev/null +++ b/testsuite/synth/issue1080/repro2.vhdl @@ -0,0 +1,100 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity repro2 is +end repro2; + +architecture behav of repro2 is + constant ERR_COUNT : natural := 3; + subtype byte_t is std_logic_vector(7 downto 0); + + function I2S(a: integer; l: integer) return std_logic_vector is + begin + return std_logic_vector(TO_UNSIGNED(a,l)); + end; + + -- Generics and arrays don't mix; use this function to index. + constant TOTAL_MSGS : integer := ERR_COUNT + 2; + subtype msgidx_t is integer range 0 to TOTAL_MSGS-1; + + impure function get_err_msg(n : integer) return string is + begin + case n is + when 0 => return "OK"; + when 1 => return "START"; + when 2 => return "ERR_MSG00"; -- Note +2 offset + when 3 => return "ERR_MSG01-1"; + when 4 => return "ERR_MSG02--2"; + when 5 => return "ERR_MSG03"; + when 6 => return "ERR_MSG04"; + when 7 => return "ERR_MSG05"; + when 8 => return "ERR_MSG06"; + when 9 => return "ERR_MSG07"; + when 10 => return "ERR_MSG08"; + when 11 => return "ERR_MSG09"; + when 12 => return "ERR_MSG10"; + when 13 => return "ERR_MSG11"; + when 14 => return "ERR_MSG12"; + when 15 => return "ERR_MSG13"; + when 16 => return "ERR_MSG14"; + when 17 => return "ERR_MSG15"; + when others => return "UNK"; + end case; + end function; + + impure function get_err_len(n : msgidx_t) return integer is + constant msg : string := get_err_msg(n); + begin + return msg'length; + end function; + + -- Calculate total length of all active messages (including startup). + impure function get_total_bytes return integer is + constant EXTRA_CHARS : integer := 2; -- Msg + CR + LF + variable total : integer := 0; + begin + for n in 0 to TOTAL_MSGS-1 loop + total := total + get_err_len(n) + EXTRA_CHARS; + end loop; + return total; + end function; + + constant TOTAL_BYTES : integer := get_total_bytes; + + -- Define terminal newline characters (CR+LF) + constant NEWLINE_CR : byte_t := i2s(13, 8); + constant NEWLINE_LF : byte_t := i2s(10, 8); + + -- Create ROM array with all concatenated messages. + type array_t is array(0 to TOTAL_BYTES-1) of byte_t; + subtype romaddr_t is integer range 0 to TOTAL_BYTES-1; + + impure function get_msg_array return array_t is + variable result : array_t := (others => (others => '0')); + variable ridx : integer := 0; + + procedure append(constant msg : string) is + begin + -- Append the message to the output array. + for c in 0 to msg'length-1 loop + result(ridx) := i2s(character'pos(msg(msg'left+c)), 8); + ridx := ridx + 1; + end loop; + -- Then append the CR+LF characters. + result(ridx+0) := NEWLINE_CR; + result(ridx+1) := NEWLINE_LF; + ridx := ridx + 2; + end procedure; + begin + -- For each fixed message... + for n in 0 to TOTAL_MSGS-1 loop + append(get_err_msg(n)); + end loop; + return result; + end function; + + constant MESSAGE_ROM : array_t := get_msg_array; +begin +end behav; + diff --git a/testsuite/synth/issue1080/repro2_1.vhdl b/testsuite/synth/issue1080/repro2_1.vhdl new file mode 100644 index 000000000..8a609e9cc --- /dev/null +++ b/testsuite/synth/issue1080/repro2_1.vhdl @@ -0,0 +1,63 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity repro2_1 is + port ( + clk : std_logic; + rst : std_logic; + tx : out std_logic_vector(7 downto 0)); +end repro2_1; + +architecture behav of repro2_1 is + subtype byte_t is std_logic_vector(7 downto 0); + + -- Define terminal newline characters (CR+LF) + constant NEWLINE_CR : byte_t := x"0d"; + constant NEWLINE_LF : byte_t := x"0a"; + + -- Create ROM array with all concatenated messages. + type array_t is array(0 to 15) of byte_t; + + impure function get_msg_array return array_t is + variable result : array_t := (others => (others => '0')); + variable ridx : integer := 0; + + procedure append(constant msg : string) is + begin + -- Append the message to the output array. + for c in 0 to msg'length-1 loop + result(ridx) := x"00"; + ridx := ridx + 1; + end loop; + -- Then append the CR+LF characters. + result(ridx+0) := NEWLINE_CR; + result(ridx+1) := NEWLINE_LF; + ridx := ridx + 2; + end procedure; + begin + -- For each fixed message... + append("xx"); + return result; + end function; + + constant MESSAGE_ROM : array_t := get_msg_array; +begin + process (clk) + variable p : natural; + begin + if rising_edge(clk) then + if rst = '1' then + p := 0; + else + tx <= message_rom (p); + if p = message_rom'right then + p := message_rom'left; + else + p := p + 1; + end if; + end if; + end if; + end process; +end behav; + diff --git a/testsuite/synth/issue1080/testsuite.sh b/testsuite/synth/issue1080/testsuite.sh index 0e3851e6b..24843415d 100755 --- a/testsuite/synth/issue1080/testsuite.sh +++ b/testsuite/synth/issue1080/testsuite.sh @@ -2,7 +2,7 @@ . ../../testenv.sh -for t in repro; do +for t in repro repro2 repro2_1; do synth $t.vhdl -e $t > syn_$t.vhdl analyze syn_$t.vhdl clean |