gcd RTL (FSM estesa)
gcdsm.vhd
—
VHDL document,
2 kB (2619 bytes)
Contenuto del file
-- extended FSM version of the gcd evaluator, synthesizable with a few
-- adjustments
library IEEE;
use IEEE.STD_LOGIC_1164.all,ieee.numeric_std.all;
entity gcd_efsm is
port(
start : in STD_LOGIC;
clk : in STD_LOGIC;
a : in STD_LOGIC_VECTOR(7 downto 0);
b : in STD_LOGIC_VECTOR(7 downto 0);
err : out STD_LOGIC;
dr : out STD_LOGIC;
gcd : out STD_LOGIC_VECTOR(7 downto 0)
);
end gcd_efsm;
-- Mealy machine
-- a,b should be steady at start, any change after start is ignored
-- the error and the data redy signal are provided for one clock cycle
architecture behav of gcd_efsm is
type states is (idle,check,test1,test2,sub1,sub2,output,err_state);
signal curr_state,next_state: states;
begin
-- next state and output logic
p0: process(curr_state,start,a,b)
constant zero:unsigned(7 downto 0):=(others=>'0');
variable vara,varb: unsigned(7 downto 0);
begin
case curr_state is
when idle =>
if (start='1') then
next_state <= check;
vara:=unsigned(a);
varb:=unsigned(b);
end if;
dr <= '0' after 1 ns;
err <= '0' after 1 ns;
when check =>
if (vara=zero) or (varb=zero) or (is_x(a)) or (is_x(b)) then
next_state <= err_state;
gcd <= (others=>'0');
else
next_state <= test1;
end if;
dr <= '0' after 1 ns;
err <= '0' after 1 ns;
when test1 =>
if (vara = varb) then
next_state <= output;
else
next_state <= test2;
end if;
dr <= '0' after 1 ns;
err <= '0' after 1 ns;
when test2 =>
if (vara > varb) then
next_state <= sub1;
else
next_state <= sub2;
end if;
dr <= '0' after 1 ns;
err <= '0' after 1 ns;
when sub1 =>
next_state <= test1;
vara:=vara-varb;
dr <= '0' after 1 ns;
err <= '0' after 1 ns;
when sub2 =>
next_state <= test1;
varb:=varb-vara;
dr <= '0' after 1 ns;
err <= '0' after 1 ns;
when output =>
next_state <= idle;
dr <= '1' after 1 ns;
err <= '0' after 1 ns;
gcd <= std_logic_vector(vara);
when err =>
next_state <= idle;
dr <= '0';
err <= '1';
-- useful when encoding
when others =>
next_state <= idle;
dr <= '0' after 1 ns;
err <= '1' after 1 ns;
end case;
end process p0;
-- state update
p1: process(clk)
begin
if (rising_edge(clk)) then
curr_state <= next_state;
end if;
end process p1;
end architecture behav;