iic_init.v
来自「Genode FX is a composition of hardware a」· Verilog 代码 · 共 220 行
V
220 行
`timescale 1 ns / 100 psmodule iic_init( Clk, //I Reset_n, //I Pixel_clk_greater_than_65Mhz, //I SDA, //O SCL, //O Done //O ); input Clk;input Reset_n;input Pixel_clk_greater_than_65Mhz;output SDA;output SCL;output Done;parameter CLK_RATE_MHZ = 100, SCK_PERIOD_US = 30, TRANSITION_CYCLE = (CLK_RATE_MHZ * SCK_PERIOD_US) / 2, TRANSITION_CYCLE_MSB = 11; localparam IDLE = 3'd0, INIT = 3'd1, START = 3'd2, CLK_FALL = 3'd3, SETUP = 3'd4, CLK_RISE = 3'd5, WAIT = 3'd6, START_BIT = 1'b1, SLAVE_ADDR= 7'b1110110, ACK = 1'b1, WRITE = 1'b0, REG_ADDR0 = 8'h49, REG_ADDR1 = 8'h21, REG_ADDR2 = 8'h33, REG_ADDR3 = 8'h34, REG_ADDR4 = 8'h36, DATA0 = 8'hC0, DATA1 = 8'h09, DATA2a = 8'h06, DATA3a = 8'h26, DATA4a = 8'hA0, DATA2b = 8'h08, DATA3b = 8'h16, DATA4b = 8'h60, STOP_BIT=1'b0, SDA_BUFFER_MSB=27; reg SDA_out; reg SCL_out; reg [TRANSITION_CYCLE_MSB:0] cycle_count;reg [2:0] c_state;reg [2:0] n_state;reg Done; reg [2:0] write_count;reg [31:0] bit_count;reg [SDA_BUFFER_MSB:0] SDA_BUFFER;wire transition; always @ (posedge Clk) begin if (~Reset_n||c_state==IDLE ) begin SDA_out <= 1'b1; SCL_out <=1'b1; end else if (c_state==INIT && transition) begin SDA_out <=1'b0; end else if (c_state==SETUP) begin SDA_out <=SDA_BUFFER[SDA_BUFFER_MSB]; end else if (c_state==CLK_RISE && cycle_count==TRANSITION_CYCLE/2 && bit_count==SDA_BUFFER_MSB) begin SDA_out <= 1'b1; end else if (c_state==CLK_FALL) begin SCL_out <=1'b0; end else if (c_state==CLK_RISE) begin SCL_out <=1'b1; endend//OBUFT_LVCMOS33 sda0(.O(SDA), .I(1'b0), .T(SDA_out));//OBUFT_LVCMOS33 scl0(.O(SCL), .I(1'b0), .T(SCL_out));assign SDA = SDA_out;assign SCL = SCL_out; always @ (posedge Clk) begin //reset or end condition if(~Reset_n) begin SDA_BUFFER <= {SLAVE_ADDR,WRITE,ACK,REG_ADDR0,ACK,DATA0,ACK,STOP_BIT}; cycle_count<=0; end //setup sda for sck rise else if ( c_state==SETUP && cycle_count==TRANSITION_CYCLE)begin SDA_BUFFER <= {SDA_BUFFER[SDA_BUFFER_MSB-1:0],1'b0}; cycle_count<=0; end //reset count at end of state else if ( cycle_count==TRANSITION_CYCLE) cycle_count<=0; //reset sda_buffer else if (c_state==WAIT && Pixel_clk_greater_than_65Mhz )begin case(write_count) 0:SDA_BUFFER <= {SLAVE_ADDR,WRITE,ACK,REG_ADDR1,ACK,DATA1,ACK,STOP_BIT}; 1:SDA_BUFFER <= {SLAVE_ADDR,WRITE,ACK,REG_ADDR2,ACK,DATA2a,ACK,STOP_BIT}; 2:SDA_BUFFER <= {SLAVE_ADDR,WRITE,ACK,REG_ADDR3,ACK,DATA3a,ACK,STOP_BIT}; 3:SDA_BUFFER <= {SLAVE_ADDR,WRITE,ACK,REG_ADDR4,ACK,DATA4a,ACK,STOP_BIT}; default: SDA_BUFFER <=28'dx; endcase cycle_count<=cycle_count+1; end else if (c_state==WAIT && ~Pixel_clk_greater_than_65Mhz )begin case(write_count) 0:SDA_BUFFER <= {SLAVE_ADDR,WRITE,ACK,REG_ADDR1,ACK,DATA1,ACK,STOP_BIT}; 1:SDA_BUFFER <= {SLAVE_ADDR,WRITE,ACK,REG_ADDR2,ACK,DATA2b,ACK,STOP_BIT}; 2:SDA_BUFFER <= {SLAVE_ADDR,WRITE,ACK,REG_ADDR3,ACK,DATA3b,ACK,STOP_BIT}; 3:SDA_BUFFER <= {SLAVE_ADDR,WRITE,ACK,REG_ADDR4,ACK,DATA4b,ACK,STOP_BIT}; default: SDA_BUFFER <=28'dx; endcase cycle_count<=cycle_count+1; end else cycle_count<=cycle_count+1;endalways @ (posedge Clk) begin if(~Reset_n) write_count<=3'd0; else if (c_state==WAIT && cycle_count==TRANSITION_CYCLE) write_count<=write_count+1;end always @ (posedge Clk) begin if(~Reset_n) Done<=1'b0; else if (c_state==IDLE) Done<=1'b1;end always @ (posedge Clk) begin if(~Reset_n||(c_state==WAIT)) bit_count<=0; else if ( c_state==CLK_RISE && cycle_count==TRANSITION_CYCLE) bit_count<=bit_count+1;end always @ (posedge Clk) begin if(~Reset_n) c_state<=INIT; else c_state<=n_state;end assign transition = (cycle_count==TRANSITION_CYCLE); //Next state always @ (*) begin case(c_state) IDLE: begin if(~Reset_n) n_state = INIT; else n_state = IDLE; end INIT: begin if (transition) n_state = START; else n_state = INIT; end START: begin if(~Reset_n) n_state = INIT; else if( transition) n_state = CLK_FALL; else n_state = START; end CLK_FALL: begin if(~Reset_n) n_state = INIT; else if( transition) n_state = SETUP; else n_state = CLK_FALL; end SETUP: begin if(~Reset_n) n_state = INIT; else if( transition) n_state = CLK_RISE; else n_state = SETUP; end CLK_RISE: begin if(~Reset_n) n_state = INIT; else if( transition && bit_count==SDA_BUFFER_MSB) n_state = WAIT; else if (transition ) n_state = CLK_FALL; else n_state = CLK_RISE; end WAIT: begin if(~Reset_n|(transition && write_count!=3'd4)) n_state = INIT; else if (transition ) n_state = IDLE; else n_state = WAIT; end default: n_state = IDLE; endcaseendendmodule
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?