📄 tb.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 Addressparameter 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; initialbegin `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 //for debugbegin 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 $display("0");
while(mbb==1) // =1, bus busy begin uc_read_i2c(read_out,I2C_MBSR_ADDR); `mbsr=read_out; end $display("1"); uc_write_i2c(I2C_MBDR_ADDR,{EEPROM_Address,1'b0}); //write i2c header in MBDR; 1'b0 means master write data $display("2"); mtx=1; //necessary msta=1; //Set MSTA in MBCR to Generate START uc_write_i2c(I2C_MBCR_ADDR,`mbcr);
$display("3"); @(posedge mcf_wire);
$display("4"); 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); endendtasktask 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 stateendendtasktask 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 stateendendtaski2c 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)); PULLUP2 pullup_sda(sda);PULLUP2 pullup_scl(scl); endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -