Anthony Chu panny
Anthony Chu panny

Reputation: 21

Using Verilog to implement light control

This is my main code. The function is switching the light on or off when I toggle. Maybe the t filp-flop can help?

module demo(
input switch1,switch2,
output reg light=1'b0
);

    always@(switch1 or switch2)
    begin
    light <= ~light;
    end
    
endmodule 

And the testbench

`timescale 1ns/100ps

module demo_test;

reg switch1,switch2;
wire light;

demo d1(.switch1(switch1),
            .switch2(switch2),
            .light(light));
            
initial
begin: in_set_blk 
    #0 switch1 =1'b0;
        switch2 =1'b0;
        $display ($time, "light=%d \n",light);
    #10 switch1 =1'b1;
        switch2 =1'b0;
        $display ($time, "light=%d \n",light);
    #10 switch1 =1'b0;
        switch2 =1'b0;
        $display ($time, "light=%d \n",light);
    #10 switch1 =1'b0;
        switch2 =1'b1;
        $display ($time, "light=%d \n",light);
    #10 switch1 =1'b0;
        switch2 =1'b0;
        $display ($time, "light=%d \n",light);
    #10 $stop;
    #10 $finish;
end
        
endmodule

This is the modelsim waveform diagram; I think it works well:

and this is the modelsim waveform diagram, I think it work well

This is the diagram in RTL viewer; that is the strange part:

and this is the diagram in RTL viewer, that is the strange part

Diagram in RTL viewer is so strange; the input even didn't connect to the inverter.

Any error in my main Verilog code?

Upvotes: 2

Views: 766

Answers (2)

Serge
Serge

Reputation: 12384

Your code represents an implied latch, which is usually not synthesizable. This is a common mistake when you try to use always blocks with sensititivity lists (verilog 95). Your code will simulate correctly, but synthseis requres that all inputs of the always block are listed in the sensitivity list and all elements from the sensitivity list must be inputs to the block (flops excluded).

 always@(switch1 or switch2)
    begin
    light <= ~light;
    end

In the code above the result is not a function of the switch1,2 listed in the sensitivity list and sensitivity list does not include light.

In your case a flop is needed. light <= ~light represents a zero-delay loop if used in combinatorial logic or in a latch. It can only be resolved with a flop.

Flop needs a clock. Clock must be generated in test bench and flagged in synthesis.

The code can look like the following:

   always@(posedge clk) begin
      if (switch1 || switch2)
          light <= ~light;
   end

Flops are recognized by synthesis tools due to specific programming pattern and do not require listing of all inputs.

As a general suggestion: do not use sensitivity lists for combinatorial logic or latches (flops excluded). Modern verilog (v2k) allows you to use always @* construt instead.

Upvotes: 1

toolic
toolic

Reputation: 62236

Yes, the problem is that your demo module Verilog code is not synthesizable.

Not all legal Verilog code is synthesizable. Synthesis tools recognize specific coding patterns, but your code does not match any of those patterns. There should be documentation with your FPGA tool set that shows what syntax is supported for synthesis.

This is why your RTL viewer tool gives you a strange diagram.

Here is how the simulation works. At time=0, you set light and the 2 switch inputs to 0. At time=10, you change switch1 to 1. This triggers the always block, executing the light <= ~light; assignment. This sets light=1.

Every time either of the inputs change, the always block is triggered, causing light to toggle.

If that is how you want the design to work, you should consider using edge detectors. However, that requires flip-flops and a clock.

Upvotes: 1

Related Questions