Verilog编程基础练习

1、用Logsim绘制一个3-8译码器电路图

在这里插入图片描述
其真值表为:
在这里插入图片描述

2、用Verilog编程设计一个3-8译码器,生成RTL原理电路图

代码为:

module D3_8( 
	a, 
	b, 
	c, 
	out 
);
input a; //输入端口a 
input b; //输入端口b 
input c; //输入端口c 
output [7:0]out;//输出端口out 
 
reg [7:0]out; 
always@(a,b,c)
begin 
	case({a,b,c}) 
	3'b000:out = 8'b0000_0001; 
	3'b001:out = 8'b0000_0010; 
	3'b010:out = 8'b0000_0100; 
	3'b011:out = 8'b0000_1000; 
	3'b100:out = 8'b0001_0000; 
	3'b101:out = 8'b0010_0000; 
	3'b110:out = 8'b0100_0000; 
	3'b111:out = 8'b1000_0000; 
	endcase 
end
endmodule

RTL电路为:
在这里插入图片描述

3、编写一个仿真测试文件,对3-8译码器进行仿真测试,输出测试波形图和Transcript结果

modelsim电路仿真文件为:

timescale 1ns/1ns

 module three_to_eight_tb();
 reg  a;
 reg  b;
 reg  c;
 wire   [7:0]   out;
 initial    begin
    a <= 1'b1;
    b <= 1'b0;
    c <= 1'b1;
 end
 //a:产生随机数,模拟 a 的输入情况
 always #10 a <= {$random} % 2;
 //b:产生随机数,模拟 b 的输入情况
 always #10 b <= {$random} % 2;
 //c:产生随机数,模拟c 的输入情况
 always #10 c <= {$random} % 2;
 initial begin
    $timeformat(-9, 0, "ns", 6);
    $monitor("@time %t:a=%b b=%b c=%b out=%b",$time,a,b,c,out);
 end
 three_to_eight three_to_eight_ins
 (
    .a(a), 
    .b(b),
    .c(c),
    .out(out)
 );
 endmodule

仿真结果:
在这里插入图片描述

4、回答问题

(1)Verilog 综合生成的3-8译码器电路原理图与原始设计电路存在什么差异? 仿真测试生成的结果是否与真值表一致?

答:使用不同的技术库或综合设置可能会导致综合工具做出不同的选择,从而产生差异。在Verilog设计中,仿真测试应该与真值表一致。然而,综合后的电路可能在实际硬件中运行,因此仿真测试结果与真值表的一致性并不总是绝对的。

(2) Verilog代码设计的3-8译码器模块的输出信号为何要定义为 reg类型而不用默认wire(导线)类型?改成wire型是否可以? (即是否可以把 output reg [7:0] out 改为 output [7:0] out) 修改后会出现什么错误?为什么会出错?

答:在Verilog中,reg 和 wire 分别用于表示寄存器类型和导线类型。默认情况下,output 端口的信号类型是 wire,因此你可以直接写 output [7:0] out,而不必显式指定为 reg。修改为 output [7:0] out 不会导致错误,因为输出端口的默认类型是 wire。这是因为在组合逻辑中,信号之间的连接通常使用 wire 类型。然而,在某些情况下,你可能需要使用 reg 类型的输出信号,比如在时序逻辑中,如在 always 块中存储信号的状态。
如果确实需要在 output 中使用 reg 类型,可以显式声明为 output reg [7:0] out。这通常在时序逻辑中需要存储输出状态时使用。如果在组合逻辑中使用 reg 类型,可能会导致一些综合工具给出的警告,因为在组合逻辑中,通常使用 wire 类型更为合适。
总的来说,对于组合逻辑,可以使用默认的 wire 类型,而对于时序逻辑,可能需要使用 reg 类型。如果在组合逻辑中使用了 reg 类型,Verilog 编译器通常会发出警告,但不会导致编译错误。

1、用Verilog的门级描述方式写一个“1位全加器”, 生成RTL电路,与Logsim的“1位全加器”进行对比。

其verilog代码为:

