admin管理员组文章数量:1122832
I have written a SystemVerilog testbench environment with a driver, monitor, and scoreboard. However, during simulation, the DUT output (gray) often mismatches the expected Gray code computed by the scoreboard.
Design Module
---------------------------------------------------
`timescale 1ns / 1ps
module binary_to_gray(input [3:0] binary, output [3:0] gray);
assign gray[3] = binary[3]; // MSB remains the same
assign gray[2] = binary[3] ^ binary[2]; // XOR for bit 2
assign gray[1] = binary[2] ^ binary[1]; // XOR for bit 1
assign gray[0] = binary[1] ^ binary[0]; // XOR for bit 0
endmodule
-----------------------------------------------------
Top_Testbench Module
-----------------------------------------------------
// Code your testbench here
// or browse Examples
`timescale 1ns / 1ps
`include "interface.sv"
`include "test"
module top_tb; // Top-level testbench module
intf i_intf(); // Interface instantiation
test t1(i_intf); // Test instantiation
// Instantiate the DUT (Device Under Test)
binary_to_gray DUT(
.binary(i_intf.binary),
.gray(i_intf.gray)
);
endmodule
-------------------------------------------------------
Environment Module
--------------------------------------------------------
`timescale 1ns / 1ps
`include "transaction.sv"
`include "generator.sv"
`include "driver.sv"
`include "monitor"
`include "scoreboard"
class environment;
generator gen;
driver driv;
monitor mon;
scoreboard scb;
mailbox m1, m2;
virtual intf vif;
function new(virtual intf vif);
this.vif = vif;
m1 = new();
m2 = new();
gen = new(m1);
driv = new(vif, m1);
mon = new(vif, m2);
scb = new(m2);
endfunction
task test();
fork
gen.main();
driv.main();
mon.main();
scb.main();
join
endtask
endclass
------------------------------------------------------------
Driver Module
-----------------------------------------------------------------
`timescale 1ns / 1ps
class driver;
virtual intf vif;
mailbox gen2driv;
function new(virtual intf vif, mailbox gen2driv);
this.vif = vif;
this.gen2driv = gen2driv;
endfunction
task main();
transaction trans;
repeat(5) begin
gen2driv.get(trans); // Receive transaction
vif.binary = trans.binary; // Drive input to DUT
#10; // Increased propagation delay
trans.gray = vif.gray; // Capture output
trans.display("Driver");
end
endtask
endclass
------------------------------------------------------------------
Generator Module
----------------------------------------------------------------
`timescale 1ns / 1ps
class generator;
transaction trans;
mailbox gen2driv;
function new(mailbox gen2driv);
this.gen2driv = gen2driv;
endfunction
task main();
repeat(5) begin
trans = new();
if (!trans.randomize()) $error("Failed to randomize transaction!");
trans.display("Generator");
gen2driv.put(trans); // Send transaction to driver
end
endtask
endclass
--------------------------------------------------------------------
Interface Module
--------------------------------------------------------------------
`timescale 1ns / 1ps
interface intf();
logic [3:0] binary;
logic [3:0] gray;
endinterface
---------------------------------------------------------------------
Transaction Module
--------------------------------------------------------------------
`timescale 1ns / 1ps
class transaction;
rand bit [3:0] binary; // Randomizable binary input
bit [3:0] gray; // Output to store Gray code
function void display(string name);
$display("--------------------------");
$display("%s", name);
$display("--------------------------");
$display("Binary = %b", binary);
$display("Gray = %b", gray);
$display("--------------------------");
endfunction
endclass
----------------------------------------------------------------------
test module
---------------------------------------------------------------------
`timescale 1ns / 1ps
`include "environment.sv"
program test(intf i_intf);
environment env;
initial begin
env = new(i_intf);
env.test();
$finish;
end
endprogram
---------------------------------------------------------------------
Monitor Module
------------------------------------------------------------------------
`timescale 1ns / 1ps
class monitor;
virtual intf vif; // Virtual interface for DUT connections
mailbox mon2scb; // Mailbox to send transactions to the scoreboard
// Constructor
function new(virtual intf vif, mailbox mon2scb);
this.vif = vif;
this.mon2scb = mon2scb;
endfunction
// Main task to observe DUT behavior
task main();
transaction trans;
repeat(5) begin
#10; // Increased propagation delay (align with Driver)
trans = new(); // Initialize the transaction object
trans.binary = vif.binary; // Capture binary input
trans.gray = vif.gray; // Capture Gray code output
trans.display("Monitor"); // Display the transaction details
mon2scb.put(trans); // Send the transaction to the scoreboard
end
endtask
endclass
-----------------------------------------------------------------------
Scoreboard Module
-----------------------------------------------------------------------
`timescale 1ns / 1ps
class scoreboard;
mailbox mon2scb;
logic [3:0] expected_gray; // Declare at the class level
function new(mailbox mon2scb);
this.mon2scb = mon2scb;
endfunction
task main();
transaction trans;
repeat(5) begin
mon2scb.get(trans); // Receive transaction
expected_gray[3] = trans.binary[3];
expected_gray[2] = trans.binary[3] ^ trans.binary[2];
expected_gray[1] = trans.binary[2] ^ trans.binary[1];
expected_gray[0] = trans.binary[1] ^ trans.binary[0];
if (trans.gray == expected_gray)
$display("PASS: Binary = %b, Gray = %b", trans.binary, trans.gray);
else
$error("FAIL: Binary = %b, Expected Gray = %b, DUT Gray = %b",
trans.binary, expected_gray, trans.gray);
end
endtask
endclass
Here's an example of the errors:
FAIL: Binary = 1111, Expected Gray = 1000, DUT Gray = 1100
FAIL: Binary = 0001, Expected Gray = 0001, DUT Gray = 1100
What could be causing this mismatch, and how can I fix it? Is there an issue with my DUT implementation, testbench timing, or some other aspect?
Additional Details:
The simulation tool used is Synopsys VCS. All modules are instantiated and connected through a virtual interface. The errors occur inconsistently across different binary input values.
I have written a SystemVerilog testbench environment with a driver, monitor, and scoreboard. However, during simulation, the DUT output (gray) often mismatches the expected Gray code computed by the scoreboard.
Design Module
---------------------------------------------------
`timescale 1ns / 1ps
module binary_to_gray(input [3:0] binary, output [3:0] gray);
assign gray[3] = binary[3]; // MSB remains the same
assign gray[2] = binary[3] ^ binary[2]; // XOR for bit 2
assign gray[1] = binary[2] ^ binary[1]; // XOR for bit 1
assign gray[0] = binary[1] ^ binary[0]; // XOR for bit 0
endmodule
-----------------------------------------------------
Top_Testbench Module
-----------------------------------------------------
// Code your testbench here
// or browse Examples
`timescale 1ns / 1ps
`include "interface.sv"
`include "test"
module top_tb; // Top-level testbench module
intf i_intf(); // Interface instantiation
test t1(i_intf); // Test instantiation
// Instantiate the DUT (Device Under Test)
binary_to_gray DUT(
.binary(i_intf.binary),
.gray(i_intf.gray)
);
endmodule
-------------------------------------------------------
Environment Module
--------------------------------------------------------
`timescale 1ns / 1ps
`include "transaction.sv"
`include "generator.sv"
`include "driver.sv"
`include "monitor"
`include "scoreboard"
class environment;
generator gen;
driver driv;
monitor mon;
scoreboard scb;
mailbox m1, m2;
virtual intf vif;
function new(virtual intf vif);
this.vif = vif;
m1 = new();
m2 = new();
gen = new(m1);
driv = new(vif, m1);
mon = new(vif, m2);
scb = new(m2);
endfunction
task test();
fork
gen.main();
driv.main();
mon.main();
scb.main();
join
endtask
endclass
------------------------------------------------------------
Driver Module
-----------------------------------------------------------------
`timescale 1ns / 1ps
class driver;
virtual intf vif;
mailbox gen2driv;
function new(virtual intf vif, mailbox gen2driv);
this.vif = vif;
this.gen2driv = gen2driv;
endfunction
task main();
transaction trans;
repeat(5) begin
gen2driv.get(trans); // Receive transaction
vif.binary = trans.binary; // Drive input to DUT
#10; // Increased propagation delay
trans.gray = vif.gray; // Capture output
trans.display("Driver");
end
endtask
endclass
------------------------------------------------------------------
Generator Module
----------------------------------------------------------------
`timescale 1ns / 1ps
class generator;
transaction trans;
mailbox gen2driv;
function new(mailbox gen2driv);
this.gen2driv = gen2driv;
endfunction
task main();
repeat(5) begin
trans = new();
if (!trans.randomize()) $error("Failed to randomize transaction!");
trans.display("Generator");
gen2driv.put(trans); // Send transaction to driver
end
endtask
endclass
--------------------------------------------------------------------
Interface Module
--------------------------------------------------------------------
`timescale 1ns / 1ps
interface intf();
logic [3:0] binary;
logic [3:0] gray;
endinterface
---------------------------------------------------------------------
Transaction Module
--------------------------------------------------------------------
`timescale 1ns / 1ps
class transaction;
rand bit [3:0] binary; // Randomizable binary input
bit [3:0] gray; // Output to store Gray code
function void display(string name);
$display("--------------------------");
$display("%s", name);
$display("--------------------------");
$display("Binary = %b", binary);
$display("Gray = %b", gray);
$display("--------------------------");
endfunction
endclass
----------------------------------------------------------------------
test module
---------------------------------------------------------------------
`timescale 1ns / 1ps
`include "environment.sv"
program test(intf i_intf);
environment env;
initial begin
env = new(i_intf);
env.test();
$finish;
end
endprogram
---------------------------------------------------------------------
Monitor Module
------------------------------------------------------------------------
`timescale 1ns / 1ps
class monitor;
virtual intf vif; // Virtual interface for DUT connections
mailbox mon2scb; // Mailbox to send transactions to the scoreboard
// Constructor
function new(virtual intf vif, mailbox mon2scb);
this.vif = vif;
this.mon2scb = mon2scb;
endfunction
// Main task to observe DUT behavior
task main();
transaction trans;
repeat(5) begin
#10; // Increased propagation delay (align with Driver)
trans = new(); // Initialize the transaction object
trans.binary = vif.binary; // Capture binary input
trans.gray = vif.gray; // Capture Gray code output
trans.display("Monitor"); // Display the transaction details
mon2scb.put(trans); // Send the transaction to the scoreboard
end
endtask
endclass
-----------------------------------------------------------------------
Scoreboard Module
-----------------------------------------------------------------------
`timescale 1ns / 1ps
class scoreboard;
mailbox mon2scb;
logic [3:0] expected_gray; // Declare at the class level
function new(mailbox mon2scb);
this.mon2scb = mon2scb;
endfunction
task main();
transaction trans;
repeat(5) begin
mon2scb.get(trans); // Receive transaction
expected_gray[3] = trans.binary[3];
expected_gray[2] = trans.binary[3] ^ trans.binary[2];
expected_gray[1] = trans.binary[2] ^ trans.binary[1];
expected_gray[0] = trans.binary[1] ^ trans.binary[0];
if (trans.gray == expected_gray)
$display("PASS: Binary = %b, Gray = %b", trans.binary, trans.gray);
else
$error("FAIL: Binary = %b, Expected Gray = %b, DUT Gray = %b",
trans.binary, expected_gray, trans.gray);
end
endtask
endclass
Here's an example of the errors:
FAIL: Binary = 1111, Expected Gray = 1000, DUT Gray = 1100
FAIL: Binary = 0001, Expected Gray = 0001, DUT Gray = 1100
What could be causing this mismatch, and how can I fix it? Is there an issue with my DUT implementation, testbench timing, or some other aspect?
Additional Details:
The simulation tool used is Synopsys VCS. All modules are instantiated and connected through a virtual interface. The errors occur inconsistently across different binary input values.
Share Improve this question edited Dec 3, 2024 at 12:49 toolic 61.8k19 gold badges79 silver badges126 bronze badges asked Nov 22, 2024 at 15:51 Kotupalli Venkata Siva TejaKotupalli Venkata Siva Teja 211 silver badge1 bronze badge 01 Answer
Reset to default 1The timing of the monitor is incorrect. Add a delay before you start creating the transactions from the interface signals. For example, add #5
:
// Main task to observe DUT behavior
task main();
transaction trans;
#5;
repeat(5) begin
#10; // Increased propagation delay (align with Driver)
The problem with your code is you have a simulation race condition. You are sampling the interface signals at the same time they are changing. The added delay guarantees that you will sample them when they are stable.
本文标签: verilogBinarytoGray code module failing testbench verification with mismatched outputsStack Overflow
版权声明:本文标题:verilog - Binary-to-Gray code module failing testbench verification with mismatched outputs? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736302561a1931579.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论