FSM-based Digital Design 实例: 异步串行接收机

文章附图摘自《FSM-based Digitial Design Using Verilog HDL》

 

1. 系统框图

2. 状态转移图

 

3. FSM 

// async receiver fsm
// 
module async_rx_fsm (//input
st,en,rst,ack,ed,rxf,rxo,clk,
//output
PD,CDC,RXCK,DRY,ERR
);

input st; //start detection
input en; //enable the FSM
input rst;//reset signal
input ack; // feedback to data ready
input ed; // error detection input
input rxf; //div/11 counter can issue an full signal
input rxo; //unused
input clk; //fsm clock

output PD; // to pulse data latch
output CDC; // clear shift register and counter
output RXCK; //gating clock for counter and shift register
output DRY; //data ready signal
output ERR; //data error

parameter S0=4'b0000;
parameter S1=4'b1000;
parameter S2=4'b1100;
parameter S4=4'b1110;
parameter S5=4'b1111;
parameter S6=4'b1011;
parameter S7=4'b0011;
parameter S8=4'b0111;
parameter S9=4'b1101;
parameter S10=4'b0101;
parameter S11=4'b0110;
parameter S12=4'b0010;

reg [3:0] next_state;
reg [3:0] state;
always @(posedge clk or negedge rst) begin
		if (~rst)
				state <= 4'b0000;
		else 
				state <= next_state;
end
always @(*) begin
		case (state) 
			S0: begin
					if(en&~st)
							next_state = S1;
					else
							next_state = S0;
			end
			S1: begin
					next_state = S2;
			end
			S2: begin
					next_state = S4;
			end			
			S4: begin
					next_state = S5;
			end
			S5: begin
					if(~rxf)
						next_state = S6;
					else
						next_state = S9;
			end
			S6: begin
					next_state = S7;
			end
			S7: begin
					next_state = S8;
			end
			S8: begin
					next_state = S5;
			end
			S9: begin
					if (ed) 
						next_state = S11;
					else 
						next_state = S10;
			end
			S11: begin
					if(ack) 
						next_state = S12;
					else 
						next_state = S11;
			end
			S12: begin
					if (~ack) 
						next_state = S0;
					else
						next_state = S12;
			end
			default: begin
					next_state = S0;
			end
		
		endcase
end
assign RXCK = &state;
//0110
assign PD = (~state[3])&state[2]&state[1]&(~state[0]);
assign DRY = PD;
//0101
assign ERR = (~state[3])&state[2]&(~state[1])&state[0];  
//
assign CDC = ~(~st&en&(~|state));
endmodule
module async_rx_fsm_top (
//input
clk,en,ack,data_in,rst,
//output
DRY,ERR,qout
);
input clk;
input en;
input ack;
input data_in;
input rst;
output DRY;
output ERR;
output [7:0] qout;
//wire
wire RXCK;
wire CDC;
wire PD;
wire QST;
wire [7:0] Q_reg;
wire QSP1;
wire QSP2;
wire [10:0] shift_q;

wire rxf;
wire ed;
async_rx_fsm inst_fsm(//input
.st(data_in),
.en(en),
.rst(rst),
.ack(ack), // from testbench
.ed(ed),
.rxf(rxf),
.rxo(), // unused
.clk(clk),
//output
.PD(PD),
.CDC(CDC),
.RXCK(RXCK),
.DRY(DRY), // to testbench
.ERR(ERR)); // to testbench

div11_cnt inst_div_11 (
.clr(CDC),
.clk(RXCK),
//output
.q(rxf));

shift_regs inst_shift_regs (
.clk(RXCK),
.clr(CDC),
.in(data_in),
//output
.q(shift_q));
//
assign QST =shift_q[10];
assign Q_reg = shift_q[9:2];
assign {QSP2,QSP1} = shift_q[1:0];

assign ed = ~QST&&QSP1&&QSP2;
data_latch inst_data_latch (
.clk(PD),
.d(Q_reg),
//output
.q(qout));

endmodule

 

module tb();
reg clk;
reg rst;
reg st;
reg clk_in;
reg data_in;
reg en;
reg seed;
reg [7:0] wave;
wire clk_rxck;
		integer i; 
		       assign  clk_rxck = u_async_rx_fsm_top.inst_fsm.RXCK;
initial begin
          clk = 0;
          clk_in = 0;

          rst = 0;
          data_in = 1;
          en = 0;
          seed =0;
          wave = 7'b0110101;
    #20  rst = 1;
    @(posedge clk_in) ;
     data_in = 0;
     en=1;
    //for (i=0;i<7;i=i+1) begin
    	@(posedge clk_rxck) data_in = 1;
    	@(posedge clk_rxck) data_in = 0;
    	@(posedge clk_rxck) data_in = 0;
    	@(posedge clk_rxck) data_in = 1;
    	@(posedge clk_rxck) data_in = 0;
    	@(posedge clk_rxck) data_in = 1;
    	@(posedge clk_rxck) data_in = 1;
    //end
    @(posedge clk_rxck) data_in = 1;
    @(posedge clk_rxck) data_in = 1;
    #2000 $finish;
end
always #5 clk =~clk;
always #20 clk_in = ~clk_in;
async_rx_fsm_top u_async_rx_fsm_top (
//input
.clk(clk),
.en(en),
.ack(),
.data_in(data_in),
.rst(rst),
//output
.DRY(),
.ERR(),
.qout());

endmodule

 

waveform

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值