0

I've implemented a moving average filter (in Verilog), based on an article I read which performs differently pre and post synthesis. The design implements $y[n]=y[n-1]+x[n]-x[N-1]$.

module ma_width #(parameter WIDTH =16)(
    new_sample,
    en,
    sample_out, 
    clk,
    reset_b
    );

input   [15:0]  new_sample;
input   en;
input   clk;
input   reset_b;          //active low reset
output reg  [15:0]  sample_out;



 // ex. adding 16 16-bit numbers requires 20bits...

(*keep="true"*) reg [15:0]sample_in_fifo[0:WIDTH-1];

// use generate to create fifo as a chain of sixteen 16-bit registers

genvar i;
generate
     for (i = 0; i < WIDTH-1 ; i = i + 1) begin: gd
         always @(posedge clk) begin
            if(!reset_b)
            begin
                sample_in_fifo[i+1] <=4'h0000 ;
            end
            else if (en)
            begin
                sample_in_fifo[i+1] <= sample_in_fifo[i];
            end
         end
    end
endgenerate

always @(posedge clk) begin
    if(!reset_b)
    begin
        sample_in_fifo[0]<=4'h0000;
    end
    else if (en)
    begin
        sample_in_fifo[0] <= new_sample;
    end
end

(*keep = "true"*)reg  [19:0]prevout;
(*keep = "true"*)wire [19:0] currout;

assign currout = prevout + {4'b0000,new_sample} - {4'b0000,sample_in_fifo[WIDTH-1]}; 

always @(posedge clk) begin
    if (!reset_b)
    begin
        sample_out <= 16'h0000;
        prevout <= 20'h00000;
    end
    else if (en)
    begin
       sample_out <= currout[19:4]; //divide by 16
       prevout[19:0] <= currout[19:0];  //but don't lose precision....
    end
end

endmodule

I've run into two issues:

  1. prevout was being synthesized down from a [19:0] register to a [3:0] register -I got around this by using the "keep" synthesis directive --but I'm not sure why it was being synthesized "out" like that ---I'm sure that is a clue to the other anomaly I'm seeing.

  2. In the simulation, I expect prevout to latch the state of the currout signal prior to the rising clock edge. However, for some reason, this is not the case until about 6 clock cycles, after which it then behaves as expected:

POST SYNTH SIM: updated Post synth sim

At this point I'm baffled w.r.t. to what synthesizer is doing. This works fine in the behavioral simulation, and I can't figure out what in the code (always blocks) may be ambiguously defining the registers or the logic to "confuse" or mislead the synthesizer. Any pointers on how to approach debugging this would help a lot.

In effect, the moving average filter does do what it is supposed to, except at start up. And, since I don't understand what is happening at start up, it makes me not trust the design/synthesis/and perhaps the implementation fully.

Pre-synth SIM below: enter image description here

per request in the comments, i'm including the 2 warnings (there were no errors) obtained from synthesis:

  1. [Synth 8-2507] parameter declaration becomes local in ma_width with formal parameter declaration list ["C:/Users/jorge.rive/ClampPWM/Vivado/cip_repo/ma-width/ma_width.v":44]

this is due to a parameter definintion, but it isn't used, so ignore. and

  1. [Constraints 18-5210] No constraint will be written out.

In short, these were benign warnings, as far as I can tell.

jrive
  • 218
  • 2
  • 3
  • 14
  • 2 benign warnings as faras I can tell........no errors:[Synth 8-2507] parameter declaration becomes local in ma_width with formal parameter declaration list ["C:/Users/jorge.rive/ClampPWM/Vivado/cip_repo/ma-width/ma_width.v":44] --> due to a parameter definintion which is not used...2[Constraints 18-5210] No constraint will be written out. ) – jrive Sep 20 '22 at 17:03
  • 1
    Could the de-assertion of reset be a factor? Its not shown on the post synth sym? Did the tool infer DSP blocks? The reset may act strange (differently than a reset with flops) when used with the DSP block. Maybe try active high or no reset? – Mikef Sep 20 '22 at 17:10
  • 1
    you do not have reset_b in your diagram. Can you provide it as well? – Serge Sep 20 '22 at 17:53
  • @mikef, nah...that was my bad..I updated the post synth waveforms to show the active-low reset signal. – jrive Sep 20 '22 at 18:44
  • looks like the fifo is also not updating with every input sample, until clock 7 or so....investigating that....I'm weary of the `generate block --Im using it for the first time... – jrive Sep 20 '22 at 20:00
  • @wow, @Mikef --I was about to dismiss this comment...glad I didnt! you hit the nail on the head.!! I changed deasserting `reset_b` in my testbench from #50 reset_b = `1b1 to #100 reset_b=1'b1..and that did it. Please offer that as a solution so I can give you credit. Thank you!!! – jrive Sep 20 '22 at 21:31

1 Answers1

1

A possibility is that the entire part is held in reset by a hardware global reset built into the hardware/fabric for some number of clocks or some amount of time.

Try delaying the stimulus and user reset for 10 clocks to test this theory.

I have seen stuff like this where there are resets in hardware that are not well understood without some deep drilling.

Post-synthesis simulations execute the vendors simulation model (the users RTL that has been targeted to a vendor model by synthesis) rather than the users RTL.
It can behave in ways not known to the user.

Mikef
  • 1,572
  • 2
  • 10
  • 21