Verilog可综合有限状态机的4种写法
- 格式:doc
- 大小:50.50 KB
- 文档页数:8
verilog 状态机最佳写法Verilog编程语言广泛应用于数字电路设计中,特别是在嵌入式系统和硬件描述语言中。
状态机是一种常用的设计模式,可以帮助我们描述复杂的行为和控制逻辑。
本文将介绍如何使用Verilog编写状态机,并提供一些最佳实践。
第一部分:Verilog简介Verilog是一种硬件描述语言,最初由美国自动化控制协会(ACM)开发。
它是一种用于描述、仿真和生成数字电路的高级编程语言。
Verilog提供了描述硬件的能力,使我们能够在逻辑级别上描述电路的行为。
第二部分:状态机简介状态机是一种抽象的数学模型,用于描述系统或程序的行为。
它由一组状态、输入和输出组成,并在不同状态之间进行转换。
状态机可以用于描述任何连续或离散的系统,包括硬件和软件。
第三部分:状态机的设计方法在Verilog中,我们可以使用参数化模块和状态寄存器来描述状态机。
参数化模块可以接受输入和输出,根据当前状态和输入转换到下一个状态,并产生相应的输出。
下面是一个简单的例子:```module fsm #(parameter N=3) (input logic clk, reset, input logic [N-1:0] input, output [N-1:0] output);typedef enum logic [1:0] {S0, S1, S2} state_t;state_t state, next_state;always_ff @(posedge clk or posedge reset) begin if (reset) beginstate <= S0;end else beginstate <= next_state;endendalways_comb begincase (state)S0: begin// State S0 behavioroutput = input;next_state = S1;endS1: begin// State S1 behavioroutput = ~input;next_state = S2;endS2: begin// State S2 behavioroutput = 2'b11;next_state = S0;enddefault: begin// Default behavioroutput = 2'b00;next_state = S0;endendcaseendendmodule```在这个例子中,我们定义了一个状态机模块,它有一个时钟信号、一个复位信号、一个输入信号和一个输出信号。
有限状态机的verilog例子有限状态机(Finite State Machine, FSM)是数字电路设计中的一种基本构件,它可以用来实现各种复杂的控制逻辑。
在Verilog中,可以用模块(module)来描述一个有限状态机,使用参数(parameters)来定义状态数量和状态转移逻辑。
以下是一个简单的有限状态机的Verilog例子,该FSM有3个状态(S0, S1, S2)和两个输入(clk, rst_n)以及一个输出(next_state, out):```verilogmodule fsm(input wire clk, // 时钟信号input wire rst_n, // 低电平复位信号input wire [1:0] in, // 输入信号,这里位宽为2,可以扩展output reg next_state, // 下一状态输出output reg out // 输出信号);// 状态参数parameter S0 = 2'b00;parameter S1 = 2'b01;parameter S2 = 2'b10;// 状态寄存器reg [1:0] state;// 状态转移逻辑always @(posedge clk or negedge rst_n) beginif (!rst_n) begin// 当处于复位状态时,状态寄存器和输出都初始化为0state <= S0;out <= 1'b0;end else begin// 根据当前状态和输入信号,更新下一状态和输出case (state)S0: beginnext_state <= S1;out <= 1'b1;endS1: beginnext_state <= S2;out <= 1'b0;endS2: beginnext_state <= S0;out <= 1'b1;enddefault: beginnext_state <= S0;out <= 1'b0;endendcaseendendendmodule```在这个例子中:- `clk` 是时钟信号。
verilog中的可综合与不可综合语句
verilog中可综合语句:input,output,parameter,reg,wire,always,assign,
begin...end,case,for,posedge,negedge,or,and,default,if,function,generate,integer,while,repeat(while、repeat循环可综合时,要具有明确的循环表达式和循环条件,for可综合时也要有具体的循环范围),·define
不可综合语句:initial,fork...join,wait,time,display,forever。
保证Verilog HDL赋值语句的可综合性,在建模时应注意以下要点:(1)不能使⽤initial,initial⼀般使⽤在测试程序,做初始化。
(2)不建议使⽤延时,#1,这种只是模拟数字电路中因为布线产⽣的信号延时,不可综合,但也不会报错。
(3)不能使⽤循环次数不确定的函数,但forever在综合设计中禁⽌使⽤,只能使⽤在仿真测试程序中。
(4)尽量使⽤同步电路设计⽅式。
(5)除⾮关键电路设计,⼀般不建议调⽤门级元件进⾏设计,⼀般使⽤⾏为级进⾏设计。
(6)当使⽤always进⾏组合逻辑设计时,敏感列表⾥⾯的要列出所有输⼊信号。
(7)在进⾏时序电路进⾏编写时,采样⾮阻塞赋值。
组合逻辑设计时,采样阻塞赋值,但是不能在同⼀个always语句⾥两种混合使⽤。
(8)为避免产⽣锁存器,if,case要进⾏完整的语句赋值,且case语句中避免使⽤X值,Z值。
verilog 状态机写法在Verilog中,有几种常用的状态机写法,包括Mealy状态机、Moore状态机和通用状态机。
下面简要介绍每种写法的特点:Mealy状态机:输出依赖于当前状态和输入信号。
输出的变化可以与状态的变化同步。
Verilog代码示例:module MealyFSM (input logic clk,input logic reset,input logic input_signal,output logic output_signal);enum logic [2:0] states;logic [2:0] current_state, next_state;always_ff @(posedge clk or posedge reset) beginif (reset)current_state <= states[0];elsecurrent_state <= next_state;endalways_comb begincase (current_state)states[0]: begin // State 0if (input_signal)next_state = states[1];elsenext_state = states[0];output_signal = input_signal & next_state[0]; // Output depends on current state and input signalendstates[1]: begin // State 1if (input_signal)next_state = states[0];elsenext_state = states[1];output_signal = input_signal | next_state[0]; // Output depends on current state and input signalend// Add more states and conditions as neededendcaseendEndmoduleMoore状态机:输出只依赖于当前状态。
verilog之可综合与不可综合可综合的意思是说所编写的代码可以对应成详细的,不行综合就是所写代码没有对应的电路结构,例如行为级语法就是一种不行综合的代码,通常用于写测试文件。
建立可综合模型时,需注重以下几点:不用法initial不用法10之类的延时语句不用法循环次数不确定的循环语句,如forever,while等不用法用户自定义原语(UDP元件)尽量用法同步方式设计电路用always块来描述组合规律时,应列出全部输入信号作为敏感信号列表,即always@(*)全部的内部寄存器都应当能够被复位,在用法实现设计时,尽量用法器件的全局复位端作为系统的总复位对时序规律描述和建模,尽量用法非堵塞赋值的方式,对组合规律描述和建模,虽然堵塞和非堵塞赋值的方式都可以,但在同一过程快中最好不要同时用法堵塞赋值和非堵塞赋值。
我个人比较推举用堵塞赋值的方式描述组合规律不能在多个always块中对同一个变量举行赋值。
对同一个对象不能既用法非堵塞赋值,又用法堵塞赋值假如不决定让变量生成锁存器,那么必需在用法if语句或case语句时补全全部条件不行综合语句:initial 初始化语句,只能在testbench中用法,不行综合event event在同步testbench时更实用,不能综合real 不支持real数据类型的综合time 不支持time数据类型的综合assign 和 deassign 不支持对reg数据类型赋值的综合,但支持wire类型赋值的综合以开始的延时语句不能被综合verilog是一种硬件描述语言,我们在写verilog 代码时,首先要有所要写的module在硬件上如何实现的概念,而不是去想编译器如何说明这个module。
比如在打算是否用法 reg 定义时,要问问自己物理上是不是真正存在这个 register, 假如是,它的clock 是什么? D 端是什么?Q 端是什么?有没有清零和置位?同步还是异步?再比如上面研究的三态输出问题,首先想到的应当是在 register 的输出后面加一个三态门,而不是如何才干让编译器知道要“赋值”给一个信号为三态。
verilog状态机设计例题Verilog状态机设计是数字电路设计中的重要内容,它通常用于控制系统和序列逻辑电路的设计。
在Verilog中,状态机通常使用行为级描述或者结构级描述来实现。
下面我将从例题的角度来介绍Verilog状态机设计。
假设我们要设计一个简单的2位计数器,它可以按顺序循环输出00、01、10、11、00……的计数序列。
我们可以使用Verilog来实现这个状态机。
首先,我们需要定义状态机的状态和状态转移。
在这个例子中,我们有4个状态:S0、S1、S2和S3,分别对应00、01、10、11四种计数状态。
状态转移规则如下:当当前状态为S0时,下一个状态为S1;当当前状态为S1时,下一个状态为S2;当当前状态为S2时,下一个状态为S3;当当前状态为S3时,下一个状态为S0。
接下来,我们可以使用Verilog的行为级描述来实现这个状态机。
下面是一个简单的Verilog代码示例:verilog.module counter (。
input clk, // 时钟输入。
input rst, // 复位输入。
output reg [1:0] count // 2位计数输出。
);// 定义状态。
typedef enum {S0, S1, S2, S3} state_type;reg [1:0] state, next_state;// 状态转移逻辑。
always @(posedge clk or posedge rst) begin.if (rst) begin.state <= S0; // 复位时初始状态为S0。
end.else begin.state <= next_state; // 根据下一个状态更新当前状态。
end.end.// 下一个状态逻辑。
case (state)。
S0: next_state = S1;S1: next_state = S2;S2: next_state = S3;S3: next_state = S0;default: next_state = S0;endcase.end.// 输出逻辑。
V e r i l o g 语言的可综合性可综合的Verilog HDL 语句都是V e r i l o g H D L 标准( I E E E 1 3 6 4 ) 的一个子集,并且因所用工具不同而异。
在设计中不能采用不可综合的语句( 测试代码除外) 。
下面我们讨论一下大部分综合工具都支持的语句,具体到某种工具的特性还要查看说明文档。
对于数据类型、运算符、赋值语句、基本门级元件等的可综合性问题,因为都有固定的规定,这里就不多讨论了。
组合逻辑和时序逻辑的可综合性: 用a s s i g n 语句对w i r e 型变量进行赋值,综合后的结果是组合逻辑电路。
用a l w a y s @ ( 电平敏感变量表) ,即电平敏感的a l w a y s 块描述的电路综合后的结果是组合逻辑电路或电平敏感的锁存器,此时,a l w a y s 块内赋值语句左边的变量是r e g或i n t e g e r 型,块中要避免组合反馈回路,每次执行a l w a y s 块时,在生成组合逻辑的a l w a y s 块中被赋值的所有信号必须都在敏感电平列表中列出,否则在综合时将会为没有列出的信号隐含的产生一个透明的锁存器,这时综合后的电路已不是纯组合电路了。
用a l w a y s @( p o s e d g e c l o c k ) 或a l w a y s @ ( n e g e d g e c l o c k ) 块描述的电路综合为同步时序逻辑电路,设计同步时序逻辑电路的关键是建立描述该电路状态转移的可综合的有限状态机模型,在V e r i l o g H D L语言中最常用的描述同步时序状态机的结构是a l w a y s 和块内的c a s e . i f 语句,除了紧跟在a l w a y s 后的@( p o s e d g e c l o c k ) , @ ( n e g e d g e c l o c k ) 外,a l w a y s 块中不允许其他的@ ( e v e n t ) 语句,目前大多数综合工具不能综合V e r i l o g H D L描述的异步状态机,所以用V e r i l o g 设计的时序电路应该是同步时序电路。
可综合Verilog语句⏹一:综合就是从采用Verilog HDL 语言描述的寄存器传输级电路模型构造出门级网表的过程.产生门级网表之后,逻辑优化器读入网表并以用户指定的面积和定时约束为目标优化网表.⏹二.设计流程中的综合⏹Verilog HDL允许用户在不同的抽象层次上对电路进行建模,这些层次从门级、寄存器传输级、行为级直至算法级。
因此,同一电路就可以有多种不同的描述方式,但不是每一中描述都是可综合的。
事实上,Verilog HDL 原本被设计成一种仿真语言,而不时一种综合语言。
结果导致Verilog HDL 中很多结构没有相应的硬件可以对应,例如系统调用$display.同样也不存在用于寄存器传输级综合的Verilog HDL 标准子集.⏹正是由于存在这些问题,不同的综合系统所支持的Verilog HDL 综合子集是不同的.由于Verilog HDL 中不存在单个的对象来表示锁存器或触发器,所以每一种综合系统都会提供不同的机制以实现锁存器或触发器的建模.因此各种综合系统都定义了自己的Verilog HDL 可综合子集以及自己的建模方式.⏹使用Verilog HDL 以不同的方式描述了同一电路.某综合系统支持对方式A和方式B的综合,但可能不支持对方式C的综合,这意味着综合模型在不同的综合系统之间通常是不可移植的.⏹这一局限性使设计者不仅需要理解Verilog HDL ,而且必须理解特定综合系统的建模方式,才能编写出可综合的模型.可综合的数据类型⏹1.网线数据类型:⏹Wire,wor,wand,tri,supply0,supply1⏹2.寄存器数据类型:⏹Reg,integer⏹Time,real:不能综合.⏹3.常量:⏹整型.⏹实型和字符串型不能综合.可综合的运算符⏹1.逻辑运算符能直接映射成硬件中的基本逻辑门.⏹2.算术运算符⏹3.关系运算符:⏹能综合的有:>,<,<=,>=.⏹4.相等性算符:⏹能够综合的有:==和!=.⏹不能综合:===和!==(有些工具按==和!=综合).⏹5.移位运算符:⏹<<和>>,移位腾出的位都补0.多个时钟的可综合情况⏹1.多个时钟的情况:对变量的赋值不能受多个时钟控制例如:⏹ module multclk(clk1,clk2,addclk,and,rstn,subclr,subn,dsadd,dssub);⏹input clk1,addclk,adn,rstn,subclr,subn,clk2;⏹output dsadd,dssub;⏹reg dsadd,dssub;⏹reg addstate,substate;⏹always @(posedge clk1)⏹begin⏹addstate<=addclk^(adn|rstn);⏹substate<=subclr^(subn&rstn);⏹end⏹always @(posedge clk2)⏹begin⏹dsadd<=addstate;⏹dssun<=substate;⏹end⏹ endmodule⏹2.多相位时钟:对变量的赋值不能受两种不同的时钟条件的控制.⏹module multphase(clk,a,b,c,e);⏹input clk,a,b,c;⏹output e;⏹reg e,d;⏹always @(posedge clk)⏹e<=d|c;⏹always @(negedge clk)⏹d<=a&b;⏹ endmodule用有限状态机实现的3位二进制计数器.(带进位)module fsm_count(clk,rst,dout,cout);input clk,rst;output [2:0] dout;output cout;reg cout;reg [2:0] dout;reg [3:0] state;always @(posedge clk){cout,dout}<=state;parameter zero=4'b1000,one=4'b0001,two=4'b0010,three=4'b0011,four=4'b0100, five=4'b0101,six=4'b0110,seven=4'b0111,init=4'b0000;always @(posedge clk)beginif(!rst)state<=init;elsebegincase(state)zero:state<=one;init:state<=one;one: state<=two;two:state<=three;three:state<=four;four:state<=five;five:state<=six;six:state<=seven;seven:state<=zero;default:state<=init;endcaseendend状态机设计的一般原则:状态机是逻辑设计中的最重要的设计内容之一,通过状态转移图设计手段可以将复杂的控制时序图形化表示,分解为状态之间的转换关系,将问题简化。
状态机是一种用于实现特定顺序逻辑的硬件设计方法。
在Verilog中,状态机通常通过定义不同的状态和状态迁移来实现。
以下是状态机在Verilog中的基本写法:1. 定义状态:首先,需要定义状态机的状态。
状态可以用整数或符号表示。
```verilogmodule state_machine (input clk,input rst,// 其他输入信号output reg [1:0] state // 输出状态);```2. 状态迁移:定义状态机的状态迁移逻辑。
这通常包括两个部分:状态转移条件和转移输出。
- 状态转移条件:描述当前状态和输入信号之间的关系,用于确定状态机何时迁移到哪个新状态。
```verilogalways @(posedge clk) beginif (rst) beginstate <= 0; // 初始化状态end else begin// 状态迁移条件state <= next_state;endend```- 转移输出:描述状态机在新状态下的输出信号。
```verilogalways @(posedge clk) beginif (rst) beginstate <= 0; // 初始化状态end else begin// 状态迁移条件state <= next_state;// 状态机在新状态下的输出output_signal = next_output_signal;endend```3. 循环结构:如果状态机需要在一个状态中执行一系列操作,可以使用循环结构(如for循环、while循环等)。
```verilogalways @(posedge clk) beginif (rst) beginstate <= 0; // 初始化状态end else begin// 状态迁移条件state <= next_state;// 循环执行的操作for (integer i = 0; i < 4; i = i + 1) begin// 状态机在新状态下的输出output_signal = next_output_signal;endendend```4. 描述输入和输出信号:根据状态机的需求,定义输入和输出信号。
verilog状态机的三种写法1,单always块结构(⼀段式):always @(posedge clk ) begincase(FSM)st0;beginout0;//输出if(case0) FSM<=st1;//状态转移endst1;beginout1;//输出if(case0) FSM<=st2;//状态转移end……default:endcaseend单always块把组合逻辑和时序逻辑放在⼀个时序always块描述。
输出时为寄存器输出,所以⽆⽑刺。
但是这种⽅式会产⽣多余的触发器(因为把组合逻辑也放在时序逻辑中实现),⽽且代码难以修改调试。
但对于那些简单的状态机,⼀段式还是不错的,因为它把输⼊,转移,输出⼀起体现,更⽅便理解。
但是对于复杂状态机就是灾难了,所以最好还是养成不使⽤该结构的习惯。
双always块结构(两段式)://时序逻辑,这段⼀般是不变的,描述从现态转移到次态always @ (posedge clk) begincurrent_state<=next_state;end//组合逻辑,包括转移条件以及状态内容(即输出)always @ (*) begincase(current_state)st0:beginout0;if(case0) FSM=st1; //组合逻辑使⽤阻塞语句endst1:beginout1;if(case1) FSM=st2;end……endcaseend⼆段式中,⼀个always块采⽤同步时序描述状态转移;另⼀个采⽤组合逻辑判断转移条件,以及描述输出。
⼆段式便于阅读,理解和维护,有利于综合器优化代码。
但是由于采⽤的是组合逻辑输出,容易产⽣⽑刺,且不利于约束,也不利于综合器和布局布线器实现⾼性能设计。
三always块结构(三段式)://第⼀个always块,时序逻辑,描述现态转移到次态always @ (posedge clk negedge rst_n) beginif(!rst_n) current_state<=IDLE;else current_state<=next_state;end//第⼆个always块,组合逻辑,描述状态转移的条件always @ (current_state) begincase(current_state)s1:if(……) next_state=s2;//组合逻辑,采⽤阻塞赋值……endcaseend//第三个always块,时序逻辑,描述输出always @ (posedge clk negedge rst_n) begincase(next_state) //这⾥有的是next_state,有的是current_state,需根据电路要求s1: out1<=……;s2: out2<=……;default:……endcaseend三段式结构中,2个时序always块分别⽤来描述现态逻辑转移,及输出赋值。
verilog 状态机写法Verilog是一种硬件描述语言,常用于设计和开发数字电路和系统。
在Verilog中,状态机是一种常用的建模方法,用于描述系统的状态和状态转移。
Verilog的状态机可以使用不同的写法来实现,通常有两种主要的方法:行为级描述和结构级描述。
行为级描述是一种以状态转移的逻辑和状态转移的条件为基础的写法。
在行为级描述中,我们需要定义状态变量和状态转移条件,然后使用if-else语句来实现状态转移逻辑。
以下是一个简单的例子,使用行为级描述写法实现一个简单的二进制计数器状态机:```verilogmodule binary_counter(input clk,input reset,output reg [3:0] count);reg [3:0] next_count;always @(posedge clk or posedge reset) beginif (reset) begincount <= 4'b0000;end else begincase (count)4'b0000: next_count = 4'b0001;4'b0001: next_count = 4'b0010;4'b0010: next_count = 4'b0011;4'b0011: next_count = 4'b0100;4'b0100: next_count = 4'b0101;4'b0101: next_count = 4'b0110;4'b0110: next_count = 4'b0111;4'b0111: next_count = 4'b1000;4'b1000: next_count = 4'b1001;4'b1001: next_count = 4'b0000;default: next_count = 4'b0000;endcasecount <= next_count;endendendmodule```在上面的例子中,我们定义了一个4位的计数器变量`count`,并在always块中定义了状态转移逻辑。
设计可综合状态机几种状态编码方式的比较潘存斌;詹宜巨;李赛斯【摘要】本文介绍了采用verilog硬件描述语言设计有限状态机时几种常用的状态编码方式,并结合有限状态机的设计例子来比较各编码方式.【期刊名称】《自动化与信息工程》【年(卷),期】2003(024)004【总页数】3页(P13-15)【关键词】有限状态机;verilog硬件描述语言;状态编码方式;状态机编码方式【作者】潘存斌;詹宜巨;李赛斯【作者单位】华南理工大学自动化学院;广东省科学院自动化工程研制中心;湘潭大学信息工程学院【正文语种】中文【中图分类】TP27有限状态机(FSM,Finite State Machine)是时序电路设计中经常采用的一种方式,尤其适合于数字系统的控制模块,是许多数字电路的核心。
在系统设计中,能否设计出高效的状态机非常关键。
从状态机的信号输出方式上分,有两种类型的状态机。
第一种是moore状态机,其输出只跟当前状态有关。
这种状态机相对简单,但由于各触发器时钟到输出的延时不同以及组合逻辑中传输延时的不同,输出信号会出现毛刺现象,如果输出用于控制的话,将可能导致错误的操作;第二种是mealy状态机,它的输出既与当前的状态有关,还跟输入信号有关。
正因为如此,输出时序不仅跟时钟时序有关,还跟输入时序有关,这将使状态机的实现产生比较大的时序问题,所以在进行同步设计时一般不选mealy状态机。
除了根据输出信号的产生方式划分外,状态机还可以根据状态编码方式划分。
常用的编码方式有以下几种:二进制顺序编码、格雷码、随机码、一位热、零空闲一位热编码等等。
本文将以moore状态机为例,结合图1描述的状态图,详细介绍分别采用二进制顺序编码、一位热、完整一位热(verbose one-hot)和简化一位热(simplified one-hot))、零空闲一位热(one-hot with zero-idle)编码方式进行状态编码时,用verilog语言设计状态机的编码风格。
基于Verilog HDL的有限状态机1.有限状态机1.1 概述有限状态机是指输出取决于过去输入部分和当前输入部分的时序逻辑电路。
有限状态机又可以认为是组合逻辑和寄存器逻辑的一种组合。
状态机特别适合描述那些发生有先后顺序或者有逻辑规律的事情,其实这就是状态机的本质。
状态机就是对具有逻辑顺序或时序规律的事件进行描述的一种方法在实际的应用中根据状态机的输出是否与输入条件相关,可将状态机分为两大类,即摩尔 (Moore)型状态机和米勒 (Mealy) 型状态机。
图 1Mealy型状态转移图1.2 状态机的描述方法状态机的描述方法多种多样,将整个状态机写到1个always 模块里,在该模块中既描述状态转移,又描述状态的输入和输出,这种写法一般被称为一段式FSM 描述方法;还有一种写法是使用两个always模块,其中一个always 模块采用同步时序的方式描述状态转移,而另一个模块采用组合逻辑的方式判断状态转移条件,描述状态转移规律,这种写法被称为两段式FSM 描述方法;还有一种写法是在两段式描述方法的基础上发展而来的,这种写法使用3 个always模块,一个always 模块采用同步时序的方式描述状态转移,一个采用组合逻辑的方式判断状态转移条件,描述状态转移规律,第三个always 模块使用同步时序电路描述每个状态的输出,这种写法称为三段式写法。
1.3 FSM的状态编码二进制码(Binary)和格雷码(Gray)属于压缩状态编码,这种编码的优点是使用的状态向量最少,但是需要较多的逻辑资源用来状态译码。
二进制码从一个状态转换到相邻状态时,可能有多个比特位发生变化,易产生中间状态转移问题,状态机的速度也要比采用其它编码方式慢。
格雷码两个相邻的码值仅有一位就可区分,这将会减少电路中相邻物理信号线同时变化的情况,因而可以减少电路中的电噪声。
Johnson码也有同样的特点,但是要用较多的位数。
独热码(One-hot)指对任意给定的状态,状态寄存器中只有l位为1,其余位都为0。
Verilog可综合有限状态机的4种写法第一种:自然编码1.module fsm1(2.input i_clk,3.input rst_n,4.input A,5.output reg K1,6.output reg K2,7.output reg [1:0] state8.);[/color][/font]9.[font=Times New Roman][color=#000000]parameter Idle=2'b00,10. Start=2'b01,11. Stop=2'b10,12. Clear=2'b11;[/color][/font]13.[font=Times NewRoman][color=#000000][email=always@(posedge]always@(posedge[/email]i_clk)14.if(!rst_n)15.begin16. state<=Idle;17. K2<=0;18. K1<=0;19.end20.else21.case(state)22. Idle:if(A)23. begin24. state<=Start;25. K1<=0;26. end28. begin29. state<=Idle;30. K2<=0;31. K1<=0;32. end33. Start:if(!A)34. state<=Stop;35. else36. state<=Start;37. Stop:if(A)38. begin39. state<=Clear;40. K2<=1;41. end42. else43. begin44. state<=Stop;45. K2<=0;46. K1<=0;47. end48. Clear:if(!A)49. begin50. state<=Idle;51. K1<=1;52. K2<=0;53. end54. else55. begin56. state<=Clear;57. K2<=0;58. K1<=1;60. default:61. state<=Idle;62. endcase63.endmodule第二种:采用独热编码,据说其可靠性和速度都不错1.module fsm2(2.input i_clk,3.input rst_n,4.input A,5.output reg K1,6.output reg K2,7.output reg [3:0] state8.);9.10.parameter Idle=4'b1000;11.parameter Start=4'b0100;12.parameter Stop=4'b0010;13.parameter Clear=4'b0001;14.15.always@(posedge i_clk)16.begin17. if(!rst_n)18. begin19. state<=Idle;20. K2<=0;21. K1<=0;22. end23. else24. case(state)25. Idle:if(A)26. begin28. K1<=0;29. end30. else31. begin32. state<=Idle;33. K2<=0;34. K1<=0;35. end36. Start:if(!A)37. state<=Stop;38. else39. state<=Start;40. Stop:if(A)41. begin42. state<=Clear;43. K2<=1;44. end45. else46. begin47. state<=Stop;48. K1<=0;49. K2<=0;50. end51. Clear:if(!A)52. begin53. state<=Idle;54. K2<=0;55. K1<=1;56. end57. else58. begin60. K2<=0;61. K1<=0;62. end63. default:state<=Idle;64.endcase65.end66.endmodule第三种:把输出直接指定为状态码,即把状态码的指定和状态机的输出联系起来,状态的变化直接用做输出据说可以提高输出信号的开关速度并节省电路资源(希望了解其机理的高手们能够解说下时怎样提高开关速度的?)1.module fsm3(2.input i_clk,3.input rst_n,4.input A,5.output K1,6.output K2,7.output reg [4:0] state8.);9.10.11.assign K2=state[4];12.assign K1=state[0];13.14.parameter Idle =5'b00000;15.parameter Start =5'b00010;16.parameter Stop =5'b00100;17.parameter StopToClear =5'b11000;18.parameter Clear =5'b01010;19.parameter ClearToIdle =5'b00111;20.21.always@(posedge i_clk)22.if(!rst_n)23.begin24. state<=Idle;25.end26.else27.case(state)28. Idle:if(A)29. state<=Start;30. else31. state<=Idle;32. Start:if(!A)33. state<=Stop;34. else35. state<=Start;36. Stop:if(A)37. state<=StopToClear;38. else39. state<=Stop;40. StopToClear:state<=Clear;41. Clear:if(!A)42. state<=ClearToIdle;43. else44. state<=Clear;45. ClearToIdle:state<=Idle;46. default:state<=Idle;47.endcase48.endmodule第四:把状态的变化和输出开关的控制分成两部分考虑1.module fsm4(2.input i_clk,3.input rst_n,4.input A,5.output reg K1,6.output reg K2,7.output reg[1:0] state8.);9.10.11.//reg [1:0] state;12.reg [1:0] nextstate;13.parameter Idle=2'b00,14. Start=2'b01,15. Stop=2'b10,16. Clear=2'b11;17.always@(posedge i_clk)18.if(!rst_n)19. state<=Idle;20.else21. state<=nextstate;22.23.always@(state or A)24. case(state)25. Idle:if(A)26. nextstate=Start;27. else28. nextstate=Idle;29. Start:if(!A)30. nextstate=Stop;31. else32. nextstate=Start;33. Stop:if(A)34. nextstate=Clear;35. else36. nextstate=Stop;37. Clear:if(!A)38. nextstate=Idle;39. else40. nextstate=Clear;41. default:nextstate=2'bxx;42. endcase43.always@(state or rst_n or A)44.if(!rst_n)45. K1<=0;46.else47. if(state==Clear&&!A)48. K1<=1;49. else50. K1<=0;51.52.always@(state or rst_n or A)53.if(!rst_n)54. K2<=0;55.else56. if(state==Stop&&A)57. K2<=1;58. else59. K2<=0;60.endmodule。