3238|4

73

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

这个i2c程序仿真错在哪了? [复制链接]

module i2c(
   input                 clk,
   input                 rst_n,
   input                enable,
   output reg        scl,
   inout                 sda,
   output reg[7:0] dout,
   output reg[3:0] state,
   output reg[2:0] cmd,
   output reg[4:0] i_state,
   output reg[4:0] i_next_state,
   output reg        r_w,
   output reg        next,
   output reg[3:0] bit_num
 );


reg           ack_data;
reg           bit_num_check;
reg           bit_false;
reg           sda_reg;
reg [  7:0] sec_value;
reg [19:0]  delay_num;
reg [  3:0]  next_state;
 

parameter idle                 = 4'd0;    parameter start_1             = 4'd1; 
parameter sla_w              = 4'd2;    parameter sla_w_ack        = 4'd3; 
parameter sec_addr        = 4'd4;    parameter sec_addr_ack  = 4'd5; 
parameter start_2            = 4'd6;    parameter sla_r                = 4'd7; 
parameter sla_r_ack        = 4'd8;    parameter sec_data         = 4'd9; 
parameter sec_data_ack = 4'd10;  parameter stop                 = 4'd11;
parameter delay               = 4'd12;

parameter i_idle     = 5'd0;      parameter start_a = 5'd1; 
parameter start_b  = 5'd2;      parameter start_c = 5'd3; 
parameter bit_a     = 5'd4;      parameter bit_b    = 5'd5; 
parameter bit_c     = 5'd6;      parameter ack_a   = 5'd7; 
parameter ack_b   = 5'd8;      parameter ack_c   = 5'd9; 
parameter stop_a  = 5'd10;    parameter stop_b  = 5'd11; 
parameter stop_c  = 5'd12;    parameter stop_d  = 5'd13;
parameter stop_e  = 5'd14;    parameter stop_f  = 5'd15;
parameter i_delay = 5'd16;

 

parameter cmd_start = 3'd0;    
parameter cmd_byte  = 3'd1;
parameter cmd_ack   = 3'd2;
parameter cmd_stop  = 3'd3;
parameter cmd_delay = 3'd4;

[ 本帖最后由 andyandy 于 2010-11-5 09:44 编辑 ]
此帖出自FPGA/CPLD论坛
点赞 关注
 

回复
举报

73

帖子

0

TA的资源

一粒金砂(初级)

沙发
 

always@(posedge clk)
if(!rst_n)      begin                  state <= idle;                               i_state <= idle;           r_w <= 0; end
else if(enable)        begin    state <= next_state;    i_state <= i_next_state;   end

always@(posedge clk)
if(enable)
case(state)
        idle:                       begin                cmd               <= cmd_start;
                             next_state <= start_1;        end
                       
        start_1:                    if(next) begin                cmd               <= cmd_byte;
                                                           r_w               <= 1'b0;
                                                         next_state <= sla_w;                end

        sla_w:               begin        if(!bit_num_check)  next_state <= idle;
                                      if(next) begin                                cmd               <= cmd_ack;
                                                               r_w               <= 1'b1;
                                                             next_state <= sla_w_ack;        end        end

        sla_w_ack:           if(ack_data)          next_state <= idle;
                                else begin     cmd               <= cmd_byte;
                                                    r_w               <= 1'b0;
                                                    next_state <= sec_addr;         end

        sec_addr:            begin        if(!bit_num_check)                                next_state   <= idle;
                                      if(next) begin                                cmd               <= cmd_ack;
                                                             r_w               <= 1'b1;
                                                             next_state <= sec_addr_ack;        end
                                     end
        sec_addr_ack:        if(ack_data)  next_state <= idle;
                                else begin                  cmd               <= cmd_start;
                                                   next_state <= start_2;         end

        start_2:                    if(next) begin                                cmd           <= cmd_byte;
                                                       r_w           <= 1'b0;
                                                   next_state <= sla_r;                end

        sla_r:               begin        if(!bit_num_check)                next_state <= idle;
                                      if(next) begin                                  cmd           <= cmd_ack;
                                                               r_w           <= 1'b1;
                                                               next_state <= sla_r_ack;        end
                                     end
        sla_r_ack:                  if(ack_data)                next_state  <= idle;
                                   else begin                cmd              <= cmd_byte;
                                                        next_state  <= sec_data;         end

        sec_data:            begin            if(!bit_num_check) next_state <= idle;
                                              if(next) begin            cmd <= cmd_ack;
                                                                             r_w <= 1'b0;
                                                                      next_state <= sec_data_ack;        end       
                                     end       
        sec_data_ack:        if(next) begin                cmd <= cmd_stop;      next_state   <= stop;          end
        stop:                      if(next) begin                cmd <= cmd_delay;                next_state   <= delay;          end
        delay:                   if(next) begin    cmd <= cmd_start;                next_state   <= start_1;        end
        default:                                                                           next_state   <= start_1;       
