概述
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;
sel | bus中1的个数 | check |
---|---|---|
0 | odd | 0 |
0 | even | 1 |
1 | odd | 1 |
1 | even | 0 |
实现方法
首先,判断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中的数据类型和运算表达式的语法使用注意事项。
最后
以上就是含糊饼干为你收集整理的Verilog1——数据类型与运算表达式VL1:四选一多路选择器VL2:奇偶校验的全部内容,希望文章能够帮你解决Verilog1——数据类型与运算表达式VL1:四选一多路选择器VL2:奇偶校验所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复