这里简易的画一下IIC收发模块的结构
module i2c_rw_data
(
input wire sys_clk ,
input wire sys_rst_n ,
input wire i2c_clk ,
input wire write ,
input wire read ,
input wire i2c_end ,
input wire [7:0] rd_data ,
output reg wr_en ,
output reg rd_en ,
output reg i2c_start ,
output reg [15:0] byte_addr ,
output reg [7:0] wr_data ,
output wire [7:0] fifo_rd_data
);
/参数定义//
parameter DATA_NUM = 8'd3 ,//读/写操作读出或写入的数据个数
CNT_START_MAX = 15'd5000 ,//cnt_start 计数器计数最大值
CNT_WR_RD_MAX = 8'd200 ,//cnt_wr/cnt_rd 计数器计数最大值
CNT_WAIT_MAX = 28'd500_000 ;//cnt_wait 计数器计数最大值
/线网变量定义//
wire [7:0] w_data_num ;
/寄存器变量定义
reg r_write_valid ;
reg [7:0] r_cnt_wr ;
reg r_read_valid ;
reg [7:0] r_cnt_rd ;
reg [14:0] r_cnt_start ;
reg [7:0] r_wr_i2c_data_num ;
reg [7:0] r_rd_i2c_data_num ;
reg r_fifo_rd_vlid ;
reg [27:0] r_cnt_wait ;
reg r_fifo_rd_en ;
reg [7:0] r_rd_data_num ;
/程序//
//跨时钟处理的相关信号
always@(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)
r_write_valid <= 'd0;
else if(r_cnt_wr == (CNT_WR_RD_MAX - 'd1))
r_write_valid <= 'd0;
else if(write == 'd1)
r_write_valid <= 'd1;
else
r_write_valid <= r_write_valid;
end
always@(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)
r_cnt_wr <= 'd0;
else if(r_write_valid == 'd0)
r_cnt_wr <= 'd0;
else if(r_write_valid == 'd1)
r_cnt_wr <= r_cnt_wr + 'd1;
else
r_cnt_wr <= 'd0;
end
always@(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)
r_read_valid <= 'd0;
else if(r_cnt_rd == (CNT_WR_RD_MAX - 'd1))
r_read_valid <= 'd0;
else if(read == 'd1)
r_read_valid <= 'd1;
else
r_read_valid <= r_read_valid;
end
always@(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)
r_cnt_rd <= 'd0;
else if(r_read_valid == 'd0)
r_cnt_rd <= 'd0;
else if(r_read_valid == 'd1)
r_cnt_rd <= r_cnt_rd + 'd1;
else
r_cnt_rd <= 'd0;
end
//通过iic协议发送的相关信号
always@(posedge i2c_clk or negedge sys_rst_n)begin
if(!sys_rst_n)
wr_en <= 'd0;
else if((i2c_end == 'd1) && (r_wr_i2c_data_num == DATA_NUM -'d1) && (wr_en == 'd1))
wr_en <= 'd0;
else if(r_write_valid == 'd1)
wr_en <= 'd1;
else
wr_en <= wr_en;
end
always@(posedge i2c_clk or negedge sys_rst_n)begin
if(!sys_rst_n)
r_cnt_start <= 'd0;
else if((wr_en == 'd0) && (rd_en == 'd0))
r_cnt_start <= 'd0;
else if(r_cnt_start == (CNT_START_MAX - 'd1))
r_cnt_start <= 'd0;
else if((wr_en == 'd1) || (rd_en == 'd1))
r_cnt_start <= r_cnt_start + 'd1;
else
r_cnt_start <= 'd0;
end
always@(posedge i2c_clk or negedge sys_rst_n)begin
if(!sys_rst_n)
i2c_start <= 'd0;
else if(r_cnt_start == CNT_START_MAX - 'd1)
i2c_start <= 'd1;
else
i2c_start <= 'd0;
end
always@(posedge i2c_clk or negedge sys_rst_n)begin
if(!sys_rst_n)
byte_addr <= 'h005A;
else if(((i2c_end == 'd1) && (r_wr_i2c_data_num == DATA_NUM -'d1)) || ((i2c_end == 'd1) && (r_rd_i2c_data_num == DATA_NUM -'d1)))
byte_addr <= 'h005A;
else if((i2c_end == 'd1) && ((wr_en == 'd1) || (rd_en == 'd1)))
byte_addr <= byte_addr + 'd1;
else
byte_addr <= byte_addr;
end
always@(posedge i2c_clk or negedge sys_rst_n)begin
if(!sys_rst_n)
wr_data <= 'hAA;
else if((i2c_end == 'd1) && (r_wr_i2c_data_num == DATA_NUM -'d1))
wr_data <= 'hAA;
else if((i2c_end == 'd1) && (wr_en == 'd1))
wr_data <= wr_data +'d1;
else
wr_data <= wr_data;
end
always@(posedge i2c_clk or negedge sys_rst_n)begin
if(!sys_rst_n)
r_wr_i2c_data_num <= 'd0;
else if(wr_en == 'd0)
r_wr_i2c_data_num <= 'd0;
else if((i2c_end == 1) && (wr_en == 'd1))
r_wr_i2c_data_num <= r_wr_i2c_data_num + 'd1;
else
r_wr_i2c_data_num <= r_wr_i2c_data_num;
end
//通过iic协议读取的相关信号
always@(posedge i2c_clk or negedge sys_rst_n)begin
if(!sys_rst_n)
rd_en <= 'd0;
else if((i2c_end == 'd1) && (r_rd_i2c_data_num == (DATA_NUM -'d1)) && (rd_en == 'd1))
rd_en <= 'd0;
else if(r_read_valid == 'd1)
rd_en <= 'd1;
else
rd_en <= rd_en;
end
always@(posedge i2c_clk or negedge sys_rst_n)begin
if(!sys_rst_n)
r_rd_i2c_data_num <= 'd0;
else if(rd_en == 'd0)
r_rd_i2c_data_num <= 'd0;
else if((i2c_end == 1) && (rd_en == 'd1))
r_rd_i2c_data_num <= r_rd_i2c_data_num + 'd1;
else
r_rd_i2c_data_num <= r_rd_i2c_data_num;
end
always@(posedge i2c_clk or negedge sys_rst_n)begin
if(!sys_rst_n)
r_fifo_rd_vlid <= 'd0;
else if((r_cnt_wait == (CNT_WAIT_MAX - 'd1)) && (r_rd_data_num == DATA_NUM))
r_fifo_rd_vlid <= 'd0;
else if(w_data_num == DATA_NUM)
r_fifo_rd_vlid <= 'd1;
else
r_fifo_rd_vlid <= r_fifo_rd_vlid;
end
//与fifo有关的信号
always@(posedge i2c_clk or negedge sys_rst_n)begin
if(!sys_rst_n)
r_cnt_wait <= 'd0;
else if(r_fifo_rd_vlid == 'd0)
r_cnt_wait <= 'd0;
else if(r_cnt_wait == CNT_WAIT_MAX - 'd1)
r_cnt_wait <= 'd0;
else if(r_fifo_rd_vlid == 'd1)
r_cnt_wait <= r_cnt_wait + 'd1;
else
r_cnt_wait <= 'd0;
end
always@(posedge i2c_clk or negedge sys_rst_n)begin
if(!sys_rst_n)
r_fifo_rd_en <= 'd0;
else if((r_cnt_wait == (CNT_WAIT_MAX - 'd1)) && (r_rd_data_num < DATA_NUM))
r_fifo_rd_en <= 'd1;
else
r_fifo_rd_en <= 'd0;
end
always@(posedge i2c_clk or negedge sys_rst_n)begin
if(!sys_rst_n)
r_rd_data_num <= 'd0;
else if(r_fifo_rd_vlid == 'd0)
r_rd_data_num <= 'd0;
else if(r_fifo_rd_en == 'd1)
r_rd_data_num <= r_rd_data_num+'d1;
else
r_rd_data_num <= r_rd_data_num;
end
fifo_read fifo_read_inst (
.clock ( i2c_clk ) ,
.data ( rd_data ) ,
.rdreq ( r_fifo_rd_en ) ,
.wrreq ( i2c_end && rd_en ) ,
.q ( fifo_rd_data ) ,
.usedw ( w_data_num )
);
endmodule