一、Basic
XOR(异或)
assign out = a ^ b ;
NXOR(同或)
assign out = ~ a ^ b ;
Declaring wires
出现了莫名报错,可能是打错符号了(?)
二、Vectors
vectorgates
!是逻辑非,~是取反要区分清楚
vectors3
assign {out[7:0], out[15:8]} = in; // Swap two bytes. Right side and left side are both 16-bit vectors. assign out[15:0] = {in[7:0], in[15:8]}; // This is the same thing. assign out = {in[7:0], in[15:8]}; // This is different. The 16-bit vector on the right is extended to // match the 24-bit vector on the left, so out[23:16] are zero. // In the first two examples, out[23:16] are not assigned
vectors4
{5{1'b1}} 五个11111; {2{a,b,c}} abcabc
vectors5
assign out = ~{5{a}}^{a,b,c,d,e}} 来表示五个a和abcde分别同或
三、Modules: Hierarchy
Module shift
中间变量要先声明wire
module top_module ( input clk, input d, output q );
wire a1,a2;
my_dff my_dff_list1(.clk(clk),.d(d),.q(a1));
my_dff my_dff_list2(.clk(clk),.d(a1),.q(a2));
my_dff my_dff_list3(.clk(clk),.d(a2),.q(q));
endmodule
module_shift8
声明变量要注意是不是默认位数 不是要声明,变量要看清楚声明是几位,对应清楚。
Module cseladd
module top_module(
input [31:0] a,
input [31:0] b,
output [31:0] sum
);
wire cout1,cout2,cout3;
wire [15:0]sum1;
wire [15:0]sum2;
add16 add16_one(.a(a[15:0]),.b(b[15:0]),.cin(1'b0),.sum(sum[15:0]),.cout(cout1));
add16 add16_two_one(.a(a[31:16]),.b(b[31:16]),.cin(1'b0),.sum(sum1),.cout(cout2));
add16 add16_two_two(.a(a[31:16]),.b(b[31:16]),.cin(1'b1),.sum(sum2),.cout(cout3));
assign sum[31:16]= cout1?sum2:sum1;
endmodule
assign sum[31:16]= cout1?sum2:sum1;这个语句来完成二选一的选择
引用类的时候类名千万不要忘记
四、Procedures
always@(*)
b = 1'b0;
在这种情况下,做仿真时a将会正常为0, 但是b却是不定态。这是为什么?verilog规定,always@(*)中的*是指该always块内的所有输入信号的变化为敏感列表,也就是仿真时只有当always@(*)块内的输入信号产生变化,该块内描述的信号才会产生变化,而像always@(*) b = 1'b0 这种写法由于1'b0一直没有变化,所以b的信号状态一直没有改变,由于b是组合逻辑输出,所以复位时没有明确的值(不定态),而又因为always@(*)块内没有敏感信号变化,因此b的信号状态一直保持为不定态。
Always case2
case要写在模块里
always@(*)
begin
case(1)//对比各位是否为1 所以1是case里的值
in[0]:pos = 2'd0;
in[1]:pos = 2'd1;
in[2]:pos = 2'd2;
in[3]:pos = 2'd3;
default pos = 0;
endcase
end
Always casez
写循环要写casez(不在乎z的位)casex(不在乎x和z)
Vector100r
module top_module(
input [99:0] in,
output [99:0] out
);
integer i;//循环中用的变量(int 整形
always@(*)always里赋值不需要assign
begin
for(i=0;i<100;i=i+1)//分号 其实是三个语句
begin
out[i]=in[99-i];
end
end
endmodule
Adder100i
实例化100个加法器(有一位的加法器),用生成语句,完成实例重复引用
genvar i;//声明生成变量,只能用在生成块里
generate
for(i=0;i<100;i=i+1)
begin:add1//生成块块名
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
Bcdadd100
已经提供了一个加法器 所以要在生成语句直接引用提供的加法器 f赋值也要都在生成模块完成
wire [99:0]cout1;
genvar i;
generate
for(i=0;i<100;i=i+1)
begin:add
if(i==0)
bcd_fadd bcd_fadd_one(.a(a[3:0]),.b(b[3:0]),.cin(cin),.cout(cout1[0]),.sum(sum[3:0]));
else
bcd_fadd bcd_fadd_one(.a(a[4*i+3:4*i]),.b(b[4*i+3:4*i]),.cin(cout1[i-1]),.cout(cout1[i]),.sum(sum[4*i+3:4*i]));
end
assign cout = cout1[99];
endgenerate