Skip to content

Session #5: RTL Design and Design and Verification

Homework

  • Write Verilog for your project’s core module (aim for 10-30 lines to start)

  • Integrate with any provided library modules (e.g., debounce, UART, PWM) — create a top-level wrapper

  • Simulate with a testbench and examine waveforms in GTKWave

  • Run linter (verilator –lint-only) and fix and warnings

Write Verilog

For my project I am designing a button to trigger a PWM signal. I read a button/switch casues an unpredictable bounce in the signal on the circuits, therefore a design strategy uses what is called a ‘debounce’ circuit. I am going to write “debounce” circuit.

First try with the help of #3 resource. alt text

Unsuccessful alt text

Unsuccessful Again alt text

Yet again, working through the faults. alt text

OK, After this. I am going to try a simplier program first. Since I know the debouncer has two flip flop gates I am writing a flip flop below.

alt text

Final got something to work, somewhat. Need to figure out what to do from here.

alt text

alt text

Code for a d flip flop Behavioral style

// D Flip-Flop Module
module dff (
    input wire clk,     // Clock input
    input wire reset,   // Asynchronous reset
    input wire d,       // Data input
    output reg q        // Data output
);

    // Always block triggered on the rising edge of the clock or reset
    always @(posedge clk or posedge reset) begin
        if (reset) begin
            q <= 1'b0; // Reset output to 0
        end
        else begin
            q <= d;   // Capture data input on rising edge of clock
        end
    end

endmodule
Test Bench for the D Flip Flop

// Testbench for D Flip-Flop
module tb_dff;

    // Testbench signals
    reg clk, reset, d;
    wire q;

    // Instantiate the D Flip-Flop module
    dff uut (
        .clk(clk),
        .reset(reset),
        .d(d),
        .q(q)
    );

    // Clock generation
    always #5 clk = ~clk; // Clock period of 10 time units

    // Test scenarios
    initial begin
        clk = 0;
        reset = 1;
        d = 0;

        #10; // Wait for 10 time units

        // Release reset and apply test vectors
        reset = 0;
        d = 1; #10; // Check output when D is 1

        d = 0; #10; // Check output when D is 0

        d = 1; #10; // Check output when D is 1 again

        // Apply reset again
        reset = 1; #10; // Output should be reset to 0

        reset = 0; // Release reset
        d = 1; #10; // Final check

        // End of simulation
        $finish;
    end

    // Dump signals for waveform analysis
    initial begin
        $dumpfile("dump.vcd");
        $dumpvars(1);
    end
    endmodule

Commands

verilator --lint-only -Wall <i>name</i>.v

The verilator builds and check the file

iverilog -o <i>name-executable-file</i> <i>name.v</i> <i>name_tb.v</i>

name-executable-file is the instantiation of the veriolg file and the textbench data name.v is the verilog file name_tb.v is the testbench file that goes iwth the verilogfile

vvp <i>name-executable-file</i>

gtkwave dump.vcd

Success on this example alt text

Next, run the test bench Test ran, compiled and I was able to view, however, I need to go back and look. In the wave viewer I cannot move the cycle around.

I thought that I could look at the vcd file and I was correct. I saw the unit of time was every 10 second which was out of the range of the gktwave. So I adjusted some of the settings in the wave and wola it worked. Now with this new found skill and confidence on to writing in gate style. I don’t like black boxes until I have some understanding.

alt text

alt text

ok, learned something cool

Learned Something Cool

wire and_gate_output; // “and_gate_output” is a wire that only outputs

reg d_flip_flop_output; // “d_flip_flop_output” is a register; it stores and outputs a value

reg [7:0] address_bus; // “address_bus” is a little-endian 8-bit register

Layed out the gates for a D Flip flop to get a handle on the flow of data at the lowest abstraction layer. alt text

Labeled the gates alt text

Some errors!

alt text

Some more errors!

alt text

Tried this!!

alt text

One of the same errors: circular q which I understand the reason, I just don’t know how to fix it.

alt text

ALright here is what I found thank you ChatGPT for help, the code is not a dflipflop it is a latch. THanks interent. Well chalk it up to learning. Now map the d flip flop schematically then write it in verilog.

I found this schematic online, however, I may run into the same problem above due to the right most nand gates.

alt text

