计算机组成原理笔记03——Verilog快速入门

Verilog快速入门

本篇文章综合北航计算机组成原理课题组&大黑书&网上一些资料&自己杂七杂八的一些想法整理而成,笔者主要写在这儿做复习用。。。。若有侵权请联系删除。

数据类型

  1. wire型:属于nets型数据,通常用于组合逻辑。

    1. 有输入才有输出
    2. 输出随输入即时改变
    3. 一般用assign赋值
    4. 在声明过程中指明位数。(例如32位wire型变量的声明为:wire [31:0] in;)
    5. assign a=a+1不合法!!!
  2. reg型:通常用于时序逻辑,尤其是always块里。

    1. reg的值改变需要有触发信号
    2. 不能被assign赋值
    3. 可以用于建立数组,(例如reg [31:0] mem [0:1023];前面的中括号内是位宽,后面的是存储器数量。
    4. 字符串保存在reg型变量中,每个字符占用一个字节(8bit),如果寄存器变量的宽度小于字符串大小,会截去字符串左边多余的数据。
  3. integer型:通常用于for循环

    1. 不用声明位宽,默认为32位
    2. 默认为有符号数
  4. parameter型:定义在编译时为确定值的常量

    1. parameter width =8;
  5. real型:实数,可用十进制或者科学计数法表示

    1. 声明不能带有范围,默认为0
    2. 如果将实数赋值给一个整数,只有整数部分会赋值过去。
  6. time型:对仿真时间进行保存。

    1. 其宽度一般为 64 bit
    2. 通过调用系统函数 $time 获取当前仿真时间。
  7. 有一些特殊字符在显示字符串中有特殊意义,例如换行符,制表符等。如果需要在字符串中显示这些特殊的字符,则需要在前面加前缀转义字符 \ 。例如下表所示:

    转义字符显示字符
    \n换行
    \t制表符
    %%%
    \\
    ""
    \ooo1到3个8进制数字字符
  8. 数字字面量

    1. 数字的完整表达为<位宽>’<进制><值>,例如2’b00
    2. 省略【位宽】时使用默认位宽,一般为32位
    3. 省略【进制】时一般为十进制
    4. 【值】部分可以用下划线隔开,但下划线只能用于数字之间,例如8’b_0100_1000是非法的,而8’b0100_1000则是合法的。
  9. 有符号数

    1. verilog语言默认wire、reg型变量为无符号数。

    2. 要进行有符号数的比较,需要使用$signed( );

      reg [3:0] a;
      reg [3:0] b;
      wire result;
      assign result = $signed(a)>$signed(b);
      

常用语句

  1. assign语句

    1. 连续赋值:assign out=~in;
    2. 条件运算:
      • assign y = s ? di:d0;(单个条件)
      • assign y= s ? (s[0] ? 1:0) : (s[1] ? 1:0); (多个条件复用)
    3. asssign语句的含义表示a的值时刻等于b
    4. assign语句不能在always和initial块中使用
  2. 优先级:

    • ~
    • *,/,%
    • +,-
    • <<,>> 逻辑左移/逻辑右移
    • <<<,>>> 算数左移/算数右移 <,<=,>,>=(相对比较) ==,!=(相等比较)

    逻辑左移=算数左移,右边统一添0 ;逻辑右移,左边统一添0 ,算数右移,左边添加的数和符号有关

    • &,~&(NAND)

    • ,~(XNOR)

    • |,~| (NOR)

    • ?= (条件运算)

  3. verilog的其他运算符:

    1. 相等比较运算符“= =”、“===”、“!=”、“!= = =” (没有空格,但是markdown里面两个等号好像是高亮格式,有点难受
      • ==和!=可能由于不定值x和高阻值z的出现导致结果为不定值x
      • 而= = =和!==的结果一定是确定的0或1(x与z也参与比较)
    2. 阻塞赋值=和非阻塞赋值<=
      • 阻塞赋值表示每条语句依次执行,有明确的顺序关系,当一条赋值完成后再执行下一条语句
      • 非阻塞赋值表示多条语句并行执行,在描述时序逻辑时要使用非阻塞式赋值<=
    3. 位拼接运算符{}
      • {a,3{a,b} } == {a,a,b,a,b,a,b} 将信号拼接
      • {a,b[3:0],w,3’b101} 拼接
    4. 缩减运算符
      • 如reg [31:0] B,&B表示将B的每一位与得到结果
  4. always语句:

    1. always@或者always@(*)==always_comb

      • 可以避免因为漏写变量而出现错误(尤其是当always语句块中出现中间变量的情况)
    2. 用always语句实现同步复位/异步复位:

      • 同步:

        always@(posedge clk)
            begin
                if (reset)
                ···
            end
        
      • 异步:

        always@(posedge clk,posedge reset)
            begin
                ···
            end
        
    3. always紧跟多个条件时,用‘,’或者‘ or ’连接,只要有其中一个条件被触发,always之后的语句都会被执行

    4. 不要在多个always块中对同一个变量进行赋值

  5. initial语句:

    1. 在硬件仿真开始时执行,且仅执行一次
    2. 一般用于对reg型变量进行初始化
  6. if语句

    1. 记得写else
  7. case语句

    1. begin+endcase标准模板别忘了!

    2. case语句在分支执行结束后不会落入下一个分支,而会自动退出。

    3. 写出default语句,消除异常输入或者无关项。

      • 例如,0-11为有效信号,当输入12-15时,case会记录之前的输出。
      • 定义所有情况下的输出,保证产生组合逻辑
    4. case语句只能在always块中使用

    5. casez语句:可以识别作为无关系的“?”

      casez(a)
          4'b00??: y<=2'b00;
          4'b01??: y<=2'b01;
          4'b10??: y<=2'b10;
          4'b11??: y<=2'b11;
          default:		;
      endcase
      
  8. for&while语句:

    module vote7(
        input [6:0] vote,
    	output reg pass
    );
        reg [2:0] sum;
        integer i;
        always @(vote) begin
        	sum=3'b000;
            for (i=0;i<7;i=i+1) begin
                if (vote[i]) sum=sum+1;
            end
            if (sum>3'd4) pass=1'b1;
            else pass=1'b0;
        end
    endmodule
    
    module counts1_while(
    	input clk,
        input [7:0] rega;
        output reg [3:0] count
    	);
        always @(posedge clk) begin:count1//命名顺序快,建模时序逻辑
            reg [7:0] tempreg;//中间变量
            count=0;
            tempreg=rega;
            while (tempreg) begin
                if (tempreg[0]) count=count+1;
                tempreg = tempreg >> 1;//逻辑右移一位
            end
        end
    endmodule
    
  9. 时间控制语句:

    #3;
    #5 b=a;
    always #5 clk=~clk;
    assign #5 b=a;//表达式右边的值延时5个时间单位后赋值给b
    

模块引用

调用方式1:被调用模块的名称+实例名(自定义)+按模块端口顺序写下实例的端口名。

调用方式2:被调用模块的名称+实例名(自定义)+( ‘ . ’ +模块接口+(被调用接口) )。此方式不需要使用全部接口,且接口顺序任意。

module Sample(
	input a,
    input b,
    input c,
    output d
);
    Sample sample_1(e,f,g,h);
    Sample sample_2(.a(i), .b(j), c(k), .d(l));

宏定义

目前只涉及用宏定义定义常量(类似于parameter)。

**引用宏名时也必须在宏名前加上符号"`"**表明该名字是经过宏定义的名字。

`define WORDLENGTH 8
reg [`WORDLENGTH:1] data;
  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值