├── 08697415.pdf ├── README.md ├── i2cmaster.v ├── i2cslave.v ├── sipo.v ├── spi_fsm.v ├── spitoi2c.v └── spitoi2ct.v /08697415.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trivedidvijen/SPI-to-I2C-Protocol-Conversion-Using-Verilog/2c8ef94f427ee30f99c95ed51800525165bf2fbe/08697415.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SPI to I2C Protocol Conversion using Verilog 2 | 3 | ## Introduction 4 | 5 | This project was developed as part of Final Year Project for my B.Tech in Electronics and Telecommunications Engineering at [K. J. Somaiya College of Engineering, Mumbai](https://kjsce.somaiya.edu/en) during 2017 - 2018. This project was developed using [Xilinx ISE Design Suite 14.7](https://www.xilinx.com/support/download/index.html/content/xilinx/en/downloadNav/vivado-design-tools/archive-ise.html) and [ISim](https://www.xilinx.com/products/design-tools/isim.html) using [Verilog](https://en.wikipedia.org/wiki/Verilog). 6 | 7 | Project Guide: [Prof. Ruchira A Jadhav](https://kjsce.somaiya.edu/en/view-member/160154?type=faculty) 8 | 9 | Finally based on this project, a research paper was published in [IEEE](http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=8697415&isnumber=8697217) on 25 April, 2019. This paper was presented in [2018 Fourth International Conference on Computing Communication Control and Automation (ICCUBEA)](https://ieeexplore.ieee.org/xpl/conhome/8681925/proceeding). 10 | 11 | Co-Author: [Dvijen Trivedi](https://ieeexplore.ieee.org/author/37086820124), [Aniruddha Khade](https://ieeexplore.ieee.org/author/37086823074), [Kashish Jain](https://ieeexplore.ieee.org/author/37086515830), [Ruchira Jadhav](https://ieeexplore.ieee.org/author/37086456327) 12 | 13 | **_Note:_** For ready reference, a pdf copy of the publised IEEE paper as mentioned above is attached here in the repository as [08697415.pdf](./08697415.pdf) 14 | 15 | ## Abstract 16 | 17 | The purpose of this paper is to design and simulate a Protocol Conversion Unit (PCU) for seamless communication between the two widely accepted serial communication protocols SPI and I2C. Design given in this paper takes data from a sender device working on SPI protocol and sends it to a receiver device working on I2C protocol, which otherwise without such design would not be possible. SPI supports full duplex communication unlike I2C which is half duplex. Also SPI is faster than I2C. I2C on the other hand is just a two wire interface as unlike SPI it does not use a dedicated Slave Select line. Instead I2C relies on Address and Acknowledgement scheme to communicate with slave. Thus in areas where the controlling device needs to communicate with a lot of peripheral devices, it is essential for the controller to send commands and data to the concerned peripheral device quickly using high speed of SPI and at the same time save on dedicated pins for each peripheral device using a rather simple Two Wire Interface of I2C, a design capable of providing conversion between SPI and I2C formats becomes essential. In this paper support for just one peripheral device is given. The design in this paper can be upgraded to support large no of peripherals by providing a First In First Out (FIFO) Queue for storing commands and data along with corresponding addresses of peripheral devices in the Protocol Conversion Unit (PCU). 18 | 19 | ## Design and Test Code Files 20 | 21 | 5 Design files and 1 Test file, all coded in Verilog are provided here in the repository. 22 | 23 | ## References 24 | 25 | 1. Abhilash S.Warrier, Akshay S.Belvadi, Dhiraj R.Gawhane, Babu Ravi Teja K, FPGA Implementation Of SPI To I2C Bridge, International Journal of Engineering Research & Technology (IJERT), Vol. 2 Issue 11, November - 2013. 26 | 2. M. Morris Mano, Michael D. Ciletti, Digital Design:With an Introduction to verilog HDL, 5e, Pearson, 2013. -------------------------------------------------------------------------------- /i2cmaster.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | ////////////////////////////////////////////////////////////////////////////////// 3 | // Company: 4 | // Engineer: 5 | // 6 | // Create Date: 16:20:00 03/19/2018 7 | // Design Name: 8 | // Module Name: i2cmaster 9 | // Project Name: 10 | // Target Devices: 11 | // Tool versions: 12 | // Description: 13 | // 14 | // Dependencies: 15 | // 16 | // Revision: 17 | // Revision 0.01 - File Created 18 | // Additional Comments: 19 | // 20 | ////////////////////////////////////////////////////////////////////////////////// 21 | module i2cmaster( 22 | input wire clk, 23 | input wire reset, 24 | input [7:0] in, 25 | inout i2c_sda, 26 | output i2c_scl 27 | ); 28 | 29 | reg a; 30 | reg i2c_scl2; 31 | reg temp; 32 | reg direction; 33 | reg ack; 34 | reg [7:0]state; 35 | reg[6:0]addr; 36 | reg [7:0]data; 37 | reg[8:0]count; 38 | reg[8:0]countd; 39 | localparam STATE_IDLE=0; 40 | localparam STATE_START=1; 41 | localparam STATE_ADDR=2; 42 | localparam STATE_RW=3; 43 | localparam STATE_WACK=4; 44 | localparam STATE_DATA=5; 45 | localparam STATE_WACK2=6; 46 | localparam STATE_STOP=7; 47 | 48 | i2cslave i2cslave1(.i2c_sda(i2c_sda),.i2c_scl(i2c_scl)); 49 | //initial begin 50 | //data<=in; 51 | //end 52 | 53 | always@(*) 54 | begin 55 | data<=in; 56 | end 57 | 58 | assign i2c_sda = direction ? temp : 1'bZ ; 59 | assign i2c_scl=(reset || a)?1'b1:clk; 60 | 61 | 62 | always@(posedge clk) 63 | begin 64 | if (reset==1) 65 | begin 66 | direction<=1; 67 | state<=0; 68 | temp<=1; 69 | addr <=7'b0001000; 70 | count <= 8'd6; 71 | countd <= 8'd7; 72 | // data <= 8'b11101110; 73 | a<=1; 74 | end 75 | 76 | else begin 77 | case(state) 78 | 79 | STATE_IDLE: begin //idle state 80 | direction<=1; 81 | temp<=1; 82 | a<=1; 83 | state<=STATE_START; 84 | end 85 | 86 | STATE_START:begin //start state 87 | direction<=1; 88 | temp<=0; 89 | #5 a<=0; 90 | state<=STATE_ADDR; 91 | end 92 | 93 | STATE_ADDR:begin //address bits 94 | a<=0; 95 | temp<=addr[count]; 96 | if(count==0) state<=STATE_RW; 97 | else count<=count-8'd1; 98 | end 99 | 100 | 101 | STATE_RW:begin //read/write 102 | temp <= 0; 103 | state<= STATE_WACK; 104 | end 105 | 106 | 107 | STATE_WACK:begin //COMPLICATED STATE 108 | direction<=0; 109 | ack<=i2c_sda; 110 | if(ack == 0) 111 | begin 112 | a<=0; 113 | state<= STATE_DATA; 114 | end 115 | else if(ack == 1) 116 | begin 117 | a<=0; 118 | state<= STATE_ADDR; 119 | end 120 | else 121 | begin 122 | a<=1; 123 | end 124 | 125 | end 126 | 127 | 128 | 129 | STATE_DATA:begin //DATA 130 | direction<=1; 131 | temp<=data[countd]; 132 | if(countd==0) state<=STATE_WACK2; 133 | else countd<=countd-8'd1; 134 | end 135 | 136 | STATE_WACK2:begin 137 | state<= STATE_STOP; 138 | end 139 | 140 | 141 | 142 | STATE_STOP:begin 143 | direction<=1; 144 | a<=1; 145 | #5 temp<=1; 146 | end 147 | 148 | endcase 149 | 150 | end 151 | end 152 | endmodule 153 | -------------------------------------------------------------------------------- /i2cslave.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | ////////////////////////////////////////////////////////////////////////////////// 3 | // Company: 4 | // Engineer: 5 | // 6 | // Create Date: 16:21:17 03/19/2018 7 | // Design Name: 8 | // Module Name: i2cslave 9 | // Project Name: 10 | // Target Devices: 11 | // Tool versions: 12 | // Description: 13 | // 14 | // Dependencies: 15 | // 16 | // Revision: 17 | // Revision 0.01 - File Created 18 | // Additional Comments: 19 | // 20 | ////////////////////////////////////////////////////////////////////////////////// 21 | module i2cslave( 22 | inout i2c_sda, 23 | input i2c_scl 24 | ); 25 | 26 | 27 | reg temp; 28 | reg direction; 29 | reg rw; 30 | reg [7:0]state; 31 | reg[6:0]addr; 32 | reg[6:0]raddr; 33 | reg [7:0]rdata; 34 | reg [7:0]addrw; 35 | reg[7:0]counta; 36 | reg[7:0]countd; 37 | reg en; 38 | reg dis; 39 | 40 | 41 | localparam STATE_ADDR=1; 42 | localparam STATE_RW=3; 43 | localparam STATE_WACK=4; 44 | localparam STATE_DATA=5; 45 | localparam STATE_WACK2=6; 46 | localparam STATE_STOP=7; 47 | 48 | initial begin 49 | addr<=7'b0001000; 50 | direction<=1; 51 | state<=8'd1; 52 | counta<=8'd8; 53 | countd<=8'd7; 54 | end 55 | 56 | assign i2c_sda=direction?1'bz:temp; //direction 1 for input and 0 for output 57 | 58 | initial begin 59 | temp<=0; 60 | end 61 | 62 | 63 | always@(negedge i2c_sda) //start condition 64 | begin 65 | if(i2c_scl==1) 66 | begin 67 | en<=1; 68 | end 69 | else en<=0; 70 | end 71 | 72 | always@(posedge i2c_sda) //end condition 73 | begin 74 | if(i2c_scl==1) 75 | begin 76 | dis<=1; 77 | end 78 | else dis<=0; 79 | end 80 | 81 | always@(negedge i2c_scl) 82 | begin 83 | if(en==1) 84 | begin 85 | case(state) 86 | STATE_ADDR:begin //address bits 87 | direction<=1; 88 | raddr[countd]<=i2c_sda; 89 | if(countd==0) state<=STATE_RW; 90 | else countd<=countd-8'd1; 91 | end 92 | 93 | STATE_RW:begin //read/write 94 | rw <= i2c_sda; 95 | if(raddr == addr) temp<=0; 96 | else temp<=1; 97 | state<=STATE_WACK; 98 | end 99 | 100 | STATE_WACK:begin //acknowledgement 1 101 | direction<=0; 102 | if(temp == 0) 103 | begin 104 | direction<=1; 105 | // repeat(2) 106 | // begin 107 | // rdata[counta]<=i2c_sda; 108 | // counta<=counta-1'd1; 109 | // end 110 | state<=STATE_DATA; 111 | end 112 | else 113 | begin 114 | state<=STATE_ADDR; 115 | end 116 | end 117 | 118 | 119 | STATE_DATA:begin //DATA 120 | if(counta==0) 121 | begin 122 | direction<=1; 123 | rdata[counta]<=i2c_sda; 124 | state<=STATE_WACK2; 125 | end 126 | else 127 | rdata[counta]<=i2c_sda; 128 | counta<=counta-8'd1; 129 | end 130 | 131 | STATE_WACK2:begin //acknowledgement 2 132 | end 133 | 134 | endcase 135 | end 136 | end 137 | //assign out=rdata; 138 | endmodule 139 | 140 | 141 | 142 | 143 | -------------------------------------------------------------------------------- /sipo.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | ////////////////////////////////////////////////////////////////////////////////// 3 | // Company: 4 | // Engineer: 5 | // 6 | // Create Date: 16:19:41 03/19/2018 7 | // Design Name: 8 | // Module Name: sipo 9 | // Project Name: 10 | // Target Devices: 11 | // Tool versions: 12 | // Description: 13 | // 14 | // Dependencies: 15 | // 16 | // Revision: 17 | // Revision 0.01 - File Created 18 | // Additional Comments: 19 | // 20 | ////////////////////////////////////////////////////////////////////////////////// 21 | module sipo ( 22 | output reg [7:0] dout , 23 | input din , 24 | input clk , 25 | input ss, 26 | output reg siso 27 | //output reg ndone 28 | ); 29 | 30 | reg [7:0]s; 31 | initial begin 32 | s <= 8'b01111110; 33 | //ndone<=1; 34 | end 35 | 36 | always @ (posedge (clk)) 37 | begin 38 | if(ss==0) 39 | begin 40 | s[0] <= din; 41 | s[1] <= s[0]; 42 | s[2] <= s[1]; 43 | s[3] <= s[2]; 44 | s[4] <= s[3]; 45 | s[5] <= s[4]; 46 | s[6] <= s[5]; 47 | s[7] <= s[6]; 48 | siso <= s[7]; 49 | end 50 | else if(ss==1) 51 | begin 52 | dout = s; 53 | //ndone<=0; 54 | end 55 | else; 56 | end 57 | 58 | // always@(posedge ss) 59 | // begin 60 | // ndone<=0; 61 | // end 62 | 63 | endmodule 64 | 65 | -------------------------------------------------------------------------------- /spi_fsm.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | ////////////////////////////////////////////////////////////////////////////////// 3 | // Company: 4 | // Engineer: 5 | // 6 | // Create Date: 16:19:18 03/19/2018 7 | // Design Name: 8 | // Module Name: spi_fsm 9 | // Project Name: 10 | // Target Devices: 11 | // Tool versions: 12 | // Description: 13 | // 14 | // Dependencies: 15 | // 16 | // Revision: 17 | // Revision 0.01 - File Created 18 | // Additional Comments: 19 | // 20 | ////////////////////////////////////////////////////////////////////////////////// 21 | module spi_fsm( 22 | input wire clk, 23 | input wire reset, 24 | input [7:0]data, 25 | input wire start, 26 | output reg mosi, 27 | output reg ss, 28 | output reg done, 29 | input miso 30 | ); 31 | 32 | 33 | reg [2:0]state; 34 | reg [7:0]tdata; 35 | reg[7:0]rdata; 36 | localparam STATE_IDLE=0; 37 | localparam STATE_SEND=1; 38 | localparam STATE_FINISH=2; 39 | 40 | reg [7:0]count; 41 | reg[7:0]countr; 42 | 43 | initial begin 44 | ss<=1; 45 | //done<=0; 46 | done<=1; 47 | tdata <= data; 48 | count<=8'd7; 49 | countr<=8'd7; 50 | end 51 | 52 | always@(posedge clk) 53 | begin 54 | if (reset==1) 55 | begin 56 | state<=0; 57 | mosi<=0; 58 | end 59 | 60 | else begin 61 | case(state) 62 | STATE_IDLE: begin //idle state 63 | ss<=1; 64 | //done<=0; 65 | done<=1; 66 | tdata<=data; 67 | if(start==1) state<=STATE_SEND; 68 | else state<=STATE_IDLE; 69 | end 70 | 71 | STATE_SEND:begin //start state 72 | ss<=0; 73 | mosi<=tdata[count]; 74 | rdata[countr]<=miso; 75 | if((count==0) && (countr == 0)) 76 | begin 77 | state<=STATE_FINISH; 78 | end 79 | else 80 | begin 81 | count<=count-8'd1; 82 | countr<=countr-8'd1; 83 | end 84 | end 85 | 86 | 87 | 88 | STATE_FINISH:begin 89 | //done<=1; 90 | done<=0; 91 | ss<=1; 92 | mosi<=0; 93 | end 94 | 95 | endcase 96 | end 97 | end 98 | endmodule 99 | -------------------------------------------------------------------------------- /spitoi2c.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | ////////////////////////////////////////////////////////////////////////////////// 3 | // Company: 4 | // Engineer: 5 | // 6 | // Create Date: 16:18:58 03/19/2018 7 | // Design Name: 8 | // Module Name: spitoi2c 9 | // Project Name: 10 | // Target Devices: 11 | // Tool versions: 12 | // Description: 13 | // 14 | // Dependencies: 15 | // 16 | // Revision: 17 | // Revision 0.01 - File Created 18 | // Additional Comments: 19 | // 20 | ////////////////////////////////////////////////////////////////////////////////// 21 | module spitoi2c( 22 | input start, 23 | input [7:0]data, 24 | input clk, 25 | input reset, 26 | output i2c_sda, 27 | output i2c_scl 28 | ); 29 | 30 | //wire mosi; 31 | wire ss; 32 | wire din; 33 | wire done; 34 | wire siso; 35 | wire [7:0]in; 36 | wire i2cmreset; 37 | 38 | spi_fsm spi_fsm1( 39 | .clk(clk), 40 | .reset(reset), 41 | .data(data), 42 | .start(start), 43 | .mosi(din), 44 | .ss(ss), 45 | .done(i2cmreset), 46 | .miso(siso) 47 | ); 48 | 49 | sipo sipo1( 50 | .din(din), 51 | .clk(clk), 52 | .ss(ss), 53 | .dout(in), 54 | .siso(siso) 55 | //.ndone(i2cmreset) 56 | ); 57 | 58 | i2cmaster i2cmaster1( 59 | .clk(clk), 60 | .reset(i2cmreset), 61 | .in(in), 62 | .i2c_sda(i2c_sda), 63 | .i2c_scl(i2c_scl) 64 | ); 65 | 66 | //bridge bridge1( 67 | //.mosi(mosi), 68 | //.ss(ss), 69 | //.clk(clk), 70 | //.miso(siso), 71 | //.i2c_sda(i2c_sda), 72 | //.i2c_scl(i2c_scl) 73 | //); 74 | 75 | //i2cslave i2cslave1( 76 | //.i2c_sda(i2c_sda), 77 | //.i2c_scl(i2c_scl) 78 | //); 79 | 80 | endmodule 81 | 82 | -------------------------------------------------------------------------------- /spitoi2ct.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | 3 | //////////////////////////////////////////////////////////////////////////////// 4 | // Company: 5 | // Engineer: 6 | // 7 | // Create Date: 16:46:48 03/19/2018 8 | // Design Name: spitoi2c 9 | // Module Name: C:/Users/bat/Desktop/spi to i2c 2/spitoi2c/spitoi2ct.v 10 | // Project Name: spitoi2c 11 | // Target Device: 12 | // Tool versions: 13 | // Description: 14 | // 15 | // Verilog Test Fixture created by ISE for module: spitoi2c 16 | // 17 | // Dependencies: 18 | // 19 | // Revision: 20 | // Revision 0.01 - File Created 21 | // Additional Comments: 22 | // 23 | //////////////////////////////////////////////////////////////////////////////// 24 | 25 | module spitoi2ct; 26 | 27 | // Inputs 28 | reg start; 29 | reg [7:0] data; 30 | reg clk; 31 | reg reset; 32 | 33 | // Outputs 34 | wire i2c_sda; 35 | wire i2c_scl; 36 | 37 | // Instantiate the Unit Under Test (UUT) 38 | spitoi2c uut ( 39 | .start(start), 40 | .data(data), 41 | .clk(clk), 42 | .reset(reset), 43 | .i2c_sda(i2c_sda), 44 | .i2c_scl(i2c_scl) 45 | ); 46 | 47 | initial begin 48 | // Initialize Inputs 49 | start = 0; 50 | data = 8'b10101010; 51 | clk = 0; 52 | reset = 1; 53 | 54 | forever #10 clk=~clk; 55 | end 56 | 57 | // Add stimulus here 58 | initial begin 59 | #90 60 | data = 8'b10101010; 61 | reset=0; 62 | start=1; 63 | end 64 | 65 | endmodule 66 | 67 | --------------------------------------------------------------------------------