Verilog基础编程练习

这篇具有很好参考价值的文章主要介绍了Verilog基础编程练习。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、关于Quartus和ModelSim的安装

请自行搜索方法,比较简单,本文使用quartus ii 13.1和Modelsim SE-10.4进行练习。

二、关于3-8译码器的实验仿真

(一)对比分析Verilog生成的电路原理图和原始设计电路

使用Logsim绘制一个3-8译码器的电路图:
Verilog基础编程练习,fpga开发,物联网
真值表:
Verilog基础编程练习,fpga开发,物联网
利用Verilog代码生成RTL电路图:

module decoder3_8

 (

    input   wire    in1 ,   //输入信号 in1

    input   wire    in2 ,   //输入信号 in2

    input   wire    in3 ,   //输入信号 in3

    output reg [7:0]    out     //输出信号 out

 );

 //out:根据输入的 3bit in 信号选择输出对应的 8bit out 信号

 always@(*)

    case({in1, in2, in3})

        3'b000 : out = 8'b0000_0001;    //输入与输出的 8 种译码对应关系

        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;

 //因为 case 中列举了 in 所有可能输入的 8 种情况,且每种情况都有对应确定的输出

 //所以此处 default 可以省略,但是为了以后因不能够完全列举而产生 latch

 //所以我们默认一定要加上 default,并任意指定一种确定的输出情况

        default: out = 8'b0000_0001;

    endcase

 endmodule
 

Verilog基础编程练习,fpga开发,物联网
测试文件:

