时序电路设计

 状态图描述
module checker(Z, X, clk); parameter s0 = 2'b00, s1 = 2'b01, s2 = 2'b11, s3 =
2'b10; output Z; input X, clk; reg [1:0] state, next_state; reg Z; always @(X,
state) 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 always @(posedge clk) state
<= next_state; endmodule

化简描述 

//序列检测器模块 module test (Z, X, clk); output Z; input X, clk; wire w1, w2; DFF U1
(.clk(clk), .D(X), .Q(w1)); DFF U2 (.clk(clk), .D(w1), .Q(w2)); assign Z = X &
w1 & w2; endmodule //D触发器模块 module DFF (Q, D, clk); output Q; input D, clk; reg
Q; always @(posedge clk) Q <= D; endmodule

 抽象描述方式
module checker (Z, X, clk); output Z; input X, clk; reg [2:0] q; reg Z; always
@(posedge clk) q<= {q[1:0], X}; always @(posedge clk) if(q==3'b111) Z=1; else Z
= 0; endmodule

触发器

最简D触发器

module DFF(q, clk, data_in); output q; input clk, data_in; reg q; always
@(posedge clk) q <= data_in; endmodule
带复位端的D触发器 
module DFF_rst (q, clk, reset, data_in); output q; input clk, reset, data_in;
reg q; always @(posedge clk) if (!reset) q <= 0; else q <= data_in; endmodule
复杂功能的D触发器 
module DFF_l(q, clk, resetl, reset2, data_in); output q; input clk, reset1,
reset2, data_in; reg q; always @(posedge clk) if (!reset1) q <= 0; else q <=
data_in; always @(posedge clk or negedge reset2) if (!reset2) q <= 0; else q <=
data_in; endmodule
T触发器

module TFF(data_out, T, clk, reset); output data_out; input T, clk, reset; reg
data_out; always @(posedge clk or negedge reset) if (!reset) data_out <= 1'b0;
else if (T) data_out <= ~data_out; endmodule
计数器

二进制计数器

module comp2bit (Q, clk, reset); output Q; input clk, reset; reg Q; always @
(posedge clk or negedge reset) if (!reset) Q<= 1'b0; else Q <= ~Q; endmoduld
任意进制计数器 

        对于M进制的计数器,首先应确定计数器所需触发器的个数。N个触发器对应了 2^n

个状态,应有2^n>M。任意进制计数器选取满足条件的最小N, N为计数器中触发器的个数。

        以十一进制计数器为例,最少需要4个触发器。
module comp_11 (count, clk, reset); output [3:0] count; input clk, reset; reg
[3:0] count; always @ (posedge clk) if(reset) count <= 4'b0000; else if (count
== 4'b1010) count <= 4'b0000; else count <= count+1; endmodule
移位寄存器

环形移位寄存器
module shiftregistl(D, clk, reset); parameter shiftregist_width = 4; output
[shiftregist_width-1:0] D; input clk, reset; reg [shiftregist_width-1:0] D;
always @(posedge clk) if (!reset) D <= 4'b0000; else D <=
{D[shiftregist_width-2:0], D[shiftregist_width-1]}; endmodule
序列信号发生器

由移位寄存器构成

module signal_maker(out, clk, load, D); parameter M = 6; output out; input
clk, load; input [M-1:0] D; reg [M-1:0] Q; initial Q = 6'b100111; always
@(posedge clk) if (load) Q <= D; else Q <= {Q[M-2:0], Q[M-1]}; assign out =
Q[M-1]; endmodule
由移位寄存器和组合逻辑电路构成 

        首先确定所需移位寄存器的个数n。因M = 6,故 n>=3。其次确定移位寄存器的6个独立状态。按照移位规律每三位一组,划分6个状态为
100、001、011、111, 111、110。其中状态111重复出现,故取n = 4,并重新划分状态,
得到1001、0011、0111、1111、1110、1100。因此确定n = 4。第三,列态序表和反馈激励函数表,求反馈函数F的表达式。

F= ~Q3 + ~Q1 • ~Q0 +Q3+~Q2

module signal_maker(out, clk, load, D); parameter M = 4; output out; input
clk, load; input [M-1 :0] D; reg [M-1:0] Q; wire w1; always @(posedge clk)
//时序电路部分,移位寄存器 if (load) Q<=D; else Q <= {Q[M-2:0], w1}; assign w1
=(~Q[3])|(~Q[1]&(~Q[0]))|(Q[3]&(~Q[2])); //组合逻辑电路,反馈网络 assign out =Q[M-1];
endmodule

由计数器构成

module signal_maker(out, clk, reset); parameter M = 3; output out; input clk,
reset; reg [M-l:0] counter; always @(posedge clk) if (!reset) counter <=
3'b000; else counter <= counter+1; assign out =
counter[2]|((~counter[1])&(~counter[0]))l(counter[1]&counter[0]); endmodule
有限同步状态机

        Mealy型状态机的输出与当前状态和输入有关

        Moore型状态机的输出仅依赖于当前状态, 而与输入无关

状态机的编码方式:

* 二进制编码:其状态寄存器是由触发器组成的。
* 格雷编码:格雷编码状态跳转时只有一个bit(位)发生变化,减少了产生毛刺和一些暂态的可能。
* 一位独热编码:这是对于n个状态采用n个bit(位)来编码,每个状态编码中只有一个bit(位)为1,如0001、0010、0100、1000。
状态机的两段式描述方法:
//第一个进程,同步时序always模块,格式化描述次态寄存器迁移到现态寄存器 always @(posedge clk or negedge rst_n)
//异步复位 if(!rst_n) current_state <= IDLE; else current_state <= next_state;
//注意,使用的是非阻塞赋值 //第二个进程,组合逻辑 always模块,描述状态转移条件判断 always @(current_state or 输入信号)
//电平触发 begin next_state = x; //要初始化,使得系统复位后能进入正确的状态 case(current_state)
Sl:if(...) next_state = S2; //阻塞赋值 outl <= 1'bl; //注意是非阻塞逻辑 ... endcase end
状态机的三段式描述方法:
//第一个进程,同步时序always模块,格式化描述次态寄存器迁移到现态寄存器 always @(posedge clk or negedge rst_n)
//异步复位 if(!rst_n) current_state <= IDLE; else current_state <= next_state;
//注意,使用的是非阻塞赋值 //第二个进程,组合逻辑always模块,描述状态转移条件判断 always @(current_state or 输入信号)
//电平触发 begin next_state = x; //要初始化,使得系统复位后能进入正确的状态 case(current_state) S1:
if(...) next_state = S2; //阻塞赋值 ... endcase end
//第三个进程,同步时序always模块,格式化描述次态寄存器输出 always @ (posedge clk or negedge rst_n) begin
...//初始化 case(next_state or 输入信号) S1: outl <= 1'bl; //注意是非阻塞逻辑 S2: outl <=
1'b0; default:... //default的作用是免除综合工具综合出锁存器 endcase end
4位顺序脉冲发生器

module state4(OUT, clk, rst_n); output [3:0] OUT: input clk; input rst_n; reg
[3:0] OUT; reg [1:0] STATE, next_STATE; always @(STATE) case (STATE) 2'b00:
begin OUT <= 4'b11000; next_STATE <= 2'b01; 2'b01: begin OUT <= 4'b0100;
next_STATE <= 2'b10; end 2'b10: begin OUT<= 4'b0010; next_STATE <= 2'b11; end
2'bll: begin OUT <= 4'b0001; next_STATE <= 2'b00; end endcase always @(posedge
clk or negedge rst_n) if(!rst_n) STATE <= 2'b00: else STATE <= next_STATE;
endmodule
 自动售报机

