微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > FPGA,CPLD和ASIC > 菜鸟求助!modelsim仿真I2C过程出问题

菜鸟求助!modelsim仿真I2C过程出问题

时间:10-02 整理:3721RD 点击:
毕业设计要做一个I2C的时序仿真,用verilog语言编写的。因为我自己没这个基础做不来,求大神帮忙。这个是SCCB底层驱动程序:module I2C_Controller (
CLOCK,
I2C_SCLK,//I2C CLOCK

I2C_SDAT,//I2C DATA
I2C_DATA,//DATA:[SLAVE_ADDR,SUB_ADDR,DATA]
GO,      //GO transfor
END,     //END transfor
W_R,     //W_R
ACK,      //ACK
RESET,
//TEST
SD_COUNTER,
        count,
SDO
);
output [7:0] count;
        input  CLOCK;
input  [23:0]I2C_DATA;

input  GO;
input  RESET;

input  W_R;

inout  I2C_SDAT;

output I2C_SCLK;
output END;

output ACK;

//TEST
output [5:0] SD_COUNTER;
output SDO;
reg [7:0] count;
parameter tpd_RESET_to_count = 3;
parameter tpd_CLOCK_to_count   = 2;
function [7:0] increment;
input [7:0] val;
reg [3:0] i;
reg carry;
  begin
    increment = val;
    carry = 1'b1;
    /*
     Exit this loop when carry == zero, OR all bits processed
     */
    for (i = 4'b0; ((carry == 4'b1) && (i <= 7));  i = i+ 4'b1)
       begin
         increment = val ^ carry;
         carry = val & carry;
       end
  end      
endfunction
/*
always @ (posedge CLOCK or posedge RESET)
  if (RESET)
     count = #tpd_RESET_to_count 8'h00;
  else
     count <= #tpd_CLOCK_to_count increment(count);
*/

always @ (posedge CLOCK or posedge RESET)
  if (RESET)
     count = 8'h00;
  else
     count <= count + 8'h01;

