[转] CSA 累加器的verilog 仿真

源代码转自《精通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

oen_n拉高,清空寄存器

猜你喜欢

转载自blog.csdn.net/u012369580/article/details/78956855