FPGA之道(67)代码中的约束信息(四)状态机的相关约束

前言

这是这个话题的第四篇,最重要的前言是本文节选自:《FPGA之道》。

状态机的相关约束

通常来说,编译器默认的状态机相关约束已经足够满足我们的需求,但也有的时候我们需要对个别状态机做“特殊关照”。此时若通过修改编译选项实现,所带来的效应是全局的,不符合我们的初衷,因此掌握一些基本的状态机相关约束语法,就可以让我们更加灵活的对所描述的状态机进行实现控制。

fsm_extract

fsm_extract是关于状态机提取的综合约束,它决定编译器是否会从我们编写的HDL代码中推断出状态机的存在。它的语法如下:

-- VHDL syntax
	-- 第一步,先要声明fsm_extract约束;
attribute fsm_extract: string;
-- 第二步,为fsm_extract语法指定约束线网名称和属性取值;
attribute fsm_extract of <{entity_name|signal_name}> : {entity|signal} is "{yes|no}";
// Verilog syntax
(* fsm_extract = "{yes|no}" *) 
// 上述约束会作用于紧随其后调用的实体、模块或信号

fsm_style

fsm_style这一综合约束决定了有限状态机的实现风格,即是基于LUT还是基于BRAM的。至于这两种实现风格到底有什么不同,大家可以回顾一下【本篇->编程思路->状态机,FPGA的灵魂->状态机的实现方式】章节。fsm_style约束的语法如下:

-- VHDL syntax
-- 第一步,先要声明fsm_style约束;
attribute fsm_style : string;
-- 第二步,为fsm_style语法指定约束线网名称和属性取值;
attribute fsm_style of <{entity_name|signal_name}> : {entity|signal} is "{lut|bram}";
// Verilog syntax
(* fsm_style = "{lut|bram}" *) 
// 上述约束会作用于紧随其后调用的实体、模块或信号

fsm_encoding

fsm_encoding这一综合约束决定了状态机的状态编码方式,关于状态编码,大家可以回顾一下【本篇->编程思路->状态机,FPGA的灵魂->状态的编码方式】章节。fsm_encoding约束的语法如下:

-- VHDL syntax
-- 第一步,先要声明fsm_encoding约束;
attribute fsm_encoding : string;
-- 第二步,为fsm_encoding语法指定约束线网名称和属性取值;
	attribute fsm_encoding of <{entity_name|signal_name}> : {entity|signal} is
	"{auto|one-hot|compact|sequential|gray|johnson|speed1|user}";
// Verilog syntax
(* fsm_encoding = "{auto|one-hot|compact|sequential|gray|johnson|speed1|user}" *) 
// 上述约束会作用于紧随其后调用的实体、模块或信号

enum_encoding

enum_encoding这一约束用来显式指定枚举类型中各个元素的实际数字编码表示,它主要用于人为指定VHDL语言所描述的状态机的状态编码形式,因为Verilog语言在声明状态机的状态时已经显式的为各个状态分配了数字编码。需要说明的是,enum_encoding这一约束要想生效,必须先要将fsm_encoding的属性值设置为user才行。关于enum_encoding约束的一个示例如下:

-- VHDL example
	type state_type is (s1, s2, s3, s4, s5);
	attribute enum_encoding of state_type : type is "001 011 010 100 111"; 

safe_implementation

safe_implementation这一约束是决定编译器是否采用安全模式来实现状态机。关于安全模式,大家可以回顾一下【本篇->编程思路->状态机,FPGA的灵魂->状态的编码方式->safe mode】小节。safe_implementation约束的语法如下:

-- VHDL syntax
-- 第一步,先要声明safe_implementation约束;
attribute safe_implementation : string;
-- 第二步,为safe_implementation语法指定约束线网名称和属性取值;
	attribute safe_implementation of {entity_name|component_name|signal_name} : 
		{entity|component|signal} is "{yes|no}";
// Verilog syntax
(* safe_implementation = "{yes|no}" *) 
// 上述约束会作用于紧随其后调用的实体、模块或信号

safe_recovery_state

如果使能了safe_implementation约束,那么编译器将会以安全模式来实现状态机,当出现非法状态时,编译器会采用其自身的规则选取状态机的某一个状态作为默认的恢复状态。不过“某一个”状态到底是状态机的哪一个状态呢?这个就不得而知了,有可能是状态机的初始化状态,也可能是上电后默认状态。当我们想显式的指定一个状态作为状态机的故障恢复状态时, safe_recovery_state约束就派上了用场,其约束语法如下:

-- VHDL syntax
-- 第一步,先要声明safe_recovery_state约束;
attribute safe_recovery_state : string;
-- 第二步,为safe_recovery_state语法指定约束线网名称和属性取值;
	attribute safe_recovery_state of {signal_name}:{signal} is "<value>";
// Verilog syntax
(* safe_recovery_state = "<value>" *) 
// 上述约束会作用于紧随其后调用的信号
发布了806 篇原创文章 · 获赞 1541 · 访问量 151万+

猜你喜欢

转载自blog.csdn.net/Reborn_Lee/article/details/105020847