You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Verilog累加器代码无报错但无输出结果问题排查求助

Verilog Accumulator Not Producing Output (Dual-Edge Accumulation Requirement)

Problem Description

I'm working on a Verilog accumulator where:

  1. I generate a pseudorandom signal, convert it from 0-1 range to a signed -1-1 range to get the acmin signal, then accumulate it.
  2. The debugger throws no errors, but I can't see any results from the accumulator acc.
  3. My goal is to accumulate acmin on both the rising and falling edges of the clock.

Here's my design and testbench code:

Design Module

module lfsr(clk, rst, seed, load, R, acc);
input [3:0] R;
input [26:0] seed;
input load;
input rst;
input clk;
reg [3:0]q;
wire [3:0] S;
wire overflow;
wire [3:0] acmin ;
wire [26:0] state_out;
wire [26:0] state_in;
output [7:0] acc;
reg [7:0] acc;
flipflop F[26:0] (state_out, clk, rst, state_in);
mux M1[26:0] (state_in, load, seed, {state_out[25],state_out[24],state_out[23],state_out[22],state_out[21],state_out[20],state_out[19],state_out[18],state_out[17],state_out[16],state_out[15],state_out[14],state_out[13],state_out[12],state_out[11],state_out[10],state_out[9],state_out[8],state_out[7],state_out[6],state_out[5],state_out[4],state_out[3],state_out[2], state_out[1], state_out[0], nextbit});
xor G1(nextbit, state_out[5], state_out[2], state_out[1], state_out[26]);
// Pseudorandom generator
always@(clk) begin
if (state_out[26]==0)
q=4'b1111; // 0 to -1
else
q=4'b0001; //1 to 1
end
assign acmin= R*q; // accumulator input
always@(clk) begin
if(rst)
acc = 8'b00000000;
else
acc = acc + acmin;
end
endmodule

Testbench

module lfsrtst;
reg [3:0] R;
reg clk;
reg rst;
reg [26:0] seed;
reg load;
wire [7:0] acc;
lfsr lfsr(clk, rst, seed, load, R, acc);
initial begin
clk = 0;
load = 0;
seed = 0;
rst = 0;
R=0;
#10 rst = 1;
#10 rst = 0;
#50 R = 4'b0111;
#50 R = 4'b0010;
#100 R = 4'b1111;
#50 R = 4'b1011;
#150 R = 4'b1101;
#50 R = 4'b1000;
end
// drive clock
always #50 clk = !clk;
// program lfsr
initial begin
#100 seed = 27'b000000110000011000001000001;
load = 1;
#100 load = 0;
#1400 $stop;
end
endmodule

I'm getting the expected acmin signal, but acc shows no results. What's wrong here?


Root Cause Analysis

There are three critical issues preventing acc from working correctly:

1. Reset Logic Isn't Triggered When Needed

Your accumulator's always block only listens for clk changes in its sensitivity list, but rst is excluded. In your testbench, rst goes high then low before the clock ever toggles (clock first flips at #50, while rst changes at #10 and #20). This means the reset assignment if(rst) acc = 8'b0; never runs, leaving acc stuck in its initial unknown state (x). Any addition with x will just keep acc as x, so you'll never see valid output.

2. Unsigned/Signed Mismatch Breaks acmin Calculation

You intend q to represent -1 or 1, but both q and R are declared as unsigned (reg [3:0]). When you do R*q, Verilog performs unsigned multiplication:

  • 4'b1111 as an unsigned value is 15, not -1
  • This makes acmin completely different from what you expect, even if acc did work.

3. Dual-Edge Trigger Implementation Is Ambiguous

While always@(clk) will trigger on both clock edges, it's not explicit, and combining it with an unlisted reset signal creates unpredictable behavior. It's better to explicitly define the sensitivity list for dual-edge triggering.


Fixed Code

Updated Design Module

module lfsr(clk, rst, seed, load, R, acc);
input signed [3:0] R;  // Mark as signed for correct arithmetic
input [26:0] seed;
input load;
input rst;
input clk;
reg signed [3:0] q;    // Signed to represent -1/1 correctly
wire [3:0] S;
wire overflow;
wire signed [3:0] acmin ;  // Signed output from multiplication
wire [26:0] state_out;
wire [26:0] state_in;
output signed [7:0] acc;   // Signed accumulator for negative values
reg signed [7:0] acc;

flipflop F[26:0] (state_out, clk, rst, state_in);
// Simplified concatenation for readability
mux M1[26:0] (state_in, load, seed, {state_out[25:0], nextbit});

xor G1(nextbit, state_out[5], state_out[2], state_out[1], state_out[26]);

// Pseudorandom generator with explicit signed values
always@(*) begin
    if (state_out[26] == 0)
        q = -4'sd1;  // Clearer way to write signed -1
    else
        q = 4'sd1;   // Clearer way to write signed 1
end

assign acmin = R * q;  // Now performs signed multiplication as intended

// Dual-edge triggered accumulator with asynchronous reset
always@(posedge clk or negedge clk or posedge rst) begin
    if(rst)
        acc = 8'sd0;  // Reset to signed 0
    else
        acc = acc + acmin;  // Signed accumulation
end
endmodule

Updated Testbench

module lfsrtst;
reg signed [3:0] R;  // Match signed type from design
reg clk;
reg rst;
reg [26:0] seed;
reg load;
wire signed [7:0] acc;

lfsr lfsr(clk, rst, seed, load, R, acc);

initial begin
    clk = 0;
    load = 0;
    seed = 0;
    rst = 0;
    R = 0;
    #10 rst = 1;
    #10 rst = 0;
    #50 R = 4'sd7;    // Signed 7 (matches 4'b0111)
    #50 R = 4'sd2;    // Signed 2 (matches 4'b0010)
    #100 R = -4'sd1;  // Explicit signed -1 (matches 4'b1111)
    #50 R = -4'sd5;   // Signed -5 (matches 4'b1011)
    #150 R = -4'sd3;  // Signed -3 (matches 4'b1101)
    #50 R = -4'sd8;   // Signed -8 (matches 4'b1000)
end

// Clock with 50ns total period (triggers twice per cycle for dual-edge)
always #25 clk = !clk;

// Load LFSR seed
initial begin
    #100 seed = 27'b000000110000011000001000001;
    load = 1;
    #100 load = 0;
    #1400 $stop;
end
endmodule

Key Changes Explained

  1. Sensitivity List Fix: The accumulator's always list now includes posedge clk, negedge clk, and posedge rst, ensuring reset triggers immediately and both clock edges trigger accumulation.
  2. Signed Type Declarations: All relevant signals are marked signed to ensure multiplication and accumulation behave as intended for negative values.
  3. Clearer Value Assignments: Using -4'sd1 instead of 4'b1111 makes the intent of representing -1 explicit, avoiding unsigned/signed confusion.
  4. Clock Adjustment: The testbench clock now toggles every 25ns (50ns total period), so each cycle triggers accumulation twice (once on rising, once on falling edge) as you requested.

内容的提问来源于stack exchange,提问作者Derun Karabeyoglu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:52:38