verilog more features 代码总结汇总
1.简易条件选择语句
格式为:(condition ? a : b)对了选a不对选b
题目:Conditional
Given four unsigned numbers, find the minimum. Unsigned numbers can be compared with standard comparison operators (a < b). Use the conditional operator to make two-way min circuits, then compose a few of them to create a 4-way min circuit. You'll probably want some wire vectors for the intermediate results.
答案:
1 module top_module ( 2 input [7:0] a, b, c, d, 3 output [7:0] min);// 4 wire [7:0] buffer1,buffer2; 5 // assign intermediate_result1 = compare? true: false; 6 assign buffer1 = (a<b? a:b); 7 assign buffer2 = (c<d? c:d); 8 9 assign min = (buffer1<buffer2? buffer1:buffer2); 10 11 endmodule
2.简化多个同一寄存器间的位操作
从下面的例子可以简单易懂的了解本部分的含义
& a[3:0] // AND: a[3]&a[2]&a[1]&a[0]. Equivalent to (a[3:0] == 4'hf) | b[3:0] // OR: b[3]|b[2]|b[1]|b[0]. Equivalent to (b[3:0] != 4'h0) ^ c[2:0] // XOR: c[2]^c[1]^c[0]
当然该方法不只局限于以上三种符号像是~&这样的符号也可以套用这种方法。
题目:
Parity checking is often used as a simple method of detecting errors when transmitting data through an imperfect channel. Create a circuit that will compute a parity bit for a 8-bit byte (which will add a 9th bit to the byte). We will use "even" parity, where the parity bit is just the XOR of all 8 data bits.
答案:
1 module top_module ( 2 input [7:0] in, 3 output parity); 4 5 assign parity = ^in[7:0]; 6 7 endmodule
这道题有点过于简单了。。
3.熟练使用上面的方法
题目:Gates100
Build a combinational circuit with 100 inputs, in[99:0].
There are 3 outputs:
- out_and: output of a 100-input AND gate.
- out_or: output of a 100-input OR gate.
- out_xor: output of a 100-input XOR gate.
答案:
1 module top_module( 2 input [99:0] in, 3 output out_and, 4 output out_or, 5 output out_xor 6 ); 7 assign out_and = &in[99:0]; 8 assign out_or = |in[99:0]; 9 assign out_xor = ^in[99:0]; 10 11 endmodule
4.verilog中的for循环
其具体用法与C语言十分相似,但是for循环对应于硬件电路的意义暂时没有搞懂,只好浅尝辄止。
题目:Vector100r
Given a 100-bit input vector [99:0], reverse its bit ordering.
答案:
1 module top_module( 2 input [99:0] in, 3 output [99:0] out 4 ); 5 int i = 0; 6 always @(*) begin 7 for(i = 0;i < 100;i++) 8 out[100-i-1] = in[i]; 9 end 10 11 endmodule
5.for循环熟练使用
题目:
A "population count" circuit counts the number of '1's in an input vector. Build a population count circuit for a 255-bit input vector.
答案:
1 module top_module( 2 input [254:0] in, 3 output [7:0] out ); 4 int i; 5 always @(*) begin 6 out = 8'h00; 7 for(i = 0 ; i<255 ; i++ ) 8 begin 9 if(in[i] == 1) 10 out = out+1'b1; 11 else 12 out = out+1'b0; 13 end 14 end 15 16 endmodule
做这道题的时候有两个点卡了我很久:
一是不确定verilog有没有加的操作,后来经过查阅后发现是可以直接使用+的。
二是忘记初始化out端口,导致无法输出正常结果,加上out = 8'h00即可。
6.verilog中的generate语句使用方法
generate语法:
- 定义genvar,作为generate种的循环变量。
- generate语句中定义的for语句,必须要有begin,为后续增加标签做准备。
- begin必须要有名称,也就是必须要有标签,因为标签会作为generate循环的实例名称。
- 可以使用在generate语句中的类型主要有:
- ü module(模块)
- ü UDP(用户自定义原语)
- ü 门级原语
- ü 连续赋值语句
- ü initial或always语句
- 基本结构如下:
genvar 循环变量名;
generate
// generate循环语句
// generate 条件语句
// generate 分支语句
// 嵌套的generate语句
endgenerate
下面是generate的三个例子:
一、generate-loop循环语句

