URL
https://opencores.org/ocsvn/oms8051mini/oms8051mini/trunk
Subversion Repositories oms8051mini
Compare Revisions
- This comparison shows the changes necessary to convert path
/oms8051mini/trunk/rtl/i2cm
- from Rev 28 to Rev 36
- ↔ Reverse comparison
Rev 28 → Rev 36
/i2cm_bit_ctrl.v
22,7 → 22,8
// v0.0 - Dinesh A, 6th Jan 2017 |
// 1. Initail version picked from |
// http://www.opencores.org/projects/i2c/ |
// |
// v0.1 - Dinesh A, 19th Jan 2017 |
// 1. Lint warning clean up |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000 Authors and OPENCORES.ORG //// |
141,7 → 142,7
// whenever the slave is not ready it can delay the cycle by pulling SCL low |
// delay scl_oen |
always @(posedge clk) |
dscl_oen <= #1 scl_oen; |
dscl_oen <= scl_oen; |
|
// slave_wait is asserted when master wants to drive SCL high, but the slave pulls it low |
// slave_wait remains asserted until the slave releases SCL |
158,23 → 159,23
always @(posedge clk or negedge aresetn) |
if (~aresetn) |
begin |
cnt <= #1 16'h0; |
clk_en <= #1 1'b1; |
cnt <= 16'h0; |
clk_en <= 1'b1; |
end |
else if (!sresetn || ~|cnt || !ena || scl_sync) |
begin |
cnt <= #1 clk_cnt; |
clk_en <= #1 1'b1; |
cnt <= clk_cnt; |
clk_en <= 1'b1; |
end |
else if (slave_wait) |
begin |
cnt <= #1 cnt; |
clk_en <= #1 1'b0; |
cnt <= cnt; |
clk_en <= 1'b0; |
end |
else |
begin |
cnt <= #1 cnt - 16'h1; |
clk_en <= #1 1'b0; |
cnt <= cnt - 16'h1; |
clk_en <= 1'b0; |
end |
|
|
185,13 → 186,13
always @(posedge clk or negedge aresetn) |
if (!aresetn) |
begin |
cSCL <= #1 2'b00; |
cSDA <= #1 2'b00; |
cSCL <= 2'b00; |
cSDA <= 2'b00; |
end |
else if (!sresetn) |
begin |
cSCL <= #1 2'b00; |
cSDA <= #1 2'b00; |
cSCL <= 2'b00; |
cSDA <= 2'b00; |
end |
else |
begin |
230,27 → 231,27
always @(posedge clk or negedge aresetn) |
if (~aresetn) |
begin |
sSCL <= #1 1'b1; |
sSDA <= #1 1'b1; |
sSCL <= 1'b1; |
sSDA <= 1'b1; |
|
dSCL <= #1 1'b1; |
dSDA <= #1 1'b1; |
dSCL <= 1'b1; |
dSDA <= 1'b1; |
end |
else if (!sresetn) |
begin |
sSCL <= #1 1'b1; |
sSDA <= #1 1'b1; |
sSCL <= 1'b1; |
sSDA <= 1'b1; |
|
dSCL <= #1 1'b1; |
dSDA <= #1 1'b1; |
dSCL <= 1'b1; |
dSDA <= 1'b1; |
end |
else |
begin |
sSCL <= #1 &fSCL[2:1] | &fSCL[1:0] | (fSCL[2] & fSCL[0]); |
sSDA <= #1 &fSDA[2:1] | &fSDA[1:0] | (fSDA[2] & fSDA[0]); |
sSCL <= &fSCL[2:1] | &fSCL[1:0] | (fSCL[2] & fSCL[0]); |
sSDA <= &fSDA[2:1] | &fSDA[1:0] | (fSDA[2] & fSDA[0]); |
|
dSCL <= #1 sSCL; |
dSDA <= #1 sSDA; |
dSCL <= sSCL; |
dSDA <= sSDA; |
end |
|
// detect start condition => detect falling edge on SDA while SCL is high |
260,26 → 261,26
always @(posedge clk or negedge aresetn) |
if (~aresetn) |
begin |
sta_condition <= #1 1'b0; |
sto_condition <= #1 1'b0; |
sta_condition <= 1'b0; |
sto_condition <= 1'b0; |
end |
else if (!sresetn) |
begin |
sta_condition <= #1 1'b0; |
sto_condition <= #1 1'b0; |
sta_condition <= 1'b0; |
sto_condition <= 1'b0; |
end |
else |
begin |
sta_condition <= #1 ~sSDA & dSDA & sSCL; |
sto_condition <= #1 sSDA & ~dSDA & sSCL; |
sta_condition <= ~sSDA & dSDA & sSCL; |
sto_condition <= sSDA & ~dSDA & sSCL; |
end |
|
|
// generate i2c bus busy signal |
always @(posedge clk or negedge aresetn) |
if (!aresetn) busy <= #1 1'b0; |
else if (!sresetn ) busy <= #1 1'b0; |
else busy <= #1 (sta_condition | busy) & ~sto_condition; |
if (!aresetn) busy <= 1'b0; |
else if (!sresetn ) busy <= 1'b0; |
else busy <= (sta_condition | busy) & ~sto_condition; |
|
|
// generate arbitration lost signal |
289,24 → 290,24
reg cmd_stop; |
always @(posedge clk or negedge aresetn) |
if (~aresetn) |
cmd_stop <= #1 1'b0; |
cmd_stop <= 1'b0; |
else if (!sresetn) |
cmd_stop <= #1 1'b0; |
cmd_stop <= 1'b0; |
else if (clk_en) |
cmd_stop <= #1 cmd == `I2C_CMD_STOP; |
cmd_stop <= cmd == `I2C_CMD_STOP; |
|
always @(posedge clk or negedge aresetn) |
if (~aresetn) |
al <= #1 1'b0; |
al <= 1'b0; |
else if (!sresetn) |
al <= #1 1'b0; |
al <= 1'b0; |
else |
al <= #1 (sda_chk & ~sSDA & sda_oen) | (|c_state & sto_condition & ~cmd_stop); |
al <= (sda_chk & ~sSDA & sda_oen) | (|c_state & sto_condition & ~cmd_stop); |
|
|
// generate dout signal (store SDA on rising edge of SCL) |
always @(posedge clk) |
if (sSCL & ~dSCL) dout <= #1 sSDA; |
if (sSCL & ~dSCL) dout <= sSDA; |
|
|
// generate statemachine |
334,23 → 335,23
always @(posedge clk or negedge aresetn) |
if (!aresetn) |
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; |
c_state <= idle; |
cmd_ack <= 1'b0; |
scl_oen <= 1'b1; |
sda_oen <= 1'b1; |
sda_chk <= 1'b0; |
end |
else if (!sresetn | 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; |
c_state <= idle; |
cmd_ack <= 1'b0; |
scl_oen <= 1'b1; |
sda_oen <= 1'b1; |
sda_chk <= 1'b0; |
end |
else |
begin |
cmd_ack <= #1 1'b0; // default no command acknowledge + assert cmd_ack only 1clk cycle |
cmd_ack <= 1'b0; // default no command acknowledge + assert cmd_ack only 1clk cycle |
|
if (clk_en) |
case (c_state) // synopsys full_case parallel_case |
358,161 → 359,161
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; |
`I2C_CMD_START: c_state <= start_a; |
`I2C_CMD_STOP: c_state <= stop_a; |
`I2C_CMD_WRITE: c_state <= wr_a; |
`I2C_CMD_READ: c_state <= rd_a; |
default: c_state <= 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 |
scl_oen <= scl_oen; // keep SCL in same state |
sda_oen <= sda_oen; // keep SDA in same state |
sda_chk <= 1'b0; // don't check SDA output |
end |
|
// start |
start_a: |
begin |
c_state <= #1 start_b; |
scl_oen <= #1 scl_oen; // keep SCL in same state |
sda_oen <= #1 1'b1; // set SDA high |
sda_chk <= #1 1'b0; // don't check SDA output |
c_state <= start_b; |
scl_oen <= scl_oen; // keep SCL in same state |
sda_oen <= 1'b1; // set SDA high |
sda_chk <= 1'b0; // don't check SDA output |
end |
|
start_b: |
begin |
c_state <= #1 start_c; |
scl_oen <= #1 1'b1; // set SCL high |
sda_oen <= #1 1'b1; // keep SDA high |
sda_chk <= #1 1'b0; // don't check SDA output |
c_state <= start_c; |
scl_oen <= 1'b1; // set SCL high |
sda_oen <= 1'b1; // keep SDA high |
sda_chk <= 1'b0; // don't check SDA output |
end |
|
start_c: |
begin |
c_state <= #1 start_d; |
scl_oen <= #1 1'b1; // keep SCL high |
sda_oen <= #1 1'b0; // set SDA low |
sda_chk <= #1 1'b0; // don't check SDA output |
c_state <= start_d; |
scl_oen <= 1'b1; // keep SCL high |
sda_oen <= 1'b0; // set SDA low |
sda_chk <= 1'b0; // don't check SDA output |
end |
|
start_d: |
begin |
c_state <= #1 start_e; |
scl_oen <= #1 1'b1; // keep SCL high |
sda_oen <= #1 1'b0; // keep SDA low |
sda_chk <= #1 1'b0; // don't check SDA output |
c_state <= start_e; |
scl_oen <= 1'b1; // keep SCL high |
sda_oen <= 1'b0; // keep SDA low |
sda_chk <= 1'b0; // don't check SDA output |
end |
|
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 |
c_state <= idle; |
cmd_ack <= 1'b1; |
scl_oen <= 1'b0; // set SCL low |
sda_oen <= 1'b0; // keep SDA low |
sda_chk <= 1'b0; // don't check SDA output |
end |
|
// stop |
stop_a: |
begin |
c_state <= #1 stop_b; |
scl_oen <= #1 1'b0; // keep SCL low |
sda_oen <= #1 1'b0; // set SDA low |
sda_chk <= #1 1'b0; // don't check SDA output |
c_state <= stop_b; |
scl_oen <= 1'b0; // keep SCL low |
sda_oen <= 1'b0; // set SDA low |
sda_chk <= 1'b0; // don't check SDA output |
end |
|
stop_b: |
begin |
c_state <= #1 stop_c; |
scl_oen <= #1 1'b1; // set SCL high |
sda_oen <= #1 1'b0; // keep SDA low |
sda_chk <= #1 1'b0; // don't check SDA output |
c_state <= stop_c; |
scl_oen <= 1'b1; // set SCL high |
sda_oen <= 1'b0; // keep SDA low |
sda_chk <= 1'b0; // don't check SDA output |
end |
|
stop_c: |
begin |
c_state <= #1 stop_d; |
scl_oen <= #1 1'b1; // keep SCL high |
sda_oen <= #1 1'b0; // keep SDA low |
sda_chk <= #1 1'b0; // don't check SDA output |
c_state <= stop_d; |
scl_oen <= 1'b1; // keep SCL high |
sda_oen <= 1'b0; // keep SDA low |
sda_chk <= 1'b0; // don't check SDA output |
end |
|
stop_d: |
begin |
c_state <= #1 idle; |
cmd_ack <= #1 1'b1; |
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 |
c_state <= idle; |
cmd_ack <= 1'b1; |
scl_oen <= 1'b1; // keep SCL high |
sda_oen <= 1'b1; // set SDA high |
sda_chk <= 1'b0; // don't check SDA output |
end |
|
// read |
rd_a: |
begin |
c_state <= #1 rd_b; |
scl_oen <= #1 1'b0; // keep SCL low |
sda_oen <= #1 1'b1; // tri-state SDA |
sda_chk <= #1 1'b0; // don't check SDA output |
c_state <= rd_b; |
scl_oen <= 1'b0; // keep SCL low |
sda_oen <= 1'b1; // tri-state SDA |
sda_chk <= 1'b0; // don't check SDA output |
end |
|
rd_b: |
begin |
c_state <= #1 rd_c; |
scl_oen <= #1 1'b1; // set SCL high |
sda_oen <= #1 1'b1; // keep SDA tri-stated |
sda_chk <= #1 1'b0; // don't check SDA output |
c_state <= rd_c; |
scl_oen <= 1'b1; // set SCL high |
sda_oen <= 1'b1; // keep SDA tri-stated |
sda_chk <= 1'b0; // don't check SDA output |
end |
|
rd_c: |
begin |
c_state <= #1 rd_d; |
scl_oen <= #1 1'b1; // keep SCL high |
sda_oen <= #1 1'b1; // keep SDA tri-stated |
sda_chk <= #1 1'b0; // don't check SDA output |
c_state <= rd_d; |
scl_oen <= 1'b1; // keep SCL high |
sda_oen <= 1'b1; // keep SDA tri-stated |
sda_chk <= 1'b0; // don't check SDA output |
end |
|
rd_d: |
begin |
c_state <= #1 idle; |
cmd_ack <= #1 1'b1; |
scl_oen <= #1 1'b0; // set SCL low |
sda_oen <= #1 1'b1; // keep SDA tri-stated |
sda_chk <= #1 1'b0; // don't check SDA output |
c_state <= idle; |
cmd_ack <= 1'b1; |
scl_oen <= 1'b0; // set SCL low |
sda_oen <= 1'b1; // keep SDA tri-stated |
sda_chk <= 1'b0; // don't check SDA output |
end |
|
// write |
wr_a: |
begin |
c_state <= #1 wr_b; |
scl_oen <= #1 1'b0; // keep SCL low |
sda_oen <= #1 din; // set SDA |
sda_chk <= #1 1'b0; // don't check SDA output (SCL low) |
c_state <= wr_b; |
scl_oen <= 1'b0; // keep SCL low |
sda_oen <= din; // set SDA |
sda_chk <= 1'b0; // don't check SDA output (SCL low) |
end |
|
wr_b: |
begin |
c_state <= #1 wr_c; |
scl_oen <= #1 1'b1; // set SCL high |
sda_oen <= #1 din; // keep SDA |
sda_chk <= #1 1'b0; // don't check SDA output yet |
c_state <= wr_c; |
scl_oen <= 1'b1; // set SCL high |
sda_oen <= din; // keep SDA |
sda_chk <= 1'b0; // don't check SDA output yet |
// allow some time for SDA and SCL to settle |
end |
|
wr_c: |
begin |
c_state <= #1 wr_d; |
scl_oen <= #1 1'b1; // keep SCL high |
sda_oen <= #1 din; |
sda_chk <= #1 1'b1; // check SDA output |
c_state <= wr_d; |
scl_oen <= 1'b1; // keep SCL high |
sda_oen <= din; |
sda_chk <= 1'b1; // check SDA output |
end |
|
wr_d: |
begin |
c_state <= #1 idle; |
cmd_ack <= #1 1'b1; |
scl_oen <= #1 1'b0; // set SCL low |
sda_oen <= #1 din; |
sda_chk <= #1 1'b0; // don't check SDA output (SCL low) |
c_state <= idle; |
cmd_ack <= 1'b1; |
scl_oen <= 1'b0; // set SCL low |
sda_oen <= din; |
sda_chk <= 1'b0; // don't check SDA output (SCL low) |
end |
|
endcase |
/i2cm_byte_ctrl.v
19,11 → 19,12
//// Revision : Jan 6, 2017 //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// v0.0 - Dinesh A, 6th Jan 2017 |
// 1. Initail version picked from |
// http://www.opencores.org/projects/i2c/ |
// 2. renaming of reset signal to aresetn and sresetn |
// |
//// v0.0 - Dinesh A, 6th Jan 2017 |
//// 1. Initail version picked from |
//// http://www.opencores.org/projects/i2c/ |
//// 2. renaming of reset signal to aresetn and sresetn |
//// v0.1 - Dinesh.A, 19th Jan 2017 |
//// 1. Lint Error fixes |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000 Authors and OPENCORES.ORG //// |
151,24 → 152,24
// generate shift register |
always @(posedge clk or negedge aresetn) |
if (!aresetn) |
sr <= #1 8'h0; |
sr <= 8'h0; |
else if (!sresetn) |
sr <= #1 8'h0; |
sr <= 8'h0; |
else if (ld) |
sr <= #1 din; |
sr <= din; |
else if (shift) |
sr <= #1 {sr[6:0], core_rxd}; |
sr <= {sr[6:0], core_rxd}; |
|
// generate counter |
always @(posedge clk or negedge aresetn) |
if (!aresetn) |
dcnt <= #1 3'h0; |
dcnt <= 3'h0; |
else if (!sresetn) |
dcnt <= #1 3'h0; |
dcnt <= 3'h0; |
else if (ld) |
dcnt <= #1 3'h7; |
dcnt <= 3'h7; |
else if (shift) |
dcnt <= #1 dcnt - 3'h1; |
dcnt <= dcnt - 3'h1; |
|
assign cnt_done = ~(|dcnt); |
|
180,31 → 181,31
always @(posedge clk or negedge aresetn) |
if (!aresetn) |
begin |
core_cmd <= #1 `I2C_CMD_NOP; |
core_txd <= #1 1'b0; |
shift <= #1 1'b0; |
ld <= #1 1'b0; |
cmd_ack <= #1 1'b0; |
c_state <= #1 ST_IDLE; |
ack_out <= #1 1'b0; |
core_cmd <= `I2C_CMD_NOP; |
core_txd <= 1'b0; |
shift <= 1'b0; |
ld <= 1'b0; |
cmd_ack <= 1'b0; |
c_state <= ST_IDLE; |
ack_out <= 1'b0; |
end |
else if (!sresetn | i2c_al) |
begin |
core_cmd <= #1 `I2C_CMD_NOP; |
core_txd <= #1 1'b0; |
shift <= #1 1'b0; |
ld <= #1 1'b0; |
cmd_ack <= #1 1'b0; |
c_state <= #1 ST_IDLE; |
ack_out <= #1 1'b0; |
core_cmd <= `I2C_CMD_NOP; |
core_txd <= 1'b0; |
shift <= 1'b0; |
ld <= 1'b0; |
cmd_ack <= 1'b0; |
c_state <= ST_IDLE; |
ack_out <= 1'b0; |
end |
else |
begin |
// initially reset all signals |
core_txd <= #1 sr[7]; |
shift <= #1 1'b0; |
ld <= #1 1'b0; |
cmd_ack <= #1 1'b0; |
core_txd <= sr[7]; |
shift <= 1'b0; |
ld <= 1'b0; |
cmd_ack <= 1'b0; |
|
case (c_state) // synopsys full_case parallel_case |
ST_IDLE: |
212,26 → 213,26
begin |
if (start) |
begin |
c_state <= #1 ST_START; |
core_cmd <= #1 `I2C_CMD_START; |
c_state <= ST_START; |
core_cmd <= `I2C_CMD_START; |
end |
else if (read) |
begin |
c_state <= #1 ST_READ; |
core_cmd <= #1 `I2C_CMD_READ; |
c_state <= ST_READ; |
core_cmd <= `I2C_CMD_READ; |
end |
else if (write) |
begin |
c_state <= #1 ST_WRITE; |
core_cmd <= #1 `I2C_CMD_WRITE; |
c_state <= ST_WRITE; |
core_cmd <= `I2C_CMD_WRITE; |
end |
else // stop |
begin |
c_state <= #1 ST_STOP; |
core_cmd <= #1 `I2C_CMD_STOP; |
c_state <= ST_STOP; |
core_cmd <= `I2C_CMD_STOP; |
end |
|
ld <= #1 1'b1; |
ld <= 1'b1; |
end |
|
ST_START: |
239,16 → 240,16
begin |
if (read) |
begin |
c_state <= #1 ST_READ; |
core_cmd <= #1 `I2C_CMD_READ; |
c_state <= ST_READ; |
core_cmd <= `I2C_CMD_READ; |
end |
else |
begin |
c_state <= #1 ST_WRITE; |
core_cmd <= #1 `I2C_CMD_WRITE; |
c_state <= ST_WRITE; |
core_cmd <= `I2C_CMD_WRITE; |
end |
|
ld <= #1 1'b1; |
ld <= 1'b1; |
end |
|
ST_WRITE: |
255,14 → 256,14
if (core_ack) |
if (cnt_done) |
begin |
c_state <= #1 ST_ACK; |
core_cmd <= #1 `I2C_CMD_READ; |
c_state <= ST_ACK; |
core_cmd <= `I2C_CMD_READ; |
end |
else |
begin |
c_state <= #1 ST_WRITE; // stay in same state |
core_cmd <= #1 `I2C_CMD_WRITE; // write next bit |
shift <= #1 1'b1; |
c_state <= ST_WRITE; // stay in same state |
core_cmd <= `I2C_CMD_WRITE; // write next bit |
shift <= 1'b1; |
end |
|
ST_READ: |
270,17 → 271,17
begin |
if (cnt_done) |
begin |
c_state <= #1 ST_ACK; |
core_cmd <= #1 `I2C_CMD_WRITE; |
c_state <= ST_ACK; |
core_cmd <= `I2C_CMD_WRITE; |
end |
else |
begin |
c_state <= #1 ST_READ; // stay in same state |
core_cmd <= #1 `I2C_CMD_READ; // read next bit |
c_state <= ST_READ; // stay in same state |
core_cmd <= `I2C_CMD_READ; // read next bit |
end |
|
shift <= #1 1'b1; |
core_txd <= #1 ack_in; |
shift <= 1'b1; |
core_txd <= ack_in; |
end |
|
ST_ACK: |
288,35 → 289,36
begin |
if (stop) |
begin |
c_state <= #1 ST_STOP; |
core_cmd <= #1 `I2C_CMD_STOP; |
c_state <= ST_STOP; |
core_cmd <= `I2C_CMD_STOP; |
end |
else |
begin |
c_state <= #1 ST_IDLE; |
core_cmd <= #1 `I2C_CMD_NOP; |
c_state <= ST_IDLE; |
core_cmd <= `I2C_CMD_NOP; |
|
// generate command acknowledge signal |
cmd_ack <= #1 1'b1; |
cmd_ack <= 1'b1; |
end |
|
// assign ack_out output to bit_controller_rxd (contains last received bit) |
ack_out <= #1 core_rxd; |
ack_out <= core_rxd; |
|
core_txd <= #1 1'b1; |
core_txd <= 1'b1; |
end |
else |
core_txd <= #1 ack_in; |
core_txd <= ack_in; |
|
ST_STOP: |
if (core_ack) |
begin |
c_state <= #1 ST_IDLE; |
core_cmd <= #1 `I2C_CMD_NOP; |
c_state <= ST_IDLE; |
core_cmd <= `I2C_CMD_NOP; |
|
// generate command acknowledge signal |
cmd_ack <= #1 1'b1; |
cmd_ack <= 1'b1; |
end |
default: c_state <= ST_IDLE; |
|
endcase |
end |