In Verilog, “circular logic” typically refers to a combinational feedback loop where a signal’s value depends on itself within the same clock cycle. These loops are generally considered bad practice in synthesizable code and should be avoided because they can lead to unpredictable behavior, oscillation, and difficulty with synthesis and timing closure. - Gemni

alt text

Ok, next try! Now all I see in d flip flops are combinational feedback loops

Let’s attempt this. alt text

Colored and labeled the schematic, this helps a lot.

alt text

ChatGPT

Verilator calls it “circular combinational logic” because it’s doing lint and doesn’t assume you intended a latch.

In hardware, that pair of NANDs is a latch core (state-holding element), not a combinational block.

I gave up with the dff using NAND gates for now due to the circular logic. Frustrating but need to move on.

I completed a counter example using some code from #9 and #10. With some work I was able to create a vcd file and see the waves. It felt good and I am closer to getting my project done. The below code does not work.

This is where the code begins

Counter

//Work through tutorial using the behavior abstration layer

//work through a different text bench

module counter( clk, //clock input rst, // active high, synchronous Reset input enable, //Active high enable signal for counter counter_out //4 bit vector output of the counter );

//input ports
    input wire clk;
    input wire rst;
    input wire enable;
//output ports
    output[3:0] counter_out; //register 4 bit 
//output data type
    reg[3:0] counter_out;
//Code starts here
//Since the counter is positive edge trigged one, we trigger the below block with respect to positive edge of the clock
    always @(posedge clk)
        begin: COUNTER //Block Name
        //at every rising edge of clock we check if reset is active
        //if active, we load the counter output with "0000"
        if(rst ==1'b1) begin
            counter_out <=#1 4'b000;
        end
        //if enable is active the we increment the counter
        else if (enable ==1'b1) begin
            counter_out <=#1 counter_out+1;
        end
    end

endmodule

I had to modify both of the codes since there was some error and the test bench did not execute adump file, it was designed for something other than verilog.

“Counter Test Bench

module counter_tb(); //declare inputs as regs and outputs as wires reg clk, rst, enable; wire [3:0] counter_out; //

//Initialize all variables initial begin clk = 1; rst = 0; enable = 0; #5 rst = 1; //Assert the reset #5 rst = 0; //De-assert the reset #5 enable =1; //Assert enable #100 enable = 0; //De-assert enable #10 $finish; //Terminate simulation end

//Clock generator always begin #5 clk = ~clk; //toggle clock every 5 ticks end //connect DUT to test bench counter U_counter(clk,rst,enable,counter_out);

//added this

initial begin //create simulated output $dumpfile(“dump.vcd”); // $dumpvars(1);
end

endmodule

I finally got the counter to work:

Working Counter and Test Bench

alt text

alt text

Integrate

Simulate

Simluation for the counter example. Now looking at it, I don’t know if it is correct. - rst looks good - clk looks good - enable looks good - not so sure about the counter

alt text

Zoomed up into the 0-20 second range the counter is not counting. Look’s Like a got to fix it.

alt text

Added this code to display the variables.

alt text

The counter_out is not counting.

alt text

Ok, looked at another counter and counter test bed. It is becoming easier to read and write. Counter2 worked with a little.

alt text

alt text

I compared the two counters to start and peel back the layers of understanding.

alt text

alt text

alt text

Heck ya! work through the first counter finally. It was couple of this that did not work with the tutorial and I fixed them. For some reason there was a #1 in front of the counter = counter +1 statement that was removed. Additionally, on the test bed I made I set the clk <= 0; rst <=0 alt text

Run Linter

Resources:

  1. https://www.fpga4student.com/2017/04/simple-debouncing-verilog-code-for.html
  2. https://www.youtube.com/watch?v=LO8ONR1TceI
  3. https://www.chipverify.com/verilog/verilog-debounce-circuit
  4. https://www.youtube.com/watch?v=YUB-OyGr1oA
  5. https://logicflick.com/how-to-write-verilog-code-for-a-d-flip-flop/
  6. https://www.asic-world.com/verilog/veritut.html
  7. https://electronics.stackexchange.com/questions/98591/please-explain-the-following-verilog-code-of-a-d-flip-flop
  8. https://technobyte.org/verilog-code-d-flip-flop-dataflow-gate-behavioral/
  9. Some
  10. some