数字IC手撕代码-XX公司笔试真题(脉冲密度调制)

 前言:

        本专栏旨在记录高频笔面试手撕代码题,以备数字前端秋招,本专栏所有文章提供原理分析、代码及波形,所有代码均经过本人验证。

目录如下:

1.数字IC手撕代码-分频器(任意偶数分频)

2.数字IC手撕代码-分频器(任意奇数分频)

3.数字IC手撕代码-分频器(任意小数分频)

4.数字IC手撕代码-异步复位同步释放

5.数字IC手撕代码-边沿检测(上升沿、下降沿、双边沿)

6.数字IC手撕代码-序列检测(状态机写法)

7.数字IC手撕代码-序列检测(移位寄存器写法)

8.数字IC手撕代码-半加器、全加器

9.数字IC手撕代码-串转并、并转串

10.数字IC手撕代码-数据位宽转换器(宽-窄,窄-宽转换)

11.数字IC手撕代码-有限状态机FSM-饮料机

12.数字IC手撕代码-握手信号(READY-VALID)

13.数字IC手撕代码-流水握手(利用握手解决流水线断流、反压问题)

14.数字IC手撕代码-泰凌微笔试真题

15.数字IC手撕代码-平头哥技术终面手撕真题

16.数字IC手撕代码-兆易创新笔试真题

17.数字IC手撕代码-乐鑫科技笔试真题(4倍频)

18.数字IC手撕代码-双端口RAM(dual-port-RAM)

        ...持续更新

 更多手撕代码题可以前往 数字IC手撕代码--题库


目录

题目描述

解决思路

代码

testbench

输出波形 


题目描述

         使用HDL实现脉冲密度调制(PDM),即根据输入12bit pdm_in,按下列要求输出不同占空比的方波:

        ① 当pdm_in>10,pdm_out即输出的波形占空比为4/pdm_in;

        ② 当pdm_in<=10,pdm_out不翻转输出固定值。

其输入输出接口为:

input clk;
input [11:0]pdm_in;
input reset;
output pdm_out;

解决思路

        脉冲密度调制(PDM),通过调节波形的占空比来改变脉冲的密度。信号逻辑为高的时间T_hign除以周期T_cycle所得到的比值叫做占空比。

        实现第一个要求,当pdm_in>10时,可以让新信号在4个clk周期为高,在(pdm_in-4)个clk周期为低,这样就实现了一个pdm_in分频,占空比为4/pdm_in。

        第二个要求,当pdm_in<=10时,pdm_out就不让他翻转,并且让实现分频的计数器清零。 


代码

module pdm(
    input           clk     ,
    input   [11:0]  pdm_in  ,
    input           reset   ,
    output          pdm_out
);

reg pdm_processed;
reg [11:0] count;

always @(posedge clk)begin
    if(reset)begin
        pdm_processed <= 1'd0;
    end
    else if(pdm_in > 10)begin
        if(count <= 3)
            pdm_processed <= 1'b1;
        else if(count < pdm_in -1)
            pdm_processed <= 1'b0;
        else if(count == pdm_in-1)
            pdm_processed <= 1'b0;
    end
    else begin // pdm_in <= 10
        pdm_processed <= pdm_processed;  //stay 
    end
end

always @(posedge clk)begin
    if(reset)begin
        count <= 12'd0;
    end
    else begin
        if(pdm_in > 10 && count < pdm_in-1)begin
            count <= count + 1'b1;
        end
        else if(pdm_in > 10 && count == pdm_in-1)begin  // one pdm_out cycle finish
            count <= 12'd0;  
        end
        else begin // pdm_in <= 10
            count <= 12'd0;
        end
    end
end

assign pdm_out = pdm_processed;

endmodule

testbench

module pdm_tb();

reg clk,reset;
wire pdm_out;

always #5 clk = ~clk;
reg [11:0] pdm_in;

initial begin
    clk     <=  1'b0;
    reset   <=  1'b1;
    pdm_in  <=  12'd0;
    #20
    reset   <=  1'b0;
    #20
    pdm_in  <=  12'd20;
    #400
    pdm_in  <=  12'd12;
    #240
    pdm_in  <=  12'd5;
    #50
    pdm_in  <=  12'd12;
    #30
    pdm_in  <=  12'd5;
    #200
    $finish();
end

//dump fsdb 
initial begin 
    $fsdbDumpfile("pdm.fsdb");
    $fsdbDumpvars(0);
end 

pdm u_pdm(
    .clk    (clk)   ,
    .pdm_in (pdm_in),
    .reset  (reset) ,
    .pdm_out(pdm_out)
);

endmodule

输出波形 

        从波形中可以看到我们设置了pdm_in = 20,pdm_out如我们所想,输出为占空比4/20的方波。当设置pdm_in = 12时,pdm_out输出为占空比4/12的方波。当设置pdm_in < 10时,dpm_out保持原来的状态不变。


 更多手撕代码题可以前往 数字IC手撕代码--题库

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不吃葱的酸菜鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值