module auto_sellor(current_state, data_out, data_out_return1,
data_out_return2, clk, rst_n, data_in); parameter state_width = 3,
data_in_width = 3; output [state_width-1:0] current_state; output data_out,
data_out_return1, data_out_return2; input [dala_in_width-1:O] data_in; input
clk, rst_n; reg [state_width-l:OJ current_state, next_state; reg data_out,
data_out_returnl, data_out_return2; always @(current_state or data_in) case
(current_state) 3'b000: case (data_in) 3'b000: begin next_state <= 3'b000;
data_out <= 1'b0; data_out_return1 <= 1'b0; data_out_return2 <= 1'b0; end
3'b001: begin next_state <= 3'b001; data_out <= 1'bO; data_out_return 1 <=
1'bO; data_out_retum2 <= 1'bO; end 3'b010: begin next_state <= 3'b010; data_out
<= 1'b0; data_out_return1 <= 1'b0; data_out_return2 <= 1'b0; end 3'b011: begin
next_state <= 3'bl01; data_out <= 1'bO; data_out_return 1 <= 1'bO;
data_out_retum2 <= 1'bO; end 3'bl00: begin next_state <= 3'bOOO; data_out <=
1'bl; data_out_retum1 <= 1'bO; data_out_retum2 <= 1'bl; end endcase 3'b001:
case (data_in) 3'b000: begin next_state <= 3'b001; data_out <= 1'b0;
data_out_retum1 <= 1'b0; data_out_retum2 <= 1'b0; end 3'b001: begin next_state
<= 3'b010; data_out <= 1'b0; data_out_return1 <= 1'b0: data_out_return2 <=
1'b0; end 3'b010: begin nexl_state <= 3'b011; data_out <= 1'b0;
data_oul_return1 <= 1'b0; data_out_return2 <= 1'b0: end 3'b011: begin
next_state <= 3'b110; data_out <= 1'b0; data_out_return1 <= 1'b0;
data_out_return2 <= 1'b0: end endcase 3'b010: case (daia_in) 3'b000: begin
next_state <= 3'b010; data_out <= 1'b0; data_out_returnl <= 1'b0;
data_out_return2 <= 1'b0; end 3'bOO1: begin next_state <= 3'b011; data_out <=
1'b0; data_out_return1 <= 1'b0; data_oul_return2 <= 1'b0; end 3'b010: begin
next_state <= 3'b100; data_out <= 1'b0; data_out_return1 <= 1'b0;
data_out_return2 <= 1'b0; end 3'b011: begin next_state <= 3'b111; data_out <=
1'b0; data_out_return1 <= 1'b0; data_out_return2 <= 1'b0; end endcase 3'bO11:
case (data_in) 3'b000: begin next_state <= 3'b011; data_out <= 1'b0;
data_out_retuml <= 1'b0; data_out_return2 <= 1'b0; end 3'b001: begin next_state
<= 3'b100; data_out <= 1'b0; data_out_return1 <= 1'b0; data_out_return2 <=
1'b0; end 3'b010: begin next_state <= 3'b101; data_out <= 1'b0;
data_out_return1 <= 1'b0; data_out_return2 <= 1'b0; end 3'b011: begin
next_state <= 3'b000; data_out <= 1'b1; data_out_returnl <= 1'b0;
data_out_return2 <= 1'b0; end endcase 3'blOO: case (data_in) 3'bOOO: begin
next_state <= 3'b000; data_out <= 1'b0; data_out_return1 <= 1'b0;
data_out_return2 <= 1'b0; end 31)001: begin next_state <= 3'b101; data_out <=
1'b0; data_out_return1 <= 1'b0; data_out_return2 <= 1'b0; end 3'b010: begin
next_state <= 3'b110; data_out <= 1'b0; data_oul_return1 <= 1'b0;
data_out_retumrn2 <= 1'b0; end 3'b011: begin next_state <= 3'b000; data_out <=
1'b1; data_out_return1 <= 1'b1; data_out_return2 <= 1'b0; end endcase 3'b101:
case (data_in) 3'bOOO: begin next_state <= 3'b101; data_out <= 1'b0;
data_out_retuml <= 1'b0; data_out_retum2 <= 1'b0; end 3'bOO1: begin next_state
<= 3'b110; data_out <= 1'b0; data_out_return1 <= 1'b0; data_out_return2 <=
1'b0; end 3'b010: begin next_state v= 3'bl 11; data_out <= 1'bO;
data_out_retum1 <= 1'bO; data_out_retum2 <= 1'bO; end 3'bO11: begin next_state
<= 3'b000; data_out <= 1'b1; data_out_return1 <= 1'b0; data_out_return2 <=
1'b1; end endcase 3'b110: case (data_in) 3'b000: begin next_state <= 3'b110:
data_out <= 1'b0; data_out_return1 <= 1'b0; data_out_relurn2 <= 1'b0: end
3'b001: begin next_state <= 3'b111; data_out <= 1'b0; data_out_relurnl <= 1'bO:
data_out_return2 <= 1'bO; end 3'b010: begin next_state <= 3'bOOO; data_out <=
1'b1; data_out_return1 <= 1'bO; data_out_return2 <= 1'bO; end endcase 3'b111:
case (data_in) 3'bOOO: begin next_state <= 3'b111; data_out <= 1'b0;
data_oul_return 1 <= 1'b0; data_out_retum2 <= 1'b0; end 3'bOO1: begin
next_state <= 3'b000; data_out <= 1'b1; data_out_retum 1 <= 1'b0;
data_out_return2 <= 1'b0; end endcase endcase always @(posedge clk or rst_n)
if(!rst_n) current_state <= 3'bOOO; else current_state <= next_state; endmodule
“11010”序列检测器

module seqdet (D_out, D_in, rst_n, clk); parameter IDLE = 3'd0, A = 3'd1,B =
3'd2, C = 3'd3, D = 3'd4, E = 3'd5; output D_out; input D_in, rst_n, clk; reg
[2:0] state, next_state; wire D_out; assign D_out = (state == E)? 1:0; always
@(state or D_in) case (state) IDLE : if(D_in) next_state = A; else next_state =
IDLE; A : if(D_in) next_state = B; else next_state = IDLE; B : if(D_in)
next_state = B; else next_state = C; C : if (D_in) next_state = D; else
next_state = IDLE; D : if (D_in) next_state = B; else next_state = E; E : if
(D_in) next_state = IDLE; else next_state = A; default: next_state = IDLE;
endcase always @(posedge clk) state <= next_state; endmodule

技术
下载桌面版
GitHub
Gitee
SourceForge
百度网盘(提取码:draw)
云服务器优惠
华为云优惠券
腾讯云优惠券
阿里云优惠券
Vultr优惠券
站点信息
问题反馈
邮箱:[email protected]
吐槽一下
QQ群:766591547
关注微信