集成电路技术分享

 找回密码
 我要注册

QQ登录

只需一步,快速开始

搜索
查看: 953|回复: 1

状态机程序

[复制链接]
小舍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 [7:0]  wrd_add;//iic器件地址
input      sda_pin;//iic数据多用输入
output     sda;//iic总线数据输出
output     scl;//iic总线时钟输出
output     scl_cnt_en;//总线计数使能端
output     iic_rdy;//总线准备好
output     iic_act;//总线周期响应
output [7:0] iic_rdata;//总线上的数据
output     ack_err;//响应错误
//寄存器型
    reg       sda;
reg       scl;
reg       scl_cnt_en;
reg       iic_rdy;
reg [7:0]  iic_rdata;
reg[14:0]  iic_state;
reg [2:0]  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) &&         // write  address
             (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[bit_cntr];
    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[bit_cntr] <= #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     

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?我要注册

x
 楼主| 小舍YZ 发表于 2017-9-23 17:05:47 | 显示全部楼层
状态机                                                      

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?我要注册

x
您需要登录后才可以回帖 登录 | 我要注册

本版积分规则

关闭

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

QQ|小黑屋|手机版|Archiver|fpga论坛|fpga设计论坛 ( 京ICP备20003123号-1 )

GMT+8, 2025-4-20 09:28 , Processed in 0.060506 second(s), 21 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表