Mojo v3 Modulator Example Code

  • Accessing Xilinx ISE
  • Starter Code to generate 8 PWM signals
  • To synthesize any changes to the starter code, you will need to run the synthesize command in Xilinx ISE. Xilinx ISE (student edition) is a free download. Once you have synthesized your code, you will use the mojo loader to program the FPGA.

    Embedded micro, the manufacturer of the Mojo v3 platform that we are using, has a series of tutorials for this process on their website. Note: You may use the Mojo IDE if you like, but it is not necessary and will not be supported in the class. Also, Version 1.1.2 of the Mojo Loader should be used, as more recent versions require a firmware update that is not necessary for the purposes of this project

  • Tutorial and download link for Xilinx ISE
  • Tutorial and download link for Mojo Loader

  • Example of FPGA code modification
  • The example code consists of a top-level (mojo_top.v) file, and several modules to implement specific hardware blocks. You should be able to generate arbitrary frequency, phase, and duty cycle PWMs only altering the code in mojo_top.v, but are welcome to look into the other files to understand their function. Each file is commented with a description of functionality and the purpose of constants and I/O

    In mojo_top.v, there is a clock multiplier which boosts the system clock to 300 MHz, then a sawtooth generator and eight PWM modulators to generate the eight gate driver input signals. First, have a look at the modulator:

    sawtooth_gen sawtooth_gen (
    	 .max_mod_value(300),
    	 .rst(rst),
    	 .clk(clk300),
    	 .sawtooth(sawtooth)
    	 );

    By default, the code initializes the maximum modulator value to 300. This means that the sawtooth wave will count from 0 to 300, incrementing once every clock, then reset. The output signal, "sawtooth" is then:

    which is a digital sawtooth wave used for comparison in the PWM modulator (See textbook section 7.6 for additional details of the analog equivalent). The modulator period is the switching period of any PWM signals derived from it. Thus the PWM signal swithing period will be $T_s = T_{clk}\times{\mathrm{max\_mod\_value}}$, where $T_{clk} = \frac{1}{300MHz}$. Thus, for the example file with $\mathrm{max\_mod\_value}=300$, the PWM signals will have switching frequency $f_s=100~\mathrm{MHz}$. If, for example, we want to set the switching frequency to 5 MHz, we would alter the code to read

    sawtooth_gen sawtooth_gen (
    	 .max_mod_value(60),
    	 .rst(rst),
    	 .clk(clk300),
    	 .sawtooth(sawtooth)
    	 );

    Once it is generated, the digital sawtooth is sent to eight individual modulators. The first one, as an example, is

    modulator_single gL0 (
     .sawtooth(sawtooth),
     .falling_edge(298),
     .rising_edge(152),
     .rst(rst),
     .clk(clk300),
     .DPWM(gL[0])
     );

    Each modulator defines a "rising_edge" and a "falling_edge". Both of these are compare values at which the output, "DPWM" will toggle high or low, respectively. The general behavior is shown below.

    By selecting the rising and falling edge values for each modulator, you can generate up to eight signals with the same switching frequency, but with arbitrary phase and duty cycle relative to one another. Note that both falling_edge and rising_edge must be less than the value you set for max_mod_value, otherwise the signal will never switch. For some cases, this may mean falling_edge < rising_edge is necessary to get the signals you want.

    If you use less than eight PWM signals, you can shut down the extra modulators by setting their reset pins high. To do this, modify the module declaration code of the modulators you want to shut down from

    
     .rst(rst),
    
    to
    
     .rst(~rst),