URL
https://opencores.org/ocsvn/i2cslave/i2cslave/trunk
Subversion Repositories i2cslave
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 1 to Rev 2
- ↔ Reverse comparison
Rev 1 → Rev 2
/trunk/bench/i2cSlaveTB_defines.v
0,0 → 1,17
// ---------------------------- i2cSlaveTB_defines.v ----------------- |
`define SEND_START 1'b1 |
`define SEND_STOP 1'b1 |
`define NULL 1'b0 |
`define ACK 1'b0 |
`define NACK 1'b1 |
|
`define DEV_I2C_ADDR 8'hcc |
|
`define PRER_LO_REG 3'b000 |
`define PRER_HI_REG 3'b001 |
`define CTR_REG 3'b010 |
`define RXR_REG 3'b011 |
`define TXR_REG 3'b011 |
`define CR_REG 3'b100 |
`define SR_REG 3'b100 |
|
/trunk/bench/testCase0.v
0,0 → 1,41
// ---------------------------------- testcase0.v ---------------------------- |
`include "timescale.v" |
`include "i2cSlave_define.v" |
`include "i2cSlaveTB_defines.v" |
|
module testCase0(); |
|
reg ack; |
reg [7:0] data; |
reg [15:0] dataWord; |
reg [7:0] dataRead; |
reg [7:0] dataWrite; |
integer i; |
integer j; |
|
initial |
begin |
$write("\n\n"); |
testHarness.reset; |
#1000; |
|
// set i2c master clock scale reg PRER = (48MHz / (5 * 400KHz) ) - 1 |
$write("Testing register read/write\n"); |
testHarness.u_wb_master_model.wb_write(1, `PRER_LO_REG , 8'h17); |
testHarness.u_wb_master_model.wb_write(1, `PRER_HI_REG , 8'h00); |
testHarness.u_wb_master_model.wb_cmp(1, `PRER_LO_REG , 8'h17); |
|
// enable i2c master |
testHarness.u_wb_master_model.wb_write(1, `CTR_REG , 8'h80); |
|
multiByteReadWrite.write({`I2C_ADDRESS, 1'b0}, 8'h00, 32'h89abcdef, `SEND_STOP); |
multiByteReadWrite.read({`I2C_ADDRESS, 1'b0}, 8'h00, 32'h89abcdef, dataWord, `NULL); |
multiByteReadWrite.read({`I2C_ADDRESS, 1'b0}, 8'h04, 32'h12345678, dataWord, `NULL); |
|
$write("Finished all tests\n"); |
$stop; |
|
end |
|
endmodule |
|
/trunk/bench/testHarness.v
0,0 → 1,119
// -------------------------- testHarness.v ----------------------- |
`include "timescale.v" |
|
module testHarness (); |
|
reg rst; |
reg clk; |
reg i2cHostClk; |
wire sda; |
wire scl; |
wire sdaOutEn; |
wire sdaOut; |
wire sdaIn; |
wire [2:0] adr; |
wire [7:0] masterDout; |
wire [7:0] masterDin; |
wire we; |
wire stb; |
wire cyc; |
wire ack; |
wire scl_pad_i; |
wire scl_pad_o; |
wire scl_padoen_o; |
wire sda_pad_i; |
wire sda_pad_o; |
wire sda_padoen_o; |
|
initial begin |
$dumpfile("wave.vcd"); |
$dumpvars(0, testHarness); |
end |
|
|
i2cSlave u_i2cSlave( |
.clk(clk), |
.rst(rst), |
.sda(sda), |
.scl(scl), |
.myReg0(), |
.myReg1(), |
.myReg2(), |
.myReg3(), |
.myReg4(8'h12), |
.myReg5(8'h34), |
.myReg6(8'h56), |
.myReg7(8'h78) |
); |
|
i2c_master_top #(.ARST_LVL(1'b1)) u_i2c_master_top ( |
.wb_clk_i(clk), |
.wb_rst_i(rst), |
.arst_i(rst), |
.wb_adr_i(adr), |
.wb_dat_i(masterDout), |
.wb_dat_o(masterDin), |
.wb_we_i(we), |
.wb_stb_i(stb), |
.wb_cyc_i(cyc), |
.wb_ack_o(ack), |
.wb_inta_o(), |
.scl_pad_i(scl_pad_i), |
.scl_pad_o(scl_pad_o), |
.scl_padoen_o(scl_padoen_o), |
.sda_pad_i(sda_pad_i), |
.sda_pad_o(sda_pad_o), |
.sda_padoen_o(sda_padoen_o) |
); |
|
wb_master_model #(.dwidth(8), .awidth(3)) u_wb_master_model ( |
.clk(clk), |
.rst(rst), |
.adr(adr), |
.din(masterDin), |
.dout(masterDout), |
.cyc(cyc), |
.stb(stb), |
.we(we), |
.sel(), |
.ack(ack), |
.err(1'b0), |
.rty(1'b0) |
); |
|
assign sda = (sda_padoen_o == 1'b0) ? sda_pad_o : 1'bz; |
assign sda_pad_i = sda; |
pullup(sda); |
|
assign scl = (scl_padoen_o == 1'b0) ? scl_pad_o : 1'bz; |
assign scl_pad_i = scl; |
pullup(scl); |
|
|
// ****************************** Clock section ****************************** |
//approx 48MHz clock |
`define CLK_HALF_PERIOD 10 |
always begin |
#`CLK_HALF_PERIOD clk <= 1'b0; |
#`CLK_HALF_PERIOD clk <= 1'b1; |
end |
|
|
// ****************************** reset ****************************** |
task reset; |
begin |
rst <= 1'b1; |
@(posedge clk); |
@(posedge clk); |
@(posedge clk); |
@(posedge clk); |
@(posedge clk); |
@(posedge clk); |
rst <= 1'b0; |
@(posedge clk); |
@(posedge clk); |
@(posedge clk); |
end |
endtask |
|
endmodule |
/trunk/bench/multiByteReadWrite.v
0,0 → 1,152
// ------------------ multiByteReadWrite.v ---------------------- |
`include "timescale.v" |
`include "i2cSlaveTB_defines.v" |
|
|
module multiByteReadWrite(); |
reg ack; |
reg [31:0] readData; |
reg [7:0] dataByteRead; |
//reg [7:0] dataMSB; |
|
// ------------------ write ---------------------- |
task write; |
input [7:0] i2cAddr; |
input [7:0] regAddr; |
input [31:0] data; |
input stop; |
|
begin |
$write("I2C Write: At [0x%0x] = 0x%0x\n", regAddr, data); |
|
//i2c address |
testHarness.u_wb_master_model.wb_write(1, `TXR_REG, i2cAddr); |
testHarness.u_wb_master_model.wb_write(1, `CR_REG , 8'h90); //STA, WR |
testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead); |
while (dataByteRead[1] == 1'b1) //while trans in progress |
testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead); |
//$write("I2C device address sent, SR = 0x%x\n", dataByteRead ); |
|
//slave reg address |
testHarness.u_wb_master_model.wb_write(1, `TXR_REG, regAddr); |
testHarness.u_wb_master_model.wb_write(1, `CR_REG , 8'h10); //WR |
testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead); |
while (dataByteRead[1] == 1'b1) //while trans in progress |
testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead); |
//$write("Slave reg address sent, SR = 0x%x\n", dataByteRead ); |
|
//data[31:24] |
testHarness.u_wb_master_model.wb_write(1, `TXR_REG, data[31:24]); |
testHarness.u_wb_master_model.wb_write(1, `CR_REG , 8'h10); //WR |
testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead); |
while (dataByteRead[1] == 1'b1) //while trans in progress |
testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead); |
//$write("Data[31:24] sent, SR = 0x%x\n", dataByteRead ); |
|
//data[23:16] |
testHarness.u_wb_master_model.wb_write(1, `TXR_REG, data[23:16]); |
testHarness.u_wb_master_model.wb_write(1, `CR_REG , 8'h10); //WR |
testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead); |
while (dataByteRead[1] == 1'b1) //while trans in progress |
testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead); |
//$write("Data[23:16] sent, SR = 0x%x\n", dataByteRead ); |
|
//data[15:8] |
testHarness.u_wb_master_model.wb_write(1, `TXR_REG, data[15:8]); |
testHarness.u_wb_master_model.wb_write(1, `CR_REG , 8'h10); //WR |
testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead); |
while (dataByteRead[1] == 1'b1) //while trans in progress |
testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead); |
//$write("Data[15:8] sent, SR = 0x%x\n", dataByteRead ); |
|
//data[7:0] |
testHarness.u_wb_master_model.wb_write(1, `TXR_REG, data[7:0]); |
testHarness.u_wb_master_model.wb_write(1, `CR_REG , {1'b0, stop, 6'b010000}); //STO?, WR |
testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead); |
while (dataByteRead[1] == 1'b1) //while trans in progress |
testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead); |
//$write("Data[7:0] sent, SR = 0x%x\n", dataByteRead ); |
|
end |
endtask |
|
// ------------------ read ---------------------- |
task read; |
input [7:0] i2cAddr; |
input [7:0] regAddr; |
input [31:0] expectedData; |
output [31:0] data; |
input stop; |
|
begin |
|
//i2c address |
testHarness.u_wb_master_model.wb_write(1, `TXR_REG, i2cAddr); //write |
testHarness.u_wb_master_model.wb_write(1, `CR_REG , 8'h90); //STA, WR |
testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead); |
while (dataByteRead[1] == 1'b1) //while trans in progress |
testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead); |
//$write("I2C device address sent, SR = 0x%x\n", dataByteRead ); |
#5000; |
|
//slave reg address |
testHarness.u_wb_master_model.wb_write(1, `TXR_REG, regAddr); |
testHarness.u_wb_master_model.wb_write(1, `CR_REG , {1'b0, stop, 6'b010000}); //STO?, WR |
testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead); |
while (dataByteRead[1] == 1'b1) //while trans in progress |
testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead); |
//$write("Slave reg address sent, SR = 0x%x\n", dataByteRead ); |
#5000; |
|
//i2c address |
testHarness.u_wb_master_model.wb_write(1, `TXR_REG, {i2cAddr[7:1], 1'b1}); //read |
testHarness.u_wb_master_model.wb_write(1, `CR_REG , 8'h90); //STA, WR |
testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead); |
while (dataByteRead[1] == 1'b1) //while trans in progress |
testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead); |
//$write("I2C device address sent, SR = 0x%x\n", dataByteRead ); |
|
//data[31:24] |
testHarness.u_wb_master_model.wb_write(1, `CR_REG , 8'h20); //RD, ACK |
testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead); |
while (dataByteRead[1] == 1'b1) //while trans in progress |
testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead); |
//$write("Data[31:24] rxed, SR = 0x%x\n", dataByteRead ); |
testHarness.u_wb_master_model.wb_read(1, `RXR_REG, readData[31:24]); |
|
//data[23:16] |
testHarness.u_wb_master_model.wb_write(1, `CR_REG , 8'h20); //RD, ACK |
testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead); |
while (dataByteRead[1] == 1'b1) //while trans in progress |
testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead); |
//$write("Data[23:16] rxed, SR = 0x%x\n", dataByteRead ); |
testHarness.u_wb_master_model.wb_read(1, `RXR_REG, readData[23:16]); |
|
//data[15:8] |
testHarness.u_wb_master_model.wb_write(1, `CR_REG , 8'h20); //RD, ACK |
testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead); |
while (dataByteRead[1] == 1'b1) //while trans in progress |
testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead); |
//$write("Data[15:8] rxed, SR = 0x%x\n", dataByteRead ); |
testHarness.u_wb_master_model.wb_read(1, `RXR_REG, readData[15:8]); |
|
//data[7:0] |
testHarness.u_wb_master_model.wb_write(1, `CR_REG , {1'b0, 1'b0, 6'b101000}); //STO, RD, NAK |
testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead); |
while (dataByteRead[1] == 1'b1) //while trans in progress |
testHarness.u_wb_master_model.wb_read(1, `SR_REG , dataByteRead); |
//$write("Data[7:0] rxed, SR = 0x%x\n", dataByteRead ); |
testHarness.u_wb_master_model.wb_read(1, `RXR_REG, readData[7:0]); |
|
data = readData; |
if (data != expectedData) begin |
$write("***** I2C Read ERROR: At 0x%0x. Expected 0x%0x, got 0x%0x\n", regAddr, expectedData, data); |
$stop; |
end |
else |
$write("I2C Read: At [0x%0x] = 0x%0x\n", regAddr, data); |
end |
endtask |
|
endmodule |
|
/trunk/model/i2c_master_byte_ctrl.v
0,0 → 1,344
///////////////////////////////////////////////////////////////////// |
//// //// |
//// WISHBONE rev.B2 compliant I2C Master byte-controller //// |
//// //// |
//// //// |
//// Author: Richard Herveille //// |
//// richard@asics.ws //// |
//// www.asics.ws //// |
//// //// |
//// Downloaded from: http://www.opencores.org/projects/i2c/ //// |
//// //// |
///////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2001 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_master_byte_ctrl.v,v 1.1 2008-11-08 13:15:10 sfielding Exp $ |
// |
// $Date: 2008-11-08 13:15:10 $ |
// $Revision: 1.1 $ |
// $Author: sfielding $ |
// $Locker: $ |
// $State: Exp $ |
// |
// Change History: |
// $Log: not supported by cvs2svn $ |
// Revision 1.7 2004/02/18 11:40:46 rherveille |
// Fixed a potential bug in the statemachine. During a 'stop' 2 cmd_ack signals were generated. Possibly canceling a new start command. |
// |
// Revision 1.6 2003/08/09 07:01:33 rherveille |
// Fixed a bug in the Arbitration Lost generation caused by delay on the (external) sda line. |
// Fixed a potential bug in the byte controller's host-acknowledge generation. |
// |
// Revision 1.5 2002/12/26 15:02:32 rherveille |
// Core is now a Multimaster I2C controller |
// |
// Revision 1.4 2002/11/30 22:24:40 rherveille |
// Cleaned up code |
// |
// Revision 1.3 2001/11/05 11:59:25 rherveille |
// Fixed wb_ack_o generation bug. |
// Fixed bug in the byte_controller statemachine. |
// Added headers. |
// |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
`include "i2c_master_defines.v" |
|
module i2c_master_byte_ctrl ( |
clk, rst, nReset, ena, clk_cnt, start, stop, read, write, ack_in, din, |
cmd_ack, ack_out, dout, i2c_busy, i2c_al, scl_i, scl_o, scl_oen, sda_i, sda_o, sda_oen ); |
|
// |
// inputs & outputs |
// |
input clk; // master clock |
input rst; // synchronous active high reset |
input nReset; // asynchronous active low reset |
input ena; // core enable signal |
|
input [15:0] clk_cnt; // 4x SCL |
|
// control inputs |
input start; |
input stop; |
input read; |
input write; |
input ack_in; |
input [7:0] din; |
|
// status outputs |
output cmd_ack; |
reg cmd_ack; |
output ack_out; |
reg ack_out; |
output i2c_busy; |
output i2c_al; |
output [7:0] dout; |
|
// I2C signals |
input scl_i; |
output scl_o; |
output scl_oen; |
input sda_i; |
output sda_o; |
output sda_oen; |
|
|
// |
// Variable declarations |
// |
|
// statemachine |
parameter [4:0] ST_IDLE = 5'b0_0000; |
parameter [4:0] ST_START = 5'b0_0001; |
parameter [4:0] ST_READ = 5'b0_0010; |
parameter [4:0] ST_WRITE = 5'b0_0100; |
parameter [4:0] ST_ACK = 5'b0_1000; |
parameter [4:0] ST_STOP = 5'b1_0000; |
|
// signals for bit_controller |
reg [3:0] core_cmd; |
reg core_txd; |
wire core_ack, core_rxd; |
|
// signals for shift register |
reg [7:0] sr; //8bit shift register |
reg shift, ld; |
|
// signals for state machine |
wire go; |
reg [2:0] dcnt; |
wire cnt_done; |
|
// |
// Module body |
// |
|
// hookup bit_controller |
i2c_master_bit_ctrl bit_controller ( |
.clk ( clk ), |
.rst ( rst ), |
.nReset ( nReset ), |
.ena ( ena ), |
.clk_cnt ( clk_cnt ), |
.cmd ( core_cmd ), |
.cmd_ack ( core_ack ), |
.busy ( i2c_busy ), |
.al ( i2c_al ), |
.din ( core_txd ), |
.dout ( core_rxd ), |
.scl_i ( scl_i ), |
.scl_o ( scl_o ), |
.scl_oen ( scl_oen ), |
.sda_i ( sda_i ), |
.sda_o ( sda_o ), |
.sda_oen ( sda_oen ) |
); |
|
// generate go-signal |
assign go = (read | write | stop) & ~cmd_ack; |
|
// assign dout output to shift-register |
assign dout = sr; |
|
// generate shift register |
always @(posedge clk or negedge nReset) |
if (!nReset) |
sr <= #1 8'h0; |
else if (rst) |
sr <= #1 8'h0; |
else if (ld) |
sr <= #1 din; |
else if (shift) |
sr <= #1 {sr[6:0], core_rxd}; |
|
// generate counter |
always @(posedge clk or negedge nReset) |
if (!nReset) |
dcnt <= #1 3'h0; |
else if (rst) |
dcnt <= #1 3'h0; |
else if (ld) |
dcnt <= #1 3'h7; |
else if (shift) |
dcnt <= #1 dcnt - 3'h1; |
|
assign cnt_done = ~(|dcnt); |
|
// |
// state machine |
// |
reg [4:0] c_state; // synopsis enum_state |
|
always @(posedge clk or negedge nReset) |
if (!nReset) |
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; |
end |
else if (rst | 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; |
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; |
|
case (c_state) // synopsys full_case parallel_case |
ST_IDLE: |
if (go) |
begin |
if (start) |
begin |
c_state <= #1 ST_START; |
core_cmd <= #1 `I2C_CMD_START; |
end |
else if (read) |
begin |
c_state <= #1 ST_READ; |
core_cmd <= #1 `I2C_CMD_READ; |
end |
else if (write) |
begin |
c_state <= #1 ST_WRITE; |
core_cmd <= #1 `I2C_CMD_WRITE; |
end |
else // stop |
begin |
c_state <= #1 ST_STOP; |
core_cmd <= #1 `I2C_CMD_STOP; |
end |
|
ld <= #1 1'b1; |
end |
|
ST_START: |
if (core_ack) |
begin |
if (read) |
begin |
c_state <= #1 ST_READ; |
core_cmd <= #1 `I2C_CMD_READ; |
end |
else |
begin |
c_state <= #1 ST_WRITE; |
core_cmd <= #1 `I2C_CMD_WRITE; |
end |
|
ld <= #1 1'b1; |
end |
|
ST_WRITE: |
if (core_ack) |
if (cnt_done) |
begin |
c_state <= #1 ST_ACK; |
core_cmd <= #1 `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; |
end |
|
ST_READ: |
if (core_ack) |
begin |
if (cnt_done) |
begin |
c_state <= #1 ST_ACK; |
core_cmd <= #1 `I2C_CMD_WRITE; |
end |
else |
begin |
c_state <= #1 ST_READ; // stay in same state |
core_cmd <= #1 `I2C_CMD_READ; // read next bit |
end |
|
shift <= #1 1'b1; |
core_txd <= #1 ack_in; |
end |
|
ST_ACK: |
if (core_ack) |
begin |
if (stop) |
begin |
c_state <= #1 ST_STOP; |
core_cmd <= #1 `I2C_CMD_STOP; |
end |
else |
begin |
c_state <= #1 ST_IDLE; |
core_cmd <= #1 `I2C_CMD_NOP; |
|
// generate command acknowledge signal |
cmd_ack <= #1 1'b1; |
end |
|
// assign ack_out output to bit_controller_rxd (contains last received bit) |
ack_out <= #1 core_rxd; |
|
core_txd <= #1 1'b1; |
end |
else |
core_txd <= #1 ack_in; |
|
ST_STOP: |
if (core_ack) |
begin |
c_state <= #1 ST_IDLE; |
core_cmd <= #1 `I2C_CMD_NOP; |
|
// generate command acknowledge signal |
cmd_ack <= #1 1'b1; |
end |
|
endcase |
end |
endmodule |
/trunk/model/wb_master_model.v
0,0 → 1,176
////////////////////////////////////////////////////////////////////// |
//// //// |
//// wb_master_model.v //// |
//// //// |
//// This file is part of the SPI IP core project //// |
//// http://www.opencores.org/projects/spi/ //// |
//// //// |
//// Author(s): //// |
//// - Simon Srot (simons@opencores.org) //// |
//// //// |
//// Based on: //// |
//// - i2c/bench/verilog/wb_master_model.v //// |
//// Copyright (C) 2001 Richard Herveille //// |
//// //// |
//// All additional information is avaliable in the Readme.txt //// |
//// file. //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2002 Authors //// |
//// //// |
//// 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 source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
`include "timescale.v" |
|
module wb_master_model(clk, rst, adr, din, dout, cyc, stb, we, sel, ack, err, rty); |
|
parameter dwidth = 32; |
parameter awidth = 32; |
|
input clk, rst; |
output [awidth -1:0] adr; |
input [dwidth -1:0] din; |
output [dwidth -1:0] dout; |
output cyc, stb; |
output we; |
output [dwidth/8 -1:0] sel; |
input ack, err, rty; |
|
// Internal signals |
reg [awidth -1:0] adr; |
reg [dwidth -1:0] dout; |
reg cyc, stb; |
reg we; |
reg [dwidth/8 -1:0] sel; |
|
reg [dwidth -1:0] q; |
|
// Memory Logic |
initial |
begin |
adr = {awidth{1'bx}}; |
dout = {dwidth{1'bx}}; |
cyc = 1'b0; |
stb = 1'bx; |
we = 1'hx; |
sel = {dwidth/8{1'bx}}; |
#1; |
end |
|
// Wishbone write cycle |
task wb_write; |
input delay; |
integer delay; |
|
input [awidth -1:0] a; |
input [dwidth -1:0] d; |
|
begin |
|
// wait initial delay |
repeat(delay) @(posedge clk); |
|
// assert wishbone signal |
#1; |
adr = a; |
dout = d; |
cyc = 1'b1; |
stb = 1'b1; |
we = 1'b1; |
sel = {dwidth/8{1'b1}}; |
@(posedge clk); |
|
// wait for acknowledge from slave |
while(~ack) @(posedge clk); |
|
// negate wishbone signals |
#1; |
cyc = 1'b0; |
stb = 1'bx; |
adr = {awidth{1'bx}}; |
dout = {dwidth{1'bx}}; |
we = 1'hx; |
sel = {dwidth/8{1'bx}}; |
|
end |
endtask |
|
// Wishbone read cycle |
task wb_read; |
input delay; |
integer delay; |
|
input [awidth -1:0] a; |
output [dwidth -1:0] d; |
|
begin |
|
// wait initial delay |
repeat(delay) @(posedge clk); |
|
// assert wishbone signals |
#1; |
adr = a; |
dout = {dwidth{1'bx}}; |
cyc = 1'b1; |
stb = 1'b1; |
we = 1'b0; |
sel = {dwidth/8{1'b1}}; |
@(posedge clk); |
|
// wait for acknowledge from slave |
while(~ack) @(posedge clk); |
|
// negate wishbone signals |
#1; |
cyc = 1'b0; |
stb = 1'bx; |
adr = {awidth{1'bx}}; |
dout = {dwidth{1'bx}}; |
we = 1'hx; |
sel = {dwidth/8{1'bx}}; |
d = din; |
|
end |
endtask |
|
// Wishbone compare cycle (read data from location and compare with expected data) |
task wb_cmp; |
input delay; |
integer delay; |
|
input [awidth -1:0] a; |
input [dwidth -1:0] d_exp; |
|
begin |
wb_read (delay, a, q); |
|
if (d_exp !== q) |
$display("Data compare error. Received %h, expected %h at time %t", q, d_exp, $time); |
end |
endtask |
|
endmodule |
|
/trunk/model/i2c_master_defines.v
0,0 → 1,64
///////////////////////////////////////////////////////////////////// |
//// //// |
//// WISHBONE rev.B2 compliant I2C Master controller defines //// |
//// //// |
//// //// |
//// Author: Richard Herveille //// |
//// richard@asics.ws //// |
//// www.asics.ws //// |
//// //// |
//// Downloaded from: http://www.opencores.org/projects/i2c/ //// |
//// //// |
///////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2001 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_master_defines.v,v 1.1 2008-11-08 13:15:10 sfielding Exp $ |
// |
// $Date: 2008-11-08 13:15:10 $ |
// $Revision: 1.1 $ |
// $Author: sfielding $ |
// $Locker: $ |
// $State: Exp $ |
// |
// Change History: |
// $Log: not supported by cvs2svn $ |
// Revision 1.3 2001/11/05 11:59:25 rherveille |
// Fixed wb_ack_o generation bug. |
// Fixed bug in the byte_controller statemachine. |
// Added headers. |
// |
|
|
// I2C registers wishbone addresses |
|
// bitcontroller states |
`define I2C_CMD_NOP 4'b0000 |
`define I2C_CMD_START 4'b0001 |
`define I2C_CMD_STOP 4'b0010 |
`define I2C_CMD_WRITE 4'b0100 |
`define I2C_CMD_READ 4'b1000 |
/trunk/model/i2c_master_specs.pdf
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
trunk/model/i2c_master_specs.pdf
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: trunk/model/i2c_master_bit_ctrl.v
===================================================================
--- trunk/model/i2c_master_bit_ctrl.v (nonexistent)
+++ trunk/model/i2c_master_bit_ctrl.v (revision 2)
@@ -0,0 +1,538 @@
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// WISHBONE rev.B2 compliant I2C Master bit-controller ////
+//// ////
+//// ////
+//// Author: Richard Herveille ////
+//// richard@asics.ws ////
+//// www.asics.ws ////
+//// ////
+//// Downloaded from: http://www.opencores.org/projects/i2c/ ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2001 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_master_bit_ctrl.v,v 1.1 2008-11-08 13:15:10 sfielding Exp $
+//
+// $Date: 2008-11-08 13:15:10 $
+// $Revision: 1.1 $
+// $Author: sfielding $
+// $Locker: $
+// $State: Exp $
+//
+// Change History:
+// $Log: not supported by cvs2svn $
+// Revision 1.12 2006/09/04 09:08:13 rherveille
+// fixed short scl high pulse after clock stretch
+// fixed slave model not returning correct '(n)ack' signal
+//
+// Revision 1.11 2004/05/07 11:02:26 rherveille
+// Fixed a bug where the core would signal an arbitration lost (AL bit set), when another master controls the bus and the other master generates a STOP bit.
+//
+// Revision 1.10 2003/08/09 07:01:33 rherveille
+// Fixed a bug in the Arbitration Lost generation caused by delay on the (external) sda line.
+// Fixed a potential bug in the byte controller's host-acknowledge generation.
+//
+// Revision 1.9 2003/03/10 14:26:37 rherveille
+// Fixed cmd_ack generation item (no bug).
+//
+// Revision 1.8 2003/02/05 00:06:10 rherveille
+// Fixed a bug where the core would trigger an erroneous 'arbitration lost' interrupt after being reset, when the reset pulse width < 3 clk cycles.
+//
+// Revision 1.7 2002/12/26 16:05:12 rherveille
+// Small code simplifications
+//
+// Revision 1.6 2002/12/26 15:02:32 rherveille
+// Core is now a Multimaster I2C controller
+//
+// Revision 1.5 2002/11/30 22:24:40 rherveille
+// Cleaned up code
+//
+// Revision 1.4 2002/10/30 18:10:07 rherveille
+// Fixed some reported minor start/stop generation timing issuess.
+//
+// Revision 1.3 2002/06/15 07:37:03 rherveille
+// Fixed a small timing bug in the bit controller.\nAdded verilog simulation environment.
+//
+// Revision 1.2 2001/11/05 11:59:25 rherveille
+// Fixed wb_ack_o generation bug.
+// Fixed bug in the byte_controller statemachine.
+// Added headers.
+//
+
+//
+/////////////////////////////////////
+// Bit controller section
+/////////////////////////////////////
+//
+// Translate simple commands into SCL/SDA transitions
+// Each command has 5 states, A/B/C/D/idle
+//
+// start: SCL ~~~~~~~~~~\____
+// SDA ~~~~~~~~\______
+// x | A | B | C | D | i
+//
+// repstart SCL ____/~~~~\___
+// SDA __/~~~\______
+// x | A | B | C | D | i
+//
+// stop SCL ____/~~~~~~~~
+// SDA ==\____/~~~~~
+// x | A | B | C | D | i
+//
+//- write SCL ____/~~~~\____
+// SDA ==X=========X=
+// x | A | B | C | D | i
+//
+//- read SCL ____/~~~~\____
+// SDA XXXX=====XXXX
+// x | A | B | C | D | i
+//
+
+// Timing: Normal mode Fast mode
+///////////////////////////////////////////////////////////////////////
+// Fscl 100KHz 400KHz
+// Th_scl 4.0us 0.6us High period of SCL
+// Tl_scl 4.7us 1.3us Low period of SCL
+// Tsu:sta 4.7us 0.6us setup time for a repeated start condition
+// Tsu:sto 4.0us 0.6us setup time for a stop conditon
+// Tbuf 4.7us 1.3us Bus free time between a stop and start condition
+//
+
+// synopsys translate_off
+`include "timescale.v"
+// synopsys translate_on
+
+`include "i2c_master_defines.v"
+
+module i2c_master_bit_ctrl(
+ clk, rst, nReset,
+ clk_cnt, ena, cmd, cmd_ack, busy, al, din, dout,
+ scl_i, scl_o, scl_oen, sda_i, sda_o, sda_oen
+ );
+
+ //
+ // inputs & outputs
+ //
+ input clk;
+ input rst;
+ input nReset;
+ input ena; // core enable signal
+
+ input [15:0] clk_cnt; // clock prescale value
+
+ input [3:0] cmd;
+ output cmd_ack; // command complete acknowledge
+ reg cmd_ack;
+ output busy; // i2c bus busy
+ reg busy;
+ output al; // i2c bus arbitration lost
+ reg al;
+
+ input din;
+ output dout;
+ reg dout;
+
+ // I2C lines
+ input scl_i; // i2c clock line input
+ output scl_o; // i2c clock line output
+ output scl_oen; // i2c clock line output enable (active low)
+ reg scl_oen;
+ input sda_i; // i2c data line input
+ output sda_o; // i2c data line output
+ output sda_oen; // i2c data line output enable (active low)
+ reg sda_oen;
+
+
+ //
+ // variable declarations
+ //
+
+ reg sSCL, sSDA; // synchronized SCL and SDA inputs
+ reg dscl_oen; // delayed scl_oen
+ reg sda_chk; // check SDA output (Multi-master arbitration)
+ reg clk_en; // clock generation signals
+ wire slave_wait;
+// reg [15:0] cnt = clk_cnt; // clock divider counter (simulation)
+ reg [15:0] cnt; // clock divider counter (synthesis)
+
+ // state machine variable
+ reg [16:0] c_state; // synopsys enum_state
+
+ //
+ // module body
+ //
+
+ // 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;
+
+ assign slave_wait = dscl_oen && !sSCL;
+
+
+ // generate clk enable signal
+ always @(posedge clk or negedge nReset)
+ if(~nReset)
+ begin
+ cnt <= #1 16'h0;
+ clk_en <= #1 1'b1;
+ end
+ else if (rst)
+ begin
+ cnt <= #1 16'h0;
+ clk_en <= #1 1'b1;
+ end
+ else if ( ~|cnt || !ena)
+ begin
+ cnt <= #1 clk_cnt;
+ clk_en <= #1 1'b1;
+ end
+ else if (slave_wait)
+ begin
+ cnt <= #1 cnt;
+ clk_en <= #1 1'b0;
+ end
+ else
+ begin
+ cnt <= #1 cnt - 16'h1;
+ clk_en <= #1 1'b0;
+ end
+
+
+ // generate bus status controller
+ reg dSCL, dSDA;
+ reg sta_condition;
+ reg sto_condition;
+
+ // synchronize SCL and SDA inputs
+ // reduce metastability risc
+ always @(posedge clk or negedge nReset)
+ if (~nReset)
+ begin
+ sSCL <= #1 1'b1;
+ sSDA <= #1 1'b1;
+
+ dSCL <= #1 1'b1;
+ dSDA <= #1 1'b1;
+ end
+ else if (rst)
+ begin
+ sSCL <= #1 1'b1;
+ sSDA <= #1 1'b1;
+
+ dSCL <= #1 1'b1;
+ dSDA <= #1 1'b1;
+ end
+ else
+ begin
+ sSCL <= #1 scl_i;
+ sSDA <= #1 sda_i;
+
+ dSCL <= #1 sSCL;
+ dSDA <= #1 sSDA;
+ end
+
+ // detect start condition => detect falling edge on SDA while SCL is high
+ // detect stop condition => detect rising edge on SDA while SCL is high
+ always @(posedge clk or negedge nReset)
+ if (~nReset)
+ begin
+ sta_condition <= #1 1'b0;
+ sto_condition <= #1 1'b0;
+ end
+ else if (rst)
+ begin
+ sta_condition <= #1 1'b0;
+ sto_condition <= #1 1'b0;
+ end
+ else
+ begin
+ sta_condition <= #1 ~sSDA & dSDA & sSCL;
+ sto_condition <= #1 sSDA & ~dSDA & sSCL;
+ end
+
+ // generate i2c bus busy signal
+ always @(posedge clk or negedge nReset)
+ if(!nReset)
+ busy <= #1 1'b0;
+ else if (rst)
+ busy <= #1 1'b0;
+ else
+ busy <= #1 (sta_condition | busy) & ~sto_condition;
+
+ // generate arbitration lost signal
+ // aribitration lost when:
+ // 1) master drives SDA high, but the i2c bus is low
+ // 2) stop detected while not requested
+ reg cmd_stop;
+ always @(posedge clk or negedge nReset)
+ if (~nReset)
+ cmd_stop <= #1 1'b0;
+ else if (rst)
+ cmd_stop <= #1 1'b0;
+ else if (clk_en)
+ cmd_stop <= #1 cmd == `I2C_CMD_STOP;
+
+ always @(posedge clk or negedge nReset)
+ if (~nReset)
+ al <= #1 1'b0;
+ else if (rst)
+ al <= #1 1'b0;
+ else
+ al <= #1 (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;
+
+ // generate statemachine
+
+ // nxt_state decoder
+ parameter [16:0] idle = 17'b0_0000_0000_0000_0000;
+ parameter [16:0] start_a = 17'b0_0000_0000_0000_0001;
+ parameter [16:0] start_b = 17'b0_0000_0000_0000_0010;
+ parameter [16:0] start_c = 17'b0_0000_0000_0000_0100;
+ parameter [16:0] start_d = 17'b0_0000_0000_0000_1000;
+ parameter [16:0] start_e = 17'b0_0000_0000_0001_0000;
+ parameter [16:0] stop_a = 17'b0_0000_0000_0010_0000;
+ parameter [16:0] stop_b = 17'b0_0000_0000_0100_0000;
+ parameter [16:0] stop_c = 17'b0_0000_0000_1000_0000;
+ parameter [16:0] stop_d = 17'b0_0000_0001_0000_0000;
+ parameter [16:0] rd_a = 17'b0_0000_0010_0000_0000;
+ parameter [16:0] rd_b = 17'b0_0000_0100_0000_0000;
+ parameter [16:0] rd_c = 17'b0_0000_1000_0000_0000;
+ parameter [16:0] rd_d = 17'b0_0001_0000_0000_0000;
+ parameter [16:0] wr_a = 17'b0_0010_0000_0000_0000;
+ parameter [16:0] wr_b = 17'b0_0100_0000_0000_0000;
+ parameter [16:0] wr_c = 17'b0_1000_0000_0000_0000;
+ parameter [16:0] wr_d = 17'b1_0000_0000_0000_0000;
+
+ 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
+ cmd_ack <= #1 1'b0; // default no command acknowledge + assert cmd_ack only 1clk cycle
+
+ 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
+
+ // 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
+ 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
+ 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
+ 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
+ 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
+ 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
+ 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
+ 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
+ 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
+ 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
+ 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
+ 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
+ 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
+ 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)
+ 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'b1; // check SDA output
+ 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
+ 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)
+ end
+
+ endcase
+ end
+
+
+ // assign scl and sda output (always gnd)
+ assign scl_o = 1'b0;
+ assign sda_o = 1'b0;
+
+endmodule
Index: trunk/model/i2c_master_top.v
===================================================================
--- trunk/model/i2c_master_top.v (nonexistent)
+++ trunk/model/i2c_master_top.v (revision 2)
@@ -0,0 +1,301 @@
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// WISHBONE revB.2 compliant I2C Master controller Top-level ////
+//// ////
+//// ////
+//// Author: Richard Herveille ////
+//// richard@asics.ws ////
+//// www.asics.ws ////
+//// ////
+//// Downloaded from: http://www.opencores.org/projects/i2c/ ////
+//// ////
+/////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2001 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_master_top.v,v 1.1 2008-11-08 13:15:10 sfielding Exp $
+//
+// $Date: 2008-11-08 13:15:10 $
+// $Revision: 1.1 $
+// $Author: sfielding $
+// $Locker: $
+// $State: Exp $
+//
+// Change History:
+// $Log: not supported by cvs2svn $
+// Revision 1.11 2005/02/27 09:26:24 rherveille
+// Fixed register overwrite issue.
+// Removed full_case pragma, replaced it by a default statement.
+//
+// Revision 1.10 2003/09/01 10:34:38 rherveille
+// Fix a blocking vs. non-blocking error in the wb_dat output mux.
+//
+// Revision 1.9 2003/01/09 16:44:45 rherveille
+// Fixed a bug in the Command Register declaration.
+//
+// Revision 1.8 2002/12/26 16:05:12 rherveille
+// Small code simplifications
+//
+// Revision 1.7 2002/12/26 15:02:32 rherveille
+// Core is now a Multimaster I2C controller
+//
+// Revision 1.6 2002/11/30 22:24:40 rherveille
+// Cleaned up code
+//
+// Revision 1.5 2001/11/10 10:52:55 rherveille
+// Changed PRER reset value from 0x0000 to 0xffff, conform specs.
+//
+
+// synopsys translate_off
+`include "timescale.v"
+// synopsys translate_on
+
+`include "i2c_master_defines.v"
+
+module i2c_master_top(
+ wb_clk_i, wb_rst_i, arst_i, wb_adr_i, wb_dat_i, wb_dat_o,
+ wb_we_i, wb_stb_i, wb_cyc_i, wb_ack_o, wb_inta_o,
+ scl_pad_i, scl_pad_o, scl_padoen_o, sda_pad_i, sda_pad_o, sda_padoen_o );
+
+ // parameters
+ parameter ARST_LVL = 1'b0; // asynchronous reset level
+
+ //
+ // inputs & outputs
+ //
+
+ // wishbone signals
+ input wb_clk_i; // master clock input
+ input wb_rst_i; // synchronous active high reset
+ input arst_i; // asynchronous reset
+ input [2:0] wb_adr_i; // lower address bits
+ input [7:0] wb_dat_i; // databus input
+ output [7:0] wb_dat_o; // databus output
+ input wb_we_i; // write enable input
+ input wb_stb_i; // stobe/core select signal
+ input wb_cyc_i; // valid bus cycle input
+ output wb_ack_o; // bus cycle acknowledge output
+ output wb_inta_o; // interrupt request signal output
+
+ reg [7:0] wb_dat_o;
+ reg wb_ack_o;
+ reg wb_inta_o;
+
+ // I2C signals
+ // i2c clock line
+ input scl_pad_i; // SCL-line input
+ output scl_pad_o; // SCL-line output (always 1'b0)
+ output scl_padoen_o; // SCL-line output enable (active low)
+
+ // i2c data line
+ input sda_pad_i; // SDA-line input
+ output sda_pad_o; // SDA-line output (always 1'b0)
+ output sda_padoen_o; // SDA-line output enable (active low)
+
+
+ //
+ // variable declarations
+ //
+
+ // registers
+ reg [15:0] prer; // clock prescale register
+ reg [ 7:0] ctr; // control register
+ reg [ 7:0] txr; // transmit register
+ wire [ 7:0] rxr; // receive register
+ reg [ 7:0] cr; // command register
+ wire [ 7:0] sr; // status register
+
+ // done signal: command completed, clear command register
+ wire done;
+
+ // core enable signal
+ wire core_en;
+ wire ien;
+
+ // status register signals
+ wire irxack;
+ reg rxack; // received aknowledge from slave
+ reg tip; // transfer in progress
+ reg irq_flag; // interrupt pending flag
+ wire i2c_busy; // bus busy (start signal detected)
+ wire i2c_al; // i2c bus arbitration lost
+ reg al; // status register arbitration lost bit
+
+ //
+ // module body
+ //
+
+ // generate internal reset
+ wire rst_i = arst_i ^ ARST_LVL;
+
+ // generate wishbone signals
+ wire wb_wacc = wb_cyc_i & wb_stb_i & wb_we_i;
+
+ // generate acknowledge output signal
+ always @(posedge wb_clk_i)
+ wb_ack_o <= #1 wb_cyc_i & wb_stb_i & ~wb_ack_o; // because timing is always honored
+
+ // assign DAT_O
+ always @(posedge wb_clk_i)
+ begin
+ case (wb_adr_i) // synopsis parallel_case
+ 3'b000: wb_dat_o <= #1 prer[ 7:0];
+ 3'b001: wb_dat_o <= #1 prer[15:8];
+ 3'b010: wb_dat_o <= #1 ctr;
+ 3'b011: wb_dat_o <= #1 rxr; // write is transmit register (txr)
+ 3'b100: wb_dat_o <= #1 sr; // write is command register (cr)
+ 3'b101: wb_dat_o <= #1 txr;
+ 3'b110: wb_dat_o <= #1 cr;
+ 3'b111: wb_dat_o <= #1 0; // reserved
+ endcase
+ end
+
+ // generate registers
+ always @(posedge wb_clk_i or negedge rst_i)
+ if (!rst_i)
+ begin
+ prer <= #1 16'hffff;
+ ctr <= #1 8'h0;
+ txr <= #1 8'h0;
+ end
+ else if (wb_rst_i)
+ begin
+ prer <= #1 16'hffff;
+ ctr <= #1 8'h0;
+ txr <= #1 8'h0;
+ end
+ else
+ if (wb_wacc)
+ case (wb_adr_i) // synopsis parallel_case
+ 3'b000 : prer [ 7:0] <= #1 wb_dat_i;
+ 3'b001 : prer [15:8] <= #1 wb_dat_i;
+ 3'b010 : ctr <= #1 wb_dat_i;
+ 3'b011 : txr <= #1 wb_dat_i;
+ default: ;
+ endcase
+
+ // generate command register (special case)
+ always @(posedge wb_clk_i or negedge rst_i)
+ if (~rst_i)
+ cr <= #1 8'h0;
+ else if (wb_rst_i)
+ cr <= #1 8'h0;
+ else if (wb_wacc)
+ begin
+ if (core_en & (wb_adr_i == 3'b100) )
+ cr <= #1 wb_dat_i;
+ end
+ else
+ begin
+ if (done | i2c_al)
+ cr[7:4] <= #1 4'h0; // clear command bits when done
+ // or when aribitration lost
+ cr[2:1] <= #1 2'b0; // reserved bits
+ cr[0] <= #1 2'b0; // clear IRQ_ACK bit
+ end
+
+
+ // decode command register
+ wire sta = cr[7];
+ wire sto = cr[6];
+ wire rd = cr[5];
+ wire wr = cr[4];
+ wire ack = cr[3];
+ wire iack = cr[0];
+
+ // decode control register
+ assign core_en = ctr[7];
+ assign ien = ctr[6];
+
+ // hookup byte controller block
+ i2c_master_byte_ctrl byte_controller (
+ .clk ( wb_clk_i ),
+ .rst ( wb_rst_i ),
+ .nReset ( rst_i ),
+ .ena ( core_en ),
+ .clk_cnt ( prer ),
+ .start ( sta ),
+ .stop ( sto ),
+ .read ( rd ),
+ .write ( wr ),
+ .ack_in ( ack ),
+ .din ( txr ),
+ .cmd_ack ( done ),
+ .ack_out ( irxack ),
+ .dout ( rxr ),
+ .i2c_busy ( i2c_busy ),
+ .i2c_al ( i2c_al ),
+ .scl_i ( scl_pad_i ),
+ .scl_o ( scl_pad_o ),
+ .scl_oen ( scl_padoen_o ),
+ .sda_i ( sda_pad_i ),
+ .sda_o ( sda_pad_o ),
+ .sda_oen ( sda_padoen_o )
+ );
+
+ // status register block + interrupt request signal
+ always @(posedge wb_clk_i or negedge rst_i)
+ if (!rst_i)
+ begin
+ al <= #1 1'b0;
+ rxack <= #1 1'b0;
+ tip <= #1 1'b0;
+ irq_flag <= #1 1'b0;
+ end
+ else if (wb_rst_i)
+ begin
+ al <= #1 1'b0;
+ rxack <= #1 1'b0;
+ tip <= #1 1'b0;
+ irq_flag <= #1 1'b0;
+ end
+ else
+ begin
+ al <= #1 i2c_al | (al & ~sta);
+ rxack <= #1 irxack;
+ tip <= #1 (rd | wr);
+ irq_flag <= #1 (done | i2c_al | irq_flag) & ~iack; // interrupt request flag is always generated
+ end
+
+ // generate interrupt request signals
+ always @(posedge wb_clk_i or negedge rst_i)
+ if (!rst_i)
+ wb_inta_o <= #1 1'b0;
+ else if (wb_rst_i)
+ wb_inta_o <= #1 1'b0;
+ else
+ wb_inta_o <= #1 irq_flag && ien; // interrupt signal is only generated when IEN (interrupt enable bit is set)
+
+ // assign status register bits
+ assign sr[7] = rxack;
+ assign sr[6] = i2c_busy;
+ assign sr[5] = al;
+ assign sr[4:2] = 3'h0; // reserved
+ assign sr[1] = tip;
+ assign sr[0] = irq_flag;
+
+endmodule
Index: trunk/rtl/i2cSlaveTop.v
===================================================================
--- trunk/rtl/i2cSlaveTop.v (nonexistent)
+++ trunk/rtl/i2cSlaveTop.v (revision 2)
@@ -0,0 +1,82 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// i2cSlaveTop.v ////
+//// ////
+//// This file is part of the i2cSlave opencores effort.
+//// ////
+//// ////
+//// Module Description: ////
+//// You will need to modify this file to implement your
+//// interface.
+//// ////
+//// To Do: ////
+////
+//// ////
+//// Author(s): ////
+//// - Steve Fielding, sfielding@base2designs.com ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2008 Steve Fielding and OPENCORES.ORG ////
+//// ////
+//// 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 source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//
+`include "i2cSlave_define.v"
+
+
+module i2cSlaveTop (
+ clk,
+ rst,
+ sda,
+ scl,
+ myReg0
+);
+input clk;
+input rst;
+inout sda;
+input scl;
+output [7:0] myReg0;
+
+
+i2cSlave u_i2cSlave(
+ .clk(clk),
+ .rst(rst),
+ .sda(sda),
+ .scl(scl),
+ .myReg0(myReg0),
+ .myReg1(),
+ .myReg2(),
+ .myReg3(),
+ .myReg4(8'h12),
+ .myReg5(8'h34),
+ .myReg6(8'h56),
+ .myReg7(8'h78)
+
+);
+
+
+endmodule
+
+
+
Index: trunk/rtl/serialInterface.v
===================================================================
--- trunk/rtl/serialInterface.v (nonexistent)
+++ trunk/rtl/serialInterface.v (revision 2)
@@ -0,0 +1,365 @@
+
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// serialInterface.v ////
+//// ////
+//// This file is part of the i2cSlave opencores effort.
+//// ////
+//// ////
+//// Module Description: ////
+//// Perform all serial to parallel, and parallel
+//// to serial conversions. Perform device address matching
+//// Handle arbitrary length I2C reads terminated by NAK
+//// from host, and arbitrary length I2C writes terminated
+//// by STOP from host
+//// The second byte of a I2C write is always interpreted
+//// as a register address, and becomes the base register address
+//// for all read and write transactions.
+//// I2C WRITE: devAddr, regAddr, data[regAddr], data[regAddr+1], ..... data[regAddr+N]
+//// I2C READ: data[regAddr], data[regAddr+1], ..... data[regAddr+N]
+//// Note that when regAddR reaches 255 it will automatically wrap round to 0
+//// ////
+//// To Do: ////
+////
+//// ////
+//// Author(s): ////
+//// - Steve Fielding, sfielding@base2designs.com ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2008 Steve Fielding and OPENCORES.ORG ////
+//// ////
+//// 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 source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//
+`include "timescale.v"
+`include "i2cSlave_define.v"
+
+module serialInterface (clearStartStopDet, clk, dataIn, dataOut, regAddr, rst, scl, sdaIn, sdaOut, startStopDetState, writeEn);
+input clk;
+input [7:0]dataIn;
+input rst;
+input scl;
+input sdaIn;
+input [1:0]startStopDetState;
+output clearStartStopDet;
+output [7:0]dataOut;
+output [7:0]regAddr;
+output sdaOut;
+output writeEn;
+
+reg clearStartStopDet, next_clearStartStopDet;
+wire clk;
+wire [7:0]dataIn;
+reg [7:0]dataOut, next_dataOut;
+reg [7:0]regAddr, next_regAddr;
+wire rst;
+wire scl;
+wire sdaIn;
+reg sdaOut, next_sdaOut;
+wire [1:0]startStopDetState;
+reg writeEn, next_writeEn;
+
+// diagram signals declarations
+reg [2:0]bitCnt, next_bitCnt;
+reg [7:0]rxData, next_rxData;
+reg [1:0]streamSt, next_streamSt;
+reg [7:0]txData, next_txData;
+
+// BINARY ENCODED state machine: SISt
+// State codes definitions:
+`define START 4'b0000
+`define CHK_RD_WR 4'b0001
+`define READ_RD_LOOP 4'b0010
+`define READ_WT_HI 4'b0011
+`define READ_CHK_LOOP_FIN 4'b0100
+`define READ_WT_LO 4'b0101
+`define READ_WT_ACK 4'b0110
+`define WRITE_WT_LO 4'b0111
+`define WRITE_WT_HI 4'b1000
+`define WRITE_CHK_LOOP_FIN 4'b1001
+`define WRITE_LOOP_WT_LO 4'b1010
+`define WRITE_ST_LOOP 4'b1011
+`define WRITE_WT_LO2 4'b1100
+`define WRITE_WT_HI2 4'b1101
+`define WRITE_CLR_WR 4'b1110
+`define WRITE_CLR_ST_STOP 4'b1111
+
+reg [3:0]CurrState_SISt, NextState_SISt;
+
+// Diagram actions (continuous assignments allowed only: assign ...)
+// diagram ACTION
+
+
+// Machine: SISt
+
+// NextState logic (combinatorial)
+always @ (startStopDetState or streamSt or scl or txData or bitCnt or rxData or sdaIn or regAddr or dataIn or sdaOut or writeEn or dataOut or clearStartStopDet or CurrState_SISt)
+begin
+ NextState_SISt <= CurrState_SISt;
+ // Set default values for outputs and signals
+ next_streamSt <= streamSt;
+ next_txData <= txData;
+ next_rxData <= rxData;
+ next_sdaOut <= sdaOut;
+ next_writeEn <= writeEn;
+ next_dataOut <= dataOut;
+ next_bitCnt <= bitCnt;
+ next_clearStartStopDet <= clearStartStopDet;
+ next_regAddr <= regAddr;
+ case (CurrState_SISt) // synopsys parallel_case full_case
+ `START:
+ begin
+ next_streamSt <= `STREAM_IDLE;
+ next_txData <= 8'h00;
+ next_rxData <= 8'h00;
+ next_sdaOut <= 1'b1;
+ next_writeEn <= 1'b0;
+ next_dataOut <= 8'h00;
+ next_bitCnt <= 3'b000;
+ next_clearStartStopDet <= 1'b0;
+ NextState_SISt <= `CHK_RD_WR;
+ end
+ `CHK_RD_WR:
+ begin
+ if (streamSt == `STREAM_READ)
+ begin
+ NextState_SISt <= `READ_RD_LOOP;
+ next_txData <= dataIn;
+ next_regAddr <= regAddr + 1'b1;
+ next_bitCnt <= 3'b001;
+ end
+ else
+ begin
+ NextState_SISt <= `WRITE_WT_HI;
+ next_rxData <= 8'h00;
+ end
+ end
+ `READ_RD_LOOP:
+ begin
+ if (scl == 1'b0)
+ begin
+ NextState_SISt <= `READ_WT_HI;
+ next_sdaOut <= txData [7];
+ next_txData <= {txData [6:0], 1'b0};
+ end
+ end
+ `READ_WT_HI:
+ begin
+ if (scl == 1'b1)
+ begin
+ NextState_SISt <= `READ_CHK_LOOP_FIN;
+ end
+ end
+ `READ_CHK_LOOP_FIN:
+ begin
+ if (bitCnt == 3'b000)
+ begin
+ NextState_SISt <= `READ_WT_LO;
+ end
+ else
+ begin
+ NextState_SISt <= `READ_RD_LOOP;
+ next_bitCnt <= bitCnt + 1'b1;
+ end
+ end
+ `READ_WT_LO:
+ begin
+ if (scl == 1'b0)
+ begin
+ NextState_SISt <= `READ_WT_ACK;
+ next_sdaOut <= 1'b1;
+ end
+ end
+ `READ_WT_ACK:
+ begin
+ if (scl == 1'b1)
+ begin
+ NextState_SISt <= `CHK_RD_WR;
+ if (sdaIn == `I2C_NAK)
+ next_streamSt <= `STREAM_IDLE;
+ end
+ end
+ `WRITE_WT_LO:
+ begin
+ if ((scl == 1'b0) && (startStopDetState == `STOP_DET ||
+ (streamSt == `STREAM_IDLE && startStopDetState == `NULL_DET)))
+ begin
+ NextState_SISt <= `WRITE_CLR_ST_STOP;
+ case (startStopDetState)
+ `NULL_DET:
+ next_bitCnt <= bitCnt + 1'b1;
+ `START_DET: begin
+ next_streamSt <= `STREAM_IDLE;
+ next_rxData <= 8'h00;
+ end
+ default: ;
+ endcase
+ next_streamSt <= `STREAM_IDLE;
+ next_clearStartStopDet <= 1'b1;
+ end
+ else if (scl == 1'b0)
+ begin
+ NextState_SISt <= `WRITE_ST_LOOP;
+ case (startStopDetState)
+ `NULL_DET:
+ next_bitCnt <= bitCnt + 1'b1;
+ `START_DET: begin
+ next_streamSt <= `STREAM_IDLE;
+ next_rxData <= 8'h00;
+ end
+ default: ;
+ endcase
+ end
+ end
+ `WRITE_WT_HI:
+ begin
+ if (scl == 1'b1)
+ begin
+ NextState_SISt <= `WRITE_WT_LO;
+ next_rxData <= {rxData [6:0], sdaIn};
+ next_bitCnt <= 3'b000;
+ end
+ end
+ `WRITE_CHK_LOOP_FIN:
+ begin
+ if (bitCnt == 3'b111)
+ begin
+ NextState_SISt <= `WRITE_CLR_WR;
+ next_sdaOut <= `I2C_ACK;
+ case (streamSt)
+ `STREAM_IDLE: begin
+ if (rxData[7:1] == `I2C_ADDRESS &&
+ startStopDetState == `START_DET) begin
+ if (rxData[0] == 1'b1)
+ next_streamSt <= `STREAM_READ;
+ else
+ next_streamSt <= `STREAM_WRITE_ADDR;
+ end
+ else
+ next_sdaOut <= `I2C_NAK;
+ end
+ `STREAM_WRITE_ADDR: begin
+ next_streamSt <= `STREAM_WRITE_DATA;
+ next_regAddr <= rxData;
+ end
+ `STREAM_WRITE_DATA: begin
+ next_dataOut <= rxData;
+ next_writeEn <= 1'b1;
+ end
+ default:
+ next_streamSt <= streamSt;
+ endcase
+ end
+ else
+ begin
+ NextState_SISt <= `WRITE_ST_LOOP;
+ next_bitCnt <= bitCnt + 1'b1;
+ end
+ end
+ `WRITE_LOOP_WT_LO:
+ begin
+ if (scl == 1'b0)
+ begin
+ NextState_SISt <= `WRITE_CHK_LOOP_FIN;
+ end
+ end
+ `WRITE_ST_LOOP:
+ begin
+ if (scl == 1'b1)
+ begin
+ NextState_SISt <= `WRITE_LOOP_WT_LO;
+ next_rxData <= {rxData [6:0], sdaIn};
+ end
+ end
+ `WRITE_WT_LO2:
+ begin
+ if (scl == 1'b0)
+ begin
+ NextState_SISt <= `CHK_RD_WR;
+ next_sdaOut <= 1'b1;
+ end
+ end
+ `WRITE_WT_HI2:
+ begin
+ next_clearStartStopDet <= 1'b0;
+ if (scl == 1'b1)
+ begin
+ NextState_SISt <= `WRITE_WT_LO2;
+ end
+ end
+ `WRITE_CLR_WR:
+ begin
+ if (writeEn == 1'b1)
+ next_regAddr <= regAddr + 1'b1;
+ next_writeEn <= 1'b0;
+ next_clearStartStopDet <= 1'b1;
+ NextState_SISt <= `WRITE_WT_HI2;
+ end
+ `WRITE_CLR_ST_STOP:
+ begin
+ next_clearStartStopDet <= 1'b0;
+ NextState_SISt <= `CHK_RD_WR;
+ end
+ endcase
+end
+
+// Current State Logic (sequential)
+always @ (posedge clk)
+begin
+ if (rst == 1'b1)
+ CurrState_SISt <= `START;
+ else
+ CurrState_SISt <= NextState_SISt;
+end
+
+// Registered outputs logic
+always @ (posedge clk)
+begin
+ if (rst == 1'b1)
+ begin
+ sdaOut <= 1'b1;
+ writeEn <= 1'b0;
+ dataOut <= 8'h00;
+ clearStartStopDet <= 1'b0;
+ // regAddr <= // Initialization in the reset state or default value required!!
+ streamSt <= `STREAM_IDLE;
+ txData <= 8'h00;
+ rxData <= 8'h00;
+ bitCnt <= 3'b000;
+ end
+ else
+ begin
+ sdaOut <= next_sdaOut;
+ writeEn <= next_writeEn;
+ dataOut <= next_dataOut;
+ clearStartStopDet <= next_clearStartStopDet;
+ regAddr <= next_regAddr;
+ streamSt <= next_streamSt;
+ txData <= next_txData;
+ rxData <= next_rxData;
+ bitCnt <= next_bitCnt;
+ end
+end
+
+endmodule
\ No newline at end of file
Index: trunk/rtl/i2cSlave_define.v
===================================================================
--- trunk/rtl/i2cSlave_define.v (nonexistent)
+++ trunk/rtl/i2cSlave_define.v (revision 2)
@@ -0,0 +1,68 @@
+// ----------------------- i2cSlave_define.v --------------------
+
+// stream states
+`define STREAM_IDLE 2'b00
+`define STREAM_READ 2'b01
+`define STREAM_WRITE_ADDR 2'b10
+`define STREAM_WRITE_DATA 2'b11
+
+// start stop detection states
+`define NULL_DET 2'b00
+`define START_DET 2'b01
+`define STOP_DET 2'b10
+
+// i2c ack and nak
+`define I2C_NAK 1'b1
+`define I2C_ACK 1'b0
+
+// ----------------------------------------------------------------
+// ------------- modify constants below this line -----------------
+// ----------------------------------------------------------------
+
+// i2c device address
+`define I2C_ADDRESS 7'h3c
+
+// System clock frequency in MHz
+// If you are using a clock frequency below 24MHz, then the macro
+// for SDA_DEL_LEN will result in compile errors for i2cSlave.v
+// you will need to hand tweak the SDA_DEL_LEN constant definition
+`define CLK_FREQ 48
+
+// Debounce SCL and SDA over this many clock ticks
+// The rise time of SCL and SDA can be up to 1000nS (in standard mode)
+// so it is essential to debounce the inputs.
+// The spec requires 0.05V of hysteresis, but in practise
+// simply debouncing the inputs is sufficient
+// I2C spec requires suppresion of spikes of
+// maximum duration 50nS, so this debounce time should be greater than 50nS
+// Also increases data hold time and decreases data setup time
+// during an I2C read operation
+// 10 ticks = 208nS @ 48MHz
+`define DEB_I2C_LEN (10*`CLK_FREQ)/48
+
+// Delay SCL for use as internal sampling clock
+// Using delayed version of SCL to ensure that
+// SDA is stable when it is sampled.
+// Not entirely citical, as according to I2C spec
+// SDA should have a minimum of 100nS of set up time
+// with respect to SCL rising edge. But with the very slow edge
+// speeds used in I2C it is better to err on the side of caution.
+// This delay also has the effect of adding extra hold time to the data
+// with respect to SCL falling edge. I2C spec requires 0nS of data hold time.
+// 10 ticks = 208nS @ 48MHz
+`define SCL_DEL_LEN (10*`CLK_FREQ)/48
+
+// Delay SDA for use in start/stop detection
+// Use delayed SDA during start/stop detection to avoid
+// incorrect detection at SCL falling edge.
+// From I2C spec start/stop setup is 600nS with respect to SCL rising edge
+// and start/stop hold is 600nS wrt SCL falling edge.
+// So it is relatively easy to discriminate start/stop,
+// but data setup time is a minimum of 100nS with respect to SCL rising edge
+// and 0nS hold wrt to SCL falling edge.
+// So the tricky part is providing robust start/stop detection
+// in the presence of regular data transitions.
+// This delay time should be less than 100nS
+// 4 ticks = 83nS @ 48MHz
+`define SDA_DEL_LEN (4*`CLK_FREQ)/48
+
Index: trunk/rtl/registerInterface.v
===================================================================
--- trunk/rtl/registerInterface.v (nonexistent)
+++ trunk/rtl/registerInterface.v (revision 2)
@@ -0,0 +1,116 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// registerInterface.v ////
+//// ////
+//// This file is part of the i2cSlave opencores effort.
+//// ////
+//// ////
+//// Module Description: ////
+//// You will need to modify this file to implement your
+//// interface.
+//// Add your control and status bytes/bits to module inputs and outputs,
+//// and also to the I2C read and write process blocks
+//// ////
+//// To Do: ////
+////
+//// ////
+//// Author(s): ////
+//// - Steve Fielding, sfielding@base2designs.com ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2008 Steve Fielding and OPENCORES.ORG ////
+//// ////
+//// 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 source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//
+`include "i2cSlave_define.v"
+
+
+module registerInterface (
+ clk,
+ addr,
+ dataIn,
+ writeEn,
+ dataOut,
+ myReg0,
+ myReg1,
+ myReg2,
+ myReg3,
+ myReg4,
+ myReg5,
+ myReg6,
+ myReg7
+
+);
+input clk;
+input [7:0] addr;
+input [7:0] dataIn;
+input writeEn;
+output [7:0] dataOut;
+output [7:0] myReg0;
+output [7:0] myReg1;
+output [7:0] myReg2;
+output [7:0] myReg3;
+input [7:0] myReg4;
+input [7:0] myReg5;
+input [7:0] myReg6;
+input [7:0] myReg7;
+
+reg [7:0] dataOut;
+reg [7:0] myReg0;
+reg [7:0] myReg1;
+reg [7:0] myReg2;
+reg [7:0] myReg3;
+
+// --- I2C Read
+always @(posedge clk) begin
+ case (addr)
+ 8'h00: dataOut <= myReg0;
+ 8'h01: dataOut <= myReg1;
+ 8'h02: dataOut <= myReg2;
+ 8'h03: dataOut <= myReg3;
+ 8'h04: dataOut <= myReg4;
+ 8'h05: dataOut <= myReg5;
+ 8'h06: dataOut <= myReg6;
+ 8'h07: dataOut <= myReg7;
+ default: dataOut <= 8'h00;
+ endcase
+end
+
+// --- I2C Write
+always @(posedge clk) begin
+ if (writeEn == 1'b1) begin
+ case (addr)
+ 8'h00: myReg0 <= dataIn;
+ 8'h01: myReg1 <= dataIn;
+ 8'h02: myReg2 <= dataIn;
+ 8'h03: myReg3 <= dataIn;
+ endcase
+ end
+end
+
+endmodule
+
+
+
Index: trunk/rtl/timescale.v
===================================================================
--- trunk/rtl/timescale.v (nonexistent)
+++ trunk/rtl/timescale.v (revision 2)
@@ -0,0 +1,5 @@
+//////////////////////////////////////////////////////////////////////
+// timescale.v
+//////////////////////////////////////////////////////////////////////
+`timescale 1ns / 1ps
+
Index: trunk/rtl/i2cSlave.v
===================================================================
--- trunk/rtl/i2cSlave.v (nonexistent)
+++ trunk/rtl/i2cSlave.v (revision 2)
@@ -0,0 +1,207 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// i2cSlave.v ////
+//// ////
+//// This file is part of the i2cSlave opencores effort.
+//// ////
+//// ////
+//// Module Description: ////
+//// You will need to modify this file to implement your
+//// interface.
+//// ////
+//// To Do: ////
+////
+//// ////
+//// Author(s): ////
+//// - Steve Fielding, sfielding@base2designs.com ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2008 Steve Fielding and OPENCORES.ORG ////
+//// ////
+//// 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 source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//
+`include "i2cSlave_define.v"
+
+
+module i2cSlave (
+ clk,
+ rst,
+ sda,
+ scl,
+ myReg0,
+ myReg1,
+ myReg2,
+ myReg3,
+ myReg4,
+ myReg5,
+ myReg6,
+ myReg7
+);
+
+input clk;
+input rst;
+inout sda;
+input scl;
+output [7:0] myReg0;
+output [7:0] myReg1;
+output [7:0] myReg2;
+output [7:0] myReg3;
+input [7:0] myReg4;
+input [7:0] myReg5;
+input [7:0] myReg6;
+input [7:0] myReg7;
+
+
+// local wires and regs
+reg sdaDeb;
+reg sclDeb;
+reg [`DEB_I2C_LEN-1:0] sdaPipe;
+reg [`DEB_I2C_LEN-1:0] sclPipe;
+
+reg [`SCL_DEL_LEN-1:0] sclDelayed;
+reg [`SDA_DEL_LEN-1:0] sdaDelayed;
+reg [1:0] startStopDetState;
+wire clearStartStopDet;
+wire sdaOut;
+wire sdaIn;
+wire [7:0] regAddr;
+wire [7:0] dataToRegIF;
+wire writeEn;
+wire [7:0] dataFromRegIF;
+reg [1:0] rstPipe;
+wire rstSyncToClk;
+reg startEdgeDet;
+
+assign sda = (sdaOut == 1'b0) ? 1'b0 : 1'bz;
+assign sdaIn = sda;
+
+// sync rst rsing edge to clk
+always @(posedge clk) begin
+ if (rst == 1'b1)
+ rstPipe <= 2'b11;
+ else
+ rstPipe <= {rstPipe[0], 1'b0};
+end
+
+assign rstSyncToClk = rstPipe[1];
+
+// debounce sda and scl
+always @(posedge clk) begin
+ if (rstSyncToClk == 1'b1) begin
+ sdaPipe <= {`DEB_I2C_LEN{1'b1}};
+ sdaDeb <= 1'b1;
+ sclPipe <= {`DEB_I2C_LEN{1'b1}};
+ sclDeb <= 1'b1;
+ end
+ else begin
+ sdaPipe <= {sdaPipe[`DEB_I2C_LEN-2:0], sdaIn};
+ sclPipe <= {sclPipe[`DEB_I2C_LEN-2:0], scl};
+ if (&sclPipe[`DEB_I2C_LEN-1:1] == 1'b1)
+ sclDeb <= 1'b1;
+ else if (|sclPipe[`DEB_I2C_LEN-1:1] == 1'b0)
+ sclDeb <= 1'b0;
+ if (&sdaPipe[`DEB_I2C_LEN-1:1] == 1'b1)
+ sdaDeb <= 1'b1;
+ else if (|sdaPipe[`DEB_I2C_LEN-1:1] == 1'b0)
+ sdaDeb <= 1'b0;
+ end
+end
+
+
+// delay scl and sda
+// sclDelayed is used as a delayed sampling clock
+// sdaDelayed is only used for start stop detection
+// Because sda hold time from scl falling is 0nS
+// sda must be delayed with respect to scl to avoid incorrect
+// detection of start/stop at scl falling edge.
+always @(posedge clk) begin
+ if (rstSyncToClk == 1'b1) begin
+ sclDelayed <= {`SCL_DEL_LEN{1'b1}};
+ sdaDelayed <= {`SDA_DEL_LEN{1'b1}};
+ end
+ else begin
+ sclDelayed <= {sclDelayed[`SCL_DEL_LEN-2:0], sclDeb};
+ sdaDelayed <= {sdaDelayed[`SDA_DEL_LEN-2:0], sdaDeb};
+ end
+end
+
+// start stop detection
+always @(posedge clk) begin
+ if (rstSyncToClk == 1'b1) begin
+ startStopDetState <= `NULL_DET;
+ startEdgeDet <= 1'b0;
+ end
+ else begin
+ if (sclDeb == 1'b1 && sdaDelayed[`SDA_DEL_LEN-2] == 1'b0 && sdaDelayed[`SDA_DEL_LEN-1] == 1'b1)
+ startEdgeDet <= 1'b1;
+ else
+ startEdgeDet <= 1'b0;
+ if (clearStartStopDet == 1'b1)
+ startStopDetState <= `NULL_DET;
+ else if (sclDeb == 1'b1) begin
+ if (sdaDelayed[`SDA_DEL_LEN-2] == 1'b1 && sdaDelayed[`SDA_DEL_LEN-1] == 1'b0)
+ startStopDetState <= `STOP_DET;
+ else if (sdaDelayed[`SDA_DEL_LEN-2] == 1'b0 && sdaDelayed[`SDA_DEL_LEN-1] == 1'b1)
+ startStopDetState <= `START_DET;
+ end
+ end
+end
+
+
+registerInterface u_registerInterface(
+ .clk(clk),
+ .addr(regAddr),
+ .dataIn(dataToRegIF),
+ .writeEn(writeEn),
+ .dataOut(dataFromRegIF),
+ .myReg0(myReg0),
+ .myReg1(myReg1),
+ .myReg2(myReg2),
+ .myReg3(myReg3),
+ .myReg4(myReg4),
+ .myReg5(myReg5),
+ .myReg6(myReg6),
+ .myReg7(myReg7)
+);
+
+serialInterface u_serialInterface (
+ .clk(clk),
+ .rst(rstSyncToClk | startEdgeDet),
+ .dataIn(dataFromRegIF),
+ .dataOut(dataToRegIF),
+ .writeEn(writeEn),
+ .regAddr(regAddr),
+ .scl(sclDelayed[`SCL_DEL_LEN-1]),
+ .sdaIn(sdaDeb),
+ .sdaOut(sdaOut),
+ .startStopDetState(startStopDetState),
+ .clearStartStopDet(clearStartStopDet)
+);
+
+
+endmodule
+
+
+
Index: trunk/doc/i2cSlave_IPCore_Specification.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: trunk/doc/i2cSlave_IPCore_Specification.pdf
===================================================================
--- trunk/doc/i2cSlave_IPCore_Specification.pdf (nonexistent)
+++ trunk/doc/i2cSlave_IPCore_Specification.pdf (revision 2)
trunk/doc/i2cSlave_IPCore_Specification.pdf
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: trunk/doc/i2cSlave_FSM.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: trunk/doc/i2cSlave_FSM.pdf
===================================================================
--- trunk/doc/i2cSlave_FSM.pdf (nonexistent)
+++ trunk/doc/i2cSlave_FSM.pdf (revision 2)
trunk/doc/i2cSlave_FSM.pdf
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: trunk/doc/Philips_I2C_spec.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: trunk/doc/Philips_I2C_spec.pdf
===================================================================
--- trunk/doc/Philips_I2C_spec.pdf (nonexistent)
+++ trunk/doc/Philips_I2C_spec.pdf (revision 2)
trunk/doc/Philips_I2C_spec.pdf
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: trunk/doc/src/i2cSlave_IPCore_Specification.sxw
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: trunk/doc/src/i2cSlave_IPCore_Specification.sxw
===================================================================
--- trunk/doc/src/i2cSlave_IPCore_Specification.sxw (nonexistent)
+++ trunk/doc/src/i2cSlave_IPCore_Specification.sxw (revision 2)
trunk/doc/src/i2cSlave_IPCore_Specification.sxw
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: trunk/Aldec/design0/fsm.set
===================================================================
--- trunk/Aldec/design0/fsm.set (nonexistent)
+++ trunk/Aldec/design0/fsm.set (revision 2)
@@ -0,0 +1,5 @@
+FSMSET_CUTHEADER=1
+FSMSET_GENCOMMENTS=1
+FSMSET_USEDEFINE=1
+FSMSET_OMITGENNULL=0
+FSMSET_ENABLEPARSING=1
Index: trunk/Aldec/design0/design0.adf
===================================================================
--- trunk/Aldec/design0/design0.adf (nonexistent)
+++ trunk/Aldec/design0/design0.adf (revision 2)
@@ -0,0 +1,28 @@
+[Project]
+Current Flow=Generic
+VCS=0
+version=1
+Current Config=compile
+
+[Configurations]
+compile=design0
+
+[Library]
+design0=.\design0.LIB
+
+[$LibMap$]
+design0=.
+
+[Settings]
+FLOW_TYPE=HDL
+LANGUAGE=VHDL
+
+[Files]
+/serialInterface.asf=-1
+
+[Files.Data]
+.\src\serialInterface.asf=State Diagram
+
+[file_out:/serialInterface.asf]
+/\compile\serialInterface.v=-1
+
Index: trunk/Aldec/design0/src/serialInterface.asf
===================================================================
--- trunk/Aldec/design0/src/serialInterface.asf (nonexistent)
+++ trunk/Aldec/design0/src/serialInterface.asf (revision 2)
@@ -0,0 +1,207 @@
+VERSION=1.15
+HEADER
+FILE="serialInterface.asf"
+FID=4788d213
+LANGUAGE=VERILOG
+ENTITY="serialInterface"
+FRAMES=ON
+FREEOID=1240
+"LIBRARIES=//////////////////////////////////////////////////////////////////////\n//// ////\n//// serialInterface.v ////\n//// ////\n//// This file is part of the i2cSlave opencores effort.\n//// ////\n//// ////\n//// Module Description: ////\n//// Perform all serial to parallel, and parallel\n//// to serial conversions. Perform device address matching\n//// Handle arbitrary length I2C reads terminated by NAK\n//// from host, and arbitrary length I2C writes terminated\n//// by STOP from host\n//// The second byte of a I2C write is always interpreted\n//// as a register address, and becomes the base register address\n//// for all read and write transactions.\n//// I2C WRITE: devAddr, regAddr, data[regAddr], data[regAddr+1], ..... data[regAddr+N]\n//// I2C READ: data[regAddr], data[regAddr+1], ..... data[regAddr+N]\n//// Note that when regAddR reaches 255 it will automatically wrap round to 0\n//// ////\n//// To Do: ////\n//// \n//// ////\n//// Author(s): ////\n//// - Steve Fielding, sfielding@base2designs.com ////\n//// ////\n//////////////////////////////////////////////////////////////////////\n//// ////\n//// Copyright (C) 2008 Steve Fielding and OPENCORES.ORG ////\n//// ////\n//// This source file may be used and distributed without ////\n//// restriction provided that this copyright statement is not ////\n//// removed from the file and that any derivative work contains ////\n//// the original copyright notice and the associated disclaimer. ////\n//// ////\n//// This source file is free software; you can redistribute it ////\n//// and/or modify it under the terms of the GNU Lesser General ////\n//// Public License as published by the Free Software Foundation; ////\n//// either version 2.1 of the License, or (at your option) any ////\n//// later version. ////\n//// ////\n//// This source is distributed in the hope that it will be ////\n//// useful, but WITHOUT ANY WARRANTY; without even the implied ////\n//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////\n//// PURPOSE. See the GNU Lesser General Public License for more ////\n//// details. ////\n//// ////\n//// You should have received a copy of the GNU Lesser General ////\n//// Public License along with this source; if not, download it ////\n//// from ////\n//// ////\n//////////////////////////////////////////////////////////////////////\n//\n`include \"timescale.v\"\n`include \"i2cSlave_define.v\"\n"
+END
+BUNDLES
+B T "Declarations" 0,0,255 0 0 1 255,255,255 0 2844 0 0000 1 "Arial" 0
+B T "Conditions" 0,0,0 0 0 0 255,255,255 0 2844 0 0110 1 "Arial" 0
+B F "States" 0,0,0 0 0 1 0,255,0 1 3527 1480 0000 1 "Arial" 0
+B T "Actions" 0,0,0 0 0 1 255,255,255 0 2844 0 0000 1 "Arial" 0
+B T "Labels" 0,0,0 0 0 0 255,255,255 0 2844 0 0000 1 "Arial" 0
+B L "Transitions" 0,0,0 0 0 1 0,0,0 1 3527 1480 0000 1 "Arial" 0
+B F "Ports" 0,0,0 0 0 1 0,255,255 1 3527 1480 0000 1 "Arial" 0
+B L "Errors" 255,0,0 0 3 1 255,255,255 1 3527 1480 0000 1 "Arial" 0
+B T "State Labels" 0,0,0 0 0 0 255,255,255 0 2844 0 0000 1 "Arial" 4
+B F "Current State" 255,255,0 0 0 1 255,255,0 1 3527 1480 0000 1 "Arial" 0
+B T "Comments" 157,157,157 0 0 1 255,255,255 0 3527 1480 0000 1 "Arial" 0
+B L "Info" 0,255,0 0 3 1 255,255,255 1 3527 1480 0000 1 "Arial" 0
+END
+INSTHEADER 1
+PAGE 25400,25400 215900,279400
+UPPERLEFT 0,0
+GRID=OFF
+GRIDSIZE 5000,5000 10000,10000
+END
+INSTHEADER 1093
+PAGE 25400,25400 215900,279400
+UPPERLEFT 0,0
+GRID=OFF
+GRIDSIZE 0,0 10000,10000
+END
+INSTHEADER 1102
+PAGE 25400,25400 215900,279400
+UPPERLEFT 0,0
+GRID=OFF
+GRIDSIZE 0,0 10000,10000
+END
+INSTHEADER 1163
+PAGE 25400,25400 215900,279400
+UPPERLEFT 0,0
+GRID=OFF
+GRIDSIZE 0,0 10000,10000
+END
+OBJECTS
+L 7 6 0 TEXT "Labels" | 31673,209974 1 0 0 "SISt"
+F 6 0 512 72 0 RECT 0,0,0 0 0 1 255,255,255 0 | 28400,28400 212900,212603
+A 5 0 1 TEXT "Actions" | 30400,266783 1 0 0 "-- diagram ACTION"
+G 1 0 0 TEXT 0,0,0 0 0 0 255,255,255 0 3527 1480 0000 1 "Arial" 0 | 110650,276400 1 0 0 "Module: serialInterface"
+I 1088 0 130 Builtin Signal | 170556,231962 "" ""
+A 1089 100 4 TEXT "Actions" | 164916,210687 1 0 0 "streamSt <= `STREAM_IDLE;\ntxData <= 8'h00;\nrxData <= 8'h00;\nsdaOut <= 1'b1;\nwriteEn <= 1'b0;\ndataOut <= 8'h00;\nbitCnt <= 3'b000;\nclearStartStopDet <= 1'b0;"
+L 1090 1091 0 TEXT "State Labels" | 113022,167010 1 0 0 "CHK_RD_WR\n/1/"
+S 1091 6 4096 ELLIPSE "States" | 113022,167010 6500 6500
+L 1092 1093 0 TEXT "State Labels" | 145788,131922 1 0 0 "READ"
+S 1093 6 8196 ELLIPSE 0,0,0 0 0 1 0,255,255 1 | 145788,131922 6500 6500
+H 1094 1093 0 RECT 0,0,0 0 0 1 255,255,255 0 | 28400,28400 212900,276400
+I 1097 1094 0 Builtin Entry | 45436,264408
+I 1098 1094 0 Builtin Exit | 66804,75108
+L 1101 1102 0 TEXT "State Labels" | 82836,130374 1 0 0 "WRITE"
+S 1102 6 12292 ELLIPSE 0,0,0 0 0 1 0,255,255 1 | 82836,130374 6500 6500
+H 1103 1102 0 RECT 0,0,0 0 0 1 255,255,255 0 | 28400,28400 212900,276400
+I 1106 1103 0 Builtin Entry | 45436,269052
+W 1111 6 1 1091 1093 BEZIER "Transitions" | 117575,162372 124283,155471 134905,143802 141613,136901
+W 1112 6 2 1091 1102 BEZIER "Transitions" | 108455,162386 102521,154775 92600,143235 86666,135624
+C 1113 1111 0 TEXT "Conditions" | 124761,159657 1 0 0 "streamSt == `STREAM_READ"
+L 1114 1115 0 TEXT "State Labels" | 60132,233832 1 0 0 "RD_LOOP\n/2/"
+S 1115 1094 16384 ELLIPSE "States" | 60132,233832 6500 6500
+W 1116 1094 0 1097 1115 BEZIER "Transitions" | 49435,264408 51757,258345 54648,245572 56970,239509
+L 1117 1118 0 TEXT "State Labels" | 62196,202356 1 0 0 "WT_HI\n/3/"
+S 1118 1094 20480 ELLIPSE "States" | 62196,202356 6500 6500
+W 1119 1094 0 1115 1118 BEZIER "Transitions" | 60334,227358 60656,222198 61220,213982 61542,208822
+C 1120 1119 0 TEXT "Conditions" | 61814,227496 1 0 0 "scl == 1'b0"
+L 1121 1122 0 TEXT "State Labels" | 63833,168493 1 0 0 "CHK_LOOP_FIN\n/4/"
+S 1122 1094 24576 ELLIPSE "States" | 63833,168493 6500 6500
+W 1123 1094 0 1118 1122 BEZIER "Transitions" | 62616,195885 62873,192095 63548,178990 63552,174971
+C 1124 1123 0 TEXT "Conditions" | 65004,194763 1 0 0 "scl == 1'b1"
+A 1125 1116 16 TEXT "Actions" | 46574,259544 1 0 0 "txData <= dataIn;\nregAddr <= regAddr + 1'b1;\nbitCnt <= 3'b001;"
+L 1127 1128 0 TEXT "State Labels" | 64515,139815 1 0 0 "WT_LO\n/5/"
+S 1128 1094 28672 ELLIPSE "States" | 64515,139815 6500 6500
+W 1133 1094 1 1122 1128 BEZIER "Transitions" | 63734,162016 63671,157426 63956,150868 63893,146278
+C 1135 1133 0 TEXT "Conditions" | 67448,161363 1 0 0 "bitCnt == 3'b000"
+W 1136 1094 2 1122 1115 BEZIER "Transitions" | 70264,169432 80793,170973 95664,170699 106435,174896\
+ 117206,179094 120169,183293 119563,193014 118958,202736\
+ 113857,211534 106441,217176 99026,222818 76882,233683\
+ 66172,236233
+L 1137 1138 0 TEXT "State Labels" | 65790,108960 1 0 0 "WT_ACK\n/6/"
+S 1138 1094 32768 ELLIPSE "States" | 65790,108960 6500 6500
+W 1139 1094 0 1128 1138 BEZIER "Transitions" | 64641,133339 64223,128449 65212,119705 65696,115446
+A 1141 1136 16 TEXT "Actions" | 99952,191787 1 0 0 "bitCnt <= bitCnt + 1'b1;"
+A 1143 1119 16 TEXT "Actions" | 42458,221543 1 0 0 "sdaOut <= txData [7];\ntxData <= {txData [6:0], 1'b0};"
+C 1144 1139 0 TEXT "Conditions" | 66481,131783 1 0 0 "scl == 1'b0"
+W 1147 1094 0 1138 1098 BEZIER "Transitions" | 65848,102499 65911,97591 66741,82032 66804,77124
+C 1148 1147 0 TEXT "Conditions" | 67234,101707 1 0 0 "scl == 1'b1"
+A 1149 1147 16 TEXT "Actions" | 61593,95455 1 0 0 "if (sdaIn == `I2C_NAK)\n streamSt <= `STREAM_IDLE;"
+A 1150 1139 16 TEXT "Actions" | 63113,125918 1 0 0 "sdaOut <= 1'b1;"
+L 71 72 0 TEXT "Labels" | 201700,272800 1 0 0 "clk"
+I 72 0 3 Builtin InPort | 195700,272800 "" ""
+L 73 74 0 TEXT "Labels" | 201700,267632 1 0 0 "rst"
+I 74 0 2 Builtin InPort | 195700,267632 "" ""
+L 1152 1153 0 TEXT "State Labels" | 50328,243636 1 0 0 "WT_HI\n/8/"
+S 1153 1103 45056 ELLIPSE "States" | 50328,243636 6500 6500
+W 1154 1103 0 1106 1153 BEZIER "Transitions" | 45436,266988 46403,261957 48180,255054 49147,250023
+L 1156 1157 0 TEXT "State Labels" | 53682,211902 1 0 0 "WT_LO\n/7/"
+S 1157 1103 40960 ELLIPSE "States" | 53682,211902 6500 6500
+W 1158 1103 0 1153 1157 BEZIER "Transitions" | 50941,237173 51263,234013 52778,221621 52602,218309
+C 1160 1158 0 TEXT "Conditions" | 52521,236757 1 0 0 "scl == 1'b1"
+L 1162 1163 0 TEXT "State Labels" | 54198,183780 1 0 0 "J1"
+S 1163 1103 36868 ELLIPSE 0,0,0 0 0 1 255,0,0 1 | 54136,183976 3858 3858
+W 1164 1103 0 1157 1163 BEZIER "Transitions" | 53938,205422 54389,199424 52869,194235 53483,187777
+C 1165 1164 0 TEXT "Conditions" | 36280,204549 1 0 0 "scl == 1'b0"
+H 1166 1163 0 RECT 0,0,0 0 0 1 255,255,255 0 | 28400,28400 212900,276400
+I 1169 1166 0 Builtin Entry | 96520,182880
+I 1170 1166 0 Builtin Exit | 144780,121920
+W 1171 1166 0 1169 1170 BEZIER "Transitions" | 100503,182880 105961,175176 136367,129625 141825,121920
+C 1174 1173 0 TEXT "Conditions" | 38599,178519 1 0 0 "startStopDetState == `STOP_DET || \n(streamSt == `STREAM_IDLE && startStopDetState == `NULL_DET)"
+A 1175 1158 16 TEXT "Actions" | 50457,231381 1 0 0 "rxData <= {rxData [6:0], sdaIn};\nbitCnt <= 3'b000;"
+L 1176 1177 0 TEXT "State Labels" | 153270,180426 1 0 0 "ST_LOOP\n/11/"
+S 1177 1103 57344 ELLIPSE "States" | 153270,180426 6500 6500
+W 1178 1103 2 1163 1177 BEZIER "Transitions" | 57992,183868 81212,183352 123565,181370 146785,180854
+L 1179 1180 0 TEXT "State Labels" | 155592,146628 1 0 0 "LOOP_WT_LO\n/10/"
+S 1180 1103 53248 ELLIPSE "States" | 155592,146628 6500 6500
+L 1181 1182 0 TEXT "State Labels" | 157656,119022 1 0 0 "CHK_LOOP_FIN\n/9/"
+S 1182 1103 49152 ELLIPSE "States" | 157656,119022 6500 6500
+W 1183 1103 0 1177 1180 BEZIER "Transitions" | 153480,173948 154060,169433 154616,157853 155339,153110
+W 1173 1103 1 1163 1227 BEZIER "Transitions" | 53628,180156 50790,158613 43756,133955 42667,107411
+L 99 100 0 TEXT "State Labels" | 112176,193512 1 0 0 "START\n/0/"
+S 100 6 0 ELLIPSE "States" | 112176,193512 6500 6500
+C 1184 1183 0 TEXT "Conditions" | 155746,173950 1 0 0 "scl == 1'b1"
+A 1185 1183 16 TEXT "Actions" | 132915,164958 1 0 0 "rxData <= {rxData [6:0], sdaIn};"
+W 1186 1103 0 1180 1182 BEZIER "Transitions" | 155830,140145 156152,136275 156699,129381 156919,125472
+C 1187 1186 0 TEXT "Conditions" | 157807,138966 1 0 0 "scl == 1'b0"
+L 1188 1189 0 TEXT "State Labels" | 140079,63027 1 0 0 "WT_HI2\n/13/"
+S 1189 1103 65536 ELLIPSE "States" | 140079,63027 6500 6500
+W 1190 1103 1 1182 1222 BEZIER "Transitions" | 158063,112542 158373,105705 114008,67631 99616,51225
+C 1191 1190 0 TEXT "Conditions" | 154327,105370 1 0 0 "bitCnt == 3'b111"
+W 1192 1103 2 1182 1177 BEZIER "Transitions" | 164050,120187 172177,122186 187713,125537 192034,132825\
+ 196356,140113 197388,165269 194840,174814 192293,184360\
+ 181069,197390 175554,198486 170040,199583 161883,190407\
+ 156465,186086
+A 1194 1192 16 TEXT "Actions" | 177909,132825 1 0 0 "bitCnt <= bitCnt + 1'b1;"
+A 1195 1190 16 TEXT "Actions" | 75201,159471 1 0 0 "sdaOut <= `I2C_ACK;\ncase (streamSt)\n `STREAM_IDLE: begin\n if (rxData[7:1] == `I2C_ADDRESS && \n startStopDetState == `START_DET) begin\n if (rxData[0] == 1'b1)\n streamSt <= `STREAM_READ;\n else\n streamSt <= `STREAM_WRITE_ADDR;\n end\n else\n sdaOut <= `I2C_NAK;\n end\n `STREAM_WRITE_ADDR: begin\n streamSt <= `STREAM_WRITE_DATA;\n regAddr <= rxData;\n end\n `STREAM_WRITE_DATA: begin\n dataOut <= rxData;\n writeEn <= 1'b1;\n end\n default:\n streamSt <= streamSt; \nendcase"
+L 1196 1197 0 TEXT "State Labels" | 191305,78543 1 0 0 "WT_LO2\n/12/"
+S 1197 1103 61440 ELLIPSE "States" | 191305,78543 6500 6500
+W 1198 1103 0 1189 1197 BEZIER "Transitions" | 146335,64787 154139,63625 179557,72674 185403,75822
+C 1199 1198 0 TEXT "Conditions" | 155872,71869 1 0 0 "scl == 1'b1"
+W 1211 6 0 1102 1091 BEZIER "Transitions" | 76391,131214 68980,132010 55006,133664 50535,137890\
+ 46064,142116 43001,157429 45206,164043 47411,170658\
+ 59294,181807 66276,184103 73258,186400 89307,184440\
+ 95064,182296 100821,180153 105473,175392 108964,172085
+W 1210 6 0 1093 1091 BEZIER "Transitions" | 152177,133113 160752,135501 176220,139177 178823,144934\
+ 181427,150691 174688,168944 167277,174211 159867,179478\
+ 136958,182297 130006,181531 123055,180765 119021,175394\
+ 116571,172454
+I 1209 0 130 Builtin Signal | 170935,221379 "" ""
+L 1208 1209 0 TEXT "Labels" | 173935,221379 1 0 0 "rxData[7:0]"
+I 1207 0 130 Builtin Signal | 170682,226692 "" ""
+L 1206 1207 0 TEXT "Labels" | 173682,226692 1 0 0 "txData[7:0]"
+I 387 6 0 Builtin Reset | 49555,202550
+W 388 6 0 387 100 BEZIER "Transitions" | 49555,202550 64193,201024 91216,196545 105854,195019
+C 389 388 0 TEXT "Conditions" | 63836,205024 1 0 0 "rst == 1'b1"
+W 1201 1103 0 1197 1228 BEZIER "Transitions" | 192418,72141 193381,63146 199794,43721 197819,33702
+C 1202 1201 0 TEXT "Conditions" | 186842,58803 1 0 0 "scl == 1'b0"
+A 1203 1173 16 TEXT "Actions" | 31827,161251 1 0 0 "streamSt <= `STREAM_IDLE;\nclearStartStopDet <= 1'b1;"
+A 1205 1154 16 TEXT "Actions" | 46743,263198 1 0 0 "rxData <= 8'h00;"
+L 1212 1213 0 TEXT "Labels" | 173176,236812 1 0 0 "bitCnt[2:0]"
+I 1213 0 130 Builtin Signal | 170176,236812 "" ""
+L 1215 1216 0 TEXT "Labels" | 82738,249858 1 0 0 "clearStartStopDet"
+I 1216 0 2 Builtin OutPort | 76738,249858 "" ""
+A 1218 1164 16 TEXT "Actions" | 61717,219098 1 0 0 "case (startStopDetState)\n `NULL_DET:\n bitCnt <= bitCnt + 1'b1;\n `START_DET: begin\n streamSt <= `STREAM_IDLE;\n rxData <= 8'h00;\n end\n default: ;\nendcase"
+A 1219 1201 16 TEXT "Actions" | 186936,64587 1 0 0 "sdaOut <= 1'b1;"
+L 1221 1222 0 TEXT "State Labels" | 97155,45210 1 0 0 "CLR_WR\n/14/"
+S 1222 1103 69632 ELLIPSE "States" | 97155,45210 6500 6500
+A 1223 1222 4 TEXT "Actions" | 51543,60237 1 0 0 "if (writeEn == 1'b1)\n regAddr <= regAddr + 1'b1;\nwriteEn <= 1'b0;\nclearStartStopDet <= 1'b1;"
+W 1224 1103 0 1222 1189 BEZIER "Transitions" | 103397,43398 108943,43589 118129,42724 122750,44891\
+ 127372,47058 132685,53538 136382,57681
+A 1225 1189 4 TEXT "Actions" | 138593,50693 1 0 0 "clearStartStopDet <= 1'b0;"
+L 1226 1227 0 TEXT "State Labels" | 44784,101266 1 0 0 "CLR_ST_STOP\n/15/"
+S 1227 1103 73728 ELLIPSE "States" | 44784,101266 6500 6500
+I 1228 1103 0 Builtin Exit | 194898,33702
+W 1229 1103 0 1227 1228 BEZIER "Transitions" | 43558,94885 41209,84027 36973,63356 36338,55800\
+ 35703,48244 37863,39734 41355,37226 44847,34718\
+ 56659,33194 75867,32940 95076,32686 159465,33448\
+ 191977,33702
+A 1230 1227 4 TEXT "Actions" | 30606,92250 1 0 0 "clearStartStopDet <= 1'b0;"
+W 1239 6 0 100 1091 BEZIER "Transitions" | 112488,187021 112665,183009 112810,177405 112987,173393
+I 479 0 130 Builtin InPort | 123454,253473 "" ""
+L 478 477 0 TEXT "Labels" | 127232,248761 1 0 0 "dataOut[7:0]"
+I 477 0 130 Builtin OutPort | 121232,248761 "" ""
+L 476 475 0 TEXT "Labels" | 127470,243915 1 0 0 "writeEn"
+I 475 0 2 Builtin OutPort | 121470,243915 "" ""
+L 472 471 0 TEXT "Labels" | 126974,258272 1 0 0 "regAddr[7:0]"
+I 471 0 130 Builtin OutPort | 120974,258272 "" ""
+L 480 479 0 TEXT "Labels" | 129454,253473 1 0 0 "dataIn[7:0]"
+I 499 0 2 Builtin InPort | 79523,242127 "" ""
+L 498 499 0 TEXT "Labels" | 85523,242127 1 0 0 "scl"
+I 497 0 130 Builtin InPort | 78578,254745 "" ""
+L 496 497 0 TEXT "Labels" | 84578,254745 1 0 0 "startStopDetState[1:0]"
+I 1065 0 2 Builtin InPort | 79622,237762 "" ""
+L 1064 1065 0 TEXT "Labels" | 85622,237762 1 0 0 "sdaIn"
+L 1083 1084 0 TEXT "Labels" | 83208,232994 1 0 0 "sdaOut"
+I 1084 0 2 Builtin OutPort | 77208,232994 "" ""
+L 1087 1088 0 TEXT "Labels" | 173556,231962 1 0 0 "streamSt[1:0]"
+END
Index: trunk/sim/run_icarus.bat
===================================================================
--- trunk/sim/run_icarus.bat (nonexistent)
+++ trunk/sim/run_icarus.bat (revision 2)
@@ -0,0 +1,2 @@
+vvp testHarness
+
Index: trunk/sim/filelist.icarus
===================================================================
--- trunk/sim/filelist.icarus (nonexistent)
+++ trunk/sim/filelist.icarus (revision 2)
@@ -0,0 +1,16 @@
+../rtl/serialInterface.v
+../rtl/registerInterface.v
+../rtl/i2cSlave.v
+../model/i2c_master_bit_ctrl.v
+../model/i2c_master_byte_ctrl.v
+../model/i2c_master_top.v
+../model/wb_master_model.v
+../bench/multiByteReadWrite.v
+../bench/testHarness.v
+../bench/testCase0.v
+
++incdir+../rtl
++incdir+../bench
++incdir+../model
++define+SIM_COMPILE
+
Index: trunk/sim/build_icarus.bat
===================================================================
--- trunk/sim/build_icarus.bat (nonexistent)
+++ trunk/sim/build_icarus.bat (revision 2)
@@ -0,0 +1,4 @@
+iverilog -o testHarness -cfilelist.icarus
+
+pause
+