Verilog写题笔记9--使用子模块实现三输入数的大小比较

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

https://www.nowcoder.com/practice/bfc9e2f37fe84c678f6fd04dbce0ad27?tpId=301&tqId=5000623&ru=/exam/oj&qru=/ta/verilog-start/question-ranking&sourceUrl=%2Fexam%2Foj%3Fpage%3D1%26tab%3DVerilog%25E7%25AF%2587%26topicId%3D301

这个题是第一道分子模块的题目:
子模块有四个输入:
1、时钟信号clk
2、复位信号rst_n
3、8位数据a
4、8位数据b
一个输出:
8位数据c
子模块要完成的任务是两个数比大小,这几乎没有难度,也没什么好说的,直接把代码放出来:
module zimokuai(
	input clk,
	input rst_n,
	input [7:0]a,
	input [7:0]b,
	
	output reg [7:0] d_reg
);

always@(posedge clk or negedge rst_n)
	if(rst_n == 1'b0)
		d_reg <= 8'd0;
	else if(a < b)
		d_reg <= a;
	else
		d_reg <= b;

endmodule
这个题主要想考察的还是子模块的调用
Verilog子模块的调用相对于c还是有些麻烦的。Verilog的模块调用主要有一下几点要注意的:
1、顶层模块的所有变量都必须是wire型
    理解起来也不是很难,子模块是一个黑盒子,顶层模块只需要将线连到子模块中即可,所以是wire型也就顺理成章了
2、如果是多个子模块调用,子模块的中间输出也必须在顶层模块声明。(当然也是wire型)
    这个题就是一个例子,顶层模块调用了 三次子模块,且子模块之间是有联系的,这时顶层模块必须将中间输出也声明出来。
3、子模块的调用的语法结构如下:
    子模块名 (必须与子模块名完全相同)  顶层模块名(可以随便起)(
            .子模块变量1(必须与子模块中变量名完全相同)(顶层模块变量1),
            .子模块变量2(必须与子模块中变量名完全相同)(顶层模块变量2),
            ...
     );
    这个是子模块调用的结构。结构的讲解我这里不再赘述。如果读者看不懂,可以先查阅其他资料学习Verilog语法,不用急于做题。
顶层模块需要比较三个数的值,然后再输出最小的。如果我们编译的是c语言,我们很容易想到,只输出极值的比较题,只需要调用两次子模块就好了,第一次比较a和b,然后再将ab的最小值跟c去比即可。
但是,在Verilog中,这个思路是不行的。如果我们按照c语言的思路只用两次子模块,会输出错误的结果。问题在于时序,FPGA是并行执行的,如图所示:

在第一个上升沿,ab进入第一个比较器,c进入第二个比较器。但是比较器输出是需要时间的,在第一个上升沿,c立刻进入第二个比较器,但ab比较器的输出会较晚的进入第二个比较器,这就造成了输入时间不同步,从而造成输出错误。
解决办法也很简单,用三个比较器即可。

用三个比较器的目的是让输入子模块的时间都相等,这样就不会出现进入时间不同导致的错误。
所有代码如下:
`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] x,y;
     
zimokuai zimokuai_inst1(
    .clk(clk),
    .rst_n(rst_n),
    .a(a),
    .b(b),
     
    .d_reg(x)
);
     
zimokuai zimokuai_inst2(
    .clk(clk),
    .rst_n(rst_n),
    .a(a),
    .b(c),
     
    .d_reg(y)
); 
     
zimokuai zimokuai_inst3(
    .clk(clk),
    .rst_n(rst_n),
    .a(x),
    .b(y),
     
    .d_reg(d)
);     
endmodule
 
 
 
 
 
 
 
module zimokuai(
    input clk,
    input rst_n,
    input [7:0]a,
    input [7:0]b,
     
    output reg [7:0] d_reg
);
 
always@(posedge clk or negedge rst_n)
    if(rst_n == 1'b0)
        d_reg <= 8'd0;
    else if(a < b)
        d_reg <= a;
    else
        d_reg <= b;
 
endmodule












verilog写题笔记 文章被收录于专栏

写Verilog题目的一些笔记备忘

全部评论
打一拍就完了
点赞 回复 分享
发布于 2024-05-15 13:57 上海

相关推荐

北漂的牛马人:211佬,包进的,可能是系统问题
点赞 评论 收藏
分享
04-25 18:13
五邑大学 Java
后来123321:大二两段实习太厉害了,我现在大二连面试都没有
点赞 评论 收藏
分享
就只能3个月,但是要求长期全职实习
Swaying:你确实是能长期实习啊,但是你那时候有事也没啥办法嘛
点赞 评论 收藏
分享
评论
7
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务