OpenCores
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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.