IIC协议仿真
小结
相信大家读完上一篇博客对IIC协议与eeprom读写已经有了一定的了解,本篇博客将以黑金A7102开发板为例进行验证上结代码的准确性,这里注意之江将上篇文章的代码放在A7102中是不能用的,因为上篇文章的代码是以24LC64为例进行书写的,而A7102中的eeprom芯片是24LC04。这里为了简单起见不再给出修改后的代码,需要的同学可以进群自取。
modelsim仿真测试
从上图中我们可以看到我们编写的eeprom控制器modelsim仿真通过验证。
上板测试代码
为了上板验证的方便性,我们将添加如下代码:
top_test模块:
`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author : zhangningning
// Email : nnzhang1996@foxmail.com
// Website :
// Module Name : top_test.v
// Create Time : 2020-01-14 16:13:00
// Editor : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date By Version Change Description
// -----------------------------------------------------------------------
// XXXX zhangningning 1.0 Original
//
// *********************************************************************************
module top_test(
input sys_clk_p ,
input sys_clk_n ,
input rst_n ,
input key_wr ,
input key_rd ,
output wire iic_sck ,
inout iic_sda
);
//========================================================================================\
//**************Define Parameter and Internal Signals**********************************
//========================================================================================/
wire wr_req ;
wire rd_req ;
wire [ 7:0] addr ;
wire [ 7:0] wr_data ;
wire [ 7:0] rd_data ;
wire rd_valid ;
wire sclk ;
//========================================================================================\
//************** Main Code **********************************
//========================================================================================/
clk_wiz_0 clk_wiz_0_inst(
.clk_out1 (sclk ),
.resetn (rst_n ),
.clk_in1_p (sys_clk_p ),
.clk_in1_n (sys_clk_n )
);
key key_inst1(
.sclk (sclk ),
.rst_n (rst_n ),
.key (~key_wr ),
.key_o (wr_req )
);
key key_inst2(
.sclk (sclk ),
.rst_n (rst_n ),
.key (~key_rd ),
.key_o (rd_req )
);
top top_inst(
.sclk (sclk ),
.rst_n (rst_n ),
.wr_req (wr_req ),
.rd_req (rd_req ),
.addr (addr ),
.rd_data (rd_data ),
.rd_valid (rd_valid ),
.wr_data (wr_data ),
.busy ( ),
.iic_sck (iic_sck ),
.iic_sda (iic_sda )
);
//========================================================================================\
//******************************* Debug **********************************
//========================================================================================/
ila_0 ila_0_inst (
.clk (sclk ), // input wire clk
.probe0 (rd_data ), // input wire [7:0] probe0
.probe1 (rd_valid ) // input wire [0:0] probe1
);
vio_0 vio_0_inst (
.clk (sclk ), // input wire clk
.probe_out0 (addr ), // output wire [7 : 0] probe_out0
.probe_out1 (wr_data ) // output wire [7 : 0] probe_out1
);
endmodule
key模块:
`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author : zhangningning
// Email : nnzhang1996@foxmail.com
// Website :
// Module Name : key.v
// Create Time : 2020-01-05 13:49:36
// Editor : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date By Version Change Description
// -----------------------------------------------------------------------
// XXXX zhangningning 1.0 Original
//
// *********************************************************************************
module key(
input sclk ,
input rst_n ,
input key ,
output reg key_o
);
//========================================================================================\
//**************Define Parameter and Internal Signals**********************************
//========================================================================================/
parameter IDLE = 4'b0001 ;
parameter S1 = 4'b0010 ;
parameter S2 = 4'b0100 ;
parameter S3 = 4'b1000 ;
reg [ 3:0] state ;
reg [ 9:0] cnt ;
reg key_r1 ;
reg key_r2 ;
reg key_r3 ;
reg nege_flag ;
reg pose_flag ;
//========================================================================================\
//************** Main Code **********************************
//========================================================================================/
always @(posedge sclk)
key_r1 <= key;
always @(posedge sclk)
key_r2 <= key_r1;
always @(posedge sclk)
key_r3 <= key_r2;
always @(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
nege_flag <= 1'b0;
else if(key_r3 == 1'b1 && key_r2 == 1'b0)
nege_flag <= 1'b1;
else
nege_flag <= 1'b0;
always @(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
pose_flag <= 1'b0;
else if(key_r3 == 1'b0 && key_r2 == 1'b1)
pose_flag <= 1'b1;
else
pose_flag <= 1'b0;
always @(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
state <= IDLE;
else case(state)
IDLE : if(nege_flag == 1'b1)
state <= S1;
else
state <= IDLE;
S1 : if(cnt == 10'd999)
state <= S2;
else if(pose_flag == 1'b1)
state <= IDLE;
else
state <= S1;
S2 : if(pose_flag == 1'b1)
state <= S3;
else
state <= S2;
S3 : if(cnt == 10'd999)
state <= IDLE;
else if(nege_flag == 1'b1)
state <= S2;
else
state <= S3;
default : state <= IDLE;
endcase
always @(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
cnt <= 10'd0;
else if(state != S1 && state != S3)
cnt <= 10'd0;
else
cnt <= cnt + 1'b1;
always @(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
key_o <= 1'b0;
else if(state == S1 && cnt == 10'd999)
key_o <= 1'b1;
else
key_o <= 1'b0;
endmodule
从代码中可以看出我们使用了ila与vio在线调试工具,这在vivado中非常常见。
上班调试
我们首先通过按键与ila向地址8’h15写入aa,再向地址8‘h51写入55,最后读出数据通过ila显示在图形化界面中验证我们控制器的正确性。
从上面的图中可以验证我们eeprom控制器代码的正确性。
结束语
创作不易,认为文章有帮助的同学们可以收藏点赞支持。(工程也都在群中)对文章有什么看法或者需要更近一步交流的同学,可以加入下面的群:
来源:CSDN
作者:朽月
链接:https://blog.csdn.net/zhangningning1996/article/details/103992689