亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Industrial programming >> VHDL

利用进程内过程简化VHDL状态机设计

在VHDL中,只要信号在作用域内,过程即可驱动外部信号。虽然架构中声明的过程无法访问外部信号——因那些信号在编译时不可见——但定义在进程内的过程可自由读写该进程可见的任何信号。

使用进程内过程能有效清理状态机或复杂协议中的重复逻辑。通过将常见动作(如定时状态转移)封装在过程中,可减少样板代码,提高可读性,使每步意图清晰明了。

例如在红绿灯控制器中,将操作重命名为ChangeState(ToState, Minutes, Seconds),无需深究底层变量赋值即可知代码意图。

实践练习

前一教程用不纯函数驱动Counter信号并决定状态变化。但因VHDL要求函数调用必须有返回值,无法将State赋值移入该函数。而无返回值的过程完美适配此用例。

下面是演示由进程内过程驱动的红绿灯FSM的完整测试平台和模块。

测试平台

library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity T23_ProcedureInProcessTb is end entity; architecture sim of T23_ProcedureInProcessTb is constant ClockFrequencyHz : integer := 100; -- 100 Hz constant ClockPeriod : time := 1000 ms / ClockFrequencyHz; signal Clk : std_logic := '1'; signal nRst : std_logic := '0'; signal NorthRed : std_logic; signal NorthYellow : std_logic; signal NorthGreen : std_logic; signal WestRed : std_logic; signal WestYellow : std_logic; signal WestGreen : std_logic; begin i_TrafficLights : entity work.T23_TrafficLights(rtl) generic map(ClockFrequencyHz => ClockFrequencyHz) port map ( Clk => Clk, nRst => nRst, NorthRed => NorthRed, NorthYellow => NorthYellow, NorthGreen => NorthGreen, WestRed => WestRed, WestYellow => WestYellow, WestGreen => WestGreen); Clk <= not Clk after ClockPeriod / 2; process is begin wait until rising_edge(Clk); wait until rising_edge(Clk); nRst <= '1'; wait; end process; end architecture;

红绿灯模块

library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity T23_TrafficLights is generic(ClockFrequencyHz : integer); port( Clk : in std_logic; nRst : in std_logic; NorthRed : out std_logic; NorthYellow : out std_logic; NorthGreen : out std_logic; WestRed : out std_logic; WestYellow : out std_logic; WestGreen : out std_logic); end entity; architecture rtl of T23_TrafficLights is type t_State is (NorthNext, StartNorth, North, StopNorth, WestNext, StartWest, West, StopWest); signal State : t_State; signal Counter : integer range 0 to ClockFrequencyHz * 60; begin process(Clk) is procedure ChangeState(ToState : t_State; Minutes : integer := 0; Seconds : integer := 0) is variable TotalSeconds : integer; variable ClockCycles : integer; begin TotalSeconds := Seconds + Minutes * 60; ClockCycles := TotalSeconds * ClockFrequencyHz - 1; if Counter = ClockCycles then Counter <= 0; State <= ToState; end if; end procedure; begin if rising_edge(Clk) then if nRst = '0' then State <= NorthNext; Counter <= 0; NorthRed <= '1'; NorthYellow <= '0'; NorthGreen <= '0'; WestRed <= '1'; WestYellow <= '0'; WestGreen <= '0'; else NorthRed <= '0'; NorthYellow <= '0'; NorthGreen <= '0'; WestRed <= '0'; WestYellow <= '0'; WestGreen <= '0'; Counter <= Counter + 1; case State is when NorthNext => NorthRed <= '1'; WestRed <= '1'; ChangeState(StartNorth, Seconds => 5); when StartNorth => NorthRed <= '1'; NorthYellow <= '1'; WestRed <= '1'; ChangeState(North, Seconds => 5); when North => NorthGreen <= '1'; WestRed <= '1'; ChangeState(StopNorth, Minutes => 1); when StopNorth => NorthYellow <= '1'; WestRed <= '1'; ChangeState(WestNext, Seconds => 5); when WestNext => NorthRed <= '1'; WestRed <= '1'; ChangeState(StartWest, Seconds => 5); when StartWest => NorthRed <= '1'; WestRed <= '1'; WestYellow <= '1'; ChangeState(West, Seconds => 5); when West => NorthRed <= '1'; WestGreen <= '1'; ChangeState(StopWest, Minutes => 1); when StopWest => NorthRed <= '1'; WestYellow <= '1'; ChangeState(NorthNext, Seconds => 5); end case; end if; end if; end process; end architecture;

波形

仿真波形与原始FSM完全一致——仅代码变得更易维护和理解。

分析

将定时和状态变更逻辑移入单一过程,在保持模块行为不变的前提下大幅提升可读性。过程确保在所有调用处一致实现。

关键要点

VHDL

  1. 刀具磨床实战技法指南:从入门到精通
  2. 钼如何塑造现代工业:用途、优势与供应动态
  3. VHDL入门:构建你的第一个与门
  4. VHDL过程示例:标准逻辑向量自增
  5. VHDL 字符串列表创建:最佳实践与示例
  6. 使用VHDL不纯函数提升FSM可读性与可维护性
  7. 掌握VHDL函数:高效设计实战指南
  8. 在VHDL中使用过程:用可复用代码简化设计
  9. 构建可靠VHDL计时器:从时钟周期计数到小时
  10. 构建VHDL时钟触发进程实战指南
  11. 利用VHDL常量与泛型映射实现灵活模块设计
  12. 掌握VHDL端口映射实例化实战指南