📄 at24c02b.v
字号:
// AT24C02B.v`timescale 1ns / 100psmodule AT24C02B( scl, sda); parameter ROM_SIZE = 256; parameter DADDR = 7'b1010_000; parameter T_SU_STA = 600; parameter T_HD_STA = 600; parameter T_AA = 900; parameter T_DH = 50; parameter T_SU_DTA = 100; parameter T_HD_DTA = 0; parameter T_SU_STO = 600; parameter T_BUF = 1200; parameter T_WRO = 5000000; parameter S_IDLE = 0; parameter S_DADDR = 1; parameter S_WADDR = 2; parameter S_WRITE = 3; parameter S_READ = 4; input scl; inout sda; reg [2:0] opstate; //状态 reg [2:0] opstate_next; //下一状态 reg [3:0] cc; //计数 reg [7:0] cmd; //命令 reg [7:0] addr; //地址 reg [7:0] datain; //数据数据 reg [7:0] data [7 : 0]; reg is_start; reg is_stop;
wire [2:0] bit_id = 3'b111-cc[2:0]; initial begin opstate = S_IDLE; cc = 0; cmd = 0; addr = 0; datain = 0; is_start = 0; is_stop = 0; end reg scl_dly; //scl延时 always@(*) scl_dly = #(T_SU_STA) scl; reg sda_dly; always@(*) sda_dly = #(T_SU_DTA) sda; //检测START、STOP wire is_stop_clr = (opstate==S_IDLE); wire is_start_clr = (opstate==S_DADDR); always@(negedge sda or posedge is_start_clr) is_start <= is_start_clr ? 0 : scl_dly; always@(posedge sda or posedge is_stop_clr) is_stop<= is_stop_clr ? 0 : scl; //状态 always@(negedge scl) opstate <= opstate_next; always@(*) begin opstate_next = opstate; case(opstate) S_IDLE: opstate_next = is_start ? S_DADDR : S_IDLE; S_DADDR: //opstate_next = (cc>=8) ? S_WADDR : S_DADDR; opstate_next = (cc>=8) ? (cmd[0] ? S_READ : S_WADDR) : S_DADDR; S_WADDR: opstate_next = (cc>=8) ? (is_start ? S_DADDR : S_WRITE) : S_WADDR; S_WRITE: opstate_next = is_start ? S_DADDR : S_WRITE; S_READ: opstate_next = S_READ; endcase if(is_stop) opstate_next = S_IDLE; end //计数 always@(negedge scl) begin //if((opstate==S_IDLE) || ((opstate==S_WRITE)&&is_start)) if(opstate==S_IDLE) cc<=0; else cc<=(cc>=8)?0:cc+1; end //输入命令、地址、数据 always@(posedge scl) begin case(opstate) S_IDLE: cmd<=0; S_DADDR: if(cc<8) cmd[bit_id] <=sda_dly; S_WADDR: if(cc<8) addr[bit_id] <=sda_dly; S_WRITE: begin if(cc<8) datain[bit_id] <= sda_dly; else begin data[addr] <= datain; addr <= addr+1; end end S_READ: if(cc>=8) addr <= addr+1; endcase end //应答和输出数据 wire [7:0] data_o = data[addr];
wire [2:0] bito_id = 3'b111-cc[2:0]; reg sda_o; always@(negedge scl) begin case(opstate) S_IDLE: sda_o <= #(T_AA) 1'bz; S_DADDR: sda_o <= #(T_AA) (cc==7) ? 0 : (cmd[0] ? data_o[bit_id] : 1'bz); S_WADDR: sda_o <= #(T_AA) (cc==7) ? 0 : 1'bz; S_WRITE: sda_o <= #(T_AA) (cc==7) ? 0 : 1'bz; S_READ: sda_o <= #(T_AA) (cc==7) ? 1 : data_o[bit_id]; endcase end
assign sda = sda_o;endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -