/************************************************************************** * File Name: cpu_dio.v * Author: mengxj * Called by: ../../harness.v * Description: Bus Function Model: Interface of CPU for configure * Intel/Motorala two modes * Company: Huawei Technology Inc. * Copyright(c): 2000, Huawei Technology Inc., All rights reserved. * * 5/Dec/2000 -- Creation ***************************************************************************/ /************************************************************************** * Procedure interface: * * instance_name.write_reg( Addr,Din ) * * instance_name.read_reg( Addr,Dout ) * * instance_name.Intel_Moto_mode_select(Intel_Moto_select) ***************************************************************************/ module cfgbfm ( Clk, //reference Clk, input Rst , //0,reset,input INT_n , //0,interrupt requst,input Intel_Moto, //0,intel;BTS ,output Rd_Wr_CPU_n , //Intel_RD_n or Moto_RW_n,output Wr_Ds_CPU_n , //Intel_WR_n or Moto_DS_n,output CS_n , //0,select Addr , //output Data //inout ); parameter ADDRSIZE=16; parameter DATASIZE=32; parameter CYCLE=20; //50MHz atspeed/10M(100ns),func parameter CPU_DELAY=CYCLE/2; parameter t1= CYCLE/4 ; //Set Up Time for Address Valid to CS_n Active, min 0ns parameter t2= CYCLE/4 ; //Set Up Time for CS_n active to either RD_n,WR_n,or DS_n Active, min 0ns parameter t3= 6*CYCLE/2 ; //CPU_DELAY Time from either RD_n,WR_n,or DS_n Active to Data Vaild, max 15ns parameter t4= CYCLE/4 ; //Hold Time from either RD_n,WR_n,or DS_n inactive to CS_n inactive,min 0ns,max 15ns parameter t5= 3*CYCLE/4 ; //Hold Time from CS_n inactive to Data Bus 3-state, min 5ns, max 15ns parameter t6= 5*CYCLE/2 ; //Wait Time from either WR_n or DS_n active to Latch Data, min 50ns parameter t7= 3*CYCLE/2 ; //Data Set Up Time to either WR_n or DS_n inactive, min 30ns parameter t8= CYCLE/4 ; //Data Hold Time to either WR_n or DS_n inactive, min 5ns parameter t9= CYCLE/4 ; //Address Hold Time to either WR_n or DS_n inactive,min 5ns input Clk ; input Rst ; input INT_n ; output Intel_Moto; //BTS ; output Rd_Wr_CPU_n ; output Wr_Ds_CPU_n ; output CS_n ; output [ADDRSIZE-1:0] Addr ; inout [DATASIZE-1:0] Data ; wire Clk ; wire Rst ; wire INT_n ; reg Intel_Moto; wire Rd_Wr_CPU_n ; wire Wr_Ds_CPU_n ; reg CS_n ; reg [ADDRSIZE-1:0] Addr ; wire [DATASIZE-1:0] Data ; reg Intel_WR_n; reg Intel_RD_n; reg Moto_RW_n; reg Moto_DS_n; wire [DATASIZE-1:0] Din ; reg [DATASIZE-1:0] Dout ; reg Dout_en; integer I; initial begin CS_n=1'b1; Addr={ADDRSIZE{1'b0}}; Dout={DATASIZE{1'bZ}}; Intel_WR_n=1'b1; Intel_RD_n=1'b1; Moto_RW_n=1'b1; Moto_DS_n=1'b1; Intel_Moto=1'b0; //$monitor("Addr=%h,Data=%h,CS=%b,Rd_Wr=%b,Wr_Ds=%b",Addr,Data,CS_n,Rd_Wr_CPU_n,Wr_Ds_CPU_n); end assign Din=Data; assign Data=Dout_en?Dout:{DATASIZE{1'bZ}}; always @(Rst) begin if (Rst==0) begin CS_n=1'b1; Addr={ADDRSIZE{1'b0}}; Dout={DATASIZE{1'bZ}}; Intel_WR_n=1'b1; Intel_RD_n=1'b1; Moto_RW_n=1'b1; Moto_DS_n=1'b1; Intel_Moto=1'b0; Dout_en=1'b0; end end assign Wr_Ds_CPU_n=Intel_Moto?Moto_DS_n:Intel_WR_n; assign Rd_Wr_CPU_n=Intel_Moto?Moto_RW_n:Intel_RD_n; always @(Intel_Moto or CS_n or Moto_RW_n or Intel_RD_n) begin if(Intel_Moto==1) Dout_en=!(Moto_RW_n||CS_n); else Dout_en=!((!Intel_RD_n)||CS_n); end task Intel_Moto_mode_select; input Intel_Moto_select; //0,select Intel begin Intel_Moto=Intel_Moto_select; end endtask task read_reg ; input [ADDRSIZE-1:0] Addr_reg ; output [DATASIZE-1:0] Data_reg ; reg in_use; begin if( in_use === 1'b1 ) begin $display( " \nColision occur in cpu interface read_reg task call " ); $stop; end in_use = 1'b1; @Clk; #CPU_DELAY; Addr={ADDRSIZE{1'b0}}; Intel_WR_n=1'b1; Intel_RD_n=1'b1; Moto_RW_n=1'b1; Moto_DS_n=1'b1; CS_n=1'b1; Addr=Addr_reg ; #t1; CS_n=1'b0; #t2; Intel_RD_n=1'b0; Moto_DS_n=1'b0; #t3; //if ((^Din)===1'bX|(^Din)===1'bZ) if ((^Din)===1'bZ) begin $display("error! CPU_DELAY Time from either RD_n Active to Data Vaild is too long,D=%h",Din); end if ((^Din)===1'bX) begin $display("Warning! CPU_DELAY Time from either RD_n Active to Data Vaild is too long,D=%h",Din); end Data_reg=Din ; Addr={ADDRSIZE{1'b0}}; Intel_RD_n=1'b1; Moto_DS_n=1'b1; fork #t4 CS_n=1'b1; #t5 begin if (Din!=={DATASIZE{1'bZ}}) begin $display("error! Hold Time from CS_n inactive to Data Bus 3-state is too long"); $stop; end end join Intel_WR_n=1'b1; //X Moto_RW_n=1'b1; //X in_use = 1'b0; end endtask task write_reg ; input [ADDRSIZE-1:0] Addr_reg ; input [DATASIZE-1:0] Data_reg ; reg in_use; begin if( in_use === 1'b1 ) begin $display( " \nColision occur in cpu interface write_reg task call " ); $stop; end in_use = 1'b1; @Clk; #CPU_DELAY; Dout={DATASIZE{1'bZ}}; //X Addr={ADDRSIZE{1'b0}}; //X Intel_WR_n=1'b1; Intel_RD_n=1'b1; Moto_RW_n=1'b0; Moto_DS_n=1'b1; CS_n=1'b1; Addr=Addr_reg ; #t1; CS_n=1'b0; #t2; Intel_WR_n=1'b0; Moto_DS_n=1'b0; #(t6-t7); Dout=Data_reg ; #t7; Intel_WR_n=1'b1; Moto_DS_n=1'b1; fork #t4 CS_n=1'b1; #t8 Dout={DATASIZE{1'bZ}}; //X #t9 Addr={ADDRSIZE{1'b0}}; //X join Intel_RD_n=1'b1; //X Moto_RW_n=1'b1; //X in_use = 1'b0; end endtask endmodule