Skip to main content

· 5 min read

Fixed width CSS triangles can be created easily by specifying two transparent borders and a colored border to a zero width and zero height element. Creating variable width triangles for responsive designs is not straightforward because CSS accepts border widths in pixels only. I came accross this issue recently while working on making my color picker plugin responsive.

I came up with a simple solution that uses two divs or one div and a pseudo-element to create responsive CSS triangles. Both consist of a large fixed width triangle that is covered/uncovered according to width, effectively faking responsiveness. Partially covering/uncovering the triangle makes it keep its proportions.

Now, to the code. The following are up, down, right and left pointing CSS triangles. The code is presented for both the one and two div versions. The logic used is exactly the same for both. Using two divs makes these pure CSS triangles compatible with IE7, which does not support pseudo-elements. I set up a JSFiddle for playing around with the two-div triangles: jsfiddle.net/josedvq/xEGM4 and one div triangles: jsfiddle.net/josedvq/3HG6d.

Note: For the triangles to work properly box-sizing should be set to content-box (the CSS default). Add this rule to the triangle's class if necessary.

Up-pointing CSS triangles

The following triangle is set to take 25% of the width of its container.

This code creates a responsive triangle with base-height ratio of 2, and width 100% (of its parent). To modify this code its necessary to understand how to set the triangles proportions. In short:

(padding-left + width)/padding-bottom = (border-left + border-right)/border-bottom = base/height

margin-left = -border-left = -border-right

width = padding-left

Where base/height is the base to height ratio of the desired CSS triangle. border-left + border-right is the maximum lenght of the base and border-bottom the maximum height of the responsive triangle. Your responsive triangle won't get any bigger than the inner fixed width triangle formed by this borders. Be sure to set the px widths to values large enough and with the proportions you expect the triangle to have. This internal triangle is uncovered as width increases, so these px values determine its proportions.

The outer div must uncover the fixed width triangle keeping its proportions. In the code given the total width of the triangle is width(50%) + padding-left(50%) = 100% of its parent's width. Padding and width may be set to any other value, but should be the same for both (use 25% to create a 50% total width triangle). The total height of the outer div is height(0) + padding-bottom(50%) = 50%. Here we are taking advantage of percentages in padding being calculated against parent's width. The porportions are kept: total width/total height = 2 in the example.

For example, for an equilateral triangle base = 1.1547*height, so (border-left + border-right)/border-bottom should be base/height = 1.1547. To create a 200px maximum width equilateral triangle set border-left = border-right = 100px and border-bottom = 200/1.1547 = 173px (rounded). Then we have that (padding-left + width)/padding-bottom should also be 1.1547. Say yow want it to take 20% of its parent width. Set padding-left = 10%, width = 10% and padding-bottom = 20%/1.1547 = 18.1865%.

Down-pointing CSS triangles

The following triangle is set to take 25% of the width of its container.

Change the triangle proportions respecting:

(padding-left + width)/padding-top = (border-left + border-right)/border-top = base/height

margin-left = -border-left = -border-right

margin-top = -border-top

width = padding-left

Where base/height is the base-height ratio of the desired responsive triangle. border-left and border-right set the maximum length of the base and border-top sets the maximum height. Set this fixed width triangle to be larger than the largest triangle your layout will use. Just be sure to use the porportions you want your responsive CSS triangle to have. Then set the div's padding-left, padding-top and width according to these proportions (change just padding-top for total width = 100%). For the :after pseudo-element set margin-left = - border-left and margin-top = - border-top.

Right-pointing CSS triangles

The following triangle is set to take 25% of the width of its container.

Change the triangle proportions respecting:

(padding-top + padding-bottom)/padding-left = (border-top + border-bottom)/border-left = base/height

margin-left = -border-left

margin-top = -border-top = -border-bottom

padding-top = padding-bottom

Left-pointing CSS triangles

The following triangle is set to take 25% of the width of its container.

Change the triangle proportions respecting:

(padding-top + padding-bottom)/width = (border-top + border-bottom)/border-right = base/height

margin-top = -border-top = -border-bottom

padding-top = padding-bottom

Up-right, up-left, down-right, down-left pointing triangles

For the up-right, down-right, down-left and up-left pointing CSS triangles I'll present the one-div CSS code.

The following triangles are set to take 25% of the width of their container.

