Alwaysblock1
要求:使用 assign 语句和 always 块构建 AND 门。
注意:always赋值的左侧必须要是变量如:reg。
module top_module(
input a,
input b,
output wire out_assign,
output reg out_alwaysblock
);
assign out_assign = a & b;
always@(*)
out_alwaysblock = a & b;
endmodule
Alwaysblock2
要求:用下图所示的三种方式实现XOR门。
注意:时序逻辑产生的结果会延迟一个周期。
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) & (~a | ~b);
always@(*)
out_always_comb = (a | b) & (~a | ~b);
always@(posedge clk)
out_always_ff = (a | b) & (~a | ~b);
endmodule
Always if
分别使用 if 语句和条件运算符实现下图所示的多路选择器。
条件运算符 ?: (?前面为条件判断式,结果为真时执行 : 前的语句,为假执行后面的语句)
module top_module(
input a,
input b,
input sel_b1,
input sel_b2,
output wire out_assign,
output reg out_always );
always@(*)
begin
if({sel_b1,sel_b2} == 2'b00)
out_always = a;
else if({sel_b1,sel_b2} == 2'b01)
out_always = a;
else if({sel_b1,sel_b2} == 2'b10)
out_always = a;
else
out_always = b;
end
assign out_assign = (sel_b1 & sel_b2)? b : a;
endmodule
Always if2
要求:仅在计算机过热时关闭计算机,即cpu_overheted为1时,shut_off_computer为1;当到达目的地或需要加油时,停止驾驶,即arrived或gas_tank_empty为1时,keep_driving为0.
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
shut_off_computer = 0;
end
always @(*) begin
if (arrived | gas_tank_empty)
keep_driving = 0;
else
keep_driving = 1;
end
endmodule
Always case
要求:使用case语句实现6选1数据选择器,选择信号sel在0到5之间时,选择对应的数据,否则输出0.
如果情况有很多种,使用case语句要比if语句更简便。
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 = 4'b0000;
endcase
end
endmodule
Always case2
要求:实现一个4位优先编码器,给定一个输入,输出该向量中第一个1的位置,如给定输入8'b1001_0000的 8 位优先级编码器将输出3'd4,因为 bit[4] 是第一个高位。如果输入为0,则输出0.
这里可以将所有case全部列举出来,也可以使用casex语句,对于不关心的高位使用x代替,这里的default是多余的,因为4位输入的所有情况都已列举出来了,如果在没有列举出所有case的场合,不要忘记default。
module top_module (
input [3:0] in,
output reg [1:0] pos );
/* always@(*)
begin
case(in)
4'b0001 : pos = 2'd0;
4'b0011 : pos = 2'd0;
4'b0101 : pos = 2'd0;
4'b0111 : pos = 2'd0;
4'b1001 : pos = 2'd0;
4'b1011 : pos = 2'd0;
4'b1101 : pos = 2'd0;
4'b1111 : pos = 2'd0;
4'b0010 : pos = 2'd1;
4'b0110 : pos = 2'd1;
4'b1010 : pos = 2'd1;
4'b1110 : pos = 2'd1;
4'b0100 : pos = 2'd2;
4'b1100 : pos = 2'd2;
4'b1000 : pos = 2'd3;
default : pos = 2'd0;
endcase
end */
always @(*)
begin
casex (in)
4'bxxx1: pos = 2'd0;
4'bxx10: pos = 2'd1;
4'bx100: pos = 2'd2;
4'b1000: pos = 2'd3;
default: pos = 2'd0;
endcase
end
endmodule
Always casez
要求:用casez语句实现8位编码器。
casez语句和casex语句的用法差不多。
module top_module (
input [7:0] in,
output reg [2:0] pos );
always @(*)
begin
casez (in[7:0])
8'bzzzz_zzz1: pos = 3'd0;
8'bzzzz_zz10: pos = 3'd1;
8'bzzzz_z100: pos = 3'd2;
8'bzzzz_1000: pos = 3'd3;
8'bzzz1_0000: pos = 3'd4;
8'bzz10_0000: pos = 3'd5;
8'bz100_0000: pos = 3'd6;
8'b1000_0000: pos = 3'd7;
default: pos = 3'd0;
endcase
end
endmodule
Always nolatches
要求:实现如下的按键功能,注意避免产生latch。
注意:if...else语句中,条件没有列举完全且没有else,可能产生latch,case语句中没有列举完全且没有default,也可能产生latch。
这里先给四个按键都分配了0,只有当case满足,按键的赋值才会被覆盖,所以这里可以不需要加上default。
module top_module (
input [15:0] scancode,
output reg left,
output reg down,
output reg right,
output reg up );
always@(*)
begin
up = 1'b0;
down = 1'b0;
left = 1'b0;
right = 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