组合逻辑电路中的语法1
1、 Verilog语句都是在module–endmodule模块中的
module test_module(
input wire [3:0] in, //不写wire或者reg默认为wire
output wire [3:0] out);
.......
endmodule
2、端口关键字有:input, output, inout ;
除了Test Bench代码外,都需要定义端口
3、连续赋值语句
`timescale 10ns/1ns //基本时间单元/时间精度
assign #6 R1 = A & B; // #6延时时间60ns
4、always@(敏感信号列表)begin
…
end
begin–end为顺序执行语句块,相当于大括号,仅限在always语句中使用
5、assign连续赋值语句只能给wire型变量赋值
wire R1 = A & B; //相当于wire R1; assign R1 = A & B;
always过程语句中只能给reg型赋值。
6、等于符号为“ == ”,两边操作数的位数不相等时,在高位补0,符号两边出现了x或者z则结果为假;
全等为“ === ”, 若位数不等,则直接结果为假,并且会对所有位进行比较(比较x和z)。
7、阻塞赋值“=”, 等号左边目标变量执行完当前语句后直接获得左边变量的值;
非阻塞赋值“<=”,在语句块执行结束时才赋值,且只能出现在顺序语句中。
对同一过程的同一变量,不能混合使用这两种赋值
在循环语句中不能使用非阻塞赋值,因为非阻塞赋值在过程块结束时才赋值,会造成循环结束只赋值了一次
reg out1, out2;
always@(posedge clk) begin
out1 = din;
out2 = out1;
end
综合出来的电路为:
reg out1, out2;
always@(posedge clk) begin
out1 <= din;
out2 <= out1;
end
//或者
reg out1, out2;
always@(posedge clk) begin
out2 = out1;
out1 = din;
end
综合处的电路为
8、拼接运算符{}
reg [3:0] Vec;
wire [1:0] a, b;
always@ * begin //语句块中所有变量都为敏感信号
Vec = {b, a};
end
{2’d3, {3{3’b101}}},重复某个数需要再加一个{}
9、切片 a = Vec[3:2];
10、case语句,包含case、casex、casez(某一位位x或者z则不比较这一位,即x或者z和任意值相比都为真),casez中?和z意思相同,即这些位不比较
11、case语句只执行一条符合条件的语句就跳出语句,允许多个分支的条件同事满足case表达式,此时执行最先满足表达式的分支,然后跳出语句
12、若分支中包含所有case表达式中的数据,则可不写default,但是,若不全部包含不写default的话,可能在电路中插入不必要的latch(锁存器,满足未覆盖的语句时,需要保持上次输出值)。有时候可能存在的情况有很多种,但是在实际问题中只会出现几种,这时可以在case语句之前对所有变量赋初值,防止生成latch
input [15:0] scancode; //scancode有很多种情况
always @(*) begin
up = 1'b0; down = 1'b0; left = 1'b0; right = 1'b0;
case (scancode)
... : up <= 1'b1; down = ....// Set to 1 as necessary.
endcase
end
13、4’b1001为无符号二进制数9;
4’sb1001为有符号二进制数 -1。但是所有的运算都是以无符号数进行的,负数变换成补码形式.(有符号数,无符号数在存储器里都是一样的,只不过我们自己看的时候把它看做不同,将其看成有符号数则认为这个数为负数的补码)
14、Verilog中+ - *都能直接被综合,但是/ 和% 只有在操作数为以2为底的幂时才能被综合
15、在定义端口时,input signed [3:0] A;为定义了一个有符号的操作数;运算时,加法则将操作数当成无符号数计算(即:负数用补码形式表示,输出的结果也为补码),输出结果的是源码;减法运算时(负数用补码表示),输出的是补码
16、进位或者借位输出可以使用拼接符,{C0, S} = {1’b0, A} +(-) {1’b0, B};
17、参数定义,parameter S = 4, C = 8; 一般用来表示延时、位宽等常量。
参数传递:
module MULT4B
#(parameter S = 1, N = 2)(R, A, B);
input[S:1] A, B;
output [2*S - 1] S;
.......
endmodlue
//上层模块
module MULTB(...);
......
MULT4B #(.S(8), .N(10))
U1(.R(R), ...);
localparam 也表示的常量,只是无法通过顶层模块对其进行数据传递
defparam传递参数说明语句,
defparam 实例名 .模块参数名 = 新值 (注意后面不是元件名,而是下面模块中例化元件名)
defparam只能将参数传递到比当前模块低一层的元件文件,即当前的例化文件
18、integer 和reg一样也为寄存器类型,integer A;
integer B[3:0] 定义一个4位的数组。B[0]…B[3]每一个都是32位的寄存器类型。在verilog语言中,一个reg类型的数据是被解释成无符号数,integer类型的数据是被解释成二进制补码的有符号数,而且最右边是有符号数的最低位