源代码转自《精通verilog:IC设计核心实例详解》
top
module top;
reg clk,nrst;
integer seed1;
reg getrsult = 0;
reg [7:0] dim;
wire [11:0] dout;
reg oen = 0;
reg [11:0] sum;
always #20 clk = ~clk;
initial
begin
clk =0;
seed1 = 6;
sum =0;
#41 nrst = 0;
#85 nrst = 1;
repeat (20)
begin
repeat(10)
@(posedge clk);
oen=0;
@(posedge clk);
oen = #1 1;
@(posedge clk);
@(posedge clk);
@(posedge clk);
oen = #1 0;
end
# 100 $finish;
end
always @(posedge clk or negedge nrst)
if (~nrst) dim <=0;
else dim <= #1 $random(seed1);
wire oen_n = top.csaacc.oen_n;
wire [7:0] din = (oen|oen_n)?0:dim;
csaacc csaacc(//input
.clk(clk),
.nrst(nrst),
.din(din),
.oen(oen),
//output
.dout(dout));
//reg [11:0] sum;
always @(posedge clk)
if (oen_n) sum <= 0;
else if (oen) sum <=sum;
else sum<=sum +din;
wire err_found = oen &(dout !=sum);
always @(negedge clk)
begin
if (err_found) begin
$display("result mismatch found at %t", $time);
$display("exact value = %d but get %d",sum,dout);
#500;
$stop;
end
end
initial
begin
$fsdbDumpfile("wave.fsdb");
$fsdbDumpvars(0,top);
end
endmodule
// csaacc
module csaacc(//input
clk,nrst,
din,oen,
//output
dout);
input clk,nrst;
input [7:0] din;
input oen;
output [11:0] dout;
reg [10:0] s_d,c_d;
wire [10:0] s,c;
wire [10:0] c_in = {c_d,1'b0};
csa3_11 csa3_11 (.a1({3'b0,din}),
.a2(s_d),
.a3(c_in),
.s(s),
.c(c));
reg oen_d;
always @(posedge clk or negedge nrst)
if (~nrst) oen_d <=0;
else oen_d <=oen;
wire oen_n =~oen &oen_d;
always @(posedge clk or negedge nrst)
if (~nrst) begin
s_d <=0;
c_d <=0;
end else if (oen_n) begin
s_d <=0;
c_d <=0;
end else if (oen) begin
s_d <=s_d;
c_d <=c_d;
end else begin
s_d <=s;
c_d <=c;
end
wire [11:0] dout = oen ?(s_d + c_in) :0;
endmodule
//adder
`define width 11
module csa3_11 (//input
a1,a2,a3,
//output
s,c);
input [`width-1:0] a1,a2,a3;
output [`width-1:0] s,c;
wire [`width-1:0] s = a1^a2^a3;
wire [`width-1:0] c = (a1 & a2) |(a1 & a3)| (a2 & a3);
endmodule