本原创教程由深圳市小眼睛科技有限公司创作,版权归本公司所有,如需转载,需授权并注明出处(www.meyesemi.com)
第一练:如何区分<=表示的含义?
题目:请描述以下两种方法产生的信号有何区别?
答案:根据“<=”所在语句,在赋值语句中表示非阻塞赋值,在条件判断语句中表示小于等于解析:如以下代码中,if后面括号中的语句表示条件判断,<=表示小于或等于,其余为赋值语句表示赋值。
第二练:变量之间的三目运算练习
问题:设变量a,b,c,请用三目运算符实现:c的值为a和b两者较大的数值
答案:assign c=(a>b)?a:b;
解析:condition_expr?true_expr1:false_expr2;
condition_expr为逻辑真则结果为true_expr1,condition_expr为逻辑假则结果为false_expr2
第三练:“inout"双向端口类型的使用
题目:Verilog除了input和output的端口类型,还有inout双向端口,比如在IIC协议中sda为双向信号。若sda在sda_out_en为1时输出sda_out的数值,在sda_out_en为0时sda为输入状态,如何使用三目运算符实现此功能?
答案:
解析:Verilog的4种数据状态:
0: 逻辑“0”或“假” ;
1: 逻辑“1”或“真” ;
x: 未知状态;
z: 高阻态;
若sda输出则将sda_out赋值给sda,若sda为输入则为高阻态“z”
第四练:位拼接符的使用
题目:请用位拼接符实现c[22:0]的表示,c的数值为:
答案:
解析: 位拼接运算符{ }用于将两个或多个信号拼接起来,中间用逗号间隔,表示一个整体的信号,支持嵌套写法,位拼接运算符需注意位宽的匹配。其中“3{b}”表示复制,“a[2]”表示变量a[3:0]即a[3],a[2],a[1],a[0]中的第二位。
第五练:位拼接符的应用
题目:若1bit串行信号data_in按高位先发的顺序传输一个8bit的数据,data_en为使能信号,请用位拼接符实现串行数据的接收并输出接收的8bit数据data[7:0]。
答案:
解析:data_in的接收顺序为高位在前,所以使用位拼接符将每次接收到的data_in放在data[7:0]的最低位,同时将原data[7:0]的低六位即data[6:0]往高位移一位,先接收的数据会逐步移位到高位,后接收的数据放在低位,接收完8bit数据后data[7:0]就是最终的结果。若低位在前则处理方式相反。
第六练:if_else语句基本用法
题目:请用if_else语句实现:c为a和b中的较大值。
答案:
解析:if-else基本语法。
第七练:if_else语句的嵌套用法
题目:请用if_else嵌套语句实现:d的值为a,b,c三个数取其中最大数值。
答案:
解析:if语句和else语句均支持嵌套用法。
第八练:if_else语句优先级
题目:利用if_else语句中多个条件的优先级关系实现:将变量a[5:0]的十进制中的十位对应的数字提取出来,并且将十位对应的数字赋值给变量b[3:0],要求每个if-else语句中每个条件表达式只允许使用一个关系运算符。
答案:
解析:if…else if…else语句中多个条件表达式具有按顺序的优先级关系,若题目答案中7个条件表达式顺序相反,则b一直为0。
第九练:基本逻辑运算符的使用
题目:用组合逻辑实现以下运算:
答案:assign L=(A&&B)||(!A&&B);
解析:verilog常用操作符如下,需注意多种操作符同时使用情况下操作符之间的优先级关系。
第十练:移位操作符的使用
题目:定义变量reg [7:0]a;reg [7:0]b;reg [7:0]c;暂不考虑溢出及小数,用移位操作符(<<、>>)实现b等于a乘以4的结果,c等于a除以8的结果
答案:
解析:A<<2表示A左移n位且低位补0,A>>2表示A右移n位且高位补0,若实现乘/除以2^n可使用移位操作符,移位操作符将变量a二进制数每左移(<<)一位表示乘以2,每右移(>>)一位表示除以2。
第十一练:二进制数值中1的个数奇偶判断
题目:用verilog实现变量flag为1表示变量a的数值中二进制1的个数是奇数,flag为0表示变量a的数值中二进制1的个数是偶数,比如:a为8’b1111_0000,则二进制1的个数为4,即偶数。
答案:
解析:按位异或,^a等效于a[7]^a[6]^a[5]^a[4]^a[3]^a[2]^a[1]^a[0],二进制中1的个数为奇数个的时候结果为1,二进制中11的个数为偶数个的时候结果为0。
第十二练:变量位宽的选取
题目:定义一个reg型变量a,a的最大值为2000,则a的最小位宽需定义为多少?
答案:reg [10:0]a;
解析:在verilog中位宽指二进制数的位宽,十进制的2000转成二进制为:111 1101 0000,所以变量a最小位宽为11。通常在代码上会为变量再预留一部分位宽避免溢出,若数值超出所定位宽能表示的最大值后会出现高位溢出。
第十三练:计数器计时
题目:已知外部输入时钟信号clk为50MHz,请用verilog实现计数器的计时1秒钟,每间隔1秒输出一个clk时钟周期的脉冲信号flag,参考波形如下:
答案:
解析:时钟信号为50MHz则50_000_000个时钟周期的时间为1s,所以计数器需按每个时钟上升沿+1计数,计数范围从0~49_999_999,循环计数,计数器每次计到一个固定数值时flag信号置为1。
第十四练:寄存器“打一拍”
题目:请用verilog实现寄存器“打一拍”,将信号延时1个时钟周期,默认signal与clk信号同步,参考波形如下:
答案:
解析:“打拍”即使用寄存器将信号延时1个时钟周期。如题目波形图,在时序电路中时钟上升沿3处将signal由0置为1,同一时刻将signal当前值赋给signal_1d,所以signal_1d仍为0;时钟上升沿5处将signal由1置为0,同一时刻将signal当前值赋给signal_1d,所以signal_1d仍为1,达到延时1个时钟周期的效果。
第十五练:识别信号边沿
题目:请用verilog实现signal信号上升沿的识别,每识别到上升沿将flag信号拉高1个时钟周期。
答案:
解析:signal信号经过“打一拍”处理后,延时一个时钟周期的signal_1d信号,在signal为1并且signal_1d为0处即为上升沿的标志,下降沿则相反。