1
\$\begingroup\$

I'm trying to access register values from the analyzer in the test bench. Is there a way to access them without calling the register file module? (I don't want to call the rf module because accessing it writes values in address3 and I don't want to change its value.)

  • The analyzer is part of the test bench that compares the result with the expected value, and returns PASS or FAIL. but I need to access the register value so that I can calculate the expected result.
module testBench ();

  reg [31:0] instructions [0:10];
  integer i; 
  reg clk;
  reg [31:0] current_instruction; // To hold the current instruction
  wire [31:0] result; // To capture the result from mp_top
   
  mp_top uut (clk, current_instruction, result);

  initial clk = 0; 
  always #5 clk = ~clk;
  
  initial begin
    instructions[0] = 32'b000100_00000_00001_00010_00000000000;  
    instructions[1] = 32'b001110_00000_00001_00010_00000000000;  
    instructions[2] = 32'b001000_00000_00001_00010_00000000000;  
    instructions[3] = 32'b001011_00011_00001_00010_00000000000;  
    instructions[4] = 32'b001010_00000_00001_00010_00000000000;     
    instructions[5] = 32'b000001_00000_00001_00010_00000000000;  
    instructions[6] = 32'b001101_00000_00001_00010_00000000000;  
    instructions[7] = 32'b000110_00000_00001_00010_00000000000;  
    instructions[8] = 32'b001001_00000_00001_00010_00000000000;  
    instructions[9] = 32'b000101_00000_00001_00010_00000000000;  
    instructions[10]= 32'b000111_00000_00001_00010_00000000000;  

    for (i = 0; i < 11; i = i + 1) begin
      current_instruction = instructions[i];   
      // here i want to access the values in the register file to analyze it.
      #20;
    end 

    $finish; 
  end
endmodule 

and here is the register file

module reg_file (clk, addr1, addr2, addr3, in , out1, out2);

input clk;
input [4:0] addr1, addr2, addr3;
input [31:0] in;
output reg [31:0] out1, out2;
reg enable = 0; //flag for ensuring there is no garbage values.  

function [31:0] get_register_value;
    input [4:0] register_number; // 5 bits to address 32 registers
    begin
      get_register_value = registers[register_number];
    end
endfunction 
    
// Declare a register array with 32 registers, each 32 bits wide
  reg [31:0] registers [0:31];

    initial begin
    registers[0]  = 32'h0000;
    registers[1]  = 32'h175A;
    registers[2]  = 32'h2FC2;
    registers[3]  = 32'h01E2;
    registers[4]  = 32'h37A6;
    registers[5]  = 32'h1404;
    registers[6]  = 32'h0738;
    registers[7]  = 32'h1494;
    registers[8]  = 32'h3F3A;
    registers[9]  = 32'h129E;
    registers[10] = 32'h10CA;
    registers[11] = 32'h0262;
    registers[12] = 32'h05E6;
    registers[13] = 32'h2642;
    registers[14] = 32'h1D20;
    registers[15] = 32'h15B4;
    registers[16] = 32'h2454;
    registers[17] = 32'h3012;
    registers[18] = 32'h31F6;
    registers[19] = 32'h28F6;
    registers[20] = 32'h2D34;
    registers[21] = 32'h1A7A;
    registers[22] = 32'h20EE;
    registers[23] = 32'h1644;
    registers[24] = 32'h3466;
    registers[25] = 32'h2BE0;
    registers[26] = 32'h07C6;
    registers[27] = 32'h039A;
    registers[28] = 32'h1784;
    registers[29] = 32'h3D80;
    registers[30] = 37'h1600;
    registers[31] = 32'h0000;
  end 
  
  always @(posedge clk) begin 
    if(enable)
    registers[addr3] <= in; // Write 'in' to the register at 'addr3'
  end

  always @(posedge clk) begin 
    enable = 1; 
    $display("Instructionx : %h", registers[addr3]);
    out1 = registers[addr1]; // Read from the register at 'addr1'
    out2 = registers[addr2]; // Read from the register at 'addr2'
  end

