Reputation: 10560
I'm an experienced programmer but new to HDL. I'm trying to figure out how to implement basic unit testing for my hardware designs for a class I'm taking. I'm aware of SVUnit, but I need to submit the code so I would prefer to just implement the barebones testing functionality myself. This will also help me learn more.
I'm having trouble figuring out what language constructs to use. All I really need to do is instantiate a component, drive the inputs, then verify the output values. The verification is where I'm stuck. Does that need to go into an always block?
Even pointing me in the right direction for what terms I should be googling would be very helpful. So far I've tried: verilog modelsim unit testing, verilog modelsim self-checking testbench, etc without too much success.
EDIT: Example: Let's say I have a design for a 1 bit half adder. How would I write a testbench to exercise every possible input combination, and automatically verify that the output is correct?
Upvotes: 1
Views: 1496
Reputation: 1001
As a first draft I would look at something like this.
reg clk = 0;
reg rst_n;
initial
begin
rst_n = 'bx;
#5
rst_n = 1'b0;
#20
rst_n = 1'b1;
end
always @(clk)
begin
clk = #10 ~clk;
end
reg a,b;
wire adder = a + b;
task test;
input i0,i1,o;
a = i0;
b = i1;
#1
if (adder !== o)
$display("Error:Incorrect output");
endtask
initial
begin
wait(rst_n === 1'b0);
@(posedge clk)
test(0,0,0);
@(posedge clk)
test(0,1,1);
@(posedge clk)
test(1,1,0);
@(posedge clk)
test(1,0,1);
end
Then you might as a second draft implement test data as something like:
wire [3:0] stim_data [1:0];
wire [3:0] expected_output;
always @(posedge clk)
if (!rst_n)
begin
cnt <= 2'b00;
end
else
begin
cnt <= cnt + 1;
end
assign {a,b} = stim_data[cnt];
always @(posedge clk)
if (!rst_n)
begin
end
else
begin
if (adder !== expected_output[cnt])
// add error message
end
Hopefully that should get you started.
Upvotes: 0