题解 | #使用子模块实现三输入数的大小比较#

使用子模块实现三输入数的大小比较

https://www.nowcoder.com/practice/bfc9e2f37fe84c678f6fd04dbce0ad27

本来也准备直接例化两次;看完揭发后发现不行,还是需要例化三次。参考解法和讨论,做下记录防止自己汪

参考解法:

1.子模块写成组合逻辑,一个周期就可以比较完。比答案早一个周期,要对的话要打一拍。

2,子模块也带时序,用两个模块先比较a和b,a和c。再用一个模块比较它两的结果,跟答案一样。

3,子模块也带时序,一个模块比较a和b得到d1;将c打一拍,再用一个模块比较d2和c,在d1出现的下一个周期得到结果。先选择a、b最小的输出m,然后再将m与c比较输出d,因此需要2拍延迟。如果a、b最小值m直接与c进行比较,则时序错误,c永远比较的都是m的前一拍的值,故需要将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] min_ab,min_ac;
	son_mod min1(
		.clk(clk),
		.rst_n(rst_n),
		.data_a(a),
		.data_b(b),
		.data_c(min_ab)
	);
	son_mod min2(
		.clk(clk),
		.rst_n(rst_n),
		.data_a(a),
		.data_b(c),
		.data_c(min_ac)
	);
	son_mod min3(
		.clk(clk),
		.rst_n(rst_n),
		.data_a(min_ab),
		.data_b(min_ac),
		.data_c(d)
	);


endmodule

module son_mod(
	input clk,
	input rst_n,
	input [7:0] data_a,
	input [7:0] data_b,

	output [7:0] data_c
);
	reg[7:0] c_r;
	always@(posedge clk or negedge rst_n)begin
		if (!rst_n)
			c_r <= 0;
		else if (data_a < data_b)
			c_r <= data_a;
		else c_r <= data_b;
	end
	assign data_c = c_r;

endmodule

testbench

testbench中module test();要改成module testbench();

`timescale 1ns/1ns 
module testbench();
    reg signed [7:0] a,b,c;
    reg clk,rst_n;
    wire [7:0]d;
initial begin 
    $dumpfile("out.vcd");
    $dumpvars(0,testbench);
end 
//always #5 clk = !clk; 
initial begin 
    clk = 1;
    repeat(50) #1 clk = ~clk;
end 
 
initial begin 
    rst_n = 0;
    #2;rst_n = 1;
end 
main_mod dut(
    .clk(clk),
    .rst_n(rst_n),
    .a(a),
    .b(b),
    .c(c),
    .d(d)
);
initial begin 
    #2;
    a = 1;
    b = 2;
    c = 3;
    #10;
    a = 6;
    b = 5;
    c = 4;
    #10;
    a = 9;
    b = 7;
    c = 8;
    #20 
    $stop;
end 
endmodule 

看图形可以看出来比较会有延时。

看讨论大神讲的有道理,没看懂。先做个标记以后看。(实际上例化2个子模块也可以,比较器里也可以用组合逻辑写。。这个没看懂)

tb里想的是比较器用时序逻辑写,例化3个子模块,这样需要2个周期计算出结果

实际上例化2个子模块也可以,比较器里也可以用组合逻辑写

如果比较器里用组合逻辑写,例化2个或者3个子模块都可以,这样子当前周期就可以直接计算出结果,那么做完之后将输出结果打2拍就和tb结果一致了

如果比较器里用时序逻辑写,例化3个子模块,是和tb一致

如果比较器里用时序逻辑写,例化2个子模块,其中第一个子模块输入a、b,第二个子模块输入ab的最小值和c_1d,这样需要1个周期计算出结果,所以将结果打1拍就可以和tb结果一致

用组合逻辑+2个子模块的代码:(我不知道这个为什么是组合逻辑。。看来我自己写的就是组合逻辑。那么时序逻辑得代码又是什么样子?)

wire [7:0] min_a_b;
    gen_min Inst_a_b (
        .clk    (clk),
        .rst_n    (rst_n),
        .a    (a),
        .b    (b),
        .c    (min_a_b)
    );
    
    wire [7:0] min_a_b_c;
    gen_min Inst_a_b_c (
        .clk    (clk),
        .rst_n    (rst_n),
        .a    (min_a_b),
        .b    (c),
        .c    (min_a_b_c)
    );
    
    reg [7:0] min_abc_1d;
    reg [7:0] min_abc_2d;
    always @ (posedge clk&nbs***bsp;negedge rst_n) begin
        if (~rst_n) begin
            min_abc_1d <= 'd0;
            min_abc_2d <= 'd0;
        end
        else begin
            min_abc_1d <= min_a_b_c;
            min_abc_2d <= min_abc_1d;
        end
    end
    
    assign d = min_abc_2d;

endmodule

全部评论

相关推荐

02-15 22:29
门头沟学院 Java
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务