小舍YZ 发表于 2017-9-23 17:04:32

状态机程序

状态机程序

`timescale 1 ns/100 ps
module iic_st(rst_l,clock,scl_tick,iic_go,wrd_add,sda_pin,sda,scl,scl_cnt_en,                         iic_rdy, iic_act, iic_rdata, ack_err); //端口列表
input      rst_l;//复位
input      clock;//系统时钟
input      scl_tick;//scl的时钟
input      iic_go;//启动iic总线周期
input wrd_add;//iic器件地址
input      sda_pin;//iic数据多用输入
output   sda;//iic总线数据输出
output   scl;//iic总线时钟输出
output   scl_cnt_en;//总线计数使能端
output   iic_rdy;//总线准备好
output   iic_act;//总线周期响应
output iic_rdata;//总线上的数据
output   ack_err;//响应错误
//寄存器型
    reg       sda;
reg       scl;
reg       scl_cnt_en;
reg       iic_rdy;
reg iic_rdata;
regiic_state;
reg bit_cntr;
reg      scl_en;
reg      en_cntr;
reg      cntr_done;
reg   ack_err;
wire    iic_act;
//参数
parameter   idle   = 4'b0000;   // state 0
parameter   en_clk   = 4'b0001;   // state 1
parameter   start1   = 4'b1100;   // state C
parameter   dev_add1 = 4'b1000;   // state 8
parameter   ack1   = 4'b0100;   // state 4
parameter   w_add    = 4'b1010;   // state A
parameter   ack2   = 4'b0101;   // state 5
parameter   wait1    = 4'b0011;   // state 3
parameter   dis_clk1 = 4'b1111;   // state F
parameter   start2   = 4'b1101;   // state D
parameter   dev_add2 = 4'b1001;   // state 9
parameter   ack3   = 4'b0110;   // state 6
parameter   data   = 4'b1011;   // state B
parameter   ack4   = 4'b0111;   // state 7
parameter   stop1    = 4'b1110;   // state E
//状态机
always @(posedge clock or negedge rst_l)
    if (!rst_l)
            iic_state <= #1 idle;
    else case(iic_state)
      idle : if (iic_go)
      iic_state <= #1 en_clk;         
    en_clk : if (scl_tick)
      iic_state <= #1 start1;            
    start1 : if (scl_tick)
      iic_state <= #1 dev_add1;            
    dev_add1 : if (cntr_done && scl_tick)
      iic_state <= #1 ack1;      
    ack1 : if (scl_tick && scl)
      iic_state <= #1 w_add;            
    w_add : if (cntr_done && scl_tick)
      iic_state <= #1 ack2;               
    ack2 : if (scl_tick && scl)
      iic_state <= #1 dis_clk1;         
    dis_clk1 : if (scl_tick && scl)
      iic_state <= #1 wait1;         
    wait1 : if (scl_tick)
      iic_state <= #1 start2;
    start2 : if (scl_tick)
      iic_state <= #1 dev_add2;
    dev_add2 : if (cntr_done && scl_tick)
      iic_state <= #1 ack3;         
    ack3 : if (scl_tick && scl)
      iic_state <= #1 data;
    data : if (cntr_done && scl_tick)
      iic_state <= #1 ack4;
    ack4 : if (scl_tick && scl)
      iic_state <= #1 stop1;         
    stop1 : if (scl_tick && scl)

      iic_state <= #1 idle;               
      default :
                iic_state <= #1 idle;         
    endcase
// 位计数器
always @(posedge clock or negedge rst_l)
    if (!rst_l)
      bit_cntr <= #1 3'b111;
    else if (en_cntr && scl && scl_tick)
      bit_cntr <= #1 bit_cntr - 1;
         
always @(posedge clock or negedge rst_l)
    if (!rst_l)
      cntr_done <= #1 1'b0;
    else if (bit_cntr == 3'b0 && scl)
      cntr_done <= #1 1'b1;
    else
      cntr_done <= #1 1'b0;
         
always @(posedge clock or negedge rst_l)
    if (!rst_l)
      en_cntr <= #1 1'b0;
    else if ((iic_state == dev_add1) ||
             (iic_state == w_add)    ||
             (iic_state == dev_add2) ||
             (iic_state == data))
      en_cntr <= #1 1'b1;
    else if (cntr_done)
      en_cntr <= #1 1'b0;
         
//-------------------------------------------------------------------

//产生 scl
// 使能时钟分频器
always @(posedge clock or negedge rst_l)
    if (!rst_l)
      scl_cnt_en <= #1 1'b0;
    else if (iic_state == en_clk)
      scl_cnt_en <= #1 1'b1;
    else if (iic_state == idle)
      scl_cnt_en <= #1 1'b0;         
   
always @(posedge clock or negedge rst_l)
    if (!rst_l)
      scl_en <= #1 1'b0;
    else if (iic_state == start1)
      scl_en <= #1 1'b1;
    else if (iic_state == dis_clk1 && scl_tick)
      scl_en <= #1 1'b0;
    else if (iic_state == start2)
      scl_en <= #1 1'b1;
    else if (iic_state == stop1 && scl)
      scl_en <= #1 1'b0;
      
always @(posedge clock or negedge rst_l)
    if (!rst_l)
      scl <= #1 1'b1;
    else if (scl_en && scl_tick)
      scl <= #1 ~scl;   
//产生sda
always @(posedge clock or negedge rst_l)
    if (!rst_l)
      sda <= #1 1'b1;      

    else if ((iic_state == start1)   ||         // starts
             (iic_state == start2)   ||
             (iic_state == stop1)    ||
            ((iic_state == dev_add1) &&         // writeaddress
             (bit_cntr != 3'b111)    &&         // device bit 7
             (bit_cntr != 3'b101))   ||         // device bit 5
            ((iic_state == dev_add2) &&         // read address
             (bit_cntr != 3'b111)    &&         // device bit 7
             (bit_cntr != 3'b101)    &&         // device bit 5
             (bit_cntr != 3'b000)))             // read bit
      sda <= #1 1'b0;
    else if((iic_state == w_add))               // word address
      sda <= #1 wrd_add;
    else
      sda <= #1 1'b1;

always @(posedge clock or negedge rst_l)
    if (!rst_l)
      iic_rdata <= #1 8'b0;
    else if ((iic_state == data) && scl)
      iic_rdata <= #1 sda_pin;
    else if (iic_go)
      iic_rdata <= #1 8'b0;
         
always @(posedge clock or negedge rst_l)
    if (!rst_l)
      iic_rdy <= #1 1'b0;
    else if ((iic_state == stop1) && scl)
      iic_rdy <= #1 1'b1;
    else if (iic_go)
      iic_rdy <= #1 1'b0;

         
always @(posedge clock or negedge rst_l)
    if (!rst_l)
      ack_err <= #1 1'b0;
    else if (((iic_state == ack1)||
            (iic_state == ack2)||
            (iic_state == ack3)) && scl && sda_pin)
      ack_err <= #1 1'b1;
    else if (iic_go)
      ack_err <= #1 1'b0;
      assign iic_act = ~(iic_state == idle);
          endmodule   

小舍YZ 发表于 2017-9-23 17:05:47

状态机                                                      
页: [1]
查看完整版本: 状态机程序