sdlyyuxi的个人空间 https://blog.eetop.cn/907322 [收藏] [复制] [分享] [RSS]

空间首页 动态 记录 日志 相册 主题 分享 留言板 个人资料

日志

FSM-based Digital Design 实例: 串行发送器状态机

已有 684 次阅读| 2018-12-15 18:23 |个人分类:FSM|系统分类:芯片设计

根据书中讲解,用Verilog实现了功能,经过简单的仿真,状态机可以正常工作。

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

1 系统框图


状态机控制下将计数器的数值并行加载到移位寄存器中,并串行发送出去;

2 状态转移图


3. fsm 

module tx_fsm(//input

rst,st,re,done,clk,

//output

CB,RC,LD);

input clk;

input rst; // reset of fsm

input st; // start of FSM

input re; // shift done

input done;// counter run out

output CB;//clock counter

output RC;//reset counter

output LD;//loading default counter


parameter S0= 3'b000;

parameter S1= 3'b010;

parameter S2= 3'b110;

parameter S3= 3'b100;

parameter S4= 3'b101;

parameter S5= 3'b111;

parameter S6= 3'b011;


//state diagram

//

reg [2:0] next_state;

reg [2:0] state;

always @(posedge clk or negedge rst) begin 

if (~rst) 

state <= 3'b000;

else 

state <= next_state;

end


always @(*) begin

case(state)  

S0: begin // st assert as high, then FSM starts

if (st) 

next_state = S1;

else

next_state = S0;

end

S1: begin // release reset from binary counter

next_state = S2;

end

S2: begin // load parallel data into shift reg

next_state = S3;

end

S3: begin

next_state = S4;

end

S4: begin

if (re) 

next_state =S5;

else 

next_state =S4;

end

S5: begin

if (done) 

next_state = S6;

else 

next_state = S1;

end

S6: begin

if (st)

next_state = S6;

else 

next_state = S0;

end 

default: next_state =S0;

endcase

end

assign RC = |state;

assign LD = ~state[2]|~state[1]|state[0];// /LD = AB/C

assign CB = state[2]&~state[1]&~state[0];


endmodule

4. shift_regs and binary counter

module shift_regs (//input

P,Ld,rst,clk,

//output

TX,RE);

input [3:0] P;

input Ld;

input rst;

input clk;

output TX;

output RE;


reg [3:0] shift_regs;

reg [3:0] shift_cnt;

always @(posedge clk or negedge rst) begin

  if(~rst) begin

    shift_regs <= 4'b0000;

    shift_cnt <= 4'b0000;

  end else if (~Ld)

    shift_regs <= P;

  else begin

    shift_regs <= {shift_regs[2:0],1'b0};

    if(shift_cnt<4'b1000)

      shift_cnt <= shift_cnt + 1;

    else

      shift_cnt <= 4'b0000;

  end

end

assign TX = shift_regs[3];

assign RE = shift_cnt[3];

endmodule

module binary_cnt (//input

clk,rst,

//output

q);

input clk;

input rst;

output reg [3:0] q;

always @(posedge clk or negedge rst) begin

  if (~rst) 

     q<=4'b0000;

  else

     q<=q+1;

end

endmodule

5. top and tb
module tx_top (// input
clk,rst,st,
//output
TX);

input clk;
input rst;
input st;
output TX;

wire done;
wire [3:0] q;
assign done = q[3]&q[2]&q[1]&q[0]; 

wire RE;
wire clk_bin;
wire RC;
wire LD;
// instantiation
tx_fsm u_tx_fsm (
//input
.rst(rst),
.st(st),
.re(RE),
.done(done),
.clk(clk),
//output
.CB(clk_bin),
.RC(RC),
.LD(LD));

binary_cnt u_bin_cnt (
.rst(RC),
.clk(clk_bin),
.q(q));

shift_regs u_sft_regs (
.Ld(LD),
.clk(clk),
.rst(RC),
.P(q),
.RE(RE),
.TX(TX));

endmodule

module tb();
reg clk;
reg rst;
reg st;
wire TX;
initial begin
          clk = 0;
          rst = 0;
          st = 0;
 //         rstn_r = 0;
 //         resume = 0;
 //         seed = 0;
 //         enable = 0;
    #20  rst = 1;
    #40  st =1;
    #2000 $finish;
end
always #5 clk =~clk;
tx_top u_tx_top (// input
.clk(clk),
.rst(rst),
.st(st),
//output
.TX(TX));  

endmodule

6. waveform



点赞

发表评论 评论 (1 个评论)

回复 sdlyyuxi 2018-12-15 18:27
https://blog.csdn.net/u012369580/article/details/85016513

facelist

您需要登录后才可以评论 登录 | 注册

  • 关注TA
  • 加好友
  • 联系TA
  • 0

    周排名
  • 0

    月排名
  • 0

    总排名
  • 1

    关注
  • 4

    粉丝
  • 0

    好友
  • 0

    获赞
  • 3

    评论
  • 538

    访问数
关闭

站长推荐 上一条 /1 下一条

小黑屋| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-4-27 22:05 , Processed in 0.025421 second(s), 16 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
返回顶部