FPGA, SoC, And CPLD Boards And Kits
FPGA Evaluation and Development Kits
Announcements
Intel Support hours are Monday-Fridays, 8am-5pm PST, except Holidays. Thanks to our community members who provide support during our down time or before we get to your questions. We appreciate you!

Need Forum Guidance? Click here
Search our FPGA Knowledge Articles here.
5241 Discussions

FPGA hardware result different from simulation

Altera_Forum
Honored Contributor II
1,011 Views

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
0 Kudos
3 Replies
Altera_Forum
Honored Contributor II
99 Views

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
Honored Contributor II
99 Views

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
Honored Contributor II
99 Views

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

Reply