【自用】Verilog笔记

一、语法

1、模块

【自用】Verilog笔记_第1张图片

module test(A,B,C,D,F1,F2);      // test为模块名

    input A,B,C,D;               // 输入端口,默认为wire类型信号,一般都是wire
    output F1,F2;                // 输出端口,默认wire
    wire F1;                     // 连线
    reg  [2:0] F2;               // 3bit寄存器

endmodule




module  top_module(
    input a,
    input b,
    output out
);

// 模块实例化语法: 模块名 实例名(定义连接port的信号);
	mod_a instance2 (.in1(a), .in2(b), .out(out));    // 即普通函数
 
endmodule




module top_module(input [7:0] in,  output [7:0] out);
    genvar i;        // genvar i; 也可以定义在generate内部
    generate
        for(i = 0; i < 8; i++) begin: bit
             assign out[i]=^in[8-1:i];
        end
    endgenerate
endmodule

2、赋值语句

 对应wire,持续赋值语句

assign F = (A & B) | (A & C);      // F = AB + AC




 对应assign,可用if、case、for

always@(A or B)            // A或B发生变化就执行后面语句
begin
    if(A == B)             // 只能在always块内
      C <= 1;
    else
      C <= 0;

    case(A)                   // 只能在always块内
        2'b00 : B <= 1;       // 2'b表示2位二进制
        2'b01 : B <= 0;
        2'b10 : B <= 1;
        2'b11 : B <= 1;
        default :B <= 0;     // 当A为01时,输出B为0;A为00,10,11时为1
    endcase
end

always@(posedge A)            // 在A的上升沿时执行后面语句
begin
  b <= 1'b1;                  // 1'b表示一位二进制,再例如4’b 1111表示四位二进制数1111
  a <= b;                     // 非阻塞赋值(< =),b先赋值给a,b再变为1
end

always@(negedge B)            // 在B的下降沿时执行后面语句
begin
  b = 1'b1;                   // 阻塞赋值(=),a、b均为1
  a = b;
end

3、逻辑运算

(1)逻辑运算符:&& (与)、==(相等)、||(或)、!=(不等)

        m&&n :判断m和n是否全为真(非0即为真),真则输出1'b1,否则输出1'b0

        最后输出结果只有1bit 

(2)按位运算符:& 、| 、~ 、^ 、~& 、~^ 、~| 

        m&n  : 是把m的每一位与n的每一位按位做与运算(4’b1010 & 4’b0101 = 4’b0000)

        输出结果与m/n的bit数相同

(3)归约运算符:& 、| 、~ 、^ 、& 、~^ 、~| 

        只有一个参量参与运算时(&为一元运算符),表示规约与,即向量内部进行与运算

&a [3:0]      // AND:a[3]&a[2]&a[1]&a[0] 相当于 (a[3:0] == 4'hf)
|b [3:0]      // OR:b[3]|b[2]|b[1]|b[0] 相当于 (b[3:0] != 4'h0)
^c [2:0]      // XOR:c[2]^c[1]^c[0]

        即(&4’b0101 = 0&1&0&1 = 1'b0)
        最后输出结果只有1bit 

(4)其他:

 条件运算符 “ ?:”

assign a = (b==3) ? 4 : 5;      // 如果b=3,那就将4赋值给a,如果不等于就将5赋值给a;




 拼接运算符 “ { , } ”

c = { a , b };      // 假设a=3’b011,b=3’b101,c的结果就为011101

// 但前提是c这个变量的位宽必须要大于6,如果他只有4bit位宽,那结果就变为1101。

二、常量

1、十进制整数 表示 整型常量

        1)正数: 直接写 10 表示位宽为32bit的十进制整数(系统默认)

        2)负数:  -10需要用二进制补码表示,多了一位符号位(1 1010)

        3)用科学计数法表示:12.345e3  表示  12345

2、基数法 表示 整数型常量

        1) 二进制(b):     8'b1000_1100

                当表示二进制时,最好每4位写一个下划线以增强可读性

                当位宽大于二进制位数时左边自动补0,位宽小于二进制数时从左边截断

        2)十六进制(h):  8'h8c

        3)八进制(o):      8'o214

                基数表示法中遇到x时:十六进制表示4个x,八进制中表示3个x

        4)十进制(d):      8'140

3、字符串

       每个字符由1个8位的ASCII码值表示,即需要1byte存储空间

        eg.  “Hello world”  字符串由11个ASCII符号构成,需要11byte存储空间

三、参数

        参数的名称一般为大写,以区分其他变量

1、parameter(常量)

        通常出现在module内部,常被用于定义状态、数据位宽等

        只作用于声明的那个文件,且可以被灵活改变

parameter STATE = 1'b0;

2、localparam(局部参数)

        只在本模块中使用

localparam  STATE= 1'b1’;

四、向量(vector)

        是一组信号的集合,可视为位宽超过1bit  的 wire 信号

1、定义方式

//输入输出型
input [7:0] a, b;        // [upper:lower] 定义位宽,如 [7:0] 表示位宽为8 bit
output reg [7:0] out;
 
// 模块中间向量
wire [7:0] c, e;
reg [7:0] d;

2、向量片选

        eg. 多路选择器:实现一个 256 选 1 选择器,sel 信号作为选择信号

                                    当 sel = 0 时选择 in[3:0],sel = 1 时选择 in[7:4],以此类推

module top_module (
	input [1023:0] in,
	input [7:0] sel,
	output [3:0] out
);

	assign out = {in[sel*4+3], in[sel*4+2], in[sel*4+1], in[sel*4+0]};    // 直接一个个选
 
    // or

	assign out = in[sel*4 +: 4];          // 索引从 sel*4 开始的高4bit信号

    // or

	assign out = in[sel*4+3 -: 4];        // 索引从 sel*4+3 开始的低4bit信号

endmodule

你可能感兴趣的:(笔记)