aboutsummaryrefslogtreecommitdiffstats
path: root/testsuite/pyunit/dom/examples/StopWatch/StopWatch.vhdl
blob: 87a147833d4c55430c3760141f6137f49890fa2a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
-- 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_Utilities;
use     lib_Utilities.Utilities_pkg.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 rtl 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 lib_Utilities.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 lib_Utilities.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;