OpenCores
URL https://opencores.org/ocsvn/i2c_master_slave_core/i2c_master_slave_core/trunk

Subversion Repositories i2c_master_slave_core

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 3 to Rev 2
    Reverse comparison

Rev 3 → Rev 2

/tags/t1/i2c_master_slave_core/doc/i2c_spec.doc Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
tags/t1/i2c_master_slave_core/doc/i2c_spec.doc Property changes : Deleted: svn:mime-type ## -1 +0,0 ## -application/octet-stream \ No newline at end of property Index: tags/t1/i2c_master_slave_core/doc/i2c_spec.pdf =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/t1/i2c_master_slave_core/doc/i2c_spec.pdf =================================================================== --- tags/t1/i2c_master_slave_core/doc/i2c_spec.pdf (revision 3) +++ tags/t1/i2c_master_slave_core/doc/i2c_spec.pdf (nonexistent)
tags/t1/i2c_master_slave_core/doc/i2c_spec.pdf Property changes : Deleted: svn:mime-type ## -1 +0,0 ## -application/octet-stream \ No newline at end of property Index: tags/t1/i2c_master_slave_core/verilog/rtl/counter.v =================================================================== --- tags/t1/i2c_master_slave_core/verilog/rtl/counter.v (revision 3) +++ tags/t1/i2c_master_slave_core/verilog/rtl/counter.v (nonexistent) @@ -1,41 +0,0 @@ -//////////////////////////counter.v/////////////////////////////////////////////////////////////////////////////// - // -//Designed Engineer: Ravi Gupta // -//Company Name : Toomuch Semiconductor -//Email : ravi1.gupta@toomuchsemi.com // - // -//Purpose : Used for counting clock pulses for prescale register and number of bytes transferred // -//Created : 22-11-07 // - // -////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -/*// synopsys translate_off -`include "oc8051_timescale.v" -// synopsys translate_on - -`include "oc8051_defines.v"*/ - - -module counter (clk,asyn_rst,enable,load,data_in,out); - -input clk,asyn_rst,enable,load; -input [7:0] data_in; -output [7:0] out; - -reg [7:0]data; - -always@(posedge clk or posedge asyn_rst) -begin - if(asyn_rst) - data<=8'h0; //clear all bits upon asynchronous reset. - else if(load) - data<=data_in; //load the counter with incoming data if load signal is high - else if(enable) - data<=data + 1'b1; //Increment the counter if enable bit is high - else - data<=data; //else hold the data;else part is mention to avoid latch formation -end - -assign out=data; - -endmodule Index: tags/t1/i2c_master_slave_core/verilog/rtl/controller_interface.v =================================================================== --- tags/t1/i2c_master_slave_core/verilog/rtl/controller_interface.v (revision 3) +++ tags/t1/i2c_master_slave_core/verilog/rtl/controller_interface.v (nonexistent) @@ -1,546 +0,0 @@ -////////////////////////////////////////////controller_interface.v//////////////////////////////////////// -// // -//Design Engineer: Ravi Gupta // -//Company Name : Toomuch Semiconductor -//Email : ravi1.gupta@toomuchsemi.com // -// // -//Purpose : This core will be used as an interface between I2C core and Processor // -//Created : 6-12-2007 // -// // -// // -// // -// // -// // -// // -// // -// // -//Modification : Change the control register,added halt reset and inter_rst in control register -///////////////////////////////////////////////////////////////////////////////////////////////////////// - -/*// synopsys translate_off -`include "oc8051_timescale.v" -// synopsys translate_on - -`include "oc8051_defines.v"*/ - - -module processor_interface (clk,rst,add_bus,data_in,data_out,as,ds,rw,bus_busy,byte_trans,slave_addressed,arb_lost,slave_rw,inter,ack_rec, - core_en,inter_en,mode,master_rw,ack,rep_start,data,i2c_data,slave_add,time_out_reg,prescale,irq,time_out,inter_rst,halt,data_en,time_rst); -input clk; //System clock -input rst; //system reset - -//signals connecting core to processor -///////////////////////////////////// - -input [7:0]add_bus; //contains address of internal register -input [7:0]data_in; //trnasport the data for i2c core -input as; //asserted high indicates vallid address has been placed on the address bus -input ds; //asserted high indicates valid data on data bus -input rw; //"1" indicates that processor has to write else read -output irq; //interrupt to processor -output inter_rst; //this bit will be written by processor when it will clear the interrupt. -output [7:0]data_out; -output halt; -output data_en; -input time_rst; - -//signals from core to reflect te status of core and buses -/////////////////////////////////////////////////////////// - -input bus_busy; //signal from core indicates bus is busy -input byte_trans; //signal from core indicates byte transfer is in progress -input slave_addressed; //signal from core indicares core has been identified as slave -input arb_lost; //signal from core indicates bus error -input slave_rw; //signal from core indicates operation of slave core -input inter; //signal from core.this will interrupt the processor if this bit as well as interrupt enable is high -input ack_rec; //signal from core to reflect the status of ack bit -input time_out; - -//bits of control register -////////////////////////// - -inout core_en; //this bit must be cleared before any other bit of control register have any effect on core -inout inter_en; //To intrrupt the core this bit must be set when interrupt is pending -inout mode; //Transaction from "0" to "1" directes core to act as master else slave -inout master_rw; //set directiion for master either to transmit or receive -inout ack; //value of acknowledgment bit to be transmitted on SDA line during ack cycle -inout rep_start; //set this bit if processor wants a repeated start - -//data register -//////////////// - -inout [7:0]prescale; //contains the value for generating SCL frequency -inout [7:0]time_out_reg; //contains the value for maximum low period for scl -inout [7:0]slave_add; //this is the programmble slave address -inout [7:0]data; //data for i2c core -input [7:0]i2c_data; //data from core for processor - -//defining registers addresses -///////////////////////////// - -`define PRER 8'b0000_0010 -`define CTR 8'b0000_0100 -`define SR 8'b0000_1000 -`define TO 8'b0000_1010 -`define ADDR 8'b0000_1100 -`define DR 8'b0000_1110 -`define RR 8'b0000_0000 - -/*//defing the machine state -////////////////////////// - -parameter processor_idle=2'b00; -parameter processor_address=2'b01; -parameter processor_data=2'b10; -parameter processor_ack=2'b11;*/ - -//Definig internal registers and wires -///////////////////////////////////// - -wire core_en,inter_en,mode,master_rw,ack,rep_start,inter_rst,halt; -wire prescale_reg_en; -wire ctr_reg_en; -wire sr_reg_en; -wire to_reg_en; -wire addr_reg_en; -wire dr_reg_en; -reg [7:0]data_out,sr_reg,ctr_reg,dr_reg,rr_reg; -wire [7:0]data_in; //if address on add_bus matches with register address then set this high. -wire data_ie; //this is signal used for enaling the data line in read or write cycle. -wire as_d; //delay version of address strobe signal for detection of rising and falling edge -reg as_delay_sig; //same signal. -wire ds_d; //delayed version of data strobe. -wire decode; -wire rr_reg_en; - -reg ds_delay_sig; - -reg prescale_reg_en_sig; -assign prescale_reg_en = prescale_reg_en_sig; - -reg ctr_reg_en_sig; -assign ctr_reg_en = ctr_reg_en_sig; - -reg sr_reg_en_sig; -assign sr_reg_en = sr_reg_en_sig; - -reg to_reg_en_sig; -assign to_reg_en = to_reg_en_sig; - -reg addr_reg_en_sig; -assign addr_reg_en = addr_reg_en_sig; - -reg dr_reg_en_sig; -assign dr_reg_en = dr_reg_en_sig; - -reg as_d_sig; -assign as_d = as_d_sig; - -reg ds_d_sig; -assign ds_d = ds_d_sig; - -reg data_ie_sig; -assign data_ie = data_ie_sig; - -//reg core_en_sig; -//assign core_en = core_en_sig; - -//reg inter_en_sig; -//assign inter_en = inter_en_sig; - -//reg mode_sig; -//assign mode = mode_sig; - -//reg master_rw_sig; -//assign master_rw = master_rw_sig; - -//reg ack_sig; -//assign ack = ack_sig; - -//reg rep_start_sig; -//assign rep_start = rep_start_sig; - -reg [7:0]data_sig; -assign data = dr_reg; - -reg [7:0]prescale_sig; -assign prescale = prescale_sig; - -reg [7:0]time_out_sig; -assign time_out_reg = time_out_sig; - -reg [7:0]slave_add_sig; -assign slave_add = slave_add_sig; - -//reg [7:0]data_out_sig; -//assign data_out = data_out_sig; - -reg decode_sig; -assign decode = decode_sig; - -//reg inter_rst_sig; -//assign inter_rst = inter_rst_sig; - -//reg halt_sig; -//assign halt = halt_sig; -assign data_en = dr_reg_en_sig; - -reg rr_reg_en_sig; -assign rr_reg_en = rr_reg_en_sig; - - - -assign core_en = ctr_reg [7]; -assign inter_en = ctr_reg [6]; -assign mode = ctr_reg [5]; -assign master_rw = ctr_reg [4]; -assign ack = ctr_reg [3]; -assign rep_start = ctr_reg [2]; -assign inter_rst = ctr_reg [1]; -assign halt = ctr_reg [0]; - - - - - - -//generating delayed version of inputs for detection of rising and falling edge. -////////////////////////////////////////////////////////////////////////////// - -always@(posedge clk or posedge rst) -begin - -if(rst) -begin - as_delay_sig<=1'b0; - as_d_sig<=1'b0; - ds_delay_sig<=1'b0; - ds_d_sig<=1'b0; -end - -else -begin - as_delay_sig<=as; - as_d_sig<=as_delay_sig; - ds_delay_sig<=ds; - ds_d_sig<=ds_delay_sig; -end -end - -always@(posedge clk or posedge rst) -begin - if(rst) - decode_sig<=1'b0; - else if(!as_d && as) - decode_sig<=1'b1; - //else - //decode_sig<=1'b0; -end - -//address decoding logic -/////////////////////// - -//always@(posedge clk or posedge rst) -always@(rst or as or add_bus or posedge time_rst) -begin - -if(rst || time_rst) -begin -prescale_reg_en_sig<=1'b0; -ctr_reg_en_sig<=1'b0; -sr_reg_en_sig<=1'b0; -to_reg_en_sig<=1'b0; -addr_reg_en_sig<=1'b0; -dr_reg_en_sig<=1'b0; -rr_reg_en_sig <= 1'b0; - -//add_match_sig<=1'b0; -end - - - -else if(as) -begin - if(add_bus == `PRER) - begin - rr_reg_en_sig <= 1'b0; - prescale_reg_en_sig<=1'b1; - ctr_reg_en_sig<=1'b0; - sr_reg_en_sig<=1'b0; - to_reg_en_sig<=1'b0; - addr_reg_en_sig<=1'b0; - dr_reg_en_sig<=1'b0; - //add_match_sig<=1'b1; - end - - else if(add_bus == `CTR) - begin - rr_reg_en_sig <= 1'b0; - prescale_reg_en_sig<=1'b0; - ctr_reg_en_sig<=1'b1; - sr_reg_en_sig<=1'b0; - to_reg_en_sig<=1'b0; - addr_reg_en_sig<=1'b0; - dr_reg_en_sig<=1'b0; - //add_match_sig<=1'b1; - end - - else if(add_bus == `SR) - begin - rr_reg_en_sig <= 1'b0; - prescale_reg_en_sig<=1'b0; - ctr_reg_en_sig<=1'b0; - sr_reg_en_sig<=1'b1; - to_reg_en_sig<=1'b0; - addr_reg_en_sig<=1'b0; - dr_reg_en_sig<=1'b0; - //add_match_sig<=1'b1; - end - - else if(add_bus == `TO) - begin - rr_reg_en_sig <= 1'b0; - prescale_reg_en_sig<=1'b0; - ctr_reg_en_sig<=1'b0; - sr_reg_en_sig<=1'b0; - to_reg_en_sig<=1'b1; - addr_reg_en_sig<=1'b0; - dr_reg_en_sig<=1'b0; - //add_match_sig<=1'b1; - end - - else if(add_bus == `ADDR) - begin - rr_reg_en_sig <= 1'b0; - prescale_reg_en_sig<=1'b0; - ctr_reg_en_sig<=1'b0; - sr_reg_en_sig<=1'b0; - to_reg_en_sig<=1'b0; - addr_reg_en_sig<=1'b1; - dr_reg_en_sig<=1'b0; - //add_match_sig<=1'b1; - end - - else if(add_bus == `DR) - begin - - prescale_reg_en_sig<=1'b0; - ctr_reg_en_sig<=1'b0; - sr_reg_en_sig<=1'b0; - to_reg_en_sig<=1'b0; - addr_reg_en_sig<=1'b0; - dr_reg_en_sig<=1'b1; - rr_reg_en_sig <= 1'b0; - //add_match_sig<=1'b1; - end - - else if(add_bus == `RR) - begin - rr_reg_en_sig <= 1'b1; - prescale_reg_en_sig<=1'b0; - ctr_reg_en_sig<=1'b0; - sr_reg_en_sig<=1'b0; - to_reg_en_sig<=1'b0; - addr_reg_en_sig<=1'b0; - dr_reg_en_sig<=1'b0; - //add_match_sig<=1'b1; - end - - else - begin - rr_reg_en_sig <= 1'b0; - prescale_reg_en_sig<=1'b0; - ctr_reg_en_sig<=1'b0; - sr_reg_en_sig<=1'b0; - to_reg_en_sig<=1'b0; - addr_reg_en_sig<=1'b0; - dr_reg_en_sig<=1'b0; - //add_match_sig<=1'b0; - end - - -end -else -begin - prescale_reg_en_sig<=1'b0; - ctr_reg_en_sig<=1'b0; - sr_reg_en_sig<=1'b0; - to_reg_en_sig<=1'b0; - addr_reg_en_sig<=1'b0; - dr_reg_en_sig<=1'b0; - rr_reg_en_sig <= 1'b0; - end - -end - -//assigning value of data_ie line -////////////////////////////////// -always@(posedge clk or posedge rst) -begin - if(rst) - data_ie_sig<=1'b0; - else if(!ds_d && ds) - data_ie_sig<=1'b1; - -end - - -//read data to/from the register specified by processor addrress. - - -//always@(rst or addr_reg_en or ctr_reg_en or dr_reg_en or sr_reg_en or prescale_reg_en or to_reg_en or data_ie or rw or data_in ) - -always@(posedge clk or posedge rst) -begin -if(rst) -begin - sr_reg <= 8'b0; - dr_reg <= 8'b0; - rr_reg <= 8'b0; -//ctr_reg <= 8'b0; -end - -/*else if(ctr_reg_en) -begin - //sr_reg <= {byte_trans,slave_addressed,bus_busy,arb_lost,time_out,slave_rw,inter,ack_rec}; - ctr_reg <= data_in; -end*/ -else -begin - sr_reg <= {byte_trans,slave_addressed,bus_busy,arb_lost,time_out,slave_rw,inter,ack_rec}; - rr_reg <= i2c_data; -end -end - -always@(posedge clk or posedge rst or posedge time_rst) -begin - if(rst || time_rst) - begin - //initializing control register - ctr_reg <= 8'b0; - /*core_en_sig <= 1'b0; - inter_en_sig <= 1'b0; - mode_sig <= 1'b0; - master_rw_sig <= 1'b0; - ack_sig <= 1'b0; - rep_start_sig <= 1'b0; - inter_rst_sig<=1'b0;*/ - //initializing data and timer register - data_sig <= 8'b00000000; - prescale_sig <= 8'b00000000; - time_out_sig <= 8'b00000000; - data_out <= 8'b00000000; - end - - else if (data_ie) - begin - //address register - if(addr_reg_en) //if address matches with slave address register - begin - if(rw) //processor write cycle - slave_add_sig <= {data_in[7:1] , 1'b0}; - else //processor read cycle - data_out <= slave_add; - end - - //control register - if(ctr_reg_en) //if address matches with cntrol register - begin - if(rw) //processor write cycle - //begin - /*core_en_sig <= #2 ctr_reg [7]; - inter_en_sig <= #2 ctr_reg [6]; - mode_sig <= #2 ctr_reg [5]; - master_rw_sig <= #2 ctr_reg [4]; - ack_sig <= #2 ctr_reg [3]; - rep_start_sig <= #2 ctr_reg [2]; - inter_rst_sig <= #2 ctr_reg [1]; - halt_sig <= #2 ctr_reg [0];*/ - //end - - //else - ctr_reg <= data_in; //processor read cycle - else - data_out <= ctr_reg; - end - - else if(!byte_trans && bus_busy) - ctr_reg[1:0] <= 2'b0; - //data register - - if(dr_reg_en) - begin - if(rw) - dr_reg <= data_in; - else - data_out <= dr_reg; - end - - if(rr_reg_en) - begin - data_out <= rr_reg; - end - - //staus register - - if(sr_reg_en) - begin - if(!rw) - //begin - //if(data_in[0]==1'b0) - //inter_rst_sig <= 1'b0; - //else - //inter_rst_sig <= 1'b1; - //end - //else - //begin - data_out <= sr_reg; - //inter_rst_sig<=1'b0; - //end - //else - //inter_rst_sig<=1'b0; - - end - - - //prescale register - - if(prescale_reg_en) - begin - if(rw) - prescale_sig <= data_in; - else - data_out <= prescale; - end - - //time_out register - - if(to_reg_en) - begin - if(rw) - time_out_sig <= data_in; - else - data_out <= time_out_reg; - end - end -end - -//assigning values to bidirectional bus -////////////////////////////////////// - -//assign data_bus = (!rw && data_ie) ? data_out : 8'bzzzzzzzz; -//assign data_in = (rw) ? data_bus : 8'bzzzzzzzz; - -//interuupt pin to processor -assign irq = (inter && inter_en) ? 1'b1 : 1'b0; -endmodule - - - - - - - - - - Index: tags/t1/i2c_master_slave_core/verilog/rtl/i2c_blk.v =================================================================== --- tags/t1/i2c_master_slave_core/verilog/rtl/i2c_blk.v (revision 3) +++ tags/t1/i2c_master_slave_core/verilog/rtl/i2c_blk.v (nonexistent) @@ -1,172 +0,0 @@ -////////////////////////////////////////////////////////////////////////////////////////// -//Design Engineer: Ravi Gupta // -//Company Name : Toomuch Semiconductor -//Email : ravi1.gupta@toomuchsemi.com // -// // -// // -//Purpose : This module will simply interconnect controller interface // // -// controller_interface with ms_core. // -// // -// // -//Date : 11-12-07 // -// // -// // -// // -// // -// // -// // -// // -////////////////////////////////////////////////////////////////////////////////////////// -/*// synopsys translate_off -`include "oc8051_timescale.v" -// synopsys translate_on - -`include "oc8051_defines.v"*/ - - -module block(scl_oe,scl_in,scl_o,sda_oe,sda_in,sda_o,wb_add_i,wb_data_i,wb_data_o,wb_we_i,wb_stb_i,wb_cyc_i,irq,trans_comp,wb_clk_i,wb_rst_i,wb_ack_o); - -//inout scl; //Bi-directional lines to follow i2c protocol for data transfer. -input sda_in; //sda input -output sda_oe; //control line for bidirectional buffer -output sda_o; //input line for bi_firectional buffer -input scl_in; -output scl_o; -output scl_oe; -input [7:0]wb_data_i; //Bi-direction buses for transfering data to/from processor. -input [7:0]wb_add_i; //Transfer the addresses of intenal registers. -input wb_we_i; //signal from processor to indicate whether its a read or write cycle. -input wb_stb_i; //when asserted indicates address is valid. -input wb_cyc_i; //when asserted indicates data is valid. -output irq; //interupt signal to processor. -input wb_clk_i; //system clock. -input wb_rst_i; //asynchrnous reset active high. -inout trans_comp; //temprory signal for testing the core -output [7:0]wb_data_o; -output wb_ack_o; - -//declaratiion of internal signals -////////////////////////////////// - - // control register - wire [7:0] slave_add; // I2C address - wire arb_lost; // indicates that arbitration for the i2c bus is lost - wire bus_busy; // indicates the i2c bus is busy - wire [7:0] i2c_up; // i2c data register - wire [7:0] data; // uC data register - wire core_en; // i2c enable - used as i2c reset - wire inter_en; // interrupt enable - wire inter; // interrupt pending - wire mode; // i2c master/slave select - wire master_rw; // master read/write - wire rep_start; // generate a repeated start - wire ack_rec; // value of received acknowledge - wire slave_rw; // slave read/write - wire ack; // value of acknowledge to be transmitted - wire byte_trans; // indicates that one byte of data is being transferred - wire slave_addressed; // address of core matches with address transferred - wire time_out; // max low period for SCL has excedded - wire [7:0]time_out_reg; // programmable max time for SCL low period - wire [7:0]prescale; - wire inter_rst; - wire [7:0]wb_data_o; - wire halt; - wire data_en; - wire time_rst; - reg wb_ack_o; - wire rst; - -assign trans_comp = byte_trans; - -always@(posedge wb_clk_i) -begin - wb_ack_o <= #1 wb_stb_i & wb_cyc_i & ~wb_ack_o; -end - -//port map for i2c controller -//////////////////////////// - -core i2c_core - - ( - .clk(wb_clk_i), - .rst(core_en), - .sda_oe(sda_oe), - .sda_in(sda_in), - .sda_o(sda_o), - .scl_oe(scl_oe), - .scl_o(scl_o), - .scl_in(scl_in), - .ack(ack), - .mode(mode), - .rep_start(rep_start), - .master_rw(master_rw), - .data_in(data[7:0]), - .slave_add(slave_add[7:0]), - .bus_busy(bus_busy), - .byte_trans(byte_trans), - .slave_addressed(slave_addressed), - .arb_lost(arb_lost), - .slave_rw(slave_rw), - .time_out(time_out), - .inter(inter), - .ack_rec(ack_rec), - .i2c_up(i2c_up[7:0]), - .time_out_reg(time_out_reg[7:0]), - .prescale_reg(prescale[7:0]), - .inter_en(inter_en), - .inter_rst(inter_rst), - .data_en(data_en), - .halt_rst(halt), - .h_rst(wb_rst_i), - .time_rst(time_rst)); - - -//port map for controller interface -/////////////////////////////////// - -processor_interface processor_interface - - ( - .clk(wb_clk_i), - .rst(wb_rst_i), - .add_bus(wb_add_i[7:0]), - .data_in(wb_data_i[7:0]), - .as(wb_stb_i), - .ds(wb_cyc_i), - .rw(wb_we_i), - .bus_busy(bus_busy), - .byte_trans(byte_trans), - .slave_addressed(slave_addressed), - .arb_lost(arb_lost), - .slave_rw(slave_rw), - .inter(inter), - .ack_rec(ack_rec), - .core_en(core_en), - .inter_en(inter_en), - .mode(mode), - .master_rw(master_rw), - .ack(ack), - .rep_start(rep_start), - .data(data[7:0]), - .i2c_data(i2c_up[7:0]), - .slave_add(slave_add), - .time_out_reg(time_out_reg[7:0]), - .prescale(prescale[7:0]), - .irq(irq), - .time_out(time_out), - .inter_rst(inter_rst), - .halt(halt), - .data_en(data_en), - .time_rst(time_rst), - .data_out(wb_data_o)); - -//always@(scl or sda) -//$display($time,"scl=%b\tsda=%b\t\n",scl,sda); - - -endmodule - - - - Index: tags/t1/i2c_master_slave_core/verilog/rtl/ms_core.v =================================================================== --- tags/t1/i2c_master_slave_core/verilog/rtl/ms_core.v (revision 3) +++ tags/t1/i2c_master_slave_core/verilog/rtl/ms_core.v (nonexistent) @@ -1,1157 +0,0 @@ -///////////////////////////////////////ms_core.v//////////////////////////////////////////////////////////////////////// -// // -//Design engineer: Ravi Gupta // -//Company Name : Toomuch Semiconductor -//Email : ravi1.gupta@toomuchsemi.com // -// // -//Purpose : This is the core which will be used to interface I2C bus. // -//Created : 23-11-07 // - // -//Modification : Changes made in data_reg_ld // - // -//Modification : Change byte_trans generation bit // - // -//Modification : Implemented a halt bit that will be generated at the completion of 9th scl pulse in master_mode only // - // -//Modification : After core reset(time out feature) core will go in idle escaping stop generation so need to clear // -//all // -//of status register. // - // -//Modification : Remove the sm_state clause,so that even if there is no acknowledegement it will not stop the // -//generation of SCL and SDA // -//untill it gets command to generate stop from processor. // - // -//Modification : Now also checking for detect_start in acknowledgement state for repeted start condition. // -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - - -module core(clk,rst,sda_oe,sda_in,sda_o,scl_oe,scl_in,scl_o,ack,mode,rep_start,master_rw,data_in,slave_add,bus_busy,byte_trans,slave_addressed,arb_lost,slave_rw,time_out,inter,ack_rec,i2c_up,time_out_reg,prescale_reg,inter_rst,inter_en,halt_rst,data_en,time_rst,h_rst); - -////////////////////////////////////////////////signal defination//////////////////////////////////////////////////////////////// - -input clk; //System Clock -input rst; //Main Reset -output sda_oe; //I2C serial data line output to be connected to control line of bidirectional buffer on physical SDA line -input sda_in; //I2C serial data line input -output sda_o; //I2C sda line always asssign to zero this is to be connected to input of bidirectional buffer on physical SDA line -output scl_oe; //I2C serial clock line output to be connected to control line of bidirectiional buffer on physical scl line -input scl_in; //I2C serial clock line input -output scl_o; //SCL output line to be connected to input of bidirectional line -input ack; //Acknowledgement signal from control register -input mode; //master/slave mode select -input rep_start; //repeated start -input master_rw; //command to core in master mode -input [7:0]data_in; //data from processor to be outputed on I2C -input [7:0]slave_add; //I2C slave address -input data_en; -output time_rst; -input h_rst; - -//status signal: - -output bus_busy; //bus busy -inout byte_trans; //transfer of byte is in progress_reg_en - -inout slave_addressed; //addressed as slave -inout arb_lost; //arbitration has lost -inout slave_rw; //indicates the operation by slave -inout time_out; //indicates that SCL LOW time has been exceeded -output inter; //interrupt pending,will be used for interrupting processor -input inter_rst; //use to clear the interrupt -input inter_en; //processor wants to take interrupt or not - -//signal for processor -input halt_rst; -output ack_rec; //indicates that ack has been recieved,will be used to inform if master reciever wants to terminate the transfer -output [7:0]i2c_up; //I2C data for micro processor -//timing control registers -input [7:0]time_out_reg; //max SCL low period. -input [7:0]prescale_reg; //clock divider for generating SCL frequency. - -/////////////////////////////////////////End of port defination////////////////////////////////////////////////////////////////// - -wire master_slave,arbitration_lost,bb,gen_start,rep_start,byte_trans_delay,byte_trans_fall; - -//wire scl_out,sda_out,clk_cnt_enable,clk_cnt_rst,bit_cnt_enable,bit_cnt_rst,timer_cnt_enable,timer_cnt_rst,scl_in,sda_in,sda_out_reg,stop_scl_reg,master_sda, gen_stop; -wire master_sda,scl_in,gen_stop,sm_stop,detect_stop,detect_start,addr_match,core_rst,stop_scl,scl_out,neg_scl_sig,sda_sig; -//reg [7:0]clk1_cnt,bit1_cnt,timer1_cnt; -reg posedge_mode,negedge_mode; -reg [2:0]scl_state; -reg [1:0]state; -reg [2:0]scl_main_state; -wire [7:0] add_reg,shift_reg; -wire [7:0]clk_cnt,bit_cnt; -reg [7:0]time_cnt; -reg [7:0]i2c_up; -wire bit_cnt_enable,bit_cnt_rst,clk_cnt_enable,clk_cnt_rst,data_reg_ld,data_reg_en,sda_in,serial_out,i2c_serial_out,add_reg_ld,add_reg_en,posedge_mode_sig,negedge_mode_sig,interrupt; -wire [7:0]zero; -wire [7:0]reg_clr; - -wire slave_sda,sda_out,halt,arb_rst,interrupt_rst,d_detect_stop; - -shift shift_data(neg_scl,rst,data_reg_ld,data_reg_en,sda_in,data_in,serial_out,shift_reg); //shift register for transferring the data -shift shift_add(neg_scl,rst,add_reg_ld,add_reg_en,sda_in,reg_clr,i2c_serial_out,add_reg); //shift register for transferring address -counter clock_counter(clk,rst,clk_cnt_enable,clk_cnt_rst,zero,clk_cnt); //This will count number of clock pulses for prescale -counter bit_counter(neg_scl,rst,bit_cnt_enable,bit_cnt_rst,zero,bit_cnt); //Implementation of bit counter - - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -reg clk_cnt_enable_sig; -assign clk_cnt_enable = clk_cnt_enable_sig; - -reg clk_cnt_rst_sig; -assign clk_cnt_rst = clk_cnt_rst_sig; - - -//reg sda_in_sig; -//assign sda_in = sda_in_sig; - -reg sm_stop_sig; -assign sm_stop = sm_stop_sig; - -//reg scl_in_sig; -//assign scl_in = scl_in_sig; - -reg gen_start_sig; -assign gen_start = gen_start_sig; - -reg gen_stop_sig; -assign gen_stop = gen_stop_sig; - -reg master_slave_sig; -assign master_slave = master_slave_sig; - -reg detect_start_sig; -assign detect_start=detect_start_sig; - -reg detect_stop_sig; -assign detect_stop=detect_stop_sig; - -reg byte_trans_sig; -assign byte_trans= byte_trans_sig; - -reg bb_sig; -assign bb=bb_sig; - -reg slave_addressed_sig; -assign slave_addressed=slave_addressed_sig; - -reg slave_rw_sig; -assign slave_rw=slave_rw_sig; - -reg inter_sig; -assign inter=inter_sig; -assign interrupt=inter_sig; - -reg time_out_sig; -assign time_out=time_out_sig; - -reg ack_rec_sig; -assign ack_rec=ack_rec_sig; - -reg add_reg_enable_sig; -assign add_reg_en=add_reg_enable_sig; - -reg data_reg_en_sig; -assign data_reg_en=data_reg_en_sig; - -reg data_reg_ld_sig; -assign data_reg_ld=data_reg_ld_sig; - -reg stop_scl_sig; -assign stop_scl=stop_scl_sig; - -reg core_rst_sig; -assign core_rst=core_rst_sig; - -reg sda_out_sig; -assign sda_out=sda_out_sig; - -reg scl_out_sig; -assign scl_out=scl_out_sig; - -reg master_sda_sig; -assign master_sda=master_sda_sig; - -reg slave_sda_sig; -assign slave_sda=slave_sda_sig; - -reg arbitration_lost_sig; -assign arbitration_lost=arbitration_lost_sig; - -reg arb_lost_sig; -assign arb_lost=arb_lost_sig; - -reg byte_trans_delay_sig; -assign byte_trans_delay=byte_trans_delay_sig; - -reg byte_trans_fall_sig; -assign byte_trans_fall=byte_trans_fall_sig; - -reg halt_sig; -assign halt = halt_sig; - -reg arb_rst_sig; -assign arb_rst=arb_rst_sig; - -reg interrupt_rst_sig; -assign interrupt_rst=interrupt_rst_sig; - -reg rep_start_sig; -assign time_rst = core_rst; - -reg d_detect_stop_sig; -assign d_detect_stop = d_detect_stop_sig; - -reg d1_detect_stop_sig; - - -assign bus_busy = bb; -assign reg_clr=8'b00000000; -assign neg_scl_sig=(~scl_in); -assign neg_scl=neg_scl_sig; -assign zero=8'b00000000; -assign posedge_mode_sig=posedge_mode; -assign negedge_mode_sig=negedge_mode; -assign sda_o = 1'b0; //assign this to 0 always -assign scl_o = 1'b0; - - - -parameter scl_idle=3'b000,scl_start=3'b001,scl_low_edge=3'b010,scl_low=3'b011,scl_high_edge=3'b100,scl_high=3'b101; -parameter scl_address_shift=3'b001,scl_ack_address=3'b010,scl_rx_data=3'b011,scl_tx_data=3'b100,scl_send_ack=3'b101,scl_wait_ack=3'b110,scl_main_idle= 3'b000; - -parameter a=2'b00,b=2'b01,c=2'b10; - -////////////////////SCL Generator/////////////////////////////// -//This machine will generate SCL and SDA when in master mode.It will -//also generate START and STOP condition. - -//always@(scl_state or arbitration_lost or sm_stop or gen_stop or rep_start -// or bb or gen_start or master_slave or clk_cnt or bit_cnt or -// scl_in or sda_out or master_sda or core_rst) -always@(posedge clk or posedge rst or posedge core_rst or posedge h_rst) -begin - -//State machine initial conditions - -if(rst || h_rst) -begin - scl_state<=scl_idle; - scl_out_sig<=1'b1; - sda_out_sig<=1'b1; - stop_scl_sig<=1'b0; - clk_cnt_enable_sig<=1'b0; - clk_cnt_rst_sig<=1'b1; - //bit_cnt_rst_sig<=1'b0; - //bit_cnt_enable_sig<=1'b0; -end - -else if(core_rst) -begin - - scl_state<=scl_idle; - scl_main_state <= scl_main_idle; - scl_out_sig<=1'b1; - sda_out_sig<=1'b1; - stop_scl_sig<=1'b0; - clk_cnt_enable_sig<=1'b0; - clk_cnt_rst_sig<=1'b1; - slave_addressed_sig<=1'b0; -end - - -else -begin - - case (scl_state) - - scl_idle: - begin - arb_rst_sig <= 1'b1; - interrupt_rst_sig<=1'b1; - sda_out_sig<=1'b1; - stop_scl_sig<=1'b0; - - if(master_slave && !bb && gen_start) - begin - scl_state<=scl_start; - - end - end - - - scl_start: - begin - arb_rst_sig <= 1'b0; - interrupt_rst_sig<=1'b0; - clk_cnt_enable_sig<=1'b1; //enable the counter as soon as machine enters in this state. - clk_cnt_rst_sig<=1'b0; - //sda_out_sig<=1'b0; //generating start condition - stop_scl_sig<=1'b0; - if(clk_cnt == prescale_reg / 3) - sda_out_sig<= 1'b0; - - if(clk_cnt == prescale_reg) //wait for prescale value to over - scl_state<=scl_low_edge; - else - scl_state<=scl_start; - end - - scl_low_edge: - begin - clk_cnt_rst_sig<=1'b1; //This state will generate only SCL negative edge,and reset all the counters - //timer_cnt_enable_sig<=1'b1; //except timer counter which will be enabled at this state. - //timer_cnt_rst_sig<=1'b0; //also reseting the timer counter in this state. - scl_out_sig<=1'b0; - scl_state<=scl_low; - stop_scl_sig<=1'b0; - end - - scl_low: - begin - clk_cnt_enable_sig<=1'b1; //enable the clock counter - clk_cnt_rst_sig<=1'b0; - scl_out_sig<=1'b0; - - if(arbitration_lost) - stop_scl_sig<=1'b0; - else if(rep_start_sig) - begin - sda_out_sig<=1'b1; - stop_scl_sig<=1'b0; - end - - - else if((gen_stop) && ((scl_main_state != scl_ack_address) && (scl_main_state != scl_send_ack) - && (scl_main_state != scl_wait_ack))) //Ravi remove sm_stop from oring with gen_stop - begin - sda_out_sig<=1'b0; - stop_scl_sig<=1'b1; - - end - - /*else if(rep_start) - begin - sda_out_sig<=1'b1; - stop_scl_sig<=1'b0; - end*/ - else if(clk_cnt == prescale_reg / 3) - begin - sda_out_sig<=master_sda; - stop_scl_sig<=1'b0; - - end - - else - stop_scl_sig<=1'b0; - - - //determine next state. - - if(clk_cnt == prescale_reg) - begin - if(bit_cnt == 8'b0000_0111 && arbitration_lost ) - scl_state<=scl_idle; - else if(interrupt && inter_en) //uncomenting out for cheking the core in interrupt mode - scl_state<=scl_low; - else if(halt) - scl_state<=scl_low; - else - scl_state<=scl_high_edge; - end - - else - scl_state<=scl_low; - end - - - - - scl_high_edge: - begin - clk_cnt_rst_sig<=1'b1; - scl_out_sig<=1'b1; - if(gen_stop) //Ravi sm_stop from oring with gen_stop - stop_scl_sig<=1'b1; - - else - stop_scl_sig<=1'b0; - if(!scl_in) - scl_state<=scl_high_edge; - else - scl_state<=scl_high; - end - - - - scl_high: - begin - clk_cnt_enable_sig<=1'b1; - clk_cnt_rst_sig<=1'b0; - scl_out_sig<=1'b1; - if(clk_cnt == prescale_reg) - begin - if(rep_start_sig) - scl_state<=scl_start; - else if(stop_scl) - scl_state<=scl_idle; - - else - scl_state<=scl_low_edge; - end - - else - scl_state<=scl_high; - end - - - endcase -end -end - - -//Sample the incoming SDA and SCL line with System clock - -/*always@(posedge clk or posedge rst) -begin - - if(rst) - begin - //sda_in_sig <= 1'b1; - scl_in_sig <=1'b1; - end - else - begin - if(!scl) - scl_in_sig <= 1'b0; - else - scl_in_sig <= 1'b1; - - if(!sda) - sda_in_sig <= 1'b0; - else - sda_in_sig <= 1'b1; - - //sda_out_sig <= sda; - end -end*/ - -//Generartion of control signal from the command based on processor. -//This will control generation of start and stop signal. -//This will also set the master_slave bit based on MODE signal -//if bus is not busy i.e bb = 0 - -always@(posedge clk or posedge rst or posedge h_rst) -begin - if(rst || h_rst) - begin - gen_start_sig <= 1'b0; - gen_stop_sig <= 1'b0; - master_slave_sig <= 1'b0; - - end - - else - begin - if(posedge_mode_sig) - gen_start_sig <= 1'b1; - else if(detect_start) - gen_start_sig <= 1'b0; - - if(!arbitration_lost && negedge_mode_sig) - gen_stop_sig <= 1'b1; - else if(detect_stop) - gen_stop_sig <= 1'b0; - - if(!bb) - master_slave_sig <= mode; - else - master_slave_sig <= master_slave; - end -end - -//State machine for detection of rising and falling edge of input mode for the generation of START and STOP. -always@(posedge clk or posedge rst or posedge h_rst) -begin - if(rst || h_rst) - begin - posedge_mode<=1'b0; - negedge_mode<=1'b0; - state<=a; - end - - else - begin - case(state) - - a: - if(mode==1'b0) - begin - state<=b; - posedge_mode<=1'b0; - negedge_mode<=1'b0; - end - - else - begin - state<=c; - posedge_mode<=1'b1; - negedge_mode<=1'b0; - end - - b: - if(mode==1'b0) - begin - state<=b; - posedge_mode<=1'b0; - negedge_mode<=1'b0; - end - - else - begin - state<=a; - posedge_mode<=1'b1; - negedge_mode<=1'b0; - end - - c: - if(mode==1'b0) - begin - state<=a; - posedge_mode<=1'b0; - negedge_mode<=1'b1; - end - - else - begin - state<=c; - posedge_mode<=1'b0; - negedge_mode<=1'b0; - end - - endcase -end -end - -//This is the main state machine which will be used as both master as well as slave. -//This gets triggered at falling edge of SCL. -//If stop codition gets detected then it should work as asyn reset. - -always@(posedge rst or negedge scl_in or posedge detect_stop or posedge core_rst or posedge h_rst) -begin - -if(rst || core_rst || h_rst) -begin - scl_main_state<=scl_main_idle; - sm_stop_sig<=1'b0; -end - -else -begin - case(scl_main_state) - scl_main_idle: - - if(detect_start) - scl_main_state<=scl_address_shift; - else if(detect_stop) - begin - scl_main_state<=scl_main_idle; - sm_stop_sig<=1'b0; - end - - scl_address_shift: //machine will remain in this state,unless all the bits of address has been transferred. - - if(bit_cnt == 8'b0000_0111) - scl_main_state<=scl_ack_address; - else if(detect_stop) - begin - scl_main_state<=scl_main_idle; - sm_stop_sig<=1'b0; - end - - scl_ack_address: - - //if(arbitration_lost) //if arbitration lost then go to idle state releasing buses.remove this because its a - //scl_main_state<=scl_main_idle; //software problem if even after arb_lost it is giving wr/rd then it has to go to respective state. - if(detect_stop) - begin //Go to idle state if there is stop command - scl_main_state<=scl_main_idle; - sm_stop_sig<=1'b0; - end - - else if(detect_start) - begin - scl_main_state<=scl_address_shift; - sm_stop_sig<=1'b0; - end - //else if(!sda_in) - //If ack has been received then,check for slave/master - - else if(master_slave) - begin //if master then set the direction for master to either transmit - if(!master_rw) //or receive the data. - scl_main_state<=scl_rx_data; - else - scl_main_state<=scl_tx_data; //Ravi: if no detect_stop then check if master send to state depending upon - end //tx/rx bit of control register. - - else - begin //If slave then check if received address has matched - //if(addr_match) - //begin //if address matches then set the direction of communication based - if(add_reg[0]) //last bit of shift register of address cycle. - scl_main_state<=scl_tx_data; - else - scl_main_state<=scl_rx_data; - end - //else - //scl_main_state<=scl_main_idle; - //end - - - //else - //begin - // scl_main_state<=scl_main_idle; //If no ack received go to idle state. - //if(master_slave) - // sm_stop_sig<=1'b1; - //end - - scl_rx_data: - if(bit_cnt == 8'b0000_0111) - scl_main_state<=scl_send_ack; - else if(detect_stop) - begin - scl_main_state<=scl_main_idle; - sm_stop_sig<=1'b0; - end - else if(detect_start) - begin - scl_main_state<=scl_address_shift; - sm_stop_sig<=1'b0; - end - - - - - scl_tx_data: - if(bit_cnt == 8'b0000_0111) - scl_main_state<=scl_wait_ack; - else if(detect_stop) - begin - scl_main_state<=scl_main_idle; - sm_stop_sig<=1'b0; - end - else if(detect_start) - begin - scl_main_state<=scl_address_shift; - sm_stop_sig<=1'b0; - end - - - scl_send_ack: - if(detect_stop) - begin - scl_main_state<=scl_main_idle; - sm_stop_sig<=1'b0; - end - - else - scl_main_state<=scl_rx_data; - - scl_wait_ack: //Ravi: Even in this state machine will goto Tx state,if no ack or arb_lost has occur - //if(arbitration_lost) //This is software part to program the control register so that it will generate stop - //scl_main_state<=scl_main_idle; //and will go in idle state.So removing all clauses except detect stop. - if(detect_stop) - begin - scl_main_state<=scl_main_idle; - sm_stop_sig<=1'b0; - end - - - else - scl_main_state<=scl_tx_data; - //else - //begin - //if(master_slave) - //sm_stop_sig<=1'b1; - //scl_main_state<=scl_main_idle; - //end - endcase -end -end - -//Start and stop detect process -////////////////////////////// - -always@(sda_in or scl_main_state) -begin - - if(rst || h_rst) - detect_start_sig<=1'b0; - else if(!sda_in && scl_in) - detect_start_sig<=1'b1; - else if(scl_address_shift) - detect_start_sig<=1'b0; - else - detect_start_sig<=1'b0; -end - -always@(posedge sda_in or posedge detect_start) -begin - - if(rst || h_rst) - detect_stop_sig<=1'b0; - else if(detect_start) - detect_stop_sig<=1'b0; - else if(scl_in) - detect_stop_sig<=1'b1; - //else if(detect_start) - //detect_stop_sig<=1'b0; - else - detect_stop_sig<=1'b0; -end - -//generate a delay version of byte_trans signal -//This will be used for detecting falling edge of byte_trans - -always@(posedge clk or posedge rst or posedge h_rst) -begin - if(rst || h_rst) - byte_trans_delay_sig <= 1'b0; - else - begin - byte_trans_delay_sig <= byte_trans; - byte_trans_fall_sig <= byte_trans_delay && !byte_trans; - end -end - - -//Processor status bits///// -//byte_trans bit -//This indicate data is being transferred,This bit will be one only after all 8 bits has -//been tranferred.i.e on rising pulse of SCL in ack cycle. - -always@(negedge scl_in or posedge rst or posedge halt_rst or posedge core_rst or posedge h_rst) -begin - if(rst || h_rst) - byte_trans_sig<=1'b0; - else if(halt_rst) - byte_trans_sig <= 1'b0; - else if(bit_cnt == 8'b0000_1000) - byte_trans_sig<=1'b1; - else if(halt_rst || core_rst) // after core_rst negate byte_trans bit - byte_trans_sig<=1'b0; -end - -//bus_busy -//This indicates that communication is in progress and bus in not free. -//This bit will be set on detection of start and will be cleared on STOP - -always@(posedge clk or posedge rst or posedge h_rst) -begin - if(rst || h_rst) - bb_sig<=1'b0; - else - begin - if(detect_start) - bb_sig<=1'b1; - if(detect_stop || core_rst) - bb_sig<=1'b0; - end -end - -//slave_addressed bit -//This indicates that slave has been addressed,and after sending ack -//core will switch to slave mode. -//This bit will be set if adds matched in add ack state. - -always@(posedge clk or posedge rst or posedge h_rst) -begin - if(rst) //Removing h_rst - slave_addressed_sig<=1'b0; - //else if(scl_main_state == scl_ack_address) - else if(byte_trans) - slave_addressed_sig<=addr_match; - else - slave_addressed_sig<=slave_addressed; - //slave_addressed_sig<= 1'b0; -end - -//set address match bit if address reg matches with shift register output -/*always@(negedge scl or posedge rst) -begin - if(rst) - addr_match_sig<=1'b0; - else if( slave_add[7:1] == add_reg[7:1]) - addr_match_sig <=1'b1; - else - addr_match_sig<=1'b0; -end*/ -assign addr_match = slave_add[7:1] == add_reg[7:1]? 1'b1:1'b0; -assign add_reg_ld = 1'b0; - -//Slave read write -//This bit indicates slave has been addressed,this indicates -//read or write bit sent by processor. - -always@(posedge clk or posedge rst or posedge h_rst) -begin - if(rst || h_rst) - slave_rw_sig<=1'b0; - else if(scl_main_state == scl_ack_address) - slave_rw_sig<=add_reg[0]; -end - -//interrupt pending -//This will cause an interrupt to processor if interrupt enable is set -//This bit will be set in following circumstances: -//1):Byte transfer has been completed. -//2):Arbitration lost. -//3):slave has been addressed and and bytes have been transferred. -//4):Time out condition has been reached. -//5):Repeated start condition. -//Only processor can clear the interrupt. - -always@(posedge clk or posedge rst or posedge h_rst) -begin - if(rst || h_rst) - inter_sig<=1'b0; - - else - begin - //if(interrupt_rst) - //inter_sig<=1'b0; - - if(inter_rst) - inter_sig<=1'b0; - - //in below else if condition anding byte_trans with master_slave also removing add_reg[] condition in next clause - else if((byte_trans && master_slave) || arbitration_lost || (slave_addressed && !master_slave && byte_trans) || rep_start) - inter_sig<=1'b1; - - - - //else //interrupt need to get cleared by processor,so do not reset in else condition - //inter_sig<=1'b0; - - - end -end - -//generate delay version of detect_stop -always@(posedge clk or posedge rst or posedge h_rst) -begin -if(rst || h_rst) -d_detect_stop_sig <= 1'b0; -else -begin -d1_detect_stop_sig <= detect_stop; -d_detect_stop_sig <= d1_detect_stop_sig; -end -end - - -always@(posedge clk or posedge rst or posedge h_rst) -begin - if(rst || h_rst) - halt_sig <= 1'b0; - - else - begin - if(halt_rst) - halt_sig<=1'b0; - - else if(byte_trans && master_slave) - halt_sig<=1'b1; - end -end - -//acknoweldege recieve -//This bit indicates the data on SDA line during ack cycle. - -always@(posedge clk or posedge rst or posedge h_rst) -begin - if(rst || h_rst) - ack_rec_sig<=1'b0; - else if((scl_main_state == scl_wait_ack) || (scl_main_state == scl_ack_address) || (scl_main_state == scl_send_ack)) - ack_rec_sig<=sda_in; -end - -//Setting control bits of shift registers and counters -////////////////////////////////////////////////////// - -//Address shift register will just receive the data after start -//condition detection.It wont be get loaded.While data shift register -//will receive as well as transmit the data. - -//address shift register enable bit -always@(posedge clk or posedge rst or posedge h_rst) -begin - if(rst || h_rst) - add_reg_enable_sig<=1'b0; - else if(detect_start || scl_main_state == scl_address_shift) - add_reg_enable_sig<=1'b1; - else - add_reg_enable_sig<=1'b0; -end - - -//Data shift register. -//This register will be enabled every time when it is either transmitting or receiving the data. - always @(posedge clk or posedge rst or posedge h_rst) - begin - if (rst || h_rst) - begin - data_reg_en_sig <= 1'b0; - data_reg_ld_sig <= 1'b0; - end - else - begin - if (((master_slave && scl_main_state == scl_address_shift) || (scl_main_state == - scl_rx_data) || (scl_main_state == scl_tx_data))) - data_reg_en_sig <= 1'b1; - else - data_reg_en_sig <= 1'b0; - - /*if ((master_slave && scl_main_state == scl_idle) || (scl_main_state == - scl_wait_ack) || (scl_main_state == scl_ack_address && - !add_reg[0] && !master_slave) || (scl_main_state == scl_ack_address && - master_rw && master_slave))*/ - if(((scl_main_state == scl_main_idle) || byte_trans) && data_en) - - data_reg_ld_sig <= 1'b1; - else - data_reg_ld_sig <= 1'b0; - - end - - end - -//logic for generating control bits for bit counter -//////////////////////////////////////////////////////////////////////////////////////////////// -assign bit_cnt_enable = ((scl_main_state == scl_address_shift) || (scl_main_state == scl_rx_data) || (scl_main_state == scl_tx_data)); -assign bit_cnt_rst = ((scl_main_state == scl_main_idle) || (scl_main_state == scl_send_ack) || (scl_main_state == scl_wait_ack) || (scl_main_state == scl_ack_address)); -///////////////////////////////////////////////////////////////////////////////////////////// -//implementation of timer counter - -always@(posedge clk or posedge rst or posedge h_rst) -begin - if(rst || h_rst) - time_cnt<=8'b0000_0000; - else if(!scl_in) - time_cnt<=time_cnt + 1'b1; - else - time_cnt<=8'b0000_0000; -end - -always@(posedge clk or posedge rst or posedge h_rst) -begin - if(rst || h_rst) - begin - core_rst_sig<=1'b0; - time_out_sig<=1'b0; - end - else if((time_cnt == time_out_reg) & bb) - begin - core_rst_sig <= 1'b1; - time_out_sig <= 1'b1; - end - /*else if((time_cnt == time_out_reg) && (scl_state == scl_idle)) - begin - core_rst_sig <= 1'b0; - time_out_sig <= 1'b1; - end*/ - else - begin - core_rst_sig <= 1'b0; - time_out_sig <= 1'b0; - end -end - -//Process for assigning Master and slave SDA. -always@(posedge clk or posedge rst or posedge h_rst) -begin - if(rst || h_rst) - master_sda_sig<=1'b1; - else if((scl_main_state == scl_address_shift) || (scl_main_state == scl_tx_data)) - master_sda_sig<=serial_out; - else if(scl_main_state == scl_send_ack) - master_sda_sig<=ack; - else - master_sda_sig<=1'b1; -end - -always@(posedge clk or posedge rst or posedge h_rst) -begin - if(rst || h_rst) - slave_sda_sig<=1'b1; - else if(scl_main_state == scl_tx_data) - slave_sda_sig<=serial_out; - else if((addr_match && (scl_main_state == scl_ack_address)) || (scl_main_state == scl_send_ack)) - slave_sda_sig<=ack; - else - slave_sda_sig<=1'b1; -end - -//assigning SCL and SDA lines in output conditions. - - -assign scl_oe = master_slave ? scl_out : 1'b1; -assign sda_sig = (((master_slave == 1'b1 && sda_out == 1'b0) || - (master_slave == 1'b0 && slave_sda == 1'b0) || stop_scl) ? 1'b1 : 1'b0); -assign sda_oe = (sda_sig ?1'b0 : 1'b1); - -//Presenting data on data_register which is for processor -always@(posedge clk or posedge rst or posedge h_rst) -begin - if(rst || h_rst) - i2c_up<=8'b00000000; - else if(scl_main_state == scl_send_ack) - i2c_up<=shift_reg; - else - i2c_up<=i2c_up; -end - - - -//This process will set arbitration lost signal -////////////////////////////////////////////// - // This process checks the master's outgoing SDA with the incoming SDA to determine - // if control of the bus has been lost. SDA is checked only when SCL is high - // and during the states IDLE, ADD_SHIFT, and TX_DATA to insure that START and STOP - // conditions are not set when the bus is busy. Note that this is only done when Master. - always @( posedge (clk) or posedge (rst) or posedge (h_rst) ) - begin - if (rst || h_rst) - begin - arbitration_lost_sig <= 1'b0; - end - else - begin - if (scl_main_state == scl_idle) - begin - arbitration_lost_sig <= 1'b0; - end - else if ((master_slave)) - // only need to check arbitration in master mode - // check for SCL high before comparing data - if ((scl_in && scl_oe && (scl_main_state == scl_address_shift || scl_main_state - == scl_tx_data || scl_main_state == scl_idle))) - // when master, will check bus in all states except ACK_ADDR and WAIT_ACK - // this will insure that arb_lost is set if a start or stop condition - // is set at the wrong time - //if(sda_in == 1'b0 && sda_oe == 1'b1) || (detect_stop - - if (sda_in == 1'b0 && sda_oe == 1'b1) - begin - arbitration_lost_sig <= 1'b1; - - end - else - begin - arbitration_lost_sig <= 1'b0; - - end - - else - begin - arbitration_lost_sig <= arbitration_lost; - end - - - end - - end - -//setting the arbitration lost bit of status register -//////////////////////////////////////////////////// -//this bit will be set when: - //arbiration has lost. - //core is in master mode and a generate strat condition has detected while bus is busy - //or a stop conditioin has been detected when not requested - //or a repeate start has been detected when in slave mode. - -always@(posedge clk or posedge rst or posedge core_rst or posedge h_rst) -begin - if(rst || h_rst) - arb_lost_sig<=1'b0; - else - begin - if(arb_rst) - arb_lost_sig<=1'b0; - else if(master_slave) - begin - if((arbitration_lost)||(bus_busy && gen_start)) - arb_lost_sig<=1'b1; - end - - else if(rep_start) - arb_lost_sig<=1'b1; - //else if(core_rst && master_slave) - //arb_lost_sig<=1'b0; - else - arb_lost_sig<=1'b0; - end -end - -always@(posedge clk or posedge rst or posedge h_rst) -begin -if(rst || h_rst) - rep_start_sig<=1'b0; -else if(scl_main_state == scl_address_shift || scl_main_state == scl_ack_address || scl_main_state == scl_send_ack || scl_main_state == scl_wait_ack) - rep_start_sig<=1'b0; -else - rep_start_sig<=rep_start; -end - - - -endmodule - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Index: tags/t1/i2c_master_slave_core/verilog/rtl/shift.v =================================================================== --- tags/t1/i2c_master_slave_core/verilog/rtl/shift.v (revision 3) +++ tags/t1/i2c_master_slave_core/verilog/rtl/shift.v (nonexistent) @@ -1,52 +0,0 @@ -////////////////////////////Shift.v///////////////////////////////////////////////////////////////////// -// // -//Design Engineer: Ravi Gupta // -//Company Name : Toomuch Semiconductor -//Email : ravi1.gupta@toomuchsemi.com // -// // -//Purpose : Used for shifting address and data in both transmit and recieve mode // -//created : 22-11-07 // -// // -//////////////////////////////////////////////////////////////////////////////////////////////////////// - -/*// synopsys translate_off -`include "oc8051_timescale.v" -// synopsys translate_on - -`include "oc8051_defines.v"*/ - - -module shift(clk,asyn_rst,load,shift_en,serial_in,data_in,serial_out,data_out); - -input clk,asyn_rst,load,shift_en,serial_in; -input [7:0]data_in; - -output serial_out; -output [7:0]data_out; - -reg [7:0]data; - -always@(posedge clk or posedge asyn_rst or posedge load) -begin - if(asyn_rst) - data<=8'h0; //clear the data register upon asynchronous reset. - - else if(load) - data<=data_in; //Load the internal register upon insertion of load bit. - - else if(shift_en) - data<={data[6:0],serial_in}; //Upon shift_en high every time a new serial data is coming to LSB bit and data will be shifted - //to one bit. - else - data<=data; //Prevent formation of latches -end - - -assign data_out = data; //Output the data in a data_register -assign serial_out = data[7]; //MSB is transmitted first in I2C protocol. - - -endmodule - -//change loading into asynchronous mode -

powered by: WebSVN 2.1.0

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