endcase

always@(posedge clk)
if(enable)
case(i_state)
i_idle:          begin bit_num_check <= 1'b1;
                next                 <= 1'b0;
                           case(cmd)
                                    cmd_start:                      i_next_state <= start_a;
                                    cmd_byte:         begin         i_next_state <= bit_a;            bit_num   <= 4'd8;        end
                                    cmd_ack:                        i_next_state <= ack_a;
                                      cmd_stop:                       i_next_state <= stop_a;
                                      cmd_delay:        begin         i_next_state <= i_delay;           delay_num <= 20'd1000000;  end
                                    default:                        i_next_state <= i_idle;
                            endcase
                 end       
start_a:                       i_next_state <= start_b;
start_b:                       i_next_state <= start_c;      
start_c:         begin         i_next_state <= i_idle;                  next    <= 1'b1;                         end
bit_a:           begin         i_next_state <= bit_b;            bit_num <= bit_num - 4'b1;        end
bit_b:                                       i_next_state <= bit_c;
bit_c:           begin         if(!bit_false) begin                   i_next_state <= i_idle;                bit_num_check <= 1'b0;        end       
                           else if(bit_num != 4'd0)        i_next_state <= bit_a;
                           else         begin                            i_next_state <= i_idle;                next <= 1'b1;        end        end
               
ack_a:                  i_next_state <= ack_b;
ack_b:                         i_next_state <= ack_c;
ack_c:                         i_next_state <= i_idle;
stop_a:                 i_next_state <= stop_b;
stop_b:                        i_next_state <= stop_c;
stop_c:                        i_next_state <= stop_d;               
stop_d:                        i_next_state <= stop_e;
stop_e:                        i_next_state <= stop_f;
stop_f:          begin         i_next_state <= i_idle;                    next <= 1'b1;                end
i_delay:         begin         delay_num    <= delay_num -1;
                           if(delay_num != 20'd0)        i_next_state <= i_delay;
                           else         begin                      i_next_state <= i_idle;                next <= 1'b1;        end       
                     end
default:                       i_next_state <= i_idle;
endcase

always@(posedge clk)
if(enable)
case(i_state)
i_idle:  begin        scl <= scl;        sda_reg <= sda_reg;        end
start_b,
stop_a,
stop_b,
stop_c,       
stop_d,
stop_e:          begin        scl <= 1'b1;        sda_reg <= 1'b0;        end
start_c:         begin        scl <= 1'b0;        sda_reg <= 1'b0;        end

bit_a:         begin        scl <= 1'b0;        case(state)
                                          sla_w:        begin bit_false <= 1'b1;
                                                                                        case(bit_num)
                                                     8:        sda_reg <= 1'b1;                                7:        sda_reg <= 1'b0;
                                                     6:        sda_reg <= 1'b1;                                5:        sda_reg <= 1'b0;
                                                     4:        sda_reg <= 1'b0;                                3:        sda_reg <= 1'b0;
                                                     2:        sda_reg <= 1'b1;                                1:        sda_reg <= 1'b0;
                                                     default:        bit_false <= 1'b0;
                                                     endcase end
                                          sla_r:        begin bit_false <= 1'b1;
                                                                                        case(bit_num)
                                                     8:        sda_reg <= 1'b1;                                7:        sda_reg <= 1'b0;
                                                     6:        sda_reg <= 1'b1;                                5:        sda_reg <= 1'b0;
                                                     4:        sda_reg <= 1'b0;                                3:        sda_reg <= 1'b0;
                                                     2:        sda_reg <= 1'b1;                                1:        sda_reg <= 1'b1;
                                                     default:        bit_false <= 1'b0;
                                                     endcase end
                                          sec_addr:        begin bit_false <= 1'b1;
                                                                                        case(bit_num)
                                                     8:              sda_reg <= 1'b0;                                7:              sda_reg <= 1'b0;
                                                     6:              sda_reg <= 1'b0;                                5:              sda_reg <= 1'b0;
                                                     4:              sda_reg <= 1'b0;                                3:              sda_reg <= 1'b0;
                                                     2:              sda_reg <= 1'b1;                                1:              sda_reg <= 1'b0;
                                                     default:        bit_false <= 1'b0;
                                                     endcase end
                                                               endcase                                       
                        end

bit_b:         begin        scl <= 1'b1;   if(state == sec_data)        begin bit_false <= 1'b1;
                                                                                case(bit_num)
                                                                            7:              sec_value[7] <= sda;                                6:              sec_value[6] <= sda;
                                                                            5:              sec_value[5] <= sda;                                4:              sec_value[4] <= sda;
                                                                            3:              sec_value[3] <= sda;                        2:              sec_value[2] <= sda;
                                                                            1:              sec_value[1] <= sda;                                0:              sec_value[0] <= sda;
                                                                            default:        bit_false           <= 1'b0;
                                                                       endcase        end                               
                        end
bit_c:          begin        scl <= 1'b0;          if(state == sec_data)                    dout     <= sec_value;        end
ack_a:          begin        scl <= 1'b0;         if(state == sec_data_ack)         sda_reg  <= 1'b0;             end
ack_b:          begin        scl <= 1'b1;         if(state != sec_data_ack)  ack_data <= sda;              end
ack_c:                       scl <= 1'b0;
default:        begin        scl <= 1'b1;         sda_reg <= 1'b1;        end
endcase

assign        sda = (!r_w)? sda_reg:1'bz;       

endmodule
此帖出自FPGA/CPLD论坛
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

板凳
 

请见谅!

格式不好,改起来更烦。
稍后我会上传文件和仿真波形。
网络太差。
此帖出自FPGA/CPLD论坛
 
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

4
 

仿真波形

最早不正确的是bit_num。原意是仅在i_state等于bit_a(也就是4)时递减,但仿真不是这样。

哪位大侠能告诉我原因?谢谢!

1.JPG (104.7 KB, 下载次数: 0)

1.JPG
此帖出自FPGA/CPLD论坛
 
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

5
 

testbench

module test_v;

        // Inputs
        reg clk;
        reg rst_n;
        reg enable;

        // Outputs
        wire scl;
        wire [7:0] dout;
        wire [3:0] state;
        wire [4:0] i_state;
        wire [4:0] i_next_state;
        wire [2:0] cmd;
        wire       r_w;
        wire       next;
        wire [3:0] bit_num;

        // Bidirs
        wire sda;

       
        i2c uut (
                .clk(clk),
                .rst_n(rst_n),
                .enable(enable),
                .scl(scl),
                .sda(sda),
                .dout(dout),
                .state(state),
                .i_state(i_state),
                .i_next_state(i_next_state),
                .cmd(cmd),
                .r_w(r_w),
                .next(next),
                .bit_num(bit_num)
        );

        initial begin
                // Initialize Inputs
                clk = 0;
                rst_n = 0;
                enable = 0;

                #100 rst_n = 1;
        end
       
        always #10 clk = !clk;
        always #10 enable = !enable;   
   
endmodule
此帖出自FPGA/CPLD论坛
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表