状态机程序
状态机程序`timescale 1 ns/100 ps
module iic_st(rst_l,clock,scl_tick,iic_go,wrd_add,sda_pin,sda,scl,scl_cnt_en, iic_rdy, iic_act, iic_rdata, ack_err); //端口列表
input rst_l;//复位
input clock;//系统时钟
input scl_tick;//scl的时钟
input iic_go;//启动iic总线周期
input wrd_add;//iic器件地址
input sda_pin;//iic数据多用输入
output sda;//iic总线数据输出
output scl;//iic总线时钟输出
output scl_cnt_en;//总线计数使能端
output iic_rdy;//总线准备好
output iic_act;//总线周期响应
output iic_rdata;//总线上的数据
output ack_err;//响应错误
//寄存器型
reg sda;
reg scl;
reg scl_cnt_en;
reg iic_rdy;
reg iic_rdata;
regiic_state;
reg bit_cntr;
reg scl_en;
reg en_cntr;
reg cntr_done;
reg ack_err;
wire iic_act;
//参数
parameter idle = 4'b0000; // state 0
parameter en_clk = 4'b0001; // state 1
parameter start1 = 4'b1100; // state C
parameter dev_add1 = 4'b1000; // state 8
parameter ack1 = 4'b0100; // state 4
parameter w_add = 4'b1010; // state A
parameter ack2 = 4'b0101; // state 5
parameter wait1 = 4'b0011; // state 3
parameter dis_clk1 = 4'b1111; // state F
parameter start2 = 4'b1101; // state D
parameter dev_add2 = 4'b1001; // state 9
parameter ack3 = 4'b0110; // state 6
parameter data = 4'b1011; // state B
parameter ack4 = 4'b0111; // state 7
parameter stop1 = 4'b1110; // state E
//状态机
always @(posedge clock or negedge rst_l)
if (!rst_l)
iic_state <= #1 idle;
else case(iic_state)
idle : if (iic_go)
iic_state <= #1 en_clk;
en_clk : if (scl_tick)
iic_state <= #1 start1;
start1 : if (scl_tick)
iic_state <= #1 dev_add1;
dev_add1 : if (cntr_done && scl_tick)
iic_state <= #1 ack1;
ack1 : if (scl_tick && scl)
iic_state <= #1 w_add;
w_add : if (cntr_done && scl_tick)
iic_state <= #1 ack2;
ack2 : if (scl_tick && scl)
iic_state <= #1 dis_clk1;
dis_clk1 : if (scl_tick && scl)
iic_state <= #1 wait1;
wait1 : if (scl_tick)
iic_state <= #1 start2;
start2 : if (scl_tick)
iic_state <= #1 dev_add2;
dev_add2 : if (cntr_done && scl_tick)
iic_state <= #1 ack3;
ack3 : if (scl_tick && scl)
iic_state <= #1 data;
data : if (cntr_done && scl_tick)
iic_state <= #1 ack4;
ack4 : if (scl_tick && scl)
iic_state <= #1 stop1;
stop1 : if (scl_tick && scl)
iic_state <= #1 idle;
default :
iic_state <= #1 idle;
endcase
// 位计数器
always @(posedge clock or negedge rst_l)
if (!rst_l)
bit_cntr <= #1 3'b111;
else if (en_cntr && scl && scl_tick)
bit_cntr <= #1 bit_cntr - 1;
always @(posedge clock or negedge rst_l)
if (!rst_l)
cntr_done <= #1 1'b0;
else if (bit_cntr == 3'b0 && scl)
cntr_done <= #1 1'b1;
else
cntr_done <= #1 1'b0;
always @(posedge clock or negedge rst_l)
if (!rst_l)
en_cntr <= #1 1'b0;
else if ((iic_state == dev_add1) ||
(iic_state == w_add) ||
(iic_state == dev_add2) ||
(iic_state == data))
en_cntr <= #1 1'b1;
else if (cntr_done)
en_cntr <= #1 1'b0;
//-------------------------------------------------------------------
//产生 scl
// 使能时钟分频器
always @(posedge clock or negedge rst_l)
if (!rst_l)
scl_cnt_en <= #1 1'b0;
else if (iic_state == en_clk)
scl_cnt_en <= #1 1'b1;
else if (iic_state == idle)
scl_cnt_en <= #1 1'b0;
always @(posedge clock or negedge rst_l)
if (!rst_l)
scl_en <= #1 1'b0;
else if (iic_state == start1)
scl_en <= #1 1'b1;
else if (iic_state == dis_clk1 && scl_tick)
scl_en <= #1 1'b0;
else if (iic_state == start2)
scl_en <= #1 1'b1;
else if (iic_state == stop1 && scl)
scl_en <= #1 1'b0;
always @(posedge clock or negedge rst_l)
if (!rst_l)
scl <= #1 1'b1;
else if (scl_en && scl_tick)
scl <= #1 ~scl;
//产生sda
always @(posedge clock or negedge rst_l)
if (!rst_l)
sda <= #1 1'b1;
else if ((iic_state == start1) || // starts
(iic_state == start2) ||
(iic_state == stop1) ||
((iic_state == dev_add1) && // writeaddress
(bit_cntr != 3'b111) && // device bit 7
(bit_cntr != 3'b101)) || // device bit 5
((iic_state == dev_add2) && // read address
(bit_cntr != 3'b111) && // device bit 7
(bit_cntr != 3'b101) && // device bit 5
(bit_cntr != 3'b000))) // read bit
sda <= #1 1'b0;
else if((iic_state == w_add)) // word address
sda <= #1 wrd_add;
else
sda <= #1 1'b1;
always @(posedge clock or negedge rst_l)
if (!rst_l)
iic_rdata <= #1 8'b0;
else if ((iic_state == data) && scl)
iic_rdata <= #1 sda_pin;
else if (iic_go)
iic_rdata <= #1 8'b0;
always @(posedge clock or negedge rst_l)
if (!rst_l)
iic_rdy <= #1 1'b0;
else if ((iic_state == stop1) && scl)
iic_rdy <= #1 1'b1;
else if (iic_go)
iic_rdy <= #1 1'b0;
always @(posedge clock or negedge rst_l)
if (!rst_l)
ack_err <= #1 1'b0;
else if (((iic_state == ack1)||
(iic_state == ack2)||
(iic_state == ack3)) && scl && sda_pin)
ack_err <= #1 1'b1;
else if (iic_go)
ack_err <= #1 1'b0;
assign iic_act = ~(iic_state == idle);
endmodule
状态机
页:
[1]