Verilog编程基础练习


一、3-8译码器的实验与仿真

1.logisim绘制3-8译码器

利用logisim绘制出3-8译码器电路如下:
在这里插入图片描述
其真值表如下:

A2A1A0B7B6B5B4B3B2B1B0
00000000001
00100000010
01000000100
01100001000
10000010000
10100100000
11001000000
11110000000

2.quartus软件利用verilog语言生成RTL电路并实现仿真

1)verilog实现三八译码器代码如下

module three_to_eight( 
	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

2)生成的RTL电路

在这里插入图片描述

3)quartus电路仿真结果

在这里插入图片描述
仿真结果正确,仿真正确

4)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
 

仿真结果如下:
在这里插入图片描述
仿真结果正确,仿真正确

5)问题分析

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

答:verilog综合生成的电路将内部的基本门电路进行封装,只通过输入与输出来观察相应的功能,简化了操作;仿真测试生成的结果与真值表一致。

2.Verilog代码设计的3-8译码器模块的输出信号 为何要定义为 reg类型而不用默认wire(导线)类型?改成wire型是否可以?

答:wire型数据常用来表示以assign关键字指定的组合逻辑信号,模块的输入输出端口类型都默认为wire型,wire相当于物理连线,默认初始值是z(高组态)。reg型表示的寄存器类型,用于always模块内被赋值的信号,必须定义为reg型,代表触发器,常用于时序逻辑电路,reg相当于存储单元,默认初始值是x(未知状态)。三八译码器中使用always语句是过程赋值应该使用reg类型的输出模块,若替换成wir类型会发生错误。

二、全加器电路实验

1.一位全加器

1)门级描述

verilog代码如下:

module ad_1(A,B,cin,sum,cout);
	input A,B,cin;
	output sum,cout;
	wire t1,t2,t3,t4;
	and U1(t1,A,B);
	and U2(t2,A,cin);
	and U3(t3,B,cin);
	or U4(cout,t1,t2,t3);
	xor U5(t4,A,B);
	xor U6(sum,t4,cin);
endmodule

RTL电路如下:
请添加图片描述
logisim电路如下:

在这里插入图片描述

2)行为级描述

verilog代码如下:

module ad_12 (
  input A, B, Cin,
  output Sum, Cout

);
  assign {Cout, Sum} = A + B + Cin;
endmodule


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

2.四位全加器

1)门级描述

verilog代码如下:

module ad1(A,B,cin,sum,cout);
	input A,B,cin;
	output sum,cout;
	wire t1,t2,t3,t4;
	and U1(t1,A,B);
	and U2(t2,A,cin);
	and U3(t3,B,cin);
	or U4(cout,t1,t2,t3);
	xor U5(t4,A,B);
	xor U6(sum,t4,cin);
endmodule

module ad4
(
	input [3:0]A,B,
	input cin,
	output [3:0]sum,
	output cout
);
	wire[4:0]c;
	assign c[0] = cin;
	ad1 ad10(A[0],B[0],c[0],sum[0],c[1]);
	ad1 ad11(A[1],B[1],c[1],sum[1],c[2]);
	ad1 ad12(A[2],B[2],c[2],sum[2],c[3]);
	ad1 ad13(A[3],B[3],c[3],sum[3],c[4]);
	assign cout = c[4];
endmodule

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

2)行为级描述

verilog代码如下:

module ad1 (
  input A, B, Cin,
  output Sum, Cout

);
  assign {Cout, Sum} = A + B + Cin;
endmodule


module ad4
(
	input [3:0]A,B,
	input cin,
	output [3:0]sum,
	output cout
);
	wire[4:0]c;
	assign c[0] = cin;
	ad1 ad10(A[0],B[0],c[0],sum[0],c[1]);
	ad1 ad11(A[1],B[1],c[1],sum[1],c[2]);
	ad1 ad12(A[2],B[2],c[2],sum[2],c[3]);
	ad1 ad13(A[3],B[3],c[3],sum[3],c[4]);
	assign cout = c[4];
endmodule

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

3.八位全加器

verilog代码如下:

module ad8 (
  input [7:0] A, B, 
  input cin,
  output[7:0]sum, 
  output cout

);
  assign {cout, sum} = A + B + cin;
endmodule


RTL电路如下:

在这里插入图片描述

三、16位ALU(算术逻辑单元)的电路设计

1.verilog语言实现及其RTL电路

module ALU16 (
    input [15:0] operand_A,
    input [15:0] operand_B,
    input [2:0]  opcode,  // 0: ADD, 1: SUB, 2: AND, 3: OR, 4: XOR, 5: NOT
    output reg [15:0] result,
    output reg zero_flag
);

always @* begin
    case(opcode)
        3'b000: result = operand_A + operand_B;      // 加法
        3'b001: result = operand_A - operand_B;      // 减法
        3'b010: result = operand_A & operand_B;      // 与
        3'b011: result = operand_A | operand_B;      // 或
        3'b100: result = operand_A ^ operand_B;      // 或非
        3'b101: result = ~operand_A;                 // 非
        default: result = 16'b0;                     // Default case (optional)
    endcase

    // Set zero_flag
    zero_flag = (result == 16'b0);
end

endmodule


在这个模块中,operand_A和operand_B是输入的16位操作数,opcode是控制ALU执行哪种操作的3位输入。result是16位输出,表示ALU的计算结果。zero_flag表示结果是否为零,如果为零则置1,否则置0。

在这里插入图片描述

2.仿真测试

仿真文件:

`timescale 1ns/1ps

module ALU16_tb;

  // Inputs
  reg [15:0] operand_A;
  reg [15:0] operand_B;
  reg [2:0]  opcode;

  // Outputs
  wire [15:0] result;
  wire zero_flag;

  // Instantiate the ALU module
  ALU16 uut (
    .operand_A(operand_A),
    .operand_B(operand_B),
    .opcode(opcode),
    .result(result),
    .zero_flag(zero_flag)
  );

  // Stimulus generation
  initial begin
    // Test case 1: ADD
    operand_A = 8'b11001100;
    operand_B = 8'b00110011;
    opcode = 3'b000;
    #10;

    // Test case 2: SUB
    operand_A = 8'b11001100;
    operand_B = 8'b00110011;
    opcode = 3'b001;
    #10;

    // Test case 3: AND
    operand_A = 8'b11001100;
    operand_B = 8'b00110011;
    opcode = 3'b010;
    #10;

    // Test case 4: OR
    operand_A = 8'b11001100;
    operand_B = 8'b00110011;
    opcode = 3'b011;
    #10;

    // Test case 5: XOR
    operand_A = 8'b11001100;
    operand_B = 8'b00110011;
    opcode = 3'b100;
    #10;

    // Test case 6: NOT
    operand_A = 8'b11001100;
    opcode = 3'b101;
    #10;

    $stop;
  end

endmodule

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值