在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 7545|回复: 17

[求助] (Opencore)I2C主控模块的原代码问题

[复制链接]
发表于 2014-8-24 21:23:51 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

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

x
本帖最后由 chandler_an1988 于 2014-8-24 21:28 编辑

i2c.zip (359.21 KB, 下载次数: 159 ) 最近学习IIC总线协议,一时心血来潮就从Opencore上下了个IIC设计文档。
  本想照着写一下的,结果在阅读代码的时候有很多困惑,请诸位前辈大神指点,感激不尽!
  代码比较复杂,我把整个设计文档上传到附件中了(其中有Spec,RTL,验证代码,有兴趣的同学可以收下~)

正文 :
  先贴段代码,这个是IIC bit control模块的状态机,如下:



  1.         always @(posedge clk or negedge nReset)
  2.           if (!nReset)
  3.             begin
  4.                 c_state <= #1 idle;
  5.                 cmd_ack <= #1 1'b0;
  6.                 scl_oen <= #1 1'b1;
  7.                 sda_oen <= #1 1'b1;
  8.                 sda_chk <= #1 1'b0;
  9.             end
  10.           else if (rst | al)
  11.             begin
  12.                 c_state <= #1 idle;
  13.                 cmd_ack <= #1 1'b0;
  14.                 scl_oen <= #1 1'b1;
  15.                 sda_oen <= #1 1'b1;
  16.                 sda_chk <= #1 1'b0;
  17.             end
  18.           else
  19.             begin
  20.                 [color=Red]cmd_ack   <= #1 1'b0; // default no command acknowledge + assert cmd_ack only 1clk cycle[/color]

  21.                 if (clk_en)
  22.                   case (c_state) // synopsys full_case parallel_case
  23.                     // idle state
  24.                     idle:
  25.                     begin
  26.                         case (cmd) // synopsys full_case parallel_case
  27.                           `I2C_CMD_START:
  28.                              c_state <= #1 start_a;

  29.                           `I2C_CMD_STOP:
  30.                              c_state <= #1 stop_a;

  31.                           `I2C_CMD_WRITE:
  32.                              c_state <= #1 wr_a;

  33.                           `I2C_CMD_READ:
  34.                              c_state <= #1 rd_a;

  35.                           default:
  36.                             c_state <= #1 idle;
  37.                         endcase

  38.                         scl_oen <= #1 scl_oen; // keep SCL in same state
  39.                         sda_oen <= #1 sda_oen; // keep SDA in same state
  40.                         sda_chk <= #1 1'b0;    // don't check SDA output
  41.                     end


复制代码
这里每个始终周期都把cmd_ack信号置为0(注意,这里的cmd_ack是寄存器输出),但是后边又在组合逻辑中给cmd_ack信号赋值。



  1.                     start_e:
  2.                     begin
  3.                         c_state <= #1 idle;
  4.                         [color=Red]cmd_ack <= #1 1'b1[/color];
  5.                         scl_oen <= #1 1'b0; // set SCL low
  6.                         sda_oen <= #1 1'b0; // keep SDA low
  7.                         sda_chk <= #1 1'b0; // don't check SDA output
  8.                     end


复制代码
------------------------------分割线------------------------------------------------------



  1.                     stop_d:
  2.                     begin
  3.                         c_state <= #1 idle;
  4.                         [color=Red]cmd_ack <= #1 1'b1[/color];
  5.                         scl_oen <= #1 1'b1; // keep SCL high
  6.                         sda_oen <= #1 1'b1; // set SDA high
  7.                         sda_chk <= #1 1'b0; // don't check SDA output
  8.                     end


复制代码
疑惑:
         这段RTL代码中cmd_ack信号既被状态机的组合逻辑驱动,又被寄存器驱动。实在想象不出这个电路的结构,
         Opencore上说这段代码可以用FPGA综合,同样能不能用在ASIC中呢?
         如果那位大神看懂这个信号的控制,请指点一二,十分感谢!!
        ( ps:代码太长了,所以我上传了整个设计文档,可能要全看了以后才能回答我这个问题。)
 楼主| 发表于 2014-8-24 21:26:16 | 显示全部楼层
回复 1# chandler_an1988
不要沉,自己先顶一个
 楼主| 发表于 2014-8-24 21:39:31 | 显示全部楼层
大家有什么疑问,或者想法,也请发表下意见啊;
很希望能和大家讨论
发表于 2014-8-25 15:15:59 | 显示全部楼层
顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶
发表于 2014-8-25 16:33:51 | 显示全部楼层
人家写的没错啊 没有组合逻辑 赋值都在always @(posedge clk or negedge nReset)模块里啊
发表于 2014-8-25 16:39:23 | 显示全部楼层
边沿触发,生成D触发器了呗,状态机不是组合逻辑好不。clk_en是个门控使能,它的频率应该就是IIC的CLK
 楼主| 发表于 2014-8-26 20:32:28 | 显示全部楼层
回复 6# layueliuhuo


    我没太看懂这个状态机,以前自己写的都是两段或者三段的状态机,把组合逻辑部分和状态存储的寄存器分开写。
    我是不太清楚,这样写成一段的状态机,电路是怎样的结构。
    让我比较困惑的是这个信号的描述
    always @(posedge clk or negedge nReset)
    <省略...>
    else
     begin
         cmd_ack   <= #1 1'b0;
     if (clk_en)
     <省略...>
                  start_e:
             begin
                 c_state <= #1 idle;
                 cmd_ack <= #1 1'b1;
                 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  
    比如说我想要一个功能相同的状态机,但是分成两段或者三段,那么该怎么描述呢?
    如果要是分成三段的写法,关键是怎么样能让cmd_ack信号在每个clk上升沿时归零呢?
    能否帮我讲下,感谢!
发表于 2014-10-22 14:43:21 | 显示全部楼层
ref only !!!
发表于 2014-11-13 20:38:48 | 显示全部楼层
xie xie
发表于 2014-11-13 23:16:32 | 显示全部楼层
看清楚哈,cmd_ack只在这一个always里被驱动了,没有什么组合逻辑哈。
还有,这段代码放在FPGA里,简直太烂了,幸好IIC一般就几百k,不会出太大的时序问题,但如果和其它高速模块综合到一块,也许会影响整体的时序。。。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

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


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

GMT+8, 2024-11-26 01:33 , Processed in 0.027444 second(s), 10 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表