二、generate-conditional条件语句
generate允许对语句进行条件选择,即将条件选择加入到generate中的for循环中,只例化条件成立时对应的语句或者module。

三、generate-case分支语句
generate-case分支语句与generate-条件语句类似,只不过将原来的分支语句换做了case语句。

有了上面的语法基础后,可以开始尝试做本题了:
题目:Adder100i
Create a 100-bit binary ripple-carry adder by instantiating 100 full adders. The adder adds two 100-bit numbers and a carry-in to produce a 100-bit sum and carry out. To encourage you to actually instantiate full adders, also output the carry-out from each full adder in the ripple-carry adder. cout[99] is the final carry-out from the last full adder, and is the carry-out you usually see.
答案:
1 module top_module( 2 input [99:0] a, b, 3 input cin, 4 output [99:0] cout, 5 output [99:0] sum ); 6 7 assign cout[0] = a[0]&b[0]|a[0]&cin|b[0]&cin; 8 assign sum[0] = a[0]^b[0]^cin; 9 10 genvar i ; 11 generate 12 for(i = 1;i<100;i++) 13 begin:adder99 14 assign cout[i] = a[i]&b[i]|a[i]&cout[i-1]|b[i]&cout[i-1]; 15 assign sum[i] = a[i]^b[i]^cout[i-1]; 16 end 17 endgenerate 18 19 endmodule
这份代码是我参考了网上其他兄弟的结果...其实这道题不用generate而用always也能实现,因为没有实例化任何模块。
7.进一步熟悉使用generate语句
本部分切实使用并提供到了BCD加法器,这里肯定要用generate实现本题目。
题目:Bcdadd100
You are provided with a BCD one-digit adder named bcd_fadd that adds two BCD digits and carry-in, and produces a sum and carry-out.
答案:
1 module top_module( 2 input [399:0] a, b, 3 input cin, 4 output cout, 5 output [399:0] sum ); 6 7 genvar i ; 8 reg [100:0]buffer; 9 assign buffer[0] = cin; 10 11 generate 12 for(i = 1;i<=100;i++) 13 begin:lable 14 bcd_fadd adder(.a(a[(i*4-1)-:4]), 15 .b(b[(i*4-1)-:4]), 16 .cin(buffer[i-1]), 17 .cout(buffer[i]), 18 .sum(sum[(i*4-1)-:4])); 19 end 20 endgenerate 21 assign cout = buffer[100]; 22 23 endmodule
这道题值得分析一下,由于verilog中实现的电路为并发性的,所以不能单纯的使用上一个加法器的cout送入洗一个加法器的cin,故考虑使用一个缓冲数组来实现所有加法器的进位识别。
为什么要创建101位地数组?因为首位可以用来存放模块外送入的进位,这样就免得单独对首个加法器进行初始化了。
最后注意在generate部分代码后要对整个模块的cout幅值。
同时注意[(i*4-1)-:4]这部分代码,表示从(i*4-1)开始向下四位。
这样的用法还有:
1 big_vect [0 +: 8] 从0 开始,升序,位宽为8 ======》》》》》big_vect [7 :0] 2 little_vect [0 +: 8] 从0 开始,升序,位宽为8 ======》》》》》little_vect [0 :7] 3 big_vect [15 -: 8] 从15开始,降序,位宽为8 ======》》》》》big_vect [15 :8] 4 little_vect [15 -: 8] 从15开始,降序,位宽为8 ======》》》》》little_vect [8:15]

浙公网安备 33010602011771号