Altera_Forum
Honored Contributor
9 years agoFPGA 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