Forum Discussion

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

FPGA hardware result different from simulation

Hi,

I may be wrong, but I think this is where I should post this question. I'm working with the max10 development board .

https://www.altera.com/products/boards_and_kits/dev-kits/altera/max-10-fpga-development-kit.html

I have written a piece of code for a counter and pwm generator which uses altera's pll megafunction. I believe the code is right and there shouldn't be any latches. Simulation shows what I am expecting, but when I program this to the FPGA, the results on the oscilloscope is completely off. I am expecting a 500Hz pwm signal, but I am getting something in the 1.5-2Mhz range, not a square wave and very jittery. I don't have pictures right now, I will try to get them up soon.

I suspect my problem is related to the way I've set up the pll or assigned the pins. Below is the code I've written. Is there anything else I can provide that would help troubleshoot this issue.

My global clock is connected to M9 from the pin out and that should be the onboard generated 50MHz.

module fc_top (

//Reset and Clocks

input clk_50,

input rst_n,

input pwm_up,

input pwm_dwn,

//LED PB DIPSW

output pwm_out

);

// wire clk;

wire clk_256khz;

wire lock;

reg pwm_o;

// altclkctrl altclkctrl (

// .inclk (clk_50), // altclkctrl_input.inclk

// .outclk (clk) // altclkctrl_output.outclk

// );

//used max divisor, 10000 gave 500hz output

pll pll_inst (

.areset ( rst_n ),

.inclk0 ( clk_50 ),

.c0 ( clk_256khz ),

.locked (lock)

);

//PWM module

localparam COUNTER_WIDTH = 9;

//localparam COUNT_MAX = 9'b111110100; //500

//localparam COUNT_MAX = 500; //500

reg [COUNTER_WIDTH - 1:0] counter;

// at 500hz (=2ms), 1ms = 250count

//reg [COUNTER_WIDTH - 1:0] duty_cycle = 9'b011111010; // change to whatever bit gives 50% duty cycle. ini of pwm

reg [COUNTER_WIDTH - 1:0] duty_cycle; // change to whatever bit gives 50% duty cycle. ini of pwm

//user can use pushbutton to increase/decrease pwm duty cycle.

//not sequential, this block only active if sensitivity list is true.

//so if user does nothing, duty_cycle should remain unchanged.

// at thet start and while counter is less than duty cycle, output is high

// when greater than duty cycle output is low. reset when max reached.

// reset active high? loook for falling edge

always @ (posedge clk_256khz) begin

if (rst_n == 1) begin //rst and lock cannot be 1 at the same time. a rst occurs and requires ~70ns before we get lock

pwm_o <= 1;

counter <= 0;

duty_cycle <= 255;

end else if (lock == 1) begin //I only want output to change when locked.

if (pwm_up == 0) begin // push buttom press = pulled low.

if (duty_cycle + 63 <= 511) begin

duty_cycle <= duty_cycle + 63;

end else begin

duty_cycle <= 511;

end

end else if (pwm_dwn == 0) begin

if (duty_cycle - 63 >= 255) begin

duty_cycle <= duty_cycle - 63; //if duty_cycle 256, leave it. this will have to change to represet push buttons later.

end else begin

duty_cycle <= 255;

end

end else begin //else if (pwm_up == 1|| pwm_dwn == 1) begin

duty_cycle <= duty_cycle;

end

if (counter < duty_cycle) begin

pwm_o <= 1;

end else begin // counter on second part of cycle, will auto wrap around

pwm_o <= 0;

end

counter <= counter + 1;

end else begin

counter <= counter;

end

end

//pwm_out will always receive value of pwm_o, anytime all time.

// pwm_out is wire to outside top module, pwm_o is register holding value.

assign pwm_out = pwm_o;

endmodule

3 Replies

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

    Hi,

    a few thoughts on this:

    • the "always" block is not sensitive to the reset; should be no reset in the real design, though, just something which would behave strange in the simulation

    • does that PLL actually support a 256 kHz output clock? Sounds mighty low for a FPGA PLL. Was there any warning in the MegaWizard/IP Catalog?

    • the reset signal seems to be active-low (I assume so because the name is "rst_n"), but your reset condition is "if (rst=1)"; typo?

    • I assume "pwm_up" and "pwm_down" are push-buttons; are they debounced?

    • are the "pwm_up" and "pwm_down" input signals maybe floating? If you accidentally mapped them to floating pins, they would wildly change the PWM duty cycle, which might cause the described behavior; actually, same for all input signals

    I agree most of these points are unlikely to cause the described behavior, but maybe it's a combination of several effects...

    I didn't see your simulation, so I have to assume it's correct. Also, I assume there are no timing issues. You didn't mention a static timing analysis, but 50 MHz sounds doable for just about any design in a MAX10.

    One more thing: please consider using code-tags when posting code; your code lost all indentation and is hard to read when being posted as plain-text. Code tags can easily be inserted using that toolbar button with the "#" symbol.

    Best regards,

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

    Hi GooGooCluster,

    Thank you for the response. I figured it out. I messed up at the third point, the reset signals. I also ran into problems with setting/changing duty cycle and after some time, was a result of not debouncing.

    I have verified everything to be working, so the points you described were on point. =]

    I will look for the code tags in the future, thanks!

    I would consider this resolved, do we need to flag this thread or anything?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    You got me. No idea. I think there's no way to mark a thread as resolved...?