• 牛客刷题<九>使用子模块实现三输入数的大小比较


    题目:使用子模块实现三输入数的大小比较_牛客题霸_牛客网

    思路:

    法一:使用三个比较器完成

    法二:使用两个比较器加一个触发器

    解析:

    module模块

    一个.v文件中可以写多个模块module(一般是一个文件写一个module),其中主模块的名字和.v文件名相同。且要注意子模块和主模块都要有endmodule,不然会报错,且最好先写主模块,再写子模块。子模块也要像主模块格式那样写。

    1. module模块名(
    2. 端口描述
    3. );
    4. ...
    5. endmodule

    例化

    1. 模块名例化名(
    2. 端口参数传递(按位置或者按名字均可)
    3. );

    比如模块名是“人”,例化名可以起名为“张三”、“李四”,这样就例化了2个“人”。

    为什么调用两个子模块就不对

    两种情况:

    (1)子模块是纯组合逻辑

    如果你的子模块用的全部是组合逻辑实现的比较,那么可以使用2个子模块,和波形不对应的原因在于提前了1个时钟。使用2个组合逻辑得到最小值后,再主模块里要对这个值打两拍,这样时序和题目答案的波形一致。

    (2)子模块是时序逻辑

    子模块里面的比较也选择时序逻辑寄存输出。

    先说使用三个子模块的做法,a、b比较,在T+1时刻输出最小值tmp1,同时a、c比较在T+1时刻得到最小值tmp2,然后是tmp1和tmp2比较在T+2时刻得到最小值d;

    一定注意这个同时的含义。T时刻输入a、b、c,T+1时刻得到tmp1和tmp2,T+2时刻得到d

    如果是使用2个子模块T时刻比较a、b,在T+1时刻输出最小值tmp1,然后T+1时刻比较时才是c和tmp1比,在T+2时刻得到T+1时的c和tmp1的最小值;

    注意,这样比较完就是拿T时刻的a、b和T+1时刻的c比较!

    解法一

    1. `timescale 1ns/1ns
    2. module main_mod(
    3. input clk,
    4. input rst_n,
    5. input [7:0]a,
    6. input [7:0]b,
    7. input [7:0]c,
    8. output [7:0]d
    9. );
    10. wire [7:0] m,n;
    11. //先得到ab之中的较小值m
    12. sub_mod mod_ab(
    13. .clk(clk),
    14. .rst_n(rst_n),
    15. .data_a(a),
    16. .data_b(b),
    17. .data_c(m)
    18. );
    19. //先得到bc之中的较小值n
    20. sub_mod mod_bc(
    21. .clk(clk),
    22. .rst_n(rst_n),
    23. .data_a(b),
    24. .data_b(c),
    25. .data_c(n)
    26. );
    27. //最后对比mn的大小
    28. sub_mod mod_mn(
    29. .clk(clk),
    30. .rst_n(rst_n),
    31. .data_a(m),
    32. .data_b(n),
    33. .data_c(d)
    34. );
    35. endmodule
    36. module sub_mod
    37. (
    38. input clk,
    39. input rst_n,
    40. input [7:0] data_a,
    41. input [7:0] data_b,
    42. output reg [7:0] data_c
    43. );
    44. always@(posedge clk or negedge rst_n)
    45. begin
    46. if(!rst_n)
    47. data_c <= 8'b0;
    48. else if(data_a < data_b)
    49. data_c <= data_a;
    50. else
    51. data_c <= data_b;
    52. end
    53. endmodule

    解法二:通过延时输入信号C一个时钟周期,通过两个子模块例化实现对三个输入无符号数的大小比较

    1. `timescale 1ns/1ns
    2. module main_mod(
    3. input clk,
    4. input rst_n,
    5. input [7:0]a,
    6. input [7:0]b,
    7. input [7:0]c,
    8. output [7:0]d
    9. );
    10. reg [7:0] c_0;
    11. wire [7:0] tmp0;
    12. always@(posedge clk or negedge rst_n)begin
    13. if(!rst_n)
    14. c_0 <= 0;
    15. else
    16. c_0 <= c;
    17. end
    18. sub_mod sub_mod0(.clk(clk), .rst_n(rst_n), .a(a), .b(b), .c(tmp0));
    19. sub_mod sub_mod1(.clk(clk), .rst_n(rst_n), .a(tmp0), .b(c_0), .c(d));
    20. endmodule
    21. module sub_mod(
    22. input clk,
    23. input rst_n,
    24. input [7:0] a,
    25. input [7:0] b,
    26. output [7:0] c
    27. );
    28. reg [7:0] c_r;
    29. always@(posedge clk or negedge rst_n) begin
    30. if(~rst_n)
    31. c_r <= 8'b0;
    32. else
    33. c_r <= a < b? a:b;
    34. end
    35. assign c = c_r;
    36. endmodule

    这一题不能为了简化资源而只例化两次子模块sub_mod,因为是always块里的非阻塞赋值,比较的结果会差一拍。 如果非要只例化两次,比如说先比较a与b,然后直接把较小的结果与c比较的话,那么得到的结果就是min(a,b)与下一时刻的c的较小值,所以此时需要另加一个触发器进行延时一拍。 所以为了同步,否则要例化三次。

  • 相关阅读:
    Linux知识点 -- 网络基础(二)-- 应用层
    云安全—集群攻击入口攻与防
    4款值得推荐的AI辅助编程工具(支持C#语言)
    JavaEE中进程、线程的知识点
    testng-xslt使用详细教程
    如何借助ai(文心一言)获取tushare的数据
    Java 基于 SpringBoot 的学生考勤系统
    周鸿祎自称3次破解特斯拉云端系统:安全隐患巨大
    《亚马逊云科技-游戏孵化营》第一次公开课学习心得
    月薪9000招不到人?为什么这届年轻人不愿进工厂了?
  • 原文地址:https://blog.csdn.net/mxh3600/article/details/126427582