最近跟着老师学习Verilog,做了中科大的练习题,将答案记录一下
Q28always过程块_组合逻辑
题目描述
所有的数字电路都是由逻辑门和连线构成的,因此理论上来说都可以通过模块的连接和assign语句进行描述,然而在很多情况下这并不是最方便的一种方式,过程块提供了一种更加方便的描述方式,always过程块便是其中最常用的一种。
对于可综合电路(即能转化成实际电路的verilog描述方式,与之相对的是不可综合电路,多用于电路仿真,不能转换成实际电路),有两种always块的语法形式:
-组合逻辑电路:always@()
-时序逻辑电路:always@(posedge clk)
组合逻辑电路的always块与assign语句等效,用户描述组合逻辑电路时,可根据便利性选择其中一种方式使用。两者生成的硬件电路一般是等效的,但在语法规则上稍有不同:
-assign语句只能对一个信号进行赋值,always块内可对多个信号进行赋值
-assign语句中被赋值信号为wire类型,always块内被赋值信号需定义为reg类型
-always块内支持更加丰富的语法,如使用if…else..、case等适合实现交复杂的组合逻辑
例如下述两条语句是等效的(out1需定义为wire类型,out2需定义为reg类型,但这仅仅是语法上的要求,生成的电路并没有区别):
assign out1 = a & b | c ^ d;
always @() out2 = a & b | c ^ d;
其对应的电路图如下所示:
always语句后的括号内放的是敏感变量列表,对于上例来说,可以写成always @(a,b,c,d) out2 = a & b | c ^ d,但为了简单起见,我们一般都用符号*代替。
试创建一verilog模块,实现一与门,分别用assign语句和always块实现。
输入格式
1位的a,1位的b
输出格式
1位的out_assign,1位的out_alwaysblock
示例波形

代码编辑
module top_module(
input a,
input b,
output wire out_assign,
output reg out_alwaysblock
);
assign out_assign=a&b;
always@(*)
begin
out_alwaysblock=a&b;
end
endmodule
Q29always过程块_时序逻辑
题目描述
通过前例已经了解到,对于可综合电路,有两种always块的语法形式:
- 组合逻辑电路:
always@(*) - 时序逻辑电路:
always@(posedge clk)
用always描述的时序逻辑电路,除了像组合逻辑always块那样生成组合逻辑电路外,还会生成一组触发器(或称寄存器),用于寄存组合逻辑的输出。寄存器的输出只有在时钟的上升沿时(posedge clk)才会更新,其余时刻均保持不变。
阻塞赋值和非阻塞赋值:
在Verilog中,有三种赋值方式,分别为:
- 连续赋值(如
assign x = y;),该赋值方式只能用于过程块(如always块)之外 - 阻塞赋值(如
x = y;),该赋值方式只能用在过程块(如always@(*))内 - 非阻塞赋值(如
x <= y;),该赋值方式只能用在过程块内(如always@(posedge clk))
在设计Verilog模块时,请遵循以下原则:
- 在组合逻辑的always块内采用阻塞赋值
- 时序逻辑的always块内采用非阻塞赋值
违背这一原则将可能导致难以发现的电路错误,且可能导致仿真与综合的不一致,请用户切记。至于为何这样,初学者可以不必理会,简单理解为verilog语法规范性要求即可。
创建一verilog电路,分别采用上述三种赋值方式实现异或门电路,如下图所示:
Hint
- always块内被赋值的信号都应定义成reg类型
- always块内,组合逻辑采用阻塞赋值(
a = b),时序逻辑采用非阻塞赋值(a <= b) - always语句括号内是敏感变量列表,时序逻辑是边沿敏感的,
posedge clk表示的是clk信号的上升沿,此外,还可以是negedge clk,表示clk信号的下降沿。
输入格式
一位线网型变量clk,a, b。clk为时钟,a,b为输入
输出格式
一位线网型变量out_assign,out_always_comb,out_always_ff。out_assign为a,b连续赋值得到的结果。out_always_comb为a,b阻塞赋值得到的结果。out_always_ff为a,b非阻塞赋值得到的结果
示例波形

代码
module top_module(
input clk,
input a,
input b,
output wire out_assign,
output reg out_always_comb,
output reg out_always_ff
);
// 请用户在下方编辑代码
assign out_assign=a^b;
always@(*)
begin
out_always_comb=a^b;
end
always@(posedge clk)
begin
out_always_ff<=a^b;
end
//用户编辑到此为止
endmodule
Q30if…else…语句
题目描述
if语句用于过程块内部,其对应的电路是二选一的选择器,
以下述代码为例:
always@(*)
begin
if(condition) out = x;
else out = y;
end
上述代码与下面的assign语句完全等效:
assign out = (condition) ? x : y;
试创建一Verilog模块,分别采用assing语句和过程块内的if语句实现下述选择器电路:

Hint:
1.if…else…可以嵌套使用,如
if …
else if…
else if…
else…
2.使用if语句描述组合逻辑时,务必加上else语句,以免产生锁存器(数字电路设计中应尽力避免产生锁存器)
3.本题两个输出信号波形其实是完全一致的,原则上是为了训练大家采用assig

博主记录了跟着老师学习Verilog做中科大练习题的答案。内容涵盖always过程块(组合逻辑与时序逻辑)、if…else…语句、case语句等多种Verilog语法的题目及代码实现,还涉及优先编码器、D触发器、寄存器等电路设计,强调避免锁存器等要点。
最低0.47元/天 解锁文章
2682

被折叠的 条评论
为什么被折叠?