module FullAdder_gate_level (
  input A, B, Cin,
  output Sum, Cout
);
  wire X1, X2, X3, X4;
  assign X1 = A ^ B;
  assign X2 = X1 ^ Cin;
  assign X3 = A & B;
  assign X4 = X1 & Cin;
  assign Sum = X2;
  assign Cout = X3 | X4;
  
endmodule

RTL电路图为:
在这里插入图片描述
logisim电路图为:
在这里插入图片描述

2、用Verilog模块调用子模块的方式,用4个上面的“1位全加器”级联方式,构成一个“4位全加器”(即串行全加器),生成RTL电路,与Logsim的“4位全加器”电路进行对比

四位全加器verilog代码:

module FourBitAdder_gate_level (
  input [3:0] A, B, Cin,
  output [3:0] Sum, Cout
);
  wire C1, C2, C3;
  wire S1, S2, S3;
  FullAdder_gate_level f1 (.A(A[0]), .B(B[0]), .Cin(Cin), .Sum(S1), .Cout(C1));
  FullAdder_gate_level f2 (.A(A[1]), .B(B[1]), .Cin(C1), .Sum(S2), .Cout(C2));
  FullAdder_gate_level f3 (.A(A[2]), .B(B[2]), .Cin(C2), .Sum(S3), .Cout(C3));
  FullAdder_gate_level f4 (.A(A[3]), .B(B[3]), .Cin(C3), .Sum(Sum[3]), .Cout(Cout));
endmodule
module FullAdder_gate_level (
  input A, B, Cin,
  output Sum, Cout
);
  wire X1, X2, X3, X4;
  assign X1 = A ^ B;
  assign X2 = X1 ^ Cin;
  assign X3 = A & B;
  assign X4 = X1 & Cin;
  assign Sum = X2;
  assign Cout = X3 | X4;
endmodule

RTL电路图为:
在这里插入图片描述
logisim电路图为:
在这里插入图片描述

3、采用Verilog的行为级方式重新完成上面的1和2

1位全加器verilog代码:

module FullAdder_functional_level (
  input A, B, Cin,
  output Sum, Cout
);
  assign {Cout, Sum} = A + B + Cin;
endmodule

1位全加器RTL电路图:
在这里插入图片描述
四位全加器verilog代码:

module FullAdder_functional_level (
  input A, B, Cin,
  output Sum, Cout
);
  assign {Cout, Sum} = A + B + Cin;
endmodule
module FourBitAdder_functional_level (
  input [3:0] A, B, Cin,
  output [3:0] Sum,
  output Cout
);
  wire c1, c2, c3;
  FullAdder_functional_level fa1(A[0], B[0], Cin, Sum[0], c1);
  FullAdder_functional_level fa2(A[1], B[1], c1, Sum[1], c2);
  FullAdder_functional_level fa3(A[2], B[2], c2, Sum[2], c3);
  FullAdder_functional_level fa4(A[3], B[3], c3, Sum[3], Cout);
endmodule

4位全加器RTL电路图:
在这里插入图片描述

4、采用Verilog设计一个8位全加器模块

8位全加器verilog代码:

module eight_bit_adder(
    input [7:0] a,
    input [7:0] b,
    input cin,
    output [7:0] sum,
    output cout
);
wire [7:0] c;
full_adder fa0(a[0], b[0], cin, sum[0], c[0]);
full_adder fa1(a[1], b[1], c[0], sum[1], c[1]);
full_adder fa2(a[2], b[2], c[1], sum[2], c[2]);
full_adder fa3(a[3], b[3], c[2], sum[3], c[3]);
full_adder fa4(a[4], b[4], c[3], sum[4], c[4]);
full_adder fa5(a[5], b[5], c[4], sum[5], c[5]);
full_adder fa6(a[6], b[6], c[5], sum[6], c[6]);
full_adder fa7(a[7], b[7], c[6], sum[7], cout);
endmodule
module full_adder(
    input a,
    input b,
    input cin,
    output sum,
    output cout
);
assign sum = a ^ b ^ cin;
assign cout = (a & b) | (a & cin) | (b & cin);
endmodule

8位全加器RTL电路图:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值