目录
第一种情况:表达式不对以及输入输出的bit数目不匹配
第二种情况:实例引用有误和缺少输出语句
第三种情况:实例引用名和子模块中的输出名一致
第四种情况:缺乏else的情况和if条件表达式有误
第五种情况:细节处理:十进制、十六进制的字符表示以及缺乏begin end
第一种情况:表达式不对以及输入输出的bit数目不匹配 此 8 位宽 2:1 多路复用器无法正常工作。修复错误。
模块声明
module top_module ( input sel, input [7:0] a, input [7:0] b, output [7:0] out);
文章图片
应将代码修改如下:因为是2输入的数据选择器,其中sel是数据选择端。该数据选择器的原理为:当sel为0时,输出端选择输出的数据是a,但sel为1时,输出端选择输出的数据是b。同时输入a,b的位宽都为8bit,输出的位宽也应该为8bit。由此可得代码如下:
module top_module (
input sel,
input [7:0] a,
input [7:0] b,
output [7:0]out);
assign out = sel ? a:b;
endmodule
第二种情况:实例引用有误和缺少输出语句 此三输入 NAND 门不起作用。修复错误。
您必须使用提供的 5 输入 AND 门:
module andgate ( output out, input a, input b, input c, input d, input e );
模块声明
module top_module (input a, input b, input c, output out);
文章图片
【HDLBITS学习笔记|HDLBITS笔记37(testbench错误检测集合1)】 分析:观察代码,在题目所提供的 andgate 模块中是一个5输入的与门,而在例化时使用的顶层模块是一个3输入1输出的模块。因此需要将没有引用到的端口置相应的电平。同时,分析题目说该门没有起到作用的意思可以将其理解为没有输出,观察代码可以发现代码中没有assign赋值语句也没有使用always等可以对输出进行赋值的语句。因此修改代码如下:
module top_module (input a, input b, input c, output out);
//
wire d,e,out1;
andgate inst1 ( .a(a), .b(b), .c(c), .d(1'b1),.e(1'b1),.out(out1) );
assign out = !out1;
endmodule
需要注意的是在上述代码中我使用的是名称关联法对父模块和子模块进行实例引用,而原始题目中给的代码则是位置关联的方法。在这里使用名称关联方法的主要原因是需要将父模块中没有用到的值置相应的电平。
第三种情况:实例引用名和子模块中的输出名一致 此 4 对 1 多路复用器无法正常工作。修复错误。
我们为您提供了一个无错误的 2 对 1 多路复用器:
module mux2 ( input sel, input [7:0] a, input [7:0] b, output [7:0] out );
模块声明
module top_module ( input [1:0] sel, input [7:0] a, input [7:0] b, input [7:0] c, input [7:0] d, output [7:0] out);
文章图片
观察上述代码和分析题意:这是一个4选1的数据选择器,其中是由3个2选1的数据选择器例化而成。首先注意到的第一点就是wire型的mux0和mux1和实例引用名的名称一致,这是不被允许的。 第二点就是mux0和mux1这两个的输出构成了mux2的输入,因此sel的索引应该是一致的。第三点是输出和输入的位宽不匹配。
由此可得代码如下:上述实例引用的方式为位置关联法。
module top_module (
input [1:0] sel,
input [7:0] a,
input [7:0] b,
input [7:0] c,
input [7:0] d,
output [7:0] out);
//wire [7:0]mux0, mux1;
mux2 u0 ( sel[0],a,b, mux0 );
mux2 u1 ( sel[0],c,d, mux1 );
mux2 u2 ( sel[1], mux0, mux1,out );
endmodule
第四种情况:缺乏else的情况和if条件表达式有误 以下具有零标志的加法器-减法器不起作用。修复错误。
模块声明
// synthesis verilog_input_version verilog_2001 module top_module ( input do_sub, input [7:0] a, input [7:0] b, output reg [7:0] out, output reg result_is_zero );
文章图片
题目给的是一个加法器-减法器的程序。其中加法器-减法器的工作原理可参考:
加法器和减法器
在加法器-减法器中,当do-sub为0时实现的是加法;当do-sub为1时实现的是减法。在代码中可以看出当if的是表达式实现的时候置零位为1,但是其并不是完整的,因为还有else的情况(即题目所说的具有零标志的加法器-减法器不起作用)。如果缺乏else的话会造成出现latch的情况。
但是如果仅仅增加else的情况而不对if语句中的条件表达式进行修改的话,result_is_zero的结果仍会报错,这是因为out是8位的,而 if (~out)是按位取反,只有当out全为1的时候,(~out)才会是0,result_is_zero = 0; 才会被执行。而加法器-减法器中的零标志位的意思是当out为0时,result_is_zero为真。
由此可得代码如下:
// synthesis verilog_input_version verilog_2001
module top_module (
input do_sub,
input [7:0] a,
input [7:0] b,
output reg [7:0] out,
output reg result_is_zero
);
//always @(*) begin
case (do_sub)
0: out = a+b;
1: out = a-b;
endcaseif (out == 8'b0)
result_is_zero = 1;
else
result_is_zero = 0;
endendmodule
其中下图第一张图为 if (~out )时result_is_zero的取值,第二张图为if (out == 8'b0)时result_is_zero
的取值。
文章图片
文章图片
第五种情况:细节处理:十进制、十六进制的字符表示以及缺乏begin end 这种组合电路应该识别按键0到9的8位键盘扫描码。它应该指示10个案例中的一个是否被识别(有效),如果是,则检测到哪个密钥。修复错误。
模块声明
module top_module ( input [7:0] code, output reg [3:0] out, output reg valid=1 );
文章图片
注意:十进制、十六进制的表示符合以及valid的作用。
module top_module (
input [7:0] code,
output reg [3:0] out,
output reg valid );
//always @(*) begin
case (code)
8'h45: out = 0;
8'h16: out = 1;
8'h1e: out = 2;
8'h26: out = 3;
8'h25: out = 4;
8'h2e: out = 5;
8'h36: out = 6;
8'h3d: out = 7;
8'h3e: out = 8;
8'h46: out = 9;
default: out = 0;
endcase
if((out == 0) &(code != 8'h45))
valid = 0;
else
valid = 1;
endendmodule
推荐阅读
- DDR3|FPGA-DDR总线电源硬件设计技巧-Fly-by走线阻抗
- RISC-V|带你一起看代码(11.RISC-V外设解析(UART)——终篇)
- 数字IC设计|十一、RISC-V SoC外设注解——UART接口 时序设计 代码讲解(终篇)
- #|FPGA基础设计(三)(状态机(FSM))
- 设计|FSM有限状态机(三段式)-Verilog实现
- verilog|verilog中一文搞懂有限状态机(FSM)Mealy和Moore状态机(及一段式,二段式,三段式)
- HDLBits|HDLBits练习-有限状态机FSM