Salta ai contenuti. | Salta alla navigazione

Strumenti personali

gcd RTL (FSM estesa)

VHDL document icon 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;