You are almost done, all what's left is to get the logic equations from the table. Remember that w is an input so it is part of the present state and we will use it to compute values of the next state.
Let w be a 2 bit number, $$w = w_1w_0$$
so if we let A = 00, B = 01, and C = 11 then:
$$
w = \left.\begin{cases} \bar{w_1} \bar{w_0}
& w = A\\ \\ w_1 \bar{w_0} & w = B\\ \\
w_1 w_0 & w = C \end{cases} \right\} \\ \\
$$
and the 5 states are
$$
S_i = \left. \begin{cases}
\bar{y_2 }\bar{y_1 }\bar{y_0 }& i = 1 \\ \\
\bar{y_2 }\bar{y_1 } y_0 & i = 2 \\ \\
\bar{y_2 } y_1 \bar{y_0 } & i = 3 \\ \\
\bar{y_2 } y_1 y_0 & i = 4 \\ \\
y_2 \bar{y_1} \bar{y_0 } & i = 5
\end{cases} \right\}
$$
To get the logic for computing the next state you get the boolean equation for each bit of the next state separately.E.g to get the logic for computing y0 :
$$
y_{0 , next} = S_1 A + S_2 A + S_3A + S_3 C + S_4 A + S_5 A
$$
$$
y_{0, next} = \bar{y_2 }\bar{y_1 }\bar{y_0 } \bar{w_1} \bar{w_0}
+ \bar{y_2 }\bar{y_1 } y_0 \bar{w_1} \bar{w_0}
+ \bar{y_2 } y_1 \bar{y_0 } \bar{w_1} \bar{w_0}
+ \bar{y_2 } y_1 \bar{y_0 } w_1 w_0
+ \bar{y_2 } y_1 y_0 \bar{w_1} \bar{w_0}
+ y_2 \bar{y_1} \bar{y_0 } \bar{w_1} \bar{w_0}
$$
which reduces to
$$
y_{0, next} = \bar{w_1}\bar{w_0} + \bar{y_2 } y_1 \bar{y_0 } w_1 w_0
$$
Repeat this for y2 and y1, to get the rest of the combinational logic required.
The output(z) is high when this state machine is in state 5 so Z will be given by:
$$
z = S_5 = y_2 \bar{y_1} \bar{y_0 }
$$
This is a moore machine as Z is only dependent on the current state.
What you can do is create an idle state, and when you detect a button press you switch straight to the idle. Then you can have a counter in idle which waits for a while before you start scanning buttons again.
For example:
-- include numeric std
signal idle_counter : unsigned(31 downto 0);
...
when state3 =>
case bcd_val is
when "01" =>
Send <= '1';
scannel_val <= "0101";
fsm_state <= idle; -- switch to idle
when "10" =>
Send <= '1';
scannel_val <= "0110";
fsm_state <= idle; -- switch to idle
when others =>
scannel_val <= "0000";
Send <= '0';
fsm_state <= state1; -- carry on scanning
end case;
idle_counter <= (others => '0');
...
when idle =>
if (idle_counter < some_timeout) then -- some_timeout is how long you want to wait (in clock cycles)
idle_counter <= idle_counter + "1"; -- increment counter
fsm_state <= idle; -- stay here
else
idle_counter <= (others => '0'); -- reset counter
fsm_state <= state1; -- go back into checking
end
--scannel_val is valid here, so you can do something with it if you'd like.
...
when others => scannel_val <= "0000";
There is one process in this code you've posted.
It starts with
scan_fsm : process (reset, clk) <= Sensitivity list
begin -- process key_scanner
and ends with
end process scan_fsm;
The clock and reset are part of the sensitivity list. That means that this code is only going to be triggered when either clock changes or reset changes.
De-bouncing can be done in a separate process.
Basically, you want to make sure that the button was pressed for a number of microseconds before it triggers. What we want to do is save the value of the input for a number of clock cycles. Then only register a 1 when the history has been constantly 1 for for the past 32 clock cycles.
Example:
-- these are our row inputs (to become bdc_val)
signal row1 : in std_logic;
signal row2 : in std_logic;
...
-- this is our history vector
signal row1_z : std_logic_vector(31 downto 0);
signal row2_z : std_logic_vector(31 downto 0);
-- debounced signal
signal bcd_val : std_logic_vector(1 downto 0);
-- a whole vector of ones for convenience
signal ones : std_logic_vector(31 downto 0);
...
ones <= (others => '1');
-- generate our histories
gen_z : process (reset, clk)
begin
if (reset = '1') then
row1_z <= (others => '0');
row2_z <= (others => '0');
bcd_val <= (others => '0');
elsif (rising_edge(clk)) then
row1_z(31 downto 1) <= row1_z(30 downto 0); -- shift everything up 1
row1_z(0) <= row1; -- save the most recent input
row2_z(31 downto 1) <= row2_z(30 downto 0); -- shift everything up 1
row2_z(0) <= row2; -- save the most recent input
-- we only want bcd_val to be 1 when the entire row history for the past 32 cc is 1
if (row1_z = ones) then
bcd_val(0) <= '1';
else
bcd_val(0) <= '0';
end
if (row2_z = ones) then
bcd_val(1) <= '1';
else
bcd_val(1) <= '0';
end
end
end
Best Answer
You can either do it the traditional way with pen, ink, state tables, the TTL Data Book, or simply write it directly in VHDL or Verilog, following the partial example below.
Which approach is best depends on circumstances.
If this is homework, you probably have to do the former.
If you're being paid to get things done, and you don't do the latter, start looking for a new job.