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;