Forum Discussion

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

Newbie Help Request CPLD MAXII

Hi all.

I want to build a digital clock, with several 7 segments displays (HH:mm:ss). How can i make the 1s clock to drive my 4bits counters?

My board has a 50Mhz clock. How can i make 1s precisely?

- Frequency dividers?

- Counters?

I'm programing in Block Diagram File.

What is the best language? VHDL, Verilog, BDF? As i am new in this, it would be very good to start with the best language.

Regards

Mrmike

7 Replies

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

    Well don't start by asking what the best language is (because everybody knows it's Verilog). No really you may start a battle. If you want your skills to be broadly useful than chosse Verilog or VHDL.

    Well now ... 50MHz = 50,000,000 clocks per second. So technically all you have to do is write a counter that counts to 50,000,000 and that equals one second. In reality however, the accuracy of this calculation depends entirely on the accuracy of the crystal producing the 50MHz clock. Crystals come with specified tolerances. When someone designs a product that requires extremely accurate timing, they choose a low frequency crystal with a tight tolerance. So in reality you'd like to have a crystal in the low kHz range with an extremely tight tolerance.

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

    Anyway, you could write your own divider by 50,000,000 as an exercise. Try to write it in Verilog to start with an HDL language. The frequency accuracy in ppm will be the same as the one guaranteed by your crystal oscillator.

    You can use the Quartus II templates to start learning.

    Once you have created your .v file go to

    Edit>Insert Template and browse the available templates.

    Cheers

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

    Thanks for your reply,

    I've already typed my first verilog program :)

    What do you think about this?

    module clk1s (CLOCK_50,LED);

    input CLOCK_50;

    output LED;

    reg LED;

    integer count;

    wire CLOCK_50;

    always @ (posedge CLOCK_50)

    begin

    count = count + 1;

    if (count >= 50000000)begin

    LED = ~LED;

    count = 0;

    end

    end

    endmodule

    Is there a simplest/better solution?

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

    module clk1s (
        input           CLOCK_50,
        input           reset,
        output  reg     LED
    );
    localparam  COUNTDOWN = 49999999;
    reg   count;
    always @ (posedge CLOCK_50 or posedge reset)
        if(reset) begin
                    count   <= COUNTDOWN;
                    LED     <= 1'b0;
        end else begin
                    count   <= count + {26{1'b1}};    // same as minus 1
            if(!count) begin 
                    count   <= COUNTDOWN;
                    LED     <= ~LED;
            end
        end
    endmodule 
    

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

    Your design will work (you've probably tried it). Here are some recommendations. With this small design you're okay but for a beginner I would encourage you to adhere to a few things as you are learning Verilog.

    1 - As a general practice, use resets on your synchronous blocks. For instance, you'll find this design difficult to simulate in say Modelsim as no initial value for "count" is specified. There are some cases where it makes sense not to put a reset on a synchronous block but when you get to that point you'll know.

    2 - The difference between blocking and non-blocking assignments. Learn the difference now. You've used blocking assignments in your design. In this case they will work just fine. However, as a rule for beginners I encourage them to use only non-blocking assignments inside of a synchronous block. It changes the way the code behaves and can affect simulation under certain circumstances. For example, if you just changed your design to use non-blocking assignments, it would not work. You would count one extra clock every second.

    3 - Integers. The only thing I use integers for is loop variables. Doesn't mean you can't use them but there are several reasons not to.

    4 - Be consistent with your begin end positioning. If you like to put the begin on the next line or the same line, it doesn't matter. Just be consistent.

    5 - I would encourage you to write your design in as many different ways possible that you can think of. Compile each version in Quartus and see how the different coding methods affect the fmax and logic usage result. Also, use the RTL viewer to get an idea of what your code produced in hardware.

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

    Thanks for your reply Jake.

    I've so much to learn....

    What is the best Verilog tutorial, i can learn with?

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

    The best thing you can do is to just keep practicing. However, I (and I'm sure others) can suggest a little reading material:

    VerilogHDL by Palnitkar is great as a reference book.

    http://www.amazon.com/verilog-hdl-2nd-samir-palnitkar/dp/0130449113/ref=sr_1_1?ie=utf8&s=books&qid=1222294327&sr=1-1

    and

    Altera recommended coding practices:

    http://www.altera.com/literature/hb/qts/qts_qii51007.pdf?gsa_pos=1&wt.oss_r=1&wt.oss=coding%20practices

    If you would consider a course. Sunburst Design teaches some good ones:

    http://www.sunburst-design.com/

    Jake