Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
10 years ago

This verilog code does not work on FPGA

Hi, I'm new here, so if there's anything wrong with my post, please, feel free to tell me.

I'm taking logic design class at my school, learning to design logic gates and verilog, and trying it on FPGA.

My recent assignment was about building a coffee machine that takes in 100, 500, 1000 cash up to 2000.

(The money we're using here is Korean money, so don't get confused with dollars.)

It has coffee-out and change-out button.

One cup of coffee costs 600.

I'm using SW[0]~SW[4] for the money-in and the other buttons, and SW[9] as a reset button.

The following code compiled without any errors on Quartus and the wave forms came out correctly on ModelSim.

But it did not work on FPGA.

The board that we're using in our class is Cyclone III EP3C16F484C6

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


module lab7(
    input reg  SW,
    input reg CLOCK_50,
    output reg  HEX0_D, HEX1_D, HEX3_D);
    
    reg cs, ns, pulse, a;
        reg  sum;
    wire  mod10;
        wire h, f, t, cff, chg;
    
    //set wires for each input
    assign h = SW;    //hundred won
    assign f = SW;    //five hundred won
    assign t = SW;    //thousand won
    assign cff = SW;    //coffee out
    assign chg = SW;    //change out
    
    //state parameters
    parameter s0 = 0;
    parameter s1 = 1;
    
    //mealy FSM one pulse generator
    always@(*)
     a = SW ? 0 : h || f || t || cff; 
    
    always@(posedge CLOCK_50, posedge SW)
    begin
        if (SW)    cs <= s0;
        else        cs <= ns;
    end
    
    always@(*)
    begin
        case(cs)
            s0:begin
                    ns = a ? s1 : s0;
                    pulse = a;
                end
            s1:begin
                    ns = a ? s1 : s0;
                    pulse = 0;
                end
        endcase
    end
    //end of FSM
    
    //sum of money
    always@(*)
    begin
        if(SW||chg)    sum = 0;    //initialization and when change out button is on
        else if (sum<0)
            sum = 0;            //negative numbers are set to zero
        else if (sum<21)
        begin
            if(h)                    //add hundred won
                sum = pulse ? sum + 1 : sum;
            else if(f)                //add five hundred
                sum = pulse ? sum + 5 : sum;
            else if(t)                //add thousand
                sum = pulse ? sum + 10 : sum;
            else if(cff&&sum>5)           //coffee out and subtract by 6 only if sum>5
                sum = pulse ? sum - 6 : sum;
            else sum = sum;
        end
        else sum = 20;                //sum greater than 20 are set to 20
    end
    
    //output for HEX0_D
    assign mod10 = sum%10;        //sum on one's position
    always@(*)
    begin
        case(mod10)
            0 : HEX0_D = 7'b100_0000; //0
            1 : HEX0_D = 7'b111_1001; //1
            2 : HEX0_D = 7'b010_0100; //2
            3 : HEX0_D = 7'b011_0000; //3
            4 : HEX0_D = 7'b001_1001; //4
            5 : HEX0_D = 7'b001_0010; //5
            6 : HEX0_D = 7'b000_0010; //6
            7 : HEX0_D = 7'b111_1000; //7
            8 : HEX0_D = 7'b000_0000; //8
            9 : HEX0_D = 7'b001_1000; //9
        endcase
    end
    
    //output for HEX1_D
    always@(*)
    begin
        if(sum<10)        HEX1_D = 7'b100_0000; //0
        else if(sum<20)    HEX1_D = 7'b111_1001; //1
        else            HEX1_D = 7'b010_0100; //2
    end
    
    //output for HEX3_D
    always@(*)
    begin
        if (sum<6)        HEX3_D = 7'b100_0000; //0
        else if (sum<12)    HEX3_D = 7'b111_1001; //1
        else if (sum<18)    HEX3_D = 7'b010_0100; //2
        else            HEX3_D = 7'b011_0000; //3
    end
endmodule
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
According to the professor, I'm using an asyncronous design on the 'sum of money' part, which we haven't covered on our lessons yet.
I realized that I assigned the values so that sum feeds back itself without any flip-flops.
So I changed that part just a little:
    //sum of money
    always@(posedge CLOCK_50, posedge SW, posedge chg)
    begin
        if(SW||chg)    sum <= 0;    //initialization and when change out button is on
        else if (sum<0)
            sum <= 0;                    //negative numbers are set to zero
        else if (sum<20)
        begin
            if(h)                    //add hundred won
                sum <= pulse ? sum + 1 : sum;
            else if(f)                //add five hundred
                sum <= pulse ? sum + 5 : sum;
            else if(t)                //add thousand
                sum <= pulse ? sum + 10 : sum;
            else if(cff&&sum>5)           //coffee out and subtract by 6 only if sum>5
                sum <= pulse ? sum - 6 : sum;
            else sum <= sum;
        end
        else sum <= 20;                //sum greater than 20 are set to 20
    end

