I was following a tutorial to get started with Libero SoC with MicroSemi SmartFusion FPGA. I coded a small LED toggle module

module led_toggle( i_sw , o_led );
    input   wire [1:0]  i_sw;
    output  wire [4:0]  o_led;

    assign  o_led[0] = i_sw[0];
    assign  o_led[1] = i_sw[1];
    assign  o_led[2] = i_sw[0] &  i_sw[1];
    assign  o_led[3] = i_sw[0] |  i_sw[1];
    assign  o_led[4] = i_sw[0] ^  i_sw[1];

Pin mapping

i_sw[0] to on-board switch SW0
i_sw[1] to on-board switch SW1
o_led[7:0] to on-board LEDs D[4:0]

After synthesis, place and rout, I flash the FPGA with the bitstream.

On pressing SW0, led D0 lights up and on pressing SW1, led D1 lights up. This is as expected.

However, it seems leds D2, D3 and D4 donot light up according to the AND, OR and EXOR combination of SW0 and SW1 as per my Verilog design. In fact working backwards from the behavior on-board, the logical expressions for them are

LED D2 = Sw0 | SW1 instead of designed (SW0 & SW1)
LED D3 = SW0 & SW1 instead of designed (SW0 | SW1)
LED D4 = ~(SW0 ^ SW1) instead of designed (SW0 | SW1)

Now in the same tutorial it is mentioned that

Keep in mind the switches and LEDs are active low. That is, the switch creates zero when pushed and the led illuminates when a logical 0 is applied.

So an active low switch with an active low LED is buffer like behavior i.e. LED ON when switch pressed and LED OFF when switch de-pressed. However it doesn't explain the unexpected behavior with leds D2, D3 and D4.

So what am I missing here ?


1 Answer 1


(note: I am using the verilog operators in this post, but most reference materials you find will probably use other notation)

So what am I missing here ?

For AND and OR we have De-morgans theorem

A | B === ~((~A)&(~B))
A & B === ~((~A)|(~B))

For XOR the following is true (not sure if this identity has a name)

A ^ B === (~A)^(~B)

Your buttons and LEDs are active low. In other words their behaviour is inverted from what one might naively expect. The button produces a 1 when not pressed and a 0 when pressed. Similarly the LED lights up when given a 0 and does not light when given a 1.

  SW0      SW1    i_sw[0] i_sw[1] o_led[2] o_led[3] o_led[4] D2  D3  D4
release  release    1       1        1        1        0     Off Off On 
release   press     1       0        0        1        1     On  Off Off
 press   release    0       1        0        1        1     On  Off Off
 press    press     0       0        0        0        0     On  On  On
  • \$\begingroup\$ I mean I also did the same but I was not sure" Complement literals as switches are active low and complement the expression as LEDs are active low. But how to get intuitive behavior as per my Verilog design: in my pin constraints, should I add pull ups to LEDs and switches ? \$\endgroup\$
    – nurabha
    Commented Aug 25, 2020 at 23:48
  • \$\begingroup\$ Probablly the easiest way is to add inversions in the input and output lines, verilog syntheis tools optimise agressively so this shouldn't cost you anything in terms of performance. \$\endgroup\$ Commented Aug 25, 2020 at 23:51
  • \$\begingroup\$ While this is really small example, but If I have to port the design to another board, I will have to modify the design again. Can I not change the default active low to active high using pin constraints ? If yes, how ? \$\endgroup\$
    – nurabha
    Commented Aug 25, 2020 at 23:55
  • \$\begingroup\$ I have certainly never seen an inversion function in the pin mapping, though I'm not familiar with the specific toolchain you are using. As for dealing with multiple boards (which are likely to have other differences than just the logic polarity of signals) I see two main approaches, one is to put most of your logic in submodules and to have a different top-level module for each board. The other is to set preprocessor defines in the project file and then ifdef on them in the top-level verilog module. \$\endgroup\$ Commented Aug 26, 2020 at 0:00
  • \$\begingroup\$ Ok. Got it. thanks \$\endgroup\$
    – nurabha
    Commented Aug 26, 2020 at 0:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.