Modules:Hierarchy
Modules and vectors
module top_module (
input clk,
input [7:0] d,
input [1:0] sel,
output [7:0] q
);
wire [0:7]q0,q1,q2;
my_dff8 my_dff8_1(.clk(clk),.d(d),.q(q0));
my_dff8 my_dff8_2(.clk(clk),.d(q0),.q(q1));
my_dff8 my_dff8_3(.clk(clk),.d(q1),.q(q2));
always@(*)
begin
case(sel)
0:q=d;
1:q=q0;
2:q=q1;
3:q=q2;
endcase
end
endmodule
Adder 1
module top_module(
input [31:0] a,
input [31:0] b,
output [31:0] sum
);
wire cout;
add16 add16_1(.a(a[15:0]),.b(b[15:0]),.cin(0),.cout(cout),.sum(sum[15:0]));
add16 add16_2(.a(a[31:16]),.b(b[31:16]),.cin(cout),.cout(),.sum(sum[31:16]));
endmodule
Adder 2
module top_module (
input [31:0] a,
input [31:0] b,
output [31:0] sum
);//
wire cout;
add16 add16_1(.a(a[15:0]),.b(b[15:0]),.cin(0),.cout(cout),.sum(sum[15:0]));
add16 add16_2(.a(a[31:16]),.b(b[31:16]),.cin(cout),.cout(),.sum(sum[31:16]));
endmodule
module add1 ( input a, input b, input cin, output sum, output cout );
assign{cout,sum}=a+b+cin;
// Full adder module here
endmodule
Carry-select adder
module top_module(
input [31:0] a,
input [31:0] b,
output [31:0] sum
);
wire cout;
wire [15:0] x,y;
add16 add16_1(.a(a[15:0]),.b(b[15:0]),.cin(0),.cout(cout),.sum(sum[15:0]));
add16 add16_2(.a(a[31:16]),.b(b[31:16]),.cin(0),.cout(),.sum(y));
add16 add16_3(.a(a[31:16]),.b(b[31:16]),.cin(1),.cout(),.sum(x));
assign sum[31:16]=cout?x:y;
endmodule
Adder-substractor
module top_module(
input [31:0] a,
input [31:0] b,
input sub,
output [31:0] sum
);
reg [31:0]b_1;
wire cout;
assign b_1=b^{32{sub}};
//xor(b_1,b,{32{sub}});写成这样运行结果不对//
add16 add16_1( .a(a[15:0]),.b(b_1[15:0]),.cin(sub),.cout(cout),.sum(sum[15:0]));
add16 add16_2( .a(a[31:16]),.b(b_1[31:16]),.cin(cout),.cout(),.sum(sum[31:16]));
endmodule
Procedures
Always block (combination)
module top_module(
input a,
input b,
output wire out_assign,
output reg out_alwaysblock
);
and(out_assign,a,b);
always@(*)
begin
out_alwaysblock=a&b;
end
endmodule
Always blocks (clocked)
module top_module(
input clk,
input a,
input b,
output wire out_assign,
output reg out_always_comb,
output reg out_always_ff );
xor(out_assign,a,b);
always@(*)begin
out_always_comb=a^b;
end
always@(posedge clk)begin
out_always_ff<=a^b;
end
endmodule
if statement
module top_module(
input a,
input b,
input sel_b1,
input sel_b2,
output wire out_assign,
output reg out_always );
assign out_assign=(sel_b1&sel_b2)?b:a;
always@(*)
begin
if(sel_b1&sel_b2)
out_always=b;
else
out_always=a;
end
endmodule
if statement latches
// synthesis verilog_input_version verilog_2001
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)
keep_driving = ~gas_tank_empty;
else
keep_driving = 0;
end
endmodule
case statement
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=1'b0;
endcase
end
endmodule
priority encoder
4-2优先编码器
module top_module (
input [3:0] in,
output reg [1:0] pos );
always@(*)begin
if (in[0]==1) //case(1'b1)
pos=2'b00; //in[0]:pos=0;
else if(in[1]==1) //in[1]:pos=1;
pos=2'b01; //in[2]:pos=2;
else if(in[2]==1) //in[3]:pos=3;
pos=2'b10; //default:pos=0;
else if(in[3]==1) //endcase
pos=2'b11;
else
pos=2'b00;
end
endmodule
priority encoder with casez
有不确定状态的时候要用casez
module top_module (
input [7:0] in,
output reg [2:0] pos );
always@(*)begin
casez(in[7:0])
8'bzzzzzzz1:pos=0;
8'bzzzzzz10:pos=1;
8'bzzzzz100:pos=2;
8'bzzzz1000:pos=3;
8'bzzz10000:pos=4;
8'bzz100000:pos=5;
8'bz1000000:pos=6;
8'b10000000:pos=7;
default:pos=0;
endcase
end
endmodule
Avoiding latches
为了避免产生锁存器,所有的输出都必须在所有可能的条件下被分配一个值。仅仅拥有一个默认情况是不够的。你必须在所有四种情况下和默认情况下为所有四个输出赋值。这可能涉及到很多不必要的输入。一个简单的方法是在case语句之前给输出分配一个 "默认值"。
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;
default:;
endcase
end
endmodule
condition ternary operator
module top_module (
input [7:0] a, b, c, d,
output [7:0] min);//输出四个数中最小的那一个
wire [7:0]min1,min2;
always@(*)begin
min1=(a<b)?a:b;
min2=(c<d)?c:d;
min=(min1<min2)?min1:min2;
end
// assign intermediate_result1 = compare? true: false;
endmodule
Reduction operators
为一个8位字节计算一个奇偶校验位(这将为该字节增加一个第9位)。我们将使用 "偶数 "奇偶校验,其中奇偶校验位只是所有8个数据位的XOR。
& 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]
module top_module (
input [7:0] in,
output parity);
assign parity=^in[7:0];
endmodule
Reduction:Even wider gates
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.
module top_module( input [99:0] in, output out_and, output out_or, output out_xor ); assign out_and=&in[99:0]; assign out_or=|in[99:0]; assign out_xor=^in[99:0]; endmodule
Combination for-loop vector reversal 2
输入100bit位的数据,讲这个数据的输入位顺序翻转
module top_module(
input [99:0] in,
output [99:0] out
);
integer i;
always@(*)begin
for(i=0;i<100;i=i+1)
out[i]<=in[99-i];
end
endmodule
Combination for-loop:255-bit population count
输出输入向量中1的个数
module top_module(
input [254:0] in,
output [7:0] out );
integer n,k;
always@(*)begin
k=1'b0;//需要先给k一个值,避免出现latches
for(n=0;n<255;n=n+1)begin
if (in[n]==1)
k=k+1;
else k=k;
out=k;
end
end
endmodule
Generate for-loop:100-bit binary adder2
通过实例化100个全加器来创建一个100位的二进制行波进位加法器。该加法器将两个100位的数字和一个进位相加,产生一个100位的和进位。
全加器的实现:
-
assign s = a ^ b ^ cin;
-
assign cout = a & b | (cin & (a ^ b));
module top_module( input [99:0] a, b, input cin, output [99:0] cout, output [99:0] sum ); integer i; always@(*)begin {cout[0],sum[0]} = a[0]+b[0]+cin; for(i=1;i< 100;i=i+1)begin {cout[i],sum[i]} = a[i]+b[i]+cout[i-1]; end end endmodule
module top_module( input [99:0] a, b, input cin, output [99:0] cout, output [99:0] sum ); reg [100:0]C; genvar i; assign C[0]=cin; assign cout=C[100:1]; generate for(i=0;i<=99;i=i+1) begin:addbit fulladd stage(C[i],a[i],b[i],sum[i],C[i+1]); end endgenerate endmodule module fulladd(cin,a,b,sum,cout); input a,b,cin; output sum,cout; assign sum=a^b^cin; assign cout = a & b | (cin & (a ^ b)); endmodule
Generate for-loop:100-bit binary adder2
module top_module( input [399:0] a, b, input cin, output cout, output [399:0] sum ); wire[99:0] cout_1; generate genvar i; for(i=0;i<=99;i=i+1)begin:adder if(i==0)begin bcd_fadd fadd_1( .a(a[3:0]), .b(b[3:0]), .cin(cin), .cout (cout_1[0]), .sum(sum[3:0]) ); end else begin bcd_fadd bcd_2( .a(a[4*i+3:4*i]), .b(b[4*i+3:4*i]), .cin(cout_1[i-1]), .cout(cout_1[i]), .sum(sum[4*i+3:4*i]) ); end end assign cout = cout_1[99]; endgenerate endmodule