数字IC手撕代码

编程入门 行业动态 更新时间:2024-10-26 02:26:11

数字IC手撕<a href=https://www.elefans.com/category/jswz/34/1771412.html style=代码"/>

数字IC手撕代码

 前言:

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

目录如下:

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

波形


题目描述

        有一随机产生的pulse,其最小脉宽大于5ns。现有一时钟周期为20ns的时钟,他们的关系如下图所示,请写出计算该脉冲个数的verilog代码。

解决思路

        这道题的解决思路就是将pulse信号转换到clk域来进行处理。

        首先,每次检测到pulse的上升沿,我们就对Q1进行取反。这是在pulse域下改变Q1的值。 

always @(posedge pulse)beginQ1 <= ~Q1; 
end

        其次,在每一次的时钟上升沿,我们对Q1数据进行打两拍。将Q1赋给Q2,将Q2赋给Q3,然后检测pulse的信号为:edge_dect = Q2 ^ Q3;

always @(posedge clk)beginif(!rstn)beginQ1 <= 1'b0;Q2 <= 1'b0;Q3 <= 1'b0;endelse beginQ2 <= Q1;Q3 <= Q2;end
end

        最后,对edge_dect 进行计数,数字就是pulse的个数。

        这样做的原理其实就是延长pulse的宽度,让pulse能够被clk采样,接着再利用双边沿检测的方法(打两拍取异或,edge_dect = Q2 ^ Q3)得到clk域的pulse,再对其进行计数即可。

        约束:这种方法使用的前提是相邻两个pulse之间的距离要大于clk一个时钟周期,否则会出现漏采样的现象。

        针对本题pulse之间的距离均大于一个clk周期,所以可以采用该方案。 

        ps:如果有人有更好的方案相邻1ns的两个5ns pulse都能检测到的话,可以在评论区讲解自己的方法。(倍频方法就算了)

代码

module GigaDevice#(
)(input            clk       ,input            rstn      ,input            pulse     ,output reg [4:0] count     
);reg Q1,Q2,Q3;
always @(posedge pulse)beginQ1 <= ~Q1; 
endalways @(posedge clk)beginif(!rstn)beginQ1 <= 1'b0;Q2 <= 1'b0;Q3 <= 1'b0;endelse beginQ2 <= Q1;Q3 <= Q2;end
endwire edge_dect;
assign edge_dect = Q2 ^ Q3;always @(posedge clk)beginif(!rstn)begincount <= 1'd0; endelse if(edge_dect) begincount <= count + 1'b1;end
endendmodule

testbench

module GigaDevice_tb();
reg clk,rstn,pulse;always #10 clk = ~clk;initial beginclk <= 1'b0;rstn <= 1'b0;pulse <= 1'b0;#20rstn <= 1'b1;#500$stop();
end
initial begin#33 pulse <= 1'b1;#7  pulse <= 1'b0;  //40#42 pulse <= 1'b1;#5  pulse <= 1'b0;#3#27 pulse <= 1'b1;#18 pulse <= 1'b0;#5#33 pulse <= 1'b1;#5  pulse <= 1'b0;
end
wire [4:0] count;GigaDevice u_GigaDevice(.clk    (clk)     ,.rstn   (rstn)    ,.pulse  (pulse)   ,.count  (count)
);
endmodule

波形


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

更多推荐

数字IC手撕代码

本文发布于:2023-06-26 04:09:08,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/889071.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:代码   数字   IC

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!