Forum Discussion

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

modelsim noob question?

Hi all,

I'm just starting to teach myself FPGAs using Verilog and until now I managed to get some simple programs to work.

I am now trying to simulate the same program that physically worked on my board using Model sim however I cannot manage.

I managed to simulate an example from Altera's site: http://www.altera.com/support/examples/verilog/ver-add-sub.html (http://www.altera.com/support/examples/verilog/ver-add-sub.html) however when I run my program the outputs and internal registers stay as undefined (x).

I know that the code could be written in a better fashion, but still I'm curious and would like to understand why it doesn't work in ModelSim. I'm using the tools provided from altera's website and they were updated (including patches) 2 days ago.

module fpgatest(
 input KEY,
 input KEY2,
 input clk,
 output reg  LED
 );
 
 reg  counter;
 
 always @(posedge clk) counter = counter+2;
  
 always @(posedge counter) begin
  if (!KEY2) LED = 0;
  else if (KEY) LED = LED+1;
  else LED = LED-1;
 end
endmodule

3 Replies

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

    Hi strykerg,

    This is the fourth attempt to provide you with an answer, hopefully it might happen if I don't get any further interrupts by someone who doesn't understand the concept of return from interrupt herself ! Assume HEAD DESK !

    Right first thing. ABANDON YOUR IDEAS OF THIS BEING SOFTWARE !

    It isn't, you are trying to create a description of a digital circuit and NOT a program. This is done in a Hardware Description Language, not a programming language.

    You have an input called clk, the rest of the description shows you are trying to create a 22 bit counter (the variable counter of type reg).

    The first always block is being sensitized to action when it sees the postive edge of the clk. Each time it sees the this the value of counter is incremented by 2.

    However at start of day your counter does NOT have the value of 0 in it. In REAL electronics a register might come up as either '1' or '0' but it is entirely indeterminate.

    To represent this the counter value bits are at an unknown state. Adding 2 to an unknown state just has another unknown state.

    What you need to do is to make it go into a known state. This is usually done by applying what is called a reset. We can do this with your code (there is another way but I think it will be good to get you into a good methodology.

    Add this to the module description.

    module fpgatest (

    ...

    input wire reset,

    ...

    and now we need to alter the alway blocks

    always (posedge clk)

    begin : counter_block

    if (reset)

    counter <= 22'b0000000000000000000000;

    else

    counter <= counter + 2;

    end

    end //counter_block

    What will happen is that when the reset signal goes high it will set the counter to all zeros. As this is Model Sim you can use the command

    force reset 1

    for a few of the clocks and then

    force reset 0

    Note you must have it high for at least 1 one clock.

    The value of counter will then have a known value for the counter and then it can start to count properly.

    What you have created is called a Synchronous Reset. You can make it Asynchronous if you wish but I'll let you research that.

    Now the second always block has a similar problem but I think you now know how to fix it using this the same technique but using a reset timed to the 'divided' clock you have generated so it has to be as long as one of your divided clocks.

    Note it's not great practice to create a second 'clock', ie bit 20 of counter to drive another counter, it needs to be treated as a clock within the FPGA fabric.

    Alternatively you can use the counter [20] as a gating mechanism, but again for now I'll leave you to research this, but it will mean that you can use the same reset as everything is run from the same clock.

    Good luck.

    HEY I managed to get this answer out to you :)
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Thanks for your answer. I didn't see my post for quite a few days and I taught it was deleted or something went wrong.

    the same day I actually managed to get the simulation to work by adding an initial block and setting the counter values to 0 (same thing what you did here with the reset)

    thanks for your reply you taught me a couple of valuable things. what was driving me nuts is that the actual fpga was working but the sim not

    I think I should be reading about how to properly write testbenches :)
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi strykerg,

    In general the registers in any FPGA (including Xilinx) start up with their values at zero, including the SRAMs which CAN be an issue (I'll explain later).

    I was tempted to advise you to look at initial block but I thought it would be better for you to understand more of the Hardware approach.

    Testbenches are an excellent way to get into the ins and outs of a language as they don't have to be compiled into the FPGA (however I have known of testbenches that were compiled into an FPGA). You will be able to learn about asserts and all of the System Commands.

    My 'native' hardware language is VHDL which I use for home projects and I am presently using Verilog in my day job so I've become conversant with both.

    While not 'dissing' Verilog you may want to consider VHDL, the reason being is that Verilog is like learning how to ride a bike without stabilisers, VHDL has all of the safeties turned on and will tell you when you do something odd, Verilog will just 'shrug' it's shoulders and let you crash and burn.

    So take that on board.

    Now as to the SRAMs being all at zero being a problem, this is because FPGAs are used to 'emulate' a real ASIC before it has been manufactured. This is to allow testing and SW development to start early. The problem is that sometimes the SW just assumes that memory contents will always be zero which in the real ASIC it won't be. To be fair the HW team sometimes also makes this mistake, that is a lot harder to fix than SW !

    Anyway Good Luck in your endeavours :).

    Best Regards

    Andre'