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

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

思路:

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

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

解析:

module模块

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

module模块名(

端口描述

);

...

endmodule

例化

模块名例化名(

端口参数传递(按位置或者按名字均可)

);

比如模块名是“人”,例化名可以起名为“张三”、“李四”,这样就例化了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比较!

解法一

`timescale 1ns/1ns
module main_mod(
	input clk,
	input rst_n,
	input [7:0]a,
	input [7:0]b,
	input [7:0]c,
	
	output [7:0]d
);
    wire [7:0] m,n;
    //先得到ab之中的较小值m
    sub_mod mod_ab(
        .clk(clk),
        .rst_n(rst_n),
        .data_a(a),
        .data_b(b),
        .data_c(m)
    );
    //先得到bc之中的较小值n
    sub_mod mod_bc(
        .clk(clk),
        .rst_n(rst_n),
        .data_a(b),
        .data_b(c),
        .data_c(n)
    );
    //最后对比mn的大小
    sub_mod mod_mn(
        .clk(clk),
        .rst_n(rst_n),
        .data_a(m),
        .data_b(n),
        .data_c(d)
    );
endmodule
    
    module sub_mod
    (
        input clk,
        input rst_n,
        input [7:0] data_a,
        input [7:0] data_b,
        output reg [7:0] data_c
    );
    always@(posedge clk or negedge rst_n)
        begin
            if(!rst_n)
                data_c <= 8'b0;
            else if(data_a < data_b)
                data_c <= data_a;
            else
                data_c <= data_b;
        end

endmodule

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

`timescale 1ns/1ns
module main_mod(
	input clk,
	input rst_n,
	input [7:0]a,
	input [7:0]b,
	input [7:0]c,
	
	output [7:0]d
);
    reg [7:0] c_0;
    wire [7:0] tmp0;
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)
            c_0 <= 0;
        else
            c_0 <= c;
    end
    sub_mod sub_mod0(.clk(clk), .rst_n(rst_n), .a(a),    .b(b),    .c(tmp0));
    sub_mod sub_mod1(.clk(clk), .rst_n(rst_n), .a(tmp0),    .b(c_0),    .c(d));
endmodule

module sub_mod(
    input clk,
    input rst_n,
    input [7:0] a,
    input [7:0] b,
    
    output [7:0] c
);
    reg [7:0] c_r;
    always@(posedge clk or negedge rst_n) begin
        if(~rst_n)
            c_r <= 8'b0;
        else 
            c_r <= a < b? a:b;
    end
    assign c = c_r;
endmodule

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

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值