Implementation of Verilog Code for Reading and Writing Registers of LocalBUS Bus (2)-Writing of Testbench for Inout Bidirectional Bus
Testbench considerations
In this example, the difficulty of testbench lies in how to simulate the two-way signal. By searching for information, I found the following method to realize the simulation of inout-type signals.
reg [7:0]BMD$inout$reg;
wire [7:0]BMD = BMD$inout$reg;
Teshbench source code
When writing the bus, pass
BMD$inout$reg = 8'ha5;
to assign value.
When reading the bus, you only need to assign a value to the address.
`timescale 1ns/1ns
`define clock_period 20
module regs_tb;
reg clk;
reg rst_n;
reg [7:0]BMA;
reg nBOE;
reg nBWE;
reg nBCS1;
reg [7:0]BMD$inout$reg = 8'b0000_0000;
wire [7:0]BMD = BMD$inout$reg;
wire HDDog_close; //8'h60, F500_180 ADDR[9:2] write 5a
// wire SFTDog_close; //8'h71, F500_01C4 read close soft dog
// wire SFTDog_open; //8'h71, F500_01C4 write a5 open soft dog
wire SFTDog_en;
wire SFTDog_clr; //8'h72, F500_01C8 write aa
wire SFTDog_close_view; //8'h71, F500_01C4 read close soft dog
wire SFTDog_open_view; //8'h71, F500_01C4 write a5 open soft dog
assign SFTDog_close_view = regs0.SFTDog_close;
assign SFTDog_open_view = regs0.SFTDog_open;
regs regs0(
.Clk(clk),
.Rst_n(rst_n),
.BMA(BMA),
.BMD(BMD),
.nBOE(nBOE),
.nBWE(nBWE),
.nBCS1(nBCS1),
.HDDog_close(HDDog_close),
.SFTDog_en(SFTDog_en),
.SFTDog_clr(SFTDog_clr)
);
initial clk = 1;
always #(`clock_period/2) clk = ~clk;
initial begin
rst_n = 1'b0;
#(`clock_period *100);
rst_n = 1'b1;
#(`clock_period *100);
nBCS1 = 1;
nBOE = 1;
nBWE = 1;
BMA = 8'hff;
BMD$inout$reg = 8'hzz;
#(`clock_period *100);
//read
BMA = 8'h61;
nBCS1 = 0;
#(`clock_period *2);
nBOE = 0;
nBWE = 1;
#(`clock_period *3);
nBOE = 1;
nBWE = 1;
#(`clock_period *2);
nBCS1 = 1;
BMA = 8'hff;
#(`clock_period *10);
//write
BMA = 8'h61;
BMD$inout$reg = 8'ha5;
nBCS1 = 0;
#(`clock_period *2);
nBOE = 1;
nBWE = 0;
#(`clock_period *3);
nBOE = 1;
nBWE = 1;
#(`clock_period *2);
nBCS1 = 1;
BMA = 8'hff;
BMD$inout$reg = 8'hzz;
#(`clock_period *10);
//read
BMA = 8'h61;
nBCS1 = 0;
#(`clock_period *2);
nBOE = 0;
nBWE = 1;
#(`clock_period *3);
nBOE = 1;
nBWE = 1;
#(`clock_period *2);
nBCS1 = 1;
BMA = 8'hff;
#(`clock_period *10);
//write HDDog_close
BMA = 8'h60;
BMD$inout$reg = 8'h5a;
nBCS1 = 0;
#(`clock_period *2);
nBOE = 1;
nBWE = 0;
#(`clock_period *3);
nBOE = 1;
nBWE = 1;
#(`clock_period *2);
nBCS1 = 1;
BMA = 8'hff;
BMD$inout$reg = 8'hzz;
#(`clock_period *10);
//read SFTDog_close
BMA = 8'h71;
nBCS1 = 0;
#(`clock_period *2);
nBOE = 0;
nBWE = 1;
#(`clock_period *3);
nBOE = 1;
nBWE = 1;
#(`clock_period *2);
nBCS1 = 1;
BMA = 8'hff;
#(`clock_period *10);
//write SFTDog_open
BMA = 8'h71;
BMD$inout$reg = 8'ha5;
nBCS1 = 0;
#(`clock_period *2);
nBOE = 1;
nBWE = 0;
#(`clock_period *3);
nBOE = 1;
nBWE = 1;
#(`clock_period *2);
nBCS1 = 1;
BMA = 8'hff;
BMD$inout$reg = 8'hzz;
#(`clock_period *30);
//read SFTDog_close
BMA = 8'h71;
nBCS1 = 0;
#(`clock_period *2);
nBOE = 0;
nBWE = 1;
#(`clock_period *3);
nBOE = 1;
nBWE = 1;
#(`clock_period *2);
nBCS1 = 1;
BMA = 8'hff;
#(`clock_period *30);
//write SFTDog_open
BMA = 8'h71;
BMD$inout$reg = 8'ha5;
nBCS1 = 0;
#(`clock_period *2);
nBOE = 1;
nBWE = 0;
#(`clock_period *3);
nBOE = 1;
nBWE = 1;
#(`clock_period *2);
nBCS1 = 1;
BMA = 8'hff;
BMD$inout$reg = 8'hzz;
#(`clock_period *30);
//write SFTDog_clr
BMA = 8'h72;
BMD$inout$reg = 8'haa;
nBCS1 = 0;
#(`clock_period *2);
nBOE = 1;
nBWE = 0;
#(`clock_period *3);
nBOE = 1;
nBWE = 1;
#(`clock_period *2);
nBCS1 = 1;
BMA = 8'hff;
BMD$inout$reg = 8'hzz;
#(`clock_period *10);
$stop;
end
endmodule
Simulation waveform
The default value of the register to be tested is 0x3c after power-on. Perform a write operation (write 0xa5), read the register again, and the return value is 0xa5. Successful operation.