VHDL:有限状态机中的默认值
VHDL: Default values in a Finite State Machine
我正在尝试制作一个基于串行输入切换状态的有限状态机。我需要一些关于我的代码是如何执行的解释。我在一本教科书中读到,我在过程中标记 "DEFAULT VALUES" 的部分是我应该放置默认值的地方。但是,每当我切换状态时,我的信号似乎都采用这些值。例如,我将 state_next 设置为 idle 作为默认值。这样做导致FSM无缘无故地从其他状态继续跳到idle。
我的另一个问题是说明 FSM 的整个过程是如何执行的。当我从一种状态移动到另一种状态时,是否应该执行 case 语句之前的部分(标记为 DEFAULT VALUES 的部分)?还是仅当我从某个较晚的状态移回空闲状态时才执行?什么时候应该执行 DEFAULT VALUES 部分?
我的代码如下所示。请参阅 "Next-State Logic" 部分。
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity delay_incrementor is
generic ( delay_ports : natural := 3;
width_ports : natural := 3
);
Port ( clk,reset: in STD_LOGIC;
update : in STD_LOGIC;
in_data : in STD_LOGIC_VECTOR (7 downto 0);
led : out STD_LOGIC_VECTOR (2 downto 0);
out_data : out STD_LOGIC_VECTOR (7 downto 0);
d_big,d_mini,d_opo : inout STD_LOGIC_VECTOR (25 downto 0);
w_big,w_mini,w_opo : inout STD_LOGIC_VECTOR (25 downto 0));
end delay_incrementor;
architecture fsm_arch of delay_incrementor is
type state_type is (idle,channel,d_or_w,delay_channel,delay_channel_inc,width_channel,width_channel_inc);
type delay_file_type is array (delay_ports-1 downto 0) of std_logic_vector (25 downto 0);
type width_file_type is array(width_ports-1 downto 0) of std_logic_vector (25 downto 0);
signal d_reg,d_next,d_succ: delay_file_type;
signal w_reg,w_next,w_succ: width_file_type;
signal state_reg,state_next: state_type;
signal which_channel,which_channel_next: natural;
begin
--------------------------------------
--State Register
--------------------------------------
process(clk,reset)
begin
if reset='1' then
state_reg <= idle;
d_reg <= (others => (others => '0'));
w_reg <= (others => (others => '0'));
which_channel <= 0;
elsif (clk='1' and clk'event) then
state_reg <= state_next;
d_reg <= d_next;
w_reg <= w_next;
which_channel <= which_channel_next;
end if;
end process;
--------------------------------------
--Next-State Logic/Output Logic
--------------------------------------
process(state_reg,in_data,d_reg,w_reg,which_channel)
begin
state_next <= idle; --DEFAULT VALUES
d_succ <= d_reg;
w_succ <= w_reg;
which_channel_next <= 0;
case state_reg is
when idle =>
if in_data = "01100011" then --"c"
state_next <= channel;
which_channel_next <= 0;
end if;
when channel =>
if (48 <= unsigned(in_data)) and (unsigned(in_data)<= 57) then
which_channel_next <= (to_integer(unsigned(in_data))-48);
state_next <= d_or_w;
elsif in_data = "00100011" then --"#"
state_next <= idle;
which_channel_next <= which_channel;
end if;
when d_or_w =>
if in_data = "01100100" then --"d"
state_next <= delay_channel;
elsif in_data = "01110111" then --"w"
state_next <= width_channel;
elsif in_data = "00100011" then --"#"
state_next <= idle;
end if;
when delay_channel =>
if in_data = "01101001" then --"i"
state_next <= delay_channel_inc;
elsif in_data = "00100011" then --"#"
state_next <= idle;
end if;
when delay_channel_inc =>
if in_data = "01110101" then --"u"
d_succ(which_channel) <= std_logic_vector(unsigned(d_reg(which_channel))+250);
elsif in_data = "01100100" then --"d"
d_succ(which_channel) <= std_logic_vector(unsigned(d_reg(which_channel))-250);
else
d_succ(which_channel) <= d_reg(which_channel);
end if;
if in_data = "00100011" then --"#"
state_next <= idle;
end if;
when width_channel =>
if in_data = "01101001" then --"i"
state_next <= width_channel_inc;
elsif in_data = "00100011" then --"#"
state_next <= idle;
end if;
when width_channel_inc =>
if in_data = "01110101" then --"u"
w_succ(which_channel) <= std_logic_vector(unsigned(w_reg(which_channel))+250);
elsif in_data = "01100100" then --"d"
w_succ(which_channel) <= std_logic_vector(unsigned(w_reg(which_channel))-250);
else
w_succ(which_channel) <= w_reg(which_channel);
end if;
if in_data = "00100011" then --"#"
state_next <= idle;
end if;
end case;
end process;
process(update,d_reg,w_reg,reset)
begin
if reset='1' then
d_next <= (others => (others =>'0'));
w_next <= (others => (others =>'0'));
elsif (update'event and update='1') then
d_next <= d_succ;
w_next <= w_succ;
else
d_next <= d_reg;
w_next <= w_reg;
end if;
end process;
--------------------------------------
--Output Logic
--------------------------------------
d_big <= d_reg(0);
d_mini <= d_reg(1);
d_opo <= d_reg(2);
w_big <= w_reg(0);
w_mini <= w_reg(1);
w_opo <= w_reg(2);
end fsm_arch;
每当列出的信号之一发生变化时,都会评估一个过程。因此这个列表被称为 'sensitivity list'.
有两种类型的进程:
- 顺序的(带有时钟信号)和
- 组合(只是简单的逻辑)。
第一种只需要灵敏度列表中的时钟信号,后者需要每个右手边的信号,否则仿真会显示与真实硬件不同的结果。
因此,每次输入信号发生变化时('event = true),都会从 begin
... end process
.
评估过程
因此,关于您的 DEFAULT 部分,每个信号都有一个默认值,并且不可能使用这种编码风格生成锁存器。通常 state_next 没有设置为空闲。它设置为 state_reg
免费翻译:保持当前状态,除非另有通知
您的代码:
...
elsif (update'event and update='1') then
d_next <= d_succ;
w_next <= w_succ;
else
d_next <= d_reg;
w_next <= w_reg;
end if;
无法合成。我假设 update 不是真正的时钟信号,因此不应在 rising_edge 表达式中使用它。其次,else条件什么时候为真?
解决方案:您的寄存器需要一个启用信号。
附录:
process(clk,reset)
begin
if reset='1' then
state_reg <= idle;
d_reg <= (others => (others => '0'));
w_reg <= (others => (others => '0'));
which_channel <= 0;
elsif (clk='1' and clk'event) then
state_reg <= state_next;
which_channel <= which_channel_next;
if update = '1' then
d_reg <= d_next;
w_reg <= w_next;
end if;
end if;
end process;
这是单进程样式的替代版本。
如您所料,只要您未明确设置值,"default values" 就会重置包括 State
在内的内容:这可能是不需要的,并且我已将一些转换为空闲显式(在 * _channel_inc) 代替。我在这里猜测了一点语义:如果一个字符在 InData 上出现超过一个周期,或者如果出现一个不同的字符,会发生什么?但逻辑应该很容易改变。
一些注意事项:
- 任何时候你写
x <= std_logic_vector(unsigned(y)+250);
都可能是错误的类型。这意味着你在对抗类型系统而不是使用它。我制作了 d_reg
等 Unsigned
数组,并将类型转换排除在程序流程之外。 X <= Y + 250;
更清晰,更简单。
- 这些端口应该是
Out
,而不是 InOut
- 我会协商让它们成为 Unsigned
,进一步简化和阐明设计。
- 空间不消耗门。
- 单一进程样式的一个优点是仅用于互连进程的信号较少,在难以确定的时间更新。此处,"update" 与其他所有内容在同一时钟沿使用。
- 神奇数字...
if in_data = "01101001" then --"i"
与 if in_data = to_slv('i') then
。后者更容易阅读,也更容易编写(并且正确)。如果您不喜欢 to_slv
辅助函数(它是可合成的),至少使用名称反映字符的命名常量。这也很容易看出这段代码正在处理 ASCII(抱歉,Latin-1)。
- 编辑:为了让 SM 不那么混乱,我在本地重载了
=
以允许在 slv 和角色之间进行直接比较:最好将这种技巧保留在需要的地方。这些函数甚至可以在进程本身中声明。
- 更喜欢
rising_edge(clk)
而不是过时的 (clk='1' and clk'event)
风格。
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity delay_increment is
generic ( delay_ports : natural := 3;
width_ports : natural := 3
);
Port ( clk,reset: in STD_LOGIC;
update : in STD_LOGIC;
in_data : in STD_LOGIC_VECTOR (7 downto 0);
led : out STD_LOGIC_VECTOR (2 downto 0);
out_data : out STD_LOGIC_VECTOR (7 downto 0);
d_big,d_mini,d_opo : out STD_LOGIC_VECTOR (25 downto 0);
w_big,w_mini,w_opo : out STD_LOGIC_VECTOR (25 downto 0));
end delay_increment;
architecture fsm_arch of delay_increment is
type state_type is (idle,channel,d_or_w,delay_channel,delay_channel_inc,width_channel,width_channel_inc);
type delay_file_type is array (delay_ports-1 downto 0) of unsigned (25 downto 0);
type width_file_type is array(width_ports-1 downto 0) of unsigned (25 downto 0);
signal d_reg, d_succ: delay_file_type;
signal w_reg, w_succ: width_file_type;
signal state_reg : state_type;
signal which_channel : natural;
function to_slv(C : Character) return STD_LOGIC_VECTOR is
begin
return STD_LOGIC_VECTOR(to_unsigned(Character'pos(c),8));
end to_slv;
function "=" (A : STD_LOGIC_VECTOR(7 downto 0); B : Character)
return boolean is
begin
return (A = to_slv(B));
end function "+";
begin
--------------------------------------
--State Machine
--------------------------------------
process(clk,reset)
begin
if reset='1' then
state_reg <= idle;
d_reg <= (others => (others => '0'));
w_reg <= (others => (others => '0'));
which_channel <= 0;
elsif rising_edge(clk) then
-- default actions ... update if asked
if update ='1' then
d_reg <= d_succ;
w_reg <= w_succ;
end if;
case state_reg is
when idle =>
if in_data = 'c' then
state_reg <= channel;
which_channel <= 0;
end if;
when channel =>
if (Character'pos('0') <= unsigned(in_data)) and (unsigned(in_data)<= Character'pos('9')) then
which_channel <= (to_integer(unsigned(in_data)) - Character'pos('0'));
state_reg <= d_or_w;
elsif in_data = '#' then
state_reg <= idle;
which_channel <= which_channel;
end if;
when d_or_w =>
if in_data = 'd' then
state_reg <= delay_channel;
elsif in_data = 'w' then
state_reg <= width_channel;
elsif in_data = '#' then
state_reg <= idle;
end if;
when delay_channel =>
if in_data = 'i' then
state_reg <= delay_channel_inc;
elsif in_data = '#' then
state_reg <= idle;
end if;
when delay_channel_inc =>
if in_data = 'u' then
d_succ(which_channel) <= d_reg(which_channel) + 250;
state_reg <= idle;
elsif in_data = 'd' then
d_succ(which_channel) <= d_reg(which_channel) - 250;
state_reg <= idle;
else
d_succ(which_channel) <= d_reg(which_channel); -- wait for any of 'u', 'd', '#'
end if;
if in_data = '#' then
state_reg <= idle;
end if;
when width_channel =>
if in_data = 'i' then
state_reg <= width_channel_inc;
elsif in_data = '#' then
state_reg <= idle;
end if;
when width_channel_inc =>
if in_data = 'u' then
w_succ(which_channel) <= w_reg(which_channel) + 250;
state_reg <= idle;
elsif in_data = 'd' then
w_succ(which_channel) <= w_reg(which_channel) - 250;
state_reg <= idle;
else
w_succ(which_channel) <= w_reg(which_channel); -- wait for any of 'u', 'd', '#'
end if;
if in_data = '#' then
state_reg <= idle;
end if;
end case;
end if;
end process;
--------------------------------------
--Output Logic
--------------------------------------
d_big <= std_logic_vector(d_reg(0));
d_mini <= std_logic_vector(d_reg(1));
d_opo <= std_logic_vector(d_reg(2));
w_big <= std_logic_vector(w_reg(0));
w_mini <= std_logic_vector(w_reg(1));
w_opo <= std_logic_vector(w_reg(2));
end fsm_arch;
我正在尝试制作一个基于串行输入切换状态的有限状态机。我需要一些关于我的代码是如何执行的解释。我在一本教科书中读到,我在过程中标记 "DEFAULT VALUES" 的部分是我应该放置默认值的地方。但是,每当我切换状态时,我的信号似乎都采用这些值。例如,我将 state_next 设置为 idle 作为默认值。这样做导致FSM无缘无故地从其他状态继续跳到idle。
我的另一个问题是说明 FSM 的整个过程是如何执行的。当我从一种状态移动到另一种状态时,是否应该执行 case 语句之前的部分(标记为 DEFAULT VALUES 的部分)?还是仅当我从某个较晚的状态移回空闲状态时才执行?什么时候应该执行 DEFAULT VALUES 部分?
我的代码如下所示。请参阅 "Next-State Logic" 部分。
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity delay_incrementor is
generic ( delay_ports : natural := 3;
width_ports : natural := 3
);
Port ( clk,reset: in STD_LOGIC;
update : in STD_LOGIC;
in_data : in STD_LOGIC_VECTOR (7 downto 0);
led : out STD_LOGIC_VECTOR (2 downto 0);
out_data : out STD_LOGIC_VECTOR (7 downto 0);
d_big,d_mini,d_opo : inout STD_LOGIC_VECTOR (25 downto 0);
w_big,w_mini,w_opo : inout STD_LOGIC_VECTOR (25 downto 0));
end delay_incrementor;
architecture fsm_arch of delay_incrementor is
type state_type is (idle,channel,d_or_w,delay_channel,delay_channel_inc,width_channel,width_channel_inc);
type delay_file_type is array (delay_ports-1 downto 0) of std_logic_vector (25 downto 0);
type width_file_type is array(width_ports-1 downto 0) of std_logic_vector (25 downto 0);
signal d_reg,d_next,d_succ: delay_file_type;
signal w_reg,w_next,w_succ: width_file_type;
signal state_reg,state_next: state_type;
signal which_channel,which_channel_next: natural;
begin
--------------------------------------
--State Register
--------------------------------------
process(clk,reset)
begin
if reset='1' then
state_reg <= idle;
d_reg <= (others => (others => '0'));
w_reg <= (others => (others => '0'));
which_channel <= 0;
elsif (clk='1' and clk'event) then
state_reg <= state_next;
d_reg <= d_next;
w_reg <= w_next;
which_channel <= which_channel_next;
end if;
end process;
--------------------------------------
--Next-State Logic/Output Logic
--------------------------------------
process(state_reg,in_data,d_reg,w_reg,which_channel)
begin
state_next <= idle; --DEFAULT VALUES
d_succ <= d_reg;
w_succ <= w_reg;
which_channel_next <= 0;
case state_reg is
when idle =>
if in_data = "01100011" then --"c"
state_next <= channel;
which_channel_next <= 0;
end if;
when channel =>
if (48 <= unsigned(in_data)) and (unsigned(in_data)<= 57) then
which_channel_next <= (to_integer(unsigned(in_data))-48);
state_next <= d_or_w;
elsif in_data = "00100011" then --"#"
state_next <= idle;
which_channel_next <= which_channel;
end if;
when d_or_w =>
if in_data = "01100100" then --"d"
state_next <= delay_channel;
elsif in_data = "01110111" then --"w"
state_next <= width_channel;
elsif in_data = "00100011" then --"#"
state_next <= idle;
end if;
when delay_channel =>
if in_data = "01101001" then --"i"
state_next <= delay_channel_inc;
elsif in_data = "00100011" then --"#"
state_next <= idle;
end if;
when delay_channel_inc =>
if in_data = "01110101" then --"u"
d_succ(which_channel) <= std_logic_vector(unsigned(d_reg(which_channel))+250);
elsif in_data = "01100100" then --"d"
d_succ(which_channel) <= std_logic_vector(unsigned(d_reg(which_channel))-250);
else
d_succ(which_channel) <= d_reg(which_channel);
end if;
if in_data = "00100011" then --"#"
state_next <= idle;
end if;
when width_channel =>
if in_data = "01101001" then --"i"
state_next <= width_channel_inc;
elsif in_data = "00100011" then --"#"
state_next <= idle;
end if;
when width_channel_inc =>
if in_data = "01110101" then --"u"
w_succ(which_channel) <= std_logic_vector(unsigned(w_reg(which_channel))+250);
elsif in_data = "01100100" then --"d"
w_succ(which_channel) <= std_logic_vector(unsigned(w_reg(which_channel))-250);
else
w_succ(which_channel) <= w_reg(which_channel);
end if;
if in_data = "00100011" then --"#"
state_next <= idle;
end if;
end case;
end process;
process(update,d_reg,w_reg,reset)
begin
if reset='1' then
d_next <= (others => (others =>'0'));
w_next <= (others => (others =>'0'));
elsif (update'event and update='1') then
d_next <= d_succ;
w_next <= w_succ;
else
d_next <= d_reg;
w_next <= w_reg;
end if;
end process;
--------------------------------------
--Output Logic
--------------------------------------
d_big <= d_reg(0);
d_mini <= d_reg(1);
d_opo <= d_reg(2);
w_big <= w_reg(0);
w_mini <= w_reg(1);
w_opo <= w_reg(2);
end fsm_arch;
每当列出的信号之一发生变化时,都会评估一个过程。因此这个列表被称为 'sensitivity list'.
有两种类型的进程:
- 顺序的(带有时钟信号)和
- 组合(只是简单的逻辑)。
第一种只需要灵敏度列表中的时钟信号,后者需要每个右手边的信号,否则仿真会显示与真实硬件不同的结果。
因此,每次输入信号发生变化时(begin
... end process
.
因此,关于您的 DEFAULT 部分,每个信号都有一个默认值,并且不可能使用这种编码风格生成锁存器。通常 state_next 没有设置为空闲。它设置为 state_reg
免费翻译:保持当前状态,除非另有通知
您的代码:
...
elsif (update'event and update='1') then
d_next <= d_succ;
w_next <= w_succ;
else
d_next <= d_reg;
w_next <= w_reg;
end if;
无法合成。我假设 update 不是真正的时钟信号,因此不应在 rising_edge 表达式中使用它。其次,else条件什么时候为真?
解决方案:您的寄存器需要一个启用信号。
附录:
process(clk,reset)
begin
if reset='1' then
state_reg <= idle;
d_reg <= (others => (others => '0'));
w_reg <= (others => (others => '0'));
which_channel <= 0;
elsif (clk='1' and clk'event) then
state_reg <= state_next;
which_channel <= which_channel_next;
if update = '1' then
d_reg <= d_next;
w_reg <= w_next;
end if;
end if;
end process;
这是单进程样式的替代版本。
如您所料,只要您未明确设置值,"default values" 就会重置包括 State
在内的内容:这可能是不需要的,并且我已将一些转换为空闲显式(在 * _channel_inc) 代替。我在这里猜测了一点语义:如果一个字符在 InData 上出现超过一个周期,或者如果出现一个不同的字符,会发生什么?但逻辑应该很容易改变。
一些注意事项:
- 任何时候你写
x <= std_logic_vector(unsigned(y)+250);
都可能是错误的类型。这意味着你在对抗类型系统而不是使用它。我制作了d_reg
等Unsigned
数组,并将类型转换排除在程序流程之外。X <= Y + 250;
更清晰,更简单。 - 这些端口应该是
Out
,而不是InOut
- 我会协商让它们成为Unsigned
,进一步简化和阐明设计。 - 空间不消耗门。
- 单一进程样式的一个优点是仅用于互连进程的信号较少,在难以确定的时间更新。此处,"update" 与其他所有内容在同一时钟沿使用。
- 神奇数字...
if in_data = "01101001" then --"i"
与if in_data = to_slv('i') then
。后者更容易阅读,也更容易编写(并且正确)。如果您不喜欢to_slv
辅助函数(它是可合成的),至少使用名称反映字符的命名常量。这也很容易看出这段代码正在处理 ASCII(抱歉,Latin-1)。 - 编辑:为了让 SM 不那么混乱,我在本地重载了
=
以允许在 slv 和角色之间进行直接比较:最好将这种技巧保留在需要的地方。这些函数甚至可以在进程本身中声明。 - 更喜欢
rising_edge(clk)
而不是过时的(clk='1' and clk'event)
风格。
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity delay_increment is
generic ( delay_ports : natural := 3;
width_ports : natural := 3
);
Port ( clk,reset: in STD_LOGIC;
update : in STD_LOGIC;
in_data : in STD_LOGIC_VECTOR (7 downto 0);
led : out STD_LOGIC_VECTOR (2 downto 0);
out_data : out STD_LOGIC_VECTOR (7 downto 0);
d_big,d_mini,d_opo : out STD_LOGIC_VECTOR (25 downto 0);
w_big,w_mini,w_opo : out STD_LOGIC_VECTOR (25 downto 0));
end delay_increment;
architecture fsm_arch of delay_increment is
type state_type is (idle,channel,d_or_w,delay_channel,delay_channel_inc,width_channel,width_channel_inc);
type delay_file_type is array (delay_ports-1 downto 0) of unsigned (25 downto 0);
type width_file_type is array(width_ports-1 downto 0) of unsigned (25 downto 0);
signal d_reg, d_succ: delay_file_type;
signal w_reg, w_succ: width_file_type;
signal state_reg : state_type;
signal which_channel : natural;
function to_slv(C : Character) return STD_LOGIC_VECTOR is
begin
return STD_LOGIC_VECTOR(to_unsigned(Character'pos(c),8));
end to_slv;
function "=" (A : STD_LOGIC_VECTOR(7 downto 0); B : Character)
return boolean is
begin
return (A = to_slv(B));
end function "+";
begin
--------------------------------------
--State Machine
--------------------------------------
process(clk,reset)
begin
if reset='1' then
state_reg <= idle;
d_reg <= (others => (others => '0'));
w_reg <= (others => (others => '0'));
which_channel <= 0;
elsif rising_edge(clk) then
-- default actions ... update if asked
if update ='1' then
d_reg <= d_succ;
w_reg <= w_succ;
end if;
case state_reg is
when idle =>
if in_data = 'c' then
state_reg <= channel;
which_channel <= 0;
end if;
when channel =>
if (Character'pos('0') <= unsigned(in_data)) and (unsigned(in_data)<= Character'pos('9')) then
which_channel <= (to_integer(unsigned(in_data)) - Character'pos('0'));
state_reg <= d_or_w;
elsif in_data = '#' then
state_reg <= idle;
which_channel <= which_channel;
end if;
when d_or_w =>
if in_data = 'd' then
state_reg <= delay_channel;
elsif in_data = 'w' then
state_reg <= width_channel;
elsif in_data = '#' then
state_reg <= idle;
end if;
when delay_channel =>
if in_data = 'i' then
state_reg <= delay_channel_inc;
elsif in_data = '#' then
state_reg <= idle;
end if;
when delay_channel_inc =>
if in_data = 'u' then
d_succ(which_channel) <= d_reg(which_channel) + 250;
state_reg <= idle;
elsif in_data = 'd' then
d_succ(which_channel) <= d_reg(which_channel) - 250;
state_reg <= idle;
else
d_succ(which_channel) <= d_reg(which_channel); -- wait for any of 'u', 'd', '#'
end if;
if in_data = '#' then
state_reg <= idle;
end if;
when width_channel =>
if in_data = 'i' then
state_reg <= width_channel_inc;
elsif in_data = '#' then
state_reg <= idle;
end if;
when width_channel_inc =>
if in_data = 'u' then
w_succ(which_channel) <= w_reg(which_channel) + 250;
state_reg <= idle;
elsif in_data = 'd' then
w_succ(which_channel) <= w_reg(which_channel) - 250;
state_reg <= idle;
else
w_succ(which_channel) <= w_reg(which_channel); -- wait for any of 'u', 'd', '#'
end if;
if in_data = '#' then
state_reg <= idle;
end if;
end case;
end if;
end process;
--------------------------------------
--Output Logic
--------------------------------------
d_big <= std_logic_vector(d_reg(0));
d_mini <= std_logic_vector(d_reg(1));
d_opo <= std_logic_vector(d_reg(2));
w_big <= std_logic_vector(w_reg(0));
w_mini <= std_logic_vector(w_reg(1));
w_opo <= std_logic_vector(w_reg(2));
end fsm_arch;