2.4.3 If statement
问题陈述:
构建一个在a和b之间进行选择的 2 对 1 多路复用器。如果sel_b1和sel_b2都为真,则选择b 。否则,选择. 做同样的事情两次,一次使用分配语句,一次使用过程 if 语句。
Verilog代码:
module top_module(
input a,
input b,
input sel_b1,
input sel_b2,
output wire out_assign,
output reg out_always );
assign out_assign=(sel_b1&&sel_b2)? b:a;
always @(*)
begin
if(sel_b1&&sel_b2)
begin
out_always=b;
end
else
begin
out_always=a;
end
end
endmodule
2.4.4 If statement latches
问题陈述:
以下代码包含创建闩锁的不正确行为。修复错误,以便您仅在计算机真正过热时关闭计算机,并在您到达目的地或需要加油时停止驾驶。
always @(*) begin
if (cpu_overheated)
shut_off_computer = 1; endalways @(*) begin
if (~arrived)
keep_driving = ~gas_tank_empty; end
Verilog代码:
module top_module (
input cpu_overheated,
output reg shut_off_computer,
input arrived,
input gas_tank_empty,
output reg keep_driving ); //
always @(*) begin
if (cpu_overheated)
shut_off_computer = 1;
else if (~cpu_overheated)
shut_off_computer=0;
end
always @(*) begin
if (~arrived)
keep_driving = ~gas_tank_empty;
else
keep_driving=0;
end
endmodule
2.4.5 Case statement
问题陈述:
如果有大量 case,case 语句比 if 语句更方便。因此,在本练习中,创建一个 6 对 1 多路复用器。当sel在 0 到 5 之间时,选择对应的数据输入。否则,输出 0。数据输入和输出均为 4 位宽。
小心推断锁存器
Verilog代码:
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'b000: out=data0;
3'b001: out=data1;
3'b010: out=data2;
3'b011: out=data3;
3'b100: out=data4;
3'b101: out=data5;
default:out=3'b0;
endcase
end
endmodule
2.4.6 Priority encoder
问题陈述:
构建一个 4 位优先级编码器。对于这个问题,如果没有一个输入位为高(即输入为零),则输出零。请注意,一个 4 位数字有 16 种可能的组合。
Verilog代码:
module top_module (
input [3:0] in,
output reg [1:0] pos );
always@(*)
begin
casez(in)
4'bzzz1:pos=2'd0;
4'bzz10:pos=2'd1;
4'bz100:pos=2'd2;
4'b1000: pos=2'd3;
default pos=0;
endcase
end
endmodule
2.4.7 Priority encoder with casez
问题陈述:
为 8 位输入构建优先级编码器。给定一个 8 位向量,输出应报告向量中的第一位1。如果输入向量没有高位,则报告零。
Verilog代码:
module top_module (
input [7:0] in,
output reg [2:0] pos );
always @(*)
begin
casez(in)
8'bz1:pos=0;
8'bz10:pos=1;
8'bz100:pos=2;
8'bz1000:pos=3;
8'bz10000:pos=4;
8'bz100000:pos=5;
8'bz1000000:pos=6;
8'b10000000:pos=7;
default pos=0;
endcase
end
endmodule
2.4.8 Avoiding latches
问题陈述:
假设您正在构建一个电路来处理来自游戏的 PS/2 键盘的扫描码。鉴于收到的扫描码的最后两个字节,您需要指出是否已按下键盘上的箭头键之一。这涉及到一个相当简单的映射,它可以实现为具有四个案例的案例语句(或 if-elseif)。
Scancode [15:0] | Arrow key |
---|---|
16’he06b | left arrow |
16’he072 | down arrow |
16’he074 | right arrow |
16’he075 | up arrow |
Anything else | none |
您的电路有一个 16 位输入和四个输出。构建识别这四个扫描码并断言正确输出的电路。
Verilog代码:
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
每日总结
一、条件语句
1.3种形式的if语句
- if(表达式)语句。例如:
if(a>b)
out1=int1; - if(表达式)
语句1;
else
语句2;
3)if(表达式1)
语句1;
else if(表达式2) 语句2;
else if(表达式3) 语句3;…
注意:条件语句必须再过程块中使用。所谓的过程块语句是指由initial和always语句引导的执行语句集合。
二、case语句
case语句处理多分支的选择。通常用于微处理器的指令译码。
一般形式如下:
1)case(表达式)<case分支> endcase
2)casez(表达式)<case分支> endcase//casez用来处理不考虑高阻值z的比较过程
3)casex(表达式)<case分支> endcase //casex用来处理高阻值z和不定值的比较过程
说明:
1)default项可有可无,一个case语句里只准有一个default项
2)case语句的所有表达式值的位宽必须相等
注意:
为了避免verilog代码出综合后的电路中的生成锁存器,如果用到if语句,最好写上else项;如果用到case语句,最好写上default项。