|  | 
 
| 
本帖最后由 chandler_an1988 于 2014-8-24 21:28 编辑
×
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?注册  
 
  i2c.zip
            
            (359.21 KB , 下载次数:
                160 )
            
            
            
            
            
最近学习IIC总线协议,一时心血来潮就从Opencore上下了个IIC设计文档。 本想照着写一下的,结果在阅读代码的时候有很多困惑,请诸位前辈大神指点,感激不尽!
 代码比较复杂,我把整个设计文档上传到附件中了(其中有Spec,RTL,验证代码,有兴趣的同学可以收下~)
 
 正文 :
 先贴段代码,这个是IIC bit control模块的状态机,如下:
 
 
    这里每个始终周期都把cmd_ack信号置为0(注意,这里的cmd_ack是寄存器输出),但是后边又在组合逻辑中给cmd_ack信号赋值。
        复制代码
         always @(posedge clk or negedge nReset)
          if (!nReset)
            begin
                c_state <= #1 idle;
                cmd_ack <= #1 1'b0;
                scl_oen <= #1 1'b1;
                sda_oen <= #1 1'b1;
                sda_chk <= #1 1'b0;
            end
          else if (rst | al)
            begin
                c_state <= #1 idle;
                cmd_ack <= #1 1'b0;
                scl_oen <= #1 1'b1;
                sda_oen <= #1 1'b1;
                sda_chk <= #1 1'b0;
            end
          else
            begin
                [color=Red]cmd_ack   <= #1 1'b0; // default no command acknowledge + assert cmd_ack only 1clk cycle[/color]
                if (clk_en)
                  case (c_state) // synopsys full_case parallel_case
                    // idle state
                    idle:
                    begin
                        case (cmd) // synopsys full_case parallel_case
                          `I2C_CMD_START:
                             c_state <= #1 start_a;
                          `I2C_CMD_STOP:
                             c_state <= #1 stop_a;
                          `I2C_CMD_WRITE:
                             c_state <= #1 wr_a;
                          `I2C_CMD_READ:
                             c_state <= #1 rd_a;
                          default:
                            c_state <= #1 idle;
                        endcase
                        scl_oen <= #1 scl_oen; // keep SCL in same state
                        sda_oen <= #1 sda_oen; // keep SDA in same state
                        sda_chk <= #1 1'b0;    // don't check SDA output
                    end
 
 
    ------------------------------分割线------------------------------------------------------
        复制代码
                     start_e:
                    begin
                        c_state <= #1 idle;
                        [color=Red]cmd_ack <= #1 1'b1[/color];
                        scl_oen <= #1 1'b0; // set SCL low
                        sda_oen <= #1 1'b0; // keep SDA low
                        sda_chk <= #1 1'b0; // don't check SDA output
                    end
 
 
    疑惑:
        复制代码
                     stop_d:
                    begin
                        c_state <= #1 idle;
                        [color=Red]cmd_ack <= #1 1'b1[/color];
                        scl_oen <= #1 1'b1; // keep SCL high
                        sda_oen <= #1 1'b1; // set SDA high
                        sda_chk <= #1 1'b0; // don't check SDA output
                    end
 这段RTL代码中cmd_ack信号既被状态机的组合逻辑驱动,又被寄存器驱动。实在想象不出这个电路的结构,
 Opencore上说这段代码可以用FPGA综合,同样能不能用在ASIC中呢?
 如果那位大神看懂这个信号的控制,请指点一二,十分感谢!!
 ( ps:代码太长了,所以我上传了整个设计文档,可能要全看了以后才能回答我这个问题。)
 | 
 |