Verilog学习之路(8)— 时序电路的设计

一、前言

时序逻辑电路的输出不仅与当前时刻输入变量的取值有关,而且与电路的原状态,即与过去的输入情况有关。

时序逻辑电路的两个特点:

时序逻辑电路包括组合逻辑电路和存储电路两部分,存储电路具有记忆功能,通常由触发器组成;存储电路的状态反馈到组合逻辑电路输入端,与外部输入信号共同决定组合逻辑电路的输出。

时序逻辑电路的结构框图如下所示: 其中各部分代表的含义如下:

X(x1, x2, …, xn)是外部输入信号,;Q(q1, q2, … , qj)是存储电路的状态输出,也是组合逻辑电路的内部输入;Z(z1, z2, …, zm)为外部输出信号;Y(y1, y2, …, yk)为存储电路的激励信号,也是组合电路的内部输出。

我们可以写出三大方程如下所示: 方程中的上标n和n+1表示相邻的两个离散时间(或称为相邻的两个节拍),n表示当前状态,n+1表示下一状态。

二、状态机

鉴于时序电路在工作时是在电路的有限个状态间按一定的规律转换的,所以又将时序电路称为状态机(State Machine, 简称SM )、有限状态机(Finite State Machine, 简称FSM)或算法状态机(Algorithmic State Machine, 简称ASM)。

有时还会根据输出信号的特点将状态机分成米利(Mealy)型状态机和摩尔(Moore)型状态机两种。

摩尔型状态机:输出仅仅取决于储存电路的状态;米利型状态机:输出不仅取决于存储电路的状态,而且还取决于输入变量。

另外,根据状态机的描述方式,可以分为一段式、两段式以及三段式状态机。

一段式:整个状态机写到一个always 模块里面。在该模块中既描述状态转移,又描述状态的输入和输出。两段式:用两个always模块来描述状态机。其中一个always 模块采用同步时序描述状态转移,另一个模块采用组合逻辑判断状态转移条件,描述状态转移规律及其输出。三段式:使用3个always模块。一个always 块采用同步时序描述状态转移,一个always采用组合逻辑判断状态转移条件和描述其状态转移规律,另一个always模块描述状态输出(可以用组合电路输出,也可以时序电路输出)。

三、序列检测器

设计一个111的序列检测器,当输入三个或三个以上1时,电路输出为1,否则为0。

我们可以得到状态转移图如下所示:

我们即可编写代码check0.v如下所示

module checker0(Z, X, clk, rst_n);

output reg Z; // 输出检测结果

input X, clk, rst_n; // 输入序列,时钟,复位

// 对状态进行定义

parameter s0 = 2'b00,

s1 = 2'b01,

s2 = 2'b11,

s3 = 2'b10;

reg[1:0] state, next_state;

// 描述状态转移

always@(posedge clk or negedge rst_n) begin

if(!rst_n) begin

state = s0;

next_state = s0;

end

else

state <= next_state;

end

// 判断状态转移条件和状态输出

always@(X, state) begin

case(state)

s0: if(X) begin

next_state <= s1;

Z <= 0;

end

else begin

next_state <= s0;

Z <= 0;

end

s1: if(X) begin

next_state <= s2;

Z <= 0;

end

else begin

next_state <= s0;

Z <= 0;

end

s2: if(X) begin

next_state <= s3;

Z <= 1;

end

else begin

next_state <= s0;

Z <= 0;

end

s3: if(X) begin

next_state <= s3;

Z <= 1;

end

else begin

next_state <= s0;

Z <= 0;

end

endcase

end

endmodule

编写测试代码tb.sv如下所示

module tb;

reg clk, rst_n, X;

wire Z;

bit data_in[] = {0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0};

checker0 dut(Z, X, clk, rst_n);

always#10 clk = ~clk;

initial begin

clk = 0; rst_n = 0;

#51 rst_n = 1'b1;

foreach(data_in[i]) begin

#20;

X = data_in[i];

end

#100;

$stop;

end

endmodule

仿真波形如下所示 我们可以看到,这是一个米利型的状态机,输出不仅和当前状态有关,还和输入有关。

四、附录

上一篇:Verilog学习之路(7)— 数字加法器 下一篇:Verilog学习之路(9)—计数器和移位寄存器

参考阅读

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。