Hi,
This is the verilog code for a convolutional encoder with constraint length=3 and code rate=1/2 where dff is the d flipflop that I have called in the code.
module conv_enc(clk,rst,ip,cw);
input clk,rst;
input ip;
wire c0,c1;
output [15:0]cw;
wire d1,d0;
dff u0(clk,rst,ip,d1);
dff u1(clk,rst,d1,d0);
assign c0=ip^d1^d0;
assign c1=ip^d0;
assign cw = {c0,c1};
endmodule
I have to write a system verilog layered testbench for the same.
This is the layered testbench code I have written but I’m not getting the correct values.
//-------------------------------------------------------------------
//Transaction
//-------------------------------------------------------------------
class transaction;
//declaring the transaction items
rand bit ip;
bit [15:0]cw;
function void display(string name);
$display("- %s ",name);
$display("-ip = %b,- cw = %b",ip,cw);
endfunction
endclass
//-------------------------------------------------------------------
//Generator
//-------------------------------------------------------------------
class generator;
//declaring transaction class
rand transaction trans;
//repeat count, to specify number of items to generate
int repeat_count;
//mailbox, to generate and send the packet to driver
mailbox gen2driv;
//event, to indicate the end of transaction generation
event ended;
//constructor
function new(mailbox gen2driv);
//getting the mailbox handle from env, in order to share the transaction packet between the generator and driver, the same mailbox is shared between both.
this.gen2driv = gen2driv;
endfunction
//main task, generates(create and randomizes) the repeat_count number of transaction packets and puts into mailbox
task main();
repeat(repeat_count) begin
trans = new();
if(!trans.randomize())
$fatal("GEN::transaction randomization failed");
trans.display("[ Generator ]");
gen2driv.put(trans);
end
-> ended; //triggering indicates the end of generation
endtask
endclass
//---------------------------------------------------------------------------------------
//Interface
//---------------------------------------------------------------------------------------
interface intf(input logic clk,rst);
//declaring the signals
logic ip;
logic [15:0]cw;
logic valid;
endinterface
//---------------------------------------------------------------------------------------
//Driver
//---------------------------------------------------------------------------------------
class driver;
int no_transactions;
virtual intf vif;
mailbox gen2driv,driv2scb;
function new(virtual intf vif,mailbox gen2driv,driv2scb);
this.vif = vif;
this.gen2driv = gen2driv;
this.driv2scb = driv2scb;
endfunction
task rst;
wait(vif.rst);
$display("[ DRIVER ] ----- Reset Started -----");
vif.ip <= 0;
vif.valid <= 0;
wait(!vif.rst);
$display("[ DRIVER ] ----- Reset Ended -----");
endtask
task main;
forever begin
transaction trans;
gen2driv.get(trans);
@(posedge vif.clk);
vif.ip <= trans.ip;
vif.valid <= 1;
@(posedge vif.clk);
vif.valid <= 0;
trans.cw = vif.cw;
@(posedge vif.clk);
driv2scb.put(trans);
trans.display("[ Driver ]");
no_transactions++;
end
endtask
endclass
//------------------------------------------------------------------------------
//Monitor
//------------------------------------------------------------------------------
class monitor;
//creating virtual interface handle
virtual intf vif;
//creating mailbox handle
mailbox mon2scb;
//constructor
function new(virtual intf vif,mailbox mon2scb);
//getting the interface
this.vif = vif;
//getting the mailbox handles from environment
this.mon2scb = mon2scb;
endfunction
//Samples the interface signal and send the sample packet to scoreboard
task main;
forever begin
transaction trans;
trans = new();
@(posedge vif.clk);
wait(vif.valid);
trans.ip = vif.ip;
@(posedge vif.clk);
trans.cw = vif.cw;
@(posedge vif.clk);
mon2scb.put(trans);
trans.display("[ Monitor ]");
end
endtask
endclass
//------------------------------------------------------------------------------------
//Scoreboard
//------------------------------------------------------------------------------------
class scoreboard;
mailbox mon2scb, driv2scb;
int no_transactions;
function new(mailbox mon2scb, driv2scb);
this.mon2scb = mon2scb;
this.driv2scb = driv2scb;
endfunction
task main;
transaction trans1,trans2;
forever begin
mon2scb.get(trans1);
driv2scb.get(trans2);
$display("transaction No : %0d", no_transactions+1);
if((no_transactions+1) == 8) begin
if (trans1.cw == trans2.cw)
//if (trans1.c1 == trans2.c1)
$display("Result is as Expected Driver to Scoreboard : %p, Monitor to Scoreboard : %p", trans1, trans2);
else
$error("Wrong Result.\n\tDriver to Scoreboard : %p, Monitor to Scoreboard : %p", trans1, trans2);
end
no_transactions++;
//trans.display("[ Scoreboard ]");
end
endtask
endclass
//----------------------------------------------------------------------------------------
// Environment
//----------------------------------------------------------------------------------------
//`include "transaction.sv"
//`include "generator.sv"
//`include "driver.sv"
//`include "monitor.sv"
//`include "scoreboard.sv"
class environment;
//generator and driver instance
generator gen;
driver driv;
monitor mon;
scoreboard scb;
//mailbox handle's
mailbox gen2driv;
mailbox mon2scb;
mailbox driv2scb;
//virtual interface
virtual intf vif;
//constructor
function new(virtual intf vif);
//get the interface from test
this.vif = vif;
//creating the mailbox (Same handle will be shared across generator and driver)
gen2driv = new();
mon2scb = new();
driv2scb = new();
//creating generator and driver
gen = new(gen2driv);
driv = new(vif,gen2driv,driv2scb);
mon = new(vif,mon2scb);
scb = new(driv2scb,mon2scb);
endfunction
//
task pre_test();
driv.rst();
endtask
task test();
fork
gen.main();
driv.main();
mon.main();
scb.main();
join_any
endtask
task post_test();
wait(gen.ended.triggered);
wait(gen.repeat_count == driv.no_transactions);
//Optional
wait(gen.repeat_count == scb.no_transactions);
endtask
//run task
task run;
pre_test();
test();
post_test();
$finish;
endtask
endclass
//------------------------------------------------------------------------------------
//Random test
//------------------------------------------------------------------------------------
program test(intf i_intf);
//declaring environment instance
environment env;
initial begin
//creating environment
env = new(i_intf);
//setting the repeat count of generator as 8, means to generate 8 packets
env.gen.repeat_count = 8;
//calling run of env, it interns calls generator and driver main tasks.
env.run();
end
endprogram
//-------------------------------------------------------------------------------
// testbench
//-------------------------------------------------------------------------------
module new_testb_top;
//clock and reset signal declaration
bit clk;
bit rst;
//clock generation
always #5 clk = ~clk;
//reset Generation
initial begin
rst = 1;
#5 rst =0;
end
//creatinng instance of interface, inorder to connect DUT and testcase
intf i_intf(clk,rst);
//Testcase instance, interface handle is passed to test as an argument
test t1(i_intf);
//DUT instance, interface signals are connected to the DUT ports
conv_enc DUT (
.clk(i_intf.clk),
.rst(i_intf.rst),
.ip(i_intf.ip),
.cw(i_intf.cw)
);
endmodule
Thanks in advance