This website uses cookies. By using this site, you consent to the use of cookies. For more information, please take a look at our Privacy Policy.
Home > Wiki encyclopedia > MMCM


Mixed-Mode Clock Manager. Multi-output configurable block which includes PLL and phase shifters to give fine-grain control of clocks within a Xilinx® FPGA.



(1) After a specific period of time, perform a specific operation;   (2) Perform a specific operation according to a given period. The traditional approach is to use the front and background methods: set a hardware timer to make a count operation on the flag variables of various related operations in the background in a specific cycle; the front desk continuously patrols each flag variable, if it is found that the flag variable reaches a predetermined value , Perform a specific operation. It can be seen that the above requirements need to be realized by directly operating the hardware timer, the process is cumbersome, and requires the user to have an in-depth understanding of the relevant hardware. Therefore, a low-end system clock manager that is easy to use is designed and implemented.  In the implementation of the clock manager, the hardware-related parts form an independent module (file). For different target system processors, replace the module. In order to make the expression not abstract, the design and implementation of the embedded clock manager are explained with the 8051 series MCU as the target system processor and c51 as the tool language.


(1) configclk.h defines the adjustable parameters related to system cutting and configuration. By configuring the relevant macro parameters in configclk.h, the configuration and cutting of the clock manager system can be achieved.  (2) The clk_impl.* function module is used to encapsulate a hardware timer of the target system to shield the hardware differences between different processors and play the role of hal (hardware abstract layer). The system clock is built here. (3) The clk.* module is further encapsulated on the basis of hal provided by clk_impl.*, and provides a clock pulse for the system through a hook function, and the pulse width is adjustable (you can configure the relevant macro parameters in configclk.h ).  (4) The wdlib.* module provides multiple software timers for user applications.


