[转] 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拉高,清空寄存器

### Verilog实现8位累加器仿真电路 以下是一个基于Verilog的8位累加器的设计及其测试代码示例。该设计通过输入时钟信号和复位信号来控制累加操作,并提供一个简单的测试平台验证其功能。 #### 设计模块 ```verilog module eight_bit_adder( input clk, // 时钟信号 input reset, // 复位信号 input [7:0] data_in,// 输入数据 output reg [7:0] sum// 输出累加结果 ); always @(posedge clk or posedge reset) begin if (reset) begin sum <= 8'b0; // 当复位信号有效时,清除累加器 end else begin sum <= sum + data_in; // 每个时钟周期将输入数据加入到当前累加值中 end end endmodule ``` 此部分实现了基本的功能逻辑,在每个时钟上升沿更新累加值[^1]。如果`reset`信号被激活,则重置累加器至初始状态。 #### 测试模块 下面提供了用于验证上述8位累加器行为的测试台代码: ```verilog module testbench; reg clk; reg reset; reg [7:0] data_in; wire [7:0] sum; eight_bit_adder uut ( .clk(clk), .reset(reset), .data_in(data_in), .sum(sum) ); initial begin $dumpfile("adder.vcd"); $dumpvars(0, testbench); clk = 0; forever #5 clk = ~clk; // 创建时钟信号,每10时间单位翻一次 end initial begin reset = 1; // 初始化复位 data_in = 8'd0; // 初始输入设为0 #10 reset = 0; // 取消复位后开始正常运行 #10 data_in = 8'd1; // 设置第一个输入值为1 #10 data_in = 8'd2; // 下一时钟设置第二个输入值为2 #10 data_in = 8'd3; // 继续增加新的输入... #10 data_in = 8'd4; #10 data_in = 8'd5; #20 $stop(); // 停止模拟以便观察波形图 end endmodule ``` 这段测试代码设置了必要的激励源并记录了VCD文件以供后续分析[^3]。它还展示了如何逐步改变输入变量并通过波形查看最终的结果变化情况。 ### 结果说明 当执行以上程序时,可以预期得到一系列连续递增的数据流作为输出响应于不同的输入序列。这有助于确认所构建实体能够按照预定规格正确运作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值