码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 数字IC手撕代码-XX公司笔试真题(数据流pipeline加和)


     前言: 

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

    目录如下:

    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

    输出波形


    题目描述

            输入连续数据流,得出每 256 个数据流的加和值,时序示意图如下:

            输入为 i0,i1,i2,…,i253,i254,….占 1 个时钟周期, 输出 sum0 为 i0 +i2+….+i254 的加和值(隔点相加), sum1 为 i1+i3+….+i255,sum2 为 i2+i4+….+i256,如此下去,每个输出占一个时钟周期 Sum0 和 i0 的相对延时关系任意即可。假设输入 i0,i1,i254,…为 8 比特值, 输出 sum 请选择认为不会损失精度且合适的位宽,并用你认为的最省资源的方式用 verilog 语言实现上述要求。

    解题思路

            这道题求和其实比较简单,但是关键在于使用最省资源的方式来实现要求。所有的input都是8bit的,sum0加sum1是从i0加和到i255,256个8bit数相加。所以256个8bit数加和需要用16bit的数来表示,因此设置sum为15bit即可。并且还存在规律:

            sum2=sum0-i0+i256,sum3=sum1-i1+i257

            可以用一个深度为257*8bit位宽的空间datain_store来存储i0-i256,然后再每进一个值,datain_store就移位8bit把新进来的数存起来。再用两个sum,一个sum输出奇数128项求和,一个sum输出偶数128项求和即可。

    代码

    1. module pip_sum(
    2. input clk ,
    3. input rstn ,
    4. input [7:0] datain ,
    5. input datain_ena ,
    6. output [14:0] sum ,
    7. output dataout_ena
    8. );
    9. reg [8*257-1:0] datain_store; //DEPTH = 2056
    10. reg [7:0] count;
    11. reg [14:0] sum_odd,sum_even;
    12. reg datain_ena_onebeat;
    13. reg flag;
    14. always @(posedge clk)begin
    15. if(datain_ena)begin
    16. datain_store <= {datain_store[8*256-1:0],datain}; //left shift 8bit, store datain in low 8bit
    17. end
    18. end
    19. always @(posedge clk)begin
    20. if(!rstn)begin
    21. count <= 8'd0;
    22. end
    23. else if(datain_ena_onebeat == 1'b1 && count < 8'd255)begin
    24. count <= count + 1'b1;
    25. end
    26. else if(datain_ena_onebeat == 1'b1 && count == 8'd255)begin
    27. count <= 8'd0;
    28. end
    29. end
    30. always @(posedge clk)begin
    31. if(!rstn)
    32. flag <= 1'b0;
    33. else if(count == 8'd255)
    34. flag <= 1'b1; //
    35. end
    36. wire [7:0] look;
    37. assign look = datain_store[7:0];
    38. always @(posedge clk)begin
    39. if(!rstn)begin
    40. sum_odd <= 15'd0;
    41. sum_even <= 15'd0;
    42. end
    43. else begin
    44. datain_ena_onebeat <= datain_ena;
    45. if(datain_ena_onebeat)
    46. case(count[0])
    47. 0:begin
    48. if(flag==0)
    49. sum_even <= sum_even + datain_store[7:0];
    50. else
    51. sum_even <= sum_even - datain_store[8*257-1:8*256] + datain_store[7:0];
    52. end
    53. 1:begin
    54. if(flag==0)
    55. sum_odd <= sum_odd + datain_store[7:0];
    56. else
    57. sum_odd <= sum_odd - datain_store[8*257-1:8*256] + datain_store[7:0];
    58. end
    59. endcase
    60. end
    61. end
    62. reg [14:0] sum_odd_onebeat,sum_even_onebeat;
    63. always @(posedge clk)begin
    64. sum_odd_onebeat <= sum_odd;
    65. sum_even_onebeat <= sum_even;
    66. end
    67. assign sum = (count[0]) ? sum_odd_onebeat: sum_even_onebeat;
    68. assign dataout_ena = flag;
    69. endmodule

    testbench

    1. module pip_sum_tb();
    2. reg clk,rstn;
    3. reg [15:0] count;
    4. reg [7:0] datain;
    5. reg datain_ena;
    6. wire [14:0] sum;
    7. wire dataout_ena;
    8. always #5 clk <= ~clk;
    9. initial begin
    10. clk <= 1'b0;
    11. rstn <= 1'b0;
    12. #16
    13. rstn <= 1'b1;
    14. #20
    15. datain_ena <= 1'b1;
    16. #10000
    17. $finish();
    18. end
    19. initial begin
    20. datain <= 8'd0;
    21. count <= 1'b0;
    22. forever begin
    23. @(posedge clk)begin
    24. if(datain_ena == 1)begin
    25. if(count < 255)begin
    26. datain <= 1'b0;
    27. end
    28. else
    29. datain <= datain + 1'b1;
    30. count <= count + 1'b1;
    31. end
    32. end
    33. end
    34. end
    35. //dump fsdb
    36. initial begin
    37. $fsdbDumpfile("pip_sum.fsdb");
    38. $fsdbDumpvars(0);
    39. end
    40. pip_sum u_pip_sum(
    41. .clk (clk) ,
    42. .rstn (rstn) ,
    43. .datain (datain) ,
    44. .datain_ena (datain_ena),
    45. .sum (sum) ,
    46. .dataout_ena (dataout_ena)
    47. );
    48. endmodule

    输出波形

            为了方便看结果的正确性,让datain的前256个周期都为0,这样输出的sum0和sum1都为0,然后再让datain为正整数序列递增。 从输出结果可以看到,和我们预期一致,sum0=sum1=0,sum2=sum0-i0+i256=0-0+1=1;sum3=sum1-i1+i257=0-0+2=2,以此类推。


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

  • 相关阅读:
    【国科方案】设置引脚复用、方向和输入输出
    分类算法-逻辑回归与二分类
    Linux自动化构建项目工具——Makefile/makefile
    Apache Tomcat下载安装配置使用超详细
    PHP 危险函数1-OS 命令执行函数
    GPU(国内外发展,概念参数(CUDA,Tensor Core等),类别,如何选型,NPU,TPU)
    Yolo v4:目标检测的最佳速度和精度
    【juc学习之路第9天】屏障衍生工具
    设计模式——单例模式
    设置Unity URP管线中的渲染开关
  • 原文地址:https://blog.csdn.net/qq_57502075/article/details/127836194
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号