Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Pre- and Post-Layout Simulation with VCS and Verdi in a CIC Filter Design

Tech May 9 4

Synopsys VCS and Verdi provide a robust environment for both pre- and post-layout digital simulations. This walkthrough uses a CIC filter as the design under test to illustrate a typical workflow from compile to waveform analysis, employing Makefiles and file lists to streamline the process.

RTL Refinement Before Simulation

The original CIC filter had a comb stage susceptible to race conditions, causing glitches in post-layout simulations and preventing successful compilation under VCS. An intermediate pipeline register eliminates the hazard, as shown in the revised design below.

module cic_filter (
    input clk,
    input rst_n,
    input in,
    output reg [18:0] out
);
    wire clk_div;
    reg [18:0] integrator1, integrator2, integrator3;
    wire [18:0] integrator1_next, integrator2_next, integrator3_next;

    assign integrator1_next = integrator1 + in;
    assign integrator2_next = integrator2 + integrator1;
    assign integrator3_next = integrator3 + integrator2;

    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            integrator1 <= 19'd0;
            integrator2 <= 19'd0;
            integrator3 <= 19'd0;
        end else begin
            integrator1 <= integrator1_next;
            integrator2 <= integrator2_next;
            integrator3 <= integrator3_next;
        end
    end

    divider div_inst (
        .clk(clk),
        .rst_n(rst_n),
        .clk_div(clk_div)
    );

    reg [18:0] comb_a, comb_b, comb_c;
    reg [18:0] comb_a_next, comb_b_next, comb_c_next;

    always @(posedge clk_div or negedge rst_n) begin
        if (!rst_n) begin
            comb_a_next <= 19'd0;
            comb_b_next <= 19'd0;
            comb_c_next <= 19'd0;
        end else begin
            comb_a_next <= integrator3_next - comb_a;
            comb_b_next <= comb_a_next    - comb_b;
            comb_c_next <= comb_b_next    - comb_c;
        end
    end

    always @(posedge clk_div or negedge rst_n) begin
        if (!rst_n) begin
            comb_a <= 19'd0;
            comb_b <= 19'd0;
            comb_c <= 19'd0;
        end else begin
            comb_a <= integrator3_next;
            comb_b <= comb_a_next;
            comb_c <= comb_b_next;
        end
    end

    always @(posedge clk_div or negedge rst_n) begin
        if (!rst_n) out <= 19'd0;
        else out <= comb_c_next;
    end
endmodule

Pre-Layout Simulation Setup

VCS separates compilation and simulation phases. A Makefile automates the invocation, defines a timescale, and selects the required FSDB waveform format for Verdi. A file list (file_list.f) controls which sources are used and allows easy switching between RTL and netlist.

.PHONY: vcs_com vcs_sim verdi

OUTPUT = cic_filter
TIMESCALE = 1ns/1ns

vcs_com:
	cd ../vcs && vcs -full64 +v2k -debug_pp -timescale=${TIMESCALE} -cpp g++ -cc gcc -LDFLAGS -no-pie -LDFLAGS -Wl,--no-as-needed -CFLAGS -fPIE -fsdb -f file_list.f -o ${OUTPUT} -l compile.log

vcs_sim:
	cd ../vcs && ./${OUTPUT} -l sim.log

verdi:
	cd ../verdi && verdi -f ../vcs/file_list.f -ssf ../vcs/tb_${OUTPUT}.fsdb

For pre-layout simulation, the file list activates RTL sources and the testbench, while netlist and standard cell library references remain commented out:

+define+FSDB

// RTL Sources
../src/cic_filter.v
../src/divider64.v

// Netlist
//../icc/outputs/cic_filter_post_layout.v

// Standard Cell Library
//../lib/verilog/smic18.v

// Testbench
../tb/tb_cic_filter.v

The testbench uses a clock period definition, resets the design, streams a digital input pattern from a file, and terminates the simulation with $finish. FSDB dumping is conditionally compiled, and SDF annotation code is prepared for post-layout use but disabled with a macro.

`define period 78.125

module testbench;
    reg clk, rst_n, in;
    wire [18:0] out;

    always #`period clk <= ~clk;

    initial begin
        rst_n = 1'b0;
        clk   = 1'b0;
        #500;
        rst_n = 1'b1;
        #(10 * 12800 * `period);
        $finish;
    end

    integer i;
    reg mem[0:3000000];

    initial $readmemb("../src/1k1000mv.txt", mem);

    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            i = 0;
            in <= 1'b0;
        end else begin
            in <= mem[i];
            i  = i + 1;
        end
    end

    cic_filter cic (
        .clk(clk),
        .rst_n(rst_n),
        .in(in),
        .out(out)
    );

    `ifdef FSDB
    initial begin
        $fsdbDumpfile("tb_cic_filter.fsdb");
        $fsdbDumpvars;
        $fsdbDumpMDA();
    end
    `endif

    //  `define post_sim

    `ifdef post_sim
    initial begin
        $sdf_annotate("../icc/outputs/cic_filter_post_layout.sdf", cic);
    end
    `endif
endmodule

Execute the three targets sequentially from the project directory.

make vcs_com
make vcs_sim
make verdi

Verdi loads the FSDB file and the source list. Signals or entire instances can be added to the waveform viewer through the context menu.

Post-Layout Simulation

To run post-layout simulation, update the file list to point to the synthesized netlist and the standard cell library, leaving only those entries active:

+define+FSDB

//../src/cic_filter.v
//../src/divider64.v

../icc/outputs/cic_filter_post_layout.v

../lib/verilog/smic18.v

../tb/tb_cic_filter.v

Enable the post_sim macro in the testbench by removing its comment, allowing SDF back-annotation of cell and wire delays. Then rerun the same three Makefile steps. The FSDB waveform now reflects the timing behavior of the placed-and-routed netlist.

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.