diff options
author | Patrick Lehmann <Patrick.Lehmann@plc2.de> | 2022-12-19 22:11:44 +0100 |
---|---|---|
committer | Patrick Lehmann <Patrick.Lehmann@plc2.de> | 2022-12-23 23:44:14 +0100 |
commit | 633373d0054f551158cdf668c464646bb9e6af27 (patch) | |
tree | bc989fb2ce39865cb529ea1aa2fd957ec2d0310f | |
parent | 5853a37df7c9468a01d62f7b2eeee7d9773e72ca (diff) | |
download | ghdl-633373d0054f551158cdf668c464646bb9e6af27.tar.gz ghdl-633373d0054f551158cdf668c464646bb9e6af27.tar.bz2 ghdl-633373d0054f551158cdf668c464646bb9e6af27.zip |
Added StopWatch example for DOM and documentation testing.
-rw-r--r-- | testsuite/pyunit/dom/StopWatch.py (renamed from testsuite/pyunit/dom/SimplePackage.py) | 56 | ||||
-rw-r--r-- | testsuite/pyunit/dom/examples/StopWatch/Counter.vhdl | 45 | ||||
-rw-r--r-- | testsuite/pyunit/dom/examples/StopWatch/Debouncer.vhdl | 58 | ||||
-rw-r--r-- | testsuite/pyunit/dom/examples/StopWatch/StopWatch.pkg.vhdl | 21 | ||||
-rw-r--r-- | testsuite/pyunit/dom/examples/StopWatch/StopWatch.vhdl | 127 | ||||
-rw-r--r-- | testsuite/pyunit/dom/examples/StopWatch/Utilities.pkg.vhdl | 99 | ||||
-rw-r--r-- | testsuite/pyunit/dom/examples/StopWatch/seg7_Display.vhdl | 90 | ||||
-rw-r--r-- | testsuite/pyunit/dom/examples/StopWatch/seg7_Encoder.vhdl | 46 | ||||
-rw-r--r-- | testsuite/pyunit/dom/examples/StopWatch/toplevel.Display.vhdl | 65 | ||||
-rw-r--r-- | testsuite/pyunit/dom/examples/StopWatch/toplevel.Encoder.vhdl | 42 | ||||
-rw-r--r-- | testsuite/pyunit/dom/examples/StopWatch/toplevel.StopWatch.tb.vhdl | 58 | ||||
-rw-r--r-- | testsuite/pyunit/dom/examples/StopWatch/toplevel.StopWatch.vhdl | 118 |
12 files changed, 813 insertions, 12 deletions
diff --git a/testsuite/pyunit/dom/SimplePackage.py b/testsuite/pyunit/dom/StopWatch.py index 9c62db4a1..a51c44cf2 100644 --- a/testsuite/pyunit/dom/SimplePackage.py +++ b/testsuite/pyunit/dom/StopWatch.py @@ -42,22 +42,54 @@ if __name__ == "__main__": exit(1) -class SimplePackage(TestCase): +class Display(TestCase): _root = Path(__file__).resolve().parent.parent - _filename: Path = _root / "SimplePackage.vhdl" + _sourceDirectory: Path = _root / "dom/examples/StopWatch" - def test_Package(self): + def test_Encoder(self): design = Design() - document = Document(self._filename) - design.Documents.append(document) + files = ( + Path("Utilities.pkg.vhdl"), + Path("StopWatch.pkg.vhdl"), + Path("seg7_Encoder.vhdl"), + Path("toplevel.Encoder.vhdl"), + ) + for file in files: + document = Document(self._sourceDirectory / file) + design.Documents.append(document) - self.assertEqual(1, len(design.Documents[0].Packages)) - self.assertEqual("pack_1", design.Documents[0].Packages[0].Identifier) + self.assertEqual(len(files), len(design.Documents)) - def test_PackageBody(self): + def test_Display(self): design = Design() - document = Document(self._filename) - design.Documents.append(document) + files = ( + Path("Utilities.pkg.vhdl"), + Path("StopWatch.pkg.vhdl"), + Path("Counter.vhdl"), + Path("seg7_Encoder.vhdl"), + Path("seg7_Display.vhdl"), + Path("toplevel.Display.vhdl"), + ) + for file in files: + document = Document(self._sourceDirectory / file) + design.Documents.append(document) - self.assertEqual(1, len(design.Documents[0].PackageBodies)) - self.assertEqual("pack_1", design.Documents[0].PackageBodies[0].Identifier) + self.assertEqual(len(files), len(design.Documents)) + + def test_StopWatch(self): + design = Design() + files = ( + Path("Utilities.pkg.vhdl"), + Path("StopWatch.pkg.vhdl"), + Path("Counter.vhdl"), + Path("seg7_Encoder.vhdl"), + Path("seg7_Display.vhdl"), + Path("StopWatch.vhdl"), + Path("Debouncer.vhdl"), + Path("toplevel.StopWatch.vhdl"), + ) + for file in files: + document = Document(self._sourceDirectory / file) + design.Documents.append(document) + + self.assertEqual(len(files), len(design.Documents)) diff --git a/testsuite/pyunit/dom/examples/StopWatch/Counter.vhdl b/testsuite/pyunit/dom/examples/StopWatch/Counter.vhdl new file mode 100644 index 000000000..3ef284b98 --- /dev/null +++ b/testsuite/pyunit/dom/examples/StopWatch/Counter.vhdl @@ -0,0 +1,45 @@ +-- Author: Patrick Lehmann +-- License: MIT +-- +-- A generic counter module used in the StopWatch example. +-- +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +use work.Utilities.all; + + +entity Counter is + generic ( + MODULO : positive; + BITS : natural := log2(MODULO) + ); + port ( + Clock : in std_logic; + Reset : in std_logic; + Enable : in std_logic; + + Value : out unsigned(BITS - 1 downto 0); + WrapAround : out std_logic + ); +end entity; + + +architecture rtl of Counter is + signal CounterValue : unsigned(log2(MODULO) - 1 downto 0) := (others => '0'); +begin + process (Clock) + begin + if rising_edge(Clock) then + if ((Reset or WrapAround) = '1') then + CounterValue <= (others => '0'); + elsif (Enable = '1') then + CounterValue <= CounterValue + 1; + end if; + end if; + end process; + + Value <= resize(CounterValue, BITS); + WrapAround <= Enable when (CounterValue = MODULO - 1) else '0'; +end architecture; diff --git a/testsuite/pyunit/dom/examples/StopWatch/Debouncer.vhdl b/testsuite/pyunit/dom/examples/StopWatch/Debouncer.vhdl new file mode 100644 index 000000000..18207c7f1 --- /dev/null +++ b/testsuite/pyunit/dom/examples/StopWatch/Debouncer.vhdl @@ -0,0 +1,58 @@ +-- Author: Patrick Lehmann +-- License: MIT +-- +-- A generic counter module used in the StopWatch example. +-- +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +use work.Utilities.all; + + +entity Debouncer is + generic ( + CLOCK_PERIOD : time := 10 ns; + DEBOUNCE_TIME : time := 3 ms; + + BITS : positive + ); + port ( + Clock : in std_logic; + + Input : in std_logic_vector(BITS - 1 downto 0); + Output : out std_logic_vector(BITS - 1 downto 0) := (others => '0') + ); +end entity; + +architecture rtl of Debouncer is + constant DEBOUNCE_COUNTER_MAX : positive := DEBOUNCE_TIME / (CLOCK_PERIOD* ite(IS_SIMULATION, 20, 1)); + constant DEBOUNCE_COUNTER_BITS : positive := log2(DEBOUNCE_COUNTER_MAX); + +begin + assert false report "CLOCK_PERIOD: " & time'image(CLOCK_PERIOD); + assert false report "DEBOUNCE_TIME: " & time'image(DEBOUNCE_TIME); + --assert false report "DEBOUNCE_COUNTER_MAX: " & to_string(10 ns); + --assert false report "INTEGER'high: " & integer'image(integer'high); + + genBits: for i in Input'range generate + signal DebounceCounter : signed(DEBOUNCE_COUNTER_BITS downto 0) := to_signed(DEBOUNCE_COUNTER_MAX - 3, DEBOUNCE_COUNTER_BITS + 1); + begin + process (Clock) + begin + if rising_edge(Clock) then + -- restart counter, whenever Input(i) was unstable within DEBOUNCE_TIME_MS + if (Input(i) /= Output(i)) then + DebounceCounter <= DebounceCounter - 1; + else + DebounceCounter <= to_signed(DEBOUNCE_COUNTER_MAX - 3, DebounceCounter'length); + end if; + + -- latch input bit, if input was stable for DEBOUNCE_TIME_MS + if (DebounceCounter(DebounceCounter'high) = '1') then + Output(i) <= Input(i); + end if; + end if; + end process; + end generate; +end architecture; diff --git a/testsuite/pyunit/dom/examples/StopWatch/StopWatch.pkg.vhdl b/testsuite/pyunit/dom/examples/StopWatch/StopWatch.pkg.vhdl new file mode 100644 index 000000000..3bcafdd6d --- /dev/null +++ b/testsuite/pyunit/dom/examples/StopWatch/StopWatch.pkg.vhdl @@ -0,0 +1,21 @@ +-- Author: Patrick Lehmann +-- License: MIT +-- +-- A generic counter module used in the StopWatch example. +-- +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + + +package StopWatch_pkg is + subtype T_BCD is unsigned(3 downto 0); + type T_BCD_Vector is array(natural range <>) of T_BCD; + + type T_DIGIT_CONFIGURATION is record + Modulo : positive; + Dot : std_logic; + end record; + + type T_STOPWATCH_CONFIGURATION is array(natural range <>) of T_DIGIT_CONFIGURATION; +end package; diff --git a/testsuite/pyunit/dom/examples/StopWatch/StopWatch.vhdl b/testsuite/pyunit/dom/examples/StopWatch/StopWatch.vhdl new file mode 100644 index 000000000..c7c9068ab --- /dev/null +++ b/testsuite/pyunit/dom/examples/StopWatch/StopWatch.vhdl @@ -0,0 +1,127 @@ +-- Author: Patrick Lehmann +-- License: MIT +-- +-- A generic counter module used in the StopWatch example. +-- +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +use work.Utilities.all; +use work.StopWatch_pkg.all; + + +entity Stopwatch is + generic ( + CLOCK_PERIOD : time := 10 ns; + + TIMEBASE : time; + CONFIG : T_STOPWATCH_CONFIGURATION + ); + port ( + Clock : in std_logic; + Reset : in std_logic; + + Start : in std_logic; + + Digits : out T_BCD_Vector(CONFIG'length - 1 downto 0); + Dots : out std_logic_vector(CONFIG'length - 1 downto 0) + ); +end entity; + + +architecture trl of Stopwatch is + type T_STATE is (ST_RESET, ST_IDLE, ST_COUNTING, ST_PAUSE); + + signal State : T_STATE := ST_IDLE; + signal NextState : T_STATE; + + signal FSM_Reset : std_logic; + signal FSM_Enable : std_logic; + + signal Tick : std_logic; + signal Overflows : std_logic_vector(CONFIG'length downto 0); + + +begin + process(Clock) + begin + if rising_edge(Clock) then + if (Reset = '1') then + State <= ST_RESET; + else + State <= NextState; + end if; + end if; + end process; + + process(State, Start) + begin + NextState <= State; + + FSM_Reset <= '0'; + FSM_Enable <= '0'; + + case State is + when ST_RESET => + FSM_Reset <= '1'; + NextState <= ST_IDLE; + + when ST_IDLE => + if (Start = '1') then + NextState <= ST_COUNTING; + end if; + + when ST_COUNTING => + FSM_Enable <= '1'; + + if (Start = '1') then + NextState <= ST_PAUSE; + end if; + + when ST_PAUSE => + if (Start = '1') then + NextState <= ST_COUNTING; + end if; + + when others => + NextState <= ST_RESET; + + end case; + end process; + + TimeBaseCnt: entity work.Counter + generic map ( + MODULO => TIMEBASE / (CLOCK_PERIOD * ite(IS_SIMULATION, 100, 1)), + BITS => 0 + ) + port map ( + Clock => Clock, + Reset => FSM_Reset, + Enable => FSM_Enable, + + Value => open, + WrapAround => Tick + ); + + Overflows(0) <= Tick; + + genDigits: for i in CONFIG'range generate + cnt: entity work.Counter + generic map ( + MODULO => CONFIG(i).Modulo, + BITS => Digits(i)'length + ) + port map ( + Clock => Clock, + Reset => FSM_Reset, + Enable => Overflows(i), + + Value => Digits(i), + WrapAround => Overflows(i + 1) + ); + + Dots(i) <= CONFIG(i).Dot; + end generate; + +end architecture; diff --git a/testsuite/pyunit/dom/examples/StopWatch/Utilities.pkg.vhdl b/testsuite/pyunit/dom/examples/StopWatch/Utilities.pkg.vhdl new file mode 100644 index 000000000..8daf39614 --- /dev/null +++ b/testsuite/pyunit/dom/examples/StopWatch/Utilities.pkg.vhdl @@ -0,0 +1,99 @@ +-- Author: Patrick Lehmann +-- License: MIT +-- +-- A generic counter module used in the StopWatch example. +-- +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + + +package Utilities is + type freq is range integer'low to integer'high units + Hz; + kHz = 1000 Hz; + MHz = 1000 kHz; + GHz = 1000 MHz; + THz = 1000 GHz; + end units; + + -- deferred constant + constant IS_SIMULATION : boolean; + + function ite(condition : boolean; ThenValue : integer; ElseValue : integer) return integer; + + function log2(Value : positive) return positive; + + function bin2onehot(binary : std_logic_vector; bits : natural := 0) return std_logic_vector; + function bin2onehot(binary : unsigned; bits : natural := 0) return std_logic_vector; + + function to_index(value : unsigned; max : positive) return natural; + function to_index(value : natural; max : positive) return natural; +end package; + + +package body Utilities is + function simulation return boolean is + variable result : boolean := FALSE; + begin + -- synthesis translate_off + result := TRUE; + -- synthesis translate_on + return result; + end function; + + -- deferred constant initialization + constant IS_SIMULATION : boolean := simulation; + + function ite(condition : boolean; ThenValue : integer; ElseValue : integer) return integer is + begin + if condition then + return ThenValue; + else + return ElseValue; + end if; + end function; + + function log2(Value : positive) return positive is + variable twosPower : natural := 1; + variable result : natural := 0; + begin + while (twosPower < Value) loop + twosPower := twosPower * 2; + result := result + 1; + end loop; + return result; + end function; + + function bin2onehot(binary : std_logic_vector; bits : natural := 0) return std_logic_vector is + begin + return bin2onehot(unsigned(binary), bits); + end function; + + function bin2onehot(binary : unsigned; bits : natural := 0) return std_logic_vector is + variable result : std_logic_vector(2**binary'length - 1 downto 0) := (others => '0'); + begin + result(to_integer(binary)) := '1'; + + if (bits = 0) then + return result; + else + return result(bits - 1 downto 0); + end if; + end function; + + function to_index(value : unsigned; max : positive) return natural is + begin + return to_index(to_integer(value), max); + end function; + + function to_index(value : natural; max : positive) return natural is + begin + if (value <= max) then + return value; + else + return max; + end if; + -- return minimum(value, max); + end function; +end package body; diff --git a/testsuite/pyunit/dom/examples/StopWatch/seg7_Display.vhdl b/testsuite/pyunit/dom/examples/StopWatch/seg7_Display.vhdl new file mode 100644 index 000000000..c3771ba68 --- /dev/null +++ b/testsuite/pyunit/dom/examples/StopWatch/seg7_Display.vhdl @@ -0,0 +1,90 @@ +-- Author: Patrick Lehmann +-- License: MIT +-- +-- A generic counter module used in the StopWatch example. +-- +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +use work.Utilities.all; +use work.StopWatch_pkg.all; + + +entity seg7_Display is + generic ( + CLOCK_PERIOD : time := 10 ns; + REFRESH_RATE : time := 200 us; + DIGITS : positive + ); + port ( + Clock : in std_logic; + + DigitValues : in T_BCD_Vector(DIGITS - 1 downto 0); + DotValues : in std_logic_vector(DIGITS - 1 downto 0) := (others => '0'); + + Seg7_Segments : out std_logic_vector(7 downto 0); + Seg7_Selects : out std_logic_vector(DIGITS - 1 downto 0) + ); +end entity; + + +architecture rtl of seg7_Display is + constant TIMEBASE_COUNTER_MAX : positive := REFRESH_RATE / (CLOCK_PERIOD * ite(IS_SIMULATION, 1_000, 1)); + + signal Timebase_Counter : unsigned(log2(TIMEBASE_COUNTER_MAX) - 1 downto 0) := (others => '0'); + signal Timebase_Tick : std_logic; + + signal Digit_Select : unsigned(log2(DIGITS) - 1 downto 0) := (others => '0'); + signal Digit_Select_ov : std_logic; + + signal Digit : T_BCD; + signal Dot : std_logic; +begin + -- refresh rate + process(Clock) + begin + if rising_edge(Clock) then + if (Timebase_Tick = '1') then + Timebase_Counter <= (others => '0'); + else + Timebase_Counter <= Timebase_Counter + 1; + end if; + end if; + end process; + + Timebase_Tick <= '1' when (Timebase_Counter = TIMEBASE_COUNTER_MAX - 1) else '0'; + + + -- counter to select digits (time multiplexing) + process(Clock) + begin + if rising_edge(Clock) then + if (Timebase_Tick = '1') then + if (Digit_Select_ov = '1') then + Digit_Select <= (others => '0'); -- to_unsigned(5, Digit_Select'length); + else + Digit_Select <= Digit_Select + 1; + end if; + end if; + end if; + end process; + + Digit_Select_ov <= '1' when (Digit_Select = DIGITS - 1) else '0'; + + -- multiplexer + Digit <= DigitValues(to_index(Digit_Select, DigitValues'high)); + Dot <= DotValues(to_index(Digit_Select, DotValues'high)); + + -- 7-segment encoder + enc: entity work.seg7_Encoder + port map ( + BCDValue => Digit, + Dot => Dot, + + Seg7Code => Seg7_Segments + ); + + + Seg7_Selects <= bin2onehot(Digit_Select, DIGITS); +end architecture; diff --git a/testsuite/pyunit/dom/examples/StopWatch/seg7_Encoder.vhdl b/testsuite/pyunit/dom/examples/StopWatch/seg7_Encoder.vhdl new file mode 100644 index 000000000..e4c731ff9 --- /dev/null +++ b/testsuite/pyunit/dom/examples/StopWatch/seg7_Encoder.vhdl @@ -0,0 +1,46 @@ +-- Author: Patrick Lehmann +-- License: MIT +-- +-- A generic counter module used in the StopWatch example. +-- +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +use work.Utilities.all; +use work.StopWatch_pkg.all; + + +entity seg7_Encoder is + port ( + BCDValue : in T_BCD; + Dot : in std_logic := '0'; + + Seg7Code : out std_logic_vector(7 downto 0) + ); +end entity; + + +architecture rtl of seg7_Encoder is + +begin + process(BCDValue, Dot) + variable temp : std_logic_vector(6 downto 0); + begin + case BCDValue is -- segments: GFEDCBA -- Segment Pos. Index Pos. + when x"0" => temp := "0111111"; -- + when x"1" => temp := "0000110"; -- + when x"2" => temp := "1011011"; -- AAA 000 + when x"3" => temp := "1001111"; -- F B 5 1 + when x"4" => temp := "1100110"; -- F B 5 1 + when x"5" => temp := "1101101"; -- GGG 666 + when x"6" => temp := "1111101"; -- E C 4 2 + when x"7" => temp := "0000111"; -- E C 4 2 + when x"8" => temp := "1111111"; -- DDD DOT 333 7 + when x"9" => temp := "1101111"; -- + when others => temp := "XXXXXXX"; -- + end case; + + Seg7Code <= Dot & temp; + end process; +end architecture; diff --git a/testsuite/pyunit/dom/examples/StopWatch/toplevel.Display.vhdl b/testsuite/pyunit/dom/examples/StopWatch/toplevel.Display.vhdl new file mode 100644 index 000000000..67228a5ac --- /dev/null +++ b/testsuite/pyunit/dom/examples/StopWatch/toplevel.Display.vhdl @@ -0,0 +1,65 @@ +-- Author: Patrick Lehmann +-- License: MIT +-- +-- A generic counter module used in the StopWatch example. +-- +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +use work.Utilities.all; +use work.StopWatch_pkg.all; + + +entity toplevel is + generic ( + constant CLOCK_PERIOD : time := 10 ns + ); + port ( + NexysA7_SystemClock : in std_logic; + + NexysA7_GPIO_Switch : in std_logic_vector(15 downto 0); + + NexysA7_GPIO_Seg7_Cathode_n : out std_logic_vector(7 downto 0); + NexysA7_GPIO_Seg7_Anode_n : out std_logic_vector(7 downto 0) + ); +end entity; + + +architecture rtl of toplevel is + signal Digits : T_BCD_Vector(5 downto 0); + + signal Cathode : std_logic_vector(7 downto 0); + signal Anode : std_logic_vector(Digits'range); + +begin + -- connect switches to first 4 digits + genDigits: for i in 0 to 3 generate + Digits(i) <= unsigned(NexysA7_GPIO_Switch(i * 4 + 3 downto i * 4)); + end generate; + + -- do arithmetic calculations on next 2 digits + Digits(4) <= Digits(1) + Digits(0); + Digits(5) <= Digits(3) - Digits(2); + + + -- 7-segment display + display: entity work.seg7_Display + generic map ( + CLOCK_PERIOD => CLOCK_PERIOD, + DIGITS => Digits'length + ) + port map ( + Clock => NexysA7_SystemClock, + + DigitValues => Digits, + DotValues => 6d"16", + + Seg7_Segments => Cathode, + Seg7_Selects => Anode + ); + + -- convert low-active outputs + NexysA7_GPIO_Seg7_Cathode_n <= not Cathode; + NexysA7_GPIO_Seg7_Anode_n <= not ((NexysA7_GPIO_Seg7_Anode_n'high downto Anode'length => '0') & Anode); +end architecture; diff --git a/testsuite/pyunit/dom/examples/StopWatch/toplevel.Encoder.vhdl b/testsuite/pyunit/dom/examples/StopWatch/toplevel.Encoder.vhdl new file mode 100644 index 000000000..7775a6eb6 --- /dev/null +++ b/testsuite/pyunit/dom/examples/StopWatch/toplevel.Encoder.vhdl @@ -0,0 +1,42 @@ +-- Author: Patrick Lehmann +-- License: MIT +-- +-- A generic counter module used in the StopWatch example. +-- +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +use work.Utilities.all; +use work.StopWatch_pkg.all; + + +entity toplevel is + port ( + NexysA7_GPIO_Switch : in std_logic_vector(3 downto 0); + + NexysA7_GPIO_Seg7_Cathode_n : out std_logic_vector(7 downto 0); + NexysA7_GPIO_Seg7_Anode_n : out std_logic_vector(7 downto 0) + ); +end entity; + + +architecture rtl of toplevel is + signal Cathode : std_logic_vector(7 downto 0); + signal Anode : std_logic_vector(7 downto 0); + +begin + + -- 7-segment encoder + encoder: entity work.seg7_Encoder + port map ( + BCDValue => unsigned(NexysA7_GPIO_Switch), + Dot => '1', + + Seg7Code => Cathode + ); + + -- convert low-active outputs + NexysA7_GPIO_Seg7_Cathode_n <= not Cathode; + NexysA7_GPIO_Seg7_Anode_n <= not x"01"; +end architecture; diff --git a/testsuite/pyunit/dom/examples/StopWatch/toplevel.StopWatch.tb.vhdl b/testsuite/pyunit/dom/examples/StopWatch/toplevel.StopWatch.tb.vhdl new file mode 100644 index 000000000..a334475c4 --- /dev/null +++ b/testsuite/pyunit/dom/examples/StopWatch/toplevel.StopWatch.tb.vhdl @@ -0,0 +1,58 @@ +-- Author: Patrick Lehmann +-- License: MIT +-- +-- A generic counter module used in the StopWatch example. +-- +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +library lib_StopWatch; +use lib_StopWatch.Utilities.all; +use lib_StopWatch.StopWatch_pkg.all; + + +entity toplevel_tb is +end entity; + + +architecture tb of toplevel_tb is + constant CLOCK_PERIOD : time := 10 ns; + + signal StopSimulation : std_logic := '0'; + signal Clock : std_logic := '1'; + signal Reset : std_logic := '1'; + + signal StartButton : std_logic := '0'; + +begin + StopSimulation <= '1' after 30 ms; + + Clock <= (Clock xnor StopSimulation) after CLOCK_PERIOD / 2; + Reset <= '0' after 2 us, + '1' after 3 us, + '0' after 20 ms, + '1' after 20 ms + 2 us; + StartButton <= '1' after 10 us, + '0' after 15 us, + '1' after 10 ms, + '0' after 10 ms + 1 us, + '1' after 12 ms, + '0' after 12 ms + 2 us, + '1' after 22 ms, + '0' after 22 ms + 2 us; + + DUT: entity lib_StopWatch.toplevel + generic map ( + CLOCK_PERIOD_NS => CLOCK_PERIOD / 1 ns + ) + port map ( + Clock => Clock, + Reset_n => Reset, + + Button(0) => StartButton, + Seg7_Cathode_n => open, + Seg7_Anode_n => open + ); + +end architecture; diff --git a/testsuite/pyunit/dom/examples/StopWatch/toplevel.StopWatch.vhdl b/testsuite/pyunit/dom/examples/StopWatch/toplevel.StopWatch.vhdl new file mode 100644 index 000000000..1c8547446 --- /dev/null +++ b/testsuite/pyunit/dom/examples/StopWatch/toplevel.StopWatch.vhdl @@ -0,0 +1,118 @@ +-- Author: Patrick Lehmann +-- License: MIT +-- +-- A generic counter module used in the StopWatch example. +-- +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +use work.Utilities.all; +use work.StopWatch_pkg.all; + + +entity toplevel is + generic ( + constant CLOCK_PERIOD : time := 10 ns + ); + port ( + NexysA7_SystemClock : in std_logic; + NexysA7_GPIO_Button_Reset_n : in std_logic; + + NexysA7_GPIO_Button : in std_logic_vector(0 downto 0); + NexysA7_GPIO_Seg7_Cathode_n : out std_logic_vector(7 downto 0); + NexysA7_GPIO_Seg7_Anode_n : out std_logic_vector(7 downto 0) + ); +end entity; + + +architecture rtl of toplevel is + constant STOPWATCH_CONFIGURATION : T_STOPWATCH_CONFIGURATION := ( + 0 => (Modulo => 10, Dot => '0'), + 1 => (Modulo => 10, Dot => '0'), + 2 => (Modulo => 10, Dot => '0'), + 3 => (Modulo => 6, Dot => '0'), + 4 => (Modulo => 10, Dot => '0'), + 5 => (Modulo => 6, Dot => '0') + ); + + signal Board_Reset : std_logic; + + signal Deb_Reset : std_logic; + signal Deb_Start : std_logic; + signal Deb_Start_d : std_logic := '0'; + signal Deb_Start_re : std_logic; + + signal Reset : std_logic; + signal Start : std_logic; + + + signal Digits : T_BCD_Vector(STOPWATCH_CONFIGURATION'length - 1 downto 0); + + signal Cathode : std_logic_vector(7 downto 0); + signal Anode : std_logic_vector(Digits'range); + +begin + -- convert from low-active inputs + Board_Reset <= not NexysA7_GPIO_Button_Reset_n; + + -- Debounce input signals + deb: entity work.Debouncer + generic map ( + CLOCK_PERIOD => CLOCK_PERIOD, + BITS => 2 + ) + port map ( + Clock => NexysA7_SystemClock, + + Input(0) => Board_Reset, + Input(1) => NexysA7_GPIO_Button(0), + Output(0) => Deb_Reset, + Output(1) => Deb_Start + ); + + Reset <= Deb_Reset; + + -- Rising edge detection + Deb_Start_d <= Deb_Start when rising_edge(NexysA7_SystemClock); + Deb_Start_re <= not Deb_Start_d and Deb_Start; + + -- renaming + Start <= Deb_Start_re; + + -- Stopwatch + sw: entity work.Stopwatch + generic map ( + CLOCK_PERIOD => CLOCK_PERIOD, + + TIMEBASE => 10 ms, + CONFIG => STOPWATCH_CONFIGURATION + ) + port map ( + Clock => NexysA7_SystemClock, + Reset => Reset, + + Start => Start, + + Digits => Digits + ); + + -- 7-segment display + display: entity work.seg7_Display + generic map ( + CLOCK_PERIOD => CLOCK_PERIOD, + DIGITS => Digits'length + ) + port map ( + Clock => NexysA7_SystemClock, + + DigitValues => Digits, + + Seg7_Segments => Cathode, + Seg7_Selects => Anode + ); + + -- convert to low-active outputs + NexysA7_GPIO_Seg7_Cathode_n <= not Cathode; + NexysA7_GPIO_Seg7_Anode_n <= not ((NexysA7_GPIO_Seg7_Anode_n'high downto Anode'length => '0') & Anode); +end architecture; |