summaryrefslogtreecommitdiff
path: root/tests/i2c_bench/i2c_slave_model.v
diff options
context:
space:
mode:
Diffstat (limited to 'tests/i2c_bench/i2c_slave_model.v')
-rw-r--r--tests/i2c_bench/i2c_slave_model.v361
1 files changed, 0 insertions, 361 deletions
diff --git a/tests/i2c_bench/i2c_slave_model.v b/tests/i2c_bench/i2c_slave_model.v
deleted file mode 100644
index 02b7572c..00000000
--- a/tests/i2c_bench/i2c_slave_model.v
+++ /dev/null
@@ -1,361 +0,0 @@
-/////////////////////////////////////////////////////////////////////
-//// ////
-//// WISHBONE rev.B2 compliant synthesizable I2C Slave model ////
-//// ////
-//// ////
-//// Authors: Richard Herveille (richard@asics.ws) www.asics.ws ////
-//// John Sheahan (jrsheahan@optushome.com.au) ////
-//// ////
-//// Downloaded from: http://www.opencores.org/projects/i2c/ ////
-//// ////
-/////////////////////////////////////////////////////////////////////
-//// ////
-//// Copyright (C) 2001,2002 Richard Herveille ////
-//// richard@asics.ws ////
-//// ////
-//// This source file may be used and distributed without ////
-//// restriction provided that this copyright statement is not ////
-//// removed from the file and that any derivative work contains ////
-//// the original copyright notice and the associated disclaimer.////
-//// ////
-//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
-//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
-//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
-//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
-//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
-//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
-//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
-//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
-//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
-//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
-//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
-//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
-//// POSSIBILITY OF SUCH DAMAGE. ////
-//// ////
-/////////////////////////////////////////////////////////////////////
-
-// CVS Log
-//
-// $Id: i2c_slave_model.v,v 1.7 2006-09-04 09:08:51 rherveille Exp $
-//
-// $Date: 2006-09-04 09:08:51 $
-// $Revision: 1.7 $
-// $Author: rherveille $
-// $Locker: $
-// $State: Exp $
-//
-// Change History:
-// $Log: not supported by cvs2svn $
-// Revision 1.6 2005/02/28 11:33:48 rherveille
-// Fixed Tsu:sta timing check.
-// Added Thd:sta timing check.
-//
-// Revision 1.5 2003/12/05 11:05:19 rherveille
-// Fixed slave address MSB='1' bug
-//
-// Revision 1.4 2003/09/11 08:25:37 rherveille
-// Fixed a bug in the timing section. Changed 'tst_scl' into 'tst_sto'.
-//
-// Revision 1.3 2002/10/30 18:11:06 rherveille
-// Added timing tests to i2c_model.
-// Updated testbench.
-//
-// Revision 1.2 2002/03/17 10:26:38 rherveille
-// Fixed some race conditions in the i2c-slave model.
-// Added debug information.
-// Added headers.
-//
-
-`include "timescale.v"
-
-module i2c_slave_model (scl, sda);
-
- //
- // parameters
- //
- parameter I2C_ADR = 7'b001_0000;
-
- //
- // input && outpus
- //
- input scl;
- inout sda;
-
- //
- // Variable declaration
- //
- wire debug = 1'b1;
-
- reg [7:0] mem [3:0]; // initiate memory
- reg [7:0] mem_adr; // memory address
- reg [7:0] mem_do; // memory data output
-
- reg sta, d_sta;
- reg sto, d_sto;
-
- reg [7:0] sr; // 8bit shift register
- reg rw; // read/write direction
-
- wire my_adr; // my address called ??
- wire i2c_reset; // i2c-statemachine reset
- reg [2:0] bit_cnt; // 3bit downcounter
- wire acc_done; // 8bits transfered
- reg ld; // load downcounter
-
- reg sda_o; // sda-drive level
- wire sda_dly; // delayed version of sda
-
- // statemachine declaration
- parameter idle = 3'b000;
- parameter slave_ack = 3'b001;
- parameter get_mem_adr = 3'b010;
- parameter gma_ack = 3'b011;
- parameter data = 3'b100;
- parameter data_ack = 3'b101;
-
- reg [2:0] state; // synopsys enum_state
-
- //
- // module body
- //
-
- initial
- begin
- sda_o = 1'b1;
- state = idle;
- mem[0] = 0;
- mem[1] = 0;
- mem[2] = 0;
- mem[3] = 0;
- end
-
- // generate shift register
- always @(posedge scl)
- sr <= #1 {sr[6:0],sda};
-
- //detect my_address
- assign my_adr = (sr[7:1] == I2C_ADR);
- // FIXME: This should not be a generic assign, but rather
- // qualified on address transfer phase and probably reset by stop
-
- //generate bit-counter
- always @(posedge scl)
- if(ld)
- bit_cnt <= #1 3'b111;
- else
- bit_cnt <= #1 bit_cnt - 3'h1;
-
- //generate access done signal
- assign acc_done = !(|bit_cnt);
-
- // generate delayed version of sda
- // this model assumes a hold time for sda after the falling edge of scl.
- // According to the Phillips i2c spec, there s/b a 0 ns hold time for sda
- // with regards to scl. If the data changes coincident with the clock, the
- // acknowledge is missed
- // Fix by Michael Sosnoski
- assign #1 sda_dly = sda;
-
-
- //detect start condition
- always @(negedge sda)
- if(scl)
- begin
- sta <= #1 1'b1;
- d_sta <= #1 1'b0;
- sto <= #1 1'b0;
-
- if(debug)
- $display("DEBUG i2c_slave; start condition detected at %t", $time);
- end
- else
- sta <= #1 1'b0;
-
- always @(posedge scl)
- d_sta <= #1 sta;
-
- // detect stop condition
- always @(posedge sda)
- if(scl)
- begin
- sta <= #1 1'b0;
- sto <= #1 1'b1;
-
- if(debug)
- $display("DEBUG i2c_slave; stop condition detected at %t", $time);
- end
- else
- sto <= #1 1'b0;
-
- //generate i2c_reset signal
- assign i2c_reset = sta || sto;
-
- // generate statemachine
- always @(negedge scl or posedge sto)
- if (sto || (sta && !d_sta) )
- begin
- state <= #1 idle; // reset statemachine
-
- sda_o <= #1 1'b1;
- ld <= #1 1'b1;
- end
- else
- begin
- // initial settings
- sda_o <= #1 1'b1;
- ld <= #1 1'b0;
-
- case(state) // synopsys full_case parallel_case
- idle: // idle state
- if (acc_done && my_adr)
- begin
- state <= #1 slave_ack;
- rw <= #1 sr[0];
- sda_o <= #1 1'b0; // generate i2c_ack
-
- #2;
- if(debug && rw)
- $display("DEBUG i2c_slave; command byte received (read) at %t", $time);
- if(debug && !rw)
- $display("DEBUG i2c_slave; command byte received (write) at %t", $time);
-
- if(rw)
- begin
- mem_do <= #1 mem[mem_adr % 4];
-
- if(debug)
- begin
- #2 $display("DEBUG i2c_slave; data block read %x from address %x (1)", mem_do, mem_adr);
- #2 $display("DEBUG i2c_slave; memcheck [0]=%x, [1]=%x, [2]=%x", mem[4'h0], mem[4'h1], mem[4'h2]);
- end
- end
- end
-
- slave_ack:
- begin
- if(rw)
- begin
- state <= #1 data;
- sda_o <= #1 mem_do[7];
- end
- else
- state <= #1 get_mem_adr;
-
- ld <= #1 1'b1;
- end
-
- get_mem_adr: // wait for memory address
- if(acc_done)
- begin
- state <= #1 gma_ack;
- mem_adr <= #1 sr; // store memory address
- sda_o <= #1 !(sr <= 15); // generate i2c_ack, for valid address
-
- if(debug)
- #1 $display("DEBUG i2c_slave; address received. adr=%x, ack=%b", sr, sda_o);
- end
-
- gma_ack:
- begin
- state <= #1 data;
- ld <= #1 1'b1;
- end
-
- data: // receive or drive data
- begin
- if(rw)
- sda_o <= #1 mem_do[7];
-
- if(acc_done)
- begin
- state <= #1 data_ack;
- mem_adr <= #2 mem_adr + 8'h1;
- sda_o <= #1 (rw && (mem_adr <= 15) ); // send ack on write, receive ack on read
-
- if(rw)
- begin
- #3 mem_do <= mem[mem_adr % 4];
-
- if(debug)
- #5 $display("DEBUG i2c_slave; data block read %x from address %x (2)", mem_do, mem_adr);
- end
-
- if(!rw)
- begin
- mem[ mem_adr[3:0] ] <= #1 sr; // store data in memory
-
- if(debug)
- #2 $display("DEBUG i2c_slave; data block write %x to address %x", sr, mem_adr);
- end
- end
- end
-
- data_ack:
- begin
- ld <= #1 1'b1;
-
- if(rw)
- if(sr[0]) // read operation && master send NACK
- begin
- state <= #1 idle;
- sda_o <= #1 1'b1;
- end
- else
- begin
- state <= #1 data;
- sda_o <= #1 mem_do[7];
- end
- else
- begin
- state <= #1 data;
- sda_o <= #1 1'b1;
- end
- end
-
- endcase
- end
-
- // read data from memory
- always @(posedge scl)
- if(!acc_done && rw)
- mem_do <= #1 {mem_do[6:0], 1'b1}; // insert 1'b1 for host ack generation
-
- // generate tri-states
- assign sda = sda_o ? 1'bz : 1'b0;
-
-
- //
- // Timing checks
- //
-
- wire tst_sto = sto;
- wire tst_sta = sta;
-
- specify
- specparam normal_scl_low = 4700,
- normal_scl_high = 4000,
- normal_tsu_sta = 4700,
- normal_thd_sta = 4000,
- normal_tsu_sto = 4000,
- normal_tbuf = 4700,
-
- fast_scl_low = 1300,
- fast_scl_high = 600,
- fast_tsu_sta = 1300,
- fast_thd_sta = 600,
- fast_tsu_sto = 600,
- fast_tbuf = 1300;
-
- $width(negedge scl, normal_scl_low); // scl low time
- $width(posedge scl, normal_scl_high); // scl high time
-
- $setup(posedge scl, negedge sda &&& scl, normal_tsu_sta); // setup start
- $setup(negedge sda &&& scl, negedge scl, normal_thd_sta); // hold start
- $setup(posedge scl, posedge sda &&& scl, normal_tsu_sto); // setup stop
-
- $setup(posedge tst_sta, posedge tst_sto, normal_tbuf); // stop to start time
- endspecify
-
-endmodule
-
-