How can I use display or monitor in verilog to check a register

Viewed 455

I have 2 Modules. One is Register_File_Rf which is a file of 32 Registers I have created. I want to be able to see what every single register is storing.

Can I do this with $display or $monitor somehow? Where these should be? In actual code or in Testbench, and how do I get the value in testbench when the stored Data is neither input or output?

module Register(
input Clk,
input [31:0] Data,
input WE,
output reg[31:0] Dout
);
reg [31:0] stored;

// With every Positive Edge of the Clock
always @(posedge Clk)begin
    // If Write is Enabled we store the new Data
    if (WE)begin
        stored <= Data;
        Dout <= stored;
    end else
        Dout <= stored;
end

module Register_File_RF(
input [4:0] Adr1,
input [4:0] Adr2,
input [4:0] Awr,
output reg[31:0] Dout1,
output reg[31:0] Dout2,
input [31:0] Din,
input WrEn,
input Clk
);

integer j;
genvar i;
wire [31:0]Temp_Dout[31:0];
reg W_E [31:0];

// Writing only in the first time R0 Register with 0
initial begin
W_E[0] = 1;
end
// Creating the R0 Register
Register register (.Clk(Clk),.WE(W_E[0]),.Data(0),.Dout(Temp_Dout[0]));


// Creating 30 Registers
for(i = 1; i < 32; i = i + 1)begin:loop
    Register register (.Clk(Clk),.WE(W_E[i]),.Data(Din),.Dout(Temp_Dout[i]));
end:loop

// Assigning to Dout1 and Dout2 the Data from a spesific register
always @(Adr1, Adr2) begin
    Dout1 = Temp_Dout[Adr1];
    Dout2 = Temp_Dout[Adr2];
end

// Wrting Data to a specific register
always @(posedge Clk)begin
    //Reseting Write Enable of the register to 0
    for (j = 0; j < 32; j = j + 1)begin:loop2
            W_E[j] = 0;
    end:loop2
    
    if(WrEn)begin
        W_E[Awr] = WrEn;
    end
end
endmodule
1 Answers

Yes, you can do this with either $display or $monitor.

Typically, $monitor would be called inside an initial block since it should only be called at one time in your simulation. It automatically displays values whenever one of its argument signals changes value.

Unlike $monitor, $display only displays values when it is called; it must be called whenever you want to display a signal value. It can be called in an initial block, but it is often called in an always block.

Regarding when to use either one, it is up to you to decide what you require.

If you are not planning to synthesize your modules, you could place monitor/display inside your design module directly. However, if you plan to synthesize, it might be better to place them in the testbench.

You can use hierarchical scoping to view internal signals from the testbench module. For example, assume you named the instance of the Register_File_RF module in the testbench as dut:

Register_File_RF dut (
   // ports
);

always @(posedge Clk) begin
    $display($time, " dout='h%x", dut.register.Dout);
end

initial begin
    $monitor($time, " dout='h%x", dut.register.Dout);
end

$monitor will display a value every time Dout changes value, whereas $display will show the value at the posedge of the clock.

If your simulator supports SystemVerilog features, you can also use bind to magically add code to your design modules.

Related