Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Altera_Forum
Honored Contributor I
949 Views

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

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

Reply