📄 iiic1.v
字号:
module IIIC(clk, reset, updata_en, data_rden, scl, sda,data, reg_readback, base_addr, updata_req, data_rdreq, sdaout, sda_oe_en,debug1, debug2, debug3, debug4 );input clk, reset, updata_en, data_rden, scl, sda;output[15:0] data; output[7:0] base_addr; input [15:0] reg_readback; output updata_req, data_rdreq, sdaout, sda_oe_en;output debug1, debug2, debug3, debug4 ;//-----------------scl_clr neg_scl_clr iic_start-------------- reg[7:0] data0, data1, base_addr; reg pos_scl, pos_sda, pos2_scl, pos2_sda;reg scl_clr,neg_scl_clr,iic_start;wire [15:0] data={data1,data0} ;always@(posedge clk or posedge reset) beginif (reset) beginpos_scl<=0; pos_sda<=0; pos2_scl<=0; pos2_sda<=0; scl_clr<=0; neg_scl_clr<=0; iic_start<=0; end else begin pos_scl<=scl; pos2_scl<=pos_scl; scl_clr<=~pos2_scl & pos_scl; neg_scl_clr<=pos2_scl & ~pos_scl; pos_sda<=sda; pos2_sda<=pos_sda; iic_start<=(pos_scl & pos2_scl) & (~pos_sda & pos2_sda);end end//---------------iic sme--------------parameter iic_idle = 16'b0000_0000_0000_0001; parameter iic_bs_addr = 16'b0000_0000_0000_0010; parameter iic_bs_addr1 = 16'b0000_0000_0000_0100; parameter iic_bs_addr2 = 16'b0000_0000_0000_1000; parameter iic_reg_addr = 16'b0000_0000_0001_0000; parameter iic_reg_addr1 = 16'b0000_0000_0010_0000; parameter iic_reg_addr2 = 16'b0000_0000_0100_0000; parameter iic_rd_addr = 16'b0000_0000_1000_0000; parameter iic_rd_addr1 = 16'b0000_0001_0000_0000; parameter iic_rd_addr2 = 16'b0000_0010_0000_0000; parameter iic_wr_dat = 16'b0000_0100_0000_0000; parameter iic_wr_dat1 = 16'b0000_1000_0000_0000; parameter iic_wr_dat2 = 16'b0001_0000_0000_0000; parameter iic_rd_dat = 16'b0010_0000_0000_0000; parameter iic_rd_dat1 = 16'b0100_0000_0000_0000; parameter iic_rd_dat2 = 16'b1000_0000_0000_0000; parameter data_width=3;reg[7:0] addr, buffer, rd_tmp;reg[3:0] bit_count;reg[15:0] iic_seq;reg[3:0] byte_count;reg byte_end, iic_wr_end, sda_oe, sdaout, idle_ok, rdreg_ack;reg data_rdreq, updata_req; wire debug1=(iic_seq==iic_rd_dat);wire debug2=(iic_seq==iic_rd_dat2); //sda_oe;//iic_seq[0];wire debug3=(iic_seq==iic_rd_dat1);wire debug4=(iic_seq==iic_idle);wire sda_oe_en;wave_move sda_oe_wavemove( .a(sda_oe), .b(sda_oe_en),.len(8'h0a), .clk(clk), .rst(reset));/*always @(posedge clk or posedge reset) beginif (reset) beginsda_oe_en<=0; sda_oe_pos<=0; sda_oe_pos2<=0; end else begin sda_oe_pos<=sda_oe; sda_oe_pos2<=sda_oe_pos; sda_oe_en<=sda_oe_pos2;end end */always@(posedge clk or posedge reset) beginif (reset) beginaddr<=8'h00; buffer<=8'h00; idle_ok<=0;bit_count<=4'h0; byte_count<=4'h0;iic_seq<=iic_idle; byte_end<=0; iic_wr_end<=0; sda_oe<=0; sdaout<=0; rdreg_ack<=0;updata_req<=0; data_rdreq<=0; rd_tmp<=0;base_addr<=0; data0<=0; data1<=0; end else begin byte_end<=(bit_count==4'h8); if (scl_clr) bit_count<=bit_count+4'h1; case(iic_seq)iic_idle: begin iic_wr_end<=0; sda_oe<=0; rdreg_ack<=0; byte_count<=4'h0; bit_count<=4'h0; idle_ok<=1; if (iic_start) iic_seq<=iic_bs_addr; else iic_seq<=iic_idle;end iic_bs_addr: begin if (scl_clr & (bit_count<8)) addr[7:0]<={addr[6:0],pos_sda}; casex ({idle_ok, byte_end, (addr==8'haa)}) {3'b0??} : iic_seq<=iic_idle; {3'b111} : iic_seq<=iic_bs_addr1; {3'b110} : iic_seq<=iic_idle; {3'b10?} : iic_seq<=iic_bs_addr; default : iic_seq<=iic_idle; endcase endiic_bs_addr1:begin if (~idle_ok) iic_seq<=iic_idle; else if (neg_scl_clr)begin sda_oe<=1; sdaout<=0; iic_seq<=iic_bs_addr2; end else iic_seq<=iic_bs_addr1;endiic_bs_addr2:begin if (~idle_ok) iic_seq<=iic_idle; else if (neg_scl_clr)begin iic_seq<=iic_reg_addr; sda_oe<=0; bit_count<=4'h0; end else iic_seq<=iic_bs_addr2; endiic_reg_addr:begin if (scl_clr & (bit_count<8) ) buffer[7:0]<={buffer[6:0],pos_sda}; if (~idle_ok) iic_seq<=iic_idle; else if (byte_end) iic_seq<=iic_reg_addr1; else iic_seq<=iic_reg_addr; endiic_reg_addr1:begin if (~idle_ok) iic_seq<=iic_idle; else if (neg_scl_clr)begin iic_seq<=iic_reg_addr2; sda_oe<=1; sdaout<=0; byte_count<=byte_count+4'h1; end else iic_seq<=iic_reg_addr1;endiic_reg_addr2:begin if (~idle_ok) iic_seq<=iic_idle; else if (neg_scl_clr)begin sda_oe<=0; bit_count<=4'h0; iic_seq<=iic_wr_dat; end else iic_seq<=iic_reg_addr2;endiic_wr_dat:begin if (scl_clr & (bit_count<8) ) buffer[7:0]<={buffer[6:0],pos_sda}; /* if (~idle_ok) iic_seq<=iic_idle; else if (iic_start) begin iic_seq<=iic_rd_addr; bit_count<=4'h0; rdreg_ack<=1; end else if (byte_end) iic_seq<=iic_wr_dat1; else iic_seq<=iic_wr_dat; */ casex ({idle_ok, iic_start, byte_end}) {3'b0??} : iic_seq<=iic_idle; {3'b11?} : begin iic_seq<=iic_rd_addr; bit_count<=4'h0; rdreg_ack<=1; end {3'b101} : iic_seq<=iic_wr_dat1; {3'b100} : iic_seq<=iic_wr_dat; default : iic_seq<=iic_idle; endcase endiic_wr_dat1:begin if (~idle_ok) iic_seq<=iic_idle; else if (neg_scl_clr)begin iic_seq<=iic_wr_dat2; sda_oe<=1; sdaout<=0; byte_count<=byte_count+4'h1; end else iic_seq<=iic_wr_dat1;endiic_wr_dat2:begin /* if (~idle_ok) iic_seq<=iic_idle; else if (neg_scl_clr)begin sda_oe<=0; bit_count<=4'h0; if (byte_count==data_width) begin iic_seq<=iic_idle; iic_wr_end<=1; end else iic_seq<=iic_wr_dat; end else iic_seq<=iic_wr_dat2; */ casex ({idle_ok, neg_scl_clr, (byte_count==data_width)}) {3'b0??} : iic_seq<=iic_idle; {3'b110} : begin sda_oe<=0; bit_count<=4'h0; iic_seq<=iic_wr_dat; end {3'b111} : begin sda_oe<=0; bit_count<=4'h0; iic_seq<=iic_idle; iic_wr_end<=1; end {3'b10?} : iic_seq<=iic_wr_dat2; default : iic_seq<=iic_idle; endcase endiic_rd_addr:begin rdreg_ack<=0; if (scl_clr & (bit_count<8)) addr[7:0]<={addr[6:0],pos_sda}; /* if (byte_end) begin if (addr==8'hab) iic_seq<=iic_rd_addr1; else iic_seq<=iic_idle; end else iic_seq<=iic_rd_addr; */ casex ({idle_ok, byte_end, (addr==8'hab)}) {3'b0??} : iic_seq<=iic_idle; {3'b111} : iic_seq<=iic_rd_addr1; {3'b110} : iic_seq<=iic_idle; {3'b10?} : iic_seq<=iic_rd_addr; default : iic_seq<=iic_idle; endcase endiic_rd_addr1:begin if (~idle_ok) iic_seq<=iic_idle; else if (neg_scl_clr)begin iic_seq<=iic_rd_addr2; sda_oe<=1; sdaout<=0; end else iic_seq<=iic_rd_addr1;endiic_rd_addr2:begin if (~idle_ok) iic_seq<=iic_idle; else if (neg_scl_clr)begin bit_count<=4'h0; iic_seq<=iic_rd_dat; sdaout<=rd_tmp[7]; rd_tmp[7:0]<={rd_tmp[6:0],1'b0};end else iic_seq<=iic_rd_addr2;endiic_rd_dat:begin if (neg_scl_clr & (bit_count<8) ) begin sdaout<=rd_tmp[7]; rd_tmp[7:0]<={rd_tmp[6:0],1'b0}; end if (~idle_ok) iic_seq<=iic_idle; else if (byte_end) iic_seq<=iic_rd_dat1; else iic_seq<=iic_rd_dat;endiic_rd_dat1:begin if (~idle_ok) iic_seq<=iic_idle; else if (neg_scl_clr)begin iic_seq<=iic_rd_dat2; sda_oe<=0; //att!!! must before the master get control byte_count<=byte_count+4'h1; end else iic_seq<=iic_rd_dat1;endiic_rd_dat2:begin/* if (~idle_ok) iic_seq<=iic_idle; else if (neg_scl_clr&)begin sda_oe<=1; bit_count<=4'h0; if (byte_count==data_width) iic_seq<=iic_idle; else iic_seq<=iic_rd_dat; end else iic_seq<=iic_rd_dat2; */ casex ({idle_ok, neg_scl_clr, (byte_count>2)}) //data_width {3'b0??} : iic_seq<=iic_idle; {3'b110} : begin sda_oe<=1; bit_count<=4'h0; sdaout<=rd_tmp[7]; rd_tmp[7:0]<={rd_tmp[6:0],1'b0}; iic_seq<=iic_rd_dat; end {3'b111} : begin sda_oe<=0; idle_ok<=0; bit_count<=4'h0; iic_seq<=iic_idle; end {3'b10?} : iic_seq<=iic_rd_dat2; default : iic_seq<=iic_idle; endcase enddefault : begin addr<=8'h00; buffer<=8'h00; bit_count<=4'h0; byte_count<=4'h0;iic_seq<=iic_idle; sda_oe<=0; sdaout<=0;iic_wr_end<=0; end endcase if (byte_end&scl_clr)begin case (byte_count)4'h1: begin base_addr<=buffer; rd_tmp[7:0]<=reg_readback[7:0]; end //4'h2: begin data0<=buffer; rd_tmp[7:0]<=reg_readback[15:8]; end //4'h3: data1<=buffer; endcaseend if (iic_wr_end) updata_req<=1; else if (updata_en) updata_req<=0; if (rdreg_ack) data_rdreq<=1; else if (data_rden) data_rdreq<=0;end end/*always @(posedge clk or posedge reset) beginif (reset) begin end else begin end end */endmodulemodule wave_move(clk, rst,a, b, len);input clk, rst, a;input [7:0] len;output b;reg a_pos, a_pos2, a_clr, neg_a_clr, a_counten, neg_a_counten, b;reg [7:0] a_count, neg_a_count;always @(posedge clk or posedge rst) beginif (rst) begin a_pos<=0; a_pos2<=0; a_clr<=0; neg_a_clr<=0; b<=0; a_counten<=0; a_count<=0; neg_a_counten<=0; neg_a_count<=0;end else begin a_pos<=a; a_pos2<=a_pos;a_clr<=~a_pos2&a_pos; neg_a_clr<=~a_pos&a_pos2;if (a_clr) a_counten<=1; else if (a_count==len) a_counten<=0; if (a_clr) a_count<=0;else if (a_counten) a_count<=a_count+8'h01;if (neg_a_clr) neg_a_counten<=1; else if (neg_a_count==len) neg_a_counten<=0; if (neg_a_clr) neg_a_count<=0;else if (neg_a_counten) neg_a_count<=neg_a_count+8'h01;if (a_count==len) b<=1;else if (neg_a_count==len) b<=0;end endendmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -