在网上中看到了这么一段代码,大家看看,是不是好熟悉,verilog一秒钟变C语言了,外部时钟clock经过了分频,看样子好像效果还行,大伙讨论一下。
module I2C_Master (clock, reset, sdai, GO, I2C_DATA, scl, sdao, ACK, END, regvalue);
input clock; //FPGA clock, 50MHz
input reset; //Asynchronous reset
input sdai;
input GO;
input [23:0]I2C_DATA;
output scl;
output sdao;
output ACK;
output END;
output [7:0]regvalue;
reg scl;
reg END;
reg SDO;
reg ACK1;
reg ACK2;
reg ACK3;
reg [23:0]SD;
reg [7:0]counter;
reg [7:0]read_buf;
reg [7:0]regvalue;
assign ACK = ACK1 |ACK2 |ACK3;
assign sdao = SDO;
//--I2C COUNTER
always @(negedge reset or posedge clock)
begin
if (!reset)counter=8'b11111111;
else
begin
if (GO==0)
counter=0;
else
begin
if (counter < 8'b11111111) counter=counter+1'b1;
else counter =0;
end
end
end
//----
//read and write
always @ (negedge reset or posedge clock)
begin
if(!reset)
begin ACK1=0; ACK2=0; ACK3=0; END=0; SDO=0; scl=0; regvalue=0; read_buf=0; end
else
begin
if(I2C_DATA[16]==1) //read
begin
case(counter)
8'd0 : begin ACK1=0 ;ACK2=0 ;ACK3=0 ; END=0; SDO=1; scl=1; end
//8'd1 :
//start
8'd2 : begin SD=I2C_DATA; SDO=0; end
8'd3 : scl=0;
//SLAVE ADDR
8'd4 : SDO=SD[23]; //第1 bit
8'd5 : scl=1;
//8'd6 :
8'd7 : scl=0;
8'd8 : SDO=SD[22]; //第2 bit
8'd9 : scl=1;
//8'd10 :
8'd11 : scl=0;
8'd12 : SDO=SD[21]; //第3 bit
8'd13 : scl=1;
//8'd14 :
8'd15 : scl=0;
8'd16 : SDO=SD[20]; //第4 bit
8'd17 : scl=1;
//8'd18 :
8'd19 : scl=0;
8'd20 : SDO=SD[19]; //第5 bit
8'd21 : scl=1;
//8'd22 :
8'd23 : scl=0;
8'd24 : SDO=SD[18]; //第6 bit
8'd25 : scl=1;
//8'd26 :
8'd27 : scl=0;
8'd28 : SDO=SD[17]; //第7 bit
8'd29 : scl=1;
//8'd30 :
8'd31 : scl=0;
8'd32 : SDO=0; //第8 bit 0 在读之前先写存储单元地址
8'd33 : scl=1;
//8'd34 :
8'd35 : scl=0; //从器件响应ack 信号,输出置高阻关闭输出
8'd36 : SDO=1; //ack
8'd37 : begin scl=1; ACK1=sdai; end //主器件读取从器件响应
//8'd38 :
8'd39 : scl=0; //打开输出
8'd40 : SDO=SD[15]; //主器件写寄存器地址第 1 bit
8'd41 : scl=1;
//8'd42 :
8'd43 : scl=0; //寄存器地址第 2 bit
8'd44 : SDO=SD[14];
8'd45 : scl=1;
//8'd46 :
8'd47 : scl=0; //寄存器地址第 3 bit
8'd48 : SDO=SD[13];
8'd49 : scl=1;
//8'd50 :
8'd51 : scl=0; //寄存器地址第 4 bit
8'd52 : SDO=SD[12];
8'd53 : scl=1;
//8'd54 :
8'd55 : scl=0; //寄存器地址第 5 bit
8'd56 : SDO=SD[11];
8'd57 : scl=1;
//8'd58 :
8'd59 : scl=0; //寄存器地址第 6 bit
8'd60 : SDO=SD[10];
8'd61 : scl=1;
//8'd62 :
8'd63 : scl=0; //寄存器地址第 7 bit
8'd64 : SDO=SD[9];
8'd65 : scl=1;
//8'd66 :
8'd67 : scl=0; //寄存器地址第 8 bit
8'd68 : SDO=SD[8];
8'd69 : scl=1;
//8'd70 :
8'd71 : scl=0; //从器件响应ack 信号,关闭输出
8'd72 : SDO=1; //ack
8'd73 : begin scl=1; ACK2=sdai; end //主器件上升沿检测是否有响应,有则另外发送一个开始信号,继续发数据
//8'd74 :
8'd75 : scl=0;
8'd76 : SDO=1;
8'd77 : scl=1;
8'd78 : begin SD=I2C_DATA; SDO=0;end //Repeated Start signal
//8'd79 :
8'd80 : scl=0;
//SLAVE ADDR
8'd81 : SDO=SD[23]; //第1 bit
8'd82 : scl=1;
//8'd83 :
8'd84 : scl=0;
8'd85 : SDO=SD[22]; //第2 bit
8'd86 : scl=1;
//8'd87 :
8'd88 : scl=0;
8'd89 : SDO=SD[21]; //第3 bit
8'd90 : scl=1;
//8'd91 :
8'd92 : scl=0;
8'd93 : SDO=SD[20]; //第4 bit
8'd94 : scl=1;
//8'd95 :
8'd96 : scl=0;
8'd97 : SDO=SD[19]; //第5 bit
8'd98 : scl=1;
//8'd99 :
8'd100 : scl=0;
8'd101 : SDO=SD[18]; //第6 bit
8'd102 : scl=1;
//8'd103 :
8'd104 : scl=0;
8'd105 : SDO=SD[17]; //第7 bit
8'd106 : scl=1;
//8'd107 :
8'd108 : scl=0;
8'd109 : SDO=1; //第8 bit 1, 表示读
8'd110 : scl=1;
//8'111 :
8'd112 : scl=0; //从器件响应ack 信号,输出置高阻关闭输出
8'd113 : SDO=1; //ack
8'd114 : begin scl=1; ACK1=sdai; end //主器件上升沿检测是否有响应,有则读数据
//8'd115 :
8'd116 : scl=0;
//8'd117 :
8'd118 : begin scl=1; read_buf[7]=sdai; end //主器件读第 1 bit
//8'd119 :
8'd120 : scl=0;
//8'd121 :
8'd122 : begin scl=1; read_buf[6]=sdai; end //第 2 bit
//8'd123 :
8'd124 : scl=0;
//8'd125 :
8'd126 : begin scl=1; read_buf[5]=sdai; end //第 3 bit
//8'd127 :
8'd128 : scl=0;
//8'd129 :
8'd130 : begin scl=1; read_buf[4]=sdai; end //第 4 bit
//8'd131 :
8'd132 : scl=0;
//8'd133
8'd134 : begin scl=1; read_buf[3]=sdai; end //第 5 bit
//8'd135
8'd136 : scl=0;
//8'd137 :
8'd138 : begin scl=1; read_buf[2]=sdai; end //第 6 bit
//8'd139 :
8'd140 : scl=0;
//8'd141 :
8'd142 : begin scl=1; read_buf[1]=sdai; end //第 7 bit
//8'd143 :
8'd144 : scl=0;
//8'd145 :
8'd146 : begin scl=1; read_buf[0]=sdai; end //第 8 bit
//8'd147 :
//ack
8'd148 : scl=0; //从器件写入 1,进入高阻态,释放数据线, 等待主器件相应,打开输出
8'd149 : SDO=1; //主器件响应 noacknowledge信号结束读取
8'd150 : scl=1; //从器件上升沿检测是否有响应,若是noack就停止发送
//8'd151 :
//结束
8'd152 : scl=0; //关闭输出
8'd153 : SDO=0; //准备进入结束信号
8'd154 : scl=1;
8'd155 : begin SDO=1; END=1; regvalue=read_buf; end //产生结束信号
endcase
end
else //write
begin
case(counter)
8'd0 : begin ACK1=0 ;ACK2=0 ;ACK3=0 ; END=0; SDO=1; scl=1; end
//start
8'd1 : begin SD=I2C_DATA;SDO=0;end
8'd2 : scl=0;
//SLAVE ADDR
8'd3 : SDO=SD[23]; //第1 bit
8'd4 : scl=1;
//8'd5 :
8'd6 : scl=0;
8'd7 : SDO=SD[22]; //第2 bit
8'd8 : scl=1;
//8'd9 :
8'd10 : scl=0;
8'd11 : SDO=SD[21]; //第3 bit
8'd12 : scl=1;
//8'd13 :
8'd14 : scl=0;
8'd15 : SDO=SD[20]; //第4 bit
8'd16 : scl=1;
//8'd17 :
8'd18 : scl=0;
8'd19 : SDO=SD[19]; //第5 bit
8'd20 : scl=1;
//8'd21 :
8'd22 : scl=0;
8'd23 : SDO=SD[18]; //第6 bit
8'd24 : scl=1;
//8'd25 :
8'd26 : scl=0;
8'd27 : SDO=SD[17]; //第7 bit
8'd28 : scl=1;
//8'd29 :
8'd30 : scl=0;
8'd31 : SDO=0; //第8 bit 写0
8'd32 : scl=1;
//8'd33 :
8'd34 : scl=0; //从器件响应ack 信号,关闭输出
8'd35 : SDO=1; //ack
8'd36 : begin scl=1; ACK1= sdai; end //主器件读取从器件响应
//8'd37 :
8'd38 : scl=0; //寄存器地址第 1 bit,打开输出
8'd39 : SDO=SD[15];
8'd40 : scl=1;
//8'd41 :
8'd42 : scl=0; //寄存器地址第 2 bit
8'd43 : SDO=SD[14];
8'd44 : scl=1;
//8'd45 :
8'd46 : scl=0; //寄存器地址第 3 bit
8'd47 : SDO=SD[13];
8'd48 : scl=1;
//8'd49 :
8'd50 : scl=0; //寄存器地址第 4 bit
8'd51 : SDO=SD[12];
8'd52 : scl=1;
//8'd53 :
8'd54 : scl=0; //寄存器地址第 5 bit
8'd55 : SDO=SD[11];
8'd56 : scl=1;
//8'd57 :
8'd58 : scl=0; //寄存器地址第 6 bit
8'd59 : SDO=SD[10];
8'd60 : scl=1;
//8'd61 :
8'd62 : scl=0; //寄存器地址第 7 bit
8'd63 : SDO=SD[9];
8'd64 : scl=1;
//8'd65 :
8'd66 : scl=0; //寄存器地址第 8 bit
8'd67 : SDO=SD[8];
8'd68 : scl=1;
//8'd69 :
8'd70 : scl=0; //从器件响应ack 信号,关闭输出
8'd71 : SDO=1;
8'd72 : begin scl=1; ACK2=sdai; end //主器件上升沿检测是否有相应有继续发数据
//8'd73 :
8'd74 : scl=0; //从器件置高阻,释放数据线 ,打开输出
8'd75 : SDO=SD[7]; //写数据第 1 bit
8'd76 : scl=1; //主器件读第 9 bit
//8'd77 :
8'd78 : scl=0;
8'd79 : SDO=SD[6]; //写数据第 2 bit
8'd80 : scl=1;
//8'd81 :
//器件写第 11 bit
8'd82 : scl=0;
8'd83 : SDO=SD[5]; //写数据第 3 bit
8'd84 : scl=1;
//8'd85 :
//器件写第 12 bit
8'd86 : scl=0;
8'd87 : SDO=SD[4]; //写数据第 4 bit
8'd88 : scl=1;
//8'd89 :
//器件写第 13 bit
8'd90 : scl=0;
8'd91 : SDO=SD[3]; //写数据第 5 bit
8'd92 : scl=1;
//8'd93 :
//器件写第 14 bit
8'd94 : scl=0;
8'd95 : SDO=SD[2]; //写数据第 6 bit
8'd96 : scl=1;
//8'd101 :
//器件写第 15 bit
8'd97 : scl=0;
8'd98 : SDO=SD[1]; //写数据第 7 bit
8'd99 : scl=1;
//8'd100 :
//器件写第 16 bit
8'd101 : scl=0;
8'd102 : SDO=SD[0]; //写数据第 8 bit
8'd103 : scl=1;
//8'd104 :
8'd105 : scl=0; // 从器件响应,关闭输出
8'd106 : SDO=1;
8'd107 : begin scl=1; ACK3=sdai; end //主器件读取响应信号并判断
//8'd108 :
8'd109 : scl=0; //从器件释放数据线,置高阻
8'd110 : SDO=0; //准备进入结束
8'd111 : scl=1;
8'd112 : begin SDO=1; END=1; end //结束信号
endcase
end
end
end
endmodule