I'm not sure if this is the correct way of doing it

Can anyone help me out on here?

The Quartus version I'm using is Quartus II 64-bit version 13.1.0 Build 162 10/23/2013 SJ Web Edition

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Sorry, I forgot to post about the errors shown on the hardware.

The function that I want the board to work is to show,

1) the number of coffees I can get from the sum of money I've put into the machine

- which is displayed on HEX3

2) the total sum of money divided by hundred (so it should show 1 for 100, and 12 for 1200)

- this is displayed on HEX1 and HEX0

The problem is that when the verilog code is downloaded to the board, it shows 3 on HEX3 and 20 on HEX1, HEX0

which says that I can take out 3 coffees and the total sum of money is 2000.

This is the initial state when everything is set up.

When I raise the reset switch, SW[9], or change-out switch, SW[4], everything goes back to 0.

However, if I raise any switch to put in the money, it instantly goes back to the original problem that showed 3, 20.

And from there, nothing works except the reset and change-out switches.

8 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi,

    If the design can pass Quartus II compilation and Modelsim simulation show no issue, it means that there is no issue with design implemenation into the Cyclone III and functionality should be ok. Probably you might need to further elaborate the error observation that you are having ie LED status is wrong or?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Once you got the codes compiled ok, you should assign your pins correctly according to your dev kit.

    Maybe that explains why you got it ok in Quartus compilation and modelsim, but not the hardware.

    Still need more input from you to know what is the real problem.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    The Sum value is unregistered, meaning you'll have a logic loop in your design. Ie. one input to the adder is it's own output, meaning it will do the sum over and over again depending on the delay through the adder.

    You need to register the sum value.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Have you tried Design Assistant Tool which is a part of Quartus II software? I believe it gives you some advices.

    http://quartushelp.altera.com/15.0/mergedprojects/verify/da/comp_view_doctor.htm

    Here are some hints for you.

    1) Other than CLOCK_50 and sw[9], all signals must be synchronous to CLOCK_50 otherwise you will see malfunction in the real world. Don't do "if(h)".

    2) Signal Tap II, which is also a part of Quartus II software, is a very powerful tool which allows us to monitor signals on the hardware. You can see what happens in the FPGA.

    3) I'm not sure if you have leant anti-chatter circuit. If input signals are connected to external push buttons or switches, you must remove chatter.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Sry I forgot to post that

    The thread is updated with the problem explanation at the bottom

    (For some reason, I can't view the edited post above; hope it comes up later)
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    Once you got the codes compiled ok, you should assign your pins correctly according to your dev kit.

    Maybe that explains why you got it ok in Quartus compilation and modelsim, but not the hardware.

    Still need more input from you to know what is the real problem.

    --- Quote End ---

    I updated the post and wrote about the problems shown on the hardware.

    Sry I didn't do that earlier
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    The Sum value is unregistered, meaning you'll have a logic loop in your design. Ie. one input to the adder is it's own output, meaning it will do the sum over and over again depending on the delay through the adder.

    You need to register the sum value.

    --- Quote End ---

    That's actually what my professor told me, except he explained it with tons of details that I had no idea about.

    I'll try to change the "sum of money" part a little more so it doesn't get the loop.

    Thank you for the reply
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    Have you tried Design Assistant Tool which is a part of Quartus II software? I believe it gives you some advices.

    http://quartushelp.altera.com/15.0/mergedprojects/verify/da/comp_view_doctor.htm

    Here are some hints for you.

    1) Other than CLOCK_50 and sw[9], all signals must be synchronous to CLOCK_50 otherwise you will see malfunction in the real world. Don't do "if(h)".

    2) Signal Tap II, which is also a part of Quartus II software, is a very powerful tool which allows us to monitor signals on the hardware. You can see what happens in the FPGA.

    3) I'm not sure if you have leant anti-chatter circuit. If input signals are connected to external push buttons or switches, you must remove chatter.

    --- Quote End ---

    I never knew there was an Assistant Tool lol. I'll try that right away and update the post as soon as I get the results

    1) I haven't gone through asynchronous design in my class yet, so I don't understand how making the asynchronous causes problems on the circuit board.

    But I got some good feedbacks from other replies; maybe I'll try those first and see what's gonna happen.

    2) The FPGA that I'm using in the class is actually the professor's lab equipment. I'll try that feature on my next try.

    3) I haven't learned about anti-chatter circuit.