module test05(sclk, ack, scl, sda, rst, data, STATE, NEXTSTATE);
input sclk, rst;
input[3:0] data;
output ack, scl;
inout sda;
output[7:0] STATE, NEXTSTATE;
reg scl, ack;
reg link_sda, sdabuf;
reg[3:0] databuf;
reg[7:0] state, nextstate;
assign sda = link_sda ? sdabuf : 1'bz;
assign STATE = state;
assign NEXTSTATE = nextstate;
parameter ready = 8'b0000_0000,
start = 8'b0000_0001,
bit1 = 8'b0000_0010,
bit2 = 8'b0000_0100,
bit3 = 8'b0000_1000,
bit4 = 8'b0001_0000,
bit5 = 8'b0010_0000,
stop = 8'b0100_0000,
IDLE = 8'b1000_0000;
always @(posedge sclk or negedge rst)
begin
if (!rst) // reset
scl <= 1'b1;
else
scl <= ~scl;
end
always @(posedge ack)
begin
databuf <= data;
end
always @(negedge sclk or negedge rst)
begin
if (!rst)
state <= ready;
else
state <= nextstate;
end
always @(state or scl or ack)
begin
nextstate = 8'bxxxx_xxxx;
case (state)
ready: if (!scl && !ack)
nextstate = start;
else
nextstate = ready;
start: if (scl && ack)
nextstate = bit1;
else
nextstate = start;
bit1: if (!scl)
nextstate = bit2;
else
nextstate = bit1;
bit2: if (!scl)
nextstate = bit3;
else
nextstate = bit2;
bit3: if (!scl)
nextstate = bit4;
else
nextstate = bit3;
bit4: if (!scl)
nextstate = bit5;
else
nextstate = bit4;
bit5: if (!scl)
nextstate = stop;
else
nextstate = bit5;
stop: if (scl)
nextstate = IDLE;
else
nextstate = stop;
IDLE: nextstate = ready;
default: nextstate = ready;
endcase
end
always @(negedge sclk or negedge rst)
begin
if (!rst)
begin
link_sda <= 0;
sdabuf <= 1'b1;
ack <= 1'b0;
end
else
case (nextstate)
start: begin
link_sda <= 1'b1;
ack <= 1'b1;
end
bit1: sdabuf <= 1'b0;
bit2: sdabuf <= databuf[3];
bit3: sdabuf <= databuf[2];
bit4: sdabuf <= databuf[1];
bit5: sdabuf <= databuf[0];
stop: begin
sdabuf <= 1'b0;
ack <= 1'b0;
end
IDLE: sdabuf <= 1'b1;
ready: link_sda <= 1'b0;
default: begin
link_sda <=1'b0;
sdabuf <= 1'b1;
end
endcase
end
endmodule |