|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?注册
x
本帖最后由 chandler_an1988 于 2014-8-24 21:28 编辑
i2c.zip
(359.21 KB, 下载次数: 159 )
最近学习IIC总线协议,一时心血来潮就从Opencore上下了个IIC设计文档。
本想照着写一下的,结果在阅读代码的时候有很多困惑,请诸位前辈大神指点,感激不尽!
代码比较复杂,我把整个设计文档上传到附件中了(其中有Spec,RTL,验证代码,有兴趣的同学可以收下~)
正文 :
先贴段代码,这个是IIC bit control模块的状态机,如下:
- 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
复制代码 这里每个始终周期都把cmd_ack信号置为0(注意,这里的cmd_ack是寄存器输出),但是后边又在组合逻辑中给cmd_ack信号赋值。
- 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:代码太长了,所以我上传了整个设计文档,可能要全看了以后才能回答我这个问题。) |
|