That's it for now. I'll be writing other articles on CSS shapes soon. If you have any trouble on using these responsive CSS triangles please leave a comment below.

· 19 min read
Jose Vargas

The C Puzzles by Gowri Kumar are fifty C language programs meant to be compiled, run and explained. It's a great resource for those who are learning C. You'll learn the most if you use this post to compare with your own answers.

I took the time to understand and answer the first 25 problems. I'm not a C programmer (just know the basics) but did my best to explain each program both from my knowledge and googling for answers. Don't believe these are the correct answers as they may in fact be wrong. Most of the C puzzles answers may be found on different forums and Q&A sites but were not gathered on a single place before. Hope it helps. Please leave feedback and let me know any errors you find using the comments at the end of the page.

  1. The expected output of the following C program is to print the elements in the array. But when actually run, it doesn't do so.
    #include <stdio.h>
    #define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))
    int array[] = {23,34,12,17,204,99,16};
    int main(){
    int d;
    for(d=-1;d <= (TOTAL_ELEMENTS-2);d++)
    printf("%d\n",array[d+1]);
    return 0;
    }

    Find out what's going wrong.

    A: The for loop is not being executed. TOTAL_ELEMENTS is of type size_t which is unsigned. d is of type signed int. When an operator has a signed and an unsigned argument, and the unsigned argument is of greater or equal size to the signed argument, then the signed argument is converted to unsigned. So -1 is converted to 2^32 - 1 which of course is larger than TOTAL_ELEMENTS - 2. The comparisson is false. Forcing conversion to signed int with
    for(d=-1;d <= (signed int)(TOTAL_ELEMENTS-2);d++)

    makes it work as expected.

  2. I thought the following program was a perfect C program. But on compiling, I found a silly mistake. Can you find it out (without compiling the program :-) ?
    #include<stdio.h>

    void OS_Solaris_print()
    {
    printf("Solaris - Sun Microsystems\n");
    }

    void OS_Windows_print()
    {
    printf("Windows - Microsoft\n");

    }
    void OS_HP-UX_print()
    {
    printf("HP-UX - Hewlett Packard\n");
    }

    int main()
    {
    int num;
    printf("Enter the number (1-3):\n");
    scanf("%d",&num);
    switch(num)
    {
    case 1:
    OS_Solaris_print();
    break;
    case 2:
    OS_Windows_print();
    break;
    case 3:
    OS_HP-UX_print();
    break;
    default:
    printf("Hmm! only 1-3 :-)\n");
    break;
    }

    return 0;
    }
    A: There's a dash in the function name void OS_HP-UX_print(). C does not accept dashes in function names. It must be deleted or changed by an underscore for the program to work.
  3. What's the expected output for the following program and why?
    enum {false,true};

    int main()
    {
    int i=1;
    do
    {
    printf("%d\n",i);
    i++;
    if(i < 15)
    continue;
    }while(false);
    return 0;
    }
    A: Output: 1 The continue statement passes control to the next iteration of the nearest enclosing do, for, or while statement in which it appears. Within a do or a while statement, the next iteration starts by reevaluating the expression of the do or while statement. In this case, the expression is false so there are no more iterations.
  4. The following program doesn't "seem" to print "hello-out". (Try executing it)
    #include <stdio.h>
    #include <unistd.h>
    int main()
    {
    while(1)
    {
    fprintf(stdout,"hello-out");
    fprintf(stderr,"hello-err");
    sleep(1);
    }
    return 0;
    }
    A: What is sent to stdout is kept in a buffer and is printed until a newline is sent. If the program ends without sending a newline to stdout nothing is printed. What is sent to stderr is printed immediatly. That's why just "hello-err" is printed. Change "hello-out" for "hello-out\n" to print it.
  5. Consider the following:
    #include <stdio.h>
    #define f(a,b) a##b
    #define g(a) #a
    #define h(a) g(a)

    int main()
    {
    printf("%s\n",h(f(1,2)));
    printf("%s\n",g(f(1,2)));
    return 0;
    }

    Just by looking at the program one "might" expect the output to be the same for both the printf statements. But on running the program you get it as: 12 f(1,2)

    A: The definitions at the beggining are macros, read by the C preprocesor. The transforming or "evaluating" of a macro into a sequence is known as expansion. The parameter of a function-like macro is expanded unless it is the operand # or ##. Because g's parameter is the operand #, the argument is not expanded but instead immediately stringified "f(1,2)". Because h's parameter is not the operand # nor ##, the argument f(1,2) is expanded (12), then substituted (g(12)). Then the code is rescanned and further expansion occurs ("12").

    Source: stackoverflow.com/questions/4364971/and-in-macros

  6. Consider the following:
    #include<stdio.h>
    int main()
    {
    int a=10;
    switch(a)
    {
    case '1':
    printf("ONE\n");
    break;
    case '2':
    printf("TWO\n");
    break;
    defa1ut:
    printf("NONE\n");
    }
    return 0;
    }

    If you expect the output of the above program to be NONE, I would request you to check it out!!

    A: The program doesn't print anything because the switch has no default case. It says "defau1t", not "default" so it is simply ignored. It is not a syntax error as it is treated as a normal C label.
  7. The following C program segfaults on IA-64, but works fine on IA-32.
    int main()
    {
    int* p;
    p = (int*)malloc(sizeof(int));
    *p = 10;
    return 0;
    }

    Why does it happen so?

    A: It happens because on IA-64 a pointer takes up 64 bits, more than an integer (32 bits). Without the header file stdlib.h the return type of malloc is assumed to be integer, not pointer (int is the default return type in C). The returned 64 bits are truncated to 32 and then the line p = (int*)malloc(sizeof(int)); casts it to a 64 bit pointer. This, of course, damages the pointer causing a segfault when trying to write. Add stdlib.h to tell C to expect a pointer returned from malloc and fix the problem.
  8. Here is a small piece of program(again just 14 lines of program) which counts the number of bits set in a number.
    Input   Output
    0 0(0000000)
    5 2(0000101)
    7 3(0000111)
    int CountBits (unsigned int x )
    {
    static unsigned int mask[] = { 0x55555555,
    0x33333333,
    0x0F0F0F0F,
    0x00FF00FF,
    0x0000FFFF
    };

    int i ;
    int shift ; /* Number of positions to shift to right*/
    for ( i =0, shift =1; i < 5; i ++, shift *= 2)
    x = (x & mask[i ])+ ( ( x >> shift) & mask[i]);
    return x;
    }

    Find out the logic used in the above program.

    A: This algorithm counts the number of ones in a number in binary. It does so by "dividing" the original number in pairs of bits and adding both bits of each pair. It keeps adding the results until there are no more groups to add. For example, for 11010101:
    | 1 + 1 | 0 + 1 | 0 + 1 | 0 + 1 |  
    | 1 0 + 0 1 | 0 1 + 0 1 |
    | 0 0 1 1 + 0 0 1 0 |
    | 0 0 0 0 0 1 0 1 |

    The code given doesn't look as intuitive because it uses masks to add the groups of bits, optimizing the number of operations. Take, for example, the first iteration. The first mask is 0x55555555 = 01010101...0101 The logical AND of this mask and x (x & mask[1]) makes zero all odd positions of x:

      1 1 0 1 0 1 0 1
    & 0 1 0 1 0 1 0 1
    = 0 1 0 1 0 1 0 1

    Shifting x to the right and then applying the mask to get ((x >> shift) & mask[1]) makes zero all even positions:

      1 1 1 0 1 0 1 0
    & 0 1 0 1 0 1 0 1
    = 0 1 0 0 0 0 0 0

    Now adding up to get (x & mask[1])+ ((x >> shift) & mask[1]):

      0 1 0 1 0 1 0 1
    + 0 1 0 0 0 0 0 0
    = 1 0 0 1 0 1 0 1

    This effectively adds up each pair of bits in x as it ends up adding each odd position to the next (even) position of the original number. The masks used on next iterations are then 00110011, 00001111... and so on.

  9. What do you think would be the output of the following program and why? (If you are about to say "f is 1.0", I would say check it out again)
    #include <stdio.h>

    int main()
    {
    float f=0.0f;
    int i;

    for(i=0;i<10;i++)
    f = f + 0.1f;

    if(f == 1.0f)
    printf("f is 1.0 \n"
    else
    printf("f is NOT 1.0\n");

    return 0;
    }
    A: Output: f is NOT 1.0 Floats can't represent value 0.1 exactly because it has an infinite binary expansion the same way 1/3 has an infinite decimal expansion. 0.1 in binary is 0.000110011001100110011001100... When truncated, the decimal value used is approximately 0.100000001490116119. So after the for loop f has a value near but not exactly 1.0. The number must be compared using a narrow interval close to 1.0. A function used to compare floats is:
    #define EPSILON 0.00001f
    inline int floatsEqual(float f1, float f2)
    {
    return fabs(f1 - f2) < EPSILON; // or fabsf
    }

    Source: stackoverflow.com/questions/9577179/c-floating-point-precision

  10. I thought the following C program was perfectly valid (after reading about the comma operator in C). But there is a mistake in the following program, can you identify it?
    #include <stdio.h>

    int main()
    {
    int a = 1,2;
    printf("a : %d\n",a);
    return 0;
    }
    A: The mistake is on the line int a = 1,2;. Comma in C may act as an operator or as a separator deppending on context. Comma acts as a separator when used with function calls and definitions, function like macros, variable declarations, enum declarations, and similar constructs. So here the comma is a separator, not an operator because the variable "a" is being declared. C expects another variable name after the comma: int a = 1, b = 2;. The line a = 1, 2; is also valid.

    Source: www.geeksforgeeks.org/comna-in-c-and-c/

  11. What would be the output of the following C program? (Is it a valid C program?)
    #include <stdio.h>
    int main()
    {
    int i=43;
    printf("%d\n",printf("%d",printf("%d",i)));
    return 0;
    }
    A: It is a valid C program. Its output is 4321. It's valid because printf's return type is integer. This allows nesting printfs that way. The innermost printf prints 43 and returns the number of printed characters: 2. This is printed by the second printf which returns 1, printed by the outermost printf.
  12. Consider the following:
    void duff(register char *to, register char *from, register int count)
    {
    register int n=(count+7)/8;
    switch(count%8){
    case 0: do{ *to++ = *from++;
    case 7: *to++ = *from++;
    case 6: *to++ = *from++;
    case 5: *to++ = *from++;
    case 4: *to++ = *from++;
    case 3: *to++ = *from++;
    case 2: *to++ = *from++;
    case 1: *to++ = *from++;
    }while( --n >0);
    }
    }

    Is the above valid C code? If so, what is it trying to acheive and why would anyone do something like the above?

    A: It is valid C code, known as the Duff's Device. It is a memory-to-memory copy speed optimized alogorithm that copies "count" bits beggining at adress "from" into adress "to". It's an example of loop unrolling or unwinding, which tries to reduce the frequency of branches and loop maintenance instructions at the expense of making the code longer. An unoptimized but simpler code would be:
    do { 
    *to++ = *from++;
    } while(--count > 0);

    See Duff's Device Wikipedia article for more information on why C allows to write a do-while loop inside a switch statement.

  13. Here is yet another implementation of CountBits. Verify whether it is correct (how do you that???). If so, find out the logic used.
    int CountBits(unsigned int x)
    {
    int count=0;
    while(x)
    {
    count++;
    x = x&(x-1);
    }
    return count;
    }
    A: The code is correct. It counts the numbers of bits set in x. The while loop iterates once for each 1 bit of the original x because the line x = x&(x-1); reduces the number of bits by one each time. When doing logical and of x and x-1 the rightmost 1 bit is always changed to 0, for example:
      10011010
    & 10011001
    = 10011000

    This is repeated until x is zero.

  14. Are the following two function prototypes same?
    int foobar(void);
    int foobar();

    The following programs should be of some help in finding the answer: (Compile and run both the programs and see what happens) Program 1:

    #include <stdio.h>
    void foobar1(void)
    {
    printf("In foobar1\n");
    }

    void foobar2()
    {
    printf("In foobar2\n");
    }

    int main()
    {
    char ch = 'a';
    foobar1();
    foobar2(33, ch);
    return 0;
    }

    Program 2:

    #include <stdio.h>
    void foobar1(void)
    {
    printf("In foobar1\n");
    }

    void foobar2()
    {
    printf("In foobar2\n");
    }

    int main()
    {
    char ch = 'a';
    foobar1(33, ch);
    foobar2();
    return 0;
    }
    A: The function prototypes are different. When using void the function cannot receive parameters. Passing a parameter results in a "too many arguments to function 'foobar1'" compiling error (program 2). When using int foobar() prototype parameters may be passed to the function, but will just be ignored. Then program 1 is valid.
  15. What's the output of the following program and why?
    #include <stdio.h>
    int main()
    {
    float a = 12.5;
    printf("%d\n", a);
    printf("%d\n", *(int *)&a);
    return 0;
    }
  16. A: Output: 0 1095237632 The first printf takes a float and prints it as integer. This causes print f to print "0". The second printf takes the address of a float, casts it to an integer pointer and then dereferences that as an integer. There are problems here as an integer pointer may not have the same size of a float pointer. The representations of integers and floats are also different. The behaviour may be differente depending on the compiler, but in most cases the second printf will print a big strange number.

    Source: stackoverflow.com/questions/6574134/unexpected-output-printing-a-float-cast-as-an-int

  17. The following is a small C program split across files. What do you expect the output to be, when both of them compiled together and run? File1.c
    int arr[80];

    File2.c

    extern int *arr;
    int main()
    {
    arr[1] = 100;
    return 0;
    }
    A: Pointer and arrays are not the same. Declaring with extern int *arr tells C to use the bytes at location "arr" as if they point to something. However an array was defined there with int arr[80]; and array data is stored there, not a pointer. The result is that the first bytes of the array ("garbage") are dereferenced as if they were a pointer producing a segfault.

    The solution is to make both the declaration and the definition the same with, for example extern int arr[] . This way C knows it is an array.

  18. Explain the output of the following C program (No, the output is not 20).
    #include<stdio.h>
    int main()
    {
    int a=1;
    switch(a)
    {
    int b=20;
    case 1: printf("b is %d\n",b);
    break;
    default:printf("b is %d\n",b);
    break;
    }
    return 0;
    }
    A: Depending on the compiler there could be a warning message ("unreachable code at beginning of switch statement") or no messages at all. The output is a random integer (garbage). The line int b=20; is never executed because the switch jumps to a case (or default if there are no cases). b is therefore not initialized. Move the line right above the switch statement to get 20 as output. There is no "b not declared error" because of the inner workings of the compiler. When it gets to int b it sets up a variable b before assigning a value to it. The line isn't completely ignored: b is declared but not initialized.

    Source: stackoverflow.com/questions/1683417/variable-declared-and-initialized-in-a-switch-statement

  19. What is the output of the following program? (Again, it is not 40, (if the size of integer is 4)).
    #define SIZE 10
    void size(int arr[SIZE])
    {
    printf("size of array is:%d\n",sizeof(arr));
    }

    int main()
    {
    int arr[SIZE];
    size(arr);
    return 0;
    }
    A: The output is "size of array is:4". arr is passed to the function by reference. A pointer, which takes up 4 bytes is sent to the function so in its context sizeof(arr) is 4. Moving the printf line to main() outputs the expected value of 40.
  20. The following is a simple c program, in which there is a function called Error to display errors. Can you see a potential problem with the way Error is defined?
    #include <stdlib.h>
    #include <stdio.h>
    void Error(char* s)
    {
    printf(s);
    return;
    }

    int main()
    {
    int *p;
    p = malloc(sizeof(int));
    if(p == NULL)
    {
    Error("Could not allocate the memory\n");
    Error("Quitting....\n");
    exit(1);
    }
    else
    {
    /*some stuff to use p*/
    }
    return 0;
    }
    A: When compiling a warning is generated because printf(s) expects a string literal as its first argument, not a char*. Changing this line to printf("%s", s); does the job as it passes a string literal as first argument. The following arguments may be strings if the correct modifier is used.
  21. What is the differnce between the following function calls to scanf? (Please notice the space carefully in the second call. Try removing it and observe the behaviour of the program)
    #include <stdio.h>
    int main()
    {
    char c;
    scanf("%c",&c);
    printf("%c\n",c);

    scanf(" %c",&c);
    printf("%c\n",c);

    return 0;
    }
    A: The first scanf scans just for a character. If there is no space before %c, when Enter is pressed the first scanf captures the character, but the newline character \n is kept and captured by the second scanf. This is normally undesired and is fixed by adding the space. Keep in mind that newlines, spaces and tabs are characters. The space makes the second scanf scan for one or more whitespace characters followed by any character. Because the newline is whitespace character, the space "eats" it and the next character is captured as expected.
  22. What is the potential problem with the following C program?
    #include <stdio.h>
    int main()
    {
    char str[80];
    printf("Enter the string:");
    scanf("%s",str);
    printf("You entered:%s\n",str);

    return 0;
    }
    A: The problem is that %s scans for any number of non-whitespace characters, stopping at the first whitespace character found. This means that just the first word will be captured. To capture a complete line use scanf("%[^\n]",str); which captureseverything until a newline character is entered.
  23. What is the output of the following program?
    #include <stdio.h>
    int main()
    {
    int i;
    i = 10;
    printf("i : %d\n",i);
    printf("sizeof(i++) is: %d\n",sizeof(i++));
    printf("i : %d\n",i);
    return 0;
    }
    A: Output:
    i : 10
    sizeof(i++) is: 4
    i : 10

    The expression in a sizeof is not evaluated because sizeof is not a function, but a compile-time operator. Only its operand's type is used to determine size. The sizeof(i++) expresion is then replaced by a constant, so there is no "++" at run-time.

    Source: stackoverflow.com/questions/1581839/whats-the-mechanism-of-sizeof-in-c-c

  24. Why does the following program give a warning? (Please remember that sending a normal pointer to a function requiring const pointer does not give any warning)
    #include <stdio.h>
    void foo(const char **p) { }
    int main(int argc, char **argv)
    {
    foo(argv);
    return 0;
    }
    A: A char** is being passed to a function that requires a const char**. A pointer to a constant is one through which one cannot change the value of variable it points. These pointers can change the address they point to but cannot change the value kept at those addresses. This is known as const-correctness. There is no cast from char** to const char** even when there is between char* and const char* because it would not be const-correct. If this assignment was allowed the following code would be valid:
    char const        c = 'a';
    char* p = 0;
    char const** pp = &p; // not allowed in C

    *pp = &c; // p now points to c.
    *p = 'b'; // changing a const value!

    Source: stackoverflow.com/questions/7016098/implicit-cast-from-char-to-const-char

  25. What is the output of the following program?
    #include <stdio.h>
    int main()
    {
    int i;
    i = 1,2,3;
    printf("i:%d\n",i);
    return 0;
    }
    A: Output: i:1 Here comma acts as a separator. It separates expressions and returns the value of the expression to its right. i = 1,2,3; is equivalent to (i=1),2,3;. The whole line evaluates to the last expression: 3, but it is not being stored. i = (1,2,3); stores 3 into i.

    Source: en.wikipedia.org/wiki/Comma_operator

  26. The following is a piece of code which implements the reverse Polish Calculator. There are serious bugs in the code. Find them!!! Assume that the function getop returns the appropriate return values for operands, opcodes, EOF etc...
    #include <stdio.h>
    #include <stdlib.h>

    #define MAX 80
    #define NUMBER '0'

    int getop(char[]);
    void push(double);
    double pop(void);
    int main()
    {
    int type;
    char s[MAX];

    while((type = getop(s)) != EOF)
    {
    switch(type)
    {
    case NUMBER:
    push(atof(s));
    break;
    case '+':
    push(pop() + pop());
    break;
    case '*':
    push(pop() * pop());
    break;
    case '-':
    push(pop() - pop());
    break;
    case '/':
    push(pop() / pop());
    break;
    /* ...
    * ...
    * ...
    */
    }
    }
    }
    A: Reverse Polish notation is a mathematical notation in which every operator follows all of its operands. Here the operands are stacked and accessed when an operator is processed. In case '-' and case '/' the expected output is the first operand minus/divided by the second one. Supposing it's a LIFO stack the order is incorrect. The second operand (last stacked) should be substracted from the first one:
    case '-':
    op2 = pop();
    push(pop() - op2);
    break;
    case '/':
    op2 = pop();
    if (op2 != 0.0)
    push(pop() / op2);
    else
    printf("error: zero divisor\n");
    break;

    This code also checks if the second operand is zero, to avoid trying to divide by zero.

The C puzzles questions, by CH Gowri Kumar are licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.

· 10 min read
Jose Vargas
Icarus Verilog is a Verilog standard IEEE-1364 compiler that targets Linux but works almost as well on Windows. It's lightweight, free software and includes a virtual machine that simulates the design. This tutorial goes through the process of downloading, installing and using Icarus Verilog to write a simple program, compile it, simulate it and view the simulation results on a timing diagram. It assumes no previous knowledge on Verilog, but prior programming experience is recommended.

Installing Icarus Verilog

Download Icarus Verilog latest stable release for Windows from: bleyer.org/icarus

Installing Icarus Verilog is as easy as installing any other Windows program. Just hit next, but be sure to select GTK Wave (full installation) and "Add Executables to Windows Path" option. You should be able to use it from a Command Prompt by now. On Windows Vista/7/8 press Windows key and type cmd to open a command prompt. Just type "iverilog" and you should get a message saying "iverilog: no source files" and some instructions. Type "gtkwave" and the GTKWave GUI should open. This program is used to view the simulation results graphically on a timing diagram.

If these commands are not recognized but the installation was successful chances are the executables were not added to Windows Path. See How to set the Path on Windows to add "C:\iverilog\bin" to Path manually.

Writing a simple program

Now you are ready to write your first Verilog program. For this tutorial we'll write a D type flip-flop description, that is, a Verilog module that works like a D flip-flop. At the same time you'll learn some of the basic Verilog concepts by example.  You'll also write a tester module to reproduce the following D flip-flop timing diagram:

D type flip-flop timing diagram

Verilog programs are separated in modules, which are functional blocks that have inputs, outputs and internal logic. You can think of them like the blocks on a circuit's block diagram, but in this case they work. There are two types of Verilog modules: behavioral modules and structural modules. Both may have the same behaviour but are different in the way they are written as you'll see throughout the example.

For the flip-flop program three modules are used: the flip-flop module, tester module and testbench module. The last two are modules you'll need on almost every design in order to test your circuit.

Flip-flop module

Represents a simple D type flip-flop. Receives a clock signal and D signal as inputs and outputs Q and QN signals. The outputs may change on the positive clock edge. The code for this module is:

module dff(d,clk,q,qn);
input d,clk;
output q,qn;
reg q,qn;

//Initialize flip-flop outputs
initial begin q=0; qn=1; end

//Change output on positive clock edge
always @(posedge clk)
begin
q &lt;= d;
qn &lt;= !d;
end

From this code, you can see the basic structure of every Verilog module. It starts with a declaration: module dff(d,clk,q,qn); and ends with endmodule. The declaration states the module's name and both its inputs and outputs. In the module we must declare which variables are inputs and which are outputs, using "input" and "output".

Variables in Verilog are wires or regs. A wire, like a real wire, has no memory. Thus Verilog wire variables do not retain their values by themselves. The reg keyword gives variables the ability to hold their values after they are assigned, until their value is changed, of course. We want this behaviour for the flip-flop's outputs so q and qn are defined as regs. If we use a wire the output is never seen by other blocks. It loses its value immediatly after any assignment. There is no need to define variables as wires, because they are all wires by default.

The way the inner logic of the module is written deppends on wether it is behavioral or structural. The flip-flop module is an example of behavioral code. That is, you describe the behavior the module should have. To do it, use initial and always blocks. The code within an initial block is executed once, when the flip-flop is created. In the example it's used to define q=0 and qn=1 initially. By default in Verilog the variables are undefined (represented by an "x"), not zero, not one. If we did'nt use this initial block q and qn would be left undefined until they are assigned for the first time.

The code within an always block is executed when a condition is met. In this case, when the clock has a positive edge, q and qn are reassigned. This describes completely the flip-flop's logic. As you can see, it is simple. When the condition is not met, Verilog keeps the outputs' values.

As a rule of thumb, when writing a behavioral module, define outputs as wires.

Verilog has control structures like while, if-else, case, for and repeat (similar to for) like most programming languages. These assist you on writting your behavioral code. For example, replacing the flip-flop module's always block by:

begin
if(clk == 1)
begin
q &lt;= d;
qn &lt;= !d;
end
end

produces exactly the same behaviour. Some things changed. Now the always condition is always @(clk) instead of always @(posedge clk) . This means that now the always block is executed every time clk changes its value, on positive and negative edges. An always block can be triggered by any number of variables. For example, @(clk or d) would trigger it whenever clk or d change. This is used in combinational logic where the output is recalculated whenever an input changes. Back to the example, if clk == 1 then the edge is positive. We check it using an if statement. Note that adding the "begin" and "end" keywords is necessary when any block (always, initial, if, for...) has more than one instruction. If omitted for the "if" statement above the second instruction: qn <= !d; would be executed always (it would be ouside of the if statement). These two keywords act like the curly brackets on many programming languages.

Tester module

This module tests the flip-flop by generating the clock and D signal of the timing diagram above and dumping the Q and QN signals of the flip-flop. It's outputs are the flip-flop's inputs and viceversa.

flip-flop
module tester(q,qn,clk,d);
input q,qn;
output clk,d;
reg clk,d;

//Run the test once
initial
begin
clk=0;
//Dump results of the simulation to ff.cvd
$dumpfile("dff.vcd");
$dumpvars;
//Generate input signal d
d=0; #9 d=1; #1 d=0; #1 d=1; #2 d=0; #1 d=1; #12 d=0;
#1 d=1; #2 d=0; #1 d=1; #1 d=0; #1 d=1; #1 d=0; # 7 d=1;
#8 $finish;
end

//Generate periodic clock signal
always
begin
#4 clk=!clk;
end
endmodule

This module is behavioral too as we have initial and always blocks. You should be able to undestand most of the code. However, there are a few new concepts here. The $dumpfile and $dumpvars commands tell the Verilog simulator (more on this ahead) to log the module's variables to the specified file, "dff.vcd" in this case. You may also be wondering what the #s do. These are Verilog delays. The delay the following instruction by a given amount of time. For example, #4 clk=!clk; within an always block changes "clk" every four time units from 0 to 1, producing a square wave. The time unit is a second by default.

Without using delays there is no way of making the program work. This is the way to control time in the design. You may add delays to any instruction. For example, you could model the flip-flop's delay by adding some to its always block. It's now easy to understand how the d=0; #9 d=1; #1 d=0; #1 d=1; ... lines produce the D signal we want.

Finally, the $finish command tells the simulator to stop the simulation once the D signal was generated. If this command was omitted the simulation would continue indefinetly because this time the always block has no condition (there is no @ like in the flip-flop module).

Testbench module

This module just connects the tester module to the flip-flop module:

module
module testbench;
wire clk,d,q,qn;
dff ff1(d,clk,q,qn);
tester tst1(q,qn,clk,d);
endmodule

It is the most simple of the modules, but it's very different. This time it's structural code, that is, you define the structure of the circuit. It's like describing the circuit diagram. In this case the final circuit is simply the flip-flop connected to the tester. To create a flip flop use dff ff1(d,clk,q,qn);. First goes the module name, followed by the part name, which could be almost any string, followed by the wires that connect to the module in parenthesis. These must follow the order in the module's declaration. In a structural module we use wires. Regs are not necessary because they are defined inside the different modules.

Compiling and simulating

Go ahead and copy/paste the modules into a text file, order doesn't matter. Call the file "dff.v". The .v extension is standard for Verilog files, but isn't required by the compiler. To compile open a Command Prompt at your working directory (where you saved the file). A quick way to open a command prompt at any directory is to hold shift and right-click the folder, then click "Open Command Window Here". Type:

iverilog -o dff dff.v

The "-o" tells Icarus Verilog to "save output to the following file". The output is then saved to "dff". This file is not executable. It has to be run using vvp, the Icarus Verilog simulator which is the one that actually produces simulation results, zeros and ones for each of the model variables, as a function of time. To run the simulation type:

vvp dff

This is what outputs the dff.vcd file with all the simulation results. However if you open this file with your text editor you'll see it's not easy to understand. To generate an easy-to-understand timing diagram from this file we use GTKWave.

GTKWave does have a GUI. To open it press Windows key and type "gtkwave". Then click File -> Open New Tab and chose the ffd.vcd file. Now you must add the variables in order to see their timing diagram. Click on "testbench" at the left (SST panel) and then select all the variables using Ctrl or Shift and "Insert" them.

If everything is okay you should get a timing diagram exactly as the one at the beggining of the tutorial, just like the following:

Icarus Verilog simulation results shown using GTKWave

When testing your programs you'll have to go to the compiling-simulating-loading process every few minutes. Remember you can use the up-down arrow keys while in the command prompt to access the last commands and compile/simulate. On GTKWave use File->Reload Waveform to reload the .vcd file and refresh the timing diagrams without having to reload each variable. By using these tips the whole proccess will take you a few seconds.

It's over. Now feel free to change the code around to see what happens. Mastering the use of delays, wires and regs takes some time. See Verilog in One Day for a more in depth explanation of the language.