endmodule
module alu (
  input [5:0] opcode,
  input [31:0] a, b,
  output reg [31:0] result
);
  // Define opcodes for different operations
  localparam [5:0] ADD   = 6'b000100,
                   SUB   = 6'b001110,
                   ABS   = 6'b001000,
                   NEG   = 6'b001011,
                   MAX   = 6'b001010,
                   MIN   = 6'b000001,
                   AVG   = 6'b001101,
                   NOT   = 6'b000110,
                   OR    = 6'b001001,
                   AND   = 6'b000101,
                   XOR   = 6'b000111;
  
  always @(*) begin
    case (opcode)
      ADD: result = a + b; // Addition
      SUB: result = a - b; // Subtraction
      AND: result = a & b; // Bitwise AND
      ABS: result = (a>0)? a:-a;
      NEG: result = -a;    // negate a  
      MAX: result = (a>b) ? a:b;
      MIN: result = (a<b) ? a:b;
      AVG: result = (a+b)/2; 
      NOT: result = ~a;    // Bitwise NOT (unary operation, ignores b)  
      OR : result = a | b; // Bitwise OR
      XOR: result = a ^ b; // Bitwise XOR   
      
      default: result = 32'b0; // Default case to handle undefined opcodes
    endcase
  end
endmodule
module mp_top (clk, instruction , result );
input clk;
input [31:0] instruction;
output reg [31:0] result;


 // Decode the instruction
  wire [5:0] opcode;
  wire [4:0] address1;
  wire [4:0] address2;
  wire [4:0] address3; 
  wire [31:0] out1;
  wire [31:0] out2;

  // Assign the instruction fields
  assign opcode = instruction[31:26];
  assign address1 = instruction[25:21];
  assign address2 = instruction[20:16];
  assign address3 = instruction[15:11];
  
reg_file file_regester(
.clk(clk),
.addr1(address1),
.addr2(address2),
.addr3(address3),
.out1(out1),
.out2(out2),
.in(result)
); 

alu ALU ( 
.opcode(opcode),
.a(out1),
.b(out2),
.result(result)
);
endmodule



```
\$\endgroup\$
0

1 Answer 1

1
\$\begingroup\$

You can add code like this into the testbench module. It uses a Verilog hierarchical specifier to access a signal in a sub-module:

#20 $display("uut registers[6]='h%04x", uut.file_regester.registers[6]);

Here is the modified testbench code as an example:

module testBench ();
  reg [31:0] instructions [0:10];
  integer i; 
  reg clk;
  reg [31:0] current_instruction; // To hold the current instruction
  wire [31:0] result; // To capture the result from mp_top
   
  mp_top uut (clk, current_instruction, result);

  initial clk = 0; 
  always #5 clk = ~clk;
  
  initial begin
    instructions[0] = 32'b000100_00000_00001_00010_00000000000;  
    instructions[1] = 32'b001110_00000_00001_00010_00000000000;  
    instructions[2] = 32'b001000_00000_00001_00010_00000000000;  
    instructions[3] = 32'b001011_00011_00001_00010_00000000000;  
    instructions[4] = 32'b001010_00000_00001_00010_00000000000;     
    instructions[5] = 32'b000001_00000_00001_00010_00000000000;  
    instructions[6] = 32'b001101_00000_00001_00010_00000000000;  
    instructions[7] = 32'b000110_00000_00001_00010_00000000000;  
    instructions[8] = 32'b001001_00000_00001_00010_00000000000;  
    instructions[9] = 32'b000101_00000_00001_00010_00000000000;  
    instructions[10]= 32'b000111_00000_00001_00010_00000000000;  

    for (i = 0; i < 11; i = i + 1) begin
      current_instruction = instructions[i];   
      // here i want to access the values in the register file to analyze it.
      #20;
    end 

    #20 $display("uut registers[6]='h%04x", uut.file_regester.registers[6]);

    $finish; 
  end
endmodule 

Here is the output when you run a simulation:

uut registers[6]='h0738

A runnable code example is available on EDA Playground.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.