⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spi_to_i2c.v

📁 SPI和I2C转换的verilogHDL程序
💻 V
字号:
/***************************************************************************************** SPI to I2C interface* January 2007.*****************************************************************************************//* Top module */module SPI_to_I2C (SPI_sclk, SPI_cs, SPI_miso, SPI_mosi, I2C_sda, I2C_scl );inout I2C_sda;                     // Bidirectional SDA lineinout I2C_scl;                     // Bidirectional SCL lineinput SPI_sclk;                    // SPI clock    input SPI_cs;                      // SPI chip selectinput SPI_mosi;                    // Master out slave inoutput SPI_miso;                   // Master in slave out wire cpld_clk_w, osc_w, oscena_w; assign oscena_w = 1;               // Enable internal oscillator wire [7:0] command_reg_w, status_reg_w, data_in_w, data_out_w;wire count_byte_w;internal_oss_altufm_osc_7p3 	ufmosc	(.osc(osc_w), .oscena(oscena_w));divider 	divide	(.osc(osc_w), .cpld_clk(cpld_clk_w)); SPI_slave spi (.miso(SPI_miso), .mosi(SPI_mosi), .cs(SPI_cs), .sclk(SPI_sclk), .command_reg(command_reg_w), .status_reg(status_reg_w), .data_in(data_in_w), .data_out(data_out_w), .count_byte1(count_byte_w));I2C_master i2c (.sda(I2C_sda), .scl(I2C_scl), .cpld_clk(cpld_clk_w), .command_reg(command_reg_w), .status_reg(status_reg_w), .count_byte(count_byte_w), .cs(SPI_cs), .data_in(data_in_w), .data_out(data_out_w));endmodule/*****************************************************************************************************************************************************************************************************************//* SPI_slave module*/module SPI_slave ( miso, mosi, cs, sclk , command_reg, data_in, status_reg, data_out, count_bit, count_byte, count, done, done1, count_byte1, count_1);input mosi, cs, sclk;input [7:0] status_reg, data_out;   // data to send via misooutput miso;output [7:0] command_reg, data_in;  // Data to recieve via mosioutput [2:0] count_bit;             // 7 to 0 counteroutput count_byte;                  // command/data select  output done, done1, count_byte1;    // done indicated end of word output [3:0] count; output [3:0] count_1;reg miso;reg [3:0] count;reg [3:0] count_1; /* SPI word length = count_byte * count_bit = 16 */wire [2:0] count_bit; assign count_bit[2] = ~count[2]; assign count_bit[1] = ~count[1];assign count_bit[0] = ~count[0]; wire [2:0] count_bit1;assign count_bit1[2] = ~count_1[2]; assign count_bit1[1] = ~count_1[1]; assign count_bit1[0] = ~count_1[0];wire count_byte = count[3];wire count_byte1 = count_1[3];reg done;reg done1;// When done is high, write over miso is not possible always @ (negedge count_byte or posedge cs)if (cs) begin    done <= 0;end else begin    done <= 1;end  // When done1 is high, read over mosi is not possiblealways @ (negedge sclk or posedge cs)if (cs) begin    done1 <= 0;end else if ((count_bit == 7) & count_byte1) begin    done1 <= 1;endreg [7:0] command_reg;reg [7:0] data_in;                       // data recieved via mosialways @ (posedge sclk or posedge cs) begin    if (cs) begin        count <= 0;    end else begin        count <= count + 4'h1;        count_1 <= count;    endend/* Reading the Mosi */always@ (negedge sclk)if (~done1)begin    if (~count_byte1)begin         command_reg[count_bit1] = mosi;    end else begin               data_in[count_bit1] = mosi;           endend/* Writing the Miso */always@ (posedge sclk) begin  if (~done) begin    if (count_byte) begin        miso = data_out[count_bit];    end else begin        miso = status_reg[count_bit];    end  endendendmodule/*****************************************************************************************************************************************************************************************************************//* I2C Master module */module I2C_master (sda, scl, cpld_clk, command_reg, command_word, status_reg, count_byte, cs, data_in, data_out, sda_out, sda_out1, scl_out, count, sda_is_ack, repeat_start, sda_out_en, start_stop, start, stop);inout sda;                               inout scl;input cpld_clk;input count_byte, cs;input [7:0] command_reg, data_in;output [7:0] status_reg, data_out, command_word;output sda_out, sda_out1, scl_out, sda_is_ack, repeat_start, sda_out_en, start_stop, start, stop;output [3:0] count;reg sda_out;                   // Bidirectional SDA linereg scl_out;                   // Bidirectional scl Linereg repeat_start_flag;                 reg [3:0] count;               // Down countreg sda_out1;                  // For start_stop signalsreg sda_out_en;                // SDA output is tristate for high and gnd for low;reg start_stop;                // Bus status reg start,stop,reset;          //Detecting start stop conditions on the busreg word_retain;               // retaining command word[5] for ack;reg [7:0] status_reg, data_out, command_word;wire sda, scl;                     wire sda_is_ack = count[3];wire repeat_start;  assign scl = scl_out;/* Controlling the I2C Bus scl line, i.e scl_out */always@(negedge cpld_clk)if (scl & ((command_word!=0 | count==0)|~start_stop)) begin    scl_out = 1'b0;end else begin    scl_out = 1'bz;   end /* Initializing the repeat start and stop conditions */always @ (posedge cpld_clk)if (repeat_start & scl)begin     sda_out1 <= 1'b0;    // repeat startend else if (scl & command_word[7] & ~start_stop) begin    sda_out1 <= 1'b0;   //  start sonditionend else if (command_word[4] & ~scl & (start_stop)) begin    sda_out1 <= 1'b0;end else if (command_word[4] & scl & (start_stop)) begin    sda_out1 <= 1'b1;end else if (~scl) begin    sda_out1 <= 1'b1;end else if (cs) begin    sda_out1 <= 1'b1;end/* Repeat start generation */always@ (posedge cpld_clk)     if (~command_word[7]) begin         repeat_start_flag <= 1;     end else if (scl) begin         repeat_start_flag <= 0;     endassign repeat_start = (command_word[7] & repeat_start_flag & start_stop); /* Detecting the start stop on the sda line */always @ (posedge sda or posedge reset)if (reset) begin    stop <= 0;end else if (scl) begin    stop <= 1;end//cont..always @ (negedge sda or posedge reset)if (reset) begin    start <= 0;end else if (scl) begin    start <= 1;end//cont..always @ (negedge scl) if (start_stop & start) begin     reset <= 1; end else if (start) begin     start_stop = 1;     reset <= 1; end else if (stop) begin     start_stop = 0;     reset <= 1;      end else begin     reset <= 0;       end/* Down counter */always @ (negedge scl) if (repeat_start) begin    count <= 4'hF;end else if (start) begin    count <= 4'h7;   end else if (start_stop) begin   if (sda_is_ack) begin       // count is restored to 7       count <= 4'h7;   end else begin       count <= count - 4'h1;  // count is decremented until zero.    endend else begin   count <= 4'hF;end/* Putting command reg into the command word */wire count_zero = ~(count[0] | count[1] | count[2] | count [3]); always @ ( posedge cs or posedge(count_zero))begin    if (count_zero) begin        command_word <= 0;    end else begin         command_word = command_reg;    end end/* Word retain for ack during read operation */ always@ (negedge scl)   if (command_word[5]) begin      word_retain <= 1;   end else begin      word_retain <=0;   end/* Reading the sda and sending data and ack to SPI side*/always @ (posedge scl)if (start_stop) begin   if (((command_word[5]) & count!= 15)|word_retain) begin       data_out[count] = sda;   end else if (count==15) begin       status_reg[0] = ~sda;   endend/* Sending out address and data on the bus. */always@(negedge scl)if (start_stop | start) begin    if ((command_word[7] | command_word[6]) & (count != 0) & (~repeat_start)) begin        if (count == 15 & ~data_in[7]) begin sda_out <= 0;        end else if (count == 7 & ~data_in[6])begin sda_out <= 0;        end else if (count == 6 & ~data_in[5])begin sda_out <= 0;        end else if (count == 5 & ~data_in[4])begin sda_out <= 0;        end else if (count == 4 & ~data_in[3])begin sda_out <= 0;        end else if (count == 3 & ~data_in[2])begin sda_out <= 0;        end else if (count == 2 & ~data_in[1])begin sda_out <= 0;        end else if (count == 1 & ~data_in[0])begin sda_out <= 0;            end else sda_out <= 1;    end else if (word_retain) begin          if (count==0) sda_out <= 0;          else sda_out <= 1;    end else begin        sda_out <= 1;    end    end else begin    sda_out = 1'b1;end/* Controlling the sda output enable */always @ (sda_out or sda_out1)begin    if (~sda_out1) begin         sda_out_en <= 1'b0;    end else if (sda_out) begin        sda_out_en = 1'bz;    end else begin        sda_out_en = 1'b0;    endendassign sda = sda_out_en;/* Not for synthesis, only for testbench */initial begin    start = 0;    stop = 0;    start_stop = 0;    sda_out_en = 1'bz;    scl_out = 1'bz;    endendmodule/*******************************************************************************************//* Internal Oscillator */module  internal_oss_altufm_osc_7p3	( 	osc,	oscena) /* synthesis synthesis_clearbox=1 */;	output   osc;	input   oscena;	wire  wire_maxii_ufm_block1_osc;	maxii_ufm   maxii_ufm_block1	( 	.arclk(1'b0),	.ardin(1'b0),	.arshft(1'b0),	.bgpbusy(),	.busy(),	.drclk(1'b0),	.drdout(),	.drshft(1'b0),	.osc(wire_maxii_ufm_block1_osc),	.oscena(oscena)	`ifdef FORMAL_VERIFICATION	`else	// synopsys translate_off	`endif	,	.drdin(1'b0),	.erase(1'b0),	.program(1'b0)	`ifdef FORMAL_VERIFICATION	`else	// synopsys translate_on	`endif	// synopsys translate_off	,	.ctrl_bgpbusy(),	.devclrn(),	.devpor(),	.sbdin(),	.sbdout()	// synopsys translate_on	);	defparam		maxii_ufm_block1.address_width = 9,		maxii_ufm_block1.osc_sim_setting = 180000,		maxii_ufm_block1.lpm_type = "maxii_ufm";	assign		osc = wire_maxii_ufm_block1_osc;endmodule/******************************************************************************************//* Clock Divider */module divider (osc, cpld_clk);input osc;output cpld_clk;reg [9:0] count;wire cpld_clk;assign cpld_clk = count[9];initial count <= 0; always @ (posedge(osc))begincount = count + 1;end endmodule /*********************************************END************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -