美文网首页fpga && verilog
给 Verilog 写一个总结(一)

给 Verilog 写一个总结(一)

作者: madao756 | 来源:发表于2019-11-03 13:33 被阅读0次

前言:我大致完成了一个学期的「数字逻辑实验」,是时候给我的 verilog 写一个总结了,好不容易学会的 verilog 不能说忘就忘,后续会创建一个仓库,把自己经常使用的代码收集起来

首先特别想吐槽 verilog 的 begin end,真的非常非常蠢。。。尤其是 case 里面的:

case (variable)
    
endcase

由于自己实现过一个简单的「解释器」,像这样语法方面的东西,真的说改就能改,作为一个 1992 左右年出来的语言, 就不能在语法方面向 C 语言靠拢吗

0X00 运行代码

verilog 不是非要和 vivado 等类似的工具在一起才能运行的,是有工具能够编译和执行的:

详细看我的这篇文章:

Verilog 入门(一)Hello World

0X01 变量基础

变量方面的知识绝对是一大难点,跟其他语言完全不一样!

数据类型以及变量的声明

  • NETS

wire 是 NETS 的一种,通常我们使用 wire 声明 NETS 变量

wire a;
  • Registers

reg 是 Registers 的一种,通常我们使用 reg 声明 Registers 变量

reg b;

module 输入/输出类型的声明

我们可以这样声明 input / output 类型:

module test(
    input a,
    output b
);
reg b;
...
endmodule

也可以这样声明 input / output 类型:

module test(
    input a,
    output reg b
);

...
endmodule

其中未声明的 input / output 默认是 wire 类型,这两种类型具体有啥区别,你在后面的内容中会慢慢感受到

为了方便,我将 NETS 类型和 Registers 类型分别用 wire 和 reg 代替

变量的赋值

在这里我们将遇到 wire 和 reg 的第一个不同点

  • 给 wire 赋值

你可以这样写:

wire a = 10;

也可以这样写:

wire a;
assign a = 10;

这两者赋值的方式等价!

  • 给 reg 赋值

给 reg 赋值不能用 assign,而且要在块里面赋值。

你可以这样赋值:

module test();
    reg t;
    always @(*) begin
        t = 10;
    end
endmodule

也可以这样赋值:

module test();
    reg t;
    always @(*) begin
        t <= 10;
    end
endmodule

这两种方式不等价,待会会具体抽出来比较这两者的区别

0X02 = VS <=

我们来看下面这两段代码:

// A.v
module A(
    input D, Clock;
    output reg Q1, Q2;
);
    always @(posedge Clock) begin
        Q1 = D;
        Q2 = Q1;
    end
endmodule
// B.v
module B(
    input D, Clock;
    output reg Q1, Q2;
);
    always @(posedge Clock) begin
        Q1 <= D;
        Q2 <= Q1;
    end
endmodule

下面分别是他们综合以后的图:


第一幅图是 A 的,第二幅图是 B 的。为什么会这样呢?

= 是阻塞赋值,<= 是非阻塞赋值。A 的代码会被认为:

Q1 = D;
Q2 = D;

所以会出现两个并行 D 触发器的样子

而 <= 赋值是等这个块结束以后再赋值,Q2 拿的不是 Q1 的新值,拿的是 Q1 的旧值。

0X03 变量的初始化

在其他语言中我们经常干的就是「变量初始化」:

String text = "你真的是我见过的最好看的女生"

在 verilog 中「变量的初始化」很不同!

首先对于 input 与 output 的初始化:

module A(
    input D, Clock;
    output reg Q1, Q2;
);
...
endmodule
  • input 不用初始化

input 是不能被初始化的,因为 input 是上一个 module 给的的,你初始化他干啥!

  • output 初始化的时候一定是 reg 类型

之前我们说过 reg 类型只能在块中被赋值

所以 reg 类型的初始化在

initial begin 
end

中。

写一段代码就是这样:

module A(
    input D, Clock;
    output reg Q1, Q2;
);
    initial begin 
        Q1 <= 0;
        Q2 <= 0;
    end
endmodule

最后说说对 wire 的赋值:

通常在块外使用 assign 给 wire 赋值,最简单的理解 assign 的方法就是想象「一条线」

assign y = 1;

相当于给 y 拉一条恒等于 1 的线。

0X04 Wire VS Reg

我们来到我这篇博客的最后一部分「Wire VS Reg」

  • wire 的 assign 的赋值都可以转换成 reg 在块中赋值

首先来看两段代码:

wire 的 assign 的赋值

// A.v
module A( a, b, y);
    input a, b;
    output y;
    wire a, b, y;
    assign y = a & b;
endmodule

这段代码综合以后的电路:

而 reg 在块中赋值

// B.v
module B( a, b, y);
        input a, b;
        output y;

        reg   y;
        wire a, b;

        always @ ( a or b)
        begin   
             y = a & b;
        end
endmodule

综合以后的电路:

这两者的电路真的一模一样!!!

所以 wire 的 assign 的赋值都可以转换成 reg 在块中赋值

未完待续...

相关文章

  • 给 Verilog 写一个总结(一)

    前言:我大致完成了一个学期的「数字逻辑实验」,是时候给我的 verilog 写一个总结了,好不容易学会的 veri...

  • Modsim 使用过程中出现的一些问题

    MODSIM写verilog 首先要创建名为work的library,然后添加project,注意是verilog...

  • 工作总结

    每日工作总结20191024 1.verilog写测试激励,定向验证很方便。 注意无法,task中不能用alway...

  • Verilog 语言简介

    什么是 Verilog 语言 Verilog一般指Verilog HDL。Verilog HDL是一种硬件描述语言...

  • 【Verilog语言】Verilog语法基础

    Verilog是一个名词,那么对名词首先得知道What是什么问题?那 Verilog是什么呢? Verilog是一...

  • Verilog进行饱和与截位操作

    转载自jgliu的博客 Verilog进行饱和与截位操作 一、引言 在利用Verilog写数字信号处理相关算法的过...

  • 如何用 verilog 写一个 ALU

    前言:之前也写过一个 toy_vm,里面也涉及到四个标志位的更新,ALU 的难点也是这个四个标志位的更新,我每次都...

  • Verilog:基础语法(上)

    Verilog HDL简介 Verilog HDL(简称 Verilog )是一种硬件描述语言,用于数字电路的系统...

  • ISE——demo

    新建项目 型号与器件对应 新建Source 选择Verilog Module 写一个led的demo 按下复位键灯...

  • PLI

    Verilog PLI(Programming Language Interface )是一种Verilog代码调...

网友评论

    本文标题:给 Verilog 写一个总结(一)

    本文链接:https://www.haomeiwen.com/subject/zfgkbctx.html