reg SDO;
reg SCLK;
reg END;
reg [23:0]SD;
reg [5:0]SD_COUNTER;
wire I2C_SCLK=SCLK | ( ((SD_COUNTER >= 4) & (SD_COUNTER <=30))? ~CLOCK :0 );
wire I2C_SDAT=SDO?1'bz:0 ;
reg ACK1,ACK2,ACK3;
wire ACK=ACK1 | ACK2 |ACK3;
//--I2C COUNTER
always @(negedge RESET or posedge CLOCK ) begin
if (!RESET) SD_COUNTER=6'b111111;
else begin
if (GO==0)
SD_COUNTER=0;
else
if (SD_COUNTER < 6'b111111) SD_COUNTER=SD_COUNTER+1;
end
end
//----
always @(negedge RESET or  posedge CLOCK ) begin
if (!RESET) begin SCLK=1;SDO=1; ACK1=0;ACK2=0;ACK3=0; END=1; end
else
case (SD_COUNTER)
6'd0  : begin ACK1=0 ;ACK2=0 ;ACK3=0 ; END=0; SDO=1; SCLK=1;end
//start
6'd1  : begin SD=I2C_DATA;SDO=0;end
6'd2  : SCLK=0;
//SLAVE ADDR
6'd3  : SDO=SD[23];
6'd4  : SDO=SD[22];
6'd5  : SDO=SD[21];
6'd6  : SDO=SD[20];
6'd7  : SDO=SD[19];
6'd8  : SDO=SD[18];
6'd9  : SDO=SD[17];
6'd10 : SDO=SD[16];

6'd11 : SDO=1'b1;//ACK

//SUB ADDR
6'd12  : begin SDO=SD[15]; ACK1=I2C_SDAT; end
6'd13  : SDO=SD[14];
6'd14  : SDO=SD[13];
6'd15  : SDO=SD[12];
6'd16  : SDO=SD[11];
6'd17  : SDO=SD[10];
6'd18  : SDO=SD[9];
6'd19  : SDO=SD[8];
6'd20  : SDO=1'b1;//ACK

//DATA
6'd21  : begin SDO=SD[7]; ACK2=I2C_SDAT; end
6'd22  : SDO=SD[6];
6'd23  : SDO=SD[5];
6'd24  : SDO=SD[4];
6'd25  : SDO=SD[3];
6'd26  : SDO=SD[2];
6'd27  : SDO=SD[1];
6'd28  : SDO=SD[0];
6'd29  : SDO=1'b1;//ACK


//stop
    6'd30 : begin SDO=1'b0;
SCLK=1'b0; ACK3=I2C_SDAT; end
    6'd31 : SCLK=1'b1;
    6'd32 : begin SDO=1'b1; END=1; end
endcase
end
endmodule
这个是已经编写的部分激励程序
`timescale 1 ps/ 1 ps
module I2C_Controller_vlg_tst();
// constants                                          
// general purpose registers
reg eachvec;
// test vector input registers
reg CLOCK;
reg GO;
reg [23:0] I2C_DATA;
reg treg_I2C_SDAT;
reg RESET;
reg W_R;
// wires                                               
wire ACK;
wire END;
wire I2C_SCLK;
wire I2C_SDAT;
wire SDO;
wire [5:0]  SD_COUNTER;
wire [7:0]  count;


// assign statements (if any)                          
assign I2C_SDAT = treg_I2C_SDAT;
I2C_Controller i1 (
// port map - connection between master ports and signals/registers   
.ACK(ACK),
.CLOCK(CLOCK),
.\END (END),
.GO(GO),
.I2C_DATA(I2C_DATA),
.I2C_SCLK(I2C_SCLK),
.I2C_SDAT(I2C_SDAT),
.RESET(RESET),
.SDO(SDO),
.SD_COUNTER(SD_COUNTER),
.W_R(W_R),
.count(count)
);
initial  

begin
  CLOCK = 0;
forever #50 CLOCK = ~CLOCK;
end

initial
begin
    RESET=0;
    #50 RESET=1;
    #40 RESET = 0;
    #40 RESET = 1;
    GO=1;
         #500 GO=0;
    #400 GO = 1;
end
initial
    $monitor($stime,, RESET,, CLOCK,,, count,, SD_COUNTER);
endmodule       求助:要在源程序或者激励文件中怎样修改,才能使所有端口的波形都能正确仿真,尤其是I2C_DATA  跟I2C_SDAT。

同学,你要说明你又哪些不明白的,不能让大家看你这么长的代码啊,说出来你不明白的地方大家帮你解答。可以贴部分代码然后提出问题,大家给你解答。


不好意思,没注意到这个。非常抱歉。就是这个例子里面的I2C_DATA要怎样写 才能在仿真的波形里面会有输出,我自己做的时候,一直都是一条红线。还有inout型的  I2C_SDAT  要怎样在激励文件里面写可以使仿真的波形里面使这个信号有输出。(我是新手,表述不太准确,不好意思)

inout型在testbench里作为wire声明,如wire data;在定义一个输出数据如reg data_out,在定义一个输出使能信号,如reg data_oe;然后需要输出data到线上时data_oe拉高,要输出的数据准备好赋值到data_out,用一个语句描述双向动作,assign data = data_oe ? data_out : 1'bz;就行了


虽然还是不知道具体要怎么做,还是谢谢你


  我去尝试了一下,做不出来。如果小编有时间的话,能不能帮我看下,我贴出来的那个程序的那个inout要怎么写?非常感谢



   在定义几个变量的时候 ,是在源文件里面定义还是要在testbench里面定义?搞不懂,求解



    当然在源程序定义

opencores上面有代码,自己看一下就可以了。
data是inout的,可能在仿真环境中需要pullup。

testbench里也要这样写,只不过定义的时候要定义成wire。你的工程文件要定义为inout。

谢谢楼上各位

:):):):):):):):):):):):):):)

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top