Remember the PWM behavior equation
Here, we need translate in terms of the register values since the instructions for the HACK CPU will update the values, consequently, the PWM signal will change.
where MAX is the register value in the peripheral memory map.
Other important register is which the counter is compared to generate a Duty Cylce in the PWM signal. This register is called CMP and has its own mapping in the peripheral memory map.
A proposed memory map for three instances of the PWM module is the following
The first two registers are reserved for future BSP.
At this point, I have a small implementation of the HACK CPU for peripheral testing. In the future I will provide more information about my design in other Blog. In this moment I post my HACK Assembly code to test the peripheral configuration
// Engineer: Miguel Angel Castillo Martinez // Dummy code to configure the three PWM peripheral instances @1024 D=A @16387 M=D @128 D=A @16388 M=D @1024 D=A @16389 M=D @512 D=A @16390 M=D @1024 D=A @16391 M=D @768 D=A @16392 M=D @END (END) 0;JMP
You can use the Software tools provided in the nand2tetris courseware, available in https://www.nand2tetris.org/software to test and validate your own design. Remember!!! the software is designed with other purposes, consequently, consider the new memory map for your design instead of the original memory map. The memory map start in 0x400, so, you will observe some dots in the screen for the CPU emulator.
Ok, I understand, but how is this shown in the board?
I need uncomment the needed lines in the .xdc file and rename them to be meaningful
## 12 MHz System Clock set_property -dict { PACKAGE_PIN M9 IOSTANDARD LVCMOS33 } [get_ports { CLK_SYS }]; #IO_L13P_T2_MRCC_14 Sch=gclk create_clock -add -name sys_clk_pin -period 83.33 -waveform {0 41.66} [get_ports { CLK_SYS }]; ## Push Buttons set_property -dict { PACKAGE_PIN D2 IOSTANDARD LVCMOS33 } [get_ports { RST }]; #IO_L6P_T0_34 Sch=btn[0] ## 4 LEDs set_property -dict { PACKAGE_PIN E2 IOSTANDARD LVCMOS33 } [get_ports { LEDS[0] }]; #IO_L8P_T1_34 Sch=led[1] set_property -dict { PACKAGE_PIN K1 IOSTANDARD LVCMOS33 } [get_ports { LEDS[1] }]; #IO_L16P_T2_34 Sch=led[2] set_property -dict { PACKAGE_PIN J1 IOSTANDARD LVCMOS33 } [get_ports { LEDS[2] }]; #IO_L16N_T2_34 Sch=led[3]
You must add the Digilent boards to Vivado following the https://digilent.com/reference/programmable-logic/guides/installing-vivado-and-sdk tutorial. In addition, you find the .xdc file in https://github.com/Digilent/digilent-xdc. This procedure reduces the risk of bad definitions of board terminals.
Using a logic analizer we can observe the behavior of the three instances. the clock frequency is 12MHz according to CMOD S7 wiki page. With the implemented code it is possible to calculate that the PWM frequency is about 11.7 KHz. The CMP values were selected for 12.5%, 50% and 75% duty cycle in the respective instance.