Verilog1——数据类型与运算表达式


title: Verilog1——数据类型与运算表达式
date: 2022-08-19 09:15:26
tags: -Verilog
categories: -乔治的进乎技
author: George
email: rzhceie@nuaa.edu.cn
readmore: false
hideTime: true
typora-root-url: …


前言:本博客中的练习题目来源于牛客网牛客题霸-Verilog篇,通过具体练习题目掌握Verilog语法知识。

VL1:四选一多路选择器

功能描述:

在这里插入图片描述
在这里插入图片描述

思路分析:

首先,四选一多路选择器,输入包括四个数据信号为d0 d1 d2 d3,输入一个选择信号为sel;

sel选择结果如下:

sel = 'd0; mux_out = d3;
sel = 'd1; mux_out = d2;
sel = 'd2; mux_out = d1;
sel = 'd3; mux_out = d0;

其次,题目要求输出为线网wire型,这里分析wire型与reg型变量的区别:

Focus1:VerilogHDL中的数据类型

VerilogHDL中共有19中数据类型,
常用的常量数据类型包括integer、parameter等,常用的变量数据类型包括wire、reg、memory等。

wire

​ 1-wire型数据变量为网络类型变量,不能存储值,只表示结构实体之间的物理连接,

​ wire型变量常用来表示assign语句中的组合逻辑信号。

需要由驱动器(门或者连续赋值语句assign)的驱动实现赋值。
Verilog程序块中的输入输出默认都是wire型变量。可以定义时声明为reg型

reg

​ 2-reg型数据变量为寄存器数据类型,通过赋值语句可以改变寄存器存储的值,

​ reg型变量数据常用来表示always模块内的指定信号。

always块内被赋值的每个信号都要定义为reg型。

​ reg型变量被赋值即代表一组触发器的存储数据被改变,

​ 赋值语句是否执行何时由触发条件(如时钟上升沿、逻辑判断指令)决定。

always块与assign语句

​ 3-Verilog基本设计单元为模块module,模块包括端口I/O声明、内部信号声明和逻辑功能定义。

逻辑功能定义由三种方法产生:

连续赋值语句assign assign a = b + c;

实例原件的例化引用 nco u_nco(clk,rst,in,out);

always过程块 always @(posedge clk or negedge rst) begin ... end

在同一个module中,上述三种语句并发执行,与出现的先后顺序无关。只有always过程块内部为顺序执行。

assign语句只能实现组合逻辑赋值,always块内可以实现组合逻辑和时序逻辑。

其他数据类型:

菜鸟教程——Verilog 数据类型

实现方法

基于此,在输入输出信号已经定义为wire型的前提下,

本题有两种实现方法:

1-使用连续赋值语句assign对输出信号直接赋值;

2-定义输出信号的中间变量为reg型,在always块中作逻辑判断赋值

//1-使用连续赋值语句assign对输出信号直接赋值;
`timescale 1ns/1ns
module mux4_1(
input [1:0]d1,d2,d3,d0,
input [1:0]sel,
output[1:0]mux_out
);
    //11-d0 01-d2 ; 10-d1 00-d3 
    //先判高位再判低位
    assign mux_out = sel[0]?(sel[1]?d0:d2):(sel[1]?d1:d3);
    // 先判断低位,后判断高位
    //assign mux_out = sel[1]?(sel[0]?d0:d1):(sel[0]?d2:d3);  
endmodule

//2-定义输出信号的中间变量为reg型,在always块中作逻辑判断赋值
`timescale 1ns/1ns
module mux4_1(
input [1:0]d1,d2,d3,d0,
input [1:0]sel,
output[1:0]mux_out
);
//*************code***********//
    reg[1:0]out_tmp;
    always@(*) begin
    case(sel)
        'd0:out_tmp = d3;
        'd1:out_tmp = d2;
        'd2:out_tmp = d1;
        'd3:out_tmp = d0;
        default:out_tmp = d3;
	endcase
    end
    assign mux_out = out_tmp;
