三目运算符
(条件 ? if_true : if_false)
可通过三目运算符在一行中,选择两个值之一,无需在always块中使用if-then,给出如下例子:
(sel ? b : a) // 通过sel进行二选一
always @(posedge clk) // T触发器
q <= toggle ? ~q : q;
always @(*) // State transition logic for a one-input FSM
case (state)
A: next = w ? B : A;
B: next = w ? A : B;
endcase
assign out = ena ? q : 1'bz; // A tri-state buffer
((sel[1:0] == 2'h0) ? a : // A 3-to-1 mux
(sel[1:0] == 2'h1) ? b :
c )
练习
给定四个无符号数字,找到最小值。无符号数字可以与标准比较运算符(a < b)进行比较。使用条件运算符来得到,同时两两比较时,可创建新的变量来暂存中间结果。
module top_module (
input [7:0] a, b, c, d,
output [7:0] min
);
wire [7:0] min1;
wire [7:0] min2;
assign min1 = (a < b)? a: b;
assign min2 = (c < min1)? c : min1;
assign min = (d < min2)? d: min2;
endmodule
缩位运算符
若想创建一个多位宽的逻辑门操作,就要对一个向量的所有位进行操作,比如(a[0] & a[1] & a[2] & a[3] … ),如果向量很长,这种计算方式很麻烦。而缩位运算符即可对一个向量的各个位进行操作,产生一位的输出,例如:
练习 1
奇偶校验可在数据传输时进行错误的检测。
创建一个电路,该电路将计算 8 位字节的奇偶校验位(这将向字节添加第 9 位)。我们将使用“偶数”奇偶校验,其中奇偶校验位只是所有8个数据位的异或。
module top_module (
input [7:0] in,
output parity);
assign parity = ^in[7:0];
//assign parity = ^in;
endmodule
练习 2
构建具有 100 个输入的组合电路,采用[99:0]。有 3 个输出:
out_and:100 输入 对应的AND 门的输出。
out_or:100 输入对应的 OR 门的输出。
out_xor:100输入对应的异或门的输出。
module top_module(
input [99:0] in,
output out_and,
output out_or,
output out_xor
);
assign out_and = ∈
assign out_or = |in;
assign out_xor = ^in;
endmodule
组合for循环,向量反转
给定一个 100 位输入向量 [99:0],反转其位顺序。
module top_module(
input [99:0] in,
output [99:0] out
);
integer i;
always @ (*) begin
for(i=0;i<100;i++)begin
out[i] = in[99-i];
end
end
endmodule
组合for循环,255位计数
module top_module(
input [254:0] in,
output [7:0] out );
integer i;
always @(*) begin
out = 8'd0;
for(i=0;i<255;i++) begin
out = out + in[i];
end
end
endmodule
循环生成语句
关于生成块:
Verilog中的generate生成语句可动态地生成Verilog代码,常用于编写可配置的、可综合的RTL的设计结构。它可用于参数化模块的生成,可创建模块的多个实例化,或者有条件的实例化代码块。——生成块的本质是用循环内的一条语句来代替多条重复的Verilog语句。
在使用generate循环生成语句时,必须说明生成的实例范围。
生成的实例具有唯一的标识名,因此可用层次命名规则引用,生成的声明和实例,能在设计中被有条件的调用。
genvar用于声明生成变量,并且只能在生成块中用(生成变量的值只能由循环生成语句改变),其被用作整数用来判断generate循环。
循环生成语句可嵌套,但是使用同一个生成变量作为索引的循环生成语句不可相互嵌套。
练习1
用循环生成语句 设计100位二进制加法器
module top_module(
input [99:0] a, b,
input cin,
output [99:0] cout,
output [99:0] sum );
genvar i;
generate
for(i=0;i<100;i++) begin:adder //adder是循环生成语句的名
if(i==0)
assign{cout[0],sum[0]}=a[0]+b[0]+cin;
else
assign{cout[i],sum[i]}=a[i]+b[i]+cout[i-1];
end
endgenerate
endmodule
练习2
100位BCD加法器
module top_module(
input [399:0] a, b,
input cin,
output cout,
output [399:0] sum
);
genvar i;
wire [99:0] cout_tmp;
generate
for(i=0;i<100;i++)begin:bcd_fadd
if(i == 0)
bcd_fadd u_bcd(a[3:0],b[3:0],cin,cout_tmp[0],sum[3:0]);
else
bcd_fadd u_bcd(a[4*i+3:4*i],b[4*i+3:4*i],cout_tmp[i-1],cout_tmp[i],sum[4*i+3:4*i]);
end
endgenerate
endmodule