Verilog设计入门

Posted 数学小学霸

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Verilog设计入门相关的知识,希望对你有一定的参考价值。

EDA(03)Verilog设计入门

2020-10-04

基础知识

常用

关键字

// 输入
input
// 输出
output
// 参数
parameter
// 赋值语句
assign
// 上升沿 与 下降沿
posedge  negedge

常用运算符

// 逻辑操作
~ // 逻辑取反
| // 逻辑或
& // 逻辑与
^ // 逻辑异或
~^ // 逻辑同或

// 逻辑运算符
&&
||
!
// 关系运算
< <=
> >=

// 算术运算
+
-
*
/
%
// {}拼接运算
[7:0] a // a 为声明
a[6:3] // a 为调用

数值表示

长度'数制简写 数字
4'd8
4'b1011
12'ha2e
// 默认位宽 取决于本身的长度
2345
// 逻辑状态
0 1 x z
x 表示不确定
12'h13x
32'bz
z 表示高阻态

注意

  • assign 只能给wire 类型赋值

  • reg 类型只能在always 赋值

  • 变量缺省定义默认是wire类型

  • 组合电路用= 时序电路用<=

文件

后缀名是.v

常见电路

选择电路

2选1

image-20201019111150086

module mux2_1_a(a, b, s, y);
    input a, b, s;
    output y;
    assign y = (s ? a : b);
endmodule
module mux2_1_b(a, b, s, y);
    input a, b, s;
    output y;
    wire c, d;
    // 虽然位置有先后,但是同时运行的
    assign c = a & (~s);
    assign d = s & b;
    assign y = c | d;
endmodule

4选1

image-20201019111202090

module mux_4_1(y, a, b, c, d, s1, s0);
    output out;
    input a, b, c, d;
    input s1, s0;
    assign y = s1 ? (s0 ? d : c) : (s0 ? b : a);
endmodule

使用always

module mux_4_1(a, b, c, d, s1, s0, y);
    input a, b, c, d, s1, s0;
    output reg y;
    always @ (a, b, c, d, s1, s0)
        begin
            // case 要在always 里面
            case({s1, s0})
                2'b00: y = a;
                2'b01: y = b;
                2'b10: y = c;
                2'b11: y = d;
                default: y = a;
            endcase
        end
endmodule

加法器

全加器

module full_add(a, b, c, so, co);
    input a, b, c;
    output so;
    output co;
    assign {co, so} = a + b + c;
endmodule

8位全加器

module adder_8bit(a, b, cin, cout, dout);
    output [7:0] dout;
    output cout;
    input [7:0] a, b;
    input cin;
    // { } 是拼接操作符
    assign {cout, dout} = a + b + cin;
endmodule

半加器

image-20201004204443736

module h_adder(A, B, SO, CO);
    input A, B;
    output SO, CO;
    assign SO = A ^ B;
    assign CO = A & B;
endmodule

计数器

8位

module cnt_8bit(clk, nRST, cnt_out);
    input clk, nRST;
    output reg [7:0] cnt_out;
    always @ (posedge clk or negedge nRST)
        begin
            if (!nRST)
                cnt_out <= 0;
            else
                cnt_out <= cnt_out + 1;
        end
endmodule

0 - 199计数

