如何用PSoC UDB实现硬件PDM
0赞如何用PSoC UDB实现硬件PDM
- 基于累加的PDM算法(4)
除了FPGA/CPLD外,目前能在MCU内部实现基于累加的PDM算法的硬件PDM还只有Cypress PSoC的UDB(PSoC3-5,而PSoC1不带UDB)。本节具体介绍如何用PSoC的UDB Datapath来做基于累加算法的硬件PDM。同时这对熟悉UDB中的Datapath也有好处,因为我觉得UDB的Datapath是一项很有利用价值的资源。
开发环境为Cypress PSoC Creator 2.2,实例在最近大家都感兴趣的PSoC4上实现。
图0
我们用 File – New – Project – Empty PSoC4(CY8C42*) Design 建立项目ExampleHWPDM8后(图0),由于我们还没有PDM这个部件(Component),所以还无法画出电路图。因此必须先建立PDM这个部件,步骤如下。
(1)点垂直方向的“Components”TAB,然后右键点Project ‘ExampleHWPDM8’,选择“Add Component Item”(图1)。
图1
(2)在弹出的“Add Component Item”窗口,选择“Symbol Wizard”,并在Component Name处填上部件名称(例如)“MyPDM8B”。然后点“Create New”。(图2)
图2
(3)在弹出的“Symbol Creation Wizard”窗口,填写部件的输入、输出端。
这里输入端为clock – Digital Input。输出端为极性相反的两个输出PDM_p、PDM_n – Digital Output。“Symbol Creation Wizard”窗口会自动生成部件的电路符号。点击“OK”完成此步操作。(图3A)
图3A
于是项目就有了可供调用的部件“MyPDM8B”的电路符号,其通用名称为“MyPDM8B_N”。将来多个同样的部件可用MyPDM8B_1、MyPDM8B_2、MyPDM8B_3区分。(图3B)
图3B
(4)点“MyPDM8B_N”图纸的空白处(右键),并选择“Generate Verilog” (图4),在弹出窗口中点击“Generate”,自动生成Verilog文件“MyPDM8B.v”。
图4
(5)开发环境的主窗口自动显示Verilog文件“MyPDM8B.v”的内容,待编辑(图5A)。新生成的MyPDM8B.v未被保存,要先保存。
图5A
编辑的第一步使用Cypress PSoC Creator 2.2 开发环境提供的Datapath Config Tool完成部件“MyPDM8B”的内部结构配置。
在开发环境左边窗口用右键点文件“MyPDM8B.v”,在弹出的小窗口选“Datapath Config Tool…”(图5B)。
图5B
(6)自动转到Datapath Config Tool环境。
根据前面文章的介绍,我们的算法只使用“A0 = A0 + D0”一条指令,所以填写表格非常方便。
(6A)Edit – New Datapath…
本例为8位PDM,所以取Instance Name为PDM8,选Instance Type为cy_psoc3_dp8。点“OK” (图6A)。
图6A
(6B)填写表格:我们只须把CFGRAM – Reg0的FUNC设为“ADD”,以及将ALU结果写回A0(A0 WR SRC 设为 ALU)就可以了,其余都与Default的设置一致,无需改动。(图6B)
图6B
File – Save会自动写入MyPDM8B.v。然后File – Exit退出Tool环境,回到开发环境。这时开发环境主窗口中的MyPDM8B.v已加入了Datapath Config Tool所添加的Datapath Config内容。(图6C)
图6C
(7)人工编辑MyPDM8B.v。主要是连接Datapath的输入(将时钟clock连至clk)、输出(将加法的进位位co_msb输出至PDM_p及PDM_n);以及加一些注释。(图7A,图7B)。
图7A
图7B
修改完成的MyPDM8B.v如下:
MyPDM8B.v
//`#start header` -- edit after this line, do not edit this line // ======================================== // // Copyright FY_ZHU, 2013 // All Rights Reserved // UNPUBLISHED, LICENSED SOFTWARE. // // CONFIDENTIAL AND PROPRIETARY INFORMATION // WHICH IS THE PROPERTY OF FY_ZHU. // // *The PDM Algorithm Based On Addition : // * CNT += H ; // * if ( CNT >= N ) // * { CNT %= N ; Pout = 1 ; } // * else Pout = 0 ; // *This algorithm generates H active output pulses in period N . // * // *The algorithm is free for all under mentioning that the algorithm is from author FY_ZHU. // * // *In this example the algorithm is implemented using hardware and software respectively. // *Here the PDM output is generated by hardware, a datapath with only one operation : A0 = A0 + D0 . // // ======================================== `include "cypress.v" //`#end` -- edit above this line, do not edit this line // Generated on 08/12/2013 at 16:52 // Component: MyPDM8B module MyPDM8B ( output PDM_n, output PDM_p, input clock ); //`#start body` -- edit after this line, do not edit this line /* Connections from the DP */ wire co_msb; /* Carry out of MSB */ /* c0_msb(Carry out of MSB) to the output - pos/neg */ assign PDM_p = co_msb; assign PDM_n = ~co_msb; cy_psoc3_dp8 #(.cy_dpconfig_a( { `CS_ALU_OP__ADD, `CS_SRCA_A0, `CS_SRCB_D0, `CS_SHFT_OP_PASS, `CS_A0_SRC__ALU, `CS_A1_SRC_NONE, `CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA, `CS_CMP_SEL_CFGA, /*CFGRAM0: A0 = A0 + D0*/ `CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0, `CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE, `CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA, `CS_CMP_SEL_CFGA, /*CFGRAM1: */ `CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0, `CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE, `CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA, `CS_CMP_SEL_CFGA, /*CFGRAM2: */ `CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0, `CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE, `CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA, `CS_CMP_SEL_CFGA, /*CFGRAM3: */ `CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0, `CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE, `CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA, `CS_CMP_SEL_CFGA, /*CFGRAM4: */ `CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0, `CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE, `CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA, `CS_CMP_SEL_CFGA, /*CFGRAM5: */ `CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0, `CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE, `CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA, `CS_CMP_SEL_CFGA, /*CFGRAM6: */ `CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0, `CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE, `CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA, `CS_CMP_SEL_CFGA, /*CFGRAM7: */ 8'hFF, 8'h00, /*CFG9: */ 8'hFF, 8'hFF, /*CFG11-10: */ `SC_CMPB_A1_D1, `SC_CMPA_A1_D1, `SC_CI_B_ARITH, `SC_CI_A_ARITH, `SC_C1_MASK_DSBL, `SC_C0_MASK_DSBL, `SC_A_MASK_DSBL, `SC_DEF_SI_0, `SC_SI_B_DEFSI, `SC_SI_A_DEFSI, /*CFG13-12: */ `SC_A0_SRC_ACC, `SC_SHIFT_SL, 1'h0, 1'h0, `SC_FIFO1_BUS, `SC_FIFO0_BUS, `SC_MSB_DSBL, `SC_MSB_BIT0, `SC_MSB_NOCHN, `SC_FB_NOCHN, `SC_CMP1_NOCHN, `SC_CMP0_NOCHN, /*CFG15-14: */ 10'h00, `SC_FIFO_CLK__DP,`SC_FIFO_CAP_AX, `SC_FIFO_LEVEL,`SC_FIFO__SYNC,`SC_EXTCRC_DSBL, `SC_WRK16CAT_DSBL /*CFG17-16: */ } )) PDM8( /* input */ .reset(1'b0), /* input */ .clk(clock), /* input [02:00] */ .cs_addr(3'b0), /* input */ .route_si(1'b0), /* input */ .route_ci(1'b0), /* input */ .f0_load(1'b0), /* input */ .f1_load(1'b0), /* input */ .d0_load(1'b0), /* input */ .d1_load(1'b0), /* output */ .ce0(), /* output */ .cl0(), /* output */ .z0(), /* output */ .ff0(), /* output */ .ce1(), /* output */ .cl1(), /* output */ .z1(), /* output */ .ff1(), /* output */ .ov_msb(), /* output */ .co_msb(co_msb), /* output */ .cmsb(), /* output */ .so(), /* output */ .f0_bus_stat(), /* output */ .f0_blk_stat(), /* output */ .f1_bus_stat(), /* output */ .f1_blk_stat() ); //`#end` -- edit above this line, do not edit this line endmodule //`#start footer` -- edit after this line, do not edit this line //`#end` -- edit above this line, do not edit this line
至此,8位PDM部件MyPDM8B已经完成。就如PSoC Creator的其他部件一样,可以在开发环境中使用了。
例如,我们可以回到TopDesign的线路设计,在Default Component Catalog中找到MyPDM8B部件,把它拖放到设计图中。两个部件自动被命名为MyPDM8B_1、MyPDM8B_2(图8)。
图8
在程序中,只须按需对Datapath中的D0寄存器赋值就可以了。
例如
/* Feed datapath with new value */
CY_SET_REG8(MyPDM8B_1_PDM8_u0__D0_REG, new_value); // 0~255
具体可参见文(1)中的实例。
上面仅介绍8位硬件PDM的做法,而16位硬件PDM的做法可依此类推。
PSoC4只有4块UDB,只可做4个8位硬件PDM,或2个16位硬件PDM。而PSoC3及PSoC5有有24块UDB,灵活性就大了。
How to Realize the Hardware PDM with PSoC UDB
- A PDM Algorithm Based On Addition (4)
===
FY_ZHU
2013-08-15 BOS-MA
基于累加的PDM算法(1) - 只用一条加法指令实现的PWM算法,软硬都行
基于累加的PDM算法(2) - 基于累加的PDM算法的原理
基于累加的PDM算法(3) - 硬件PWM与基于累加的硬件PDM的比较