Verilog Language
目录
Combinational for-loop: Vector reversal 2
Combinational for-loop: 255-bit population count
Generate for-loop: 100-bit binary adder 2
Generate for-loop: 100-digit BCD adder
Basics
Simple wire
module top_module( input in, output out );
assign out = in;
endmodule
Four wires
module top_module(
input a,b,c,
output w,x,y,z );
assign w = a;
assign x = b;
assign y = b;
assign z = c;
endmodule
Inverter
module top_module( input in, output out );
assign out = ~in;
endmodule
AND gate
module top_module(
input a,
input b,
output out );
assign out = a&b;
endmodule
NOR gate
module top_module(
input a,
input b,
output out );
assign out = ~(a||b);
endmodule
XNOR gate
module top_module(
input a,
input b,
output out );
assign out = ~(a^b);
endmodule
Declaring wires
`default_nettype none
module top_module(
input a,
input b,
input c,
input d,
output out,
output out_n );
wire out1, out2;
assign out1 = a & b;
assign out2 = c & d;
assign out = out1 | out2;
assign out_n = ~out;
endmodule
7458 chip
module top_module (
input p1a, p1b, p1c, p1d, p1e, p1f,
output p1y,
input p2a, p2b, p2c, p2d,
output p2y );
wire w1, w2, w3, w4;
assign w1 = p2a&p2b;
assign w2 = p1a&p1b&p1c;
assign w3 = p2c&p2d;
assign w4 = p1d&p1e&p1f;
assign p2y = w1|w3;
assign p1y = w2|w4;
endmodule
Vectors
Vectors
module top_module (
input wire [2:0] vec,
output wire [2:0] outv,
output wire o2,
output wire o1,
output wire o0 ); // Module body starts after module declaration
assign o0 = vec[0];
assign o1 = vec[1];
assign o2 = vec[2];
assign outv = vec;
endmodule
Vectors in more detail
`default_nettype none // Disable implicit nets. Reduces some types of bugs.
module top_module(
input wire [15:0] in,
output wire [7:0] out_hi,
output wire [7:0] out_lo );
assign out_lo = in[7:0];
assign out_hi = in[15:8];
endmodule
Vectors part select
module top_module(
input [31:0] in,
output [31:0] out );//
assign out[31:24] = in[7:0];
assign out[23:16] = in[15:8];
assign out[15:8] = in[23:16];
assign out[7:0] = in[31:24];
endmodule
Bitwise operators
module top_module(
input [2:0] a,
input [2:0] b,
output [2:0] out_or_bitwise,
output out_or_logical,
output [5:0] out_not
);
assign out_or_bitwise = a|b;
assign out_or_logical = a||b;
assign out_not = {~b, ~a};
endmodule
Four-input gates
module top_module(
input [3:0] in,
output out_and,
output out_or,
output out_xor
);
assign out_and = ∈
assign out_or = |in;
assign out_xor = ^in;
endmodule
Vector concatenation operator
module top_module (
input [4:0] a, b, c, d, e, f,
output [7:0] w, x, y, z );//
assign {w,x,y,z} = {a,b,c,d,e,f,2'b11};
endmodule
Vector reversal 1
module top_module(
input [7:0] in,
output [7:0] out
);
assign out = {in[0], in[1], in[2], in[3], in[4], in[5], in[6], in[7]};
endmodule
Replication operator
module top_module (
input [7:0] in,
output [31:0] out );//
assign out = {{24{in[7]}}, in[7:0]};
endmodule
More replication
module top_module (
input a, b, c, d, e,
output [24:0] out );//
assign out = ~{{5{a}}, {5{b}}, {5{c}}, {5{d}}, {5{e}}} ^ {5{a, b, c, d, e}};
endmodule
Modules: Hierarchy
Modules
module top_module ( input a, input b, output out );
mod_a instance1(a, b, out);
endmodule
Connecting ports by position
module top_module (
input a,
input b,
input c,
input d,
output out1,
output out2
);
mod_a instance1(out1, out2, a, b, c, d);
endmodule
Connecting ports by name
module top_module (
input a,
input b,
input c,
input d,
output out1,
output out2
);
mod_a inst(
.out1(out1),
.out2(out2),
.in1(a),
.in2(b),
.in3(c),
.in4(d)
);
endmodule
Three modules
module top_module ( input clk, input d, output q );
wire q1, q2, q3;
my_dff(
.clk(clk),
.d(d),
.q(q1)
);
my_dff(
.clk(clk),
.d(q1),
.q(q2)
);
my_dff(
.clk(clk),
.d(q2),
.q(q3)
);
assign q = q3;
endmodule
Modules and vectors
module top_module (
input clk,
input [7:0] d,
input [1:0] sel,
output [7:0] q
);
wire [7:0] a, b, c;
my_dff8 instan1(clk, d, a);
my_dff8 instan2(clk, a, b);
my_dff8 instan3(clk, b, c);
always @*
case(sel)
2'b00: q <= d;
2'b01: q <= a;
2'b10: q <= b;
2'b11: q <= c;
endcase
endmodule
Adder1
module top_module(
input [31:0] a,
input [31:0] b,
output [31:0] sum
);
wire [15:0] sum1, sum2;
wire cin, cout;
assign cin = 1'b0;
add16 add_low(
.a(a[15:0]),
.b(b[15:0]),
.cin(cin),
.sum(sum1),
.cout(cout)
);
add16 add_high(
.a(a[31:16]),
.b(b[31:16]),
.cin(cout),
.sum(sum2),
.cout()
);
//add16 add_low(a[15:0], b[15:0], cin, sum1, cout);
//add16 add_high(a[31:16], b[31:16], cout, sum2);
assign sum = {sum2, sum1};
endmodule
Adder2
module top_module (
input [31:0] a,
input [31:0] b,
output [31:0] sum
);//
wire cout;
add16 add_low(
.a(a[15:0]),
.b(b[15:0]),
.cin(1'b0),
.sum(sum[15:0]),
.cout(cout)
);
add16 add_high(
.a(a[31:16]),
.b(b[31:16]),
.cin(cout),
.sum(sum[31:16]),
.cout()
);
endmodule
module add1 ( input a, input b, input cin, output sum, output cout );
//assign {cout, sum} = a + b + cin;//This row can replace the next two rows.
assign sum = a^b^cin;
assign cout = (a&b)|((a^b)&cin);
endmodule
Carry-select adder
module top_module(
input [31:0] a,
input [31:0] b,
output [31:0] sum
);
wire cout;
wire [15:0] sum1, sum2;
add16 add_low(
.a(a[15:0]),
.b(b[15:0]),
.cin(1'b0),
.sum(sum[15:0]),
.cout(cout)
);
add16 add_high_1(
.a(a[31:16]),
.b(b[31:16]),
.cin(1'b0),
.sum(sum1),
.cout()
);
add16 add_high_2(
.a(a[31:16]),
.b(b[31:16]),
.cin(1'b1),
.sum(sum2),
.cout()
);
always @*
case(cout)
1'b0: sum[31:16] = sum1;
1'b1: sum[31:16] = sum2;
endcase
//assign sum = {sum[31:16], sum[15:0]};//Redundant codes
endmodule
Adder-subtractor
module top_module(
input [31:0] a,
input [31:0] b,
input sub,
output [31:0] sum
);
wire cout;
wire [31:0] ox;
assign ox = b^{32{sub}};
add16 add_low(
.a(a[15:0]),
.b(ox[15:0]),
.cin(sub),
.sum(sum[15:0]),
.cout(cout)
);
add16 add_high(
.a(a[31:16]),
.b(ox[31:16]),
.cin(cout),
.sum(sum[31:16]),
.cout()//no cout
);
endmodule
Procedures
Always blocks(combinational)
// synthesis verilog_input_version verilog_2001
module top_module(
input a,
input b,
output wire out_assign,
output reg out_alwaysblock
);
assign out_assign = a&b;
always @*
out_alwaysblock = a&b;
endmodule
Always blocks(clocked)
// synthesis verilog_input_version verilog_2001
module top_module(
input clk,
input a,
input b,
output wire out_assign,
output reg out_always_comb,
output reg out_always_ff );
assign out_assign = a^b;
always @*
out_always_comb = a^b;
always @(posedge clk)
out_always_ff <= a^b;
endmodule
If statement
// synthesis verilog_input_version verilog_2001
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 == 1) ? b : a;
always @* begin
if(sel_b1 & sel_b2 == 1) begin
out_always = b;
end
else begin
out_always = a;
end
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;
end
always @(*) begin
if (~arrived)
keep_driving = ~gas_tank_empty;
end
endmodule
Case statement
// synthesis verilog_input_version verilog_2001
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 = 0;
endcase
end
endmodule
Priority encoder
// synthesis verilog_input_version verilog_2001
module top_module (
input [3:0] in,
output reg [1:0] pos );
always@*
begin
case(in)
4'b0000: pos <= 1'd0;
4'b0001: pos <= 1'd0;
4'b0010: pos <= 1'd1;
4'b0011: pos <= 1'd0;
4'b0100: pos <= 2'd2;
4'b0101: pos <= 1'd0;
4'b0110: pos <= 1'd1;
4'b0111: pos <= 1'd0;
4'b1000: pos <= 2'd3;
4'b1001: pos <= 1'd0;
4'b1010: pos <= 1'd1;
4'b1011: pos <= 1'd0;
4'b1100: pos <= 2'd2;
4'b1101: pos <= 1'd0;
4'b1110: pos <= 1'd1;
4'b1111: pos <= 1'd0;
default: pos <= 1'd0;
endcase
end
endmodule
Priority encoder with casez
// synthesis verilog_input_version verilog_2001
module top_module (
input [7:0] in,
output reg [2:0] pos );
always @(*) begin
casez (in[7:0])
8'bzzzzzzz1: pos <= 0; // in[7:1] can be anything
8'bzzzzzz1z: pos <= 1;
8'bzzzzz1zz: pos <= 2;
8'bzzzz1zzz: pos <= 3;
8'bzzz1zzzz: pos <= 4;
8'bzz1zzzzz: pos <= 5;
8'bz1zzzzzz: pos <= 6;
8'b1zzzzzzz: pos <= 7;
default: pos <= 0;
endcase
end
endmodule
Avoiding latches
// synthesis verilog_input_version verilog_2001
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: begin
up = 1'b0; down = 1'b0; left = 1'b0; right = 1'b0;
end
endcase
end
endmodule
More Verilog Features
conditional temary operator
module top_module (
input [7:0] a, b, c, d,
output [7:0] min);//
// assign intermediate_result1 = compare? true: false;
wire [7:0] min1, min2;
assign min1 = a < b ? a : b;
assign min2 = min1 < c ? min1 : c;
assign min = min2 < d ? min2 : d;
endmodule
Reduction operators
module top_module (
input [7:0] in,
output parity);
assign parity = ^ in[7 : 0];
endmodule
Reduction: Even wider gates
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
Combinational for-loop: Vector reversal 2
module top_module(
input [99:0] in,
output [99:0] out
);
integer i;
always@*
for(i = 0; i < 100; i = i + 1) begin
out[i] = in[99 - i];
end
endmodule
Combinational for-loop: 255-bit population count
module top_module(
input [254:0] in,
output [7:0] out );
integer i;
wire [7: 0] count;
always @* begin
count = 0;
for(i = 0; i < 255; i = i + 1) begin
if(in[i] == 1) begin
count = count + 1;
end
else begin
count = count;
end
end
end
assign out = count;
endmodule
Generate for-loop: 100-bit binary adder 2
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
Generate for-loop: 100-digit BCD adder
module top_module(
input [399:0] a, b,
input cin,
output cout,
output [399:0] sum );
wire [99 : 0] cc;
bcd_fadd inst(
.a(a[3 : 0]),
.b(b[3 : 0]),
.cin(cin),
.cout(cc[0]),
.sum(sum[3 : 0])
);
genvar i;
generate
for(i = 1; i < 100; i = i + 1)
begin : bcdadd
bcd_fadd inst(
.a(a[7 + 4 * (i - 1) : 4 + 4 * (i - 1)]),
.b(b[7 + 4 * (i - 1) : 4 + 4 * (i - 1)]),
.cin(cc[i - 1]),
.cout(cc[i]),
.sum(sum[7 + 4 * (i - 1) : 4 + 4 * (i - 1)])
);
end
endgenerate
assign cout = cc[99];
endmodule
题目详见:https://hdlbits.01xz.net/wiki/Problem_sets
以上代码仅供参考,如有错误敬请指正