//*************code***********//
endmodule
//testbench测试激励
`timescale 1ns/1ns
module testbench();
	reg clk=0;
	always #5 clk = ~clk;  // Create clock with period=10
// A testbench
    reg[1:0]sel;
    reg[1:0]d1;
    reg[1:0]d2;
    reg[1:0]d3;
    reg[1:0]d0;
    wire[1:0]mux_out;
    initial begin
        assign sel = 'b00;
        assign d1 = 'd0;
        assign d2 = 'd1;
        assign d3 = 'd2;
        assign d0 = 'd3;
        #5 assign sel = 'b01;
        #5 assign sel = 'b10;
        #5 assign sel = 'b11;
        #5 $finish;
    end
 mux4_1 u_mux41(
     .d1(d1),
     .d2(d2),
     .d3(d3),
     .d0(d0),
     .sel(sel),
     .mux_out(mux_out)
);
    
    
//end    
  initial begin
    $dumpfile("out.vcd");
    // This will dump all signal, which may not be useful
    //$dumpvars;
    // dumping only this module
    //$dumpvars(1, testbench);
    // dumping only these variable
    // the first number (level) is actually useless
    $dumpvars(0, testbench);
end  
    
endmodule

VL2:奇偶校验

功能描述:

在这里插入图片描述
在这里插入图片描述

思路分析:

首先,奇偶校验的意思是说,

**奇校验:**对输入数据添加1位0或者1,使得添加后的数包含奇数个1;

比如100,有奇数个1,那么奇校验结果就是0,这样补完0以后还是奇数个1;

**偶校验:**对输入数据添加1位0或者1,使得添加后的数包含偶数个1;

本题的意思应当是说,奇偶检测

**奇检测:**输入的数据位里有奇数个1就输出1;

**偶检测:**输入的数据位里有偶数个1就输出1;

因此,模块输入数据信号为32位数据[31:0]bus,控制信号sel决定该功能模块为奇还是偶检测。

根据波形示意图,sel=0,bus=0,check=1;sel=1,bus=1/2,check=1;sel=1,bus=3,check=0;

可知,sel=0为偶检测,sel=1为奇检测。

综上,当sel=0,若输入数据bus的32位数据中有奇数个1,输出check应当为0;bus有偶数个1,输出check应当为1;

当sel=1,若输入数据bus的32位数据中有奇数个1,输出check应当为1;bus有偶数个1,输出check应当为0;

selbus中1的个数check
0odd0
0even1
1odd1
1even0

实现方法

首先,判断bus中1的位数是奇数还是偶数;其次,结合sel决定check输出。

Focus2:VerilogHDL中的运算符与表达式

算术运算符:

加法:+ a+b

减法:- a-3

乘法:× a*5

除法:/ 5/3

模/求余运算符:% 11%3

#### 位运算符:

电路信号中的与或非运算操作,是相应的操作数的位运算。

取反:~ 单目运算符,对单个操作数进行按位取反;

按位与:& 单/双目运算符

按位或:| 单/双目运算符

按位异或:^ 单/双目运算符

按位同或:^~ 单/双目运算符

其中,按位异或:^ 作为单目运算符时,data=4’b1001,out = ^data = 0;data=4’b1011,out = ^data = 1;

实现了“偶数个1输出0,奇数个1输出1”的奇检测效果。

逻辑运算符:

逻辑操作符主要有 3 个:&&(逻辑与), ||(逻辑或),!(逻辑非)。

逻辑操作符的计算结果是布尔代数值即一个 1bit 的值,0 表示假,1 表示真,x 表示不确定。

A = 3;
B = 0;
C = 2'b1x ;
   
A && B    //     为假
A || B    //     为真
! A       //     为假
! B       //     为真
A && C    //     为X,不确定
A || C    //     为真,因为A为真
条件运算符:

三目运算符:condition_expression ? true_expression : false_expression

其他运算符:

菜鸟教程-Verilog表达式

代码实现:

`timescale 1ns/1ns
module odd_sel(
input [31:0] bus,
input sel,
output check
);
//*************code***********//
    assign check = sel?(^bus): (~(^bus));
//*************code***********//
endmodule

结语:

本篇通过四选一选择器和奇偶检测两个练习,讲解了VerilogHDL中的数据类型和运算表达式的语法使用注意事项。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值