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

📄 demo_24c01a.v

📁 24C01A的Verilog HDL仿真代码
💻 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 + -