module cnt_8bit(clk, nRST, cnt_out);
    input clk, nRST;
    output reg [7:0] cnt_out;
    always @ (posedge clk or negedge nRST)
        begin
            if (!nRST)
                cnt_out <= 0;
            else if (cnt_out < 8'd199)
                cnt_out <= cnt_out + 1;
            else
                cnt_out <= 0;
        end
endmodule

定时器

// clk = 1M Hz
// 1000000
//  999999
// 1s 产生 1 us高脉冲pulse
// 异步复位 低电平复位
module timer_pulse(clk, nRST, pulse);
    input clk;
    input nRST;
    output reg pulse;
    reg [19:0] cnt;
	// 运行1 M 次才是 1 s
    always @ (posedge clk or negedge nRST)
        begin
            if (!nRST)
                cnt <= 0;
            else if (cnt < 999999)
                cnt <= cnt + 1;
            else 
                cnt <= 0;
        end

    always @ (posedge clk or negedge nRST)
        begin
            if (!nRST)
                pulse <= 0;
            // 产生1 us = 10 e-6 脉冲
            else if (cnt < 1)
                pulse <= 1;
            else 
                pulse <= 0;
        end
endmodule
// clk = 1M Hz
// 1000000
//  999999
// 1s 产生 1 ms高脉冲pulse
// 异步复位 低电平复位
module timer_pulse(clk, nRST, pulse);
    input clk;
    input nRST;
    output reg pulse;
    reg [19:0] cnt;
	// 运行1 M 次才是 1 s
    always @ (posedge clk or negedge nRST)
        begin
            if (!nRST)
                cnt <= 0;
            else if (cnt < 999999)
                cnt <= cnt + 1;
            else 
                cnt <= 0;
        end

    always @ (posedge clk or negedge nRST)
        begin
            if (!nRST)
                pulse <= 0;
            // 产生1 ms = 10 e-3 脉冲
            else if (cnt < 1000)
                pulse <= 1;
            else 
                pulse <= 0;
        end
endmodule

寄存器

移位

module SHFT4(DIN, CLK, RST, DOUT);
    input CLK, DIN, RST;
    output DOUT;
    reg [3:0] SHFT;
    always @ (posedge CLK or posedge RST)
        if (RST)
            SHFT <= 0;
    	else
            begin
                SHFT[3] <= DIN;
                SHFT[2:0] <= SHFT[3:1];
            end
    assign DOUT = SHFT[0];
endmodule

分频器

2 分频器

// 2 分频
// 50 % 占空比
module div_2(clk, div_2_out);
    input clk;
    output reg div_2_out;
    reg cnt;
    always @ (posedge clk)
        begin
            if (cnt == 1)
                cnt <= 0;
            else
                cnt <= cnt + 1;
            if (cnt == 1)
                div_2_out <= 0;
            else
                div_2_out <= 1;
        end
endmodule

4分频器

16分频器

module fenpin_16(clk, clk_out);
    input clk;
    output clk_out;
    reg [3:0] cnt;
    
    always @ (posedge clk)
        begin
           cnt <= cnt + 1; 
        end
    assign clk_out = cnt[3];
endmodule

5 分频器

// 5 分频
// 3 / 5 占空比
// 带异步复位 低电平复位
module fenpin_53(clk, clk_out);
    input clk;
    output reg clk_out;
    reg [3:0] cnt;
    
    always @ (posedge clk)
        begin
            if (cnt == 4)
                cnt <= 0;
            else 
                cnt <= cnt + 1;
        end
    
    always @ (posedge clk)
        begin
            if (cnt <= 2)
                clk_out <= 1;
            else
                clk_out <= 0;
        end
endmodule

LED灯

跑马灯

module paomadeng(clk, nRST, LED);
    input clk;
    input nRST;
    output reg[7:0] LED;
    
    // IN
    reg [31:0] cnt;
    always @ (posedge clk or negedge nRST)
        begin
            if (!nRST)
                cnt <= 0;
            else if (cnt >= 499999)
                cnt <= 0;
            else 
                cnt <= cnt + 1;
        end
    
    always @ (posedge clk or negedge nRST)
        begin
            if (!nRST)
                LED[7:0] <= 8'b10000000;
            else if (cnt == 499999)
                LED[7:0] <= {LED[0], LED[7:1]};
            else 
                LED <= LED;
        end
endmodule

回马灯

// 500ms 定时器 cnt
// 每3500 ms 翻转一次
// 500 ms 改变一次LED状态
// state 0 右移
// state 1 左移
module huimadeng(clk, nRST, LED);
    input clk;
    input nRST;
    output reg [7:0] LED;

    // IN
    reg [31:0] cnt;
    reg state;

    always @ (posedge clk or negedge nRST)
        begin
            if (!nRST)
                cnt <= 0;        
            else if (cnt == 499999)
                cnt <= 0;
            else 
                cnt <= cnt + 1;
        end
    
    always @ (posedge clk or negedge nRST)
        begin
            if (!nRST)
                LED <= 4'b10000000;
            else if (cnt == 1)
                begin
                    if (state == 0)
                        LED <= {LED[0], LED[7:1]};
                    else
                        LED <= {LED[6:0], LED[7]}};
                end
            else
                LED <= LED;
        end
    
    always @ (posedge clk or negedge nRST)
        begin
            if (!nRST)
                state <= 0;
            else if (LED == 8'b00000001)
                state <= 1;
            else if (LED = 8'b10000000)
                state <= 0;
            else 
                state <= state;
        end
endmodule

交通灯

时序逻辑电路

触发器

// 同步复位
module DFF1(clk, D, Q);
	output reg Q;
    input clk, D;
    always @ (posedge CLK)
        Q <= D;
endmodule
// 异步复位
module DFF2(CLK, Q, D, RST, EN);
    input CLK, D, RST;
    output reg Q;
    always @ (posedge CLK or negedge RST)
        begin
            if (!RST)
                Q <= 0;
            else if (EN)
                Q <= D;
        end
endmodule

阻塞和非阻塞

// in = 1 2 3 4 5 6 7 ...
// 阻塞
always @ (*)
    begin
        a = in;
        b = a;
        c = b;
    end
// 跟C 语言一样, 是有顺序的
// 1 1 1
// 2 2 2
// 3 3 3
// 4 4 4
// ...

// 非阻塞
always @ (posedge clk)
    begin
        a <= in;
        b <= a;
        c <= b;
    end

// 同时执行的
// 1 0 0
// 2 1 0
// 3 2 1
// 4 3 2

基本时序

以上是关于Verilog设计入门的主要内容,如果未能解决你的问题,请参考以下文章

verilog hdl中啥是综合?啥是模拟?

Verilog设计入门

计算机基础——Verilog语法入门

计算机基础——Verilog语法入门

计算机基础——Verilog语法入门

数字IC入门之一(Verilog)