//rtl code
module counter_m
#(
parameter int unsigned w = 1
)
(
output logic [w-1:0] count,
input logic [w-1:0] data,
input load,
input rst_,
input clk
);
timeunit 1ns;
timeprecision 100ps;
logic [w-1:0] ncount;
always_comb
priority if(load == 1)
ncount = data;
else
ncount = count + 1;
always_ff @(posedge clk or negedge rst_)
if (rst_ == 0)
count <= 0;
else
count <= ncount;
endmodule : counter_m
//testbench
module counter_test_m;
timeunit 1ns;
timeprecision 100ps;
localparam time period = 20;
localparam time width = 5;
logic [width-1:0] count_out;
logic [width-1:0] count_in;
logic load;
logic rst_;
logic clk;
counter_m #(width) counter (.data(count_in), .count(count_out), .*);
initial clk = 0;
always #(period/2) clk = ~clk;
initial
begin
$timeformat( -9, 0, "ns", 5);
$monitor ("%t clk = %b rst_ = %b load = %b count_in = %h count_out = %h", $time, clk, rst_, load, count_in, count_out);
#(period * 99)
$display("counter test timeout");
$finish;
end
task xpect( input logic [width-1:0]expects);
if(count_out !== expects)
begin
$display("count is %b and should be %b", count_out, expects);
$display("counter test failed");
$finish;
end
endtask
initial
begin
@(negedge clk)
rst_= 1; load= 1'bx; count_in = 'x; @(negedge clk)
rst_= 0; load= 1'bx; count_in = 'x; @(negedge clk) xpect(0);
rst_= 1; load= 1'b0; count_in = 'x; @(negedge clk) xpect(1);
rst_= 1; load= 1'b0; count_in = 'x; @(negedge clk) xpect(2);
rst_= 1; load= 1'b0; count_in = 'x; @(negedge clk) xpect(3);
rst_= 1; load= 1'b0; count_in = 'x; @(negedge clk) xpect(4);
rst_= 1; load= 1'b1; count_in = 29; @(negedge clk) xpect(29);
rst_= 1; load= 1'b0; count_in = 'x; @(negedge clk) xpect(30);
rst_= 1; load= 1'b0; count_in = 'x; @(negedge clk) xpect(31);
rst_= 1; load= 1'b0; count_in = 'x; @(negedge clk) xpect(0);
rst_= 1; load= 1'b0; count_in = 'x; @(negedge clk) xpect(1);
$display("counter test passed");
$finish;
end
initial
begin
$recordfile("counter_m.trn");
$recordvars("depth = 0");
end
endmodule : counter_test_m
No comments:
Post a Comment