`timescale 1ns/1ns

 module tb_decoder3_8();

 //reg define

 reg        in1;

 reg        in2;

 reg        in3;

 //wire     define

 wire   [7:0]   out;

 //初始化输入信号

 initial    begin

    in1 <= 1'b0;

    in2 <= 1'b0;

    in3 <= 1'b0;

 end

 //in1:产生输入随机数,模拟输入端 1 的输入情况

 always #10 in1 <= {$random} % 2;

 //in2:产生输入随机数,模拟输入端 2 的输入情况

 always #10 in2 <= {$random} % 2;

 //in3:产生输入随机数,模拟输入端 3 的输入情况

 always #10 in3 <= {$random} % 2;

 //------------------------------------------------------------

 initial begin

    $timeformat(-9, 0, "ns", 6);

    $monitor("@time %t:in1=%b in2=%b in3=%b out=%b",$time,in1,in2,in3,out);

 end

 //------------------------------------------------------------

 //-------------decoder3_8_inst----------------

 decoder3_8 decoder3_8_ins

 (

    .in1(in1), //input in1

    .in2(in2), //input in2

    .in3(in3), //input in3

    .out(out) //output [7:0] out

 );

 endmodule
 

在Modelsim中仿真分析生成波形图和transcript结果:
Verilog基础编程练习,fpga开发,物联网
通过对比,可以看出两者的电路图思路是一样的,不过verilog生成的电路图把中间复杂的接线部分改成了一个模块,看起来更简洁。
同时,仿真测试的结果与真值表是一致的。

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

分析:在Verilog中,reg类型表示寄存器类型,用于always模块内被赋值的信号。而wire类型表示导线类型,用于always模块内未被赋值的信号。因为3-8译码器模块的输出信号out是在always块中被赋值的,所以必须定义为reg类型。如果将output reg [7:0] out改为output [7:0] out,会出现“Multiple drivers”错误,因为wire类型的信号可以有多个驱动器,而reg类型的信号只能有一个驱动器。因此,如果将out定义为wire类型,会出现多个驱动器的情况,从而导致错误。

三、关于全加器的实验仿真

(一)Verilog的1位全加器和4位全加器(门级描述方式)

1.一位全加器:

Verilog代码:

module FullAdder_gate_level (

  input A, B, Cin,

  output Sum, Cout

);

  

  wire X1, X2, X3, X4;

  // XOR gates

  assign X1 = A ^ B;

  assign X2 = X1 ^ Cin;

  // AND gates

  assign X3 = A & B;

  assign X4 = X1 & Cin;

  // OR gates

  assign Sum = X2;

  assign Cout = X3 | X4;

  

endmodule

1位全加器RTL电路图:
Verilog基础编程练习,fpga开发,物联网
对比1位全加器logisim电路:
Verilog基础编程练习,fpga开发,物联网

2.四位全加器

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;

  // XOR gates

  assign X1 = A ^ B;

  assign X2 = X1 ^ Cin;

  // AND gates

  assign X3 = A & B;

  assign X4 = X1 & Cin;

  // OR gates

  assign Sum = X2;

  assign Cout = X3 | X4;

  

endmodule

4位全加器RTL电路图:
Verilog基础编程练习,fpga开发,物联网
对比4位全加器logisim电路:
Verilog基础编程练习,fpga开发,物联网

(二)Verilog的1位全加器和4位全加器(行为级描述方式)

1.一位全加器

Verilog代码:

module FullAdder_functional_level (

  input A, B, Cin,

  output Sum, Cout

);

  

  // Full Adder logic

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

  

endmodule

1位全加器RTL电路图:
Verilog基础编程练习,fpga开发,物联网
对比1位全加器logisim电路:
Verilog基础编程练习,fpga开发,物联网

2.四位全加器

Verilog代码:

module FullAdder_functional_level (

  input A, B, Cin,

  output Sum, Cout

);

  

  // Full Adder logic

  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电路图:
Verilog基础编程练习,fpga开发,物联网
对比4位全加器logisim电路:
Verilog基础编程练习,fpga开发,物联网

(三)Verilog的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

生成的RTL电路图:
Verilog基础编程练习,fpga开发,物联网

四、拓展实验

学习利用并行加法器原理(先行进位加法器),完成一个16位ALU(算术逻辑单元)的电路设计,采用Verilog设计模式,生成RTL电路。

Verilog代码:

module ALU_16bit (

  input [15:0] operand_A,

  input [15:0] operand_B,

  input [2:0]  opcode,

  input       cin,

  output reg [15:0] result,

  output      cout,

  output      zero

);

  

  reg [15:0] temp_result;

  

  always @*

    case(opcode)

      3'b000: temp_result = operand_A + operand_B;

      3'b001: temp_result = operand_A - operand_B;

      3'b010: temp_result = operand_A & operand_B;

      3'b011: temp_result = operand_A | operand_B;

      3'b100: temp_result = operand_A ^ operand_B;

      3'b101: temp_result = operand_A + 1;

      3'b110: temp_result = operand_A - 1;

      3'b111: temp_result = ~operand_A;

      default: temp_result = 16'b0;

    endcase

  

  assign cout = (temp_result[15] == 1) ? 1'b1 : 1'b0; // Fix index to 15

  assign zero = (temp_result == 16'b0) ? 1'b1 : 1'b0;

  always @*

    if (cin)

      result = temp_result + 1;

    else

      result = temp_result;

  

endmodule

RTL电路图:
Verilog基础编程练习,fpga开发,物联网
测试文件:

module ALU_16bit_tb;

  

  reg [15:0] operand_A;

  reg [15:0] operand_B;

  reg [2:0]  opcode;

  reg       cin;

  wire [15:0] result;

  wire       cout;

  wire       zero;

  

  ALU_16bit uut (

    .operand_A(operand_A),

    .operand_B(operand_B),

    .opcode(opcode),

    .cin(cin),

    .result(result),

    .cout(cout),

    .zero(zero)

  );

  

  initial begin

    // Test case 1: Addition

    operand_A = 16'b1010101010101010;

    operand_B = 16'b0101010101010101;

    opcode = 3'b000;

    cin = 1'b0;

    #10;

    // Test case 2: Subtraction

    operand_A = 16'b1010101010101010;

    operand_B = 16'b0101010101010101;

    opcode = 3'b001;

    cin = 1'b0;

    #10;

  

    // Add more test cases as needed

  

    $stop;

  end

  

endmodule

Modelsim仿真结果:
Verilog基础编程练习,fpga开发,物联网文章来源地址https://www.toymoban.com/news/detail-770731.html

到了这里,关于Verilog基础编程练习的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【FPGA Verilog开发实战指南】初识Verilog HDL-基础语法

    就是用代码来描述硬件结构 语言有VHDL与Verilog HDL Verilog HDL 是从C语言来的,学的快 ###例子 也叫保留字,一般是小写 module 表示模块的开始 endmodule 模块的结束 模块名 一般与.v文件的名字一致 输入信号 input 输出信号 output 既做输入也做输出 inout 需要一些变量和参数对输

    2024年02月21日
    浏览(43)
  • Verilog编程:位数值比较器 FPGA

    Verilog编程:位数值比较器 FPGA 在FPGA(现场可编程门阵列)的数字电路设计中,位数值比较器是一个重要的组件。位数值比较器用于比较两个二进制值的大小,并输出比较的结果。本文将介绍如何使用Verilog编程语言实现一个简单的位数值比较器,并演示相应的源代码。 首先,

    2024年04月14日
    浏览(34)
  • Verilog 编程实现 3-8 译码器 FPGA

    Verilog 编程实现 3-8 译码器 FPGA FPGA 是一种可重构的数字电路芯片,可用于实现各种逻辑电路。在 FPGA 中,我们可以使用 Verilog HDL(硬件描述语言)来编写数字电路设计。本篇文章将为您介绍如何使用 Verilog 实现基本的数字电路,即 3-8 译码器。 3-8 译码器是一种常用的数字电路

    2024年02月07日
    浏览(40)
  • 【FPGA】Verilog编程实现SDRAM读写(一) ----- 初识SDRAM

    SDRAM(Synchronous Dynamic Random Access Memory),同步动态随机存储器。同步、动态、随机是其性能特点的外在说明: 同步(Synchronous )是指内存工作需要同步时钟,内部的命令的发送与数据的传输都以它为基准 动态(Dynamic )是指存储阵列 需要不断的刷新来保证数据不丢失 随机(

    2023年04月08日
    浏览(44)
  • Verilog编程:8线-3线优先编码器FPGA

    Verilog编程:8线-3线优先编码器FPGA 基于FPGA的数字电路设计是当前领域中的关键技术之一,因为这种设计具有高速、可编程、可重构等优点。在数字电路设计中,编码器是常见的模块,尤其是8线-3线优先编码器,可以实现将八个输入信号中最先出现的一个编码输出到三位二进制

    2024年02月08日
    浏览(41)
  • FPGA | Verilog基础语法

    菜鸟教程连接 举例(\\\"//\\\"符号后的内容为注释文字): initial $dumpfile (“myfile.dump”); //指定VCD文件的名字为myfile.dump,仿真信息将记录到此文件 可以指定某一模块层次上的所有信号,也可以单独指定某一个信号。 典型语法为$dumpvar(level, module_name); 参数level为一个整数,用于指

    2024年02月05日
    浏览(49)
  • FPGA基础概念_Verilog

     一、文件尾缀含义等常识 sof文件时编译(分析、综合、布线、生成、时序)过程中生成的一个文件,可通过Jtag下载到FPGA的SRAM中去执行. pof文件生成过程同上,但不同之处在于不能直接下载到FPGA的SRAM中,需要通过ASP端口直接下载到FPGA的配置芯片中,配置芯片一般时串行F

    2024年02月03日
    浏览(44)
  • Verilog实现FPGA可编程电路中的RAM存储器

    Verilog实现FPGA可编程电路中的RAM存储器 在FPGA可编程电路的设计中,RAM存储器通常被广泛使用。而手写RAM存储器则可以提供更加灵活、高效的设计方案。本文将介绍如何使用Verilog语言来手写FPGA中的RAM存储器。 首先,我们需要确定RAM存储器的大小和宽度。假设我们需要实现一个

    2024年02月04日
    浏览(53)
  • FPGA设计Verilog基础之Verilog的运算符

    注意:后续技术分享,第一时间更新,以及更多更及时的技术资讯和学习技术资料 ,将在公众号 CTO Plus 发布,请关注公众号: CTO Plus FPGA设计Verilog基础之Verilog的运算符 Verilog是一种硬件描述语言,支持多种运算符,包括算术运算符、比较(关系)运算符、逻辑运算符、条件

    2024年02月03日
    浏览(48)
  • FPGA设计Verilog基础之Verilog全局变量和局部变量定义

    注意:后续技术分享,第一时间更新,以及更多更及时的技术资讯和学习技术资料 ,将在公众号 CTO Plus 发布,请关注公众号: CTO Plus   在Verilog中,变量可以分为全局变量和局部变量两种类型。全局变量在整个模块中都可以使用,而局部变量只能在某个特定的代码块中使用。

    2024年02月15日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包