The bottom package of the hardware timer   The bottom package of the hardware timer is implemented in clk_impl.* shown in Figure 1. It defines an initialization interface function and a timer interrupt isr (interrupt service routine). Let the selected hardware clock be timer 0 (can be configured in configclk.h). (1) Initialize the interface function void_clkinit(void){}  By calling this interface function, the user can periodically execute the corresponding isr_clktick_isr to form a logical system clock. In addition, this interface function is not directly accessed by the user, but is called in the upper module clk.*. (2) Isr_clktick_isr of timer 0  void clktick_isr (void) interrupt 1 using reg_grp_for_  sys_clk{}   Among them: reg_grp_for_sys_clk is an adjustable parameter defined in configclk.h, used to set the working register group of this isr. 2.2 Clock pulse supply  Clock pulse is implemented in clk.* shown in Figure 1. This article provides three user interface functions and a user-modifiable, but non-callable hook function (clktick_isr_hook can only be called in clktick_isr). The user interface declaration is as follows:  extern void constructclk(void);  extern void destructclk(void);  extern uint8 getclkrate(void);  where: constructclk is used to construct the system clock, to use the clock manager described in this article, you must first call _clkinit (defined in clk_impl.* module) implements the call to this function; destructclk is used to parse the system clock that has been built; getclkrate is used to obtain the current clock tick rate of the system (that is, the current value of the macro sys_clk_rate defined in configclk.h ). Clktick_isr_hook is declared by the system, and the user can modify its definition, which ultimately only makes periodic calls to the system. The user can put the periodic operations that he needs to do in it. The "wddaemon" routine of the software timer described later is placed here and called periodically. Since the operations placed in it will be interrupted, these operations should be as short and time-saving as possible. 2.3 The provision of software timer  This function is implemented in wdlib.* shown in Figure 1. It provides users with an interface function that can quickly and easily realize the user's timing needs and a timer daemon wddaemon that is periodically called. extern void constructwdog(void);//In order to use the timer system for initialization operation extern void destructwdog(void)//Set the timer system to the initial state extern wdog_id wdcreate(void);//Create a timer and return its id extern status wdcancel(wdog_id wdid); // Terminate the specified timer and reset extern status wddelete(wdog_id wdid); // Delete the specified timer extern status wdstart(wdog_id wdid, uint16 ticks, voidfuncptr wdr); // Start the specified timer , It will trigger the given operation after a specified time: wdog_id is the timer id type, that is uint8. The parameter "uint16 ticks" transmitted to wdstart indicates the length of the timing time, in units of system clock ticks, 1 tick = 1/sys_clk_rate(s). Because the type of this parameter is set to uint16, the maximum timing length of the timer is 216×(1/sys_clk_rate), which is 216/sys_clk_rate(s). The realization scheme of timer has two methods of static array method and delta list method. These two methods have their own advantages and disadvantages: the former logic is simple, the rom usage is small, but the efficiency is low (related to the number of timers); the latter logic is complex, the rom usage is large, but the efficiency is high (independent of the number of timers). Which scheme is used in the application can be configured and selected in configclk.h. 2.3.1 Static array method The data structure of the static array method is as follows:  struct wdnode { bool flag; //Mark whether the node has been used uint16 ticks;//Used to time the number of beats voidfuncptr rout;//When the time is up Operations performed} data wdlistmax_wdog_num_];  where: _max_wdog_num_ indicates the maximum number of timers allowed in the system, its value depends on the application requirements and the amount of system resources, which can be set in configclk.h. A timer node occupies 5b of ram space. A static array with a given data structure is the basis for the implementation of the program.  In addition, the static array exists as a global variable of the software timer. When multiple timers are active in the system, they will all access the global static array. The important thing is that their activities are asynchronous, so access to the static array (critical resources) needs to be critically protected. For the 51 system, it should be implemented by means of switch interruption, and it should be ensured that it will not affect the interruption state before the interruption. (1) User interface definition  The above user interfaces are all based on the static array, limited to space, here is the definition of the key interface wdstart. status wdstart(wdog_id wdid, uint16 ticks,  voidfuncptr wdr) { if(wdid<_max_wdog_num_) { if(wdlistdid].flag) {//Judge whether the given timer id is valid rtx_enter_critical();//Enter the critical area wdlistdid ticks=ticks;//Operate a specific timing node wdlistdid].rout=wdr in the static array;  rtx_exit_critical();//Exit the critical section return ok;//The timer starts successfully}  }  return error;//The given timing The device id is invalid}  Call this interface function to start the software timer that has been created (wdcreate). After experiencing ticks, the given function wdr will be executed to complete the user's timing requirements.  (2) Timer daemon   Timer daemon wddaemon is placed in the aforementioned hook function clktick_isr_hook to make it execute periodically. Due to the characteristics of this routine, it should be used as the last calling function of clktick_isr_hook. This routine is the core of software timer implementation, and the key is to adjust the system stack. In order to explain its implementation process, the stack structure of wddaemon shown in Figure 2 is given. It can be seen from Figure 2: The return address of wddaemon is not pushed onto the stack. Because it is the last function call in clktick_isr_hook, its return address is optimized. The wddaemon moves the 8b data at the top of the stack up by 2b, and then inserts the address of the function specified by the timer into the vacated stack space (2b). In this way, the address will be popped into the IP by iret. Due to the execution of the iret instruction, the interrupt system is reset to re-respond to external interrupts, and the timer specified function is also executed in the non-interrupted state, thereby not excessively affecting the response speed of the system. 2.3.2 The delta list method  The delta list method only maintains a linked list of valid timers, and the timer nodes in the linked list are arranged in ascending order of time remaining, so that the timer closest to the timeout point is used as the first node of the linked list. The order of the timer nodes in the linked list is determined by its unique node insertion algorithm: if there are 5 timers, their timing lengths are 10, 14, 21, 32, and 39, respectively. When they form a delta list, the timing value is the smallest The node is the first node, its timing storage value is 10, and then arranged in sequence, its timing storage value is 4, 7, 11, 7 respectively, that is, the timing storage value of the latter timer is determined by its actual timing value and phase. The actual timing value of the adjacent previous timer is subtracted. It can be seen that the counting operation of all timers except the first node is completed when it is inserted into the delta list. Therefore, when the timer daemon determines the timeout timer, only the first node needs to be decremented or deleted, rather than traversing the entire list, so that the operation of the delta list has nothing to do with the number of timers. This makes the delta list method effective in a large number of timer management. The data structure implemented by this method in the system is a static doubly linked list:  struct wdnode { bool flag;  uint16 ticks;  voidfuncptr rout;  uint8 prior;  uint8 next;  } index wdata_dlist_data_dw_list_data_did The idea of the list method and the data structure of its implementation can be obtained on the basis of the specific implementation of the static array method. If the target system rom is small and the timers enabled in the system are small, the static array method is used; if the target system rom is large and the timers used in the system are large, the delta list method is used.


In response to the timing requirements in the aforementioned embedded system, the implementation code is given using a timer management system.  Assume that the "specific operation" is void specfunc(void) and the length of the "specific period" is 10 minutes. (1) After a specific period of time, perform a specific operation. #include ″clk.h″  #include ″wdlib.h″  void main(void) { wdog_id wdid;  constructclk(); constructwdog();  wdid=wdcreate();  wdstart(wdid, 10*one_minute, specf 1);  }   (2) periodically perform specific operations at a given cycle. Based on the former, just add the following code at the end of the void specfunc(void) function body:  wdstart(wdid, 10*one_minute, specfunc);  Note: The given period is 10 minutes. Because this clock manager only needs the support of a hardware timer, it has wide applicability. When in use, only a simple configuration is needed to add a simple software abstraction layer to the bare target system. Its friendly user interface effectively reduces the development difficulty of embedded systems and improves the reliability of the target system. I have used this clock manager many times in actual projects. The target system based on the clock manager is stable and reliable, which fully illustrates the practicality and scientificity of the clock manager design.


FPGA Tutorial Lattice FPGA
Need Help?


If you have any questions about the product and related issues, Please contact us.