系列文章目录
Verilog学习1——三目运算符
Verilog学习2——与门(按位与和逻辑与)
Verilog学习3——向量
Verilog学习4——取反与移位运算
Verilog学习5——门电路
Verilog学习6——加法器
Verilog学习7——case的使用
一、case的用法
Verilog中的case语句几乎等同于if-elseif-else的序列,该序列将一个表达式与其他表达式的列表进行比较。它的语法和功能与C语言中的switch语句不同。使用方法如下:
always @(*)
begin // This is a combinational circuit
case (in)
1'b1: begin
out = 1'b1; // begin-end if >1 statement
end
1'b0: out = 1'b0;
default: out = 1'bx;
endcase
end
- case语句以case开头,每个“case项”以冒号结尾。不使用“switch”。
- 每个case项只能执行一个语句,如果需要执行多个语句,则必须使用begin-end。
- 允许重复(和部分重叠)的case项,使用第一个匹配的。C语言不允许重复case项。
例:创建一个6对1多路复用器。当sel介于0和5之间时,选择相应的数据输入,否则输出0。数据输入和输出均为4位宽。
module top_module (
input [2:0] sel,
input [3:0] data0,
input [3:0] data1,
input [3:0] data2,
input [3:0] data3,
input [3:0] data4,
input [3:0] data5,
output reg [3:0] out );
always@(*) begin // This is a combinational circuit
case(sel)
3'd0: out = data0;
3'd1: out = data1;
3'd2: out = data2;
3'd3: out = data3;
3'd4: out = data4;
3'd5: out = data5;
default: out = 0;
endcase
end
endmodule
二、casez的用法
为8位输入构建优先级编码器。给定一个8位向量,输出应该报告向量中的第一个(最低有效)高电平位,即1。如果输入向量没有高电平位,则报告零。例如,输入8’d10010000应该输出3’d4,因为位[4]是第一个高电平的位。
若使用case语句,则需要有256个case项。而如果case语句中的某些case项不属于关键位,我们可以将其减少到9个case。这就是casez的作用:在比较中,它将具有值z的位视为不需要比较。
八位优先级编码器:
module top_module (
input [7:0] in,
output reg [2:0] pos );
always@(*)
begin
casez(in)
8'b00000000: pos = 0;
8'bzzzzzzz1: pos = 0;
8'bzzzzzz1z: pos = 1;
8'bzzzzz1zz: pos = 2;
8'bzzzz1zzz: pos = 3;
8'bzzz1zzzz: pos = 4;
8'bzz1zzzzz: pos = 5;
8'bz1zzzzzz: pos = 6;
8'b1zzzzzzz: pos = 7;
default: pos = 0;
endcase
end
endmodule
三、避免latch的产生
假设您正在构建一个电路来处理键盘上的扫描代码。给定接收到的扫描代码的最后两个字节,您需要指示是否按下了键盘上的一个箭头键。这涉及到一个相当简单的映射,它可以用四个case语句(或者如果elseif)来实现。
这个电路有一个16位输入和四个输出。在构建此电路时,为了避免产生锁存器,必须在所有可能的条件下为所有输出都分配一个值。仅仅有一个default是不够的。在所有四种情况和默认情况下,必须为四个输出都指定一个值。一个简单的方法是在case语句之前为输出分配一个“默认值”:
module top_module (
input [15:0] scancode,
output reg left,
output reg down,
output reg right,
output reg up );
always @(*)
begin
left = 1'b0;
down = 1'b0;
right = 1'b0;
up = 1'b0;
case(scancode)
16'he06b: left = 1'b1;
16'he072: down = 1'b1;
16'he074: right = 1'b1;
16'he075: up = 1'b1;
endcase
end
endmodule