📄 demo_24c01a.v
字号:
`timescale 1ns/100ps
module demo_24c01a(reset, scl, sda, dev_add) ; //Asynchronous design example for iic_slave
input reset, scl ;
input [2:0] dev_add ;
inout sda ;
reg start ; //When high, a start condition occurs
reg stt_rst ;
reg stop ; //When high, a stop condition occurs
reg sda_tmp ;
reg [1:0] iic_state, new_state;
reg [3:0] bit_count;
reg [7:0] comm_buff, addr_buff, data_buff ;
reg [7:0] content[0:127] ;
wire frame_end, new_sda ; //, sda_out;
wire stop_rst;
//wire [7:0] data_temp ;
reg dev_sel, rwb_reg, sda_ctl;
genvar i ;
parameter idle = 2'b00, //waiting for iic transaction
comd = 2'b01, //Receive command from IIC master
addr = 2'b11, //Receive address from IIC master
data = 2'b10; //Data transaction
always @ (posedge reset or negedge scl)
if (reset) stt_rst <= 'b0 ;
else stt_rst <= start ;
always @ (posedge reset or posedge stt_rst or negedge sda)
if (reset | stt_rst == 1'b1) start <= 'b0 ;
else start <= (scl !== 1'b0) ; //Indicating a start condition
assign stop_rst = (iic_state == idle);
always @ (posedge stop_rst or posedge sda)
if (stop_rst) stop <= 'b0 ;
else stop <= (scl !== 1'b0) ;
always @ (posedge reset or posedge stop or negedge scl)
if (reset | stop == 1'b1) #5 iic_state <= idle ;
else iic_state <= new_state ;
always @ (iic_state or start or frame_end or comm_buff)
case(iic_state)
idle : new_state = (start == 1'b1) ? comd : idle ;
comd : new_state = (frame_end != 1'b1) ? comd
:(data_buff[0] == 1'b0) ? addr : data;
addr : new_state = (frame_end != 1'b1) ? addr : data ;
default : new_state = (frame_end == 1'b1) ? idle : data ;
endcase
assign new_sda = (sda !== 1'b0) ;
always @ (posedge reset or negedge scl)
if (reset == 1'b1) data_buff <= 8'h00 ;
else data_buff <= {data_buff[6:0],new_sda} ;
always @ (posedge reset or negedge scl)
if (reset == 1'b1) bit_count <= 4'h0 ;
else if (start == 1'b1) bit_count <= 4'h0 ;
else if (bit_count == 4'h8) bit_count <= 4'h0 ;
else bit_count <= bit_count + 4'h1 ;
assign frame_end = bit_count[3] ;
always @ (posedge reset or negedge scl)
if (reset) comm_buff <= 8'h00 ;
else if (iic_state == comd)
comm_buff <= (frame_end == 1'b1) ? data_buff : comm_buff;
always @ (posedge reset or negedge scl)
if (reset) addr_buff <= 8'h00 ;
else if (iic_state == addr)
addr_buff <= (frame_end == 1'b1) ? data_buff : addr_buff;
always @ (posedge reset or negedge scl)
if (reset) dev_sel <= 'b0 ;
else if (iic_state == idle) dev_sel <= 'b0 ;
else if ((iic_state == data) && (frame_end)) dev_sel <= 'b0 ;
else if ((iic_state == comd) && (frame_end)) dev_sel <= (comm_buff[3:1] == dev_add) ;
generate
for (i=0; i<128; i=i+1)
begin: dat_wrt
always @ (posedge reset or negedge scl)
if (reset == 1'b1) content[i] <= 8'h00 ;
else if ((iic_state == data) && (frame_end == 1'b1) && (addr_buff[6:0] == i))
content[i] <= data_buff ;
end
endgenerate
//assign data_temp = content[addr_buff[6:0]] ;
always @ (iic_state or frame_end or addr_buff or bit_count or comm_buff or dev_add )//or sda_out)
casez ({iic_state,frame_end})
{data,1'b0} : sda_tmp = (comm_buff[0] == 1'b0)? 1'bz
: (comm_buff[3:1] != dev_add) ? 1'bz
//: (sda_out == 1'b1) ? 1'bz : 1'b0 ;
: (content[addr_buff[6:0]][7-bit_count[2:0]] == 1'b1) ? 1'bz : 1'b0 ;
{data,1'b1} : sda_tmp = (comm_buff[0] == 1'b1)? 1'bz
: (comm_buff[3:1] != dev_add) ? 1'bz : 1'b0 ;
3'b??0 : sda_tmp = 1'bz ;
default : sda_tmp = 1'b0 ;
endcase
//assign sda_out = data_temp[7-bit_count[2:0]] ;
assign #5 sda = sda_tmp ;
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -