VerilogHDL基本语法和程序

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

Verilog语法

注意点

  • 在always过程块中赋值的变量应该定义为 reg 型。reg型的变量不能用assign赋值
  • 函数可以出现在持续赋值assign的右端表达式中
  • input,output如果没有规定位宽或者类型的话,则默认是1位的wire类型
  • verilog中for,if语句都不用加“:”
  • 当没有指定函数名(返回值)的位宽和类型时,则默认是1位的reg类型
  • output reg [7:0] y = 0;这种初始化赋值方式只能在模块级别出现,不能在函数中出现
  • 变量声明尽量不要在匿名代码块begin end中,可以在模块级别声明,代码块中赋值
  • 几进制计数器就是模几计数器

module命名规则

  • 模块的名称必须以字母或下划线开头。
  • 模块的名称可以包含字母、数字和下划线。
  • 模块的名称不能包含空格或其他特殊字符,如符号和标点符号。

assign关键字

assign 关键字用于在 Verilog 中创建连续赋值,它可以将一个表达式赋值给一个 wire 类型的信号。assign 赋值发生在每个仿真时间步骤的开始,因此连续赋值可以用于在组合逻辑中实现一些功能。assign左侧的值必须是wire型,右侧的值可以是寄存器或者函数表达式。

下面是一个使用 assign 的简单例子,实现了一个两个输入信号的异或门:

module xor_gate(
    input a,
    input b,
    output y
);
	wire a,b;
    assign y = a ^ b;
endmodule
//这里使用 assign 关键字将 a ^ b 赋值给 y,从而实现了异或门的逻辑。
//需要注意的是,
//使用 assign 赋值的信号必须是 wire 类型的信号,
//而且不能使用时序逻辑语句来修改这些信号的值

reg 关键字

reg 是 Verilog HDL 中的一种数据类型,表示寄存器类型。在模块中,我们通常使用 reg 声明模块的内部寄存器变量。

reg 变量可以存储数字、布尔、字符串等类型的值,可以通过赋值语句来修改其值。在模块中,reg 变量的值可以在 always 块、initial 块或任务,函数中修改。

下面是一个简单的例子,展示如何在模块中使用 reg 变量:

module example_module(
    input clk,
    input rst,
    output reg [7:0] counter
);

always @(posedge clk, posedge rst) begin
    if (rst) begin
        counter <= 8'b0; // 复位计数器为0
    end else begin
        counter <= counter + 1; // 正常加1
    end
end

endmodule

在这个例子中,我们声明了一个名为 counter 的 8 位寄存器变量,并在 always 块中使用了该变量。当 rst 信号为高电平时,我们将 counter 变量复位为0。当 clk 信号上升沿到来时,我们将 counter 变量的值加 1。output reg 声明指定了 counter 变量是该模块的一个输出端口,并且是一个寄存器类型。

需要注意的是,在 always 块中,对于 reg 变量的修改操作必须在时钟上升沿或下降沿的敏感列表中,否则在模拟过程中可能会导致意外的行为。

<=运算符

在 Verilog HDL 中,= 表示的是阻塞式赋值操作符,而 <= 表示的是非阻塞式赋值操作符。在时序逻辑中,我们通常使用 <= 来表示寄存器或者组合逻辑的输出信号。这是因为 <= 是一种非阻塞式赋值,可以在时钟边沿触发时更新输出信号,而不受其他语句的阻塞。在always块中,如果有多条“<=”赋值语句的话,是并行执行的,而有多条“=”赋值语句的话,是顺序执行的。

wire关键字

用途1:
wire clk,rst;
wire clk, rst; 是 Verilog HDL 语言中的语句,用于声明两个信号变量 clk 和 rst。

在 Verilog HDL 中,wire 类型的变量用于声明一个信号线,它表示一种被连接到模块输入或输出端口的信号类型,因此 wire 类型的变量通常被用来表示模块的输入输出端口,或者用于将模块中的各个部分连接起来。

在你的程序中,clk 和 rst 分别表示模块的时钟信号和复位信号,声明为 wire 类型的变量表示它们是从模块的外部输入的信号。因此,在模块实例化时,需要将外部的时钟信号和复位信号连接到这两个信号变量上,以便模块能够正确地工作。

8421BCD码是什么意思

8421BCD码是一种二进制编码方式,其中每个十进制数位用4个二进制位表示,这四个二进制位分别代表这个数位上的权值分别为8、4、2和1。因此,它的名称中“8421”代表了这四个权值,而“BCD”代表了“二进制编码的十进制数”(Binary Coded Decimal)的缩写。

举个例子,如果要表示十进制数53,就可以使用8421BCD码来表示为0101 0011,其中第一个字节“0101”代表5,第二个字节“0011”代表3。这种编码方式在数字电路中常被用于数码管的驱动和BCD码加法器等电路中。

练习实例:

组合逻辑电路

verilog设计方式(以2选一MUX为例)

bcd码加法器,数字逻辑与EDA设计,fpga开发

//结构描述---根据电路结构图来画
//行为描述---只需描述出输入和输出的关系即可
//数据流描述---根据逻辑表达式把verilog中的逻辑运算符替换布尔代数中的逻辑运算符
统计二进制数中1的个数
module cal(a,
           y);
    input [7:0] a;
    output [7:0] y;
    function reg [7:0] get0;
        input [7:0] x;
        reg [7:0] count;
        integer i;
        begin   //这里尽量使用begin end 包裹
            count = 0;
            for (i = 0; i <= 7; i = i + 1)
                if (x[i] == 1'b1) 
                    count = count + 1;
            get0 = count;
        end
    endfunction
    assign  y = get0(a);
endmodule 
for语句实现8位二进制数的乘法
module mult_repeat(a,
                   b,
                   result);
    parameter size = 8;
    input [size : 1] a,b;
    output reg [2*size :1] result;
    integer i;
    always @ (a or b)
        begin
            result = 0;
            for (i = 1; i <= size; i=i+1)
                if(b[i])
                    result = result + (a << (i - 1));
        end
endmodule

带同步复位的4位模10 8421BCD码计数器

时序逻辑电路

模4方向可控计数器
module counter(clk,rst,dir,count);
    input clk,rst,dir;
    output [1:0] count;
    
    reg [1:0] count;  // 声明寄存器变量
    always @(posedge clk, negedge rst)
    begin
        if (~rst)
            count <= 2'b00;
        else if (dir)
            count <= (count == 2'b11) ? 2'b00 : count + 1;
        else
            count <= (count == 2'b00) ? 2'b11 : count - 1;
    end
endmodule

模7方向可控计数器
module mode7(clk,
             rst,
             dir,    // dir为 1 表示加法,dir 为 0 表示减法
             count);
    input clk,rst,dir;
    wire clk,rst;
    output reg [2:0] count;
    
    always @(posedge clk or negedge rst)
    begin
        if (~rst)
            count <= 3'b000;
        else if (dir)  // 加法
        begin
            if (count == 3'b110)
                count <= 3'b000;
            else
                count = count + 1;
        end
        else
            count <= (count == 3'b000) ? 3'b110 : count - 1;
    end
endmodule
寄存器(74HC175)
module HC175_Reg (
    input wire clk,    // 时钟输入
    input wire resetn, // 复位输入,低电平有效
    input wire [3:0] d, // 数据输入
    input wire we,     // 写使能信号
    output reg [3:0] q  // 数据输出
);
    always @(posedge clk or negedge resetn) begin
        if (~resetn) begin
            q <= 4'b0; // 复位时将寄存器清零
        end else if (we) begin
            q <= d; // 写入数据到寄存器
        end
    end
endmodule

移位寄存器
  • 具有移位 + 存储功能

  • 真值表
    bcd码加法器,数字逻辑与EDA设计,fpga开发

  • 电路图
    bcd码加法器,数字逻辑与EDA设计,fpga开发

  • 波形图
    bcd码加法器,数字逻辑与EDA设计,fpga开发

  • verilog程序代码文章来源地址https://www.toymoban.com/news/detail-755897.html

module shifter_latch(din,
                     clk,
                     qout);
    input din,clk;
    output reg [3:0] qout;
    output reg dout;
    always @(posedge clk)
        begin
            qout <= qout << 1; //左移一位八上一个时钟上升沿时的输出删掉
            qout[0] <= din; //输入信号补充到输出信号的最低位
            dout <= qout[3]; //输出最高位
        end
endmodule
有限状态机的设计
  • 101序列检测器(三种方法)
//1. CS,NS,OL各用一个过程描述
module fsm1_seq101(input clk,
                   clr,
                   x,
                   output reg z);
    reg[1:0] state, next_state;
    parameter S0 = 2'b00, S1 = 2'b01,S2 = 2 'b11,S3 = 2'b10;
    /*状态编码,采用格雷(Gray)编码方式*/
    always @(posedge clk , posedge clr)  /*此过程定义当前状态*/
        begin 
            if (clr)  state <= S0;   //异步复位,s0为起始状态
            else state <= next_state; 
        end
        always @(state, x)  /*此过程定义次态*/
        begin
            case (state)
                S0 : begin if (x) next_state <= S1; else next_state <= S0; end
                S1 : begin if (x) next_state <= S1; else next_state <= S2; end
                S2 : begin if (x) next_state <= S3; else next_state <= S0; end
                S3 : begin if (x) next_state <= S1; else next_state <= S2; end
                default: next_state <= S0;
            endcase
        end
        always @*
        //此过程产生输出逻辑
            begin 
                case (state)
                    S3:      z = 1'b1;
                    default: z = 1'b0;
                endcase
            end
endmodule


// 2. CS + NS ,OL双过程描述
module fsm2_seq101(input clk,
                   clr,
                   x,
                   output reg z);
    reg [1:0] state;
    parameter S0 = 2'b00,S1 = 2'b01,S2 = 2'b11,S3 = 2'b10; /*状态编码,采用格雷(Gray)编码方式*/
    always @(posedge clk, posedge clr)  /*此过程定义起始状态*/
        begin if (clr) state <= S0;  //异步复位, sO为起始状态
              else 
                case(state)
                    S0 : begin if (x) state <= S1; else state <= S0; end
                    S1 : begin if (x) state <= S1; else state <= S2; end
                    S2 : begin if (x) state <= S3; else state <= S0; end
                    S3 : begin if (x) state <= S1; else state <= S2; end
                default:state <= S0;
                endcase
        end
    //产生输出逻辑(OL)
    always @(state)
        begin
            case (state)
                S3:      z = 1'b1;
                default: z = 1'b0;
            endcase
    end
endmodule


// 3.CS+NS+OL 单过程描述
module fsm4_seq101(input clk,
                   clr,
                   x,
                   output reg z);
    reg [1:0] state;
    parameter S0 = 2'b00, S1 = 2'b01,S2 = 2'b11,S3 = 2'b10; /*状态编码,采用格雷(Gray)编码方式*/
    always @(posedge clk, posedge clr)
        begin 
            if (clr) state <= S0;
            else 
                case (state)
                    S0: begin if (x) begin state <= S1; z = 1'b0; end else begin state <= S0; z = 1'b0; end end
                    S1: begin if (x) begin state <= S1; z = 1'b0; end else begin state <= S2; z = 1'b0; end end
                    S2: begin if (x) begin state <= S3; z = 1'b0; end else begin state <= S0; z = 1'b0; end end
                    S3: begin if (x) begin state <= S1; z = 1'b1; end else begin state <= S2; z = 1'b1; end end
                default:begin state <= S0; z = 1'b0; end
            endcase
        end        
endmodule
  • 1111序列检测器
module fsm_detect(input x,
                  clk,
                  reset,
                  output reg Z);
    reg[4:0] state;
    localparam S0='d0,S1 ='d1, S2 = 'd2,S3 = 'd3,S4 ='d4;  //用localparam语句进行状态定义
    always @(posedge clk)
        begin 
            if (reset) begin state <= S0; Z <= 0; end 
            else 
                case (state) 
                    S0: begin if (x == 0) begin state <= S0; Z <= 0; end else begin state <= S1; Z <= 0; end end
                    S1: begin if (x == 0) begin state <= S0; Z <= 0; end else begin state <= S2; Z <= 0; end end
                    S2: begin if (x == 0) begin state <= S0; Z <= 0; end else begin state <= S3; Z <= 0; end end
                    S3: begin if (x == 0) begin state <= S0; Z <= 0; end else begin state <= S4; Z <= 1; end end
                    S4: begin if (x == 0) begin state <= S0; Z <= 0; end else begin state <= S4; Z <= 1; end end
                default: state <= S0;
                endcase
        end
endmodule

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

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

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

相关文章

  • 【FPGA】Verilog:二进制并行加法器 | 超前进位 | 实现 4 位二进制并行加法器和减法器 | MSI/LSI 运算电路

    0x00 并行加法器和减法器 如果我们要对 4 位加法器和减法器进行关于二进制并行运算功能,可以通过将加法器和减法器以 N 个并行连接的方式,创建一个执行 N 位加法和减法运算的电路。 4 位二进制并行加法器 4 位二进制并行减法器

    2024年02月05日
    浏览(55)
  • Quartus 入门 —— 加法器

    这里使用的 intel 的 芯片为 EP4CE115F29C7 的开发板,软件使用的是 Quartus(Quartus Prime 18.1) 的版本 首先点击新建项目: 下面我们就直接点击下一步到芯片选择部分: 这里我们需要选择 Cyclone IV E 的 EP4CE115F29C7 芯片 然后这里我们选择使用 ModelSim-Altera 进行仿真,然后我们直接点击下

    2024年02月08日
    浏览(40)
  • UVM实战--加法器

    这里以UVM实战(张强)第二章为基础修改原有的DUT,将DUT修改为加法器,从而修改代码以使得更加深入的了解各个组件的类型和使用。 和第二章的平台的主要区别点 (1)有两个transaction,一个为transaction_i,一个为transaction_o,由于DUT的输入输出值并不相同,输入为a,b,cin,输

    2024年02月06日
    浏览(43)
  • 加法器电路

    图3 图三中,由虚短知: V- = V+ = 0 ……a 由虚断及基尔霍夫定律知,通过R2与R1的电流之和等于通过R3的电流,故 (V1 – V-)/R1 + (V2 – V-)/R2 = (V- –Vout)/R3 ……b 代入a式,b式变为V1/R1 + V2/R2 = Vout/R3 如果取R1=R2=R3,则上式变为-Vout=V1+V2,这就是传说中的加法器了。 图4 请看图四。因为

    2024年02月14日
    浏览(35)
  • 运算放大电路(三)-加法器

    加法器 由虚短知: V- = V+ = 0 ……a 由虚断及基尔霍夫定律知,通过R2与R1的电流之和等于通过R3的电流,故 (V1 – V-)/R1 + (V2 – V-)/R2 = (Vout – V-)/R3 ……b 代入a式,b式变为 V1/R1 + V2/R2 = Vout/R3 如果取 R1=R2=R3 则上式变为 Vout=V1+V2 这就是传说中的加法器了。 因为虚断,运放同向端没

    2024年02月04日
    浏览(56)
  • Verilog实现超前进位加法器

    在CPU等对性能要求较高的电路中,一般都会采用超前进位加法器,因为超前进位加法器的延时相对来说比较小。下面讲述超前进位加法器的原理: 我们知道,一个三输入,二输出的全加器,其逻辑关系为 S = A ⊕ B ⊕ C i n S=Aoplus Boplus C_{in} S = A ⊕ B ⊕ C in ​ C o u t = ( A B ) ∣

    2023年04月08日
    浏览(38)
  • 使用FPGA实现逐级进位加法器

    逐级进位加法器就是将上一位的输出作为下一位的进位输入,依次这样相加。下面以一个8位逐级进位加法器给大家展示。 我增加了电路结构,应该很容易理解吧。 下面我也列举了一位加法器,可以看下。 library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; entity adder1 is

    2024年04月23日
    浏览(33)
  • 2-1、地址加法器CS:IP

    语雀原文链接 一个CPU由运算器、控制器、寄存器等器件构成,这些器件靠内部总线相连。 运算器进行信息处理 寄存器进行信息储存 控制器控制各种器件进行工作 内部总线连接各种器件,在它们之间进行数据的传递 内部总线实现CPU内部各个器件之间的联系,外部总线实现

    2024年02月04日
    浏览(38)
  • 用逻辑门实现四位加法器

    一.无符号数全加器 1.无符号数四位全加器原理: 先来看一位全加器: 加数A 加数B 结果 0 0 0 0 1 1 1 0 1 1 1 0(进位1) 与 异或门 相似,用异或门记录 用与门记录A+B的进位 将进位输入与A+B结果相与再与进位相或得进位输出,将进位输入与加数相加计算结果 四位全加器则将低位

    2024年01月19日
    浏览(40)
  • 用加法器实现补码的加/减运算

    目录 1.原码的加减运算 (1)原码的加/减法运算 (2)溢出判断 (3)符号扩展 2.加法器原理 3.加法器实现补码的加减运算 1.原码的加减运算 (1)原码的加/减法运算 正+正---绝对值做加法,结果为正 负+负---绝对值做加法,结果为负 正+负---绝对值大的减绝对值小的,符号同绝

    2024年01月18日
    浏览(49)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包