⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tb.v

📁 FPGA-CPLD_DesignTool(8-9-10)源代码
💻 V
字号:
`timescale 1ns/10ps
`define mbsr {mcf,maas,mbb,mal,reserved_mbsr,srw,mif,rxak}
`define mbcr {men,mien,msta,mtx,txak,rsta,reserved_mbcr}
module tb();
reg clk,reset;
wire sda,scl;

parameter EEPROM_Address = 7'b1010000;  // Device Address
parameter I2C_Address_base=16'h0000;
parameter I2C_MADR_ADDR={I2C_Address_base,8'b10001101};
parameter I2C_MBCR_ADDR={I2C_Address_base,8'b10010001};
parameter I2C_MBSR_ADDR={I2C_Address_base,8'b10010011};
parameter I2C_MBDR_ADDR={I2C_Address_base,8'b10010101};

//************ MBCR ***********
reg men;
reg mien;
reg msta;
reg mtx;
reg txak;
reg rsta;
reg[1:0] reserved_mbcr;
wire mcf_wire;
        
//*********** MBSR ************
reg mcf;
reg maas;
reg mbb;
reg mal;
reg reserved_mbsr;
reg srw;
reg mif;
reg rxak;

//********** MBDR ***********
reg[7:0] mbdr;

reg[23:0]  addr_bus;
reg[7:0]  data_bus;
trireg[7:0]   data_bus_tri;         
reg as;
reg ds;
reg r_w;
wire dtack;
wire irq;

reg[7:0] count;
reg[7:0] data_in_uc;
reg[7:0] read_out;

reg data_bus_drive;
assign  data_bus_tri=(data_bus_drive==1'b1)? data_bus:8'bz; 

initial
begin
        `mbcr=8'b0;
        `mbsr=8'b0;
        mbb=1'b1;   //set i2c busy 
        as=1;
        ds=1;
        r_w=1;
        addr_bus=0;
        data_bus=0;
        data_bus_drive=0;
        reset=0;
        #300 reset=1;
        current_write_eeprom;    
        #100000;
        current_read_eeprom;
        #100000 $finish;
end
                        

initial
begin
        clk=0;
        forever #250 clk=~clk;
end


//*************  read data from EEPROM ****************
task current_read_eeprom;
begin
        `mbcr=8'b0;  //mtx be cleared
        men=1'b1;
        txak=1'b0;  //ack
        mbb=1'b1;
        uc_write_i2c(I2C_MBCR_ADDR,`mbcr);  //enable I2C
        while(mbb==1)   // =1, bus busy
                begin             
                        uc_read_i2c(read_out,I2C_MBSR_ADDR);
                        `mbsr=read_out;
                end
        
        uc_write_i2c(I2C_MBDR_ADDR,{EEPROM_Address,1'b1}); //write i2c header in MBDR; 1'b1: master requests data

        msta=1'b1;//Set MSTA in MBCR to Generate START
        uc_write_i2c(I2C_MBCR_ADDR,`mbcr); 

        @(posedge mcf_wire);
        count=8'd255;  //number of data to read
        while(count!=0)
                begin
                        @(posedge mcf_wire)
                        uc_read_i2c(read_out,I2C_MBDR_ADDR);  //read data from MBDR
                        data_in_uc=read_out;
                        $display("data out: %d",read_out);
                        if (count==2) begin
                                txak=1'b1;//reset txak in MBCR to make master generate a zero ack
                                uc_write_i2c(I2C_MBCR_ADDR,`mbcr);
                        end                     
                        count=count-1;
                end

 
        @(posedge mcf_wire);              
        msta=1'b0;//reset MSTA in MBCR to Generate stop
        uc_write_i2c(I2C_MBCR_ADDR,`mbcr);
             
end          
endtask      
             
//*********** write data to EEPROM ****************
task current_write_eeprom;
begin        
        `mbcr=8'b0;
        men=1'b1;
        mbb=1'b1;
        txak=1'b0;  //ack
        uc_write_i2c(I2C_MBCR_ADDR,`mbcr);  //enable I2C
        while(mbb==1)   // =1, bus busy
                   begin             
                        uc_read_i2c(read_out,I2C_MBSR_ADDR);
                        `mbsr=read_out;
                   end
             
        uc_write_i2c(I2C_MBDR_ADDR,{EEPROM_Address,1'b0}); //write i2c header in MBDR; 1'b0 means master write data
             
        mtx=1;  //necessary
        msta=1; //Set MSTA in MBCR to Generate START
        uc_write_i2c(I2C_MBCR_ADDR,`mbcr); 
             
        @(posedge mcf_wire);
             
        for(count=255;count>=1;count=count-1)
                   begin
                        @(posedge mcf_wire)
                        uc_write_i2c(I2C_MBDR_ADDR,count);  //write data to MBDR
                        $display("tb: write data: %d",count);
                end

        @(posedge mcf_wire);
        msta=1'b0;//reset MSTA in MBCR to Generate stop
        uc_write_i2c(I2C_MBCR_ADDR,`mbcr); 
end
endtask




task uc_write_i2c;
input [23:0] addr;
input [7:0] data;
begin
        @(negedge clk)  
        r_w=1'b0;        
        addr_bus=addr;
        as=1'b0;
        data_bus=data;
        ds=1'b0;
        data_bus_drive=1;
        @(negedge dtack)
        as=1'b1;
        ds=1'b1;
        data_bus=8'hzz;
        r_w=1'b1;               //reset the r_w line
        data_bus_drive=0;
        #1000;                  //2clk, wait for uc_interface to transit to idle state
end
endtask


task uc_read_i2c;
output [7:0] data;
input [23:0] addr;
begin
        @(negedge clk)          //write i2c header in MBDR
        r_w=1'b1;
        addr_bus=addr;
        as=1'b0;
        ds=1'b0;                //wait for state transition from addr to data_trs
        data_bus_drive=1'b0;
        @(negedge dtack)
        as=1'b1;
        ds=1'b1;
        data=data_bus_tri;
        #1000 ;                 //2clk, wait for uc_interface to transite to idle state
end
endtask


i2c  my_i2c(
                //-- I2C bus signals
                .sda(sda),                      //: inout       std_logic;              
                .scl(scl),                      //: inout       std_logic;

                //-- uC interface signals
                .addr_bus(addr_bus),            //: in          std_logic_vector(23 downto 0);
                .data_bus(data_bus_tri),        //: inout       std_logic_vector(7 downto 0);
                .as(as) ,                       //: in          std_logic;      -- address strobe, active low
                .ds(ds),                        //: in          std_logic;      -- data strobe, active low
                .r_w(r_w),                      //: in          std_logic;      -- read/write
                .dtack(dtack),                  //: out         std_logic;      -- data transfer acknowledge
                .irq(irq),                      //: out         std_logic;      -- interrupt request
                
                .mcf(mcf_wire),                 //: inout               std_logic;  -- temporary output for testing 

                //-- clock and reset
                .clk(clk),                      //: in          std_logic;
                .reset(reset)                   //: in          std_logic
        );


AT24C02  eeprom(
  .sda(sda),
  .scl(scl),
  .wp(1'b0));
 
pullup pullup_sda(sda);
pullup pullup_scl(scl); 
 
endmodule

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -